pax_global_header00006660000000000000000000000064150543757700014527gustar00rootroot0000000000000052 comment=e0ec98c9dbbf6f6b8777f121a2da38f2d09cf2ed sinclairzx81-typebox-e0ec98c/000077500000000000000000000000001505437577000162605ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/.github/000077500000000000000000000000001505437577000176205ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/.github/.keep000066400000000000000000000000001505437577000205330ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/.github/workflows/000077500000000000000000000000001505437577000216555ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/.github/workflows/build.yml000066400000000000000000000010251505437577000234750ustar00rootroot00000000000000name: Build on: [push, pull_request] jobs: TypeBox: runs-on: ${{ matrix.os }} strategy: matrix: node: [16.x, 18.x, 20.x] os: [ubuntu-latest, windows-latest, macOS-latest] steps: - uses: actions/checkout@v3 - name: Install Node uses: actions/setup-node@v3 with: node-version: ${{ matrix.node }} - name: Install Packages run: npm install - name: Build Library run: npm run build - name: Test Library run: npm run testsinclairzx81-typebox-e0ec98c/.github/workflows/nightly.yml000066400000000000000000000012641505437577000240610ustar00rootroot00000000000000name: Build Nightly on: schedule: - cron: '0 18 * * *' # 6pm Daily jobs: TypeBox: runs-on: ${{ matrix.os }} strategy: matrix: node: [20.x] os: [ubuntu-latest] steps: - uses: actions/checkout@v3 - name: Install Node uses: actions/setup-node@v3 with: node-version: ${{ matrix.node }} - name: Install Packages run: npm install - name: Install TypeScript Latest run: npm install typescript@latest - name: Build TypeBox run: npm run build - name: Install TypeScript Next run: npm install typescript@next - name: Build TypeBox run: npm run buildsinclairzx81-typebox-e0ec98c/.gitignore000066400000000000000000000000311505437577000202420ustar00rootroot00000000000000node_modules target dist sinclairzx81-typebox-e0ec98c/.vscode/000077500000000000000000000000001505437577000176215ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/.vscode/settings.json000066400000000000000000000003031505437577000223500ustar00rootroot00000000000000{ "files.exclude": { "node_modules": true, "package-lock.json": true }, "editor.suggest.showStatusBar": false, "typescript.tsdk": "node_modules\\typescript\\lib" }sinclairzx81-typebox-e0ec98c/changelog/000077500000000000000000000000001505437577000202075ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/changelog/0.17.1.md000066400000000000000000000021741505437577000212610ustar00rootroot00000000000000## [0.17.1](https://www.npmjs.com/package/@sinclair/typebox/v/0.17.1) - Remove default `additionalProperties: false` constraint from all object schemas. This update removes the `additionalProperties: false` constraint on all object schemas. This constraint was introduced on `0.16.x` but has resulted in significant downstream problems composing schemas whose types `intersect`. This is due to a JSON schema design principle where constraints should only be added (never removed), and that intersection types may require removal of the `additionalProperties` constraint in some cases, this had resulted in some ambiguity with respect to how TypeBox should handle such intersections. This update can also be seen as a precursor towards TypeBox potentially leveraging `unevaluatedProperties` for type intersection in future releases. Implementers should take note that in order to constrain the schema to known properties, one should apply the `additionalProperties: false` as the second argument to `Type.Object({...})`. ```typescript const T = Type.Object({ a: Type.String(), b: Type.Number() }, { additionalProperties: false })sinclairzx81-typebox-e0ec98c/changelog/0.17.4.md000066400000000000000000000027351505437577000212670ustar00rootroot00000000000000## [0.17.4](https://www.npmjs.com/package/@sinclair/typebox/v/0.17.4) Changes: - Added `Type.Box()` and `Type.Ref()` functions. Notes: This update provides the `Type.Box()` function to enable common related schemas to grouped under a common namespace; typically expressed as a `URI`. This functionality is primarily geared towards allowing one to define a common set of domain objects that may be shared across application domains running over a network. The `Type.Box()` is intended to be an analog to `XML` `xmlns` namespaces. The `Type.Ref()` function is limited to referencing from boxes only. The following is an example. ```typescript // Domain objects for the fruit service. const Fruit = Type.Box('https://fruit.domain.com', { Apple: Type.Object({ ... }), Orange: Type.Object({ ... }), }) // An order referencing types of the fruit service. const Order = Type.Object({ id: Type.String(), quantity: Type.Number(), item: Type.Union([ Type.Ref(Fruit, 'Apple'), Type.Ref(Fruit, 'Orange') ]) }) ``` > Note: As of this release, the `Type.Omit()`, `Type.Pick()`, `Type.Partial()`, `Type.Readonly()` and `Type.Intersect()` functions do not work with Reference Types. This may change in later revisions. For validation using `Ajv`, its possible to apply the `Box` directly as a schema. ```typescript ajv.addSchema(Fruit) // makes all boxed types known to Ajv ``` This functionality is flagged as `EXPERIMENTAL` and awaits community feedback.sinclairzx81-typebox-e0ec98c/changelog/0.17.6.md000066400000000000000000000033131505437577000212620ustar00rootroot00000000000000## [0.17.6](https://www.npmjs.com/package/@sinclair/typebox/v/0.17.6) Changes: - Added `Type.Rec(...)` function. Notes: This update introduces the `Type.Rec()` function for enabling Recursive Types. Please note that due to current inference limitations in TypeScript, TypeBox is unable to infer the type and resolves inner types to `any`. This functionality enables for complex self referential schemas to be composed. The following creates a binary expression syntax node with the expression self referential for left and right operands. ```typescript const Operator = Type.Union([ Type.Literal('+'), Type.Literal('-'), Type.Literal('/'), Type.Literal('*') ]) type Expression = Static // Defines a self referencing type. const Expression = Type.Rec(Self => Type.Object({ left: Type.Union([Self, Type.Number()]), right: Type.Union([Self, Type.Number()]), operator: Operator })) function evaluate(expression: Expression): number { const left = typeof expression.left !== 'number' ? evaluate(expression.left as Expression) // assert as Expression : expression.left const right = typeof expression.right !== 'number' ? evaluate(expression.right as Expression) // assert as Expression : expression.right switch(expression.operator) { case '+': return left + right case '-': return left - right case '*': return left * right case '/': return left / right } } const result = evaluate({ left: { left: 10, operator: '*', right: 4, }, operator: '+', right: 2, }) // -> 42 ``` This functionality is flagged as `EXPERIMENTAL` and awaits community feedback.sinclairzx81-typebox-e0ec98c/changelog/0.18.0.md000066400000000000000000000024311505437577000212550ustar00rootroot00000000000000## [0.18.0](https://www.npmjs.com/package/@sinclair/typebox/v/0.18.0) Changes: - Function `Type.Intersect(...)` is now implemented with `allOf` and constrained with `unevaluatedProperties` (draft `2019-09`) - Function `Type.Dict(...)` has been deprecated and replaced with `Type.Record(...)`. - Function `Type.Strict(...)` now includes the `$schema` property referencing the `2019-09` draft. ### Type.Intersect(...) TypeBox now targets JSON schema draft `2019-09` for expressing `Type.Intersect(...)`. This is now expressed via `allOf` with additionalProperties constrained with `unevaluatedProperties`. Note that `unevaluatedProperties` is a feature of the `2019-09` specification. ### Type.Record(K, V) TypeBox has deprecated `Type.Dict(...)` in favor of the more generic `Type.Record(...)`. Where as `Type.Dict(...)` was previously expressed with `additionalProperties: { ... }`, `Type.Record(...)` is expressed with `patternProperties` and supports both `string` and `number` indexer keys. Additionally, `Type.Record(...)` supports string union arguments. This is analogous to TypeScript's utility record type `Record<'a' | 'b' | 'c', T>`. ## [0.17.7](https://www.npmjs.com/package/@sinclair/typebox/v/0.17.7) Changes: - Added optional `$id` argument on `Type.Rec()`. - Documentation updates.sinclairzx81-typebox-e0ec98c/changelog/0.18.1.md000066400000000000000000000006561505437577000212650ustar00rootroot00000000000000## [0.18.1](https://www.npmjs.com/package/@sinclair/typebox/v/0.18.1) - Function `Type.Enum(...)` now expressed with `anyOf`. This to remove the `allowUnionTypes` configuration required to use `enum` with in AJV strict. - Function `Type.Rec(...)` now takes a required `$id` as the first parameter. - Function `Type.Strict(...)` no longer includes a `$schema`. Callers can now optionally pass `CustomOptions` on `Type.Strict(...)`sinclairzx81-typebox-e0ec98c/changelog/0.19.0.md000066400000000000000000000013031505437577000212530ustar00rootroot00000000000000## [0.19.0](https://www.npmjs.com/package/@sinclair/typebox/v/0.19.0) Updates: - Function `Type.Box(...)` removes `$id` parameter as first argument. - Function `Type.Ref(...)` is now overloaded to support referencing `Type.Box(...)` and `TSchema`. Notes: This update changes the signature of `Type.Box(...)` and removes the explicit `$id` passing on the first parameter. The `$id` must be passed as an option if the caller wants to reference that type. ```typescript const T = Type.String({ $id: 'T' }) const B = Type.Box({ T }, { $id: 'B' }) const R1 = Type.Ref(T) // const R1 = { $ref: 'T' } const R2 = Type.Ref(B, 'T') // const R2 = { $ref: 'B#/definitions/T' } ```sinclairzx81-typebox-e0ec98c/changelog/0.20.0.md000066400000000000000000000011741505437577000212510ustar00rootroot00000000000000## [0.20.0](https://www.npmjs.com/package/@sinclair/typebox/v/0.20.0) Updates: - Function `Type.Rec(...)` signature change. - Minor documentation updates. Notes: The `Type.Rec(...)` function signature has been changed to allow passing the `$id` as a custom option. This is to align `Type.Rec(...)` with other functions that accept `$id` as an option. `Type.Rec(...)` can work with or without an explicit `$id`, but it is recommend to specify one if the recursive type is nested in an outer schema. ```typescript const Node = Type.Rec(Self => Type.Object({ id: Type.String(), nodes: Type.Array(Self) }), { $id: 'Node' }) ```sinclairzx81-typebox-e0ec98c/changelog/0.20.1.md000066400000000000000000000002221505437577000212430ustar00rootroot00000000000000## [0.20.1](https://www.npmjs.com/package/@sinclair/typebox/v/0.20.1) Updates: - TypeBox mandates TypeScript compiler version `4.3.5` and above.sinclairzx81-typebox-e0ec98c/changelog/0.21.0.md000066400000000000000000000010161505437577000212450ustar00rootroot00000000000000## [0.21.0](https://www.npmjs.com/package/@sinclair/typebox/v/0.21.0) Updates: - TypeBox static inference has been updated inline with additional inference constraints added in TypeScript 4.5. All types now include a phantom `_infer` property which contains the inference TS type for a given schema. The type of this property is inferred at the construction of the schema, and referenced directly via `Static`. - `Type.Box(...)` has been renamed to `Type.Namespace(...)` to draw an analogy with XML's `xmlns` XSD types. sinclairzx81-typebox-e0ec98c/changelog/0.21.2.md000066400000000000000000000012561505437577000212550ustar00rootroot00000000000000## [0.21.2](https://www.npmjs.com/package/@sinclair/typebox/v/0.21.2) Updates: - TypeBox now correctly infers for nested union and intersect types. Before ```typescript const A = Type.Object({ a: Type.String() }) const B = Type.Object({ b: Type.String() }) const C = Type.Object({ c: Type.String() }) const T = Type.Intersect([A, Type.Union([B, C])]) // type T = { a: string } & { b: string } & { c: string } ``` After ```typescript const A = Type.Object({ a: Type.String() }) const B = Type.Object({ b: Type.String() }) const C = Type.Object({ c: Type.String() }) const T = Type.Intersect([A, Type.Union([B, C])]) // type T = { a: string } & ({ b: string } | { c: string }) ```sinclairzx81-typebox-e0ec98c/changelog/0.22.0.md000066400000000000000000000016771505437577000212630ustar00rootroot00000000000000## [0.22.0](https://www.npmjs.com/package/@sinclair/typebox/v/0.22.0) Updates: - The type `TSchema` is now expressed as an HKT compatible interface. All types now extend the `TSchema` interface and are themselves also expressed as interfaces. This work was undertaken to explore recursive type aliases in future releases. - The phantom property `_infer` has been renamed to `$static`. Callers should not interact with this property as it will always be `undefined` and used exclusively for optimizing type inference in TypeScript 4.5 and above. - TypeBox re-adds the feature to deeply introspect schema properties. This feature was temporarily removed on the `0.21.0` update to resolve deep instantiation errors on TypeScript 4.5. - The `Type.Box(...)` and `Type.Rec(...)` functions internally rename the property `definitions` to `$defs` inline with JSON schema draft 2019-09 conventions. Reference [here](https://opis.io/json-schema/2.x/definitions.html).sinclairzx81-typebox-e0ec98c/changelog/0.23.0.md000066400000000000000000000015471505437577000212600ustar00rootroot00000000000000## [0.23.0](https://www.npmjs.com/package/@sinclair/typebox/v/0.23.0) Updates: - The types `Type.Namespace(...)` and `Type.Ref(...)` are promoted to `Standard`. - TypeBox now includes an additional type named `TRef<...>` that is returned on calls to `Type.Ref(...)`. The `TRef<...>` includes a new `RefKind` symbol for introspection of the reference type. - TypeBox now maintains an internal dictionary of all schemas passed that contain an `$id` property. This dictionary is checked whenever a user attempts to reference a type and will throw if attempting to reference a target schema with no `$id`. - The types `Type.Partial(...)`, `Type.Required(...)`, `Type.Omit()` and `Type.Pick(...)` now support reference types. Note that when using these functions with references, TypeBox will replicate the source schema and apply the necessary modifiers to the replication.sinclairzx81-typebox-e0ec98c/changelog/0.23.1.md000066400000000000000000000002361505437577000212530ustar00rootroot00000000000000## [0.23.1](https://www.npmjs.com/package/@sinclair/typebox/v/0.23.1) Updates: - The `Type.KeyOf(...)` type can now accept references of `Type.Ref(TObject)`sinclairzx81-typebox-e0ec98c/changelog/0.23.3.md000066400000000000000000000001671505437577000212600ustar00rootroot00000000000000## [0.23.3](https://www.npmjs.com/package/@sinclair/typebox/v/0.23.3) Updates: - Fix: Rename BoxKind to NamespaceKindsinclairzx81-typebox-e0ec98c/changelog/0.24.0.md000066400000000000000000000040771505437577000212620ustar00rootroot00000000000000## [0.24.0](https://www.npmjs.com/package/@sinclair/typebox/v/0.24.0) Changes: - The `kind` and `modifier` keywords are now expressed as symbol keys. This change allows AJV to leverage TypeBox schemas directly without explicit configuration of `kind` and `modifier` in strict mode. - `Type.Intersect([...])` now returns a composite `TObject` instead of a `allOf` schema representation. This change allows intersected types to be leveraged in calls to `Omit`, `Pick`, `Partial`, `Required`. - `Type.Void(...)` now generates a `{ type: null }` schema representation. This is principally used for RPC implementations where a RPC target function needs to respond with a serializable value for `void` return. - `Type.Rec(...)` renamed to `Type.Recursive(...)` and now supports non-mutual recursive type inference. Added: - `Type.Unsafe(...)`. This type enables custom schema representations whose static type is informed by generic type T. - `Type.Uint8Array(...)`. This is a non-standard schema that can be configured on AJV to enable binary buffer range validation. - Added optional extended `design` property on all schema options. This property can be used to specify design time metadata when rendering forms. Compiler: - TypeBox now provides an optional experimental type compiler that can be used to validate types without AJV. This compiler is not a standard JSON schema compiler and will only compile TypeBox's known schema representations. For full JSON schema validation, AJV should still be the preference. This compiler is a work in progress. Value: - TypeBox now provides a value generator that can generate default values from TypeBox types. Breaking Changes: - `Type.Intersect(...)` is constrained to accept types of `TObject` only. - `Type.Namespace(...)` has been removed. - The types `TUnion`, `TEnum`, `KeyOf` and `TLiteral[]` are all now expressed via `allOf`. For Open API users, Please consider `Type.Unsafe()` to express `enum` string union representations. Documentation on using `Type.Unsafe()` can be found [here](https://github.com/sinclairzx81/typebox#Unsafe-Types)sinclairzx81-typebox-e0ec98c/changelog/0.24.15.md000066400000000000000000000017231505437577000213430ustar00rootroot00000000000000## [0.24.15](https://www.npmjs.com/package/@sinclair/typebox/v/0.24.15) Added: - `Conditional.Extends(...)` This enables TypeBox to conditionally map types inline with TypeScripts structural equivalence checks. Tested against TypeScript 4.7.4. - `Conditional.Extract(...)` Which analogs TypeScripts `Extract<...>` utility type. Additional information [here](https://www.typescriptlang.org/docs/handbook/utility-types.html#extracttype-union) - `Conditional.Exclude(...)` Which analogs TypeScripts `Exclude<...>` utility type. Additional information [here](https://www.typescriptlang.org/docs/handbook/utility-types.html#excludeuniontype-excludedmembers) - `Type.Parameters(...)` Returns the parameters of a `TFunction` as a `TTuple` - `Type.ReturnType(...)` Returns the return type schema of a `TFunction` - `Type.ConstructorParameters(...)` Returns the parameters of a `TConstructor` as a `TTuple` - `Type.InstanceType(...)` Returns the instance type schema of a `TConstructor`sinclairzx81-typebox-e0ec98c/changelog/0.24.44.md000066400000000000000000000102771505437577000213510ustar00rootroot00000000000000## [0.24.44](https://www.npmjs.com/package/@sinclair/typebox/v/0.24.44) Updates: - [189](https://github.com/sinclairzx81/typebox/pull/189) Both `Value.Error(T, value)` and `TypeCheck.Error(value)` now return an iterator for validation errors. - [191](https://github.com/sinclairzx81/typebox/pull/191) TypeBox now provides a `TypeGuard` API that can be used to check the structural validity of TypeBox type. The TypeGuard can be used in reflection / code generation scenarios to resolve the appropriate inner `TSchema` type while traversing a outer type. - [197](https://github.com/sinclairzx81/typebox/pull/197) TypeBox now implements conditional runtime type mapping. This functionality is offered as separate import for the `0.24.0` release but may be provided as standard type in later releases. This API enables `type T = Foo extends Bar ? true : false` conditional checks to be implemented at runtime. This API also provides the `Exclude` and `Extract` utility types which are implemented through conditional types in TypeScript. - [199](https://github.com/sinclairzx81/typebox/pull/199) TypeBox now provides better support for variadic function and constructor signatures. Currently variadic types are mapped as `Tuple` types. - [200](https://github.com/sinclairzx81/typebox/pull/200) The types `TPick` and `TOmit` now support types of `TUnion[]>` to be used to select properties. Additionally, `KeyOf` now returns `TUnion[]>`, allowing `KeyOf` schemas to be passed to `TPick` and `TOmit`. - [214](https://github.com/sinclairzx81/typebox/pull/214) TypeBox now provides better support for i18n. To achieve this, TypeBox includes fixed mappable error codes on the `ValueError` type. These codes can be used by external implementers to create localized error messages. TypeBox may include localized error codes as an optional import in future releases. - [288](https://github.com/sinclairzx81/typebox/pull/228) TypeBox now allows users to implement custom string validator formats. These formats are internally shared between the `Value` and `TypeCompiler` API's. TypeBox does not currently provide any built in formats, however the standard expected set (email, uuid, uri, etc) may be provided via optional import (inline with ajv-formats usage) - [229](https://github.com/sinclairzx81/typebox/pull/229) The `Value.Cast()` function now implements automatic coercion of string, number and Boolean types. - [231](https://github.com/sinclairzx81/typebox/pull/231) TypeBox provides a new `Value.Diff()` and `Value.Patch()` utility API for JavaScript values. This API is intended to provide a basis for the efficient transmission of state updates across a network. This API can diff any JavaScript value (typed or untyped) but is recommended to be used in conjunction with a formal static type. - [236](https://github.com/sinclairzx81/typebox/pull/236) TypeBox now implements the `TNever` type. This type is analogous to TypeScript's `never` type and is used in instances a composition results in a non-reconcilable type. Currently this type is implemented for empty `TUnion<[]>` types only. Future releases may utilize this type for planned updates to `TIntersect` (for example `string & number` resolves to `never`) - [241](https://github.com/sinclairzx81/typebox/pull/241) [247](https://github.com/sinclairzx81/typebox/pull/247) TypeBox now exposes a ValuePointer API that can be used to mutate a value via an RFC6901 JSON Pointer. Previously this functionality was internally used by `Value.Diff()` and `Value.Patch()` functions but is now offered as an optional import for implementations that need to update values manually through pointer references. Additional: - This project now includes two reference code generation utilities that can be used in custom build tooling. The first is `TypeScriptCodeGen` which will remap TypeScript `interface` and `type` definitions to TypeBox types. The second is `TypeBoxCodeGen` which will map existing TypeBox types into TypeScript type definitions. These implementations are not expected to be part of the TypeBox package, but users are free to clone and enhance them in their existing tool chains. Reference implementations can be found https://github.com/sinclairzx81/typebox/tree/master/codegensinclairzx81-typebox-e0ec98c/changelog/0.24.49.md000066400000000000000000000010061505437577000213440ustar00rootroot00000000000000## [0.24.49](https://www.npmjs.com/package/@sinclair/typebox/v/0.24.49) Updates: - [264](https://github.com/sinclairzx81/typebox/pull/264) TypeBox now provides preliminary support for non Boolean `additionalProperties`. This allows existing `TObject` schemas to be augmented with additional properties of a known type. Additional: - TypeBox provides an additional reference `codegen` module for generating raw JSON Schema from TypeScript types via the TS compiler API. This generator may be used in future tooling.sinclairzx81-typebox-e0ec98c/changelog/0.24.6.md000066400000000000000000000013001505437577000212520ustar00rootroot00000000000000## [0.24.6](https://www.npmjs.com/package/@sinclair/typebox/v/0.24.6) Added: - TypeBox now offers a `TypeGuard` module for structurally checking TypeBox schematics. This module can be used in runtime type reflection scenarios where it's helpful to test a schema is of a particular form. This module can be imported under the `@sinclair/typebox/guard` import path. Example: ```typescript import { TypeGuard } from '@sinclair/typebox/guard' const T: any = {} // T is any const { type } = T // unsafe: type is any if(TypeGuard.IsString(T)) { const { type } = T // safe: type is 'string' } ```sinclairzx81-typebox-e0ec98c/changelog/0.24.8.md000066400000000000000000000006611505437577000212650ustar00rootroot00000000000000## [0.24.8](https://www.npmjs.com/package/@sinclair/typebox/v/0.24.8) Added: - `Value.Cast(T, value)` structurally casts a value into another form while retaining information within the original value. - `Value.Check(T, value)` provides slow dynamic type checking for values. For performance, one should consider the `TypeCompiler` or `Ajv` validator. - `Value.Errors(T, value)` returns an iterator of errors found in a given value.sinclairzx81-typebox-e0ec98c/changelog/0.25.0.md000066400000000000000000000017361505437577000212620ustar00rootroot00000000000000## [0.25.0](https://www.npmjs.com/package/@sinclair/typebox/v/0.25.0) Updates: - [271](https://github.com/sinclairzx81/typebox/pull/271) Adds a new non-standard `Type.Date()` type. This type joins the existing `Type.UInt8Array()` as a promoted extended type used to represent core JavaScript primitives. It's inclusion was prompted by end user requirements to validate Date objects prior to writing them to Date supported API's and where serialization of the Date object is handled internally by the API. - [271](https://github.com/sinclairzx81/typebox/pull/271) Redesign of Extended Type representations. Extended types been updated to provide external validators (such as Ajv) additional standard proporties to use when defining the custom schema. These properties are `instanceOf` (used for validating a class `object` instances), and `typeOf` (when validating `value` types). Information on configuring AJV for these properties can be found in the AJV section of the TypeBox readme.sinclairzx81-typebox-e0ec98c/changelog/0.25.10.md000066400000000000000000000006131505437577000213340ustar00rootroot00000000000000## [0.25.10](https://www.npmjs.com/package/@sinclair/typebox/v/0.25.10) Updates: - [283](https://github.com/sinclairzx81/typebox/pull/283) Updates the custom type validator callback signature to accept a schema instance. The schema instance may include additional constraints (such as options) that may be used during the validation process. `Custom.Set('', (schema, value) => { ... })`.sinclairzx81-typebox-e0ec98c/changelog/0.25.11.md000066400000000000000000000013601505437577000213350ustar00rootroot00000000000000## [0.25.11](https://www.npmjs.com/package/@sinclair/typebox/v/0.25.11) Updates: - [286](https://github.com/sinclairzx81/typebox/pull/286) implements a FNV1A-64 non cryptographic hashing function in TypeBox. This function should not be used in place of cryptographic hashing functions, rather it's purpose is to provide relatively fast, hashing mechanism to assist with checks for arrays with uniqueItems constraints, specifically for cases where the array may contains reference values (such as objects, arrays, Dates and Uint8Array). This function is provided via `Value.Hash()` for convenience as the hash may be useful to generate a numeric identifier for values (with some considerations to React array rendering in absence of key or identifier)sinclairzx81-typebox-e0ec98c/changelog/0.25.18.md000066400000000000000000000007431505437577000213500ustar00rootroot00000000000000## [0.25.18](https://www.npmjs.com/package/@sinclair/typebox/v/0.25.18) Updates: - [307](https://github.com/sinclairzx81/typebox/pull/307) implements date conversion when casting values with `Value.Cast(Type.Date(), ...)`. Castable values include numbers (interpretted as timestamps) and iso8601 string values. UNCASTABLE values will result in dates with values of `1970-01-01T00:00:00.000Z`. This version also includes more robust checks for Dates initialized with invalid values.sinclairzx81-typebox-e0ec98c/changelog/0.25.22.md000066400000000000000000000003341505437577000213370ustar00rootroot00000000000000## [0.25.22](https://www.npmjs.com/package/@sinclair/typebox/v/0.25.22) Updates: - [323](https://github.com/sinclairzx81/typebox/pull/323) adds compiler support for UTF-16 (unicode) characters for schema identifiers. sinclairzx81-typebox-e0ec98c/changelog/0.25.23.md000066400000000000000000000007341505437577000213440ustar00rootroot00000000000000## [0.25.23](https://www.npmjs.com/package/@sinclair/typebox/v/0.25.23) Updates: - [324](https://github.com/sinclairzx81/typebox/pull/324) TypeScript Language Service now presents JSDoc comments when inferring static object properties. (IntelliSense) - [325](https://github.com/sinclairzx81/typebox/pull/325) Additional property inference optimizations. Additional: - Huge thank you to GITHUB user [stevezhu](https://github.com/stevezhu) for these excellent contributions.sinclairzx81-typebox-e0ec98c/changelog/0.25.24.md000066400000000000000000000010361505437577000213410ustar00rootroot00000000000000## [0.25.24](https://www.npmjs.com/package/@sinclair/typebox/v/0.25.23) Updates: - [331](https://github.com/sinclairzx81/typebox/pull/331) Implements an additional check specific to property types of `required & undefined`. This to ensure the property key exists when the property value extends `undefined`. - [331](https://github.com/sinclairzx81/typebox/pull/331) Documentation updates for AJV and TypeCompiler Additional: - [331](https://github.com/sinclairzx81/typebox/pull/331) Remove unused recursive code paths for create and cast.sinclairzx81-typebox-e0ec98c/changelog/0.25.9.md000066400000000000000000000006441505437577000212700ustar00rootroot00000000000000## [0.25.9](https://www.npmjs.com/package/@sinclair/typebox/v/0.25.9) Updates: - [282](https://github.com/sinclairzx81/typebox/pull/282) TypeBox now supports custom types. These types require the user to specify a custom `[Kind]` string on the type. Custom types can be registered via `Custom.Set('', (value) => { ... })` which allow the TypeCompiler and Value API's to make use of user defined validation logic.sinclairzx81-typebox-e0ec98c/changelog/0.26.0.md000066400000000000000000000363251505437577000212650ustar00rootroot00000000000000## [0.26.0](https://www.npmjs.com/package/@sinclair/typebox/v/0.26.0) ## Overview TypeBox now provides "runtime conditional types" (formally the `Conditional` module) as standard on `Type.*`. Additional updates in this revision include automatic union and intersection unwrap, universal support for utility types, several ergonomic enhancements and additional options for framework integrators. This revision also carries out a number an internal refactorings to reduce the amount of submodule imports. Revision 0.26.0 is a milestone release for the TypeBox project and requires a minor semver update. ## Contents - Enhancements - [Standard Type Builder](#Standard-Type-Builder) - [Automatic Unwrap for Union and Intersect](#Automatic-Unwrap-for-Union-and-Intersect) - [Intersect and Union now Compose](#Intersect-and-Union-now-Compose) - [Runtime Conditional Types](#Runtime-Conditional-Types) - [Value Convert](#Value-Convert) - [Error Iterator](#Error-Iterator) - [Codegen without JIT](#Codegen-without-JIT) - [Standard Type (Composite)](#Standard-Type-Composite) - [Standard Type (Not)](#Standard-Type-Not) - [Extended Type (BigInt)](#Extended-Type-BigInt) - [Extended Type (Symbol)](#Extended-Type-Symbol) - Breaking - [Minimum TypeScript Version](#Minimum-TypeScript-Version) - [Intersect Schema Representation](#Intersect-Schema-Representation) - [Never Schema Representation](#Never-Schema-Representation) - [Value Cast and Convert](#Value-Cast-and-Convert) - [Moved TypeGuard Module](#Moved-TypeGuard-Module) - [Format Renamed to FormatRegistry](#Format-Renamed-to-FormatRegistry) - [Custom Renamed to TypeRegistry](#Custom-Renamed-to-TypeRegistry) ## Standard Type Builder Revision 0.26.0 exports a new type builder called `StandardType`. This builder only allows for the construction JSON Schema compliant types by omitting all Extended types. ```typescript import { StandardType as Type, Static } from '@sinclair/typebox' const T = Type.Date() // error: no such function ``` ## Automatic Unwrap for Union and Intersect Revision 0.26.0 will automatically unwrap unions and intersections for the following cases. ```typescript const T1 = Type.Union([Type.String(), Type.Number()]) // TUnion<[TString, TNumber]> const T2 = Type.Union([Type.String()]) // TString const T3 = Type.Union([]) // TNever ``` ## Intersect and Union now Compose Revision 0.26.0 re-enables support for union and intersection type composition. These types are also made compatible with `Pick`, `Omit`, `Partial`, `Required` and `KeyOf` utility types. ```typescript const A = Type.Object({ type: Type.Literal('A') }) const B = Type.Object({ type: Type.Literal('B') }) const C = Type.Object({ type: Type.Literal('C') }) const Union = Type.Union([A, B, C]) const Extended = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number() }) const T = Type.Intersect([Union, Extended]) // type T = ({ // type: "A"; // } | { // type: "B"; // } | { // type: "C"; // }) & { // x: number; // y: number; // z: number; // } const K = Type.KeyOf(T) // type K = "type" | "x" | "y" | "z" const P = Type.Pick(T, ['type', 'x']) // type P = ({ // type: "A"; // } | { // type: "B"; // } | { // type: "C"; // }) & { // x: number; // } const O = Type.Partial(P) // type O = ({ // type?: "A" | undefined; // } | { // type?: "B" | undefined; // } | { // type?: "C" | undefined; // }) & { // x?: number | undefined; // } ``` ## Runtime Conditional Types Revision 0.26.0 adds the runtime conditional types `Extends`, `Extract` and `Exclude` as standard. #### TypeScript ```typescript type T0 = string extends number ? true : false // ^ false type T1 = Extract // ^ number type T2 = Exclude // ^ string ``` #### TypeBox ```typescript const T0 = Type.Extends(Type.String(), Type.Number(), Type.Literal(true), Type.Literal(false)) // ^ TLiteral const T1 = Type.Extract(Type.Union([Type.String(), Type.Number()]), Type.Number()) // ^ TNumber const T2 = Type.Exclude(Type.Union([Type.String(), Type.Number()]), Type.Number()) // ^ TString ``` ## Value Convert Revision 0.26.0 adds a new `Convert` function to the `Value.*` module. This function will perform a type coercion for any value mismatched to its type if a reasonable conversion is possible. ```typescript const T = Type.Number() const A = Value.Convert(T, '42') // const A: unknown = 42 - ... Convert(...) will return `unknown` const B = Value.Check(T, A) // const B = true - ... so should be checked ``` ## Error Iterator Revision 0.26.0 now returns a `ValueErrorIterator` for `.Errors(...)`. This iterator provides a utility function to obtain the first error only. To obtain all errors, continue to use `for-of` enumeration or array spread syntax. ```typescript const T = Type.Number() const First = Value.Errors(T, 'foo').First() // const First = { path: '', message: 'Expected number', ... } const All = [...Value.Errors(T, 'foo')] // const All = [{ path: '', message: 'Expected number', ... }] ``` ## Codegen without JIT Revision 0.26.0 adds a `.Code()` function to the `TypeCompiler` to enable code generation without JIT evaluation. ```typescript import { TypeCompiler } from '@sinclair/typebox/compiler' const T = Type.Object({ x: Type.Number(), y: Type.Number() }) const C = TypeCompiler.Code(T) // return function check(value) { // return ( // (typeof value === 'object' && value !== null) && // !Array.isArray(value) && // typeof value.x === 'number' && // Number.isFinite(value.x) && // typeof value.y === 'number' && // Number.isFinite(value.y) // ) // } ``` ## Standard Type (Not) Revision 0.26.0 introduces the `Not` standard type. This type allows for the inversion of assertion logic which can be useful to narrow for broader types. #### Example 1 ```typescript const T = Type.Not(Type.String({ pattern: 'A|B|C' }), Type.String()) Value.Check(T, 'A') // false Value.Check(T, 'B') // false Value.Check(T, 'C') // false Value.Check(T, 'D') // true ``` #### Example 2 ```typescript const Even = Type.Number({ multipleOf: 2 }) const Odd = Type.Not(Even, Type.Number()) Value.Check(Even, 0) // true Value.Check(Even, 1) // false Value.Check(Even, 2) // true Value.Check(Odd, 0) // false Value.Check(Odd, 1) // true Value.Check(Odd, 2) // false ``` ## Standard Type (Composite) Revision 0.26.0 includes a new `Composite` standard type. This type will combine an array of `TObject[]` into a `TObject` by taking a union of any overlapping properties. ```typescript const A = Type.Object({ type: Type.Literal('A') }) const B = Type.Object({ type: Type.Literal('B') }) const C = Type.Object({ type: Type.Literal('C'), value: Type.Number() }) const T = Type.Composite([A, B, C]) // type T = { // type: 'A' | 'B' | 'C' // value: number // } ``` ## Extended Type (Symbol) Revision 0.26.0 provides provisional support for `Symbol` type validation. ```typescript const T = Type.Symbol() Value.Check(A, Symbol('Foo')) // true ``` ## Extended Type (BigInt) Revision 0.26.0 provides provisional support for `BigInt` type validation. ```typescript const T = Type.BigInt({ minimum: 10n }) Value.Check(B, 1_000_000n) // true ``` ## Breaking Changes The following are breaking changed in Revision 0.26.0 ## Minimum TypeScript Version Revision 0.26.0 requires a minimum recommended TypeScript version of `4.2.3`. Version `4.1.5` is no longer supported. ## Intersect Schema Representation Revision 0.26.0 changes the schema representation for `Intersect`. Revision 0.25.0 would construct a composite `object` type, in 0.26.0, `Intersect` is expressed as `anyOf`. If upgrading, consider using `Type.Composite(...)` to return backwards compatible representations. #### Intersect 0.25.0 ```typescript const T = Type.Intersect([ // const U = { Type.Object({ // type: 'object', x: Type.Number(), // required: ['x', 'y'], }), // properties: { Type.Object({ // x: { y: Type.Number(), // type: 'number' }) // }, ]) // y: { // type: 'number' // } // } // } ``` #### Intersect 0.26.0 ```typescript const T = Type.Intersect([ // const U = { Type.Object({ // type: 'object', x: Type.Number(), // allOf: [{ }), // type: 'object', Type.Object({ // required: [ 'x' ], y: Type.Number(), // properties: { }) // x: { type: 'number' } ]) // } // }, { // type: 'object', // required: ['y'], // properties: { // y: { type: 'number' } // } // }] // } ``` ## Never Schema Representation Revision 0.26.0 simplifies the representation for `TNever`. Previous versions of TypeBox used an illogical intersection of Boolean constants via `allOf`. In 0.26.0, `never` is expressed as a `not` schema of type `any`. #### Intersect 0.25.0 ```typescript const T = Type.Never() // const T = { // allOf: [ // { type: 'boolean', const: true } // { type: 'boolean', const: false } // ] // } ``` #### Intersect 0.26.0 ```typescript const T = Type.Never() // const T = { not: {} } ``` ## Value Cast and Convert Revision 0.26.0 removes the `Cast` functions ability to coerce values. Use the new `Convert` function prior to `Cast`. ```typescript const T = Type.Number() const V = Value.Cast(T, '42') // const V = 42 - 0.25.0 coerces to 42 const V = Value.Cast(T, Value.Convert(T, '42')) // const V = 42 - 0.26.0 convert then cast ``` ## Moved TypeGuard Module The `TypeGuard` is now imported via the `@sinclair/typebox` module. This move is due to the TypeBox compositor internally using the guard when constructing types. ```typescript import { TypeGuard } from '@sinclair/typebox/guard' // 0.25.0 import { TypeGuard } from '@sinclair/typebox' // 0.26.0 ``` ## Format Renamed to FormatRegistry The `Format` module has been renamed to `FormatRegistry` and moved to the `typebox.ts` module. ```typescript import { Format } from '@sinclair/typebox/format' // 0.25.0 import { FormatRegistry } from '@sinclair/typebox' // 0.26.0 ``` ## Custom Renamed to TypeRegistry The `Format` module has been renamed to `FormatRegistry` and moved to the `typebox.ts` module. ```typescript import { Custom } from '@sinclair/typebox/format' // 0.25.0 import { TypeRegistry } from '@sinclair/typebox' // 0.26.0 ```sinclairzx81-typebox-e0ec98c/changelog/0.26.2.md000066400000000000000000000035331505437577000212620ustar00rootroot00000000000000## [0.26.2](https://www.npmjs.com/package/@sinclair/typebox/v/0.26.2) Updates: - [331](https://github.com/sinclairzx81/typebox/pull/349) Revert 0.25.0 Intersect logic for Composite Notes: This PR reverts the logic on Type.Composite back to 0.25.0 Type.Intersect due to excessive type instantiation issues. On 0.26.0, Type.Composite attempted to take a union for overlapping properties, however due to the sophistication required to type map the unions for overlapping properties, this has resulted in type instantiation problems for some users upgrading to 0.26.0. As such, 0.26.2 reverts back to the 0.25.0 interpretation, but applies type mappings more inline with TS's interpretation of an overlapping varying property types. In the examples below, the type `C` is the evaluated type for Type.Composite. Note that TS will not union for overlapping properties and instead evaluate `never`. The 0.26.2 implementation falls inline with this evaluation. ```typescript { // evaluation case 1: non-varying type T = { a: number } & { a: number } type C = {[K in keyof T]: T[K] } // type C = { a: number } } { // evaluation case 2: varying type T = { a: number } & { a: string } type C = {[K in keyof T]: T[K] } // type C = { a: never } } { // evaluation case 3: single optional type T = { a?: number } & { a: number } type C = {[K in keyof T]: T[K] } // type C = { a: number } } { // evaluation case 4: all optional type T = { a?: number } & { a?: number } type C = {[K in keyof T]: T[K] } // type C = { a?: number | undefined } } ``` Note: the Type.Composite is intended to be a temporary type which can be replaced with a more general `Type.Mapped` in future revisions of TypeBox. As the infrastructure to support mapped types does not exist, users can use Type.Composite to partially replicate mapped type evaluation for composited object types only. sinclairzx81-typebox-e0ec98c/changelog/0.27.0.md000066400000000000000000000175731505437577000212720ustar00rootroot00000000000000## [0.27.0](https://www.npmjs.com/package/@sinclair/typebox/v/0.27.0) ## Overview Revision 0.27.0 adds support for runtime [Template Literal Types](https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html). This revision does not include any functional breaking changes but does rename some public type aliases. As such this revision requires a minor semver increment. ## Contents - Enhancements - [Template Literal Types](#Template-Literal-Types) - [TemplateLiteralParser](#TemplateLiteralParser) - [WorkBench](#WorkBench) - Breaking Changes - [TSelf renamed to TThis](#TSelf-renamed-to-TThis) ## Template Literal Types Revision 0.27.0 adds support for Template Literal types. These types operate as a form of computed `TUnion>`. TypeBox encodes template literals using a subset of [ECMA 262](https://json-schema.org/understanding-json-schema/reference/regular_expressions.html) regular erxpressions which are applied to `pattern` properties of type `string`. This encoding enables JSON Schema validators to assert using existing regular expression checks. ### TypeScript TypeScript defines Template Literals using back tick quoted strings which may include embedded union groups. ```typescript type T = `option${'A'|'B'}` // type T = 'optionA' | 'optionB' type R = Record // type R = { // optionA: string // optionB: string // } ``` ### TypeBox TypeBox defines Template Literals using the `TemplateLiteral` function. This function accepts a sequence of TLiteral, TString, TNumber, TInteger and TBigInt which describe a sequence concatenations. The embedded TUnion type defines an option group which can later be expanded into a set of `TLiteral`. This expansion enables Template Literal types to also be used as Record keys. ```typescript const T = Type.TemplateLiteral([ // const T = { Type.Literal('option'), // pattern: '^option(A|B)$', Type.Union([ // type: 'string' Type.Literal('A'), // } Type.Literal('B') ]) ]) const R = Type.Record(T, Type.String()) // const R = { // type: 'object', // required: ['optionA', 'optionB'], // properties: { // optionA: { // type: 'string' // }, // optionB: { // type: 'string' // } // } // } type T = Static // type T = 'optionA' | 'optionB' type R = Static // type R = { // optionA: string // optionB: string // } ``` ## TemplateLiteralParser Template Literal types are encoded as `string` patterns. Because these types also need to act as composable union types, Revision 0.27.0 includes an expression parser / generator system specifically for regular expressions. This system is used during composition to allow templates to compose with other types, but can also be used in isolation to generate string sequences for the supported expression grammar. This functionality may be provided as standard on the `Value.*` sub module in subsequent revisions. The following generates a 8-bit binary sequence for the given expression. ```typescript import { TemplateLiteralParser, TemplateLiteralGenerator, TemplateLiteralFinite } from '@sinclair/typebox' const Bit = `(0|1)` // bit union const Byte = `${Bit}${Bit}${Bit}${Bit}${Bit}${Bit}${Bit}${Bit}` // byte sequence const E = TemplateLiteralParser.Parse(Byte) // parsed expression tree const F = TemplateLiteralFinite.Check(E) // is the expression finite? const S = [...TemplateLiteralGenerator.Generate(E)] // generate sequence // const S = [ // computed sequence // '00000000', '00000001', '00000010', '00000011', '00000100', // '00000101', '00000110', '00000111', '00001000', '00001001', // '00001010', '00001011', '00001100', '00001101', '00001110', // '00001111', '00010000', '00010001', '00010010', '00010011', // '00010100', '00010101', '00010110', '00010111', '00011000', // '00011001', '00011010', '00011011', '00011100', '00011101', // '00011110', '00011111', '00100000', '00100001', '00100010', // '00100011', '00100100', '00100101', '00100110', '00100111', // '00101000', '00101001', '00101010', '00101011', '00101100', // '00101101', '00101110', '00101111', '00110000', '00110001', // '00110010', '00110011', '00110100', '00110101', '00110110', // '00110111', '00111000', '00111001', '00111010', '00111011', // '00111100', '00111101', '00111110', '00111111', '01000000', // '01000001', '01000010', '01000011', '01000100', '01000101', // '01000110', '01000111', '01001000', '01001001', '01001010', // '01001011', '01001100', '01001101', '01001110', '01001111', // '01010000', '01010001', '01010010', '01010011', '01010100', // '01010101', '01010110', '01010111', '01011000', '01011001', // '01011010', '01011011', '01011100', '01011101', '01011110', // '01011111', '01100000', '01100001', '01100010', '01100011', // ... 156 more items // ] ``` ## Workbench To assist with TypeScript alignment and to prototype new features. A new web based compiler tool has been written that allows interactive cross compiling between TypeScript and TypeBox. This tool will be enhanced seperately from the TypeBox project, but can be used to quickly generate TypeBox type definitions from existing TypeScript types. [TypeBox Workbench Application](https://sinclairzx81.github.io/typebox-workbench) [TypeBox Workbench Project](https://github.com/sinclairzx81/typebox-workbench) ## Breaking Changes The following are breaking changes in Revision 0.27.0 ## TSelf renamed to TThis This rename is to align with TypeScript interfaces. Unlike `type` aliases, TypeScript `interface` types include a implicit `this` type. This change relates specifically to TypeBox's current Recursive type which passes the `TThis` parameter via callback. The `TThis` parameter can be seen as analogous to the implicit TypeScript interface `this`. Consider the following. ```typescript // type T = { id: string, nodes: this[] } // error: no implicit this interface Node { // ok: this is implicit for interfaces id: string, nodes: this[] } const T = Type.Recursive(This => // `This` === implicit 'this' for interface Type.Object({ // id: Type.String(), // Should `Recursive` be renamed to `Interface`? nodes: Type.Array(This) }) ) ``` Future revisions may rename `Recurisve` to `Interface`, but for now, just the `TSelf` has been renamed.sinclairzx81-typebox-e0ec98c/changelog/0.27.1.md000066400000000000000000000010701505437577000212540ustar00rootroot00000000000000## [0.27.1](https://www.npmjs.com/package/@sinclair/typebox/v/0.27.1) ## Updates - Adds a `Value.Mutate(left, right)` function. This function performs a deep mutable assignment on a value by internally remapping the `right` values on the `left`. Values omitted on the right will also be deleted on the left. This function can be useful scenarios where mutation of data is required without replacing existing reference values. An example of which might be React which tracks reference values to indicate redraw. This function is implemented by way of `ValuePointer`. sinclairzx81-typebox-e0ec98c/changelog/0.28.0.md000066400000000000000000000225701505437577000212640ustar00rootroot00000000000000## [0.28.0](https://www.npmjs.com/package/@sinclair/typebox/v/0.28.0) ## Overview Revision 0.28.0 adds support for Indexed Access Types. This update also includes moderate breaking changes to Record and Composite types and does require a minor semver revision tick. ## Contents - Enhancements - [Indexed Access Types](#Indexed-Access-Types) - [KeyOf Tuple and Array](#KeyOf-Tuple-and-Array) - Breaking Changes - [Record Types Allow Additional Properties By Default](#Record-Types-Allow-Additional-Properties-By-Default) - [Composite Returns Intersect for Overlapping Properties](#Composite-Returns-Intersect-for-Overlapping-Properties) ## Indexed Access Types Revision 0.28.0 adds [Indexed Access Type](https://www.typescriptlang.org/docs/handbook/2/indexed-access-types.html) support with a new `Type.Index()` mapping type. These types allow for deep property lookups without needing to prop dive through JSON Schema properties. This type is based on the TypeScript implementation of Indexed Access Types and allows for generalized selection of properties for complex types irrespective of if that type is a Object, Union, Intersection, Array or Tuple. ```typescript // ---------------------------------------------------------- // The following types A and B are structurally equivalent, // but have varying JSON Schema representations. // ---------------------------------------------------------- const A = Type.Object({ x: Type.Number(), y: Type.String(), z: Type.Boolean(), }) const B = Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.String() }), Type.Object({ z: Type.Boolean() }) ]) // ---------------------------------------------------------- // TypeBox 0.27.0 - Non Uniform // ---------------------------------------------------------- const A_X = A.properties.x // TNumber const A_Y = A.properties.y // TString const A_Z = A.properties.z // TBoolean const B_X = B.allOf[0].properties.x // TNumber const B_Y = B.allOf[1].properties.y // TString const B_Z = B.allOf[2].properties.z // TBoolean // ---------------------------------------------------------- // TypeBox 0.28.0 - Uniform via Type.Index // ---------------------------------------------------------- const A_X = Type.Index(A, ['x']) // TNumber const A_Y = Type.Index(A, ['y']) // TString const A_Z = Type.Index(A, ['z']) // TBoolean const B_X = Type.Index(B, ['x']) // TNumber const B_Y = Type.Index(B, ['y']) // TString const B_Z = Type.Index(B, ['z']) // TBoolean ``` Indexed Access Types support has also been extended to Tuple and Array types. ```typescript // ----------------------------------------------------------- // Array // ----------------------------------------------------------- type T = string[] type I = T[number] // type T = string const T = Type.Array(Type.String()) const I = Type.Index(T, Type.Number()) // const I = TString // ----------------------------------------------------------- // Tuple // ----------------------------------------------------------- type T = ['A', 'B', 'C'] type I = T[0 | 1] // type I = 'A' | 'B' const T = Type.Array(Type.String()) const I = Type.Index(T, Type.Union([ // const I = TUnion<[ Type.Literal(0), // TLiteral<'A'>, Type.Literal(1), // TLiteral<'B'> ])) // ]> ``` ## KeyOf Tuple and Array Revision 0.28.0 includes additional `Type.KeyOf` support for Array and Tuple types. Keys of Array will always return `TNumber`, whereas keys of Tuple will return a LiteralUnion for each index of that tuple. ```typescript // ----------------------------------------------------------- // KeyOf: Tuple // ----------------------------------------------------------- const T = Type.Tuple([Type.Number(), Type.Number(), Type.Number()]) const K = Type.KeyOf(T) // const K = TUnion<[ // TLiteral<'0'>, // TLiteral<'1'>, // TLiteral<'2'>, // ]> // ----------------------------------------------------------- // KeyOf: Array // ----------------------------------------------------------- const T = Type.Array(Type.String()) const K = Type.KeyOf(T) // const K = TNumber ``` It is possible to combine KeyOf with Index types to extract properties from array and object constructs. ```typescript // ----------------------------------------------------------- // KeyOf + Index: Object // ----------------------------------------------------------- const T = Type.Object({ x: Type.Number(), y: Type.String(), z: Type.Boolean() }) const K = Type.Index(T, Type.KeyOf(T)) // const K = TUnion<[ // TNumber, // TString, // TBoolean, // ]> // ----------------------------------------------------------- // KeyOf + Index: Tuple // ----------------------------------------------------------- const T = Type.Tuple([Type.Number(), Type.String(), Type.Boolean()]) const K = Type.Index(T, Type.KeyOf(T)) // const K = TUnion<[ // TNumber, // TString, // TBoolean, // ]> ``` ## Breaking Changes The following are breaking changes in Revision 0.28.0 ## Record Types Allow Additional Properties By Default Revision 0.28.0 no longer applies an automatic `additionalProperties: false` constraint to types of `TRecord`. Previously this constraint was set to prevent records with numeric keys from allowing unevaluated additional properties with non-numeric keys. This constraint worked in revisions up to 0.26.0, but since the move to use `allOf` intersect schema representations, this meant that types of Record could no longer be composed with intersections. This is due to the JSON Schema rules around extending closed schemas. Information on these rules can be found at the link below. https://json-schema.org/understanding-json-schema/reference/object.html#extending-closed-schemas For the most part, the omission of this constraint shouldn't impact existing record types with string keys, however numeric keys may cause problems. Consider the following where the validation unexpectedly succeeds for the following numeric keyed record. ```typescript const T = Type.Record(Type.Number(), Type.String()) const R = Value.Check(T, { a: null }) // true - Because `a` is non-numeric and thus is treated as an // additional unevaluated property. ``` Moving forward, Records with numeric keys "should" be constrained explicitly with `additionalProperties: false` via options if that record does not require composition through intersection. This is largely inline with the existing constraints one might apply to types of Object. ```typescript const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: false }) const R = Value.Check(T, { a: null }) // false - Because `a` is non-numeric additional property ``` ## Composite Returns Intersect for Overlapping Properties This is a minor breaking change with respect to the schema returned for Composite objects with overlapping varying property types. Previously TypeBox would evaluate `TNever` by performing an internal `extends` check against each overlapping property type. However problems emerged using this implementation for users who needed to use Composite with types of `TUnsafe`. This is due to unsafe types being incompatible with TypeBox's internal extends logic. The solution implemented in 0.28.0 is to return the full intersection of all overlapping properties. The reasoning here is that if the overlapping properties of varying types result in an illogical intersection, this is semantically the same as resolving `never` for that property. This approach avoids the need to internally check if all overlapping properties extend or narrow one another. ```typescript const T = Type.Composite([ Type.Object({ x: Type.Number() }), // overlapping property 'x' of varying type Type.Object({ x: Type.String() }) ]) // ----------------------------------------------------------- // Revision 0.27.0 // ----------------------------------------------------------- const R = Type.Object({ x: Type.Never() // Never evaluated through extends checks. }) // ----------------------------------------------------------- // Revision 0.28.0 // ----------------------------------------------------------- const R = Type.Object({ x: Type.Intersect([ // Illogical intersections are semantically the same as never Type.Number(), Type.String() ]) }) ``` This implementation should make it more clear what the internal mechanics are for object compositing. Future revisions of TypeBox may however provide a utility function to test illogical intersections for Never for known types. sinclairzx81-typebox-e0ec98c/changelog/0.28.3.md000066400000000000000000000023021505437577000212560ustar00rootroot00000000000000## [0.28.3](https://www.npmjs.com/package/@sinclair/typebox/v/0.28.3) ## Overview Revision 0.28.3 adds a new Rest type to support variadic type composition. ## Contents - Enhancements - [Variadic Types](#Variadic-Types) ## Variadic Types Revision 0.28.3 adds a new type named `Type.Rest`. This type is used to extract a tuple array of type of `[...TSchema]`. The return value of this type is not strictly JSON Schema, however the tuple array can be used as a parameter to other types that accept tuples as their arguments. ### Tuple Concatenation ```typescript // TypeScript type A = [1, 2] type B = [3, 4] type C = [...A, ...B] // TypeBox const A = Type.Tuple([Type.Literal(1), Type.Literal(2)]) const B = Type.Tuple([Type.Literal(3), Type.Literal(4)]) const C = Type.Tuple([...Type.Rest(A), ...Type.Rest(B)]) ``` ### Tuple To Parameter ```typescript // TypeScript type P = [number, number] type F1 = (param: [...P]) => void type F2 = (param: [...P, number]) => void // TypeBox const P = Type.Tuple([Type.Number(), Type.Number()]) const F1 = Type.Function(Type.Rest(P), Type.Void()) const F2 = Type.Function([...Type.Rest(P), Type.Number()], Type.Void()) ``` sinclairzx81-typebox-e0ec98c/changelog/0.29.0.md000066400000000000000000000104761505437577000212670ustar00rootroot00000000000000## [0.29.0](https://www.npmjs.com/package/@sinclair/typebox/v/0.29.0) ## Overview Revision 0.29.0 makes a minor interface and schema representation change to the `Type.Not` type. This revision also includes a fix for indexed access types on TypeScript 5.1.6. As this revision constitutes a breaking representation change for `Type.Not`, a minor semver revision is required. ## Contents - Enhancements - [Type.Not Representation Change](#Representation-Change) - [Not Inversion](#Not-Inversion) - [Inference Limitations](#Inference-Limitations) ## Type.Not Representation Change The `Type.Not` was first introduced in Revision 0.26.0. This type accepted two arguments, the first is the `not` type, the second is the `allowed` type. In 0.26.0, TypeBox would treat the `allowed` type as the inferred type with the schema represented in the following form. ### 0.26.0 ```typescript // allow all numbers except the number 42 // const T = Type.Not(Type.Literal(42), Type.Number()) // ^ ^ // not type allowed type // represented as // const T = { allOf: [ { not: { const: 42 } }, { type: 'number' } ] } // inferred as // type T = Static // type T = number ``` In 0.26.0. the rationale for the second `allowed` argument was provide a correct static type to infer, where one could describe what the type wasn't on the first and what it was on the second (with inference of operating on the second argument). This approach was to echo possible suggestions for negated type syntax in TypeScript. ```typescript type T = number & not 42 // not actual typescript syntax! ``` ### 0.29.0 Revision 0.29.0 changes the `Type.Not` type to take a single `not` argument only. This type statically infers as `unknown` ```typescript // allow all types except the literal number 42 // const T = Type.Not(Type.Literal(42)) // ^ // not type // represented as // const T = { not: { const: 42 } } // inferred as // type T = Static // type T = unknown ``` ### Upgrading to 0.29.0 In revision 0.29.0, you can express the 0.26.0 Not type via `Type.Intersect` which explicitly creates the `allOf` representation. The type inference works in this case as intersected `number & unknown` yields the most narrowed type (which is `number`) ```typescript // allow all numbers except the number 42 // const T = Type.Intersect([ Type.Not(Type.Literal(42)), Type.Number() ]) // ^ ^ // not type allowed type // represented as // const T = { allOf: [ { not: { const: 42 } }, { type: 'number' } ] } // inferred as // type T = Static // type T = number ``` The 0.29.0 `Not` type properly represents the JSON Schema `not` keyword in its simplest form, as well as making better use of intersection type narrowing capabilities of TypeScript. ## Not Inversion The not type can be inverted through nesting. ```typescript // not not string // const T = Type.Not(Type.Not(Type.String())) // represented as // const T = { not: { not: { type: "string" } } } // inferred as // type T = Static // type T = string ``` ## Inference Limitations Not types are synonymous with the concept of [negated types](https://github.com/microsoft/TypeScript/issues/4196) which are not supported in the TypeScript language. Because of this, it is not currently possible to infer negated types in a way one would naturally expect for some cases. Consider the following. ```typescript const T = Type.Intersect([Type.String(), Type.Not(Type.String())]) type T = Static // type T = string & not string // actual: string // expect: never ``` As such, the use of Not types should be used with some consideration to current limitations, and reserved primarily for narrowing cases such as the following. ```typescript const T = Type.Intersect([Type.String(), Type.Not(Type.Literal('disallowed string'))]) type T = Static // type T = string & not 'disallowed string' // actual: string // expect: string ``` sinclairzx81-typebox-e0ec98c/changelog/0.29.2.md000066400000000000000000000070441505437577000212660ustar00rootroot00000000000000## [0.29.2](https://www.npmjs.com/package/@sinclair/typebox/v/0.29.2) ## Overview Revision 0.29.2 includes enhancements to `Type.Index` This revision contains no breaking changes ## Contents - Enhancements - [Modifier Index Resolver](#Modifier-Index-Resolver) - [Indexed Intersect](#Indexed-Intersect) - [Indexed Union](#Indexed-Union) - [Composite](#Composite) ## Modifier Index Resolver Revision 0.29.2 re-introduces optional property narrowing for Indexed Access Types. This functionality is specific when indexing overlapping properties with one or more optional modifiers. Revision 0.28.0 attempted to implement this narrowing, however was pulled due to instantiation issues raised on issue [419](https://github.com/sinclairzx81/typebox/issues/419) (specific to composite narrowing) Revision 0.29.2 attempts to re-introduce this functionality using a different resolution strategy. It uses Indexed Access Types as the construct in which to apply such narrowing and expands upon Union and Intersection type normalization for optional modifier unwrap and remapping. This approach unifies Composite inference with Index Access Types and makes provisions for a possible `Type.Mapped` feature in later releases. ## Indexed Intersect The following are the index resolver cases for intersect types. ### Case 1 ```typescript const T = Type.Intersect([ Type.Object({ x: Type.Optional(Type.Number()) }), Type.Object({ x: Type.Optional(Type.Number()) }) ]) const I = Type.Index(T, ['x']) // type I = TOptional> ``` ### Case 2 ```typescript const T = Type.Intersect([ Type.Object({ x: Type.Optional(Type.Number()) }), Type.Object({ x: Type.Number() }) ]) const I = Type.Index(T, ['x']) // type I = TUnion<[TNumber, TNumber]> ``` ### Case 3 ```typescript const T = Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ x: Type.Number() }) ]) const I = Type.Index(T, ['x']) // type I = TUnion<[TNumber, TNumber]> ``` ## Indexed Union The following are the index resolver cases for union types. ### Case 1 ```typescript const T = Type.Union([ Type.Object({ x: Type.Optional(Type.Number()) }), Type.Object({ x: Type.Optional(Type.Number()) }) ]) const I = Type.Index(T, ['x']) // type I = TOptional> ``` ### Case 2 ```typescript const T = Type.Union([ Type.Object({ x: Type.Optional(Type.Number()) }), Type.Object({ x: Type.Number() }) ]) const I = Type.Index(T, ['x']) // type I = TOptional> ``` ### Case 3 ```typescript const T = Type.Union([ Type.Object({ x: Type.Number() }), Type.Object({ x: Type.Number() }) ]) const I = Type.Index(T, ['x']) // type I = TUnion<[TNumber, TNumber]> ``` ## Composite The following are the resolver cases for indexed types when applied to composite intersection. ### Case 1 ```typescript const T = Type.Composite([ Type.Object({ x: Type.Optional(Type.Number()) }), Type.Object({ x: Type.Optional(Type.Number()) }) ]) // type T = TObject<{ // x: TOptional> // }> ``` ### Case 2 ```typescript const T = Type.Composite([ Type.Object({ x: Type.Optional(Type.Number()) }), Type.Object({ x: Type.Number() }) ]) // type T = TObject<{ // x: TUnion<[TNumber, TNumber]> // }> ``` ### Case 3 ```typescript const T = Type.Composite([ Type.Object({ x: Type.Number() }), Type.Object({ x: Type.Number() }) ]) // type T = TObject<{ // x: TUnion<[TNumber, TNumber]> // }> ```sinclairzx81-typebox-e0ec98c/changelog/0.30.0.md000066400000000000000000000565751505437577000212710ustar00rootroot00000000000000## [0.30.0](https://www.npmjs.com/package/@sinclair/typebox/v/0.30.0) ## Overview Revision 0.30.0 is a milestone revision for the TypeBox project. It is primarily focused on internal optimizations, refactoring work to reduce package and bundle sizes, enable increased modularity of internal sub modules (with some considerations given to future ESM publishing), renaming internal functions to address react native bundling issues and consolidating shared internal modules to reduce overall code overhead. This revision also implements several new features, including new validation constraints for Array, new types for iterators, new utility types, a TypeScript code generation option for the compiler, enhancements made to modifiers and better options for TypeScript to TypeBox code translation. This revision also includes new examples including a transform type for handling IO encode an decode as well as a reference implementation for JSON Type Definition specification. This revision includes breaking changes and some deprecations. It requires a minor semver revision. ## Contents - Enhancements - [TypeScript Code Generation](#TypeScript-Code-Generation) - [Optional and Readonly](#Optional-and-Readonly) - [Iterator and AsyncIterator](#Iterator-and-AsyncIterator) - [Order Independent References](#Order-Independent-References) - [Value Submodules](#Value-Submodules) - [Array Contains Constraint](#Array-Contains-Constraint) - [Additional Utility Types](#Additional-Utility-Types) - [Reduced Package Size](#Reduced-Package-Size) - [TypeBox Codegen](#TypeBox-Codegen) - Examples - [JSON Type Definition](#JSON-Type-Definition) - [Prototype Types](#Prototype-Types) - [Transform Types](#Transform-Types) - Breaking - [Extended Type Representation-Change](#Extended-Type-Representation-Change) - [Modifier Symbol Deprecated](#Modifier-Deprecated) - [RegEx Renamed To RegExp](#RegEx-Renamed-To-RegExp) - [ValueErrorType Custom Renamed To Kind](#ValueErrorType-Custom-Renamed-To-Kind) ## TypeScript Code Generation Revision 0.30.0 adds TypeScript code generation support to the TypeCompiler. By specifying the language option on the `.Code()` function, TypeBox will add type annotations to the compiled output. This functionality can be used to produce typed TS functions for projects that preference AOT compilation. ```typescript const Code = TypeCompiler.Code(Type.String(), { // return function check(value: any): boolean { language: 'typescript' // return ( }) // (typeof value === 'string') // ) // } ``` ## Optional and Readonly Revision 0.30.0 deprecates the `[Modifier]` symbol and introduces two new symbols, `[Readonly]` and `[Optional]`. This change is carried out to simplify type inference as well as to simplify runtime mapping logic. This change should not implicate users leveraging the `Type.*` purely for type composition, however implementors using TypeBox for reflection and code generation should update to the new symbols. ```typescript // Revision 0.29.0 // const A = Type.ReadonlyOptional(Type.Number()) // const A: TReadonlyOptional = { // type: 'number', // [TypeBox.Modifier]: 'ReadonlyOptional' // } const B = Type.Readonly(Type.Number()) // const B: TReadonly = { // type: 'number', // [TypeBox.Modifier]: 'Readonly' // } const C = Type.Optional(Type.Number()) // const C: TOptional = { // type: 'number', // [TypeBox.Modifier]: 'Optional' // } // Revision 0.30.0 // const A = Type.ReadonlyOptional(Type.Number()) // const A: TReadonly> = { // type: 'number', // [TypeBox.Readonly]: 'Readonly', // [TypeBox.Optional]: 'Optional' // } const B = Type.Readonly(Type.Number()) // const B: TReadonly = { // type: 'number', // [TypeBox.Readonly]: 'Readonly' // } const C = Type.Optional(Type.Number()) // const C: TOptional = { // type: 'number', // [TypeBox.Optional]: 'Optional' // } ``` ## Iterator and AsyncIterator Revision 0.30.0 adds the types `Iterator` and `AsyncIterator`. These types add to the existing non-validatable extended type set and can be used build callable generator functions. These types are written primarily to describe RPC network interfaces that return multiple values. Examples of which may include web socket streams or reading database result cursors over a network. ```typescript // Revision 0.30.0 // const Enumerable = (T: T) => Type.Function([ Type.Number({ description: 'Start index' }), Type.Number({ description: 'End index' }) ], Type.Iterator(T)) const EnumerableNumber = Enumerable(Type.Number()) const Range: Static = function * (start: number, end: number) { for(let i = start; i < end; i++) yield i } const R = [...Range(10, 20)] // const R = [10, 11, 12, ..., 19] ``` ## Order Independent References Revision 0.30.0 adds an overload for `Ref` to enable non order dependent type referencing. Prior to this revision, reference targets needed to be defined first before being referenced. Revision 0.30.0 lifts this restriction and allows referencing of "yet to be defined" targets through the use of `typeof` operator. This overload borrows on TypeScript's ability to derive type information irrespective of topological ordering. This overload is implemented for "TypeScript to TypeBox" code generation utilities where TypeScript types are not guaranteed ordered in a runtime sorted fashion. ```typescript // Revision 0.29.0 // const R = Type.Ref(T) // Error: T isn't defined yet const T = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number() }, { $id: 'T' }) // Revision 0.30.0 // const R = Type.Ref('T') // Ok: infer from typeof T const T = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number() }, { $id: 'T' }) ``` ## Value Submodules Revision 0.30.0 carries out a number of refactorings for the `Value.*` modules to enable each submodule to be imported individually. These refactorings are support better "pay to play" library characteristics, allowing users to import only the submodules they need. This update also makes provisions for ESM publishing by removing internal namespaces. The top level `Value.*` namespace will remain on all subsequent versions of TypeBox. ```typescript // Revision 0.29.0 // import { Value } from '@sinclair/typebox/value' // Value.* namespace const A = Value.Create(Type.String()) // Revision 0.30.0 // import { Create } from '@sinclair/typebox/value/create' // Only Create() const A = Create(Type.String()) ``` ## Array Contains Constraint Revision 0.30.0 implements validation support for the `contains` keyword as well as the draft 2019-09 `minContains` and `maxContains` constraints on `Array`. Documentation on these constraints can be found https://json-schema.org/understanding-json-schema/reference/array.html#contains ```typescript // Revision 0.30.0 // const T = Type.Array(Type.Number(), { contains: Type.Literal(1), minContains: 3, maxContains: 5 }) Value.Check(T, [1, 1, 1]) // true - between 3 and 5 instances of 1 Value.Check(T, [1, 1, 1, 1, 1]) // true - between 3 and 5 instances of 1 Value.Check(T, [0, 1, 1, 1, 1, 1]) // true - between 3 and 5 instances of 1 Value.Check(T, [1, 1]) // false - less than 3 instances of 1 Value.Check(T, [1, 1, 1, 1, 1, 1]) // false - more than 5 instances of 1 Value.Check(T, [0]) // false - no instances of 1 ``` ## Additional Utility Types Revision 0.30.0 adds the utility types `Awaited`, `Uppercase`, `Lowercase`, `Capitalize`, and `Uncapitalize` to the supported type set. ```typescript // Revision 0.30.0 const T1 = Type.Awaited(Type.Promise(Type.String())) // const T1: TString const T2 = Type.Uppercase(Type.Literal('hello')) // const T2: TLiteral<'HELLO'> const T3 = Type.Lowercase(Type.Literal('HELLO')) // const T3: TLiteral<'hello'> const T4 = Type.Capitalize(Type.Literal('hello')) // const T4: TLiteral<'Hello'> const T5 = Type.Uncapitalize(Type.Literal('HELLO')) // const T5: TLiteral<'hELLO'> ``` A full list of TypeScript utility types can be found at this [link](https://www.typescriptlang.org/docs/handbook/utility-types.html). ## Reduced Package Size Revision 0.30.0 carries out several internal refactorings to reduce package and bundle sizes. This work is largely an ongoing process with provisional work carried out across `type`, `value` and `compiler` modules. Revision 0.30.0 manages to weigh in slightly less than Revision 0.29.0 with the additional functionality provided on the revision. ```typescript // Revision 0.29.0 // ┌──────────────────────┬────────────┬────────────┬─────────────� │ (index) │ Compiled │ Minified │ Compression │ ├──────────────────────┼────────────┼────────────┼─────────────┤ │ typebox/compiler │ '130.3 kb' │ ' 58.2 kb' │ '2.24 x' │ │ typebox/errors │ '113.3 kb' │ ' 49.8 kb' │ '2.27 x' │ │ typebox/system │ ' 78.8 kb' │ ' 32.2 kb' │ '2.45 x' │ │ typebox/value │ '180.0 kb' │ ' 77.7 kb' │ '2.32 x' │ │ typebox │ ' 77.7 kb' │ ' 31.7 kb' │ '2.45 x' │ └──────────────────────┴────────────┴────────────┴─────────────┘ // Revision 0.30.0 // ┌──────────────────────┬────────────┬────────────┬─────────────� │ (index) │ Compiled │ Minified │ Compression │ ├──────────────────────┼────────────┼────────────┼─────────────┤ │ typebox/compiler │ '129.4 kb' │ ' 58.6 kb' │ '2.21 x' │ │ typebox/errors │ '111.6 kb' │ ' 50.1 kb' │ '2.23 x' │ │ typebox/system │ ' 76.5 kb' │ ' 31.7 kb' │ '2.41 x' │ │ typebox/value │ '180.7 kb' │ ' 79.3 kb' │ '2.28 x' │ │ typebox │ ' 75.4 kb' │ ' 31.3 kb' │ '2.41 x' │ └──────────────────────┴────────────┴────────────┴─────────────┘ ``` ## TypeBox Codegen Revision 0.30.0 offers an external code generation API tool which can be used to programmatically convert TypeScript types into TypeBox types. [TypeBox-Code Project](https://github.com/sinclairzx81/typebox-codegen) ```typescript import * as Codegen from '@sinclair/typebox-codegen' const Code = Codegen.TypeScriptToTypeBox.Generate(` type T = { x: number, y: number, z: number } `) console.log(Code) // Output: // // import { Type, Static } from '@sinclair/typebox' // // type T = Static // const T = Type.Object({ // x: Type.Number(), // y: Type.Number(), // z: Type.Number() // }) ``` ## JSON Type Definition Revision 0.30.0 includes a reference implementation for JSON Type Definition (RFC 8927). This specification is currently under consideration for inclusion in the TypeBox library as an alternative schema representation for nominal type systems. The implementation currently contains all types expressed in the JSON Type Definition spec, but omits constraints such and `minimum` and `maximum` values (which are not formally represented in the specification). The implementation is offered as a single file which can be copied in to projects with TypeBox installed. This implementation may be enhanced over the next few revisions (with some potential to implement mapping types such as partial, required, omit, pick, keyof). This specification will be considered for inclusion under `@sinclair/typebox/typedef` if there is enough interest. ```typescript import { Type } from './typedef' // from: examples/typedef/typedef.ts const T3 = Type.Struct({ // const T3 = { x: Type.Float32(), // properties: { y: Type.Float32(), // x: { type: 'float32' }, z: Type.Float32() // y: { type: 'float32' }, }) // z: { type: 'float32' } // } // } const T2 = Type.Struct({ // const T3 = { x: Type.Float32(), // properties: { y: Type.Float32() // x: { type: 'float32' }, }) // y: { type: 'float32' } // } // } const U = Type.Union([ // const U = { T3, // discriminator: 'type', T2 // mapping: { ]) // 0: { // properties: { // x: { type: 'float32' }, // y: { type: 'float32' }, // z: { type: 'float32' } // } // }, // 1: { // properties: { // x: { type: 'float32' }, // y: { type: 'float32' } // } // } // } // } ``` ## Prototype Types Revision 0.30.0 renames `Experimental` types to `Prototype` types within the examples directory. Updates here include additional documentation and rationales for the existing types `UnionOneOf`, `UnionEnum`, `Const`, and includes two new types `Evaluate` and `PartialDeep`. These types are written as standalone modules and can be copied into a project for direct use. The TypeBox project is open to community discussions around the inclusion of these types in future revisions. ## Transform Types Revision 0.30.0 provides a reference implementation for Transform types. There has been some interest from users to offer combinators similar to Zod's `.transform()` function that permits remapping values during `.parse()` like operations. As TypeBox types do not have fluent combinators or a parse function (and are just JSON Schema objects), introducing similar functionality without augmenting types or implementing a `.parse()` on all types has proven to be particularily challenging. The reference Transform implementation implements a workable design by augmenting TypeBox types with codec functions outside the type system. These functions allow values to be structurally encoded and decoded through the `.parseLike()` functions `Encode()` and `Decode()`. TypeBox adopts the `io-ts` perspective for value transformation, viewing the act of transforming values primarily the role of dedicated codec system. As much of this functionality is considered high level and above and beyond the type system, Transform types will not likely be added to TypeBox type system; but rather added as an optional import in later revisions. ```typescript import { Transform, Encode, Decode } from './transform' const Timestamp = Transform(Type.Number(), { // The Transform function wraps a TypeBox type with two codec decode: (value) => new Date(value), // functions which implement logic to decode a received value encode: (value) => value.getTime(), // (i.e. number) into a application type (Date). The encode }) // function handles the reverse mapping. type N = Static // type N = { timestamp: number } // const N = Type.Object({ // Transform types are to be used like any other type and will timestamp: Timestamp // infer as the original TypeBox type. For example, the type `N` }) // above will infer as { timestamp: number } (as derived from // the TB type) const D = Decode(N, { timestamp: 123 }) // const D = { timestamp: Date(123) } // // The Decode function accepts any type plus a value. The Decode // function return type will be that of the transforms decode() // return type (which is Date), with the second argument statically // typed as N. This function acts as a kind of parse() that returns // the decoded type or throws on validation error. const E = Encode(N, { timestamp: new Date(123) }) // const E = { timestamp: 123 } // // The encode function performs the inverse, accepting the // decoded type { timestamp: Date } and re-encoding to the // target type { timestamp: number }. This function will // also throw on validation error. ``` ## Extended Type Representation Change Revision 0.30.0 updates representations for all extended types. This change is made due to TypeBox's observed role as a general purpose JavaScript validation library as well as to deprecate support for extended type validation in Ajv which was only ever partially functional at best. Attempts were made on Revision 0.25.0 to restructure extended types to provide Ajv hooks for custom type configuration. These hooks used the `type` property where `{ type: 'object', instanceOf: 'Type' }` was used to configure schematics for JavaScript objects, and `{ type: 'null', typeOf: 'Type' }` was used for JavaScript primitives. Despite these hooks, Ajv would still struggle with validation of primitive types (such as `undefined`), and for the types `Function`, `Constructor` and `Promise`; these were meaningless to Ajv and it did not make sense to try provide hooks for a validator that could not make use of them. This change represents a move towards a formal specification to express pure JavaScript constructs which is partially under discussion within the runtime type community. This change will implicate the use of `Uint8Array` and `Date` objects when configuring for Ajv. A supplimentary fallback will be provided in the `/examples` directory using `Type.Unsafe` ```typescript // Revision 0.29.0 // const T = Type.Date() // const T: TDate = { type: 'object', instanceOf: 'Date' } const U = Type.Undefined() // const U: TUndefined = { type: 'null', typeOf: 'Undefined' } // Revision 0.30.0 // const T = Type.Date() // const T: TDate = { type: 'Date' } const U = Type.Undefined() // const U: TUndefined = { type: 'undefined' } ``` ## RegEx Renamed To RegExp Revision 0.30.0 marks `Type.RegEx` as deprecated but provides `Type.RegExp` as an alternative (matching the JavaScript `RegExp` type name). Additionally this type has also been moved from the `Standard` to `Extended` type set. The `RegExp` type will no longer considered part of the Standard type set due to JavaScript Regular Expressions supporting a wider range of symbols and control characeters than is supported by the ECMA262 subset used by the JSON Schema specification. Information on the ECMA262 subset supported by JSON Schema can be found at the following Url https://json-schema.org/understanding-json-schema/reference/regular_expressions.html As `Type.RegEx()` is widely used, this function will be retained under the `@deprecated` annotation for the 0.30.0 revision. ```typescript // Revision 0.29.0 const T = Type.RegEx(/abc/) // Revision 0.30.0 const A = Type.RegEx(/abc/) // deprecation warning! const B = Type.RegExp(/abc/) // Extended Type const T = Type.String({ pattern: /abc/.source }) // Standard Type ``` For Unicode (UTF-16) support on 0.30.0, the recommendation is to continue using user defined formats. ```typescript import { Type, FormatRegistry } from '@sinclair/typebox' FormatRegistry.Set('emoji', value => /|\p{Extended_Pictographic}/gu.test(value)) const T = Type.String({ format: 'emoji' }) Value.Check(T, '♥�♦�♠�♣�') // Ok ``` For information on configuring custom formats on Ajv, refer to https://ajv.js.org/guide/formats.html#user-defined-formats sinclairzx81-typebox-e0ec98c/changelog/0.31.0.md000066400000000000000000000401211505437577000212460ustar00rootroot00000000000000## [0.31.0](https://www.npmjs.com/package/@sinclair/typebox/v/0.31.0) ## Overview Revision 0.31.0 is a subsequent milestone revision for the TypeBox library and a direct continuation of the work carried out in 0.30.0 to optimize and prepare TypeBox for a 1.0 release candidate. This revision implements a new codec system with Transform types, provides configurable error message generation for i18n support, adds a library wide exception type named TypeBoxError and generalizes the Rest type to enable richer composition. This revision also finalizes optimization work to reduce the TypeBox package size. This revision contains relatively minor breaking changes due to internal type renaming. A minor semver revision is required. ## Contents - Enhancements - [Transform Types](#Transform-Types) - [Encode and Decode](#Encode-and-Decode) - [StaticEncode and StaticDecode](#StaticEncode-and-StaticDecode) - [Rest Types](#Rest-Types) - [Record Key](#Record-Key) - [TypeBoxError](#TypeBoxError) - [TypeSystemErrorFunction](#TypeSystemErrorFunction) - [Reduce Package Size](#Reduce-Package-Size) - Breaking - [JsonTypeBuilder and JavaScriptTypeBuilder](#JsonTypeBuilder-and-JavaScriptTypeBuilder) - [TypeSystemPolicy](#TypeSystemPolicy) ## Transform Types Revision 0.31.0 includes a new codec system referred to as Transform types. A Transform type is used to augment a regular TypeBox type with Encode and Decode functions. These functions are invoked via the new Encode and Decode functions available on both Value and TypeCompiler modules. The following shows a Transform type which increments and decrements a number. ```typescript import { Value } from '@sinclair/typebox/value' const T = Type.Transform(Type.Number()) // const T = { .Decode(value => value + 1) // type: 'number', .Encode(value => value - 1) // [Symbol(TypeBox.Kind)]: 'Number', // [Symbol(TypeBox.Transform)]: { // Decode: [Function: Decode], // Encode: [Function: Encode] // } // } const A = Value.Decode(T, 0) // const A: number = 1 const B = Value.Encode(T, 1) // const B: number = 0 ``` ## Encode and Decode Revision 0.31.0 includes new functions to Decode and Encode values. These functions are written in service to Transform types, but can be used equally well without them. These functions return a typed value that matches the type being transformed. TypeBox will infer decode and encode differently, yielding the correct type as derived from the codec implementation. The following shows decoding and encoding between number to Date. Note these functions will throw if the value is invalid. ```typescript const T = Type.Transform(Type.Number()) .Decode(value => new Date(value)) // number to Date .Encode(value => value.getTime()) // Date to number // Ok // const A = Value.Decode(T, 42) // const A = new Date(42) const B = Value.Encode(T, new Date(42)) // const B = 42 // Error // const C = Value.Decode(T, true) // Error: Expected number const D = Value.Encode(T, 'not a date') // Error: getTime is not a function ``` The Decode function is extremely fast when decoding regular TypeBox types; and TypeBox will by pass codec execution if the type being decoded contains no interior Transforms (and will only use Check). When using Transforms however, these functions may incur a performance penelty due to codecs operating structurally on values using dynamic techniques (as would be the case for applications manually decoding values). As such the Decode design is built to be general and opt in, but not necessarily high performance. ## StaticEncode and StaticDecode Revision 0.31.0 includes new inference types `StaticEncode` and `StaticDecode`. These types can be used to infer the encoded and decoded states of a Transform as well as regular TypeBox types. These types can be used to replace `Static` for `Request` and `Response` inference pipelines. The following shows an example `Route` function that uses Transform inference via `StaticDecode`. ```typescript // Route // export type RouteCallback = (request: StaticDecode) => StaticDecode // replace Static with StaticDecode export function Route( path: TPath, requestType: TRequest, responseType: TResponse, callback: RouteCallback ) { // route handling here ... const input = null // receive input const request = Value.Decode(requestType, input) const response = callback(request) const output = Value.Encode(responseType, response) // send output } // Route: Without Transform // const Timestamp = Type.Number() Route('/exampleA', Timestamp, Timestamp, (value) => { return value // value observed as number }) // Route: With Transform // const Timestamp = Type.Transform(Type.Number()) .Decode(value => new Date(value)) .Encode(value => value.getTime()) Route('/exampleB', Timestamp, Timestamp, (value) => { return value // value observed as Date }) ``` ## Rest Types Revision 0.31.0 updates the Rest type to support variadic tuple extraction from Union, Intersection and Tuple types. Previously the Rest type was limited to Tuple types only, but has been extended to other types to allow uniform remapping without having to extract types from specific schema representations. The following remaps a Tuple into a Union. ```typescript const T = Type.Tuple([ // const T = { Type.String(), // type: 'array', Type.Number() // items: [ ]) // { type: 'string' }, // { type: 'number' } // ], // additionalItems: false, // minItems: 2, // maxItems: 2, // } const R = Type.Rest(T) // const R = [ // { type: 'string' }, // { type: 'number' } // ] const U = Type.Union(R) // const U = { // anyOf: [ // { type: 'string' }, // { type: 'number' } // ] // } ``` This type can be used to remap Intersect a Composite ```typescript const I = Type.Intersect([ // const I = { Type.Object({ x: Type.Number() }), // allOf: [{ Type.Object({ y: Type.Number() }) // type: 'object', ]) // required: ['x'], // properties: { // x: { type: 'number' } // } // }, { // type: 'object', // required: ['y'], // properties: { // y: { type: 'number' } // } // }] // } const C = Type.Composite(Type.Rest(I)) // const C = { // type: 'object', // required: ['x', 'y'], // properties: { // 'x': { type: 'number' }, // 'y': { type: 'number' } // } // } ``` ## Record Key Revision 0.31.0 updates the inference strategy for Record types and generalizes RecordKey to TSchema. This update aims to help Record types compose better when used with generic functions. The update also removes the overloaded Record factory methods, opting for a full conditional inference path. It also removes the `RecordKey` type which would type error when used with Record overloads. The return type of Record will be TNever if passing an invalid key. Valid Record key types include TNumber, TString, TInteger, TTemplateLiteral, TLiteralString, TLiteralNumber and TUnion. ```typescript // 0.30.0 // import { RecordKey, TSchema } from '@sinclair/typebox' function StrictRecord(K: K, T: T) { return Type.Record(K, T, { additionalProperties: false }) // Error: RecordKey unresolvable to overload } // 0.31.0 // import { TSchema } from '@sinclair/typebox' function StrictRecord(K: K, T: T) { return Type.Record(K, T, { additionalProperties: false }) // Ok: dynamically mapped } const A = StrictRecord(Type.String(), Type.Null()) // const A: TRecord const B = StrictRecord(Type.Literal('A'), Type.Null()) // const B: TObject<{ A: TNull }> const C = StrictRecord(Type.BigInt(), Type.Null()) // const C: TNever ``` ## TypeBoxError Revision 0.31.0 updates all errors thrown by TypeBox to extend the sub type `TypeBoxError`. This can be used to help narrow down the source of errors in `try/catch` blocks. ```typescript import { Type, TypeBoxError } from '@sinclair/typebox' import { Value } from '@sinclair/typebox/value' try { const A = Value.Decode(Type.Number(), 'hello') } catch(error) { if(error instanceof TypeBoxError) { // typebox threw this error } } ``` ## TypeSystemErrorFunction Revision 0.31.0 adds functionality to remap error messages with the TypeSystemErrorFunction. This function is invoked whenever a validation error is generated in TypeBox. The following is an example of a custom TypeSystemErrorFunction using some of the messages TypeBox generates by default. TypeBox also provides the DefaultErrorFunction which can be used for fallthrough cases. ```typescript import { TypeSystemErrorFunction, DefaultErrorFunction } from '@sinclair/typebox/system' // Example CustomErrorFunction export function CustomErrorFunction(schema: Types.TSchema, errorType: ValueErrorType) { switch (errorType) { case ValueErrorType.ArrayContains: return 'Expected array to contain at least one matching value' case ValueErrorType.ArrayMaxContains: return `Expected array to contain no more than ${schema.maxContains} matching values` case ValueErrorType.ArrayMinContains: return `Expected array to contain at least ${schema.minContains} matching values` ... default: return DefaultErrorFunction(schema, errorType) } } // Sets the CustomErrorFunction TypeSystemErrorFunction.Set(CustomErrorFunction) ``` It is possible to call `.Set()` on the TypeSystemErrorFunction module prior to each call to `.Errors()`. This can be useful for applications that require i18n support in their validation pipelines. ## Reduce Package Size Revision 0.31.0 completes a full sweep of code optimizations and modularization to reduce package bundle size. The following table shows the bundle sizes inclusive of the new 0.31.0 functionality against 0.30.0. ```typescript // Revision 0.30.0 // ┌──────────────────────┬────────────┬────────────┬─────────────� │ (index) │ Compiled │ Minified │ Compression │ ├──────────────────────┼────────────┼────────────┼─────────────┤ │ typebox/compiler │ '131.4 kb' │ ' 59.4 kb' │ '2.21 x' │ │ typebox/errors │ '113.6 kb' │ ' 50.9 kb' │ '2.23 x' │ │ typebox/system │ ' 78.5 kb' │ ' 32.5 kb' │ '2.42 x' │ │ typebox/value │ '182.8 kb' │ ' 80.0 kb' │ '2.28 x' │ │ typebox │ ' 77.4 kb' │ ' 32.0 kb' │ '2.42 x' │ └──────────────────────┴────────────┴────────────┴─────────────┘ // Revision 0.31.0 // ┌──────────────────────┬────────────┬────────────┬─────────────� │ (index) │ Compiled │ Minified │ Compression │ ├──────────────────────┼────────────┼────────────┼─────────────┤ │ typebox/compiler │ '149.5 kb' │ ' 66.1 kb' │ '2.26 x' │ │ typebox/errors │ '112.1 kb' │ ' 49.4 kb' │ '2.27 x' │ │ typebox/system │ ' 83.2 kb' │ ' 37.1 kb' │ '2.24 x' │ │ typebox/value │ '191.1 kb' │ ' 82.7 kb' │ '2.31 x' │ │ typebox │ ' 73.0 kb' │ ' 31.9 kb' │ '2.29 x' │ └──────────────────────┴────────────┴────────────┴─────────────┘ ``` Additional code reductions may not be possible without implicating code maintainability. The `typebox` module may however be broken down into sub modules in later revisions to further bolster modularity, but is retained as a single file on this revision for historical reasons (not necessarily technical ones). ## JsonTypeBuilder and JavaScriptTypeBuilder Revision 0.31.0 renames the `StandardTypeBuilder` and `ExtendedTypeBuilder` to `JsonTypeBuilder` and `JavaScriptTypeBuilder` respectively. Applications that extend TypeBox's TypeBuilders will need to update to these names. ```typescript // 0.30.0 // export class ApplicationTypeBuilder extends ExtendedTypeBuilder {} // 0.31.0 // export class ApplicationTypeBuilder extends JavaScriptTypeBuilder {} ``` These builders also update the jsdoc comment to `[Json]` and `[JavaScript]` inline with this new naming convention. ## TypeSystemPolicy Revision 0.31.0 moves the `TypeSystem.Policy` configurations into a new type named `TypeSystemPolicy`. This change was done to unify internal policy checks used by the Value and Error modules during bundle size optimization; as well as to keep policy configurations contextually separate from the Type and Format API on the TypeSystem module. ```typescript // Revision 0.30.0 // import { TypeSystem } from '@sinclair/typebox/system' TypeSystem.AllowNaN = true // Revision 0.31.0 // import { TypeSystemPolicy } from '@sinclair/typebox/system' TypeSystemPolicy.AllowNaN = true TypeSystemPolicy.IsNumberLike(NaN) // true ```sinclairzx81-typebox-e0ec98c/changelog/0.32.0.md000066400000000000000000000653631505437577000212660ustar00rootroot00000000000000### 0.32.0 --- ### Revision Updates - [Revision 0.32.35](https://github.com/sinclairzx81/typebox/pull/914) Support Any for Record keys, Revert error message on required property, Fix order dependency for Union Convert. - [Revision 0.32.34](https://github.com/sinclairzx81/typebox/pull/914) Fix template literal generation for template literals embedded within template literals. - [Revision 0.32.33](https://github.com/sinclairzx81/typebox/pull/905) Pin ESM compiler target to ES2020. - [Revision 0.32.32](https://github.com/sinclairzx81/typebox/pull/898) Fix for Enum properties when used with Mapped types. - [Revision 0.32.31](https://github.com/sinclairzx81/typebox/pull/881) Fix for Cast. Dereference Union variants before scoring. - [Revision 0.32.30](https://github.com/sinclairzx81/typebox/pull/868) Support null object prototypes for Encode/Decode. - [Revision 0.32.29](https://github.com/sinclairzx81/typebox/pull/862) Key derive optimization to improve Intersect Encode/Decode performance. - [Revision 0.32.28](https://github.com/sinclairzx81/typebox/pull/861) Fix for TransformEncode introduced with 0.32.24, 0.32.25 optimizations. - [Revision 0.32.27](https://github.com/sinclairzx81/typebox/pull/854) Support for esm.sh and general build tooling updates. - [Revision 0.32.26](https://github.com/sinclairzx81/typebox/pull/851) Optimization for number checks, use Number.isFinite(x) over typeof `number`. - [Revision 0.32.25](https://github.com/sinclairzx81/typebox/pull/849) Optimizations for type builder to improve schema creation performance for computed types. - [Revision 0.32.24](https://github.com/sinclairzx81/typebox/pull/848) Optimizations for Convert to avoid unnecessary object initialization and cloning. - [Revision 0.32.22](https://github.com/sinclairzx81/typebox/pull/840) Add Support for Optional and Readonly Function and Constructor Arguments. - [Revision 0.32.21](https://github.com/sinclairzx81/typebox/pull/836) Refactor Array Conversion logic. Discard TNever on TComposite. - [Revision 0.32.20](https://github.com/sinclairzx81/typebox/pull/810) Fix compiler regression (TS 5.3.3 -> 5.4.2) generating Diff declaration structures. - [Revision 0.32.19](https://github.com/sinclairzx81/typebox/pull/805) Revert Union Convert logic added on 0.32.16. - [Revision 0.32.18](https://github.com/sinclairzx81/typebox/pull/801) Add explicit return type on TypeSystem.Type. - [Revision 0.32.17](https://github.com/sinclairzx81/typebox/pull/799) Detect ambiguous inference for StaticDecode when inferring as any. - [Revision 0.32.16](https://github.com/sinclairzx81/typebox/pull/791) Enhance Composite, Mapped, Indexed and Transform types. Intersect and Union Convert updates, Include Path in Validation Error. - [Revision 0.32.15](https://github.com/sinclairzx81/typebox/pull/774) Additional internal guards for Type Arrays, Map and Set structures. - [Revision 0.32.14](https://github.com/sinclairzx81/typebox/pull/753) Use barrel exports for submodules. - [Revision 0.32.13](https://github.com/sinclairzx81/typebox/pull/744) Add minLength and maxLength constraint for RegExp - [Revision 0.32.12](https://github.com/sinclairzx81/typebox/pull/740) Fix option assignment on Record types. - [Revision 0.32.11](https://github.com/sinclairzx81/typebox/pull/738) Optimize Extract, Exclude. Overloads for Template Literal - [Revision 0.32.10](https://github.com/sinclairzx81/typebox/pull/734) Export additional type infrastructure for Partial and Required - [Revision 0.32.9](https://github.com/sinclairzx81/typebox/pull/731) Generalize Composite to accept schematics of type TSchema[] - [Revision 0.32.8](https://github.com/sinclairzx81/typebox/pull/728) Ensure schema `default` annotation is cloned on Create. - [Revision 0.32.7](https://github.com/sinclairzx81/typebox/pull/727) Ensure schema `default` annotation is cloned on Default. - [Revision 0.32.6](https://github.com/sinclairzx81/typebox/pull/724) Export additional type infrastructure for mapping types - [Revision 0.32.5](https://github.com/sinclairzx81/typebox/pull/718) Update licence year span for 2024 - [Revision 0.32.4](https://github.com/sinclairzx81/typebox/pull/708) Ensure ErrorFunctionParameter type is exported - [Revision 0.32.3](https://github.com/sinclairzx81/typebox/pull/703) Simplify Record Static Type - [Revision 0.32.1](https://github.com/sinclairzx81/typebox/pull/701) Specify default exports for Web Pack ## [0.32.0](https://www.npmjs.com/package/@sinclair/typebox/v/0.32.0) ## Overview Revision 0.32.0 adds support for ESM and carries out the work necessary to fully modularize the TypeBox type system to enable selective type imports. This revision also adds three new types (Mapped, Const, and Deref), along with two new Value functions (Clean and Default) as well as many enhancements to existing types (Index, KeyOf, RegExp, Optional and Readonly). This revision also carries out many internal optimizations to enhance type inference across all types. This revision is a milestone revision for the TypeBox project. It has several breaking changes and requires a minor revision. ## Contents - [Type Imports](#Type-Imports) - [Value Function Import](#Value-Function-Imports) - [CommonJS and ESM](#CommonJS-and-ESM) - [Types](#Types) - [Mapped Type](#Types-Mapped-Type) - [Const Type](#Types-Const-Type) - [Deref Type](#Types-Deref-Type) - [RegExp Type](#Types-RegExp-Type) - [Subtract Modifiers](#Types-Subtract-Modifiers) - [Values](#Values) - [Clean Function](#Values-Clean-Function) - [Default Function](#Values-Default-Function) - [Errors](#Errors) - [Error Parameter](#Errors-Error-Parameter) - [Optimizations](#Optimizations) - [Bundle Size](#Optimizations-Bundle-Size) - [Breaking](#Breaking) - [Renamed Symbols](#Breaking-Renamed-Symbols) - [TypeGuard Interface Change](#Breaking-TypeGuard-Interface-Change) - [Value Submodule Imports](#Breaking-Value-Submodule-Imports) - [Error Function](#Breaking-Error-Function) - [RegEx](#Breaking-RegEx) ### Type Imports Revision 0.32.0 adds the ability to import types individually. ```typescript import { Type, type Static } from '@sinclair/typebox' // classic - 37.0 kb minified import { Object, String, Number, type Static } from '@sinclair/typebox' // selective - 6.5 kb minified ``` ### Value Function Imports Revision 0.32.0 adds the ability to import value functions from the `/value` module path. ```typescript import { Value } from '@sinclair/typebox/value' // classic - 61.5 kb minified import { Check } from '@sinclair/typebox/value' // selective - 18.2 kb minified ``` ### CommonJS and ESM Revision 0.32.0 now publishes both CommonJS and ESM builds of TypeBox. Existing CommonJS users should not be impacted by the addition of ESM. For ESM users however, particularily those using bundlers, it's now possible to benefit from deep tree shake optimizations provided by modern bundler tooling. ## Types Revision 0.32.0 adds three new types to the type system and makes enhancements to Readonly and Optional modifiers. ### Mapped Type Revision 0.32.0 adds the Mapped type which replicates TS [Mapped Types](https://www.typescriptlang.org/docs/handbook/2/mapped-types.html) at runtime. The following shows the syntax comparison between TypeScript and TypeBox. #### TypeScript ```typescript type T = { x: number, y: number, z: number } type M = { [K in keyof T]: T[K] } // a mapped type ``` #### TypeBox ```typescript const T = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.Index(T, K)) // a mapped type ``` Mapped types use a functional design to replicate the TypeScript feature. For users interested in this type, it may be helpful to use the [TypeBox Workbench](https://sinclairzx81.github.io/typebox-workbench/) which can generate runtime Mapped types from TypeScript syntax. ### Const Type Revision 0.32.0 adds a new Const type that creates `readonly` types from object, array and primitive literal values. This type analogs the TypeScript `as const` syntax. The following shows general usage. ```typescript const A = Type.Const(1 as const) // const A: TLiteral<1> const B = Type.Const([1, 2, 3] as const) // const B: TReadonly, // TLiteral<2>, // TLiteral<3> // ]>> const C = Type.Const({ // const C: TObject<{ x: 1, // x: TReadonly>, y: 2, // y: TReadonly>, z: 3 // z: TReadonly>, } as const) // }> ``` Revision 0.32.0 continues support for TypeScript 4.0, and because of this, the `as const` syntax must be appended to each literal value passed to the Const type. When TypeBox ends support for 4.0, updates will be made to this type to make use of [Const Type Parameters](https://devblogs.microsoft.com/typescript/announcing-typescript-5-0/#const-type-parameters). This update will enable TypeBox to correctly infer the readonly literal type without the need for `as const`. ### Deref Type Revision 0.32.0 adds a new Type.Deref type which can be used to dereference type schematics. ```typescript const Vector = Type.Object({ // const Vector = { x: Type.Number(), // type: 'object', y: Type.Number(), // required: ['x', 'y', 'z'], }, { $id: 'Vector' }) // properties: { // x: { type: 'number' }, // y: { type: 'number' } // }, // $id: 'Vector' // } const VectorRef = Type.Ref(Vector) // const VectorRef = { // $ref: 'Vector' // } // ... Embedded Reference Type const Vertex = Type.Object({ // const Vertex = { position: VectorRef, // type: 'object', texcoord: VectorRef, // required: ['position', 'texcoord'], }) // properties: { // position: { $ref: 'Vector' }, // texcoord: { $ref: 'Vector' } // } // } // ... Dereferenced Embedded Reference Type const VertexDeref = Type.Deref(Vertex, [Vector]) // const VertexDeref = { // type: 'object', // required: ['position', 'texcoord'], // properties: { // position: { // type: 'object', // required: ['x', 'y', 'z'], // properties: { // x: { type: 'number' }, // y: { type: 'number' } // } // }, // texcoord: { // type: 'object', // required: ['x', 'y', 'z'], // properties: { // x: { type: 'number' }, // y: { type: 'number' } // } // } // } // } ``` The addition of Deref was prompted by issues composing reference types with mapping types (such as Partial, Required, Pick and Omit) which is generally not supported. Prior to Revision 0.32.0, there was some expectation for users to maintain and dereference types manually. In 0.32.0, users will still need to maintain references, but Deref will offer a more convenient mechanism to normalize reference types prior to composition. ### RegExp Type Revision 0.32.0 updates RegExp to support the full ECMA 262 regular expression syntax. In previous revisions, this type had been expressed as an alias for `TString` with a `pattern` to try ensure compliance with the [regular expression](https://json-schema.org/understanding-json-schema/reference/regular_expressions) subset supported by Json Schema. In Revision 0.32.0, RegExp is given a new type representation unto itself (named `TRegExp`) which houses both `source` and `flags` properties used to reconstruct a JavaScript regular expression object, making it properly distinct from `TString` and fully supportive of UTF-16. ```typescript // Case Insensitive const T = Type.RegExp(/abc/i) // const T = { // type: 'RegExp', // source: 'abc', // flags: 'i' // } type T = Static // type T = string Value.Check(T, 'abc') // ok Value.Check(T, 'ABC') // ok // Extended Syntax const E = Type.RegExp(/|\p{Extended_Pictographic}/gu) Value.Check(E, '♥�♦�♠�♣�') // ok - emoji supported ``` The RegExp type can be thought of as a more capable TemplateLiteral that can only reasonably infer as `string`. Additionally, the RegExp inference type of `string` is unique to the other `[JavaScript]` types in that it does not infer as it's named type. The updates to RegExp were prompted by the limitations with Json Schema expressions, and to provide better options for users requiring general Unicode validation support. For Json Schema compliance, the recommendation moving forward will be to use either String with pattern or TemplateLiteral. ```typescript const T = Type.String({ pattern: '^(a|b|c)$' }) // Json Schema compliant const T = Type.TemplateLiteral('${a|b|c}') // Json Schema compliant const T = Type.RegExp(/$(a|b|c)$/) // Non Json Schema compliant ``` ### Subtract Modifier Revision 0.32.0 adds new overloads for Readonly and Optional modifiers that enable them to subtract (or remove) that modifier from a type. Both Readonly and Optional now accept an optional secondary boolean argument that if `false`, will remove the modifier. #### TypeScript ```typescript type T = { x?: number, y?: number } type M = { [K in keyof T]-?: T[K] } // -? - subtract optional modifier ``` #### TypeBox ```typescript const T = Type.Object({ x: Type.Optional(Type.Number()), y: Type.Optional(Type.Number()) }) const M = Type.Mapped(Type.KeyOf(T), K => { return Type.Optional(Type.Index(T, K), false) // false - subtract optional modifier }) ``` Subtractive modifiers are provided in support of the new Mapped type feature. ## Values Revision 0.32.0 adds two new functions to the Value module. ### Clean Function Revision 0.32.0 adds a new Clean function that can be used to omit any values unknown to the type. This function will work irrespective of if `additionalProperties` is specified on the type. The Clean function is intended to replicate the functionality of Ajv's `removeAdditional` configuration. ```typescript const T = Type.Object({ x: Type.Number(), y: Type.Number() }) const X = Value.Clean(T, null) // const 'X = null const Y = Value.Clean(T, { x: 1 }) // const 'Y = { x: 1 } const Z = Value.Clean(T, { x: 1, y: 2, z: 3 }) // const 'Z = { x: 1, y: 2 } ``` Note: the Clean function does not check the validity of the value being cleaned, and does not provide assurances that the result will be valid. Its return value is `unknown` and should be checked before use. ### Default Function Revision 0.32.0 adds a new Default function that can be used to add missing values if the type specifies a `default` annotation. This function is intended to replicate Ajv's `useDefaults` functionality. ```typescript const T = Type.Object({ x: Type.Number({ default: 0 }), y: Type.Number({ default: 0 }) }) const X = Value.Default(T, null) // const 'X = null - non-enumerable const Y = Value.Default(T, { }) // const 'Y = { x: 0, y: 0 } const Z = Value.Default(T, { x: 1 }) // const 'Z = { x: 1, y: 0 } ``` The Default function does not check the validity of the value being defaulted, and does not provide assurances that the result will be valid. Its return value is `unknown` and should be checked before use. ## Optimizations Following the work to modularize TypeBox's type system, additional optimizations were carried out across each submodule to only import dependent type infrastructure. This has led to some fairly significant reductions in output sizes across each submodule. The main TypeBox import has increased in size due in part to the new Mapped types feature and other associative types, however selective imports supported on this revision should offer options for users concerned about output bundle size. There will be contined work to optimize the new type system throughout 0.32.0 and subsequent revisions. The following shows the comparisons between 0.31.0 and 0.32.0. ```typescript // Revision 0.31.0 ┌──────────────────────┬────────────┬────────────┬─────────────� │ (index) │ Compiled │ Minified │ Compression │ ├──────────────────────┼────────────┼────────────┼─────────────┤ │ typebox/compiler │ '163.6 kb' │ ' 71.6 kb' │ '2.28 x' │ │ typebox/errors │ '113.3 kb' │ ' 50.1 kb' │ '2.26 x' │ │ typebox/system │ ' 83.9 kb' │ ' 37.5 kb' │ '2.24 x' │ │ typebox/value │ '191.1 kb' │ ' 82.3 kb' │ '2.32 x' │ │ typebox │ ' 73.8 kb' │ ' 32.3 kb' │ '2.29 x' │ └──────────────────────┴────────────┴────────────┴─────────────┘ // Revision 0.32.0 ┌──────────────────────┬────────────┬────────────┬─────────────� │ (index) │ Compiled │ Minified │ Compression │ ├──────────────────────┼────────────┼────────────┼─────────────┤ │ typebox/compiler │ '120.6 kb' │ ' 52.9 kb' │ '2.28 x' │ │ typebox/errors │ ' 55.7 kb' │ ' 25.5 kb' │ '2.19 x' │ │ typebox/system │ ' 4.7 kb' │ ' 2.0 kb' │ '2.33 x' │ │ typebox/value │ '146.2 kb' │ ' 62.0 kb' │ '2.36 x' │ │ typebox │ ' 91.4 kb' │ ' 37.8 kb' │ '2.42 x' │ └──────────────────────┴────────────┴────────────┴─────────────┘ ``` ## Errors Revision 0.32.0 makes some enhancements to errors. ### Error Parameter Revision 0.32.0 updates TypeBox's ErrorFunction to accept an ErrorParameter that contains additional information regarding the cause of a validation error. In Revision 0.31.0, only `errorType` and `schema` were passed through to this function. In 0.32.0 the additional properties `value` and `path` are also passed through. This update was prompted by some users needing to be able to generate specific error messages derived from specific values or other associated information. The following shows the changes from 0.31.0 to 0.32.0. ```typescript // Revision 0.31.0 import { TypeSystemErrorFunction } from '@sinclair/typebox/system' TypeSystemErrorFunction.Set((schema, errorType) => { return 'oh no, an error!' }) // Revision 0.32.0 import { SetErrorFunction } from '@sinclair/typebox/errors' SetErrorFunction(({ schema, errorType, path, value }) => { // as destructured object return 'oh no, an error!' }) ``` Note that Revision 0.32.0 does make a breaking interface change by moving the ErrorFunction from `/system` to `/errors`. See breaking changes for more information. ## Breaking The following list the breaking changes in Revision 0.32.0. ### Renamed Symbols Revision 0.32.0 renames the `Optional`, `Required` and `Transform` symbols to `OptionalKind`, `RequiredKind` and `TransformKind`. This change was necessary to avoid conflicts with exported type functions. ```typescript // Revision 0.31.0 import { Kind, Hint, Optional, Required, Transform } from '@sinclair/typebox' // these are symbols // Revision 0.32.0 import { Kind, Hint, OptionalKind, RequiredKind, TransformKind, // these are symbols Optional, Required, Transform // these are type imports } from '@sinclair/typebox' ``` ### TypeGuard Interface Change Revision 0.32.0 has a breaking interface change on the TypeGuard utility where the `T` prefixed guard functions have been updated to use the `Is` prefix. This naming change is perhaps somewhat more sensible than the previous naming, however the update was largely prompted by TypeScript compiler issues where interface types (i.e. `TString`) where conflicting with the `TString` functions leading to breakage in CommonJS. ```typescript // Revision 0.31.0 import { TypeGuard, Kind } from '@sinclair/typebox' const R = TypeGuard.TString({ ... }) // Revision 0.32.0 import { TypeGuard } from '@sinclair/typebox' const R = TypeGuard.IsString({ ... }) ``` ### Value Submodule Imports The value submodule function import paths are unfortunately no longer supported. Instead, these can be imported directly on the `/value` path. The need to break the submodule paths was mostly due to complexities configuring dual ESM and CommonJS publishing for the package, as well as retaining support for pre and post node16 module resolution (of which many complexities reside, both for Node as well as for TypeScript type module resolution) ```typescript // Revision 0.31.0 import { Check } from '@sinclair/typebox/value/check' // Revision 0.32.0 import { Check } from '@sinclair/typebox/value' ``` ### Error Function The TypeSystemErrorFunction has been replaced with SetErrorFunction which can be imported on the `/errors` submodule. This change is generally a tidy up, and to reserve the `/system` submodule for type system policy configuration, as well as future Json Schema generation options (draft 2020-12) ```typescript // Revision 0.31.0 import { TypeSystemErrorFunction, ValueErrorType, DefaultErrorFunction } from '@sinclair/typebox/system' TypeSystemErrorFunction.Set((schema, errorType) => { // i18n override switch(errorType) { /* en-US */ case ValueErrorType.String: return 'Expected string' /* fr-FR */ case ValueErrorType.Number: return 'Nombre attendu' /* ko-KR */ case ValueErrorType.Boolean: return '예� 부울' /* en-US */ default: return DefaultErrorFunction(schema, errorType) } }) // Revision 0.32.0 import { SetErrorFunction, ValueErrorType, DefaultErrorFunction } from '@sinclair/typebox/errors' SetErrorFunction((error) => { // i18n override switch(error.errorType) { /* en-US */ case ValueErrorType.String: return 'Expected string' /* fr-FR */ case ValueErrorType.Number: return 'Nombre attendu' /* ko-KR */ case ValueErrorType.Boolean: return '예� 부울' /* en-US */ default: return DefaultErrorFunction(error) } }) ``` ### RegEx This RegEx function was flagged for deprecation on 0.30.0. It has been removed on Revision 0.32.0. Use the Type.RegExp type, or Type.String with a pattern to remain compatible with the Json Schema specification. ```typescript // Revision 0.31.0 const T = Type.RegEx(/abc/) // deprecation warning // Revision 0.32.0 const A = Type.RegExp(/abc/) // JavaScript Type const B = Type.String({ pattern: /abc/.source }) // Json Type ```sinclairzx81-typebox-e0ec98c/changelog/0.33.0.md000066400000000000000000000112411505437577000212510ustar00rootroot00000000000000### 0.33.0 --- ### Revision Updates - [Revision 0.33.22](https://github.com/sinclairzx81/typebox/pull/1065) - Rename TypeScript parsing infrastructure from `/parse` to `/syntax`. Remove Parse API from top level import. - [Revision 0.33.21](https://github.com/sinclairzx81/typebox/pull/1064) - [1063](https://github.com/sinclairzx81/typebox/issues/1063) Hotfix to resolve variable shadowing on Object (Parser Runtime) - [Revision 0.33.20](https://github.com/sinclairzx81/typebox/pull/1062) - Add TypeScript Parsing Infrastructure. Add Parse API to top level import. - [Revision 0.33.19](https://github.com/sinclairzx81/typebox/pull/1061) - Preemptive fix for TypeScript 5.8.0-dev (Type Fix for Immutable Function) - [Revision 0.33.18](https://github.com/sinclairzx81/typebox/pull/1060) - [1052](https://github.com/sinclairzx81/typebox/pull/1052) Export the Encode | Decode functions directly. Refactoring on Value submodule. - [1057](https://github.com/sinclairzx81/typebox/pull/1057) Export Object with var declaration to prevent global shadowing. Related Babel [Issue](https://github.com/babel/babel/issues/16943). - [Revision 0.33.17](https://github.com/sinclairzx81/typebox/pull/1042) - [1041](https://github.com/sinclairzx81/typebox/issues/1041) Avoid Exponentiation operator on Value.Hash - [Revision 0.33.16](https://github.com/sinclairzx81/typebox/pull/1015) - [1015](https://github.com/sinclairzx81/typebox/issues/1015) Add sub error iterators to ValueError - [Revision 0.33.15](https://github.com/sinclairzx81/typebox/pull/1025) - [1024](https://github.com/sinclairzx81/typebox/issues/1024) Fix to correctly resolve default Dates - [Revision 0.33.14](https://github.com/sinclairzx81/typebox/pull/1019) - [1019](https://github.com/sinclairzx81/typebox/pull/1019) Converting Large Numbers to BigInt - [Revision 0.33.13](https://github.com/sinclairzx81/typebox/pull/1011) - [1010](https://github.com/sinclairzx81/typebox/pull/1011) Fixes Value.Parse fails with recursive types - [Revision 0.33.12](https://github.com/sinclairzx81/typebox/pull/999) - [998](https://github.com/sinclairzx81/typebox/issues/998) Avoid losing precision when converting to bigints - [Revision 0.33.11](https://github.com/sinclairzx81/typebox/pull/994) - [993](https://github.com/sinclairzx81/typebox/issues/993) Prevent mutation on union values during Convert - [Revision 0.33.10](https://github.com/sinclairzx81/typebox/pull/991) - [907](https://github.com/sinclairzx81/typebox/issues/907) Add package.json metadata to specify possible side effect modules - [Revision 0.33.9](https://github.com/sinclairzx81/typebox/pull/984) - [887](https://github.com/sinclairzx81/typebox/issues/887) Generate Nested Intersect Errors - [Revision 0.33.8](https://github.com/sinclairzx81/typebox/pull/983) - [982](https://github.com/sinclairzx81/typebox/issues/982) Prevent Intersect Transform Encode callback from being called twice - [974](https://github.com/sinclairzx81/typebox/issues/974) Make strict the Encode and Decode return type - [975](https://github.com/sinclairzx81/typebox/issues/975) Support default annotation being assigned Functions for lazy value initialization on Create - [980](https://github.com/sinclairzx81/typebox/issues/980) Enable Mapping types to override user defined options from source type - [976](https://github.com/sinclairzx81/typebox/issues/976) Support Constraint Copy for Pick, Omit (inline with Partial / Required) (Trialing Implementation) - Flag Strict For Deprecation - [Revision 0.33.7](https://github.com/sinclairzx81/typebox/pull/964) - Additional updates to improve Default for enumerable objects. - [Revision 0.33.6](https://github.com/sinclairzx81/typebox/pull/963) - Add object traversal path for Default. Ensure enumerable objects are traversed. - [Revision 0.33.5](https://github.com/sinclairzx81/typebox/pull/959) - Provide better support for transforming properties with optional modifiers. - [Revision 0.33.4](https://github.com/sinclairzx81/typebox/pull/953) - Add Assert and Parse value functions. Add defacto AssertError type. - [Revision 0.33.3](https://github.com/sinclairzx81/typebox/pull/950) - Optimize Value Diff algorithm. Update edit sequence to INSERT, UPDATE then DELETE. - [Revision 0.33.2](https://github.com/sinclairzx81/typebox/pull/947) - Ensure user defined schema options are retained on mapping types, Pick, Omit and Mapped. - [Revision 0.33.1](https://github.com/sinclairzx81/typebox/pull/945) - Apply mutability fix for Intrinsic and Not schematics (inline with Default) - [Revision 0.33.0](https://github.com/sinclairzx81/typebox/pull/941) - Add InstanceMode to enable Clone, Freeze and Default schema initialization options. Optimize for Default. sinclairzx81-typebox-e0ec98c/changelog/0.34.0.md000066400000000000000000000315551505437577000212640ustar00rootroot00000000000000### 0.34.0 --- ### Revision Updates - [Revision 0.34.41](https://github.com/sinclairzx81/typebox/pull/1310) - Disable Node10 Module Resolution | TS7 Deprecation Warning. - [Revision 0.34.40](https://github.com/sinclairzx81/typebox/pull/1293) - Use Uniform over Reciprocal weighting on Cast Union Select - [Revision 0.34.39](https://github.com/sinclairzx81/typebox/pull/1296) - Guard for Array in Object and Record conversion - [Revision 0.34.38](https://github.com/sinclairzx81/typebox/pull/1282) - Preserve exact type matches in Union conversion - [Revision 0.34.37](https://github.com/sinclairzx81/typebox/pull/1278) - Fix Support nested Union selection when scoring for Cast - [Revision 0.34.36](https://github.com/sinclairzx81/typebox/pull/1276) - Fix Record Intersect on Cast - [Revision 0.34.35](https://github.com/sinclairzx81/typebox/pull/1265) - Deep Assign on Intersect Cast - [Revision 0.34.34](https://github.com/sinclairzx81/typebox/pull/1263) - Support Inference of Ref inside Recursive inside Module - [Revision 0.34.33](https://github.com/sinclairzx81/typebox/pull/1220) - Hotfix: Correct Invalid Import Specifier - [Revision 0.34.32](https://github.com/sinclairzx81/typebox/pull/1218) - Accelerated | High Performance Syntax Parsing - [Revision 0.34.31](https://github.com/sinclairzx81/typebox/pull/1209) - Use Tail Call Optimized Inference for Records with Large Union Keys - [Revision 0.34.30](https://github.com/sinclairzx81/typebox/pull/1198) - Additional Syntax Parsing Optimizations - [Revision 0.34.29](https://github.com/sinclairzx81/typebox/pull/1197) - Syntax Parsing Optimizations - [Revision 0.34.28](https://github.com/sinclairzx81/typebox/pull/1187) - Add Cast to Configurable Parse Pipeline - [Revision 0.34.27](https://github.com/sinclairzx81/typebox/pull/1182) - [1178](https://github.com/sinclairzx81/typebox/issues/1178) Support Deep Referential Transform Inference Inside Modules - [Revision 0.34.26](https://github.com/sinclairzx81/typebox/pull/1181) - Internal: Use Parser Context Threading for Generic Arguments. - [Revision 0.34.25](https://github.com/sinclairzx81/typebox/pull/1176) - Evaluate Conditional Expression for Instatiated Object Types - [Revision 0.34.24](https://github.com/sinclairzx81/typebox/pull/1175) - Add Support For Generic Parameter Syntax - [Revision 0.34.23](https://github.com/sinclairzx81/typebox/pull/1174) - Inline Instantiate Type Logic Local to Instantiate Module - [Revision 0.34.22](https://github.com/sinclairzx81/typebox/pull/1171) - Intrinsic Types Number, String, Boolean, etc Passthrough on Required and Partial Mapping - [Revision 0.34.21](https://github.com/sinclairzx81/typebox/pull/1168) - Reimplement Computed Record Types - [Revision 0.34.20](https://github.com/sinclairzx81/typebox/pull/1167) - Hotfix: Disable Computed Record Types - [Revision 0.34.19](https://github.com/sinclairzx81/typebox/pull/1166) - Hotfix: Republished due to NPM error - [Revision 0.34.18](https://github.com/sinclairzx81/typebox/pull/1164) - Hotfix: Internal Remap Imports - [Revision 0.34.17](https://github.com/sinclairzx81/typebox/pull/1162) - Add Argument() and Instantiate() Types and Instancing via Syntax support. - [Revision 0.34.16](https://github.com/sinclairzx81/typebox/pull/1156) - Export TypeBox String Parsing Infrastructure - [Revision 0.34.15](https://github.com/sinclairzx81/typebox/pull/1148) - [1147](https://github.com/sinclairzx81/typebox/issues/1147) Fix incorrect truncation for integers that exceed 32-bit values in Value.Convert - [Revision 0.34.14](https://github.com/sinclairzx81/typebox/pull/1140) - [1139](https://github.com/sinclairzx81/typebox/issues/1139) Update TypeCompiler Check for Promise (use instanceof Promise over Thenable check) - [Revision 0.34.13](https://github.com/sinclairzx81/typebox/pull/1124) - Pre emptive fix for TypeScript 5.8.0-nightly to resolve symbol narrowing on Convert. - [Revision 0.34.12](https://github.com/sinclairzx81/typebox/pull/1120) - [1119](https://github.com/sinclairzx81/typebox/issues/1119) Fix for Mutate Object Comparison - [1117](https://github.com/sinclairzx81/typebox/issues/1117) Re-Add Type.Recursive Documentation - [Revision 0.34.11](https://github.com/sinclairzx81/typebox/pull/1110) - Fix Compiler Emit for Deeply Referential Module Types - [Revision 0.34.10](https://github.com/sinclairzx81/typebox/pull/1107) - Fix Declaration Emit for Index and Mapped Types - Fix Record Inference Presentation when Embedded in Modules - Fix Record Mapping when using TImport as Key - Add Encode to Parse Operation List - [Revision 0.34.9](https://github.com/sinclairzx81/typebox/pull/1101) - User Defined Parse Pipelines - Access to Schema and References on TypeCheck - [Revision 0.34.8](https://github.com/sinclairzx81/typebox/pull/1098) - Fix for Computed Readonly and Optional Properties - [Revision 0.34.7](https://github.com/sinclairzx81/typebox/pull/1093) - Revert Ref(Schema) Signature with Deprecation Notice - [Revision 0.34.6](https://github.com/sinclairzx81/typebox/pull/1090) - Add Computed To Type and Kind Guards (IsSchema) - [Revision 0.34.5](https://github.com/sinclairzx81/typebox/pull/1088) - Record Types no longer TCompute for TRef Value Type (Modules) - [Revision 0.34.4](https://github.com/sinclairzx81/typebox/pull/1085) - Inference Path for Enum within Modules - [Revision 0.34.3](https://github.com/sinclairzx81/typebox/pull/1083) - Retain Array Elements on Value Default - [Revision 0.34.2](https://github.com/sinclairzx81/typebox/pull/1082) - Resolve import pathing issue introduced on 0.34.1 - [Revision 0.34.1](https://github.com/sinclairzx81/typebox/pull/1080) - Implement Computed Type Deref in Modules ## [0.34.0](https://www.npmjs.com/package/@sinclair/typebox/v/0.34.0) ## Overview Revision 0.34.0 represents a significant milestone for the TypeBox project. This update changes how TypeBox manages type references (Ref) and introduces a new Module type to support mutual recursion and self-referencing types. Additionally, it includes a new submodule for parsing TypeScript syntax directly into TypeBox types. Please note that this release includes breaking changes to Ref and some deprecations. These updates require a minor semver revision. ## Contents - [Enhancements](#Enhancements) - [Module Types](#Module-Types) - [Syntax Types](#Syntax-Types) - [Breaking Changes](#Breaking-Changes) - [Ref](#Ref) - [Deref](#Deref) - [Strict](#Strict) ## Enhancements Below are the enhancements introduced in Version 0.34.0. ### Module Types Revision 0.34.0 introduces a new type, called Module. Modules are represented as JSON Schema $def schematics, specifically designed to support both mutual and self-recursive types. This addition resolves a longstanding issue in TypeBox, where complex recursive structures often encountered "definition order" problems, making certain recursive structures difficult to represent cleanly. With Modules, you can now define schematics within a Module context, allowing them to be referenced within the type system through a separate inference operation. ```typescript // The following creates a circular recursive type. const Module = Type.Module({ A: Type.Object({ b: Type.Ref('B') // Ref B: }), B: Type.Object({ c: Type.Ref('C') // Ref C: }), C: Type.Object({ a: Type.Ref('A') // Ref A: }), }) // Module types must be imported before use. const A = Module.Import('A') // const A: TImport<{...}, 'A'> type A = Static // type A = { // b: { // c: { // a: { // b: ... // } // } // } // } ``` ### Syntax Types Revision 0.34.0 introduces a new submodule for parsing TypeScript syntax directly into TypeBox types, implemented both at runtime and within the type system. This feature was made possible through the development of a separate project, [ParseBox](https://github.com/sinclairzx81/parsebox) (MIT-licensed), which provides a symmetric runtime and type-level parsing infrastructure. As of 0.34.0, Syntax Types are available as an opt-in feature, with the parsing infrastructure adding approximately 10kb (minified) to the existing type builder. With further optimizations, this feature may be elevated to a top-level import in future updates to minimize bundling size. To use Syntax Types, import them from the `@sinclair/typebox/syntax` path. ```typescript import { Parse } from '@sinclair/typebox/syntax' // All primitive types are supported const A = Parse('string') // const A: TString const B = Parse('number') // const B: TNumber const C = Parse('boolean') // const C: TBoolean // ... Multiline parsing is supported (but comments are not) const T = Parse(`{ x: number y: number z: number }`) // ... Parametertized parsing is supported const O = Parse({ T }, `T & { w: number }`) // const O: TIntersect<[ // TObject<{ // x: TNumber, // y: TNumber, // z: TNumber, // }>, // TObject<{ // w: TNumber // }> // ]> // ... Module parsing is also supported. const Math = Parse(`module Math { export interface X { x: number } export interface Y { y: number } export interface Z { z: number } export interface Vector extends X, Y, Z { type: 'Vector' } }`) const Vector = Math.Import('Vector') ``` Runtime parsing performance should be quite good; however, static parsing performance could be improved. TypeScript will invoke the parser for each property accessed at design time. Ongoing efforts within the ParseBox project aim to optimize string parsing in TypeScript, with additional research underway into type-level caching strategies within the TypeScript compiler. Additional optimizations will be explored over the course of 0.34.x. ## Breaking Changes The following are the breaking changes in Revision 0.34.0. ### Ref Revision 0.34.0 introduces a breaking change to Ref, modifying its signature to accept only constant string values. Previously, Ref could accept an existing TypeBox type, provided it had an $id assigned. ```typescript // Revision 0.33.0 const T = Type.String({ $id: 'T' }) const R = Type.Ref(T) type R = Static // type R = string // Revision 0.34.0 const T = Type.String({ $id: 'T' }) const R = Type.Ref('T') type R = Static // type R = unknown ``` In Revision 0.34.0, the inferred type for Ref is now unknown. Implementations using the previous version of Ref can switch to Unsafe to type the reference to the target value. ```typescript // Revision 0.34.0 const T = Type.String({ $id: 'T' }) const R = Type.Unsafe>(Type.Ref('T')) type R = Static // type R = string ``` ### Deref Revision 0.34.0 removes the Deref type, which was previously used to dereference schematics. Since the Ref signature has changed from TSchema to string, there is no longer a way to resolve reference types accurately. TypeBox may provide a prototype example of this type upon request. ### Strict Revision 0.34.0 removes the Strict type from the Type Builder, which was deprecated in version 0.33.8. This type was introduced several years ago in response to a change in Ajv that prohibited unknown keywords. At that time, TypeBox used string property keys for `kind` and `modifier`, which required either Ajv configuration or the use of Strict. These properties have since been updated to Symbol properties, resolving the issues with Ajv. However, the Strict type remained due to some use in ecosystem projects, which has since reduced. For those who still need Strict, the recommended approach is to use the JSON stringify/parse method outlined in the deprecation notice. ```typescript /** * @deprecated `[Json]` Omits compositing symbols from this schema. It is recommended * to use the JSON parse/stringify to remove compositing symbols if needed. This * is how Strict works internally. * * ```typescript * JSON.parse(JSON.stringify(Type.String())) * ``` */ export function Strict(schema: T): TStrict { return JSON.parse(JSON.stringify(schema)) } ```sinclairzx81-typebox-e0ec98c/example/000077500000000000000000000000001505437577000177135ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/example/annotation/000077500000000000000000000000001505437577000220655ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/example/annotation/annotation.ts000066400000000000000000000166171505437577000246220ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import * as Types from '@sinclair/typebox' // ------------------------------------------------------------------- // Annotation // // Generates TypeScript Type Annotations from TypeBox types // ------------------------------------------------------------------- /** Generates TypeScript Type Annotations from TypeBox types */ export namespace Annotation { // ----------------------------------------------------------------- // Escape // ----------------------------------------------------------------- function Escape(content: string) { return content.replace(/'/g, "\\'") } // ----------------------------------------------------------------- // Types // ----------------------------------------------------------------- function Intersect(schema: Types.TSchema[], references: Types.TSchema[]): string { const [L, ...R] = schema // prettier-ignore return R.length === 0 ? `${Visit(L, references)}` : `${Visit(L, references)} & ${Intersect(R, references)}` } function Union(schema: Types.TSchema[], references: Types.TSchema[]): string { const [L, ...R] = schema // prettier-ignore return R.length === 0 ? `${Visit(L, references)}` : `${Visit(L, references)} | ${Union(R, references)}` } function Tuple(schema: Types.TSchema[], references: Types.TSchema[]): string { const [L, ...R] = schema // prettier-ignore return R.length > 0 ? `${Visit(L, references)}, ${Tuple(R, references)}` : `` } function Property(schema: Types.TProperties, K: string, references: Types.TSchema[]): string { const TK = schema[K] // prettier-ignore return ( Types.TypeGuard.IsOptional(TK) && Types.TypeGuard.IsReadonly(TK) ? `readonly ${K}?: ${Visit(TK, references)}` : Types.TypeGuard.IsReadonly(TK) ? `readonly ${K}: ${Visit(TK, references)}` : Types.TypeGuard.IsOptional(TK) ? `${K}?: ${Visit(TK, references)}` : `${K}: ${Visit(TK, references)}` ) } function Properties(schema: Types.TProperties, K: string[], references: Types.TSchema[]): string { const [L, ...R] = K // prettier-ignore return R.length === 0 ? `${Property(schema, L, references)}` : `${Property(schema, L, references)}; ${Properties(schema, R, references)}` } function Parameters(schema: Types.TSchema[], I: number, references: Types.TSchema[]): string { const [L, ...R] = schema // prettier-ignore return R.length === 0 ? `param_${I}: ${Visit(L, references)}` : `param_${I}: ${Visit(L, references)}, ${Parameters(R, I + 1, references)}` } function Literal(schema: Types.TLiteral, references: Types.TSchema[]): string { return typeof schema.const === 'string' ? `'${Escape(schema.const)}'` : schema.const.toString() } function Record(schema: Types.TRecord, references: Types.TSchema[]): string { // prettier-ignore return ( Types.PatternBooleanExact in schema.patternProperties ? `Record` : Types.PatternNumberExact in schema.patternProperties ? `Record` : Types.PatternStringExact in schema.patternProperties ? `Record` : `{}` ) } function TemplateLiteral(schema: Types.TTemplateLiteral, references: Types.TSchema[]) { const E = Types.TemplateLiteralParseExact(schema.pattern) if (!Types.IsTemplateLiteralExpressionFinite(E)) return 'string' return [...Types.TemplateLiteralExpressionGenerate(E)].map((literal) => `'${Escape(literal)}'`).join(' | ') } function Visit(schema: Types.TSchema, references: Types.TSchema[]): string { // prettier-ignore return ( Types.TypeGuard.IsAny(schema) ? 'any' : Types.TypeGuard.IsArray(schema) ? `${Visit(schema.items, references)}[]` : Types.TypeGuard.IsAsyncIterator(schema) ? `AsyncIterableIterator<${Visit(schema.items, references)}>` : Types.TypeGuard.IsBigInt(schema) ? `bigint` : Types.TypeGuard.IsBoolean(schema) ? `boolean` : Types.TypeGuard.IsConstructor(schema) ? `new (${Parameters(schema.parameter, 0, references)}) => ${Visit(schema.returns, references)}` : Types.TypeGuard.IsDate(schema) ? 'Date' : Types.TypeGuard.IsFunction(schema) ? `(${Parameters(schema.parameters, 0, references)}) => ${Visit(schema.returns, references)}` : Types.TypeGuard.IsInteger(schema) ? 'number' : Types.TypeGuard.IsIntersect(schema) ? `(${Intersect(schema.allOf, references)})` : Types.TypeGuard.IsIterator(schema) ? `IterableIterator<${Visit(schema.items, references)}>` : Types.TypeGuard.IsLiteral(schema) ? `${Literal(schema, references)}` : Types.TypeGuard.IsNever(schema) ? `never` : Types.TypeGuard.IsNull(schema) ? `null` : Types.TypeGuard.IsNot(schema) ? 'unknown' : Types.TypeGuard.IsNumber(schema) ? 'number' : Types.TypeGuard.IsObject(schema) ? `{ ${Properties(schema.properties, Object.getOwnPropertyNames(schema.properties), references)} }` : Types.TypeGuard.IsPromise(schema) ? `Promise<${Visit(schema.item, references)}>` : Types.TypeGuard.IsRecord(schema) ? `${Record(schema, references)}` : Types.TypeGuard.IsRef(schema) ? `${Visit(Types.Type.Deref(schema, references), references)}` : Types.TypeGuard.IsString(schema) ? 'string' : Types.TypeGuard.IsSymbol(schema) ? 'symbol' : Types.TypeGuard.IsTemplateLiteral(schema) ? `${TemplateLiteral(schema, references)}` : Types.TypeGuard.IsThis(schema) ? 'unknown' : // requires named interface Types.TypeGuard.IsTuple(schema) ? `[${Tuple(schema.items || [], references)}]` : Types.TypeGuard.IsUint8Array(schema) ? `Uint8Array` : Types.TypeGuard.IsUndefined(schema) ? 'undefined' : Types.TypeGuard.IsUnion(schema) ? `${Union(schema.anyOf, references)}` : Types.TypeGuard.IsVoid(schema) ? `void` : 'unknown' ) } /** Generates a TypeScript annotation for the given schema */ export function Code(schema: Types.TSchema, references: Types.TSchema[] = []): string { return Visit(schema, references) } }sinclairzx81-typebox-e0ec98c/example/annotation/index.ts000066400000000000000000000000341505437577000235410ustar00rootroot00000000000000export * from './annotation'sinclairzx81-typebox-e0ec98c/example/collections/000077500000000000000000000000001505437577000222315ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/example/collections/array.ts000066400000000000000000000450141505437577000237230ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/collections The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { TypeCheck, TypeCompiler, ValueError } from '@sinclair/typebox/compiler' import { TSchema, Static, TypeBoxError } from '@sinclair/typebox' import { Value } from '@sinclair/typebox/value' // ---------------------------------------------------------------- // TypeArrayError // ---------------------------------------------------------------- export class TypeArrayError extends TypeBoxError { constructor(message: string) { super(`${message}`) } } export class TypeArrayLengthError extends TypeBoxError { constructor() { super('arrayLength not a number') } } // ---------------------------------------------------------------- // TypeArray // ---------------------------------------------------------------- export class TypeArray implements Iterable> { readonly #typeCheck: TypeCheck readonly #values: Static[] constructor(schema: T, arrayLength: number = 0) { if (typeof arrayLength !== 'number') throw new TypeArrayLengthError() this.#typeCheck = TypeCompiler.Compile(schema) this.#values = new Array(arrayLength) for (let i = 0; i < arrayLength; i++) { this.#values[i] = Value.Create(schema) } } // --------------------------------------------------- // Indexer // --------------------------------------------------- /** Sets the value at the given index */ public set(index: number, item: Static): void { this.#assertIndexInBounds(index) this.#assertItem(index, item) this.#values[index] = item } // --------------------------------------------------- // Array // --------------------------------------------------- /** Iterator for values in this array */ public [Symbol.iterator](): IterableIterator> { return this.#values[Symbol.iterator]() as IterableIterator } /** Gets the value at the given index */ public at(index: number): Static { this.#assertIndexInBounds(index) return this.#values[index] as T } /** * Gets the length of the array. This is a number one higher than the highest index in the array. */ public get length(): number { return this.#values.length } /** * Returns a string representation of an array. */ public toString(): string { return this.#values.toString() } /** * Returns a string representation of an array. The elements are converted to string using their toLocaleString methods. */ public toLocaleString(): string { return this.#values.toLocaleString() } /** * Removes the last element from an array and returns it. * If the array is empty, undefined is returned and the array is not modified. */ public pop(): Static | undefined { return this.#values.pop() } /** * Appends new elements to the end of an array, and returns the new length of the array. * @param items New elements to add to the array. */ public push(...items: Static[]): number { this.#assertItems(items) return this.#values.push(...items) } /** * Combines two or more arrays. * This method returns a new array without modifying any existing arrays. * @param items Additional arrays and/or items to add to the end of the array. */ public concat(...items: ConcatArray>[]): Static[] /** * Combines two or more arrays. * This method returns a new array without modifying any existing arrays. * @param items Additional arrays and/or items to add to the end of the array. */ public concat(...items: (T | ConcatArray>)[]): Static[] { this.#assertItems(items) return this.#values.concat(...items) as Static[] } /** * Adds all the elements of an array into a string, separated by the specified separator string. * @param separator A string used to separate one element of the array from the next in the resulting string. If omitted, the array elements are separated with a comma. */ public join(separator?: string): string { return this.#values.join(separator) } /** * Reverses the elements in an array in place. * This method mutates the array and returns a reference to the same array. */ public reverse(): Static[] { return this.#values.reverse() as Static[] } /** * Removes the first element from an array and returns it. * If the array is empty, undefined is returned and the array is not modified. */ public shift(): Static | undefined { return this.#values.shift() as Static | undefined } /** * Returns a copy of a section of an array. * For both start and end, a negative index can be used to indicate an offset from the end of the array. * For example, -2 refers to the second to last element of the array. * @param start The beginning index of the specified portion of the array. * If start is undefined, then the slice begins at index 0. * @param end The end index of the specified portion of the array. This is exclusive of the element at the index 'end'. * If end is undefined, then the slice extends to the end of the array. */ public slice(start?: number, end?: number): Static[] { return this.#values.slice(start, end) as Static[] } /** * Sorts an array in place. * This method mutates the array and returns a reference to the same array. * @param compareFn Function used to determine the order of the elements. It is expected to return * a negative value if the first argument is less than the second argument, zero if they're equal, and a positive * value otherwise. If omitted, the elements are sorted in ascending, ASCII character order. * ```ts * [11,2,22,1].sort((a, b) => a - b) * ``` */ public sort(compareFn?: (a: Static, b: Static) => number): this { this.#values.sort(compareFn as any) return this } /** * Removes elements from an array and, if necessary, inserts new elements in their place, returning the deleted elements. * @param start The zero-based location in the array from which to start removing elements. * @param deleteCount The number of elements to remove. * @returns An array containing the elements that were deleted. */ public splice(start: number, deleteCount?: number): Static[] /** * Removes elements from an array and, if necessary, inserts new elements in their place, returning the deleted elements. * @param start The zero-based location in the array from which to start removing elements. * @param deleteCount The number of elements to remove. * @param items Elements to insert into the array in place of the deleted elements. * @returns An array containing the elements that were deleted. */ public splice(start: number, deleteCount: number, ...items: Static[]): Static[] { this.#assertItems(items) return this.#values.splice(start, deleteCount, items) as Static[] } /** * Inserts new elements at the start of an array, and returns the new length of the array. * @param items Elements to insert at the start of the array. */ public unshift(...items: Static[]): number { this.#assertItems(items) return this.#values.unshift(items) } /** * Returns the index of the first occurrence of a value in an array, or -1 if it is not present. * @param searchElement The value to locate in the array. * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0. */ public indexOf(searchElement: Static, fromIndex?: number): number { return this.#values.indexOf(searchElement, fromIndex) } /** * Returns the index of the last occurrence of a specified value in an array, or -1 if it is not present. * @param searchElement The value to locate in the array. * @param fromIndex The array index at which to begin searching backward. If fromIndex is omitted, the search starts at the last index in the array. */ public lastIndexOf(searchElement: Static, fromIndex?: number): number { return this.#values.lastIndexOf(searchElement, fromIndex) } /** * Determines whether all the members of an array satisfy the specified test. * @param predicate A function that accepts up to three arguments. The every method calls * the predicate function for each element in the array until the predicate returns a value * which is coercible to the Boolean value false, or until the end of the array. * @param thisArg An object to which the this keyword can refer in the predicate function. * If thisArg is omitted, undefined is used as the this value. */ public every(predicate: (value: Static, index: number, array: Static[]) => value is Static, thisArg?: any): this is Static[] /** * Determines whether all the members of an array satisfy the specified test. * @param predicate A function that accepts up to three arguments. The every method calls * the predicate function for each element in the array until the predicate returns a value * which is coercible to the Boolean value false, or until the end of the array. * @param thisArg An object to which the this keyword can refer in the predicate function. * If thisArg is omitted, undefined is used as the this value. */ public every(predicate: (value: Static, index: number, array: Static[]) => unknown, thisArg?: any): boolean { return this.#values.every(predicate as any, thisArg) } /** * Determines whether the specified callback function returns true for any element of an array. * @param predicate A function that accepts up to three arguments. The some method calls * the predicate function for each element in the array until the predicate returns a value * which is coercible to the Boolean value true, or until the end of the array. * @param thisArg An object to which the this keyword can refer in the predicate function. * If thisArg is omitted, undefined is used as the this value. */ public some(predicate: (value: Static, index: number, array: T[]) => unknown, thisArg?: any): boolean { return this.#values.some(predicate as any, thisArg) } /** * Performs the specified action for each element in an array. * @param callbackfn A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array. * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value. */ public forEach(callbackfn: (value: Static, index: number, array: Static[]) => void, thisArg?: any): void { return this.#values.forEach(callbackfn as any, thisArg) } /** * Calls a defined callback function on each element of an array, and returns an array that contains the results. * @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array. * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value. */ public map(callbackfn: (value: Static, index: number, array: Static[]) => U, thisArg?: any): U[] { return this.#values.map(callbackfn as any, thisArg) } /** * Returns the elements of an array that meet the condition specified in a callback function. * @param predicate A function that accepts up to three arguments. The filter method calls the predicate function one time for each element in the array. * @param thisArg An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value. */ public filter(predicate: (value: Static, index: number, array: Static[]) => value is Static, thisArg?: any): Static[] /** * Returns the elements of an array that meet the condition specified in a callback function. * @param predicate A function that accepts up to three arguments. The filter method calls the predicate function one time for each element in the array. * @param thisArg An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value. */ public filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[] public filter(predicate: any, thisArg: any): any { return this.#values.filter(predicate as any, thisArg) } /** * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array. * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value. */ public reduce(callbackfn: (previousValue: Static, currentValue: Static, currentIndex: number, array: T[]) => Static): Static public reduce(callbackfn: (previousValue: Static, currentValue: Static, currentIndex: number, array: T[]) => Static, initialValue: Static): Static /** * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array. * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value. */ public reduce(callbackfn: (previousValue: U, currentValue: Static, currentIndex: number, array: Static[]) => U, initialValue: U): U public reduce(callbackfn: any, initialValue?: any): any { return this.#values.reduce(callbackfn, initialValue) } /** * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array. * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value. */ public reduceRight(callbackfn: (previousValue: Static, currentValue: Static, currentIndex: number, array: Static[]) => Static): Static public reduceRight(callbackfn: (previousValue: Static, currentValue: Static, currentIndex: number, array: Static[]) => Static, initialValue: T): Static /** * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array. * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value. */ public reduceRight(callbackfn: (previousValue: U, currentValue: Static, currentIndex: number, array: Static[]) => U, initialValue: U): U public reduceRight(callbackfn: any, initialValue?: any): any { return this.#values.reduceRight(callbackfn, initialValue) } // --------------------------------------------------- // Assertions // --------------------------------------------------- #formatError(errors: ValueError[]) { return errors.map((error) => `${error.message} ${error.path}`).join('. ') } /** Asserts the given values */ #assertIndexInBounds(index: number) { if (index >= 0 && index < this.#values.length) return throw new TypeArrayError(`Index ${index} is outside the bounds of this Array.`) } /** Asserts the given values */ #assertItem(index: number, item: unknown): asserts item is Static { if (this.#typeCheck.Check(item)) return const message = this.#formatError([...this.#typeCheck.Errors(item)]) throw new TypeArrayError(`Item at Index ${index} is invalid. ${message}`) } /** Asserts the given values */ #assertItems(items: unknown[]): asserts items is Static[] { for (let i = 0; i < items.length; i++) { this.#assertItem(i, items[i]) } } /** Creates a typed array from an existing array */ public static from(schema: T, iterable: IterableIterator> | Array>): TypeArray { if (globalThis.Array.isArray(iterable)) { const array = new TypeArray(schema, iterable.length) for (let i = 0; i < iterable.length; i++) { array.set(i, iterable[i]) } return array } const array = new TypeArray(schema) for (const value of iterable) { array.push(value) } return array } } sinclairzx81-typebox-e0ec98c/example/collections/index.ts000066400000000000000000000025461505437577000237170ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/collections The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './array' export * from './map' export * from './set' sinclairzx81-typebox-e0ec98c/example/collections/map.ts000066400000000000000000000144231505437577000233620ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/collections The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { TypeCheck, TypeCompiler, ValueError } from '@sinclair/typebox/compiler' import { TSchema, Static, TypeBoxError } from '@sinclair/typebox' import { Value } from '@sinclair/typebox/value' // ---------------------------------------------------------------- // TypeMapKeyError // ---------------------------------------------------------------- export class TypeMapKeyError extends TypeBoxError { constructor(message: string) { super(`${message} for key`) } } export class TypeMapValueError extends TypeBoxError { constructor(key: unknown, message: string) { super(`${message} for key ${JSON.stringify(key)}`) } } // ---------------------------------------------------------------- // TypeMap // ---------------------------------------------------------------- // prettier-ignore type TypeMapEntries = | Iterable<[Static, Static]> | Array<[Static, Static]> /** Runtime type checked Map collection */ export class TypeMap { readonly #keycheck: TypeCheck readonly #valuecheck: TypeCheck readonly #keys: Map> readonly #values: Map> /** Constructs a new HashMap of the given key and value types. */ constructor(key: K, value: V, entries: TypeMapEntries = []) { this.#keycheck = TypeCompiler.Compile(key) this.#valuecheck = TypeCompiler.Compile(value) this.#keys = new Map>() this.#values = new Map>() for (const [key, value] of entries) { this.set(key, value) } } /** Iterator for this TypeMap */ public *[Symbol.iterator](): IterableIterator<[Static, Static]> { for (const [key, value] of this.#values) { yield [this.#keys.get(key)!, value] } } /** Iterator for the keys in this TypeMap */ public *keys(): IterableIterator> { yield* this.#keys.values() } /** Iterator for the values in this TypeMap */ public *values(): IterableIterator> { yield* this.#values.values() } /** Clears all entries in this map */ public clear(): void { this.#values.clear() this.#keys.clear() } /** Executes a provided function once per each key/value pair in the Map, in insertion order. */ public forEach(callbackfn: (value: Static, key: Static, map: TypeMap) => void, thisArg?: any): void { this.#values.forEach((value, key) => callbackfn(value, this.#keys.get(key)!, this)) } /** @returns the number of elements in the TypeMap. */ public get size(): number { return this.#values.size } /** * @returns boolean indicating whether an element with the specified key exists or not. */ public has(key: Static): boolean { this.#assertKey(key) return this.#values.has(this.#encodeKey(key)) } /** * Returns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map. * @returns Returns the element associated with the specified key. If no element is associated with the specified key, undefined is returned. */ public get(key: Static): Static | undefined { this.#assertKey(key) return this.#values.get(this.#encodeKey(key))! } /** * Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated. */ public set(key: Static, value: Static) { this.#assertKey(key) this.#assertValue(key, value) const encodedKey = this.#encodeKey(key) this.#keys.set(encodedKey, key) this.#values.set(encodedKey, value) } /** * @returns true if an element in the Map existed and has been removed, or false if the element does not exist. */ public delete(key: Static): boolean { this.#assertKey(key) const encodedKey = this.#encodeKey(key) this.#keys.delete(encodedKey) return this.#values.delete(encodedKey) } // --------------------------------------------------- // Encoder // --------------------------------------------------- /** Encodes the key as a 64bit numeric */ #encodeKey(key: Static) { return Value.Hash(key) } // --------------------------------------------------- // Assertions // --------------------------------------------------- #formatError(errors: ValueError[]) { return errors .map((error) => `${error.message} ${error.path}`) .join('. ') .trim() } /** Asserts the key matches the key schema */ #assertKey(key: unknown): asserts key is Static { if (this.#keycheck.Check(key)) return throw new TypeMapKeyError(this.#formatError([...this.#keycheck.Errors(key)])) } /** Asserts the key matches the value schema */ #assertValue(key: Static, value: unknown): asserts value is Static { if (this.#valuecheck.Check(value)) return throw new TypeMapValueError(key, this.#formatError([...this.#valuecheck.Errors(value)])) } } sinclairzx81-typebox-e0ec98c/example/collections/readme.md000066400000000000000000000002351505437577000240100ustar00rootroot00000000000000# Collections This example implements runtime type safe generic `Array`, `Map` and `Set` collection types using TypeBox types as the generic type arguments.sinclairzx81-typebox-e0ec98c/example/collections/set.ts000066400000000000000000000102261505437577000233750ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/collections The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { TypeCheck, TypeCompiler, ValueError } from '@sinclair/typebox/compiler' import { TSchema, Static, TypeBoxError } from '@sinclair/typebox' import { Value } from '@sinclair/typebox/value' // ---------------------------------------------------------------- // Errors // ---------------------------------------------------------------- export class TypeSetError extends TypeBoxError { constructor(message: string) { super(`${message}`) } } // ---------------------------------------------------------------- // TypeSet // ---------------------------------------------------------------- /** Runtime type checked Set collection */ export class TypeSet { readonly #valuecheck: TypeCheck readonly values: Map> constructor(schema: T, iterable: Array | Iterable = []) { this.#valuecheck = TypeCompiler.Compile(schema) this.values = new Map>() for (const value of iterable) { this.add(value) } } /** Adds a value to this set */ public add(value: Static): this { this.#assertValue(value) this.values.set(this.#encodeKey(value), value) return this } /** Clears the values in this set */ public clear(): void { this.values.clear() } /** * Removes a specified value from the Set. * @returns Returns true if an element in the Set existed and has been removed, or false if the element does not exist. */ public delete(value: Static): boolean { return this.values.delete(this.#encodeKey(value)) } /** Executes a provided function once per each value in the Set object, in insertion order. */ public forEach(callbackfn: (value: Static, value2: Static, set: TypeSet) => void, thisArg?: any): void { this.values.forEach((value, value2) => callbackfn(value, value2, this), thisArg) } /** * @returns a boolean indicating whether an element with the specified value exists in the Set or not. */ public has(value: Static): boolean { return this.values.has(this.#encodeKey(value)) } /** * @returns the number of (unique) elements in Set. */ public get size(): number { return this.values.size } // --------------------------------------------------- // Encoder // --------------------------------------------------- #encodeKey(value: Static) { return Value.Hash(value) } // --------------------------------------------------- // Assertions // --------------------------------------------------- /** Formats errors */ #formatError(errors: ValueError[]) { return errors .map((error) => `${error.message} ${error.path}`) .join('. ') .trim() } /** Asserts the key matches the value schema */ #assertValue(value: unknown): asserts value is Static { if (this.#valuecheck.Check(value)) return throw new TypeSetError(this.#formatError([...this.#valuecheck.Errors(value)])) } } sinclairzx81-typebox-e0ec98c/example/formats/000077500000000000000000000000001505437577000213665ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/example/formats/date-time.ts000066400000000000000000000031641505437577000236130ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/format The MIT License (MIT) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { IsDate } from './date' import { IsTime } from './time' const DATE_TIME_SEPARATOR = /t|\s/i /** * `[ajv-formats]` ISO8601 DateTime * @example `2020-12-12T20:20:40+00:00` */ export function IsDateTime(value: string, strictTimeZone?: boolean): boolean { const dateTime: string[] = value.split(DATE_TIME_SEPARATOR) return dateTime.length === 2 && IsDate(dateTime[0]) && IsTime(dateTime[1], strictTimeZone) } sinclairzx81-typebox-e0ec98c/example/formats/date.ts000066400000000000000000000035211505437577000226540ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/format The MIT License (MIT) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ const DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] const DATE = /^(\d\d\d\d)-(\d\d)-(\d\d)$/ function IsLeapYear(year: number): boolean { return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0) } /** * `[ajv-formats]` ISO8601 Date component * @example `2020-12-12` */ export function IsDate(value: string): boolean { const matches: string[] | null = DATE.exec(value) if (!matches) return false const year: number = +matches[1] const month: number = +matches[2] const day: number = +matches[3] return month >= 1 && month <= 12 && day >= 1 && day <= (month === 2 && IsLeapYear(year) ? 29 : DAYS[month]) } sinclairzx81-typebox-e0ec98c/example/formats/email.ts000066400000000000000000000031241505437577000230250ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/format The MIT License (MIT) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ const Email = /^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i /** * `[ajv-formats]` Internet Email Address [RFC 5321, section 4.1.2.](http://tools.ietf.org/html/rfc5321#section-4.1.2) * @example `user@domain.com` */ export function IsEmail(value: string): boolean { return Email.test(value) } sinclairzx81-typebox-e0ec98c/example/formats/index.ts000066400000000000000000000027321505437577000230510ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/format The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './date-time' export * from './date' export * from './email' export * from './ipv4' export * from './ipv6' export * from './time' export * from './url' export * from './uuid' sinclairzx81-typebox-e0ec98c/example/formats/ipv4.ts000066400000000000000000000030721505437577000226220ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/format The MIT License (MIT) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ const IPv4 = /^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/ /** * `[ajv-formats]` IPv4 address according to dotted-quad ABNF syntax as defined in [RFC 2673, section 3.2](http://tools.ietf.org/html/rfc2673#section-3.2) * @example `192.168.0.1` */ export function IsIPv4(value: string): boolean { return IPv4.test(value) } sinclairzx81-typebox-e0ec98c/example/formats/ipv6.ts000066400000000000000000000047231505437577000226300ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/format The MIT License (MIT) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ const IPv6 = /^((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))$/i /** * `[ajv-formats]` IPv6 address as defined in [RFC 2373, section 2.2](http://tools.ietf.org/html/rfc2373#section-2.2). * @example `2001:0db8:85a3:0000:0000:8a2e:0370:7334` */ export function IsIPv6(value: string): boolean { return IPv6.test(value) } sinclairzx81-typebox-e0ec98c/example/formats/time.ts000066400000000000000000000041211505437577000226720ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/format The MIT License (MIT) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ const TIME = /^(\d\d):(\d\d):(\d\d(?:\.\d+)?)(z|([+-])(\d\d)(?::?(\d\d))?)?$/i /** * `[ajv-formats]` ISO8601 Time component * @example `20:20:39+00:00` */ export function IsTime(value: string, strictTimeZone?: boolean): boolean { const matches: string[] | null = TIME.exec(value) if (!matches) return false const hr: number = +matches[1] const min: number = +matches[2] const sec: number = +matches[3] const tz: string | undefined = matches[4] const tzSign: number = matches[5] === '-' ? -1 : 1 const tzH: number = +(matches[6] || 0) const tzM: number = +(matches[7] || 0) if (tzH > 23 || tzM > 59 || (strictTimeZone && !tz)) return false if (hr <= 23 && min <= 59 && sec < 60) return true const utcMin = min - tzM * tzSign const utcHr = hr - tzH * tzSign - (utcMin < 0 ? 1 : 0) return (utcHr === 23 || utcHr === -1) && (utcMin === 59 || utcMin === -1) && sec < 61 } sinclairzx81-typebox-e0ec98c/example/formats/url.ts000066400000000000000000000036331505437577000225450ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/format The MIT License (MIT) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ const Url = /^(?:https?|wss?|ftp):\/\/(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u{00a1}-\u{ffff}]+-)*[a-z0-9\u{00a1}-\u{ffff}]+)(?:\.(?:[a-z0-9\u{00a1}-\u{ffff}]+-)*[a-z0-9\u{00a1}-\u{ffff}]+)*(?:\.(?:[a-z\u{00a1}-\u{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/iu /** * `[ajv-formats:deprecated]` A uniform resource locator as defined in [RFC 1738](https://www.rfc-editor.org/rfc/rfc1738) * @example `http://domain.com` */ export function IsUrl(value: string) { return Url.test(value) } sinclairzx81-typebox-e0ec98c/example/formats/uuid.ts000066400000000000000000000030371505437577000227070ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/format The MIT License (MIT) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ const Uuid = /^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i /** * `[ajv-formats]` A Universally Unique Identifier as defined by [RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122). * @example `9aa8a673-8590-4db2-9830-01755844f7c1` */ export function IsUuid(value: string): boolean { return Uuid.test(value) } sinclairzx81-typebox-e0ec98c/example/index.ts000066400000000000000000000025051505437577000213740ustar00rootroot00000000000000import { TypeSystem } from '@sinclair/typebox/system' import { TypeCompiler } from '@sinclair/typebox/compiler' import { Value, ValuePointer } from '@sinclair/typebox/value' import { Type, TypeGuard, Kind, Static, TSchema } from '@sinclair/typebox' import { Syntax } from '@sinclair/typebox/syntax' // ----------------------------------------------------------- // Create: Type // ----------------------------------------------------------- const T = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }) type T = Static console.log(T) // ----------------------------------------------------------- // Syntax: Type // ----------------------------------------------------------- const S = Syntax({ T }, `{ x: T, y: T, z: T }`) type S = Static // ----------------------------------------------------------- // Create: Value // ----------------------------------------------------------- const V = Value.Create(T) console.log(V) // ----------------------------------------------------------- // Compile: Type // ----------------------------------------------------------- const C = TypeCompiler.Compile(T) console.log(C.Code()) // ----------------------------------------------------------- // Check: Value // ----------------------------------------------------------- console.log(C.Check(V)) sinclairzx81-typebox-e0ec98c/example/prototypes/000077500000000000000000000000001505437577000221435ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/example/prototypes/discriminated-union.ts000066400000000000000000000104531505437577000264630ustar00rootroot00000000000000 /*-------------------------------------------------------------------------- @sinclair/typebox/prototypes The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { Static, Kind, TSchema, TObject, SchemaOptions, CreateType, TLiteral, TypeRegistry, ValueGuard, KindGuard, TUnion } from '@sinclair/typebox' import { GetErrorFunction, SetErrorFunction } from 'src/errors/function' import { Value } from '@sinclair/typebox/value' // ------------------------------------------------------------------ // DiscriminatedUnionError // ------------------------------------------------------------------ const errorFunction = GetErrorFunction() // prettier-ignore SetErrorFunction((parameter) => { if (parameter.schema[Kind] !== 'DiscriminatedUnion') { return errorFunction(parameter) } const union = parameter.schema as TDiscriminatedUnion // Try generate error when value matches known discriminator literal if (ValueGuard.IsObject(parameter.value) && union.discriminator in parameter.value) { const variant = parameter.schema.anyOf.find((variant: TSchema) => union.discriminator in variant.properties && (variant.properties[union.discriminator] as TLiteral).const === (parameter.value as Record)[union.discriminator]) if (KindGuard.IsSchema(variant)) { const literal = variant.properties[union.discriminator] return `Invalid value for DiscriminatedUnion variant '${literal.const}'` } } // Return generic error containing possible discriminator types. const options = union.anyOf.map(object => object.properties[union.discriminator].const) as string[] return `Expected value of ${options.map(option => `'${option}'`).join(', ')} for DiscriminatedUnion` }) // ------------------------------------------------------------------ // TDiscriminatedUnionObject // // Constructs a base TObject type requiring 1 discriminator property // ------------------------------------------------------------------ // prettier-ignore type TDiscriminatedUnionProperties = { [_ in Discriminator]: TLiteral } // prettier-ignore type TDiscriminatedUnionObject = TObject> // ------------------------------------------------------------------ // DiscriminatedUnion // ------------------------------------------------------------------ // prettier-ignore TypeRegistry.Set('DiscriminatedUnion', (schema: TDiscriminatedUnion, value) => { return schema.anyOf.some(variant => Value.Check(variant, [], value)) }) // prettier-ignore export interface TDiscriminatedUnion extends TSchema { [Kind]: 'DiscriminatedUnion' static: Static> discriminator: Discriminator anyOf: Types } /** Creates a DiscriminatedUnion. */ // prettier-ignore export function DiscriminatedUnion[]>( discriminator: Discriminator, types: [...Types], options?: SchemaOptions ): TDiscriminatedUnion { return CreateType({ [Kind]: 'DiscriminatedUnion', anyOf: types, discriminator }, options) as never } sinclairzx81-typebox-e0ec98c/example/prototypes/from-schema.ts000066400000000000000000000267271505437577000247320ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/prototypes The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import * as Type from '@sinclair/typebox' // ------------------------------------------------------------------ // Schematics // ------------------------------------------------------------------ const IsExact = (value: unknown, expect: unknown) => value === expect const IsSValue = (value: unknown): value is SValue => Type.ValueGuard.IsString(value) || Type.ValueGuard.IsNumber(value) || Type.ValueGuard.IsBoolean(value) const IsSEnum = (value: unknown): value is SEnum => Type.ValueGuard.IsObject(value) && Type.ValueGuard.IsArray(value.enum) && value.enum.every((value) => IsSValue(value)) const IsSAllOf = (value: unknown): value is SAllOf => Type.ValueGuard.IsObject(value) && Type.ValueGuard.IsArray(value.allOf) const IsSAnyOf = (value: unknown): value is SAnyOf => Type.ValueGuard.IsObject(value) && Type.ValueGuard.IsArray(value.anyOf) const IsSOneOf = (value: unknown): value is SOneOf => Type.ValueGuard.IsObject(value) && Type.ValueGuard.IsArray(value.oneOf) const IsSTuple = (value: unknown): value is STuple => Type.ValueGuard.IsObject(value) && IsExact(value.type, 'array') && Type.ValueGuard.IsArray(value.items) const IsSArray = (value: unknown): value is SArray => Type.ValueGuard.IsObject(value) && IsExact(value.type, 'array') && !Type.ValueGuard.IsArray(value.items) && Type.ValueGuard.IsObject(value.items) const IsSConst = (value: unknown): value is SConst => Type.ValueGuard.IsObject(value) && Type.ValueGuard.IsObject(value['const']) const IsSString = (value: unknown): value is SString => Type.ValueGuard.IsObject(value) && IsExact(value.type, 'string') const IsSRef = (value: unknown): value is SRef => Type.ValueGuard.IsObject(value) && Type.ValueGuard.IsString(value.$ref) const IsSNumber = (value: unknown): value is SNumber => Type.ValueGuard.IsObject(value) && IsExact(value.type, 'number') const IsSInteger = (value: unknown): value is SInteger => Type.ValueGuard.IsObject(value) && IsExact(value.type, 'integer') const IsSBoolean = (value: unknown): value is SBoolean => Type.ValueGuard.IsObject(value) && IsExact(value.type, 'boolean') const IsSNull = (value: unknown): value is SBoolean => Type.ValueGuard.IsObject(value) && IsExact(value.type, 'null') const IsSProperties = (value: unknown): value is SProperties => Type.ValueGuard.IsObject(value) // prettier-ignore const IsSObject = (value: unknown): value is SObject => Type.ValueGuard.IsObject(value) && IsExact(value.type, 'object') && IsSProperties(value.properties) && (value.required === undefined || Type.ValueGuard.IsArray(value.required) && value.required.every((value: unknown) => Type.ValueGuard.IsString(value))) type SValue = string | number | boolean type SEnum = Readonly<{ enum: readonly SValue[] }> type SAllOf = Readonly<{ allOf: readonly unknown[] }> type SAnyOf = Readonly<{ anyOf: readonly unknown[] }> type SOneOf = Readonly<{ oneOf: readonly unknown[] }> type SProperties = Record type SObject = Readonly<{ type: 'object'; properties: SProperties; required?: readonly string[] }> type STuple = Readonly<{ type: 'array'; items: readonly unknown[] }> type SArray = Readonly<{ type: 'array'; items: unknown }> type SConst = Readonly<{ const: SValue }> type SRef = Readonly<{ $ref: string }> type SString = Readonly<{ type: 'string' }> type SNumber = Readonly<{ type: 'number' }> type SInteger = Readonly<{ type: 'integer' }> type SBoolean = Readonly<{ type: 'boolean' }> type SNull = Readonly<{ type: 'null' }> // ------------------------------------------------------------------ // FromRest // ------------------------------------------------------------------ // prettier-ignore type TFromRest = ( T extends readonly [infer L extends unknown, ...infer R extends unknown[]] ? TFromSchema extends infer S extends Type.TSchema ? TFromRest : TFromRest : Acc ) function FromRest(T: T): TFromRest { return T.map((L) => FromSchema(L)) as never } // ------------------------------------------------------------------ // FromEnumRest // ------------------------------------------------------------------ // prettier-ignore type TFromEnumRest = ( T extends readonly [infer L extends SValue, ...infer R extends SValue[]] ? TFromEnumRest]> : Acc ) function FromEnumRest(T: T): TFromEnumRest { return T.map((L) => Type.Literal(L)) as never } // ------------------------------------------------------------------ // AllOf // ------------------------------------------------------------------ // prettier-ignore type TFromAllOf = ( TFromRest extends infer Rest extends Type.TSchema[] ? Type.TIntersectEvaluated : Type.TNever ) function FromAllOf(T: T): TFromAllOf { return Type.IntersectEvaluated(FromRest(T.allOf), T) } // ------------------------------------------------------------------ // AnyOf // ------------------------------------------------------------------ // prettier-ignore type TFromAnyOf = ( TFromRest extends infer Rest extends Type.TSchema[] ? Type.TUnionEvaluated : Type.TNever ) function FromAnyOf(T: T): TFromAnyOf { return Type.UnionEvaluated(FromRest(T.anyOf), T) } // ------------------------------------------------------------------ // OneOf // ------------------------------------------------------------------ // prettier-ignore type TFromOneOf = ( TFromRest extends infer Rest extends Type.TSchema[] ? Type.TUnionEvaluated : Type.TNever ) function FromOneOf(T: T): TFromOneOf { return Type.UnionEvaluated(FromRest(T.oneOf), T) } // ------------------------------------------------------------------ // Enum // ------------------------------------------------------------------ // prettier-ignore type TFromEnum = ( TFromEnumRest extends infer Elements extends Type.TSchema[] ? Type.TUnionEvaluated : Type.TNever ) function FromEnum(T: T): TFromEnum { return Type.UnionEvaluated(FromEnumRest(T.enum)) } // ------------------------------------------------------------------ // Tuple // ------------------------------------------------------------------ // prettier-ignore type TFromTuple = ( TFromRest extends infer Elements extends Type.TSchema[] ? Type.TTuple : Type.TTuple<[]> ) // prettier-ignore function FromTuple(T: T): TFromTuple { return Type.Tuple(FromRest(T.items), T) as never } // ------------------------------------------------------------------ // Array // ------------------------------------------------------------------ // prettier-ignore type TFromArray = ( TFromSchema extends infer Items extends Type.TSchema ? Type.TArray : Type.TArray ) // prettier-ignore function FromArray(T: T): TFromArray { return Type.Array(FromSchema(T.items), T) as never } // ------------------------------------------------------------------ // Const // ------------------------------------------------------------------ // prettier-ignore type TFromConst = ( Type.Ensure> ) function FromConst(T: T) { return Type.Literal(T.const, T) } // ------------------------------------------------------------------ // Ref // ------------------------------------------------------------------ // prettier-ignore type TFromRef = ( Type.Ensure> ) function FromRef(T: T) { return Type.Ref(T['$ref']) } // ------------------------------------------------------------------ // Object // ------------------------------------------------------------------ type TFromPropertiesIsOptional = unknown extends R ? true : K extends R ? false : true // prettier-ignore type TFromProperties = Type.Evaluate<{ -readonly [K in keyof T]: TFromPropertiesIsOptional extends true ? Type.TOptional> : TFromSchema }> // prettier-ignore type TFromObject = ( TFromProperties[number]> extends infer Properties extends Type.TProperties ? Type.TObject : Type.TObject<{}> ) function FromObject(T: T): TFromObject { const properties = globalThis.Object.getOwnPropertyNames(T.properties).reduce((Acc, K) => { return { ...Acc, [K]: T.required && T.required.includes(K) ? FromSchema(T.properties[K]) : Type.Optional(FromSchema(T.properties[K])) } }, {} as Type.TProperties) return Type.Object(properties, T) as never } // ------------------------------------------------------------------ // FromSchema // ------------------------------------------------------------------ // prettier-ignore export type TFromSchema = ( T extends SAllOf ? TFromAllOf : T extends SAnyOf ? TFromAnyOf : T extends SOneOf ? TFromOneOf : T extends SEnum ? TFromEnum : T extends SObject ? TFromObject : T extends STuple ? TFromTuple : T extends SArray ? TFromArray : T extends SConst ? TFromConst : T extends SRef ? TFromRef : T extends SString ? Type.TString : T extends SNumber ? Type.TNumber : T extends SInteger ? Type.TInteger : T extends SBoolean ? Type.TBoolean : T extends SNull ? Type.TNull : Type.TUnknown ) /** Parses a TypeBox type from raw JsonSchema */ export function FromSchema(T: T): TFromSchema { // prettier-ignore return ( IsSAllOf(T) ? FromAllOf(T) : IsSAnyOf(T) ? FromAnyOf(T) : IsSOneOf(T) ? FromOneOf(T) : IsSEnum(T) ? FromEnum(T) : IsSObject(T) ? FromObject(T) : IsSTuple(T) ? FromTuple(T) : IsSArray(T) ? FromArray(T) : IsSConst(T) ? FromConst(T) : IsSRef(T) ? FromRef(T) : IsSString(T) ? Type.String(T) : IsSNumber(T) ? Type.Number(T) : IsSInteger(T) ? Type.Integer(T) : IsSBoolean(T) ? Type.Boolean(T) : IsSNull(T) ? Type.Null(T) : Type.Unknown(T || {}) ) as never } sinclairzx81-typebox-e0ec98c/example/prototypes/index.ts000066400000000000000000000027711505437577000236310ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/prototypes The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './discriminated-union' export * from './from-schema' export * from './options' export * from './partial-deep' export * from './recursive-map' export * from './union-enum' export * from './union-oneof' sinclairzx81-typebox-e0ec98c/example/prototypes/options.ts000066400000000000000000000034031505437577000242060ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/prototypes The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { TSchema, CloneType } from '@sinclair/typebox' // prettier-ignore export type TOptions> = ( Type & Options ) /** `[Prototype]` Augments a schema with additional generics aware properties */ // prettier-ignore export function Options>(type: Type, options: Options): TOptions { return CloneType(type, options) as never } sinclairzx81-typebox-e0ec98c/example/prototypes/partial-deep.ts000066400000000000000000000064651505437577000250750ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/prototypes The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { TypeGuard, Type, TSchema, TIntersect, TUnion, TObject, TPartial, TProperties, Evaluate } from '@sinclair/typebox' // ------------------------------------------------------------------------------------- // TPartialDeepProperties // ------------------------------------------------------------------------------------- export type TPartialDeepProperties = { [K in keyof T]: TPartialDeep } function PartialDeepProperties(properties: T): TPartialDeepProperties { return Object.getOwnPropertyNames(properties).reduce((acc, key) => { return {...acc, [key]: PartialDeep(properties[key])} }, {}) as never } // ------------------------------------------------------------------------------------- // TPartialDeepRest // ------------------------------------------------------------------------------------- export type TPartialDeepRest = ( T extends [infer L extends TSchema, ...infer R extends TSchema[]] ? TPartialDeepRest]> : Acc ) function PartialDeepRest(rest: [...T]): TPartialDeepRest { return rest.map(schema => PartialDeep(schema)) as never } // ------------------------------------------------------------------------------------- // TPartialDeep // ------------------------------------------------------------------------------------- export type TPartialDeep = T extends TIntersect ? TIntersect> : T extends TUnion ? TUnion> : T extends TObject ? TPartial>>> : T export function PartialDeep(schema: T): TPartialDeep { return ( TypeGuard.IsIntersect(schema) ? Type.Intersect(PartialDeepRest(schema.allOf)) : TypeGuard.IsUnion(schema) ? Type.Union(PartialDeepRest(schema.anyOf)) : TypeGuard.IsObject(schema) ? Type.Partial(Type.Object(PartialDeepProperties(schema.properties))) : schema ) as never }sinclairzx81-typebox-e0ec98c/example/prototypes/readme.md000066400000000000000000000134271505437577000237310ustar00rootroot00000000000000# TypeBox Prototypes TypeBox prototypes are a set of types that are either under consideration for inclusion into the library, or have been requested by users but cannot be added to the library either due to complexity, using schematics that fall outside the supported TypeBox or should be expressed by users via advanced type composition. ## PartialDeep Maps the given schema as deep partial, making all properties and sub properties optional. This type is asked for on occation, but as there is no TypeScript equivalent and because this type is typically handled through end user type mapping, this type is left out of TypeBox. ```typescript import { PartialDeep } from './prototypes' const T = Type.Object({ x: Type.Object({ x: Type.Number(), y: Type.Number() }), y: Type.Object({ x: Type.Number(), y: Type.Number() }) }) const P = PartialDeep(T) type P = Static // type P = { // x?: { // x?: number, // y?: number // }, // y?: { // x?: number, // y?: number // }, // } ``` ## UnionEnum Creates an `enum` union string schema representation. This type is often requested by OpenAPI users, particularily for documentation presentation. As TypeBox standardizes on `anyOf` for all unions, this type is generally at odds with TypeBox's internal representation. Some considerations for internally remapping this type into a `anyOf` through composition have been considered (and would be feasible), but as TypeScript doesn't have multiple representations for unions, neither should TypeBox, making this type an unlikely candidate. ```typescript import { UnionEnum } from './prototypes' const T = UnionEnum(['A', 'B', 'C']) // const T = { // enum: ['A', 'B', 'C'] // } type T = Static // type T = 'A' | 'B' | 'C' ``` ## UnionOneOf Creates a `oneOf` union representation. This type is often requested by users looking for discriminated union support (which is not formally supported by JSON Schema). TypeBox omits this type as `oneOf` has the potential to create illogical schematics where values match more than one sub schema (making type inference extremely difficult). TypeBox preferences users explicitly narrowing on a overlapping union post type check, making `anyOf` the ideal representation, leaving the `oneOf` type an unlikely candidate for inclusion in the library. ```typescript import { UnionOneOf } from './prototypes' const T = UnionOneOf([ // const T = { Type.Literal('A'), // oneOf: [ Type.Literal('B'), // { const: 'A' }, Type.Literal('C') // { const: 'B' }, ]) // { const: 'C' }, // ] // } type T = Static // type T = 'A' | 'B' | 'C' ``` ## Options By default, TypeBox does not represent arbituary options as generics aware properties. However, there are cases where having options observable to the type system can be useful, for example conditionally mapping schematics based on custom metadata. The Options function makes user defined options generics aware. ```typescript import { Options } from './prototypes' const A = Options(Type.String(), { foo: 1 }) // Options type A = typeof A extends { foo: number } ? true : false // true: foo property is observable to the type system ``` ## Recursive Map The Recursive Map type enables deep structural remapping of a type and it's internal constituents. This type accepts a TSchema type and a mapping type function (expressed via HKT). The HKT is applied when traversing the type and it's interior. The mapping HKT can apply conditional tests to each visited type to remap into a new form. The following augments a schematic via Options, and conditionally remaps any schema with an default annotation to make it optional. ```typescript import { Type, TOptional, Static, TSchema } from '@sinclair/typebox' import { TRecursiveMap, TMappingType, Options } from './prototypes' // ------------------------------------------------------------------ // StaticDefault // ------------------------------------------------------------------ export interface StaticDefaultMapping extends TMappingType { output: ( this['input'] extends TSchema // if input schematic contains an default ? this['input'] extends { default: unknown } // annotation, remap it to be optional, ? TOptional // otherwise just return the schema as is. : this['input'] : this['input'] ) } export type StaticDefault = ( Static> ) // ------------------------------------------------------------------ // Usage // ------------------------------------------------------------------ const T = Type.Object({ x: Options(Type.String(), { default: 'hello' }), y: Type.String() }) type T = StaticDefault // { x?: string, y: string } type S = Static // { x: string, y: string }sinclairzx81-typebox-e0ec98c/example/prototypes/recursive-map.ts000066400000000000000000000204001505437577000252710ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/prototypes The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import * as Types from '@sinclair/typebox' // ------------------------------------------------------------------ // Mapping: Functions and Type // ------------------------------------------------------------------ export type TMappingFunction = (schema: Types.TSchema) => Types.TSchema export interface TMappingType { input: unknown output: unknown } // ------------------------------------------------------------------ // Record Parameters // ------------------------------------------------------------------ function GetRecordPattern(record: Types.TRecord): string { return globalThis.Object.getOwnPropertyNames(record.patternProperties)[0] } function GetRecordKey(record: Types.TRecord): Types.TSchema { const pattern = GetRecordPattern(record) return ( pattern === Types.PatternStringExact ? Types.String() : pattern === Types.PatternNumberExact ? Types.Number() : pattern === Types.PatternBooleanExact ? Types.Boolean() : Types.String({ pattern }) ) } function GetRecordValue(record: Types.TRecord): Types.TSchema { return record.patternProperties[GetRecordPattern(record)] } // ------------------------------------------------------------------ // Traversal // ------------------------------------------------------------------ // prettier-ignore type TApply = Result // prettier-ignore type TFromProperties }> = Result function FromProperties(properties: Types.TProperties, func: TMappingFunction): Types.TProperties { return globalThis.Object.getOwnPropertyNames(properties).reduce((result, key) => { return {...result, [key]: RecursiveMap(properties[key], func) } }, {}) } // prettier-ignore type TFromRest = ( Types extends [infer Left extends Types.TSchema, ...infer Right extends Types.TSchema[]] ? TFromRest]> : Result ) function FromRest(types: Types.TSchema[], func: TMappingFunction): Types.TSchema[] { return types.map(type => RecursiveMap(type, func)) } // prettier-ignore type TFromType )> = Result function FromType(type: Types.TSchema, func: TMappingFunction): Types.TSchema { return func(type) } // ------------------------------------------------------------------ // TRecursiveMap // ------------------------------------------------------------------ /** `[Prototype]` Applies a deep recursive map across the given type and sub types. */ // prettier-ignore export type TRecursiveMap, // Maps the Interior Parameterized Types Interior extends Types.TSchema = ( Exterior extends Types.TConstructor ? Types.TConstructor, TFromType> : Exterior extends Types.TFunction ? Types.TFunction, TFromType> : Exterior extends Types.TIntersect ? Types.TIntersect> : Exterior extends Types.TUnion ? Types.TUnion> : Exterior extends Types.TTuple ? Types.TTuple> : Exterior extends Types.TArray ? Types.TArray>: Exterior extends Types.TAsyncIterator ? Types.TAsyncIterator> : Exterior extends Types.TIterator ? Types.TIterator> : Exterior extends Types.TPromise ? Types.TPromise> : Exterior extends Types.TObject ? Types.TObject> : Exterior extends Types.TRecord ? Types.TRecordOrObject, TFromType> : Exterior ), // Modifiers Derived from Exterior Type Mapping IsOptional extends number = Exterior extends Types.TOptional ? 1 : 0, IsReadonly extends number = Exterior extends Types.TReadonly ? 1 : 0, Result extends Types.TSchema = ( [IsReadonly, IsOptional] extends [1, 1] ? Types.TReadonlyOptional : [IsReadonly, IsOptional] extends [0, 1] ? Types.TOptional : [IsReadonly, IsOptional] extends [1, 0] ? Types.TReadonly : Interior ) > = Result /** `[Prototype]` Applies a deep recursive map across the given type and sub types. */ // prettier-ignore export function RecursiveMap(type: Types.TSchema, func: TMappingFunction): Types.TSchema { // Maps the Exterior Type const exterior = Types.CloneType(FromType(type, func), type) // Maps the Interior Parameterized Types const interior = ( Types.KindGuard.IsConstructor(type) ? Types.Constructor(FromRest(type.parameters, func), FromType(type.returns, func), exterior) : Types.KindGuard.IsFunction(type) ? Types.Function(FromRest(type.parameters, func), FromType(type.returns, func), exterior) : Types.KindGuard.IsIntersect(type) ? Types.Intersect(FromRest(type.allOf, func), exterior) : Types.KindGuard.IsUnion(type) ? Types.Union(FromRest(type.anyOf, func), exterior) : Types.KindGuard.IsTuple(type) ? Types.Tuple(FromRest(type.items || [], func), exterior) : Types.KindGuard.IsArray(type) ? Types.Array(FromType(type.items, func), exterior) : Types.KindGuard.IsAsyncIterator(type) ? Types.AsyncIterator(FromType(type.items, func), exterior) : Types.KindGuard.IsIterator(type) ? Types.Iterator(FromType(type.items, func), exterior) : Types.KindGuard.IsPromise(type) ? Types.Promise(FromType(type.items, func), exterior) : Types.KindGuard.IsObject(type) ? Types.Object(FromProperties(type.properties, func), exterior) : Types.KindGuard.IsRecord(type) ? Types.Record(FromType(GetRecordKey(type), func), FromType(GetRecordValue(type), func), exterior) : Types.CloneType(exterior, exterior) ) // Modifiers Derived from Exterior Type Mapping const isOptional = Types.KindGuard.IsOptional(exterior) const isReadonly = Types.KindGuard.IsOptional(exterior) return ( isOptional && isReadonly ? Types.ReadonlyOptional(interior) : isOptional ? Types.Optional(interior) : isReadonly ? Types.Readonly(interior) : interior ) }sinclairzx81-typebox-e0ec98c/example/prototypes/union-enum.ts000066400000000000000000000046121505437577000246100ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/prototypes The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { TypeRegistry, Kind, TSchema, SchemaOptions } from '@sinclair/typebox' // ------------------------------------------------------------------------------------- // TUnionEnum // ------------------------------------------------------------------------------------- export interface TUnionEnum extends TSchema { [Kind]: 'UnionEnum' static: T[number] enum: T } // ------------------------------------------------------------------------------------- // UnionEnum // ------------------------------------------------------------------------------------- /** `[Experimental]` Creates a Union type with a `enum` schema representation */ export function UnionEnum(values: [...T], options: SchemaOptions = {}) { function UnionEnumCheck(schema: TUnionEnum<(string | number)[]>, value: unknown) { return (typeof value === 'string' || typeof value === 'number') && schema.enum.includes(value) } if (!TypeRegistry.Has('UnionEnum')) TypeRegistry.Set('UnionEnum', UnionEnumCheck) return { ...options, [Kind]: 'UnionEnum', enum: values } as TUnionEnum }sinclairzx81-typebox-e0ec98c/example/prototypes/union-oneof.ts000066400000000000000000000047311505437577000247540ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/prototypes The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { TypeRegistry, Kind, Static, TSchema, SchemaOptions } from '@sinclair/typebox' import { Value } from '@sinclair/typebox/value' // ------------------------------------------------------------------------------------- // TUnionOneOf // ------------------------------------------------------------------------------------- export interface TUnionOneOf extends TSchema { [Kind]: 'UnionOneOf' static: { [K in keyof T]: Static }[number] oneOf: T } // ------------------------------------------------------------------------------------- // UnionOneOf // ------------------------------------------------------------------------------------- /** `[Experimental]` Creates a Union type with a `oneOf` schema representation */ export function UnionOneOf(oneOf: [...T], options: SchemaOptions = {}) { function UnionOneOfCheck(schema: TUnionOneOf, value: unknown) { return 1 === schema.oneOf.reduce((acc: number, schema: any) => (Value.Check(schema, value) ? acc + 1 : acc), 0) } if (!TypeRegistry.Has('UnionOneOf')) TypeRegistry.Set('UnionOneOf', UnionOneOfCheck) return { ...options, [Kind]: 'UnionOneOf', oneOf } as TUnionOneOf }sinclairzx81-typebox-e0ec98c/example/standard/000077500000000000000000000000001505437577000215135ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/example/standard/index.ts000066400000000000000000000024731505437577000232000ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/standard-schema The MIT License (MIT) Copyright (c) 2024 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './standard'sinclairzx81-typebox-e0ec98c/example/standard/readme.md000066400000000000000000000036701505437577000233000ustar00rootroot00000000000000### Standard Schema Reference implementation of [Standard Schema](https://github.com/standard-schema/standard-schema) for TypeBox. ### Example The following example augments a TypeBox schema with the required `~standard` interface. The `~standard` interface is applied via non-enumerable configuration enabling the schematics to continue to be used with strict compliant validators such as Ajv that would otherwise reject the non-standard `~standard` keyword. ```typescript import { StandardSchema } from './standard' import { Type } from '@sinclair/typebox' const T = StandardSchema(Type.Object({ // const A = { x: Type.Number(), // (non-enumerable) '~standard': { y: Type.Number(), // version: 1, z: Type.Number(), // vendor: 'TypeBox', })) // validate: [Function: validate] // }, // type: 'object', // properties: { // x: { type: 'number', [Symbol(TypeBox.Kind)]: 'Number' }, // y: { type: 'number', [Symbol(TypeBox.Kind)]: 'Number' }, // z: { type: 'number', [Symbol(TypeBox.Kind)]: 'Number' } // }, // required: [ 'x', 'y', 'z' ], // [Symbol(TypeBox.Kind)]: 'Object' // } const R = T['~standard'].validate({ x: 1, y: 2, z: 3 }) // const R = { // value: { x: 1, y: 2, z: 3 }, // issues: [] // } ```sinclairzx81-typebox-e0ec98c/example/standard/standard.ts000066400000000000000000000074701505437577000236730ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/standard-schema The MIT License (MIT) Copyright (c) 2024 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { AssertError, Value, ValueError, ValueErrorType } from '@sinclair/typebox/value' import { TSchema, StaticDecode, CloneType } from '@sinclair/typebox' // ------------------------------------------------------------------ // StandardSchema // ------------------------------------------------------------------ interface StandardResult { value: Output issues: ValueError[] } interface StandardSchema { readonly "~standard": StandardSchemaProperties } interface StandardSchemaProperties { readonly version: 1 readonly vendor: 'TypeBox' readonly validate: (value: unknown) => StandardResult readonly types?: undefined } // ------------------------------------------------------------------ // Issues // ------------------------------------------------------------------ // prettier-ignore function CreateIssues(schema: TSchema, value: unknown, error: unknown): ValueError[] { const isAssertError = error instanceof AssertError ? error : undefined return !isAssertError ? [{errors: [], message: 'Unknown error', path: '/', type: ValueErrorType.Kind, schema, value }] : [...isAssertError.Errors()] } // ------------------------------------------------------------------ // Validate // ------------------------------------------------------------------ // prettier-ignore function CreateValidator(schema: Type, references: TSchema[]): (value: unknown) => StandardResult> { return (value: unknown): StandardResult> => { try { return { value: Value.Parse(schema, references, value), issues: [] } } catch (error) { return { value: undefined, issues: CreateIssues(schema, value, error) } } } } // ------------------------------------------------------------------ // StandardSchema // ------------------------------------------------------------------ /** Augments a TypeBox type with the `~standard` validation interface. */ export type TStandardSchema = ( Input & StandardSchema ) /** Augments a TypeBox type with the `~standard` validation interface. */ export function StandardSchema(schema: Type, references: TSchema[] = []): TStandardSchema> { const standard = { version: 1, vendor: 'TypeBox', validate: CreateValidator(schema, references) } return Object.defineProperty(CloneType(schema), "~standard", { enumerable: false, value: standard }) as never }sinclairzx81-typebox-e0ec98c/example/typedef/000077500000000000000000000000001505437577000213535ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/example/typedef/index.ts000066400000000000000000000024671505437577000230430ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/typedef The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './typedef'sinclairzx81-typebox-e0ec98c/example/typedef/readme.md000066400000000000000000000541601505437577000231400ustar00rootroot00000000000000# TypeDef TypeBox is considering support for the JSON Type Definition [RFC8927](https://www.rfc-editor.org/rfc/rfc8927) specification in future releases. This specification is similar to JSON Schema but provides a constrained type representation that enables schematics to map more naturally to [nominal type systems](https://en.wikipedia.org/wiki/Nominal_type_system) as well as offering type primitives such as `int8`, `uint32` or `float32`. JSON Type Definition can be useful in applications that need to express and share data structures in a way that can be understood by a wide range of programming languages outside of JavaScript. License MIT ## Contents - [Usage](#Usage) - [Types](#Types) - [Unions](#Unions) - [Check](#Check) ## Usage TypeBox currently doesn't publish TypeDef as part of the mainline package. However the TypeDef functionality is written to be a standalone module you can copy into your project. You will also need `@sinclair/typebox` installed. You can obtain the `typedef` module from `example/typedef/typedef.ts` contained within this repository. ```typescript import { Type, Static } from './typedef' const T = Type.Struct({ // const T = { x: Type.Float32(), // properties: { y: Type.Float32(), // x: { type: 'float32' }, z: Type.Float32() // y: { type: 'float32' }, }) // z: { type: 'float32' } // } // } type T = Static // type T = { // x: number, // y: number, // z: number // } ``` ## Types The following types are supported by the typedef module. Please note these types are not compatible with the JSON Schema specification and should not be combined with the standard TypeBox types. ```typescript ┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────� │ TypeBox │ TypeScript │ JSON Type Definition │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Boolean() │ type T = boolean │ const T = { │ │ │ │ type: 'boolean' │ │ │ │ } │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.String() │ type T = string │ const T = { │ │ │ │ type: 'string' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Float32() │ type T = number │ const T = { │ │ │ │ type: 'float32' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Float64() │ type T = number │ const T = { │ │ │ │ type: 'float64' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Int8() │ type T = number │ const T = { │ │ │ │ type: 'int8' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Int16() │ type T = number │ const T = { │ │ │ │ type: 'int16' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Int32() │ type T = number │ const T = { │ │ │ │ type: 'int32' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Uint8() │ type T = number │ const T = { │ │ │ │ type: 'uint8' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Uint16() │ type T = number │ const T = { │ │ │ │ type: 'uint16' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Uint32() │ type T = number │ const T = { │ │ │ │ type: 'uint32' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Timestamp() │ type T = number │ const T = { │ │ │ │ type: 'timestamp' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Struct([ │ type T = { │ const T = { │ │ x: Type.Float32(), │ x: number, │ properties: { │ │ y: Type.Float32(), │ y: number │ x: number, │ │ ]) │ } │ y: number │ │ │ │ } │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Array( │ type T = number[] │ const T = { │ │ Type.Float32() │ │ elements: { │ │ ) │ │ type: 'float32' │ │ │ │ } │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Record( │ type T = Record< │ const T = { │ │ Type.Float32() │ string, │ values: { │ │ ) │ number │ type: 'float32' │ │ │ > │ } │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Enum([ │ type T = 'A' | 'B' | 'C' │ const T = { │ │ 'A', 'B', 'C' │ │ enum: [ │ │ ]) │ │ 'A', │ │ │ │ 'B', │ │ │ │ 'C' │ │ │ │ ] │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Union([ │ type T = { │ const T = { │ │ Type.Struct({ │ kind: '0', │ discriminator: 'kind', │ │ x: Type.Float32() │ x: number │ mapping: { │ │ }), │ } | { │ '0': { │ │ Type.Struct({ │ kind: '1' │ properties: { │ │ y: Type.Float32() │ y: number │ x: { │ │ ]) │ } │ type: 'float32' │ │ ], 'kind') │ │ } │ │ │ │ } │ │ │ │ }, │ │ │ │ '1': { | │ │ │ properties: { │ │ │ │ y: { │ │ │ │ type: 'float32' │ │ │ │ } │ │ │ │ } │ │ │ │ } │ │ │ │ } │ │ │ │ } │ │ │ │ │ └────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘ ``` ## Unions TypeBox supports JSON Type Definition discriminated unions with `Type.Union`. This type works similar its JSON Schema counterpart, but can only accept types of `Type.Struct` and will infer each struct with an additional named `discriminator` field. The representation for discriminated unions are also quite different, where instead of `anyOf` or `oneOf`, a set of `mapping` properties are used for each sub type. ```typescript const Vector2 = Type.Struct({ // const Vector2 = { x: Type.Float32(), // properties: { y: Type.Float32() // x: { type: 'float32' }, }) // y: { type: 'float32' } // } // } const Vector3 = Type.Struct({ // const Vector3 = { x: Type.Float32(), // properties: { y: Type.Float32(), // x: { type: 'float32' }, z: Type.Float32() // y: { type: 'float32' }, }) // z: { type: 'float32' } // } // } const Vector4 = Type.Struct({ // const Vector4 = { x: Type.Float32(), // properties: { y: Type.Float32(), // x: { type: 'float32' }, z: Type.Float32(), // y: { type: 'float32' }, w: Type.Float32() // z: { type: 'float32' }, }) // w: { type: 'float32' } // } // } const T = Type.Union([ // const T = { Vector2, // discriminator: 'type', Vector3, // mapping: { Vector4 // 0: { ]) // properties: { // x: { type: 'float32' }, // y: { type: 'float32' } // } // }, // 1: { // properties: { // x: { type: 'float32' }, // y: { type: 'float32' }, // z: { type: 'float32' } // } // }, // 2: { // properties: { // x: { type: 'float32' }, // y: { type: 'float32' }, // z: { type: 'float32' } // } // } // } // } type T = Static // type T = { // type: '0', // x: number, // y: number // } | { // type: '1', // x: number, // y: number, // y: number // } | { // type: '2', // x: number, // y: number, // y: number, // w: number // } ``` To type check a value matching the above union, the value will need to contain the discriminator property `type` with a value matching one of the sub type `mapping` keys. The inference type shown above can be a good reference point to understand the structure of the expected value. Nominal type systems will use the discriminator to an expected target type. The following are examples of valid and invalid union data. ```typescript const V = { x: 1, y: 1 } // invalid Vector2 const V = { type: '0', x: 1, y: 1 } // valid Vector2 const V = { type: '0', x: 1, y: 1, z: 1 } // invalid Vector2 const V = { type: '1', x: 1, y: 1, z: 1 } // valid Vector3 ``` ## Check TypeDef types are partially supported with the `TypeCompiler` and `Value` checking modules through the extensible type system in TypeBox. Please note these types are not optimized for JIT performance and do not provide deep error reporting support. For more fully featured validation support consider Ajv. Documentation of Ajv support can be found [here](https://ajv.js.org/json-type-definition.html). The following is TypeDef used with TypeBox's type checking infrastructure. ```typescript import { TypeCompiler } from '@sinclair/typebox/compiler' import { Value } from '@sinclair/typebox/value' const T = Type.Struct({ x: Type.Float32(), y: Type.Float32(), z: Type.Float32() }) const V = { x: 1, y: 2, z: 3 } const R1 = TypeCompiler.Compile(T).Check(V) // true const R2 = Value.Check(T, V) // true ```sinclairzx81-typebox-e0ec98c/example/typedef/typedef.ts000066400000000000000000000734071505437577000233760ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/typedef The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { SetErrorFunction, DefaultErrorFunction } from '@sinclair/typebox/errors' import * as Types from '@sinclair/typebox/type' // -------------------------------------------------------------------------- // Metadata // -------------------------------------------------------------------------- export interface Metadata { [name: string]: any } // -------------------------------------------------------------------------- // TArray // -------------------------------------------------------------------------- export interface TArray extends Types.TSchema { [Types.Kind]: 'TypeDef:Array' static: Types.Static[] elements: T } // -------------------------------------------------------------------------- // TBoolean // -------------------------------------------------------------------------- export interface TBoolean extends Types.TSchema { [Types.Kind]: 'TypeDef:Boolean' static: 'boolean' type: 'boolean' } // -------------------------------------------------------------------------- // TUnion // -------------------------------------------------------------------------- export type InferUnion = T extends [infer L extends TStruct, ...infer R extends TStruct[]] ? Types.Evaluate<{ [_ in D]: Index } & Types.Static> | InferUnion>> : never export interface TUnion extends Types.TSchema { [Types.Kind]: 'TypeDef:Union' static: InferUnion discriminator: D, mapping: T } // -------------------------------------------------------------------------- // TEnum // -------------------------------------------------------------------------- export interface TEnum extends Types.TSchema { [Types.Kind]: 'TypeDef:Enum' static: T[number] enum: [...T] } // -------------------------------------------------------------------------- // TFloat32 // -------------------------------------------------------------------------- export interface TFloat32 extends Types.TSchema { [Types.Kind]: 'TypeDef:Float32' type: 'float32' static: number } // -------------------------------------------------------------------------- // TFloat64 // -------------------------------------------------------------------------- export interface TFloat64 extends Types.TSchema { [Types.Kind]: 'TypeDef:Float64' type: 'float64' static: number } // -------------------------------------------------------------------------- // TInt8 // -------------------------------------------------------------------------- export interface TInt8 extends Types.TSchema { [Types.Kind]: 'TypeDef:Int8' type: 'int8' static: number } // -------------------------------------------------------------------------- // TInt16 // -------------------------------------------------------------------------- export interface TInt16 extends Types.TSchema { [Types.Kind]: 'TypeDef:Int16' type: 'int16' static: number } // -------------------------------------------------------------------------- // TInt32 // -------------------------------------------------------------------------- export interface TInt32 extends Types.TSchema { [Types.Kind]: 'TypeDef:Int32' type: 'int32' static: number } // -------------------------------------------------------------------------- // TUint8 // -------------------------------------------------------------------------- export interface TUint8 extends Types.TSchema { [Types.Kind]: 'TypeDef:Uint8' type: 'uint8' static: number } // -------------------------------------------------------------------------- // TUint16 // -------------------------------------------------------------------------- export interface TUint16 extends Types.TSchema { [Types.Kind]: 'TypeDef:Uint16' type: 'uint16' static: number } // -------------------------------------------------------------------------- // TUint32 // -------------------------------------------------------------------------- export interface TUint32 extends Types.TSchema { [Types.Kind]: 'TypeDef:Uint32' type: 'uint32' static: number } // -------------------------------------------------------------------------- // TProperties // -------------------------------------------------------------------------- export type TFields = Record // -------------------------------------------------------------------------- // TRecord // -------------------------------------------------------------------------- export interface TRecord extends Types.TSchema { [Types.Kind]: 'TypeDef:Record' static: Record> values: T } // -------------------------------------------------------------------------- // TString // -------------------------------------------------------------------------- export interface TString extends Types.TSchema { [Types.Kind]: 'TypeDef:String' type: 'string' static: string } // -------------------------------------------------------------------------- // TStruct // -------------------------------------------------------------------------- // used for structural type inference type OptionalKeys = { [K in keyof T]: T[K] extends (Types.TOptional) ? T[K] : never } type RequiredKeys = { [K in keyof T]: T[K] extends (Types.TOptional) ? never : T[K] } // static inference type ReadonlyOptionalPropertyKeys = { [K in keyof T]: T[K] extends Types.TReadonly ? (T[K] extends Types.TOptional ? K : never) : never }[keyof T] type ReadonlyPropertyKeys = { [K in keyof T]: T[K] extends Types.TReadonly ? (T[K] extends Types.TOptional ? never : K) : never }[keyof T] type OptionalPropertyKeys = { [K in keyof T]: T[K] extends Types.TOptional ? (T[K] extends Types.TReadonly ? never : K) : never }[keyof T] type RequiredPropertyKeys = keyof Omit | ReadonlyPropertyKeys | OptionalPropertyKeys> // prettier-ignore type StructStaticProperties> = Types.Evaluate<( Readonly>>> & Readonly>> & Partial>> & Required>> )> // prettier-ignore export type StructStatic = StructStaticProperties }> export interface StructMetadata extends Metadata { additionalProperties?: boolean } export interface TStruct extends Types.TSchema, StructMetadata { [Types.Kind]: 'TypeDef:Struct' static: StructStatic optionalProperties: { [K in Types.Assert, keyof T>]: T[K] } properties: { [K in Types.Assert, keyof T>]: T[K] } } // -------------------------------------------------------------------------- // TTimestamp // -------------------------------------------------------------------------- export interface TTimestamp extends Types.TSchema { [Types.Kind]: 'TypeDef:Timestamp' type: 'timestamp' static: string } // -------------------------------------------------------------------------- // Static // -------------------------------------------------------------------------- export type Static = Types.Static // -------------------------------------------------------------------------- // TimestampFormat // -------------------------------------------------------------------------- export namespace TimestampFormat { const DATE_TIME_SEPARATOR = /t|\s/i const TIME = /^(\d\d):(\d\d):(\d\d(?:\.\d+)?)(z|([+-])(\d\d)(?::?(\d\d))?)?$/i const DATE = /^(\d\d\d\d)-(\d\d)-(\d\d)$/ const DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] function IsLeapYear(year: number): boolean { return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0) } function IsDate(str: string): boolean { const matches: string[] | null = DATE.exec(str) if (!matches) return false const year: number = +matches[1] const month: number = +matches[2] const day: number = +matches[3] return month >= 1 && month <= 12 && day >= 1 && day <= (month === 2 && IsLeapYear(year) ? 29 : DAYS[month]) } function IsTime(str: string, strictTimeZone?: boolean): boolean { const matches: string[] | null = TIME.exec(str) if (!matches) return false const hr: number = +matches[1] const min: number = +matches[2] const sec: number = +matches[3] const tz: string | undefined = matches[4] const tzSign: number = matches[5] === '-' ? -1 : 1 const tzH: number = +(matches[6] || 0) const tzM: number = +(matches[7] || 0) if (tzH > 23 || tzM > 59 || (strictTimeZone && !tz)) return false if (hr <= 23 && min <= 59 && sec < 60) return true const utcMin = min - tzM * tzSign const utcHr = hr - tzH * tzSign - (utcMin < 0 ? 1 : 0) return (utcHr === 23 || utcHr === -1) && (utcMin === 59 || utcMin === -1) && sec < 61 } function IsDateTime(value: string, strictTimeZone?: boolean): boolean { const dateTime: string[] = value.split(DATE_TIME_SEPARATOR) return dateTime.length === 2 && IsDate(dateTime[0]) && IsTime(dateTime[1], strictTimeZone) } export function Check(value: string): boolean { return IsDateTime(value) } } // -------------------------------------------------------------------------- // ValueCheck // -------------------------------------------------------------------------- export class ValueCheckError extends Types.TypeBoxError { constructor(public readonly schema: Types.TSchema) { super('Unknown type') } } export namespace ValueCheck { // ------------------------------------------------------------------------ // Guards // ------------------------------------------------------------------------ function IsObject(value: unknown): value is Record { return typeof value === 'object' && value !== null && !globalThis.Array.isArray(value) } function IsArray(value: unknown): value is unknown[] { return globalThis.Array.isArray(value) } function IsString(value: unknown): value is string { return typeof value === 'string' } function IsInt(value: unknown, min: number, max: number): value is number { return typeof value === 'number' && globalThis.Number.isInteger(value) && value >= min && value < max } // ------------------------------------------------------------------------ // Types // ------------------------------------------------------------------------ function Array(schema: TArray, value: unknown): boolean { return IsArray(value) && value.every(value => Visit(schema.elements, value)) } function Boolean(schema: TBoolean, value: unknown): boolean { return typeof value === 'boolean' } function Enum(schema: TEnum, value: unknown): boolean { return typeof value === 'string' && schema.enum.includes(value) } function Float32(schema: TFloat32, value: unknown): boolean { return typeof value === 'number' } function Float64(schema: TFloat64, value: unknown): boolean { return typeof value === 'number' } function Int8(schema: TInt8, value: unknown): boolean { return IsInt(value, -128, 127) } function Int16(schema: TInt16, value: unknown): boolean { return IsInt(value, -32_768, 32_767) } function Int32(schema: TInt32, value: unknown): boolean { return IsInt(value, -2_147_483_648, 2_147_483_647) } function Uint8(schema: TUint8, value: unknown): boolean { return IsInt(value, 0, 255) } function Uint16(schema: TUint16, value: unknown): boolean { return IsInt(value, 0, 65535) } function Uint32(schema: TUint32, value: unknown): boolean { return IsInt(value, 0, 4_294_967_295) } function Record(schema: TRecord, value: unknown): boolean { return IsObject(value) && globalThis.Object.getOwnPropertyNames(value).every(key => Visit(schema.values, value[key])) } function String(schema: TString, value: unknown): boolean { return typeof value === 'string' } function Struct(schema: TStruct, value: unknown, descriminator?: string): boolean { if (!IsObject(value)) return false const optionalKeys = schema.optionalProperties === undefined ? [] : globalThis.Object.getOwnPropertyNames(schema.optionalProperties) const requiredKeys = schema.properties === undefined ? [] : globalThis.Object.getOwnPropertyNames(schema.properties) const unknownKeys = globalThis.Object.getOwnPropertyNames(value) for (const requiredKey of requiredKeys) { if (!(requiredKey in value)) return false const requiredProperty = value[requiredKey] const requiredSchema = (schema as any).properties[requiredKey] if (!Visit(requiredSchema, requiredProperty)) return false } for (const optionalKey of optionalKeys) { if (!(optionalKey in value)) continue const optionalProperty = value[optionalKey] const optionalSchema = (schema as any).properties[optionalKey] if (!Visit(optionalSchema, optionalProperty)) return false } if (schema.additionalProperties === true) return true const knownKeys = [...optionalKeys, ...requiredKeys] for (const unknownKey of unknownKeys) if (!knownKeys.includes(unknownKey) && (descriminator !== undefined && unknownKey !== descriminator)) return false for (const knownKey of knownKeys) if (!unknownKeys.includes(knownKey)) return false return true } function Timestamp(schema: TString, value: unknown): boolean { return IsString(value) && TimestampFormat.Check(value) } function Union(schema: TUnion, value: unknown): boolean { if (!IsObject(value)) return false if (!(schema.discriminator in value)) return false if (!IsString(value[schema.discriminator])) return false if (!(value[schema.discriminator] in schema.mapping)) return false const struct = schema.mapping[value[schema.discriminator]] as TStruct return Struct(struct, value, schema.discriminator) } function Visit(schema: Types.TSchema, value: unknown): boolean { const anySchema = schema as any switch (anySchema[Types.Kind]) { case 'TypeDef:Array': return Array(anySchema, value) case 'TypeDef:Boolean': return Boolean(anySchema, value) case 'TypeDef:Union': return Union(anySchema, value) case 'TypeDef:Enum': return Enum(anySchema, value) case 'TypeDef:Float32': return Float32(anySchema, value) case 'TypeDef:Float64': return Float64(anySchema, value) case 'TypeDef:Int8': return Int8(anySchema, value) case 'TypeDef:Int16': return Int16(anySchema, value) case 'TypeDef:Int32': return Int32(anySchema, value) case 'TypeDef:Uint8': return Uint8(anySchema, value) case 'TypeDef:Uint16': return Uint16(anySchema, value) case 'TypeDef:Uint32': return Uint32(anySchema, value) case 'TypeDef:Record': return Record(anySchema, value) case 'TypeDef:String': return String(anySchema, value) case 'TypeDef:Struct': return Struct(anySchema, value) case 'TypeDef:Timestamp': return Timestamp(anySchema, value) default: throw new ValueCheckError(anySchema) } } export function Check(schema: T, value: unknown): value is Types.Static { return Visit(schema, value) } } // -------------------------------------------------------------------------- // TypeGuard // -------------------------------------------------------------------------- export namespace TypeGuard { // ------------------------------------------------------------------------ // Guards // ------------------------------------------------------------------------ function IsObject(value: unknown): value is Record { return typeof value === 'object' } function IsArray(value: unknown): value is unknown[] { return globalThis.Array.isArray(value) } function IsOptionalBoolean(value: unknown): value is boolean | undefined { return IsBoolean(value) || value === undefined } function IsBoolean(value: unknown): value is boolean { return typeof value === 'boolean' } function IsString(value: unknown): value is string { return typeof value === 'string' } // ------------------------------------------------------------------------ // Types // ------------------------------------------------------------------------ export function TArray(schema: unknown): schema is TArray { return IsObject(schema) && schema[Types.Kind] === 'TypeDef:Array' && TSchema(schema['elements']) } export function TBoolean(schema: unknown): schema is TBoolean { return IsObject(schema) && schema[Types.Kind] === 'TypeDef:Boolean' && schema['type'] === 'boolean' } export function TUnion(schema: unknown): schema is TUnion { if(!(IsObject(schema) && schema[Types.Kind] === 'TypeDef:Union' && IsString(schema['discriminator']) && IsObject(schema['mapping']))) return false return globalThis.Object.getOwnPropertyNames(schema['mapping']).every(key => TSchema((schema['mapping'] as any)[key])) } export function TEnum(schema: unknown): schema is TEnum { return IsObject(schema) && schema[Types.Kind] === 'TypeDef:Enum' && IsArray(schema['enum']) && schema['enum'].every(item => IsString(item)) } export function TFloat32(schema: unknown): schema is TFloat32 { return IsObject(schema) && schema[Types.Kind] === 'TypeDef:Float32' && schema['type'] === 'float32' } export function TFloat64(schema: unknown): schema is TFloat64 { return IsObject(schema) && schema[Types.Kind] === 'TypeDef:Float64' && schema['type'] === 'float64' } export function TInt8(schema: unknown): schema is TInt8 { return IsObject(schema) && schema[Types.Kind] === 'TypeDef:Int8' && schema['type'] === 'int8' } export function TInt16(schema: unknown): schema is TInt16 { return IsObject(schema) && schema[Types.Kind] === 'TypeDef:Int16' && schema['type'] === 'int16' } export function TInt32(schema: unknown): schema is TInt32 { return IsObject(schema) && schema[Types.Kind] === 'TypeDef:Int32' && schema['type'] === 'int32' } export function TUint8(schema: unknown): schema is TUint8 { return IsObject(schema) && schema[Types.Kind] === 'TypeDef:Uint8' && schema['type'] === 'uint8' } export function TUint16(schema: unknown): schema is TUint16 { return IsObject(schema) && schema[Types.Kind] === 'TypeDef:Uint16' && schema['type'] === 'uint16' } export function TUint32(schema: unknown): schema is TUint32 { return IsObject(schema) && schema[Types.Kind] === 'TypeDef:Uint32' && schema['type'] === 'uint32' } export function TRecord(schema: unknown): schema is TRecord { return IsObject(schema) && schema[Types.Kind] === 'TypeDef:Record' && TSchema(schema['values']) } export function TString(schema: unknown): schema is TString { return IsObject(schema) && schema[Types.Kind] === 'TypeDef:String' && schema['type'] === 'string' } export function TStruct(schema: unknown): schema is TStruct { if(!(IsObject(schema) && schema[Types.Kind] === 'TypeDef:Struct' && IsOptionalBoolean(schema['additionalProperties']))) return false const optionalProperties = schema['optionalProperties'] const requiredProperties = schema['properties'] const optionalCheck = optionalProperties === undefined || IsObject(optionalProperties) && globalThis.Object.getOwnPropertyNames(optionalProperties).every(key => TSchema(optionalProperties[key])) const requiredCheck = requiredProperties === undefined || IsObject(requiredProperties) && globalThis.Object.getOwnPropertyNames(requiredProperties).every(key => TSchema(requiredProperties[key])) return optionalCheck && requiredCheck } export function TTimestamp(schema: unknown): schema is TTimestamp { return IsObject(schema) && schema[Types.Kind] === 'TypeDef:Timestamp' && schema['type'] === 'timestamp' } export function TKind(schema: unknown): schema is Types.TKind { return IsObject(schema) && Types.Kind in schema && typeof (schema as any)[Types.Kind] === 'string' // TS 4.1.5: any required for symbol indexer } export function TSchema(schema: unknown): schema is Types.TSchema { // prettier-ignore return ( TArray(schema) || TBoolean(schema) || TUnion(schema) || TEnum(schema) || TFloat32(schema) || TFloat64(schema) || TInt8(schema) || TInt16(schema) || TInt32(schema) || TUint8(schema) || TUint16(schema) || TUint32(schema) || TRecord(schema) || TString(schema) || TStruct(schema) || TTimestamp(schema) || (TKind(schema) && Types.TypeRegistry.Has(schema[Types.Kind])) ) } } // -------------------------------------------------------------------------- // TypeRegistry // -------------------------------------------------------------------------- Types.TypeRegistry.Set('TypeDef:Array', (schema, value) => ValueCheck.Check(schema, value)) Types.TypeRegistry.Set('TypeDef:Boolean', (schema, value) => ValueCheck.Check(schema, value)) Types.TypeRegistry.Set('TypeDef:Union', (schema, value) => ValueCheck.Check(schema, value)) Types.TypeRegistry.Set('TypeDef:Int8', (schema, value) => ValueCheck.Check(schema, value)) Types.TypeRegistry.Set('TypeDef:Int16', (schema, value) => ValueCheck.Check(schema, value)) Types.TypeRegistry.Set('TypeDef:Int32', (schema, value) => ValueCheck.Check(schema, value)) Types.TypeRegistry.Set('TypeDef:Uint8', (schema, value) => ValueCheck.Check(schema, value)) Types.TypeRegistry.Set('TypeDef:Uint16', (schema, value) => ValueCheck.Check(schema, value)) Types.TypeRegistry.Set('TypeDef:Uint32', (schema, value) => ValueCheck.Check(schema, value)) Types.TypeRegistry.Set('TypeDef:Record', (schema, value) => ValueCheck.Check(schema, value)) Types.TypeRegistry.Set('TypeDef:String', (schema, value) => ValueCheck.Check(schema, value)) Types.TypeRegistry.Set('TypeDef:Struct', (schema, value) => ValueCheck.Check(schema, value)) Types.TypeRegistry.Set('TypeDef:Timestamp', (schema, value) => ValueCheck.Check(schema, value)) // -------------------------------------------------------------------------- // TypeSystemErrorFunction // -------------------------------------------------------------------------- SetErrorFunction((error) => { switch(error.schema[Types.Kind]) { case 'TypeDef:Array': return 'Expected Array' case 'TypeDef:Boolean': return 'Expected Boolean' case 'TypeDef:Union': return 'Expected Union' case 'TypeDef:Int8': return 'Expected Int8' case 'TypeDef:Int16': return 'Expected Int16' case 'TypeDef:Int32': return 'Expected Int32' case 'TypeDef:Uint8': return 'Expected Uint8' case 'TypeDef:Uint16': return 'Expected Uint16' case 'TypeDef:Uint32': return 'Expected Uint32' case 'TypeDef:Record': return 'Expected Record' case 'TypeDef:String': return 'Expected String' case 'TypeDef:Struct': return 'Expected Struct' case 'TypeDef:Timestamp': return 'Expected Timestamp' } return DefaultErrorFunction(error) }) // -------------------------------------------------------------------------- // TypeDefBuilder // -------------------------------------------------------------------------- export class TypeDefBuilder { // ------------------------------------------------------------------------ // Core // ------------------------------------------------------------------------ protected Create(schema: Record, metadata: Record): any { const keys = globalThis.Object.getOwnPropertyNames(metadata) return keys.length > 0 ? { ...schema, metadata: { ...metadata } } : { ...schema } } /** [Standard] Removes compositing symbols from this schema */ public Strict(schema: T): T { return JSON.parse(JSON.stringify(schema)) as T } // ------------------------------------------------------------------------ // Modifiers // ------------------------------------------------------------------------ /** `[Standard]` Creates an Optional property */ public Optional(schema: T): Types.TOptional { return this.Optional(schema) } /** `[Standard]` Creates a Readonly property */ public Readonly(schema: T): Types.TReadonly { return this.Readonly(schema) } // ------------------------------------------------------------------------ // Types // ------------------------------------------------------------------------ /** [Standard] Creates a Array type */ public Array(elements: T, metadata: Metadata = {}): TArray { return this.Create({ [Types.Kind]: 'TypeDef:Array', elements }, metadata) } /** [Standard] Creates a Boolean type */ public Boolean(metadata: Metadata = {}): TBoolean { return this.Create({ [Types.Kind]: 'TypeDef:Boolean', type: 'boolean' }, metadata) } /** [Standard] Creates a Enum type */ public Enum(values: [...T], metadata: Metadata = {}): TEnum { return this.Create({[Types.Kind]: 'TypeDef:Enum', enum: values }, metadata ) } /** [Standard] Creates a Float32 type */ public Float32(metadata: Metadata = {}): TFloat32 { return this.Create({ [Types.Kind]: 'TypeDef:Float32', type: 'float32' }, metadata) } /** [Standard] Creates a Float64 type */ public Float64(metadata: Metadata = {}): TFloat64 { return this.Create({ [Types.Kind]: 'TypeDef:Float64', type: 'float64' }, metadata) } /** [Standard] Creates a Int8 type */ public Int8(metadata: Metadata = {}): TInt8 { return this.Create({ [Types.Kind]: 'TypeDef:Int8', type: 'int8' }, metadata) } /** [Standard] Creates a Int16 type */ public Int16(metadata: Metadata = {}): TInt16 { return this.Create({ [Types.Kind]: 'TypeDef:Int16', type: 'int16' }, metadata) } /** [Standard] Creates a Int32 type */ public Int32(metadata: Metadata = {}): TInt32 { return this.Create({ [Types.Kind]: 'TypeDef:Int32', type: 'int32' }, metadata) } /** [Standard] Creates a Uint8 type */ public Uint8(metadata: Metadata = {}): TUint8 { return this.Create({ [Types.Kind]: 'TypeDef:Uint8', type: 'uint8' }, metadata) } /** [Standard] Creates a Uint16 type */ public Uint16(metadata: Metadata = {}): TUint16 { return this.Create({ [Types.Kind]: 'TypeDef:Uint16', type: 'uint16' }, metadata) } /** [Standard] Creates a Uint32 type */ public Uint32(metadata: Metadata = {}): TUint32 { return this.Create({ [Types.Kind]: 'TypeDef:Uint32', type: 'uint32' }, metadata) } /** [Standard] Creates a Record type */ public Record(values: T, metadata: Metadata = {}): TRecord { return this.Create({ [Types.Kind]: 'TypeDef:Record', values },metadata) } /** [Standard] Creates a String type */ public String(metadata: Metadata = {}): TString { return this.Create({ [Types.Kind]: 'TypeDef:String', type: 'string' }, metadata) } /** [Standard] Creates a Struct type */ public Struct(fields: T, metadata: StructMetadata = {}): TStruct { const optionalProperties = globalThis.Object.getOwnPropertyNames(fields).reduce((acc, key) => (Types.TypeGuard.IsOptional(fields[key]) ? { ...acc, [key]: fields[key] } : { ...acc }), {} as TFields) const properties = globalThis.Object.getOwnPropertyNames(fields).reduce((acc, key) => (Types.TypeGuard.IsOptional(fields[key]) ? { ...acc } : { ...acc, [key]: fields[key] }), {} as TFields) const optionalObject = globalThis.Object.getOwnPropertyNames(optionalProperties).length > 0 ? { optionalProperties: optionalProperties } : {} const requiredObject = globalThis.Object.getOwnPropertyNames(properties).length === 0 ? {} : { properties: properties } return this.Create({ [Types.Kind]: 'TypeDef:Struct', ...requiredObject, ...optionalObject }, metadata) } /** [Standard] Creates a Union type */ public Union[], D extends string = 'type'>(structs: [...T], discriminator?: D): TUnion { discriminator = (discriminator || 'type') as D if (structs.length === 0) throw new Error('TypeDefBuilder: Union types must contain at least one struct') const mapping = structs.reduce((acc, current, index) => ({ ...acc, [index.toString()]: current }), {}) return this.Create({ [Types.Kind]: 'TypeDef:Union', discriminator, mapping }, {}) } /** [Standard] Creates a Timestamp type */ public Timestamp(metadata: Metadata = {}): TTimestamp { return this.Create({ [Types.Kind]: 'TypeDef:Timestamp', type: 'timestamp' }, metadata) } } /** JSON Type Definition Type Builder */ export const Type = new TypeDefBuilder() sinclairzx81-typebox-e0ec98c/hammer.mjs000066400000000000000000000120001505437577000202350ustar00rootroot00000000000000import * as Benchmark from './task/benchmark' import * as Build from './task/build' import * as Fs from 'fs' // ------------------------------------------------------------------------------- // Clean // ------------------------------------------------------------------------------- export async function clean() { await folder('node_modules/typebox').delete() await folder('target').delete() } // ------------------------------------------------------------------------------- // Format // ------------------------------------------------------------------------------- export async function format() { await shell('prettier --no-semi --single-quote --print-width 240 --trailing-comma all --write src test task example/index.ts') } // ------------------------------------------------------------------------------- // Start // ------------------------------------------------------------------------------- export async function start() { await shell(`hammer run example/index.ts --dist target/example`) } // ------------------------------------------------------------------------------- // Benchmark // ------------------------------------------------------------------------------- export async function benchmark() { await Benchmark.compression() await Benchmark.measurement() } // ------------------------------------------------------------------------------- // Test // ------------------------------------------------------------------------------- export async function test_typescript() { for (const version of [ '4.9.5', '5.0.4', '5.1.3', '5.1.6', '5.2.2', '5.3.2', '5.3.3', '5.4.3', '5.4.5', '5.5.2', '5.5.3', '5.5.4', '5.6.2', '5.6.3', '5.7.2', '5.7.3', '5.8.2', '5.8.3', 'next', 'latest' ]) { await shell(`npm install typescript@${version} --no-save`) await test_static() } } export async function test_static() { await shell(`tsc -v`) await shell(`tsc -p test/static/tsconfig.json --noEmit --strict`) } export async function test_runtime(filter = '') { await shell(`hammer build ./test/runtime/index.ts --dist target/test/runtime --platform node`) await shell(`mocha target/test/runtime/index.js -g "${filter}"`) } export async function test(filter = '') { await test_static() await test_runtime(filter) } // ------------------------------------------------------------------------------- // Build // ------------------------------------------------------------------------------- export async function build_check(target = 'target/build') { const { version } = JSON.parse(Fs.readFileSync('package.json', 'utf8')) await shell(`cd ${target} && attw sinclair-typebox-${version}.tgz`) } export async function build(target = 'target/build') { await test() await clean() await Promise.all([ Build.Package.build(target), Build.Esm.build(target), Build.Cjs.build(target), ]) await folder(target).add('readme.md') await folder(target).add('license') await shell(`cd ${target} && npm pack`) await build_check(target) } // ------------------------------------------------------------------------------- // Build To // ------------------------------------------------------------------------------- export async function build_to(remote = 'target/remote', target = 'target/build') { await clean() await Promise.all([ Build.Package.build(target), Build.Esm.build(target), Build.Cjs.build(target), ]) await folder(target).add('readme.md') await folder(target).add('license') await shell(`cd ${target} && npm pack`) const { version } = JSON.parse(Fs.readFileSync('package.json', 'utf8')) const filename = `${target}/sinclair-typebox-${version}.tgz` await folder(remote).add(filename) } // ------------------------------------------------------------------------------- // Install // ------------------------------------------------------------------------------- export async function install_local() { await clean() await build('target/typebox') await folder('node_modules').add('target/typebox') } // ------------------------------------------------------------- // Publish // ------------------------------------------------------------- export async function publish(otp, target = 'target/build') { const { version } = JSON.parse(Fs.readFileSync('package.json', 'utf8')) if(version.includes('-dev')) throw Error(`package version should not include -dev specifier`) await shell(`cd ${target} && npm publish sinclair-typebox-${version}.tgz --access=public --otp ${otp}`) await shell(`git tag ${version}`) await shell(`git push origin ${version}`) } // ------------------------------------------------------------- // Publish-Dev // ------------------------------------------------------------- export async function publish_dev(otp, target = 'target/build') { const { version } = JSON.parse(Fs.readFileSync(`${target}/package.json`, 'utf8')) if(!version.includes('-dev')) throw Error(`development package version should include -dev specifier`) await shell(`cd ${target} && npm publish sinclair-typebox-${version}.tgz --access=public --otp ${otp} --tag dev`) }sinclairzx81-typebox-e0ec98c/license000066400000000000000000000022631505437577000176300ustar00rootroot00000000000000TypeBox Json Schema Type Builder with Static Type Resolution for TypeScript The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.sinclairzx81-typebox-e0ec98c/package-lock.json000066400000000000000000003641761505437577000215150ustar00rootroot00000000000000{ "name": "@sinclair/typebox", "version": "0.34.41", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@sinclair/typebox", "version": "0.34.41", "license": "MIT", "devDependencies": { "@arethetypeswrong/cli": "^0.13.2", "@sinclair/hammer": "^0.18.0", "@types/mocha": "^9.1.1", "@types/node": "^22.13.5", "ajv": "^8.12.0", "ajv-formats": "^2.1.1", "mocha": "^11.1.0", "prettier": "^2.7.1", "typescript": "^5.9.2" } }, "node_modules/@andrewbranch/untar.js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@andrewbranch/untar.js/-/untar.js-1.0.3.tgz", "integrity": "sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw==", "dev": true }, "node_modules/@arethetypeswrong/cli": { "version": "0.13.2", "resolved": "https://registry.npmjs.org/@arethetypeswrong/cli/-/cli-0.13.2.tgz", "integrity": "sha512-eqRWeFFiI58xwsiUfZSdZsmNCaqqtxmSPP9554ajiCDrB/aNzq5VktVK7dNiT9PamunNeoej4KbDBnkNwVacvg==", "dev": true, "dependencies": { "@arethetypeswrong/core": "0.13.2", "chalk": "^4.1.2", "cli-table3": "^0.6.3", "commander": "^10.0.1", "marked": "^9.1.2", "marked-terminal": "^6.0.0", "semver": "^7.5.4" }, "bin": { "attw": "dist/index.js" }, "engines": { "node": ">=18" } }, "node_modules/@arethetypeswrong/core": { "version": "0.13.2", "resolved": "https://registry.npmjs.org/@arethetypeswrong/core/-/core-0.13.2.tgz", "integrity": "sha512-1l6ygar+6TH4o1JipWWGCEZlOhAwEShm1yKx+CgIByNjCzufbu6k9DNbDmBjdouusNRhBIOYQe1UHnJig+GtAw==", "dev": true, "dependencies": { "@andrewbranch/untar.js": "^1.0.3", "fflate": "^0.7.4", "semver": "^7.5.4", "typescript": "5.3.2", "validate-npm-package-name": "^5.0.0" }, "engines": { "node": ">=18" } }, "node_modules/@arethetypeswrong/core/node_modules/typescript": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz", "integrity": "sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { "node": ">=14.17" } }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", "dev": true, "optional": true, "engines": { "node": ">=0.1.90" } }, "node_modules/@esbuild/linux-loong64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.7.tgz", "integrity": "sha512-IKznSJOsVUuyt7cDzzSZyqBEcZe+7WlBqTVXiF1OXP/4Nm387ToaXZ0fyLwI1iBlI/bzpxVq411QE2/Bt2XWWw==", "cpu": [ "loong64" ], "dev": true, "optional": true, "os": [ "linux" ], "engines": { "node": ">=12" } }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, "engines": { "node": ">=12" } }, "node_modules/@isaacs/cliui/node_modules/ansi-regex": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@isaacs/cliui/node_modules/strip-ansi": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { "ansi-regex": "^6.0.1" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "dev": true, "optional": true, "engines": { "node": ">=14" } }, "node_modules/@sinclair/hammer": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/@sinclair/hammer/-/hammer-0.18.0.tgz", "integrity": "sha512-nIrsOWvvCV/SjTSU4qcOsY3mEO8ErN2WBWzbn6mVpqDajy36lG9WbDEfR6Agm3LbN2pdPl1HGjKuiHpbpOTZ2A==", "dev": true, "dependencies": { "esbuild": "0.15.7" }, "bin": { "hammer": "hammer" } }, "node_modules/@sindresorhus/is": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sindresorhus/is?sponsor=1" } }, "node_modules/@types/mocha": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", "dev": true }, "node_modules/@types/node": { "version": "22.13.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.5.tgz", "integrity": "sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg==", "dev": true, "dependencies": { "undici-types": "~6.20.0" } }, "node_modules/ajv": { "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.2.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/ajv-formats": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "dev": true, "dependencies": { "ajv": "^8.0.0" }, "peerDependencies": { "ajv": "^8.0.0" }, "peerDependenciesMeta": { "ajv": { "optional": true } } }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/ansi-escapes": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==", "dev": true, "dependencies": { "type-fest": "^3.0.0" }, "engines": { "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/ansicolors": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", "dev": true }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" }, "engines": { "node": ">= 8" } }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, "node_modules/builtins": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", "dev": true, "dependencies": { "semver": "^7.0.0" } }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cardinal": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", "dev": true, "dependencies": { "ansicolors": "~0.3.2", "redeyed": "~2.1.0" }, "bin": { "cdl": "bin/cdl.js" } }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/chalk/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/char-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, "engines": { "node": ">=10" } }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "funding": [ { "type": "individual", "url": "https://paulmillr.com/funding/" } ], "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "engines": { "node": ">= 8.10.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "node_modules/cli-table3": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", "dev": true, "dependencies": { "string-width": "^4.2.0" }, "engines": { "node": "10.* || >= 12.*" }, "optionalDependencies": { "@colors/colors": "1.5.0" } }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" }, "engines": { "node": ">=12" } }, "node_modules/cliui/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "node_modules/commander": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", "dev": true, "engines": { "node": ">=14" } }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" }, "engines": { "node": ">= 8" } }, "node_modules/debug": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, "dependencies": { "ms": "^2.1.3" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/decamelize": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/diff": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true, "engines": { "node": ">=0.3.1" } }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "node_modules/emojilib": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", "dev": true }, "node_modules/esbuild": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.7.tgz", "integrity": "sha512-7V8tzllIbAQV1M4QoE52ImKu8hT/NLGlGXkiDsbEU5PS6K8Mn09ZnYoS+dcmHxOS9CRsV4IRAMdT3I67IyUNXw==", "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" }, "engines": { "node": ">=12" }, "optionalDependencies": { "@esbuild/linux-loong64": "0.15.7", "esbuild-android-64": "0.15.7", "esbuild-android-arm64": "0.15.7", "esbuild-darwin-64": "0.15.7", "esbuild-darwin-arm64": "0.15.7", "esbuild-freebsd-64": "0.15.7", "esbuild-freebsd-arm64": "0.15.7", "esbuild-linux-32": "0.15.7", "esbuild-linux-64": "0.15.7", "esbuild-linux-arm": "0.15.7", "esbuild-linux-arm64": "0.15.7", "esbuild-linux-mips64le": "0.15.7", "esbuild-linux-ppc64le": "0.15.7", "esbuild-linux-riscv64": "0.15.7", "esbuild-linux-s390x": "0.15.7", "esbuild-netbsd-64": "0.15.7", "esbuild-openbsd-64": "0.15.7", "esbuild-sunos-64": "0.15.7", "esbuild-windows-32": "0.15.7", "esbuild-windows-64": "0.15.7", "esbuild-windows-arm64": "0.15.7" } }, "node_modules/esbuild-android-64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.7.tgz", "integrity": "sha512-p7rCvdsldhxQr3YHxptf1Jcd86dlhvc3EQmQJaZzzuAxefO9PvcI0GLOa5nCWem1AJ8iMRu9w0r5TG8pHmbi9w==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "android" ], "engines": { "node": ">=12" } }, "node_modules/esbuild-android-arm64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.7.tgz", "integrity": "sha512-L775l9ynJT7rVqRM5vo+9w5g2ysbOCfsdLV4CWanTZ1k/9Jb3IYlQ06VCI1edhcosTYJRECQFJa3eAvkx72eyQ==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "android" ], "engines": { "node": ">=12" } }, "node_modules/esbuild-darwin-64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.7.tgz", "integrity": "sha512-KGPt3r1c9ww009t2xLB6Vk0YyNOXh7hbjZ3EecHoVDxgtbUlYstMPDaReimKe6eOEfyY4hBEEeTvKwPsiH5WZg==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "darwin" ], "engines": { "node": ">=12" } }, "node_modules/esbuild-darwin-arm64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.7.tgz", "integrity": "sha512-kBIHvtVqbSGajN88lYMnR3aIleH3ABZLLFLxwL2stiuIGAjGlQW741NxVTpUHQXUmPzxi6POqc9npkXa8AcSZQ==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "darwin" ], "engines": { "node": ">=12" } }, "node_modules/esbuild-freebsd-64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.7.tgz", "integrity": "sha512-hESZB91qDLV5MEwNxzMxPfbjAhOmtfsr9Wnuci7pY6TtEh4UDuevmGmkUIjX/b+e/k4tcNBMf7SRQ2mdNuK/HQ==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "freebsd" ], "engines": { "node": ">=12" } }, "node_modules/esbuild-freebsd-arm64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.7.tgz", "integrity": "sha512-dLFR0ChH5t+b3J8w0fVKGvtwSLWCv7GYT2Y2jFGulF1L5HftQLzVGN+6pi1SivuiVSmTh28FwUhi9PwQicXI6Q==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "freebsd" ], "engines": { "node": ">=12" } }, "node_modules/esbuild-linux-32": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.7.tgz", "integrity": "sha512-v3gT/LsONGUZcjbt2swrMjwxo32NJzk+7sAgtxhGx1+ZmOFaTRXBAi1PPfgpeo/J//Un2jIKm/I+qqeo4caJvg==", "cpu": [ "ia32" ], "dev": true, "optional": true, "os": [ "linux" ], "engines": { "node": ">=12" } }, "node_modules/esbuild-linux-64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.7.tgz", "integrity": "sha512-LxXEfLAKwOVmm1yecpMmWERBshl+Kv5YJ/1KnyAr6HRHFW8cxOEsEfisD3sVl/RvHyW//lhYUVSuy9jGEfIRAQ==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "linux" ], "engines": { "node": ">=12" } }, "node_modules/esbuild-linux-arm": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.7.tgz", "integrity": "sha512-JKgAHtMR5f75wJTeuNQbyznZZa+pjiUHV7sRZp42UNdyXC6TiUYMW/8z8yIBAr2Fpad8hM1royZKQisqPABPvQ==", "cpu": [ "arm" ], "dev": true, "optional": true, "os": [ "linux" ], "engines": { "node": ">=12" } }, "node_modules/esbuild-linux-arm64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.7.tgz", "integrity": "sha512-P3cfhudpzWDkglutWgXcT2S7Ft7o2e3YDMrP1n0z2dlbUZghUkKCyaWw0zhp4KxEEzt/E7lmrtRu/pGWnwb9vw==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "linux" ], "engines": { "node": ">=12" } }, "node_modules/esbuild-linux-mips64le": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.7.tgz", "integrity": "sha512-T7XKuxl0VpeFLCJXub6U+iybiqh0kM/bWOTb4qcPyDDwNVhLUiPcGdG2/0S7F93czUZOKP57YiLV8YQewgLHKw==", "cpu": [ "mips64el" ], "dev": true, "optional": true, "os": [ "linux" ], "engines": { "node": ">=12" } }, "node_modules/esbuild-linux-ppc64le": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.7.tgz", "integrity": "sha512-6mGuC19WpFN7NYbecMIJjeQgvDb5aMuvyk0PDYBJrqAEMkTwg3Z98kEKuCm6THHRnrgsdr7bp4SruSAxEM4eJw==", "cpu": [ "ppc64" ], "dev": true, "optional": true, "os": [ "linux" ], "engines": { "node": ">=12" } }, "node_modules/esbuild-linux-riscv64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.7.tgz", "integrity": "sha512-uUJsezbswAYo/X7OU/P+PuL/EI9WzxsEQXDekfwpQ23uGiooxqoLFAPmXPcRAt941vjlY9jtITEEikWMBr+F/g==", "cpu": [ "riscv64" ], "dev": true, "optional": true, "os": [ "linux" ], "engines": { "node": ">=12" } }, "node_modules/esbuild-linux-s390x": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.7.tgz", "integrity": "sha512-+tO+xOyTNMc34rXlSxK7aCwJgvQyffqEM5MMdNDEeMU3ss0S6wKvbBOQfgd5jRPblfwJ6b+bKiz0g5nABpY0QQ==", "cpu": [ "s390x" ], "dev": true, "optional": true, "os": [ "linux" ], "engines": { "node": ">=12" } }, "node_modules/esbuild-netbsd-64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.7.tgz", "integrity": "sha512-yVc4Wz+Pu3cP5hzm5kIygNPrjar/v5WCSoRmIjCPWfBVJkZNb5brEGKUlf+0Y759D48BCWa0WHrWXaNy0DULTQ==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "netbsd" ], "engines": { "node": ">=12" } }, "node_modules/esbuild-openbsd-64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.7.tgz", "integrity": "sha512-GsimbwC4FSR4lN3wf8XmTQ+r8/0YSQo21rWDL0XFFhLHKlzEA4SsT1Tl8bPYu00IU6UWSJ+b3fG/8SB69rcuEQ==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "openbsd" ], "engines": { "node": ">=12" } }, "node_modules/esbuild-sunos-64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.7.tgz", "integrity": "sha512-8CDI1aL/ts0mDGbWzjEOGKXnU7p3rDzggHSBtVryQzkSOsjCHRVe0iFYUuhczlxU1R3LN/E7HgUO4NXzGGP/Ag==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "sunos" ], "engines": { "node": ">=12" } }, "node_modules/esbuild-windows-32": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.7.tgz", "integrity": "sha512-cOnKXUEPS8EGCzRSFa1x6NQjGhGsFlVgjhqGEbLTPsA7x4RRYiy2RKoArNUU4iR2vHmzqS5Gr84MEumO/wxYKA==", "cpu": [ "ia32" ], "dev": true, "optional": true, "os": [ "win32" ], "engines": { "node": ">=12" } }, "node_modules/esbuild-windows-64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.7.tgz", "integrity": "sha512-7MI08Ec2sTIDv+zH6StNBKO+2hGUYIT42GmFyW6MBBWWtJhTcQLinKS6ldIN1d52MXIbiJ6nXyCJ+LpL4jBm3Q==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "win32" ], "engines": { "node": ">=12" } }, "node_modules/esbuild-windows-arm64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.7.tgz", "integrity": "sha512-R06nmqBlWjKHddhRJYlqDd3Fabx9LFdKcjoOy08YLimwmsswlFBJV4rXzZCxz/b7ZJXvrZgj8DDv1ewE9+StMw==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "win32" ], "engines": { "node": ">=12" } }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" }, "engines": { "node": ">=4" } }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "node_modules/fflate": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz", "integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==", "dev": true }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, "bin": { "flat": "cli.js" } }, "node_modules/foreground-child": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", "dev": true, "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" }, "engines": { "node": ">=14" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "hasInstallScript": true, "optional": true, "os": [ "darwin" ], "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "dependencies": { "is-glob": "^4.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/glob/node_modules/minimatch": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, "bin": { "he": "bin/he" } }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, "engines": { "node": ">=0.12.0" } }, "node_modules/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, "node_modules/jackspeak": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, "dependencies": { "@isaacs/cliui": "^8.0.2" }, "funding": { "url": "https://github.com/sponsors/isaacs" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "dependencies": { "p-locate": "^5.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=10" } }, "node_modules/marked": { "version": "9.1.6", "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.6.tgz", "integrity": "sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==", "dev": true, "bin": { "marked": "bin/marked.js" }, "engines": { "node": ">= 16" } }, "node_modules/marked-terminal": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-6.1.0.tgz", "integrity": "sha512-QaCSF6NV82oo6K0szEnmc65ooDeW0T/Adcyf0fcW+Hto2GT1VADFg8dn1zaeHqzj65fqDH1hMNChGNRaC/lbkA==", "dev": true, "dependencies": { "ansi-escapes": "^6.2.0", "cardinal": "^2.1.1", "chalk": "^5.3.0", "cli-table3": "^0.6.3", "node-emoji": "^2.1.0", "supports-hyperlinks": "^3.0.0" }, "engines": { "node": ">=16.0.0" }, "peerDependencies": { "marked": ">=1 <11" } }, "node_modules/marked-terminal/node_modules/chalk": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/minimatch": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { "node": ">=10" } }, "node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" } }, "node_modules/mocha": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.1.0.tgz", "integrity": "sha512-8uJR5RTC2NgpY3GrYcgpZrsEd9zKbPDpob1RezyR2upGHRQtHWofmzTMzTMSV6dru3tj5Ukt0+Vnq1qhFEEwAg==", "dev": true, "dependencies": { "ansi-colors": "^4.1.3", "browser-stdout": "^1.3.1", "chokidar": "^3.5.3", "debug": "^4.3.5", "diff": "^5.2.0", "escape-string-regexp": "^4.0.0", "find-up": "^5.0.0", "glob": "^10.4.5", "he": "^1.2.0", "js-yaml": "^4.1.0", "log-symbols": "^4.1.0", "minimatch": "^5.1.6", "ms": "^2.1.3", "serialize-javascript": "^6.0.2", "strip-json-comments": "^3.1.1", "supports-color": "^8.1.1", "workerpool": "^6.5.1", "yargs": "^17.7.2", "yargs-parser": "^21.1.1", "yargs-unparser": "^2.0.0" }, "bin": { "_mocha": "bin/_mocha", "mocha": "bin/mocha.js" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "node_modules/node-emoji": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", "dev": true, "dependencies": { "@sindresorhus/is": "^4.6.0", "char-regex": "^1.0.2", "emojilib": "^2.4.0", "skin-tone": "^2.0.0" }, "engines": { "node": ">=18" } }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "dependencies": { "yocto-queue": "^0.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "dependencies": { "p-limit": "^3.0.2" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "dev": true }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/path-scurry/node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "engines": { "node": ">=8.6" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/prettier": { "version": "2.8.8", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, "bin": { "prettier": "bin-prettier.js" }, "engines": { "node": ">=10.13.0" }, "funding": { "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "dependencies": { "safe-buffer": "^5.1.0" } }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "dependencies": { "picomatch": "^2.2.1" }, "engines": { "node": ">=8.10.0" } }, "node_modules/redeyed": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", "dev": true, "dependencies": { "esprima": "~4.0.0" } }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ] }, "node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, "engines": { "node": ">=8" } }, "node_modules/shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, "engines": { "node": ">=14" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/skin-tone": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", "dev": true, "dependencies": { "unicode-emoji-modifier-base": "^1.0.0" }, "engines": { "node": ">=8" } }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/string-width-cjs": { "name": "string-width", "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/supports-hyperlinks": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", "dev": true, "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" }, "engines": { "node": ">=14.18" } }, "node_modules/supports-hyperlinks/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "dependencies": { "is-number": "^7.0.0" }, "engines": { "node": ">=8.0" } }, "node_modules/type-fest": { "version": "3.13.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", "dev": true, "engines": { "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/typescript": { "version": "5.9.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { "node": ">=14.17" } }, "node_modules/undici-types": { "version": "6.20.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", "dev": true }, "node_modules/unicode-emoji-modifier-base": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "dependencies": { "punycode": "^2.1.0" } }, "node_modules/validate-npm-package-name": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz", "integrity": "sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==", "dev": true, "dependencies": { "builtins": "^5.0.0" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" }, "engines": { "node": ">= 8" } }, "node_modules/workerpool": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", "dev": true }, "node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/wrap-ansi/node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, "node_modules/wrap-ansi/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/wrap-ansi/node_modules/strip-ansi": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { "ansi-regex": "^6.0.1" }, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, "engines": { "node": ">=10" } }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" }, "engines": { "node": ">=12" } }, "node_modules/yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, "engines": { "node": ">=12" } }, "node_modules/yargs-unparser": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" }, "engines": { "node": ">=10" } }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } } }, "dependencies": { "@andrewbranch/untar.js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@andrewbranch/untar.js/-/untar.js-1.0.3.tgz", "integrity": "sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw==", "dev": true }, "@arethetypeswrong/cli": { "version": "0.13.2", "resolved": "https://registry.npmjs.org/@arethetypeswrong/cli/-/cli-0.13.2.tgz", "integrity": "sha512-eqRWeFFiI58xwsiUfZSdZsmNCaqqtxmSPP9554ajiCDrB/aNzq5VktVK7dNiT9PamunNeoej4KbDBnkNwVacvg==", "dev": true, "requires": { "@arethetypeswrong/core": "0.13.2", "chalk": "^4.1.2", "cli-table3": "^0.6.3", "commander": "^10.0.1", "marked": "^9.1.2", "marked-terminal": "^6.0.0", "semver": "^7.5.4" } }, "@arethetypeswrong/core": { "version": "0.13.2", "resolved": "https://registry.npmjs.org/@arethetypeswrong/core/-/core-0.13.2.tgz", "integrity": "sha512-1l6ygar+6TH4o1JipWWGCEZlOhAwEShm1yKx+CgIByNjCzufbu6k9DNbDmBjdouusNRhBIOYQe1UHnJig+GtAw==", "dev": true, "requires": { "@andrewbranch/untar.js": "^1.0.3", "fflate": "^0.7.4", "semver": "^7.5.4", "typescript": "5.3.2", "validate-npm-package-name": "^5.0.0" }, "dependencies": { "typescript": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz", "integrity": "sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==", "dev": true } } }, "@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", "dev": true, "optional": true }, "@esbuild/linux-loong64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.7.tgz", "integrity": "sha512-IKznSJOsVUuyt7cDzzSZyqBEcZe+7WlBqTVXiF1OXP/4Nm387ToaXZ0fyLwI1iBlI/bzpxVq411QE2/Bt2XWWw==", "dev": true, "optional": true }, "@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, "requires": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, "dependencies": { "ansi-regex": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true }, "emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, "string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, "requires": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "strip-ansi": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "requires": { "ansi-regex": "^6.0.1" } } } }, "@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "dev": true, "optional": true }, "@sinclair/hammer": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/@sinclair/hammer/-/hammer-0.18.0.tgz", "integrity": "sha512-nIrsOWvvCV/SjTSU4qcOsY3mEO8ErN2WBWzbn6mVpqDajy36lG9WbDEfR6Agm3LbN2pdPl1HGjKuiHpbpOTZ2A==", "dev": true, "requires": { "esbuild": "0.15.7" } }, "@sindresorhus/is": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "dev": true }, "@types/mocha": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", "dev": true }, "@types/node": { "version": "22.13.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.5.tgz", "integrity": "sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg==", "dev": true, "requires": { "undici-types": "~6.20.0" } }, "ajv": { "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.2.2" } }, "ajv-formats": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "dev": true, "requires": { "ajv": "^8.0.0" } }, "ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true }, "ansi-escapes": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==", "dev": true, "requires": { "type-fest": "^3.0.0" } }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { "color-convert": "^2.0.1" } }, "ansicolors": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", "dev": true }, "anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, "brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "requires": { "balanced-match": "^1.0.0" } }, "braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "requires": { "fill-range": "^7.1.1" } }, "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, "builtins": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", "dev": true, "requires": { "semver": "^7.0.0" } }, "camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true }, "cardinal": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", "dev": true, "requires": { "ansicolors": "~0.3.2", "redeyed": "~2.1.0" } }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "dependencies": { "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" } } } }, "char-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "requires": { "anymatch": "~3.1.2", "braces": "~3.0.2", "fsevents": "~2.3.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" } }, "cli-table3": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", "dev": true, "requires": { "@colors/colors": "1.5.0", "string-width": "^4.2.0" } }, "cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" }, "dependencies": { "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } } } }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" } }, "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "commander": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", "dev": true }, "cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "debug": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, "requires": { "ms": "^2.1.3" } }, "decamelize": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true }, "diff": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true }, "eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "emojilib": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", "dev": true }, "esbuild": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.7.tgz", "integrity": "sha512-7V8tzllIbAQV1M4QoE52ImKu8hT/NLGlGXkiDsbEU5PS6K8Mn09ZnYoS+dcmHxOS9CRsV4IRAMdT3I67IyUNXw==", "dev": true, "requires": { "@esbuild/linux-loong64": "0.15.7", "esbuild-android-64": "0.15.7", "esbuild-android-arm64": "0.15.7", "esbuild-darwin-64": "0.15.7", "esbuild-darwin-arm64": "0.15.7", "esbuild-freebsd-64": "0.15.7", "esbuild-freebsd-arm64": "0.15.7", "esbuild-linux-32": "0.15.7", "esbuild-linux-64": "0.15.7", "esbuild-linux-arm": "0.15.7", "esbuild-linux-arm64": "0.15.7", "esbuild-linux-mips64le": "0.15.7", "esbuild-linux-ppc64le": "0.15.7", "esbuild-linux-riscv64": "0.15.7", "esbuild-linux-s390x": "0.15.7", "esbuild-netbsd-64": "0.15.7", "esbuild-openbsd-64": "0.15.7", "esbuild-sunos-64": "0.15.7", "esbuild-windows-32": "0.15.7", "esbuild-windows-64": "0.15.7", "esbuild-windows-arm64": "0.15.7" } }, "esbuild-android-64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.7.tgz", "integrity": "sha512-p7rCvdsldhxQr3YHxptf1Jcd86dlhvc3EQmQJaZzzuAxefO9PvcI0GLOa5nCWem1AJ8iMRu9w0r5TG8pHmbi9w==", "dev": true, "optional": true }, "esbuild-android-arm64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.7.tgz", "integrity": "sha512-L775l9ynJT7rVqRM5vo+9w5g2ysbOCfsdLV4CWanTZ1k/9Jb3IYlQ06VCI1edhcosTYJRECQFJa3eAvkx72eyQ==", "dev": true, "optional": true }, "esbuild-darwin-64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.7.tgz", "integrity": "sha512-KGPt3r1c9ww009t2xLB6Vk0YyNOXh7hbjZ3EecHoVDxgtbUlYstMPDaReimKe6eOEfyY4hBEEeTvKwPsiH5WZg==", "dev": true, "optional": true }, "esbuild-darwin-arm64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.7.tgz", "integrity": "sha512-kBIHvtVqbSGajN88lYMnR3aIleH3ABZLLFLxwL2stiuIGAjGlQW741NxVTpUHQXUmPzxi6POqc9npkXa8AcSZQ==", "dev": true, "optional": true }, "esbuild-freebsd-64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.7.tgz", "integrity": "sha512-hESZB91qDLV5MEwNxzMxPfbjAhOmtfsr9Wnuci7pY6TtEh4UDuevmGmkUIjX/b+e/k4tcNBMf7SRQ2mdNuK/HQ==", "dev": true, "optional": true }, "esbuild-freebsd-arm64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.7.tgz", "integrity": "sha512-dLFR0ChH5t+b3J8w0fVKGvtwSLWCv7GYT2Y2jFGulF1L5HftQLzVGN+6pi1SivuiVSmTh28FwUhi9PwQicXI6Q==", "dev": true, "optional": true }, "esbuild-linux-32": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.7.tgz", "integrity": "sha512-v3gT/LsONGUZcjbt2swrMjwxo32NJzk+7sAgtxhGx1+ZmOFaTRXBAi1PPfgpeo/J//Un2jIKm/I+qqeo4caJvg==", "dev": true, "optional": true }, "esbuild-linux-64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.7.tgz", "integrity": "sha512-LxXEfLAKwOVmm1yecpMmWERBshl+Kv5YJ/1KnyAr6HRHFW8cxOEsEfisD3sVl/RvHyW//lhYUVSuy9jGEfIRAQ==", "dev": true, "optional": true }, "esbuild-linux-arm": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.7.tgz", "integrity": "sha512-JKgAHtMR5f75wJTeuNQbyznZZa+pjiUHV7sRZp42UNdyXC6TiUYMW/8z8yIBAr2Fpad8hM1royZKQisqPABPvQ==", "dev": true, "optional": true }, "esbuild-linux-arm64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.7.tgz", "integrity": "sha512-P3cfhudpzWDkglutWgXcT2S7Ft7o2e3YDMrP1n0z2dlbUZghUkKCyaWw0zhp4KxEEzt/E7lmrtRu/pGWnwb9vw==", "dev": true, "optional": true }, "esbuild-linux-mips64le": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.7.tgz", "integrity": "sha512-T7XKuxl0VpeFLCJXub6U+iybiqh0kM/bWOTb4qcPyDDwNVhLUiPcGdG2/0S7F93czUZOKP57YiLV8YQewgLHKw==", "dev": true, "optional": true }, "esbuild-linux-ppc64le": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.7.tgz", "integrity": "sha512-6mGuC19WpFN7NYbecMIJjeQgvDb5aMuvyk0PDYBJrqAEMkTwg3Z98kEKuCm6THHRnrgsdr7bp4SruSAxEM4eJw==", "dev": true, "optional": true }, "esbuild-linux-riscv64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.7.tgz", "integrity": "sha512-uUJsezbswAYo/X7OU/P+PuL/EI9WzxsEQXDekfwpQ23uGiooxqoLFAPmXPcRAt941vjlY9jtITEEikWMBr+F/g==", "dev": true, "optional": true }, "esbuild-linux-s390x": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.7.tgz", "integrity": "sha512-+tO+xOyTNMc34rXlSxK7aCwJgvQyffqEM5MMdNDEeMU3ss0S6wKvbBOQfgd5jRPblfwJ6b+bKiz0g5nABpY0QQ==", "dev": true, "optional": true }, "esbuild-netbsd-64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.7.tgz", "integrity": "sha512-yVc4Wz+Pu3cP5hzm5kIygNPrjar/v5WCSoRmIjCPWfBVJkZNb5brEGKUlf+0Y759D48BCWa0WHrWXaNy0DULTQ==", "dev": true, "optional": true }, "esbuild-openbsd-64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.7.tgz", "integrity": "sha512-GsimbwC4FSR4lN3wf8XmTQ+r8/0YSQo21rWDL0XFFhLHKlzEA4SsT1Tl8bPYu00IU6UWSJ+b3fG/8SB69rcuEQ==", "dev": true, "optional": true }, "esbuild-sunos-64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.7.tgz", "integrity": "sha512-8CDI1aL/ts0mDGbWzjEOGKXnU7p3rDzggHSBtVryQzkSOsjCHRVe0iFYUuhczlxU1R3LN/E7HgUO4NXzGGP/Ag==", "dev": true, "optional": true }, "esbuild-windows-32": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.7.tgz", "integrity": "sha512-cOnKXUEPS8EGCzRSFa1x6NQjGhGsFlVgjhqGEbLTPsA7x4RRYiy2RKoArNUU4iR2vHmzqS5Gr84MEumO/wxYKA==", "dev": true, "optional": true }, "esbuild-windows-64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.7.tgz", "integrity": "sha512-7MI08Ec2sTIDv+zH6StNBKO+2hGUYIT42GmFyW6MBBWWtJhTcQLinKS6ldIN1d52MXIbiJ6nXyCJ+LpL4jBm3Q==", "dev": true, "optional": true }, "esbuild-windows-arm64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.7.tgz", "integrity": "sha512-R06nmqBlWjKHddhRJYlqDd3Fabx9LFdKcjoOy08YLimwmsswlFBJV4rXzZCxz/b7ZJXvrZgj8DDv1ewE9+StMw==", "dev": true, "optional": true }, "escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "fflate": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz", "integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==", "dev": true }, "fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "requires": { "to-regex-range": "^5.0.1" } }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "requires": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true }, "foreground-child": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", "dev": true, "requires": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" } }, "fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "optional": true }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "requires": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "dependencies": { "minimatch": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "requires": { "brace-expansion": "^2.0.1" } } } }, "glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { "is-glob": "^4.0.1" } }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "requires": { "binary-extensions": "^2.0.0" } }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "requires": { "is-extglob": "^2.1.1" } }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, "is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, "is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, "jackspeak": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, "requires": { "@isaacs/cliui": "^8.0.2", "@pkgjs/parseargs": "^0.11.0" } }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "requires": { "argparse": "^2.0.1" } }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "requires": { "p-locate": "^5.0.0" } }, "log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "requires": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" } }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { "yallist": "^4.0.0" } }, "marked": { "version": "9.1.6", "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.6.tgz", "integrity": "sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==", "dev": true }, "marked-terminal": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-6.1.0.tgz", "integrity": "sha512-QaCSF6NV82oo6K0szEnmc65ooDeW0T/Adcyf0fcW+Hto2GT1VADFg8dn1zaeHqzj65fqDH1hMNChGNRaC/lbkA==", "dev": true, "requires": { "ansi-escapes": "^6.2.0", "cardinal": "^2.1.1", "chalk": "^5.3.0", "cli-table3": "^0.6.3", "node-emoji": "^2.1.0", "supports-hyperlinks": "^3.0.0" }, "dependencies": { "chalk": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true } } }, "minimatch": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "requires": { "brace-expansion": "^2.0.1" } }, "minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true }, "mocha": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.1.0.tgz", "integrity": "sha512-8uJR5RTC2NgpY3GrYcgpZrsEd9zKbPDpob1RezyR2upGHRQtHWofmzTMzTMSV6dru3tj5Ukt0+Vnq1qhFEEwAg==", "dev": true, "requires": { "ansi-colors": "^4.1.3", "browser-stdout": "^1.3.1", "chokidar": "^3.5.3", "debug": "^4.3.5", "diff": "^5.2.0", "escape-string-regexp": "^4.0.0", "find-up": "^5.0.0", "glob": "^10.4.5", "he": "^1.2.0", "js-yaml": "^4.1.0", "log-symbols": "^4.1.0", "minimatch": "^5.1.6", "ms": "^2.1.3", "serialize-javascript": "^6.0.2", "strip-json-comments": "^3.1.1", "supports-color": "^8.1.1", "workerpool": "^6.5.1", "yargs": "^17.7.2", "yargs-parser": "^21.1.1", "yargs-unparser": "^2.0.0" } }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "node-emoji": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", "dev": true, "requires": { "@sindresorhus/is": "^4.6.0", "char-regex": "^1.0.2", "emojilib": "^2.4.0", "skin-tone": "^2.0.0" } }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "requires": { "yocto-queue": "^0.1.0" } }, "p-locate": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "requires": { "p-limit": "^3.0.2" } }, "package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "dev": true }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, "requires": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "dependencies": { "lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true } } }, "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, "prettier": { "version": "2.8.8", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true }, "punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "requires": { "safe-buffer": "^5.1.0" } }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "requires": { "picomatch": "^2.2.1" } }, "redeyed": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", "dev": true, "requires": { "esprima": "~4.0.0" } }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true }, "semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { "lru-cache": "^6.0.0" } }, "serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "requires": { "randombytes": "^2.1.0" } }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { "shebang-regex": "^3.0.0" } }, "shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true }, "skin-tone": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", "dev": true, "requires": { "unicode-emoji-modifier-base": "^1.0.0" } }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "string-width-cjs": { "version": "npm:string-width@4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { "ansi-regex": "^5.0.1" } }, "strip-ansi-cjs": { "version": "npm:strip-ansi@6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { "ansi-regex": "^5.0.1" } }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, "supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { "has-flag": "^4.0.0" } }, "supports-hyperlinks": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", "dev": true, "requires": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" }, "dependencies": { "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" } } } }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { "is-number": "^7.0.0" } }, "type-fest": { "version": "3.13.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", "dev": true }, "typescript": { "version": "5.9.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "dev": true }, "undici-types": { "version": "6.20.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", "dev": true }, "unicode-emoji-modifier-base": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", "dev": true }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "requires": { "punycode": "^2.1.0" } }, "validate-npm-package-name": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz", "integrity": "sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==", "dev": true, "requires": { "builtins": "^5.0.0" } }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" } }, "workerpool": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", "dev": true }, "wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, "requires": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" }, "dependencies": { "ansi-regex": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true }, "ansi-styles": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true }, "emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, "string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, "requires": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "strip-ansi": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "requires": { "ansi-regex": "^6.0.1" } } } }, "wrap-ansi-cjs": { "version": "npm:wrap-ansi@7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "requires": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true }, "yargs-unparser": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, "requires": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" } }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true } } } sinclairzx81-typebox-e0ec98c/package.json000066400000000000000000000023101505437577000205420ustar00rootroot00000000000000{ "name": "@sinclair/typebox", "version": "0.34.41", "description": "Json Schema Type Builder with Static Type Resolution for TypeScript", "keywords": [ "typescript", "json-schema", "validate", "typecheck" ], "author": "sinclairzx81", "license": "MIT", "repository": { "type": "git", "url": "https://github.com/sinclairzx81/typebox" }, "scripts": { "test:typescript": "hammer task test_typescript", "test:static": "hammer task test_static", "test:runtime": "hammer task test_runtime", "install:local": "hammer task install_local", "benchmark": "hammer task benchmark", "build:to": "hammer task build_to", "build": "hammer task build", "test": "hammer task test", "clean": "hammer task clean", "format": "hammer task format", "start": "hammer task start", "publish": "hammer task publish", "publish:dev": "hammer task publish_dev" }, "devDependencies": { "@arethetypeswrong/cli": "^0.13.2", "@sinclair/hammer": "^0.18.0", "@types/mocha": "^9.1.1", "@types/node": "^22.13.5", "ajv": "^8.12.0", "ajv-formats": "^2.1.1", "mocha": "^11.1.0", "prettier": "^2.7.1", "typescript": "^5.9.2" } } sinclairzx81-typebox-e0ec98c/readme.md000066400000000000000000003642361505437577000200550ustar00rootroot00000000000000

TypeBox

Json Schema Type Builder with Static Type Resolution for TypeScript



[![npm version](https://badge.fury.io/js/%40sinclair%2Ftypebox.svg)](https://badge.fury.io/js/%40sinclair%2Ftypebox) [![Downloads](https://img.shields.io/npm/dm/%40sinclair%2Ftypebox.svg)](https://www.npmjs.com/package/%40sinclair%2Ftypebox) [![Build](https://github.com/sinclairzx81/typebox/actions/workflows/build.yml/badge.svg)](https://github.com/sinclairzx81/typebox/actions/workflows/build.yml) [![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
## Install ```bash $ npm install @sinclair/typebox --save ``` ## Example ```typescript import { Type, type Static } from '@sinclair/typebox' const T = Type.Object({ // const T = { x: Type.Number(), // type: 'object', y: Type.Number(), // required: ['x', 'y', 'z'], z: Type.Number() // properties: { }) // x: { type: 'number' }, // y: { type: 'number' }, // z: { type: 'number' } // } // } type T = Static // type T = { // x: number, // y: number, // z: number // } ``` ## Overview TypeBox is a runtime type builder that creates in-memory Json Schema objects that infer as TypeScript types. The schematics produced by this library are designed to match the static type checking rules of the TypeScript compiler. TypeBox offers a unified type that can be statically checked by TypeScript and runtime asserted using standard Json Schema validation. This library is designed to allow Json Schema to compose similar to how types compose within TypeScript's type system. It can be used as a simple tool to build up complex schematics or integrated into REST and RPC services to help validate data received over the wire. License MIT ## Contents - [Install](#install) - [Overview](#overview) - [Usage](#usage) - [Types](#types) - [Json](#types-json) - [JavaScript](#types-javascript) - [Options](#types-options) - [Properties](#types-properties) - [Generics](#types-generics) - [Recursive](#types-recursive) - [Modules](#types-modules) - [Template Literal](#types-template-literal) - [Indexed](#types-indexed) - [Mapped](#types-mapped) - [Conditional](#types-conditional) - [Transform](#types-transform) - [Guard](#types-guard) - [Unsafe](#types-unsafe) - [Values](#values) - [Assert](#values-assert) - [Create](#values-create) - [Clone](#values-clone) - [Check](#values-check) - [Convert](#values-convert) - [Default](#values-default) - [Clean](#values-clean) - [Cast](#values-cast) - [Decode](#values-decode) - [Encode](#values-decode) - [Parse](#values-parse) - [Equal](#values-equal) - [Hash](#values-hash) - [Diff](#values-diff) - [Patch](#values-patch) - [Errors](#values-errors) - [Mutate](#values-mutate) - [Pointer](#values-pointer) - [Syntax](#syntax) - [Create](#syntax-create) - [Parameters](#syntax-parameters) - [Generics](#syntax-generics) - [Options](#syntax-options) - [NoInfer](#syntax-no-infer) - [TypeRegistry](#typeregistry) - [Type](#typeregistry-type) - [Format](#typeregistry-format) - [TypeCheck](#typecheck) - [Ajv](#typecheck-ajv) - [TypeCompiler](#typecheck-typecompiler) - [TypeMap](#typemap) - [Usage](#typemap-usage) - [TypeSystem](#typesystem) - [Policies](#typesystem-policies) - [Error Function](#error-function) - [Workbench](#workbench) - [Codegen](#codegen) - [Ecosystem](#ecosystem) - [Benchmark](#benchmark) - [Compile](#benchmark-compile) - [Validate](#benchmark-validate) - [Compression](#benchmark-compression) - [Contribute](#contribute) ## Usage The following shows general usage. ```typescript import { Type, type Static } from '@sinclair/typebox' //-------------------------------------------------------------------------------------------- // // Let's say you have the following type ... // //-------------------------------------------------------------------------------------------- type T = { id: string, name: string, timestamp: number } //-------------------------------------------------------------------------------------------- // // ... you can express this type in the following way. // //-------------------------------------------------------------------------------------------- const T = Type.Object({ // const T = { id: Type.String(), // type: 'object', name: Type.String(), // properties: { timestamp: Type.Integer() // id: { }) // type: 'string' // }, // name: { // type: 'string' // }, // timestamp: { // type: 'integer' // } // }, // required: [ // 'id', // 'name', // 'timestamp' // ] // } //-------------------------------------------------------------------------------------------- // // ... then infer back to the original static type this way. // //-------------------------------------------------------------------------------------------- type T = Static // type T = { // id: string, // name: string, // timestamp: number // } //-------------------------------------------------------------------------------------------- // // ... or use the type to parse JavaScript values. // //-------------------------------------------------------------------------------------------- import { Value } from '@sinclair/typebox/value' const R = Value.Parse(T, value) // const R: { // id: string, // name: string, // timestamp: number // } ``` ## Types TypeBox types are Json Schema fragments that compose into more complex types. Each fragment is structured such that any Json Schema compliant validator can runtime assert a value the same way TypeScript will statically assert a type. TypeBox offers a set of Json Types which are used to create Json Schema compliant schematics as well as a JavaScript type set used to create schematics for constructs native to JavaScript. ### Json Types The following table lists the supported Json types. These types are fully compatible with the Json Schema Draft 7 specification. ```typescript ┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────� │ TypeBox │ TypeScript │ Json Schema │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Any() │ type T = any │ const T = { } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Unknown() │ type T = unknown │ const T = { } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.String() │ type T = string │ const T = { │ │ │ │ type: 'string' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Number() │ type T = number │ const T = { │ │ │ │ type: 'number' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Integer() │ type T = number │ const T = { │ │ │ │ type: 'integer' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Boolean() │ type T = boolean │ const T = { │ │ │ │ type: 'boolean' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Null() │ type T = null │ const T = { │ │ │ │ type: 'null' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Literal(42) │ type T = 42 │ const T = { │ │ │ │ const: 42, │ │ │ │ type: 'number' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Array( │ type T = number[] │ const T = { │ │ Type.Number() │ │ type: 'array', │ │ ) │ │ items: { │ │ │ │ type: 'number' │ │ │ │ } │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Object({ │ type T = { │ const T = { │ │ x: Type.Number(), │ x: number, │ type: 'object', │ │ y: Type.Number() │ y: number │ required: ['x', 'y'], │ │ }) │ } │ properties: { │ │ │ │ x: { │ │ │ │ type: 'number' │ │ │ │ }, │ │ │ │ y: { │ │ │ │ type: 'number' │ │ │ │ } │ │ │ │ } │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Tuple([ │ type T = [number, number] │ const T = { │ │ Type.Number(), │ │ type: 'array', │ │ Type.Number() │ │ items: [{ │ │ ]) │ │ type: 'number' │ │ │ │ }, { │ │ │ │ type: 'number' │ │ │ │ }], │ │ │ │ additionalItems: false, │ │ │ │ minItems: 2, │ │ │ │ maxItems: 2 │ │ │ │ } │ │ │ │ │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ enum Foo { │ enum Foo { │ const T = { │ │ A, │ A, │ anyOf: [{ │ │ B │ B │ type: 'number', │ │ } │ } │ const: 0 │ │ │ │ }, { │ │ const T = Type.Enum(Foo) │ type T = Foo │ type: 'number', │ │ │ │ const: 1 │ │ │ │ }] │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Const({ │ type T = { │ const T = { │ │ x: 1, │ readonly x: 1, │ type: 'object', │ │ y: 2, │ readonly y: 2 │ required: ['x', 'y'], │ │ } as const) │ } │ properties: { │ │ │ │ x: { │ │ │ │ type: 'number', │ │ │ │ const: 1 │ │ │ │ }, │ │ │ │ y: { │ │ │ │ type: 'number', │ │ │ │ const: 2 │ │ │ │ } │ │ │ │ } │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.KeyOf( │ type T = keyof { │ const T = { │ │ Type.Object({ │ x: number, │ anyOf: [{ │ │ x: Type.Number(), │ y: number │ type: 'string', │ │ y: Type.Number() │ } │ const: 'x' │ │ }) │ │ }, { │ │ ) │ │ type: 'string', │ │ │ │ const: 'y' │ │ │ │ }] │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Union([ │ type T = string | number │ const T = { │ │ Type.String(), │ │ anyOf: [{ │ │ Type.Number() │ │ type: 'string' │ │ ]) │ │ }, { │ │ │ │ type: 'number' │ │ │ │ }] │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Intersect([ │ type T = { │ const T = { │ │ Type.Object({ │ x: number │ allOf: [{ │ │ x: Type.Number() │ } & { │ type: 'object', │ │ }), │ y: number │ required: ['x'], │ │ Type.Object({ │ } │ properties: { │ │ y: Type.Number() │ │ x: { │ │ }) │ │ type: 'number' │ │ ]) │ │ } │ │ │ │ } │ │ │ │ }, { │ │ │ │ type: 'object', | │ │ │ required: ['y'], │ │ │ │ properties: { │ │ │ │ y: { │ │ │ │ type: 'number' │ │ │ │ } │ │ │ │ } │ │ │ │ }] │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Composite([ │ type T = { │ const T = { │ │ Type.Object({ │ x: number, │ type: 'object', │ │ x: Type.Number() │ y: number │ required: ['x', 'y'], │ │ }), │ } │ properties: { │ │ Type.Object({ │ │ x: { │ │ y: Type.Number() │ │ type: 'number' │ │ }) │ │ }, │ │ ]) │ │ y: { │ │ │ │ type: 'number' │ │ │ │ } │ │ │ │ } │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Never() │ type T = never │ const T = { │ │ │ │ not: {} │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Not( | type T = unknown │ const T = { │ │ Type.String() │ │ not: { │ │ ) │ │ type: 'string' │ │ │ │ } │ │ │ │ } │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Extends( │ type T = │ const T = { │ │ Type.String(), │ string extends number │ const: false, │ │ Type.Number(), │ ? true │ type: 'boolean' │ │ Type.Literal(true), │ : false │ } │ │ Type.Literal(false) │ │ │ │ ) │ │ │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Extract( │ type T = Extract< │ const T = { │ │ Type.Union([ │ string | number, │ type: 'string' │ │ Type.String(), │ string │ } │ │ Type.Number(), │ > │ │ │ ]), │ │ │ │ Type.String() │ │ │ │ ) │ │ │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Exclude( │ type T = Exclude< │ const T = { │ │ Type.Union([ │ string | number, │ type: 'number' │ │ Type.String(), │ string │ } │ │ Type.Number(), │ > │ │ │ ]), │ │ │ │ Type.String() │ │ │ │ ) │ │ │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Mapped( │ type T = { │ const T = { │ │ Type.Union([ │ [_ in 'x' | 'y'] : number │ type: 'object', │ │ Type.Literal('x'), │ } │ required: ['x', 'y'], │ │ Type.Literal('y') │ │ properties: { │ │ ]), │ │ x: { │ │ () => Type.Number() │ │ type: 'number' │ │ ) │ │ }, │ │ │ │ y: { │ │ │ │ type: 'number' │ │ │ │ } │ │ │ │ } │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const U = Type.Union([ │ type U = 'open' | 'close' │ const T = { │ │ Type.Literal('open'), │ │ type: 'string', │ │ Type.Literal('close') │ type T = `on${U}` │ pattern: '^on(open|close)$' │ │ ]) │ │ } │ │ │ │ │ │ const T = Type │ │ │ │ .TemplateLiteral([ │ │ │ │ Type.Literal('on'), │ │ │ │ U │ │ │ │ ]) │ │ │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Record( │ type T = Record< │ const T = { │ │ Type.String(), │ string, │ type: 'object', │ │ Type.Number() │ number │ patternProperties: { │ │ ) │ > │ '^.*$': { │ │ │ │ type: 'number' │ │ │ │ } │ │ │ │ } │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Partial( │ type T = Partial<{ │ const T = { │ │ Type.Object({ │ x: number, │ type: 'object', │ │ x: Type.Number(), │ y: number │ properties: { │ │ y: Type.Number() | }> │ x: { │ │ }) │ │ type: 'number' │ │ ) │ │ }, │ │ │ │ y: { │ │ │ │ type: 'number' │ │ │ │ } │ │ │ │ } │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Required( │ type T = Required<{ │ const T = { │ │ Type.Object({ │ x?: number, │ type: 'object', │ │ x: Type.Optional( │ y?: number │ required: ['x', 'y'], │ │ Type.Number() | }> │ properties: { │ │ ), │ │ x: { │ │ y: Type.Optional( │ │ type: 'number' │ │ Type.Number() │ │ }, │ │ ) │ │ y: { │ │ }) │ │ type: 'number' │ │ ) │ │ } │ │ │ │ } │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Pick( │ type T = Pick<{ │ const T = { │ │ Type.Object({ │ x: number, │ type: 'object', │ │ x: Type.Number(), │ y: number │ required: ['x'], │ │ y: Type.Number() │ }, 'x'> │ properties: { │ │ }), ['x'] | │ x: { │ │ ) │ │ type: 'number' │ │ │ │ } │ │ │ │ } │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Omit( │ type T = Omit<{ │ const T = { │ │ Type.Object({ │ x: number, │ type: 'object', │ │ x: Type.Number(), │ y: number │ required: ['y'], │ │ y: Type.Number() │ }, 'x'> │ properties: { │ │ }), ['x'] | │ y: { │ │ ) │ │ type: 'number' │ │ │ │ } │ │ │ │ } │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Index( │ type T = { │ const T = { │ │ Type.Object({ │ x: number, │ type: 'number' │ │ x: Type.Number(), │ y: string │ } │ │ y: Type.String() │ }['x'] │ │ │ }), ['x'] │ │ │ │ ) │ │ │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const A = Type.Tuple([ │ type A = [0, 1] │ const T = { │ │ Type.Literal(0), │ type B = [2, 3] │ type: 'array', │ │ Type.Literal(1) │ type T = [ │ items: [ │ │ ]) │ ...A, │ { const: 0 }, │ │ const B = Type.Tuple([ │ ...B │ { const: 1 }, │ | Type.Literal(2), │ ] │ { const: 2 }, │ | Type.Literal(3) │ │ { const: 3 } │ │ ]) │ │ ], │ │ const T = Type.Tuple([ │ │ additionalItems: false, │ | ...Type.Rest(A), │ │ minItems: 4, │ | ...Type.Rest(B) │ │ maxItems: 4 │ │ ]) │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Uncapitalize( │ type T = Uncapitalize< │ const T = { │ │ Type.Literal('Hello') │ 'Hello' │ type: 'string', │ │ ) │ > │ const: 'hello' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Capitalize( │ type T = Capitalize< │ const T = { │ │ Type.Literal('hello') │ 'hello' │ type: 'string', │ │ ) │ > │ const: 'Hello' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Uppercase( │ type T = Uppercase< │ const T = { │ │ Type.Literal('hello') │ 'hello' │ type: 'string', │ │ ) │ > │ const: 'HELLO' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Lowercase( │ type T = Lowercase< │ const T = { │ │ Type.Literal('HELLO') │ 'HELLO' │ type: 'string', │ │ ) │ > │ const: 'hello' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const R = Type.Ref('T') │ type R = unknown │ const R = { $ref: 'T' } │ │ │ │ │ └────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘ ``` ### JavaScript Types TypeBox provides an extended type set that can be used to create schematics for common JavaScript constructs. These types can not be used with any standard Json Schema validator; but can be used to frame schematics for interfaces that may receive Json validated data. JavaScript types are prefixed with the `[JavaScript]` JSDoc comment for convenience. The following table lists the supported types. ```typescript ┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────� │ TypeBox │ TypeScript │ Extended Schema │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Constructor([ │ type T = new ( │ const T = { │ │ Type.String(), │ arg0: string, │ type: 'Constructor', │ │ Type.Number() │ arg0: number │ parameters: [{ │ │ ], Type.Boolean()) │ ) => boolean │ type: 'string' │ │ │ │ }, { │ │ │ │ type: 'number' │ │ │ │ }], │ │ │ │ returns: { │ │ │ │ type: 'boolean' │ │ │ │ } │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Function([ │ type T = ( │ const T = { │ | Type.String(), │ arg0: string, │ type: 'Function', │ │ Type.Number() │ arg1: number │ parameters: [{ │ │ ], Type.Boolean()) │ ) => boolean │ type: 'string' │ │ │ │ }, { │ │ │ │ type: 'number' │ │ │ │ }], │ │ │ │ returns: { │ │ │ │ type: 'boolean' │ │ │ │ } │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Promise( │ type T = Promise │ const T = { │ │ Type.String() │ │ type: 'Promise', │ │ ) │ │ item: { │ │ │ │ type: 'string' │ │ │ │ } │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = │ type T = │ const T = { │ │ Type.AsyncIterator( │ AsyncIterableIterator< │ type: 'AsyncIterator', │ │ Type.String() │ string │ items: { │ │ ) │ > │ type: 'string' │ │ │ │ } │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Iterator( │ type T = │ const T = { │ │ Type.String() │ IterableIterator │ type: 'Iterator', │ │ ) │ │ items: { │ │ │ │ type: 'string' │ │ │ │ } │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.RegExp(/abc/i) │ type T = string │ const T = { │ │ │ │ type: 'RegExp' │ │ │ │ source: 'abc' │ │ │ │ flags: 'i' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Uint8Array() │ type T = Uint8Array │ const T = { │ │ │ │ type: 'Uint8Array' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Date() │ type T = Date │ const T = { │ │ │ │ type: 'Date' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Undefined() │ type T = undefined │ const T = { │ │ │ │ type: 'undefined' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Symbol() │ type T = symbol │ const T = { │ │ │ │ type: 'symbol' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.BigInt() │ type T = bigint │ const T = { │ │ │ │ type: 'bigint' │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Void() │ type T = void │ const T = { │ │ │ │ type: 'void' │ │ │ │ } │ │ │ │ │ └────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘ ``` ### Options You can pass Json Schema options on the last argument of any given type. Option hints specific to each type are provided for convenience. ```typescript // String must be an email const T = Type.String({ // const T = { format: 'email' // type: 'string', }) // format: 'email' // } // Number must be a multiple of 2 const T = Type.Number({ // const T = { multipleOf: 2 // type: 'number', }) // multipleOf: 2 // } // Array must have at least 5 integer values const T = Type.Array(Type.Integer(), { // const T = { minItems: 5 // type: 'array', }) // minItems: 5, // items: { // type: 'integer' // } // } ``` ### Properties Object properties can be modified with Readonly and Optional. The following table shows how these modifiers map between TypeScript and Json Schema. ```typescript ┌────────────────────────────────┬─────────────────────────────┬────────────────────────────────� │ TypeBox │ TypeScript │ Json Schema │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Object({ │ type T = { │ const T = { │ │ name: Type.ReadonlyOptional( │ readonly name?: string │ type: 'object', │ │ Type.String() │ } │ properties: { │ │ ) │ │ name: { │ │ }) │ │ type: 'string' │ │ │ │ } │ │ │ │ } │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Object({ │ type T = { │ const T = { │ │ name: Type.Readonly( │ readonly name: string │ type: 'object', │ │ Type.String() │ } │ properties: { │ │ ) │ │ name: { │ │ }) │ │ type: 'string' │ │ │ │ } │ │ │ │ }, │ │ │ │ required: ['name'] │ │ │ │ } │ │ │ │ │ ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤ │ const T = Type.Object({ │ type T = { │ const T = { │ │ name: Type.Optional( │ name?: string │ type: 'object', │ │ Type.String() │ } │ properties: { │ │ ) │ │ name: { │ │ }) │ │ type: 'string' │ │ │ │ } │ │ │ │ } │ │ │ │ } │ │ │ │ │ └────────────────────────────────┴─────────────────────────────┴────────────────────────────────┘ ``` ### Generic Types Generic types can be created with generic functions. ```typescript const Nullable = (T: T) => { // type Nullable = T | null return Type.Union([T, Type.Null()]) } const T = Nullable(Type.String()) // type T = Nullable ``` ### Recursive Types Use the Recursive function to create recursive types. ```typescript const Node = Type.Recursive(This => Type.Object({ // const Node = { id: Type.String(), // $id: 'Node', nodes: Type.Array(This) // type: 'object', }), { $id: 'Node' }) // properties: { // id: { // type: 'string' // }, // nodes: { // type: 'array', // items: { // $ref: 'Node' // } // } // }, // required: [ // 'id', // 'nodes' // ] // } type Node = Static // type Node = { // id: string // nodes: Node[] // } function test(node: Node) { const id = node.nodes[0].nodes[0].id // id is string } ``` ### Module Types Module types are containers for a set of referential types. Modules act as namespaces, enabling types to reference one another via string identifiers. Modules support both singular and mutually recursive references, as well as deferred dereferencing for computed types such as Partial. Types imported from a module are expressed using the Json Schema `$defs` keyword. ```typescript const Module = Type.Module({ PartialUser: Type.Partial(Type.Ref('User')), // TComputed<'Partial', [TRef<'User'>]> User: Type.Object({ // TObject<{ id: Type.String(), // user: TString, name: Type.String(), // name: TString, email: Type.String() // email: TString }), // }> }) const User = Module.Import('User') // const User: TImport<{...}, 'User'> type User = Static // type User = { // id: string, // name: string, // email: string // } const PartialUser = Module.Import('PartialUser') // const PartialUser: TImport<{...}, 'PartialUser'> type PartialUser = Static // type PartialUser = { // id?: string, // name?: string, // email?: string // } ``` ### Template Literal Types TypeBox supports template literal types with the TemplateLiteral function. This type can be created using a syntax similar to the TypeScript template literal syntax or composed from exterior types. TypeBox encodes template literals as regular expressions which enables the template to be checked by Json Schema validators. This type also supports regular expression parsing that enables template patterns to be used for generative types. The following shows both TypeScript and TypeBox usage. ```typescript // TypeScript type K = `prop${'A'|'B'|'C'}` // type T = 'propA' | 'propB' | 'propC' type R = Record // type R = { // propA: string // propB: string // propC: string // } // TypeBox const K = Type.TemplateLiteral('prop${A|B|C}') // const K: TTemplateLiteral<[ // TLiteral<'prop'>, // TUnion<[ // TLiteral<'A'>, // TLiteral<'B'>, // TLiteral<'C'>, // ]> // ]> const R = Type.Record(K, Type.String()) // const R: TObject<{ // propA: TString, // propB: TString, // propC: TString, // }> ``` ### Indexed Access Types TypeBox supports indexed access types with the Index function. This function enables uniform access to interior property and element types without having to extract them from the underlying schema representation. Index types are supported for Object, Array, Tuple, Union and Intersect types. ```typescript const T = Type.Object({ // type T = { x: Type.Number(), // x: number, y: Type.String(), // y: string, z: Type.Boolean() // z: boolean }) // } const A = Type.Index(T, ['x']) // type A = T['x'] // // ... evaluated as // // const A: TNumber const B = Type.Index(T, ['x', 'y']) // type B = T['x' | 'y'] // // ... evaluated as // // const B: TUnion<[ // TNumber, // TString, // ]> const C = Type.Index(T, Type.KeyOf(T)) // type C = T[keyof T] // // ... evaluated as // // const C: TUnion<[ // TNumber, // TString, // TBoolean // ]> ``` ### Mapped Types TypeBox supports mapped types with the Mapped function. This function accepts two arguments, the first is a union type typically derived from KeyOf, the second is a mapping function that receives a mapping key `K` that can be used to index properties of a type. The following implements a mapped type that remaps each property to be `T | null`. ```typescript const T = Type.Object({ // type T = { x: Type.Number(), // x: number, y: Type.String(), // y: string, z: Type.Boolean() // z: boolean }) // } const M = Type.Mapped(Type.KeyOf(T), K => { // type M = { [K in keyof T]: T[K] | null } return Type.Union([Type.Index(T, K), Type.Null()]) // }) // ... evaluated as // // const M: TObject<{ // x: TUnion<[TNumber, TNull]>, // y: TUnion<[TString, TNull]>, // z: TUnion<[TBoolean, TNull]> // }> ``` ### Conditional Types TypeBox supports runtime conditional types with the Extends function. This function performs a structural assignability check against the first (`left`) and second (`right`) arguments and will return either the third (`true`) or fourth (`false`) argument based on the result. The conditional types Exclude and Extract are also supported. The following shows both TypeScript and TypeBox examples of conditional types. ```typescript // Extends const A = Type.Extends( // type A = string extends number ? 1 : 2 Type.String(), // Type.Number(), // ... evaluated as Type.Literal(1), // Type.Literal(2) // const A: TLiteral<2> ) // Extract const B = Type.Extract( // type B = Extract<1 | 2 | 3, 1> Type.Union([ // Type.Literal(1), // ... evaluated as Type.Literal(2), // Type.Literal(3) // const B: TLiteral<1> ]), Type.Literal(1) ) // Exclude const C = Type.Exclude( // type C = Exclude<1 | 2 | 3, 1> Type.Union([ // Type.Literal(1), // ... evaluated as Type.Literal(2), // Type.Literal(3) // const C: TUnion<[ ]), // TLiteral<2>, Type.Literal(1) // TLiteral<3>, ) // ]> ``` ### Transform Types TypeBox supports value decoding and encoding with Transform types. These types work in tandem with the Encode and Decode functions available on the Value and TypeCompiler submodules. Transform types can be used to convert Json encoded values into constructs more natural to JavaScript. The following creates a Transform type to decode numbers into Dates using the Value submodule. ```typescript import { Value } from '@sinclair/typebox/value' const T = Type.Transform(Type.Number()) .Decode(value => new Date(value)) // decode: number to Date .Encode(value => value.getTime()) // encode: Date to number const D = Value.Decode(T, 0) // const D = Date(1970-01-01T00:00:00.000Z) const E = Value.Encode(T, D) // const E = 0 ``` Use the StaticEncode or StaticDecode types to infer a Transform type. ```typescript import { Static, StaticDecode, StaticEncode } from '@sinclair/typebox' const T = Type.Transform(Type.Array(Type.Number(), { uniqueItems: true })) .Decode(value => new Set(value)) .Encode(value => [...value]) type D = StaticDecode // type D = Set type E = StaticEncode // type E = Array type T = Static // type T = Array ``` ### Unsafe Types TypeBox supports user defined types with Unsafe. This type allows you to specify both schema representation and inference type. The following creates an Unsafe type with a number schema that infers as string. ```typescript const T = Type.Unsafe({ type: 'number' }) // const T = { type: 'number' } type T = Static // type T = string - ? ``` The Unsafe type is often used to create schematics for extended specifications like OpenAPI. ```typescript const Nullable = (schema: T) => Type.Unsafe | null>({ ...schema, nullable: true }) const T = Nullable(Type.String()) // const T = { // type: 'string', // nullable: true // } type T = Static // type T = string | null const StringEnum = (values: [...T]) => Type.Unsafe({ type: 'string', enum: values }) const S = StringEnum(['A', 'B', 'C']) // const S = { // enum: ['A', 'B', 'C'] // } type S = Static // type S = 'A' | 'B' | 'C' ``` ### TypeGuard TypeBox can check its own types with the TypeGuard module. This module is written for type introspection and provides structural tests for every built-in TypeBox type. Functions of this module return `is` guards which can be used with control flow assertions to obtain schema inference for unknown values. The following guards that the value `T` is TString. ```typescript import { TypeGuard, Kind } from '@sinclair/typebox' const T = { [Kind]: 'String', type: 'string' } if(TypeGuard.IsString(T)) { // T is TString } ``` ## Values TypeBox provides an optional Value submodule that can be used to perform structural operations on JavaScript values. This submodule includes functionality to create, check and cast values from types as well as check equality, clone, diff and patch JavaScript values. This submodule is provided via optional import. ```typescript import { Value } from '@sinclair/typebox/value' ``` ### Assert Use the Assert function to assert a value is valid. ```typescript let value: unknown = 1 Value.Assert(Type.Number(), value) // throws AssertError if invalid ``` ### Create Use the Create function to create a value from a type. TypeBox will use default values if specified. ```typescript const T = Type.Object({ x: Type.Number(), y: Type.Number({ default: 42 }) }) const A = Value.Create(T) // const A = { x: 0, y: 42 } ``` ### Clone Use the Clone function to deeply clone a value. ```typescript const A = Value.Clone({ x: 1, y: 2, z: 3 }) // const A = { x: 1, y: 2, z: 3 } ``` ### Check Use the Check function to type check a value. ```typescript const T = Type.Object({ x: Type.Number() }) const R = Value.Check(T, { x: 1 }) // const R = true ``` ### Convert Use the Convert function to convert a value into its target type if a reasonable conversion is possible. This function may return an invalid value and should be checked before use. Its return type is `unknown`. ```typescript const T = Type.Object({ x: Type.Number() }) const R1 = Value.Convert(T, { x: '3.14' }) // const R1 = { x: 3.14 } const R2 = Value.Convert(T, { x: 'not a number' }) // const R2 = { x: 'not a number' } ``` ### Clean Use Clean to remove excess properties from a value. This function does not check the value and returns an unknown type. You should Check the result before use. Clean is a mutable operation. To avoid mutation, Clone the value first. ```typescript const T = Type.Object({ x: Type.Number(), y: Type.Number() }) const X = Value.Clean(T, null) // const 'X = null const Y = Value.Clean(T, { x: 1 }) // const 'Y = { x: 1 } const Z = Value.Clean(T, { x: 1, y: 2, z: 3 }) // const 'Z = { x: 1, y: 2 } ``` ### Default Use Default to generate missing properties on a value using default schema annotations if available. This function does not check the value and returns an unknown type. You should Check the result before use. Default is a mutable operation. To avoid mutation, Clone the value first. ```typescript const T = Type.Object({ x: Type.Number({ default: 0 }), y: Type.Number({ default: 0 }) }) const X = Value.Default(T, null) // const 'X = null - non-enumerable const Y = Value.Default(T, { }) // const 'Y = { x: 0, y: 0 } const Z = Value.Default(T, { x: 1 }) // const 'Z = { x: 1, y: 0 } ``` ### Cast Use the Cast function to upcast a value into a target type. This function will retain as much information as possible from the original value. The Cast function is intended to be used in data migration scenarios where existing values need to be upgraded to match a modified type. ```typescript const T = Type.Object({ x: Type.Number(), y: Type.Number() }, { additionalProperties: false }) const X = Value.Cast(T, null) // const X = { x: 0, y: 0 } const Y = Value.Cast(T, { x: 1 }) // const Y = { x: 1, y: 0 } const Z = Value.Cast(T, { x: 1, y: 2, z: 3 }) // const Z = { x: 1, y: 2 } ``` ### Decode Use the Decode function to decode a value from a type or throw if the value is invalid. The return value will infer as the decoded type. This function will run Transform codecs if available. ```typescript const A = Value.Decode(Type.String(), 'hello') // const A = 'hello' const B = Value.Decode(Type.String(), 42) // throw ``` ### Encode Use the Encode function to encode a value to a type or throw if the value is invalid. The return value will infer as the encoded type. This function will run Transform codecs if available. ```typescript const A = Value.Encode(Type.String(), 'hello') // const A = 'hello' const B = Value.Encode(Type.String(), 42) // throw ``` ### Parse Use the Parse function to parse a value. This function calls the `Clone` `Clean`, `Default`, `Convert`, `Assert` and `Decode` Value functions in this exact order to process a value. ```typescript const R = Value.Parse(Type.String(), 'hello') // const R: string = "hello" const E = Value.Parse(Type.String(), undefined) // throws AssertError ``` You can override the order in which functions are run, or omit functions entirely using the following. ```typescript // Runs no functions. const R = Value.Parse([], Type.String(), 12345) // Runs the Assert() function. const E = Value.Parse(['Assert'], Type.String(), 12345) // Runs the Convert() function followed by the Assert() function. const S = Value.Parse(['Convert', 'Assert'], Type.String(), 12345) ``` ### Equal Use the Equal function to deeply check for value equality. ```typescript const R = Value.Equal( // const R = true { x: 1, y: 2, z: 3 }, { x: 1, y: 2, z: 3 } ) ``` ### Hash Use the Hash function to create a [FNV1A-64](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function) non-cryptographic hash of a value. ```typescript const A = Value.Hash({ x: 1, y: 2, z: 3 }) // const A = 2910466848807138541n const B = Value.Hash({ x: 1, y: 4, z: 3 }) // const B = 1418369778807423581n ``` ### Diff Use the Diff function to generate a sequence of edits that will transform one value into another. ```typescript const E = Value.Diff( // const E = [ { x: 1, y: 2, z: 3 }, // { type: 'update', path: '/y', value: 4 }, { y: 4, z: 5, w: 6 } // { type: 'update', path: '/z', value: 5 }, ) // { type: 'insert', path: '/w', value: 6 }, // { type: 'delete', path: '/x' } // ] ``` ### Patch Use the Patch function to apply a sequence of edits. ```typescript const A = { x: 1, y: 2 } const B = { x: 3 } const E = Value.Diff(A, B) // const E = [ // { type: 'update', path: '/x', value: 3 }, // { type: 'delete', path: '/y' } // ] const C = Value.Patch(A, E) // const C = { x: 3 } ``` ### Errors Use the Errors function to enumerate validation errors. ```typescript const T = Type.Object({ x: Type.Number(), y: Type.Number() }) const R = [...Value.Errors(T, { x: '42' })] // const R = [{ // schema: { type: 'number' }, // path: '/x', // value: '42', // message: 'Expected number' // }, { // schema: { type: 'number' }, // path: '/y', // value: undefined, // message: 'Expected number' // }] ``` ### Mutate Use the Mutate function to perform a deep mutable value assignment while retaining internal references. ```typescript const Y = { z: 1 } // const Y = { z: 1 } const X = { y: Y } // const X = { y: { z: 1 } } const A = { x: X } // const A = { x: { y: { z: 1 } } } Value.Mutate(A, { x: { y: { z: 2 } } }) // A' = { x: { y: { z: 2 } } } const R0 = A.x.y.z === 2 // const R0 = true const R1 = A.x.y === Y // const R1 = true const R2 = A.x === X // const R2 = true ``` ### Pointer Use ValuePointer to perform mutable updates on existing values using [RFC6901](https://www.rfc-editor.org/rfc/rfc6901) Json Pointers. ```typescript import { ValuePointer } from '@sinclair/typebox/value' const A = { x: 0, y: 0, z: 0 } ValuePointer.Set(A, '/x', 1) // A' = { x: 1, y: 0, z: 0 } ValuePointer.Set(A, '/y', 1) // A' = { x: 1, y: 1, z: 0 } ValuePointer.Set(A, '/z', 1) // A' = { x: 1, y: 1, z: 1 } ``` ## Syntax Types TypeBox provides experimental support for parsing TypeScript annotation syntax into TypeBox types. This feature is provided via optional import. ```typescript import { Syntax } from '@sinclair/typebox/syntax' ``` ### Create Use the Syntax function to create TypeBox types from TypeScript syntax ([Example](https://www.typescriptlang.org/play/?moduleResolution=99&module=199&ts=5.8.0-beta#code/JYWwDg9gTgLgBAbzgZQJ4DsYEMAecC+cAZlBCHAOQACAzsOgMYA2WwUA9DKmAKYBGEHOxoZsOCgChQkWIhTYYwBgWKly1OoxZtO3foMkSGEdDXgAVOAF4Uo3AAoABkhwAuOOgCuIPjygAaOFR3Lx8-AkcASjgY2Jj2djhjUwt3cwB5PgArHgYYAB4ECTiS0rLyisrYhNi3OHMAOW9fAOKq9o7OuBqY4PqmsKg2rpHR+MT8AD4JCS5eeut5LEUGfLmeCCJ6ybHKmvWFmyLdk86euDrQlv9h07uy876rv1v7t-GCIA)) ```typescript const T = Syntax(`{ x: number, y: number }`) // const T: TObject<{ // x: TNumber, // y: TNumber // }> type T = Static // type T = { // x: number, // y: number // } ``` ### Parameters Syntax types can be parameterized to receive exterior types ([Example](https://www.typescriptlang.org/play/?moduleResolution=99&module=199&ts=5.8.0-beta#code/JYWwDg9gTgLgBAbzgZQJ4DsYEMAecC+cAZlBCHAOQACAzsOgMYA2WwUA9DKmAKYBGEHOxoZsOCgCgJDCOhrwAKnAC8KUbgAUAAyQ4AXHHQBXEHx5QANHFQHjp8wS0BKOK7ev27ODLmKDCgHk+ACseBhgAHgQJd1i4+ITEpLdPN304BQA5EzNLGOSCwqK4VNcbDOz7KHzi2rqPL3wAPikfeRQVNUxNJCV8Ky0ABSxYYCwmCIUm52LUtvhkfyDQ8Kia+o2C0rh0wLAYYFlxycrcpot1zav47fK9g6OJrJzzFuv3m8amoA)) ```typescript const T = Syntax(`{ x: number, y: number }`) // const T: TObject<{ // x: TNumber, // y: TNumber // }> const S = Syntax({ T }, `Partial`) // const S: TObject<{ // x: TOptional, // y: TOptional // }> ``` ### Generics Syntax types support generic parameters in the following way ([Example](https://www.typescriptlang.org/play/?moduleResolution=99&module=199&ts=5.8.0-beta#code/JYWwDg9gTgLgBAbzgZQJ4DsYEMAecC+cAZlBCHAOQACAzsOgMYA2WwUA9DKmAKYBGEHOxoZsOCgChQkWIhTYYwBgWKly1OoxZtO3foMkSGEdDXgA1HgxjQ4AXhSjcACgAGAHgAaAGjgBNXwAtAD45CTg4HAAuOB84cLhUGID4iIAvGMD4-FcASgkjEzM4ACEsOhpLa2gae0dMFyQqmygCX1cEBOi4Zuh3AEZfAAZh4O8EpJ6rFvcRuEG4IbGEjKnqqFnh337lnPyJLl5S8uBK6Zq65AUld0OeCCJjit6oGlCIiPZ2ODun05fag5Oh8QaCweCIZCoV8Pt0kN0FpM5qshm0ElCMZisSCYRFJvCYnNJgsUWjseSKeDcXBVgTFr4kb5Vv0COjKezsTD8EA)) ```typescript const Vector = Syntax(` { x: X, y: Y, z: Z }`) const BasisVectors = Syntax({ Vector }, `{ x: Vector<1, 0, 0>, y: Vector<0, 1, 0>, z: Vector<0, 0, 1>, }`) type BasisVectors = Static // type BasisVectors = { // x: { x: 1, y: 0, z: 0 }, // y: { x: 0, y: 1, z: 0 }, // z: { x: 0, y: 0, z: 1 } // } ``` ### Options Options can be passed via the last parameter. ```typescript const T = Syntax(`number`, { minimum: 42 }) // const T = { // type: 'number', // minimum: 42 // } ``` ### NoInfer Syntax parsing is an expensive type level operation and can impact on language service performance. Use the NoInfer function parse syntax at runtime only. ```typescript import { NoInfer } from '@sinclair/typebox/syntax' const T = NoInfer(`number | string`) // const T: TSchema = { // anyOf: [ // { type: 'number' }, // { type: 'string' } // ] // } ``` ## TypeRegistry The TypeBox type system can be extended with additional types and formats using the TypeRegistry and FormatRegistry modules. These modules integrate deeply with TypeBox's internal type checking infrastructure and can be used to create application specific types, or register schematics for alternative specifications. ### TypeRegistry Use the TypeRegistry to register a type. The Kind must match the registered type name. ```typescript import { TSchema, Kind, TypeRegistry } from '@sinclair/typebox' TypeRegistry.Set('Foo', (schema, value) => value === 'foo') const Foo = { [Kind]: 'Foo' } as TSchema const A = Value.Check(Foo, 'foo') // const A = true const B = Value.Check(Foo, 'bar') // const B = false ``` ### FormatRegistry Use the FormatRegistry to register a string format. ```typescript import { FormatRegistry } from '@sinclair/typebox' FormatRegistry.Set('foo', (value) => value === 'foo') const T = Type.String({ format: 'foo' }) const A = Value.Check(T, 'foo') // const A = true const B = Value.Check(T, 'bar') // const B = false ``` ## TypeCheck TypeBox types target Json Schema Draft 7 and are compatible with any validator that supports this specification. TypeBox also provides a built-in type checking compiler designed specifically for TypeBox types that offers high performance compilation and value checking. The following sections detail using Ajv and the TypeBox compiler infrastructure. ## Ajv The following shows the recommended setup for Ajv. ```bash $ npm install ajv ajv-formats --save ``` ```typescript import { Type } from '@sinclair/typebox' import addFormats from 'ajv-formats' import Ajv from 'ajv' const ajv = addFormats(new Ajv({}), [ 'date-time', 'time', 'date', 'email', 'hostname', 'ipv4', 'ipv6', 'uri', 'uri-reference', 'uuid', 'uri-template', 'json-pointer', 'relative-json-pointer', 'regex' ]) const validate = ajv.compile(Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number() })) const R = validate({ x: 1, y: 2, z: 3 }) // const R = true ``` ### TypeCompiler The TypeBox TypeCompiler is a high performance JIT validation compiler that transforms TypeBox types into optimized JavaScript validation routines. The compiler is tuned for fast compilation as well as fast value assertion. It is built to serve as a validation backend that can be integrated into larger applications. It can also be used for code generation. The TypeCompiler is provided as an optional import. ```typescript import { TypeCompiler } from '@sinclair/typebox/compiler' ``` Use the Compile function to JIT compile a type. Note that compilation is generally an expensive operation and should only be performed once per type during application start up. TypeBox does not cache previously compiled types, and applications are expected to hold references to each compiled type for the lifetime of the application. ```typescript const C = TypeCompiler.Compile(Type.Object({ // const C: TypeCheck> const R = C.Check({ x: 1, y: 2, z: 3 }) // const R = true ``` Use the Errors function to generate diagnostic errors for a value. The Errors function will return an iterator that when enumerated; will perform an exhaustive check across the entire value yielding any error found. For performance, this function should only be called after a failed Check. Applications may also choose to yield only the first value to avoid exhaustive error generation. ```typescript const C = TypeCompiler.Compile(Type.Object({ // const C: TypeCheck> const value = { } const first = C.Errors(value).First() // const first = { // schema: { type: 'number' }, // path: '/x', // value: undefined, // message: 'Expected number' // } const all = [...C.Errors(value)] // const all = [{ // schema: { type: 'number' }, // path: '/x', // value: undefined, // message: 'Expected number' // }, { // schema: { type: 'number' }, // path: '/y', // value: undefined, // message: 'Expected number' // }, { // schema: { type: 'number' }, // path: '/z', // value: undefined, // message: 'Expected number' // }] ``` Use the Code function to generate assertion functions as strings. This function can be used to generate code that can be written to disk as importable modules. This technique is sometimes referred to as Ahead of Time (AOT) compilation. The following generates code to check a string. ```typescript const C = TypeCompiler.Code(Type.String()) // const C = `return function check(value) { // return ( // (typeof value === 'string') // ) // }` ``` ## TypeMap TypeBox offers an external package for bidirectional mapping between TypeBox, Valibot, and Zod type libraries. It also includes syntax parsing support for Valibot and Zod and supports the Standard Schema specification. For more details on TypeMap, refer to the project repository. [TypeMap Repository](https://github.com/sinclairzx81/typemap) ### Usage TypeMap needs to be installed separately ```bash $ npm install @sinclair/typemap ``` Once installed it offers advanced structural remapping between various runtime type libraries ([Example](https://www.typescriptlang.org/play/?moduleResolution=99&module=199&ts=5.8.0-beta#code/JYWwDg9gTgLgBAbzgFQJ5gKYCEIA8A0cAyqgHYwCGBcAWhACZwC+cAZlBCHAOQACAzsFIBjADYVgUAPQx0GEBTDcAUMuERS-eMjgBeFHJy4AFAAMkuAFxxSAVxAAjDFEKprdx88IAvd-adQzKYAlHBwUlJw6pra1sgA8g4AVhjCMAA8CMphObl5+QWFRcW5ETlWKABy-s4A3NkljU3NBWVhblU1UPUtvX3FbXC+nZ7dDf0TE2VMAHyq0VrEesRklCbIoS1lC-BE1twWfqOuRwE+p87MKmoaiwBKy3T0xkTBAHRgFFD8GMZ2oqJNnltrd4HdrFlJltImEKh4Aj0oU1Bh14XVxkiBjChhcxpjGtMwkA)) ```typescript import { TypeBox, Syntax, Zod } from '@sinclair/typemap' const T = TypeBox(`{ x: number, y: number, z: number }`) // const T: TObject<{ // x: TNumber; // y: TNumber; // z: TNumber; // }> const S = Syntax(T) // const S: '{ x: number, y: number, z: number }' const R = Zod(S).parse(null) // const R: { // x: number; // y: number; // z: number; // } ``` ## TypeSystem The TypeBox TypeSystem module provides configurations to use either Json Schema or TypeScript type checking semantics. Configurations made to the TypeSystem module are observed by the TypeCompiler, Value and Error modules. ### Policies TypeBox validates using standard Json Schema assertion policies by default. The TypeSystemPolicy module can override some of these to have TypeBox assert values inline with TypeScript static checks. It also provides overrides for certain checking rules related to non-serializable values (such as void) which can be helpful in Json based protocols such as Json Rpc 2.0. The following overrides are available. ```typescript import { TypeSystemPolicy } from '@sinclair/typebox/system' // Disallow undefined values for optional properties (default is false) // // const A: { x?: number } = { x: undefined } - disallowed when enabled TypeSystemPolicy.ExactOptionalPropertyTypes = true // Allow arrays to validate as object types (default is false) // // const A: {} = [] - allowed in TS TypeSystemPolicy.AllowArrayObject = true // Allow numeric values to be NaN or + or - Infinity (default is false) // // const A: number = NaN - allowed in TS TypeSystemPolicy.AllowNaN = true // Allow void types to check with undefined and null (default is false) // // Used to signal void return on Json-Rpc 2.0 protocol TypeSystemPolicy.AllowNullVoid = true ``` ## Error Function Error messages in TypeBox can be customized by defining an ErrorFunction. This function allows for the localization of error messages as well as enabling custom error messages for custom types. By default, TypeBox will generate messages using the `en-US` locale. To support additional locales, you can replicate the function found in `src/errors/function.ts` and create a locale specific translation. The function can then be set via SetErrorFunction. The following example shows an inline error function that intercepts errors for String, Number and Boolean only. The DefaultErrorFunction is used to return a default error message. ```typescript import { SetErrorFunction, DefaultErrorFunction, ValueErrorType } from '@sinclair/typebox/errors' SetErrorFunction((error) => { // i18n override switch(error.errorType) { /* en-US */ case ValueErrorType.String: return 'Expected string' /* fr-FR */ case ValueErrorType.Number: return 'Nombre attendu' /* ko-KR */ case ValueErrorType.Boolean: return '예� 부울' /* en-US */ default: return DefaultErrorFunction(error) } }) const T = Type.Object({ // const T: TObject<{ x: Type.String(), // TString, y: Type.Number(), // TNumber, z: Type.Boolean() // TBoolean }) // }> const E = [...Value.Errors(T, { // const E = [{ x: null, // type: 48, y: null, // schema: { ... }, z: null // path: '/x', })] // value: null, // message: 'Expected string' // }, { // type: 34, // schema: { ... }, // path: '/y', // value: null, // message: 'Nombre attendu' // }, { // type: 14, // schema: { ... }, // path: '/z', // value: null, // message: '예� 부울' // }] ``` ## TypeBox Workbench TypeBox offers a web based code generation tool that can convert TypeScript types into TypeBox types as well as several other ecosystem libraries. [TypeBox Workbench Link Here](https://sinclairzx81.github.io/typebox-workbench/) ## TypeBox Codegen TypeBox provides a code generation library that can be integrated into toolchains to automate type translation between TypeScript and TypeBox. This library also includes functionality to transform TypeScript types to other ecosystem libraries. [TypeBox Codegen Link Here](https://github.com/sinclairzx81/typebox-codegen) ## Ecosystem The following is a list of community packages that offer general tooling, extended functionality and framework integration support for TypeBox. | Package | Description | | ------------- | ------------- | | [drizzle-typebox](https://www.npmjs.com/package/drizzle-typebox) | Generates TypeBox types from Drizzle ORM schemas | | [elysia](https://github.com/elysiajs/elysia) | Fast and friendly Bun web framework | | [fastify-type-provider-typebox](https://github.com/fastify/fastify-type-provider-typebox) | Fastify TypeBox integration with the Fastify Type Provider | | [feathersjs](https://github.com/feathersjs/feathers) | The API and real-time application framework | | [fetch-typebox](https://github.com/erfanium/fetch-typebox) | Drop-in replacement for fetch that brings easy integration with TypeBox | | [@lonli-lokli/fetcher-typebox](https://github.com/Lonli-Lokli/fetcher-ts/tree/master/packages/fetcher-typebox) | A strongly-typed fetch wrapper for TypeScript applications with optional runtime validation using TypeBox | | [h3-typebox](https://github.com/kevinmarrec/h3-typebox) | Schema validation utilities for h3 using TypeBox & Ajv | | [http-wizard](https://github.com/flodlc/http-wizard) | Type safe http client library for Fastify | | [json2typebox](https://github.com/hacxy/json2typebox) | Creating TypeBox code from Json Data | | [nominal-typebox](https://github.com/Coder-Spirit/nominal/tree/main/%40coderspirit/nominal-typebox) | Allows devs to integrate nominal types into TypeBox schemas | | [openapi-box](https://github.com/geut/openapi-box) | Generate TypeBox types from OpenApi IDL + Http client library | | [prismabox](https://github.com/m1212e/prismabox) | Converts a prisma.schema to TypeBox schema matching the database models | | [schema2typebox](https://github.com/xddq/schema2typebox) | Creating TypeBox code from Json Schemas | | [sveltekit-superforms](https://github.com/ciscoheat/sveltekit-superforms) | A comprehensive SvelteKit form library for server and client validation | | [ts2typebox](https://github.com/xddq/ts2typebox) | Creating TypeBox code from Typescript types | | [typebox-cli](https://github.com/gsuess/typebox-cli) | Generate Schema with TypeBox from the CLI | | [typebox-form-parser](https://github.com/jtlapp/typebox-form-parser) | Parses form and query data based on TypeBox schemas | | [typebox-schema-faker](https://github.com/iam-medvedev/typebox-schema-faker) | Generate fake data from TypeBox schemas for testing, prototyping and development | ## Benchmark This project maintains a set of benchmarks that measure Ajv, Value and TypeCompiler compilation and validation performance. These benchmarks can be run locally by cloning this repository and running `npm run benchmark`. The results below show for Ajv version 8.12.0 running on Node 20.10.0. For additional comparative benchmarks, please refer to [typescript-runtime-type-benchmarks](https://moltar.github.io/typescript-runtime-type-benchmarks/). ### Compile This benchmark measures compilation performance for varying types. ```typescript ┌────────────────────────────┬────────────┬──────────────┬──────────────┬──────────────� │ (index) │ Iterations │ Ajv │ TypeCompiler │ Performance │ ├────────────────────────────┼────────────┼──────────────┼──────────────┼──────────────┤ │ Literal_String │ 1000 │ ' 211 ms' │ ' 8 ms' │ ' 26.38 x' │ │ Literal_Number │ 1000 │ ' 185 ms' │ ' 5 ms' │ ' 37.00 x' │ │ Literal_Boolean │ 1000 │ ' 195 ms' │ ' 4 ms' │ ' 48.75 x' │ │ Primitive_Number │ 1000 │ ' 149 ms' │ ' 7 ms' │ ' 21.29 x' │ │ Primitive_String │ 1000 │ ' 135 ms' │ ' 5 ms' │ ' 27.00 x' │ │ Primitive_String_Pattern │ 1000 │ ' 193 ms' │ ' 10 ms' │ ' 19.30 x' │ │ Primitive_Boolean │ 1000 │ ' 152 ms' │ ' 4 ms' │ ' 38.00 x' │ │ Primitive_Null │ 1000 │ ' 147 ms' │ ' 4 ms' │ ' 36.75 x' │ │ Object_Unconstrained │ 1000 │ ' 1065 ms' │ ' 26 ms' │ ' 40.96 x' │ │ Object_Constrained │ 1000 │ ' 1183 ms' │ ' 26 ms' │ ' 45.50 x' │ │ Object_Vector3 │ 1000 │ ' 407 ms' │ ' 9 ms' │ ' 45.22 x' │ │ Object_Box3D │ 1000 │ ' 1777 ms' │ ' 24 ms' │ ' 74.04 x' │ │ Tuple_Primitive │ 1000 │ ' 485 ms' │ ' 11 ms' │ ' 44.09 x' │ │ Tuple_Object │ 1000 │ ' 1344 ms' │ ' 17 ms' │ ' 79.06 x' │ │ Composite_Intersect │ 1000 │ ' 606 ms' │ ' 14 ms' │ ' 43.29 x' │ │ Composite_Union │ 1000 │ ' 522 ms' │ ' 17 ms' │ ' 30.71 x' │ │ Math_Vector4 │ 1000 │ ' 851 ms' │ ' 9 ms' │ ' 94.56 x' │ │ Math_Matrix4 │ 1000 │ ' 406 ms' │ ' 10 ms' │ ' 40.60 x' │ │ Array_Primitive_Number │ 1000 │ ' 367 ms' │ ' 6 ms' │ ' 61.17 x' │ │ Array_Primitive_String │ 1000 │ ' 339 ms' │ ' 7 ms' │ ' 48.43 x' │ │ Array_Primitive_Boolean │ 1000 │ ' 325 ms' │ ' 5 ms' │ ' 65.00 x' │ │ Array_Object_Unconstrained │ 1000 │ ' 1863 ms' │ ' 21 ms' │ ' 88.71 x' │ │ Array_Object_Constrained │ 1000 │ ' 1535 ms' │ ' 18 ms' │ ' 85.28 x' │ │ Array_Tuple_Primitive │ 1000 │ ' 829 ms' │ ' 14 ms' │ ' 59.21 x' │ │ Array_Tuple_Object │ 1000 │ ' 1674 ms' │ ' 14 ms' │ ' 119.57 x' │ │ Array_Composite_Intersect │ 1000 │ ' 789 ms' │ ' 13 ms' │ ' 60.69 x' │ │ Array_Composite_Union │ 1000 │ ' 822 ms' │ ' 15 ms' │ ' 54.80 x' │ │ Array_Math_Vector4 │ 1000 │ ' 1129 ms' │ ' 14 ms' │ ' 80.64 x' │ │ Array_Math_Matrix4 │ 1000 │ ' 673 ms' │ ' 9 ms' │ ' 74.78 x' │ └────────────────────────────┴────────────┴──────────────┴──────────────┴──────────────┘ ``` ### Validate This benchmark measures validation performance for varying types. ```typescript ┌────────────────────────────┬────────────┬──────────────┬──────────────┬──────────────┬──────────────� │ (index) │ Iterations │ ValueCheck │ Ajv │ TypeCompiler │ Performance │ ├────────────────────────────┼────────────┼──────────────┼──────────────┼──────────────┼──────────────┤ │ Literal_String │ 1000000 │ ' 17 ms' │ ' 5 ms' │ ' 5 ms' │ ' 1.00 x' │ │ Literal_Number │ 1000000 │ ' 14 ms' │ ' 18 ms' │ ' 9 ms' │ ' 2.00 x' │ │ Literal_Boolean │ 1000000 │ ' 14 ms' │ ' 20 ms' │ ' 9 ms' │ ' 2.22 x' │ │ Primitive_Number │ 1000000 │ ' 17 ms' │ ' 19 ms' │ ' 9 ms' │ ' 2.11 x' │ │ Primitive_String │ 1000000 │ ' 17 ms' │ ' 18 ms' │ ' 10 ms' │ ' 1.80 x' │ │ Primitive_String_Pattern │ 1000000 │ ' 172 ms' │ ' 46 ms' │ ' 41 ms' │ ' 1.12 x' │ │ Primitive_Boolean │ 1000000 │ ' 14 ms' │ ' 19 ms' │ ' 10 ms' │ ' 1.90 x' │ │ Primitive_Null │ 1000000 │ ' 16 ms' │ ' 19 ms' │ ' 9 ms' │ ' 2.11 x' │ │ Object_Unconstrained │ 1000000 │ ' 437 ms' │ ' 28 ms' │ ' 14 ms' │ ' 2.00 x' │ │ Object_Constrained │ 1000000 │ ' 653 ms' │ ' 46 ms' │ ' 37 ms' │ ' 1.24 x' │ │ Object_Vector3 │ 1000000 │ ' 201 ms' │ ' 22 ms' │ ' 12 ms' │ ' 1.83 x' │ │ Object_Box3D │ 1000000 │ ' 961 ms' │ ' 37 ms' │ ' 19 ms' │ ' 1.95 x' │ │ Object_Recursive │ 1000000 │ ' 3715 ms' │ ' 363 ms' │ ' 174 ms' │ ' 2.09 x' │ │ Tuple_Primitive │ 1000000 │ ' 107 ms' │ ' 23 ms' │ ' 11 ms' │ ' 2.09 x' │ │ Tuple_Object │ 1000000 │ ' 375 ms' │ ' 28 ms' │ ' 15 ms' │ ' 1.87 x' │ │ Composite_Intersect │ 1000000 │ ' 377 ms' │ ' 22 ms' │ ' 12 ms' │ ' 1.83 x' │ │ Composite_Union │ 1000000 │ ' 337 ms' │ ' 30 ms' │ ' 17 ms' │ ' 1.76 x' │ │ Math_Vector4 │ 1000000 │ ' 137 ms' │ ' 23 ms' │ ' 11 ms' │ ' 2.09 x' │ │ Math_Matrix4 │ 1000000 │ ' 576 ms' │ ' 37 ms' │ ' 28 ms' │ ' 1.32 x' │ │ Array_Primitive_Number │ 1000000 │ ' 145 ms' │ ' 23 ms' │ ' 12 ms' │ ' 1.92 x' │ │ Array_Primitive_String │ 1000000 │ ' 152 ms' │ ' 22 ms' │ ' 13 ms' │ ' 1.69 x' │ │ Array_Primitive_Boolean │ 1000000 │ ' 131 ms' │ ' 20 ms' │ ' 13 ms' │ ' 1.54 x' │ │ Array_Object_Unconstrained │ 1000000 │ ' 2821 ms' │ ' 62 ms' │ ' 45 ms' │ ' 1.38 x' │ │ Array_Object_Constrained │ 1000000 │ ' 2958 ms' │ ' 119 ms' │ ' 134 ms' │ ' 0.89 x' │ │ Array_Object_Recursive │ 1000000 │ ' 14695 ms' │ ' 1621 ms' │ ' 635 ms' │ ' 2.55 x' │ │ Array_Tuple_Primitive │ 1000000 │ ' 478 ms' │ ' 35 ms' │ ' 28 ms' │ ' 1.25 x' │ │ Array_Tuple_Object │ 1000000 │ ' 1623 ms' │ ' 63 ms' │ ' 48 ms' │ ' 1.31 x' │ │ Array_Composite_Intersect │ 1000000 │ ' 1582 ms' │ ' 43 ms' │ ' 30 ms' │ ' 1.43 x' │ │ Array_Composite_Union │ 1000000 │ ' 1331 ms' │ ' 76 ms' │ ' 40 ms' │ ' 1.90 x' │ │ Array_Math_Vector4 │ 1000000 │ ' 564 ms' │ ' 38 ms' │ ' 24 ms' │ ' 1.58 x' │ │ Array_Math_Matrix4 │ 1000000 │ ' 2382 ms' │ ' 111 ms' │ ' 83 ms' │ ' 1.34 x' │ └────────────────────────────┴────────────┴──────────────┴──────────────┴──────────────┴──────────────┘ ``` ### Compression The following table lists esbuild compiled and minified sizes for each TypeBox module. ```typescript ┌──────────────────────┬────────────┬────────────┬─────────────� │ (index) │ Compiled │ Minified │ Compression │ ├──────────────────────┼────────────┼────────────┼─────────────┤ │ typebox/compiler │ '122.4 kb' │ ' 53.4 kb' │ '2.29 x' │ │ typebox/errors │ ' 67.6 kb' │ ' 29.6 kb' │ '2.28 x' │ │ typebox/syntax │ '132.9 kb' │ ' 54.2 kb' │ '2.45 x' │ │ typebox/system │ ' 7.4 kb' │ ' 3.2 kb' │ '2.33 x' │ │ typebox/value │ '150.1 kb' │ ' 62.2 kb' │ '2.41 x' │ │ typebox │ '106.8 kb' │ ' 43.2 kb' │ '2.47 x' │ └──────────────────────┴────────────┴────────────┴─────────────┘ ``` ## Contribute TypeBox is open to community contribution. Please ensure you submit an open issue before submitting your pull request. The TypeBox project prefers open community discussion before accepting new features. sinclairzx81-typebox-e0ec98c/src/000077500000000000000000000000001505437577000170475ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/compiler/000077500000000000000000000000001505437577000206615ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/compiler/compiler.ts000066400000000000000000001043031505437577000230440ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/compiler The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { TransformEncode, TransformDecode, HasTransform, TransformDecodeCheckError, TransformEncodeCheckError } from '../value/transform/index' import { Errors, ValueErrorIterator } from '../errors/index' import { TypeSystemPolicy } from '../system/index' import { TypeBoxError } from '../type/error/index' import { Deref } from '../value/deref/index' import { Hash } from '../value/hash/index' import { Kind } from '../type/symbols/index' import { TypeRegistry, FormatRegistry } from '../type/registry/index' import { KeyOfPattern } from '../type/keyof/index' import { ExtendsUndefinedCheck } from '../type/extends/extends-undefined' import type { TSchema } from '../type/schema/index' import type { TAsyncIterator } from '../type/async-iterator/index' import type { TAny } from '../type/any/index' import type { TArgument } from '../type/argument/index' import type { TArray } from '../type/array/index' import type { TBigInt } from '../type/bigint/index' import type { TBoolean } from '../type/boolean/index' import type { TDate } from '../type/date/index' import type { TConstructor } from '../type/constructor/index' import type { TFunction } from '../type/function/index' import type { TImport } from '../type/module/index' import type { TInteger } from '../type/integer/index' import type { TIntersect } from '../type/intersect/index' import type { TIterator } from '../type/iterator/index' import type { TLiteral } from '../type/literal/index' import { Never, type TNever } from '../type/never/index' import type { TNot } from '../type/not/index' import type { TNull } from '../type/null/index' import type { TNumber } from '../type/number/index' import type { TObject } from '../type/object/index' import type { TPromise } from '../type/promise/index' import type { TRecord } from '../type/record/index' import { Ref, type TRef } from '../type/ref/index' import type { TRegExp } from '../type/regexp/index' import type { TTemplateLiteral } from '../type/template-literal/index' import type { TThis } from '../type/recursive/index' import type { TTuple } from '../type/tuple/index' import type { TUnion } from '../type/union/index' import type { TUnknown } from '../type/unknown/index' import type { Static, StaticDecode, StaticEncode } from '../type/static/index' import type { TString } from '../type/string/index' import type { TSymbol } from '../type/symbol/index' import type { TUndefined } from '../type/undefined/index' import type { TUint8Array } from '../type/uint8array/index' import type { TVoid } from '../type/void/index' // ------------------------------------------------------------------ // ValueGuard // ------------------------------------------------------------------ import { IsArray, IsString, IsNumber, IsBigInt } from '../value/guard/index' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsSchema } from '../type/guard/type' // ------------------------------------------------------------------ // CheckFunction // ------------------------------------------------------------------ export type CheckFunction = (value: unknown) => boolean // ------------------------------------------------------------------ // TypeCheck // ------------------------------------------------------------------ export class TypeCheck { private readonly hasTransform: boolean constructor(private readonly schema: T, private readonly references: TSchema[], private readonly checkFunc: CheckFunction, private readonly code: string) { this.hasTransform = HasTransform(schema, references) } /** Returns the generated assertion code used to validate this type. */ public Code(): string { return this.code } /** Returns the schema type used to validate */ public Schema(): T { return this.schema } /** Returns reference types used to validate */ public References(): TSchema[] { return this.references } /** Returns an iterator for each error in this value. */ public Errors(value: unknown): ValueErrorIterator { return Errors(this.schema, this.references, value) } /** Returns true if the value matches the compiled type. */ public Check(value: unknown): value is Static { return this.checkFunc(value) } /** Decodes a value or throws if error */ public Decode, Result extends Static = Static>(value: unknown): Result { if (!this.checkFunc(value)) throw new TransformDecodeCheckError(this.schema, value, this.Errors(value).First()!) return (this.hasTransform ? TransformDecode(this.schema, this.references, value) : value) as never } /** Encodes a value or throws if error */ public Encode, Result extends Static = Static>(value: unknown): Result { const encoded = this.hasTransform ? TransformEncode(this.schema, this.references, value) : value if (!this.checkFunc(encoded)) throw new TransformEncodeCheckError(this.schema, value, this.Errors(value).First()!) return encoded as never } } // ------------------------------------------------------------------ // Character // ------------------------------------------------------------------ namespace Character { export function DollarSign(code: number) { return code === 36 } export function IsUnderscore(code: number) { return code === 95 } export function IsAlpha(code: number) { return (code >= 65 && code <= 90) || (code >= 97 && code <= 122) } export function IsNumeric(code: number) { return code >= 48 && code <= 57 } } // ------------------------------------------------------------------ // MemberExpression // ------------------------------------------------------------------ namespace MemberExpression { function IsFirstCharacterNumeric(value: string) { if (value.length === 0) return false return Character.IsNumeric(value.charCodeAt(0)) } function IsAccessor(value: string) { if (IsFirstCharacterNumeric(value)) return false for (let i = 0; i < value.length; i++) { const code = value.charCodeAt(i) const check = Character.IsAlpha(code) || Character.IsNumeric(code) || Character.DollarSign(code) || Character.IsUnderscore(code) if (!check) return false } return true } function EscapeHyphen(key: string) { return key.replace(/'/g, "\\'") } export function Encode(object: string, key: string) { return IsAccessor(key) ? `${object}.${key}` : `${object}['${EscapeHyphen(key)}']` } } // ------------------------------------------------------------------ // Identifier // ------------------------------------------------------------------ namespace Identifier { export function Encode($id: string) { const buffer: string[] = [] for (let i = 0; i < $id.length; i++) { const code = $id.charCodeAt(i) if (Character.IsNumeric(code) || Character.IsAlpha(code)) { buffer.push($id.charAt(i)) } else { buffer.push(`_${code}_`) } } return buffer.join('').replace(/__/g, '_') } } // ------------------------------------------------------------------ // LiteralString // ------------------------------------------------------------------ namespace LiteralString { export function Escape(content: string) { return content.replace(/'/g, "\\'") } } // ------------------------------------------------------------------ // Errors // ------------------------------------------------------------------ export class TypeCompilerUnknownTypeError extends TypeBoxError { constructor(public readonly schema: TSchema) { super('Unknown type') } } export class TypeCompilerTypeGuardError extends TypeBoxError { constructor(public readonly schema: TSchema) { super('Preflight validation check failed to guard for the given schema') } } // ------------------------------------------------------------------ // Policy // ------------------------------------------------------------------ export namespace Policy { export function IsExactOptionalProperty(value: string, key: string, expression: string) { return TypeSystemPolicy.ExactOptionalPropertyTypes ? `('${key}' in ${value} ? ${expression} : true)` : `(${MemberExpression.Encode(value, key)} !== undefined ? ${expression} : true)` } export function IsObjectLike(value: string): string { return !TypeSystemPolicy.AllowArrayObject ? `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}))` : `(typeof ${value} === 'object' && ${value} !== null)` } export function IsRecordLike(value: string): string { return !TypeSystemPolicy.AllowArrayObject ? `(typeof ${value} === 'object' && ${value} !== null && !Array.isArray(${value}) && !(${value} instanceof Date) && !(${value} instanceof Uint8Array))` : `(typeof ${value} === 'object' && ${value} !== null && !(${value} instanceof Date) && !(${value} instanceof Uint8Array))` } export function IsNumberLike(value: string): string { return TypeSystemPolicy.AllowNaN ? `typeof ${value} === 'number'` : `Number.isFinite(${value})` } export function IsVoidLike(value: string): string { return TypeSystemPolicy.AllowNullVoid ? `(${value} === undefined || ${value} === null)` : `${value} === undefined` } } // ------------------------------------------------------------------ // TypeCompiler // ------------------------------------------------------------------ export type TypeCompilerLanguageOption = 'typescript' | 'javascript' export interface TypeCompilerCodegenOptions { language?: TypeCompilerLanguageOption } /** Compiles Types for Runtime Type Checking */ export namespace TypeCompiler { // ---------------------------------------------------------------- // Guards // ---------------------------------------------------------------- function IsAnyOrUnknown(schema: TSchema) { return schema[Kind] === 'Any' || schema[Kind] === 'Unknown' } // ---------------------------------------------------------------- // Types // ---------------------------------------------------------------- function* FromAny(schema: TAny, references: TSchema[], value: string): IterableIterator { yield 'true' } function* FromArgument(schema: TArgument, references: TSchema[], value: string): IterableIterator { yield 'true' } function* FromArray(schema: TArray, references: TSchema[], value: string): IterableIterator { yield `Array.isArray(${value})` const [parameter, accumulator] = [CreateParameter('value', 'any'), CreateParameter('acc', 'number')] if (IsNumber(schema.maxItems)) yield `${value}.length <= ${schema.maxItems}` if (IsNumber(schema.minItems)) yield `${value}.length >= ${schema.minItems}` const elementExpression = CreateExpression(schema.items, references, 'value') yield `${value}.every((${parameter}) => ${elementExpression})` if (IsSchema(schema.contains) || IsNumber(schema.minContains) || IsNumber(schema.maxContains)) { const containsSchema = IsSchema(schema.contains) ? schema.contains : Never() const checkExpression = CreateExpression(containsSchema, references, 'value') const checkMinContains = IsNumber(schema.minContains) ? [`(count >= ${schema.minContains})`] : [] const checkMaxContains = IsNumber(schema.maxContains) ? [`(count <= ${schema.maxContains})`] : [] const checkCount = `const count = value.reduce((${accumulator}, ${parameter}) => ${checkExpression} ? acc + 1 : acc, 0)` const check = [`(count > 0)`, ...checkMinContains, ...checkMaxContains].join(' && ') yield `((${parameter}) => { ${checkCount}; return ${check}})(${value})` } if (schema.uniqueItems === true) { const check = `const hashed = hash(element); if(set.has(hashed)) { return false } else { set.add(hashed) } } return true` const block = `const set = new Set(); for(const element of value) { ${check} }` yield `((${parameter}) => { ${block} )(${value})` } } function* FromAsyncIterator(schema: TAsyncIterator, references: TSchema[], value: string): IterableIterator { yield `(typeof value === 'object' && Symbol.asyncIterator in ${value})` } function* FromBigInt(schema: TBigInt, references: TSchema[], value: string): IterableIterator { yield `(typeof ${value} === 'bigint')` if (IsBigInt(schema.exclusiveMaximum)) yield `${value} < BigInt(${schema.exclusiveMaximum})` if (IsBigInt(schema.exclusiveMinimum)) yield `${value} > BigInt(${schema.exclusiveMinimum})` if (IsBigInt(schema.maximum)) yield `${value} <= BigInt(${schema.maximum})` if (IsBigInt(schema.minimum)) yield `${value} >= BigInt(${schema.minimum})` if (IsBigInt(schema.multipleOf)) yield `(${value} % BigInt(${schema.multipleOf})) === 0` } function* FromBoolean(schema: TBoolean, references: TSchema[], value: string): IterableIterator { yield `(typeof ${value} === 'boolean')` } function* FromConstructor(schema: TConstructor, references: TSchema[], value: string): IterableIterator { yield* Visit(schema.returns, references, `${value}.prototype`) } function* FromDate(schema: TDate, references: TSchema[], value: string): IterableIterator { yield `(${value} instanceof Date) && Number.isFinite(${value}.getTime())` if (IsNumber(schema.exclusiveMaximumTimestamp)) yield `${value}.getTime() < ${schema.exclusiveMaximumTimestamp}` if (IsNumber(schema.exclusiveMinimumTimestamp)) yield `${value}.getTime() > ${schema.exclusiveMinimumTimestamp}` if (IsNumber(schema.maximumTimestamp)) yield `${value}.getTime() <= ${schema.maximumTimestamp}` if (IsNumber(schema.minimumTimestamp)) yield `${value}.getTime() >= ${schema.minimumTimestamp}` if (IsNumber(schema.multipleOfTimestamp)) yield `(${value}.getTime() % ${schema.multipleOfTimestamp}) === 0` } function* FromFunction(schema: TFunction, references: TSchema[], value: string): IterableIterator { yield `(typeof ${value} === 'function')` } function* FromImport(schema: TImport, references: TSchema[], value: string): IterableIterator { const members = globalThis.Object.getOwnPropertyNames(schema.$defs).reduce((result, key) => { return [...result, schema.$defs[key as never] as TSchema] }, [] as TSchema[]) yield* Visit(Ref(schema.$ref), [...references, ...members], value) } function* FromInteger(schema: TInteger, references: TSchema[], value: string): IterableIterator { yield `Number.isInteger(${value})` if (IsNumber(schema.exclusiveMaximum)) yield `${value} < ${schema.exclusiveMaximum}` if (IsNumber(schema.exclusiveMinimum)) yield `${value} > ${schema.exclusiveMinimum}` if (IsNumber(schema.maximum)) yield `${value} <= ${schema.maximum}` if (IsNumber(schema.minimum)) yield `${value} >= ${schema.minimum}` if (IsNumber(schema.multipleOf)) yield `(${value} % ${schema.multipleOf}) === 0` } function* FromIntersect(schema: TIntersect, references: TSchema[], value: string): IterableIterator { const check1 = schema.allOf.map((schema: TSchema) => CreateExpression(schema, references, value)).join(' && ') if (schema.unevaluatedProperties === false) { const keyCheck = CreateVariable(`${new RegExp(KeyOfPattern(schema))};`) const check2 = `Object.getOwnPropertyNames(${value}).every(key => ${keyCheck}.test(key))` yield `(${check1} && ${check2})` } else if (IsSchema(schema.unevaluatedProperties)) { const keyCheck = CreateVariable(`${new RegExp(KeyOfPattern(schema))};`) const check2 = `Object.getOwnPropertyNames(${value}).every(key => ${keyCheck}.test(key) || ${CreateExpression(schema.unevaluatedProperties, references, `${value}[key]`)})` yield `(${check1} && ${check2})` } else { yield `(${check1})` } } function* FromIterator(schema: TIterator, references: TSchema[], value: string): IterableIterator { yield `(typeof value === 'object' && Symbol.iterator in ${value})` } function* FromLiteral(schema: TLiteral, references: TSchema[], value: string): IterableIterator { if (typeof schema.const === 'number' || typeof schema.const === 'boolean') { yield `(${value} === ${schema.const})` } else { yield `(${value} === '${LiteralString.Escape(schema.const)}')` } } function* FromNever(schema: TNever, references: TSchema[], value: string): IterableIterator { yield `false` } function* FromNot(schema: TNot, references: TSchema[], value: string): IterableIterator { const expression = CreateExpression(schema.not, references, value) yield `(!${expression})` } function* FromNull(schema: TNull, references: TSchema[], value: string): IterableIterator { yield `(${value} === null)` } function* FromNumber(schema: TNumber, references: TSchema[], value: string): IterableIterator { yield Policy.IsNumberLike(value) if (IsNumber(schema.exclusiveMaximum)) yield `${value} < ${schema.exclusiveMaximum}` if (IsNumber(schema.exclusiveMinimum)) yield `${value} > ${schema.exclusiveMinimum}` if (IsNumber(schema.maximum)) yield `${value} <= ${schema.maximum}` if (IsNumber(schema.minimum)) yield `${value} >= ${schema.minimum}` if (IsNumber(schema.multipleOf)) yield `(${value} % ${schema.multipleOf}) === 0` } function* FromObject(schema: TObject, references: TSchema[], value: string): IterableIterator { yield Policy.IsObjectLike(value) if (IsNumber(schema.minProperties)) yield `Object.getOwnPropertyNames(${value}).length >= ${schema.minProperties}` if (IsNumber(schema.maxProperties)) yield `Object.getOwnPropertyNames(${value}).length <= ${schema.maxProperties}` const knownKeys = Object.getOwnPropertyNames(schema.properties) for (const knownKey of knownKeys) { const memberExpression = MemberExpression.Encode(value, knownKey) const property = schema.properties[knownKey] if (schema.required && schema.required.includes(knownKey)) { yield* Visit(property, references, memberExpression) if (ExtendsUndefinedCheck(property) || IsAnyOrUnknown(property)) yield `('${knownKey}' in ${value})` } else { const expression = CreateExpression(property, references, memberExpression) yield Policy.IsExactOptionalProperty(value, knownKey, expression) } } if (schema.additionalProperties === false) { if (schema.required && schema.required.length === knownKeys.length) { yield `Object.getOwnPropertyNames(${value}).length === ${knownKeys.length}` } else { const keys = `[${knownKeys.map((key) => `'${key}'`).join(', ')}]` yield `Object.getOwnPropertyNames(${value}).every(key => ${keys}.includes(key))` } } if (typeof schema.additionalProperties === 'object') { const expression = CreateExpression(schema.additionalProperties, references, `${value}[key]`) const keys = `[${knownKeys.map((key) => `'${key}'`).join(', ')}]` yield `(Object.getOwnPropertyNames(${value}).every(key => ${keys}.includes(key) || ${expression}))` } } function* FromPromise(schema: TPromise, references: TSchema[], value: string): IterableIterator { yield `${value} instanceof Promise` } function* FromRecord(schema: TRecord, references: TSchema[], value: string): IterableIterator { yield Policy.IsRecordLike(value) if (IsNumber(schema.minProperties)) yield `Object.getOwnPropertyNames(${value}).length >= ${schema.minProperties}` if (IsNumber(schema.maxProperties)) yield `Object.getOwnPropertyNames(${value}).length <= ${schema.maxProperties}` const [patternKey, patternSchema] = Object.entries(schema.patternProperties)[0] const variable = CreateVariable(`${new RegExp(patternKey)}`) const check1 = CreateExpression(patternSchema, references, 'value') const check2 = IsSchema(schema.additionalProperties) ? CreateExpression(schema.additionalProperties, references, value) : schema.additionalProperties === false ? 'false' : 'true' const expression = `(${variable}.test(key) ? ${check1} : ${check2})` yield `(Object.entries(${value}).every(([key, value]) => ${expression}))` } function* FromRef(schema: TRef, references: TSchema[], value: string): IterableIterator { const target = Deref(schema, references) // Reference: If we have seen this reference before we can just yield and return the function call. // If this isn't the case we defer to visit to generate and set the function for subsequent passes. if (state.functions.has(schema.$ref)) return yield `${CreateFunctionName(schema.$ref)}(${value})` yield* Visit(target, references, value) } function* FromRegExp(schema: TRegExp, references: TSchema[], value: string): IterableIterator { const variable = CreateVariable(`${new RegExp(schema.source, schema.flags)};`) yield `(typeof ${value} === 'string')` if (IsNumber(schema.maxLength)) yield `${value}.length <= ${schema.maxLength}` if (IsNumber(schema.minLength)) yield `${value}.length >= ${schema.minLength}` yield `${variable}.test(${value})` } function* FromString(schema: TString, references: TSchema[], value: string): IterableIterator { yield `(typeof ${value} === 'string')` if (IsNumber(schema.maxLength)) yield `${value}.length <= ${schema.maxLength}` if (IsNumber(schema.minLength)) yield `${value}.length >= ${schema.minLength}` if (schema.pattern !== undefined) { const variable = CreateVariable(`${new RegExp(schema.pattern)};`) yield `${variable}.test(${value})` } if (schema.format !== undefined) { yield `format('${schema.format}', ${value})` } } function* FromSymbol(schema: TSymbol, references: TSchema[], value: string): IterableIterator { yield `(typeof ${value} === 'symbol')` } function* FromTemplateLiteral(schema: TTemplateLiteral, references: TSchema[], value: string): IterableIterator { yield `(typeof ${value} === 'string')` const variable = CreateVariable(`${new RegExp(schema.pattern)};`) yield `${variable}.test(${value})` } function* FromThis(schema: TThis, references: TSchema[], value: string): IterableIterator { // Note: This types are assured to be hoisted prior to this call. Just yield the function. yield `${CreateFunctionName(schema.$ref)}(${value})` } function* FromTuple(schema: TTuple, references: TSchema[], value: string): IterableIterator { yield `Array.isArray(${value})` if (schema.items === undefined) return yield `${value}.length === 0` yield `(${value}.length === ${schema.maxItems})` for (let i = 0; i < schema.items.length; i++) { const expression = CreateExpression(schema.items[i], references, `${value}[${i}]`) yield `${expression}` } } function* FromUndefined(schema: TUndefined, references: TSchema[], value: string): IterableIterator { yield `${value} === undefined` } function* FromUnion(schema: TUnion, references: TSchema[], value: string): IterableIterator { const expressions = schema.anyOf.map((schema: TSchema) => CreateExpression(schema, references, value)) yield `(${expressions.join(' || ')})` } function* FromUint8Array(schema: TUint8Array, references: TSchema[], value: string): IterableIterator { yield `${value} instanceof Uint8Array` if (IsNumber(schema.maxByteLength)) yield `(${value}.length <= ${schema.maxByteLength})` if (IsNumber(schema.minByteLength)) yield `(${value}.length >= ${schema.minByteLength})` } function* FromUnknown(schema: TUnknown, references: TSchema[], value: string): IterableIterator { yield 'true' } function* FromVoid(schema: TVoid, references: TSchema[], value: string): IterableIterator { yield Policy.IsVoidLike(value) } function* FromKind(schema: TSchema, references: TSchema[], value: string): IterableIterator { const instance = state.instances.size state.instances.set(instance, schema) yield `kind('${schema[Kind]}', ${instance}, ${value})` } function* Visit(schema: TSchema, references: TSchema[], value: string, useHoisting: boolean = true): IterableIterator { const references_ = IsString(schema.$id) ? [...references, schema] : references const schema_ = schema as any // -------------------------------------------------------------- // Hoisting // -------------------------------------------------------------- if (useHoisting && IsString(schema.$id)) { const functionName = CreateFunctionName(schema.$id) if (state.functions.has(functionName)) { return yield `${functionName}(${value})` } else { // Note: In the case of cyclic types, we need to create a 'functions' record // to prevent infinitely re-visiting the CreateFunction. Subsequent attempts // to visit will be caught by the above condition. state.functions.set(functionName, '') const functionCode = CreateFunction(functionName, schema, references, 'value', false) state.functions.set(functionName, functionCode) return yield `${functionName}(${value})` } } switch (schema_[Kind]) { case 'Any': return yield* FromAny(schema_, references_, value) case 'Argument': return yield* FromArgument(schema_, references_, value) case 'Array': return yield* FromArray(schema_, references_, value) case 'AsyncIterator': return yield* FromAsyncIterator(schema_, references_, value) case 'BigInt': return yield* FromBigInt(schema_, references_, value) case 'Boolean': return yield* FromBoolean(schema_, references_, value) case 'Constructor': return yield* FromConstructor(schema_, references_, value) case 'Date': return yield* FromDate(schema_, references_, value) case 'Function': return yield* FromFunction(schema_, references_, value) case 'Import': return yield* FromImport(schema_, references_, value) case 'Integer': return yield* FromInteger(schema_, references_, value) case 'Intersect': return yield* FromIntersect(schema_, references_, value) case 'Iterator': return yield* FromIterator(schema_, references_, value) case 'Literal': return yield* FromLiteral(schema_, references_, value) case 'Never': return yield* FromNever(schema_, references_, value) case 'Not': return yield* FromNot(schema_, references_, value) case 'Null': return yield* FromNull(schema_, references_, value) case 'Number': return yield* FromNumber(schema_, references_, value) case 'Object': return yield* FromObject(schema_, references_, value) case 'Promise': return yield* FromPromise(schema_, references_, value) case 'Record': return yield* FromRecord(schema_, references_, value) case 'Ref': return yield* FromRef(schema_, references_, value) case 'RegExp': return yield* FromRegExp(schema_, references_, value) case 'String': return yield* FromString(schema_, references_, value) case 'Symbol': return yield* FromSymbol(schema_, references_, value) case 'TemplateLiteral': return yield* FromTemplateLiteral(schema_, references_, value) case 'This': return yield* FromThis(schema_, references_, value) case 'Tuple': return yield* FromTuple(schema_, references_, value) case 'Undefined': return yield* FromUndefined(schema_, references_, value) case 'Union': return yield* FromUnion(schema_, references_, value) case 'Uint8Array': return yield* FromUint8Array(schema_, references_, value) case 'Unknown': return yield* FromUnknown(schema_, references_, value) case 'Void': return yield* FromVoid(schema_, references_, value) default: if (!TypeRegistry.Has(schema_[Kind])) throw new TypeCompilerUnknownTypeError(schema) return yield* FromKind(schema_, references_, value) } } // ---------------------------------------------------------------- // Compiler State // ---------------------------------------------------------------- // prettier-ignore const state = { language: 'javascript', // target language functions: new Map(), // local functions variables: new Map(), // local variables instances: new Map() // exterior kind instances } // ---------------------------------------------------------------- // Compiler Factory // ---------------------------------------------------------------- function CreateExpression(schema: TSchema, references: TSchema[], value: string, useHoisting: boolean = true): string { return `(${[...Visit(schema, references, value, useHoisting)].join(' && ')})` } function CreateFunctionName($id: string) { return `check_${Identifier.Encode($id)}` } function CreateVariable(expression: string) { const variableName = `local_${state.variables.size}` state.variables.set(variableName, `const ${variableName} = ${expression}`) return variableName } function CreateFunction(name: string, schema: TSchema, references: TSchema[], value: string, useHoisting: boolean = true): string { const [newline, pad] = ['\n', (length: number) => ''.padStart(length, ' ')] const parameter = CreateParameter('value', 'any') const returns = CreateReturns('boolean') const expression = [...Visit(schema, references, value, useHoisting)].map((expression) => `${pad(4)}${expression}`).join(` &&${newline}`) return `function ${name}(${parameter})${returns} {${newline}${pad(2)}return (${newline}${expression}${newline}${pad(2)})\n}` } function CreateParameter(name: string, type: string) { const annotation = state.language === 'typescript' ? `: ${type}` : '' return `${name}${annotation}` } function CreateReturns(type: string) { return state.language === 'typescript' ? `: ${type}` : '' } // ---------------------------------------------------------------- // Compile // ---------------------------------------------------------------- function Build(schema: T, references: TSchema[], options: TypeCompilerCodegenOptions): string { const functionCode = CreateFunction('check', schema, references, 'value') // will populate functions and variables const parameter = CreateParameter('value', 'any') const returns = CreateReturns('boolean') const functions = [...state.functions.values()] const variables = [...state.variables.values()] // prettier-ignore const checkFunction = IsString(schema.$id) // ensure top level schemas with $id's are hoisted ? `return function check(${parameter})${returns} {\n return ${CreateFunctionName(schema.$id)}(value)\n}` : `return ${functionCode}` return [...variables, ...functions, checkFunction].join('\n') } /** Generates the code used to assert this type and returns it as a string */ export function Code(schema: T, references: TSchema[], options?: TypeCompilerCodegenOptions): string /** Generates the code used to assert this type and returns it as a string */ export function Code(schema: T, options?: TypeCompilerCodegenOptions): string /** Generates the code used to assert this type and returns it as a string */ export function Code(...args: any[]) { const defaults = { language: 'javascript' } // prettier-ignore const [schema, references, options] = ( args.length === 2 && IsArray(args[1]) ? [args[0], args[1], defaults] : args.length === 2 && !IsArray(args[1]) ? [args[0], [], args[1]] : args.length === 3 ? [args[0], args[1], args[2]] : args.length === 1 ? [args[0], [], defaults] : [null, [], defaults] ) // compiler-reset state.language = options.language state.variables.clear() state.functions.clear() state.instances.clear() if (!IsSchema(schema)) throw new TypeCompilerTypeGuardError(schema) for (const schema of references) if (!IsSchema(schema)) throw new TypeCompilerTypeGuardError(schema) return Build(schema, references, options) } /** Compiles a TypeBox type for optimal runtime type checking. Types must be valid TypeBox types of TSchema */ export function Compile(schema: T, references: TSchema[] = []): TypeCheck { const generatedCode = Code(schema, references, { language: 'javascript' }) const compiledFunction = globalThis.Function('kind', 'format', 'hash', generatedCode) const instances = new Map(state.instances) function typeRegistryFunction(kind: string, instance: number, value: unknown) { if (!TypeRegistry.Has(kind) || !instances.has(instance)) return false const checkFunc = TypeRegistry.Get(kind)! const schema = instances.get(instance)! return checkFunc(schema, value) } function formatRegistryFunction(format: string, value: string) { if (!FormatRegistry.Has(format)) return false const checkFunc = FormatRegistry.Get(format)! return checkFunc(value) } function hashFunction(value: unknown) { return Hash(value) } const checkFunction = compiledFunction(typeRegistryFunction, formatRegistryFunction, hashFunction) return new TypeCheck(schema, references, checkFunction, generatedCode) } } sinclairzx81-typebox-e0ec98c/src/compiler/index.ts000066400000000000000000000026131505437577000223420ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/compiler The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export { ValueError, ValueErrorType, ValueErrorIterator } from '../errors/index' export * from './compiler' sinclairzx81-typebox-e0ec98c/src/errors/000077500000000000000000000000001505437577000203635ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/errors/errors.ts000066400000000000000000000725151505437577000222610ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/errors The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { TypeSystemPolicy } from '../system/index' import { KeyOfPattern } from '../type/keyof/index' import { TypeRegistry, FormatRegistry } from '../type/registry/index' import { ExtendsUndefinedCheck } from '../type/extends/extends-undefined' import { GetErrorFunction } from './function' import { TypeBoxError } from '../type/error/index' import { Deref } from '../value/deref/index' import { Hash } from '../value/hash/index' import { Check } from '../value/check/index' import { Kind } from '../type/symbols/index' import type { TSchema } from '../type/schema/index' import type { TAsyncIterator } from '../type/async-iterator/index' import type { TAny } from '../type/any/index' import type { TArray } from '../type/array/index' import type { TBigInt } from '../type/bigint/index' import type { TBoolean } from '../type/boolean/index' import type { TDate } from '../type/date/index' import type { TConstructor } from '../type/constructor/index' import type { TFunction } from '../type/function/index' import type { TImport } from '../type/module/index' import type { TInteger } from '../type/integer/index' import type { TIntersect } from '../type/intersect/index' import type { TIterator } from '../type/iterator/index' import type { TLiteral } from '../type/literal/index' import { Never, type TNever } from '../type/never/index' import type { TNot } from '../type/not/index' import type { TNull } from '../type/null/index' import type { TNumber } from '../type/number/index' import type { TObject } from '../type/object/index' import type { TPromise } from '../type/promise/index' import type { TRecord } from '../type/record/index' import type { TRef } from '../type/ref/index' import type { TRegExp } from '../type/regexp/index' import type { TTemplateLiteral } from '../type/template-literal/index' import type { TThis } from '../type/recursive/index' import type { TTuple } from '../type/tuple/index' import type { TUnion } from '../type/union/index' import type { TUnknown } from '../type/unknown/index' import type { TString } from '../type/string/index' import type { TSymbol } from '../type/symbol/index' import type { TUndefined } from '../type/undefined/index' import type { TUint8Array } from '../type/uint8array/index' import type { TVoid } from '../type/void/index' // ------------------------------------------------------------------ // ValueGuard // ------------------------------------------------------------------ // prettier-ignore import { IsArray, IsUint8Array, IsDate, IsPromise, IsFunction, IsAsyncIterator, IsIterator, IsBoolean, IsNumber, IsBigInt, IsString, IsSymbol, IsInteger, IsNull, IsUndefined } from '../value/guard/index' // ------------------------------------------------------------------ // ValueErrorType // ------------------------------------------------------------------ export enum ValueErrorType { ArrayContains, ArrayMaxContains, ArrayMaxItems, ArrayMinContains, ArrayMinItems, ArrayUniqueItems, Array, AsyncIterator, BigIntExclusiveMaximum, BigIntExclusiveMinimum, BigIntMaximum, BigIntMinimum, BigIntMultipleOf, BigInt, Boolean, DateExclusiveMaximumTimestamp, DateExclusiveMinimumTimestamp, DateMaximumTimestamp, DateMinimumTimestamp, DateMultipleOfTimestamp, Date, Function, IntegerExclusiveMaximum, IntegerExclusiveMinimum, IntegerMaximum, IntegerMinimum, IntegerMultipleOf, Integer, IntersectUnevaluatedProperties, Intersect, Iterator, Kind, Literal, Never, Not, Null, NumberExclusiveMaximum, NumberExclusiveMinimum, NumberMaximum, NumberMinimum, NumberMultipleOf, Number, ObjectAdditionalProperties, ObjectMaxProperties, ObjectMinProperties, ObjectRequiredProperty, Object, Promise, RegExp, StringFormatUnknown, StringFormat, StringMaxLength, StringMinLength, StringPattern, String, Symbol, TupleLength, Tuple, Uint8ArrayMaxByteLength, Uint8ArrayMinByteLength, Uint8Array, Undefined, Union, Void, } // ------------------------------------------------------------------ // ValueError // ------------------------------------------------------------------ export interface ValueError { type: ValueErrorType schema: TSchema path: string value: unknown message: string errors: ValueErrorIterator[] } // ------------------------------------------------------------------ // ValueErrors // ------------------------------------------------------------------ export class ValueErrorsUnknownTypeError extends TypeBoxError { constructor(public readonly schema: TSchema) { super('Unknown type') } } // ------------------------------------------------------------------ // EscapeKey // ------------------------------------------------------------------ function EscapeKey(key: string): string { return key.replace(/~/g, '~0').replace(/\//g, '~1') // RFC6901 Path } // ------------------------------------------------------------------ // Guards // ------------------------------------------------------------------ function IsDefined(value: unknown): value is T { return value !== undefined } // ------------------------------------------------------------------ // ValueErrorIterator // ------------------------------------------------------------------ export class ValueErrorIterator { constructor(private readonly iterator: IterableIterator) {} public [Symbol.iterator]() { return this.iterator } /** Returns the first value error or undefined if no errors */ public First(): ValueError | undefined { const next = this.iterator.next() return next.done ? undefined : next.value } } // -------------------------------------------------------------------------- // Create // -------------------------------------------------------------------------- function Create(errorType: ValueErrorType, schema: TSchema, path: string, value: unknown, errors: ValueErrorIterator[] = []): ValueError { return { type: errorType, schema, path, value, message: GetErrorFunction()({ errorType, path, schema, value, errors }), errors, } } // -------------------------------------------------------------------------- // Types // -------------------------------------------------------------------------- function* FromAny(schema: TAny, references: TSchema[], path: string, value: any): IterableIterator {} function* FromArgument(schema: TAny, references: TSchema[], path: string, value: any): IterableIterator {} function* FromArray(schema: TArray, references: TSchema[], path: string, value: any): IterableIterator { if (!IsArray(value)) { return yield Create(ValueErrorType.Array, schema, path, value) } if (IsDefined(schema.minItems) && !(value.length >= schema.minItems)) { yield Create(ValueErrorType.ArrayMinItems, schema, path, value) } if (IsDefined(schema.maxItems) && !(value.length <= schema.maxItems)) { yield Create(ValueErrorType.ArrayMaxItems, schema, path, value) } for (let i = 0; i < value.length; i++) { yield* Visit(schema.items, references, `${path}/${i}`, value[i]) } // prettier-ignore if (schema.uniqueItems === true && !((function () { const set = new Set(); for (const element of value) { const hashed = Hash(element); if (set.has(hashed)) { return false } else { set.add(hashed) } } return true })())) { yield Create(ValueErrorType.ArrayUniqueItems, schema, path, value) } // contains if (!(IsDefined(schema.contains) || IsDefined(schema.minContains) || IsDefined(schema.maxContains))) { return } const containsSchema = IsDefined(schema.contains) ? schema.contains : Never() const containsCount = value.reduce((acc: number, value, index) => (Visit(containsSchema, references, `${path}${index}`, value).next().done === true ? acc + 1 : acc), 0) if (containsCount === 0) { yield Create(ValueErrorType.ArrayContains, schema, path, value) } if (IsNumber(schema.minContains) && containsCount < schema.minContains) { yield Create(ValueErrorType.ArrayMinContains, schema, path, value) } if (IsNumber(schema.maxContains) && containsCount > schema.maxContains) { yield Create(ValueErrorType.ArrayMaxContains, schema, path, value) } } function* FromAsyncIterator(schema: TAsyncIterator, references: TSchema[], path: string, value: any): IterableIterator { if (!IsAsyncIterator(value)) yield Create(ValueErrorType.AsyncIterator, schema, path, value) } function* FromBigInt(schema: TBigInt, references: TSchema[], path: string, value: any): IterableIterator { if (!IsBigInt(value)) return yield Create(ValueErrorType.BigInt, schema, path, value) if (IsDefined(schema.exclusiveMaximum) && !(value < schema.exclusiveMaximum)) { yield Create(ValueErrorType.BigIntExclusiveMaximum, schema, path, value) } if (IsDefined(schema.exclusiveMinimum) && !(value > schema.exclusiveMinimum)) { yield Create(ValueErrorType.BigIntExclusiveMinimum, schema, path, value) } if (IsDefined(schema.maximum) && !(value <= schema.maximum)) { yield Create(ValueErrorType.BigIntMaximum, schema, path, value) } if (IsDefined(schema.minimum) && !(value >= schema.minimum)) { yield Create(ValueErrorType.BigIntMinimum, schema, path, value) } if (IsDefined(schema.multipleOf) && !(value % schema.multipleOf === BigInt(0))) { yield Create(ValueErrorType.BigIntMultipleOf, schema, path, value) } } function* FromBoolean(schema: TBoolean, references: TSchema[], path: string, value: any): IterableIterator { if (!IsBoolean(value)) yield Create(ValueErrorType.Boolean, schema, path, value) } function* FromConstructor(schema: TConstructor, references: TSchema[], path: string, value: any): IterableIterator { yield* Visit(schema.returns, references, path, value.prototype) } function* FromDate(schema: TDate, references: TSchema[], path: string, value: any): IterableIterator { if (!IsDate(value)) return yield Create(ValueErrorType.Date, schema, path, value) if (IsDefined(schema.exclusiveMaximumTimestamp) && !(value.getTime() < schema.exclusiveMaximumTimestamp)) { yield Create(ValueErrorType.DateExclusiveMaximumTimestamp, schema, path, value) } if (IsDefined(schema.exclusiveMinimumTimestamp) && !(value.getTime() > schema.exclusiveMinimumTimestamp)) { yield Create(ValueErrorType.DateExclusiveMinimumTimestamp, schema, path, value) } if (IsDefined(schema.maximumTimestamp) && !(value.getTime() <= schema.maximumTimestamp)) { yield Create(ValueErrorType.DateMaximumTimestamp, schema, path, value) } if (IsDefined(schema.minimumTimestamp) && !(value.getTime() >= schema.minimumTimestamp)) { yield Create(ValueErrorType.DateMinimumTimestamp, schema, path, value) } if (IsDefined(schema.multipleOfTimestamp) && !(value.getTime() % schema.multipleOfTimestamp === 0)) { yield Create(ValueErrorType.DateMultipleOfTimestamp, schema, path, value) } } function* FromFunction(schema: TFunction, references: TSchema[], path: string, value: any): IterableIterator { if (!IsFunction(value)) yield Create(ValueErrorType.Function, schema, path, value) } function* FromImport(schema: TImport, references: TSchema[], path: string, value: any): IterableIterator { const definitions = globalThis.Object.values(schema.$defs) as TSchema[] const target = schema.$defs[schema.$ref] as TSchema yield* Visit(target, [...references, ...definitions], path, value) } function* FromInteger(schema: TInteger, references: TSchema[], path: string, value: any): IterableIterator { if (!IsInteger(value)) return yield Create(ValueErrorType.Integer, schema, path, value) if (IsDefined(schema.exclusiveMaximum) && !(value < schema.exclusiveMaximum)) { yield Create(ValueErrorType.IntegerExclusiveMaximum, schema, path, value) } if (IsDefined(schema.exclusiveMinimum) && !(value > schema.exclusiveMinimum)) { yield Create(ValueErrorType.IntegerExclusiveMinimum, schema, path, value) } if (IsDefined(schema.maximum) && !(value <= schema.maximum)) { yield Create(ValueErrorType.IntegerMaximum, schema, path, value) } if (IsDefined(schema.minimum) && !(value >= schema.minimum)) { yield Create(ValueErrorType.IntegerMinimum, schema, path, value) } if (IsDefined(schema.multipleOf) && !(value % schema.multipleOf === 0)) { yield Create(ValueErrorType.IntegerMultipleOf, schema, path, value) } } function* FromIntersect(schema: TIntersect, references: TSchema[], path: string, value: any): IterableIterator { let hasError = false for (const inner of schema.allOf) { for (const error of Visit(inner, references, path, value)) { hasError = true yield error } } if (hasError) { return yield Create(ValueErrorType.Intersect, schema, path, value) } if (schema.unevaluatedProperties === false) { const keyCheck = new RegExp(KeyOfPattern(schema)) for (const valueKey of Object.getOwnPropertyNames(value)) { if (!keyCheck.test(valueKey)) { yield Create(ValueErrorType.IntersectUnevaluatedProperties, schema, `${path}/${valueKey}`, value) } } } if (typeof schema.unevaluatedProperties === 'object') { const keyCheck = new RegExp(KeyOfPattern(schema)) for (const valueKey of Object.getOwnPropertyNames(value)) { if (!keyCheck.test(valueKey)) { const next = Visit(schema.unevaluatedProperties, references, `${path}/${valueKey}`, value[valueKey]).next() if (!next.done) yield next.value // yield interior } } } } function* FromIterator(schema: TIterator, references: TSchema[], path: string, value: any): IterableIterator { if (!IsIterator(value)) yield Create(ValueErrorType.Iterator, schema, path, value) } function* FromLiteral(schema: TLiteral, references: TSchema[], path: string, value: any): IterableIterator { if (!(value === schema.const)) yield Create(ValueErrorType.Literal, schema, path, value) } function* FromNever(schema: TNever, references: TSchema[], path: string, value: any): IterableIterator { yield Create(ValueErrorType.Never, schema, path, value) } function* FromNot(schema: TNot, references: TSchema[], path: string, value: any): IterableIterator { if (Visit(schema.not, references, path, value).next().done === true) yield Create(ValueErrorType.Not, schema, path, value) } function* FromNull(schema: TNull, references: TSchema[], path: string, value: any): IterableIterator { if (!IsNull(value)) yield Create(ValueErrorType.Null, schema, path, value) } function* FromNumber(schema: TNumber, references: TSchema[], path: string, value: any): IterableIterator { if (!TypeSystemPolicy.IsNumberLike(value)) return yield Create(ValueErrorType.Number, schema, path, value) if (IsDefined(schema.exclusiveMaximum) && !(value < schema.exclusiveMaximum)) { yield Create(ValueErrorType.NumberExclusiveMaximum, schema, path, value) } if (IsDefined(schema.exclusiveMinimum) && !(value > schema.exclusiveMinimum)) { yield Create(ValueErrorType.NumberExclusiveMinimum, schema, path, value) } if (IsDefined(schema.maximum) && !(value <= schema.maximum)) { yield Create(ValueErrorType.NumberMaximum, schema, path, value) } if (IsDefined(schema.minimum) && !(value >= schema.minimum)) { yield Create(ValueErrorType.NumberMinimum, schema, path, value) } if (IsDefined(schema.multipleOf) && !(value % schema.multipleOf === 0)) { yield Create(ValueErrorType.NumberMultipleOf, schema, path, value) } } function* FromObject(schema: TObject, references: TSchema[], path: string, value: any): IterableIterator { if (!TypeSystemPolicy.IsObjectLike(value)) return yield Create(ValueErrorType.Object, schema, path, value) if (IsDefined(schema.minProperties) && !(Object.getOwnPropertyNames(value).length >= schema.minProperties)) { yield Create(ValueErrorType.ObjectMinProperties, schema, path, value) } if (IsDefined(schema.maxProperties) && !(Object.getOwnPropertyNames(value).length <= schema.maxProperties)) { yield Create(ValueErrorType.ObjectMaxProperties, schema, path, value) } const requiredKeys = Array.isArray(schema.required) ? schema.required : ([] as string[]) const knownKeys = Object.getOwnPropertyNames(schema.properties) const unknownKeys = Object.getOwnPropertyNames(value) for (const requiredKey of requiredKeys) { if (unknownKeys.includes(requiredKey)) continue yield Create(ValueErrorType.ObjectRequiredProperty, schema.properties[requiredKey], `${path}/${EscapeKey(requiredKey)}`, undefined) } if (schema.additionalProperties === false) { for (const valueKey of unknownKeys) { if (!knownKeys.includes(valueKey)) { yield Create(ValueErrorType.ObjectAdditionalProperties, schema, `${path}/${EscapeKey(valueKey)}`, value[valueKey]) } } } if (typeof schema.additionalProperties === 'object') { for (const valueKey of unknownKeys) { if (knownKeys.includes(valueKey)) continue yield* Visit(schema.additionalProperties as TSchema, references, `${path}/${EscapeKey(valueKey)}`, value[valueKey]) } } for (const knownKey of knownKeys) { const property = schema.properties[knownKey] if (schema.required && schema.required.includes(knownKey)) { yield* Visit(property, references, `${path}/${EscapeKey(knownKey)}`, value[knownKey]) if (ExtendsUndefinedCheck(schema) && !(knownKey in value)) { yield Create(ValueErrorType.ObjectRequiredProperty, property, `${path}/${EscapeKey(knownKey)}`, undefined) } } else { if (TypeSystemPolicy.IsExactOptionalProperty(value, knownKey)) { yield* Visit(property, references, `${path}/${EscapeKey(knownKey)}`, value[knownKey]) } } } } function* FromPromise(schema: TPromise, references: TSchema[], path: string, value: any): IterableIterator { if (!IsPromise(value)) yield Create(ValueErrorType.Promise, schema, path, value) } function* FromRecord(schema: TRecord, references: TSchema[], path: string, value: any): IterableIterator { if (!TypeSystemPolicy.IsRecordLike(value)) return yield Create(ValueErrorType.Object, schema, path, value) if (IsDefined(schema.minProperties) && !(Object.getOwnPropertyNames(value).length >= schema.minProperties)) { yield Create(ValueErrorType.ObjectMinProperties, schema, path, value) } if (IsDefined(schema.maxProperties) && !(Object.getOwnPropertyNames(value).length <= schema.maxProperties)) { yield Create(ValueErrorType.ObjectMaxProperties, schema, path, value) } const [patternKey, patternSchema] = Object.entries(schema.patternProperties)[0] const regex = new RegExp(patternKey) for (const [propertyKey, propertyValue] of Object.entries(value)) { if (regex.test(propertyKey)) yield* Visit(patternSchema, references, `${path}/${EscapeKey(propertyKey)}`, propertyValue) } if (typeof schema.additionalProperties === 'object') { for (const [propertyKey, propertyValue] of Object.entries(value)) { if (!regex.test(propertyKey)) yield* Visit(schema.additionalProperties as TSchema, references, `${path}/${EscapeKey(propertyKey)}`, propertyValue) } } if (schema.additionalProperties === false) { for (const [propertyKey, propertyValue] of Object.entries(value)) { if (regex.test(propertyKey)) continue return yield Create(ValueErrorType.ObjectAdditionalProperties, schema, `${path}/${EscapeKey(propertyKey)}`, propertyValue) } } } function* FromRef(schema: TRef, references: TSchema[], path: string, value: any): IterableIterator { yield* Visit(Deref(schema, references), references, path, value) } function* FromRegExp(schema: TRegExp, references: TSchema[], path: string, value: any): IterableIterator { if (!IsString(value)) return yield Create(ValueErrorType.String, schema, path, value) if (IsDefined(schema.minLength) && !(value.length >= schema.minLength)) { yield Create(ValueErrorType.StringMinLength, schema, path, value) } if (IsDefined(schema.maxLength) && !(value.length <= schema.maxLength)) { yield Create(ValueErrorType.StringMaxLength, schema, path, value) } const regex = new RegExp(schema.source, schema.flags) if (!regex.test(value)) { return yield Create(ValueErrorType.RegExp, schema, path, value) } } function* FromString(schema: TString, references: TSchema[], path: string, value: any): IterableIterator { if (!IsString(value)) return yield Create(ValueErrorType.String, schema, path, value) if (IsDefined(schema.minLength) && !(value.length >= schema.minLength)) { yield Create(ValueErrorType.StringMinLength, schema, path, value) } if (IsDefined(schema.maxLength) && !(value.length <= schema.maxLength)) { yield Create(ValueErrorType.StringMaxLength, schema, path, value) } if (IsString(schema.pattern)) { const regex = new RegExp(schema.pattern) if (!regex.test(value)) { yield Create(ValueErrorType.StringPattern, schema, path, value) } } if (IsString(schema.format)) { if (!FormatRegistry.Has(schema.format)) { yield Create(ValueErrorType.StringFormatUnknown, schema, path, value) } else { const format = FormatRegistry.Get(schema.format)! if (!format(value)) { yield Create(ValueErrorType.StringFormat, schema, path, value) } } } } function* FromSymbol(schema: TSymbol, references: TSchema[], path: string, value: any): IterableIterator { if (!IsSymbol(value)) yield Create(ValueErrorType.Symbol, schema, path, value) } function* FromTemplateLiteral(schema: TTemplateLiteral, references: TSchema[], path: string, value: any): IterableIterator { if (!IsString(value)) return yield Create(ValueErrorType.String, schema, path, value) const regex = new RegExp(schema.pattern) if (!regex.test(value)) { yield Create(ValueErrorType.StringPattern, schema, path, value) } } function* FromThis(schema: TThis, references: TSchema[], path: string, value: any): IterableIterator { yield* Visit(Deref(schema, references), references, path, value) } function* FromTuple(schema: TTuple, references: TSchema[], path: string, value: any): IterableIterator { if (!IsArray(value)) return yield Create(ValueErrorType.Tuple, schema, path, value) if (schema.items === undefined && !(value.length === 0)) { return yield Create(ValueErrorType.TupleLength, schema, path, value) } if (!(value.length === schema.maxItems)) { return yield Create(ValueErrorType.TupleLength, schema, path, value) } if (!schema.items) { return } for (let i = 0; i < schema.items.length; i++) { yield* Visit(schema.items[i], references, `${path}/${i}`, value[i]) } } function* FromUndefined(schema: TUndefined, references: TSchema[], path: string, value: any): IterableIterator { if (!IsUndefined(value)) yield Create(ValueErrorType.Undefined, schema, path, value) } function* FromUnion(schema: TUnion, references: TSchema[], path: string, value: any): IterableIterator { if (Check(schema, references, value)) return const errors = schema.anyOf.map((variant) => new ValueErrorIterator(Visit(variant, references, path, value))) yield Create(ValueErrorType.Union, schema, path, value, errors) } function* FromUint8Array(schema: TUint8Array, references: TSchema[], path: string, value: any): IterableIterator { if (!IsUint8Array(value)) return yield Create(ValueErrorType.Uint8Array, schema, path, value) if (IsDefined(schema.maxByteLength) && !(value.length <= schema.maxByteLength)) { yield Create(ValueErrorType.Uint8ArrayMaxByteLength, schema, path, value) } if (IsDefined(schema.minByteLength) && !(value.length >= schema.minByteLength)) { yield Create(ValueErrorType.Uint8ArrayMinByteLength, schema, path, value) } } function* FromUnknown(schema: TUnknown, references: TSchema[], path: string, value: any): IterableIterator {} function* FromVoid(schema: TVoid, references: TSchema[], path: string, value: any): IterableIterator { if (!TypeSystemPolicy.IsVoidLike(value)) yield Create(ValueErrorType.Void, schema, path, value) } function* FromKind(schema: TSchema, references: TSchema[], path: string, value: any): IterableIterator { const check = TypeRegistry.Get(schema[Kind])! if (!check(schema, value)) yield Create(ValueErrorType.Kind, schema, path, value) } function* Visit(schema: T, references: TSchema[], path: string, value: any): IterableIterator { const references_ = IsDefined(schema.$id) ? [...references, schema] : references const schema_ = schema as any switch (schema_[Kind]) { case 'Any': return yield* FromAny(schema_, references_, path, value) case 'Argument': return yield* FromArgument(schema_, references_, path, value) case 'Array': return yield* FromArray(schema_, references_, path, value) case 'AsyncIterator': return yield* FromAsyncIterator(schema_, references_, path, value) case 'BigInt': return yield* FromBigInt(schema_, references_, path, value) case 'Boolean': return yield* FromBoolean(schema_, references_, path, value) case 'Constructor': return yield* FromConstructor(schema_, references_, path, value) case 'Date': return yield* FromDate(schema_, references_, path, value) case 'Function': return yield* FromFunction(schema_, references_, path, value) case 'Import': return yield* FromImport(schema_, references_, path, value) case 'Integer': return yield* FromInteger(schema_, references_, path, value) case 'Intersect': return yield* FromIntersect(schema_, references_, path, value) case 'Iterator': return yield* FromIterator(schema_, references_, path, value) case 'Literal': return yield* FromLiteral(schema_, references_, path, value) case 'Never': return yield* FromNever(schema_, references_, path, value) case 'Not': return yield* FromNot(schema_, references_, path, value) case 'Null': return yield* FromNull(schema_, references_, path, value) case 'Number': return yield* FromNumber(schema_, references_, path, value) case 'Object': return yield* FromObject(schema_, references_, path, value) case 'Promise': return yield* FromPromise(schema_, references_, path, value) case 'Record': return yield* FromRecord(schema_, references_, path, value) case 'Ref': return yield* FromRef(schema_, references_, path, value) case 'RegExp': return yield* FromRegExp(schema_, references_, path, value) case 'String': return yield* FromString(schema_, references_, path, value) case 'Symbol': return yield* FromSymbol(schema_, references_, path, value) case 'TemplateLiteral': return yield* FromTemplateLiteral(schema_, references_, path, value) case 'This': return yield* FromThis(schema_, references_, path, value) case 'Tuple': return yield* FromTuple(schema_, references_, path, value) case 'Undefined': return yield* FromUndefined(schema_, references_, path, value) case 'Union': return yield* FromUnion(schema_, references_, path, value) case 'Uint8Array': return yield* FromUint8Array(schema_, references_, path, value) case 'Unknown': return yield* FromUnknown(schema_, references_, path, value) case 'Void': return yield* FromVoid(schema_, references_, path, value) default: if (!TypeRegistry.Has(schema_[Kind])) throw new ValueErrorsUnknownTypeError(schema) return yield* FromKind(schema_, references_, path, value) } } /** Returns an iterator for each error in this value. */ export function Errors(schema: T, references: TSchema[], value: unknown): ValueErrorIterator /** Returns an iterator for each error in this value. */ export function Errors(schema: T, value: unknown): ValueErrorIterator /** Returns an iterator for each error in this value. */ export function Errors(...args: any[]) { const iterator = args.length === 3 ? Visit(args[0], args[1], '', args[2]) : Visit(args[0], [], '', args[1]) return new ValueErrorIterator(iterator) } sinclairzx81-typebox-e0ec98c/src/errors/function.ts000066400000000000000000000217661505437577000225740ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/system The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { TSchema } from '../type/schema/index' import { Kind } from '../type/symbols/index' import { ValueErrorIterator, ValueErrorType } from './errors' /** Creates an error message using en-US as the default locale */ export function DefaultErrorFunction(error: ErrorFunctionParameter) { switch (error.errorType) { case ValueErrorType.ArrayContains: return 'Expected array to contain at least one matching value' case ValueErrorType.ArrayMaxContains: return `Expected array to contain no more than ${error.schema.maxContains} matching values` case ValueErrorType.ArrayMinContains: return `Expected array to contain at least ${error.schema.minContains} matching values` case ValueErrorType.ArrayMaxItems: return `Expected array length to be less or equal to ${error.schema.maxItems}` case ValueErrorType.ArrayMinItems: return `Expected array length to be greater or equal to ${error.schema.minItems}` case ValueErrorType.ArrayUniqueItems: return 'Expected array elements to be unique' case ValueErrorType.Array: return 'Expected array' case ValueErrorType.AsyncIterator: return 'Expected AsyncIterator' case ValueErrorType.BigIntExclusiveMaximum: return `Expected bigint to be less than ${error.schema.exclusiveMaximum}` case ValueErrorType.BigIntExclusiveMinimum: return `Expected bigint to be greater than ${error.schema.exclusiveMinimum}` case ValueErrorType.BigIntMaximum: return `Expected bigint to be less or equal to ${error.schema.maximum}` case ValueErrorType.BigIntMinimum: return `Expected bigint to be greater or equal to ${error.schema.minimum}` case ValueErrorType.BigIntMultipleOf: return `Expected bigint to be a multiple of ${error.schema.multipleOf}` case ValueErrorType.BigInt: return 'Expected bigint' case ValueErrorType.Boolean: return 'Expected boolean' case ValueErrorType.DateExclusiveMinimumTimestamp: return `Expected Date timestamp to be greater than ${error.schema.exclusiveMinimumTimestamp}` case ValueErrorType.DateExclusiveMaximumTimestamp: return `Expected Date timestamp to be less than ${error.schema.exclusiveMaximumTimestamp}` case ValueErrorType.DateMinimumTimestamp: return `Expected Date timestamp to be greater or equal to ${error.schema.minimumTimestamp}` case ValueErrorType.DateMaximumTimestamp: return `Expected Date timestamp to be less or equal to ${error.schema.maximumTimestamp}` case ValueErrorType.DateMultipleOfTimestamp: return `Expected Date timestamp to be a multiple of ${error.schema.multipleOfTimestamp}` case ValueErrorType.Date: return 'Expected Date' case ValueErrorType.Function: return 'Expected function' case ValueErrorType.IntegerExclusiveMaximum: return `Expected integer to be less than ${error.schema.exclusiveMaximum}` case ValueErrorType.IntegerExclusiveMinimum: return `Expected integer to be greater than ${error.schema.exclusiveMinimum}` case ValueErrorType.IntegerMaximum: return `Expected integer to be less or equal to ${error.schema.maximum}` case ValueErrorType.IntegerMinimum: return `Expected integer to be greater or equal to ${error.schema.minimum}` case ValueErrorType.IntegerMultipleOf: return `Expected integer to be a multiple of ${error.schema.multipleOf}` case ValueErrorType.Integer: return 'Expected integer' case ValueErrorType.IntersectUnevaluatedProperties: return 'Unexpected property' case ValueErrorType.Intersect: return 'Expected all values to match' case ValueErrorType.Iterator: return 'Expected Iterator' case ValueErrorType.Literal: return `Expected ${typeof error.schema.const === 'string' ? `'${error.schema.const}'` : error.schema.const}` case ValueErrorType.Never: return 'Never' case ValueErrorType.Not: return 'Value should not match' case ValueErrorType.Null: return 'Expected null' case ValueErrorType.NumberExclusiveMaximum: return `Expected number to be less than ${error.schema.exclusiveMaximum}` case ValueErrorType.NumberExclusiveMinimum: return `Expected number to be greater than ${error.schema.exclusiveMinimum}` case ValueErrorType.NumberMaximum: return `Expected number to be less or equal to ${error.schema.maximum}` case ValueErrorType.NumberMinimum: return `Expected number to be greater or equal to ${error.schema.minimum}` case ValueErrorType.NumberMultipleOf: return `Expected number to be a multiple of ${error.schema.multipleOf}` case ValueErrorType.Number: return 'Expected number' case ValueErrorType.Object: return 'Expected object' case ValueErrorType.ObjectAdditionalProperties: return 'Unexpected property' case ValueErrorType.ObjectMaxProperties: return `Expected object to have no more than ${error.schema.maxProperties} properties` case ValueErrorType.ObjectMinProperties: return `Expected object to have at least ${error.schema.minProperties} properties` case ValueErrorType.ObjectRequiredProperty: return 'Expected required property' case ValueErrorType.Promise: return 'Expected Promise' case ValueErrorType.RegExp: return 'Expected string to match regular expression' case ValueErrorType.StringFormatUnknown: return `Unknown format '${error.schema.format}'` case ValueErrorType.StringFormat: return `Expected string to match '${error.schema.format}' format` case ValueErrorType.StringMaxLength: return `Expected string length less or equal to ${error.schema.maxLength}` case ValueErrorType.StringMinLength: return `Expected string length greater or equal to ${error.schema.minLength}` case ValueErrorType.StringPattern: return `Expected string to match '${error.schema.pattern}'` case ValueErrorType.String: return 'Expected string' case ValueErrorType.Symbol: return 'Expected symbol' case ValueErrorType.TupleLength: return `Expected tuple to have ${error.schema.maxItems || 0} elements` case ValueErrorType.Tuple: return 'Expected tuple' case ValueErrorType.Uint8ArrayMaxByteLength: return `Expected byte length less or equal to ${error.schema.maxByteLength}` case ValueErrorType.Uint8ArrayMinByteLength: return `Expected byte length greater or equal to ${error.schema.minByteLength}` case ValueErrorType.Uint8Array: return 'Expected Uint8Array' case ValueErrorType.Undefined: return 'Expected undefined' case ValueErrorType.Union: return 'Expected union value' case ValueErrorType.Void: return 'Expected void' case ValueErrorType.Kind: return `Expected kind '${error.schema[Kind]}'` default: return 'Unknown error type' } } // ------------------------------------------------------------------ // ErrorFunction // ------------------------------------------------------------------ export type ErrorFunctionParameter = { /** The type of validation error */ errorType: ValueErrorType /** The path of the error */ path: string /** The schema associated with the error */ schema: TSchema /** The value associated with the error */ value: unknown /** Interior errors for this error */ errors: ValueErrorIterator[] } export type ErrorFunction = (parameter: ErrorFunctionParameter) => string /** Manages error message providers */ let errorFunction: ErrorFunction = DefaultErrorFunction /** Sets the error function used to generate error messages. */ export function SetErrorFunction(callback: ErrorFunction) { errorFunction = callback } /** Gets the error function used to generate error messages */ export function GetErrorFunction(): ErrorFunction { return errorFunction } sinclairzx81-typebox-e0ec98c/src/errors/index.ts000066400000000000000000000025211505437577000220420ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/errors The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './errors' export * from './function' sinclairzx81-typebox-e0ec98c/src/index.ts000066400000000000000000000104621505437577000205310ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ // ------------------------------------------------------------------ // Infrastructure // ------------------------------------------------------------------ export * from './type/clone/index' export * from './type/create/index' export * from './type/error/index' export * from './type/guard/index' export * from './type/helpers/index' export * from './type/patterns/index' export * from './type/registry/index' export * from './type/sets/index' export * from './type/symbols/index' // ------------------------------------------------------------------ // Types // ------------------------------------------------------------------ export * from './type/any/index' export * from './type/array/index' export * from './type/argument/index' export * from './type/async-iterator/index' export * from './type/awaited/index' export * from './type/bigint/index' export * from './type/boolean/index' export * from './type/composite/index' export * from './type/const/index' export * from './type/constructor/index' export * from './type/constructor-parameters/index' export * from './type/date/index' export * from './type/enum/index' export * from './type/exclude/index' export * from './type/extends/index' export * from './type/extract/index' export * from './type/function/index' export * from './type/indexed/index' export * from './type/instance-type/index' export * from './type/instantiate/index' export * from './type/integer/index' export * from './type/intersect/index' export * from './type/iterator/index' export * from './type/intrinsic/index' export * from './type/keyof/index' export * from './type/literal/index' export * from './type/module/index' export * from './type/mapped/index' export * from './type/never/index' export * from './type/not/index' export * from './type/null/index' export * from './type/number/index' export * from './type/object/index' export * from './type/omit/index' export * from './type/optional/index' export * from './type/parameters/index' export * from './type/partial/index' export * from './type/pick/index' export * from './type/promise/index' export * from './type/readonly/index' export * from './type/readonly-optional/index' export * from './type/record/index' export * from './type/recursive/index' export * from './type/ref/index' export * from './type/regexp/index' export * from './type/required/index' export * from './type/rest/index' export * from './type/return-type/index' export * from './type/schema/index' export * from './type/static/index' export * from './type/string/index' export * from './type/symbol/index' export * from './type/template-literal/index' export * from './type/transform/index' export * from './type/tuple/index' export * from './type/uint8array/index' export * from './type/undefined/index' export * from './type/union/index' export * from './type/unknown/index' export * from './type/unsafe/index' export * from './type/void/index' // ------------------------------------------------------------------ // Type.* // ------------------------------------------------------------------ export * from './type/type/index' sinclairzx81-typebox-e0ec98c/src/parser/000077500000000000000000000000001505437577000203435ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/parser/index.ts000066400000000000000000000025461505437577000220310ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/parsebox The MIT License (MIT) Copyright (c) 2024 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * as Runtime from './runtime/index' export * as Static from './static/index' sinclairzx81-typebox-e0ec98c/src/parser/runtime/000077500000000000000000000000001505437577000220265ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/parser/runtime/guard.ts000066400000000000000000000120641505437577000235030ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/parsebox The MIT License (MIT) Copyright (c) 2024 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { IArray, IConst, IContext, IIdent, INumber, IOptional, IRef, IString, ITuple, IUnion } from './types' // ------------------------------------------------------------------ // Value Guard // ------------------------------------------------------------------ // prettier-ignore function HasPropertyKey(value: Record, key: Key): value is Record & { [_ in Key]: unknown } { return key in value } // prettier-ignore function IsObjectValue(value: unknown): value is Record { return typeof value === 'object' && value !== null } // prettier-ignore function IsArrayValue(value: unknown): value is unknown[] { return globalThis.Array.isArray(value) } // ------------------------------------------------------------------ // Parser Guard // ------------------------------------------------------------------ /** Returns true if the value is a Array Parser */ export function IsArray(value: unknown): value is IArray { return IsObjectValue(value) && HasPropertyKey(value, 'type') && value.type === 'Array' && HasPropertyKey(value, 'parser') && IsObjectValue(value.parser) } /** Returns true if the value is a Const Parser */ export function IsConst(value: unknown): value is IConst { return IsObjectValue(value) && HasPropertyKey(value, 'type') && value.type === 'Const' && HasPropertyKey(value, 'value') && typeof value.value === 'string' } /** Returns true if the value is a Context Parser */ export function IsContext(value: unknown): value is IContext { return IsObjectValue(value) && HasPropertyKey(value, 'type') && value.type === 'Context' && HasPropertyKey(value, 'left') && IsParser(value.left) && HasPropertyKey(value, 'right') && IsParser(value.right) } /** Returns true if the value is a Ident Parser */ export function IsIdent(value: unknown): value is IIdent { return IsObjectValue(value) && HasPropertyKey(value, 'type') && value.type === 'Ident' } /** Returns true if the value is a Number Parser */ export function IsNumber(value: unknown): value is INumber { return IsObjectValue(value) && HasPropertyKey(value, 'type') && value.type === 'Number' } /** Returns true if the value is a Optional Parser */ export function IsOptional(value: unknown): value is IOptional { return IsObjectValue(value) && HasPropertyKey(value, 'type') && value.type === 'Optional' && HasPropertyKey(value, 'parser') && IsObjectValue(value.parser) } /** Returns true if the value is a Ref Parser */ export function IsRef(value: unknown): value is IRef { return IsObjectValue(value) && HasPropertyKey(value, 'type') && value.type === 'Ref' && HasPropertyKey(value, 'ref') && typeof value.ref === 'string' } /** Returns true if the value is a String Parser */ export function IsString(value: unknown): value is IString { return IsObjectValue(value) && HasPropertyKey(value, 'type') && value.type === 'String' && HasPropertyKey(value, 'options') && IsArrayValue(value.options) } /** Returns true if the value is a Tuple Parser */ export function IsTuple(value: unknown): value is ITuple { return IsObjectValue(value) && HasPropertyKey(value, 'type') && value.type === 'Tuple' && HasPropertyKey(value, 'parsers') && IsArrayValue(value.parsers) } /** Returns true if the value is a Union Parser */ export function IsUnion(value: unknown): value is IUnion { return IsObjectValue(value) && HasPropertyKey(value, 'type') && value.type === 'Union' && HasPropertyKey(value, 'parsers') && IsArrayValue(value.parsers) } /** Returns true if the value is a Parser */ export function IsParser(value: unknown) { // prettier-ignore return ( IsArray(value) || IsConst(value) || IsContext(value) || IsIdent(value) || IsNumber(value) || IsOptional(value) || IsRef(value) || IsString(value) || IsTuple(value) || IsUnion(value) ) } sinclairzx81-typebox-e0ec98c/src/parser/runtime/index.ts000066400000000000000000000026351505437577000235130ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/parsebox The MIT License (MIT) Copyright (c) 2024 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * as Guard from './guard' export * as Token from './token' export * from './types' export * from './module' export * from './parse' sinclairzx81-typebox-e0ec98c/src/parser/runtime/module.ts000066400000000000000000000047041505437577000236700ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/parsebox The MIT License (MIT) Copyright (c) 2024 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import * as Types from './types' import { Parse } from './parse' // ------------------------------------------------------------------ // Module // ------------------------------------------------------------------ export class Module { constructor(private readonly properties: Properties) {} /** Parses using one of the parsers defined on this instance */ public Parse(key: Key, content: string, context: unknown): [] | [Types.StaticParser, string] /** Parses using one of the parsers defined on this instance */ public Parse(key: Key, content: string): [] | [Types.StaticParser, string] /** Parses using one of the parsers defined on this instance */ public Parse(...args: any[]): never { // prettier-ignore const [key, content, context] = ( args.length === 3 ? [args[0], args[1], args[2]] : args.length === 2 ? [args[0], args[1], undefined] : (() => { throw Error('Invalid parse arguments') })() ) return Parse(this.properties, this.properties[key], content, context) as never } } sinclairzx81-typebox-e0ec98c/src/parser/runtime/parse.ts000066400000000000000000000210451505437577000235120ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/parsebox The MIT License (MIT) Copyright (c) 2024 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import * as Guard from './guard' import * as Token from './token' import * as Types from './types' // ------------------------------------------------------------------ // Context // ------------------------------------------------------------------ function ParseContext(moduleProperties: ModuleProperties, left: Parser, right: Parser, code: string, context: unknown): unknown[] { const result = ParseParser(moduleProperties, left, code, context) return result.length === 2 ? ParseParser(moduleProperties, right, result[1], result[0]) : [] } // ------------------------------------------------------------------ // Array // ------------------------------------------------------------------ function ParseArray(moduleProperties: ModuleProperties, parser: Parser, code: string, context: unknown): unknown[] { const buffer = [] as unknown[] let rest = code while (rest.length > 0) { const result = ParseParser(moduleProperties, parser, rest, context) if (result.length === 0) return [buffer, rest] buffer.push(result[0]) rest = result[1] } return [buffer, rest] } // ------------------------------------------------------------------ // Const // ------------------------------------------------------------------ function ParseConst(value: Value, code: string, context: unknown): [] | [Value, string] { return Token.Const(value, code) as never } // ------------------------------------------------------------------ // Ident // ------------------------------------------------------------------ function ParseIdent(code: string, _context: unknown): [] | [string, string] { return Token.Ident(code) } // ------------------------------------------------------------------ // Number // ------------------------------------------------------------------ // prettier-ignore function ParseNumber(code: string, _context: unknown): [] | [string, string] { return Token.Number(code) } // ------------------------------------------------------------------ // Optional // ------------------------------------------------------------------ function ParseOptional(moduleProperties: ModuleProperties, parser: Parser, code: string, context: unknown): [] | [[unknown] | [], unknown] { const result = ParseParser(moduleProperties, parser, code, context) return (result.length === 2 ? [[result[0]], result[1]] : [[], code]) as never } // ------------------------------------------------------------------ // Ref // ------------------------------------------------------------------ function ParseRef(moduleProperties: ModuleProperties, ref: Ref, code: string, context: unknown): [] | [string, string] { const parser = moduleProperties[ref] if (!Guard.IsParser(parser)) throw Error(`Cannot dereference Parser '${ref}'`) return ParseParser(moduleProperties, parser, code, context) as never } // ------------------------------------------------------------------ // String // ------------------------------------------------------------------ // prettier-ignore function ParseString(options: string[], code: string, _context: unknown): [] | [string, string] { return Token.String(options, code) } // ------------------------------------------------------------------ // Tuple // ------------------------------------------------------------------ function ParseTuple(moduleProperties: ModuleProperties, parsers: [...Parsers], code: string, context: unknown): [] | [unknown[], string] { const buffer = [] as unknown[] let rest = code for (const parser of parsers) { const result = ParseParser(moduleProperties, parser, rest, context) if (result.length === 0) return [] buffer.push(result[0]) rest = result[1] } return [buffer, rest] } // ------------------------------------------------------------------ // Union // ------------------------------------------------------------------ // prettier-ignore function ParseUnion(moduleProperties: ModuleProperties, parsers: [...Parsers], code: string, context: unknown): [] | [unknown, string] { for(const parser of parsers) { const result = ParseParser(moduleProperties, parser, code, context) if(result.length === 0) continue return result } return [] } // ------------------------------------------------------------------ // Parser // ------------------------------------------------------------------ // prettier-ignore function ParseParser(moduleProperties: Types.IModuleProperties, parser: Parser, code: string, context: unknown): [] | [Types.StaticParser, string] { const result = ( Guard.IsContext(parser) ? ParseContext(moduleProperties, parser.left, parser.right, code, context) : Guard.IsArray(parser) ? ParseArray(moduleProperties, parser.parser, code, context) : Guard.IsConst(parser) ? ParseConst(parser.value, code, context) : Guard.IsIdent(parser) ? ParseIdent(code, context) : Guard.IsNumber(parser) ? ParseNumber(code, context) : Guard.IsOptional(parser) ? ParseOptional(moduleProperties, parser.parser, code, context) : Guard.IsRef(parser) ? ParseRef(moduleProperties, parser.ref, code, context) : Guard.IsString(parser) ? ParseString(parser.options, code, context) : Guard.IsTuple(parser) ? ParseTuple(moduleProperties, parser.parsers, code, context) : Guard.IsUnion(parser) ? ParseUnion(moduleProperties, parser.parsers, code, context) : [] ) return ( result.length === 2 ? [parser.mapping(result[0], context), result[1]] : result ) as never } // ------------------------------------------------------------------ // Parse // ------------------------------------------------------------------ /** Parses content using the given Parser */ // prettier-ignore export function Parse(moduleProperties: Types.IModuleProperties, parser: Parser, code: string, context: unknown): [] | [Types.StaticParser, string] /** Parses content using the given Parser */ // prettier-ignore export function Parse(moduleProperties: Types.IModuleProperties, parser: Parser, code: string): [] | [Types.StaticParser, string] /** Parses content using the given Parser */ // prettier-ignore export function Parse(parser: Parser, content: string, context: unknown): [] | [Types.StaticParser, string] /** Parses content using the given Parser */ // prettier-ignore export function Parse(parser: Parser, content: string): [] | [Types.StaticParser, string] /** Parses content using the given parser */ // prettier-ignore export function Parse(...args: any[]): never { const withModuleProperties = typeof args[1] === 'string' ? false : true const [moduleProperties, parser, content, context] = withModuleProperties ? [args[0], args[1], args[2], args[3]] : [{}, args[0], args[1], args[2]] return ParseParser(moduleProperties, parser, content, context) as never } sinclairzx81-typebox-e0ec98c/src/parser/runtime/token.ts000066400000000000000000000174601505437577000235260ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/parsebox The MIT License (MIT) Copyright (c) 2024 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ // ------------------------------------------------------------------ // Chars // ------------------------------------------------------------------ // prettier-ignore namespace Chars { /** Returns true if the char code is a whitespace */ export function IsWhitespace(value: number): boolean { return value === 32 } /** Returns true if the char code is a newline */ export function IsNewline(value: number): boolean { return value === 10 } /** Returns true if the char code is a alpha */ export function IsAlpha(value: number): boolean { return ( (value >= 65 && value <= 90) || // A-Z (value >= 97 && value <= 122) // a-z ) } /** Returns true if the char code is zero */ export function IsZero(value: number): boolean { return value === 48 } /** Returns true if the char code is non-zero */ export function IsNonZero(value: number): boolean { return value >= 49 && value <= 57 } /** Returns true if the char code is a digit */ export function IsDigit(value: number): boolean { return ( IsNonZero(value) || IsZero(value) ) } /** Returns true if the char code is a dot */ export function IsDot(value: number): boolean { return value === 46 } /** Returns true if this char code is a underscore */ export function IsUnderscore(value: unknown): boolean { return value === 95 } /** Returns true if this char code is a dollar sign */ export function IsDollarSign(value: unknown): boolean { return value === 36 } } // ------------------------------------------------------------------ // Trim // ------------------------------------------------------------------ // prettier-ignore namespace Trim { /** Trims Whitespace and retains Newline, Tabspaces, etc. */ export function TrimWhitespaceOnly(code: string): string { for (let i = 0; i < code.length; i++) { if (Chars.IsWhitespace(code.charCodeAt(i))) continue return code.slice(i) } return code } /** Trims Whitespace including Newline, Tabspaces, etc. */ export function TrimAll(code: string): string { return code.trimStart() } } // ------------------------------------------------------------------ // Const // ------------------------------------------------------------------ /** Checks the value matches the next string */ // prettier-ignore function NextTokenCheck(value: string, code: string): boolean { if (value.length > code.length) return false for (let i = 0; i < value.length; i++) { if (value.charCodeAt(i) !== code.charCodeAt(i)) return false } return true } /** Gets the next constant string value or empty if no match */ // prettier-ignore function NextConst(value: string, code: string, ): [] | [string, string] { return NextTokenCheck(value, code) ? [code.slice(0, value.length), code.slice(value.length)] : [] } /** Takes the next constant string value skipping any whitespace */ // prettier-ignore export function Const(value: string, code: string): [] | [string, string] { if(value.length === 0) return ['', code] const char_0 = value.charCodeAt(0) return ( Chars.IsNewline(char_0) ? NextConst(value, Trim.TrimWhitespaceOnly(code)) : Chars.IsWhitespace(char_0) ? NextConst(value, code) : NextConst(value, Trim.TrimAll(code)) ) } // ------------------------------------------------------------------ // Ident // ------------------------------------------------------------------ // prettier-ignore function IdentIsFirst(char: number) { return ( Chars.IsAlpha(char) || Chars.IsDollarSign(char) || Chars.IsUnderscore(char) ) } // prettier-ignore function IdentIsRest(char: number) { return ( Chars.IsAlpha(char) || Chars.IsDigit(char) || Chars.IsDollarSign(char) || Chars.IsUnderscore(char) ) } // prettier-ignore function NextIdent(code: string): [] | [string, string] { if (!IdentIsFirst(code.charCodeAt(0))) return [] for (let i = 1; i < code.length; i++) { const char = code.charCodeAt(i) if (IdentIsRest(char)) continue const slice = code.slice(0, i) const rest = code.slice(i) return [slice, rest] } return [code, ''] } /** Scans for the next Ident token */ // prettier-ignore export function Ident(code: string): [] | [string, string] { return NextIdent(Trim.TrimAll(code)) } // ------------------------------------------------------------------ // Number // ------------------------------------------------------------------ /** Checks that the next number is not a leading zero */ // prettier-ignore function NumberLeadingZeroCheck(code: string, index: number) { const char_0 = code.charCodeAt(index + 0) const char_1 = code.charCodeAt(index + 1) return ( ( // 1-9 Chars.IsNonZero(char_0) ) || ( // 0 Chars.IsZero(char_0) && !Chars.IsDigit(char_1) ) || ( // 0. Chars.IsZero(char_0) && Chars.IsDot(char_1) ) || ( // .0 Chars.IsDot(char_0) && Chars.IsDigit(char_1) ) ) } /** Gets the next number token */ // prettier-ignore function NextNumber(code: string): [] | [string, string] { const negated = code.charAt(0) === '-' const index = negated ? 1 : 0 if (!NumberLeadingZeroCheck(code, index)) { return [] } const dash = negated ? '-' : '' let hasDot = false for (let i = index; i < code.length; i++) { const char_i = code.charCodeAt(i) if (Chars.IsDigit(char_i)) { continue } if (Chars.IsDot(char_i)) { if (hasDot) { const slice = code.slice(index, i) const rest = code.slice(i) return [`${dash}${slice}`, rest] } hasDot = true continue } const slice = code.slice(index, i) const rest = code.slice(i) return [`${dash}${slice}`, rest] } return [code, ''] } /** Scans for the next number token */ // prettier-ignore export function Number(code: string) { return NextNumber(Trim.TrimAll(code)) } // ------------------------------------------------------------------ // String // ------------------------------------------------------------------ // prettier-ignore function NextString(options: string[], code: string): [] | [string, string] { const first = code.charAt(0) if(!options.includes(first)) return [] const quote = first for(let i = 1; i < code.length; i++) { const char = code.charAt(i) if(char === quote) { const slice = code.slice(1, i) const rest = code.slice(i + 1) return [slice, rest] } } return [] } /** Scans the next Literal String value */ // prettier-ignore export function String(options: string[], code: string) { return NextString(options, Trim.TrimAll(code)) } sinclairzx81-typebox-e0ec98c/src/parser/runtime/types.ts000066400000000000000000000276511505437577000235550ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/parsebox The MIT License (MIT) Copyright (c) 2024 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export type IModuleProperties = Record // ------------------------------------------------------------------ // Static // ------------------------------------------------------------------ /** Force output static type evaluation for Arrays */ export type StaticEnsure = T extends infer R ? R : never /** Infers the Output Parameter for a Parser */ export type StaticParser = Parser extends IParser ? Output : unknown // ------------------------------------------------------------------ // Mapping // ------------------------------------------------------------------ export type IMapping = (input: Input, context: any) => Output /** Maps input to output. This is the default Mapping */ export const Identity = (value: unknown) => value /** Maps the output as the given parameter T */ // prettier-ignore export const As = (mapping: T): ((value: unknown) => T) => (_: unknown) => mapping // ------------------------------------------------------------------ // Parser // ------------------------------------------------------------------ export interface IParser { type: string mapping: IMapping } // ------------------------------------------------------------------ // Context // ------------------------------------------------------------------ // prettier-ignore export type ContextParameter<_Left extends IParser, Right extends IParser> = ( StaticParser ) export interface IContext extends IParser { type: 'Context' left: IParser right: IParser } /** `[Context]` Creates a Context Parser */ export function Context>>(left: Left, right: Right, mapping: Mapping): IContext> /** `[Context]` Creates a Context Parser */ export function Context(left: Left, right: Right): IContext> /** `[Context]` Creates a Context Parser */ export function Context(...args: unknown[]): never { const [left, right, mapping] = args.length === 3 ? [args[0], args[1], args[2]] : [args[0], args[1], Identity] return { type: 'Context', left, right, mapping } as never } // ------------------------------------------------------------------ // Array // ------------------------------------------------------------------ // prettier-ignore export type ArrayParameter = StaticEnsure< StaticParser[] > export interface IArray extends IParser { type: 'Array' parser: IParser } /** `[EBNF]` Creates an Array Parser */ export function Array>>(parser: Parser, mapping: Mapping): IArray> /** `[EBNF]` Creates an Array Parser */ export function Array(parser: Parser): IArray> /** `[EBNF]` Creates an Array Parser */ export function Array(...args: unknown[]): never { const [parser, mapping] = args.length === 2 ? [args[0], args[1]] : [args[0], Identity] return { type: 'Array', parser, mapping } as never } // ------------------------------------------------------------------ // Const // ------------------------------------------------------------------ export interface IConst extends IParser { type: 'Const' value: string } /** `[TERM]` Creates a Const Parser */ export function Const>(value: Value, mapping: Mapping): IConst> /** `[TERM]` Creates a Const Parser */ export function Const(value: Value): IConst /** `[TERM]` Creates a Const Parser */ export function Const(...args: unknown[]): never { const [value, mapping] = args.length === 2 ? [args[0], args[1]] : [args[0], Identity] return { type: 'Const', value, mapping } as never } // ------------------------------------------------------------------ // Ref // ------------------------------------------------------------------ export interface IRef extends IParser { type: 'Ref' ref: string } /** `[BNF]` Creates a Ref Parser. This Parser can only be used in the context of a Module */ export function Ref>(ref: string, mapping: Mapping): IRef> /** `[BNF]` Creates a Ref Parser. This Parser can only be used in the context of a Module */ export function Ref(ref: string): IRef /** `[BNF]` Creates a Ref Parser. This Parser can only be used in the context of a Module */ export function Ref(...args: unknown[]): never { const [ref, mapping] = args.length === 2 ? [args[0], args[1]] : [args[0], Identity] return { type: 'Ref', ref, mapping } as never } // ------------------------------------------------------------------ // String // ------------------------------------------------------------------ export interface IString extends IParser { type: 'String' options: string[] } /** `[TERM]` Creates a String Parser. Options are an array of permissable quote characters */ export function String>(options: string[], mapping: Mapping): IString> /** `[TERM]` Creates a String Parser. Options are an array of permissable quote characters */ export function String(options: string[]): IString /** `[TERM]` Creates a String Parser. Options are an array of permissable quote characters */ export function String(...params: unknown[]): never { const [options, mapping] = params.length === 2 ? [params[0], params[1]] : [params[0], Identity] return { type: 'String', options, mapping } as never } // ------------------------------------------------------------------ // Ident // ------------------------------------------------------------------ export interface IIdent extends IParser { type: 'Ident' } /** `[TERM]` Creates an Ident Parser where Ident matches any valid JavaScript identifier */ export function Ident>(mapping: Mapping): IIdent> /** `[TERM]` Creates an Ident Parser where Ident matches any valid JavaScript identifier */ export function Ident(): IIdent /** `[TERM]` Creates an Ident Parser where Ident matches any valid JavaScript identifier */ export function Ident(...params: unknown[]): never { const mapping = params.length === 1 ? params[0] : Identity return { type: 'Ident', mapping } as never } // ------------------------------------------------------------------ // Number // ------------------------------------------------------------------ export interface INumber extends IParser { type: 'Number' } /** `[TERM]` Creates an Number Parser */ export function Number>(mapping: Mapping): INumber> /** `[TERM]` Creates an Number Parser */ export function Number(): INumber /** `[TERM]` Creates an Number Parser */ export function Number(...params: unknown[]): never { const mapping = params.length === 1 ? params[0] : Identity return { type: 'Number', mapping } as never } // ------------------------------------------------------------------ // Optional // ------------------------------------------------------------------ // prettier-ignore export type OptionalParameter] | []> = ( Result ) export interface IOptional extends IParser { type: 'Optional' parser: IParser } /** `[EBNF]` Creates an Optional Parser */ export function Optional>>(parser: Parser, mapping: Mapping): IOptional> /** `[EBNF]` Creates an Optional Parser */ export function Optional(parser: Parser): IOptional> /** `[EBNF]` Creates an Optional Parser */ export function Optional(...args: unknown[]): never { const [parser, mapping] = args.length === 2 ? [args[0], args[1]] : [args[0], Identity] return { type: 'Optional', parser, mapping } as never } // ------------------------------------------------------------------ // Tuple // ------------------------------------------------------------------ // prettier-ignore export type TupleParameter = StaticEnsure< Parsers extends [infer Left extends IParser, ...infer Right extends IParser[]] ? TupleParameter>]> : Result > export interface ITuple extends IParser { type: 'Tuple' parsers: IParser[] } /** `[BNF]` Creates a Tuple Parser */ export function Tuple>>(parsers: [...Parsers], mapping: Mapping): ITuple> /** `[BNF]` Creates a Tuple Parser */ export function Tuple(parsers: [...Parsers]): ITuple> /** `[BNF]` Creates a Tuple Parser */ export function Tuple(...args: unknown[]): never { const [parsers, mapping] = args.length === 2 ? [args[0], args[1]] : [args[0], Identity] return { type: 'Tuple', parsers, mapping } as never } // ------------------------------------------------------------------ // Union // ------------------------------------------------------------------ // prettier-ignore export type UnionParameter = StaticEnsure< Parsers extends [infer Left extends IParser, ...infer Right extends IParser[]] ? UnionParameter> : Result > export interface IUnion extends IParser { type: 'Union' parsers: IParser[] } /** `[BNF]` Creates a Union parser */ export function Union>>(parsers: [...Parsers], mapping: Mapping): IUnion> /** `[BNF]` Creates a Union parser */ export function Union(parsers: [...Parsers]): IUnion> /** `[BNF]` Creates a Union parser */ export function Union(...args: unknown[]): never { const [parsers, mapping] = args.length === 2 ? [args[0], args[1]] : [args[0], Identity] return { type: 'Union', parsers, mapping } as never } sinclairzx81-typebox-e0ec98c/src/parser/static/000077500000000000000000000000001505437577000216325ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/parser/static/index.ts000066400000000000000000000025431505437577000233150ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/parsebox The MIT License (MIT) Copyright (c) 2024 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * as Token from './token' export * from './parse' export * from './types' sinclairzx81-typebox-e0ec98c/src/parser/static/parse.ts000066400000000000000000000154641505437577000233260ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/parsebox The MIT License (MIT) Copyright (c) 2024 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import * as Tokens from './token' import * as Types from './types' // ------------------------------------------------------------------ // Context // ------------------------------------------------------------------ // prettier-ignore type ContextParser = ( Parse extends [infer Context extends unknown, infer Rest extends string] ? Parse : [] ) // ------------------------------------------------------------------ // Array // ------------------------------------------------------------------ // prettier-ignore type ArrayParser = ( Parse extends [infer Value1 extends unknown, infer Rest extends string] ? ArrayParser : [Result, Code] ) // ------------------------------------------------------------------ // Const // ------------------------------------------------------------------ // prettier-ignore type ConstParser = ( Tokens.Const extends [infer Match extends Value, infer Rest extends string] ? [Match, Rest] : [] ) // ------------------------------------------------------------------ // Ident // ------------------------------------------------------------------ // prettier-ignore type IdentParser = ( Tokens.Ident extends [infer Match extends string, infer Rest extends string] ? [Match, Rest] : [] ) // ------------------------------------------------------------------ // Number // ------------------------------------------------------------------ // prettier-ignore type NumberParser = ( Tokens.Number extends [infer Match extends string, infer Rest extends string] ? [Match, Rest] : [] ) // ------------------------------------------------------------------ // Optional // ------------------------------------------------------------------ // prettier-ignore type OptionalParser = ( Parse extends [infer Value extends unknown, infer Rest extends string] ? [[Value], Rest] : [[], Code] ) // ------------------------------------------------------------------ // String // ------------------------------------------------------------------ // prettier-ignore type StringParser = ( Tokens.String extends [infer Match extends string, infer Rest extends string] ? [Match, Rest] : [] ) // ------------------------------------------------------------------ // Tuple // ------------------------------------------------------------------ // prettier-ignore type TupleParser = ( Parsers extends [infer Left extends Types.IParser, ...infer Right extends Types.IParser[]] ? Parse extends [infer Value extends unknown, infer Rest extends string] ? TupleParser : [] : [Result, Code] ) // ------------------------------------------------------------------ // Union // ------------------------------------------------------------------ // prettier-ignore type UnionParser = ( Parsers extends [infer Left extends Types.IParser, ...infer Right extends Types.IParser[]] ? Parse extends [infer Value extends unknown, infer Rest extends string] ? [Value, Rest] : UnionParser : [] ) // ------------------------------------------------------------------ // Parse // ------------------------------------------------------------------ // prettier-ignore type ParseCode = ( Type extends Types.Context ? ContextParser : Type extends Types.Array ? ArrayParser : Type extends Types.Const ? ConstParser : Type extends Types.Ident ? IdentParser : Type extends Types.Number ? NumberParser : Type extends Types.Optional ? OptionalParser : Type extends Types.String ? StringParser : Type extends Types.Tuple ? TupleParser : Type extends Types.Union ? UnionParser : [] ) // prettier-ignore type ParseMapping = ( (Parser['mapping'] & { input: Result, context: Context })['output'] ) /** Parses code with the given parser */ // prettier-ignore export type Parse = ( ParseCode extends [infer L extends unknown, infer R extends string] ? [ParseMapping, R] : [] ) sinclairzx81-typebox-e0ec98c/src/parser/static/token.ts000066400000000000000000000207621505437577000233310ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/parsebox The MIT License (MIT) Copyright (c) 2024 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ // ------------------------------------------------------------------ // Chars // ------------------------------------------------------------------ // prettier-ignore namespace Chars { export type Empty = '' export type Space = ' ' export type Newline = '\n' export type Dot = '.' export type Hyphen = '-' export type Digit = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ] export type Alpha = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' ] } // ------------------------------------------------------------------ // Trim // ------------------------------------------------------------------ // prettier-ignore namespace Trim { // ------------------------------------------------------------------ // Whitespace Filters // ------------------------------------------------------------------ type W9 = `${W8}${W8}` // 512 type W8 = `${W7}${W7}` // 256 type W7 = `${W6}${W6}` // 128 type W6 = `${W5}${W5}` // 64 type W5 = `${W4}${W4}` // 32 type W4 = `${W3}${W3}` // 16 type W3 = `${W2}${W2}` // 8 type W2 = `${W1}${W1}` // 4 type W1 = `${W0}${W0}` // 2 type W0 = ` ` // 1 // ------------------------------------------------------------------ // TrimWhitespace // ------------------------------------------------------------------ /** Trims whitespace only */ export type TrimWhitespace = ( Code extends `${W4}${infer Rest extends string}` ? TrimWhitespace : Code extends `${W3}${infer Rest extends string}` ? TrimWhitespace : Code extends `${W1}${infer Rest extends string}` ? TrimWhitespace : Code extends `${W0}${infer Rest extends string}` ? TrimWhitespace : Code ) // ------------------------------------------------------------------ // Trim // ------------------------------------------------------------------ /** Trims Whitespace and Newline */ export type TrimAll = ( Code extends `${W4}${infer Rest extends string}` ? TrimAll : Code extends `${W3}${infer Rest extends string}` ? TrimAll : Code extends `${W1}${infer Rest extends string}` ? TrimAll : Code extends `${W0}${infer Rest extends string}` ? TrimAll : Code extends `${Chars.Newline}${infer Rest extends string}` ? TrimAll : Code ) } // ------------------------------------------------------------------ // Union // ------------------------------------------------------------------ /** Scans for the next match union */ // prettier-ignore type NextUnion = ( Variants extends [infer Variant extends string, ...infer Rest1 extends string[]] ? NextConst extends [infer Match extends string, infer Rest2 extends string] ? [Match, Rest2] : NextUnion : [] ) // ------------------------------------------------------------------ // Const // ------------------------------------------------------------------ // prettier-ignore type NextConst = ( Code extends `${Value}${infer Rest extends string}` ? [Value, Rest] : [] ) /** Scans for the next constant value */ // prettier-ignore export type Const = ( Value extends '' ? ['', Code] : Value extends `${infer First extends string}${string}` ? ( First extends Chars.Newline ? NextConst> : First extends Chars.Space ? NextConst : NextConst> ) : never ) // ------------------------------------------------------------------ // Number // ------------------------------------------------------------------ // prettier-ignore type NextNumberNegate = ( Code extends `${Chars.Hyphen}${infer Rest extends string}` ? [Chars.Hyphen, Rest] : [Chars.Empty, Code] ) // prettier-ignore type NextNumberZeroCheck = ( Code extends `0${infer Rest}` ? NextUnion extends [string, string] ? false : true : true ) // prettier-ignore type NextNumberScan = ( NextUnion<[...Chars.Digit, Chars.Dot], Code> extends [infer Char extends string, infer Rest extends string] ? Char extends Chars.Dot ? HasDecimal extends false ? NextNumberScan : [Result, `.${Rest}`] : NextNumberScan : [Result, Code] ) // prettier-ignore export type NextNumber = ( NextNumberNegate extends [infer Negate extends string, infer Rest extends string] ? NextNumberZeroCheck extends true ? NextNumberScan extends [infer Number extends string, infer Rest2 extends string] ? Number extends Chars.Empty ? [] : [`${Negate}${Number}`, Rest2] : [] : [] : [] ) /** Scans for the next literal number */ export type Number = NextNumber> // ------------------------------------------------------------------ // String // ------------------------------------------------------------------ type NextStringQuote = NextUnion // prettier-ignore type NextStringBody = ( Code extends `${infer Char extends string}${infer Rest extends string}` ? Char extends Quote ? [Result, Rest] : NextStringBody : [] ) // prettier-ignore type NextString = ( NextStringQuote extends [infer Quote extends string, infer Rest extends string] ? NextStringBody extends [infer String extends string, infer Rest extends string] ? [String, Rest] : [] : [] ) /** Scans for the next literal string */ export type String = NextString> // ------------------------------------------------------------------ // Ident // ------------------------------------------------------------------ type IdentLeft = [...Chars.Alpha, '_', '$'] // permissable first characters type IdentRight = [...Chars.Digit, ...IdentLeft] // permissible subsequent characters // prettier-ignore type NextIdentScan = ( NextUnion extends [infer Char extends string, infer Rest extends string] ? NextIdentScan : [Result, Code] ) // prettier-ignore type NextIdent = ( NextUnion extends [infer Left extends string, infer Rest1 extends string] ? NextIdentScan extends [infer Right extends string, infer Rest2 extends string] ? [`${Left}${Right}`, Rest2] : [] : [] ) /** Scans for the next Ident */ export type Ident = NextIdent> sinclairzx81-typebox-e0ec98c/src/parser/static/types.ts000066400000000000000000000127121505437577000233510ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/parsebox The MIT License (MIT) Copyright (c) 2024 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ // ------------------------------------------------------------------ // Mapping // ------------------------------------------------------------------ /** * `[ACTION]` Inference mapping base type. Used to specify semantic actions for * Parser productions. This type is implemented as a higher-kinded type where * productions are received on the `input` property with mapping assigned * the `output` property. The parsing context is available on the `context` * property. */ export interface IMapping { context: unknown input: unknown output: unknown } /** `[ACTION]` Default inference mapping. */ export interface Identity extends IMapping { output: this['input'] } /** `[ACTION]` Maps the given argument `T` as the mapping output */ export interface As extends IMapping { output: T } // ------------------------------------------------------------------ // Parser // ------------------------------------------------------------------ /** Base type Parser implemented by all other parsers */ export interface IParser { type: string mapping: Mapping } // ------------------------------------------------------------------ // Context // ------------------------------------------------------------------ /** `[Context]` Creates a Context Parser */ export interface Context extends IParser { type: 'Context' left: Left right: Right } // ------------------------------------------------------------------ // Array // ------------------------------------------------------------------ /** `[EBNF]` Creates an Array Parser */ export interface Array extends IParser { type: 'Array' parser: Parser } // ------------------------------------------------------------------ // Const // ------------------------------------------------------------------ /** `[TERM]` Creates a Const Parser */ export interface Const extends IParser { type: 'Const' value: Value } // ------------------------------------------------------------------ // Ident // ------------------------------------------------------------------ /** `[TERM]` Creates an Ident Parser. */ // prettier-ignore export interface Ident extends IParser { type: 'Ident' } // ------------------------------------------------------------------ // Number // ------------------------------------------------------------------ /** `[TERM]` Creates a Number Parser. */ // prettier-ignore export interface Number extends IParser { type: 'Number' } // ------------------------------------------------------------------ // Optional // ------------------------------------------------------------------ /** `[EBNF]` Creates a Optional Parser */ export interface Optional extends IParser { type: 'Optional' parser: Parser } // ------------------------------------------------------------------ // String // ------------------------------------------------------------------ /** `[TERM]` Creates a String Parser. Options are an array of permissable quote characters */ export interface String extends IParser { type: 'String' quote: Options } // ------------------------------------------------------------------ // Tuple // ------------------------------------------------------------------ /** `[BNF]` Creates a Tuple Parser */ export interface Tuple extends IParser { type: 'Tuple' parsers: [...Parsers] } // ------------------------------------------------------------------ // Union // ------------------------------------------------------------------ /** `[BNF]` Creates a Union Parser */ export interface Union extends IParser { type: 'Union' parsers: [...Parsers] } sinclairzx81-typebox-e0ec98c/src/syntax/000077500000000000000000000000001505437577000203755ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/syntax/index.ts000066400000000000000000000024661505437577000220640ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/syntax The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './syntax' sinclairzx81-typebox-e0ec98c/src/syntax/mapping.ts000066400000000000000000001371671505437577000224170ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/syntax The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import * as T from '../type/index' // ------------------------------------------------------------------ // // Dereference // // Referential types pull from the Context or defer dereferencing // for later execution. This overlaps with module dereferencing, // where named identifiers in the syntax are deferred until // instantiation. This code should be revised as part of a // general-purpose Instantiate module (next revision) // // ------------------------------------------------------------------ // prettier-ignore type TDereference = ( Key extends keyof Context ? Context[Key] : T.TRef ) // prettier-ignore const Dereference = (context: T.TProperties, key: string): T.TSchema => { return key in context ? context[key] : T.Ref(key) } // ------------------------------------------------------------------ // // Delimited // // Delimited sequences use an accumulated buffer to parse sequence // tokens. This approach is more scalable than using a Union + Tuple // + Epsilon pattern, as TypeScript can instantiate deeper when // tail-call recursive accumulators are employed. However, this // comes with a latent processing cost due to the need to decode // the accumulated buffer. // // - Encoding: [[, ','][], [] | []] // // ------------------------------------------------------------------ // prettier-ignore type TDelimitedDecode = ( Input extends [infer Left, ...infer Right] ? Left extends [infer Item, infer _] ? TDelimitedDecode : TDelimitedDecode : Result ) // prettier-ignore type TDelimited = Input extends [infer Left extends unknown[], infer Right extends unknown[]] ? TDelimitedDecode<[...Left, ...Right]> : [] // prettier-ignore const DelimitedDecode = (input: ([unknown, unknown] | unknown)[], result: unknown[] = []) => { return input.reduce((result, left) => { return T.ValueGuard.IsArray(left) && left.length === 2 ? [...result, left[0]] : [...result, left] }, []) } // prettier-ignore const Delimited = (input: [unknown, unknown]) => { const [left, right] = input as [unknown[], unknown[]] return DelimitedDecode([...left, ...right]) } // ------------------------------------------------------------------- // GenericReferenceParameterList: [[Type, ','][], [Type] | []] // ------------------------------------------------------------------- // prettier-ignore export type TGenericReferenceParameterListMapping = TDelimited // prettier-ignore export function GenericReferenceParameterListMapping(input: [unknown, unknown], context: unknown) { return Delimited(input) } // ------------------------------------------------------------------- // GenericReference: [, '<', GenericReferenceParameterList, '>'] // ------------------------------------------------------------------- // prettier-ignore export type TGenericReferenceMapping'] ? T.TInstantiate, Args> : never : never > = Result // prettier-ignore export function GenericReferenceMapping(input: [unknown, unknown, unknown, unknown], context: unknown) { const type = Dereference(context as T.TProperties, input[0] as string) const args = input[2] as T.TSchema[] return T.Instantiate(type, args) } // ------------------------------------------------------------------- // GenericArgumentsList: [[, ','][], [] | []] // ------------------------------------------------------------------- // prettier-ignore export type TGenericArgumentsListMapping = TDelimited // prettier-ignore export function GenericArgumentsListMapping(input: [unknown, unknown], context: unknown) { return Delimited(input) } // ------------------------------------------------------------------- // GenericArguments: ['<', GenericArgumentsList, '>'] // ------------------------------------------------------------------- // prettier-ignore type GenericArgumentsContext = ( Arguments extends [...infer Left extends string[], infer Right extends string] ? GenericArgumentsContext }> : T.Evaluate ) // prettier-ignore export type TGenericArgumentsMapping = Input extends ['<', infer Arguments extends string[], '>'] ? Context extends infer Context extends T.TProperties ? GenericArgumentsContext : never : never // ... // prettier-ignore const GenericArgumentsContext = (_arguments: string[], context: T.TProperties) => { return _arguments.reduce((result, arg, index) => { return { ...result, [arg]: T.Argument(index) } }, context) } // prettier-ignore export function GenericArgumentsMapping(input: [unknown, unknown, unknown], context: unknown) { return input.length === 3 ? GenericArgumentsContext(input[1] as string[], context as T.TProperties) : {} } // ------------------------------------------------------------------- // KeywordString: 'string' // ------------------------------------------------------------------- // prettier-ignore export type TKeywordStringMapping = T.TString // prettier-ignore export function KeywordStringMapping(input: 'string', context: unknown) { return T.String() } // ------------------------------------------------------------------- // KeywordNumber: 'number' // ------------------------------------------------------------------- // prettier-ignore export type TKeywordNumberMapping = T.TNumber // prettier-ignore export function KeywordNumberMapping(input: 'number', context: unknown) { return T.Number() } // ------------------------------------------------------------------- // KeywordBoolean: 'boolean' // ------------------------------------------------------------------- // prettier-ignore export type TKeywordBooleanMapping = T.TBoolean // prettier-ignore export function KeywordBooleanMapping(input: 'boolean', context: unknown) { return T.Boolean() } // ------------------------------------------------------------------- // KeywordUndefined: 'undefined' // ------------------------------------------------------------------- // prettier-ignore export type TKeywordUndefinedMapping = T.TUndefined // prettier-ignore export function KeywordUndefinedMapping(input: 'undefined', context: unknown) { return T.Undefined() } // ------------------------------------------------------------------- // KeywordNull: 'null' // ------------------------------------------------------------------- // prettier-ignore export type TKeywordNullMapping = T.TNull // prettier-ignore export function KeywordNullMapping(input: 'null', context: unknown) { return T.Null() } // ------------------------------------------------------------------- // KeywordInteger: 'integer' // ------------------------------------------------------------------- // prettier-ignore export type TKeywordIntegerMapping = T.TInteger // prettier-ignore export function KeywordIntegerMapping(input: 'integer', context: unknown) { return T.Integer() } // ------------------------------------------------------------------- // KeywordBigInt: 'bigint' // ------------------------------------------------------------------- // prettier-ignore export type TKeywordBigIntMapping = T.TBigInt // prettier-ignore export function KeywordBigIntMapping(input: 'bigint', context: unknown) { return T.BigInt() } // ------------------------------------------------------------------- // KeywordUnknown: 'unknown' // ------------------------------------------------------------------- // prettier-ignore export type TKeywordUnknownMapping = T.TUnknown // prettier-ignore export function KeywordUnknownMapping(input: 'unknown', context: unknown) { return T.Unknown() } // ------------------------------------------------------------------- // KeywordAny: 'any' // ------------------------------------------------------------------- // prettier-ignore export type TKeywordAnyMapping = T.TAny // prettier-ignore export function KeywordAnyMapping(input: 'any', context: unknown) { return T.Any() } // ------------------------------------------------------------------- // KeywordNever: 'never' // ------------------------------------------------------------------- // prettier-ignore export type TKeywordNeverMapping = T.TNever // prettier-ignore export function KeywordNeverMapping(input: 'never', context: unknown) { return T.Never() } // ------------------------------------------------------------------- // KeywordSymbol: 'symbol' // ------------------------------------------------------------------- // prettier-ignore export type TKeywordSymbolMapping = T.TSymbol // prettier-ignore export function KeywordSymbolMapping(input: 'symbol', context: unknown) { return T.Symbol() } // ------------------------------------------------------------------- // KeywordVoid: 'void' // ------------------------------------------------------------------- // prettier-ignore export type TKeywordVoidMapping = T.TVoid // prettier-ignore export function KeywordVoidMapping(input: 'void', context: unknown) { return T.Void() } // ------------------------------------------------------------------- // Keyword: KeywordString | KeywordNumber | KeywordBoolean | KeywordUndefined | KeywordNull | KeywordInteger | KeywordBigInt | KeywordUnknown | KeywordAny | KeywordNever | KeywordSymbol | KeywordVoid // ------------------------------------------------------------------- // prettier-ignore export type TKeywordMapping = Input // prettier-ignore export function KeywordMapping(input: unknown, context: unknown) { return input } // ------------------------------------------------------------------- // LiteralString: // ------------------------------------------------------------------- // prettier-ignore export type TLiteralStringMapping = Input extends T.TLiteralValue ? T.TLiteral : never // prettier-ignore export function LiteralStringMapping(input: string, context: unknown) { return T.Literal(input) } // ------------------------------------------------------------------- // LiteralNumber: // ------------------------------------------------------------------- // prettier-ignore export type TLiteralNumberMapping = Input extends `${infer Value extends number}` ? T.TLiteral : never // prettier-ignore export function LiteralNumberMapping(input: string, context: unknown) { return T.Literal(parseFloat(input)) } // ------------------------------------------------------------------- // LiteralBoolean: 'true' | 'false' // ------------------------------------------------------------------- // prettier-ignore export type TLiteralBooleanMapping = Input extends 'true' ? T.TLiteral : T.TLiteral // prettier-ignore export function LiteralBooleanMapping(input: 'true' | 'false', context: unknown) { return T.Literal(input === 'true') } // ------------------------------------------------------------------- // Literal: LiteralBoolean | LiteralNumber | LiteralString // ------------------------------------------------------------------- // prettier-ignore export type TLiteralMapping = Input // prettier-ignore export function LiteralMapping(input: unknown, context: unknown) { return input } // ------------------------------------------------------------------- // KeyOf: ['keyof'] | [] // ------------------------------------------------------------------- // prettier-ignore export type TKeyOfMapping = Input extends [unknown] ? true : false // prettier-ignore export function KeyOfMapping(input: [unknown] | [], context: unknown) { return input.length > 0 } // ------------------------------------------------------------------- // IndexArray: ['[', Type, ']'] | ['[', ']'][] // ------------------------------------------------------------------- // prettier-ignore type TIndexArrayMappingReduce = ( Input extends [infer Left extends unknown, ...infer Right extends unknown[]] ? Left extends ['[', infer Type extends T.TSchema, ']'] ? TIndexArrayMappingReduce : TIndexArrayMappingReduce : Result ) // prettier-ignore export type TIndexArrayMapping = Input extends unknown[] ? TIndexArrayMappingReduce : [] // prettier-ignore export function IndexArrayMapping(input: ([unknown, unknown, unknown] | [unknown, unknown])[], context: unknown) { return input.reduce((result: unknown[], current) => { return current.length === 3 ? [...result, [current[1]]] : [...result, []] }, [] as unknown[]) } // ------------------------------------------------------------------- // Extends: ['extends', Type, '?', Type, ':', Type] | [] // ------------------------------------------------------------------- // prettier-ignore export type TExtendsMapping = Input extends ['extends', infer Type extends T.TSchema, '?', infer True extends T.TSchema, ':', infer False extends T.TSchema] ? [Type, True, False] : [] // prettier-ignore export function ExtendsMapping(input: [unknown, unknown, unknown, unknown, unknown, unknown] | [], context: unknown) { return input.length === 6 ? [input[1], input[3], input[5]] : [] } // ------------------------------------------------------------------- // Base: ['(', Type, ')'] | Keyword | Object | Tuple | Literal | Constructor | Function | Mapped | AsyncIterator | Iterator | ConstructorParameters | FunctionParameters | InstanceType | ReturnType | Argument | Awaited | Array | Record | Promise | Partial | Required | Pick | Omit | Exclude | Extract | Uppercase | Lowercase | Capitalize | Uncapitalize | Date | Uint8Array | GenericReference | Reference // ------------------------------------------------------------------- // prettier-ignore export type TBaseMapping = ( Input extends ['(', infer Type extends T.TSchema, ')'] ? Type : Input extends infer Type extends T.TSchema ? Type : never ) // prettier-ignore export function BaseMapping(input: [unknown, unknown, unknown] | unknown, context: unknown) { return T.ValueGuard.IsArray(input) && input.length === 3 ? input[1] : input } // ------------------------------------------------------------------- // Factor: [KeyOf, Base, IndexArray, Extends] // ------------------------------------------------------------------- // prettier-ignore type TFactorIndexArray = ( IndexArray extends [...infer Left extends unknown[], infer Right extends T.TSchema[]] ? ( Right extends [infer Indexer extends T.TSchema] ? T.TIndex, T.TIndexPropertyKeys> : Right extends [] ? T.TArray> : T.TNever ) : Type ) // prettier-ignore type TFactorExtends = ( Extends extends [infer Right extends T.TSchema, infer True extends T.TSchema, infer False extends T.TSchema] ? T.TExtends : Type ) // prettier-ignore export type TFactorMapping = Input extends [infer KeyOf extends boolean, infer Type extends T.TSchema, infer IndexArray extends unknown[], infer Extends extends unknown[]] ? KeyOf extends true ? TFactorExtends>, Extends> : TFactorExtends, Extends> : never // ... // prettier-ignore const FactorIndexArray = (Type: T.TSchema, indexArray: unknown[]): T.TSchema => { return indexArray.reduceRight((result, right) => { const _right = right as T.TSchema[] return ( _right.length === 1 ? T.Index(result, _right[0]) : _right.length === 0 ? T.Array(result, _right[0]) : T.Never() ) }, Type) } // prettier-ignore const FactorExtends = (Type: T.TSchema, Extends: T.TSchema[]) => { return Extends.length === 3 ? T.Extends(Type, Extends[0], Extends[1], Extends[2]) : Type } // prettier-ignore export function FactorMapping(input: [unknown, unknown, unknown, unknown], context: unknown) { const [KeyOf, Type, IndexArray, Extends] = input as [boolean, T.TSchema, unknown[], T.TSchema[]] return KeyOf ? FactorExtends(T.KeyOf(FactorIndexArray(Type, IndexArray)), Extends) : FactorExtends(FactorIndexArray(Type, IndexArray), Extends) } // ------------------------------------------------------------------ // // ExprBinaryMapping // // TypeBox Union and Intersection types are flattened to prevent // excessive nesting of `anyOf` and `allOf`, ensuring a more // readable and presentable type for the user. This function // recursively reduces Union and Intersection types based on // binary expressions parsed from input. // // ------------------------------------------------------------------ // prettier-ignore type TExprBinaryMapping = ( Rest extends [infer Operator extends unknown, infer Right extends T.TSchema, infer Next extends unknown[]] ? ( TExprBinaryMapping extends infer Schema extends T.TSchema ? ( Operator extends '&' ? ( Schema extends T.TIntersect ? T.TIntersect<[Left, ...Types]> : T.TIntersect<[Left, Schema]> ) : Operator extends '|' ? ( Schema extends T.TUnion ? T.TUnion<[Left, ...Types]> : T.TUnion<[Left, Schema]> ) : never ) : never ) : Left ) // prettier-ignore function ExprBinaryMapping(Left: T.TSchema, Rest: unknown[]): T.TSchema { return ( Rest.length === 3 ? (() => { const [Operator, Right, Next] = Rest as [string, T.TSchema, unknown[]] const Schema = ExprBinaryMapping(Right, Next) if (Operator === '&') { return T.TypeGuard.IsIntersect(Schema) ? T.Intersect([Left, ...Schema.allOf]) : T.Intersect([Left, Schema]) } if (Operator === '|') { return T.TypeGuard.IsUnion(Schema) ? T.Union([Left, ...Schema.anyOf]) : T.Union([Left, Schema]) } throw 1 })() : Left ) } // ------------------------------------------------------------------- // ExprTermTail: ['&', Factor, ExprTermTail] | [] // ------------------------------------------------------------------- // prettier-ignore export type TExprTermTailMapping = Input // prettier-ignore export function ExprTermTailMapping(input: [unknown, unknown, unknown] | [], context: unknown) { return input } // ------------------------------------------------------------------- // ExprTerm: [Factor, ExprTermTail] // ------------------------------------------------------------------- // prettier-ignore export type TExprTermMapping = ( Input extends [infer Left extends T.TSchema, infer Rest extends unknown[]] ? TExprBinaryMapping : [] ) // prettier-ignore export function ExprTermMapping(input: [unknown, unknown], context: unknown) { const [left, rest] = input as [T.TSchema, unknown[]] return ExprBinaryMapping(left, rest) } // ------------------------------------------------------------------- // ExprTail: ['|', ExprTerm, ExprTail] | [] // ------------------------------------------------------------------- // prettier-ignore export type TExprTailMapping = Input // prettier-ignore export function ExprTailMapping(input: [unknown, unknown, unknown] | [], context: unknown) { return input } // ------------------------------------------------------------------- // Expr: [ExprTerm, ExprTail] // ------------------------------------------------------------------- // prettier-ignore export type TExprMapping = Input extends [infer Left extends T.TSchema, infer Rest extends unknown[]] ? TExprBinaryMapping : [] // prettier-ignore export function ExprMapping(input: [unknown, unknown], context: unknown) { const [left, rest] = input as [T.TSchema, unknown[]] return ExprBinaryMapping(left, rest) } // ------------------------------------------------------------------- // Type: GenericArguments -> Expr | Expr // ------------------------------------------------------------------- // prettier-ignore export type TTypeMapping = Input // prettier-ignore export function TypeMapping(input: unknown, context: unknown) { return input } // ------------------------------------------------------------------- // PropertyKey: | // ------------------------------------------------------------------- // prettier-ignore export type TPropertyKeyMapping = Input // prettier-ignore export function PropertyKeyMapping(input: string, context: unknown) { return input } // ------------------------------------------------------------------- // Readonly: ['readonly'] | [] // ------------------------------------------------------------------- // prettier-ignore export type TReadonlyMapping = Input extends [unknown] ? true : false // prettier-ignore export function ReadonlyMapping(input: [unknown] | [], context: unknown) { return input.length > 0 } // ------------------------------------------------------------------- // Optional: ['?'] | [] // ------------------------------------------------------------------- // prettier-ignore export type TOptionalMapping = Input extends [unknown] ? true : false // prettier-ignore export function OptionalMapping(input: [unknown] | [], context: unknown) { return input.length > 0 } // ------------------------------------------------------------------- // Property: [Readonly, PropertyKey, Optional, ':', Type] // ------------------------------------------------------------------- // prettier-ignore export type TPropertyMapping = Input extends [infer IsReadonly extends boolean, infer Key extends string, infer IsOptional extends boolean, string, infer Type extends T.TSchema] ? { [_ in Key]: ( [IsReadonly, IsOptional] extends [true, true] ? T.TReadonlyOptional : [IsReadonly, IsOptional] extends [true, false] ? T.TReadonly : [IsReadonly, IsOptional] extends [false, true] ? T.TOptional : Type ) } : never // prettier-ignore export function PropertyMapping(input: [unknown, unknown, unknown, unknown, unknown], context: unknown) { const [isReadonly, key, isOptional, _colon, type] = input as [boolean, string, boolean, ':', T.TSchema] return { [key]: ( isReadonly && isOptional ? T.ReadonlyOptional(type) : isReadonly && !isOptional ? T.Readonly(type) : !isReadonly && isOptional ? T.Optional(type) : type ) } } // ------------------------------------------------------------------- // PropertyDelimiter: [',', '\n'] | [';', '\n'] | [','] | [';'] | ['\n'] // ------------------------------------------------------------------- // prettier-ignore export type TPropertyDelimiterMapping = Input // prettier-ignore export function PropertyDelimiterMapping(input: [unknown, unknown] | [unknown], context: unknown) { return input } // ------------------------------------------------------------------- // PropertyList: [[Property, PropertyDelimiter][], [Property] | []] // ------------------------------------------------------------------- // prettier-ignore export type TPropertyListMapping = TDelimited // prettier-ignore export function PropertyListMapping(input: [unknown, unknown], context: unknown) { return Delimited(input) } // ------------------------------------------------------------------- // Object: ['{', PropertyList, '}'] // ------------------------------------------------------------------- // prettier-ignore type TObjectMappingReduce = ( PropertiesList extends [infer Left extends T.TProperties, ...infer Right extends T.TProperties[]] ? TObjectMappingReduce : { [Key in keyof Result]: Result[Key] } ) // prettier-ignore export type TObjectMapping = Input extends ['{', infer PropertyList extends T.TProperties[], '}'] ? T.TObject> : never // prettier-ignore export function ObjectMapping(input: [unknown, unknown, unknown], context: unknown) { const propertyList = input[1] as T.TProperties[] return T.Object(propertyList.reduce((result, property) => { return { ...result, ...property } }, {} as T.TProperties)) } // ------------------------------------------------------------------- // ElementList: [[Type, ','][], [Type] | []] // ------------------------------------------------------------------- // prettier-ignore export type TElementListMapping = TDelimited // prettier-ignore export function ElementListMapping(input: [unknown, unknown], context: unknown) { return Delimited(input) } // ------------------------------------------------------------------- // Tuple: ['[', ElementList, ']'] // ------------------------------------------------------------------- // prettier-ignore export type TTupleMapping = Input extends ['[', infer Types extends T.TSchema[], ']'] ? T.TTuple : never // prettier-ignore export function TupleMapping(input: [unknown, unknown, unknown], context: unknown) { return T.Tuple(input[1] as T.TSchema[]) } // ------------------------------------------------------------------- // Parameter: [, ':', Type] // ------------------------------------------------------------------- // prettier-ignore export type TParameterMapping = Input extends [string, ':', infer Type extends T.TSchema] ? Type : never // prettier-ignore export function ParameterMapping(input: [unknown, unknown, unknown], context: unknown) { const [_ident, _colon, type] = input as [string, ':', T.TSchema] return type } // ------------------------------------------------------------------- // ParameterList: [[Parameter, ','][], [Parameter] | []] // ------------------------------------------------------------------- // prettier-ignore export type TParameterListMapping = TDelimited // prettier-ignore export function ParameterListMapping(input: [unknown, unknown], context: unknown) { return Delimited(input) } // ------------------------------------------------------------------- // Function: ['(', ParameterList, ')', '=>', Type] // ------------------------------------------------------------------- // prettier-ignore export type TFunctionMapping = Input extends ['(', infer ParameterList extends T.TSchema[], ')', '=>', infer ReturnType extends T.TSchema] ? T.TFunction : never // prettier-ignore export function FunctionMapping(input: [unknown, unknown, unknown, unknown, unknown], context: unknown) { const [_lparan, parameterList, _rparan, _arrow, returnType] = input as ['(', T.TSchema[], ')', '=>', T.TSchema] return T.Function(parameterList, returnType) } // ------------------------------------------------------------------- // Constructor: ['new', '(', ParameterList, ')', '=>', Type] // ------------------------------------------------------------------- // prettier-ignore export type TConstructorMapping = Input extends ['new', '(', infer ParameterList extends T.TSchema[], ')', '=>', infer InstanceType extends T.TSchema] ? T.TConstructor : never // prettier-ignore export function ConstructorMapping(input: [unknown, unknown, unknown, unknown, unknown, unknown], context: unknown) { const [_new, _lparan, parameterList, _rparan, _arrow, instanceType] = input as ['new', '(', T.TSchema[], ')', '=>', T.TSchema] return T.Constructor(parameterList, instanceType) } // ------------------------------------------------------------------- // Mapped: ['{', '[', , 'in', Type, ']', ':', Type, '}'] // ------------------------------------------------------------------- // prettier-ignore export type TMappedMapping = Input extends ['{', '[', infer _Key extends string, 'in', infer _Right extends T.TSchema, ']', ':', infer _Type extends T.TSchema, '}'] ? T.TLiteral<'Mapped types not supported'> : never // prettier-ignore export function MappedMapping(input: [unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown], context: unknown) { const [_lbrace, _lbracket, _key, _in, _right, _rbracket, _colon, _type] = input as ['{', '[', string, 'in', T.TSchema, ']', ':', T.TSchema, '}'] return T.Literal('Mapped types not supported') } // ------------------------------------------------------------------- // AsyncIterator: ['AsyncIterator', '<', Type, '>'] // ------------------------------------------------------------------- // prettier-ignore export type TAsyncIteratorMapping = Input extends ['AsyncIterator', '<', infer Type extends T.TSchema, '>'] ? T.TAsyncIterator : never // prettier-ignore export function AsyncIteratorMapping(input: [unknown, unknown, unknown, unknown], context: unknown) { const [_name, _langle, type, _rangle] = input as ['AsyncIterator', '<', T.TSchema, '>'] return T.AsyncIterator(type) } // ------------------------------------------------------------------- // Iterator: ['Iterator', '<', Type, '>'] // ------------------------------------------------------------------- // prettier-ignore export type TIteratorMapping = Input extends ['Iterator', '<', infer Type extends T.TSchema, '>'] ? T.TIterator : never // prettier-ignore export function IteratorMapping(input: [unknown, unknown, unknown, unknown], context: unknown) { const [_name, _langle, type, _rangle] = input as ['Iterator', '<', T.TSchema, '>'] return T.Iterator(type) } // ------------------------------------------------------------------- // Argument: ['Argument', '<', Type, '>'] // ------------------------------------------------------------------- // prettier-ignore export type TArgumentMapping = Input extends ['Argument', '<', infer Type extends T.TSchema, '>'] ? Type extends T.TLiteral ? T.TArgument : T.TNever : never // prettier-ignore export function ArgumentMapping(input: [unknown, unknown, unknown, unknown], context: unknown) { return T.KindGuard.IsLiteralNumber(input[2]) ? T.Argument(Math.trunc(input[2].const)) : T.Never() } // ------------------------------------------------------------------- // Awaited: ['Awaited', '<', Type, '>'] // ------------------------------------------------------------------- // prettier-ignore export type TAwaitedMapping = Input extends ['Awaited', '<', infer Type extends T.TSchema, '>'] ? T.TAwaited : never // prettier-ignore export function AwaitedMapping(input: [unknown, unknown, unknown, unknown], context: unknown) { const [_name, _langle, type, _rangle] = input as ['Awaited', '<', T.TSchema, '>'] return T.Awaited(type) } // ------------------------------------------------------------------- // Array: ['Array', '<', Type, '>'] // ------------------------------------------------------------------- // prettier-ignore export type TArrayMapping = Input extends ['Array', '<', infer Type extends T.TSchema, '>'] ? T.TArray : never // prettier-ignore export function ArrayMapping(input: [unknown, unknown, unknown, unknown], context: unknown) { const [_name, _langle, type, _rangle] = input as ['Array', '<', T.TSchema, '>'] return T.Array(type) } // ------------------------------------------------------------------- // Record: ['Record', '<', Type, ',', Type, '>'] // ------------------------------------------------------------------- // prettier-ignore export type TRecordMapping = Input extends ['Record', '<', infer Key extends T.TSchema, ',', infer Type extends T.TSchema, '>'] ? T.TRecordOrObject : never // prettier-ignore export function RecordMapping(input: [unknown, unknown, unknown, unknown, unknown, unknown], context: unknown) { const [_name, _langle, key, _comma, type, _rangle] = input as ['Record', '<', T.TSchema, ',', T.TSchema, '>'] return T.Record(key, type) } // ------------------------------------------------------------------- // Promise: ['Promise', '<', Type, '>'] // ------------------------------------------------------------------- // prettier-ignore export type TPromiseMapping = Input extends ['Promise', '<', infer Type extends T.TSchema, '>'] ? T.TPromise : never // prettier-ignore export function PromiseMapping(input: [unknown, unknown, unknown, unknown], context: unknown) { const [_name, _langle, type, _rangle] = input as ['Promise', '<', T.TSchema, '>'] return T.Promise(type) } // ------------------------------------------------------------------- // ConstructorParameters: ['ConstructorParameters', '<', Type, '>'] // ------------------------------------------------------------------- // prettier-ignore export type TConstructorParametersMapping = Input extends ['ConstructorParameters', '<', infer Type extends T.TSchema, '>'] ? T.TConstructorParameters : never // prettier-ignore export function ConstructorParametersMapping(input: [unknown, unknown, unknown, unknown], context: unknown) { const [_name, _langle, type, _rangle] = input as ['ConstructorParameters', '<', T.TSchema, '>'] return T.ConstructorParameters(type) } // ------------------------------------------------------------------- // FunctionParameters: ['Parameters', '<', Type, '>'] // ------------------------------------------------------------------- // prettier-ignore export type TFunctionParametersMapping = Input extends ['Parameters', '<', infer Type extends T.TSchema, '>'] ? T.TParameters : never // prettier-ignore export function FunctionParametersMapping(input: [unknown, unknown, unknown, unknown], context: unknown) { const [_name, _langle, type, _rangle] = input as ['Parameters', '<', T.TSchema, '>'] return T.Parameters(type) } // ------------------------------------------------------------------- // InstanceType: ['InstanceType', '<', Type, '>'] // ------------------------------------------------------------------- // prettier-ignore export type TInstanceTypeMapping = Input extends ['InstanceType', '<', infer Type extends T.TSchema, '>'] ? T.TInstanceType : never // prettier-ignore export function InstanceTypeMapping(input: [unknown, unknown, unknown, unknown], context: unknown) { const [_name, _langle, type, _rangle] = input as ['InstanceType', '<', T.TSchema, '>'] return T.InstanceType(type) } // ------------------------------------------------------------------- // ReturnType: ['ReturnType', '<', Type, '>'] // ------------------------------------------------------------------- // prettier-ignore export type TReturnTypeMapping = Input extends ['ReturnType', '<', infer Type extends T.TSchema, '>'] ? T.TReturnType : never // prettier-ignore export function ReturnTypeMapping(input: [unknown, unknown, unknown, unknown], context: unknown) { const [_name, _langle, type, _rangle] = input as ['ReturnType', '<', T.TSchema, '>'] return T.ReturnType(type) } // ------------------------------------------------------------------- // Partial: ['Partial', '<', Type, '>'] // ------------------------------------------------------------------- // prettier-ignore export type TPartialMapping = Input extends ['Partial', '<', infer Type extends T.TSchema, '>'] ? T.TPartial : never // prettier-ignore export function PartialMapping(input: [unknown, unknown, unknown, unknown], context: unknown) { const [_name, _langle, type, _rangle] = input as ['Partial', '<', T.TSchema, '>'] return T.Partial(type) } // ------------------------------------------------------------------- // Required: ['Required', '<', Type, '>'] // ------------------------------------------------------------------- // prettier-ignore export type TRequiredMapping = Input extends ['Required', '<', infer Type extends T.TSchema, '>'] ? T.TRequired : never // prettier-ignore export function RequiredMapping(input: [unknown, unknown, unknown, unknown], context: unknown) { const [_name, _langle, type, _rangle] = input as ['Required', '<', T.TSchema, '>'] return T.Required(type) } // ------------------------------------------------------------------- // Pick: ['Pick', '<', Type, ',', Type, '>'] // ------------------------------------------------------------------- // prettier-ignore export type TPickMapping = Input extends ['Pick', '<', infer Type extends T.TSchema, ',', infer Key extends T.TSchema, '>'] ? T.TPick : never // prettier-ignore export function PickMapping(input: [unknown, unknown, unknown, unknown, unknown, unknown], context: unknown) { const [_name, _langle, key, _comma, type, _rangle] = input as ['Pick', '<', T.TSchema, ',', T.TSchema, '>'] return T.Pick(key, type) } // ------------------------------------------------------------------- // Omit: ['Omit', '<', Type, ',', Type, '>'] // ------------------------------------------------------------------- // prettier-ignore export type TOmitMapping = Input extends ['Omit', '<', infer Type extends T.TSchema, ',', infer Key extends T.TSchema, '>'] ? T.TOmit : never // prettier-ignore export function OmitMapping(input: [unknown, unknown, unknown, unknown, unknown, unknown], context: unknown) { const [_name, _langle, key, _comma, type, _rangle] = input as ['Omit', '<', T.TSchema, ',', T.TSchema, '>'] return T.Omit(key, type) } // ------------------------------------------------------------------- // Exclude: ['Exclude', '<', Type, ',', Type, '>'] // ------------------------------------------------------------------- // prettier-ignore export type TExcludeMapping = Input extends ['Exclude', '<', infer Type extends T.TSchema, ',', infer Key extends T.TSchema, '>'] ? T.TExclude : never // prettier-ignore export function ExcludeMapping(input: [unknown, unknown, unknown, unknown, unknown, unknown], context: unknown) { const [_name, _langle, key, _comma, type, _rangle] = input as ['Exclude', '<', T.TSchema, ',', T.TSchema, '>'] return T.Exclude(key, type) } // ------------------------------------------------------------------- // Extract: ['Extract', '<', Type, ',', Type, '>'] // ------------------------------------------------------------------- // prettier-ignore export type TExtractMapping = Input extends ['Extract', '<', infer Type extends T.TSchema, ',', infer Key extends T.TSchema, '>'] ? T.TExtract : never // prettier-ignore export function ExtractMapping(input: [unknown, unknown, unknown, unknown, unknown, unknown], context: unknown) { const [_name, _langle, key, _comma, type, _rangle] = input as ['Extract', '<', T.TSchema, ',', T.TSchema, '>'] return T.Extract(key, type) } // ------------------------------------------------------------------- // Uppercase: ['Uppercase', '<', Type, '>'] // ------------------------------------------------------------------- // prettier-ignore export type TUppercaseMapping = Input extends ['Uppercase', '<', infer Type extends T.TSchema, '>'] ? T.TUppercase : never // prettier-ignore export function UppercaseMapping(input: [unknown, unknown, unknown, unknown], context: unknown) { const [_name, _langle, type, _rangle] = input as ['Uppercase', '<', T.TSchema, '>'] return T.Uppercase(type) } // ------------------------------------------------------------------- // Lowercase: ['Lowercase', '<', Type, '>'] // ------------------------------------------------------------------- // prettier-ignore export type TLowercaseMapping = Input extends ['Lowercase', '<', infer Type extends T.TSchema, '>'] ? T.TLowercase : never // prettier-ignore export function LowercaseMapping(input: [unknown, unknown, unknown, unknown], context: unknown) { const [_name, _langle, type, _rangle] = input as ['Lowercase', '<', T.TSchema, '>'] return T.Lowercase(type) } // ------------------------------------------------------------------- // Capitalize: ['Capitalize', '<', Type, '>'] // ------------------------------------------------------------------- // prettier-ignore export type TCapitalizeMapping = Input extends ['Capitalize', '<', infer Type extends T.TSchema, '>'] ? T.TCapitalize : never // prettier-ignore export function CapitalizeMapping(input: [unknown, unknown, unknown, unknown], context: unknown) { const [_name, _langle, type, _rangle] = input as ['Capitalize', '<', T.TSchema, '>'] return T.Capitalize(type) } // ------------------------------------------------------------------- // Uncapitalize: ['Uncapitalize', '<', Type, '>'] // ------------------------------------------------------------------- // prettier-ignore export type TUncapitalizeMapping = Input extends ['Uncapitalize', '<', infer Type extends T.TSchema, '>'] ? T.TUncapitalize : never // prettier-ignore export function UncapitalizeMapping(input: [unknown, unknown, unknown, unknown], context: unknown) { const [_name, _langle, type, _rangle] = input as ['Uncapitalize', '<', T.TSchema, '>'] return T.Uncapitalize(type) } // ------------------------------------------------------------------- // Date: 'Date' // ------------------------------------------------------------------- // prettier-ignore export type TDateMapping = T.TDate // prettier-ignore export function DateMapping(input: 'Date', context: unknown) { return T.Date() } // ------------------------------------------------------------------- // Uint8Array: 'Uint8Array' // ------------------------------------------------------------------- // prettier-ignore export type TUint8ArrayMapping = T.TUint8Array // prettier-ignore export function Uint8ArrayMapping(input: 'Uint8Array', context: unknown) { return T.Uint8Array() } // ------------------------------------------------------------------- // Reference: // ------------------------------------------------------------------- // prettier-ignore export type TReferenceMapping = Context extends T.TProperties ? Input extends string ? TDereference : never : never // prettier-ignore export function ReferenceMapping(input: string, context: unknown) { const target = Dereference(context as T.TProperties, input) return target } sinclairzx81-typebox-e0ec98c/src/syntax/parser.ts000066400000000000000000002746541505437577000222630ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/syntax The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { Runtime, Static } from '../parser/index' import * as T from '../type/index' import * as S from './mapping' // ------------------------------------------------------------------ // Parser // // The following code is optimized inline types generated by a remote // compiler process. It is readonly and should not be modified. // ------------------------------------------------------------------ export type TGenericReferenceParameterList_0 = ( TType extends [infer _0, infer Input extends string] ? (Static.Token.Const<',', Input> extends [infer _1, infer Input extends string] ? [[_0, _1], Input] : []) : [] ) extends [infer _0, infer Input extends string] ? TGenericReferenceParameterList_0 : [Result, Input] export type TGenericReferenceParameterList = ( TGenericReferenceParameterList_0 extends [infer _0, infer Input extends string] ? ( (TType extends [infer _0, infer Input extends string] ? [[_0], Input] : []) extends [infer _0, infer Input extends string] ? [_0, Input] : [[], Input] extends [infer _0, infer Input extends string] ? [_0, Input] : [] ) extends [infer _1, infer Input extends string] ? [[_0, _1], Input] : [] : [] ) extends [infer _0 extends [unknown, unknown], infer Input extends string] ? [S.TGenericReferenceParameterListMapping<_0, Context>, Input] : [] export type TGenericReference = ( Static.Token.Ident extends [infer _0, infer Input extends string] ? Static.Token.Const<'<', Input> extends [infer _1, infer Input extends string] ? TGenericReferenceParameterList extends [infer _2, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _3, infer Input extends string] ? [[_0, _1, _2, _3], Input] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TGenericReferenceMapping<_0, Context>, Input] : [] export type TGenericArgumentsList_0 = ( Static.Token.Ident extends [infer _0, infer Input extends string] ? (Static.Token.Const<',', Input> extends [infer _1, infer Input extends string] ? [[_0, _1], Input] : []) : [] ) extends [infer _0, infer Input extends string] ? TGenericArgumentsList_0 : [Result, Input] export type TGenericArgumentsList = ( TGenericArgumentsList_0 extends [infer _0, infer Input extends string] ? ( (Static.Token.Ident extends [infer _0, infer Input extends string] ? [[_0], Input] : []) extends [infer _0, infer Input extends string] ? [_0, Input] : [[], Input] extends [infer _0, infer Input extends string] ? [_0, Input] : [] ) extends [infer _1, infer Input extends string] ? [[_0, _1], Input] : [] : [] ) extends [infer _0 extends [unknown, unknown], infer Input extends string] ? [S.TGenericArgumentsListMapping<_0, Context>, Input] : [] export type TGenericArguments = ( Static.Token.Const<'<', Input> extends [infer _0, infer Input extends string] ? TGenericArgumentsList extends [infer _1, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _2, infer Input extends string] ? [[_0, _1, _2], Input] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown], infer Input extends string] ? [S.TGenericArgumentsMapping<_0, Context>, Input] : [] export type TKeywordString = Static.Token.Const<'string', Input> extends [infer _0 extends 'string', infer Input extends string] ? [S.TKeywordStringMapping<_0, Context>, Input] : [] export type TKeywordNumber = Static.Token.Const<'number', Input> extends [infer _0 extends 'number', infer Input extends string] ? [S.TKeywordNumberMapping<_0, Context>, Input] : [] export type TKeywordBoolean = Static.Token.Const<'boolean', Input> extends [infer _0 extends 'boolean', infer Input extends string] ? [S.TKeywordBooleanMapping<_0, Context>, Input] : [] export type TKeywordUndefined = Static.Token.Const<'undefined', Input> extends [infer _0 extends 'undefined', infer Input extends string] ? [S.TKeywordUndefinedMapping<_0, Context>, Input] : [] export type TKeywordNull = Static.Token.Const<'null', Input> extends [infer _0 extends 'null', infer Input extends string] ? [S.TKeywordNullMapping<_0, Context>, Input] : [] export type TKeywordInteger = Static.Token.Const<'integer', Input> extends [infer _0 extends 'integer', infer Input extends string] ? [S.TKeywordIntegerMapping<_0, Context>, Input] : [] export type TKeywordBigInt = Static.Token.Const<'bigint', Input> extends [infer _0 extends 'bigint', infer Input extends string] ? [S.TKeywordBigIntMapping<_0, Context>, Input] : [] export type TKeywordUnknown = Static.Token.Const<'unknown', Input> extends [infer _0 extends 'unknown', infer Input extends string] ? [S.TKeywordUnknownMapping<_0, Context>, Input] : [] export type TKeywordAny = Static.Token.Const<'any', Input> extends [infer _0 extends 'any', infer Input extends string] ? [S.TKeywordAnyMapping<_0, Context>, Input] : [] export type TKeywordNever = Static.Token.Const<'never', Input> extends [infer _0 extends 'never', infer Input extends string] ? [S.TKeywordNeverMapping<_0, Context>, Input] : [] export type TKeywordSymbol = Static.Token.Const<'symbol', Input> extends [infer _0 extends 'symbol', infer Input extends string] ? [S.TKeywordSymbolMapping<_0, Context>, Input] : [] export type TKeywordVoid = Static.Token.Const<'void', Input> extends [infer _0 extends 'void', infer Input extends string] ? [S.TKeywordVoidMapping<_0, Context>, Input] : [] export type TKeyword = ( TKeywordString extends [infer _0, infer Input extends string] ? [_0, Input] : TKeywordNumber extends [infer _0, infer Input extends string] ? [_0, Input] : TKeywordBoolean extends [infer _0, infer Input extends string] ? [_0, Input] : TKeywordUndefined extends [infer _0, infer Input extends string] ? [_0, Input] : TKeywordNull extends [infer _0, infer Input extends string] ? [_0, Input] : TKeywordInteger extends [infer _0, infer Input extends string] ? [_0, Input] : TKeywordBigInt extends [infer _0, infer Input extends string] ? [_0, Input] : TKeywordUnknown extends [infer _0, infer Input extends string] ? [_0, Input] : TKeywordAny extends [infer _0, infer Input extends string] ? [_0, Input] : TKeywordNever extends [infer _0, infer Input extends string] ? [_0, Input] : TKeywordSymbol extends [infer _0, infer Input extends string] ? [_0, Input] : TKeywordVoid extends [infer _0, infer Input extends string] ? [_0, Input] : [] ) extends [infer _0 extends unknown, infer Input extends string] ? [S.TKeywordMapping<_0, Context>, Input] : [] export type TLiteralString = Static.Token.String<["'", '"', '`'], Input> extends [infer _0 extends string, infer Input extends string] ? [S.TLiteralStringMapping<_0, Context>, Input] : [] export type TLiteralNumber = Static.Token.Number extends [infer _0 extends string, infer Input extends string] ? [S.TLiteralNumberMapping<_0, Context>, Input] : [] export type TLiteralBoolean = ( Static.Token.Const<'true', Input> extends [infer _0, infer Input extends string] ? [_0, Input] : Static.Token.Const<'false', Input> extends [infer _0, infer Input extends string] ? [_0, Input] : [] ) extends [infer _0 extends 'true' | 'false', infer Input extends string] ? [S.TLiteralBooleanMapping<_0, Context>, Input] : [] export type TLiteral = ( TLiteralBoolean extends [infer _0, infer Input extends string] ? [_0, Input] : TLiteralNumber extends [infer _0, infer Input extends string] ? [_0, Input] : TLiteralString extends [infer _0, infer Input extends string] ? [_0, Input] : [] ) extends [infer _0 extends unknown, infer Input extends string] ? [S.TLiteralMapping<_0, Context>, Input] : [] export type TKeyOf = ( (Static.Token.Const<'keyof', Input> extends [infer _0, infer Input extends string] ? [[_0], Input] : []) extends [infer _0, infer Input extends string] ? [_0, Input] : [[], Input] extends [infer _0, infer Input extends string] ? [_0, Input] : [] ) extends [infer _0 extends [unknown] | [], infer Input extends string] ? [S.TKeyOfMapping<_0, Context>, Input] : [] export type TIndexArray_0 = ( ( Static.Token.Const<'[', Input> extends [infer _0, infer Input extends string] ? TType extends [infer _1, infer Input extends string] ? Static.Token.Const<']', Input> extends [infer _2, infer Input extends string] ? [[_0, _1, _2], Input] : [] : [] : [] ) extends [infer _0, infer Input extends string] ? [_0, Input] : (Static.Token.Const<'[', Input> extends [infer _0, infer Input extends string] ? (Static.Token.Const<']', Input> extends [infer _1, infer Input extends string] ? [[_0, _1], Input] : []) : []) extends [ infer _0, infer Input extends string, ] ? [_0, Input] : [] ) extends [infer _0, infer Input extends string] ? TIndexArray_0 : [Result, Input] export type TIndexArray = TIndexArray_0 extends [infer _0 extends ([unknown, unknown, unknown] | [unknown, unknown])[], infer Input extends string] ? [S.TIndexArrayMapping<_0, Context>, Input] : [] export type TExtends = ( ( Static.Token.Const<'extends', Input> extends [infer _0, infer Input extends string] ? TType extends [infer _1, infer Input extends string] ? Static.Token.Const<'?', Input> extends [infer _2, infer Input extends string] ? TType extends [infer _3, infer Input extends string] ? Static.Token.Const<':', Input> extends [infer _4, infer Input extends string] ? TType extends [infer _5, infer Input extends string] ? [[_0, _1, _2, _3, _4, _5], Input] : [] : [] : [] : [] : [] : [] ) extends [infer _0, infer Input extends string] ? [_0, Input] : [[], Input] extends [infer _0, infer Input extends string] ? [_0, Input] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown, unknown, unknown] | [], infer Input extends string] ? [S.TExtendsMapping<_0, Context>, Input] : [] export type TBase = ( ( Static.Token.Const<'(', Input> extends [infer _0, infer Input extends string] ? TType extends [infer _1, infer Input extends string] ? Static.Token.Const<')', Input> extends [infer _2, infer Input extends string] ? [[_0, _1, _2], Input] : [] : [] : [] ) extends [infer _0, infer Input extends string] ? [_0, Input] : TKeyword extends [infer _0, infer Input extends string] ? [_0, Input] : TObject extends [infer _0, infer Input extends string] ? [_0, Input] : TTuple extends [infer _0, infer Input extends string] ? [_0, Input] : TLiteral extends [infer _0, infer Input extends string] ? [_0, Input] : TConstructor extends [infer _0, infer Input extends string] ? [_0, Input] : TFunction extends [infer _0, infer Input extends string] ? [_0, Input] : TMapped extends [infer _0, infer Input extends string] ? [_0, Input] : TAsyncIterator extends [infer _0, infer Input extends string] ? [_0, Input] : TIterator extends [infer _0, infer Input extends string] ? [_0, Input] : TConstructorParameters extends [infer _0, infer Input extends string] ? [_0, Input] : TFunctionParameters extends [infer _0, infer Input extends string] ? [_0, Input] : TInstanceType extends [infer _0, infer Input extends string] ? [_0, Input] : TReturnType extends [infer _0, infer Input extends string] ? [_0, Input] : TArgument extends [infer _0, infer Input extends string] ? [_0, Input] : TAwaited extends [infer _0, infer Input extends string] ? [_0, Input] : TArray extends [infer _0, infer Input extends string] ? [_0, Input] : TRecord extends [infer _0, infer Input extends string] ? [_0, Input] : TPromise extends [infer _0, infer Input extends string] ? [_0, Input] : TPartial extends [infer _0, infer Input extends string] ? [_0, Input] : TRequired extends [infer _0, infer Input extends string] ? [_0, Input] : TPick extends [infer _0, infer Input extends string] ? [_0, Input] : TOmit extends [infer _0, infer Input extends string] ? [_0, Input] : TExclude extends [infer _0, infer Input extends string] ? [_0, Input] : TExtract extends [infer _0, infer Input extends string] ? [_0, Input] : TUppercase extends [infer _0, infer Input extends string] ? [_0, Input] : TLowercase extends [infer _0, infer Input extends string] ? [_0, Input] : TCapitalize extends [infer _0, infer Input extends string] ? [_0, Input] : TUncapitalize extends [infer _0, infer Input extends string] ? [_0, Input] : TDate extends [infer _0, infer Input extends string] ? [_0, Input] : TUint8Array extends [infer _0, infer Input extends string] ? [_0, Input] : TGenericReference extends [infer _0, infer Input extends string] ? [_0, Input] : TReference extends [infer _0, infer Input extends string] ? [_0, Input] : [] ) extends [infer _0 extends [unknown, unknown, unknown] | unknown, infer Input extends string] ? [S.TBaseMapping<_0, Context>, Input] : [] export type TFactor = ( TKeyOf extends [infer _0, infer Input extends string] ? TBase extends [infer _1, infer Input extends string] ? TIndexArray extends [infer _2, infer Input extends string] ? TExtends extends [infer _3, infer Input extends string] ? [[_0, _1, _2, _3], Input] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TFactorMapping<_0, Context>, Input] : [] export type TExprTermTail = ( ( Static.Token.Const<'&', Input> extends [infer _0, infer Input extends string] ? TFactor extends [infer _1, infer Input extends string] ? TExprTermTail extends [infer _2, infer Input extends string] ? [[_0, _1, _2], Input] : [] : [] : [] ) extends [infer _0, infer Input extends string] ? [_0, Input] : [[], Input] extends [infer _0, infer Input extends string] ? [_0, Input] : [] ) extends [infer _0 extends [unknown, unknown, unknown] | [], infer Input extends string] ? [S.TExprTermTailMapping<_0, Context>, Input] : [] export type TExprTerm = ( TFactor extends [infer _0, infer Input extends string] ? (TExprTermTail extends [infer _1, infer Input extends string] ? [[_0, _1], Input] : []) : [] ) extends [infer _0 extends [unknown, unknown], infer Input extends string] ? [S.TExprTermMapping<_0, Context>, Input] : [] export type TExprTail = ( ( Static.Token.Const<'|', Input> extends [infer _0, infer Input extends string] ? TExprTerm extends [infer _1, infer Input extends string] ? TExprTail extends [infer _2, infer Input extends string] ? [[_0, _1, _2], Input] : [] : [] : [] ) extends [infer _0, infer Input extends string] ? [_0, Input] : [[], Input] extends [infer _0, infer Input extends string] ? [_0, Input] : [] ) extends [infer _0 extends [unknown, unknown, unknown] | [], infer Input extends string] ? [S.TExprTailMapping<_0, Context>, Input] : [] export type TExpr = ( TExprTerm extends [infer _0, infer Input extends string] ? (TExprTail extends [infer _1, infer Input extends string] ? [[_0, _1], Input] : []) : [] ) extends [infer _0 extends [unknown, unknown], infer Input extends string] ? [S.TExprMapping<_0, Context>, Input] : [] export type TType = ( TGenericArguments extends [infer _0 extends T.TProperties, infer Input extends string] ? TExpr : [] extends [infer _0, infer Input extends string] ? [_0, Input] : TExpr extends [infer _0, infer Input extends string] ? [_0, Input] : [] ) extends [infer _0 extends unknown, infer Input extends string] ? [S.TTypeMapping<_0, Context>, Input] : [] export type TPropertyKey = ( Static.Token.Ident extends [infer _0, infer Input extends string] ? [_0, Input] : Static.Token.String<["'", '"'], Input> extends [infer _0, infer Input extends string] ? [_0, Input] : [] ) extends [infer _0 extends string, infer Input extends string] ? [S.TPropertyKeyMapping<_0, Context>, Input] : [] export type TReadonly = ( (Static.Token.Const<'readonly', Input> extends [infer _0, infer Input extends string] ? [[_0], Input] : []) extends [infer _0, infer Input extends string] ? [_0, Input] : [[], Input] extends [infer _0, infer Input extends string] ? [_0, Input] : [] ) extends [infer _0 extends [unknown] | [], infer Input extends string] ? [S.TReadonlyMapping<_0, Context>, Input] : [] export type TOptional = ( (Static.Token.Const<'?', Input> extends [infer _0, infer Input extends string] ? [[_0], Input] : []) extends [infer _0, infer Input extends string] ? [_0, Input] : [[], Input] extends [infer _0, infer Input extends string] ? [_0, Input] : [] ) extends [infer _0 extends [unknown] | [], infer Input extends string] ? [S.TOptionalMapping<_0, Context>, Input] : [] export type TProperty = ( TReadonly extends [infer _0, infer Input extends string] ? TPropertyKey extends [infer _1, infer Input extends string] ? TOptional extends [infer _2, infer Input extends string] ? Static.Token.Const<':', Input> extends [infer _3, infer Input extends string] ? TType extends [infer _4, infer Input extends string] ? [[_0, _1, _2, _3, _4], Input] : [] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TPropertyMapping<_0, Context>, Input] : [] export type TPropertyDelimiter = ( (Static.Token.Const<',', Input> extends [infer _0, infer Input extends string] ? (Static.Token.Const<'\n', Input> extends [infer _1, infer Input extends string] ? [[_0, _1], Input] : []) : []) extends [ infer _0, infer Input extends string, ] ? [_0, Input] : (Static.Token.Const<';', Input> extends [infer _0, infer Input extends string] ? (Static.Token.Const<'\n', Input> extends [infer _1, infer Input extends string] ? [[_0, _1], Input] : []) : []) extends [ infer _0, infer Input extends string, ] ? [_0, Input] : (Static.Token.Const<',', Input> extends [infer _0, infer Input extends string] ? [[_0], Input] : []) extends [infer _0, infer Input extends string] ? [_0, Input] : (Static.Token.Const<';', Input> extends [infer _0, infer Input extends string] ? [[_0], Input] : []) extends [infer _0, infer Input extends string] ? [_0, Input] : (Static.Token.Const<'\n', Input> extends [infer _0, infer Input extends string] ? [[_0], Input] : []) extends [infer _0, infer Input extends string] ? [_0, Input] : [] ) extends [infer _0 extends [unknown, unknown] | [unknown], infer Input extends string] ? [S.TPropertyDelimiterMapping<_0, Context>, Input] : [] export type TPropertyList_0 = ( TProperty extends [infer _0, infer Input extends string] ? (TPropertyDelimiter extends [infer _1, infer Input extends string] ? [[_0, _1], Input] : []) : [] ) extends [infer _0, infer Input extends string] ? TPropertyList_0 : [Result, Input] export type TPropertyList = ( TPropertyList_0 extends [infer _0, infer Input extends string] ? ( (TProperty extends [infer _0, infer Input extends string] ? [[_0], Input] : []) extends [infer _0, infer Input extends string] ? [_0, Input] : [[], Input] extends [infer _0, infer Input extends string] ? [_0, Input] : [] ) extends [infer _1, infer Input extends string] ? [[_0, _1], Input] : [] : [] ) extends [infer _0 extends [unknown, unknown], infer Input extends string] ? [S.TPropertyListMapping<_0, Context>, Input] : [] export type TObject = ( Static.Token.Const<'{', Input> extends [infer _0, infer Input extends string] ? TPropertyList extends [infer _1, infer Input extends string] ? Static.Token.Const<'}', Input> extends [infer _2, infer Input extends string] ? [[_0, _1, _2], Input] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown], infer Input extends string] ? [S.TObjectMapping<_0, Context>, Input] : [] export type TElementList_0 = ( TType extends [infer _0, infer Input extends string] ? (Static.Token.Const<',', Input> extends [infer _1, infer Input extends string] ? [[_0, _1], Input] : []) : [] ) extends [infer _0, infer Input extends string] ? TElementList_0 : [Result, Input] export type TElementList = ( TElementList_0 extends [infer _0, infer Input extends string] ? ( (TType extends [infer _0, infer Input extends string] ? [[_0], Input] : []) extends [infer _0, infer Input extends string] ? [_0, Input] : [[], Input] extends [infer _0, infer Input extends string] ? [_0, Input] : [] ) extends [infer _1, infer Input extends string] ? [[_0, _1], Input] : [] : [] ) extends [infer _0 extends [unknown, unknown], infer Input extends string] ? [S.TElementListMapping<_0, Context>, Input] : [] export type TTuple = ( Static.Token.Const<'[', Input> extends [infer _0, infer Input extends string] ? TElementList extends [infer _1, infer Input extends string] ? Static.Token.Const<']', Input> extends [infer _2, infer Input extends string] ? [[_0, _1, _2], Input] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown], infer Input extends string] ? [S.TTupleMapping<_0, Context>, Input] : [] export type TParameter = ( Static.Token.Ident extends [infer _0, infer Input extends string] ? Static.Token.Const<':', Input> extends [infer _1, infer Input extends string] ? TType extends [infer _2, infer Input extends string] ? [[_0, _1, _2], Input] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown], infer Input extends string] ? [S.TParameterMapping<_0, Context>, Input] : [] export type TParameterList_0 = ( TParameter extends [infer _0, infer Input extends string] ? (Static.Token.Const<',', Input> extends [infer _1, infer Input extends string] ? [[_0, _1], Input] : []) : [] ) extends [infer _0, infer Input extends string] ? TParameterList_0 : [Result, Input] export type TParameterList = ( TParameterList_0 extends [infer _0, infer Input extends string] ? ( (TParameter extends [infer _0, infer Input extends string] ? [[_0], Input] : []) extends [infer _0, infer Input extends string] ? [_0, Input] : [[], Input] extends [infer _0, infer Input extends string] ? [_0, Input] : [] ) extends [infer _1, infer Input extends string] ? [[_0, _1], Input] : [] : [] ) extends [infer _0 extends [unknown, unknown], infer Input extends string] ? [S.TParameterListMapping<_0, Context>, Input] : [] export type TFunction = ( Static.Token.Const<'(', Input> extends [infer _0, infer Input extends string] ? TParameterList extends [infer _1, infer Input extends string] ? Static.Token.Const<')', Input> extends [infer _2, infer Input extends string] ? Static.Token.Const<'=>', Input> extends [infer _3, infer Input extends string] ? TType extends [infer _4, infer Input extends string] ? [[_0, _1, _2, _3, _4], Input] : [] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TFunctionMapping<_0, Context>, Input] : [] export type TConstructor = ( Static.Token.Const<'new', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'(', Input> extends [infer _1, infer Input extends string] ? TParameterList extends [infer _2, infer Input extends string] ? Static.Token.Const<')', Input> extends [infer _3, infer Input extends string] ? Static.Token.Const<'=>', Input> extends [infer _4, infer Input extends string] ? TType extends [infer _5, infer Input extends string] ? [[_0, _1, _2, _3, _4, _5], Input] : [] : [] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TConstructorMapping<_0, Context>, Input] : [] export type TMapped = ( Static.Token.Const<'{', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'[', Input> extends [infer _1, infer Input extends string] ? Static.Token.Ident extends [infer _2, infer Input extends string] ? Static.Token.Const<'in', Input> extends [infer _3, infer Input extends string] ? TType extends [infer _4, infer Input extends string] ? Static.Token.Const<']', Input> extends [infer _5, infer Input extends string] ? Static.Token.Const<':', Input> extends [infer _6, infer Input extends string] ? TType extends [infer _7, infer Input extends string] ? Static.Token.Const<'}', Input> extends [infer _8, infer Input extends string] ? [[_0, _1, _2, _3, _4, _5, _6, _7, _8], Input] : [] : [] : [] : [] : [] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TMappedMapping<_0, Context>, Input] : [] export type TAsyncIterator = ( Static.Token.Const<'AsyncIterator', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'<', Input> extends [infer _1, infer Input extends string] ? TType extends [infer _2, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _3, infer Input extends string] ? [[_0, _1, _2, _3], Input] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TAsyncIteratorMapping<_0, Context>, Input] : [] export type TIterator = ( Static.Token.Const<'Iterator', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'<', Input> extends [infer _1, infer Input extends string] ? TType extends [infer _2, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _3, infer Input extends string] ? [[_0, _1, _2, _3], Input] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TIteratorMapping<_0, Context>, Input] : [] export type TArgument = ( Static.Token.Const<'Argument', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'<', Input> extends [infer _1, infer Input extends string] ? TType extends [infer _2, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _3, infer Input extends string] ? [[_0, _1, _2, _3], Input] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TArgumentMapping<_0, Context>, Input] : [] export type TAwaited = ( Static.Token.Const<'Awaited', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'<', Input> extends [infer _1, infer Input extends string] ? TType extends [infer _2, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _3, infer Input extends string] ? [[_0, _1, _2, _3], Input] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TAwaitedMapping<_0, Context>, Input] : [] export type TArray = ( Static.Token.Const<'Array', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'<', Input> extends [infer _1, infer Input extends string] ? TType extends [infer _2, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _3, infer Input extends string] ? [[_0, _1, _2, _3], Input] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TArrayMapping<_0, Context>, Input] : [] export type TRecord = ( Static.Token.Const<'Record', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'<', Input> extends [infer _1, infer Input extends string] ? TType extends [infer _2, infer Input extends string] ? Static.Token.Const<',', Input> extends [infer _3, infer Input extends string] ? TType extends [infer _4, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _5, infer Input extends string] ? [[_0, _1, _2, _3, _4, _5], Input] : [] : [] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TRecordMapping<_0, Context>, Input] : [] export type TPromise = ( Static.Token.Const<'Promise', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'<', Input> extends [infer _1, infer Input extends string] ? TType extends [infer _2, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _3, infer Input extends string] ? [[_0, _1, _2, _3], Input] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TPromiseMapping<_0, Context>, Input] : [] export type TConstructorParameters = ( Static.Token.Const<'ConstructorParameters', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'<', Input> extends [infer _1, infer Input extends string] ? TType extends [infer _2, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _3, infer Input extends string] ? [[_0, _1, _2, _3], Input] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TConstructorParametersMapping<_0, Context>, Input] : [] export type TFunctionParameters = ( Static.Token.Const<'Parameters', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'<', Input> extends [infer _1, infer Input extends string] ? TType extends [infer _2, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _3, infer Input extends string] ? [[_0, _1, _2, _3], Input] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TFunctionParametersMapping<_0, Context>, Input] : [] export type TInstanceType = ( Static.Token.Const<'InstanceType', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'<', Input> extends [infer _1, infer Input extends string] ? TType extends [infer _2, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _3, infer Input extends string] ? [[_0, _1, _2, _3], Input] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TInstanceTypeMapping<_0, Context>, Input] : [] export type TReturnType = ( Static.Token.Const<'ReturnType', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'<', Input> extends [infer _1, infer Input extends string] ? TType extends [infer _2, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _3, infer Input extends string] ? [[_0, _1, _2, _3], Input] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TReturnTypeMapping<_0, Context>, Input] : [] export type TPartial = ( Static.Token.Const<'Partial', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'<', Input> extends [infer _1, infer Input extends string] ? TType extends [infer _2, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _3, infer Input extends string] ? [[_0, _1, _2, _3], Input] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TPartialMapping<_0, Context>, Input] : [] export type TRequired = ( Static.Token.Const<'Required', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'<', Input> extends [infer _1, infer Input extends string] ? TType extends [infer _2, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _3, infer Input extends string] ? [[_0, _1, _2, _3], Input] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TRequiredMapping<_0, Context>, Input] : [] export type TPick = ( Static.Token.Const<'Pick', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'<', Input> extends [infer _1, infer Input extends string] ? TType extends [infer _2, infer Input extends string] ? Static.Token.Const<',', Input> extends [infer _3, infer Input extends string] ? TType extends [infer _4, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _5, infer Input extends string] ? [[_0, _1, _2, _3, _4, _5], Input] : [] : [] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TPickMapping<_0, Context>, Input] : [] export type TOmit = ( Static.Token.Const<'Omit', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'<', Input> extends [infer _1, infer Input extends string] ? TType extends [infer _2, infer Input extends string] ? Static.Token.Const<',', Input> extends [infer _3, infer Input extends string] ? TType extends [infer _4, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _5, infer Input extends string] ? [[_0, _1, _2, _3, _4, _5], Input] : [] : [] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TOmitMapping<_0, Context>, Input] : [] export type TExclude = ( Static.Token.Const<'Exclude', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'<', Input> extends [infer _1, infer Input extends string] ? TType extends [infer _2, infer Input extends string] ? Static.Token.Const<',', Input> extends [infer _3, infer Input extends string] ? TType extends [infer _4, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _5, infer Input extends string] ? [[_0, _1, _2, _3, _4, _5], Input] : [] : [] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TExcludeMapping<_0, Context>, Input] : [] export type TExtract = ( Static.Token.Const<'Extract', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'<', Input> extends [infer _1, infer Input extends string] ? TType extends [infer _2, infer Input extends string] ? Static.Token.Const<',', Input> extends [infer _3, infer Input extends string] ? TType extends [infer _4, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _5, infer Input extends string] ? [[_0, _1, _2, _3, _4, _5], Input] : [] : [] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TExtractMapping<_0, Context>, Input] : [] export type TUppercase = ( Static.Token.Const<'Uppercase', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'<', Input> extends [infer _1, infer Input extends string] ? TType extends [infer _2, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _3, infer Input extends string] ? [[_0, _1, _2, _3], Input] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TUppercaseMapping<_0, Context>, Input] : [] export type TLowercase = ( Static.Token.Const<'Lowercase', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'<', Input> extends [infer _1, infer Input extends string] ? TType extends [infer _2, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _3, infer Input extends string] ? [[_0, _1, _2, _3], Input] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TLowercaseMapping<_0, Context>, Input] : [] export type TCapitalize = ( Static.Token.Const<'Capitalize', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'<', Input> extends [infer _1, infer Input extends string] ? TType extends [infer _2, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _3, infer Input extends string] ? [[_0, _1, _2, _3], Input] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TCapitalizeMapping<_0, Context>, Input] : [] export type TUncapitalize = ( Static.Token.Const<'Uncapitalize', Input> extends [infer _0, infer Input extends string] ? Static.Token.Const<'<', Input> extends [infer _1, infer Input extends string] ? TType extends [infer _2, infer Input extends string] ? Static.Token.Const<'>', Input> extends [infer _3, infer Input extends string] ? [[_0, _1, _2, _3], Input] : [] : [] : [] : [] ) extends [infer _0 extends [unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TUncapitalizeMapping<_0, Context>, Input] : [] export type TDate = Static.Token.Const<'Date', Input> extends [infer _0 extends 'Date', infer Input extends string] ? [S.TDateMapping<_0, Context>, Input] : [] export type TUint8Array = Static.Token.Const<'Uint8Array', Input> extends [infer _0 extends 'Uint8Array', infer Input extends string] ? [S.TUint8ArrayMapping<_0, Context>, Input] : [] export type TReference = Static.Token.Ident extends [infer _0 extends string, infer Input extends string] ? [S.TReferenceMapping<_0, Context>, Input] : [] const If = (result: [unknown, string] | [], left: (input: [unknown, string]) => [unknown, string] | [], right: () => [unknown, string] | [] = () => []): [unknown, string] | [] => (result.length === 2 ? left(result) : right()) export const GenericReferenceParameterList_0 = (input: string, context: T.TProperties, result: unknown[] = []): [unknown[], string] => If( If(Type(input, context), ([_0, input]) => If(Runtime.Token.Const(',', input), ([_1, input]) => [[_0, _1], input])), ([_0, input]) => GenericReferenceParameterList_0(input, context, [...result, _0]), () => [result, input], ) as [unknown[], string] export const GenericReferenceParameterList = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(GenericReferenceParameterList_0(input, context), ([_0, input]) => If( If( If(Type(input, context), ([_0, input]) => [[_0], input]), ([_0, input]) => [_0, input], () => If( [[], input], ([_0, input]) => [_0, input], () => [], ), ), ([_1, input]) => [[_0, _1], input], ), ), ([_0, input]) => [S.GenericReferenceParameterListMapping(_0 as [unknown, unknown], context), input], ) export const GenericReference = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Ident(input), ([_0, input]) => If(Runtime.Token.Const('<', input), ([_1, input]) => If(GenericReferenceParameterList(input, context), ([_2, input]) => If(Runtime.Token.Const('>', input), ([_3, input]) => [[_0, _1, _2, _3], input]))), ), ([_0, input]) => [S.GenericReferenceMapping(_0 as [unknown, unknown, unknown, unknown], context), input], ) export const GenericArgumentsList_0 = (input: string, context: T.TProperties, result: unknown[] = []): [unknown[], string] => If( If(Runtime.Token.Ident(input), ([_0, input]) => If(Runtime.Token.Const(',', input), ([_1, input]) => [[_0, _1], input])), ([_0, input]) => GenericArgumentsList_0(input, context, [...result, _0]), () => [result, input], ) as [unknown[], string] export const GenericArgumentsList = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(GenericArgumentsList_0(input, context), ([_0, input]) => If( If( If(Runtime.Token.Ident(input), ([_0, input]) => [[_0], input]), ([_0, input]) => [_0, input], () => If( [[], input], ([_0, input]) => [_0, input], () => [], ), ), ([_1, input]) => [[_0, _1], input], ), ), ([_0, input]) => [S.GenericArgumentsListMapping(_0 as [unknown, unknown], context), input], ) export const GenericArguments = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('<', input), ([_0, input]) => If(GenericArgumentsList(input, context), ([_1, input]) => If(Runtime.Token.Const('>', input), ([_2, input]) => [[_0, _1, _2], input]))), ([_0, input]) => [S.GenericArgumentsMapping(_0 as [unknown, unknown, unknown], context), input], ) export const KeywordString = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If(Runtime.Token.Const('string', input), ([_0, input]) => [S.KeywordStringMapping(_0 as 'string', context), input]) export const KeywordNumber = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If(Runtime.Token.Const('number', input), ([_0, input]) => [S.KeywordNumberMapping(_0 as 'number', context), input]) export const KeywordBoolean = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If(Runtime.Token.Const('boolean', input), ([_0, input]) => [S.KeywordBooleanMapping(_0 as 'boolean', context), input]) export const KeywordUndefined = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If(Runtime.Token.Const('undefined', input), ([_0, input]) => [S.KeywordUndefinedMapping(_0 as 'undefined', context), input]) export const KeywordNull = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If(Runtime.Token.Const('null', input), ([_0, input]) => [S.KeywordNullMapping(_0 as 'null', context), input]) export const KeywordInteger = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If(Runtime.Token.Const('integer', input), ([_0, input]) => [S.KeywordIntegerMapping(_0 as 'integer', context), input]) export const KeywordBigInt = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If(Runtime.Token.Const('bigint', input), ([_0, input]) => [S.KeywordBigIntMapping(_0 as 'bigint', context), input]) export const KeywordUnknown = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If(Runtime.Token.Const('unknown', input), ([_0, input]) => [S.KeywordUnknownMapping(_0 as 'unknown', context), input]) export const KeywordAny = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If(Runtime.Token.Const('any', input), ([_0, input]) => [S.KeywordAnyMapping(_0 as 'any', context), input]) export const KeywordNever = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If(Runtime.Token.Const('never', input), ([_0, input]) => [S.KeywordNeverMapping(_0 as 'never', context), input]) export const KeywordSymbol = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If(Runtime.Token.Const('symbol', input), ([_0, input]) => [S.KeywordSymbolMapping(_0 as 'symbol', context), input]) export const KeywordVoid = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If(Runtime.Token.Const('void', input), ([_0, input]) => [S.KeywordVoidMapping(_0 as 'void', context), input]) export const Keyword = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If( KeywordString(input, context), ([_0, input]) => [_0, input], () => If( KeywordNumber(input, context), ([_0, input]) => [_0, input], () => If( KeywordBoolean(input, context), ([_0, input]) => [_0, input], () => If( KeywordUndefined(input, context), ([_0, input]) => [_0, input], () => If( KeywordNull(input, context), ([_0, input]) => [_0, input], () => If( KeywordInteger(input, context), ([_0, input]) => [_0, input], () => If( KeywordBigInt(input, context), ([_0, input]) => [_0, input], () => If( KeywordUnknown(input, context), ([_0, input]) => [_0, input], () => If( KeywordAny(input, context), ([_0, input]) => [_0, input], () => If( KeywordNever(input, context), ([_0, input]) => [_0, input], () => If( KeywordSymbol(input, context), ([_0, input]) => [_0, input], () => If( KeywordVoid(input, context), ([_0, input]) => [_0, input], () => [], ), ), ), ), ), ), ), ), ), ), ), ), ([_0, input]) => [S.KeywordMapping(_0 as unknown, context), input], ) export const LiteralString = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If(Runtime.Token.String(["'", '"', '`'], input), ([_0, input]) => [S.LiteralStringMapping(_0 as string, context), input]) export const LiteralNumber = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If(Runtime.Token.Number(input), ([_0, input]) => [S.LiteralNumberMapping(_0 as string, context), input]) export const LiteralBoolean = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If( Runtime.Token.Const('true', input), ([_0, input]) => [_0, input], () => If( Runtime.Token.Const('false', input), ([_0, input]) => [_0, input], () => [], ), ), ([_0, input]) => [S.LiteralBooleanMapping(_0 as 'true' | 'false', context), input], ) export const Literal = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If( LiteralBoolean(input, context), ([_0, input]) => [_0, input], () => If( LiteralNumber(input, context), ([_0, input]) => [_0, input], () => If( LiteralString(input, context), ([_0, input]) => [_0, input], () => [], ), ), ), ([_0, input]) => [S.LiteralMapping(_0 as unknown, context), input], ) export const KeyOf = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If( If(Runtime.Token.Const('keyof', input), ([_0, input]) => [[_0], input]), ([_0, input]) => [_0, input], () => If( [[], input], ([_0, input]) => [_0, input], () => [], ), ), ([_0, input]) => [S.KeyOfMapping(_0 as [unknown] | [], context), input], ) export const IndexArray_0 = (input: string, context: T.TProperties, result: unknown[] = []): [unknown[], string] => If( If( If(Runtime.Token.Const('[', input), ([_0, input]) => If(Type(input, context), ([_1, input]) => If(Runtime.Token.Const(']', input), ([_2, input]) => [[_0, _1, _2], input]))), ([_0, input]) => [_0, input], () => If( If(Runtime.Token.Const('[', input), ([_0, input]) => If(Runtime.Token.Const(']', input), ([_1, input]) => [[_0, _1], input])), ([_0, input]) => [_0, input], () => [], ), ), ([_0, input]) => IndexArray_0(input, context, [...result, _0]), () => [result, input], ) as [unknown[], string] export const IndexArray = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If(IndexArray_0(input, context), ([_0, input]) => [S.IndexArrayMapping(_0 as ([unknown, unknown, unknown] | [unknown, unknown])[], context), input]) export const Extends = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If( If(Runtime.Token.Const('extends', input), ([_0, input]) => If(Type(input, context), ([_1, input]) => If(Runtime.Token.Const('?', input), ([_2, input]) => If(Type(input, context), ([_3, input]) => If(Runtime.Token.Const(':', input), ([_4, input]) => If(Type(input, context), ([_5, input]) => [[_0, _1, _2, _3, _4, _5], input])))), ), ), ([_0, input]) => [_0, input], () => If( [[], input], ([_0, input]) => [_0, input], () => [], ), ), ([_0, input]) => [S.ExtendsMapping(_0 as [unknown, unknown, unknown, unknown, unknown, unknown] | [], context), input], ) export const Base = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If( If(Runtime.Token.Const('(', input), ([_0, input]) => If(Type(input, context), ([_1, input]) => If(Runtime.Token.Const(')', input), ([_2, input]) => [[_0, _1, _2], input]))), ([_0, input]) => [_0, input], () => If( Keyword(input, context), ([_0, input]) => [_0, input], () => If( _Object(input, context), ([_0, input]) => [_0, input], () => If( Tuple(input, context), ([_0, input]) => [_0, input], () => If( Literal(input, context), ([_0, input]) => [_0, input], () => If( Constructor(input, context), ([_0, input]) => [_0, input], () => If( Function(input, context), ([_0, input]) => [_0, input], () => If( Mapped(input, context), ([_0, input]) => [_0, input], () => If( AsyncIterator(input, context), ([_0, input]) => [_0, input], () => If( Iterator(input, context), ([_0, input]) => [_0, input], () => If( ConstructorParameters(input, context), ([_0, input]) => [_0, input], () => If( FunctionParameters(input, context), ([_0, input]) => [_0, input], () => If( InstanceType(input, context), ([_0, input]) => [_0, input], () => If( ReturnType(input, context), ([_0, input]) => [_0, input], () => If( Argument(input, context), ([_0, input]) => [_0, input], () => If( Awaited(input, context), ([_0, input]) => [_0, input], () => If( Array(input, context), ([_0, input]) => [_0, input], () => If( Record(input, context), ([_0, input]) => [_0, input], () => If( Promise(input, context), ([_0, input]) => [_0, input], () => If( Partial(input, context), ([_0, input]) => [_0, input], () => If( Required(input, context), ([_0, input]) => [_0, input], () => If( Pick(input, context), ([_0, input]) => [_0, input], () => If( Omit(input, context), ([_0, input]) => [_0, input], () => If( Exclude(input, context), ([_0, input]) => [_0, input], () => If( Extract(input, context), ([_0, input]) => [_0, input], () => If( Uppercase(input, context), ([_0, input]) => [_0, input], () => If( Lowercase(input, context), ([_0, input]) => [_0, input], () => If( Capitalize(input, context), ([_0, input]) => [_0, input], () => If( Uncapitalize(input, context), ([_0, input]) => [_0, input], () => If( Date(input, context), ([_0, input]) => [_0, input], () => If( Uint8Array(input, context), ([_0, input]) => [_0, input], () => If( GenericReference(input, context), ([_0, input]) => [_0, input], () => If( Reference(input, context), ([_0, input]) => [_0, input], () => [], ), ), ), ), ), ), ), ), ), ), ), ), ), ), ), ), ), ), ), ), ), ), ), ), ), ), ), ), ), ), ), ), ), ([_0, input]) => [S.BaseMapping(_0 as [unknown, unknown, unknown] | unknown, context), input], ) export const Factor = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(KeyOf(input, context), ([_0, input]) => If(Base(input, context), ([_1, input]) => If(IndexArray(input, context), ([_2, input]) => If(Extends(input, context), ([_3, input]) => [[_0, _1, _2, _3], input])))), ([_0, input]) => [S.FactorMapping(_0 as [unknown, unknown, unknown, unknown], context), input], ) export const ExprTermTail = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If( If(Runtime.Token.Const('&', input), ([_0, input]) => If(Factor(input, context), ([_1, input]) => If(ExprTermTail(input, context), ([_2, input]) => [[_0, _1, _2], input]))), ([_0, input]) => [_0, input], () => If( [[], input], ([_0, input]) => [_0, input], () => [], ), ), ([_0, input]) => [S.ExprTermTailMapping(_0 as [unknown, unknown, unknown] | [], context), input], ) export const ExprTerm = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Factor(input, context), ([_0, input]) => If(ExprTermTail(input, context), ([_1, input]) => [[_0, _1], input])), ([_0, input]) => [S.ExprTermMapping(_0 as [unknown, unknown], context), input], ) export const ExprTail = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If( If(Runtime.Token.Const('|', input), ([_0, input]) => If(ExprTerm(input, context), ([_1, input]) => If(ExprTail(input, context), ([_2, input]) => [[_0, _1, _2], input]))), ([_0, input]) => [_0, input], () => If( [[], input], ([_0, input]) => [_0, input], () => [], ), ), ([_0, input]) => [S.ExprTailMapping(_0 as [unknown, unknown, unknown] | [], context), input], ) export const Expr = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(ExprTerm(input, context), ([_0, input]) => If(ExprTail(input, context), ([_1, input]) => [[_0, _1], input])), ([_0, input]) => [S.ExprMapping(_0 as [unknown, unknown], context), input], ) export const Type = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If( If( GenericArguments(input, context), ([_0, input]) => Expr(input, _0 as T.TProperties), () => [], ), ([_0, input]) => [_0, input], () => If( Expr(input, context), ([_0, input]) => [_0, input], () => [], ), ), ([_0, input]) => [S.TypeMapping(_0 as unknown, context), input], ) export const PropertyKey = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If( Runtime.Token.Ident(input), ([_0, input]) => [_0, input], () => If( Runtime.Token.String(["'", '"'], input), ([_0, input]) => [_0, input], () => [], ), ), ([_0, input]) => [S.PropertyKeyMapping(_0 as string, context), input], ) export const Readonly = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If( If(Runtime.Token.Const('readonly', input), ([_0, input]) => [[_0], input]), ([_0, input]) => [_0, input], () => If( [[], input], ([_0, input]) => [_0, input], () => [], ), ), ([_0, input]) => [S.ReadonlyMapping(_0 as [unknown] | [], context), input], ) export const Optional = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If( If(Runtime.Token.Const('?', input), ([_0, input]) => [[_0], input]), ([_0, input]) => [_0, input], () => If( [[], input], ([_0, input]) => [_0, input], () => [], ), ), ([_0, input]) => [S.OptionalMapping(_0 as [unknown] | [], context), input], ) export const Property = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Readonly(input, context), ([_0, input]) => If(PropertyKey(input, context), ([_1, input]) => If(Optional(input, context), ([_2, input]) => If(Runtime.Token.Const(':', input), ([_3, input]) => If(Type(input, context), ([_4, input]) => [[_0, _1, _2, _3, _4], input])))), ), ([_0, input]) => [S.PropertyMapping(_0 as [unknown, unknown, unknown, unknown, unknown], context), input], ) export const PropertyDelimiter = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If( If(Runtime.Token.Const(',', input), ([_0, input]) => If(Runtime.Token.Const('\n', input), ([_1, input]) => [[_0, _1], input])), ([_0, input]) => [_0, input], () => If( If(Runtime.Token.Const(';', input), ([_0, input]) => If(Runtime.Token.Const('\n', input), ([_1, input]) => [[_0, _1], input])), ([_0, input]) => [_0, input], () => If( If(Runtime.Token.Const(',', input), ([_0, input]) => [[_0], input]), ([_0, input]) => [_0, input], () => If( If(Runtime.Token.Const(';', input), ([_0, input]) => [[_0], input]), ([_0, input]) => [_0, input], () => If( If(Runtime.Token.Const('\n', input), ([_0, input]) => [[_0], input]), ([_0, input]) => [_0, input], () => [], ), ), ), ), ), ([_0, input]) => [S.PropertyDelimiterMapping(_0 as [unknown, unknown] | [unknown], context), input], ) export const PropertyList_0 = (input: string, context: T.TProperties, result: unknown[] = []): [unknown[], string] => If( If(Property(input, context), ([_0, input]) => If(PropertyDelimiter(input, context), ([_1, input]) => [[_0, _1], input])), ([_0, input]) => PropertyList_0(input, context, [...result, _0]), () => [result, input], ) as [unknown[], string] export const PropertyList = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(PropertyList_0(input, context), ([_0, input]) => If( If( If(Property(input, context), ([_0, input]) => [[_0], input]), ([_0, input]) => [_0, input], () => If( [[], input], ([_0, input]) => [_0, input], () => [], ), ), ([_1, input]) => [[_0, _1], input], ), ), ([_0, input]) => [S.PropertyListMapping(_0 as [unknown, unknown], context), input], ) export const _Object = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('{', input), ([_0, input]) => If(PropertyList(input, context), ([_1, input]) => If(Runtime.Token.Const('}', input), ([_2, input]) => [[_0, _1, _2], input]))), ([_0, input]) => [S.ObjectMapping(_0 as [unknown, unknown, unknown], context), input], ) export const ElementList_0 = (input: string, context: T.TProperties, result: unknown[] = []): [unknown[], string] => If( If(Type(input, context), ([_0, input]) => If(Runtime.Token.Const(',', input), ([_1, input]) => [[_0, _1], input])), ([_0, input]) => ElementList_0(input, context, [...result, _0]), () => [result, input], ) as [unknown[], string] export const ElementList = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(ElementList_0(input, context), ([_0, input]) => If( If( If(Type(input, context), ([_0, input]) => [[_0], input]), ([_0, input]) => [_0, input], () => If( [[], input], ([_0, input]) => [_0, input], () => [], ), ), ([_1, input]) => [[_0, _1], input], ), ), ([_0, input]) => [S.ElementListMapping(_0 as [unknown, unknown], context), input], ) export const Tuple = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('[', input), ([_0, input]) => If(ElementList(input, context), ([_1, input]) => If(Runtime.Token.Const(']', input), ([_2, input]) => [[_0, _1, _2], input]))), ([_0, input]) => [S.TupleMapping(_0 as [unknown, unknown, unknown], context), input], ) export const Parameter = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Ident(input), ([_0, input]) => If(Runtime.Token.Const(':', input), ([_1, input]) => If(Type(input, context), ([_2, input]) => [[_0, _1, _2], input]))), ([_0, input]) => [S.ParameterMapping(_0 as [unknown, unknown, unknown], context), input], ) export const ParameterList_0 = (input: string, context: T.TProperties, result: unknown[] = []): [unknown[], string] => If( If(Parameter(input, context), ([_0, input]) => If(Runtime.Token.Const(',', input), ([_1, input]) => [[_0, _1], input])), ([_0, input]) => ParameterList_0(input, context, [...result, _0]), () => [result, input], ) as [unknown[], string] export const ParameterList = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(ParameterList_0(input, context), ([_0, input]) => If( If( If(Parameter(input, context), ([_0, input]) => [[_0], input]), ([_0, input]) => [_0, input], () => If( [[], input], ([_0, input]) => [_0, input], () => [], ), ), ([_1, input]) => [[_0, _1], input], ), ), ([_0, input]) => [S.ParameterListMapping(_0 as [unknown, unknown], context), input], ) export const Function = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('(', input), ([_0, input]) => If(ParameterList(input, context), ([_1, input]) => If(Runtime.Token.Const(')', input), ([_2, input]) => If(Runtime.Token.Const('=>', input), ([_3, input]) => If(Type(input, context), ([_4, input]) => [[_0, _1, _2, _3, _4], input])))), ), ([_0, input]) => [S.FunctionMapping(_0 as [unknown, unknown, unknown, unknown, unknown], context), input], ) export const Constructor = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('new', input), ([_0, input]) => If(Runtime.Token.Const('(', input), ([_1, input]) => If(ParameterList(input, context), ([_2, input]) => If(Runtime.Token.Const(')', input), ([_3, input]) => If(Runtime.Token.Const('=>', input), ([_4, input]) => If(Type(input, context), ([_5, input]) => [[_0, _1, _2, _3, _4, _5], input]))), ), ), ), ([_0, input]) => [S.ConstructorMapping(_0 as [unknown, unknown, unknown, unknown, unknown, unknown], context), input], ) export const Mapped = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('{', input), ([_0, input]) => If(Runtime.Token.Const('[', input), ([_1, input]) => If(Runtime.Token.Ident(input), ([_2, input]) => If(Runtime.Token.Const('in', input), ([_3, input]) => If(Type(input, context), ([_4, input]) => If(Runtime.Token.Const(']', input), ([_5, input]) => If(Runtime.Token.Const(':', input), ([_6, input]) => If(Type(input, context), ([_7, input]) => If(Runtime.Token.Const('}', input), ([_8, input]) => [[_0, _1, _2, _3, _4, _5, _6, _7, _8], input]))), ), ), ), ), ), ), ([_0, input]) => [S.MappedMapping(_0 as [unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown], context), input], ) export const AsyncIterator = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('AsyncIterator', input), ([_0, input]) => If(Runtime.Token.Const('<', input), ([_1, input]) => If(Type(input, context), ([_2, input]) => If(Runtime.Token.Const('>', input), ([_3, input]) => [[_0, _1, _2, _3], input]))), ), ([_0, input]) => [S.AsyncIteratorMapping(_0 as [unknown, unknown, unknown, unknown], context), input], ) export const Iterator = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('Iterator', input), ([_0, input]) => If(Runtime.Token.Const('<', input), ([_1, input]) => If(Type(input, context), ([_2, input]) => If(Runtime.Token.Const('>', input), ([_3, input]) => [[_0, _1, _2, _3], input]))), ), ([_0, input]) => [S.IteratorMapping(_0 as [unknown, unknown, unknown, unknown], context), input], ) export const Argument = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('Argument', input), ([_0, input]) => If(Runtime.Token.Const('<', input), ([_1, input]) => If(Type(input, context), ([_2, input]) => If(Runtime.Token.Const('>', input), ([_3, input]) => [[_0, _1, _2, _3], input]))), ), ([_0, input]) => [S.ArgumentMapping(_0 as [unknown, unknown, unknown, unknown], context), input], ) export const Awaited = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('Awaited', input), ([_0, input]) => If(Runtime.Token.Const('<', input), ([_1, input]) => If(Type(input, context), ([_2, input]) => If(Runtime.Token.Const('>', input), ([_3, input]) => [[_0, _1, _2, _3], input]))), ), ([_0, input]) => [S.AwaitedMapping(_0 as [unknown, unknown, unknown, unknown], context), input], ) export const Array = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('Array', input), ([_0, input]) => If(Runtime.Token.Const('<', input), ([_1, input]) => If(Type(input, context), ([_2, input]) => If(Runtime.Token.Const('>', input), ([_3, input]) => [[_0, _1, _2, _3], input])))), ([_0, input]) => [S.ArrayMapping(_0 as [unknown, unknown, unknown, unknown], context), input], ) export const Record = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('Record', input), ([_0, input]) => If(Runtime.Token.Const('<', input), ([_1, input]) => If(Type(input, context), ([_2, input]) => If(Runtime.Token.Const(',', input), ([_3, input]) => If(Type(input, context), ([_4, input]) => If(Runtime.Token.Const('>', input), ([_5, input]) => [[_0, _1, _2, _3, _4, _5], input])))), ), ), ([_0, input]) => [S.RecordMapping(_0 as [unknown, unknown, unknown, unknown, unknown, unknown], context), input], ) export const Promise = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('Promise', input), ([_0, input]) => If(Runtime.Token.Const('<', input), ([_1, input]) => If(Type(input, context), ([_2, input]) => If(Runtime.Token.Const('>', input), ([_3, input]) => [[_0, _1, _2, _3], input]))), ), ([_0, input]) => [S.PromiseMapping(_0 as [unknown, unknown, unknown, unknown], context), input], ) export const ConstructorParameters = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('ConstructorParameters', input), ([_0, input]) => If(Runtime.Token.Const('<', input), ([_1, input]) => If(Type(input, context), ([_2, input]) => If(Runtime.Token.Const('>', input), ([_3, input]) => [[_0, _1, _2, _3], input]))), ), ([_0, input]) => [S.ConstructorParametersMapping(_0 as [unknown, unknown, unknown, unknown], context), input], ) export const FunctionParameters = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('Parameters', input), ([_0, input]) => If(Runtime.Token.Const('<', input), ([_1, input]) => If(Type(input, context), ([_2, input]) => If(Runtime.Token.Const('>', input), ([_3, input]) => [[_0, _1, _2, _3], input]))), ), ([_0, input]) => [S.FunctionParametersMapping(_0 as [unknown, unknown, unknown, unknown], context), input], ) export const InstanceType = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('InstanceType', input), ([_0, input]) => If(Runtime.Token.Const('<', input), ([_1, input]) => If(Type(input, context), ([_2, input]) => If(Runtime.Token.Const('>', input), ([_3, input]) => [[_0, _1, _2, _3], input]))), ), ([_0, input]) => [S.InstanceTypeMapping(_0 as [unknown, unknown, unknown, unknown], context), input], ) export const ReturnType = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('ReturnType', input), ([_0, input]) => If(Runtime.Token.Const('<', input), ([_1, input]) => If(Type(input, context), ([_2, input]) => If(Runtime.Token.Const('>', input), ([_3, input]) => [[_0, _1, _2, _3], input]))), ), ([_0, input]) => [S.ReturnTypeMapping(_0 as [unknown, unknown, unknown, unknown], context), input], ) export const Partial = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('Partial', input), ([_0, input]) => If(Runtime.Token.Const('<', input), ([_1, input]) => If(Type(input, context), ([_2, input]) => If(Runtime.Token.Const('>', input), ([_3, input]) => [[_0, _1, _2, _3], input]))), ), ([_0, input]) => [S.PartialMapping(_0 as [unknown, unknown, unknown, unknown], context), input], ) export const Required = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('Required', input), ([_0, input]) => If(Runtime.Token.Const('<', input), ([_1, input]) => If(Type(input, context), ([_2, input]) => If(Runtime.Token.Const('>', input), ([_3, input]) => [[_0, _1, _2, _3], input]))), ), ([_0, input]) => [S.RequiredMapping(_0 as [unknown, unknown, unknown, unknown], context), input], ) export const Pick = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('Pick', input), ([_0, input]) => If(Runtime.Token.Const('<', input), ([_1, input]) => If(Type(input, context), ([_2, input]) => If(Runtime.Token.Const(',', input), ([_3, input]) => If(Type(input, context), ([_4, input]) => If(Runtime.Token.Const('>', input), ([_5, input]) => [[_0, _1, _2, _3, _4, _5], input])))), ), ), ([_0, input]) => [S.PickMapping(_0 as [unknown, unknown, unknown, unknown, unknown, unknown], context), input], ) export const Omit = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('Omit', input), ([_0, input]) => If(Runtime.Token.Const('<', input), ([_1, input]) => If(Type(input, context), ([_2, input]) => If(Runtime.Token.Const(',', input), ([_3, input]) => If(Type(input, context), ([_4, input]) => If(Runtime.Token.Const('>', input), ([_5, input]) => [[_0, _1, _2, _3, _4, _5], input])))), ), ), ([_0, input]) => [S.OmitMapping(_0 as [unknown, unknown, unknown, unknown, unknown, unknown], context), input], ) export const Exclude = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('Exclude', input), ([_0, input]) => If(Runtime.Token.Const('<', input), ([_1, input]) => If(Type(input, context), ([_2, input]) => If(Runtime.Token.Const(',', input), ([_3, input]) => If(Type(input, context), ([_4, input]) => If(Runtime.Token.Const('>', input), ([_5, input]) => [[_0, _1, _2, _3, _4, _5], input])))), ), ), ([_0, input]) => [S.ExcludeMapping(_0 as [unknown, unknown, unknown, unknown, unknown, unknown], context), input], ) export const Extract = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('Extract', input), ([_0, input]) => If(Runtime.Token.Const('<', input), ([_1, input]) => If(Type(input, context), ([_2, input]) => If(Runtime.Token.Const(',', input), ([_3, input]) => If(Type(input, context), ([_4, input]) => If(Runtime.Token.Const('>', input), ([_5, input]) => [[_0, _1, _2, _3, _4, _5], input])))), ), ), ([_0, input]) => [S.ExtractMapping(_0 as [unknown, unknown, unknown, unknown, unknown, unknown], context), input], ) export const Uppercase = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('Uppercase', input), ([_0, input]) => If(Runtime.Token.Const('<', input), ([_1, input]) => If(Type(input, context), ([_2, input]) => If(Runtime.Token.Const('>', input), ([_3, input]) => [[_0, _1, _2, _3], input]))), ), ([_0, input]) => [S.UppercaseMapping(_0 as [unknown, unknown, unknown, unknown], context), input], ) export const Lowercase = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('Lowercase', input), ([_0, input]) => If(Runtime.Token.Const('<', input), ([_1, input]) => If(Type(input, context), ([_2, input]) => If(Runtime.Token.Const('>', input), ([_3, input]) => [[_0, _1, _2, _3], input]))), ), ([_0, input]) => [S.LowercaseMapping(_0 as [unknown, unknown, unknown, unknown], context), input], ) export const Capitalize = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('Capitalize', input), ([_0, input]) => If(Runtime.Token.Const('<', input), ([_1, input]) => If(Type(input, context), ([_2, input]) => If(Runtime.Token.Const('>', input), ([_3, input]) => [[_0, _1, _2, _3], input]))), ), ([_0, input]) => [S.CapitalizeMapping(_0 as [unknown, unknown, unknown, unknown], context), input], ) export const Uncapitalize = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If( If(Runtime.Token.Const('Uncapitalize', input), ([_0, input]) => If(Runtime.Token.Const('<', input), ([_1, input]) => If(Type(input, context), ([_2, input]) => If(Runtime.Token.Const('>', input), ([_3, input]) => [[_0, _1, _2, _3], input]))), ), ([_0, input]) => [S.UncapitalizeMapping(_0 as [unknown, unknown, unknown, unknown], context), input], ) export const Date = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If(Runtime.Token.Const('Date', input), ([_0, input]) => [S.DateMapping(_0 as 'Date', context), input]) export const Uint8Array = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If(Runtime.Token.Const('Uint8Array', input), ([_0, input]) => [S.Uint8ArrayMapping(_0 as 'Uint8Array', context), input]) export const Reference = (input: string, context: T.TProperties = {}): [unknown, string] | [] => If(Runtime.Token.Ident(input), ([_0, input]) => [S.ReferenceMapping(_0 as string, context), input]) sinclairzx81-typebox-e0ec98c/src/syntax/syntax.ts000066400000000000000000000063541505437577000223030ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/syntax The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import * as t from '../type/index' import { Type, TType } from './parser' // ------------------------------------------------------------------ // NoInfer // ------------------------------------------------------------------ /** `[Experimental]` Parses type expressions into TypeBox types but does not infer */ export function NoInfer, Input extends string>(context: Context, input: Input, options?: t.SchemaOptions): t.TSchema /** `[Experimental]` Parses type expressions into TypeBox types but does not infer */ export function NoInfer(input: Input, options?: t.SchemaOptions): t.TSchema /** `[Experimental]` Parses type expressions into TypeBox types but does not infer */ // prettier-ignore export function NoInfer(...args: any[]): t.TSchema { const withContext = typeof args[0] === 'string' ? false : true const [context, code, options] = withContext ? [args[0], args[1], args[2] || {}] : [{}, args[0], args[1] || {}] const result = Type(code, context)[0] return t.KindGuard.IsSchema(result) ? t.CloneType(result, options) : t.Never(options) } /** `[Experimental]` Parses type expressions into TypeBox types */ // prettier-ignore export type TSyntax, Code extends string> = ( TType extends [infer Type extends t.TSchema, string] ? Type : t.TNever ) /** `[Experimental]` Parses type expressions into TypeBox types */ export function Syntax, Input extends string>(context: Context, input: Input, options?: t.SchemaOptions): TSyntax /** `[Experimental]` Parses type expressions into TypeBox types */ export function Syntax(annotation: Input, options?: t.SchemaOptions): TSyntax<{}, Input> /** `[Experimental]` Parses type expressions into TypeBox types */ export function Syntax(...args: any[]): never { return NoInfer.apply(null, args as never) as never } sinclairzx81-typebox-e0ec98c/src/system/000077500000000000000000000000001505437577000203735ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/system/index.ts000066400000000000000000000025171505437577000220570ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/system The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './policy' export * from './system' sinclairzx81-typebox-e0ec98c/src/system/policy.ts000066400000000000000000000102731505437577000222450ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/system The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { IsObject, IsArray, IsNumber, IsUndefined } from '../value/guard/index' export namespace TypeSystemPolicy { // ------------------------------------------------------------------ // TypeSystemPolicy: Instancing // ------------------------------------------------------------------ /** * Configures the instantiation behavior of TypeBox types. The `default` option assigns raw JavaScript * references for embedded types, which may cause side effects if type properties are explicitly updated * outside the TypeBox type builder. The `clone` option creates copies of any shared types upon creation, * preventing unintended side effects. The `freeze` option applies `Object.freeze()` to the type, making * it fully readonly and immutable. Implementations should use `default` whenever possible, as it is the * fastest way to instantiate types. The default setting is `default`. */ export let InstanceMode: 'default' | 'clone' | 'freeze' = 'default' // ------------------------------------------------------------------ // TypeSystemPolicy: Checking // ------------------------------------------------------------------ /** Sets whether TypeBox should assert optional properties using the TypeScript `exactOptionalPropertyTypes` assertion policy. The default is `false` */ export let ExactOptionalPropertyTypes: boolean = false /** Sets whether arrays should be treated as a kind of objects. The default is `false` */ export let AllowArrayObject: boolean = false /** Sets whether `NaN` or `Infinity` should be treated as valid numeric values. The default is `false` */ export let AllowNaN: boolean = false /** Sets whether `null` should validate for void types. The default is `false` */ export let AllowNullVoid: boolean = false /** Checks this value using the ExactOptionalPropertyTypes policy */ export function IsExactOptionalProperty(value: Record, key: string) { return ExactOptionalPropertyTypes ? key in value : value[key] !== undefined } /** Checks this value using the AllowArrayObjects policy */ export function IsObjectLike(value: unknown): value is Record { const isObject = IsObject(value) return AllowArrayObject ? isObject : isObject && !IsArray(value) } /** Checks this value as a record using the AllowArrayObjects policy */ export function IsRecordLike(value: unknown): value is Record { return IsObjectLike(value) && !(value instanceof Date) && !(value instanceof Uint8Array) } /** Checks this value using the AllowNaN policy */ export function IsNumberLike(value: unknown): value is number { return AllowNaN ? IsNumber(value) : Number.isFinite(value) } /** Checks this value using the AllowVoidNull policy */ export function IsVoidLike(value: unknown): value is void { const isUndefined = IsUndefined(value) return AllowNullVoid ? isUndefined || value === null : isUndefined } } sinclairzx81-typebox-e0ec98c/src/system/system.ts000066400000000000000000000060121505437577000222660ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/system The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { TypeRegistry, FormatRegistry } from '../type/registry/index' import { Unsafe, type TUnsafe } from '../type/unsafe/index' import { Kind } from '../type/symbols/index' import { TypeBoxError } from '../type/error/index' // ------------------------------------------------------------------ // Errors // ------------------------------------------------------------------ export class TypeSystemDuplicateTypeKind extends TypeBoxError { constructor(kind: string) { super(`Duplicate type kind '${kind}' detected`) } } export class TypeSystemDuplicateFormat extends TypeBoxError { constructor(kind: string) { super(`Duplicate string format '${kind}' detected`) } } // ------------------------------------------------------------------ // TypeSystem // ------------------------------------------------------------------ export type TypeFactoryFunction> = (options?: Partial) => TUnsafe /** Creates user defined types and formats and provides overrides for value checking behaviours */ export namespace TypeSystem { /** Creates a new type */ export function Type>(kind: string, check: (options: Options, value: unknown) => boolean): TypeFactoryFunction { if (TypeRegistry.Has(kind)) throw new TypeSystemDuplicateTypeKind(kind) TypeRegistry.Set(kind, check) return (options: Partial = {}) => Unsafe({ ...options, [Kind]: kind }) } /** Creates a new string format */ export function Format(format: F, check: (value: string) => boolean): F { if (FormatRegistry.Has(format)) throw new TypeSystemDuplicateFormat(format) FormatRegistry.Set(format, check) return format } } sinclairzx81-typebox-e0ec98c/src/tsconfig.json000066400000000000000000000003011505437577000215500ustar00rootroot00000000000000{ "extends": "../tsconfig.json", "files": ["compiler/index.ts", "errors/index.ts", "parser/index.ts", "syntax/index.ts", "system/index.ts", "type/index.ts", "value/index.ts", "index.ts"] } sinclairzx81-typebox-e0ec98c/src/type/000077500000000000000000000000001505437577000200305ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/any/000077500000000000000000000000001505437577000206175ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/any/any.ts000066400000000000000000000032141505437577000217560ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/index' import type { TSchema, SchemaOptions } from '../schema/index' import { Kind } from '../symbols/index' export interface TAny extends TSchema { [Kind]: 'Any' static: any } /** `[Json]` Creates an Any type */ export function Any(options?: SchemaOptions): TAny { return CreateType({ [Kind]: 'Any' }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/any/index.ts000066400000000000000000000024611505437577000223010ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './any' sinclairzx81-typebox-e0ec98c/src/type/argument/000077500000000000000000000000001505437577000216525ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/argument/argument.ts000066400000000000000000000033421505437577000240460ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema } from '../schema/index' import { Kind } from '../symbols/index' export interface TArgument extends TSchema { [Kind]: 'Argument' static: unknown index: Index } /** `[JavaScript]` Creates an Argument Type. */ export function Argument(index: Index): TArgument { return CreateType({ [Kind]: 'Argument', index }) as never } sinclairzx81-typebox-e0ec98c/src/type/argument/index.ts000066400000000000000000000024661505437577000233410ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './argument' sinclairzx81-typebox-e0ec98c/src/type/array/000077500000000000000000000000001505437577000211465ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/array/array.ts000066400000000000000000000047221505437577000226410ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import { Ensure } from '../helpers/index' import type { SchemaOptions, TSchema } from '../schema/index' import type { Static } from '../static/index' import { Kind } from '../symbols/index' export interface ArrayOptions extends SchemaOptions { /** The minimum number of items in this array */ minItems?: number /** The maximum number of items in this array */ maxItems?: number /** Should this schema contain unique items */ uniqueItems?: boolean /** A schema for which some elements should match */ contains?: TSchema /** A minimum number of contains schema matches */ minContains?: number /** A maximum number of contains schema matches */ maxContains?: number } type ArrayStatic = Ensure[]> export interface TArray extends TSchema, ArrayOptions { [Kind]: 'Array' static: ArrayStatic type: 'array' items: T } /** `[Json]` Creates an Array type */ export function Array(items: Type, options?: ArrayOptions): TArray { return CreateType({ [Kind]: 'Array', type: 'array', items }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/array/index.ts000066400000000000000000000024631505437577000226320ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './array' sinclairzx81-typebox-e0ec98c/src/type/async-iterator/000077500000000000000000000000001505437577000227745ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/async-iterator/async-iterator.ts000066400000000000000000000036441505437577000263170ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import type { Static } from '../static/index' import { Kind } from '../symbols/index' import { CreateType } from '../create/type' export interface TAsyncIterator extends TSchema { [Kind]: 'AsyncIterator' static: AsyncIterableIterator> type: 'AsyncIterator' items: T } /** `[JavaScript]` Creates a AsyncIterator type */ export function AsyncIterator(items: T, options?: SchemaOptions): TAsyncIterator { return CreateType({ [Kind]: 'AsyncIterator', type: 'AsyncIterator', items }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/async-iterator/index.ts000066400000000000000000000024741505437577000244620ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './async-iterator' sinclairzx81-typebox-e0ec98c/src/type/awaited/000077500000000000000000000000001505437577000214465ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/awaited/awaited.ts000066400000000000000000000131071505437577000234360ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import { Ensure } from '../helpers/index' import type { TSchema, SchemaOptions } from '../schema/index' import { Computed, type TComputed } from '../computed/index' import { Intersect, type TIntersect } from '../intersect/index' import { Union, type TUnion } from '../union/index' import { type TPromise } from '../promise/index' import { Ref, type TRef } from '../ref/index' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsIntersect, IsUnion, IsPromise, IsRef, IsComputed } from '../guard/kind' // ---------------------------------------------------------------- // FromComputed // ---------------------------------------------------------------- // prettier-ignore type TFromComputed = Ensure<( TComputed<'Awaited', [TComputed]> )> // prettier-ignore function FromComputed(target: Target, parameters: Parameters): TFromComputed { return Computed('Awaited', [Computed(target, parameters)]) as never } // ---------------------------------------------------------------- // Ref // ---------------------------------------------------------------- type TFromRef = Ensure]>> // prettier-ignore function FromRef($ref: Ref): TFromRef { return Computed('Awaited', [Ref($ref)]) as never } // ---------------------------------------------------------------- // FromIntersect // ---------------------------------------------------------------- // prettier-ignore type TFromIntersect = ( TIntersect> ) // prettier-ignore function FromIntersect(types: [...Types]): TFromIntersect { return Intersect(FromRest(types) as TSchema[]) as never } // ---------------------------------------------------------------- // FromUnion // ---------------------------------------------------------------- // prettier-ignore type TFromUnion = TUnion> // prettier-ignore function FromUnion(types: [...Types]): TFromUnion { return Union(FromRest(types) as TSchema[]) as never } // ---------------------------------------------------------------- // Promise // ---------------------------------------------------------------- type TFromPromise = TAwaited // prettier-ignore function FromPromise(type: Type): TFromPromise { return Awaited(type) as never } // ------------------------------------------------------------------ // FromRest // ------------------------------------------------------------------ // prettier-ignore type TFromRest = ( Types extends [infer Left extends TSchema, ...infer Right extends TSchema[]] ? TFromRest]> : Result ) // prettier-ignore function FromRest(types: [...Types]) : TFromRest { return types.map(type => Awaited(type)) as never } // ------------------------------------------------------------------ // TAwaited // ------------------------------------------------------------------ // prettier-ignore export type TAwaited = ( Type extends TComputed ? TFromComputed : Type extends TRef ? TFromRef : Type extends TIntersect ? TIntersect> : Type extends TUnion ? TUnion> : Type extends TPromise ? TAwaited : Type ) /** `[JavaScript]` Constructs a type by recursively unwrapping Promise types */ export function Awaited(type: T, options?: SchemaOptions): TAwaited { return CreateType( IsComputed(type) ? FromComputed(type.target, type.parameters) : IsIntersect(type) ? FromIntersect(type.allOf) : IsUnion(type) ? FromUnion(type.anyOf) : IsPromise(type) ? FromPromise(type.item) : IsRef(type) ? FromRef(type.$ref) : type, options, ) as never } sinclairzx81-typebox-e0ec98c/src/type/awaited/index.ts000066400000000000000000000024651505437577000231340ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './awaited' sinclairzx81-typebox-e0ec98c/src/type/bigint/000077500000000000000000000000001505437577000213045ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/bigint/bigint.ts000066400000000000000000000036021505437577000231310ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import { Kind } from '../symbols/index' import { CreateType } from '../create/index' export interface BigIntOptions extends SchemaOptions { exclusiveMaximum?: bigint exclusiveMinimum?: bigint maximum?: bigint minimum?: bigint multipleOf?: bigint } export interface TBigInt extends TSchema, BigIntOptions { [Kind]: 'BigInt' static: bigint type: 'bigint' } /** `[JavaScript]` Creates a BigInt type */ export function BigInt(options?: BigIntOptions): TBigInt { return CreateType({ [Kind]: 'BigInt', type: 'bigint' }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/bigint/index.ts000066400000000000000000000024641505437577000227710ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './bigint' sinclairzx81-typebox-e0ec98c/src/type/boolean/000077500000000000000000000000001505437577000214475ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/boolean/boolean.ts000066400000000000000000000033111505437577000234340ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import { Kind } from '../symbols/index' import { CreateType } from '../create/index' export interface TBoolean extends TSchema { [Kind]: 'Boolean' static: boolean type: 'boolean' } /** `[Json]` Creates a Boolean type */ export function Boolean(options?: SchemaOptions): TBoolean { return CreateType({ [Kind]: 'Boolean', type: 'boolean' }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/boolean/index.ts000066400000000000000000000024651505437577000231350ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './boolean' sinclairzx81-typebox-e0ec98c/src/type/clone/000077500000000000000000000000001505437577000211305ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/clone/index.ts000066400000000000000000000025121505437577000226070ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './type' export * from './value' sinclairzx81-typebox-e0ec98c/src/type/clone/type.ts000066400000000000000000000033101505437577000224560ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { TSchema, SchemaOptions } from '../schema/index' import { Clone } from './value' /** Clones a Rest */ export function CloneRest(schemas: T): T { return schemas.map((schema) => CloneType(schema)) as never } /** Clones a Type */ export function CloneType(schema: T, options?: SchemaOptions): T { return options === undefined ? Clone(schema) : Clone({ ...options, ...schema }) } sinclairzx81-typebox-e0ec98c/src/type/clone/value.ts000066400000000000000000000046351505437577000226240ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import * as ValueGuard from '../guard/value' function ArrayType(value: unknown[]) { return (value as any).map((value: unknown) => Visit(value as any)) } function DateType(value: Date) { return new Date(value.getTime()) } function Uint8ArrayType(value: Uint8Array) { return new Uint8Array(value) } function RegExpType(value: RegExp) { return new RegExp(value.source, value.flags) } function ObjectType(value: Record) { const result = {} as Record for (const key of Object.getOwnPropertyNames(value)) { result[key] = Visit(value[key]) } for (const key of Object.getOwnPropertySymbols(value)) { result[key] = Visit(value[key]) } return result } // prettier-ignore function Visit(value: unknown): any { return ( ValueGuard.IsArray(value) ? ArrayType(value) : ValueGuard.IsDate(value) ? DateType(value) : ValueGuard.IsUint8Array(value) ? Uint8ArrayType(value) : ValueGuard.IsRegExp(value) ? RegExpType(value) : ValueGuard.IsObject(value) ? ObjectType(value) : value ) } /** Clones a value */ export function Clone(value: T): T { return Visit(value) } sinclairzx81-typebox-e0ec98c/src/type/composite/000077500000000000000000000000001505437577000220325ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/composite/composite.ts000066400000000000000000000123641505437577000244120ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema } from '../schema/index' import type { Evaluate } from '../helpers/index' import { IntersectEvaluated, type TIntersectEvaluated } from '../intersect/index' import { IndexFromPropertyKeys, type TIndexFromPropertyKeys } from '../indexed/index' import { KeyOfPropertyKeys, type TKeyOfPropertyKeys } from '../keyof/index' import { type TNever } from '../never/index' import { Object, type TObject, type TProperties, type ObjectOptions } from '../object/index' import { SetDistinct, TSetDistinct } from '../sets/index' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsNever } from '../guard/kind' // ------------------------------------------------------------------ // CompositeKeys // ------------------------------------------------------------------ // prettier-ignore type TCompositeKeys = ( T extends [infer L extends TSchema, ...infer R extends TSchema[]] ? TCompositeKeys]> : TSetDistinct ) // prettier-ignore function CompositeKeys(T: [...T]): TCompositeKeys { const Acc = [] as PropertyKey[] for(const L of T) Acc.push(...KeyOfPropertyKeys(L)) return SetDistinct(Acc) as never } // ------------------------------------------------------------------ // FilterNever // ------------------------------------------------------------------ // prettier-ignore type TFilterNever = ( T extends [infer L extends TSchema, ...infer R extends TSchema[]] ? L extends TNever ? TFilterNever : TFilterNever : Acc ) // prettier-ignore function FilterNever(T: [...T]): TFilterNever { return T.filter(L => !IsNever(L)) as never } // ------------------------------------------------------------------ // CompositeProperty // ------------------------------------------------------------------ // prettier-ignore type TCompositeProperty = ( T extends [infer L extends TSchema, ...infer R extends TSchema[]] ? TCompositeProperty]> : TFilterNever ) // prettier-ignore function CompositeProperty(T: [...T], K: K): TCompositeProperty { const Acc = [] as TSchema[] for(const L of T) Acc.push(...IndexFromPropertyKeys(L, [K])) return FilterNever(Acc) as never } // ------------------------------------------------------------------ // CompositeProperties // ------------------------------------------------------------------ // prettier-ignore type TCompositeProperties = ( K extends [infer L extends PropertyKey, ...infer R extends PropertyKey[]] ? TCompositeProperties> }> : Acc ) // prettier-ignore function CompositeProperties(T: [...T], K: [...K]): TCompositeProperties { const Acc = {} as never for(const L of K) { Acc[L] = IntersectEvaluated(CompositeProperty(T, L)) } return Acc } // ------------------------------------------------------------------ // Composite // ------------------------------------------------------------------ // prettier-ignore type TCompositeEvaluate< T extends TSchema[], K extends PropertyKey[] = TCompositeKeys, P extends TProperties = Evaluate>, R extends TObject = TObject

> = R // prettier-ignore export type TComposite = TCompositeEvaluate // prettier-ignore export function Composite(T: [...T], options?: ObjectOptions): TComposite { const K = CompositeKeys(T) const P = CompositeProperties(T, K) const R = Object(P, options) return R as never } sinclairzx81-typebox-e0ec98c/src/type/composite/index.ts000066400000000000000000000024671505437577000235220ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './composite' sinclairzx81-typebox-e0ec98c/src/type/computed/000077500000000000000000000000001505437577000216505ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/computed/computed.ts000066400000000000000000000042541505437577000240450ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import { CreateType } from '../create/index' import { Kind } from '../symbols/symbols' // ------------------------------------------------------------------ // Computed // ------------------------------------------------------------------ export interface TComputed extends TSchema { [Kind]: 'Computed' target: Target parameters: Parameters } /** `[Internal]` Creates a deferred computed type. This type is used exclusively in modules to defer resolution of computable types that contain interior references */ export function Computed(target: Target, parameters: [...Parameters], options?: SchemaOptions): TComputed { return CreateType({ [Kind]: 'Computed', target, parameters }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/computed/index.ts000066400000000000000000000024661505437577000233370ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './computed' sinclairzx81-typebox-e0ec98c/src/type/const/000077500000000000000000000000001505437577000211565ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/const/const.ts000066400000000000000000000146201505437577000226570ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { AssertRest, Evaluate } from '../helpers/index' import type { TSchema, SchemaOptions } from '../schema/index' import type { TProperties } from '../object/index' import { Any, type TAny } from '../any/index' import { BigInt, type TBigInt } from '../bigint/index' import { Date, type TDate } from '../date/index' import { Function as FunctionType, type TFunction } from '../function/index' import { Literal, type TLiteral } from '../literal/index' import { type TNever } from '../never/index' import { Null, type TNull } from '../null/index' import { Object, type TObject } from '../object/index' import { Symbol, type TSymbol } from '../symbol/index' import { Tuple, type TTuple } from '../tuple/index' import { Readonly, type TReadonly } from '../readonly/index' import { Undefined, type TUndefined } from '../undefined/index' import { Uint8Array, type TUint8Array } from '../uint8array/index' import { Unknown, type TUnknown } from '../unknown/index' import { CreateType } from '../create/index' // ------------------------------------------------------------------ // ValueGuard // ------------------------------------------------------------------ import { IsArray, IsNumber, IsBigInt, IsUint8Array, IsDate, IsIterator, IsObject, IsAsyncIterator, IsFunction, IsUndefined, IsNull, IsSymbol, IsBoolean, IsString } from '../guard/value' // ------------------------------------------------------------------ // FromArray // ------------------------------------------------------------------ // prettier-ignore type TFromArray = T extends readonly [infer L extends unknown, ...infer R extends unknown[]] ? [FromValue, ...TFromArray] : T // prettier-ignore function FromArray(T: [...T]): TFromArray { return T.map(L => FromValue(L, false)) as never } // ------------------------------------------------------------------ // FromProperties // ------------------------------------------------------------------ // prettier-ignore type TFromProperties> = { -readonly [K in keyof T]: FromValue extends infer R extends TSchema ? TReadonly : TReadonly } // prettier-ignore function FromProperties>(value: T): TFromProperties { const Acc = {} as TProperties for(const K of globalThis.Object.getOwnPropertyNames(value)) Acc[K] = Readonly(FromValue(value[K], false)) return Acc as never } // ------------------------------------------------------------------ // ConditionalReadonly - Only applied if not root // ------------------------------------------------------------------ type TConditionalReadonly = Root extends true ? T : TReadonly function ConditionalReadonly(T: T, root: Root): TConditionalReadonly { return (root === true ? T : Readonly(T)) as never } // ------------------------------------------------------------------ // FromValue // ------------------------------------------------------------------ // prettier-ignore type FromValue = T extends AsyncIterableIterator ? TConditionalReadonly : T extends IterableIterator ? TConditionalReadonly : T extends readonly unknown[] ? TReadonly>>> : T extends Uint8Array ? TUint8Array : T extends Date ? TDate : T extends Record ? TConditionalReadonly>>, Root> : T extends Function ? TConditionalReadonly, Root> : T extends undefined ? TUndefined : T extends null ? TNull : T extends symbol ? TSymbol : T extends number ? TLiteral : T extends boolean ? TLiteral : T extends string ? TLiteral : T extends bigint ? TBigInt : TObject<{}> // prettier-ignore function FromValue(value: T, root: Root): FromValue { return ( IsAsyncIterator(value) ? ConditionalReadonly(Any(), root) : IsIterator(value) ? ConditionalReadonly(Any(), root) : IsArray(value) ? Readonly(Tuple(FromArray(value) as TSchema[])) : IsUint8Array(value) ? Uint8Array() : IsDate(value) ? Date() : IsObject(value) ? ConditionalReadonly(Object(FromProperties(value as Record) as TProperties), root) : IsFunction(value) ? ConditionalReadonly(FunctionType([], Unknown()), root) : IsUndefined(value) ? Undefined() : IsNull(value) ? Null() : IsSymbol(value) ? Symbol() : IsBigInt(value) ? BigInt() : IsNumber(value) ? Literal(value) : IsBoolean(value) ? Literal(value) : IsString(value) ? Literal(value) : Object({}) ) as never } // ------------------------------------------------------------------ // TConst // ------------------------------------------------------------------ export type TConst = FromValue /** `[JavaScript]` Creates a readonly const type from the given value. */ export function Const(T: T, options?: SchemaOptions): TConst { return CreateType(FromValue(T, true), options) as never } sinclairzx81-typebox-e0ec98c/src/type/const/index.ts000066400000000000000000000024631505437577000226420ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './const' sinclairzx81-typebox-e0ec98c/src/type/constructor-parameters/000077500000000000000000000000001505437577000245565ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/constructor-parameters/constructor-parameters.ts000066400000000000000000000043571505437577000316650ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import type { TConstructor } from '../constructor/index' import { Tuple, type TTuple } from '../tuple/index' import { Never, type TNever } from '../never/index' import * as KindGuard from '../guard/kind' // ------------------------------------------------------------------ // ConstructorParameters // ------------------------------------------------------------------ // prettier-ignore export type TConstructorParameters = ( Type extends TConstructor ? TTuple : TNever ) /** `[JavaScript]` Extracts the ConstructorParameters from the given Constructor type */ export function ConstructorParameters(schema: Type, options?: SchemaOptions): TConstructorParameters { return (KindGuard.IsConstructor(schema) ? Tuple(schema.parameters, options) : Never(options)) as never } sinclairzx81-typebox-e0ec98c/src/type/constructor-parameters/index.ts000066400000000000000000000025041505437577000262360ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './constructor-parameters' sinclairzx81-typebox-e0ec98c/src/type/constructor/000077500000000000000000000000001505437577000224155ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/constructor/constructor.ts000066400000000000000000000064321505437577000253570ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import type { Static } from '../static/index' import type { Ensure } from '../helpers/index' import type { TReadonlyOptional } from '../readonly-optional/index' import type { TReadonly } from '../readonly/index' import type { TOptional } from '../optional/index' import { CreateType } from '../create/type' import { Kind } from '../symbols/index' // ------------------------------------------------------------------ // StaticConstructor // ------------------------------------------------------------------ type StaticReturnType = Static // prettier-ignore type StaticParameter = T extends TReadonlyOptional ? [Readonly>?] : T extends TReadonly ? [Readonly>] : T extends TOptional ? [Static?] : [Static] // prettier-ignore type StaticParameters = ( T extends [infer L extends TSchema, ...infer R extends TSchema[]] ? StaticParameters]> : Acc ) // prettier-ignore type StaticConstructor = Ensure) => StaticReturnType> // ------------------------------------------------------------------ // TConstructor // ------------------------------------------------------------------ export interface TConstructor extends TSchema { [Kind]: 'Constructor' static: StaticConstructor type: 'Constructor' parameters: T returns: U } /** `[JavaScript]` Creates a Constructor type */ export function Constructor(parameters: [...T], returns: U, options?: SchemaOptions): TConstructor { return CreateType({ [Kind]: 'Constructor', type: 'Constructor', parameters, returns }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/constructor/index.ts000066400000000000000000000024711505437577000241000ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './constructor' sinclairzx81-typebox-e0ec98c/src/type/create/000077500000000000000000000000001505437577000212735ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/create/immutable.ts000066400000000000000000000047331505437577000236310ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import * as ValueGuard from '../guard/value' function ImmutableArray(value: unknown[]) { return globalThis.Object.freeze(value as any).map((value: unknown) => Immutable(value as any)) } function ImmutableDate(value: Date) { return value } function ImmutableUint8Array(value: Uint8Array) { return value } function ImmutableRegExp(value: RegExp) { return value } function ImmutableObject(value: Record) { const result = {} as Record for (const key of Object.getOwnPropertyNames(value)) { result[key] = Immutable(value[key]) } for (const key of Object.getOwnPropertySymbols(value)) { result[key] = Immutable(value[key]) } return globalThis.Object.freeze(result) } /** Specialized deep immutable value. Applies freeze recursively to the given value */ // prettier-ignore export function Immutable(value: unknown): unknown { return ( ValueGuard.IsArray(value) ? ImmutableArray(value) : ValueGuard.IsDate(value) ? ImmutableDate(value) : ValueGuard.IsUint8Array(value) ? ImmutableUint8Array(value) : ValueGuard.IsRegExp(value) ? ImmutableRegExp(value) : ValueGuard.IsObject(value) ? ImmutableObject(value) : value ) } sinclairzx81-typebox-e0ec98c/src/type/create/index.ts000066400000000000000000000024621505437577000227560ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './type' sinclairzx81-typebox-e0ec98c/src/type/create/type.ts000066400000000000000000000035611505437577000226310ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { TypeSystemPolicy } from '../../system/policy' import { SchemaOptions } from '../schema/schema' import { Immutable } from './immutable' import { Clone } from '../clone/value' /** Creates TypeBox schematics using the configured InstanceMode */ export function CreateType(schema: Record, options?: SchemaOptions): unknown { const result = options !== undefined ? { ...options, ...schema } : schema switch (TypeSystemPolicy.InstanceMode) { case 'freeze': return Immutable(result) case 'clone': return Clone(result) default: return result } } sinclairzx81-typebox-e0ec98c/src/type/date/000077500000000000000000000000001505437577000207455ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/date/date.ts000066400000000000000000000041471505437577000222400ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import { Kind } from '../symbols/index' import { CreateType } from '../create/type' export interface DateOptions extends SchemaOptions { /** The exclusive maximum timestamp value */ exclusiveMaximumTimestamp?: number /** The exclusive minimum timestamp value */ exclusiveMinimumTimestamp?: number /** The maximum timestamp value */ maximumTimestamp?: number /** The minimum timestamp value */ minimumTimestamp?: number /** The multiple of timestamp value */ multipleOfTimestamp?: number } export interface TDate extends TSchema, DateOptions { [Kind]: 'Date' static: Date type: 'date' } /** `[JavaScript]` Creates a Date type */ export function Date(options?: DateOptions): TDate { return CreateType({ [Kind]: 'Date', type: 'Date' }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/date/index.ts000066400000000000000000000024621505437577000224300ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './date' sinclairzx81-typebox-e0ec98c/src/type/discard/000077500000000000000000000000001505437577000214415ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/discard/discard.ts000066400000000000000000000032071505437577000234240ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ function DiscardKey(value: Record, key: PropertyKey) { const { [key]: _, ...rest } = value return rest } /** Discards property keys from the given value. This function returns a shallow Clone. */ export function Discard(value: Record, keys: PropertyKey[]) { return keys.reduce((acc, key) => DiscardKey(acc, key), value) } sinclairzx81-typebox-e0ec98c/src/type/discard/index.ts000066400000000000000000000024651505437577000231270ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './discard' sinclairzx81-typebox-e0ec98c/src/type/enum/000077500000000000000000000000001505437577000207745ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/enum/enum.ts000066400000000000000000000052451505437577000223160ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import { Literal, type TLiteral } from '../literal/index' import { Kind, Hint } from '../symbols/index' import { Union } from '../union/index' // ------------------------------------------------------------------ // ValueGuard // ------------------------------------------------------------------ import { IsUndefined } from '../guard/value' // ------------------------------------------------------------------ // TEnum // ------------------------------------------------------------------ export type TEnumRecord = Record export type TEnumValue = string | number export type TEnumKey = string export interface TEnum = Record> extends TSchema { [Kind]: 'Union' [Hint]: 'Enum' static: T[keyof T] anyOf: TLiteral[] } /** `[Json]` Creates a Enum type */ export function Enum>(item: T, options?: SchemaOptions): TEnum { if (IsUndefined(item)) throw new Error('Enum undefined or empty') const values1 = globalThis.Object.getOwnPropertyNames(item) .filter((key) => isNaN(key as any)) .map((key) => item[key]) as T[keyof T][] const values2 = [...new Set(values1)] const anyOf = values2.map((value) => Literal(value)) return Union(anyOf, { ...options, [Hint]: 'Enum' }) as never } sinclairzx81-typebox-e0ec98c/src/type/enum/index.ts000066400000000000000000000024621505437577000224570ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './enum' sinclairzx81-typebox-e0ec98c/src/type/error/000077500000000000000000000000001505437577000211615ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/error/error.ts000066400000000000000000000026751505437577000226740ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ /** The base Error type thrown for all TypeBox exceptions */ export class TypeBoxError extends Error { constructor(message: string) { super(message) } } sinclairzx81-typebox-e0ec98c/src/type/error/index.ts000066400000000000000000000024631505437577000226450ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './error' sinclairzx81-typebox-e0ec98c/src/type/exclude/000077500000000000000000000000001505437577000214615ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/exclude/exclude-from-mapped-result.ts000066400000000000000000000061651505437577000272130ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema } from '../schema/index' import type { TProperties } from '../object/index' import { MappedResult, type TMappedResult } from '../mapped/index' import { Exclude, type TExclude } from './exclude' // ------------------------------------------------------------------ // FromProperties // ------------------------------------------------------------------ // prettier-ignore type TFromProperties< K extends TProperties, T extends TSchema > = ( { [K2 in keyof K]: TExclude } ) // prettier-ignore function FromProperties< P extends TProperties, T extends TSchema >(P: P, U: T): TFromProperties { const Acc = {} as TProperties for(const K2 of globalThis.Object.getOwnPropertyNames(P)) Acc[K2] = Exclude(P[K2], U) return Acc as never } // ------------------------------------------------------------------ // FromMappedResult // ------------------------------------------------------------------ // prettier-ignore type TFromMappedResult< R extends TMappedResult, T extends TSchema > = ( TFromProperties ) // prettier-ignore function FromMappedResult< R extends TMappedResult, T extends TSchema >(R: R, T: T): TFromMappedResult { return FromProperties(R.properties, T) as never } // ------------------------------------------------------------------ // ExcludeFromMappedResult // ------------------------------------------------------------------ // prettier-ignore export type TExcludeFromMappedResult< R extends TMappedResult, T extends TSchema, P extends TProperties = TFromMappedResult > = ( TMappedResult

) // prettier-ignore export function ExcludeFromMappedResult< R extends TMappedResult, T extends TSchema, P extends TProperties = TFromMappedResult >(R: R, T: T): TMappedResult

{ const P = FromMappedResult(R, T) return MappedResult(P) as never } sinclairzx81-typebox-e0ec98c/src/type/exclude/exclude-from-template-literal.ts000066400000000000000000000035201505437577000276660ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema } from '../schema/index' import { TExclude, Exclude } from './exclude' import { TemplateLiteralToUnion, type TTemplateLiteral, type TTemplateLiteralToUnion } from '../template-literal/index' // prettier-ignore export type TExcludeFromTemplateLiteral = ( TExclude, R> ) export function ExcludeFromTemplateLiteral(L: L, R: R): TExcludeFromTemplateLiteral { return Exclude(TemplateLiteralToUnion(L), R) as never } sinclairzx81-typebox-e0ec98c/src/type/exclude/exclude.ts000066400000000000000000000110461505437577000234640ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import type { UnionToTuple, AssertRest, AssertType } from '../helpers/index' import type { TMappedResult } from '../mapped/index' import { type TTemplateLiteral } from '../template-literal/index' import { Union, type TUnion } from '../union/index' import { Never, type TNever } from '../never/index' import { type Static } from '../static/index' import { type TUnionEvaluated } from '../union/index' import { ExtendsCheck, ExtendsResult } from '../extends/index' import { ExcludeFromMappedResult, type TExcludeFromMappedResult } from './exclude-from-mapped-result' import { ExcludeFromTemplateLiteral, type TExcludeFromTemplateLiteral } from './exclude-from-template-literal' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsMappedResult, IsTemplateLiteral, IsUnion } from '../guard/kind' // ------------------------------------------------------------------ // ExcludeRest // ------------------------------------------------------------------ // prettier-ignore type TExcludeRest = AssertRest> extends Static ? never : L[K] }[number]>> extends infer R extends TSchema[] ? TUnionEvaluated : never function ExcludeRest(L: [...L], R: R) { const excluded = L.filter((inner) => ExtendsCheck(inner, R) === ExtendsResult.False) return excluded.length === 1 ? excluded[0] : Union(excluded) } // ------------------------------------------------------------------ // TExclude // ------------------------------------------------------------------ // prettier-ignore export type TExclude = ( L extends TUnion ? TExcludeRest : L extends R ? TNever : L ) /** `[Json]` Constructs a type by excluding from unionType all union members that are assignable to excludedMembers */ export function Exclude(unionType: L, excludedMembers: R, options?: SchemaOptions): TExcludeFromMappedResult /** `[Json]` Constructs a type by excluding from unionType all union members that are assignable to excludedMembers */ export function Exclude(unionType: L, excludedMembers: R, options?: SchemaOptions): TExcludeFromTemplateLiteral /** `[Json]` Constructs a type by excluding from unionType all union members that are assignable to excludedMembers */ export function Exclude(unionType: L, excludedMembers: R, options?: SchemaOptions): TExclude /** `[Json]` Constructs a type by excluding from unionType all union members that are assignable to excludedMembers */ export function Exclude(L: TSchema, R: TSchema, options: SchemaOptions = {}): any { // overloads if (IsTemplateLiteral(L)) return CreateType(ExcludeFromTemplateLiteral(L, R), options) if (IsMappedResult(L)) return CreateType(ExcludeFromMappedResult(L, R), options) // prettier-ignore return CreateType( IsUnion(L) ? ExcludeRest(L.anyOf, R) : ExtendsCheck(L, R) !== ExtendsResult.False ? Never() : L , options) } sinclairzx81-typebox-e0ec98c/src/type/exclude/index.ts000066400000000000000000000026221505437577000231420ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './exclude-from-mapped-result' export * from './exclude-from-template-literal' export * from './exclude' sinclairzx81-typebox-e0ec98c/src/type/extends/000077500000000000000000000000001505437577000215025ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/extends/extends-check.ts000066400000000000000000000776011505437577000246120ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { type TAny, Any } from '../any/index' import { type TArray } from '../array/index' import { type TAsyncIterator } from '../async-iterator/index' import { type TBigInt } from '../bigint/index' import { type TBoolean } from '../boolean/index' import { type TConstructor } from '../constructor/index' import { type TDate } from '../date/index' import { type TFunction, Function as FunctionType } from '../function/index' import { type TInteger } from '../integer/index' import { type TIntersect } from '../intersect/index' import { type TIterator } from '../iterator/index' import { type TLiteral } from '../literal/index' import { type TNever } from '../never/index' import { type TNot } from '../not/index' import { type TNull } from '../null/index' import { type TNumber, Number } from '../number/index' import { type TObject } from '../object/index' import { type TPromise } from '../promise/index' import { type TRecord } from '../record/index' import { type TSchema } from '../schema/index' import { type TString, String } from '../string/index' import { type TSymbol } from '../symbol/index' import { type TTuple } from '../tuple/index' import { type TUint8Array } from '../uint8array/index' import { type TUndefined } from '../undefined/index' import { type TUnion } from '../union/index' import { type TUnknown, Unknown } from '../unknown/index' import { type TVoid } from '../void/index' import { TemplateLiteralToUnion } from '../template-literal/index' import { PatternNumberExact, PatternStringExact } from '../patterns/index' import { Kind, Hint } from '../symbols/index' import { TypeBoxError } from '../error/index' import { TypeGuard, ValueGuard } from '../guard/index' export class ExtendsResolverError extends TypeBoxError {} export enum ExtendsResult { Union, True, False, } // ------------------------------------------------------------------ // IntoBooleanResult // ------------------------------------------------------------------ // prettier-ignore function IntoBooleanResult(result: ExtendsResult) { return result === ExtendsResult.False ? result : ExtendsResult.True } // ------------------------------------------------------------------ // Throw // ------------------------------------------------------------------ // prettier-ignore function Throw(message: string): never { throw new ExtendsResolverError(message) } // ------------------------------------------------------------------ // StructuralRight // ------------------------------------------------------------------ // prettier-ignore function IsStructuralRight(right: TSchema): boolean { return ( TypeGuard.IsNever(right) || TypeGuard.IsIntersect(right) || TypeGuard.IsUnion(right) || TypeGuard.IsUnknown(right) || TypeGuard.IsAny(right) ) } // prettier-ignore function StructuralRight(left: TSchema, right: TSchema) { return ( TypeGuard.IsNever(right) ? FromNeverRight(left, right) : TypeGuard.IsIntersect(right) ? FromIntersectRight(left, right) : TypeGuard.IsUnion(right) ? FromUnionRight(left, right) : TypeGuard.IsUnknown(right) ? FromUnknownRight(left, right) : TypeGuard.IsAny(right) ? FromAnyRight(left, right) : Throw('StructuralRight') ) } // ------------------------------------------------------------------ // Any // ------------------------------------------------------------------ // prettier-ignore function FromAnyRight(left: TSchema, right: TAny) { return ExtendsResult.True } // prettier-ignore function FromAny(left: TAny, right: TSchema) { return ( TypeGuard.IsIntersect(right) ? FromIntersectRight(left, right) : (TypeGuard.IsUnion(right) && right.anyOf.some((schema) => TypeGuard.IsAny(schema) || TypeGuard.IsUnknown(schema))) ? ExtendsResult.True : TypeGuard.IsUnion(right) ? ExtendsResult.Union : TypeGuard.IsUnknown(right) ? ExtendsResult.True : TypeGuard.IsAny(right) ? ExtendsResult.True : ExtendsResult.Union ) } // ------------------------------------------------------------------ // Array // ------------------------------------------------------------------ // prettier-ignore function FromArrayRight(left: TSchema, right: TArray) { return ( TypeGuard.IsUnknown(left) ? ExtendsResult.False : TypeGuard.IsAny(left) ? ExtendsResult.Union : TypeGuard.IsNever(left) ? ExtendsResult.True : ExtendsResult.False ) } // prettier-ignore function FromArray(left: TArray, right: TSchema) { return ( TypeGuard.IsObject(right) && IsObjectArrayLike(right) ? ExtendsResult.True : IsStructuralRight(right) ? StructuralRight(left, right) : !TypeGuard.IsArray(right) ? ExtendsResult.False : IntoBooleanResult(Visit(left.items, right.items)) ) } // ------------------------------------------------------------------ // AsyncIterator // ------------------------------------------------------------------ // prettier-ignore function FromAsyncIterator(left: TAsyncIterator, right: TSchema) { return ( IsStructuralRight(right) ? StructuralRight(left, right) : !TypeGuard.IsAsyncIterator(right) ? ExtendsResult.False : IntoBooleanResult(Visit(left.items, right.items)) ) } // ------------------------------------------------------------------ // BigInt // ------------------------------------------------------------------ // prettier-ignore function FromBigInt(left: TBigInt, right: TSchema): ExtendsResult { return ( IsStructuralRight(right) ? StructuralRight(left, right) : TypeGuard.IsObject(right) ? FromObjectRight(left, right) : TypeGuard.IsRecord(right) ? FromRecordRight(left, right) : TypeGuard.IsBigInt(right) ? ExtendsResult.True : ExtendsResult.False ) } // ------------------------------------------------------------------ // Boolean // ------------------------------------------------------------------ // prettier-ignore function FromBooleanRight(left: TSchema, right: TBoolean) { return ( TypeGuard.IsLiteralBoolean(left) ? ExtendsResult.True : TypeGuard.IsBoolean(left) ? ExtendsResult.True : ExtendsResult.False ) } // prettier-ignore function FromBoolean(left: TBoolean, right: TSchema): ExtendsResult { return ( IsStructuralRight(right) ? StructuralRight(left, right) : TypeGuard.IsObject(right) ? FromObjectRight(left, right) : TypeGuard.IsRecord(right) ? FromRecordRight(left, right) : TypeGuard.IsBoolean(right) ? ExtendsResult.True : ExtendsResult.False ) } // ------------------------------------------------------------------ // Constructor // ------------------------------------------------------------------ // prettier-ignore function FromConstructor(left: TConstructor, right: TSchema) { return ( IsStructuralRight(right) ? StructuralRight(left, right) : TypeGuard.IsObject(right) ? FromObjectRight(left, right) : !TypeGuard.IsConstructor(right) ? ExtendsResult.False : left.parameters.length > right.parameters.length ? ExtendsResult.False : (!left.parameters.every((schema, index) => IntoBooleanResult(Visit(right.parameters[index], schema)) === ExtendsResult.True)) ? ExtendsResult.False : IntoBooleanResult(Visit(left.returns, right.returns)) ) } // ------------------------------------------------------------------ // Date // ------------------------------------------------------------------ // prettier-ignore function FromDate(left: TDate, right: TSchema) { return ( IsStructuralRight(right) ? StructuralRight(left, right) : TypeGuard.IsObject(right) ? FromObjectRight(left, right) : TypeGuard.IsRecord(right) ? FromRecordRight(left, right) : TypeGuard.IsDate(right) ? ExtendsResult.True : ExtendsResult.False ) } // ------------------------------------------------------------------ // Function // ------------------------------------------------------------------ // prettier-ignore function FromFunction(left: TFunction, right: TSchema) { return ( IsStructuralRight(right) ? StructuralRight(left, right) : TypeGuard.IsObject(right) ? FromObjectRight(left, right) : !TypeGuard.IsFunction(right) ? ExtendsResult.False : left.parameters.length > right.parameters.length ? ExtendsResult.False : (!left.parameters.every((schema, index) => IntoBooleanResult(Visit(right.parameters[index], schema)) === ExtendsResult.True)) ? ExtendsResult.False : IntoBooleanResult(Visit(left.returns, right.returns)) ) } // ------------------------------------------------------------------ // Integer // ------------------------------------------------------------------ // prettier-ignore function FromIntegerRight(left: TSchema, right: TInteger) { return ( TypeGuard.IsLiteral(left) && ValueGuard.IsNumber(left.const) ? ExtendsResult.True : TypeGuard.IsNumber(left) || TypeGuard.IsInteger(left) ? ExtendsResult.True : ExtendsResult.False ) } // prettier-ignore function FromInteger(left: TInteger, right: TSchema): ExtendsResult { return ( TypeGuard.IsInteger(right) || TypeGuard.IsNumber(right) ? ExtendsResult.True : IsStructuralRight(right) ? StructuralRight(left, right) : TypeGuard.IsObject(right) ? FromObjectRight(left, right) : TypeGuard.IsRecord(right) ? FromRecordRight(left, right) : ExtendsResult.False ) } // ------------------------------------------------------------------ // Intersect // ------------------------------------------------------------------ // prettier-ignore function FromIntersectRight(left: TSchema, right: TIntersect): ExtendsResult { return right.allOf.every((schema) => Visit(left, schema) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False } // prettier-ignore function FromIntersect(left: TIntersect, right: TSchema) { return left.allOf.some((schema) => Visit(schema, right) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False } // ------------------------------------------------------------------ // Iterator // ------------------------------------------------------------------ // prettier-ignore function FromIterator(left: TIterator, right: TSchema) { return ( IsStructuralRight(right) ? StructuralRight(left, right) : !TypeGuard.IsIterator(right) ? ExtendsResult.False : IntoBooleanResult(Visit(left.items, right.items)) ) } // ------------------------------------------------------------------ // Literal // ------------------------------------------------------------------ // prettier-ignore function FromLiteral(left: TLiteral, right: TSchema): ExtendsResult { return ( TypeGuard.IsLiteral(right) && right.const === left.const ? ExtendsResult.True : IsStructuralRight(right) ? StructuralRight(left, right) : TypeGuard.IsObject(right) ? FromObjectRight(left, right) : TypeGuard.IsRecord(right) ? FromRecordRight(left, right) : TypeGuard.IsString(right) ? FromStringRight(left, right) : TypeGuard.IsNumber(right) ? FromNumberRight(left, right) : TypeGuard.IsInteger(right) ? FromIntegerRight(left, right) : TypeGuard.IsBoolean(right) ? FromBooleanRight(left, right) : ExtendsResult.False ) } // ------------------------------------------------------------------ // Never // ------------------------------------------------------------------ // prettier-ignore function FromNeverRight(left: TSchema, right: TNever) { return ExtendsResult.False } // prettier-ignore function FromNever(left: TNever, right: TSchema) { return ExtendsResult.True } // ------------------------------------------------------------------ // Not // ------------------------------------------------------------------ // prettier-ignore function UnwrapTNot(schema: T): TUnknown | TNot['not'] { let [current, depth]: [TSchema, number] = [schema, 0] while (true) { if (!TypeGuard.IsNot(current)) break current = current.not depth += 1 } return depth % 2 === 0 ? current : Unknown() } // prettier-ignore function FromNot(left: TSchema, right: TSchema) { // TypeScript has no concept of negated types, and attempts to correctly check the negated // type at runtime would put TypeBox at odds with TypeScripts ability to statically infer // the type. Instead we unwrap to either unknown or T and continue evaluating. // prettier-ignore return ( TypeGuard.IsNot(left) ? Visit(UnwrapTNot(left), right) : TypeGuard.IsNot(right) ? Visit(left, UnwrapTNot(right)) : Throw('Invalid fallthrough for Not') ) } // ------------------------------------------------------------------ // Null // ------------------------------------------------------------------ // prettier-ignore function FromNull(left: TNull, right: TSchema) { return ( IsStructuralRight(right) ? StructuralRight(left, right) : TypeGuard.IsObject(right) ? FromObjectRight(left, right) : TypeGuard.IsRecord(right) ? FromRecordRight(left, right) : TypeGuard.IsNull(right) ? ExtendsResult.True : ExtendsResult.False ) } // ------------------------------------------------------------------ // Number // ------------------------------------------------------------------ // prettier-ignore function FromNumberRight(left: TSchema, right: TNumber) { return ( TypeGuard.IsLiteralNumber(left) ? ExtendsResult.True : TypeGuard.IsNumber(left) || TypeGuard.IsInteger(left) ? ExtendsResult.True : ExtendsResult.False ) } // prettier-ignore function FromNumber(left: TNumber, right: TSchema): ExtendsResult { return ( IsStructuralRight(right) ? StructuralRight(left, right) : TypeGuard.IsObject(right) ? FromObjectRight(left, right) : TypeGuard.IsRecord(right) ? FromRecordRight(left, right) : TypeGuard.IsInteger(right) || TypeGuard.IsNumber(right) ? ExtendsResult.True : ExtendsResult.False ) } // ------------------------------------------------------------------ // Object // ------------------------------------------------------------------ // prettier-ignore function IsObjectPropertyCount(schema: TObject, count: number) { return Object.getOwnPropertyNames(schema.properties).length === count } // prettier-ignore function IsObjectStringLike(schema: TObject) { return IsObjectArrayLike(schema) } // prettier-ignore function IsObjectSymbolLike(schema: TObject) { return IsObjectPropertyCount(schema, 0) || ( IsObjectPropertyCount(schema, 1) && 'description' in schema.properties && TypeGuard.IsUnion(schema.properties.description) && schema.properties.description.anyOf.length === 2 && (( TypeGuard.IsString(schema.properties.description.anyOf[0]) && TypeGuard.IsUndefined(schema.properties.description.anyOf[1]) ) || ( TypeGuard.IsString(schema.properties.description.anyOf[1]) && TypeGuard.IsUndefined(schema.properties.description.anyOf[0]) )) ) } // prettier-ignore function IsObjectNumberLike(schema: TObject) { return IsObjectPropertyCount(schema, 0) } // prettier-ignore function IsObjectBooleanLike(schema: TObject) { return IsObjectPropertyCount(schema, 0) } // prettier-ignore function IsObjectBigIntLike(schema: TObject) { return IsObjectPropertyCount(schema, 0) } // prettier-ignore function IsObjectDateLike(schema: TObject) { return IsObjectPropertyCount(schema, 0) } // prettier-ignore function IsObjectUint8ArrayLike(schema: TObject) { return IsObjectArrayLike(schema) } // prettier-ignore function IsObjectFunctionLike(schema: TObject) { const length = Number() return IsObjectPropertyCount(schema, 0) || (IsObjectPropertyCount(schema, 1) && 'length' in schema.properties && IntoBooleanResult(Visit(schema.properties['length'], length)) === ExtendsResult.True) } // prettier-ignore function IsObjectConstructorLike(schema: TObject) { return IsObjectPropertyCount(schema, 0) } // prettier-ignore function IsObjectArrayLike(schema: TObject) { const length = Number() return IsObjectPropertyCount(schema, 0) || (IsObjectPropertyCount(schema, 1) && 'length' in schema.properties && IntoBooleanResult(Visit(schema.properties['length'], length)) === ExtendsResult.True) } // prettier-ignore function IsObjectPromiseLike(schema: TObject) { const then = FunctionType([Any()], Any()) return IsObjectPropertyCount(schema, 0) || (IsObjectPropertyCount(schema, 1) && 'then' in schema.properties && IntoBooleanResult(Visit(schema.properties['then'], then)) === ExtendsResult.True) } // ------------------------------------------------------------------ // Property // ------------------------------------------------------------------ // prettier-ignore function Property(left: TSchema, right: TSchema) { return ( Visit(left, right) === ExtendsResult.False ? ExtendsResult.False : TypeGuard.IsOptional(left) && !TypeGuard.IsOptional(right) ? ExtendsResult.False : ExtendsResult.True ) } // prettier-ignore function FromObjectRight(left: TSchema, right: TObject) { return ( TypeGuard.IsUnknown(left) ? ExtendsResult.False : TypeGuard.IsAny(left) ? ExtendsResult.Union : ( TypeGuard.IsNever(left) || (TypeGuard.IsLiteralString(left) && IsObjectStringLike(right)) || (TypeGuard.IsLiteralNumber(left) && IsObjectNumberLike(right)) || (TypeGuard.IsLiteralBoolean(left) && IsObjectBooleanLike(right)) || (TypeGuard.IsSymbol(left) && IsObjectSymbolLike(right)) || (TypeGuard.IsBigInt(left) && IsObjectBigIntLike(right)) || (TypeGuard.IsString(left) && IsObjectStringLike(right)) || (TypeGuard.IsSymbol(left) && IsObjectSymbolLike(right)) || (TypeGuard.IsNumber(left) && IsObjectNumberLike(right)) || (TypeGuard.IsInteger(left) && IsObjectNumberLike(right)) || (TypeGuard.IsBoolean(left) && IsObjectBooleanLike(right)) || (TypeGuard.IsUint8Array(left) && IsObjectUint8ArrayLike(right)) || (TypeGuard.IsDate(left) && IsObjectDateLike(right)) || (TypeGuard.IsConstructor(left) && IsObjectConstructorLike(right)) || (TypeGuard.IsFunction(left) && IsObjectFunctionLike(right)) ) ? ExtendsResult.True : (TypeGuard.IsRecord(left) && TypeGuard.IsString(RecordKey(left))) ? (() => { // When expressing a Record with literal key values, the Record is converted into a Object with // the Hint assigned as `Record`. This is used to invert the extends logic. return right[Hint] === 'Record' ? ExtendsResult.True : ExtendsResult.False })() : (TypeGuard.IsRecord(left) && TypeGuard.IsNumber(RecordKey(left))) ? (() => { return IsObjectPropertyCount(right, 0) ? ExtendsResult.True : ExtendsResult.False })() : ExtendsResult.False ) } // prettier-ignore function FromObject(left: TObject, right: TSchema) { return ( IsStructuralRight(right) ? StructuralRight(left, right) : TypeGuard.IsRecord(right) ? FromRecordRight(left, right) : !TypeGuard.IsObject(right) ? ExtendsResult.False : (() => { for (const key of Object.getOwnPropertyNames(right.properties)) { if (!(key in left.properties) && !TypeGuard.IsOptional(right.properties[key])) { return ExtendsResult.False } if (TypeGuard.IsOptional(right.properties[key])) { return ExtendsResult.True } if (Property(left.properties[key], right.properties[key]) === ExtendsResult.False) { return ExtendsResult.False } } return ExtendsResult.True })() ) } // ------------------------------------------------------------------ // Promise // ------------------------------------------------------------------ // prettier-ignore function FromPromise(left: TPromise, right: TSchema) { return ( IsStructuralRight(right) ? StructuralRight(left, right) : TypeGuard.IsObject(right) && IsObjectPromiseLike(right) ? ExtendsResult.True : !TypeGuard.IsPromise(right) ? ExtendsResult.False : IntoBooleanResult(Visit(left.item, right.item)) ) } // ------------------------------------------------------------------ // Record // ------------------------------------------------------------------ // prettier-ignore function RecordKey(schema: TRecord) { return ( PatternNumberExact in schema.patternProperties ? Number() : PatternStringExact in schema.patternProperties ? String() : Throw('Unknown record key pattern') ) } // prettier-ignore function RecordValue(schema: TRecord) { return ( PatternNumberExact in schema.patternProperties ? schema.patternProperties[PatternNumberExact] : PatternStringExact in schema.patternProperties ? schema.patternProperties[PatternStringExact] : Throw('Unable to get record value schema') ) } // prettier-ignore function FromRecordRight(left: TSchema, right: TRecord) { const [Key, Value] = [RecordKey(right), RecordValue(right)] return ( ( TypeGuard.IsLiteralString(left) && TypeGuard.IsNumber(Key) && IntoBooleanResult(Visit(left, Value)) === ExtendsResult.True) ? ExtendsResult.True : TypeGuard.IsUint8Array(left) && TypeGuard.IsNumber(Key) ? Visit(left, Value) : TypeGuard.IsString(left) && TypeGuard.IsNumber(Key) ? Visit(left, Value) : TypeGuard.IsArray(left) && TypeGuard.IsNumber(Key) ? Visit(left, Value) : TypeGuard.IsObject(left) ? (() => { for (const key of Object.getOwnPropertyNames(left.properties)) { if (Property(Value, left.properties[key]) === ExtendsResult.False) { return ExtendsResult.False } } return ExtendsResult.True })() : ExtendsResult.False ) } // prettier-ignore function FromRecord(left: TRecord, right: TSchema) { return ( IsStructuralRight(right) ? StructuralRight(left, right) : TypeGuard.IsObject(right) ? FromObjectRight(left, right) : !TypeGuard.IsRecord(right) ? ExtendsResult.False : Visit(RecordValue(left), RecordValue(right)) ) } // ------------------------------------------------------------------ // RegExp // ------------------------------------------------------------------ // prettier-ignore function FromRegExp(left: TSchema, right: TSchema) { // Note: RegExp types evaluate as strings, not RegExp objects. // Here we remap either into string and continue evaluating. const L = TypeGuard.IsRegExp(left) ? String() : left const R = TypeGuard.IsRegExp(right) ? String() : right return Visit(L, R) } // ------------------------------------------------------------------ // String // ------------------------------------------------------------------ // prettier-ignore function FromStringRight(left: TSchema, right: TString) { return ( TypeGuard.IsLiteral(left) && ValueGuard.IsString(left.const) ? ExtendsResult.True : TypeGuard.IsString(left) ? ExtendsResult.True : ExtendsResult.False ) } // prettier-ignore function FromString(left: TString, right: TSchema): ExtendsResult { return ( IsStructuralRight(right) ? StructuralRight(left, right) : TypeGuard.IsObject(right) ? FromObjectRight(left, right) : TypeGuard.IsRecord(right) ? FromRecordRight(left, right) : TypeGuard.IsString(right) ? ExtendsResult.True : ExtendsResult.False ) } // ------------------------------------------------------------------ // Symbol // ------------------------------------------------------------------ // prettier-ignore function FromSymbol(left: TSymbol, right: TSchema): ExtendsResult { return ( IsStructuralRight(right) ? StructuralRight(left, right) : TypeGuard.IsObject(right) ? FromObjectRight(left, right) : TypeGuard.IsRecord(right) ? FromRecordRight(left, right) : TypeGuard.IsSymbol(right) ? ExtendsResult.True : ExtendsResult.False ) } // ------------------------------------------------------------------ // TemplateLiteral // ------------------------------------------------------------------ // prettier-ignore function FromTemplateLiteral(left: TSchema, right: TSchema) { // TemplateLiteral types are resolved to either unions for finite expressions or string // for infinite expressions. Here we call to TemplateLiteralResolver to resolve for // either type and continue evaluating. return ( TypeGuard.IsTemplateLiteral(left) ? Visit(TemplateLiteralToUnion(left), right) : TypeGuard.IsTemplateLiteral(right) ? Visit(left, TemplateLiteralToUnion(right)) : Throw('Invalid fallthrough for TemplateLiteral') ) } // ------------------------------------------------------------------ // Tuple // ------------------------------------------------------------------ // prettier-ignore function IsArrayOfTuple(left: TTuple, right: TSchema) { return ( TypeGuard.IsArray(right) && left.items !== undefined && left.items.every((schema) => Visit(schema, right.items) === ExtendsResult.True) ) } // prettier-ignore function FromTupleRight(left: TSchema, right: TTuple) { return ( TypeGuard.IsNever(left) ? ExtendsResult.True : TypeGuard.IsUnknown(left) ? ExtendsResult.False : TypeGuard.IsAny(left) ? ExtendsResult.Union : ExtendsResult.False ) } // prettier-ignore function FromTuple(left: TTuple, right: TSchema): ExtendsResult { return ( IsStructuralRight(right) ? StructuralRight(left, right) : TypeGuard.IsObject(right) && IsObjectArrayLike(right) ? ExtendsResult.True : TypeGuard.IsArray(right) && IsArrayOfTuple(left, right) ? ExtendsResult.True : !TypeGuard.IsTuple(right) ? ExtendsResult.False : (ValueGuard.IsUndefined(left.items) && !ValueGuard.IsUndefined(right.items)) || (!ValueGuard.IsUndefined(left.items) && ValueGuard.IsUndefined(right.items)) ? ExtendsResult.False : (ValueGuard.IsUndefined(left.items) && !ValueGuard.IsUndefined(right.items)) ? ExtendsResult.True : left.items!.every((schema, index) => Visit(schema, right.items![index]) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False ) } // ------------------------------------------------------------------ // Uint8Array // ------------------------------------------------------------------ // prettier-ignore function FromUint8Array(left: TUint8Array, right: TSchema) { return ( IsStructuralRight(right) ? StructuralRight(left, right) : TypeGuard.IsObject(right) ? FromObjectRight(left, right) : TypeGuard.IsRecord(right) ? FromRecordRight(left, right) : TypeGuard.IsUint8Array(right) ? ExtendsResult.True : ExtendsResult.False ) } // ------------------------------------------------------------------ // Undefined // ------------------------------------------------------------------ // prettier-ignore function FromUndefined(left: TUndefined, right: TSchema) { return ( IsStructuralRight(right) ? StructuralRight(left, right) : TypeGuard.IsObject(right) ? FromObjectRight(left, right) : TypeGuard.IsRecord(right) ? FromRecordRight(left, right) : TypeGuard.IsVoid(right) ? FromVoidRight(left, right) : TypeGuard.IsUndefined(right) ? ExtendsResult.True : ExtendsResult.False ) } // ------------------------------------------------------------------ // Union // ------------------------------------------------------------------ // prettier-ignore function FromUnionRight(left: TSchema, right: TUnion): ExtendsResult { return right.anyOf.some((schema) => Visit(left, schema) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False } // prettier-ignore function FromUnion(left: TUnion, right: TSchema): ExtendsResult { return left.anyOf.every((schema) => Visit(schema, right) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False } // ------------------------------------------------------------------ // Unknown // ------------------------------------------------------------------ // prettier-ignore function FromUnknownRight(left: TSchema, right: TUnknown) { return ExtendsResult.True } // prettier-ignore function FromUnknown(left: TUnknown, right: TSchema) { return ( TypeGuard.IsNever(right) ? FromNeverRight(left, right) : TypeGuard.IsIntersect(right) ? FromIntersectRight(left, right) : TypeGuard.IsUnion(right) ? FromUnionRight(left, right) : TypeGuard.IsAny(right) ? FromAnyRight(left, right) : TypeGuard.IsString(right) ? FromStringRight(left, right) : TypeGuard.IsNumber(right) ? FromNumberRight(left, right) : TypeGuard.IsInteger(right) ? FromIntegerRight(left, right) : TypeGuard.IsBoolean(right) ? FromBooleanRight(left, right) : TypeGuard.IsArray(right) ? FromArrayRight(left, right) : TypeGuard.IsTuple(right) ? FromTupleRight(left, right) : TypeGuard.IsObject(right) ? FromObjectRight(left, right) : TypeGuard.IsUnknown(right) ? ExtendsResult.True : ExtendsResult.False ) } // ------------------------------------------------------------------ // Void // ------------------------------------------------------------------ // prettier-ignore function FromVoidRight(left: TSchema, right: TVoid) { return ( TypeGuard.IsUndefined(left) ? ExtendsResult.True : TypeGuard.IsUndefined(left) ? ExtendsResult.True : ExtendsResult.False ) } // prettier-ignore function FromVoid(left: TVoid, right: TSchema) { return ( TypeGuard.IsIntersect(right) ? FromIntersectRight(left, right) : TypeGuard.IsUnion(right) ? FromUnionRight(left, right) : TypeGuard.IsUnknown(right) ? FromUnknownRight(left, right) : TypeGuard.IsAny(right) ? FromAnyRight(left, right) : TypeGuard.IsObject(right) ? FromObjectRight(left, right) : TypeGuard.IsVoid(right) ? ExtendsResult.True : ExtendsResult.False ) } // prettier-ignore function Visit(left: TSchema, right: TSchema): ExtendsResult { return ( // resolvable (TypeGuard.IsTemplateLiteral(left) || TypeGuard.IsTemplateLiteral(right)) ? FromTemplateLiteral(left, right) : (TypeGuard.IsRegExp(left) || TypeGuard.IsRegExp(right)) ? FromRegExp(left, right) : (TypeGuard.IsNot(left) || TypeGuard.IsNot(right)) ? FromNot(left, right) : // standard TypeGuard.IsAny(left) ? FromAny(left, right) : TypeGuard.IsArray(left) ? FromArray(left, right) : TypeGuard.IsBigInt(left) ? FromBigInt(left, right) : TypeGuard.IsBoolean(left) ? FromBoolean(left, right) : TypeGuard.IsAsyncIterator(left) ? FromAsyncIterator(left, right) : TypeGuard.IsConstructor(left) ? FromConstructor(left, right) : TypeGuard.IsDate(left) ? FromDate(left, right) : TypeGuard.IsFunction(left) ? FromFunction(left, right) : TypeGuard.IsInteger(left) ? FromInteger(left, right) : TypeGuard.IsIntersect(left) ? FromIntersect(left, right) : TypeGuard.IsIterator(left) ? FromIterator(left, right) : TypeGuard.IsLiteral(left) ? FromLiteral(left, right) : TypeGuard.IsNever(left) ? FromNever(left, right) : TypeGuard.IsNull(left) ? FromNull(left, right) : TypeGuard.IsNumber(left) ? FromNumber(left, right) : TypeGuard.IsObject(left) ? FromObject(left, right) : TypeGuard.IsRecord(left) ? FromRecord(left, right) : TypeGuard.IsString(left) ? FromString(left, right) : TypeGuard.IsSymbol(left) ? FromSymbol(left, right) : TypeGuard.IsTuple(left) ? FromTuple(left, right) : TypeGuard.IsPromise(left) ? FromPromise(left, right) : TypeGuard.IsUint8Array(left) ? FromUint8Array(left, right) : TypeGuard.IsUndefined(left) ? FromUndefined(left, right) : TypeGuard.IsUnion(left) ? FromUnion(left, right) : TypeGuard.IsUnknown(left) ? FromUnknown(left, right) : TypeGuard.IsVoid(left) ? FromVoid(left, right) : Throw(`Unknown left type operand '${left[Kind]}'`) ) } export function ExtendsCheck(left: TSchema, right: TSchema): ExtendsResult { return Visit(left, right) } sinclairzx81-typebox-e0ec98c/src/type/extends/extends-from-mapped-key.ts000066400000000000000000000107671505437577000265320ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import type { TProperties } from '../object/index' import type { Assert } from '../helpers/index' import { MappedResult, type TMappedResult, type TMappedKey } from '../mapped/index' import { Literal, type TLiteral, type TLiteralValue } from '../literal/index' import { Extends, type TExtends } from './extends' import { Clone } from '../clone/value' // ------------------------------------------------------------------ // FromPropertyKey // ------------------------------------------------------------------ // prettier-ignore type TFromPropertyKey< K extends PropertyKey, U extends TSchema, L extends TSchema, R extends TSchema > = { [_ in K]: TExtends>, U, L, R> } // prettier-ignore function FromPropertyKey< K extends PropertyKey, U extends TSchema, L extends TSchema, R extends TSchema >(K: K, U: U, L: L, R: R, options?: SchemaOptions): TFromPropertyKey { return { [K]: Extends(Literal(K as TLiteralValue), U, L, R, Clone(options)) as any } as never } // ------------------------------------------------------------------ // FromPropertyKeys // ------------------------------------------------------------------ // prettier-ignore type TFromPropertyKeys< K extends PropertyKey[], U extends TSchema, L extends TSchema, R extends TSchema, Acc extends TProperties = {} > = ( K extends [infer LK extends PropertyKey, ...infer RK extends PropertyKey[]] ? TFromPropertyKeys> : Acc ) // prettier-ignore function FromPropertyKeys< K extends PropertyKey[], U extends TSchema, L extends TSchema, R extends TSchema >(K: [...K], U: U, L: L, R: R, options?: SchemaOptions): TFromPropertyKeys { return K.reduce((Acc, LK) => { return { ...Acc, ...FromPropertyKey(LK, U, L, R, options) } }, {} as TProperties) as never } // ------------------------------------------------------------------ // FromMappedKey // ------------------------------------------------------------------ // prettier-ignore type TFromMappedKey< K extends TMappedKey, U extends TSchema, L extends TSchema, R extends TSchema > = ( TFromPropertyKeys ) // prettier-ignore function FromMappedKey< K extends TMappedKey, U extends TSchema, L extends TSchema, R extends TSchema >(K: K, U: U, L: L, R: R, options?: SchemaOptions): TFromMappedKey { return FromPropertyKeys(K.keys, U, L, R, options) as never } // ------------------------------------------------------------------ // ExtendsFromMappedKey // ------------------------------------------------------------------ // prettier-ignore export type TExtendsFromMappedKey< T extends TMappedKey, U extends TSchema, L extends TSchema, R extends TSchema, P extends TProperties = TFromMappedKey > = ( TMappedResult

) // prettier-ignore export function ExtendsFromMappedKey< T extends TMappedKey, U extends TSchema, L extends TSchema, R extends TSchema, P extends TProperties = TFromMappedKey >(T: T, U: U, L: L, R: R, options?: SchemaOptions): TMappedResult

{ const P = FromMappedKey(T, U, L, R, options) return MappedResult(P) as never } sinclairzx81-typebox-e0ec98c/src/type/extends/extends-from-mapped-result.ts000066400000000000000000000075751505437577000272630ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import type { TProperties } from '../object/index' import { MappedResult, type TMappedResult } from '../mapped/index' import { Extends, type TExtends } from './extends' import { Clone } from '../clone/value' // ------------------------------------------------------------------ // FromProperties // ------------------------------------------------------------------ // prettier-ignore type TFromProperties< P extends TProperties, Right extends TSchema, False extends TSchema, True extends TSchema > = ( { [K2 in keyof P]: TExtends } ) // prettier-ignore function FromProperties< P extends TProperties, Right extends TSchema, True extends TSchema, False extends TSchema >(P: P, Right: Right, True: True, False: False, options?: SchemaOptions): TFromProperties { const Acc = {} as TProperties for(const K2 of globalThis.Object.getOwnPropertyNames(P)) Acc[K2] = Extends(P[K2], Right, True, False, Clone(options)) return Acc as never } // ------------------------------------------------------------------ // FromMappedResult // ------------------------------------------------------------------ // prettier-ignore type TFromMappedResult< Left extends TMappedResult, Right extends TSchema, True extends TSchema, False extends TSchema > = ( TFromProperties ) // prettier-ignore function FromMappedResult< Left extends TMappedResult, Right extends TSchema, True extends TSchema, False extends TSchema >(Left: Left, Right: Right, True: True, False: False, options?: SchemaOptions): TFromMappedResult { return FromProperties(Left.properties, Right, True, False, options) as never } // ------------------------------------------------------------------ // ExtendsFromMappedResult // ------------------------------------------------------------------ // prettier-ignore export type TExtendsFromMappedResult< Left extends TMappedResult, Right extends TSchema, True extends TSchema, False extends TSchema, P extends TProperties = TFromMappedResult > = ( TMappedResult

) // prettier-ignore export function ExtendsFromMappedResult< Left extends TMappedResult, Right extends TSchema, True extends TSchema, False extends TSchema, P extends TProperties = TFromMappedResult >(Left: Left, Right: Right, True: True, False: False, options?: SchemaOptions): TMappedResult

{ const P = FromMappedResult(Left, Right, True, False, options) return MappedResult(P) as never } sinclairzx81-typebox-e0ec98c/src/type/extends/extends-undefined.ts000066400000000000000000000043631505437577000254710ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema } from '../schema/index' import type { TIntersect } from '../intersect/index' import type { TUnion } from '../union/index' import type { TNot } from '../not/index' import { Kind } from '../symbols/index' /** Fast undefined check used for properties of type undefined */ function Intersect(schema: TIntersect) { return schema.allOf.every((schema) => ExtendsUndefinedCheck(schema)) } function Union(schema: TUnion) { return schema.anyOf.some((schema) => ExtendsUndefinedCheck(schema)) } function Not(schema: TNot) { return !ExtendsUndefinedCheck(schema.not) } /** Fast undefined check used for properties of type undefined */ // prettier-ignore export function ExtendsUndefinedCheck(schema: TSchema): boolean { return ( schema[Kind] === 'Intersect' ? Intersect(schema as TIntersect) : schema[Kind] === 'Union' ? Union(schema as TUnion) : schema[Kind] === 'Not' ? Not(schema as TNot) : schema[Kind] === 'Undefined' ? true : false ) } sinclairzx81-typebox-e0ec98c/src/type/extends/extends.ts000066400000000000000000000101351505437577000235240ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import type { Static } from '../static/index' import { type TUnion, Union } from '../union/index' import { TMappedKey, TMappedResult } from '../mapped/index' import { ExtendsCheck, ExtendsResult } from './extends-check' import { UnionToTuple } from '../helpers/index' import { ExtendsFromMappedKey, type TExtendsFromMappedKey } from './extends-from-mapped-key' import { ExtendsFromMappedResult, type TExtendsFromMappedResult } from './extends-from-mapped-result' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsMappedKey, IsMappedResult } from '../guard/kind' // prettier-ignore type TExtendsResolve = ( (Static extends Static ? T : U) extends infer O extends TSchema ? UnionToTuple extends [infer X extends TSchema, infer Y extends TSchema] ? TUnion<[X, Y]> : O : never ) // prettier-ignore function ExtendsResolve(left: L, right: R, trueType: T, falseType: U): TExtendsResolve { const R = ExtendsCheck(left, right) return ( R === ExtendsResult.Union ? Union([trueType, falseType]) : R === ExtendsResult.True ? trueType : falseType ) as never } // ------------------------------------------------------------------ // TExtends // ------------------------------------------------------------------ export type TExtends = TExtendsResolve /** `[Json]` Creates a Conditional type */ export function Extends(L: L, R: R, T: T, F: F, options?: SchemaOptions): TExtendsFromMappedResult /** `[Json]` Creates a Conditional type */ export function Extends(L: L, R: R, T: T, F: F, options?: SchemaOptions): TExtendsFromMappedKey /** `[Json]` Creates a Conditional type */ export function Extends(L: L, R: R, T: T, F: F, options?: SchemaOptions): TExtends /** `[Json]` Creates a Conditional type */ export function Extends(L: L, R: R, T: T, F: F, options?: SchemaOptions) { // prettier-ignore return ( IsMappedResult(L) ? ExtendsFromMappedResult(L, R, T, F, options) : IsMappedKey(L) ? CreateType(ExtendsFromMappedKey(L, R, T, F, options)) : CreateType(ExtendsResolve(L, R, T, F), options) ) as never } sinclairzx81-typebox-e0ec98c/src/type/extends/index.ts000066400000000000000000000027201505437577000231620ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './extends-check' export * from './extends-from-mapped-key' export * from './extends-from-mapped-result' export * from './extends-undefined' export * from './extends' sinclairzx81-typebox-e0ec98c/src/type/extract/000077500000000000000000000000001505437577000215025ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/extract/extract-from-mapped-result.ts000066400000000000000000000061631505437577000272530ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema } from '../schema/index' import type { TProperties } from '../object/index' import { MappedResult, type TMappedResult } from '../mapped/index' import { Extract, type TExtract } from './extract' // ------------------------------------------------------------------ // FromProperties // ------------------------------------------------------------------ // prettier-ignore type TFromProperties< P extends TProperties, T extends TSchema > = ( { [K2 in keyof P]: TExtract } ) // prettier-ignore function FromProperties< P extends TProperties, T extends TSchema >(P: P, T: T): TFromProperties { const Acc = {} as TProperties for(const K2 of globalThis.Object.getOwnPropertyNames(P)) Acc[K2] = Extract(P[K2], T) return Acc as never } // ------------------------------------------------------------------ // FromMappedResult // ------------------------------------------------------------------ // prettier-ignore type TFromMappedResult< R extends TMappedResult, T extends TSchema > = ( TFromProperties ) // prettier-ignore function FromMappedResult< R extends TMappedResult, T extends TSchema >(R: R, T: T): TFromMappedResult { return FromProperties(R.properties, T) as never } // ------------------------------------------------------------------ // ExtractFromMappedResult // ------------------------------------------------------------------ // prettier-ignore export type TExtractFromMappedResult< R extends TMappedResult, T extends TSchema, P extends TProperties = TFromMappedResult > = ( TMappedResult

) // prettier-ignore export function ExtractFromMappedResult< R extends TMappedResult, T extends TSchema, P extends TProperties = TFromMappedResult >(R: R, T: T): TMappedResult

{ const P = FromMappedResult(R, T) return MappedResult(P) as never } sinclairzx81-typebox-e0ec98c/src/type/extract/extract-from-template-literal.ts000066400000000000000000000035251505437577000277350ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema } from '../schema/index' import { Extract, type TExtract } from './extract' import { TemplateLiteralToUnion, type TTemplateLiteral, type TTemplateLiteralToUnion } from '../template-literal/index' // prettier-ignore export type TExtractFromTemplateLiteral = ( TExtract, R> ) export function ExtractFromTemplateLiteral(L: L, R: R): TExtractFromTemplateLiteral { return Extract(TemplateLiteralToUnion(L), R) as never } sinclairzx81-typebox-e0ec98c/src/type/extract/extract.ts000066400000000000000000000107451505437577000235330ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import type { AssertRest, AssertType, UnionToTuple } from '../helpers/index' import type { TMappedResult } from '../mapped/index' import { Union, type TUnion } from '../union/index' import { type Static } from '../static/index' import { Never, type TNever } from '../never/index' import { type TUnionEvaluated } from '../union/index' import { type TTemplateLiteral } from '../template-literal/index' import { ExtendsCheck, ExtendsResult } from '../extends/index' import { ExtractFromMappedResult, type TExtractFromMappedResult } from './extract-from-mapped-result' import { ExtractFromTemplateLiteral, type TExtractFromTemplateLiteral } from './extract-from-template-literal' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsMappedResult, IsTemplateLiteral, IsUnion } from '../guard/kind' // ------------------------------------------------------------------ // ExtractRest // ------------------------------------------------------------------ // prettier-ignore type TExtractRest = AssertRest> extends Static ? L[K] : never }[number]>> extends infer R extends TSchema[] ? TUnionEvaluated : never function ExtractRest(L: [...L], R: R) { const extracted = L.filter((inner) => ExtendsCheck(inner, R) !== ExtendsResult.False) return extracted.length === 1 ? extracted[0] : Union(extracted) } // ------------------------------------------------------------------ // TExtract // ------------------------------------------------------------------ // prettier-ignore export type TExtract = ( L extends TUnion ? TExtractRest : L extends U ? L : TNever ) /** `[Json]` Constructs a type by extracting from type all union members that are assignable to union */ export function Extract(type: L, union: R, options?: SchemaOptions): TExtractFromMappedResult /** `[Json]` Constructs a type by extracting from type all union members that are assignable to union */ export function Extract(type: L, union: R, options?: SchemaOptions): TExtractFromTemplateLiteral /** `[Json]` Constructs a type by extracting from type all union members that are assignable to union */ export function Extract(type: L, union: R, options?: SchemaOptions): TExtract /** `[Json]` Constructs a type by extracting from type all union members that are assignable to union */ export function Extract(L: TSchema, R: TSchema, options?: SchemaOptions): never { // overloads if (IsTemplateLiteral(L)) return CreateType(ExtractFromTemplateLiteral(L, R), options) as never if (IsMappedResult(L)) return CreateType(ExtractFromMappedResult(L, R), options) as never // prettier-ignore return CreateType( IsUnion(L) ? ExtractRest(L.anyOf, R) : ExtendsCheck(L, R) !== ExtendsResult.False ? L : Never() , options) as never } sinclairzx81-typebox-e0ec98c/src/type/extract/index.ts000066400000000000000000000026221505437577000231630ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './extract-from-mapped-result' export * from './extract-from-template-literal' export * from './extract' sinclairzx81-typebox-e0ec98c/src/type/function/000077500000000000000000000000001505437577000216555ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/function/function.ts000066400000000000000000000063631505437577000240620ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import type { Static } from '../static/index' import type { Ensure } from '../helpers/index' import type { TReadonlyOptional } from '../readonly-optional/index' import type { TReadonly } from '../readonly/index' import type { TOptional } from '../optional/index' import { Kind } from '../symbols/index' // ------------------------------------------------------------------ // StaticFunction // ------------------------------------------------------------------ type StaticReturnType = Static // prettier-ignore type StaticParameter = T extends TReadonlyOptional ? [Readonly>?] : T extends TReadonly ? [Readonly>] : T extends TOptional ? [Static?] : [Static] // prettier-ignore type StaticParameters = ( T extends [infer L extends TSchema, ...infer R extends TSchema[]] ? StaticParameters]> : Acc ) // prettier-ignore type StaticFunction = Ensure<(...param: StaticParameters) => StaticReturnType> // ------------------------------------------------------------------ // TFunction // ------------------------------------------------------------------ export interface TFunction extends TSchema { [Kind]: 'Function' static: StaticFunction type: 'Function' parameters: T returns: U } /** `[JavaScript]` Creates a Function type */ export function Function(parameters: [...T], returns: U, options?: SchemaOptions): TFunction { return CreateType({ [Kind]: 'Function', type: 'Function', parameters, returns }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/function/index.ts000066400000000000000000000024661505437577000233440ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './function' sinclairzx81-typebox-e0ec98c/src/type/guard/000077500000000000000000000000001505437577000211325ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/guard/index.ts000066400000000000000000000026111505437577000226110ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * as KindGuard from './kind' export * as TypeGuard from './type' export * as ValueGuard from './value' sinclairzx81-typebox-e0ec98c/src/type/guard/kind.ts000066400000000000000000000315001505437577000224260ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import * as ValueGuard from './value' import { Kind, Hint, TransformKind, ReadonlyKind, OptionalKind } from '../symbols/index' import { TransformOptions } from '../transform/index' import type { TAny } from '../any/index' import type { TArgument } from '../argument/index' import type { TArray } from '../array/index' import type { TAsyncIterator } from '../async-iterator/index' import type { TBoolean } from '../boolean/index' import type { TComputed } from '../computed/index' import type { TBigInt } from '../bigint/index' import type { TConstructor } from '../constructor/index' import type { TFunction } from '../function/index' import type { TImport } from '../module/index' import type { TInteger } from '../integer/index' import type { TIntersect } from '../intersect/index' import type { TIterator } from '../iterator/index' import type { TLiteral, TLiteralValue } from '../literal/index' import type { TMappedKey, TMappedResult } from '../mapped/index' import type { TNever } from '../never/index' import type { TNot } from '../not/index' import type { TNull } from '../null/index' import type { TNumber } from '../number/index' import type { TObject, TProperties } from '../object/index' import type { TOptional } from '../optional/index' import type { TPromise } from '../promise/index' import type { TReadonly } from '../readonly/index' import type { TRecord } from '../record/index' import type { TRef } from '../ref/index' import type { TRegExp } from '../regexp/index' import type { TSchema } from '../schema/index' import type { TString } from '../string/index' import type { TSymbol } from '../symbol/index' import type { TTemplateLiteral } from '../template-literal/index' import type { TTuple } from '../tuple/index' import type { TUint8Array } from '../uint8array/index' import type { TUndefined } from '../undefined/index' import type { TUnknown } from '../unknown/index' import type { TUnion } from '../union/index' import type { TUnsafe } from '../unsafe/index' import type { TVoid } from '../void/index' import type { TDate } from '../date/index' import type { TThis } from '../recursive/index' /** `[Kind-Only]` Returns true if this value has a Readonly symbol */ export function IsReadonly(value: T): value is TReadonly { return ValueGuard.IsObject(value) && value[ReadonlyKind] === 'Readonly' } /** `[Kind-Only]` Returns true if this value has a Optional symbol */ export function IsOptional(value: T): value is TOptional { return ValueGuard.IsObject(value) && value[OptionalKind] === 'Optional' } /** `[Kind-Only]` Returns true if the given value is TAny */ export function IsAny(value: unknown): value is TAny { return IsKindOf(value, 'Any') } /** `[Kind-Only]` Returns true if the given value is TArgument */ export function IsArgument(value: unknown): value is TArgument { return IsKindOf(value, 'Argument') } /** `[Kind-Only]` Returns true if the given value is TArray */ export function IsArray(value: unknown): value is TArray { return IsKindOf(value, 'Array') } /** `[Kind-Only]` Returns true if the given value is TAsyncIterator */ export function IsAsyncIterator(value: unknown): value is TAsyncIterator { return IsKindOf(value, 'AsyncIterator') } /** `[Kind-Only]` Returns true if the given value is TBigInt */ export function IsBigInt(value: unknown): value is TBigInt { return IsKindOf(value, 'BigInt') } /** `[Kind-Only]` Returns true if the given value is TBoolean */ export function IsBoolean(value: unknown): value is TBoolean { return IsKindOf(value, 'Boolean') } /** `[Kind-Only]` Returns true if the given value is TComputed */ export function IsComputed(value: unknown): value is TComputed { return IsKindOf(value, 'Computed') } /** `[Kind-Only]` Returns true if the given value is TConstructor */ export function IsConstructor(value: unknown): value is TConstructor { return IsKindOf(value, 'Constructor') } /** `[Kind-Only]` Returns true if the given value is TDate */ export function IsDate(value: unknown): value is TDate { return IsKindOf(value, 'Date') } /** `[Kind-Only]` Returns true if the given value is TFunction */ export function IsFunction(value: unknown): value is TFunction { return IsKindOf(value, 'Function') } /** `[Kind-Only]` Returns true if the given value is TInteger */ export function IsImport(value: unknown): value is TImport { return IsKindOf(value, 'Import') } /** `[Kind-Only]` Returns true if the given value is TInteger */ export function IsInteger(value: unknown): value is TInteger { return IsKindOf(value, 'Integer') } /** `[Kind-Only]` Returns true if the given schema is TProperties */ export function IsProperties(value: unknown): value is TProperties { return ValueGuard.IsObject(value) } /** `[Kind-Only]` Returns true if the given value is TIntersect */ export function IsIntersect(value: unknown): value is TIntersect { return IsKindOf(value, 'Intersect') } /** `[Kind-Only]` Returns true if the given value is TIterator */ export function IsIterator(value: unknown): value is TIterator { return IsKindOf(value, 'Iterator') } /** `[Kind-Only]` Returns true if the given value is a TKind with the given name. */ export function IsKindOf(value: unknown, kind: T): value is Record & { [Kind]: T } { return ValueGuard.IsObject(value) && Kind in value && value[Kind] === kind } /** `[Kind-Only]` Returns true if the given value is TLiteral */ export function IsLiteralString(value: unknown): value is TLiteral { return IsLiteral(value) && ValueGuard.IsString(value.const) } /** `[Kind-Only]` Returns true if the given value is TLiteral */ export function IsLiteralNumber(value: unknown): value is TLiteral { return IsLiteral(value) && ValueGuard.IsNumber(value.const) } /** `[Kind-Only]` Returns true if the given value is TLiteral */ export function IsLiteralBoolean(value: unknown): value is TLiteral { return IsLiteral(value) && ValueGuard.IsBoolean(value.const) } /** `[Kind-Only]` Returns true if the given value is TLiteralValue */ export function IsLiteralValue(value: unknown): value is TLiteralValue { return ValueGuard.IsBoolean(value) || ValueGuard.IsNumber(value) || ValueGuard.IsString(value) } /** `[Kind-Only]` Returns true if the given value is TLiteral */ export function IsLiteral(value: unknown): value is TLiteral { return IsKindOf(value, 'Literal') } /** `[Kind-Only]` Returns true if the given value is a TMappedKey */ export function IsMappedKey(value: unknown): value is TMappedKey { return IsKindOf(value, 'MappedKey') } /** `[Kind-Only]` Returns true if the given value is TMappedResult */ export function IsMappedResult(value: unknown): value is TMappedResult { return IsKindOf(value, 'MappedResult') } /** `[Kind-Only]` Returns true if the given value is TNever */ export function IsNever(value: unknown): value is TNever { return IsKindOf(value, 'Never') } /** `[Kind-Only]` Returns true if the given value is TNot */ export function IsNot(value: unknown): value is TNot { return IsKindOf(value, 'Not') } /** `[Kind-Only]` Returns true if the given value is TNull */ export function IsNull(value: unknown): value is TNull { return IsKindOf(value, 'Null') } /** `[Kind-Only]` Returns true if the given value is TNumber */ export function IsNumber(value: unknown): value is TNumber { return IsKindOf(value, 'Number') } /** `[Kind-Only]` Returns true if the given value is TObject */ export function IsObject(value: unknown): value is TObject { return IsKindOf(value, 'Object') } /** `[Kind-Only]` Returns true if the given value is TPromise */ export function IsPromise(value: unknown): value is TPromise { return IsKindOf(value, 'Promise') } /** `[Kind-Only]` Returns true if the given value is TRecord */ export function IsRecord(value: unknown): value is TRecord { return IsKindOf(value, 'Record') } /** `[Kind-Only]` Returns true if this value is TRecursive */ export function IsRecursive(value: unknown): value is { [Hint]: 'Recursive' } { return ValueGuard.IsObject(value) && Hint in value && value[Hint] === 'Recursive' } /** `[Kind-Only]` Returns true if the given value is TRef */ export function IsRef(value: unknown): value is TRef { return IsKindOf(value, 'Ref') } /** `[Kind-Only]` Returns true if the given value is TRegExp */ export function IsRegExp(value: unknown): value is TRegExp { return IsKindOf(value, 'RegExp') } /** `[Kind-Only]` Returns true if the given value is TString */ export function IsString(value: unknown): value is TString { return IsKindOf(value, 'String') } /** `[Kind-Only]` Returns true if the given value is TSymbol */ export function IsSymbol(value: unknown): value is TSymbol { return IsKindOf(value, 'Symbol') } /** `[Kind-Only]` Returns true if the given value is TTemplateLiteral */ export function IsTemplateLiteral(value: unknown): value is TTemplateLiteral { return IsKindOf(value, 'TemplateLiteral') } /** `[Kind-Only]` Returns true if the given value is TThis */ export function IsThis(value: unknown): value is TThis { return IsKindOf(value, 'This') } /** `[Kind-Only]` Returns true of this value is TTransform */ export function IsTransform(value: unknown): value is { [TransformKind]: TransformOptions } { return ValueGuard.IsObject(value) && TransformKind in value } /** `[Kind-Only]` Returns true if the given value is TTuple */ export function IsTuple(value: unknown): value is TTuple { return IsKindOf(value, 'Tuple') } /** `[Kind-Only]` Returns true if the given value is TUndefined */ export function IsUndefined(value: unknown): value is TUndefined { return IsKindOf(value, 'Undefined') } /** `[Kind-Only]` Returns true if the given value is TUnion */ export function IsUnion(value: unknown): value is TUnion { return IsKindOf(value, 'Union') } /** `[Kind-Only]` Returns true if the given value is TUint8Array */ export function IsUint8Array(value: unknown): value is TUint8Array { return IsKindOf(value, 'Uint8Array') } /** `[Kind-Only]` Returns true if the given value is TUnknown */ export function IsUnknown(value: unknown): value is TUnknown { return IsKindOf(value, 'Unknown') } /** `[Kind-Only]` Returns true if the given value is a raw TUnsafe */ export function IsUnsafe(value: unknown): value is TUnsafe { return IsKindOf(value, 'Unsafe') } /** `[Kind-Only]` Returns true if the given value is TVoid */ export function IsVoid(value: unknown): value is TVoid { return IsKindOf(value, 'Void') } /** `[Kind-Only]` Returns true if the given value is TKind */ export function IsKind(value: unknown): value is Record & { [Kind]: string } { return ValueGuard.IsObject(value) && Kind in value && ValueGuard.IsString(value[Kind]) } /** `[Kind-Only]` Returns true if the given value is TSchema */ export function IsSchema(value: unknown): value is TSchema { // prettier-ignore return ( IsAny(value) || IsArgument(value) || IsArray(value) || IsBoolean(value) || IsBigInt(value) || IsAsyncIterator(value) || IsComputed(value) || IsConstructor(value) || IsDate(value) || IsFunction(value) || IsInteger(value) || IsIntersect(value) || IsIterator(value) || IsLiteral(value) || IsMappedKey(value) || IsMappedResult(value) || IsNever(value) || IsNot(value) || IsNull(value) || IsNumber(value) || IsObject(value) || IsPromise(value) || IsRecord(value) || IsRef(value) || IsRegExp(value) || IsString(value) || IsSymbol(value) || IsTemplateLiteral(value) || IsThis(value) || IsTuple(value) || IsUndefined(value) || IsUnion(value) || IsUint8Array(value) || IsUnknown(value) || IsUnsafe(value) || IsVoid(value) || IsKind(value) ) } sinclairzx81-typebox-e0ec98c/src/type/guard/type.ts000066400000000000000000000542161505437577000224730ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import * as ValueGuard from './value' import { Kind, Hint, TransformKind, ReadonlyKind, OptionalKind } from '../symbols/index' import { TypeBoxError } from '../error/index' import { TransformOptions } from '../transform/index' import type { TAny } from '../any/index' import type { TArgument } from '../argument/index' import type { TArray } from '../array/index' import type { TAsyncIterator } from '../async-iterator/index' import type { TBoolean } from '../boolean/index' import type { TComputed } from '../computed/index' import type { TBigInt } from '../bigint/index' import type { TConstructor } from '../constructor/index' import type { TFunction } from '../function/index' import type { TImport } from '../module/index' import type { TInteger } from '../integer/index' import type { TIntersect } from '../intersect/index' import type { TIterator } from '../iterator/index' import type { TLiteral, TLiteralValue } from '../literal/index' import type { TMappedKey, TMappedResult } from '../mapped/index' import type { TNever } from '../never/index' import type { TNot } from '../not/index' import type { TNull } from '../null/index' import type { TNumber } from '../number/index' import type { TObject, TAdditionalProperties, TProperties } from '../object/index' import type { TOptional } from '../optional/index' import type { TPromise } from '../promise/index' import type { TReadonly } from '../readonly/index' import type { TRecord } from '../record/index' import type { TRef } from '../ref/index' import type { TRegExp } from '../regexp/index' import type { TSchema } from '../schema/index' import type { TString } from '../string/index' import type { TSymbol } from '../symbol/index' import type { TTemplateLiteral } from '../template-literal/index' import type { TTuple } from '../tuple/index' import type { TUint8Array } from '../uint8array/index' import type { TUndefined } from '../undefined/index' import type { TUnion } from '../union/index' import type { TUnknown } from '../unknown/index' import type { TUnsafe } from '../unsafe/index' import type { TVoid } from '../void/index' import type { TDate } from '../date/index' import type { TThis } from '../recursive/index' export class TypeGuardUnknownTypeError extends TypeBoxError {} const KnownTypes = [ 'Argument', 'Any', 'Array', 'AsyncIterator', 'BigInt', 'Boolean', 'Computed', 'Constructor', 'Date', 'Enum', 'Function', 'Integer', 'Intersect', 'Iterator', 'Literal', 'MappedKey', 'MappedResult', 'Not', 'Null', 'Number', 'Object', 'Promise', 'Record', 'Ref', 'RegExp', 'String', 'Symbol', 'TemplateLiteral', 'This', 'Tuple', 'Undefined', 'Union', 'Uint8Array', 'Unknown', 'Void', ] function IsPattern(value: unknown): value is string { try { new RegExp(value as string) return true } catch { return false } } function IsControlCharacterFree(value: unknown): value is string { if (!ValueGuard.IsString(value)) return false for (let i = 0; i < value.length; i++) { const code = value.charCodeAt(i) if ((code >= 7 && code <= 13) || code === 27 || code === 127) { return false } } return true } function IsAdditionalProperties(value: unknown): value is TAdditionalProperties { return IsOptionalBoolean(value) || IsSchema(value) } function IsOptionalBigInt(value: unknown): value is bigint | undefined { return ValueGuard.IsUndefined(value) || ValueGuard.IsBigInt(value) } function IsOptionalNumber(value: unknown): value is number | undefined { return ValueGuard.IsUndefined(value) || ValueGuard.IsNumber(value) } function IsOptionalBoolean(value: unknown): value is boolean | undefined { return ValueGuard.IsUndefined(value) || ValueGuard.IsBoolean(value) } function IsOptionalString(value: unknown): value is string | undefined { return ValueGuard.IsUndefined(value) || ValueGuard.IsString(value) } function IsOptionalPattern(value: unknown): value is string | undefined { return ValueGuard.IsUndefined(value) || (ValueGuard.IsString(value) && IsControlCharacterFree(value) && IsPattern(value)) } function IsOptionalFormat(value: unknown): value is string | undefined { return ValueGuard.IsUndefined(value) || (ValueGuard.IsString(value) && IsControlCharacterFree(value)) } function IsOptionalSchema(value: unknown): value is boolean | undefined { return ValueGuard.IsUndefined(value) || IsSchema(value) } // ------------------------------------------------------------------ // Modifiers // ------------------------------------------------------------------ /** Returns true if this value has a Readonly symbol */ export function IsReadonly(value: T): value is TReadonly { return ValueGuard.IsObject(value) && value[ReadonlyKind] === 'Readonly' } /** Returns true if this value has a Optional symbol */ export function IsOptional(value: T): value is TOptional { return ValueGuard.IsObject(value) && value[OptionalKind] === 'Optional' } // ------------------------------------------------------------------ // Types // ------------------------------------------------------------------ /** Returns true if the given value is TAny */ export function IsAny(value: unknown): value is TAny { // prettier-ignore return ( IsKindOf(value, 'Any') && IsOptionalString(value.$id) ) } /** Returns true if the given value is TArgument */ export function IsArgument(value: unknown): value is TArgument { // prettier-ignore return ( IsKindOf(value, 'Argument') && ValueGuard.IsNumber(value.index) ) } /** Returns true if the given value is TArray */ export function IsArray(value: unknown): value is TArray { return ( IsKindOf(value, 'Array') && value.type === 'array' && IsOptionalString(value.$id) && IsSchema(value.items) && IsOptionalNumber(value.minItems) && IsOptionalNumber(value.maxItems) && IsOptionalBoolean(value.uniqueItems) && IsOptionalSchema(value.contains) && IsOptionalNumber(value.minContains) && IsOptionalNumber(value.maxContains) ) } /** Returns true if the given value is TAsyncIterator */ export function IsAsyncIterator(value: unknown): value is TAsyncIterator { // prettier-ignore return ( IsKindOf(value, 'AsyncIterator') && value.type === 'AsyncIterator' && IsOptionalString(value.$id) && IsSchema(value.items) ) } /** Returns true if the given value is TBigInt */ export function IsBigInt(value: unknown): value is TBigInt { // prettier-ignore return ( IsKindOf(value, 'BigInt') && value.type === 'bigint' && IsOptionalString(value.$id) && IsOptionalBigInt(value.exclusiveMaximum) && IsOptionalBigInt(value.exclusiveMinimum) && IsOptionalBigInt(value.maximum) && IsOptionalBigInt(value.minimum) && IsOptionalBigInt(value.multipleOf) ) } /** Returns true if the given value is TBoolean */ export function IsBoolean(value: unknown): value is TBoolean { // prettier-ignore return ( IsKindOf(value, 'Boolean') && value.type === 'boolean' && IsOptionalString(value.$id) ) } /** Returns true if the given value is TComputed */ export function IsComputed(value: unknown): value is TComputed { // prettier-ignore return ( IsKindOf(value, 'Computed') && ValueGuard.IsString(value.target) && ValueGuard.IsArray(value.parameters) && value.parameters.every((schema) => IsSchema(schema)) ) } /** Returns true if the given value is TConstructor */ export function IsConstructor(value: unknown): value is TConstructor { // prettier-ignore return ( IsKindOf(value, 'Constructor') && value.type === 'Constructor' && IsOptionalString(value.$id) && ValueGuard.IsArray(value.parameters) && value.parameters.every(schema => IsSchema(schema)) && IsSchema(value.returns) ) } /** Returns true if the given value is TDate */ export function IsDate(value: unknown): value is TDate { return ( IsKindOf(value, 'Date') && value.type === 'Date' && IsOptionalString(value.$id) && IsOptionalNumber(value.exclusiveMaximumTimestamp) && IsOptionalNumber(value.exclusiveMinimumTimestamp) && IsOptionalNumber(value.maximumTimestamp) && IsOptionalNumber(value.minimumTimestamp) && IsOptionalNumber(value.multipleOfTimestamp) ) } /** Returns true if the given value is TFunction */ export function IsFunction(value: unknown): value is TFunction { // prettier-ignore return ( IsKindOf(value, 'Function') && value.type === 'Function' && IsOptionalString(value.$id) && ValueGuard.IsArray(value.parameters) && value.parameters.every(schema => IsSchema(schema)) && IsSchema(value.returns) ) } /** Returns true if the given value is TImport */ export function IsImport(value: unknown): value is TImport { // prettier-ignore return ( IsKindOf(value, 'Import') && ValueGuard.HasPropertyKey(value, '$defs') && ValueGuard.IsObject(value.$defs) && IsProperties(value.$defs) && ValueGuard.HasPropertyKey(value, '$ref') && ValueGuard.IsString(value.$ref) && value.$ref in value.$defs // required ) } /** Returns true if the given value is TInteger */ export function IsInteger(value: unknown): value is TInteger { return ( IsKindOf(value, 'Integer') && value.type === 'integer' && IsOptionalString(value.$id) && IsOptionalNumber(value.exclusiveMaximum) && IsOptionalNumber(value.exclusiveMinimum) && IsOptionalNumber(value.maximum) && IsOptionalNumber(value.minimum) && IsOptionalNumber(value.multipleOf) ) } /** Returns true if the given schema is TProperties */ export function IsProperties(value: unknown): value is TProperties { // prettier-ignore return ( ValueGuard.IsObject(value) && Object.entries(value).every(([key, schema]) => IsControlCharacterFree(key) && IsSchema(schema)) ) } /** Returns true if the given value is TIntersect */ export function IsIntersect(value: unknown): value is TIntersect { // prettier-ignore return ( IsKindOf(value, 'Intersect') && (ValueGuard.IsString(value.type) && value.type !== 'object' ? false : true) && ValueGuard.IsArray(value.allOf) && value.allOf.every(schema => IsSchema(schema) && !IsTransform(schema)) && IsOptionalString(value.type) && (IsOptionalBoolean(value.unevaluatedProperties) || IsOptionalSchema(value.unevaluatedProperties)) && IsOptionalString(value.$id) ) } /** Returns true if the given value is TIterator */ export function IsIterator(value: unknown): value is TIterator { // prettier-ignore return ( IsKindOf(value, 'Iterator') && value.type === 'Iterator' && IsOptionalString(value.$id) && IsSchema(value.items) ) } /** Returns true if the given value is a TKind with the given name. */ export function IsKindOf(value: unknown, kind: T): value is Record & { [Kind]: T } { return ValueGuard.IsObject(value) && Kind in value && value[Kind] === kind } /** Returns true if the given value is TLiteral */ export function IsLiteralString(value: unknown): value is TLiteral { return IsLiteral(value) && ValueGuard.IsString(value.const) } /** Returns true if the given value is TLiteral */ export function IsLiteralNumber(value: unknown): value is TLiteral { return IsLiteral(value) && ValueGuard.IsNumber(value.const) } /** Returns true if the given value is TLiteral */ export function IsLiteralBoolean(value: unknown): value is TLiteral { return IsLiteral(value) && ValueGuard.IsBoolean(value.const) } /** Returns true if the given value is TLiteral */ export function IsLiteral(value: unknown): value is TLiteral { // prettier-ignore return ( IsKindOf(value, 'Literal') && IsOptionalString(value.$id) && IsLiteralValue(value.const) ) } /** Returns true if the given value is a TLiteralValue */ export function IsLiteralValue(value: unknown): value is TLiteralValue { return ValueGuard.IsBoolean(value) || ValueGuard.IsNumber(value) || ValueGuard.IsString(value) } /** Returns true if the given value is a TMappedKey */ export function IsMappedKey(value: unknown): value is TMappedKey { // prettier-ignore return ( IsKindOf(value, 'MappedKey') && ValueGuard.IsArray(value.keys) && value.keys.every(key => ValueGuard.IsNumber(key) || ValueGuard.IsString(key)) ) } /** Returns true if the given value is TMappedResult */ export function IsMappedResult(value: unknown): value is TMappedResult { // prettier-ignore return ( IsKindOf(value, 'MappedResult') && IsProperties(value.properties) ) } /** Returns true if the given value is TNever */ export function IsNever(value: unknown): value is TNever { // prettier-ignore return ( IsKindOf(value, 'Never') && ValueGuard.IsObject(value.not) && Object.getOwnPropertyNames(value.not).length === 0 ) } /** Returns true if the given value is TNot */ export function IsNot(value: unknown): value is TNot { // prettier-ignore return ( IsKindOf(value, 'Not') && IsSchema(value.not) ) } /** Returns true if the given value is TNull */ export function IsNull(value: unknown): value is TNull { // prettier-ignore return ( IsKindOf(value, 'Null') && value.type === 'null' && IsOptionalString(value.$id) ) } /** Returns true if the given value is TNumber */ export function IsNumber(value: unknown): value is TNumber { return ( IsKindOf(value, 'Number') && value.type === 'number' && IsOptionalString(value.$id) && IsOptionalNumber(value.exclusiveMaximum) && IsOptionalNumber(value.exclusiveMinimum) && IsOptionalNumber(value.maximum) && IsOptionalNumber(value.minimum) && IsOptionalNumber(value.multipleOf) ) } /** Returns true if the given value is TObject */ export function IsObject(value: unknown): value is TObject { // prettier-ignore return ( IsKindOf(value, 'Object') && value.type === 'object' && IsOptionalString(value.$id) && IsProperties(value.properties) && IsAdditionalProperties(value.additionalProperties) && IsOptionalNumber(value.minProperties) && IsOptionalNumber(value.maxProperties) ) } /** Returns true if the given value is TPromise */ export function IsPromise(value: unknown): value is TPromise { // prettier-ignore return ( IsKindOf(value, 'Promise') && value.type === 'Promise' && IsOptionalString(value.$id) && IsSchema(value.item) ) } /** Returns true if the given value is TRecord */ export function IsRecord(value: unknown): value is TRecord { // prettier-ignore return ( IsKindOf(value, 'Record') && value.type === 'object' && IsOptionalString(value.$id) && IsAdditionalProperties(value.additionalProperties) && ValueGuard.IsObject(value.patternProperties) && ((schema: Record) => { const keys = Object.getOwnPropertyNames(schema.patternProperties) return ( keys.length === 1 && IsPattern(keys[0]) && ValueGuard.IsObject(schema.patternProperties) && IsSchema(schema.patternProperties[keys[0]]) ) })(value) ) } /** Returns true if this value is TRecursive */ export function IsRecursive(value: unknown): value is { [Hint]: 'Recursive' } { return ValueGuard.IsObject(value) && Hint in value && value[Hint] === 'Recursive' } /** Returns true if the given value is TRef */ export function IsRef(value: unknown): value is TRef { // prettier-ignore return ( IsKindOf(value, 'Ref') && IsOptionalString(value.$id) && ValueGuard.IsString(value.$ref) ) } /** Returns true if the given value is TRegExp */ export function IsRegExp(value: unknown): value is TRegExp { // prettier-ignore return ( IsKindOf(value, 'RegExp') && IsOptionalString(value.$id) && ValueGuard.IsString(value.source) && ValueGuard.IsString(value.flags) && IsOptionalNumber(value.maxLength) && IsOptionalNumber(value.minLength) ) } /** Returns true if the given value is TString */ export function IsString(value: unknown): value is TString { // prettier-ignore return ( IsKindOf(value, 'String') && value.type === 'string' && IsOptionalString(value.$id) && IsOptionalNumber(value.minLength) && IsOptionalNumber(value.maxLength) && IsOptionalPattern(value.pattern) && IsOptionalFormat(value.format) ) } /** Returns true if the given value is TSymbol */ export function IsSymbol(value: unknown): value is TSymbol { // prettier-ignore return ( IsKindOf(value, 'Symbol') && value.type === 'symbol' && IsOptionalString(value.$id) ) } /** Returns true if the given value is TTemplateLiteral */ export function IsTemplateLiteral(value: unknown): value is TTemplateLiteral { // prettier-ignore return ( IsKindOf(value, 'TemplateLiteral') && value.type === 'string' && ValueGuard.IsString(value.pattern) && value.pattern[0] === '^' && value.pattern[value.pattern.length - 1] === '$' ) } /** Returns true if the given value is TThis */ export function IsThis(value: unknown): value is TThis { // prettier-ignore return ( IsKindOf(value, 'This') && IsOptionalString(value.$id) && ValueGuard.IsString(value.$ref) ) } /** Returns true of this value is TTransform */ export function IsTransform(value: unknown): value is { [TransformKind]: TransformOptions } { return ValueGuard.IsObject(value) && TransformKind in value } /** Returns true if the given value is TTuple */ export function IsTuple(value: unknown): value is TTuple { // prettier-ignore return ( IsKindOf(value, 'Tuple') && value.type === 'array' && IsOptionalString(value.$id) && ValueGuard.IsNumber(value.minItems) && ValueGuard.IsNumber(value.maxItems) && value.minItems === value.maxItems && (( // empty ValueGuard.IsUndefined(value.items) && ValueGuard.IsUndefined(value.additionalItems) && value.minItems === 0 ) || ( ValueGuard.IsArray(value.items) && value.items.every(schema => IsSchema(schema)) )) ) } /** Returns true if the given value is TUndefined */ export function IsUndefined(value: unknown): value is TUndefined { // prettier-ignore return ( IsKindOf(value, 'Undefined') && value.type === 'undefined' && IsOptionalString(value.$id) ) } /** Returns true if the given value is TUnion[]> */ export function IsUnionLiteral(value: unknown): value is TUnion { return IsUnion(value) && value.anyOf.every((schema) => IsLiteralString(schema) || IsLiteralNumber(schema)) } /** Returns true if the given value is TUnion */ export function IsUnion(value: unknown): value is TUnion { // prettier-ignore return ( IsKindOf(value, 'Union') && IsOptionalString(value.$id) && ValueGuard.IsObject(value) && ValueGuard.IsArray(value.anyOf) && value.anyOf.every(schema => IsSchema(schema)) ) } /** Returns true if the given value is TUint8Array */ export function IsUint8Array(value: unknown): value is TUint8Array { // prettier-ignore return ( IsKindOf(value, 'Uint8Array') && value.type === 'Uint8Array' && IsOptionalString(value.$id) && IsOptionalNumber(value.minByteLength) && IsOptionalNumber(value.maxByteLength) ) } /** Returns true if the given value is TUnknown */ export function IsUnknown(value: unknown): value is TUnknown { // prettier-ignore return ( IsKindOf(value, 'Unknown') && IsOptionalString(value.$id) ) } /** Returns true if the given value is a raw TUnsafe */ export function IsUnsafe(value: unknown): value is TUnsafe { return IsKindOf(value, 'Unsafe') } /** Returns true if the given value is TVoid */ export function IsVoid(value: unknown): value is TVoid { // prettier-ignore return ( IsKindOf(value, 'Void') && value.type === 'void' && IsOptionalString(value.$id) ) } /** Returns true if the given value is TKind */ export function IsKind(value: unknown): value is Record & { [Kind]: string } { return ValueGuard.IsObject(value) && Kind in value && ValueGuard.IsString(value[Kind]) && !KnownTypes.includes(value[Kind] as string) } /** Returns true if the given value is TSchema */ export function IsSchema(value: unknown): value is TSchema { // prettier-ignore return ( ValueGuard.IsObject(value) ) && ( IsAny(value) || IsArgument(value) || IsArray(value) || IsBoolean(value) || IsBigInt(value) || IsAsyncIterator(value) || IsComputed(value) || IsConstructor(value) || IsDate(value) || IsFunction(value) || IsInteger(value) || IsIntersect(value) || IsIterator(value) || IsLiteral(value) || IsMappedKey(value) || IsMappedResult(value) || IsNever(value) || IsNot(value) || IsNull(value) || IsNumber(value) || IsObject(value) || IsPromise(value) || IsRecord(value) || IsRef(value) || IsRegExp(value) || IsString(value) || IsSymbol(value) || IsTemplateLiteral(value) || IsThis(value) || IsTuple(value) || IsUndefined(value) || IsUnion(value) || IsUint8Array(value) || IsUnknown(value) || IsUnsafe(value) || IsVoid(value) || IsKind(value) ) } sinclairzx81-typebox-e0ec98c/src/type/guard/value.ts000066400000000000000000000103021505437577000226120ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ // -------------------------------------------------------------------------- // PropertyKey // -------------------------------------------------------------------------- /** Returns true if this value has this property key */ export function HasPropertyKey(value: Record, key: K): value is Record & { [_ in K]: unknown } { return key in value } // -------------------------------------------------------------------------- // Object Instances // -------------------------------------------------------------------------- /** Returns true if this value is an async iterator */ export function IsAsyncIterator(value: unknown): value is AsyncIterableIterator { return IsObject(value) && !IsArray(value) && !IsUint8Array(value) && Symbol.asyncIterator in value } /** Returns true if this value is an array */ export function IsArray(value: unknown): value is unknown[] { return Array.isArray(value) } /** Returns true if this value is bigint */ export function IsBigInt(value: unknown): value is bigint { return typeof value === 'bigint' } /** Returns true if this value is a boolean */ export function IsBoolean(value: unknown): value is boolean { return typeof value === 'boolean' } /** Returns true if this value is a Date object */ export function IsDate(value: unknown): value is Date { return value instanceof globalThis.Date } /** Returns true if this value is a function */ export function IsFunction(value: unknown): value is Function { return typeof value === 'function' } /** Returns true if this value is an iterator */ export function IsIterator(value: unknown): value is IterableIterator { return IsObject(value) && !IsArray(value) && !IsUint8Array(value) && Symbol.iterator in value } /** Returns true if this value is null */ export function IsNull(value: unknown): value is null { return value === null } /** Returns true if this value is number */ export function IsNumber(value: unknown): value is number { return typeof value === 'number' } /** Returns true if this value is an object */ export function IsObject(value: unknown): value is Record { return typeof value === 'object' && value !== null } /** Returns true if this value is RegExp */ export function IsRegExp(value: unknown): value is RegExp { return value instanceof globalThis.RegExp } /** Returns true if this value is string */ export function IsString(value: unknown): value is string { return typeof value === 'string' } /** Returns true if this value is symbol */ export function IsSymbol(value: unknown): value is symbol { return typeof value === 'symbol' } /** Returns true if this value is a Uint8Array */ export function IsUint8Array(value: unknown): value is Uint8Array { return value instanceof globalThis.Uint8Array } /** Returns true if this value is undefined */ export function IsUndefined(value: unknown): value is undefined { return value === undefined } sinclairzx81-typebox-e0ec98c/src/type/helpers/000077500000000000000000000000001505437577000214725ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/helpers/helpers.ts000066400000000000000000000076251505437577000235160ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema } from '../schema/index' import type { TProperties } from '../object/index' import type { TNever } from '../never/index' // ------------------------------------------------------------------ // Helper: Common // ------------------------------------------------------------------ export type TupleToIntersect = T extends [infer I] ? I : T extends [infer I, ...infer R] ? I & TupleToIntersect : never export type TupleToUnion = { [K in keyof T]: T[K] }[number] export type UnionToIntersect = (U extends unknown ? (arg: U) => 0 : never) extends (arg: infer I) => 0 ? I : never export type UnionLast = UnionToIntersect 0 : never> extends (x: infer L) => 0 ? L : never export type UnionToTuple> = [U] extends [never] ? Acc : UnionToTuple, [Extract, ...Acc]> export type Trim = T extends `${' '}${infer U}` ? Trim : T extends `${infer U}${' '}` ? Trim : T export type Assert = T extends E ? T : never export type Evaluate = T extends infer O ? { [K in keyof O]: O[K] } : never export type Ensure = T extends infer U ? U : never export type EmptyString = '' export type ZeroString = '0' // ------------------------------------------------------------------ // Helper: Increment // ------------------------------------------------------------------ type IncrementBase = { m: '9'; t: '01'; '0': '1'; '1': '2'; '2': '3'; '3': '4'; '4': '5'; '5': '6'; '6': '7'; '7': '8'; '8': '9'; '9': '0' } type IncrementTake = IncrementBase[T] type IncrementStep = T extends IncrementBase['m'] ? IncrementBase['t'] : T extends `${infer L extends keyof IncrementBase}${infer R}` ? L extends IncrementBase['m'] ? `${IncrementTake}${IncrementStep}` : `${IncrementTake}${R}` : never type IncrementReverse = T extends `${infer L}${infer R}` ? `${IncrementReverse}${L}` : T export type TIncrement = IncrementReverse>> /** Increments the given string value + 1 */ export function Increment(T: T): TIncrement { return (parseInt(T) + 1).toString() as never } // ------------------------------------------------------------------ // Helper: Type Asserts // ------------------------------------------------------------------ export type AssertProperties = T extends TProperties ? T : TProperties export type AssertRest = T extends E ? T : [] export type AssertType = T extends E ? T : TNever sinclairzx81-typebox-e0ec98c/src/type/helpers/index.ts000066400000000000000000000024651505437577000231600ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './helpers' sinclairzx81-typebox-e0ec98c/src/type/index.ts000066400000000000000000000070131505437577000215100ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './any/index' export * from './argument/index' export * from './array/index' export * from './async-iterator/index' export * from './awaited/index' export * from './bigint/index' export * from './boolean/index' export * from './clone/index' export * from './composite/index' export * from './const/index' export * from './constructor/index' export * from './constructor-parameters/index' export * from './date/index' export * from './discard/index' export * from './enum/index' export * from './error/index' export * from './exclude/index' export * from './extends/index' export * from './extract/index' export * from './function/index' export * from './guard/index' export * from './helpers/index' export * from './indexed/index' export * from './instance-type/index' export * from './instantiate/index' export * from './integer/index' export * from './intersect/index' export * from './intrinsic/index' export * from './iterator/index' export * from './keyof/index' export * from './literal/index' export * from './mapped/index' export * from './module/index' export * from './never/index' export * from './not/index' export * from './null/index' export * from './number/index' export * from './object/index' export * from './omit/index' export * from './optional/index' export * from './parameters/index' export * from './partial/index' export * from './patterns/index' export * from './pick/index' export * from './promise/index' export * from './readonly/index' export * from './readonly-optional/index' export * from './record/index' export * from './recursive/index' export * from './ref/index' export * from './regexp/index' export * from './registry/index' export * from './required/index' export * from './rest/index' export * from './return-type/index' export * from './schema/index' export * from './sets/index' export * from './static/index' export * from './string/index' export * from './symbol/index' export * from './symbols/index' export * from './template-literal/index' export * from './transform/index' export * from './tuple/index' export * from './type/index' export * from './uint8array/index' export * from './undefined/index' export * from './union/index' export * from './unknown/index' export * from './unsafe/index' export * from './void/index' sinclairzx81-typebox-e0ec98c/src/type/indexed/000077500000000000000000000000001505437577000214505ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/indexed/index.ts000066400000000000000000000026641505437577000231370ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './indexed-from-mapped-key' export * from './indexed-from-mapped-result' export * from './indexed-property-keys' export * from './indexed' sinclairzx81-typebox-e0ec98c/src/type/indexed/indexed-from-mapped-key.ts000066400000000000000000000106021505437577000264320ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import type { Ensure, Evaluate } from '../helpers/index' import type { TProperties } from '../object/index' import { Index, type TIndex } from './indexed' import { MappedResult, type TMappedResult, type TMappedKey } from '../mapped/index' import { Clone } from '../clone/value' // ------------------------------------------------------------------ // MappedIndexPropertyKey // ------------------------------------------------------------------ // prettier-ignore type TMappedIndexPropertyKey = { [_ in Key]: TIndex } // prettier-ignore function MappedIndexPropertyKey(type: Type, key: Key, options?: SchemaOptions): TMappedIndexPropertyKey { return { [key]: Index(type, [key], Clone(options)) } as never } // ------------------------------------------------------------------ // MappedIndexPropertyKeys // ------------------------------------------------------------------ // prettier-ignore type TMappedIndexPropertyKeys = ( PropertyKeys extends [infer Left extends PropertyKey, ...infer Right extends PropertyKey[]] ? TMappedIndexPropertyKeys> : Result ) // prettier-ignore function MappedIndexPropertyKeys< Type extends TSchema, PropertyKeys extends PropertyKey[] >(type: Type, propertyKeys: [...PropertyKeys], options?: SchemaOptions): TMappedIndexPropertyKeys { return propertyKeys.reduce((result, left) => { return { ...result, ...MappedIndexPropertyKey(type, left, options) } }, {} as TProperties) as never } // ------------------------------------------------------------------ // MappedIndexProperties // ------------------------------------------------------------------ // prettier-ignore type TMappedIndexProperties = Evaluate< TMappedIndexPropertyKeys > // prettier-ignore function MappedIndexProperties(type: Type, mappedKey: MappedKey, options?: SchemaOptions): TMappedIndexProperties { return MappedIndexPropertyKeys(type, mappedKey.keys, options) as never } // ------------------------------------------------------------------ // TIndexFromMappedKey // ------------------------------------------------------------------ // prettier-ignore export type TIndexFromMappedKey > = ( Ensure> ) // prettier-ignore export function IndexFromMappedKey >(type: Type, mappedKey: MappedKey, options?: SchemaOptions): TMappedResult { const properties = MappedIndexProperties(type, mappedKey, options) return MappedResult(properties) as never } sinclairzx81-typebox-e0ec98c/src/type/indexed/indexed-from-mapped-result.ts000066400000000000000000000072541505437577000271710ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import type { TProperties } from '../object/index' import { MappedResult, type TMappedResult } from '../mapped/index' import { IndexPropertyKeys, type TIndexPropertyKeys } from './indexed-property-keys' import { Index, type TIndex } from './index' // ------------------------------------------------------------------ // FromProperties // ------------------------------------------------------------------ // prettier-ignore type TFromProperties = ( { [K2 in keyof Properties]: TIndex> } ) // prettier-ignore function FromProperties(type: Type, properties: Properties, options?: SchemaOptions): TFromProperties { const result = {} as Record for(const K2 of Object.getOwnPropertyNames(properties)) { result[K2] = Index(type, IndexPropertyKeys(properties[K2]), options) } return result as never } // ------------------------------------------------------------------ // FromMappedResult // ------------------------------------------------------------------ // prettier-ignore type TFromMappedResult = ( TFromProperties ) // prettier-ignore function FromMappedResult(type: Type, mappedResult: MappedResult, options?: SchemaOptions): TFromMappedResult { return FromProperties(type, mappedResult.properties, options) as never } // ------------------------------------------------------------------ // TIndexFromMappedResult // ------------------------------------------------------------------ // prettier-ignore export type TIndexFromMappedResult > = ( TMappedResult ) // prettier-ignore export function IndexFromMappedResult >(type: Type, mappedResult: MappedResult, options?: SchemaOptions): TMappedResult { const properties = FromMappedResult(type, mappedResult, options) return MappedResult(properties) as never } sinclairzx81-typebox-e0ec98c/src/type/indexed/indexed-property-keys.ts000066400000000000000000000112161505437577000262740ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { TemplateLiteralGenerate, type TTemplateLiteralGenerate, type TTemplateLiteral } from '../template-literal/index' import type { TLiteral, TLiteralValue } from '../literal/index' import type { TInteger } from '../integer/index' import type { TNumber } from '../number/index' import type { TSchema } from '../schema/index' import type { TUnion } from '../union/index' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsTemplateLiteral, IsUnion, IsLiteral, IsNumber, IsInteger } from '../guard/kind' // ------------------------------------------------------------------ // FromTemplateLiteral // ------------------------------------------------------------------ // prettier-ignore type TFromTemplateLiteral> = (Keys) // prettier-ignore function FromTemplateLiteral(templateLiteral: TemplateLiteral): TFromTemplateLiteral { const keys = TemplateLiteralGenerate(templateLiteral) as string[] return keys.map(key => key.toString()) as never } // ------------------------------------------------------------------ // FromUnion // ------------------------------------------------------------------ // prettier-ignore type TFromUnion = ( Types extends [infer Left extends TSchema, ...infer Right extends TSchema[]] ? TFromUnion]> : Result ) // prettier-ignore function FromUnion(types: Types): TFromUnion { const result = [] as string[] for(const type of types) result.push(...IndexPropertyKeys(type)) return result as never } // ------------------------------------------------------------------ // FromLiteral // ------------------------------------------------------------------ // prettier-ignore type TFromLiteral = ( LiteralValue extends PropertyKey ? [`${LiteralValue}`] : [] ) // prettier-ignore function FromLiteral(literalValue: LiteralValue): TFromLiteral { return ( [(literalValue as string).toString()] // TS 5.4 observes TLiteralValue as not having a toString() ) as never } // ------------------------------------------------------------------ // IndexPropertyKeys // ------------------------------------------------------------------ // prettier-ignore export type TIndexPropertyKeys = ( Type extends TTemplateLiteral ? TFromTemplateLiteral : Type extends TUnion ? TFromUnion : Type extends TLiteral ? TFromLiteral : Type extends TNumber ? ['[number]'] : Type extends TInteger ? ['[number]'] : [] ) /** Returns a tuple of PropertyKeys derived from the given TSchema */ // prettier-ignore export function IndexPropertyKeys(type: Type): TIndexPropertyKeys { return [...new Set(( IsTemplateLiteral(type) ? FromTemplateLiteral(type) : IsUnion(type) ? FromUnion(type.anyOf) : IsLiteral(type) ? FromLiteral(type.const) : IsNumber(type) ? ['[number]'] : IsInteger(type) ? ['[number]'] : [] ))] as never } sinclairzx81-typebox-e0ec98c/src/type/indexed/indexed.ts000066400000000000000000000341141505437577000234430ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import { TypeBoxError } from '../error/index' import { type TSchema, SchemaOptions } from '../schema/index' import { type Assert } from '../helpers/index' import { type TComputed, Computed } from '../computed/index' import { type TNever, Never } from '../never/index' import { type TArray } from '../array/index' import { type TIntersect } from '../intersect/index' import { type TMappedResult, type TMappedKey } from '../mapped/index' import { type TObject, type TProperties } from '../object/index' import { type TUnion } from '../union/index' import { type TRecursive } from '../recursive/index' import { type TRef } from '../ref/index' import { type TTuple } from '../tuple/index' import { IntersectEvaluated, type TIntersectEvaluated } from '../intersect/index' import { UnionEvaluated, type TUnionEvaluated } from '../union/index' import { IndexPropertyKeys, type TIndexPropertyKeys } from './indexed-property-keys' import { IndexFromMappedKey, type TIndexFromMappedKey } from './indexed-from-mapped-key' import { IndexFromMappedResult, type TIndexFromMappedResult } from './indexed-from-mapped-result' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsArray, IsIntersect, IsObject, IsMappedKey, IsMappedResult, IsNever, IsSchema, IsTuple, IsUnion, IsRef } from '../guard/kind' // ------------------------------------------------------------------ // FromRest // ------------------------------------------------------------------ // prettier-ignore type TFromRest = ( Types extends [infer Left extends TSchema, ...infer Right extends TSchema[]] ? TFromRest, TSchema>]> : Result ) // prettier-ignore function FromRest(types: [...Types], key: Key): TFromRest { return types.map(type => IndexFromPropertyKey(type, key)) as never } // ------------------------------------------------------------------ // FromIntersectRest // ------------------------------------------------------------------ // prettier-ignore type TFromIntersectRest = ( Types extends [infer Left extends TSchema, ...infer Right extends TSchema[]] ? Left extends TNever ? TFromIntersectRest : TFromIntersectRest : Result ) // prettier-ignore function FromIntersectRest(types: [...Types]): TFromIntersectRest { return types.filter(type => !IsNever(type)) as never } // prettier-ignore type TFromIntersect = ( TIntersectEvaluated>> ) // prettier-ignore function FromIntersect(types: [...Types], key: Key): TFromIntersect { return ( IntersectEvaluated(FromIntersectRest(FromRest(types as TSchema[], key))) ) as never } // ------------------------------------------------------------------ // FromUnionRest // // The following accept a tuple of indexed key results. When evaluating // these results, we check if any result evaluated to TNever. For key // indexed unions, a TNever result indicates that the key was not // present on the variant. In these cases, we must evaluate the indexed // union to TNever (as given by a [] result). This logic aligns to the // following behaviour. // // Non-Overlapping Union // // type A = { a: string } // type B = { b: string } // type C = (A | B) & { a: number } // C is { a: number } // // Overlapping Union // // type A = { a: string } // type B = { a: string } // type C = (A | B) & { a: number } // C is { a: never } // // ------------------------------------------------------------------ // prettier-ignore type TFromUnionRest = Types extends [infer Left extends TSchema, ...infer Right extends TSchema[]] ? Left extends TNever ? [] : TFromUnionRest : Result // prettier-ignore function FromUnionRest(types: [...Types]): TFromUnionRest { return ( types.some(L => IsNever(L)) ? [] : types ) as never } // ------------------------------------------------------------------ // FromUnion // ------------------------------------------------------------------ // prettier-ignore type TFromUnion = ( TUnionEvaluated>> ) // prettier-ignore function FromUnion(types: [...Types], key: Key): TFromUnion { return ( UnionEvaluated(FromUnionRest(FromRest(types as TSchema[], key))) ) as never } // ------------------------------------------------------------------ // FromTuple // ------------------------------------------------------------------ // prettier-ignore type TFromTuple = ( Key extends keyof Types ? Types[Key] : Key extends '[number]' ? TUnionEvaluated : TNever ) // prettier-ignore function FromTuple(types: [...Types], key: Key): TFromTuple { return ( key in types ? types[key as number] : key === '[number]' ? UnionEvaluated(types) : Never() ) as never } // ------------------------------------------------------------------ // FromArray // ------------------------------------------------------------------ // prettier-ignore type TFromArray = ( Key extends '[number]' ? Type : TNever ) // prettier-ignore function FromArray(type: Type, key: Key): TFromArray { return ( key === '[number]' ? type : Never() ) as never } // ------------------------------------------------------------------ // FromProperty // ------------------------------------------------------------------ type AssertPropertyKey = Assert // prettier-ignore type TFromProperty = ( // evaluate for string keys Key extends keyof Properties ? Properties[Key] // evaluate for numeric keys : `${AssertPropertyKey}` extends `${AssertPropertyKey}` ? Properties[AssertPropertyKey] : TNever ) // prettier-ignore function FromProperty(properties: Properties, propertyKey: Key): TFromProperty { return (propertyKey in properties ? properties[propertyKey as string] : Never()) as never } // ------------------------------------------------------------------ // FromKey // ------------------------------------------------------------------ // prettier-ignore export type TIndexFromPropertyKey = ( Type extends TRecursive ? TIndexFromPropertyKey : Type extends TIntersect ? TFromIntersect : Type extends TUnion ? TFromUnion : Type extends TTuple ? TFromTuple : Type extends TArray ? TFromArray : Type extends TObject ? TFromProperty : TNever ) // prettier-ignore export function IndexFromPropertyKey(type: Type, propertyKey: Key): TIndexFromPropertyKey { return ( IsIntersect(type) ? FromIntersect(type.allOf, propertyKey) : IsUnion(type) ? FromUnion(type.anyOf, propertyKey) : IsTuple(type) ? FromTuple(type.items ?? [], propertyKey) : IsArray(type) ? FromArray(type.items, propertyKey) : IsObject(type) ? FromProperty(type.properties, propertyKey) : Never() ) as never } // ------------------------------------------------------------------ // FromKeys // ------------------------------------------------------------------ // prettier-ignore export type TIndexFromPropertyKeys = ( PropertyKeys extends [infer Left extends PropertyKey, ...infer Right extends PropertyKey[]] ? TIndexFromPropertyKeys, TSchema>]> : Result ) // prettier-ignore export function IndexFromPropertyKeys(type: Type, propertyKeys: [...PropertyKeys]): TIndexFromPropertyKeys { return propertyKeys.map(propertyKey => IndexFromPropertyKey(type, propertyKey)) as never } // ------------------------------------------------------------------ // FromSchema // ------------------------------------------------------------------ // prettier-ignore type FromSchema = ( TUnionEvaluated> ) // prettier-ignore function FromSchema(type: Type, propertyKeys: [...PropertyKeys]): FromSchema { return ( UnionEvaluated(IndexFromPropertyKeys(type, propertyKeys as PropertyKey[])) ) as never } // ------------------------------------------------------------------ // FromSchema // ------------------------------------------------------------------ // prettier-ignore export type TIndexFromComputed = ( TComputed<'Index', [Type, Key]> ) // prettier-ignore export function IndexFromComputed(type: Type, key: Key): TIndexFromComputed { return Computed('Index', [type, key]) } // ------------------------------------------------------------------ // TIndex // ------------------------------------------------------------------ // prettier-ignore export type TIndex = ( FromSchema ) /** `[Json]` Returns an Indexed property type for the given keys */ export function Index(type: Type, key: Key, options?: SchemaOptions): TIndexFromComputed /** `[Json]` Returns an Indexed property type for the given keys */ export function Index(type: Type, key: Key, options?: SchemaOptions): TIndexFromComputed /** `[Json]` Returns an Indexed property type for the given keys */ export function Index(type: Type, key: Key, options?: SchemaOptions): TIndexFromComputed /** `[Json]` Returns an Indexed property type for the given keys */ export function Index(type: Type, mappedResult: MappedResult, options?: SchemaOptions): TIndexFromMappedResult /** `[Json]` Returns an Indexed property type for the given keys */ export function Index(type: Type, mappedResult: MappedResult, options?: SchemaOptions): TIndexFromMappedResult /** `[Json]` Returns an Indexed property type for the given keys */ export function Index(type: Type, mappedKey: MappedKey, options?: SchemaOptions): TIndexFromMappedKey /** `[Json]` Returns an Indexed property type for the given keys */ export function Index>(T: Type, K: Key, options?: SchemaOptions): TIndex /** `[Json]` Returns an Indexed property type for the given keys */ export function Index(type: Type, propertyKeys: readonly [...PropertyKeys], options?: SchemaOptions): TIndex /** `[Json]` Returns an Indexed property type for the given keys */ export function Index(type: TSchema, key: any, options?: SchemaOptions): any { // computed-type if (IsRef(type) || IsRef(key)) { const error = `Index types using Ref parameters require both Type and Key to be of TSchema` if (!IsSchema(type) || !IsSchema(key)) throw new TypeBoxError(error) return Computed('Index', [type, key]) } // mapped-types if (IsMappedResult(key)) return IndexFromMappedResult(type, key, options) if (IsMappedKey(key)) return IndexFromMappedKey(type, key, options) // prettier-ignore return CreateType( IsSchema(key) ? FromSchema(type, IndexPropertyKeys(key)) : FromSchema(type, key as string[]) , options) as never } sinclairzx81-typebox-e0ec98c/src/type/instance-type/000077500000000000000000000000001505437577000226135ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/instance-type/index.ts000066400000000000000000000024731505437577000243000ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './instance-type' sinclairzx81-typebox-e0ec98c/src/type/instance-type/instance-type.ts000066400000000000000000000040711505437577000257500ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import { type TSchema, SchemaOptions } from '../schema/index' import { type TConstructor } from '../constructor/index' import { type TNever, Never } from '../never/index' import * as KindGuard from '../guard/kind' // prettier-ignore export type TInstanceType ? InstanceType : TNever > = Result /** `[JavaScript]` Extracts the InstanceType from the given Constructor type */ export function InstanceType(schema: Type, options?: SchemaOptions): TInstanceType { return (KindGuard.IsConstructor(schema) ? CreateType(schema.returns, options) : Never(options)) as never } sinclairzx81-typebox-e0ec98c/src/type/instantiate/000077500000000000000000000000001505437577000223535ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/instantiate/index.ts000066400000000000000000000024711505437577000240360ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './instantiate' sinclairzx81-typebox-e0ec98c/src/type/instantiate/instantiate.ts000066400000000000000000000335611505437577000252560ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CloneType } from '../clone/type' import { type TSchema } from '../schema/index' import { type TArgument } from '../argument/index' import { type TUnknown, Unknown } from '../unknown/index' import { type TReadonlyOptional, ReadonlyOptional } from '../readonly-optional/index' import { type TReadonly, Readonly } from '../readonly/index' import { type TOptional, Optional } from '../optional/index' import { type TConstructor } from '../constructor/index' import { type TFunction } from '../function/index' import { type TIntersect } from '../intersect/index' import { type TUnion } from '../union/index' import { type TTuple } from '../tuple/index' import { type TArray } from '../array/index' import { type TAsyncIterator } from '../async-iterator/index' import { type TIterator } from '../iterator/index' import { type TPromise } from '../promise/index' import { type TObject, type TProperties, Object } from '../object/index' import { type TRecordOrObject, type TRecord, Record, RecordKey, RecordValue } from '../record/index' import * as ValueGuard from '../guard/value' import * as KindGuard from '../guard/kind' // ------------------------------------------------------------------ // Constructor // ------------------------------------------------------------------ // prettier-ignore type TFromConstructor, TFromType> > = Result // prettier-ignore function FromConstructor(args: TSchema[], type: TConstructor): TConstructor { type.parameters = FromTypes(args, type.parameters) type.returns = FromType(args, type.returns) return type } // ------------------------------------------------------------------ // Function // ------------------------------------------------------------------ // prettier-ignore type TFromFunction, TFromType> > = Result // prettier-ignore function FromFunction(args: TSchema[], type: TFunction): TFunction { type.parameters = FromTypes(args, type.parameters) type.returns = FromType(args, type.returns) return type } // ------------------------------------------------------------------ // Intersect // ------------------------------------------------------------------ // prettier-ignore type TFromIntersect> > = Result // prettier-ignore function FromIntersect(args: TSchema[], type: TIntersect): TIntersect { type.allOf = FromTypes(args, type.allOf) return type } // ------------------------------------------------------------------ // Union // ------------------------------------------------------------------ // prettier-ignore type TFromUnion> > = Result // prettier-ignore function FromUnion(args: TSchema[], type: TUnion): TUnion { type.anyOf = FromTypes(args, type.anyOf) return type } // ------------------------------------------------------------------ // Tuple // ------------------------------------------------------------------ // prettier-ignore type TFromTuple> > = Result // prettier-ignore function FromTuple(args: TSchema[], type: TTuple): TTuple { if(ValueGuard.IsUndefined(type.items)) return type type.items = FromTypes(args, type.items!) return type } // ------------------------------------------------------------------ // Array // ------------------------------------------------------------------ // prettier-ignore type TFromArray> > = Result // prettier-ignore function FromArray(args: TSchema[], type: TArray): TArray { type.items = FromType(args, type.items) return type } // ------------------------------------------------------------------ // AsyncIterator // ------------------------------------------------------------------ // prettier-ignore type TFromAsyncIterator> > = Result // prettier-ignore function FromAsyncIterator(args: TSchema[], type: TAsyncIterator): TAsyncIterator { type.items = FromType(args, type.items) return type } // ------------------------------------------------------------------ // Iterator // ------------------------------------------------------------------ // prettier-ignore type TFromIterator> > = Result // prettier-ignore function FromIterator(args: TSchema[], type: TIterator): TIterator { type.items = FromType(args, type.items) return type } // ------------------------------------------------------------------ // Promise // ------------------------------------------------------------------ // prettier-ignore type TFromPromise> > = Result // prettier-ignore function FromPromise(args: TSchema[], type: TPromise): TPromise { type.item = FromType(args, type.item) return type } // ------------------------------------------------------------------ // Object // ------------------------------------------------------------------ // prettier-ignore type TFromObject, Result extends TObject = TObject > = Result // prettier-ignore function FromObject(args: TSchema[], type: TObject): TObject { const mappedProperties = FromProperties(args, type.properties) return { ...type, ...Object(mappedProperties) } // retain options } // ------------------------------------------------------------------ // Object // ------------------------------------------------------------------ // prettier-ignore type TFromRecord, MappedValue extends TSchema = TFromType, Result extends TSchema = TRecordOrObject > = Result // prettier-ignore function FromRecord(args: TSchema[], type: TRecord): TRecord { const mappedKey = FromType(args, RecordKey(type)) const mappedValue = FromType(args, RecordValue(type)) const result = Record(mappedKey, mappedValue) return { ...type, ... result } as never // retain options } // ------------------------------------------------------------------ // Argument // ------------------------------------------------------------------ // prettier-ignore type TFromArgument = Result // prettier-ignore function FromArgument(args: TSchema[], argument: TArgument): TSchema { return argument.index in args ? args[argument.index] : Unknown() } // ------------------------------------------------------------------ // Property // ------------------------------------------------------------------ // prettier-ignore type TFromProperty ? true : false, IsOptional extends boolean = Type extends TOptional ? true : false, Mapped extends TSchema = TFromType, Result extends TSchema = ( [IsReadonly, IsOptional] extends [true, true] ? TReadonlyOptional : [IsReadonly, IsOptional] extends [true, false] ? TReadonly : [IsReadonly, IsOptional] extends [false, true] ? TOptional : Mapped ) > = Result // prettier-ignore function FromProperty(args: [...Args], type: Type): TFromProperty { const isReadonly = KindGuard.IsReadonly(type) const isOptional = KindGuard.IsOptional(type) const mapped = FromType(args, type) return ( isReadonly && isOptional ? ReadonlyOptional(mapped) : isReadonly && !isOptional ? Readonly(mapped) : !isReadonly && isOptional ? Optional(mapped) : mapped ) as never } // ------------------------------------------------------------------ // Properties // ------------------------------------------------------------------ // prettier-ignore type TFromProperties } > = Result // prettier-ignore function FromProperties(args: TSchema[], properties: TProperties): TFromProperties { return globalThis.Object.getOwnPropertyNames(properties).reduce((result, key) => { return { ...result, [key]: FromProperty(args, properties[key]) } }, {}) as never } // ------------------------------------------------------------------ // Types // ------------------------------------------------------------------ // prettier-ignore export type TFromTypes = ( Types extends [infer Left extends TSchema, ...infer Right extends TSchema[]] ? TFromTypes]> : Result ) // prettier-ignore export function FromTypes(args: [...Args], types: [...Types]): TFromTypes { return types.map(type => FromType(args, type)) as never } // ------------------------------------------------------------------ // Type // ------------------------------------------------------------------ // prettier-ignore export type TFromType = ( Type extends TConstructor ? TFromConstructor : Type extends TFunction ? TFromFunction : Type extends TIntersect ? TFromIntersect : Type extends TUnion ? TFromUnion : Type extends TTuple ? TFromTuple : Type extends TArray ? TFromArray: Type extends TAsyncIterator ? TFromAsyncIterator : Type extends TIterator ? TFromIterator : Type extends TPromise ? TFromPromise : Type extends TObject ? TFromObject : Type extends TRecord ? TFromRecord : Type extends TArgument ? TFromArgument : Type ) // prettier-ignore function FromType(args: [...Args], type: TSchema): TFromType { return ( KindGuard.IsConstructor(type) ? FromConstructor(args, type) : KindGuard.IsFunction(type) ? FromFunction(args, type) : KindGuard.IsIntersect(type) ? FromIntersect(args, type) : KindGuard.IsUnion(type) ? FromUnion(args, type) : KindGuard.IsTuple(type) ? FromTuple(args, type) : KindGuard.IsArray(type) ? FromArray(args, type) : KindGuard.IsAsyncIterator(type) ? FromAsyncIterator(args, type) : KindGuard.IsIterator(type) ? FromIterator(args, type) : KindGuard.IsPromise(type) ? FromPromise(args, type) : KindGuard.IsObject(type) ? FromObject(args, type): KindGuard.IsRecord(type) ? FromRecord(args, type) : KindGuard.IsArgument(type) ? FromArgument(args, type) : type ) as never } // ------------------------------------------------------------------ // Instantiate // ------------------------------------------------------------------ /** `[JavaScript]` Instantiates a type with the given parameters */ // prettier-ignore export type TInstantiate > = Result /** `[JavaScript]` Instantiates a type with the given parameters */ // prettier-ignore export function Instantiate(type: Type, args: [...Args]): TInstantiate { return FromType(args, CloneType(type)) } sinclairzx81-typebox-e0ec98c/src/type/integer/000077500000000000000000000000001505437577000214655ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/integer/index.ts000066400000000000000000000024651505437577000231530ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './integer' sinclairzx81-typebox-e0ec98c/src/type/integer/integer.ts000066400000000000000000000036071505437577000235000ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import { Kind } from '../symbols/index' export interface IntegerOptions extends SchemaOptions { exclusiveMaximum?: number exclusiveMinimum?: number maximum?: number minimum?: number multipleOf?: number } export interface TInteger extends TSchema, IntegerOptions { [Kind]: 'Integer' static: number type: 'integer' } /** `[Json]` Creates an Integer type */ export function Integer(options?: IntegerOptions): TInteger { return CreateType({ [Kind]: 'Integer', type: 'integer' }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/intersect/000077500000000000000000000000001505437577000220305ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/intersect/index.ts000066400000000000000000000025761505437577000235210ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './intersect-evaluated' export * from './intersect-type' export * from './intersect' sinclairzx81-typebox-e0ec98c/src/type/intersect/intersect-create.ts000066400000000000000000000047361505437577000256530ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema } from '../schema/index' import { Kind } from '../symbols/index' import type { TIntersect, IntersectOptions } from './intersect-type' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsObject, IsSchema } from '../guard/kind' // ------------------------------------------------------------------ // IntersectCreate // ------------------------------------------------------------------ // prettier-ignore export function IntersectCreate(T: [...T], options: IntersectOptions = {}): TIntersect { const allObjects = T.every((schema) => IsObject(schema)) const clonedUnevaluatedProperties = IsSchema(options.unevaluatedProperties) ? { unevaluatedProperties: options.unevaluatedProperties } : {} return CreateType( (options.unevaluatedProperties === false || IsSchema(options.unevaluatedProperties) || allObjects ? { ...clonedUnevaluatedProperties, [Kind]: 'Intersect', type: 'object', allOf: T } : { ...clonedUnevaluatedProperties, [Kind]: 'Intersect', allOf: T }) , options) as never } sinclairzx81-typebox-e0ec98c/src/type/intersect/intersect-evaluated.ts000066400000000000000000000127321505437577000263550ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { SchemaOptions, TSchema } from '../schema/index' import { OptionalKind } from '../symbols/index' import { CreateType } from '../create/type' import { Discard } from '../discard/index' import { Never, type TNever } from '../never/index' import { Optional, type TOptional } from '../optional/index' import type { TReadonly } from '../readonly/index' import { TIntersect, IntersectOptions } from './intersect-type' import { IntersectCreate } from './intersect-create' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsOptional, IsTransform } from '../guard/kind' // ------------------------------------------------------------------ // IsIntersectOptional // ------------------------------------------------------------------ // prettier-ignore type TIsIntersectOptional = ( Types extends [infer Left extends TSchema, ...infer Right extends TSchema[]] ? Left extends TOptional ? TIsIntersectOptional : false : true ) // prettier-ignore function IsIntersectOptional(types: [...Types]): TIsIntersectOptional { return types.every(left => IsOptional(left)) as never } // ------------------------------------------------------------------ // RemoveOptionalFromType // ------------------------------------------------------------------ // prettier-ignore type TRemoveOptionalFromType = ( Type extends TReadonly ? TReadonly> : Type extends TOptional ? TRemoveOptionalFromType : Type ) // prettier-ignore function RemoveOptionalFromType(type: Type): TRemoveOptionalFromType { return ( Discard(type, [OptionalKind]) ) as never } // ------------------------------------------------------------------ // RemoveOptionalFromRest // ------------------------------------------------------------------ // prettier-ignore type TRemoveOptionalFromRest = ( Types extends [infer Left extends TSchema, ...infer Right extends TSchema[]] ? Left extends TOptional ? TRemoveOptionalFromRest]> : TRemoveOptionalFromRest : Result ) // prettier-ignore function RemoveOptionalFromRest(types: [...Types]): TRemoveOptionalFromRest { return types.map(left => IsOptional(left) ? RemoveOptionalFromType(left) : left) as never } // ------------------------------------------------------------------ // ResolveIntersect // ------------------------------------------------------------------ // prettier-ignore type TResolveIntersect = ( TIsIntersectOptional extends true ? TOptional>> : TIntersect> ) // prettier-ignore function ResolveIntersect(types: [...Types], options: SchemaOptions): TResolveIntersect { return ( IsIntersectOptional(types) ? Optional(IntersectCreate(RemoveOptionalFromRest(types) as TSchema[], options)) : IntersectCreate(RemoveOptionalFromRest(types) as TSchema[], options) ) as never } // ------------------------------------------------------------------ // IntersectEvaluated // ------------------------------------------------------------------ // prettier-ignore export type TIntersectEvaluated = ( Types extends [TSchema] ? Types[0] : Types extends [] ? TNever : TResolveIntersect ) /** `[Json]` Creates an evaluated Intersect type */ export function IntersectEvaluated>(types: [...Types], options: IntersectOptions = {}): Result { if (types.length === 1) return CreateType(types[0], options) as never if (types.length === 0) return Never(options) as never if (types.some((schema) => IsTransform(schema))) throw new Error('Cannot intersect transform types') return ResolveIntersect(types, options) as never } sinclairzx81-typebox-e0ec98c/src/type/intersect/intersect-type.ts000066400000000000000000000046171505437577000253670ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import type { Static } from '../static/index' import { Kind } from '../symbols/index' // ------------------------------------------------------------------ // IntersectStatic // ------------------------------------------------------------------ // prettier-ignore type TIntersectStatic = T extends [infer L extends TSchema, ...infer R extends TSchema[]] ? TIntersectStatic> : Acc // ------------------------------------------------------------------ // TIntersect // ------------------------------------------------------------------ // prettier-ignore export type TUnevaluatedProperties = undefined | TSchema | boolean // prettier-ignore export interface IntersectOptions extends SchemaOptions { unevaluatedProperties?: TUnevaluatedProperties } // prettier-ignore export interface TIntersect extends TSchema, IntersectOptions { [Kind]: 'Intersect' static: TIntersectStatic type?: 'object' allOf: [...T] } sinclairzx81-typebox-e0ec98c/src/type/intersect/intersect.ts000066400000000000000000000047451505437577000244120ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema } from '../schema/index' import { Never, type TNever } from '../never/index' import { TIntersect, IntersectOptions } from './intersect-type' import { IntersectCreate } from './intersect-create' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsTransform } from '../guard/kind' // ------------------------------------------------------------------ // Intersect // ------------------------------------------------------------------ // prettier-ignore export type Intersect = ( Types extends [TSchema] ? Types[0] : Types extends [] ? TNever : TIntersect ) /** `[Json]` Creates an evaluated Intersect type */ export function Intersect(types: [...Types], options?: IntersectOptions): Intersect { if (types.length === 1) return CreateType(types[0], options) as never if (types.length === 0) return Never(options) as never if (types.some((schema) => IsTransform(schema))) throw new Error('Cannot intersect transform types') return IntersectCreate(types, options) as never } sinclairzx81-typebox-e0ec98c/src/type/intrinsic/000077500000000000000000000000001505437577000220325ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/intrinsic/capitalize.ts000066400000000000000000000033061505437577000245310ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import { Intrinsic, type TIntrinsic } from './intrinsic' // prettier-ignore export type TCapitalize = TIntrinsic /** `[Json]` Intrinsic function to Capitalize LiteralString types */ export function Capitalize(T: T, options: SchemaOptions = {}): TCapitalize { return Intrinsic(T, 'Capitalize', options) } sinclairzx81-typebox-e0ec98c/src/type/intrinsic/index.ts000066400000000000000000000027271505437577000235210ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './capitalize' export * from './intrinsic-from-mapped-key' export * from './intrinsic' export * from './lowercase' export * from './uncapitalize' export * from './uppercase' sinclairzx81-typebox-e0ec98c/src/type/intrinsic/intrinsic-from-mapped-key.ts000066400000000000000000000105411505437577000274000ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { SchemaOptions } from '../schema/index' import type { TProperties } from '../object/index' import { Assert } from '../helpers/index' import { MappedResult, type TMappedResult, type TMappedKey } from '../mapped/index' import { Intrinsic, type TIntrinsic, type IntrinsicMode } from './intrinsic' import { Literal, type TLiteral, type TLiteralValue } from '../literal/index' import { Clone } from '../clone/value' // ------------------------------------------------------------------ // MappedIntrinsicPropertyKey // ------------------------------------------------------------------ // prettier-ignore type TMappedIntrinsicPropertyKey< K extends PropertyKey, M extends IntrinsicMode, > = { [_ in K]: TIntrinsic>, M> } // prettier-ignore function MappedIntrinsicPropertyKey< K extends PropertyKey, M extends IntrinsicMode, >(K: K, M: M, options: SchemaOptions): TMappedIntrinsicPropertyKey { return { [K]: Intrinsic(Literal(K as TLiteralValue), M, Clone(options)) } as never } // ------------------------------------------------------------------ // MappedIntrinsicPropertyKeys // ------------------------------------------------------------------ // prettier-ignore type TMappedIntrinsicPropertyKeys< K extends PropertyKey[], M extends IntrinsicMode, Acc extends TProperties = {} > = ( K extends [infer L extends PropertyKey, ...infer R extends PropertyKey[]] ? TMappedIntrinsicPropertyKeys> : Acc ) // prettier-ignore function MappedIntrinsicPropertyKeys< K extends PropertyKey[], M extends IntrinsicMode >(K: [...K], M: M, options: SchemaOptions): TMappedIntrinsicPropertyKeys { const result = K.reduce((Acc, L) => { return { ...Acc, ...MappedIntrinsicPropertyKey(L, M, options) } }, {} as TProperties) as never return result } // ------------------------------------------------------------------ // MappedIntrinsicProperties // ------------------------------------------------------------------ // prettier-ignore type TMappedIntrinsicProperties< K extends TMappedKey, M extends IntrinsicMode, > = ( TMappedIntrinsicPropertyKeys ) // prettier-ignore function MappedIntrinsicProperties< K extends TMappedKey, M extends IntrinsicMode, >(T: K, M: M, options: SchemaOptions): TMappedIntrinsicProperties { return MappedIntrinsicPropertyKeys(T['keys'], M, options) as never } // ------------------------------------------------------------------ // IntrinsicFromMappedKey // ------------------------------------------------------------------ // prettier-ignore export type TIntrinsicFromMappedKey< K extends TMappedKey, M extends IntrinsicMode, P extends TProperties = TMappedIntrinsicProperties > = ( TMappedResult

) // prettier-ignore export function IntrinsicFromMappedKey< K extends TMappedKey, M extends IntrinsicMode, P extends TProperties = TMappedIntrinsicProperties >(T: K, M: M, options: SchemaOptions): TMappedResult

{ const P = MappedIntrinsicProperties(T, M, options) return MappedResult(P) as never } sinclairzx81-typebox-e0ec98c/src/type/intrinsic/intrinsic.ts000066400000000000000000000163231505437577000244110ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import { TemplateLiteral, TemplateLiteralParseExact, IsTemplateLiteralExpressionFinite, TemplateLiteralExpressionGenerate, type TTemplateLiteral, type TTemplateLiteralKind } from '../template-literal/index' import { IntrinsicFromMappedKey, type TIntrinsicFromMappedKey } from './intrinsic-from-mapped-key' import { Literal, type TLiteral, type TLiteralValue } from '../literal/index' import { Union, type TUnion } from '../union/index' import { type TMappedKey } from '../mapped/index' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsMappedKey, IsTemplateLiteral, IsUnion, IsLiteral } from '../guard/kind' // ------------------------------------------------------------------ // Apply // ------------------------------------------------------------------ function ApplyUncapitalize(value: string): string { const [first, rest] = [value.slice(0, 1), value.slice(1)] return [first.toLowerCase(), rest].join('') } function ApplyCapitalize(value: string): string { const [first, rest] = [value.slice(0, 1), value.slice(1)] return [first.toUpperCase(), rest].join('') } function ApplyUppercase(value: string): string { return value.toUpperCase() } function ApplyLowercase(value: string): string { return value.toLowerCase() } // ------------------------------------------------------------------ // IntrinsicMode // ------------------------------------------------------------------ export type IntrinsicMode = 'Uppercase' | 'Lowercase' | 'Capitalize' | 'Uncapitalize' // ------------------------------------------------------------------ // FromTemplateLiteral // ------------------------------------------------------------------ // prettier-ignore type TFromTemplateLiteral = M extends IntrinsicMode ? T extends [infer L extends TTemplateLiteralKind, ...infer R extends TTemplateLiteralKind[]] ? [TIntrinsic, ...TFromTemplateLiteral] : T : T function FromTemplateLiteral(schema: TTemplateLiteral, mode: IntrinsicMode, options: SchemaOptions): TFromTemplateLiteral { // note: template literals require special runtime handling as they are encoded in string patterns. // This diverges from the mapped type which would otherwise map on the template literal kind. const expression = TemplateLiteralParseExact(schema.pattern) const finite = IsTemplateLiteralExpressionFinite(expression) if (!finite) return { ...schema, pattern: FromLiteralValue(schema.pattern, mode) } as any const strings = [...TemplateLiteralExpressionGenerate(expression)] const literals = strings.map((value) => Literal(value)) const mapped = FromRest(literals as any, mode) const union = Union(mapped) return TemplateLiteral([union], options) as never } // ------------------------------------------------------------------ // FromLiteralValue // ------------------------------------------------------------------ // prettier-ignore type TFromLiteralValue = ( T extends string ? M extends 'Uncapitalize' ? Uncapitalize : M extends 'Capitalize' ? Capitalize : M extends 'Uppercase' ? Uppercase : M extends 'Lowercase' ? Lowercase : string : T ) // prettier-ignore function FromLiteralValue(value: TLiteralValue, mode: IntrinsicMode) { return ( typeof value === 'string' ? ( mode === 'Uncapitalize' ? ApplyUncapitalize(value) : mode === 'Capitalize' ? ApplyCapitalize(value) : mode === 'Uppercase' ? ApplyUppercase(value) : mode === 'Lowercase' ? ApplyLowercase(value) : value ) : value.toString() ) } // ------------------------------------------------------------------ // FromRest // ------------------------------------------------------------------ // prettier-ignore type TFromRest = T extends [infer L extends TSchema, ...infer R extends TSchema[]] ? TFromRest]> : Acc // prettier-ignore function FromRest(T: [...T], M: M): TFromRest { return T.map(L => Intrinsic(L, M)) as never } // ------------------------------------------------------------------ // TIntrinsic // ------------------------------------------------------------------ // prettier-ignore export type TIntrinsic = // Intrinsic-Mapped-Inference T extends TMappedKey ? TIntrinsicFromMappedKey : // Standard-Inference T extends TTemplateLiteral ? TTemplateLiteral> : T extends TUnion ? TUnion> : T extends TLiteral ? TLiteral> : T /** Applies an intrinsic string manipulation to the given type. */ export function Intrinsic(schema: T, mode: M, options?: SchemaOptions): TIntrinsicFromMappedKey /** Applies an intrinsic string manipulation to the given type. */ export function Intrinsic(schema: T, mode: M, options?: SchemaOptions): TIntrinsic /** Applies an intrinsic string manipulation to the given type. */ export function Intrinsic(schema: TSchema, mode: IntrinsicMode, options: SchemaOptions = {}): never { // prettier-ignore return ( // Intrinsic-Mapped-Inference IsMappedKey(schema) ? IntrinsicFromMappedKey(schema, mode, options) : // Standard-Inference IsTemplateLiteral(schema) ? FromTemplateLiteral(schema, mode, options) : IsUnion(schema) ? Union(FromRest(schema.anyOf, mode), options) : IsLiteral(schema) ? Literal(FromLiteralValue(schema.const, mode), options) : // Default Type CreateType(schema, options) ) as never } sinclairzx81-typebox-e0ec98c/src/type/intrinsic/lowercase.ts000066400000000000000000000033001505437577000243620ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import { Intrinsic, type TIntrinsic } from './intrinsic' // prettier-ignore export type TLowercase = TIntrinsic /** `[Json]` Intrinsic function to Lowercase LiteralString types */ export function Lowercase(T: T, options: SchemaOptions = {}): TLowercase { return Intrinsic(T, 'Lowercase', options) } sinclairzx81-typebox-e0ec98c/src/type/intrinsic/uncapitalize.ts000066400000000000000000000033221505437577000250720ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import { Intrinsic, type TIntrinsic } from './intrinsic' // prettier-ignore export type TUncapitalize = TIntrinsic /** `[Json]` Intrinsic function to Uncapitalize LiteralString types */ export function Uncapitalize(T: T, options: SchemaOptions = {}): TUncapitalize { return Intrinsic(T, 'Uncapitalize', options) } sinclairzx81-typebox-e0ec98c/src/type/intrinsic/uppercase.ts000066400000000000000000000033001505437577000243650ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import { Intrinsic, type TIntrinsic } from './intrinsic' // prettier-ignore export type TUppercase = TIntrinsic /** `[Json]` Intrinsic function to Uppercase LiteralString types */ export function Uppercase(T: T, options: SchemaOptions = {}): TUppercase { return Intrinsic(T, 'Uppercase', options) } sinclairzx81-typebox-e0ec98c/src/type/iterator/000077500000000000000000000000001505437577000216615ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/iterator/index.ts000066400000000000000000000024661505437577000233500ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './iterator' sinclairzx81-typebox-e0ec98c/src/type/iterator/iterator.ts000066400000000000000000000035701505437577000240670ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import type { Static } from '../static/index' import { Kind } from '../symbols/index' export interface TIterator extends TSchema { [Kind]: 'Iterator' static: IterableIterator> type: 'Iterator' items: T } /** `[JavaScript]` Creates an Iterator type */ export function Iterator(items: T, options?: SchemaOptions): TIterator { return CreateType({ [Kind]: 'Iterator', type: 'Iterator', items }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/keyof/000077500000000000000000000000001505437577000211455ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/keyof/index.ts000066400000000000000000000026551505437577000226340ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './keyof-from-mapped-result' export * from './keyof-property-entries' export * from './keyof-property-keys' export * from './keyof' sinclairzx81-typebox-e0ec98c/src/type/keyof/keyof-from-mapped-result.ts000066400000000000000000000067061505437577000263640ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { SchemaOptions } from '../schema/index' import type { Ensure, Evaluate } from '../helpers/index' import type { TProperties } from '../object/index' import { MappedResult, type TMappedResult } from '../mapped/index' import { KeyOf, type TKeyOfFromType } from './keyof' import { Clone } from '../clone/value' // ------------------------------------------------------------------ // FromProperties // ------------------------------------------------------------------ // prettier-ignore type TFromProperties = ( { [K2 in keyof Properties]: TKeyOfFromType } ) // prettier-ignore function FromProperties(properties: Properties, options?: SchemaOptions): TFromProperties { const result = {} as TProperties for(const K2 of globalThis.Object.getOwnPropertyNames(properties)) result[K2] = KeyOf(properties[K2], Clone(options)) return result as never } // ------------------------------------------------------------------ // FromMappedResult // ------------------------------------------------------------------ // prettier-ignore type TFromMappedResult = ( Evaluate> ) // prettier-ignore function FromMappedResult(mappedResult: MappedResult, options?: SchemaOptions): TFromMappedResult { return FromProperties(mappedResult.properties, options) as never } // ------------------------------------------------------------------ // KeyOfFromMappedResult // ------------------------------------------------------------------ // prettier-ignore export type TKeyOfFromMappedResult< MappedResult extends TMappedResult, Properties extends TProperties = TFromMappedResult > = ( Ensure> ) // prettier-ignore export function KeyOfFromMappedResult< MappedResult extends TMappedResult, Properties extends TProperties = TFromMappedResult >(mappedResult: MappedResult, options?: SchemaOptions): TMappedResult { const properties = FromMappedResult(mappedResult, options) return MappedResult(properties) as never } sinclairzx81-typebox-e0ec98c/src/type/keyof/keyof-property-entries.ts000066400000000000000000000036711505437577000261720ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { IndexFromPropertyKeys } from '../indexed/indexed' import { KeyOfPropertyKeys } from './keyof-property-keys' import { TSchema } from '../schema/index' /** * `[Utility]` Resolves an array of keys and schemas from the given schema. This method is faster * than obtaining the keys and resolving each individually via indexing. This method was written * accellerate Intersect and Union encoding. */ export function KeyOfPropertyEntries(schema: TSchema): [key: string, schema: TSchema][] { const keys = KeyOfPropertyKeys(schema) as string[] const schemas = IndexFromPropertyKeys(schema, keys) return keys.map((_, index) => [keys[index], schemas[index]]) } sinclairzx81-typebox-e0ec98c/src/type/keyof/keyof-property-keys.ts000066400000000000000000000170431505437577000254720ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema } from '../schema/index' import { type ZeroString, type UnionToTuple, type TIncrement } from '../helpers/index' import type { TRecursive } from '../recursive/index' import type { TIntersect } from '../intersect/index' import type { TUnion } from '../union/index' import type { TTuple } from '../tuple/index' import type { TArray } from '../array/index' import type { TObject, TProperties } from '../object/index' import { SetUnionMany, SetIntersectMany, type TSetUnionMany, type TSetIntersectMany } from '../sets/index' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsIntersect, IsUnion, IsTuple, IsArray, IsObject, IsRecord } from '../guard/kind' // ------------------------------------------------------------------ // FromRest // ------------------------------------------------------------------ // prettier-ignore type TFromRest = ( Types extends [infer L extends TSchema, ...infer R extends TSchema[]] ? TFromRest]> : Result ) // prettier-ignore function FromRest(types: [...Types]): TFromRest { const result = [] as PropertyKey[][] for(const L of types) result.push(KeyOfPropertyKeys(L)) return result as never } // ------------------------------------------------------------------ // FromIntersect // ------------------------------------------------------------------ // prettier-ignore type TFromIntersect, PropertyKeys extends PropertyKey[] = TSetUnionMany > = PropertyKeys // prettier-ignore function FromIntersect(types: [...Types]): TFromIntersect { const propertyKeysArray = FromRest(types) as PropertyKey[][] const propertyKeys = SetUnionMany(propertyKeysArray) return propertyKeys as never } // ------------------------------------------------------------------ // FromUnion // ------------------------------------------------------------------ // prettier-ignore type TFromUnion, PropertyKeys extends PropertyKey[] = TSetIntersectMany > = PropertyKeys // prettier-ignore function FromUnion(types: [...Types]): TFromUnion { const propertyKeysArray = FromRest(types) as PropertyKey[][] const propertyKeys = SetIntersectMany(propertyKeysArray) return propertyKeys as never } // ------------------------------------------------------------------ // FromTuple // ------------------------------------------------------------------ // prettier-ignore type TFromTuple = Types extends [infer _ extends TSchema, ...infer R extends TSchema[]] ? TFromTuple, [...Acc, Indexer]> : Acc // prettier-ignore function FromTuple(types: [...Types]): TFromTuple { return types.map((_, indexer) => indexer.toString()) as never } // ------------------------------------------------------------------ // FromArray // ------------------------------------------------------------------ // prettier-ignore type TFromArray<_ extends TSchema> = ( ['[number]'] ) // prettier-ignore function FromArray<_ extends TSchema>(_: _): TFromArray<_> { return ( ['[number]'] ) } // ------------------------------------------------------------------ // FromProperties // ------------------------------------------------------------------ // prettier-ignore type TFromProperties = ( UnionToTuple ) // prettier-ignore function FromProperties(T: Properties): TFromProperties { return ( globalThis.Object.getOwnPropertyNames(T) ) as never } // ------------------------------------------------------------------ // FromPatternProperties // ------------------------------------------------------------------ // prettier-ignore function FromPatternProperties(patternProperties: Record): string[] { if(!includePatternProperties) return [] const patternPropertyKeys = globalThis.Object.getOwnPropertyNames(patternProperties) return patternPropertyKeys.map(key => { return (key[0] === '^' && key[key.length - 1] === '$') ? key.slice(1, key.length - 1) : key }) } // ------------------------------------------------------------------ // KeyOfPropertyKeys // ------------------------------------------------------------------ // prettier-ignore export type TKeyOfPropertyKeys = ( Type extends TRecursive ? TKeyOfPropertyKeys : Type extends TIntersect ? TFromIntersect : Type extends TUnion ? TFromUnion : Type extends TTuple ? TFromTuple : Type extends TArray ? TFromArray : Type extends TObject ? TFromProperties : [] ) /** Returns a tuple of PropertyKeys derived from the given TSchema. */ // prettier-ignore export function KeyOfPropertyKeys(type: Type): TKeyOfPropertyKeys { return ( IsIntersect(type) ? FromIntersect(type.allOf) : IsUnion(type) ? FromUnion(type.anyOf) : IsTuple(type) ? FromTuple(type.items ?? []) : IsArray(type) ? FromArray(type.items) : IsObject(type) ? FromProperties(type.properties) : IsRecord(type) ? FromPatternProperties(type.patternProperties) : [] ) as never } // ---------------------------------------------------------------- // KeyOfPattern // ---------------------------------------------------------------- let includePatternProperties = false /** Returns a regular expression pattern derived from the given TSchema */ export function KeyOfPattern(schema: TSchema): string { includePatternProperties = true const keys = KeyOfPropertyKeys(schema) includePatternProperties = false const pattern = keys.map((key) => `(${key})`) return `^(${pattern.join('|')})$` } sinclairzx81-typebox-e0ec98c/src/type/keyof/keyof.ts000066400000000000000000000131131505437577000226310ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema } from '../schema/index' import type { Assert, Ensure } from '../helpers/index' import type { TMappedResult } from '../mapped/index' import type { SchemaOptions } from '../schema/index' import { Literal, type TLiteral, type TLiteralValue } from '../literal/index' import { Number, type TNumber } from '../number/index' import { Computed, TComputed } from '../computed/index' import { Ref, type TRef } from '../ref/index' import { KeyOfPropertyKeys, type TKeyOfPropertyKeys } from './keyof-property-keys' import { UnionEvaluated, type TUnionEvaluated } from '../union/index' import { KeyOfFromMappedResult, type TKeyOfFromMappedResult } from './keyof-from-mapped-result' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsMappedResult, IsRef, IsComputed } from '../guard/kind' // ------------------------------------------------------------------ // FromComputed // ------------------------------------------------------------------ // prettier-ignore type TFromComputed = Ensure< TComputed<'KeyOf', [TComputed]> > // prettier-ignore function FromComputed(target: Target, parameters: Parameters): TFromComputed { return Computed('KeyOf', [Computed(target, parameters)]) as never } // ------------------------------------------------------------------ // FromRef // ------------------------------------------------------------------ // prettier-ignore type TFromRef = Ensure< TComputed<'KeyOf', [TRef]> > // prettier-ignore function FromRef($ref: Ref): TFromRef { return Computed('KeyOf', [Ref($ref)]) as never } // ------------------------------------------------------------------ // KeyOfFromType // ------------------------------------------------------------------ // prettier-ignore /** `[Internal]` Used by KeyOfFromMappedResult */ export type TKeyOfFromType, PropertyKeyTypes extends TSchema[] = TKeyOfPropertyKeysToRest, Result = TUnionEvaluated > = Ensure // prettier-ignore function KeyOfFromType(type: Type, options?: SchemaOptions): TKeyOfFromType { const propertyKeys = KeyOfPropertyKeys(type) as PropertyKey[] const propertyKeyTypes = KeyOfPropertyKeysToRest(propertyKeys) const result = UnionEvaluated(propertyKeyTypes) return CreateType(result, options) as never } // ------------------------------------------------------------------ // FromPropertyKeys // ------------------------------------------------------------------ // prettier-ignore export type TKeyOfPropertyKeysToRest = ( PropertyKeys extends [infer L extends PropertyKey, ...infer R extends PropertyKey[]] ? L extends '[number]' ? TKeyOfPropertyKeysToRest : TKeyOfPropertyKeysToRest>]> : Result ) // prettier-ignore export function KeyOfPropertyKeysToRest(propertyKeys: [...PropertyKeys]): TKeyOfPropertyKeysToRest { return propertyKeys.map(L => L === '[number]' ? Number() : Literal(L as TLiteralValue)) as never } // ------------------------------------------------------------------ // TKeyOf // ------------------------------------------------------------------ // prettier-ignore export type TKeyOf = ( Type extends TComputed ? TFromComputed : Type extends TRef ? TFromRef : Type extends TMappedResult ? TKeyOfFromMappedResult : TKeyOfFromType ) /** `[Json]` Creates a KeyOf type */ export function KeyOf(type: Type, options?: SchemaOptions): TKeyOf { return (IsComputed(type) ? FromComputed(type.target, type.parameters) : IsRef(type) ? FromRef(type.$ref) : IsMappedResult(type) ? KeyOfFromMappedResult(type, options) : KeyOfFromType(type, options)) as never } sinclairzx81-typebox-e0ec98c/src/type/literal/000077500000000000000000000000001505437577000214645ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/literal/index.ts000066400000000000000000000024651505437577000231520ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './literal' sinclairzx81-typebox-e0ec98c/src/type/literal/literal.ts000066400000000000000000000044421505437577000234740ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import { Kind } from '../symbols/index' // ------------------------------------------------------------------ // TLiteralValue // ------------------------------------------------------------------ export type TLiteralValue = boolean | number | string // | bigint - supported but variant disable due to potential numeric type conflicts // ------------------------------------------------------------------ // TLiteral // ------------------------------------------------------------------ export interface TLiteral extends TSchema { [Kind]: 'Literal' static: T const: T } /** `[Json]` Creates a Literal type */ export function Literal(value: T, options?: SchemaOptions): TLiteral { return CreateType( { [Kind]: 'Literal', const: value, type: typeof value as 'string' | 'number' | 'boolean', }, options, ) as never } sinclairzx81-typebox-e0ec98c/src/type/mapped/000077500000000000000000000000001505437577000212765ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/mapped/index.ts000066400000000000000000000025611505437577000227610ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './mapped-key' export * from './mapped-result' export * from './mapped' sinclairzx81-typebox-e0ec98c/src/type/mapped/mapped-key.ts000066400000000000000000000033311505437577000237020ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema } from '../schema/index' import { Kind } from '../symbols/index' export interface TMappedKey extends TSchema { [Kind]: 'MappedKey' static: T[number] keys: T } // prettier-ignore export function MappedKey(T: [...T]): TMappedKey { return CreateType({ [Kind]: 'MappedKey', keys: T }) as never } sinclairzx81-typebox-e0ec98c/src/type/mapped/mapped-result.ts000066400000000000000000000034401505437577000244310ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema } from '../schema/index' import type { TProperties } from '../object/index' import { Kind } from '../symbols/index' export interface TMappedResult extends TSchema { [Kind]: 'MappedResult' properties: T static: unknown } // prettier-ignore export function MappedResult(properties: T): TMappedResult { return CreateType({ [Kind]: 'MappedResult', properties }) as never } sinclairzx81-typebox-e0ec98c/src/type/mapped/mapped.ts000066400000000000000000000322261505437577000231210ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema } from '../schema/index' import type { Ensure, Evaluate, Assert } from '../helpers/index' import { Kind, OptionalKind, ReadonlyKind } from '../symbols/index' import { CreateType } from '../create/type' import { Discard } from '../discard/index' // evaluation types import { Array, type TArray } from '../array/index' import { AsyncIterator, type TAsyncIterator } from '../async-iterator/index' import { Constructor, type TConstructor } from '../constructor/index' import { type TEnum, type TEnumRecord } from '../enum/index' import { Function as FunctionType, type TFunction } from '../function/index' import { IndexPropertyKeys, type TIndexPropertyKeys } from '../indexed/index' import { Intersect, type TIntersect } from '../intersect/index' import { Iterator, type TIterator } from '../iterator/index' import { Literal, type TLiteral, type TLiteralValue } from '../literal/index' import { Object, type TObject, type TProperties, type ObjectOptions } from '../object/index' import { Optional, type TOptional } from '../optional/index' import { Promise, type TPromise } from '../promise/index' import { Readonly, type TReadonly } from '../readonly/index' import { Tuple, type TTuple } from '../tuple/index' import { Union, type TUnion } from '../union/index' // operator import { SetIncludes, type TSetIncludes } from '../sets/index' // mapping types import { MappedResult, type TMappedResult } from './mapped-result' import type { TMappedKey } from './mapped-key' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsArray, IsAsyncIterator, IsConstructor, IsFunction, IsIntersect, IsIterator, IsReadonly, IsMappedResult, IsMappedKey, IsObject, IsOptional, IsPromise, IsSchema, IsTuple, IsUnion } from '../guard/kind' // ------------------------------------------------------------------ // FromMappedResult // // We only evaluate the context (K) if it is a keyof P. Otherwise we // remap the back to a MappedResult with the expectation it will be // evaluated by an outer context. Note that overlapping keys in the // outer context may result in incorrect evaluation of the outer // context. Reproduction code below. // // type S = { // [L in 'A' | 'B']: { // [R in 'B' | 'C']: [L, R] // issue: overlapping 'B' // } // } // // ------------------------------------------------------------------ // prettier-ignore type TFromMappedResult = ( K extends keyof P ? FromSchemaType : TMappedResult

) // prettier-ignore function FromMappedResult(K: K, P: P): TFromMappedResult { return ( K in P ? FromSchemaType(K, P[K as string]) : MappedResult(P) ) as never } // ------------------------------------------------------------------ // MappedKeyToKnownMappedResultProperties // // This path is used when K is in the PropertyKey set of P. This is // the standard (fast) path when not nesting mapped types. // ------------------------------------------------------------------ // prettier-ignore type TMappedKeyToKnownMappedResultProperties = { [_ in K]: TLiteral> } // prettier-ignore function MappedKeyToKnownMappedResultProperties(K: K): TMappedKeyToKnownMappedResultProperties { return { [K]: Literal(K as TLiteralValue) } as never } // ------------------------------------------------------------------ // MappedKeyToUnknownMappedResultProperties // // This path is used when K is outside the set of P. This indicates // that the K originates from outside the current mappped type. This // path is very slow as we need to construct a full MappedResult // to be evaluated by the exterior mapped type. // ------------------------------------------------------------------ // prettier-ignore type TMappedKeyToUnknownMappedResultProperties

= ( P extends [infer L extends PropertyKey, ...infer R extends PropertyKey[]] ? TMappedKeyToUnknownMappedResultProperties> }> : Acc ) // prettier-ignore function MappedKeyToUnknownMappedResultProperties

(P: [...P]): TMappedKeyToUnknownMappedResultProperties

{ const Acc = {} as Record for(const L of P) Acc[L] = Literal(L as TLiteralValue) return Acc as never } // ------------------------------------------------------------------ // MappedKeyToMappedResultProperties // ------------------------------------------------------------------ // prettier-ignore type TMappedKeyToMappedResultProperties = ( TSetIncludes extends true ? TMappedKeyToKnownMappedResultProperties : TMappedKeyToUnknownMappedResultProperties

) // prettier-ignore function MappedKeyToMappedResultProperties(K: K, P: [...P]): TMappedKeyToMappedResultProperties { return ( SetIncludes(P, K) ? MappedKeyToKnownMappedResultProperties(K) : MappedKeyToUnknownMappedResultProperties(P) ) as never } // prettier-ignore type TFromMappedKey< K extends PropertyKey, P extends PropertyKey[], R extends TProperties = TMappedKeyToMappedResultProperties > = ( TFromMappedResult ) // prettier-ignore function FromMappedKey(K: K, P: [...P]): TFromMappedKey { const R = MappedKeyToMappedResultProperties(K, P) return FromMappedResult(K, R) as never } // ------------------------------------------------------------------ // FromRest // ------------------------------------------------------------------ // prettier-ignore type TFromRest = ( T extends [infer L extends TSchema, ...infer R extends TSchema[]] ? TFromRest]> : Acc ) // prettier-ignore function FromRest(K: K, T: [...T]): TFromRest { return T.map(L => FromSchemaType(K, L)) as never } // ------------------------------------------------------------------ // FromProperties // ------------------------------------------------------------------ // prettier-ignore type FromProperties }>> = R // prettier-ignore function FromProperties(K: K, T: T): FromProperties { const Acc = {} as Record for(const K2 of globalThis.Object.getOwnPropertyNames(T)) Acc[K2] = FromSchemaType(K, T[K2]) return Acc as never } // ------------------------------------------------------------------ // FromMappedPropertyKey // ------------------------------------------------------------------ // prettier-ignore type FromSchemaType = ( // unevaluated modifier types T extends TReadonly ? TReadonly> : T extends TOptional ? TOptional> : // unevaluated mapped types T extends TMappedResult ? TFromMappedResult : T extends TMappedKey ? TFromMappedKey : // unevaluated types T extends TConstructor ? TConstructor, FromSchemaType> : T extends TFunction ? TFunction, FromSchemaType> : T extends TAsyncIterator ? TAsyncIterator> : T extends TIterator ? TIterator> : T extends TIntersect ? TIntersect> : // note: special case for enums as these are mapped as union types. T extends TEnum ? TEnum : T extends TUnion ? TUnion> : T extends TTuple ? TTuple> : T extends TObject ? TObject> : T extends TArray ? TArray> : T extends TPromise ? TPromise> : T ) // prettier-ignore function FromSchemaType(K: K, T: T): FromSchemaType { // required to retain user defined options for mapped type const options = { ...T } return ( // unevaluated modifier types IsOptional(T) ? Optional(FromSchemaType(K, Discard(T, [OptionalKind]) as TSchema)) : IsReadonly(T) ? Readonly(FromSchemaType(K, Discard(T, [ReadonlyKind]) as TSchema)) : // unevaluated mapped types IsMappedResult(T) ? FromMappedResult(K, T.properties) : IsMappedKey(T) ? FromMappedKey(K, T.keys) : // unevaluated types IsConstructor(T) ? Constructor(FromRest(K, T.parameters), FromSchemaType(K, T.returns), options) : IsFunction(T) ? FunctionType(FromRest(K, T.parameters), FromSchemaType(K, T.returns), options) : IsAsyncIterator(T) ? AsyncIterator(FromSchemaType(K, T.items), options) : IsIterator(T) ? Iterator(FromSchemaType(K, T.items), options) : IsIntersect(T) ? Intersect(FromRest(K, T.allOf), options) : IsUnion(T) ? Union(FromRest(K, T.anyOf), options) : IsTuple(T) ? Tuple(FromRest(K, T.items ?? []), options) : IsObject(T) ? Object(FromProperties(K, T.properties), options) : IsArray(T) ? Array(FromSchemaType(K, T.items), options) : IsPromise(T) ? Promise(FromSchemaType(K, T.item), options) : T ) as never } // ------------------------------------------------------------------ // MappedFunctionReturnType // ------------------------------------------------------------------ // prettier-ignore export type TMappedFunctionReturnType = ( K extends [infer L extends PropertyKey, ...infer R extends PropertyKey[]] ? TMappedFunctionReturnType }> : Acc ) // prettier-ignore export function MappedFunctionReturnType(K: [...K], T: T): TMappedFunctionReturnType { const Acc = {} as Record for(const L of K) Acc[L] = FromSchemaType(L, T) return Acc as never } // ------------------------------------------------------------------ // TMappedFunction // ------------------------------------------------------------------ // prettier-ignore export type TMappedFunction> = (T: I) => TSchema // ------------------------------------------------------------------ // TMapped // ------------------------------------------------------------------ // prettier-ignore export type TMapped< K extends PropertyKey[], F extends TMappedFunction, R extends TProperties = Evaluate>>, > = Ensure> /** `[Json]` Creates a Mapped object type */ export function Mapped, F extends TMappedFunction = TMappedFunction, R extends TMapped = TMapped>(key: K, map: F, options?: ObjectOptions): R /** `[Json]` Creates a Mapped object type */ export function Mapped = TMappedFunction, R extends TMapped = TMapped>(key: [...K], map: F, options?: ObjectOptions): R /** `[Json]` Creates a Mapped object type */ export function Mapped(key: any, map: Function, options?: ObjectOptions) { const K = IsSchema(key) ? IndexPropertyKeys(key) : (key as PropertyKey[]) const RT = map({ [Kind]: 'MappedKey', keys: K } as TMappedKey) const R = MappedFunctionReturnType(K, RT) return Object(R, options) } sinclairzx81-typebox-e0ec98c/src/type/module/000077500000000000000000000000001505437577000213155ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/module/compute.ts000066400000000000000000000576251505437577000233600ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/index' import { CloneType } from '../clone/index' import { Discard } from '../discard/index' import { Ensure, Evaluate } from '../helpers/index' import { type TSchema } from '../schema/index' import { Array, type TArray } from '../array/index' import { Awaited, type TAwaited } from '../awaited/index' import { AsyncIterator, type TAsyncIterator } from '../async-iterator/index' import { TComputed } from '../computed/index' import { Constructor, type TConstructor } from '../constructor/index' import { Index, type TIndex, type TIndexPropertyKeys } from '../indexed/index' import { TEnum, type TEnumRecord } from '../enum/index' import { Function as FunctionType, type TFunction } from '../function/index' import { Intersect, type TIntersect, type TIntersectEvaluated } from '../intersect/index' import { Iterator, type TIterator } from '../iterator/index' import { KeyOf, type TKeyOf } from '../keyof/index' import { Object, type TObject, type TProperties } from '../object/index' import { Omit, type TOmit } from '../omit/index' import { type TOptional } from '../optional/index' import { Pick, type TPick } from '../pick/index' import { Never, type TNever } from '../never/index' import { Partial, TPartial } from '../partial/index' import { type TReadonly } from '../readonly/index' import { RecordValue, RecordPattern, type TRecordOrObject, type TRecord } from '../record/index' import { type TRef } from '../ref/index' import { Required, type TRequired } from '../required/index' import { type TTransform } from '../transform/index' import { Tuple, type TTuple } from '../tuple/index' import { Union, type TUnion, type TUnionEvaluated } from '../union/index' // ------------------------------------------------------------------ // Symbols // ------------------------------------------------------------------ import { TransformKind, OptionalKind, ReadonlyKind } from '../symbols/index' // ------------------------------------------------------------------ // KindGuard // ------------------------------------------------------------------ import * as KindGuard from '../guard/kind' // ------------------------------------------------------------------ // // DereferenceParameters // // Dereferences TComputed parameters. It is important to note that // dereferencing anything other than these parameters may result // inference and evaluation problems, potentially resulting in a // stack overflow. All open TRef types must be preserved !!! // // ------------------------------------------------------------------ // prettier-ignore type TDereferenceParameters = ( Types extends [infer Left extends TSchema, ...infer Right extends TSchema[]] ? Left extends TRef ? TDereferenceParameters]> : TDereferenceParameters]> : Result ) // prettier-ignore function DereferenceParameters(moduleProperties: ModuleProperties, types: [...Types]): TSchema[] { return types.map((type) => { return KindGuard.IsRef(type) ? Dereference(moduleProperties, type.$ref) : FromType(moduleProperties, type) }) as never } // prettier-ignore type TDereference ? TDereference : TFromType : TNever )> = Result // prettier-ignore function Dereference(moduleProperties: ModuleProperties, ref: Ref): TSchema { return ( ref in moduleProperties ? KindGuard.IsRef(moduleProperties[ref]) ? Dereference(moduleProperties, moduleProperties[ref].$ref) : FromType(moduleProperties, moduleProperties[ref]) : Never() ) as never } // ------------------------------------------------------------------ // // TComputed // // The following types support deferred evaluation // // ------------------------------------------------------------------ // ------------------------------------------------------------------ // Awaited // ------------------------------------------------------------------ // prettier-ignore type TFromAwaited = ( Parameters extends [infer T0 extends TSchema] ? TAwaited : never ) // prettier-ignore function FromAwaited(parameters: Parameters): TFromAwaited { return Awaited(parameters[0]) as never } // ------------------------------------------------------------------ // Index // ------------------------------------------------------------------ // prettier-ignore type TFromIndex = ( Parameters extends [infer T0 extends TSchema, infer T1 extends TSchema] // Note: This inferred result check is required to mitgate a "as never" // assertion on FromComputed resolution. This should be removed when // reimplementing TIndex to use TSchema as the primary key indexer. ? TIndex> extends infer Result extends TSchema ? Result : never : never ) // prettier-ignore function FromIndex(parameters: Parameters): TFromIndex { return Index(parameters[0], parameters[1]) as never } // ------------------------------------------------------------------ // KeyOf // ------------------------------------------------------------------ // prettier-ignore type TFromKeyOf = ( Parameters extends [infer T0 extends TSchema] ? TKeyOf : never ) // prettier-ignore function FromKeyOf(parameters: Parameters): TFromAwaited { return KeyOf(parameters[0]) as never } // ------------------------------------------------------------------ // Partial // ------------------------------------------------------------------ // prettier-ignore type TFromPartial = ( Parameters extends [infer T0 extends TSchema] ? TPartial : never ) // prettier-ignore function FromPartial(parameters: Parameters): TFromPartial { return Partial(parameters[0]) as never } // ------------------------------------------------------------------ // Omit // ------------------------------------------------------------------ // prettier-ignore type TFromOmit = ( Parameters extends [infer T0 extends TSchema, infer T1 extends TSchema] ? TOmit : never ) // prettier-ignore function FromOmit(parameters: Parameters): TFromPick { return Omit(parameters[0], parameters[1]) as never } // ------------------------------------------------------------------ // Pick // ------------------------------------------------------------------ // prettier-ignore type TFromPick = ( Parameters extends [infer T0 extends TSchema, infer T1 extends TSchema] ? TPick : never ) // prettier-ignore function FromPick(parameters: Parameters): TFromPick { return Pick(parameters[0], parameters[1]) as never } // ------------------------------------------------------------------ // Required // ------------------------------------------------------------------ // prettier-ignore type TFromRequired = ( Parameters extends [infer T0 extends TSchema] ? TRequired : never ) // prettier-ignore function FromRequired(parameters: Parameters): TFromPick { return Required(parameters[0]) as never } // ------------------------------------------------------------------ // Computed // ------------------------------------------------------------------ // prettier-ignore type TFromComputed > = ( Target extends 'Awaited' ? TFromAwaited : Target extends 'Index' ? TFromIndex : Target extends 'KeyOf' ? TFromKeyOf : Target extends 'Partial' ? TFromPartial : Target extends 'Omit' ? TFromOmit : Target extends 'Pick' ? TFromPick : Target extends 'Required' ? TFromRequired : TNever ) // prettier-ignore function FromComputed(moduleProperties: ModuleProperties, target: Target, parameters: Parameters): TFromComputed { const dereferenced = DereferenceParameters(moduleProperties, parameters) return ( target === 'Awaited' ? FromAwaited(dereferenced) : target === 'Index' ? FromIndex(dereferenced) : target === 'KeyOf' ? FromKeyOf(dereferenced) : target === 'Partial' ? FromPartial(dereferenced) : target === 'Omit' ? FromOmit(dereferenced) : target === 'Pick' ? FromPick(dereferenced) : target === 'Required' ? FromRequired(dereferenced) : Never() ) as never } // ------------------------------------------------------------------ // // Standard Types // // The following are the standard mappable types and structures // // ------------------------------------------------------------------ // ------------------------------------------------------------------ // Array // ------------------------------------------------------------------ // prettier-ignore type TFromArray = ( Ensure>> ) function FromArray(moduleProperties: ModuleProperties, type: Type): TFromArray { return Array(FromType(moduleProperties, type)) } // ------------------------------------------------------------------ // AsyncIterator // ------------------------------------------------------------------ // prettier-ignore type TFromAsyncIterator = ( TAsyncIterator> ) function FromAsyncIterator(moduleProperties: ModuleProperties, type: Type): TFromAsyncIterator { return AsyncIterator(FromType(moduleProperties, type)) } // ------------------------------------------------------------------ // Constructor // ------------------------------------------------------------------ // prettier-ignore type TFromConstructor = ( TConstructor, TFromType> ) // prettier-ignore function FromConstructor( moduleProperties: ModuleProperties, parameters: [...Parameters], instanceType: InstanceType, ): TFromConstructor { return Constructor(FromTypes(moduleProperties, parameters as never), FromType(moduleProperties, instanceType) as never) as never } // ------------------------------------------------------------------ // Function // ------------------------------------------------------------------ // prettier-ignore type TFromFunction = Ensure< Ensure, TFromType>> > // prettier-ignore function FromFunction( moduleProperties: ModuleProperties, parameters: [...Parameters], returnType: ReturnType, ): TFromFunction { return FunctionType(FromTypes(moduleProperties, parameters as never), FromType(moduleProperties, returnType) as never) as never } // ------------------------------------------------------------------ // Intersect // ------------------------------------------------------------------ // prettier-ignore type TFromIntersect = ( Ensure>> ) function FromIntersect(moduleProperties: ModuleProperties, types: [...Types]): TFromIntersect { return Intersect(FromTypes(moduleProperties, types as never)) as never } // ------------------------------------------------------------------ // Iterator // ------------------------------------------------------------------ // prettier-ignore type TFromIterator = ( TIterator> ) function FromIterator(moduleProperties: ModuleProperties, type: Type): TFromIterator { return Iterator(FromType(moduleProperties, type)) } // ------------------------------------------------------------------ // Object // ------------------------------------------------------------------ // prettier-ignore type TFromObject = Ensure }>>> function FromObject(moduleProperties: ModuleProperties, properties: Properties): TFromObject { return Object( globalThis.Object.keys(properties).reduce((result, key) => { return { ...result, [key]: FromType(moduleProperties, properties[key]) as never } }, {} as TProperties), ) as never } // ------------------------------------------------------------------ // Record // // Note: Varying Runtime and Static path here as we need to retain // constraints on the Record. This requires remapping the entire // Record in the Runtime path but where the Static path is merely // a facade for the patternProperties regular expression. // ------------------------------------------------------------------ // prettier-ignore type TFromRecord> > = Result // prettier-ignore function FromRecord(moduleProperties: ModuleProperties, type: Type): never { const [value, pattern] = [FromType(moduleProperties, RecordValue(type)), RecordPattern(type)] const result = CloneType(type) result.patternProperties[pattern] = value return result as never } // ------------------------------------------------------------------ // Transform // ------------------------------------------------------------------ // prettier-ignore type TFromTransform ? TTransform, Output> : TTransform > = Result // prettier-ignore function FromTransform(moduleProperties: ModuleProperties, transform: Transform): TSchema { return (KindGuard.IsRef(transform)) ? { ...Dereference(moduleProperties, transform.$ref), [TransformKind]: transform[TransformKind] } : transform } // ------------------------------------------------------------------ // Tuple // ------------------------------------------------------------------ // prettier-ignore type TFromTuple = ( Ensure>> ) function FromTuple(moduleProperties: ModuleProperties, types: [...Types]): TFromTuple { return Tuple(FromTypes(moduleProperties, types as never)) as never } // ------------------------------------------------------------------ // Union // ------------------------------------------------------------------ // prettier-ignore type TFromUnion = ( Ensure>> ) function FromUnion(moduleProperties: ModuleProperties, types: [...Types]): TFromUnion { return Union(FromTypes(moduleProperties, types as never)) as never } // ------------------------------------------------------------------ // Types // ------------------------------------------------------------------ // prettier-ignore type TFromTypes = ( Types extends [infer Left extends TSchema, ...infer Right extends TSchema[]] ? TFromTypes]> : Result ) function FromTypes(moduleProperties: ModuleProperties, types: [...Types]): TFromTypes { return types.map((type) => FromType(moduleProperties, type)) as never } // ------------------------------------------------------------------ // Type // ------------------------------------------------------------------ // prettier-ignore export type TFromType = ( // Modifier Type extends TOptional ? TOptional> : Type extends TReadonly ? TReadonly> : // Transform Type extends TTransform ? TFromTransform : // Types Type extends TArray ? TFromArray : Type extends TAsyncIterator ? TFromAsyncIterator : Type extends TComputed ? TFromComputed : Type extends TConstructor ? TFromConstructor : Type extends TFunction ? TFromFunction : Type extends TIntersect ? TFromIntersect : Type extends TIterator ? TFromIterator : Type extends TObject ? TFromObject : Type extends TRecord ? TFromRecord : Type extends TTuple ? TFromTuple : Type extends TEnum ? Type : // intercept enum before union Type extends TUnion ? TFromUnion : Type ) // prettier-ignore export function FromType(moduleProperties: ModuleProperties, type: Type): TFromType { return ( // Modifiers KindGuard.IsOptional(type) ? CreateType(FromType(moduleProperties, Discard(type, [OptionalKind]) as TSchema) as never, type) : KindGuard.IsReadonly(type) ? CreateType(FromType(moduleProperties, Discard(type, [ReadonlyKind]) as TSchema) as never, type) : // Transform KindGuard.IsTransform(type) ? CreateType(FromTransform(moduleProperties, type), type) : // Types KindGuard.IsArray(type) ? CreateType(FromArray(moduleProperties, type.items), type) : KindGuard.IsAsyncIterator(type) ? CreateType(FromAsyncIterator(moduleProperties, type.items), type) : KindGuard.IsComputed(type) ? CreateType(FromComputed(moduleProperties, type.target, type.parameters)) : KindGuard.IsConstructor(type) ? CreateType(FromConstructor(moduleProperties, type.parameters, type.returns), type) : KindGuard.IsFunction(type) ? CreateType(FromFunction(moduleProperties, type.parameters, type.returns), type) : KindGuard.IsIntersect(type) ? CreateType(FromIntersect(moduleProperties, type.allOf), type) : KindGuard.IsIterator(type) ? CreateType(FromIterator(moduleProperties, type.items), type) : KindGuard.IsObject(type) ? CreateType(FromObject(moduleProperties, type.properties), type) : KindGuard.IsRecord(type) ? CreateType(FromRecord(moduleProperties, type)) : KindGuard.IsTuple(type)? CreateType(FromTuple(moduleProperties, type.items || []), type) : KindGuard.IsUnion(type) ? CreateType(FromUnion(moduleProperties, type.anyOf), type) : type ) as never } // ------------------------------------------------------------------ // ComputeType // ------------------------------------------------------------------ // prettier-ignore export type TComputeType = ( Key extends keyof ModuleProperties ? TFromType : TNever ) // prettier-ignore export function ComputeType(moduleProperties: ModuleProperties, key: Key): TComputeType { return ( key in moduleProperties ? FromType(moduleProperties, moduleProperties[key as keyof ModuleProperties]) : Never() ) as never } // ------------------------------------------------------------------ // ComputeModuleProperties // ------------------------------------------------------------------ // prettier-ignore export type TComputeModuleProperties = Evaluate<{ [Key in keyof ModuleProperties]: TComputeType }> // prettier-ignore export function ComputeModuleProperties(moduleProperties: ModuleProperties): TComputeModuleProperties { return globalThis.Object.getOwnPropertyNames(moduleProperties).reduce((result, key) => { return {...result, [key]: ComputeType(moduleProperties, key) } }, {} as TProperties) as never } sinclairzx81-typebox-e0ec98c/src/type/module/index.ts000066400000000000000000000024641505437577000230020ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './module' sinclairzx81-typebox-e0ec98c/src/type/module/infer.ts000066400000000000000000000234171505437577000227770ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { Ensure, Evaluate } from '../helpers/index' import { TSchema } from '../schema/index' import { TArray } from '../array/index' import { TAsyncIterator } from '../async-iterator/index' import { TConstructor } from '../constructor/index' import { TEnum, TEnumRecord } from '../enum/index' import { TFunction } from '../function/index' import { TIntersect } from '../intersect/index' import { TIterator } from '../iterator/index' import { TObject, TProperties } from '../object/index' import { TOptional } from '../optional/index' import { TRecord } from '../record/index' import { TReadonly } from '../readonly/index' import { TRef } from '../ref/index' import { TTuple } from '../tuple/index' import { TUnion } from '../union/index' import { Static } from '../static/index' import { TRecursive } from '../recursive/index' // ------------------------------------------------------------------ // Array // ------------------------------------------------------------------ // prettier-ignore type TInferArray = ( Ensure>> ) // ------------------------------------------------------------------ // AsyncIterator // ------------------------------------------------------------------ // prettier-ignore type TInferAsyncIterator = ( Ensure>> ) // ------------------------------------------------------------------ // Constructor // ------------------------------------------------------------------ // prettier-ignore type TInferConstructor = Ensure< new (...args: TInferTuple) => TInfer > // ------------------------------------------------------------------ // Function // ------------------------------------------------------------------ // prettier-ignore type TInferFunction = Ensure< (...args: TInferTuple) => TInfer > // ------------------------------------------------------------------ // Iterator // ------------------------------------------------------------------ // prettier-ignore type TInferIterator = ( Ensure>> ) // ------------------------------------------------------------------ // Intersect // ------------------------------------------------------------------ // prettier-ignore type TInferIntersect = ( Types extends [infer Left extends TSchema, ...infer Right extends TSchema[]] ? TInferIntersect> : Result ) // ------------------------------------------------------------------ // Object // ------------------------------------------------------------------ type ReadonlyOptionalPropertyKeys = { [Key in keyof Properties]: Properties[Key] extends TReadonly ? (Properties[Key] extends TOptional ? Key : never) : never }[keyof Properties] type ReadonlyPropertyKeys = { [Key in keyof Source]: Source[Key] extends TReadonly ? (Source[Key] extends TOptional ? never : Key) : never }[keyof Source] type OptionalPropertyKeys = { [Key in keyof Source]: Source[Key] extends TOptional ? (Source[Key] extends TReadonly ? never : Key) : never }[keyof Source] type RequiredPropertyKeys = keyof Omit | ReadonlyPropertyKeys | OptionalPropertyKeys> // prettier-ignore type InferPropertiesWithModifiers> = Evaluate<( Readonly>>> & Readonly>> & Partial>> & Required>> )> // prettier-ignore type InferProperties = InferPropertiesWithModifiers }> // prettier-ignore type TInferObject = ( InferProperties ) // ------------------------------------------------------------------ // Tuple // ------------------------------------------------------------------ // prettier-ignore type TInferTuple = ( Types extends [infer L extends TSchema, ...infer R extends TSchema[]] ? TInferTuple]> : Result ) // ------------------------------------------------------------------ // Record // ------------------------------------------------------------------ // prettier-ignore type TInferRecord extends infer Key extends PropertyKey ? Key : never, InferedType extends unknown = TInfer, > = Ensure<{ [_ in InferredKey]: InferedType }> // ------------------------------------------------------------------ // Ref // ------------------------------------------------------------------ // prettier-ignore type TInferRef = ( Ref extends keyof ModuleProperties ? TInfer : unknown ) // ------------------------------------------------------------------ // Union // ------------------------------------------------------------------ // prettier-ignore type TInferUnion = ( Types extends [infer L extends TSchema, ...infer R extends TSchema[]] ? TInferUnion> : Result ) // ------------------------------------------------------------------ // Infer // ------------------------------------------------------------------ // prettier-ignore type TInfer = ( Type extends TArray ? TInferArray : Type extends TAsyncIterator ? TInferAsyncIterator : Type extends TConstructor ? TInferConstructor : Type extends TFunction ? TInferFunction : Type extends TIntersect ? TInferIntersect : Type extends TIterator ? TInferIterator : Type extends TObject ? TInferObject : Type extends TRecord ? TInferRecord : Type extends TRef ? TInferRef : Type extends TTuple ? TInferTuple : Type extends TEnum ? Static : // intercept enum before union Type extends TUnion ? TInferUnion : Type extends TRecursive ? TInfer : Static ) // ------------------------------------------------------------------ // InferFromModuleKey // ------------------------------------------------------------------ /** Inference Path for Imports. This type is used to compute TImport `static` */ // prettier-ignore export type TInferFromModuleKey = ( Key extends keyof ModuleProperties ? TInfer : never ) sinclairzx81-typebox-e0ec98c/src/type/module/module.ts000066400000000000000000000076041505437577000231610ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/index' import { Kind } from '../symbols/index' import { SchemaOptions, TSchema } from '../schema/index' import { TProperties } from '../object/index' import { Static } from '../static/index' // ------------------------------------------------------------------ // Module Infrastructure Types // ------------------------------------------------------------------ import { ComputeModuleProperties, TComputeModuleProperties } from './compute' import { TInferFromModuleKey } from './infer' // ------------------------------------------------------------------ // Definitions // ------------------------------------------------------------------ export interface TDefinitions extends TSchema { static: { [K in keyof ModuleProperties]: Static } $defs: ModuleProperties } // ------------------------------------------------------------------ // Import // ------------------------------------------------------------------ // prettier-ignore export interface TImport extends TSchema { [Kind]: 'Import' static: TInferFromModuleKey $defs: ModuleProperties $ref: Key } // ------------------------------------------------------------------ // Module // ------------------------------------------------------------------ // prettier-ignore export class TModule> { private readonly $defs: ComputedModuleProperties constructor($defs: ModuleProperties) { const computed = ComputeModuleProperties($defs) const identified = this.WithIdentifiers(computed as never) this.$defs = identified as never } /** `[Json]` Imports a Type by Key. */ public Import(key: Key, options?: SchemaOptions): TImport { const $defs = { ...this.$defs, [key]: CreateType(this.$defs[key], options) } return CreateType({ [Kind]: 'Import', $defs, $ref: key }) as never } // prettier-ignore private WithIdentifiers($defs: ComputedModuleProperties): ComputedModuleProperties { return globalThis.Object.getOwnPropertyNames($defs).reduce((result, key) => { return { ...result, [key]: { ...$defs[key], $id: key }} }, {}) as never } } /** `[Json]` Creates a Type Definition Module. */ export function Module(properties: Properties): TModule { return new TModule(properties) } sinclairzx81-typebox-e0ec98c/src/type/never/000077500000000000000000000000001505437577000211475ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/never/index.ts000066400000000000000000000024621505437577000226320ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './never' sinclairzx81-typebox-e0ec98c/src/type/never/never.ts000066400000000000000000000032521505437577000226400ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import { Kind } from '../symbols/index' export interface TNever extends TSchema { [Kind]: 'Never' static: never not: {} } /** `[Json]` Creates a Never type */ export function Never(options?: SchemaOptions): TNever { return CreateType({ [Kind]: 'Never', not: {} }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/not/000077500000000000000000000000001505437577000206305ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/not/index.ts000066400000000000000000000024611505437577000223120ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './not' sinclairzx81-typebox-e0ec98c/src/type/not/not.ts000066400000000000000000000034721505437577000220060ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import type { Static } from '../static/index' import { Kind } from '../symbols/index' export interface TNot extends TSchema { [Kind]: 'Not' static: T extends TNot ? Static : unknown not: T } /** `[Json]` Creates a Not type */ export function Not(type: Type, options?: SchemaOptions): TNot { return CreateType({ [Kind]: 'Not', not: type }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/null/000077500000000000000000000000001505437577000210025ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/null/index.ts000066400000000000000000000024621505437577000224650ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './null' sinclairzx81-typebox-e0ec98c/src/type/null/null.ts000066400000000000000000000032551505437577000223310ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import { Kind } from '../symbols/index' export interface TNull extends TSchema { [Kind]: 'Null' static: null type: 'null' } /** `[Json]` Creates a Null type */ export function Null(options?: SchemaOptions): TNull { return CreateType({ [Kind]: 'Null', type: 'null' }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/number/000077500000000000000000000000001505437577000213205ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/number/index.ts000066400000000000000000000024641505437577000230050ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './number' sinclairzx81-typebox-e0ec98c/src/type/number/number.ts000066400000000000000000000035731505437577000231700ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import { Kind } from '../symbols/index' export interface NumberOptions extends SchemaOptions { exclusiveMaximum?: number exclusiveMinimum?: number maximum?: number minimum?: number multipleOf?: number } export interface TNumber extends TSchema, NumberOptions { [Kind]: 'Number' static: number type: 'number' } /** `[Json]` Creates a Number type */ export function Number(options?: NumberOptions): TNumber { return CreateType({ [Kind]: 'Number', type: 'number' }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/object/000077500000000000000000000000001505437577000212765ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/object/index.ts000066400000000000000000000024641505437577000227630ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './object' sinclairzx81-typebox-e0ec98c/src/type/object/object.ts000066400000000000000000000114351505437577000231200ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import type { Static } from '../static/index' import type { Evaluate } from '../helpers/index' import type { TReadonly } from '../readonly/index' import type { TOptional } from '../optional/index' import { Kind } from '../symbols/index' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsOptional } from '../guard/kind' // ------------------------------------------------------------------ // ObjectStatic // ------------------------------------------------------------------ type ReadonlyOptionalPropertyKeys = { [K in keyof T]: T[K] extends TReadonly ? (T[K] extends TOptional ? K : never) : never }[keyof T] type ReadonlyPropertyKeys = { [K in keyof T]: T[K] extends TReadonly ? (T[K] extends TOptional ? never : K) : never }[keyof T] type OptionalPropertyKeys = { [K in keyof T]: T[K] extends TOptional ? (T[K] extends TReadonly ? never : K) : never }[keyof T] type RequiredPropertyKeys = keyof Omit | ReadonlyPropertyKeys | OptionalPropertyKeys> // prettier-ignore type ObjectStaticProperties> = Evaluate<( Readonly>>> & Readonly>> & Partial>> & Required>> )> // prettier-ignore type ObjectStatic = ObjectStaticProperties }> // ------------------------------------------------------------------ // TProperties // ------------------------------------------------------------------ export type TPropertyKey = string | number // Consider making this PropertyKey export type TProperties = Record // ------------------------------------------------------------------ // TObject // ------------------------------------------------------------------ export type TAdditionalProperties = undefined | TSchema | boolean export interface ObjectOptions extends SchemaOptions { /** Additional property constraints for this object */ additionalProperties?: TAdditionalProperties /** The minimum number of properties allowed on this object */ minProperties?: number /** The maximum number of properties allowed on this object */ maxProperties?: number } export interface TObject extends TSchema, ObjectOptions { [Kind]: 'Object' static: ObjectStatic additionalProperties?: TAdditionalProperties type: 'object' properties: T required?: string[] } function RequiredKeys(properties: T): string[] { const keys: string[] = [] for (let key in properties) { if (!IsOptional(properties[key])) keys.push(key) } return keys } /** `[Json]` Creates an Object type */ function _Object(properties: T, options?: ObjectOptions): TObject { const required = RequiredKeys(properties) const schematic = required.length > 0 ? { [Kind]: 'Object', type: 'object', properties, required } : { [Kind]: 'Object', type: 'object', properties } return CreateType(schematic, options) as never } /** `[Json]` Creates an Object type */ export var Object = _Object sinclairzx81-typebox-e0ec98c/src/type/omit/000077500000000000000000000000001505437577000210005ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/omit/index.ts000066400000000000000000000026031505437577000224600ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './omit-from-mapped-key' export * from './omit-from-mapped-result' export * from './omit' sinclairzx81-typebox-e0ec98c/src/type/omit/omit-from-mapped-key.ts000066400000000000000000000101751505437577000253170ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import type { TProperties } from '../object/index' import { MappedResult, type TMappedResult, type TMappedKey } from '../mapped/index' import { Omit, type TOmit } from './omit' import { Clone } from '../clone/value' // ------------------------------------------------------------------ // FromPropertyKey // ------------------------------------------------------------------ // prettier-ignore type TFromPropertyKey = { [_ in Key]: TOmit } // prettier-ignore function FromPropertyKey(type: Type, key: Key, options?: SchemaOptions): TFromPropertyKey { return { [key]: Omit(type, [key], Clone(options)) } as never } // ------------------------------------------------------------------ // FromPropertyKeys // ------------------------------------------------------------------ // prettier-ignore type TFromPropertyKeys = ( PropertyKeys extends [infer LK extends PropertyKey, ...infer RK extends PropertyKey[]] ? TFromPropertyKeys> : Result ) // prettier-ignore function FromPropertyKeys(type: Type, propertyKeys: [...PropertyKeys], options?: SchemaOptions): TFromPropertyKeys { return propertyKeys.reduce((Acc, LK) => { return { ...Acc, ...FromPropertyKey(type, LK, options) } }, {} as TProperties) as never } // ------------------------------------------------------------------ // FromMappedKey // ------------------------------------------------------------------ // prettier-ignore type TFromMappedKey = ( TFromPropertyKeys ) // prettier-ignore function FromMappedKey(type: Type, mappedKey: MappedKey, options?: SchemaOptions): TFromMappedKey { return FromPropertyKeys(type, mappedKey.keys, options) as never } // ------------------------------------------------------------------ // OmitFromMappedKey // ------------------------------------------------------------------ // prettier-ignore export type TOmitFromMappedKey > = ( TMappedResult ) // prettier-ignore export function OmitFromMappedKey >(type: Type, mappedKey: MappedKey, options?: SchemaOptions): TMappedResult { const properties = FromMappedKey(type, mappedKey, options) return MappedResult(properties) as never } sinclairzx81-typebox-e0ec98c/src/type/omit/omit-from-mapped-result.ts000066400000000000000000000075551505437577000260550ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { SchemaOptions } from '../schema/index' import type { Ensure, Evaluate } from '../helpers/index' import type { TProperties } from '../object/index' import { MappedResult, type TMappedResult } from '../mapped/index' import { Omit, type TOmit } from './omit' import { Clone } from '../clone/value' // ------------------------------------------------------------------ // FromProperties // ------------------------------------------------------------------ // prettier-ignore type TFromProperties = ( { [K2 in keyof Properties]: TOmit } ) // prettier-ignore function FromProperties(properties: Properties, propertyKeys: [...PropertyKeys], options?: SchemaOptions): TFromProperties { const result = {} as TProperties for(const K2 of globalThis.Object.getOwnPropertyNames(properties)) result[K2] = Omit(properties[K2], propertyKeys, Clone(options)) return result as never } // ------------------------------------------------------------------ // FromMappedResult // ------------------------------------------------------------------ // prettier-ignore type TFromMappedResult = ( Evaluate> ) // prettier-ignore function FromMappedResult(mappedResult: MappedResult, propertyKeys: [...PropertyKeys], options?: SchemaOptions): TFromMappedResult { return FromProperties(mappedResult.properties, propertyKeys, options) as never } // ------------------------------------------------------------------ // TOmitFromMappedResult // ------------------------------------------------------------------ // prettier-ignore export type TOmitFromMappedResult< MappedResult extends TMappedResult, PropertyKeys extends PropertyKey[], Properties extends TProperties = TFromMappedResult > = ( Ensure> ) // prettier-ignore export function OmitFromMappedResult< MappedResult extends TMappedResult, PropertyKeys extends PropertyKey[], Properties extends TProperties = TFromMappedResult >(mappedResult: MappedResult, propertyKeys: [...PropertyKeys], options?: SchemaOptions): TMappedResult { const properties = FromMappedResult(mappedResult, propertyKeys, options) return MappedResult(properties) as never } sinclairzx81-typebox-e0ec98c/src/type/omit/omit.ts000066400000000000000000000247131505437577000223270ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import { Discard } from '../discard/discard' import { TransformKind } from '../symbols/symbols' import type { SchemaOptions, TSchema } from '../schema/index' import type { TupleToUnion, Evaluate, Ensure } from '../helpers/index' import { type TRecursive } from '../recursive/index' import type { TMappedKey, TMappedResult } from '../mapped/index' import { Computed, TComputed } from '../computed/index' import { Literal, TLiteral, TLiteralValue } from '../literal/index' import { IndexPropertyKeys, type TIndexPropertyKeys } from '../indexed/index' import { Intersect, type TIntersect } from '../intersect/index' import { Union, type TUnion } from '../union/index' import { Object, type TObject, type TProperties } from '../object/index' import { type TRef } from '../ref/index' // ------------------------------------------------------------------ // Mapped // ------------------------------------------------------------------ import { OmitFromMappedKey, type TOmitFromMappedKey } from './omit-from-mapped-key' import { OmitFromMappedResult, type TOmitFromMappedResult } from './omit-from-mapped-result' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsMappedKey, IsIntersect, IsUnion, IsObject, IsSchema, IsMappedResult, IsLiteralValue, IsRef } from '../guard/kind' import { IsArray as IsArrayValue } from '../guard/value' // ------------------------------------------------------------------ // FromIntersect // ------------------------------------------------------------------ // prettier-ignore type TFromIntersect = ( Types extends [infer L extends TSchema, ...infer R extends TSchema[]] ? TFromIntersect]> : Result ) // prettier-ignore function FromIntersect(types: Types, propertyKeys: PropertyKeys) { return types.map((type) => OmitResolve(type, propertyKeys)) as never } // ------------------------------------------------------------------ // FromUnion // ------------------------------------------------------------------ // prettier-ignore type TFromUnion = ( T extends [infer L extends TSchema, ...infer R extends TSchema[]] ? TFromUnion]> : Result ) // prettier-ignore function FromUnion(types: Types, propertyKeys: PropertyKeys) { return types.map((type) => OmitResolve(type, propertyKeys)) as never } // ------------------------------------------------------------------ // FromProperty // ------------------------------------------------------------------ // prettier-ignore function FromProperty(properties: Properties, key: Key): TProperties { const { [key]: _, ...R } = properties return R } // prettier-ignore type TFromProperties> = ( Evaluate> ) // prettier-ignore function FromProperties(properties: Properties, propertyKeys: PropertyKeys) { return propertyKeys.reduce((T, K2) => FromProperty(T, K2), properties as TProperties) } // ------------------------------------------------------------------ // FromObject // ------------------------------------------------------------------ // prettier-ignore type TFromObject = Ensure )>> // prettier-ignore function FromObject(properties: Properties, propertyKeys: PropertyKeys): TFromObject { const options = Discard(properties, [TransformKind, '$id', 'required', 'properties']) const omittedProperties = FromProperties(properties['properties'], propertyKeys) return Object(omittedProperties, options) as never } // ------------------------------------------------------------------ // UnionFromPropertyKeys // ------------------------------------------------------------------ // prettier-ignore type TUnionFromPropertyKeys = ( PropertyKeys extends [infer Key extends PropertyKey, ...infer Rest extends PropertyKey[]] ? Key extends TLiteralValue ? TUnionFromPropertyKeys]> : TUnionFromPropertyKeys : TUnion ) // prettier-ignore function UnionFromPropertyKeys(propertyKeys: PropertyKeys): TUnionFromPropertyKeys { const result = propertyKeys.reduce((result, key) => IsLiteralValue(key) ? [...result, Literal(key)]: result, [] as TLiteral[]) return Union(result) as never } // ------------------------------------------------------------------ // TOmitResolve // ------------------------------------------------------------------ // prettier-ignore export type TOmitResolve = ( Properties extends TRecursive ? TRecursive> : Properties extends TIntersect ? TIntersect> : Properties extends TUnion ? TUnion> : Properties extends TObject ? TFromObject, PropertyKeys> : TObject<{}> ) // prettier-ignore function OmitResolve(properties: Properties, propertyKeys: [...PropertyKeys]): TOmitResolve { return ( IsIntersect(properties) ? Intersect(FromIntersect(properties.allOf, propertyKeys)) : IsUnion(properties) ? Union(FromUnion(properties.anyOf, propertyKeys)) : IsObject(properties) ? FromObject(properties, propertyKeys) : Object({}) ) as never } // ------------------------------------------------------------------ // TOmit // // This mapping logic is to overly complex because of the decision // to use PropertyKey[] as the default selector. The PropertyKey[] // did make TMapped types simpler to implement, but a non-TSchema // selector makes supporting TComputed awkward as it requires // generalization via TSchema. This type should be reimplemented // in the next major revision to support TSchema as the primary // selector. // // ------------------------------------------------------------------ // prettier-ignore (do not export this type) type TResolvePropertyKeys = Key extends TSchema ? TIndexPropertyKeys : Key // prettier-ignore (do not export this type) type TResolveTypeKey = Key extends PropertyKey[] ? TUnionFromPropertyKeys : Key // prettier-ignore export type TOmit = ( Type extends TMappedResult ? TOmitFromMappedResult> : Key extends TMappedKey ? TOmitFromMappedKey : [IsTypeRef, IsKeyRef] extends [true, true] ? TComputed<'Omit', [Type, TResolveTypeKey]> : [IsTypeRef, IsKeyRef] extends [false, true] ? TComputed<'Omit', [Type, TResolveTypeKey]> : [IsTypeRef, IsKeyRef] extends [true, false] ? TComputed<'Omit', [Type, TResolveTypeKey]> : TOmitResolve> ) /** `[Json]` Constructs a type whose keys are picked from the given type */ export function Omit(type: Type, key: readonly [...Key], options?: SchemaOptions): TOmit /** `[Json]` Constructs a type whose keys are picked from the given type */ export function Omit(type: Type, key: Key, options?: SchemaOptions): TOmit /** `[Json]` Constructs a type whose keys are picked from the given type */ // prettier-ignore export function Omit(type: any, key: any, options?: SchemaOptions): any { const typeKey: TSchema = IsArrayValue(key) ? UnionFromPropertyKeys(key as PropertyKey[]) : key const propertyKeys: PropertyKey[] = IsSchema(key) ? IndexPropertyKeys(key) : key const isTypeRef: boolean = IsRef(type) const isKeyRef: boolean = IsRef(key) return ( IsMappedResult(type) ? OmitFromMappedResult(type, propertyKeys, options) : IsMappedKey(key) ? OmitFromMappedKey(type, key, options) : (isTypeRef && isKeyRef) ? Computed('Omit', [type, typeKey], options) : (!isTypeRef && isKeyRef) ? Computed('Omit', [type, typeKey], options) : (isTypeRef && !isKeyRef) ? Computed('Omit', [type, typeKey], options) : CreateType({ ...OmitResolve(type, propertyKeys), ...options }) ) as never } sinclairzx81-typebox-e0ec98c/src/type/optional/000077500000000000000000000000001505437577000216555ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/optional/index.ts000066400000000000000000000025441505437577000233410ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './optional-from-mapped-result' export * from './optional' sinclairzx81-typebox-e0ec98c/src/type/optional/optional-from-mapped-result.ts000066400000000000000000000061501505437577000275750ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TProperties } from '../object/index' import { MappedResult, type TMappedResult } from '../mapped/index' import { Optional, type TOptionalWithFlag } from './optional' // ------------------------------------------------------------------ // FromProperties // ------------------------------------------------------------------ // prettier-ignore type TFromProperties< P extends TProperties, F extends boolean, > = ( { [K2 in keyof P]: TOptionalWithFlag } ) // prettier-ignore function FromProperties< P extends TProperties, F extends boolean, >(P: P, F: F): TFromProperties { const Acc = {} as TProperties for(const K2 of globalThis.Object.getOwnPropertyNames(P)) Acc[K2] = Optional(P[K2], F) return Acc as never } // ------------------------------------------------------------------ // FromMappedResult // ------------------------------------------------------------------ // prettier-ignore type TFromMappedResult< R extends TMappedResult, F extends boolean, > = ( TFromProperties ) // prettier-ignore function FromMappedResult< R extends TMappedResult, F extends boolean, >(R: R, F: F): TFromMappedResult { return FromProperties(R.properties, F) as never } // ------------------------------------------------------------------ // OptionalFromMappedResult // ------------------------------------------------------------------ // prettier-ignore export type TOptionalFromMappedResult< R extends TMappedResult, F extends boolean, P extends TProperties = TFromMappedResult > = ( TMappedResult

) // prettier-ignore export function OptionalFromMappedResult< R extends TMappedResult, F extends boolean, P extends TProperties = TFromMappedResult >(R: R, F: F): TMappedResult

{ const P = FromMappedResult(R, F) as unknown as P return MappedResult(P) } sinclairzx81-typebox-e0ec98c/src/type/optional/optional.ts000066400000000000000000000074511505437577000240610ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema } from '../schema/index' import type { Ensure } from '../helpers/index' import { OptionalKind } from '../symbols/index' import { Discard } from '../discard/index' import type { TMappedResult } from '../mapped/index' import { OptionalFromMappedResult, type TOptionalFromMappedResult } from './optional-from-mapped-result' import { IsMappedResult } from '../guard/kind' // ------------------------------------------------------------------ // RemoveOptional // ------------------------------------------------------------------ type TRemoveOptional = T extends TOptional ? S : T function RemoveOptional(schema: T) { return CreateType(Discard(schema, [OptionalKind])) } // ------------------------------------------------------------------ // AddOptional // ------------------------------------------------------------------ type TAddOptional = T extends TOptional ? TOptional : Ensure> function AddOptional(schema: T) { return CreateType({ ...schema, [OptionalKind]: 'Optional' }) } // prettier-ignore export type TOptionalWithFlag = F extends false ? TRemoveOptional : TAddOptional // prettier-ignore function OptionalWithFlag(schema: T, F: F) { return ( F === false ? RemoveOptional(schema) : AddOptional(schema) ) } // ------------------------------------------------------------------ // Optional // ------------------------------------------------------------------ export type TOptional = T & { [OptionalKind]: 'Optional' } /** `[Json]` Creates a Optional property */ export function Optional(schema: T, enable: F): TOptionalFromMappedResult /** `[Json]` Creates a Optional property */ export function Optional(schema: T, enable: F): TOptionalWithFlag /** `[Json]` Creates a Optional property */ export function Optional(schema: T): TOptionalFromMappedResult /** `[Json]` Creates a Optional property */ export function Optional(schema: T): TOptionalWithFlag /** `[Json]` Creates a Optional property */ export function Optional(schema: TSchema, enable?: boolean): any { const F = enable ?? true return IsMappedResult(schema) ? OptionalFromMappedResult(schema, F) : OptionalWithFlag(schema, F) } sinclairzx81-typebox-e0ec98c/src/type/parameters/000077500000000000000000000000001505437577000221735ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/parameters/index.ts000066400000000000000000000024701505437577000236550ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './parameters' sinclairzx81-typebox-e0ec98c/src/type/parameters/parameters.ts000066400000000000000000000042401505437577000247060ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import type { TFunction } from '../function/index' import { Tuple, type TTuple } from '../tuple/index' import { Never, type TNever } from '../never/index' import * as KindGuard from '../guard/kind' // ------------------------------------------------------------------ // Parameters // ------------------------------------------------------------------ // prettier-ignore export type TParameters = ( Type extends TFunction ? TTuple : TNever ) /** `[JavaScript]` Extracts the Parameters from the given Function type */ export function Parameters(schema: Type, options?: SchemaOptions): TParameters { return (KindGuard.IsFunction(schema) ? Tuple(schema.parameters, options) : Never()) as never } sinclairzx81-typebox-e0ec98c/src/type/partial/000077500000000000000000000000001505437577000214645ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/partial/index.ts000066400000000000000000000025421505437577000231460ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './partial-from-mapped-result' export * from './partial' sinclairzx81-typebox-e0ec98c/src/type/partial/partial-from-mapped-result.ts000066400000000000000000000062561505437577000272220ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { SchemaOptions } from '../schema/index' import type { Ensure, Evaluate } from '../helpers/index' import type { TProperties } from '../object/index' import { MappedResult, type TMappedResult } from '../mapped/index' import { Partial, type TPartial } from './partial' import { Clone } from '../clone/value' // ------------------------------------------------------------------ // FromProperties // ------------------------------------------------------------------ // prettier-ignore type TFromProperties< P extends TProperties > = ( { [K2 in keyof P]: TPartial } ) // prettier-ignore function FromProperties< P extends TProperties >(K: P, options?: SchemaOptions): TFromProperties

{ const Acc = {} as TProperties for(const K2 of globalThis.Object.getOwnPropertyNames(K)) Acc[K2] = Partial(K[K2], Clone(options)) return Acc as never } // ------------------------------------------------------------------ // FromMappedResult // ------------------------------------------------------------------ // prettier-ignore type TFromMappedResult< R extends TMappedResult > = ( Evaluate> ) // prettier-ignore function FromMappedResult< R extends TMappedResult >(R: R, options?: SchemaOptions): TFromMappedResult { return FromProperties(R.properties, options) as never } // ------------------------------------------------------------------ // TPartialFromMappedResult // ------------------------------------------------------------------ // prettier-ignore export type TPartialFromMappedResult< R extends TMappedResult, P extends TProperties = TFromMappedResult > = ( Ensure> ) // prettier-ignore export function PartialFromMappedResult< R extends TMappedResult, P extends TProperties = TFromMappedResult >(R: R, options?: SchemaOptions): TMappedResult

{ const P = FromMappedResult(R, options) return MappedResult(P) as never } sinclairzx81-typebox-e0ec98c/src/type/partial/partial.ts000066400000000000000000000207461505437577000235010ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import type { Evaluate, Ensure } from '../helpers/index' import type { TMappedResult } from '../mapped/index' import { type TReadonlyOptional } from '../readonly-optional/index' import { type TComputed, Computed } from '../computed/index' import { type TOptional, Optional } from '../optional/index' import { type TReadonly } from '../readonly/index' import { type TRecursive } from '../recursive/index' import { type TObject, type TProperties, Object } from '../object/index' import { type TIntersect, Intersect } from '../intersect/index' import { type TUnion, Union } from '../union/index' import { type TRef, Ref } from '../ref/index' import { type TBigInt } from '../bigint/index' import { type TBoolean } from '../boolean/index' import { type TInteger } from '../integer/index' import { type TLiteral } from '../literal/index' import { type TNull } from '../null/index' import { type TNumber } from '../number/index' import { type TString } from '../string/index' import { type TSymbol } from '../symbol/index' import { type TUndefined } from '../undefined/index' import { Discard } from '../discard/index' import { TransformKind } from '../symbols/index' import { PartialFromMappedResult, type TPartialFromMappedResult } from './partial-from-mapped-result' // ------------------------------------------------------------------ // KindGuard // ------------------------------------------------------------------ import * as KindGuard from '../guard/kind' // ------------------------------------------------------------------ // FromComputed // ------------------------------------------------------------------ // prettier-ignore type TFromComputed = Ensure< TComputed<'Partial', [TComputed]> > // prettier-ignore function FromComputed(target: Target, parameters: Parameters): TFromComputed { return Computed('Partial', [Computed(target, parameters)]) as never } // ------------------------------------------------------------------ // FromRef // ------------------------------------------------------------------ // prettier-ignore type TFromRef = Ensure< TComputed<'Partial', [TRef]> > // prettier-ignore function FromRef($ref: Ref): TFromRef { return Computed('Partial', [Ref($ref)]) as never } // ------------------------------------------------------------------ // FromProperties // ------------------------------------------------------------------ // prettier-ignore type TFromProperties = Evaluate<{ [K in keyof Properties]: Properties[K] extends (TReadonlyOptional) ? TReadonlyOptional : Properties[K] extends (TReadonly) ? TReadonlyOptional : Properties[K] extends (TOptional) ? TOptional : TOptional }> // prettier-ignore function FromProperties(properties: Properties): TFromProperties { const partialProperties = {} as TProperties for(const K of globalThis.Object.getOwnPropertyNames(properties)) partialProperties[K] = Optional(properties[K]) return partialProperties as never } // ------------------------------------------------------------------ // FromObject // ------------------------------------------------------------------ // prettier-ignore type TFromObject = Ensure )>> // prettier-ignore function FromObject(type: Type): TFromObject { const options = Discard(type, [TransformKind, '$id', 'required', 'properties']) const properties = FromProperties(type['properties']) return Object(properties, options) as never } // ------------------------------------------------------------------ // FromRest // ------------------------------------------------------------------ // prettier-ignore type TFromRest = ( Types extends [infer L extends TSchema, ...infer R extends TSchema[]] ? TFromRest]> : Result ) // prettier-ignore function FromRest(types: [...Types]): TFromRest { return types.map(type => PartialResolve(type)) as never } // ------------------------------------------------------------------ // PartialResolve // ------------------------------------------------------------------ // prettier-ignore function PartialResolve(type: Type): TPartial { return ( // Mappable KindGuard.IsComputed(type) ? FromComputed(type.target, type.parameters) : KindGuard.IsRef(type) ? FromRef(type.$ref) : KindGuard.IsIntersect(type) ? Intersect(FromRest(type.allOf)) : KindGuard.IsUnion(type) ? Union(FromRest(type.anyOf)) : KindGuard.IsObject(type) ? FromObject(type) : // Intrinsic KindGuard.IsBigInt(type) ? type : KindGuard.IsBoolean(type) ? type : KindGuard.IsInteger(type) ? type : KindGuard.IsLiteral(type) ? type : KindGuard.IsNull(type) ? type : KindGuard.IsNumber(type) ? type : KindGuard.IsString(type) ? type : KindGuard.IsSymbol(type) ? type : KindGuard.IsUndefined(type) ? type : // Passthrough Object({}) ) as never } // ------------------------------------------------------------------ // TPartial // ------------------------------------------------------------------ // prettier-ignore export type TPartial = ( // Mappable Type extends TRecursive ? TRecursive> : Type extends TComputed ? TFromComputed : Type extends TRef ? TFromRef : Type extends TIntersect ? TIntersect> : Type extends TUnion ? TUnion> : Type extends TObject ? TFromObject> : // Intrinsic Type extends TBigInt ? Type : Type extends TBoolean ? Type : Type extends TInteger ? Type : Type extends TLiteral ? Type : Type extends TNull ? Type : Type extends TNumber ? Type : Type extends TString ? Type : Type extends TSymbol ? Type : Type extends TUndefined ? Type : // Passthrough TObject<{}> ) /** `[Json]` Constructs a type where all properties are optional */ export function Partial(type: MappedResult, options?: SchemaOptions): TPartialFromMappedResult /** `[Json]` Constructs a type where all properties are optional */ export function Partial(type: Type, options?: SchemaOptions): TPartial /** `[Json]` Constructs a type where all properties are optional */ export function Partial(type: TSchema, options?: SchemaOptions): unknown { if (KindGuard.IsMappedResult(type)) { return PartialFromMappedResult(type, options) } else { // special: mapping types require overridable options return CreateType({ ...PartialResolve(type), ...options }) } } sinclairzx81-typebox-e0ec98c/src/type/patterns/000077500000000000000000000000001505437577000216705ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/patterns/index.ts000066400000000000000000000024661505437577000233570ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './patterns' sinclairzx81-typebox-e0ec98c/src/type/patterns/patterns.ts000066400000000000000000000032341505437577000241020ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export const PatternBoolean = '(true|false)' export const PatternNumber = '(0|[1-9][0-9]*)' export const PatternString = '(.*)' export const PatternNever = '(?!.*)' export const PatternBooleanExact = `^${PatternBoolean}$` export const PatternNumberExact = `^${PatternNumber}$` export const PatternStringExact = `^${PatternString}$` export const PatternNeverExact = `^${PatternNever}$` sinclairzx81-typebox-e0ec98c/src/type/pick/000077500000000000000000000000001505437577000207565ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/pick/index.ts000066400000000000000000000026031505437577000224360ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './pick-from-mapped-key' export * from './pick-from-mapped-result' export * from './pick' sinclairzx81-typebox-e0ec98c/src/type/pick/pick-from-mapped-key.ts000066400000000000000000000102531505437577000252500ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import type { TProperties } from '../object/index' import { MappedResult, type TMappedResult, type TMappedKey } from '../mapped/index' import { Pick, type TPick } from './pick' import { Clone } from '../clone/value' // ------------------------------------------------------------------ // FromPropertyKey // ------------------------------------------------------------------ // prettier-ignore type TFromPropertyKey = { [_ in Key]: TPick } // prettier-ignore function FromPropertyKey(type: Type, key: Key, options?: SchemaOptions): TFromPropertyKey { return { [key]: Pick(type, [key], Clone(options)) } as never } // ------------------------------------------------------------------ // FromPropertyKeys // ------------------------------------------------------------------ // prettier-ignore type TFromPropertyKeys = ( PropertyKeys extends [infer LeftKey extends PropertyKey, ...infer RightKeys extends PropertyKey[]] ? TFromPropertyKeys> : Result ) // prettier-ignore function FromPropertyKeys(type: Type, propertyKeys: [...PropertyKeys], options?: SchemaOptions): TFromPropertyKeys { return propertyKeys.reduce((result, leftKey) => { return { ...result, ...FromPropertyKey(type, leftKey, options) } }, {} as TProperties) as never } // ------------------------------------------------------------------ // FromMappedKey // ------------------------------------------------------------------ // prettier-ignore type TFromMappedKey = ( TFromPropertyKeys ) // prettier-ignore function FromMappedKey(type: Type, mappedKey: MappedKey, options?: SchemaOptions): TFromMappedKey { return FromPropertyKeys(type, mappedKey.keys, options) as never } // ------------------------------------------------------------------ // PickFromMappedKey // ------------------------------------------------------------------ // prettier-ignore export type TPickFromMappedKey > = ( TMappedResult ) // prettier-ignore export function PickFromMappedKey >(type: Type, mappedKey: MappedKey, options?: SchemaOptions): TMappedResult { const properties = FromMappedKey(type, mappedKey, options) return MappedResult(properties) as never } sinclairzx81-typebox-e0ec98c/src/type/pick/pick-from-mapped-result.ts000066400000000000000000000075471505437577000260120ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { SchemaOptions } from '../schema/index' import type { Ensure, Evaluate } from '../helpers/index' import type { TProperties } from '../object/index' import { MappedResult, type TMappedResult } from '../mapped/index' import { Pick, type TPick } from './pick' import { Clone } from '../clone/value' // ------------------------------------------------------------------ // FromProperties // ------------------------------------------------------------------ // prettier-ignore type TFromProperties = ( { [K2 in keyof Properties]: TPick } ) // prettier-ignore function FromProperties(properties: Properties, propertyKeys: [...PropertyKeys], options?: SchemaOptions): TFromProperties { const result = {} as TProperties for(const K2 of globalThis.Object.getOwnPropertyNames(properties)) result[K2] = Pick(properties[K2], propertyKeys, Clone(options)) return result as never } // ------------------------------------------------------------------ // FromMappedResult // ------------------------------------------------------------------ // prettier-ignore type TFromMappedResult = ( Evaluate> ) // prettier-ignore function FromMappedResult(mappedResult: MappedResult, propertyKeys: [...PropertyKeys], options?: SchemaOptions): TFromMappedResult { return FromProperties(mappedResult.properties, propertyKeys, options) as never } // ------------------------------------------------------------------ // PickFromMappedResult // ------------------------------------------------------------------ // prettier-ignore export type TPickFromMappedResult > = ( Ensure> ) // prettier-ignore export function PickFromMappedResult< MappedResult extends TMappedResult, PropertyKeys extends PropertyKey[], Properties extends TProperties = TFromMappedResult >(mappedResult: MappedResult, propertyKeys: [...PropertyKeys], options?: SchemaOptions): TMappedResult { const properties = FromMappedResult(mappedResult, propertyKeys, options) return MappedResult(properties) as never } sinclairzx81-typebox-e0ec98c/src/type/pick/pick.ts000066400000000000000000000246231505437577000222630ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import { Discard } from '../discard/discard' import type { TSchema, SchemaOptions } from '../schema/index' import type { TupleToUnion, Evaluate, Ensure } from '../helpers/index' import { type TRecursive } from '../recursive/index' import { Computed, type TComputed } from '../computed/index' import { Intersect, type TIntersect } from '../intersect/index' import { Literal, type TLiteral, type TLiteralValue } from '../literal/index' import { Object, type TObject, type TProperties, type TPropertyKey } from '../object/index' import { Union, type TUnion } from '../union/index' import { type TMappedKey, type TMappedResult } from '../mapped/index' import { type TRef } from '../ref/index' import { IndexPropertyKeys, type TIndexPropertyKeys } from '../indexed/index' import { TransformKind } from '../symbols/symbols' // ------------------------------------------------------------------ // Guards // ------------------------------------------------------------------ import { IsMappedKey, IsMappedResult, IsIntersect, IsUnion, IsObject, IsSchema, IsLiteralValue, IsRef } from '../guard/kind' import { IsArray as IsArrayValue } from '../guard/value' // ------------------------------------------------------------------ // Infrastructure // ------------------------------------------------------------------ import { PickFromMappedKey, type TPickFromMappedKey } from './pick-from-mapped-key' import { PickFromMappedResult, type TPickFromMappedResult } from './pick-from-mapped-result' // ------------------------------------------------------------------ // FromIntersect // ------------------------------------------------------------------ // prettier-ignore type TFromIntersect = Types extends [infer L extends TSchema, ...infer R extends TSchema[]] ? TFromIntersect]> : Result function FromIntersect(types: Types, propertyKeys: PropertyKeys): TFromIntersect { return types.map((type) => PickResolve(type, propertyKeys)) as never } // ------------------------------------------------------------------ // FromUnion // ------------------------------------------------------------------ // prettier-ignore type TFromUnion = Types extends [infer L extends TSchema, ...infer R extends TSchema[]] ? TFromUnion]> : Result // prettier-ignore function FromUnion(types: Types, propertyKeys: PropertyKeys): TFromUnion { return types.map((type) => PickResolve(type, propertyKeys)) as never } // ------------------------------------------------------------------ // FromProperties // ------------------------------------------------------------------ // prettier-ignore type TFromProperties> = ( Evaluate> ) // prettier-ignore function FromProperties(properties: Properties, propertyKeys: PropertyKeys): TFromProperties { const result = {} as TProperties for(const K2 of propertyKeys) if(K2 in properties) result[K2 as TPropertyKey] = properties[K2 as keyof Properties] return result as never } // ------------------------------------------------------------------ // FromObject // ------------------------------------------------------------------ // prettier-ignore type TFromObject = Ensure )>> // prettier-ignore function FromObject(T: T, K: K): TFromObject { const options = Discard(T, [TransformKind, '$id', 'required', 'properties']) const properties = FromProperties(T['properties'], K) return Object(properties, options) as never } // ------------------------------------------------------------------ // UnionFromPropertyKeys // ------------------------------------------------------------------ // prettier-ignore type TUnionFromPropertyKeys = ( PropertyKeys extends [infer Key extends PropertyKey, ...infer Rest extends PropertyKey[]] ? Key extends TLiteralValue ? TUnionFromPropertyKeys]> : TUnionFromPropertyKeys : TUnion ) // prettier-ignore function UnionFromPropertyKeys(propertyKeys: PropertyKeys): TUnionFromPropertyKeys { const result = propertyKeys.reduce((result, key) => IsLiteralValue(key) ? [...result, Literal(key)]: result, [] as TLiteral[]) return Union(result) as never } // ------------------------------------------------------------------ // TPickResolve // ------------------------------------------------------------------ // prettier-ignore export type TPickResolve = ( Properties extends TRecursive ? TRecursive> : Properties extends TIntersect ? TIntersect> : Properties extends TUnion ? TUnion> : Properties extends TObject ? TFromObject, PropertyKeys> : TObject<{}> ) // prettier-ignore function PickResolve(properties: Properties, propertyKeys: [...PropertyKeys]): TPickResolve { return ( IsIntersect(properties) ? Intersect(FromIntersect(properties.allOf, propertyKeys)) : IsUnion(properties) ? Union(FromUnion(properties.anyOf, propertyKeys)) : IsObject(properties) ? FromObject(properties, propertyKeys) : Object({}) ) as never } // ------------------------------------------------------------------ // TPick // // This mapping logic is to overly complex because of the decision // to use PropertyKey[] as the default selector. The PropertyKey[] // did make TMapped types simpler to implement, but a non-TSchema // selector makes supporting TComputed awkward as it requires // generalization via TSchema. This type should be reimplemented // in the next major revision to support TSchema as the primary // selector. // // ------------------------------------------------------------------ // prettier-ignore (do not export this type) type TResolvePropertyKeys = Key extends TSchema ? TIndexPropertyKeys : Key // prettier-ignore (do not export this type) type TResolveTypeKey = Key extends PropertyKey[] ? TUnionFromPropertyKeys : Key // prettier-ignore export type TPick = ( Type extends TMappedResult ? TPickFromMappedResult> : Key extends TMappedKey ? TPickFromMappedKey : [IsTypeRef, IsKeyRef] extends [true, true] ? TComputed<'Pick', [Type, TResolveTypeKey]> : [IsTypeRef, IsKeyRef] extends [false, true] ? TComputed<'Pick', [Type, TResolveTypeKey]> : [IsTypeRef, IsKeyRef] extends [true, false] ? TComputed<'Pick', [Type, TResolveTypeKey]> : TPickResolve> ) /** `[Json]` Constructs a type whose keys are picked from the given type */ export function Pick(type: Type, key: readonly [...Key], options?: SchemaOptions): TPick /** `[Json]` Constructs a type whose keys are picked from the given type */ export function Pick(type: Type, key: Key, options?: SchemaOptions): TPick /** `[Json]` Constructs a type whose keys are picked from the given type */ // prettier-ignore export function Pick(type: any, key: any, options?: SchemaOptions): any { const typeKey: TSchema = IsArrayValue(key) ? UnionFromPropertyKeys(key as PropertyKey[]) : key const propertyKeys: PropertyKey[] = IsSchema(key) ? IndexPropertyKeys(key) : key const isTypeRef: boolean = IsRef(type) const isKeyRef: boolean = IsRef(key) return ( IsMappedResult(type) ? PickFromMappedResult(type, propertyKeys, options) : IsMappedKey(key) ? PickFromMappedKey(type, key, options) : (isTypeRef && isKeyRef) ? Computed('Pick', [type, typeKey], options) : (!isTypeRef && isKeyRef) ? Computed('Pick', [type, typeKey], options) : (isTypeRef && !isKeyRef) ? Computed('Pick', [type, typeKey], options) : CreateType({ ...PickResolve(type, propertyKeys), ...options }) ) as never } sinclairzx81-typebox-e0ec98c/src/type/promise/000077500000000000000000000000001505437577000215065ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/promise/index.ts000066400000000000000000000024651505437577000231740ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './promise' sinclairzx81-typebox-e0ec98c/src/type/promise/promise.ts000066400000000000000000000035511505437577000235400ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import type { Static } from '../static/index' import { Kind } from '../symbols/index' export interface TPromise extends TSchema { [Kind]: 'Promise' static: Promise> type: 'Promise' item: TSchema } /** `[JavaScript]` Creates a Promise type */ export function Promise(item: T, options?: SchemaOptions): TPromise { return CreateType({ [Kind]: 'Promise', type: 'Promise', item }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/readonly-optional/000077500000000000000000000000001505437577000234705ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/readonly-optional/index.ts000066400000000000000000000024771505437577000251610ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './readonly-optional' sinclairzx81-typebox-e0ec98c/src/type/readonly-optional/readonly-optional.ts000066400000000000000000000033271505437577000275050ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema } from '../schema/index' import { type TReadonly, Readonly } from '../readonly/index' import { type TOptional, Optional } from '../optional/index' export type TReadonlyOptional = TOptional & TReadonly /** `[Json]` Creates a Readonly and Optional property */ export function ReadonlyOptional(schema: T): TReadonly> { return Readonly(Optional(schema)) as never } sinclairzx81-typebox-e0ec98c/src/type/readonly/000077500000000000000000000000001505437577000216455ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/readonly/index.ts000066400000000000000000000025441505437577000233310ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './readonly-from-mapped-result' export * from './readonly' sinclairzx81-typebox-e0ec98c/src/type/readonly/readonly-from-mapped-result.ts000066400000000000000000000061441505437577000275600ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TProperties } from '../object/index' import { MappedResult, type TMappedResult } from '../mapped/index' import { Readonly, type TReadonlyWithFlag } from './readonly' // ------------------------------------------------------------------ // FromProperties // ------------------------------------------------------------------ // prettier-ignore type TFromProperties< P extends TProperties, F extends boolean, > = ( { [K2 in keyof P]: TReadonlyWithFlag } ) // prettier-ignore function FromProperties< P extends TProperties, F extends boolean, >(K: P, F: F): TFromProperties { const Acc = {} as TProperties for(const K2 of globalThis.Object.getOwnPropertyNames(K)) Acc[K2] = Readonly(K[K2], F) return Acc as never } // ------------------------------------------------------------------ // FromMappedResult // ------------------------------------------------------------------ // prettier-ignore type TFromMappedResult< R extends TMappedResult, F extends boolean, > = ( TFromProperties ) // prettier-ignore function FromMappedResult< R extends TMappedResult, F extends boolean, >(R: R, F: F): TFromMappedResult { return FromProperties(R.properties, F) as never } // ------------------------------------------------------------------ // ReadonlyFromMappedResult // ------------------------------------------------------------------ // prettier-ignore export type TReadonlyFromMappedResult< R extends TMappedResult, F extends boolean, P extends TProperties = TFromMappedResult > = ( TMappedResult

) // prettier-ignore export function ReadonlyFromMappedResult< R extends TMappedResult, F extends boolean, P extends TProperties = TFromMappedResult >(R: R, F: F): TMappedResult

{ const P = FromMappedResult(R, F) return MappedResult(P) as never } sinclairzx81-typebox-e0ec98c/src/type/readonly/readonly.ts000066400000000000000000000074521505437577000240420ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema } from '../schema/index' import type { Ensure } from '../helpers/index' import { ReadonlyKind } from '../symbols/index' import { Discard } from '../discard/index' import type { TMappedResult } from '../mapped/index' import { ReadonlyFromMappedResult, type TReadonlyFromMappedResult } from './readonly-from-mapped-result' import { IsMappedResult } from '../guard/kind' // ------------------------------------------------------------------ // RemoveReadonly // ------------------------------------------------------------------ type TRemoveReadonly = T extends TReadonly ? S : T function RemoveReadonly(schema: T) { return CreateType(Discard(schema, [ReadonlyKind])) } // ------------------------------------------------------------------ // AddReadonly // ------------------------------------------------------------------ type TAddReadonly = T extends TReadonly ? TReadonly : Ensure> function AddReadonly(schema: T) { return CreateType({ ...schema, [ReadonlyKind]: 'Readonly' }) } // prettier-ignore export type TReadonlyWithFlag = F extends false ? TRemoveReadonly : TAddReadonly // prettier-ignore function ReadonlyWithFlag(schema: T, F: F) { return ( F === false ? RemoveReadonly(schema) : AddReadonly(schema) ) } // ------------------------------------------------------------------ // TReadonly // ------------------------------------------------------------------ export type TReadonly = T & { [ReadonlyKind]: 'Readonly' } /** `[Json]` Creates a Readonly property */ export function Readonly(schema: T, enable: F): TReadonlyFromMappedResult /** `[Json]` Creates a Readonly property */ export function Readonly(schema: T, enable: F): TReadonlyWithFlag /** `[Json]` Creates a Readonly property */ export function Readonly(schema: T): TReadonlyFromMappedResult /** `[Json]` Creates a Readonly property */ export function Readonly(schema: T): TReadonlyWithFlag /** `[Json]` Creates a Readonly property */ export function Readonly(schema: TSchema, enable?: boolean): any { const F = enable ?? true return IsMappedResult(schema) ? ReadonlyFromMappedResult(schema, F) : ReadonlyWithFlag(schema, F) } sinclairzx81-typebox-e0ec98c/src/type/record/000077500000000000000000000000001505437577000213065ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/record/index.ts000066400000000000000000000024641505437577000227730ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './record' sinclairzx81-typebox-e0ec98c/src/type/record/record.ts000066400000000000000000000361161505437577000231430ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import { Kind, Hint } from '../symbols/index' import type { TSchema } from '../schema/index' import type { Static } from '../static/index' import type { Evaluate, Ensure, Assert } from '../helpers/index' import { type TAny } from '../any/index' import { type TBoolean } from '../boolean/index' import { type TEnumRecord, type TEnum } from '../enum/index' import { type TInteger } from '../integer/index' import { type TLiteral, type TLiteralValue } from '../literal/index' import { type TNever, Never } from '../never/index' import { type TNumber, Number } from '../number/index' import { type TObject, type TProperties, type TAdditionalProperties, type ObjectOptions, Object } from '../object/index' import { type TRegExp } from '../regexp/index' import { type TString, String } from '../string/index' import { type TUnion, Union } from '../union/index' import { IsTemplateLiteralFinite, TIsTemplateLiteralFinite, type TTemplateLiteral } from '../template-literal/index' import { PatternStringExact, PatternNumberExact, PatternNeverExact } from '../patterns/index' import { IndexPropertyKeys } from '../indexed/index' // ------------------------------------------------------------------ // ValueGuard // ------------------------------------------------------------------ import { IsUndefined } from '../guard/value' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsInteger, IsLiteral, IsAny, IsBoolean, IsNever, IsNumber, IsString, IsRegExp, IsTemplateLiteral, IsUnion, IsRef, IsComputed } from '../guard/kind' // ------------------------------------------------------------------ // RecordCreateFromPattern // ------------------------------------------------------------------ // prettier-ignore function RecordCreateFromPattern(pattern: string, T: TSchema, options: ObjectOptions): TRecord { return CreateType({ [Kind]: 'Record', type: 'object', patternProperties: { [pattern]: T } }, options) as never } // ------------------------------------------------------------------ // RecordCreateFromKeys // ------------------------------------------------------------------ // prettier-ignore function RecordCreateFromKeys(K: string[], T: TSchema, options: ObjectOptions): TObject { const result = {} as TProperties for(const K2 of K) result[K2] = T return Object(result, { ...options, [Hint]: 'Record' }) } // ------------------------------------------------------------------ // FromTemplateLiteralKey (Fast Inference) // ------------------------------------------------------------------ // prettier-ignore type TFromTemplateLiteralKeyInfinite = Ensure> // prettier-ignore type TFromTemplateLiteralKeyFinite> = ( Ensure>> ) // prettier-ignore type TFromTemplateLiteralKey = TIsTemplateLiteralFinite extends false ? TFromTemplateLiteralKeyInfinite : TFromTemplateLiteralKeyFinite // prettier-ignore function FromTemplateLiteralKey(K: Key, T: Type, options: ObjectOptions): TFromTemplateLiteralKey { return ( IsTemplateLiteralFinite(K) ? RecordCreateFromKeys(IndexPropertyKeys(K), T, options) : RecordCreateFromPattern(K.pattern, T, options) ) as never } // ------------------------------------------------------------------ // FromEnumKey (Special Case) // ------------------------------------------------------------------ // prettier-ignore type TFromEnumKey, Type extends TSchema> = Ensure> // ------------------------------------------------------------------ // FromUnionKey // ------------------------------------------------------------------ // prettier-ignore type TFromUnionKeyLiteralString, Type extends TSchema> = { [_ in Key['const']]: Type } // prettier-ignore type TFromUnionKeyLiteralNumber, Type extends TSchema> = { [_ in Key['const']]: Type } // prettier-ignore type TFromUnionKeyVariants = Keys extends [infer Left extends TSchema, ...infer Right extends TSchema[]] ? ( Left extends TUnion ? TFromUnionKeyVariants> : Left extends TLiteral ? TFromUnionKeyVariants> : Left extends TLiteral ? TFromUnionKeyVariants> : {}) : Result // prettier-ignore type TFromUnionKey> = ( Ensure>> ) // prettier-ignore function FromUnionKey(key: Key, type: Type, options: ObjectOptions): TFromUnionKey { return RecordCreateFromKeys(IndexPropertyKeys(Union(key)), type, options) as never } // ------------------------------------------------------------------ // FromLiteralKey // ------------------------------------------------------------------ // prettier-ignore type TFromLiteralKey = ( Ensure]: Type }>> ) // prettier-ignore function FromLiteralKey(key: Key, type: Type, options: ObjectOptions): TFromLiteralKey { return RecordCreateFromKeys([(key as string).toString()], type, options) as never } // ------------------------------------------------------------------ // TFromRegExpKey // ------------------------------------------------------------------ // prettier-ignore type TFromRegExpKey<_Key extends TRegExp, Type extends TSchema> = ( Ensure> ) // prettier-ignore function FromRegExpKey(key: Key, type: Type, options: ObjectOptions): TFromRegExpKey { return RecordCreateFromPattern(key.source, type, options) as never } // ------------------------------------------------------------------ // FromStringKey // ------------------------------------------------------------------ // prettier-ignore type TFromStringKey<_Key extends TString, Type extends TSchema> = ( Ensure> ) // prettier-ignore function FromStringKey(key: Key, type: Type, options: ObjectOptions): TFromStringKey { const pattern = IsUndefined(key.pattern) ? PatternStringExact : key.pattern return RecordCreateFromPattern(pattern, type, options) as never } // ------------------------------------------------------------------ // FromAnyKey // ------------------------------------------------------------------ // prettier-ignore type TFromAnyKey<_Key extends TAny, Type extends TSchema> = ( Ensure> ) // prettier-ignore function FromAnyKey(_: Key, type: Type, options: ObjectOptions): TFromAnyKey { return RecordCreateFromPattern(PatternStringExact, type, options) as never } // ------------------------------------------------------------------ // FromNeverKey // ------------------------------------------------------------------ // prettier-ignore type TFromNeverKey<_Key extends TNever, Type extends TSchema> = ( Ensure> ) // prettier-ignore function FromNeverKey(_key: Key, type: Type, options: ObjectOptions): TFromNeverKey { return RecordCreateFromPattern(PatternNeverExact, type, options) as never } // ------------------------------------------------------------------ // TromBooleanKey // ------------------------------------------------------------------ // prettier-ignore type TFromBooleanKey<_Key extends TBoolean, Type extends TSchema> = ( Ensure> ) // prettier-ignore function FromBooleanKey(_key: Key, type: Type, options: ObjectOptions): TFromBooleanKey { return Object({ true: type, false: type }, options) } // ------------------------------------------------------------------ // FromIntegerKey // ------------------------------------------------------------------ // prettier-ignore type TFromIntegerKey<_Key extends TSchema, Type extends TSchema> = ( Ensure> ) // prettier-ignore function FromIntegerKey(_key: Key, type: Type, options: ObjectOptions): TFromIntegerKey { return RecordCreateFromPattern(PatternNumberExact, type, options) as never } // ------------------------------------------------------------------ // FromNumberKey // ------------------------------------------------------------------ // prettier-ignore type TFromNumberKey<_Key extends TSchema, Type extends TSchema> = ( Ensure> ) // prettier-ignore function FromNumberKey(_: Key, type: Type, options: ObjectOptions): TFromNumberKey { return RecordCreateFromPattern(PatternNumberExact, type, options) as never } // ------------------------------------------------------------------ // TRecord // ------------------------------------------------------------------ // prettier-ignore type RecordStatic = ( // Note: We would return a Record here, but recursive Record types will // break when T is self recursive. We can mitigate this by using a Mapped instead. Evaluate<{ [_ in Assert, PropertyKey>]: Static }> ) // prettier-ignore export interface TRecord extends TSchema { [Kind]: 'Record' static: RecordStatic type: 'object' patternProperties: { [pattern: string]: Type } additionalProperties: TAdditionalProperties } // ------------------------------------------------------------------ // TRecordOrObject // ------------------------------------------------------------------ // prettier-ignore export type TRecordOrObject = ( Key extends TTemplateLiteral ? TFromTemplateLiteralKey : Key extends TEnum ? TFromEnumKey : // (Special: Ensure resolve Enum before Union) Key extends TUnion ? TFromUnionKey : Key extends TLiteral ? TFromLiteralKey : Key extends TBoolean ? TFromBooleanKey : Key extends TInteger ? TFromIntegerKey : Key extends TNumber ? TFromNumberKey : Key extends TRegExp ? TFromRegExpKey : Key extends TString ? TFromStringKey : Key extends TAny ? TFromAnyKey : Key extends TNever ? TFromNeverKey : TNever ) // ------------------------------------------------------------------ // TRecordOrObject // ------------------------------------------------------------------ /** `[Json]` Creates a Record type */ export function Record(key: Key, type: Type, options: ObjectOptions = {}): TRecordOrObject { // prettier-ignore return ( IsUnion(key) ? FromUnionKey(key.anyOf, type, options) : IsTemplateLiteral(key) ? FromTemplateLiteralKey(key, type, options) : IsLiteral(key) ? FromLiteralKey(key.const, type, options) : IsBoolean(key) ? FromBooleanKey(key, type, options) : IsInteger(key) ? FromIntegerKey(key, type, options) : IsNumber(key) ? FromNumberKey(key, type, options) : IsRegExp(key) ? FromRegExpKey(key, type, options) : IsString(key) ? FromStringKey(key, type, options) : IsAny(key) ? FromAnyKey(key, type, options) : IsNever(key) ? FromNeverKey(key, type, options) : Never(options) ) as never } // ------------------------------------------------------------------ // Record Utilities // ------------------------------------------------------------------ /** Gets the Records Pattern */ export function RecordPattern(record: TRecord): string { return globalThis.Object.getOwnPropertyNames(record.patternProperties)[0] } // ------------------------------------------------------------------ // RecordKey // ------------------------------------------------------------------ /** Gets the Records Key Type */ // prettier-ignore export type TRecordKey ? ( Key extends TNumber ? TNumber : Key extends TString ? TString : TString ) : TString > = Result /** Gets the Records Key Type */ // prettier-ignore export function RecordKey(type: Type): TRecordKey { const pattern = RecordPattern(type) return ( pattern === PatternStringExact ? String() : pattern === PatternNumberExact ? Number() : String({ pattern }) ) as never } // ------------------------------------------------------------------ // RecordValue // ------------------------------------------------------------------ /** Gets a Record Value Type */ // prettier-ignore export type TRecordValue ? Value : TNever ) > = Result /** Gets a Record Value Type */ // prettier-ignore export function RecordValue(type: Type): TRecordValue { return type.patternProperties[RecordPattern(type)] as never } sinclairzx81-typebox-e0ec98c/src/type/recursive/000077500000000000000000000000001505437577000220375ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/recursive/index.ts000066400000000000000000000024671505437577000235270ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './recursive' sinclairzx81-typebox-e0ec98c/src/type/recursive/recursive.ts000066400000000000000000000054611505437577000244240ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import { CloneType } from '../clone/type' import { CreateType } from '../create/type' import { IsUndefined } from '../guard/value' import { Kind, Hint } from '../symbols/index' import { Static } from '../static/index' // ------------------------------------------------------------------ // TThis // ------------------------------------------------------------------ export interface TThis extends TSchema { [Kind]: 'This' static: this['params'][0] $ref: string } // ------------------------------------------------------------------ // RecursiveStatic // ------------------------------------------------------------------ type RecursiveStatic = Static]> // ------------------------------------------------------------------ // TRecursive // ------------------------------------------------------------------ export interface TRecursive extends TSchema { [Hint]: 'Recursive' static: RecursiveStatic } // Auto Tracked For Recursive Types without ID's let Ordinal = 0 /** `[Json]` Creates a Recursive type */ export function Recursive(callback: (thisType: TThis) => T, options: SchemaOptions = {}): TRecursive { if (IsUndefined(options.$id)) (options as any).$id = `T${Ordinal++}` const thisType = CloneType(callback({ [Kind]: 'This', $ref: `${options.$id}` } as any)) thisType.$id = options.$id // prettier-ignore return CreateType({ [Hint]: 'Recursive', ...thisType }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/ref/000077500000000000000000000000001505437577000206045ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/ref/index.ts000066400000000000000000000024611505437577000222660ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './ref' sinclairzx81-typebox-e0ec98c/src/type/ref/ref.ts000066400000000000000000000063601505437577000217350ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import { TypeBoxError } from '../error/index' import { CreateType } from '../create/type' import { Kind } from '../symbols/index' import { TUnsafe } from '../unsafe/index' import { Static } from '../static/index' // ------------------------------------------------------------------ // TRef // ------------------------------------------------------------------ export interface TRef extends TSchema { [Kind]: 'Ref' static: unknown $ref: Ref } export type TRefUnsafe = TUnsafe> /** `[Json]` Creates a Ref type.*/ export function Ref($ref: Ref, options?: SchemaOptions): TRef /** * @deprecated `[Json]` Creates a Ref type. This signature was deprecated in 0.34.0 where Ref requires callers to pass * a `string` value for the reference (and not a schema). * * To adhere to the 0.34.0 signature, Ref implementations should be updated to the following. * * ```typescript * // pre-0.34.0 * * const T = Type.String({ $id: 'T' }) * * const R = Type.Ref(T) * ``` * should be changed to the following * * ```typescript * // post-0.34.0 * * const T = Type.String({ $id: 'T' }) * * const R = Type.Unsafe>(Type.Ref('T')) * ``` * You can also create a generic function to replicate the pre-0.34.0 signature if required * * ```typescript * const LegacyRef = (schema: T) => Type.Unsafe>(Type.Ref(schema.$id!)) * ``` */ export function Ref(type: Type, options?: SchemaOptions): TRefUnsafe /** `[Json]` Creates a Ref type. The referenced type must contain a $id */ export function Ref(...args: any[]): unknown { const [$ref, options] = typeof args[0] === 'string' ? [args[0], args[1]] : [args[0].$id, args[1]] if (typeof $ref !== 'string') throw new TypeBoxError('Ref: $ref must be a string') return CreateType({ [Kind]: 'Ref', $ref }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/regexp/000077500000000000000000000000001505437577000213225ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/regexp/index.ts000066400000000000000000000024641505437577000230070ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './regexp' sinclairzx81-typebox-e0ec98c/src/type/regexp/regexp.ts000066400000000000000000000045561505437577000231760ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { SchemaOptions } from '../schema/index' import type { TSchema } from '../schema/index' import { IsString } from '../guard/value' import { Kind } from '../symbols/index' export interface RegExpOptions extends SchemaOptions { /** The maximum length of the string */ maxLength?: number /** The minimum length of the string */ minLength?: number } export interface TRegExp extends TSchema { [Kind]: 'RegExp' static: `${string}` type: 'RegExp' source: string flags: string } /** `[JavaScript]` Creates a RegExp type */ export function RegExp(pattern: string, options?: RegExpOptions): TRegExp /** `[JavaScript]` Creates a RegExp type */ export function RegExp(regex: RegExp, options?: RegExpOptions): TRegExp /** `[JavaScript]` Creates a RegExp type */ export function RegExp(unresolved: RegExp | string, options?: RegExpOptions) { const expr = IsString(unresolved) ? new globalThis.RegExp(unresolved) : unresolved return CreateType({ [Kind]: 'RegExp', type: 'RegExp', source: expr.source, flags: expr.flags }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/registry/000077500000000000000000000000001505437577000217005ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/registry/format.ts000066400000000000000000000042551505437577000235460ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export type FormatRegistryValidationFunction = (value: string) => boolean /** A registry for user defined string formats */ const map = new Map() /** Returns the entries in this registry */ export function Entries() { return new Map(map) } /** Clears all user defined string formats */ export function Clear() { return map.clear() } /** Deletes a registered format */ export function Delete(format: string) { return map.delete(format) } /** Returns true if the user defined string format exists */ export function Has(format: string) { return map.has(format) } /** Sets a validation function for a user defined string format */ export function Set(format: string, func: FormatRegistryValidationFunction) { map.set(format, func) } /** Gets a validation function for a user defined string format */ export function Get(format: string) { return map.get(format) } sinclairzx81-typebox-e0ec98c/src/type/registry/index.ts000066400000000000000000000025551505437577000233660ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * as FormatRegistry from './format' export * as TypeRegistry from './type' sinclairzx81-typebox-e0ec98c/src/type/registry/type.ts000066400000000000000000000042601505437577000232330ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export type TypeRegistryValidationFunction = (schema: TSchema, value: unknown) => boolean /** A registry for user defined types */ const map = new Map>() /** Returns the entries in this registry */ export function Entries() { return new Map(map) } /** Clears all user defined types */ export function Clear() { return map.clear() } /** Deletes a registered type */ export function Delete(kind: string) { return map.delete(kind) } /** Returns true if this registry contains this kind */ export function Has(kind: string) { return map.has(kind) } /** Sets a validation function for a user defined type */ export function Set(kind: string, func: TypeRegistryValidationFunction) { map.set(kind, func) } /** Gets a custom validation function for a user defined type */ export function Get(kind: string) { return map.get(kind) } sinclairzx81-typebox-e0ec98c/src/type/required/000077500000000000000000000000001505437577000216505ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/required/index.ts000066400000000000000000000025441505437577000233340ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './required-from-mapped-result' export * from './required' sinclairzx81-typebox-e0ec98c/src/type/required/required-from-mapped-result.ts000066400000000000000000000062101505437577000275600ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { SchemaOptions } from '../schema/index' import type { Ensure, Evaluate } from '../helpers/index' import type { TProperties } from '../object/index' import { MappedResult, type TMappedResult } from '../mapped/index' import { Required, type TRequired } from './required' // ------------------------------------------------------------------ // FromProperties // ------------------------------------------------------------------ // prettier-ignore type TFromProperties< P extends TProperties > = ( { [K2 in keyof P]: TRequired } ) // prettier-ignore function FromProperties< P extends TProperties >(P: P, options?: SchemaOptions): TFromProperties

{ const Acc = {} as TProperties for(const K2 of globalThis.Object.getOwnPropertyNames(P)) Acc[K2] = Required(P[K2], options) return Acc as never } // ------------------------------------------------------------------ // FromMappedResult // ------------------------------------------------------------------ // prettier-ignore type TFromMappedResult< R extends TMappedResult > = ( Evaluate> ) // prettier-ignore function FromMappedResult< R extends TMappedResult >(R: R, options?: SchemaOptions): TFromMappedResult { return FromProperties(R.properties, options) as never } // ------------------------------------------------------------------ // TRequiredFromMappedResult // ------------------------------------------------------------------ // prettier-ignore export type TRequiredFromMappedResult< R extends TMappedResult, P extends TProperties = TFromMappedResult > = ( Ensure> ) // prettier-ignore export function RequiredFromMappedResult< R extends TMappedResult, P extends TProperties = TFromMappedResult >(R: R, options?: SchemaOptions): TMappedResult

{ const P = FromMappedResult(R, options) return MappedResult(P) as never } sinclairzx81-typebox-e0ec98c/src/type/required/required.ts000066400000000000000000000207731505437577000240510ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import type { Evaluate, Ensure } from '../helpers/index' import type { TMappedResult } from '../mapped/index' import { type TReadonlyOptional } from '../readonly-optional/index' import { type TComputed, Computed } from '../computed/index' import { type TOptional } from '../optional/index' import { type TReadonly } from '../readonly/index' import { type TRecursive } from '../recursive/index' import { type TObject, type TProperties, Object } from '../object/index' import { type TIntersect, Intersect } from '../intersect/index' import { type TUnion, Union } from '../union/index' import { type TRef, Ref } from '../ref/index' import { type TBigInt } from '../bigint/index' import { type TBoolean } from '../boolean/index' import { type TInteger } from '../integer/index' import { type TLiteral } from '../literal/index' import { type TNull } from '../null/index' import { type TNumber } from '../number/index' import { type TString } from '../string/index' import { type TSymbol } from '../symbol/index' import { type TUndefined } from '../undefined/index' import { OptionalKind, TransformKind } from '../symbols/index' import { Discard } from '../discard/index' import { RequiredFromMappedResult, type TRequiredFromMappedResult } from './required-from-mapped-result' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import * as KindGuard from '../guard/kind' // ------------------------------------------------------------------ // FromComputed // ------------------------------------------------------------------ // prettier-ignore type TFromComputed = Ensure< TComputed<'Required', [TComputed]> > // prettier-ignore function FromComputed(target: Target, parameters: Parameters): TFromComputed { return Computed('Required', [Computed(target, parameters)]) as never } // ------------------------------------------------------------------ // FromRef // ------------------------------------------------------------------ // prettier-ignore type TFromRef = Ensure< TComputed<'Required', [TRef]> > // prettier-ignore function FromRef($ref: Ref): TFromRef { return Computed('Required', [Ref($ref)]) as never } // ------------------------------------------------------------------ // FromProperties // ------------------------------------------------------------------ // prettier-ignore type TFromProperties = Evaluate<{ [K in keyof Properties]: Properties[K] extends (TReadonlyOptional) ? TReadonly : Properties[K] extends (TReadonly) ? TReadonly : Properties[K] extends (TOptional) ? S : Properties[K] }> // prettier-ignore function FromProperties(properties: Properties) { const requiredProperties = {} as TProperties for(const K of globalThis.Object.getOwnPropertyNames(properties)) requiredProperties[K] = Discard(properties[K], [OptionalKind]) as TSchema return requiredProperties as never } // ------------------------------------------------------------------ // FromObject // ------------------------------------------------------------------ // prettier-ignore type TFromObject = Ensure )>> // prettier-ignore function FromObject(type: Type): TFromObject { const options = Discard(type, [TransformKind, '$id', 'required', 'properties']) const properties = FromProperties(type['properties']) return Object(properties, options) as never } // ------------------------------------------------------------------ // FromRest // ------------------------------------------------------------------ // prettier-ignore type TFromRest = ( Types extends [infer L extends TSchema, ...infer R extends TSchema[]] ? TFromRest]> : Result ) // prettier-ignore function FromRest(types: [...Types]) : TFromRest { return types.map(type => RequiredResolve(type)) as never } // ------------------------------------------------------------------ // RequiredResolve // ------------------------------------------------------------------ // prettier-ignore function RequiredResolve(type: Type): TRequired { return ( // Mappable KindGuard.IsComputed(type) ? FromComputed(type.target, type.parameters) : KindGuard.IsRef(type) ? FromRef(type.$ref) : KindGuard.IsIntersect(type) ? Intersect(FromRest(type.allOf)) : KindGuard.IsUnion(type) ? Union(FromRest(type.anyOf)) : KindGuard.IsObject(type) ? FromObject(type) : // Intrinsic KindGuard.IsBigInt(type) ? type : KindGuard.IsBoolean(type) ? type : KindGuard.IsInteger(type) ? type : KindGuard.IsLiteral(type) ? type : KindGuard.IsNull(type) ? type : KindGuard.IsNumber(type) ? type : KindGuard.IsString(type) ? type : KindGuard.IsSymbol(type) ? type : KindGuard.IsUndefined(type) ? type : // Passthrough Object({}) ) as never } // ------------------------------------------------------------------ // TRequired // ------------------------------------------------------------------ // prettier-ignore export type TRequired = ( // Mappable Type extends TRecursive ? TRecursive> : Type extends TComputed ? TFromComputed : Type extends TRef ? TFromRef : Type extends TIntersect ? TIntersect> : Type extends TUnion ? TUnion> : Type extends TObject ? TFromObject> : // Intrinsic Type extends TBigInt ? Type : Type extends TBoolean ? Type : Type extends TInteger ? Type : Type extends TLiteral ? Type : Type extends TNull ? Type : Type extends TNumber ? Type : Type extends TString ? Type : Type extends TSymbol ? Type : Type extends TUndefined ? Type : // Passthrough TObject<{}> ) /** `[Json]` Constructs a type where all properties are required */ export function Required(type: MappedResult, options?: SchemaOptions): TRequiredFromMappedResult /** `[Json]` Constructs a type where all properties are required */ export function Required(type: Type, options?: SchemaOptions): TRequired /** `[Json]` Constructs a type where all properties are required */ export function Required(type: Type, options?: SchemaOptions): never { if (KindGuard.IsMappedResult(type)) { return RequiredFromMappedResult(type, options) as never } else { // special: mapping types require overridable options return CreateType({ ...RequiredResolve(type), ...options }) as never } } sinclairzx81-typebox-e0ec98c/src/type/rest/000077500000000000000000000000001505437577000210055ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/rest/index.ts000066400000000000000000000024621505437577000224700ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './rest' sinclairzx81-typebox-e0ec98c/src/type/rest/rest.ts000066400000000000000000000051501505437577000223330ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema } from '../schema/index' import type { TIntersect } from '../intersect/index' import type { TUnion } from '../union/index' import type { TTuple } from '../tuple/index' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsIntersect, IsUnion, IsTuple } from '../guard/kind' // ------------------------------------------------------------------ // RestResolve // ------------------------------------------------------------------ // prettier-ignore type TRestResolve = T extends TIntersect ? S : T extends TUnion ? S : T extends TTuple ? S : [] // prettier-ignore function RestResolve(T: T) { return ( IsIntersect(T) ? T.allOf : IsUnion(T) ? T.anyOf : IsTuple(T) ? T.items ?? [] : [] ) as never } // ------------------------------------------------------------------ // TRest // ------------------------------------------------------------------ export type TRest = TRestResolve /** `[Json]` Extracts interior Rest elements from Tuple, Intersect and Union types */ export function Rest(T: T): TRest { return RestResolve(T) } sinclairzx81-typebox-e0ec98c/src/type/return-type/000077500000000000000000000000001505437577000223265ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/return-type/index.ts000066400000000000000000000024711505437577000240110ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './return-type' sinclairzx81-typebox-e0ec98c/src/type/return-type/return-type.ts000066400000000000000000000040431505437577000251750ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import { type TSchema, type SchemaOptions } from '../schema/index' import { type TFunction } from '../function/index' import { type TNever, Never } from '../never/index' import * as KindGuard from '../guard/kind' // prettier-ignore export type TReturnType ? ReturnType : TNever > = Result /** `[JavaScript]` Extracts the ReturnType from the given Function type */ export function ReturnType(schema: Type, options?: SchemaOptions): TReturnType { return (KindGuard.IsFunction(schema) ? CreateType(schema.returns, options) : Never(options)) as never } sinclairzx81-typebox-e0ec98c/src/type/schema/000077500000000000000000000000001505437577000212705ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/schema/anyschema.ts000066400000000000000000000065471505437577000236240ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ // ------------------------------------------------------------------ // Type: Module // ------------------------------------------------------------------ import type { TAny } from '../any/index' import type { TArray } from '../array/index' import type { TAsyncIterator } from '../async-iterator/index' import type { TBigInt } from '../bigint/index' import type { TBoolean } from '../boolean/index' import type { TConstructor } from '../constructor/index' import type { TDate } from '../date/index' import type { TEnum } from '../enum/index' import type { TFunction } from '../function/index' import type { TInteger } from '../integer/index' import type { TIntersect } from '../intersect/index' import type { TIterator } from '../iterator/index' import type { TLiteral } from '../literal/index' import type { TNot } from '../not/index' import type { TNull } from '../null/index' import type { TNumber } from '../number/index' import type { TObject } from '../object/index' import type { TPromise } from '../promise/index' import type { TRecord } from '../record/index' import type { TThis } from '../recursive/index' import type { TRef } from '../ref/index' import type { TRegExp } from '../regexp/index' import type { TString } from '../string/index' import type { TSymbol } from '../symbol/index' import type { TTemplateLiteral } from '../template-literal/index' import type { TTuple } from '../tuple/index' import type { TUint8Array } from '../uint8array/index' import type { TUndefined } from '../undefined/index' import type { TUnion } from '../union/index' import type { TUnknown } from '../unknown/index' import type { TVoid } from '../void/index' import type { TSchema } from './schema' export type TAnySchema = | TSchema | TAny | TArray | TAsyncIterator | TBigInt | TBoolean | TConstructor | TDate | TEnum | TFunction | TInteger | TIntersect | TIterator | TLiteral | TNot | TNull | TNumber | TObject | TPromise | TRecord | TRef | TRegExp | TString | TSymbol | TTemplateLiteral | TThis | TTuple | TUndefined | TUnion | TUint8Array | TUnknown | TVoid sinclairzx81-typebox-e0ec98c/src/type/schema/index.ts000066400000000000000000000025201505437577000227460ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './anyschema' export * from './schema' sinclairzx81-typebox-e0ec98c/src/type/schema/schema.ts000066400000000000000000000040161505437577000231010ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { Kind, Hint, ReadonlyKind, OptionalKind } from '../symbols/index' export interface SchemaOptions { $schema?: string /** Id for this schema */ $id?: string /** Title of this schema */ title?: string /** Description of this schema */ description?: string /** Default value for this schema */ default?: any /** Example values matching this schema */ examples?: any /** Optional annotation for readOnly */ readOnly?: boolean /** Optional annotation for writeOnly */ writeOnly?: boolean [prop: string]: any } export interface TKind { [Kind]: string } export interface TSchema extends TKind, SchemaOptions { [ReadonlyKind]?: string [OptionalKind]?: string [Hint]?: string params: unknown[] static: unknown } sinclairzx81-typebox-e0ec98c/src/type/sets/000077500000000000000000000000001505437577000210065ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/sets/index.ts000066400000000000000000000024611505437577000224700ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './set' sinclairzx81-typebox-e0ec98c/src/type/sets/set.ts000066400000000000000000000156531505437577000221630ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ // ------------------------------------------------------------------ // SetIncludes // ------------------------------------------------------------------ // prettier-ignore export type TSetIncludes = ( T extends [infer L extends PropertyKey, ...infer R extends PropertyKey[]] ? S extends L ? true : TSetIncludes : false ) /** Returns true if element right is in the set of left */ // prettier-ignore export function SetIncludes(T: [...T], S: S): TSetIncludes { return T.includes(S) as never } // ------------------------------------------------------------------ // SetIsSubset // ------------------------------------------------------------------ // prettier-ignore export type TSetIsSubset = ( T extends [infer L extends PropertyKey, ...infer R extends PropertyKey[]] ? TSetIncludes extends true ? TSetIsSubset : false : true ) /** Returns true if left is a subset of right */ export function SetIsSubset(T: [...T], S: [...S]): TSetIsSubset { return T.every((L) => SetIncludes(S, L)) as never } // ------------------------------------------------------------------ // SetDistinct // ------------------------------------------------------------------ // prettier-ignore export type TSetDistinct = T extends [infer L extends PropertyKey, ...infer R extends PropertyKey[]] ? TSetIncludes extends false ? TSetDistinct : TSetDistinct : Acc /** Returns a distinct set of elements */ export function SetDistinct(T: [...T]): TSetDistinct { return [...new Set(T)] as never } // ------------------------------------------------------------------ // SetIntersect // ------------------------------------------------------------------ // prettier-ignore export type TSetIntersect = ( T extends [infer L extends PropertyKey, ...infer R extends PropertyKey[]] ? TSetIncludes extends true ? TSetIntersect : TSetIntersect : Acc ) /** Returns the Intersect of the given sets */ export function SetIntersect(T: [...T], S: [...S]): TSetIntersect { return T.filter((L) => S.includes(L)) as never } // ------------------------------------------------------------------ // SetUnion // ------------------------------------------------------------------ // prettier-ignore export type TSetUnion = ( [...T, ...S] ) /** Returns the Union of the given sets */ export function SetUnion(T: [...T], S: [...S]): TSetUnion { return [...T, ...S] } // ------------------------------------------------------------------ // SetComplement // ------------------------------------------------------------------ // prettier-ignore export type TSetComplement = ( T extends [infer L extends PropertyKey, ...infer R extends PropertyKey[]] ? TSetIncludes extends true ? TSetComplement : TSetComplement : Acc ) /** Returns the Complement by omitting elements in T that are in S */ // prettier-ignore export function SetComplement(T: [...T], S: [...S]): TSetComplement { return T.filter(L => !S.includes(L)) as never } // ------------------------------------------------------------------ // SetIntersectMany // ------------------------------------------------------------------ // prettier-ignore type TSetIntersectManyResolve = ( T extends [infer L extends PropertyKey[], ...infer R extends PropertyKey[][]] ? TSetIntersectManyResolve> : Acc ) // prettier-ignore function SetIntersectManyResolve(T: [...T], Init: Acc): TSetIntersectManyResolve { return T.reduce((Acc: PropertyKey[], L: PropertyKey[]) => { return SetIntersect(Acc, L) }, Init) as never } // prettier-ignore export type TSetIntersectMany = ( T extends [infer L extends PropertyKey[]] ? L // Use left to initialize the accumulator for resolve : T extends [infer L extends PropertyKey[], ...infer R extends PropertyKey[][]] ? TSetIntersectManyResolve : [] ) // prettier-ignore export function SetIntersectMany(T: [...T]): TSetIntersectMany { return ( T.length === 1 ? T[0] // Use left to initialize the accumulator for resolve : T.length > 1 ? SetIntersectManyResolve(T.slice(1), T[0]) : [] ) as never } // ------------------------------------------------------------------ // SetUnionMany // ------------------------------------------------------------------ // prettier-ignore export type TSetUnionMany = ( T extends [infer L extends PropertyKey[], ...infer R extends PropertyKey[][]] ? TSetUnionMany> : Acc ) /** Returns the Union of multiple sets */ export function SetUnionMany(T: [...T]): TSetUnionMany { const Acc = [] as PropertyKey[] for (const L of T) Acc.push(...L) return Acc as never } sinclairzx81-typebox-e0ec98c/src/type/static/000077500000000000000000000000001505437577000213175ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/static/index.ts000066400000000000000000000024641505437577000230040ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './static' sinclairzx81-typebox-e0ec98c/src/type/static/static.ts000066400000000000000000000147251505437577000231670ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { Evaluate } from '../helpers/index' import type { TOptional } from '../optional/index' import type { TReadonly } from '../readonly/index' import type { TArray } from '../array/index' import type { TAsyncIterator } from '../async-iterator/index' import type { TConstructor } from '../constructor/index' import type { TEnum } from '../enum/index' import type { TFunction } from '../function/index' import type { TIntersect } from '../intersect/index' import type { TImport } from '../module/index' import type { TIterator } from '../iterator/index' import type { TNot } from '../not/index' import type { TObject, TProperties } from '../object/index' import type { TPromise } from '../promise/index' import type { TRecursive } from '../recursive/index' import type { TRecord } from '../record/index' import type { TRef } from '../ref/index' import type { TTuple } from '../tuple/index' import type { TUnion } from '../union/index' import type { TUnsafe } from '../unsafe/index' import type { TSchema } from '../schema/index' import type { TTransform } from '../transform/index' import type { TNever } from '../never/index' // ------------------------------------------------------------------ // Import // ------------------------------------------------------------------ // prettier-ignore type TDecodeImport = ( Key extends keyof ModuleProperties ? TDecodeType extends infer Type extends TSchema ? Type extends TRef ? TDecodeImport : Type : TNever : TNever ) // ------------------------------------------------------------------ // Properties // ------------------------------------------------------------------ // prettier-ignore type TDecodeProperties = { [Key in keyof Properties]: TDecodeType } // ------------------------------------------------------------------ // Types // ------------------------------------------------------------------ // prettier-ignore type TDecodeTypes = ( Types extends [infer Left extends TSchema, ...infer Right extends TSchema[]] ? TDecodeTypes]> : Result ) // ------------------------------------------------------------------ // Types // ------------------------------------------------------------------ // prettier-ignore export type TDecodeType = ( Type extends TOptional ? TOptional> : Type extends TReadonly ? TReadonly> : Type extends TTransform ? TUnsafe : Type extends TArray ? TArray> : Type extends TAsyncIterator ? TAsyncIterator> : Type extends TConstructor ? TConstructor, TDecodeType> : Type extends TEnum ? TEnum : // intercept for union. interior non decodable Type extends TFunction ? TFunction, TDecodeType> : Type extends TIntersect ? TIntersect> : Type extends TImport ? TDecodeImport : Type extends TIterator ? TIterator> : Type extends TNot ? TNot> : Type extends TObject ? TObject>> : Type extends TPromise ? TPromise> : Type extends TRecord ? TRecord> : Type extends TRecursive ? TRecursive> : Type extends TRef ? TRef : Type extends TTuple ? TTuple> : Type extends TUnion ? TUnion> : Type ) // ------------------------------------------------------------------ // Static // ------------------------------------------------------------------ export type StaticDecodeIsAny = boolean extends (Type extends TSchema ? true : false) ? true : false /** Creates an decoded static type from a TypeBox type */ // prettier-ignore export type StaticDecode extends true ? unknown : Static, Params> > = Result /** Creates an encoded static type from a TypeBox type */ export type StaticEncode> = Result /** Creates a static type from a TypeBox type */ export type Static = Result sinclairzx81-typebox-e0ec98c/src/type/string/000077500000000000000000000000001505437577000213365ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/string/index.ts000066400000000000000000000024641505437577000230230ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './string' sinclairzx81-typebox-e0ec98c/src/type/string/string.ts000066400000000000000000000054471505437577000232260ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import { TSchema, SchemaOptions } from '../schema/index' import { Kind } from '../symbols/index' // ------------------------------------------------------------------ // TString // ------------------------------------------------------------------ export type StringFormatOption = | 'date-time' | 'time' | 'date' | 'email' | 'idn-email' | 'hostname' | 'idn-hostname' | 'ipv4' | 'ipv6' | 'uri' | 'uri-reference' | 'iri' | 'uuid' | 'iri-reference' | 'uri-template' | 'json-pointer' | 'relative-json-pointer' | 'regex' | ({} & string) // prettier-ignore export type StringContentEncodingOption = | '7bit' | '8bit' | 'binary' | 'quoted-printable' | 'base64' | ({} & string) export interface StringOptions extends SchemaOptions { /** The maximum string length */ maxLength?: number /** The minimum string length */ minLength?: number /** A regular expression pattern this string should match */ pattern?: string /** A format this string should match */ format?: StringFormatOption /** The content encoding for this string */ contentEncoding?: StringContentEncodingOption /** The content media type for this string */ contentMediaType?: string } export interface TString extends TSchema, StringOptions { [Kind]: 'String' static: string type: 'string' } /** `[Json]` Creates a String type */ export function String(options?: StringOptions): TString { return CreateType({ [Kind]: 'String', type: 'string' }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/symbol/000077500000000000000000000000001505437577000213355ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/symbol/index.ts000066400000000000000000000024641505437577000230220ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './symbol' sinclairzx81-typebox-e0ec98c/src/type/symbol/symbol.ts000066400000000000000000000034061505437577000232150ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import { TSchema, SchemaOptions } from '../schema/index' import { Kind } from '../symbols/index' export type TSymbolValue = string | number | undefined export interface TSymbol extends TSchema, SchemaOptions { [Kind]: 'Symbol' static: symbol type: 'symbol' } /** `[JavaScript]` Creates a Symbol type */ export function Symbol(options?: SchemaOptions): TSymbol { return CreateType({ [Kind]: 'Symbol', type: 'symbol' }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/symbols/000077500000000000000000000000001505437577000215205ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/symbols/index.ts000066400000000000000000000024651505437577000232060ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './symbols' sinclairzx81-typebox-e0ec98c/src/type/symbols/symbols.ts000066400000000000000000000033671505437577000235710ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ /** Symbol key applied to transform types */ export const TransformKind = Symbol.for('TypeBox.Transform') /** Symbol key applied to readonly types */ export const ReadonlyKind = Symbol.for('TypeBox.Readonly') /** Symbol key applied to optional types */ export const OptionalKind = Symbol.for('TypeBox.Optional') /** Symbol key applied to types */ export const Hint = Symbol.for('TypeBox.Hint') /** Symbol key applied to types */ export const Kind = Symbol.for('TypeBox.Kind') sinclairzx81-typebox-e0ec98c/src/type/template-literal/000077500000000000000000000000001505437577000232755ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/template-literal/finite.ts000066400000000000000000000120551505437577000251260ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { TemplateLiteralParseExact } from './parse' import { TypeBoxError } from '../error/index' import type { TTemplateLiteral, TTemplateLiteralKind } from './index' import type { TUnion } from '../union/index' import type { TString } from '../string/index' import type { TBoolean } from '../boolean/index' import type { TNumber } from '../number/index' import type { TInteger } from '../integer/index' import type { TBigInt } from '../bigint/index' import type { TLiteral } from '../literal/index' import type { Expression } from './parse' // ------------------------------------------------------------------ // TemplateLiteralFiniteError // ------------------------------------------------------------------ export class TemplateLiteralFiniteError extends TypeBoxError {} // ------------------------------------------------------------------ // IsTemplateLiteralFiniteCheck // ------------------------------------------------------------------ // prettier-ignore function IsNumberExpression(expression: Expression): boolean { return ( expression.type === 'or' && expression.expr.length === 2 && expression.expr[0].type === 'const' && expression.expr[0].const === '0' && expression.expr[1].type === 'const' && expression.expr[1].const === '[1-9][0-9]*' ) } // prettier-ignore function IsBooleanExpression(expression: Expression): boolean { return ( expression.type === 'or' && expression.expr.length === 2 && expression.expr[0].type === 'const' && expression.expr[0].const === 'true' && expression.expr[1].type === 'const' && expression.expr[1].const === 'false' ) } // prettier-ignore function IsStringExpression(expression: Expression) { return expression.type === 'const' && expression.const === '.*' } // prettier-ignore type TFromTemplateLiteralKind = T extends TTemplateLiteral ? TFromTemplateLiteralKinds : T extends TUnion ? TFromTemplateLiteralKinds : T extends TString ? false : T extends TNumber ? false : T extends TInteger ? false : T extends TBigInt ? false : T extends TBoolean ? true : T extends TLiteral ? true : false // prettier-ignore type TFromTemplateLiteralKinds = T extends [infer L extends TTemplateLiteralKind, ...infer R extends TTemplateLiteralKind[]] ? TFromTemplateLiteralKind extends false ? false : TFromTemplateLiteralKinds : true // ------------------------------------------------------------------ // IsTemplateLiteralExpressionFinite // ------------------------------------------------------------------ // prettier-ignore export function IsTemplateLiteralExpressionFinite(expression: Expression): boolean { return ( IsNumberExpression(expression) || IsStringExpression(expression) ? false : IsBooleanExpression(expression) ? true : (expression.type === 'and') ? expression.expr.every((expr) => IsTemplateLiteralExpressionFinite(expr)) : (expression.type === 'or') ? expression.expr.every((expr) => IsTemplateLiteralExpressionFinite(expr)) : (expression.type === 'const') ? true : (() => { throw new TemplateLiteralFiniteError(`Unknown expression type`) })() ) } // ------------------------------------------------------------------ // TIsTemplateLiteralFinite // ------------------------------------------------------------------ // prettier-ignore export type TIsTemplateLiteralFinite = T extends TTemplateLiteral ? TFromTemplateLiteralKinds : false /** Returns true if this TemplateLiteral resolves to a finite set of values */ export function IsTemplateLiteralFinite(schema: T) { const expression = TemplateLiteralParseExact(schema.pattern) return IsTemplateLiteralExpressionFinite(expression) } sinclairzx81-typebox-e0ec98c/src/type/template-literal/generate.ts000066400000000000000000000156351505437577000254510ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { IsTemplateLiteralExpressionFinite, TIsTemplateLiteralFinite } from './finite' import { TemplateLiteralParseExact } from './parse' import { TypeBoxError } from '../error/index' import type { Assert } from '../helpers/index' import type { TBoolean } from '../boolean/index' import type { TTemplateLiteral, TTemplateLiteralKind } from './index' import type { TLiteral, TLiteralValue } from '../literal/index' import type { Expression, ExpressionAnd, ExpressionOr, ExpressionConst } from './parse' import type { TUnion } from '../union/index' // ------------------------------------------------------------------ // TemplateLiteralGenerateError // ------------------------------------------------------------------ export class TemplateLiteralGenerateError extends TypeBoxError {} // ------------------------------------------------------------------ // StringReducers // ------------------------------------------------------------------ // StringReduceUnary<"A", ["B", "C"]> -> ["AB", "AC"] // prettier-ignore type TStringReduceUnary = R extends [infer A extends string, ...infer B extends string[]] ? TStringReduceUnary : Acc // StringReduceBinary<['A', 'B'], ['C', 'D']> -> ["AC", "AD", "BC", "BD"] // prettier-ignore type TStringReduceBinary = L extends [infer A extends string, ...infer B extends string[]] ? TStringReduceBinary]> : Acc // StringReduceMany<[['A', 'B'], ['C', 'D'], ['E']]> -> [["ACE", "ADE", "BCE", "BDE"]] // prettier-ignore type TStringReduceMany = // consider optimizing T extends [infer L extends string[], infer R extends string[], ...infer Rest extends string[][]] ? TStringReduceMany<[TStringReduceBinary, ...Rest]> : T // Reduce<[['A', 'B'], ['C', 'D'], ['E']]> -> ["ACE", "ADE", "BCE", "BDE"] // prettier-ignore type TStringReduce> = 0 extends keyof O ? Assert : [] // ------------------------------------------------------------------ // FromTemplateLiteralUnionKinds // ------------------------------------------------------------------ // prettier-ignore type TFromTemplateLiteralUnionKinds = T extends [infer L extends TLiteral, ...infer R extends TLiteral[]] ? [`${L['const']}`, ...TFromTemplateLiteralUnionKinds] : [] // ------------------------------------------------------------------ // FromTemplateLiteralKinds // ------------------------------------------------------------------ // prettier-ignore type TFromTemplateLiteralKinds = T extends [infer L extends TTemplateLiteralKind, ...infer R extends TTemplateLiteralKind[]] ? ( L extends TTemplateLiteral ? TFromTemplateLiteralKinds<[...S, ...R], Acc> : L extends TLiteral ? TFromTemplateLiteralKinds : L extends TUnion ? TFromTemplateLiteralKinds]> : L extends TBoolean ? TFromTemplateLiteralKinds : Acc ) : Acc // ------------------------------------------------------------------ // TemplateLiteralExpressionGenerate // ------------------------------------------------------------------ // prettier-ignore function* GenerateReduce(buffer: string[][]): IterableIterator { if (buffer.length === 1) return yield* buffer[0] for (const left of buffer[0]) { for (const right of GenerateReduce(buffer.slice(1))) { yield `${left}${right}` } } } // prettier-ignore function* GenerateAnd(expression: ExpressionAnd): IterableIterator { return yield* GenerateReduce(expression.expr.map((expr) => [...TemplateLiteralExpressionGenerate(expr)])) } // prettier-ignore function* GenerateOr(expression: ExpressionOr): IterableIterator { for (const expr of expression.expr) yield* TemplateLiteralExpressionGenerate(expr) } // prettier-ignore function* GenerateConst(expression: ExpressionConst): IterableIterator { return yield expression.const } export function* TemplateLiteralExpressionGenerate(expression: Expression): IterableIterator { return expression.type === 'and' ? yield* GenerateAnd(expression) : expression.type === 'or' ? yield* GenerateOr(expression) : expression.type === 'const' ? yield* GenerateConst(expression) : (() => { throw new TemplateLiteralGenerateError('Unknown expression') })() } // ------------------------------------------------------------------ // TTemplateLiteralGenerate // ------------------------------------------------------------------ // prettier-ignore export type TTemplateLiteralGenerate> = F extends true ? ( T extends TTemplateLiteral ? TFromTemplateLiteralKinds extends infer R extends string[][] ? TStringReduce : [] : [] ) : [] /** Generates a tuple of strings from the given TemplateLiteral. Returns an empty tuple if infinite. */ export function TemplateLiteralGenerate(schema: T): TTemplateLiteralGenerate { const expression = TemplateLiteralParseExact(schema.pattern) // prettier-ignore return ( IsTemplateLiteralExpressionFinite(expression) ? [...TemplateLiteralExpressionGenerate(expression)] : [] ) as never } sinclairzx81-typebox-e0ec98c/src/type/template-literal/index.ts000066400000000000000000000027251505437577000247620ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './finite' export * from './generate' export * from './syntax' export * from './parse' export * from './pattern' export * from './union' export * from './template-literal' sinclairzx81-typebox-e0ec98c/src/type/template-literal/parse.ts000066400000000000000000000166621505437577000247720ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { TypeBoxError } from '../error/index' // ------------------------------------------------------------------ // TemplateLiteralParserError // ------------------------------------------------------------------ export class TemplateLiteralParserError extends TypeBoxError {} // ------------------------------------------------------------------ // TemplateLiteralParse // ------------------------------------------------------------------ // prettier-ignore export type Expression = ExpressionAnd | ExpressionOr | ExpressionConst export type ExpressionConst = { type: 'const'; const: string } export type ExpressionAnd = { type: 'and'; expr: Expression[] } export type ExpressionOr = { type: 'or'; expr: Expression[] } // ------------------------------------------------------------------- // Unescape // // Unescape for these control characters specifically. Note that this // function is only called on non union group content, and where we // still want to allow the user to embed control characters in that // content. For review. // ------------------------------------------------------------------- // prettier-ignore function Unescape(pattern: string) { return pattern .replace(/\\\$/g, '$') .replace(/\\\*/g, '*') .replace(/\\\^/g, '^') .replace(/\\\|/g, '|') .replace(/\\\(/g, '(') .replace(/\\\)/g, ')') } // ------------------------------------------------------------------- // Control Characters // ------------------------------------------------------------------- function IsNonEscaped(pattern: string, index: number, char: string) { return pattern[index] === char && pattern.charCodeAt(index - 1) !== 92 } function IsOpenParen(pattern: string, index: number) { return IsNonEscaped(pattern, index, '(') } function IsCloseParen(pattern: string, index: number) { return IsNonEscaped(pattern, index, ')') } function IsSeparator(pattern: string, index: number) { return IsNonEscaped(pattern, index, '|') } // ------------------------------------------------------------------- // Control Groups // ------------------------------------------------------------------- function IsGroup(pattern: string) { if (!(IsOpenParen(pattern, 0) && IsCloseParen(pattern, pattern.length - 1))) return false let count = 0 for (let index = 0; index < pattern.length; index++) { if (IsOpenParen(pattern, index)) count += 1 if (IsCloseParen(pattern, index)) count -= 1 if (count === 0 && index !== pattern.length - 1) return false } return true } // prettier-ignore function InGroup(pattern: string) { return pattern.slice(1, pattern.length - 1) } // prettier-ignore function IsPrecedenceOr(pattern: string) { let count = 0 for (let index = 0; index < pattern.length; index++) { if (IsOpenParen(pattern, index)) count += 1 if (IsCloseParen(pattern, index)) count -= 1 if (IsSeparator(pattern, index) && count === 0) return true } return false } // prettier-ignore function IsPrecedenceAnd(pattern: string) { for (let index = 0; index < pattern.length; index++) { if (IsOpenParen(pattern, index)) return true } return false } // prettier-ignore function Or(pattern: string): Expression { let [count, start] = [0, 0] const expressions: Expression[] = [] for (let index = 0; index < pattern.length; index++) { if (IsOpenParen(pattern, index)) count += 1 if (IsCloseParen(pattern, index)) count -= 1 if (IsSeparator(pattern, index) && count === 0) { const range = pattern.slice(start, index) if (range.length > 0) expressions.push(TemplateLiteralParse(range)) start = index + 1 } } const range = pattern.slice(start) if (range.length > 0) expressions.push(TemplateLiteralParse(range)) if (expressions.length === 0) return { type: 'const', const: '' } if (expressions.length === 1) return expressions[0] return { type: 'or', expr: expressions } } // prettier-ignore function And(pattern: string): Expression { function Group(value: string, index: number): [number, number] { if (!IsOpenParen(value, index)) throw new TemplateLiteralParserError(`TemplateLiteralParser: Index must point to open parens`) let count = 0 for (let scan = index; scan < value.length; scan++) { if (IsOpenParen(value, scan)) count += 1 if (IsCloseParen(value, scan)) count -= 1 if (count === 0) return [index, scan] } throw new TemplateLiteralParserError(`TemplateLiteralParser: Unclosed group parens in expression`) } function Range(pattern: string, index: number): [number, number] { for (let scan = index; scan < pattern.length; scan++) { if (IsOpenParen(pattern, scan)) return [index, scan] } return [index, pattern.length] } const expressions: Expression[] = [] for (let index = 0; index < pattern.length; index++) { if (IsOpenParen(pattern, index)) { const [start, end] = Group(pattern, index) const range = pattern.slice(start, end + 1) expressions.push(TemplateLiteralParse(range)) index = end } else { const [start, end] = Range(pattern, index) const range = pattern.slice(start, end) if (range.length > 0) expressions.push(TemplateLiteralParse(range)) index = end - 1 } } return ( (expressions.length === 0) ? { type: 'const', const: '' } : (expressions.length === 1) ? expressions[0] : { type: 'and', expr: expressions } ) } // ------------------------------------------------------------------ // TemplateLiteralParse // ------------------------------------------------------------------ /** Parses a pattern and returns an expression tree */ export function TemplateLiteralParse(pattern: string): Expression { // prettier-ignore return ( IsGroup(pattern) ? TemplateLiteralParse(InGroup(pattern)) : IsPrecedenceOr(pattern) ? Or(pattern) : IsPrecedenceAnd(pattern) ? And(pattern) : { type: 'const', const: Unescape(pattern) } ) } // ------------------------------------------------------------------ // TemplateLiteralParseExact // ------------------------------------------------------------------ /** Parses a pattern and strips forward and trailing ^ and $ */ export function TemplateLiteralParseExact(pattern: string): Expression { return TemplateLiteralParse(pattern.slice(1, pattern.length - 1)) } sinclairzx81-typebox-e0ec98c/src/type/template-literal/pattern.ts000066400000000000000000000061541505437577000253300ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema } from '../schema/index' import type { TTemplateLiteralKind } from './index' import { PatternNumber, PatternString, PatternBoolean } from '../patterns/index' import { Kind } from '../symbols/index' import { TypeBoxError } from '../error/index' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsTemplateLiteral, IsUnion, IsNumber, IsInteger, IsBigInt, IsString, IsLiteral, IsBoolean } from '../guard/kind' // ------------------------------------------------------------------ // TemplateLiteralPatternError // ------------------------------------------------------------------ export class TemplateLiteralPatternError extends TypeBoxError {} // ------------------------------------------------------------------ // TemplateLiteralPattern // ------------------------------------------------------------------ function Escape(value: string) { return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') } // prettier-ignore function Visit(schema: TSchema, acc: string): string { return ( IsTemplateLiteral(schema) ? schema.pattern.slice(1, schema.pattern.length - 1) : IsUnion(schema) ? `(${schema.anyOf.map((schema) => Visit(schema, acc)).join('|')})` : IsNumber(schema) ? `${acc}${PatternNumber}` : IsInteger(schema) ? `${acc}${PatternNumber}` : IsBigInt(schema) ? `${acc}${PatternNumber}` : IsString(schema) ? `${acc}${PatternString}` : IsLiteral(schema) ? `${acc}${Escape(schema.const.toString())}` : IsBoolean(schema) ? `${acc}${PatternBoolean}` : (() => { throw new TemplateLiteralPatternError(`Unexpected Kind '${schema[Kind]}'`) })() ) } export function TemplateLiteralPattern(kinds: TTemplateLiteralKind[]): string { return `^${kinds.map((schema) => Visit(schema, '')).join('')}\$` } sinclairzx81-typebox-e0ec98c/src/type/template-literal/syntax.ts000066400000000000000000000113741505437577000252010ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { Assert, Trim } from '../helpers/index' import type { TTemplateLiteral, TTemplateLiteralKind } from './index' import { Literal, type TLiteral } from '../literal/index' import { Boolean, type TBoolean } from '../boolean/index' import { BigInt, type TBigInt } from '../bigint/index' import { Number, type TNumber } from '../number/index' import { String, type TString } from '../string/index' import { UnionEvaluated, type TUnionEvaluated } from '../union/index' import { Never } from '../never/index' // ------------------------------------------------------------------ // SyntaxParsers // ------------------------------------------------------------------ // prettier-ignore function* FromUnion(syntax: string): IterableIterator { const trim = syntax.trim().replace(/"|'/g, '') return ( trim === 'boolean' ? yield Boolean() : trim === 'number' ? yield Number() : trim === 'bigint' ? yield BigInt() : trim === 'string' ? yield String() : yield (() => { const literals = trim.split('|').map((literal) => Literal(literal.trim())) return ( literals.length === 0 ? Never() : literals.length === 1 ? literals[0] : UnionEvaluated(literals) ) })() ) } // prettier-ignore function* FromTerminal(syntax: string): IterableIterator { if (syntax[1] !== '{') { const L = Literal('$') const R = FromSyntax(syntax.slice(1)) return yield* [L, ...R] } for (let i = 2; i < syntax.length; i++) { if (syntax[i] === '}') { const L = FromUnion(syntax.slice(2, i)) const R = FromSyntax(syntax.slice(i + 1)) return yield* [...L, ...R] } } yield Literal(syntax) } // prettier-ignore function* FromSyntax(syntax: string): IterableIterator { for (let i = 0; i < syntax.length; i++) { if (syntax[i] === '$') { const L = Literal(syntax.slice(0, i)) const R = FromTerminal(syntax.slice(i)) return yield* [L, ...R] } } yield Literal(syntax) } // prettier-ignore type FromUnionLiteral = T extends `${infer L}|${infer R}` ? [TLiteral>, ...FromUnionLiteral] : T extends `${infer L}` ? [TLiteral>] : [] type FromUnion = TUnionEvaluated> // prettier-ignore type FromTerminal = T extends 'boolean' ? TBoolean : T extends 'bigint' ? TBigInt : T extends 'number' ? TNumber : T extends 'string' ? TString : FromUnion // prettier-ignore type FromString = T extends `{${infer L}}${infer R}` ? [FromTerminal, ...FromString] : // note: to correctly handle $ characters encoded in the sequence, we need to // lookahead and test against opening and closing union groups. T extends `${infer L}$\{${infer R1}\}${infer R2}` ? [TLiteral, ...FromString<`{${R1}}`>, ...FromString] : T extends `${infer L}$\{${infer R1}\}` ? [TLiteral, ...FromString<`{${R1}}`>] : T extends `${infer L}` ? [TLiteral] : [] // ------------------------------------------------------------------ // TTemplateLiteralSyntax // ------------------------------------------------------------------ // prettier-ignore export type TTemplateLiteralSyntax = ( TTemplateLiteral, TTemplateLiteralKind[]>> ) /** Parses TemplateLiteralSyntax and returns a tuple of TemplateLiteralKinds */ export function TemplateLiteralSyntax(syntax: string): TTemplateLiteralKind[] { return [...FromSyntax(syntax)] } sinclairzx81-typebox-e0ec98c/src/type/template-literal/template-literal.ts000066400000000000000000000112221505437577000271100ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import type { Assert } from '../helpers/index' import type { TUnion } from '../union/index' import type { TLiteral } from '../literal/index' import type { TInteger } from '../integer/index' import type { TNumber } from '../number/index' import type { TBigInt } from '../bigint/index' import type { TString } from '../string/index' import type { TBoolean } from '../boolean/index' import type { TNever } from '../never/index' import type { Static } from '../static/index' import { TemplateLiteralSyntax, type TTemplateLiteralSyntax } from './syntax' import { TemplateLiteralPattern } from './pattern' import { EmptyString } from '../helpers/index' import { IsString } from '../guard/value' import { Kind } from '../symbols/index' // ------------------------------------------------------------------ // TemplateLiteralStaticKind // ------------------------------------------------------------------ // prettier-ignore type TemplateLiteralStaticKind = T extends TUnion ? { [K in keyof U]: TemplateLiteralStatic, Acc> }[number] : T extends TTemplateLiteral ? `${Static}` : T extends TLiteral ? `${U}` : T extends TString ? `${string}` : T extends TNumber ? `${number}` : T extends TBigInt ? `${bigint}` : T extends TBoolean ? `${boolean}` : never // ------------------------------------------------------------------ // TemplateLiteralStatic // ------------------------------------------------------------------ // prettier-ignore type TemplateLiteralStatic = T extends [infer L, ...infer R] ? `${TemplateLiteralStaticKind}${TemplateLiteralStatic, Acc>}` : Acc // ------------------------------------------------------------------ // TTemplateLiteralKind // ------------------------------------------------------------------ // prettier-ignore export type TTemplateLiteralKind = | TTemplateLiteral | TUnion | TLiteral | TInteger | TNumber | TBigInt | TString | TBoolean | TNever // ------------------------------------------------------------------ // TTemplateLiteral // ------------------------------------------------------------------ // prettier-ignore export interface TTemplateLiteral extends TSchema { [Kind]: 'TemplateLiteral' static: TemplateLiteralStatic type: 'string' pattern: string // todo: it may be possible to infer this pattern } /** `[Json]` Creates a TemplateLiteral type from template dsl string */ export function TemplateLiteral(syntax: T, options?: SchemaOptions): TTemplateLiteralSyntax /** `[Json]` Creates a TemplateLiteral type */ export function TemplateLiteral(kinds: [...T], options?: SchemaOptions): TTemplateLiteral /** `[Json]` Creates a TemplateLiteral type */ // prettier-ignore export function TemplateLiteral(unresolved: TTemplateLiteralKind[] | string, options?: SchemaOptions): any { const pattern = IsString(unresolved) ? TemplateLiteralPattern(TemplateLiteralSyntax(unresolved)) : TemplateLiteralPattern(unresolved as TTemplateLiteralKind[]) return CreateType({ [Kind]: 'TemplateLiteral', type: 'string', pattern }, options) } sinclairzx81-typebox-e0ec98c/src/type/template-literal/union.ts000066400000000000000000000050141505437577000247750ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { Static } from '../static/index' import type { TTemplateLiteral } from './template-literal' import type { UnionToTuple } from '../helpers/index' import { UnionEvaluated, type TUnionEvaluated } from '../union/index' import { Literal, type TLiteral } from '../literal/index' import { TemplateLiteralGenerate } from './generate' // ------------------------------------------------------------------ // TemplateLiteralToUnion // ------------------------------------------------------------------ // prettier-ignore export type TTemplateLiteralToUnionLiteralArray = ( T extends [infer L extends string, ...infer R extends string[]] ? TTemplateLiteralToUnionLiteralArray]> : Acc ) // prettier-ignore export type TTemplateLiteralToUnion< T extends TTemplateLiteral, U extends string[] = UnionToTuple> > = TUnionEvaluated> /** Returns a Union from the given TemplateLiteral */ export function TemplateLiteralToUnion(schema: TTemplateLiteral): TTemplateLiteralToUnion { const R = TemplateLiteralGenerate(schema) as string[] const L = R.map((S) => Literal(S)) return UnionEvaluated(L) } sinclairzx81-typebox-e0ec98c/src/type/transform/000077500000000000000000000000001505437577000220435ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/transform/index.ts000066400000000000000000000024671505437577000235330ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './transform' sinclairzx81-typebox-e0ec98c/src/type/transform/transform.ts000066400000000000000000000103041505437577000244240ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema } from '../schema/index' import type { Static, StaticDecode } from '../static/index' import { TransformKind } from '../symbols/index' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsTransform } from '../guard/kind' // ------------------------------------------------------------------ // TransformBuilders // ------------------------------------------------------------------ export class TransformDecodeBuilder { constructor(private readonly schema: T) {} public Decode, U>>(decode: D): TransformEncodeBuilder { return new TransformEncodeBuilder(this.schema, decode) } } // prettier-ignore export class TransformEncodeBuilder { constructor(private readonly schema: T, private readonly decode: D) { } private EncodeTransform, StaticDecode>>(encode: E, schema: TTransform) { const Encode = (value: unknown) => schema[TransformKind as any].Encode(encode(value as any)) const Decode = (value: unknown) => this.decode(schema[TransformKind as any].Decode(value)) const Codec = { Encode: Encode, Decode: Decode } return { ...schema, [TransformKind]: Codec } } private EncodeSchema, StaticDecode>>(encode: E, schema: TSchema) { const Codec = { Decode: this.decode, Encode: encode } return { ...schema, [TransformKind]: Codec } } public Encode, StaticDecode>>(encode: E): TTransform> { return ( IsTransform(this.schema) ? this.EncodeTransform(encode, this.schema): this.EncodeSchema(encode, this.schema) ) as never } } // ------------------------------------------------------------------ // TransformStatic // ------------------------------------------------------------------ type TransformStatic = T extends TTransform ? S : Static // ------------------------------------------------------------------ // TTransform // ------------------------------------------------------------------ export type TransformFunction = (value: T) => U export interface TransformOptions { Decode: TransformFunction, O> Encode: TransformFunction> } export interface TTransform extends TSchema { static: TransformStatic [TransformKind]: TransformOptions [key: string]: any } /** `[Json]` Creates a Transform type */ export function Transform(schema: I): TransformDecodeBuilder { return new TransformDecodeBuilder(schema) } sinclairzx81-typebox-e0ec98c/src/type/tuple/000077500000000000000000000000001505437577000211615ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/tuple/index.ts000066400000000000000000000024631505437577000226450ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './tuple' sinclairzx81-typebox-e0ec98c/src/type/tuple/tuple.ts000066400000000000000000000052401505437577000226630ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import type { Static } from '../static/index' import { Kind } from '../symbols/index' // ------------------------------------------------------------------ // TupleStatic // ------------------------------------------------------------------ // prettier-ignore type TupleStatic = T extends [infer L extends TSchema, ...infer R extends TSchema[]] ? TupleStatic]> : Acc // ------------------------------------------------------------------ // TTuple // ------------------------------------------------------------------ export interface TTuple extends TSchema { [Kind]: 'Tuple' static: TupleStatic type: 'array' items?: T additionalItems?: false minItems: number maxItems: number } /** `[Json]` Creates a Tuple type */ export function Tuple(types: [...Types], options?: SchemaOptions): TTuple { // prettier-ignore return CreateType( types.length > 0 ? { [Kind]: 'Tuple', type: 'array', items: types, additionalItems: false, minItems: types.length, maxItems: types.length } : { [Kind]: 'Tuple', type: 'array', minItems: types.length, maxItems: types.length }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/type/000077500000000000000000000000001505437577000210115ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/type/index.ts000066400000000000000000000036421505437577000224750ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ // ------------------------------------------------------------------ // JsonTypeBuilder // ------------------------------------------------------------------ export { JsonTypeBuilder } from './json' // ------------------------------------------------------------------ // JavaScriptTypeBuilder // ------------------------------------------------------------------ import * as TypeBuilder from './type' import { JavaScriptTypeBuilder } from './javascript' /** JavaScript Type Builder with Static Resolution for TypeScript */ const Type = TypeBuilder as InstanceType export { JavaScriptTypeBuilder } export { Type } sinclairzx81-typebox-e0ec98c/src/type/type/javascript.ts000066400000000000000000000152451505437577000235360ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { JsonTypeBuilder } from './json' import { Argument, type TArgument } from '../argument/index' import { AsyncIterator, type TAsyncIterator } from '../async-iterator/index' import { Awaited, type TAwaited } from '../awaited/index' import { BigInt, type TBigInt, type BigIntOptions } from '../bigint/index' import { Constructor, type TConstructor } from '../constructor/index' import { ConstructorParameters, type TConstructorParameters } from '../constructor-parameters/index' import { Date, type TDate, type DateOptions } from '../date/index' import { Function as FunctionType, type TFunction } from '../function/index' import { InstanceType, type TInstanceType } from '../instance-type/index' import { Instantiate, type TInstantiate } from '../instantiate/index' import { Iterator, type TIterator } from '../iterator/index' import { Parameters, type TParameters } from '../parameters/index' import { Promise, type TPromise } from '../promise/index' import { RegExp, type TRegExp, RegExpOptions } from '../regexp/index' import { ReturnType, type TReturnType } from '../return-type/index' import { type TSchema, type SchemaOptions } from '../schema/index' import { Symbol, type TSymbol } from '../symbol/index' import { Uint8Array, type TUint8Array, type Uint8ArrayOptions } from '../uint8array/index' import { Undefined, type TUndefined } from '../undefined/index' import { Void, type TVoid } from '../void/index' /** JavaScript Type Builder with Static Resolution for TypeScript */ export class JavaScriptTypeBuilder extends JsonTypeBuilder { /** `[JavaScript]` Creates a Generic Argument Type */ public Argument(index: Index): TArgument { return Argument(index) } /** `[JavaScript]` Creates a AsyncIterator type */ public AsyncIterator(items: Type, options?: SchemaOptions): TAsyncIterator { return AsyncIterator(items, options) } /** `[JavaScript]` Constructs a type by recursively unwrapping Promise types */ public Awaited(schema: Type, options?: SchemaOptions): TAwaited { return Awaited(schema, options) } /** `[JavaScript]` Creates a BigInt type */ public BigInt(options?: BigIntOptions): TBigInt { return BigInt(options) } /** `[JavaScript]` Extracts the ConstructorParameters from the given Constructor type */ public ConstructorParameters(schema: Type, options?: SchemaOptions): TConstructorParameters { return ConstructorParameters(schema, options) } /** `[JavaScript]` Creates a Constructor type */ public Constructor(parameters: [...Parameters], instanceType: InstanceType, options?: SchemaOptions): TConstructor { return Constructor(parameters, instanceType, options) } /** `[JavaScript]` Creates a Date type */ public Date(options: DateOptions = {}): TDate { return Date(options) } /** `[JavaScript]` Creates a Function type */ public Function(parameters: [...Parameters], returnType: ReturnType, options?: SchemaOptions): TFunction { return FunctionType(parameters, returnType, options) } /** `[JavaScript]` Extracts the InstanceType from the given Constructor type */ public InstanceType(schema: Type, options?: SchemaOptions): TInstanceType { return InstanceType(schema, options) } /** `[JavaScript]` Instantiates a type with the given parameters */ public Instantiate(schema: Type, parameters: [...Parameters]): TInstantiate { return Instantiate(schema, parameters) } /** `[JavaScript]` Creates an Iterator type */ public Iterator(items: Type, options?: SchemaOptions): TIterator { return Iterator(items, options) } /** `[JavaScript]` Extracts the Parameters from the given Function type */ public Parameters(schema: Type, options?: SchemaOptions): TParameters { return Parameters(schema, options) } /** `[JavaScript]` Creates a Promise type */ public Promise(item: Type, options?: SchemaOptions): TPromise { return Promise(item, options) } /** `[JavaScript]` Creates a RegExp type */ public RegExp(pattern: string, options?: RegExpOptions): TRegExp /** `[JavaScript]` Creates a RegExp type */ public RegExp(regex: RegExp, options?: RegExpOptions): TRegExp /** `[JavaScript]` Creates a RegExp type */ public RegExp(unresolved: string | RegExp, options?: RegExpOptions) { return RegExp(unresolved as any, options) } /** `[JavaScript]` Extracts the ReturnType from the given Function type */ public ReturnType(type: Type, options?: SchemaOptions): TReturnType { return ReturnType(type, options) } /** `[JavaScript]` Creates a Symbol type */ public Symbol(options?: SchemaOptions): TSymbol { return Symbol(options) } /** `[JavaScript]` Creates a Undefined type */ public Undefined(options?: SchemaOptions): TUndefined { return Undefined(options) } /** `[JavaScript]` Creates a Uint8Array type */ public Uint8Array(options?: Uint8ArrayOptions): TUint8Array { return Uint8Array(options) } /** `[JavaScript]` Creates a Void type */ public Void(options?: SchemaOptions): TVoid { return Void(options) } } sinclairzx81-typebox-e0ec98c/src/type/type/json.ts000066400000000000000000000513321505437577000223360ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { Any, type TAny } from '../any/index' import { Array, type TArray, type ArrayOptions } from '../array/index' import { Boolean, type TBoolean } from '../boolean/index' import { Composite, type TComposite } from '../composite/index' import { Const, type TConst } from '../const/index' import { Enum, type TEnum, type TEnumKey, type TEnumValue } from '../enum/index' import { Exclude, type TExclude, type TExcludeFromMappedResult, type TExcludeFromTemplateLiteral } from '../exclude/index' import { Extends, type TExtends, type TExtendsFromMappedKey, type TExtendsFromMappedResult } from '../extends/index' import { Extract, type TExtract, type TExtractFromMappedResult, type TExtractFromTemplateLiteral } from '../extract/index' import { Index, TIndex, type TIndexPropertyKeys, type TIndexFromMappedKey, type TIndexFromMappedResult, type TIndexFromComputed } from '../indexed/index' import { Integer, type IntegerOptions, type TInteger } from '../integer/index' import { Intersect, type IntersectOptions } from '../intersect/index' import { Capitalize, Uncapitalize, Lowercase, Uppercase, type TCapitalize, type TUncapitalize, type TLowercase, type TUppercase } from '../intrinsic/index' import { KeyOf, type TKeyOf } from '../keyof/index' import { Literal, type TLiteral, type TLiteralValue } from '../literal/index' import { Mapped, type TMappedFunction, type TMapped, type TMappedResult } from '../mapped/index' import { Never, type TNever } from '../never/index' import { Not, type TNot } from '../not/index' import { Null, type TNull } from '../null/index' import { type TMappedKey } from '../mapped/index' import { Module, TModule } from '../module/index' import { Number, type TNumber, type NumberOptions } from '../number/index' import { Object, type TObject, type TProperties, type ObjectOptions } from '../object/index' import { Omit, type TOmit } from '../omit/index' import { Optional, type TOptionalWithFlag, type TOptionalFromMappedResult } from '../optional/index' import { Partial, type TPartial, type TPartialFromMappedResult } from '../partial/index' import { Pick, type TPick } from '../pick/index' import { Readonly, type TReadonlyWithFlag, type TReadonlyFromMappedResult } from '../readonly/index' import { ReadonlyOptional, type TReadonlyOptional } from '../readonly-optional/index' import { Record, type TRecordOrObject } from '../record/index' import { Recursive, type TRecursive, type TThis } from '../recursive/index' import { Ref, type TRef, type TRefUnsafe } from '../ref/index' import { Required, type TRequired, type TRequiredFromMappedResult } from '../required/index' import { Rest, type TRest } from '../rest/index' import { type TSchema, type SchemaOptions } from '../schema/index' import { String, type TString, type StringOptions } from '../string/index' import { TemplateLiteral, type TTemplateLiteral, type TTemplateLiteralKind, type TTemplateLiteralSyntax } from '../template-literal/index' import { Transform, TransformDecodeBuilder } from '../transform/index' import { Tuple, type TTuple } from '../tuple/index' import { Union } from '../union/index' import { Unknown, type TUnknown } from '../unknown/index' import { Unsafe, type TUnsafe, type UnsafeOptions } from '../unsafe/index' /** Json Type Builder with Static Resolution for TypeScript */ export class JsonTypeBuilder { // ------------------------------------------------------------------------ // Modifiers // ------------------------------------------------------------------------ /** `[Json]` Creates a Readonly and Optional property */ public ReadonlyOptional(type: Type): TReadonlyOptional { return ReadonlyOptional(type) } /** `[Json]` Creates a Readonly property */ public Readonly(type: Type, enable: Flag): TReadonlyFromMappedResult /** `[Json]` Creates a Readonly property */ public Readonly(type: Type, enable: Flag): TReadonlyWithFlag /** `[Json]` Creates a Optional property */ public Readonly(type: Type): TReadonlyFromMappedResult /** `[Json]` Creates a Readonly property */ public Readonly(type: Type): TReadonlyWithFlag /** `[Json]` Creates a Readonly property */ public Readonly(type: TSchema, enable?: boolean): any { return Readonly(type, enable ?? true) } /** `[Json]` Creates a Optional property */ public Optional(type: Type, enable: Flag): TOptionalFromMappedResult /** `[Json]` Creates a Optional property */ public Optional(type: Type, enable: Flag): TOptionalWithFlag /** `[Json]` Creates a Optional property */ public Optional(type: Type): TOptionalFromMappedResult /** `[Json]` Creates a Optional property */ public Optional(type: Type): TOptionalWithFlag /** `[Json]` Creates a Optional property */ public Optional(type: TSchema, enable?: boolean): any { return Optional(type, enable ?? true) } // ------------------------------------------------------------------------ // Types // ------------------------------------------------------------------------ /** `[Json]` Creates an Any type */ public Any(options?: SchemaOptions): TAny { return Any(options) } /** `[Json]` Creates an Array type */ public Array(items: Type, options?: ArrayOptions): TArray { return Array(items, options) } /** `[Json]` Creates a Boolean type */ public Boolean(options?: SchemaOptions): TBoolean { return Boolean(options) } /** `[Json]` Intrinsic function to Capitalize LiteralString types */ public Capitalize(schema: T, options?: SchemaOptions): TCapitalize { return Capitalize(schema, options) } /** `[Json]` Creates a Composite object type */ public Composite(schemas: [...T], options?: ObjectOptions): TComposite { return Composite(schemas, options) // (error) TS 5.4.0-dev - review TComposite implementation } /** `[JavaScript]` Creates a readonly const type from the given value. */ public Const(value: T, options?: SchemaOptions): TConst { return Const(value, options) } /** `[Json]` Creates a Enum type */ public Enum>(item: T, options?: SchemaOptions): TEnum { return Enum(item, options) } /** `[Json]` Constructs a type by excluding from unionType all union members that are assignable to excludedMembers */ public Exclude(unionType: L, excludedMembers: R, options?: SchemaOptions): TExcludeFromMappedResult /** `[Json]` Constructs a type by excluding from unionType all union members that are assignable to excludedMembers */ public Exclude(unionType: L, excludedMembers: R, options?: SchemaOptions): TExcludeFromTemplateLiteral /** `[Json]` Constructs a type by excluding from unionType all union members that are assignable to excludedMembers */ public Exclude(unionType: L, excludedMembers: R, options?: SchemaOptions): TExclude /** `[Json]` Constructs a type by excluding from unionType all union members that are assignable to excludedMembers */ public Exclude(unionType: TSchema, excludedMembers: TSchema, options?: SchemaOptions): any { return Exclude(unionType, excludedMembers, options) } /** `[Json]` Creates a Conditional type */ public Extends(L: L, R: R, T: T, F: F, options?: SchemaOptions): TExtendsFromMappedResult /** `[Json]` Creates a Conditional type */ public Extends(L: L, R: R, T: T, F: F, options?: SchemaOptions): TExtendsFromMappedKey /** `[Json]` Creates a Conditional type */ public Extends(L: L, R: R, T: T, F: F, options?: SchemaOptions): TExtends /** `[Json]` Creates a Conditional type */ public Extends(L: L, R: R, T: T, F: F, options?: SchemaOptions) { return Extends(L, R, T, F, options) } /** `[Json]` Constructs a type by extracting from type all union members that are assignable to union */ public Extract(type: L, union: R, options?: SchemaOptions): TExtractFromMappedResult /** `[Json]` Constructs a type by extracting from type all union members that are assignable to union */ public Extract(type: L, union: R, options?: SchemaOptions): TExtractFromTemplateLiteral /** `[Json]` Constructs a type by extracting from type all union members that are assignable to union */ public Extract(type: L, union: R, options?: SchemaOptions): TExtract /** `[Json]` Constructs a type by extracting from type all union members that are assignable to union */ public Extract(type: TSchema, union: TSchema, options?: SchemaOptions): any { return Extract(type, union, options) } /** `[Json]` Returns an Indexed property type for the given keys */ public Index(type: Type, key: Key, options?: SchemaOptions): TIndexFromComputed /** `[Json]` Returns an Indexed property type for the given keys */ public Index(type: Type, key: Key, options?: SchemaOptions): TIndexFromComputed /** `[Json]` Returns an Indexed property type for the given keys */ public Index(type: Type, key: Key, options?: SchemaOptions): TIndexFromComputed /** `[Json]` Returns an Indexed property type for the given keys */ public Index(type: Type, mappedResult: MappedResult, options?: SchemaOptions): TIndexFromMappedResult /** `[Json]` Returns an Indexed property type for the given keys */ public Index(type: Type, mappedKey: MappedKey, options?: SchemaOptions): TIndexFromMappedKey /** `[Json]` Returns an Indexed property type for the given keys */ public Index>(T: Type, K: Key, options?: SchemaOptions): TIndex /** `[Json]` Returns an Indexed property type for the given keys */ public Index(type: Type, propertyKeys: readonly [...PropertyKeys], options?: SchemaOptions): TIndex /** `[Json]` Returns an Indexed property type for the given keys */ public Index(type: TSchema, key: any, options?: SchemaOptions): any { return Index(type, key, options) } /** `[Json]` Creates an Integer type */ public Integer(options?: IntegerOptions): TInteger { return Integer(options) } /** `[Json]` Creates an Intersect type */ public Intersect(types: [...Types], options?: IntersectOptions): Intersect { return Intersect(types, options) } /** `[Json]` Creates a KeyOf type */ public KeyOf(type: Type, options?: SchemaOptions): TKeyOf { return KeyOf(type, options) as never } /** `[Json]` Creates a Literal type */ public Literal(literalValue: LiteralValue, options?: SchemaOptions): TLiteral { return Literal(literalValue, options) } /** `[Json]` Intrinsic function to Lowercase LiteralString types */ public Lowercase(type: Type, options?: SchemaOptions): TLowercase { return Lowercase(type, options) } /** `[Json]` Creates a Mapped object type */ public Mapped, F extends TMappedFunction = TMappedFunction, R extends TMapped = TMapped>(key: K, map: F, options?: ObjectOptions): R /** `[Json]` Creates a Mapped object type */ public Mapped = TMappedFunction, R extends TMapped = TMapped>(key: [...K], map: F, options?: ObjectOptions): R /** `[Json]` Creates a Mapped object type */ public Mapped(key: any, map: TMappedFunction, options?: ObjectOptions): any { return Mapped(key, map, options) } /** `[Json]` Creates a Type Definition Module. */ public Module(properties: Properties): TModule { return Module(properties) } /** `[Json]` Creates a Never type */ public Never(options?: SchemaOptions): TNever { return Never(options) } /** `[Json]` Creates a Not type */ public Not(type: T, options?: SchemaOptions): TNot { return Not(type, options) } /** `[Json]` Creates a Null type */ public Null(options?: SchemaOptions): TNull { return Null(options) } /** `[Json]` Creates a Number type */ public Number(options?: NumberOptions): TNumber { return Number(options) } /** `[Json]` Creates an Object type */ public Object(properties: T, options?: ObjectOptions): TObject { return Object(properties, options) } /** `[Json]` Constructs a type whose keys are picked from the given type */ public Omit(type: Type, key: readonly [...Key], options?: SchemaOptions): TOmit /** `[Json]` Constructs a type whose keys are picked from the given type */ public Omit(type: Type, key: Key, options?: SchemaOptions): TOmit /** `[Json]` Constructs a type whose keys are omitted from the given type */ public Omit(schema: TSchema, selector: any, options?: SchemaOptions): any { return Omit(schema, selector, options) } /** `[Json]` Constructs a type where all properties are optional */ public Partial(type: MappedResult, options?: SchemaOptions): TPartialFromMappedResult /** `[Json]` Constructs a type where all properties are optional */ public Partial(type: Type, options?: SchemaOptions): TPartial /** `[Json]` Constructs a type where all properties are optional */ public Partial(type: TSchema, options?: SchemaOptions): any { return Partial(type, options) } /** `[Json]` Constructs a type whose keys are picked from the given type */ public Pick(type: Type, key: readonly [...Key], options?: SchemaOptions): TPick /** `[Json]` Constructs a type whose keys are picked from the given type */ public Pick(type: Type, key: Key, options?: SchemaOptions): TPick /** `[Json]` Constructs a type whose keys are picked from the given type */ public Pick(type: any, key: any, options?: SchemaOptions): any { return Pick(type, key, options) } /** `[Json]` Creates a Record type */ public Record(key: Key, value: Value, options?: ObjectOptions): TRecordOrObject { return Record(key, value, options) } /** `[Json]` Creates a Recursive type */ public Recursive(callback: (thisType: TThis) => T, options?: SchemaOptions): TRecursive { return Recursive(callback, options) } /** `[Json]` Creates a Ref type.*/ public Ref($ref: Ref, options?: SchemaOptions): TRef /** * @deprecated `[Json]` Creates a Ref type. This signature was deprecated in 0.34.0 where Ref requires callers to pass * a `string` value for the reference (and not a schema). * * To adhere to the 0.34.0 signature, Ref implementations should be updated to the following. * * ```typescript * // pre-0.34.0 * * const T = Type.String({ $id: 'T' }) * * const R = Type.Ref(T) * ``` * should be changed to the following * * ```typescript * // post-0.34.0 * * const T = Type.String({ $id: 'T' }) * * const R = Type.Unsafe>(Type.Ref('T')) * ``` * You can also create a generic function to replicate the pre-0.34.0 signature if required * * ```typescript * const LegacyRef = (schema: T) => Type.Unsafe>(Type.Ref(schema.$id!)) * ``` */ public Ref(type: Type, options?: SchemaOptions): TRefUnsafe /** `[Json]` Creates a Ref type. The referenced type must contain a $id */ public Ref(...args: any[]): unknown { return Ref(args[0] as string, args[1]) } /** `[Json]` Constructs a type where all properties are required */ public Required(type: MappedResult, options?: SchemaOptions): TRequiredFromMappedResult /** `[Json]` Constructs a type where all properties are required */ public Required(type: Type, options?: SchemaOptions): TRequired /** `[Json]` Constructs a type where all properties are required */ public Required(type: TSchema, options?: SchemaOptions): any { return Required(type, options) } /** `[Json]` Extracts interior Rest elements from Tuple, Intersect and Union types */ public Rest(type: Type): TRest { return Rest(type) } /** `[Json]` Creates a String type */ public String(options?: StringOptions): TString { return String(options) } /** `[Json]` Creates a TemplateLiteral type from template dsl string */ public TemplateLiteral(syntax: Syntax, options?: SchemaOptions): TTemplateLiteralSyntax /** `[Json]` Creates a TemplateLiteral type */ public TemplateLiteral(kinds: [...Kinds], options?: SchemaOptions): TTemplateLiteral /** `[Json]` Creates a TemplateLiteral type */ public TemplateLiteral(unresolved: TTemplateLiteralKind[] | string, options?: SchemaOptions) { return TemplateLiteral(unresolved as any, options) } /** `[Json]` Creates a Transform type */ public Transform(type: Type): TransformDecodeBuilder { return Transform(type) } /** `[Json]` Creates a Tuple type */ public Tuple(types: [...Types], options?: SchemaOptions): TTuple { return Tuple(types, options) } /** `[Json]` Intrinsic function to Uncapitalize LiteralString types */ public Uncapitalize(type: Type, options?: SchemaOptions): TUncapitalize { return Uncapitalize(type, options) } /** `[Json]` Creates a Union type */ public Union(types: [...Types], options?: SchemaOptions): Union { return Union(types, options) } /** `[Json]` Creates an Unknown type */ public Unknown(options?: SchemaOptions): TUnknown { return Unknown(options) } /** `[Json]` Creates a Unsafe type that will infers as the generic argument T */ public Unsafe(options?: UnsafeOptions): TUnsafe { return Unsafe(options) } /** `[Json]` Intrinsic function to Uppercase LiteralString types */ public Uppercase(schema: T, options?: SchemaOptions): TUppercase { return Uppercase(schema, options) } } sinclairzx81-typebox-e0ec98c/src/type/type/type.ts000066400000000000000000000077651505437577000223610ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ // ------------------------------------------------------------------ // Type: Module // ------------------------------------------------------------------ export { Any } from '../any/index' export { Argument } from '../argument/index' export { Array } from '../array/index' export { AsyncIterator } from '../async-iterator/index' export { Awaited } from '../awaited/index' export { BigInt } from '../bigint/index' export { Boolean } from '../boolean/index' export { Composite } from '../composite/index' export { Const } from '../const/index' export { Constructor } from '../constructor/index' export { ConstructorParameters } from '../constructor-parameters/index' export { Date } from '../date/index' export { Enum } from '../enum/index' export { Exclude } from '../exclude/index' export { Extends } from '../extends/index' export { Extract } from '../extract/index' export { Function } from '../function/index' export { Index } from '../indexed/index' export { InstanceType } from '../instance-type/index' export { Instantiate } from '../instantiate/index' export { Integer } from '../integer/index' export { Intersect } from '../intersect/index' export { Capitalize, Uncapitalize, Lowercase, Uppercase } from '../intrinsic/index' export { Iterator } from '../iterator/index' export { KeyOf } from '../keyof/index' export { Literal } from '../literal/index' export { Mapped } from '../mapped/index' export { Module } from '../module/index' export { Never } from '../never/index' export { Not } from '../not/index' export { Null } from '../null/index' export { Number } from '../number/index' export { Object } from '../object/index' export { Omit } from '../omit/index' export { Optional } from '../optional/index' export { Parameters } from '../parameters/index' export { Partial } from '../partial/index' export { Pick } from '../pick/index' export { Promise } from '../promise/index' export { Readonly } from '../readonly/index' export { ReadonlyOptional } from '../readonly-optional/index' export { Record } from '../record/index' export { Recursive } from '../recursive/index' export { Ref } from '../ref/index' export { RegExp } from '../regexp/index' export { Required } from '../required/index' export { Rest } from '../rest/index' export { ReturnType } from '../return-type/index' export { String } from '../string/index' export { Symbol } from '../symbol/index' export { TemplateLiteral } from '../template-literal/index' export { Transform } from '../transform/index' export { Tuple } from '../tuple/index' export { Uint8Array } from '../uint8array/index' export { Undefined } from '../undefined/index' export { Union } from '../union/index' export { Unknown } from '../unknown/index' export { Unsafe } from '../unsafe/index' export { Void } from '../void/index' sinclairzx81-typebox-e0ec98c/src/type/uint8array/000077500000000000000000000000001505437577000221365ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/uint8array/index.ts000066400000000000000000000024701505437577000236200ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './uint8array' sinclairzx81-typebox-e0ec98c/src/type/uint8array/uint8array.ts000066400000000000000000000035571505437577000246260ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import { Kind } from '../symbols/index' export interface Uint8ArrayOptions extends SchemaOptions { maxByteLength?: number minByteLength?: number } export interface TUint8Array extends TSchema, Uint8ArrayOptions { [Kind]: 'Uint8Array' static: Uint8Array type: 'uint8array' } /** `[JavaScript]` Creates a Uint8Array type */ export function Uint8Array(options?: Uint8ArrayOptions): TUint8Array { return CreateType({ [Kind]: 'Uint8Array', type: 'Uint8Array' }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/undefined/000077500000000000000000000000001505437577000217715ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/undefined/index.ts000066400000000000000000000024671505437577000234610ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './undefined' sinclairzx81-typebox-e0ec98c/src/type/undefined/undefined.ts000066400000000000000000000033401505437577000243020ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import { Kind } from '../symbols/index' export interface TUndefined extends TSchema { [Kind]: 'Undefined' static: undefined type: 'undefined' } /** `[JavaScript]` Creates a Undefined type */ export function Undefined(options?: SchemaOptions): TUndefined { return CreateType({ [Kind]: 'Undefined', type: 'undefined' }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/union/000077500000000000000000000000001505437577000211605ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/union/index.ts000066400000000000000000000025621505437577000226440ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './union-evaluated' export * from './union-type' export * from './union' sinclairzx81-typebox-e0ec98c/src/type/union/union-create.ts000066400000000000000000000031751505437577000241270ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import { CreateType } from '../create/type' import { TUnion } from './union-type' import { Kind } from '../symbols/index' export function UnionCreate(T: [...T], options?: SchemaOptions): TUnion { return CreateType({ [Kind]: 'Union', anyOf: T }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/union/union-evaluated.ts000066400000000000000000000124011505437577000246260ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { SchemaOptions, TSchema } from '../schema/index' import { OptionalKind } from '../symbols/index' import { Discard } from '../discard/index' import { Never, type TNever } from '../never/index' import { Optional, type TOptional } from '../optional/index' import type { TReadonly } from '../readonly/index' import type { TUnion } from './union-type' import { UnionCreate } from './union-create' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsOptional } from '../guard/kind' // ------------------------------------------------------------------ // IsUnionOptional // ------------------------------------------------------------------ // prettier-ignore type TIsUnionOptional = ( Types extends [infer Left extends TSchema, ...infer Right extends TSchema[]] ? Left extends TOptional ? true : TIsUnionOptional : false ) // prettier-ignore function IsUnionOptional(types: Types): TIsUnionOptional { return types.some(type => IsOptional(type)) as never } // ------------------------------------------------------------------ // RemoveOptionalFromRest // ------------------------------------------------------------------ // prettier-ignore type TRemoveOptionalFromRest = ( Types extends [infer Left extends TSchema, ...infer Right extends TSchema[]] ? Left extends TOptional ? TRemoveOptionalFromRest]> : TRemoveOptionalFromRest : Result ) // prettier-ignore function RemoveOptionalFromRest(types: Types): TRemoveOptionalFromRest { return types.map(left => IsOptional(left) ? RemoveOptionalFromType(left) : left) as never } // ------------------------------------------------------------------ // RemoveOptionalFromType // ------------------------------------------------------------------ // prettier-ignore type TRemoveOptionalFromType = ( Type extends TReadonly ? TReadonly> : Type extends TOptional ? TRemoveOptionalFromType : Type ) // prettier-ignore function RemoveOptionalFromType(T: Type): TRemoveOptionalFromType { return ( Discard(T, [OptionalKind]) ) as never } // ------------------------------------------------------------------ // ResolveUnion // ------------------------------------------------------------------ // prettier-ignore type TResolveUnion, IsOptional extends boolean = TIsUnionOptional > = ( IsOptional extends true ? TOptional> : TUnion ) // prettier-ignore function ResolveUnion(types: Types, options?: SchemaOptions): TResolveUnion { const isOptional = IsUnionOptional(types) return ( isOptional ? Optional(UnionCreate(RemoveOptionalFromRest(types) as TSchema[], options)) : UnionCreate(RemoveOptionalFromRest(types) as TSchema[], options) ) as never } // ------------------------------------------------------------------ // Union // ------------------------------------------------------------------ // prettier-ignore export type TUnionEvaluated = ( Types extends [TSchema] ? Types[0] : Types extends [] ? TNever : TResolveUnion ) /** `[Json]` Creates an evaluated Union type */ export function UnionEvaluated>(T: [...Types], options?: SchemaOptions): Result { // prettier-ignore return ( T.length === 1 ? CreateType(T[0], options) : T.length === 0 ? Never(options) : ResolveUnion(T, options) ) as never } sinclairzx81-typebox-e0ec98c/src/type/union/union-type.ts000066400000000000000000000040041505437577000236350ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema } from '../schema/index' import type { Static } from '../static/index' import { Kind } from '../symbols/index' // ------------------------------------------------------------------ // UnionStatic // ------------------------------------------------------------------ // prettier-ignore type UnionStatic = { [K in keyof T]: T[K] extends TSchema ? Static : never }[number] // ------------------------------------------------------------------ // TUnion // ------------------------------------------------------------------ export interface TUnion extends TSchema { [Kind]: 'Union' static: UnionStatic anyOf: T } sinclairzx81-typebox-e0ec98c/src/type/union/union.ts000066400000000000000000000037401505437577000226640ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' import { type TNever, Never } from '../never/index' import type { TUnion } from './union-type' import { CreateType } from '../create/type' import { UnionCreate } from './union-create' // prettier-ignore export type Union = ( T extends [] ? TNever : T extends [TSchema] ? T[0] : TUnion ) /** `[Json]` Creates a Union type */ export function Union(types: [...Types], options?: SchemaOptions): Union { // prettier-ignore return ( types.length === 0 ? Never(options) : types.length === 1 ? CreateType(types[0], options) : UnionCreate(types, options) ) as Union } sinclairzx81-typebox-e0ec98c/src/type/unknown/000077500000000000000000000000001505437577000215275ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/unknown/index.ts000066400000000000000000000024651505437577000232150ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './unknown' sinclairzx81-typebox-e0ec98c/src/type/unknown/unknown.ts000066400000000000000000000032461505437577000236030ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import { Kind } from '../symbols/index' export interface TUnknown extends TSchema { [Kind]: 'Unknown' static: unknown } /** `[Json]` Creates an Unknown type */ export function Unknown(options?: SchemaOptions): TUnknown { return CreateType({ [Kind]: 'Unknown' }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/unsafe/000077500000000000000000000000001505437577000213115ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/unsafe/index.ts000066400000000000000000000024641505437577000227760ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './unsafe' sinclairzx81-typebox-e0ec98c/src/type/unsafe/unsafe.ts000066400000000000000000000034531505437577000231470ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import { Kind } from '../symbols/index' export interface UnsafeOptions extends SchemaOptions { [Kind]?: string } export interface TUnsafe extends TSchema { [Kind]: string static: T } /** `[Json]` Creates a Unsafe type that will infers as the generic argument T */ export function Unsafe(options: UnsafeOptions = {}): TUnsafe { return CreateType({ [Kind]: options[Kind] ?? 'Unsafe' }, options) as never } sinclairzx81-typebox-e0ec98c/src/type/void/000077500000000000000000000000001505437577000207715ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/type/void/index.ts000066400000000000000000000024621505437577000224540ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './void' sinclairzx81-typebox-e0ec98c/src/type/void/void.ts000066400000000000000000000032631505437577000223060ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/type The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' import type { TSchema, SchemaOptions } from '../schema/index' import { Kind } from '../symbols/index' export interface TVoid extends TSchema { [Kind]: 'Void' static: void type: 'void' } /** `[JavaScript]` Creates a Void type */ export function Void(options?: SchemaOptions): TVoid { return CreateType({ [Kind]: 'Void', type: 'void' }, options) as never } sinclairzx81-typebox-e0ec98c/src/value/000077500000000000000000000000001505437577000201635ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/value/assert/000077500000000000000000000000001505437577000214645ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/value/assert/assert.ts000066400000000000000000000065751505437577000233520ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { Errors, ValueErrorIterator, ValueError } from '../../errors/index' import { TypeBoxError } from '../../type/error/error' import { TSchema } from '../../type/schema/index' import { Static } from '../../type/static/index' import { Check } from '../check/check' // ------------------------------------------------------------------ // AssertError // ------------------------------------------------------------------ export class AssertError extends TypeBoxError { readonly #iterator: ValueErrorIterator error: ValueError | undefined constructor(iterator: ValueErrorIterator) { const error = iterator.First() super(error === undefined ? 'Invalid Value' : error.message) this.#iterator = iterator this.error = error } /** Returns an iterator for each error in this value. */ public Errors(): ValueErrorIterator { return new ValueErrorIterator(this.#Iterator()) } *#Iterator(): IterableIterator { if (this.error) yield this.error yield* this.#iterator } } // ------------------------------------------------------------------ // AssertValue // ------------------------------------------------------------------ function AssertValue(schema: TSchema, references: TSchema[], value: unknown): unknown { if (Check(schema, references, value)) return throw new AssertError(Errors(schema, references, value)) } // ------------------------------------------------------------------ // Assert // ------------------------------------------------------------------ /** Asserts a value matches the given type or throws an `AssertError` if invalid */ export function Assert(schema: T, references: TSchema[], value: unknown): asserts value is Static /** Asserts a value matches the given type or throws an `AssertError` if invalid */ export function Assert(schema: T, value: unknown): asserts value is Static /** Asserts a value matches the given type or throws an `AssertError` if invalid */ export function Assert(...args: any[]): unknown { return args.length === 3 ? AssertValue(args[0], args[1], args[2]) : AssertValue(args[0], [], args[1]) } sinclairzx81-typebox-e0ec98c/src/value/assert/index.ts000066400000000000000000000024651505437577000231520ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './assert' sinclairzx81-typebox-e0ec98c/src/value/cast/000077500000000000000000000000001505437577000211155ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/value/cast/cast.ts000066400000000000000000000314601505437577000224230ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { IsObject, IsArray, IsString, IsNumber, IsNull } from '../guard/index' import { TypeBoxError } from '../../type/error/index' import { Kind } from '../../type/symbols/index' import { Create } from '../create/index' import { Check } from '../check/index' import { Clone } from '../clone/index' import { Deref, Pushref } from '../deref/index' import type { TSchema } from '../../type/schema/index' import type { Static } from '../../type/static/index' import type { TArray } from '../../type/array/index' import type { TConstructor } from '../../type/constructor/index' import type { TImport } from '../../type/module/index' import type { TIntersect } from '../../type/intersect/index' import type { TObject } from '../../type/object/index' import type { TRecord } from '../../type/record/index' import type { TRef } from '../../type/ref/index' import type { TThis } from '../../type/recursive/index' import type { TTuple } from '../../type/tuple/index' import type { TUnion } from '../../type/union/index' import type { TNever } from '../../type/never/index' // ------------------------------------------------------------------ // Errors // ------------------------------------------------------------------ export class ValueCastError extends TypeBoxError { constructor(public readonly schema: TSchema, message: string) { super(message) } } // ------------------------------------------------------------------ // The following logic assigns a score to a schema based on how well // it matches a given value. For object types, the score is calculated // by evaluating each property of the value against the schema's // properties. To avoid bias towards objects with many properties, // each property contributes equally to the total score. Properties // that exactly match literal values receive the highest possible // score, as literals are often used as discriminators in union types. // ------------------------------------------------------------------ function ScoreUnion(schema: TSchema, references: TSchema[], value: any): number { if (schema[Kind] === 'Object' && typeof value === 'object' && !IsNull(value)) { const object = schema as TObject const keys = Object.getOwnPropertyNames(value) const entries = Object.entries(object.properties) return entries.reduce((acc, [key, schema]) => { const literal = schema[Kind] === 'Literal' && schema.const === value[key] ? 100 : 0 const checks = Check(schema, references, value[key]) ? 10 : 0 const exists = keys.includes(key) ? 1 : 0 return acc + (literal + checks + exists) }, 0) } else if (schema[Kind] === 'Union') { const schemas = schema.anyOf.map((schema: TSchema) => Deref(schema, references)) const scores = schemas.map((schema: TSchema) => ScoreUnion(schema, references, value)) return Math.max(...scores) } else { return Check(schema, references, value) ? 1 : 0 } } function SelectUnion(union: TUnion, references: TSchema[], value: any): TSchema { const schemas = union.anyOf.map((schema) => Deref(schema, references)) let [select, best] = [schemas[0], 0] for (const schema of schemas) { const score = ScoreUnion(schema, references, value) if (score > best) { select = schema best = score } } return select } function CastUnion(union: TUnion, references: TSchema[], value: any) { if ('default' in union) { return typeof value === 'function' ? union.default : Clone(union.default) } else { const schema = SelectUnion(union, references, value) return Cast(schema, references, value) } } // ------------------------------------------------------------------ // Default // ------------------------------------------------------------------ function DefaultClone(schema: TSchema, references: TSchema[], value: any): any { return Check(schema, references, value) ? Clone(value) : Create(schema, references) } function Default(schema: TSchema, references: TSchema[], value: any): any { return Check(schema, references, value) ? value : Create(schema, references) } // ------------------------------------------------------------------ // Cast // ------------------------------------------------------------------ function FromArray(schema: TArray, references: TSchema[], value: any): any { if (Check(schema, references, value)) return Clone(value) const created = IsArray(value) ? Clone(value) : Create(schema, references) const minimum = IsNumber(schema.minItems) && created.length < schema.minItems ? [...created, ...Array.from({ length: schema.minItems - created.length }, () => null)] : created const maximum = IsNumber(schema.maxItems) && minimum.length > schema.maxItems ? minimum.slice(0, schema.maxItems) : minimum const casted = maximum.map((value: unknown) => Visit(schema.items, references, value)) if (schema.uniqueItems !== true) return casted const unique = [...new Set(casted)] if (!Check(schema, references, unique)) throw new ValueCastError(schema, 'Array cast produced invalid data due to uniqueItems constraint') return unique } function FromConstructor(schema: TConstructor, references: TSchema[], value: any): any { if (Check(schema, references, value)) return Create(schema, references) const required = new Set(schema.returns.required || []) const result = function () {} for (const [key, property] of Object.entries(schema.returns.properties)) { if (!required.has(key) && value.prototype[key] === undefined) continue result.prototype[key] = Visit(property as TSchema, references, value.prototype[key]) } return result } function FromImport(schema: TImport, references: TSchema[], value: unknown): boolean { const definitions = globalThis.Object.values(schema.$defs) as TSchema[] const target = schema.$defs[schema.$ref] as TSchema return Visit(target, [...references, ...definitions], value) } // ------------------------------------------------------------------ // Intersect // ------------------------------------------------------------------ function IntersectAssign(correct: unknown, value: unknown): unknown { // trust correct on mismatch | value on non-object if ((IsObject(correct) && !IsObject(value)) || (!IsObject(correct) && IsObject(value))) return correct if (!IsObject(correct) || !IsObject(value)) return value return globalThis.Object.getOwnPropertyNames(correct).reduce((result, key) => { const property = key in value ? IntersectAssign(correct[key], value[key]) : correct[key] return { ...result, [key]: property } }, {}) } function FromIntersect(schema: TIntersect, references: TSchema[], value: any): any { if (Check(schema, references, value)) return value const correct = Create(schema, references) const assigned = IntersectAssign(correct, value) return Check(schema, references, assigned) ? assigned : correct } function FromNever(schema: TNever, references: TSchema[], value: any): any { throw new ValueCastError(schema, 'Never types cannot be cast') } function FromObject(schema: TObject, references: TSchema[], value: any): any { if (Check(schema, references, value)) return value if (value === null || typeof value !== 'object') return Create(schema, references) const required = new Set(schema.required || []) const result = {} as Record for (const [key, property] of Object.entries(schema.properties)) { if (!required.has(key) && value[key] === undefined) continue result[key] = Visit(property, references, value[key]) } // additional schema properties if (typeof schema.additionalProperties === 'object') { const propertyNames = Object.getOwnPropertyNames(schema.properties) for (const propertyName of Object.getOwnPropertyNames(value)) { if (propertyNames.includes(propertyName)) continue result[propertyName] = Visit(schema.additionalProperties, references, value[propertyName]) } } return result } function FromRecord(schema: TRecord, references: TSchema[], value: any): any { if (Check(schema, references, value)) return Clone(value) if (value === null || typeof value !== 'object' || Array.isArray(value) || value instanceof Date) return Create(schema, references) const subschemaPropertyName = Object.getOwnPropertyNames(schema.patternProperties)[0] const subschema = schema.patternProperties[subschemaPropertyName] const result = {} as Record for (const [propKey, propValue] of Object.entries(value)) { result[propKey] = Visit(subschema, references, propValue) } return result } function FromRef(schema: TRef, references: TSchema[], value: any): any { return Visit(Deref(schema, references), references, value) } function FromThis(schema: TThis, references: TSchema[], value: any): any { return Visit(Deref(schema, references), references, value) } function FromTuple(schema: TTuple, references: TSchema[], value: any): any { if (Check(schema, references, value)) return Clone(value) if (!IsArray(value)) return Create(schema, references) if (schema.items === undefined) return [] return schema.items.map((schema, index) => Visit(schema, references, value[index])) } function FromUnion(schema: TUnion, references: TSchema[], value: any): any { return Check(schema, references, value) ? Clone(value) : CastUnion(schema, references, value) } function Visit(schema: TSchema, references: TSchema[], value: any): any { const references_ = IsString(schema.$id) ? Pushref(schema, references) : references const schema_ = schema as any switch (schema[Kind]) { // -------------------------------------------------------------- // Structural // -------------------------------------------------------------- case 'Array': return FromArray(schema_, references_, value) case 'Constructor': return FromConstructor(schema_, references_, value) case 'Import': return FromImport(schema_, references_, value) case 'Intersect': return FromIntersect(schema_, references_, value) case 'Never': return FromNever(schema_, references_, value) case 'Object': return FromObject(schema_, references_, value) case 'Record': return FromRecord(schema_, references_, value) case 'Ref': return FromRef(schema_, references_, value) case 'This': return FromThis(schema_, references_, value) case 'Tuple': return FromTuple(schema_, references_, value) case 'Union': return FromUnion(schema_, references_, value) // -------------------------------------------------------------- // DefaultClone // -------------------------------------------------------------- case 'Date': case 'Symbol': case 'Uint8Array': return DefaultClone(schema, references, value) // -------------------------------------------------------------- // Default // -------------------------------------------------------------- default: return Default(schema_, references_, value) } } // ------------------------------------------------------------------ // Cast // ------------------------------------------------------------------ /** Casts a value into a given type and references. The return value will retain as much information of the original value as possible. */ export function Cast(schema: T, references: TSchema[], value: unknown): Static /** Casts a value into a given type. The return value will retain as much information of the original value as possible. */ export function Cast(schema: T, value: unknown): Static /** Casts a value into a given type. The return value will retain as much information of the original value as possible. */ export function Cast(...args: any[]) { return args.length === 3 ? Visit(args[0], args[1], args[2]) : Visit(args[0], [], args[1]) } sinclairzx81-typebox-e0ec98c/src/value/cast/index.ts000066400000000000000000000024631505437577000226010ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './cast' sinclairzx81-typebox-e0ec98c/src/value/check/000077500000000000000000000000001505437577000212405ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/value/check/check.ts000066400000000000000000000514271505437577000226760ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { TypeSystemPolicy } from '../../system/index' import { Deref, Pushref } from '../deref/index' import { Hash } from '../hash/index' import { Kind } from '../../type/symbols/index' import { KeyOfPattern } from '../../type/keyof/index' import { ExtendsUndefinedCheck } from '../../type/extends/index' import { TypeRegistry, FormatRegistry } from '../../type/registry/index' import { TypeBoxError } from '../../type/error/index' import type { TSchema } from '../../type/schema/index' import type { TAny } from '../../type/any/index' import type { TArgument } from '../../type/argument/index' import type { TArray } from '../../type/array/index' import type { TAsyncIterator } from '../../type/async-iterator/index' import type { TBigInt } from '../../type/bigint/index' import type { TBoolean } from '../../type/boolean/index' import type { TDate } from '../../type/date/index' import type { TConstructor } from '../../type/constructor/index' import type { TFunction } from '../../type/function/index' import type { TInteger } from '../../type/integer/index' import type { TIntersect } from '../../type/intersect/index' import type { TIterator } from '../../type/iterator/index' import type { TLiteral } from '../../type/literal/index' import type { TImport } from '../../type/module/index' import { Never, type TNever } from '../../type/never/index' import type { TNot } from '../../type/not/index' import type { TNull } from '../../type/null/index' import type { TNumber } from '../../type/number/index' import type { TObject } from '../../type/object/index' import type { TPromise } from '../../type/promise/index' import type { TRecord } from '../../type/record/index' import type { TRef } from '../../type/ref/index' import type { TRegExp } from '../../type/regexp/index' import type { TTemplateLiteral } from '../../type/template-literal/index' import type { TThis } from '../../type/recursive/index' import type { TTuple } from '../../type/tuple/index' import type { TUnion } from '../../type/union/index' import type { TUnknown } from '../../type/unknown/index' import type { Static } from '../../type/static/index' import type { TString } from '../../type/string/index' import type { TSymbol } from '../../type/symbol/index' import type { TUndefined } from '../../type/undefined/index' import type { TUint8Array } from '../../type/uint8array/index' import type { TVoid } from '../../type/void/index' // ------------------------------------------------------------------ // ValueGuard // ------------------------------------------------------------------ import { IsArray, IsUint8Array, IsDate, IsPromise, IsFunction, IsAsyncIterator, IsIterator, IsBoolean, IsNumber, IsBigInt, IsString, IsSymbol, IsInteger, IsNull, IsUndefined } from '../guard/index' // ------------------------------------------------------------------ // KindGuard // ------------------------------------------------------------------ import { IsSchema } from '../../type/guard/kind' // ------------------------------------------------------------------ // Errors // ------------------------------------------------------------------ export class ValueCheckUnknownTypeError extends TypeBoxError { constructor(public readonly schema: TSchema) { super(`Unknown type`) } } // ------------------------------------------------------------------ // TypeGuards // ------------------------------------------------------------------ function IsAnyOrUnknown(schema: TSchema) { return schema[Kind] === 'Any' || schema[Kind] === 'Unknown' } // ------------------------------------------------------------------ // Guards // ------------------------------------------------------------------ function IsDefined(value: unknown): value is T { return value !== undefined } // ------------------------------------------------------------------ // Types // ------------------------------------------------------------------ function FromAny(schema: TAny, references: TSchema[], value: any): boolean { return true } function FromArgument(schema: TArgument, references: TSchema[], value: any): boolean { return true } function FromArray(schema: TArray, references: TSchema[], value: any): boolean { if (!IsArray(value)) return false if (IsDefined(schema.minItems) && !(value.length >= schema.minItems)) { return false } if (IsDefined(schema.maxItems) && !(value.length <= schema.maxItems)) { return false } if (!value.every((value) => Visit(schema.items, references, value))) { return false } // prettier-ignore if (schema.uniqueItems === true && !((function() { const set = new Set(); for(const element of value) { const hashed = Hash(element); if(set.has(hashed)) { return false } else { set.add(hashed) } } return true })())) { return false } // contains if (!(IsDefined(schema.contains) || IsNumber(schema.minContains) || IsNumber(schema.maxContains))) { return true // exit } const containsSchema = IsDefined(schema.contains) ? schema.contains : Never() const containsCount = value.reduce((acc: number, value) => (Visit(containsSchema, references, value) ? acc + 1 : acc), 0) if (containsCount === 0) { return false } if (IsNumber(schema.minContains) && containsCount < schema.minContains) { return false } if (IsNumber(schema.maxContains) && containsCount > schema.maxContains) { return false } return true } function FromAsyncIterator(schema: TAsyncIterator, references: TSchema[], value: any): boolean { return IsAsyncIterator(value) } function FromBigInt(schema: TBigInt, references: TSchema[], value: any): boolean { if (!IsBigInt(value)) return false if (IsDefined(schema.exclusiveMaximum) && !(value < schema.exclusiveMaximum)) { return false } if (IsDefined(schema.exclusiveMinimum) && !(value > schema.exclusiveMinimum)) { return false } if (IsDefined(schema.maximum) && !(value <= schema.maximum)) { return false } if (IsDefined(schema.minimum) && !(value >= schema.minimum)) { return false } if (IsDefined(schema.multipleOf) && !(value % schema.multipleOf === BigInt(0))) { return false } return true } function FromBoolean(schema: TBoolean, references: TSchema[], value: any): boolean { return IsBoolean(value) } function FromConstructor(schema: TConstructor, references: TSchema[], value: any): boolean { return Visit(schema.returns, references, value.prototype) } function FromDate(schema: TDate, references: TSchema[], value: any): boolean { if (!IsDate(value)) return false if (IsDefined(schema.exclusiveMaximumTimestamp) && !(value.getTime() < schema.exclusiveMaximumTimestamp)) { return false } if (IsDefined(schema.exclusiveMinimumTimestamp) && !(value.getTime() > schema.exclusiveMinimumTimestamp)) { return false } if (IsDefined(schema.maximumTimestamp) && !(value.getTime() <= schema.maximumTimestamp)) { return false } if (IsDefined(schema.minimumTimestamp) && !(value.getTime() >= schema.minimumTimestamp)) { return false } if (IsDefined(schema.multipleOfTimestamp) && !(value.getTime() % schema.multipleOfTimestamp === 0)) { return false } return true } function FromFunction(schema: TFunction, references: TSchema[], value: any): boolean { return IsFunction(value) } function FromImport(schema: TImport, references: TSchema[], value: any): boolean { const definitions = globalThis.Object.values(schema.$defs) as TSchema[] const target = schema.$defs[schema.$ref] as TSchema return Visit(target, [...references, ...definitions], value) } function FromInteger(schema: TInteger, references: TSchema[], value: any): boolean { if (!IsInteger(value)) { return false } if (IsDefined(schema.exclusiveMaximum) && !(value < schema.exclusiveMaximum)) { return false } if (IsDefined(schema.exclusiveMinimum) && !(value > schema.exclusiveMinimum)) { return false } if (IsDefined(schema.maximum) && !(value <= schema.maximum)) { return false } if (IsDefined(schema.minimum) && !(value >= schema.minimum)) { return false } if (IsDefined(schema.multipleOf) && !(value % schema.multipleOf === 0)) { return false } return true } function FromIntersect(schema: TIntersect, references: TSchema[], value: any): boolean { const check1 = schema.allOf.every((schema) => Visit(schema, references, value)) if (schema.unevaluatedProperties === false) { const keyPattern = new RegExp(KeyOfPattern(schema)) const check2 = Object.getOwnPropertyNames(value).every((key) => keyPattern.test(key)) return check1 && check2 } else if (IsSchema(schema.unevaluatedProperties)) { const keyCheck = new RegExp(KeyOfPattern(schema)) const check2 = Object.getOwnPropertyNames(value).every((key) => keyCheck.test(key) || Visit(schema.unevaluatedProperties as TSchema, references, value[key])) return check1 && check2 } else { return check1 } } function FromIterator(schema: TIterator, references: TSchema[], value: any): boolean { return IsIterator(value) } function FromLiteral(schema: TLiteral, references: TSchema[], value: any): boolean { return value === schema.const } function FromNever(schema: TNever, references: TSchema[], value: any): boolean { return false } function FromNot(schema: TNot, references: TSchema[], value: any): boolean { return !Visit(schema.not, references, value) } function FromNull(schema: TNull, references: TSchema[], value: any): boolean { return IsNull(value) } function FromNumber(schema: TNumber, references: TSchema[], value: any): boolean { if (!TypeSystemPolicy.IsNumberLike(value)) return false if (IsDefined(schema.exclusiveMaximum) && !(value < schema.exclusiveMaximum)) { return false } if (IsDefined(schema.exclusiveMinimum) && !(value > schema.exclusiveMinimum)) { return false } if (IsDefined(schema.minimum) && !(value >= schema.minimum)) { return false } if (IsDefined(schema.maximum) && !(value <= schema.maximum)) { return false } if (IsDefined(schema.multipleOf) && !(value % schema.multipleOf === 0)) { return false } return true } function FromObject(schema: TObject, references: TSchema[], value: any): boolean { if (!TypeSystemPolicy.IsObjectLike(value)) return false if (IsDefined(schema.minProperties) && !(Object.getOwnPropertyNames(value).length >= schema.minProperties)) { return false } if (IsDefined(schema.maxProperties) && !(Object.getOwnPropertyNames(value).length <= schema.maxProperties)) { return false } const knownKeys = Object.getOwnPropertyNames(schema.properties) for (const knownKey of knownKeys) { const property = schema.properties[knownKey] if (schema.required && schema.required.includes(knownKey)) { if (!Visit(property, references, value[knownKey])) { return false } if ((ExtendsUndefinedCheck(property) || IsAnyOrUnknown(property)) && !(knownKey in value)) { return false } } else { if (TypeSystemPolicy.IsExactOptionalProperty(value, knownKey) && !Visit(property, references, value[knownKey])) { return false } } } if (schema.additionalProperties === false) { const valueKeys = Object.getOwnPropertyNames(value) // optimization: value is valid if schemaKey length matches the valueKey length if (schema.required && schema.required.length === knownKeys.length && valueKeys.length === knownKeys.length) { return true } else { return valueKeys.every((valueKey) => knownKeys.includes(valueKey)) } } else if (typeof schema.additionalProperties === 'object') { const valueKeys = Object.getOwnPropertyNames(value) return valueKeys.every((key) => knownKeys.includes(key) || Visit(schema.additionalProperties as TSchema, references, value[key])) } else { return true } } function FromPromise(schema: TPromise, references: TSchema[], value: any): boolean { return IsPromise(value) } function FromRecord(schema: TRecord, references: TSchema[], value: any): boolean { if (!TypeSystemPolicy.IsRecordLike(value)) { return false } if (IsDefined(schema.minProperties) && !(Object.getOwnPropertyNames(value).length >= schema.minProperties)) { return false } if (IsDefined(schema.maxProperties) && !(Object.getOwnPropertyNames(value).length <= schema.maxProperties)) { return false } const [patternKey, patternSchema] = Object.entries(schema.patternProperties)[0] const regex = new RegExp(patternKey) // prettier-ignore const check1 = Object.entries(value).every(([key, value]) => { return (regex.test(key)) ? Visit(patternSchema, references, value) : true }) // prettier-ignore const check2 = typeof schema.additionalProperties === 'object' ? Object.entries(value).every(([key, value]) => { return (!regex.test(key)) ? Visit(schema.additionalProperties as TSchema, references, value) : true }) : true const check3 = schema.additionalProperties === false ? Object.getOwnPropertyNames(value).every((key) => { return regex.test(key) }) : true return check1 && check2 && check3 } function FromRef(schema: TRef, references: TSchema[], value: any): boolean { return Visit(Deref(schema, references), references, value) } function FromRegExp(schema: TRegExp, references: TSchema[], value: any): boolean { const regex = new RegExp(schema.source, schema.flags) if (IsDefined(schema.minLength)) { if (!(value.length >= schema.minLength)) return false } if (IsDefined(schema.maxLength)) { if (!(value.length <= schema.maxLength)) return false } return regex.test(value) } function FromString(schema: TString, references: TSchema[], value: any): boolean { if (!IsString(value)) { return false } if (IsDefined(schema.minLength)) { if (!(value.length >= schema.minLength)) return false } if (IsDefined(schema.maxLength)) { if (!(value.length <= schema.maxLength)) return false } if (IsDefined(schema.pattern)) { const regex = new RegExp(schema.pattern) if (!regex.test(value)) return false } if (IsDefined(schema.format)) { if (!FormatRegistry.Has(schema.format)) return false const func = FormatRegistry.Get(schema.format)! return func(value) } return true } function FromSymbol(schema: TSymbol, references: TSchema[], value: any): boolean { return IsSymbol(value) } function FromTemplateLiteral(schema: TTemplateLiteral, references: TSchema[], value: any): boolean { return IsString(value) && new RegExp(schema.pattern).test(value) } function FromThis(schema: TThis, references: TSchema[], value: any): boolean { return Visit(Deref(schema, references), references, value) } function FromTuple(schema: TTuple, references: TSchema[], value: any): boolean { if (!IsArray(value)) { return false } if (schema.items === undefined && !(value.length === 0)) { return false } if (!(value.length === schema.maxItems)) { return false } if (!schema.items) { return true } for (let i = 0; i < schema.items.length; i++) { if (!Visit(schema.items[i], references, value[i])) return false } return true } function FromUndefined(schema: TUndefined, references: TSchema[], value: any): boolean { return IsUndefined(value) } function FromUnion(schema: TUnion, references: TSchema[], value: any): boolean { return schema.anyOf.some((inner) => Visit(inner, references, value)) } function FromUint8Array(schema: TUint8Array, references: TSchema[], value: any): boolean { if (!IsUint8Array(value)) { return false } if (IsDefined(schema.maxByteLength) && !(value.length <= schema.maxByteLength)) { return false } if (IsDefined(schema.minByteLength) && !(value.length >= schema.minByteLength)) { return false } return true } function FromUnknown(schema: TUnknown, references: TSchema[], value: any): boolean { return true } function FromVoid(schema: TVoid, references: TSchema[], value: any): boolean { return TypeSystemPolicy.IsVoidLike(value) } function FromKind(schema: TSchema, references: TSchema[], value: unknown): boolean { if (!TypeRegistry.Has(schema[Kind])) return false const func = TypeRegistry.Get(schema[Kind])! return func(schema, value) } function Visit(schema: T, references: TSchema[], value: any): boolean { const references_ = IsDefined(schema.$id) ? Pushref(schema, references) : references const schema_ = schema as any switch (schema_[Kind]) { case 'Any': return FromAny(schema_, references_, value) case 'Argument': return FromArgument(schema_, references_, value) case 'Array': return FromArray(schema_, references_, value) case 'AsyncIterator': return FromAsyncIterator(schema_, references_, value) case 'BigInt': return FromBigInt(schema_, references_, value) case 'Boolean': return FromBoolean(schema_, references_, value) case 'Constructor': return FromConstructor(schema_, references_, value) case 'Date': return FromDate(schema_, references_, value) case 'Function': return FromFunction(schema_, references_, value) case 'Import': return FromImport(schema_, references_, value) case 'Integer': return FromInteger(schema_, references_, value) case 'Intersect': return FromIntersect(schema_, references_, value) case 'Iterator': return FromIterator(schema_, references_, value) case 'Literal': return FromLiteral(schema_, references_, value) case 'Never': return FromNever(schema_, references_, value) case 'Not': return FromNot(schema_, references_, value) case 'Null': return FromNull(schema_, references_, value) case 'Number': return FromNumber(schema_, references_, value) case 'Object': return FromObject(schema_, references_, value) case 'Promise': return FromPromise(schema_, references_, value) case 'Record': return FromRecord(schema_, references_, value) case 'Ref': return FromRef(schema_, references_, value) case 'RegExp': return FromRegExp(schema_, references_, value) case 'String': return FromString(schema_, references_, value) case 'Symbol': return FromSymbol(schema_, references_, value) case 'TemplateLiteral': return FromTemplateLiteral(schema_, references_, value) case 'This': return FromThis(schema_, references_, value) case 'Tuple': return FromTuple(schema_, references_, value) case 'Undefined': return FromUndefined(schema_, references_, value) case 'Union': return FromUnion(schema_, references_, value) case 'Uint8Array': return FromUint8Array(schema_, references_, value) case 'Unknown': return FromUnknown(schema_, references_, value) case 'Void': return FromVoid(schema_, references_, value) default: if (!TypeRegistry.Has(schema_[Kind])) throw new ValueCheckUnknownTypeError(schema_) return FromKind(schema_, references_, value) } } // -------------------------------------------------------------------------- // Check // -------------------------------------------------------------------------- /** Returns true if the value matches the given type. */ export function Check(schema: T, references: TSchema[], value: unknown): value is Static /** Returns true if the value matches the given type. */ export function Check(schema: T, value: unknown): value is Static /** Returns true if the value matches the given type. */ export function Check(...args: any[]) { return args.length === 3 ? Visit(args[0], args[1], args[2]) : Visit(args[0], [], args[1]) } sinclairzx81-typebox-e0ec98c/src/value/check/index.ts000066400000000000000000000024641505437577000227250ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './check' sinclairzx81-typebox-e0ec98c/src/value/clean/000077500000000000000000000000001505437577000212455ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/value/clean/clean.ts000066400000000000000000000211461505437577000227030ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { KeyOfPropertyKeys } from '../../type/keyof/index' import { Check } from '../check/index' import { Clone } from '../clone/index' import { Deref, Pushref } from '../deref/index' import { Kind } from '../../type/symbols/index' import type { TSchema } from '../../type/schema/index' import type { TArray } from '../../type/array/index' import type { TImport } from '../../type/module/index' import type { TIntersect } from '../../type/intersect/index' import type { TObject } from '../../type/object/index' import type { TRecord } from '../../type/record/index' import type { TRef } from '../../type/ref/index' import type { TThis } from '../../type/recursive/index' import type { TTuple } from '../../type/tuple/index' import type { TUnion } from '../../type/union/index' // ------------------------------------------------------------------ // ValueGuard // ------------------------------------------------------------------ // prettier-ignore import { HasPropertyKey, IsString, IsObject, IsArray, IsUndefined } from '../guard/index' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ // prettier-ignore import { IsKind } from '../../type/guard/kind' // ------------------------------------------------------------------ // IsCheckable // ------------------------------------------------------------------ function IsCheckable(schema: unknown): boolean { return IsKind(schema) && schema[Kind] !== 'Unsafe' } // ------------------------------------------------------------------ // Types // ------------------------------------------------------------------ function FromArray(schema: TArray, references: TSchema[], value: unknown): any { if (!IsArray(value)) return value return value.map((value) => Visit(schema.items, references, value)) } function FromImport(schema: TImport, references: TSchema[], value: unknown): any { const definitions = globalThis.Object.values(schema.$defs) as TSchema[] const target = schema.$defs[schema.$ref] as TSchema return Visit(target, [...references, ...definitions], value) } function FromIntersect(schema: TIntersect, references: TSchema[], value: unknown): any { const unevaluatedProperties = schema.unevaluatedProperties as TSchema const intersections = schema.allOf.map((schema) => Visit(schema, references, Clone(value))) const composite = intersections.reduce((acc: any, value: any) => (IsObject(value) ? { ...acc, ...value } : value), {}) if (!IsObject(value) || !IsObject(composite) || !IsKind(unevaluatedProperties)) return composite const knownkeys = KeyOfPropertyKeys(schema) as string[] for (const key of Object.getOwnPropertyNames(value)) { if (knownkeys.includes(key)) continue if (Check(unevaluatedProperties, references, value[key])) { composite[key] = Visit(unevaluatedProperties, references, value[key]) } } return composite } function FromObject(schema: TObject, references: TSchema[], value: unknown): any { if (!IsObject(value) || IsArray(value)) return value // Check IsArray for AllowArrayObject configuration const additionalProperties = schema.additionalProperties as TSchema for (const key of Object.getOwnPropertyNames(value)) { if (HasPropertyKey(schema.properties, key)) { value[key] = Visit(schema.properties[key], references, value[key]) continue } if (IsKind(additionalProperties) && Check(additionalProperties, references, value[key])) { value[key] = Visit(additionalProperties, references, value[key]) continue } delete value[key] } return value } function FromRecord(schema: TRecord, references: TSchema[], value: unknown): any { if (!IsObject(value)) return value const additionalProperties = schema.additionalProperties as TSchema const propertyKeys = Object.getOwnPropertyNames(value) const [propertyKey, propertySchema] = Object.entries(schema.patternProperties)[0] const propertyKeyTest = new RegExp(propertyKey) for (const key of propertyKeys) { if (propertyKeyTest.test(key)) { value[key] = Visit(propertySchema, references, value[key]) continue } if (IsKind(additionalProperties) && Check(additionalProperties, references, value[key])) { value[key] = Visit(additionalProperties, references, value[key]) continue } delete value[key] } return value } function FromRef(schema: TRef, references: TSchema[], value: unknown): any { return Visit(Deref(schema, references), references, value) } function FromThis(schema: TThis, references: TSchema[], value: unknown): any { return Visit(Deref(schema, references), references, value) } function FromTuple(schema: TTuple, references: TSchema[], value: unknown): any { if (!IsArray(value)) return value if (IsUndefined(schema.items)) return [] const length = Math.min(value.length, schema.items.length) for (let i = 0; i < length; i++) { value[i] = Visit(schema.items[i], references, value[i]) } // prettier-ignore return value.length > length ? value.slice(0, length) : value } function FromUnion(schema: TUnion, references: TSchema[], value: unknown): any { for (const inner of schema.anyOf) { if (IsCheckable(inner) && Check(inner, references, value)) { return Visit(inner, references, value) } } return value } function Visit(schema: TSchema, references: TSchema[], value: unknown): unknown { const references_ = IsString(schema.$id) ? Pushref(schema, references) : references const schema_ = schema as any switch (schema_[Kind]) { case 'Array': return FromArray(schema_, references_, value) case 'Import': return FromImport(schema_, references_, value) case 'Intersect': return FromIntersect(schema_, references_, value) case 'Object': return FromObject(schema_, references_, value) case 'Record': return FromRecord(schema_, references_, value) case 'Ref': return FromRef(schema_, references_, value) case 'This': return FromThis(schema_, references_, value) case 'Tuple': return FromTuple(schema_, references_, value) case 'Union': return FromUnion(schema_, references_, value) default: return value } } // ------------------------------------------------------------------ // Clean // ------------------------------------------------------------------ /** `[Mutable]` Removes excess properties from a value and returns the result. This function does not check the value and returns an unknown type. You should Check the result before use. Clean is a mutable operation. To avoid mutation, Clone the value first. */ export function Clean(schema: TSchema, references: TSchema[], value: unknown): unknown /** `[Mutable]` Removes excess properties from a value and returns the result. This function does not check the value and returns an unknown type. You should Check the result before use. Clean is a mutable operation. To avoid mutation, Clone the value first. */ export function Clean(schema: TSchema, value: unknown): unknown /** `[Mutable]` Removes excess properties from a value and returns the result. This function does not check the value and returns an unknown type. You should Check the result before use. Clean is a mutable operation. To avoid mutation, Clone the value first. */ export function Clean(...args: any[]) { return args.length === 3 ? Visit(args[0], args[1], args[2]) : Visit(args[0], [], args[1]) } sinclairzx81-typebox-e0ec98c/src/value/clean/index.ts000066400000000000000000000024641505437577000227320ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './clean' sinclairzx81-typebox-e0ec98c/src/value/clone/000077500000000000000000000000001505437577000212635ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/value/clone/clone.ts000066400000000000000000000063121505437577000227350ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { ObjectType as FromObject, ArrayType as FromArray, TypedArrayType, ValueType } from '../guard/index' // ------------------------------------------------------------------ // ValueGuard // ------------------------------------------------------------------ import { IsArray, IsDate, IsMap, IsSet, IsObject, IsTypedArray, IsValueType } from '../guard/index' // ------------------------------------------------------------------ // Clonable // ------------------------------------------------------------------ function FromObject(value: FromObject): any { const Acc = {} as Record for (const key of Object.getOwnPropertyNames(value)) { Acc[key] = Clone(value[key]) } for (const key of Object.getOwnPropertySymbols(value)) { Acc[key] = Clone(value[key]) } return Acc } function FromArray(value: FromArray): any { return value.map((element: any) => Clone(element)) } function FromTypedArray(value: TypedArrayType): any { return value.slice() } function FromMap(value: Map): any { return new Map(Clone([...value.entries()])) } function FromSet(value: Set): any { return new Set(Clone([...value.entries()])) } function FromDate(value: Date): any { return new Date(value.toISOString()) } function FromValue(value: ValueType): any { return value } // ------------------------------------------------------------------ // Clone // ------------------------------------------------------------------ /** Returns a clone of the given value */ export function Clone(value: T): T { if (IsArray(value)) return FromArray(value) if (IsDate(value)) return FromDate(value) if (IsTypedArray(value)) return FromTypedArray(value) if (IsMap(value)) return FromMap(value) if (IsSet(value)) return FromSet(value) if (IsObject(value)) return FromObject(value) if (IsValueType(value)) return FromValue(value) throw new Error('ValueClone: Unable to clone value') } sinclairzx81-typebox-e0ec98c/src/value/clone/index.ts000066400000000000000000000024641505437577000227500ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './clone' sinclairzx81-typebox-e0ec98c/src/value/convert/000077500000000000000000000000001505437577000216435ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/value/convert/convert.ts000066400000000000000000000344601505437577000237020ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { Clone } from '../clone/index' import { Check } from '../check/index' import { Deref, Pushref } from '../deref/index' import { Kind } from '../../type/symbols/index' import type { TSchema } from '../../type/schema/index' import type { TArray } from '../../type/array/index' import type { TBigInt } from '../../type/bigint/index' import type { TBoolean } from '../../type/boolean/index' import type { TDate } from '../../type/date/index' import type { TInteger } from '../../type/integer/index' import type { TIntersect } from '../../type/intersect/index' import type { TImport } from '../../type/module/index' import type { TLiteral } from '../../type/literal/index' import type { TNull } from '../../type/null/index' import type { TNumber } from '../../type/number/index' import type { TObject } from '../../type/object/index' import type { TRecord } from '../../type/record/index' import type { TRef } from '../../type/ref/index' import type { TThis } from '../../type/recursive/index' import type { TTuple } from '../../type/tuple/index' import type { TUnion } from '../../type/union/index' import type { TString } from '../../type/string/index' import type { TSymbol } from '../../type/symbol/index' import type { TUndefined } from '../../type/undefined/index' // ------------------------------------------------------------------ // ValueGuard // ------------------------------------------------------------------ import { IsArray, IsObject, IsDate, IsUndefined, IsString, IsNumber, IsBoolean, IsBigInt, IsSymbol, HasPropertyKey } from '../guard/index' // ------------------------------------------------------------------ // Conversions // ------------------------------------------------------------------ function IsStringNumeric(value: unknown): value is string { return IsString(value) && !isNaN(value as any) && !isNaN(parseFloat(value)) } function IsValueToString(value: unknown): value is { toString: () => string } { return IsBigInt(value) || IsBoolean(value) || IsNumber(value) } function IsValueTrue(value: unknown): value is true { return value === true || (IsNumber(value) && value === 1) || (IsBigInt(value) && value === BigInt('1')) || (IsString(value) && (value.toLowerCase() === 'true' || value === '1')) } function IsValueFalse(value: unknown): value is false { return value === false || (IsNumber(value) && (value === 0 || Object.is(value, -0))) || (IsBigInt(value) && value === BigInt('0')) || (IsString(value) && (value.toLowerCase() === 'false' || value === '0' || value === '-0')) } function IsTimeStringWithTimeZone(value: unknown): value is string { return IsString(value) && /^(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)$/i.test(value) } function IsTimeStringWithoutTimeZone(value: unknown): value is string { return IsString(value) && /^(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)?$/i.test(value) } function IsDateTimeStringWithTimeZone(value: unknown): value is string { return IsString(value) && /^\d\d\d\d-[0-1]\d-[0-3]\dt(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)$/i.test(value) } function IsDateTimeStringWithoutTimeZone(value: unknown): value is string { return IsString(value) && /^\d\d\d\d-[0-1]\d-[0-3]\dt(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)?$/i.test(value) } function IsDateString(value: unknown): value is string { return IsString(value) && /^\d\d\d\d-[0-1]\d-[0-3]\d$/i.test(value) } // ------------------------------------------------------------------ // Convert // ------------------------------------------------------------------ function TryConvertLiteralString(value: unknown, target: string) { const conversion = TryConvertString(value) return conversion === target ? conversion : value } function TryConvertLiteralNumber(value: unknown, target: number) { const conversion = TryConvertNumber(value) return conversion === target ? conversion : value } function TryConvertLiteralBoolean(value: unknown, target: boolean) { const conversion = TryConvertBoolean(value) return conversion === target ? conversion : value } // prettier-ignore function TryConvertLiteral(schema: TLiteral, value: unknown) { return ( IsString(schema.const) ? TryConvertLiteralString(value, schema.const) : IsNumber(schema.const) ? TryConvertLiteralNumber(value, schema.const) : IsBoolean(schema.const) ? TryConvertLiteralBoolean(value, schema.const) : value ) } function TryConvertBoolean(value: unknown) { return IsValueTrue(value) ? true : IsValueFalse(value) ? false : value } function TryConvertBigInt(value: unknown) { const truncateInteger = (value: string) => value.split('.')[0] return IsStringNumeric(value) ? BigInt(truncateInteger(value)) : IsNumber(value) ? BigInt(Math.trunc(value)) : IsValueFalse(value) ? BigInt(0) : IsValueTrue(value) ? BigInt(1) : value } function TryConvertString(value: unknown) { return IsSymbol(value) && value.description !== undefined ? value.description.toString() : IsValueToString(value) ? value.toString() : value } function TryConvertNumber(value: unknown) { return IsStringNumeric(value) ? parseFloat(value) : IsValueTrue(value) ? 1 : IsValueFalse(value) ? 0 : value } function TryConvertInteger(value: unknown) { return IsStringNumeric(value) ? parseInt(value) : IsNumber(value) ? Math.trunc(value) : IsValueTrue(value) ? 1 : IsValueFalse(value) ? 0 : value } function TryConvertNull(value: unknown) { return IsString(value) && value.toLowerCase() === 'null' ? null : value } function TryConvertUndefined(value: unknown) { return IsString(value) && value === 'undefined' ? undefined : value } // ------------------------------------------------------------------ // note: this function may return an invalid dates for the regex // tests above. Invalid dates will however be checked during the // casting function and will return a epoch date if invalid. // Consider better string parsing for the iso dates in future // revisions. // ------------------------------------------------------------------ // prettier-ignore function TryConvertDate(value: unknown) { return ( IsDate(value) ? value : IsNumber(value) ? new Date(value) : IsValueTrue(value) ? new Date(1) : IsValueFalse(value) ? new Date(0) : IsStringNumeric(value) ? new Date(parseInt(value)) : IsTimeStringWithoutTimeZone(value) ? new Date(`1970-01-01T${value}.000Z`) : IsTimeStringWithTimeZone(value) ? new Date(`1970-01-01T${value}`) : IsDateTimeStringWithoutTimeZone(value) ? new Date(`${value}.000Z`) : IsDateTimeStringWithTimeZone(value) ? new Date(value) : IsDateString(value) ? new Date(`${value}T00:00:00.000Z`) : value ) } // ------------------------------------------------------------------ // Default // ------------------------------------------------------------------ function Default(value: unknown): unknown { return value } // ------------------------------------------------------------------ // Convert // ------------------------------------------------------------------ function FromArray(schema: TArray, references: TSchema[], value: any): any { const elements = IsArray(value) ? value : [value] return elements.map((element) => Visit(schema.items, references, element)) } function FromBigInt(schema: TBigInt, references: TSchema[], value: any): unknown { return TryConvertBigInt(value) } function FromBoolean(schema: TBoolean, references: TSchema[], value: any): unknown { return TryConvertBoolean(value) } function FromDate(schema: TDate, references: TSchema[], value: any): unknown { return TryConvertDate(value) } function FromImport(schema: TImport, references: TSchema[], value: unknown): unknown { const definitions = globalThis.Object.values(schema.$defs) as TSchema[] const target = schema.$defs[schema.$ref] as TSchema return Visit(target, [...references, ...definitions], value) } function FromInteger(schema: TInteger, references: TSchema[], value: any): unknown { return TryConvertInteger(value) } function FromIntersect(schema: TIntersect, references: TSchema[], value: any): unknown { return schema.allOf.reduce((value, schema) => Visit(schema, references, value), value) } function FromLiteral(schema: TLiteral, references: TSchema[], value: any): unknown { return TryConvertLiteral(schema, value) } function FromNull(schema: TNull, references: TSchema[], value: any): unknown { return TryConvertNull(value) } function FromNumber(schema: TNumber, references: TSchema[], value: any): unknown { return TryConvertNumber(value) } // prettier-ignore function FromObject(schema: TObject, references: TSchema[], value: any): unknown { if(!IsObject(value) || IsArray(value)) return value for(const propertyKey of Object.getOwnPropertyNames(schema.properties)) { if(!HasPropertyKey(value, propertyKey)) continue value[propertyKey] = Visit(schema.properties[propertyKey], references, value[propertyKey]) } return value } function FromRecord(schema: TRecord, references: TSchema[], value: any): unknown { const isConvertable = IsObject(value) && !IsArray(value) if (!isConvertable) return value const propertyKey = Object.getOwnPropertyNames(schema.patternProperties)[0] const property = schema.patternProperties[propertyKey] for (const [propKey, propValue] of Object.entries(value)) { value[propKey] = Visit(property, references, propValue) } return value } function FromRef(schema: TRef, references: TSchema[], value: any): unknown { return Visit(Deref(schema, references), references, value) } function FromString(schema: TString, references: TSchema[], value: any): unknown { return TryConvertString(value) } function FromSymbol(schema: TSymbol, references: TSchema[], value: any): unknown { return IsString(value) || IsNumber(value) ? Symbol(value) : value } function FromThis(schema: TThis, references: TSchema[], value: any): unknown { return Visit(Deref(schema, references), references, value) } // prettier-ignore function FromTuple(schema: TTuple, references: TSchema[], value: any): unknown { const isConvertable = IsArray(value) && !IsUndefined(schema.items) if(!isConvertable) return value return value.map((value, index) => { return (index < schema.items!.length) ? Visit(schema.items![index], references, value) : value }) } function FromUndefined(schema: TUndefined, references: TSchema[], value: any): unknown { return TryConvertUndefined(value) } function FromUnion(schema: TUnion, references: TSchema[], value: any): unknown { // Check if original value already matches one of the union variants for (const subschema of schema.anyOf) { if (Check(subschema, references, value)) { return value } } // Attempt conversion for each variant for (const subschema of schema.anyOf) { const converted = Visit(subschema, references, Clone(value)) if (!Check(subschema, references, converted)) continue return converted } return value } function Visit(schema: TSchema, references: TSchema[], value: any): unknown { const references_ = Pushref(schema, references) const schema_ = schema as any switch (schema[Kind]) { case 'Array': return FromArray(schema_, references_, value) case 'BigInt': return FromBigInt(schema_, references_, value) case 'Boolean': return FromBoolean(schema_, references_, value) case 'Date': return FromDate(schema_, references_, value) case 'Import': return FromImport(schema_, references_, value) case 'Integer': return FromInteger(schema_, references_, value) case 'Intersect': return FromIntersect(schema_, references_, value) case 'Literal': return FromLiteral(schema_, references_, value) case 'Null': return FromNull(schema_, references_, value) case 'Number': return FromNumber(schema_, references_, value) case 'Object': return FromObject(schema_, references_, value) case 'Record': return FromRecord(schema_, references_, value) case 'Ref': return FromRef(schema_, references_, value) case 'String': return FromString(schema_, references_, value) case 'Symbol': return FromSymbol(schema_, references_, value) case 'This': return FromThis(schema_, references_, value) case 'Tuple': return FromTuple(schema_, references_, value) case 'Undefined': return FromUndefined(schema_, references_, value) case 'Union': return FromUnion(schema_, references_, value) default: return Default(value) } } // ------------------------------------------------------------------ // Convert // ------------------------------------------------------------------ /** `[Mutable]` Converts any type mismatched values to their target type if a reasonable conversion is possible. */ export function Convert(schema: TSchema, references: TSchema[], value: unknown): unknown /** `[Mutable]` Converts any type mismatched values to their target type if a reasonable conversion is possible. */ export function Convert(schema: TSchema, value: unknown): unknown /** `[Mutable]` Converts any type mismatched values to their target type if a reasonable conversion is possible. */ // prettier-ignore export function Convert(...args: any[]) { return args.length === 3 ? Visit(args[0], args[1], args[2]) : Visit(args[0], [], args[1]) } sinclairzx81-typebox-e0ec98c/src/value/convert/index.ts000066400000000000000000000024661505437577000233320ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './convert' sinclairzx81-typebox-e0ec98c/src/value/create/000077500000000000000000000000001505437577000214265ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/value/create/create.ts000066400000000000000000000434111505437577000232440ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { HasPropertyKey } from '../guard/index' import { Check } from '../check/index' import { Clone } from '../clone/index' import { Deref, Pushref } from '../deref/index' import { TemplateLiteralGenerate, IsTemplateLiteralFinite } from '../../type/template-literal/index' import { PatternStringExact, PatternNumberExact } from '../../type/patterns/index' import { TypeRegistry } from '../../type/registry/index' import { Kind } from '../../type/symbols/index' import { TypeBoxError } from '../../type/error/index' import type { TSchema } from '../../type/schema/index' import type { TAsyncIterator } from '../../type/async-iterator/index' import type { TAny } from '../../type/any/index' import type { TArray } from '../../type/array/index' import type { TBigInt } from '../../type/bigint/index' import type { TBoolean } from '../../type/boolean/index' import type { TDate } from '../../type/date/index' import type { TConstructor } from '../../type/constructor/index' import type { TFunction } from '../../type/function/index' import type { TImport } from '../../type/module/index' import type { TInteger } from '../../type/integer/index' import type { TIntersect } from '../../type/intersect/index' import type { TIterator } from '../../type/iterator/index' import type { TLiteral } from '../../type/literal/index' import type { TNever } from '../../type/never/index' import type { TNot } from '../../type/not/index' import type { TNull } from '../../type/null/index' import type { TNumber } from '../../type/number/index' import type { TObject } from '../../type/object/index' import type { TPromise } from '../../type/promise/index' import type { TRecord } from '../../type/record/index' import type { TRef } from '../../type/ref/index' import type { TRegExp } from '../../type/regexp/index' import type { TTemplateLiteral } from '../../type/template-literal/index' import type { TThis } from '../../type/recursive/index' import type { TTuple } from '../../type/tuple/index' import type { TUnion } from '../../type/union/index' import type { TUnknown } from '../../type/unknown/index' import type { Static } from '../../type/static/index' import type { TString } from '../../type/string/index' import type { TSymbol } from '../../type/symbol/index' import type { TUndefined } from '../../type/undefined/index' import type { TUint8Array } from '../../type/uint8array/index' import type { TVoid } from '../../type/void/index' import { IsFunction } from '../guard/guard' // ------------------------------------------------------------------ // Errors // ------------------------------------------------------------------ export class ValueCreateError extends TypeBoxError { constructor(public readonly schema: TSchema, message: string) { super(message) } } // ------------------------------------------------------------------ // Default // ------------------------------------------------------------------ function FromDefault(value: unknown) { return IsFunction(value) ? value() : Clone(value) } // ------------------------------------------------------------------ // Create // ------------------------------------------------------------------ function FromAny(schema: TAny, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else { return {} } } function FromArgument(schema: TAny, references: TSchema[]): any { return {} } function FromArray(schema: TArray, references: TSchema[]): any { if (schema.uniqueItems === true && !HasPropertyKey(schema, 'default')) { throw new ValueCreateError(schema, 'Array with the uniqueItems constraint requires a default value') } else if ('contains' in schema && !HasPropertyKey(schema, 'default')) { throw new ValueCreateError(schema, 'Array with the contains constraint requires a default value') } else if ('default' in schema) { return FromDefault(schema.default) } else if (schema.minItems !== undefined) { return Array.from({ length: schema.minItems }).map((item) => { return Visit(schema.items, references) }) } else { return [] } } function FromAsyncIterator(schema: TAsyncIterator, references: TSchema[]) { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else { return (async function* () {})() } } function FromBigInt(schema: TBigInt, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else { return BigInt(0) } } function FromBoolean(schema: TBoolean, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else { return false } } function FromConstructor(schema: TConstructor, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else { const value = Visit(schema.returns, references) as any if (typeof value === 'object' && !Array.isArray(value)) { return class { constructor() { for (const [key, val] of Object.entries(value)) { const self = this as any self[key] = val } } } } else { return class {} } } } function FromDate(schema: TDate, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else if (schema.minimumTimestamp !== undefined) { return new Date(schema.minimumTimestamp) } else { return new Date() } } function FromFunction(schema: TFunction, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else { return () => Visit(schema.returns, references) } } function FromImport(schema: TImport, references: TSchema[]): any { const definitions = globalThis.Object.values(schema.$defs) as TSchema[] const target = schema.$defs[schema.$ref] as TSchema return Visit(target, [...references, ...definitions]) } function FromInteger(schema: TInteger, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else if (schema.minimum !== undefined) { return schema.minimum } else { return 0 } } function FromIntersect(schema: TIntersect, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else { // -------------------------------------------------------------- // Note: The best we can do here is attempt to instance each // sub type and apply through object assign. For non-object // sub types, we just escape the assignment and just return // the value. In the latter case, this is typically going to // be a consequence of an illogical intersection. // -------------------------------------------------------------- const value = schema.allOf.reduce((acc, schema) => { const next = Visit(schema, references) as any return typeof next === 'object' ? { ...acc, ...next } : next }, {}) if (!Check(schema, references, value)) throw new ValueCreateError(schema, 'Intersect produced invalid value. Consider using a default value.') return value } } function FromIterator(schema: TIterator, references: TSchema[]) { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else { return (function* () {})() } } function FromLiteral(schema: TLiteral, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else { return schema.const } } function FromNever(schema: TNever, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else { throw new ValueCreateError(schema, 'Never types cannot be created. Consider using a default value.') } } function FromNot(schema: TNot, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else { throw new ValueCreateError(schema, 'Not types must have a default value') } } function FromNull(schema: TNull, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else { return null } } function FromNumber(schema: TNumber, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else if (schema.minimum !== undefined) { return schema.minimum } else { return 0 } } function FromObject(schema: TObject, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else { const required = new Set(schema.required) const Acc = {} as Record for (const [key, subschema] of Object.entries(schema.properties)) { if (!required.has(key)) continue Acc[key] = Visit(subschema, references) } return Acc } } function FromPromise(schema: TPromise, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else { return Promise.resolve(Visit(schema.item, references)) } } function FromRecord(schema: TRecord, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else { return {} } } function FromRef(schema: TRef, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else { return Visit(Deref(schema, references), references) } } function FromRegExp(schema: TRegExp, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else { throw new ValueCreateError(schema, 'RegExp types cannot be created. Consider using a default value.') } } function FromString(schema: TString, references: TSchema[]): any { if (schema.pattern !== undefined) { if (!HasPropertyKey(schema, 'default')) { throw new ValueCreateError(schema, 'String types with patterns must specify a default value') } else { return FromDefault(schema.default) } } else if (schema.format !== undefined) { if (!HasPropertyKey(schema, 'default')) { throw new ValueCreateError(schema, 'String types with formats must specify a default value') } else { return FromDefault(schema.default) } } else { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else if (schema.minLength !== undefined) { // prettier-ignore return Array.from({ length: schema.minLength }).map(() => ' ').join('') } else { return '' } } } function FromSymbol(schema: TSymbol, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else if ('value' in schema) { return Symbol.for(schema.value) } else { return Symbol() } } function FromTemplateLiteral(schema: TTemplateLiteral, references: TSchema[]) { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } if (!IsTemplateLiteralFinite(schema)) throw new ValueCreateError(schema, 'Can only create template literals that produce a finite variants. Consider using a default value.') const generated = TemplateLiteralGenerate(schema) as string[] return generated[0] } function FromThis(schema: TThis, references: TSchema[]): any { if (recursiveDepth++ > recursiveMaxDepth) throw new ValueCreateError(schema, 'Cannot create recursive type as it appears possibly infinite. Consider using a default.') if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else { return Visit(Deref(schema, references), references) } } function FromTuple(schema: TTuple, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } if (schema.items === undefined) { return [] } else { return Array.from({ length: schema.minItems }).map((_, index) => Visit((schema.items as any[])[index], references)) } } function FromUndefined(schema: TUndefined, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else { return undefined } } function FromUnion(schema: TUnion, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else if (schema.anyOf.length === 0) { throw new Error('ValueCreate.Union: Cannot create Union with zero variants') } else { return Visit(schema.anyOf[0], references) } } function FromUint8Array(schema: TUint8Array, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else if (schema.minByteLength !== undefined) { return new Uint8Array(schema.minByteLength) } else { return new Uint8Array(0) } } function FromUnknown(schema: TUnknown, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else { return {} } } function FromVoid(schema: TVoid, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else { return void 0 } } function FromKind(schema: TSchema, references: TSchema[]): any { if (HasPropertyKey(schema, 'default')) { return FromDefault(schema.default) } else { throw new Error('User defined types must specify a default value') } } function Visit(schema: TSchema, references: TSchema[]): unknown { const references_ = Pushref(schema, references) const schema_ = schema as any switch (schema_[Kind]) { case 'Any': return FromAny(schema_, references_) case 'Argument': return FromArgument(schema_, references_) case 'Array': return FromArray(schema_, references_) case 'AsyncIterator': return FromAsyncIterator(schema_, references_) case 'BigInt': return FromBigInt(schema_, references_) case 'Boolean': return FromBoolean(schema_, references_) case 'Constructor': return FromConstructor(schema_, references_) case 'Date': return FromDate(schema_, references_) case 'Function': return FromFunction(schema_, references_) case 'Import': return FromImport(schema_, references_) case 'Integer': return FromInteger(schema_, references_) case 'Intersect': return FromIntersect(schema_, references_) case 'Iterator': return FromIterator(schema_, references_) case 'Literal': return FromLiteral(schema_, references_) case 'Never': return FromNever(schema_, references_) case 'Not': return FromNot(schema_, references_) case 'Null': return FromNull(schema_, references_) case 'Number': return FromNumber(schema_, references_) case 'Object': return FromObject(schema_, references_) case 'Promise': return FromPromise(schema_, references_) case 'Record': return FromRecord(schema_, references_) case 'Ref': return FromRef(schema_, references_) case 'RegExp': return FromRegExp(schema_, references_) case 'String': return FromString(schema_, references_) case 'Symbol': return FromSymbol(schema_, references_) case 'TemplateLiteral': return FromTemplateLiteral(schema_, references_) case 'This': return FromThis(schema_, references_) case 'Tuple': return FromTuple(schema_, references_) case 'Undefined': return FromUndefined(schema_, references_) case 'Union': return FromUnion(schema_, references_) case 'Uint8Array': return FromUint8Array(schema_, references_) case 'Unknown': return FromUnknown(schema_, references_) case 'Void': return FromVoid(schema_, references_) default: if (!TypeRegistry.Has(schema_[Kind])) throw new ValueCreateError(schema_, 'Unknown type') return FromKind(schema_, references_) } } // ------------------------------------------------------------------ // State // ------------------------------------------------------------------ const recursiveMaxDepth = 512 let recursiveDepth = 0 // ------------------------------------------------------------------ // Create // ------------------------------------------------------------------ /** Creates a value from the given schema and references */ export function Create(schema: T, references: TSchema[]): Static /** Creates a value from the given schema */ export function Create(schema: T): Static /** Creates a value from the given schema */ export function Create(...args: any[]) { recursiveDepth = 0 return args.length === 2 ? Visit(args[0], args[1]) : Visit(args[0], []) } sinclairzx81-typebox-e0ec98c/src/value/create/index.ts000066400000000000000000000024651505437577000231140ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './create' sinclairzx81-typebox-e0ec98c/src/value/decode/000077500000000000000000000000001505437577000214065ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/value/decode/decode.ts000066400000000000000000000045531505437577000232100ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { HasTransform, TransformDecode, TransformDecodeCheckError } from '../transform/index' import { Check } from '../check/index' import { Errors } from '../../errors/index' import type { TSchema } from '../../type/schema/index' import type { StaticDecode } from '../../type/static/index' /** Decodes a value or throws if error */ export function Decode, Result extends Static = Static>(schema: T, references: TSchema[], value: unknown): Result /** Decodes a value or throws if error */ export function Decode, Result extends Static = Static>(schema: T, value: unknown): Result /** Decodes a value or throws if error */ export function Decode(...args: any[]): any { const [schema, references, value] = args.length === 3 ? [args[0], args[1], args[2]] : [args[0], [], args[1]] if (!Check(schema, references, value)) throw new TransformDecodeCheckError(schema, value, Errors(schema, references, value).First()!) return HasTransform(schema, references) ? TransformDecode(schema, references, value) : value } sinclairzx81-typebox-e0ec98c/src/value/decode/index.ts000066400000000000000000000024651505437577000230740ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './decode' sinclairzx81-typebox-e0ec98c/src/value/default/000077500000000000000000000000001505437577000216075ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/value/default/default.ts000066400000000000000000000237241505437577000236130ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { Check } from '../check/index' import { Clone } from '../clone/index' import { Deref, Pushref } from '../deref/index' import { Kind } from '../../type/symbols/index' import type { TSchema } from '../../type/schema/index' import type { TArray } from '../../type/array/index' import type { TImport } from '../../type/module/index' import type { TIntersect } from '../../type/intersect/index' import type { TObject } from '../../type/object/index' import type { TRecord } from '../../type/record/index' import type { TRef } from '../../type/ref/index' import type { TThis } from '../../type/recursive/index' import type { TTuple } from '../../type/tuple/index' import type { TUnion } from '../../type/union/index' // ------------------------------------------------------------------ // ValueGuard // ------------------------------------------------------------------ import { IsArray, IsDate, IsFunction, IsObject, IsUndefined, HasPropertyKey } from '../guard/index' // ------------------------------------------------------------------ // TypeGuard // ------------------------------------------------------------------ import { IsKind } from '../../type/guard/kind' // ------------------------------------------------------------------ // ValueOrDefault // ------------------------------------------------------------------ function ValueOrDefault(schema: TSchema, value: unknown): unknown { const defaultValue = HasPropertyKey(schema, 'default') ? schema.default : undefined const clone = IsFunction(defaultValue) ? defaultValue() : Clone(defaultValue) return IsUndefined(value) ? clone : IsObject(value) && IsObject(clone) ? Object.assign(clone, value) : value } // ------------------------------------------------------------------ // HasDefaultProperty // ------------------------------------------------------------------ function HasDefaultProperty(schema: unknown): schema is TSchema { return IsKind(schema) && 'default' in schema } // ------------------------------------------------------------------ // Types // ------------------------------------------------------------------ function FromArray(schema: TArray, references: TSchema[], value: unknown): any { // if the value is an array, we attempt to initialize it's elements if (IsArray(value)) { for (let i = 0; i < value.length; i++) { value[i] = Visit(schema.items, references, value[i]) } return value } // ... otherwise use default initialization const defaulted = ValueOrDefault(schema, value) if (!IsArray(defaulted)) return defaulted for (let i = 0; i < defaulted.length; i++) { defaulted[i] = Visit(schema.items, references, defaulted[i]) } return defaulted } function FromDate(schema: TArray, references: TSchema[], value: unknown): any { // special case intercept for dates return IsDate(value) ? value : ValueOrDefault(schema, value) } function FromImport(schema: TImport, references: TSchema[], value: unknown): any { const definitions = globalThis.Object.values(schema.$defs) as TSchema[] const target = schema.$defs[schema.$ref] as TSchema return Visit(target, [...references, ...definitions], value) } function FromIntersect(schema: TIntersect, references: TSchema[], value: unknown): any { const defaulted = ValueOrDefault(schema, value) return schema.allOf.reduce((acc, schema) => { const next = Visit(schema, references, defaulted) return IsObject(next) ? { ...acc, ...next } : next }, {}) } function FromObject(schema: TObject, references: TSchema[], value: unknown): any { const defaulted = ValueOrDefault(schema, value) // return defaulted if (!IsObject(defaulted)) return defaulted const knownPropertyKeys = Object.getOwnPropertyNames(schema.properties) // properties for (const key of knownPropertyKeys) { // note: we need to traverse into the object and test if the return value // yielded a non undefined result. Here we interpret an undefined result as // a non assignable property and continue. const propertyValue = Visit(schema.properties[key], references, defaulted[key]) if (IsUndefined(propertyValue)) continue defaulted[key] = Visit(schema.properties[key], references, defaulted[key]) } // return if not additional properties if (!HasDefaultProperty(schema.additionalProperties)) return defaulted // additional properties for (const key of Object.getOwnPropertyNames(defaulted)) { if (knownPropertyKeys.includes(key)) continue defaulted[key] = Visit(schema.additionalProperties, references, defaulted[key]) } return defaulted } function FromRecord(schema: TRecord, references: TSchema[], value: unknown): any { const defaulted = ValueOrDefault(schema, value) if (!IsObject(defaulted)) return defaulted const additionalPropertiesSchema = schema.additionalProperties as TSchema const [propertyKeyPattern, propertySchema] = Object.entries(schema.patternProperties)[0] const knownPropertyKey = new RegExp(propertyKeyPattern) // properties for (const key of Object.getOwnPropertyNames(defaulted)) { if (!(knownPropertyKey.test(key) && HasDefaultProperty(propertySchema))) continue defaulted[key] = Visit(propertySchema, references, defaulted[key]) } // return if not additional properties if (!HasDefaultProperty(additionalPropertiesSchema)) return defaulted // additional properties for (const key of Object.getOwnPropertyNames(defaulted)) { if (knownPropertyKey.test(key)) continue defaulted[key] = Visit(additionalPropertiesSchema, references, defaulted[key]) } return defaulted } function FromRef(schema: TRef, references: TSchema[], value: unknown): any { return Visit(Deref(schema, references), references, ValueOrDefault(schema, value)) } function FromThis(schema: TThis, references: TSchema[], value: unknown): any { return Visit(Deref(schema, references), references, value) } function FromTuple(schema: TTuple, references: TSchema[], value: unknown): any { const defaulted = ValueOrDefault(schema, value) if (!IsArray(defaulted) || IsUndefined(schema.items)) return defaulted const [items, max] = [schema.items!, Math.max(schema.items!.length, defaulted.length)] for (let i = 0; i < max; i++) { if (i < items.length) defaulted[i] = Visit(items[i], references, defaulted[i]) } return defaulted } function FromUnion(schema: TUnion, references: TSchema[], value: unknown): any { const defaulted = ValueOrDefault(schema, value) for (const inner of schema.anyOf) { const result = Visit(inner, references, Clone(defaulted)) if (Check(inner, references, result)) { return result } } return defaulted } function Visit(schema: TSchema, references: TSchema[], value: unknown): any { const references_ = Pushref(schema, references) const schema_ = schema as any switch (schema_[Kind]) { case 'Array': return FromArray(schema_, references_, value) case 'Date': return FromDate(schema_, references_, value) case 'Import': return FromImport(schema_, references_, value) case 'Intersect': return FromIntersect(schema_, references_, value) case 'Object': return FromObject(schema_, references_, value) case 'Record': return FromRecord(schema_, references_, value) case 'Ref': return FromRef(schema_, references_, value) case 'This': return FromThis(schema_, references_, value) case 'Tuple': return FromTuple(schema_, references_, value) case 'Union': return FromUnion(schema_, references_, value) default: return ValueOrDefault(schema_, value) } } // ------------------------------------------------------------------ // Default // ------------------------------------------------------------------ /** `[Mutable]` Generates missing properties on a value using default schema annotations if available. This function does not check the value and returns an unknown type. You should Check the result before use. Default is a mutable operation. To avoid mutation, Clone the value first. */ export function Default(schema: TSchema, references: TSchema[], value: unknown): unknown /** `[Mutable]` Generates missing properties on a value using default schema annotations if available. This function does not check the value and returns an unknown type. You should Check the result before use. Default is a mutable operation. To avoid mutation, Clone the value first. */ export function Default(schema: TSchema, value: unknown): unknown /** `[Mutable]` Generates missing properties on a value using default schema annotations if available. This function does not check the value and returns an unknown type. You should Check the result before use. Default is a mutable operation. To avoid mutation, Clone the value first. */ export function Default(...args: any[]) { return args.length === 3 ? Visit(args[0], args[1], args[2]) : Visit(args[0], [], args[1]) } sinclairzx81-typebox-e0ec98c/src/value/default/index.ts000066400000000000000000000024661505437577000232760ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './default' sinclairzx81-typebox-e0ec98c/src/value/delta/000077500000000000000000000000001505437577000212545ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/value/delta/delta.ts000066400000000000000000000210651505437577000227210ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { HasPropertyKey, IsStandardObject, IsArray, IsTypedArray, IsValueType } from '../guard/index' import type { ObjectType, ArrayType, TypedArrayType, ValueType } from '../guard/index' import type { Static } from '../../type/static/index' import { ValuePointer } from '../pointer/index' import { Clone } from '../clone/index' import { Equal } from '../equal/equal' import { TypeBoxError } from '../../type/error/index' import { Literal, type TLiteral } from '../../type/literal/index' import { Object, type TObject } from '../../type/object/index' import { String, type TString } from '../../type/string/index' import { Unknown, type TUnknown } from '../../type/unknown/index' import { Union, type TUnion } from '../../type/union/index' // ------------------------------------------------------------------ // Commands // ------------------------------------------------------------------ // Note: A TypeScript 5.4.2 compiler regression resulted in the type // import paths being generated incorrectly. We can resolve this by // explicitly importing the correct TSchema types above. Note also // that the left-side annotations are optional, but since the types // are imported we might as well use them. We should check this // regression in future. The regression occured between TypeScript // versions 5.3.3 -> 5.4.2. export type Insert = Static export const Insert: TObject<{ type: TLiteral<'insert'> path: TString value: TUnknown }> = Object({ type: Literal('insert'), path: String(), value: Unknown(), }) export type Update = Static export const Update: TObject<{ type: TLiteral<'update'> path: TString value: TUnknown }> = Object({ type: Literal('update'), path: String(), value: Unknown(), }) export type Delete = Static export const Delete: TObject<{ type: TLiteral<'delete'> path: TString }> = Object({ type: Literal('delete'), path: String(), }) export type Edit = Static export const Edit: TUnion<[typeof Insert, typeof Update, typeof Delete]> = Union([Insert, Update, Delete]) // ------------------------------------------------------------------ // Errors // ------------------------------------------------------------------ export class ValueDiffError extends TypeBoxError { constructor(public readonly value: unknown, message: string) { super(message) } } // ------------------------------------------------------------------ // Command Factory // ------------------------------------------------------------------ function CreateUpdate(path: string, value: unknown): Edit { return { type: 'update', path, value } } function CreateInsert(path: string, value: unknown): Edit { return { type: 'insert', path, value } } function CreateDelete(path: string): Edit { return { type: 'delete', path } } // ------------------------------------------------------------------ // AssertDiffable // ------------------------------------------------------------------ function AssertDiffable(value: unknown): asserts value is Record { if (globalThis.Object.getOwnPropertySymbols(value).length > 0) throw new ValueDiffError(value, 'Cannot diff objects with symbols') } // ------------------------------------------------------------------ // Diffing Generators // ------------------------------------------------------------------ function* ObjectType(path: string, current: ObjectType, next: unknown): IterableIterator { AssertDiffable(current) AssertDiffable(next) if (!IsStandardObject(next)) return yield CreateUpdate(path, next) const currentKeys = globalThis.Object.getOwnPropertyNames(current) const nextKeys = globalThis.Object.getOwnPropertyNames(next) // ---------------------------------------------------------------- // inserts // ---------------------------------------------------------------- for (const key of nextKeys) { if (HasPropertyKey(current, key)) continue yield CreateInsert(`${path}/${key}`, next[key]) } // ---------------------------------------------------------------- // updates // ---------------------------------------------------------------- for (const key of currentKeys) { if (!HasPropertyKey(next, key)) continue if (Equal(current, next)) continue yield* Visit(`${path}/${key}`, current[key], next[key]) } // ---------------------------------------------------------------- // deletes // ---------------------------------------------------------------- for (const key of currentKeys) { if (HasPropertyKey(next, key)) continue yield CreateDelete(`${path}/${key}`) } } function* ArrayType(path: string, current: ArrayType, next: unknown): IterableIterator { if (!IsArray(next)) return yield CreateUpdate(path, next) for (let i = 0; i < Math.min(current.length, next.length); i++) { yield* Visit(`${path}/${i}`, current[i], next[i]) } for (let i = 0; i < next.length; i++) { if (i < current.length) continue yield CreateInsert(`${path}/${i}`, next[i]) } for (let i = current.length - 1; i >= 0; i--) { if (i < next.length) continue yield CreateDelete(`${path}/${i}`) } } function* TypedArrayType(path: string, current: TypedArrayType, next: unknown): IterableIterator { if (!IsTypedArray(next) || current.length !== next.length || globalThis.Object.getPrototypeOf(current).constructor.name !== globalThis.Object.getPrototypeOf(next).constructor.name) return yield CreateUpdate(path, next) for (let i = 0; i < Math.min(current.length, next.length); i++) { yield* Visit(`${path}/${i}`, current[i], next[i]) } } function* ValueType(path: string, current: ValueType, next: unknown): IterableIterator { if (current === next) return yield CreateUpdate(path, next) } function* Visit(path: string, current: unknown, next: unknown): IterableIterator { if (IsStandardObject(current)) return yield* ObjectType(path, current, next) if (IsArray(current)) return yield* ArrayType(path, current, next) if (IsTypedArray(current)) return yield* TypedArrayType(path, current, next) if (IsValueType(current)) return yield* ValueType(path, current, next) throw new ValueDiffError(current, 'Unable to diff value') } // ------------------------------------------------------------------ // Diff // ------------------------------------------------------------------ export function Diff(current: unknown, next: unknown): Edit[] { return [...Visit('', current, next)] } // ------------------------------------------------------------------ // Patch // ------------------------------------------------------------------ function IsRootUpdate(edits: Edit[]): edits is [Update] { return edits.length > 0 && edits[0].path === '' && edits[0].type === 'update' } function IsIdentity(edits: Edit[]) { return edits.length === 0 } export function Patch(current: unknown, edits: Edit[]): T { if (IsRootUpdate(edits)) { return Clone(edits[0].value) as T } if (IsIdentity(edits)) { return Clone(current) as T } const clone = Clone(current) for (const edit of edits) { switch (edit.type) { case 'insert': { ValuePointer.Set(clone, edit.path, edit.value) break } case 'update': { ValuePointer.Set(clone, edit.path, edit.value) break } case 'delete': { ValuePointer.Delete(clone, edit.path) break } } } return clone as T } sinclairzx81-typebox-e0ec98c/src/value/delta/index.ts000066400000000000000000000024641505437577000227410ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './delta' sinclairzx81-typebox-e0ec98c/src/value/deref/000077500000000000000000000000001505437577000212505ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/value/deref/deref.ts000066400000000000000000000052061505437577000227100ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema } from '../../type/schema/index' import type { TRef } from '../../type/ref/index' import type { TThis } from '../../type/recursive/index' import { TypeBoxError } from '../../type/error/index' import { Kind } from '../../type/symbols/index' import { IsString } from '../guard/guard' export class TypeDereferenceError extends TypeBoxError { constructor(public readonly schema: TRef | TThis) { super(`Unable to dereference schema with $id '${schema.$ref}'`) } } function Resolve(schema: TThis | TRef, references: TSchema[]): TSchema { const target = references.find((target) => target.$id === schema.$ref) if (target === undefined) throw new TypeDereferenceError(schema) return Deref(target, references) } /** `[Internal]` Pushes a schema onto references if the schema has an $id and does not exist on references */ export function Pushref(schema: TSchema, references: TSchema[]): TSchema[] { if (!IsString(schema.$id) || references.some((target) => target.$id === schema.$id)) return references references.push(schema) return references } /** `[Internal]` Dereferences a schema from the references array or throws if not found */ export function Deref(schema: TSchema, references: TSchema[]): TSchema { // prettier-ignore return (schema[Kind] === 'This' || schema[Kind] === 'Ref') ? Resolve(schema as never, references) : schema } sinclairzx81-typebox-e0ec98c/src/value/deref/index.ts000066400000000000000000000024641505437577000227350ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './deref' sinclairzx81-typebox-e0ec98c/src/value/encode/000077500000000000000000000000001505437577000214205ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/value/encode/encode.ts000066400000000000000000000046131505437577000232310ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { HasTransform, TransformEncode, TransformEncodeCheckError } from '../transform/index' import { Check } from '../check/index' import { Errors } from '../../errors/index' import type { TSchema } from '../../type/schema/index' import type { StaticEncode } from '../../type/static/index' /** Encodes a value or throws if error */ export function Encode, Result extends Static = Static>(schema: T, references: TSchema[], value: unknown): Result /** Encodes a value or throws if error */ export function Encode, Result extends Static = Static>(schema: T, value: unknown): Result /** Encodes a value or throws if error */ export function Encode(...args: any[]): any { const [schema, references, value] = args.length === 3 ? [args[0], args[1], args[2]] : [args[0], [], args[1]] const encoded = HasTransform(schema, references) ? TransformEncode(schema, references, value) : value if (!Check(schema, references, encoded)) throw new TransformEncodeCheckError(schema, encoded, Errors(schema, references, encoded).First()!) return encoded } sinclairzx81-typebox-e0ec98c/src/value/encode/index.ts000066400000000000000000000024651505437577000231060ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './encode' sinclairzx81-typebox-e0ec98c/src/value/equal/000077500000000000000000000000001505437577000212725ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/value/equal/equal.ts000066400000000000000000000064101505437577000227520ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { IsObject, IsDate, IsArray, IsTypedArray, IsValueType } from '../guard/index' import type { ObjectType, ArrayType, TypedArrayType, ValueType } from '../guard/index' // ------------------------------------------------------------------ // Equality Checks // ------------------------------------------------------------------ function ObjectType(left: ObjectType, right: unknown): boolean { if (!IsObject(right)) return false const leftKeys = [...Object.keys(left), ...Object.getOwnPropertySymbols(left)] const rightKeys = [...Object.keys(right), ...Object.getOwnPropertySymbols(right)] if (leftKeys.length !== rightKeys.length) return false return leftKeys.every((key) => Equal(left[key], right[key])) } function DateType(left: Date, right: unknown): any { return IsDate(right) && left.getTime() === right.getTime() } function ArrayType(left: ArrayType, right: unknown): any { if (!IsArray(right) || left.length !== right.length) return false return left.every((value, index) => Equal(value, right[index])) } function TypedArrayType(left: TypedArrayType, right: unknown): any { if (!IsTypedArray(right) || left.length !== right.length || Object.getPrototypeOf(left).constructor.name !== Object.getPrototypeOf(right).constructor.name) return false return left.every((value, index) => Equal(value, right[index])) } function ValueType(left: ValueType, right: unknown): any { return left === right } // ------------------------------------------------------------------ // Equal // ------------------------------------------------------------------ /** Returns true if the left value deep-equals the right */ export function Equal(left: T, right: unknown): right is T { if (IsDate(left)) return DateType(left, right) if (IsTypedArray(left)) return TypedArrayType(left, right) if (IsArray(left)) return ArrayType(left, right) if (IsObject(left)) return ObjectType(left, right) if (IsValueType(left)) return ValueType(left, right) throw new Error('ValueEquals: Unable to compare value') } sinclairzx81-typebox-e0ec98c/src/value/equal/index.ts000066400000000000000000000024641505437577000227570ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './equal' sinclairzx81-typebox-e0ec98c/src/value/guard/000077500000000000000000000000001505437577000212655ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/value/guard/guard.ts000066400000000000000000000212261505437577000227420ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ // ------------------------------------------------------------------ // Types // ------------------------------------------------------------------ export type ObjectType = Record export type ArrayType = unknown[] export type ValueType = null | undefined | symbol | bigint | number | boolean | string // prettier-ignore export type TypedArrayType = | Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array // -------------------------------------------------------------------------- // Iterators // -------------------------------------------------------------------------- /** Returns true if this value is an async iterator */ export function IsAsyncIterator(value: unknown): value is AsyncIterableIterator { return IsObject(value) && globalThis.Symbol.asyncIterator in value } /** Returns true if this value is an iterator */ export function IsIterator(value: unknown): value is IterableIterator { return IsObject(value) && globalThis.Symbol.iterator in value } // -------------------------------------------------------------------------- // Object Instances // -------------------------------------------------------------------------- /** Returns true if this value is not an instance of a class */ export function IsStandardObject(value: unknown): value is ObjectType { return IsObject(value) && (globalThis.Object.getPrototypeOf(value) === Object.prototype || globalThis.Object.getPrototypeOf(value) === null) } /** Returns true if this value is an instance of a class */ export function IsInstanceObject(value: unknown): value is ObjectType { return IsObject(value) && !IsArray(value) && IsFunction(value.constructor) && value.constructor.name !== 'Object' } // -------------------------------------------------------------------------- // JavaScript // -------------------------------------------------------------------------- /** Returns true if this value is a Promise */ export function IsPromise(value: unknown): value is Promise { return value instanceof globalThis.Promise } /** Returns true if this value is a Date */ export function IsDate(value: unknown): value is Date { return value instanceof Date && globalThis.Number.isFinite(value.getTime()) } /** Returns true if this value is an instance of Map */ export function IsMap(value: unknown): value is Map { return value instanceof globalThis.Map } /** Returns true if this value is an instance of Set */ export function IsSet(value: unknown): value is Set { return value instanceof globalThis.Set } /** Returns true if this value is RegExp */ export function IsRegExp(value: unknown): value is RegExp { return value instanceof globalThis.RegExp } /** Returns true if this value is a typed array */ export function IsTypedArray(value: unknown): value is TypedArrayType { return globalThis.ArrayBuffer.isView(value) } /** Returns true if the value is a Int8Array */ export function IsInt8Array(value: unknown): value is Int8Array { return value instanceof globalThis.Int8Array } /** Returns true if the value is a Uint8Array */ export function IsUint8Array(value: unknown): value is Uint8Array { return value instanceof globalThis.Uint8Array } /** Returns true if the value is a Uint8ClampedArray */ export function IsUint8ClampedArray(value: unknown): value is Uint8ClampedArray { return value instanceof globalThis.Uint8ClampedArray } /** Returns true if the value is a Int16Array */ export function IsInt16Array(value: unknown): value is Int16Array { return value instanceof globalThis.Int16Array } /** Returns true if the value is a Uint16Array */ export function IsUint16Array(value: unknown): value is Uint16Array { return value instanceof globalThis.Uint16Array } /** Returns true if the value is a Int32Array */ export function IsInt32Array(value: unknown): value is Int32Array { return value instanceof globalThis.Int32Array } /** Returns true if the value is a Uint32Array */ export function IsUint32Array(value: unknown): value is Uint32Array { return value instanceof globalThis.Uint32Array } /** Returns true if the value is a Float32Array */ export function IsFloat32Array(value: unknown): value is Float32Array { return value instanceof globalThis.Float32Array } /** Returns true if the value is a Float64Array */ export function IsFloat64Array(value: unknown): value is Float64Array { return value instanceof globalThis.Float64Array } /** Returns true if the value is a BigInt64Array */ export function IsBigInt64Array(value: unknown): value is BigInt64Array { return value instanceof globalThis.BigInt64Array } /** Returns true if the value is a BigUint64Array */ export function IsBigUint64Array(value: unknown): value is BigUint64Array { return value instanceof globalThis.BigUint64Array } // -------------------------------------------------------------------------- // PropertyKey // -------------------------------------------------------------------------- /** Returns true if this value has this property key */ export function HasPropertyKey(value: Record, key: K): value is Record & { [_ in K]: unknown } { return key in value } // -------------------------------------------------------------------------- // Standard // -------------------------------------------------------------------------- /** Returns true of this value is an object type */ export function IsObject(value: unknown): value is ObjectType { return value !== null && typeof value === 'object' } /** Returns true if this value is an array, but not a typed array */ export function IsArray(value: unknown): value is ArrayType { return globalThis.Array.isArray(value) && !globalThis.ArrayBuffer.isView(value) } /** Returns true if this value is an undefined */ export function IsUndefined(value: unknown): value is undefined { return value === undefined } /** Returns true if this value is an null */ export function IsNull(value: unknown): value is null { return value === null } /** Returns true if this value is an boolean */ export function IsBoolean(value: unknown): value is boolean { return typeof value === 'boolean' } /** Returns true if this value is an number */ export function IsNumber(value: unknown): value is number { return typeof value === 'number' } /** Returns true if this value is an integer */ export function IsInteger(value: unknown): value is number { return globalThis.Number.isInteger(value) } /** Returns true if this value is bigint */ export function IsBigInt(value: unknown): value is bigint { return typeof value === 'bigint' } /** Returns true if this value is string */ export function IsString(value: unknown): value is string { return typeof value === 'string' } /** Returns true if this value is a function */ export function IsFunction(value: unknown): value is Function { return typeof value === 'function' } /** Returns true if this value is a symbol */ export function IsSymbol(value: unknown): value is symbol { return typeof value === 'symbol' } /** Returns true if this value is a value type such as number, string, boolean */ export function IsValueType(value: unknown): value is ValueType { // prettier-ignore return ( IsBigInt(value) || IsBoolean(value) || IsNull(value) || IsNumber(value) || IsString(value) || IsSymbol(value) || IsUndefined(value) ) } sinclairzx81-typebox-e0ec98c/src/value/guard/index.ts000066400000000000000000000024641505437577000227520ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './guard' sinclairzx81-typebox-e0ec98c/src/value/hash/000077500000000000000000000000001505437577000211065ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/value/hash/hash.ts000066400000000000000000000127241505437577000224070ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { IsArray, IsBoolean, IsBigInt, IsDate, IsNull, IsNumber, IsObject, IsString, IsSymbol, IsUint8Array, IsUndefined } from '../guard/index' import { TypeBoxError } from '../../type/error/index' // ------------------------------------------------------------------ // Errors // ------------------------------------------------------------------ export class ValueHashError extends TypeBoxError { constructor(public readonly value: unknown) { super(`Unable to hash value`) } } // ------------------------------------------------------------------ // ByteMarker // ------------------------------------------------------------------ enum ByteMarker { Undefined, Null, Boolean, Number, String, Object, Array, Date, Uint8Array, Symbol, BigInt, } // ------------------------------------------------------------------ // State // ------------------------------------------------------------------ let Accumulator = BigInt('14695981039346656037') const [Prime, Size] = [BigInt('1099511628211'), BigInt('18446744073709551616' /* 2 ^ 64 */)] const Bytes = Array.from({ length: 256 }).map((_, i) => BigInt(i)) const F64 = new Float64Array(1) const F64In = new DataView(F64.buffer) const F64Out = new Uint8Array(F64.buffer) // ------------------------------------------------------------------ // NumberToBytes // ------------------------------------------------------------------ function* NumberToBytes(value: number): IterableIterator { const byteCount = value === 0 ? 1 : Math.ceil(Math.floor(Math.log2(value) + 1) / 8) for (let i = 0; i < byteCount; i++) { yield (value >> (8 * (byteCount - 1 - i))) & 0xff } } // ------------------------------------------------------------------ // Hashing Functions // ------------------------------------------------------------------ function ArrayType(value: Array) { FNV1A64(ByteMarker.Array) for (const item of value) { Visit(item) } } function BooleanType(value: boolean) { FNV1A64(ByteMarker.Boolean) FNV1A64(value ? 1 : 0) } function BigIntType(value: bigint) { FNV1A64(ByteMarker.BigInt) F64In.setBigInt64(0, value) for (const byte of F64Out) { FNV1A64(byte) } } function DateType(value: Date) { FNV1A64(ByteMarker.Date) Visit(value.getTime()) } function NullType(value: null) { FNV1A64(ByteMarker.Null) } function NumberType(value: number) { FNV1A64(ByteMarker.Number) F64In.setFloat64(0, value) for (const byte of F64Out) { FNV1A64(byte) } } function ObjectType(value: Record) { FNV1A64(ByteMarker.Object) for (const key of globalThis.Object.getOwnPropertyNames(value).sort()) { Visit(key) Visit(value[key]) } } function StringType(value: string) { FNV1A64(ByteMarker.String) for (let i = 0; i < value.length; i++) { for (const byte of NumberToBytes(value.charCodeAt(i))) { FNV1A64(byte) } } } function SymbolType(value: symbol) { FNV1A64(ByteMarker.Symbol) Visit(value.description) } function Uint8ArrayType(value: Uint8Array) { FNV1A64(ByteMarker.Uint8Array) for (let i = 0; i < value.length; i++) { FNV1A64(value[i]) } } function UndefinedType(value: undefined) { return FNV1A64(ByteMarker.Undefined) } function Visit(value: any) { if (IsArray(value)) return ArrayType(value) if (IsBoolean(value)) return BooleanType(value) if (IsBigInt(value)) return BigIntType(value) if (IsDate(value)) return DateType(value) if (IsNull(value)) return NullType(value) if (IsNumber(value)) return NumberType(value) if (IsObject(value)) return ObjectType(value) if (IsString(value)) return StringType(value) if (IsSymbol(value)) return SymbolType(value) if (IsUint8Array(value)) return Uint8ArrayType(value) if (IsUndefined(value)) return UndefinedType(value) throw new ValueHashError(value) } function FNV1A64(byte: number) { Accumulator = Accumulator ^ Bytes[byte] Accumulator = (Accumulator * Prime) % Size } // ------------------------------------------------------------------ // Hash // ------------------------------------------------------------------ /** Creates a FNV1A-64 non cryptographic hash of the given value */ export function Hash(value: unknown) { Accumulator = BigInt('14695981039346656037') Visit(value) return Accumulator } sinclairzx81-typebox-e0ec98c/src/value/hash/index.ts000066400000000000000000000024631505437577000225720ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './hash' sinclairzx81-typebox-e0ec98c/src/value/index.ts000066400000000000000000000050461505437577000216470ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ // ------------------------------------------------------------------ // Errors (re-export) // ------------------------------------------------------------------ export { ValueError, ValueErrorType, ValueErrorIterator } from '../errors/index' // ------------------------------------------------------------------ // Guards // ------------------------------------------------------------------ export * from './guard/index' // ------------------------------------------------------------------ // Operators // ------------------------------------------------------------------ export * from './assert/index' export * from './cast/index' export * from './check/index' export * from './clean/index' export * from './clone/index' export * from './convert/index' export * from './create/index' export * from './decode/index' export * from './default/index' export * from './delta/index' export * from './encode/index' export * from './equal/index' export * from './hash/index' export * from './mutate/index' export * from './parse/index' export * from './pointer/index' export * from './transform/index' // ------------------------------------------------------------------ // Namespace // ------------------------------------------------------------------ export { Value } from './value/index' sinclairzx81-typebox-e0ec98c/src/value/mutate/000077500000000000000000000000001505437577000214625ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/value/mutate/index.ts000066400000000000000000000024651505437577000231500ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './mutate' sinclairzx81-typebox-e0ec98c/src/value/mutate/mutate.ts000066400000000000000000000122221505437577000233300ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { IsObject, IsArray, IsTypedArray, IsValueType, type TypedArrayType } from '../guard/index' import { ValuePointer } from '../pointer/index' import { Clone } from '../clone/index' import { TypeBoxError } from '../../type/error/index' // ------------------------------------------------------------------ // IsStandardObject // ------------------------------------------------------------------ function IsStandardObject(value: unknown): value is Record { return IsObject(value) && !IsArray(value) } // ------------------------------------------------------------------ // Errors // ------------------------------------------------------------------ export class ValueMutateError extends TypeBoxError { constructor(message: string) { super(message) } } // ------------------------------------------------------------------ // Mutators // ------------------------------------------------------------------ export type Mutable = { [key: string]: unknown } | unknown[] function ObjectType(root: Mutable, path: string, current: unknown, next: Record) { if (!IsStandardObject(current)) { ValuePointer.Set(root, path, Clone(next)) } else { const currentKeys = Object.getOwnPropertyNames(current) const nextKeys = Object.getOwnPropertyNames(next) for (const currentKey of currentKeys) { if (!nextKeys.includes(currentKey)) { delete current[currentKey] } } for (const nextKey of nextKeys) { if (!currentKeys.includes(nextKey)) { current[nextKey] = null } } for (const nextKey of nextKeys) { Visit(root, `${path}/${nextKey}`, current[nextKey], next[nextKey]) } } } function ArrayType(root: Mutable, path: string, current: unknown, next: unknown[]) { if (!IsArray(current)) { ValuePointer.Set(root, path, Clone(next)) } else { for (let index = 0; index < next.length; index++) { Visit(root, `${path}/${index}`, current[index], next[index]) } current.splice(next.length) } } function TypedArrayType(root: Mutable, path: string, current: unknown, next: TypedArrayType) { if (IsTypedArray(current) && current.length === next.length) { for (let i = 0; i < current.length; i++) { current[i] = next[i] } } else { ValuePointer.Set(root, path, Clone(next)) } } function ValueType(root: Mutable, path: string, current: unknown, next: unknown) { if (current === next) return ValuePointer.Set(root, path, next) } function Visit(root: Mutable, path: string, current: unknown, next: unknown) { if (IsArray(next)) return ArrayType(root, path, current, next) if (IsTypedArray(next)) return TypedArrayType(root, path, current, next) if (IsStandardObject(next)) return ObjectType(root, path, current, next) if (IsValueType(next)) return ValueType(root, path, current, next) } // ------------------------------------------------------------------ // IsNonMutableValue // ------------------------------------------------------------------ function IsNonMutableValue(value: unknown): value is Mutable { return IsTypedArray(value) || IsValueType(value) } function IsMismatchedValue(current: unknown, next: unknown) { // prettier-ignore return ( (IsStandardObject(current) && IsArray(next)) || (IsArray(current) && IsStandardObject(next)) ) } // ------------------------------------------------------------------ // Mutate // ------------------------------------------------------------------ /** `[Mutable]` Performs a deep mutable value assignment while retaining internal references */ export function Mutate(current: Mutable, next: Mutable): void { if (IsNonMutableValue(current) || IsNonMutableValue(next)) throw new ValueMutateError('Only object and array types can be mutated at the root level') if (IsMismatchedValue(current, next)) throw new ValueMutateError('Cannot assign due type mismatch of assignable values') Visit(current, '', current, next) } sinclairzx81-typebox-e0ec98c/src/value/parse/000077500000000000000000000000001505437577000212755ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/value/parse/index.ts000066400000000000000000000024641505437577000227620ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './parse' sinclairzx81-typebox-e0ec98c/src/value/parse/parse.ts000066400000000000000000000143641505437577000227670ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { TypeBoxError } from '../../type/error/index' import { TransformDecode, TransformEncode, HasTransform } from '../transform/index' import { TSchema } from '../../type/schema/index' import { StaticDecode } from '../../type/static/index' import { Assert } from '../assert/index' import { Cast } from '../cast/index' import { Clean } from '../clean/index' import { Clone } from '../clone/index' import { Convert } from '../convert/index' import { Default } from '../default/index' // ------------------------------------------------------------------ // Guards // ------------------------------------------------------------------ import { IsArray, IsUndefined } from '../guard/index' // ------------------------------------------------------------------ // Error // ------------------------------------------------------------------ export class ParseError extends TypeBoxError { constructor(message: string) { super(message) } } // ------------------------------------------------------------------ // ParseRegistry // ------------------------------------------------------------------ export type TParseOperation = 'Assert' | 'Cast' | 'Clean' | 'Clone' | 'Convert' | 'Decode' | 'Default' | 'Encode' | ({} & string) export type TParseFunction = (type: TSchema, references: TSchema[], value: unknown) => unknown // prettier-ignore export namespace ParseRegistry { const registry = new Map([ ['Assert', (type, references, value: unknown) => { Assert(type, references, value); return value }], ['Cast', (type, references, value: unknown) => Cast(type, references, value)], ['Clean', (type, references, value: unknown) => Clean(type, references, value)], ['Clone', (_type, _references, value: unknown) => Clone(value)], ['Convert', (type, references, value: unknown) => Convert(type, references, value)], ['Decode', (type, references, value: unknown) => (HasTransform(type, references) ? TransformDecode(type, references, value) : value)], ['Default', (type, references, value: unknown) => Default(type, references, value)], ['Encode', (type, references, value: unknown) => (HasTransform(type, references) ? TransformEncode(type, references, value) : value)], ]) // Deletes an entry from the registry export function Delete(key: string): void { registry.delete(key) } // Sets an entry in the registry export function Set(key: string, callback: TParseFunction): void { registry.set(key, callback) } // Gets an entry in the registry export function Get(key: string): TParseFunction | undefined { return registry.get(key) } } // ------------------------------------------------------------------ // Default Parse Pipeline // ------------------------------------------------------------------ // prettier-ignore export const ParseDefault = [ 'Clone', 'Clean', 'Default', 'Convert', 'Assert', 'Decode' ] as const // ------------------------------------------------------------------ // ParseValue // ------------------------------------------------------------------ function ParseValue = StaticDecode>(operations: TParseOperation[], type: Type, references: TSchema[], value: unknown): Result { return operations.reduce((value, operationKey) => { const operation = ParseRegistry.Get(operationKey) if (IsUndefined(operation)) throw new ParseError(`Unable to find Parse operation '${operationKey}'`) return operation(type, references, value) }, value) as Result } // ------------------------------------------------------------------ // Parse // ------------------------------------------------------------------ /** Parses a value using the default parse pipeline. Will throws an `AssertError` if invalid. */ export function Parse, Result extends Output = Output>(schema: Type, references: TSchema[], value: unknown): Result /** Parses a value using the default parse pipeline. Will throws an `AssertError` if invalid. */ export function Parse, Result extends Output = Output>(schema: Type, value: unknown): Result /** Parses a value using the specified operations. */ export function Parse(operations: TParseOperation[], schema: Type, references: TSchema[], value: unknown): unknown /** Parses a value using the specified operations. */ export function Parse(operations: TParseOperation[], schema: Type, value: unknown): unknown /** Parses a value */ export function Parse(...args: any[]): unknown { // prettier-ignore const [operations, schema, references, value] = ( args.length === 4 ? [args[0], args[1], args[2], args[3]] : args.length === 3 ? IsArray(args[0]) ? [args[0], args[1], [], args[2]] : [ParseDefault, args[0], args[1], args[2]] : args.length === 2 ? [ParseDefault, args[0], [], args[1]] : (() => { throw new ParseError('Invalid Arguments') })() ) return ParseValue(operations, schema, references, value) } sinclairzx81-typebox-e0ec98c/src/value/pointer/000077500000000000000000000000001505437577000216435ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/value/pointer/index.ts000066400000000000000000000025061505437577000233250ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * as ValuePointer from './pointer' sinclairzx81-typebox-e0ec98c/src/value/pointer/pointer.ts000066400000000000000000000111771505437577000237020ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { TypeBoxError } from '../../type/error/index' // ------------------------------------------------------------------ // Errors // ------------------------------------------------------------------ export class ValuePointerRootSetError extends TypeBoxError { constructor(public readonly value: unknown, public readonly path: string, public readonly update: unknown) { super('Cannot set root value') } } export class ValuePointerRootDeleteError extends TypeBoxError { constructor(public readonly value: unknown, public readonly path: string) { super('Cannot delete root value') } } // ------------------------------------------------------------------ // ValuePointer // ------------------------------------------------------------------ /** Provides functionality to update values through RFC6901 string pointers */ // prettier-ignore function Escape(component: string) { return component.indexOf('~') === -1 ? component : component.replace(/~1/g, '/').replace(/~0/g, '~') } /** Formats the given pointer into navigable key components */ // prettier-ignore export function* Format(pointer: string): IterableIterator { if (pointer === '') return let [start, end] = [0, 0] for (let i = 0; i < pointer.length; i++) { const char = pointer.charAt(i) if (char === '/') { if (i === 0) { start = i + 1 } else { end = i yield Escape(pointer.slice(start, end)) start = i + 1 } } else { end = i } } yield Escape(pointer.slice(start)) } /** Sets the value at the given pointer. If the value at the pointer does not exist it is created */ // prettier-ignore export function Set(value: any, pointer: string, update: unknown): void { if (pointer === '') throw new ValuePointerRootSetError(value, pointer, update) let [owner, next, key] = [null as any, value, ''] for (const component of Format(pointer)) { if (next[component] === undefined) next[component] = {} owner = next next = next[component] key = component } owner[key] = update } /** Deletes a value at the given pointer */ // prettier-ignore export function Delete(value: any, pointer: string): void { if (pointer === '') throw new ValuePointerRootDeleteError(value, pointer) let [owner, next, key] = [null as any, value as any, ''] for (const component of Format(pointer)) { if (next[component] === undefined || next[component] === null) return owner = next next = next[component] key = component } if (Array.isArray(owner)) { const index = parseInt(key) owner.splice(index, 1) } else { delete owner[key] } } /** Returns true if a value exists at the given pointer */ // prettier-ignore export function Has(value: any, pointer: string): boolean { if (pointer === '') return true let [owner, next, key] = [null as any, value as any, ''] for (const component of Format(pointer)) { if (next[component] === undefined) return false owner = next next = next[component] key = component } return Object.getOwnPropertyNames(owner).includes(key) } /** Gets the value at the given pointer */ // prettier-ignore export function Get(value: any, pointer: string): any { if (pointer === '') return value let current = value for (const component of Format(pointer)) { if (current[component] === undefined) return undefined current = current[component] } return current } sinclairzx81-typebox-e0ec98c/src/value/transform/000077500000000000000000000000001505437577000221765ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/value/transform/decode.ts000066400000000000000000000260361505437577000240000ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { TypeSystemPolicy } from '../../system/policy' import { Kind, TransformKind } from '../../type/symbols/index' import { TypeBoxError } from '../../type/error/index' import { ValueError } from '../../errors/index' import { KeyOfPropertyKeys, KeyOfPropertyEntries } from '../../type/keyof/index' import { Deref, Pushref } from '../deref/index' import { Check } from '../check/index' import type { TSchema } from '../../type/schema/index' import type { TArray } from '../../type/array/index' import type { TImport } from '../../type/module/index' import type { TIntersect } from '../../type/intersect/index' import type { TNot } from '../../type/not/index' import type { TObject } from '../../type/object/index' import type { TRecord } from '../../type/record/index' import type { TRef } from '../../type/ref/index' import type { TThis } from '../../type/recursive/index' import type { TTuple } from '../../type/tuple/index' import type { TUnion } from '../../type/union/index' // ------------------------------------------------------------------ // ValueGuard // ------------------------------------------------------------------ import { HasPropertyKey, IsObject, IsArray, IsValueType, IsUndefined as IsUndefinedValue } from '../guard/index' // ------------------------------------------------------------------ // KindGuard // ------------------------------------------------------------------ import { IsTransform, IsSchema, IsUndefined } from '../../type/guard/kind' // ------------------------------------------------------------------ // Errors // ------------------------------------------------------------------ // thrown externally // prettier-ignore export class TransformDecodeCheckError extends TypeBoxError { constructor( public readonly schema: TSchema, public readonly value: unknown, public readonly error: ValueError ) { super(`Unable to decode value as it does not match the expected schema`) } } // prettier-ignore export class TransformDecodeError extends TypeBoxError { constructor( public readonly schema: TSchema, public readonly path: string, public readonly value: unknown, public readonly error: Error, ) { super(error instanceof Error ? error.message : 'Unknown error') } } // ------------------------------------------------------------------ // Decode // ------------------------------------------------------------------ // prettier-ignore function Default(schema: TSchema, path: string, value: any): unknown { try { return IsTransform(schema) ? schema[TransformKind].Decode(value) : value } catch (error) { throw new TransformDecodeError(schema, path, value, error as Error) } } // prettier-ignore function FromArray(schema: TArray, references: TSchema[], path: string, value: any): unknown { return (IsArray(value)) ? Default(schema, path, value.map((value: any, index) => Visit(schema.items, references, `${path}/${index}`, value))) : Default(schema, path, value) } // prettier-ignore function FromIntersect(schema: TIntersect, references: TSchema[], path: string, value: any): unknown { if (!IsObject(value) || IsValueType(value)) return Default(schema, path, value) const knownEntries = KeyOfPropertyEntries(schema) const knownKeys = knownEntries.map(entry => entry[0]) const knownProperties = { ...value } as Record for(const [knownKey, knownSchema] of knownEntries) if(knownKey in knownProperties) { knownProperties[knownKey] = Visit(knownSchema, references, `${path}/${knownKey}`, knownProperties[knownKey]) } if (!IsTransform(schema.unevaluatedProperties)) { return Default(schema, path, knownProperties) } const unknownKeys = Object.getOwnPropertyNames(knownProperties) const unevaluatedProperties = schema.unevaluatedProperties as TSchema const unknownProperties = { ...knownProperties } as Record for(const key of unknownKeys) if(!knownKeys.includes(key)) { unknownProperties[key] = Default(unevaluatedProperties, `${path}/${key}`, unknownProperties[key]) } return Default(schema, path, unknownProperties) } // prettier-ignore function FromImport(schema: TImport, references: TSchema[], path: string, value: unknown): unknown { const additional = globalThis.Object.values(schema.$defs) as TSchema[] const target = schema.$defs[schema.$ref] as TSchema const result = Visit(target, [...references, ...additional], path, value) return Default(schema, path, result) } function FromNot(schema: TNot, references: TSchema[], path: string, value: any): unknown { return Default(schema, path, Visit(schema.not, references, path, value)) } // prettier-ignore function FromObject(schema: TObject, references: TSchema[], path: string, value: any): unknown { if (!IsObject(value)) return Default(schema, path, value) const knownKeys = KeyOfPropertyKeys(schema) as string[] const knownProperties = { ...value } as Record for(const key of knownKeys) { if(!HasPropertyKey(knownProperties, key)) continue // if the property value is undefined, but the target is not, nor does it satisfy exact optional // property policy, then we need to continue. This is a special case for optional property handling // where a transforms wrapped in a optional modifiers should not run. if(IsUndefinedValue(knownProperties[key]) && ( !IsUndefined(schema.properties[key]) || TypeSystemPolicy.IsExactOptionalProperty(knownProperties, key) )) continue // decode property knownProperties[key] = Visit(schema.properties[key], references, `${path}/${key}`, knownProperties[key]) } if (!IsSchema(schema.additionalProperties)) { return Default(schema, path, knownProperties) } const unknownKeys = Object.getOwnPropertyNames(knownProperties) const additionalProperties = schema.additionalProperties as TSchema const unknownProperties = { ...knownProperties } as Record for(const key of unknownKeys) if(!knownKeys.includes(key)) { unknownProperties[key] = Default(additionalProperties, `${path}/${key}`, unknownProperties[key]) } return Default(schema, path, unknownProperties) } // prettier-ignore function FromRecord(schema: TRecord, references: TSchema[], path: string, value: any): unknown { if (!IsObject(value)) return Default(schema, path, value) const pattern = Object.getOwnPropertyNames(schema.patternProperties)[0] const knownKeys = new RegExp(pattern) const knownProperties = { ...value } as Record for(const key of Object.getOwnPropertyNames(value)) if(knownKeys.test(key)) { knownProperties[key] = Visit(schema.patternProperties[pattern], references, `${path}/${key}`, knownProperties[key]) } if (!IsSchema(schema.additionalProperties)) { return Default(schema, path, knownProperties) } const unknownKeys = Object.getOwnPropertyNames(knownProperties) const additionalProperties = schema.additionalProperties as TSchema const unknownProperties = {...knownProperties} as Record for(const key of unknownKeys) if(!knownKeys.test(key)) { unknownProperties[key] = Default(additionalProperties, `${path}/${key}`, unknownProperties[key]) } return Default(schema, path, unknownProperties) } // prettier-ignore function FromRef(schema: TRef, references: TSchema[], path: string, value: any): unknown { const target = Deref(schema, references) return Default(schema, path, Visit(target, references, path, value)) } // prettier-ignore function FromThis(schema: TThis, references: TSchema[], path: string, value: any): unknown { const target = Deref(schema, references) return Default(schema, path, Visit(target, references, path, value)) } // prettier-ignore function FromTuple(schema: TTuple, references: TSchema[], path: string, value: any): unknown { return (IsArray(value) && IsArray(schema.items)) ? Default(schema, path, schema.items.map((schema, index) => Visit(schema, references, `${path}/${index}`, value[index]))) : Default(schema, path, value) } // prettier-ignore function FromUnion(schema: TUnion, references: TSchema[], path: string, value: any): unknown { for (const subschema of schema.anyOf) { if (!Check(subschema, references, value)) continue // note: ensure interior is decoded first const decoded = Visit(subschema, references, path, value) return Default(schema, path, decoded) } return Default(schema, path, value) } // prettier-ignore function Visit(schema: TSchema, references: TSchema[], path: string, value: any): any { const references_ = Pushref(schema, references) const schema_ = schema as any switch (schema[Kind]) { case 'Array': return FromArray(schema_, references_, path, value) case 'Import': return FromImport(schema_, references_, path, value) case 'Intersect': return FromIntersect(schema_, references_, path, value) case 'Not': return FromNot(schema_, references_, path, value) case 'Object': return FromObject(schema_, references_, path, value) case 'Record': return FromRecord(schema_, references_, path, value) case 'Ref': return FromRef(schema_, references_, path, value) case 'Symbol': return Default(schema_, path, value) case 'This': return FromThis(schema_, references_, path, value) case 'Tuple': return FromTuple(schema_, references_, path, value) case 'Union': return FromUnion(schema_, references_, path, value) default: return Default(schema_, path, value) } } /** * `[Internal]` Decodes the value and returns the result. This function requires that * the caller `Check` the value before use. Passing unchecked values may result in * undefined behavior. Refer to the `Value.Decode()` for implementation details. */ export function TransformDecode(schema: TSchema, references: TSchema[], value: unknown): unknown { return Visit(schema, references, '', value) } sinclairzx81-typebox-e0ec98c/src/value/transform/encode.ts000066400000000000000000000261651505437577000240150ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { TypeSystemPolicy } from '../../system/policy' import { Kind, TransformKind } from '../../type/symbols/index' import { TypeBoxError } from '../../type/error/index' import { ValueError } from '../../errors/index' import { KeyOfPropertyKeys, KeyOfPropertyEntries } from '../../type/keyof/index' import { Deref, Pushref } from '../deref/index' import { Check } from '../check/index' import type { TSchema } from '../../type/schema/index' import type { TArray } from '../../type/array/index' import type { TImport } from '../../type/module/index' import type { TIntersect } from '../../type/intersect/index' import type { TNot } from '../../type/not/index' import type { TObject } from '../../type/object/index' import type { TRecord } from '../../type/record/index' import type { TRef } from '../../type/ref/index' import type { TThis } from '../../type/recursive/index' import type { TTuple } from '../../type/tuple/index' import type { TUnion } from '../../type/union/index' // ------------------------------------------------------------------ // ValueGuard // ------------------------------------------------------------------ import { HasPropertyKey, IsObject, IsArray, IsValueType, IsUndefined as IsUndefinedValue } from '../guard/index' // ------------------------------------------------------------------ // KindGuard // ------------------------------------------------------------------ import { IsTransform, IsSchema, IsUndefined } from '../../type/guard/kind' // ------------------------------------------------------------------ // Errors // ------------------------------------------------------------------ // prettier-ignore export class TransformEncodeCheckError extends TypeBoxError { constructor( public readonly schema: TSchema, public readonly value: unknown, public readonly error: ValueError ) { super(`The encoded value does not match the expected schema`) } } // prettier-ignore export class TransformEncodeError extends TypeBoxError { constructor( public readonly schema: TSchema, public readonly path: string, public readonly value: unknown, public readonly error: Error, ) { super(`${error instanceof Error ? error.message : 'Unknown error'}`) } } // ------------------------------------------------------------------ // Encode // ------------------------------------------------------------------ // prettier-ignore function Default(schema: TSchema, path: string, value: any) { try { return IsTransform(schema) ? schema[TransformKind].Encode(value) : value } catch (error) { throw new TransformEncodeError(schema, path, value, error as Error) } } // prettier-ignore function FromArray(schema: TArray, references: TSchema[], path: string, value: any): any { const defaulted = Default(schema, path, value) return IsArray(defaulted) ? defaulted.map((value: any, index) => Visit(schema.items, references, `${path}/${index}`, value)) : defaulted } // prettier-ignore function FromImport(schema: TImport, references: TSchema[], path: string, value: unknown): unknown { const additional = globalThis.Object.values(schema.$defs) as TSchema[] const target = schema.$defs[schema.$ref] as TSchema const result = Default(schema, path, value) return Visit(target, [...references, ...additional], path, result) } // prettier-ignore function FromIntersect(schema: TIntersect, references: TSchema[], path: string, value: any) { const defaulted = Default(schema, path, value) if (!IsObject(value) || IsValueType(value)) return defaulted const knownEntries = KeyOfPropertyEntries(schema) const knownKeys = knownEntries.map(entry => entry[0]) const knownProperties = { ...defaulted } as Record for(const [knownKey, knownSchema] of knownEntries) if(knownKey in knownProperties) { knownProperties[knownKey] = Visit(knownSchema, references, `${path}/${knownKey}`, knownProperties[knownKey]) } if (!IsTransform(schema.unevaluatedProperties)) { return knownProperties } const unknownKeys = Object.getOwnPropertyNames(knownProperties) const unevaluatedProperties = schema.unevaluatedProperties as TSchema const properties = { ...knownProperties } as Record for(const key of unknownKeys) if(!knownKeys.includes(key)) { properties[key] = Default(unevaluatedProperties, `${path}/${key}`, properties[key]) } return properties } // prettier-ignore function FromNot(schema: TNot, references: TSchema[], path: string, value: any) { return Default(schema.not, path, Default(schema, path, value)) } // prettier-ignore function FromObject(schema: TObject, references: TSchema[], path: string, value: any) { const defaulted = Default(schema, path, value) if (!IsObject(defaulted)) return defaulted const knownKeys = KeyOfPropertyKeys(schema) as string[] const knownProperties = { ...defaulted } as Record for(const key of knownKeys) { if(!HasPropertyKey(knownProperties, key)) continue // if the property value is undefined, but the target is not, nor does it satisfy exact optional // property policy, then we need to continue. This is a special case for optional property handling // where a transforms wrapped in a optional modifiers should not run. if(IsUndefinedValue(knownProperties[key]) && ( !IsUndefined(schema.properties[key]) || TypeSystemPolicy.IsExactOptionalProperty(knownProperties, key) )) continue // encode property knownProperties[key] = Visit(schema.properties[key], references, `${path}/${key}`, knownProperties[key]) } if (!IsSchema(schema.additionalProperties)) { return knownProperties } const unknownKeys = Object.getOwnPropertyNames(knownProperties) const additionalProperties = schema.additionalProperties as TSchema const properties = { ...knownProperties } as Record for(const key of unknownKeys) if(!knownKeys.includes(key)) { properties[key] = Default(additionalProperties, `${path}/${key}`, properties[key]) } return properties } // prettier-ignore function FromRecord(schema: TRecord, references: TSchema[], path: string, value: any) { const defaulted = Default(schema, path, value) as Record if (!IsObject(value)) return defaulted const pattern = Object.getOwnPropertyNames(schema.patternProperties)[0] const knownKeys = new RegExp(pattern) const knownProperties = {...defaulted } as Record for(const key of Object.getOwnPropertyNames(value)) if(knownKeys.test(key)) { knownProperties[key] = Visit(schema.patternProperties[pattern], references, `${path}/${key}`, knownProperties[key]) } if (!IsSchema(schema.additionalProperties)) { return knownProperties } const unknownKeys = Object.getOwnPropertyNames(knownProperties) const additionalProperties = schema.additionalProperties as TSchema const properties = { ...knownProperties } as Record for(const key of unknownKeys) if(!knownKeys.test(key)) { properties[key] = Default(additionalProperties, `${path}/${key}`, properties[key]) } return properties } // prettier-ignore function FromRef(schema: TRef, references: TSchema[], path: string, value: any) { const target = Deref(schema, references) const resolved = Visit(target, references, path, value) return Default(schema, path, resolved) } // prettier-ignore function FromThis(schema: TThis, references: TSchema[], path: string, value: any) { const target = Deref(schema, references) const resolved = Visit(target, references, path, value) return Default(schema, path, resolved) } // prettier-ignore function FromTuple(schema: TTuple, references: TSchema[], path: string, value: any) { const value1 = Default(schema, path, value) return IsArray(schema.items) ? schema.items.map((schema, index) => Visit(schema, references, `${path}/${index}`, value1[index])) : [] } // prettier-ignore function FromUnion(schema: TUnion, references: TSchema[], path: string, value: any) { // test value against union variants for (const subschema of schema.anyOf) { if (!Check(subschema, references, value)) continue const value1 = Visit(subschema, references, path, value) return Default(schema, path, value1) } // test transformed value against union variants for (const subschema of schema.anyOf) { const value1 = Visit(subschema, references, path, value) if (!Check(schema, references, value1)) continue return Default(schema, path, value1) } return Default(schema, path, value) } // prettier-ignore function Visit(schema: TSchema, references: TSchema[], path: string, value: any): any { const references_ = Pushref(schema, references) const schema_ = schema as any switch (schema[Kind]) { case 'Array': return FromArray(schema_, references_, path, value) case 'Import': return FromImport(schema_, references_, path, value) case 'Intersect': return FromIntersect(schema_, references_, path, value) case 'Not': return FromNot(schema_, references_, path, value) case 'Object': return FromObject(schema_, references_, path, value) case 'Record': return FromRecord(schema_, references_, path, value) case 'Ref': return FromRef(schema_, references_, path, value) case 'This': return FromThis(schema_, references_, path, value) case 'Tuple': return FromTuple(schema_, references_, path, value) case 'Union': return FromUnion(schema_, references_, path, value) default: return Default(schema_, path, value) } } /** * `[Internal]` Encodes the value and returns the result. This function expects the * caller to pass a statically checked value. This function does not check the encoded * result, meaning the result should be passed to `Check` before use. Refer to the * `Value.Encode()` function for implementation details. */ export function TransformEncode(schema: TSchema, references: TSchema[], value: unknown): unknown { return Visit(schema, references, '', value) } sinclairzx81-typebox-e0ec98c/src/value/transform/has.ts000066400000000000000000000164551505437577000233340ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { Deref, Pushref } from '../deref/index' import { Kind } from '../../type/symbols/index' import type { TSchema } from '../../type/schema/index' import type { TArray } from '../../type/array/index' import type { TAsyncIterator } from '../../type/async-iterator/index' import type { TConstructor } from '../../type/constructor/index' import type { TFunction } from '../../type/function/index' import type { TIntersect } from '../../type/intersect/index' import type { TIterator } from '../../type/iterator/index' import type { TImport } from '../../type/module/index' import type { TNot } from '../../type/not/index' import type { TObject } from '../../type/object/index' import type { TPromise } from '../../type/promise/index' import type { TRecord } from '../../type/record/index' import type { TRef } from '../../type/ref/index' import type { TThis } from '../../type/recursive/index' import type { TTuple } from '../../type/tuple/index' import type { TUnion } from '../../type/union/index' // ------------------------------------------------------------------ // KindGuard // ------------------------------------------------------------------ import { IsTransform, IsSchema } from '../../type/guard/kind' // ------------------------------------------------------------------ // ValueGuard // ------------------------------------------------------------------ import { IsUndefined } from '../guard/index' // prettier-ignore function FromArray(schema: TArray, references: TSchema[]): boolean { return IsTransform(schema) || Visit(schema.items, references) } // prettier-ignore function FromAsyncIterator(schema: TAsyncIterator, references: TSchema[]): boolean { return IsTransform(schema) || Visit(schema.items, references) } // prettier-ignore function FromConstructor(schema: TConstructor, references: TSchema[]) { return IsTransform(schema) || Visit(schema.returns, references) || schema.parameters.some((schema) => Visit(schema, references)) } // prettier-ignore function FromFunction(schema: TFunction, references: TSchema[]) { return IsTransform(schema) || Visit(schema.returns, references) || schema.parameters.some((schema) => Visit(schema, references)) } // prettier-ignore function FromIntersect(schema: TIntersect, references: TSchema[]) { return IsTransform(schema) || IsTransform(schema.unevaluatedProperties) || schema.allOf.some((schema) => Visit(schema, references)) } // prettier-ignore function FromImport(schema: TImport, references: TSchema[]) { const additional = globalThis.Object.getOwnPropertyNames(schema.$defs).reduce((result, key) => [...result, schema.$defs[key as never]], [] as TSchema[]) const target = schema.$defs[schema.$ref] return IsTransform(schema) || Visit(target, [...additional, ...references]) } // prettier-ignore function FromIterator(schema: TIterator, references: TSchema[]) { return IsTransform(schema) || Visit(schema.items, references) } // prettier-ignore function FromNot(schema: TNot, references: TSchema[]) { return IsTransform(schema) || Visit(schema.not, references) } // prettier-ignore function FromObject(schema: TObject, references: TSchema[]) { return ( IsTransform(schema) || Object.values(schema.properties).some((schema) => Visit(schema, references)) || ( IsSchema(schema.additionalProperties) && Visit(schema.additionalProperties, references) ) ) } // prettier-ignore function FromPromise(schema: TPromise, references: TSchema[]) { return IsTransform(schema) || Visit(schema.item, references) } // prettier-ignore function FromRecord(schema: TRecord, references: TSchema[]) { const pattern = Object.getOwnPropertyNames(schema.patternProperties)[0] const property = schema.patternProperties[pattern] return IsTransform(schema) || Visit(property, references) || (IsSchema(schema.additionalProperties) && IsTransform(schema.additionalProperties)) } // prettier-ignore function FromRef(schema: TRef, references: TSchema[]) { if (IsTransform(schema)) return true return Visit(Deref(schema, references), references) } // prettier-ignore function FromThis(schema: TThis, references: TSchema[]) { if (IsTransform(schema)) return true return Visit(Deref(schema, references), references) } // prettier-ignore function FromTuple(schema: TTuple, references: TSchema[]) { return IsTransform(schema) || (!IsUndefined(schema.items) && schema.items.some((schema) => Visit(schema, references))) } // prettier-ignore function FromUnion(schema: TUnion, references: TSchema[]) { return IsTransform(schema) || schema.anyOf.some((schema) => Visit(schema, references)) } // prettier-ignore function Visit(schema: TSchema, references: TSchema[]): boolean { const references_ = Pushref(schema, references) const schema_ = schema as any if (schema.$id && visited.has(schema.$id)) return false if (schema.$id) visited.add(schema.$id) switch (schema[Kind]) { case 'Array': return FromArray(schema_, references_) case 'AsyncIterator': return FromAsyncIterator(schema_, references_) case 'Constructor': return FromConstructor(schema_, references_) case 'Function': return FromFunction(schema_, references_) case 'Import': return FromImport(schema_, references_) case 'Intersect': return FromIntersect(schema_, references_) case 'Iterator': return FromIterator(schema_, references_) case 'Not': return FromNot(schema_, references_) case 'Object': return FromObject(schema_, references_) case 'Promise': return FromPromise(schema_, references_) case 'Record': return FromRecord(schema_, references_) case 'Ref': return FromRef(schema_, references_) case 'This': return FromThis(schema_, references_) case 'Tuple': return FromTuple(schema_, references_) case 'Union': return FromUnion(schema_, references_) default: return IsTransform(schema) } } const visited = new Set() /** Returns true if this schema contains a transform codec */ export function HasTransform(schema: TSchema, references: TSchema[]): boolean { visited.clear() return Visit(schema, references) } sinclairzx81-typebox-e0ec98c/src/value/transform/index.ts000066400000000000000000000025441505437577000236620ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * from './decode' export * from './encode' export * from './has' sinclairzx81-typebox-e0ec98c/src/value/value/000077500000000000000000000000001505437577000212775ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/src/value/value/index.ts000066400000000000000000000024751505437577000227660ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * as Value from './value' sinclairzx81-typebox-e0ec98c/src/value/value/value.ts000066400000000000000000000037161505437577000227720ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox/value The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export { Errors, ValueErrorIterator } from '../../errors/index' export { Assert } from '../assert/index' export { Cast } from '../cast/index' export { Check } from '../check/index' export { Clean } from '../clean/index' export { Clone } from '../clone/index' export { Convert } from '../convert/index' export { Create } from '../create/index' export { Decode } from '../decode/index' export { Default } from '../default/index' export { Diff, Patch, Edit } from '../delta/index' export { Encode } from '../encode/index' export { Equal } from '../equal/index' export { Hash } from '../hash/index' export { Mutate, type Mutable } from '../mutate/index' export { Parse } from '../parse/index' sinclairzx81-typebox-e0ec98c/task/000077500000000000000000000000001505437577000172225ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/task/benchmark/000077500000000000000000000000001505437577000211545ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/task/benchmark/compression/000077500000000000000000000000001505437577000235155ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/task/benchmark/compression/index.ts000066400000000000000000000022741505437577000252010ustar00rootroot00000000000000import { shell } from '@sinclair/hammer' import { statSync, readdirSync } from 'fs' import { basename, extname } from 'path' export async function measure(test: string) { await shell(`hammer build task/benchmark/compression/module/${test}.ts --dist target/benchmark/compression`) const compiled = statSync(`target/benchmark/compression/${test}.js`) await shell(`hammer build task/benchmark/compression/module/${test}.ts --dist target/benchmark/compression --minify`) const minified = statSync(`target/benchmark/compression/${test}.js`) return { test: test.padEnd(20), compiled: `${(compiled.size / 1000).toFixed(1)} kb`.padStart(8), minified: `${(minified.size / 1000).toFixed(1)} kb`.padStart(8), ratio: compiled.size / minified.size, } } export async function compression() { const tests = readdirSync('task/benchmark/compression/module').map((name) => basename(name, extname(name))) const results = await Promise.all(tests.map((test) => measure(test))) const present = results.reduce((acc, c) => { return { ...acc, [c.test.replace(/-/g, '/')]: { Compiled: c.compiled, Minified: c.minified, Compression: `${c.ratio.toFixed(2)} x` } } }, {}) console.table(present) } sinclairzx81-typebox-e0ec98c/task/benchmark/compression/module/000077500000000000000000000000001505437577000250025ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/task/benchmark/compression/module/typebox-compiler.ts000066400000000000000000000001251505437577000306520ustar00rootroot00000000000000import { TypeCompiler } from '@sinclair/typebox/compiler' console.log(TypeCompiler) sinclairzx81-typebox-e0ec98c/task/benchmark/compression/module/typebox-errors.ts000066400000000000000000000001101505437577000303460ustar00rootroot00000000000000import * as Errors from '@sinclair/typebox/errors' console.log(Errors) sinclairzx81-typebox-e0ec98c/task/benchmark/compression/module/typebox-syntax.ts000066400000000000000000000001101505437577000303600ustar00rootroot00000000000000import * as Syntax from '@sinclair/typebox/syntax' console.log(Syntax) sinclairzx81-typebox-e0ec98c/task/benchmark/compression/module/typebox-system.ts000066400000000000000000000001171505437577000303650ustar00rootroot00000000000000import { TypeSystem } from '@sinclair/typebox/system' console.log(TypeSystem) sinclairzx81-typebox-e0ec98c/task/benchmark/compression/module/typebox-value.ts000066400000000000000000000001041505437577000301510ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' console.log(Value) sinclairzx81-typebox-e0ec98c/task/benchmark/compression/module/typebox.ts000066400000000000000000000001021505437577000270350ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' const T = Type.String() sinclairzx81-typebox-e0ec98c/task/benchmark/index.ts000066400000000000000000000001101505437577000226230ustar00rootroot00000000000000export * from './compression/index' export * from './measurement/index' sinclairzx81-typebox-e0ec98c/task/benchmark/measurement/000077500000000000000000000000001505437577000235015ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/task/benchmark/measurement/index.ts000066400000000000000000000002751505437577000251640ustar00rootroot00000000000000import { shell } from '@sinclair/hammer' export async function measurement() { await shell(`hammer run task/benchmark/measurement/module/index.ts --dist target/benchmark/measurement`) } sinclairzx81-typebox-e0ec98c/task/benchmark/measurement/module/000077500000000000000000000000001505437577000247665ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/task/benchmark/measurement/module/benchmark.ts000066400000000000000000000003741505437577000272740ustar00rootroot00000000000000export namespace Benchmark { export function Measure(execute: Function, iterations: number = 16_000_000) { const start = Date.now() for (let i = 0; i < iterations; i++) execute() return { iterations, completed: Date.now() - start } } } sinclairzx81-typebox-e0ec98c/task/benchmark/measurement/module/cases.ts000066400000000000000000000101161505437577000264330ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' export namespace Cases { export const Literal_String = Type.Literal('hello') export const Literal_Number = Type.Literal(1) export const Literal_Boolean = Type.Literal(true) export const Primitive_Number = Type.Number() export const Primitive_String = Type.String() export const Primitive_String_Pattern = Type.String({ pattern: 'foo', default: 'foo' }) export const Primitive_Boolean = Type.Boolean() export const Primitive_Null = Type.Null() export const Object_Unconstrained = Type.Object({ number: Type.Number(), negNumber: Type.Number(), maxNumber: Type.Number(), string: Type.String(), longString: Type.String(), boolean: Type.Boolean(), deeplyNested: Type.Object({ foo: Type.String(), num: Type.Number(), bool: Type.Boolean(), }), }) export const Object_Constrained = Type.Object(Object_Unconstrained.properties, { additionalProperties: false, }) export const Object_Vector3 = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }) export const Object_Box3D = Type.Object({ scale: Object_Vector3, position: Object_Vector3, rotate: Object_Vector3, pivot: Object_Vector3, }) export const Object_Recursive = Type.Recursive( (Recursive) => Type.Object({ id: Type.String(), nodes: Type.Array(Recursive), }), { default: { id: '', nodes: [ { id: '', nodes: [ { id: '', nodes: [] }, { id: '', nodes: [] }, { id: '', nodes: [] }, ], }, { id: '', nodes: [ { id: '', nodes: [] }, { id: '', nodes: [] }, { id: '', nodes: [] }, ], }, { id: '', nodes: [ { id: '', nodes: [] }, { id: '', nodes: [] }, { id: '', nodes: [] }, ], }, ], }, }, ) // prettier-ignore export const Tuple_Primitive = Type.Tuple([ Type.String(), Type.Number(), Type.Boolean() ]) // prettier-ignore export const Tuple_Object = Type.Tuple([ Type.Object({ x: Type.Number(), y: Type.Number() }), Type.Object({ a: Type.String(), b: Type.String() }) ]) // prettier-ignore export const Composite_Intersect = Type.Intersect([ Type.Object({ x: Type.Number(), y: Type.Number() }), Type.Object({ a: Type.String(), b: Type.String() }) ], { default: { x: 1, y: 2, a: 'a', b: 'b' } }) // prettier-ignore export const Composite_Union = Type.Union([ Type.Object({ x: Type.Number(), y: Type.Number() }), Type.Object({ a: Type.String(), b: Type.String() }) ], { default: { a: 'a', b: 'b' } }) export const Math_Vector4 = Type.Tuple([Type.Number(), Type.Number(), Type.Number(), Type.Number()]) export const Math_Matrix4 = Type.Array(Type.Array(Type.Number()), { default: [ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1], ], }) export const Array_Primitive_Number = Type.Array(Type.Number(), { minItems: 4 }) export const Array_Primitive_String = Type.Array(Type.String(), { minItems: 4 }) export const Array_Primitive_Boolean = Type.Array(Type.Boolean(), { minItems: 4 }) export const Array_Object_Unconstrained = Type.Array(Object_Unconstrained, { minItems: 4 }) export const Array_Object_Constrained = Type.Array(Object_Constrained, { minItems: 4 }) export const Array_Object_Recursive = Type.Array(Object_Recursive, { minItems: 4 }) export const Array_Tuple_Primitive = Type.Array(Tuple_Primitive, { minItems: 4 }) export const Array_Tuple_Object = Type.Array(Tuple_Object, { minItems: 4 }) export const Array_Composite_Intersect = Type.Array(Composite_Intersect, { minItems: 4 }) export const Array_Composite_Union = Type.Array(Composite_Union, { minItems: 4 }) export const Array_Math_Vector4 = Type.Array(Math_Vector4, { minItems: 4 }) export const Array_Math_Matrix4 = Type.Array(Math_Matrix4, { minItems: 4 }) } sinclairzx81-typebox-e0ec98c/task/benchmark/measurement/module/check.ts000066400000000000000000000022311505437577000264110ustar00rootroot00000000000000import { Cases } from './cases' import { Benchmark } from './benchmark' import { TypeCompiler } from '@sinclair/typebox/compiler' import { TSchema, TypeGuard } from '@sinclair/typebox' import { Value } from '@sinclair/typebox/value' import Ajv from 'ajv' const ajv = new Ajv() // ensure single instance export namespace CheckBenchmark { function Measure(type: string, schema: T) { console.log('CheckBenchmark.Measure(', type, ')') const iterations = 1_000_000 const V = Value.Create(schema) const AC = ajv.compile(schema) const A = Benchmark.Measure(() => { if (!AC(V)) throw Error() }, iterations) const CC = TypeCompiler.Compile(schema) const T = Benchmark.Measure(() => { if (!CC.Check(V)) throw Error() }, iterations) const VC = Benchmark.Measure(() => { if (!Value.Check(schema, V)) throw Error() }, iterations) return { type, ajv: A, compiler: T, value: VC } } export function* Execute() { for (const [type, schema] of Object.entries(Cases)) { if (!TypeGuard.IsSchema(schema)) throw Error('Invalid TypeBox schema') yield Measure(type, schema) } } } sinclairzx81-typebox-e0ec98c/task/benchmark/measurement/module/compile.ts000066400000000000000000000032641505437577000267730ustar00rootroot00000000000000import { Cases } from './cases' import { Benchmark } from './benchmark' import { TypeCompiler } from '@sinclair/typebox/compiler' import { TSchema, TypeGuard } from '@sinclair/typebox' import Ajv from 'ajv' const ajv = new Ajv() // ensure single instance export namespace CompileBenchmark { function Measure(type: string, schema: T) { const iterations = 1000 console.log('CompileBenchmark.Measure(', type, ')') // ------------------------------------------------------------------------------- // Note: Ajv caches schemas by reference. To ensure we measure actual // compilation times, we must pass a new reference via { ...schema } // ------------------------------------------------------------------------------- const AC = Benchmark.Measure(() => ajv.compile({ ...schema }), iterations) const CC = Benchmark.Measure(() => TypeCompiler.Compile({ ...schema }), iterations) return { type, ajv: AC, compiler: CC } } export function* Execute() { for (const [type, schema] of Object.entries(Cases)) { if (!TypeGuard.IsSchema(schema)) throw Error('Invalid TypeBox schema') // ------------------------------------------------------------------------------- // Note: it is not possible to benchmark recursive schemas as ajv will cache and // track duplicate $id (resulting in compile error). It is not possible to ammend // recursive $id's without potentially biasing results, so we omit on this case. // ------------------------------------------------------------------------------- if (type === 'Object_Recursive' || type === 'Array_Object_Recursive') continue yield Measure(type, schema) } } } sinclairzx81-typebox-e0ec98c/task/benchmark/measurement/module/index.ts000066400000000000000000000023011505437577000264410ustar00rootroot00000000000000import { CompileBenchmark } from './compile' import { CheckBenchmark } from './check' import { Result } from './result' export function present(results: Result[]) { console.table( results.reduce((acc, result) => { const ratio = result.ajv.completed / result.compiler.completed if (result.value) { return { ...acc, [result.type.padEnd(26, ' ')]: { Iterations: result.compiler.iterations, ValueCheck: `${result.value.completed} ms`.padStart(10), Ajv: `${result.ajv.completed} ms`.padStart(10), TypeCompiler: `${result.compiler.completed} ms`.padStart(10), Performance: `${ratio.toFixed(2)} x`.padStart(10, ' '), }, } } else { return { ...acc, [result.type.padEnd(26, ' ')]: { Iterations: result.compiler.iterations, Ajv: `${result.ajv.completed} ms`.padStart(10), TypeCompiler: `${result.compiler.completed} ms`.padStart(10), Performance: `${ratio.toFixed(2)} x`.padStart(10, ' '), }, } } }, {}), ) } present([...CompileBenchmark.Execute()]) present([...CheckBenchmark.Execute()]) sinclairzx81-typebox-e0ec98c/task/benchmark/measurement/module/result.ts000066400000000000000000000003361505437577000266560ustar00rootroot00000000000000export type Result = { type: string ajv: { iterations: number completed: number } compiler: { iterations: number completed: number } value?: { iterations: number completed: number } } sinclairzx81-typebox-e0ec98c/task/build/000077500000000000000000000000001505437577000203215ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/task/build/cjs/000077500000000000000000000000001505437577000211005ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/task/build/cjs/build.ts000066400000000000000000000031441505437577000225510ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { removeNotices } from '../notices/remove-notices' import { compile } from './compile' /** Builds the CommonJS version of this package */ export async function build(target: string) { console.log('building...cjs') const buildTarget = `${target}/build/cjs` await compile(buildTarget) await removeNotices(buildTarget) } sinclairzx81-typebox-e0ec98c/task/build/cjs/compile.ts000066400000000000000000000031521505437577000231010ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ declare function shell(command: string): Promise // prettier-ignore export async function compile(target: string) { const options = [ `--outDir ${target}`, '--target ES2020', '--module Node16', '--moduleResolution Node16', '--declaration', ].join(' ') await shell(`tsc -p ./src/tsconfig.json ${options}`) } sinclairzx81-typebox-e0ec98c/task/build/esm/000077500000000000000000000000001505437577000211055ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/task/build/esm/build.ts000066400000000000000000000032611505437577000225560ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { removeNotices } from '../notices/remove-notices' import { convertToEsm } from './convert-to-esm' import { compile } from './compile' /** Builds the ESM version of this package */ export async function build(target: string) { console.log('building...esm') const buildTarget = `${target}/build/esm` await compile(buildTarget) await convertToEsm(buildTarget) await removeNotices(buildTarget) } sinclairzx81-typebox-e0ec98c/task/build/esm/compile.ts000066400000000000000000000031531505437577000231070ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ declare function shell(command: string): Promise // prettier-ignore export async function compile(target: string) { const options = [ `--outDir ${target}`, '--target ES2020', '--module ESNext', '--moduleResolution Bundler', '--declaration', ].join(' ') await shell(`tsc -p ./src/tsconfig.json ${options}`) } sinclairzx81-typebox-e0ec98c/task/build/esm/convert-to-esm.ts000066400000000000000000000101321505437577000243340ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import * as Path from 'node:path' import * as Fs from 'node:fs' // ------------------------------------------------------------------ // Specifier Rewrite // ------------------------------------------------------------------ // prettier-ignore function replaceInlineImportSpecifiers(content: string): string { const pattern = /import\((.*?)\)/g while (true) { const match = pattern.exec(content) if (match === null) return content const captured = match[1] if(captured.includes('.mjs')) continue const specifier = captured.slice(1, captured.length - 1) content = content.replace(captured, `"${specifier}.mjs"`) } } // prettier-ignore function replaceExportSpecifiers(content: string): string { const pattern = /(export|import)(.*) from ('(.*)');/g while(true) { const match = pattern.exec(content) if(match === null) return content const captured = match[3] const specifier = captured.slice(1, captured.length - 1) content = content.replace(captured, `'${specifier}.mjs'`) } } function replaceSpecifiers(content: string): string { const pass1 = replaceExportSpecifiers(content) const pass2 = replaceInlineImportSpecifiers(pass1) return pass2 } // ------------------------------------------------------------------ // ConvertToEsm // ------------------------------------------------------------------ // prettier-ignore function shouldProcess(sourcePath: string) { const extname = Path.extname(sourcePath) return ['.js', '.ts'].includes(extname) } // prettier-ignore function newExtension(extname: string) { return ( extname === '.js' ? '.mjs' : extname === '.ts' ? '.mts' : extname ) } // prettier-ignore function processFile(sourcePath: string) { if(!shouldProcess(sourcePath)) return const extname = Path.extname(sourcePath) const dirname = Path.dirname(sourcePath) const basename = Path.basename(sourcePath, extname) const new_extname = newExtension(extname) const sourceContent = Fs.readFileSync(sourcePath, 'utf-8') const targetContent = replaceSpecifiers(sourceContent) const targetPath = `${Path.join(dirname, basename)}${new_extname}` Fs.writeFileSync(sourcePath, targetContent) Fs.renameSync(sourcePath, targetPath) } // prettier-ignore function processSourcePath(sourcePath: string) { const stat = Fs.statSync(sourcePath) if(stat.isDirectory()) return readDirectory(sourcePath) if(stat.isFile()) return processFile(sourcePath) } // prettier-ignore function readDirectory(sourceDirectory: string) { for(const entry of Fs.readdirSync(sourceDirectory)) { const sourcePath = Path.join(sourceDirectory, entry) processSourcePath(sourcePath) } } /** Converts the JavaScript and TypeScript declaration modules in the given source directory to use .mjs extensions */ export function convertToEsm(sourceDirectory: string) { readDirectory(sourceDirectory) } sinclairzx81-typebox-e0ec98c/task/build/index.ts000066400000000000000000000026071505437577000220050ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ export * as Package from './package/build' export * as Esm from './esm/build' export * as Cjs from './cjs/build' sinclairzx81-typebox-e0ec98c/task/build/notices/000077500000000000000000000000001505437577000217655ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/task/build/notices/remove-notices.ts000066400000000000000000000066251505437577000253050ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import * as Path from 'node:path' import * as Fs from 'node:fs' // ---------------------------------------------------------------------- // Remove Module Level MIT Notice on Package Distribution // // The MIT copyright notice the unnecessarily increases the distribution // size of the package, this code removes it. The MIT license is available // in the package root. // // ---------------------------------------------------------------------- // prettier-ignore function escape(content: string) { return content.split('').map((c) => `\\${c}`).join('') } // prettier-ignore function removeNotice(content: string): string { const open = escape('/*--------------------------------------------------------------------------') const close = escape('---------------------------------------------------------------------------*/') const critera = 'Permission is hereby granted, free of charge' const pattern = new RegExp(`${open}[\\s\\S]*?${close}`, 'gm') while (true) { const match = pattern.exec(content) if (match === null) return content.trimStart() if (!match[0].includes(critera)) continue content = content.replace(match[0], '') } } // ------------------------------------------------------------------ // Directory Enumeration // ------------------------------------------------------------------ // prettier-ignore function processFile(sourcePath: string) { const sourceContent = Fs.readFileSync(sourcePath, 'utf-8') const targetContent = removeNotice(sourceContent) Fs.writeFileSync(sourcePath, targetContent) } // prettier-ignore function processSourcePath(sourcePath: string) { const stat = Fs.statSync(sourcePath) if(stat.isDirectory()) return readDirectory(sourcePath) if(stat.isFile()) return processFile(sourcePath) } // prettier-ignore function readDirectory(sourceDirectory: string) { for(const entry of Fs.readdirSync(sourceDirectory)) { const sourcePath = Path.join(sourceDirectory, entry) processSourcePath(sourcePath) } } /** Removes the MIT copyright notices from each source file in the given directory */ export function removeNotices(sourceDirectory: string) { readDirectory(sourceDirectory) } sinclairzx81-typebox-e0ec98c/task/build/package/000077500000000000000000000000001505437577000217145ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/task/build/package/build.ts000066400000000000000000000033501505437577000233640ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import { createPackageJsonRedirect } from './create-package-json-redirect' import { createPackageJson } from './create-package-json' /** Builds package.json and redirect directories */ export async function build(target: string) { console.log('building...package.json') const submodules = ['compiler', 'errors', 'parser', 'syntax', 'system', 'type', 'value'] await createPackageJsonRedirect(target, submodules) await createPackageJson(target, submodules) } sinclairzx81-typebox-e0ec98c/task/build/package/create-package-json-redirect.ts000066400000000000000000000047711505437577000276770ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import * as Fs from 'node:fs' // prettier-ignore function writeRedirect(target: string, submodule: string) { Fs.mkdirSync(`${target}/${submodule}`, { recursive: true }) Fs.writeFileSync(`${target}/${submodule}/package.json`,JSON.stringify({ main: `../build/cjs/${submodule}/index.js`, types: `../build/cjs/${submodule}/index.d.ts`, }, null, 2)) } // -------------------------------------------------------------------------------------------------------------------------- // Builds redirect directories for earlier versions of Node. Note that TypeScript will use these directories to // resolve types when tsconfig.json is configured for `moduleResolution: 'Node16'`. This approach is referred to as // `package-json-redirect` and enables correct type resolution in lieu of a correct end user configuration. // // https://github.com/andrewbranch/example-subpath-exports-ts-compat/tree/main/examples/node_modules/package-json-redirects // -------------------------------------------------------------------------------------------------------------------------- // prettier-ignore export function createPackageJsonRedirect(target: string, submodules: string[]) { submodules.forEach((submodule) => writeRedirect(target, submodule)) } sinclairzx81-typebox-e0ec98c/task/build/package/create-package-json.ts000066400000000000000000000074121505437577000260730ustar00rootroot00000000000000/*-------------------------------------------------------------------------- @sinclair/typebox The MIT License (MIT) Copyright (c) 2017-2025 Haydn Paterson (sinclair) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------*/ import * as Fs from 'node:fs' import * as Path from 'node:path' // prettier-ignore export function createPackageJson(target: string, submodules: string[]) { const content = JSON.stringify(resolvePackageJson(submodules), null, 2) const targetPath = Path.join(target, 'package.json') const targetDir = Path.dirname(targetPath) Fs.mkdirSync(targetDir, { recursive: true }) Fs.writeFileSync(targetPath, content, 'utf-8') } // prettier-ignore function resolvePackageJson(submodules: string[]) { return { ...resolveMetadata(), ...resolveExports(submodules) } } // prettier-ignore function resolveSubmoduleExports(submodule: string) { return { require: { types: `./build/cjs/${submodule}/index.d.ts`, default: `./build/cjs/${submodule}/index.js`, }, import: { types: `./build/esm/${submodule}/index.d.mts`, default: `./build/esm/${submodule}/index.mjs`, } } } // prettier-ignore function resolveExports(submodules: string[]) { const exports = submodules.reduce((acc, submodule) => { return { ...acc, [`./${submodule}`]: resolveSubmoduleExports(submodule) } }, { // ... and root module ".": { "require": { "types": "./build/cjs/index.d.ts", "default": "./build/cjs/index.js", }, "import": { "types": "./build/esm/index.d.mts", "default": "./build/esm/index.mjs", } } }) return { exports } } // prettier-ignore function resolveMetadata() { const packagePath = Path.join(process.cwd(), 'package.json') const packageJson = JSON.parse(Fs.readFileSync(packagePath, 'utf-8')) return { name: packageJson.name, version: packageJson.version, description: packageJson.description, keywords: packageJson.keywords, author: packageJson.author, license: packageJson.license, repository: packageJson.repository, // flagged by socket.dev if not present scripts: { test: 'echo test' }, types: "./build/cjs/index.d.ts", main: "./build/cjs/index.js", module: "./build/esm/index.mjs", // disable auto bundle strategy: see https://github.com/esm-dev/esm.sh#bundling-strategy 'esm.sh': { 'bundle': false }, // specify modules with potential for side effects 'sideEffects': [ './build/esm/type/registry/format.mjs', './build/esm/type/registry/type.mjs', './build/esm/type/system/policy.mjs', './build/cjs/type/registry/format.js', './build/cjs/type/registry/type.js', './build/cjs/type/system/policy.js' ] } } sinclairzx81-typebox-e0ec98c/test/000077500000000000000000000000001505437577000172375ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/000077500000000000000000000000001505437577000207225ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/assert/000077500000000000000000000000001505437577000222235ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/assert/assert.ts000066400000000000000000000040731505437577000241000ustar00rootroot00000000000000import * as assert from 'assert' export namespace Assert { export function HasProperty(value: unknown, key: K): asserts value is Record { if (typeof value === 'object' && value !== null && key in value) return throw new Error(`Expected value to have property '${key as string}'`) } export function IsTrue(value: boolean): asserts value is true { return assert.strictEqual(value, true) } export function IsFalse(value: boolean): asserts value is false { return assert.strictEqual(value, false) } export function IsEqual(actual: unknown, expect: unknown) { if (actual instanceof Uint8Array && expect instanceof Uint8Array) { assert.equal(actual.length, expect.length) for (let i = 0; i < actual.length; i++) assert.equal(actual[i], expect[i]) } return assert.deepStrictEqual(actual, expect) } export function NotEqual(actual: unknown, expect: unknown) { return assert.notEqual(actual, expect) } /** Asserts a numeric value is within range of the expected */ export function InRange(value: number, expect: number, range: number) { if (Math.abs(value - expect) <= range) return throw Error('Expected value to be in range') } let nextIdOrdinal = 0 export function NextId() { return `$id-${nextIdOrdinal++}` } export function Throws(callback: Function) { try { callback() } catch { return } throw Error('Expected throw') } export async function ThrowsAsync(callback: Function) { try { await callback() } catch { return } throw Error('Expected throw') } export function IsInstanceOf any>(value: any, constructor: T): asserts value is InstanceType { if (value instanceof constructor) return throw Error(`Value is not instance of ${constructor}`) } export function IsTypeOf(value: any, type: T) { if (typeof value === type) return throw Error(`Value is not typeof ${type}`) } } sinclairzx81-typebox-e0ec98c/test/runtime/assert/index.ts000066400000000000000000000000311505437577000236740ustar00rootroot00000000000000export * from './assert' sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/000077500000000000000000000000001505437577000233125ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/any.ts000066400000000000000000000013321505437577000244500ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok } from './validate' describe('compiler-ajv/Any', () => { it('Should validate number', () => { const T = Type.Any() Ok(T, 1) }) it('Should validate string', () => { const T = Type.Any() Ok(T, 'hello') }) it('Should validate boolean', () => { const T = Type.Any() Ok(T, true) }) it('Should validate array', () => { const T = Type.Any() Ok(T, [1, 2, 3]) }) it('Should validate object', () => { const T = Type.Any() Ok(T, { a: 1, b: 2 }) }) it('Should validate null', () => { const T = Type.Any() Ok(T, null) }) it('Should validate undefined', () => { const T = Type.Any() Ok(T, undefined) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/array.ts000066400000000000000000000142401505437577000250010ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler-ajv/Array', () => { it('Should validate an array of any', () => { const T = Type.Array(Type.Any()) Ok(T, [0, true, 'hello', {}]) }) it('Should not validate varying array when item is number', () => { const T = Type.Array(Type.Number()) Fail(T, [1, 2, 3, 'hello']) }) it('Should validate for an array of unions', () => { const T = Type.Array(Type.Union([Type.Number(), Type.String()])) Ok(T, [1, 'hello', 3, 'world']) }) it('Should not validate for an array of unions where item is not in union.', () => { const T = Type.Array(Type.Union([Type.Number(), Type.String()])) Fail(T, [1, 'hello', 3, 'world', true]) }) it('Should validate for an empty array', () => { const T = Type.Array(Type.Union([Type.Number(), Type.String()])) Ok(T, []) }) it('Should validate for an array of intersection types', () => { const A = Type.Object({ a: Type.String() }) const B = Type.Object({ b: Type.String() }) const C = Type.Intersect([A, B]) const T = Type.Array(C) Ok(T, [ { a: 'hello', b: 'hello' }, { a: 'hello', b: 'hello' }, { a: 'hello', b: 'hello' }, ]) }) it('Should not validate for an array of composite types when passing additionalProperties false', () => { const A = Type.Object({ a: Type.String() }) const B = Type.Object({ b: Type.String() }) const C = Type.Composite([A, B], { additionalProperties: false }) const T = Type.Array(C) Fail(T, [ { a: 'hello', b: 'hello' }, { a: 'hello', b: 'hello' }, { a: 'hello', b: 'hello', c: 'additional' }, ]) }) it('Should validate an array of tuples', () => { const A = Type.String() const B = Type.Number() const C = Type.Tuple([A, B]) const T = Type.Array(C) Ok(T, [ ['hello', 1], ['hello', 1], ['hello', 1], ]) }) it('Should not validate an array of tuples when tuple values are incorrect', () => { const A = Type.String() const B = Type.Number() const C = Type.Tuple([A, B]) const T = Type.Array(C) Fail(T, [ [1, 'hello'], [1, 'hello'], [1, 'hello'], ]) }) it('Should not validate array with failed minItems', () => { const T = Type.Array(Type.Number(), { minItems: 3 }) Fail(T, [0, 1]) }) it('Should not validate array with failed maxItems', () => { const T = Type.Array(Type.Number(), { maxItems: 3 }) Fail(T, [0, 1, 2, 3]) }) // --------------------------------------------------------- // Unique Items // --------------------------------------------------------- it('Should validate array with uniqueItems when items are distinct objects', () => { const T = Type.Array(Type.Object({ x: Type.Number(), y: Type.Number() }), { uniqueItems: true }) Ok(T, [ { x: 0, y: 1 }, { x: 1, y: 0 }, ]) }) it('Should not validate array with uniqueItems when items are not distinct objects', () => { const T = Type.Array(Type.Object({ x: Type.Number(), y: Type.Number() }), { uniqueItems: true }) Fail(T, [ { x: 1, y: 0 }, { x: 1, y: 0 }, ]) }) it('Should not validate array with non uniqueItems', () => { const T = Type.Array(Type.Number(), { uniqueItems: true }) Fail(T, [0, 0]) }) // --------------------------------------------------------- // Contains // --------------------------------------------------------- it('Should validate for contains', () => { const T = Type.Array(Type.Number(), { contains: Type.Literal(1) }) Ok(T, [1]) Ok(T, [1, 2]) Fail(T, []) Fail(T, [2]) }) it('Should validate for minContains', () => { const T = Type.Array(Type.Number(), { contains: Type.Literal(1), minContains: 3 }) Ok(T, [1, 1, 1, 2]) Ok(T, [2, 1, 1, 1, 2]) Ok(T, [1, 1, 1]) Fail(T, []) Fail(T, [1, 1]) Fail(T, [2]) }) it('Should validate for maxContains', () => { const T = Type.Array(Type.Number(), { contains: Type.Literal(1), maxContains: 3 }) Ok(T, [1, 1, 1]) Ok(T, [1, 1]) Ok(T, [2, 2, 2, 2, 1, 1, 1]) Fail(T, [1, 1, 1, 1]) }) it('Should validate for minContains and maxContains', () => { const T = Type.Array(Type.Number(), { contains: Type.Literal(1), minContains: 3, maxContains: 5 }) Fail(T, [1, 1]) Ok(T, [1, 1, 1]) Ok(T, [1, 1, 1, 1]) Ok(T, [1, 1, 1, 1, 1]) Fail(T, [1, 1, 1, 1, 1, 1]) }) it('Should not validate minContains or maxContains when contains is unspecified', () => { const T = Type.Array(Type.Number(), { minContains: 3, maxContains: 5 }) Fail(T, [1, 1]) Fail(T, [1, 1, 1]) Fail(T, [1, 1, 1, 1]) Fail(T, [1, 1, 1, 1, 1]) Fail(T, [1, 1, 1, 1, 1, 1]) }) it('Should produce illogical schema when contains is not sub type of items', () => { const T = Type.Array(Type.Number(), { contains: Type.String(), minContains: 3, maxContains: 5 }) Fail(T, [1, 1]) Fail(T, [1, 1, 1]) Fail(T, [1, 1, 1, 1]) Fail(T, [1, 1, 1, 1, 1]) Fail(T, [1, 1, 1, 1, 1, 1]) }) // ---------------------------------------------------------------- // Issue: https://github.com/sinclairzx81/typebox/discussions/607 // ---------------------------------------------------------------- it('Should correctly handle undefined array properties', () => { const Answer = Type.Object({ text: Type.String(), isCorrect: Type.Boolean(), }) const Question = Type.Object({ text: Type.String(), options: Type.Array(Answer, { minContains: 1, maxContains: 1, contains: Type.Object({ text: Type.String(), isCorrect: Type.Literal(true), }), }), }) Fail(Question, { text: 'A' }) Fail(Question, { text: 'A', options: [] }) Ok(Question, { text: 'A', options: [{ text: 'A', isCorrect: true }] }) Ok(Question, { text: 'A', options: [ { text: 'A', isCorrect: true }, { text: 'B', isCorrect: false }, ], }) Fail(Question, { text: 'A', options: [{ text: 'A', isCorrect: false }] }) Fail(Question, { text: 'A', options: [ { text: 'A', isCorrect: true }, { text: 'B', isCorrect: true }, ], }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/boolean.ts000066400000000000000000000014671505437577000253110ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler-ajv/Boolean', () => { it('Should validate a boolean', () => { const T = Type.Boolean() Ok(T, true) Ok(T, false) }) it('Should not validate a number', () => { const T = Type.Boolean() Fail(T, 1) }) it('Should not validate a string', () => { const T = Type.Boolean() Fail(T, 'true') }) it('Should not validate an array', () => { const T = Type.Boolean() Fail(T, [true]) }) it('Should not validate an object', () => { const T = Type.Boolean() Fail(T, {}) }) it('Should not validate an null', () => { const T = Type.Boolean() Fail(T, null) }) it('Should not validate an undefined', () => { const T = Type.Boolean() Fail(T, undefined) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/composite.ts000066400000000000000000000075261505437577000256760ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Assert } from '../assert' import { Ok, Fail } from './validate' describe('compiler-ajv/Composite', () => { it('Should compose two objects', () => { const A = Type.Object({ a: Type.String() }) const B = Type.Object({ b: Type.Number() }) const T = Type.Composite([A, B], { additionalProperties: false }) Ok(T, { a: 'hello', b: 42 }) }) it('Should compose with partial', () => { const A = Type.Partial(Type.Object({ a: Type.Number() })) const B = Type.Partial(Type.Object({ b: Type.Number() })) const P = Type.Composite([A, B], { additionalProperties: false }) Ok(P, { a: 1, b: 2 }) Ok(P, { a: 1 }) Ok(P, { b: 1 }) Ok(P, {}) Fail(P, { a: 1, b: 2, c: 3 }) Fail(P, { c: 1 }) }) it('Should compose with overlapping same type', () => { const A = Type.Object({ a: Type.Number() }) const B = Type.Object({ a: Type.Number() }) const P = Type.Composite([A, B]) Ok(P, { a: 1 }) Fail(P, { a: '1' }) }) it('Should not compose with overlapping varying type', () => { const A = Type.Object({ a: Type.Number() }) const B = Type.Object({ a: Type.String() }) const T = Type.Composite([A, B]) Fail(T, { a: 1 }) Fail(T, { a: 'hello' }) Fail(T, {}) }) it('Should compose with deeply nest overlapping varying type', () => { const A = Type.Object({ a: Type.Number() }) const B = Type.Object({ b: Type.String() }) const C = Type.Object({ c: Type.Boolean() }) const D = Type.Object({ d: Type.Null() }) const T = Type.Composite([A, B, C, D]) Ok(T, { a: 1, b: 'hello', c: true, d: null }) }) it('Should not compose with deeply nest overlapping varying type', () => { const A = Type.Object({ a: Type.Number() }) const B = Type.Object({ a: Type.String() }) const C = Type.Object({ a: Type.Boolean() }) const D = Type.Object({ a: Type.Null() }) const T = Type.Composite([A, B, C, D]) Fail(T, { a: 1 }) Fail(T, { a: 'hello' }) Fail(T, { a: false }) Fail(T, { a: null }) Fail(T, { a: [] }) Fail(T, {}) }) it('Should pick from composited type', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const C = Type.Object({ z: Type.Number() }) const T = Type.Composite([A, B, C]) const P = Type.Pick(T, ['x', 'y'], { additionalProperties: false }) Ok(P, { x: 1, y: 1 }) Fail(P, { x: 1, y: 1, z: 1 }) }) it('Should omit from composited type', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const C = Type.Object({ z: Type.Number() }) const T = Type.Composite([A, B, C]) const P = Type.Omit(T, ['z'], { additionalProperties: false }) Ok(P, { x: 1, y: 1 }) Fail(P, { x: 1, y: 1, z: 1 }) }) it('Should compose nested object properties', () => { const A = Type.Object({ x: Type.Object({ x: Type.Number() }) }) const B = Type.Object({ y: Type.Object({ x: Type.String() }) }) const T = Type.Composite([A, B]) Ok(T, { x: { x: 1 }, y: { x: '' } }) Fail(T, { x: { x: '1' }, y: { x: '' } }) Fail(T, { x: { x: 1 }, y: { x: 1 } }) }) // todo: move to composition / type guard spec it('Should compose and produce the same schema', () => { const T = Type.Object({ field: Type.Optional(Type.String()), }) const A = Type.Composite([T]) const B = Type.Composite([T]) Assert.IsEqual(A, B) }) // prettier-ignore it('Should composite intersection', () => { const T = Type.Composite([ Type.Intersect([ Type.Object({ x: Type.Number() }) ]), Type.Intersect([ Type.Object({ y: Type.Number() }) ]), Type.Intersect([ Type.Object({ z: Type.Number() }) ]), ]) Ok(T, { x: 1, y: 2, z: 3 }) Fail(T, { x: 1, y: 2, z: '3' }) Fail(T, { x: 1, y: 2 }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/const.ts000066400000000000000000000015721505437577000250150ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok } from './validate' describe('compiler-ajv/Const', () => { it('Should validate 1', () => { const T = Type.Const(1) Ok(T, 1) }) it('Should validate 2', () => { const T = Type.Const('hello') Ok(T, 'hello') }) it('Should validate 3', () => { const T = Type.Const(true) Ok(T, true) }) it('Should validate 4', () => { const T = Type.Const({ x: 1, y: 2 }) Ok(T, { x: 1, y: 2 }) }) it('Should validate 5', () => { const T = Type.Const([1, 2, 3]) Ok(T, [1, 2, 3]) }) it('Should validate 6', () => { const T = Type.Const([1, true, 'hello']) Ok(T, [1, true, 'hello']) }) it('Should validate 7', () => { const T = Type.Const({ x: [1, 2, 3, 4], y: { x: 1, y: 2, z: 3 }, }) Ok(T, { x: [1, 2, 3, 4], y: { x: 1, y: 2, z: 3 }, }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/date.ts000066400000000000000000000042311505437577000245770ustar00rootroot00000000000000// --------------------------------------------------- // No Longer Supported // --------------------------------------------------- // import { Type } from '@sinclair/typebox' // import { Ok, Fail } from './validate' // ---------------------------------------------------- // These tests are implemented by way of .addKeyword() // which are configured to use Value.Check() // ---------------------------------------------------- // describe('compiler-ajv/Date', () => { // it('Should not validate number', () => { // const T = Type.Date() // Fail(T, 1) // }) // it('Should not validate string', () => { // const T = Type.Date() // Fail(T, 'hello') // }) // it('Should not validate boolean', () => { // const T = Type.Date() // Fail(T, true) // }) // it('Should not validate array', () => { // const T = Type.Date() // Fail(T, [1, 2, 3]) // }) // it('Should not validate object', () => { // const T = Type.Date() // Fail(T, { a: 1, b: 2 }) // }) // it('Should not validate null', () => { // const T = Type.Date() // Fail(T, null) // }) // it('Should not validate undefined', () => { // const T = Type.Date() // Fail(T, undefined) // }) // it('Should validate Date', () => { // const T = Type.Date() // Ok(T, new Date()) // }) // it('Should not validate Date if is invalid', () => { // const T = Type.Date() // Fail(T, new Date('not-a-valid-date')) // }) // it('Should validate Date minimumTimestamp', () => { // const T = Type.Date({ minimumTimestamp: 10 }) // Fail(T, new Date(9)) // Ok(T, new Date(10)) // }) // it('Should validate Date maximumTimestamp', () => { // const T = Type.Date({ maximumTimestamp: 10 }) // Ok(T, new Date(10)) // Fail(T, new Date(11)) // }) // it('Should validate Date exclusiveMinimumTimestamp', () => { // const T = Type.Date({ exclusiveMinimumTimestamp: 10 }) // Fail(T, new Date(10)) // Ok(T, new Date(11)) // }) // it('Should validate Date exclusiveMaximumTimestamp', () => { // const T = Type.Date({ exclusiveMaximumTimestamp: 10 }) // Ok(T, new Date(9)) // Fail(T, new Date(10)) // }) // }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/enum.ts000066400000000000000000000022301505437577000246230ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler-ajv/Enum', () => { it('Should validate when emum uses default numeric values', () => { enum Kind { Foo, // = 0 Bar, // = 1 } const T = Type.Enum(Kind) Ok(T, 0) Ok(T, 1) }) it('Should not validate when given enum values are not numeric', () => { enum Kind { Foo, // = 0 Bar, // = 1 } const T = Type.Enum(Kind) Fail(T, 'Foo') Fail(T, 'Bar') }) it('Should validate when emum has defined string values', () => { enum Kind { Foo = 'foo', Bar = 'bar', } const T = Type.Enum(Kind) Ok(T, 'foo') Ok(T, 'bar') }) it('Should not validate when emum has defined string values and user passes numeric', () => { enum Kind { Foo = 'foo', Bar = 'bar', } const T = Type.Enum(Kind) Fail(T, 0) Fail(T, 1) }) it('Should validate when enum has one or more string values', () => { enum Kind { Foo, Bar = 'bar', } const T = Type.Enum(Kind) Ok(T, 0) Ok(T, 'bar') Fail(T, 'baz') Fail(T, 'Foo') Fail(T, 1) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/index.ts000066400000000000000000000012421505437577000247700ustar00rootroot00000000000000import './any' import './array' import './boolean' import './composite' import './const' import './date' import './enum' import './integer' import './intersect' import './keyof' import './literal' import './module' import './never' import './not' import './null' import './number' import './object' import './omit' import './optional' import './partial' import './pick' import './readonly-optional' import './readonly' import './recursive' import './record' import './ref' import './required' import './string-pattern' import './string' import './template-literal' import './tuple' import './uint8array' import './union' import './unknown' import './unsafe' import './void' sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/integer.ts000066400000000000000000000027271505437577000253270ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler-ajv/Integer', () => { it('Should not validate number', () => { const T = Type.Integer() Fail(T, 3.14) }) it('Should validate integer', () => { const T = Type.Integer() Ok(T, 1) }) it('Should not validate string', () => { const T = Type.Integer() Fail(T, 'hello') }) it('Should not validate boolean', () => { const T = Type.Integer() Fail(T, true) }) it('Should not validate array', () => { const T = Type.Integer() Fail(T, [1, 2, 3]) }) it('Should not validate object', () => { const T = Type.Integer() Fail(T, { a: 1, b: 2 }) }) it('Should not validate null', () => { const T = Type.Integer() Fail(T, null) }) it('Should not validate undefined', () => { const T = Type.Integer() Fail(T, undefined) }) it('Should validate minimum', () => { const T = Type.Integer({ minimum: 10 }) Fail(T, 9) Ok(T, 10) }) it('Should validate maximum', () => { const T = Type.Integer({ maximum: 10 }) Ok(T, 10) Fail(T, 11) }) it('Should validate Date exclusiveMinimum', () => { const T = Type.Integer({ exclusiveMinimum: 10 }) Fail(T, 10) Ok(T, 11) }) it('Should validate Date exclusiveMaximum', () => { const T = Type.Integer({ exclusiveMaximum: 10 }) Ok(T, 9) Fail(T, 10) }) it('Should not validate NaN', () => { Fail(Type.Integer(), NaN) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/intersect.ts000066400000000000000000000146571505437577000256770ustar00rootroot00000000000000import { Type, Static } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler-ajv/Intersect', () => { it('Should intersect number and number', () => { const A = Type.Number() const B = Type.Number() const T = Type.Intersect([A, B], {}) Ok(T, 1) }) it('Should not intersect string and number', () => { const A = Type.String() const B = Type.Number() const T = Type.Intersect([A, B], {}) Fail(T, 1) Fail(T, '1') }) it('Should intersect two objects', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const T = Type.Intersect([A, B], {}) Ok(T, { x: 1, y: 1 }) }) it('Should not intersect two objects with internal additionalProperties false', () => { const A = Type.Object({ x: Type.Number() }, { additionalProperties: false }) const B = Type.Object({ y: Type.Number() }, { additionalProperties: false }) const T = Type.Intersect([A, B], {}) Fail(T, { x: 1, y: 1 }) }) it('Should intersect two objects and mandate required properties', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const T = Type.Intersect([A, B], {}) Ok(T, { x: 1, y: 1 }) Fail(T, { x: 1 }) Fail(T, { y: 1 }) }) it('Should intersect two objects with unevaluated properties', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const T = Type.Intersect([A, B], {}) Ok(T, { x: 1, y: 2, z: 1 }) }) it('Should intersect two objects and restrict unevaluated properties', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const T = Type.Intersect([A, B], { unevaluatedProperties: false }) Fail(T, { x: 1, y: 2, z: 1 }) }) it('Should intersect two objects and allow unevaluated properties of number', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const T = Type.Intersect([A, B], { unevaluatedProperties: Type.Number() }) Ok(T, { x: 1, y: 2, z: 3 }) Fail(T, { x: 1, y: 2, z: '1' }) }) it('Should intersect two union objects with overlapping properties of the same type', () => { const A = Type.Union([Type.Object({ x: Type.Number() })]) const B = Type.Union([Type.Object({ x: Type.Number() })]) const T = Type.Intersect([A, B]) Ok(T, { x: 1 }) Fail(T, { x: '1' }) }) it('Should not intersect two union objects with overlapping properties of varying types', () => { const A = Type.Union([Type.Object({ x: Type.Number() })]) const B = Type.Union([Type.Object({ x: Type.String() })]) const T = Type.Intersect([A, B]) Fail(T, { x: 1 }) Fail(T, { x: '1' }) }) it('Should intersect two union objects with non-overlapping properties', () => { const A = Type.Union([Type.Object({ x: Type.Number() })]) const B = Type.Union([Type.Object({ y: Type.Number() })]) const T = Type.Intersect([A, B]) Ok(T, { x: 1, y: 1 }) }) it('Should not intersect two union objects with non-overlapping properties for additionalProperties false', () => { const A = Type.Union([Type.Object({ x: Type.Number() }, { additionalProperties: false })]) const B = Type.Union([Type.Object({ y: Type.Number() }, { additionalProperties: false })]) const T = Type.Intersect([A, B]) Fail(T, { x: 1, y: 1 }) }) it('unevaluatedProperties with Record 1', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: false, }, ) Ok(T, { x: 1, y: 2 }) }) it('unevaluatedProperties with Record 2', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: false, }, ) Ok(T, { x: 1, y: 2, 0: 'hello' }) }) it('unevaluatedProperties with Record 3', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: false, }, ) Fail(T, { x: 1, y: 2, 0: 1 }) }) it('unevaluatedProperties with Record 4', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: Type.Boolean(), }, ) Ok(T, { x: 1, y: 2 }) }) it('unevaluatedProperties with Record 5', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: Type.Boolean(), }, ) Ok(T, { x: 1, y: 2, z: true }) }) it('unevaluatedProperties with Record 6', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: Type.Boolean(), }, ) Fail(T, { x: 1, y: 2, z: 1 }) }) it('unevaluatedProperties with Record 7', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: Type.Boolean(), }, ) Ok(T, { x: 1, y: 2, 0: '' }) }) it('unevaluatedProperties with Record 8', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: Type.Boolean(), }, ) Ok(T, { x: 1, y: 2, 0: '', z: true }) }) it('unevaluatedProperties with Record 9', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: Type.Boolean(), }, ) Fail(T, { x: 1, y: 2, 0: '', z: 1 }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/keyof.ts000066400000000000000000000017431505437577000250040ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler-ajv/KeyOf', () => { it('Should validate with all object keys as a kind of union', () => { const T = Type.KeyOf( Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }), ) Ok(T, 'x') Ok(T, 'y') Ok(T, 'z') Fail(T, 'w') }) it('Should validate when using pick', () => { const T = Type.KeyOf( Type.Pick( Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }), ['x', 'y'], ), ) Ok(T, 'x') Ok(T, 'y') Fail(T, 'z') }) it('Should validate when using omit', () => { const T = Type.KeyOf( Type.Omit( Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }), ['x', 'y'], ), ) Fail(T, 'x') Fail(T, 'y') Ok(T, 'z') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/literal.ts000066400000000000000000000026651505437577000253270ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler-ajv/Literal', () => { it('Should validate literal number', () => { const T = Type.Literal(42) Ok(T, 42) }) it('Should validate literal string', () => { const T = Type.Literal('hello') Ok(T, 'hello') }) it('Should validate literal boolean', () => { const T = Type.Literal(true) Ok(T, true) }) it('Should not validate invalid literal number', () => { const T = Type.Literal(42) Fail(T, 43) }) it('Should not validate invalid literal string', () => { const T = Type.Literal('hello') Fail(T, 'world') }) it('Should not validate invalid literal boolean', () => { const T = Type.Literal(false) Fail(T, true) }) it('Should validate literal union', () => { const T = Type.Union([Type.Literal(42), Type.Literal('hello')]) Ok(T, 42) Ok(T, 'hello') }) it('Should not validate invalid literal union', () => { const T = Type.Union([Type.Literal(42), Type.Literal('hello')]) Fail(T, 43) Fail(T, 'world') }) // reference: https://github.com/sinclairzx81/typebox/issues/539 it('Should escape single quote literals', () => { const T = Type.Literal("it's") Ok(T, "it's") Fail(T, "it''s") }) it('Should escape multiple single quote literals', () => { const T = Type.Literal("'''''''''") Ok(T, "'''''''''") Fail(T, "''''''''") // minus 1 }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/module.ts000066400000000000000000000106071505437577000251530ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler-ajv/Module', () => { it('Should validate string', () => { const Module = Type.Module({ A: Type.String(), }) const T = Module.Import('A') Ok(T, 'hello') Fail(T, true) }) it('Should validate referenced string', () => { const Module = Type.Module({ A: Type.String(), B: Type.Ref('A'), }) const T = Module.Import('B') Ok(T, 'hello') Fail(T, true) }) it('Should validate self referential', () => { const Module = Type.Module({ A: Type.Object({ nodes: Type.Array(Type.Ref('A')), }), }) const T = Module.Import('A') Ok(T, { nodes: [{ nodes: [{ nodes: [] }, { nodes: [] }] }] }) Fail(T, { nodes: [{ nodes: [{ nodes: [] }, { nodes: false }] }] }) Fail(T, true) }) it('Should validate mutual recursive', () => { const Module = Type.Module({ A: Type.Object({ b: Type.Ref('B'), }), B: Type.Object({ a: Type.Union([Type.Ref('A'), Type.Null()]), }), }) const T = Module.Import('A') Ok(T, { b: { a: null } }) Ok(T, { b: { a: { b: { a: null } } } }) Fail(T, { b: { a: 1 } }) Fail(T, { b: { a: { b: { a: 1 } } } }) Fail(T, true) }) it('Should validate mutual recursive (Array)', () => { const Module = Type.Module({ A: Type.Object({ b: Type.Ref('B'), }), B: Type.Object({ a: Type.Array(Type.Ref('A')), }), }) const T = Module.Import('A') Ok(T, { b: { a: [{ b: { a: [] } }] } }) Fail(T, { b: { a: [{ b: { a: [null] } }] } }) Fail(T, true) }) it('Should validate deep referential', () => { const Module = Type.Module({ A: Type.Ref('B'), B: Type.Ref('C'), C: Type.Ref('D'), D: Type.Ref('E'), E: Type.Ref('F'), F: Type.Ref('G'), G: Type.Ref('H'), H: Type.Literal('hello'), }) const T = Module.Import('A') Ok(T, 'hello') Fail(T, 'world') }) // ---------------------------------------------------------------- // Modifiers // ---------------------------------------------------------------- it('Should validate objects with property modifiers 1', () => { const Module = Type.Module({ T: Type.Object({ x: Type.ReadonlyOptional(Type.Null()), y: Type.Readonly(Type.Null()), z: Type.Optional(Type.Null()), w: Type.Null(), }), }) const T = Module.Import('T') Ok(T, { x: null, y: null, w: null }) Ok(T, { y: null, w: null }) Fail(T, { x: 1, y: null, w: null }) }) it('Should validate objects with property modifiers 2', () => { const Module = Type.Module({ T: Type.Object({ x: Type.ReadonlyOptional(Type.Array(Type.Null())), y: Type.Readonly(Type.Array(Type.Null())), z: Type.Optional(Type.Array(Type.Null())), w: Type.Array(Type.Null()), }), }) const T = Module.Import('T') Ok(T, { x: [null], y: [null], w: [null] }) Ok(T, { y: [null], w: [null] }) Fail(T, { x: [1], y: [null], w: [null] }) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/1109 // ---------------------------------------------------------------- it('Should validate deep referential 1', () => { const Module = Type.Module({ A: Type.Union([Type.Literal('Foo'), Type.Literal('Bar')]), B: Type.Ref('A'), C: Type.Object({ ref: Type.Ref('B') }), D: Type.Union([Type.Ref('B'), Type.Ref('C')]), }) Ok(Module.Import('A') as never, 'Foo') Ok(Module.Import('A') as never, 'Bar') Ok(Module.Import('B') as never, 'Foo') Ok(Module.Import('B') as never, 'Bar') Ok(Module.Import('C') as never, { ref: 'Foo' }) Ok(Module.Import('C') as never, { ref: 'Bar' }) Ok(Module.Import('D') as never, 'Foo') Ok(Module.Import('D') as never, 'Bar') Ok(Module.Import('D') as never, { ref: 'Foo' }) Ok(Module.Import('D') as never, { ref: 'Bar' }) }) it('Should validate deep referential 2', () => { const Module = Type.Module({ A: Type.Literal('Foo'), B: Type.Ref('A'), C: Type.Ref('B'), D: Type.Ref('C'), E: Type.Ref('D'), }) Ok(Module.Import('A'), 'Foo') Ok(Module.Import('B'), 'Foo') Ok(Module.Import('C'), 'Foo') Ok(Module.Import('D'), 'Foo') Ok(Module.Import('E'), 'Foo') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/never.ts000066400000000000000000000014221505437577000250000ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Fail } from './validate' describe('compiler-ajv/Never', () => { it('Should not validate number', () => { const T = Type.Never() Fail(T, 1) }) it('Should not validate string', () => { const T = Type.Never() Fail(T, 'hello') }) it('Should not validate boolean', () => { const T = Type.Never() Fail(T, true) }) it('Should not validate array', () => { const T = Type.Never() Fail(T, [1, 2, 3]) }) it('Should not validate object', () => { const T = Type.Never() Fail(T, { a: 1, b: 2 }) }) it('Should not validate null', () => { const T = Type.Never() Fail(T, null) }) it('Should validate undefined', () => { const T = Type.Never() Fail(T, undefined) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/not.ts000066400000000000000000000021231505437577000244600ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler-ajv/Not', () => { it('Should validate not number', () => { const T = Type.Not(Type.Number()) Fail(T, 1) Ok(T, '1') }) it('Should validate not not number', () => { const T = Type.Not(Type.Not(Type.Number())) Ok(T, 1) Fail(T, '1') }) it('Should validate not union', () => { // prettier-ignore const T = Type.Not(Type.Union([ Type.Literal('A'), Type.Literal('B'), Type.Literal('C') ])) Fail(T, 'A') Fail(T, 'B') Fail(T, 'C') Ok(T, 'D') }) it('Should validate not object intersection', () => { const T = Type.Intersect([ Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }), Type.Object({ x: Type.Not(Type.Literal(0)), y: Type.Not(Type.Literal(0)), z: Type.Not(Type.Literal(0)), }), ]) Fail(T, { x: 0, y: 0, z: 0 }) Fail(T, { x: 1, y: 0, z: 0 }) Fail(T, { x: 1, y: 1, z: 0 }) Ok(T, { x: 1, y: 1, z: 1 }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/null.ts000066400000000000000000000014201505437577000246310ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler-ajv/Null', () => { it('Should not validate number', () => { const T = Type.Null() Fail(T, 1) }) it('Should not validate string', () => { const T = Type.Null() Fail(T, 'hello') }) it('Should not validate boolean', () => { const T = Type.Null() Fail(T, true) }) it('Should not validate array', () => { const T = Type.Null() Fail(T, [1, 2, 3]) }) it('Should not validate object', () => { const T = Type.Null() Fail(T, { a: 1, b: 2 }) }) it('Should not validate null', () => { const T = Type.Null() Ok(T, null) }) it('Should not validate undefined', () => { const T = Type.Null() Fail(T, undefined) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/number.ts000066400000000000000000000027031505437577000251540ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler-ajv/Number', () => { it('Should validate number', () => { const T = Type.Number() Ok(T, 3.14) }) it('Should validate integer', () => { const T = Type.Number() Ok(T, 1) }) it('Should not validate string', () => { const T = Type.Number() Fail(T, 'hello') }) it('Should not validate boolean', () => { const T = Type.Number() Fail(T, true) }) it('Should not validate array', () => { const T = Type.Number() Fail(T, [1, 2, 3]) }) it('Should not validate object', () => { const T = Type.Number() Fail(T, { a: 1, b: 2 }) }) it('Should not validate null', () => { const T = Type.Number() Fail(T, null) }) it('Should not validate undefined', () => { const T = Type.Number() Fail(T, undefined) }) it('Should validate minimum', () => { const T = Type.Number({ minimum: 10 }) Fail(T, 9) Ok(T, 10) }) it('Should validate maximum', () => { const T = Type.Number({ maximum: 10 }) Ok(T, 10) Fail(T, 11) }) it('Should validate Date exclusiveMinimum', () => { const T = Type.Number({ exclusiveMinimum: 10 }) Fail(T, 10) Ok(T, 11) }) it('Should validate Date exclusiveMaximum', () => { const T = Type.Number({ exclusiveMaximum: 10 }) Ok(T, 9) Fail(T, 10) }) it('Should not validate NaN', () => { Fail(Type.Number(), NaN) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/object.ts000066400000000000000000000104401505437577000251270ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler-ajv/Object', () => { it('Should not validate a number', () => { const T = Type.Object({}) Fail(T, 42) }) it('Should not validate a string', () => { const T = Type.Object({}) Fail(T, 'hello') }) it('Should not validate a boolean', () => { const T = Type.Object({}) Fail(T, true) }) it('Should not validate a null', () => { const T = Type.Object({}) Fail(T, null) }) it('Should not validate an array', () => { const T = Type.Object({}) Fail(T, [1, 2]) }) it('Should validate with correct property values', () => { const T = Type.Object({ a: Type.Number(), b: Type.String(), c: Type.Boolean(), d: Type.Array(Type.Number()), e: Type.Object({ x: Type.Number(), y: Type.Number() }), }) Ok(T, { a: 10, b: 'hello', c: true, d: [1, 2, 3], e: { x: 10, y: 20 }, }) }) it('Should not validate with incorrect property values', () => { const T = Type.Object({ a: Type.Number(), b: Type.String(), c: Type.Boolean(), d: Type.Array(Type.Number()), e: Type.Object({ x: Type.Number(), y: Type.Number() }), }) Fail(T, { a: 'not a number', // error b: 'hello', c: true, d: [1, 2, 3], e: { x: 10, y: 20 }, }) }) it('Should allow additionalProperties by default', () => { const T = Type.Object({ a: Type.Number(), b: Type.String(), }) Ok(T, { a: 1, b: 'hello', c: true, }) }) it('Should not allow an empty object if minProperties is set to 1', () => { const T = Type.Object( { a: Type.Optional(Type.Number()), b: Type.Optional(Type.String()), }, { additionalProperties: false, minProperties: 1 }, ) Ok(T, { a: 1 }) Ok(T, { b: 'hello' }) Fail(T, {}) }) it('Should not allow 3 properties if maxProperties is set to 2', () => { const T = Type.Object( { a: Type.Optional(Type.Number()), b: Type.Optional(Type.String()), c: Type.Optional(Type.Boolean()), }, { additionalProperties: false, maxProperties: 2 }, ) Ok(T, { a: 1 }) Ok(T, { a: 1, b: 'hello' }) Fail(T, { a: 1, b: 'hello', c: true, }) }) it('Should not allow additionalProperties if additionalProperties is false', () => { const T = Type.Object( { a: Type.Number(), b: Type.String(), }, { additionalProperties: false }, ) Fail(T, { a: 1, b: 'hello', c: true, }) }) it('Should not allow properties for an empty object when additionalProperties is false', () => { const T = Type.Object({}, { additionalProperties: false }) Ok(T, {}) Fail(T, { a: 10 }) }) it('Should validate with non-syntax property keys', () => { const T = Type.Object({ 'with-hyphen': Type.Literal(1), '0-leading': Type.Literal(2), '$-leading': Type.Literal(3), '!@#$%^&*(': Type.Literal(4), }) Ok(T, { 'with-hyphen': 1, '0-leading': 2, '$-leading': 3, '!@#$%^&*(': 4, }) }) it('Should validate schema additional properties of string', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.String(), }, ) Ok(T, { x: 1, y: 2, z: 'hello', }) Fail(T, { x: 1, y: 2, z: 3, }) }) it('Should validate schema additional properties of array', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.Array(Type.Number()), }, ) Ok(T, { x: 1, y: 2, z: [0, 1, 2], }) Fail(T, { x: 1, y: 2, z: 3, }) }) it('Should validate schema additional properties of object', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.Object({ z: Type.Number(), }), }, ) Ok(T, { x: 1, y: 2, z: { z: 1 }, }) Fail(T, { x: 1, y: 2, z: 3, }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/omit.ts000066400000000000000000000035341505437577000246370ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' import { strictEqual } from 'assert' describe('compiler-ajv/Omit', () => { it('Should omit properties on the source schema', () => { const A = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { additionalProperties: false }, ) const T = Type.Omit(A, ['z']) Ok(T, { x: 1, y: 1 }) }) it('Should remove required properties on the target schema', () => { const A = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { additionalProperties: false }, ) const T = Type.Omit(A, ['z']) strictEqual(T.required!.includes('z'), false) }) it('Should delete the required property if no required properties remain', () => { const A = Type.Object( { x: Type.Optional(Type.Number()), y: Type.Readonly(Type.Optional(Type.Number())), z: Type.Number(), }, { additionalProperties: false }, ) const T = Type.Omit(A, ['z']) strictEqual(T.required, undefined) }) it('Should inherit options from the source object', () => { const A = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { additionalProperties: false }, ) const T = Type.Omit(A, ['z']) strictEqual(A.additionalProperties, false) strictEqual(T.additionalProperties, false) }) it('Should omit with keyof object', () => { const A = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }) const B = Type.Object({ x: Type.Number(), y: Type.Number(), }) const T = Type.Omit(A, Type.KeyOf(B), { additionalProperties: false }) Ok(T, { z: 0 }) Fail(T, { x: 0, y: 0, z: 0 }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/optional.ts000066400000000000000000000012761505437577000255150ustar00rootroot00000000000000import { strictEqual } from 'assert' import { Type } from '@sinclair/typebox' import { Ok } from './validate' describe('compiler-ajv/Optional', () => { it('Should validate object with optional', () => { const T = Type.Object( { a: Type.Optional(Type.String()), b: Type.String(), }, { additionalProperties: false }, ) Ok(T, { a: 'hello', b: 'world' }) Ok(T, { b: 'world' }) }) it('Should remove required value from schema', () => { const T = Type.Object( { a: Type.Optional(Type.String()), b: Type.String(), }, { additionalProperties: false }, ) strictEqual(T.required!.includes('a'), false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/partial.ts000066400000000000000000000031501505437577000253150ustar00rootroot00000000000000import { Type, ReadonlyKind, OptionalKind } from '@sinclair/typebox' import { Ok } from './validate' import { Assert } from '../assert' describe('compiler-ajv/Partial', () => { it('Should convert a required object into a partial.', () => { const A = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { additionalProperties: false }, ) const T = Type.Partial(A) Ok(T, { x: 1, y: 1, z: 1 }) Ok(T, { x: 1, y: 1 }) Ok(T, { x: 1 }) Ok(T, {}) }) it('Should update modifier types correctly when converting to partial', () => { const A = Type.Object( { x: Type.Readonly(Type.Optional(Type.Number())), y: Type.Readonly(Type.Number()), z: Type.Optional(Type.Number()), w: Type.Number(), }, { additionalProperties: false }, ) const T = Type.Partial(A) Assert.IsEqual(T.properties.x[ReadonlyKind], 'Readonly') Assert.IsEqual(T.properties.x[OptionalKind], 'Optional') Assert.IsEqual(T.properties.y[ReadonlyKind], 'Readonly') Assert.IsEqual(T.properties.y[OptionalKind], 'Optional') Assert.IsEqual(T.properties.z[OptionalKind], 'Optional') Assert.IsEqual(T.properties.w[OptionalKind], 'Optional') }) it('Should inherit options from the source object', () => { const A = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { additionalProperties: false }, ) const T = Type.Partial(A) Assert.IsEqual(A.additionalProperties, false) Assert.IsEqual(T.additionalProperties, false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/pick.ts000066400000000000000000000036171505437577000246170ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' import { Assert } from '../assert' describe('compiler-ajv/Pick', () => { it('Should pick properties from the source schema', () => { const Vector3 = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { additionalProperties: false }, ) const T = Type.Pick(Vector3, ['x', 'y']) Ok(T, { x: 1, y: 1 }) }) it('Should remove required properties on the target schema', () => { const A = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { additionalProperties: false }, ) const T = Type.Pick(A, ['x', 'y']) Assert.IsEqual(T.required!.includes('z'), false) }) it('Should delete the required property if no required properties remain', () => { const A = Type.Object( { x: Type.Optional(Type.Number()), y: Type.Readonly(Type.Optional(Type.Number())), z: Type.Number(), }, { additionalProperties: false }, ) const T = Type.Pick(A, ['x', 'y']) Assert.IsEqual(T.required, undefined) }) it('Should inherit options from the source object', () => { const A = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { additionalProperties: false }, ) const T = Type.Pick(A, ['x', 'y']) Assert.IsEqual(A.additionalProperties, false) Assert.IsEqual(T.additionalProperties, false) }) it('Should pick with keyof object', () => { const A = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }) const B = Type.Object({ x: Type.Number(), y: Type.Number(), }) const T = Type.Pick(A, Type.KeyOf(B), { additionalProperties: false }) Ok(T, { x: 0, y: 0 }) Fail(T, { x: 0, y: 0, z: 0 }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/readonly-optional.ts000066400000000000000000000013451505437577000273250ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok } from './validate' import { Assert } from '../assert' describe('compiler-ajv/ReadonlyOptional', () => { it('Should validate object with optional', () => { const T = Type.Object( { a: Type.Readonly(Type.Optional(Type.String())), b: Type.String(), }, { additionalProperties: false }, ) Ok(T, { a: 'hello', b: 'world' }) Ok(T, { b: 'world' }) }) it('Should remove required value from schema', () => { const T = Type.Object( { a: Type.Readonly(Type.Optional(Type.String())), b: Type.String(), }, { additionalProperties: false }, ) Assert.IsEqual(T.required!.includes('a'), false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/readonly.ts000066400000000000000000000013641505437577000255030ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok } from './validate' import { Assert } from '../assert' describe('compiler-ajv/Readonly', () => { it('Should validate object with readonly', () => { const T = Type.Object( { a: Type.Readonly(Type.String()), b: Type.Readonly(Type.String()), }, { additionalProperties: false }, ) Ok(T, { a: 'hello', b: 'world' }) }) it('Should retain required array on object', () => { const T = Type.Object( { a: Type.Readonly(Type.String()), b: Type.Readonly(Type.String()), }, { additionalProperties: false }, ) Assert.IsEqual(T.required!.includes('a'), true) Assert.IsEqual(T.required!.includes('b'), true) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/record.ts000066400000000000000000000230721505437577000251440ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler-ajv/Record', () => { it('Should validate when all property values are numbers', () => { const T = Type.Record(Type.String(), Type.Number()) Ok(T, { a: 1, b: 2, c: 3 }) }) it('Should validate when all property keys are strings', () => { const T = Type.Record(Type.String(), Type.Number()) Ok(T, { a: 1, b: 2, c: 3, '0': 4 }) }) it('Should not validate when below minProperties', () => { const T = Type.Record(Type.String(), Type.Number(), { minProperties: 4 }) Ok(T, { a: 1, b: 2, c: 3, d: 4 }) Fail(T, { a: 1, b: 2, c: 3 }) }) it('Should not validate when above maxProperties', () => { const T = Type.Record(Type.String(), Type.Number(), { maxProperties: 4 }) Ok(T, { a: 1, b: 2, c: 3, d: 4 }) Fail(T, { a: 1, b: 2, c: 3, d: 4, e: 5 }) }) it('Should not validate with illogical minProperties | maxProperties', () => { const T = Type.Record(Type.String(), Type.Number(), { minProperties: 5, maxProperties: 4 }) Fail(T, { a: 1, b: 2, c: 3 }) Fail(T, { a: 1, b: 2, c: 3, d: 4 }) Fail(T, { a: 1, b: 2, c: 3, d: 4, e: 5 }) }) it('Should validate when specifying string union literals when additionalProperties is true', () => { const K = Type.Union([Type.Literal('a'), Type.Literal('b'), Type.Literal('c')]) const T = Type.Record(K, Type.Number()) Ok(T, { a: 1, b: 2, c: 3, d: 'hello' }) }) it('Should not validate when specifying string union literals when additionalProperties is false', () => { const K = Type.Union([Type.Literal('a'), Type.Literal('b'), Type.Literal('c')]) const T = Type.Record(K, Type.Number(), { additionalProperties: false }) Fail(T, { a: 1, b: 2, c: 3, d: 'hello' }) }) it('Should validate for keyof records', () => { const T = Type.Object({ a: Type.String(), b: Type.Number(), c: Type.String(), }) const R = Type.Record(Type.KeyOf(T), Type.Number()) Ok(R, { a: 1, b: 2, c: 3 }) }) it('Should not validate for unknown key via keyof', () => { const T = Type.Object({ a: Type.String(), b: Type.Number(), c: Type.String(), }) const R = Type.Record(Type.KeyOf(T), Type.Number(), { additionalProperties: false }) Fail(R, { a: 1, b: 2, c: 3, d: 4 }) }) it('Should validate when specifying regular expressions', () => { const K = Type.RegExp(/^op_.*$/) const T = Type.Record(K, Type.Number()) Ok(T, { op_a: 1, op_b: 2, op_c: 3, }) }) it('Should not validate when specifying regular expressions and passing invalid property', () => { const K = Type.RegExp(/^op_.*$/) const T = Type.Record(K, Type.Number(), { additionalProperties: false }) Fail(T, { op_a: 1, op_b: 2, aop_c: 3, }) }) it('Should validate with quoted string pattern', () => { const K = Type.String({ pattern: "'(a|b|c)" }) const T = Type.Record(K, Type.Number()) Ok(T, { "'a": 1, "'b": 2, "'c": 3, }) }) it('Should validate with forward-slash pattern', () => { const K = Type.String({ pattern: '/(a|b|c)' }) const T = Type.Record(K, Type.Number()) Ok(T, { '/a': 1, '/b': 2, '/c': 3, }) }) // ------------------------------------------------------------ // Integer Keys // ------------------------------------------------------------ it('Should validate when all property keys are integers', () => { const T = Type.Record(Type.Integer(), Type.Number()) Ok(T, { '0': 1, '1': 2, '2': 3, '3': 4 }) }) it('Should validate when all property keys are integers, but one property is a string with varying type', () => { const T = Type.Record(Type.Integer(), Type.Number(), { additionalProperties: false }) Fail(T, { '0': 1, '1': 2, '2': 3, '3': 4, a: 'hello' }) }) it('Should not validate if passing a leading zeros for integers keys', () => { const T = Type.Record(Type.Integer(), Type.Number(), { additionalProperties: false }) Fail(T, { '00': 1, '01': 2, '02': 3, '03': 4, }) }) it('Should not validate if passing a signed integers keys', () => { const T = Type.Record(Type.Integer(), Type.Number(), { additionalProperties: false }) Fail(T, { '-0': 1, '-1': 2, '-2': 3, '-3': 4, }) }) // ------------------------------------------------------------ // Number Keys // ------------------------------------------------------------ it('Should validate when all property keys are numbers', () => { const T = Type.Record(Type.Number(), Type.Number()) Ok(T, { '0': 1, '1': 2, '2': 3, '3': 4 }) }) it('Should validate when all property keys are numbers, but one property is a string with varying type', () => { const T = Type.Record(Type.Number(), Type.Number(), { additionalProperties: false }) Fail(T, { '0': 1, '1': 2, '2': 3, '3': 4, a: 'hello' }) }) it('Should not validate if passing a leading zeros for numeric keys', () => { const T = Type.Record(Type.Number(), Type.Number(), { additionalProperties: false }) Fail(T, { '00': 1, '01': 2, '02': 3, '03': 4, }) }) it('Should not validate if passing a signed numeric keys', () => { const T = Type.Record(Type.Number(), Type.Number(), { additionalProperties: false }) Fail(T, { '-0': 1, '-1': 2, '-2': 3, '-3': 4, }) }) it('Should not validate when all property keys are numbers, but one property is a string with varying type', () => { const T = Type.Record(Type.Number(), Type.Number(), { additionalProperties: false }) Fail(T, { '0': 1, '1': 2, '2': 3, '3': 4, a: 'hello' }) }) // ------------------------------------------------------------ // AdditionalProperties // ------------------------------------------------------------ it('AdditionalProperties 1', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: true }) Ok(T, { 1: '', 2: '', x: 1, y: 2, z: 3 }) }) it('AdditionalProperties 2', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: false }) Ok(T, { 1: '', 2: '', 3: '' }) }) it('AdditionalProperties 3', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: false }) Fail(T, { 1: '', 2: '', x: '' }) }) it('AdditionalProperties 4', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: Type.Boolean() }) Fail(T, { 1: '', 2: '', x: '' }) }) it('AdditionalProperties 5', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: Type.Boolean() }) Ok(T, { 1: '', 2: '', x: true }) }) // ---------------------------------------------------------------- // TemplateLiteral // ---------------------------------------------------------------- it('TemplateLiteral 1', () => { const K = Type.TemplateLiteral('key${number}') const R = Type.Record(K, Type.Number(), { additionalProperties: false }) Ok(R, { key0: 1, key1: 1, key2: 1, }) }) it('TemplateLiteral 2', () => { const K = Type.TemplateLiteral('key${number}') const R = Type.Record(K, Type.Number()) Ok(R, { keyA: 0 }) }) it('TemplateLiteral 3', () => { const K = Type.TemplateLiteral('key${number}') const R = Type.Record(K, Type.Number(), { additionalProperties: false }) Fail(R, { keyA: 0 }) }) it('TemplateLiteral 4', () => { const K = Type.TemplateLiteral('key${number}') const R = Type.Record(K, Type.Number()) const T = Type.Object({ x: Type.Number(), y: Type.Number() }) const I = Type.Intersect([R, T], { unevaluatedProperties: false }) Ok(I, { x: 1, y: 2, key0: 1, key1: 1, key2: 1, }) }) it('TemplateLiteral 5', () => { const K = Type.TemplateLiteral('key${number}') const R = Type.Record(K, Type.Number()) const T = Type.Object({ x: Type.Number(), y: Type.Number() }) const I = Type.Intersect([R, T]) Ok(I, { x: 1, y: 2, z: 3, key0: 1, key1: 1, key2: 1, }) }) it('TemplateLiteral 6', () => { const K = Type.TemplateLiteral('key${number}') const R = Type.Record(K, Type.Number()) const T = Type.Object({ x: Type.Number(), y: Type.Number() }) const I = Type.Intersect([R, T], { unevaluatedProperties: false }) Fail(I, { x: 1, y: 2, z: 3, key0: 1, key1: 1, key2: 1, }) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/916 // ---------------------------------------------------------------- it('Should validate for string keys', () => { const T = Type.Record(Type.String(), Type.Null(), { additionalProperties: false, }) Ok(T, { a: null, b: null, 0: null, 1: null, }) }) it('Should validate for number keys', () => { const T = Type.Record(Type.Number(), Type.Null(), { additionalProperties: false, }) Fail(T, { a: null, b: null, 0: null, 1: null, }) Ok(T, { 0: null, 1: null, }) }) it('Should validate for any keys', () => { const T = Type.Record(Type.Any(), Type.Null(), { additionalProperties: false, }) Ok(T, { a: null, b: null, 0: null, 1: null, }) }) it('Should validate for never keys', () => { const T = Type.Record(Type.Never(), Type.Null(), { additionalProperties: false, }) Ok(T, {}) Fail(T, { a: null, b: null, 0: null, 1: null, }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/recursive.ts000066400000000000000000000034561505437577000257010ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' import { Assert } from '../assert/index' describe('compiler-ajv/Recursive', () => { it('Should generate default ordinal $id if not specified', () => { const Node = Type.Recursive((Node) => Type.Object({ id: Type.String(), nodes: Type.Array(Node), }), ) Assert.IsFalse(Node.$id === undefined) }) it('Should override default ordinal $id if specified', () => { const Node = Type.Recursive( (Node) => Type.Object({ id: Type.String(), nodes: Type.Array(Node), }), { $id: 'Node' }, ) Assert.IsEqual(Node.$id === 'Node', true) }) it('Should validate recursive node type', () => { const Node = Type.Recursive((This) => Type.Object({ id: Type.String(), nodes: Type.Array(This), }), ) Ok(Node, { id: 'A', nodes: [ { id: 'B', nodes: [] }, { id: 'C', nodes: [] }, ], }) }) it('Should validate wrapped recursive node type', () => { const Node = Type.Tuple([ Type.Recursive((This) => Type.Object({ id: Type.String(), nodes: Type.Array(This), }), ), ]) Ok(Node, [ { id: 'A', nodes: [ { id: 'B', nodes: [] }, { id: 'C', nodes: [] }, ], }, ]) }) it('Should not validate wrapped recursive node type with invalid id', () => { const Node = Type.Tuple([ Type.Recursive((This) => Type.Object({ id: Type.String(), nodes: Type.Array(This), }), ), ]) Fail(Node, [ { id: 'A', nodes: [ { id: 1, nodes: [] }, { id: 'C', nodes: [] }, ], }, ]) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/ref.ts000066400000000000000000000034301505437577000244360ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler-ajv/Ref', () => { // ---------------------------------------------------------------- // Deprecated // ---------------------------------------------------------------- it('Should validate for Ref(Schema)', () => { const T = Type.Number({ $id: 'T' }) const R = Type.Ref(T) Ok(R, 1234, [T]) Fail(R, 'hello', [T]) }) // ---------------------------------------------------------------- // Standard // ---------------------------------------------------------------- it('Should should validate when referencing a type', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { $id: 'T' }, ) const R = Type.Ref(T.$id!) Ok( R, { x: 1, y: 2, z: 3, }, [T], ) }) it('Should not validate when passing invalid data', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { $id: 'T' }, ) const R = Type.Ref(T.$id!) Fail( R, { x: 1, y: 2, }, [T], ) }) it('Should de-reference object property schema', () => { const R = Type.Object( { name: Type.String(), }, { $id: 'R' }, ) const T = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), r: Type.Optional(Type.Ref(R.$id!)), }, { $id: 'T' }, ) Ok(T, { x: 1, y: 2, z: 3 }, [R]) Ok(T, { x: 1, y: 2, z: 3, r: { name: 'hello' } }, [R]) Fail(T, { x: 1, y: 2, z: 3, r: { name: 1 } }, [R]) Fail(T, { x: 1, y: 2, z: 3, r: {} }, [R]) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/required.ts000066400000000000000000000035441505437577000255100ustar00rootroot00000000000000import { Type, ReadonlyKind, OptionalKind } from '@sinclair/typebox' import { Ok, Fail } from './validate' import { Assert } from '../assert' describe('compiler-ajv/Required', () => { it('Should convert a partial object into a required object', () => { const A = Type.Object( { x: Type.Optional(Type.Number()), y: Type.Optional(Type.Number()), z: Type.Optional(Type.Number()), }, { additionalProperties: false }, ) const T = Type.Required(A) Ok(T, { x: 1, y: 1, z: 1 }) Fail(T, { x: 1, y: 1 }) Fail(T, { x: 1 }) Fail(T, {}) }) it('Should update modifier types correctly when converting to required', () => { const A = Type.Object({ x: Type.Readonly(Type.Optional(Type.Number())), y: Type.Readonly(Type.Number()), z: Type.Optional(Type.Number()), w: Type.Number(), }) const T = Type.Required(A) Assert.IsEqual(T.properties.x[ReadonlyKind], 'Readonly') Assert.IsEqual(T.properties.y[ReadonlyKind], 'Readonly') Assert.IsEqual(T.properties.z[OptionalKind], undefined) Assert.IsEqual(T.properties.w[OptionalKind], undefined) }) it('Should inherit options from the source object', () => { const A = Type.Object( { x: Type.Optional(Type.Number()), y: Type.Optional(Type.Number()), z: Type.Optional(Type.Number()), }, { additionalPropeties: false }, ) const T = Type.Required(A) Assert.IsEqual(A.additionalPropeties, false) Assert.IsEqual(T.additionalPropeties, false) }) // it('Should construct new object when targetting reference', () => { // const T = Type.Object({ a: Type.String(), b: Type.String() }, { $id: 'T' }) // const R = Type.Ref(T) // const P = Type.Required(R) // strictEqual(P.properties.a.type, 'string') // strictEqual(P.properties.b.type, 'string') // }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/string-pattern.ts000066400000000000000000000033761505437577000266540ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler-ajv/StringPattern', () => { //----------------------------------------------------- // Regular Expression //----------------------------------------------------- it('Should validate regular expression 1', () => { const T = Type.String({ pattern: /[012345]/.source }) Ok(T, '0') Ok(T, '1') Ok(T, '2') Ok(T, '3') Ok(T, '4') Ok(T, '5') }) it('Should validate regular expression 2', () => { const T = Type.String({ pattern: /true|false/.source }) Ok(T, 'true') Ok(T, 'true') Ok(T, 'true') Ok(T, 'false') Ok(T, 'false') Ok(T, 'false') Fail(T, '6') }) it('Should validate regular expression 3', () => { const T = Type.String({ pattern: /true|false/.source }) Fail(T, 'unknown') }) it('Should validate regular expression 4', () => { const T = Type.String({ pattern: /[\d]{5}/.source }) Ok(T, '12345') }) //----------------------------------------------------- // Regular Pattern //----------------------------------------------------- it('Should validate pattern 1', () => { const T = Type.String({ pattern: '[012345]' }) Ok(T, '0') Ok(T, '1') Ok(T, '2') Ok(T, '3') Ok(T, '4') Ok(T, '5') }) it('Should validate pattern 2', () => { const T = Type.String({ pattern: 'true|false' }) Ok(T, 'true') Ok(T, 'true') Ok(T, 'true') Ok(T, 'false') Ok(T, 'false') Ok(T, 'false') Fail(T, '6') }) it('Should validate pattern 3', () => { const T = Type.String({ pattern: 'true|false' }) Fail(T, 'unknown') }) it('Should validate pattern 4', () => { const T = Type.String({ pattern: '[\\d]{5}' }) Ok(T, '12345') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/string.ts000066400000000000000000000031321505437577000251670ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler-ajv/String', () => { it('Should not validate number', () => { const T = Type.String() Fail(T, 1) }) it('Should validate string', () => { const T = Type.String() Ok(T, 'hello') }) it('Should not validate boolean', () => { const T = Type.String() Fail(T, true) }) it('Should not validate array', () => { const T = Type.String() Fail(T, [1, 2, 3]) }) it('Should not validate object', () => { const T = Type.String() Fail(T, { a: 1, b: 2 }) }) it('Should not validate null', () => { const T = Type.String() Fail(T, null) }) it('Should not validate undefined', () => { const T = Type.String() Fail(T, undefined) }) it('Should validate string format as email', () => { const T = Type.String({ format: 'email' }) Ok(T, 'name@domain.com') }) it('Should validate string format as uuid', () => { const T = Type.String({ format: 'uuid' }) Ok(T, '4a7a17c9-2492-4a53-8e13-06ea2d3f3bbf') }) it('Should validate string format as iso8601 date', () => { const T = Type.String({ format: 'date-time' }) Ok(T, '2021-06-11T20:30:00-04:00') }) it('Should validate minLength', () => { const T = Type.String({ minLength: 4 }) Ok(T, '....') Fail(T, '...') }) it('Should validate maxLength', () => { const T = Type.String({ maxLength: 4 }) Ok(T, '....') Fail(T, '.....') }) it('Should pass numeric 5 digit test', () => { const T = Type.String({ pattern: '[\\d]{5}' }) Ok(T, '12345') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/template-literal.ts000066400000000000000000000100151505437577000271240ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler-ajv/TemplateLiteral', () => { // -------------------------------------------------------- // Finite // -------------------------------------------------------- it('Should validate finite pattern 1', () => { // prettier-ignore const T = Type.TemplateLiteral([]) Ok(T, '') Fail(T, 'X') }) it('Should validate finite pattern 1', () => { // prettier-ignore const T = Type.TemplateLiteral([Type.Boolean()]) Ok(T, 'true') Ok(T, 'false') Fail(T, 'X') }) it('Should validate finite pattern 2', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A') ]) Ok(T, 'A') Fail(T, 'X') }) it('Should validate finite pattern 3', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.Literal('B') ]) Ok(T, 'AB') Fail(T, 'X') }) it('Should validate finite pattern 4', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.Union([ Type.Literal('B'), Type.Literal('C') ]), ]) Ok(T, 'AB') Ok(T, 'AC') Fail(T, 'X') }) it('Should validate finite pattern 5', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.Union([ Type.Literal('B'), Type.Literal('C') ]), Type.Literal('D'), ]) Ok(T, 'ABD') Ok(T, 'ACD') Fail(T, 'X') }) it('Should validate finite pattern 6', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Union([ Type.Literal('0'), Type.Literal('1') ]), Type.Union([ Type.Literal('0'), Type.Literal('1') ]), ]) Ok(T, '00') Ok(T, '01') Ok(T, '10') Ok(T, '11') Fail(T, 'X') }) // -------------------------------------------------------- // Infinite // -------------------------------------------------------- it('Should validate infinite pattern 1', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Number() ]) Ok(T, '1') Ok(T, '22') Ok(T, '333') Ok(T, '4444') Fail(T, 'X') }) it('Should validate infinite pattern 2', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Integer() ]) Ok(T, '1') Ok(T, '22') Ok(T, '333') Ok(T, '4444') Fail(T, 'X') }) it('Should validate infinite pattern 3', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.BigInt() ]) Ok(T, '1') Ok(T, '22') Ok(T, '333') Ok(T, '4444') Fail(T, 'X') }) it('Should validate infinite pattern 4', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.String() ]) Ok(T, '1') Ok(T, '22') Ok(T, '333') Ok(T, '4444') Ok(T, 'a') Ok(T, 'bb') Ok(T, 'ccc') Ok(T, 'dddd') }) it('Should validate infinite pattern 5', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.Number() ]) Ok(T, 'A1') Ok(T, 'A22') Ok(T, 'A333') Ok(T, 'A4444') Fail(T, 'X') }) it('Should validate infinite pattern 6', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.Integer() ]) Ok(T, 'A1') Ok(T, 'A22') Ok(T, 'A333') Ok(T, 'A4444') Fail(T, 'X') }) it('Should validate infinite pattern 7', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.BigInt() ]) Ok(T, 'A1') Ok(T, 'A22') Ok(T, 'A333') Ok(T, 'A4444') Fail(T, 'X') }) it('Should validate infinite pattern 8', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.String() ]) Ok(T, 'A1') Ok(T, 'A22') Ok(T, 'A333') Ok(T, 'A4444') Ok(T, 'Aa') Ok(T, 'Abb') Ok(T, 'Accc') Ok(T, 'Adddd') Fail(T, 'X') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/tuple.ts000066400000000000000000000034541505437577000250210ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler-ajv/Tuple', () => { it('Should validate tuple of [string, number]', () => { const A = Type.String() const B = Type.Number() const T = Type.Tuple([A, B]) Ok(T, ['hello', 42]) }) it('Should not validate tuple of [string, number] when reversed', () => { const A = Type.String() const B = Type.Number() const T = Type.Tuple([A, B]) Fail(T, [42, 'hello']) }) it('Should validate with empty tuple', () => { const T = Type.Tuple([]) Ok(T, []) }) it('Should not validate with empty tuple with more items', () => { const T = Type.Tuple([]) Fail(T, [1]) }) it('Should not validate with empty tuple with less items', () => { const T = Type.Tuple([Type.Number(), Type.Number()]) Fail(T, [1]) }) it('Should validate tuple of objects', () => { const A = Type.Object({ a: Type.String() }) const B = Type.Object({ b: Type.Number() }) const T = Type.Tuple([A, B]) Ok(T, [{ a: 'hello' }, { b: 42 }]) }) it('Should not validate tuple of objects when reversed', () => { const A = Type.Object({ a: Type.String() }) const B = Type.Object({ b: Type.Number() }) const T = Type.Tuple([A, B]) Fail(T, [{ b: 42 }, { a: 'hello' }]) }) it('Should not validate tuple when array is less than tuple length', () => { const A = Type.Object({ a: Type.String() }) const B = Type.Object({ b: Type.Number() }) const T = Type.Tuple([A, B]) Fail(T, [{ a: 'hello' }]) }) it('Should not validate tuple when array is greater than tuple length', () => { const A = Type.Object({ a: Type.String() }) const B = Type.Object({ b: Type.Number() }) const T = Type.Tuple([A, B]) Fail(T, [{ a: 'hello' }, { b: 42 }, { b: 42 }]) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/uint8array.ts000066400000000000000000000030051505437577000257660ustar00rootroot00000000000000// --------------------------------------------------- // No Longer Supported // --------------------------------------------------- // import { Type } from '@sinclair/typebox' // import { Ok, Fail } from './validate' // describe('compiler-ajv/Uint8Array', () => { // it('Should not validate number', () => { // const T = Type.Uint8Array() // Fail(T, 1) // }) // it('Should not validate string', () => { // const T = Type.Uint8Array() // Fail(T, 'hello') // }) // it('Should not validate boolean', () => { // const T = Type.Uint8Array() // Fail(T, true) // }) // it('Should not validate array', () => { // const T = Type.Uint8Array() // Fail(T, [1, 2, 3]) // }) // it('Should not validate object', () => { // const T = Type.Uint8Array() // Fail(T, { a: 1, b: 2 }) // }) // it('Should not validate null', () => { // const T = Type.Uint8Array() // Fail(T, null) // }) // it('Should not validate undefined', () => { // const T = Type.Uint8Array() // Fail(T, undefined) // }) // it('Should validate Uint8Array', () => { // const T = Type.Uint8Array() // Ok(T, new Uint8Array(100)) // }) // it('Should validate minByteLength', () => { // const T = Type.Uint8Array({ minByteLength: 4 }) // Ok(T, new Uint8Array(4)) // Fail(T, new Uint8Array(3)) // }) // it('Should validate maxByteLength', () => { // const T = Type.Uint8Array({ maxByteLength: 4 }) // Ok(T, new Uint8Array(4)) // Fail(T, new Uint8Array(5)) // }) // }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/union.ts000066400000000000000000000043751505437577000250230ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler-ajv/Union', () => { it('Should validate union of string, number and boolean', () => { const A = Type.String() const B = Type.Number() const C = Type.Boolean() const T = Type.Union([A, B, C]) Ok(T, 'hello') Ok(T, true) Ok(T, 42) }) it('Should validate union of objects', () => { const A = Type.Object({ a: Type.String() }, { additionalProperties: false }) const B = Type.Object({ b: Type.String() }, { additionalProperties: false }) const T = Type.Union([A, B]) Ok(T, { a: 'hello' }) Ok(T, { b: 'world' }) }) it('Should fail to validate for descriminated union types', () => { const A = Type.Object({ kind: Type.Literal('A'), value: Type.String() }) const B = Type.Object({ kind: Type.Literal('B'), value: Type.Number() }) const T = Type.Union([A, B]) Fail(T, { kind: 'A', value: 42 }) // expect { kind: 'A', value: string } Fail(T, { kind: 'B', value: 'hello' }) // expect { kind: 'B', value: number } }) it('Should validate union of objects where properties overlap', () => { const A = Type.Object({ a: Type.String() }, { additionalProperties: false }) const B = Type.Object({ a: Type.String(), b: Type.String() }, { additionalProperties: false }) const T = Type.Union([A, B]) Ok(T, { a: 'hello' }) // A Ok(T, { a: 'hello', b: 'world' }) // B }) it('Should validate union of overlapping property of varying type', () => { const A = Type.Object({ a: Type.String(), b: Type.Number() }, { additionalProperties: false }) const B = Type.Object({ a: Type.String(), b: Type.String() }, { additionalProperties: false }) const T = Type.Union([A, B]) Ok(T, { a: 'hello', b: 42 }) // A Ok(T, { a: 'hello', b: 'world' }) // B }) it('Should validate union of literal strings', () => { const A = Type.Literal('hello') const B = Type.Literal('world') const T = Type.Union([A, B]) Ok(T, 'hello') // A Ok(T, 'world') // B }) it('Should not validate union of literal strings for unknown string', () => { const A = Type.Literal('hello') const B = Type.Literal('world') const T = Type.Union([A, B]) Fail(T, 'foo') // A Fail(T, 'bar') // B }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/unknown.ts000066400000000000000000000013361505437577000253640ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok } from './validate' describe('compiler-ajv/Unknown', () => { it('Should validate number', () => { const T = Type.Any() Ok(T, 1) }) it('Should validate string', () => { const T = Type.Any() Ok(T, 'hello') }) it('Should validate boolean', () => { const T = Type.Any() Ok(T, true) }) it('Should validate array', () => { const T = Type.Any() Ok(T, [1, 2, 3]) }) it('Should validate object', () => { const T = Type.Any() Ok(T, { a: 1, b: 2 }) }) it('Should validate null', () => { const T = Type.Any() Ok(T, null) }) it('Should validate undefined', () => { const T = Type.Any() Ok(T, undefined) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/unsafe.ts000066400000000000000000000007151505437577000251460ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler-ajv/Unsafe', () => { it('Should validate an unsafe type', () => { const T = Type.Unsafe({ type: 'object', properties: { x: { type: 'number' }, y: { type: 'number' }, z: { type: 'number' }, }, additionalProperties: false, }) Ok(T, { x: 1, y: 2, z: 3 }) Fail(T, { x: 1, y: 2, z: 3, w: 4 }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/validate.ts000066400000000000000000000065441505437577000254640ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Value } from '@sinclair/typebox/value' import { TSchema } from '@sinclair/typebox' import addFormats from 'ajv-formats' import Ajv, { AnySchema } from 'ajv/dist/2019' function schemaOf(schemaOf: string, value: unknown, schema: unknown) { switch (schemaOf) { case 'Constructor': return TypeGuard.IsConstructor(schema) && Value.Check(schema, value) case 'Function': return TypeGuard.IsFunction(schema) && Value.Check(schema, value) case 'Date': return TypeGuard.IsDate(schema) && Value.Check(schema, value) case 'Promise': return TypeGuard.IsPromise(schema) && Value.Check(schema, value) case 'Uint8Array': return TypeGuard.IsUint8Array(schema) && Value.Check(schema, value) case 'Undefined': return TypeGuard.IsUndefined(schema) && Value.Check(schema, value) case 'Void': return TypeGuard.IsVoid(schema) && Value.Check(schema, value) default: return false } } export function createAjv(references: AnySchema[]) { return addFormats(new Ajv({}), ['date-time', 'time', 'date', 'email', 'hostname', 'ipv4', 'ipv6', 'uri', 'uri-reference', 'uuid', 'uri-template', 'json-pointer', 'relative-json-pointer', 'regex']) .addKeyword({ type: 'object', keyword: 'instanceOf', validate: schemaOf }) .addKeyword({ type: 'null', keyword: 'typeOf', validate: schemaOf }) .addKeyword('exclusiveMinimumTimestamp') .addKeyword('exclusiveMaximumTimestamp') .addKeyword('minimumTimestamp') .addKeyword('maximumTimestamp') .addKeyword('minByteLength') .addKeyword('maxByteLength') .addSchema(references) } export function Ok(type: T, data: unknown, additional: AnySchema[] = []) { const ajv = createAjv(additional) function execute() { // required as ajv will throw if referenced schema is not found try { return ajv.validate(type, data) as boolean } catch { return false } } if (execute() === false) { console.log('---------------------------') console.log('type') console.log('---------------------------') console.log(JSON.stringify(type, null, 2)) console.log('---------------------------') console.log('data') console.log('---------------------------') console.log(JSON.stringify(data, null, 2)) console.log('---------------------------') console.log('errors') console.log('---------------------------') console.log(ajv.errorsText(ajv.errors)) throw Error('expected ok') } } export function Fail(type: T, data: unknown, additional: AnySchema[] = []) { const ajv = createAjv(additional) function execute() { // required as ajv will throw if referenced schema is not found try { return ajv.validate(type, data) as boolean } catch { return false } } if (execute() === true) { console.log('---------------------------') console.log('type') console.log('---------------------------') console.log(JSON.stringify(type, null, 2)) console.log('---------------------------') console.log('data') console.log('---------------------------') console.log(JSON.stringify(data, null, 2)) console.log('---------------------------') console.log('errors') console.log('---------------------------') console.log(ajv.errorsText(ajv.errors)) throw Error('expected ok') } } sinclairzx81-typebox-e0ec98c/test/runtime/compiler-ajv/void.ts000066400000000000000000000014141505437577000246230ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler-ajv/Void', () => { it('Should not validate number', () => { const T = Type.Void() Fail(T, 1) }) it('Should not validate string', () => { const T = Type.Void() Fail(T, 'hello') }) it('Should not validate boolean', () => { const T = Type.Void() Fail(T, true) }) it('Should not validate array', () => { const T = Type.Void() Fail(T, [1, 2, 3]) }) it('Should not validate object', () => { const T = Type.Void() Fail(T, { a: 1, b: 2 }) }) it('Should validate null', () => { const T = Type.Null() Ok(T, null) }) it('Should not validate undefined', () => { const T = Type.Void() Fail(T, undefined) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/000077500000000000000000000000001505437577000225345ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/compiler/__members.ts000066400000000000000000000015261505437577000250400ustar00rootroot00000000000000import { TypeCompiler } from '@sinclair/typebox/compiler' import { Type, TypeGuard, ValueGuard } from '@sinclair/typebox' import { Assert } from '../assert/index' describe('compiler/TypeCheckMembers', () => { it('Should return Schema', () => { const A = TypeCompiler.Compile(Type.Number(), [Type.String(), Type.Boolean()]) Assert.IsTrue(TypeGuard.IsNumber(A.Schema())) }) it('Should return References', () => { const A = TypeCompiler.Compile(Type.Number(), [Type.String(), Type.Boolean()]) Assert.IsTrue(TypeGuard.IsNumber(A.Schema())) Assert.IsTrue(TypeGuard.IsString(A.References()[0])) Assert.IsTrue(TypeGuard.IsBoolean(A.References()[1])) }) it('Should return Code', () => { const A = TypeCompiler.Compile(Type.Number(), [Type.String(), Type.Boolean()]) Assert.IsTrue(ValueGuard.IsString(A.Code())) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/any.ts000066400000000000000000000016121505437577000236730ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok } from './validate' describe('compiler/Any', () => { it('Should validate number', () => { const T = Type.Any() Ok(T, 1) }) it('Should validate string', () => { const T = Type.Any() Ok(T, 'hello') }) it('Should validate boolean', () => { const T = Type.Any() Ok(T, true) }) it('Should validate array', () => { const T = Type.Any() Ok(T, [1, 2, 3]) }) it('Should validate object', () => { const T = Type.Any() Ok(T, { a: 1, b: 2 }) }) it('Should validate null', () => { const T = Type.Any() Ok(T, null) }) it('Should validate undefined', () => { const T = Type.Any() Ok(T, undefined) }) it('Should validate bigint', () => { const T = Type.Any() Ok(T, BigInt(1)) }) it('Should validate symbol', () => { const T = Type.Any() Ok(T, Symbol(1)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/argument.ts000066400000000000000000000017051505437577000247310ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok } from './validate' describe('compiler/Argument', () => { it('Should validate number', () => { const T = Type.Argument(0) Ok(T, 1) }) it('Should validate string', () => { const T = Type.Argument(0) Ok(T, 'hello') }) it('Should validate boolean', () => { const T = Type.Argument(0) Ok(T, true) }) it('Should validate array', () => { const T = Type.Argument(0) Ok(T, [1, 2, 3]) }) it('Should validate object', () => { const T = Type.Argument(0) Ok(T, { a: 1, b: 2 }) }) it('Should validate null', () => { const T = Type.Argument(0) Ok(T, null) }) it('Should validate undefined', () => { const T = Type.Argument(0) Ok(T, undefined) }) it('Should validate bigint', () => { const T = Type.Argument(0) Ok(T, BigInt(1)) }) it('Should validate symbol', () => { const T = Type.Argument(0) Ok(T, Symbol(1)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/array.ts000066400000000000000000000142341505437577000242260ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Array', () => { it('Should validate an array of any', () => { const T = Type.Array(Type.Any()) Ok(T, [0, true, 'hello', {}]) }) it('Should not validate varying array when item is number', () => { const T = Type.Array(Type.Number()) Fail(T, [1, 2, 3, 'hello']) }) it('Should validate for an array of unions', () => { const T = Type.Array(Type.Union([Type.Number(), Type.String()])) Ok(T, [1, 'hello', 3, 'world']) }) it('Should not validate for an array of unions where item is not in union.', () => { const T = Type.Array(Type.Union([Type.Number(), Type.String()])) Fail(T, [1, 'hello', 3, 'world', true]) }) it('Should validate for an empty array', () => { const T = Type.Array(Type.Union([Type.Number(), Type.String()])) Ok(T, []) }) it('Should validate for an array of intersection types', () => { const A = Type.Object({ a: Type.String() }) const B = Type.Object({ b: Type.String() }) const C = Type.Intersect([A, B]) const T = Type.Array(C) Ok(T, [ { a: 'hello', b: 'hello' }, { a: 'hello', b: 'hello' }, { a: 'hello', b: 'hello' }, ]) }) it('Should not validate for an array of composite types when passing additionalProperties false', () => { const A = Type.Object({ a: Type.String() }) const B = Type.Object({ b: Type.String() }) const C = Type.Composite([A, B], { additionalProperties: false }) const T = Type.Array(C) Fail(T, [ { a: 'hello', b: 'hello' }, { a: 'hello', b: 'hello' }, { a: 'hello', b: 'hello', c: 'additional' }, ]) }) it('Should validate an array of tuples', () => { const A = Type.String() const B = Type.Number() const C = Type.Tuple([A, B]) const T = Type.Array(C) Ok(T, [ ['hello', 1], ['hello', 1], ['hello', 1], ]) }) it('Should not validate an array of tuples when tuple values are incorrect', () => { const A = Type.String() const B = Type.Number() const C = Type.Tuple([A, B]) const T = Type.Array(C) Fail(T, [ [1, 'hello'], [1, 'hello'], [1, 'hello'], ]) }) it('Should not validate array with failed minItems', () => { const T = Type.Array(Type.Number(), { minItems: 3 }) Fail(T, [0, 1]) }) it('Should not validate array with failed maxItems', () => { const T = Type.Array(Type.Number(), { maxItems: 3 }) Fail(T, [0, 1, 2, 3]) }) // --------------------------------------------------------- // Unique Items // --------------------------------------------------------- it('Should validate array with uniqueItems when items are distinct objects', () => { const T = Type.Array(Type.Object({ x: Type.Number(), y: Type.Number() }), { uniqueItems: true }) Ok(T, [ { x: 0, y: 1 }, { x: 1, y: 0 }, ]) }) it('Should not validate array with uniqueItems when items are not distinct objects', () => { const T = Type.Array(Type.Object({ x: Type.Number(), y: Type.Number() }), { uniqueItems: true }) Fail(T, [ { x: 1, y: 0 }, { x: 1, y: 0 }, ]) }) it('Should not validate array with non uniqueItems', () => { const T = Type.Array(Type.Number(), { uniqueItems: true }) Fail(T, [0, 0]) }) // --------------------------------------------------------- // Contains // --------------------------------------------------------- it('Should validate for contains', () => { const T = Type.Array(Type.Number(), { contains: Type.Literal(1) }) Ok(T, [1]) Ok(T, [1, 2]) Fail(T, []) Fail(T, [2]) }) it('Should validate for minContains', () => { const T = Type.Array(Type.Number(), { contains: Type.Literal(1), minContains: 3 }) Ok(T, [1, 1, 1, 2]) Ok(T, [2, 1, 1, 1, 2]) Ok(T, [1, 1, 1]) Fail(T, []) Fail(T, [1, 1]) Fail(T, [2]) }) it('Should validate for maxContains', () => { const T = Type.Array(Type.Number(), { contains: Type.Literal(1), maxContains: 3 }) Ok(T, [1, 1, 1]) Ok(T, [1, 1]) Ok(T, [2, 2, 2, 2, 1, 1, 1]) Fail(T, [1, 1, 1, 1]) }) it('Should validate for minContains and maxContains', () => { const T = Type.Array(Type.Number(), { contains: Type.Literal(1), minContains: 3, maxContains: 5 }) Fail(T, [1, 1]) Ok(T, [1, 1, 1]) Ok(T, [1, 1, 1, 1]) Ok(T, [1, 1, 1, 1, 1]) Fail(T, [1, 1, 1, 1, 1, 1]) }) it('Should not validate minContains or maxContains when contains is unspecified', () => { const T = Type.Array(Type.Number(), { minContains: 3, maxContains: 5 }) Fail(T, [1, 1]) Fail(T, [1, 1, 1]) Fail(T, [1, 1, 1, 1]) Fail(T, [1, 1, 1, 1, 1]) Fail(T, [1, 1, 1, 1, 1, 1]) }) it('Should produce illogical schema when contains is not sub type of items', () => { const T = Type.Array(Type.Number(), { contains: Type.String(), minContains: 3, maxContains: 5 }) Fail(T, [1, 1]) Fail(T, [1, 1, 1]) Fail(T, [1, 1, 1, 1]) Fail(T, [1, 1, 1, 1, 1]) Fail(T, [1, 1, 1, 1, 1, 1]) }) // ---------------------------------------------------------------- // Issue: https://github.com/sinclairzx81/typebox/discussions/607 // ---------------------------------------------------------------- it('Should correctly handle undefined array properties', () => { const Answer = Type.Object({ text: Type.String(), isCorrect: Type.Boolean(), }) const Question = Type.Object({ text: Type.String(), options: Type.Array(Answer, { minContains: 1, maxContains: 1, contains: Type.Object({ text: Type.String(), isCorrect: Type.Literal(true), }), }), }) Fail(Question, { text: 'A' }) Fail(Question, { text: 'A', options: [] }) Ok(Question, { text: 'A', options: [{ text: 'A', isCorrect: true }] }) Ok(Question, { text: 'A', options: [ { text: 'A', isCorrect: true }, { text: 'B', isCorrect: false }, ], }) Fail(Question, { text: 'A', options: [{ text: 'A', isCorrect: false }] }) Fail(Question, { text: 'A', options: [ { text: 'A', isCorrect: true }, { text: 'B', isCorrect: true }, ], }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/async-iterator.ts000066400000000000000000000010441505437577000260470ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/AsyncIterator', () => { it('Should validate a async iterator 1', () => { async function* f() {} const T = Type.AsyncIterator(Type.Any()) Ok(T, f()) }) it('Should validate a async iterator 2', () => { const T = Type.AsyncIterator(Type.Any()) Ok(T, { [Symbol.asyncIterator]: () => {}, }) }) it('Should not validate a async iterator', () => { const T = Type.AsyncIterator(Type.Any()) Fail(T, {}) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/bigint.ts000066400000000000000000000040171505437577000243620ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/BigInt', () => { it('Should not validate number', () => { const T = Type.BigInt() Fail(T, 3.14) }) it('Should not validate NaN', () => { const T = Type.BigInt() Fail(T, NaN) }) it('Should not validate +Infinity', () => { const T = Type.BigInt() Fail(T, Infinity) }) it('Should not validate -Infinity', () => { const T = Type.BigInt() Fail(T, -Infinity) }) it('Should not validate integer', () => { const T = Type.BigInt() Fail(T, 1) }) it('Should not validate string', () => { const T = Type.BigInt() Fail(T, 'hello') }) it('Should not validate boolean', () => { const T = Type.BigInt() Fail(T, true) }) it('Should not validate array', () => { const T = Type.BigInt() Fail(T, [1, 2, 3]) }) it('Should not validate object', () => { const T = Type.BigInt() Fail(T, { a: 1, b: 2 }) }) it('Should not validate null', () => { const T = Type.BigInt() Fail(T, null) }) it('Should not validate undefined', () => { const T = Type.BigInt() Fail(T, undefined) }) it('Should not validate symbol', () => { const T = Type.BigInt() Fail(T, Symbol()) }) it('Should validate bigint', () => { const T = Type.BigInt() Ok(T, BigInt(1)) }) it('Should validate minimum', () => { const T = Type.BigInt({ minimum: BigInt(10) }) Fail(T, BigInt(9)) Ok(T, BigInt(10)) }) it('Should validate maximum', () => { const T = Type.BigInt({ maximum: BigInt(10) }) Ok(T, BigInt(10)) Fail(T, BigInt(11)) }) it('Should validate Date exclusiveMinimum', () => { const T = Type.BigInt({ exclusiveMinimum: BigInt(10) }) Fail(T, BigInt(10)) Ok(T, BigInt(11)) }) it('Should validate Date exclusiveMaximum', () => { const T = Type.BigInt({ exclusiveMaximum: BigInt(10) }) Ok(T, BigInt(9)) Fail(T, BigInt(10)) }) it('Should not validate NaN', () => { Fail(Type.Number(), NaN) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/boolean.ts000066400000000000000000000017731505437577000245330ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Boolean', () => { it('Should validate a boolean', () => { const T = Type.Boolean() Ok(T, true) Ok(T, false) }) it('Should not validate a number', () => { const T = Type.Boolean() Fail(T, 1) }) it('Should not validate a string', () => { const T = Type.Boolean() Fail(T, 'true') }) it('Should not validate an array', () => { const T = Type.Boolean() Fail(T, [true]) }) it('Should not validate an object', () => { const T = Type.Boolean() Fail(T, {}) }) it('Should not validate an null', () => { const T = Type.Boolean() Fail(T, null) }) it('Should not validate an undefined', () => { const T = Type.Boolean() Fail(T, undefined) }) it('Should not validate bigint', () => { const T = Type.Boolean() Fail(T, BigInt(1)) }) it('Should not validate symbol', () => { const T = Type.Boolean() Fail(T, Symbol(1)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/composite.ts000066400000000000000000000070231505437577000251100ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Composite', () => { it('Should compose two objects', () => { const A = Type.Object({ a: Type.String() }) const B = Type.Object({ b: Type.Number() }) const T = Type.Composite([A, B], { additionalProperties: false }) Ok(T, { a: 'hello', b: 42 }) }) it('Should compose with partial', () => { const A = Type.Partial(Type.Object({ a: Type.Number() })) const B = Type.Partial(Type.Object({ b: Type.Number() })) const P = Type.Composite([A, B], { additionalProperties: false }) Ok(P, { a: 1, b: 2 }) Ok(P, { a: 1 }) Ok(P, { b: 1 }) Ok(P, {}) Fail(P, { a: 1, b: 2, c: 3 }) Fail(P, { c: 1 }) }) it('Should compose with overlapping same type', () => { const A = Type.Object({ a: Type.Number() }) const B = Type.Object({ a: Type.Number() }) const P = Type.Composite([A, B]) Ok(P, { a: 1 }) Fail(P, { a: '1' }) }) it('Should not compose with overlapping varying type', () => { const A = Type.Object({ a: Type.Number() }) const B = Type.Object({ a: Type.String() }) const T = Type.Composite([A, B]) Fail(T, { a: 1 }) Fail(T, { a: 'hello' }) Fail(T, {}) }) it('Should compose with deeply nest overlapping varying type', () => { const A = Type.Object({ a: Type.Number() }) const B = Type.Object({ b: Type.String() }) const C = Type.Object({ c: Type.Boolean() }) const D = Type.Object({ d: Type.Null() }) const T = Type.Composite([A, B, C, D]) Ok(T, { a: 1, b: 'hello', c: true, d: null }) }) it('Should not compose with deeply nest overlapping varying type', () => { const A = Type.Object({ a: Type.Number() }) const B = Type.Object({ a: Type.String() }) const C = Type.Object({ a: Type.Boolean() }) const D = Type.Object({ a: Type.Null() }) const T = Type.Composite([A, B, C, D]) Fail(T, { a: 1 }) Fail(T, { a: 'hello' }) Fail(T, { a: false }) Fail(T, { a: null }) Fail(T, { a: [] }) Fail(T, {}) }) it('Should pick from composited type', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const C = Type.Object({ z: Type.Number() }) const T = Type.Composite([A, B, C]) const P = Type.Pick(T, ['x', 'y'], { additionalProperties: false }) Ok(P, { x: 1, y: 1 }) Fail(P, { x: 1, y: 1, z: 1 }) }) it('Should omit from composited type', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const C = Type.Object({ z: Type.Number() }) const T = Type.Composite([A, B, C]) const P = Type.Omit(T, ['z'], { additionalProperties: false }) Ok(P, { x: 1, y: 1 }) Fail(P, { x: 1, y: 1, z: 1 }) }) it('Should compose nested object properties', () => { const A = Type.Object({ x: Type.Object({ x: Type.Number() }) }) const B = Type.Object({ y: Type.Object({ x: Type.String() }) }) const T = Type.Composite([A, B]) Ok(T, { x: { x: 1 }, y: { x: '' } }) Fail(T, { x: { x: '1' }, y: { x: '' } }) Fail(T, { x: { x: 1 }, y: { x: 1 } }) }) // prettier-ignore it('Should composite intersection', () => { const T = Type.Composite([ Type.Intersect([ Type.Object({ x: Type.Number() }) ]), Type.Intersect([ Type.Object({ y: Type.Number() }) ]), Type.Intersect([ Type.Object({ z: Type.Number() }) ]), ]) Ok(T, { x: 1, y: 2, z: 3 }) Fail(T, { x: 1, y: 2, z: '3' }) Fail(T, { x: 1, y: 2 }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/const.ts000066400000000000000000000015661505437577000242420ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok } from './validate' describe('compiler/Const', () => { it('Should validate 1', () => { const T = Type.Const(1) Ok(T, 1) }) it('Should validate 2', () => { const T = Type.Const('hello') Ok(T, 'hello') }) it('Should validate 3', () => { const T = Type.Const(true) Ok(T, true) }) it('Should validate 4', () => { const T = Type.Const({ x: 1, y: 2 }) Ok(T, { x: 1, y: 2 }) }) it('Should validate 5', () => { const T = Type.Const([1, 2, 3]) Ok(T, [1, 2, 3]) }) it('Should validate 6', () => { const T = Type.Const([1, true, 'hello']) Ok(T, [1, true, 'hello']) }) it('Should validate 7', () => { const T = Type.Const({ x: [1, 2, 3, 4], y: { x: 1, y: 2, z: 3 }, }) Ok(T, { x: [1, 2, 3, 4], y: { x: 1, y: 2, z: 3 }, }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/constructor.ts000066400000000000000000000031701505437577000254720ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Constructor', () => { it('Should validate constructor 1', () => { const T = Type.Constructor([], Type.Object({})) Ok(T, class {}) }) it('Should validate constructor 2', () => { const T = Type.Constructor([Type.Number()], Type.Object({})) // note: constructor arguments are non-checkable Ok(T, class {}) }) it('Should validate constructor 3', () => { const T = Type.Constructor( [Type.Number()], Type.Object({ method: Type.Function([], Type.Void()), }), ) Ok( T, class { method() {} }, ) }) it('Should validate constructor 4', () => { const T = Type.Constructor( [Type.Number()], Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }), ) Ok( T, class { get x() { return 1 } get y() { return 1 } get z() { return 1 } }, ) }) it('Should not validate constructor 1', () => { const T = Type.Constructor([Type.Number()], Type.Object({})) Fail(T, 1) }) it('Should not validate constructor 2', () => { const T = Type.Constructor( [Type.Number()], Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }), ) Fail( T, class { get x() { return null } get y() { return null } get z() { return null } }, ) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/date.ts000066400000000000000000000037521505437577000240300ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Date', () => { it('Should not validate number', () => { const T = Type.Date() Fail(T, 1) }) it('Should not validate string', () => { const T = Type.Date() Fail(T, 'hello') }) it('Should not validate boolean', () => { const T = Type.Date() Fail(T, true) }) it('Should not validate array', () => { const T = Type.Date() Fail(T, [1, 2, 3]) }) it('Should not validate object', () => { const T = Type.Date() Fail(T, { a: 1, b: 2 }) }) it('Should not validate null', () => { const T = Type.Date() Fail(T, null) }) it('Should not validate undefined', () => { const T = Type.Date() Fail(T, undefined) }) it('Should validate Date', () => { const T = Type.Date() Ok(T, new Date()) }) it('Should not validate bigint', () => { const T = Type.Date() Fail(T, BigInt(1)) }) it('Should not validate symbol', () => { const T = Type.Date() Fail(T, Symbol(1)) }) it('Should not validate Date if is invalid', () => { const T = Type.Date() Fail(T, new Date('not-a-valid-date')) }) it('Should validate Date minimumTimestamp', () => { const T = Type.Date({ minimumTimestamp: 10 }) Fail(T, new Date(9)) Ok(T, new Date(10)) }) it('Should validate Date maximumTimestamp', () => { const T = Type.Date({ maximumTimestamp: 10 }) Fail(T, new Date(11)) Ok(T, new Date(10)) }) it('Should validate Date exclusiveMinimumTimestamp', () => { const T = Type.Date({ exclusiveMinimumTimestamp: 10 }) Fail(T, new Date(10)) Ok(T, new Date(11)) }) it('Should validate Date exclusiveMaximumTimestamp', () => { const T = Type.Date({ exclusiveMaximumTimestamp: 10 }) Fail(T, new Date(10)) Ok(T, new Date(9)) }) it('Should validate Date multipleOfTimestamp', () => { const T = Type.Date({ multipleOfTimestamp: 2 }) Fail(T, new Date(1)) Ok(T, new Date(2)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/enum.ts000066400000000000000000000022241505437577000240500ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Enum', () => { it('Should validate when emum uses default numeric values', () => { enum Kind { Foo, // = 0 Bar, // = 1 } const T = Type.Enum(Kind) Ok(T, 0) Ok(T, 1) }) it('Should not validate when given enum values are not numeric', () => { enum Kind { Foo, // = 0 Bar, // = 1 } const T = Type.Enum(Kind) Fail(T, 'Foo') Fail(T, 'Bar') }) it('Should validate when emum has defined string values', () => { enum Kind { Foo = 'foo', Bar = 'bar', } const T = Type.Enum(Kind) Ok(T, 'foo') Ok(T, 'bar') }) it('Should not validate when emum has defined string values and user passes numeric', () => { enum Kind { Foo = 'foo', Bar = 'bar', } const T = Type.Enum(Kind) Fail(T, 0) Fail(T, 1) }) it('Should validate when enum has one or more string values', () => { enum Kind { Foo, Bar = 'bar', } const T = Type.Enum(Kind) Ok(T, 0) Ok(T, 'bar') Fail(T, 'baz') Fail(T, 'Foo') Fail(T, 1) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/function.ts000066400000000000000000000014771505437577000247420ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Function', () => { it('Should validate function 1', () => { const T = Type.Function([Type.Number()], Type.Number()) Ok(T, function () {}) }) it('Should validate function 2', () => { const T = Type.Function([Type.Number()], Type.Number()) // note: validation only checks typeof 'function' Ok(T, function (a: string, b: string, c: string, d: string) {}) }) it('Should validate function 3', () => { const T = Type.Function([Type.Number()], Type.Number()) // note: validation only checks typeof 'function' Ok(T, function () { return 'not-a-number' }) }) it('Should not validate function', () => { const T = Type.Function([Type.Number()], Type.Number()) Fail(T, 1) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/index.ts000066400000000000000000000015531505437577000242170ustar00rootroot00000000000000import './__members' import './any' import './argument' import './array' import './async-iterator' import './bigint' import './boolean' import './composite' import './const' import './constructor' import './date' import './unicode' import './enum' import './function' import './integer' import './intersect' import './iterator' import './keyof' import './kind' import './literal' import './module' import './never' import './not' import './null' import './number' import './object' import './omit' import './optional' import './partial' import './pick' import './readonly-optional' import './readonly' import './recursive' import './record' import './ref' import './regexp' import './required' import './string-pattern' import './string' import './symbol' import './template-literal' import './tuple' import './uint8array' import './union' import './unknown' import './void' sinclairzx81-typebox-e0ec98c/test/runtime/compiler/integer.ts000066400000000000000000000035701505437577000245460ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Integer', () => { it('Should not validate number', () => { const T = Type.Integer() Fail(T, 3.14) }) it('Should not validate NaN', () => { const T = Type.Integer() Fail(T, NaN) }) it('Should not validate +Infinity', () => { const T = Type.Integer() Fail(T, Infinity) }) it('Should not validate -Infinity', () => { const T = Type.Integer() Fail(T, -Infinity) }) it('Should validate integer', () => { const T = Type.Integer() Ok(T, 1) }) it('Should not validate string', () => { const T = Type.Integer() Fail(T, 'hello') }) it('Should not validate boolean', () => { const T = Type.Integer() Fail(T, true) }) it('Should not validate array', () => { const T = Type.Integer() Fail(T, [1, 2, 3]) }) it('Should not validate object', () => { const T = Type.Integer() Fail(T, { a: 1, b: 2 }) }) it('Should not validate null', () => { const T = Type.Integer() Fail(T, null) }) it('Should not validate undefined', () => { const T = Type.Integer() Fail(T, undefined) }) it('Should not validate bigint', () => { const T = Type.Integer() Fail(T, BigInt(1)) }) it('Should not validate symbol', () => { const T = Type.Integer() Fail(T, Symbol(1)) }) it('Should validate minimum', () => { const T = Type.Integer({ minimum: 10 }) Fail(T, 9) Ok(T, 10) }) it('Should validate maximum', () => { const T = Type.Integer({ maximum: 10 }) Ok(T, 10) Fail(T, 11) }) it('Should validate Date exclusiveMinimum', () => { const T = Type.Integer({ exclusiveMinimum: 10 }) Fail(T, 10) Ok(T, 11) }) it('Should validate Date exclusiveMaximum', () => { const T = Type.Integer({ exclusiveMaximum: 10 }) Ok(T, 9) Fail(T, 10) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/intersect.ts000066400000000000000000000154531505437577000251140ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Intersect', () => { it('Should intersect number and number', () => { const A = Type.Number() const B = Type.Number() const T = Type.Intersect([A, B], {}) Ok(T, 1) }) it('Should not intersect string and number', () => { const A = Type.String() const B = Type.Number() const T = Type.Intersect([A, B], {}) Fail(T, 1) Fail(T, '1') }) it('Should intersect two objects', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const T = Type.Intersect([A, B], {}) Ok(T, { x: 1, y: 1 }) }) it('Should not intersect two objects with internal additionalProperties false', () => { const A = Type.Object({ x: Type.Number() }, { additionalProperties: false }) const B = Type.Object({ y: Type.Number() }, { additionalProperties: false }) const T = Type.Intersect([A, B], {}) Fail(T, { x: 1, y: 1 }) }) it('Should intersect two objects and mandate required properties', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const T = Type.Intersect([A, B], {}) Ok(T, { x: 1, y: 1 }) Fail(T, { x: 1 }) Fail(T, { y: 1 }) }) it('Should intersect two objects with unevaluated properties', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const T = Type.Intersect([A, B], {}) Ok(T, { x: 1, y: 2, z: 1 }) }) it('Should intersect two objects and restrict unevaluated properties', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const T = Type.Intersect([A, B], { unevaluatedProperties: false }) Fail(T, { x: 1, y: 2, z: 1 }) }) it('Should intersect two objects and allow unevaluated properties of number', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const T = Type.Intersect([A, B], { unevaluatedProperties: Type.Number() }) Ok(T, { x: 1, y: 2, z: 3 }) Fail(T, { x: 1, y: 2, z: '1' }) }) it('Should intersect two nested objects and allow unevaluated properties of number', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const T = Type.Object({ nested: Type.Intersect([A, B], { unevaluatedProperties: Type.Number() }) }) Ok(T, { nested: { x: 1, y: 2, z: 3 } }) Fail(T, { nested: { x: 1, y: 2, z: '1' } }) }) it('Should intersect two union objects with overlapping properties of the same type', () => { const A = Type.Union([Type.Object({ x: Type.Number() })]) const B = Type.Union([Type.Object({ x: Type.Number() })]) const T = Type.Intersect([A, B]) Ok(T, { x: 1 }) Fail(T, { x: '1' }) }) it('Should not intersect two union objects with overlapping properties of varying types', () => { const A = Type.Union([Type.Object({ x: Type.Number() })]) const B = Type.Union([Type.Object({ x: Type.String() })]) const T = Type.Intersect([A, B]) Fail(T, { x: 1 }) Fail(T, { x: '1' }) }) it('Should intersect two union objects with non-overlapping properties', () => { const A = Type.Union([Type.Object({ x: Type.Number() })]) const B = Type.Union([Type.Object({ y: Type.Number() })]) const T = Type.Intersect([A, B]) Ok(T, { x: 1, y: 1 }) }) it('Should not intersect two union objects with non-overlapping properties for additionalProperties false', () => { const A = Type.Union([Type.Object({ x: Type.Number() }, { additionalProperties: false })]) const B = Type.Union([Type.Object({ y: Type.Number() }, { additionalProperties: false })]) const T = Type.Intersect([A, B]) Fail(T, { x: 1, y: 1 }) }) it('unevaluatedProperties with Record 1', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: false, }, ) Ok(T, { x: 1, y: 2 }) }) it('unevaluatedProperties with Record 2', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: false, }, ) Ok(T, { x: 1, y: 2, 0: 'hello' }) }) it('unevaluatedProperties with Record 3', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: false, }, ) Fail(T, { x: 1, y: 2, 0: 1 }) }) it('unevaluatedProperties with Record 4', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: Type.Boolean(), }, ) Ok(T, { x: 1, y: 2 }) }) it('unevaluatedProperties with Record 5', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: Type.Boolean(), }, ) Ok(T, { x: 1, y: 2, z: true }) }) it('unevaluatedProperties with Record 6', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: Type.Boolean(), }, ) Fail(T, { x: 1, y: 2, z: 1 }) }) it('unevaluatedProperties with Record 7', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: Type.Boolean(), }, ) Ok(T, { x: 1, y: 2, 0: '' }) }) it('unevaluatedProperties with Record 8', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: Type.Boolean(), }, ) Ok(T, { x: 1, y: 2, 0: '', z: true }) }) it('unevaluatedProperties with Record 9', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: Type.Boolean(), }, ) Fail(T, { x: 1, y: 2, 0: '', z: 1 }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/iterator.ts000066400000000000000000000007631505437577000247430ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Iterator', () => { it('Should validate a iterator 1', () => { function* f() {} const T = Type.Iterator(Type.Any()) Ok(T, f()) }) it('Should validate a iterator 2', () => { const T = Type.Iterator(Type.Any()) Ok(T, { [Symbol.iterator]: () => {}, }) }) it('Should not validate a iterator', () => { const T = Type.Iterator(Type.Any()) Fail(T, {}) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/keyof.ts000066400000000000000000000017371505437577000242310ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/KeyOf', () => { it('Should validate with all object keys as a kind of union', () => { const T = Type.KeyOf( Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }), ) Ok(T, 'x') Ok(T, 'y') Ok(T, 'z') Fail(T, 'w') }) it('Should validate when using pick', () => { const T = Type.KeyOf( Type.Pick( Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }), ['x', 'y'], ), ) Ok(T, 'x') Ok(T, 'y') Fail(T, 'z') }) it('Should validate when using omit', () => { const T = Type.KeyOf( Type.Omit( Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }), ['x', 'y'], ), ) Fail(T, 'x') Fail(T, 'y') Ok(T, 'z') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/kind.ts000066400000000000000000000106161505437577000240350ustar00rootroot00000000000000import { TypeRegistry, Type, Kind, TSchema } from '@sinclair/typebox' import { TypeCompiler } from '@sinclair/typebox/compiler' import { Ok, Fail } from './validate' import { Assert } from '../assert' describe('compiler/Kind', () => { // ------------------------------------------------------------ // Fixtures // ------------------------------------------------------------ beforeEach(() => TypeRegistry.Set('PI', (_, value) => value === Math.PI)) afterEach(() => TypeRegistry.Delete('PI')) // ------------------------------------------------------------ // Tests // ------------------------------------------------------------ it('Should validate', () => { const T = Type.Unsafe({ [Kind]: 'PI' }) Ok(T, Math.PI) }) it('Should not validate', () => { const T = Type.Unsafe({ [Kind]: 'PI' }) Fail(T, Math.PI * 2) }) it('Should validate in object', () => { const T = Type.Object({ x: Type.Unsafe({ [Kind]: 'PI' }), }) Ok(T, { x: Math.PI }) }) it('Should not validate in object', () => { const T = Type.Object({ x: Type.Unsafe({ [Kind]: 'PI' }), }) Fail(T, { x: Math.PI * 2 }) }) it('Should validate in array', () => { const T = Type.Array(Type.Unsafe({ [Kind]: 'PI' })) Ok(T, [Math.PI]) }) it('Should not validate in array', () => { const T = Type.Array(Type.Unsafe({ [Kind]: 'PI' })) Fail(T, [Math.PI * 2]) }) it('Should validate in tuple', () => { const T = Type.Tuple([Type.Unsafe({ [Kind]: 'PI' })]) Ok(T, [Math.PI]) }) it('Should not validate in tuple', () => { const T = Type.Tuple([Type.Unsafe({ [Kind]: 'PI' })]) Fail(T, [Math.PI * 2]) }) // ------------------------------------------------------------ // Instances // ------------------------------------------------------------ it('Should receive kind instance on registry callback', () => { const stack: string[] = [] TypeRegistry.Set('Kind', (schema: unknown) => { // prettier-ignore return (typeof schema === 'object' && schema !== null && Kind in schema && schema[Kind] === 'Kind' && '$id' in schema && typeof schema.$id === 'string') ? (() => { stack.push(schema.$id); return true })() : false }) const A = { [Kind]: 'Kind', $id: 'A' } as TSchema const B = { [Kind]: 'Kind', $id: 'B' } as TSchema const T = Type.Object({ a: A, b: B }) const C = TypeCompiler.Compile(T) const R = C.Check({ a: null, b: null }) Assert.IsTrue(R) Assert.IsEqual(stack[0], 'A') Assert.IsEqual(stack[1], 'B') TypeRegistry.Delete('Kind') }) // ------------------------------------------------------------ // Instances Retain // ------------------------------------------------------------ it('Should retain kind instances on subsequent compile', () => { let stack: string[] = [] TypeRegistry.Set('Kind', (schema: unknown) => { // prettier-ignore return (typeof schema === 'object' && schema !== null && Kind in schema && schema[Kind] === 'Kind' && '$id' in schema && typeof schema.$id === 'string') ? (() => { stack.push(schema.$id); return true })() : false }) const A = { [Kind]: 'Kind', $id: 'A' } as TSchema const B = { [Kind]: 'Kind', $id: 'B' } as TSchema const C = { [Kind]: 'Kind', $id: 'C' } as TSchema const D = { [Kind]: 'Kind', $id: 'D' } as TSchema const T1 = Type.Object({ a: A, b: B }) const T2 = Type.Object({ a: C, b: D }) // Compile T1 and run check, expect A and B const C1 = TypeCompiler.Compile(T1) const R1 = C1.Check({ a: null, b: null }) Assert.IsTrue(R1) Assert.IsEqual(stack.length, 2) Assert.IsEqual(stack[0], 'A') Assert.IsEqual(stack[1], 'B') stack = [] // compile T2 and force instance.clear() const C2 = TypeCompiler.Compile(T2) // run T1 check const R2 = C1.Check({ a: null, b: null }) Assert.IsTrue(R2) Assert.IsEqual(stack.length, 2) Assert.IsEqual(stack[0], 'A') Assert.IsEqual(stack[1], 'B') stack = [] // run T2 check const R3 = C2.Check({ a: null, b: null }) Assert.IsTrue(R3) Assert.IsEqual(stack.length, 2) Assert.IsEqual(stack[0], 'C') Assert.IsEqual(stack[1], 'D') stack = [] // run T1 check const R4 = C1.Check({ a: null, b: null }) Assert.IsTrue(R4) Assert.IsEqual(stack.length, 2) Assert.IsEqual(stack[0], 'A') Assert.IsEqual(stack[1], 'B') stack = [] TypeRegistry.Delete('Kind') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/literal.ts000066400000000000000000000026611505437577000245450ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Literal', () => { it('Should validate literal number', () => { const T = Type.Literal(42) Ok(T, 42) }) it('Should validate literal string', () => { const T = Type.Literal('hello') Ok(T, 'hello') }) it('Should validate literal boolean', () => { const T = Type.Literal(true) Ok(T, true) }) it('Should not validate invalid literal number', () => { const T = Type.Literal(42) Fail(T, 43) }) it('Should not validate invalid literal string', () => { const T = Type.Literal('hello') Fail(T, 'world') }) it('Should not validate invalid literal boolean', () => { const T = Type.Literal(false) Fail(T, true) }) it('Should validate literal union', () => { const T = Type.Union([Type.Literal(42), Type.Literal('hello')]) Ok(T, 42) Ok(T, 'hello') }) it('Should not validate invalid literal union', () => { const T = Type.Union([Type.Literal(42), Type.Literal('hello')]) Fail(T, 43) Fail(T, 'world') }) // reference: https://github.com/sinclairzx81/typebox/issues/539 it('Should escape single quote literals', () => { const T = Type.Literal("it's") Ok(T, "it's") Fail(T, "it''s") }) it('Should escape multiple single quote literals', () => { const T = Type.Literal("'''''''''") Ok(T, "'''''''''") Fail(T, "''''''''") // minus 1 }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/module.ts000066400000000000000000000106031505437577000243710ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Module', () => { it('Should validate string', () => { const Module = Type.Module({ A: Type.String(), }) const T = Module.Import('A') Ok(T, 'hello') Fail(T, true) }) it('Should validate referenced string', () => { const Module = Type.Module({ A: Type.String(), B: Type.Ref('A'), }) const T = Module.Import('B') Ok(T, 'hello') Fail(T, true) }) it('Should validate self referential', () => { const Module = Type.Module({ A: Type.Object({ nodes: Type.Array(Type.Ref('A')), }), }) const T = Module.Import('A') Ok(T, { nodes: [{ nodes: [{ nodes: [] }, { nodes: [] }] }] }) Fail(T, { nodes: [{ nodes: [{ nodes: [] }, { nodes: false }] }] }) Fail(T, true) }) it('Should validate mutual recursive', () => { const Module = Type.Module({ A: Type.Object({ b: Type.Ref('B'), }), B: Type.Object({ a: Type.Union([Type.Ref('A'), Type.Null()]), }), }) const T = Module.Import('A') Ok(T, { b: { a: null } }) Ok(T, { b: { a: { b: { a: null } } } }) Fail(T, { b: { a: 1 } }) Fail(T, { b: { a: { b: { a: 1 } } } }) Fail(T, true) }) it('Should validate mutual recursive (Array)', () => { const Module = Type.Module({ A: Type.Object({ b: Type.Ref('B'), }), B: Type.Object({ a: Type.Array(Type.Ref('A')), }), }) const T = Module.Import('A') Ok(T, { b: { a: [{ b: { a: [] } }] } }) Fail(T, { b: { a: [{ b: { a: [null] } }] } }) Fail(T, true) }) it('Should validate deep referential', () => { const Module = Type.Module({ A: Type.Ref('B'), B: Type.Ref('C'), C: Type.Ref('D'), D: Type.Ref('E'), E: Type.Ref('F'), F: Type.Ref('G'), G: Type.Ref('H'), H: Type.Literal('hello'), }) const T = Module.Import('A') Ok(T, 'hello') Fail(T, 'world') }) // ---------------------------------------------------------------- // Modifiers // ---------------------------------------------------------------- it('Should validate objects with property modifiers 1', () => { const Module = Type.Module({ T: Type.Object({ x: Type.ReadonlyOptional(Type.Null()), y: Type.Readonly(Type.Null()), z: Type.Optional(Type.Null()), w: Type.Null(), }), }) const T = Module.Import('T') Ok(T, { x: null, y: null, w: null }) Ok(T, { y: null, w: null }) Fail(T, { x: 1, y: null, w: null }) }) it('Should validate objects with property modifiers 2', () => { const Module = Type.Module({ T: Type.Object({ x: Type.ReadonlyOptional(Type.Array(Type.Null())), y: Type.Readonly(Type.Array(Type.Null())), z: Type.Optional(Type.Array(Type.Null())), w: Type.Array(Type.Null()), }), }) const T = Module.Import('T') Ok(T, { x: [null], y: [null], w: [null] }) Ok(T, { y: [null], w: [null] }) Fail(T, { x: [1], y: [null], w: [null] }) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/1109 // ---------------------------------------------------------------- it('Should validate deep referential 1', () => { const Module = Type.Module({ A: Type.Union([Type.Literal('Foo'), Type.Literal('Bar')]), B: Type.Ref('A'), C: Type.Object({ ref: Type.Ref('B') }), D: Type.Union([Type.Ref('B'), Type.Ref('C')]), }) Ok(Module.Import('A') as never, 'Foo') Ok(Module.Import('A') as never, 'Bar') Ok(Module.Import('B') as never, 'Foo') Ok(Module.Import('B') as never, 'Bar') Ok(Module.Import('C') as never, { ref: 'Foo' }) Ok(Module.Import('C') as never, { ref: 'Bar' }) Ok(Module.Import('D') as never, 'Foo') Ok(Module.Import('D') as never, 'Bar') Ok(Module.Import('D') as never, { ref: 'Foo' }) Ok(Module.Import('D') as never, { ref: 'Bar' }) }) it('Should validate deep referential 2', () => { const Module = Type.Module({ A: Type.Literal('Foo'), B: Type.Ref('A'), C: Type.Ref('B'), D: Type.Ref('C'), E: Type.Ref('D'), }) Ok(Module.Import('A'), 'Foo') Ok(Module.Import('B'), 'Foo') Ok(Module.Import('C'), 'Foo') Ok(Module.Import('D'), 'Foo') Ok(Module.Import('E'), 'Foo') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/never.ts000066400000000000000000000017261505437577000242310ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Fail } from './validate' describe('compiler/Never', () => { it('Should not validate number', () => { const T = Type.Never() Fail(T, 1) }) it('Should not validate string', () => { const T = Type.Never() Fail(T, 'hello') }) it('Should not validate boolean', () => { const T = Type.Never() Fail(T, true) }) it('Should not validate array', () => { const T = Type.Never() Fail(T, [1, 2, 3]) }) it('Should not validate object', () => { const T = Type.Never() Fail(T, { a: 1, b: 2 }) }) it('Should not validate null', () => { const T = Type.Never() Fail(T, null) }) it('Should not validate undefined', () => { const T = Type.Never() Fail(T, undefined) }) it('Should not validate bigint', () => { const T = Type.Never() Fail(T, BigInt(1)) }) it('Should not validate symbol', () => { const T = Type.Never() Fail(T, Symbol(1)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/not.ts000066400000000000000000000021171505437577000237050ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Not', () => { it('Should validate not number', () => { const T = Type.Not(Type.Number()) Fail(T, 1) Ok(T, '1') }) it('Should validate not not number', () => { const T = Type.Not(Type.Not(Type.Number())) Ok(T, 1) Fail(T, '1') }) it('Should validate not union', () => { // prettier-ignore const T = Type.Not(Type.Union([ Type.Literal('A'), Type.Literal('B'), Type.Literal('C') ])) Fail(T, 'A') Fail(T, 'B') Fail(T, 'C') Ok(T, 'D') }) it('Should validate not object intersection', () => { const T = Type.Intersect([ Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }), Type.Object({ x: Type.Not(Type.Literal(0)), y: Type.Not(Type.Literal(0)), z: Type.Not(Type.Literal(0)), }), ]) Fail(T, { x: 0, y: 0, z: 0 }) Fail(T, { x: 1, y: 0, z: 0 }) Fail(T, { x: 1, y: 1, z: 0 }) Ok(T, { x: 1, y: 1, z: 1 }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/null.ts000066400000000000000000000017161505437577000240630ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Null', () => { it('Should not validate number', () => { const T = Type.Null() Fail(T, 1) }) it('Should not validate string', () => { const T = Type.Null() Fail(T, 'hello') }) it('Should not validate boolean', () => { const T = Type.Null() Fail(T, true) }) it('Should not validate array', () => { const T = Type.Null() Fail(T, [1, 2, 3]) }) it('Should not validate object', () => { const T = Type.Null() Fail(T, { a: 1, b: 2 }) }) it('Should not validate null', () => { const T = Type.Null() Ok(T, null) }) it('Should not validate undefined', () => { const T = Type.Null() Fail(T, undefined) }) it('Should not validate bigint', () => { const T = Type.Null() Fail(T, BigInt(1)) }) it('Should not validate symbol', () => { const T = Type.Null() Fail(T, Symbol(1)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/number.ts000066400000000000000000000035401505437577000243760ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Number', () => { it('Should validate number', () => { const T = Type.Number() Ok(T, 3.14) }) it('Should not validate NaN', () => { const T = Type.Number() Fail(T, NaN) }) it('Should not validate +Infinity', () => { const T = Type.Number() Fail(T, Infinity) }) it('Should not validate -Infinity', () => { const T = Type.Number() Fail(T, -Infinity) }) it('Should validate integer', () => { const T = Type.Number() Ok(T, 1) }) it('Should not validate string', () => { const T = Type.Number() Fail(T, 'hello') }) it('Should not validate boolean', () => { const T = Type.Number() Fail(T, true) }) it('Should not validate array', () => { const T = Type.Number() Fail(T, [1, 2, 3]) }) it('Should not validate object', () => { const T = Type.Number() Fail(T, { a: 1, b: 2 }) }) it('Should not validate null', () => { const T = Type.Number() Fail(T, null) }) it('Should not validate undefined', () => { const T = Type.Number() Fail(T, undefined) }) it('Should not validate bigint', () => { const T = Type.Number() Fail(T, BigInt(1)) }) it('Should not validate symbol', () => { const T = Type.Number() Fail(T, Symbol(1)) }) it('Should validate minimum', () => { const T = Type.Number({ minimum: 10 }) Fail(T, 9) Ok(T, 10) }) it('Should validate maximum', () => { const T = Type.Number({ maximum: 10 }) Ok(T, 10) Fail(T, 11) }) it('Should validate Date exclusiveMinimum', () => { const T = Type.Number({ exclusiveMinimum: 10 }) Fail(T, 10) Ok(T, 11) }) it('Should validate Date exclusiveMaximum', () => { const T = Type.Number({ exclusiveMaximum: 10 }) Ok(T, 9) Fail(T, 10) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/object.ts000066400000000000000000000226451505437577000243630ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Object', () => { // ----------------------------------------------------- // TypeCompiler Only // ----------------------------------------------------- it('Should handle extends undefined check 1', () => { const T = Type.Object({ A: Type.Not(Type.Number()), B: Type.Union([Type.Number(), Type.Undefined()]), C: Type.Intersect([Type.Undefined(), Type.Undefined()]), }) Ok(T, { A: undefined, B: undefined, C: undefined, }) }) // https://github.com/sinclairzx81/typebox/issues/437 it('Should handle extends undefined check 2', () => { const T = Type.Object({ A: Type.Not(Type.Null()), }) Ok(T, { A: undefined }) Fail(T, { A: null }) Fail(T, {}) }) // ----------------------------------------------------- // Standard Checks // ----------------------------------------------------- it('Should not validate a number', () => { const T = Type.Object({}) Fail(T, 42) }) it('Should not validate a string', () => { const T = Type.Object({}) Fail(T, 'hello') }) it('Should not validate a boolean', () => { const T = Type.Object({}) Fail(T, true) }) it('Should not validate a null', () => { const T = Type.Object({}) Fail(T, null) }) it('Should not validate undefined', () => { const T = Type.Object({}) Fail(T, undefined) }) it('Should not validate bigint', () => { const T = Type.Object({}) Fail(T, BigInt(1)) }) it('Should not validate symbol', () => { const T = Type.Object({}) Fail(T, Symbol(1)) }) it('Should not validate an array', () => { const T = Type.Object({}) Fail(T, [1, 2]) }) it('Should validate with correct property values', () => { const T = Type.Object({ a: Type.Number(), b: Type.String(), c: Type.Boolean(), d: Type.Array(Type.Number()), e: Type.Object({ x: Type.Number(), y: Type.Number() }), }) Ok(T, { a: 10, b: 'hello', c: true, d: [1, 2, 3], e: { x: 10, y: 20 }, }) }) it('Should not validate with incorrect property values', () => { const T = Type.Object({ a: Type.Number(), b: Type.String(), c: Type.Boolean(), d: Type.Array(Type.Number()), e: Type.Object({ x: Type.Number(), y: Type.Number() }), }) Fail(T, { a: 'not a number', // error b: 'hello', c: true, d: [1, 2, 3], e: { x: 10, y: 20 }, }) }) it('Should allow additionalProperties by default', () => { const T = Type.Object({ a: Type.Number(), b: Type.String(), }) Ok(T, { a: 1, b: 'hello', c: true, }) }) it('Should not allow an empty object if minProperties is set to 1', () => { const T = Type.Object( { a: Type.Optional(Type.Number()), b: Type.Optional(Type.String()), }, { additionalProperties: false, minProperties: 1 }, ) Ok(T, { a: 1 }) Ok(T, { b: 'hello' }) Fail(T, {}) }) it('Should not allow 3 properties if maxProperties is set to 2', () => { const T = Type.Object( { a: Type.Optional(Type.Number()), b: Type.Optional(Type.String()), c: Type.Optional(Type.Boolean()), }, { additionalProperties: false, maxProperties: 2 }, ) Ok(T, { a: 1 }) Ok(T, { a: 1, b: 'hello' }) Fail(T, { a: 1, b: 'hello', c: true, }) }) it('Should not allow additionalProperties if additionalProperties is false', () => { const T = Type.Object( { a: Type.Number(), b: Type.String(), }, { additionalProperties: false }, ) Fail(T, { a: 1, b: 'hello', c: true, }) }) it('Should not allow properties for an empty object when additionalProperties is false', () => { const T = Type.Object({}, { additionalProperties: false }) Ok(T, {}) Fail(T, { a: 10 }) }) it('Should validate with non-syntax property keys', () => { const T = Type.Object({ 'with-hyphen': Type.Literal(1), '0-leading': Type.Literal(2), '$-leading': Type.Literal(3), '!@#$%^&*(': Type.Literal(4), 'node-mirror:release:0': Type.Literal(5), // issue: 353 'node-mirror:release:1': Type.Optional(Type.Literal(6)), // issue: 356 'node-mirror:release:2': Type.Union([Type.Literal(7), Type.Undefined()]), // key known "a'a": Type.Literal(8), '@onlyAtSymbol': Type.Literal(9), }) Ok(T, { 'with-hyphen': 1, '0-leading': 2, '$-leading': 3, '!@#$%^&*(': 4, 'node-mirror:release:0': 5, 'node-mirror:release:1': 6, 'node-mirror:release:2': 7, "a'a": 8, '@onlyAtSymbol': 9, }) }) it('Should validate schema additional properties of string', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.String(), }, ) Ok(T, { x: 1, y: 2, z: 'hello', }) Fail(T, { x: 1, y: 2, z: 3, }) }) it('Should validate schema additional properties of array', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.Array(Type.Number()), }, ) Ok(T, { x: 1, y: 2, z: [0, 1, 2], }) Fail(T, { x: 1, y: 2, z: 3, }) }) it('Should validate schema additional properties of object', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.Object({ z: Type.Number(), }), }, ) Ok(T, { x: 1, y: 2, z: { z: 1 }, }) Fail(T, { x: 1, y: 2, z: 3, }) }) it('Should validate nested schema additional properties of string', () => { const T = Type.Object({ nested: Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.String(), }, ), }) Ok(T, { nested: { x: 1, y: 2, z: 'hello', }, }) Fail(T, { nested: { x: 1, y: 2, z: 3, }, }) }) it('Should validate nested schema additional properties of array', () => { const T = Type.Object({ nested: Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.Array(Type.Number()), }, ), }) Ok(T, { nested: { x: 1, y: 2, z: [0, 1, 2], }, }) Fail(T, { nested: { x: 1, y: 2, z: 3, }, }) }) it('Should validate nested schema additional properties of object', () => { const T = Type.Object({ nested: Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.Object({ z: Type.Number(), }), }, ), }) Ok(T, { nested: { x: 1, y: 2, z: { z: 1 }, }, }) Fail(T, { nested: { x: 1, y: 2, z: 3, }, }) }) it('Should check for property key if property type is undefined', () => { const T = Type.Object({ x: Type.Undefined() }) Ok(T, { x: undefined }) Fail(T, {}) }) it('Should check for property key if property type extends undefined', () => { const T = Type.Object({ x: Type.Union([Type.Number(), Type.Undefined()]) }) Ok(T, { x: 1 }) Ok(T, { x: undefined }) Fail(T, {}) }) it('Should not check for property key if property type is undefined and optional', () => { const T = Type.Object({ x: Type.Optional(Type.Undefined()) }) Ok(T, { x: undefined }) Ok(T, {}) }) it('Should not check for property key if property type extends undefined and optional', () => { const T = Type.Object({ x: Type.Optional(Type.Union([Type.Number(), Type.Undefined()])) }) Ok(T, { x: 1 }) Ok(T, { x: undefined }) Ok(T, {}) }) it('Should check undefined for optional property of number', () => { const T = Type.Object({ x: Type.Optional(Type.Number()) }) Ok(T, { x: 1 }) Ok(T, { x: undefined }) // allowed by default Ok(T, {}) }) it('Should check undefined for optional property of undefined', () => { const T = Type.Object({ x: Type.Optional(Type.Undefined()) }) Fail(T, { x: 1 }) Ok(T, { x: undefined }) Ok(T, {}) }) it('Should check for required property of any', () => { const T = Type.Object({ x: Type.Any() }) Fail(T, {}) Ok(T, { x: undefined }) Ok(T, { x: 1 }) Ok(T, { x: true }) }) it('Should check for required property of unknown', () => { const T = Type.Object({ x: Type.Unknown() }) Fail(T, {}) Ok(T, { x: undefined }) Ok(T, { x: 1 }) Ok(T, { x: true }) }) it('Should check for required property of any (when optional)', () => { const T = Type.Object({ x: Type.Optional(Type.Any()) }) Ok(T, {}) Ok(T, { x: undefined }) Ok(T, { x: 1 }) Ok(T, { x: true }) }) it('Should check for required property of unknown (when optional)', () => { const T = Type.Object({ x: Type.Optional(Type.Unknown()) }) Ok(T, {}) Ok(T, { x: undefined }) Ok(T, { x: 1 }) Ok(T, { x: true }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/omit.ts000066400000000000000000000041461505437577000240610ustar00rootroot00000000000000import { Type, Kind } from '@sinclair/typebox' import { Ok, Fail } from './validate' import { deepEqual, strictEqual } from 'assert' describe('compiler/Omit', () => { it('Should omit properties on the source schema', () => { const A = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { additionalProperties: false }, ) const T = Type.Omit(A, ['z']) Ok(T, { x: 1, y: 1 }) }) it('Should remove required properties on the target schema', () => { const A = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { additionalProperties: false }, ) const T = Type.Omit(A, ['z']) strictEqual(T.required!.includes('z'), false) }) it('Should inherit options from the source object', () => { const A = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { additionalProperties: false }, ) const T = Type.Omit(A, ['z']) strictEqual(A.additionalProperties, false) strictEqual(T.additionalProperties, false) }) it('Should omit with keyof object', () => { const A = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }) const B = Type.Object({ x: Type.Number(), y: Type.Number(), }) const T = Type.Omit(A, Type.KeyOf(B), { additionalProperties: false }) Ok(T, { z: 0 }) Fail(T, { x: 0, y: 0, z: 0 }) }) it('Should support Omit of Literal', () => { const A = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }) const T = Type.Omit(A, Type.Literal('x'), { additionalProperties: false, }) Ok(T, { y: 1, z: 1 }) Fail(T, { x: 1, y: 1, z: 1 }) }) it('Should support Omit of Never', () => { const A = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { additionalProperties: false }, ) const T = Type.Omit(A, Type.Never()) Fail(T, { y: 1, z: 1 }) Ok(T, { x: 1, y: 1, z: 1 }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/optional.ts000066400000000000000000000012721505437577000247330ustar00rootroot00000000000000import { strictEqual } from 'assert' import { Type } from '@sinclair/typebox' import { Ok } from './validate' describe('compiler/Optional', () => { it('Should validate object with optional', () => { const T = Type.Object( { a: Type.Optional(Type.String()), b: Type.String(), }, { additionalProperties: false }, ) Ok(T, { a: 'hello', b: 'world' }) Ok(T, { b: 'world' }) }) it('Should remove required value from schema', () => { const T = Type.Object( { a: Type.Optional(Type.String()), b: Type.String(), }, { additionalProperties: false }, ) strictEqual(T.required!.includes('a'), false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/partial.ts000066400000000000000000000032111505437577000245350ustar00rootroot00000000000000import { TypeSystem } from '@sinclair/typebox/system' import { Type, OptionalKind, ReadonlyKind } from '@sinclair/typebox' import { Ok, Fail } from './validate' import { strictEqual } from 'assert' describe('compiler/Partial', () => { it('Should convert a required object into a partial', () => { const A = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { additionalProperties: false }, ) const T = Type.Partial(A) Ok(T, { x: 1, y: 1, z: 1 }) Ok(T, { x: 1, y: 1 }) Ok(T, { x: 1 }) Ok(T, {}) }) it('Should update modifier types correctly when converting to partial', () => { const A = Type.Object( { x: Type.Readonly(Type.Optional(Type.Number())), y: Type.Readonly(Type.Number()), z: Type.Optional(Type.Number()), w: Type.Number(), }, { additionalProperties: false }, ) const T = Type.Partial(A) strictEqual(T.properties.x[ReadonlyKind], 'Readonly') strictEqual(T.properties.x[OptionalKind], 'Optional') strictEqual(T.properties.y[ReadonlyKind], 'Readonly') strictEqual(T.properties.y[OptionalKind], 'Optional') strictEqual(T.properties.z[OptionalKind], 'Optional') strictEqual(T.properties.w[OptionalKind], 'Optional') }) it('Should inherit options from the source object', () => { const A = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { additionalProperties: false }, ) const T = Type.Partial(A) strictEqual(A.additionalProperties, false) strictEqual(T.additionalProperties, false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/pick.ts000066400000000000000000000041261505437577000240350ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' import { strictEqual } from 'assert' describe('compiler/Pick', () => { it('Should pick properties from the source schema', () => { const Vector3 = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { additionalProperties: false }, ) const T = Type.Pick(Vector3, ['x', 'y']) Ok(T, { x: 1, y: 1 }) }) it('Should remove required properties on the target schema', () => { const A = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { additionalProperties: false }, ) const T = Type.Pick(A, ['x', 'y']) strictEqual(T.required!.includes('z'), false) }) it('Should inherit options from the source object', () => { const A = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { additionalProperties: false }, ) const T = Type.Pick(A, ['x', 'y']) strictEqual(A.additionalProperties, false) strictEqual(T.additionalProperties, false) }) it('Should pick with keyof object', () => { const A = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }) const B = Type.Object({ x: Type.Number(), y: Type.Number(), }) const T = Type.Pick(A, Type.KeyOf(B), { additionalProperties: false }) Ok(T, { x: 0, y: 0 }) Fail(T, { x: 0, y: 0, z: 0 }) }) it('Should support Pick of Literal', () => { const A = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }) const T = Type.Pick(A, Type.Literal('x'), { additionalProperties: false, }) Ok(T, { x: 1 }) Fail(T, { x: 1, y: 1, z: 1 }) }) it('Should support Pick of Never', () => { const A = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }) const T = Type.Pick(A, Type.Never(), { additionalProperties: false, }) Fail(T, { x: 1, y: 1, z: 1 }) Ok(T, {}) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/readonly-optional.ts000066400000000000000000000013461505437577000265500ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' import { strictEqual } from 'assert' describe('compiler/ReadonlyOptional', () => { it('Should validate object with optional', () => { const T = Type.Object( { a: Type.Readonly(Type.Optional(Type.String())), b: Type.String(), }, { additionalProperties: false }, ) Ok(T, { a: 'hello', b: 'world' }) Ok(T, { b: 'world' }) }) it('Should remove required value from schema', () => { const T = Type.Object( { a: Type.Readonly(Type.Optional(Type.String())), b: Type.String(), }, { additionalProperties: false }, ) strictEqual(T.required!.includes('a'), false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/readonly.ts000066400000000000000000000014031505437577000247170ustar00rootroot00000000000000import { deepStrictEqual, strictEqual } from 'assert' import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Readonly', () => { it('Should validate object with readonly', () => { const T = Type.Object( { a: Type.Readonly(Type.String()), b: Type.Readonly(Type.String()), }, { additionalProperties: false }, ) Ok(T, { a: 'hello', b: 'world' }) }) it('Should retain required array on object', () => { const T = Type.Object( { a: Type.Readonly(Type.String()), b: Type.Readonly(Type.String()), }, { additionalProperties: false }, ) strictEqual(T.required!.includes('a'), true) strictEqual(T.required!.includes('b'), true) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/record.ts000066400000000000000000000253031505437577000243650ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Record', () => { // ------------------------------------------------------------- // Issues // ------------------------------------------------------------- it('Issue: https://github.com/sinclairzx81/typebox/issues/402', () => { const T = Type.Object({ foo: Type.Object({ bar: Type.Record(Type.String(), Type.Number()), }), }) Ok(T, { foo: { bar: { x: 42 } } }) Ok(T, { foo: { bar: {} } }) Fail(T, { foo: { bar: { x: '42' } } }) Fail(T, { foo: { bar: [] } }) Fail(T, { foo: {} }) Fail(T, { foo: [] }) Fail(T, {}) }) // ------------------------------------------------------------- // TypeBox Only: Date and Record // ------------------------------------------------------------- it('Should fail record with Date', () => { const T = Type.Record(Type.String(), Type.String()) Fail(T, new Date()) }) it('Should fail record with Uint8Array', () => { const T = Type.Record(Type.String(), Type.String()) Fail(T, new Uint8Array()) }) // ------------------------------------------------------------- // Standard Assertions // ------------------------------------------------------------- it('Should validate when all property values are numbers', () => { const T = Type.Record(Type.String(), Type.Number()) Ok(T, { a: 1, b: 2, c: 3 }) }) it('Should validate when all property keys are strings', () => { const T = Type.Record(Type.String(), Type.Number()) Ok(T, { a: 1, b: 2, c: 3, '0': 4 }) }) it('Should not validate when below minProperties', () => { const T = Type.Record(Type.String(), Type.Number(), { minProperties: 4 }) Ok(T, { a: 1, b: 2, c: 3, d: 4 }) Fail(T, { a: 1, b: 2, c: 3 }) }) it('Should not validate when above maxProperties', () => { const T = Type.Record(Type.String(), Type.Number(), { maxProperties: 4 }) Ok(T, { a: 1, b: 2, c: 3, d: 4 }) Fail(T, { a: 1, b: 2, c: 3, d: 4, e: 5 }) }) it('Should not validate with illogical minProperties | maxProperties', () => { const T = Type.Record(Type.String(), Type.Number(), { minProperties: 5, maxProperties: 4 }) Fail(T, { a: 1, b: 2, c: 3 }) Fail(T, { a: 1, b: 2, c: 3, d: 4 }) Fail(T, { a: 1, b: 2, c: 3, d: 4, e: 5 }) }) it('Should validate when specifying string union literals when additionalProperties is true', () => { const K = Type.Union([Type.Literal('a'), Type.Literal('b'), Type.Literal('c')]) const T = Type.Record(K, Type.Number()) Ok(T, { a: 1, b: 2, c: 3, d: 'hello' }) }) it('Should not validate when specifying string union literals when additionalProperties is false', () => { const K = Type.Union([Type.Literal('a'), Type.Literal('b'), Type.Literal('c')]) const T = Type.Record(K, Type.Number(), { additionalProperties: false }) Fail(T, { a: 1, b: 2, c: 3, d: 'hello' }) }) it('Should validate for keyof records', () => { const T = Type.Object({ a: Type.String(), b: Type.Number(), c: Type.String(), }) const R = Type.Record(Type.KeyOf(T), Type.Number()) Ok(R, { a: 1, b: 2, c: 3 }) }) it('Should not validate for unknown key via keyof', () => { const T = Type.Object({ a: Type.String(), b: Type.Number(), c: Type.String(), }) const R = Type.Record(Type.KeyOf(T), Type.Number(), { additionalProperties: false }) Fail(R, { a: 1, b: 2, c: 3, d: 4 }) }) it('Should validate when specifying regular expressions', () => { const K = Type.RegExp(/^op_.*$/) const T = Type.Record(K, Type.Number()) Ok(T, { op_a: 1, op_b: 2, op_c: 3, }) }) it('Should not validate when specifying regular expressions and passing invalid property', () => { const K = Type.RegExp(/^op_.*$/) const T = Type.Record(K, Type.Number(), { additionalProperties: false }) Fail(T, { op_a: 1, op_b: 2, aop_c: 3, }) }) it('Should validate with quoted string pattern', () => { const K = Type.String({ pattern: "'(a|b|c)" }) const T = Type.Record(K, Type.Number()) Ok(T, { "'a": 1, "'b": 2, "'c": 3, }) }) it('Should validate with forward-slash pattern', () => { const K = Type.String({ pattern: '/(a|b|c)' }) const T = Type.Record(K, Type.Number()) Ok(T, { '/a': 1, '/b': 2, '/c': 3, }) }) // ------------------------------------------------------------ // Integer Keys // ------------------------------------------------------------ it('Should validate when all property keys are integers', () => { const T = Type.Record(Type.Integer(), Type.Number()) Ok(T, { '0': 1, '1': 2, '2': 3, '3': 4 }) }) it('Should validate when all property keys are integers, but one property is a string with varying type', () => { const T = Type.Record(Type.Integer(), Type.Number(), { additionalProperties: false }) Fail(T, { '0': 1, '1': 2, '2': 3, '3': 4, a: 'hello' }) }) it('Should not validate if passing a leading zeros for integers keys', () => { const T = Type.Record(Type.Integer(), Type.Number(), { additionalProperties: false }) Fail(T, { '00': 1, '01': 2, '02': 3, '03': 4, }) }) it('Should not validate if passing a signed integers keys', () => { const T = Type.Record(Type.Integer(), Type.Number(), { additionalProperties: false }) Fail(T, { '-0': 1, '-1': 2, '-2': 3, '-3': 4, }) }) // ------------------------------------------------------------ // Number Keys // ------------------------------------------------------------ it('Should validate when all property keys are numbers', () => { const T = Type.Record(Type.Number(), Type.Number()) Ok(T, { '0': 1, '1': 2, '2': 3, '3': 4 }) }) it('Should validate when all property keys are numbers, but one property is a string with varying type', () => { const T = Type.Record(Type.Number(), Type.Number(), { additionalProperties: false }) Fail(T, { '0': 1, '1': 2, '2': 3, '3': 4, a: 'hello' }) }) it('Should not validate if passing a leading zeros for numeric keys', () => { const T = Type.Record(Type.Number(), Type.Number(), { additionalProperties: false }) Fail(T, { '00': 1, '01': 2, '02': 3, '03': 4, }) }) it('Should not validate if passing a signed numeric keys', () => { const T = Type.Record(Type.Number(), Type.Number(), { additionalProperties: false }) Fail(T, { '-0': 1, '-1': 2, '-2': 3, '-3': 4, }) }) it('Should not validate when all property keys are numbers, but one property is a string with varying type', () => { const T = Type.Record(Type.Number(), Type.Number(), { additionalProperties: false }) Fail(T, { '0': 1, '1': 2, '2': 3, '3': 4, a: 'hello' }) }) // ------------------------------------------------------------ // AdditionalProperties // ------------------------------------------------------------ it('AdditionalProperties 1', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: true }) Ok(T, { 1: '', 2: '', x: 1, y: 2, z: 3 }) }) it('AdditionalProperties 2', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: false }) Ok(T, { 1: '', 2: '', 3: '' }) }) it('AdditionalProperties 3', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: false }) Fail(T, { 1: '', 2: '', x: '' }) }) it('AdditionalProperties 4', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: Type.Boolean() }) Fail(T, { 1: '', 2: '', x: '' }) }) it('AdditionalProperties 5', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: Type.Boolean() }) Ok(T, { 1: '', 2: '', x: true }) }) // ---------------------------------------------------------------- // TemplateLiteral // ---------------------------------------------------------------- it('TemplateLiteral 1', () => { const K = Type.TemplateLiteral('key${number}') const R = Type.Record(K, Type.Number(), { additionalProperties: false }) Ok(R, { key0: 1, key1: 1, key2: 1, }) }) it('TemplateLiteral 2', () => { const K = Type.TemplateLiteral('key${number}') const R = Type.Record(K, Type.Number()) Ok(R, { keyA: 0 }) }) it('TemplateLiteral 3', () => { const K = Type.TemplateLiteral('key${number}') const R = Type.Record(K, Type.Number(), { additionalProperties: false }) Fail(R, { keyA: 0 }) }) it('TemplateLiteral 4', () => { const K = Type.TemplateLiteral('key${number}') const R = Type.Record(K, Type.Number()) const T = Type.Object({ x: Type.Number(), y: Type.Number() }) const I = Type.Intersect([R, T], { unevaluatedProperties: false }) Ok(I, { x: 1, y: 2, key0: 1, key1: 1, key2: 1, }) }) it('TemplateLiteral 5', () => { const K = Type.TemplateLiteral('key${number}') const R = Type.Record(K, Type.Number()) const T = Type.Object({ x: Type.Number(), y: Type.Number() }) const I = Type.Intersect([R, T]) Ok(I, { x: 1, y: 2, z: 3, key0: 1, key1: 1, key2: 1, }) }) it('TemplateLiteral 6', () => { const K = Type.TemplateLiteral('key${number}') const R = Type.Record(K, Type.Number()) const T = Type.Object({ x: Type.Number(), y: Type.Number() }) const I = Type.Intersect([R, T], { unevaluatedProperties: false }) Fail(I, { x: 1, y: 2, z: 3, key0: 1, key1: 1, key2: 1, }) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/916 // ---------------------------------------------------------------- it('Should validate for string keys', () => { const T = Type.Record(Type.String(), Type.Null(), { additionalProperties: false, }) Ok(T, { a: null, b: null, 0: null, 1: null, }) }) it('Should validate for number keys', () => { const T = Type.Record(Type.Number(), Type.Null(), { additionalProperties: false, }) Fail(T, { a: null, b: null, 0: null, 1: null, }) Ok(T, { 0: null, 1: null, }) }) it('Should validate for any keys', () => { const T = Type.Record(Type.Any(), Type.Null(), { additionalProperties: false, }) Ok(T, { a: null, b: null, 0: null, 1: null, }) }) it('Should validate for never keys', () => { const T = Type.Record(Type.Never(), Type.Null(), { additionalProperties: false, }) Ok(T, {}) Fail(T, { a: null, b: null, 0: null, 1: null, }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/recursive.ts000066400000000000000000000034611505437577000251170ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Assert } from '../assert/index' import { Ok, Fail } from './validate' describe('compiler/Recursive', () => { it('Should generate default ordinal $id if not specified', () => { const Node = Type.Recursive((Node) => Type.Object({ id: Type.String(), nodes: Type.Array(Node), }), ) Assert.IsEqual(Node.$id === undefined, false) }) it('Should override default ordinal $id if specified', () => { const Node = Type.Recursive( (Node) => Type.Object({ id: Type.String(), nodes: Type.Array(Node), }), { $id: 'Node' }, ) Assert.IsEqual(Node.$id === 'Node', true) }) it('Should validate recursive node type', () => { const Node = Type.Recursive((This) => Type.Object({ id: Type.String(), nodes: Type.Array(This), }), ) Ok(Node, { id: 'A', nodes: [ { id: 'B', nodes: [] }, { id: 'C', nodes: [] }, ], }) }) it('Should validate wrapped recursive node type', () => { const Node = Type.Tuple([ Type.Recursive((This) => Type.Object({ id: Type.String(), nodes: Type.Array(This), }), ), ]) Ok(Node, [ { id: 'A', nodes: [ { id: 'B', nodes: [] }, { id: 'C', nodes: [] }, ], }, ]) }) it('Should not validate wrapped recursive node type with invalid id', () => { const Node = Type.Tuple([ Type.Recursive((This) => Type.Object({ id: Type.String(), nodes: Type.Array(This), }), ), ]) Fail(Node, [ { id: 'A', nodes: [ { id: 1, nodes: [] }, { id: 'C', nodes: [] }, ], }, ]) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/ref.ts000066400000000000000000000042501505437577000236610ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' import { Assert } from '../assert/index' describe('compiler/Ref', () => { // ---------------------------------------------------------------- // Deprecated // ---------------------------------------------------------------- it('Should validate for Ref(Schema)', () => { const T = Type.Number({ $id: 'T' }) const R = Type.Ref(T) Ok(R, 1234, [T]) Fail(R, 'hello', [T]) }) // ---------------------------------------------------------------- // Standard // ---------------------------------------------------------------- it('Should should validate when referencing a type', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { $id: Assert.NextId() }, ) const R = Type.Ref(T.$id!) Ok( R, { x: 1, y: 2, z: 3, }, [T], ) }) it('Should not validate when passing invalid data', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { $id: Assert.NextId() }, ) const R = Type.Ref(T.$id!) Fail( R, { x: 1, y: 2, }, [T], ) }) it('Should de-reference object property schema', () => { const T = Type.Object( { name: Type.String(), }, { $id: 'R' }, ) const R = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), r: Type.Optional(Type.Ref(T.$id!)), }, { $id: 'T' }, ) Ok(R, { x: 1, y: 2, z: 3 }, [T]) Ok(R, { x: 1, y: 2, z: 3, r: { name: 'hello' } }, [T]) Fail(R, { x: 1, y: 2, z: 3, r: { name: 1 } }, [T]) Fail(R, { x: 1, y: 2, z: 3, r: {} }, [T]) }) it('Should reference recursive schema', () => { const T = Type.Recursive((Node) => Type.Object({ id: Type.String(), nodes: Type.Array(Node), }), ) const R = Type.Ref(T.$id!) Ok(R, { id: '', nodes: [{ id: '', nodes: [] }] }, [T]) Fail(R, { id: '', nodes: [{ id: 1, nodes: [] }] }, [T]) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/regexp.ts000066400000000000000000000014061505437577000243770ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/RegExp', () => { it('Should validate regular expression 1', () => { const T = Type.RegExp(/foo/i) Ok(T, 'foo') Ok(T, 'Foo') Ok(T, 'fOO') Fail(T, 'bar') }) it('Should validate regular expression 2', () => { const T = Type.RegExp(/|\p{Extended_Pictographic}/gu) Ok(T, '♥�♦�♠�♣�') }) it('Should validate with minLength constraint', () => { const T = Type.RegExp(/(.*)/, { minLength: 3, }) Ok(T, 'xxx') Fail(T, 'xx') }) it('Should validate with maxLength constraint', () => { const T = Type.RegExp(/(.*)/, { maxLength: 3, }) Ok(T, 'xxx') Fail(T, 'xxxx') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/required.ts000066400000000000000000000035201505437577000247240ustar00rootroot00000000000000import { Type, ReadonlyKind, OptionalKind } from '@sinclair/typebox' import { Ok, Fail } from './validate' import { strictEqual } from 'assert' describe('compiler/Required', () => { it('Should convert a partial object into a required object', () => { const A = Type.Object( { x: Type.Optional(Type.Number()), y: Type.Optional(Type.Number()), z: Type.Optional(Type.Number()), }, { additionalProperties: false }, ) const T = Type.Required(A) Ok(T, { x: 1, y: 1, z: 1 }) Fail(T, { x: 1, y: 1 }) Fail(T, { x: 1 }) Fail(T, {}) }) it('Should update modifier types correctly when converting to required', () => { const A = Type.Object({ x: Type.Readonly(Type.Optional(Type.Number())), y: Type.Readonly(Type.Number()), z: Type.Optional(Type.Number()), w: Type.Number(), }) const T = Type.Required(A) strictEqual(T.properties.x[ReadonlyKind], 'Readonly') strictEqual(T.properties.y[ReadonlyKind], 'Readonly') strictEqual(T.properties.z[OptionalKind], undefined) strictEqual(T.properties.w[OptionalKind], undefined) }) it('Should inherit options from the source object', () => { const A = Type.Object( { x: Type.Optional(Type.Number()), y: Type.Optional(Type.Number()), z: Type.Optional(Type.Number()), }, { additionalPropeties: false }, ) const T = Type.Required(A) strictEqual(A.additionalPropeties, false) strictEqual(T.additionalPropeties, false) }) // it('Should construct new object when targetting reference', () => { // const T = Type.Object({ a: Type.String(), b: Type.String() }, { $id: 'T' }) // const R = Type.Ref(T) // const P = Type.Required(R) // strictEqual(P.properties.a.type, 'string') // strictEqual(P.properties.b.type, 'string') // }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/string-pattern.ts000066400000000000000000000033721505437577000260720ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/StringPattern', () => { //----------------------------------------------------- // Regular Expression //----------------------------------------------------- it('Should validate regular expression 1', () => { const T = Type.String({ pattern: /[012345]/.source }) Ok(T, '0') Ok(T, '1') Ok(T, '2') Ok(T, '3') Ok(T, '4') Ok(T, '5') }) it('Should validate regular expression 2', () => { const T = Type.String({ pattern: /true|false/.source }) Ok(T, 'true') Ok(T, 'true') Ok(T, 'true') Ok(T, 'false') Ok(T, 'false') Ok(T, 'false') Fail(T, '6') }) it('Should validate regular expression 3', () => { const T = Type.String({ pattern: /true|false/.source }) Fail(T, 'unknown') }) it('Should validate regular expression 4', () => { const T = Type.String({ pattern: /[\d]{5}/.source }) Ok(T, '12345') }) //----------------------------------------------------- // Regular Pattern //----------------------------------------------------- it('Should validate pattern 1', () => { const T = Type.String({ pattern: '[012345]' }) Ok(T, '0') Ok(T, '1') Ok(T, '2') Ok(T, '3') Ok(T, '4') Ok(T, '5') }) it('Should validate pattern 2', () => { const T = Type.String({ pattern: 'true|false' }) Ok(T, 'true') Ok(T, 'true') Ok(T, 'true') Ok(T, 'false') Ok(T, 'false') Ok(T, 'false') Fail(T, '6') }) it('Should validate pattern 3', () => { const T = Type.String({ pattern: 'true|false' }) Fail(T, 'unknown') }) it('Should validate pattern 4', () => { const T = Type.String({ pattern: '[\\d]{5}' }) Ok(T, '12345') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/string.ts000066400000000000000000000036371505437577000244230ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/String', () => { it('Should not validate number', () => { const T = Type.String() Fail(T, 1) }) it('Should validate string', () => { const T = Type.String() Ok(T, 'hello') }) it('Should not validate boolean', () => { const T = Type.String() Fail(T, true) }) it('Should not validate array', () => { const T = Type.String() Fail(T, [1, 2, 3]) }) it('Should not validate object', () => { const T = Type.String() Fail(T, { a: 1, b: 2 }) }) it('Should not validate null', () => { const T = Type.String() Fail(T, null) }) it('Should not validate undefined', () => { const T = Type.String() Fail(T, undefined) }) it('Should not validate bigint', () => { const T = Type.String() Fail(T, BigInt(1)) }) it('Should not validate symbol', () => { const T = Type.String() Fail(T, Symbol(1)) }) it('Should validate string format as email', () => { const T = Type.String({ format: 'email' }) Ok(T, 'name@domain.com') }) it('Should validate string format as uuid', () => { const T = Type.String({ format: 'uuid' }) Ok(T, '4a7a17c9-2492-4a53-8e13-06ea2d3f3bbf') }) it('Should validate string format as iso8601 date', () => { const T = Type.String({ format: 'date-time' }) Ok(T, '2021-06-11T20:30:00-04:00') }) it('Should validate minLength', () => { const T = Type.String({ minLength: 4 }) Ok(T, '....') Fail(T, '...') }) it('Should validate maxLength', () => { const T = Type.String({ maxLength: 4 }) Ok(T, '....') Fail(T, '.....') }) it('Should pass numeric 5 digit test', () => { const T = Type.String({ pattern: '[\\d]{5}' }) Ok(T, '12345') }) it('Should should escape characters in the pattern', () => { const T = Type.String({ pattern: '/a/' }) Ok(T, '/a/') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/symbol.ts000066400000000000000000000017671505437577000244240ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Symbol', () => { it('Should not validate a boolean', () => { const T = Type.Symbol() Fail(T, true) Fail(T, false) }) it('Should not validate a number', () => { const T = Type.Symbol() Fail(T, 1) }) it('Should not validate a string', () => { const T = Type.Symbol() Fail(T, 'true') }) it('Should not validate an array', () => { const T = Type.Symbol() Fail(T, [true]) }) it('Should not validate an object', () => { const T = Type.Symbol() Fail(T, {}) }) it('Should not validate an null', () => { const T = Type.Symbol() Fail(T, null) }) it('Should not validate an undefined', () => { const T = Type.Symbol() Fail(T, undefined) }) it('Should not validate bigint', () => { const T = Type.Symbol() Fail(T, BigInt(1)) }) it('Should not validate symbol', () => { const T = Type.Symbol() Ok(T, Symbol(1)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/template-literal.ts000066400000000000000000000110231505437577000263460ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/TemplateLiteral', () => { // -------------------------------------------------------- // Finite // -------------------------------------------------------- it('Should validate finite pattern 1', () => { // prettier-ignore const T = Type.TemplateLiteral([]) Ok(T, '') Fail(T, 'X') }) it('Should validate finite pattern 1', () => { // prettier-ignore const T = Type.TemplateLiteral([Type.Boolean()]) Ok(T, 'true') Ok(T, 'false') Fail(T, 'X') }) it('Should validate finite pattern 2', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A') ]) Ok(T, 'A') Fail(T, 'X') }) it('Should validate finite pattern 3', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.Literal('B') ]) Ok(T, 'AB') Fail(T, 'X') }) it('Should validate finite pattern 4', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.Union([ Type.Literal('B'), Type.Literal('C') ]), ]) Ok(T, 'AB') Ok(T, 'AC') Fail(T, 'X') }) it('Should validate finite pattern 5', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.Union([ Type.Literal('B'), Type.Literal('C') ]), Type.Literal('D'), ]) Ok(T, 'ABD') Ok(T, 'ACD') Fail(T, 'X') }) it('Should validate finite pattern 6', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Union([ Type.Literal('0'), Type.Literal('1') ]), Type.Union([ Type.Literal('0'), Type.Literal('1') ]), ]) Ok(T, '00') Ok(T, '01') Ok(T, '10') Ok(T, '11') Fail(T, 'X') }) // -------------------------------------------------------- // Infinite // -------------------------------------------------------- it('Should validate infinite pattern 1', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Number() ]) Ok(T, '1') Ok(T, '22') Ok(T, '333') Ok(T, '4444') Fail(T, 'X') }) it('Should validate infinite pattern 2', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Integer() ]) Ok(T, '1') Ok(T, '22') Ok(T, '333') Ok(T, '4444') Fail(T, 'X') }) it('Should validate infinite pattern 3', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.BigInt() ]) Ok(T, '1') Ok(T, '22') Ok(T, '333') Ok(T, '4444') Fail(T, 'X') }) it('Should validate infinite pattern 4', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.String() ]) Ok(T, '1') Ok(T, '22') Ok(T, '333') Ok(T, '4444') Ok(T, 'a') Ok(T, 'bb') Ok(T, 'ccc') Ok(T, 'dddd') }) it('Should validate infinite pattern 5', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.Number() ]) Ok(T, 'A1') Ok(T, 'A22') Ok(T, 'A333') Ok(T, 'A4444') Fail(T, 'X') }) it('Should validate infinite pattern 6', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.Integer() ]) Ok(T, 'A1') Ok(T, 'A22') Ok(T, 'A333') Ok(T, 'A4444') Fail(T, 'X') }) it('Should validate infinite pattern 7', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.BigInt() ]) Ok(T, 'A1') Ok(T, 'A22') Ok(T, 'A333') Ok(T, 'A4444') Fail(T, 'X') }) it('Should validate infinite pattern 8', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.String() ]) Ok(T, 'A1') Ok(T, 'A22') Ok(T, 'A333') Ok(T, 'A4444') Ok(T, 'Aa') Ok(T, 'Abb') Ok(T, 'Accc') Ok(T, 'Adddd') Fail(T, 'X') }) it('Should validate enum (implicit)', () => { enum E { A, B, C, } const T = Type.TemplateLiteral([Type.Literal('hello'), Type.Enum(E)]) Ok(T, 'hello0') Ok(T, 'hello1') Ok(T, 'hello2') Fail(T, 'hello3') }) it('Should validate enum (explicit)', () => { enum E { A, B = 'B', C = 'C', } const T = Type.TemplateLiteral([Type.Literal('hello'), Type.Enum(E)]) Ok(T, 'hello0') Ok(T, 'helloB') Ok(T, 'helloC') Fail(T, 'helloD') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/tuple.ts000066400000000000000000000034501505437577000242370ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Tuple', () => { it('Should validate tuple of [string, number]', () => { const A = Type.String() const B = Type.Number() const T = Type.Tuple([A, B]) Ok(T, ['hello', 42]) }) it('Should not validate tuple of [string, number] when reversed', () => { const A = Type.String() const B = Type.Number() const T = Type.Tuple([A, B]) Fail(T, [42, 'hello']) }) it('Should validate with empty tuple', () => { const T = Type.Tuple([]) Ok(T, []) }) it('Should not validate with empty tuple with more items', () => { const T = Type.Tuple([]) Fail(T, [1]) }) it('Should not validate with empty tuple with less items', () => { const T = Type.Tuple([Type.Number(), Type.Number()]) Fail(T, [1]) }) it('Should validate tuple of objects', () => { const A = Type.Object({ a: Type.String() }) const B = Type.Object({ b: Type.Number() }) const T = Type.Tuple([A, B]) Ok(T, [{ a: 'hello' }, { b: 42 }]) }) it('Should not validate tuple of objects when reversed', () => { const A = Type.Object({ a: Type.String() }) const B = Type.Object({ b: Type.Number() }) const T = Type.Tuple([A, B]) Fail(T, [{ b: 42 }, { a: 'hello' }]) }) it('Should not validate tuple when array is less than tuple length', () => { const A = Type.Object({ a: Type.String() }) const B = Type.Object({ b: Type.Number() }) const T = Type.Tuple([A, B]) Fail(T, [{ a: 'hello' }]) }) it('Should not validate tuple when array is greater than tuple length', () => { const A = Type.Object({ a: Type.String() }) const B = Type.Object({ b: Type.Number() }) const T = Type.Tuple([A, B]) Fail(T, [{ a: 'hello' }, { b: 42 }, { b: 42 }]) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/uint8array.ts000066400000000000000000000023631505437577000252160ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Uint8Array', () => { it('Should not validate number', () => { const T = Type.Uint8Array() Fail(T, 1) }) it('Should not validate string', () => { const T = Type.Uint8Array() Fail(T, 'hello') }) it('Should not validate boolean', () => { const T = Type.Uint8Array() Fail(T, true) }) it('Should not validate array', () => { const T = Type.Uint8Array() Fail(T, [1, 2, 3]) }) it('Should not validate object', () => { const T = Type.Uint8Array() Fail(T, { a: 1, b: 2 }) }) it('Should not validate null', () => { const T = Type.Uint8Array() Fail(T, null) }) it('Should not validate undefined', () => { const T = Type.Uint8Array() Fail(T, undefined) }) it('Should validate Uint8Array', () => { const T = Type.Uint8Array() Ok(T, new Uint8Array(100)) }) it('Should validate minByteLength', () => { const T = Type.Uint8Array({ minByteLength: 4 }) Ok(T, new Uint8Array(4)) Fail(T, new Uint8Array(3)) }) it('Should validate maxByteLength', () => { const T = Type.Uint8Array({ maxByteLength: 4 }) Ok(T, new Uint8Array(4)) Fail(T, new Uint8Array(5)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/unicode.ts000066400000000000000000000032001505437577000245250ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok } from './validate' describe('compiler/Unicode', () => { // --------------------------------------------------------- // Identifiers // --------------------------------------------------------- it('Should support unicode identifiers', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), }, { $id: '�별�', }, ) Ok(T, { x: 1, y: 2, }) }) it('Should support unicode identifier references', () => { const R = Type.Object( { x: Type.Number(), y: Type.Number(), }, { $id: '�별�', }, ) const T = Type.Object({ vector: Type.Ref(R.$id!), }) Ok( T, { vector: { x: 1, y: 2, }, }, [R], ) }) it('Should support unicode identifier recursion', () => { const Node = Type.Recursive( (Node) => Type.Object({ id: Type.String(), nodes: Type.Array(Node), }), { $id: '�별�', }, ) Ok(Node, { id: 'A', nodes: [ { id: 'B', nodes: [ { id: 'C', nodes: [], }, ], }, ], }) }) // --------------------------------------------------------- // Properties // --------------------------------------------------------- it('Should support unicode properties', () => { const T = Type.Object({ �름: Type.String(), }) Ok(T, { �름: 'dave', }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/union.ts000066400000000000000000000043711505437577000242410ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Union', () => { it('Should validate union of string, number and boolean', () => { const A = Type.String() const B = Type.Number() const C = Type.Boolean() const T = Type.Union([A, B, C]) Ok(T, 'hello') Ok(T, true) Ok(T, 42) }) it('Should validate union of objects', () => { const A = Type.Object({ a: Type.String() }, { additionalProperties: false }) const B = Type.Object({ b: Type.String() }, { additionalProperties: false }) const T = Type.Union([A, B]) Ok(T, { a: 'hello' }) Ok(T, { b: 'world' }) }) it('Should fail to validate for descriminated union types', () => { const A = Type.Object({ kind: Type.Literal('A'), value: Type.String() }) const B = Type.Object({ kind: Type.Literal('B'), value: Type.Number() }) const T = Type.Union([A, B]) Fail(T, { kind: 'A', value: 42 }) // expect { kind: 'A', value: string } Fail(T, { kind: 'B', value: 'hello' }) // expect { kind: 'B', value: number } }) it('Should validate union of objects where properties overlap', () => { const A = Type.Object({ a: Type.String() }, { additionalProperties: false }) const B = Type.Object({ a: Type.String(), b: Type.String() }, { additionalProperties: false }) const T = Type.Union([A, B]) Ok(T, { a: 'hello' }) // A Ok(T, { a: 'hello', b: 'world' }) // B }) it('Should validate union of overlapping property of varying type', () => { const A = Type.Object({ a: Type.String(), b: Type.Number() }, { additionalProperties: false }) const B = Type.Object({ a: Type.String(), b: Type.String() }, { additionalProperties: false }) const T = Type.Union([A, B]) Ok(T, { a: 'hello', b: 42 }) // A Ok(T, { a: 'hello', b: 'world' }) // B }) it('Should validate union of literal strings', () => { const A = Type.Literal('hello') const B = Type.Literal('world') const T = Type.Union([A, B]) Ok(T, 'hello') // A Ok(T, 'world') // B }) it('Should not validate union of literal strings for unknown string', () => { const A = Type.Literal('hello') const B = Type.Literal('world') const T = Type.Union([A, B]) Fail(T, 'foo') // A Fail(T, 'bar') // B }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/unknown.ts000066400000000000000000000013321505437577000246020ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok } from './validate' describe('compiler/Unknown', () => { it('Should validate number', () => { const T = Type.Any() Ok(T, 1) }) it('Should validate string', () => { const T = Type.Any() Ok(T, 'hello') }) it('Should validate boolean', () => { const T = Type.Any() Ok(T, true) }) it('Should validate array', () => { const T = Type.Any() Ok(T, [1, 2, 3]) }) it('Should validate object', () => { const T = Type.Any() Ok(T, { a: 1, b: 2 }) }) it('Should validate null', () => { const T = Type.Any() Ok(T, null) }) it('Should validate undefined', () => { const T = Type.Any() Ok(T, undefined) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/compiler/validate.ts000066400000000000000000000115341505437577000247010ustar00rootroot00000000000000import { TypeCompiler } from '@sinclair/typebox/compiler' import { Value } from '@sinclair/typebox/value' import { TSchema, FormatRegistry } from '@sinclair/typebox' // ------------------------------------------------------------------------- // Test Formats: https://github.com/ajv-validator/ajv-formats/blob/master/src/formats.ts // // - date-time // - email // - uuid // // ------------------------------------------------------------------------- const EMAIL = /^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i const UUID = /^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i const DATE_TIME_SEPARATOR = /t|\s/i const TIME = /^(\d\d):(\d\d):(\d\d(?:\.\d+)?)(z|([+-])(\d\d)(?::?(\d\d))?)?$/i const DATE = /^(\d\d\d\d)-(\d\d)-(\d\d)$/ const DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] function isLeapYear(year: number): boolean { return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0) } function isDate(str: string): boolean { const matches: string[] | null = DATE.exec(str) if (!matches) return false const year: number = +matches[1] const month: number = +matches[2] const day: number = +matches[3] return month >= 1 && month <= 12 && day >= 1 && day <= (month === 2 && isLeapYear(year) ? 29 : DAYS[month]) } function isTime(str: string, strictTimeZone?: boolean): boolean { const matches: string[] | null = TIME.exec(str) if (!matches) return false const hr: number = +matches[1] const min: number = +matches[2] const sec: number = +matches[3] const tz: string | undefined = matches[4] const tzSign: number = matches[5] === '-' ? -1 : 1 const tzH: number = +(matches[6] || 0) const tzM: number = +(matches[7] || 0) if (tzH > 23 || tzM > 59 || (strictTimeZone && !tz)) return false if (hr <= 23 && min <= 59 && sec < 60) return true // leap second const utcMin = min - tzM * tzSign const utcHr = hr - tzH * tzSign - (utcMin < 0 ? 1 : 0) return (utcHr === 23 || utcHr === -1) && (utcMin === 59 || utcMin === -1) && sec < 61 } function isDateTime(str: string, strictTimeZone?: boolean): boolean { const dateTime: string[] = str.split(DATE_TIME_SEPARATOR) return dateTime.length === 2 && isDate(dateTime[0]) && isTime(dateTime[1], strictTimeZone) } // ------------------------------------------------------------------------- // Use Formats // ------------------------------------------------------------------------- FormatRegistry.Set('email', (value) => EMAIL.test(value)) FormatRegistry.Set('uuid', (value) => UUID.test(value)) FormatRegistry.Set('date-time', (value) => isDateTime(value, true)) export function Ok(schema: T, data: unknown, references: any[] = []) { const C = TypeCompiler.Compile(schema, references) const result = C.Check(data) if (result !== Value.Check(schema, references, data)) { throw Error('Compiler and Value Check disparity') } if (result === false) { const errors = [...Value.Errors(schema, references, data)] if (errors.length === 0) throw Error('expected at least 1 error') } if (result === true) { const errors = [...Value.Errors(schema, references, data)] if (errors.length > 0) throw Error('expected no errors') } if (!result) { console.log('---------------------------') console.log('type') console.log('---------------------------') console.log(JSON.stringify(schema, null, 2)) console.log('---------------------------') console.log('data') console.log('---------------------------') console.log(JSON.stringify(data, null, 2)) console.log('---------------------------') console.log('errors') console.log('---------------------------') console.log(result) throw Error('expected ok') } } export function Fail(schema: T, data: unknown, references: any[] = []) { const C = TypeCompiler.Compile(schema, references) const result = C.Check(data) if (result !== Value.Check(schema, references, data)) { throw Error('Compiler and Value Check disparity') } if (result === false) { const errors = [...Value.Errors(schema, references, data)] if (errors.length === 0) throw Error('expected at least 1 error') } if (result === true) { const errors = [...Value.Errors(schema, references, data)] if (errors.length > 0) throw Error('expected no errors') } if (result) { console.log('---------------------------') console.log('type') console.log('---------------------------') console.log(JSON.stringify(schema, null, 2)) console.log('---------------------------') console.log('data') console.log('---------------------------') console.log(JSON.stringify(data, null, 2)) console.log('---------------------------') console.log('errors') console.log('---------------------------') console.log('none') throw Error('expected ok') } } sinclairzx81-typebox-e0ec98c/test/runtime/compiler/void.ts000066400000000000000000000015341505437577000240500ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Ok, Fail } from './validate' describe('compiler/Void', () => { it('Should not validate number', () => { const T = Type.Void() Fail(T, 1) }) it('Should not validate string', () => { const T = Type.Void() Fail(T, 'hello') }) it('Should not validate boolean', () => { const T = Type.Void() Fail(T, true) }) it('Should not validate array', () => { const T = Type.Void() Fail(T, [1, 2, 3]) }) it('Should not validate object', () => { const T = Type.Void() Fail(T, { a: 1, b: 2 }) }) it('Should validate null', () => { const T = Type.Void() Fail(T, null) }) it('Should validate undefined', () => { const T = Type.Void() Ok(T, undefined) }) it('Should validate void 0', () => { const T = Type.Void() Ok(T, void 0) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/000077500000000000000000000000001505437577000222365ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/errors/index.ts000066400000000000000000000000611505437577000237120ustar00rootroot00000000000000import './iterator/index' import './types/index' sinclairzx81-typebox-e0ec98c/test/runtime/errors/iterator/000077500000000000000000000000001505437577000240675ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/errors/iterator/index.ts000066400000000000000000000000241505437577000255420ustar00rootroot00000000000000import './iterator' sinclairzx81-typebox-e0ec98c/test/runtime/errors/iterator/iterator.ts000066400000000000000000000021511505437577000262670ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Errors } from '@sinclair/typebox/errors' import { Assert } from '../../assert' describe('errors/ValueErrorIterator', () => { it('Should return undefined for non error', () => { const R = Errors(Type.Number(), [], 1).First() Assert.IsEqual(R, undefined) }) it('Should return a value error when error', () => { const { type, path, message } = Errors(Type.Number(), [], '').First()! Assert.IsTypeOf(type, 'number') Assert.IsTypeOf(path, 'string') Assert.IsTypeOf(message, 'string') }) it('Should yield empty array for non error', () => { const R = [...Errors(Type.Number(), [], 1)] Assert.IsEqual(R.length, 0) }) it('Should yield array with 1 error when error', () => { const R = [...Errors(Type.Number(), [], 'foo')] Assert.IsEqual(R.length, 1) }) it('Should yield array with N errors when error', () => { // prettier-ignore const R = [...Errors(Type.Object({ x: Type.Number(), y: Type.Number() }), [], {})] // require object to invoke internal check Assert.IsEqual(R.length > 1, true) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/000077500000000000000000000000001505437577000234025ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/array-contains.ts000066400000000000000000000010471505437577000267060ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/ArrayMaxContainsItems', () => { const T = Type.Array(Type.Any(), { contains: Type.Literal(1) }) it('Should pass 0', () => { const R = Resolve(T, [1]) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, [2]) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.ArrayContains) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/array-max-contains.ts000066400000000000000000000022161505437577000274700ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/ArrayMaxContainsItems', () => { const T = Type.Array(Type.Any(), { contains: Type.Literal(1), maxContains: 4 }) it('Should pass 0', () => { const R = Resolve(T, [1, 1, 1, 1]) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, null) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Array) }) it('Should pass 2', () => { const R = Resolve(T, [1, 1, 1, 1, 1]) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.ArrayMaxContains) }) it('Should pass 3', () => { const R = Resolve(T, []) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.ArrayContains) }) it('Should pass 4', () => { const R = Resolve(T, [1, 2, 3, 4]) Assert.IsEqual(R.length, 0) }) it('Should pass 5', () => { const R = Resolve(T, [2, 3, 4]) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.ArrayContains) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/array-max-items.ts000066400000000000000000000012741505437577000267760ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/ArrayMaxItems', () => { const T = Type.Array(Type.Any(), { maxItems: 4 }) it('Should pass 0', () => { const R = Resolve(T, [1, 2, 3, 4]) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, null) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Array) }) it('Should pass 2', () => { const R = Resolve(T, [1, 2, 3, 4, 5]) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.ArrayMaxItems) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/array-min-contains.ts000066400000000000000000000016641505437577000274740ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/ArrayMinContainsItems', () => { const T = Type.Array(Type.Any(), { contains: Type.Literal(1), minContains: 4 }) it('Should pass 0', () => { const R = Resolve(T, [1, 1, 1, 1]) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, null) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Array) }) it('Should pass 2', () => { const R = Resolve(T, [1]) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.ArrayMinContains) }) it('Should pass 3', () => { const R = Resolve(T, []) Assert.IsEqual(R.length, 2) Assert.IsEqual(R[0].type, ValueErrorType.ArrayContains) Assert.IsEqual(R[1].type, ValueErrorType.ArrayMinContains) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/array-min-items.ts000066400000000000000000000012571505437577000267750ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/ArrayMinItems', () => { const T = Type.Array(Type.Any(), { minItems: 4 }) it('Should pass 0', () => { const R = Resolve(T, [1, 2, 3, 4]) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, null) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Array) }) it('Should pass 2', () => { const R = Resolve(T, []) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.ArrayMinItems) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/array-unique-items.ts000066400000000000000000000012171505437577000275140ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/ArrayUniqueItems', () => { const T = Type.Array(Type.Any(), { uniqueItems: true }) it('Should pass 0', () => { const R = Resolve(T, [1, 2, 3, 4]) Assert.IsEqual(R.length, 0) }) it('Should pass 2', () => { const R = Resolve(T, []) Assert.IsEqual(R.length, 0) }) it('Should pass 3', () => { const R = Resolve(T, [1, 1, 3, 4]) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.ArrayUniqueItems) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/array.ts000066400000000000000000000014361505437577000250740ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/Array', () => { const T = Type.Array(Type.Any()) it('Should pass 0', () => { const R = Resolve(T, [1, 2, 3]) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 1) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Array) }) it('Should pass 2', () => { const R = Resolve(T, {}) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Array) }) it('Should pass 3', () => { const R = Resolve(T, null) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Array) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/async-iterator.ts000066400000000000000000000010411505437577000267120ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/AsyncIterator', () => { const T = Type.AsyncIterator(Type.Any()) it('Should pass 0', () => { const R = Resolve(T, (async function* (): any {})()) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 1) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.AsyncIterator) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/bigint-exclusive-maximum.ts000066400000000000000000000010371505437577000307070ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/BigIntExclusiveMaximum', () => { const T = Type.BigInt({ exclusiveMaximum: 4n }) it('Should pass 0', () => { const R = Resolve(T, 0n) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 4n) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.BigIntExclusiveMaximum) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/bigint-exclusive-minimum.ts000066400000000000000000000010371505437577000307050ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/BigIntExclusiveMinimum', () => { const T = Type.BigInt({ exclusiveMinimum: 4n }) it('Should pass 0', () => { const R = Resolve(T, 5n) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 4n) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.BigIntExclusiveMinimum) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/bigint-maximum.ts000066400000000000000000000010041505437577000266740ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/BigIntMaximum', () => { const T = Type.BigInt({ maximum: 4n }) it('Should pass 0', () => { const R = Resolve(T, 0n) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 5n) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.BigIntMaximum) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/bigint-minimum.ts000066400000000000000000000010041505437577000266720ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/BigIntMinimum', () => { const T = Type.BigInt({ minimum: 4n }) it('Should pass 0', () => { const R = Resolve(T, 4n) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 3n) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.BigIntMinimum) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/bigint-multiple-of.ts000066400000000000000000000010151505437577000274560ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/BigIntMultipleOf', () => { const T = Type.BigInt({ multipleOf: 2n }) it('Should pass 0', () => { const R = Resolve(T, 0n) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 1n) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.BigIntMultipleOf) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/bigint.ts000066400000000000000000000007461505437577000252350ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/BigInt', () => { const T = Type.BigInt() it('Should pass 0', () => { const R = Resolve(T, 0n) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 0) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.BigInt) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/boolean.ts000066400000000000000000000007531505437577000253760ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/Boolean', () => { const T = Type.Boolean() it('Should pass 0', () => { const R = Resolve(T, true) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 0) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Boolean) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/date-exclusive-maximum-timestamp.ts000066400000000000000000000011051505437577000323450ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/DateExclusiveMaximumTimestamp', () => { const T = Type.Date({ exclusiveMaximumTimestamp: 4 }) it('Should pass 0', () => { const R = Resolve(T, new Date(0)) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, new Date(4)) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.DateExclusiveMaximumTimestamp) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/date-exclusive-minimum-timestamp.ts000066400000000000000000000011051505437577000323430ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/DateExclusiveMinimumTimestamp', () => { const T = Type.Date({ exclusiveMinimumTimestamp: 4 }) it('Should pass 0', () => { const R = Resolve(T, new Date(5)) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, new Date(4)) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.DateExclusiveMinimumTimestamp) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/date-maximum-timestamp.ts000066400000000000000000000010521505437577000303410ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/DateMaximumTimestamp', () => { const T = Type.Date({ maximumTimestamp: 4 }) it('Should pass 0', () => { const R = Resolve(T, new Date(0)) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, new Date(5)) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.DateMaximumTimestamp) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/date-minimum-timestamp.ts000066400000000000000000000010521505437577000303370ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/DateMinimumTimestamp', () => { const T = Type.Date({ minimumTimestamp: 4 }) it('Should pass 0', () => { const R = Resolve(T, new Date(4)) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, new Date(3)) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.DateMinimumTimestamp) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/date-multiple-of-timestamp.ts000066400000000000000000000010631505437577000311230ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/DateMultipleOfTimestamp', () => { const T = Type.Date({ multipleOfTimestamp: 2 }) it('Should pass 0', () => { const R = Resolve(T, new Date(0)) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, new Date(1)) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.DateMultipleOfTimestamp) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/date.ts000066400000000000000000000007501505437577000246710ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/Date', () => { const T = Type.Date() it('Should pass 0', () => { const R = Resolve(T, new Date()) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 0) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Date) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/function.ts000066400000000000000000000010131505437577000255720ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/Function', () => { const T = Type.Function([], Type.Any()) it('Should pass 0', () => { const R = Resolve(T, function (): any {}) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 1) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Function) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/index.ts000066400000000000000000000034701505437577000250650ustar00rootroot00000000000000import './array-contains' import './array-max-contains' import './array-min-items' import './array-min-contains' import './array-max-items' import './array-unique-items' import './array' import './async-iterator' import './bigint-exclusive-maximum' import './bigint-exclusive-minimum' import './bigint-maximum' import './bigint-minimum' import './bigint-multiple-of' import './bigint' import './boolean' import './date-exclusive-maximum-timestamp' import './date-exclusive-minimum-timestamp' import './date-maximum-timestamp' import './date-minimum-timestamp' import './date-multiple-of-timestamp' import './date' import './function' import './integer-exclusive-maximum' import './integer-exclusive-minimum' import './integer-maximum' import './integer-minimum' import './integer-multiple-of' import './integer' import './intersect-unevaluated-properties' import './intersect' import './iterator' import './kind' import './literal' import './never' import './not' import './null' import './number-exclusive-maximum' import './number-exclusive-minimum' import './number-maximum' import './number-minimum' import './number' import './number-multiple-of' import './object-additional-properties' import './object-max-properties' import './object-min-properties' import './object-pointer-property' import './object-required-property' import './object' import './promise' import './record-pointer-property' import './regexp-max-length' import './regexp-min-length' import './regexp' import './string-format-unknown' import './string-format' import './string-max-length' import './string-min-length' import './string-pattern' import './string' import './symbol' import './tuple-length' import './tuple' import './uint8array-max-byte-length' import './uint8array-min-byte-length' import './uint8array' import './undefined' import './union' import './void' sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/integer-exclusive-maximum.ts000066400000000000000000000010371505437577000310700ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/IntegerExclusiveMaximum', () => { const T = Type.Integer({ exclusiveMaximum: 4 }) it('Should pass 0', () => { const R = Resolve(T, 0) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 4) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.IntegerExclusiveMaximum) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/integer-exclusive-minimum.ts000066400000000000000000000010371505437577000310660ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/IntegerExclusiveMinimum', () => { const T = Type.Integer({ exclusiveMinimum: 4 }) it('Should pass 0', () => { const R = Resolve(T, 5) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 4) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.IntegerExclusiveMinimum) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/integer-maximum.ts000066400000000000000000000010041505437577000270550ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/IntegerMaximum', () => { const T = Type.Integer({ maximum: 4 }) it('Should pass 0', () => { const R = Resolve(T, 0) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 5) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.IntegerMaximum) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/integer-minimum.ts000066400000000000000000000010041505437577000270530ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/IntegerMinimum', () => { const T = Type.Integer({ minimum: 4 }) it('Should pass 0', () => { const R = Resolve(T, 4) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 3) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.IntegerMinimum) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/integer-multiple-of.ts000066400000000000000000000010151505437577000276370ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/IntegerMultipleOf', () => { const T = Type.Integer({ multipleOf: 2 }) it('Should pass 0', () => { const R = Resolve(T, 0) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 1) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.IntegerMultipleOf) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/integer.ts000066400000000000000000000007511505437577000254120ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/Integer', () => { const T = Type.Integer() it('Should pass 0', () => { const R = Resolve(T, 0) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 0n) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Integer) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/intersect-unevaluated-properties.ts000066400000000000000000000024431505437577000324620ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/IntersectUnevaluatedProperties', () => { const T1 = Type.Intersect([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })], { unevaluatedProperties: false, }) it('Should pass 0', () => { const R = Resolve(T1, { x: 1, y: 2 }) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T1, { x: 1, y: 2, z: 3 }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.IntersectUnevaluatedProperties) }) const T2 = Type.Intersect([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })], { unevaluatedProperties: Type.String(), }) it('Should pass 3', () => { const R = Resolve(T2, { x: 1, y: 2, z: '1' }) Assert.IsEqual(R.length, 0) }) it('Should pass 4', () => { const R = Resolve(T2, { x: 1, y: 2, a: 1, b: 2 }) Assert.IsEqual(R.length, 2) Assert.IsEqual(R[0].type, ValueErrorType.String) Assert.IsEqual(R[0].path, '/a') Assert.IsEqual(R[0].value, 1) Assert.IsEqual(R[1].type, ValueErrorType.String) Assert.IsEqual(R[1].path, '/b') Assert.IsEqual(R[1].value, 2) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/intersect.ts000066400000000000000000000045131505437577000257550ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/Intersect', () => { it('Should pass 0', () => { const T = Type.Intersect([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })]) const R = Resolve(T, { x: 1, y: 1 }) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const T = Type.Intersect([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })]) const R = Resolve(T, { x: 1 }) Assert.IsEqual(R.length, 3) Assert.IsEqual(R[0].type, ValueErrorType.ObjectRequiredProperty) Assert.IsEqual(R[1].type, ValueErrorType.Number) Assert.IsEqual(R[2].type, ValueErrorType.Intersect) }) it('Should pass 2', () => { const T = Type.Intersect([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })]) const R = Resolve(T, { y: 1 }) Assert.IsEqual(R.length, 3) Assert.IsEqual(R[0].type, ValueErrorType.ObjectRequiredProperty) Assert.IsEqual(R[1].type, ValueErrorType.Number) Assert.IsEqual(R[2].type, ValueErrorType.Intersect) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/887 // ---------------------------------------------------------------- it('Should pass 3', () => { const A = Type.Intersect([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })]) const B = Type.Intersect([Type.Object({ x: Type.Number() }), Type.Object({ z: Type.Number() })]) const T = Type.Intersect([A, B]) const R = Resolve(T, {}) Assert.IsEqual(R.length, 11) Assert.IsEqual(R[0].type, ValueErrorType.ObjectRequiredProperty) Assert.IsEqual(R[1].type, ValueErrorType.Number) Assert.IsEqual(R[2].type, ValueErrorType.ObjectRequiredProperty) Assert.IsEqual(R[3].type, ValueErrorType.Number) Assert.IsEqual(R[4].type, ValueErrorType.Intersect) Assert.IsEqual(R[5].type, ValueErrorType.ObjectRequiredProperty) Assert.IsEqual(R[6].type, ValueErrorType.Number) Assert.IsEqual(R[7].type, ValueErrorType.ObjectRequiredProperty) Assert.IsEqual(R[8].type, ValueErrorType.Number) Assert.IsEqual(R[9].type, ValueErrorType.Intersect) Assert.IsEqual(R[10].type, ValueErrorType.Intersect) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/iterator.ts000066400000000000000000000010141505437577000255770ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/Iterator', () => { const T = Type.Iterator(Type.Any()) it('Should pass 0', () => { const R = Resolve(T, (function* (): any {})()) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 1) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Iterator) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/kind.ts000066400000000000000000000016101505437577000246750ustar00rootroot00000000000000import { TypeRegistry, Kind, TSchema } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/Kind', () => { // ---------------------------------------------------- // Fixture // ---------------------------------------------------- beforeEach(() => TypeRegistry.Set('Foo', (schema, value) => value === 'foo')) afterEach(() => TypeRegistry.Delete('Foo')) // ---------------------------------------------------- // Test // ---------------------------------------------------- const T = { [Kind]: 'Foo' } as TSchema it('Should pass 0', () => { const R = Resolve(T, 'foo') Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 1) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Kind) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/literal.ts000066400000000000000000000027121505437577000254100ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/Literal', () => { // ----------------------------------------------------- // LiteralString // ----------------------------------------------------- const T1 = Type.Literal('hello') it('Should pass 0', () => { const R = Resolve(T1, 'hello') Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T1, 'world') Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Literal) }) // ----------------------------------------------------- // LiteralNumber // ----------------------------------------------------- const T2 = Type.Literal(0) it('Should pass 2', () => { const R = Resolve(T2, 0) Assert.IsEqual(R.length, 0) }) it('Should pass 3', () => { const R = Resolve(T2, 1) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Literal) }) // ----------------------------------------------------- // LiteralBoolean // ----------------------------------------------------- const T3 = Type.Literal(true) it('Should pass 4', () => { const R = Resolve(T3, true) Assert.IsEqual(R.length, 0) }) it('Should pass 5', () => { const R = Resolve(T3, false) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Literal) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/never.ts000066400000000000000000000006031505437577000250700ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/Never', () => { const T = Type.Never() it('Should pass 1', () => { const R = Resolve(T, 0) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Never) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/not.ts000066400000000000000000000007621505437577000245570ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/Not', () => { const T = Type.Not(Type.String()) it('Should pass 0', () => { const R = Resolve(T, true) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 'hello') Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Not) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/null.ts000066400000000000000000000007421505437577000247270ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/Null', () => { const T = Type.Null() it('Should pass 0', () => { const R = Resolve(T, null) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 1) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/number-exclusive-maximum.ts000066400000000000000000000010341505437577000307200ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/NumberExclusiveMaximum', () => { const T = Type.Number({ exclusiveMaximum: 4 }) it('Should pass 0', () => { const R = Resolve(T, 0) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 4) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.NumberExclusiveMaximum) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/number-exclusive-minimum.ts000066400000000000000000000010341505437577000307160ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/NumberExclusiveMinimum', () => { const T = Type.Number({ exclusiveMinimum: 4 }) it('Should pass 0', () => { const R = Resolve(T, 5) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 4) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.NumberExclusiveMinimum) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/number-maximum.ts000066400000000000000000000010011505437577000267050ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/NumberMaximum', () => { const T = Type.Number({ maximum: 4 }) it('Should pass 0', () => { const R = Resolve(T, 0) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 5) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.NumberMaximum) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/number-minimum.ts000066400000000000000000000010011505437577000267030ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/NumberMinimum', () => { const T = Type.Number({ minimum: 4 }) it('Should pass 0', () => { const R = Resolve(T, 4) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 3) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.NumberMinimum) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/number-multiple-of.ts000066400000000000000000000010121505437577000274670ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/NumberMultipleOf', () => { const T = Type.Number({ multipleOf: 2 }) it('Should pass 0', () => { const R = Resolve(T, 0) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 1) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.NumberMultipleOf) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/number.ts000066400000000000000000000007461505437577000252510ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/Number', () => { const T = Type.Number() it('Should pass 0', () => { const R = Resolve(T, 0) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 0n) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Number) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/object-additional-properties.ts000066400000000000000000000027651505437577000315320ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/ObjectAdditionalProperties', () => { // ---------------------------------------------------------- // additionalProperties: false // ---------------------------------------------------------- const T1 = Type.Object( { x: Type.Number(), }, { additionalProperties: false }, ) it('Should pass 0', () => { const R = Resolve(T1, { x: 1 }) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T1, { x: 1, y: 1 }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.ObjectAdditionalProperties) }) // ---------------------------------------------------------- // additionalProperties: TSchema // ---------------------------------------------------------- const T2 = Type.Object( { x: Type.Number(), }, { additionalProperties: Type.String() }, ) it('Should pass 2', () => { const R = Resolve(T2, { x: 1 }) Assert.IsEqual(R.length, 0) }) it('Should pass 3', () => { const R = Resolve(T2, { x: 1, a: 1, b: 2 }) Assert.IsEqual(R.length, 2) Assert.IsEqual(R[0].type, ValueErrorType.String) Assert.IsEqual(R[0].path, '/a') Assert.IsEqual(R[0].value, 1) Assert.IsEqual(R[1].type, ValueErrorType.String) Assert.IsEqual(R[1].path, '/b') Assert.IsEqual(R[1].value, 2) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/object-max-properties.ts000066400000000000000000000010671505437577000302010ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/ObjectMaxProperties', () => { const T = Type.Object({}, { maxProperties: 2 }) it('Should pass 0', () => { const R = Resolve(T, { x: 1, y: 2 }) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, { x: 1, y: 2, z: 3 }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.ObjectMaxProperties) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/object-min-properties.ts000066400000000000000000000010531505437577000301720ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/ObjectMinProperties', () => { const T = Type.Object({}, { minProperties: 2 }) it('Should pass 0', () => { const R = Resolve(T, { x: 1, y: 2 }) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, { x: 1 }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.ObjectMinProperties) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/object-pointer-property.ts000066400000000000000000000116251505437577000305650ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/ObjectPointerProperty', () => { // ---------------------------------------------------------------- // Known // ---------------------------------------------------------------- it('Should produce known pointer property path 1', () => { const T = Type.Object({ 'a/b': Type.String() }) const R = Resolve(T, { 'a/b': 1 }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].path, '/a~1b') }) it('Should produce known pointer property path 2', () => { const T = Type.Object({ 'a~b': Type.String() }) const R = Resolve(T, { 'a~b': 1 }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].path, '/a~0b') }) it('Should produce known pointer property path 3', () => { const T = Type.Object({ 'a/b~c': Type.String() }) const R = Resolve(T, { 'a/b~c': 1 }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].path, '/a~1b~0c') }) it('Should produce known pointer property path 4', () => { const T = Type.Object({ 'a~b/c': Type.String() }) const R = Resolve(T, { 'a~b/c': 1 }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].path, '/a~0b~1c') }) it('Should produce known pointer property path 5', () => { const T = Type.Object({ 'a~b/c/d': Type.String() }) const R = Resolve(T, { 'a~b/c/d': 1 }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].path, '/a~0b~1c~1d') }) it('Should produce known pointer property path 6', () => { const T = Type.Object({ 'a~b/c/d~e': Type.String() }) const R = Resolve(T, { 'a~b/c/d~e': 1 }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].path, '/a~0b~1c~1d~0e') }) // ---------------------------------------------------------------- // Unknown Additional // ---------------------------------------------------------------- it('Should produce unknown pointer property path 1', () => { const T = Type.Object({}, { additionalProperties: false }) const R = Resolve(T, { 'a/b': 1 }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].path, '/a~1b') }) it('Should produce unknown pointer property path 2', () => { const T = Type.Object({}, { additionalProperties: false }) const R = Resolve(T, { 'a~b': 1 }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].path, '/a~0b') }) // ---------------------------------------------------------------- // Unknown Constrained // ---------------------------------------------------------------- it('Should produce unknown constrained pointer property path 1', () => { const T = Type.Object({}, { additionalProperties: Type.String() }) const R = Resolve(T, { 'a/b': 1 }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].path, '/a~1b') }) it('Should produce unknown constrained pointer property path 2', () => { const T = Type.Object({}, { additionalProperties: Type.String() }) const R = Resolve(T, { 'a~b': 1 }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].path, '/a~0b') }) // ---------------------------------------------------------------- // Nested // ---------------------------------------------------------------- it('Should produce nested pointer 1', () => { const T = Type.Object({ 'x/y': Type.Object({ z: Type.Object({ w: Type.String(), }), }), }) const R = Resolve(T, { 'x/y': { z: { w: 1 } } }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].path, '/x~1y/z/w') }) it('Should produce nested pointer 2', () => { const T = Type.Object({ x: Type.Object({ 'y/z': Type.Object({ w: Type.String(), }), }), }) const R = Resolve(T, { x: { 'y/z': { w: 1 } } }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].path, '/x/y~1z/w') }) it('Should produce nested pointer 3', () => { const T = Type.Object({ x: Type.Object({ y: Type.Object({ 'z/w': Type.String(), }), }), }) const R = Resolve(T, { x: { y: { 'z/w': 1 } } }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].path, '/x/y/z~1w') }) // ---------------------------------------------------------------- // Nested Array // ---------------------------------------------------------------- it('Should produce nested array pointer property path 1', () => { const T = Type.Object({ 'x/y': Type.Object({ z: Type.Array(Type.String()), }), }) const R = Resolve(T, { 'x/y': { z: ['a', 'b', 1] } }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].path, '/x~1y/z/2') }) it('Should produce nested array pointer property path 2', () => { const T = Type.Object({ x: Type.Array( Type.Object({ 'y/z': Type.String(), }), ), }) const R = Resolve(T, { x: [{ 'y/z': 'a' }, { 'y/z': 'b' }, { 'y/z': 1 }] }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].path, '/x/2/y~1z') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/object-required-property.ts000066400000000000000000000014201505437577000307150ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/ObjectRequiredProperty', () => { const T = Type.Object({ x: Type.Number(), y: Type.Number() }) it('Should pass 0', () => { const R = Resolve(T, { x: 1, y: 2 }) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, { x: 1 }) Assert.IsEqual(R.length, 2) Assert.IsEqual(R[0].type, ValueErrorType.ObjectRequiredProperty) Assert.IsEqual(R[0].path, '/y') Assert.IsEqual(R[0].value, undefined) Assert.IsEqual(R[1].type, ValueErrorType.Number) Assert.IsEqual(R[1].path, '/y') Assert.IsEqual(R[1].value, undefined) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/object.ts000066400000000000000000000043341505437577000252240ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/Object', () => { // ----------------------------------------------------------------- // Object // ----------------------------------------------------------------- const T1 = Type.Object({ x: Type.Number(), y: Type.Number() }) it('Should pass 0', () => { const R = Resolve(T1, { x: 1, y: 2 }) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T1, null) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Object) }) // ----------------------------------------------------------------- // Object: Optional // ----------------------------------------------------------------- const T2 = Type.Object({ x: Type.Optional(Type.Number()) }) it('Should pass 2', () => { const R = Resolve(T2, {}) Assert.IsEqual(R.length, 0) }) it('Should pass 3', () => { const R = Resolve(T2, { x: 1 }) Assert.IsEqual(R.length, 0) }) it('Should pass 4', () => { const R = Resolve(T2, { x: '' }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Number) Assert.IsEqual(R[0].path, '/x') Assert.IsEqual(R[0].value, '') }) // ----------------------------------------------------------------- // Object: Optional Multiple // ----------------------------------------------------------------- const T3 = Type.Partial(Type.Object({ x: Type.Number(), y: Type.Number() })) it('Should pass 5', () => { const R = Resolve(T3, {}) Assert.IsEqual(R.length, 0) }) it('Should pass 6', () => { const R = Resolve(T3, { x: 1 }) Assert.IsEqual(R.length, 0) }) it('Should pass 7', () => { const R = Resolve(T3, { y: 1 }) Assert.IsEqual(R.length, 0) }) it('Should pass 8', () => { const R = Resolve(T3, { x: 'a', y: 'b' }) Assert.IsEqual(R.length, 2) Assert.IsEqual(R[0].type, ValueErrorType.Number) Assert.IsEqual(R[0].path, '/x') Assert.IsEqual(R[0].value, 'a') Assert.IsEqual(R[1].type, ValueErrorType.Number) Assert.IsEqual(R[1].path, '/y') Assert.IsEqual(R[1].value, 'b') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/promise.ts000066400000000000000000000010031505437577000254220ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/Promise', () => { const T = Type.Promise(Type.Any()) it('Should pass 0', () => { const R = Resolve(T, Promise.resolve(0)) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 0) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Promise) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/record-pointer-property.ts000066400000000000000000000052601505437577000305730ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/RecordPointerProperty', () => { // ---------------------------------------------------------------- // Known // ---------------------------------------------------------------- it('Should produce known pointer property path 1', () => { const T = Type.Record(Type.String(), Type.String()) const R = Resolve(T, { 'a/b': 1 }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].path, '/a~1b') }) it('Should produce known pointer property path 2', () => { const T = Type.Record(Type.String(), Type.String()) const R = Resolve(T, { 'a~b': 1 }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].path, '/a~0b') }) // ---------------------------------------------------------------- // Unknown // ---------------------------------------------------------------- it('Should produce unknown pointer property path 1', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: false, }) const R = Resolve(T, { 'a/b': 1 }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].path, '/a~1b') }) it('Should produce unknown pointer property path 1', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: false, }) const R = Resolve(T, { 'a~b': 1 }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].path, '/a~0b') }) // ---------------------------------------------------------------- // Unknown Constrained // ---------------------------------------------------------------- it('Should produce unknown constrained pointer property path 1', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: Type.String(), }) const R = Resolve(T, { 'a/b': 1 }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].path, '/a~1b') }) it('Should produce unknown constrained pointer property path 1', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: Type.String(), }) const R = Resolve(T, { 'a~b': 1 }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].path, '/a~0b') }) // ---------------------------------------------------------------- // PatternProperties // ---------------------------------------------------------------- it('Should produce pattern pointer property path 1', () => { const T = Type.Record(Type.TemplateLiteral('${string}/${string}/c'), Type.String(), { additionalProperties: false, }) const R = Resolve(T, { 'x/y/z': 1 }) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].path, '/x~1y~1z') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/regexp-max-length.ts000066400000000000000000000010611505437577000273040ustar00rootroot00000000000000import { Type, FormatRegistry } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/RegExpMaxLength', () => { const T = Type.RegExp(/(.*)/, { maxLength: 4, }) it('Should pass 0', () => { const R = Resolve(T, 'xxxx') Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 'xxxxx') Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.StringMaxLength) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/regexp-min-length.ts000066400000000000000000000010371505437577000273050ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/RegExpMinLength', () => { const T = Type.RegExp(/(.*)/, { minLength: 4, }) it('Should pass 0', () => { const R = Resolve(T, 'xxxx') Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 'xxx') Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.StringMinLength) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/regexp.ts000066400000000000000000000007621505437577000252510ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/RegExp', () => { const T = Type.RegExp(/123/) it('Should pass 0', () => { const R = Resolve(T, '123') Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, '321') Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.RegExp) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/resolve.ts000066400000000000000000000003441505437577000254320ustar00rootroot00000000000000import { Errors } from '@sinclair/typebox/errors' import { TSchema } from '@sinclair/typebox' /** Resolves errors */ export function Resolve(schema: T, value: unknown) { return [...Errors(schema, value)] } sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/string-format-unknown.ts000066400000000000000000000006661505437577000302530ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/StringFormatUnknown', () => { const T = Type.String({ format: 'unknown' }) it('Should pass 1', () => { const R = Resolve(T, '') Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.StringFormatUnknown) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/string-format.ts000066400000000000000000000015741505437577000265550ustar00rootroot00000000000000import { Type, FormatRegistry } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/StringFormat', () => { // ---------------------------------------------- // Fixture // ---------------------------------------------- beforeEach(() => FormatRegistry.Set('foo', (value) => value === 'foo')) afterEach(() => FormatRegistry.Delete('foo')) // ---------------------------------------------- // Tests // ---------------------------------------------- const T = Type.String({ format: 'foo' }) it('Should pass 0', () => { const R = Resolve(T, 'foo') Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 'bar') Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.StringFormat) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/string-max-length.ts000066400000000000000000000010421505437577000273170ustar00rootroot00000000000000import { Type, FormatRegistry } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/StringMaxLength', () => { const T = Type.String({ maxLength: 4 }) it('Should pass 0', () => { const R = Resolve(T, '1234') Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, '12345') Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.StringMaxLength) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/string-min-length.ts000066400000000000000000000010201505437577000273110ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/StringMinLength', () => { const T = Type.String({ minLength: 4 }) it('Should pass 0', () => { const R = Resolve(T, '1234') Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, '123') Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.StringMinLength) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/string-pattern.ts000066400000000000000000000010151505437577000267300ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/StringPattern', () => { const T = Type.String({ pattern: '123' }) it('Should pass 0', () => { const R = Resolve(T, '123') Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, '321') Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.StringPattern) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/string.ts000066400000000000000000000007531505437577000252650ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/String', () => { const T = Type.String() it('Should pass 0', () => { const R = Resolve(T, 'hello') Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 1) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.String) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/symbol.ts000066400000000000000000000007551505437577000252660ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/Symbol', () => { const T = Type.Symbol() it('Should pass 0', () => { const R = Resolve(T, Symbol(1)) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 1) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Symbol) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/tuple-length.ts000066400000000000000000000034511505437577000263650ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/TupleLength', () => { // ---------------------------------------------- // Tuple: Empty // ---------------------------------------------- const T1 = Type.Tuple([]) it('Should pass 0', () => { const R = Resolve(T1, []) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T1, [1]) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.TupleLength) }) // ---------------------------------------------- // Tuple: One // ---------------------------------------------- const T2 = Type.Tuple([Type.Number()]) it('Should pass 2', () => { const R = Resolve(T2, [1]) Assert.IsEqual(R.length, 0) }) it('Should pass 3', () => { const R = Resolve(T2, []) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.TupleLength) }) it('Should pass 4', () => { const R = Resolve(T2, [1, 1]) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.TupleLength) }) // ---------------------------------------------- // Tuple: Element // ---------------------------------------------- const T3 = Type.Tuple([Type.Number(), Type.Number()]) it('Should pass 5', () => { const R = Resolve(T3, [1, 1]) Assert.IsEqual(R.length, 0) }) it('Should pass 6', () => { const R = Resolve(T3, ['a', 'b']) Assert.IsEqual(R.length, 2) Assert.IsEqual(R[0].type, ValueErrorType.Number) Assert.IsEqual(R[0].path, '/0') Assert.IsEqual(R[0].value, 'a') Assert.IsEqual(R[1].type, ValueErrorType.Number) Assert.IsEqual(R[1].path, '/1') Assert.IsEqual(R[1].value, 'b') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/tuple.ts000066400000000000000000000007451505437577000251110ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/Tuple', () => { const T = Type.Tuple([]) it('Should pass 0', () => { const R = Resolve(T, []) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 1) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Tuple) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/uint8array-max-byte-length.ts000066400000000000000000000010771505437577000310700ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/Uint8ArrayMaxByteLength', () => { const T = Type.Uint8Array({ maxByteLength: 4 }) it('Should pass 0', () => { const R = Resolve(T, new Uint8Array(4)) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, new Uint8Array(5)) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Uint8ArrayMaxByteLength) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/uint8array-min-byte-length.ts000066400000000000000000000011171505437577000310610ustar00rootroot00000000000000import { Type, FormatRegistry } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/Uint8ArrayMinByteLength', () => { const T = Type.Uint8Array({ minByteLength: 4 }) it('Should pass 0', () => { const R = Resolve(T, new Uint8Array(4)) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, new Uint8Array(3)) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Uint8ArrayMinByteLength) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/uint8array.ts000066400000000000000000000010241505437577000260550ustar00rootroot00000000000000import { Type, FormatRegistry } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/Uint8Array', () => { const T = Type.Uint8Array() it('Should pass 0', () => { const R = Resolve(T, new Uint8Array(4)) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, null) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Uint8Array) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/undefined.ts000066400000000000000000000007661505437577000257240ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/Undefined', () => { const T = Type.Undefined() it('Should pass 0', () => { const R = Resolve(T, undefined) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 0) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Undefined) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/union.ts000066400000000000000000000014101505437577000250760ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorIterator, ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' describe('errors/type/Union', () => { const T = Type.Union([Type.String(), Type.Number()]) it('Should pass 0', () => { const R = Resolve(T, '1') Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, 1) Assert.IsEqual(R.length, 0) }) it('Should pass 2', () => { const R = Resolve(T, true) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Union) Assert.IsEqual(R[0].errors[0].First()?.type, ValueErrorType.String) Assert.IsEqual(R[0].errors[1].First()?.type, ValueErrorType.Number) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/errors/types/void.ts000066400000000000000000000016451505437577000247210ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { ValueErrorType } from '@sinclair/typebox/errors' import { Resolve } from './resolve' import { Assert } from '../../assert' import { TypeSystemPolicy } from '@sinclair/typebox/system' describe('errors/type/Void', () => { const T = Type.Void() it('Should pass 0', () => { const R = Resolve(T, void 0) Assert.IsEqual(R.length, 0) }) it('Should pass 1', () => { const R = Resolve(T, undefined) Assert.IsEqual(R.length, 0) }) it('Should pass 2', () => { const R = Resolve(T, void 1) Assert.IsEqual(R.length, 0) }) it('Should pass 3', () => { const R = Resolve(T, null) Assert.IsEqual(R.length, 1) Assert.IsEqual(R[0].type, ValueErrorType.Void) }) it('Should pass 4', () => { TypeSystemPolicy.AllowNullVoid = true const R = Resolve(T, null) Assert.IsEqual(R.length, 0) TypeSystemPolicy.AllowNullVoid = false }) }) sinclairzx81-typebox-e0ec98c/test/runtime/index.ts000066400000000000000000000007311505437577000224020ustar00rootroot00000000000000import { TypeSystemPolicy } from '@sinclair/typebox/system' // ------------------------------------------------------------------ // InstanceMode: Freeze (Detect Unintended Side Effects) // ------------------------------------------------------------------ TypeSystemPolicy.InstanceMode = 'freeze' import './compiler/index' import './compiler-ajv/index' import './errors/index' import './syntax/index' import './system/index' import './type/index' import './value/index' sinclairzx81-typebox-e0ec98c/test/runtime/syntax/000077500000000000000000000000001505437577000222505ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/syntax/index.ts000066400000000000000000000000221505437577000237210ustar00rootroot00000000000000import './syntax' sinclairzx81-typebox-e0ec98c/test/runtime/syntax/syntax.ts000066400000000000000000000365611505437577000241610ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Syntax } from '@sinclair/typebox/syntax' import { Assert } from '../assert/index' // prettier-ignore describe('syntax/Syntax', () => { // ---------------------------------------------------------------- // Type Expressions // ---------------------------------------------------------------- it('Should parse Any', () => { const T = Syntax(`any`) Assert.IsTrue(TypeGuard.IsAny(T)) }) it('Should parse Array 1', () => { const T = Syntax(`number[]`) Assert.IsTrue(TypeGuard.IsArray(T)) Assert.IsTrue(TypeGuard.IsNumber(T.items)) }) it('Should parse Array 2', () => { const T = Syntax(`Array`) Assert.IsTrue(TypeGuard.IsArray(T)) Assert.IsTrue(TypeGuard.IsNumber(T.items)) }) it('Should parse AsyncIterator', () => { const T = Syntax(`AsyncIterator`) Assert.IsTrue(TypeGuard.IsAsyncIterator(T)) Assert.IsTrue(TypeGuard.IsNumber(T.items)) }) it('Should parse Awaited', () => { const T = Syntax(`Awaited>`) Assert.IsTrue(TypeGuard.IsNumber(T)) }) it('Should parse BigInt', () => { const T = Syntax(`bigint`) Assert.IsTrue(TypeGuard.IsBigInt(T)) }) it('Should parse Boolean', () => { const T = Syntax(`boolean`) Assert.IsTrue(TypeGuard.IsBoolean(T)) }) it('Should parse ConstructorParameters', () => { const T = Syntax(`ConstructorParameters boolean>`) Assert.IsTrue(TypeGuard.IsTuple(T)) Assert.IsTrue(TypeGuard.IsNumber(T.items![0])) Assert.IsTrue(TypeGuard.IsString(T.items![1])) }) it('Should parse Constructor', () => { const T = Syntax(`new (a: number, b: string) => boolean`) Assert.IsTrue(TypeGuard.IsConstructor(T)) Assert.IsTrue(TypeGuard.IsNumber(T.parameters[0])) Assert.IsTrue(TypeGuard.IsString(T.parameters[1])) Assert.IsTrue(TypeGuard.IsBoolean(T.returns)) }) it('Should parse Date', () => { const T = Syntax(`Date`) Assert.IsTrue(TypeGuard.IsDate(T)) }) it('Should parse Exclude', () => { const T = Syntax(`Exclude<1 | 2 | 3, 1>`) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsTrue(T.anyOf[0].const === 2) Assert.IsTrue(T.anyOf[1].const === 3) }) it('Should parse Extract', () => { const T = Syntax(`Extract<1 | 2 | 3, 1 | 2>`) Assert.IsTrue(TypeGuard.IsUnion(T)) // @ts-ignore fix: incorrect union order (result of UnionToTuple, replace with Tuple destructuring) Assert.IsTrue(T.anyOf[0].const === 1) // @ts-ignore fix: incorrect union order (result of UnionToTuple, replace with Tuple destructuring) Assert.IsTrue(T.anyOf[1].const === 2) }) it('Should parse Function', () => { const T = Syntax(`(a: number, b: string) => boolean`) Assert.IsTrue(TypeGuard.IsFunction(T)) Assert.IsTrue(TypeGuard.IsNumber(T.parameters[0])) Assert.IsTrue(TypeGuard.IsString(T.parameters[1])) Assert.IsTrue(TypeGuard.IsBoolean(T.returns)) }) it('Should parse Indexed 1', () => { const T = Syntax(`{ x: 1, y: 2, z: 3 }['x']`) Assert.IsTrue(T.const === 1) }) it('Should parse Indexed 2', () => { const T = Syntax(`{ x: 1, y: 2, z: 3 }['x' | 'y' | 'z']`) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsTrue(T.anyOf[0].const === 1) Assert.IsTrue(T.anyOf[1].const === 2) Assert.IsTrue(T.anyOf[2].const === 3) }) it('Should parse Indexed 3', () => { const T = Syntax(`{ x: 1, y: 2, z: 3 }`) const S = Syntax({ T }, `T[keyof T]`) Assert.IsTrue(TypeGuard.IsUnion(S)) Assert.IsTrue(S.anyOf[0].const === 1) Assert.IsTrue(S.anyOf[1].const === 2) Assert.IsTrue(S.anyOf[2].const === 3) }) it('Should parse Indexed 4', () => { const T = Syntax(`['A', 'B', 'C']`) const S = Syntax({ T }, `T[number]`) Assert.IsTrue(TypeGuard.IsUnion(S)) Assert.IsTrue(S.anyOf[0].const === 'A') Assert.IsTrue(S.anyOf[1].const === 'B') Assert.IsTrue(S.anyOf[2].const === 'C') }) it('Should parse Integer', () => { const T = Syntax(`integer`) Assert.IsTrue(TypeGuard.IsInteger(T)) }) it('Should parse Intersect 1', () => { const T = Syntax(`1 & 2`) Assert.IsTrue(TypeGuard.IsIntersect(T)) Assert.IsTrue(T.allOf[0].const === 1) Assert.IsTrue(T.allOf[1].const === 2) }) it('Should parse Intersect 2', () => { const T = Syntax(`1 & (2 & 3)`) // expect flatten Assert.IsTrue(TypeGuard.IsIntersect(T)) Assert.IsTrue(T.allOf[0].const === 1) Assert.IsTrue(T.allOf[1].const === 2) Assert.IsTrue(T.allOf[2].const === 3) }) it('Should parse Intersect 3', () => { const T = Syntax(`(1 | 2) & 3`) // operator precedence Assert.IsTrue(TypeGuard.IsIntersect(T)) Assert.IsTrue(TypeGuard.IsUnion(T.allOf[0])) Assert.IsTrue(T.allOf[1].const === 3) }) it('Should parse InstanceType 1', () => { const T = Syntax(`InstanceType { x: 1, y: 2 }>`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(T.properties.x.const === 1) Assert.IsTrue(T.properties.y.const === 2) }) it('Should parse InstanceType 2', () => { const T = Syntax(`InstanceType`) // generalization issue Assert.IsTrue(TypeGuard.IsNever(T)) }) it('Should parse Iterator', () => { const T = Syntax(`Iterator`) Assert.IsTrue(TypeGuard.IsIterator(T)) Assert.IsTrue(TypeGuard.IsNumber(T.items)) }) it('Should parse KeyOf 1', () => { const T = Syntax(`keyof { x: 1, y: 2 }`) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsTrue(T.anyOf[0].const === 'x') Assert.IsTrue(T.anyOf[1].const === 'y') }) it('Should parse KeyOf 2', () => { const T = Syntax(`keyof [0, 1]`) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsTrue(T.anyOf[0].const === '0') Assert.IsTrue(T.anyOf[1].const === '1') }) it('Should parse KeyOf 3', () => { const T = Syntax(`{ x: 1, y: 2 }`) const S = Syntax({ T }, `keyof T`) Assert.IsTrue(TypeGuard.IsUnion(S)) Assert.IsTrue(S.anyOf[0].const === 'x') Assert.IsTrue(S.anyOf[1].const === 'y') }) it('Should parse Literal Boolean 1', () => { const T = Syntax(`true`) Assert.IsTrue(T.const === true) }) it('Should parse Literal Boolean 2', () => { const T = Syntax(`false`) Assert.IsTrue(T.const === false) }) it('Should parse Literal Number', () => { const T = Syntax(`1`) Assert.IsTrue(T.const === 1) }) it('Should parse Literal String', () => { const T = Syntax(`'1'`) Assert.IsTrue(T.const === '1') }) it('Should parse Mapped (Pending)', () => { const T = Syntax(`{ [K in 1 | 2 | 3]: K }`) Assert.IsTrue(T.const === 'Mapped types not supported') }) it('Should parse Never', () => { const T = Syntax(`never`) Assert.IsTrue(TypeGuard.IsNever(T)) }) it('Should parse Null', () => { const T = Syntax(`null`) Assert.IsTrue(TypeGuard.IsNull(T)) }) it('Should parse Number', () => { const T = Syntax(`number`) Assert.IsTrue(TypeGuard.IsNumber(T)) }) it('Should parse Object 1', () => { const T = Syntax(`{x: boolean, y: number, z: string, }`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x)) Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) Assert.IsTrue(TypeGuard.IsString(T.properties.z)) }) it('Should parse Object 2', () => { const T = Syntax(`{x: boolean; y: number; z: string; }`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x)) Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) Assert.IsTrue(TypeGuard.IsString(T.properties.z)) }) it('Should parse Object 3', () => { const T = Syntax(`{ x: boolean y: number z: string }`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x)) Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) Assert.IsTrue(TypeGuard.IsString(T.properties.z)) }) it('Should parse Object 4', () => { const T = Syntax(`{ x: boolean; y: number; z: string; }`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x)) Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) Assert.IsTrue(TypeGuard.IsString(T.properties.z)) }) it('Should parse Object 5', () => { const T = Syntax(`{ x: boolean, y: number, z: string, }`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x)) Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) Assert.IsTrue(TypeGuard.IsString(T.properties.z)) }) it('Should parse Omit 1', () => { const T = Syntax(`Omit<{ x: boolean, y: number, z: string }, 'z'>`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x)) Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) Assert.IsTrue(('z' in T.properties) === false) }) it('Should parse Omit 2', () => { const T = Syntax(`Omit<{ x: boolean, y: number, z: string }, 'z' | 'y'>`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x)) Assert.IsTrue(('y' in T.properties) === false) Assert.IsTrue(('z' in T.properties) === false) }) it('Should parse Parameters', () => { const T = Syntax(`Parameters<(a: number, b: string) => boolean>`) Assert.IsTrue(TypeGuard.IsTuple(T)) Assert.IsTrue(TypeGuard.IsNumber(T.items![0])) Assert.IsTrue(TypeGuard.IsString(T.items![1])) }) it('Should parse Partial', () => { const T = Syntax(`Partial<{ x: boolean, y: number, z: string }>`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(('required' in T) === false) }) it('Should parse Pick 1', () => { const T = Syntax(`Pick<{ x: boolean, y: number, z: string }, 'x' | 'y'>`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x)) Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) Assert.IsTrue(('z' in T.properties) === false) }) it('Should parse Pick 2', () => { const T = Syntax(`Pick<{ x: boolean, y: number, z: string }, 'x'>`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x)) Assert.IsTrue(('y' in T.properties) === false) Assert.IsTrue(('z' in T.properties) === false) }) it('Should parse Promise', () => { const T = Syntax(`Promise`) Assert.IsTrue(TypeGuard.IsPromise(T)) Assert.IsTrue(TypeGuard.IsNumber(T.item)) }) it('Should parse ReadonlyOptional', () => { const T = Syntax(`{ readonly x?: boolean, readonly y?: number }`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x)) Assert.IsTrue(TypeGuard.IsReadonly(T.properties.x)) Assert.IsTrue(TypeGuard.IsOptional(T.properties.x)) Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) Assert.IsTrue(TypeGuard.IsReadonly(T.properties.y)) Assert.IsTrue(TypeGuard.IsOptional(T.properties.y)) }) it('Should parse Readonly', () => { const T = Syntax(`{ readonly x: boolean, readonly y: number }`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x)) Assert.IsTrue(TypeGuard.IsReadonly(T.properties.x)) Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) Assert.IsTrue(TypeGuard.IsReadonly(T.properties.y)) }) it('Should parse Record 1', () => { const T = Syntax(`Record`) Assert.IsTrue(TypeGuard.IsRecord(T)) Assert.IsTrue(TypeGuard.IsNumber(T.patternProperties['^(.*)$'])) }) it('Should parse Record 2', () => { const T = Syntax(`Record`) Assert.IsTrue(TypeGuard.IsRecord(T)) Assert.IsTrue(TypeGuard.IsNumber(T.patternProperties['^(0|[1-9][0-9]*)$'])) }) it('Should parse Record 3', () => { const T = Syntax(`Record<'x' | 'y', number>`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsNumber(T.properties.x)) Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) }) it('Should parse Recursive', () => { const T = Type.Recursive(This => Syntax({ This }, `{ id: string, nodes: This[] }`)) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsString(T.properties.id)) Assert.IsTrue(TypeGuard.IsArray(T.properties.nodes)) Assert.IsTrue(TypeGuard.IsThis(T.properties.nodes.items)) }) it('Should parse Ref', () => { const T = Syntax('foo') Assert.IsTrue(TypeGuard.IsRef(T)) Assert.IsTrue(T.$ref === 'foo') }) it('Should parse Required', () => { const T = Syntax(`Required<{ x?: boolean, y?: number, z?: string }>`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsEqual(T.required, ['x', 'y', 'z']) }) it('Should parse ReturnType 1', () => { const T = Syntax(`ReturnType<() => { x: 1, y: 2 }>`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(T.properties.x.const === 1) Assert.IsTrue(T.properties.y.const === 2) }) it('Should parse ReturnType 2', () => { const T = Syntax(`ReturnType`) // generalization issue Assert.IsTrue(TypeGuard.IsNever(T)) }) it('Should parse String', () => { const T = Syntax(`string`) Assert.IsTrue(TypeGuard.IsString(T)) }) it('Should parse Symbol', () => { const T = Syntax(`symbol`) Assert.IsTrue(TypeGuard.IsSymbol(T)) }) it('Should parse Tuple', () => { const T = Syntax(`[0, 1, 2, 3]`) Assert.IsTrue(TypeGuard.IsTuple(T)) Assert.IsTrue(T.items![0].const === 0) Assert.IsTrue(T.items![1].const === 1) Assert.IsTrue(T.items![2].const === 2) Assert.IsTrue(T.items![3].const === 3) }) it('Should parse Uint8Array', () => { const T = Syntax(`Uint8Array`) Assert.IsTrue(TypeGuard.IsUint8Array(T)) }) it('Should parse Undefined', () => { const T = Syntax(`undefined`) Assert.IsTrue(TypeGuard.IsUndefined(T)) }) it('Should parse Union 1', () => { const T = Syntax(`1 | 2`) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsTrue(T.anyOf[0].const === 1) Assert.IsTrue(T.anyOf[1].const === 2) }) it('Should parse Union 2', () => { const T = Syntax(`1 | (2 | 3)`) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsTrue(T.anyOf[0].const === 1) Assert.IsTrue(T.anyOf[1].const === 2) Assert.IsTrue(T.anyOf[2].const === 3) }) it('Should parse Unknown', () => { const T = Syntax(`unknown`) Assert.IsTrue(TypeGuard.IsUnknown(T)) }) it('Should parse Void', () => { const T = Syntax(`void`) Assert.IsTrue(TypeGuard.IsVoid(T)) }) // ---------------------------------------------------------------- // Argument + Instantiation // ---------------------------------------------------------------- it('Should parse Argument 0', () => { const G = Syntax(`[Argument<0>]`) const T = Syntax({ G }, `G`) Assert.IsTrue(TypeGuard.IsTuple(T)) Assert.IsTrue(TypeGuard.IsArgument(T.items![0])) }) it('Should parse Argument 1', () => { const G = Syntax(`[Argument<0>]`) const T = Syntax({ G }, `G`) Assert.IsTrue(TypeGuard.IsTuple(T)) Assert.IsTrue(TypeGuard.IsNumber(T.items![0])) }) it('Should parse Argument 2', () => { const G = Syntax(`[Argument<0>, Argument<1>]`) const T = Syntax({ G }, `G`) Assert.IsTrue(TypeGuard.IsTuple(T)) Assert.IsTrue(TypeGuard.IsNumber(T.items![0])) Assert.IsTrue(TypeGuard.IsString(T.items![1])) }) it('Should parse Argument 3', () => { const G = Syntax(`[Argument<0>, Argument<1>]`) const T = Syntax({ G }, `G`) Assert.IsTrue(TypeGuard.IsTuple(T)) Assert.IsTrue(TypeGuard.IsNumber(T.items![0])) Assert.IsTrue(TypeGuard.IsUnknown(T.items![1])) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/system/000077500000000000000000000000001505437577000222465ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/system/index.ts000066400000000000000000000000561505437577000237260ustar00rootroot00000000000000import './policy/index' import './type/index' sinclairzx81-typebox-e0ec98c/test/runtime/system/policy/000077500000000000000000000000001505437577000235455ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/system/policy/allow-array-object.ts000066400000000000000000000044271505437577000276220ustar00rootroot00000000000000import { Ok, Fail } from '../../compiler/validate' import { TypeSystemPolicy } from '@sinclair/typebox/system' import { Type } from '@sinclair/typebox' describe('system/TypeSystemPolicy/AllowArrayObject', () => { beforeEach(() => { TypeSystemPolicy.AllowArrayObject = true }) afterEach(() => { TypeSystemPolicy.AllowArrayObject = false }) // --------------------------------------------------------------- // Object // --------------------------------------------------------------- it('Should validate arrays with empty objects', () => { const T = Type.Object({}) Ok(T, [0, 1, 2]) }) it('Should validate arrays with objects with length property', () => { const T = Type.Object({ length: Type.Number() }) Ok(T, [0, 1, 2]) }) it('Should validate arrays with objects with additionalProperties false when array has no elements', () => { const T = Type.Object({ length: Type.Number() }, { additionalProperties: false }) Ok(T, []) }) it('Should not validate arrays with objects with additionalProperties false when array has elements', () => { const T = Type.Object({ length: Type.Number() }, { additionalProperties: false }) Fail(T, [0, 1, 2]) }) it('Should not validate arrays with objects when length property is string', () => { const T = Type.Object({ length: Type.String() }) Fail(T, [0, 1, 2]) }) // --------------------------------------------------------------- // Record // --------------------------------------------------------------- it('Should validate arrays as Records with String Keys', () => { const T = Type.Record(Type.String(), Type.Number()) Ok(T, [0, 1, 2]) }) it('Should validate arrays as Records with Number Keys', () => { const T = Type.Record(Type.Number(), Type.Number()) Ok(T, [0, 1, 2]) }) it('Should validate arrays as Records with Integer Keys', () => { const T = Type.Record(Type.Integer(), Type.Number()) Ok(T, [0, 1, 2]) }) it('Should not validate arrays as Records with Object Values', () => { const T = Type.Record( Type.String(), Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }), ) Ok(T, [ { x: 1, y: 1, z: 1 }, { x: 1, y: 1, z: 1 }, { x: 1, y: 1, z: 1 }, ]) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/system/policy/allow-nan.ts000066400000000000000000000036561505437577000260170ustar00rootroot00000000000000import { Ok, Fail } from '../../compiler/validate' import { TypeSystemPolicy } from '@sinclair/typebox/system' import { Type } from '@sinclair/typebox' describe('system/TypeSystemPolicy/AllowNaN', () => { beforeEach(() => { TypeSystemPolicy.AllowNaN = true }) afterEach(() => { TypeSystemPolicy.AllowNaN = false }) // --------------------------------------------------------------- // Number // --------------------------------------------------------------- it('Should validate number with NaN', () => { const T = Type.Number() Ok(T, NaN) }) it('Should validate number with +Infinity', () => { const T = Type.Number() Ok(T, Infinity) }) it('Should validate number with -Infinity', () => { const T = Type.Number() Ok(T, -Infinity) }) // --------------------------------------------------------------- // Integer // // Note: The Number.isInteger() test will fail for NaN. Because // of this we cannot reasonably override NaN handling for integers. // --------------------------------------------------------------- it('Should not validate integer with NaN', () => { const T = Type.Integer() Fail(T, NaN) }) it('Should not validate integer with +Infinity', () => { const T = Type.Integer() Fail(T, Infinity) }) it('Should not validate integer with -Infinity', () => { const T = Type.Integer() Fail(T, -Infinity) }) // --------------------------------------------------------------- // BigInt // // Note: We expect failures here as bigint isn't IEEE754 // --------------------------------------------------------------- it('Should not validate bigint with NaN', () => { const T = Type.BigInt() Fail(T, NaN) }) it('Should not validate bigint with +Infinity', () => { const T = Type.BigInt() Fail(T, Infinity) }) it('Should not validate bigint with -Infinity', () => { const T = Type.BigInt() Fail(T, -Infinity) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/system/policy/allow-null-void.ts000066400000000000000000000015441505437577000271460ustar00rootroot00000000000000import { Ok } from '../../compiler/validate' import { TypeSystemPolicy } from '@sinclair/typebox/system' import { Type } from '@sinclair/typebox' describe('system/TypeSystemPolicy/AllowNullVoid', () => { beforeEach(() => { TypeSystemPolicy.AllowNullVoid = true }) afterEach(() => { TypeSystemPolicy.AllowNullVoid = false }) // --------------------------------------------------------------- // Object // --------------------------------------------------------------- it('Should validate with null', () => { const T = Type.Void() Ok(T, null) }) it('Should validate with undefined', () => { const T = Type.Void() Ok(T, undefined) }) it('Should validate with void 0', () => { const T = Type.Void() Ok(T, void 0) }) it('Should validate with void 1', () => { const T = Type.Void() Ok(T, void 1) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/system/policy/exact-optional-property-types.ts000066400000000000000000000022071505437577000320710ustar00rootroot00000000000000import { Ok, Fail } from '../../compiler/validate' import { TypeSystemPolicy } from '@sinclair/typebox/system' import { Type } from '@sinclair/typebox' describe('system/TypeSystemPolicy/ExactOptionalPropertyTypes', () => { beforeEach(() => { TypeSystemPolicy.ExactOptionalPropertyTypes = true }) afterEach(() => { TypeSystemPolicy.ExactOptionalPropertyTypes = false }) // --------------------------------------------------------------- // Number // --------------------------------------------------------------- it('Should not validate optional number', () => { const T = Type.Object({ x: Type.Optional(Type.Number()), }) Ok(T, {}) Ok(T, { x: 1 }) Fail(T, { x: undefined }) }) it('Should not validate undefined', () => { const T = Type.Object({ x: Type.Optional(Type.Undefined()), }) Ok(T, {}) Fail(T, { x: 1 }) Ok(T, { x: undefined }) }) it('Should validate optional number | undefined', () => { const T = Type.Object({ x: Type.Optional(Type.Union([Type.Number(), Type.Undefined()])), }) Ok(T, {}) Ok(T, { x: 1 }) Ok(T, { x: undefined }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/system/policy/index.ts000066400000000000000000000002201505437577000252160ustar00rootroot00000000000000import './allow-array-object' import './allow-nan' import './allow-null-void' import './exact-optional-property-types' import './instance-mode' sinclairzx81-typebox-e0ec98c/test/runtime/system/policy/instance-mode.ts000066400000000000000000000020631505437577000266440ustar00rootroot00000000000000import { TypeSystemPolicy } from '@sinclair/typebox/system' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('system/TypeSystemPolicy/InstanceMode', () => { after(() => { TypeSystemPolicy.InstanceMode = 'freeze' }) // --------------------------------------------------------------- // Number // --------------------------------------------------------------- it('Should use instance mode default', () => { TypeSystemPolicy.InstanceMode = 'default' const S = Type.String() const T = Type.Array(S) S.$id = 'updated' Assert.IsEqual(T.items.$id, 'updated') }) it('Should use instance mode clone', () => { TypeSystemPolicy.InstanceMode = 'clone' const S = Type.String() const T = Type.Array(S) S.$id = 'updated' Assert.IsEqual(T.items.$id, undefined) }) it('Should use instance mode freeze', () => { TypeSystemPolicy.InstanceMode = 'freeze' Assert.Throws(() => { const S = Type.String() const T = Type.Array(S) S.$id = 'updated' }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/system/type/000077500000000000000000000000001505437577000232275ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/system/type/format.ts000066400000000000000000000012721505437577000250710ustar00rootroot00000000000000import { Ok, Fail } from '../../compiler/validate' import { Assert } from '../../assert/index' import { TypeSystem } from '@sinclair/typebox/system' import { Type, FormatRegistry } from '@sinclair/typebox' describe('system/TypeSystem/Format', () => { it('Should create and validate a format', () => { const Foo = TypeSystem.Format('Foo', (value) => value === 'foo') const T = Type.String({ format: Foo }) Ok(T, 'foo') Fail(T, 'bar') FormatRegistry.Delete('Foo') }) it('Should throw if registering the same type twice', () => { TypeSystem.Format('Foo', () => true) Assert.Throws(() => TypeSystem.Format('Foo', () => true)) FormatRegistry.Delete('Foo') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/system/type/index.ts000066400000000000000000000000421505437577000247020ustar00rootroot00000000000000import './format' import './type' sinclairzx81-typebox-e0ec98c/test/runtime/system/type/type.ts000066400000000000000000000013621505437577000245620ustar00rootroot00000000000000import { Ok, Fail } from '../../compiler/validate' import { TypeSystem } from '@sinclair/typebox/system' import { TypeRegistry } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('system/TypeSystem/Type', () => { it('Should create and validate a type', () => { const Foo = TypeSystem.Type('Foo', (options, value) => { Assert.IsEqual(options.option, 'test') return value === 'foo' }) const T = Foo({ option: 'test' }) Ok(T, 'foo') Fail(T, 'bar') TypeRegistry.Delete('Foo') }) it('Should throw if registering the same type twice', () => { TypeSystem.Type('Foo', () => true) Assert.Throws(() => TypeSystem.Type('Foo', () => true)) TypeRegistry.Delete('Foo') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/000077500000000000000000000000001505437577000217035ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/type/clone/000077500000000000000000000000001505437577000230035ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/type/clone/clone.ts000066400000000000000000000131371505437577000244600ustar00rootroot00000000000000// -------------------------------------------------------------------- // $id deletion was omitted from 0.26.0 to reduce complexity overhead. // -------------------------------------------------------------------- // import { Type } from '@sinclair/typebox' // import { Assert } from '../../assert' // describe('type/Clone', () => { // it('Should retain source type $id for cloned objects', () => { // const S = Type.String({ $id: 'S' }) // const T = Type.Object({ x: S, y: S }) // Assert.equal(T.properties.x.$id, undefined) // Assert.equal(T.properties.y.$id, undefined) // Assert.equal(S.$id, 'S') // }) // it('Should retain source type $id when composing objects with cloned arrays', () => { // const S = Type.String({ $id: 'S' }) // const T = Type.Function([S], S) // Assert.equal(S.$id, 'S') // }) // it('Should remove cloned $id for Array', () => { // const S = Type.String({ $id: 'S' }) // const T = Type.Array(S) // Assert.equal(T.items.$id, undefined) // Assert.equal(S.$id, 'S') // }) // it('Should remove cloned $id for Composite', () => { // const S = Type.String({ $id: 'S' }) // const T = Type.Composite([Type.Object({ a: S }), Type.Object({ b: S })]) // Assert.equal(T.properties.a.$id, undefined) // Assert.equal(T.properties.b.$id, undefined) // Assert.equal(S.$id, 'S') // }) // it('Should remove cloned $id for Constructor', () => { // const S = Type.String({ $id: 'S' }) // const T = Type.Constructor([S], S) // Assert.equal(T.parameters[0].$id, undefined) // Assert.equal(T.returns.$id, undefined) // Assert.equal(S.$id, 'S') // }) // it('Should remove cloned $id for Function', () => { // const S = Type.String({ $id: 'S' }) // const T = Type.Function([S], S) // Assert.equal(T.parameters[0].$id, undefined) // Assert.equal(T.returns.$id, undefined) // Assert.equal(S.$id, 'S') // }) // it('Should remove cloned $id for Intersect', () => { // const S = Type.String({ $id: 'S' }) // const T = Type.Intersect([S, S]) // Assert.equal(T.allOf[0].$id, undefined) // Assert.equal(T.allOf[1].$id, undefined) // Assert.equal(S.$id, 'S') // }) // it('Should remove cloned $id for Intersect with unevaluatedProperties', () => { // const S = Type.String({ $id: 'S' }) // const T = Type.Intersect([S, S], { unevaluatedProperties: S }) // // @ts-ignore // Assert.equal(T.unevaluatedProperties.$id, undefined) // Assert.equal(S.$id, 'S') // }) // it('Should remove cloned $id for Not', () => { // const S = Type.String({ $id: 'S' }) // const T = Type.Not(S, S) // Assert.equal(T.allOf[0].not.$id, undefined) // Assert.equal(T.allOf[1].$id, undefined) // Assert.equal(S.$id, 'S') // }) // it('Should remove cloned $id for Object', () => { // const S = Type.String({ $id: 'S' }) // const T = Type.Object({ x: S, y: S }) // Assert.equal(T.properties.x.$id, undefined) // Assert.equal(T.properties.y.$id, undefined) // Assert.equal(S.$id, 'S') // }) // it('Should remove cloned $id for nested Object', () => { // const S = Type.String({ $id: 'S' }) // const N = Type.Object({ s: S }, { $id: 'N' }) // const T = Type.Object({ x: S, y: S, z: N }) // Assert.equal(T.properties.x.$id, undefined) // Assert.equal(T.properties.y.$id, undefined) // Assert.equal(T.properties.z.$id, undefined) // Assert.equal(T.properties.z.properties.s.$id, undefined) // Assert.equal(S.$id, 'S') // }) // it('Should remove cloned $id for Object additionalProperties', () => { // const S = Type.String({ $id: 'S' }) // const T = Type.Object({}, { additionalProperties: S }) // // @ts-ignore // Assert.equal(T.additionalProperties!.$id, undefined) // Assert.equal(S.$id, 'S') // }) // it('Should remove cloned $id for Promise', () => { // const S = Type.String({ $id: 'S' }) // const T = Type.Promise(S) // Assert.equal(T.item.$id, undefined) // Assert.equal(S.$id, 'S') // }) // it('Should remove cloned $id for Record', () => { // const S = Type.String({ $id: 'S' }) // const T = Type.Record(Type.String(), S) // Assert.equal(T.patternProperties['^.*$'].$id, undefined) // Assert.equal(S.$id, 'S') // }) // it('Should remove cloned $id for Tuple', () => { // const S = Type.String({ $id: 'S' }) // const T = Type.Tuple([S, S]) // Assert.equal(T.items![0]!.$id, undefined) // Assert.equal(T.items![1]!.$id, undefined) // Assert.equal(S.$id, 'S') // }) // it('Should remove cloned $id for Union', () => { // const S = Type.String({ $id: 'S' }) // const T = Type.Union([S, S]) // Assert.equal(T.anyOf[0]!.$id, undefined) // Assert.equal(T.anyOf[1]!.$id, undefined) // Assert.equal(S.$id, 'S') // }) // it('Should retain cloned $id for wrapped Recursive 1', () => { // const S = Type.String({ $id: 'S' }) // const T = Type.Object({ // x: Type.Recursive( // (Self) => // Type.Object({ // self: Type.Optional(Self), // }), // { $id: 'RecursiveClone' }, // ), // }) // Assert.equal(T.properties.x.$id, 'RecursiveClone') // Assert.equal(S.$id, 'S') // }) // it('Should retain cloned $id for wrapped Recursive 2', () => { // const S = Type.String({ $id: 'S' }) // const T = Type.Tuple([ // Type.Recursive( // (Self) => // Type.Object({ // self: Type.Optional(Self), // }), // { $id: 'RecursiveClone' }, // ), // ]) // Assert.equal(T.items![0].$id, 'RecursiveClone') // Assert.equal(S.$id, 'S') // }) // }) sinclairzx81-typebox-e0ec98c/test/runtime/type/clone/index.ts000066400000000000000000000000211505437577000244530ustar00rootroot00000000000000import './clone' sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/000077500000000000000000000000001505437577000233555ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/any.ts000066400000000000000000000067251505437577000245260ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/Any', () => { it('Should extend Any', () => { type T = any extends any ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Unknown', () => { type T = any extends unknown ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = any extends string ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.String()) Assert.IsEqual(R, ExtendsResult.Union) }) it('Should extend Boolean', () => { type T = any extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.Union) }) it('Should extend Number', () => { type T = any extends number ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.Number()) Assert.IsEqual(R, ExtendsResult.Union) }) it('Should extend Integer', () => { type T = any extends number ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.Integer()) Assert.IsEqual(R, ExtendsResult.Union) }) it('Should extend Array 1', () => { type T = any extends Array ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.Union) }) it('Should extend Array 2', () => { type T = any extends Array ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.Array(Type.String())) Assert.IsEqual(R, ExtendsResult.Union) }) it('Should extend Tuple', () => { type T = any extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.Union) }) it('Should extend Object 1', () => { type T = any extends object ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.Object({})) Assert.IsEqual(R, ExtendsResult.Union) }) it('Should extend Object 2', () => { type T = any extends {} ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.Object({})) Assert.IsEqual(R, ExtendsResult.Union) }) it('Should extend Object 3', () => { type T = any extends { a: number } ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.Object({ a: Type.Number() })) Assert.IsEqual(R, ExtendsResult.Union) }) it('Should extend Union 1', () => { type T = any extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.Union) }) it('Should extend Union 2', () => { type T = any extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.Union([Type.Any(), Type.String()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Null', () => { type T = any extends null ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.Null()) Assert.IsEqual(R, ExtendsResult.Union) }) it('Should extend Undefined', () => { type T = any extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.Union) }) it('Should extend Void', () => { type T = any extends void ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.Void()) Assert.IsEqual(R, ExtendsResult.Union) }) it('Should extend Date', () => { type T = any extends Date ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.Date()) Assert.IsEqual(R, ExtendsResult.Union) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/array.ts000066400000000000000000000267431505437577000250570ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/Array', () => { // ---------------------------------------------- // Generic Varying // ---------------------------------------------- it('Should extend Array Varying 1', () => { type T = Array extends Array ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Any()), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Array Varying 2', () => { type T = Array extends Array ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Array Varying 3', () => { type T = Array extends Array ? 1 : 2 // 1 const R = ExtendsCheck(Type.Array(Type.Any()), Type.Array(Type.String())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Array Varying 4', () => { type T = Array extends Array ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Number()), Type.Array(Type.String())) Assert.IsEqual(R, ExtendsResult.False) }) // ---------------------------------------------- // Any // ---------------------------------------------- it('Should extend Any', () => { type T = Array extends any ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Any()), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Unknown', () => { type T = Array extends unknown ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Any()), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = Array extends string ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Any()), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Boolean', () => { type T = Array extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Any()), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number', () => { type T = Array extends number ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Any()), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer', () => { type T = Array extends number ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Any()), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array 1', () => { type T = Array extends Array ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Any()), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Array 2', () => { type T = Array extends Array ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Any()), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Array 3', () => { type T = Array extends Array ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Any()), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Tuple', () => { type T = Array extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Any()), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1', () => { type T = Array extends object ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Any()), Type.Object({})) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 2', () => { type T = Array extends {} ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Any()), Type.Object({})) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 3', () => { type T = Array extends { a: number } ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Any()), Type.Object({ a: Type.Number() })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 4', () => { type T = Array extends { length: '1' } ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Any()), Type.Object({ length: Type.Literal('1') })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 5', () => { type T = Array extends { length: number } ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Any()), Type.Object({ length: Type.Number() })) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 1', () => { type T = Array extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Any()), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 2', () => { type T = Array extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Any()), Type.Union([Type.Any(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 3', () => { type T = Array extends any | Array ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Any()), Type.Union([Type.Any(), Type.Array(Type.Any())])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 4', () => { type T = Array extends any | Array ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Union([Type.Any(), Type.Array(Type.Any())])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 5', () => { type T = Array extends any | Array ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Any()), Type.Union([Type.Any(), Type.Array(Type.String())])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Null', () => { type T = Array extends null ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Any()), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined', () => { type T = Array extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.Any()), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) // ---------------------------------------------- // Constrained // ---------------------------------------------- it('Should extend constrained Any', () => { type T = Array extends any ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend constrained Unknown', () => { type T = Array extends unknown ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend constrained String', () => { type T = Array extends string ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend constrained Boolean', () => { type T = Array extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend constrained Number', () => { type T = Array extends number ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend constrained Integer', () => { type T = Array extends number ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend constrained Array 1', () => { type T = Array extends Array ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend constrained Array 2', () => { type T = Array extends Array ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend constrained Array 3', () => { type T = Array extends Array ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend constrained Tuple', () => { type T = Array extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend constrained Object 1', () => { type T = Array extends object ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Object({})) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend constrained Object 2', () => { type T = Array extends {} ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Object({})) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend constrained Object 3', () => { type T = Array extends { a: number } ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Object({ a: Type.Number() })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend constrained Object 4', () => { type T = Array extends { length: '1' } ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Object({ length: Type.Literal('1') })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend constrained Object 5', () => { type T = Array extends { length: number } ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Object({ length: Type.Number() })) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend constrained Union 1', () => { type T = Array extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Union([Type.Null(), Type.String()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend constrained Union 2', () => { type T = Array extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Union([Type.Any(), Type.String()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend constrained Union 3', () => { type T = Array extends any | Array ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Union([Type.Any(), Type.Array(Type.Any())])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend constrained Union 4', () => { type T = Array extends any | Array ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Union([Type.Any(), Type.Array(Type.Any())])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend constrained Union 5', () => { type T = Array extends any | Array ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Union([Type.Any(), Type.Array(Type.String())])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend constrained Null', () => { type T = Array extends null ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend constrained Undefined', () => { type T = Array extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend constrained Void', () => { type T = Array extends void ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Void()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Date', () => { type T = Array extends Date ? 1 : 2 const R = ExtendsCheck(Type.Array(Type.String()), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/async-iterator.ts000066400000000000000000000070141505437577000266730ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/AsyncIterator', () => { // ---------------------------------------------- // Generic Varying // ---------------------------------------------- it('Should extend AsyncIterator 1', () => { type T = AsyncIterableIterator extends AsyncIterableIterator ? 1 : 2 const R = ExtendsCheck(Type.AsyncIterator(Type.Any()), Type.AsyncIterator(Type.Any())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend AsyncIterator 2', () => { type T = AsyncIterableIterator extends AsyncIterableIterator ? 1 : 2 const R = ExtendsCheck(Type.AsyncIterator(Type.String()), Type.AsyncIterator(Type.String())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend AsyncIterator 3', () => { type T = AsyncIterableIterator<'hello'> extends AsyncIterableIterator ? 1 : 2 const R = ExtendsCheck(Type.AsyncIterator(Type.Literal('hello')), Type.AsyncIterator(Type.String())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend AsyncIterator 4', () => { type T = AsyncIterableIterator extends AsyncIterableIterator<'hello'> ? 1 : 2 const R = ExtendsCheck(Type.AsyncIterator(Type.String()), Type.AsyncIterator(Type.Literal('hello'))) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend AsyncIterator 5', () => { type T = AsyncIterableIterator extends AsyncIterableIterator<'hello' | number> ? 1 : 2 const R = ExtendsCheck(Type.AsyncIterator(Type.String()), Type.AsyncIterator(Type.Union([Type.Literal('hello'), Type.Number()]))) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend AsyncIterator 6', () => { type T = AsyncIterableIterator<'hello' | number> extends AsyncIterableIterator ? 1 : 2 const R = ExtendsCheck(Type.AsyncIterator(Type.Union([Type.Literal('hello'), Type.Number()])), Type.AsyncIterator(Type.String())) Assert.IsEqual(R, ExtendsResult.False) }) // -------------------------------------------------------------------- // Structural // -------------------------------------------------------------------- it('Should extends Any 1', () => { type T = AsyncIterableIterator extends any ? 1 : 2 const R = ExtendsCheck(Type.AsyncIterator(Type.Number()), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extends Any 2', () => { type T = any extends AsyncIterableIterator ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.AsyncIterator(Type.Number())) Assert.IsEqual(R, ExtendsResult.Union) }) it('Should extends Unknown 1', () => { type T = AsyncIterableIterator extends unknown ? 1 : 2 const R = ExtendsCheck(Type.AsyncIterator(Type.Number()), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extends Unknown 2', () => { type T = unknown extends AsyncIterableIterator ? 1 : 2 const R = ExtendsCheck(Type.Unknown(), Type.AsyncIterator(Type.Number())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extends Never 1', () => { type T = AsyncIterableIterator extends never ? 1 : 2 const R = ExtendsCheck(Type.AsyncIterator(Type.Number()), Type.Never()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extends Never 2', () => { type T = never extends AsyncIterableIterator ? 1 : 2 const R = ExtendsCheck(Type.Never(), Type.AsyncIterator(Type.Number())) Assert.IsEqual(R, ExtendsResult.True) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/bigint.ts000066400000000000000000000075351505437577000252130ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/BigInt', () => { it('Should extend Any', () => { type T = bigint extends any ? 1 : 2 const R = ExtendsCheck(Type.BigInt(), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Unknown', () => { type T = bigint extends unknown ? 1 : 2 const R = ExtendsCheck(Type.BigInt(), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = bigint extends string ? 1 : 2 const R = ExtendsCheck(Type.BigInt(), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Boolean', () => { type T = bigint extends boolean ? 1 : 2 const R = ExtendsCheck(Type.BigInt(), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number', () => { type T = bigint extends number ? 1 : 2 const R = ExtendsCheck(Type.BigInt(), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer', () => { type T = bigint extends number ? 1 : 2 const R = ExtendsCheck(Type.BigInt(), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array', () => { type T = bigint extends Array ? 1 : 2 const R = ExtendsCheck(Type.BigInt(), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple', () => { type T = bigint extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.BigInt(), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Record', () => { type T = bigint extends Record ? 1 : 2 const R = ExtendsCheck(Type.BigInt(), Type.Record(Type.Number(), Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1', () => { type T = bigint extends {} ? 1 : 2 const R = ExtendsCheck(Type.BigInt(), Type.Object({})) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 2', () => { type T = bigint extends { a: 10 } ? 1 : 2 const R = ExtendsCheck(Type.BigInt(), Type.Object({ a: Type.Literal(10) })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 1', () => { type T = bigint extends number | string ? 1 : 2 const R = ExtendsCheck(Type.BigInt(), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 2', () => { type T = bigint extends any | number ? 1 : 2 const R = ExtendsCheck(Type.BigInt(), Type.Union([Type.Any(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 3', () => { type T = bigint extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.BigInt(), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 4', () => { type T = bigint extends boolean | bigint ? 1 : 2 const R = ExtendsCheck(Type.BigInt(), Type.Union([Type.Boolean(), Type.BigInt()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Null', () => { type T = bigint extends null ? 1 : 2 const R = ExtendsCheck(Type.BigInt(), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined', () => { type T = bigint extends undefined ? 1 : 2 const R = ExtendsCheck(Type.BigInt(), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Void', () => { type T = bigint extends undefined ? 1 : 2 const R = ExtendsCheck(Type.BigInt(), Type.Void()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Date', () => { type T = bigint extends Date ? 1 : 2 const R = ExtendsCheck(Type.BigInt(), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/boolean.ts000066400000000000000000000070351505437577000253510ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/Boolean', () => { it('Should extend Any', () => { type T = boolean extends any ? 1 : 2 const R = ExtendsCheck(Type.Boolean(), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = boolean extends string ? 1 : 2 const R = ExtendsCheck(Type.Boolean(), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Boolean', () => { type T = boolean extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Boolean(), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Number', () => { type T = boolean extends number ? 1 : 2 const R = ExtendsCheck(Type.Boolean(), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer', () => { type T = boolean extends number ? 1 : 2 const R = ExtendsCheck(Type.Boolean(), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array', () => { type T = boolean extends Array ? 1 : 2 const R = ExtendsCheck(Type.Boolean(), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple', () => { type T = boolean extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Boolean(), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Record', () => { type T = boolean extends Record ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Record(Type.Number(), Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1', () => { type T = boolean extends {} ? 1 : 2 const R = ExtendsCheck(Type.Boolean(), Type.Object({}, { additionalProperties: false })) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 2', () => { type T = boolean extends { a: 10 } ? 1 : 2 const R = ExtendsCheck(Type.Boolean(), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 1', () => { type T = boolean extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Boolean(), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 2', () => { type T = boolean extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Boolean(), Type.Union([Type.Any(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 2', () => { type T = boolean extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Boolean(), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Null', () => { type T = boolean extends null ? 1 : 2 const R = ExtendsCheck(Type.Boolean(), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined', () => { type T = boolean extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Boolean(), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Void', () => { type T = boolean extends void ? 1 : 2 const R = ExtendsCheck(Type.Boolean(), Type.Void()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Date', () => { type T = boolean extends Date ? 1 : 2 const R = ExtendsCheck(Type.Boolean(), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/constructor.ts000066400000000000000000000246141505437577000263210ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/Constructor', () => { it('Should extend Function', () => { type T = (new () => number) extends () => number ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Function([], Type.Number())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Constructor 1', () => { type T = (new () => number) extends new () => number ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Constructor([], Type.Number())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Constructor 2', () => { type T = (new () => any) extends new () => number ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Any()), Type.Constructor([], Type.Number())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Constructor 3', () => { type T = (new () => number) extends new () => any ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Any()), Type.Constructor([], Type.Number())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Constructor 4', () => { type T = (new (a: number) => number) extends new () => any ? 1 : 2 const R = ExtendsCheck(Type.Constructor([Type.Number()], Type.Number()), Type.Constructor([], Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Constructor 5', () => { type T = (new (a: number | string) => number) extends new (a: number) => number ? 1 : 2 const R = ExtendsCheck(Type.Constructor([Type.Union([Type.Number(), Type.String()])], Type.Number()), Type.Constructor([Type.Number()], Type.Any())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Constructor 6', () => { type T = (new (a: number) => number) extends new (a: number | string) => any ? 1 : 2 const R = ExtendsCheck(Type.Constructor([Type.Number()], Type.Number()), Type.Constructor([Type.Union([Type.Number(), Type.String()])], Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Constructor 7', () => { type T = (new (a: number, b: number) => number) extends new (a: number) => number ? 1 : 2 const R = ExtendsCheck(Type.Constructor([Type.Number(), Type.Number()], Type.Number()), Type.Constructor([Type.Number()], Type.Number())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Constructor 8', () => { type T = (new (a: number) => number) extends new (a: number, b: number) => number ? 1 : 2 const R = ExtendsCheck(Type.Constructor([Type.Number()], Type.Number()), Type.Constructor([Type.Number(), Type.Number()], Type.Number())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Constructor 9', () => { type T = (new () => number) extends new () => any ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Constructor([], Type.Any())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Constructor 9', () => { type T = (new () => any) extends new () => number ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Any()), Type.Constructor([], Type.Number())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Constructor 10', () => { type T = (new () => Array) extends new () => object ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Array(Type.Any())), Type.Constructor([], Type.Object({}))) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Constructor 11', () => { type T = (new () => Array) extends new () => object ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Array(Type.String())), Type.Constructor([], Type.Object({}))) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Constructor 12', () => { type T = (new () => object) extends new () => Array ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Object({})), Type.Constructor([], Type.Array(Type.Any()))) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Constructor 13', () => { type T = (new (a: unknown) => number) extends new (a: any) => number ? 1 : 2 const R = ExtendsCheck(Type.Constructor([Type.Unknown()], Type.Number({})), Type.Constructor([Type.Any()], Type.Number({}))) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Constructor 14', () => { type T = (new (a: any) => number) extends new (a: unknown) => number ? 1 : 2 const R = ExtendsCheck(Type.Constructor([Type.Any()], Type.Number({})), Type.Constructor([Type.Unknown()], Type.Number({}))) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Constructor 15', () => { type T = (new () => any) extends new () => unknown ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Any({})), Type.Constructor([], Type.Unknown({}))) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Constructor 16', () => { type T = (new () => unknown) extends new () => any ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Unknown({})), Type.Constructor([], Type.Any({}))) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Any', () => { type T = (new () => number) extends any ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = (new () => number) extends string ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Boolean', () => { type T = (new () => number) extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number', () => { type T = (new () => number) extends number ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer', () => { type T = (new () => number) extends number ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array 1', () => { type T = (new () => number) extends Array ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array 2', () => { type T = (new () => number) extends Array ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array 3', () => { type T = (new () => number) extends Array ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple', () => { type T = (new () => number) extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Record', () => { type T = (() => number) extends Record ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Record(Type.Number(), Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1', () => { type T = (new () => number) extends object ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Object({})) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 2', () => { type T = (new () => number) extends {} ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Object({})) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 3', () => { type T = (new () => number) extends { a: number } ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Object({ a: Type.Number() })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 4', () => { type T = (new () => number) extends { length: '1' } ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Object({ length: Type.Literal('1') })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 1', () => { type T = (new () => number) extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Union([Type.Null(), Type.String()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 2', () => { type T = (new () => number) extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Union([Type.Any(), Type.String()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 3', () => { type T = (new () => number) extends any | Array ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Union([Type.Any(), Type.Array(Type.Any())])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 4', () => { type T = (new () => number) extends any | Array ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Union([Type.Any(), Type.Array(Type.Any())])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 5', () => { type T = (new () => number) extends any | Array ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Union([Type.Any(), Type.Array(Type.String())])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Null', () => { type T = (new () => number) extends null ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined', () => { type T = (new () => number) extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Void', () => { type T = (new () => number) extends void ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Void()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Date', () => { type T = (new () => number) extends Date ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/date.ts000066400000000000000000000071141505437577000246450ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/Date', () => { it('Should extend Any', () => { type T = Date extends any ? 1 : 2 const R = ExtendsCheck(Type.Date(), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Unknown', () => { type T = Date extends unknown ? 1 : 2 const R = ExtendsCheck(Type.Date(), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = Date extends string ? 1 : 2 const R = ExtendsCheck(Type.Date(), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Boolean', () => { type T = Date extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Date(), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number', () => { type T = Date extends number ? 1 : 2 const R = ExtendsCheck(Type.Date(), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer', () => { type T = Date extends number ? 1 : 2 const R = ExtendsCheck(Type.Date(), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array', () => { type T = Date extends Array ? 1 : 2 const R = ExtendsCheck(Type.Date(), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple', () => { type T = Date extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Date(), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Record', () => { type T = Date extends Record ? 1 : 2 const R = ExtendsCheck(Type.Date(), Type.Record(Type.Number(), Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1', () => { type T = Date extends {} ? 1 : 2 const R = ExtendsCheck(Type.Date(), Type.Object({})) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 2', () => { type T = Date extends { a: 10 } ? 1 : 2 const R = ExtendsCheck(Type.Date(), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 1', () => { type T = Date extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Date(), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 2', () => { type T = Date extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Date(), Type.Union([Type.Any(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 3', () => { type T = Date extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Date(), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Null', () => { type T = Date extends null ? 1 : 2 const R = ExtendsCheck(Type.Date(), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined', () => { type T = Date extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Date(), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Void', () => { type T = Date extends void ? 1 : 2 const R = ExtendsCheck(Type.Date(), Type.Void()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Date', () => { type T = Date extends Date ? 1 : 2 const R = ExtendsCheck(Type.Date(), Type.Date()) Assert.IsEqual(R, ExtendsResult.True) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/function.ts000066400000000000000000000237651505437577000255670ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/Function', () => { it('Should extend Constructor 1', () => { type T = (() => number) extends new () => number ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Constructor([], Type.Number())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Function 1', () => { type T = (() => number) extends () => number ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Function([], Type.Number())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Function 2', () => { type T = (() => any) extends () => number ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Any()), Type.Function([], Type.Number())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Function 3', () => { type T = (() => number) extends () => any ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Any()), Type.Function([], Type.Number())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Function 4', () => { type T = ((a: number) => number) extends () => any ? 1 : 2 const R = ExtendsCheck(Type.Function([Type.Number()], Type.Number()), Type.Function([], Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Function 5', () => { type T = ((a: number | string) => number) extends (a: number) => number ? 1 : 2 const R = ExtendsCheck(Type.Function([Type.Union([Type.Number(), Type.String()])], Type.Number()), Type.Function([Type.Number()], Type.Any())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Function 6', () => { type T = ((a: number) => number) extends (a: number | string) => any ? 1 : 2 const R = ExtendsCheck(Type.Function([Type.Number()], Type.Number()), Type.Function([Type.Union([Type.Number(), Type.String()])], Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Function 7', () => { type T = ((a: number, b: number) => number) extends (a: number) => number ? 1 : 2 const R = ExtendsCheck(Type.Function([Type.Number(), Type.Number()], Type.Number()), Type.Function([Type.Number()], Type.Number())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Function 8', () => { type T = ((a: number) => number) extends (a: number, b: number) => number ? 1 : 2 const R = ExtendsCheck(Type.Function([Type.Number()], Type.Number()), Type.Function([Type.Number(), Type.Number()], Type.Number())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Function 9', () => { type T = (() => number) extends () => any ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Function([], Type.Any())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Function 9', () => { type T = (() => any) extends () => number ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Any()), Type.Function([], Type.Number())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Function 10', () => { type T = (() => Array) extends () => object ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Array(Type.Any())), Type.Function([], Type.Object({}))) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Function 11', () => { type T = (() => Array) extends () => object ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Array(Type.String())), Type.Function([], Type.Object({}))) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Function 12', () => { type T = (() => object) extends () => Array ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Object({})), Type.Function([], Type.Array(Type.Any()))) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Function 13', () => { type T = ((a: unknown) => number) extends (a: any) => number ? 1 : 2 const R = ExtendsCheck(Type.Function([Type.Unknown()], Type.Number({})), Type.Function([Type.Any()], Type.Number({}))) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Function 14', () => { type T = ((a: any) => number) extends (a: unknown) => number ? 1 : 2 const R = ExtendsCheck(Type.Function([Type.Any()], Type.Number({})), Type.Function([Type.Unknown()], Type.Number({}))) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Function 15', () => { type T = (() => any) extends () => unknown ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Any({})), Type.Function([], Type.Unknown({}))) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Function 16', () => { type T = (() => unknown) extends () => any ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Unknown({})), Type.Function([], Type.Any({}))) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Any', () => { type T = (() => number) extends any ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = (() => number) extends string ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Boolean', () => { type T = (() => number) extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number', () => { type T = (() => number) extends number ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer', () => { type T = (() => number) extends number ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array 1', () => { type T = (() => number) extends Array ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array 2', () => { type T = (() => number) extends Array ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array 3', () => { type T = (() => number) extends Array ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple', () => { type T = (() => number) extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Record', () => { type T = (() => number) extends Record ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Record(Type.Number(), Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1', () => { type T = (() => number) extends object ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Object({})) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 2', () => { type T = (() => number) extends {} ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Object({})) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 3', () => { type T = (() => number) extends { a: number } ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Object({ a: Type.Number() })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 4', () => { type T = (() => number) extends { length: '1' } ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Object({ length: Type.Literal('1') })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 5', () => { type T = (() => number) extends { length: number } ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Object({ length: Type.Number() })) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 1', () => { type T = (() => number) extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Union([Type.Null(), Type.String()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 2', () => { type T = (() => number) extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Union([Type.Any(), Type.String()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 3', () => { type T = (() => number) extends any | Array ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Union([Type.Any(), Type.Array(Type.Any())])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 4', () => { type T = (() => number) extends any | Array ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Union([Type.Any(), Type.Array(Type.Any())])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 5', () => { type T = (() => number) extends any | Array ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Union([Type.Any(), Type.Array(Type.String())])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Null', () => { type T = (() => number) extends null ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Void', () => { type T = (() => number) extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Function([], Type.Number()), Type.Void()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Date', () => { type T = (() => number) extends Date ? 1 : 2 const R = ExtendsCheck(Type.Constructor([], Type.Number()), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/index.ts000066400000000000000000000007761505437577000250460ustar00rootroot00000000000000import './any' import './array' import './async-iterator' import './bigint' import './boolean' import './constructor' import './date' import './function' import './integer' import './iterator' import './literal' import './not' import './null' import './number' import './object' import './promise' import './record' import './regexp' import './string' import './symbol' import './template-literal' import './tuple' import './uint8array' import './undefined' import './union' import './unknown' import './void' sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/integer.ts000066400000000000000000000072121505437577000253640ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/Integer', () => { it('Should extend Any', () => { type T = number extends any ? 1 : 2 const R = ExtendsCheck(Type.Integer(), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Unknown', () => { type T = number extends unknown ? 1 : 2 const R = ExtendsCheck(Type.Integer(), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = number extends string ? 1 : 2 const R = ExtendsCheck(Type.Integer(), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Boolean', () => { type T = number extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Integer(), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number', () => { type T = number extends number ? 1 : 2 const R = ExtendsCheck(Type.Integer(), Type.Number()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Integer', () => { type T = number extends number ? 1 : 2 const R = ExtendsCheck(Type.Integer(), Type.Integer()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Array', () => { type T = number extends Array ? 1 : 2 const R = ExtendsCheck(Type.Integer(), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple', () => { type T = number extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Integer(), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Record', () => { type T = number extends Record ? 1 : 2 const R = ExtendsCheck(Type.Integer(), Type.Record(Type.Number(), Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1', () => { type T = number extends {} ? 1 : 2 const R = ExtendsCheck(Type.Integer(), Type.Object({})) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 2', () => { type T = number extends { a: 10 } ? 1 : 2 const R = ExtendsCheck(Type.Integer(), Type.Object({ a: Type.Literal(10) })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 1', () => { type T = number extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Integer(), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 2', () => { type T = number extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Integer(), Type.Union([Type.Any(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 2', () => { type T = number extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Integer(), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Null', () => { type T = number extends null ? 1 : 2 const R = ExtendsCheck(Type.Integer(), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined', () => { type T = number extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Integer(), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Void', () => { type T = number extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Integer(), Type.Void()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Date', () => { type T = number extends Date ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/iterator.ts000066400000000000000000000064651505437577000255710ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/Iterator', () => { // ---------------------------------------------- // Generic Varying // ---------------------------------------------- it('Should extend Iterator 1', () => { type T = IterableIterator extends IterableIterator ? 1 : 2 const R = ExtendsCheck(Type.Iterator(Type.Any()), Type.Iterator(Type.Any())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Iterator 2', () => { type T = IterableIterator extends IterableIterator ? 1 : 2 const R = ExtendsCheck(Type.Iterator(Type.String()), Type.Iterator(Type.String())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Iterator 3', () => { type T = IterableIterator<'hello'> extends IterableIterator ? 1 : 2 const R = ExtendsCheck(Type.Iterator(Type.Literal('hello')), Type.Iterator(Type.String())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Iterator 4', () => { type T = IterableIterator extends IterableIterator<'hello'> ? 1 : 2 const R = ExtendsCheck(Type.Iterator(Type.String()), Type.Iterator(Type.Literal('hello'))) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Iterator 5', () => { type T = IterableIterator extends IterableIterator<'hello' | number> ? 1 : 2 const R = ExtendsCheck(Type.Iterator(Type.String()), Type.Iterator(Type.Union([Type.Literal('hello'), Type.Number()]))) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Iterator 6', () => { type T = IterableIterator<'hello' | number> extends IterableIterator ? 1 : 2 const R = ExtendsCheck(Type.Iterator(Type.Union([Type.Literal('hello'), Type.Number()])), Type.Iterator(Type.String())) Assert.IsEqual(R, ExtendsResult.False) }) // -------------------------------------------------------------------- // Structural // -------------------------------------------------------------------- it('Should extends Any 1', () => { type T = IterableIterator extends any ? 1 : 2 const R = ExtendsCheck(Type.Iterator(Type.Number()), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extends Any 2', () => { type T = any extends IterableIterator ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.Iterator(Type.Number())) Assert.IsEqual(R, ExtendsResult.Union) }) it('Should extends Unknown 1', () => { type T = IterableIterator extends unknown ? 1 : 2 const R = ExtendsCheck(Type.Iterator(Type.Number()), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extends Unknown 2', () => { type T = unknown extends IterableIterator ? 1 : 2 const R = ExtendsCheck(Type.Unknown(), Type.Iterator(Type.Number())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extends Never 1', () => { type T = IterableIterator extends never ? 1 : 2 const R = ExtendsCheck(Type.Iterator(Type.Number()), Type.Never()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extends Never 2', () => { type T = never extends IterableIterator ? 1 : 2 const R = ExtendsCheck(Type.Never(), Type.Iterator(Type.Number())) Assert.IsEqual(R, ExtendsResult.True) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/literal.ts000066400000000000000000000261531505437577000253700ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/Literal', () => { // ------------------------------------------------------------------- // String Literal // ------------------------------------------------------------------- it('Should extend Any (String)', () => { type T = 'hello' extends any ? 1 : 2 const R = ExtendsCheck(Type.Literal('hello'), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Unknown (String)', () => { type T = 'hello' extends unknown ? 1 : 2 const R = ExtendsCheck(Type.Literal('hello'), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String (String)', () => { type T = 'hello' extends string ? 1 : 2 const R = ExtendsCheck(Type.Literal('hello'), Type.String()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Boolean (String)', () => { type T = 'hello' extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Literal('hello'), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number (String)', () => { type T = 'hello' extends number ? 1 : 2 const R = ExtendsCheck(Type.Literal('hello'), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer (String)', () => { type T = 'hello' extends number ? 1 : 2 const R = ExtendsCheck(Type.Literal('hello'), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array (String)', () => { type T = 'hello' extends Array ? 1 : 2 const R = ExtendsCheck(Type.Literal('hello'), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple (String)', () => { type T = 'hello' extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Literal('hello'), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1 (String)', () => { type T = 'hello' extends {} ? 1 : 2 const R = ExtendsCheck(Type.Literal('hello'), Type.Object({}, { additionalProperties: false })) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 2 (String)', () => { type T = 'hello' extends { a: 10 } ? 1 : 2 const R = ExtendsCheck(Type.Literal('hello'), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 1 (String)', () => { type T = 'hello' extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Literal('hello'), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 2 (String)', () => { type T = 'hello' extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Literal('hello'), Type.Union([Type.Any(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 3 (String)', () => { type T = 'hello' extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Literal('hello'), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Null (String)', () => { type T = 'hello' extends null ? 1 : 2 const R = ExtendsCheck(Type.Literal('hello'), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined (String)', () => { type T = 'hello' extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Literal('hello'), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) // ------------------------------------------------------------------- // Number Literal // ------------------------------------------------------------------- it('Should extend Any (Number)', () => { type T = 10 extends any ? 1 : 2 const R = ExtendsCheck(Type.Literal(10), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Unknown (Number)', () => { type T = 10 extends unknown ? 1 : 2 const R = ExtendsCheck(Type.Literal(10), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String (Number)', () => { type T = 10 extends string ? 1 : 2 const R = ExtendsCheck(Type.Literal(10), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Boolean (Number)', () => { type T = 10 extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Literal(10), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number (Number)', () => { type T = 10 extends number ? 1 : 2 const R = ExtendsCheck(Type.Literal(10), Type.Number()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Integer (Number)', () => { type T = 10 extends number ? 1 : 2 const R = ExtendsCheck(Type.Literal(10), Type.Integer()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Array (Number)', () => { type T = 10 extends Array ? 1 : 2 const R = ExtendsCheck(Type.Literal(10), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple (Number)', () => { type T = 10 extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Literal(10), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1 (Number)', () => { type T = 10 extends {} ? 1 : 2 const R = ExtendsCheck(Type.Literal(10), Type.Object({}, { additionalProperties: false })) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 2 (Number)', () => { type T = 10 extends { a: 10 } ? 1 : 2 const R = ExtendsCheck(Type.Literal(10), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 1 (Number)', () => { type T = 10 extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Literal(10), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 2 (Number)', () => { type T = 10 extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Literal(10), Type.Union([Type.Any(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 3 (Number)', () => { type T = 10 extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Literal(10), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Null (Number)', () => { type T = 10 extends null ? 1 : 2 const R = ExtendsCheck(Type.Literal(10), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined (Number)', () => { type T = 10 extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Literal(10), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) // ------------------------------------------------------------------- // Boolean Literal // ------------------------------------------------------------------- it('Should extend Any (Boolean)', () => { type T = true extends any ? 1 : 2 const R = ExtendsCheck(Type.Literal(true), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Unknown (Boolean)', () => { type T = true extends unknown ? 1 : 2 const R = ExtendsCheck(Type.Literal(true), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String (Boolean)', () => { type T = true extends string ? 1 : 2 const R = ExtendsCheck(Type.Literal(true), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Boolean (Boolean)', () => { type T = true extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Literal(true), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Number (Boolean)', () => { type T = true extends number ? 1 : 2 const R = ExtendsCheck(Type.Literal(true), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer (Boolean)', () => { type T = true extends number ? 1 : 2 const R = ExtendsCheck(Type.Literal(true), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array (Boolean)', () => { type T = true extends Array ? 1 : 2 const R = ExtendsCheck(Type.Literal(true), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple (Boolean)', () => { type T = true extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Literal(true), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Record 1', () => { type T = 'hello' extends Record ? 1 : 2 const R = ExtendsCheck(Type.Literal('hello'), Type.Record(Type.Number(), Type.Any())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 2', () => { type T = 10 extends Record ? 1 : 2 const R = ExtendsCheck(Type.Literal(10), Type.Record(Type.Number(), Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Record 3', () => { type T = true extends Record ? 1 : 2 const R = ExtendsCheck(Type.Literal(true), Type.Record(Type.Number(), Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1 (Boolean)', () => { type T = true extends {} ? 1 : 2 const R = ExtendsCheck(Type.Literal(true), Type.Object({}, { additionalProperties: false })) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 2 (Boolean)', () => { type T = true extends { a: 10 } ? 1 : 2 const R = ExtendsCheck(Type.Literal(true), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 1 (Boolean)', () => { type T = true extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Literal(true), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 2 (Boolean)', () => { type T = true extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Literal(true), Type.Union([Type.Any(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 3 (Boolean)', () => { type T = true extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Literal(true), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Null (Boolean)', () => { type T = true extends null ? 1 : 2 const R = ExtendsCheck(Type.Literal(true), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined (Boolean)', () => { type T = true extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Literal(true), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Void', () => { type T = true extends void ? 1 : 2 const R = ExtendsCheck(Type.Literal(true), Type.Void()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Date', () => { type T = true extends Date ? 1 : 2 const R = ExtendsCheck(Type.Literal(true), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/not.ts000066400000000000000000000140551505437577000245320ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' // --------------------------------------------------------------------------- // Note: Not is equivalent to Unknown with the exception of nested negation. // --------------------------------------------------------------------------- describe('type/extends/Not', () => { // ------------------------------------------------------------------------- // Issue: type T = number extends not number ? true : false // true // type T = number extends unknown ? true : false // true // // TypeScript does not support type negation. The best TypeBox can do is // treat "not" as "unknown". From this standpoint, the extends assignability // check needs to return true for the following case to keep TypeBox aligned // with TypeScript static inference. // ------------------------------------------------------------------------- it('Should extend with unknown assignability check', () => { const A = Type.Number() const B = Type.Not(Type.Number()) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.True) // we would expect false }) // --------------------------------------------------------------------------- // Nested // --------------------------------------------------------------------------- it('Should extend with nested negation', () => { const T1 = Type.String() const T2 = Type.Not(T1) const T3 = Type.Not(T2) const T4 = Type.Not(T3) const T5 = Type.Not(T4) const R1 = ExtendsCheck(T1, Type.String()) const R2 = ExtendsCheck(T2, Type.String()) const R3 = ExtendsCheck(T3, Type.String()) const R4 = ExtendsCheck(T4, Type.String()) const R5 = ExtendsCheck(T5, Type.String()) Assert.IsEqual(R1, ExtendsResult.True) Assert.IsEqual(R2, ExtendsResult.False) Assert.IsEqual(R3, ExtendsResult.True) Assert.IsEqual(R4, ExtendsResult.False) Assert.IsEqual(R5, ExtendsResult.True) }) // --------------------------------------------------------------------------- // Not as Unknown Tests // --------------------------------------------------------------------------- it('Should extend Any', () => { type T = unknown extends any ? 1 : 2 const R = ExtendsCheck(Type.Not(Type.Number()), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Unknown', () => { type T = unknown extends unknown ? 1 : 2 const R = ExtendsCheck(Type.Not(Type.Number()), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = unknown extends string ? 1 : 2 const R = ExtendsCheck(Type.Not(Type.Number()), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Boolean', () => { type T = unknown extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Not(Type.Number()), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number', () => { type T = unknown extends number ? 1 : 2 const R = ExtendsCheck(Type.Not(Type.Number()), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer', () => { type T = unknown extends number ? 1 : 2 const R = ExtendsCheck(Type.Not(Type.Number()), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array 1', () => { type T = unknown extends Array ? 1 : 2 const R = ExtendsCheck(Type.Not(Type.Number()), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array 2', () => { type T = unknown extends Array ? 1 : 2 const R = ExtendsCheck(Type.Not(Type.Number()), Type.Array(Type.String())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple', () => { type T = unknown extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Not(Type.Number()), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1', () => { type T = unknown extends {} ? 1 : 2 const R = ExtendsCheck(Type.Not(Type.Number()), Type.Object({})) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 2', () => { type T = unknown extends { a: number } ? 1 : 2 const R = ExtendsCheck(Type.Not(Type.Number()), Type.Object({ a: Type.Number() })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 1', () => { type T = unknown extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Not(Type.Number()), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 2', () => { type T = unknown extends any | number ? 1 : 2 // 1 const R = ExtendsCheck(Type.Not(Type.Number()), Type.Union([Type.Any(), Type.String()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 3', () => { type T = unknown extends unknown | number ? 1 : 2 // 1 const R = ExtendsCheck(Type.Not(Type.Number()), Type.Union([Type.Unknown(), Type.String()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 4', () => { type T = unknown extends unknown | any ? 1 : 2 // 1 const R = ExtendsCheck(Type.Not(Type.Number()), Type.Union([Type.Unknown(), Type.String()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Null', () => { type T = unknown extends null ? 1 : 2 const R = ExtendsCheck(Type.Not(Type.Number()), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined', () => { type T = unknown extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Not(Type.Number()), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Void', () => { type T = unknown extends void ? 1 : 2 const R = ExtendsCheck(Type.Not(Type.Number()), Type.Void()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Date', () => { type T = unknown extends Date ? 1 : 2 const R = ExtendsCheck(Type.Not(Type.Number()), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/null.ts000066400000000000000000000074471505437577000247130ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/Null', () => { it('Should extend Any', () => { type T = null extends any ? 1 : 2 const R = ExtendsCheck(Type.Null(), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Unknown', () => { type T = null extends unknown ? 1 : 2 const R = ExtendsCheck(Type.Null(), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = null extends string ? 1 : 2 const R = ExtendsCheck(Type.Null(), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Boolean', () => { type T = null extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Null(), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number', () => { type T = null extends number ? 1 : 2 const R = ExtendsCheck(Type.Null(), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer', () => { type T = null extends number ? 1 : 2 const R = ExtendsCheck(Type.Null(), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array', () => { type T = null extends Array ? 1 : 2 const R = ExtendsCheck(Type.Null(), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple', () => { type T = null extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Null(), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Record', () => { type T = null extends Record ? 1 : 2 const R = ExtendsCheck(Type.Null(), Type.Record(Type.Number(), Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1', () => { type T = null extends {} ? 1 : 2 const R = ExtendsCheck(Type.Null(), Type.Object({}, { additionalProperties: false })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 2', () => { type T = null extends { a: 10 } ? 1 : 2 const R = ExtendsCheck(Type.Null(), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 3', () => { type T = null extends object ? 1 : 2 const R = ExtendsCheck(Type.Null(), Type.Object({})) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 1', () => { type T = null extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Null(), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 2', () => { type T = null extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Null(), Type.Union([Type.Any(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 2', () => { type T = null extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Null(), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Null', () => { type T = null extends null ? 1 : 2 const R = ExtendsCheck(Type.Null(), Type.Null()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Undefined', () => { type T = null extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Null(), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Void', () => { type T = null extends void ? 1 : 2 const R = ExtendsCheck(Type.Null(), Type.Void()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Date', () => { type T = null extends Date ? 1 : 2 const R = ExtendsCheck(Type.Null(), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/number.ts000066400000000000000000000072641505437577000252260ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/Number', () => { it('Should extend Any', () => { type T = number extends any ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Unknown', () => { type T = number extends unknown ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = number extends string ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Boolean', () => { type T = number extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number', () => { type T = number extends number ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Number()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Integer', () => { type T = number extends number ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Integer()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Array', () => { type T = number extends Array ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple', () => { type T = number extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Record', () => { type T = number extends Record ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Record(Type.Number(), Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1', () => { type T = number extends {} ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Object({}, { additionalProperties: false })) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 2', () => { type T = number extends { a: 10 } ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 1', () => { type T = number extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 2', () => { type T = number extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Union([Type.Any(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 2', () => { type T = number extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Null', () => { type T = number extends null ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined', () => { type T = number extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Void', () => { type T = number extends void ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Void()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Date', () => { type T = number extends Date ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/object.ts000066400000000000000000000222301505437577000251720ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/Object', () => { // ---------------------------------------------------------- // Object // ---------------------------------------------------------- it('Should extend Object 1', () => { type T = { x: number; y: number } extends { x: number } ? 1 : 2 const A = Type.Object({ x: Type.Number(), y: Type.Number() }) const B = Type.Object({ x: Type.Number() }) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 2', () => { type T = { x: number } extends { x: number; y: number } ? 1 : 2 const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ x: Type.Number(), y: Type.Number() }) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 3', () => { type T = { x: number; y: string } extends { x: number } ? 1 : 2 const A = Type.Object({ x: Type.Number(), y: Type.String() }) const B = Type.Object({ x: Type.Number() }) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 4', () => { type T = { x: number } extends { x: number; y: string } ? 1 : 2 const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ x: Type.Number(), y: Type.String() }) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 5', () => { type T = { x: number | string } extends { x: number } ? 1 : 2 const A = Type.Object({ x: Type.Union([Type.Number(), Type.String()]) }) const B = Type.Object({ x: Type.Number() }) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 6', () => { type T = { x: number } extends { x: number | string } ? 1 : 2 const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ x: Type.Union([Type.Number(), Type.String()]) }) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.True) }) // ---------------------------------------------------------- // Record // ---------------------------------------------------------- it('Should extend Record 2', () => { type T = { a: number; b: number } extends Record ? 1 : 2 const A = Type.Object({ a: Type.Number(), b: Type.Number() }) const B = Type.Record(Type.String(), Type.Number()) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 3', () => { type T = { a: number; b: number } extends Record ? 1 : 2 const A = Type.Object({ a: Type.Number(), b: Type.Number() }) const B = Type.Record(Type.Number(), Type.Number()) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 4', () => { type T = { a: number; b: number } extends Record<'a' | 'b', number> ? 1 : 2 const A = Type.Object({ a: Type.Number(), b: Type.Number() }) const B = Type.Record(Type.Union([Type.Literal('a'), Type.Literal('b')]), Type.Number()) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 5', () => { type T = { a: number; b: number } extends Record<'a' | 'b', number> ? 1 : 2 const A = Type.Object({ a: Type.Number(), b: Type.Number() }) const B = Type.Record(Type.String(), Type.Number()) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 6', () => { type T = { a: number; b: number } extends Record<'a' | 'b', number> ? 1 : 2 const A = Type.Object({ a: Type.Number(), b: Type.Number() }) const B = Type.Record(Type.Number(), Type.Number()) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.True) }) // ---------------------------------------------------------- // Standard // ---------------------------------------------------------- it('Should extend Any', () => { type T = { a: number } extends any ? 1 : 2 const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = { a: number } extends string ? 1 : 2 const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Boolean', () => { type T = { a: number } extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number', () => { type T = { a: number } extends number ? 1 : 2 const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer', () => { type T = { a: number } extends number ? 1 : 2 const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array', () => { type T = { a: number } extends Array ? 1 : 2 const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple', () => { type T = { a: number } extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1', () => { type T = { a: number } extends {} ? 1 : 2 const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Object({}, { additionalProperties: false })) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 2', () => { type T = { a: number } extends { a: 10 } ? 1 : 2 const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Object({ a: Type.Literal(10) })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 3', () => { type T = { a: number } extends object ? 1 : 2 const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Object({})) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 1', () => { type T = { a: number } extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Union([Type.Null(), Type.String()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 2', () => { type T = { a: number } extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Union([Type.Any(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 2', () => { type T = { a: number } extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Null', () => { type T = { a: number } extends null ? 1 : 2 const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined', () => { type T = { a: number } extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Void', () => { type T = { a: number } extends void ? 1 : 2 const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Void()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Date', () => { type T = { a: number } extends Date ? 1 : 2 const R = ExtendsCheck(Type.Object({ a: Type.Number() }), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) // ---------------------------------------------------------------- // Optional // ---------------------------------------------------------------- it('Should extend optional 1', () => { const A = Type.Object({ a: Type.Number() }) const B = Type.Object({ a: Type.Optional(Type.Number()) }) const C = ExtendsCheck(A, B) Assert.IsEqual(C, ExtendsResult.True) }) it('Should extend optional 2', () => { const A = Type.Object({ a: Type.Number() }) const B = Type.Object({ a: Type.Optional(Type.Number()) }) const C = ExtendsCheck(B, A) Assert.IsEqual(C, ExtendsResult.False) }) it('Should extend optional 3', () => { const A = Type.Object({ x: Type.Optional(Type.Number()), y: Type.Number(), }) const B = Type.Object({ y: Type.Number(), z: Type.Number(), }) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend optional 4', () => { const A = Type.Object({ x: Type.Number(), y: Type.Number(), }) const B = Type.Object({ y: Type.Number(), z: Type.Number(), }) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend optional 5', () => { const A = Type.Object({ x: Type.Number(), y: Type.Number(), }) const B = Type.Object({ y: Type.Number(), z: Type.Optional(Type.Number()), }) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.True) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/promise.ts000066400000000000000000000222331505437577000254050ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/Promise', () => { // ---------------------------------------------- // Generic Varying // ---------------------------------------------- it('Should extend Promise Varying 1', () => { type T = Promise extends Promise ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Promise(Type.Any())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Promise Varying 2', () => { type T = Promise extends Promise ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.String()), Type.Promise(Type.Any())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Promise Varying 3', () => { type T = Promise extends Promise ? 1 : 2 // 1 const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Promise(Type.String())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Promise Varying 4', () => { type T = Promise extends Promise ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Promise(Type.String())) Assert.IsEqual(R, ExtendsResult.False) }) // ---------------------------------------------- // Any // ---------------------------------------------- it('Should extend Any', () => { type T = Promise extends any ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Unknown', () => { type T = Promise extends unknown ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = Promise extends string ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Any()), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Boolean', () => { type T = Promise extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number', () => { type T = Promise extends number ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer', () => { type T = Promise extends number ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array', () => { type T = Promise extends Array ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple', () => { type T = Promise extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Record', () => { type T = Promise extends Record ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Record(Type.Number(), Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1', () => { type T = Promise extends {} ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Object({}, { additionalProperties: false })) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 2', () => { type T = Promise extends { a: 10 } ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 3', () => { type T = Promise extends object ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Object({})) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 1', () => { type T = Promise extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 2', () => { type T = Promise extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Union([Type.Any(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 2', () => { type T = Promise extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Null', () => { type T = Promise extends null ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined', () => { type T = Promise extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) // ---------------------------------------------- // Constrained // ---------------------------------------------- it('Should extend constrained Any', () => { type T = Promise extends any ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend constrained Unknown', () => { type T = Promise extends unknown ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend constrained String', () => { type T = Promise extends string ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Number()), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend constrained Boolean', () => { type T = Promise extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend constrained Number', () => { type T = Promise extends number ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Any()), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend constrained Integer', () => { type T = Promise extends number ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend constrained Array', () => { type T = Promise extends Array ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend constrained Tuple', () => { type T = Promise extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend constrained Object 1', () => { type T = Promise extends {} ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Object({}, { additionalProperties: false })) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend constrained Object 2', () => { type T = Promise extends { a: 10 } ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend constrained Object 3', () => { type T = Promise extends object ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Object({})) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend constrained Union 1', () => { type T = Promise extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend constrained Union 2', () => { type T = Promise extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Union([Type.Any(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend constrained Union 2', () => { type T = Promise extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend constrained Null', () => { type T = Promise extends null ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend constrained Undefined', () => { type T = Promise extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Void', () => { type T = Promise extends void ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Void()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Date', () => { type T = Promise extends Date ? 1 : 2 const R = ExtendsCheck(Type.Promise(Type.Number()), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/record.ts000066400000000000000000000221151505437577000252040ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/Record', () => { it('Should extend Record 1', () => { type T = Record<'a' | 'b', number> extends { a: number; b: number } ? 1 : 2 const A = Type.Record(Type.Union([Type.Literal('a'), Type.Literal('b')]), Type.Number()) const B = Type.Object({ a: Type.Number(), b: Type.Number() }) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 2', () => { type T = Record extends { a: number; b: number } ? 1 : 2 const A = Type.Record(Type.String(), Type.Number()) const B = Type.Object({ a: Type.Number(), b: Type.Number() }) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Record 3', () => { type T = Record extends { a: number; b: number } ? 1 : 2 const A = Type.Record(Type.Number(), Type.Number()) const B = Type.Object({ a: Type.Number(), b: Type.Number() }) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Record 4', () => { type T = Record<'a' | 'b', number> extends { a: number; b: number } ? 1 : 2 const A = Type.Record(Type.Union([Type.Literal('a'), Type.Literal('b')]), Type.Number()) const B = Type.Object({ a: Type.Number(), b: Type.Number() }) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 5', () => { type T = Record<'a' | 'b', number> extends { a: number; b: number } ? 1 : 2 const A = Type.Record(Type.Union([Type.Literal('a'), Type.Literal('b')]), Type.Number()) const B = Type.Object({ a: Type.Number(), b: Type.Number() }) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 6', () => { type T = Record extends Record<'a' | 'b', number> ? true : false const A = Type.Record(Type.String(), Type.Number()) const B = Type.Record(Type.Union([Type.Literal('a'), Type.Literal('b')]), Type.Number()) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 7', () => { type T = Record extends Record ? 1 : 2 const A = Type.Record(Type.String(), Type.Number()) const B = Type.Record(Type.String(), Type.Number()) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 8', () => { type T = Record extends Record ? 1 : 2 const A = Type.Record(Type.String(), Type.Number()) const B = Type.Record(Type.Number(), Type.Number()) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 9', () => { type T = Record extends Record<'a' | 'b', number> ? 1 : 2 const A = Type.Record(Type.Number(), Type.Number()) const B = Type.Record(Type.Union([Type.Literal('a'), Type.Literal('b')]), Type.Number()) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Record 10', () => { type T = Record extends Record ? 1 : 2 const A = Type.Record(Type.Number(), Type.Number()) const B = Type.Record(Type.String(), Type.Number()) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 11', () => { type T = Record extends Record ? 1 : 2 const A = Type.Record(Type.Number(), Type.Number()) const B = Type.Record(Type.Number(), Type.Number()) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.True) }) // ----- it('Should extend Record 12', () => { type T = Record extends Record ? 1 : 2 const A = Type.Record(Type.String(), Type.Number()) const B = Type.Record(Type.Integer(), Type.Number()) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 13', () => { type T = Record extends Record<'a' | 'b', number> ? 1 : 2 const A = Type.Record(Type.Integer(), Type.Number()) const B = Type.Record(Type.Union([Type.Literal('a'), Type.Literal('b')]), Type.Number()) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Record 14', () => { type T = Record extends Record ? 1 : 2 const A = Type.Record(Type.Integer(), Type.Number()) const B = Type.Record(Type.String(), Type.Number()) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 15', () => { type T = Record extends Record ? 1 : 2 const A = Type.Record(Type.Integer(), Type.Number()) const B = Type.Record(Type.Integer(), Type.Number()) const R = ExtendsCheck(A, B) Assert.IsEqual(R, ExtendsResult.True) }) // ------------------------------------------------------------------- // Standard // ------------------------------------------------------------------- it('Should extend Any', () => { type T = Record extends any ? 1 : 2 const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Unknown', () => { type T = Record extends unknown ? 1 : 2 const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = Record extends string ? 1 : 2 const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Boolean', () => { type T = Record extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number', () => { type T = Record extends number ? 1 : 2 const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer', () => { type T = Record extends number ? 1 : 2 const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array 1', () => { type T = Record extends Array ? 1 : 2 const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array 2', () => { type T = Record extends Array ? 1 : 2 const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Array(Type.String())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple', () => { type T = Record extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 2', () => { type T = Record extends {} ? 1 : 2 const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Object({})) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 3', () => { type T = Record extends { a: number } ? 1 : 2 const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Object({ a: Type.Number() })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 1', () => { type T = Record extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 2', () => { type T = Record extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Union([Type.Any(), Type.String()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Null', () => { type T = Record extends null ? 1 : 2 const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined', () => { type T = Record extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Void', () => { type T = Record extends void ? 1 : 2 const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Void()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Date', () => { type T = Record extends Date ? 1 : 2 const R = ExtendsCheck(Type.Record(Type.Number(), Type.Number()), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/regexp.ts000066400000000000000000000111621505437577000252200ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' // ------------------------------------------------------------------ // Note: RegExp infers as type String // ------------------------------------------------------------------ describe('type/extends/RegExp', () => { it('Should extend Any', () => { type T = string extends any ? 1 : 2 const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Unknown', () => { type T = string extends unknown ? 1 : 2 const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = string extends string ? 1 : 2 const R = ExtendsCheck(Type.RegExp(/xyz/), Type.RegExp(/xyz/)) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Boolean', () => { type T = string extends boolean ? 1 : 2 const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number', () => { type T = string extends number ? 1 : 2 const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer', () => { type T = string extends number ? 1 : 2 const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array', () => { type T = string extends Array ? 1 : 2 const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple', () => { type T = string extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Record 1', () => { type T = string extends Record ? 1 : 2 const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Record(Type.Number(), Type.Any())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 2', () => { type T = string extends Record ? 1 : 2 const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Record(Type.Number(), Type.Unknown())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 3', () => { type T = string extends Record ? 1 : 2 const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Record(Type.Number(), Type.RegExp(/xyz/))) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 4', () => { type T = string extends Record ? 1 : 2 const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Record(Type.Number(), Type.Number())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1', () => { type T = string extends {} ? 1 : 2 const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Object({}, { additionalProperties: false })) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 2', () => { type T = string extends { a: 10 } ? 1 : 2 const R = ExtendsCheck(Type.RegExp(/xyz/), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 1', () => { type T = number extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Union([Type.Number(), Type.RegExp(/xyz/)])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 2', () => { type T = number extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Union([Type.Any(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 3', () => { type T = number extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Null', () => { type T = number extends null ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined', () => { type T = number extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Void', () => { type T = number extends void ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Void()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Date', () => { type T = number extends Date ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/string.ts000066400000000000000000000105531505437577000252370ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/String', () => { it('Should extend Any', () => { type T = string extends any ? 1 : 2 const R = ExtendsCheck(Type.String(), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Unknown', () => { type T = string extends unknown ? 1 : 2 const R = ExtendsCheck(Type.String(), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = string extends string ? 1 : 2 const R = ExtendsCheck(Type.String(), Type.String()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Boolean', () => { type T = string extends boolean ? 1 : 2 const R = ExtendsCheck(Type.String(), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number', () => { type T = string extends number ? 1 : 2 const R = ExtendsCheck(Type.String(), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer', () => { type T = string extends number ? 1 : 2 const R = ExtendsCheck(Type.String(), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array', () => { type T = string extends Array ? 1 : 2 const R = ExtendsCheck(Type.String(), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple', () => { type T = string extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.String(), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Record 1', () => { type T = string extends Record ? 1 : 2 const R = ExtendsCheck(Type.String(), Type.Record(Type.Number(), Type.Any())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 2', () => { type T = string extends Record ? 1 : 2 const R = ExtendsCheck(Type.String(), Type.Record(Type.Number(), Type.Unknown())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 3', () => { type T = string extends Record ? 1 : 2 const R = ExtendsCheck(Type.String(), Type.Record(Type.Number(), Type.String())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 4', () => { type T = string extends Record ? 1 : 2 const R = ExtendsCheck(Type.String(), Type.Record(Type.Number(), Type.Number())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1', () => { type T = string extends {} ? 1 : 2 const R = ExtendsCheck(Type.String(), Type.Object({}, { additionalProperties: false })) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 2', () => { type T = string extends { a: 10 } ? 1 : 2 const R = ExtendsCheck(Type.String(), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 1', () => { type T = number extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 2', () => { type T = number extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Union([Type.Any(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 3', () => { type T = number extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Null', () => { type T = number extends null ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined', () => { type T = number extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Void', () => { type T = number extends void ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Void()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Date', () => { type T = number extends Date ? 1 : 2 const R = ExtendsCheck(Type.Number(), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/symbol.ts000066400000000000000000000100251505437577000252300ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/Symbol', () => { it('Should extend Any', () => { type T = symbol extends any ? 1 : 2 const R = ExtendsCheck(Type.Symbol(), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Unknown', () => { type T = symbol extends unknown ? 1 : 2 const R = ExtendsCheck(Type.Symbol(), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = symbol extends string ? 1 : 2 const R = ExtendsCheck(Type.Symbol(), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Boolean', () => { type T = symbol extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Symbol(), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number', () => { type T = symbol extends number ? 1 : 2 const R = ExtendsCheck(Type.Symbol(), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer', () => { type T = symbol extends number ? 1 : 2 const R = ExtendsCheck(Type.Symbol(), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array', () => { type T = symbol extends Array ? 1 : 2 const R = ExtendsCheck(Type.Symbol(), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple', () => { type T = symbol extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Symbol(), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Record', () => { type T = symbol extends Record ? 1 : 2 const R = ExtendsCheck(Type.Symbol(), Type.Record(Type.Number(), Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1', () => { type T = symbol extends {} ? 1 : 2 const R = ExtendsCheck(Type.Symbol(), Type.Object({})) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 2', () => { type T = symbol extends { a: 10 } ? 1 : 2 const R = ExtendsCheck(Type.Symbol(), Type.Object({ a: Type.Literal(10) })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 1', () => { type T = symbol extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Symbol(), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 2', () => { type T = symbol extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Symbol(), Type.Union([Type.Any(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 3', () => { type T = symbol extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Symbol(), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 4', () => { type T = symbol extends boolean | symbol ? 1 : 2 const R = ExtendsCheck(Type.Symbol(), Type.Union([Type.Boolean(), Type.Symbol()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Null', () => { type T = symbol extends null ? 1 : 2 const R = ExtendsCheck(Type.Symbol(), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined', () => { type T = symbol extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Symbol(), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Void', () => { type T = symbol extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Symbol(), Type.Void()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Date', () => { type T = symbol extends Date ? 1 : 2 const R = ExtendsCheck(Type.Symbol(), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Symbol', () => { type T = symbol extends symbol ? 1 : 2 const R = ExtendsCheck(Type.Symbol(), Type.Symbol()) Assert.IsEqual(R, ExtendsResult.True) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/template-literal.ts000066400000000000000000000206721505437577000272010ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/TemplateLiteral', () => { // ------------------------------------------------------------------- // String Literal 'hello' // ------------------------------------------------------------------- it('Should extend Any (hello)', () => { type T = 'hello' extends any ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Unknown (hello)', () => { type T = 'hello' extends unknown ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String (hello)', () => { type T = 'hello' extends string ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.String()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Boolean (hello)', () => { type T = 'hello' extends boolean ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number (hello)', () => { type T = 'hello' extends number ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer (hello)', () => { type T = 'hello' extends number ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array (hello)', () => { type T = 'hello' extends Array ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple (hello)', () => { type T = 'hello' extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1 (hello)', () => { type T = 'hello' extends {} ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Object({}, { additionalProperties: false })) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 2 (hello)', () => { type T = 'hello' extends { a: 10 } ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 1 (hello)', () => { type T = 'hello' extends number | string ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 2 (hello)', () => { type T = 'hello' extends any | number ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Union([Type.Any(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 3 (hello)', () => { type T = 'hello' extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Null (hello)', () => { type T = 'hello' extends null ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined (hello)', () => { type T = 'hello' extends undefined ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Literal('hello')]), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) // ------------------------------------------------------------------- // String Literal 'hello' | 'world' // ------------------------------------------------------------------- it('Should extend Any (hello | world)', () => { type T = 'hello' | 'world' extends any ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Unknown (hello | world)', () => { type T = 'hello' | 'world' extends unknown ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String (hello | world)', () => { type T = 'hello' | 'world' extends string ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.String()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Boolean (hello | world)', () => { type T = 'hello' | 'world' extends boolean ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number (hello | world)', () => { type T = 'hello' | 'world' extends number ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer (hello | world)', () => { type T = 'hello' | 'world' extends number ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array (hello | world)', () => { type T = 'hello' | 'world' extends Array ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple (hello | world)', () => { type T = 'hello' | 'world' extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1 (hello | world)', () => { type T = 'hello' | 'world' extends {} ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Object({}, { additionalProperties: false })) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 2 (hello | world)', () => { type T = 'hello' | 'world' extends { a: 10 } ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 1 (hello | world)', () => { type T = 'hello' | 'world' extends number | string ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 2 (hello | world)', () => { type T = 'hello' | 'world' extends any | number ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Union([Type.Any(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 3 (hello | world)', () => { type T = 'hello' | 'world' extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Null (hello | world)', () => { type T = 'hello' | 'world' extends null ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined (hello | world)', () => { type T = 'hello' | 'world' extends undefined ? 1 : 2 const R = ExtendsCheck(Type.TemplateLiteral([Type.Union([Type.Literal('hello'), Type.Literal('world')])]), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/tuple.ts000066400000000000000000000171351505437577000250650ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/Tuple', () => { it('Should extend Any', () => { type T = [string, number] extends any ? 1 : 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = [string, number] extends string ? 1 : 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Boolean', () => { type T = [string, number] extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number', () => { type T = [string, number] extends number ? 1 : 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer', () => { type T = [string, number] extends number ? 1 : 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array 1', () => { type T = [string, number] extends Array ? 1 : 2 // 1 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Array 2', () => { type T = [string, number] extends Array ? 1 : 2 // 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Array(Type.String())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array 3', () => { type T = [string, number] extends Array ? 1 : 2 // 1 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Array(Type.Union([Type.String(), Type.Number()]))) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Array 4', () => { type T = [string, number] extends Array ? 1 : 2 // 1 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Array(Type.Union([Type.String(), Type.Number(), Type.Boolean()]))) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Tuple 1', () => { type T = [string, number] extends [string, number] ? 1 : 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Tuple([Type.String(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Tuple 2', () => { type T = [string, number] extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple 3', () => { type T = [string, any] extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Any()]), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple 4', () => { type T = [string, number] extends [string, any] ? 1 : 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Tuple([Type.String(), Type.Any()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Tuple 5', () => { type T = [string, unknown] extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Unknown()]), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple 6', () => { type T = [string, number] extends [string, unknown] ? 1 : 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Tuple([Type.String(), Type.Unknown()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Tuple 7', () => { type T = [] extends [string, number] ? 1 : 2 const R = ExtendsCheck(Type.Tuple([]), Type.Tuple([Type.String(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple 8', () => { type T = [string, number] extends [] ? 1 : 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Tuple([])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Record 1', () => { type T = [string, number] extends Record ? 1 : 2 const R = ExtendsCheck(Type.String(), Type.Record(Type.Number(), Type.Any())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 2', () => { type T = [string, number] extends Record ? 1 : 2 const R = ExtendsCheck(Type.String(), Type.Record(Type.Number(), Type.Unknown())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 3', () => { type T = [string, number] extends Record ? 1 : 2 const R = ExtendsCheck(Type.String(), Type.Record(Type.Number(), Type.String())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Record 4', () => { type T = [string, number] extends Record ? 1 : 2 const R = ExtendsCheck(Type.String(), Type.Record(Type.Number(), Type.Number())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1', () => { type T = [string, number] extends {} ? 1 : 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Object({}, { additionalProperties: false })) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 2', () => { type T = [string, number] extends { a: 10 } ? 1 : 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 3', () => { type T = [string, number] extends object ? 1 : 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Object({})) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 1', () => { type T = [string, number] extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 2', () => { type T = [string, number] extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Union([Type.Any(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 2', () => { type T = [string, number] extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Null', () => { type T = [string, number] extends null ? 1 : 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined', () => { type T = [string, number] extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Void', () => { type T = [string, number] extends void ? 1 : 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Void()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Date', () => { type T = [string, number] extends Date ? 1 : 2 const R = ExtendsCheck(Type.Tuple([Type.String(), Type.Number()]), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/uint8array.ts000066400000000000000000000075131505437577000260410ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/Uint8Array', () => { it('Should extend Any', () => { type T = Uint8Array extends any ? 1 : 2 const R = ExtendsCheck(Type.Uint8Array(), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Unknown', () => { type T = Uint8Array extends unknown ? 1 : 2 const R = ExtendsCheck(Type.Uint8Array(), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = Uint8Array extends string ? 1 : 2 const R = ExtendsCheck(Type.Uint8Array(), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Boolean', () => { type T = Uint8Array extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Uint8Array(), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number', () => { type T = Uint8Array extends number ? 1 : 2 const R = ExtendsCheck(Type.Uint8Array(), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer', () => { type T = Uint8Array extends number ? 1 : 2 const R = ExtendsCheck(Type.Uint8Array(), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array', () => { type T = Uint8Array extends Array ? 1 : 2 const R = ExtendsCheck(Type.Uint8Array(), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple', () => { type T = Uint8Array extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Uint8Array(), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Record', () => { type T = Uint8Array extends Record ? 1 : 2 const R = ExtendsCheck(Type.Uint8Array(), Type.Record(Type.Number(), Type.Any())) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 1', () => { type T = Uint8Array extends {} ? 1 : 2 const R = ExtendsCheck(Type.Uint8Array(), Type.Object({}, { additionalProperties: false })) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 2', () => { type T = Uint8Array extends { a: 10 } ? 1 : 2 const R = ExtendsCheck(Type.Uint8Array(), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 1', () => { type T = Uint8Array extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Uint8Array(), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 2', () => { type T = Uint8Array extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Uint8Array(), Type.Union([Type.Any(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 3', () => { type T = Uint8Array extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Uint8Array(), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Null', () => { type T = Uint8Array extends null ? 1 : 2 const R = ExtendsCheck(Type.Uint8Array(), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined', () => { type T = Uint8Array extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Uint8Array(), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Void', () => { type T = Uint8Array extends void ? 1 : 2 const R = ExtendsCheck(Type.Uint8Array(), Type.Void()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Date', () => { type T = Uint8Array extends Date ? 1 : 2 const R = ExtendsCheck(Type.Uint8Array(), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/undefined.ts000066400000000000000000000071031505437577000256670ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/Undefined', () => { it('Should extend Any', () => { type T = undefined extends any ? 1 : 2 const R = ExtendsCheck(Type.Undefined(), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = undefined extends string ? 1 : 2 const R = ExtendsCheck(Type.Undefined(), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Boolean', () => { type T = undefined extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Undefined(), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number', () => { type T = undefined extends number ? 1 : 2 const R = ExtendsCheck(Type.Undefined(), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer', () => { type T = undefined extends number ? 1 : 2 const R = ExtendsCheck(Type.Undefined(), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array', () => { type T = undefined extends Array ? 1 : 2 const R = ExtendsCheck(Type.Undefined(), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple', () => { type T = undefined extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Undefined(), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1', () => { type T = undefined extends {} ? 1 : 2 const R = ExtendsCheck(Type.Undefined(), Type.Object({}, { additionalProperties: false })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 2', () => { type T = undefined extends { a: 10 } ? 1 : 2 const R = ExtendsCheck(Type.Undefined(), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 3', () => { type T = undefined extends object ? 1 : 2 const R = ExtendsCheck(Type.Undefined(), Type.Object({})) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 1', () => { type T = undefined extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Undefined(), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 2', () => { type T = undefined extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Undefined(), Type.Union([Type.Any(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 2', () => { type T = undefined extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Undefined(), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Null', () => { type T = undefined extends null ? 1 : 2 const R = ExtendsCheck(Type.Undefined(), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined', () => { type T = undefined extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Undefined(), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Void', () => { type T = undefined extends void ? 1 : 2 const R = ExtendsCheck(Type.Undefined(), Type.Void()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Date', () => { type T = undefined extends Date ? 1 : 2 const R = ExtendsCheck(Type.Undefined(), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/union.ts000066400000000000000000000142671505437577000250670ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/Union', () => { it('Should extend Any', () => { type T = number | string extends any ? 1 : 2 const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = number | string extends string ? 1 : 2 const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Boolean', () => { type T = number | string extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number', () => { type T = number | string extends number ? 1 : 2 const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer', () => { type T = number | string extends number ? 1 : 2 const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array', () => { type T = number | string extends Array ? 1 : 2 const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple', () => { type T = number | string extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1', () => { type T = number | string extends {} ? 1 : 2 const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Object({}, { additionalProperties: false })) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Object 2', () => { type T = number | string extends { a: 10 } ? 1 : 2 const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Object({ a: Type.Literal(10) }, { additionalProperties: true })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 1', () => { type T = number | string extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 2', () => { type T = number | string extends any | number ? 1 : 2 const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Union([Type.Any(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 3', () => { type T = number | string extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 4', () => { type T = any | boolean extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.Union) }) it('Should extend Union 5', () => { type T = any | string extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.Union) }) it('Should extend Union 6', () => { type T = any | {} extends {} ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.Union) }) it('Should extend Union 7', () => { type T = any extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Any(), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.Union) }) it('Should extend Union 8', () => { type T = unknown | string extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Union([Type.Unknown(), Type.String()]), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 9', () => { type T = unknown extends boolean | number ? 1 : 2 const R = ExtendsCheck(Type.Unknown(), Type.Union([Type.Boolean(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Null', () => { type T = number | string extends null ? 1 : 2 const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined', () => { type T = number | string extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Void', () => { type T = number | string extends void ? 1 : 2 const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Void()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Void 2', () => { type T = number | string | void extends void ? 1 : 2 const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Void()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Date', () => { type T = number | string | void extends Date ? 1 : 2 const R = ExtendsCheck(Type.Union([Type.Number(), Type.String()]), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Date 2', () => { type T = Date | number | string | void extends Date ? 1 : 2 const R = ExtendsCheck(Type.Union([Type.Date(), Type.Number(), Type.String()]), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend BigInt', () => { type T = bigint | number | string | void extends Date ? 1 : 2 const R = ExtendsCheck(Type.Union([Type.BigInt(), Type.Number(), Type.String()]), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Symbol', () => { type T = symbol | number | string | void extends Date ? 1 : 2 const R = ExtendsCheck(Type.Union([Type.Symbol(), Type.Number(), Type.String()]), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/unknown.ts000066400000000000000000000075741505437577000254410ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/Unknown', () => { it('Should extend Any', () => { type T = unknown extends any ? 1 : 2 const R = ExtendsCheck(Type.Unknown(), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Unknown', () => { type T = unknown extends unknown ? 1 : 2 const R = ExtendsCheck(Type.Unknown(), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = unknown extends string ? 1 : 2 const R = ExtendsCheck(Type.Unknown(), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Boolean', () => { type T = unknown extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Unknown(), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number', () => { type T = unknown extends number ? 1 : 2 const R = ExtendsCheck(Type.Unknown(), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer', () => { type T = unknown extends number ? 1 : 2 const R = ExtendsCheck(Type.Unknown(), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array 1', () => { type T = unknown extends Array ? 1 : 2 const R = ExtendsCheck(Type.Unknown(), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array 2', () => { type T = unknown extends Array ? 1 : 2 const R = ExtendsCheck(Type.Unknown(), Type.Array(Type.String())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple', () => { type T = unknown extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Unknown(), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1', () => { type T = unknown extends {} ? 1 : 2 const R = ExtendsCheck(Type.Unknown(), Type.Object({})) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 2', () => { type T = unknown extends { a: number } ? 1 : 2 const R = ExtendsCheck(Type.Unknown(), Type.Object({ a: Type.Number() })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 1', () => { type T = unknown extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Unknown(), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 2', () => { type T = unknown extends any | number ? 1 : 2 // 1 const R = ExtendsCheck(Type.Unknown(), Type.Union([Type.Any(), Type.String()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 3', () => { type T = unknown extends unknown | number ? 1 : 2 // 1 const R = ExtendsCheck(Type.Unknown(), Type.Union([Type.Unknown(), Type.String()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 4', () => { type T = unknown extends unknown | any ? 1 : 2 // 1 const R = ExtendsCheck(Type.Unknown(), Type.Union([Type.Unknown(), Type.String()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Null', () => { type T = unknown extends null ? 1 : 2 const R = ExtendsCheck(Type.Unknown(), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined', () => { type T = unknown extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Unknown(), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Void', () => { type T = unknown extends void ? 1 : 2 const R = ExtendsCheck(Type.Unknown(), Type.Void()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Date', () => { type T = unknown extends Date ? 1 : 2 const R = ExtendsCheck(Type.Unknown(), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/extends/void.ts000066400000000000000000000076771505437577000247070ustar00rootroot00000000000000import { Type, ExtendsCheck, ExtendsResult } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/extends/Void', () => { it('Should extend Any', () => { type T = void extends any ? 1 : 2 const R = ExtendsCheck(Type.Void(), Type.Any()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Unknown', () => { type T = void extends unknown ? 1 : 2 const R = ExtendsCheck(Type.Void(), Type.Unknown()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend String', () => { type T = void extends string ? 1 : 2 const R = ExtendsCheck(Type.Void(), Type.String()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Boolean', () => { type T = void extends boolean ? 1 : 2 const R = ExtendsCheck(Type.Void(), Type.Boolean()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Number', () => { type T = void extends number ? 1 : 2 const R = ExtendsCheck(Type.Void(), Type.Number()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Integer', () => { type T = void extends number ? 1 : 2 const R = ExtendsCheck(Type.Void(), Type.Integer()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array 1', () => { type T = void extends Array ? 1 : 2 const R = ExtendsCheck(Type.Void(), Type.Array(Type.Any())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Array 2', () => { type T = void extends Array ? 1 : 2 const R = ExtendsCheck(Type.Void(), Type.Array(Type.String())) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Tuple', () => { type T = void extends [number, number] ? 1 : 2 const R = ExtendsCheck(Type.Void(), Type.Tuple([Type.Number(), Type.Number()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 1', () => { type T = void extends object ? 1 : 2 const R = ExtendsCheck(Type.Void(), Type.Object({})) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 2', () => { type T = void extends {} ? 1 : 2 const R = ExtendsCheck(Type.Void(), Type.Object({})) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Object 3', () => { type T = void extends { a: number } ? 1 : 2 const R = ExtendsCheck(Type.Void(), Type.Object({ a: Type.Number() })) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 1', () => { type T = void extends number | string ? 1 : 2 const R = ExtendsCheck(Type.Void(), Type.Union([Type.Number(), Type.String()])) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Union 2', () => { type T = void extends any | number ? 1 : 2 // 1 const R = ExtendsCheck(Type.Void(), Type.Union([Type.Any(), Type.String()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 3', () => { type T = void extends unknown | number ? 1 : 2 // 1 const R = ExtendsCheck(Type.Void(), Type.Union([Type.Unknown(), Type.String()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Union 4', () => { type T = void extends unknown | any ? 1 : 2 // 1 const R = ExtendsCheck(Type.Void(), Type.Union([Type.Unknown(), Type.String()])) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Null', () => { type T = void extends null ? 1 : 2 const R = ExtendsCheck(Type.Void(), Type.Null()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Undefined', () => { type T = void extends undefined ? 1 : 2 const R = ExtendsCheck(Type.Void(), Type.Undefined()) Assert.IsEqual(R, ExtendsResult.False) }) it('Should extend Void', () => { type T = void extends void ? 1 : 2 const R = ExtendsCheck(Type.Void(), Type.Void()) Assert.IsEqual(R, ExtendsResult.True) }) it('Should extend Date', () => { type T = void extends Date ? 1 : 2 const R = ExtendsCheck(Type.Void(), Type.Date()) Assert.IsEqual(R, ExtendsResult.False) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/000077500000000000000000000000001505437577000230055ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/index.ts000066400000000000000000000001031505437577000244560ustar00rootroot00000000000000import './type/index' import './kind/index' import './value/index' sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/000077500000000000000000000000001505437577000237325ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/any.ts000066400000000000000000000006011505437577000250660ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TAny', () => { it('Should guard for TAny', () => { const R = KindGuard.IsAny(Type.Any()) Assert.IsTrue(R) }) it('Should not guard for TAny', () => { const R = KindGuard.IsAny(null) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/argument.ts000066400000000000000000000006401505437577000261240ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TArgument', () => { it('Should guard for TArgument', () => { const R = KindGuard.IsArgument(Type.Argument(0)) Assert.IsTrue(R) }) it('Should not guard for TArgument', () => { const R = KindGuard.IsArgument(null) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/array.ts000066400000000000000000000006321505437577000254210ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TArray', () => { it('Should guard for TArray', () => { const R = KindGuard.IsArray(Type.Array(Type.Number())) Assert.IsTrue(R) }) it('Should not guard for TArray', () => { const R = KindGuard.IsArray(null) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/async-iterator.ts000066400000000000000000000007471505437577000272560ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TAsyncIterator', () => { it('Should guard for TAsyncIterator', () => { const T = Type.AsyncIterator(Type.Any()) const R = KindGuard.IsAsyncIterator(T) Assert.IsTrue(R) }) it('Should not guard for TAsyncIterator', () => { const T = null const R = KindGuard.IsAsyncIterator(T) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/awaited.ts000066400000000000000000000030701505437577000257200ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/Awaited', () => { it('Should guard for Awaited 1', () => { const T = Type.Awaited(Type.String()) const R = KindGuard.IsString(T) Assert.IsTrue(R) }) it('Should guard for Awaited 2', () => { const T = Type.Awaited(Type.Promise(Type.String())) const R = KindGuard.IsString(T) Assert.IsTrue(R) }) it('Should guard for Awaited 3', () => { const T = Type.Awaited(Type.Awaited(Type.Promise(Type.String()))) const R = KindGuard.IsString(T) Assert.IsTrue(R) }) it('Should guard for Awaited 4', () => { const T = Type.Awaited(Type.Union([Type.Promise(Type.Promise(Type.String()))])) Assert.IsTrue(KindGuard.IsString(T)) }) it('Should guard for Awaited 5', () => { const T = Type.Awaited(Type.Union([Type.Promise(Type.Promise(Type.String())), Type.Number()])) Assert.IsTrue(KindGuard.IsUnion(T)) Assert.IsTrue(KindGuard.IsString(T.anyOf[0])) Assert.IsTrue(KindGuard.IsNumber(T.anyOf[1])) }) it('Should guard for Awaited 6', () => { const T = Type.Awaited(Type.Intersect([Type.Promise(Type.Promise(Type.String()))])) Assert.IsTrue(KindGuard.IsString(T)) }) it('Should guard for Awaited 7', () => { const T = Type.Awaited(Type.Intersect([Type.Promise(Type.Promise(Type.String())), Type.Number()])) Assert.IsTrue(KindGuard.IsIntersect(T)) Assert.IsTrue(KindGuard.IsString(T.allOf[0])) Assert.IsTrue(KindGuard.IsNumber(T.allOf[1])) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/bigint.ts000066400000000000000000000006231505437577000255570ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TBigInt', () => { it('Should guard for TBigInt', () => { const R = KindGuard.IsBigInt(Type.BigInt()) Assert.IsTrue(R) }) it('Should not guard for TBigInt', () => { const R = KindGuard.IsBigInt(null) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/boolean.ts000066400000000000000000000006311505437577000257210ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TBoolean', () => { it('Should guard for TBoolean', () => { const R = KindGuard.IsBoolean(Type.Boolean()) Assert.IsTrue(R) }) it('Should not guard for TBoolean', () => { const R = KindGuard.IsBoolean(null) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/capitalize.ts000066400000000000000000000025321505437577000264310ustar00rootroot00000000000000import { KindGuard, Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/Capitalize', () => { it('Should guard for Capitalize 1', () => { const T = Type.Capitalize(Type.Literal('hello'), { $id: 'hello', foo: 1 }) Assert.IsTrue(KindGuard.IsLiteral(T)) Assert.IsEqual(T.const, 'Hello') Assert.IsEqual(T.$id, 'hello') Assert.IsEqual(T.foo, 1) }) it('Should guard for Capitalize 2', () => { const T = Type.Capitalize(Type.Literal('hello')) Assert.IsTrue(KindGuard.IsLiteral(T)) Assert.IsEqual(T.const, 'Hello') }) it('Should guard for Capitalize 3', () => { const T = Type.Capitalize(Type.Union([Type.Literal('hello'), Type.Literal('world')])) Assert.IsTrue(KindGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, 'Hello') Assert.IsEqual(T.anyOf[1].const, 'World') }) it('Should guard for Capitalize 4', () => { const T = Type.Capitalize(Type.TemplateLiteral('hello${0|1}')) Assert.IsTrue(KindGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(Hello0|Hello1)$') }) it('Should guard for Capitalize 5', () => { const T = Type.Capitalize(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(0), Type.Literal(1)])])) Assert.IsTrue(KindGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(Hello0|Hello1)$') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/composite.ts000066400000000000000000000134031505437577000263050ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TComposite', () => { it('Should guard for distinct properties', () => { const T = Type.Composite([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })]) Assert.IsTrue(KindGuard.IsNumber(T.properties.x)) Assert.IsTrue(KindGuard.IsNumber(T.properties.y)) }) it('Should guard for overlapping properties', () => { const T = Type.Composite([Type.Object({ x: Type.Number() }), Type.Object({ x: Type.Number() })]) Assert.IsTrue(KindGuard.IsIntersect(T.properties.x)) // @ts-ignore Assert.IsTrue(KindGuard.IsNumber(T.properties.x.allOf[0])) // @ts-ignore Assert.IsTrue(KindGuard.IsNumber(T.properties.x.allOf[1])) }) it('Should not produce optional property if all properties are not optional', () => { const T = Type.Composite([Type.Object({ x: Type.Optional(Type.Number()) }), Type.Object({ x: Type.Number() })]) Assert.IsFalse(KindGuard.IsOptional(T.properties.x)) }) // Note for: https://github.com/sinclairzx81/typebox/issues/419 // Determining if a composite property is optional requires a deep check for all properties gathered during a indexed access // call. Currently, there isn't a trivial way to perform this check without running into possibly infinite instantiation issues. // The optional check is only specific to overlapping properties. Singular properties will continue to work as expected. The // rule is "if all composite properties for a key are optional, then the composite property is optional". Defer this test and // document as minor breaking change. // it('Should produce optional property if all composited properties are optional', () => { // prettier-ignore const T = Type.Composite([ Type.Object({ x: Type.Optional(Type.Number()) }), Type.Object({ x: Type.Optional(Type.Number()) }) ]) Assert.IsTrue(KindGuard.IsOptional(T.properties.x)) Assert.IsEqual(T.required, undefined) }) // prettier-ignore it('Should produce required property if some composited properties are not optional', () => { const T = Type.Composite([ Type.Object({ x: Type.Optional(Type.Number()) }), Type.Object({ x: Type.Number() }) ]) Assert.IsFalse(KindGuard.IsOptional(T.properties.x)) Assert.IsTrue(T.required!.includes('x')) }) // prettier-ignore it('Should preserve single optional property', () => { const T = Type.Composite([ Type.Object({ x: Type.Optional(Type.Number()) }), ]) Assert.IsTrue(KindGuard.IsOptional(T.properties.x)) Assert.IsEqual(T.required, undefined) }) // ---------------------------------------------------------------- // Intersect // ---------------------------------------------------------------- // prettier-ignore it('Should composite Intersect 1', () => { const T = Type.Composite([ Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }), ]), Type.Intersect([ Type.Object({ z: Type.Number() }), ]) ]) Assert.IsEqual(T, Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number() })) }) // prettier-ignore it('Should composite Intersect 2', () => { const T = Type.Composite([ Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ x: Type.Number() }), ]), Type.Intersect([ Type.Object({ x: Type.Number() }), ]) ]) Assert.IsEqual(T, Type.Object({ x: Type.Intersect([Type.Intersect([Type.Number(), Type.Number()]), Type.Number()]) })) }) // prettier-ignore it('Should composite Intersect 3', () => { const T = Type.Composite([ Type.Number(), Type.Boolean() ]) Assert.IsEqual(T, Type.Object({})) }) // prettier-ignore it('Should composite Intersect 4', () => { const T = Type.Composite([ Type.Number(), Type.Boolean(), Type.Object({ x: Type.String() }) ]) Assert.IsEqual(T, Type.Object({ x: Type.String() })) }) // prettier-ignore it('Should composite Intersect 5', () => { const T = Type.Composite([ Type.Object({ x: Type.Optional(Type.String()) }), Type.Object({ x: Type.String() }) ]) Assert.IsEqual(T, Type.Object({ x: Type.Intersect([Type.String(), Type.String()]) })) }) // prettier-ignore it('Should composite Intersect 6', () => { const T = Type.Composite([ Type.Object({ x: Type.Optional(Type.String()) }), Type.Object({ x: Type.Optional(Type.String()) }) ]) Assert.IsEqual(T, Type.Object({ x: Type.Optional(Type.Intersect([Type.String(), Type.String()])) })) }) // ---------------------------------------------------------------- // Union // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/789 // prettier-ignore it('Should composite Union 1 (non-overlapping)', () => { const T = Type.Composite([ Type.Union([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }), ]), Type.Union([ Type.Object({ z: Type.Number() }), ]) ]) Assert.IsEqual(T, Type.Object({ z: Type.Number() })) }) // https://github.com/sinclairzx81/typebox/issues/789 // prettier-ignore it('Should composite Union 2 (overlapping)', () => { const T = Type.Composite([ Type.Union([ Type.Object({ x: Type.Number() }), Type.Object({ x: Type.Number() }), ]), Type.Union([ Type.Object({ x: Type.Number() }), ]) ]) Assert.IsEqual(T, Type.Object({ x: Type.Intersect([Type.Union([Type.Number(), Type.Number()]), Type.Number()]) })) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/computed.ts000066400000000000000000000023331505437577000261230ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TComputed', () => { // ---------------------------------------------------------------- // Schema // ---------------------------------------------------------------- it('Should guard for Schema', () => { const T = Type.Partial(Type.Ref('A')) Assert.IsTrue(KindGuard.IsComputed(T)) Assert.IsTrue(KindGuard.IsSchema(T)) }) // ---------------------------------------------------------------- // Record // ---------------------------------------------------------------- it('Should guard for Record 1', () => { const T = Type.Record(Type.String(), Type.String()) Assert.IsTrue(KindGuard.IsRecord(T)) }) it('Should guard for Record 3', () => { const T = Type.Record(Type.String(), Type.Ref('A')) Assert.IsTrue(KindGuard.IsRecord(T)) }) it('Should guard for Record 3', () => { const T = Type.Record(Type.String(), Type.Partial(Type.Ref('A'))) Assert.IsTrue(KindGuard.IsRecord(T)) }) it('Should guard for Record 4', () => { const T = Type.Record(Type.Ref('A'), Type.String()) Assert.IsTrue(KindGuard.IsNever(T)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/const.ts000066400000000000000000000107031505437577000254310ustar00rootroot00000000000000import { KindGuard, ValueGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TConstT', () => { // ---------------------------------------------------------------- // Identity Types // ---------------------------------------------------------------- it('Should guard for TConst 1', () => { const T = Type.Const(undefined) Assert.IsFalse(KindGuard.IsReadonly(T)) Assert.IsTrue(KindGuard.IsUndefined(T)) }) it('Should guard for TConst 2', () => { const T = Type.Const(null) Assert.IsFalse(KindGuard.IsReadonly(T)) Assert.IsTrue(KindGuard.IsNull(T)) }) it('Should guard for TConst 3', () => { const T = Type.Const(Symbol()) Assert.IsFalse(KindGuard.IsReadonly(T)) Assert.IsTrue(KindGuard.IsSymbol(T)) }) it('Should guard for TConst 4', () => { const T = Type.Const(1 as const) Assert.IsFalse(KindGuard.IsReadonly(T)) Assert.IsTrue(KindGuard.IsLiteral(T)) Assert.IsEqual(T.const, 1) }) it('Should guard for TConst 5', () => { const T = Type.Const('hello' as const) Assert.IsFalse(KindGuard.IsReadonly(T)) Assert.IsTrue(KindGuard.IsLiteral(T)) Assert.IsEqual(T.const, 'hello') }) it('Should guard for TConst 6', () => { const T = Type.Const(true as const) Assert.IsFalse(KindGuard.IsReadonly(T)) Assert.IsTrue(KindGuard.IsLiteral(T)) Assert.IsEqual(T.const, true) }) // ---------------------------------------------------------------- // Complex Types // ---------------------------------------------------------------- it('Should guard for TConst 7', () => { const T = Type.Const(100n as const) Assert.IsFalse(KindGuard.IsReadonly(T)) // TS disparity because TLiteral does not support Bigint Assert.IsTrue(KindGuard.IsBigInt(T)) }) it('Should guard for TConst 8', () => { const T = Type.Const(new Date()) Assert.IsFalse(KindGuard.IsReadonly(T)) Assert.IsTrue(KindGuard.IsDate(T)) }) it('Should guard for TConst 9', () => { const T = Type.Const(new Uint8Array()) Assert.IsFalse(KindGuard.IsReadonly(T)) Assert.IsTrue(KindGuard.IsUint8Array(T)) }) it('Should guard for TConst 10', () => { const T = Type.Const(function () {}) Assert.IsFalse(KindGuard.IsReadonly(T)) Assert.IsTrue(KindGuard.IsFunction(T)) Assert.IsTrue(T.parameters.length === 0) Assert.IsTrue(KindGuard.IsUnknown(T.returns)) }) it('Should guard for TConst 11', () => { const T = Type.Const(new (class {})()) Assert.IsFalse(KindGuard.IsReadonly(T)) Assert.IsTrue(KindGuard.IsObject(T)) // Object types that are neither Date or Uint8Array evaluate as empty objects Assert.IsEqual(T.properties, {}) }) it('Should guard for TConst 12', () => { const T = Type.Const((function* (): any {})()) const R = ValueGuard.IsIterator((function* (): any {})()) Assert.IsFalse(KindGuard.IsReadonly(T)) Assert.IsTrue(KindGuard.IsAny(T)) }) it('Should guard for TConst 13', () => { const T = Type.Const((async function* (): any {})()) const R = ValueGuard.IsAsyncIterator((function* (): any {})()) Assert.IsFalse(KindGuard.IsReadonly(T)) Assert.IsTrue(KindGuard.IsAny(T)) }) it('Should guard for TConst 14', () => { const T = Type.Const({ x: 1, y: { z: 2, }, } as const) // root Assert.IsFalse(KindGuard.IsReadonly(T)) Assert.IsTrue(KindGuard.IsObject(T)) // x Assert.IsTrue(KindGuard.IsLiteral(T.properties.x)) Assert.IsEqual(T.properties.x.const, 1) // y Assert.IsTrue(KindGuard.IsReadonly(T.properties.y)) Assert.IsTrue(KindGuard.IsObject(T.properties.y)) // y.z Assert.IsTrue(KindGuard.IsReadonly(T.properties.y.properties.z)) Assert.IsTrue(KindGuard.IsLiteral(T.properties.y.properties.z)) Assert.IsEqual(T.properties.y.properties.z.const, 2) }) it('Should guard for TConst 15', () => { const T = Type.Const([1, 2, 3] as const) // root (arrays are always readonly as root) Assert.IsTrue(KindGuard.IsReadonly(T)) Assert.IsTrue(KindGuard.IsTuple(T)) Assert.IsTrue(T.items?.length === 3) // 0 Assert.IsFalse(KindGuard.IsReadonly(T.items![0])) Assert.IsTrue(KindGuard.IsLiteral(T.items![0])) // 1 Assert.IsFalse(KindGuard.IsReadonly(T.items![1])) Assert.IsTrue(KindGuard.IsLiteral(T.items![1])) // 2 Assert.IsFalse(KindGuard.IsReadonly(T.items![2])) Assert.IsTrue(KindGuard.IsLiteral(T.items![2])) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/constructor.ts000066400000000000000000000007021505437577000266660ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TConstructor', () => { it('Should guard for TConstructor', () => { const R = KindGuard.IsConstructor(Type.Constructor([], Type.Number())) Assert.IsTrue(R) }) it('Should not guard for TConstructor', () => { const R = KindGuard.IsConstructor(null) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/date.ts000066400000000000000000000006071505437577000252220ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TDate', () => { it('Should guard for TDate', () => { const R = KindGuard.IsDate(Type.Date()) Assert.IsTrue(R) }) it('Should not guard for TDate', () => { const R = KindGuard.IsDate(null) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/enum.ts000066400000000000000000000101331505437577000252440ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TEnum', () => { // ---------------------------------------------------------------- // Options // ---------------------------------------------------------------- it('Should guard for Options 1', () => { const T = Type.Enum({ x: 1 }, { extra: 'hello', $id: 'T' }) Assert.IsEqual(T.extra, 'hello') Assert.IsEqual(T.$id, 'T') }) it('Should guard for Options 2', () => { enum E { x, } const T = Type.Enum(E, { extra: 'hello', $id: 'T' }) Assert.IsEqual(T.extra, 'hello') Assert.IsEqual(T.$id, 'T') }) it('Should guard for Options 3', () => { enum E {} const T = Type.Enum(E, { extra: 'hello', $id: 'T' }) Assert.IsEqual(T.extra, 'hello') Assert.IsEqual(T.$id, 'T') }) it('Should guard for Options 4', () => { const T = Type.Enum({}, { extra: 'hello', $id: 'T' }) Assert.IsEqual(T.extra, 'hello') Assert.IsEqual(T.$id, 'T') }) // ---------------------------------------------------------------- // Empty // ---------------------------------------------------------------- it('Should guard for Empty 1', () => { const T = Type.Enum({}) Assert.IsTrue(KindGuard.IsNever(T)) }) it('Should guard for Empty 2', () => { enum E {} const T = Type.Enum(E) Assert.IsTrue(KindGuard.IsNever(T)) }) // ---------------------------------------------------------------- // Enum // ---------------------------------------------------------------- it('Should guard for TEnum Enum 0', () => { enum E {} const T = Type.Enum(E) Assert.IsTrue(KindGuard.IsNever(T)) }) it('Should guard for TEnum Enum 1', () => { enum E { A, } const T = Type.Enum(E) Assert.IsTrue(KindGuard.IsLiteral(T)) Assert.IsEqual(T.const, E.A) }) it('Should guard for TEnum Enum 2', () => { enum E { A = 1, B = 2, C = 3, } const T = Type.Enum(E) Assert.IsTrue(KindGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, E.A) Assert.IsEqual(T.anyOf[1].const, E.B) Assert.IsEqual(T.anyOf[2].const, E.C) }) it('Should guard for TEnum Enum 3', () => { enum E { A = 'X', B = 'Y', C = 'Z', } const T = Type.Enum(E) Assert.IsTrue(KindGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, E.A) Assert.IsEqual(T.anyOf[1].const, E.B) Assert.IsEqual(T.anyOf[2].const, E.C) }) it('Should guard for TEnum Enum 4', () => { enum E { A = 'X', B = 'Y', C = 'X', } const T = Type.Enum(E) Assert.IsTrue(KindGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, E.A) Assert.IsEqual(T.anyOf[1].const, E.B) Assert.IsEqual(T.anyOf.length, 2) }) // ---------------------------------------------------------------- // Object Literal // ---------------------------------------------------------------- it('Should guard for TEnum Object Literal 0', () => { const T = Type.Enum({}) Assert.IsTrue(KindGuard.IsNever(T)) }) it('Should guard for TEnum Object Literal 1', () => { const T = Type.Enum({ A: 1 }) Assert.IsTrue(KindGuard.IsLiteral(T)) Assert.IsEqual(T.const, 1) }) it('Should guard for TEnum Object Literal 2', () => { const T = Type.Enum({ A: 1, B: 2, C: 3, }) Assert.IsTrue(KindGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, 1) Assert.IsEqual(T.anyOf[1].const, 2) Assert.IsEqual(T.anyOf[2].const, 3) }) it('Should guard for TEnum Object Literal 3', () => { const T = Type.Enum({ A: 'X', B: 'Y', C: 'Z', }) Assert.IsTrue(KindGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, 'X') Assert.IsEqual(T.anyOf[1].const, 'Y') Assert.IsEqual(T.anyOf[2].const, 'Z') }) it('Should guard for TEnum Object Literal 4', () => { const T = Type.Enum({ A: 'X', B: 'Y', C: 'X', }) Assert.IsTrue(KindGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, 'X') Assert.IsEqual(T.anyOf[1].const, 'Y') Assert.IsEqual(T.anyOf.length, 2) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/exclude.ts000066400000000000000000000114661505437577000257430ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TExclude', () => { it('Should exclude string from number', () => { const T = Type.Exclude(Type.String(), Type.Number()) Assert.IsTrue(KindGuard.IsString(T)) }) it('Should exclude string from string', () => { const T = Type.Exclude(Type.String(), Type.String()) Assert.IsTrue(KindGuard.IsNever(T)) }) it('Should exclude string | number | boolean from string', () => { const T = Type.Exclude(Type.Union([Type.String(), Type.Number(), Type.Boolean()]), Type.String()) Assert.IsTrue(KindGuard.IsUnion(T)) Assert.IsTrue(KindGuard.IsNumber(T.anyOf[0])) Assert.IsTrue(KindGuard.IsBoolean(T.anyOf[1])) }) it('Should exclude string | number | boolean from string | boolean', () => { const T = Type.Exclude(Type.Union([Type.String(), Type.Number(), Type.Boolean()]), Type.Union([Type.String(), Type.Boolean()])) Assert.IsTrue(KindGuard.IsNumber(T)) }) // ------------------------------------------------------------------------ // TemplateLiteral | TemplateLiteral // ------------------------------------------------------------------------ it('Should exclude TemplateLiteral | TemplateLiteral 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const T = Type.Exclude(A, B) Assert.IsTrue(KindGuard.IsNever(T)) }) it('Should exclude TemplateLiteral | TemplateLiteral 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])]) const T = Type.Exclude(A, B) Assert.IsTrue(['C'].includes(T.const)) }) it('Should exclude TemplateLiteral | TemplateLiteral 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A')])]) const T = Type.Exclude(A, B) Assert.IsTrue(['C', 'B'].includes(T.anyOf[0].const)) Assert.IsTrue(['C', 'B'].includes(T.anyOf[1].const)) }) // ------------------------------------------------------------------------ // TemplateLiteral | Union 1 // ------------------------------------------------------------------------ it('Should exclude TemplateLiteral | Union 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const T = Type.Exclude(A, B) Assert.IsTrue(KindGuard.IsNever(T)) }) it('Should exclude TemplateLiteral | Union 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.Union([Type.Literal('A'), Type.Literal('B')]) const T = Type.Exclude(A, B) Assert.IsTrue(['C'].includes(T.const)) }) it('Should exclude TemplateLiteral | Union 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.Union([Type.Literal('A')]) const T = Type.Exclude(A, B) Assert.IsTrue(['C', 'B'].includes(T.anyOf[0].const)) Assert.IsTrue(['C', 'B'].includes(T.anyOf[1].const)) }) // ------------------------------------------------------------------------ // Union | TemplateLiteral 1 // ------------------------------------------------------------------------ it('Should exclude Union | TemplateLiteral 1', () => { const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const T = Type.Exclude(A, B) Assert.IsTrue(KindGuard.IsNever(T)) }) it('Should exclude Union | TemplateLiteral 1', () => { const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])]) const T = Type.Exclude(A, B) Assert.IsTrue(['C'].includes(T.const)) }) it('Should exclude Union | TemplateLiteral 1', () => { const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A')])]) const T = Type.Exclude(A, B) Assert.IsTrue(['C', 'B'].includes(T.anyOf[0].const)) Assert.IsTrue(['C', 'B'].includes(T.anyOf[1].const)) }) it('Should exclude with options', () => { const A = Type.String() const B = Type.String() const T = Type.Exclude(A, B, { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/extract.ts000066400000000000000000000123541505437577000257610ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TExtract', () => { it('Should extract string from number', () => { const T = Type.Extract(Type.String(), Type.Number()) Assert.IsTrue(KindGuard.IsNever(T)) }) it('Should extract string from string', () => { const T = Type.Extract(Type.String(), Type.String()) Assert.IsTrue(KindGuard.IsString(T)) }) it('Should extract string | number | boolean from string', () => { const T = Type.Extract(Type.Union([Type.String(), Type.Number(), Type.Boolean()]), Type.String()) Assert.IsTrue(KindGuard.IsString(T)) }) it('Should extract string | number | boolean from string | boolean', () => { const T = Type.Extract(Type.Union([Type.String(), Type.Number(), Type.Boolean()]), Type.Union([Type.String(), Type.Boolean()])) Assert.IsTrue(KindGuard.IsUnion(T)) Assert.IsTrue(KindGuard.IsString(T.anyOf[0])) Assert.IsTrue(KindGuard.IsBoolean(T.anyOf[1])) }) // ------------------------------------------------------------------------ // TemplateLiteral | TemplateLiteral // ------------------------------------------------------------------------ it('Should extract TemplateLiteral | TemplateLiteral 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const T = Type.Extract(A, B) Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[0].const)) Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[1].const)) Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[2].const)) }) it('Should extract TemplateLiteral | TemplateLiteral 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])]) const T = Type.Extract(A, B) Assert.IsTrue(['A', 'B'].includes(T.anyOf[0].const)) Assert.IsTrue(['A', 'B'].includes(T.anyOf[1].const)) }) it('Should extract TemplateLiteral | TemplateLiteral 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A')])]) const T = Type.Extract(A, B) Assert.IsTrue(['A'].includes(T.const)) }) // ------------------------------------------------------------------------ // TemplateLiteral | Union 1 // ------------------------------------------------------------------------ it('Should extract TemplateLiteral | Union 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const T = Type.Extract(A, B) Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[0].const)) Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[1].const)) Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[2].const)) }) it('Should extract TemplateLiteral | Union 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.Union([Type.Literal('A'), Type.Literal('B')]) const T = Type.Extract(A, B) Assert.IsTrue(['A', 'B'].includes(T.anyOf[0].const)) Assert.IsTrue(['A', 'B'].includes(T.anyOf[1].const)) }) it('Should extract TemplateLiteral | Union 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.Union([Type.Literal('A')]) const T = Type.Extract(A, B) Assert.IsTrue(['A'].includes(T.const)) }) // ------------------------------------------------------------------------ // Union | TemplateLiteral 1 // ------------------------------------------------------------------------ it('Should extract Union | TemplateLiteral 1', () => { const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const T = Type.Extract(A, B) Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[0].const)) Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[1].const)) Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[2].const)) }) it('Should extract Union | TemplateLiteral 1', () => { const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])]) const T = Type.Extract(A, B) Assert.IsTrue(['A', 'B'].includes(T.anyOf[0].const)) Assert.IsTrue(['A', 'B'].includes(T.anyOf[1].const)) }) it('Should extract Union | TemplateLiteral 1', () => { const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A')])]) const T = Type.Extract(A, B) Assert.IsTrue(['A'].includes(T.const)) }) it('Should extract with options', () => { const A = Type.String() const B = Type.String() const T = Type.Extract(A, B, { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/function.ts000066400000000000000000000006601505437577000261310ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TFunction', () => { it('Should guard for TFunction', () => { const R = KindGuard.IsFunction(Type.Function([], Type.Number())) Assert.IsTrue(R) }) it('Should not guard for TFunction', () => { const R = KindGuard.IsFunction(null) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/import.ts000066400000000000000000000265031505437577000256220ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TImport', () => { it('Should guard for TImport', () => { const Module = Type.Module({ A: Type.String(), }) const A = Module.Import('A') const N = A.$defs[A.$ref] Assert.IsTrue(KindGuard.IsImport(A)) Assert.IsTrue(KindGuard.IsString(N)) }) // ---------------------------------------------------------------- // Computed: Options // ---------------------------------------------------------------- it('Should guard for TImport with Options 1', () => { const Module = Type.Module({ A: Type.String(), }) const A = Module.Import('A', { format: 'string' }) const N = A.$defs[A.$ref] Assert.IsTrue(KindGuard.IsImport(A)) Assert.IsTrue(KindGuard.IsString(N)) Assert.IsTrue(N.format === 'string') }) it('Should guard for TImport with Options 2', () => { const Module = Type.Module({ R: Type.Object({ x: Type.Number() }), A: Type.Ref('R'), }) const A = Module.Import('A', { test: 'test' }) const N = A.$defs[A.$ref] Assert.IsTrue(KindGuard.IsImport(A)) Assert.IsTrue(KindGuard.IsRef(N)) Assert.IsTrue(N.test === 'test') }) it('Should guard for TImport with Options 3', () => { const Module = Type.Module({ R: Type.Object({ x: Type.Number() }), A: Type.Partial(Type.Ref('R')), }) const A = Module.Import('A', { additionalProperties: false }) const N = A.$defs[A.$ref] Assert.IsTrue(KindGuard.IsImport(A)) Assert.IsTrue(KindGuard.IsObject(N)) Assert.IsTrue(N.additionalProperties === false) }) // ---------------------------------------------------------------- // Computed: Awaited // ---------------------------------------------------------------- it('Should compute for Awaited', () => { const Module = Type.Module({ T: Type.Promise(Type.String()), R: Type.Awaited(Type.Ref('T')), }) const T = Module.Import('R') Assert.IsTrue(KindGuard.IsString(T.$defs['R'])) }) // ---------------------------------------------------------------- // Computed: Index (Note: Pending Reimplementation of Index) // ---------------------------------------------------------------- it('Should compute for Index 2', () => { const Module = Type.Module({ T: Type.Object({ x: Type.Number(), y: Type.String() }), I: Type.Literal('x'), R: Type.Index(Type.Ref('T'), Type.Ref('I')) as never, // fail }) const T = Module.Import('R') Assert.IsTrue(KindGuard.IsNumber(T.$defs['R'])) }) // ---------------------------------------------------------------- // Computed: Omit // ---------------------------------------------------------------- it('Should compute for Omit 1', () => { const Module = Type.Module({ T: Type.Object({ x: Type.Number(), y: Type.Number() }), R: Type.Omit(Type.Ref('T'), Type.Literal('x')), }) const T = Module.Import('R') Assert.IsTrue(KindGuard.IsObject(T.$defs['R'])) Assert.IsTrue(KindGuard.IsNumber(T.$defs['R'].properties.y)) // @ts-ignore Assert.IsTrue(T.$defs['R'].properties.x === undefined) }) it('Should compute for Omit 2', () => { const Module = Type.Module({ T: Type.Object({ x: Type.Number(), y: Type.Number() }), K: Type.Literal('x'), R: Type.Omit(Type.Ref('T'), Type.Ref('K')), }) const T = Module.Import('R') Assert.IsTrue(KindGuard.IsObject(T.$defs['R'])) Assert.IsTrue(KindGuard.IsNumber(T.$defs['R'].properties.y)) // @ts-ignore Assert.IsTrue(T.$defs['R'].properties.x === undefined) }) // ---------------------------------------------------------------- // Computed: Partial // ---------------------------------------------------------------- it('Should compute for Partial', () => { const Module = Type.Module({ T: Type.Object({ x: Type.Number() }), R: Type.Partial(Type.Ref('T')), }) const T = Module.Import('R') Assert.IsTrue(KindGuard.IsObject(T.$defs['R'])) Assert.IsTrue(KindGuard.IsNumber(T.$defs['R'].properties.x)) Assert.IsTrue(KindGuard.IsOptional(T.$defs['R'].properties.x)) }) // ---------------------------------------------------------------- // Computed: Pick // ---------------------------------------------------------------- it('Should compute for Pick 1', () => { const Module = Type.Module({ T: Type.Object({ x: Type.Number(), y: Type.Number() }), R: Type.Pick(Type.Ref('T'), Type.Literal('x')), }) const T = Module.Import('R') Assert.IsTrue(KindGuard.IsObject(T.$defs['R'])) Assert.IsTrue(KindGuard.IsNumber(T.$defs['R'].properties.x)) // @ts-ignore Assert.IsTrue(T.$defs['R'].properties.y === undefined) }) it('Should compute for Pick 2', () => { const Module = Type.Module({ T: Type.Object({ x: Type.Number(), y: Type.Number() }), K: Type.Literal('x'), R: Type.Pick(Type.Ref('T'), Type.Ref('K')), }) const T = Module.Import('R') Assert.IsTrue(KindGuard.IsObject(T.$defs['R'])) Assert.IsTrue(KindGuard.IsNumber(T.$defs['R'].properties.x)) // @ts-ignore Assert.IsTrue(T.$defs['R'].properties.y === undefined) }) // ---------------------------------------------------------------- // Computed: Record // ---------------------------------------------------------------- it('Should compute for Record 1', () => { const Module = Type.Module({ T: Type.Object({ x: Type.Number(), y: Type.String() }), R: Type.Record(Type.String(), Type.Ref('T')), }) const T = Module.Import('R') Assert.IsTrue(KindGuard.IsRecord(T.$defs['R'])) // note: TRecord> are not computed. Only the Key is // computed as TypeBox needs to make a deferred call to transform from // TRecord to TObject for finite keys. Assert.IsTrue(KindGuard.IsRef(T.$defs['R'].patternProperties['^(.*)$'])) Assert.IsTrue(T.$defs['R'].patternProperties['^(.*)$'].$ref === 'T') }) it('Should compute for Record 2', () => { const Module = Type.Module({ T: Type.Number(), R: Type.Record(Type.Union([Type.Literal('x'), Type.Literal('y')]), Type.Ref('T')), }) // Retain reference if not computed const T = Module.Import('R') Assert.IsTrue(KindGuard.IsObject(T.$defs['R'])) Assert.IsTrue(KindGuard.IsRef(T.$defs['R'].properties.x)) Assert.IsTrue(KindGuard.IsRef(T.$defs['R'].properties.y)) }) it('Should compute for Record 3', () => { const Module = Type.Module({ T: Type.Object({ x: Type.Number() }), R: Type.Record(Type.Union([Type.Literal('x'), Type.Literal('y')]), Type.Partial(Type.Ref('T'))), }) // Dereference if computed const T = Module.Import('R') Assert.IsTrue(KindGuard.IsObject(T.$defs['R'])) Assert.IsTrue(KindGuard.IsObject(T.$defs['R'].properties.x)) Assert.IsTrue(KindGuard.IsObject(T.$defs['R'].properties.y)) }) // ---------------------------------------------------------------- // Computed: Required // ---------------------------------------------------------------- it('Should compute for Required', () => { const Module = Type.Module({ T: Type.Partial(Type.Object({ x: Type.Number() })), R: Type.Required(Type.Ref('T')), }) const T = Module.Import('R') Assert.IsTrue(KindGuard.IsObject(T.$defs['R'])) Assert.IsTrue(KindGuard.IsNumber(T.$defs['R'].properties.x)) Assert.IsFalse(KindGuard.IsOptional(T.$defs['R'].properties.x)) }) // ---------------------------------------------------------------- // Computed: KeyOf // ---------------------------------------------------------------- it('Should compute for KeyOf', () => { const Module = Type.Module({ T: Type.Object({ x: Type.Number(), y: Type.String() }), R: Type.KeyOf(Type.Ref('T')), }) const T = Module.Import('R') Assert.IsTrue(KindGuard.IsUnion(T.$defs['R'])) Assert.IsTrue(KindGuard.IsLiteral(T.$defs['R'].anyOf[0])) Assert.IsTrue(KindGuard.IsLiteral(T.$defs['R'].anyOf[1])) Assert.IsTrue(T.$defs['R'].anyOf[0].const === 'x') Assert.IsTrue(T.$defs['R'].anyOf[1].const === 'y') }) // ---------------------------------------------------------------- // Modifiers: 1 // ---------------------------------------------------------------- it('Should compute for Modifiers 1', () => { const Module = Type.Module({ T: Type.Object({ x: Type.ReadonlyOptional(Type.Null()), y: Type.Readonly(Type.Null()), z: Type.Optional(Type.Null()), w: Type.Null(), }), }) const T = Module.Import('T') const R = T.$defs[T.$ref] Assert.IsTrue(KindGuard.IsObject(R)) Assert.IsTrue(KindGuard.IsNull(R.properties.x)) Assert.IsTrue(KindGuard.IsReadonly(R.properties.x)) Assert.IsTrue(KindGuard.IsOptional(R.properties.x)) Assert.IsTrue(KindGuard.IsNull(R.properties.y)) Assert.IsTrue(KindGuard.IsReadonly(R.properties.y)) Assert.IsFalse(KindGuard.IsOptional(R.properties.y)) Assert.IsTrue(KindGuard.IsNull(R.properties.z)) Assert.IsTrue(KindGuard.IsOptional(R.properties.z)) Assert.IsFalse(KindGuard.IsReadonly(R.properties.z)) Assert.IsTrue(KindGuard.IsNull(R.properties.w)) Assert.IsFalse(KindGuard.IsOptional(R.properties.w)) Assert.IsFalse(KindGuard.IsReadonly(R.properties.w)) }) // ---------------------------------------------------------------- // Modifiers: 2 // ---------------------------------------------------------------- it('Should compute for Modifiers 2', () => { const Module = Type.Module({ T: Type.Object({ x: Type.ReadonlyOptional(Type.Array(Type.Null())), y: Type.Readonly(Type.Array(Type.Null())), z: Type.Optional(Type.Array(Type.Null())), w: Type.Array(Type.Null()), }), }) const T = Module.Import('T') const R = T.$defs[T.$ref] Assert.IsTrue(KindGuard.IsObject(R)) Assert.IsTrue(KindGuard.IsArray(R.properties.x)) Assert.IsTrue(KindGuard.IsNull(R.properties.x.items)) Assert.IsTrue(KindGuard.IsReadonly(R.properties.x)) Assert.IsTrue(KindGuard.IsOptional(R.properties.x)) Assert.IsTrue(KindGuard.IsArray(R.properties.y)) Assert.IsTrue(KindGuard.IsNull(R.properties.y.items)) Assert.IsTrue(KindGuard.IsReadonly(R.properties.y)) Assert.IsFalse(KindGuard.IsOptional(R.properties.y)) Assert.IsTrue(KindGuard.IsArray(R.properties.z)) Assert.IsTrue(KindGuard.IsNull(R.properties.z.items)) Assert.IsTrue(KindGuard.IsOptional(R.properties.z)) Assert.IsFalse(KindGuard.IsReadonly(R.properties.z)) Assert.IsTrue(KindGuard.IsArray(R.properties.w)) Assert.IsTrue(KindGuard.IsNull(R.properties.w.items)) Assert.IsFalse(KindGuard.IsOptional(R.properties.w)) Assert.IsFalse(KindGuard.IsReadonly(R.properties.w)) }) // ---------------------------------------------------------------- // Modifiers: 3 // ---------------------------------------------------------------- it('Should compute for Modifiers 3', () => { const Module = Type.Module({ T: Type.Object({ x: Type.Array(Type.Null()), }), // Computed Partial U: Type.Partial(Type.Ref('T')), }) const T = Module.Import('U') const R = T.$defs[T.$ref] Assert.IsTrue(KindGuard.IsObject(R)) Assert.IsTrue(KindGuard.IsArray(R.properties.x)) Assert.IsTrue(KindGuard.IsNull(R.properties.x.items)) Assert.IsTrue(KindGuard.IsOptional(R.properties.x)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/index.ts000066400000000000000000000017671505437577000254240ustar00rootroot00000000000000import './any' import './argument' import './array' import './async-iterator' import './awaited' import './bigint' import './boolean' import './capitalize' import './composite' import './computed' import './const' import './constructor' import './date' import './enum' import './exclude' import './extract' import './function' import './import' import './indexed' import './integer' import './intersect' import './iterator' import './keyof' import './kind' import './literal' import './lowercase' import './mapped' import './not' import './null' import './number' import './object' import './omit' import './partial' import './pick' import './promise' import './record' import './recursive' import './ref' import './regexp' import './required' import './rest' import './string' import './symbol' import './template-literal' import './this' import './tuple' import './uint8array' import './uncapitalize' import './undefined' import './union' import './unknown' import './unsafe' import './uppercase' import './void' sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/indexed.ts000066400000000000000000000262171505437577000257320ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TIndex', () => { it('Should Index 1', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), }) const I = Type.Index(T, ['x']) Assert.IsTrue(KindGuard.IsNumber(I)) }) it('Should Index 2', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), }) const I = Type.Index(T, ['x', 'y']) Assert.IsTrue(KindGuard.IsUnion(I)) Assert.IsTrue(KindGuard.IsNumber(I.anyOf[0])) Assert.IsTrue(KindGuard.IsString(I.anyOf[1])) }) it('Should Index 3', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), }) const I = Type.Index(T, Type.KeyOf(T)) Assert.IsTrue(KindGuard.IsUnion(I)) Assert.IsTrue(KindGuard.IsNumber(I.anyOf[0])) Assert.IsTrue(KindGuard.IsString(I.anyOf[1])) }) it('Should Index 4', () => { const T = Type.Object({ ab: Type.Number(), ac: Type.String(), }) const I = Type.Index(T, Type.TemplateLiteral([Type.Literal('a'), Type.Union([Type.Literal('b'), Type.Literal('c')])])) Assert.IsTrue(KindGuard.IsUnion(I)) Assert.IsTrue(KindGuard.IsNumber(I.anyOf[0])) Assert.IsTrue(KindGuard.IsString(I.anyOf[1])) }) it('Should Index 5', () => { const T = Type.Intersect([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.String() })]) const I = Type.Index(T, ['x', 'y']) Assert.IsTrue(KindGuard.IsUnion(I)) Assert.IsTrue(KindGuard.IsNumber(I.anyOf[0])) Assert.IsTrue(KindGuard.IsString(I.anyOf[1])) }) it('Should Index 6', () => { const T = Type.Union([Type.Object({ x: Type.Number() }), Type.Object({ x: Type.String() })]) const I = Type.Index(T, ['x']) Assert.IsTrue(KindGuard.IsUnion(I)) Assert.IsTrue(KindGuard.IsNumber(I.anyOf[0])) Assert.IsTrue(KindGuard.IsString(I.anyOf[1])) }) it('Should Index 7', () => { const T = Type.Array(Type.Null()) const I = Type.Index(T, Type.Number()) Assert.IsTrue(KindGuard.IsNull(I)) }) it('Should Index 6', () => { const T = Type.Tuple([Type.Literal('hello'), Type.Literal('world')]) const I = Type.Index(T, [0]) Assert.IsTrue(KindGuard.IsLiteralString(I)) Assert.IsEqual(I.const, 'hello') }) it('Should Index 8', () => { const T = Type.Tuple([Type.Literal('hello'), Type.Literal('world')]) const I = Type.Index(T, [1]) Assert.IsTrue(KindGuard.IsLiteralString(I)) Assert.IsEqual(I.const, 'world') }) it('Should Index 9', () => { const T = Type.Tuple([Type.Literal('hello'), Type.Literal('world')]) const I = Type.Index(T, [0, 1]) Assert.IsTrue(KindGuard.IsUnion(I)) Assert.IsEqual(I.anyOf[0].const, 'hello') Assert.IsEqual(I.anyOf[1].const, 'world') }) it('Should Index 10', () => { const T = Type.Tuple([Type.Literal('hello'), Type.Literal('world')]) const I = Type.Index(T, [1, 0]) Assert.IsTrue(KindGuard.IsUnion(I)) Assert.IsEqual(I.anyOf[0].const, 'world') Assert.IsEqual(I.anyOf[1].const, 'hello') }) it('Should Index 11', () => { const T = Type.Tuple([Type.Literal('hello'), Type.Literal('world')]) const I = Type.Index(T, [0, 0, 0, 1]) Assert.IsTrue(KindGuard.IsUnion(I)) Assert.IsEqual(I.anyOf[0].const, 'hello') Assert.IsEqual(I.anyOf[1].const, 'hello') Assert.IsEqual(I.anyOf[2].const, 'hello') Assert.IsEqual(I.anyOf[3].const, 'world') }) it('Should Index 12', () => { const T = Type.Tuple([Type.String(), Type.Boolean()]) const I = Type.Index(T, Type.Number()) Assert.IsTrue(KindGuard.IsUnion(I)) Assert.IsTrue(KindGuard.IsString(I.anyOf[0])) Assert.IsTrue(KindGuard.IsBoolean(I.anyOf[1])) }) it('Should Index 13', () => { const T = Type.Tuple([Type.String()]) const I = Type.Index(T, Type.Number()) Assert.IsTrue(KindGuard.IsString(I)) }) it('Should Index 14', () => { const T = Type.Tuple([]) const I = Type.Index(T, Type.Number()) Assert.IsTrue(KindGuard.IsNever(I)) }) it('Should Index 15', () => { const T = Type.Object({ 0: Type.Number(), }) const I = Type.Index(T, Type.Literal(0)) Assert.IsTrue(KindGuard.IsNumber(I)) }) it('Should Index 16', () => { const T = Type.Object({ 0: Type.Number(), }) const I = Type.Index(T, Type.Literal('0')) Assert.IsTrue(KindGuard.IsNumber(I)) }) it('Should Index 17', () => { const T = Type.Object({ '0': Type.Number(), }) const I = Type.Index(T, Type.Literal(0)) Assert.IsTrue(KindGuard.IsNumber(I)) }) it('Should Index 18', () => { const T = Type.Object({ '0': Type.Number(), }) const I = Type.Index(T, Type.Literal('0')) Assert.IsTrue(KindGuard.IsNumber(I)) }) it('Should Index 19', () => { const T = Type.Object({ 0: Type.Number(), 1: Type.String(), 2: Type.Boolean(), }) const I = Type.Index(T, Type.Union([Type.Literal(0), Type.Literal(2)])) Assert.IsTrue(KindGuard.IsUnion(I)) Assert.IsTrue(KindGuard.IsNumber(I.anyOf[0])) Assert.IsTrue(KindGuard.IsBoolean(I.anyOf[1])) }) it('Should Index 20', () => { const T = Type.Object({ 0: Type.Number(), 1: Type.String(), 2: Type.Boolean(), }) const I = Type.Index(T, Type.BigInt()) Assert.IsTrue(KindGuard.IsNever(I)) }) it('Should Index 21', () => { const T = Type.Object({ 0: Type.Number(), 1: Type.String(), 2: Type.Boolean(), }) const I = Type.Index(T, Type.Object({})) Assert.IsTrue(KindGuard.IsNever(I)) }) it('Should Index 22', () => { const A = Type.Object({ x: Type.Literal('A') }) const B = Type.Object({ x: Type.Literal('B') }) const C = Type.Object({ x: Type.Literal('C') }) const D = Type.Object({ x: Type.Literal('D') }) const T = Type.Intersect([A, B, C, D]) const I = Type.Index(T, ['x']) Assert.IsTrue(KindGuard.IsIntersect(I)) Assert.IsTrue(KindGuard.IsLiteral(I.allOf[0])) Assert.IsTrue(KindGuard.IsLiteral(I.allOf[1])) Assert.IsTrue(KindGuard.IsLiteral(I.allOf[2])) Assert.IsTrue(KindGuard.IsLiteral(I.allOf[3])) }) it('Should Index 23', () => { const A = Type.Object({ x: Type.Literal('A') }) const B = Type.Object({ x: Type.Literal('B') }) const C = Type.Object({ x: Type.Literal('C') }) const D = Type.Object({ x: Type.Literal('D') }) const T = Type.Union([A, B, C, D]) const I = Type.Index(T, ['x']) Assert.IsTrue(KindGuard.IsUnion(I)) Assert.IsTrue(KindGuard.IsLiteral(I.anyOf[0])) Assert.IsTrue(KindGuard.IsLiteral(I.anyOf[1])) Assert.IsTrue(KindGuard.IsLiteral(I.anyOf[2])) Assert.IsTrue(KindGuard.IsLiteral(I.anyOf[3])) }) it('Should Index 24', () => { const A = Type.Object({ x: Type.Literal('A'), y: Type.Number() }) const B = Type.Object({ x: Type.Literal('B') }) const C = Type.Object({ x: Type.Literal('C') }) const D = Type.Object({ x: Type.Literal('D') }) const T = Type.Intersect([A, B, C, D]) const I = Type.Index(T, ['x', 'y']) Assert.IsTrue(KindGuard.IsUnion(I)) Assert.IsTrue(KindGuard.IsIntersect(I.anyOf[0])) Assert.IsTrue(KindGuard.IsNumber(I.anyOf[1])) }) it('Should Index 25', () => { const A = Type.Object({ x: Type.Literal('A'), y: Type.Number() }) const B = Type.Object({ x: Type.Literal('B'), y: Type.String() }) const C = Type.Object({ x: Type.Literal('C') }) const D = Type.Object({ x: Type.Literal('D') }) const T = Type.Intersect([A, B, C, D]) const I = Type.Index(T, ['x', 'y']) Assert.IsTrue(KindGuard.IsUnion(I)) Assert.IsTrue(KindGuard.IsIntersect(I.anyOf[0])) Assert.IsTrue(KindGuard.IsIntersect(I.anyOf[1])) Assert.IsTrue(KindGuard.IsNumber(I.anyOf[1].allOf[0])) Assert.IsTrue(KindGuard.IsString(I.anyOf[1].allOf[1])) }) it('Should Index 26', () => { const T = Type.Recursive((This) => Type.Object({ x: Type.String(), y: Type.Number(), z: This, }), ) const I = Type.Index(T, ['x', 'y', 'z']) Assert.IsTrue(KindGuard.IsUnion(I)) Assert.IsTrue(KindGuard.IsString(I.anyOf[0])) Assert.IsTrue(KindGuard.IsNumber(I.anyOf[1])) Assert.IsTrue(KindGuard.IsThis(I.anyOf[2])) }) it('Should Index 27', () => { const T = Type.Object({ 0: Type.String(), 1: Type.Number(), }) const I = Type.Index(T, [0, 1]) Assert.IsTrue(KindGuard.IsUnion(I)) Assert.IsTrue(KindGuard.IsString(I.anyOf[0])) Assert.IsTrue(KindGuard.IsNumber(I.anyOf[1])) }) it('Should Index 28', () => { const T = Type.Object({ 0: Type.String(), '1': Type.Number(), }) const I = Type.Index(T, [0, '1']) Assert.IsTrue(KindGuard.IsUnion(I)) Assert.IsTrue(KindGuard.IsString(I.anyOf[0])) Assert.IsTrue(KindGuard.IsNumber(I.anyOf[1])) }) it('Should Index 29', () => { const T = Type.Object({ 0: Type.String(), '1': Type.Number(), }) const I = Type.Index(T, Type.Union([Type.Literal(0), Type.Literal('1')])) Assert.IsTrue(KindGuard.IsUnion(I)) Assert.IsTrue(KindGuard.IsString(I.anyOf[0])) Assert.IsTrue(KindGuard.IsNumber(I.anyOf[1])) }) it('Should Index 30', () => { const T = Type.Object({ 0: Type.String(), '1': Type.Number(), }) const I = Type.Index(T, Type.Union([Type.Literal(0), Type.Literal(1)])) Assert.IsTrue(KindGuard.IsUnion(I)) Assert.IsTrue(KindGuard.IsString(I.anyOf[0])) Assert.IsTrue(KindGuard.IsNumber(I.anyOf[1])) // Note: Expect TNever for anyOf[1] but permit for TNumber due to IndexedAccess // Resolve() which currently cannot differentiate between string and numeric keys // on the object. This may be resolvable in later revisions, but test for this // fall-through to ensure case is documented. For review. }) // -------------------------------------------------------- // Modifier Optional Indexing // -------------------------------------------------------- it('Should Index 31', () => { const T = Type.Object({ x: Type.Optional(Type.String()), y: Type.Number(), }) const I = Type.Index(T, ['x']) Assert.IsTrue(KindGuard.IsOptional(I)) Assert.IsTrue(KindGuard.IsString(I)) }) it('Should Index 32', () => { const T = Type.Object({ x: Type.Optional(Type.String()), y: Type.Number(), }) const I = Type.Index(T, ['y']) Assert.IsFalse(KindGuard.IsOptional(I)) Assert.IsTrue(KindGuard.IsNumber(I)) }) it('Should Index 33', () => { const T = Type.Object({ x: Type.Optional(Type.String()), y: Type.Number(), }) const I = Type.Index(T, ['x', 'y']) Assert.IsTrue(KindGuard.IsOptional(I)) Assert.IsTrue(KindGuard.IsUnion(I)) Assert.IsTrue(KindGuard.IsString(I.anyOf[0])) Assert.IsTrue(KindGuard.IsNumber(I.anyOf[1])) }) it('Should Index 34', () => { const T = Type.String() const I = Type.Index(T, ['x']) Assert.IsTrue(KindGuard.IsNever(I)) }) it('Should Index 35', () => { const T = Type.Array(Type.String()) const I = Type.Index(T, Type.Number()) Assert.IsTrue(KindGuard.IsString(I)) }) it('Should Index 36', () => { const T = Type.Array(Type.String()) const I = Type.Index(T, ['[number]']) Assert.IsTrue(KindGuard.IsString(I)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/integer.ts000066400000000000000000000006311505437577000257370ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TInteger', () => { it('Should guard for TInteger', () => { const R = KindGuard.IsInteger(Type.Integer()) Assert.IsTrue(R) }) it('Should not guard for TInteger', () => { const R = KindGuard.IsInteger(null) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/intersect.ts000066400000000000000000000016601505437577000263050ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TIntersect', () => { it('Should guard for TIntersect', () => { const R = KindGuard.IsIntersect( Type.Intersect([ Type.Object({ x: Type.Number(), }), Type.Object({ y: Type.Number(), }), ]), ) Assert.IsTrue(R) }) it('Should not guard for TIntersect', () => { const R = KindGuard.IsIntersect( Type.Union([ Type.Object({ x: Type.Number(), }), Type.Object({ y: Type.Number(), }), ]), ) Assert.IsFalse(R) }) it('Should throw for intersected transform types', () => { const N = Type.Transform(Type.Number()) .Decode((value) => value) .Encode((value) => value) Assert.Throws(() => Type.Intersect([N, N])) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/iterator.ts000066400000000000000000000007111505437577000261320ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TIterator', () => { it('Should guard for TIterator', () => { const T = Type.Iterator(Type.Any()) const R = KindGuard.IsIterator(T) Assert.IsTrue(R) }) it('Should not guard for TIterator', () => { const T = null const R = KindGuard.IsIterator(T) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/keyof.ts000066400000000000000000000040121505437577000254140ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TKeyOf', () => { it('Should KeyOf 1', () => { const T = Type.Object({ x: Type.Number(), y: Type.Number(), }) const K = Type.KeyOf(T) Assert.IsTrue(KindGuard.IsUnion(K)) Assert.IsTrue(KindGuard.IsLiteral(K.anyOf[0])) Assert.IsTrue(KindGuard.IsLiteral(K.anyOf[1])) }) it('Should KeyOf 2', () => { const T = Type.Recursive((Self) => Type.Object({ x: Type.Number(), y: Type.Array(Self), }), ) const K = Type.KeyOf(T) Assert.IsTrue(KindGuard.IsUnion(K)) Assert.IsTrue(KindGuard.IsLiteral(K.anyOf[0])) Assert.IsTrue(KindGuard.IsLiteral(K.anyOf[1])) }) it('Should KeyOf 3', () => { const T = Type.Intersect([ Type.Object({ x: Type.Number(), }), Type.Object({ y: Type.Number(), }), ]) const K = Type.KeyOf(T) Assert.IsTrue(KindGuard.IsUnion(K)) Assert.IsTrue(KindGuard.IsLiteral(K.anyOf[0])) Assert.IsTrue(KindGuard.IsLiteral(K.anyOf[1])) }) it('Should KeyOf 4', () => { const T = Type.Union([ Type.Object({ x: Type.Number(), }), Type.Object({ y: Type.Number(), }), ]) const K = Type.KeyOf(T) Assert.IsTrue(KindGuard.IsNever(K)) }) it('Should KeyOf 5', () => { const T = Type.Null() const K = Type.KeyOf(T) Assert.IsTrue(KindGuard.IsNever(K)) }) it('Should KeyOf 6', () => { const T = Type.Array(Type.Number()) const K = Type.KeyOf(T) Assert.IsTrue(KindGuard.IsNumber(K)) }) it('Should KeyOf 7', () => { const T = Type.Tuple([]) const K = Type.KeyOf(T) Assert.IsTrue(KindGuard.IsNever(K)) }) it('Should KeyOf 8', () => { const T = Type.Tuple([Type.Number(), Type.Null()]) const K = Type.KeyOf(T) Assert.IsTrue(KindGuard.IsUnion(K)) Assert.IsEqual(K.anyOf[0].const, '0') Assert.IsEqual(K.anyOf[1].const, '1') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/kind.ts000066400000000000000000000005251505437577000252310ustar00rootroot00000000000000import { KindGuard, Kind } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TKind', () => { it('Should guard 1', () => { const T = { [Kind]: 'Kind' } Assert.IsTrue(KindGuard.IsKind(T)) }) it('Should guard 2', () => { const T = {} Assert.IsFalse(KindGuard.IsKind(T)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/literal.ts000066400000000000000000000011001505437577000257260ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TLiteral', () => { it('Should guard for TLiteral of String', () => { const R = KindGuard.IsLiteral(Type.Literal('hello')) Assert.IsTrue(R) }) it('Should guard for TLiteral of Number', () => { const R = KindGuard.IsLiteral(Type.Literal(42)) Assert.IsTrue(R) }) it('Should guard for TLiteral of Boolean', () => { const R = KindGuard.IsLiteral(Type.Literal(true)) Assert.IsTrue(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/lowercase.ts000066400000000000000000000025171505437577000262730ustar00rootroot00000000000000import { KindGuard, Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/Lowercase', () => { it('Should guard for Lowercase 1', () => { const T = Type.Lowercase(Type.Literal('HELLO'), { $id: 'hello', foo: 1 }) Assert.IsTrue(KindGuard.IsLiteral(T)) Assert.IsEqual(T.const, 'hello') Assert.IsEqual(T.$id, 'hello') Assert.IsEqual(T.foo, 1) }) it('Should guard for Lowercase 2', () => { const T = Type.Lowercase(Type.Literal('HELLO')) Assert.IsTrue(KindGuard.IsLiteral(T)) Assert.IsEqual(T.const, 'hello') }) it('Should guard for Lowercase 3', () => { const T = Type.Lowercase(Type.Union([Type.Literal('HELLO'), Type.Literal('WORLD')])) Assert.IsTrue(KindGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, 'hello') Assert.IsEqual(T.anyOf[1].const, 'world') }) it('Should guard for Lowercase 4', () => { const T = Type.Lowercase(Type.TemplateLiteral('HELLO${0|1}')) Assert.IsTrue(KindGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(hello0|hello1)$') }) it('Should guard for Lowercase 5', () => { const T = Type.Lowercase(Type.TemplateLiteral([Type.Literal('HELLO'), Type.Union([Type.Literal(0), Type.Literal(1)])])) Assert.IsTrue(KindGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(hello0|hello1)$') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/mapped.ts000066400000000000000000000450251505437577000255560ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' // prettier-ignore describe('guard/kind/Mapped', () => { it('Should guard mapped 1', () => { const T = Type.Mapped(Type.Union([ Type.Literal('x'), Type.Literal('y'), Type.Literal('z'), ]), _ => Type.Number(), { custom: 1 }) Assert.IsEqual(T, Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number() }, { custom: 1 })) }) it('Should guard mapped 2', () => { const T = Type.Mapped(Type.Union([ Type.Literal('x'), Type.Literal('y'), Type.Literal('z'), ]), _ => Type.Number()) Assert.IsEqual(T, Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number() })) }) it('Should guard mapped 3', () => { const T = Type.Mapped(Type.Union([ Type.Literal('x'), Type.Literal('y'), Type.Literal('z'), ]), K => K) Assert.IsEqual(T, Type.Object({ x: Type.Literal('x'), y: Type.Literal('y'), z: Type.Literal('z'), })) }) it('Should guard mapped 4', () => { const T = Type.Mapped(Type.TemplateLiteral('${0|1}${0|1}'), K => Type.Number()) Assert.IsEqual(T, Type.Object({ '00': Type.Number(), '01': Type.Number(), '10': Type.Number(), '11': Type.Number(), })) }) it('Should guard mapped 5', () => { const T = Type.Mapped(Type.TemplateLiteral('${a|b}'), X => Type.Mapped(Type.TemplateLiteral('${c|d}'), Y => Type.Mapped(Type.TemplateLiteral('${e|f}'), Z => Type.Tuple([X, Y, Z]) ) ) ) Assert.IsEqual(T, Type.Object({ a: Type.Object({ c: Type.Object({ e: Type.Tuple([Type.Literal("a"), Type.Literal("c"), Type.Literal("e")]), f: Type.Tuple([Type.Literal("a"), Type.Literal("c"), Type.Literal("f")]) }), d: Type.Object({ e: Type.Tuple([Type.Literal("a"), Type.Literal("d"), Type.Literal("e")]), f: Type.Tuple([Type.Literal("a"), Type.Literal("d"), Type.Literal("f")]) }), }), b: Type.Object({ c: Type.Object({ e: Type.Tuple([Type.Literal("b"), Type.Literal("c"), Type.Literal("e")]), f: Type.Tuple([Type.Literal("b"), Type.Literal("c"), Type.Literal("f")]) }), d: Type.Object({ e: Type.Tuple([Type.Literal("b"), Type.Literal("d"), Type.Literal("e")]), f: Type.Tuple([Type.Literal("b"), Type.Literal("d"), Type.Literal("f")]) }), }), })) }) it('Should guard mapped 6', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), z: Type.Boolean() }) const M = Type.Mapped(Type.KeyOf(T), K => K) Assert.IsEqual(M, Type.Object({ x: Type.Literal('x'), y: Type.Literal('y'), z: Type.Literal('z') })) }) it('Should guard mapped 7', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), z: Type.Boolean() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.Index(T, K)) Assert.IsEqual(M, Type.Object({ x: Type.Number(), y: Type.String(), z: Type.Boolean() })) }) it('Should guard mapped 8', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), z: Type.Boolean() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.Index(T, K, { custom: 1 })) Assert.IsEqual(M, Type.Object({ x: Type.Number({ custom: 1 }), y: Type.String({ custom: 1 }), z: Type.Boolean({ custom: 1 }) })) }) // ---------------------------------------------------------------- // Extract // ---------------------------------------------------------------- it('Should guard mapped 9', () => { const T = Type.Object({ x: Type.Union([Type.String(), Type.Number(), Type.Boolean()]) }) const M = Type.Mapped(Type.KeyOf(T), K => { return Type.Extract(Type.Index(T, K), Type.String()) }) Assert.IsEqual(M, Type.Object({ x: Type.String() })) }) it('Should guard mapped 10', () => { const T = Type.Object({ x: Type.Union([Type.String(), Type.Number(), Type.Boolean()]) }) const M = Type.Mapped(Type.KeyOf(T), K => { return Type.Extract(Type.Index(T, K), Type.Union([ Type.String(), Type.Number() ])) }) Assert.IsEqual(M, Type.Object({ x: Type.Union([Type.String(), Type.Number()]) })) }) it('Should guard mapped 11', () => { const T = Type.Object({ x: Type.Union([Type.String(), Type.Number(), Type.Boolean()]) }) const M = Type.Mapped(Type.KeyOf(T), K => { return Type.Extract(Type.Index(T, K), Type.Null()) }) Assert.IsEqual(M, Type.Object({ x: Type.Never() })) }) // ---------------------------------------------------------------- // Extends // ---------------------------------------------------------------- it('Should guard mapped 12', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), z: Type.Boolean() }) const M = Type.Mapped(Type.KeyOf(T), K => { return ( Type.Extends(K, Type.Literal('x'), Type.Literal(1), Type.Extends(K, Type.Literal('y'), Type.Literal(2), Type.Extends(K, Type.Literal('z'), Type.Literal(3), Type.Never()))) ) }) Assert.IsEqual(M, Type.Object({ x: Type.Literal(1), y: Type.Literal(2), z: Type.Literal(3), })) }) it('Should guard mapped 13', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), z: Type.Boolean() }) const M = Type.Mapped(Type.KeyOf(T), K => { return ( Type.Extends(Type.Index(T, K), Type.Number(), Type.Literal(3), Type.Extends(Type.Index(T, K), Type.String(), Type.Literal(2), Type.Extends(Type.Index(T, K), Type.Boolean(), Type.Literal(1), Type.Never()))) ) }) Assert.IsEqual(M, Type.Object({ x: Type.Literal(3), y: Type.Literal(2), z: Type.Literal(1), })) }) // ---------------------------------------------------------------- // Exclude // ---------------------------------------------------------------- it('Should guard mapped 14', () => { const T = Type.Object({ x: Type.Union([Type.String(), Type.Number(), Type.Boolean()]) }) const M = Type.Mapped(Type.KeyOf(T), K => { return Type.Exclude(Type.Index(T, K), Type.String()) }) Assert.IsEqual(M, Type.Object({ x: Type.Union([Type.Number(), Type.Boolean()]) })) }) it('Should guard mapped 15', () => { const T = Type.Object({ x: Type.Union([Type.String(), Type.Number(), Type.Boolean()]) }) const M = Type.Mapped(Type.KeyOf(T), K => { return Type.Exclude(Type.Index(T, K), Type.Union([ Type.String(), Type.Number() ])) }) Assert.IsEqual(M, Type.Object({ x: Type.Boolean() })) }) it('Should guard mapped 16', () => { const T = Type.Object({ x: Type.Union([Type.String(), Type.Number(), Type.Boolean()]) }) const M = Type.Mapped(Type.KeyOf(T), K => { return Type.Exclude(Type.Index(T, K), Type.Null()) }) Assert.IsEqual(M, Type.Object({ x: Type.Union([Type.String(), Type.Number(), Type.Boolean()]) })) }) // ---------------------------------------------------------------- // Non-Evaluated // ---------------------------------------------------------------- it('Should guard mapped 17', () => { const T = Type.Object({ x: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.Array(Type.Index(T, K))) Assert.IsEqual(M, Type.Object({ x: Type.Array(Type.Number()) })) }) it('Should guard mapped 18', () => { const T = Type.Object({ x: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.Promise(Type.Index(T, K))) Assert.IsEqual(M, Type.Object({ x: Type.Promise(Type.Number()) })) }) it('Should guard mapped 19', () => { const T = Type.Object({ x: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.Function([Type.Index(T, K)], Type.Index(T, K))) Assert.IsEqual(M, Type.Object({ x: Type.Function([Type.Number()], Type.Number())})) }) it('Should guard mapped 20', () => { const T = Type.Object({ x: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.Tuple([Type.Index(T, K), Type.Index(T, K)])) Assert.IsEqual(M, Type.Object({ x: Type.Tuple([Type.Number(), Type.Number()]) })) }) it('Should guard mapped 21', () => { const T = Type.Object({ x: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.Union([Type.Index(T, K), Type.Index(T, K)])) Assert.IsEqual(M, Type.Object({ x: Type.Union([Type.Number(), Type.Number()]) })) }) it('Should guard mapped 22', () => { const T = Type.Object({ x: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.Intersect([Type.Index(T, K), Type.Index(T, K)])) Assert.IsEqual(M, Type.Object({ x: Type.Intersect([Type.Number(), Type.Number()]) })) }) // ---------------------------------------------------------------- // Numeric Keys // ---------------------------------------------------------------- it('Should guard mapped 23', () => { const T = Type.Object({ 0: Type.Number(), 1: Type.Number(), 2: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), K => K) Assert.IsEqual(M, Type.Object({ 0: Type.Literal('0'), 1: Type.Literal('1'), 2: Type.Literal('2'), })) }) it('Should guard mapped 24', () => { const T = Type.Object({ 0: Type.Number(), 1: Type.Number(), 2: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.Index(T, K)) Assert.IsEqual(M, Type.Object({ 0: Type.Number(), 1: Type.Number(), 2: Type.Number(), })) }) it('Should guard mapped 25', () => { const T = Type.Object({ 0: Type.Number(), 1: Type.Number(), 2: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.String()) Assert.IsEqual(M, Type.Object({ 0: Type.String(), 1: Type.String(), 2: Type.String(), })) }) it('Should guard mapped 26', () => { const T = Type.Object({ 0: Type.Number(), 1: Type.Number(), 2: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.Extends(K, Type.Literal('1'), Type.String(), Type.Number())) Assert.IsEqual(M, Type.Object({ 0: Type.Number(), 1: Type.String(), 2: Type.Number(), })) }) // ---------------------------------------------------------------- // Modifiers: Optional // ---------------------------------------------------------------- it('Should guard mapped 27', () => { const T = Type.Object({ x: Type.Optional(Type.Number()), y: Type.Number() }) // subtractive const M = Type.Mapped(Type.KeyOf(T), K => Type.Optional(Type.Index(T, K), false)) Assert.IsEqual(M, Type.Object({ x: Type.Number(), y: Type.Number() })) }) it('Should guard mapped 28', () => { const T = Type.Object({ x: Type.Optional(Type.Number()), y: Type.Number() }) // additive const M = Type.Mapped(Type.KeyOf(T), K => Type.Optional(Type.Index(T, K), true)) Assert.IsEqual(M, Type.Object({ x: Type.Optional(Type.Number()), y: Type.Optional(Type.Number()) })) }) // ---------------------------------------------------------------- // Modifiers: Readonly // ---------------------------------------------------------------- it('Should guard mapped 27', () => { const T = Type.Object({ x: Type.Readonly(Type.Number()), y: Type.Number() }) // subtractive const M = Type.Mapped(Type.KeyOf(T), K => Type.Readonly(Type.Index(T, K), false)) Assert.IsEqual(M, Type.Object({ x: Type.Number(), y: Type.Number() })) }) it('Should guard mapped 28', () => { const T = Type.Object({ x: Type.Readonly(Type.Number()), y: Type.Number() }) // additive const M = Type.Mapped(Type.KeyOf(T), K => Type.Readonly(Type.Index(T, K), true)) Assert.IsEqual(M, Type.Object({ x: Type.Readonly(Type.Number()), y: Type.Readonly(Type.Number()) })) }) // ---------------------------------------------------------------- // Finite Boolean // ---------------------------------------------------------------- it('Should guard mapped 29', () => { const T = Type.TemplateLiteral('${boolean}') const M = Type.Mapped(T, K => K) Assert.IsEqual(M, Type.Object({ true: Type.Literal('true'), false: Type.Literal('false'), })) }) it('Should guard mapped 30', () => { const T = Type.TemplateLiteral('${0|1}${boolean}') const M = Type.Mapped(T, K => K) Assert.IsEqual(M, Type.Object({ '0true': Type.Literal('0true'), '0false': Type.Literal('0false'), '1true': Type.Literal('1true'), '1false': Type.Literal('1false'), })) }) it('Should guard mapped 31', () => { const T = Type.TemplateLiteral('${boolean}${0|1}') const M = Type.Mapped(T, K => K) Assert.IsEqual(M, Type.Object({ 'true0': Type.Literal('true0'), 'true1': Type.Literal('true1'), 'false0': Type.Literal('false0'), 'false1': Type.Literal('false1'), })) }) // ---------------------------------------------------------------- // Numeric Mapping // ---------------------------------------------------------------- it('Should guard mapped 32', () => { const T = Type.TemplateLiteral([ Type.Union([Type.Literal(0), Type.Literal(1)]), Type.Union([Type.Literal(0), Type.Literal(1)]), ]) const M = Type.Mapped(T, (K) => K) Assert.IsEqual(M, Type.Object({ '00': Type.Literal('00'), '01': Type.Literal('01'), '10': Type.Literal('10'), '11': Type.Literal('11'), })) }) // ---------------------------------------------------------------- // Indexed Key Remap // ---------------------------------------------------------------- it('Should guard mapped 33', () => { const T = Type.Object({ hello: Type.Number(), world: Type.String(), }) const M = Type.Mapped(Type.Uppercase(Type.KeyOf(T)), (K) => { return Type.Index(T, Type.Lowercase(K)) }) Assert.IsEqual(M, Type.Object({ HELLO: Type.Number(), WORLD: Type.String() })) }) // ---------------------------------------------------------------- // Partial // ---------------------------------------------------------------- it('Should guard mapped 34', () => { const T = Type.Object({ x: Type.Object({ x: Type.Number(), y: Type.Number(), }), y: Type.Object({ x: Type.Number(), y: Type.Number(), }), }) const M = Type.Mapped(Type.KeyOf(T), (K) => { return Type.Partial(Type.Index(T, K)) }) Assert.IsEqual(M, Type.Object({ x: Type.Partial(Type.Object({ x: Type.Optional(Type.Number()), y: Type.Optional(Type.Number()), })), y: Type.Partial(Type.Object({ x: Type.Optional(Type.Number()), y: Type.Optional(Type.Number()), })), })) }) // ---------------------------------------------------------------- // Required // ---------------------------------------------------------------- it('Should guard mapped 35', () => { const T = Type.Object({ x: Type.Partial(Type.Object({ x: Type.Number(), y: Type.Number(), })), y: Type.Partial(Type.Object({ x: Type.Number(), y: Type.Number(), })), }) const M = Type.Mapped(Type.KeyOf(T), (K) => { return Type.Required(Type.Index(T, K)) }) Assert.IsEqual(M, Type.Object({ x: Type.Object({ x: Type.Number(), y: Type.Number(), }), y: Type.Object({ x: Type.Number(), y: Type.Number(), }), })) }) // ------------------------------------------------------------------ // Pick With Key // ------------------------------------------------------------------ it('Should guard mapped 36', () => { const T = Type.Object({ x: Type.Object({ x: Type.Number(), y: Type.Number() }), y: Type.Object({ x: Type.Number(), y: Type.Number() }) }) const M = Type.Mapped(Type.KeyOf(T), K => { return Type.Pick(T, K) }) Assert.IsEqual(M, Type.Object({ x: Type.Object({ x: Type.Object({ x: Type.Number(), y: Type.Number(), }) }), y: Type.Object({ y: Type.Object({ x: Type.Number(), y: Type.Number(), }) }), })) }) // ------------------------------------------------------------------ // Pick With Result // ------------------------------------------------------------------ it('Should guard mapped 37', () => { const T = Type.Object({ x: Type.Object({ x: Type.Number(), y: Type.Number(), }), y: Type.Object({ x: Type.Number(), y: Type.Number(), }), }) const M = Type.Mapped(Type.KeyOf(T), (K) => { return Type.Pick(Type.Index(T, K), ['x']) }) Assert.IsEqual(M, Type.Object({ x: Type.Object({ x: Type.Number() }), y: Type.Object({ x: Type.Number() }) })) }) // ------------------------------------------------------------------ // Omit With Key // ------------------------------------------------------------------ it('Should guard mapped 36', () => { const T = Type.Object({ x: Type.Object({ x: Type.Number(), y: Type.Number() }), y: Type.Object({ x: Type.Number(), y: Type.Number() }) }) const M = Type.Mapped(Type.KeyOf(T), K => { return Type.Omit(T, K) }) Assert.IsEqual(M, Type.Object({ x: Type.Object({ y: Type.Object({ x: Type.Number(), y: Type.Number(), }) }), y: Type.Object({ x: Type.Object({ x: Type.Number(), y: Type.Number(), }) }), })) }) // ------------------------------------------------------------------ // Omit With Result // ------------------------------------------------------------------ it('Should guard mapped 37', () => { const T = Type.Object({ x: Type.Object({ x: Type.Number(), y: Type.Number(), }), y: Type.Object({ x: Type.Number(), y: Type.Number(), }), }) const M = Type.Mapped(Type.KeyOf(T), (K) => { return Type.Omit(Type.Index(T, K), ['x']) }) Assert.IsEqual(M, Type.Object({ x: Type.Object({ y: Type.Number() }), y: Type.Object({ y: Type.Number() }) })) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/not.ts000066400000000000000000000004451505437577000251050ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TNot', () => { it('Should guard for TNot', () => { const R = KindGuard.IsNot(Type.Not(Type.String())) Assert.IsTrue(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/null.ts000066400000000000000000000006071505437577000252570ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TNull', () => { it('Should guard for TNull', () => { const R = KindGuard.IsNull(Type.Null()) Assert.IsTrue(R) }) it('Should not guard for TNull', () => { const R = KindGuard.IsNull(null) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/number.ts000066400000000000000000000006231505437577000255730ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TNumber', () => { it('Should guard for TNumber', () => { const R = KindGuard.IsNumber(Type.Number()) Assert.IsTrue(R) }) it('Should not guard for TNumber', () => { const R = KindGuard.IsNumber(null) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/object.ts000066400000000000000000000007351505437577000255550ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TObject', () => { it('Should guard for TObject', () => { const R = KindGuard.IsObject( Type.Object({ x: Type.Number(), y: Type.Number(), }), ) Assert.IsTrue(R) }) it('Should not guard for TObject', () => { const R = KindGuard.IsObject(null) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/omit.ts000066400000000000000000000101011505437577000252430ustar00rootroot00000000000000import { KindGuard, Type, Kind, TransformKind } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TOmit', () => { // ------------------------------------------------------------------------- // case: https://github.com/sinclairzx81/typebox/issues/384 // ------------------------------------------------------------------------- it('Should support TUnsafe omit properties with no Kind', () => { const T = Type.Omit(Type.Object({ x: Type.Unsafe({ x: 1 }), y: Type.Number() }), ['x']) Assert.IsEqual(T.required, ['y']) }) it('Should support TUnsafe omit properties with unregistered Kind', () => { const T = Type.Omit(Type.Object({ x: Type.Unsafe({ x: 1, [Kind]: 'UnknownOmitType' }), y: Type.Number() }), ['x']) Assert.IsEqual(T.required, ['y']) }) // ------------------------------------------------------------------------- // Standard Tests // ------------------------------------------------------------------------- it('Should Omit 1', () => { const T = Type.Omit( Type.Object({ x: Type.Number(), y: Type.Number(), }), ['x'], ) Assert.IsTrue(KindGuard.IsNumber(T.properties.y)) Assert.IsEqual(T.required, ['y']) }) it('Should Omit 2', () => { const T = Type.Omit( Type.Object({ x: Type.Number(), y: Type.Optional(Type.Number()), }), ['x'], ) Assert.IsTrue(KindGuard.IsNumber(T.properties.y)) Assert.IsEqual(T.required, undefined) }) it('Should Omit 3', () => { const L = Type.Literal('x') const T = Type.Omit( Type.Object({ x: Type.Number(), y: Type.Number(), }), L, ) Assert.IsTrue(KindGuard.IsNumber(T.properties.y)) Assert.IsEqual(T.required, ['y']) }) it('Should Omit 4', () => { const L = Type.Literal('x') const T = Type.Omit(Type.Intersect([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })]), L) Assert.IsEqual(KindGuard.IsNumber(T.allOf[1].properties.y), true) // @ts-ignore Assert.IsEqual(T.allOf[1].properties.x, undefined) }) it('Should Omit 5', () => { const L = Type.Union([Type.Literal('x'), Type.Literal('y')]) const T = Type.Omit( Type.Object({ x: Type.Number(), y: Type.Number(), }), L, ) // @ts-ignore Assert.IsEqual(T.properties.x, undefined) // @ts-ignore Assert.IsEqual(T.properties.y, undefined) // @ts-ignore Assert.IsEqual(T.required, undefined) }) it('Should Omit 6', () => { const L = Type.Union([Type.Literal('x'), Type.Literal('y'), Type.Literal('z')]) const T = Type.Omit( Type.Object({ x: Type.Number(), y: Type.Number(), }), L, ) // @ts-ignore Assert.IsEqual(T.properties.x, undefined) // @ts-ignore Assert.IsEqual(T.properties.y, undefined) // @ts-ignore Assert.IsEqual(T.required, undefined) }) it('Should Omit 7', () => { const L = Type.TemplateLiteral([Type.Literal('a'), Type.Union([Type.Literal('b'), Type.Literal('c')])]) const T = Type.Omit( Type.Object({ ab: Type.Number(), ac: Type.Number(), ad: Type.Number(), }), L, ) Assert.IsTrue(KindGuard.IsNumber(T.properties.ad)) Assert.IsEqual(T.required, ['ad']) }) // ---------------------------------------------------------------- // Discard // ---------------------------------------------------------------- it('Should override $id', () => { const A = Type.Object({ x: Type.Number() }, { $id: 'A' }) const T = Type.Omit(A, ['x'], { $id: 'T' }) Assert.IsEqual(T.$id!, 'T') }) it('Should discard $id', () => { const A = Type.Object({ x: Type.Number() }, { $id: 'A' }) const T = Type.Omit(A, ['x']) Assert.IsFalse('$id' in T) }) it('Should discard transform', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), }) const S = Type.Transform(T) .Decode((value) => value) .Encode((value) => value) const R = Type.Omit(S, ['x']) Assert.IsFalse(TransformKind in R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/partial.ts000066400000000000000000000073711505437577000257460ustar00rootroot00000000000000import { KindGuard, TypeRegistry, Type, Kind, TransformKind } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TPartial', () => { it('Should produce a valid TSchema', () => { const T = Type.Partial(Type.Object({ x: Type.Number() })) Assert.IsTrue(KindGuard.IsSchema(T)) }) // ------------------------------------------------------------------------- // case: https://github.com/sinclairzx81/typebox/issues/364 // ------------------------------------------------------------------------- it('Should support TUnsafe partial properties with no Kind', () => { const T = Type.Partial(Type.Object({ x: Type.Unsafe({ x: 1 }) })) Assert.IsEqual(T.required, undefined) }) it('Should support TUnsafe partial properties with unknown Kind', () => { const T = Type.Partial(Type.Object({ x: Type.Unsafe({ [Kind]: 'UnknownPartialType', x: 1 }) })) Assert.IsEqual(T.required, undefined) }) it('Should support TUnsafe partial properties with known Kind', () => { TypeRegistry.Set('KnownPartialType', () => true) const T = Type.Partial(Type.Object({ x: Type.Unsafe({ [Kind]: 'KnownPartialType', x: 1 }) })) Assert.IsEqual(T.required, undefined) }) it('Should support applying partial to intersect', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const I = Type.Intersect([A, B]) const T = Type.Partial(I) Assert.IsEqual(T.allOf.length, 2) Assert.IsEqual(T.allOf[0].required, undefined) Assert.IsEqual(T.allOf[1].required, undefined) }) it('Should support applying partial to union', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const I = Type.Union([A, B]) const T = Type.Partial(I) Assert.IsEqual(T.anyOf.length, 2) Assert.IsEqual(T.anyOf[0].required, undefined) Assert.IsEqual(T.anyOf[1].required, undefined) }) // ---------------------------------------------------------------- // Discard // ---------------------------------------------------------------- it('Should override $id', () => { const A = Type.Object({ x: Type.Number() }, { $id: 'A' }) const T = Type.Partial(A, { $id: 'T' }) Assert.IsEqual(T.$id!, 'T') }) it('Should discard $id', () => { const A = Type.Object({ x: Type.Number() }, { $id: 'A' }) const T = Type.Partial(A) Assert.IsFalse('$id' in T) }) it('Should discard transform', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), }) const S = Type.Transform(T) .Decode((value) => value) .Encode((value) => value) const R = Type.Partial(S) Assert.IsFalse(TransformKind in R) }) // ------------------------------------------------------------------ // Intrinsic Passthough // https://github.com/sinclairzx81/typebox/issues/1169 // ------------------------------------------------------------------ it('Should pass through on intrinsic types on union 1', () => { const T = Type.Partial( Type.Union([ Type.Number(), Type.Object({ x: Type.Number(), }), ]), ) Assert.IsTrue(KindGuard.IsUnion(T)) Assert.IsTrue(KindGuard.IsNumber(T.anyOf[0])) Assert.IsTrue(KindGuard.IsObject(T.anyOf[1])) Assert.IsTrue(KindGuard.IsOptional(T.anyOf[1].properties.x)) }) it('Should pass through on intrinsic types on union 2', () => { const T = Type.Partial( Type.Union([ Type.Literal(1), Type.Object({ x: Type.Number(), }), ]), ) Assert.IsTrue(KindGuard.IsUnion(T)) Assert.IsTrue(KindGuard.IsLiteral(T.anyOf[0])) Assert.IsTrue(KindGuard.IsObject(T.anyOf[1])) Assert.IsTrue(KindGuard.IsOptional(T.anyOf[1].properties.x)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/pick.ts000066400000000000000000000101301505437577000252230ustar00rootroot00000000000000import { KindGuard, Type, Kind, TransformKind } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TPick', () => { // ------------------------------------------------------------------------- // case: https://github.com/sinclairzx81/typebox/issues/384 // ------------------------------------------------------------------------- it('Should support TUnsafe omit properties with no Kind', () => { const T = Type.Pick( Type.Object({ x: Type.Unsafe({ x: 1 }), y: Type.Number(), }), ['x'], ) Assert.IsEqual(T.required, ['x']) }) it('Should support TUnsafe omit properties with unregistered Kind', () => { const T = Type.Pick(Type.Object({ x: Type.Unsafe({ x: 1, [Kind]: 'UnknownPickType' }), y: Type.Number() }), ['x']) Assert.IsEqual(T.required, ['x']) }) // ------------------------------------------------------------------------- // Standard Tests // ------------------------------------------------------------------------- it('Should Pick 1', () => { const T = Type.Pick( Type.Object({ x: Type.Number(), y: Type.Number(), }), ['x'], ) Assert.IsTrue(KindGuard.IsNumber(T.properties.x)) Assert.IsEqual(T.required, ['x']) }) it('Should Pick 2', () => { const T = Type.Pick( Type.Object({ x: Type.Optional(Type.Number()), y: Type.Number(), }), ['x'], ) Assert.IsTrue(KindGuard.IsNumber(T.properties.x)) Assert.IsEqual(T.required, undefined) }) it('Should Pick 3', () => { const L = Type.Literal('x') const T = Type.Pick( Type.Object({ x: Type.Number(), y: Type.Number(), }), L, ) Assert.IsTrue(KindGuard.IsNumber(T.properties.x)) Assert.IsEqual(T.required, ['x']) }) it('Should Pick 4', () => { const L = Type.Literal('x') const T = Type.Pick(Type.Intersect([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })]), L) Assert.IsTrue(KindGuard.IsNumber(T.allOf[0].properties.x)) // @ts-ignore Assert.IsEqual(T.allOf[1].properties.y, undefined) }) it('Should Pick 5', () => { const L = Type.Union([Type.Literal('x'), Type.Literal('y')]) const T = Type.Pick( Type.Object({ x: Type.Number(), y: Type.Number(), }), L, ) Assert.IsTrue(KindGuard.IsNumber(T.properties.x)) Assert.IsTrue(KindGuard.IsNumber(T.properties.y)) Assert.IsEqual(T.required, ['x', 'y']) }) it('Should Pick 6', () => { const L = Type.Union([Type.Literal('x'), Type.Literal('y'), Type.Literal('z')]) const T = Type.Pick( Type.Object({ x: Type.Number(), y: Type.Number(), }), L, ) Assert.IsTrue(KindGuard.IsNumber(T.properties.x)) Assert.IsTrue(KindGuard.IsNumber(T.properties.y)) Assert.IsEqual(T.required, ['x', 'y']) }) it('Should Pick 7', () => { const L = Type.TemplateLiteral([Type.Literal('a'), Type.Union([Type.Literal('b'), Type.Literal('c')])]) const T = Type.Pick( Type.Object({ ab: Type.Number(), ac: Type.Number(), ad: Type.Number(), }), L, ) Assert.IsTrue(KindGuard.IsNumber(T.properties.ab)) Assert.IsTrue(KindGuard.IsNumber(T.properties.ac)) Assert.IsEqual(T.required, ['ab', 'ac']) }) // ---------------------------------------------------------------- // Discard // ---------------------------------------------------------------- it('Should override $id', () => { const A = Type.Object({ x: Type.Number() }, { $id: 'A' }) const T = Type.Pick(A, ['x'], { $id: 'T' }) Assert.IsEqual(T.$id!, 'T') }) it('Should discard $id', () => { const A = Type.Object({ x: Type.Number() }, { $id: 'A' }) const T = Type.Pick(A, ['x']) Assert.IsFalse('$id' in T) }) it('Should discard transform', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), }) const S = Type.Transform(T) .Decode((value) => value) .Encode((value) => value) const R = Type.Pick(S, ['x']) Assert.IsFalse(TransformKind in R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/promise.ts000066400000000000000000000006461505437577000257660ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TPromise', () => { it('Should guard for TPromise', () => { const R = KindGuard.IsPromise(Type.Promise(Type.Number())) Assert.IsTrue(R) }) it('Should not guard for TPromise', () => { const R = KindGuard.IsPromise(null) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/record.ts000066400000000000000000000156571505437577000255760ustar00rootroot00000000000000import { TypeGuard, PatternNumberExact, PatternStringExact, PatternString, PatternNeverExact } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TRecord', () => { // ------------------------------------------------------------- // Overloads // ------------------------------------------------------------- it('Should guard overload 1', () => { const T = Type.Record(Type.Union([Type.Literal('A'), Type.Literal('B')]), Type.String(), { extra: 1 }) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsString(T.properties.A)) Assert.IsTrue(TypeGuard.IsString(T.properties.B)) Assert.IsEqual(T.extra, 1) }) it('Should guard overload 2', () => { const T = Type.Record(Type.Union([Type.Literal('A')]), Type.String(), { extra: 1 }) // unwrap as literal Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsString(T.properties.A)) Assert.IsEqual(T.extra, 1) }) it('Should guard overload 3', () => { // @ts-ignore const N = Type.Union([]) // Never const T = Type.Record(N, Type.String(), { extra: 1 }) Assert.IsTrue(TypeGuard.IsRecord(T)) Assert.IsTrue(TypeGuard.IsString(T.patternProperties[PatternNeverExact])) Assert.IsEqual(T.extra, 1) }) it('Should guard overload 4', () => { // @ts-ignore const T = Type.Record(Type.BigInt(), Type.String(), { extra: 1 }) Assert.IsTrue(TypeGuard.IsNever(T)) }) it('Should guard overload 5', () => { const T = Type.Record(Type.Literal('A'), Type.String(), { extra: 1 }) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsString(T.properties.A)) Assert.IsEqual(T.extra, 1) }) it('Should guard overload 6', () => { const L = Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal('A'), Type.Literal('B')])]) const T = Type.Record(L, Type.String(), { extra: 1 }) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsString(T.properties.helloA)) Assert.IsTrue(TypeGuard.IsString(T.properties.helloB)) Assert.IsEqual(T.extra, 1) }) it('Should guard overload 7', () => { const T = Type.Record(Type.Number(), Type.String(), { extra: 1 }) Assert.IsTrue(TypeGuard.IsRecord(T)) Assert.IsTrue(TypeGuard.IsString(T.patternProperties[PatternNumberExact])) Assert.IsEqual(T.extra, 1) }) it('Should guard overload 8', () => { const T = Type.Record(Type.Integer(), Type.String(), { extra: 1 }) Assert.IsTrue(TypeGuard.IsRecord(T)) Assert.IsTrue(TypeGuard.IsString(T.patternProperties[PatternNumberExact])) Assert.IsEqual(T.extra, 1) }) it('Should guard overload 9', () => { const T = Type.Record(Type.String(), Type.String(), { extra: 1 }) Assert.IsTrue(TypeGuard.IsRecord(T)) Assert.IsTrue(TypeGuard.IsString(T.patternProperties[PatternStringExact])) Assert.IsEqual(T.extra, 1) }) it('Should guard overload 10', () => { const L = Type.TemplateLiteral([Type.String(), Type.Literal('_foo')]) const T = Type.Record(L, Type.String(), { extra: 1 }) Assert.IsTrue(TypeGuard.IsRecord(T)) Assert.IsTrue(TypeGuard.IsString(T.patternProperties[`^${PatternString}_foo$`])) Assert.IsEqual(T.extra, 1) }) it('Should guard overload 11', () => { const L = Type.Union([Type.Literal('A'), Type.Union([Type.Literal('B'), Type.Literal('C')])]) const T = Type.Record(L, Type.String()) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsString(T.properties.A)) Assert.IsTrue(TypeGuard.IsString(T.properties.B)) Assert.IsTrue(TypeGuard.IsString(T.properties.C)) }) it('Should guard overload 12', () => { enum E { A = 'X', B = 'Y', C = 'Z', } const T = Type.Enum(E) const R = Type.Record(T, Type.Null()) Assert.IsTrue(TypeGuard.IsObject(R)) Assert.IsTrue(TypeGuard.IsNull(R.properties.X)) Assert.IsTrue(TypeGuard.IsNull(R.properties.Y)) Assert.IsTrue(TypeGuard.IsNull(R.properties.Z)) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/916 // ---------------------------------------------------------------- it('Should guard overload 13', () => { // @ts-ignore const T = Type.Record(Type.Never(), Type.String(), { extra: 1 }) Assert.IsTrue(TypeGuard.IsRecord(T)) Assert.IsTrue(TypeGuard.IsString(T.patternProperties[PatternNeverExact])) Assert.IsEqual(T.extra, 1) }) it('Should guard overload 14', () => { // @ts-ignore const T = Type.Record(Type.Any(), Type.String(), { extra: 1 }) Assert.IsTrue(TypeGuard.IsRecord(T)) Assert.IsTrue(TypeGuard.IsString(T.patternProperties[PatternStringExact])) Assert.IsEqual(T.extra, 1) }) // ------------------------------------------------------------- // Variants // ------------------------------------------------------------- it('Should guard for TRecord', () => { const R = TypeGuard.IsRecord(Type.Record(Type.String(), Type.Number())) Assert.IsTrue(R) }) it('Should guard for TRecord with TObject value', () => { const R = TypeGuard.IsRecord( Type.Record( Type.String(), Type.Object({ x: Type.Number(), y: Type.Number(), }), ), ) Assert.IsTrue(R) }) it('Should not guard for TRecord', () => { const R = TypeGuard.IsRecord(null) Assert.IsFalse(R) }) it('Should not guard for TRecord with invalid $id', () => { // @ts-ignore const R = TypeGuard.IsRecord(Type.Record(Type.String(), Type.Number(), { $id: 1 })) Assert.IsFalse(R) }) it('Should not guard for TRecord with TObject value with invalid Property', () => { const R = TypeGuard.IsRecord( Type.Record( Type.String(), Type.Object({ x: Type.Number(), y: {} as any, }), ), ) Assert.IsFalse(R) }) it('Normalize: Should should normalize to TObject for single literal union value', () => { const K = Type.Union([Type.Literal('ok')]) const R = TypeGuard.IsObject(Type.Record(K, Type.Number())) Assert.IsTrue(R) }) it('Normalize: Should should normalize to TObject for multi literal union value', () => { const K = Type.Union([Type.Literal('A'), Type.Literal('B')]) const R = TypeGuard.IsObject(Type.Record(K, Type.Number())) Assert.IsTrue(R) }) // ------------------------------------------------------------------ // Evaluated: Dollar Sign Escape // https://github.com/sinclairzx81/typebox/issues/794 // ------------------------------------------------------------------ // prettier-ignore { const K = Type.TemplateLiteral('$prop${A|B|C}') // issue const T = Type.Record(K, Type.String()) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsString(T.properties.$propA)) Assert.IsTrue(TypeGuard.IsString(T.properties.$propB)) Assert.IsTrue(TypeGuard.IsString(T.properties.$propC)) Assert.IsEqual(T.required, ['$propA', '$propB', '$propC']) } }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/recursive.ts000066400000000000000000000011531505437577000263110ustar00rootroot00000000000000import { KindGuard, PatternNumberExact, PatternStringExact, PatternString, PatternNumber } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TRecursive', () => { it('Should guard 1', () => { const T = Type.Recursive((This) => Type.Object({ nodes: This })) Assert.IsTrue(KindGuard.IsRecursive(T)) Assert.IsTrue(KindGuard.IsObject(T)) }) it('Should guard 2', () => { const T = Type.Recursive((This) => Type.Tuple([This])) Assert.IsTrue(KindGuard.IsRecursive(T)) Assert.IsTrue(KindGuard.IsTuple(T)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/ref.ts000066400000000000000000000022661505437577000250640ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TRef', () => { // ---------------------------------------------------------------- // Deprecated // ---------------------------------------------------------------- it('Should guard for Ref(Schema) 1', () => { const T = Type.Number({ $id: 'T' }) const R = Type.Ref(T) Assert.IsTrue(KindGuard.IsRef(R)) Assert.IsTrue(typeof R['$ref'] === 'string') }) it('Should guard for Ref(Schema) 2', () => { const T = Type.Number() Assert.Throws(() => Type.Ref(T)) }) it('Should guard for Ref(Schema) 3', () => { // @ts-ignore const T = Type.Number({ $id: null }) Assert.Throws(() => Type.Ref(T)) }) // ---------------------------------------------------------------- // Standard // ---------------------------------------------------------------- it('Should guard for TRef', () => { const T = Type.Number({ $id: 'T' }) const R = KindGuard.IsRef(Type.Ref(T)) Assert.IsTrue(R) }) it('Should not guard for TRef', () => { const R = KindGuard.IsRef(null) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/regexp.ts000066400000000000000000000011111505437577000255660ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TRegExp', () => { it('Should guard for TRegExp 1', () => { const T = Type.RegExp(/foo/, { $id: 'T' }) Assert.IsTrue(KindGuard.IsSchema(T)) }) it('Should guard for TRegExp 1', () => { const T = Type.RegExp(/foo/, { $id: 'T' }) Assert.IsTrue(KindGuard.IsRegExp(T)) }) it('Should guard for TRegExp 2', () => { const T = Type.RegExp('foo', { $id: 'T' }) Assert.IsTrue(KindGuard.IsRegExp(T)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/required.ts000066400000000000000000000072361505437577000261320ustar00rootroot00000000000000import { KindGuard, TypeRegistry, Type, Kind, TransformKind } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TRequired', () => { it('Should produce a valid TSchema', () => { const T = Type.Required(Type.Object({ x: Type.Number() })) Assert.IsTrue(KindGuard.IsSchema(T)) }) it('Should support TUnsafe required properties with no Kind', () => { const T = Type.Required(Type.Object({ x: Type.Optional(Type.Unsafe({ x: 1 })) })) Assert.IsEqual(T.required, ['x']) }) it('Should support TUnsafe required properties with unknown Kind', () => { const T = Type.Required(Type.Object({ x: Type.Optional(Type.Unsafe({ [Kind]: 'UnknownRequiredType', x: 1 })) })) Assert.IsEqual(T.required, ['x']) }) it('Should support TUnsafe required properties with known Kind', () => { TypeRegistry.Set('KnownRequiredType', () => true) const T = Type.Required(Type.Object({ x: Type.Optional(Type.Unsafe({ [Kind]: 'KnownRequiredType', x: 1 })) })) Assert.IsEqual(T.required, ['x']) }) it('Should support applying required to intersect', () => { const A = Type.Object({ x: Type.Optional(Type.Number()) }) const B = Type.Object({ y: Type.Optional(Type.Number()) }) const I = Type.Intersect([A, B]) const T = Type.Required(I) Assert.IsEqual(T.allOf.length, 2) Assert.IsEqual(T.allOf[0].required, ['x']) Assert.IsEqual(T.allOf[1].required, ['y']) }) it('Should support applying required to union', () => { const A = Type.Object({ x: Type.Optional(Type.Number()) }) const B = Type.Object({ y: Type.Optional(Type.Number()) }) const I = Type.Union([A, B]) const T = Type.Required(I) Assert.IsEqual(T.anyOf.length, 2) Assert.IsEqual(T.anyOf[0].required, ['x']) Assert.IsEqual(T.anyOf[1].required, ['y']) }) // ---------------------------------------------------------------- // Discard // ---------------------------------------------------------------- it('Should override $id', () => { const A = Type.Object({ x: Type.Number() }, { $id: 'A' }) const T = Type.Required(A, { $id: 'T' }) Assert.IsEqual(T.$id!, 'T') }) it('Should discard $id', () => { const A = Type.Object({ x: Type.Number() }, { $id: 'A' }) const T = Type.Required(A) Assert.IsFalse('$id' in T) }) it('Should discard transform', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), }) const S = Type.Transform(T) .Decode((value) => value) .Encode((value) => value) const R = Type.Required(S) Assert.IsFalse(TransformKind in R) }) // ------------------------------------------------------------------ // Intrinsic Passthough // https://github.com/sinclairzx81/typebox/issues/1169 // ------------------------------------------------------------------ it('Should pass through on intrinsic types on union 1', () => { const T = Type.Required( Type.Union([ Type.Number(), Type.Object({ x: Type.Optional(Type.Number()), }), ]), ) Assert.IsTrue(KindGuard.IsUnion(T)) Assert.IsTrue(KindGuard.IsNumber(T.anyOf[0])) Assert.IsTrue(KindGuard.IsObject(T.anyOf[1])) Assert.IsFalse(KindGuard.IsOptional(T.anyOf[1].properties.x)) }) it('Should pass through on intrinsic types on union 2', () => { const T = Type.Required( Type.Union([ Type.Literal(1), Type.Object({ x: Type.Optional(Type.Number()), }), ]), ) Assert.IsTrue(KindGuard.IsUnion(T)) Assert.IsTrue(KindGuard.IsLiteral(T.anyOf[0])) Assert.IsTrue(KindGuard.IsObject(T.anyOf[1])) Assert.IsFalse(KindGuard.IsOptional(T.anyOf[1].properties.x)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/rest.ts000066400000000000000000000040441505437577000252610ustar00rootroot00000000000000import { Type, KindGuard } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TRest', () => { it('Should guard 1', () => { // union never const A = Type.String() const B = Type.Union(Type.Rest(A)) Assert.IsTrue(KindGuard.IsNever(B)) }) it('Should guard 2', () => { // intersect never const A = Type.String() const B = Type.Intersect(Type.Rest(A)) Assert.IsTrue(KindGuard.IsNever(B)) }) it('Should guard 3', () => { // tuple const A = Type.Tuple([Type.Number(), Type.String()]) const B = Type.Union(Type.Rest(A)) Assert.IsTrue(KindGuard.IsUnion(B)) Assert.IsEqual(B.anyOf.length, 2) Assert.IsTrue(KindGuard.IsNumber(B.anyOf[0])) Assert.IsTrue(KindGuard.IsString(B.anyOf[1])) }) it('Should guard 4', () => { // tuple spread const A = Type.Tuple([Type.Literal(1), Type.Literal(2)]) const B = Type.Tuple([Type.Literal(3), Type.Literal(4)]) const C = Type.Tuple([...Type.Rest(A), ...Type.Rest(B)]) Assert.IsTrue(KindGuard.IsTuple(C)) Assert.IsEqual(C.items!.length, 4) Assert.IsEqual(C.items![0].const, 1) Assert.IsEqual(C.items![1].const, 2) Assert.IsEqual(C.items![2].const, 3) Assert.IsEqual(C.items![3].const, 4) }) it('Should guard 5', () => { // union to intersect const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.String() }) const C = Type.Union([A, B]) const D = Type.Intersect(Type.Rest(C)) Assert.IsTrue(KindGuard.IsIntersect(D)) Assert.IsEqual(D.allOf.length, 2) Assert.IsTrue(KindGuard.IsObject(D.allOf[0])) Assert.IsTrue(KindGuard.IsObject(D.allOf[1])) }) it('Should guard 6', () => { // intersect to composite const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.String() }) const C = Type.Intersect([A, B]) const D = Type.Composite(Type.Rest(C)) Assert.IsTrue(KindGuard.IsObject(D)) Assert.IsTrue(KindGuard.IsNumber(D.properties.x)) Assert.IsTrue(KindGuard.IsString(D.properties.y)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/string.ts000066400000000000000000000006231505437577000256110ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TString', () => { it('Should guard for TString', () => { const R = KindGuard.IsString(Type.String()) Assert.IsTrue(R) }) it('Should not guard for TString', () => { const R = KindGuard.IsString(null) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/symbol.ts000066400000000000000000000006231505437577000256100ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TSymbol', () => { it('Should guard for TSymbol', () => { const R = KindGuard.IsSymbol(Type.Symbol()) Assert.IsTrue(R) }) it('Should not guard for TSymbol', () => { const R = KindGuard.IsSymbol(null) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/template-literal.ts000066400000000000000000000025461505437577000275560ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TTemplateLiteral', () => { it('Should guard for empty TemplateLiteral', () => { const R = KindGuard.IsTemplateLiteral(Type.TemplateLiteral([])) Assert.IsTrue(R) }) it('Should guard for TSchema', () => { const R = KindGuard.IsSchema(Type.TemplateLiteral([])) Assert.IsTrue(R) }) it('Should guard for TemplateLiteral (TTemplateLiteral)', () => { const T = Type.TemplateLiteral([Type.Literal('hello')]) const R = KindGuard.IsTemplateLiteral(Type.TemplateLiteral([T, Type.Literal('world')])) Assert.IsTrue(R) }) it('Should guard for TemplateLiteral (TLiteral)', () => { const R = KindGuard.IsTemplateLiteral(Type.TemplateLiteral([Type.Literal('hello')])) Assert.IsTrue(R) }) it('Should guard for TemplateLiteral (TString)', () => { const R = KindGuard.IsTemplateLiteral(Type.TemplateLiteral([Type.String()])) Assert.IsTrue(R) }) it('Should guard for TemplateLiteral (TNumber)', () => { const R = KindGuard.IsTemplateLiteral(Type.TemplateLiteral([Type.Number()])) Assert.IsTrue(R) }) it('Should guard for TemplateLiteral (TBoolean)', () => { const R = KindGuard.IsTemplateLiteral(Type.TemplateLiteral([Type.Boolean()])) Assert.IsTrue(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/this.ts000066400000000000000000000005651505437577000252570ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TThis', () => { it('Should guard for TThis', () => { Type.Recursive((This) => { const R = KindGuard.IsThis(This) Assert.IsTrue(R) return Type.Object({ nodes: Type.Array(This) }) }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/tuple.ts000066400000000000000000000006531505437577000254370ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TTuple', () => { it('Should guard for TTuple', () => { const R = KindGuard.IsTuple(Type.Tuple([Type.Number(), Type.Number()])) Assert.IsTrue(R) }) it('Should not guard for TTuple', () => { const R = KindGuard.IsTuple(null) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/uint8array.ts000066400000000000000000000006531505437577000264140ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TUint8Array', () => { it('Should guard for TUint8Array', () => { const R = KindGuard.IsUint8Array(Type.Uint8Array()) Assert.IsTrue(R) }) it('Should not guard for TUint8Array', () => { const R = KindGuard.IsUint8Array(null) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/uncapitalize.ts000066400000000000000000000025601505437577000267750ustar00rootroot00000000000000import { KindGuard, Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/Uncapitalize', () => { it('Should guard for Uncapitalize 1', () => { const T = Type.Uncapitalize(Type.Literal('HELLO'), { $id: 'hello', foo: 1 }) Assert.IsTrue(KindGuard.IsLiteral(T)) Assert.IsEqual(T.const, 'hELLO') Assert.IsEqual(T.$id, 'hello') Assert.IsEqual(T.foo, 1) }) it('Should guard for Uncapitalize 2', () => { const T = Type.Uncapitalize(Type.Literal('HELLO')) Assert.IsTrue(KindGuard.IsLiteral(T)) Assert.IsEqual(T.const, 'hELLO') }) it('Should guard for Uncapitalize 3', () => { const T = Type.Uncapitalize(Type.Union([Type.Literal('HELLO'), Type.Literal('WORLD')])) Assert.IsTrue(KindGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, 'hELLO') Assert.IsEqual(T.anyOf[1].const, 'wORLD') }) it('Should guard for Uncapitalize 4', () => { const T = Type.Uncapitalize(Type.TemplateLiteral('HELLO${0|1}')) Assert.IsTrue(KindGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(hELLO0|hELLO1)$') }) it('Should guard for Uncapitalize 5', () => { const T = Type.Uncapitalize(Type.TemplateLiteral([Type.Literal('HELLO'), Type.Union([Type.Literal(0), Type.Literal(1)])])) Assert.IsTrue(KindGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(hELLO0|hELLO1)$') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/undefined.ts000066400000000000000000000006451505437577000262500ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TUndefined', () => { it('Should guard for TUndefined', () => { const R = KindGuard.IsUndefined(Type.Undefined()) Assert.IsTrue(R) }) it('Should not guard for TUndefined', () => { const R = KindGuard.IsUndefined(null) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/union.ts000066400000000000000000000023061505437577000254330ustar00rootroot00000000000000import { TSchema, KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TUnion', () => { it('Should guard for TUnion', () => { const R = KindGuard.IsUnion( Type.Union([ Type.Object({ x: Type.Number(), }), Type.Object({ y: Type.Number(), }), ]), ) Assert.IsTrue(R) }) it('Should not guard for TUnion', () => { const R = KindGuard.IsUnion(null) Assert.IsFalse(R) }) it('Transform: Should transform to never for zero length union', () => { const T = Type.Union([]) const R = KindGuard.IsNever(T) Assert.IsTrue(R) }) it('Transform: Should unwrap union type for array of length === 1', () => { const T = Type.Union([Type.String()]) const R = KindGuard.IsString(T) Assert.IsTrue(R) }) it('Transform: Should retain union if array length > 1', () => { const T = Type.Union([Type.String(), Type.Number()]) const R1 = KindGuard.IsUnion(T) const R2 = KindGuard.IsString(T.anyOf[0]) const R3 = KindGuard.IsNumber(T.anyOf[1]) Assert.IsTrue(R1) Assert.IsTrue(R2) Assert.IsTrue(R3) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/unknown.ts000066400000000000000000000006311505437577000260010ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TUnknown', () => { it('Should guard for TUnknown', () => { const R = KindGuard.IsUnknown(Type.Unknown()) Assert.IsTrue(R) }) it('Should not guard for TUnknown', () => { const R = KindGuard.IsUnknown(null) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/unsafe.ts000066400000000000000000000020611505437577000255620ustar00rootroot00000000000000import { Kind, KindGuard, TypeRegistry } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TUnsafe', () => { it('Should guard raw TUnsafe', () => { const T = Type.Unsafe({ x: 1 }) const R = KindGuard.IsUnsafe(T) Assert.IsTrue(R) }) it('Should guard raw TUnsafe as TSchema', () => { const T = Type.Unsafe({ x: 1 }) const R = KindGuard.IsSchema(T) Assert.IsTrue(R) }) it('Should guard override TUnsafe as TSchema when registered', () => { TypeRegistry.Set('UnsafeType', () => true) const T = Type.Unsafe({ [Kind]: 'UnsafeType' }) const R = KindGuard.IsSchema(T) Assert.IsTrue(R) TypeRegistry.Delete('UnsafeType') }) it('Should not guard TUnsafe with unregistered kind', () => { const T = Type.Unsafe({ [Kind]: 'UnsafeType' }) const R = KindGuard.IsUnsafe(T) Assert.IsFalse(R) }) it('Should not guard for TString', () => { const T = Type.String() const R = KindGuard.IsUnsafe(T) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/uppercase.ts000066400000000000000000000025171505437577000262760ustar00rootroot00000000000000import { KindGuard, Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/Uppercase', () => { it('Should guard for Uppercase 1', () => { const T = Type.Uppercase(Type.Literal('hello'), { $id: 'hello', foo: 1 }) Assert.IsTrue(KindGuard.IsLiteral(T)) Assert.IsEqual(T.const, 'HELLO') Assert.IsEqual(T.$id, 'hello') Assert.IsEqual(T.foo, 1) }) it('Should guard for Uppercase 2', () => { const T = Type.Uppercase(Type.Literal('hello')) Assert.IsTrue(KindGuard.IsLiteral(T)) Assert.IsEqual(T.const, 'HELLO') }) it('Should guard for Uppercase 3', () => { const T = Type.Uppercase(Type.Union([Type.Literal('hello'), Type.Literal('world')])) Assert.IsTrue(KindGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, 'HELLO') Assert.IsEqual(T.anyOf[1].const, 'WORLD') }) it('Should guard for Uppercase 4', () => { const T = Type.Uppercase(Type.TemplateLiteral('hello${0|1}')) Assert.IsTrue(KindGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(HELLO0|HELLO1)$') }) it('Should guard for Uppercase 5', () => { const T = Type.Uppercase(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(0), Type.Literal(1)])])) Assert.IsTrue(KindGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(HELLO0|HELLO1)$') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/kind/void.ts000066400000000000000000000006071505437577000252460ustar00rootroot00000000000000import { KindGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/kind/TVoid', () => { it('Should guard for TVoid', () => { const R = KindGuard.IsVoid(Type.Void()) Assert.IsTrue(R) }) it('Should not guard for TVoid', () => { const R = KindGuard.IsVoid(null) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/000077500000000000000000000000001505437577000237665ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/any.ts000066400000000000000000000010351505437577000251240ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TAny', () => { it('Should guard for TAny', () => { const R = TypeGuard.IsAny(Type.Any()) Assert.IsTrue(R) }) it('Should not guard for TAny', () => { const R = TypeGuard.IsAny(null) Assert.IsFalse(R) }) it('Should not guard for TAny with invalid $id', () => { // @ts-ignore const R = TypeGuard.IsAny(Type.Any({ $id: 1 })) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/argument.ts000066400000000000000000000006401505437577000261600ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TArgument', () => { it('Should guard for TArgument', () => { const R = TypeGuard.IsArgument(Type.Argument(0)) Assert.IsTrue(R) }) it('Should not guard for TArgument', () => { const R = TypeGuard.IsArgument(null) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/array.ts000066400000000000000000000031411505437577000254530ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TArray', () => { it('Should guard for TArray', () => { const R = TypeGuard.IsArray(Type.Array(Type.Number())) Assert.IsTrue(R) }) it('Should not guard for TArray', () => { const R = TypeGuard.IsArray(null) Assert.IsFalse(R) }) it('Should guard for nested object TArray', () => { const R = TypeGuard.IsArray( Type.Array( Type.Object({ x: Type.Number(), y: Type.Number(), }), ), ) Assert.IsTrue(R) }) it('Should not guard for nested object TArray', () => { const R = TypeGuard.IsArray( Type.Array( Type.Object({ x: Type.Number(), y: {} as any, }), ), ) Assert.IsFalse(R) }) it('Should not guard for TArray with invalid $id', () => { // @ts-ignore const R = TypeGuard.IsArray(Type.Array(Type.Number(), { $id: 1 })) Assert.IsFalse(R) }) it('Should not guard for TArray with invalid minItems', () => { // @ts-ignore const R = TypeGuard.IsArray(Type.Array(Type.String(), { minItems: '1' })) Assert.IsFalse(R) }) it('Should not guard for TArray with invalid maxItems', () => { // @ts-ignore const R = TypeGuard.IsArray(Type.Array(Type.String(), { maxItems: '1' })) Assert.IsFalse(R) }) it('Should not guard for TArray with invalid uniqueItems', () => { // @ts-ignore const R = TypeGuard.IsArray(Type.Array(Type.String(), { uniqueItems: '1' })) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/async-iterator.ts000066400000000000000000000012741505437577000273060ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TAsyncIterator', () => { it('Should guard for TAsyncIterator', () => { const T = Type.AsyncIterator(Type.Any()) const R = TypeGuard.IsAsyncIterator(T) Assert.IsTrue(R) }) it('Should not guard for TAsyncIterator', () => { const T = null const R = TypeGuard.IsAsyncIterator(T) Assert.IsFalse(R) }) it('Should not guard for TAsyncIterator with invalid $id', () => { //@ts-ignore const T = Type.AsyncIterator(Type.Any(), { $id: 1 }) const R = TypeGuard.IsAsyncIterator(T) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/awaited.ts000066400000000000000000000030701505437577000257540ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/Awaited', () => { it('Should guard for Awaited 1', () => { const T = Type.Awaited(Type.String()) const R = TypeGuard.IsString(T) Assert.IsTrue(R) }) it('Should guard for Awaited 2', () => { const T = Type.Awaited(Type.Promise(Type.String())) const R = TypeGuard.IsString(T) Assert.IsTrue(R) }) it('Should guard for Awaited 3', () => { const T = Type.Awaited(Type.Awaited(Type.Promise(Type.String()))) const R = TypeGuard.IsString(T) Assert.IsTrue(R) }) it('Should guard for Awaited 4', () => { const T = Type.Awaited(Type.Union([Type.Promise(Type.Promise(Type.String()))])) Assert.IsTrue(TypeGuard.IsString(T)) }) it('Should guard for Awaited 5', () => { const T = Type.Awaited(Type.Union([Type.Promise(Type.Promise(Type.String())), Type.Number()])) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsTrue(TypeGuard.IsString(T.anyOf[0])) Assert.IsTrue(TypeGuard.IsNumber(T.anyOf[1])) }) it('Should guard for Awaited 6', () => { const T = Type.Awaited(Type.Intersect([Type.Promise(Type.Promise(Type.String()))])) Assert.IsTrue(TypeGuard.IsString(T)) }) it('Should guard for Awaited 7', () => { const T = Type.Awaited(Type.Intersect([Type.Promise(Type.Promise(Type.String())), Type.Number()])) Assert.IsTrue(TypeGuard.IsIntersect(T)) Assert.IsTrue(TypeGuard.IsString(T.allOf[0])) Assert.IsTrue(TypeGuard.IsNumber(T.allOf[1])) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/bigint.ts000066400000000000000000000010671505437577000256160ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TBigInt', () => { it('Should guard for TBigInt', () => { const R = TypeGuard.IsBigInt(Type.BigInt()) Assert.IsTrue(R) }) it('Should not guard for TBigInt', () => { const R = TypeGuard.IsBigInt(null) Assert.IsFalse(R) }) it('Should not guard for BigInt with invalid $id', () => { // @ts-ignore const R = TypeGuard.IsBigInt(Type.BigInt({ $id: 1 })) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/boolean.ts000066400000000000000000000011011505437577000257460ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TBoolean', () => { it('Should guard for TBoolean', () => { const R = TypeGuard.IsBoolean(Type.Boolean()) Assert.IsTrue(R) }) it('Should not guard for TBoolean', () => { const R = TypeGuard.IsBoolean(null) Assert.IsFalse(R) }) it('Should not guard for TBoolean with invalid $id', () => { // @ts-ignore const R = TypeGuard.IsBoolean(Type.Boolean({ $id: 1 })) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/capitalize.ts000066400000000000000000000025321505437577000264650ustar00rootroot00000000000000import { TypeGuard, Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/Capitalize', () => { it('Should guard for Capitalize 1', () => { const T = Type.Capitalize(Type.Literal('hello'), { $id: 'hello', foo: 1 }) Assert.IsTrue(TypeGuard.IsLiteral(T)) Assert.IsEqual(T.const, 'Hello') Assert.IsEqual(T.$id, 'hello') Assert.IsEqual(T.foo, 1) }) it('Should guard for Capitalize 2', () => { const T = Type.Capitalize(Type.Literal('hello')) Assert.IsTrue(TypeGuard.IsLiteral(T)) Assert.IsEqual(T.const, 'Hello') }) it('Should guard for Capitalize 3', () => { const T = Type.Capitalize(Type.Union([Type.Literal('hello'), Type.Literal('world')])) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, 'Hello') Assert.IsEqual(T.anyOf[1].const, 'World') }) it('Should guard for Capitalize 4', () => { const T = Type.Capitalize(Type.TemplateLiteral('hello${0|1}')) Assert.IsTrue(TypeGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(Hello0|Hello1)$') }) it('Should guard for Capitalize 5', () => { const T = Type.Capitalize(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(0), Type.Literal(1)])])) Assert.IsTrue(TypeGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(Hello0|Hello1)$') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/composite.ts000066400000000000000000000134031505437577000263410ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TComposite', () => { it('Should guard for distinct properties', () => { const T = Type.Composite([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })]) Assert.IsTrue(TypeGuard.IsNumber(T.properties.x)) Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) }) it('Should guard for overlapping properties', () => { const T = Type.Composite([Type.Object({ x: Type.Number() }), Type.Object({ x: Type.Number() })]) Assert.IsTrue(TypeGuard.IsIntersect(T.properties.x)) // @ts-ignore Assert.IsTrue(TypeGuard.IsNumber(T.properties.x.allOf[0])) // @ts-ignore Assert.IsTrue(TypeGuard.IsNumber(T.properties.x.allOf[1])) }) it('Should not produce optional property if all properties are not optional', () => { const T = Type.Composite([Type.Object({ x: Type.Optional(Type.Number()) }), Type.Object({ x: Type.Number() })]) Assert.IsFalse(TypeGuard.IsOptional(T.properties.x)) }) // Note for: https://github.com/sinclairzx81/typebox/issues/419 // Determining if a composite property is optional requires a deep check for all properties gathered during a indexed access // call. Currently, there isn't a trivial way to perform this check without running into possibly infinite instantiation issues. // The optional check is only specific to overlapping properties. Singular properties will continue to work as expected. The // rule is "if all composite properties for a key are optional, then the composite property is optional". Defer this test and // document as minor breaking change. // it('Should produce optional property if all composited properties are optional', () => { // prettier-ignore const T = Type.Composite([ Type.Object({ x: Type.Optional(Type.Number()) }), Type.Object({ x: Type.Optional(Type.Number()) }) ]) Assert.IsTrue(TypeGuard.IsOptional(T.properties.x)) Assert.IsEqual(T.required, undefined) }) // prettier-ignore it('Should produce required property if some composited properties are not optional', () => { const T = Type.Composite([ Type.Object({ x: Type.Optional(Type.Number()) }), Type.Object({ x: Type.Number() }) ]) Assert.IsFalse(TypeGuard.IsOptional(T.properties.x)) Assert.IsTrue(T.required!.includes('x')) }) // prettier-ignore it('Should preserve single optional property', () => { const T = Type.Composite([ Type.Object({ x: Type.Optional(Type.Number()) }), ]) Assert.IsTrue(TypeGuard.IsOptional(T.properties.x)) Assert.IsEqual(T.required, undefined) }) // ---------------------------------------------------------------- // Intersect // ---------------------------------------------------------------- // prettier-ignore it('Should composite Intersect 1', () => { const T = Type.Composite([ Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }), ]), Type.Intersect([ Type.Object({ z: Type.Number() }), ]) ]) Assert.IsEqual(T, Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number() })) }) // prettier-ignore it('Should composite Intersect 2', () => { const T = Type.Composite([ Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ x: Type.Number() }), ]), Type.Intersect([ Type.Object({ x: Type.Number() }), ]) ]) Assert.IsEqual(T, Type.Object({ x: Type.Intersect([Type.Intersect([Type.Number(), Type.Number()]), Type.Number()]) })) }) // prettier-ignore it('Should composite Intersect 3', () => { const T = Type.Composite([ Type.Number(), Type.Boolean() ]) Assert.IsEqual(T, Type.Object({})) }) // prettier-ignore it('Should composite Intersect 4', () => { const T = Type.Composite([ Type.Number(), Type.Boolean(), Type.Object({ x: Type.String() }) ]) Assert.IsEqual(T, Type.Object({ x: Type.String() })) }) // prettier-ignore it('Should composite Intersect 5', () => { const T = Type.Composite([ Type.Object({ x: Type.Optional(Type.String()) }), Type.Object({ x: Type.String() }) ]) Assert.IsEqual(T, Type.Object({ x: Type.Intersect([Type.String(), Type.String()]) })) }) // prettier-ignore it('Should composite Intersect 6', () => { const T = Type.Composite([ Type.Object({ x: Type.Optional(Type.String()) }), Type.Object({ x: Type.Optional(Type.String()) }) ]) Assert.IsEqual(T, Type.Object({ x: Type.Optional(Type.Intersect([Type.String(), Type.String()])) })) }) // ---------------------------------------------------------------- // Union // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/789 // prettier-ignore it('Should composite Union 1 (non-overlapping)', () => { const T = Type.Composite([ Type.Union([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }), ]), Type.Union([ Type.Object({ z: Type.Number() }), ]) ]) Assert.IsEqual(T, Type.Object({ z: Type.Number() })) }) // https://github.com/sinclairzx81/typebox/issues/789 // prettier-ignore it('Should composite Union 2 (overlapping)', () => { const T = Type.Composite([ Type.Union([ Type.Object({ x: Type.Number() }), Type.Object({ x: Type.Number() }), ]), Type.Union([ Type.Object({ x: Type.Number() }), ]) ]) Assert.IsEqual(T, Type.Object({ x: Type.Intersect([Type.Union([Type.Number(), Type.Number()]), Type.Number()]) })) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/computed.ts000066400000000000000000000023331505437577000261570ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TComputed', () => { // ---------------------------------------------------------------- // Schema // ---------------------------------------------------------------- it('Should guard for Schema', () => { const T = Type.Partial(Type.Ref('A')) Assert.IsTrue(TypeGuard.IsComputed(T)) Assert.IsTrue(TypeGuard.IsSchema(T)) }) // ---------------------------------------------------------------- // Record // ---------------------------------------------------------------- it('Should guard for Record 1', () => { const T = Type.Record(Type.String(), Type.String()) Assert.IsTrue(TypeGuard.IsRecord(T)) }) it('Should guard for Record 3', () => { const T = Type.Record(Type.String(), Type.Ref('A')) Assert.IsTrue(TypeGuard.IsRecord(T)) }) it('Should guard for Record 3', () => { const T = Type.Record(Type.String(), Type.Partial(Type.Ref('A'))) Assert.IsTrue(TypeGuard.IsRecord(T)) }) it('Should guard for Record 4', () => { const T = Type.Record(Type.Ref('A'), Type.String()) Assert.IsTrue(TypeGuard.IsNever(T)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/const.ts000066400000000000000000000107031505437577000254650ustar00rootroot00000000000000import { TypeGuard, ValueGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TConstT', () => { // ---------------------------------------------------------------- // Identity Types // ---------------------------------------------------------------- it('Should guard for TConst 1', () => { const T = Type.Const(undefined) Assert.IsFalse(TypeGuard.IsReadonly(T)) Assert.IsTrue(TypeGuard.IsUndefined(T)) }) it('Should guard for TConst 2', () => { const T = Type.Const(null) Assert.IsFalse(TypeGuard.IsReadonly(T)) Assert.IsTrue(TypeGuard.IsNull(T)) }) it('Should guard for TConst 3', () => { const T = Type.Const(Symbol()) Assert.IsFalse(TypeGuard.IsReadonly(T)) Assert.IsTrue(TypeGuard.IsSymbol(T)) }) it('Should guard for TConst 4', () => { const T = Type.Const(1 as const) Assert.IsFalse(TypeGuard.IsReadonly(T)) Assert.IsTrue(TypeGuard.IsLiteral(T)) Assert.IsEqual(T.const, 1) }) it('Should guard for TConst 5', () => { const T = Type.Const('hello' as const) Assert.IsFalse(TypeGuard.IsReadonly(T)) Assert.IsTrue(TypeGuard.IsLiteral(T)) Assert.IsEqual(T.const, 'hello') }) it('Should guard for TConst 6', () => { const T = Type.Const(true as const) Assert.IsFalse(TypeGuard.IsReadonly(T)) Assert.IsTrue(TypeGuard.IsLiteral(T)) Assert.IsEqual(T.const, true) }) // ---------------------------------------------------------------- // Complex Types // ---------------------------------------------------------------- it('Should guard for TConst 7', () => { const T = Type.Const(100n as const) Assert.IsFalse(TypeGuard.IsReadonly(T)) // TS disparity because TLiteral does not support Bigint Assert.IsTrue(TypeGuard.IsBigInt(T)) }) it('Should guard for TConst 8', () => { const T = Type.Const(new Date()) Assert.IsFalse(TypeGuard.IsReadonly(T)) Assert.IsTrue(TypeGuard.IsDate(T)) }) it('Should guard for TConst 9', () => { const T = Type.Const(new Uint8Array()) Assert.IsFalse(TypeGuard.IsReadonly(T)) Assert.IsTrue(TypeGuard.IsUint8Array(T)) }) it('Should guard for TConst 10', () => { const T = Type.Const(function () {}) Assert.IsFalse(TypeGuard.IsReadonly(T)) Assert.IsTrue(TypeGuard.IsFunction(T)) Assert.IsTrue(T.parameters.length === 0) Assert.IsTrue(TypeGuard.IsUnknown(T.returns)) }) it('Should guard for TConst 11', () => { const T = Type.Const(new (class {})()) Assert.IsFalse(TypeGuard.IsReadonly(T)) Assert.IsTrue(TypeGuard.IsObject(T)) // Object types that are neither Date or Uint8Array evaluate as empty objects Assert.IsEqual(T.properties, {}) }) it('Should guard for TConst 12', () => { const T = Type.Const((function* (): any {})()) const R = ValueGuard.IsIterator((function* (): any {})()) Assert.IsFalse(TypeGuard.IsReadonly(T)) Assert.IsTrue(TypeGuard.IsAny(T)) }) it('Should guard for TConst 13', () => { const T = Type.Const((async function* (): any {})()) const R = ValueGuard.IsAsyncIterator((function* (): any {})()) Assert.IsFalse(TypeGuard.IsReadonly(T)) Assert.IsTrue(TypeGuard.IsAny(T)) }) it('Should guard for TConst 14', () => { const T = Type.Const({ x: 1, y: { z: 2, }, } as const) // root Assert.IsFalse(TypeGuard.IsReadonly(T)) Assert.IsTrue(TypeGuard.IsObject(T)) // x Assert.IsTrue(TypeGuard.IsLiteral(T.properties.x)) Assert.IsEqual(T.properties.x.const, 1) // y Assert.IsTrue(TypeGuard.IsReadonly(T.properties.y)) Assert.IsTrue(TypeGuard.IsObject(T.properties.y)) // y.z Assert.IsTrue(TypeGuard.IsReadonly(T.properties.y.properties.z)) Assert.IsTrue(TypeGuard.IsLiteral(T.properties.y.properties.z)) Assert.IsEqual(T.properties.y.properties.z.const, 2) }) it('Should guard for TConst 15', () => { const T = Type.Const([1, 2, 3] as const) // root (arrays are always readonly as root) Assert.IsTrue(TypeGuard.IsReadonly(T)) Assert.IsTrue(TypeGuard.IsTuple(T)) Assert.IsTrue(T.items?.length === 3) // 0 Assert.IsFalse(TypeGuard.IsReadonly(T.items![0])) Assert.IsTrue(TypeGuard.IsLiteral(T.items![0])) // 1 Assert.IsFalse(TypeGuard.IsReadonly(T.items![1])) Assert.IsTrue(TypeGuard.IsLiteral(T.items![1])) // 2 Assert.IsFalse(TypeGuard.IsReadonly(T.items![2])) Assert.IsTrue(TypeGuard.IsLiteral(T.items![2])) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/constructor.ts000066400000000000000000000026071505437577000267300ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TConstructor', () => { it('Should guard for TConstructor', () => { const R = TypeGuard.IsConstructor(Type.Constructor([], Type.Number())) Assert.IsTrue(R) }) it('Should not guard for TConstructor', () => { const R = TypeGuard.IsConstructor(null) Assert.IsFalse(R) }) it('Should not guard for TConstructor with invalid $id', () => { // @ts-ignore const R = TypeGuard.IsConstructor(Type.Constructor([], Type.Number(), { $id: 1 })) Assert.IsFalse(R) }) it('Should not guard for TConstructor with invalid Params', () => { const R = TypeGuard.IsConstructor(Type.Constructor([{} as any, {} as any], Type.Number())) Assert.IsFalse(R) }) it('Should not guard for TConstructor with invalid Return', () => { const R = TypeGuard.IsConstructor(Type.Constructor([], {} as any)) Assert.IsFalse(R) }) it('Should guard for TConstructor with empty Rest Tuple', () => { const R = TypeGuard.IsConstructor(Type.Constructor(Type.Rest(Type.Tuple([])), Type.Number())) Assert.IsTrue(R) }) it('Should guard for TConstructor with Rest Tuple', () => { const R = TypeGuard.IsConstructor(Type.Constructor(Type.Rest(Type.Tuple([Type.Number(), Type.String()])), Type.Number())) Assert.IsTrue(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/date.ts000066400000000000000000000027671505437577000252670ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TDate', () => { it('Should guard for TDate', () => { const R = TypeGuard.IsDate(Type.Date()) Assert.IsTrue(R) }) it('Should not guard for TDate', () => { const R = TypeGuard.IsDate(null) Assert.IsFalse(R) }) it('Should not guard for TDate with invalid $id', () => { // @ts-ignore const R = TypeGuard.IsDate(Type.Date({ $id: 1 })) Assert.IsFalse(R) }) it('Should not guard for TDate with invalid exclusiveMaximumTimestamp', () => { // @ts-ignore const R = TypeGuard.IsDate(Type.Date({ exclusiveMaximumTimestamp: '1' })) Assert.IsFalse(R) }) it('Should not guard for TDate with invalid exclusiveMinimumTimestamp', () => { // @ts-ignore const R = TypeGuard.IsDate(Type.Date({ exclusiveMinimumTimestamp: '1' })) Assert.IsFalse(R) }) it('Should not guard for TDate with invalid maximumTimestamp', () => { // @ts-ignore const R = TypeGuard.IsDate(Type.Date({ maximumTimestamp: '1' })) Assert.IsFalse(R) }) it('Should not guard for TDate with invalid minimumTimestamp', () => { // @ts-ignore const R = TypeGuard.IsDate(Type.Date({ minimumTimestamp: '1' })) Assert.IsFalse(R) }) it('Should not guard for TDate with invalid multipleOfTimestamp', () => { // @ts-ignore const R = TypeGuard.IsDate(Type.Date({ multipleOfTimestamp: '1' })) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/enum.ts000066400000000000000000000101331505437577000253000ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TEnum', () => { // ---------------------------------------------------------------- // Options // ---------------------------------------------------------------- it('Should guard for Options 1', () => { const T = Type.Enum({ x: 1 }, { extra: 'hello', $id: 'T' }) Assert.IsEqual(T.extra, 'hello') Assert.IsEqual(T.$id, 'T') }) it('Should guard for Options 2', () => { enum E { x, } const T = Type.Enum(E, { extra: 'hello', $id: 'T' }) Assert.IsEqual(T.extra, 'hello') Assert.IsEqual(T.$id, 'T') }) it('Should guard for Options 3', () => { enum E {} const T = Type.Enum(E, { extra: 'hello', $id: 'T' }) Assert.IsEqual(T.extra, 'hello') Assert.IsEqual(T.$id, 'T') }) it('Should guard for Options 4', () => { const T = Type.Enum({}, { extra: 'hello', $id: 'T' }) Assert.IsEqual(T.extra, 'hello') Assert.IsEqual(T.$id, 'T') }) // ---------------------------------------------------------------- // Empty // ---------------------------------------------------------------- it('Should guard for Empty 1', () => { const T = Type.Enum({}) Assert.IsTrue(TypeGuard.IsNever(T)) }) it('Should guard for Empty 2', () => { enum E {} const T = Type.Enum(E) Assert.IsTrue(TypeGuard.IsNever(T)) }) // ---------------------------------------------------------------- // Enum // ---------------------------------------------------------------- it('Should guard for TEnum Enum 0', () => { enum E {} const T = Type.Enum(E) Assert.IsTrue(TypeGuard.IsNever(T)) }) it('Should guard for TEnum Enum 1', () => { enum E { A, } const T = Type.Enum(E) Assert.IsTrue(TypeGuard.IsLiteral(T)) Assert.IsEqual(T.const, E.A) }) it('Should guard for TEnum Enum 2', () => { enum E { A = 1, B = 2, C = 3, } const T = Type.Enum(E) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, E.A) Assert.IsEqual(T.anyOf[1].const, E.B) Assert.IsEqual(T.anyOf[2].const, E.C) }) it('Should guard for TEnum Enum 3', () => { enum E { A = 'X', B = 'Y', C = 'Z', } const T = Type.Enum(E) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, E.A) Assert.IsEqual(T.anyOf[1].const, E.B) Assert.IsEqual(T.anyOf[2].const, E.C) }) it('Should guard for TEnum Enum 4', () => { enum E { A = 'X', B = 'Y', C = 'X', } const T = Type.Enum(E) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, E.A) Assert.IsEqual(T.anyOf[1].const, E.B) Assert.IsEqual(T.anyOf.length, 2) }) // ---------------------------------------------------------------- // Object Literal // ---------------------------------------------------------------- it('Should guard for TEnum Object Literal 0', () => { const T = Type.Enum({}) Assert.IsTrue(TypeGuard.IsNever(T)) }) it('Should guard for TEnum Object Literal 1', () => { const T = Type.Enum({ A: 1 }) Assert.IsTrue(TypeGuard.IsLiteral(T)) Assert.IsEqual(T.const, 1) }) it('Should guard for TEnum Object Literal 2', () => { const T = Type.Enum({ A: 1, B: 2, C: 3, }) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, 1) Assert.IsEqual(T.anyOf[1].const, 2) Assert.IsEqual(T.anyOf[2].const, 3) }) it('Should guard for TEnum Object Literal 3', () => { const T = Type.Enum({ A: 'X', B: 'Y', C: 'Z', }) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, 'X') Assert.IsEqual(T.anyOf[1].const, 'Y') Assert.IsEqual(T.anyOf[2].const, 'Z') }) it('Should guard for TEnum Object Literal 4', () => { const T = Type.Enum({ A: 'X', B: 'Y', C: 'X', }) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, 'X') Assert.IsEqual(T.anyOf[1].const, 'Y') Assert.IsEqual(T.anyOf.length, 2) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/exclude.ts000066400000000000000000000114661505437577000257770ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TExclude', () => { it('Should exclude string from number', () => { const T = Type.Exclude(Type.String(), Type.Number()) Assert.IsTrue(TypeGuard.IsString(T)) }) it('Should exclude string from string', () => { const T = Type.Exclude(Type.String(), Type.String()) Assert.IsTrue(TypeGuard.IsNever(T)) }) it('Should exclude string | number | boolean from string', () => { const T = Type.Exclude(Type.Union([Type.String(), Type.Number(), Type.Boolean()]), Type.String()) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsTrue(TypeGuard.IsNumber(T.anyOf[0])) Assert.IsTrue(TypeGuard.IsBoolean(T.anyOf[1])) }) it('Should exclude string | number | boolean from string | boolean', () => { const T = Type.Exclude(Type.Union([Type.String(), Type.Number(), Type.Boolean()]), Type.Union([Type.String(), Type.Boolean()])) Assert.IsTrue(TypeGuard.IsNumber(T)) }) // ------------------------------------------------------------------------ // TemplateLiteral | TemplateLiteral // ------------------------------------------------------------------------ it('Should exclude TemplateLiteral | TemplateLiteral 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const T = Type.Exclude(A, B) Assert.IsTrue(TypeGuard.IsNever(T)) }) it('Should exclude TemplateLiteral | TemplateLiteral 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])]) const T = Type.Exclude(A, B) Assert.IsTrue(['C'].includes(T.const)) }) it('Should exclude TemplateLiteral | TemplateLiteral 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A')])]) const T = Type.Exclude(A, B) Assert.IsTrue(['C', 'B'].includes(T.anyOf[0].const)) Assert.IsTrue(['C', 'B'].includes(T.anyOf[1].const)) }) // ------------------------------------------------------------------------ // TemplateLiteral | Union 1 // ------------------------------------------------------------------------ it('Should exclude TemplateLiteral | Union 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const T = Type.Exclude(A, B) Assert.IsTrue(TypeGuard.IsNever(T)) }) it('Should exclude TemplateLiteral | Union 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.Union([Type.Literal('A'), Type.Literal('B')]) const T = Type.Exclude(A, B) Assert.IsTrue(['C'].includes(T.const)) }) it('Should exclude TemplateLiteral | Union 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.Union([Type.Literal('A')]) const T = Type.Exclude(A, B) Assert.IsTrue(['C', 'B'].includes(T.anyOf[0].const)) Assert.IsTrue(['C', 'B'].includes(T.anyOf[1].const)) }) // ------------------------------------------------------------------------ // Union | TemplateLiteral 1 // ------------------------------------------------------------------------ it('Should exclude Union | TemplateLiteral 1', () => { const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const T = Type.Exclude(A, B) Assert.IsTrue(TypeGuard.IsNever(T)) }) it('Should exclude Union | TemplateLiteral 1', () => { const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])]) const T = Type.Exclude(A, B) Assert.IsTrue(['C'].includes(T.const)) }) it('Should exclude Union | TemplateLiteral 1', () => { const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A')])]) const T = Type.Exclude(A, B) Assert.IsTrue(['C', 'B'].includes(T.anyOf[0].const)) Assert.IsTrue(['C', 'B'].includes(T.anyOf[1].const)) }) it('Should exclude with options', () => { const A = Type.String() const B = Type.String() const T = Type.Exclude(A, B, { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/extract.ts000066400000000000000000000123541505437577000260150ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TExtract', () => { it('Should extract string from number', () => { const T = Type.Extract(Type.String(), Type.Number()) Assert.IsTrue(TypeGuard.IsNever(T)) }) it('Should extract string from string', () => { const T = Type.Extract(Type.String(), Type.String()) Assert.IsTrue(TypeGuard.IsString(T)) }) it('Should extract string | number | boolean from string', () => { const T = Type.Extract(Type.Union([Type.String(), Type.Number(), Type.Boolean()]), Type.String()) Assert.IsTrue(TypeGuard.IsString(T)) }) it('Should extract string | number | boolean from string | boolean', () => { const T = Type.Extract(Type.Union([Type.String(), Type.Number(), Type.Boolean()]), Type.Union([Type.String(), Type.Boolean()])) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsTrue(TypeGuard.IsString(T.anyOf[0])) Assert.IsTrue(TypeGuard.IsBoolean(T.anyOf[1])) }) // ------------------------------------------------------------------------ // TemplateLiteral | TemplateLiteral // ------------------------------------------------------------------------ it('Should extract TemplateLiteral | TemplateLiteral 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const T = Type.Extract(A, B) Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[0].const)) Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[1].const)) Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[2].const)) }) it('Should extract TemplateLiteral | TemplateLiteral 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])]) const T = Type.Extract(A, B) Assert.IsTrue(['A', 'B'].includes(T.anyOf[0].const)) Assert.IsTrue(['A', 'B'].includes(T.anyOf[1].const)) }) it('Should extract TemplateLiteral | TemplateLiteral 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A')])]) const T = Type.Extract(A, B) Assert.IsTrue(['A'].includes(T.const)) }) // ------------------------------------------------------------------------ // TemplateLiteral | Union 1 // ------------------------------------------------------------------------ it('Should extract TemplateLiteral | Union 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const T = Type.Extract(A, B) Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[0].const)) Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[1].const)) Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[2].const)) }) it('Should extract TemplateLiteral | Union 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.Union([Type.Literal('A'), Type.Literal('B')]) const T = Type.Extract(A, B) Assert.IsTrue(['A', 'B'].includes(T.anyOf[0].const)) Assert.IsTrue(['A', 'B'].includes(T.anyOf[1].const)) }) it('Should extract TemplateLiteral | Union 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.Union([Type.Literal('A')]) const T = Type.Extract(A, B) Assert.IsTrue(['A'].includes(T.const)) }) // ------------------------------------------------------------------------ // Union | TemplateLiteral 1 // ------------------------------------------------------------------------ it('Should extract Union | TemplateLiteral 1', () => { const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const T = Type.Extract(A, B) Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[0].const)) Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[1].const)) Assert.IsTrue(['A', 'B', 'C'].includes(T.anyOf[2].const)) }) it('Should extract Union | TemplateLiteral 1', () => { const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])]) const T = Type.Extract(A, B) Assert.IsTrue(['A', 'B'].includes(T.anyOf[0].const)) Assert.IsTrue(['A', 'B'].includes(T.anyOf[1].const)) }) it('Should extract Union | TemplateLiteral 1', () => { const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A')])]) const T = Type.Extract(A, B) Assert.IsTrue(['A'].includes(T.const)) }) it('Should extract with options', () => { const A = Type.String() const B = Type.String() const T = Type.Extract(A, B, { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/function.ts000066400000000000000000000025101505437577000261610ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TFunction', () => { it('Should guard for TFunction', () => { const R = TypeGuard.IsFunction(Type.Function([], Type.Number())) Assert.IsTrue(R) }) it('Should not guard for TFunction', () => { const R = TypeGuard.IsFunction(null) Assert.IsFalse(R) }) it('Should not guard for TFunction with invalid $id', () => { // @ts-ignore const R = TypeGuard.IsFunction(Type.Function([], Type.Number(), { $id: 1 })) Assert.IsFalse(R) }) it('Should not guard for TFunction with invalid Params', () => { const R = TypeGuard.IsFunction(Type.Function([{} as any, {} as any], Type.Number())) Assert.IsFalse(R) }) it('Should not guard for TFunction with invalid Return', () => { const R = TypeGuard.IsFunction(Type.Function([], {} as any)) Assert.IsFalse(R) }) it('Should guard for TFunction with empty Rest Tuple', () => { const R = TypeGuard.IsFunction(Type.Function(Type.Rest(Type.Tuple([])), Type.Number())) Assert.IsTrue(R) }) it('Should guard for TFunction with Rest Tuple', () => { const R = TypeGuard.IsFunction(Type.Function(Type.Rest(Type.Tuple([Type.Number(), Type.String()])), Type.Number())) Assert.IsTrue(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/import.ts000066400000000000000000000265031505437577000256560ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TImport', () => { it('Should guard for TImport', () => { const Module = Type.Module({ A: Type.String(), }) const A = Module.Import('A') const N = A.$defs[A.$ref] Assert.IsTrue(TypeGuard.IsImport(A)) Assert.IsTrue(TypeGuard.IsString(N)) }) // ---------------------------------------------------------------- // Computed: Options // ---------------------------------------------------------------- it('Should guard for TImport with Options 1', () => { const Module = Type.Module({ A: Type.String(), }) const A = Module.Import('A', { format: 'string' }) const N = A.$defs[A.$ref] Assert.IsTrue(TypeGuard.IsImport(A)) Assert.IsTrue(TypeGuard.IsString(N)) Assert.IsTrue(N.format === 'string') }) it('Should guard for TImport with Options 2', () => { const Module = Type.Module({ R: Type.Object({ x: Type.Number() }), A: Type.Ref('R'), }) const A = Module.Import('A', { test: 'test' }) const N = A.$defs[A.$ref] Assert.IsTrue(TypeGuard.IsImport(A)) Assert.IsTrue(TypeGuard.IsRef(N)) Assert.IsTrue(N.test === 'test') }) it('Should guard for TImport with Options 3', () => { const Module = Type.Module({ R: Type.Object({ x: Type.Number() }), A: Type.Partial(Type.Ref('R')), }) const A = Module.Import('A', { additionalProperties: false }) const N = A.$defs[A.$ref] Assert.IsTrue(TypeGuard.IsImport(A)) Assert.IsTrue(TypeGuard.IsObject(N)) Assert.IsTrue(N.additionalProperties === false) }) // ---------------------------------------------------------------- // Computed: Awaited // ---------------------------------------------------------------- it('Should compute for Awaited', () => { const Module = Type.Module({ T: Type.Promise(Type.String()), R: Type.Awaited(Type.Ref('T')), }) const T = Module.Import('R') Assert.IsTrue(TypeGuard.IsString(T.$defs['R'])) }) // ---------------------------------------------------------------- // Computed: Index (Note: Pending Reimplementation of Index) // ---------------------------------------------------------------- it('Should compute for Index 2', () => { const Module = Type.Module({ T: Type.Object({ x: Type.Number(), y: Type.String() }), I: Type.Literal('x'), R: Type.Index(Type.Ref('T'), Type.Ref('I')) as never, // fail }) const T = Module.Import('R') Assert.IsTrue(TypeGuard.IsNumber(T.$defs['R'])) }) // ---------------------------------------------------------------- // Computed: Omit // ---------------------------------------------------------------- it('Should compute for Omit 1', () => { const Module = Type.Module({ T: Type.Object({ x: Type.Number(), y: Type.Number() }), R: Type.Omit(Type.Ref('T'), Type.Literal('x')), }) const T = Module.Import('R') Assert.IsTrue(TypeGuard.IsObject(T.$defs['R'])) Assert.IsTrue(TypeGuard.IsNumber(T.$defs['R'].properties.y)) // @ts-ignore Assert.IsTrue(T.$defs['R'].properties.x === undefined) }) it('Should compute for Omit 2', () => { const Module = Type.Module({ T: Type.Object({ x: Type.Number(), y: Type.Number() }), K: Type.Literal('x'), R: Type.Omit(Type.Ref('T'), Type.Ref('K')), }) const T = Module.Import('R') Assert.IsTrue(TypeGuard.IsObject(T.$defs['R'])) Assert.IsTrue(TypeGuard.IsNumber(T.$defs['R'].properties.y)) // @ts-ignore Assert.IsTrue(T.$defs['R'].properties.x === undefined) }) // ---------------------------------------------------------------- // Computed: Partial // ---------------------------------------------------------------- it('Should compute for Partial', () => { const Module = Type.Module({ T: Type.Object({ x: Type.Number() }), R: Type.Partial(Type.Ref('T')), }) const T = Module.Import('R') Assert.IsTrue(TypeGuard.IsObject(T.$defs['R'])) Assert.IsTrue(TypeGuard.IsNumber(T.$defs['R'].properties.x)) Assert.IsTrue(TypeGuard.IsOptional(T.$defs['R'].properties.x)) }) // ---------------------------------------------------------------- // Computed: Pick // ---------------------------------------------------------------- it('Should compute for Pick 1', () => { const Module = Type.Module({ T: Type.Object({ x: Type.Number(), y: Type.Number() }), R: Type.Pick(Type.Ref('T'), Type.Literal('x')), }) const T = Module.Import('R') Assert.IsTrue(TypeGuard.IsObject(T.$defs['R'])) Assert.IsTrue(TypeGuard.IsNumber(T.$defs['R'].properties.x)) // @ts-ignore Assert.IsTrue(T.$defs['R'].properties.y === undefined) }) it('Should compute for Pick 2', () => { const Module = Type.Module({ T: Type.Object({ x: Type.Number(), y: Type.Number() }), K: Type.Literal('x'), R: Type.Pick(Type.Ref('T'), Type.Ref('K')), }) const T = Module.Import('R') Assert.IsTrue(TypeGuard.IsObject(T.$defs['R'])) Assert.IsTrue(TypeGuard.IsNumber(T.$defs['R'].properties.x)) // @ts-ignore Assert.IsTrue(T.$defs['R'].properties.y === undefined) }) // ---------------------------------------------------------------- // Computed: Record // ---------------------------------------------------------------- it('Should compute for Record 1', () => { const Module = Type.Module({ T: Type.Object({ x: Type.Number(), y: Type.String() }), R: Type.Record(Type.String(), Type.Ref('T')), }) const T = Module.Import('R') Assert.IsTrue(TypeGuard.IsRecord(T.$defs['R'])) // note: TRecord> are not computed. Only the Key is // computed as TypeBox needs to make a deferred call to transform from // TRecord to TObject for finite keys. Assert.IsTrue(TypeGuard.IsRef(T.$defs['R'].patternProperties['^(.*)$'])) Assert.IsTrue(T.$defs['R'].patternProperties['^(.*)$'].$ref === 'T') }) it('Should compute for Record 2', () => { const Module = Type.Module({ T: Type.Number(), R: Type.Record(Type.Union([Type.Literal('x'), Type.Literal('y')]), Type.Ref('T')), }) // Retain reference if not computed const T = Module.Import('R') Assert.IsTrue(TypeGuard.IsObject(T.$defs['R'])) Assert.IsTrue(TypeGuard.IsRef(T.$defs['R'].properties.x)) Assert.IsTrue(TypeGuard.IsRef(T.$defs['R'].properties.y)) }) it('Should compute for Record 3', () => { const Module = Type.Module({ T: Type.Object({ x: Type.Number() }), R: Type.Record(Type.Union([Type.Literal('x'), Type.Literal('y')]), Type.Partial(Type.Ref('T'))), }) // Dereference if computed const T = Module.Import('R') Assert.IsTrue(TypeGuard.IsObject(T.$defs['R'])) Assert.IsTrue(TypeGuard.IsObject(T.$defs['R'].properties.x)) Assert.IsTrue(TypeGuard.IsObject(T.$defs['R'].properties.y)) }) // ---------------------------------------------------------------- // Computed: Required // ---------------------------------------------------------------- it('Should compute for Required', () => { const Module = Type.Module({ T: Type.Partial(Type.Object({ x: Type.Number() })), R: Type.Required(Type.Ref('T')), }) const T = Module.Import('R') Assert.IsTrue(TypeGuard.IsObject(T.$defs['R'])) Assert.IsTrue(TypeGuard.IsNumber(T.$defs['R'].properties.x)) Assert.IsFalse(TypeGuard.IsOptional(T.$defs['R'].properties.x)) }) // ---------------------------------------------------------------- // Computed: KeyOf // ---------------------------------------------------------------- it('Should compute for KeyOf', () => { const Module = Type.Module({ T: Type.Object({ x: Type.Number(), y: Type.String() }), R: Type.KeyOf(Type.Ref('T')), }) const T = Module.Import('R') Assert.IsTrue(TypeGuard.IsUnion(T.$defs['R'])) Assert.IsTrue(TypeGuard.IsLiteral(T.$defs['R'].anyOf[0])) Assert.IsTrue(TypeGuard.IsLiteral(T.$defs['R'].anyOf[1])) Assert.IsTrue(T.$defs['R'].anyOf[0].const === 'x') Assert.IsTrue(T.$defs['R'].anyOf[1].const === 'y') }) // ---------------------------------------------------------------- // Modifiers: 1 // ---------------------------------------------------------------- it('Should compute for Modifiers 1', () => { const Module = Type.Module({ T: Type.Object({ x: Type.ReadonlyOptional(Type.Null()), y: Type.Readonly(Type.Null()), z: Type.Optional(Type.Null()), w: Type.Null(), }), }) const T = Module.Import('T') const R = T.$defs[T.$ref] Assert.IsTrue(TypeGuard.IsObject(R)) Assert.IsTrue(TypeGuard.IsNull(R.properties.x)) Assert.IsTrue(TypeGuard.IsReadonly(R.properties.x)) Assert.IsTrue(TypeGuard.IsOptional(R.properties.x)) Assert.IsTrue(TypeGuard.IsNull(R.properties.y)) Assert.IsTrue(TypeGuard.IsReadonly(R.properties.y)) Assert.IsFalse(TypeGuard.IsOptional(R.properties.y)) Assert.IsTrue(TypeGuard.IsNull(R.properties.z)) Assert.IsTrue(TypeGuard.IsOptional(R.properties.z)) Assert.IsFalse(TypeGuard.IsReadonly(R.properties.z)) Assert.IsTrue(TypeGuard.IsNull(R.properties.w)) Assert.IsFalse(TypeGuard.IsOptional(R.properties.w)) Assert.IsFalse(TypeGuard.IsReadonly(R.properties.w)) }) // ---------------------------------------------------------------- // Modifiers: 2 // ---------------------------------------------------------------- it('Should compute for Modifiers 2', () => { const Module = Type.Module({ T: Type.Object({ x: Type.ReadonlyOptional(Type.Array(Type.Null())), y: Type.Readonly(Type.Array(Type.Null())), z: Type.Optional(Type.Array(Type.Null())), w: Type.Array(Type.Null()), }), }) const T = Module.Import('T') const R = T.$defs[T.$ref] Assert.IsTrue(TypeGuard.IsObject(R)) Assert.IsTrue(TypeGuard.IsArray(R.properties.x)) Assert.IsTrue(TypeGuard.IsNull(R.properties.x.items)) Assert.IsTrue(TypeGuard.IsReadonly(R.properties.x)) Assert.IsTrue(TypeGuard.IsOptional(R.properties.x)) Assert.IsTrue(TypeGuard.IsArray(R.properties.y)) Assert.IsTrue(TypeGuard.IsNull(R.properties.y.items)) Assert.IsTrue(TypeGuard.IsReadonly(R.properties.y)) Assert.IsFalse(TypeGuard.IsOptional(R.properties.y)) Assert.IsTrue(TypeGuard.IsArray(R.properties.z)) Assert.IsTrue(TypeGuard.IsNull(R.properties.z.items)) Assert.IsTrue(TypeGuard.IsOptional(R.properties.z)) Assert.IsFalse(TypeGuard.IsReadonly(R.properties.z)) Assert.IsTrue(TypeGuard.IsArray(R.properties.w)) Assert.IsTrue(TypeGuard.IsNull(R.properties.w.items)) Assert.IsFalse(TypeGuard.IsOptional(R.properties.w)) Assert.IsFalse(TypeGuard.IsReadonly(R.properties.w)) }) // ---------------------------------------------------------------- // Modifiers: 3 // ---------------------------------------------------------------- it('Should compute for Modifiers 3', () => { const Module = Type.Module({ T: Type.Object({ x: Type.Array(Type.Null()), }), // Computed Partial U: Type.Partial(Type.Ref('T')), }) const T = Module.Import('U') const R = T.$defs[T.$ref] Assert.IsTrue(TypeGuard.IsObject(R)) Assert.IsTrue(TypeGuard.IsArray(R.properties.x)) Assert.IsTrue(TypeGuard.IsNull(R.properties.x.items)) Assert.IsTrue(TypeGuard.IsOptional(R.properties.x)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/index.ts000066400000000000000000000017671505437577000254600ustar00rootroot00000000000000import './any' import './argument' import './array' import './async-iterator' import './awaited' import './bigint' import './boolean' import './capitalize' import './composite' import './computed' import './const' import './constructor' import './date' import './enum' import './exclude' import './extract' import './function' import './import' import './indexed' import './integer' import './intersect' import './iterator' import './keyof' import './kind' import './literal' import './lowercase' import './mapped' import './not' import './null' import './number' import './object' import './omit' import './partial' import './pick' import './promise' import './record' import './recursive' import './ref' import './regexp' import './required' import './rest' import './string' import './symbol' import './template-literal' import './this' import './tuple' import './uint8array' import './uncapitalize' import './undefined' import './union' import './unknown' import './unsafe' import './uppercase' import './void' sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/indexed.ts000066400000000000000000000262171505437577000257660ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TIndex', () => { it('Should Index 1', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), }) const I = Type.Index(T, ['x']) Assert.IsTrue(TypeGuard.IsNumber(I)) }) it('Should Index 2', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), }) const I = Type.Index(T, ['x', 'y']) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsNumber(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsString(I.anyOf[1])) }) it('Should Index 3', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), }) const I = Type.Index(T, Type.KeyOf(T)) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsNumber(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsString(I.anyOf[1])) }) it('Should Index 4', () => { const T = Type.Object({ ab: Type.Number(), ac: Type.String(), }) const I = Type.Index(T, Type.TemplateLiteral([Type.Literal('a'), Type.Union([Type.Literal('b'), Type.Literal('c')])])) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsNumber(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsString(I.anyOf[1])) }) it('Should Index 5', () => { const T = Type.Intersect([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.String() })]) const I = Type.Index(T, ['x', 'y']) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsNumber(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsString(I.anyOf[1])) }) it('Should Index 6', () => { const T = Type.Union([Type.Object({ x: Type.Number() }), Type.Object({ x: Type.String() })]) const I = Type.Index(T, ['x']) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsNumber(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsString(I.anyOf[1])) }) it('Should Index 7', () => { const T = Type.Array(Type.Null()) const I = Type.Index(T, Type.Number()) Assert.IsTrue(TypeGuard.IsNull(I)) }) it('Should Index 6', () => { const T = Type.Tuple([Type.Literal('hello'), Type.Literal('world')]) const I = Type.Index(T, [0]) Assert.IsTrue(TypeGuard.IsLiteralString(I)) Assert.IsEqual(I.const, 'hello') }) it('Should Index 8', () => { const T = Type.Tuple([Type.Literal('hello'), Type.Literal('world')]) const I = Type.Index(T, [1]) Assert.IsTrue(TypeGuard.IsLiteralString(I)) Assert.IsEqual(I.const, 'world') }) it('Should Index 9', () => { const T = Type.Tuple([Type.Literal('hello'), Type.Literal('world')]) const I = Type.Index(T, [0, 1]) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsEqual(I.anyOf[0].const, 'hello') Assert.IsEqual(I.anyOf[1].const, 'world') }) it('Should Index 10', () => { const T = Type.Tuple([Type.Literal('hello'), Type.Literal('world')]) const I = Type.Index(T, [1, 0]) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsEqual(I.anyOf[0].const, 'world') Assert.IsEqual(I.anyOf[1].const, 'hello') }) it('Should Index 11', () => { const T = Type.Tuple([Type.Literal('hello'), Type.Literal('world')]) const I = Type.Index(T, [0, 0, 0, 1]) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsEqual(I.anyOf[0].const, 'hello') Assert.IsEqual(I.anyOf[1].const, 'hello') Assert.IsEqual(I.anyOf[2].const, 'hello') Assert.IsEqual(I.anyOf[3].const, 'world') }) it('Should Index 12', () => { const T = Type.Tuple([Type.String(), Type.Boolean()]) const I = Type.Index(T, Type.Number()) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsString(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsBoolean(I.anyOf[1])) }) it('Should Index 13', () => { const T = Type.Tuple([Type.String()]) const I = Type.Index(T, Type.Number()) Assert.IsTrue(TypeGuard.IsString(I)) }) it('Should Index 14', () => { const T = Type.Tuple([]) const I = Type.Index(T, Type.Number()) Assert.IsTrue(TypeGuard.IsNever(I)) }) it('Should Index 15', () => { const T = Type.Object({ 0: Type.Number(), }) const I = Type.Index(T, Type.Literal(0)) Assert.IsTrue(TypeGuard.IsNumber(I)) }) it('Should Index 16', () => { const T = Type.Object({ 0: Type.Number(), }) const I = Type.Index(T, Type.Literal('0')) Assert.IsTrue(TypeGuard.IsNumber(I)) }) it('Should Index 17', () => { const T = Type.Object({ '0': Type.Number(), }) const I = Type.Index(T, Type.Literal(0)) Assert.IsTrue(TypeGuard.IsNumber(I)) }) it('Should Index 18', () => { const T = Type.Object({ '0': Type.Number(), }) const I = Type.Index(T, Type.Literal('0')) Assert.IsTrue(TypeGuard.IsNumber(I)) }) it('Should Index 19', () => { const T = Type.Object({ 0: Type.Number(), 1: Type.String(), 2: Type.Boolean(), }) const I = Type.Index(T, Type.Union([Type.Literal(0), Type.Literal(2)])) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsNumber(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsBoolean(I.anyOf[1])) }) it('Should Index 20', () => { const T = Type.Object({ 0: Type.Number(), 1: Type.String(), 2: Type.Boolean(), }) const I = Type.Index(T, Type.BigInt()) Assert.IsTrue(TypeGuard.IsNever(I)) }) it('Should Index 21', () => { const T = Type.Object({ 0: Type.Number(), 1: Type.String(), 2: Type.Boolean(), }) const I = Type.Index(T, Type.Object({})) Assert.IsTrue(TypeGuard.IsNever(I)) }) it('Should Index 22', () => { const A = Type.Object({ x: Type.Literal('A') }) const B = Type.Object({ x: Type.Literal('B') }) const C = Type.Object({ x: Type.Literal('C') }) const D = Type.Object({ x: Type.Literal('D') }) const T = Type.Intersect([A, B, C, D]) const I = Type.Index(T, ['x']) Assert.IsTrue(TypeGuard.IsIntersect(I)) Assert.IsTrue(TypeGuard.IsLiteral(I.allOf[0])) Assert.IsTrue(TypeGuard.IsLiteral(I.allOf[1])) Assert.IsTrue(TypeGuard.IsLiteral(I.allOf[2])) Assert.IsTrue(TypeGuard.IsLiteral(I.allOf[3])) }) it('Should Index 23', () => { const A = Type.Object({ x: Type.Literal('A') }) const B = Type.Object({ x: Type.Literal('B') }) const C = Type.Object({ x: Type.Literal('C') }) const D = Type.Object({ x: Type.Literal('D') }) const T = Type.Union([A, B, C, D]) const I = Type.Index(T, ['x']) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsLiteral(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsLiteral(I.anyOf[1])) Assert.IsTrue(TypeGuard.IsLiteral(I.anyOf[2])) Assert.IsTrue(TypeGuard.IsLiteral(I.anyOf[3])) }) it('Should Index 24', () => { const A = Type.Object({ x: Type.Literal('A'), y: Type.Number() }) const B = Type.Object({ x: Type.Literal('B') }) const C = Type.Object({ x: Type.Literal('C') }) const D = Type.Object({ x: Type.Literal('D') }) const T = Type.Intersect([A, B, C, D]) const I = Type.Index(T, ['x', 'y']) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsIntersect(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsNumber(I.anyOf[1])) }) it('Should Index 25', () => { const A = Type.Object({ x: Type.Literal('A'), y: Type.Number() }) const B = Type.Object({ x: Type.Literal('B'), y: Type.String() }) const C = Type.Object({ x: Type.Literal('C') }) const D = Type.Object({ x: Type.Literal('D') }) const T = Type.Intersect([A, B, C, D]) const I = Type.Index(T, ['x', 'y']) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsIntersect(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsIntersect(I.anyOf[1])) Assert.IsTrue(TypeGuard.IsNumber(I.anyOf[1].allOf[0])) Assert.IsTrue(TypeGuard.IsString(I.anyOf[1].allOf[1])) }) it('Should Index 26', () => { const T = Type.Recursive((This) => Type.Object({ x: Type.String(), y: Type.Number(), z: This, }), ) const I = Type.Index(T, ['x', 'y', 'z']) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsString(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsNumber(I.anyOf[1])) Assert.IsTrue(TypeGuard.IsThis(I.anyOf[2])) }) it('Should Index 27', () => { const T = Type.Object({ 0: Type.String(), 1: Type.Number(), }) const I = Type.Index(T, [0, 1]) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsString(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsNumber(I.anyOf[1])) }) it('Should Index 28', () => { const T = Type.Object({ 0: Type.String(), '1': Type.Number(), }) const I = Type.Index(T, [0, '1']) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsString(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsNumber(I.anyOf[1])) }) it('Should Index 29', () => { const T = Type.Object({ 0: Type.String(), '1': Type.Number(), }) const I = Type.Index(T, Type.Union([Type.Literal(0), Type.Literal('1')])) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsString(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsNumber(I.anyOf[1])) }) it('Should Index 30', () => { const T = Type.Object({ 0: Type.String(), '1': Type.Number(), }) const I = Type.Index(T, Type.Union([Type.Literal(0), Type.Literal(1)])) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsString(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsNumber(I.anyOf[1])) // Note: Expect TNever for anyOf[1] but permit for TNumber due to IndexedAccess // Resolve() which currently cannot differentiate between string and numeric keys // on the object. This may be resolvable in later revisions, but test for this // fall-through to ensure case is documented. For review. }) // -------------------------------------------------------- // Modifier Optional Indexing // -------------------------------------------------------- it('Should Index 31', () => { const T = Type.Object({ x: Type.Optional(Type.String()), y: Type.Number(), }) const I = Type.Index(T, ['x']) Assert.IsTrue(TypeGuard.IsOptional(I)) Assert.IsTrue(TypeGuard.IsString(I)) }) it('Should Index 32', () => { const T = Type.Object({ x: Type.Optional(Type.String()), y: Type.Number(), }) const I = Type.Index(T, ['y']) Assert.IsFalse(TypeGuard.IsOptional(I)) Assert.IsTrue(TypeGuard.IsNumber(I)) }) it('Should Index 33', () => { const T = Type.Object({ x: Type.Optional(Type.String()), y: Type.Number(), }) const I = Type.Index(T, ['x', 'y']) Assert.IsTrue(TypeGuard.IsOptional(I)) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsString(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsNumber(I.anyOf[1])) }) it('Should Index 34', () => { const T = Type.String() const I = Type.Index(T, ['x']) Assert.IsTrue(TypeGuard.IsNever(I)) }) it('Should Index 35', () => { const T = Type.Array(Type.String()) const I = Type.Index(T, Type.Number()) Assert.IsTrue(TypeGuard.IsString(I)) }) it('Should Index 36', () => { const T = Type.Array(Type.String()) const I = Type.Index(T, ['[number]']) Assert.IsTrue(TypeGuard.IsString(I)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/integer.ts000066400000000000000000000027451505437577000260030ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TInteger', () => { it('Should guard for TInteger', () => { const R = TypeGuard.IsInteger(Type.Integer()) Assert.IsTrue(R) }) it('Should not guard for TInteger', () => { const R = TypeGuard.IsInteger(null) Assert.IsFalse(R) }) it('Should not guard for TInteger with invalid $id', () => { // @ts-ignore const R = TypeGuard.IsInteger(Type.Integer({ $id: 1 })) Assert.IsFalse(R) }) it('Should not guard for TInteger with invalid multipleOf', () => { // @ts-ignore const R = TypeGuard.IsInteger(Type.Integer({ multipleOf: '1' })) Assert.IsFalse(R) }) it('Should not guard for TInteger with invalid minimum', () => { // @ts-ignore const R = TypeGuard.IsInteger(Type.Integer({ minimum: '1' })) Assert.IsFalse(R) }) it('Should not guard for TInteger with invalid maximum', () => { // @ts-ignore const R = TypeGuard.IsInteger(Type.Integer({ maximum: '1' })) Assert.IsFalse(R) }) it('Should not guard for TInteger with invalid exclusiveMinimum', () => { // @ts-ignore const R = TypeGuard.IsInteger(Type.Integer({ exclusiveMinimum: '1' })) Assert.IsFalse(R) }) it('Should not guard for TInteger with invalid exclusiveMaximum', () => { // @ts-ignore const R = TypeGuard.IsInteger(Type.Integer({ exclusiveMaximum: '1' })) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/intersect.ts000066400000000000000000000016601505437577000263410ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TIntersect', () => { it('Should guard for TIntersect', () => { const R = TypeGuard.IsIntersect( Type.Intersect([ Type.Object({ x: Type.Number(), }), Type.Object({ y: Type.Number(), }), ]), ) Assert.IsTrue(R) }) it('Should not guard for TIntersect', () => { const R = TypeGuard.IsIntersect( Type.Union([ Type.Object({ x: Type.Number(), }), Type.Object({ y: Type.Number(), }), ]), ) Assert.IsFalse(R) }) it('Should throw for intersected transform types', () => { const N = Type.Transform(Type.Number()) .Decode((value) => value) .Encode((value) => value) Assert.Throws(() => Type.Intersect([N, N])) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/iterator.ts000066400000000000000000000012171505437577000261700ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TIterator', () => { it('Should guard for TIterator', () => { const T = Type.Iterator(Type.Any()) const R = TypeGuard.IsIterator(T) Assert.IsTrue(R) }) it('Should not guard for TIterator', () => { const T = null const R = TypeGuard.IsIterator(T) Assert.IsFalse(R) }) it('Should not guard for TIterator with invalid $id', () => { //@ts-ignore const T = Type.Iterator(Type.Any(), { $id: 1 }) const R = TypeGuard.IsIterator(T) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/keyof.ts000066400000000000000000000040121505437577000254500ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TKeyOf', () => { it('Should KeyOf 1', () => { const T = Type.Object({ x: Type.Number(), y: Type.Number(), }) const K = Type.KeyOf(T) Assert.IsTrue(TypeGuard.IsUnion(K)) Assert.IsTrue(TypeGuard.IsLiteral(K.anyOf[0])) Assert.IsTrue(TypeGuard.IsLiteral(K.anyOf[1])) }) it('Should KeyOf 2', () => { const T = Type.Recursive((Self) => Type.Object({ x: Type.Number(), y: Type.Array(Self), }), ) const K = Type.KeyOf(T) Assert.IsTrue(TypeGuard.IsUnion(K)) Assert.IsTrue(TypeGuard.IsLiteral(K.anyOf[0])) Assert.IsTrue(TypeGuard.IsLiteral(K.anyOf[1])) }) it('Should KeyOf 3', () => { const T = Type.Intersect([ Type.Object({ x: Type.Number(), }), Type.Object({ y: Type.Number(), }), ]) const K = Type.KeyOf(T) Assert.IsTrue(TypeGuard.IsUnion(K)) Assert.IsTrue(TypeGuard.IsLiteral(K.anyOf[0])) Assert.IsTrue(TypeGuard.IsLiteral(K.anyOf[1])) }) it('Should KeyOf 4', () => { const T = Type.Union([ Type.Object({ x: Type.Number(), }), Type.Object({ y: Type.Number(), }), ]) const K = Type.KeyOf(T) Assert.IsTrue(TypeGuard.IsNever(K)) }) it('Should KeyOf 5', () => { const T = Type.Null() const K = Type.KeyOf(T) Assert.IsTrue(TypeGuard.IsNever(K)) }) it('Should KeyOf 6', () => { const T = Type.Array(Type.Number()) const K = Type.KeyOf(T) Assert.IsTrue(TypeGuard.IsNumber(K)) }) it('Should KeyOf 7', () => { const T = Type.Tuple([]) const K = Type.KeyOf(T) Assert.IsTrue(TypeGuard.IsNever(K)) }) it('Should KeyOf 8', () => { const T = Type.Tuple([Type.Number(), Type.Null()]) const K = Type.KeyOf(T) Assert.IsTrue(TypeGuard.IsUnion(K)) Assert.IsEqual(K.anyOf[0].const, '0') Assert.IsEqual(K.anyOf[1].const, '1') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/kind.ts000066400000000000000000000005251505437577000252650ustar00rootroot00000000000000import { TypeGuard, Kind } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TKind', () => { it('Should guard 1', () => { const T = { [Kind]: 'Kind' } Assert.IsTrue(TypeGuard.IsKind(T)) }) it('Should guard 2', () => { const T = {} Assert.IsFalse(TypeGuard.IsKind(T)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/literal.ts000066400000000000000000000017661505437577000260040ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TLiteral', () => { it('Should guard for TLiteral of String', () => { const R = TypeGuard.IsLiteral(Type.Literal('hello')) Assert.IsTrue(R) }) it('Should guard for TLiteral of Number', () => { const R = TypeGuard.IsLiteral(Type.Literal(42)) Assert.IsTrue(R) }) it('Should guard for TLiteral of Boolean', () => { const R = TypeGuard.IsLiteral(Type.Literal(true)) Assert.IsTrue(R) }) it('Should not guard for TLiteral of Null', () => { // @ts-ignore const R = TypeGuard.IsLiteral(Type.Literal(null)) Assert.IsFalse(R) }) it('Should not guard for TLiteral', () => { const R = TypeGuard.IsLiteral(null) Assert.IsFalse(R) }) it('Should not guard for TLiteral with invalid $id', () => { // @ts-ignore const R = TypeGuard.IsLiteral(Type.Literal(42, { $id: 1 })) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/lowercase.ts000066400000000000000000000025171505437577000263270ustar00rootroot00000000000000import { TypeGuard, Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/Lowercase', () => { it('Should guard for Lowercase 1', () => { const T = Type.Lowercase(Type.Literal('HELLO'), { $id: 'hello', foo: 1 }) Assert.IsTrue(TypeGuard.IsLiteral(T)) Assert.IsEqual(T.const, 'hello') Assert.IsEqual(T.$id, 'hello') Assert.IsEqual(T.foo, 1) }) it('Should guard for Lowercase 2', () => { const T = Type.Lowercase(Type.Literal('HELLO')) Assert.IsTrue(TypeGuard.IsLiteral(T)) Assert.IsEqual(T.const, 'hello') }) it('Should guard for Lowercase 3', () => { const T = Type.Lowercase(Type.Union([Type.Literal('HELLO'), Type.Literal('WORLD')])) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, 'hello') Assert.IsEqual(T.anyOf[1].const, 'world') }) it('Should guard for Lowercase 4', () => { const T = Type.Lowercase(Type.TemplateLiteral('HELLO${0|1}')) Assert.IsTrue(TypeGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(hello0|hello1)$') }) it('Should guard for Lowercase 5', () => { const T = Type.Lowercase(Type.TemplateLiteral([Type.Literal('HELLO'), Type.Union([Type.Literal(0), Type.Literal(1)])])) Assert.IsTrue(TypeGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(hello0|hello1)$') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/mapped.ts000066400000000000000000000450251505437577000256120ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' // prettier-ignore describe('guard/type/Mapped', () => { it('Should guard mapped 1', () => { const T = Type.Mapped(Type.Union([ Type.Literal('x'), Type.Literal('y'), Type.Literal('z'), ]), _ => Type.Number(), { custom: 1 }) Assert.IsEqual(T, Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number() }, { custom: 1 })) }) it('Should guard mapped 2', () => { const T = Type.Mapped(Type.Union([ Type.Literal('x'), Type.Literal('y'), Type.Literal('z'), ]), _ => Type.Number()) Assert.IsEqual(T, Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number() })) }) it('Should guard mapped 3', () => { const T = Type.Mapped(Type.Union([ Type.Literal('x'), Type.Literal('y'), Type.Literal('z'), ]), K => K) Assert.IsEqual(T, Type.Object({ x: Type.Literal('x'), y: Type.Literal('y'), z: Type.Literal('z'), })) }) it('Should guard mapped 4', () => { const T = Type.Mapped(Type.TemplateLiteral('${0|1}${0|1}'), K => Type.Number()) Assert.IsEqual(T, Type.Object({ '00': Type.Number(), '01': Type.Number(), '10': Type.Number(), '11': Type.Number(), })) }) it('Should guard mapped 5', () => { const T = Type.Mapped(Type.TemplateLiteral('${a|b}'), X => Type.Mapped(Type.TemplateLiteral('${c|d}'), Y => Type.Mapped(Type.TemplateLiteral('${e|f}'), Z => Type.Tuple([X, Y, Z]) ) ) ) Assert.IsEqual(T, Type.Object({ a: Type.Object({ c: Type.Object({ e: Type.Tuple([Type.Literal("a"), Type.Literal("c"), Type.Literal("e")]), f: Type.Tuple([Type.Literal("a"), Type.Literal("c"), Type.Literal("f")]) }), d: Type.Object({ e: Type.Tuple([Type.Literal("a"), Type.Literal("d"), Type.Literal("e")]), f: Type.Tuple([Type.Literal("a"), Type.Literal("d"), Type.Literal("f")]) }), }), b: Type.Object({ c: Type.Object({ e: Type.Tuple([Type.Literal("b"), Type.Literal("c"), Type.Literal("e")]), f: Type.Tuple([Type.Literal("b"), Type.Literal("c"), Type.Literal("f")]) }), d: Type.Object({ e: Type.Tuple([Type.Literal("b"), Type.Literal("d"), Type.Literal("e")]), f: Type.Tuple([Type.Literal("b"), Type.Literal("d"), Type.Literal("f")]) }), }), })) }) it('Should guard mapped 6', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), z: Type.Boolean() }) const M = Type.Mapped(Type.KeyOf(T), K => K) Assert.IsEqual(M, Type.Object({ x: Type.Literal('x'), y: Type.Literal('y'), z: Type.Literal('z') })) }) it('Should guard mapped 7', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), z: Type.Boolean() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.Index(T, K)) Assert.IsEqual(M, Type.Object({ x: Type.Number(), y: Type.String(), z: Type.Boolean() })) }) it('Should guard mapped 8', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), z: Type.Boolean() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.Index(T, K, { custom: 1 })) Assert.IsEqual(M, Type.Object({ x: Type.Number({ custom: 1 }), y: Type.String({ custom: 1 }), z: Type.Boolean({ custom: 1 }) })) }) // ---------------------------------------------------------------- // Extract // ---------------------------------------------------------------- it('Should guard mapped 9', () => { const T = Type.Object({ x: Type.Union([Type.String(), Type.Number(), Type.Boolean()]) }) const M = Type.Mapped(Type.KeyOf(T), K => { return Type.Extract(Type.Index(T, K), Type.String()) }) Assert.IsEqual(M, Type.Object({ x: Type.String() })) }) it('Should guard mapped 10', () => { const T = Type.Object({ x: Type.Union([Type.String(), Type.Number(), Type.Boolean()]) }) const M = Type.Mapped(Type.KeyOf(T), K => { return Type.Extract(Type.Index(T, K), Type.Union([ Type.String(), Type.Number() ])) }) Assert.IsEqual(M, Type.Object({ x: Type.Union([Type.String(), Type.Number()]) })) }) it('Should guard mapped 11', () => { const T = Type.Object({ x: Type.Union([Type.String(), Type.Number(), Type.Boolean()]) }) const M = Type.Mapped(Type.KeyOf(T), K => { return Type.Extract(Type.Index(T, K), Type.Null()) }) Assert.IsEqual(M, Type.Object({ x: Type.Never() })) }) // ---------------------------------------------------------------- // Extends // ---------------------------------------------------------------- it('Should guard mapped 12', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), z: Type.Boolean() }) const M = Type.Mapped(Type.KeyOf(T), K => { return ( Type.Extends(K, Type.Literal('x'), Type.Literal(1), Type.Extends(K, Type.Literal('y'), Type.Literal(2), Type.Extends(K, Type.Literal('z'), Type.Literal(3), Type.Never()))) ) }) Assert.IsEqual(M, Type.Object({ x: Type.Literal(1), y: Type.Literal(2), z: Type.Literal(3), })) }) it('Should guard mapped 13', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), z: Type.Boolean() }) const M = Type.Mapped(Type.KeyOf(T), K => { return ( Type.Extends(Type.Index(T, K), Type.Number(), Type.Literal(3), Type.Extends(Type.Index(T, K), Type.String(), Type.Literal(2), Type.Extends(Type.Index(T, K), Type.Boolean(), Type.Literal(1), Type.Never()))) ) }) Assert.IsEqual(M, Type.Object({ x: Type.Literal(3), y: Type.Literal(2), z: Type.Literal(1), })) }) // ---------------------------------------------------------------- // Exclude // ---------------------------------------------------------------- it('Should guard mapped 14', () => { const T = Type.Object({ x: Type.Union([Type.String(), Type.Number(), Type.Boolean()]) }) const M = Type.Mapped(Type.KeyOf(T), K => { return Type.Exclude(Type.Index(T, K), Type.String()) }) Assert.IsEqual(M, Type.Object({ x: Type.Union([Type.Number(), Type.Boolean()]) })) }) it('Should guard mapped 15', () => { const T = Type.Object({ x: Type.Union([Type.String(), Type.Number(), Type.Boolean()]) }) const M = Type.Mapped(Type.KeyOf(T), K => { return Type.Exclude(Type.Index(T, K), Type.Union([ Type.String(), Type.Number() ])) }) Assert.IsEqual(M, Type.Object({ x: Type.Boolean() })) }) it('Should guard mapped 16', () => { const T = Type.Object({ x: Type.Union([Type.String(), Type.Number(), Type.Boolean()]) }) const M = Type.Mapped(Type.KeyOf(T), K => { return Type.Exclude(Type.Index(T, K), Type.Null()) }) Assert.IsEqual(M, Type.Object({ x: Type.Union([Type.String(), Type.Number(), Type.Boolean()]) })) }) // ---------------------------------------------------------------- // Non-Evaluated // ---------------------------------------------------------------- it('Should guard mapped 17', () => { const T = Type.Object({ x: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.Array(Type.Index(T, K))) Assert.IsEqual(M, Type.Object({ x: Type.Array(Type.Number()) })) }) it('Should guard mapped 18', () => { const T = Type.Object({ x: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.Promise(Type.Index(T, K))) Assert.IsEqual(M, Type.Object({ x: Type.Promise(Type.Number()) })) }) it('Should guard mapped 19', () => { const T = Type.Object({ x: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.Function([Type.Index(T, K)], Type.Index(T, K))) Assert.IsEqual(M, Type.Object({ x: Type.Function([Type.Number()], Type.Number())})) }) it('Should guard mapped 20', () => { const T = Type.Object({ x: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.Tuple([Type.Index(T, K), Type.Index(T, K)])) Assert.IsEqual(M, Type.Object({ x: Type.Tuple([Type.Number(), Type.Number()]) })) }) it('Should guard mapped 21', () => { const T = Type.Object({ x: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.Union([Type.Index(T, K), Type.Index(T, K)])) Assert.IsEqual(M, Type.Object({ x: Type.Union([Type.Number(), Type.Number()]) })) }) it('Should guard mapped 22', () => { const T = Type.Object({ x: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.Intersect([Type.Index(T, K), Type.Index(T, K)])) Assert.IsEqual(M, Type.Object({ x: Type.Intersect([Type.Number(), Type.Number()]) })) }) // ---------------------------------------------------------------- // Numeric Keys // ---------------------------------------------------------------- it('Should guard mapped 23', () => { const T = Type.Object({ 0: Type.Number(), 1: Type.Number(), 2: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), K => K) Assert.IsEqual(M, Type.Object({ 0: Type.Literal('0'), 1: Type.Literal('1'), 2: Type.Literal('2'), })) }) it('Should guard mapped 24', () => { const T = Type.Object({ 0: Type.Number(), 1: Type.Number(), 2: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.Index(T, K)) Assert.IsEqual(M, Type.Object({ 0: Type.Number(), 1: Type.Number(), 2: Type.Number(), })) }) it('Should guard mapped 25', () => { const T = Type.Object({ 0: Type.Number(), 1: Type.Number(), 2: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.String()) Assert.IsEqual(M, Type.Object({ 0: Type.String(), 1: Type.String(), 2: Type.String(), })) }) it('Should guard mapped 26', () => { const T = Type.Object({ 0: Type.Number(), 1: Type.Number(), 2: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), K => Type.Extends(K, Type.Literal('1'), Type.String(), Type.Number())) Assert.IsEqual(M, Type.Object({ 0: Type.Number(), 1: Type.String(), 2: Type.Number(), })) }) // ---------------------------------------------------------------- // Modifiers: Optional // ---------------------------------------------------------------- it('Should guard mapped 27', () => { const T = Type.Object({ x: Type.Optional(Type.Number()), y: Type.Number() }) // subtractive const M = Type.Mapped(Type.KeyOf(T), K => Type.Optional(Type.Index(T, K), false)) Assert.IsEqual(M, Type.Object({ x: Type.Number(), y: Type.Number() })) }) it('Should guard mapped 28', () => { const T = Type.Object({ x: Type.Optional(Type.Number()), y: Type.Number() }) // additive const M = Type.Mapped(Type.KeyOf(T), K => Type.Optional(Type.Index(T, K), true)) Assert.IsEqual(M, Type.Object({ x: Type.Optional(Type.Number()), y: Type.Optional(Type.Number()) })) }) // ---------------------------------------------------------------- // Modifiers: Readonly // ---------------------------------------------------------------- it('Should guard mapped 27', () => { const T = Type.Object({ x: Type.Readonly(Type.Number()), y: Type.Number() }) // subtractive const M = Type.Mapped(Type.KeyOf(T), K => Type.Readonly(Type.Index(T, K), false)) Assert.IsEqual(M, Type.Object({ x: Type.Number(), y: Type.Number() })) }) it('Should guard mapped 28', () => { const T = Type.Object({ x: Type.Readonly(Type.Number()), y: Type.Number() }) // additive const M = Type.Mapped(Type.KeyOf(T), K => Type.Readonly(Type.Index(T, K), true)) Assert.IsEqual(M, Type.Object({ x: Type.Readonly(Type.Number()), y: Type.Readonly(Type.Number()) })) }) // ---------------------------------------------------------------- // Finite Boolean // ---------------------------------------------------------------- it('Should guard mapped 29', () => { const T = Type.TemplateLiteral('${boolean}') const M = Type.Mapped(T, K => K) Assert.IsEqual(M, Type.Object({ true: Type.Literal('true'), false: Type.Literal('false'), })) }) it('Should guard mapped 30', () => { const T = Type.TemplateLiteral('${0|1}${boolean}') const M = Type.Mapped(T, K => K) Assert.IsEqual(M, Type.Object({ '0true': Type.Literal('0true'), '0false': Type.Literal('0false'), '1true': Type.Literal('1true'), '1false': Type.Literal('1false'), })) }) it('Should guard mapped 31', () => { const T = Type.TemplateLiteral('${boolean}${0|1}') const M = Type.Mapped(T, K => K) Assert.IsEqual(M, Type.Object({ 'true0': Type.Literal('true0'), 'true1': Type.Literal('true1'), 'false0': Type.Literal('false0'), 'false1': Type.Literal('false1'), })) }) // ---------------------------------------------------------------- // Numeric Mapping // ---------------------------------------------------------------- it('Should guard mapped 32', () => { const T = Type.TemplateLiteral([ Type.Union([Type.Literal(0), Type.Literal(1)]), Type.Union([Type.Literal(0), Type.Literal(1)]), ]) const M = Type.Mapped(T, (K) => K) Assert.IsEqual(M, Type.Object({ '00': Type.Literal('00'), '01': Type.Literal('01'), '10': Type.Literal('10'), '11': Type.Literal('11'), })) }) // ---------------------------------------------------------------- // Indexed Key Remap // ---------------------------------------------------------------- it('Should guard mapped 33', () => { const T = Type.Object({ hello: Type.Number(), world: Type.String(), }) const M = Type.Mapped(Type.Uppercase(Type.KeyOf(T)), (K) => { return Type.Index(T, Type.Lowercase(K)) }) Assert.IsEqual(M, Type.Object({ HELLO: Type.Number(), WORLD: Type.String() })) }) // ---------------------------------------------------------------- // Partial // ---------------------------------------------------------------- it('Should guard mapped 34', () => { const T = Type.Object({ x: Type.Object({ x: Type.Number(), y: Type.Number(), }), y: Type.Object({ x: Type.Number(), y: Type.Number(), }), }) const M = Type.Mapped(Type.KeyOf(T), (K) => { return Type.Partial(Type.Index(T, K)) }) Assert.IsEqual(M, Type.Object({ x: Type.Partial(Type.Object({ x: Type.Optional(Type.Number()), y: Type.Optional(Type.Number()), })), y: Type.Partial(Type.Object({ x: Type.Optional(Type.Number()), y: Type.Optional(Type.Number()), })), })) }) // ---------------------------------------------------------------- // Required // ---------------------------------------------------------------- it('Should guard mapped 35', () => { const T = Type.Object({ x: Type.Partial(Type.Object({ x: Type.Number(), y: Type.Number(), })), y: Type.Partial(Type.Object({ x: Type.Number(), y: Type.Number(), })), }) const M = Type.Mapped(Type.KeyOf(T), (K) => { return Type.Required(Type.Index(T, K)) }) Assert.IsEqual(M, Type.Object({ x: Type.Object({ x: Type.Number(), y: Type.Number(), }), y: Type.Object({ x: Type.Number(), y: Type.Number(), }), })) }) // ------------------------------------------------------------------ // Pick With Key // ------------------------------------------------------------------ it('Should guard mapped 36', () => { const T = Type.Object({ x: Type.Object({ x: Type.Number(), y: Type.Number() }), y: Type.Object({ x: Type.Number(), y: Type.Number() }) }) const M = Type.Mapped(Type.KeyOf(T), K => { return Type.Pick(T, K) }) Assert.IsEqual(M, Type.Object({ x: Type.Object({ x: Type.Object({ x: Type.Number(), y: Type.Number(), }) }), y: Type.Object({ y: Type.Object({ x: Type.Number(), y: Type.Number(), }) }), })) }) // ------------------------------------------------------------------ // Pick With Result // ------------------------------------------------------------------ it('Should guard mapped 37', () => { const T = Type.Object({ x: Type.Object({ x: Type.Number(), y: Type.Number(), }), y: Type.Object({ x: Type.Number(), y: Type.Number(), }), }) const M = Type.Mapped(Type.KeyOf(T), (K) => { return Type.Pick(Type.Index(T, K), ['x']) }) Assert.IsEqual(M, Type.Object({ x: Type.Object({ x: Type.Number() }), y: Type.Object({ x: Type.Number() }) })) }) // ------------------------------------------------------------------ // Omit With Key // ------------------------------------------------------------------ it('Should guard mapped 36', () => { const T = Type.Object({ x: Type.Object({ x: Type.Number(), y: Type.Number() }), y: Type.Object({ x: Type.Number(), y: Type.Number() }) }) const M = Type.Mapped(Type.KeyOf(T), K => { return Type.Omit(T, K) }) Assert.IsEqual(M, Type.Object({ x: Type.Object({ y: Type.Object({ x: Type.Number(), y: Type.Number(), }) }), y: Type.Object({ x: Type.Object({ x: Type.Number(), y: Type.Number(), }) }), })) }) // ------------------------------------------------------------------ // Omit With Result // ------------------------------------------------------------------ it('Should guard mapped 37', () => { const T = Type.Object({ x: Type.Object({ x: Type.Number(), y: Type.Number(), }), y: Type.Object({ x: Type.Number(), y: Type.Number(), }), }) const M = Type.Mapped(Type.KeyOf(T), (K) => { return Type.Omit(Type.Index(T, K), ['x']) }) Assert.IsEqual(M, Type.Object({ x: Type.Object({ y: Type.Number() }), y: Type.Object({ y: Type.Number() }) })) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/not.ts000066400000000000000000000011131505437577000251320ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TNot', () => { it('Should guard for TNot', () => { const R = TypeGuard.IsNot(Type.Not(Type.String())) Assert.IsTrue(R) }) it('Should not guard for TNot 1', () => { const R = TypeGuard.IsNot(Type.Not(null as any)) Assert.IsFalse(R) }) it('Should not guard for TNot with invalid $id', () => { // @ts-ignore const R = TypeGuard.IsNot(Type.Not(Type.String()), { $id: 1 }) Assert.IsTrue(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/null.ts000066400000000000000000000010461505437577000253110ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TNull', () => { it('Should guard for TNull', () => { const R = TypeGuard.IsNull(Type.Null()) Assert.IsTrue(R) }) it('Should not guard for TNull', () => { const R = TypeGuard.IsNull(null) Assert.IsFalse(R) }) it('Should not guard for TNull with invalid $id', () => { // @ts-ignore const R = TypeGuard.IsNull(Type.Null({ $id: 1 })) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/number.ts000066400000000000000000000027151505437577000256330ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TNumber', () => { it('Should guard for TNumber', () => { const R = TypeGuard.IsNumber(Type.Number()) Assert.IsTrue(R) }) it('Should not guard for TNumber', () => { const R = TypeGuard.IsNumber(null) Assert.IsFalse(R) }) it('Should not guard for TNumber with invalid $id', () => { // @ts-ignore const R = TypeGuard.IsNumber(Type.Number({ $id: 1 })) Assert.IsFalse(R) }) it('Should not guard for TNumber with invalid multipleOf', () => { // @ts-ignore const R = TypeGuard.IsNumber(Type.Number({ multipleOf: '1' })) Assert.IsFalse(R) }) it('Should not guard for TNumber with invalid minimum', () => { // @ts-ignore const R = TypeGuard.IsNumber(Type.Number({ minimum: '1' })) Assert.IsFalse(R) }) it('Should not guard for TNumber with invalid maximum', () => { // @ts-ignore const R = TypeGuard.IsNumber(Type.Number({ maximum: '1' })) Assert.IsFalse(R) }) it('Should not guard for TNumber with invalid exclusiveMinimum', () => { // @ts-ignore const R = TypeGuard.IsNumber(Type.Number({ exclusiveMinimum: '1' })) Assert.IsFalse(R) }) it('Should not guard for TNumber with invalid exclusiveMaximum', () => { // @ts-ignore const R = TypeGuard.IsNumber(Type.Number({ exclusiveMaximum: '1' })) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/object.ts000066400000000000000000000052471505437577000256140ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TObject', () => { it('Should guard for TObject', () => { const R = TypeGuard.IsObject( Type.Object({ x: Type.Number(), y: Type.Number(), }), ) Assert.IsTrue(R) }) it('Should not guard for TObject', () => { const R = TypeGuard.IsObject(null) Assert.IsFalse(R) }) it('Should not guard for TObject with escape characters in property key', () => { const R = TypeGuard.IsObject( Type.Object({ 'hello\nworld': Type.Number(), }), ) Assert.IsFalse(R) }) it('Should not guard for TObject with invalid property values', () => { const R = TypeGuard.IsObject( Type.Object({ x: Type.Number(), y: {} as any, }), ) Assert.IsFalse(R) }) it('Should not guard for TObject with invalid additionalProperties', () => { const R = TypeGuard.IsObject( Type.Object( { x: Type.Number(), }, { // @ts-ignore additionalProperties: 'true', }, ), ) Assert.IsFalse(R) }) it('Should not guard for TObject with invalid $id', () => { const R = TypeGuard.IsObject( Type.Object( { x: Type.Number(), }, { // @ts-ignore $id: 1, }, ), ) Assert.IsFalse(R) }) it('Should not guard for TObject with invalid minProperties', () => { const R = TypeGuard.IsObject( Type.Object( { x: Type.Number(), }, { // @ts-ignore minProperties: '1', }, ), ) Assert.IsFalse(R) }) it('Should not guard for TObject with invalid maxProperties', () => { const R = TypeGuard.IsObject( Type.Object( { x: Type.Number(), }, { // @ts-ignore maxProperties: '1', }, ), ) Assert.IsFalse(R) }) it('Should guard for TObject with invalid additional properties', () => { const R = TypeGuard.IsObject( Type.Object( { x: Type.Number(), y: Type.Number(), }, { // @ts-ignore additionalProperties: 1, }, ), ) Assert.IsFalse(R) }) it('Should not guard for TObject with valid additional properties schema', () => { const R = TypeGuard.IsObject( Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.String(), }, ), ) Assert.IsTrue(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/omit.ts000066400000000000000000000142271505437577000253140ustar00rootroot00000000000000import { TypeGuard, Type, Kind, TransformKind } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TOmit', () => { // ------------------------------------------------------------------------- // case: https://github.com/sinclairzx81/typebox/issues/384 // ------------------------------------------------------------------------- it('Should support TUnsafe omit properties with no Kind', () => { const T = Type.Omit(Type.Object({ x: Type.Unsafe({ x: 1 }), y: Type.Number() }), ['x']) Assert.IsEqual(T.required, ['y']) }) it('Should support TUnsafe omit properties with unregistered Kind', () => { const T = Type.Omit(Type.Object({ x: Type.Unsafe({ x: 1, [Kind]: 'UnknownOmitType' }), y: Type.Number() }), ['x']) Assert.IsEqual(T.required, ['y']) }) // ------------------------------------------------------------------------- // Standard Tests // ------------------------------------------------------------------------- it('Should Omit 1', () => { const T = Type.Omit( Type.Object({ x: Type.Number(), y: Type.Number(), }), ['x'], ) Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) Assert.IsEqual(T.required, ['y']) }) it('Should Omit 2', () => { const T = Type.Omit( Type.Object({ x: Type.Number(), y: Type.Optional(Type.Number()), }), ['x'], ) Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) Assert.IsEqual(T.required, undefined) }) it('Should Omit 3', () => { const L = Type.Literal('x') const T = Type.Omit( Type.Object({ x: Type.Number(), y: Type.Number(), }), L, ) Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) Assert.IsEqual(T.required, ['y']) }) it('Should Omit 4', () => { const L = Type.Literal('x') const T = Type.Omit(Type.Intersect([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })]), L) Assert.IsEqual(TypeGuard.IsNumber(T.allOf[1].properties.y), true) // @ts-ignore Assert.IsEqual(T.allOf[1].properties.x, undefined) }) it('Should Omit 5', () => { const L = Type.Union([Type.Literal('x'), Type.Literal('y')]) const T = Type.Omit( Type.Object({ x: Type.Number(), y: Type.Number(), }), L, ) // @ts-ignore Assert.IsEqual(T.properties.x, undefined) // @ts-ignore Assert.IsEqual(T.properties.y, undefined) // @ts-ignore Assert.IsEqual(T.required, undefined) }) it('Should Omit 6', () => { const L = Type.Union([Type.Literal('x'), Type.Literal('y'), Type.Literal('z')]) const T = Type.Omit( Type.Object({ x: Type.Number(), y: Type.Number(), }), L, ) // @ts-ignore Assert.IsEqual(T.properties.x, undefined) // @ts-ignore Assert.IsEqual(T.properties.y, undefined) // @ts-ignore Assert.IsEqual(T.required, undefined) }) it('Should Omit 7', () => { const L = Type.TemplateLiteral([Type.Literal('a'), Type.Union([Type.Literal('b'), Type.Literal('c')])]) const T = Type.Omit( Type.Object({ ab: Type.Number(), ac: Type.Number(), ad: Type.Number(), }), L, ) Assert.IsTrue(TypeGuard.IsNumber(T.properties.ad)) Assert.IsEqual(T.required, ['ad']) }) // ---------------------------------------------------------------- // Discard // ---------------------------------------------------------------- it('Should override $id', () => { const A = Type.Object({ x: Type.Number() }, { $id: 'A' }) const T = Type.Omit(A, ['x'], { $id: 'T' }) Assert.IsEqual(T.$id!, 'T') }) it('Should discard $id', () => { const A = Type.Object({ x: Type.Number() }, { $id: 'A' }) const T = Type.Omit(A, ['x']) Assert.IsFalse('$id' in T) }) it('Should discard transform', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), }) const S = Type.Transform(T) .Decode((value) => value) .Encode((value) => value) const R = Type.Omit(S, ['x']) Assert.IsFalse(TransformKind in R) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/944 // ---------------------------------------------------------------- it('Should retain interior properties 1', () => { const A = Type.Object({ x: Type.Number() }, { additionalProperties: false }) const T = Type.Omit(A, ['x']) Assert.IsFalse(T.additionalProperties as boolean) }) it('Should retain interior properties 2', () => { const A = Type.Object({ x: Type.Number() }, { additionalProperties: false }) const B = Type.Object({ y: Type.Number() }, { additionalProperties: false }) const U = Type.Union([A, B]) const T = Type.Omit(U, ['x']) Assert.IsFalse(T.anyOf[0].additionalProperties as boolean) Assert.IsFalse(T.anyOf[1].additionalProperties as boolean) }) it('Should retain interior properties 3', () => { const A = Type.Object({ x: Type.Number() }, { additionalProperties: false }) const B = Type.Object({ y: Type.Number() }, { additionalProperties: false }) const U = Type.Intersect([A, B]) const T = Type.Omit(U, ['x']) Assert.IsFalse(T.allOf[0].additionalProperties as boolean) Assert.IsFalse(T.allOf[1].additionalProperties as boolean) }) it('Should retain interior properties 4', () => { const A = Type.Object({ x: Type.Number(), y: Type.Number() }, { additionalProperties: false }) const T = Type.Mapped(Type.TemplateLiteral('${x|y|z}'), (_) => Type.Omit(A, ['x'])) Assert.IsFalse(T.properties.x.additionalProperties as boolean) Assert.IsFalse(T.properties.y.additionalProperties as boolean) Assert.IsFalse(T.properties.z.additionalProperties as boolean) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/980 // ---------------------------------------------------------------- it('Should override properties in source type', () => { const A = Type.Object({ x: Type.Number() }, { title: 'A' }) const B = Type.Omit(A, ['x'], { title: 'B' }) Assert.IsEqual(A.title, 'A') Assert.IsEqual(B.title, 'B') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/partial.ts000066400000000000000000000102541505437577000257740ustar00rootroot00000000000000import { TypeGuard, TypeRegistry, Type, Kind, TransformKind } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TPartial', () => { it('Should produce a valid TSchema', () => { const T = Type.Partial(Type.Object({ x: Type.Number() })) Assert.IsTrue(TypeGuard.IsSchema(T)) }) // ------------------------------------------------------------------------- // case: https://github.com/sinclairzx81/typebox/issues/364 // ------------------------------------------------------------------------- it('Should support TUnsafe partial properties with no Kind', () => { const T = Type.Partial(Type.Object({ x: Type.Unsafe({ x: 1 }) })) Assert.IsEqual(T.required, undefined) }) it('Should support TUnsafe partial properties with unknown Kind', () => { const T = Type.Partial(Type.Object({ x: Type.Unsafe({ [Kind]: 'UnknownPartialType', x: 1 }) })) Assert.IsEqual(T.required, undefined) }) it('Should support TUnsafe partial properties with known Kind', () => { TypeRegistry.Set('KnownPartialType', () => true) const T = Type.Partial(Type.Object({ x: Type.Unsafe({ [Kind]: 'KnownPartialType', x: 1 }) })) Assert.IsEqual(T.required, undefined) }) it('Should support applying partial to intersect', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const I = Type.Intersect([A, B]) const T = Type.Partial(I) Assert.IsEqual(T.allOf.length, 2) Assert.IsEqual(T.allOf[0].required, undefined) Assert.IsEqual(T.allOf[1].required, undefined) }) it('Should support applying partial to union', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const I = Type.Union([A, B]) const T = Type.Partial(I) Assert.IsEqual(T.anyOf.length, 2) Assert.IsEqual(T.anyOf[0].required, undefined) Assert.IsEqual(T.anyOf[1].required, undefined) }) // ---------------------------------------------------------------- // Discard // ---------------------------------------------------------------- it('Should override $id', () => { const A = Type.Object({ x: Type.Number() }, { $id: 'A' }) const T = Type.Partial(A, { $id: 'T' }) Assert.IsEqual(T.$id!, 'T') }) it('Should discard $id', () => { const A = Type.Object({ x: Type.Number() }, { $id: 'A' }) const T = Type.Partial(A) Assert.IsFalse('$id' in T) }) it('Should discard transform', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), }) const S = Type.Transform(T) .Decode((value) => value) .Encode((value) => value) const R = Type.Partial(S) Assert.IsFalse(TransformKind in R) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/980 // ---------------------------------------------------------------- it('Should override properties in source type', () => { const A = Type.Object({ x: Type.Number() }, { title: 'A' }) const B = Type.Partial(A, { title: 'B' }) Assert.IsEqual(A.title, 'A') Assert.IsEqual(B.title, 'B') }) // ------------------------------------------------------------------ // Intrinsic Passthough // https://github.com/sinclairzx81/typebox/issues/1169 // ------------------------------------------------------------------ it('Should pass through on intrinsic types on union 1', () => { const T = Type.Partial( Type.Union([ Type.Number(), Type.Object({ x: Type.Number(), }), ]), ) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsTrue(TypeGuard.IsNumber(T.anyOf[0])) Assert.IsTrue(TypeGuard.IsObject(T.anyOf[1])) Assert.IsTrue(TypeGuard.IsOptional(T.anyOf[1].properties.x)) }) it('Should pass through on intrinsic types on union 2', () => { const T = Type.Partial( Type.Union([ Type.Literal(1), Type.Object({ x: Type.Number(), }), ]), ) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsTrue(TypeGuard.IsLiteral(T.anyOf[0])) Assert.IsTrue(TypeGuard.IsObject(T.anyOf[1])) Assert.IsTrue(TypeGuard.IsOptional(T.anyOf[1].properties.x)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/pick.ts000066400000000000000000000142561505437577000252740ustar00rootroot00000000000000import { TypeGuard, Type, Kind, TransformKind } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TPick', () => { // ------------------------------------------------------------------------- // case: https://github.com/sinclairzx81/typebox/issues/384 // ------------------------------------------------------------------------- it('Should support TUnsafe omit properties with no Kind', () => { const T = Type.Pick( Type.Object({ x: Type.Unsafe({ x: 1 }), y: Type.Number(), }), ['x'], ) Assert.IsEqual(T.required, ['x']) }) it('Should support TUnsafe omit properties with unregistered Kind', () => { const T = Type.Pick(Type.Object({ x: Type.Unsafe({ x: 1, [Kind]: 'UnknownPickType' }), y: Type.Number() }), ['x']) Assert.IsEqual(T.required, ['x']) }) // ------------------------------------------------------------------------- // Standard Tests // ------------------------------------------------------------------------- it('Should Pick 1', () => { const T = Type.Pick( Type.Object({ x: Type.Number(), y: Type.Number(), }), ['x'], ) Assert.IsTrue(TypeGuard.IsNumber(T.properties.x)) Assert.IsEqual(T.required, ['x']) }) it('Should Pick 2', () => { const T = Type.Pick( Type.Object({ x: Type.Optional(Type.Number()), y: Type.Number(), }), ['x'], ) Assert.IsTrue(TypeGuard.IsNumber(T.properties.x)) Assert.IsEqual(T.required, undefined) }) it('Should Pick 3', () => { const L = Type.Literal('x') const T = Type.Pick( Type.Object({ x: Type.Number(), y: Type.Number(), }), L, ) Assert.IsTrue(TypeGuard.IsNumber(T.properties.x)) Assert.IsEqual(T.required, ['x']) }) it('Should Pick 4', () => { const L = Type.Literal('x') const T = Type.Pick(Type.Intersect([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })]), L) Assert.IsTrue(TypeGuard.IsNumber(T.allOf[0].properties.x)) // @ts-ignore Assert.IsEqual(T.allOf[1].properties.y, undefined) }) it('Should Pick 5', () => { const L = Type.Union([Type.Literal('x'), Type.Literal('y')]) const T = Type.Pick( Type.Object({ x: Type.Number(), y: Type.Number(), }), L, ) Assert.IsTrue(TypeGuard.IsNumber(T.properties.x)) Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) Assert.IsEqual(T.required, ['x', 'y']) }) it('Should Pick 6', () => { const L = Type.Union([Type.Literal('x'), Type.Literal('y'), Type.Literal('z')]) const T = Type.Pick( Type.Object({ x: Type.Number(), y: Type.Number(), }), L, ) Assert.IsTrue(TypeGuard.IsNumber(T.properties.x)) Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) Assert.IsEqual(T.required, ['x', 'y']) }) it('Should Pick 7', () => { const L = Type.TemplateLiteral([Type.Literal('a'), Type.Union([Type.Literal('b'), Type.Literal('c')])]) const T = Type.Pick( Type.Object({ ab: Type.Number(), ac: Type.Number(), ad: Type.Number(), }), L, ) Assert.IsTrue(TypeGuard.IsNumber(T.properties.ab)) Assert.IsTrue(TypeGuard.IsNumber(T.properties.ac)) Assert.IsEqual(T.required, ['ab', 'ac']) }) // ---------------------------------------------------------------- // Discard // ---------------------------------------------------------------- it('Should override $id', () => { const A = Type.Object({ x: Type.Number() }, { $id: 'A' }) const T = Type.Pick(A, ['x'], { $id: 'T' }) Assert.IsEqual(T.$id!, 'T') }) it('Should discard $id', () => { const A = Type.Object({ x: Type.Number() }, { $id: 'A' }) const T = Type.Pick(A, ['x']) Assert.IsFalse('$id' in T) }) it('Should discard transform', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), }) const S = Type.Transform(T) .Decode((value) => value) .Encode((value) => value) const R = Type.Pick(S, ['x']) Assert.IsFalse(TransformKind in R) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/944 // ---------------------------------------------------------------- it('Should retain interior properties 1', () => { const A = Type.Object({ x: Type.Number() }, { additionalProperties: false }) const T = Type.Pick(A, ['x']) Assert.IsFalse(T.additionalProperties as boolean) }) it('Should retain interior properties 2', () => { const A = Type.Object({ x: Type.Number() }, { additionalProperties: false }) const B = Type.Object({ y: Type.Number() }, { additionalProperties: false }) const U = Type.Union([A, B]) const T = Type.Pick(U, ['x']) Assert.IsFalse(T.anyOf[0].additionalProperties as boolean) Assert.IsFalse(T.anyOf[1].additionalProperties as boolean) }) it('Should retain interior properties 3', () => { const A = Type.Object({ x: Type.Number() }, { additionalProperties: false }) const B = Type.Object({ y: Type.Number() }, { additionalProperties: false }) const U = Type.Intersect([A, B]) const T = Type.Pick(U, ['x']) Assert.IsFalse(T.allOf[0].additionalProperties as boolean) Assert.IsFalse(T.allOf[1].additionalProperties as boolean) }) it('Should retain interior properties 4', () => { const A = Type.Object({ x: Type.Number(), y: Type.Number() }, { additionalProperties: false }) const T = Type.Mapped(Type.TemplateLiteral('${x|y|z}'), (_) => Type.Pick(A, ['x'])) Assert.IsFalse(T.properties.x.additionalProperties as boolean) Assert.IsFalse(T.properties.y.additionalProperties as boolean) Assert.IsFalse(T.properties.z.additionalProperties as boolean) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/980 // ---------------------------------------------------------------- it('Should override properties in source type', () => { const A = Type.Object({ x: Type.Number() }, { title: 'A' }) const B = Type.Pick(A, ['x'], { title: 'B' }) Assert.IsEqual(A.title, 'A') Assert.IsEqual(B.title, 'B') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/promise.ts000066400000000000000000000021161505437577000260140ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TPromise', () => { it('Should guard for TPromise', () => { const R = TypeGuard.IsPromise(Type.Promise(Type.Number())) Assert.IsTrue(R) }) it('Should not guard for TPromise', () => { const R = TypeGuard.IsPromise(null) Assert.IsFalse(R) }) it('Should not guard for TPromise with invalid $id', () => { // @ts-ignore const R = TypeGuard.IsPromise(Type.Promise(Type.Number(), { $id: 1 })) Assert.IsFalse(R) }) it('Should guard for TPromise with nested TObject', () => { const R = TypeGuard.IsPromise( Type.Promise( Type.Object({ x: Type.Number(), y: Type.Number(), }), ), ) Assert.IsTrue(R) }) it('Should not guard for TPromise with nested TObject', () => { const R = TypeGuard.IsPromise( Type.Promise( Type.Object({ x: Type.Number(), y: {} as any, }), ), ) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/record.ts000066400000000000000000000206171505437577000256220ustar00rootroot00000000000000import { TypeGuard, PatternNumberExact, PatternStringExact, PatternNeverExact, PatternString, PatternNumber } from '@sinclair/typebox' import { Type, RecordKey, RecordValue, RecordPattern } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TRecord', () => { // ------------------------------------------------------------- // Overloads // ------------------------------------------------------------- it('Should guard overload 1', () => { const T = Type.Record(Type.Union([Type.Literal('A'), Type.Literal('B')]), Type.String(), { extra: 1 }) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsString(T.properties.A)) Assert.IsTrue(TypeGuard.IsString(T.properties.B)) Assert.IsEqual(T.extra, 1) }) it('Should guard overload 2', () => { const T = Type.Record(Type.Union([Type.Literal('A')]), Type.String(), { extra: 1 }) // unwrap as literal Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsString(T.properties.A)) Assert.IsEqual(T.extra, 1) }) it('Should guard overload 3', () => { // @ts-ignore const N = Type.Union([]) // Never const T = Type.Record(N, Type.String(), { extra: 1 }) Assert.IsTrue(TypeGuard.IsRecord(T)) Assert.IsTrue(TypeGuard.IsString(T.patternProperties[PatternNeverExact])) Assert.IsEqual(T.extra, 1) }) it('Should guard overload 4', () => { // @ts-ignore const T = Type.Record(Type.BigInt(), Type.String(), { extra: 1 }) Assert.IsTrue(TypeGuard.IsNever(T)) }) it('Should guard overload 5', () => { const T = Type.Record(Type.Literal('A'), Type.String(), { extra: 1 }) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsString(T.properties.A)) Assert.IsEqual(T.extra, 1) }) it('Should guard overload 6', () => { const L = Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal('A'), Type.Literal('B')])]) const T = Type.Record(L, Type.String(), { extra: 1 }) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsString(T.properties.helloA)) Assert.IsTrue(TypeGuard.IsString(T.properties.helloB)) Assert.IsEqual(T.extra, 1) }) it('Should guard overload 7', () => { const T = Type.Record(Type.Number(), Type.String(), { extra: 1 }) Assert.IsTrue(TypeGuard.IsRecord(T)) Assert.IsTrue(TypeGuard.IsString(T.patternProperties[PatternNumberExact])) Assert.IsEqual(T.extra, 1) }) it('Should guard overload 8', () => { const T = Type.Record(Type.Integer(), Type.String(), { extra: 1 }) Assert.IsTrue(TypeGuard.IsRecord(T)) Assert.IsTrue(TypeGuard.IsString(T.patternProperties[PatternNumberExact])) Assert.IsEqual(T.extra, 1) }) it('Should guard overload 9', () => { const T = Type.Record(Type.String(), Type.String(), { extra: 1 }) Assert.IsTrue(TypeGuard.IsRecord(T)) Assert.IsTrue(TypeGuard.IsString(T.patternProperties[PatternStringExact])) Assert.IsEqual(T.extra, 1) }) it('Should guard overload 10', () => { const L = Type.TemplateLiteral([Type.String(), Type.Literal('_foo')]) const T = Type.Record(L, Type.String(), { extra: 1 }) Assert.IsTrue(TypeGuard.IsRecord(T)) Assert.IsTrue(TypeGuard.IsString(T.patternProperties[`^${PatternString}_foo$`])) Assert.IsEqual(T.extra, 1) }) it('Should guard overload 11', () => { const L = Type.Union([Type.Literal('A'), Type.Union([Type.Literal('B'), Type.Literal('C')])]) const T = Type.Record(L, Type.String()) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsString(T.properties.A)) Assert.IsTrue(TypeGuard.IsString(T.properties.B)) Assert.IsTrue(TypeGuard.IsString(T.properties.C)) }) it('Should guard overload 12', () => { enum E { A = 'X', B = 'Y', C = 'Z', } const T = Type.Enum(E) const R = Type.Record(T, Type.Null()) Assert.IsTrue(TypeGuard.IsObject(R)) Assert.IsTrue(TypeGuard.IsNull(R.properties.X)) Assert.IsTrue(TypeGuard.IsNull(R.properties.Y)) Assert.IsTrue(TypeGuard.IsNull(R.properties.Z)) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/916 // // Added overload for Any and Never Keys // ---------------------------------------------------------------- it('Should guard overload 13', () => { // @ts-ignore const T = Type.Record(Type.Never(), Type.String(), { extra: 1 }) Assert.IsTrue(TypeGuard.IsRecord(T)) Assert.IsTrue(TypeGuard.IsString(T.patternProperties[PatternNeverExact])) Assert.IsEqual(T.extra, 1) }) it('Should guard overload 14', () => { // @ts-ignore const T = Type.Record(Type.Any(), Type.String(), { extra: 1 }) Assert.IsTrue(TypeGuard.IsRecord(T)) Assert.IsTrue(TypeGuard.IsString(T.patternProperties[PatternStringExact])) Assert.IsEqual(T.extra, 1) }) // ------------------------------------------------------------- // Variants // ------------------------------------------------------------- it('Should guard for TRecord', () => { const R = TypeGuard.IsRecord(Type.Record(Type.String(), Type.Number())) Assert.IsTrue(R) }) it('Should guard for TRecord with TObject value', () => { const R = TypeGuard.IsRecord( Type.Record( Type.String(), Type.Object({ x: Type.Number(), y: Type.Number(), }), ), ) Assert.IsTrue(R) }) it('Should not guard for TRecord', () => { const R = TypeGuard.IsRecord(null) Assert.IsFalse(R) }) it('Should not guard for TRecord with invalid $id', () => { // @ts-ignore const R = TypeGuard.IsRecord(Type.Record(Type.String(), Type.Number(), { $id: 1 })) Assert.IsFalse(R) }) it('Should not guard for TRecord with TObject value with invalid Property', () => { const R = TypeGuard.IsRecord( Type.Record( Type.String(), Type.Object({ x: Type.Number(), y: {} as any, }), ), ) Assert.IsFalse(R) }) it('Normalize: Should normalize to TObject for single literal union value', () => { const K = Type.Union([Type.Literal('ok')]) const R = TypeGuard.IsObject(Type.Record(K, Type.Number())) Assert.IsTrue(R) }) it('Normalize: Should normalize to TObject for multi literal union value', () => { const K = Type.Union([Type.Literal('A'), Type.Literal('B')]) const R = TypeGuard.IsObject(Type.Record(K, Type.Number())) Assert.IsTrue(R) }) it('Normalize: Should normalize boolean key into true and false', () => { const K = Type.Boolean() const R = Type.Record(K, Type.Number()) Assert.IsTrue(TypeGuard.IsObject(R)) Assert.IsTrue(TypeGuard.IsNumber(R.properties.true)) Assert.IsTrue(TypeGuard.IsNumber(R.properties.false)) }) // ------------------------------------------------------------------ // Utility Types // ------------------------------------------------------------------ it('Should return RecordPattern', () => { const R = Type.Record(Type.Number(), Type.Number()) const K = RecordPattern(R) Assert.IsTrue(typeof K === 'string') }) it('Should return RecordKey (Number)', () => { const R = Type.Record(Type.Number(), Type.Number()) const K = RecordKey(R) Assert.IsTrue(TypeGuard.IsNumber(K)) }) it('Should return RecordKey (String)', () => { const R = Type.Record(Type.String(), Type.Number()) const K = RecordKey(R) Assert.IsTrue(TypeGuard.IsString(K)) }) it('Should return RecordKey (RegExp)', () => { const R = Type.Record(Type.RegExp(/(a|b)/), Type.Number()) const K = RecordKey(R) Assert.IsTrue(TypeGuard.IsString(K)) // facade }) it('Should return RecordValue', () => { const R = Type.Record(Type.String(), Type.Literal(12345)) const V = RecordValue(R) Assert.IsTrue(TypeGuard.IsLiteral(V)) Assert.IsEqual(V.const, 12345) }) // ------------------------------------------------------------------ // Evaluated: Dollar Sign Escape // https://github.com/sinclairzx81/typebox/issues/794 // ------------------------------------------------------------------ // prettier-ignore { const K = Type.TemplateLiteral('$prop${A|B|C}') // issue const T = Type.Record(K, Type.String()) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsString(T.properties.$propA)) Assert.IsTrue(TypeGuard.IsString(T.properties.$propB)) Assert.IsTrue(TypeGuard.IsString(T.properties.$propC)) Assert.IsEqual(T.required, ['$propA', '$propB', '$propC']) } }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/recursive.ts000066400000000000000000000011531505437577000263450ustar00rootroot00000000000000import { TypeGuard, PatternNumberExact, PatternStringExact, PatternString, PatternNumber } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TRecursive', () => { it('Should guard 1', () => { const T = Type.Recursive((This) => Type.Object({ nodes: This })) Assert.IsTrue(TypeGuard.IsRecursive(T)) Assert.IsTrue(TypeGuard.IsObject(T)) }) it('Should guard 2', () => { const T = Type.Recursive((This) => Type.Tuple([This])) Assert.IsTrue(TypeGuard.IsRecursive(T)) Assert.IsTrue(TypeGuard.IsTuple(T)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/ref.ts000066400000000000000000000026531505437577000251200ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type, CloneType } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TRef', () => { // ---------------------------------------------------------------- // Deprecated // ---------------------------------------------------------------- it('Should guard for Ref(Schema) 1', () => { const T = Type.Number({ $id: 'T' }) const R = Type.Ref(T) Assert.IsTrue(TypeGuard.IsRef(R)) Assert.IsTrue(typeof R['$ref'] === 'string') }) it('Should guard for Ref(Schema) 2', () => { const T = Type.Number() Assert.Throws(() => Type.Ref(T)) }) it('Should guard for Ref(Schema) 3', () => { // @ts-ignore const T = Type.Number({ $id: null }) Assert.Throws(() => Type.Ref(T)) }) // ---------------------------------------------------------------- // Standard // ---------------------------------------------------------------- it('Should guard for TRef', () => { const T = Type.Number({ $id: 'T' }) const R = TypeGuard.IsRef(Type.Ref('T')) Assert.IsTrue(R) }) it('Should not guard for TRef', () => { const R = TypeGuard.IsRef(null) Assert.IsFalse(R) }) it('Should not guard for TRef with invalid $ref', () => { const T = Type.Number({ $id: 'T' }) const S = CloneType(Type.Ref('T')) // @ts-ignore S.$ref = 1 const R = TypeGuard.IsRef(S) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/regexp.ts000066400000000000000000000020741505437577000256330ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TRegExp', () => { it('Should guard for TRegExp 1', () => { const T = Type.RegExp(/foo/, { $id: 'T' }) Assert.IsTrue(TypeGuard.IsSchema(T)) }) it('Should guard for TRegExp 1', () => { const T = Type.RegExp(/foo/, { $id: 'T' }) Assert.IsTrue(TypeGuard.IsRegExp(T)) }) it('Should guard for TRegExp 2', () => { const T = Type.RegExp('foo', { $id: 'T' }) Assert.IsTrue(TypeGuard.IsRegExp(T)) }) it('Should not guard for TRegExp 1', () => { // @ts-ignore const T = Type.RegExp('foo', { $id: 1 }) Assert.IsFalse(TypeGuard.IsRegExp(T)) }) it('Should guard for RegExp constraint 1', () => { // @ts-ignore const T = Type.RegExp('foo', { maxLength: '1' }) Assert.IsFalse(TypeGuard.IsRegExp(T)) }) it('Should guard for RegExp constraint 2', () => { // @ts-ignore const T = Type.RegExp('foo', { minLength: '1' }) Assert.IsFalse(TypeGuard.IsRegExp(T)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/required.ts000066400000000000000000000101221505437577000261520ustar00rootroot00000000000000import { TypeGuard, TypeRegistry, Type, Kind, TransformKind } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TRequired', () => { it('Should produce a valid TSchema', () => { const T = Type.Required(Type.Object({ x: Type.Number() })) Assert.IsTrue(TypeGuard.IsSchema(T)) }) it('Should support TUnsafe required properties with no Kind', () => { const T = Type.Required(Type.Object({ x: Type.Optional(Type.Unsafe({ x: 1 })) })) Assert.IsEqual(T.required, ['x']) }) it('Should support TUnsafe required properties with unknown Kind', () => { const T = Type.Required(Type.Object({ x: Type.Optional(Type.Unsafe({ [Kind]: 'UnknownRequiredType', x: 1 })) })) Assert.IsEqual(T.required, ['x']) }) it('Should support TUnsafe required properties with known Kind', () => { TypeRegistry.Set('KnownRequiredType', () => true) const T = Type.Required(Type.Object({ x: Type.Optional(Type.Unsafe({ [Kind]: 'KnownRequiredType', x: 1 })) })) Assert.IsEqual(T.required, ['x']) }) it('Should support applying required to intersect', () => { const A = Type.Object({ x: Type.Optional(Type.Number()) }) const B = Type.Object({ y: Type.Optional(Type.Number()) }) const I = Type.Intersect([A, B]) const T = Type.Required(I) Assert.IsEqual(T.allOf.length, 2) Assert.IsEqual(T.allOf[0].required, ['x']) Assert.IsEqual(T.allOf[1].required, ['y']) }) it('Should support applying required to union', () => { const A = Type.Object({ x: Type.Optional(Type.Number()) }) const B = Type.Object({ y: Type.Optional(Type.Number()) }) const I = Type.Union([A, B]) const T = Type.Required(I) Assert.IsEqual(T.anyOf.length, 2) Assert.IsEqual(T.anyOf[0].required, ['x']) Assert.IsEqual(T.anyOf[1].required, ['y']) }) // ---------------------------------------------------------------- // Discard // ---------------------------------------------------------------- it('Should override $id', () => { const A = Type.Object({ x: Type.Number() }, { $id: 'A' }) const T = Type.Required(A, { $id: 'T' }) Assert.IsEqual(T.$id!, 'T') }) it('Should discard $id', () => { const A = Type.Object({ x: Type.Number() }, { $id: 'A' }) const T = Type.Required(A) Assert.IsFalse('$id' in T) }) it('Should discard transform', () => { const T = Type.Object({ x: Type.Number(), y: Type.String(), }) const S = Type.Transform(T) .Decode((value) => value) .Encode((value) => value) const R = Type.Required(S) Assert.IsFalse(TransformKind in R) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/980 // ---------------------------------------------------------------- it('Should override properties in source type', () => { const A = Type.Object({ x: Type.Number() }, { title: 'A' }) const B = Type.Required(A, { title: 'B' }) Assert.IsEqual(A.title, 'A') Assert.IsEqual(B.title, 'B') }) // ------------------------------------------------------------------ // Intrinsic Passthough // https://github.com/sinclairzx81/typebox/issues/1169 // ------------------------------------------------------------------ it('Should pass through on intrinsic types on union 1', () => { const T = Type.Required( Type.Union([ Type.Number(), Type.Object({ x: Type.Optional(Type.Number()), }), ]), ) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsTrue(TypeGuard.IsNumber(T.anyOf[0])) Assert.IsTrue(TypeGuard.IsObject(T.anyOf[1])) Assert.IsFalse(TypeGuard.IsOptional(T.anyOf[1].properties.x)) }) it('Should pass through on intrinsic types on union 2', () => { const T = Type.Required( Type.Union([ Type.Literal(1), Type.Object({ x: Type.Optional(Type.Number()), }), ]), ) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsTrue(TypeGuard.IsLiteral(T.anyOf[0])) Assert.IsTrue(TypeGuard.IsObject(T.anyOf[1])) Assert.IsFalse(TypeGuard.IsOptional(T.anyOf[1].properties.x)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/rest.ts000066400000000000000000000040441505437577000253150ustar00rootroot00000000000000import { Type, TypeGuard } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TRest', () => { it('Should guard 1', () => { // union never const A = Type.String() const B = Type.Union(Type.Rest(A)) Assert.IsTrue(TypeGuard.IsNever(B)) }) it('Should guard 2', () => { // intersect never const A = Type.String() const B = Type.Intersect(Type.Rest(A)) Assert.IsTrue(TypeGuard.IsNever(B)) }) it('Should guard 3', () => { // tuple const A = Type.Tuple([Type.Number(), Type.String()]) const B = Type.Union(Type.Rest(A)) Assert.IsTrue(TypeGuard.IsUnion(B)) Assert.IsEqual(B.anyOf.length, 2) Assert.IsTrue(TypeGuard.IsNumber(B.anyOf[0])) Assert.IsTrue(TypeGuard.IsString(B.anyOf[1])) }) it('Should guard 4', () => { // tuple spread const A = Type.Tuple([Type.Literal(1), Type.Literal(2)]) const B = Type.Tuple([Type.Literal(3), Type.Literal(4)]) const C = Type.Tuple([...Type.Rest(A), ...Type.Rest(B)]) Assert.IsTrue(TypeGuard.IsTuple(C)) Assert.IsEqual(C.items!.length, 4) Assert.IsEqual(C.items![0].const, 1) Assert.IsEqual(C.items![1].const, 2) Assert.IsEqual(C.items![2].const, 3) Assert.IsEqual(C.items![3].const, 4) }) it('Should guard 5', () => { // union to intersect const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.String() }) const C = Type.Union([A, B]) const D = Type.Intersect(Type.Rest(C)) Assert.IsTrue(TypeGuard.IsIntersect(D)) Assert.IsEqual(D.allOf.length, 2) Assert.IsTrue(TypeGuard.IsObject(D.allOf[0])) Assert.IsTrue(TypeGuard.IsObject(D.allOf[1])) }) it('Should guard 6', () => { // intersect to composite const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.String() }) const C = Type.Intersect([A, B]) const D = Type.Composite(Type.Rest(C)) Assert.IsTrue(TypeGuard.IsObject(D)) Assert.IsTrue(TypeGuard.IsNumber(D.properties.x)) Assert.IsTrue(TypeGuard.IsString(D.properties.y)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/string.ts000066400000000000000000000021131505437577000256410ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TString', () => { it('Should guard for TString', () => { const R = TypeGuard.IsString(Type.String()) Assert.IsTrue(R) }) it('Should not guard for TString', () => { const R = TypeGuard.IsString(null) Assert.IsFalse(R) }) it('Should not guard for TString with invalid $id', () => { // @ts-ignore const R = TypeGuard.IsString(Type.String({ $id: 1 })) Assert.IsFalse(R) }) it('Should not guard for TString with invalid minLength', () => { // @ts-ignore const R = TypeGuard.IsString(Type.String({ minLength: '1' })) Assert.IsFalse(R) }) it('Should not guard for TString with invalid maxLength', () => { // @ts-ignore const R = TypeGuard.IsString(Type.String({ maxLength: '1' })) Assert.IsFalse(R) }) it('Should not guard for TString with invalid pattern', () => { // @ts-ignore const R = TypeGuard.IsString(Type.String({ pattern: 1 })) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/symbol.ts000066400000000000000000000010701505437577000256410ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TSymbol', () => { it('Should guard for TSymbol', () => { const R = TypeGuard.IsSymbol(Type.Symbol()) Assert.IsTrue(R) }) it('Should not guard for TSymbol', () => { const R = TypeGuard.IsSymbol(null) Assert.IsFalse(R) }) it('Should not guard for TSymbol with invalid $id', () => { // @ts-ignore const R = TypeGuard.IsSymbol(Type.Symbol({ $id: 1 })) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/template-literal.ts000066400000000000000000000076041505437577000276120ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type, CloneType, TemplateLiteralGenerate } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TTemplateLiteral', () => { it('Should guard for empty TemplateLiteral', () => { const R = TypeGuard.IsTemplateLiteral(Type.TemplateLiteral([])) Assert.IsTrue(R) }) it('Should guard for TSchema', () => { const R = TypeGuard.IsSchema(Type.TemplateLiteral([])) Assert.IsTrue(R) }) it('Should guard for TemplateLiteral (TTemplateLiteral)', () => { const T = Type.TemplateLiteral([Type.Literal('hello')]) const R = TypeGuard.IsTemplateLiteral(Type.TemplateLiteral([T, Type.Literal('world')])) Assert.IsTrue(R) }) it('Should guard for TemplateLiteral (TLiteral)', () => { const R = TypeGuard.IsTemplateLiteral(Type.TemplateLiteral([Type.Literal('hello')])) Assert.IsTrue(R) }) it('Should guard for TemplateLiteral (TString)', () => { const R = TypeGuard.IsTemplateLiteral(Type.TemplateLiteral([Type.String()])) Assert.IsTrue(R) }) it('Should guard for TemplateLiteral (TNumber)', () => { const R = TypeGuard.IsTemplateLiteral(Type.TemplateLiteral([Type.Number()])) Assert.IsTrue(R) }) it('Should guard for TemplateLiteral (TBoolean)', () => { const R = TypeGuard.IsTemplateLiteral(Type.TemplateLiteral([Type.Boolean()])) Assert.IsTrue(R) }) it('Should not guard for missing ^ expression prefix', () => { const T = CloneType(Type.TemplateLiteral([Type.Literal('hello')])) // @ts-ignore T.pattern = T.pattern.slice(1) Assert.IsFalse(TypeGuard.IsTemplateLiteral(T)) }) it('Should not guard for missing $ expression postfix', () => { const T = CloneType(Type.TemplateLiteral([Type.Literal('hello')])) // @ts-ignore T.pattern = T.pattern.slice(0, T.pattern.length - 1) Assert.IsFalse(TypeGuard.IsTemplateLiteral(T)) }) // ---------------------------------------------------------------- // issue: https://github.com/sinclairzx81/typebox/issues/913 // ---------------------------------------------------------------- it('Should generate embedded template literal 1', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('X'), Type.Literal('Y')])]) const L = Type.TemplateLiteral([Type.Literal('KEY'), A, B]) const T = TemplateLiteralGenerate(L) Assert.IsEqual(T, ['KEYAX', 'KEYAY', 'KEYBX', 'KEYBY']) }) it('Should generate embedded template literal 2', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('X'), Type.Literal('Y')])]) const L = Type.TemplateLiteral([A, Type.Literal('KEY'), B]) const T = TemplateLiteralGenerate(L) Assert.IsEqual(T, ['AKEYX', 'AKEYY', 'BKEYX', 'BKEYY']) }) it('Should generate embedded template literal 3', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('X'), Type.Literal('Y')])]) const L = Type.TemplateLiteral([A, B, Type.Literal('KEY')]) const T = TemplateLiteralGenerate(L) Assert.IsEqual(T, ['AXKEY', 'AYKEY', 'BXKEY', 'BYKEY']) }) it('Should map embedded template literal', () => { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('X'), Type.Literal('Y')])]) const L = Type.TemplateLiteral([Type.Literal('KEY'), A, B]) const T = Type.Mapped(L, (K) => Type.Null()) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsNull(T.properties.KEYAX)) Assert.IsTrue(TypeGuard.IsNull(T.properties.KEYAY)) Assert.IsTrue(TypeGuard.IsNull(T.properties.KEYBX)) Assert.IsTrue(TypeGuard.IsNull(T.properties.KEYBY)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/this.ts000066400000000000000000000011661505437577000253110ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TThis', () => { it('Should guard for TThis', () => { Type.Recursive((This) => { const R = TypeGuard.IsThis(This) Assert.IsTrue(R) return Type.Object({ nodes: Type.Array(This) }) }) }) it('Should guard for TThis with invalid $ref', () => { Type.Recursive((This) => { // @ts-ignore This.$ref = 1 const R = TypeGuard.IsThis(This) Assert.IsFalse(R) return Type.Object({ nodes: Type.Array(This) }) }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/tuple.ts000066400000000000000000000014171505437577000254720ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TTuple', () => { it('Should guard for TTuple', () => { const R = TypeGuard.IsTuple(Type.Tuple([Type.Number(), Type.Number()])) Assert.IsTrue(R) }) it('Should not guard for TTuple', () => { const R = TypeGuard.IsTuple(null) Assert.IsFalse(R) }) it('Should not guard for TTuple with invalid $id', () => { // @ts-ignore const R = TypeGuard.IsTuple(Type.Tuple([Type.Number(), Type.Number()], { $id: 1 })) Assert.IsFalse(R) }) it('Should not guard for TTuple with invalid Items', () => { const R = TypeGuard.IsTuple(Type.Tuple([Type.Number(), {} as any])) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/uint8array.ts000066400000000000000000000017521505437577000264510ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TUint8Array', () => { it('Should guard for TUint8Array', () => { const R = TypeGuard.IsUint8Array(Type.Uint8Array()) Assert.IsTrue(R) }) it('Should not guard for TUint8Array', () => { const R = TypeGuard.IsUint8Array(null) Assert.IsFalse(R) }) it('Should not guard for TUint8Array with invalid $id', () => { // @ts-ignore const R = TypeGuard.IsUint8Array(Type.Uint8Array({ $id: 1 })) Assert.IsFalse(R) }) it('Should not guard for TUint8Array with invalid minByteLength', () => { // @ts-ignore const R = TypeGuard.IsUint8Array(Type.Uint8Array({ minByteLength: '1' })) Assert.IsFalse(R) }) it('Should not guard for TUint8Array with invalid maxByteLength', () => { // @ts-ignore const R = TypeGuard.IsUint8Array(Type.Uint8Array({ maxByteLength: '1' })) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/uncapitalize.ts000066400000000000000000000025601505437577000270310ustar00rootroot00000000000000import { TypeGuard, Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/Uncapitalize', () => { it('Should guard for Uncapitalize 1', () => { const T = Type.Uncapitalize(Type.Literal('HELLO'), { $id: 'hello', foo: 1 }) Assert.IsTrue(TypeGuard.IsLiteral(T)) Assert.IsEqual(T.const, 'hELLO') Assert.IsEqual(T.$id, 'hello') Assert.IsEqual(T.foo, 1) }) it('Should guard for Uncapitalize 2', () => { const T = Type.Uncapitalize(Type.Literal('HELLO')) Assert.IsTrue(TypeGuard.IsLiteral(T)) Assert.IsEqual(T.const, 'hELLO') }) it('Should guard for Uncapitalize 3', () => { const T = Type.Uncapitalize(Type.Union([Type.Literal('HELLO'), Type.Literal('WORLD')])) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, 'hELLO') Assert.IsEqual(T.anyOf[1].const, 'wORLD') }) it('Should guard for Uncapitalize 4', () => { const T = Type.Uncapitalize(Type.TemplateLiteral('HELLO${0|1}')) Assert.IsTrue(TypeGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(hELLO0|hELLO1)$') }) it('Should guard for Uncapitalize 5', () => { const T = Type.Uncapitalize(Type.TemplateLiteral([Type.Literal('HELLO'), Type.Union([Type.Literal(0), Type.Literal(1)])])) Assert.IsTrue(TypeGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(hELLO0|hELLO1)$') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/undefined.ts000066400000000000000000000011231505437577000262740ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TUndefined', () => { it('Should guard for TUndefined', () => { const R = TypeGuard.IsUndefined(Type.Undefined()) Assert.IsTrue(R) }) it('Should not guard for TUndefined', () => { const R = TypeGuard.IsUndefined(null) Assert.IsFalse(R) }) it('Should not guard for TUndefined with invalid $id', () => { // @ts-ignore const R = TypeGuard.IsUndefined(Type.Undefined({ $id: 1 })) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/union.ts000066400000000000000000000041401505437577000254650ustar00rootroot00000000000000import { TSchema, TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TUnion', () => { it('Should guard for TUnion', () => { const R = TypeGuard.IsUnion( Type.Union([ Type.Object({ x: Type.Number(), }), Type.Object({ y: Type.Number(), }), ]), ) Assert.IsTrue(R) }) it('Should not guard for TUnion', () => { const R = TypeGuard.IsUnion(null) Assert.IsFalse(R) }) it('Should guard for TUnion with invalid $id', () => { const R = TypeGuard.IsUnion( // @ts-ignore Type.Union( [ Type.Object({ x: Type.Number(), }), Type.Object({ y: Type.Number(), }), ], { // @ts-ignore $id: 1, }, ), ) Assert.IsFalse(R) }) it('Should not guard for TUnion with invalid variant', () => { const R = TypeGuard.IsUnion( Type.Union([ Type.Object({ x: Type.Number(), }), {} as TSchema, ]), ) Assert.IsFalse(R) }) it('Should not guard for TUnion with invalid object variant', () => { const R = TypeGuard.IsUnion( Type.Union([ Type.Object({ x: Type.Number(), }), Type.Object({ y: {} as any, }), ]), ) Assert.IsFalse(R) }) it('Transform: Should transform to never for zero length union', () => { const T = Type.Union([]) const R = TypeGuard.IsNever(T) Assert.IsTrue(R) }) it('Transform: Should unwrap union type for array of length === 1', () => { const T = Type.Union([Type.String()]) const R = TypeGuard.IsString(T) Assert.IsTrue(R) }) it('Transform: Should retain union if array length > 1', () => { const T = Type.Union([Type.String(), Type.Number()]) const R1 = TypeGuard.IsUnion(T) const R2 = TypeGuard.IsString(T.anyOf[0]) const R3 = TypeGuard.IsNumber(T.anyOf[1]) Assert.IsTrue(R1) Assert.IsTrue(R2) Assert.IsTrue(R3) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/unknown.ts000066400000000000000000000011011505437577000260260ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TUnknown', () => { it('Should guard for TUnknown', () => { const R = TypeGuard.IsUnknown(Type.Unknown()) Assert.IsTrue(R) }) it('Should not guard for TUnknown', () => { const R = TypeGuard.IsUnknown(null) Assert.IsFalse(R) }) it('Should not guard for TUnknown with invalid $id', () => { // @ts-ignore const R = TypeGuard.IsUnknown(Type.Unknown({ $id: 1 })) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/unsafe.ts000066400000000000000000000020611505437577000256160ustar00rootroot00000000000000import { Kind, TypeGuard, TypeRegistry } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TUnsafe', () => { it('Should guard raw TUnsafe', () => { const T = Type.Unsafe({ x: 1 }) const R = TypeGuard.IsUnsafe(T) Assert.IsTrue(R) }) it('Should guard raw TUnsafe as TSchema', () => { const T = Type.Unsafe({ x: 1 }) const R = TypeGuard.IsSchema(T) Assert.IsTrue(R) }) it('Should guard override TUnsafe as TSchema when registered', () => { TypeRegistry.Set('UnsafeType', () => true) const T = Type.Unsafe({ [Kind]: 'UnsafeType' }) const R = TypeGuard.IsSchema(T) Assert.IsTrue(R) TypeRegistry.Delete('UnsafeType') }) it('Should not guard TUnsafe with unregistered kind', () => { const T = Type.Unsafe({ [Kind]: 'UnsafeType' }) const R = TypeGuard.IsUnsafe(T) Assert.IsFalse(R) }) it('Should not guard for TString', () => { const T = Type.String() const R = TypeGuard.IsUnsafe(T) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/uppercase.ts000066400000000000000000000025171505437577000263320ustar00rootroot00000000000000import { TypeGuard, Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/Uppercase', () => { it('Should guard for Uppercase 1', () => { const T = Type.Uppercase(Type.Literal('hello'), { $id: 'hello', foo: 1 }) Assert.IsTrue(TypeGuard.IsLiteral(T)) Assert.IsEqual(T.const, 'HELLO') Assert.IsEqual(T.$id, 'hello') Assert.IsEqual(T.foo, 1) }) it('Should guard for Uppercase 2', () => { const T = Type.Uppercase(Type.Literal('hello')) Assert.IsTrue(TypeGuard.IsLiteral(T)) Assert.IsEqual(T.const, 'HELLO') }) it('Should guard for Uppercase 3', () => { const T = Type.Uppercase(Type.Union([Type.Literal('hello'), Type.Literal('world')])) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, 'HELLO') Assert.IsEqual(T.anyOf[1].const, 'WORLD') }) it('Should guard for Uppercase 4', () => { const T = Type.Uppercase(Type.TemplateLiteral('hello${0|1}')) Assert.IsTrue(TypeGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(HELLO0|HELLO1)$') }) it('Should guard for Uppercase 5', () => { const T = Type.Uppercase(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(0), Type.Literal(1)])])) Assert.IsTrue(TypeGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(HELLO0|HELLO1)$') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/type/void.ts000066400000000000000000000010461505437577000253000ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../../assert/index' describe('guard/type/TVoid', () => { it('Should guard for TVoid', () => { const R = TypeGuard.IsVoid(Type.Void()) Assert.IsTrue(R) }) it('Should not guard for TVoid', () => { const R = TypeGuard.IsVoid(null) Assert.IsFalse(R) }) it('Should not guard for TVoid with invalid $id', () => { // @ts-ignore const R = TypeGuard.IsVoid(Type.Void({ $id: 1 })) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/value/000077500000000000000000000000001505437577000241215ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/value/guard.ts000066400000000000000000000132761505437577000256040ustar00rootroot00000000000000import { Assert } from '../../../assert/index' import { ValueGuard } from '@sinclair/typebox' describe('type/ValueGuard', () => { // ----------------------------------------------------- // IsSymbol // ----------------------------------------------------- it('Should guard symbol 1', () => { const R = ValueGuard.IsSymbol(Symbol()) Assert.IsTrue(R) }) it('Should guard symbol 2', () => { const R = ValueGuard.IsSymbol({}) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsNull // ----------------------------------------------------- it('Should guard null 1', () => { const R = ValueGuard.IsNull(null) Assert.IsTrue(R) }) it('Should guard null 2', () => { const R = ValueGuard.IsNull({}) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsUndefined // ----------------------------------------------------- it('Should guard undefined 1', () => { const R = ValueGuard.IsUndefined(undefined) Assert.IsTrue(R) }) it('Should guard undefined 2', () => { const R = ValueGuard.IsUndefined({}) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsBigInt // ----------------------------------------------------- it('Should guard bigint 1', () => { const R = ValueGuard.IsBigInt(1n) Assert.IsTrue(R) }) it('Should guard bigint 2', () => { const R = ValueGuard.IsBigInt(1) Assert.IsFalse(R) }) it('Should guard bigint 3', () => { const R = ValueGuard.IsBigInt('123') Assert.IsFalse(R) }) // ----------------------------------------------------- // IsNumber // ----------------------------------------------------- it('Should guard number 1', () => { const R = ValueGuard.IsNumber(1) Assert.IsTrue(R) }) it('Should guard number 2', () => { const R = ValueGuard.IsNumber(3.14) Assert.IsTrue(R) }) it('Should guard number 3', () => { const R = ValueGuard.IsNumber('') Assert.IsFalse(R) }) it('Should guard number 4', () => { const R = ValueGuard.IsNumber(NaN) Assert.IsTrue(R) }) // ----------------------------------------------------- // IsString // ----------------------------------------------------- it('Should guard string 1', () => { const R = ValueGuard.IsString('') Assert.IsTrue(R) }) it('Should guard string 2', () => { const R = ValueGuard.IsString(true) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsBoolean // ----------------------------------------------------- it('Should guard boolean 1', () => { const R = ValueGuard.IsBoolean(true) Assert.IsTrue(R) }) it('Should guard boolean 2', () => { const R = ValueGuard.IsBoolean(1) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsObject // ----------------------------------------------------- it('Should guard object 1', () => { const R = ValueGuard.IsObject({}) Assert.IsTrue(R) }) it('Should guard object 2', () => { const R = ValueGuard.IsObject(1) Assert.IsFalse(R) }) it('Should guard object 3', () => { const R = ValueGuard.IsObject([]) Assert.IsTrue(R) }) // ----------------------------------------------------- // IsArray // ----------------------------------------------------- it('Should guard array 1', () => { const R = ValueGuard.IsArray([]) Assert.IsTrue(R) }) it('Should guard array 2', () => { const R = ValueGuard.IsArray({}) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsFunction // ----------------------------------------------------- it('Should guard function 1', () => { const R = ValueGuard.IsFunction(function () {}) Assert.IsTrue(R) }) it('Should guard function 2', () => { const R = ValueGuard.IsFunction({}) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsAsyncIterator // ----------------------------------------------------- it('Should guard async iterator 1', () => { const R = ValueGuard.IsAsyncIterator((async function* (): any {})()) Assert.IsTrue(R) }) it('Should guard async iterator 2', () => { const R = ValueGuard.IsAsyncIterator((function* (): any {})()) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsAsyncIterator // ----------------------------------------------------- it('Should guard iterator 1', () => { const R = ValueGuard.IsIterator((function* (): any {})()) Assert.IsTrue(R) }) it('Should guard iterator 2', () => { const R = ValueGuard.IsIterator((async function* (): any {})()) Assert.IsFalse(R) }) it('Should guard iterator 3', () => { const R = ValueGuard.IsIterator([]) Assert.IsFalse(R) }) it('Should guard iterator 4', () => { const R = ValueGuard.IsIterator(new Uint8Array()) Assert.IsFalse(R) }) // ----------------------------------------------------- // Date // ----------------------------------------------------- it('Should guard date 1', () => { const R = ValueGuard.IsDate(new Date()) Assert.IsTrue(R) }) it('Should guard date 2', () => { const R = ValueGuard.IsDate({}) Assert.IsFalse(R) }) // ----------------------------------------------------- // Date // ----------------------------------------------------- it('Should guard uint8array 1', () => { const R = ValueGuard.IsUint8Array(new Uint8Array()) Assert.IsTrue(R) }) it('Should guard uint8array 2', () => { const R = ValueGuard.IsUint8Array({}) Assert.IsFalse(R) }) it('Should guard uint8array 2', () => { const R = ValueGuard.IsUint8Array([]) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/guard/value/index.ts000066400000000000000000000000211505437577000255710ustar00rootroot00000000000000import './guard' sinclairzx81-typebox-e0ec98c/test/runtime/type/index.ts000066400000000000000000000003501505437577000233600ustar00rootroot00000000000000import './clone/index' import './extends/index' import './guard/index' import './intrinsic/index' import './normalize/index' import './options/index' import './registry/index' import './sets/index' import './template-literal/index' sinclairzx81-typebox-e0ec98c/test/runtime/type/intrinsic/000077500000000000000000000000001505437577000237055ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/type/intrinsic/index.ts000066400000000000000000000000251505437577000253610ustar00rootroot00000000000000import './intrinsic' sinclairzx81-typebox-e0ec98c/test/runtime/type/intrinsic/intrinsic.ts000066400000000000000000000164571505437577000262740ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Intrinsic } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/intrinsic/Intrinsic', () => { // ---------------------------------------------------- // Passthrough // ---------------------------------------------------- it('Should passthrough 1', () => { const T = Intrinsic(Type.String(), 'Capitalize') Assert.IsTrue(TypeGuard.IsString(T)) }) it('Should passthrough 2', () => { const T = Intrinsic(Type.Number(), 'Capitalize') Assert.IsTrue(TypeGuard.IsNumber(T)) }) it('Should passthrough 3', () => { const T = Intrinsic( Type.Object({ x: Type.Number(), }), 'Capitalize', ) Assert.IsTrue(TypeGuard.IsObject(T)) }) // ---------------------------------------------------- // Partial Passthrough // ---------------------------------------------------- it('Should partial passthrough 3', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Literal('hello') const U = Type.Union([A, B]) const T = Intrinsic(U, 'Capitalize') Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsTrue(TypeGuard.IsObject(T.anyOf[0])) Assert.IsTrue(TypeGuard.IsLiteral(T.anyOf[1])) Assert.IsEqual(T.anyOf[1].const, 'Hello') }) // ---------------------------------------------------- // Mode: Literal // ---------------------------------------------------- it('Should map literal: Capitalize', () => { const T = Intrinsic(Type.Literal('hello'), 'Capitalize') Assert.IsTrue(TypeGuard.IsLiteral(T)) Assert.IsEqual(T.const, 'Hello') }) it('Should map literal: Uncapitalize', () => { const T = Intrinsic(Type.Literal('HELLO'), 'Uncapitalize') Assert.IsTrue(TypeGuard.IsLiteral(T)) Assert.IsEqual(T.const, 'hELLO') }) it('Should map literal: Uppercase', () => { const T = Intrinsic(Type.Literal('hello'), 'Uppercase') Assert.IsTrue(TypeGuard.IsLiteral(T)) Assert.IsEqual(T.const, 'HELLO') }) it('Should map literal: Lowercase', () => { const T = Intrinsic(Type.Literal('HELLO'), 'Lowercase') Assert.IsTrue(TypeGuard.IsLiteral(T)) Assert.IsEqual(T.const, 'hello') }) // ---------------------------------------------------- // Mode: Literal Union // ---------------------------------------------------- it('Should map literal union: Capitalize', () => { const T = Intrinsic(Type.Union([Type.Literal('hello'), Type.Literal('world')]), 'Capitalize') Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, 'Hello') Assert.IsEqual(T.anyOf[1].const, 'World') }) it('Should map literal union: Uncapitalize', () => { const T = Intrinsic(Type.Union([Type.Literal('Hello'), Type.Literal('World')]), 'Uncapitalize') Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, 'hello') Assert.IsEqual(T.anyOf[1].const, 'world') }) it('Should map literal union: Uppercase', () => { const T = Intrinsic(Type.Union([Type.Literal('hello'), Type.Literal('world')]), 'Uppercase') Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, 'HELLO') Assert.IsEqual(T.anyOf[1].const, 'WORLD') }) it('Should map literal union: Lowercase', () => { const T = Intrinsic(Type.Union([Type.Literal('HELLO'), Type.Literal('WORLD')]), 'Lowercase') Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsEqual(T.anyOf[0].const, 'hello') Assert.IsEqual(T.anyOf[1].const, 'world') }) // ---------------------------------------------------- // Mode: TemplateLiteral // ---------------------------------------------------- it('Should map template literal: Capitalize', () => { const T = Intrinsic(Type.TemplateLiteral('hello${1|2}world'), 'Capitalize') Assert.IsTrue(TypeGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(Hello1world|Hello2world)$') }) it('Should map template literal: Uncapitalize', () => { const T = Intrinsic(Type.TemplateLiteral('HELLO${1|2}WORLD'), 'Uncapitalize') Assert.IsTrue(TypeGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(hELLO1WORLD|hELLO2WORLD)$') }) it('Should map template literal: Uppercase', () => { const T = Intrinsic(Type.TemplateLiteral('hello${1|2}world'), 'Uppercase') Assert.IsTrue(TypeGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(HELLO1WORLD|HELLO2WORLD)$') }) it('Should map template literal: Lowercase', () => { const T = Intrinsic(Type.TemplateLiteral('HELLO${1|2}WORLD'), 'Lowercase') Assert.IsTrue(TypeGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(hello1world|hello2world)$') }) // ---------------------------------------------------- // Mode: TemplateLiteral Numeric // ---------------------------------------------------- it('Should map template literal numeric: Capitalize', () => { const T = Intrinsic(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(1), Type.Literal(2)])]), 'Capitalize') Assert.IsTrue(TypeGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(Hello1|Hello2)$') }) it('Should map template literal numeric: Uncapitalize', () => { const T = Intrinsic(Type.TemplateLiteral([Type.Literal('HELLO'), Type.Union([Type.Literal(1), Type.Literal(2)])]), 'Uncapitalize') Assert.IsTrue(TypeGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(hELLO1|hELLO2)$') }) it('Should map template literal numeric: Uppercase', () => { const T = Intrinsic(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(1), Type.Literal(2)])]), 'Uppercase') Assert.IsTrue(TypeGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(HELLO1|HELLO2)$') }) it('Should map template literal numeric: Lowercase', () => { const T = Intrinsic(Type.TemplateLiteral([Type.Literal('HELLO'), Type.Union([Type.Literal(1), Type.Literal(2)])]), 'Lowercase') Assert.IsTrue(TypeGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(hello1|hello2)$') }) // ---------------------------------------------------- // Mode: TemplateLiteral Patterns // ---------------------------------------------------- it('Should map template literal patterns 1', () => { const T = Intrinsic(Type.TemplateLiteral('HELLO${string}WORLD'), 'Lowercase') Assert.IsTrue(TypeGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^hello(.*)world$') }) it('Should map template literal patterns 2', () => { const T = Intrinsic(Type.TemplateLiteral('HELLO${number}WORLD'), 'Lowercase') Assert.IsTrue(TypeGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^hello(0|[1-9][0-9]*)world$') }) it('Should map template literal patterns 3', () => { const T = Intrinsic(Type.TemplateLiteral('${number}${string}'), 'Lowercase') Assert.IsTrue(TypeGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(0|[1-9][0-9]*)(.*)$') }) it('Should map template literal patterns 3', () => { const T = Intrinsic(Type.TemplateLiteral('${number}HELLO${string}'), 'Lowercase') Assert.IsTrue(TypeGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(0|[1-9][0-9]*)hello(.*)$') }) it('Should map template literal patterns 3', () => { const T = Intrinsic(Type.TemplateLiteral('${string|number}HELLO'), 'Lowercase') Assert.IsTrue(TypeGuard.IsTemplateLiteral(T)) Assert.IsEqual(T.pattern, '^(stringhello|numberhello)$') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/normalize/000077500000000000000000000000001505437577000237035ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/type/normalize/exclude.ts000066400000000000000000000013011505437577000256770ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/normalize/Exclude', () => { it('Normalize 1', () => { const T = Type.Exclude(Type.Union([Type.String(), Type.Number(), Type.Boolean()]), Type.String()) const R = TypeGuard.IsUnion(T) Assert.IsTrue(R) }) it('Normalize 2', () => { const T = Type.Exclude(Type.Union([Type.String(), Type.Number()]), Type.String()) const R = TypeGuard.IsNumber(T) Assert.IsTrue(R) }) it('Normalize 3', () => { const T = Type.Exclude(Type.Union([Type.String()]), Type.String()) const R = TypeGuard.IsNever(T) Assert.IsTrue(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/normalize/extract.ts000066400000000000000000000020621505437577000257250ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/normalize/Extract', () => { it('Normalize 1', () => { const T = Type.Extract(Type.Union([Type.String(), Type.Number(), Type.Boolean()]), Type.Union([Type.String(), Type.Number()])) const R = TypeGuard.IsUnion(T) Assert.IsTrue(R) }) it('Normalize 2', () => { const T = Type.Extract(Type.Union([Type.String(), Type.Number(), Type.Boolean()]), Type.String()) const R = TypeGuard.IsString(T) Assert.IsTrue(R) }) it('Normalize 3', () => { const T = Type.Extract(Type.Union([Type.String(), Type.Number()]), Type.String()) const R = TypeGuard.IsString(T) Assert.IsTrue(R) }) it('Normalize 4', () => { const T = Type.Extract(Type.Union([Type.String()]), Type.String()) const R = TypeGuard.IsString(T) Assert.IsTrue(R) }) it('Normalize 5', () => { const T = Type.Extract(Type.Union([]), Type.String()) const R = TypeGuard.IsNever(T) Assert.IsTrue(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/normalize/index.ts000066400000000000000000000001611505437577000253600ustar00rootroot00000000000000import './exclude' import './extract' import './intersect' import './indexed' import './record' import './union' sinclairzx81-typebox-e0ec98c/test/runtime/type/normalize/indexed.ts000066400000000000000000000134471505437577000257040ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/normalize/Index', () => { // --------------------------------------------------------- // Array // --------------------------------------------------------- it('Normalize Array 1', () => { const T = Type.Array(Type.String()) const I = Type.Index(T, Type.Number()) Assert.IsTrue(TypeGuard.IsString(I)) }) // --------------------------------------------------------- // Tuple // --------------------------------------------------------- it('Normalize Tuple 1', () => { const T = Type.Tuple([Type.String(), Type.Number()]) const I = Type.Index(T, Type.Number()) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsString(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsNumber(I.anyOf[1])) }) it('Normalize Tuple 2', () => { const T = Type.Tuple([Type.String(), Type.Number()]) const I = Type.Index(T, [0, 1]) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsString(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsNumber(I.anyOf[1])) }) it('Normalize Tuple 3', () => { const T = Type.Tuple([Type.String(), Type.Number()]) const I = Type.Index(T, ['0', '1']) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsString(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsNumber(I.anyOf[1])) }) it('Normalize Tuple 4', () => { const T = Type.Tuple([Type.String(), Type.Number()]) const I = Type.Index(T, ['0']) Assert.IsTrue(TypeGuard.IsString(I)) }) it('Normalize Tuple 5', () => { const T = Type.Tuple([Type.String(), Type.Number()]) const I = Type.Index(T, ['1']) Assert.IsTrue(TypeGuard.IsNumber(I)) }) // --------------------------------------------------------- // Intersect // --------------------------------------------------------- it('Normalize Intersect 1', () => { const T = Type.Intersect([Type.Object({ x: Type.Optional(Type.String()) }), Type.Object({ x: Type.Optional(Type.String()) })]) const I = Type.Index(T, ['x']) Assert.IsTrue(TypeGuard.IsOptional(I)) Assert.IsTrue(TypeGuard.IsIntersect(I)) Assert.IsTrue(TypeGuard.IsString(I.allOf[0])) Assert.IsTrue(TypeGuard.IsString(I.allOf[1])) }) it('Normalize Intersect 2', () => { const T = Type.Intersect([Type.Object({ x: Type.Optional(Type.String()) }), Type.Object({ x: Type.String() })]) const I = Type.Index(T, ['x']) Assert.IsFalse(TypeGuard.IsOptional(I)) Assert.IsTrue(TypeGuard.IsIntersect(I)) Assert.IsTrue(TypeGuard.IsString(I.allOf[0])) Assert.IsTrue(TypeGuard.IsString(I.allOf[1])) }) it('Normalize Intersect 3', () => { const T = Type.Intersect([Type.Object({ x: Type.String() }), Type.Object({ x: Type.String() })]) const I = Type.Index(T, ['x']) Assert.IsFalse(TypeGuard.IsOptional(I)) Assert.IsTrue(TypeGuard.IsIntersect(I)) Assert.IsTrue(TypeGuard.IsString(I.allOf[0])) Assert.IsTrue(TypeGuard.IsString(I.allOf[1])) }) it('Normalize Intersect 4', () => { const T = Type.Intersect([Type.Object({ x: Type.String() })]) const I = Type.Index(T, ['x']) Assert.IsTrue(TypeGuard.IsString(I)) }) it('Normalize Intersect 5', () => { const T = Type.Intersect([Type.Object({ x: Type.String() }), Type.Object({ y: Type.String() })]) const I = Type.Index(T, ['x', 'y']) Assert.IsFalse(TypeGuard.IsOptional(I)) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsString(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsString(I.anyOf[1])) }) it('Normalize Intersect 6', () => { const T = Type.Recursive(() => Type.Intersect([Type.Object({ x: Type.String() }), Type.Object({ y: Type.String() })])) const I = Type.Index(T, ['x', 'y']) Assert.IsFalse(TypeGuard.IsOptional(I)) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsString(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsString(I.anyOf[1])) }) // --------------------------------------------------------- // Union // --------------------------------------------------------- it('Normalize Union 1', () => { const T = Type.Union([Type.Object({ x: Type.Optional(Type.String()) }), Type.Object({ x: Type.Optional(Type.String()) })]) const I = Type.Index(T, ['x']) Assert.IsTrue(TypeGuard.IsOptional(I)) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsString(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsString(I.anyOf[1])) }) it('Normalize Union 2', () => { const T = Type.Union([Type.Object({ x: Type.Optional(Type.String()) }), Type.Object({ x: Type.String() })]) const I = Type.Index(T, ['x']) Assert.IsTrue(TypeGuard.IsOptional(I)) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsString(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsString(I.anyOf[1])) }) it('Normalize Union 3', () => { const T = Type.Union([Type.Object({ x: Type.String() }), Type.Object({ x: Type.String() })]) const I = Type.Index(T, ['x']) Assert.IsFalse(TypeGuard.IsOptional(I)) Assert.IsTrue(TypeGuard.IsUnion(I)) Assert.IsTrue(TypeGuard.IsString(I.anyOf[0])) Assert.IsTrue(TypeGuard.IsString(I.anyOf[1])) }) it('Normalize Union 4', () => { const T = Type.Union([Type.Object({ x: Type.String() })]) const I = Type.Index(T, ['x']) Assert.IsTrue(TypeGuard.IsString(I)) }) it('Normalize Union 5', () => { const T = Type.Union([Type.Object({ x: Type.String() }), Type.Object({ y: Type.String() })]) // @ts-ignore const I = Type.Index(T, ['x', 'y']) Assert.IsFalse(TypeGuard.IsNever(I)) }) it('Normalize Union 6', () => { const T = Type.Recursive(() => Type.Union([Type.Object({ x: Type.String() }), Type.Object({ y: Type.String() })])) // @ts-ignore const I = Type.Index(T, ['x', 'y']) Assert.IsFalse(TypeGuard.IsNever(I)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/normalize/intersect.ts000066400000000000000000000011201505437577000262450ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/normalize/Intersect', () => { it('Normalize 1', () => { const T = Type.Intersect([Type.Number(), Type.String()]) const R = TypeGuard.IsIntersect(T) Assert.IsTrue(R) }) it('Normalize 2', () => { const T = Type.Intersect([Type.Number()]) const R = TypeGuard.IsNumber(T) Assert.IsTrue(R) }) it('Normalize 3', () => { const T = Type.Intersect([]) const R = TypeGuard.IsNever(T) Assert.IsTrue(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/normalize/record.ts000066400000000000000000000005701505437577000255330ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/normalize/Record', () => { it('Normalize 1', () => { const K = Type.Union([Type.Literal('A'), Type.Literal('B')]) const T = Type.Record(K, Type.String()) const R = TypeGuard.IsObject(T) Assert.IsTrue(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/normalize/union.ts000066400000000000000000000010741505437577000254050ustar00rootroot00000000000000import { TypeGuard } from '@sinclair/typebox' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/normalize/Union', () => { it('Normalize 1', () => { const T = Type.Union([Type.Number(), Type.String()]) const R = TypeGuard.IsUnion(T) Assert.IsTrue(R) }) it('Normalize 2', () => { const T = Type.Union([Type.Number()]) const R = TypeGuard.IsNumber(T) Assert.IsTrue(R) }) it('Normalize 3', () => { const T = Type.Union([]) const R = TypeGuard.IsNever(T) Assert.IsTrue(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/options/000077500000000000000000000000001505437577000233765ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/type/options/assign-builder.ts000066400000000000000000000215641505437577000266660ustar00rootroot00000000000000import { JavaScriptTypeBuilder } from '@sinclair/typebox' import { Assert } from '../../assert/index' const Type = new JavaScriptTypeBuilder() // TypeBuilder will proxy calls through to the raw function API describe('type/options/AssignTypeBuilder', () => { it('Should assign options for Any', () => { const T = Type.Any({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Array', () => { const T = Type.Array(Type.String(), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for AsyncIterator', () => { const T = Type.AsyncIterator(Type.String(), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Awaited', () => { const T = Type.Awaited(Type.String(), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for BigInt', () => { const T = Type.BigInt({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Boolean', () => { const T = Type.Boolean({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Capitalize', () => { const T = Type.Capitalize(Type.Literal('hello'), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Composite', () => { const T = Type.Composite([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })], { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Const', () => { const T = Type.Const(1, { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Constructor', () => { const T = Type.Constructor([], Type.Any(), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Date', () => { const T = Type.Date({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Enum', () => { const T = Type.Enum({}, { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Exclude', () => { const T = Type.Exclude(Type.Union([Type.Literal(1), Type.Literal(2)]), Type.Literal(2), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Extends', () => { const T = Type.Extends(Type.String(), Type.String(), Type.Number(), Type.Null(), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Extract', () => { const T = Type.Extract(Type.Union([Type.Literal(1), Type.Literal(2)]), Type.Literal(2), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Function', () => { const T = Type.Function([], Type.Any(), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Integer', () => { const T = Type.Integer({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Intersect 1', () => { const T = Type.Intersect([], { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Intersect 2', () => { const T = Type.Intersect([Type.Object({ x: Type.Number() })], { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Intersect 3', () => { const T = Type.Intersect([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })], { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Iterator', () => { const T = Type.Iterator(Type.String(), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for KeyOf', () => { const T = Type.KeyOf(Type.Object({ x: Type.Number() }), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Literal', () => { const T = Type.Literal(1, { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Lowercase', () => { const T = Type.Lowercase(Type.Literal('hello'), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Mapped 1', () => { const M = Type.Mapped(Type.TemplateLiteral('${1|2|3}'), (K) => K, { foo: 'bar' }) Assert.IsEqual(M.foo, 'bar') }) it('Should assign options for Mapped 2', () => { const T = Type.Object({ x: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), (K) => Type.Index(T, K), { foo: 'bar' }) Assert.IsEqual(M.foo, 'bar') }) it('Should assign options for Never', () => { const T = Type.Never({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Not', () => { const T = Type.Not(Type.String(), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Null', () => { const T = Type.Null({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Number', () => { const T = Type.Number({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Object', () => { const T = Type.Object( { x: Type.String(), }, { foo: 'bar' }, ) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Omit', () => { const T = Type.Omit( Type.Object({ x: Type.String(), y: Type.String(), }), ['x'], { foo: 'bar' }, ) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Partial', () => { const T = Type.Partial( Type.Object({ x: Type.String(), }), { foo: 'bar' }, ) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Pick', () => { const T = Type.Pick( Type.Object({ x: Type.String(), y: Type.String(), }), ['x'], { foo: 'bar' }, ) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Record', () => { const T = Type.Record(Type.String(), Type.Number(), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Recursive', () => { const T = Type.Recursive( (This) => Type.Object({ x: Type.Number(), y: Type.Array(This), }), { foo: 'bar' }, ) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Ref 1', () => { const T = Type.Object({ x: Type.Number() }, { $id: 'T' }) const R = Type.Ref(T, { foo: 'bar' }) Assert.IsEqual(R.foo, 'bar') }) it('Should assign options for Ref 2', () => { const R = Type.Ref('T', { foo: 'bar' }) Assert.IsEqual(R.foo, 'bar') }) it('Should assign options for RegExp', () => { const R = Type.RegExp(/xyz/, { foo: 'bar' }) Assert.IsEqual(R.foo, 'bar') }) it('Should assign options for Partial', () => { const T = Type.Required( Type.Object({ x: Type.String(), }), { foo: 'bar' }, ) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for String', () => { const T = Type.String({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Symbol', () => { const T = Type.Symbol({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for TemplateLiteral 1', () => { const T = Type.TemplateLiteral('hello${1|2|3}', { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for TemplateLiteral 2', () => { const T = Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal('1'), Type.Literal('2'), Type.Literal('3')])], { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Tuple 1', () => { const T = Type.Tuple([], { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Tuple 2', () => { const T = Type.Tuple([Type.String(), Type.Number()], { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Uint8Array', () => { const T = Type.Uint8Array({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Uncapitalize', () => { const T = Type.Uncapitalize(Type.Literal('hello'), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Undefined', () => { const T = Type.Undefined({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Union 1', () => { const T = Type.Union([], { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Union 1', () => { const T = Type.Union([Type.String()], { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Union 1', () => { const T = Type.Union([Type.String(), Type.Boolean()], { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Unknown', () => { const T = Type.Unknown({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Uppercase', () => { const T = Type.Uppercase(Type.Literal('hello'), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Void', () => { const T = Type.Void({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/options/assign.ts000066400000000000000000000213561505437577000252410ustar00rootroot00000000000000import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/options/Assign', () => { it('Should assign options for Any', () => { const T = Type.Any({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Array', () => { const T = Type.Array(Type.String(), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for AsyncIterator', () => { const T = Type.AsyncIterator(Type.String(), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Awaited', () => { const T = Type.Awaited(Type.String(), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for BigInt', () => { const T = Type.BigInt({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Boolean', () => { const T = Type.Boolean({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Capitalize', () => { const T = Type.Capitalize(Type.Literal('hello'), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Composite', () => { const T = Type.Composite([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })], { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Const', () => { const T = Type.Const(1, { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Constructor', () => { const T = Type.Constructor([], Type.Any(), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Date', () => { const T = Type.Date({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Enum', () => { const T = Type.Enum({}, { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Exclude', () => { const T = Type.Exclude(Type.Union([Type.Literal(1), Type.Literal(2)]), Type.Literal(2), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Extends', () => { const T = Type.Extends(Type.String(), Type.String(), Type.Number(), Type.Null(), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Extract', () => { const T = Type.Extract(Type.Union([Type.Literal(1), Type.Literal(2)]), Type.Literal(2), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Function', () => { const T = Type.Function([], Type.Any(), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Integer', () => { const T = Type.Integer({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Intersect 1', () => { const T = Type.Intersect([], { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Intersect 2', () => { const T = Type.Intersect([Type.Object({ x: Type.Number() })], { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Intersect 3', () => { const T = Type.Intersect([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })], { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Iterator', () => { const T = Type.Iterator(Type.String(), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for KeyOf', () => { const T = Type.KeyOf(Type.Object({ x: Type.Number() }), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Literal', () => { const T = Type.Literal(1, { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Lowercase', () => { const T = Type.Lowercase(Type.Literal('hello'), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Mapped 1', () => { const M = Type.Mapped(Type.TemplateLiteral('${1|2|3}'), (K) => K, { foo: 'bar' }) Assert.IsEqual(M.foo, 'bar') }) it('Should assign options for Mapped 2', () => { const T = Type.Object({ x: Type.Number() }) const M = Type.Mapped(Type.KeyOf(T), (K) => Type.Index(T, K), { foo: 'bar' }) Assert.IsEqual(M.foo, 'bar') }) it('Should assign options for Never', () => { const T = Type.Never({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Not', () => { const T = Type.Not(Type.String(), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Null', () => { const T = Type.Null({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Number', () => { const T = Type.Number({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Object', () => { const T = Type.Object( { x: Type.String(), }, { foo: 'bar' }, ) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Omit', () => { const T = Type.Omit( Type.Object({ x: Type.String(), y: Type.String(), }), ['x'], { foo: 'bar' }, ) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Partial', () => { const T = Type.Partial( Type.Object({ x: Type.String(), }), { foo: 'bar' }, ) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Pick', () => { const T = Type.Pick( Type.Object({ x: Type.String(), y: Type.String(), }), ['x'], { foo: 'bar' }, ) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Record', () => { const T = Type.Record(Type.String(), Type.Number(), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Recursive', () => { const T = Type.Recursive( (This) => Type.Object({ x: Type.Number(), y: Type.Array(This), }), { foo: 'bar' }, ) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Ref 1', () => { const T = Type.Object({ x: Type.Number() }, { $id: 'T' }) const R = Type.Ref(T, { foo: 'bar' }) Assert.IsEqual(R.foo, 'bar') }) it('Should assign options for Ref 2', () => { const R = Type.Ref('T', { foo: 'bar' }) Assert.IsEqual(R.foo, 'bar') }) it('Should assign options for RegExp', () => { const R = Type.RegExp(/xyz/, { foo: 'bar' }) Assert.IsEqual(R.foo, 'bar') }) it('Should assign options for Partial', () => { const T = Type.Required( Type.Object({ x: Type.String(), }), { foo: 'bar' }, ) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for String', () => { const T = Type.String({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Symbol', () => { const T = Type.Symbol({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for TemplateLiteral 1', () => { const T = Type.TemplateLiteral('hello${1|2|3}', { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for TemplateLiteral 2', () => { const T = Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal('1'), Type.Literal('2'), Type.Literal('3')])], { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Tuple 1', () => { const T = Type.Tuple([], { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Tuple 2', () => { const T = Type.Tuple([Type.String(), Type.Number()], { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Uint8Array', () => { const T = Type.Uint8Array({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Uncapitalize', () => { const T = Type.Uncapitalize(Type.Literal('hello'), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Undefined', () => { const T = Type.Undefined({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Union 1', () => { const T = Type.Union([], { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Union 1', () => { const T = Type.Union([Type.String()], { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Union 1', () => { const T = Type.Union([Type.String(), Type.Boolean()], { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Unknown', () => { const T = Type.Unknown({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Uppercase', () => { const T = Type.Uppercase(Type.Literal('hello'), { foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) it('Should assign options for Void', () => { const T = Type.Void({ foo: 'bar' }) Assert.IsEqual(T.foo, 'bar') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/options/index.ts000066400000000000000000000000541505437577000250540ustar00rootroot00000000000000import './assign-builder' import './assign' sinclairzx81-typebox-e0ec98c/test/runtime/type/registry/000077500000000000000000000000001505437577000235535ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/type/registry/format.ts000066400000000000000000000013561505437577000254200ustar00rootroot00000000000000import { FormatRegistry } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/registry/Format', () => { it('Should set format', () => { FormatRegistry.Set('test#format1', () => true) }) it('Should get format', () => { FormatRegistry.Set('test#format2', () => true) const format = FormatRegistry.Get('test#format2') Assert.IsEqual(typeof format, 'function') }) it('Should return true if exists', () => { FormatRegistry.Set('test#format3', () => true) Assert.IsTrue(FormatRegistry.Has('test#format3')) }) it('Should clear formats', () => { FormatRegistry.Set('test#format4', () => true) FormatRegistry.Clear() Assert.IsFalse(FormatRegistry.Has('test#format4')) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/registry/index.ts000066400000000000000000000000421505437577000252260ustar00rootroot00000000000000import './format' import './type' sinclairzx81-typebox-e0ec98c/test/runtime/type/registry/type.ts000066400000000000000000000013061505437577000251040ustar00rootroot00000000000000import { TypeRegistry } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/registry/Type', () => { it('Should set type', () => { TypeRegistry.Set('test#type1', () => true) }) it('Should get type', () => { TypeRegistry.Set('test#type2', () => true) const format = TypeRegistry.Get('test#type2') Assert.IsEqual(typeof format, 'function') }) it('Should return true if exists', () => { TypeRegistry.Set('test#type3', () => true) Assert.IsTrue(TypeRegistry.Has('test#type3')) }) it('Should clear types', () => { TypeRegistry.Set('test#type4', () => true) TypeRegistry.Clear() Assert.IsFalse(TypeRegistry.Has('test#type4')) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/sets/000077500000000000000000000000001505437577000226615ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/type/sets/index.ts000066400000000000000000000000201505437577000243300ustar00rootroot00000000000000import './sets' sinclairzx81-typebox-e0ec98c/test/runtime/type/sets/sets.ts000066400000000000000000000123651505437577000242160ustar00rootroot00000000000000import * as Type from '@sinclair/typebox' import { Assert } from '../../assert' describe('type/sets', () => { // ---------------------------------------------------------------- // Distinct // ---------------------------------------------------------------- it('Should Distinct', () => { const R = Type.SetDistinct([1, 1, 2, 2]) Assert.IsEqual(R, [1, 2]) }) // ---------------------------------------------------------------- // Includes // ---------------------------------------------------------------- it('Should Includes 1', () => { const R = Type.SetIncludes([1, 2, 3, 4], 1) Assert.IsTrue(R) }) it('Should Includes 2', () => { const R = Type.SetIncludes([1, 2, 3, 4], 7) Assert.IsFalse(R) }) // ---------------------------------------------------------------- // IsSubset // ---------------------------------------------------------------- it('Should IsSubset 1', () => { const R = Type.SetIsSubset([1, 2], [1, 2]) Assert.IsTrue(R) }) it('Should IsSubset 2', () => { const R = Type.SetIsSubset([1, 2], [1, 2, 3]) Assert.IsTrue(R) }) it('Should IsSubset 3', () => { const R = Type.SetIsSubset([1, 2], [1]) Assert.IsFalse(R) }) // ---------------------------------------------------------------- // Intersect // ---------------------------------------------------------------- it('Should Intersect 1', () => { const R = Type.SetIntersect([1, 2], [1, 2]) Assert.IsEqual(R, [1, 2]) }) it('Should Intersect 2', () => { const R = Type.SetIntersect([1], [1, 2]) Assert.IsEqual(R, [1]) }) it('Should Intersect 3', () => { const R = Type.SetIntersect([1, 2], [1]) Assert.IsEqual(R, [1]) }) it('Should Intersect 4', () => { const R = Type.SetIntersect([], [1]) Assert.IsEqual(R, []) }) it('Should Intersect 5', () => { const R = Type.SetIntersect([1], []) Assert.IsEqual(R, []) }) it('Should Intersect 6', () => { const R = Type.SetIntersect([1], [2]) Assert.IsEqual(R, []) }) // ---------------------------------------------------------------- // Union // ---------------------------------------------------------------- it('Should Union 1', () => { const R = Type.SetUnion([1, 2], [1, 2]) Assert.IsEqual(R, [1, 2, 1, 2]) }) it('Should Union 2', () => { const R = Type.SetUnion([1], [1, 2]) Assert.IsEqual(R, [1, 1, 2]) }) it('Should Union 3', () => { const R = Type.SetUnion([1, 2], [1]) Assert.IsEqual(R, [1, 2, 1]) }) it('Should Union 4', () => { const R = Type.SetUnion([], [1]) Assert.IsEqual(R, [1]) }) it('Should Union 5', () => { const R = Type.SetUnion([1], []) Assert.IsEqual(R, [1]) }) // ---------------------------------------------------------------- // Complement // ---------------------------------------------------------------- it('Should Complement 1', () => { const R = Type.SetComplement([1, 2, 3, 4], [2, 3]) Assert.IsEqual(R, [1, 4]) }) it('Should Complement 2', () => { const R = Type.SetComplement([2, 3], [1, 2, 3, 4]) Assert.IsEqual(R, []) }) // ---------------------------------------------------------------- // IntersectMany // ---------------------------------------------------------------- it('Should IntersectMany 1', () => { const R = Type.SetIntersectMany([[1, 2, 3], [1, 2], [1]] as const) Assert.IsEqual(R, [1]) }) it('Should IntersectMany 2', () => { const R = Type.SetIntersectMany([[1], [1, 2], [1, 2, 3]] as const) Assert.IsEqual(R, [1]) }) it('Should IntersectMany 3', () => { const R = Type.SetIntersectMany([ [1, 2], [1, 2], ] as const) Assert.IsEqual(R, [1, 2]) }) it('Should IntersectMany 4', () => { const R = Type.SetIntersectMany([[1], [2]] as const) Assert.IsEqual(R, []) }) it('Should IntersectMany 5', () => { const R = Type.SetIntersectMany([[1], []] as const) Assert.IsEqual(R, []) }) it('Should IntersectMany 6', () => { const R = Type.SetIntersectMany([[], [1]] as const) Assert.IsEqual(R, []) }) it('Should IntersectMany 7', () => { const R = Type.SetIntersectMany([[1], [1], [1], [1], []] as const) Assert.IsEqual(R, []) }) it('Should IntersectMany 8', () => { const R = Type.SetIntersectMany([[], [1], [1], [1], [1]] as const) Assert.IsEqual(R, []) }) // ---------------------------------------------------------------- // UnionMany // ---------------------------------------------------------------- it('Should UnionMany 1', () => { const R = Type.SetUnionMany([[1, 2, 3], [1, 2], [1]] as const) Assert.IsEqual(R, [1, 2, 3, 1, 2, 1]) }) it('Should UnionMany 2', () => { const R = Type.SetUnionMany([[1], [1, 2], [1, 2, 3]] as const) Assert.IsEqual(R, [1, 1, 2, 1, 2, 3]) }) it('Should UnionMany 3', () => { const R = Type.SetUnionMany([ [1, 2], [1, 2], ] as const) Assert.IsEqual(R, [1, 2, 1, 2]) }) it('Should UnionMany 4', () => { const R = Type.SetUnionMany([[1], [2]] as const) Assert.IsEqual(R, [1, 2]) }) it('Should UnionMany 5', () => { const R = Type.SetUnionMany([[1], []] as const) Assert.IsEqual(R, [1]) }) it('Should UnionMany 6', () => { const R = Type.SetUnionMany([[], [1]] as const) Assert.IsEqual(R, [1]) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/template-literal/000077500000000000000000000000001505437577000251505ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/type/template-literal/finite.ts000066400000000000000000000046041505437577000270020ustar00rootroot00000000000000import { TemplateLiteralParse, IsTemplateLiteralExpressionFinite, PatternString, PatternBoolean, PatternNumber } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/template-literal/IsTemplateLiteralExpressionFinite', () => { // --------------------------------------------------------------- // Finite // --------------------------------------------------------------- it('Finite 1', () => { const E = TemplateLiteralParse(`A`) const R = IsTemplateLiteralExpressionFinite(E) Assert.IsTrue(R) }) it('Finite 2', () => { const E = TemplateLiteralParse(`A|B`) const R = IsTemplateLiteralExpressionFinite(E) Assert.IsTrue(R) }) it('Finite 3', () => { const E = TemplateLiteralParse(`A(B|C)`) const R = IsTemplateLiteralExpressionFinite(E) Assert.IsTrue(R) }) it('Finite 4', () => { const E = TemplateLiteralParse(`${PatternBoolean}`) const R = IsTemplateLiteralExpressionFinite(E) Assert.IsTrue(R) }) it('Finite 5', () => { const E = TemplateLiteralParse(`\\.\\*`) const R = IsTemplateLiteralExpressionFinite(E) Assert.IsTrue(R) }) // --------------------------------------------------------------- // Infinite // --------------------------------------------------------------- it('Infinite 1', () => { const E = TemplateLiteralParse(`${PatternString}`) const R = IsTemplateLiteralExpressionFinite(E) Assert.IsFalse(R) }) it('Infinite 2', () => { const E = TemplateLiteralParse(`${PatternNumber}`) const R = IsTemplateLiteralExpressionFinite(E) Assert.IsFalse(R) }) it('Infinite 3', () => { const E = TemplateLiteralParse(`A|${PatternString}`) const R = IsTemplateLiteralExpressionFinite(E) Assert.IsFalse(R) }) it('Infinite 4', () => { const E = TemplateLiteralParse(`A|${PatternNumber}`) const R = IsTemplateLiteralExpressionFinite(E) Assert.IsFalse(R) }) it('Infinite 5', () => { const E = TemplateLiteralParse(`A(${PatternString})`) const R = IsTemplateLiteralExpressionFinite(E) Assert.IsFalse(R) }) it('Infinite 6', () => { const E = TemplateLiteralParse(`A(${PatternNumber})`) const R = IsTemplateLiteralExpressionFinite(E) Assert.IsFalse(R) }) it('Infinite 7', () => { const E = TemplateLiteralParse(`${PatternString}_foo`) const R = IsTemplateLiteralExpressionFinite(E) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/template-literal/generate.ts000066400000000000000000000156711505437577000273240ustar00rootroot00000000000000import { TemplateLiteralParse, TemplateLiteralExpressionGenerate } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/template-literal/TemplateLiteralExpressionGenerate', () => { // --------------------------------------------------------------- // Exact (No Default Unwrap) // --------------------------------------------------------------- it('Exact 1', () => { const E = TemplateLiteralParse('^$') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['^$']) }) it('Exact 2', () => { const E = TemplateLiteralParse('^A$') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['^A$']) }) // --------------------------------------------------------------- // Patterns // --------------------------------------------------------------- it('Pattern 1', () => { const E = TemplateLiteralParse('(true|false)') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['true', 'false']) }) it('Pattern 2', () => { const E = TemplateLiteralParse('(0|[1-9][0-9]*)') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['0', '[1-9][0-9]*']) }) it('Pattern 3', () => { const E = TemplateLiteralParse('.*') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['.*']) }) // --------------------------------------------------------------- // Expression // --------------------------------------------------------------- it('Expression 1', () => { const E = TemplateLiteralParse(')') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, [')']) }) it('Expression 2', () => { const E = TemplateLiteralParse('\\)') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, [')']) }) it('Expression 3', () => { const E = TemplateLiteralParse('\\(') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['(']) }) it('Expression 4', () => { const E = TemplateLiteralParse('') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['']) }) it('Expression 5', () => { const E = TemplateLiteralParse('\\') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['\\']) }) it('Expression 6', () => { const E = TemplateLiteralParse('()') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['']) }) it('Expression 7', () => { const E = TemplateLiteralParse('(a)') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['a']) }) it('Expression 8', () => { const E = TemplateLiteralParse('()))') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['))']) }) it('Expression 9', () => { const E = TemplateLiteralParse('())') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, [')']) }) it('Expression 10', () => { const E = TemplateLiteralParse('A|B') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['A', 'B']) }) it('Expression 11', () => { const E = TemplateLiteralParse('A|(B)') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['A', 'B']) }) it('Expression 12', () => { const E = TemplateLiteralParse('A(B)') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['AB']) }) it('Expression 13', () => { const E = TemplateLiteralParse('(A)B') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['AB']) }) it('Expression 14', () => { const E = TemplateLiteralParse('(A)|B') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['A', 'B']) }) it('Expression 15', () => { const E = TemplateLiteralParse('|') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['']) }) it('Expression 16', () => { const E = TemplateLiteralParse('||') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['']) }) it('Expression 17', () => { const E = TemplateLiteralParse('||A') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['A']) }) it('Expression 18', () => { const E = TemplateLiteralParse('A||') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['A']) }) it('Expression 19', () => { const E = TemplateLiteralParse('A||B') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['A', 'B']) }) it('Expression 20', () => { const E = TemplateLiteralParse('A|()|B') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['A', '', 'B']) }) it('Expression 21', () => { const E = TemplateLiteralParse('A|(|)|B') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['A', '', 'B']) }) it('Expression 22', () => { const E = TemplateLiteralParse('A|(||)|B') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['A', '', 'B']) }) it('Expression 23', () => { const E = TemplateLiteralParse('|A(||)B|') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['AB']) }) it('Expression 24', () => { const E = TemplateLiteralParse('A(B)(C)') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['ABC']) }) it('Expression 25', () => { const E = TemplateLiteralParse('A(B)|(C)') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['AB', 'C']) }) it('Expression 26', () => { const E = TemplateLiteralParse('A(B|C)') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['AB', 'AC']) }) it('Expression 27', () => { const E = TemplateLiteralParse('A|(B|C)') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['A', 'B', 'C']) }) it('Expression 28', () => { const E = TemplateLiteralParse('((A)B)C') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['ABC']) }) it('Expression 29', () => { const E = TemplateLiteralParse('(0|1)(0|1)') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['00', '01', '10', '11']) }) it('Expression 30', () => { const E = TemplateLiteralParse('(0|1)|(0|1)') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['0', '1', '0', '1']) }) it('Expression 31', () => { const E = TemplateLiteralParse('(0|(1|0)|1)') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['0', '1', '0', '1']) }) it('Expression 32', () => { const E = TemplateLiteralParse('(0(1|0)1)') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['011', '001']) }) it('Expression 33', () => { const E = TemplateLiteralParse('\\$prop(1|2|3)') const R = [...TemplateLiteralExpressionGenerate(E)] Assert.IsEqual(R, ['$prop1', '$prop2', '$prop3']) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/template-literal/index.ts000066400000000000000000000001121505437577000266210ustar00rootroot00000000000000import './finite' import './generate' import './parse' import './pattern' sinclairzx81-typebox-e0ec98c/test/runtime/type/template-literal/parse.ts000066400000000000000000000271221505437577000266360ustar00rootroot00000000000000import { TemplateLiteralParse } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/template-literal/TemplateLiteralParser', () => { // --------------------------------------------------------------- // Throws // --------------------------------------------------------------- it('Throw 1', () => { Assert.Throws(() => TemplateLiteralParse('(')) }) it('Throw 2', () => { Assert.Throws(() => TemplateLiteralParse('(')) }) // --------------------------------------------------------------- // Exact (No Default Unwrap) // --------------------------------------------------------------- it('Exact 1', () => { const E = TemplateLiteralParse('^$') Assert.IsEqual(E, { type: 'const', const: '^$', }) }) it('Exact 2', () => { const E = TemplateLiteralParse('^A$') Assert.IsEqual(E, { type: 'const', const: '^A$', }) }) // --------------------------------------------------------------- // Patterns // --------------------------------------------------------------- it('Pattern 1', () => { const E = TemplateLiteralParse('(true|false)') Assert.IsEqual(E, { type: 'or', expr: [ { type: 'const', const: 'true', }, { type: 'const', const: 'false', }, ], }) }) it('Pattern 2', () => { const E = TemplateLiteralParse('(0|[1-9][0-9]*)') Assert.IsEqual(E, { type: 'or', expr: [ { type: 'const', const: '0', }, { type: 'const', const: '[1-9][0-9]*', }, ], }) }) it('Pattern 3', () => { const E = TemplateLiteralParse('.*') Assert.IsEqual(E, { type: 'const', const: '.*', }) }) // --------------------------------------------------------------- // Expression // --------------------------------------------------------------- it('Expression 1', () => { const E = TemplateLiteralParse(')') Assert.IsEqual(E, { type: 'const', const: ')', }) }) it('Expression 2', () => { const E = TemplateLiteralParse('\\)') Assert.IsEqual(E, { type: 'const', const: ')', }) }) it('Expression 3', () => { const E = TemplateLiteralParse('\\(') Assert.IsEqual(E, { type: 'const', const: '(', }) }) it('Expression 4', () => { const E = TemplateLiteralParse('') Assert.IsEqual(E, { type: 'const', const: '', }) }) it('Expression 5', () => { const E = TemplateLiteralParse('\\') Assert.IsEqual(E, { type: 'const', const: '\\', }) }) it('Expression 6', () => { const E = TemplateLiteralParse('()') Assert.IsEqual(E, { type: 'const', const: '', }) }) it('Expression 7', () => { const E = TemplateLiteralParse('(a)') Assert.IsEqual(E, { type: 'const', const: 'a', }) }) it('Expression 8', () => { const E = TemplateLiteralParse('()))') Assert.IsEqual(E, { type: 'and', expr: [ { type: 'const', const: '', }, { type: 'const', const: '))', }, ], }) }) it('Expression 9', () => { const E = TemplateLiteralParse('())') Assert.IsEqual(E, { type: 'and', expr: [ { type: 'const', const: '', }, { type: 'const', const: ')', }, ], }) }) it('Expression 10', () => { const E = TemplateLiteralParse('A|B') Assert.IsEqual(E, { type: 'or', expr: [ { type: 'const', const: 'A', }, { type: 'const', const: 'B', }, ], }) }) it('Expression 11', () => { const E = TemplateLiteralParse('A|(B)') Assert.IsEqual(E, { type: 'or', expr: [ { type: 'const', const: 'A', }, { type: 'const', const: 'B', }, ], }) }) it('Expression 12', () => { const E = TemplateLiteralParse('A(B)') Assert.IsEqual(E, { type: 'and', expr: [ { type: 'const', const: 'A', }, { type: 'const', const: 'B', }, ], }) }) it('Expression 13', () => { const E = TemplateLiteralParse('(A)B') Assert.IsEqual(E, { type: 'and', expr: [ { type: 'const', const: 'A', }, { type: 'const', const: 'B', }, ], }) }) it('Expression 14', () => { const E = TemplateLiteralParse('(A)|B') Assert.IsEqual(E, { type: 'or', expr: [ { type: 'const', const: 'A', }, { type: 'const', const: 'B', }, ], }) }) it('Expression 15', () => { const E = TemplateLiteralParse('|') Assert.IsEqual(E, { type: 'const', const: '', }) }) it('Expression 16', () => { const E = TemplateLiteralParse('||') Assert.IsEqual(E, { type: 'const', const: '', }) }) it('Expression 17', () => { const E = TemplateLiteralParse('||A') Assert.IsEqual(E, { type: 'const', const: 'A', }) }) it('Expression 18', () => { const E = TemplateLiteralParse('A||') Assert.IsEqual(E, { type: 'const', const: 'A', }) }) it('Expression 19', () => { const E = TemplateLiteralParse('A||B') Assert.IsEqual(E, { type: 'or', expr: [ { type: 'const', const: 'A', }, { type: 'const', const: 'B', }, ], }) }) it('Expression 20', () => { const E = TemplateLiteralParse('A|()|B') Assert.IsEqual(E, { type: 'or', expr: [ { type: 'const', const: 'A', }, { type: 'const', const: '', }, { type: 'const', const: 'B', }, ], }) }) it('Expression 21', () => { const E = TemplateLiteralParse('A|(|)|B') Assert.IsEqual(E, { type: 'or', expr: [ { type: 'const', const: 'A', }, { type: 'const', const: '', }, { type: 'const', const: 'B', }, ], }) }) it('Expression 22', () => { const E = TemplateLiteralParse('A|(||)|B') Assert.IsEqual(E, { type: 'or', expr: [ { type: 'const', const: 'A', }, { type: 'const', const: '', }, { type: 'const', const: 'B', }, ], }) }) it('Expression 23', () => { const E = TemplateLiteralParse('|A(||)B|') Assert.IsEqual(E, { type: 'and', expr: [ { type: 'const', const: 'A', }, { type: 'const', const: '', }, { type: 'const', const: 'B', }, ], }) }) it('Expression 24', () => { const E = TemplateLiteralParse('A(B)(C)') Assert.IsEqual(E, { type: 'and', expr: [ { type: 'const', const: 'A', }, { type: 'const', const: 'B', }, { type: 'const', const: 'C', }, ], }) }) it('Expression 25', () => { const E = TemplateLiteralParse('A(B)|(C)') Assert.IsEqual(E, { type: 'or', expr: [ { type: 'and', expr: [ { type: 'const', const: 'A', }, { type: 'const', const: 'B', }, ], }, { type: 'const', const: 'C', }, ], }) }) it('Expression 26', () => { const E = TemplateLiteralParse('A(B|C)') Assert.IsEqual(E, { type: 'and', expr: [ { type: 'const', const: 'A', }, { type: 'or', expr: [ { type: 'const', const: 'B', }, { type: 'const', const: 'C', }, ], }, ], }) }) it('Expression 27', () => { const E = TemplateLiteralParse('A|(B|C)') Assert.IsEqual(E, { type: 'or', expr: [ { type: 'const', const: 'A', }, { type: 'or', expr: [ { type: 'const', const: 'B', }, { type: 'const', const: 'C', }, ], }, ], }) }) it('Expression 28', () => { const E = TemplateLiteralParse('((A)B)C') Assert.IsEqual(E, { type: 'and', expr: [ { type: 'and', expr: [ { type: 'const', const: 'A', }, { type: 'const', const: 'B', }, ], }, { type: 'const', const: 'C', }, ], }) }) it('Expression 29', () => { const E = TemplateLiteralParse('(0|1)(0|1)') Assert.IsEqual(E, { type: 'and', expr: [ { type: 'or', expr: [ { type: 'const', const: '0', }, { type: 'const', const: '1', }, ], }, { type: 'or', expr: [ { type: 'const', const: '0', }, { type: 'const', const: '1', }, ], }, ], }) }) it('Expression 30', () => { const E = TemplateLiteralParse('(0|1)|(0|1)') Assert.IsEqual(E, { type: 'or', expr: [ { type: 'or', expr: [ { type: 'const', const: '0', }, { type: 'const', const: '1', }, ], }, { type: 'or', expr: [ { type: 'const', const: '0', }, { type: 'const', const: '1', }, ], }, ], }) }) it('Expression 31', () => { const E = TemplateLiteralParse('(0|(1|0)|1)') Assert.IsEqual(E, { type: 'or', expr: [ { type: 'const', const: '0', }, { type: 'or', expr: [ { type: 'const', const: '1', }, { type: 'const', const: '0', }, ], }, { type: 'const', const: '1', }, ], }) }) it('Expression 32', () => { const E = TemplateLiteralParse('(0(1|0)1)') Assert.IsEqual(E, { type: 'and', expr: [ { type: 'const', const: '0', }, { type: 'or', expr: [ { type: 'const', const: '1', }, { type: 'const', const: '0', }, ], }, { type: 'const', const: '1', }, ], }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/type/template-literal/pattern.ts000066400000000000000000000110001505437577000271650ustar00rootroot00000000000000import { Type, TTemplateLiteral, PatternNumber, PatternString, PatternBoolean } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('type/template-literal/TemplateLiteralPattern', () => { const Equal = (template: TTemplateLiteral, expect: string) => { const pattern = template.pattern.slice(1, template.pattern.length - 1) Assert.IsEqual(pattern, expect) } // --------------------------------------------------------------- // Escape // --------------------------------------------------------------- it('Escape 1', () => { const T = Type.TemplateLiteral([Type.Literal('.*')]) Assert.IsEqual(T.pattern, '^\\.\\*$') }) it('Escape 2', () => { const T = Type.TemplateLiteral([Type.Literal('(')]) Assert.IsEqual(T.pattern, '^\\($') }) it('Escape 3', () => { const T = Type.TemplateLiteral([Type.Literal(')')]) Assert.IsEqual(T.pattern, '^\\)$') }) it('Escape 4', () => { const T = Type.TemplateLiteral([Type.Literal('|')]) Assert.IsEqual(T.pattern, '^\\|$') }) // --------------------------------------------------------------- // Pattern // --------------------------------------------------------------- it('Pattern 1', () => { const T = Type.TemplateLiteral([Type.Number()]) Equal(T, `${PatternNumber}`) }) it('Pattern 2', () => { const T = Type.TemplateLiteral([Type.String()]) Equal(T, `${PatternString}`) }) it('Pattern 3', () => { const T = Type.TemplateLiteral([Type.Boolean()]) Equal(T, `${PatternBoolean}`) }) it('Pattern 4', () => { const T = Type.TemplateLiteral([Type.Literal('A'), Type.Number()]) Equal(T, `A${PatternNumber}`) }) it('Pattern 5', () => { const T = Type.TemplateLiteral([Type.Literal('A'), Type.String()]) Equal(T, `A${PatternString}`) }) it('Pattern 6', () => { const T = Type.TemplateLiteral([Type.Literal('A'), Type.Boolean()]) Equal(T, `A${PatternBoolean}`) }) it('Pattern 7', () => { const T = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Number()])]) Equal(T, `(A|${PatternNumber})`) }) it('Pattern 8', () => { const T = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.String()])]) Equal(T, `(A|${PatternString})`) }) it('Pattern 9', () => { const T = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Boolean()])]) Equal(T, `(A|${PatternBoolean})`) }) // --------------------------------------------------------------- // Template // --------------------------------------------------------------- it('Template 1', () => { const T = Type.TemplateLiteral([]) Equal(T, '') }) it('Template 2', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A') ]) Equal(T, 'A') }) it('Template 3', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.Literal('B'), ]) Equal(T, 'AB') }) it('Template 4', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.Union([ Type.Literal('B'), ]) ]) Equal(T, 'AB') }) it('Template 5', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.Union([ Type.Literal('B'), Type.Literal('C'), ]) ]) Equal(T, 'A(B|C)') }) it('Template 6', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.Union([ Type.Literal('B'), Type.Literal('C'), ]), Type.Union([ Type.Literal('D'), Type.Literal('E'), ]) ]) Equal(T, 'A(B|C)(D|E)') }) it('Template 7', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.TemplateLiteral([Type.Literal('A')]), Type.TemplateLiteral([Type.Literal('B')]) ]) Equal(T, 'AB') }) it('Template 8', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.Union([ Type.TemplateLiteral([ Type.Literal('B'), Type.Literal('C'), ]), Type.Literal('D') ]), ]) Equal(T, 'A(BC|D)') }) it('Template 9', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.Union([ Type.TemplateLiteral([ Type.Literal('B'), Type.Literal('C'), ]), Type.Union([ Type.Literal('D'), Type.Literal('E') ]) ]), ]) Equal(T, 'A(BC|(D|E))') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/000077500000000000000000000000001505437577000220365ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/value/assert/000077500000000000000000000000001505437577000233375ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/value/assert/assert.ts000066400000000000000000000017041505437577000252120ustar00rootroot00000000000000import { Value, AssertError } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/Assert', () => { it('Should Assert', () => { Assert.Throws(() => Value.Assert(Type.String(), 1)) }) it('Should throw AssertError', () => { try { Value.Assert(Type.String(), 1) } catch (error) { if (error instanceof AssertError) { return } throw error } }) it('Should throw AssertError and produce Iterator', () => { try { Value.Assert(Type.String(), 1) } catch (error) { if (error instanceof AssertError) { const first = error.Errors().First() Assert.HasProperty(first, 'type') Assert.HasProperty(first, 'schema') Assert.HasProperty(first, 'path') Assert.HasProperty(first, 'value') Assert.HasProperty(first, 'message') return } throw error } }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/assert/index.ts000066400000000000000000000000221505437577000250100ustar00rootroot00000000000000import './assert' sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/000077500000000000000000000000001505437577000227705ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/any.ts000066400000000000000000000027621505437577000241360ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Any', () => { const T = Type.Any() it('Should upcast from string', () => { const value = 'hello' const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should upcast from number', () => { const value = 1 const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should upcast from boolean', () => { const value = false const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result.getTime(100), 100) }) it('Should preserve', () => { const value = { a: 1, b: 2 } const result = Value.Cast(T, value) Assert.IsEqual(result, { a: 1, b: 2 }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/array.ts000066400000000000000000000115141505437577000244600ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Array', () => { const T = Type.Array(Type.Number(), { default: [1, 2, 3] }) const E = [1, 2, 3] it('Should upcast from string', () => { const value = 'hello' const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from number', () => { const value = 1 const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from boolean', () => { const value = true const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, [1]) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should preserve', () => { const value = [6, 7, 8] const result = Value.Cast(T, value) Assert.IsEqual(result, [6, 7, 8]) }) it('Should preserve with invalid element set to default', () => { const value = [6, 7, 8, 'hello', 9] const result = Value.Cast(T, value) Assert.IsEqual(result, [6, 7, 8, 0, 9]) }) // ----------------------------------------------------------------- // Constraints: Ranges // ----------------------------------------------------------------- it('Should cast array and truncate to maxItems from value', () => { const result = Value.Cast(Type.Array(Type.Number(), { maxItems: 3 }), [0, 1, 2, 4, 5, 6]) Assert.IsEqual(result, [0, 1, 2]) }) it('Should cast arrays and append array to minItems from value', () => { const result = Value.Cast(Type.Array(Type.Number(), { minItems: 6 }), [0, 1, 2]) Assert.IsEqual(result, [0, 1, 2, 0, 0, 0]) }) it('Should cast array and truncate to maxItems from default value', () => { const result = Value.Cast(Type.Array(Type.Number(), { maxItems: 3, default: [0, 1, 2, 4, 5, 6] }), null) Assert.IsEqual(result, [0, 1, 2]) }) it('Should cast arrays and append array to minItems from default value', () => { const result = Value.Cast(Type.Array(Type.Number({ default: 1 }), { minItems: 6, default: [0, 1, 2] }), null) Assert.IsEqual(result, [0, 1, 2, 1, 1, 1]) }) // ----------------------------------------------------------------- // Constraints: Unique // ----------------------------------------------------------------- it('Should cast arrays with uniqueItems with unique default value', () => { const result = Value.Cast(Type.Array(Type.Number(), { uniqueItems: true, default: [0, 1, 2] }), null) Assert.IsEqual(result, [0, 1, 2]) }) it('Should cast arrays with uniqueItems with unique value', () => { const result = Value.Cast(Type.Array(Type.Number(), { uniqueItems: true }), [0, 1, 2]) Assert.IsEqual(result, [0, 1, 2]) }) it('Should throw when casting arrays with uniqueItems and no value or default value', () => { Assert.Throws(() => Value.Cast(Type.Array(Type.Number(), { uniqueItems: true }), null)) }) it('Should throw when casting arrays with uniqueItems and not enough values to populate set', () => { Assert.Throws(() => Value.Cast(Type.Array(Type.Number(), { minItems: 3, uniqueItems: true }), [0, 1])) }) it('Should throw when casting arrays with uniqueItems and not enough default values to populate set', () => { Assert.Throws(() => Value.Cast(Type.Array(Type.Number(), { minItems: 3, uniqueItems: true, default: [0, 1] }), null)) }) // ----------------------------------------------------------------- // Suggestion: https://github.com/sinclairzx81/typebox/issues/239 // ----------------------------------------------------------------- it('Should remove duplicates if uniqueItems is true', () => { const T = Type.Array(Type.Number(), { uniqueItems: true }) const value = [1, 1, 2, 2] const result = Value.Cast(T, value) Assert.IsEqual(result, [1, 2]) }) it('Should should fill up with defaults to minItems', () => { const T = Type.Array(Type.Number(), { minItems: 3 }) const value = [1, 2] const result = Value.Cast(T, value) Assert.IsEqual(result, [1, 2, 0]) }) it('Should should truncate to maxItems', () => { const T = Type.Array(Type.Number(), { maxItems: 3 }) const value = [1, 2, 3, 4] const result = Value.Cast(T, value) Assert.IsEqual(result, [1, 2, 3]) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/async-iterator.ts000066400000000000000000000022421505437577000263040ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/AsyncIterator', () => { const T = Type.AsyncIterator(Type.Any()) it('Should upcast from string', () => { const value = 'world' const result = Value.Cast(T, value) Assert.IsTrue(Symbol.asyncIterator in result) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsTrue(Symbol.asyncIterator in result) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsTrue(Symbol.asyncIterator in result) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsTrue(Symbol.asyncIterator in result) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsTrue(Symbol.asyncIterator in result) }) it('Should preseve', () => { const value = (async function* () {})() const result = Value.Cast(T, value) Assert.IsTrue(value === result) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/bigint.ts000066400000000000000000000027341505437577000246220ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/BigInt', () => { const T = Type.BigInt() const E = BigInt(0) it('Should upcast from string', () => { const value = 'hello' const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from number', () => { const value = 0 const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from boolean', () => { const value = true const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should preserve', () => { const value = BigInt(100) const result = Value.Cast(T, value) Assert.IsEqual(result, BigInt(100)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/boolean.ts000066400000000000000000000027171505437577000247660ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Boolean', () => { const T = Type.Boolean() const E = false it('Should upcast from string', () => { const value = 'hello' const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from number', () => { const value = 0 const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from boolean', () => { const value = true const result = Value.Cast(T, value) Assert.IsEqual(result, true) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should preserve', () => { const value = true const result = Value.Cast(T, value) Assert.IsEqual(result, true) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/composite.ts000066400000000000000000000042631505437577000253470ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Composite', () => { const A = Type.Object({ x: Type.Number({ default: 0 }), y: Type.Number({ default: 1 }), z: Type.Number({ default: 2 }), }) const B = Type.Object({ a: Type.Number({ default: 'a' }), b: Type.Number({ default: 'b' }), c: Type.Number({ default: 'c' }), }) const T = Type.Composite([A, B]) const E = { x: 0, y: 1, z: 2, a: 'a', b: 'b', c: 'c', } it('Should upcast from string', () => { const value = 'hello' const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from number', () => { const value = E const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from boolean', () => { const value = true const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast and preserve object', () => { const value = { x: 7, y: 8, z: 9 } const result = Value.Cast(T, value) Assert.IsEqual(result, { x: 7, y: 8, z: 9, a: 'a', b: 'b', c: 'c', }) }) it('Should upcast and preserve from incorrect properties', () => { const value = { x: {}, y: 8, z: 9 } const result = Value.Cast(T, value) Assert.IsEqual(result, { x: 0, y: 8, z: 9, a: 'a', b: 'b', c: 'c', }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/date.ts000066400000000000000000000023431505437577000242570ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Date', () => { const T = Type.Date() const E = new Date(0) it('Should upcast from string', () => { const value = 'world' const result = Value.Cast(T, value) Assert.InRange(result.getTime(), new Date().getTime(), 1000) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.InRange(result.getTime(), new Date().getTime(), 1000) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.InRange(result.getTime(), new Date().getTime(), 1000) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.InRange(result.getTime(), new Date().getTime(), 1000) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.InRange(result.getTime(), new Date().getTime(), 1000) }) it('Should preseve', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result.getTime(), 100) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/enum.ts000066400000000000000000000032121505437577000243020ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Boolean', () => { enum Foo { A, B, } const T = Type.Enum(Foo) const E = Foo.A it('Should upcast from string', () => { const value = 'hello' const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from number', () => { const value = 123 const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from boolean', () => { const value = true const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from enum A', () => { const value = Foo.A const result = Value.Cast(T, value) Assert.IsEqual(result, Foo.A) }) it('Should upcast from enum B', () => { const value = Foo.B const result = Value.Cast(T, value) Assert.IsEqual(result, Foo.B) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/import.ts000066400000000000000000000025361505437577000246600ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Import', () => { const T = Type.Module({ A: Type.Number(), }).Import('A') const E = 0 it('Should upcast from string', () => { const value = 'world' const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from number', () => { const value = 1 const result = Value.Cast(T, value) Assert.IsEqual(result, 1) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should preseve', () => { const value = 123 const result = Value.Cast(T, value) Assert.IsEqual(result, 123) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/index.ts000066400000000000000000000011231505437577000244440ustar00rootroot00000000000000import './any' import './array' import './async-iterator' import './bigint' import './boolean' import './composite' import './date' import './enum' import './import' import './integer' import './intersect' import './iterator' import './keyof' import './kind' import './literal' import './never' import './not' import './null' import './number' import './object' import './recursive' import './record' import './regexp' import './string' import './symbol' import './template-literal' import './tuple' import './uint8array' import './undefined' import './union' import './unknown' import './void' sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/integer.ts000066400000000000000000000022661505437577000250030ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Integer', () => { const T = Type.Integer() const E = 0 it('Should upcast from string', () => { const value = 'hello' const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from number', () => { const value = 1 const result = Value.Cast(T, value) Assert.IsEqual(result, 1) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/intersect.ts000066400000000000000000000076731505437577000253550ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Intersect', () => { it('Should cast from an invalid object', () => { // prettier-ignore const T = Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]) const V = Value.Cast(T, 1) Assert.IsEqual(V, { x: 0, y: 0 }) }) it('Should cast from an partial object and preserve', () => { // prettier-ignore const T = Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]) const V = Value.Cast(T, { x: 1 }) Assert.IsEqual(V, { x: 1, y: 0 }) }) it('Should cast and use default values', () => { // prettier-ignore const T = Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number({ default: 42 }) }) ]) const V = Value.Cast(T, { x: 1 }) Assert.IsEqual(V, { x: 1, y: 42 }) }) it('Should throw with an illogical intersect', () => { // prettier-ignore const T = Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ x: Type.String() }) ]) Assert.Throws(() => Value.Cast(T, { x: 1 })) }) it('Should throw with an illogical intersect (primative)', () => { // prettier-ignore const T = Type.Intersect([ Type.Number(), Type.String() ]) Assert.Throws(() => Value.Cast(T, { x: 1 })) }) it('Should use last intersected default for equivalent sub schemas', () => { // prettier-ignore const T = Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ x: Type.Number({ default: 1000 }) }) ]) const V = Value.Cast(T, null) Assert.IsEqual(V, { x: 1000 }) }) it('Should use last intersected default for equivalent sub schemas (primitives)', () => { // prettier-ignore const T = Type.Intersect([ Type.Number(), Type.Number({ default: 1000 }) ]) const V = Value.Cast(T, null) Assert.IsEqual(V, 1000) }) it('Should preserve if default is specified', () => { // prettier-ignore const T = Type.Intersect([ Type.Number(), Type.Number({ default: 1000 }) ]) const V = Value.Cast(T, 2000) Assert.IsEqual(V, 2000) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/1264 // ---------------------------------------------------------------- it('Should preserve intersected properties', () => { const T = Type.Intersect([ Type.Object({}), Type.Object({ name: Type.String(), age: Type.Optional(Type.Number()), location: Type.Object({ lat: Type.Number(), long: Type.Number(), }), greeting: Type.String(), }), ]) const V0 = Value.Cast(T, { greeting: 'Hello' }) const V1 = Value.Cast(T, { location: null, greeting: 'Hello' }) const V2 = Value.Cast(T, { location: { lat: 1 }, greeting: 'Hello' }) const V3 = Value.Cast(T, { location: { lat: 1, long: 1 }, greeting: 'Hello' }) Assert.IsEqual(V0, { name: '', location: { lat: 0, long: 0 }, greeting: 'Hello' }) Assert.IsEqual(V1, { name: '', location: { lat: 0, long: 0 }, greeting: 'Hello' }) Assert.IsEqual(V2, { name: '', location: { lat: 1, long: 0 }, greeting: 'Hello' }) Assert.IsEqual(V3, { name: '', location: { lat: 1, long: 1 }, greeting: 'Hello' }) }) // -------------------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/1269#issuecomment-2993924180 // -------------------------------------------------------------------------- it('Should Cast with intersected Record', () => { const T = Type.Intersect([Type.Record(Type.TemplateLiteral('x-${string}'), Type.Unknown()), Type.Object({ name: Type.String() })]) const R = Value.Cast(T, {}) Assert.IsEqual(R, { name: '' }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/iterator.ts000066400000000000000000000021711505437577000251720ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Iterator', () => { const T = Type.Iterator(Type.Any()) it('Should upcast from string', () => { const value = 'world' const result = Value.Cast(T, value) Assert.IsTrue(Symbol.iterator in result) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsTrue(Symbol.iterator in result) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsTrue(Symbol.iterator in result) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsTrue(Symbol.iterator in result) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsTrue(Symbol.iterator in result) }) it('Should preseve', () => { const value = (function* () {})() const result = Value.Cast(T, value) Assert.IsTrue(value === result) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/keyof.ts000066400000000000000000000030511505437577000244540ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/KeyOf', () => { const T = Type.KeyOf( Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }), ) const E = 'x' it('Should upcast from string', () => { const value = 'hello' const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from number', () => { const value = 1 const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from boolean', () => { const value = true const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should preserve', () => { const value = 'y' const result = Value.Cast(T, value) Assert.IsEqual(result, 'y') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/kind.ts000066400000000000000000000035751505437577000242770ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type, Kind, TypeRegistry } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Kind', () => { // --------------------------------------------------------- // Fixtures // --------------------------------------------------------- before(() => TypeRegistry.Set('Kind', (schema, value) => value === 'hello' || value === 'world')) after(() => TypeRegistry.Clear()) // --------------------------------------------------------- // Tests // --------------------------------------------------------- const T = Type.Unsafe({ [Kind]: 'Kind', default: 'hello' }) const E = 'hello' it('Should upcast from string', () => { const value = 'hello' const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from number', () => { const value = 1 const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from boolean', () => { const value = false const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should preserve', () => { const value = { a: 'hello', b: 'world' } const result = Value.Cast( Type.Object({ a: T, b: T, }), value, ) Assert.IsEqual(result, { a: 'hello', b: 'world' }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/literal.ts000066400000000000000000000027321505437577000250000ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Literal', () => { const T = Type.Literal('hello') const E = 'hello' it('Should upcast from string', () => { const value = 'world' const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from number', () => { const value = 1 const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from boolean', () => { const value = true const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should preseve', () => { const value = 'hello' const result = Value.Cast(T, value) Assert.IsEqual(result, 'hello') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/never.ts000066400000000000000000000021421505437577000244560ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Never', () => { const T = Type.Never() it('Should throw from string', () => { const value = 'hello' Assert.Throws(() => Value.Cast(T, value)) }) it('Should throw from number', () => { const value = 1 Assert.Throws(() => Value.Cast(T, value)) }) it('Should throw from boolean', () => { const value = false Assert.Throws(() => Value.Cast(T, value)) }) it('Should throw from object', () => { const value = {} Assert.Throws(() => Value.Cast(T, value)) }) it('Should throw from array', () => { const value = [1] Assert.Throws(() => Value.Cast(T, value)) }) it('Should throw from undefined', () => { const value = undefined Assert.Throws(() => Value.Cast(T, value)) }) it('Should throw from null', () => { const value = null Assert.Throws(() => Value.Cast(T, value)) }) it('Should upcast from date', () => { const value = null Assert.Throws(() => Value.Cast(T, value)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/not.ts000066400000000000000000000027641505437577000241510ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Not', () => { const T = Type.Not(Type.String(), { default: 0 }) it('Should upcast from string', () => { const value = 'hello' const result = Value.Cast(T, value) Assert.IsEqual(result, 0) // default }) it('Should upcast from number', () => { const value = 0 const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should upcast from boolean', () => { const value = true const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should preserve', () => { const value = 100 const result = Value.Cast(T, value) Assert.IsEqual(result, 100) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/null.ts000066400000000000000000000027041505437577000243150ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Null', () => { const T = Type.Null() const E = null it('Should upcast from string', () => { const value = 'world' const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from number', () => { const value = 1 const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from boolean', () => { const value = true const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should preseve', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/number.ts000066400000000000000000000024661505437577000246400ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Number', () => { const T = Type.Number() const E = 0 it('Should upcast from string', () => { const value = 'world' const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from number', () => { const value = 1 const result = Value.Cast(T, value) Assert.IsEqual(result, 1) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should preseve', () => { const value = 123 const result = Value.Cast(T, value) Assert.IsEqual(result, 123) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/object.ts000066400000000000000000000072331505437577000246130ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Object', () => { const T = Type.Object({ a: Type.Number({ default: 'a' }), b: Type.Number({ default: 'b' }), c: Type.Number({ default: 'c' }), x: Type.Number({ default: 0 }), y: Type.Number({ default: 1 }), z: Type.Number({ default: 2 }), }) const E = { x: 0, y: 1, z: 2, a: 'a', b: 'b', c: 'c', } it('Should upcast from string', () => { const value = 'hello' const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from number', () => { const value = E const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from boolean', () => { const value = true const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should preserve', () => { const value = { x: 7, y: 8, z: 9, a: 10, b: 11, c: 12 } const result = Value.Cast(T, value) Assert.IsEqual(result, { x: 7, y: 8, z: 9, a: 10, b: 11, c: 12, }) }) it('Should upcast and preserve partial object', () => { const value = { x: 7, y: 8, z: 9 } const result = Value.Cast(T, value) Assert.IsEqual(result, { x: 7, y: 8, z: 9, a: 'a', b: 'b', c: 'c', }) }) it('Should upcast and preserve partial object with incorrect properties', () => { const value = { x: {}, y: 8, z: 9 } const result = Value.Cast(T, value) Assert.IsEqual(result, { x: 0, y: 8, z: 9, a: 'a', b: 'b', c: 'c', }) }) it('Should upcast and preserve partial object and omit unknown properties', () => { const value = { x: 7, y: 8, z: 9, unknown: 'foo' } const result = Value.Cast(T, value) Assert.IsEqual(result, { x: 7, y: 8, z: 9, a: 'a', b: 'b', c: 'c', }) }) it('Should upcast and create invalid additional properties', () => { const result = Value.Cast( Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.Object({ a: Type.Number(), b: Type.Number(), }), }, ), { x: 1, y: 2, z: true, }, ) Assert.IsEqual(result, { x: 1, y: 2, z: { a: 0, b: 0 }, }) }) it('Should upcast and preserve additional properties', () => { const result = Value.Cast( Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.Object({ a: Type.Number(), b: Type.Number(), }), }, ), { x: 1, y: 2, z: { b: 1 }, }, ) Assert.IsEqual(result, { x: 1, y: 2, z: { a: 0, b: 1 }, }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/record.ts000066400000000000000000000041021505437577000246130ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Record', () => { const T = Type.Record( Type.String(), Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }), ) const E = {} it('Should upcast from string', () => { const value = 'hello' const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from number', () => { const value = E const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from boolean', () => { const value = true const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should preserve', () => { const value = { a: { x: 1, y: 2, z: 3 }, b: { x: 4, y: 5, z: 6 }, } const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should preserve and patch invalid records', () => { const value = { a: { x: 1, y: 2, z: 3 }, b: { x: 4, y: 5, z: {} }, c: [1, 2, 3], d: 1, e: { x: 1, y: 2, w: 9000 }, } const result = Value.Cast(T, value) Assert.IsEqual(result, { a: { x: 1, y: 2, z: 3 }, b: { x: 4, y: 5, z: 0 }, c: { x: 0, y: 0, z: 0 }, d: { x: 0, y: 0, z: 0 }, e: { x: 1, y: 2, z: 0 }, }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/recursive.ts000066400000000000000000000050301505437577000253450ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Recursive', () => { const T = Type.Recursive((This) => Type.Object({ id: Type.String(), nodes: Type.Array(This), }), ) const E = { id: '', nodes: [] } it('Should upcast from string', () => { const value = 'hello' const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from number', () => { const value = E const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from boolean', () => { const value = true const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should preserve', () => { const value = { id: 'A', nodes: [ { id: 'B', nodes: [] }, { id: 'C', nodes: [] }, { id: 'D', nodes: [] }, ], } const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should upcast from varying types', () => { const TypeA = Type.Recursive((This) => Type.Object({ id: Type.String(), nodes: Type.Array(This), }), ) const TypeB = Type.Recursive((This) => Type.Object({ id: Type.String(), name: Type.String({ default: 'test' }), nodes: Type.Array(This), }), ) const ValueA = { id: 'A', nodes: [ { id: 'B', nodes: [] }, { id: 'C', nodes: [] }, { id: 'D', nodes: [] }, ], } const ValueB = Value.Cast(TypeB, ValueA) // Assert.isEqual(ValueB, { // id: 'A', // name: 'test', // nodes: [ // { id: 'B', name: 'test', nodes: [] }, // { id: 'C', name: 'test', nodes: [] }, // { id: 'D', name: 'test', nodes: [] }, // ], // }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/regexp.ts000066400000000000000000000034001505437577000246270ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/RegExp', () => { const T = Type.RegExp(/foo/, { default: 'foo' }) const E = 'foo' it('Should upcast from string', () => { const value = 'hello' const result = Value.Cast(T, value) Assert.IsEqual(result, 'foo') }) it('Should upcast from number', () => { const value = 1 const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from boolean', () => { const value = true const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should preserve', () => { const value = 'foo' const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) // ---------------------------------------------------------------- // Throw // ---------------------------------------------------------------- it('Should throw with no default', () => { const T = Type.RegExp(/foo/) Assert.Throws(() => Value.Cast(T, null)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/string.ts000066400000000000000000000022711505437577000246500ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/String', () => { const T = Type.String() const E = '' it('Should upcast from string', () => { const value = 'hello' const result = Value.Cast(T, value) Assert.IsEqual(result, 'hello') }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should preserve', () => { const value = 'foo' const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/symbol.ts000066400000000000000000000030341505437577000246450ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Symbol', () => { const T = Type.Symbol() it('Should upcast from string', () => { const value = 'hello' const result = Value.Cast(T, value) Assert.IsTypeOf(result, 'symbol') }) it('Should upcast from number', () => { const value = 0 const result = Value.Cast(T, value) Assert.IsTypeOf(result, 'symbol') }) it('Should upcast from boolean', () => { const value = true const result = Value.Cast(T, value) Assert.IsTypeOf(result, 'symbol') }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsTypeOf(result, 'symbol') }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsTypeOf(result, 'symbol') }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsTypeOf(result, 'symbol') }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsTypeOf(result, 'symbol') }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsTypeOf(result, 'symbol') }) it('Should preserve', () => { const value = Symbol('hello') const result = Value.Cast(T, value) Assert.IsEqual(result.description, value.description) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/template-literal.ts000066400000000000000000000030401505437577000266020ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/TemplateLiteral', () => { const T = Type.TemplateLiteral([Type.Literal('hello'), Type.Literal('world')]) const E = 'helloworld' it('Should upcast from string', () => { const value = 'world' const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from number', () => { const value = 1 const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from boolean', () => { const value = true const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should preseve', () => { const value = 'helloworld' const result = Value.Cast(T, value) Assert.IsEqual(result, 'helloworld') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/tuple.ts000066400000000000000000000042171505437577000244750ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Tuple', () => { const T = Type.Tuple([Type.Number(), Type.String()]) const E = [0, ''] it('Should upcast from string', () => { const value = 'hello' const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from number', () => { const value = 1 const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from boolean', () => { const value = true const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, [1, '']) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should preserve', () => { const value = [42, 'world'] const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should upcast with empty', () => { const value = [] as any[] const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should append with less than tuple length', () => { const value = [42] const result = Value.Cast(T, value) Assert.IsEqual(result, [42, '']) }) it('Should truncate with greater than tuple length', () => { const value = [42, '', true] const result = Value.Cast(T, value) Assert.IsEqual(result, [42, '']) }) it('Should preserve and patch invalid element', () => { const value = [{}, 'hello'] const result = Value.Cast(T, value) Assert.IsEqual(result, [0, 'hello']) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/uint8array.ts000066400000000000000000000030571505437577000254530ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Uint8Array', () => { const T = Type.Uint8Array({ default: new Uint8Array([0, 1, 2, 3]) }) const E = new Uint8Array([0, 1, 2, 3]) it('Should upcast from string', () => { const value = 'hello' const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from number', () => { const value = 1 const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from boolean', () => { const value = true const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should preserve', () => { const value = new Uint8Array([6, 7, 8, 9, 10]) const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/undefined.ts000066400000000000000000000027351505437577000253100ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Undefined', () => { const T = Type.Undefined() const E = undefined it('Should upcast from string', () => { const value = 'world' const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from number', () => { const value = 1 const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from boolean', () => { const value = true const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should preseve', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, undefined) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/union.ts000066400000000000000000000262001505437577000244700ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Union', () => { const A = Type.Object( { type: Type.Literal('A'), x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { additionalProperties: false }, ) const B = Type.Object( { type: Type.Literal('B'), a: Type.String(), b: Type.String(), c: Type.String(), }, { additionalProperties: false }, ) const T = Type.Union([A, B]) const E = { type: 'A', x: 0, y: 0, z: 0, } it('Should upcast from string', () => { const value = 'hello' const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from number', () => { const value = 1 const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from boolean', () => { const value = true const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should preserve A', () => { const value = { type: 'A', x: 1, y: 2, z: 3 } const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should preserve B', () => { const value = { type: 'B', a: 'a', b: 'b', c: 'c' } const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should infer through heuristics #1', () => { const value = { type: 'A', a: 'a', b: 'b', c: 'c' } const result = Value.Cast(T, value) Assert.IsEqual(result, { type: 'A', x: 0, y: 0, z: 0 }) }) it('Should infer through heuristics #2', () => { const value = { type: 'B', x: 1, y: 2, z: 3 } const result = Value.Cast(T, value) Assert.IsEqual(result, { type: 'B', a: '', b: '', c: '' }) }) it('Should infer through heuristics #3', () => { const value = { type: 'A', a: 'a', b: 'b', c: null } const result = Value.Cast(T, value) Assert.IsEqual(result, { type: 'A', x: 0, y: 0, z: 0 }) }) it('Should infer through heuristics #4', () => { const value = { type: 'B', x: 1, y: 2, z: {} } const result = Value.Cast(T, value) Assert.IsEqual(result, { type: 'B', a: '', b: '', c: '' }) }) it('Should infer through heuristics #5', () => { const value = { type: 'B', x: 1, y: 2, z: null } const result = Value.Cast(T, value) Assert.IsEqual(result, { type: 'B', a: '', b: '', c: '' }) }) it('Should infer through heuristics #6', () => { const value = { x: 1 } const result = Value.Cast(T, value) Assert.IsEqual(result, { type: 'A', x: 1, y: 0, z: 0 }) }) it('Should infer through heuristics #7', () => { const value = { a: null } // property existing should contribute const result = Value.Cast(T, value) Assert.IsEqual(result, { type: 'B', a: '', b: '', c: '' }) }) it('Should cast with default value (create)', () => { const result = Value.Cast( Type.Object({ id: Type.Number(), value: Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')], { default: 'C' }), }), { id: 42, value: 'D', }, ) Assert.IsEqual(result, { id: 42, value: 'C', }) }) it('Should cast with default value (preserve)', () => { const result = Value.Cast( Type.Object({ id: Type.Number(), value: Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')], { default: 'C' }), }), { id: 42, value: 'B', }, ) Assert.IsEqual(result, { id: 42, value: 'B', }) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/880 // ---------------------------------------------------------------- // prettier-ignore it('Should dereference union variants', () => { const A = Type.Object({ type: Type.Literal('A') }, { $id: 'A' }) const B = Type.Object({ type: Type.Literal('B'), value: Type.Number() }, { $id: 'B' }) const RA = Type.Union([A, B]) const RB = Type.Union([Type.Ref('A'), Type.Ref('B')]) // variant 0 Assert.IsEqual(Value.Cast(RA, [A, B], { type: 'B' }), { type: 'B', value: 0 }) Assert.IsEqual(Value.Cast(RB, [A, B], { type: 'B' }), { type: 'B', value: 0 }) // variant 1 Assert.IsEqual(Value.Cast(RA, [A, B], { type: 'A' }), { type: 'A' }) Assert.IsEqual(Value.Cast(RB, [A, B], { type: 'A' }), { type: 'A' }) }) // ------------------------------------------------------------------------ // ref: https://github.com/sinclairzx81/typebox/issues/1268 // ------------------------------------------------------------------------ it('should correctly score nested union types #1', () => { const A = Type.Union([ Type.Union([ Type.Object({ type: Type.Literal('a'), name: Type.String(), in: Type.String(), }), Type.Object({ type: Type.Literal('b'), description: Type.Optional(Type.String()), nested: Type.Object({ a: Type.String(), b: Type.Optional(Type.String()), }), }), ]), Type.Object({ $ref: Type.String(), description: Type.Optional(Type.String()), }), ]) Assert.IsEqual( Value.Cast(A, { type: 'b', description: 'Hello World', nested: { b: 'hello', }, }), { type: 'b', description: 'Hello World', nested: { a: '', b: 'hello' }, }, ) }) it('should correctly score nested union types #2', () => { const A = Type.Union([ Type.Union([ Type.Object({ prop1: Type.String(), prop2: Type.String(), prop3: Type.String(), }), Type.Object({ prop1: Type.String(), prop4: Type.String(), prop5: Type.String(), }), ]), Type.Union([ Type.Object({ prop6: Type.String(), prop7: Type.String(), prop8: Type.String(), }), Type.Object({ prop1: Type.String(), prop9: Type.String(), prop10: Type.String(), }), ]), ]) // Picks the first union variant when the score is equal Assert.IsEqual( Value.Cast(A, { prop1: '', }), { prop1: '', prop2: '', prop3: '', }, ) Assert.IsEqual( Value.Cast(A, { prop1: '', prop4: '', }), { prop1: '', prop4: '', prop5: '', }, ) Assert.IsEqual( Value.Cast(A, { prop6: '', }), { prop6: '', prop7: '', prop8: '', }, ) }) it('should correctly score nested union types #3', () => { const A = Type.Union([ Type.Object({ prop1: Type.String(), prop2: Type.String(), prop3: Type.String(), }), Type.Object({ prop4: Type.String(), prop5: Type.String(), prop6: Type.String(), }), Type.Union([ Type.Object({ prop4: Type.String(), prop5: Type.String(), prop6: Type.String(), }), Type.Object({ prop1: Type.String(), prop2: Type.String(), prop7: Type.String(), prop8: Type.String(), }), ]), ]) Assert.IsEqual( Value.Cast(A, { prop1: '', prop2: '', prop7: '', }), { prop1: '', prop2: '', prop7: '', prop8: '', }, ) }) it('should correctly score nested union types #4', () => { const A = Type.Union([ Type.Object({ prop1: Type.String(), prop2: Type.String(), prop3: Type.String(), }), Type.Union([ Type.Object({ prop4: Type.String(), prop5: Type.String(), prop6: Type.String(), }), Type.Union([ Type.Object({ prop1: Type.String(), prop2: Type.String(), prop7: Type.String(), prop8: Type.String(), }), Type.Union([ Type.Object({ prop1: Type.String(), prop2: Type.String(), prop9: Type.String(), prop10: Type.String(), }), Type.Object({ prop1: Type.String(), prop2: Type.String(), prop11: Type.String(), prop12: Type.String(), }), ]), ]), ]), ]) Assert.IsEqual( Value.Cast(A, { prop1: '', prop2: '', prop9: '', }), { prop1: '', prop2: '', prop9: '', prop10: '', }, ) }) // ------------------------------------------------------------------------ // ref: https://github.com/sinclairzx81/typebox/issues/1292 // ------------------------------------------------------------------------ it('should correctly score object unions with shared properties #1', () => { const schema = Type.Union([ Type.Object({ summary: Type.Optional(Type.String()), description: Type.Optional(Type.String()), parameters: Type.Optional(Type.Array(Type.Any())), responses: Type.Optional(Type.Record(Type.String(), Type.Any())), requestBody: Type.Optional(Type.Any()), }), Type.Object({ $ref: Type.String(), summary: Type.Optional(Type.String()), }), ]) Assert.IsEqual( Value.Cast(schema, { summary: 'Test Summary', parameters: {}, }), { summary: 'Test Summary', parameters: [], }, ) }) it('should correctly score object unions with shared properties #2', () => { const A = Type.Union([ Type.Object({ prop1: Type.String(), prop2: Type.String(), prop3: Type.String(), }), Type.Object({ prop1: Type.String(), prop2: Type.String(), prop4: Type.String(), prop5: Type.String(), prop6: Type.String(), prop7: Type.String(), prop8: Type.String(), prop9: Type.String(), prop10: Type.String(), }), ]) Assert.IsEqual( Value.Cast(A, { prop1: '', prop2: '', prop7: '', }), { prop1: '', prop2: '', prop4: '', prop5: '', prop6: '', prop7: '', prop8: '', prop9: '', prop10: '', }, ) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/unknown.ts000066400000000000000000000027741505437577000250510ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Unknown', () => { const T = Type.Unknown() it('Should upcast from string', () => { const value = 'hello' const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should upcast from number', () => { const value = 1 const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should upcast from boolean', () => { const value = false const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, value) }) it('Should upcast from date', () => { const value = new Date(100) const result: any = Value.Cast(T, value) Assert.IsEqual(result.getTime(), 100) }) it('Should preserve', () => { const value = { a: 1, b: 2 } const result = Value.Cast(T, value) Assert.IsEqual(result, { a: 1, b: 2 }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/cast/void.ts000066400000000000000000000027241505437577000243060ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/cast/Void', () => { const T = Type.Void() const E = undefined it('Should upcast from string', () => { const value = 'world' const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from number', () => { const value = 1 const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from boolean', () => { const value = true const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from object', () => { const value = {} const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from array', () => { const value = [1] const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from undefined', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from null', () => { const value = null const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should upcast from date', () => { const value = new Date(100) const result = Value.Cast(T, value) Assert.IsEqual(result, E) }) it('Should preserve', () => { const value = undefined const result = Value.Cast(T, value) Assert.IsEqual(result, undefined) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/000077500000000000000000000000001505437577000231135ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/value/check/any.ts000066400000000000000000000024341505437577000242550ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Any', () => { const T = Type.Any() it('Should pass string', () => { const value = 'hello' const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass number', () => { const value = 1 const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass boolean', () => { const value = true const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass null', () => { const value = null const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass undefined', () => { const value = undefined const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass object', () => { const value = { a: 1 } const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass array', () => { const value = [1, 2] const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass Date', () => { const value = new Date() const result = Value.Check(T, value) Assert.IsEqual(result, true) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/argument.ts000066400000000000000000000024471505437577000253140ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Argument', () => { const T = Type.Argument(0) it('Should pass string', () => { const value = 'hello' const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass number', () => { const value = 1 const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass boolean', () => { const value = true const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass null', () => { const value = null const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass undefined', () => { const value = undefined const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass object', () => { const value = { a: 1 } const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass array', () => { const value = [1, 2] const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass Date', () => { const value = new Date() const result = Value.Check(T, value) Assert.IsEqual(result, true) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/array.ts000066400000000000000000000136441505437577000246110ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Array', () => { it('Should pass number array', () => { const T = Type.Array(Type.Number()) const value = [1, 2, 3] const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should fail number array', () => { const T = Type.Array(Type.Number()) const value = ['a', 'b', 'c'] const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should pass object array', () => { const T = Type.Array(Type.Object({ x: Type.Number() })) const value = [{ x: 1 }, { x: 1 }, { x: 1 }] const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should fail object array', () => { const T = Type.Array(Type.Object({ x: Type.Number() })) const value = [{ x: 1 }, { x: 1 }, 1] const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail Date', () => { const value = new Date() const result = Value.Check(Type.Array(Type.Any()), value) Assert.IsEqual(result, false) }) it('Should validate array with unique primitive items', () => { const T = Type.Array(Type.Number(), { uniqueItems: true }) const result = Value.Check(T, [0, 1, 2]) Assert.IsEqual(result, true) }) it('Should not validate array with non-unique primitive items', () => { const T = Type.Array(Type.Number(), { uniqueItems: true }) const result = Value.Check(T, [0, 0, 2]) Assert.IsEqual(result, false) }) it('Should validate array with unique object items', () => { const T = Type.Array(Type.Object({ x: Type.Number(), y: Type.Number() }), { uniqueItems: true }) const result = Value.Check(T, [ { x: 1, y: 1 }, { x: 2, y: 2 }, { x: 3, y: 3 }, ]) Assert.IsEqual(result, true) }) it('Should not validate array with non-unique object items', () => { const T = Type.Array(Type.Object({ x: Type.Number(), y: Type.Number() }), { uniqueItems: true }) const result = Value.Check(T, [ { x: 1, y: 1 }, { x: 1, y: 1 }, { x: 3, y: 3 }, ]) Assert.IsEqual(result, false) }) // --------------------------------------------------------- // Contains // --------------------------------------------------------- it('Should validate for contains', () => { const T = Type.Array(Type.Number(), { contains: Type.Literal(1) }) Assert.IsTrue(Value.Check(T, [1])) Assert.IsTrue(Value.Check(T, [1, 2])) Assert.IsFalse(Value.Check(T, [])) Assert.IsFalse(Value.Check(T, [2])) }) it('Should validate for minContains', () => { const T = Type.Array(Type.Number(), { contains: Type.Literal(1), minContains: 3 }) Assert.IsTrue(Value.Check(T, [1, 1, 1, 2])) Assert.IsTrue(Value.Check(T, [2, 1, 1, 1, 2])) Assert.IsTrue(Value.Check(T, [1, 1, 1])) Assert.IsFalse(Value.Check(T, [])) Assert.IsFalse(Value.Check(T, [1, 1])) Assert.IsFalse(Value.Check(T, [2])) }) it('Should validate for maxContains', () => { const T = Type.Array(Type.Number(), { contains: Type.Literal(1), maxContains: 3 }) Assert.IsTrue(Value.Check(T, [1, 1, 1])) Assert.IsTrue(Value.Check(T, [1, 1])) Assert.IsTrue(Value.Check(T, [2, 2, 2, 2, 1, 1, 1])) Assert.IsFalse(Value.Check(T, [1, 1, 1, 1])) }) it('Should validate for minContains and maxContains', () => { const T = Type.Array(Type.Number(), { contains: Type.Literal(1), minContains: 3, maxContains: 5 }) Assert.IsFalse(Value.Check(T, [1, 1])) Assert.IsTrue(Value.Check(T, [1, 1, 1])) Assert.IsTrue(Value.Check(T, [1, 1, 1, 1])) Assert.IsTrue(Value.Check(T, [1, 1, 1, 1, 1])) Assert.IsFalse(Value.Check(T, [1, 1, 1, 1, 1, 1])) }) it('Should not validate minContains and maxContains when contains is unspecified', () => { const T = Type.Array(Type.Number(), { minContains: 3, maxContains: 5 }) Assert.IsFalse(Value.Check(T, [1, 1])) Assert.IsFalse(Value.Check(T, [1, 1, 1])) Assert.IsFalse(Value.Check(T, [1, 1, 1, 1])) Assert.IsFalse(Value.Check(T, [1, 1, 1, 1, 1])) Assert.IsFalse(Value.Check(T, [1, 1, 1, 1, 1, 1])) }) it('Should produce illogical schema when contains is not sub type of items', () => { const T = Type.Array(Type.Number(), { contains: Type.String(), minContains: 3, maxContains: 5 }) Assert.IsFalse(Value.Check(T, [1, 1])) Assert.IsFalse(Value.Check(T, [1, 1, 1])) Assert.IsFalse(Value.Check(T, [1, 1, 1, 1])) Assert.IsFalse(Value.Check(T, [1, 1, 1, 1, 1])) Assert.IsFalse(Value.Check(T, [1, 1, 1, 1, 1, 1])) }) // ---------------------------------------------------------------- // Issue: https://github.com/sinclairzx81/typebox/discussions/607 // ---------------------------------------------------------------- it('Should correctly handle undefined array properties', () => { const Answer = Type.Object({ text: Type.String(), isCorrect: Type.Boolean(), }) const Question = Type.Object({ text: Type.String(), options: Type.Array(Answer, { minContains: 1, maxContains: 1, contains: Type.Object({ text: Type.String(), isCorrect: Type.Literal(true), }), }), }) Assert.IsFalse(Value.Check(Question, { text: 'A' })) Assert.IsFalse(Value.Check(Question, { text: 'A', options: [] })) Assert.IsTrue(Value.Check(Question, { text: 'A', options: [{ text: 'A', isCorrect: true }] })) Assert.IsTrue( Value.Check(Question, { text: 'A', options: [ { text: 'A', isCorrect: true }, { text: 'B', isCorrect: false }, ], }), ) Assert.IsFalse(Value.Check(Question, { text: 'A', options: [{ text: 'A', isCorrect: false }] })) Assert.IsFalse( Value.Check(Question, { text: 'A', options: [ { text: 'A', isCorrect: true }, { text: 'B', isCorrect: true }, ], }), ) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/async-iterator.ts000066400000000000000000000013611505437577000264300ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/AsyncIterator', () => { it('Should pass async iterator 1', () => { async function* f() {} const T = Type.AsyncIterator(Type.Any()) const result = Value.Check(T, f()) Assert.IsEqual(result, true) }) it('Should pass async iterator 2', () => { const T = Type.AsyncIterator(Type.Any()) const result = Value.Check(T, { [Symbol.asyncIterator]: () => {}, }) Assert.IsEqual(result, true) }) it('Should pass async iterator', () => { const T = Type.AsyncIterator(Type.Any()) const result = Value.Check(T, {}) Assert.IsEqual(result, false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/bigint.ts000066400000000000000000000022561505437577000247440ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/BigInt', () => { const T = Type.BigInt() it('Should not validate NaN', () => { const T = Type.BigInt() const result = Value.Check(T, NaN) Assert.IsEqual(result, false) }) it('Should not validate +Infinity', () => { const T = Type.BigInt() const result = Value.Check(T, Infinity) Assert.IsEqual(result, false) }) it('Should not validate -Infinity', () => { const T = Type.BigInt() const result = Value.Check(T, -Infinity) Assert.IsEqual(result, false) }) it('Should fail integer', () => { const value = 1 const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail integer', () => { const value = 3.14 const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail Date', () => { const value = new Date() const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should pass bigint', () => { const result = Value.Check(T, BigInt(0)) Assert.IsEqual(result, true) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/boolean.ts000066400000000000000000000024531505437577000251060ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Boolean', () => { const T = Type.Boolean() it('Should fail string', () => { const value = 'hello' const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail number', () => { const value = 1 const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should pass boolean', () => { const value = true const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should fail null', () => { const value = null const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail undefined', () => { const value = undefined const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail object', () => { const value = { a: 1 } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail array', () => { const value = [1, 2] const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail Date', () => { const value = new Date() const result = Value.Check(T, value) Assert.IsEqual(result, false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/composite.ts000066400000000000000000000033551505437577000254730ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Composite', () => { const A = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }) const B = Type.Object({ a: Type.String(), b: Type.String(), c: Type.String(), }) const T = Type.Composite([A, B]) it('Should pass composite', () => { const value = { x: 1, y: 1, z: 1, a: '1', b: '1', c: '1', } const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should fail intersect with invalid property', () => { const value = { x: true, y: 1, z: 1, a: '1', b: '1', c: '1', } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail intersect with missing property', () => { const value = { y: 1, z: 1, a: '1', b: '1', c: '1', } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail intersect with primitive value', () => { const value = 1 const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should pass intersect with optional properties', () => { const A = Type.Object({ x: Type.Optional(Type.Number()), y: Type.Optional(Type.Number()), z: Type.Optional(Type.Number()), }) const B = Type.Object({ a: Type.String(), b: Type.String(), c: Type.String(), }) const T = Type.Composite([A, B]) const value = { a: '1', b: '1', c: '1', } const result = Value.Check(T, value) Assert.IsEqual(result, true) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/const.ts000066400000000000000000000021601505437577000246100ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Const', () => { it('Should validate 1', () => { const T = Type.Const(1) Assert.IsTrue(Value.Check(T, 1)) }) it('Should validate 2', () => { const T = Type.Const('hello') Assert.IsTrue(Value.Check(T, 'hello')) }) it('Should validate 3', () => { const T = Type.Const(true) Assert.IsTrue(Value.Check(T, true)) }) it('Should validate 4', () => { const T = Type.Const({ x: 1, y: 2 }) Assert.IsTrue(Value.Check(T, { x: 1, y: 2 })) }) it('Should validate 5', () => { const T = Type.Const([1, 2, 3]) Assert.IsTrue(Value.Check(T, [1, 2, 3])) }) it('Should validate 6', () => { const T = Type.Const([1, true, 'hello']) Assert.IsTrue(Value.Check(T, [1, true, 'hello'])) }) it('Should validate 7', () => { const T = Type.Const({ x: [1, 2, 3, 4], y: { x: 1, y: 2, z: 3 }, }) Assert.IsTrue( Value.Check(T, { x: [1, 2, 3, 4], y: { x: 1, y: 2, z: 3 }, }), ) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/constructor.ts000066400000000000000000000036441505437577000260570ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Constructor', () => { it('Should validate constructor 1', () => { const T = Type.Constructor([], Type.Object({})) Assert.IsTrue(Value.Check(T, class {})) }) it('Should validate constructor 2', () => { const T = Type.Constructor([Type.Number()], Type.Object({})) // note: constructor arguments are non-checkable Assert.IsTrue(Value.Check(T, class {})) }) it('Should validate constructor 3', () => { const T = Type.Constructor( [Type.Number()], Type.Object({ method: Type.Function([], Type.Void()), }), ) Assert.IsTrue( Value.Check( T, class { method() {} }, ), ) }) it('Should validate constructor 4', () => { const T = Type.Constructor( [Type.Number()], Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }), ) Assert.IsTrue( Value.Check( T, class { get x() { return 1 } get y() { return 1 } get z() { return 1 } }, ), ) }) it('Should not validate constructor 1', () => { const T = Type.Constructor([Type.Number()], Type.Object({})) Assert.IsFalse(Value.Check(T, 1)) }) it('Should not validate constructor 2', () => { const T = Type.Constructor( [Type.Number()], Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }), ) Assert.IsFalse( Value.Check( T, class { get x() { return null } get y() { return null } get z() { return null } }, ), ) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/date.ts000066400000000000000000000051731505437577000244060ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Date', () => { const T = Type.Date() it('Should fail string', () => { const value = 'hello' const result = Value.Check(T, value) Assert.IsFalse(result) }) it('Should fail number', () => { const value = 1 const result = Value.Check(T, value) Assert.IsFalse(result) }) it('Should fail boolean', () => { const value = true const result = Value.Check(T, value) Assert.IsFalse(result) }) it('Should fail null', () => { const value = null const result = Value.Check(T, value) Assert.IsFalse(result) }) it('Should fail undefined', () => { const value = undefined const result = Value.Check(T, value) Assert.IsFalse(result) }) it('Should fail object', () => { const value = { a: 1 } const result = Value.Check(T, value) Assert.IsFalse(result) }) it('Should fail array', () => { const value = [1, 2] const result = Value.Check(T, value) Assert.IsFalse(result) }) it('Should pass Date', () => { const value = new Date() const result = Value.Check(T, value) Assert.IsTrue(result) }) it('Should not validate Date if is invalid', () => { const value = new Date('not-a-valid-date') const result = Value.Check(T, value) Assert.IsFalse(result) }) it('Should validate Date minimumTimestamp', () => { const T = Type.Date({ minimumTimestamp: 10 }) const R1 = Value.Check(T, new Date(9)) const R2 = Value.Check(T, new Date(10)) Assert.IsFalse(R1) Assert.IsTrue(R2) }) it('Should validate Date maximumTimestamp', () => { const T = Type.Date({ maximumTimestamp: 10 }) const R1 = Value.Check(T, new Date(11)) const R2 = Value.Check(T, new Date(10)) Assert.IsFalse(R1) Assert.IsTrue(R2) }) it('Should validate Date exclusiveMinimumTimestamp', () => { const T = Type.Date({ exclusiveMinimumTimestamp: 10 }) const R1 = Value.Check(T, new Date(10)) const R2 = Value.Check(T, new Date(11)) Assert.IsFalse(R1) Assert.IsTrue(R2) }) it('Should validate Date exclusiveMaximumTimestamp', () => { const T = Type.Date({ exclusiveMaximumTimestamp: 10 }) const R1 = Value.Check(T, new Date(10)) const R2 = Value.Check(T, new Date(9)) Assert.IsFalse(R1) Assert.IsTrue(R2) }) it('Should validate Date multipleOfTimestamp', () => { const T = Type.Date({ multipleOfTimestamp: 2 }) const R1 = Value.Check(T, new Date(1)) const R2 = Value.Check(T, new Date(2)) Assert.IsFalse(R1) Assert.IsTrue(R2) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/enum.ts000066400000000000000000000014661505437577000244360ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Enum', () => { enum Foo { A = 1, B = 2, } const T = Type.Enum(Foo) it('Should pass enum option A', () => { const value = Foo.A const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass enum option B', () => { const value = Foo.A const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should fail unknown value', () => { const value = 'unknown' const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail Date', () => { const value = new Date() const result = Value.Check(T, value) Assert.IsEqual(result, false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/function.ts000066400000000000000000000017501505437577000253130ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Function', () => { it('Should validate function 1', () => { const T = Type.Function([Type.Number()], Type.Number()) Assert.IsTrue(Value.Check(T, function () {})) }) it('Should validate function 2', () => { const T = Type.Function([Type.Number()], Type.Number()) // note: validation only checks typeof 'function' Assert.IsTrue(Value.Check(T, function (a: string, b: string, c: string, d: string) {})) }) it('Should validate function 3', () => { const T = Type.Function([Type.Number()], Type.Number()) // note: validation only checks typeof 'function' Assert.IsTrue( Value.Check(T, function () { return 'not-a-number' }), ) }) it('Should not validate function', () => { const T = Type.Function([Type.Number()], Type.Number()) Assert.IsFalse(Value.Check(T, 1)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/index.ts000066400000000000000000000012621505437577000245730ustar00rootroot00000000000000import './any' import './argument' import './array' import './async-iterator' import './bigint' import './boolean' import './composite' import './const' import './constructor' import './date' import './enum' import './function' import './integer' import './intersect' import './iterator' import './keyof' import './kind' import './literal' import './module' import './never' import './not' import './null' import './number' import './object' import './recursive' import './ref' import './record' import './regexp' import './string' import './symbol' import './template-literal' import './tuple' import './uint8array' import './undefined' import './union' import './unknown' import './void' sinclairzx81-typebox-e0ec98c/test/runtime/value/check/integer.ts000066400000000000000000000020741505437577000251230ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Integer', () => { const T = Type.Integer() it('Should not validate NaN', () => { const T = Type.Integer() const result = Value.Check(T, NaN) Assert.IsEqual(result, false) }) it('Should not validate +Infinity', () => { const T = Type.Integer() const result = Value.Check(T, Infinity) Assert.IsEqual(result, false) }) it('Should not validate -Infinity', () => { const T = Type.Integer() const result = Value.Check(T, -Infinity) Assert.IsEqual(result, false) }) it('Should pass integer', () => { const value = 1 const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should fail integer', () => { const value = 3.14 const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail Date', () => { const value = new Date() const result = Value.Check(T, value) Assert.IsEqual(result, false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/intersect.ts000066400000000000000000000164231505437577000254710ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Intersect', () => { it('Should intersect number and number', () => { const A = Type.Number() const B = Type.Number() const T = Type.Intersect([A, B], {}) Assert.IsEqual(Value.Check(T, 1), true) }) it('Should not intersect string and number', () => { const A = Type.String() const B = Type.Number() const T = Type.Intersect([A, B], {}) Assert.IsEqual(Value.Check(T, 1), false) Assert.IsEqual(Value.Check(T, '1'), false) }) it('Should intersect two objects', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const T = Type.Intersect([A, B], {}) Assert.IsEqual(Value.Check(T, { x: 1, y: 1 }), true) }) it('Should not intersect two objects with internal additionalProperties false', () => { const A = Type.Object({ x: Type.Number() }, { additionalProperties: false }) const B = Type.Object({ y: Type.Number() }, { additionalProperties: false }) const T = Type.Intersect([A, B], {}) Assert.IsEqual(Value.Check(T, { x: 1, y: 1 }), false) }) it('Should intersect two objects and mandate required properties', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const T = Type.Intersect([A, B], {}) Assert.IsEqual(Value.Check(T, { x: 1, y: 1 }), true) Assert.IsEqual(Value.Check(T, { x: 1 }), false) Assert.IsEqual(Value.Check(T, { x: 1 }), false) }) it('Should intersect two objects with unevaluated properties', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const T = Type.Intersect([A, B], {}) Assert.IsEqual(Value.Check(T, { x: 1, y: 1, z: 1 }), true) }) it('Should intersect two objects and restrict unevaluated properties', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const T = Type.Intersect([A, B], { unevaluatedProperties: false }) Assert.IsEqual(Value.Check(T, { x: 1, y: 1, z: 1 }), false) }) it('Should intersect two objects and allow unevaluated properties of number', () => { const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.Number() }) const T = Type.Intersect([A, B], { unevaluatedProperties: Type.Number() }) Assert.IsEqual(Value.Check(T, { x: 1, y: 2, z: 3 }), true) Assert.IsEqual(Value.Check(T, { x: 1, y: 2, z: '1' }), false) }) it('Should intersect two union objects with overlapping properties of the same type', () => { const A = Type.Union([Type.Object({ x: Type.Number() })]) const B = Type.Union([Type.Object({ x: Type.Number() })]) const T = Type.Intersect([A, B]) Assert.IsEqual(Value.Check(T, { x: 1 }), true) Assert.IsEqual(Value.Check(T, { x: '1' }), false) }) it('Should not intersect two union objects with overlapping properties of varying types', () => { const A = Type.Union([Type.Object({ x: Type.Number() })]) const B = Type.Union([Type.Object({ x: Type.String() })]) const T = Type.Intersect([A, B]) Assert.IsEqual(Value.Check(T, { x: 1 }), false) Assert.IsEqual(Value.Check(T, { x: '1' }), false) }) it('Should intersect two union objects with non-overlapping properties', () => { const A = Type.Union([Type.Object({ x: Type.Number() })]) const B = Type.Union([Type.Object({ y: Type.Number() })]) const T = Type.Intersect([A, B]) Assert.IsEqual(Value.Check(T, { x: 1, y: 1 }), true) }) it('Should not intersect two union objects with non-overlapping properties for additionalProperties false', () => { const A = Type.Union([Type.Object({ x: Type.Number() }, { additionalProperties: false })]) const B = Type.Union([Type.Object({ y: Type.Number() }, { additionalProperties: false })]) const T = Type.Intersect([A, B]) Assert.IsEqual(Value.Check(T, { x: 1, y: 1 }), false) }) it('unevaluatedProperties with Record 1', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: false, }, ) Assert.IsEqual(Value.Check(T, { x: 1, y: 2 }), true) }) it('unevaluatedProperties with Record 2', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: false, }, ) Assert.IsEqual(Value.Check(T, { x: 1, y: 2, 0: 'hello' }), true) }) it('unevaluatedProperties with Record 3', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: false, }, ) Assert.IsEqual(Value.Check(T, { x: 1, y: 2, 0: 1 }), false) }) it('unevaluatedProperties with Record 4', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: Type.Boolean(), }, ) Assert.IsEqual(Value.Check(T, { x: 1, y: 2 }), true) }) it('unevaluatedProperties with Record 5', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: Type.Boolean(), }, ) Assert.IsEqual(Value.Check(T, { x: 1, y: 2, z: true }), true) }) it('unevaluatedProperties with Record 6', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: Type.Boolean(), }, ) Assert.IsEqual(Value.Check(T, { x: 1, y: 2, z: 1 }), false) }) it('unevaluatedProperties with Record 7', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: Type.Boolean(), }, ) Assert.IsEqual(Value.Check(T, { x: 1, y: 2, 0: '' }), true) }) it('unevaluatedProperties with Record 8', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: Type.Boolean(), }, ) Assert.IsEqual(Value.Check(T, { x: 1, y: 2, 0: '', z: true }), true) }) it('unevaluatedProperties with Record 9', () => { const T = Type.Intersect( [ Type.Record(Type.Number(), Type.String()), Type.Object({ x: Type.Number(), y: Type.Number(), }), ], { unevaluatedProperties: Type.Boolean(), }, ) Assert.IsEqual(Value.Check(T, { x: 1, y: 2, 0: '', z: 1 }), false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/iterator.ts000066400000000000000000000013001505437577000253060ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Iterator', () => { it('Should pass iterator 1', () => { function* f() {} const T = Type.Iterator(Type.Any()) const result = Value.Check(T, f()) Assert.IsEqual(result, true) }) it('Should pass iterator 2', () => { const T = Type.Iterator(Type.Any()) const result = Value.Check(T, { [Symbol.iterator]: () => {}, }) Assert.IsEqual(result, true) }) it('Should pass iterator', () => { const T = Type.Iterator(Type.Any()) const result = Value.Check(T, {}) Assert.IsEqual(result, false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/keyof.ts000066400000000000000000000015541505437577000246050ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/KeyOf', () => { const T = Type.KeyOf( Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }), ) it('Should pass keyof', () => { const value = 'x' const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should fail keyof', () => { const value = 'w' const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail keyof with undefined', () => { const value = undefined const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail keyof with null', () => { const value = null const result = Value.Check(T, value) Assert.IsEqual(result, false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/kind.ts000066400000000000000000000100211505437577000244020ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { TypeRegistry, Type, Kind, TSchema } from '@sinclair/typebox' import { Assert } from '../../assert' describe('value/check/Kind', () => { // ------------------------------------------------------------ // Fixtures // ------------------------------------------------------------ beforeEach(() => TypeRegistry.Set('PI', (_, value) => value === Math.PI)) afterEach(() => TypeRegistry.Delete('PI')) // ------------------------------------------------------------ // Tests // ------------------------------------------------------------ it('Should validate', () => { const T = Type.Unsafe({ [Kind]: 'PI' }) Assert.IsTrue(Value.Check(T, Math.PI)) }) it('Should not validate', () => { const T = Type.Unsafe({ [Kind]: 'PI' }) Assert.IsFalse(Value.Check(T, Math.PI * 2)) }) it('Should validate in object', () => { const T = Type.Object({ x: Type.Unsafe({ [Kind]: 'PI' }), }) Assert.IsTrue(Value.Check(T, { x: Math.PI })) }) it('Should not validate in object', () => { const T = Type.Object({ x: Type.Unsafe({ [Kind]: 'PI' }), }) Assert.IsFalse(Value.Check(T, { x: Math.PI * 2 })) }) it('Should validate in array', () => { const T = Type.Array(Type.Unsafe({ [Kind]: 'PI' })) Assert.IsTrue(Value.Check(T, [Math.PI])) }) it('Should not validate in array', () => { const T = Type.Array(Type.Unsafe({ [Kind]: 'PI' })) Assert.IsFalse(Value.Check(T, [Math.PI * 2])) }) it('Should validate in tuple', () => { const T = Type.Tuple([Type.Unsafe({ [Kind]: 'PI' })]) Assert.IsTrue(Value.Check(T, [Math.PI])) }) it('Should not validate in tuple', () => { const T = Type.Tuple([Type.Unsafe({ [Kind]: 'PI' })]) Assert.IsFalse(Value.Check(T, [Math.PI * 2])) }) // ------------------------------------------------------------ // Instances // ------------------------------------------------------------ it('Should receive kind instance on registry callback', () => { const stack: string[] = [] TypeRegistry.Set('Kind', (schema: unknown) => { // prettier-ignore return (typeof schema === 'object' && schema !== null && Kind in schema && schema[Kind] === 'Kind' && '$id' in schema && typeof schema.$id === 'string') ? (() => { stack.push(schema.$id); return true })() : false }) const A = { [Kind]: 'Kind', $id: 'A' } as TSchema const B = { [Kind]: 'Kind', $id: 'B' } as TSchema const T = Type.Object({ a: A, b: B }) const R = Value.Check(T, { a: null, b: null }) Assert.IsTrue(R) Assert.IsEqual(stack[0], 'A') Assert.IsEqual(stack[1], 'B') TypeRegistry.Delete('Kind') }) it('Should retain kind instances on subsequent check', () => { let stack: string[] = [] TypeRegistry.Set('Kind', (schema: unknown) => { // prettier-ignore return (typeof schema === 'object' && schema !== null && Kind in schema && schema[Kind] === 'Kind' && '$id' in schema && typeof schema.$id === 'string') ? (() => { stack.push(schema.$id); return true })() : false }) const A = { [Kind]: 'Kind', $id: 'A' } as TSchema const B = { [Kind]: 'Kind', $id: 'B' } as TSchema const C = { [Kind]: 'Kind', $id: 'C' } as TSchema const D = { [Kind]: 'Kind', $id: 'D' } as TSchema const T1 = Type.Object({ a: A, b: B }) const T2 = Type.Object({ a: C, b: D }) // run T1 check const R2 = Value.Check(T1, { a: null, b: null }) Assert.IsTrue(R2) Assert.IsEqual(stack.length, 2) Assert.IsEqual(stack[0], 'A') Assert.IsEqual(stack[1], 'B') stack = [] // run T2 check const R3 = Value.Check(T2, { a: null, b: null }) Assert.IsTrue(R3) Assert.IsEqual(stack.length, 2) Assert.IsEqual(stack[0], 'C') Assert.IsEqual(stack[1], 'D') stack = [] // run T1 check const R4 = Value.Check(T1, { a: null, b: null }) Assert.IsTrue(R4) Assert.IsEqual(stack.length, 2) Assert.IsEqual(stack[0], 'A') Assert.IsEqual(stack[1], 'B') stack = [] TypeRegistry.Delete('Kind') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/literal.ts000066400000000000000000000014341505437577000251210ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Literal', () => { const T = Type.Literal('hello') it('Should pass literal', () => { const value = 'hello' const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should fail literal', () => { const value = 1 const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail literal with undefined', () => { const value = undefined const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail literal with null', () => { const value = null const result = Value.Check(T, value) Assert.IsEqual(result, false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/module.ts000066400000000000000000000124731505437577000247570ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert' describe('value/check/Module', () => { it('Should validate string', () => { const Module = Type.Module({ A: Type.String(), }) const T = Module.Import('A') Assert.IsTrue(Value.Check(T, 'hello')) Assert.IsFalse(Value.Check(T, true)) }) it('Should validate referenced string', () => { const Module = Type.Module({ A: Type.String(), B: Type.Ref('A'), }) const T = Module.Import('B') Assert.IsTrue(Value.Check(T, 'hello')) Assert.IsFalse(Value.Check(T, true)) }) it('Should validate self referential', () => { const Module = Type.Module({ A: Type.Object({ nodes: Type.Array(Type.Ref('A')), }), }) const T = Module.Import('A') Assert.IsTrue(Value.Check(T, { nodes: [{ nodes: [{ nodes: [] }, { nodes: [] }] }] })) Assert.IsFalse(Value.Check(T, { nodes: [{ nodes: [{ nodes: [] }, { nodes: false }] }] })) Assert.IsFalse(Value.Check(T, true)) }) it('Should validate mutual recursive', () => { const Module = Type.Module({ A: Type.Object({ b: Type.Ref('B'), }), B: Type.Object({ a: Type.Union([Type.Ref('A'), Type.Null()]), }), }) const T = Module.Import('A') Assert.IsTrue(Value.Check(T, { b: { a: null } })) Assert.IsTrue(Value.Check(T, { b: { a: { b: { a: null } } } })) Assert.IsFalse(Value.Check(T, { b: { a: 1 } })) Assert.IsFalse(Value.Check(T, { b: { a: { b: { a: 1 } } } })) Assert.IsFalse(Value.Check(T, true)) }) it('Should validate mutual recursive (Array)', () => { const Module = Type.Module({ A: Type.Object({ b: Type.Ref('B'), }), B: Type.Object({ a: Type.Array(Type.Ref('A')), }), }) const T = Module.Import('A') Assert.IsTrue(Value.Check(T, { b: { a: [{ b: { a: [] } }] } })) Assert.IsFalse(Value.Check(T, { b: { a: [{ b: { a: [null] } }] } })) Assert.IsFalse(Value.Check(T, true)) }) it('Should validate deep referential', () => { const Module = Type.Module({ A: Type.Ref('B'), B: Type.Ref('C'), C: Type.Ref('D'), D: Type.Ref('E'), E: Type.Ref('F'), F: Type.Ref('G'), G: Type.Ref('H'), H: Type.Literal('hello'), }) const T = Module.Import('A') Assert.IsTrue(Value.Check(T, 'hello')) Assert.IsFalse(Value.Check(T, 'world')) }) // ---------------------------------------------------------------- // Modifiers // ---------------------------------------------------------------- it('Should validate objects with property modifiers 1', () => { const Module = Type.Module({ T: Type.Object({ x: Type.ReadonlyOptional(Type.Null()), y: Type.Readonly(Type.Null()), z: Type.Optional(Type.Null()), w: Type.Null(), }), }) const T = Module.Import('T') Assert.IsTrue(Value.Check(T, { x: null, y: null, w: null })) Assert.IsTrue(Value.Check(T, { y: null, w: null })) Assert.IsFalse(Value.Check(T, { x: 1, y: null, w: null })) }) it('Should validate objects with property modifiers 2', () => { const Module = Type.Module({ T: Type.Object({ x: Type.ReadonlyOptional(Type.Array(Type.Null())), y: Type.Readonly(Type.Array(Type.Null())), z: Type.Optional(Type.Array(Type.Null())), w: Type.Array(Type.Null()), }), }) const T = Module.Import('T') Assert.IsTrue(Value.Check(T, { x: [null], y: [null], w: [null] })) Assert.IsTrue(Value.Check(T, { y: [null], w: [null] })) Assert.IsFalse(Value.Check(T, { x: [1], y: [null], w: [null] })) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/1109 // ---------------------------------------------------------------- it('Should validate deep referential 1', () => { const Module = Type.Module({ A: Type.Union([Type.Literal('Foo'), Type.Literal('Bar')]), B: Type.Ref('A'), C: Type.Object({ ref: Type.Ref('B') }), D: Type.Union([Type.Ref('B'), Type.Ref('C')]), }) Assert.IsTrue(Value.Check(Module.Import('A') as never, 'Foo')) Assert.IsTrue(Value.Check(Module.Import('A') as never, 'Bar')) Assert.IsTrue(Value.Check(Module.Import('B') as never, 'Foo')) Assert.IsTrue(Value.Check(Module.Import('B') as never, 'Bar')) Assert.IsTrue(Value.Check(Module.Import('C') as never, { ref: 'Foo' })) Assert.IsTrue(Value.Check(Module.Import('C') as never, { ref: 'Bar' })) Assert.IsTrue(Value.Check(Module.Import('D') as never, 'Foo')) Assert.IsTrue(Value.Check(Module.Import('D') as never, 'Bar')) Assert.IsTrue(Value.Check(Module.Import('D') as never, { ref: 'Foo' })) Assert.IsTrue(Value.Check(Module.Import('D') as never, { ref: 'Bar' })) }) it('Should validate deep referential 2', () => { const Module = Type.Module({ A: Type.Literal('Foo'), B: Type.Ref('A'), C: Type.Ref('B'), D: Type.Ref('C'), E: Type.Ref('D'), }) Assert.IsTrue(Value.Check(Module.Import('A'), 'Foo')) Assert.IsTrue(Value.Check(Module.Import('B'), 'Foo')) Assert.IsTrue(Value.Check(Module.Import('C'), 'Foo')) Assert.IsTrue(Value.Check(Module.Import('D'), 'Foo')) Assert.IsTrue(Value.Check(Module.Import('E'), 'Foo')) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/never.ts000066400000000000000000000022321505437577000246010ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Never', () => { const T = Type.Never() it('Should fail string', () => { const value = 'hello' const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail number', () => { const value = 1 const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail boolean', () => { const value = true const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail null', () => { const value = null const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail undefined', () => { const value = undefined const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail object', () => { const value = { a: 1 } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail array', () => { const value = [1, 2] const result = Value.Check(T, value) Assert.IsEqual(result, false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/not.ts000066400000000000000000000017631505437577000242720ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Not', () => { it('Should validate with not number', () => { const T = Type.Not(Type.Number()) Assert.IsEqual(Value.Check(T, 1), false) Assert.IsEqual(Value.Check(T, 'A'), true) }) it('Should validate with union left', () => { // prettier-ignore const T = Type.Not(Type.Union([ Type.Literal('A'), Type.Literal('B'), Type.Literal('C') ])) Assert.IsEqual(Value.Check(T, 'A'), false) Assert.IsEqual(Value.Check(T, 'B'), false) Assert.IsEqual(Value.Check(T, 'C'), false) Assert.IsEqual(Value.Check(T, 'D'), true) }) it('Should validate with union right', () => { // prettier-ignore const T = Type.Not(Type.Number()) Assert.IsEqual(Value.Check(T, 1), false) Assert.IsEqual(Value.Check(T, 'A'), true) Assert.IsEqual(Value.Check(T, true), true) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/null.ts000066400000000000000000000024451505437577000244420ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Null', () => { const T = Type.Null() it('Should fail string', () => { const value = 'hello' const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail number', () => { const value = 1 const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail boolean', () => { const value = true const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should pass null', () => { const value = null const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should fail undefined', () => { const value = undefined const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail object', () => { const value = { a: 1 } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail array', () => { const value = [1, 2] const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail Date', () => { const value = new Date() const result = Value.Check(T, value) Assert.IsEqual(result, false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/number.ts000066400000000000000000000035611505437577000247600ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Number', () => { const T = Type.Number() it('Should not validate NaN', () => { const T = Type.Number() const result = Value.Check(T, NaN) Assert.IsEqual(result, false) }) it('Should not validate +Infinity', () => { const T = Type.Number() const result = Value.Check(T, Infinity) Assert.IsEqual(result, false) }) it('Should not validate -Infinity', () => { const T = Type.Number() const result = Value.Check(T, -Infinity) Assert.IsEqual(result, false) }) it('Should fail string', () => { const value = 'hello' const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should pass number', () => { const value = 1 const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should fail boolean', () => { const value = true const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail null', () => { const value = null const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail undefined', () => { const value = undefined const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail object', () => { const value = { a: 1 } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail array', () => { const value = [1, 2] const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail Date', () => { const value = new Date() const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail NaN', () => { const result = Value.Check(Type.Number(), NaN) Assert.IsEqual(result, false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/object.ts000066400000000000000000000124541505437577000247370ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Object', () => { const T = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), a: Type.String(), b: Type.String(), c: Type.String(), }) it('Should pass object', () => { const value = { x: 1, y: 1, z: 1, a: '1', b: '1', c: '1', } const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should fail object with additional properties', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { additionalProperties: false }, ) const value = { x: 1, y: 1, z: 1, a: 1, } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail object with invalid property', () => { const value = { x: true, y: 1, z: 1, a: '1', b: '1', c: '1', } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail object with missing property', () => { const value = { y: 1, z: 1, a: '1', b: '1', c: '1', } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should pass object with optional properties', () => { const T = Type.Object({ x: Type.Optional(Type.Number()), y: Type.Optional(Type.Number()), z: Type.Optional(Type.Number()), a: Type.String(), b: Type.String(), c: Type.String(), }) const value = { a: '1', b: '1', c: '1', } const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should fail object with null', () => { const value = null const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail object with undefined', () => { const value = undefined const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should validate schema additional properties of string', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.String(), }, ) Assert.IsEqual( Value.Check(T, { x: 1, y: 2, z: 'hello', }), true, ) Assert.IsEqual( Value.Check(T, { x: 1, y: 2, z: 3, }), false, ) }) it('Should validate schema additional properties of array', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.Array(Type.Number()), }, ) Assert.IsEqual( Value.Check(T, { x: 1, y: 2, z: [0, 1, 2], }), true, ) Assert.IsEqual( Value.Check(T, { x: 1, y: 2, z: 3, }), false, ) }) it('Should validate schema additional properties of object', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.Object({ z: Type.Number(), }), }, ) Assert.IsEqual( Value.Check(T, { x: 1, y: 2, z: { z: 1 }, }), true, ) Assert.IsEqual( Value.Check(T, { x: 1, y: 2, z: 3, }), false, ) }) it('Should check for property key if property type is undefined', () => { const T = Type.Object({ x: Type.Undefined() }) Assert.IsEqual(Value.Check(T, { x: undefined }), true) Assert.IsEqual(Value.Check(T, {}), false) }) it('Should check for property key if property type extends undefined', () => { const T = Type.Object({ x: Type.Union([Type.Number(), Type.Undefined()]) }) Assert.IsEqual(Value.Check(T, { x: 1 }), true) Assert.IsEqual(Value.Check(T, { x: undefined }), true) Assert.IsEqual(Value.Check(T, {}), false) }) it('Should not check for property key if property type is undefined and optional', () => { const T = Type.Object({ x: Type.Optional(Type.Undefined()) }) Assert.IsEqual(Value.Check(T, { x: undefined }), true) Assert.IsEqual(Value.Check(T, {}), true) }) it('Should not check for property key if property type extends undefined and optional', () => { const T = Type.Object({ x: Type.Optional(Type.Union([Type.Number(), Type.Undefined()])) }) Assert.IsEqual(Value.Check(T, { x: 1 }), true) Assert.IsEqual(Value.Check(T, { x: undefined }), true) Assert.IsEqual(Value.Check(T, {}), true) }) it('Should check undefined for optional property of number', () => { const T = Type.Object({ x: Type.Optional(Type.Number()) }) Assert.IsEqual(Value.Check(T, { x: 1 }), true) Assert.IsEqual(Value.Check(T, { x: undefined }), true) // allowed by default Assert.IsEqual(Value.Check(T, {}), true) }) it('Should check undefined for optional property of undefined', () => { const T = Type.Object({ x: Type.Optional(Type.Undefined()) }) Assert.IsEqual(Value.Check(T, { x: 1 }), false) Assert.IsEqual(Value.Check(T, {}), true) Assert.IsEqual(Value.Check(T, { x: undefined }), true) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/record.ts000066400000000000000000000206731505437577000247510ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Record', () => { it('Should pass record', () => { const T = Type.Record( Type.String(), Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }), ) const value = { position: { x: 1, y: 2, z: 3, }, } const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should fail when below minProperties', () => { const T = Type.Record(Type.String(), Type.Number(), { minProperties: 4 }) Assert.IsEqual(Value.Check(T, { a: 1, b: 2, c: 3, d: 4 }), true) Assert.IsEqual(Value.Check(T, { a: 1, b: 2, c: 3 }), false) }) it('Should fail when above maxProperties', () => { const T = Type.Record(Type.String(), Type.Number(), { maxProperties: 4 }) Assert.IsEqual(Value.Check(T, { a: 1, b: 2, c: 3, d: 4 }), true) Assert.IsEqual(Value.Check(T, { a: 1, b: 2, c: 3, d: 4, e: 5 }), false) }) it('Should fail with illogical minProperties | maxProperties', () => { const T = Type.Record(Type.String(), Type.Number(), { minProperties: 5, maxProperties: 4 }) Assert.IsEqual(Value.Check(T, { a: 1, b: 2, c: 3 }), false) Assert.IsEqual(Value.Check(T, { a: 1, b: 2, c: 3, d: 4 }), false) Assert.IsEqual(Value.Check(T, { a: 1, b: 2, c: 3, d: 4, e: 5 }), false) }) it('Should fail record with Date', () => { const T = Type.Record(Type.String(), Type.String()) const result = Value.Check(T, new Date()) Assert.IsEqual(result, false) }) it('Should fail record with Uint8Array', () => { const T = Type.Record(Type.String(), Type.String()) const result = Value.Check(T, new Uint8Array()) Assert.IsEqual(result, false) }) it('Should fail record with missing property', () => { const T = Type.Record( Type.String(), Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }), ) const value = { position: { x: 1, y: 2, }, } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail record with invalid property', () => { const T = Type.Record( Type.String(), Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }), ) const value = { position: { x: 1, y: 2, z: '3', }, } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should pass record with optional property', () => { const T = Type.Record( Type.String(), Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Optional(Type.Number()), }), ) const value = { position: { x: 1, y: 2, }, } const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass record with optional property', () => { const T = Type.Record( Type.String(), Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Optional(Type.Number()), }), ) const value = { position: { x: 1, y: 2, }, } const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should validate when specifying regular expressions', () => { const K = Type.RegExp(/^op_.*$/) const T = Type.Record(K, Type.Number()) const R = Value.Check(T, { op_a: 1, op_b: 2, op_c: 3, }) Assert.IsTrue(R) }) it('Should not validate when specifying regular expressions and passing invalid property', () => { const K = Type.RegExp(/^op_.*$/) const T = Type.Record(K, Type.Number(), { additionalProperties: false }) const R = Value.Check(T, { op_a: 1, op_b: 2, aop_c: 3, }) Assert.IsFalse(R) }) it('Should validate with quoted string pattern', () => { const K = Type.String({ pattern: "'(a|b|c)" }) const T = Type.Record(K, Type.Number()) const R = Value.Check(T, { "'a": 1, "'b": 2, "'c": 3, }) Assert.IsTrue(R) }) it('Should validate with forward-slash pattern', () => { const K = Type.String({ pattern: '/(a|b|c)' }) const T = Type.Record(K, Type.Number()) const R = Value.Check(T, { '/a': 1, '/b': 2, '/c': 3, }) Assert.IsTrue(R) }) // ------------------------------------------------- // Number Key // ------------------------------------------------- it('Should pass record with number key', () => { const T = Type.Record(Type.Number(), Type.String()) const value = { 0: 'a', 1: 'a', 2: 'a', } const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should not pass record with invalid number key', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: false }) const value = { a: 'a', 1: 'a', 2: 'a', } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) // ------------------------------------------------- // Integer Key // ------------------------------------------------- it('Should pass record with integer key', () => { const T = Type.Record(Type.Integer(), Type.String()) const value = { 0: 'a', 1: 'a', 2: 'a', } const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should not pass record with invalid integer key', () => { const T = Type.Record(Type.Integer(), Type.String(), { additionalProperties: false }) const value = { a: 'a', 1: 'a', 2: 'a', } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) // ------------------------------------------------------------ // AdditionalProperties // ------------------------------------------------------------ it('AdditionalProperties 1', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: true }) const R = Value.Check(T, { 1: '', 2: '', x: 1, y: 2, z: 3 }) Assert.IsEqual(R, true) }) it('AdditionalProperties 2', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: false }) const R = Value.Check(T, { 1: '', 2: '', 3: '' }) Assert.IsEqual(R, true) }) it('AdditionalProperties 3', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: false }) const R = Value.Check(T, { 1: '', 2: '', x: '' }) Assert.IsEqual(R, false) }) it('AdditionalProperties 4', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: Type.Boolean() }) const R = Value.Check(T, { 1: '', 2: '', x: '' }) Assert.IsEqual(R, false) }) it('AdditionalProperties 5', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: Type.Boolean() }) const R = Value.Check(T, { 1: '', 2: '', x: true }) Assert.IsEqual(R, true) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/916 // ---------------------------------------------------------------- it('Should validate for string keys', () => { const T = Type.Record(Type.String(), Type.Null(), { additionalProperties: false, }) const R = Value.Check(T, { a: null, b: null, 0: null, 1: null, }) Assert.IsEqual(R, true) }) it('Should validate for number keys', () => { const T = Type.Record(Type.Number(), Type.Null(), { additionalProperties: false, }) const R1 = Value.Check(T, { a: null, b: null, 0: null, 1: null, }) const R2 = Value.Check(T, { 0: null, 1: null, }) Assert.IsEqual(R1, false) Assert.IsEqual(R2, true) }) it('Should validate for any keys', () => { const T = Type.Record(Type.Any(), Type.Null(), { additionalProperties: false, }) const R = Value.Check(T, { a: null, b: null, 0: null, 1: null, }) Assert.IsEqual(R, true) }) it('Should validate for never keys', () => { const T = Type.Record(Type.Never(), Type.Null(), { additionalProperties: false, }) const R1 = Value.Check(T, {}) const R2 = Value.Check(T, { a: null, b: null, 0: null, 1: null, }) Assert.IsEqual(R1, true) Assert.IsEqual(R2, false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/recursive.ts000066400000000000000000000032061505437577000254730ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Recursive', () => { const T = Type.Recursive((This) => Type.Object({ id: Type.String(), nodes: Type.Array(This), }), ) it('Should pass recursive', () => { const value = { id: 'A', nodes: [ { id: 'B', nodes: [] }, { id: 'C', nodes: [] }, { id: 'D', nodes: [] }, ], } const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should fail recursive with invalid id', () => { const value = { id: 'A', nodes: [ { id: 1, nodes: [] }, { id: 'C', nodes: [] }, { id: 'D', nodes: [] }, ], } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail rec with invalid nodes', () => { const value = { id: 'A', nodes: [ { id: 'B', nodes: 1 }, { id: 'C', nodes: [] }, { id: 'D', nodes: [] }, ], } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail recursive with missing id', () => { const value = { id: 'A', nodes: [{ nodes: [] }, { id: 'C', nodes: [] }, { id: 'D', nodes: [] }], } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail rec with missing nodes', () => { const value = { id: 'A', nodes: [{ id: 'B' }, { id: 'C', nodes: [] }, { id: 'D', nodes: [] }], } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/ref.ts000066400000000000000000000050731505437577000242440ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Ref', () => { // ---------------------------------------------------------------- // Deprecated // ---------------------------------------------------------------- it('Should validate for Ref(Schema)', () => { const T = Type.Number({ $id: 'T' }) const R = Type.Ref(T) Assert.IsTrue(Value.Check(T, [T], 1234)) Assert.IsFalse(Value.Check(T, [T], 'hello')) }) // ---------------------------------------------------------------- // Standard // ---------------------------------------------------------------- it('Should should validate when referencing a type', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { $id: Assert.NextId() }, ) const R = Type.Ref(T.$id!) Assert.IsEqual( Value.Check(R, [T], { x: 1, y: 2, z: 3, }), true, ) }) it('Should not validate when passing invalid data', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { $id: Assert.NextId() }, ) const R = Type.Ref(T.$id!) Assert.IsEqual( Value.Check(R, [T], { x: 1, y: 2, }), false, ) }) it('Should de-reference object property schema', () => { const T = Type.Object( { name: Type.String(), }, { $id: 'R' }, ) const R = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), r: Type.Optional(Type.Ref(T.$id!)), }, { $id: 'T' }, ) Assert.IsEqual(Value.Check(R, [T], { x: 1, y: 2, z: 3 }), true) Assert.IsEqual(Value.Check(R, [T], { x: 1, y: 2, z: 3, r: { name: 'hello' } }), true) Assert.IsEqual(Value.Check(R, [T], { x: 1, y: 2, z: 3, r: { name: 1 } }), false) Assert.IsEqual(Value.Check(R, [T], { x: 1, y: 2, z: 3, r: {} }), false) // Ok(R, { x: 1, y: 2, z: 3 }, [T]) // Ok(R, , [T]) // Fail(R, , [T]) // Fail(R, , [T]) }) it('Should reference recursive schema', () => { const T = Type.Recursive((Node) => Type.Object({ id: Type.String(), nodes: Type.Array(Node), }), ) const R = Type.Ref(T.$id!) Assert.IsEqual(Value.Check(R, [T], { id: '', nodes: [{ id: '', nodes: [] }] }), true) Assert.IsEqual(Value.Check(R, [T], { id: '', nodes: [{ id: 1, nodes: [] }] }), false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/regexp.ts000066400000000000000000000030431505437577000247550ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/RegExp', () => { // ------------------------------------------------- // Regular Expression // ------------------------------------------------- it('Should pass regular expression 1', () => { const T = Type.RegExp(/foo/) const value = 'foo' const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass regular expression 2', () => { const T = Type.RegExp(/foo/) const value = 'bar' const result = Value.Check(T, value) Assert.IsEqual(result, false) }) // ------------------------------------------------- // Pattern // ------------------------------------------------- it('Should pass pattern 1', () => { const T = Type.RegExp('foo') const value = 'foo' const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass pattern 2', () => { const T = Type.RegExp('foo') const value = 'bar' const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should validate with minLength constraint', () => { const T = Type.RegExp(/(.*)/, { minLength: 3, }) Assert.IsTrue(Value.Check(T, 'xxx')) Assert.IsFalse(Value.Check(T, 'xx')) }) it('Should validate with maxLength constraint', () => { const T = Type.RegExp(/(.*)/, { maxLength: 3, }) Assert.IsTrue(Value.Check(T, 'xxx')) Assert.IsFalse(Value.Check(T, 'xxxx')) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/string.ts000066400000000000000000000024511505437577000247730ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/String', () => { const T = Type.String() it('Should pass string', () => { const value = 'hello' const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should fail number', () => { const value = 1 const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail boolean', () => { const value = true const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail null', () => { const value = null const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail undefined', () => { const value = undefined const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail object', () => { const value = { a: 1 } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail array', () => { const value = [1, 2] const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail Date', () => { const value = new Date() const result = Value.Check(T, value) Assert.IsEqual(result, false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/symbol.ts000066400000000000000000000026701505437577000247750ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Symbol', () => { const T = Type.Symbol() it('Should fail string', () => { const value = 'hello' const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail number', () => { const value = 1 const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail boolean', () => { const value = true const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail null', () => { const value = null const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail undefined', () => { const value = undefined const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail object', () => { const value = { a: 1 } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail array', () => { const value = [1, 2] const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail Date', () => { const value = new Date() const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should pass symbol', () => { const value = Symbol(1) const result = Value.Check(T, value) Assert.IsEqual(result, true) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/template-literal.ts000066400000000000000000000141221505437577000267300ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/TemplateLiteral', () => { // -------------------------------------------------------- // Finite // -------------------------------------------------------- it('Should validate finite pattern 1', () => { // prettier-ignore const T = Type.TemplateLiteral([]) Assert.IsEqual(Value.Check(T, ''), true) Assert.IsEqual(Value.Check(T, 'X'), false) }) it('Should validate finite pattern 1', () => { // prettier-ignore const T = Type.TemplateLiteral([Type.Boolean()]) Assert.IsEqual(Value.Check(T, 'true'), true) Assert.IsEqual(Value.Check(T, 'false'), true) Assert.IsEqual(Value.Check(T, 'X'), false) }) it('Should validate finite pattern 2', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A') ]) Assert.IsEqual(Value.Check(T, 'A'), true) Assert.IsEqual(Value.Check(T, 'X'), false) }) it('Should validate finite pattern 3', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.Literal('B') ]) Assert.IsEqual(Value.Check(T, 'AB'), true) Assert.IsEqual(Value.Check(T, 'X'), false) }) it('Should validate finite pattern 4', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.Union([ Type.Literal('B'), Type.Literal('C') ]), ]) Assert.IsEqual(Value.Check(T, 'AB'), true) Assert.IsEqual(Value.Check(T, 'AC'), true) Assert.IsEqual(Value.Check(T, 'X'), false) }) it('Should validate finite pattern 5', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.Union([ Type.Literal('B'), Type.Literal('C') ]), Type.Literal('D'), ]) Assert.IsEqual(Value.Check(T, 'ABD'), true) Assert.IsEqual(Value.Check(T, 'ACD'), true) Assert.IsEqual(Value.Check(T, 'X'), false) }) it('Should validate finite pattern 6', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Union([ Type.Literal('0'), Type.Literal('1') ]), Type.Union([ Type.Literal('0'), Type.Literal('1') ]), ]) Assert.IsEqual(Value.Check(T, '00'), true) Assert.IsEqual(Value.Check(T, '01'), true) Assert.IsEqual(Value.Check(T, '10'), true) Assert.IsEqual(Value.Check(T, '11'), true) Assert.IsEqual(Value.Check(T, 'X'), false) }) // -------------------------------------------------------- // Infinite // -------------------------------------------------------- it('Should validate infinite pattern 1', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Number() ]) Assert.IsEqual(Value.Check(T, '1'), true) Assert.IsEqual(Value.Check(T, '22'), true) Assert.IsEqual(Value.Check(T, '333'), true) Assert.IsEqual(Value.Check(T, '4444'), true) Assert.IsEqual(Value.Check(T, 'X'), false) }) it('Should validate infinite pattern 2', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Integer() ]) Assert.IsEqual(Value.Check(T, '1'), true) Assert.IsEqual(Value.Check(T, '22'), true) Assert.IsEqual(Value.Check(T, '333'), true) Assert.IsEqual(Value.Check(T, '4444'), true) Assert.IsEqual(Value.Check(T, 'X'), false) }) it('Should validate infinite pattern 3', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.BigInt() ]) Assert.IsEqual(Value.Check(T, '1'), true) Assert.IsEqual(Value.Check(T, '22'), true) Assert.IsEqual(Value.Check(T, '333'), true) Assert.IsEqual(Value.Check(T, '4444'), true) Assert.IsEqual(Value.Check(T, 'X'), false) }) it('Should validate infinite pattern 4', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.String() ]) Assert.IsEqual(Value.Check(T, '1'), true) Assert.IsEqual(Value.Check(T, '22'), true) Assert.IsEqual(Value.Check(T, '333'), true) Assert.IsEqual(Value.Check(T, '4444'), true) Assert.IsEqual(Value.Check(T, 'a'), true) Assert.IsEqual(Value.Check(T, 'bb'), true) Assert.IsEqual(Value.Check(T, 'ccc'), true) Assert.IsEqual(Value.Check(T, 'dddd'), true) }) it('Should validate infinite pattern 5', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.Number() ]) Assert.IsEqual(Value.Check(T, 'A1'), true) Assert.IsEqual(Value.Check(T, 'A22'), true) Assert.IsEqual(Value.Check(T, 'A333'), true) Assert.IsEqual(Value.Check(T, 'A4444'), true) Assert.IsEqual(Value.Check(T, 'X'), false) }) it('Should validate infinite pattern 6', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.Integer() ]) Assert.IsEqual(Value.Check(T, 'A1'), true) Assert.IsEqual(Value.Check(T, 'A22'), true) Assert.IsEqual(Value.Check(T, 'A333'), true) Assert.IsEqual(Value.Check(T, 'A4444'), true) Assert.IsEqual(Value.Check(T, 'X'), false) }) it('Should validate infinite pattern 7', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.BigInt() ]) Assert.IsEqual(Value.Check(T, 'A1'), true) Assert.IsEqual(Value.Check(T, 'A22'), true) Assert.IsEqual(Value.Check(T, 'A333'), true) Assert.IsEqual(Value.Check(T, 'A4444'), true) Assert.IsEqual(Value.Check(T, 'X'), false) }) it('Should validate infinite pattern 8', () => { // prettier-ignore const T = Type.TemplateLiteral([ Type.Literal('A'), Type.String() ]) Assert.IsEqual(Value.Check(T, 'A1'), true) Assert.IsEqual(Value.Check(T, 'A22'), true) Assert.IsEqual(Value.Check(T, 'A333'), true) Assert.IsEqual(Value.Check(T, 'A4444'), true) Assert.IsEqual(Value.Check(T, 'Aa'), true) Assert.IsEqual(Value.Check(T, 'Abb'), true) Assert.IsEqual(Value.Check(T, 'Accc'), true) Assert.IsEqual(Value.Check(T, 'Adddd'), true) Assert.IsEqual(Value.Check(T, 'X'), false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/tuple.ts000066400000000000000000000022201505437577000246100ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Tuple', () => { it('Should pass tuple', () => { const T = Type.Tuple([Type.Number(), Type.Number()]) const value = [1, 2] const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should fail when tuple is less than length', () => { const T = Type.Tuple([Type.Number(), Type.Number()]) const value = [1] const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail when tuple is greater than length', () => { const T = Type.Tuple([Type.Number(), Type.Number()]) const value = [1, 1, 2] const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should pass empty tuple', () => { const T = Type.Tuple([]) const value = [] as any[] const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should fail empty tuple', () => { const T = Type.Tuple([]) const value = [1] const result = Value.Check(T, value) Assert.IsEqual(result, false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/uint8array.ts000066400000000000000000000016411505437577000255730ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Uint8Array', () => { it('Should pass Uint8Array', () => { const T = Type.Uint8Array() const value = new Uint8Array(4) const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should fail Uint8Array', () => { const T = Type.Uint8Array() const value = [0, 1, 2, 3] const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail Uint8Array with undefined', () => { const T = Type.Uint8Array() const value = undefined const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail Uint8Array with null', () => { const T = Type.Uint8Array() const value = null const result = Value.Check(T, value) Assert.IsEqual(result, false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/undefined.ts000066400000000000000000000024571505437577000254340ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Undefined', () => { const T = Type.Undefined() it('Should fail string', () => { const value = 'hello' const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail number', () => { const value = 1 const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail boolean', () => { const value = true const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail null', () => { const value = null const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should pass undefined', () => { const value = undefined const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should fail object', () => { const value = { a: 1 } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail array', () => { const value = [1, 2] const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail Date', () => { const value = new Date() const result = Value.Check(T, value) Assert.IsEqual(result, false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/union.ts000066400000000000000000000037621505437577000246230ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Union', () => { const A = Type.Object({ type: Type.Literal('A'), x: Type.Number(), y: Type.Number(), }) const B = Type.Object({ type: Type.Literal('B'), x: Type.Boolean(), y: Type.Boolean(), }) const T = Type.Union([A, B]) it('Should pass union A', () => { const value = { type: 'A', x: 1, y: 1 } const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass union B', () => { const value = { type: 'B', x: true, y: false } const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should fail union A', () => { const value = { type: 'A', x: true, y: false } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail union B', () => { const value = { type: 'B', x: 1, y: 1 } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should pass union A with optional properties', () => { const A = Type.Object({ type: Type.Literal('A'), x: Type.Optional(Type.Number()), y: Type.Optional(Type.Number()), }) const B = Type.Object({ type: Type.Literal('B'), x: Type.Boolean(), y: Type.Boolean(), }) const T = Type.Union([A, B]) const value = { type: 'A' } const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should fail union A with invalid optional properties', () => { const A = Type.Object({ type: Type.Literal('A'), x: Type.Optional(Type.Number()), y: Type.Optional(Type.Number()), }) const B = Type.Object({ type: Type.Literal('B'), x: Type.Boolean(), y: Type.Boolean(), }) const T = Type.Union([A, B]) const value = { type: 'A', x: true, y: false } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/unknown.ts000066400000000000000000000024401505437577000251620ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Unknown', () => { const T = Type.Any() it('Should pass string', () => { const value = 'hello' const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass number', () => { const value = 1 const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass boolean', () => { const value = true const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass null', () => { const value = null const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass undefined', () => { const value = undefined const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass object', () => { const value = { a: 1 } const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass array', () => { const value = [1, 2] const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should pass Date', () => { const value = new Date() const result = Value.Check(T, value) Assert.IsEqual(result, true) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/check/void.ts000066400000000000000000000024451505437577000244310ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/check/Void', () => { const T = Type.Void() it('Should fail string', () => { const value = 'hello' const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail number', () => { const value = 1 const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail boolean', () => { const value = true const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should pass null', () => { const value = null const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should pass undefined', () => { const value = undefined const result = Value.Check(T, value) Assert.IsEqual(result, true) }) it('Should fail object', () => { const value = { a: 1 } const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail array', () => { const value = [1, 2] const result = Value.Check(T, value) Assert.IsEqual(result, false) }) it('Should fail Date', () => { const value = new Date() const result = Value.Check(T, value) Assert.IsEqual(result, false) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/000077500000000000000000000000001505437577000231205ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/any.ts000066400000000000000000000004511505437577000242570ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Any', () => { it('Should clean 1', () => { const T = Type.Any() const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/array.ts000066400000000000000000000011641505437577000246100ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Array', () => { it('Should clean 1', () => { const T = Type.Any() const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean 2', () => { const T = Type.Array( Type.Object({ x: Type.Number(), y: Type.Number(), }), ) const R = Value.Clean(T, [undefined, null, { x: 1 }, { x: 1, y: 2 }, { x: 1, y: 2, z: 3 }]) Assert.IsEqual(R, [undefined, null, { x: 1 }, { x: 1, y: 2 }, { x: 1, y: 2 }]) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/async-iterator.ts000066400000000000000000000005121505437577000264320ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/AsyncIterator', () => { it('Should clean 1', () => { const T = Type.AsyncIterator(Type.Number()) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/bigint.ts000066400000000000000000000004571505437577000247520ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/BigInt', () => { it('Should clean 1', () => { const T = Type.BigInt() const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/boolean.ts000066400000000000000000000004611505437577000251100ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Boolean', () => { it('Should clean 1', () => { const T = Type.Boolean() const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/composite.ts000066400000000000000000000005731505437577000254770ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Composite', () => { it('Should clean 1', () => { const T = Type.Composite([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })]) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/constructor.ts000066400000000000000000000006421505437577000260570ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Constructor', () => { it('Should clean 1', () => { const T = Type.Constructor([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })], Type.Object({ z: Type.Number() })) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/date.ts000066400000000000000000000004531505437577000244070ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Date', () => { it('Should clean 1', () => { const T = Type.Date() const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/enum.ts000066400000000000000000000004711505437577000244360ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Enum', () => { it('Should clean 1', () => { const T = Type.Enum({ x: 1, y: 2 }) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/function.ts000066400000000000000000000006341505437577000253200ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Function', () => { it('Should clean 1', () => { const T = Type.Function([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })], Type.Object({ z: Type.Number() })) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/import.ts000066400000000000000000000125731505437577000250120ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Import', () => { // ---------------------------------------------------------------- // Clean // ---------------------------------------------------------------- it('Should clean 1', () => { const T = Type.Module({ A: Type.Object({ x: Type.Number() }) }).Import('A') const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean 2', () => { const T = Type.Module({ A: Type.Object({ x: Type.Number() }) }).Import('A') const R = Value.Clean(T, {}) Assert.IsEqual(R, {}) }) it('Should clean 3', () => { const T = Type.Module({ A: Type.Object({ x: Type.Number() }) }).Import('A') const R = Value.Clean(T, { x: 1 }) Assert.IsEqual(R, { x: 1 }) }) it('Should clean 4', () => { const T = Type.Module({ A: Type.Object({ x: Type.Number() }) }).Import('A') const R = Value.Clean(T, { x: null }) Assert.IsEqual(R, { x: null }) }) // ---------------------------------------------------------------- // Nested // ---------------------------------------------------------------- it('Should clean nested 1', () => { const T = Type.Module({ A: Type.Object({ x: Type.Object({ y: Type.Number(), }), }), }).Import('A') const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean nested 2', () => { const T = Type.Module({ A: Type.Object({ x: Type.Object({ y: Type.Number(), }), }), }).Import('A') const R = Value.Clean(T, {}) Assert.IsEqual(R, {}) }) it('Should clean nested 3', () => { const T = Type.Module({ A: Type.Object({ x: Type.Object({ y: Type.Number(), }), }), }).Import('A') const R = Value.Clean(T, { x: null }) Assert.IsEqual(R, { x: null }) }) it('Should clean nested 4', () => { const T = Type.Module({ A: Type.Object({ x: Type.Object({ y: Type.Number(), }), }), }).Import('A') const R = Value.Clean(T, { x: { y: null } }) Assert.IsEqual(R, { x: { y: null } }) }) // ---------------------------------------------------------------- // Additional Properties // ---------------------------------------------------------------- it('Should clean additional properties 1', () => { const T = Type.Module({ A: Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.String(), }, ), }).Import('A') const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean additional properties 2', () => { const T = Type.Module({ A: Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.String(), }, ), }).Import('A') const R = Value.Clean(T, {}) Assert.IsEqual(R, {}) }) it('Should clean additional properties 3', () => { const T = Type.Module({ A: Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.String(), }, ), }).Import('A') const R = Value.Clean(T, { x: 1 }) Assert.IsEqual(R, { x: 1 }) }) it('Should clean additional properties 4', () => { const T = Type.Module({ A: Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.String(), }, ), }).Import('A') const R = Value.Clean(T, { x: 1, y: 2 }) Assert.IsEqual(R, { x: 1, y: 2 }) }) // ---------------------------------------------------------------- // Additional Properties Discard // ---------------------------------------------------------------- it('Should clean additional properties discard 1', () => { const T = Type.Module({ A: Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.String(), }, ), }).Import('A') const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean additional properties discard 2', () => { const T = Type.Module({ A: Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.String(), }, ), }).Import('A') const R = Value.Clean(T, { k: '', d: null }) Assert.IsEqual(R, { k: '' }) }) it('Should clean additional properties discard 3', () => { const T = Type.Module({ A: Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.String(), }, ), }).Import('A') const R = Value.Clean(T, { k: '', d: null, x: 1 }) Assert.IsEqual(R, { k: '', x: 1 }) }) it('Should clean additional properties discard 4', () => { const T = Type.Module({ A: Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.String(), }, ), }).Import('A') const R = Value.Clean(T, { k: '', d: null, x: 1, y: 2 }) Assert.IsEqual(R, { k: '', x: 1, y: 2 }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/index.ts000066400000000000000000000012161505437577000245770ustar00rootroot00000000000000import './any' import './array' import './async-iterator' import './bigint' import './boolean' import './composite' import './constructor' import './date' import './enum' import './function' import './import' import './integer' import './intersect' import './iterator' import './keyof' import './kind' import './literal' import './never' import './not' import './null' import './object' import './promise' import './record' import './recursive' import './ref' import './regexp' import './string' import './symbol' import './template-literal' import './tuple' import './uint8array' import './undefined' import './union' import './unknown' import './void' sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/integer.ts000066400000000000000000000004611505437577000251260ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Integer', () => { it('Should clean 1', () => { const T = Type.Integer() const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/intersect.ts000066400000000000000000000250141505437577000254720ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' // prettier-ignore describe('value/clean/Intersect', () => { // ---------------------------------------------------------------- // Intersect // ---------------------------------------------------------------- it('Should clean 1', () => { const T = Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean 2', () => { const T = Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]) const R = Value.Clean(T, {}) Assert.IsEqual(R, {}) }) it('Should clean 3', () => { const T = Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]) const R = Value.Clean(T, { x: 1, y: 2 }) Assert.IsEqual(R, { x: 1, y: 2 }) }) it('Should clean 4', () => { const T = Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]) const R = Value.Clean(T, { x: 1, y: 2, z: 3 }) Assert.IsEqual(R, { x: 1, y: 2 }) }) // ---------------------------------------------------------------- // Intersect Discard // ---------------------------------------------------------------- it('Should clean discard 1', () => { const T = Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean discard 2', () => { const T = Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]) const R = Value.Clean(T, { u: null }) Assert.IsEqual(R, {}) }) it('Should clean discard 3', () => { const T = Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]) const R = Value.Clean(T, { u: null, x: 1, y: 2 }) Assert.IsEqual(R, { x: 1, y: 2 }) }) it('Should clean discard 4', () => { const T = Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]) const R = Value.Clean(T, { u: null, x: 1, y: 2 }) Assert.IsEqual(R, { x: 1, y: 2 }) }) // ---------------------------------------------------------------- // Intersect Deep // ---------------------------------------------------------------- it('Should clear intersect deep 1', () => { const T = Type.Intersect([ Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]), Type.Intersect([ Type.Object({ z: Type.Number() }), Type.Object({ w: Type.Number() }) ]) ]) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clear intersect deep 2', () => { const T = Type.Intersect([ Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]), Type.Intersect([ Type.Object({ z: Type.Number() }), Type.Object({ w: Type.Number() }) ]) ]) const R = Value.Clean(T, {}) Assert.IsEqual(R, {}) }) it('Should clear intersect deep 3', () => { const T = Type.Intersect([ Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]), Type.Intersect([ Type.Object({ z: Type.Number() }), Type.Object({ w: Type.Number() }) ]) ]) const R = Value.Clean(T, { x: 1 }) Assert.IsEqual(R, { x: 1 }) }) it('Should clear intersect deep 4', () => { const T = Type.Intersect([ Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]), Type.Intersect([ Type.Object({ z: Type.Number() }), Type.Object({ w: Type.Number() }) ]) ]) const R = Value.Clean(T, { x: 1, y: 2 }) Assert.IsEqual(R, { x: 1, y: 2 }) }) it('Should clear intersect deep 5', () => { const T = Type.Intersect([ Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]), Type.Intersect([ Type.Object({ z: Type.Number() }), Type.Object({ w: Type.Number() }) ]) ]) const R = Value.Clean(T, { x: 1, y: 2, z: 3 }) Assert.IsEqual(R, { x: 1, y: 2, z: 3 }) }) it('Should clear intersect deep 6', () => { const T = Type.Intersect([ Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]), Type.Intersect([ Type.Object({ z: Type.Number() }), Type.Object({ w: Type.Number() }) ]) ]) const R = Value.Clean(T, { x: 1, y: 2, z: 3, w: 3 }) Assert.IsEqual(R, { x: 1, y: 2, z: 3, w: 3 }) }) it('Should clear intersect deep 7', () => { const T = Type.Intersect([ Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]), Type.Intersect([ Type.Object({ z: Type.Number() }), Type.Object({ w: Type.Number() }) ]) ]) const R = Value.Clean(T, { x: 1, y: 2, z: 3, w: 3 }) Assert.IsEqual(R, { x: 1, y: 2, z: 3, w: 3 }) }) // ---------------------------------------------------------------- // Intersect Deep Discard // ---------------------------------------------------------------- it('Should clear intersect discard deep 1', () => { const T = Type.Intersect([ Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]), Type.Intersect([ Type.Object({ z: Type.Number() }), Type.Object({ w: Type.Number() }) ]) ]) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clear intersect discard deep 2', () => { const T = Type.Intersect([ Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]), Type.Intersect([ Type.Object({ z: Type.Number() }), Type.Object({ w: Type.Number() }) ]) ]) const R = Value.Clean(T, { u: null }) Assert.IsEqual(R, {}) }) it('Should clear intersect discard deep 3', () => { const T = Type.Intersect([ Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]), Type.Intersect([ Type.Object({ z: Type.Number() }), Type.Object({ w: Type.Number() }) ]) ]) const R = Value.Clean(T, { u: null, x: 1 }) Assert.IsEqual(R, { x: 1 }) }) it('Should clear intersect discard deep 4', () => { const T = Type.Intersect([ Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]), Type.Intersect([ Type.Object({ z: Type.Number() }), Type.Object({ w: Type.Number() }) ]) ]) const R = Value.Clean(T, { u: null, x: 1, y: 2 }) Assert.IsEqual(R, { x: 1, y: 2 }) }) it('Should clear intersect discard deep 5', () => { const T = Type.Intersect([ Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]), Type.Intersect([ Type.Object({ z: Type.Number() }), Type.Object({ w: Type.Number() }) ]) ]) const R = Value.Clean(T, { u: null, x: 1, y: 2, z: 3 }) Assert.IsEqual(R, { x: 1, y: 2, z: 3 }) }) it('Should clear intersect discard deep 6', () => { const T = Type.Intersect([ Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]), Type.Intersect([ Type.Object({ z: Type.Number() }), Type.Object({ w: Type.Number() }) ]) ]) const R = Value.Clean(T, { u: null, x: 1, y: 2, z: 3, w: 3 }) Assert.IsEqual(R, { x: 1, y: 2, z: 3, w: 3 }) }) it('Should clear intersect discard deep 7', () => { const T = Type.Intersect([ Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]), Type.Intersect([ Type.Object({ z: Type.Number() }), Type.Object({ w: Type.Number() }) ]) ]) const R = Value.Clean(T, { u: null, x: 1, y: 2, z: 3, w: 3, a: 1 }) Assert.IsEqual(R, { x: 1, y: 2, z: 3, w: 3 }) }) // ---------------------------------------------------------------- // Intersect Invalid // ---------------------------------------------------------------- it('Should clean intersect invalid 1', () => { const T = Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.String() }) ]) const R = Value.Clean(T, { x: 1, y: 2 }) Assert.IsEqual(R, { x: 1, y: 2 }) // types are ignored }) // ---------------------------------------------------------------- // Intersect Unevaluted Properties // ---------------------------------------------------------------- it('Should clean intersect unevaluated properties 1', () => { const T = Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.String() }) ], { unevaluatedProperties: Type.String() }) const R = Value.Clean(T, { x: 1, y: 2, a: 1, b: '' }) Assert.IsEqual(R, { x: 1, y: 2, b: '' }) }) // ---------------------------------------------------------------- // Intersect Illogical // ---------------------------------------------------------------- it('Should clean illogical 1', () => { const T = Type.Intersect([ Type.Number(), Type.Object({ x: Type.Number() }) ]) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean illogical 2', () => { const T = Type.Intersect([ Type.Number(), Type.Object({ x: Type.Number() }) ]) const R = Value.Clean(T, 1) Assert.IsEqual(R, 1) }) it('Should clean illogical 3', () => { const T = Type.Intersect([ Type.Number(), Type.Object({ x: Type.Number() }) ]) const R = Value.Clean(T, {}) Assert.IsEqual(R, {}) }) it('Should clean illogical 4', () => { const T = Type.Intersect([ Type.Number(), Type.Object({ x: Type.Number() }) ]) const R = Value.Clean(T, { x: 1 }) Assert.IsEqual(R, { x: 1 }) }) it('Should clean illogical 5', () => { const T = Type.Intersect([ Type.Number(), Type.Object({ x: Type.Number() }), ]) const R = Value.Clean(T, { u: null, x: 1 }) Assert.IsEqual(R, { u: null, x: 1 }) // u retained from Number }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/iterator.ts000066400000000000000000000005001505437577000253140ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Iterator', () => { it('Should clean 1', () => { const T = Type.Iterator(Type.String()) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/keyof.ts000066400000000000000000000005401505437577000246040ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/KeyOf', () => { it('Should clean 1', () => { const T = Type.KeyOf(Type.Object({ x: Type.Number(), y: Type.Number() })) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/kind.ts000066400000000000000000000005101505437577000244110ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type, Kind } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Kind', () => { it('Should clean 1', () => { const T = Type.Unsafe({ [Kind]: 'Unknown' }) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/literal.ts000066400000000000000000000004621505437577000251260ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Literal', () => { it('Should clean 1', () => { const T = Type.Literal(1) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/never.ts000066400000000000000000000004551505437577000246130ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Never', () => { it('Should clean 1', () => { const T = Type.Never() const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/not.ts000066400000000000000000000004631505437577000242730ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Not', () => { it('Should clean 1', () => { const T = Type.Not(Type.Any()) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/null.ts000066400000000000000000000004531505437577000244440ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Null', () => { it('Should clean 1', () => { const T = Type.Null() const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/number.ts000066400000000000000000000004571505437577000247660ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Number', () => { it('Should clean 1', () => { const T = Type.Number() const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/object.ts000066400000000000000000000111261505437577000247370ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Object', () => { // ---------------------------------------------------------------- // Clean // ---------------------------------------------------------------- it('Should clean 1', () => { const T = Type.Object({ x: Type.Number() }) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean 2', () => { const T = Type.Object({ x: Type.Number() }) const R = Value.Clean(T, {}) Assert.IsEqual(R, {}) }) it('Should clean 3', () => { const T = Type.Object({ x: Type.Number() }) const R = Value.Clean(T, { x: 1 }) Assert.IsEqual(R, { x: 1 }) }) it('Should clean 4', () => { const T = Type.Object({ x: Type.Number() }) const R = Value.Clean(T, { x: null }) Assert.IsEqual(R, { x: null }) }) // ---------------------------------------------------------------- // Nested // ---------------------------------------------------------------- it('Should clean nested 1', () => { const T = Type.Object({ x: Type.Object({ y: Type.Number(), }), }) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean nested 2', () => { const T = Type.Object({ x: Type.Object({ y: Type.Number(), }), }) const R = Value.Clean(T, {}) Assert.IsEqual(R, {}) }) it('Should clean nested 3', () => { const T = Type.Object({ x: Type.Object({ y: Type.Number(), }), }) const R = Value.Clean(T, { x: null }) Assert.IsEqual(R, { x: null }) }) it('Should clean nested 4', () => { const T = Type.Object({ x: Type.Object({ y: Type.Number(), }), }) const R = Value.Clean(T, { x: { y: null } }) Assert.IsEqual(R, { x: { y: null } }) }) // ---------------------------------------------------------------- // Additional Properties // ---------------------------------------------------------------- it('Should clean additional properties 1', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.String(), }, ) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean additional properties 2', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.String(), }, ) const R = Value.Clean(T, {}) Assert.IsEqual(R, {}) }) it('Should clean additional properties 3', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.String(), }, ) const R = Value.Clean(T, { x: 1 }) Assert.IsEqual(R, { x: 1 }) }) it('Should clean additional properties 4', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.String(), }, ) const R = Value.Clean(T, { x: 1, y: 2 }) Assert.IsEqual(R, { x: 1, y: 2 }) }) // ---------------------------------------------------------------- // Additional Properties Discard // ---------------------------------------------------------------- it('Should clean additional properties discard 1', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.String(), }, ) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean additional properties discard 2', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.String(), }, ) const R = Value.Clean(T, { k: '', d: null }) Assert.IsEqual(R, { k: '' }) }) it('Should clean additional properties discard 3', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.String(), }, ) const R = Value.Clean(T, { k: '', d: null, x: 1 }) Assert.IsEqual(R, { k: '', x: 1 }) }) it('Should clean additional properties discard 4', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), }, { additionalProperties: Type.String(), }, ) const R = Value.Clean(T, { k: '', d: null, x: 1, y: 2 }) Assert.IsEqual(R, { k: '', x: 1, y: 2 }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/promise.ts000066400000000000000000000004731505437577000251520ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Promise', () => { it('Should clean 1', () => { const T = Type.Promise(Type.Any()) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/record.ts000066400000000000000000000101231505437577000247430ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Record', () => { // ---------------------------------------------------------------- // Clean // ---------------------------------------------------------------- it('Should clean 1', () => { const T = Type.Record(Type.Number(), Type.String()) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean 2', () => { const T = Type.Record(Type.Number(), Type.String()) const R = Value.Clean(T, {}) Assert.IsEqual(R, {}) }) it('Should clean 3', () => { const T = Type.Record(Type.Number(), Type.String()) const R = Value.Clean(T, { 0: null }) Assert.IsEqual(R, { 0: null }) }) // ---------------------------------------------------------------- // Clean Discard // ---------------------------------------------------------------- it('Should clean discard 1', () => { const T = Type.Record(Type.Number(), Type.String()) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean discard 2', () => { const T = Type.Record(Type.Number(), Type.String()) const R = Value.Clean(T, { a: 1 }) Assert.IsEqual(R, {}) }) it('Should clean discard 3', () => { const T = Type.Record(Type.Number(), Type.String()) const R = Value.Clean(T, { a: 1, 0: null }) Assert.IsEqual(R, { 0: null }) }) // ---------------------------------------------------------------- // Additional Properties // ---------------------------------------------------------------- it('Should clean additional properties 1', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: Type.Boolean(), }) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean additional properties 2', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: Type.Boolean(), }) const R = Value.Clean(T, {}) Assert.IsEqual(R, {}) }) it('Should clean additional properties 3', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: Type.Boolean(), }) const R = Value.Clean(T, { 0: null }) Assert.IsEqual(R, { 0: null }) }) // ---------------------------------------------------------------- // Additional Properties Discard // ---------------------------------------------------------------- it('Should clean additional properties discard 1', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: Type.Boolean(), }) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean additional properties discard 2', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: Type.Boolean(), }) const R = Value.Clean(T, { a: null }) Assert.IsEqual(R, {}) }) it('Should clean additional properties discard 3', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: Type.Boolean(), }) const R = Value.Clean(T, { a: null, 0: null }) Assert.IsEqual(R, { 0: null }) }) // ---------------------------------------------------------------- // Additional Properties Keep // ---------------------------------------------------------------- it('Should clean additional properties keep 1', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: Type.Boolean(), }) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean additional properties keep 2', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: Type.Boolean(), }) const R = Value.Clean(T, { a: true }) Assert.IsEqual(R, { a: true }) }) it('Should clean additional properties keep 3', () => { const T = Type.Record(Type.Number(), Type.String(), { additionalProperties: Type.Boolean(), }) const R = Value.Clean(T, { a: true, 0: null }) Assert.IsEqual(R, { a: true, 0: null }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/recursive.ts000066400000000000000000000062361505437577000255060ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Recursive', () => { // ---------------------------------------------------------------- // Clean // ---------------------------------------------------------------- it('Should clean 1', () => { const T = Type.Recursive((This) => Type.Object({ id: Type.String(), nodes: Type.Array(This), }), ) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean 2', () => { const T = Type.Recursive((This) => Type.Object({ id: Type.String(), nodes: Type.Array(This), }), ) const R = Value.Clean(T, { id: null }) Assert.IsEqual(R, { id: null }) }) it('Should clean 3', () => { const T = Type.Recursive((This) => Type.Object({ id: Type.String(), nodes: Type.Array(This), }), ) const R = Value.Clean(T, { id: null, nodes: null }) Assert.IsEqual(R, { id: null, nodes: null }) }) it('Should clean 4', () => { const T = Type.Recursive((This) => Type.Object({ id: Type.String(), nodes: Type.Array(This), }), ) const R = Value.Clean(T, { id: null, nodes: [] }) Assert.IsEqual(R, { id: null, nodes: [] }) }) it('Should clean 5', () => { const T = Type.Recursive((This) => Type.Object({ id: Type.String(), nodes: Type.Array(This), }), ) const R = Value.Clean(T, { id: null, nodes: [{ id: null }] }) Assert.IsEqual(R, { id: null, nodes: [{ id: null }] }) }) // ---------------------------------------------------------------- // Clean Discard // ---------------------------------------------------------------- it('Should clean discard 1', () => { const T = Type.Recursive((This) => Type.Object({ id: Type.String(), nodes: Type.Array(This), }), ) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean discard 2', () => { const T = Type.Recursive((This) => Type.Object({ id: Type.String(), nodes: Type.Array(This), }), ) const R = Value.Clean(T, { u: null, id: null }) Assert.IsEqual(R, { id: null }) }) it('Should clean discard 3', () => { const T = Type.Recursive((This) => Type.Object({ id: Type.String(), nodes: Type.Array(This), }), ) const R = Value.Clean(T, { u: null, id: null, nodes: null }) Assert.IsEqual(R, { id: null, nodes: null }) }) it('Should clean discard 4', () => { const T = Type.Recursive((This) => Type.Object({ id: Type.String(), nodes: Type.Array(This), }), ) const R = Value.Clean(T, { u: null, id: null, nodes: [] }) Assert.IsEqual(R, { id: null, nodes: [] }) }) it('Should clean discard 5', () => { const T = Type.Recursive((This) => Type.Object({ id: Type.String(), nodes: Type.Array(This), }), ) const R = Value.Clean(T, { u: null, id: null, nodes: [{ u: null, id: null }] }) Assert.IsEqual(R, { id: null, nodes: [{ id: null }] }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/ref.ts000066400000000000000000000035711505437577000242520ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Ref', () => { // ---------------------------------------------------------------- // Clean // ---------------------------------------------------------------- it('Should clean 1', () => { const A = Type.Object( { x: Type.Number(), }, { $id: 'A' }, ) const T = Type.Ref('A') const R = Value.Clean(T, [A], null) Assert.IsEqual(R, null) }) it('Should clean 2', () => { const A = Type.Object( { x: Type.Number(), }, { $id: 'A' }, ) const T = Type.Ref('A') const R = Value.Clean(T, [A], {}) Assert.IsEqual(R, {}) }) it('Should clean 3', () => { const A = Type.Object( { x: Type.Number(), }, { $id: 'A' }, ) const T = Type.Ref('A') const R = Value.Clean(T, [A], { x: null }) Assert.IsEqual(R, { x: null }) }) // ---------------------------------------------------------------- // Clean Discard // ---------------------------------------------------------------- it('Should clean discard 1', () => { const A = Type.Object( { x: Type.Number(), }, { $id: 'A' }, ) const T = Type.Ref('A') const R = Value.Clean(T, [A], null) Assert.IsEqual(R, null) }) it('Should clean discard 2', () => { const A = Type.Object( { x: Type.Number(), }, { $id: 'A' }, ) const T = Type.Ref('A') const R = Value.Clean(T, [A], { a: null }) Assert.IsEqual(R, {}) }) it('Should clean discard 3', () => { const A = Type.Object( { x: Type.Number(), }, { $id: 'A' }, ) const T = Type.Ref('A') const R = Value.Clean(T, [A], { a: null, x: null }) Assert.IsEqual(R, { x: null }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/regexp.ts000066400000000000000000000004611505437577000247630ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/RegExp', () => { it('Should clean 1', () => { const T = Type.RegExp('') const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/string.ts000066400000000000000000000004571505437577000250040ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/String', () => { it('Should clean 1', () => { const T = Type.String() const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/symbol.ts000066400000000000000000000004571505437577000250030ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Symbol', () => { it('Should clean 1', () => { const T = Type.Symbol() const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/template-literal.ts000066400000000000000000000005031505437577000267330ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/TemplateLiteral', () => { it('Should clean 1', () => { const T = Type.TemplateLiteral('') const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/tuple.ts000066400000000000000000000057101505437577000246240ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Tuple', () => { // ---------------------------------------------------------------- // Clean // ---------------------------------------------------------------- it('Should clean 1', () => { const T = Type.Tuple([Type.Number(), Type.Number()]) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean 2', () => { const T = Type.Tuple([Type.Number(), Type.Number()]) const R = Value.Clean(T, []) Assert.IsEqual(R, []) }) it('Should clean 3', () => { const T = Type.Tuple([Type.Number(), Type.Number()]) const R = Value.Clean(T, [1, 2]) Assert.IsEqual(R, [1, 2]) }) it('Should clean 4', () => { const T = Type.Tuple([Type.Number(), Type.Number()]) const R = Value.Clean(T, [1, 2, 3]) Assert.IsEqual(R, [1, 2]) }) // ---------------------------------------------------------------- // Clean Deep // ---------------------------------------------------------------- it('Should clean deep 1', () => { const T = Type.Tuple([ Type.Number(), Type.Object({ x: Type.Number(), }), ]) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean deep 2', () => { const T = Type.Tuple([ Type.Number(), Type.Object({ x: Type.Number(), }), ]) const R = Value.Clean(T, []) Assert.IsEqual(R, []) }) it('Should clean deep 3', () => { const T = Type.Tuple([ Type.Number(), Type.Object({ x: Type.Number(), }), ]) const R = Value.Clean(T, [1]) Assert.IsEqual(R, [1]) }) it('Should clean deep 4', () => { const T = Type.Tuple([ Type.Number(), Type.Object({ x: Type.Number(), }), ]) const R = Value.Clean(T, [1, null]) Assert.IsEqual(R, [1, null]) }) it('Should clean deep 5', () => { const T = Type.Tuple([ Type.Number(), Type.Object({ x: Type.Number(), }), ]) const R = Value.Clean(T, [1, { x: null }]) Assert.IsEqual(R, [1, { x: null }]) }) it('Should clean deep 6', () => { const T = Type.Tuple([ Type.Number(), Type.Object({ x: Type.Number(), }), ]) const R = Value.Clean(T, [1, { u: null, x: null }]) Assert.IsEqual(R, [1, { x: null }]) }) // ---------------------------------------------------------------- // Clean Empty // ---------------------------------------------------------------- it('Should clean empty 1', () => { const T = Type.Tuple([]) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean empty 2', () => { const T = Type.Tuple([]) const R = Value.Clean(T, []) Assert.IsEqual(R, []) }) it('Should clean empty 3', () => { const T = Type.Tuple([]) const R = Value.Clean(T, [1]) Assert.IsEqual(R, []) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/uint8array.ts000066400000000000000000000004671505437577000256050ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Uint8Array', () => { it('Should clean 1', () => { const T = Type.Uint8Array() const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/undefined.ts000066400000000000000000000004651505437577000254360ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Undefined', () => { it('Should clean 1', () => { const T = Type.Undefined() const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/union.ts000066400000000000000000000136661505437577000246340ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Union', () => { // ---------------------------------------------------------------- // Clean // ---------------------------------------------------------------- it('Should clean 1', () => { const T = Type.Union([Type.Number(), Type.Boolean()]) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean 2', () => { const T = Type.Union([Type.Number(), Type.Boolean()]) const R = Value.Clean(T, 1) Assert.IsEqual(R, 1) }) it('Should clean 2', () => { const T = Type.Union([Type.Number(), Type.Boolean()]) const R = Value.Clean(T, true) Assert.IsEqual(R, true) }) // ---------------------------------------------------------------- // Clean Select // ---------------------------------------------------------------- it('Should clean select 1', () => { const X = Type.Object({ x: Type.Number() }) const Y = Type.Object({ y: Type.Number() }) const T = Type.Union([X, Y]) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean select 2', () => { const X = Type.Object({ x: Type.Number() }) const Y = Type.Object({ y: Type.Number() }) const T = Type.Union([X, Y]) const R = Value.Clean(T, {}) Assert.IsEqual(R, {}) }) it('Should clean select 3', () => { const X = Type.Object({ x: Type.Number() }) const Y = Type.Object({ y: Type.Number() }) const T = Type.Union([X, Y]) const R = Value.Clean(T, { x: null }) Assert.IsEqual(R, { x: null }) }) it('Should clean select 4', () => { const X = Type.Object({ x: Type.Number() }) const Y = Type.Object({ y: Type.Number() }) const T = Type.Union([X, Y]) const R = Value.Clean(T, { y: null }) Assert.IsEqual(R, { y: null }) }) // ---------------------------------------------------------------- // Clean Select Discard // ---------------------------------------------------------------- it('Should clean select discard 1', () => { const X = Type.Object({ x: Type.Number() }) const Y = Type.Object({ y: Type.Number() }) const T = Type.Union([X, Y]) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean select discard 2', () => { const X = Type.Object({ x: Type.Number() }) const Y = Type.Object({ y: Type.Number() }) const T = Type.Union([X, Y]) const R = Value.Clean(T, { u: null }) Assert.IsEqual(R, { u: null }) // no match }) it('Should clean select discard 3', () => { const X = Type.Object({ x: Type.Number() }) const Y = Type.Object({ y: Type.Number() }) const T = Type.Union([X, Y]) const R = Value.Clean(T, { u: null, x: 1 }) Assert.IsEqual(R, { x: 1 }) }) it('Should clean select discard 4', () => { const X = Type.Object({ x: Type.Number() }) const Y = Type.Object({ y: Type.Number() }) const T = Type.Union([X, Y]) const R = Value.Clean(T, { u: null, y: 1 }) Assert.IsEqual(R, { y: 1 }) }) // ---------------------------------------------------------------- // Clean Select Retain // ---------------------------------------------------------------- it('Should clean select retain 1', () => { const X = Type.Object({ x: Type.Number() }, { additionalProperties: Type.Null() }) const Y = Type.Object({ y: Type.Number() }, { additionalProperties: Type.Null() }) const T = Type.Union([X, Y]) const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) it('Should clean select retain 2', () => { const X = Type.Object({ x: Type.Number() }, { additionalProperties: Type.Null() }) const Y = Type.Object({ y: Type.Number() }, { additionalProperties: Type.Null() }) const T = Type.Union([X, Y]) const R = Value.Clean(T, { u: null }) Assert.IsEqual(R, { u: null }) }) it('Should clean select retain 3', () => { const X = Type.Object({ x: Type.Number() }, { additionalProperties: Type.Null() }) const Y = Type.Object({ y: Type.Number() }, { additionalProperties: Type.Null() }) const T = Type.Union([X, Y]) const R = Value.Clean(T, { u: null, x: 1 }) Assert.IsEqual(R, { u: null, x: 1 }) }) it('Should clean select retain 4', () => { const X = Type.Object({ x: Type.Number() }, { additionalProperties: Type.Null() }) const Y = Type.Object({ y: Type.Number() }, { additionalProperties: Type.Null() }) const T = Type.Union([X, Y]) const R = Value.Clean(T, { u: null, y: 1 }) Assert.IsEqual(R, { u: null, y: 1 }) }) // ---------------------------------------------------------------- // Clean Select First and Discard // ---------------------------------------------------------------- it('Should clean select first and discard 1', () => { const X = Type.Object({ x: Type.Number() }) const Y = Type.Object({ y: Type.Number() }, { additionalProperties: Type.Null() }) const T = Type.Union([X, Y]) const R = Value.Clean(T, { u: null, x: 1 }) Assert.IsEqual(R, { x: 1 }) }) it('Should clean select first and discard 2', () => { const X = Type.Object({ x: Type.Number() }) const Y = Type.Object({ y: Type.Number() }, { additionalProperties: Type.Null() }) const T = Type.Union([X, Y]) const R = Value.Clean(T, { u: null, y: 1 }) Assert.IsEqual(R, { u: null, y: 1 }) }) // ---------------------------------------------------------------- // Union Recursive // // https://github.com/sinclairzx81/typebox/issues/845 // ---------------------------------------------------------------- it('Should clean recursive with union', () => { const T = Type.Recursive((This) => Type.Object({ id: Type.Number(), parent: Type.Union([This, Type.Null()]), }), ) const R = Value.Clean(T, { id: 1, unknown: 1, parent: { id: 2, unknown: 1, parent: null, }, }) Assert.IsEqual(R, { id: 1, parent: { id: 2, parent: null } }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/unknown.ts000066400000000000000000000004611505437577000251700ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Unknown', () => { it('Should clean 1', () => { const T = Type.Unknown() const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clean/void.ts000066400000000000000000000004531505437577000244330ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/clean/Void', () => { it('Should clean 1', () => { const T = Type.Void() const R = Value.Clean(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clone/000077500000000000000000000000001505437577000231365ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/value/clone/clone.ts000066400000000000000000000075241505437577000246160ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Assert } from '../../assert/index' describe('value/clone/Clone', () => { // -------------------------------------------- // ValueType // -------------------------------------------- it('Should clone null', () => { const R = Value.Clone(null) Assert.IsEqual(R, null) }) it('Should clone undefined', () => { const R = Value.Clone(undefined) Assert.IsEqual(R, undefined) }) it('Should clone number', () => { const R = Value.Clone(1) Assert.IsEqual(R, 1) }) it('Should clone bigint', () => { const R = Value.Clone(1n) Assert.IsEqual(R, 1n) }) it('Should clone boolean', () => { const R = Value.Clone(true) Assert.IsEqual(R, true) }) it('Should clone string', () => { const R = Value.Clone('hello') Assert.IsEqual(R, 'hello') }) it('Should clone symbol', () => { const S = Symbol('hello') const R = Value.Clone(S) Assert.IsEqual(R, S) }) // -------------------------------------------- // ObjectType // -------------------------------------------- it('Should clone object #1', () => { const V = { x: 1, y: 2, z: 3, } const R = Value.Clone(V) Assert.IsEqual(R, V) }) it('Should clone object #2', () => { const V = { x: 1, y: 2, z: 3, w: { a: 1, b: 2, c: 3, }, } const R = Value.Clone(V) Assert.IsEqual(R, V) }) it('Should clone object #3', () => { const V = { x: 1, y: 2, z: 3, w: [0, 1, 2, 3, 4], } const R = Value.Clone(V) Assert.IsEqual(R, V) }) // -------------------------------------------- // ArrayType // -------------------------------------------- it('Should clone array #1', () => { const V = [1, 2, 3, 4] const R = Value.Clone(V) Assert.IsEqual(R, V) }) it('Should clone array #2', () => { const V = [ [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], ] const R = Value.Clone(V) Assert.IsEqual(R, V) }) it('Should clone array #3', () => { const V = [ { x: 1, y: 2, z: 3 }, { x: 1, y: 2, z: 3 }, { x: 1, y: 2, z: 3 }, { x: 1, y: 2, z: 3 }, ] const R = Value.Clone(V) Assert.IsEqual(R, V) }) it('Should clone Int8Array', () => { const V = new Int8Array([1, 2, 3, 4]) const R = Value.Clone(V) Assert.IsEqual(R, V) }) it('Should clone Uint8Array', () => { const V = new Uint8Array([1, 2, 3, 4]) const R = Value.Clone(V) Assert.IsEqual(R, V) }) it('Should clone Uint8ClampedArray', () => { const V = new Uint8ClampedArray([1, 2, 3, 4]) const R = Value.Clone(V) Assert.IsEqual(R, V) }) it('Should clone Int16Array', () => { const V = new Int16Array([1, 2, 3, 4]) const R = Value.Clone(V) Assert.IsEqual(R, V) }) it('Should clone Uint16Array', () => { const V = new Uint16Array([1, 2, 3, 4]) const R = Value.Clone(V) Assert.IsEqual(R, V) }) it('Should clone Int32Array', () => { const V = new Int32Array([1, 2, 3, 4]) const R = Value.Clone(V) Assert.IsEqual(R, V) }) it('Should clone Uint32Array', () => { const V = new Int32Array([1, 2, 3, 4]) const R = Value.Clone(V) Assert.IsEqual(R, V) }) it('Should clone Float32Array', () => { const V = new Float32Array([1, 2, 3, 4]) const R = Value.Clone(V) Assert.IsEqual(R, V) }) it('Should clone Float64Array', () => { const V = new Float64Array([1, 2, 3, 4]) const R = Value.Clone(V) Assert.IsEqual(R, V) }) it('Should clone BigInt64Array', () => { const V = new BigInt64Array([1n, 2n, 3n, 4n]) const R = Value.Clone(V) Assert.IsEqual(R, V) }) it('Should clone BigUint64Array', () => { const V = new BigUint64Array([1n, 2n, 3n, 4n]) const R = Value.Clone(V) Assert.IsEqual(R, V) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/clone/index.ts000066400000000000000000000000211505437577000246060ustar00rootroot00000000000000import './clone' sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/000077500000000000000000000000001505437577000235165ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/any.ts000066400000000000000000000020451505437577000246560ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Any', () => { const T = Type.Any() it('Should convert null', () => { const V = null const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) it('Should convert undefined', () => { const V = undefined const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) it('Should convert string', () => { const V = 'hello' const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) it('Should convert number', () => { const V = 42 const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) it('Should convert boolean', () => { const V = true const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) it('Should convert object', () => { const V = { x: 1 } const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) it('Should convert array', () => { const V = [1, 2, 3] const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/array.ts000066400000000000000000000042561505437577000252130ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Array', () => { it('Should convert array of number', () => { const T = Type.Array(Type.Number()) const R = Value.Convert(T, [1, 3.14, '1', '3.14', true, false, 'true', 'false', 'hello']) Assert.IsEqual(R, [1, 3.14, 1, 3.14, 1, 0, 1, 0, 'hello']) }) it('Should convert array of boolean', () => { const T = Type.Array(Type.Boolean()) const R = Value.Convert(T, [1, 3.14, '1', '3.14', true, false, 'true', 'false', 'hello']) Assert.IsEqual(R, [true, 3.14, true, '3.14', true, false, true, false, 'hello']) }) it('Should convert array of string', () => { const T = Type.Array(Type.String()) const R = Value.Convert(T, [1, 3.14, '1', '3.14', true, false, 'true', 'false', 'hello']) Assert.IsEqual(R, ['1', '3.14', '1', '3.14', 'true', 'false', 'true', 'false', 'hello']) }) it('Should convert array of date', () => { const T = Type.Array(Type.Date()) const R = Value.Convert(T, [1, '1', true, false, 'true', 'false', 'hello']) as any[] Assert.IsEqual(R[0].getTime(), 1) Assert.IsEqual(R[1].getTime(), 1) Assert.IsEqual(R[2].getTime(), 1) Assert.IsEqual(R[3].getTime(), 0) Assert.IsEqual(R[4].getTime(), 1) Assert.IsEqual(R[5].getTime(), 0) Assert.IsEqual(R[6], 'hello') }) // ---------------------------------------------------------------- // Array Coercion // ---------------------------------------------------------------- it('Should convert into array (convert interior)', () => { const T = Type.Array(Type.Number()) const R = Value.Convert(T, '1') Assert.IsEqual(R, [1]) }) it('Should convert into array (retain interior)', () => { const T = Type.Array(Type.Number()) const R = Value.Convert(T, 'A') Assert.IsEqual(R, ['A']) }) it('Should convert into array (object)', () => { const T = Type.Array( Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }), ) const R = Value.Convert(T, { x: '1', y: true, z: null }) Assert.IsEqual(R, [{ x: 1, y: 1, z: null }]) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/async-iterator.ts000066400000000000000000000007461505437577000270410ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/AsyncIterator', () => { const T = Type.AsyncIterator(Type.Any()) it('Should passthrough 1', () => { const V = (async function* () {})() const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) it('Should passthrough 2', () => { const V = 1 const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/bigint.ts000066400000000000000000000056041505437577000253470ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/BigInt', () => { it('Should convert bigint from string 1', () => { const T = Type.BigInt() const R = Value.Convert(T, '1') Assert.IsEqual(R, BigInt(1)) }) it('Should convert bigint from string 2', () => { const T = Type.BigInt() const R = Value.Convert(T, '3.14') Assert.IsEqual(R, BigInt(3)) }) it('Should convert bigint from string 3', () => { const T = Type.BigInt() const R = Value.Convert(T, 'true') Assert.IsEqual(R, BigInt(1)) }) it('Should convert bigint from string 4', () => { const T = Type.BigInt() const R = Value.Convert(T, 'false') Assert.IsEqual(R, BigInt(0)) }) it('Should convert bigint from string 5', () => { const T = Type.BigInt() const R = Value.Convert(T, '12345678901234567890') Assert.IsEqual(R, BigInt('12345678901234567890')) }) it('Should convert bigint from string 6', () => { const T = Type.BigInt() const R = Value.Convert(T, '-12345678901234567890') Assert.IsEqual(R, BigInt('-12345678901234567890')) }) it('Should convert bigint from string 7', () => { const T = Type.BigInt() const R = Value.Convert(T, '12345678901234567890.123') Assert.IsEqual(R, BigInt('12345678901234567890')) }) it('Should convert bigint from string 8', () => { const T = Type.BigInt() const R = Value.Convert(T, '-12345678901234567890.123') Assert.IsEqual(R, BigInt('-12345678901234567890')) }) it('Should convert bigint from number 1', () => { const T = Type.BigInt() const R = Value.Convert(T, 1) Assert.IsEqual(R, BigInt(1)) }) it('Should convert bigint from number 2', () => { const T = Type.BigInt() const R = Value.Convert(T, 3.14) Assert.IsEqual(R, BigInt(3)) }) it('Should convert bigint from number 3', () => { const T = Type.BigInt() const R = Value.Convert(T, Math.pow(2, 31)) Assert.IsEqual(R, BigInt(2147483648)) }) it('Should convert bigint from number 4', () => { const T = Type.BigInt() const R = Value.Convert(T, Number.MAX_SAFE_INTEGER) Assert.IsEqual(R, BigInt(9007199254740991)) }) it('Should convert bigint from number 5', () => { const T = Type.BigInt() const R = Value.Convert(T, 123456789012345.6789) Assert.IsEqual(R, BigInt(123456789012345)) }) it('Should convert bigint from number 6', () => { const T = Type.BigInt() const R = Value.Convert(T, -123456789012345.6789) Assert.IsEqual(R, BigInt(-123456789012345)) }) it('Should convert bigint from boolean 1', () => { const T = Type.BigInt() const R = Value.Convert(T, true) Assert.IsEqual(R, BigInt(1)) }) it('Should convert bigint from boolean 2', () => { const T = Type.BigInt() const R = Value.Convert(T, false) Assert.IsEqual(R, BigInt(0)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/boolean.ts000066400000000000000000000113731505437577000255120ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Boolean', () => { it('Should convert from string 1', () => { const T = Type.Boolean() const R = Value.Convert(T, '1') Assert.IsEqual(R, true) }) it('Should convert from string 2', () => { const T = Type.Boolean() const R = Value.Convert(T, '3.14') Assert.IsEqual(R, '3.14') }) it('Should convert from string 3', () => { const T = Type.Boolean() const R = Value.Convert(T, 'true') Assert.IsEqual(R, true) }) it('Should convert from string 4', () => { const T = Type.Boolean() const R = Value.Convert(T, 'false') Assert.IsEqual(R, false) }) it('Should convert from number 1', () => { const T = Type.Boolean() const R = Value.Convert(T, 1) Assert.IsEqual(R, true) }) it('Should convert from number 2', () => { const T = Type.Boolean() const R = Value.Convert(T, 3.14) Assert.IsEqual(R, 3.14) }) it('Should convert from number 3', () => { const T = Type.Boolean() const R = Value.Convert(T, 1.1) Assert.IsEqual(R, 1.1) }) it('Should convert from boolean 1', () => { const T = Type.Boolean() const R = Value.Convert(T, true) Assert.IsEqual(R, true) }) it('Should convert from boolean 2', () => { const T = Type.Boolean() const R = Value.Convert(T, false) Assert.IsEqual(R, false) }) // ---------------------------------------------------------- // Casts // ---------------------------------------------------------- it('Should convert string #1', () => { const value = 'hello' const result = Value.Convert(Type.Boolean(), value) Assert.IsEqual(result, 'hello') }) it('Should convert string #2', () => { const value = 'true' const result = Value.Convert(Type.Boolean(), value) Assert.IsEqual(result, true) }) it('Should convert string #3', () => { const value = 'TRUE' const result = Value.Convert(Type.Boolean(), value) Assert.IsEqual(result, true) }) it('Should convert string #4', () => { const value = 'false' const result = Value.Convert(Type.Boolean(), value) Assert.IsEqual(result, false) }) it('Should convert string #5', () => { const value = '0' const result = Value.Convert(Type.Boolean(), value) Assert.IsEqual(result, false) }) it('Should convert string #6', () => { const value = '1' const result = Value.Convert(Type.Boolean(), value) Assert.IsEqual(result, true) }) it('Should convert string #7', () => { const value = '0' const result = Value.Convert(Type.Boolean({ default: true }), value) Assert.IsEqual(result, false) }) it('Should convert string #8', () => { const value = '1' const result = Value.Convert(Type.Boolean({ default: false }), value) Assert.IsEqual(result, true) }) it('Should convert string #8', () => { const value = '2' const result = Value.Convert(Type.Boolean({ default: true }), value) Assert.IsEqual(result, '2') }) it('Should convert number #1', () => { const value = 0 const result = Value.Convert(Type.Boolean(), value) Assert.IsEqual(result, false) }) it('Should convert number #2', () => { const value = 1n const result = Value.Convert(Type.Boolean(), value) Assert.IsEqual(result, true) }) it('Should convert number #3', () => { const value = 1 const result = Value.Convert(Type.Boolean(), value) Assert.IsEqual(result, true) }) it('Should convert number #4', () => { const value = 2 const result = Value.Convert(Type.Boolean(), value) Assert.IsEqual(result, 2) }) it('Should convert number #5', () => { const value = 0 const result = Value.Convert(Type.Boolean({ default: true }), value) Assert.IsEqual(result, false) }) it('Should convert number #6', () => { const value = 1 const result = Value.Convert(Type.Boolean({ default: false }), value) Assert.IsEqual(result, true) }) it('Should convert number #7', () => { const value = 2 const result = Value.Convert(Type.Boolean({ default: true }), value) Assert.IsEqual(result, 2) }) it('Should convert true', () => { const value = true const result = Value.Convert(Type.Boolean(), value) Assert.IsEqual(result, true) }) it('Should convert false', () => { const value = false const result = Value.Convert(Type.Boolean(), value) Assert.IsEqual(result, false) }) it('Should convert object', () => { const value = {} const result = Value.Convert(Type.Boolean(), value) Assert.IsEqual(result, {}) }) it('Should convert array', () => { const value = [] as any[] const result = Value.Convert(Type.Boolean(), value) Assert.IsEqual(result, []) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/composite.ts000066400000000000000000000010261505437577000260670ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Composite', () => { it('Should convert properties', () => { // prettier-ignore const T = Type.Composite([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Boolean() }), Type.Object({ z: Type.Boolean() }) ]) const R = Value.Convert(T, { x: '42', y: 'true', z: 'hello' }) Assert.IsEqual(R, { x: 42, y: true, z: 'hello' }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/constructor.ts000066400000000000000000000007251505437577000264570ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Constructor', () => { const T = Type.Constructor([], Type.Any()) it('Should passthrough 1', () => { const V = class {} const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) it('Should passthrough 2', () => { const V = 1 const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/date.ts000066400000000000000000000035071505437577000250100ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Date', () => { it('Should convert from number', () => { const result = Value.Convert(Type.Date(), 123) as Date Assert.IsEqual(result.getTime(), 123) }) it('Should convert from numeric string', () => { const result = Value.Convert(Type.Date(), '123') as Date Assert.IsEqual(result.getTime(), 123) }) it('Should convert from boolean true (interpretted as numeric 1)', () => { const result = Value.Convert(Type.Date(), true) as Date Assert.IsEqual(result.getTime(), 1) }) it('Should convert from datetime string', () => { const result = Value.Convert(Type.Date(), '1980-02-03T01:02:03.000Z') as Date Assert.IsEqual(result.toISOString(), '1980-02-03T01:02:03.000Z') }) it('Should convert from datetime string without timezone', () => { const result = Value.Convert(Type.Date(), '1980-02-03T01:02:03') as Date Assert.IsEqual(result.toISOString(), '1980-02-03T01:02:03.000Z') }) it('Should convert from time with timezone', () => { const result = Value.Convert(Type.Date(), '01:02:03.000Z') as Date Assert.IsEqual(result.toISOString(), '1970-01-01T01:02:03.000Z') }) it('Should convert from time without timezone', () => { const result = Value.Convert(Type.Date(), '01:02:03') as Date Assert.IsEqual(result.toISOString(), '1970-01-01T01:02:03.000Z') }) it('Should convert from date string', () => { const result = Value.Convert(Type.Date(), '1980-02-03') as Date Assert.IsEqual(result.toISOString(), '1980-02-03T00:00:00.000Z') }) it('Should convert invalid strings to unix epoch 0', () => { const result = Value.Convert(Type.Date(), 'invalid-date') as Date Assert.IsEqual(result, 'invalid-date') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/enum.ts000066400000000000000000000003211505437577000250260ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Enum', () => { it('Should convert', () => {}) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/function.ts000066400000000000000000000007251505437577000257170ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Function', () => { const T = Type.Function([], Type.Any()) it('Should passthrough 1', () => { const V = function () {} const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) it('Should passthrough 2', () => { const V = 1 const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/import.ts000066400000000000000000000017421505437577000254040ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' // prettier-ignore describe('value/convert/Import', () => { it('Should convert properties', () => { const T = Type.Module({ A: Type.Object({ x: Type.Number(), y: Type.Boolean(), z: Type.Boolean() })}).Import('A') const R = Value.Convert(T, { x: '42', y: 'true', z: 'hello' }) Assert.IsEqual(R, { x: 42, y: true, z: 'hello' }) }) it('Should convert known properties', () => { const T = Type.Module({ A: Type.Object({ x: Type.Number(), y: Type.Boolean() })}).Import('A') const R = Value.Convert(T, { x: '42', y: 'true', z: 'hello' }) Assert.IsEqual(R, { x: 42, y: true, z: 'hello' }) }) it('Should not convert missing properties', () => { const T = Type.Module({ A: Type.Object({ x: Type.Number() }) }).Import('A') const R = Value.Convert(T, { }) Assert.IsEqual(R, { }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/index.ts000066400000000000000000000011461505437577000251770ustar00rootroot00000000000000import './any' import './array' import './async-iterator' import './bigint' import './boolean' import './composite' import './constructor' import './kind' import './date' import './enum' import './function' import './import' import './integer' import './intersect' import './iterator' import './keyof' import './literal' import './never' import './null' import './number' import './object' import './promise' import './recursive' import './record' import './regexp' import './string' import './symbol' import './tuple' import './uint8array' import './undefined' import './union' import './unknown' import './void' sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/integer.ts000066400000000000000000000063071505437577000255310ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Integer', () => { it('Should convert from string 1', () => { const T = Type.Integer() const R = Value.Convert(T, '3.14') Assert.IsEqual(R, 3) }) it('Should convert from string 2', () => { const T = Type.Integer() const R = Value.Convert(T, '42') Assert.IsEqual(R, 42) }) it('Should convert from boolean 1', () => { const T = Type.Integer() const R = Value.Convert(T, true) Assert.IsEqual(R, 1) }) it('Should convert from boolean 2', () => { const T = Type.Integer() const R = Value.Convert(T, false) Assert.IsEqual(R, 0) }) it('Should convert from number 1', () => { const T = Type.Integer() const R = Value.Convert(T, 3.14) Assert.IsEqual(R, 3) }) // ---------------------------------------------------------- // Casts // ---------------------------------------------------------- it('Should convert string #1', () => { const value = 'hello' const result = Value.Convert(Type.Integer(), value) Assert.IsEqual(result, 'hello') }) it('Should convert string #2', () => { const value = '3.14' const result = Value.Convert(Type.Integer(), value) Assert.IsEqual(result, 3) }) it('Should convert string #3', () => { const value = '-0' const result = Value.Convert(Type.Integer(), value) Assert.IsEqual(result, -0) }) it('Should convert string #4', () => { const value = '-100' const result = Value.Convert(Type.Integer(), value) Assert.IsEqual(result, -100) }) it('Should convert number', () => { const value = 42 const result = Value.Convert(Type.Integer(), value) Assert.IsEqual(result, 42) }) it('Should convert true', () => { const value = true const result = Value.Convert(Type.Integer(), value) Assert.IsEqual(result, 1) }) it('Should convert false', () => { const value = false const result = Value.Convert(Type.Integer(), value) Assert.IsEqual(result, 0) }) it('Should convert object', () => { const value = {} const result = Value.Convert(Type.Integer(), value) Assert.IsEqual(result, {}) }) it('Should convert array', () => { const value = [] as any[] const result = Value.Convert(Type.Integer(), value) Assert.IsEqual(result, []) }) // ---------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/1147 // ---------------------------------------------------------- it('Should convert large Integer 1', () => { const N = 1738213389080 const R = Value.Convert(Type.Integer(), N) Assert.IsEqual(R, N) }) it('Should convert large Integer 2', () => { const N = 1738213389080.5555 const R = Value.Convert(Type.Integer(), N) Assert.IsEqual(R, 1738213389080) }) it('Should convert large Integer 3', () => { const N = '1738213389080' const R = Value.Convert(Type.Integer(), N) Assert.IsEqual(R, 1738213389080) }) it('Should convert large Integer 3', () => { const N = '1738213389080.555' const R = Value.Convert(Type.Integer(), N) Assert.IsEqual(R, 1738213389080) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/intersect.ts000066400000000000000000000027471505437577000261000ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Intersect', () => { it('Should convert intersected objects', () => { // prettier-ignore const T = Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]) const R = Value.Convert(T, { x: '1', y: '2' }) Assert.IsEqual(R, { x: 1, y: 2 }) }) // ---------------------------------------------------------------- // Intersection Complex // ---------------------------------------------------------------- it('Should complex intersect 1', () => { // prettier-ignore const T = Type.Intersect([ Type.Number(), Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]) const R = Value.Convert(T, { x: '1', y: '2' }) Assert.IsEqual(R, { x: 1, y: 2 }) }) it('Should complex intersect 2', () => { // prettier-ignore const T = Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }), Type.Number(), ]) const R = Value.Convert(T, { x: '3', y: '4' }) Assert.IsEqual(R, { x: 3, y: 4 }) }) it('Should complex intersect 3', () => { // prettier-ignore const T = Type.Intersect([ Type.Number(), Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]) const R = Value.Convert(T, '123') Assert.IsEqual(R, 123) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/iterator.ts000066400000000000000000000007261505437577000257240ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Iterator', () => { const T = Type.Iterator(Type.Any()) it('Should passthrough 1', () => { const V = (function* () {})() const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) it('Should passthrough 2', () => { const V = 1 const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/keyof.ts000066400000000000000000000003221505437577000252000ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/KeyOf', () => { it('Should convert', () => {}) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/kind.ts000066400000000000000000000025421505437577000250160ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { TypeRegistry, Kind, TSchema } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Kind', () => { // --------------------------------------------------------- // Fixtures // --------------------------------------------------------- beforeEach(() => TypeRegistry.Set('Kind', () => true)) afterEach(() => TypeRegistry.Delete('Kind')) // --------------------------------------------------------- // Test // --------------------------------------------------------- it('Should not convert value 1', () => { const T = { [Kind]: 'Kind' } as TSchema const R = Value.Convert(T, true) Assert.IsEqual(R, true) }) it('Should not convert value 2', () => { const T = { [Kind]: 'Kind' } as TSchema const R = Value.Convert(T, 42) Assert.IsEqual(R, 42) }) it('Should not convert value 3', () => { const T = { [Kind]: 'Kind' } as TSchema const R = Value.Convert(T, 'hello') Assert.IsEqual(R, 'hello') }) it('Should not convert value 4', () => { const T = { [Kind]: 'Kind' } as TSchema const R = Value.Convert(T, { x: 1 }) Assert.IsEqual(R, { x: 1 }) }) it('Should not convert value 5', () => { const T = { [Kind]: 'Kind' } as TSchema const R = Value.Convert(T, [0, 1]) Assert.IsEqual(R, [0, 1]) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/literal.ts000066400000000000000000000047011505437577000255240ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/LiteralString', () => { it('Should convert from number 1', () => { const T = Type.Literal('1') const R = Value.Convert(T, 1) Assert.IsEqual(R, '1') }) it('Should convert from number 2', () => { const T = Type.Literal('1') const R = Value.Convert(T, 2) Assert.IsEqual(R, 2) }) it('Should convert from boolean', () => { const T = Type.Literal('true') const R = Value.Convert(T, true) Assert.IsEqual(R, 'true') }) }) describe('value/convert/LiteralNumber', () => { it('Should convert from number 1', () => { const T = Type.Literal(3.14) const R = Value.Convert(T, '3.14') Assert.IsEqual(R, 3.14) }) it('Should convert from number 2', () => { const T = Type.Literal(3.14) const R = Value.Convert(T, '3.15') Assert.IsEqual(R, '3.15') }) it('Should convert from boolean 1', () => { const T = Type.Literal(1) const R = Value.Convert(T, true) Assert.IsEqual(R, 1) }) it('Should convert from boolean 2', () => { const T = Type.Literal(0) const R = Value.Convert(T, false) Assert.IsEqual(R, 0) }) it('Should convert from boolean 3', () => { const T = Type.Literal(2) const R = Value.Convert(T, true) Assert.IsEqual(R, true) }) }) describe('value/convert/LiteralBoolean', () => { it('Should convert from number 1', () => { const T = Type.Literal(true) const R = Value.Convert(T, 3.14) Assert.IsEqual(R, 3.14) }) it('Should convert from number 2', () => { const T = Type.Literal(true) const R = Value.Convert(T, 1) Assert.IsEqual(R, true) }) it('Should convert from string 1', () => { const T = Type.Literal(true) const R = Value.Convert(T, 'true') Assert.IsEqual(R, true) }) it('Should convert from string 2', () => { const T = Type.Literal(false) const R = Value.Convert(T, 'false') Assert.IsEqual(R, false) }) it('Should convert from string 3', () => { const T = Type.Literal(true) const R = Value.Convert(T, '1') Assert.IsEqual(R, true) }) it('Should convert from string 4', () => { const T = Type.Literal(false) const R = Value.Convert(T, '0') Assert.IsEqual(R, false) }) it('Should convert from string 5', () => { const T = Type.Literal(false) const R = Value.Convert(T, '2') Assert.IsEqual(R, '2') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/never.ts000066400000000000000000000011031505437577000252000ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Never', () => { it('Should not convert 1', () => { const T = Type.Never() const R = Value.Convert(T, true) Assert.IsEqual(R, true) }) it('Should not convert 2', () => { const T = Type.Never() const R = Value.Convert(T, 42) Assert.IsEqual(R, 42) }) it('Should not convert 3', () => { const T = Type.Never() const R = Value.Convert(T, 'true') Assert.IsEqual(R, 'true') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/null.ts000066400000000000000000000010471505437577000250420ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Null', () => { const T = Type.Null() it('Should convert from string 1', () => { const R = Value.Convert(T, 'null') Assert.IsEqual(R, null) }) it('Should convert from string 2', () => { const R = Value.Convert(T, 'NULL') Assert.IsEqual(R, null) }) it('Should convert from string 3', () => { const R = Value.Convert(T, 'nil') Assert.IsEqual(R, 'nil') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/number.ts000066400000000000000000000044051505437577000253610ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Number', () => { const T = Type.Number() it('Should convert from string 1', () => { const R = Value.Convert(T, '3.14') Assert.IsEqual(R, 3.14) }) it('Should convert from string 2', () => { const R = Value.Convert(T, '42') Assert.IsEqual(R, 42) }) it('Should convert from boolean 1', () => { const R = Value.Convert(T, true) Assert.IsEqual(R, 1) }) it('Should convert from boolean 2', () => { const R = Value.Convert(T, false) Assert.IsEqual(R, 0) }) it('Should convert from number 1', () => { const R = Value.Convert(T, 3.14) Assert.IsEqual(R, 3.14) }) // ---------------------------------------------------------- // Casts // ---------------------------------------------------------- it('Should convert string #1', () => { const value = 'hello' const result = Value.Convert(Type.Number(), value) Assert.IsEqual(result, 'hello') }) it('Should convert string #2', () => { const value = '3.14' const result = Value.Convert(Type.Number(), value) Assert.IsEqual(result, 3.14) }) it('Should convert string #3', () => { const value = '-0' const result = Value.Convert(Type.Number(), value) Assert.IsEqual(result, -0) }) it('Should convert string #4', () => { const value = '-100' const result = Value.Convert(Type.Number(), value) Assert.IsEqual(result, -100) }) it('Should convert number', () => { const value = 42 const result = Value.Convert(Type.Number(), value) Assert.IsEqual(result, 42) }) it('Should convert true', () => { const value = true const result = Value.Convert(Type.Number(), value) Assert.IsEqual(result, 1) }) it('Should convert false', () => { const value = false const result = Value.Convert(Type.Number(), value) Assert.IsEqual(result, 0) }) it('Should convert object', () => { const value = {} const result = Value.Convert(Type.String(), value) Assert.IsEqual(result, {}) }) it('Should convert array', () => { const value = [] as any[] const result = Value.Convert(Type.String(), value) Assert.IsEqual(result, []) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/object.ts000066400000000000000000000016041505437577000253350ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' // prettier-ignore describe('value/convert/Object', () => { it('Should convert properties', () => { const T = Type.Object({ x: Type.Number(), y: Type.Boolean(), z: Type.Boolean() }) const R = Value.Convert(T, { x: '42', y: 'true', z: 'hello' }) Assert.IsEqual(R, { x: 42, y: true, z: 'hello' }) }) it('Should convert known properties', () => { const T = Type.Object({ x: Type.Number(), y: Type.Boolean() }) const R = Value.Convert(T, { x: '42', y: 'true', z: 'hello' }) Assert.IsEqual(R, { x: 42, y: true, z: 'hello' }) }) it('Should not convert missing properties', () => { const T = Type.Object({ x: Type.Number() }) const R = Value.Convert(T, { }) Assert.IsEqual(R, { }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/promise.ts000066400000000000000000000007231505437577000255460ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Promise', () => { const T = Type.Promise(Type.Any()) it('Should passthrough 1', () => { const V = Promise.resolve(1) const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) it('Should passthrough 2', () => { const V = 1 const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/record.ts000066400000000000000000000033631505437577000253510ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Record', () => { it('Should convert record value to numeric', () => { const T = Type.Record(Type.String(), Type.Number()) const V = Value.Convert(T, { x: '42', y: '24', z: 'hello' }) Assert.IsEqual(V, { x: 42, y: 24, z: 'hello' }) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/930 // ---------------------------------------------------------------- it('Should convert record union 1', () => { const T = Type.Union([Type.Null(), Type.Record(Type.Number(), Type.Any())]) const V = Value.Convert(T, {}) Assert.IsEqual(V, {}) }) it('Should convert record union 2', () => { const T = Type.Union([Type.Record(Type.Number(), Type.Any()), Type.Null()]) const V = Value.Convert(T, {}) Assert.IsEqual(V, {}) }) it('Should convert record union 3', () => { const T = Type.Union([Type.Null(), Type.Record(Type.Number(), Type.Any())]) const V = Value.Convert(T, null) Assert.IsEqual(V, null) }) it('Should convert record union 4', () => { const T = Type.Union([Type.Record(Type.Number(), Type.Any()), Type.Null()]) const V = Value.Convert(T, null) Assert.IsEqual(V, null) }) it('Should convert record union 5', () => { const T = Type.Union([Type.Null(), Type.Record(Type.Number(), Type.Any())]) const V = Value.Convert(T, 'NULL') Assert.IsEqual(V, null) }) it('Should convert record union 6', () => { const T = Type.Union([Type.Record(Type.Number(), Type.Any()), Type.Null()]) const V = Value.Convert(T, 'NULL') Assert.IsEqual(V, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/recursive.ts000066400000000000000000000003261505437577000260760ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Recursive', () => { it('Should convert', () => {}) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/regexp.ts000066400000000000000000000003231505437577000253560ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/RegExp', () => { it('Should convert', () => {}) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/string.ts000066400000000000000000000041451505437577000254000ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/String', () => { const T = Type.String() it('Should convert from number 1', () => { const R = Value.Convert(T, 3.14) Assert.IsEqual(R, '3.14') }) it('Should convert from number 2', () => { const R = Value.Convert(T, 3) Assert.IsEqual(R, '3') }) it('Should convert from boolean 1', () => { const R = Value.Convert(T, true) Assert.IsEqual(R, 'true') }) it('Should convert from boolean 2', () => { const R = Value.Convert(T, false) Assert.IsEqual(R, 'false') }) it('Should convert from bigint', () => { const R = Value.Convert(T, BigInt(12345)) Assert.IsEqual(R, '12345') }) it('Should convert from symbol', () => { const R = Value.Convert(T, Symbol(12345)) Assert.IsEqual(R, '12345') }) // ---------------------------------------------------------- // Casts // ---------------------------------------------------------- it('Should convert string', () => { const value = 'hello' const result = Value.Convert(Type.String(), value) Assert.IsEqual(result, 'hello') }) it('Should convert number #1', () => { const value = 42 const result = Value.Convert(Type.String(), value) Assert.IsEqual(result, '42') }) it('Should convert number #2', () => { const value = 42n const result = Value.Convert(Type.String(), value) Assert.IsEqual(result, '42') }) it('Should convert true', () => { const value = true const result = Value.Convert(Type.String(), value) Assert.IsEqual(result, 'true') }) it('Should convert false', () => { const value = false const result = Value.Convert(Type.String(), value) Assert.IsEqual(result, 'false') }) it('Should convert object', () => { const value = {} const result = Value.Convert(Type.String(), value) Assert.IsEqual(result, {}) }) it('Should convert array', () => { const value = [] as any[] const result = Value.Convert(Type.String(), value) Assert.IsEqual(result, []) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/symbol.ts000066400000000000000000000007341505437577000253770ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Symbol', () => { const T = Type.Symbol() it('Should convert from number 1', () => { const R = Value.Convert(T, 3.14) as Symbol Assert.IsEqual(R.description, '3.14') }) it('Should convert from number 2', () => { const R = Value.Convert(T, 3) as Symbol Assert.IsEqual(R.description, '3') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/tuple.ts000066400000000000000000000013171505437577000252210ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Tuple', () => { it('Should convert from Array 1', () => { const T = Type.Tuple([Type.Number(), Type.Number()]) const R = Value.Convert(T, ['1', 'true']) Assert.IsEqual(R, [1, 1]) }) it('Should convert from Array 2', () => { const T = Type.Tuple([Type.Number(), Type.Number()]) const R = Value.Convert(T, ['1']) Assert.IsEqual(R, [1]) }) it('Should convert from Array 3', () => { const T = Type.Tuple([Type.Number(), Type.Number()]) const R = Value.Convert(T, ['1', '2', '3']) Assert.IsEqual(R, [1, 2, '3']) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/uint8array.ts000066400000000000000000000004051505437577000261730ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Uint8Array', () => { it('Should convert from Array', () => { const T = Type.Uint8Array() }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/undefined.ts000066400000000000000000000007121505437577000260270ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Undefined', () => { const T = Type.Undefined() it('Should convert from string 1', () => { const R = Value.Convert(T, 'undefined') Assert.IsEqual(R, undefined) }) it('Should convert from string 2', () => { const R = Value.Convert(T, 'hello') Assert.IsEqual(R, 'hello') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/union.ts000066400000000000000000000100401505437577000252110ustar00rootroot00000000000000import { Convert, Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Union', () => { it('Should convert union variant', () => { const T = Type.Object({ x: Type.Union([Type.Number(), Type.Null()]), }) const V1 = Value.Convert(T, { x: '42' }) const V2 = Value.Convert(T, { x: 'null' }) const V3 = Value.Convert(T, { x: 'hello' }) Assert.IsEqual(V1, { x: 42 }) Assert.IsEqual(V2, { x: null }) Assert.IsEqual(V3, { x: 'hello' }) }) it('Should convert first variant in ambiguous conversion', () => { const T = Type.Object({ x: Type.Union([Type.Boolean(), Type.Number()]), }) const V1 = Value.Convert(T, { x: '1' }) Assert.IsEqual(V1, { x: true }) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/787 // ---------------------------------------------------------------- // prettier-ignore it('Should convert Intersect Union', () => { const T = Type.Intersect([ Type.Union([ Type.Object({ a: Type.Number() }), Type.Object({ b: Type.Number() }), ]), Type.Object({ c: Type.Number() }), ]) const A = Convert(T, { a: '1', c: '2' }) const B = Convert(T, { b: '1', c: '2' }) const C = Convert(T, { a: '1', b: '2', c: '3' }) Assert.IsEqual(A, { a: 1, c: 2 }) Assert.IsEqual(B, { b: 1, c: 2 }) Assert.IsEqual(C, { a: 1, b: '2', c: 3 }) // note: matching on first }) it('Should preserve number type in string-first union when value already matches', () => { const T = Type.Union([Type.String(), Type.Number()]) const numValue = 42 const strValue = 'hello' const A = Value.Convert(T, numValue) const B = Value.Convert(T, strValue) Assert.IsEqual(typeof A, 'number') Assert.IsEqual(typeof B, 'string') Assert.IsEqual(A, 42) Assert.IsEqual(B, 'hello') }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/1281 // Union conversion should preserve original type if valid // ---------------------------------------------------------------- it('Should preserve original type when value already matches union variant', () => { const T1 = Type.Object({ data: Type.Array(Type.Record(Type.String(), Type.Union([Type.String(), Type.Number(), Type.Null()]))), }) const T2 = Type.Object({ data: Type.Array(Type.Record(Type.String(), Type.Union([Type.Number(), Type.String(), Type.Null()]))), }) const testData = { data: [{ key1: 'hello', key2: 42, key3: null }], } const A = Value.Convert(T1, testData) const B = Value.Convert(T2, testData) // Both should preserve the original number type Assert.IsEqual(typeof (A as any).data[0].key2, 'number') Assert.IsEqual(typeof (B as any).data[0].key2, 'number') Assert.IsEqual((A as any).data[0].key2, 42) Assert.IsEqual((B as any).data[0].key2, 42) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/1295 // ---------------------------------------------------------------- it('Should guard against Array conversion in Object', () => { const T = Type.Union([ Type.Object({ type: Type.Literal('A'), values: Type.Union([Type.String(), Type.Number()]), }), Type.Object({ type: Type.Literal('B'), values: Type.String(), }), ]) const converted = Value.Convert(T, [{ type: 'A', values: 1 }]) Assert.IsEqual(converted, [{ type: 'A', values: 1 }]) }) it('Should guard against Array conversion in Record', () => { const T = Type.Union([Type.Record(Type.String({ pattern: '^values$' }), Type.Union([Type.String(), Type.Number()])), Type.Record(Type.String({ pattern: '^type$' }), Type.Union([Type.String(), Type.Number()]))]) const converted = Value.Convert(T, [{ type: 'A', values: 1 }]) Assert.IsEqual(converted, [{ type: 'A', values: 1 }]) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/unknown.ts000066400000000000000000000020551505437577000255670ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Unknown', () => { const T = Type.Unknown() it('Should convert null', () => { const V = null const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) it('Should convert undefined', () => { const V = undefined const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) it('Should convert string', () => { const V = 'hello' const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) it('Should convert number', () => { const V = 42 const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) it('Should convert boolean', () => { const V = true const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) it('Should convert object', () => { const V = { x: 1 } const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) it('Should convert array', () => { const V = [1, 2, 3] const R = Value.Convert(T, V) Assert.IsEqual(R, V) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/convert/void.ts000066400000000000000000000003211505437577000250230ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/convert/Void', () => { it('Should convert', () => {}) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/000077500000000000000000000000001505437577000233015ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/value/create/_deferred.ts000066400000000000000000000005061505437577000255710ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Deferred', () => { it('Should use deferred value', () => { const T = Type.Any({ default: () => 1 }) const R = Value.Create(T) Assert.IsEqual(R, 1) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/any.ts000066400000000000000000000006211505437577000244370ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Any', () => { it('Should create value', () => { const T = Type.Any() Assert.IsEqual(Value.Create(T), {}) }) it('Should create default', () => { const T = Type.Any({ default: 1 }) Assert.IsEqual(Value.Create(T), 1) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/argument.ts000066400000000000000000000004431505437577000254740ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Argument', () => { it('Should create value', () => { const T = Type.Argument(0) Assert.IsEqual(Value.Create(T), {}) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/array.ts000066400000000000000000000011331505437577000247650ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Array', () => { it('Should create value', () => { const T = Type.Array(Type.String()) Assert.IsEqual(Value.Create(T), []) }) it('Should create default', () => { const T = Type.Array(Type.String(), { default: ['1'] }) Assert.IsEqual(Value.Create(T), ['1']) }) it('Should create with minItems', () => { const T = Type.Array(Type.String(), { minItems: 4 }) Assert.IsEqual(Value.Create(T), ['', '', '', '']) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/async-iterator.ts000066400000000000000000000007701505437577000266210ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/AsyncIterator', () => { it('Should create value', () => { const T = Type.AsyncIterator(Type.Any()) const R = Value.Create(T) Assert.IsTrue(Symbol.asyncIterator in R) }) it('Should create default', () => { const T = Type.AsyncIterator(Type.Any(), { default: 1 }) const R = Value.Create(T) Assert.IsEqual(R, 1) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/bigint.ts000066400000000000000000000006471505437577000251340ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/BigInt', () => { it('Should create value', () => { const T = Type.BigInt() Assert.IsEqual(Value.Create(T), BigInt(0)) }) it('Should create default', () => { const T = Type.BigInt({ default: true }) Assert.IsEqual(Value.Create(T), true) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/boolean.ts000066400000000000000000000006461505437577000252760ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Boolean', () => { it('Should create value', () => { const T = Type.Boolean() Assert.IsEqual(Value.Create(T), false) }) it('Should create default', () => { const T = Type.Boolean({ default: true }) Assert.IsEqual(Value.Create(T), true) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/composite.ts000066400000000000000000000027631505437577000256630ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Composite', () => { it('Should create value', () => { const A = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }) const B = Type.Object({ a: Type.Number(), b: Type.Number(), c: Type.Number(), }) const T = Type.Composite([A, B]) Assert.IsEqual(Value.Create(T), { x: 0, y: 0, z: 0, a: 0, b: 0, c: 0, }) }) it('Should create default', () => { const A = Type.Object({ x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), z: Type.Number({ default: 3 }), }) const B = Type.Object({ a: Type.Number({ default: 4 }), b: Type.Number({ default: 5 }), c: Type.Number({ default: 6 }), }) const T = Type.Composite([A, B]) Assert.IsEqual(Value.Create(T), { x: 1, y: 2, z: 3, a: 4, b: 5, c: 6, }) }) it('Should create default and omit optionals', () => { const A = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }) const B = Type.Object({ a: Type.Optional(Type.Number()), b: Type.Optional(Type.Number()), c: Type.Optional(Type.Number()), }) const T = Type.Composite([A, B]) Assert.IsEqual(Value.Create(T), { x: 0, y: 0, z: 0, }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/constructor.ts000066400000000000000000000015651505437577000262450ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Constructor', () => { it('Should create value', () => { const T = Type.Constructor( [], Type.Object({ test: Type.Function([], Type.Number({ default: 123 })), }), ) const C = Value.Create(T) const I = new C() const R = I.test() Assert.IsEqual(R, 123) }) it('Should create default', () => { const T = Type.Constructor( [], Type.Object({ test: Type.Function([], Type.Number({ default: 123 })), }), { default: () => class { test() { return 321 } }, }, ) const C = Value.Create(T) const I = new C() const R = I.test() Assert.IsEqual(R, 321) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/date.ts000066400000000000000000000017211505437577000245670ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Date', () => { it('Should create value', () => { const T = Type.Date() const A = Value.Create(T) const B = new Date() Assert.InRange(A.getTime(), B.getTime(), 1000) }) it('Should create default', () => { const T = Type.Date({ default: new Date(1001) }) const A = Value.Create(T) const B = new Date(1001) Assert.IsEqual(A, B) }) it('Should create value nested', () => { const T = Type.Object({ value: Type.Date() }) const A = Value.Create(T) const B = { value: new Date() } Assert.InRange(A.value.getTime(), B.value.getTime(), 1000) }) it('Should create default nested', () => { const T = Type.Object({ value: Type.Date({ default: new Date(1001) }) }) const A = Value.Create(T) const B = { value: new Date(1001) } Assert.IsEqual(A, B) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/enum.ts000066400000000000000000000007701505437577000246210ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Boolean', () => { it('Should create value', () => { enum Foo { A, B, } const T = Type.Enum(Foo) Assert.IsEqual(Value.Create(T), Foo.A) }) it('Should create default', () => { enum Foo { A, B, } const T = Type.Enum(Foo, { default: Foo.B }) Assert.IsEqual(Value.Create(T), Foo.B) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/function.ts000066400000000000000000000010711505437577000254750ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Function', () => { it('Should create value', () => { const T = Type.Function([], Type.Number({ default: 123 })) const F = Value.Create(T) const R = F() Assert.IsEqual(R, 123) }) it('Should create default', () => { const T = Type.Function([], Type.Number({ default: 123 }), { default: () => () => 321 }) const F = Value.Create(T) const R = F() Assert.IsEqual(R, 321) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/import.ts000066400000000000000000000046261505437577000251730ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Import', () => { it('Should create value', () => { const T = Type.Module({ A: Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }), }).Import('A') Assert.IsEqual(Value.Create(T), { x: 0, y: 0, z: 0, }) }) it('Should create value with optional properties', () => { const T = Type.Module({ A: Type.Object({ x: Type.Optional(Type.Number()), y: Type.Optional(Type.Number()), z: Type.Optional(Type.Number()), }), }).Import('A') Assert.IsEqual(Value.Create(T), {}) }) it('Should create default with default properties', () => { const T = Type.Module({ A: Type.Object({ x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), z: Type.Number({ default: 3 }), }), }).Import('A') Assert.IsEqual(Value.Create(T), { x: 1, y: 2, z: 3, }) }) it('Should create nested object', () => { const T = Type.Module({ A: Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), w: Type.Object({ x: Type.Number({ default: 7 }), y: Type.Number(), z: Type.Number(), }), }), }).Import('A') Assert.IsEqual(Value.Create(T), { x: 0, y: 0, z: 0, w: { x: 7, y: 0, z: 0 }, }) }) it('Should create with default', () => { const T = Type.Module({ A: Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { default: { x: 1, y: 2, z: 3 } }, ), }).Import('A') Assert.IsEqual(Value.Create(T), { x: 1, y: 2, z: 3, }) }) // ---------------------------------------------------------------- // Mutation // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/726 it('Should clone defaults on assignment - no mutation', () => { const T = Type.Module({ A: Type.Object( { x: Type.Number(), }, { default: { x: 1 } }, ), }).Import('A') const V = Value.Create(T) V.x = 123 Assert.IsEqual(T.$defs.A.default, { x: 1 }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/index.ts000066400000000000000000000012661505437577000247650ustar00rootroot00000000000000import './_deferred' import './any' import './argument' import './array' import './async-iterator' import './bigint' import './boolean' import './composite' import './constructor' import './date' import './enum' import './function' import './import' import './integer' import './intersect' import './iterator' import './keyof' import './kind' import './literal' import './never' import './not' import './null' import './number' import './object' import './recursive' import './ref' import './record' import './regexp' import './string' import './symbol' import './template-literal' import './tuple' import './uint8array' import './undefined' import './union' import './unknown' import './void' sinclairzx81-typebox-e0ec98c/test/runtime/value/create/integer.ts000066400000000000000000000006341505437577000253110ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Integer', () => { it('Should create value', () => { const T = Type.Integer() Assert.IsEqual(Value.Create(T), 0) }) it('Should create default', () => { const T = Type.Integer({ default: 7 }) Assert.IsEqual(Value.Create(T), 7) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/intersect.ts000066400000000000000000000045671505437577000256650ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Intersect', () => { it('Should create value', () => { const T = Type.Intersect([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })]) const R = Value.Create(T) Assert.IsEqual(R, { x: 0, y: 0 }) }) it('Should create value with default', () => { const T = Type.Intersect([Type.Object({ x: Type.Number({ default: 100 }) }), Type.Object({ y: Type.Number({ default: 200 }) })]) const R = Value.Create(T) Assert.IsEqual(R, { x: 100, y: 200 }) }) it('Should create for overlapping intersection', () => { const T = Type.Intersect([Type.Object({ x: Type.Number() }), Type.Object({ x: Type.Number(), y: Type.Number() })]) const R = Value.Create(T) Assert.IsEqual(R, { x: 0, y: 0 }) }) it('Should create with last intersected overlapping default', () => { const T = Type.Intersect([Type.Object({ x: Type.Number({ default: 1 }) }), Type.Object({ x: Type.Number({ default: 2 }), y: Type.Number() })]) const R = Value.Create(T) Assert.IsEqual(R, { x: 2, y: 0 }) }) it('Should throw for non-constructable intersection 1', () => { const T = Type.Intersect([Type.Object({ x: Type.Number() }), Type.Object({ x: Type.String() })]) Assert.Throws(() => Value.Create(T)) }) it('Should throw for non-constructable intersection 2', () => { const T = Type.Intersect([Type.String(), Type.Number()]) Assert.Throws(() => Value.Create(T)) }) it('Should not throw for non-constructable intersection with default', () => { const T = Type.Intersect([Type.String(), Type.Number()], { default: 'hello' }) const R = Value.Create(T) Assert.IsEqual(R, 'hello') }) it('Should create from nested intersection', () => { const T = Type.Intersect([ Type.Object({ x: Type.Number({ default: 1 }), }), Type.Intersect([ Type.Object({ y: Type.Number({ default: 2 }), }), Type.Object({ z: Type.Number({ default: 3 }), }), ]), ]) const R = Value.Create(T) Assert.IsEqual(R, { x: 1, y: 2, z: 3 }) }) it('Should create non varying primitive', () => { const T = Type.Intersect([Type.Number(), Type.Number(), Type.Number()]) const R = Value.Create(T) Assert.IsEqual(R, 0) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/iterator.ts000066400000000000000000000007441505437577000255070ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Iterator', () => { it('Should create value', () => { const T = Type.Iterator(Type.Any()) const R = Value.Create(T) Assert.IsTrue(Symbol.iterator in R) }) it('Should create default', () => { const T = Type.Iterator(Type.Any(), { default: 1 }) const R = Value.Create(T) Assert.IsEqual(R, 1) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/keyof.ts000066400000000000000000000011221505437577000247620ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/KeyOf', () => { it('Should create value', () => { const T = Type.KeyOf( Type.Object({ x: Type.Number(), y: Type.Number(), }), ) Assert.IsEqual(Value.Create(T), 'x') }) it('Should create default', () => { const T = Type.KeyOf( Type.Object({ x: Type.Number(), y: Type.Number(), }), { default: 'y' }, ) Assert.IsEqual(Value.Create(T), 'y') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/kind.ts000066400000000000000000000016571505437577000246070ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type, Kind, TypeRegistry } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Kind', () => { // --------------------------------------------------------- // Fixtures // --------------------------------------------------------- beforeEach(() => TypeRegistry.Set('Kind', () => true)) afterEach(() => TypeRegistry.Delete('Kind')) // --------------------------------------------------------- // Tests // --------------------------------------------------------- it('Should create custom value with default', () => { const T = Type.Unsafe({ [Kind]: 'Kind', default: 'hello' }) Assert.IsEqual(Value.Create(T), 'hello') }) it('Should throw when no default value is specified', () => { TypeRegistry.Set('Kind', () => true) const T = Type.Unsafe({ [Kind]: 'Kind' }) Assert.Throws(() => Value.Create(T)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/literal.ts000066400000000000000000000013141505437577000253040ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Literal', () => { it('Should create literal string', () => { const T = Type.Literal('hello') Assert.IsEqual(Value.Create(T), 'hello') }) it('Should create literal number', () => { const T = Type.Literal(1) Assert.IsEqual(Value.Create(T), 1) }) it('Should create literal boolean', () => { const T = Type.Literal(true) Assert.IsEqual(Value.Create(T), true) }) it('Should create literal from default value', () => { const T = Type.Literal(true, { default: 'hello' }) Assert.IsEqual(Value.Create(T), 'hello') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/never.ts000066400000000000000000000004351505437577000247720ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Never', () => { it('Should create value', () => { const T = Type.Never() Assert.Throws(() => Value.Create(T)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/not.ts000066400000000000000000000012171505437577000244520ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Not', () => { it('Should throw without default value', () => { const T = Type.Not(Type.String()) Assert.Throws(() => Value.Create(T)) }) it('Should create value with default inner', () => { const T = Type.Not(Type.String(), { default: 100 }) const R = Value.Create(T) Assert.IsEqual(R, 100) }) it('Should create value with default outer', () => { const T = Type.Not(Type.String(), { default: 100 }) const R = Value.Create(T) Assert.IsEqual(R, 100) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/null.ts000066400000000000000000000006621505437577000246270ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Null', () => { it('Should create value', () => { const T = Type.Null() Assert.IsEqual(Value.Create(T), null) }) it('Should create null from default value', () => { const T = Type.Null({ default: 'hello' }) Assert.IsEqual(Value.Create(T), 'hello') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/number.ts000066400000000000000000000006311505437577000251410ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Number', () => { it('Should create value', () => { const T = Type.Number() Assert.IsEqual(Value.Create(T), 0) }) it('Should create default', () => { const T = Type.Number({ default: 7 }) Assert.IsEqual(Value.Create(T), 7) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/object.ts000066400000000000000000000041121505437577000251150ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Object', () => { it('Should create value', () => { const T = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }) Assert.IsEqual(Value.Create(T), { x: 0, y: 0, z: 0, }) }) it('Should create value with optional properties', () => { const T = Type.Object({ x: Type.Optional(Type.Number()), y: Type.Optional(Type.Number()), z: Type.Optional(Type.Number()), }) Assert.IsEqual(Value.Create(T), {}) }) it('Should create default with default properties', () => { const T = Type.Object({ x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), z: Type.Number({ default: 3 }), }) Assert.IsEqual(Value.Create(T), { x: 1, y: 2, z: 3, }) }) it('Should create nested object', () => { const T = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), w: Type.Object({ x: Type.Number({ default: 7 }), y: Type.Number(), z: Type.Number(), }), }) Assert.IsEqual(Value.Create(T), { x: 0, y: 0, z: 0, w: { x: 7, y: 0, z: 0 }, }) }) it('Should create with default', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { default: { x: 1, y: 2, z: 3 } }, ) Assert.IsEqual(Value.Create(T), { x: 1, y: 2, z: 3, }) }) // ---------------------------------------------------------------- // Mutation // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/726 it('Should clone defaults on assignment - no mutation', () => { const T = Type.Object( { x: Type.Number(), }, { default: { x: 1 } }, ) const V = Value.Create(T) V.x = 123 Assert.IsEqual(T.default, { x: 1 }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/record.ts000066400000000000000000000010021505437577000251200ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Record', () => { it('Should create value', () => { const T = Type.Record(Type.String(), Type.Object({})) Assert.IsEqual(Value.Create(T), {}) }) it('Should create default', () => { const T = Type.Record(Type.String(), Type.Object({}), { default: { x: {}, }, }) Assert.IsEqual(Value.Create(T), { x: {} }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/recursive.ts000066400000000000000000000025171505437577000256650ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Recursive', () => { it('Should create value', () => { const T = Type.Recursive((This) => Type.Object({ id: Type.String(), nodes: Type.Array(This), }), ) Assert.IsEqual(Value.Create(T), { id: '', nodes: [], }) }) it('Should create default', () => { const T = Type.Recursive( (This) => Type.Object({ id: Type.String(), nodes: Type.Array(This), }), { default: 7 }, ) Assert.IsEqual(Value.Create(T), 7) }) it('Should throw on infinite type', () => { const T = Type.Recursive((This) => Type.Object({ x: This, }), ) Assert.Throws(() => Value.Create(T)) }) it('Should not throw on recursive type when terminating sub type proceeds self', () => { const T = Type.Recursive((This) => Type.Object({ x: Type.Union([Type.Null(), This]), }), ) Assert.IsEqual(Value.Create(T), { x: null }) }) it('Should not throw on recursive type when self is optional', () => { const T = Type.Recursive((This) => Type.Object({ x: Type.Optional(This), }), ) Assert.IsEqual(Value.Create(T), {}) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/ref.ts000066400000000000000000000020231505437577000244220ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Ref', () => { it('Should throw if target is undefined', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { $id: 'T', default: 'target' }, ) const R = Type.Ref('T') Assert.Throws(() => Value.Create(R)) }) it('Should create ref default if ref default is defined', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), z: Type.Number(), }, { $id: 'T', default: 'target' }, ) const R = Type.Ref('T', { default: 'override' }) Assert.IsEqual(Value.Create(R), 'override') // terminated at R default value }) it('Should dereference remote schema via $ref', () => { const R = Type.Number({ $id: 'R' }) const T = Type.Object({ x: Type.Ref('R') }) Assert.IsEqual(Value.Create(T, [R]), { x: 0 }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/regexp.ts000066400000000000000000000013421505437577000251430ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/RegEx', () => { it('Should throw without a default value', () => { Assert.Throws(() => { const T = Type.RegExp(/foo/) Value.Create(T) }) }) it('Should create default', () => { const T = Type.RegExp(/foo/, { default: 'foo' }) Assert.IsEqual(Value.Create(T), 'foo') }) // ---------------------------------------------------------------- // Throw // ---------------------------------------------------------------- it('Should throw with no default', () => { const T = Type.RegExp(/foo/) Assert.Throws(() => Value.Create(T)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/string.ts000066400000000000000000000006461505437577000251650ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/String', () => { it('Should create value', () => { const T = Type.String() Assert.IsEqual(Value.Create(T), '') }) it('Should create default', () => { const T = Type.String({ default: 'hello' }) Assert.IsEqual(Value.Create(T), 'hello') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/symbol.ts000066400000000000000000000006751505437577000251660ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Symbol', () => { it('Should create value', () => { const T = Type.Symbol() const V = Value.Create(T) Assert.IsEqual(typeof V, 'symbol') }) it('Should create default', () => { const T = Type.Symbol({ default: true }) Assert.IsEqual(Value.Create(T), true) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/template-literal.ts000066400000000000000000000023511505437577000271170ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/TemplateLiteral', () => { it('Should create pattern 1', () => { const T = Type.TemplateLiteral([Type.Literal('A')]) const V = Value.Create(T) Assert.IsEqual(V, 'A') }) it('Should create pattern 2', () => { const T = Type.TemplateLiteral([Type.Literal('A'), Type.Literal('B')]) const V = Value.Create(T) Assert.IsEqual(V, 'AB') }) it('Should create pattern 3 (first only)', () => { const T = Type.TemplateLiteral([Type.Literal('A'), Type.Union([Type.Literal('B'), Type.Literal('C')])]) const V = Value.Create(T) Assert.IsEqual(V, 'AB') }) it('Should create pattern 4 (first only)', () => { const T = Type.TemplateLiteral([Type.Boolean()]) const V = Value.Create(T) Assert.IsEqual(V, 'true') }) it('Should throw on infinite pattern', () => { const T = Type.TemplateLiteral([Type.Number()]) Assert.Throws(() => Value.Create(T)) }) it('Should create on infinite pattern with default', () => { const T = Type.TemplateLiteral([Type.Number()], { default: 42 }) const V = Value.Create(T) Assert.IsEqual(V, 42) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/tuple.ts000066400000000000000000000016351505437577000250070ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Tuple', () => { it('Should create value', () => { const T = Type.Tuple([Type.Number(), Type.String()]) Assert.IsEqual(Value.Create(T), [0, '']) }) it('Should create default', () => { const T = Type.Tuple([Type.Number(), Type.String()], { default: [7, 'hello'] }) Assert.IsEqual(Value.Create(T), [7, 'hello']) }) it('Should create default elements', () => { const T = Type.Tuple([Type.Number({ default: 7 }), Type.String({ default: 'hello' })]) Assert.IsEqual(Value.Create(T), [7, 'hello']) }) it('Should create default by overriding elements', () => { const T = Type.Tuple([Type.Number({ default: 7 }), Type.String({ default: 'hello' })], { default: [32, 'world'] }) Assert.IsEqual(Value.Create(T), [32, 'world']) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/uint8array.ts000066400000000000000000000025101505437577000257550ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Uint8Array', () => { it('Should create value', () => { const T = Type.Uint8Array() const value = Value.Create(T) Assert.IsInstanceOf(value, Uint8Array) Assert.IsEqual(value.length, 0) }) it('Should create default', () => { const T = Type.Uint8Array({ default: new Uint8Array([0, 1, 2, 3]) }) const value = Value.Create(T) Assert.IsInstanceOf(value, Uint8Array) Assert.IsEqual(value.length, 4) Assert.IsEqual([value[0], value[1], value[2], value[3]], [0, 1, 2, 3]) }) it('Should create with minByteLength', () => { const T = Type.Uint8Array({ minByteLength: 4 }) const value = Value.Create(T) Assert.IsInstanceOf(value, Uint8Array) Assert.IsEqual(value.length, 4) Assert.IsEqual([value[0], value[1], value[2], value[3]], [0, 0, 0, 0]) }) it('Should create value nested', () => { const T = Type.Object({ value: Type.Uint8Array() }) Assert.IsEqual(Value.Create(T), { value: new Uint8Array() }) }) it('Should create default nested', () => { const T = Type.Object({ value: Type.Date({ default: new Uint8Array([1, 2, 3, 4]) }) }) Assert.IsEqual(Value.Create(T), { value: new Uint8Array([1, 2, 3, 4]) }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/undefined.ts000066400000000000000000000007071505437577000256160ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Undefined', () => { it('Should create value', () => { const T = Type.Undefined() Assert.IsEqual(Value.Create(T), undefined) }) it('Should create value from default value', () => { const T = Type.Undefined({ default: 'hello' }) Assert.IsEqual(Value.Create(T), 'hello') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/union.ts000066400000000000000000000022761505437577000250100ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Union', () => { it('Should create union Object', () => { const A = Type.Object({ type: Type.Literal('A'), x: Type.Number(), y: Type.Number(), z: Type.Number(), }) const B = Type.Object({ type: Type.Literal('B'), x: Type.String(), y: Type.String(), z: Type.String(), }) const T = Type.Union([A, B]) Assert.IsEqual(Value.Create(T), { type: 'A', x: 0, y: 0, z: 0, }) }) it('Should create union Null', () => { const A = Type.Null() const B = Type.Object({ type: Type.Literal('B'), x: Type.String(), y: Type.String(), z: Type.String(), }) const T = Type.Union([A, B]) Assert.IsEqual(Value.Create(T), null) }) it('Should create union Array', () => { const A = Type.Array(Type.String()) const B = Type.Object({ type: Type.Literal('B'), x: Type.String(), y: Type.String(), z: Type.String(), }) const T = Type.Union([A, B]) Assert.IsEqual(Value.Create(T), []) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/unknown.ts000066400000000000000000000006351505437577000253540ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Unknown', () => { it('Should create value', () => { const T = Type.Unknown() Assert.IsEqual(Value.Create(T), {}) }) it('Should create default', () => { const T = Type.Unknown({ default: 1 }) Assert.IsEqual(Value.Create(T), 1) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/create/void.ts000066400000000000000000000006701505437577000246150ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/create/Void', () => { it('Should create value', () => { const T = Type.Void() Assert.IsEqual(Value.Create(T), undefined) }) it('Should create value from default value', () => { const T = Type.Void({ default: 'hello' }) Assert.IsEqual(Value.Create(T), 'hello') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/000077500000000000000000000000001505437577000234625ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/value/default/_deferred.ts000066400000000000000000000005131505437577000257500ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Deferred', () => { it('Should use deferred value', () => { const T = Type.Any({ default: () => 1 }) const R = Value.Default(T, 1) Assert.IsEqual(R, 1) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/any.ts000066400000000000000000000007171505437577000246260ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Any', () => { it('Should use default', () => { const T = Type.Any({ default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Any({ default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/array.ts000066400000000000000000000045101505437577000251500ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Array', () => { it('Should use default', () => { const T = Type.Array(Type.Number(), { default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Array(Type.Number(), { default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) // ---------------------------------------------------------------- // Elements // ---------------------------------------------------------------- it('Should use default on elements', () => { const T = Type.Array(Type.Number({ default: 2 })) const R = Value.Default(T, [1, undefined, 3]) Assert.IsEqual(R, [1, 2, 3]) }) // ---------------------------------------------------------------- // Elements // ---------------------------------------------------------------- it('Should should retain array and only initialize undefined elements', () => { const T = Type.Array(Type.Literal('hello', { default: 'hello' })) const R = Value.Default(T, [1, undefined, 3]) Assert.IsEqual(R, [1, 'hello', 3]) }) // ---------------------------------------------------------------- // https://github.com/ubiquity-os-marketplace/command-start-stop/pull/86 // ---------------------------------------------------------------- it('Should retain arrays 1', () => { const U = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C'), Type.Literal('D')], { default: 'A' }) const T = Type.Array(U, { default: ['A', 'B', 'C', 'D'], uniqueItems: true }) Assert.IsEqual(Value.Default(T, undefined), ['A', 'B', 'C', 'D']) Assert.IsEqual(Value.Default(T, []), []) Assert.IsEqual(Value.Default(T, ['A']), ['A']) // initialize undefined element Assert.IsEqual(Value.Default(T, [undefined, 'B', 'C', 'D']), ['A', 'B', 'C', 'D']) }) it('Should retain arrays 2', () => { const U = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C'), Type.Literal('D')], { default: 'A' }) // undefined first element initialized by union default const T = Type.Array(U, { default: [undefined, 'B', 'C', 'D'], uniqueItems: true }) Assert.IsEqual(Value.Default(T, undefined), ['A', 'B', 'C', 'D']) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/async-iterator.ts000066400000000000000000000010131505437577000267710ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/AsyncIterator', () => { it('Should use default', () => { const T = Type.AsyncIterator(Type.Number(), { default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.AsyncIterator(Type.Number(), { default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/bigint.ts000066400000000000000000000007301505437577000253060ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/BigInt', () => { it('Should use default', () => { const T = Type.BigInt({ default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.BigInt({ default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/boolean.ts000066400000000000000000000007331505437577000254540ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Boolean', () => { it('Should use default', () => { const T = Type.Boolean({ default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Boolean({ default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/composite.ts000066400000000000000000000011611505437577000260330ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Composite', () => { it('Should use default', () => { const T = Type.Composite([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })], { default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Composite([Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() })], { default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/constructor.ts000066400000000000000000000010151505437577000264140ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Constructor', () => { it('Should use default', () => { const T = Type.Constructor([], Type.Number(), { default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Constructor([], Type.Number(), { default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/date.ts000066400000000000000000000023071505437577000247510ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Date', () => { it('Should use default', () => { const T = Type.Date({ default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Date({ default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/1024 // ---------------------------------------------------------------- it('Should use value if Date is valid', () => { const T = Type.Date({ default: new Date(1) }) const R = Value.Default(T, new Date(2)) as Date Assert.IsEqual(R.getTime(), 2) }) it('Should use default if Date is undefined', () => { const T = Type.Date({ default: new Date(1) }) const R = Value.Default(T, undefined) as Date Assert.IsEqual(R.getTime(), 1) }) it('Should use value if Date is invalid', () => { const T = Type.Date({ default: new Date(1) }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/enum.ts000066400000000000000000000007321505437577000250000ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Enum', () => { it('Should use default', () => { const T = Type.Enum({}, { default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Enum({}, { default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/function.ts000066400000000000000000000010041505437577000256520ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Function', () => { it('Should use default', () => { const T = Type.Function([], Type.Number(), { default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Function([], Type.Number(), { default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/import.ts000066400000000000000000000223461505437577000253530ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type, CloneType } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Import', () => { it('Should use default', () => { const T = Type.Module({ A: Type.Object( { x: Type.Number(), y: Type.Number(), }, { default: 1 }, ), }).Import('A') const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Module({ A: Type.Object( { x: Type.Number(), y: Type.Number(), }, { default: 1 }, ), }).Import('A') const R = Value.Default(T, null) Assert.IsEqual(R, null) }) // ---------------------------------------------------------------- // Construction // ---------------------------------------------------------------- it('Should should fully construct object 1', () => { const T = Type.Module({ A: Type.Object( { x: Type.Object( { x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), }, { default: {} }, ), y: Type.Object( { x: Type.Number({ default: 3 }), y: Type.Number({ default: 4 }), }, { default: {} }, ), }, { default: {} }, ), }).Import('A') const R = Value.Default(T, undefined) Assert.IsEqual(R, { x: { x: 1, y: 2 }, y: { x: 3, y: 4 } }) }) it('Should should fully construct object 2', () => { const T = Type.Module({ A: Type.Object( { x: Type.Object( { x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), }, { default: {} }, ), y: Type.Object( { x: Type.Number({ default: 3 }), y: Type.Number({ default: 4 }), }, { default: {} }, ), }, { default: {} }, ), }).Import('A') const R = Value.Default(T, { x: null }) Assert.IsEqual(R, { x: null, y: { x: 3, y: 4 } }) }) it('Should should fully construct object 3', () => { const T = Type.Module({ A: Type.Object( { x: Type.Object( { x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), }, { default: {} }, ), y: Type.Object( { x: Type.Number({ default: 3 }), y: Type.Number({ default: 4 }), }, { default: {} }, ), }, { default: {} }, ), }).Import('A') const R = Value.Default(T, { x: { x: null, y: null } }) Assert.IsEqual(R, { x: { x: null, y: null }, y: { x: 3, y: 4 } }) }) // ---------------------------------------------------------------- // Properties // ---------------------------------------------------------------- it('Should use property defaults 1', () => { const T = Type.Module({ A: Type.Object( { x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), }, { default: 1 }, ), }).Import('A') const R = Value.Default(T, {}) Assert.IsEqual(R, { x: 1, y: 2 }) }) it('Should use property defaults 2', () => { const T = Type.Module({ A: Type.Object({ x: Type.Number(), y: Type.Number(), }), }).Import('A') const R = Value.Default(T, {}) Assert.IsEqual(R, {}) }) it('Should use property defaults 3', () => { const T = Type.Module({ A: Type.Object({ x: Type.Number({ default: 1 }), y: Type.Number(), }), }).Import('A') const R = Value.Default(T, {}) Assert.IsEqual(R, { x: 1 }) }) it('Should use property defaults 4', () => { const T = Type.Module({ A: Type.Object({ x: Type.Number({ default: 1 }), y: Type.Number(), }), }).Import('A') const R = Value.Default(T, { x: 3 }) Assert.IsEqual(R, { x: 3 }) }) // ---------------------------------------------------------------- // AdditionalProperties // ---------------------------------------------------------------- it('Should use additional property defaults 1', () => { const T = Type.Module({ A: Type.Object( { x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), }, { additionalProperties: Type.Number({ default: 3 }), }, ), }).Import('A') const R = Value.Default(T, {}) Assert.IsEqual(R, { x: 1, y: 2 }) }) it('Should use additional property defaults 2', () => { const T = Type.Module({ A: Type.Object( { x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), }, { additionalProperties: Type.Number({ default: 3 }), }, ), }).Import('A') const R = Value.Default(T, { x: null, y: null, z: undefined }) Assert.IsEqual(R, { x: null, y: null, z: 3 }) }) it('Should use additional property defaults 3', () => { const T = Type.Module({ A: Type.Object( { x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), }, { additionalProperties: Type.Number(), }, ), }).Import('A') const R = Value.Default(T, { x: null, y: null, z: undefined }) Assert.IsEqual(R, { x: null, y: null, z: undefined }) }) // ---------------------------------------------------------------- // Mutation // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/726 it('Should retain defaults on operation', () => { const A = Type.Module({ A: Type.Object({ a: Type.Object( { b: Type.Array(Type.String(), { default: [] }), }, { default: {} }, ), }), }).Import('A') const value = Value.Default(A, {}) Assert.IsEqual(value, { a: { b: [] } }) Assert.IsEqual(A.$defs.A.properties.a.default, {}) Assert.IsEqual(A.$defs.A.properties.a.properties.b.default, []) }) // https://github.com/sinclairzx81/typebox/issues/726 it('Should retain schematics on operation', () => { const A = Type.Module({ A: Type.Object({ a: Type.Object( { b: Type.Array(Type.String(), { default: [] }), }, { default: {} }, ), }), }).Import('A') const B = CloneType(A) Value.Default(A, {}) Assert.IsEqual(A, B) }) // ---------------------------------------------------------------- // Traveral: https://github.com/sinclairzx81/typebox/issues/962 // ---------------------------------------------------------------- it('Should traverse into an object 1 (initialize)', () => { const M = Type.Module({ Y: Type.Object({ y: Type.String({ default: 'y' }) }), X: Type.Object({ x: Type.Ref('Y') }), }) const Y = M.Import('Y') const X = M.Import('X') Assert.IsEqual(Value.Default(Y, {}), { y: 'y' }) Assert.IsEqual(Value.Default(X, { x: {} }), { x: { y: 'y' } }) }) it('Should traverse into an object 2 (retain)', () => { const M = Type.Module({ Y: Type.Object({ y: Type.String({ default: 'y' }) }), X: Type.Object({ x: Type.Ref('Y') }), }) const Y = M.Import('Y') const X = M.Import('X') Assert.IsEqual(Value.Default(X, { x: { y: 1 } }), { x: { y: 1 } }) }) it('Should traverse into an object 3 (ignore on undefined)', () => { const M = Type.Module({ Y: Type.Object({ y: Type.String({ default: 'y' }) }), X: Type.Object({ x: Type.Ref('Y') }), }) const Y = M.Import('Y') const X = M.Import('X') Assert.IsEqual(Value.Default(X, { x: undefined }), { x: undefined }) }) // ---------------------------------------------------------------- // Exterior Object Defaults // ---------------------------------------------------------------- it('Should default exterior into an object 1', () => { const X = Type.Module({ A: Type.Object({ x: Type.String({ default: 1 }) }, { default: {} }) }).Import('A') const R = Value.Default(X, undefined) Assert.IsEqual(R, { x: 1 }) }) it('Should default exterior into an object 2', () => { const X = Type.Module({ A: Type.Object({ x: Type.String({ default: 1 }) }, { default: {} }) }).Import('A') const R = Value.Default(X, {}) Assert.IsEqual(R, { x: 1 }) }) it('Should default exterior into an object 3', () => { const X = Type.Module({ A: Type.Object({ x: Type.String({ default: 1 }) }, { default: {} }) }).Import('A') const R = Value.Default(X, { y: 3 }) Assert.IsEqual(R, { y: 3, x: 1 }) }) it('Should default exterior into an object 4', () => { const X = Type.Module({ A: Type.Object({ x: Type.String({ default: 1 }) }, { default: {} }) }).Import('A') const R = Value.Default(X, { y: 3, x: 7 }) Assert.IsEqual(R, { y: 3, x: 7 }) }) it('Should default exterior into an object 5', () => { const X = Type.Module({ A: Type.Object({ x: Type.String({ default: 1 }) }, { default: {} }) }).Import('A') const R = Value.Default(X, { x: 2 }) Assert.IsEqual(R, { x: 2 }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/index.ts000066400000000000000000000012651505437577000251450ustar00rootroot00000000000000import './_deferred' import './any' import './array' import './async-iterator' import './bigint' import './boolean' import './composite' import './constructor' import './date' import './enum' import './function' import './import' import './integer' import './intersect' import './iterator' import './keyof' import './kind' import './literal' import './never' import './not' import './null' import './number' import './object' import './promise' import './record' import './recursive' import './ref' import './regexp' import './string' import './symbol' import './template-literal' import './tuple' import './uint8array' import './undefined' import './union' import './unknown' import './void' sinclairzx81-typebox-e0ec98c/test/runtime/value/default/integer.ts000066400000000000000000000007331505437577000254720ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Integer', () => { it('Should use default', () => { const T = Type.Integer({ default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Integer({ default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/intersect.ts000066400000000000000000000067621505437577000260450ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Intersect', () => { it('Should use default', () => { const T = Type.Intersect([Type.Number(), Type.String()], { default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Intersect([Type.Number(), Type.String()], { default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) // ---------------------------------------------------------------- // Intersected // ---------------------------------------------------------------- it('Should use default intersected 1', () => { const A = Type.Object({ a: Type.Number({ default: 1 }), }) const B = Type.Object({ b: Type.Number({ default: 2 }), }) const T = Type.Intersect([A, B]) const R = Value.Default(T, {}) Assert.IsEqual(R, { a: 1, b: 2 }) }) it('Should use default intersected 2', () => { const A = Type.Object({ a: Type.Number(), }) const B = Type.Object({ b: Type.Number(), }) const T = Type.Intersect([A, B]) const R = Value.Default(T, {}) Assert.IsEqual(R, {}) }) it('Should use default intersected 3', () => { const A = Type.Object({ a: Type.Number({ default: 1 }), }) const B = Type.Object({ b: Type.Number({ default: 2 }), }) const T = Type.Intersect([A, B]) const R = Value.Default(T, { a: 3 }) Assert.IsEqual(R, { a: 3, b: 2 }) }) it('Should use default intersected 4', () => { const A = Type.Object({ a: Type.Number({ default: 1 }), }) const B = Type.Object({ b: Type.Number({ default: 2 }), }) const T = Type.Intersect([A, B]) const R = Value.Default(T, { a: 4, b: 5 }) Assert.IsEqual(R, { a: 4, b: 5 }) }) it('Should use default intersected 5', () => { const A = Type.Object({ a: Type.Number({ default: 1 }), }) const B = Type.Number({ default: 2 }) const T = Type.Intersect([A, B]) const R = Value.Default(T, {}) Assert.IsEqual(R, { a: 1 }) }) it('Should use default intersected 6', () => { const A = Type.Number({ default: 2 }) const B = Type.Object({ a: Type.Number({ default: 1 }), }) const T = Type.Intersect([A, B]) const R = Value.Default(T, {}) Assert.IsEqual(R, { a: 1 }) }) // ---------------------------------------------------------------- // Intersected Deep // ---------------------------------------------------------------- it('Should use default intersected deep 1', () => { const A = Type.Object({ a: Type.Number({ default: 1 }) }) const B = Type.Object({ b: Type.Number({ default: 2 }) }) const C = Type.Object({ c: Type.Number({ default: 3 }) }) const D = Type.Object({ d: Type.Number({ default: 4 }) }) const T1 = Type.Intersect([A, B]) const T2 = Type.Intersect([C, D]) const T = Type.Intersect([T1, T2]) const R = Value.Default(T, {}) Assert.IsEqual(R, { a: 1, b: 2, c: 3, d: 4 }) }) it('Should use default intersected deep 2', () => { const A = Type.Object({ a: Type.Number({}) }) const B = Type.Object({ b: Type.Number({}) }) const C = Type.Object({ c: Type.Number({}) }) const D = Type.Object({ d: Type.Number({}) }) const T1 = Type.Intersect([A, B]) const T2 = Type.Intersect([C, D]) const T = Type.Intersect([T1, T2]) const R = Value.Default(T, {}) Assert.IsEqual(R, {}) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/iterator.ts000066400000000000000000000007741505437577000256730ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Iterator', () => { it('Should use default', () => { const T = Type.Iterator(Type.Number(), { default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Iterator(Type.Number(), { default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/keyof.ts000066400000000000000000000010331505437577000251440ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/KeyOf', () => { it('Should use default', () => { const T = Type.KeyOf(Type.Object({ x: Type.Number() }), { default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.KeyOf(Type.Object({ x: Type.Number() }), { default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/kind.ts000066400000000000000000000010021505437577000247500ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type, Kind } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Kind', () => { it('Should use default', () => { const T = Type.Unsafe({ [Kind]: 'Unknown', default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Unsafe({ [Kind]: 'Unknown', default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/literal.ts000066400000000000000000000007511505437577000254710ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Literal', () => { it('Should use default', () => { const T = Type.Literal('foo', { default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Literal('foo', { default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/never.ts000066400000000000000000000007251505437577000251550ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Never', () => { it('Should use default', () => { const T = Type.Never({ default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Never({ default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/not.ts000066400000000000000000000007551505437577000246410ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Not', () => { it('Should use default', () => { const T = Type.Not(Type.String(), { default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Not(Type.String(), { default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/null.ts000066400000000000000000000007221505437577000250050ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Null', () => { it('Should use default', () => { const T = Type.Null({ default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Null({ default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/number.ts000066400000000000000000000007301505437577000253220ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Number', () => { it('Should use default', () => { const T = Type.Number({ default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Number({ default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/object.ts000066400000000000000000000177211505437577000253100ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type, CloneType } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Object', () => { it('Should use default', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), }, { default: 1 }, ) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Object( { x: Type.Number(), y: Type.Number(), }, { default: 1 }, ) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) // ---------------------------------------------------------------- // Construction // ---------------------------------------------------------------- it('Should should fully construct object 1', () => { const T = Type.Object( { x: Type.Object( { x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), }, { default: {} }, ), y: Type.Object( { x: Type.Number({ default: 3 }), y: Type.Number({ default: 4 }), }, { default: {} }, ), }, { default: {} }, ) const R = Value.Default(T, undefined) Assert.IsEqual(R, { x: { x: 1, y: 2 }, y: { x: 3, y: 4 } }) }) it('Should should fully construct object 2', () => { const T = Type.Object( { x: Type.Object( { x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), }, { default: {} }, ), y: Type.Object( { x: Type.Number({ default: 3 }), y: Type.Number({ default: 4 }), }, { default: {} }, ), }, { default: {} }, ) const R = Value.Default(T, { x: null }) Assert.IsEqual(R, { x: null, y: { x: 3, y: 4 } }) }) it('Should should fully construct object 3', () => { const T = Type.Object( { x: Type.Object( { x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), }, { default: {} }, ), y: Type.Object( { x: Type.Number({ default: 3 }), y: Type.Number({ default: 4 }), }, { default: {} }, ), }, { default: {} }, ) const R = Value.Default(T, { x: { x: null, y: null } }) Assert.IsEqual(R, { x: { x: null, y: null }, y: { x: 3, y: 4 } }) }) // ---------------------------------------------------------------- // Properties // ---------------------------------------------------------------- it('Should use property defaults 1', () => { const T = Type.Object( { x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), }, { default: 1 }, ) const R = Value.Default(T, {}) Assert.IsEqual(R, { x: 1, y: 2 }) }) it('Should use property defaults 2', () => { const T = Type.Object({ x: Type.Number(), y: Type.Number(), }) const R = Value.Default(T, {}) Assert.IsEqual(R, {}) }) it('Should use property defaults 3', () => { const T = Type.Object({ x: Type.Number({ default: 1 }), y: Type.Number(), }) const R = Value.Default(T, {}) Assert.IsEqual(R, { x: 1 }) }) it('Should use property defaults 4', () => { const T = Type.Object({ x: Type.Number({ default: 1 }), y: Type.Number(), }) const R = Value.Default(T, { x: 3 }) Assert.IsEqual(R, { x: 3 }) }) // ---------------------------------------------------------------- // AdditionalProperties // ---------------------------------------------------------------- it('Should use additional property defaults 1', () => { const T = Type.Object( { x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), }, { additionalProperties: Type.Number({ default: 3 }), }, ) const R = Value.Default(T, {}) Assert.IsEqual(R, { x: 1, y: 2 }) }) it('Should use additional property defaults 2', () => { const T = Type.Object( { x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), }, { additionalProperties: Type.Number({ default: 3 }), }, ) const R = Value.Default(T, { x: null, y: null, z: undefined }) Assert.IsEqual(R, { x: null, y: null, z: 3 }) }) it('Should use additional property defaults 3', () => { const T = Type.Object( { x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), }, { additionalProperties: Type.Number(), }, ) const R = Value.Default(T, { x: null, y: null, z: undefined }) Assert.IsEqual(R, { x: null, y: null, z: undefined }) }) // ---------------------------------------------------------------- // Mutation // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/726 it('Should retain defaults on operation', () => { const A = Type.Object({ a: Type.Object( { b: Type.Array(Type.String(), { default: [] }), }, { default: {} }, ), }) const value = Value.Default(A, {}) Assert.IsEqual(value, { a: { b: [] } }) Assert.IsEqual(A.properties.a.default, {}) Assert.IsEqual(A.properties.a.properties.b.default, []) }) // https://github.com/sinclairzx81/typebox/issues/726 it('Should retain schematics on operation', () => { const A = Type.Object({ a: Type.Object( { b: Type.Array(Type.String(), { default: [] }), }, { default: {} }, ), }) const B = CloneType(A) Value.Default(A, {}) Assert.IsEqual(A, B) }) // ---------------------------------------------------------------- // Traveral: https://github.com/sinclairzx81/typebox/issues/962 // ---------------------------------------------------------------- it('Should traverse into an object 1 (initialize)', () => { const Y = Type.Object({ y: Type.String({ default: 'y' }) }) const X = Type.Object({ x: Y }) Assert.IsEqual(Value.Default(Y, {}), { y: 'y' }) Assert.IsEqual(Value.Default(X, { x: {} }), { x: { y: 'y' } }) }) it('Should traverse into an object 2 (retain)', () => { const Y = Type.Object({ y: Type.String({ default: 'y' }) }) const X = Type.Object({ x: Y }) Assert.IsEqual(Value.Default(X, { x: { y: 1 } }), { x: { y: 1 } }) }) it('Should traverse into an object 3 (ignore on undefined)', () => { const Y = Type.Object({ y: Type.String({ default: 'y' }) }) const X = Type.Object({ x: Y }) Assert.IsEqual(Value.Default(X, { x: undefined }), { x: undefined }) }) // ---------------------------------------------------------------- // Exterior Object Defaults // ---------------------------------------------------------------- it('Should default exterior into an object 1', () => { const X = Type.Object({ x: Type.String({ default: 1 }) }, { default: {} }) const R = Value.Default(X, undefined) Assert.IsEqual(R, { x: 1 }) }) it('Should default exterior into an object 2', () => { const X = Type.Object({ x: Type.String({ default: 1 }) }, { default: {} }) const R = Value.Default(X, {}) Assert.IsEqual(R, { x: 1 }) }) it('Should default exterior into an object 3', () => { const X = Type.Object({ x: Type.String({ default: 1 }) }, { default: {} }) const R = Value.Default(X, { y: 3 }) Assert.IsEqual(R, { y: 3, x: 1 }) }) it('Should default exterior into an object 4', () => { const X = Type.Object({ x: Type.String({ default: 1 }) }, { default: {} }) const R = Value.Default(X, { y: 3, x: 7 }) Assert.IsEqual(R, { y: 3, x: 7 }) }) it('Should default exterior into an object 5', () => { const X = Type.Object({ x: Type.String({ default: 1 }) }, { default: {} }) const R = Value.Default(X, { x: 2 }) Assert.IsEqual(R, { x: 2 }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/promise.ts000066400000000000000000000007231505437577000255120ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Promise', () => { it('Should use default', () => { const T = Type.Any({ default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Any({ default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/record.ts000066400000000000000000000051401505437577000253100ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Record', () => { it('Should use default', () => { const T = Type.Record(Type.String(), Type.Number(), { default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Record(Type.String(), Type.Number(), { default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) // // ---------------------------------------------------------------- // // Properties // // ---------------------------------------------------------------- it('Should use property defaults 1', () => { const T = Type.Record(Type.Number(), Type.Number({ default: 1 })) const R = Value.Default(T, { 0: undefined }) Assert.IsEqual(R, { 0: 1 }) }) it('Should use property defaults 2', () => { const T = Type.Record(Type.Number(), Type.Number({ default: 1 })) const R = Value.Default(T, { 0: null }) Assert.IsEqual(R, { 0: null }) }) it('Should use property defaults 3', () => { const T = Type.Record(Type.Number(), Type.Number({ default: 1 })) const R = Value.Default(T, { a: undefined }) Assert.IsEqual(R, { a: undefined }) }) it('Should use property defaults 4', () => { const T = Type.Record(Type.Number(), Type.Number({ default: 1 })) const R = Value.Default(T, { 0: undefined }) Assert.IsEqual(R, { 0: 1 }) }) it('Should use property defaults 5', () => { const T = Type.Record(Type.Number(), Type.Number()) const R = Value.Default(T, { 0: undefined }) Assert.IsEqual(R, { 0: undefined }) }) it('Should use property defaults 6', () => { const T = Type.Record(Type.Number(), Type.Number({ default: 1 })) const R = Value.Default(T, {}) Assert.IsEqual(R, {}) }) // ---------------------------------------------------------------- // Additional Properties // ---------------------------------------------------------------- it('Should use additional property defaults 1', () => { const T = Type.Record(Type.Number(), Type.Number({ default: 1 }), { additionalProperties: Type.Number({ default: 3 }), }) const R = Value.Default(T, { 0: undefined, a: undefined }) Assert.IsEqual(R, { 0: 1, a: 3 }) }) it('Should use additional property defaults 2', () => { const T = Type.Record(Type.Number(), Type.Number({ default: 1 }), { additionalProperties: Type.Number(), }) const R = Value.Default(T, { 0: undefined, a: undefined }) Assert.IsEqual(R, { 0: 1, a: undefined }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/recursive.ts000066400000000000000000000045541505437577000260510ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { TSchema, Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' // prettier-ignore describe('value/default/Recursive', () => { it('Should use default', () => { const T = Type.Recursive((This) => Type.Object({ nodes: Type.Array(This) }, { default: 1 })) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Recursive((This) => Type.Object({ nodes: Type.Array(This) }, { default: 1 })) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) // ---------------------------------------------------------------- // Recursive // ---------------------------------------------------------------- it('Should use default recursive values', () => { const T = Type.Recursive((This) => Type.Object({ id: Type.String({ default: 1 }), nodes: Type.Array(This, { default: [] }) // need this })) const R = Value.Default(T, { nodes: [{ nodes: [{ nodes: [{ id: null }] }, { nodes: [{ id: null }] }] }] }) Assert.IsEqual(R, { nodes: [{ nodes: [{ nodes: [{ id: null, nodes: [] }], id: 1 }, { nodes: [{ id: null, nodes: [] }], id: 1 }], id: 1 }], id: 1 }) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/1010 // ---------------------------------------------------------------- it('Should default Recursive Union', () => { const Binary = (node: Node) => Type.Object({ type: Type.Literal('Binary'), left: node, right: node }) const Node = Type.Object({ type: Type.Literal('Node'), value: Type.String({ default: 'X' }) }) const Expr = Type.Recursive(This => Type.Union([Binary(This), Node])) const R = Value.Default(Expr, { type: 'Binary', left: { type: 'Node' }, right: { type: 'Node' } }) Assert.IsEqual(R, { type: 'Binary', left: { type: 'Node', value: 'X' }, right: { type: 'Node', value: 'X' } }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/ref.ts000066400000000000000000000021521505437577000246060ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Ref', () => { it('Should use default', () => { const A = Type.String({ $id: 'A' }) const T = Type.Ref('A', { default: 1 }) const R = Value.Default(T, [A], undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const A = Type.String({ $id: 'A' }) const T = Type.Ref('A', { default: 1 }) const R = Value.Default(T, [A], null) Assert.IsEqual(R, null) }) // ---------------------------------------------------------------- // Foreign // ---------------------------------------------------------------- it('Should use default on foreign value', () => { const A = Type.String({ $id: 'A', default: 1 }) const T = Type.Ref('A') const R = Value.Default(T, [A], undefined) Assert.IsEqual(R, 1) }) it('Should use value on foreign value', () => { const A = Type.String({ $id: 'A', default: 1 }) const T = Type.Ref('A') const R = Value.Default(T, [A], null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/regexp.ts000066400000000000000000000007401505437577000253250ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/RegExp', () => { it('Should use default', () => { const T = Type.RegExp('', { default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.RegExp('', { default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/string.ts000066400000000000000000000007301505437577000253400ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/String', () => { it('Should use default', () => { const T = Type.String({ default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.String({ default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/symbol.ts000066400000000000000000000007301505437577000253370ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Symbol', () => { it('Should use default', () => { const T = Type.Symbol({ default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Symbol({ default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/template-literal.ts000066400000000000000000000010051505437577000272730ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/TemplateLiteral', () => { it('Should use default', () => { const T = Type.TemplateLiteral('hello', { default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.TemplateLiteral('hello', { default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/tuple.ts000066400000000000000000000033531505437577000251670ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Tuple', () => { it('Should use default', () => { const T = Type.Tuple([Type.Number(), Type.Number()], { default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Tuple([Type.Number(), Type.Number()], { default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) // ---------------------------------------------------------------- // Elements // ---------------------------------------------------------------- it('Should use default elements 1', () => { const T = Type.Tuple([Type.Number({ default: 1 }), Type.Number({ default: 2 })], { default: [] }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) it('Should use default elements 2', () => { const T = Type.Tuple([Type.Number({ default: 1 }), Type.Number({ default: 2 })], { default: [] }) const R = Value.Default(T, undefined) Assert.IsEqual(R, [1, 2]) }) it('Should use default elements 3', () => { const T = Type.Tuple([Type.Number({ default: 1 }), Type.Number({ default: 2 })], { default: [] }) const R = Value.Default(T, [4, 5, 6]) Assert.IsEqual(R, [4, 5, 6]) }) it('Should use default elements 4', () => { const T = Type.Tuple([Type.Number({ default: 1 }), Type.Number({ default: 2 })]) const R = Value.Default(T, [4, 5, 6]) Assert.IsEqual(R, [4, 5, 6]) }) it('Should use default elements 5', () => { const T = Type.Tuple([Type.Number({ default: 1 }), Type.Number({ default: 2 })]) const R = Value.Default(T, [4]) Assert.IsEqual(R, [4, 2]) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/uint8array.ts000066400000000000000000000007441505437577000261450ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Uint8Array', () => { it('Should use default', () => { const T = Type.Uint8Array({ default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Uint8Array({ default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/undefined.ts000066400000000000000000000007411505437577000257750ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Undefined', () => { it('Should use default', () => { const T = Type.Undefined({ default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Undefined({ default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/union.ts000066400000000000000000000101031505437577000251550ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type, Kind, TypeRegistry } from '@sinclair/typebox' import { Assert } from '../../assert/index' // prettier-ignore describe('value/default/Union', () => { it('Should use default', () => { const T = Type.Union([Type.Number(), Type.String()], { default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Union([Type.Number(), Type.String()], { default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) // ---------------------------------------------------------------- // Interior // ---------------------------------------------------------------- it('Should default interior 1', () => { const T = Type.Union([ Type.Object({ x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), }), Type.String({ default: 'hello' }), ]) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) it('Should default interior 2', () => { const T = Type.Union([ Type.Object({ x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), }), Type.String({ default: 'hello' }), ]) const R = Value.Default(T, undefined) Assert.IsEqual(R, 'hello') }) it('Should default interior 3', () => { const T = Type.Union([ Type.Object({ x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), }), Type.String({ default: 'hello' }), ]) const R = Value.Default(T, 'world') Assert.IsEqual(R, 'world') }) it('Should default interior 4', () => { const T = Type.Union([ Type.Object({ x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), }), Type.String({ default: 'hello' }), ]) const R = Value.Default(T, {}) Assert.IsEqual(R, { x: 1, y: 2 }) }) it('Should default interior 5', () => { const T = Type.Union([ Type.Object({ x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), }), Type.String({ default: 'hello' }), ]) const R = Value.Default(T, { x: 3 }) Assert.IsEqual(R, { x: 3, y: 2 }) }) it('Should default interior 6', () => { const T = Type.Union([ Type.Object({ x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), }), Type.String({ default: 'hello' }), ]) const R = Value.Default(T, { x: 3, y: 4 }) Assert.IsEqual(R, { x: 3, y: 4 }) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/993 // ---------------------------------------------------------------- it('Should return the original value if no schemas match (cloned interior variant)', async () => { const T = Type.Union([ Type.Tuple([Type.Number(), Type.Number()]), Type.Array(Type.Number()) ]) const value = ['hello'] const R = Value.Default(T, value) Assert.IsTrue(R === value) }) // ---------------------------------------------------------------- // Interior Unsafe // ---------------------------------------------------------------- it('Should default interior unsafe 1', () => { TypeRegistry.Set('DefaultUnsafe', (schema, value) => typeof value === 'string') const T = Type.Union([ Type.Object({ x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), }), Type.Unsafe({ [Kind]: 'DefaultUnsafe', default: 'hello' }), ]) const R = Value.Default(T, undefined) Assert.IsEqual(R, 'hello') TypeRegistry.Delete('DefaultUnsafe') }) it('Should default interior unsafe 2', () => { TypeRegistry.Set('DefaultUnsafe', (schema, value) => typeof value === 'string') const T = Type.Union([ Type.Object({ x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }), }), Type.Unsafe({ [Kind]: 'DefaultUnsafe', default: 'hello' }), ]) const R = Value.Default(T, 'world') Assert.IsEqual(R, 'world') TypeRegistry.Delete('DefaultUnsafe') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/unknown.ts000066400000000000000000000007331505437577000255340ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Unknown', () => { it('Should use default', () => { const T = Type.Unknown({ default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Unknown({ default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/default/void.ts000066400000000000000000000007221505437577000247740ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' import { Assert } from '../../assert/index' describe('value/default/Void', () => { it('Should use default', () => { const T = Type.Void({ default: 1 }) const R = Value.Default(T, undefined) Assert.IsEqual(R, 1) }) it('Should use value', () => { const T = Type.Void({ default: 1 }) const R = Value.Default(T, null) Assert.IsEqual(R, null) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/delta/000077500000000000000000000000001505437577000231275ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/value/delta/diff.ts000066400000000000000000000313111505437577000244060ustar00rootroot00000000000000import { Value, Edit } from '@sinclair/typebox/value' import { Assert } from '../../assert/index' // ----------------------------------------------------------------- // Diff Factory // ----------------------------------------------------------------- function Update(path: string, value: unknown): Edit { return { type: 'update', path, value } as any } function Insert(path: string, value: unknown): Edit { return { type: 'insert', path, value } as any } function Delete(path: string): Edit { return { type: 'delete', path } as any } describe('value/delta/Diff', () => { // ---------------------------------------------------- // Null // ---------------------------------------------------- it('Should diff NULL null to null', () => { const A = null const B = null const D = Value.Diff(A, B) const E = [] as Edit[] Assert.IsEqual(D, E) }) it('Should diff NULL undefined to undefined', () => { const A = undefined const B = undefined const D = Value.Diff(A, B) const E = [] as Edit[] Assert.IsEqual(D, E) }) it('Should diff NULL string to string', () => { const A = 'hello' const B = 'hello' const D = Value.Diff(A, B) const E = [] as Edit[] Assert.IsEqual(D, E) }) it('Should diff NULL number to number', () => { const A = 1 const B = 1 const D = Value.Diff(A, B) const E = [] as Edit[] Assert.IsEqual(D, E) }) it('Should diff NULL boolean to boolean', () => { const A = true const B = true const D = Value.Diff(A, B) const E = [] as Edit[] Assert.IsEqual(D, E) }) it('Should diff NULL symbol to symbol', () => { const S = Symbol('A') const A = S const B = S const D = Value.Diff(A, B) const E = [] as Edit[] Assert.IsEqual(D, E) }) it('Should diff NULL object to object', () => { const A = { x: 1, y: 2, z: 3 } const B = { x: 1, y: 2, z: 3 } const D = Value.Diff(A, B) const E = [] as Edit[] Assert.IsEqual(D, E) }) it('Should diff NULL array to array', () => { const A = [1, 2, 3] const B = [1, 2, 3] const D = Value.Diff(A, B) const E = [] as Edit[] Assert.IsEqual(D, E) }) // ---------------------------------------------------- // Type Change Root // ---------------------------------------------------- it('Should diff TYPE change number to null', () => { const A = 1 const B = null const D = Value.Diff(A, B) const E = [Update('', B)] Assert.IsEqual(D, E) }) it('Should diff TYPE change null to undefined', () => { const A = null const B = undefined const D = Value.Diff(A, B) const E = [Update('', B)] Assert.IsEqual(D, E) }) it('Should diff TYPE change null to number', () => { const A = null const B = 1 const D = Value.Diff(A, B) const E = [Update('', B)] Assert.IsEqual(D, E) }) it('Should diff TYPE change null to boolean', () => { const A = null const B = true const D = Value.Diff(A, B) const E = [Update('', B)] Assert.IsEqual(D, E) }) it('Should diff TYPE change null to string', () => { const A = null const B = 'hello' const D = Value.Diff(A, B) const E = [Update('', B)] Assert.IsEqual(D, E) }) it('Should diff TYPE change null to symbol', () => { const A = null const B = Symbol('A') const D = Value.Diff(A, B) const E = [Update('', B)] Assert.IsEqual(D, E) }) it('Should diff TYPE change null to object', () => { const A = null const B = { x: 1, y: 1, z: 1 } const D = Value.Diff(A, B) const E = [Update('', B)] Assert.IsEqual(D, E) }) it('Should diff TYPE change null to array', () => { const A = null const B = [1, 2, 3] const D = Value.Diff(A, B) const E = [Update('', B)] Assert.IsEqual(D, E) }) // ---------------------------------------------------- // Value Change Root // ---------------------------------------------------- it('Should diff VALUE change number', () => { const A = 1 const B = 2 const D = Value.Diff(A, B) const E = [Update('', B)] Assert.IsEqual(D, E) }) it('Should diff VALUE change boolean', () => { const A = false const B = true const D = Value.Diff(A, B) const E = [Update('', B)] Assert.IsEqual(D, E) }) it('Should diff VALUE change string', () => { const A = 'hello' const B = 'world' const D = Value.Diff(A, B) const E = [Update('', B)] Assert.IsEqual(D, E) }) it('Should diff VALUE change symbol', () => { const A = Symbol('A') const B = Symbol('B') const D = Value.Diff(A, B) const E = [Update('', B)] Assert.IsEqual(D, E) }) // ---------------------------------------------------- // Array // ---------------------------------------------------- it('Should diff ELEMENT update', () => { const A = [1, 2, 3, 4] const B = [1, 2, 3, 9] const D = Value.Diff(A, B) const E = [Update('/3', 9)] Assert.IsEqual(D, E) }) it('Should diff ELEMENT push', () => { const A = [1, 2, 3, 4] const B = [1, 2, 3, 4, 5] const D = Value.Diff(A, B) const E = [Insert('/4', 5)] Assert.IsEqual(D, E) }) it('Should diff ELEMENT push twice', () => { const A = [1, 2, 3, 4] const B = [1, 2, 3, 4, 5, 6] const D = Value.Diff(A, B) const E = [Insert('/4', 5), Insert('/5', 6)] Assert.IsEqual(D, E) }) it('Should diff ELEMENT pop', () => { const A = [1, 2, 3, 4] const B = [1, 2, 3] const D = Value.Diff(A, B) const E = [Delete('/3')] Assert.IsEqual(D, E) }) it('Should diff ELEMENT pop twice', () => { const A = [1, 2, 3, 4] const B = [1, 2] const D = Value.Diff(A, B) const E = [Delete('/3'), Delete('/2')] Assert.IsEqual(D, E) }) it('Should diff ELEMENT unshift', () => { const A = [1, 2, 3, 4] const B = [2, 3, 4] const D = Value.Diff(A, B) const E = [Update('/0', 2), Update('/1', 3), Update('/2', 4), Delete('/3')] Assert.IsEqual(D, E) }) it('Should diff ELEMENT unshift twice', () => { const A = [1, 2, 3, 4] const B = [3, 4] const D = Value.Diff(A, B) const E = [Update('/0', 3), Update('/1', 4), Delete('/3'), Delete('/2')] Assert.IsEqual(D, E) }) // ---------------------------------------------------- // Object // ---------------------------------------------------- it('Should diff PROPERTY insert', () => { const A = { x: 1, y: 1 } const B = { x: 1, y: 1, z: 1 } const D = Value.Diff(A, B) const E = [Insert('/z', 1)] Assert.IsEqual(D, E) }) it('Should diff PROPERTY delete', () => { const A = { x: 1, y: 1, z: 1 } const B = { x: 1, y: 1 } const D = Value.Diff(A, B) const E = [Delete('/z')] Assert.IsEqual(D, E) }) it('Should diff PROPERTY update', () => { const A = { x: 1, y: 1, z: 1 } const B = { x: 1, y: 1, z: 2 } const D = Value.Diff(A, B) const E = [Update('/z', 2)] Assert.IsEqual(D, E) }) it('Should diff PROPERTY all values', () => { const A = { x: 1, y: 1, z: 1 } const B = { x: 2, y: 2, z: 2 } const D = Value.Diff(A, B) const E = [Update('/x', 2), Update('/y', 2), Update('/z', 2)] Assert.IsEqual(D, E) }) it('Should diff PROPERTY all delete, all insert', () => { const A = { x: 1, y: 1, z: 1 } const B = { a: 2, b: 2, c: 2 } const D = Value.Diff(A, B) const E = [Insert('/a', 2), Insert('/b', 2), Insert('/c', 2), Delete('/x'), Delete('/y'), Delete('/z')] Assert.IsEqual(D, E) }) it('Should diff PROPERTY insert, update, and delete order preserved', () => { const A = { x: 1, y: 1, z: 1, w: 1 } const B = { a: 2, b: 2, c: 2, w: 2 } const D = Value.Diff(A, B) const E = [Insert('/a', 2), Insert('/b', 2), Insert('/c', 2), Update('/w', 2), Delete('/x'), Delete('/y'), Delete('/z')] Assert.IsEqual(D, E) }) // ---------------------------------------------------- // Object Nested // ---------------------------------------------------- it('Should diff NESTED OBJECT diff type change update', () => { const A = { v: 1 } const B = { v: { x: 1, y: 1, z: 1 } } const D = Value.Diff(A, B) const E = [Update('/v', B.v)] Assert.IsEqual(D, E) }) it('Should diff NESTED OBJECT diff value change update', () => { const A = { v: 1 } const B = { v: 2 } const D = Value.Diff(A, B) const E = [Update('/v', B.v)] Assert.IsEqual(D, E) }) it('Should diff NESTED OBJECT diff partial property update', () => { const A = { v: { x: 1, y: 1, z: 1 } } const B = { v: { x: 2, y: 2, z: 2 } } const D = Value.Diff(A, B) const E = [Update('/v/x', B.v.x), Update('/v/y', B.v.y), Update('/v/z', B.v.z)] Assert.IsEqual(D, E) }) it('Should diff NESTED OBJECT diff partial property insert', () => { const A = { v: { x: 1, y: 1, z: 1 } } const B = { v: { x: 1, y: 1, z: 1, w: 1 } } const D = Value.Diff(A, B) const E = [Insert('/v/w', B.v.w)] Assert.IsEqual(D, E) }) it('Should diff NESTED OBJECT diff partial property delete', () => { const A = { v: { x: 1, y: 1, z: 1 } } const B = { v: { x: 1, y: 1 } } const D = Value.Diff(A, B) const E = [Delete('/v/z')] Assert.IsEqual(D, E) }) it('Should diff NESTED OBJECT ordered diff - update, insert and delete', () => { const A = { v: { x: 1, y: 1 } } const B = { v: { x: 2, w: 2 } } const D = Value.Diff(A, B) const E = [Insert('/v/w', B.v.w), Update('/v/x', B.v.x), Delete('/v/y')] Assert.IsEqual(D, E) }) // ---------------------------------------------------- // Array Nested // ---------------------------------------------------- it('Should diff NESTED ARRAY object diff type change update', () => { const A = [{ v: 1 }] const B = [{ v: { x: 1, y: 1, z: 1 } }] const D = Value.Diff(A, B) const E = [Update('/0/v', B[0].v)] Assert.IsEqual(D, E) }) it('Should diff NESTED ARRAY object diff value change update', () => { const A = [{ v: 1 }] const B = [{ v: 2 }] const D = Value.Diff(A, B) const E = [Update('/0/v', B[0].v)] Assert.IsEqual(D, E) }) it('Should diff NESTED ARRAY object diff partial property update', () => { const A = [{ v: { x: 1, y: 1, z: 1 } }] const B = [{ v: { x: 2, y: 2, z: 2 } }] const D = Value.Diff(A, B) const E = [Update('/0/v/x', B[0].v.x), Update('/0/v/y', B[0].v.y), Update('/0/v/z', B[0].v.z)] Assert.IsEqual(D, E) }) it('Should diff NESTED ARRAY object diff partial property insert', () => { const A = [{ v: { x: 1, y: 1, z: 1 } }] const B = [{ v: { x: 1, y: 1, z: 1, w: 1 } }] const D = Value.Diff(A, B) const E = [Insert('/0/v/w', B[0].v.w)] Assert.IsEqual(D, E) }) it('Should diff NESTED ARRAY object diff partial property delete', () => { const A = [{ v: { x: 1, y: 1, z: 1 } }] const B = [{ v: { x: 1, y: 1 } }] const D = Value.Diff(A, B) const E = [Delete('/0/v/z')] Assert.IsEqual(D, E) }) it('Should diff NESTED ARRAY insert update and delete order preserved', () => { const A = [{ v: { x: 1, y: 1 } }] const B = [{ v: { x: 2, w: 2 } }] const D = Value.Diff(A, B) const E = [Insert('/0/v/w', B[0].v.w), Update('/0/v/x', B[0].v.x), Delete('/0/v/y')] Assert.IsEqual(D, E) }) it('Should throw if attempting to diff a current value with symbol key', () => { const A = [{ [Symbol('A')]: 1, v: { x: 1, y: 1 } }] const B = [{ v: { x: 2, w: 2 } }] Assert.Throws(() => Value.Diff(A, B)) }) it('Should throw if attempting to diff a next value with symbol key', () => { const A = [{ v: { x: 1, y: 1 } }] const B = [{ [Symbol('A')]: 1, v: { x: 2, w: 2 } }] Assert.Throws(() => Value.Diff(A, B)) }) it('Should diff a Uint8Array (same size)', () => { const A = new Uint8Array([0, 1, 2, 3]) const B = new Uint8Array([0, 9, 2, 9]) const D = Value.Diff(A, B) const E = [Update('/1', 9), Update('/3', 9)] Assert.IsEqual(D, E) }) it('Should diff a Uint8Array (less than requires full update)', () => { const A = new Uint8Array([0, 1, 2, 3]) const B = new Uint8Array([0, 9, 2]) const D = Value.Diff(A, B) const E = [Update('', new Uint8Array([0, 9, 2]))] Assert.IsEqual(D, E) }) it('Should diff a Uint8Array (greater than requires full update)', () => { const A = new Uint8Array([0, 1, 2, 3]) const B = new Uint8Array([0, 9, 2, 3, 4]) const D = Value.Diff(A, B) const E = [Update('', new Uint8Array([0, 9, 2, 3, 4]))] Assert.IsEqual(D, E) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/937 // ---------------------------------------------------------------- it('Should generate no diff for undefined properties of current and next', () => { const A = { a: undefined } const B = { a: undefined } const D = Value.Diff(A, B) const E = [] as any Assert.IsEqual(D, E) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/delta/index.ts000066400000000000000000000000411505437577000246010ustar00rootroot00000000000000import './diff' import './patch' sinclairzx81-typebox-e0ec98c/test/runtime/value/delta/patch.ts000066400000000000000000000306511505437577000246030ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Assert } from '../../assert/index' describe('value/delta/Patch', () => { // ---------------------------------------------------- // Null // ---------------------------------------------------- it('Should patch NULL null to null', () => { const A = null const B = null const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch NULL undefined to undefined', () => { const A = undefined const B = undefined const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch NULL string to string', () => { const A = 'hello' const B = 'hello' const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch NULL number to number', () => { const A = 1 const B = 1 const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch NULL boolean to boolean', () => { const A = true const B = true const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch NULL symbol to symbol', () => { const S = Symbol('A') const A = S const B = S const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch NULL object to object', () => { const A = { x: 1, y: 2, z: 3 } const B = { x: 1, y: 2, z: 3 } const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch NULL array to array', () => { const A = [1, 2, 3] const B = [1, 2, 3] const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) // ---------------------------------------------------- // Type Change Root // ---------------------------------------------------- it('Should patch TYPE change number to null', () => { const A = 1 const B = null const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch TYPE change null to undefined', () => { const A = null const B = undefined const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch TYPE change null to number', () => { const A = null const B = 1 const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch TYPE change null to boolean', () => { const A = null const B = true const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch TYPE change null to string', () => { const A = null const B = 'hello' const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch TYPE change null to symbol', () => { const A = null const B = Symbol('A') const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch TYPE change null to object', () => { const A = null const B = { x: 1, y: 1, z: 1 } const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch TYPE change null to array', () => { const A = null const B = [1, 2, 3] const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch TYPE change object to array', () => { const A = { x: 1, y: 2 } const B = [1, 2, 3] const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch TYPE change array to object', () => { const A = [1, 2, 3] const B = { x: 1, y: 2 } const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) // ---------------------------------------------------- // Value Change Root // ---------------------------------------------------- it('Should patch VALUE change number', () => { const A = 1 const B = 2 const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch VALUE change boolean', () => { const A = false const B = true const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch VALUE change string', () => { const A = 'hello' const B = 'world' const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch VALUE change symbol', () => { const A = Symbol('A') const B = Symbol('B') const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) // ---------------------------------------------------- // Array // ---------------------------------------------------- it('Should patch ELEMENT update', () => { const A = [1, 2, 3, 4] const B = [1, 2, 3, 9] const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch ELEMENT push', () => { const A = [1, 2, 3, 4] const B = [1, 2, 3, 4, 5] const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch ELEMENT push twice', () => { const A = [1, 2, 3, 4] const B = [1, 2, 3, 4, 5, 6] const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch ELEMENT pop', () => { const A = [1, 2, 3, 4] const B = [1, 2, 3] const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch ELEMENT pop twice', () => { const A = [1, 2, 3, 4] const B = [1, 2] const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch ELEMENT unshift', () => { const A = [1, 2, 3, 4] const B = [2, 3, 4] const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch ELEMENT unshift twice', () => { const A = [1, 2, 3, 4] const B = [3, 4] const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) // ---------------------------------------------------- // Object // ---------------------------------------------------- it('Should patch PROPERTY insert', () => { const A = { x: 1, y: 1 } const B = { x: 1, y: 1, z: 1 } const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch PROPERTY delete', () => { const A = { x: 1, y: 1, z: 1 } const B = { x: 1, y: 1 } const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch PROPERTY update', () => { const A = { x: 1, y: 1, z: 1 } const B = { x: 1, y: 1, z: 2 } const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch PROPERTY all values', () => { const A = { x: 1, y: 1, z: 1 } const B = { x: 2, y: 2, z: 2 } const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch PROPERTY all delete, all insert', () => { const A = { x: 1, y: 1, z: 1 } const B = { a: 2, b: 2, c: 2 } const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch PROPERTY update, insert and delete order preserved', () => { const A = { x: 1, y: 1, z: 1, w: 1 } const B = { a: 2, b: 2, c: 2, w: 2 } const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) // ---------------------------------------------------- // Object Nested // ---------------------------------------------------- it('Should patch NESTED OBJECT diff type change update', () => { const A = { v: 1 } const B = { v: { x: 1, y: 1, z: 1 } } const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch NESTED OBJECT diff value change update', () => { const A = { v: 1 } const B = { v: 2 } const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch NESTED OBJECT diff partial property update', () => { const A = { v: { x: 1, y: 1, z: 1 } } const B = { v: { x: 2, y: 2, z: 2 } } const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch NESTED OBJECT update, insert and delete order preserved', () => { const A = { v: { x: 1, y: 1 } } const B = { v: { x: 2, w: 2 } } const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) // ---------------------------------------------------- // Array Nested // ---------------------------------------------------- it('Should patch NESTED ARRAY object diff type change update', () => { const A = [{ v: 1 }] const B = [{ v: { x: 1, y: 1, z: 1 } }] const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch NESTED ARRAY object diff value change update', () => { const A = [{ v: 1 }] const B = [{ v: 2 }] const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch NESTED ARRAY object diff partial property update', () => { const A = [{ v: { x: 1, y: 1, z: 1 } }] const B = [{ v: { x: 2, y: 2, z: 2 } }] const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch NESTED ARRAY object diff partial property insert', () => { const A = [{ v: { x: 1, y: 1, z: 1 } }] const B = [{ v: { x: 1, y: 1, z: 1, w: 1 } }] const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch NESTED ARRAY object diff partial property delete', () => { const A = [{ v: { x: 1, y: 1, z: 1 } }] const B = [{ v: { x: 1, y: 1 } }] const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch NESTED ARRAY object ordered diff - update, insert and delete', () => { const A = [{ v: { x: 1, y: 1 } }] const B = [{ v: { x: 2, w: 2 } }] const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch Uint8Array (same size)', () => { const A = [{ v: new Uint8Array([0, 1, 3]) }] const B = [{ v: new Uint8Array([0, 1, 2]) }] const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch Uint8Array (less than size)', () => { const A = [{ v: new Uint8Array([0, 1, 3]) }] const B = [{ v: new Uint8Array([0, 1]) }] const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) it('Should patch Uint8Array (greater than size)', () => { const A = [{ v: new Uint8Array([0, 1, 3]) }] const B = [{ v: new Uint8Array([0, 1, 2, 4]) }] const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) // ---------------------------------------------------- // Mega Values // ---------------------------------------------------- it('Should patch MEGA value', () => { const A = [ { a: { x: 1, y: 1 } }, { b: { x: 1, y: 1, z: ['hello', 1, 2] } }, { c: { x: 1, y: 1 } }, { d: [ { a: 1 }, { a: 1 }, { a: 1 }, [ { a: { x: 1, y: 1 } }, { b: { x: 1, y: 1, z: ['hello', true, true, 2] } }, { c: { x: 1, y: 1 } }, { d: [{ a: 1 }, { a: 1 }, { a: 1 }], }, ], ], }, ] const B = [ 1, 2, { a: { x: 1, y: 'a' } }, { b: { x: true, y: 1, z: ['hello', true, true] } }, { c: { x: 1, y: 1 } }, { d: [ { a: 'hello' }, 1, 2, { a: 1 }, { a: 1 }, [ { a: { x: 1, y: 1 }, x: [1, 2, 3, 4] }, { c: { x: 1, y: 1 } }, { d: [{ a: 1 }, { a: 2 }, 'hello'], }, ], ], }, ] const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/937 // ---------------------------------------------------------------- it('Should generate no diff for undefined properties of current and next', () => { const A = { a: undefined } const B = { a: undefined } const D = Value.Diff(A, B) const P = Value.Patch(A, D) Assert.IsEqual(B, P) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/equal/000077500000000000000000000000001505437577000231455ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/value/equal/equal.ts000066400000000000000000000055371505437577000246360ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Assert } from '../../assert/index' describe('value/equal/Equal', () => { it('Should equal null value', () => { const R = Value.Equal(null, null) Assert.IsTrue(R) }) it('Should not equal null value', () => { const R = Value.Equal(null, 'null') Assert.IsFalse(R) }) it('Should equal undefined value', () => { const R = Value.Equal(undefined, undefined) Assert.IsTrue(R) }) it('Should not equal undefined value', () => { const R = Value.Equal(undefined, 'undefined') Assert.IsFalse(R) }) it('Should equal symbol value', () => { const S1 = Symbol.for('test') const S2 = Symbol.for('test') const R = Value.Equal(S1, S2) Assert.IsTrue(R) }) it('Should not equal symbol value', () => { const S1 = Symbol('test') const S2 = Symbol('test') const R = Value.Equal(S1, S2) Assert.IsFalse(R) }) it('Should equal string value', () => { const R = Value.Equal('hello', 'hello') Assert.IsTrue(R) }) it('Should not equal string value', () => { const R = Value.Equal('hello', 'world') Assert.IsFalse(R) }) it('Should equal number value', () => { const R = Value.Equal(1, 1) Assert.IsTrue(R) }) it('Should not equal number value', () => { const R = Value.Equal(1, 2) Assert.IsFalse(R) }) it('Should equal boolean value', () => { const R = Value.Equal(true, true) Assert.IsTrue(R) }) it('Should not equal boolean value', () => { const R = Value.Equal(true, false) Assert.IsFalse(R) }) it('Should equal array value', () => { const R = Value.Equal([0, 1, 2], [0, 1, 2]) Assert.IsTrue(R) }) it('Should not equal array value', () => { const R = Value.Equal([0, 1, 2], [0, 1, 3]) Assert.IsFalse(R) }) it('Should not equal array value with additional elements', () => { const R = Value.Equal([0, 1, 2], [0, 1, 2, 3]) Assert.IsFalse(R) }) it('Should equal object value', () => { const R = Value.Equal({ x: 1, y: 2, z: 3 }, { x: 1, y: 2, z: 3 }) Assert.IsTrue(R) }) it('Should not equal object value', () => { const R = Value.Equal({ x: 1, y: 2, z: 3 }, { x: 1, y: 2, z: 4 }) Assert.IsFalse(R) }) it('Should not equal object value with additional properties', () => { const R = Value.Equal({ x: 1, y: 2, z: 3 }, { x: 1, y: 2, z: 3, w: 1 }) Assert.IsFalse(R) }) it('Should equal typed array value', () => { const R = Value.Equal(new Uint8Array([0, 1, 2]), new Uint8Array([0, 1, 2])) Assert.IsTrue(R) }) it('Should not equal typed array value', () => { const R = Value.Equal(new Uint8Array([0, 1, 2]), new Uint8Array([0, 1, 3])) Assert.IsFalse(R) }) it('Should not equal typed array value with varying type', () => { const R = Value.Equal(new Uint8Array([0, 1, 2]), new Int8Array([0, 1, 2])) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/equal/index.ts000066400000000000000000000000211505437577000246150ustar00rootroot00000000000000import './equal' sinclairzx81-typebox-e0ec98c/test/runtime/value/guard/000077500000000000000000000000001505437577000231405ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/value/guard/guard.ts000066400000000000000000000377741505437577000246340ustar00rootroot00000000000000import { Assert } from '../../assert/index' import * as ValueGuard from '@sinclair/typebox/value' describe('value/guard/ValueGuard', () => { // ----------------------------------------------------- // IsNull // ----------------------------------------------------- it('Should guard Null 1', () => { const R = ValueGuard.IsNull(null) Assert.IsTrue(R) }) it('Should guard Null 2', () => { const R = ValueGuard.IsNull({}) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsUndefined // ----------------------------------------------------- it('Should guard Undefined 1', () => { const R = ValueGuard.IsUndefined(undefined) Assert.IsTrue(R) }) it('Should guard Undefined 2', () => { const R = ValueGuard.IsUndefined({}) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsBigInt // ----------------------------------------------------- it('Should guard BigInt 1', () => { const R = ValueGuard.IsBigInt(1n) Assert.IsTrue(R) }) it('Should guard BigInt 2', () => { const R = ValueGuard.IsBigInt(1) Assert.IsFalse(R) }) it('Should guard BigInt 3', () => { const R = ValueGuard.IsBigInt('123') Assert.IsFalse(R) }) // ----------------------------------------------------- // IsNumber // ----------------------------------------------------- it('Should guard Number 1', () => { const R = ValueGuard.IsNumber(1) Assert.IsTrue(R) }) it('Should guard Number 2', () => { const R = ValueGuard.IsNumber(3.14) Assert.IsTrue(R) }) it('Should guard Number 3', () => { const R = ValueGuard.IsNumber('') Assert.IsFalse(R) }) it('Should guard Number 4', () => { const R = ValueGuard.IsNumber(NaN) Assert.IsTrue(R) }) // ----------------------------------------------------- // IsString // ----------------------------------------------------- it('Should guard String 1', () => { const R = ValueGuard.IsString('') Assert.IsTrue(R) }) it('Should guard String 2', () => { const R = ValueGuard.IsString(true) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsBoolean // ----------------------------------------------------- it('Should guard Boolean 1', () => { const R = ValueGuard.IsBoolean(true) Assert.IsTrue(R) }) it('Should guard Boolean 2', () => { const R = ValueGuard.IsBoolean(1) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsObject // ----------------------------------------------------- it('Should guard Object 1', () => { const R = ValueGuard.IsObject({}) Assert.IsTrue(R) }) it('Should guard Object 2', () => { const R = ValueGuard.IsObject(1) Assert.IsFalse(R) }) it('Should guard Object 3', () => { const R = ValueGuard.IsObject([]) Assert.IsTrue(R) }) // ----------------------------------------------------- // IsArray // ----------------------------------------------------- it('Should guard Array 1', () => { const R = ValueGuard.IsArray([]) Assert.IsTrue(R) }) it('Should guard Array 2', () => { const R = ValueGuard.IsArray({}) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsAsyncIterator // ----------------------------------------------------- it('Should guard AsyncIterator 1', () => { const R = ValueGuard.IsAsyncIterator((async function* (): any {})()) Assert.IsTrue(R) }) it('Should guard AsyncIterator 2', () => { const R = ValueGuard.IsAsyncIterator((function* (): any {})()) Assert.IsFalse(R) }) // ----------------------------------------------------- // HasPropertyKey // ----------------------------------------------------- it('Should guard property key 1', () => { const O = { x: 10 } const R = ValueGuard.HasPropertyKey(O, 'x') Assert.IsTrue(R) }) it('Should guard property key 2', () => { const O = { x: 10 } const R = ValueGuard.HasPropertyKey(O, 'y') Assert.IsFalse(R) }) // ----------------------------------------------------- // IsDate // ----------------------------------------------------- it('Should guard Date 1', () => { const R = ValueGuard.IsDate(new Date()) Assert.IsTrue(R) }) it('Should guard Date 2', () => { const R = ValueGuard.IsDate({}) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsFunction // ----------------------------------------------------- it('Should guard Function 1', () => { const R = ValueGuard.IsFunction(function () {}) Assert.IsTrue(R) }) it('Should guard Function 2', () => { const R = ValueGuard.IsFunction({}) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsInteger // ----------------------------------------------------- it('Should guard Integer 1', () => { const R = ValueGuard.IsInteger(1) Assert.IsTrue(R) }) it('Should guard Integer 2', () => { const R = ValueGuard.IsInteger(3.14) Assert.IsFalse(R) }) it('Should guard Integer 3', () => { const R = ValueGuard.IsInteger(NaN) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsIterator // ----------------------------------------------------- it('Should guard Iterator 1', () => { const R = ValueGuard.IsIterator((function* () {})()) Assert.IsTrue(R) }) it('Should guard Iterator 2', () => { const R = ValueGuard.IsIterator({}) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsStandardObject // ----------------------------------------------------- it('Should guard StandardObject 1', () => { const R = ValueGuard.IsStandardObject({}) Assert.IsTrue(R) }) it('Should guard StandardObject 2', () => { const R = ValueGuard.IsStandardObject(1) Assert.IsFalse(R) }) it('Should guard StandardObject 3', () => { const R = ValueGuard.IsStandardObject([]) Assert.IsFalse(R) }) it('Should guard StandardObject 4', () => { const R = ValueGuard.IsStandardObject(new (class {})()) Assert.IsFalse(R) }) it('Should guard StandardObject 5', () => { const R = ValueGuard.IsStandardObject(Object.create(null)) Assert.IsTrue(R) }) // ----------------------------------------------------- // IsInstanceObject // ----------------------------------------------------- it('Should guard InstanceObject 1', () => { const R = ValueGuard.IsInstanceObject({}) Assert.IsFalse(R) }) it('Should guard InstanceObject 2', () => { const R = ValueGuard.IsInstanceObject(1) Assert.IsFalse(R) }) it('Should guard InstanceObject 3', () => { const R = ValueGuard.IsInstanceObject([]) Assert.IsFalse(R) }) it('Should guard InstanceObject 4', () => { const R = ValueGuard.IsInstanceObject(new (class {})()) Assert.IsTrue(R) }) // ----------------------------------------------------- // IsPromise // ----------------------------------------------------- it('Should guard Promise 1', () => { const R = ValueGuard.IsPromise(Promise.resolve(1)) Assert.IsTrue(R) }) it('Should guard Promise 2', () => { const R = ValueGuard.IsPromise(new (class {})()) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsSymbol // ----------------------------------------------------- it('Should guard Symbol 1', () => { const R = ValueGuard.IsSymbol(Symbol(1)) Assert.IsTrue(R) }) it('Should guard Symbol 2', () => { const R = ValueGuard.IsSymbol(1) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsTypedArray // ----------------------------------------------------- it('Should guard TypedArray 1', () => { const R = ValueGuard.IsTypedArray(new Uint8Array(1)) Assert.IsTrue(R) }) it('Should guard TypedArray 2', () => { const R = ValueGuard.IsTypedArray(new Float32Array(1)) Assert.IsTrue(R) }) it('Should guard TypedArray 3', () => { const R = ValueGuard.IsTypedArray(new ArrayBuffer(1)) Assert.IsFalse(R) }) it('Should guard TypedArray 4', () => { const R = ValueGuard.IsTypedArray(1) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsInt8Array // ----------------------------------------------------- it('Should guard Int8Array 1', () => { const R = ValueGuard.IsInt8Array(new Int8Array(1)) Assert.IsTrue(R) }) it('Should guard Int8Array 2', () => { const R = ValueGuard.IsInt8Array(new Float32Array(1)) Assert.IsFalse(R) }) it('Should guard Int8Array 2', () => { const R = ValueGuard.IsInt8Array(1) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsUint8Array // ----------------------------------------------------- it('Should guard Uint8Array 1', () => { const R = ValueGuard.IsUint8Array(new Uint8Array(1)) Assert.IsTrue(R) }) it('Should guard Uint8Array 2', () => { const R = ValueGuard.IsUint8Array(new Float32Array(1)) Assert.IsFalse(R) }) it('Should guard Uint8Array 2', () => { const R = ValueGuard.IsUint8Array(1) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsUint8ClampedArray // ----------------------------------------------------- it('Should guard Uint8ClampedArray 1', () => { const R = ValueGuard.IsUint8ClampedArray(new Uint8ClampedArray(1)) Assert.IsTrue(R) }) it('Should guard Uint8ClampedArray 2', () => { const R = ValueGuard.IsUint8ClampedArray(new Float32Array(1)) Assert.IsFalse(R) }) it('Should guard Uint8ClampedArray 2', () => { const R = ValueGuard.IsUint8ClampedArray(1) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsInt16Array // ----------------------------------------------------- it('Should guard Int16Array 1', () => { const R = ValueGuard.IsInt16Array(new Int16Array(1)) Assert.IsTrue(R) }) it('Should guard Int16Array 2', () => { const R = ValueGuard.IsInt16Array(new Float32Array(1)) Assert.IsFalse(R) }) it('Should guard Int16Array 2', () => { const R = ValueGuard.IsInt16Array(1) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsUint16Array // ----------------------------------------------------- it('Should guard Uint16Array 1', () => { const R = ValueGuard.IsUint16Array(new Uint16Array(1)) Assert.IsTrue(R) }) it('Should guard Uint16Array 2', () => { const R = ValueGuard.IsUint16Array(new Float32Array(1)) Assert.IsFalse(R) }) it('Should guard Uint16Array 2', () => { const R = ValueGuard.IsUint16Array(1) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsInt32Array // ----------------------------------------------------- it('Should guard Int32Array 1', () => { const R = ValueGuard.IsInt32Array(new Int32Array(1)) Assert.IsTrue(R) }) it('Should guard Int32Array 2', () => { const R = ValueGuard.IsInt32Array(new Float32Array(1)) Assert.IsFalse(R) }) it('Should guard Int32Array 2', () => { const R = ValueGuard.IsInt32Array(1) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsUint32Array // ----------------------------------------------------- it('Should guard Uint32Array 1', () => { const R = ValueGuard.IsUint32Array(new Uint32Array(1)) Assert.IsTrue(R) }) it('Should guard Uint32Array 2', () => { const R = ValueGuard.IsUint32Array(new Float32Array(1)) Assert.IsFalse(R) }) it('Should guard Uint32Array 2', () => { const R = ValueGuard.IsUint32Array(1) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsFloat32Array // ----------------------------------------------------- it('Should guard Float32Array 1', () => { const R = ValueGuard.IsFloat32Array(new Float32Array(1)) Assert.IsTrue(R) }) it('Should guard Float32Array 2', () => { const R = ValueGuard.IsFloat32Array(new Float64Array(1)) Assert.IsFalse(R) }) it('Should guard Float32Array 2', () => { const R = ValueGuard.IsFloat32Array(1) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsFloat64Array // ----------------------------------------------------- it('Should guard Float64Array 1', () => { const R = ValueGuard.IsFloat64Array(new Float64Array(1)) Assert.IsTrue(R) }) it('Should guard Float64Array 2', () => { const R = ValueGuard.IsFloat64Array(new Float32Array(1)) Assert.IsFalse(R) }) it('Should guard Float64Array 2', () => { const R = ValueGuard.IsFloat64Array(1) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsBigInt64Array // ----------------------------------------------------- it('Should guard BigInt64Array 1', () => { const R = ValueGuard.IsBigInt64Array(new BigInt64Array(1)) Assert.IsTrue(R) }) it('Should guard BigInt64Array 2', () => { const R = ValueGuard.IsBigInt64Array(new Float32Array(1)) Assert.IsFalse(R) }) it('Should guard BigInt64Array 2', () => { const R = ValueGuard.IsBigInt64Array(1) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsBigUint64Array // ----------------------------------------------------- it('Should guard BigUint64Array 1', () => { const R = ValueGuard.IsBigUint64Array(new BigUint64Array(1)) Assert.IsTrue(R) }) it('Should guard BigUint64Array 2', () => { const R = ValueGuard.IsBigUint64Array(new Float32Array(1)) Assert.IsFalse(R) }) it('Should guard BigUint64Array 2', () => { const R = ValueGuard.IsBigUint64Array(1) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsMap // ----------------------------------------------------- it('Should guard Map 1', () => { const R = ValueGuard.IsMap(new Map()) Assert.IsTrue(R) }) it('Should guard Map 2', () => { const R = ValueGuard.IsMap(new Float32Array(1)) Assert.IsFalse(R) }) it('Should guard Map 2', () => { const R = ValueGuard.IsMap(1) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsSet // ----------------------------------------------------- it('Should guard Set 1', () => { const R = ValueGuard.IsSet(new Set()) Assert.IsTrue(R) }) it('Should guard Set 2', () => { const R = ValueGuard.IsSet(new Float32Array(1)) Assert.IsFalse(R) }) it('Should guard Set 2', () => { const R = ValueGuard.IsSet(1) Assert.IsFalse(R) }) // ----------------------------------------------------- // IsValueType // ----------------------------------------------------- it('Should guard value type 1', () => { const R = ValueGuard.IsValueType(1) Assert.IsTrue(R) }) it('Should guard value type 2', () => { const R = ValueGuard.IsValueType(true) Assert.IsTrue(R) }) it('Should guard value type 3', () => { const R = ValueGuard.IsValueType(false) Assert.IsTrue(R) }) it('Should guard value type 4', () => { const R = ValueGuard.IsValueType('hello') Assert.IsTrue(R) }) it('Should guard value type 5', () => { const R = ValueGuard.IsValueType(1n) Assert.IsTrue(R) }) it('Should guard value type 6', () => { const R = ValueGuard.IsValueType(null) Assert.IsTrue(R) }) it('Should guard value type 7', () => { const R = ValueGuard.IsValueType(undefined) Assert.IsTrue(R) }) it('Should guard value type 8', () => { const R = ValueGuard.IsValueType(function () {}) Assert.IsFalse(R) }) it('Should guard value type 9', () => { const R = ValueGuard.IsValueType({}) Assert.IsFalse(R) }) it('Should guard value type 10', () => { const R = ValueGuard.IsValueType([]) Assert.IsFalse(R) }) it('Should guard value type 11', () => { const R = ValueGuard.IsValueType(class {}) Assert.IsFalse(R) }) it('Should guard value type 12', () => { const R = ValueGuard.IsValueType(new (class {})()) Assert.IsFalse(R) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/guard/index.ts000066400000000000000000000000211505437577000246100ustar00rootroot00000000000000import './guard' sinclairzx81-typebox-e0ec98c/test/runtime/value/hash/000077500000000000000000000000001505437577000227615ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/value/hash/hash.ts000066400000000000000000000073061505437577000242620ustar00rootroot00000000000000import { Hash } from '@sinclair/typebox/value' import { Assert } from '../../assert/index' describe('value/hash/Hash', () => { it('Should hash number', () => { Assert.IsEqual('bigint', typeof Hash(1)) const A = Hash(1) const B = Hash(2) Assert.NotEqual(A, B) }) it('Should hash string', () => { Assert.IsEqual('bigint', typeof Hash('hello')) const A = Hash('hello') const B = Hash('world') Assert.NotEqual(A, B) }) it('Should hash boolean', () => { Assert.IsEqual('bigint', typeof Hash(true)) Assert.IsEqual('bigint', typeof Hash(false)) const A = Hash(true) const B = Hash(false) Assert.NotEqual(A, B) }) it('Should hash null', () => { Assert.IsEqual('bigint', typeof Hash(null)) const A = Hash(null) const B = Hash(undefined) Assert.NotEqual(A, B) }) it('Should hash array', () => { Assert.IsEqual('bigint', typeof Hash([0, 1, 2, 3])) const A = Hash([0, 1, 2, 3]) const B = Hash([0, 2, 2, 3]) Assert.NotEqual(A, B) }) it('Should hash object 1', () => { // prettier-ignore Assert.IsEqual('bigint', typeof Hash({ x: 1, y: 2 })) const A = Hash({ x: 1, y: 2 }) const B = Hash({ x: 2, y: 2 }) Assert.NotEqual(A, B) }) it('Should hash object 2', () => { const A = Hash({ x: 1, y: [1, 2] }) const B = Hash({ x: 1, y: [1, 3] }) Assert.NotEqual(A, B) }) it('Should hash object 3', () => { const A = Hash({ x: 1, y: undefined }) const B = Hash({ x: 1 }) Assert.NotEqual(A, B) }) it('Should hash object 4', () => { const A = Hash({ x: 1, y: new Uint8Array([0, 1, 2]) }) const B = Hash({ x: 1, y: [0, 1, 2] }) Assert.NotEqual(A, B) }) it('Should hash object 5', () => { const A = Hash({ x: 1, y: undefined }) const B = Hash({ x: 2, y: undefined }) Assert.NotEqual(A, B) }) it('Should hash Date', () => { Assert.IsEqual('bigint', typeof Hash(new Date())) const A = Hash(new Date(1)) const B = Hash(new Date(2)) Assert.NotEqual(A, B) }) it('Should hash Uint8Array', () => { Assert.IsEqual('bigint', typeof Hash(new Uint8Array([0, 1, 2, 3]))) const A = Hash(new Uint8Array([0, 1, 2, 3])) const B = Hash(new Uint8Array([0, 2, 2, 3])) Assert.NotEqual(A, B) }) it('Should hash undefined', () => { Assert.IsEqual('bigint', typeof Hash(undefined)) const A = Hash(undefined) const B = Hash(null) Assert.NotEqual(A, B) }) it('Should hash symbol 1', () => { Assert.IsEqual('bigint', typeof Hash(Symbol())) const A = Hash(Symbol(1)) const B = Hash(Symbol()) Assert.NotEqual(A, B) }) it('Should hash symbol 2', () => { Assert.IsEqual('bigint', typeof Hash(Symbol())) const A = Hash(Symbol(1)) const B = Hash(Symbol(2)) Assert.NotEqual(A, B) }) it('Should hash symbol 2', () => { Assert.IsEqual('bigint', typeof Hash(Symbol())) const A = Hash(Symbol(1)) const B = Hash(Symbol(1)) Assert.IsEqual(A, B) }) it('Should hash bigint 1', () => { Assert.IsEqual('bigint', typeof Hash(BigInt(1))) const A = Hash(BigInt(1)) const B = Hash(BigInt(2)) Assert.NotEqual(A, B) }) it('Should hash bigint 2', () => { Assert.IsEqual('bigint', typeof Hash(BigInt(1))) const A = Hash(BigInt(1)) const B = Hash(BigInt(1)) Assert.IsEqual(A, B) }) // ---------------------------------------------------------------- // Unicode // ---------------------------------------------------------------- it('Should hash unicode 1 (retain single byte hash)', () => { const hash = Hash('a') Assert.IsEqual(hash, 586962220959696054n) }) it('Should hash unicode 2', () => { const hash = Hash('안녕 세계') Assert.IsEqual(hash, 11219208047802711777n) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/hash/index.ts000066400000000000000000000000201505437577000244300ustar00rootroot00000000000000import './hash' sinclairzx81-typebox-e0ec98c/test/runtime/value/index.ts000066400000000000000000000004331505437577000235150ustar00rootroot00000000000000import './assert' import './cast' import './check' import './clean' import './clone' import './convert' import './create' import './default' import './delta' import './equal' import './guard' import './hash' import './mutate' import './parse' import './pointer' import './transform' sinclairzx81-typebox-e0ec98c/test/runtime/value/mutate/000077500000000000000000000000001505437577000233355ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/value/mutate/index.ts000066400000000000000000000000221505437577000250060ustar00rootroot00000000000000import './mutate' sinclairzx81-typebox-e0ec98c/test/runtime/value/mutate/mutate.ts000066400000000000000000000062221505437577000252060ustar00rootroot00000000000000import { Value } from '@sinclair/typebox/value' import { Assert } from '../../assert/index' describe('value/mutate/Mutate', () => { // -------------------------------------------- // Throw // -------------------------------------------- it('should throw 1', () => { // @ts-ignore Assert.Throws(() => Value.Mutate(1, 1)) }) it('should throw 2', () => { // @ts-ignore Assert.Throws(() => Value.Mutate({}, 1)) }) it('should throw 3', () => { // @ts-ignore Assert.Throws(() => Value.Mutate([], 1)) }) it('should throw 4', () => { // @ts-ignore Assert.Throws(() => Value.Mutate({}, [])) }) it('should throw 5', () => { // @ts-ignore Assert.Throws(() => Value.Mutate([], {})) }) // -------------------------------------------- // Mutate // -------------------------------------------- it('Should mutate 0', () => { const Y = { z: 1 } const X = { y: Y } const A = { x: X } Value.Mutate(A, {}) Assert.IsEqual(A, {}) }) it('Should mutate 1', () => { const Y = { z: 1 } const X = { y: Y } const A = { x: X } Value.Mutate(A, { x: { y: { z: 2 } } }) Assert.IsEqual(A.x.y.z, 2) Assert.IsEqual(A.x.y, Y) Assert.IsEqual(A.x, X) }) it('Should mutate 2', () => { const Y = { z: 1 } const X = { y: Y } const A = { x: X } Value.Mutate(A, { x: { y: { z: [1, 2, 3] } } }) Assert.IsEqual(A.x.y.z, [1, 2, 3]) Assert.IsEqual(A.x.y, Y) Assert.IsEqual(A.x, X) }) it('Should mutate 3', () => { const Y = { z: 1 } const X = { y: Y } const A = { x: X } Value.Mutate(A, { x: {} }) Assert.IsEqual(A.x.y, undefined) Assert.IsEqual(A.x, X) }) it('Should mutate 4', () => { const Y = { z: 1 } const X = { y: Y } const A = { x: X } Value.Mutate(A, { x: { y: 1 } }) Assert.IsEqual(A.x.y, 1) Assert.IsEqual(A.x, X) }) it('Should mutate 5', () => { const Y = { z: 1 } const X = { y: Y } const A = { x: X } Value.Mutate(A, { x: { y: [1, 2, 3] } }) Assert.IsEqual(A.x.y, [1, 2, 3]) Assert.IsEqual(A.x, X) }) it('Should mutate 6', () => { const Y = { z: 1 } const X = { y: Y } const A = { x: X } Value.Mutate(A, { x: [1, 2, 3] }) Assert.NotEqual(A.x, X) Assert.IsEqual(A.x, [1, 2, 3]) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/1119 // ---------------------------------------------------------------- it('Should mutate array 1', () => { const A: unknown[] = [] Value.Mutate(A, []) Assert.IsEqual(A, []) }) it('Should mutate array 2', () => { const A: unknown[] = [] Value.Mutate(A, [1]) Assert.IsEqual(A, [1]) }) it('Should mutate array 3', () => { const A: unknown[] = [1, 2, 3] Value.Mutate(A, [1, 2]) Assert.IsEqual(A, [1, 2]) }) it('Should mutate array 4', () => { const A: unknown[] = [1, 2, 3] Value.Mutate(A, [1, 2, 3, 4]) Assert.IsEqual(A, [1, 2, 3, 4]) }) it('Should mutate array 5', () => { const A: unknown[] = [1, 2, 3] Value.Mutate(A, [{}, {}, {}, [1, 2, 3]]) Assert.IsEqual(A, [{}, {}, {}, [1, 2, 3]]) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/parse/000077500000000000000000000000001505437577000231505ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/value/parse/index.ts000066400000000000000000000000211505437577000246200ustar00rootroot00000000000000import './parse' sinclairzx81-typebox-e0ec98c/test/runtime/value/parse/parse.ts000066400000000000000000000103341505437577000246330ustar00rootroot00000000000000import { Value, AssertError, ParseRegistry } from '@sinclair/typebox/value' import { Type, TypeGuard } from '@sinclair/typebox' import { Assert } from '../../assert/index' // prettier-ignore describe('value/Parse', () => { it('Should Parse', () => { const A = Value.Parse(Type.Literal('hello'), 'hello') Assert.IsEqual(A, 'hello') }) it('Should not Parse', () => { Assert.Throws(() => Value.Parse(Type.Literal('hello'), 'world')) }) it('Should throw AssertError', () => { try { Value.Parse(Type.Literal('hello'), 'world') } catch(error) { if(error instanceof AssertError) { return } throw error } }) it('Should throw AssertError and produce Iterator', () => { try { Value.Parse(Type.Literal('hello'), 'world') } catch(error) { if(error instanceof AssertError) { const first = error.Errors().First() Assert.HasProperty(first, 'type') Assert.HasProperty(first, 'schema') Assert.HasProperty(first, 'path') Assert.HasProperty(first, 'value') Assert.HasProperty(first, 'message') return } throw error } }) // ---------------------------------------------------------------- // Default // ---------------------------------------------------------------- it('Should use Default values', () => { const X = Value.Parse(Type.Object({ x: Type.Number({ default: 1 }), y: Type.Number({ default: 2 }) }), { }) Assert.IsEqual(X, { x: 1, y: 2 }) }) it('Should throw on invalid Default values', () => { Assert.Throws(() => Value.Parse(Type.Object({ x: Type.Number({ default: null }), y: Type.Number({ default: null }) }), { })) }) // ---------------------------------------------------------------- // Convert // ---------------------------------------------------------------- it('Should Convert value 1', () => { const X = Value.Parse(Type.Object({ x: Type.Number(), y: Type.Number() }), { x: '1', y: '2' }) Assert.IsEqual(X, { x: 1, y: 2 }) }) it('Should Convert value 2', () => { const X = Value.Parse(Type.Array(Type.String()), [1, 2, 3, 4]) Assert.IsEqual(X, ['1', '2', '3', '4']) }) // ---------------------------------------------------------------- // Clean // ---------------------------------------------------------------- it('Should Clean value', () => { const X = Value.Parse(Type.Object({ x: Type.Number(), y: Type.Number() }), { x: 1, y: 2, z: 3 }) Assert.IsEqual(X, { x: 1, y: 2 }) }) // ---------------------------------------------------------------- // Decode // ---------------------------------------------------------------- it('Should Decode value', () => { const T = Type.Transform(Type.String()) .Decode(value => 'hello') .Encode(value => value) const X = Value.Parse(T, 'world') Assert.IsEqual(X, 'hello') }) // ---------------------------------------------------------------- // Operations // ---------------------------------------------------------------- it('Should run operations 1', () => { const A = Type.Object({ x: Type.Number() }) const I = { x: 1 } const O = Value.Parse([], A, I) Assert.IsTrue(I === O) }) it('Should run operations 2', () => { const A = Type.Object({ x: Type.Number() }) const I = { x: 1 } const O = Value.Parse(['Clone'], A, I) Assert.IsTrue(I !== O) }) it('Should run operations 3', () => { ParseRegistry.Set('Intercept', ( schema, references, value) => { throw 1 }) const A = Type.Object({ x: Type.Number() }) Assert.Throws(() => Value.Parse(['Intercept'], A, null)) ParseRegistry.Delete('Intercept') const F = ParseRegistry.Get('Intercept') Assert.IsEqual(F, undefined) }) it('Should run operations 4', () => { ParseRegistry.Set('Intercept', ( schema, references, value) => { Assert.IsEqual(value, 12345) Assert.IsTrue(TypeGuard.IsNumber(schema)) Assert.IsTrue(TypeGuard.IsString(references[0])) }) Value.Parse(['Intercept'], Type.Number(), [Type.String()], 12345) ParseRegistry.Delete('Intercept') }) it('Should run operations 5', () => { Assert.Throws(() => Value.Parse(['Intercept'], Type.String(), null)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/pointer/000077500000000000000000000000001505437577000235165ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/value/pointer/index.ts000066400000000000000000000000231505437577000251700ustar00rootroot00000000000000import './pointer' sinclairzx81-typebox-e0ec98c/test/runtime/value/pointer/pointer.ts000066400000000000000000000264711505437577000255600ustar00rootroot00000000000000import { ValuePointer } from '@sinclair/typebox/value' import { Assert } from '../../assert/index' describe('value/pointer/Pointer', () => { //----------------------------------------------- // Format //----------------------------------------------- it('Should produce correct format #1', () => { const R = [...ValuePointer.Format('')] Assert.IsEqual(R, []) }) it('Should produce correct format #2', () => { const R = [...ValuePointer.Format('a')] Assert.IsEqual(R, ['a']) }) it('Should produce correct format #3', () => { const R = [...ValuePointer.Format('/')] Assert.IsEqual(R, ['']) }) it('Should produce correct format #4', () => { const R = [...ValuePointer.Format('/x')] Assert.IsEqual(R, ['x']) }) it('Should produce correct format #5', () => { const R = [...ValuePointer.Format('/x/')] Assert.IsEqual(R, ['x', '']) }) it('Should produce correct format #6', () => { const R = [...ValuePointer.Format('/x//')] Assert.IsEqual(R, ['x', '', '']) }) it('Should produce correct format #7', () => { const R = [...ValuePointer.Format('/x//y')] Assert.IsEqual(R, ['x', '', 'y']) }) it('Should produce correct format #8', () => { const R = [...ValuePointer.Format('/x//y/')] Assert.IsEqual(R, ['x', '', 'y', '']) }) it('Should produce correct format #9', () => { const R = [...ValuePointer.Format('/x/~0')] Assert.IsEqual(R, ['x', '~']) }) it('Should produce correct format #10', () => { const R = [...ValuePointer.Format('/x/~1')] Assert.IsEqual(R, ['x', '/']) }) it('Should produce correct format #11', () => { const R = [...ValuePointer.Format('/x/~0/')] Assert.IsEqual(R, ['x', '~', '']) }) it('Should produce correct format #12', () => { const R = [...ValuePointer.Format('/x/~1/')] Assert.IsEqual(R, ['x', '/', '']) }) it('Should produce correct format #13', () => { const R = [...ValuePointer.Format('/x/a~0b')] Assert.IsEqual(R, ['x', 'a~b']) }) it('Should produce correct format #14', () => { const R = [...ValuePointer.Format('/x/a~1b')] Assert.IsEqual(R, ['x', 'a/b']) }) it('Should produce correct format #15', () => { const R = [...ValuePointer.Format('/x/a~0b/')] Assert.IsEqual(R, ['x', 'a~b', '']) }) it('Should produce correct format #16', () => { const R = [...ValuePointer.Format('/x/a~1b/')] Assert.IsEqual(R, ['x', 'a/b', '']) }) it('Should produce correct format #17', () => { const R = [...ValuePointer.Format('/x/a~0b///y')] Assert.IsEqual(R, ['x', 'a~b', '', '', 'y']) }) it('Should produce correct format #18', () => { const R = [...ValuePointer.Format('/x/a~1b///y')] Assert.IsEqual(R, ['x', 'a/b', '', '', 'y']) }) it('Should produce correct format #19', () => { const R = [...ValuePointer.Format('/x/a~0b///')] Assert.IsEqual(R, ['x', 'a~b', '', '', '']) }) it('Should produce correct format #20', () => { const R = [...ValuePointer.Format('/x/a~1b///')] Assert.IsEqual(R, ['x', 'a/b', '', '', '']) }) //----------------------------------------------- // Get //----------------------------------------------- it('Should get array #1', () => { const V = [0, 1, 2, 3] Assert.IsEqual(ValuePointer.Get(V, ''), [0, 1, 2, 3]) Assert.IsEqual(ValuePointer.Get(V, '/'), undefined) Assert.IsEqual(ValuePointer.Get(V, '/0'), 0) Assert.IsEqual(ValuePointer.Get(V, '/1'), 1) Assert.IsEqual(ValuePointer.Get(V, '/2'), 2) Assert.IsEqual(ValuePointer.Get(V, '/3'), 3) }) it('Should get array #2', () => { const V = [{ x: 0 }, { x: 1 }, { x: 2 }, { x: 3 }] Assert.IsEqual(ValuePointer.Get(V, ''), [{ x: 0 }, { x: 1 }, { x: 2 }, { x: 3 }]) Assert.IsEqual(ValuePointer.Get(V, '/'), undefined) Assert.IsEqual(ValuePointer.Get(V, '/0'), { x: 0 }) Assert.IsEqual(ValuePointer.Get(V, '/1'), { x: 1 }) Assert.IsEqual(ValuePointer.Get(V, '/2'), { x: 2 }) Assert.IsEqual(ValuePointer.Get(V, '/3'), { x: 3 }) Assert.IsEqual(ValuePointer.Get(V, '/0/x'), 0) Assert.IsEqual(ValuePointer.Get(V, '/1/x'), 1) Assert.IsEqual(ValuePointer.Get(V, '/2/x'), 2) Assert.IsEqual(ValuePointer.Get(V, '/3/x'), 3) }) it('Should get object #1', () => { const V = { x: 0, y: 1, z: 2 } Assert.IsEqual(ValuePointer.Get(V, ''), { x: 0, y: 1, z: 2 }) Assert.IsEqual(ValuePointer.Get(V, '/'), undefined) Assert.IsEqual(ValuePointer.Get(V, '/x'), 0) Assert.IsEqual(ValuePointer.Get(V, '/y'), 1) Assert.IsEqual(ValuePointer.Get(V, '/z'), 2) }) it('Should get object #2', () => { const V = { x: { x: 0 }, y: { x: 1 }, z: { x: 2 } } Assert.IsEqual(ValuePointer.Get(V, ''), { x: { x: 0 }, y: { x: 1 }, z: { x: 2 } }) Assert.IsEqual(ValuePointer.Get(V, '/'), undefined) Assert.IsEqual(ValuePointer.Get(V, '/x'), { x: 0 }) Assert.IsEqual(ValuePointer.Get(V, '/y'), { x: 1 }) Assert.IsEqual(ValuePointer.Get(V, '/z'), { x: 2 }) }) it('Should get object #3', () => { const V = { '': { x: -1 }, x: { '': { x: 1 } }, y: { '': { x: 2 } }, z: { '': { x: 3 } } } Assert.IsEqual(ValuePointer.Get(V, ''), { '': { x: -1 }, x: { '': { x: 1 } }, y: { '': { x: 2 } }, z: { '': { x: 3 } } }) Assert.IsEqual(ValuePointer.Get(V, '/'), { x: -1 }) Assert.IsEqual(ValuePointer.Get(V, '/x'), { '': { x: 1 } }) Assert.IsEqual(ValuePointer.Get(V, '/y'), { '': { x: 2 } }) Assert.IsEqual(ValuePointer.Get(V, '/z'), { '': { x: 3 } }) Assert.IsEqual(ValuePointer.Get(V, '/x/'), { x: 1 }) Assert.IsEqual(ValuePointer.Get(V, '/y/'), { x: 2 }) Assert.IsEqual(ValuePointer.Get(V, '/z/'), { x: 3 }) Assert.IsEqual(ValuePointer.Get(V, '/x//x'), 1) Assert.IsEqual(ValuePointer.Get(V, '/y//x'), 2) Assert.IsEqual(ValuePointer.Get(V, '/z//x'), 3) }) //----------------------------------------------- // Has //----------------------------------------------- it('Should return has true for undefined', () => { const V = undefined Assert.IsEqual(ValuePointer.Has(V, ''), true) }) it('Should return has true for null', () => { const V = null Assert.IsEqual(ValuePointer.Has(V, ''), true) }) it('Should return has true for object', () => { const V = {} Assert.IsEqual(ValuePointer.Has(V, ''), true) }) it('Should return has true for array', () => { const V: any[] = [] Assert.IsEqual(ValuePointer.Has(V, ''), true) }) it('Should return has true for string', () => { const V = 'hello' Assert.IsEqual(ValuePointer.Has(V, ''), true) }) it('Should return has true for number', () => { const V = 42 Assert.IsEqual(ValuePointer.Has(V, ''), true) }) it('Should return has true for boolean', () => { const V = false Assert.IsEqual(ValuePointer.Has(V, ''), true) }) it('Should return has true for deeply nested', () => { const V = { '': { x: { y: { z: 1 } } }, x: 1, y: { x: 1 }, z: [{ x: 1 }, { y: 1 }], w: undefined, n: null, } // exists Assert.IsEqual(ValuePointer.Has(V, ''), true) Assert.IsEqual(ValuePointer.Has(V, '/'), true) Assert.IsEqual(ValuePointer.Has(V, '//x'), true) Assert.IsEqual(ValuePointer.Has(V, '//x/y'), true) Assert.IsEqual(ValuePointer.Has(V, '//x/y/z'), true) Assert.IsEqual(ValuePointer.Has(V, '/x'), true) Assert.IsEqual(ValuePointer.Has(V, '/y/x'), true) Assert.IsEqual(ValuePointer.Has(V, '/z'), true) Assert.IsEqual(ValuePointer.Has(V, '/z/0'), true) Assert.IsEqual(ValuePointer.Has(V, '/z/0/x'), true) Assert.IsEqual(ValuePointer.Has(V, '/z/1'), true) Assert.IsEqual(ValuePointer.Has(V, '/z/1/y'), true) Assert.IsEqual(ValuePointer.Has(V, '/x'), true) Assert.IsEqual(ValuePointer.Has(V, '/n'), true) }) //----------------------------------------------- // Set //----------------------------------------------- it('Should throw when setting root', () => { const V = {} Assert.Throws(() => ValuePointer.Set(V, '', { x: 1 })) }) it('Should set array values', () => { const V = [0, 1, 2] ValuePointer.Set(V, '/0', 3) ValuePointer.Set(V, '/1', 4) ValuePointer.Set(V, '/2', 5) Assert.IsEqual(V, [3, 4, 5]) }) it('Should set object values', () => { const V = { x: 0, y: 1, z: 2 } ValuePointer.Set(V, '/x', 3) ValuePointer.Set(V, '/y', 4) ValuePointer.Set(V, '/z', 5) Assert.IsEqual(V, { x: 3, y: 4, z: 5 }) }) it('Should set object values recursively #1', () => { const V = {} ValuePointer.Set(V, '/x/y/z', 1) Assert.IsEqual(V, { x: { y: { z: 1 } } }) }) it('Should set object values recursively #2', () => { const V = {} ValuePointer.Set(V, '/x/0/y/z/', 1) ValuePointer.Set(V, '/x/1/y/z/', 2) Assert.IsEqual(V, { x: { 0: { y: { z: { '': 1, }, }, }, 1: { y: { z: { '': 2, }, }, }, }, }) }) //----------------------------------------------- // Delete //----------------------------------------------- it('Should throw when deleting root', () => { const V = {} Assert.Throws(() => ValuePointer.Delete(V, '')) }) it('Should delete object properties', () => { const V = { x: { x: 1, y: 2, z: 3 }, y: { x: 3, y: 4, z: 5 }, } ValuePointer.Delete(V, '/x/y') ValuePointer.Delete(V, '/y') Assert.IsEqual(V, { x: { x: 1, z: 3 } }) }) it('Should be a noop if property does not exist', () => { const V = { x: { x: 1, y: 2, z: 3 }, y: { x: 3, y: 4, z: 5 }, } ValuePointer.Delete(V, '/x/w') ValuePointer.Delete(V, '/w') Assert.IsEqual(V, { x: { x: 1, y: 2, z: 3 }, y: { x: 3, y: 4, z: 5 }, }) }) it('Should not delete owner', () => { const V = { x: { y: { z: 1 } } } ValuePointer.Delete(V, '/x/y/z') Assert.IsEqual(V, { x: { y: {} } }) }) it('Should delete owner', () => { const V = { x: { y: { z: 1 } } } ValuePointer.Delete(V, '/x/y') Assert.IsEqual(V, { x: {} }) }) it('Should not throw if deleting null property', () => { const V = { x: { y: null } } ValuePointer.Delete(V, '/x/y/z') Assert.IsEqual(V, { x: { y: null } }) }) //----------------------------------------------- // Escapes //----------------------------------------------- it('Should support get ~0 pointer escape', () => { const V = { x: { '~': { x: 1 } }, } Assert.IsEqual(ValuePointer.Get(V, '/x/~0'), { x: 1 }) }) it('Should support get ~1 pointer escape', () => { const V = { x: { '/': { x: 1 } }, } Assert.IsEqual(ValuePointer.Get(V, '/x/~1'), { x: 1 }) }) it('Should support set ~0 pointer escape', () => { const V = { x: { '~': { x: 1 } }, } ValuePointer.Set(V, '/x/~0', { x: 2 }) Assert.IsEqual(V, { x: { '~': { x: 2 } }, }) }) it('Should support set ~1 pointer escape', () => { const V = { x: { '/': { x: 1 } }, } ValuePointer.Set(V, '/x/~1', { x: 2 }) Assert.IsEqual(V, { x: { '/': { x: 2 } }, }) }) it('Should support delete ~0 pointer escape', () => { const V = { x: { '~': { x: 1 } }, } ValuePointer.Delete(V, '/x/~0') Assert.IsEqual(V, { x: {}, }) }) it('Should support delete ~1 pointer escape', () => { const V = { x: { '/': { x: 1 } }, } ValuePointer.Delete(V, '/x/~1') Assert.IsEqual(V, { x: {}, }) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/000077500000000000000000000000001505437577000240515ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/_encoder.ts000066400000000000000000000035141505437577000262020ustar00rootroot00000000000000import { IsAsyncIterator, IsIterator, IsFunction, IsSymbol, IsDate } from '@sinclair/typebox/value' import { TSchema, StaticDecode, StaticEncode } from '@sinclair/typebox' import { TypeCompiler } from '@sinclair/typebox/compiler' import { Value } from '@sinclair/typebox/value' import { Assert } from '../../assert/index' function AssertSame(actual: unknown, expect: unknown) { if (IsAsyncIterator(actual) && IsAsyncIterator(expect)) return if (IsIterator(actual) && IsIterator(expect)) return if (IsSymbol(actual) && IsSymbol(expect)) return if (IsFunction(actual) && IsFunction(expect)) return if (IsDate(actual) && IsDate(expect)) { return Assert.IsEqual(actual.getTime(), expect.getTime()) } Assert.IsEqual(actual, expect) } export function Decode>(schema: T, references: TSchema[], value: unknown): R export function Decode>(schema: T, value: unknown): R export function Decode(...args: any[]) { const [schema, references, value] = args.length === 2 ? [args[0], [], args[1]] : [args[0], args[1], args[2]] const value1 = TypeCompiler.Compile(schema as TSchema, references).Decode(value) const value2 = Value.Decode(schema as TSchema, references, value) AssertSame(value1, value2) return value2 } export function Encode>(schema: T, references: TSchema[], value: unknown): R export function Encode>(schema: T, value: unknown): R export function Encode(...args: any[]) { const [schema, references, value] = args.length === 2 ? [args[0], [], args[1]] : [args[0], args[1], args[2]] const value1 = TypeCompiler.Compile(schema as TSchema, references).Encode(value) const value2 = Value.Encode(schema as TSchema, references, value) AssertSame(value1, value2) return value2 } sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/_nested.ts000066400000000000000000000032201505437577000260370ustar00rootroot00000000000000import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Nested', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T11 = Type.Transform(Type.Literal(1)) .Decode((value) => value) .Encode((value) => value) const T12 = Type.Transform(T11) .Decode((value) => value) .Encode((value) => value) const T13 = Type.Transform(T12) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Value.Decode(T13, 1) Assert.IsEqual(R, 1) }) it('Should encode identity', () => { const R = Value.Encode(T13, 1) Assert.IsEqual(R, 1) }) it('Should throw on identity decode', () => { Assert.Throws(() => Value.Decode(T13, null)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T21 = Type.Transform(Type.Literal(1)) .Decode((value) => 2 as const) .Encode((value) => 1 as const) const T22 = Type.Transform(T21) .Decode((value) => 3 as const) .Encode((value) => 2 as const) const T23 = Type.Transform(T22) .Decode((value) => 4 as const) .Encode((value) => 3 as const) it('Should decode mapped', () => { const R = Value.Decode(T23, 1) Assert.IsEqual(R, 4) }) it('Should encode mapped', () => { const R = Value.Encode(T23, 4) Assert.IsEqual(R, 1) }) it('Should throw on mapped decode', () => { Assert.Throws(() => Value.Decode(T23, null)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/any.ts000066400000000000000000000021151505437577000252070ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Any', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Type.Any()) .Decode((value) => value) .Encode((value) => value) it('Should decode mapped', () => { const R = Encoder.Decode(T0, 123) Assert.IsEqual(R, 123) }) it('Should encode mapped', () => { const R = Encoder.Encode(T0, 123) Assert.IsEqual(R, 123) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Type.Any()) .Decode((value) => 1) .Encode((value) => 2) it('Should decode mapped', () => { const R = Encoder.Decode(T1, null) Assert.IsEqual(R, 1) }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, null) Assert.IsEqual(R, 2) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/array.ts000066400000000000000000000065471505437577000255530ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Array', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Type.Array(Type.Number())) .Decode((value) => value) .Encode((value) => value) it('Should decode mapped', () => { const R = Encoder.Decode(T0, [0, 1, 2]) Assert.IsEqual(R, [0, 1, 2]) }) it('Should encode mapped', () => { const R = Encoder.Encode(T0, [0, 1, 2]) Assert.IsEqual(R, [0, 1, 2]) }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T0, null)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Type.Array(Type.Number())) .Decode((value) => 1) .Encode((value) => [0, 1, 2]) it('Should decode mapped', () => { const R = Encoder.Decode(T1, []) Assert.IsEqual(R, 1) }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, null) Assert.IsEqual(R, [0, 1, 2]) }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) // -------------------------------------------------------- // Elements // -------------------------------------------------------- const B2 = Type.Transform(Type.Boolean()) .Decode((value) => (value ? 'TRUE' : 'FALSE')) .Encode((value) => (value === 'TRUE' ? true : false)) const T2 = Type.Array(B2) it('Should decode elements', () => { const R = Encoder.Decode(T2, [true, false]) Assert.IsEqual(R, ['TRUE', 'FALSE']) }) it('Should encode elements', () => { const R = Encoder.Encode(T2, ['TRUE', 'FALSE']) Assert.IsEqual(R, [true, false]) }) it('Should throw on elements decode', () => { Assert.Throws(() => Encoder.Decode(T2, null)) }) // -------------------------------------------------------- // Elements Contains (Not Supported) // -------------------------------------------------------- const N3 = Type.Transform(Type.Literal(1)) .Decode((value) => 'hello') .Encode((value) => 1 as const) const T3 = Type.Array(Type.Number(), { contains: N3, }) it('Should decode contains', () => { const R = Encoder.Decode(T3, [1, 2, 3]) Assert.IsEqual(R, [1, 2, 3]) }) it('Should throw on contains encode', () => { Assert.Throws(() => Encoder.Encode(T3, ['hello', 2, 3])) }) it('Should throw on contains decode', () => { Assert.Throws(() => Encoder.Decode(T3, null)) }) // ------------------------------------------------------------ // Set // ------------------------------------------------------------ const T4 = Type.Transform(Type.Array(Type.Number())) .Decode((value) => new Set(value)) .Encode((value) => [...value]) it('should decode set', () => { const R = Encoder.Decode(T4, [1, 1, 2, 3]) Assert.IsInstanceOf(R, Set) Assert.IsTrue(R.has(1)) Assert.IsTrue(R.has(2)) Assert.IsTrue(R.has(3)) }) it('should encode set', () => { const R = Encoder.Encode(T4, new Set([1, 2, 3])) Assert.IsEqual(R, [1, 2, 3]) }) it('Should throw on set decode', () => { Assert.Throws(() => Encoder.Decode(T4, {})) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/async-iterator.ts000066400000000000000000000027451505437577000273750ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/AsyncIterator', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Type.AsyncIterator(Type.Number())) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, (async function* (): any {})()) Assert.IsTrue(Symbol.asyncIterator in R) }) it('Should encode identity', () => { const R = Encoder.Encode(T0, (async function* (): any {})()) Assert.IsTrue(Symbol.asyncIterator in R) }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, null)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Type.AsyncIterator(Type.Number())) .Decode((value) => 1) .Encode((value) => (async function* (): any {})()) it('Should decode', () => { const R = Encoder.Decode(T1, (async function* (): any {})()) Assert.IsEqual(R, 1) }) it('Should encode', () => { const R = Encoder.Encode(T1, null) Assert.IsTrue(Symbol.asyncIterator in R) }) it('Should throw on decode', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/bigint.ts000066400000000000000000000024421505437577000256770ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/BigInt', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Type.BigInt()) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, 5n) Assert.IsEqual(R, 5n) }) it('Should encode identity', () => { const R = Encoder.Encode(T0, 5n) Assert.IsEqual(R, 5n) }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, null)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Type.BigInt()) .Decode((value) => 1) .Encode((value) => 2n) it('Should decode mapped', () => { const R = Encoder.Decode(T1, 1n) Assert.IsEqual(R, 1) }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, null) Assert.IsEqual(R, 2n) }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/boolean.ts000066400000000000000000000024651505437577000260470ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Boolean', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Type.Boolean()) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, true) Assert.IsEqual(R, true) }) it('Should encode identity', () => { const R = Encoder.Encode(T0, false) Assert.IsEqual(R, false) }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, null)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Type.Boolean()) .Decode((value) => 1) .Encode((value) => true) it('Should decode mapped', () => { const R = Encoder.Decode(T1, true) Assert.IsEqual(R, 1) }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, null) Assert.IsEqual(R, true) }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/constructor.ts000066400000000000000000000026001505437577000270040ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Constructor', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Type.Constructor([], Type.Any())) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, class {}) Assert.IsTypeOf(R, 'function') }) it('Should encode identity', () => { const R = Encoder.Encode(T0, class {}) Assert.IsTypeOf(R, 'function') }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, null)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Type.Constructor([], Type.Any())) .Decode((value) => 1) .Encode((value) => class {}) it('Should decode mapped', () => { const R = Encoder.Decode(T1, class {}) Assert.IsEqual(R, 1) }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, null) Assert.IsTypeOf(R, 'function') }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/date.ts000066400000000000000000000025411505437577000253400ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Date', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Type.Date()) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, new Date(123)) Assert.IsEqual(R, new Date(123)) }) it('Should encode identity', () => { const R = Encoder.Encode(T0, new Date(123)) Assert.IsEqual(R, new Date(123)) }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, null)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Type.Date()) .Decode((value) => 1) .Encode((value) => new Date(0)) it('Should decode mapped', () => { const R = Encoder.Decode(T1, new Date(0)) Assert.IsEqual(R, 1) }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, null) Assert.IsInstanceOf(R, Date) }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/enum.ts000066400000000000000000000025111505437577000253640ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Enum', () => { enum E { A, B, C, } // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Type.Enum(E)) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, E.A) Assert.IsEqual(R, E.A) }) it('Should encode identity', () => { const R = Encoder.Encode(T0, E.A) Assert.IsEqual(R, E.A) }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, null)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Type.Enum(E)) .Decode((value) => 1) .Encode((value) => E.A) it('Should decode mapped', () => { const R = Encoder.Decode(T1, E.A) Assert.IsEqual(R, 1) }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, null) Assert.IsEqual(R, E.A) }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/function.ts000066400000000000000000000026031505437577000262470ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Function', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Type.Function([], Type.Any())) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, class {}) Assert.IsTypeOf(R, 'function') }) it('Should encode identity', () => { const R = Encoder.Encode(T0, class {}) Assert.IsTypeOf(R, 'function') }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, null)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Type.Function([], Type.Any())) .Decode((value) => 1) .Encode((value) => function () {}) it('Should decode mapped', () => { const R = Encoder.Decode(T1, function () {}) Assert.IsEqual(R, 1) }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, null) Assert.IsTypeOf(R, 'function') }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/import.ts000066400000000000000000000163671505437577000257500ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { TypeSystemPolicy } from '@sinclair/typebox/system' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' // prettier-ignore describe('value/transform/Import', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform( Type.Module({ A: Type.Object({ x: Type.Number(), y: Type.Number(), })}).Import('A'), ) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, { x: 1, y: 2 }) Assert.IsEqual(R, { x: 1, y: 2 }) }) it('Should encode identity', () => { const R = Encoder.Encode(T0, { x: 1, y: 2 }) Assert.IsEqual(R, { x: 1, y: 2 }) }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, undefined)) }) // ---------------------------------------------------------- // Object // ---------------------------------------------------------- const T1 = Type.Transform( Type.Module({ A: Type.Object({ x: Type.Number(), y: Type.Number(), })}).Import('A'), ) .Decode((value) => 42) .Encode((value) => ({ x: 1, y: 2 })) it('Should decode mapped', () => { const R = Encoder.Decode(T1, { x: 1, y: 2 }) Assert.IsEqual(R, 42) }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, null) Assert.IsEqual(R, { x: 1, y: 2 }) }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, undefined)) }) // ---------------------------------------------------------- // Object: Transform Property // ---------------------------------------------------------- const N2 = Type.Transform(Type.Module({ A: Type.Integer() }).Import('A')) .Decode((value) => value.toString()) .Encode((value) => parseInt(value)) const T2 = Type.Object({ x: N2, y: N2, }) it('Should decode transform property', () => { const R = Encoder.Decode(T2, { x: 1, y: 2 }) Assert.IsEqual(R, { x: '1', y: '2' }) }) it('Should encode transform property', () => { const R = Encoder.Encode(T2, { x: '1', y: '2' }) Assert.IsEqual(R, { x: 1, y: 2 }) }) it('Should throw on decode transform property', () => { Assert.Throws(() => Encoder.Decode(T2, undefined)) }) // ---------------------------------------------------------- // Object: Transform Property Nested (Twizzle) // ---------------------------------------------------------- const N3 = Type.Transform(Type.Module({ A: Type.Integer() }).Import('A')) .Decode((value) => value.toString()) .Encode((value) => parseInt(value)) const T3 = Type.Transform( Type.Object({ x: N3, y: N3, }), ) .Decode((value) => ({ x: value.y, y: value.x })) .Encode((value) => ({ x: value.y, y: value.x })) it('Should decode transform property nested', () => { const R = Encoder.Decode(T3, { x: 1, y: 2 }) Assert.IsEqual(R, { x: '2', y: '1' }) }) it('Should encode transform property nested', () => { const R = Encoder.Encode(T3, { x: '1', y: '2' }) Assert.IsEqual(R, { x: 2, y: 1 }) }) it('Should throw on decode transform property nested', () => { Assert.Throws(() => Encoder.Decode(T3, undefined)) }) // ---------------------------------------------------------- // Object Additional Properties // ---------------------------------------------------------- const N4 = Type.Transform(Type.Module({ A: Type.Integer() }).Import('A')) .Decode((value) => value.toString()) .Encode((value) => parseInt(value)) const T4 = Type.Transform( Type.Object( { x: Type.Number(), }, { additionalProperties: N4, }, ), ) .Decode((value) => value) .Encode((value) => value) it('Should decode additional property', () => { const R = Encoder.Decode(T4, { x: 1, y: 2 }) Assert.IsEqual(R, { x: 1, y: '2' }) }) it('Should encode additional property', () => { const R = Encoder.Encode(T4, { x: 1, y: '5' }) Assert.IsEqual(R, { x: 1, y: 5 }) }) it('Should throw on additional property 1', () => { Assert.Throws(() => Encoder.Decode(T4, undefined)) }) it('Should throw on additional property 2', () => { Assert.Throws(() => Encoder.Decode(T4, { x: 1, y: true })) }) // ------------------------------------------------------------ // Map // ------------------------------------------------------------ const T5 = Type.Transform(Type.Module({ A: Type.Object({ x: Type.String(), y: Type.String() })}).Import('A')) .Decode((value) => new Map(Object.entries(value))) .Encode((value) => Object.fromEntries(value.entries()) as any) it('Should decode map', () => { const R = Encoder.Decode(T5, { x: 'hello', y: 'world' }) Assert.IsInstanceOf(R, Map) Assert.IsEqual(R.get('x'), 'hello') Assert.IsEqual(R.get('y'), 'world') }) it('Should encode map', () => { const R = Encoder.Encode( T5, new Map([ ['x', 'hello'], ['y', 'world'], ]), ) Assert.IsEqual(R, { x: 'hello', y: 'world' }) }) it('Should throw on map decode', () => { Assert.Throws(() => Encoder.Decode(T5, {})) }) // ------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/1178 // ------------------------------------------------------------- // immediate it('Should transform embedded module codec 1', () => { const T = Type.Module({ A: Type.Transform(Type.String()) .Decode((value) => parseInt(value)) .Encode((value) => value.toString()), }).Import('A') const D = Value.Decode(T, '123') const E = Value.Encode(T, 123) Assert.IsEqual(D, 123) Assert.IsEqual(E, '123') }) // referential it('Should transform embedded module codec 2', () => { const T = Type.Module({ A: Type.Transform(Type.String()) .Decode((value) => parseInt(value)) .Encode((value) => value.toString()), B: Type.Ref('A'), }).Import('B') const D = Value.Decode(T, '123') const E = Value.Encode(T, 123) Assert.IsEqual(D, 123) Assert.IsEqual(E, '123') }) // deep-referential it('Should transform embedded module codec 3', () => { const T = Type.Module({ A: Type.Transform(Type.String()) .Decode((value) => parseInt(value)) .Encode((value) => value.toString()), B: Type.Ref('A'), C: Type.Ref('B'), D: Type.Ref('C'), E: Type.Ref('D'), }).Import('E') const D = Value.Decode(T, '123') const E = Value.Encode(T, 123) Assert.IsEqual(D, 123) Assert.IsEqual(E, '123') }) // interior-transform referential it('Should transform embedded module codec 4', () => { const T = Type.Module({ A: Type.String(), B: Type.Ref('A'), C: Type.Ref('B'), T: Type.Transform(Type.Ref('C')) .Decode((value) => parseInt(value as string)) .Encode((value) => value.toString()), X: Type.Ref('T'), Y: Type.Ref('X'), Z: Type.Ref('Y') }).Import('Z') const D = Value.Decode(T, '123') const E = Value.Encode(T, 123) Assert.IsEqual(D, 123) Assert.IsEqual(E, '123') }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/index.ts000066400000000000000000000011471505437577000255330ustar00rootroot00000000000000import './_nested' import './any' import './array' import './async-iterator' import './bigint' import './boolean' import './constructor' import './date' import './enum' import './function' import './import' import './integer' import './intersect' import './iterator' import './literal' import './never' import './not' import './null' import './number' import './object' import './promise' import './record' import './recursive' import './ref' import './string' import './symbol' import './template-literal' import './tuple' import './undefined' import './union' import './unknown' import './unsafe' import './void' sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/integer.ts000066400000000000000000000024421505437577000260600ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Integer', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Type.Integer()) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, 42) Assert.IsEqual(R, 42) }) it('Should encode identity', () => { const R = Encoder.Encode(T0, 42) Assert.IsEqual(R, 42) }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, null)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Type.Integer()) .Decode((value) => 1) .Encode((value) => 2) it('Should decode mapped', () => { const R = Encoder.Decode(T1, 1) Assert.IsEqual(R, 1) }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, null) Assert.IsEqual(R, 2) }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/intersect.ts000066400000000000000000000135721505437577000264310ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Intersect', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- // prettier-ignore const T0 = Type.Transform(Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ])) .Decode(value => value) .Encode(value => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, { x: 1, y: 2 }) Assert.IsEqual(R, { x: 1, y: 2 }) }) it('Should encode identity', () => { const R = Encoder.Encode(T0, { x: 1, y: 2 }) Assert.IsEqual(R, { x: 1, y: 2 }) }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, null)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- // prettier-ignore const T1 = Type.Transform(Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ])) .Decode((value) => 1) .Encode((value) => ({ x: 1, y: 2 })) it('Should decode mapped', () => { const R = Encoder.Decode(T1, { x: 1, y: 2 }) Assert.IsEqual(R, 1) }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, null) Assert.IsEqual(R, { x: 1, y: 2 }) }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) // -------------------------------------------------------- // Mapped Property // -------------------------------------------------------- const N2 = Type.Transform(Type.Number()) .Decode((value) => value.toString()) .Encode((value) => parseFloat(value)) // prettier-ignore const T2 = Type.Transform(Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: N2 }) ])) .Decode((value) => value) .Encode((value) => value) it('Should decode property', () => { const R = Encoder.Decode(T2, { x: 1, y: 2 }) Assert.IsEqual(R, { x: 1, y: '2' }) }) it('Should encode property', () => { const R = Encoder.Encode(T2, { x: 1, y: '2' }) Assert.IsEqual(R, { x: 1, y: 2 }) }) it('Should throw on property decode', () => { Assert.Throws(() => Encoder.Decode(T2, null)) }) // -------------------------------------------------------- // Unevaluated Property // -------------------------------------------------------- const N3 = Type.Transform(Type.Number()) .Decode((value) => value.toString()) .Encode((value) => parseFloat(value)) // prettier-ignore const T3 = Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ], { unevaluatedProperties: N3 }) it('Should decode unevaluated property', () => { const R = Encoder.Decode(T3, { x: 1, y: 2, z: 3 }) Assert.IsEqual(R, { x: 1, y: 2, z: '3' }) }) it('Should encode unevaluated property', () => { const R = Encoder.Encode(T3, { x: 1, y: 2, z: '3' }) Assert.IsEqual(R, { x: 1, y: 2, z: 3 }) }) it('Should throw on unevaluated property decode', () => { Assert.Throws(() => Encoder.Decode(T3, null)) }) // -------------------------------------------------------- // Transform Intersection Interior (Not Supported) // -------------------------------------------------------- it('Should throw on intersected interior transform types', () => { const N4 = Type.Transform(Type.Number()) .Decode((value) => value) .Encode((value) => value) Assert.Throws(() => Type.Intersect([N4, N4])) }) // -------------------------------------------------------- // Transform Intersection Exterior // -------------------------------------------------------- const T4 = Type.Transform(Type.Intersect([Type.Number(), Type.Number()])) .Decode((value) => value + 1) .Encode((value) => value - 1) it('Should decode exterior value type', () => { const R = Encoder.Decode(T4, 1) Assert.IsEqual(R, 2) }) it('Should encode exterior value type', () => { const R = Encoder.Encode(T4, 2) Assert.IsEqual(R, 1) }) it('Should throw on exterior value type decode', () => { Assert.Throws(() => Encoder.Decode(T4, null)) }) // -------------------------------------------------------- // https://github.com/sinclairzx81/typebox/discussions/672 // -------------------------------------------------------- // prettier-ignore { const A = Type.Object({ isHybrid: Type.Boolean() }) const T = Type.Transform(A) .Decode((value) => ({ isHybrid: value.isHybrid ? 1 : 0 })) .Encode((value) => ({ isHybrid: value.isHybrid === 1 ? true : false })) const I = Type.Intersect([ Type.Object({ model: Type.String() }), Type.Object({ features: Type.Array(T) }), ]) it('Should decode nested 1', () => { const value = Value.Decode(T, { isHybrid: true }) Assert.IsEqual(value, { isHybrid: 1 }) }) // prettier-ignore it('Should decode nested 2', () => { const value = Value.Decode(I, { model: 'Prius', features: [ { isHybrid: true }, { isHybrid: false } ], }) Assert.IsEqual(value, { model: 'Prius', features: [ { isHybrid: 1 }, { isHybrid: 0 } ], }) }) it('should encode nested 1', () => { let value = Value.Encode(T, { isHybrid: 1 }) Assert.IsEqual(value, { isHybrid: true }) }) // prettier-ignore it('Should encode nested 2', () => { const value = Value.Encode(I, { model: 'Prius', features: [ { isHybrid: 1 }, { isHybrid: 0 } ], }) Assert.IsEqual(value, { model: 'Prius', features: [ { isHybrid: true }, { isHybrid: false } ], }) }) } }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/iterator.ts000066400000000000000000000027041505437577000262550ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Iterator', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Type.Iterator(Type.Number())) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, (function* (): any {})()) Assert.IsTrue(Symbol.iterator in R) }) it('Should encode identity', () => { const R = Encoder.Encode(T0, (function* (): any {})()) Assert.IsTrue(Symbol.iterator in R) }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, null)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Type.Iterator(Type.Number())) .Decode((value) => 1) .Encode((value) => (function* (): any {})()) it('Should decode mapped', () => { const R = Encoder.Decode(T1, (function* (): any {})()) Assert.IsEqual(R, 1) }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, null) Assert.IsTrue(Symbol.iterator in R) }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/literal.ts000066400000000000000000000045251505437577000260630ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Literal', () => { // ----------------------------------------------- // Identity // ----------------------------------------------- const T0 = Type.Transform(Type.Literal(123)) .Decode((value) => value) .Encode((value) => value) it('Should decode mapped', () => { const R = Encoder.Decode(T0, 123) Assert.IsEqual(R, 123) }) it('Should encode mapped', () => { const R = Encoder.Encode(T0, 123) Assert.IsEqual(R, 123) }) // ----------------------------------------------- // LiteralString // ----------------------------------------------- const T1 = Type.Transform(Type.Literal('hello')) .Decode((value) => 1) .Encode((value) => 'hello' as const) it('Should decode literal string', () => { const R = Encoder.Decode(T1, 'hello') Assert.IsEqual(R, 1) }) it('Should encode literal string', () => { const R = Encoder.Encode(T1, null) Assert.IsEqual(R, 'hello') }) it('Should throw on decode literal string', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) // ----------------------------------------------- // LiteralNumber // ----------------------------------------------- const T2 = Type.Transform(Type.Literal(2)) .Decode((value) => 1) .Encode((value) => 2 as const) it('Should decode literal number', () => { const R = Encoder.Decode(T2, 2) Assert.IsEqual(R, 1) }) it('Should encode literal number', () => { const R = Encoder.Encode(T2, null) Assert.IsEqual(R, 2) }) it('Should throw on decode literal number', () => { Assert.Throws(() => Encoder.Decode(T2, null)) }) // ----------------------------------------------- // LiteralBoolean // ----------------------------------------------- const T3 = Type.Transform(Type.Literal(true)) .Decode((value) => 1) .Encode((value) => true as const) it('Should decode literal boolean', () => { const R = Encoder.Decode(T3, true) Assert.IsEqual(R, 1) }) it('Should encode literal boolean', () => { const R = Encoder.Encode(T3, null) Assert.IsEqual(R, true) }) it('Should throw on decode literal boolean', () => { Assert.Throws(() => Encoder.Decode(T3, null)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/never.ts000066400000000000000000000022131505437577000255360ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Never', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Type.Never()) .Decode((value) => value) // @ts-ignore .Encode((value) => value) it('Should throw on identity encode', () => { Assert.Throws(() => Encoder.Encode(T0, undefined)) }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, undefined)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Type.Never()) // @ts-ignore .Decode((value) => 1) // @ts-ignore .Encode((value) => 1) it('Should throw on mapped encode', () => { Assert.Throws(() => Encoder.Encode(T1, undefined)) }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, undefined)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/not.ts000066400000000000000000000024551505437577000252270ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Not', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Type.Not(Type.String())) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, 1) Assert.IsEqual(R, 1) }) it('Should encode identity', () => { const R = Encoder.Encode(T0, 1) Assert.IsEqual(R, 1) }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, '')) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Type.Not(Type.String())) .Decode((value) => 1) .Encode((value) => 2) it('Should decode mapped', () => { const R = Encoder.Decode(T1, null) Assert.IsEqual(R, 1) }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, null) Assert.IsEqual(R, 2) }) it('Should throw on decode not', () => { Assert.Throws(() => Encoder.Decode(T1, 'hello')) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/null.ts000066400000000000000000000024631505437577000254000ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Null', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Type.Null()) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, null) Assert.IsEqual(R, null) }) it('Should encode identity', () => { const R = Encoder.Encode(T0, null) Assert.IsEqual(R, null) }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, undefined)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Type.Null()) .Decode((value) => 1) .Encode((value) => null) it('Should decode mapped', () => { const R = Encoder.Decode(T1, null) Assert.IsEqual(R, 1) }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, 123) Assert.IsEqual(R, null) }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, undefined)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/number.ts000066400000000000000000000024611505437577000257140ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Number', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Type.Number()) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, 42) Assert.IsEqual(R, 42) }) it('Should encode identity', () => { const R = Encoder.Encode(T0, 42) Assert.IsEqual(R, 42) }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, null)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Type.Number()) .Decode((value) => value + 1) .Encode((value) => value - 1) it('Should decode mapped', () => { const R = Encoder.Decode(T1, 1) Assert.IsEqual(R, 2) }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, 2) Assert.IsEqual(R, 1) }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, undefined)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/object.ts000066400000000000000000000264371505437577000257030ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { TypeSystemPolicy } from '@sinclair/typebox/system' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' // prettier-ignore describe('value/transform/Object', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform( Type.Object({ x: Type.Number(), y: Type.Number(), }), ) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, { x: 1, y: 2 }) Assert.IsEqual(R, { x: 1, y: 2 }) }) it('Should encode identity', () => { const R = Encoder.Encode(T0, { x: 1, y: 2 }) Assert.IsEqual(R, { x: 1, y: 2 }) }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, undefined)) }) // ---------------------------------------------------------- // Object // ---------------------------------------------------------- const T1 = Type.Transform( Type.Object({ x: Type.Number(), y: Type.Number(), }), ) .Decode((value) => 42) .Encode((value) => ({ x: 1, y: 2 })) it('Should decode mapped', () => { const R = Encoder.Decode(T1, { x: 1, y: 2 }) Assert.IsEqual(R, 42) }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, null) Assert.IsEqual(R, { x: 1, y: 2 }) }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, undefined)) }) // ---------------------------------------------------------- // Object: Transform Property // ---------------------------------------------------------- const N2 = Type.Transform(Type.Integer()) .Decode((value) => value.toString()) .Encode((value) => parseInt(value)) const T2 = Type.Object({ x: N2, y: N2, }) it('Should decode transform property', () => { const R = Encoder.Decode(T2, { x: 1, y: 2 }) Assert.IsEqual(R, { x: '1', y: '2' }) }) it('Should encode transform property', () => { const R = Encoder.Encode(T2, { x: '1', y: '2' }) Assert.IsEqual(R, { x: 1, y: 2 }) }) it('Should throw on decode transform property', () => { Assert.Throws(() => Encoder.Decode(T2, undefined)) }) // ---------------------------------------------------------- // Object: Transform Property Nested (Twizzle) // ---------------------------------------------------------- const N3 = Type.Transform(Type.Integer()) .Decode((value) => value.toString()) .Encode((value) => parseInt(value)) const T3 = Type.Transform( Type.Object({ x: N3, y: N3, }), ) .Decode((value) => ({ x: value.y, y: value.x })) .Encode((value) => ({ x: value.y, y: value.x })) it('Should decode transform property nested', () => { const R = Encoder.Decode(T3, { x: 1, y: 2 }) Assert.IsEqual(R, { x: '2', y: '1' }) }) it('Should encode transform property nested', () => { const R = Encoder.Encode(T3, { x: '1', y: '2' }) Assert.IsEqual(R, { x: 2, y: 1 }) }) it('Should throw on decode transform property nested', () => { Assert.Throws(() => Encoder.Decode(T3, undefined)) }) // ---------------------------------------------------------- // Object Additional Properties // ---------------------------------------------------------- const N4 = Type.Transform(Type.Integer()) .Decode((value) => value.toString()) .Encode((value) => parseInt(value)) const T4 = Type.Transform( Type.Object( { x: Type.Number(), }, { additionalProperties: N4, }, ), ) .Decode((value) => value) .Encode((value) => value) it('Should decode additional property', () => { const R = Encoder.Decode(T4, { x: 1, y: 2 }) Assert.IsEqual(R, { x: 1, y: '2' }) }) it('Should encode additional property', () => { const R = Encoder.Encode(T4, { x: 1, y: '5' }) Assert.IsEqual(R, { x: 1, y: 5 }) }) it('Should throw on additional property 1', () => { Assert.Throws(() => Encoder.Decode(T4, undefined)) }) it('Should throw on additional property 2', () => { Assert.Throws(() => Encoder.Decode(T4, { x: 1, y: true })) }) // ------------------------------------------------------------ // Map // ------------------------------------------------------------ const T5 = Type.Transform(Type.Object({ x: Type.String(), y: Type.String() })) .Decode((value) => new Map(Object.entries(value))) .Encode((value) => Object.fromEntries(value.entries()) as any) it('should decode map', () => { const R = Encoder.Decode(T5, { x: 'hello', y: 'world' }) Assert.IsInstanceOf(R, Map) Assert.IsEqual(R.get('x'), 'hello') Assert.IsEqual(R.get('y'), 'world') }) it('should encode map', () => { const R = Encoder.Encode( T5, new Map([ ['x', 'hello'], ['y', 'world'], ]), ) Assert.IsEqual(R, { x: 'hello', y: 'world' }) }) it('Should throw on map decode', () => { Assert.Throws(() => Encoder.Decode(T5, {})) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/859 // ---------------------------------------------------------------- it('Should decode for nested transform with renamed property', () => { class User { constructor(public name: string, public createdAt: Date) { } } const TDate = Type.Transform(Type.Number()) .Decode(v => new Date(v)) .Encode(v => v.getTime()) const TUser = Type.Transform(Type.Object({ name: Type.String(), created_at: TDate })) .Decode(v => new User(v.name, v.created_at)) .Encode(v => ({ name: v.name, created_at: v.createdAt })) const D = Value.Decode(TUser, { name: 'name', created_at: 0 }) const E = Value.Encode(TUser, D) Assert.IsEqual(E.name, 'name') Assert.IsEqual(E.created_at, 0) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/865 // ---------------------------------------------------------------- it('Should decode for null prototype', () => { const N = Type.Transform(Type.Number()) .Decode(value => value.toString()) .Encode(value => parseInt(value)) const T = Type.Object({ x: N }) const A = Object.create(null); A.x = 1 const B = Object.create(null); B.x = '1' const D = Value.Decode(T, A) const E = Value.Encode(T, B) Assert.IsEqual(D, { x: '1' }) Assert.IsEqual(E, { x: 1 }) }) // ---------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/958 // ---------------------------------------------------------------- it('Should not decode missing optional properties 0', () => { let Invoked = false const S = Type.Transform(Type.RegExp(/foo/)) .Decode((value) => { Invoked = true; return value }) .Encode((value) => value) const T = Type.Object({ value: Type.Optional(S) }) const D = Value.Decode(T, { value: 'foo' }) Assert.IsEqual(D, { value: 'foo' }) Assert.IsTrue(Invoked) }) it('Should not decode missing optional properties 1', () => { let Invoked = false const S = Type.Transform(Type.RegExp(/foo/)) .Decode((value) => { Invoked = true; return value }) .Encode((value) => value) const T = Type.Object({ value: Type.Optional(S) }) const D = Value.Decode(T, {}) Assert.IsEqual(D, {}) Assert.IsFalse(Invoked) }) it('Should not decode missing optional properties 2', () => { let Invoked = false const S = Type.Transform(Type.RegExp(/foo/)) .Decode((value) => { Invoked = true; return value }) .Encode((value) => value) const T = Type.Object({ value: Type.Optional(S) }) const D = Value.Decode(T, { value: undefined }) Assert.IsEqual(D, { value: undefined }) Assert.IsFalse(Invoked) }) it('Should not decode missing optional properties 3 (ExactOptionalPropertyTypes)', () => { let [Invoked, Revert] = [false, TypeSystemPolicy.ExactOptionalPropertyTypes] TypeSystemPolicy.ExactOptionalPropertyTypes = true const S = Type.Transform(Type.RegExp(/foo/)) .Decode((value) => { Invoked = true; return value }) .Encode((value) => value) const T = Type.Object({ value: Type.Optional(S) }) const D = Value.Decode(T, {}) Assert.IsEqual(D, {}) Assert.IsFalse(Invoked) TypeSystemPolicy.ExactOptionalPropertyTypes = Revert }) it('Should not decode missing optional properties 4 (ExactOptionalPropertyTypes)', () => { let [Invoked, Revert] = [false, TypeSystemPolicy.ExactOptionalPropertyTypes] TypeSystemPolicy.ExactOptionalPropertyTypes = true const S = Type.Transform(Type.RegExp(/foo/)) .Decode((value) => { Invoked = true; return value }) .Encode((value) => value) const T = Type.Object({ value: Type.Optional(S) }) Assert.Throws(() => Value.Decode(T, { value: undefined })) Assert.IsFalse(Invoked) TypeSystemPolicy.ExactOptionalPropertyTypes = Revert }) it('Should not encode missing optional properties 0', () => { let Invoked = false const S = Type.Transform(Type.RegExp(/foo/)) .Decode((value) => value) .Encode((value) => { Invoked = true; return value }) const T = Type.Object({ value: Type.Optional(S) }) const D = Value.Encode(T, { value: 'foo' }) Assert.IsEqual(D, { value: 'foo' }) Assert.IsTrue(Invoked) }) it('Should not encode missing optional properties 1', () => { let Invoked = false const S = Type.Transform(Type.RegExp(/foo/)) .Decode((value) => value) .Encode((value) => { Invoked = true; return value }) const T = Type.Object({ value: Type.Optional(S) }) const D = Value.Encode(T, {}) Assert.IsEqual(D, {}) Assert.IsFalse(Invoked) }) it('Should not encode missing optional properties 2', () => { let Invoked = false const S = Type.Transform(Type.RegExp(/foo/)) .Decode((value) => value) .Encode((value) => { Invoked = true; return value }) const T = Type.Object({ value: Type.Optional(S) }) const D = Value.Encode(T, { value: undefined }) Assert.IsEqual(D, { value: undefined }) Assert.IsFalse(Invoked) }) it('Should not encode missing optional properties 3 (ExactOptionalPropertyTypes)', () => { let [Invoked, Revert] = [false, TypeSystemPolicy.ExactOptionalPropertyTypes] TypeSystemPolicy.ExactOptionalPropertyTypes = true const S = Type.Transform(Type.RegExp(/foo/)) .Decode((value) => value) .Encode((value) => { Invoked = true; return value }) const T = Type.Object({ value: Type.Optional(S) }) const D = Value.Encode(T, {}) Assert.IsEqual(D, {}) Assert.IsFalse(Invoked) TypeSystemPolicy.ExactOptionalPropertyTypes = Revert }) it('Should not encode missing optional properties 4 (ExactOptionalPropertyTypes)', () => { let [Invoked, Revert] = [false, TypeSystemPolicy.ExactOptionalPropertyTypes] TypeSystemPolicy.ExactOptionalPropertyTypes = true const S = Type.Transform(Type.RegExp(/foo/)) .Decode((value) => value) .Encode((value) => { Invoked = true; return value }) const T = Type.Object({ value: Type.Optional(S) }) Assert.Throws(() => Value.Encode(T, { value: undefined })) Assert.IsFalse(Invoked) TypeSystemPolicy.ExactOptionalPropertyTypes = Revert }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/promise.ts000066400000000000000000000026521505437577000261040ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Promise', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Type.Promise(Type.Number())) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, Promise.resolve(1)) Assert.IsTrue(R instanceof Promise) }) it('Should encode identity', () => { const R = Encoder.Encode(T0, Promise.resolve(1)) Assert.IsTrue(R instanceof Promise) }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, undefined)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T = Type.Transform(Type.Promise(Type.Number())) .Decode((value) => 1) .Encode((value) => Promise.resolve(1)) it('Should decode mapped', () => { const R = Encoder.Decode(T, Promise.resolve(1)) Assert.IsEqual(R, 1) }) it('Should encode mapped', () => { const R = Encoder.Encode(T, null) Assert.IsTrue(R instanceof Promise) }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T, null)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/record.ts000066400000000000000000000070671505437577000257110ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Type } from '@sinclair/typebox' describe('value/transform/Record', () => { // ------------------------------------------------------------ // Identity // ------------------------------------------------------------ const T0 = Type.Transform(Type.Record(Type.String(), Type.Boolean())) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, { a: true, b: false, }) Assert.IsEqual(R, { a: true, b: false, }) }) it('Should encode identity', () => { const R = Encoder.Encode(T0, { a: true, b: false, }) Assert.IsEqual(R, { a: true, b: false, }) }) it('Should throw on identity', () => { Assert.Throws(() => Encoder.Decode(T0, null)) }) // ------------------------------------------------------------ // Additional Properties True // ------------------------------------------------------------ const N1 = Type.Transform(Type.Number()) .Decode((value) => `number-${value.toString()}`) .Encode((value) => parseFloat(value.replace(/number-/g, ''))) const T1 = Type.Record(Type.Number(), N1) it('Should decode additional properties allowed', () => { const R = Encoder.Decode(T1, { 0: 1, a: true, }) Assert.IsEqual(R, { 0: 'number-1', a: true, }) }) it('Should encode additional properties allowed', () => { const R = Encoder.Encode(T1, { 0: 'number-1', a: true, }) Assert.IsEqual(R, { 0: 1, a: true, }) }) it('Should throw on additional properties allowed', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) // ------------------------------------------------------------ // Complex Transform // ------------------------------------------------------------ const N2 = Type.Transform(Type.Number()) .Decode((value) => `number-${value.toString()}`) .Encode((value) => parseFloat(value.replace(/number-/g, ''))) const B2 = Type.Transform(Type.Boolean()) .Decode((value) => (value ? 'TRUE' : 'FALSE')) .Encode((value) => (value === 'TRUE' ? true : false)) const T3 = Type.Record(Type.Number(), N2, { additionalProperties: B2 }) it('Should decode complex', () => { const R = Encoder.Decode(T3, { 0: 1, a: true, }) Assert.IsEqual(R, { 0: 'number-1', a: 'TRUE', }) }) it('Should encode complex', () => { const R = Encoder.Encode(T3, { 0: 'number-1', a: 'TRUE', }) Assert.IsEqual(R, { 0: 1, a: true, }) }) it('Should throw on complex decode', () => { Assert.Throws(() => Encoder.Decode(T3, null)) }) // ------------------------------------------------------------ // Map // ------------------------------------------------------------ const T4 = Type.Transform(Type.Record(Type.String(), Type.String())) .Decode((value) => new Map(Object.entries(value))) .Encode((value) => Object.fromEntries(value.entries())) it('should decode map', () => { const R = Encoder.Decode(T4, { x: 'hello', y: 'world' }) Assert.IsInstanceOf(R, Map) Assert.IsEqual(R.get('x'), 'hello') Assert.IsEqual(R.get('y'), 'world') }) it('should encode map', () => { const R = Encoder.Encode( T4, new Map([ ['x', 'hello'], ['y', 'world'], ]), ) Assert.IsEqual(R, { x: 'hello', y: 'world' }) }) it('Should throw on map decode', () => { Assert.Throws(() => Encoder.Decode(T4, null)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/recursive.ts000066400000000000000000000064111505437577000264320ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Recursive', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform( Type.Recursive((This) => Type.Object({ value: Type.Number(), nodes: Type.Array(This), }), ), ) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, { value: 1, nodes: [ { value: 2, nodes: [] }, { value: 3, nodes: [] }, ], }) Assert.IsEqual(R, { value: 1, nodes: [ { value: 2, nodes: [] }, { value: 3, nodes: [] }, ], }) }) it('Should encode identity', () => { const R = Encoder.Encode(T0, { value: 1, nodes: [ { value: 2, nodes: [] }, { value: 3, nodes: [] }, ], }) Assert.IsEqual(R, { value: 1, nodes: [ { value: 2, nodes: [] }, { value: 3, nodes: [] }, ], }) }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, undefined)) }) // ----------------------------------------------- // Mapped // ----------------------------------------------- const T1 = Type.Transform( Type.Recursive((This) => Type.Object({ value: Type.Number(), nodes: Type.Array(This), }), ), ) .Decode((value) => 1) .Encode((value) => ({ value: 1, nodes: [] })) it('Should decode mapped', () => { const R = Encoder.Decode(T1, { value: 1, nodes: [ { value: 2, nodes: [] }, { value: 3, nodes: [] }, ], }) Assert.IsEqual(R, 1) }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, null) Assert.IsEqual(R, { value: 1, nodes: [] }) }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) // ----------------------------------------------- // Recursive Property Remap // ----------------------------------------------- const N2 = Type.Transform(Type.Number()) .Decode((value) => new Date(value)) .Encode((value) => value.getTime()) const T2 = Type.Recursive((This) => Type.Object({ value: N2, nodes: Type.Array(This), }), ) it('Should decode property', () => { const R = Encoder.Decode(T2, { value: 1, nodes: [ { value: 2, nodes: [] }, { value: 3, nodes: [] }, ], }) Assert.IsEqual(R, { value: new Date(1), nodes: [ { value: new Date(2), nodes: [] }, { value: new Date(3), nodes: [] }, ], }) }) it('Should encode property', () => { const R = Encoder.Encode(T2, { value: new Date(1), nodes: [ { value: new Date(2), nodes: [] }, { value: new Date(3), nodes: [] }, ], }) Assert.IsEqual(R, { value: 1, nodes: [ { value: 2, nodes: [] }, { value: 3, nodes: [] }, ], }) }) it('Should throw on decode property', () => { Assert.Throws(() => Encoder.Decode(T2, null)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/ref.ts000066400000000000000000000042041505437577000251750ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Ref', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const N0 = Type.Number({ $id: 'N0' }) const T0 = Type.Transform(Type.Ref('N0')) .Decode((value) => value) .Encode((value) => value) it('Should decode mapped', () => { const R = Encoder.Decode(T0, [N0], 0) Assert.IsEqual(R, 0) }) it('Should encode mapped', () => { const R = Encoder.Encode(T0, [N0], 0) Assert.IsEqual(R, 0) }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, null)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const N1 = Type.Number({ $id: 'N1' }) const T1 = Type.Transform(Type.Unsafe(Type.Ref('N1'))) .Decode((value) => value + 1) .Encode((value) => value - 1) it('Should decode mapped', () => { const R = Encoder.Decode(T1, [N1], 0) Assert.IsEqual(R, 1) }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, [N1], 1) Assert.IsEqual(R, 0) }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) // -------------------------------------------------------- // Mapped Remote // -------------------------------------------------------- const N2 = Type.Transform(Type.Number({ $id: 'N2' })) .Decode((value) => value + 1) .Encode((value) => value - 1) const T2 = Type.Transform(Type.Unsafe(Type.Ref('N2'))) .Decode((value) => value + 1) .Encode((value) => value - 1) it('Should decode mapped remote', () => { const R = Encoder.Decode(T2, [N2], 0) Assert.IsEqual(R, 2) }) it('Should encode mapped remote', () => { const R = Encoder.Encode(T2, [N2], 2) Assert.IsEqual(R, 0) }) it('Should throw on mapped remote decode', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/string.ts000066400000000000000000000026541505437577000257360ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/String', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- // const T0 = Type.Transform(Type.String()) // .Decode((value) => value) // .Encode((value) => value) // it('Should decode identity', () => { // const R = Encoder.Decode(T0, 'hello') // Assert.IsEqual(R, 'hello') // }) // it('Should encode identity', () => { // const R = Encoder.Encode(T0, 'hello') // Assert.IsEqual(R, 'hello') // }) // it('Should throw on identity decode', () => { // Assert.Throws(() => Encoder.Decode(T0, null)) // }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Type.String()) .Decode((value) => value.split('').reverse().join('')) .Encode((value) => value.split('').reverse().join('')) it('Should decode mapped', () => { const R = Encoder.Decode(T1, 'ABC') Assert.IsEqual(R, 'CBA') }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, 'CBA') Assert.IsEqual(R, 'ABC') }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/symbol.ts000066400000000000000000000027741505437577000257400ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/String', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Type.Symbol()) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, Symbol('hello')) Assert.IsEqual(R.description, 'hello') }) it('Should encode identity', () => { const R = Encoder.Encode(T0, Symbol('hello')) Assert.IsEqual(R.description, 'hello') }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, null)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Type.Symbol()) .Decode((value) => Symbol(value.description?.split('').reverse().join(''))) .Encode((value) => Symbol(value.description?.split('').reverse().join(''))) it('Should decode mapped', () => { const R = Encoder.Decode(T1, Symbol('ABC')) Assert.IsEqual(R.description, 'CBA') }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, Symbol('CBA')) Assert.IsEqual(R.description, 'ABC') }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/template-literal.ts000066400000000000000000000027331505437577000276730ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/TemplateLiteral', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Type.TemplateLiteral([Type.Literal('hello')])) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, 'hello') Assert.IsEqual(R, 'hello') }) it('Should encode identity', () => { const R = Encoder.Encode(T0, 'hello') Assert.IsEqual(R, 'hello') }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, null)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Type.TemplateLiteral([Type.Literal('ABC')])) .Decode((value) => value.split('').reverse().join('') as 'CBA') .Encode((value) => value.split('').reverse().join('') as 'ABC') it('Should decode mapped', () => { const R = Encoder.Decode(T1, 'ABC') Assert.IsEqual(R, 'CBA') }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, 'CBA') Assert.IsEqual(R, 'ABC') }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/tuple.ts000066400000000000000000000066521505437577000255630ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Tuple', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Type.Tuple([Type.Number(), Type.Number()])) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, [1, 2]) Assert.IsEqual(R, [1, 2]) }) it('Should encode identity', () => { const R = Encoder.Encode(T0, [1, 2]) Assert.IsEqual(R, [1, 2]) }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, null)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Type.Tuple([Type.Number()])) .Decode((value) => [value[0] + 1] as [number]) .Encode((value) => [value[0] - 1] as [number]) it('Should decode mapped', () => { const R = Encoder.Decode(T1, [0]) Assert.IsEqual(R, [1]) }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, [1]) Assert.IsEqual(R, [0]) }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) // -------------------------------------------------------- // Mapped Element // -------------------------------------------------------- const N2 = Type.Transform(Type.Number()) .Decode((value) => value + 1) .Encode((value) => value - 1) const T2 = Type.Transform(Type.Tuple([N2])) .Decode((value) => value) .Encode((value) => value) it('Should decode mapped element', () => { const R = Encoder.Decode(T2, [0]) Assert.IsEqual(R, [1]) }) it('Should encode mapped element', () => { const R = Encoder.Encode(T2, [1]) Assert.IsEqual(R, [0]) }) it('Should throw on mapped element decode', () => { Assert.Throws(() => Encoder.Decode(T2, null)) }) // -------------------------------------------------------- // Mapped Element // -------------------------------------------------------- const N3 = Type.Transform(Type.Number()) .Decode((value) => value + 1) .Encode((value) => value - 1) const T3 = Type.Transform(Type.Tuple([N3])) .Decode((value) => [value[0].toString()]) .Encode((value) => [parseFloat(value[0])] as [number]) it('Should decode mapped element', () => { const R = Encoder.Decode(T3, [0]) Assert.IsEqual(R, ['1']) }) it('Should encode mapped element', () => { const R = Encoder.Encode(T3, ['1']) Assert.IsEqual(R, [0]) }) it('Should throw on mapped element decode', () => { Assert.Throws(() => Encoder.Decode(T3, null)) }) // ------------------------------------------------------------ // Set // ------------------------------------------------------------ const T4 = Type.Transform(Type.Tuple([Type.Number()])) .Decode((value) => new Set(value)) .Encode((value) => [...value] as any) it('should decode set', () => { const R = Encoder.Decode(T4, [1]) Assert.IsInstanceOf(R, Set) Assert.IsTrue(R.has(1)) }) it('should encode set', () => { const R = Encoder.Encode(T4, new Set([1])) Assert.IsEqual(R, [1]) }) it('Should throw on set decode', () => { Assert.Throws(() => Encoder.Decode(T4, {})) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/undefined.ts000066400000000000000000000025421505437577000263650ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Undefined', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Type.Undefined()) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, undefined) Assert.IsEqual(R, undefined) }) it('Should encode identity', () => { const R = Encoder.Encode(T0, undefined) Assert.IsEqual(R, undefined) }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, null)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Type.Undefined()) .Decode((value) => null) .Encode((value) => undefined) it('Should decode mapped', () => { const R = Encoder.Decode(T1, undefined) Assert.IsEqual(R, null) }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, null) Assert.IsEqual(R, undefined) }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/union.ts000066400000000000000000000175701505437577000255630ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Type } from '@sinclair/typebox' describe('value/transform/Union', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- // prettier-ignore const T0 = Type.Transform(Type.Union([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ])) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, { x: 1 }) Assert.IsEqual(R, { x: 1 }) }) it('Should encode identity', () => { const R = Encoder.Encode(T0, { y: 2 }) Assert.IsEqual(R, { y: 2 }) }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, null)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- // prettier-ignore const T1 = Type.Transform(Type.Union([ Type.Object({ type: Type.Literal('hello') }), Type.Object({ type: Type.Literal('world') }) ])) .Decode((value) => 'test' as const) .Encode((value) => ({ type: 'hello' as const })) it('Should decode mapped', () => { const R = Encoder.Decode(T1, { type: 'hello' }) Assert.IsEqual(R, 'test') }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, 'test') Assert.IsEqual(R, { type: 'hello' }) }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) // -------------------------------------------------------- // Mapped ValueType // -------------------------------------------------------- const M21 = Type.Transform(Type.Number()) .Decode((value) => value + 1) .Encode((value) => value - 1) const M22 = Type.Transform(M21) .Decode((value) => value + 1) .Encode((value) => value - 1) // prettier-ignore const T2 = Type.Transform(Type.Union([Type.String(), M22])) .Decode((value) => value) .Encode((value) => { if (value === 'hello') return 'world' return value }) it('Should decode value type 1', () => { const R = Encoder.Decode(T2, 0) Assert.IsEqual(R, 2) }) it('Should decode value type 2', () => { const R = Encoder.Decode(T2, 'hello') Assert.IsEqual(R, 'hello') }) it('Should encode value type 1', () => { const R = Encoder.Encode(T2, 'hello') Assert.IsEqual(R, 'world') }) it('Should encode value type 2', () => { const R = Encoder.Encode(T2, 2) Assert.IsEqual(R, 0) }) it('Should throw on value type decode', () => { Assert.Throws(() => Encoder.Decode(T2, null)) }) // -------------------------------------------------------- // Mapped ObjectType // -------------------------------------------------------- const N31 = Type.Transform( Type.Object({ x: Type.Number(), }), ) .Decode((value) => ({ x: value.x + 1 })) .Encode((value) => ({ x: value.x - 1 })) const N32 = Type.Transform( Type.Object({ x: Type.String(), }), ) .Decode((value) => ({ x: value.x.split('').reverse().join('') })) .Encode((value) => ({ x: value.x.split('').reverse().join('') })) // prettier-ignore const T3 = Type.Transform(Type.Union([N31, N32])) .Decode((value) => value) .Encode((value) => value) it('Should decode object types 1', () => { const R = Encoder.Decode(T3, { x: 0 }) Assert.IsEqual(R, { x: 1 }) }) it('Should decode object types 2', () => { const R = Encoder.Decode(T3, { x: 'abc' }) Assert.IsEqual(R, { x: 'cba' }) }) it('Should encode object types 1', () => { const R = Encoder.Encode(T3, { x: 1 }) Assert.IsEqual(R, { x: 0 }) }) it('Should encode object types 2', () => { const R = Encoder.Encode(T3, { x: 'cba' }) Assert.IsEqual(R, { x: 'abc' }) }) it('Should throw on object types decode', () => { Assert.Throws(() => Encoder.Decode(T3, null)) }) // -------------------------------------------------------- // Mapped Mixed Types // -------------------------------------------------------- const N41 = Type.Transform(Type.Number()) .Decode((value) => value + 1) .Encode((value) => value - 1) // prettier-ignore const N42 = Type.Transform(Type.Object({ x: Type.Number() })) .Decode((value) => ({ x: value.x + 1 })) .Encode((value) => ({ x: value.x - 1 })) const N43 = Type.Transform(Type.Tuple([Type.Number()])) .Decode((value) => [value[0] + 1]) .Encode((value) => [value[0] - 1] as [number]) // prettier-ignore const T4 = Type.Transform(Type.Union([N41, N42, N43])) .Decode((value) => typeof value === 'number' ? value + 1 : value) .Encode((value) => typeof value === 'number' ? value - 1 : value) it('Should decode mixed types 1', () => { const R = Encoder.Decode(T4, { x: 0 }) Assert.IsEqual(R, { x: 1 }) }) it('Should decode mixed types 2', () => { const R = Encoder.Decode(T4, 0) Assert.IsEqual(R, 2) }) it('Should decode mixed types 3', () => { const R = Encoder.Decode(T4, [0]) Assert.IsEqual(R, [1]) }) it('Should encode mixed types 1', () => { const R = Encoder.Encode(T4, { x: 1 }) Assert.IsEqual(R, { x: 0 }) }) it('Should encode mixed types 2', () => { const R = Encoder.Encode(T4, 2) Assert.IsEqual(R, 0) }) it('Should encode mixed types 3', () => { const R = Encoder.Encode(T4, [1]) Assert.IsEqual(R, [0]) }) it('Should throw on mixed types decode', () => { Assert.Throws(() => Encoder.Decode(T4, null)) }) // -------------------------------------------------------- // Interior Union Transform // // https://github.com/sinclairzx81/typebox/issues/631 // -------------------------------------------------------- const T51 = Type.Transform(Type.String()) .Decode((value) => new Date(value)) .Encode((value) => value.toISOString()) const T52 = Type.Union([Type.Null(), T51]) it('Should decode interior union 1', () => { const R = Encoder.Decode(T52, null) Assert.IsEqual(R, null) }) it('Should decode interior union 2', () => { const R = Encoder.Decode(T52, new Date().toISOString()) Assert.IsInstanceOf(R, Date) }) it('Should encode interior union 1', () => { const R = Encoder.Encode(T52, null) Assert.IsEqual(R, null) }) it('Should encode interior union 2', () => { const D = new Date() const R = Encoder.Encode(T52, D) Assert.IsEqual(R, D.toISOString()) }) it('Should throw on interior union decode', () => { Assert.Throws(() => Encoder.Decode(T52, {})) }) it('Should throw on interior union encode', () => { Assert.Throws(() => Encoder.Encode(T52, 1)) }) // prettier-ignore { // https://github.com/sinclairzx81/typebox/issues/676 // interior-type const S = Type.Transform(Type.String()) .Decode((value: string) => new globalThis.Date(value)) .Encode((value: Date) => value.toISOString()) // union-type const U = Type.Union([ Type.Object({ date: S }), Type.Number() ]) // expect date on decode const T1 = Type.Transform(U) .Decode((value) => { Assert.IsTypeOf(value, 'object') Assert.HasProperty(value, 'date') Assert.IsInstanceOf(value.date, globalThis.Date); return value }) .Encode((value) => value) // expect number on decode const T2 = Type.Transform(U) .Decode((value) => { Assert.IsTypeOf(value, 'number') return value }) .Encode((value) => value) it('Should decode interior union 1', () => { const R = Encoder.Decode(T1, { date: new globalThis.Date().toISOString() }) Assert.IsTypeOf(R, 'object') Assert.HasProperty(R, 'date') Assert.IsInstanceOf(R.date, globalThis.Date); }) it('Should decode interior union 2', () => { const R = Encoder.Decode(T2, 123) Assert.IsTypeOf(R, 'number') Assert.IsEqual(R, 123) }) } }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/unknown.ts000066400000000000000000000021311505437577000261150ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Unknown', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Type.Unknown()) .Decode((value) => value) .Encode((value) => value) it('Should decode mapped', () => { const R = Encoder.Decode(T0, 123) Assert.IsEqual(R, 123) }) it('Should encode mapped', () => { const R = Encoder.Encode(T0, 123) Assert.IsEqual(R, 123) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Type.Unknown()) .Decode((value) => 1) .Encode((value) => 2) it('Should decode mapped', () => { const R = Encoder.Decode(T1, null) Assert.IsEqual(R, 1) }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, null) Assert.IsEqual(R, 2) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/unsafe.ts000066400000000000000000000033171505437577000257060ustar00rootroot00000000000000import * as Encoder from './_encoder' import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type, Kind, TypeRegistry } from '@sinclair/typebox' describe('value/transform/Unsafe', () => { // -------------------------------------------------------- // Fixtures // -------------------------------------------------------- beforeEach(() => TypeRegistry.Set('Foo', (schema, value) => value !== null)) // throw on null afterEach(() => TypeRegistry.Delete('Foo')) const Foo = Type.Unsafe({ [Kind]: 'Foo' }) // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Foo) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Encoder.Decode(T0, 'hello') Assert.IsEqual(R, 'hello') }) it('Should encode identity', () => { const R = Encoder.Encode(T0, 'hello') Assert.IsEqual(R, 'hello') }) it('Should throw on identity decode', () => { Assert.Throws(() => Encoder.Decode(T0, null)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Foo) .Decode((value) => value.split('').reverse().join('')) .Encode((value) => value.split('').reverse().join('')) it('Should decode mapped', () => { const R = Encoder.Decode(T1, 'ABC') Assert.IsEqual(R, 'CBA') }) it('Should encode mapped', () => { const R = Encoder.Encode(T1, 'CBA') Assert.IsEqual(R, 'ABC') }) it('Should throw on mapped decode', () => { Assert.Throws(() => Encoder.Decode(T1, null)) }) }) sinclairzx81-typebox-e0ec98c/test/runtime/value/transform/void.ts000066400000000000000000000024411505437577000253630ustar00rootroot00000000000000import { Assert } from '../../assert' import { Value } from '@sinclair/typebox/value' import { Type } from '@sinclair/typebox' describe('value/transform/Void', () => { // -------------------------------------------------------- // Identity // -------------------------------------------------------- const T0 = Type.Transform(Type.Void()) .Decode((value) => value) .Encode((value) => value) it('Should decode identity', () => { const R = Value.Decode(T0, undefined) Assert.IsEqual(R, undefined) }) it('Should encode identity', () => { const R = Value.Encode(T0, undefined) Assert.IsEqual(R, undefined) }) it('Should throw on identity decode', () => { Assert.Throws(() => Value.Decode(T0, null)) }) // -------------------------------------------------------- // Mapped // -------------------------------------------------------- const T1 = Type.Transform(Type.Void()) .Decode((value) => null) .Encode((value) => undefined) it('Should decode mapped', () => { const R = Value.Decode(T1, undefined) Assert.IsEqual(R, null) }) it('Should encode mapped', () => { const R = Value.Encode(T1, null) Assert.IsEqual(R, undefined) }) it('Should throw on mapped decode', () => { Assert.Throws(() => Value.Decode(T1, null)) }) }) sinclairzx81-typebox-e0ec98c/test/static/000077500000000000000000000000001505437577000205265ustar00rootroot00000000000000sinclairzx81-typebox-e0ec98c/test/static/any.ts000066400000000000000000000001571505437577000216700ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' Expect(Type.Any()).ToStatic() sinclairzx81-typebox-e0ec98c/test/static/argument.ts000066400000000000000000000007011505437577000227160ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' const T = Type.Object({ x: Type.Argument(0), y: Type.Argument(1), z: Type.Argument(2), }) const I = Type.Instantiate(T, [Type.Literal(1), Type.Literal(2), Type.Literal(3)]) // Infer as Broadest Type (Pending Generic Constraints) Expect(T).ToStatic<{ x: unknown y: unknown z: unknown }>() // Infer as Narrowed Type Expect(I).ToStatic<{ x: 1 y: 2 z: 3 }>() sinclairzx81-typebox-e0ec98c/test/static/array.ts000066400000000000000000000007541505437577000222220ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' Expect(Type.Array(Type.String())).ToStatic() Expect( Type.Array( Type.Object({ x: Type.Number(), y: Type.Boolean(), z: Type.String(), }), ), ).ToStatic< { x: number y: boolean z: string }[] >() Expect(Type.Array(Type.Array(Type.String()))).ToStatic() Expect(Type.Array(Type.Tuple([Type.String(), Type.Number()]))).ToStatic<[string, number][]>() sinclairzx81-typebox-e0ec98c/test/static/assert.ts000066400000000000000000000055421505437577000224050ustar00rootroot00000000000000import { Static, StaticDecode, StaticEncode, TSchema } from '@sinclair/typebox' // ------------------------------------------------------------------ // Symbols // ------------------------------------------------------------------ export declare const Unsatisfiable: unique symbol // Warning: `never` and `any` satisfy the constraint `extends Expected<...>` export type Expected<_> = { [Unsatisfiable]: never } // ------------------------------------------------------------------ // Gates // ------------------------------------------------------------------ export type If = T extends true ? Y : N export type And = If export type Or = If export type Not = If // ------------------------------------------------------------------ // Helpers // ------------------------------------------------------------------ export type Extends = [T] extends [U] ? true : false export type IsAny = 0 extends 1 & T ? true : false export type IsNever = Extends // ------------------------------------------------------------------ // Constraints // ------------------------------------------------------------------ // See https://github.com/microsoft/TypeScript/issues/51011 export type CircularHelper = [T] extends U ? T : Expected // See https://github.com/Microsoft/TypeScript/issues/27024 export type ConstrainEqual = (() => V extends T ? 1 : 2) extends () => V extends U ? 1 : 2 ? T : Expected export type ConstraintMutuallyExtend = CircularHelper // Circular Error on TS 5.4.0 // If U is never, there's nothing we can do // export type ComplexConstraint = If< // // If U is any, we can't use Expect or it would satisfy the constraint // And>, IsAny>, // never, // If< // Or< // // If they are both any we are happy // And, IsAny>, // // If T extends U, but not because it's any, we are happy // And, Not>> // >, // T, // Expected // > // > // ------------------------------------------------------------------ // Expect // ------------------------------------------------------------------ export type ExpectResult = If< IsNever>, { ToStaticNever(): void }, { ToStatic, U>>(): void ToStaticDecode, U>>(): void ToStaticEncode, U>>(): void // ToStatic>(): void // ToStaticDecode>(): void // ToStaticEncode>(): void } > export function Expect(schema: T) { return { ToStatic() {}, ToStaticNever() {}, ToStaticDecode() {}, ToStaticEncode() {}, } as ExpectResult } sinclairzx81-typebox-e0ec98c/test/static/async-iterator.ts000066400000000000000000000002401505437577000240360ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' Expect(Type.AsyncIterator(Type.String())).ToStatic>() sinclairzx81-typebox-e0ec98c/test/static/awaited.ts000066400000000000000000000015721505437577000225210ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' Expect(Type.Awaited(Type.String())).ToStatic() Expect(Type.Awaited(Type.Promise(Type.String()))).ToStatic() Expect(Type.Awaited(Type.Promise(Type.Promise(Type.String())))).ToStatic() // One Level Expect(Type.Awaited(Type.Union([Type.Promise(Type.String()), Type.Number()]))).ToStatic() Expect(Type.Awaited(Type.Intersect([Type.Promise(Type.Object({ a: Type.String() })), Type.Object({ b: Type.Number() })]))).ToStatic<{ a: string } & { b: number }>() // Two Levels Expect(Type.Awaited(Type.Union([Type.Promise(Type.Promise(Type.String())), Type.Number()]))).ToStatic() Expect(Type.Awaited(Type.Intersect([Type.Promise(Type.Promise(Type.Object({ a: Type.String() }))), Type.Object({ b: Type.Number() })]))).ToStatic<{ a: string } & { b: number }>() sinclairzx81-typebox-e0ec98c/test/static/bigint.ts000066400000000000000000000001651505437577000223540ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' Expect(Type.BigInt()).ToStatic() sinclairzx81-typebox-e0ec98c/test/static/boolean.ts000066400000000000000000000001671505437577000225210ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' Expect(Type.Boolean()).ToStatic() sinclairzx81-typebox-e0ec98c/test/static/capitalize.ts000066400000000000000000000011601505437577000232210ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' Expect(Type.Capitalize(Type.Literal('hello'))).ToStatic<'Hello'>() Expect(Type.Capitalize(Type.Union([Type.Literal('hello'), Type.Literal('world')]))).ToStatic<'Hello' | 'World'>() Expect(Type.Capitalize(Type.TemplateLiteral('hello${0|1}'))).ToStatic<'Hello0' | 'Hello1'>() // prettier-ignore Expect(Type.Capitalize(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(1), Type.Literal(2)])]))).ToStatic<'Hello1' | 'Hello2'>() // passthrough Expect(Type.Capitalize(Type.Object({ x: Type.Number() }))).ToStatic<{ x: number }>() sinclairzx81-typebox-e0ec98c/test/static/composite.ts000066400000000000000000000123301505437577000230770ustar00rootroot00000000000000import { Expect } from './assert' import { Type, TOptional, TObject, TUnion, TIntersect, TNumber, TString, TBoolean } from '@sinclair/typebox' // ---------------------------------------------------------------------------- // Overlapping - Non Varying // ---------------------------------------------------------------------------- { const A = Type.Object({ A: Type.Number(), }) const B = Type.Object({ A: Type.Number(), }) const T = Type.Composite([A, B]) Expect(T).ToStatic<{ A: number }>() } // ---------------------------------------------------------------------------- // Overlapping - Varying // ---------------------------------------------------------------------------- { const A = Type.Object({ A: Type.Number(), }) const B = Type.Object({ A: Type.String(), }) const T = Type.Composite([A, B]) Expect(T).ToStatic<{ A: never }>() } // ---------------------------------------------------------------------------- // Overlapping Single Optional // ---------------------------------------------------------------------------- { const A = Type.Object({ A: Type.Optional(Type.Number()), }) const B = Type.Object({ A: Type.Number(), }) const T = Type.Composite([A, B]) Expect(T).ToStatic<{ A: number }>() } // ---------------------------------------------------------------------------- // Overlapping All Optional (Deferred) // // Note for: https://github.com/sinclairzx81/typebox/issues/419 // ---------------------------------------------------------------------------- { const A = Type.Object({ A: Type.Optional(Type.Number()), }) const B = Type.Object({ A: Type.Optional(Type.Number()), }) const T = Type.Composite([A, B]) Expect(T).ToStatic<{ A?: number | undefined }>() } { const A = Type.Object({ A: Type.Optional(Type.Number()), }) const B = Type.Object({ A: Type.Number(), }) const T = Type.Composite([A, B]) Expect(T).ToStatic<{ A: number }>() } { const A = Type.Object({ A: Type.Number(), }) const B = Type.Object({ A: Type.Number(), }) const T = Type.Composite([A, B]) Expect(T).ToStatic<{ A: number }>() } // ---------------------------------------------------------------------------- // Distinct Properties // ---------------------------------------------------------------------------- { const A = Type.Object({ A: Type.Number(), }) const B = Type.Object({ B: Type.Number(), }) const T = Type.Composite([A, B]) Expect(T).ToStatic<{ A: number B: number }>() } // ---------------------------------------------------------------------------- // Intersection Quirk // // TypeScript has an evaluation quirk for the following case where the first // type evaluates the sub property as never, but the second evaluates the // entire type as never. There is probably a reason for this behavior, but // TypeBox supports the former evaluation. // // { x: number } & { x: string } -> { x: number } & { x: string } => { x: never } // { x: number } & { x: boolean } -> never -> ... // ---------------------------------------------------------------------------- { // prettier-ignore const T: TObject<{ x: TIntersect<[TNumber, TBoolean]> }> = Type.Composite([ Type.Object({ x: Type.Number() }), Type.Object({ x: Type.Boolean() }) ]) } // ------------------------------------------------------------------ // Intersect // ------------------------------------------------------------------ // prettier-ignore { const T: TObject<{ x: TNumber; y: TNumber; z: TNumber; }> = Type.Composite([ Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }), ]), Type.Intersect([ Type.Object({ z: Type.Number() }) ]) ]) } // prettier-ignore { const T: TObject<{ x: TIntersect<[TNumber, TNumber]>; y: TIntersect<[TNumber, TNumber]>; }> = Type.Composite([ Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }), ]), Type.Intersect([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }), ]) ]) } // prettier-ignore { const T: TObject<{ x: TIntersect<[TNumber, TNumber]>; }> = Type.Composite([ Type.Intersect([ Type.Object({ x: Type.Optional(Type.Number()) }), Type.Object({ x: Type.Number() }), ]) ]) } // prettier-ignore { const T: TObject<{ x: TOptional>; }> = Type.Composite([ Type.Intersect([ Type.Object({ x: Type.Optional(Type.Number()) }), Type.Object({ x: Type.Optional(Type.Number()) }), ]) ]) } // ------------------------------------------------------------------ // Union // ------------------------------------------------------------------ // prettier-ignore { const T: TObject<{ x: TNumber; }> = Type.Composite([ Type.Union([ Type.Object({ x: Type.Number() }), Type.Object({ y: Type.Number() }) ]), Type.Object({ x: Type.Number() }) ]) } // prettier-ignore { const T: TObject<{ x: TIntersect<[TUnion<[TString, TString]>, TNumber]>; }> = Type.Composite([ Type.Union([ Type.Object({ x: Type.String() }), Type.Object({ x: Type.String() }) ]), Type.Object({ x: Type.Number() }) ]) } sinclairzx81-typebox-e0ec98c/test/static/const.ts000066400000000000000000000031421505437577000222240ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' // ------------------------------------------------------------------ // Identity Types // ------------------------------------------------------------------ // prettier-ignore Expect(Type.Const(undefined)).ToStatic() // prettier-ignore Expect(Type.Const(null)).ToStatic() // prettier-ignore Expect(Type.Const(Symbol())).ToStatic() // prettier-ignore Expect(Type.Const(1 as const)).ToStatic<1>() // prettier-ignore Expect(Type.Const('hello' as const)).ToStatic<'hello'>() // prettier-ignore Expect(Type.Const(true as const)).ToStatic() // ------------------------------------------------------------------ // Complex Types // ------------------------------------------------------------------ // prettier-ignore Expect(Type.Const(100n)).ToStatic() // prettier-ignore Expect(Type.Const(new Date())).ToStatic() // prettier-ignore Expect(Type.Const(new Uint8Array())).ToStatic() // prettier-ignore Expect(Type.Const(function () {})).ToStatic<() => unknown>() // prettier-ignore Expect(Type.Const((function *(): any {})())).ToStatic() // prettier-ignore Expect(Type.Const((async function *(): any {})())).ToStatic() // todo: remove when dropping TS 4.0 // prettier-ignore Expect(Type.Const({ x: 1, y: { z: 2 } })).ToStatic<{ readonly x: number, readonly y: { readonly z: number }}>() // prettier-ignore Expect(Type.Const({ x: 1, y: { z: 2 } } as const)).ToStatic<{ readonly x: 1, readonly y: { readonly z: 2 }}>() // prettier-ignore Expect(Type.Const([1, 2, 3] as const)).ToStatic<[1, 2, 3]>() sinclairzx81-typebox-e0ec98c/test/static/constructor-parameters.ts000066400000000000000000000004761505437577000256330ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' const C = Type.Constructor( [Type.Number(), Type.String()], Type.Object({ method: Type.Function([Type.Number(), Type.String()], Type.Boolean()), }), ) const P = Type.ConstructorParameters(C) Expect(P).ToStatic<[number, string]>() sinclairzx81-typebox-e0ec98c/test/static/constructor.ts000066400000000000000000000034001505437577000234600ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' { // simple const T = Type.Constructor([Type.Number(), Type.Boolean()], Type.String()) Expect(T).ToStatic string>() } { // nested // prettier-ignore const T = Type.Constructor([Type.Number(), Type.String()], Type.Object({ method: Type.Constructor([Type.Number(), Type.String()], Type.Boolean()), })) Expect(T).ToStatic { method: new (param_0: number, param_1: string) => boolean }>() } { // readonly-optional const T = Type.Constructor([Type.ReadonlyOptional(Type.Array(Type.Number()))], Type.Number()) Expect(T).ToStaticDecode number>() } { // readonly const T = Type.Constructor([Type.Readonly(Type.Array(Type.Number()))], Type.Number()) Expect(T).ToStaticDecode number>() } { // optional 1 const T = Type.Constructor([Type.Optional(Type.Number())], Type.Number()) Expect(T).ToStaticDecode number>() } { // optional 2 const T = Type.Constructor([Type.Number(), Type.Optional(Type.Number())], Type.Number()) Expect(T).ToStaticDecode number>() } { // decode 2 const S = Type.Transform(Type.Integer()) .Decode((value) => new Date(value)) .Encode((value) => value.getTime()) const T = Type.Constructor([S], Type.String()) Expect(T).ToStaticDecode string>() } { // decode 1 const S = Type.Transform(Type.Integer()) .Decode((value) => new Date(value)) .Encode((value) => value.getTime()) const T = Type.Constructor([Type.Number()], S) Expect(T).ToStaticDecode Date>() } sinclairzx81-typebox-e0ec98c/test/static/date.ts000066400000000000000000000001611505437577000220110ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' Expect(Type.Date()).ToStatic() sinclairzx81-typebox-e0ec98c/test/static/enum.ts000066400000000000000000000013361505437577000220450ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' { // expect all variants enum E { A, B = 'hello', C = 42, } const T = Type.Enum(E) Expect(T).ToStatic() } { // expect all variants const T = Type.Enum({ A: 1, B: 2, C: 3, }) Expect(T).ToStatic<1 | 2 | 3>() } { // expect variant overlap to reduce const T = Type.Enum({ A: 1, B: 2, C: 2, // overlap }) Expect(T).ToStatic<1 | 2>() } { // expect empty enum to be string (as empty enums T[keyof T] evaluates as string) enum E {} const T = Type.Enum(E) Expect(T).ToStatic() } { // expect empty enum to be never const T = Type.Enum({}) Expect(T).ToStaticNever() } sinclairzx81-typebox-e0ec98c/test/static/exclude.ts000066400000000000000000000070061505437577000225320ustar00rootroot00000000000000import { Type, TLiteral, TUnion } from '@sinclair/typebox' import { Expect } from './assert' { const T = Type.Exclude(Type.String(), Type.String()) Expect(T).ToStaticNever() } { const T = Type.Exclude(Type.String(), Type.Number()) Expect(T).ToStatic() } { const T = Type.Exclude(Type.Union([Type.Number(), Type.String(), Type.Boolean()]), Type.Number()) Expect(T).ToStatic() } // ------------------------------------------------------------------------ // TemplateLiteral | TemplateLiteral // ------------------------------------------------------------------------ { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const T = Type.Exclude(A, B) Expect(T).ToStaticNever() } { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])]) const T = Type.Exclude(A, B) Expect(T).ToStatic<'C'>() } { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A')])]) const T = Type.Exclude(A, B) Expect(T).ToStatic<'C' | 'B'>() } // ------------------------------------------------------------------------ // TemplateLiteral | Union // ------------------------------------------------------------------------ { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const T = Type.Exclude(A, B) Expect(T).ToStaticNever() } { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.Union([Type.Literal('A'), Type.Literal('B')]) const T = Type.Exclude(A, B) Expect(T).ToStatic<'C'>() } { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.Union([Type.Literal('A')]) const T = Type.Exclude(A, B) Expect(T).ToStatic<'C' | 'B'>() } // ------------------------------------------------------------------------ // Union | TemplateLiteral // ------------------------------------------------------------------------ { const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const T = Type.Exclude(A, B) Expect(T).ToStaticNever() } { const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])]) const T = Type.Exclude(A, B) Expect(T).ToStatic<'C'>() } { const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A')])]) const T = Type.Exclude(A, B) Expect(T).ToStatic<'C' | 'B'>() } // https://github.com/sinclairzx81/typebox/issues/737 { const U = Type.Union([Type.Literal('A'), Type.Literal('B')]) const T = Type.Object({ type: Type.Exclude(U, Type.Literal('A')), }) Expect(T).ToStatic<{ type: 'B' }>() } { const U = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const T = Type.Object({ type: Type.Exclude(U, Type.Literal('A')), }) Expect(T).ToStatic<{ type: 'B' | 'C' }>() } sinclairzx81-typebox-e0ec98c/test/static/extract.ts000066400000000000000000000072751505437577000225630ustar00rootroot00000000000000import { Type, TLiteral, TUnion } from '@sinclair/typebox' import { Expect } from './assert' { const T = Type.Extract(Type.String(), Type.String()) Expect(T).ToStatic() } { const T = Type.Extract(Type.String(), Type.Number()) Expect(T).ToStaticNever() } { const T = Type.Extract(Type.Union([Type.Number(), Type.String(), Type.Boolean()]), Type.Number()) Expect(T).ToStatic() } // ------------------------------------------------------------------------ // TemplateLiteral | TemplateLiteral // ------------------------------------------------------------------------ { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const T = Type.Extract(A, B) Expect(T).ToStatic<'A' | 'B' | 'C'>() } { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])]) const T = Type.Extract(A, B) Expect(T).ToStatic<'A' | 'B'>() } { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A')])]) const T = Type.Extract(A, B) Expect(T).ToStatic<'A'>() } // ------------------------------------------------------------------------ // TemplateLiteral | Union // ------------------------------------------------------------------------ { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const T = Type.Extract(A, B) Expect(T).ToStatic<'A' | 'B' | 'C'>() } { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.Union([Type.Literal('A'), Type.Literal('B')]) const T = Type.Extract(A, B) Expect(T).ToStatic<'A' | 'B'>() } { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const B = Type.Union([Type.Literal('A')]) const T = Type.Extract(A, B) Expect(T).ToStatic<'A'>() } // ------------------------------------------------------------------------ // Union | TemplateLiteral // ------------------------------------------------------------------------ { const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')])]) const T = Type.Extract(A, B) Expect(T).ToStatic<'A' | 'B' | 'C'>() } { const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])]) const T = Type.Extract(A, B) Expect(T).ToStatic<'A' | 'B'>() } { const A = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('A')])]) const T = Type.Extract(A, B) Expect(T).ToStatic<'A'>() } // ------------------------------------------------------------------------ // Nested (Inference Test) // ------------------------------------------------------------------------ { const U = Type.Union([Type.Literal('A'), Type.Literal('B')]) const T = Type.Object({ type: Type.Extract(U, Type.Literal('A')), }) Expect(T).ToStatic<{ type: 'A' }>() } { const U = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const T = Type.Object({ type: Type.Extract(U, Type.Union([Type.Literal('A'), Type.Literal('B')])), }) Expect(T).ToStatic<{ type: 'A' | 'B' }>() } sinclairzx81-typebox-e0ec98c/test/static/function.ts000066400000000000000000000034311505437577000227240ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' { // simple const T = Type.Function([Type.Number(), Type.Boolean()], Type.String()) Expect(T).ToStatic<(param_0: number, param_1: boolean) => string>() } { // nested // prettier-ignore const T = Type.Function([Type.Number(), Type.String()], Type.Object({ method: Type.Function([Type.Number(), Type.String()], Type.Boolean()), })) Expect(T).ToStatic<(param_0: number, param_1: string) => { method: (param_0: number, param_1: string) => boolean }>() } { // readonly-optional const T = Type.Function([Type.ReadonlyOptional(Type.Array(Type.Number()))], Type.Number()) Expect(T).ToStaticDecode<(param_0?: readonly number[]) => number>() } { // readonly const T = Type.Function([Type.Readonly(Type.Array(Type.Number()))], Type.Number()) Expect(T).ToStaticDecode<(param_0: readonly number[]) => number>() } { // optional 1 const T = Type.Function([Type.Optional(Type.Number())], Type.Number()) Expect(T).ToStaticDecode<(param_0?: number) => number>() } { // optional 2 const T = Type.Function([Type.Number(), Type.Optional(Type.Number())], Type.Number()) Expect(T).ToStaticDecode<(param_0: number, param_1?: number) => number>() } const F = Type.Constructor([Type.Readonly(Type.Array(Type.String()))], Type.Number()) { // decode 2 const S = Type.Transform(Type.Integer()) .Decode((value) => new Date(value)) .Encode((value) => value.getTime()) const T = Type.Function([S], Type.String()) Expect(T).ToStaticDecode<(param_0: Date) => string>() } { // decode 1 const S = Type.Transform(Type.Integer()) .Decode((value) => new Date(value)) .Encode((value) => value.getTime()) const T = Type.Function([Type.Number()], S) Expect(T).ToStaticDecode<(param_0: number) => Date>() } sinclairzx81-typebox-e0ec98c/test/static/import.ts000066400000000000000000000072141505437577000224140ustar00rootroot00000000000000import { Expect } from './assert' import { Type, Static } from '@sinclair/typebox' // ------------------------------------------------------------------ // Enum 1 // ------------------------------------------------------------------ { enum Enum { A, B, } const T = Type.Module({ T: Type.Object({ value: Type.Enum(Enum), }), }).Import('T') Expect(T).ToStatic<{ value: Enum }>() } // ------------------------------------------------------------------ // Enum 2 // ------------------------------------------------------------------ { const T = Type.Module({ T: Type.Object({ value: Type.Enum({ x: 1, y: 2, }), }), }).Import('T') Expect(T).ToStatic<{ value: 1 | 2 }>() } // ------------------------------------------------------------------ // Record 1 // ------------------------------------------------------------------ // prettier-ignore { const T = Type.Module({ R: Type.Object({ x: Type.Number(), y: Type.Number() }), T: Type.Record(Type.String(), Type.Ref('R')), }).Import('T') type T = Static Expect(T).ToStatic<{ [key: string]: { x: number, y: number } }>() } // ------------------------------------------------------------------ // Record 2 // ------------------------------------------------------------------ // prettier-ignore { const T = Type.Module({ R: Type.Object({ x: Type.Number(), y: Type.Number() }), T: Type.Record(Type.String(), Type.Partial(Type.Ref('R'))), }).Import('T') type T = Static Expect(T).ToStatic<{ [key: string]: { x?: number, y?: number } }>() } // ------------------------------------------------------------------ // Modifiers 1 // ------------------------------------------------------------------ // prettier-ignore { const Module = Type.Module({ T: Type.Object({ x: Type.ReadonlyOptional(Type.Null()), y: Type.Readonly(Type.Null()), z: Type.Optional(Type.Null()), w: Type.Null() }) }) const T = Module.Import('T') type T = Static Expect(T).ToStatic<{ readonly x?: null, readonly y: null, z?: null, w: null }>() } // ------------------------------------------------------------------ // Modifiers 2 // ------------------------------------------------------------------ // prettier-ignore { const Module = Type.Module({ T: Type.Object({ x: Type.ReadonlyOptional(Type.Array(Type.Null())), y: Type.Readonly(Type.Array(Type.Null())), z: Type.Optional(Type.Array(Type.Null())), w: Type.Array(Type.Null()) }) }) const T = Module.Import('T') type T = Static Expect(T).ToStatic<{ readonly x?: null[], readonly y: null[], z?:null[], w: null[] }>() } // ------------------------------------------------------------------ // Modifiers 3 // ------------------------------------------------------------------ // prettier-ignore { const Module = Type.Module({ T: Type.Object({ x: Type.Array(Type.Null()) }), // Computed Partial U: Type.Partial(Type.Ref('T')) }) const T = Module.Import('U') type T = Static Expect(T).ToStatic<{ x?: null[], }>() } // ------------------------------------------------------------------ // Ref inside Recursive // ------------------------------------------------------------------ // prettier-ignore { const Module = Type.Module({ T: Type.Recursive((_) => Type.Object({ M: Type.Ref("U"), }) ), U: Type.Union([ Type.Literal("A"), Type.Literal("B") ]), }); const T = Module.Import("T"); type T = Static; Expect(T).ToStatic<{ M: 'A'|'B' }>(); } sinclairzx81-typebox-e0ec98c/test/static/index.ts000066400000000000000000000021571505437577000222120ustar00rootroot00000000000000import './any' import './argument' import './array' import './async-iterator' import './awaited' import './bigint' import './boolean' import './capitalize' import './composite' import './const' import './constructor-parameters' import './constructor' import './date' import './deref' import './enum' import './extract' import './exclude' import './function' import './import' import './indexed' import './instance-type' import './intersect' import './iterator' import './keyof' import './literal' import './lowercase' import './mapped' import './modifier' import './namespace' import './never' import './not' import './null' import './number' import './object' import './omit' import './optional' import './parameters' import './partial' import './pick' import './readonly-optional' import './readonly' import './recursive' import './record' import './ref' import './regexp' import './required' import './rest' import './return-type' import './string' import './symbol' import './syntax' import './template-literal' import './transform' import './tuple' import './uncapitalize' import './union' import './unknown' import './uppercase' sinclairzx81-typebox-e0ec98c/test/static/indexed.ts000066400000000000000000000203121505437577000225140ustar00rootroot00000000000000import { Expect } from './assert' import { Type, Static } from '@sinclair/typebox' { const T = Type.Object({ x: Type.Number(), y: Type.String(), }) const R = Type.Index(T, ['x', 'y']) type O = Static Expect(R).ToStatic() } { const T = Type.Tuple([Type.Number(), Type.String(), Type.Boolean()]) const R = Type.Index(T, Type.Union([Type.Literal('0'), Type.Literal('1')])) type O = Static Expect(R).ToStatic() } { const T = Type.Tuple([Type.Number(), Type.String(), Type.Boolean()]) const R = Type.Index(T, Type.Union([Type.Literal(0), Type.Literal(1)])) type O = Static Expect(R).ToStatic() } { const T = Type.Object({ ab: Type.Number(), ac: Type.String(), }) const R = Type.Index(T, Type.TemplateLiteral([Type.Literal('a'), Type.Union([Type.Literal('b'), Type.Literal('c')])])) type O = Static Expect(R).ToStatic() } { const A = Type.Tuple([Type.String(), Type.Boolean()]) const R = Type.Index(A, Type.Number()) type O = Static Expect(R).ToStatic() } { const A = Type.Tuple([Type.String()]) const R = Type.Index(A, Type.Number()) type O = Static Expect(R).ToStatic() } { const A = Type.Tuple([]) const R = Type.Index(A, Type.Number()) type O = Static Expect(R).ToStaticNever() } { const A = Type.Object({}) const R = Type.Index(A, Type.BigInt()) // Support Overload type O = Static Expect(R).ToStaticNever() } { const A = Type.Array(Type.Number()) const R = Type.Index(A, Type.BigInt()) // Support Overload type O = Static Expect(R).ToStaticNever() } // ------------------------------------------------------------------ // Intersections // ------------------------------------------------------------------ { type A = { x: string; y: 1 } type B = { x: string; y: number } type C = A & B type R = C['y'] const A = Type.Object({ x: Type.String(), y: Type.Literal(1) }) const B = Type.Object({ x: Type.String(), y: Type.Number() }) const C = Type.Intersect([A, B]) const R = Type.Index(C, ['y']) type O = Static Expect(R).ToStatic<1>() } { type A = { x: string; y: 1 } type B = { x: string; y: number } type C = A & B type R = C['x'] const A = Type.Object({ x: Type.String(), y: Type.Literal(1) }) const B = Type.Object({ x: Type.String(), y: Type.Number() }) const C = Type.Intersect([A, B]) const R = Type.Index(C, ['x']) type O = Static Expect(R).ToStatic() } { type A = { x: string; y: 1 } type B = { x: string; y: number } type C = A & B type R = C['x' | 'y'] const A = Type.Object({ x: Type.String(), y: Type.Literal(1) }) const B = Type.Object({ x: Type.String(), y: Type.Number() }) const C = Type.Intersect([A, B]) const R = Type.Index(C, ['x', 'y']) type O = Static Expect(R).ToStatic() } { type A = { x: string; y: number } type B = { x: number; y: number } type C = A & B type R = C['x'] const A = Type.Object({ x: Type.String(), y: Type.Number() }) const B = Type.Object({ x: Type.Number(), y: Type.Number() }) const C = Type.Intersect([A, B]) const R = Type.Index(C, ['x']) type O = Static Expect(R).ToStaticNever() } { type A = { x: string; y: number } type B = { x: number; y: number } type C = A & B type R = C['y'] const A = Type.Object({ x: Type.String(), y: Type.Number() }) const B = Type.Object({ x: Type.Number(), y: Type.Number() }) const C = Type.Intersect([A, B]) const R = Type.Index(C, ['y']) type O = Static Expect(R).ToStatic() } { type A = { x: string; y: number } type B = { x: number; y: number } type C = A & B type R = C['x' | 'y'] const A = Type.Object({ x: Type.String(), y: Type.Number() }) const B = Type.Object({ x: Type.Number(), y: Type.Number() }) const C = Type.Intersect([A, B]) const R = Type.Index(C, ['x', 'y']) type O = Static Expect(R).ToStatic() } { type A = { x: string; y: 1 } type B = { x: string; y: number } type C = { x: string; y: number } type D = { x: string } type I = (A & B) & (C & D) type R = I['x' | 'y'] const A = Type.Object({ x: Type.String(), y: Type.Literal(1) }) const B = Type.Object({ x: Type.String(), y: Type.Number() }) const C = Type.Object({ x: Type.String(), y: Type.Number() }) const D = Type.Object({ x: Type.String() }) const I = Type.Intersect([Type.Intersect([A, B]), Type.Intersect([C, D])]) const R = Type.Index(I, ['x', 'y']) type O = Static Expect(R).ToStatic() } { type A = { x: string; y: 1 } type B = { x: number; y: number } type C = { x: string; y: number } type D = { x: string } type I = (A & B) & (C & D) type R = I['x' | 'y'] const A = Type.Object({ x: Type.String(), y: Type.Literal(1) }) const B = Type.Object({ x: Type.Number(), y: Type.Number() }) const C = Type.Object({ x: Type.String(), y: Type.Number() }) const D = Type.Object({ x: Type.String() }) const I = Type.Intersect([Type.Intersect([A, B]), Type.Intersect([C, D])]) const R = Type.Index(I, ['x', 'y']) // TUnion<[TIntersect<[TIntersect<[TString, TNumber]>, TIntersect<[TString, TString]>]>, TIntersect<[TIntersect<[TLiteral<...>, TNumber]>, TNumber]>]> // TUnion<[TUnion<[TString, TNumber, TString, TString]>, TUnion<[TLiteral<1>, TNumber, TNumber]>]> type O = Static Expect(R).ToStatic<1>() } { type A = { x: string; y: 1 } type B = { x: number; y: number } type C = { x: string; y: number } type D = { x: string } type I = (A | B) & (C & D) type R = I['x' | 'y'] const A = Type.Object({ x: Type.String(), y: Type.Literal(1) }) const B = Type.Object({ x: Type.Number(), y: Type.Number() }) const C = Type.Object({ x: Type.String(), y: Type.Number() }) const D = Type.Object({ x: Type.String() }) const I = Type.Intersect([Type.Union([A, B]), Type.Intersect([C, D])]) const R = Type.Index(I, ['x', 'y']) // TUnion<[TIntersect<[TUnion<[TString, TNumber]>, TIntersect<[TString, TIntersect<[TString, TIntersect<[]>]>, TIntersect<[]>]>]>, TIntersect<...>]> // TUnion<[TIntersect<[TUnion<[TString, TNumber]>, TIntersect<[TString, TString]>]>, TIntersect<[TUnion<[TLiteral<1>, TNumber]>, TNumber]>]> // TUnion<[TIntersect<[TUnion<[TString, TNumber]>, TString, TString]>, TIntersect<[TUnion<[TLiteral<1>, TNumber]>, TNumber]>]> type O = Static Expect(R).ToStatic() } { type A = { x: 'A'; y: 1 } type B = { x: 'B'; y: number } type C = { x: 'C'; y: number } type D = { x: 'D' } type I = A | B | C | D type R = I['x'] const A = Type.Object({ x: Type.Literal('A'), y: Type.Literal(1) }) const B = Type.Object({ x: Type.Literal('B'), y: Type.Number() }) const C = Type.Object({ x: Type.Literal('C'), y: Type.Number() }) const D = Type.Object({ x: Type.Literal('D') }) const I = Type.Union([A, B, C, D]) const R = Type.Index(I, ['x']) type O = Static Expect(R).ToStatic<'A' | 'B' | 'C' | 'D'>() } { type I = { x: string y: number z: I } type R = I['x' | 'y' | 'z'] const I = Type.Recursive((This) => Type.Object({ x: Type.String(), y: Type.Number(), z: This, }), ) const R = Type.Index(I, ['x', 'y', 'z']) // z unresolvable type O = Static Expect(R).ToStatic() } // ------------------------------------------------ // Numeric | String Variants // ------------------------------------------------ { const T = Type.Object({ 0: Type.Number(), '1': Type.String(), }) const R = Type.Index(T, [0, '1']) type O = Static Expect(R).ToStatic() } { const T = Type.Object({ '0': Type.Number(), '1': Type.String(), }) const R = Type.Index(T, Type.KeyOf(T)) type O = Static Expect(R).ToStatic() } { const P = Type.Tuple([Type.Number(), Type.String()]) const R = Type.Object({ x: Type.Index(P, [0, 1]), }) Expect(R).ToStatic<{ x: number | string }>() } { const T = Type.Array(Type.String()) const I = Type.Index(T, Type.Number()) Expect(I).ToStatic() } { const T = Type.Array(Type.String()) const I = Type.Index(T, ['[number]']) Expect(I).ToStatic() } sinclairzx81-typebox-e0ec98c/test/static/intersect.ts000066400000000000000000000025141505437577000231000ustar00rootroot00000000000000import { Expect } from './assert' import { Type, Static } from '@sinclair/typebox' { const A = Type.Object({ A: Type.String(), B: Type.String(), }) const B = Type.Object({ X: Type.Number(), Y: Type.Number(), }) const T = Type.Intersect([A, B]) Expect(T).ToStatic< { A: string B: string } & { X: number Y: number } >() } { const A = Type.Object({ A: Type.Optional(Type.String()), }) const B = Type.Object({ B: Type.String(), }) const T = Type.Intersect([A, B]) Expect(T).ToStatic<{ A?: string | undefined } & { B: string }>() } // https://github.com/sinclairzx81/typebox/issues/113 // https://github.com/sinclairzx81/typebox/issues/187 { const A = Type.Object({ A: Type.String() }) const B = Type.Object({ B: Type.String() }) const C = Type.Object({ C: Type.String() }) const T = Type.Intersect([A, Type.Union([B, C])]) type T = Static const _0: T = { A: '', B: '' } const _1: T = { A: '', C: '' } const _3: T = { A: '', B: '', C: '' } // invert equivelence (expect true both cases) type T1 = T extends { A: string } & ({ B: string } | { C: string }) ? true : false type T2 = { A: string } & ({ B: string } | { C: string }) extends T ? true : false Expect(T).ToStatic<{ A: string } & ({ B: string } | { C: string })>() // solved! } sinclairzx81-typebox-e0ec98c/test/static/iterator.ts000066400000000000000000000002261505437577000227270ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' Expect(Type.Iterator(Type.String())).ToStatic>() sinclairzx81-typebox-e0ec98c/test/static/keyof.ts000066400000000000000000000035141505437577000222160ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' { const K = Type.KeyOf( Type.Object({ A: Type.Null(), B: Type.Null(), C: Type.Null(), }), ) Expect(K).ToStatic<'A' | 'B' | 'C'>() } { const T = Type.Pick( Type.Object({ A: Type.Null(), B: Type.Null(), C: Type.Null(), }), ['A', 'B'], ) const K = Type.KeyOf(T) Expect(K).ToStatic<'A' | 'B'>() } { const T = Type.Omit( Type.Object({ A: Type.Null(), B: Type.Null(), C: Type.Null(), }), ['A', 'B'], ) const K = Type.KeyOf(T) Expect(K).ToStatic<'C'>() } { const T = Type.KeyOf( Type.Omit( Type.Object({ A: Type.Null(), B: Type.Null(), C: Type.Null(), }), ['A', 'B'], ), ) Expect(T).ToStatic<'C'>() } { { const A = Type.Object({ type: Type.Literal('A') }) const B = Type.Object({ type: Type.Literal('B') }) const C = Type.Object({ type: Type.Literal('C') }) const Union = Type.Union([A, B, C]) const Extended = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }) const T = Type.Intersect([Union, Extended]) const K1 = Type.KeyOf(T) Expect(K1).ToStatic<'type' | 'x' | 'y' | 'z'>() const P = Type.Omit(T, ['type', 'x']) const K2 = Type.KeyOf(P) Expect(K2).ToStatic<'y' | 'z'>() } } { const T = Type.Recursive((Self) => Type.Object({ a: Type.String(), b: Type.String(), c: Type.String(), d: Type.Array(Self), }), ) const K = Type.KeyOf(T) Expect(K).ToStatic<'a' | 'b' | 'c' | 'd'>() } { const T = Type.Object({ a: Type.Optional(Type.String()), b: Type.Optional(Type.String()), c: Type.Optional(Type.String()), }) const K = Type.KeyOf(T) Expect(K).ToStatic<'a' | 'b' | 'c'>() } sinclairzx81-typebox-e0ec98c/test/static/literal.ts000066400000000000000000000003241505437577000225310ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' Expect(Type.Literal('hello')).ToStatic<'hello'>() Expect(Type.Literal(true)).ToStatic() Expect(Type.Literal(42)).ToStatic<42>() sinclairzx81-typebox-e0ec98c/test/static/lowercase.ts000066400000000000000000000011531505437577000230620ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' Expect(Type.Lowercase(Type.Literal('HELLO'))).ToStatic<'hello'>() Expect(Type.Lowercase(Type.Union([Type.Literal('HELLO'), Type.Literal('WORLD')]))).ToStatic<'hello' | 'world'>() Expect(Type.Lowercase(Type.TemplateLiteral('HELLO${0|1}'))).ToStatic<'hello0' | 'hello1'>() // prettier-ignore Expect(Type.Lowercase(Type.TemplateLiteral([Type.Literal('HELLO'), Type.Union([Type.Literal(1), Type.Literal(2)])]))).ToStatic<'hello1' | 'hello2'>() // passthrough Expect(Type.Lowercase(Type.Object({ x: Type.Number() }))).ToStatic<{ x: number }>() sinclairzx81-typebox-e0ec98c/test/static/mapped.ts000066400000000000000000000240521505437577000223470ustar00rootroot00000000000000import { Expect } from './assert' import { Static, Type } from '@sinclair/typebox' // prettier-ignore { // Generative const A = Type.Mapped(Type.Union([ Type.Literal('x'), Type.Literal('y'), Type.Literal('z'), ]), K => Type.Number()) Expect(A).ToStatic<{ x: number, y: number, z: number }> const B = Type.Mapped(Type.TemplateLiteral('${0|1}${0|1}'), K => Type.Number()) Expect(B).ToStatic<{ '00': number, '01': number, '10': number, '11': number, }> } // prettier-ignore { // Generative Nested const T = Type.Mapped(Type.TemplateLiteral('${a|b}'), X => Type.Mapped(Type.TemplateLiteral('${c|d}'), Y => Type.Mapped(Type.TemplateLiteral('${e|f}'), Z => Type.Tuple([X, Y, Z]) ) ) ) type E = { [X in `${'a' | 'b'}`]: { [Y in `${'c' | 'd'}`]: { [Z in `${'e' | 'f'}`]: [X, Y, Z] } } } Expect(T).ToStatic // ok } // prettier-ignore { // Identity const T = Type.Object({ x: Type.Number(), y: Type.String(), z: Type.Boolean() }) const A = Type.Mapped(Type.KeyOf(T), K => K) Expect(A).ToStatic<{ x: 'x', y: 'y', z: 'z' }>() const B = Type.Mapped(Type.KeyOf(T), K => Type.Index(T, K)) Expect(B).ToStatic<{ x: number, y: string, z: boolean }>() } // prettier-ignore { // Extract const T = Type.Object({ x: Type.Union([Type.String(), Type.Number(), Type.Boolean()]) }) const A = Type.Mapped(Type.KeyOf(T), K => { return Type.Extract(Type.Index(T, K), Type.String()) }) Expect(A).ToStatic<{ x: string }> const B = Type.Mapped(Type.KeyOf(T), K => { return Type.Extract(Type.Index(T, K), Type.Union([ Type.String(), Type.Number() ])) }) Expect(B).ToStatic<{ x: string | number }> const C = Type.Mapped(Type.KeyOf(T), K => { return Type.Extract(Type.Index(T, K), Type.Null()) }) Expect(C).ToStatic<{ x: never }> } // prettier-ignore { // Numeric Keys const T = Type.Object({ 0: Type.Number(), 1: Type.Number(), 2: Type.Number() }) const A = Type.Mapped(Type.KeyOf(T), K => Type.Index(T, K)) Expect(A).ToStatic<{ 0: number, 1: number, 2: number }> } // prettier-ignore { // Extends const T = Type.Object({ x: Type.Number(), y: Type.String(), z: Type.Boolean() }) const A = Type.Mapped(Type.KeyOf(T), K => { return ( Type.Extends(K, Type.Literal('x'), Type.Literal(1), Type.Extends(K, Type.Literal('y'), Type.Literal(2), Type.Extends(K, Type.Literal('z'), Type.Literal(3), Type.Never()))) ) }) Expect(A).ToStatic<{ x: 1, y: 2, z: 3 }> const B = Type.Mapped(Type.KeyOf(T), K => { return ( Type.Extends(Type.Index(T, K), Type.Number(), Type.Literal(3), Type.Extends(Type.Index(T, K), Type.String(), Type.Literal(2), Type.Extends(Type.Index(T, K), Type.Boolean(), Type.Literal(1), Type.Never()))) ) }) Expect(B).ToStatic<{ x: 3, y: 2, z: 1 }> } // prettier-ignore { // Exclude const T = Type.Object({ x: Type.Union([Type.String(), Type.Number(), Type.Boolean()]) }) const A = Type.Mapped(Type.KeyOf(T), K => { return Type.Exclude(Type.Index(T, K), Type.String()) }) Expect(A).ToStatic<{ x: number | boolean }> const B = Type.Mapped(Type.KeyOf(T), K => { return Type.Exclude(Type.Index(T, K), Type.Union([ Type.String(), Type.Number() ])) }) Expect(B).ToStatic<{ x: boolean }> const C = Type.Mapped(Type.KeyOf(T), K => { return Type.Exclude(Type.Index(T, K), Type.Null()) }) Expect(C).ToStatic<{ x: string | number | boolean }> } // prettier-ignore { // Non-Evaluated Indexed const T = Type.Object({ x: Type.Number() }) const A = Type.Mapped(Type.KeyOf(T), K => Type.Array(Type.Index(T, K))) Expect(A).ToStatic<{ x: number[] }> const B = Type.Mapped(Type.KeyOf(T), K => Type.Promise(Type.Index(T, K))) Expect(B).ToStatic<{ x: Promise }> const C = Type.Mapped(Type.KeyOf(T), K => Type.Function([Type.Index(T, K)], Type.Index(T, K))) Expect(C).ToStatic<{ x: (x: number) => number }> const D = Type.Mapped(Type.KeyOf(T), K => Type.Tuple([Type.Index(T, K), Type.Index(T, K)])) Expect(D).ToStatic<{ x: [number, number] }> const E = Type.Mapped(Type.KeyOf(T), K => Type.Union([Type.Index(T, K)])) Expect(E).ToStatic<{ x: number }> const F = Type.Mapped(Type.KeyOf(T), K => Type.Intersect([Type.Index(T, K)])) Expect(F).ToStatic<{ x: number }> } // prettier-ignore { // Modifiers const T = Type.Object({ x: Type.Optional(Type.Number()), y: Type.Number() }) // Additive const A = Type.Mapped(Type.KeyOf(T), K => Type.Optional(Type.Index(T, K), true)) Expect(A).ToStatic<{ x?: number, y?: number}>() // Subtractive const S = Type.Mapped(Type.KeyOf(T), K => Type.Optional(Type.Index(T, K), false)) Expect(S).ToStatic<{ x: number, y: number}>() } // prettier-ignore { // Modifiers const T = Type.Object({ x: Type.Readonly(Type.Number()), y: Type.Number() }) // Additive const A = Type.Mapped(Type.KeyOf(T), K => Type.Readonly(Type.Index(T, K), true)) Expect(A).ToStatic<{ readonly x: number, readonly y: number}>() // Subtractive const S = Type.Mapped(Type.KeyOf(T), K => Type.Readonly(Type.Index(T, K), false)) Expect(S).ToStatic<{ x: number, y: number}>() } // ------------------------------------------------------------------ // Finite Boolean // ------------------------------------------------------------------ { const T = Type.TemplateLiteral('${boolean}') const M = Type.Mapped(T, (K) => K) Expect(M).ToStatic<{ true: 'true' false: 'false' }> } { const T = Type.TemplateLiteral('${0|1}${boolean}') const M = Type.Mapped(T, (K) => K) Expect(M).ToStatic<{ '0true': '0true' '0false': '0false' '1true': '1true' '1false': '1false' }> } { const T = Type.TemplateLiteral('${boolean}${0|1}') const M = Type.Mapped(T, (K) => K) Expect(M).ToStatic<{ true0: 'true0' false0: 'false0' true1: 'true1' false1: 'false1' }> } { const T = Type.TemplateLiteral([Type.Union([Type.Literal(0), Type.Literal(1)]), Type.Union([Type.Literal(0), Type.Literal(1)])]) const M = Type.Mapped(T, (K) => K) Expect(M).ToStatic<{ '00': '00' '01': '01' '10': '10' '11': '11' }> } { const T = Type.Object({ hello: Type.Number(), world: Type.String(), }) const M = Type.Mapped(Type.Uppercase(Type.KeyOf(T)), (K) => { return Type.Index(T, Type.Lowercase(K)) }) Expect(M).ToStatic<{ HELLO: number WORLD: string }> } // ------------------------------------------------------------------ // Interior Partial // ------------------------------------------------------------------ { const T = Type.Object({ x: Type.Object({ x: Type.Number(), y: Type.Number(), }), y: Type.Object({ x: Type.Number(), y: Type.Number(), }), }) const M = Type.Mapped(Type.KeyOf(T), (K) => { return Type.Partial(Type.Index(T, K)) }) Expect(M).ToStatic<{ x: { x?: number; y?: number } y: { x?: number; y?: number } }> } // ------------------------------------------------------------------ // Interior Required // ------------------------------------------------------------------ { const T = Type.Object({ x: Type.Partial( Type.Object({ x: Type.Number(), y: Type.Number(), }), ), y: Type.Partial( Type.Object({ x: Type.Number(), y: Type.Number(), }), ), }) const M = Type.Mapped(Type.KeyOf(T), (K) => { return Type.Required(Type.Index(T, K)) }) Expect(M).ToStatic<{ x: { x: number; y: number } y: { x: number; y: number } }> } // ------------------------------------------------------------------ // Pick With Key // ------------------------------------------------------------------ // prettier-ignore { const T = Type.Object({ x: Type.Object({ x: Type.Number(), y: Type.Number() }), y: Type.Object({ x: Type.Number(), y: Type.Number() }) }) const M = Type.Mapped(Type.KeyOf(T), K => { return Type.Pick(T, K) }) Expect(M).ToStatic<{ x: { x: { x: number; y: number; }; }; y: { y: { x: number; y: number; }; }; }> } // ------------------------------------------------------------------ // Pick With Result // ------------------------------------------------------------------ { const T = Type.Object({ x: Type.Object({ x: Type.Number(), y: Type.Number(), }), y: Type.Object({ x: Type.Number(), y: Type.Number(), }), }) const M = Type.Mapped(Type.KeyOf(T), (K) => { return Type.Pick(Type.Index(T, K), ['x']) }) Expect(M).ToStatic<{ x: { x: number } y: { x: number } }> } // ------------------------------------------------------------------ // Omit With Key // ------------------------------------------------------------------ // prettier-ignore { const T = Type.Object({ x: Type.Object({ x: Type.Number(), y: Type.Number() }), y: Type.Object({ x: Type.Number(), y: Type.Number() }) }) const M = Type.Mapped(Type.KeyOf(T), K => { return Type.Omit(T, K) }) Expect(M).ToStatic<{ x: { y: { x: number; y: number; }; }; y: { x: { x: number; y: number; }; }; }> } // ------------------------------------------------------------------ // Omit With Result // ------------------------------------------------------------------ { const T = Type.Object({ x: Type.Object({ x: Type.Number(), y: Type.Number(), }), y: Type.Object({ x: Type.Number(), y: Type.Number(), }), }) const M = Type.Mapped(Type.KeyOf(T), (K) => { return Type.Omit(Type.Index(T, K), ['x']) }) Expect(M).ToStatic<{ x: { y: number } y: { y: number } }> } // ------------------------------------------------------------------ // With Enum // issue: https://github.com/sinclairzx81/typebox/issues/897 // ------------------------------------------------------------------ { enum E { A, B, } const T = Type.Object({ a: Type.Enum(E) }) const M = Type.Mapped(Type.KeyOf(T), (K) => Type.Index(T, K)) Expect(M).ToStatic<{ a: E }> } sinclairzx81-typebox-e0ec98c/test/static/modifier.ts000066400000000000000000000006201505437577000226720ustar00rootroot00000000000000import { Expect } from './assert' import { Type, TSchema } from '@sinclair/typebox' // Asserts combinatory modifiers { const T = Type.Object({ A: Type.ReadonlyOptional(Type.String()), B: Type.Readonly(Type.String()), C: Type.Optional(Type.String()), D: Type.String(), }) Expect(T).ToStatic<{ readonly A?: string readonly B: string C?: string D: string }>() } sinclairzx81-typebox-e0ec98c/test/static/never.ts000066400000000000000000000002051505437577000222120ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' { const T = Type.Never() Expect(T).ToStaticNever() } sinclairzx81-typebox-e0ec98c/test/static/not.ts000066400000000000000000000017131505437577000217000ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' { // ------------------------------------------------------------------------- // Issue: type T = number extends not number ? true : false // true // type T = number extends unknown ? true : false // true // // TypeScript does not support type negation. The best TypeBox can do is // treat "not" as "unknown". From this standpoint, the extends assignability // check needs to return true for the following case to keep TypeBox aligned // with TypeScript static inference. // ------------------------------------------------------------------------- const A = Type.Number() const B = Type.Not(Type.Number()) const T = Type.Extends(A, B, Type.Literal(true), Type.Literal(false)) Expect(T).ToStatic() } { const T = Type.Not(Type.Number()) Expect(T).ToStatic() } { const T = Type.Not(Type.Not(Type.Number())) Expect(T).ToStatic() } sinclairzx81-typebox-e0ec98c/test/static/null.ts000066400000000000000000000001611505437577000220460ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' Expect(Type.Null()).ToStatic() sinclairzx81-typebox-e0ec98c/test/static/number.ts000066400000000000000000000001651505437577000223700ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' Expect(Type.Number()).ToStatic() sinclairzx81-typebox-e0ec98c/test/static/object.ts000066400000000000000000000021271505437577000223460ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' { const T = Type.Object({ A: Type.String(), B: Type.String(), C: Type.String(), }) Expect(T).ToStatic<{ A: string B: string C: string }>() } { const T = Type.Object({ A: Type.Object({ A: Type.String(), B: Type.String(), C: Type.String(), }), B: Type.Object({ A: Type.String(), B: Type.String(), C: Type.String(), }), C: Type.Object({ A: Type.String(), B: Type.String(), C: Type.String(), }), }) Expect(T).ToStatic<{ A: { A: string B: string C: string } B: { A: string B: string C: string } C: { A: string B: string C: string } }>() } { const T = Type.Object( { A: Type.Number(), B: Type.Number(), C: Type.Number(), }, { additionalProperties: Type.Boolean(), }, ) // note: Pending TypeScript support for negated types. Expect(T).ToStatic<{ A: number B: number C: number }>() } sinclairzx81-typebox-e0ec98c/test/static/omit.ts000066400000000000000000000032171505437577000220510ustar00rootroot00000000000000import { Expect } from './assert' import { Type, Static } from '@sinclair/typebox' { const A = Type.Object({ A: Type.String(), B: Type.String(), C: Type.String(), }) const T = Type.Omit(A, ['A', 'B']) type T = Static Expect(T).ToStatic<{ C: string }>() } { const A = Type.Object({ A: Type.String(), B: Type.String(), C: Type.String(), }) const keys = ['A', 'B'] as const const T = Type.Omit(A, keys) type T = Static Expect(T).ToStatic<{ C: string }>() } { const A = Type.Object({ A: Type.String(), B: Type.String(), C: Type.String(), }) const B = Type.Object({ A: Type.String(), B: Type.String(), }) const T = Type.Omit(A, Type.KeyOf(B)) type T = Static Expect(T).ToStatic<{ C: string }>() } { const A = Type.Object({ type: Type.Literal('A') }) const B = Type.Object({ type: Type.Literal('B') }) const C = Type.Object({ type: Type.Literal('C') }) const Union = Type.Union([A, B, C]) const Extended = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }) const T = Type.Intersect([Union, Extended]) Expect(T).ToStatic< ( | { type: 'A' } | { type: 'B' } | { type: 'C' } ) & { x: number y: number z: number } >() const P = Type.Omit(T, ['type', 'x']) Expect(P).ToStatic< ({} | {} | {}) & { y: number z: number } >() const O = Type.Partial(P) Expect(O).ToStatic< ({} | {} | {}) & { y?: number | undefined z?: number | undefined } >() } sinclairzx81-typebox-e0ec98c/test/static/optional.ts000066400000000000000000000014301505437577000227210ustar00rootroot00000000000000import { Expect } from './assert' import { Type, Static } from '@sinclair/typebox' { const T = Type.Object({ A: Type.Optional(Type.String()), }) type T = Static Expect(T).ToStatic<{ A?: string }>() } // Noop // prettier-ignore { const T = Type.Object({ A: Type.Optional(Type.String(), false), }) type T = Static Expect(T).ToStatic<{ A: string }>() } // Additive // prettier-ignore { const T = Type.Object({ A: Type.Optional(Type.String(), true), }) type T = Static Expect(T).ToStatic<{ A?: string }>() } // Subtractive // prettier-ignore { const T = Type.Object({ A: Type.Optional(Type.Optional(Type.String()), false) }) type T = Static Expect(T).ToStatic<{ A: string }>() } sinclairzx81-typebox-e0ec98c/test/static/parameters.ts000066400000000000000000000004601505437577000232410ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' const C = Type.Function( [Type.Number(), Type.String()], Type.Object({ method: Type.Function([Type.Number(), Type.String()], Type.Boolean()), }), ) const P = Type.Parameters(C) Expect(P).ToStatic<[number, string]>() sinclairzx81-typebox-e0ec98c/test/static/partial.ts000066400000000000000000000044571505437577000225440ustar00rootroot00000000000000import { Expect } from './assert' import { Type, Static } from '@sinclair/typebox' import * as Types from '@sinclair/typebox' { const T = Type.Partial( Type.Object({ A: Type.String(), B: Type.String(), C: Type.String(), }), ) type T = Static Expect(T).ToStatic<{ A?: string B?: string C?: string }>() } { { const A = Type.Object({ type: Type.Literal('A') }) const B = Type.Object({ type: Type.Literal('B') }) const C = Type.Object({ type: Type.Literal('C') }) const Union = Type.Union([A, B, C]) const Extended = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }) const T = Type.Intersect([Union, Extended]) Expect(T).ToStatic< ( | { type: 'A' } | { type: 'B' } | { type: 'C' } ) & { x: number y: number z: number } >() const P = Type.Partial(T) Expect(P).ToStatic< ( | { type?: 'A' | undefined } | { type?: 'B' | undefined } | { type?: 'C' | undefined } ) & { x?: number | undefined y?: number | undefined z?: number | undefined } >() } } { // https://github.com/sinclairzx81/typebox/issues/655 const T = Type.Object({ a: Type.ReadonlyOptional(Type.Number()), b: Type.Readonly(Type.Number()), c: Type.Optional(Type.Number()), d: Type.Number(), }) const R: Types.TObject<{ a: Types.TReadonlyOptional b: Types.TReadonlyOptional c: Types.TOptional d: Types.TOptional }> = Type.Partial(T) } // ------------------------------------------------------------------ // Intrinsic Passthough // https://github.com/sinclairzx81/typebox/issues/1169 // ------------------------------------------------------------------ // prettier-ignore { const T = Type.Partial(Type.Union([Type.Number(), Type.Object({ x: Type.Number() })])) Expect(T).ToStatic } // prettier-ignore { const T = Type.Partial(Type.Union([Type.Literal(1), Type.Object({ x: Type.Number() })])) Expect(T).ToStatic<1 | { x?: number }> } sinclairzx81-typebox-e0ec98c/test/static/pick.ts000066400000000000000000000037501505437577000220310ustar00rootroot00000000000000import { Expect } from './assert' import { Type, Static } from '@sinclair/typebox' { const A = Type.Object({ A: Type.String(), B: Type.String(), C: Type.String(), }) const T = Type.Pick(A, ['A', 'B']) type T = Static Expect(T).ToStatic<{ A: string B: string }>() } { const A = Type.Object({ A: Type.String(), B: Type.String(), C: Type.String(), }) const keys = ['A', 'B'] as const const T = Type.Pick(A, ['A', 'B']) type T = Static Expect(T).ToStatic<{ A: string B: string }>() } { const A = Type.Object({ A: Type.String(), B: Type.String(), C: Type.String(), }) const B = Type.Object({ A: Type.String(), B: Type.String(), }) const T = Type.Pick(A, Type.KeyOf(B)) type T = Static Expect(T).ToStatic<{ A: string B: string }>() } { const A = Type.Object({ type: Type.Literal('A') }) const B = Type.Object({ type: Type.Literal('B') }) const C = Type.Object({ type: Type.Literal('C') }) const Union = Type.Union([A, B, C]) const Extended = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }) const T = Type.Intersect([Union, Extended]) Expect(T).ToStatic< ( | { type: 'A' } | { type: 'B' } | { type: 'C' } ) & { x: number y: number z: number } >() const K = Type.KeyOf(T) Expect(K).ToStatic<'type' | 'x' | 'y' | 'z'>() const P = Type.Pick(T, ['type', 'x']) Expect(P).ToStatic< ( | { type: 'A' } | { type: 'B' } | { type: 'C' } ) & { x: number } >() const O = Type.Partial(P) Expect(O).ToStatic< ( | { type?: 'A' | undefined } | { type?: 'B' | undefined } | { type?: 'C' | undefined } ) & { x?: number | undefined } >() } sinclairzx81-typebox-e0ec98c/test/static/readonly-optional.ts000066400000000000000000000011351505437577000245360ustar00rootroot00000000000000import { Expect } from './assert' import { Type, TSchema, TReadonlyOptional } from '@sinclair/typebox' { const T = Type.Object({ A: Type.ReadonlyOptional(Type.String()), }) Expect(T).ToStatic<{ readonly A?: string }>() } { const T = Type.ReadonlyOptional(Type.String()) function test(_: TReadonlyOptional) {} test(T) } { const T = Type.Readonly(Type.String()) function test(_: TReadonlyOptional) {} // @ts-expect-error test(T) } { const T = Type.Optional(Type.String()) function test(_: TReadonlyOptional) {} // @ts-expect-error test(T) } sinclairzx81-typebox-e0ec98c/test/static/readonly.ts000066400000000000000000000014511505437577000227140ustar00rootroot00000000000000import { Expect } from './assert' import { Type, Static } from '@sinclair/typebox' { const T = Type.Object({ A: Type.Readonly(Type.String()), }) type T = Static Expect(T).ToStatic<{ readonly A: string }>() } // Noop // prettier-ignore { const T = Type.Object({ A: Type.Readonly(Type.String(), false), }) type T = Static Expect(T).ToStatic<{ A: string }>() } // Additive // prettier-ignore { const T = Type.Object({ A: Type.Readonly(Type.String(), true), }) type T = Static Expect(T).ToStatic<{ readonly A: string }>() } // Subtractive // prettier-ignore { const T = Type.Object({ A: Type.Readonly(Type.Readonly(Type.String()), false) }) type T = Static Expect(T).ToStatic<{ A: string }>() } sinclairzx81-typebox-e0ec98c/test/static/record.ts000066400000000000000000000233461505437577000223640ustar00rootroot00000000000000import { Expect } from './assert' import { Type, Static } from '@sinclair/typebox' { // type K = string const K = Type.String() const T = Type.Record(K, Type.Number()) type T = Static Expect(T).ToStatic>() } { // type K = string const K = Type.RegExp(/foo|bar/) const T = Type.Record(K, Type.Number()) type T = Static Expect(T).ToStatic>() } { // type K = number const K = Type.Number() const T = Type.Record(K, Type.Number()) type T = Static Expect(T).ToStatic>() } { // type K = 'A' | 'B' | 'C' const K = Type.Union([Type.Literal('A'), Type.Literal('B'), Type.Literal('C')]) const T = Type.Record(K, Type.Number()) type T = Static Expect(T).ToStatic>() } { // type K = keyof { A: number, B: number, C: number } const K = Type.KeyOf( Type.Object({ A: Type.Number(), B: Type.Number(), C: Type.Number(), }), ) const T = Type.Record(K, Type.Number()) type T = Static Expect(T).ToStatic>() } { // type K = keyof Omit<{ A: number, B: number, C: number }, 'C'> const K = Type.KeyOf( Type.Omit( Type.Object({ A: Type.Number(), B: Type.Number(), C: Type.Number(), }), ['C'], ), ) const T = Type.Record(K, Type.Number()) type T = Static Expect(T).ToStatic>() } { const T = Type.Record(Type.Number(), Type.String()) Expect(T).ToStatic>() } { const T = Type.Record(Type.Integer(), Type.String()) Expect(T).ToStatic>() } { // Should support enum keys 1 enum E { A = 'X', B = 'Y', C = 'Z', } const T = Type.Record(Type.Enum(E), Type.Number()) Expect(T).ToStatic<{ X: number Y: number Z: number }>() } { // Should support enum keys 2 enum E { A, B, C, } const T = Type.Record(Type.Enum(E), Type.Number()) Expect(T).ToStatic<{ 0: number 1: number 2: number }>() } { // Should support enum keys 3 enum E { A = 1, B = '2', C = 'Z', } const T = Type.Record(Type.Enum(E), Type.Number()) Expect(T).ToStatic<{ 1: number 2: number Z: number }>() } { // should support infinite record keys // https://github.com/sinclairzx81/typebox/issues/604 const K = Type.TemplateLiteral('key${number}') const R = Type.Record(K, Type.Number()) Expect(R).ToStatic>() } { // should support infinite record keys with intersect // https://github.com/sinclairzx81/typebox/issues/604 const K = Type.TemplateLiteral('key${number}') const R = Type.Record(K, Type.Number()) const T = Type.Object({ x: Type.Number(), y: Type.Number() }) const I = Type.Intersect([R, T]) Expect(I).ToStatic & { x: number; y: number }>() } { // expect T as Object enum E { A, B, C, } const T = Type.Record(Type.Enum(E), Type.Number()) Expect(T).ToStatic<{ 0: number 1: number 2: number }> } { // expect T as Partial Object enum E { A, B, C, } const T = Type.Partial(Type.Record(Type.Enum(E), Type.Number())) Expect(T).ToStatic<{ 0?: number 1?: number 2?: number }> } { // expect T to support named properties enum E { A = 'A', B = 'B', C = 'C', } const T = Type.Record(Type.Enum(E), Type.Number()) Expect(T).ToStatic<{ A: number B: number C: number }> } { // expect T to support named properties enum E {} const T = Type.Record(Type.Enum(E), Type.Number()) Expect(T).ToStatic<{ [x: string]: number }> } // ------------------------------------------------------------------ // Dollar Sign Escape // https://github.com/sinclairzx81/typebox/issues/794 // ------------------------------------------------------------------ // prettier-ignore { const K = Type.TemplateLiteral('$prop${A|B|C}') // issue const T = Type.Record(K, Type.String()) Expect(T).ToStatic<{ '$propA': string, '$propB': string, '$propC': string }>() } // ------------------------------------------------------------------ // https://github.com/sinclairzx81/typebox/issues/916 // ------------------------------------------------------------------ { const K = Type.Any() const T = Type.Record(K, Type.String()) Expect(T).ToStatic>() } { const K = Type.Never() const T = Type.Record(K, Type.String()) Expect(T).ToStatic<{}>() } // ------------------------------------------------------------------ // Deep Union // https://github.com/sinclairzx81/typebox/issues/1208 // ------------------------------------------------------------------ // prettier-ignore { const A = Type.Record(Type.Union([ Type.Literal(0), Type.Literal(1), Type.Literal(2), Type.Literal(3), Type.Literal(4), Type.Literal(5), Type.Literal(6), Type.Literal(7), Type.Literal(8), Type.Literal(9), Type.Literal(10), Type.Literal(11), Type.Literal(12), Type.Literal(13), Type.Literal(14), Type.Literal(15), Type.Literal(16), Type.Literal(17), Type.Literal(18), Type.Literal(19), Type.Literal(20), Type.Literal(21), Type.Literal(22), Type.Literal(23), Type.Literal(24), Type.Literal(25), Type.Literal(26), Type.Literal(27), Type.Literal(28), Type.Literal(29), Type.Literal(30), Type.Literal(31), Type.Literal(32), Type.Literal(33), Type.Literal(34), Type.Literal(35), Type.Literal(36), Type.Literal(37), Type.Literal(38), Type.Literal(39), Type.Literal(40), Type.Literal(41), Type.Literal(42), Type.Literal(43), Type.Literal(44), Type.Literal(45), Type.Literal(46), Type.Literal(47), Type.Literal(48), Type.Literal(49), Type.Literal(50), Type.Literal(51), Type.Literal(52), Type.Literal(53), Type.Literal(54), Type.Literal(55), Type.Literal(56), Type.Literal(57), Type.Literal(58), Type.Literal(59), Type.Literal(60), Type.Literal(61), Type.Literal(62), Type.Literal(63), // <- x64 Type.Literal(64), Type.Literal(65), Type.Literal(66), Type.Literal(67), Type.Literal(68), Type.Literal(69), Type.Literal(70), Type.Literal(71), Type.Literal(72), Type.Literal(73), Type.Literal(74), Type.Literal(75), Type.Literal(76), Type.Literal(77), Type.Literal(78), Type.Literal(79), Type.Literal(80), Type.Literal(81), Type.Literal(82), Type.Literal(83), Type.Literal(84), Type.Literal(85), Type.Literal(86), Type.Literal(87), Type.Literal(88), Type.Literal(89), Type.Literal(90), Type.Literal(91), Type.Literal(92), Type.Literal(93), Type.Literal(94), Type.Literal(95), Type.Literal(96), Type.Literal(97), Type.Literal(98), Type.Literal(99), Type.Literal(100), Type.Literal(101), Type.Literal(102), Type.Literal(103), Type.Literal(104), Type.Literal(105), Type.Literal(106), Type.Literal(107), Type.Literal(108), Type.Literal(109), Type.Literal(110), Type.Literal(111), Type.Literal(112), Type.Literal(113), Type.Literal(114), Type.Literal(115), Type.Literal(116), Type.Literal(117), Type.Literal(118), Type.Literal(119), Type.Literal(120), Type.Literal(121), Type.Literal(122), Type.Literal(123), Type.Literal(124), Type.Literal(125), Type.Literal(126), Type.Literal(127), // <- x128 ]), Type.String()) const B = Type.Record(Type.Union([ Type.Union([ Type.Literal(0), Type.Literal(1), Type.Literal(2), Type.Literal(3), Type.Literal(4), Type.Literal(5), Type.Literal(6), Type.Literal(7), Type.Literal(8), Type.Literal(9), Type.Literal(10), Type.Literal(11), Type.Literal(12), Type.Literal(13), Type.Literal(14), Type.Literal(15), Type.Literal(16), Type.Literal(17), Type.Literal(18), Type.Literal(19), Type.Literal(20), Type.Literal(21), Type.Literal(22), Type.Literal(23), Type.Literal(24), Type.Literal(25), Type.Literal(26), Type.Literal(27), Type.Literal(28), Type.Literal(29), Type.Literal(30), Type.Literal(31), ]), Type.Union([ Type.Literal(32), Type.Literal(33), Type.Literal(34), Type.Literal(35), Type.Literal(36), Type.Literal(37), Type.Literal(38), Type.Literal(39), Type.Literal(40), Type.Literal(41), Type.Literal(42), Type.Literal(43), Type.Literal(44), Type.Literal(45), Type.Literal(46), Type.Literal(47), Type.Literal(48), Type.Literal(49), Type.Literal(50), Type.Literal(51), Type.Literal(52), Type.Literal(53), Type.Literal(54), Type.Literal(55), Type.Literal(56), Type.Literal(57), Type.Literal(58), Type.Literal(59), Type.Literal(60), Type.Literal(61), Type.Literal(62), Type.Literal(63), // <- x64 ]), Type.Union([ Type.Literal(64), Type.Literal(65), Type.Literal(66), Type.Literal(67), Type.Literal(68), Type.Literal(69), Type.Literal(70), Type.Literal(71), Type.Literal(72), Type.Literal(73), Type.Literal(74), Type.Literal(75), Type.Literal(76), Type.Literal(77), Type.Literal(78), Type.Literal(79), Type.Literal(80), Type.Literal(81), Type.Literal(82), Type.Literal(83), Type.Literal(84), Type.Literal(85), Type.Literal(86), Type.Literal(87), Type.Literal(88), Type.Literal(89), Type.Literal(90), Type.Literal(91), Type.Literal(92), Type.Literal(93), Type.Literal(94), Type.Literal(95), ]), Type.Union([ Type.Literal(96), Type.Literal(97), Type.Literal(98), Type.Literal(99), Type.Literal(100), Type.Literal(101), Type.Literal(102), Type.Literal(103), Type.Literal(104), Type.Literal(105), Type.Literal(106), Type.Literal(107), Type.Literal(108), Type.Literal(109), Type.Literal(110), Type.Literal(111), Type.Literal(112), Type.Literal(113), Type.Literal(114), Type.Literal(115), Type.Literal(116), Type.Literal(117), Type.Literal(118), Type.Literal(119), Type.Literal(120), Type.Literal(121), Type.Literal(122), Type.Literal(123), Type.Literal(124), Type.Literal(125), Type.Literal(126), Type.Literal(127), // <- x128 ]) ]), Type.String()) type A = Static Expect(B).ToStatic() } sinclairzx81-typebox-e0ec98c/test/static/recursive.ts000066400000000000000000000036201505437577000231060ustar00rootroot00000000000000import { Static, Type } from '@sinclair/typebox' import { Expect } from './assert' { // identity const R = Type.Recursive((Node) => Type.Object({ id: Type.String(), nodes: Type.Array(Node), }), ) type T = Static Expect(R).ToStatic<{ id: string; nodes: T[] }>() } { // keyof const R = Type.Recursive((Node) => Type.Object({ id: Type.String(), nodes: Type.Array(Node), }), ) const T = Type.KeyOf(R) Expect(T).ToStatic<'id' | 'nodes'>() } { // partial const R = Type.Recursive((Node) => Type.Object({ id: Type.String(), nodes: Type.Array(Node), }), ) const T = Type.Partial(R) Expect(T).ToStatic<{ id?: string | undefined nodes?: Static[] | undefined }>() } { // required const R = Type.Recursive((Node) => Type.Object({ id: Type.String(), nodes: Type.Array(Node), }), ) const P = Type.Partial(R) const T = Type.Required(P) Expect(T).ToStatic<{ id: string nodes: Static[] }>() } { // pick const R = Type.Recursive((Node) => Type.Object({ id: Type.String(), nodes: Type.Array(Node), }), ) const T = Type.Pick(R, ['id']) Expect(T).ToStatic<{ id: string }>() } { // omit const R = Type.Recursive((Node) => Type.Object({ id: Type.String(), nodes: Type.Array(Node), }), ) const T = Type.Omit(R, ['id']) Expect(T).ToStatic<{ nodes: Static[] }>() } // prettier-ignore { // issue: https://github.com/sinclairzx81/typebox/issues/336 type JSONValue = | string | number | null | boolean | { [x: string]: JSONValue } | JSONValue[] const R = Type.Recursive((Node) => Type.Union([ Type.Null(), Type.String(), Type.Number(), Type.Boolean(), Type.Record(Type.String(), Node), Type.Array(Node) ])) Expect(R).ToStatic() } sinclairzx81-typebox-e0ec98c/test/static/ref.ts000066400000000000000000000004211505437577000216470ustar00rootroot00000000000000import { Expect } from './assert' import { Type, Static } from '@sinclair/typebox' { const T = Type.String({ $id: 'T' }) const R = Type.Ref('T') type T = Static type R = Static Expect(T).ToStatic() Expect(R).ToStatic() } sinclairzx81-typebox-e0ec98c/test/static/regexp.ts000066400000000000000000000001721505437577000223700ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' Expect(Type.RegExp(/foo/)).ToStatic() sinclairzx81-typebox-e0ec98c/test/static/required.ts000066400000000000000000000045471505437577000227300ustar00rootroot00000000000000import { Expect } from './assert' import { Type, Static } from '@sinclair/typebox' import * as Types from '@sinclair/typebox' { const T = Type.Required( Type.Object({ A: Type.Optional(Type.String()), B: Type.Optional(Type.String()), C: Type.Optional(Type.String()), }), ) type T = Static Expect(T).ToStatic<{ A: string B: string C: string }>() } { { const A = Type.Object({ type: Type.Literal('A') }) const B = Type.Object({ type: Type.Literal('B') }) const C = Type.Object({ type: Type.Literal('C') }) const Union = Type.Union([A, B, C]) const Extended = Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number(), }) const T = Type.Intersect([Union, Extended]) const P = Type.Partial(T) Expect(P).ToStatic< ( | { type?: 'A' | undefined } | { type?: 'B' | undefined } | { type?: 'C' | undefined } ) & { x?: number | undefined y?: number | undefined z?: number | undefined } >() const R = Type.Required(P) Expect(R).ToStatic< ( | { type: 'A' } | { type: 'B' } | { type: 'C' } ) & { x: number y: number z: number } >() } } { // https://github.com/sinclairzx81/typebox/issues/655 const T = Type.Object({ a: Type.ReadonlyOptional(Type.Number()), b: Type.Readonly(Type.Number()), c: Type.Optional(Type.Number()), d: Type.Number(), }) const R: Types.TObject<{ a: Types.TReadonly b: Types.TReadonly c: Types.TNumber d: Types.TNumber }> = Type.Required(T) } // ------------------------------------------------------------------ // Intrinsic Passthough // https://github.com/sinclairzx81/typebox/issues/1169 // ------------------------------------------------------------------ // prettier-ignore { const T = Type.Required(Type.Union([Type.Number(), Type.Object({ x: Type.Optional(Type.Number()) })])) Expect(T).ToStatic } // prettier-ignore { const T = Type.Required(Type.Union([Type.Literal(1), Type.Object({ x: Type.Optional(Type.Number()) })])) Expect(T).ToStatic<1 | { x: number }> } sinclairzx81-typebox-e0ec98c/test/static/rest.ts000066400000000000000000000023161505437577000220550ustar00rootroot00000000000000import { Expect } from './assert' import { Type, Static } from '@sinclair/typebox' { // union never const A = Type.String() const B = Type.Union(Type.Rest(A)) Expect(B).ToStaticNever() } { // intersect never const A = Type.String() const B = Type.Intersect(Type.Rest(A)) Expect(B).ToStaticNever() } { // tuple const A = Type.Tuple([Type.Number(), Type.String()]) const B = Type.Union(Type.Rest(A)) Expect(B).ToStatic() } { // tuple spread const A = Type.Tuple([Type.Literal(1), Type.Literal(2)]) const B = Type.Tuple([Type.Literal(3), Type.Literal(4)]) const C = Type.Tuple([...Type.Rest(A), ...Type.Rest(B)]) Expect(C).ToStatic<[1, 2, 3, 4]>() } { // union to intersect const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.String() }) const C = Type.Union([A, B]) const D = Type.Intersect(Type.Rest(C)) Expect(D).ToStatic< { x: number } & { y: string } >() } { // intersect to composite const A = Type.Object({ x: Type.Number() }) const B = Type.Object({ y: Type.String() }) const C = Type.Intersect([A, B]) const D = Type.Composite(Type.Rest(C)) Expect(D).ToStatic<{ x: number y: string }>() } sinclairzx81-typebox-e0ec98c/test/static/return-type.ts000066400000000000000000000005401505437577000233730ustar00rootroot00000000000000import { Expect } from './assert' import { Type, Static } from '@sinclair/typebox' { const T = Type.ReturnType(Type.Function([], Type.String())) type T = Static Expect(T).ToStatic() } { const T = Type.ReturnType(Type.Function([Type.Number()], Type.Number())) type T = Static Expect(T).ToStatic() } sinclairzx81-typebox-e0ec98c/test/static/string.ts000066400000000000000000000001651505437577000224060ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' Expect(Type.String()).ToStatic() sinclairzx81-typebox-e0ec98c/test/static/symbol.ts000066400000000000000000000001651505437577000224050ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' Expect(Type.Symbol()).ToStatic() sinclairzx81-typebox-e0ec98c/test/static/syntax.ts000066400000000000000000000010711505437577000224230ustar00rootroot00000000000000import { Expect } from './assert' import { Syntax } from '@sinclair/typebox/syntax' // prettier-ignore { const Basis = Syntax(`{ x: 1, y: 2, z: 3 }`) Expect(Basis).ToStatic<{ x: 1, y: 2, z: 3, }>() } // prettier-ignore { const Vector = Syntax(`{ x: X, y: Y, z: Z }`) const Basis = Syntax({ Vector }, `{ x: Vector<1, 0, 0>, y: Vector<0, 1, 0>, z: Vector<0, 0, 1>, }`) Expect(Basis).ToStatic<{ x: { x: 1, y: 0, z: 0 }, y: { x: 0, y: 1, z: 0 }, z: { x: 0, y: 0, z: 1 }, }>() } sinclairzx81-typebox-e0ec98c/test/static/template-literal.ts000066400000000000000000000070731505437577000243520ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' { // Empty const T = Type.TemplateLiteral([]) Expect(T).ToStatic<''>() } { // Literal const T = Type.TemplateLiteral([Type.Literal('hello')]) Expect(T).ToStatic<'hello'>() } { // And Sequence const T = Type.TemplateLiteral([Type.Literal('hello'), Type.Literal('world')]) Expect(T).ToStatic<'helloworld'>() } { // And / Or Sequence const T = Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal('1'), Type.Literal('2')])]) Expect(T).ToStatic<'hello1' | 'hello2'>() } { // Auxiliary Template const A = Type.TemplateLiteral([Type.Union([Type.Literal('1'), Type.Literal('2')])]) const T = Type.TemplateLiteral([Type.Literal('hello'), A]) Expect(T).ToStatic<'hello1' | 'hello2'>() } { // TemplateLiteral Composition const A = Type.TemplateLiteral('${A|B}') const B = Type.TemplateLiteral('${C|D}') const T = Type.TemplateLiteral([A, B]) Expect(T).ToStatic<'AC' | 'AD' | 'BC' | 'BD'>() } { // String const T = Type.TemplateLiteral([Type.String()]) Expect(T).ToStatic<`${string}`>() } { // Number const T = Type.TemplateLiteral([Type.Number()]) Expect(T).ToStatic<`${number}`>() } { // Boolean const T = Type.TemplateLiteral([Type.Boolean()]) Expect(T).ToStatic<`${boolean}`>() } { // Enum Implicit enum E { A, B, C, } const A = Type.Enum(E) const T = Type.TemplateLiteral([Type.Literal('hello'), A]) Expect(T).ToStatic<'hello0' | 'hello1' | 'hello2'>() } { // Enum Explicit enum E { A, B = 'B', C = 'C', } const A = Type.Enum(E) const T = Type.TemplateLiteral([Type.Literal('hello'), A]) Expect(T).ToStatic<'hello0' | 'helloB' | 'helloC'>() } { // Enum Object Explicit const A = Type.Enum(Object.freeze({ a: 'A', b: 'B' })) const T = Type.TemplateLiteral([Type.Literal('hello'), A]) Expect(T).ToStatic<'helloA' | 'helloB'>() } // ------------------------------------------------------------------ // Dollar Sign Escape // https://github.com/sinclairzx81/typebox/issues/794 // ------------------------------------------------------------------ // prettier-ignore { const T = Type.TemplateLiteral('$prop${A|B|C}') // issue Expect(T).ToStatic<'$propA' | '$propB' | '$propC'>() } // prettier-ignore { const T = Type.TemplateLiteral('$prop${A|B|C}x') // trailing Expect(T).ToStatic<'$propAx' | '$propBx' | '$propCx'>() } // prettier-ignore { const T = Type.TemplateLiteral('$prop${A|B|C}x}') // non-greedy Expect(T).ToStatic<'$propAx}' | '$propBx}' | '$propCx}'>() } // prettier-ignore { const T = Type.TemplateLiteral('$prop${A|B|C}x}${X|Y}') // distributive - non-greedy Expect(T).ToStatic< '$propAx}X' | '$propBx}X' | '$propCx}X' | '$propAx}Y' | '$propBx}Y' | '$propCx}Y' >() } // prettier-ignore { const T = Type.TemplateLiteral('$prop${A|B|C}x}${X|Y}x') // distributive - non-greedy - trailing Expect(T).ToStatic< '$propAx}Xx' | '$propBx}Xx' | '$propCx}Xx' | '$propAx}Yx' | '$propBx}Yx' | '$propCx}Yx' >() } // --------------------------------------------------------------------- // issue: https://github.com/sinclairzx81/typebox/issues/913 // --------------------------------------------------------------------- { const A = Type.TemplateLiteral([Type.Union([Type.Literal('A'), Type.Literal('B')])]) const B = Type.TemplateLiteral([Type.Union([Type.Literal('X'), Type.Literal('Y')])]) const L = Type.TemplateLiteral([Type.Literal('KEY'), A, B]) const T = Type.Mapped(L, (K) => Type.Null()) Expect(T).ToStatic<{ KEYAX: null KEYAY: null KEYBX: null KEYBY: null }>() } sinclairzx81-typebox-e0ec98c/test/static/transform.ts000066400000000000000000000241031505437577000231110ustar00rootroot00000000000000import { Type, TSchema, Static, StaticDecode, TObject, TNumber } from '@sinclair/typebox' import { TypeCheck } from '@sinclair/typebox/compiler' import { Value } from '@sinclair/typebox/value' import { Expect } from './assert' { // string > number const T = Type.Transform(Type.Number()) .Decode((value) => value.toString()) .Encode((value) => parseFloat(value)) Expect(T).ToStaticDecode() Expect(T).ToStaticEncode() Expect(T).ToStatic() } { // boolean > union const T = Type.Transform(Type.Boolean()) .Decode((value) => (value ? (1 as const) : (2 as const))) .Encode((value) => true) Expect(T).ToStatic() Expect(T).ToStaticDecode<1 | 2>() Expect(T).ToStaticEncode() } { // literal > union const T = Type.Transform(Type.Union([Type.Literal(1), Type.Literal(2)])) .Decode((value) => true as const) .Encode((value) => (value ? (1 as const) : (2 as const))) Expect(T).ToStatic<1 | 2>() Expect(T).ToStaticDecode() Expect(T).ToStaticEncode<1 | 2>() } { // nested: 1 > 2 > 3 const T1 = Type.Transform(Type.Literal(1)) .Decode((value) => 2 as const) .Encode((value) => 1 as const) const T2 = Type.Transform(T1) .Decode((value) => 3 as const) .Encode((value) => 2 as const) Expect(T1).ToStatic<1>() Expect(T1).ToStaticDecode<2>() Expect(T1).ToStaticEncode<1>() Expect(T2).ToStatic<2>() // resolve to base Expect(T2).ToStaticDecode<3>() Expect(T2).ToStaticEncode<2>() } { // nested: 1 > 2 > 3 > 4 const T1 = Type.Transform(Type.Literal(1)) .Decode((value) => 2 as const) .Encode((value) => 1 as const) const T2 = Type.Transform(T1) .Decode((value) => 3 as const) .Encode((value) => 2 as const) const T3 = Type.Transform(T2) .Decode((value) => 4 as const) .Encode((value) => 3 as const) Expect(T1).ToStatic<1>() Expect(T1).ToStaticDecode<2>() Expect(T1).ToStaticEncode<1>() Expect(T2).ToStatic<2>() Expect(T2).ToStaticDecode<3>() Expect(T2).ToStaticEncode<2>() Expect(T3).ToStatic<3>() Expect(T3).ToStaticDecode<4>() Expect(T3).ToStaticEncode<3>() } { // recursive > 1 // prettier-ignore const T = Type.Transform(Type.Recursive(This => Type.Object({ id: Type.String(), nodes: Type.Array(This) }))) .Decode((value) => 1 as const) .Encode((value) => ({ id: 'A', nodes: [ { id: 'B', nodes: [] }, { id: 'C', nodes: [] } ] })) interface N { id: string nodes: this[] } Expect(T).ToStatic() Expect(T).ToStaticDecode<1>() Expect(T).ToStaticEncode() } { // recursive > 1 > 2 interface N { id: string nodes: this[] } // prettier-ignore const T1 = Type.Transform(Type.Recursive(This => Type.Object({ id: Type.String(), nodes: Type.Array(This) }))) .Decode((value) => 1 as const) .Encode((value) => ({ id: 'A', nodes: [ { id: 'B', nodes: [] }, { id: 'C', nodes: [] } ] })) const T2 = Type.Transform(T1) .Decode((value) => 2 as const) .Encode((value) => 1 as const) Expect(T1).ToStatic() Expect(T1).ToStaticDecode<1>() Expect(T1).ToStaticEncode() Expect(T2).ToStatic<1>() Expect(T2).ToStaticDecode<2>() Expect(T2).ToStaticEncode<1>() } { // deep-nesting // prettier-ignore const T = Type.Transform(Type.Transform(Type.Transform(Type.Transform(Type.Transform(Type.Transform(Type.Transform(Type.Transform(Type.Transform(Type.Literal(1)) .Decode((value) => value) .Encode((value) => value)) .Decode((value) => value) .Encode((value) => value)) .Decode((value) => value) .Encode((value) => value)) .Decode((value) => value) .Encode((value) => value)) .Decode((value) => value) .Encode((value) => value)) .Decode((value) => value) .Encode((value) => value)) .Decode((value) => value) .Encode((value) => value)) .Decode((value) => value) .Encode((value) => value)) .Decode((value) => value) .Encode((value) => value) Expect(T).ToStatic<1>() Expect(T).ToStaticDecode<1>() Expect(T).ToStaticEncode<1>() } { // null to typebox type // prettier-ignore const T = Type.Transform(Type.Null()) .Decode(value => Type.Object({ x: Type.Number(), y: Type.Number(), z: Type.Number() })) .Encode(value => null) Expect(T).ToStatic() Expect(T).ToStaticDecode< TObject<{ x: TNumber y: TNumber z: TNumber }> >() Expect(T).ToStaticEncode() type T = StaticDecode type S = Static // type S = { // x: number; // y: number; // z: number; // } } { // ensure decode as optional // prettier-ignore const T = Type.Object({ x: Type.Optional(Type.Number()), y: Type.Optional(Type.Number()) }) Expect(T).ToStaticDecode<{ x?: number | undefined; y?: number | undefined }>() } { // ensure decode as readonly // prettier-ignore const T = Type.Object({ x: Type.Readonly(Type.Number()), y: Type.Readonly(Type.Number()) }) Expect(T).ToStaticDecode<{ readonly x: number; readonly y: number }>() } { // ensure decode as optional union // prettier-ignore const T = Type.Object({ x: Type.Optional(Type.Union([ Type.String(), Type.Number() ])) }) Expect(T).ToStaticDecode<{ x?: string | number | undefined }>() } { // should decode within generic function context // https://github.com/sinclairzx81/typebox/issues/554 // prettier-ignore // const ArrayOrSingle = (schema: T) => // Type.Transform(Type.Union([schema, Type.Array(schema)])[0]) // .Decode((value) => (Array.isArray(value) ? value : [value])) // .Encode((value) => (value.length === 1 ? value[0] : value) as Static[]); // const T = ArrayOrSingle(Type.String()) // Expect(T).ToStaticDecode() } { // should correctly decode record keys // https://github.com/sinclairzx81/typebox/issues/555 // prettier-ignore const T = Type.Object({ x: Type.Optional(Type.Record(Type.Number(), Type.String())) }) type A = StaticDecode type Test = E extends A ? true : false type E1 = Test type E2 = Test type E3 = Test type E4 = Test type E5 = Test // assignment const E1: E1 = true const E2: E2 = true const E3: E3 = true const E4: E4 = false const E5: E5 = true } { // should correctly decode array // https://github.com/sinclairzx81/typebox/issues/561 const T = Type.Object({ x: Type.Array(Type.Object({ y: Type.String() })), }) Expect(T).ToStaticDecode<{ x: { y: string }[] }>() } { // should decode generic union const GenericUnion = (t: T) => Type.Union([t, Type.Null()]) const T = Type.Transform(Type.String()) .Decode((value) => new Date(value)) .Encode((value) => value.toISOString()) Expect(T).ToStaticDecode() Expect(GenericUnion(T)).ToStaticDecode() } { // should decode generic tuple const GenericTuple = (t: T) => Type.Tuple([t, Type.Null()]) const T = Type.Transform(Type.String()) .Decode((value) => new Date(value)) .Encode((value) => value.toISOString()) Expect(T).ToStaticDecode() Expect(GenericTuple(T)).ToStaticDecode<[Date, null]>() } { // should decode generic intersect const GenericIntersect = (t: T) => Type.Intersect([t, Type.Literal(1)]) const T = Type.Transform(Type.Number()) .Decode((value) => value) .Encode((value) => value) Expect(T).ToStaticDecode() Expect(GenericIntersect(T)).ToStaticDecode<1>() } { // should decode enum enum E { A, B, C, } const T = Type.Transform(Type.Enum(E)) .Decode((value) => 1 as const) .Encode((value) => E.A) Expect(T).ToStaticDecode<1>() Expect(T).ToStaticEncode() } { // should transform functions const S = Type.Transform(Type.Number()) .Decode((value) => new Date(value)) .Encode((value) => value.getTime()) const T = Type.Function([S], S) Expect(T).ToStaticDecode<(x: Date) => Date>() Expect(T).ToStaticEncode<(x: number) => number>() } { // should transform constructors const S = Type.Transform(Type.Number()) .Decode((value) => new Date(value)) .Encode((value) => value.getTime()) const T = Type.Constructor([S], S) Expect(T).ToStaticDecode Date>() Expect(T).ToStaticEncode number>() } // ------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/798 // ------------------------------------------------------------- { const c1: TypeCheck = {} as any const x1 = c1.Decode({}) const x2 = Value.Decode({} as any, {}) } // ------------------------------------------------------------- // https://github.com/sinclairzx81/typebox/issues/1178 // ------------------------------------------------------------- // immediate { const T = Type.Module({ A: Type.Transform(Type.String()) .Decode((value) => parseInt(value)) .Encode((value) => value.toString()), }).Import('A') Expect(T).ToStaticDecode() Expect(T).ToStaticEncode() } // referential { const T = Type.Module({ A: Type.Transform(Type.String()) .Decode((value) => parseInt(value)) .Encode((value) => value.toString()), B: Type.Ref('A'), }).Import('B') Expect(T).ToStaticDecode() Expect(T).ToStaticEncode() } // deep-referential { const T = Type.Module({ A: Type.Transform(Type.String()) .Decode((value) => parseInt(value)) .Encode((value) => value.toString()), B: Type.Ref('A'), C: Type.Ref('B'), D: Type.Ref('C'), E: Type.Ref('D'), }).Import('E') Expect(T).ToStaticDecode() Expect(T).ToStaticEncode() } // interior-transform referential { const T = Type.Module({ A: Type.String(), B: Type.Ref('A'), C: Type.Ref('B'), T: Type.Transform(Type.Ref('C')) .Decode((value) => parseInt(value as string)) .Encode((value) => value.toString()), X: Type.Ref('T'), Y: Type.Ref('X'), Z: Type.Ref('Y'), }).Import('Z') Expect(T).ToStaticDecode() Expect(T).ToStaticEncode() } sinclairzx81-typebox-e0ec98c/test/static/tsconfig.json000066400000000000000000000001001505437577000232240ustar00rootroot00000000000000{ "extends": "../../tsconfig.json", "files": ["index.ts"] } sinclairzx81-typebox-e0ec98c/test/static/tuple.ts000066400000000000000000000003571505437577000222340ustar00rootroot00000000000000import { Expect } from './assert' import { Type, Static } from '@sinclair/typebox' { const T = Type.Tuple([Type.Number(), Type.String(), Type.Boolean()]) type T = Static Expect(T).ToStatic<[number, string, boolean]>() } sinclairzx81-typebox-e0ec98c/test/static/uncapitalize.ts000066400000000000000000000011721505437577000235670ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' Expect(Type.Uncapitalize(Type.Literal('HELLO'))).ToStatic<'hELLO'>() Expect(Type.Uncapitalize(Type.Union([Type.Literal('HELLO'), Type.Literal('WORLD')]))).ToStatic<'hELLO' | 'wORLD'>() Expect(Type.Uncapitalize(Type.TemplateLiteral('HELLO${0|1}'))).ToStatic<'hELLO0' | 'hELLO1'>() // prettier-ignore Expect(Type.Uncapitalize(Type.TemplateLiteral([Type.Literal('HELLO'), Type.Union([Type.Literal(1), Type.Literal(2)])]))).ToStatic<'hELLO1' | 'hELLO2'>() // passthrough Expect(Type.Uncapitalize(Type.Object({ x: Type.Number() }))).ToStatic<{ x: number }>() sinclairzx81-typebox-e0ec98c/test/static/union.ts000066400000000000000000000036201505437577000222270ustar00rootroot00000000000000import { Expect } from './assert' import { Type, Static } from '@sinclair/typebox' { const A = Type.String() const B = Type.Number() const T = Type.Union([A, B]) type T = Static Expect(T).ToStatic() } { const A = Type.Object({ A: Type.String(), B: Type.String(), }) const B = Type.Object({ X: Type.Number(), Y: Type.Number(), }) const T = Type.Union([A, B]) type T = Static Expect(T).ToStatic< | { A: string B: string } | { X: number Y: number } >() } { const A = Type.Object({ A: Type.String(), B: Type.String(), }) const B = Type.Object({ X: Type.Number(), Y: Type.Number(), }) const T = Type.Union([A, B, Type.Intersect([A, B])]) type T = Static Expect(T).ToStatic< | { A: string B: string } | { X: number Y: number } | ({ A: string B: string } & { X: number Y: number }) >() } { const T = Type.Union([]) Expect(T).ToStaticNever() } // prettier-ignore { // Scalable Union const X = Type.Object({ x: Type.Number() }) const Y = Type.Object({ y: Type.Number() }) const Z = Type.Object({ z: Type.Number() }) const W = Type.Object({ w: Type.Number() }) const T = Type.Union([ X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, X, Y, Z, W, ]) Expect(T).ToStatic< { x: number } | { y: number } | { z: number } | { w: number } >() } sinclairzx81-typebox-e0ec98c/test/static/unknown.ts000066400000000000000000000001671505437577000226010ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' Expect(Type.Unknown()).ToStatic() sinclairzx81-typebox-e0ec98c/test/static/uppercase.ts000066400000000000000000000011531505437577000230650ustar00rootroot00000000000000import { Expect } from './assert' import { Type } from '@sinclair/typebox' Expect(Type.Uppercase(Type.Literal('hello'))).ToStatic<'HELLO'>() Expect(Type.Uppercase(Type.Union([Type.Literal('hello'), Type.Literal('world')]))).ToStatic<'HELLO' | 'WORLD'>() Expect(Type.Uppercase(Type.TemplateLiteral('HELLO${0|1}'))).ToStatic<'HELLO0' | 'HELLO1'>() // prettier-ignore Expect(Type.Uppercase(Type.TemplateLiteral([Type.Literal('hello'), Type.Union([Type.Literal(1), Type.Literal(2)])]))).ToStatic<'HELLO1' | 'HELLO2'>() // passthrough Expect(Type.Uppercase(Type.Object({ x: Type.Number() }))).ToStatic<{ x: number }>() sinclairzx81-typebox-e0ec98c/tsconfig.json000066400000000000000000000011651505437577000207720ustar00rootroot00000000000000{ "compilerOptions": { "strict": true, "target": "ES2020", "module": "Node16", "moduleResolution": "Node16", "baseUrl": ".", "paths": { "@sinclair/typebox/compiler": ["src/compiler/index.ts"], "@sinclair/typebox/errors": ["src/errors/index.ts"], "@sinclair/typebox/parser": ["src/parser/index.ts"], "@sinclair/typebox/syntax": ["src/syntax/index.ts"], "@sinclair/typebox/system": ["src/system/index.ts"], "@sinclair/typebox/type": ["src/type/index.ts"], "@sinclair/typebox/value": ["src/value/index.ts"], "@sinclair/typebox": ["src/index.ts"], } } }sinclairzx81-typebox-e0ec98c/typebox.png000066400000000000000000032474021505437577000204740ustar00rootroot00000000000000‰PNG  IHDR€ÃóÕ¡ pHYs  šœ:tEXtFileC:\Users\relay\Desktop\design\assets\sidewinder.blend\îÄstEXtDate2023/07/02 20:42:53$�BtEXtTime00:00:06:01ɨy tEXtFrame145£’~ tEXtCameraCamerahÿïé tEXtSceneSceneå!]–tEXtRenderTime00:21.76ÄiY¶tEXtcycles.ViewLayer.samples4096�Kp$tEXtcycles.ViewLayer.total_time00:21.72f #%tEXtcycles.ViewLayer.render_time00:21.554¼\f.tEXtcycles.ViewLayer.synchronization_time00:00.17%Ö6 IDATx„�Û–d7’\IöèYkéEÿÿŸjR¶íàdUÏ 2wsssljÈ+‹þïÿóÿùó¯ÿõÇ?þóÇ?ÿñÇŸþñÇ?ÿ0ÿ©™Å2èÉÌ`ÍøÍþBçüã�¿þõ/ñþýÇß"ÿSe1y.ùRÜœ/ÖÈMöKßôNÏ2O25üùç_Š[qÊ*Ð-ãÏ?þúKyHçA¤Ó÷�#|¸WMj›ˆlÓ<�ôtc>ö1㛪®¬=1J£ÏD‰åáX%g?ŽJ°]—2WÁâd©Ñÿõ×_Îý÷¿ÿí™Øõc¼Ö$ÁœÉõ‰�fÿf¸WÈZÿ ›®?ÿ‚k²qjO’â‹Õ*sO ÅyÇBêìèô´æ³Ùþ7:g:ÚO¦Ÿ¨(³1Ú¦NuF½¤G9—Ô@¡<¸§Yûž¥›@±éÓÿ;N¶ÓË‹uúßź�íI©vhdø¼Çi‹xKí­}�Mû7Ÿëxõ�K6h²mmlf·/÷²AG¿ „×½rŒÞ‡8ó�É�»ÝgùvfÜGVpwÓ©xb�/Ò æÅ4®7‡¡Ö�ø÷}Hç�FêûôDA_5.oé2O×b�È"Ò@üÿi¸?í=Ž|?kûë¯ÿÂû¾Ô:•Mô?hrŽB©YE»vϲ»Ï™%ÏÎpû5‚ûgþ÷ßzzJöyÿŒÝBôc¤þH:.z‡ õíú7¨‡Q[b°¡/™yíœ{Qûõüar®_rûâœï¹üÔˆ+ .È{q¹ÿøŸÑOÞÓÿþ7ïCùzôàÎi)Ï›ÈW#÷×·‡øÍ«xcÍÇção$\Bº]:7‰ÿço2³³»œÉëØHε×9Û}ò^7«–­53{Ü9I/kÒ„ù�ý׿Xæõ­y;qŒOËeI7´«6` ×£y8sϮωv¾À³–F ¢®#¢±ä#vïA!üRͶy  N©ŽÝ†8±9ïÄ- xÇa[-àëÓä�F¾®$™_ãâð?¼‹;÷W…;çòýˆf3Úÿ~0Ñï]ëë^>? »÷¡ÜW?+IrGƒÕ–µ‡r̾³õ×§Õ –qΑ5úðýªøôÙ°\ˆ}´£ü_º/áv@š†‹Émv¤®ÀìÛÅšªïpͩ٢ Á4ZÃ0�æTO ïÒè¯ûuøÖ.�ÉëkNL¸“sèºï§OåJNÇ°ÑØÞóÃÃ~^xЙ¯}å)ĸŒúŠ�áÞ<36´þ…&žÄ`ÓÓzµ?\8„†1ÈpârÍæa‡Æ¼Wúk!›Ò–Ÿ¡ëÍ8ÆmšÈÛ 0ÿA ÞMÍqb!p<Ÿwò>´ûÞå5篅†+M°Šö4Y¿±¤xîÁ§­œXßËé™»Ï�¼vôÜøo{6ÐS÷ð¸>}À@�˜ôœ6>šZ»½´·ÄsO2üË鯗¸¹>g"¿ë˘îOÇš®�Š]Ÿ×ßO>a÷úÍë›÷Ö|íû³ãq?V;ñ¬Û÷ñÓ¤‰éüô„:×3_kÆ<}†¸—û:#ßGð¹à-ûƒ£zàu 2ì{7sþ¸œ|�%ÜÇ¢…×/~‰ÝpÒ&^ßÂóõ/£uÿï÷º¼ÕûqÊG*Cðó5;­y0ön°}Í’–1ù¾ïo/qQ?ò/Ê^§\¾0Žvùkí1ëõ:! Û9,Æœ¡s«¨<\û~‚¯3øÚò”™ �¸Ãqku¿¶=¼ ^öw]—�¾}lGŒ#uîþš�ï#Ü7›S±ÉzÏ�çõåÚ¨ïŸ?þK¾QØâ4¹ßxÁiכǔΗ¤öÉm<&¯ãó‹BK߈çEÍ'E{‡ 4)L®OîšI÷ç?þñï₉2¿pÀê òv‹êÛ8bœf>Ð]CÛ¬Kbºûãïžj¾˜ùáÚÞ‹Ðá�à'glĤö ¡y‡£á ^cþSZË‹ßö�°Z«T¡ï¯QƒÞ|aN]MC¤ÇK53öõÏA« ;zÓϼ¢=~GÆaiä^¹½ý#?Ãu~Pé/~…[??ùeG ýex­Ù*Ûb‡ùì1v¼\˜Þû“˜}®àkó¾U¿{��k6�T¼~„aÛ™5#Ìwž�ÂòµðåØ9µ³úܲ3f„&Plã÷K÷Ÿ¨¼�ús¦ý€£+«\Ã%B} ÍÚ½X%EkK}Œ�óî¹hŒï^¯. «)ÇïÞ+‰¢(Þµ¯Æ–eOÄqn`5´°ŽÆ­O|ÙÊ�À|Œ‡ö‹s=òávÉþ%„ú¼_,—›0ru9Ò¡59üú<ËÊ\ :°1›ŠVúuP/ù}æ°¾„ù릮×Í¾Îø§Ÿ󒛢ä%’{êXûz³Ý½c½€Ày«)÷wÎÛRɾqÆŽ¥çan~Qi>‡Cðoi!Êci}Ï%þù‚âôç¹Iøá Í@ÜAsØI6Z­ÁÑTóã;1ºÂãŸ÷fv 6a÷‰Ý‰‡ü|7Žñ’ÉÀêi?Xg*Ú<´wr°á N>ÙY“äp/;ÃàÖ‹¯ÍúXHuq¬Ó' Ñ0k‘R˜gÜÄcs€z Gü Þ7`nš´NŽoºí�ß\ìnïàY>¯dœQ`� ò…Åä>–çj'Fß6d§6oÒÿ솓'~¸škgcaÂøã™íƒ÷j8zm“2Õg�âó6ðª8ê Í'‰mÆ{…ïá6Wï K"P£Z™ÂÊœ´¢áÃ׿À:¤-j°)ŸmD½kGØ,ê,º§®“w‡ãtq.!<ïE4À%¿K!æ,²ïøx“°Ìur± këÈVfùNøI�q›GXÏfI Uaw½rhD¯WÞË�¹¹Ì±\ÊCW,Ëy‘âš±á'.ùÁòŒƒs�–þà#BËijžâú°ØOŒi| ·ƒË�‡>e¾ØÄ-qû�ÛµC6’d>,öØ™s˜vÇX4aI?0Eò°%ó>1×—Px“syÈÅëÛË—ëÕlŽ…˜ñÉI?Vù½>ô }×çoúÿ§>çHE”Óýuüâž|_ÃtÏþÖw’:gì^Ò…j&6#yàþæ›z%pý+Åx™A ¾œs™Sþp¿9ÂÇÀvèY|îñÕöÓ[À;(¯/ßìXv.pºßŽzÎúèXa& £‚¢-¾érÉݸ®aùɃgOíÆã Sô DzVD''kfÃ*|öÓJoÂuò ?>Äjì æÎ~»E“+úðË.¡8Ë[_<Ž5¶{÷ÁÍ‚m£õx¢ÖhälœÏAÂ*Y3fãðô†Ðihyó"¿C q mFË;ë|©Y;Á‚¡¬AT¯Vî…Mù\éåIxO<' ¼ñcìpløØ9‡�£Á>|¬ùrðˉaw+q9qìlñœ>ŒŸ ¨pÿ"…håL³:5ÿyš³ZVƒHHÖ8v7¬¹‰Õ@[fo²3$v;¹@`Ê;Ãí^�G+0òÁ’1!³k¾_gÔ\¦vzà–œp¿¶üz†§ž'·¨°´L­òZk-�D`GúQÝ 6~NæºÄr¬Öâ�lΛ\p°ÄäišÖ™åéÞEÂÝ)@BÍšÔÚ,Æ“‚ëÞ¯c¬bløÇg‹­J“÷Ç»z�-7ï%&<| &¯c;wçk¨àÆ¿º]‘Â%îö/˜ðât™š“QFÔu·NfFá0ƒgškIHpWfn†«bS‡F]0Á¥û�ÿÂt5‘$|�1Ý'øÄßÌÖJ ŒÍË#ÓüA¼Ú’×´è鳇¬¨3;�àëkó·?&XìòÒŠ�”s¨¥’ ™^lÑoâf]<öipmÂû o¦ìm×=ø¾Æ¡pãü¾g ¡Ø¿ü §’úK"šC�" öNn›Ì\5?q «™/ÒÁq¦±P¯NS›—½9ºü{dMÁáŸk^l[{†¯1~Ñ;;üÃfGû5sì]³Ï úò[ký‡‘|Ææ' ûäõ*‡0Æ;M²ÙR…ÍWk`µ¾Ò¯®ññŒöûb¸7U|<8²EÃÎj½}ù �ŸõbªÖ}a�û'ˆ Zßêù9›)z�$îp4îÞMò¨î“Ï…+Ô¿r¨ŽÙÐé®pééØÍБLcœ™Ñ¶ØÎ��ӽ¼¸®±Â¿{j€3'mäâ(›*xí£Ûôvî,ÁO'¨sf¾H™œÆXSøêû%û1ûzuØï 1Q´içON>ƒètNÑ¢e½!âp/eg¤2˜n-6%>ˤU=&RˆÉk+À�öü@-=ðéÛqM›5Û!×t’’µ÷ÁóØ01°1ùÞc&Wfœ£¸¹nŒÃ�6!– nçê]r0ް¯Iý˰¦0lÆö-un^Œÿ“#êoKëõ>pÖí‚Oÿ§Yd±�âÙzð—çÔ'Slh—'æŒeêËè4ÍÅd.Á2ƒK�‰|ãµfËsZê&Ö\¸Ýc-¸Ü˜dãá\�Ÿ`ßwÅØ•KíIL?¯Hòp�óFEöYG`ò-�Ã$/{Û(‚¼5xûêÄ»`kN¼Ï½”®þqœä �Ý[–žd ýaoó°ÃÄ×عnŒÞBœ¤³r�†>‘ïžMøö—Š&IG^ ÐÂÁ5ºH 9OÖ·‰¸xöw,•ÙäÚþôä­AÞä¹™Í6#´æ€¥Lö%gú#õî]ú@@Â}ZæÐÝ›BðE�s3 ç}Öë¹'ZËäc›:”`%yáõ ™?5;ø\L�Ÿ�1 Ÿ{¤õóÑ$êe�ÍDºž_ã<€Üê£;‰…·N—73”Zç˜NÅ5UîAm<°Žç=“}­7_ášöšpýr9ôÄ\é÷pñO|—3G éïü›oÞÅ¥ïøÃÉuìÆxs-qnß~\ =ÇÛ§d¤_÷~‡÷öx"yxœÁa¬cû6iÒ0»?2¸Íì±;Ä"^žâÌ ËôFííÀK@<gí9q66Bád9§¬£E€+ÂøÊhCù½4‰kxBìqÖ¤nPzèÈWY7"ØÙÞ|õ-­#bO¹Rï8O Øô´kóõ›�"ðÃ==‡þ�$XqÖÛ¸¥!ÌZÌÓGî-úÎ_œ’³9|f²ÐfFÁžc!.±uÛL¦Ù_›q§žoMÙ»nGŸ¤I릀é9Z{ôä¾Áõ�Wô]_pÚ O_ðÏæç¨PM|~Ì whèV›¢lÌk(µ[ 8§i€&½ÊLÜðèÎÑè2N×ZÒ†{†&s<á†l¯«ñyï4cîê@�koÞp%¿s$‘1,©ƒÇÎt\øü9ò©Á¶áÙÐ7Ó„ÌÈÒN>Þ÷†sj³Ù+×O8„«7d õÐ9òÀf$©KÜ<8ˆÝ×0Á ¨…1ÔÕ˜ãÃÆƒûľ©¨&(ܬk#ÆÃS×±œ+1ùkÎøÓ‹ö]ñÖ têßË¥µ41Ö»]nŒ¹] ¾'rÇùð•Ó,õƒËž+·W ‹™Mˆé}Ö]¤Ns“ï %z4c{�·—;»KÁd|“‡ó?öú\îÆ²ÏÈGô°‚¯Ûv8ˆË{ÔÉá`­WœÜ%Ð~5LÇÍã ›©Br–¯�{�¼ë�%}hèÝî�õblb½§–œŸý…/~œ£_C©�w�œÞ¢7¶1jŸMuhû„Œñø.GLåkŒmÕ�¹Nlغµ§–&×¢¸È³u0ÏðLûÇïÍCnótáž‚³÷ƒ–9ïÙÙwíE°¶ØÎj˜ñæì£ Â`² £+õ•·Vƒ{ ,üá>Ž }}ã1p?æ‡Ï¾rŸCáA_5´ÇëE÷LhBCtZ¦lx¾ŒëüéƒòŒ9©uƳ(yû!÷·Ž''šJOúçµµŒ?XÔtz*0¯‹ìÇ�ñ‰}–ùw%cM½9;6ع$8½Ä–q¿é›…Ù<–zëg_I›�qâ—#ëó9¯1¿ ,+Ú^Ÿ¹3üy´Ú¨1÷¯¢Ð„]¹“bƒïœÅ�üôßüÿ[~�í5»ï2¾haä—2]?Z—3r,Xàžq?°aÈ•˜œ-9óœßqJNÖ—qmöô‰:ôð@ó³?vðç�AâÉÃ;úç»—$2üŒiq ²Ã»{ñ¬ß⇲¸^æj.7ùØÃ’ì/Ö«Ãwó/%úïXë£â<Ó§ÒmY/nù‡3Ð÷~@)µÏGÌêpüt*ÐXk“jo^ãtÙÙ¾:ñ�Ïp‡ÊB¼}ºˆsg‚ }ÄAþGƒ67=Á¹v­] $ÖT�«ñÈ&–¾þ1°ë£#8ró8zæž¾ƒžC³8–/Z²KÞy K½)ÉõÀ2„¥ èŠr’m]¿-Yåé fÇ�L»-¯b‚©‡šZW0Ñ’nCHß`¾ÃõÝmW€ È¨�xó‚‚«h/¦„>r:N˜ÃØF|™ƒ±qÄ "yG(Ô,%œøÓÈWxª}cÙÿˆs!Ø5œ…‹ãºÇqâø,eÛëã?QÕp£¼b£g¨Ã� ¸Ð%.¾f?� lûÊyùïÛqN#º4o{Ûss¬G.‹€`9N÷®=b?ýÓ3ÎÄÃ}_xÚ¬ªIÎoäø¦õî· QX½ú ùò��äûòåµ¦áÆŸ”ÎEí|Dû� wù‹g¢ö{í=U,Öa­e=Ÿx#æÔŽïôW^ñ´NϹS¹Yçõvôk½ä,‹Ìù†JûÕn:inõb3¯mì2¦ºÀSkøœÏ·Àg6o÷‡oþSÓGмdÈØKžÃuâ„pà©=yZ̉ÇÜx2ØAíûÀ ™wMýo<éw{,¨sV–µÈfLhá¸ö}ñámO™±1s(aÙ¸7‡jǃië6—Ë Ïϱ÷€Onôô@Æ Ï G§“$çê�›¸è°h­1â± ùYg\îíÃ7­šÄ¹ø£âÞ'ËiÍI“¼]W€yƽܿ@ 8ÖÓÓ·ãøýŒÖŒôa¨è¥ÇÞ¾œ½¡ÓßÔ|¶^ŽÿÖ•‡×i,Jnø„øóÔ6äð™Ú>GÂÑa¬lÓ~>���1:/#i=ðééß46>ïDØ8!_2�$PpT™¸ÕÙÓðð€òÜlÁ±•÷¹÷_ 'ÿ‰n~06ÓTjlh íÍ·Z‚Æ>ŸVà dgd?�«3ë vk‡Í¾øoþ°™ñ.ó&Æi} ðæaŸgòlO=ÌÌ:Gö`_^óÖ•V;ÖîÏ…X8©-ÜË}’ýÀÿ¬Ãô¢9?À4¾â,290¯ò…GƤ¶Ø×ïa6›ú\Z˜'âæØýpÏ �{1ˆûÛ\Š»>ÙìP„ÉÛ<‹m>„ç/cçH}©çá™ûô"B¯^§êæÉyäLNxï :Á›òLA«‰\<ßþ`Ym�7š˜GéÚ,2ºÎxË%ý“JH>ÿ€’9á©cñoÝ'Èé§5Z~‡K¿ã·Î¥–iüÔÀúî•e¸“#Ž`±<Üö ñ‰u¢z.Þáîû[ ðÒŸq„ýÕ ŽIòIeŠE\›!´K—ìÞÛßþY‡pG߉éB¡|pæ3žläfã̾„;ù0p?-/ûå9u»x4.WúSœ÷Š�LJCqÓ¸ìYŸ¯›àïÿݰ-æf“ûšªV·•lb¢îÅ„ˆïÑ:ΤI€ó–SAÑö0�·¹²MºfšÆéškvxÍ­TÖc�É»:# <øÀþ®WÇæ�År½óÁÔO„Svsw¸ÏTè�×wlà¶a=ÝZÿŠw1F[3«”è,à§?x‡»}Ñ…ÿõiÛ_˜°Ê Þ“O&Ç SOÆ­�]�goþÕ“(°Þëâ×®ãew`¡¦âd[®q±G‡Ó°ö~?¸º]cuX÷’*0u{{ѬòÃM 殚åœÎÕÈÞOb~¹à:±ó³¡µÐ`{5kíx›­jQ™cªú3XN¯IâüÑ�^HA5ÕšJ¨}¯.ì�¡�8ù÷¦�8ð;¥’jë`CL°C–£>…Mü;ÛÝØáÑÄë×€?� x& V8‚òÙΠ+öå˜ß„q×?žÍŸL?ò–Í‘«ƒt2œ~XÿêC>šžÇÅäVi SŸš®|6Jàú“èô^ò2‡eš×ù­ œlï‹–ÄæÕÅ5™%xö¾aJi?\ÆØùðI�ë X0ò¯K4:Ûá5¿sƒÒ"îÿ¸–Ò|¯®O\çO¢C ‰ö�O?äá€û)‹E»­Ñý”fì©2±¶™¾eDK^XIñœÅ0οóä<‚ÑñÉã\²�Û8yùˆ®«'>\�>È™åuì´¯V2ê§7¹€37ý@¿9ãÛžΛDÆà‹md§rèéz²Äp½:ÈO‚'öÄ 8¼Ëwx+×_Êå�ĹžÆ!÷øÍ罃Ó74¶Á•g�«>5¥FóRe¤wP„–g?ûuã´{±�2½€|^¯ OÂD¬?‹{ä:鯘ëp’t?"ø…K>^Ÿ?¿©ýôÀBƒ�Ò IDAT„!ñ=–§GèBË éB^7(Ȱ¨Ü3ª©Sâá0WCZ¾Îð¯7É;üþ“@ö}͉òb¢Á^‰>šÝ—˱!’GÆbÙk�N;º/*x°Ãwµíè„Hþ`/D²Ùœ \±ËL³5Ú*¯·?›'wlcÏ{VðØ®´„Zø,“ÉFìÔ\n\«“E6ûçƒg�Óí±â çiGt´ÌËTáÓöÑêD©-ý ïÍöÍEšœ+rÃk#†È ÅÍO„@ë?޳VÈÖÓwhÄ­¨YÌ’EaR5!(-óWX°dÇána§9ãwþºárÂsÇO;ûçÁ�º³ ƽo_ô±‰¬Š#º~,ë]be@³§àñnìju‚Þxk\ÜúÌüA%Gm=|ØAeðOQL Øàgƒ¢âãÚùO¾µ|q`¯`6¹×Xmì¾ÙžÙíïÜ®¼ˆ­£áåhØÉ»þñ‹¶ÑhNœô©öT¬+ j"ÐÆx|ošìËxw�5¿¬uÜžáøÞS†þ‡KjIzSi2ÝÓƒoœ_Í·?Ó%Á£/±'Þ”*EÁ¦4ìY±P®™^ùþÑl츙µÈÜX&Û}±ÿý\ŒˆùûâÍ9¨ßÔ/24¬®‹mùq°ìX=‹Ãœuñ6LÞŸ#½ ¡×Zú ›#çY‰±C3*LÆúâõbÐñ»õB¢Ž‘ ùVfz…|½# òšÔIOhG šÜ�cMì?99³ùáÒeý÷†Bìè}mÕ6¨ÆÌ«ïî#*z+DIÍKˆM,Ò‡ ¹Ž/s\ÃqjfçÑJ9MY®£cjkbcÏU1vjN¸Ì[Œ›ýÖDeM÷×ðõ [ê Ø{Îг3 ~ßç �ÙŸ ÛÖ^ &±YY°�Þ›·Éä�Kv&©K±ÇþÛÖòoAý�ÜéÃ9?çÃΓñ̦ɞTû�àòàn&9…Ó{"¥E7_œ©]õ8ôÇÒø³åeà Fë|œ^†ig¦�áë¤+Ÿ’ûá —78k”wžè7øÆ4.®õ¡ÄnPbÈkw¾ç›ÃGŠo±æ\ìC#»ó™ñò¬H8/—¢Òû5Ÿ|³Í /6žWÃîÛ÷,R^4ílOý‡#<É2^Q—?|ˆ¡Nò5§ö§ÙÀ]5Ä×ö5‡×„IÞˆ�Çv²ýA`͝ÿqµÐÇ«Ùg¬¼ûšÿú¬î^m'½ÉEå)Ä«—°öHÀ êÕW·­?à &˜ÿ¢.ý¿¹ìð…¶ۂºdsÍRÖž€à눫qžê¼T)Àd Z4³ðßÑòÚÎ:‹õþÔ-³52›@‹|œÚRÿÍÇžxzšµ76^Ïâ�Òú˜ÞõÃ{ ~^ìçÜе{ Ô’=±ýŽy¸ÉÅn8¦Ï¹&¨„óA™þ<äÂbã‡G—Ý} š#Ò~5™Ïº[KAØ¿ ÕL>´�ŒY¶å¦5îãã_øìŽuÑÄâ½ñ0¿8¯… G^O�0ny­A<Ž7c/ísv%*˜ØõáëÏnÜG¯Ìoªô �æêý0ý°øëKù½žÈ±¨�åÈ,P D~/µîÌ o õ¿«�ðeÓ2ëá0È2ÿçÄÎ~»oRoÏEöËë�»ÀÉ"ÕwØ6 ϽcTóýøn´hé$Èó`q6¸©kÿ6^!ê^ÂèåÓÓ²xúÔ1Ü�ùÜWµ›Wkxa®¼sïjñ¦ˆÖ×F­ìßÉNÙñóäg[Ì·‚äãçSþ Séò:{Éå8‰¦ ²zýb1ÐTŒ!²‘H4ôÏ¿±ü!C`6ÍåC™ Ö˧ýÇ/ßr™�Á³ÖÙOyC¾æ¼³‘¹4ËŠŒýPñ‘”:‰ªq>fëò–[„#½ÉZWé2q[×¹›v¼‡gµ€S°k<1¼ªÊm¸/x×ÞXb.¯ÖýO«MSŒoî­«I©ÂP.èrFaóFUWe jœ‰ˆËû¼‘i†Ë��:«gV0ésâŽ6¤÷y`Œòãs#’]¢ÌÍN>÷Š0�ÅÀ€=û7“aæräpíáž”ÑOÆøxSgXª&rŽ_FMG·Ð.ÓB/~Œ¸´öGðÖÜþ„B¨À]ë\zãÄïgÙXç Æ9k^c éðúp^]é‘s�‡d3F§ä^#Sý˜Õ³Ó7¹Æç~(ÏÇO ápUÃäs 8qì8#Ì^_—^{¼äÖJ¶ý{5•>wf]�s¾ÜSÇÁBvç´?ùNMøɹÐàÙ[ÛJÉ–×Hë³!ñ·Vz–vçá~ÉæöÕ†÷j®E†O^1Y3óÉìx=›÷*êsª‡úr1Ž»Žzsî=âÛ?‡=¢AË–ŠÞóÂf×IÃB™4‘oµåóÓø³ ™wþóPüú÷Ú²¾¼A�„»ü‘�ÜèXq¿‰ÀÂì)‹ô|u–:à�@ì(}>§G†Ãñ—§,‡#7†u{i*aùXˆ×Ùäa}?\Ù§/³·6‡©‡Æ²‰–œ•põ;Ÿ5&�áïEæÓwQmæƒ3Æ •¿¦ðb) -Ánò{v›ë[nmsŒD^m?Pá”;\ ^Þä»ñѨ}é./¬B—wrÃð°pœ×à iìñ�šˆ‡+Ä—ÓF.¸3´´_—�õÇo‰qÁš£%uha¬øË¼3ã-ÿvÙ÷—,ô”Æj¿Nxî•`fŒŽõ„Ÿ¹ËFT ºœx¦Ž¼ÏÌö¸�{좆\…î9öþyàöq9ùX  9ÅÈÿÜ“À‘^ØÕǾA97O¡ôo÷¼Ërˆþ‚Ð JO›IÊó;ŽÄ×ü5ã°Ú'kkŠª �ÇüâQ"‡_¹…Ã~û¢Í g‘ó4m]®Më�‡r&Ïη¼²„�…V-ü“wÑ%üé#þh3– ²‚D¤Òo¯�›¯8¸Ìg— ÿ�vÍ`\Çc;º¦ŸÖ�„ƒæ=ù—ñ—úqîet í‘ãÛGß3Š÷Ù±ÕÓ™,V—}qIÛH !OÆf-ýMX»q›ò`…‰83Žm 2syñŸâ€€‹’Óx۴ך´‡Ç\öÅõóúæÂ—}V§4—[¾·ñ@µŸ†äóN¶Ì@6^ËY»§BÈÐT†ãŸž­î¡{Ðà%úüà�­&k?Û NÖã¾ Ë~cú‚€WOèlïÚùK�sK\™ù k�í=ã%ðÇ1£tZÖ°K{WXŸ~9�Ø@”ñh[ñÝÏEÄ¢kcÙ»X_>÷?±‹On]E·šk–ð<©æv< ±ÑÏ×·PãH†aF-ǧ•Ìz ‘¡éúb¢|0ð�=¼µ›û|F§õðéò ­ÖŠ�÷ä™ÎrÙ‡ö8©ÞÏžy}8õ £<Ö¦µë»@x¤îÔ@Æñ™‘«‡õ’ žr%¾d˜-F ë-7Ü̘XxS¼aªxoôÞ“OoÇÔûÒœ¸¸ ü ó«OƒÛ›Ê +öð41Æi^?r.8@·oh1öàmÂä§”ñ¬Ÿ°L ë;,2[øv†¬Àæ NúhA®vxfb¬)J«-„Ó™€]›,$5.×ãÛr¹ìÓÃ8WFÈ\>æœ%5½5²î!\ðòÙònÄK¼LŸ^Ÿt÷~1mÏY{°ûrÎÂ{¦lnï£wâÒz8šk¹í˜Öhã[ªæyÃEޱÖ"Cê ÷{v¶Ÿ³&öûía3•?ý¦ zô˾؀¦�]hfa.¦5;¯k¼›oAÚ‘û­c\ÌGî'§r™Ï‘æ[í臋§ÿÓ¿ŸyjN0zä‡ËѾdÑÛòóóýû“»¡ý¶%1íp/4“/=Mˆ ò5凣ŽÒ·Æh'ýaœÿÄ‘™ð3’+1Ôæ_�9†¸2,ÝÈwz S‘b?-ìçœf,Ǩå+DÑ6l¸O¨éÁÁøÊ…Àqjÿíe°N"²Ó�LE=܇לÚiNNƒí'UìÉ3ù‘žñá­°SH÷'09ˆD÷;œ†4æpƒ=?ÈD£0£_Øn_¸—óõŸ[¥4Á;’hË¡HqZ G ©ô>ÆÅœ>aVŒÏ<�ÅîZjÏçuÙo6duî5¶ë¾�ßÜuȔׯ€å_o Ý«?È‘?gx(µ àì¡%q#ñyÍž yŒó6¯k‘ý¡JQâqÿ~ç$æ§}ÙÉã\âÙ}ã¶-fó²yß(7„Àä0�ÖiM‹{çæM£ß$N ßÄv•#>ù�8w°äÇ·òÌCoô°Okj|umfr�À)à+¿r�ó}‚> ˆýà°1˜Mx š0 ›å3àŽëq–#yv/žÇrBó®Ù›�…†{Ð&º#« Ù‡…Õb¯[~žcx£Í;z÷@ñÖµ†ÎRÒ§Òt"öÕ1/¶ÕÄl]u®ÿ)âš¹ùá?�Jv‹ ñƒ}÷&’ß:&£ð 1ÄlöÅÝ“'âÖÔ•9�Nq‘Î}!Oë4Eb¹bóœéà´µêã_ š­£ý0gûllÔìœ`·ŽÑw�Iö �5š,¢w@Õ~+-Û!k�ÚÃÙ’R´øäý¾¸n4`¡-œàˆ?ñ/p¾â�!Ôa�cóòáÕþÜœ¬áS¾ãÃ!mΡÚ6ŽI.û¸0^Œ%ø7WÐ QOäŒ 8OÍG¨- < “Í{66}/†ÉáÐ�&R0Å�s®Þã+Kühúz ;±äÝh@9Ê5ǵ^ |÷Lˆˆ•sY>bÆ‹cqö=ý´SPÜdmæêð=Ð ãe?±^'¿%÷frà×ÅÊU{ô‘8Ï“B 3<ñ1Ö‰ÂbÍW~̧göä<£*qà-ž­–ã(e|g=àW·3r¾WKë;Ù¡ž’»~u8>Ý‚PrkoãÏäÌÆMƒÃÀ+ôè«6IÒa×k¡©é H4.NFä~r=Å€³ÆOŒÙp¹vç¨ þéû&#í%�.Y¬‰³#Œ\~¾™Á އ6 ¾£!æÅ/ušäÁ:Wöp[[mæ�ëôG±¬ÝBLžiXshì©íá©ýiƒœõäò™gþÖÆd å&*Ã�áÂP½^ºa¡ö�åÛFЙ‘sèæ™8§l™ï‹w'/˜ø›€ál6@g4è“ëôsb…?ýo¬u?©¥ðRkÎãúxŸl/‰ïƒGË ØG{XcŽÇ©ehsOüÌyî­Oúæ0-\Tܤ¥Þ}¸þukWƒà9Oâx28èmúk1åÆ6,5�uÿox²†þq9¶žÆMKr¿5߸i\äb°OØzŒ{°zmÇæEj¯k>®³(Y&êÝ85ž3MÿÀø‡g²ÛUªœQ6ûA¶[£dà–Á3¢Îˆmö«"˜Ó³R‹Añç/î0(Ÿ¿®òÒìûØ­?1èJ½Ä™¬}r˜˜Z_¶Á(ÿÛ£„ÁÇ3})“ã:ÛöF˘r¯§ïÎhQš·&Ðë·¯'ÑÑ>>p<ÉE]«ãÉm¬.¦?ªØ‡Žœ§Ö¦£ḺÍ`–õ/Wé<>î“`}ý=Äá¬N{ë°ÜÕ�Ûßw8D^ó;Hžöh[Y§dÅ_ÿú EÖÑa|–!ÐÕi¶ûÁo³¹è¼ ù¢á87èi¡+8˜«Y›ê2'x´äùrƈó÷öô_Ïl¹árLþ«B-“3¾\#æœQ]G3{kOö˜}¯Æ,ý÷¼ñ1ðû>"¯±ùš~ØíÎŽ˜>Ý�„ÙV G­îÓ3Æ6àávv^ã™^M5Ê„~kêÚµ’Ãéõ0öõЬ«°[–ss_‡÷à‹k¨ˆþôæà=³­_ ºqZÁÛzÁóÜx×ë§m s¯ÇyÃNŽ��ç[/>wí)ˆÔ˹yô†A |<0E�™¼_ŽŸñÛO¦qf «è<À ³…S?g|Z½øÃ÷]€.3Þ陿—k1ó'†6·n‹3ÊɬùiºÏü’|w+×ß«óZî œû�©AÆŸûe^gæÆt0 7†¯+fÇ«œ³�}ºo†Ñö/êËÁô›Ü€wä)•jZÜY¹7`ë9yÆ{0Ï!Së8{’=›æÝ£!ÎF—S_�±ã™=‹ÓcýR`‹™1ð'ÒA8�îάyòí @Ìç„—€xžÄ0ÿÃmŽÅÀæhÙË|™Æ½4õì3àç…røæÍlLsä"ˆŒÓ2ùsÐVcñ ç@ÈôÜ�µȼì“A«gí$9tÇÈg�Ðõ/ß> qSȼ^qˆñ 0µö'¯ ±õ&3:—aÞþØ3Q�Ü–'¦<ìSGçÛØ Îæ½cÊës1²õ-^ä±È ur°¼zB†a¥9#uxÿzy„©¶…שZ‡êú…c:nª…[C(å„çGnô;'±�ëÆÏàão�ãÖ<Z?9ìPFú_>ʯ ó16¶=„g}¶”R¼ÒF ÂÂAœsþ(Ã6ñ¯Å”³¤ž³i])ϰ* "„±÷ðä3Ám�AÑ–:¢œž|œ§#¬µ,÷2ߌžç/~¶Æ¹Î®?ÜÀÇ—PéhMâðý ûf(\Ÿ0I¡™µ7\ö i0ŽJœ“ËJRC›xpòÛö:ò‘ç’›èt¦¦òÚê½'zÇ:8þÅ$3$¬Ð—bg}Ÿæ¨Ÿõ ]îäiXRµOa/¸ƒ-ŽéŽI-ro59¹ªøÔaPZkˆèƒïÕé~ 3ÎoVkHÂÏzº´HjÛÞÞã°~ë+ìÁFC�‡d{áö,œƒ‹5 êûÙ!`Ò¿è¿<'È‹iÂß÷†Cÿö¥þ£+ìİÊH¯SGlÓœ>%×ÐĬæÌaYßí�‰Ý]s‹|ñqDÿËU'î0”¾ÀJ�á�­ �Pë“–&¡·ŒÄyyúÐ�ŠUþßáÜ?c«áúÒ¿ñ&3;KñõÚb\os¯Éq{Ä>±ëGn4lp(÷£'ç¹Þ%ûåVÌOS9p~ƒØÙorÿààñÑøb‰jXî X8Ãð…÷ávœ©Oò¦Æï>»{¥¦i½Ö“ÜÙ[äÚy4ƒ@»·A¦·‰üy=ç½bÎ<¤êÑGzÚ:RâÉ��1i�Óömäwâµ�k¡„¯Ïã9³|Ñ�˜%ZìÎܳû˜œ³¯ä€svf—<¢¸c;¸pqîiOölOyso°Éxh'ùÖ_ša¯C+çºë—ÍsÍ·¦éI]Ö$½äþþ ocw8z $b+ñ $ ˆŸ5F;ês‘ Ï_‘n�j;çŒAü²oF¿9éá±òMÇfsjöÎÔ°:‰˜íÖñVâo&? o0YŽ ­Ný…Úõƒ¼D­3•ÎA®Cö�p{lŽÕºxCneÎÑx«emŠ&‚ ƒ�Î*§ª³šö ¸6Þ«p\Ò•³=VïßZœ¥ÚŒ¯ÂÇþȺDõ§Ê‹p�âdò÷ôkc¹¶o#ð¡y> ðÅ(s×7̉#VO÷hùpv}»Y‚Ð�Äž±x‡/Óñ:ƼÖÛcsþ3ŽÍ¸„y{o´ãn�§xÅÙ*ÿQÀZvÿðÏq¢4m0çþÀ\n'â"£É¸$çqY˜ü¿4B6|?8>ðÚ—\!Oë‰ðx„»‰Ã×½f…2Ãlv°Ä» ÍÚ¯èϿـÝâOöÓ|xú\üÑ·…óTÔ&b6ºžÅúæÓL®p‘ؽ7ãY�»ºÌç^iÅëR1í¹”Ô{¸fTÌjþøËCžŸ±«OsMØKÞõq ñZ“ð³FÏbþÜÄij*qÛ9–>Œ—ÝWgý>_p�þqÚJf=Öî·þäLº–øraŸs¶‹÷LÈS�^»Ò~âàûô¬eq¦ò³Ÿ+šÝ¨tîÃÓÜ`‰ܘá¼ g“VÓ5í²‡ mã·¶™Ë;pÙcÔsX[ÉùæIŸàc—=6VP¥.êL½'¯@Îo QÁój‰Úð»¦a—Ž®g‚o6¯uñ{`5¬·kïw"ðZ$ºyžÁò“àñz·ÄòhLú[³÷ãçs?ý\ÚÍÀÜg]ü¨ŽÉ�Ù⎆XÞ8Ö�Úì9yÎ"`¶ä%вÁ !Ët8DöÈqdðm iÞ\ÍaBà´q›«CqÎ#ó$utÈ—¨’h“3ÔþÍá� ‡¯<‘Çå· "Ž$/R3}ˆÛg]¸×7ªý -ÚO@Ñœübu-F~â_®Çev8xÍa‡?y’K{;°   öàú#Ûª$&Š„°V;�dbƒJ9ëF½äðs±1ìLî×ø¿±·Îñ‡Ã('ãþuXÏX7ݨHŽÄ²ßHíwÇêôÜTa1ŸÅh/{˜ð}×6ô’˜nà›FXkƒ8��'À™’çÓ&:±î¬ƒ³Ý#jÞCððI$šœ�«ñ`á¦Û‹�³6c zëHリ={òd—zÁÂ}sq6ørßáŸÖÕ›ø\‰e�MvÔdØŽ"€¤v\ÿ?AõÆ?Ÿ^9'd@Q®¡mz[LÊ¿_ªbxFÔ&Ç^k0%��¾ÝÔê#3›kc¯¸‰i´õº�Úç@ŒÎ¥àÒs¼ô“My<?ûÕvÛ€Õ™Ž…ãMo&.Ž‘_Ξªmò¤<]×3lŒñ8EåÍÆì5ö b¯?ª­Þß 8Ίj˜/Æï¿&uN]l•5;$o”Ö—âä0(P-»­�ï…ždï Œr¥×¬ó â‰fIÏÇ<.ð.Aß›æ ¯ù Ì}KÎNØ3þÝç@â¼½‘éàêÖž:Lm8ñɵ¼Ó_whÙ¼\ÐíP _b¯4X‡IîX�3£ãôU V3v߯•wÚâOφ5u1¹Ç—-³cá{ôg ù;ªY¦óo¨bÞÆ£wš‰Þ=�ûô5…Yû‹=š%àÔIÇñ+žÇÁ°lnË ¢v=>±ûëókFŸÿy®§ðOŸ×Α r8Ïbc~®N|öæê²& y†·6×±éÌ«UzáS¬ÿÉ0æ>M×ú×Û¸¨†DÕ¢ ÅY#,l:ð¯×¸à‡ï…æJ¼®ÖEï2°o ïY׿ ûÁÂo¹£;ȃi {º­]ëÙìøÍå§çR]ΧÉZœÿàšÎ9ÌOŸ¬¿uÀ¯löƒ_vïYWx0à‹,NŸ pò°3¢ � þ%9Z,Û³¾¹¢b‡ Ì2CŸ"˜yÚ1‚‡óàT-â .Ö/P8µw óÏhÉÞ¹áÀ×a®YÒ†£sÃ1“ýþ †Iÿ IDATC»az�‰(Þú>ÿ0¯Üå]ÌæèhM�ÖÚ§Eóê^p¬¾Ó+ðä*ÈýÀ¦áœ Ž ÒÓãõ Èr™ƒ8‘gÌ n÷Àj .µ‘wÖæqOf9’�Il|`—cÜgB.M<Ë}öÍj¶¦ûê®Q±¶[Wt¿ýƒÛºgvï1vا¤¶£¹<¸]û4±õ¤.s=}4OcJ�©y‰ÆsåφrÆöÉrcæÃΘLðÈóØ|üøöšT¤‚V'�w®Õ^^ìÖ½å�æÜ‘Aã ÇqõÇ v@YÈ?þ¢_ ®ï`ØE3¸a¢ýtñûÉùáÓŽõ®h9É>üà` ÷H¡®3_8í[Ù›Ígý嬙�ÞO›Á²˜c92»OÃ×Å‚;ZòŒÑXøµ…þŽ[/˜¿ô—Ì©÷ IИۛ‰cˆw¿áÜ7‰kÉ™Ž.ñ°ûLŒÅf‹w\Îî“î³)ö Û—ü,>O‰Ç»Þ¡“µ{‚ÝÎÜ£®¡ŒLôÊý¸>Ü^ÔXNèn�Ù1vÎ?ÿR_0o ßKÓ]ǪÎ7#¹§Ì|“•Ë pùîÙ٤˘¦­¸êpÜ ÏÆçG(a =©¥1¬qƽg·µÊzëN|›4;sdÆ'Ë[ßW{ß›—¾Xljä?‡=?< ×!ƒ‡÷¥ÌÑZ͘ö¬¢éN6œp•/;_w¡¦ òGY5V”0n žýgÜ=ÿEÎýÍcy]�ó›-úq]»6r§w³EÜFúJ\r2?Õb”ÓÛ“Óy´Ì_Ø+¸È72$<6ßÅY�.Ã’sÿÓ™)ól`,Ã*Ê©¯>×DÈ�­ù·OÍ"òÄÏœØÍìjŠ£W÷^{Ã3àɵü oÛHÙ´ [WËj 0¼ñä{ñÎ�6@šÑê¸ed/îåI&‡žË¸VÚöMå\p˜SQç®Áfºxa'– û£mýémÜðy¿Ø† ¼{έy¹Ã“œ0mñ/GØÕG=È¿º~DÝ^‰h½Z­p¯vâxZwµÃyøšcyˆe­:ž¿näó…1dœÖr5÷ÕaÜâV©0ée@`Žr’T¶&J½Ä¢ƒ:ÊW„c©êäôaƒã]“Æ©| b<Ãǯ«yÀ¼¾Ã©47SÖ§tâ›×ñæsnÕžŒ¹/²V,ç¡ñ‰qõÞá¾Ê°\G·òŽ –ó¹kœõ�k5nO,kï¥óžß2T<ò3n>6ÅÕgþæn¹l‚x–Ó&.Šóè´xì»WеÎÃÝü‰Ï×ì'F>pþó ÀbýŽy.?!¸bÛ÷Ú 5æ$ÄÞ¤Ö‰¸ dnüÁ×g³¡ŽJ�õ‘«sý.¿ü‡O~ãˆe]�gz㻾E?7å8±,CØn¦ød@C[µœhÚ­´ö5/këvl˜à9ñø1oktuü­ÿiÇs=w5ì™—ãðLyD½ÃΆã¡>újg2›k/tŠ;™(°GéÅá;Úÿ¶Y6sÒ«Û¯Qå~�ó“IJwŸølÊAhÿV“™Ü6à¹,³�•ÌæÆ>°®›àŒ7š36_üôàOÌ{ïd}òŠg¼®õÙS2·ˆyÜíÆÒ[÷WNðí�»'9ãfÆwù§‡–D·ýÂx¯bÜ ¯Là~œžÀ¦e3ƒÇ^ M¶Q@±Ö¡­qÌ+.åX>þõÄxð9gæƒYC7‘?ór4Y»bݸÑÕ‡q\°ééšÁ�"ksSÄ!»]GÂí24/þ¦²‚6¬¸¨rBŽõ°”‡þb»dÔQí㇠ö˜âG{bÄ$*êfX·–é� ¶ÝlàŸþ›t^qN5'áµ9A�¬=Ø/žù»·ÎƒcAŽ aµ™Vì« ›cg ò¤¾ 0Y3ý0sò‡sZ^|rŽ–˜üe&LàyfCG¿öa«…ñ¾ž÷¨Åß¾P—««FœArẵ-ÿQp§¶üûw©MÊÞðùjQãH,ÜÁ‚¸¹î×N؈!8}¯´¼·dßf'9š­Áñ»'ã}kÄ6;óÕ.cþè=ëŸ/:ïù9®­ƒ gÝ6�#Kö2öõÒG%üú‹Ý¶‚6V‹û ­ÔúÞ+á´•3�ÃÎóÑÔ<Ä9÷ã˽�×ítGoã5±·ÏìiÒ¼˜ûï'6ûSXbÁwTÞbg†ô “¹y•+ç2-hxºzüþ�®X13*À¹ŸŠ˜ó; 7ÿrÛ@ÎQ³nbz‚ìÁ�æÌ\÷—J6µ9€øÁ³œXü6i�ã ›ñ�î‰}ç)'~F¹¶NîðÙiÈ^wɱ>ì�ç„O�cknømcVÑmè`ìþv¯mÄÚ&LJ[1X Áóàä#MrhV?ö4icç7GÎ)®ñÚì~–Ïy„‚óáYþX“�Bxd­É}]°œËO8¬·n&ƒ‹)­¦ù?O²ÃÇØïô²#þì]_0ñ)Òu€Ë³„¹–ÂOIZ˜¦µØ­6¬ ÌÔX¦õj<ÿ9Ží‰;õ»Æîzfƒ 3ðœz�º—!‘Þߢ‹oŽéæž`ŒauØhG<ùeÿ±fAìOÍÚ›cvfQÀ’{èV56ð¾wŒÍ™³GãícxnÍ• ÉÜÞ¦*ç—ñû „j }1@WáÓ°zl²=B½ÊÒˆ‘k÷- ÿLrOƒh\(B4Ì›ånnÇ?öxïu7úêp^S©ÑÄéIεýÅ¿?�Nnð·¡­"ÉÌe·÷p¾ƒ¼És­÷×Ë´ÿÄù¢²ºˆžõü5+µ³zQýözu;L ÓOö\©¯ã¬ì|$Ó®··„Qk4…3?Á&qHg¶ÉKN ­«hµaóã—z§ßHÀëñ$>3i®½I™>B>DZd¹wU­‹y™{Ÿ¯Ÿ®Ã r´O§¾ö˜rý�ÇÓsò:1ý`!¼<6Ð5.Pö¹wãêO1á'�ØL^­7˜rnÅ£8Sƒ&Ð)’söA=ƒi÷CkÏ•vÖ²¯†•�–ÙÌÑÓqÑÞœøô¤öÅGú#¬–Æ:Ÿ>¦c}EƒmŠgœZÉÓ�¹‰×ÚϧÇGŠå÷ƒÜLɳ�$ù1¬Q�£Ïk�„õ7œŽùØ=ÔzÒ·S³ÑëçS¸‡Hú8#€hÀb«.ÖßÀõÆ^ùL)ÀÑ-Ë˹¾xn~cMîlî]rÜ=Ä—Qø4FHîñÉéþÁi‹$8vbß1>"�¸cT4ƸÀe? Ä݃‹¿rm-ˆWçzä,²Ãù©wtUq·Q5ÞóK¢XDækR4²|lÞûûíY�09 ûðø—Y§ÚNó4‘D!¾$o<\ïsÜ÷^JG¢+Al5ÞÍÖô}?8 Ê)E|z Õeï�¯ÐÃ-õ —a¡™ÇS^kä5°=3é¢&»q%Oîìãc–ÇÛÙ¤”_¬a|¡AÞ…'Ë�ee¾™  7AÚi_ÿoƒÇ®À£ë]V¬Ã¹dÏ×:‡³Ô™ð;Aj0*êO­ðßgsõ-!£?�ž<Éë¾T,ß‘¼ØÐ6^ôŒsÚ˜áʆÅÜ¢ˆŽUýázøíަd›’ÄåNèÙ’3“—l¤€\u\­vèe°µfªhë¯#uWlˆÝ¥ôKYärå´Û�Ãa\¼n ¤=ÕîJ�îèY6>®ú®üšò×&ê�ÿêd<°Ãó|þj‚Cáýxµ!Äa²ªË’«ö{–ƒ×0g‰Áç^HŸæO|pž“3?kç.�·ãÖ&){/h—35ɪ[kž„¥·-æÁcqκÀ†[Žg€izϾ7j3÷/A3„øê‹.¨›Ò‹OÝ×óô´žLO^wNûÓAûÒsGâEâtõÈ=¼ ˜Üo¨vXðÔHïXÈ$Ûbgß9¼B„;yÈúôÀk£o}Æ#TãÉá=x?ñËÉUyüý(Û†ÁîõÀ@.„0 í�çÞyþ-Áò�¯kj=¤©=×�JK>ç8$^Ü×|¸ÖO‡¶yǦ½M‹uYœzêü<ÐD?kao¿{‡ð�‘ƒœo||Ý–˜åA”ˆ{x­„}õ:ƒ6ÎÕBx¯ª„¢2ù—-šÒLç~4t”'ÎZVsDVb©Å'vM€£õ²ì€‚�'ýñÖ†ë»U`ÛîúÃ5㉎æt¯8ŸU‘˜ÓûlSïêWŒû¿D/¦ëiál<[ÿ¦á˜?tÄùíßÜì‹–õž_öXûò1�« Œ�߆l@ “Ý_ÉfÄðò¯7‹üÞ !ØY¿±ð.¶RÜÇ¿L°Jl§. v”.�‡ck£€�ͦ÷"_nx¡×blA¾A‰ibDÖ&qØÅnÍéBÉqáIÓü¦xG/ƒ°˜�÷Íe×�ÜÍùêIœÓàÕh>©ŽŽìãËuú,§ÚçOÿ«¯F×Õõ'·l.ÕDLñú¶\öºVe §žO'£Õdâ„WO×Ú\‡£FðZMO-ƒ›œÃMã‚ ³í%ÅÁ5‡ãµF×W[WÑ[3Ÿ Ú»„rPƒžyÈÁ–K–Ÿ56sé²ÌÖƒS^"ÑQŠZ‰ª�e�ÆÙóà½L~#­-1ûK0ëƒG°õb\DâÇ��™‹WršÙûëÚéC±"uÌÝj/·ùä£f×vkHÀ�³ ã´úp'�5‘gI4ûL…�nzÙõƒ3aè‘�g(ÊEõƒ1ƒÖæ+lµ,þh„ ÝÌ×gÜ©¿\†É'Ü#8˜ôÍ>lz.wä%`Ü—ÍŒ耗ÇúP'z§ùà ;i¬=Ö_zR‡ãµN'nŸÉñåÌ?, zn 2»®PËÇb›§ÎÇãgÚÓ ;Êa:]ô�Ùš�–¿V,&l¾Ò xv¾Éaƒý‘>ý‰ŸŽôa¤ÃÇ"˜lÚξ=œãÍûÃ�Éj!'�YÄc‰µö5��|yM^Kò-gsXô1_ÿê´vÒâ»îòçþ¶ãwµ›DÝá›KÁÒY„©ŸÕ[ëòï½eõXCs¡)8G³«.“ÃØ#ÁŸáŒÞæÔ>gfûž%]mð^û�+ü°Ô�î@öºˆžð¢3O¸N,Ù׋aÌS>Ö¶›]otÖ‹3ÄÚÁ]^Ÿ�LôxO3iOìFþ³[‡ÎôÛ9šæZ¼´X{j|ÎJ¦¹–nQa¹»³òâì–Lsj>šÇGÍ©‡ìCƱ:sWŒW> úúÂl>‡^¦÷›‹9Yª#üÉ SV\›³ àî_ãæÆO\B¦9Ö¡¬s5 R'qþ+î„|ÙÇY™ä±žž,ÏNØå^„-Ë=ãü¾÷ÜspnÑÎÏu»g‰^¿­Uº™©ojX¿c{cZ�ð<Ì4,Çåá>Vru^¾ôgHô¼ÜoOs~æ \~ïZ8Ùáß3þÔm<1$ˆiIͳúæ?ß?BÆh ù—Ïví�@Ë€8ÖxÑÁÆ>¹‰~Œðv6Gyì½~èœÎ´’<å �ã%êýƒë„Pc mÞ×çžÛÕ$Æ›-¹Æu g WÇø¦ýå<òMOŸ1.‘2ÐÆ£'|ÑìUðrìá|`ÌŠ‡w½X~ÜûhÎ>SpŽ," y0„^Ä[Äfœ¸9kÚó0¯×Ñãx°�Ö›ûš¡_ ð oMÎØ‹\Ø’-¶ñ9^j"óêÃÃÜŽç½ËñH>öŽІ¥ˆÂ‹—sy™·~b¦#‘á^�c¤3ç~å»Ç²Ó�#‰z\SNÀšÀ‘»¾ÊpÜò›?†]^‡âz ó€_E= }óŒ`vͶ³ßîÇïTìÅ8ʳ”nB9NU`f+çnJsÖfâ᦯¾ð/‹ŒøË;-„2Œ2O÷Âa[40¯›ƒòò‰gÏ¿ÇaþP�ð»'—|Ö3µï7é Æôo"›“Š¬Ð–l\÷Ä7¿–Ÿ~Ƨ+Ü 5ÚKÙŽéÄ%œ­¡Z˜g:»à½îŸÌx÷[ŸEáøýâ Ô{OE°Ë4fG)³\Ì ú«ÖA1·êhÈÞ"¬Úûæð=K{–Oqõc÷="¶Ë],?Gb+/:‰)ÔoôAÏUý3{ësmÉ`]Ð9î:+ÃqãVN°¶“_Û/·s¨¶ë2e'Ç‹‡=éÛá©ÿjþÌ�B‹y-MYœ0{ëcïœp‘;¿�9> r$•å:6‡cÍÝvQB/…‡{\©7õ=àjA°“žÉm‹9²Ò1hçÑj¸–süày`ÁÑêäéh¨wÔå:Ø9©Í£·uxj…Ï5¦ËµaIô^ˆÞÏ ×Î𱮦“ϹÈ�®B'«{ìö CmoÑäH…`žu9-êó7¦…í?CÂå\Ãw^O3ßs"ÜgN:*+.íõÏ;”#õ¥Öhˆcgvcß+V§n,“!º4yÑ”|Y–_2p�0š‡ÍxâHdž‰c>y¢ ¦ä:cÖ« <êÿ ¡èÀzÔÙ¶Ôl|¿UwâÉ’LøÇ†pù|L’€ûe´îËâj™¦_g`Éšž¯ï­áˆÿbh0.žÑ7EÄ›ªÂ3s^�ã«Nm±øµ‘�Ãæ�ùpùÏGí; D—fÛF†s&²õ^VL$¯=# YWœ-9êðÃõ"˜óÊÊœ5F˜¶“'Ö8“|À×#cmÙ¹›Ì‘Ž>y¦5óz�Ü�Çvù“;9©Ýõ‹þÄJËaEˆFê*Ö–^Ü0zšã:Íëmë¼®g]-•DòÑÇÂróŸå06ï·‚B½˜3Á–�Íy˜õAÿýþâ<—Ó5ÜBN®W_¸à�È\Ù'?óðá÷1Ìö̳m.ï!Ž}Þå%.?Ð�‡­§ß"î×îôdýо“Å'Œ²FAŸ ü öN³|Ú®à�OÌ% †ø3Ÿ^ Ÿõ¯Vkpy}ús¸ì™ð£§�ƒO®Îl™žäXسŽPÅ-…�öCvð�—Ùµƒ5ž)öÁÆé˜N{çÊkØK„!º¬ïÌgX¤óð"5ƒ¡�Œ£-ÛÆg>dB¦” ²,ç ®îl ݽ£Háx¾˜h Ü=Û_äs<åIàYƒåЭgÿÇG¿˜l=Ç>)nœY„± Š³Î®=)×0G³B5üñµ?Þ¯£§/lhdˆÐ�#'kok³O’á\^ó�m\HAÌfü¿G³°ŽƳ/±Ñ¡äm¯N-?ög›³!]M,½&ßlË·Cf?‹ÏÞ ºÈ†š÷Xü iXwîA2gÎÓË`’S×Ú±‚sÔlô¶uóµ¿û!Læƒ^Ô‡ ÁŽUÜ8�¾rbç¨ßûK/p¿íY3ÑÆôt^tÚ í0²�ñø±î{šÔYœ§èÔçghšL|¶´û‹)ÐÓŠ”Ê4"Vˆëõ!¯_±ðnô› 7ÖîèbiŽèާ4——@Z3|1é `Z:ã(Žß™Æƒ ‰7'&üŒr�}¬ßkµ\"¹e#ë�ÿÙGÑ~{cé„!¡Ÿ,v«õSg`½"š´Îh›ëõ`Æ¿ž¼5­}ÌÉ›ë‰]7ÓWveÒäÕ‚oü´pX F�õb‹uþƒ±€y/Ït™- lZž† Uh�p;µfçAƒ>\ƒ¸¬]öã[-ÌöWwx¢/‘²˜4IÞ¸Ç|î ¡<è)#×KóËžµ¡å5��"I�.¸Þd8n~ç ~ W—k°–p˜Ï\Á‡¿ùeòh®õe3¾­§=:|/Kg[øÕ*.0<ÐFŠô¦Iðx™ä)÷ÛýÏ!Œ‘™¼§†À„Õ0ÜáGgÌèû;qÎ% ®ÆZ—¶;¯†%öSAá̵FF×oýäÏò6ÓyLã[AÈUœ)|ŽL÷`¶:+ºóÁ¾þERpá?Œ‰=ñ�”èxî{Á1|,–ZyßRŒóg?æÜO hÌåâðÈZ9Ñ?<íqÏàÀ¶³�ÿy�‘îäÈ^ωõ¢âνwLq\À¯žð ›s8¤Þ/p®>koÁMâ%cÖÇê‹Æ U‚…dòV›ƒ�Á׫óëÏYÃ-O�—Í%ÈåhJ‡ÁÇ>¸xXS¸nݺÖÖ#?½Æš8/Îù„ò2ãý]m‰ K4’¸÷¿la0EkòDKúa©¾DcC¨"`Ó³ÓÍ|s””æ÷=óèk” ÅÉ@?Ђ/<Óaƒ7ëàqxå D\¾Í©OE±¢ëÅžqß‹‚[?™±p�M;¥›ŠÍ°\Žè8šå»¸Ä'ËÕBtPùw$-‘D~j:ÃJ¼s¾SË‹…‹÷ø�âÛÔ³~Å 8´¦­9$¦0�醙9¼É¢Ûö~m+ÍòªuL¯ÞùãKlx¹j_m÷¼‰F[ÙL dg¬`½íÚ…;ë™õ,ѬìOOµpÞa:‡#ýÉgT®l‡±þw_uL^’ólb,ü¤4_âÞ¯Å!íÏ, À¼ùcãšûlêžþE³ÿôÛA†³ÒIÿ×�ìí’�XMáñUø˜çól›.‡k˜�oô~b´ WÏí”)­Ý�Pf�¦ƒÿÃÛZd±ÓýÉò‚^`®½uZ þÆ´ZI›ûÉRæÈ18ƒuaf_'Óô÷…¼Æè¿ø<ªùD·:”Ç=“�œ^(Ì9O(�Iý^ש;zrî@G×ôjý²^@”üÉ_�ñˆßôðÔ8üà�<ŽƒFfr†� ³~à–½{ÀRxì ›ÇXg ÉâC‚‡eùÄ+þñ’ùäc­ÇÑÀ.yF8¾è2¾i^.‹ Öü/W©ö_J^ææçÿÐ1}Û?2®‰œ#QKâ2›áØø'‚¢§á�^êvíý/BÜ7ê*2Ï ë\—wÆk5)6:(‘ö¿Nåóy˜ ÙN7B’Ïúp�¸¼ãáÌŠUéöÌ¢5Êž_T5Š–< 8sî÷E6ÿó6¹šGç± žõÅ{jÙ`½ÐZ£)q„–¡3a‡Ÿ n?Ÿ™\~�Ö-9ê1pr˜:±Ã jBŽAØy2&4‹ÂdmÜLO‰¹±e0üļ¼øOÞå#Î÷19îÕeXn籨ìQg}ÌØ“ȼ'ç›Ï Lh¼ù°�i}ÇÖ=îÕ“\34€q~Q*ŽZ½·'ö.�«·Ø5uåÞïý}a‘q‹u?�„¤¬4žºOïev-¾„3G ´‹gV¸—¯kÌõJaÃ�œãRT+x™FÂüŸìñ9�sÜÞ8ZÜ«Ñiš‹z|_XÃŌͱʹú²ÿõÚ²~«Ž¼~´ß§i0ïzZ�»G–eR½O@5§/·ké9œz›—d¶™#ìÎŲ6 ‹ûÿ„�‹v;Œc×ôÿó¬ÁÆCRçöÈ>%ŠA�UvÇIpòÆrãá¬7Þ™Ÿ×ÃIŠóáàñ�ÿè ùÅÉN¡=Ü2(uÉ$§×R„±L.húßñ§6×~|¿ZR1¤Ø)‘^øŠ{z²Fø]ƒ„¯ÌxÚƒ£CbM»¿ߟøŸ�Aá-é™槇—óØp°¢fó%÷–-b‚µç.lŽó‹7Tþ¤hŸ1ìÎÁŸ™C1¿ëÞô –Ü“›“~îyº'ᜠÇ'r?S‘â×—ÅîÇ‹í\&Ï\Ä«ÓãvÂ%å7•û:훀‹p–?|ÉV^'åÞÚ‰ Éê5B³�„\çð�¯÷ó|ÛNš{žþ“›gý+A X¤ôc§€Èàã?ÎàÓ+v^þBèÔ�Á»^D“·sðóÌ@$óbÝÏî“Úö›-3TþÌ@´“Í:3‘?½ÝûO<Ï[°þ&ds®æá‹%`î‡ÁÎJÏÙziäѱÎöq)Œ@ûxX,ûSáôÖù£Yøñþîw¦è¯CݼX›œ`8Ç·YY[\'&ðp¯å·Ù'÷$;�‹'tê÷5,7SEþß{^*…ߘO©ô3�>“gæÆëüɃ;µ D+¾®ƒÅ׬iÁŸû@|QòOòùÉ™RlÎ0ì³e"ó÷æ¦<©Y…ß�…è_xt—f÷.�䞃±¹¹¼¯ÆTg½Þ>—^¼Î�ï«[™Ö¹]>9佫�Qw/+ÀŸ£ùdö'šüùE˜éþbàÐ�Á‡ÃÔºŒ[&½ Ä}6б=9á'a•¨|qó>ÔÍü¢ߙߠƻ_ã­‚çÏB;@6÷ú_úÅEÝ舖‘Ù¿bv¶¢É•xtàg^‰S� ³ IDAT”мx³;à¼KQø x\¸¿ç7c‚¹—Tù.jž\L�­£:sV©« Eë£ßuvN¡£Ñü†°þ¡{ú€ÇË5œÐñoVoxü{s>¥lÎæÕÙ:Uïô§,²ñCªë¸'ynö õ_ëô¨�SÊ_D5-ó}àÇÅŽßoÚéw¸=kËŸ°ä�c:w÷á"IH+é܃Cdžƒ�àý¬=CÜÃi˜ÖSF|Wݰ#sßôþ¼øà7Gó—ýòZ¯âÛá[}a¿œÄ-td;R—n•órKÿŠßÕ9É�;÷„¸2Üá!ŸÕ-‡äyæÊ™N$±æé!Λu\)Ç—ÊŸo©è0ñ™Í‘) ´gf­iÊ’œ:¢8³°Ï OƒàyãhW OñÕ½÷™Yos¦ëÕ°‚¡1ñí�ã§Ÿ¡íXl­ƒ±ÛôÈ3ìžsHD×ñËÈ}ç¹(gK˜à¹ — @G_¶ë0QÓº]f’•|ìÁm'øÿ¹R�׸,¥>R㿵ðý.þ£þçvróŸ\<ÚÀ33m¶}yHh®‘¶‡M#"÷>_‡,<ÌÏ´óC’�¯�}ž©gX˜yÝÿ$>^ÃßúáµÿáÀ›2\cy|HéÑ�šÎè=4µü'âŠû©pîj„.Éåô®;#}&8ow¦|ÚâÉ9š6¹ã#n÷WÄ9ÐÆiåh }å›�NóTÖ뙫IÄÁîà>äžÞ~@„×ZFÔ<úH/ÉG÷jØ_mñW3¹Zùµæ²§Wæ·Ï ³Å¶>Ùmû¢C4³¯ö«Õs‚3†÷šÊe¥¾ø×¯CAÈeîÓ?| I¼ÉK>¸ÕuZÏAÖrJ"¢tóôiúåÍ.ü§8ÿõµÛ´V3•]úƧ%Wo4D*‡“¡u¢Çö8Ê�"™%hj^�Ê=³#:6'?¸ÂN©Ä‡Ž|óÄMÂ’¶7¶›Òvð¶Í3ƒ�ÌíKV·Z_ “Ëýô[ÀÓ.Öq�`rÕ¼úF4ùu o~lð9ËÌO„X¸PÉŠ[vÎ?¬AºàO?ÅúŒÍJm[ôý$§;gf|.ð­§Çí|bÖævŽ*ÃÚ†Eù©ðÊi|‰¬µ²2‚“eDêÊõ;'W*t|`Y¾Æ´î8ö‡ˆIr÷$ wzÛ=hî!*¦Ìž¯û>Å\ö™fÎèM2yÓªX¶�îÕNjtË>Úê÷¼°iBZ ×äzÖ>�Óá /ï©<ï³@œö™ºä�}b«­Ø8¬‘³›¤Nò­Ó§L#xÕšø‡#YrðNºMŒØœÍoz�$î–œä`ün™ZYÔ&eøïŒ„SÎ儵ëáÆkžÓk0ä­_ˆ°W{–ã£Ý®tpëÍØÖ;|pÕçÚ𧬯ÓÄܨᚭ€N¿YJÀ³1Sò1­‡š?qÚþ,‹O.F ,#ä;½®GÅÆ'‡Œ]äjM�ø7sû¾ÌB^K†užø—sË3¬ñ# ×6�\îQ, ñù¡^,™�~÷øZÃü²—¸óî!ì�é#ÏVr°sŽÛ$iYËÛ/ØÚ.â³æ»üéÆYÖÿ*Qšr�îøïÂÇËš[LîEñÚ†9Z¦i»r¯ú6D¥Øl–ìêÔöà|DnÎ=4§êÞ2�ˆæûèÐ9=PˆŸ&sŸþŒå¥ƒÇ¢Ûˆ“Ãß77‰·®Å[Çý âß¼ð¸ÄcÀ‘ìLä6ü©û(»`Ypð‹Î;Ó«í6ÄÎÚÝT4¦piŵРq&?;5“žÞ|çžúý¸h)ëæ²Ò69ð"`„öï¢ëjÁÈn^ú­îßr´_xˆÃîù!å<7Ååáäû 6ÂÒœi^�ä%˜Ø+bv>.ÑÜ&NýñmŸÎ 83îD2°ã�ãå©ýºL¤;l_žwÏô`fˆU¦ïI�=kÙÉM>õÏ_†ŸU~›Øã‚6ÅsÈç~ŒsbÒ Ù}êù�DN#E'*²à"gu†â/~[¿›g‘òbÁä¸\—:sO Ï`g�ÜßXä{¹�øoS�QÎZ{P|üph‹ž®W–ñËß\8Ó?{r‡K/êñ6e,È&�éãÉÅ~ó–œáMvf2 �¿¨ˆù^�öj‚EAþS›èÀBÁÕ€•ȵŒÒ1÷xyÛ›`Q䌟,–pNæC¼<1�fÈñ2¥,÷ijê•÷غFuÁÊÑ•šÉw’ƒ�/sxYÙ£2ñ’羦quŽóž¹¾"{zª8Ç©ÀyñèÏ~ù×€PPp4ÚâÞûFlsB¹à²R�}ºà¹ÔAº¿¥üî@ôZ>žÇœ:¤~æúp¥RÀsáf.êsì�ÚQOkg}Sس½Ñ²ÜÜ8Ã{ó÷q¼'«à�S29ô6?Z¨ç³Âñ�ïœãk �}ftô·á»÷Õiåƒ g®î™s}Éiܾ>÷²wo¶ƒÊ¯ÉÑšÞ›ÛÍ}•Û®¶ƒmíi¼h×®oVg{z)¬ÛROŸ7ý@A�õ˜ùgªÔ©uH7KïHQçN÷�ÄòbºqbD�½­Î™›uR€h—i/ÇbÓ¼óàì®±�fµÐP‹SíhXýéÜž¨ÓÓ³>ÏOÚµÊqu¦ßÖ=:Có\¿=çèÍõØ(È\á“}µÕÿaÌ|S?òœ«ã4g9ƒ¥„¯ÂŽß÷ÚÑsÏ–£Hô8ÓBã"%õɸ|ø]ÈF.Ñ5Á¦Ï�&A�pÿ( ÆFëÆKÀÞïEAâ ±¿óØL.@j±~<‡§½Õ6^—á8;Çæ:Z‚,èÕ³Æá§Ïœº¤½ÎzMüËÝ>à›£ÌÔrzc•³\çå”wš?اÖ�bë97­Iù¢ùLĵ8ÙSÌý©ÅøOœZÐUÝ'f¦\>:Š�fv^äy9 ”:üIƒ )­ýÚ¹ã²s‰Š˜bºŽ_µª›¾°]¿û!–1MGƒ‘A|÷ïés‚TÛÜ7åXã®H÷Åoüàs½ê†Àß³0ož�õ§ðñ»ú)éAƒ°*áE`´í…j§—ixx�Rè2 –ö“iñ÷ꮬ “0T—è,§yÍœèÙºFØAà~d*533Ò<Éñ¬VËÔôÝæ6\&•�Œ=3ÄÄsæru€b¹ÿ˜ÂòoüÙkiv7f¸m¬ýÌ®~æ‘7q,ºÙÚ£��Ùä¼~\Y‡ÃKªpîO$î�Wu<ÜÑ® |ãÊ<’KŽO¾êâþ<ÛñÔ?ÀrÐòjûO±,§šŠ·¹¨�íW'&ð¹W¡¢wYq: k}ܳ@èJ }ék8F®2îœ7G‹[H(rmÅQ-T7÷ý¼~sx‡•qøJdÌkã(þ=Ö `†{gJ~犈ƒÇÿ»4ÅxˆÏÎsùgfå¾÷s9JÎápmøîçFЉçã!y�­{”?»ô­Á'ŽÝ´ð: ±�çSc Bæë–E³êö¯“"å’o]-,µScš©”Õ^+Æ \XÚ�Ž>Lu´lF‰qZÜ ¾XJóÿâ6닦}Ø�q�ŸÊ䘘XŒ ‹T8ˆO/Ve-'^®Ó›�«�¬�Äáxk++‡Îî_÷©Õõj*BîÏy\ZÎÕ“�Y2ÏÕ¦¼]ðÑTع³j�Ôï_¾ÄÇ�ÙÜYíY"oÏëåwexVcrÆsØí¹ V+ Ëšçd©øm˰í{4'·ëá�yïžÞZeÈÜÀž!œ^,>œ…ë”gNrÆ6È©ëóø jêzežÜ÷åä¾.®ÝrªçsÎì§%Ú’ßû4y—B' Plú˜W]Þ]s¹$Vÿ‡Ÿ�¦'‹ÆxµÞ“@­ÔË>zï*ÔÚµÃìÕ Npï= 5³ÔûqÝÏ£=oOô¬¨!T9‡g¿úuXŠ$Åç_^�/XçÁ–Ú¤> ™§'�–å¸ì h6q˜kv9½s—ýö–~„j2ÚIÀŸg£@cV„¸@~�t�øhk·cqØxg-æÝ¾[ÿp–oCÏtz¯~xVßzÁ÷âNìàC°>‰[Îr~ûК˜Î«þo-;ÕÇvßlÃÅ{9á0Ku¾x÷JxõŽfœ�[þÍ¿óªßu"…¥«&NÏ=‹¡£šÁS›³ùýýƒ²‹ køœ³õûâÚ®™ ®ÍH8^´÷|æäÚ 7MÀ¸žº�#ßvùÔ€±ÆqQâáæØyÉ<\N0”Ü 28¹ðrô¿ iÊœuMÄÇdº§rÄ=ÆœH(Ÿw��æâ\v ê œ^o�߯G¦ ½‘³9àãkLû¡„ŸÍW]¨+žéjü�›]O|uMB�Xëc§h�"9û«è݈ðSàM”ýÄ6˜S´E&xûr*#âñ¹|'6‘øe£kuO}—ã¢e¶Å¼gà Â%kÜ8_[Gò= å~f¶â6+úš –0çi]¿æq>ìB¡«¯ÅÎ Á±Z+Îr|fiÛ®è<@R]%ž_žõ+¾ó››'צ0«ãnÈ™Pç+=ÿXø¿‘$N,z´‹“¹�sq9ÛËe4FG0©ÄõÆ'i\ì`'úöúɳ¶ÖÜ}|ylÓÎfQ«ÉŽ–=;ü•kU®çÄ«1‰q¸á¡×5Ü�{*v:=SXª³·82C´]\b9C>-ÿhñ'´Áà2a÷ÒàÊ2àö3wë“íû TšÏBµÎ3—ùVŽêÌ,¬ÊT¾?¶˜YjüÞ³SSF4¡#E¸Žûh!Ááà^Ù„|ªÝJ¡ î ÎmÆÁë™pÆe@û)³Ô–ÏDàêÕœÕ[ìÐ|f=,E¼2+8B5Òä… ˆ–óbñ%°oÚà᧺ÞÚù Xšõˆ¶â 2M›ËyÊM_ÕdT.Ô³²‡®çLçÙÁñRbrƒn;>œÙ‰[¨Ø9áŒ/2éG¡§~ü�ÃøœoïÍkopÿo Îð5Ûþ4ô“N=z¼¼<«;��Gð#™{•×HW�sf×aKò“Ÿ¼Å·Ç{ë<(CÆ9"Íf]Ðí§':.£Mж{0ë›_+Çç]ìk1×4ˆËž[Ð�McÓ˜2vRýà2»èNýÄ̤äÛ�SNî·&èp§>ç­«-u‡K~>S‡�Þ`ÙŽEΓWØå}g?<™9Ïv¸áÝ죊+säD§Z:Wá�/Vž…zµÁ èæÆ~z(JÛÑàŸ<9ÙN''¯h gdg^áõòË6t˜äM9ã�MœyPwX¹ÊaLdX—Ñ¿o7­À“$f\ZÝd1O_ÛgKÁi°‚Úç«£,Ž•˜œš®s.–=»×ÿÄ¡M08?FÓg´äœ¹<5ëŽ4N ‡ý§—)_Ÿ/ܸ–VØèØcë¾\œsÊÇÙáœ2|ï=tûô(ßž…· ÔYôtu£'8ö·%ãJî·Aêž¿†F #ÜmüêÞ”¬6m>ë˜ãiB>ìKí8>»‹Ç‰¹Ÿà HWó¨oˆgÓ‘ó[¢å‘¤%¸éÁ|ÚÀX£v8°÷5ŒKNò›k²ä¡È ÆÇo·)¾qÚÁ…š,ó¶ÞqÊŸTï™Cù�´øÓ»ù–DýÔ5%nÇ¿ÏÌjä^ÐË8¶­×¶¬çÞËÔàLÿ^Jó=Àƒp-˜/åUI߆hÎO4ø"Ÿû8=âvó�H.Ú¯8çÑŒÞ?µðAë ÁFñËfXç##‹Ån<štKÊØ÷'áyo¹gE‰9чހ¿\ïÙþê˜ ×y`ˆùEõpùÌQëÜ8Ùo ŠšVdÔó’ã蔃Æ<†‘�Å�Ÿï ÿkÁ;n£éWÆz^Î0œWÿÎ>sQkIÝáÚâENûµæ:µ‚ÿ3ªîÌ=yáS€wôXSv# tŸ�.åZB7‹Ý—·Ž�Jož…y£ºùÙs>%›u‰"az9ŒtF#ç¬?!Gj@Žó'¼§Nù܃ìSCs·´–Ní9‡ßì¨ÞÇi½`ˆé•Mâ,7k;4rëÃ?�'�Dó_½æƒáŠuSJ«ÈáäámƒÞÌ•?Å©;ü@YÎAÇlí®EHAÇj½6ç–ÇÍ‹ºŸ^í+ÌœIˆ>ÔsnmY[|®Òh¾å\›û ¿mÐ5تe8Ì/?}Ø>ó¶ÓùèuŸMôùðÇy|òo†ë5sCW^È8߈0Ou”ß:­ÖåØîáŠOc:I#a'–—rqmÁïhšS®ýd˜\üÃ-÷oN7)ýö9UÊÎËM!¸”Ó´=`fŸùl€˜„«ñ> ø€zzGj ¬¸�ô˜Wîqe�_\öž´¥çú̃=þ;Ïï7xAsïÛrê—hzö¬íjüÔM•õŒöqù™2uY?væµ½ rq™`ÓWž§é¥ªù™•¿‰-¬Ë0;(¸èe›3ù첌 ½,ftÀæÆë~ÊËyk\ÞOîÓ‡©HÜ{L”Øúb÷jJOráÈ)fq\¯!Ô4½©�p¡Y¾&)WܽŠã"WïúÝÄöúMÞ½x5Aû‹ƒ(Ìç|ìø½µ6}Å—þȯ#nc–¸Ø[5>rúrzæuî\*~Ïcn¼:ù �‘1^ð_ìË5¶}­}cÖÙ0÷àᦢµ·o´X�ûX$¯íàgVI“�»èՉϳåö®ã¹pú_r÷ôQñÎ/qVjÿZÁÂG¤ØÒR~5‰zÉGŽgeø//3+�öÍ«ðÌÏþÕ¶9äT÷mÆ/®ˆ5R9_¾ä”£:6CÒ†uz9ØVÓ˜ö†ÏóƹÌö¼Ø¸ŽÙWľU�?  “›kæð¶&ùzý.k“ó3£gîQm°§‚œ³Zè'hÚY!J>|s¿>c¹TßQ)ŸmüÓþÚ‡ŒúÞL1Ñ œßºœ…K_p“Xæã~šG|ý¸”üœõk}ÿsDt'iB0½Üa{Äì´<3�·ƒ]†^übn]ãÂ?¶ƒÅK B-þ¢D®/Ö€SŽ¿ñ 7Ãø¿ùMe`Û$�„^×q2= 0×>±—ϰaÛ“õÉN,A´D¿Óº0wM©ÿ½­¯æ-w$Ž÷@}ýïB¬“ãSÿÔ¯}/…#³™fÏóÉn„`YîÓÖsÙâÇ»YÉ‘˜jÄÏ;zõF]˜yY ­�_}»wÎ3âö`68[×X¸?Ú2™a¶»3…ÆŸúö>¾œ)\¸ðR›÷äuo_ ݸu Bm×Wˆ d ñG{x¨çW�ØÓIˆuúPÍ­iª¬£�8ùã~™£ˆÎjt’.� ˆ){µÝ�îd$äi­7�¯ÞSÿ’QϹººöÁ˜"uÑ­·Wħ�Ólj�Im©¤lðãˆ�ÁÕÇË 9YØz[ÿ¿97,üíéÔ‡ªµLË™Ëþ‡wM=kqí ìú¤—¤c¤ok©ŸŸã\ªµ<Óiƒ·$l³ÍéV걃ño.�s‹$0ú“O‰ ©}FºÞðçu³|‡œ×‹K¢YgÛøE4Û¹òý, ï=ŠÝ¤£#çÍàƒ)_b$ðLs­–S¯d¢2öpË8�¼#SÙr_=|óA]�«…C’¬ [¯ƒö9oE%(À­W´y–É>;õ‰ëÓt->³†¿|øÖË|u¯‰iÑ>ÎÙÉ33-©Fdžë.ýÁ¦¿ñÜ<2W7‰›-3 ‡A&—öõP×}ŒðÈð•h?¾Ì£¯ý›{kg²0É*4À‘÷•bÆl¶Ñüæ‘yû Ÿ4ß*(±”!ý8†sžÅD—ý=O¢�fŸ'üógwW(h½awÞÞð6Ãè„ûó®à£SöI?†s¦?³€�øzÝ=—ï�¿÷kÎrêxž«7Ų†åP[#�†ÀÒÉåËÐÁã#�ý˵p(<>=÷ìÍI½C'Êü» !ø"ç»^K0ý|Ñvýå[¸Æï½¸ø`ý@Å"×ùs´uñžS£uœKï>ðÑrH¾sx0”:Å$h¿—²¶Ð¢RÓ›gœÊ{>`0©åôRf44w­Äeÿ‰É(²ÆÀæçƒÖÖæiiÓï?2„›àù„6Âhö²ëž©ï©=5@¸^a†ܪýºò¼¸8xë8n?Ç(>éyþAr1É/ÇvC”áXà¶�QS{žÌäêðbBV#B|òÖ|Ö—€�¨ØåŸš®—üż§t¸]¢ŸCà×›™—k,^ÊNY„ ûê­' «F“ø¾­ßKTjØE¾Úã2wcÚ¾K´ÓKnr"ð7½°çY�¸ñ±ãqoæL™ ¢‹J§†J$#>'“¯_+C²8Îp±Á÷é§<ÑÜ¿®¥ø„Ò ô�N,–k~묈ó^&÷NNxF“ã|ó*Qæz°·yU15§þÕ‘þWúàŸT‚Ïúà,ïðSðÎ ßüÛ‡g?>úg­¨Ï»ï{RùsEÇò<Ä—’b£µ¿³zÒÒŸ¸Oœ¿u¨'Ÿ{înȈ–?ŒàÃŽërJÞ¡.ßÅësof§¨ß#ß:{ �ÃSfF&È%"j³QC¯sóà4/þ§–0¸ÿkíV)å,~ÃIöÕ&8ïo�RŒCÞ»~sÈc]xúz]âc¡…—OãA£l^ø?u›g=/?~^"3ç¸È·?\:~gÖO„šÖÕ\�ÂC«r¢3òÜàÇg—.>ùê™O�âɇh˜ìN†ÆÉØ<¬•T3¯eMl‡1­ó‹ƒ“jÓä¼£9|;º~àà}})–³RÓüœò&Gj)ß¹§ÕClЬä瞬fºK}ƒ~.äºg„Ã�Õr©Üÿ·Î;'�OZ©É;ºY‡¯úÍ#G�g·æÃCþÉ99Oìàzÿ=‡Øä£¿lÖ{xdHû™‡[Á!ϸIIÚ Øñû›\ÖÀÚŸÍ·Rp‹û}Õa\ÔjÖqêg¾|Á»¹ÞÝl\¼^½p¹'ߘW~-7”¼\¥UIè²ê‘ü´Ãu¼I&úX<«œÌ~´r>TÆ ‘8­;$F,bnù7üù©¾ ¸nÝ[õEËÅäÖ´Cîs6 7wÐñdoüOP~Ÿ�ÙÄöÝÃËU?óàͼñyª:ïßp1ó¨ÏtÁÉò»Ç†äàý_š››»ÓgQ¸ Yö«ßjý\ä'¢óæE¨useÂu¼ò|e­ÞÓ—]·¾{8µÐª˜²‘2Îû�.øÔHò)N´NHyAÌôs]€¬Ù ç¼g˜�òqF†¬¯Äð‡æôöroÏ‚Ûnõj-\©-« 6j¨©)&�3qk-;þõâš¹TxÂIFrà`þéÙ,ºä¹!’¬¿µÈßœ‚ £ IDAT[ËáÕÕ©Uú–%3î£ ¶ä�³¼íº<ãQ›g‹ÙLg1:‚Â}C`‚£¾cò°n¤g'™áˆ­«–•dbR^ÎéIÑ^*™çôO¿Å�y6èž9Ôi¾Aì”KOp¹mŽã³?9p¯~¦2h(\z¬Ê[¥Ög¾yw¥“ûqµa6ìEy‹½ú‰^NÊge–mG�;'¿Õ¼§ž6]¼‡È~b¬åŸÃvú¯>³îóÖ:¸G(Ø>~Öï c˜0èZÊVâæGÀƒ{±Ö¤˜ã.]µn–@f&CÎßeôRˆË†³”æMÆÍ¥~~ï¥ðw¨mäynVn¢/Mê(¡DÔèÁ·x‰9%žK5=¸Æ$ÇO&�k)ì4õŒ)Ž/"Œ?}ã`‘ÈÚÞ¼÷^.þ¹'?øaR7|ôèa-åm£=Eoµ�Sé«ÇÞÆ…Öp§}µeíùeø^½w�ë¥5ßpæt"€‚tþ<7s+î|�׺à¿>Ü,â1¶×G.µ{ÏÀ-g:S�¼’†‰Äã*«s—?ØÙžrÉgÍè+üÆJé { ËzÙç´,xô:ÿ¬§¼þGŠŽ–r'Nê)Q3�Ó�ÏÎU1wæ‹ Wá�^JL ü¼.+¦ª7 Ñ‚¶ý=� Ó1SÒz5eS.ŸÇók¦Ñ­›^–Y­å{qÎåBžÞSGlÎoï‘­”ËðÔèk\Ã�Ɖ7×”¡qŸo­“gò§¿êÈ_î¡).ßïÙ]XAvÖ+BÇèÊ?ªíy¼ Æñ ¨Æ•dÓž ¾'îß@œ8ÅnÃs&{Ío·W@YŠ,ÇÊߎ WÑöáq5’§Köòˆå-õÁ¸–óRtX©ðã?9â�M êQ·ÕO]> PšO­|`c}—5¸‡ÃX]:�O æ§i —ç•8&Xëo‚ó/³ùœBÑ7žÔsÏåË~™CŸ©Ë±:øf{ʳ&ù—‡´w9ç§Áô^°äÂ; óGΟþ™ÅÍH¾gÿô…_HÇ Œí8º^žÔó|Ú“mxν±ðrÿ4žÂÏ|RÍ �>ÑÍÎ"Ëò@“ðâ?åfÒã²3c)&X€íOnïgg�lª7¡Bro¦ Vúˆ°xŒ“²3ïìî£Å]*½r]xiÅý>$:¦šÓ'!IûÍlNóƒNÒ4]ùš!‡9’>éÇ�<,ò_)�’Îõ•z&…é cçüö2��¤Iã;?\Á˪þhã¹S¶ œH²gv9É!MXቾž�’Ü,èá ?¾h1¢µ±y�žÔÌÉg;È>B9|gm¿°«™ú�.ÇL&òÞG*"ÂëÁ*î|ù3‰èæóÉ©a’pºþ‰ÃsÉŽ~>÷yD–eE[±÷y†ºy�&;Û/Y¬Ì\×'’hù}€A0 Î3Û4ÎÈs‘ù$|ž©ž ;æ�%u –:Yáu]@¼l!Æ‚_€œÆ´ùÞ¼áö…œÌ×sˆèR½œ—ÏŽÂ(lÕðçˆò¦wê7×Âó“¥õt>œò Ù/¼'¾væÔŽt¸©qøe¸�jÀˆŽô©tÓ«LŸKRûs Òù)êg¡y¶É{‘eNå¦e*]Žn|å_®�¾Ü óEIäåoûø Çx¬Ù³âÞZÈÒïþjd¿¾Œÿ<»ê™­¢ê{¹ÖѰ >ö§#7¬Ë‰ã �õ¹ëk{¼½’»|ïªÐoZ!ŸËppœgBßÔrYyÐýA;¢‚o/ëϼç"¤yë�íYuß½çˆx³0¯ñ«­gD¢³yÃý³ÞÁÞÙþi…¶dìÑ¡ ËùäjŸ¢ÇÓ’ÿw�!6^ÊÄ©J}€–:îOyh!f'§Þz Ý/´ÞZ`–ç:"šôÑä Nÿ\¢ ]Nª]Á`¦nÜÖPÎÔ î]h¹:j㑟\<ìY:×ó]a„ÿúqÁ\ûÑ$ªÏ2?@–vÏå­Bþ¶ñᛃŒõe.M<ùr­ôzÉþmæÌÕs\ÒjrÏYÝ:æüä�p¡œ¡"�y²æ;%ôšûüÆ,.‹áG?§åÀ1“›@™çý¼éDD�ô�E¯…�Mk{í‹K=ܶ~;€³ô¬Xà¸O Æ†Î>‚ÚΛ±åëì›ÀÎ[Ï ©Ë�oöë�ÌQh^¬âð-ÕnÛ1Ÿ‘ÜÀó/Q®£ zÊ4/t9Íóã8t�æåÁÚãõ’•[y®ÑBéùáxx—]™ƒœc÷ MfçÎ�·þ¶�Û9:€ÀP¾è­vé½ñ %~­.½hæÌ�”¤57º|ŸQ jZ÷l3� ?c‚ãˆr«/‹Ñ“«óà5â�n3+W»AýëYÓŠÖK>òÂ�†p¹lk[Ïu8ñGˆó(ï^S�”ðõÙuä�Zs»tcˆÌ<ãpç6Ú½zNòO÷pÞ«¿ Ÿ†¥¶g™K2d¿sͤu£•ïy~uv´cë-™óŠOÎè·ÅƧ«s½{®ÁëêÜ\(ˆÉ%ƒKÖôzwpဠÏ)Ú“OmøÊ9>GŽïƒ>X0üÂtrÀSH¯ørÀÎ BH_ޑֿ”Ó¿¯%èØ=?Ïeÿµ”’Ú ®»y/eèuÆMeúÁ®þÁä›U¯.ªP¯iÎß�ÉÕÂç+Ï¥úƒQÜ5‚#”„øó›…T¢Ó¨Ý:BC_8òñÀì½X9F圬ñSƒ;@žâhµ ÷]ûžäƒÖ[…m.ɘ†`Ú°{NÿÁËø ˜^\Á:ªVŽ|Ü�óÕžjÓÞø|…€þŠL{2½/h£|«xk@‘ßPþfah™�)Ÿüà°�þØî¡þÌ@Q}£nlË�ÓšM†Í*ÎGìœÉ9ð~É{zktpåáYÎ÷@zz=ú(-Pé|¢6ùÃÔùl|ÎÈ1uN5ûáâÈêñ×ôã'“ sØù¯Zdƒ*¦Vêæ°ÉDgƒáÏï3¾Ö"nS>þñã?ì—‡<Š|VžÙwv«EôaਅÆ÷eç¹—>•šûýÔ ’þ°wï“ÍÕÝöœ[<€é�ãè}¹ áY\å{Ü«ÿ' Ì);òz÷Ù”, ³Ûü¨g~8Í/O÷pî™Ä¹{�uSúךÌÅr_lîÅú—6†QM;¢>îÝž¿¨?¡cÝ©Æç¯àZý¡,"›Óé^¹Ì±üäöHÝ·ÖqîZ)hÎ_€ÏÛžp}®hß—ÃOhío>K¿s(Â9±}ÿ©ÕÐo_hb6g=&îà•,c÷‘zøW?˜ÃpŒ}sÇ4›ÜCÏngô~³§ý§ë�–Ds½¾&5è[ŠíÎ�/Ãýº#N÷¸Ù´Y÷¾¤É¿¶R�çm€<ß=kÑ?eÏ\qߌÀÛ¶ÌÌ=šÛ$Ìm„«G^?>êºZ¨1—ÍÂ|^m8ó\”ü'§<àNŸ&UÌžô–×úˆöË1,:܃Æ¿œé€ß´F^ÏO pã�Íõï²¹½S_oÎóxÅßU ­fÂl€@ìOe®ãu( ‡‹)�×_›Ù¡úýçÃÈi«Ë.€É=µËΰN=gT»uy†¦�úS'µÜŠó‡¨G™ËAœk;üžj9J„Ïð½VöÅ�H´™S—LÕLñü¡…'éwÉõzí�NrÍ‘{ë˜æˆj�OÍêYyÿÙ󩌺­×Æ {:ð óù�ëDáÜJ�†r¤¸_u®Êv€á" �–¹à�ƒ8glÖ‹w">¥4vpOÎ`‡WØèê†aêðo�qE›íjr.]Ãs¤ؽðý®á?== ÕÊoˆ¾2Ç;s<�T¾ŽÞµ3O"ã?6smoèw�u° ooë9óPçþ¼Z<[g•ZpðmF„ù›’{ð—‘÷Xï[Ç:ä?)²]}z›=ºƒoC™•²Uj�¶s[ÒqrYŽÜObq:¶yì–4ów>>‚‹ÙÐA>Üä�ÃĽœ\Ÿ›\ü\`Œ“#ýŠÑÔa·®FðÑæìKmÚà›ÏŸv^¹ö½8HóYX~ ô@Ž?�é,\xÁ5;99Ë�¿}yÆá—³…o}êL×ì&‹&sëaó‚/kŸ#AM«#r@}þ@Á4¹ßÍ$#¯3#οk>L’]¦µ³?¹Žá™‘1úË”ûwgj¸�«0ÊÜ¿›9®;Ã÷§ —=|fpOV…"Ó_ný¸Y�JòÖb§Orw’7­WÓíÙùÅ�r*©ÉÚ3€.ßè\» :GÙ§PžEuyðLÛ­fõH›<¡J'‰¿xì÷ âñÉ´Þ‰q¿¯B–|ó&ŸªÌ-ð¤jùvèÌ2Ö}ådêÆ ð%34B$®529÷Ì:î³åVª¸¦bÑ4}8Ⱥ+süq.,7z]Ï�ˆ@Ï�vsÁ*pøê¦^fE.¯õ Ü'GaêýÑh’d[4ÏrŽÎ» U€±±‡ûåÿÑÁ(Í›ˆ¡YÏó›�À£Ç2¯p2]¯§°ë•Økçç€ÇZñoÁ7!E×R‰ OE_}>Ó]ø¤Ý¡üÔ;ÐùË×$†ô ¶ú´ù Bƒ~vêˆÂ¿(´×xPóTMž±—‡yŒ/™oÆGµÃë�f›šŸzâ–ÏœÔj‚·8í¸NâlÙtUûtºoôƒ]ͼùððEý©ÃY…/,k|ò™Í4ÿI©>i¬Ž[¹ç*_&Ï �?Íßz®ƒ(­×ï9©ÎæŠÛËñ+o6ó7ÔêwõCE$iUÃŽqæJ–u>»#O»Ô ¾1à[Ýq“¯7Þ]×¥ï|Öµfƒ[çšš“…ÊS#µÍO¢Ž¶Áÿ¬iHjP«{ ÖzNæãD‹aqh´áÞ .Gãø¬„w·è¹h5Åç\ŽÓªýAX·Ì£_pó <|Î�™›ÍɃ®EóßÌõ{ç¾¼j/Ç%SKÖ”YÁí˜ëéò‹o˜�åî¡¶×èV"Œ¦¡kï,‰]‚7÷Ö÷íës€lk¯{zò›Íñ?92ó›‚["ëUò¸2�G]ÜŸO/V¡ËC—Ÿb¦Ž™a/ª ã¯[Ü·?‚zJ.¥aßýXÜ<ó'ûJXöÙ5†}ˆ[3÷*õòq¼z¹hŒ˜Pr�8v1oè ÙÔŽ[w¢ë¸€êY£1ë�‡ë[wúòW1¹3¼iæBp‰ïè´‡‹Èx“{ë° ü­Ú  ¿÷]¼¥^îW|ÉÎ� êù](bâZïùMò´%f®Å—_âs3éÕ#ÌŰp‘×,í„£gúƒ3u‹ ÃñMîÃgðñ ÷ƽŸŸzq¥!ö–•Y‘›œò˜+ˆ\›;Š7dñ)¶ðÛGt…Ý«5 ÏØ‡h˜?lÓIbµýè~8fsU8‰Ä*£­„‹úäÜŸV|_Ê“ŸZ/ÿåsÏ ­þ÷7ZËáÞ„%Ú8¤PòüGíñÒ :ý*Õzb¿ü²Yi9¾Ô¾øÎ–±ÐÔ"³ë- ׫Û!c›#;Üáµ¾Ò|8ñÉñÈÄ1dw>¾1A-6ßüìß5äëEóí™H?:^pŤ?ˆ¹´ Çæ »K±Oo ÙçØ°�äc5™¹§÷ãTgó9÷ YDµÀ ³úòŒ¹ôüj3£ˆ`L>æšËFN£±t$—ò‚Tâ;Cô¥lr¨Aܹ2ÇRél¿@äa/~û—¸/UcjSŸü²z[=\7ü§­œÞÑ–ÿ�³U¬åÕ„Æ7Ÿ˜ëÈ�¤ñ@í3×êfÿh2†^ÅíÞÐ|„2“ûŒƒq¦«éßß1?"p�šÓxü@¦KÐ[›©¹§ÓË-½×Oîî—±éÑUrë ý½–÷Ô=€§Ýš&ÔÍežÙOíèÍ:÷Dz`pwV\Ugv¯Ë¹\´®ªk™Néçó}Þê/þP-Ô+é¾äTf�•TúÂ:s. LR›¥C|Ù�ºÃÏ15I^0;3s¾®Óç›þ…é´þ‚â>OÐÑî~ø¬K¸“mœê­Îò77°Äæ7IÓ×±Ñ^ý %=¦'�&¿×öœ_ñ&�û°A[?t‰Mã¡+æs~ëCs‚2¦g5×ÿÃuräsLÁñþ/Àöл .`ñþ�žâ ê,nÈ+7|ް8ç÷MÐÙZ¨Å ˆ^o¯ß€bÞ†íwþ èÄ$ò°æ|n< �Ûä¨W>©ãÉZîÎn ëÚ•;Øå�>Š£þëƒ7¿ ¦~Þçßt€À#Fqcùj�.«—Ÿëì>lpiüx•²¹F§ÏÆe3s$žš²vöÎi‹‰ãð“¼Å¬yoÿ°ÇVfý/üÌ™0¹Zñ]›óy­Ž…pÏ?l7Bå9 ½Öu~sª�üôž�åH~ç"÷—^ÔÞý}„º_Ršœ«³ëU\ÒT2œ>º†@@Bn}Ñi§ÏÞÚž½A©Í@S»Eæ–ÿô,Ûu(…íUmço¢û|GÚpww=‰òlœÀEHAì#§ð÷�Äh•ö ßz\ÇB“…Ÿ°Á„‡š·/jÀ'°ÓêZîÙ•{-ûZ€‡õÝù�vúïC5^”¶Ý¯x6^z°n÷rµ�GÛ™iiÎ\e¹ì èí9½ Ò¾IÏ<Í.¬#¾b;·ºSWqÎöUãòþc½Áï½¼YaŸV8xeÃl_t4FÏj±¯�¡}c}¸óÛs¹<ÂÜk´°ÇöYöúÏ> =¨Ö¾É+pæ™^¡I_2\&µÆ�/žh¡GðéõÖ7§�A¿\)@°/mwZÜ™J™ —-0Ôª‹çòe¸ÆÅg.¡ƒ3¼Æ?% Ç4žô„ f84F§"ý}{ô] ë#<‘=Œˆ2�>o–cë>S®ÃÙÞt€ë4èì>發3lîj7_1æ³ÇɺtYT¹årM%’kû�­æ—×@£^¿’!øðPjs2W¹Wg}ò€XÖÑ q?=ÿêäLþ–ǽCwØ}ß�¨ûŠNRœ[ÌËc»çŒ÷©óÔ8Þê@Ãú6l¢ù2“ö. ¿Òsñ‘#—Ji¡>¤„Ÿ\Ì ÑÖ‰|0pµ¨yŠÂ~o€Å¶®o´š:Zî[3dà>5[c1ê3Ö쎸òë÷ж¥Ã8xƒçB�n((vºƒ'÷”øc+ïá°­KsÜ ç\ •´Ë¥¿Â�³<ø§Ó ϬìÏ¡•£të#ùù¤mŽjΩÎQ>é=5Ë»$6g÷Ÿ-s×ê\#sª>§É>ã?xEðð…€ <2;ž¸‡Qü½Üÿ,üKˆo׿þDÞŸ„YæG‹œÔJÏÌŽSŒÜä'Gös{æi@ïM¹–fiÈöì‹q=÷ò}>í«·ÙÑ+p{÷s‘"çz$Cá£ñ2ŸÇ÷äÜ9æ799oîéé ¥t9’H:u<€ÌçíÇöÑu{½Ïmflsˆw;%\ny­Ýøzȳ.§Þí[œÏeG.óO€ge }Ñ{}76K±éØçG¨•»¬p ÏžHjf.”çžN÷{®#Òžœ¿¼x8õÖ%^\uO½ø|–�õrÛ¶;±qn÷J/ƯŒ¸fæVsêóRNð˜OD'��ÈLMrQŽrÑJ¦±Â³›Vla jÞ;ß×ïBVŽ/�áX~t€ßs’ FÈ\|uÇœ=LwVÏ6´Š“FïÚ¢ˆgñbm'áOÌÍ¢�.mþj)ïæk.|ñû.É ~ÝÉaó©ixr\©rå^ä§l“§ï»kŸ’úF`rÉñ·_Õ;u¸3©Ÿæø<>ê§Í|îpK\š»X[\ °rê~ÎJä]üzw{ÖÅÏc„‹Lß�l6Ólzîž^Èbþóûìºë]ÉÕõVؘ­Ÿc¬�d4ÝWÚà $'lRü2Ö鸭Ç�oÏ|,*0™»OÛø{MWÑò‰YÌÿ ™N²vý›ºGÑ„Â'�üðà ¨M¯”â�óöI€Ãÿ@©Í Ô)š½Êg[É÷ß ¨à~uqÿK4†�ø‚*üÞ¯ý� éÀMo²Ý¯š\/{föu³Ë³'v¿ƒíü)ˆ�½ÄŽaó>Ò†ƒ ”�{"¦õBãh¾“\ |ÊK<s:5Ñ›|«e "ÿÞ4ç\âÎ+·¶œÃ�7 ¦)ù] Ih(÷‰ËG¯w°E“SÀû-ÑlHrœ_¶Õhy¬3¿cÿ­ß½†kÚ B‹kÔ1ÿ#‡—õ÷áó!ü?ÒZ�ÔÌfÜ¡ë|ö5Xƒ«!ÁÎwíÃäñû”~ î|s=n_ý °žÝ+¼K�mœœ]Yͬ6~ô8íO“éc%w¿Â%o’Î^óyøQ4?H??€… �éãÕ†Ï ž­Úþ©øàZ«g�瀟×Ëæ_çrÊ3ÔúvuDq–}Êõ7›’¢‚ Á ’‰Ñn±û“jÅv[ƒóîfpþmÀ ÂÿˆuÞ?|¦þ´ž:`ñ[«Mk6ß¿¸“P°6(L<ö„2¤ÂZ‡¨<´ê®üÓ·ùP\tÕûÓGGÖä^ésЬåLŸ¥@¯GÑ|ªýò“3Ößîø­Y¬‡·Úü�ë<4ËgÎèøÊļƹ™Aá9ÚPÜùå_]œ�³½¹Ô²_ä0x}ÿp#ìº$�•¿f˜úä¡m2èçpž+¼Gã$(·‰ÖH.üz49©<¬ «ßöŠ[{ÚÀ›K¬áTˆÛ?¦z•ü\“�W>òÏ2EΛ ûì!G¹=”7ÏôfÑžyœZ6ÒæÏ ó¥'½¹�âc÷R´5á:÷„΀YÃwàòbôožÁKÚÉë‘s8e€�wÜ`–g3‡ýâH˜ufŃOì^±ÒFA®ØY‡ IDATÚ°Nï®['~ðGLž9k­>jyTôn&Á�kycšü{6Ëhé™[ó­­õà|ó-ÍœDXåXÍÇ7ó��Ñh-á–×¾Kr¬cˆÍöÓ7®’ï™�ßs�R¶{ÑÞd[³3'—[h\0ì¯T:±ØÕ$gXÏÐý¤²>}?ýí\m•e brnöt�<Ч»»“‡/[>,2>]�Öº_M€Ð}}(ëàN-“ÄoŸ+Ù–ûjœX_hH�ÝïÂ�'[+Ty.оSà (î>�Y¡ý�(ÎiŽ«3þÝ+�¼:’W?bœ!ŠÍiß$Ïlý˜{õåýØ­ˆÔfpï¹Q®yåƒæ¬|/ð¡…´ƒð•˜üë•Ó»2e{zj}t'Ü:bÕ9º“oðGYKé,Î;ß!œçË>¬çub$üÌíù4P>mÓt ŒÌ}½μ6Õ쌒*¿ysŸrŸ±Þ–ŽŽe„‹¾¸O«u'u’ª|=°¿¯ÕaOöf•žÅ“Rª�Ȥ§^úÄÉÛBµ³r/Ÿ¼Ð­¼1›¾3SüÑ!ýõð¡nËŒÀêÐfú©dj]ŸìÛ%ùýf°±‰à_/Ô:%–ȉötš¶SÏæ÷âaTT#Ì2¹q"3_y­vxƒùb§¥ löà£÷*ò¸ Q=sP·+zrƒS Z! +IÔá-¾¸­‡pKú\Žh%$‡0œó‚S~³aÅ�$9An¤ov5ír…’†GÙÖ:%­¿:�5ÉgneÚ6mmß3ZÌÈÅѦ�ߪ…Æmžû“¤…I÷ZÞ«K�iX Ï¡XtYÛrCäë©«˜9Êû±á:™>æO|nŽªë=?h¯åd UA€÷�R™OXYûo“ßæ|ó+ªùœÖ öšïîÇb0«Ñü¿²Œ+Ÿ¹& nðã÷ñ –ÿÄ ½äŠSïÔ„ ½Xèô£ ?\Ï:'ô7Fî©5M˜ÒpÌÃ7~kÑo:Ü,ô˜’Kµ»þ£ý_üäO' Æ<Úfž:p·–53 ý)2 mø2Nûu7<Ã`ãg¹?¾˜ ?œ�¿®EX+ÙC¹¦‚ìó…±÷k )ìÓÌõéÜ33±ÈÞb6~IÁøcÍàòÞóÕµüä$ç8¦Ü÷í¹cïótúk]êW×§ï=(Û]–Š2¶0OD²õ÷èÈ(gA}ÏB(¨áœ¶:’ß"æ9õÈH/Ö‚�/s¾ÜÐ,}ZHxï™Ñ¾‡Ê¦ ÞÃßzrðE¸_ˆœ1沄s¾ãßÕø‰¹N[ÿ·ÿ–úïã¤|¼~kRé�ntZWtBtþŠ­¸Þ ì®P8ÜvÀqê:_ú¤˜ßÿ�&çÊ ÛùG¯šâÍó5º`ëK:×àÑó˜Å>¾íŽA%˜}¦¥Ž#çâ™*¶ŸÀhʉŸ‚®—äôȧž1ég…öW�ò›5òÓvĵTo®çP=r¾³+þó ܹEÓšëÇû¸[󿥿f±šËî�‘’�p,CVÉ’ü¢žéËu^øˆÑçg•+ÞÆ ¿¸Yá`^²¸èµ?AÞÈ2'ÈEƒójÒÇãMÈŽV4ùÍœöïl{7¨ÿôÖÔÖßæF¡Ä•‹Ø_‚Ÿï`…‰‘�ÿ�]~)i\¨Ö¢fŸ•ÈiÙ}®ysÈB/À˜Z±©µ…°Ã_]¤ãe¶G7u*§µÀ…É{LÅ’zùóÉëX.Óúr.ãÎ*sJÕÜz¯ ×'{ærùŸr6ƒI•ÔŸ~eÁçøO ùÓ"qP»/ñ#…³÷ê…д¨lVü=ä§¡|X|öë›æ7j¦/]rœ¶Ü[9¹KÐ>³Fzyµ¾ÕƇï$Ö~Ïăe.p¾Ë³ØOü'€p™1ær–ÈŸsK¸ß¯ã�•УE©…;î›vpq}®–¢üOÒE|ÝàˆùbÝ÷9Pl4~ÀH¥íæ8mÏÓ¸ˆ%×;G–\ÿµÆêiZgëÀŸØ"Ûé‰Üó5ɩ՟ÔSÞy‚Š�ž/'ÏçîE£'dÔÈóË9>®þu8ÇãߌýùC•Çyýã¦lÀÁ梿ºÀ±N¡ô‹G.ë"¥‹óé·9Ó ô¡Á—ž–ITz«gÜàv�./uŸ¼�]…Í�FÞœw¢ûwEw_rÝUœ[©ßýà÷«ÜމÙï··ÕÝ  ¬9¨"�Ý!±ºÇ&ZÏ(Ìj-¸Ün‡zßC~B<î–pósœæ›žz©ßÞÊÞúª)eªÇÁ{±Æ{TYp‘ÇÕgóXB.Z&õÑtxw? 8Èý(†³^þ píÖÏŽ›Ë¬§ª©«ÚÔ‘'ù±lvïLQêzÄ�ò.רþi9uå7'p‚è¸úÞå_«½šN/®ã˜`¼�Ùz!¶Uýƒ¼½$ëÎa¯æËLÍf¬Ÿ‘:ña>"êûàZ¥0¾ý¥ÂòÒf3²Á¥×™o'ø?©¡Ê0dûû_vE ;¿Iâa¶³t‘åGgk …S“Î$ÿŸäD(ºtù—KÞÖòužç5~|œ ¢ƒýhµ�ßÚüåRíC�û� ¹ËŽó³sÚÍém´÷Üä@Þ–Œo·ÆÒ_üoù¬ÏLËõl˜Ö †f¬ßÞ\¢Q~ñ­‡£óøúAãÎ’–\çtŽÈñåT®ã™C²sÍ ’€½<÷óôm®ô¤£23A9í±ÆQeù`"U¯S�ãøÑ¶|{sœ wùTÖ«;DVùH¡*'Qúøf ŸÏø�(ÄzéÝš0×?¾§ŽmùîʽŒ^!F-ÏTžIœ©“Ìp†ìy99˜ï5ÏVÈ¡ÕgY÷έM=·6¿Lêן¬8´ƒ3·ûJÑ|C›×O�áápüíŸ2´Ýúmd÷¬¶çU§M.¦I Œ¦] äDN²ë#³zã¹G¾‡úà ž‰‘NpÄ¡+_wbù¦óc�Ó`{¸,-ޝ¦�\Û‡—#¬Ã ÛrDþ­wj @Ò«Ó$Õe Ó‘z«Ä”I£–뙦X�Rw¹&õÅ,äq:aÒ3­æ%|â©c]Îo2•Ñ»]²¨‹¦¸ˆïÞ Š3´ÆhgÝ:É·Æ„rõ¬fNç À&«üà‰RÏ…9h­¦ýèzz ¢|ç>  ò ŸÞ̘´Ïõæ¤÷HHΙ„2ÀýÎRñ¸Í8�—^ÁÑÛ)½'!ƒ…'@:ʺõ‰sãô¸ÅS×™ï>ž’…žåø.�‚èi.uá & g³g%%Þ8@ßÞ*Å0W<Ò"=fƒðòô`÷ã´:R³9òñͩݫ+5š¸†×Vx͘óæ@�c‹:=g¶³©xú ½É£7Áþ­çÌŒ¥©µ—E…˜ VÇ6žíÆ9¾{¾�Ùˆñ Î,‚öuZ� rø›jG°|“KÀ£…sîŸ#†™ù—“œC)Ûs¥­®Ü+]Æ8>`òî³ä¾Ü¤Lû¡4.^7ÀO¯¾¹�#ëÁêtòl§†¹��*— ïtÝ~ \fz||$yÁL¿=nÓyœ§bå:³Á­@¼y&³óðúolí}¶�£0ÿ°½~�~j=Ф€öŠ´ÿw%'|î7f4<9ë Ìpç›^-±’Æ®lË«�_æ0¢¨v\±y×_ž©}L…Ñ“«ÞûW¨ÉLöt¿5­Wau’mjŸo¬á`Çël=W�U„mPÕ?p† -îE¾ÙD¦õóÜË¿ål]Þøê»?•ÇrØÁ;Î�Úì[½A»ÄÎ"¨–ùÖës3¯?Dæ·Àgw-xôf­�1QÎ~3o’ƒu¿÷B H?ëÎ×?D ù¤¡7yRpf0àeYl‘«WzùÇ¢Ì:¨Ó{<ô5<É“%=¶áž¶õ¬À1¯òpùO¦!|^¯‡®WG@hiÆj¨½~§›Õ3f&.é�¸—ÇÉóÜp~÷ )nü©•+ù^ÊóýãPŽs–‹¹oú\i96h'X“èIÖ+¢JÖ&Os:߈àä £mšóÔ«ËÜîj ss¶ú…óÏ­¹qü]cQ<ÍñP{S©ñÁ³ÚÓîò°0£‡Ÿ\T˜Ðjá¯=|Óþøyø½Èׂ/�}3ã3Äu@±Z�f+íè§-y{HsÏÇóÉÿ™ÑEynÒ ×W‹ïÕ!º9vé¸>œ{æYÏL Þ\Ž4»œ5îsk�KjøÞ™"Ïu—ϬÇá$%º¼yONõù¹rïÔ†ULÚ­Õ˜Vš­�Z,ëj.®ß³};šÈs.x‚YéQŽòZ'¸d&²öa¬Wgö·–íÈuŒcW›/έ=ÎíŠ$¨+|¥½Ó–o ¤Ðù\D® Ý’a挧cqÜsè. gxžÁ½_¨æ)Î ~ÓRÇÑ'ÿˆr–ó6Á‡ªqùÁ {ÂpÈïù¼^€uA�Þ•à~9ý®û6€�³=<â(ÃÑ®'%x±¦+¡ú$ Ú½ìÈùû ÉW Ѹ‚IM«á»y�þ¬�¾7¬ûhŸDõ¤ñmWm›÷5d¾¾àrOƹ8{øs/±å 1D]|î žgöäyä6›)‚5ÁœÊO“Ù“®­éÍÇ‹GêúÔK0àå-3Ó.ß¾AºqþÖOOâ!aù¶WÍ‚Z&p�s–¼ü,:@ŸA8pL£|Bg^ nS¢+‚¢&Ï.:r澬új¢wÅÑ´{—œå¥× #\ôÀ)k<ô8íÙÓJŽÉí\¥†#¹ÄÜ'¬ŠM/¾¬í‹³��XxŒ=Pz…7ß,g°ÑI|™©/Ö;5AWß8JnJ¦æ0®ý�KúIOûr2GMüfÊo 9Ž®̃’›=~ú´Æ0FçØ!ÍëPºN&_t]Eš‘Þ@¸†¹ý¿÷Y~g½é}ø8CÃÕH€¹³k=yÑWÏŸԈ¦o"¼…˜î{_ÄB¡‘þpQcç@O>¤½õf›(aÂñ�Y®Ç½Ÿ$>Nø]cóȬv_ &}@ívŒ4sEÈÛGÎ\YÉ §òç BÍÕ54«³<ùc{c.1ÇöäûcÎä'óäR{/(½*ZrGàÊs÷Î~)ÞU6»©;®Å<–�N1©Hê'a´X¹¡pÏ�·5æB^À†)³Á·/¸W·k¶Nì`ÌÙ|ðc4·…df¼�„r°¹îz0'lf„Jž¬ó¹DÇÓ¡ ¨×éÜni¾ac#¯ãÁ�^¿æ¬.¹ÝgkaÁ»Û]‚\ñ¹ÞëJí\çÏý„×sÐîΗ ¸6ÛêÀÍ[§tr݃¹r9µ&|\Ã4aaŽÖ­þ¶ êE¿«?;¸Ž§zRÕùŠO£­KàÎfôY=ûoDýaÈåx–l÷‡µžˆ ôäE8½Xx5Y/˜' Nvû‡Õ ¿ëi÷§9Â’Ež^Ö<¼öpäX-pž3}taùäTÉq}÷¥¸v�*Ɔ42ó(‰Ú\íù!3èçòæ˜q.n<>R‡øü:ƒ±Wç3pÅ/v¯0ÞE2´ñ×ÕzDòû lñ»* �´œ³4¥“ü Êéß5o�oNKµÀ:Èѳz骬ntÊ«x‚s~™É9gs é=º`}—¹§‡å�À>gßy@Zf7]N.éë‹~ô&89‡,\­ýô‹’Ù8ºéáÌܰÌiÇŸg&÷/A4œ~Ûç|"9kÚqÄÞçx¬&»ñ '~ï ™¬Š:3ó�Û^ÿ½ÌóW=Ÿ~׫ҭ~¸œ gHò+|gåþÝ¥ëOjèžyd ñœgãñ»C%ÒßP„ߥIñ+÷{ó¹:¢‰XôcmÁ‡Ö÷,›ãVíé�Ž(AcüKЙYN¨©V{„ CRMž)Ú¦ÏÆLÒ³ƒ·ÐÕ ÞɽéŒÍ5÷æÃ¼âs/ÖZÇñ¯©´/�{Ÿ:¢âWý<'J¾ÿ)Jz¢É1GZNûCBø÷ùÖµ ¾˜ES8úéëÕùλl)èÜý¸ÿ)ÏÏé†뤌s–¬å°®v?rgžoW¤¡“¾NèÔ /á³h”‘°ùÂ{{F’Îsáá,71rMa·”“P §\ÏéWó.š û‡ƒc\fLƒ`¥ ¿Ó¨Cx@í3ë_ô'Íòý‡€²B“dëƒ  ëÛG%‡8¾³jGS¼æ•IèƒÅ£÷aÃõå3^Óãž¿$)RßBèÝ˹AµùÛOf8q4Mó°çYŒ•Ó>nTûwMæ¶ö÷E±±}:yž{û‡Ë°”-Ï(3X÷mŠ 5)\àŽ�õÍ’Ötµ¼Úa~—ϯˆeR« ‡Çç‚|£‚˜†¨OO/Þ`Jx‰íßÑ3gO�äùÜÞ&q{ê€Q ~�±Ñ½åØ>õëÏ<�Lk!½ÝG[4MWúl½äuGWlyuàì¥#þwù´{ÖÀ0Îã4¿ììÏÕÄäó3¦üsÏä÷¯ÄðÃ=¬Íê €_/#�7š 'º˜g áŸ0vî´¤ ÐÃkºíN^ÑÍÞ@œ2`­aì7Þ°qØÔ@—:�/N(+Ân­yµ£æ’ûA°’ÎæšN:N}ê’)ž¼Ò—õÁ¯—ó°YÞÚ¯ŽÊ²û\†;Žî ­~iÓÿEfY zõtq,K<äóÍý©;˜±d7>NçË·4ô|–ÈuÝ�ŽÖ%‘ð±sÜìÈ'~úbÆO‘è‡ÃïŠ%úbÆoNrÝÊWWÜÉŠÆ0Qß5l¡Çûªsf¢|îM—5;§v¹Î³ÞÌj|@Àn?²Êm=%qOú·áÀvuíÑÇLÂoœ5Ç’·Õ·<•üÍ÷_Q%ÿwÉ5ý·óøì·Ø›4]x\Üá]ÍñíÙé£7Uî—1€síд³Ô¤Ÿ½™{B› 2ý'Ç’j^{Iå @½½¨³Ü»?öeÎÌ{¨ÅÙÿû•¿lmîQùÔci÷½Ú9.‡ÞL®§ÖUié­¾ûMM4í™ 1ÏÏ]¤ü/>?]�¸¨„L†ÖvÌÚäšË€ïåV»þù(�¼ß|ô_¼-�í›ß;‰8"{‡äZ ß¶W4þfÁmdßpˆ–ù«‰£km¦‹[•ë{vr�Mž¡tÁ‰nKtŠÉä“ÂòâÎüǽ<4t¢1áþxR#¶C2][Éé+\S7ç`êsºðæLíSæ¼<¶äæ×ŸèÇÛ5à�¹}Ñùé°G[{4§ë›3×ê2_À£^mη·Ì0óÑ=ЋÞ<{Ÿî ù óŒ`@ xz6B¹·D‰ßÚ9§w³õ p„‡gÅ:¨§D÷àRr¬”Ðp®ÏÔË}‰¦pÏOլε‚N¾ˆ±ÏÌŸBÁ ÃÉ9çô—¥.È”/¯�¤¶ë)Àn­†È6v—w~²çî~Ï­%Ç|ÖàC8R£sZ~gAÒ·.€1-R�—Ø�P€ Þ÷ìðÇàF{Ž€qö,eçãDÙIWB{ •°ùãÈ7¡Þù4Á:Yž!ˆd­Np}¾1¿éŽ›Yß»ãy'aôÍ?3Œw—„t@3¹÷;§%ãÚHò˜ÝB.®Ì$šX¿³¼~Pá¼³Lþñ¯Pu ^×Ñ1ü-J@k5W+Xr¥XÐøû1˜Œúòl¤¯êï7Ú“Eü<+¶rLQËÃA�üG&ÔjŠ+¥·ô‘:±Ñ<ÝÊA±SŸª¼{K­{ÿ\ÙéæcbÎÇrRùÐ…‚Å‚·|u÷¯H®—¯ÖŽÕ�æ¹g¸ïó£CÓüë�‰S-3K|õªîn�É!©Përäÿ�±wÛ±,Gš3ÿ®jf€™ Ýê]õÞRU�}v ¹"³ÑÃȽHº›››;×ÞqŽl‚i˜Éæ<_¿ø„,Šø£FåÁæ{豑¶)¬¶^«ÈÙ7_­ø¦>x9cŸ3qpé‘ô½žšñÅV@â¬ú½ç‰Î5²·m¬õpN«NV�ÝoÆ>bÇ·óC*X÷…ºàÂh{fc­#8]�_îefv^â« ÛrB¼õ匿)�ÐZxò,nu·úÈúgìüátæ’.‘ÏðÎ�ؽœŸ�å|ëCÏpAºLœÿè5œ¸«}Ì8ß}XßšÝáHˆC^Œ· ×£Øö‹žšÇ×Ü¿ìmG[ÿ�öçùo¾p$½ùßÈÇvÎB€if6^õ{ �¹b7n÷a5œ³–sÜj ã†?ß4zK|Öàn?£Ø¼ä.—utoìë3×í [ç¶ýå†Ïë ˆ¬�6ÿtíÅÌ0ŽF´)œàÝ‹YDÿ²D Ój J±:0ý�¿|yª7�0þ{[ä$¾¾9XWõû%¶è©‹/v‘{ÍJ­æ:~´�ÂIÔÚ8›Q.>Ò*ïIÁá‘ïÜŠsî°{ò‘¤u•o‰ùS‡æwÖú òýN½“'U>sˆ“ض†… ùÑÍ¢{–ÈÐð©’Pm'È5Ê¡X´»'†›ï®¹Ñ(]þŽ©>žá^ëœ&œsh:¼CÎôÝ1@‰æZøøÇÕ'cÿdd<`›†øõÅ ™%UΈ»'Oê÷Ö¦¡ky8ODâ÷…×hHÜ0ÿø—ôŠúœ¯Fù‡=ýhþ?þø3ç!âøˆçF?vYßÉN7 ~EÈåìÅÑ'ÞˆÀžï¼=Áîˆpñù~¶^8V¤ù›4s$Îy6ÁŸ±ZóÍÔ(HߪQú\-ܬÏA·6Ñþ¡70.ÌÜ×wòt-۵Ǜ×<ôïoþ-Å£®�Þ�Rœ§™¹Lñ»u ÇãrŸº­åæšÝäR>�t†ÁËœ j§¶”è ãó÷oÈÑøùƒ<͵ÐçáM$ñêp†ªò:|u»RÑB�úû¨ªº†9éYò‘?ûÛ+<¹g4kí{½¯ëÏ8™=j¬¾øSõÞÅ/›± ˆÎ¯^¢Ñ:�ÓQºìÞˆ&¬œ…{¢õjZ^æøn¾ð÷äÛRøÝo?^­äô F¯ŒôcMصê+Œ#ÚåXï¥&®Š0v5©`prò/ùÎMH\nÈÕÿÆ|m÷Þ³aÌ6ÍŸšbL�]† »ŸRoôøæÏy¥%j. §6qˆŒÚþøsZl=ýi`+>CsiØûy-=yÏÑX7ô‰SVgÈBmëËÖæUØ Ÿ¾ÕíPùs>îàö>/†‚¦âø„d¸Ô½æÍqýŠÖÆ÷F¤ÓÅ5§(ï­E+gtR°(¬øñéq•½¾ôS/&<1›\¯k¡ç}AH³_.K=Ï |áŽÎoNy-51¥s�ÎXŸÔ$µöÑ“÷qÁ¤Ñá=ýÄå�F-,žl|ö^ pòøŽ©†åM\1Âí\æŸ.çÌ2·ÉèÏojv.¿¶qOˆÏ6¾°™wê©Ñpå¾¹÷÷æìh¬u�¥ŒÄö^žØxtE‹®~ú®á 'ñë}°¨Öõ,ãÕpãqèñá±�ëóâéK^oÒ—HŸü·Ïí›k‡‡ü©Ó16Dº°Y§SW0¬§vt Ëzcýw茚ÅÎjKŽp‡÷ƒÏËt�ÅiÇj:â„[\skpÖÕðBî+Bô n½(yný±§—poL�kŠBkt[ór/(ø"¿ÅUúTsjºÏÝeë|Ò�“3“Ñvlüš\@ç,±Ö†‡5H£¹޾ÚB¦+èäI‚ç‘çøÆ ¯’šßÉ Ò%zØ]Æðîü‚”÷@­Nfñém�ßЀýñvóÂ3 æ<|¢¶ÎX¹� nâ_Ïù­gÏÊû–¸Ú�õô;;’jÀ IDATrç† »ï¹ö x*tŸûà˜ÉënX{Е›3qLP||ý÷¿þJ„ræ £g°D˜œf5#ãú‹XoÉ“çžûêzÂç(ðýO—¾C¤vŒ)_ö�òÇ+ã¥Ò&¸œ_NÕ3æ…š«)ÜÖÈA€òû~i¦Ü?ç ¼ô¨Öíô]4åþbæ9 VŒkhlô]’}ãwüçëL¢tßÄa[kvdy£%y#®1–“Ü>Ä*~_cðKïÐ>ç¬ëÁ�þ~<௸ 8„…ûh˜Þó )»¹àú‘wñ À2®šþñÿþ�ÿÉ�õ›!z{ìFœÌߘÚrø7"ü.’�gJ~“ÓØ(¶8‡þ.oUœXan#ÎËÜÍk¼A§ŽÝ –geîÙN­4§¹Dˆë7ºNßT„ý2~p�þIPtÞ|Ó0Ÿ—”-Ÿcµ{q¹ññúKÑÆ<:–wøDç8w]nn,ß'ð´Â—þŽÏýZnÍÓ|y£Ë8· u9ݽO-;eD&†Ÿƒ^ÊÆw®6@¯>íÆórF­óÄß«u}¡ ?‡_oÊý® -§-@ñP4ïØæš}9ÒsE›§*¶†ƒ1¾­™àçîƒ1ìG"cH:\'VA;÷‰>çÝwp©ƒ-ÇÎE¹ü�lZçþÐâ Åã`Lãwœ8žOt,»ÍîÐSŒ,6¢œç3¦ŸÌñéÙð6ž ãÛq6v\ÜÏz'é/¸�¹±ww9ÒïÄ^†" »ÖÜKørƬN¡ÙäêF³lìÏ=ž4ÌÚ4Lä°9—«—ýîƒð,¿XΖ/ú§pDùíïl{jãæÊk2מ½m½¸Q|KZ®X Ýã¼–œœÇ†M Ù< cæòI÷ѳ¤Ÿ¢e¼¿›ÉÝ÷lOž“/‹Ÿ:ÂgEî‹Õe[Îßp;_AA×¶šÒš¨Y{¦÷ ÛëŸýÔ#g^¬ô¥øí¹^¾Ö(«\uz»ßñï OÞæŸxú¦P\];¾Ÿ¿óÆÒÜd o˜²~¯Ó��5cõ#Ækìos�º—a.×ͼ‚Îýlos]­Èñ¤ÂM÷µñå³Ï1�·7W×OŸtI ?½Ý»§<ן/ÈàJAM_d¬-­IÒ¯ÛRS'6z4J­œó‡_äÃíƒû嵈k‘ÆÈ$6ß@÷ Oý oÎù—ã­m¾wþÔpÜ>+—ô»¶ºÿßµÿ†àÄR—z [Ɯ޹‚ø,yŸÍ'»fÐÔž/ª/Grrån}rr�à©sKÓ×ÛËè ø×+4Ѻ{²œ!:÷ͬDFãkoêhtdõʲ÷ÙHÿÄ?èõ)þ±QƒÛm8]oó;ž×¾éœ¿,�]ØÍ¿ŽÊµ>ý4ä8³£ÎÏvÅ 5¸�Vkºx£ {p—Ûµ;ƒ.8Çmȳsl¬ÙhI—ûMoöï0 xóÏ—×;H©k¯7M�5¯tͽ¾a{´·ÔPÙç @]ìµV[×ôúëÃtá]ßZFÎOƳù!8’±-éŒ1…Ê�]ž7i[s­Î†fž^¸—û&œòZBxPõárÚÄ‚[ßR’Õ,üR½1&´!™#q¸¨]‡Û–(¾÷²�¾$ïöÅ5Þ æ¢&¹©×v§À¨ÑiöÜß3òójŒ¢ókdR÷~ã~¸yÆëºRpI_{²æ\ê6'DåöÉYOçØˆ]}o¯ŽÖ7_ÀÁc/‰Ÿ/Ò¾ø7öÜ/j˜?†–ã멱®¿-týhÎõ{|¤Ÿkk u})¸¯%4—ÖÍ;¾³ )vÂìê7â²#wïõÒûÆ…TÿÒc!­#ýÏ?çc9ß©‘DÅxÕó|õ ûçÿ¿þŸÿe›6&‰Z…ŒôKTªXœ±v8e Ý[ƒ9›ù—µ€â»ƒvqXÀâkè(ÙR»ýÇøôÄ™÷ÄÉ@>jvݰMââOVË—Xt�™˜Ž� Hœ=b•˜ÇÓÀM1-î_¹ß]ÊÙ>‡z]q‹¯ÄШ榙L¶o¸÷û ¥¦70Cö÷þqoÅ Í~ýð”ÏÞ—ÛDhi]æ­±i�{,Îöà'Ùñèf1�wÞ©JòΈñ, ßêaÞ8ú14èj'?½~bÑd( ½L+G)›_´âŠ&ÓÐøÅfÜ/ºœ‡Œ|ùšxÁšA`}=‹Cý<Ø>õ°ï½°Øad¬¯r¾q„äE-Q¹†éAúØãË~© ü²‡ìíÅóœ/~•”Øn0øÑ0Λ³3™�çÜ䯆DC8#ã¶ìÉ5GÀP‡ãÎ'þѲܦ¿¨V§ý²GogMÂíºØÑ«Œ(¹²m�³˜ÙÌ_ÛÎÜÅ!DDáâ~ç±Hµ³+(°?©¶ŸA>#Á¬PXdˆlƒ"ŸaÕîÙAÑòÐ T= †µûU�Kh¶÷þL’¨Ò:[ózóšׯ¨ä¾ Sßáõg0ñh1ö´±L·OŒÌ²µ¾ì`y½N�¡&þÇÎ�Síù’Ö (Ü…3­\­^œ]9g'–ï„NÃ1 ÖáÜ#Árå>L%Z·7†q�Þ�:Gaç5(÷�rLŽ¡ÉB°{P‰N'`rHÕ7H‘WçÉ—äÉDVIˆoê>ä�‚âÐW½À ã±±æžffLùI„¨ ä‰S(Ù¦=ëPá!or³îÑŽýúX’L16_t°ÄÆõøD²3Dú ™�7…¬û�’ *i›êòVëRk«•4ñvÎøY/ü¤b)yfÆjMÓ‡›~=w¯ð—¨KB�'Z�IRS—OFc|>l��Ùi–ÂqqM½¬:äÿé«û‚=.'ëimÂøþõŸ‡—Ϝɇ}÷úêƒ*5hñs`¢‡µ§ÑHY{߸Wð°„î\G´{:˜4h9Æ}ob nüâ]ËÙƒ=lŽs~÷rñšYØìa_�²« Z’s+fk(×Ù¿��ób¡&>ÿÞ7#V#,�š«Ó­Ý¿£'嘳Øå öñ㨦Üÿl2\7ÎúÏ=·¾››‹›¬óg„PÌjpø£‹lÔRŠ$çÚ¼Öµ3Ķ¡€£ÛÑUrö`ÌŒ?�ÄœÁryjリI¾¸“kLänvç ñ1;׃“Ãyã�…Îý”qe¥Ÿ—kþeÞœÔD1z,«É_ ËaŸu¨z÷çêp]j’¿ qøÁ®cùò,œÆñÿóï¿ô㬭`¡�¢/Ér˜#¼…oÅXàƒÓþ�?ÿé_1øûï¿\Àn¸qOȇëRxEþ¿ÿâ;£“üþù ömârn¬c,»ñ!XØ?þùOÆz1áËÉښˡ)[h 晵<üßÕÍ_bD¡Pùoý\(óÁ+FS:o.ì9³ºÜÕ,b¾þk?>t×µ ¯mE>6xyGóÇÿTNý®þ_ÿGÞpQ7¿�ï�‰÷{~o½~j™îUôvjõ¢Ó,¤Ì›c=æžäÊ¿¬Ñ@"ÚÏêŒå^«ûk¸±Ëe¿ÌÎK~½íjµA;�‡Ë¶g?~¿ðøÇ¼ÿî¯è(ø—A öÍ_À©]£œç‹}{÷‰vLú7 ó_ìÛ¢„þiRõò7<üä¦î_Ç7ÿ·~î~JO’¼ñ„}Fý@õÆýõkrýñçŸÿõ‡ž;ü- ^‡†³F> +wê$ÉïtcgŽÿ­ñôúÆ[.“§¥±˜T8ýÜÑ}ù—ôýkñ¯I#çAÈmÏ%^·ï-¬±g²y¾EÎÆœAN~�æúutÿj¥Î)¿:6-»^d&ÝùæÅêu%8ûpè(Π–»Ÿã÷šß<ë%:éc4¿Ø¤¸ý{õ«¾/ìÑz—ïÅÒŸÏùx',yõïÔÝ5ýȯíµ2ºÞ³ÿ¸ÿ} ­oÁ¾kà»õ„[zé×—®ç»ù„1å?þëOÝ“ÖÏ}©3±[;“ëTstæÞe.8¹çYûÛµ|ïû÷ÝO‹a~ãtSêggõþñKõ-Pd<¯î_çw«€$1‰¿gži!~”¬±ÓÇù—ß;ü:¤÷�ç}ã}~òkHŒõ {=‹ÝW]¦¯àšxgéXÙ¦ßï\÷÷<`Ì@qøàò‡B2ÝçÎp·Æ› ßâßû8YgÜ>S+¶=÷›êì�/;fJ¤ô9î_¹/¹'c—߇€ÆZþöÇlÉ�€û‹ÃÞׯ«m}]`Iü¹†³¥¹¶'ªÈi,IûxŸ áØ=™¿�™�A¼6ùË þÝ»3­›”ëÓ³¾GÔ0ìªëpΗx¿Vª�¼ñ1Æ¿úk¡ÉÚhIòý^* ®*¥%¥-?sÕ…Šö…|þ rŽ÷¼J-�Gc³)Ÿ“é,ý¹cú~1!ñ=L¤C¯Šýq5¶ü6ØøÕ+¦¥Ý¡'_¾hƽ”×–Q�?Þ—�ÏÉ(ÌïÃ�û©3 ÜϦE3c=šöÙñ¹oq° –¼ÕçºÑªb¾{uù[¿�óÇ?òç˜òî÷šˆZ É;žøŽ^š·üÒ‚¶èÚ·í/¶„ð\ýêåýéý^‡€½=}Fsn»:láœ2^¿6ÝO§sÈ<ñÍ1qÇQ»øýµ‚~\i«’³±ÞÆÞó�˜Ô3=Ä&'÷Ózv±öSOùÓáÆÈiÍ “¡áác!>ßñsç4Æh`öç÷šáùf-FygO.ŨaÝšïçlãÍsoý7Çõ|¨—çÏÏ¿þÎûüŒq/'7Å'�0þ·ÿþÿ¯CNƒ¼Iª|‚“Œö•²å�–f‘4ŸÀ'¿Ê<ñã`fÀû û“® Û¬yøï8e·l`Ë×�³GŸ:eÍ~góòKJkÆÁüH:æÅËpë ðp'ÖGM³9æèÌ .æ¹='ÏeOMÜÐxî:7z]¿L—%å-n@Ÿ¹ùÔß5;‡À|±…Á[ò‚å­/Á´Ú!I~îá9Ê£g<°ÿXï�Îô2�ËßMVbÞi¯wN--Áùèá�!ÿŒç¾pJß_œ�øŸ½#Ñ‚^|¯ »ÃwœÜâ]|s&¢#`ÚÆMërd½ÏÑ«•Q×YÆ-»{VÇ8—>üŸq�·°çµ Ÿ:å!ý�6—içœÖ¿õ7©ëSPC�N–ÙZØ»¯ÖÂ/|Дçw8r¾ãCÇg�€Q{´ó¼\ž8’“uÎóúÁñü�/Pié§7MÒòÄÏëP{ZçŸøúƒÀîeu]¦ñåê`}w~õ,Æ:«ñ�±ÿé‰÷¤ó/¾qô€–+e–Pñçüœ�_ÙVûq¹?±xsqw•ž>1Ò·Ÿr¸Ÿ\¯ãѬü>Bk¦FÛ0IÜ©k€›¶þæÕô(Âï8-(ÐÏAÐH/6ÜgË‹ÍpÊŠÅôj|šI _°e˜ú�`Iü¹1Uý±9”óÖÃ9úÅ?ñìŲ;ú{ɽ_õu½¸†™Ž×ösÍ~Y¢7û­µ)ˆ÷^:¯•ûD D@Ͻ3?ùÉ <¼^ÞxSiã³6[´lŸs·©œ:«ØÓú‘×™÷¹ãz”ëç}ºúRHôX÷I“Â×hº†Gü1~1Ñ�,Cùsgø‹Hñä\R§.G=¯®ù—s9.ßò¯g/=·ö‹g,\zHH¾ˆ�‡<{à×Û§RsO–q×�ê#OÎ#¾ÙÉ–¬’ÌÆˆcËk¥>%ñÇlÃlûÆbß>6(÷ÁpÄ;®3‹Ú }:ïäyŸW1+óxÃB�wÖöwƒþåÞ|8|4*è½o åž�Ÿ�+ó9ÙÞ7’ò�=GAòibÝ�î‹™àoN Ní£™à§LÂ7~ðúó[”;á@̽{„O]¼®Úü­[q>û÷öÅ,ŠƒþÞ#âA£>/½ŽãÅF#÷?DS. +q2j$s4­&4ûØ—ß‘÷’~îuéWͧߊw_(@FôæýÎ>''²Šó¢i0ƒ·N7 û×^hâ)̃JÈ<&ï×=“î˜Ò‹~N&>žß§–Æ�;ºœ¦Ì‘—ãßÿç<Žæø¦ìÔMòO£3Ï*þùþ{ºRKz/+f?rÏüïæôðßyÅËY9ËÅðúÅ-G§ÖþxSJ†·¦é‘ÐÛsôþ§Ì7ŸyÖ¿T.ùd{õ�³oý8c÷ñ0V±ÓØøÙ͇o¸̶Ù~Ðz”¨Ï �‹CÝ hNž7áÇWçxM¢ ³ #“ÞcÁ7FÐw»V$í�Ò()R1csãÍš"ÁQÐ[Tc¡Iž,ûÉ‹SüºÁ‹0×8ƒÐµ9Žò¸á}´'×Åj]²ðOk|æ¶ÝˆC›'•lp3ñ¶<Þ‡ÛÎ$õ’ έ™�Éþ§Ivgzø‰A®ÏzÃÞÜÜ —ßi,$ ë$1ôj]�{ã±û4pЊËZØN£µÅ§ëù"k†û™åYÃ{F—~q¯}^è’ÒyŸ’žöED¯Ÿ zƒ:=Ò çFó±}–Ú )òñoŽ0èFh²ÿK ?vgô:ÏÞþ~Áæ$;Þij'I¬î°íÀ½>æ @Ñ�û•Ìõ™W˜�~ò4WâsŸ¾<ØŽËRùûý-ÅÂë\æ)%úÇ7˜nÞä(Ùn:wÕ7®[ï±4�¼‰ÅC.æÖFûô³œhE˜ó¡»~ˆÎ›�æõ�5cµ°ž®ëǰMóýk(§Æ/ˆùŽhÔþÁãE ?)1ÿëvdÀmñ¾õÁ‘þ…Ë>Çn?³9Úxž†‘ktÇ+èÔŠ>î•÷œð’óÎW#ÆrÈ8R¤÷ñßܬx„Œëxµd§GxˆÇ·3¼¸°ÍNÌÅŽãå¥S9óD‚ÉP&iÖÚBœ¹5\Ä�æ^ÅVñj Ït»)ãöƒ Ǹ.hÜÌ.êbŠ.ž“y^&œãr^ב‹0x¤L÷¦äŠN<É—<Ù³–?p¯+Ok|Á†‡J2¾+YIñ›1¹‹;ßÌv¾oÈé]ÍÔÁÇWóÝì9d»Â½¦�¾¯†ï|œsê‚/ÃþnÇ“ûZþ¥½ —nuŒ û8ÞZšÊSbÁÈä½5Ý><"JsDiÏzõ‡ÓŠdJ-Í÷9¬÷9O__ÞÐGÎb<“»ó› ‹Éì8qÞxÙ‹É4ÝÓñ½‘è£-€ëJŽõæá³`9ɹF—ï½rLÄü º÷—ï›Í�÷×Al¾ hŒÃÞ÷¯æÌ©<ÇÞ@çá›'ðÄïuŠM_µ&盌ëKÎCÏ©\®VbùÇìÀ`Ù¿±±šå.»º÷f ÔpÒž½óbc`Àûxòú¼:—ÄþÐl/„z˜wäÝâò.ƒ5;$øô7ÜHʽY.OŵOî�L§G�1?ÐÀ}F„`˜þS²bÈèž76–¦$2¹ˆâÙ�‹`¯Ëûµ±>Zûú)#{ÛÌ¿ZòÜrœCIz9LÆ…Ø669W‰°Gç“ ´b¦Ç²Ý½ƒýò‡M7ßY†8x‹D¡:Xxs,ÝŸéÉ�˜ð侇.ýÛüqÛå$†äÖ+3óϾN”í•Ƕ²¯Õ\ùÜçͲu¾`¬Ø_#ÍaãF‹Þ–ƒ99µ*¡Ï¤ˆÅNŒëçf+®ÅŒ/æ)Y—„í½a?dœ;sÇ»ÆL~Z×;çc}žÑº°,ë87ÛçŸþ Úûxkt}6g'c±óŒ7³½ô‡á¹yØ?9ãžRvOìR,×â„áK°�jš6‚M^v—§2x�w»$Ñ> ¶aòK…óŽr‡áFˆð�1Ü!O¡Ö?³v$·X V³ÆE> ؉1~=F·Ûjphåù‚H}`p:Ëî™Ìé….ÍåÜæ3Ò^øý8XòQÜ�Ö[!ÎO�'"ýw¯kbI^&/£óðd6¿n~ç+6 5\û¼ß|9ãë³~bd‚ÏõâÐ�Á6%v~êoÍÖ…ŸÔý/õ¥2«&Fzjyö²�Íï5¹ø.©±¶ò³7rZCõx#ƒsâ°Ó4@!KÎâ‡#‡×�&Ž|‹ÿ1Û%b*Ë‘†é‚Æ}§ØZµw­L �Mø‹=5;ÿ‹O‰#FcZ Îæ@i| x×ùžõo\@ÑXý�?µ)—Ïå­¬ù˜TÿBaø{ób:ÎÃãáNž&d2äößšl~zg’ä¾|á>Zp˜¶Ü‹yæqcr�ødû�Ï?Ýþd¼Û8ˆöç u^ÏÊÔÛp‰ÁÆ=÷à/­ûáólÓÓf%Pñ–î³ÒÚ›qj£ÉÁÉàüŽË‰�]áIOYìGë#öÅœO�Lû“Ÿ}ë)0£Zx&xûo÷g�I)÷·W;oܬ †7ú¶0¹3œÔ¥x︳b@Öu7ñÛž=è3ì?;/¢‚zâ ÌÜÃ.Ê�s ">×TLêK“5ÜŠÔòê‚ “ÞI1¶â–uF€±‡Ïv¨ìÒåp%ÞY€*‰×ý¥f"¼ñ·ž8¦ž/>¨†Ðÿèà¹Æ2™gµE„¸Æ Æ9 ÍýG¼;$d„ÑÛh‹ÖXÇ_lè¬×SöÄvë òÛæû4`xža÷¤%3¹µ*m([ðVú`š‹X÷A‹æöÖ—Äë*�b�({¸Íïml¢¨õNïx8#÷Q¯ÓPY¯s7àñ‡‹Èæ9r=9 ·:0eŸ|…غ5h¤÷Ì^ÏïÙpÝ�=ooî׊>Ú"˜^tex¾ðKâïú®x�æã¬(»}Œ Îô†œw²À°jðu€ìœ��ò¸ég˜r.ãaÎú|Ѹ®ýª¹ñ¾$æ zö2£•×Ç€#öÅ?k0þ2p�EA‚˜½¿‡öN+Ì„bâxtÜ•#fþ Þ|Š€¹‰¨ýr…Æ$Ñ#š²8Ùìo$yšëÔ£ý°FqY¾be9cºn½ÉËx;’úÚ§<ž<:›yO~~Ô}›“Q zq¸â@?f ÿÝ'‹°� É~ü ž›LV ÜÄ—#!Bká:�Åx8¬GfçeÖ‚‡ÇfìŽcë’áëHžâý‰ð¾¼äN?rŸb&Þõóòn‘øwö‹1¾±ÁË·Þv†;ßå3—1‰Ø~qL,ö½�t®· ¿š�¦:–¾÷¬äž–iS¢ƒ�†¼`ö;ÿ©¨ Jïéå®{œ'çìhï:鹉c�½�X³^Ø&7ÚÌUèô-'{ÇP7˜>œãÕ`žž• ã4¿“‘œOL 3k‚t=<Æérð­ã ¿qé� ŽÆ�E"3xמþšs·ô€Œßýà —Çç(€M×á.†3£–|2gByàh�Ýyš{3FÅÒ¿)WzÕ‡ÛŒÐÚ?=d6<)!46šš ŽÍ�b¶ IDAT¤ŠÁÝö’8<ïõÉóÄ“Ãy ÏùP¯¹ìI�>S¾€ìQ‚n™ÜG-ˆcïû“¦v Ä»åÖÌr?uh FˆÁd‹Ô¼˜šÒ/™�æ³ñYÞ}ìÎ}/ÂS£Pô[öÃY îIB!‹†ö®MËS#?ž^9˜< f6g€ÖÏNÈÇ|ø­ÎFÞÕ1\/áâá]×Ñ•Zá†q5‚ÿºÂC`jg•5kQȸb•Ža[N¯à¶…Ý�F$¯l®ù’ç �ôˆÜÖ¨8§J¾ÑÌà˜ƒqŒ›#öSƒÕan¼ÉE^ìŒäמCØ�fñc<ö¤;~8¦‰Žf�þ�oþ#MÑ÷uãK˜g]{ 7}Ô?ìÑO§�³N\¶V+ðZx|'.9s�æé:ÍYFònÇÜH–R=6OÛæàÓ§p˜ÿƒe|ÎqkRÉ·BBuú‘ºÞ<á°sïí¹œ¼×³]°ì·cÄ[�–ézÃs½åˆÈþI)—+º‰õ`›ÉûóÔfšoã�Ôj�åfˆZs/Ns¢ Àxw³0ÇZ_c§ñ囿È*œ?‘¯�õ((x´Àwɬû›¶ si)ÿOÈtÌ1^Ÿ»Àçü›ê¤Qçé=øåF£’ø^•-þh™Û]'Ë#�à= ÖÄÇ7Ñ ÷Ã_¡ä…"ý=f~À¦_ÜÌ7ýÅ m‚×aZ˜&|ïÞ:jwp¡æÁ‰ÖðoŽÁ!ò:Éš2==>a:ŽŸ½ò/×f¸–ì.›Ï«}€†1Þ³–ß8{�*¹¨Y¾ êÉÀÆ›y^îaío©µñ¸\â¶gáš¶™†iÞM§~T<˜»Fu¬SÞ~˜ˆ÷Ë©‰³úŒ´ñjTL°\¦»öó µT�)Z›(uŠq,xÖ` †ß¡Lˆ.lì r is¨‡}kHÏ�lÁµÙ!¬Áž‰kl1þä®|o³aÝwÉÅÃÜdRìù.˜€0F…3ë95Æ›�MŽñ^\o,=òþ¯¿iþÔÙ< Y¾íé×Ñ:Ogå|µÁmœfëÿxéC~¤­Œ±m3mpzmPê¸Õ}b[ÙÙC=^æqmN´®?4â_ý“í½Ë ëä :çÇb̸׿@£¥¸]ãæŠ=õˆƒðw$SóËÉcùmq�,Óð¤žÄœüõ¯6Ëx¿õÚÇp›Í’èa­�6ëTÜôbg=Ý!5¸v«Ã»êzs ·Ù>66ëú!cu¹~´¹R£Åô~ÂíŸõC᳑Ãtá6L{fpGû~à³Zz4‘b=åòzü ì0ß6‰:9îQ‰Ã"t-˜ ËëCb;´\ Åhf™:Žý­Á>Ûuqu”Çë8cÃCMËÕP9z¯9X-¼® „pø×Pâ%ÀÜ'V…Új.œuÆêÉN>ËwPo*ŒíR;„À}7Ǿؽì#Ü Kà7^8¨!¶Ôé¨ân}¡Xrîáu_ ‡+s";#¹sˆ¬ÕŠs A¼½sÎ<’iSë$Þ  c’»÷®#ûÙ® ±Éë =òÓ‰GŸä/¯ö>�æPÀð�I/ºžíò÷Õ0-Ìøỹ,²%{öé�e“®q­Þ�à‰©žâÿ“?ä¤N?Dº^„0>ÖîŸ�¹�›‡§®áˆõÌQ”û !U=`ñïä|ø�w±®­©Ü; ZLËf¸XŸ½b²g¶WqZ³d¬/cM_†y{C�Īý[®ñ›×—ûÛ|OÚÓ{lç ½ÂM®áªî¯hÒƒ0£*Èp\þé\fæqj%àÅ^ßiüaå9±Ðï7@|ï˜d ֣홱Ŏæ;>›˜–çÑpÎq‰´sι|ê0dù—c÷bì¶rÑãžë2¾sA¯©ù£#÷!¨i°^cLîÈØ@)_&­øs(gca_Kê;Î,ÎÙ¿èËkê"3™s-9nYÉG >=R ˜‰zϘûºz×Á�ø Íãåçr;N¼sËŸ±Ð#©ºÑt ;÷ÄÁ4ŸÃÜÀ}œçTîóCÙ„hØûRß=Ok#"µÖf%çácq6ŠÓO~ ZùŸ.‚Ž{v<¹îÞÁlê['Ôhž?|Ío°2·¾;Æàă‚|Rwjô4£Z “ÍlêÞ4ûæÇ~8[0ûéfMnè¼ÆÇîðhѵ§ºsÉ>͇[Ä£ym£_O�ú®½w¤ú¢·ñŽ ?|cÇÿ‰o�oês!Ydg}—߯ëxì¸*–w9§k3çiñ[[•š¡ùÃÖ °�I[×wì2 ‚_kð|,�;³<å!”ÃÅÃû®5Å·œ€ˆËÑ(p]R.~¶fÇ·‡‰ãïÐà4f2ålû�›îékÎ=ø÷HU"zϬqpÚ<ò±Žñü!ýšŽ_xÀ*Æú�ßks`Ѐ³|ë™}ºø~jNâÉuøÆ]>cå﯇ÌHÂ�®'jþSèƒùý)�ʆyÔ¬+vMæ y¯pK�a¶Í±gG®“ízØÃZãgMkÞrcY‹%®�°„ìj!,$æjlû;Üg×<öDð¡Ù´YJEîžq-ÍÙéÈs)—�ìs]­I½ï¦^MÎrú“ÜãKÙUšIÎ}Éî#ÌÈ¥wÌÕ8`gAS3sl®ÉÚ9ßhˆ‹;¾Ü]]Þ‰A‹±§é°u‰Ù9�CaáêsÃy°%s:D¶Ü“Ö ¡IÉ9öÜ«ì§1QâïOg·ún]ð3@kˆn¹aÇÞ6¸ &¯Sûb\ —ÇÐÆ\�!8Q‚¿uRúg[-M«i‘³‰iÂl¾_Àó~ 8ür¦'Ê`B„ %Q6‘æÙ×ãä1Ç2�?kX®Ù-U—ïŸÀ �Ôº{õÁçÒMü=wXîe.c ŽÖ<Èn¾ù1-ÿC¤å>FÎÐI6öÓ?Y*Uørÿõ³QµZÿ|A,÷à´ƒ$#9àÎ}À*ç5ÓÎnk-=àÛ7ú¯�:Œöàõ%_ò&gÖá[�Ì»Oî:Ê.f\ØïØsï µuZx½XYN-¬O¤? _ù° У¯¼ñή½þ…–+��Ñ7×á†5�«‡ÞnÈÁ°Ÿ?é4 ’ÏÂŒò¤§b(Éxs>Ä…/pÁÞ{Œ{ä>Æã¹œdƒÆYx½ó4%Xã‹´�ÜŽd¿ØÍ˜´88€ú§ì´ÀŸ¡ÅÖÄè�-±¼ý§1ž{ß.¢g}û€<=BËè?±`ñÏi w�—óš+|ØÌ)[FÍ“^;¸Öd¾Æu}ÜìÙ8ÏH[B}G3TþÁ“$.¢¼v~q1§Ú:E~ú¢Ð�ô§¹Oñ©{0¸VOVkÈ£[„ùò£Co¼ö¹·ß¤µ^l4ª�šÌç"Úâ†\áÁDÞ3žøcÓ>Æ«0çi¼�7Nk˜k:±ìŸŒ§óÿÐŒí0(hµ¿Äî›Qé‰û²ÄðULýĸ��ꬆ՜8®®G˜¼Å†.‘ù} ©�^{çÛ ôáOd¯&Íú,‡eî€÷ŒêôþÁLÿǾšìss ”V¿_�³½|Køäso´Ï��=°÷�¹`†[’goðù´Ü;êÁàv™G�³ýù|†±à” ø\É[Œã¶f‡MW “ þ£×‹Ë~c‚ÞÛ0ƒg¿<¯¦—t� ÌðP-z‡„e¼ÎFM'þf3?¾ŽñcǺ<Ìö °ÛyÛ®q¹ 7õ�£›+~~ýËï‰#:à`@u:àªbוp£Àðwð4Œeêy ZŽ×Z~¼ü$€ÆfÇÉýÕ�¼˜Ç¶›#ùn  ŒÝh.^8—_ê�h붺ƒ%,Ÿ§µ/Ø4¹™ÏnX¼Hès9Ç÷sŠqÊç¼õKÝ·ö�àãK¾ÅV�µÌæ\ÀEø“Ÿl fYMË�¬«Ù»ð¹‰ÿ=òÈ2.8—æ²KëSk¤9¯KÉ�àC/ß æ_üáP([ÎÑDfÌeÿ –¹ÝÇaã�ýœ¾�ÜÃñŸ.Œ?ðoólš [/Ì Bv4ŽžPùÇ�;±é¿Ê�à'l×äB“ž9ì$æ>ӔƲ˾&\�ÆOóŸàî÷¬¯¦=·KA9ác½½©e#»G»p«{B[2cÍpùêr�q‘Þƒ>°Ù'Ð xd ßþ~xèSú€¶­½Ôe£I¶ýí aJÅí¾áW’ä>R½Ú=+”÷÷è±nįHh¤¶X¯~4æñD;6õÉËûƒ$–ÈèÓôoR.üÛ�+¡'‡ÌÕö’8«ûb.%H¹ÉB?Ö›0¯Þ© n�¥Þ¬Fk ‰Õ->j�%v–GN·Â p±¼ù…“á¡mï¦IŠ_Ñ5³5æ°Ü�-ÑÏ ×î�›/Šà3 äÜÖCÌ8Ö÷è~ðÁtj˜›Ùþ€’gœ²)ox`kI_�¨°i~[ÇUöV‹-±ä‹/×ìTcãÝ!Þ=Ñγ�íÍÉsÄÏ‘þb�öùdqOiHÛjOOÇ�ê“Ë0ЄÞzlüÖÓ¬©ó|£ÝI *ÜËÕZ…¹`áN8ùYc<ãÆóz.}Éó¹úÏ3—õ&ýP�Äé-Ww¥.Ïz1QA<½»šIŸ ž%Üš¢1[®î� dÏÑ•ÝòâÌÃW ¡kŒÏ¸ù&H³ÒÞ.. ¦OÐq©ÆÁ=‡Þ—ßÖõ€ÝKÚ×7Þì1ßsYԙɱ�ãÙË¢Äïû¿ÜÇÍî±Ö¦±q]gΞI’º?±d#¿»–/ç‡?±Ç�|.Þ6›³zøò¬ð\˜E•ûj¶ß®Ú¼æÂý˜˜ôè¤qIFè2̼ß=Öpœ•õ×FÊ=@6ßb\/� ùâ‡àö.ýœÐF’¦Ç*ôýâ^8!/ZŸ¯¦ï`…e ‘UfõGo¯îõÌvGDïÉ\žpÑ&yøwzg¦Ž[(çÖÕùÅå0ŒŸxSŽÀótg£+:cNxdúù0¶¼Öã|W™ý½`%Çê0 þ´uKò„ožâì·½,à4ÖoçjÎÖýyßÛ˜è¡Fz˜z�“8ż±N2^òéÑß͆@W¬‰À¾@7¹ Áo%¾bsK§+²‰Â­ b,xyÖýɱüÓ0Çûòl6�¸Þ=9½kko·˜6[°š…O×lu=¬ÌÇÜÿDÛ)mNŒŠsLì·C‹5çמxâ4(�¸ƒÇxˆð§9Æ™wîüÆ�5^ñôÄ‘»xè}H3ñÎ_¼õÆ.Û½gg&üW›×ð=>ŒÉeùM=§rl?)¬S޵!:SÓïrìü‡ƒÓºÛǘoŒÉ±úð§ ®Úu;{áÓ(R:ŸWß½á�æýÕ’å ÔZ{žÑ}ïA(æwšéh~×Ýâ`0/û0íy8^öòÅ/�€ŽzÆ„›÷��Î,�éÚb«Í¾æ_ ]à÷Àa²KBŒ}S�õ´ð÷R¼!žv¡n’è_Ü\m„ƃxƒCæ¡Ö÷³úöõ¹„Õ¡�õ†Äÿ¸¼\OE~ð®£Àä/ëÈMµ 31¿¶ÏO®Å ±@ú·Ü„¼ãž ëÉò1ØÍýp¹(ÀçôÀÜa°¯ŸÞɆ&_X(.ç �=x=R_lÓÏ‹�1ÙS“ãmÞ�ÖæIá¥._nA ¾lU‰Ÿ'Ú=þd-¯°áây‰çjø…Óéåé¶qü.G}57+áòœp°,ÎíKõÄ î­5çœcð'ؼ/6¤òëõ`kK<á½’ÊšÂ$UÒëy÷ü„!˵¾ak<~òBÇ6ág½±\Ù›óq;ÌðƒÝyiµ¾Çj7ZN~àYbM•³x2»7 coN[É=ìY8|öÙL•ZrcÒô­wcó]`í—Ú:Á¦8Â1NæøÛÛ#|1Èàœ«o m™‘º ŠsÚØ&Ït“c.ésƒ09ûàGßy6´_÷žðäªÁ‰¬ÚÚæsŸ`N°Á'kZ71ï½�ºÂIþ«Ót1{ü¥×ææÂ“|X›S´Y5äÜAWÊ�?Ï:Úsn`ƒ'–‘ŸÀKb1žtòÝ<ÚÔ3Tlè{qq¡e™\„qpnleZ i¬{=©9öE’íDÚè½LÑ7veç§w$ mÑ—¸��}~íyøn)—jV·Æ'TCt˜:ãÊsÃeÞœûUŠ—r¡ f||tpf-;ÀpŸóë¶A‚ îÚ‚UÿnC™þÈÊRPCðÆo=p�¼ôKqfz ®ð,¶!@koïå©­’‘Ïç×$ô ~‡�]çÄ®€·¯®Á±‰0ïâ†Ç¯'æä +,?âµ}mÑåDÖì½x¬†6.YH¤G.žWçˬ> xÏÇzGéÊõj¥ô˜ÃµF7|Œi½k€üág¯d?†ùp»·€:ž%¹ŒCoÛ jÍÐê1m0X¼z[ŒíÚ Ÿ¬Â™‡œËK�hÒ®¤ànï§£1`à s†ul ‹b˜@\|öÀœ ŒÆ8™ýå“&Óëö^ÜØñ¸Ç{qàc,u+ó±[ËEœ C[õ@ |Ì\é5Æ`XÙPòàkÓsâÁ¥ëi@4më�mugò^s?67«ûßù\Žr¥ï•ÚÈ�;¶@]ø¬L,Cq;?Ÿ©ëÁEŸò›„þ¤´^]ÚáÔ†6℟Ýý!X>Çè F_”ñe%ÐÉ{0¬Dp,ðÕÇ{68v'XV òu4Ú�öáð‘ß�„k›êË;Ý~’Ž�X¨»žæfën¼íå׸W‡©„YK�¿Ã9–�*�/vßÀë[1–Ç ÂhÀ/ïtîæÏ›®ð>ŸM—ÏÓ9ƒ�ˆ®Û—`ÇŸsky¬Ó‹»q,ý�“IÙ=C�ÖJé­góPö“@˜åcÆ´¼uŸ½ý2ξØÄ- AKfÎF&„ëHŒµT±9?‚â;�£LßL,ß¼™ÍÍÙÊžX!´wr/ŽõãuŒãë‡ ?:j ŽÉLMhq~HH ±i}u§&óÕ>­ l7w àÓX~æ¶Çöûhµ¸›ó育´ã˜oüÛCž5=tªs±Ý!óþ`Òó4!!ã�CO�èLêv�d· P9§Õ¯Iøk7Ÿatÿ5j-ûô/ï)^†soØjÝ)Ñž[‡¢eÿøó'}о~k}}²i½š&g¹žô7ø€0å|ÐÚ™»ý‘¾—ó׸òµ Ó'‚¿èΚ²Ú ßü8ì "÷Íj¥‡²ó¯ì0 �ϞîT׎Æx‡Sƒ°é�Èíñyþ‚áÇVµÖí\忬 jüx€�Z šG”_Ì7Nâ b™gëó[Ïô©†Á=;»²Ü×�)LEòSŸÞÚ„˜Mõj“×P!]'1{³û©Y¸ä„c ²¦„§Û�ŽzÀe!ÖñÈï·c(±ésúĽ4ï­œ†&ôtéL‰‚ëûÏäHLÎŒ¥hN�L>e·+¸h#ObsT|¬Ã?¯/é5{8†æ¬$Wfãb,çÌÈšU!ám¬sâôÀ¸‡VË©À�û5!"ZûàZ.óyS|å˜Ok[å?¼‡ ½oià‹F‰8™ƒ)Ñb=ß:RSrÀ¸\±‹½1€<Þü5€ÏôhÜ…Ëæ†œÉuÊøñïÿÐGkÞbKnŸdk`§›ž =ÂEݹwAAmÉdSù‚åš.ãÃE�s^ŠY�Ê{cÌÔKS™çãdÙ› ¨L·Pö®û¢åô²�ÅoŠùä]"®^E`(þwyr/ð&0÷|Ñ_-šx½øtëı8­´ÞVqç`Ÿ&×̯Æ�ŸqÌiEã—o5@1¾£óÉgúr7U{Adt7yqâ»’¯þÝ?ñs#m¥}6 k6‰ã<ü9^1äµf€}X‹BØæ¢©Âc#—w^“/�¬ˆ—»§œs¤Á4þÎO3ëËr6—y7¾‹n&"sz#3¹Çit/²ålçÂU.ë´f«Îý Œ˜âUÃWËúe¿EPÈA{faÓg�Ê ¿}Kàƒ.-çüê [n>ê{Q¯ |©V!Ûg[૞!H>ÎVv§õ7DAiÈðö ?c\Ç'>tNër8º*еqô–5>0zÛH]Û1ó¼›5Ùæ mž—ùá¦ôÇü²:Kµ\ûÍ�ùÈÑGöW£1Ñ’/„ ��l<1¶— ¡2Y¯–Ì1aœµØ*Ö÷¿Âˆsdçq:|>6ND@Šù?ä=º¨¥Ã1­‹õKêíÕ|î+ñ3°†S{|‰a¯÷¾`犸<ƒ@ÇÓ½‰êßÚ À’¼ˆu’æ�ÃÎ0¯AŸùÇBv@Ë�YÀKS«§u²`)ÿž|ÂÃÅÑNa^ýŽ!Ž…ˆ—g9Þ8ÖîÁrÀÏÚ?uÄÌ!æïg éíGøÑ‘üæfîØf1Ðô¯oÀžÑ<Ó;œ1ö9î«©ùèiùÇ‹eD¹¦(ksÆgUÖíS`6k,‚‚9˜þö ƒÞ&\cdæaëmd .M�'/ÿØó+Ï› ¸òL<ä`oN/`¾¦YMö8 ´ÆÏ€_§×®):›OûùwvÌ«åÌ�cO.ò;§s�l¼^úRk×áL�ò´Wä6çú:ûš@ãÕä=À"ÄÍÀ®†hª‚ˆ `WòØØõüÀUÛÁ(ßÁ9~dwv“ÖÇp¿ÀŒ5×o Äë#sß©õòÝUµ¢·šñ9ßáà'&opx´¿¦ø½‰1§ç0vÄá Èõòã†Ç\I0šÝþzßu¢@EK®ôãDzá…™ùôçäŽg|ÑŠm–wîp )²àŸœKDÎ#FƳïfÅÊ·×,òæÞ Ñá0EÉ -%•­Æh‰&âŒnˆ¾ë¥7Ï«U äKÞh– fʸu?$mÛvL{JÇ _ë;˜äJ¦þ 0¤&"òšñƒ:"Ô¼­ÖÚ¡vœ‚¦ÁÚ�ÿ+3~€� ³™æ0!i·¦¶ÔW]2` Ú? Ô‘0µe�B´q­S°¾\МüÄ_WΆǦ`¡Êdž�¶ÔM®W6÷£ðð@V‡7} ׌|ämøG�sKƒ¾ @¯Ðg¿/¹?‹6±[ŒÖ¸_aƒÿölƒCSøY1âÇÛŒ¶úrš=ØÀ˜ûб�ÇS×Gg�Ó{5hã··^ÏÙß±:bYéáŦ‡èbÎö^öå�Ÿ¨[“ƒ¼óKÙå1;‰s:]`6RÏצ�!ÁÝ×4b8ëøWkæØí7ª±KC�Ö‹_ÿö3Þ�jã¾âÍÅ…èž—™±„‹cÈáDÑùŽ3ÈwK.ºèp �Þ‚O¿çs_?„c[ {ô»)ð]üöÁŸÚWÇA t9Q¬'.8‹”õ‹à¸úˆ~ó€e�Ÿ·ñ¡ýâ–“`=Ž–¼OXüšÑ|ƾr±×x5Åàk/AYOc­g×Vän?}s—ew¿û §õ-¤!†�/Á—>áÁ®gÓ ÄÅþ\fŽÆ’ÇòVP6ÉS¼]^G9‰Ê=Mi­­©Øû r±Z�lØT Æg„/u>æ, Mý2Mޭݧ­©9æ�«=ÌÆšªe0ëÒÆó$2 Çp}Ô¦3›síÞøS'ñáÀnóáW64?q@Ü“†°ÞÃa²Ï¿ØÑ�Ž�ÕÅþ]“sµº6„‘Sz¶?|]€'î·cº–G3È¡áôpßYÓ|™“û�>�aYO‹=º¸/Öjû{ÎàÁ<<•çåô¾×ÝûÓB¦Í0ôòF�À@ûå6^úyèÓÿöë|ž ­¾þ´šÇaÞmJBžic>{ÙÑ·¾òf;T,ÐpÊhníó•�%ƒ�TÄ–ñ.Ñ|óx=Ü ä%„ðã+ ­°1ëáF•‹}ò§é‰Lìç LÒÈPN·p�J‡™äà’³kö?ZHó IDATGub!?ßÝÎô µKÕûWz�zþŸùôE&Kh�Îݘé89 §‘Ú½²�z¯MögO�Î\áìObÂìa)bŸvhe?r‚¶y0¹£‡çîÀÚ¬)¹ÙFÃsVµån‰µëè�Õ›±�©gÖkMr-A”£7ÎAãpxW-Õj“.Ã6a¶­§ð9D”΃–KHWVë˜û�5gûj.zÛÚ:%ìj™cŦDŠŒ°åx¹p>8w¿Þ¬OÜÎKMz›†Q1c F›r!)ØrUãðÆ ãN·Ã1N¢4pͽ=3ÃüRÈlUÉ>60omŽ”áÚ›ù|ãg:Tús¶ ßP߬ÁTÁ¦A·7ÆÂAêÑ8ü¾'pïGªÎý&ë4»6¢:Ü‹4ÆXÛrƒeÆ!Dý¬wOû^ÇÅ šá9rK’~ãÉÈ9Ÿøœ¥x/ëðåõäðšB(×\²"n�ÝÉÖë#Ãùj>gEmöN2”ó”]ð¸^Õt¹ð0®Az62_� œâₚGì»z|å©(0ÔëX\¸÷7“¬.r�–N�؇£&¸‰ã ¼›ÃÂÕA‡Ì–ݧNÒJˆgXS–ìL1–ë#a°ä7…LhbÜ¢˜³^üê:i^¨�ˆ‘‘ôÕ}sºžœÉ¿$ŒÞ@\¾²Ò#>4ÛnŸ™5¤qÅÆ‘çÏú5[^�Ä)C¨»šƒãš{0{r/"ç¸è׿¤¿Â§�œy³ ã8‰Ëß�®»?€ûÌ\çì¯?îV¢�»#=á-) Ñé­� ÄÆõk_ÐoP¹¿ñÉcBs‰²#‹ÿ1§_¦~t9ø8 ñÔEÈ8q­7~R[‘ @Ò{~H ö{¾r®YÌú÷~"™Ò!�FrußB×ÃØçæh‰îó>Á —ÓTˆ%6 çÕ~ÞšñØÏmÙþöz‚ÖÚå­VŒ$÷Æ5í§“kyØ­ÿÃZô^y>ç>0Q0çã$lé³¥ëBŒ­ÛÆžâTZ¸='ñÈN»hÀ/…Ýý°ÜÌä0Ö¹Ù�AÄ0‘Þá¨?Þs_8¡HM°RD�o:­íñA�tº#뼂 Çòq4–=gCð»Ÿð¶Hzøá!ä§Ç± @žw˜ŸÌvÄIŒk[µØêuVŒû bÜØ\—èÌÓ¤ØfwÞæ�ÂöƲ‡§©´ÊX´F©ìg1Ôsc2É™Œ_ˆµ•ÀÜÂ.ïÑZZפõÚdœõ€½¾?L#ÖÚܕä@¯uù©ÅùZ§{ãØ)ONÈÆçÿ³nÿäóͱNMÇt›Iü¯–�¶­É´ºÒœ7"¾—{ Çâ¥ÿŒ#:–yNžÌøxmÙùsoå<Ÿ|í‚mͦP[ÅáWR,x‚HæÄo£lÀóĸM|ÈÑÚ{˹ø‰+ñž‡n¢e¿ñ²koß#lº;Xùé�&¾Õtn„¤ø7ÖkœÿaÀ äáÞþè¯ßºµvnáù¢`£AD·ìÄ­­ãr�jMlðùözÁØV'(úâ7ÍŽô~ ‡J ˜ËͤûðÙíËé%Ÿóèêuý'f…)†:N~íaª‚‡ñ._¿³êb‹BÊ>€€ËÎ-$P†ß$Á×O'<Ä­]›<ÖÒLf ë ù`eö¿ìcŒÝýÿÆAZâå7ǸLPŒCÃ?óbï>d•c³«ª®£­9½®çÍ£õjœ.bfs±tíIèžÁÿ>ÖÕÖçF/†™r­íg½�¿9nn9egìœÌ‡A¼à'k±›“  ÓÀ¬q0hÕÛ«%ßÜlsÇn¶:Øk˜Ï¦$`?½èc�Û1œµ‚R¿éüº»øX^�&L±{°<¼]å瓇½ž›ÓMÑÊÐàC¶uëj�}FcÖ·/ ν€)gJ )7{÷Mü‘‚OÛQlÖŸ~¬&ëÀß”Ôo½,ç‘ãÜ`›«XÓ”+1MfØõà^éÐ"µ?¸³ Ë¿°; òjÙšYšÒù£_ÆÔhg06ŽAÈ�¾bƨ0‹·škÎòÝák¾„ûŠ¿tOথë^ØÕ¨éœ=ä›hH„Ù>æG§à±…€zØßpôÌXz·k|îyëèúfGõ»ÚöÁ{ÛÕ Z¢Pkªæô‘”ÞÙŸˆ7Ž@3pÉRsRÛ‘5>oÃõ “Oöj`O�¾£y<ÝÞ“gÈÄÜœpÞœØé ¬‰ ®ìq›³™F!ݹ&±É4�äXßÉÁXžù¢C±røcó‚L-É(F Ö7mɇu:ˆ6Ù’??½÷à Î Úë_Îìa0::YâËpõ ÑZwž×'T·áb3MÇ%ËlÉs¯Ü»D`¯f‘m'‡}ãO_æ Îì&-ÏÜÚÚ,†œ‘ÉØ™só§¢(|ç, é—O &r�Ày_ãœKïìˆ×_#e§¸äRö…¶GCu� �ø¬W1�õ*3©ÀêíP›„xÈûýÛÌ�$‚ëòÙž(‡nŸú¡�ioNS] É})|¢Âä^»óøW’<-�ž)þ:œ0<¨…lÑ[l6ÔÉOߥO>„‹Å•¶’�y{Îî&5#\/ÎÆß\¬CÜ€SCÖ†Öþ­O¶)Æyœëf{ÏÂü�ûB¼÷öÁn°« _òq~±c;1>ƒàpƒ7 ×�°PÚa«÷N3›S::¹å$÷é9kô8G9F5�ôKcÝOíIb5wõ»‡F€ýf ã0¾8÷~Šô‰ �´u;Ïa�f8n¾´Pºr‰Ò‡DZÓçõ;ôýjJ K4?À-ankœÛ5N‡bÀ ë^'彪Nâ�k_æ\�ù†Vë.§3Þ#€@øô–Ì„ëëÍ´%áíßúxë È¡ýÁ«l‡ çͰó<ü?êSô£.u¡ëT€l?°í�Î7çøoA©•xFTe7~ãÅ;Œs™{1™“¯ë™4?3Mj¬ù¨�:˜5îWB°Ë`3—%- àzS´· F„#5´þ­ùÄwþüî8),kç7¨s³Áï›êcI.†£›{ÚijX ¹UÎëÐ n‚ôè7F;.z5X5'ÌqQUlãV#Öi#Çá‡÷¯Í؃O#¹é³7¶M7¾÷´³ð¯MV.»©²+_}Ú³¸SwíÄ¥¢ê²¨¡OEæ”d?4 –šÊ°\ÂÎzLËÏoî‹yAkªo~°§7Í·Ú‰`= SOÇùš\ì»e•Î�ç( ÎúÜ‹` Öåf‰Åú8aý°3¼Ð¤Þö ý6º� -,v«'~�ú§=zK  ~ÛYãr]Žv}—÷gÒÕ4æÙZ¡'?”O?¶Þ nk2Þ\ìn,�'"—¨â5Y™ò¼yÍÝ…Xý;ùFÅ̃¡ùôbÍÓ‰�xÞ6(oÛ*oy¢m'¸ù0.3ë…/^¯ó5<… «*<‹ô±>&â\{cŠÂf'a¶ÅÀÚ½YÍl?X-ö‡l” Q–�AAÞ‹5)Ü[Ó*`}‰¯€7‘ÉKo¢í&ؽpsÂñþMµ`ͯåÎkZ­à£ogÞ,B1Ÿ}ÌÖñÖGe‡ãûÀ•Oú_>ªÖq_1ÎFΑçù¹>à!Wüën°èÙ€!ÆŒ÷Ò8E;„˃ˮ=Œ�<§ù;ËÛ“÷9½ðæ‘ %{ÃåÑ çÆ¾˜‚giù )Ú}¯X}O7¡�Ìp8ð¡×XðM�Z¢N̶ißU~b,CtÌS¥ $–G ïH2–—]lðD Å,J™SËlF;X—ê;÷Líù¦Y3T£3†Öaá &éÚ³ê�z9Ñ’úealï&v8ÁµÍ©+vx+ÛQÀî^gÑØ¥¸g™x� ÁÚðPœ‡'œ÷X �‹|G›’ÛY­s>Sâ'òn¬/‰fÞýkâ�D†j² ±•‹Œg�B�åóñ+Ý?Gzõà î`³XÎ9Î}vppPiÅy‹Vöïc¸Ìù{—�,Ng­Ýh£9¾hN^‚Îp-íb<Ëõò-§óÉa0^å^†1œî”—æÐÅ÷mgøé½9cÖÔo�6–këÎÄéáá™{˜‘{nú:H ¯|'·Cv99EðÔž _üã>ß,À^»9"¦áöÆV‘Úªê:ÔStì»'¬ÅBà%GÇxš»J¤CrOïêYh4ÒÏü&Öç>UãCólÄ:Bˆ\T}¦Âï ãCŠõ‘€u-èÖ žÕK®à>r´9µ;°hxÆÿ¼š¶>=SÀ Ñ ÂMÚX[ŒÉ½ûD6^�6…õä ]j^Î69½ ^þUNÏ=˜E=^°YÓë>ZQx(%52›¦\Æ k¥³5–zÇçø§¾”›úÌÙÞ”¢Bãï&Ó˜¶ã|äVòãJ}çHláFê²�q7˜õª]øðãO?ÖÿºÍ‘þ¡À¹ÀÖ §s8y²}ø©Ec:¨í3¢‹ñOCË<ýÖs®b wι¬q6ÍãkFÑõ,Å;¼z8Ï|Ê¿šÁ½p�ÿÔ ›ÙÜŒí¡öú`nX,Ñ;Ÿ©A#RLeŒ¼v åâÅ>(“±O1Äø ¼<³Šxâžr…±†ƒÅßTšäÇŽfF3x=ðbÞ~p‹#7 Ë-ûbÇ?ÃÑO^ÇÝ”/÷�ý·¾å­ÿö%œÑ¤õ�Ý'̈ª�ì.ioF0òä[*ûŸöh桘½ƒõÞ…Ç•{d¼œ(�Äù±O‡—¸õãÜÈ¡þ¥QÄY±x�] ø®—cv‘‹àb>e†+÷ÛEúŸñÕ—ZÉç7÷›w¶·Î´â –þèˆ(¶¶|Ì{#=2^}à�‡ºE+o†Õìe_ì8ó˜Ã¥F‡Ï”Xے§ FË:¼’›~È$MÖáýÃ1;ZÇ­yµ‡EWçÔ…4¬MÜáÆW'¯L€_>×íø‹wLŽ^~ZÙÁéÐç'Hñ8�.´û?�¦)Xú¡Î�>�—¨œäw¼ý _²àOdBÑ;Á8'zµ½þÄ^ÖÙOÀrØ=ì7™yÃÌ.¾xp5Øo_0÷|a[m[£mÜZv8ƒÌûé¾±{ë~kÙ:ºÆE =¨j"κ2©Âðq±yu‰måoïOs¤–û ýìï8Ͳ=¥»ùqÖ{k¾=šÞø*†¨gé­ ùa 7<ŽóÞôz:o}÷`yÛÃÐÂϯþO gÂNNýsLÍúÉq4^fb2Ÿ³õîÔp yj®áÌ[ßžÍó RJ àÍ›ìdô˜<óõ~³+±oIë1q^ â¹±£,søQ$\êL23KÓ�JTÁî514Öaâp¬~ê¢æ£Mâ�åل˽À‡=tZ˜\<ùÙ™·nëù 6l\ó¼Z–cºî|Óù Ño«&ò‚]~ûZœ®§×Ó%ñÖ™2Ê™–²Á]�qHÁfüžËë ŒcÂ7\ÙÌM3–öî1<ƹ6ÖÔ ¹ÿÕ*øzvx—ó�˜;%F¾¥3=Xñ6Ïq‘Ï�–…Jƒºø˜Á½ì] |žå5—c±¼Ü¹÷ÌS–q¥>S$ÏøÈ³çåi'’,ùªÅº±5†Ô¢­§Ó\…�äÖ7—À)nRe}ãtœ~óq£Óø:Ó‡ln�ÃhvžÎ× .ùôúzYá;÷'g1”ŸÏ&¨EkWƒ­I݃ñÓS úáUcÝGÛí¾—ö‰~%@.lãÛŒ¹QïÌÚ)ÀÇs?XOEf9‰™Ëy¤Z¿…‹)×LDg‹31€Ží…qC&fþÆÚ¬Knœo³Íœ&PʇêÉã’È÷»špàó£qøFá0œ¯6ŒæÄ¡øÁØd¾ìŠ´Á¹Ë7˜ùߤõssYÏ’.l¡îZ6VÙ!ïTH€£™üUãú†�“+·äåXœýÄ4€ü,É1-`àìé¯�¾ÑŸ<°ä±F8ÀØ Þø¶Ö|^XbÃ1(BNýĘœ˜�Oóì÷÷ÿ“íØwxq»vx®#ò �ûiŽúÛ³£G\ÎùkÀCØ¥0é?}MOàA ü«­òÒ@�5b*¨ }7‡§1MÄ.¸é…l‡‡ýúc{úl¿ìë!1 ‚ÞãÔJŽVÓ«exfx�ßܤÞQò�¿Z7J\ÂÓ�oþÍó¡«ýРŸO„·Uóò=Zñ“nâö]›åú7¹I? �‘µgæø¬£�³Ç¸œ�°±¶æoð„À#gac€­meiÌô‡ O¿¦rÜ&ðŠÏðß,ÿ3=q±Gžªwºä¼ÛgŽ–ËùS[ÅåSô6´‹§%¬ó|ÚÚ}êI,·¶VÔuó§‹`N5úí…Ê—¿¥EÔãHá=�›ð Î"yömË…5=eµø•Ú5ƒ¹{!·‘ß{DËö=ø^¬¥þs†ó¯çÙß·—ãD‡Þ,¡:˜p;ƒ)dàŸ æ­‹’5çî‹’Ÿ´y�Õz—ÚWX)ð™©1õjJïȳÆ—çïrd^p4ÝÿAókwÊ[èJmÏF€0dÿ‡>hóß “ݵPš ¶"­wÎëŸ}8mÈèÏpîcÌ.åí]0ŠÝ=IݱfD"Ë֦اƒÃ\Î.ƒyäßÙ@~Ö8瓾%&<«¸×,4n=_=ÄÆG¼êÊz ¶fŸG,õ3yt¿í¬2£5œY½œ¬3üoÚN�‘vÃ~×ÝÝÛÇ·ÁÈ#qw�E6þ�L¨ø½ÈN¡¸ó€ƒG6Ëê•išñ€D»q8 >Aòj�ÓŽÍáNxàûù�E{2¢Ÿ<Ú;‡ÍµßçM¬4ƹ±†'3ë÷�_´â}ûäÞM^ã]ûB_!Žoò»�Mùõ9¬o\¬ t.N Òà{x¡›ÉW-‰ÑNyäl€ëlÌGÀýœë`¶mç½óùÚ²£�¾gÄGC„äc¼^\�Z)fÿºñG÷ûEtåj��Êl,6ض�i:gN(<cªkýê}IÇgžÆN‡S¿øÊy}å^*´‰ˆwÂ=h².[|ÙÝÑ"^%LÎ&òÔÕ´Ók’#…3P ]f2N?šÖ\Z¿¶¸äÉ+Œi²:Æql¾5Ø$0΃ž"~Ήo>mc>‚rßÁÁ›58 ¸®K�Ý4Á•×JFÛ×õà_ÞXëo.6võ/Šy©˜y,ßz�þ3X¾ûá±û 1èáх츨ý—Aod$çÞ0`ÛýLÌ"ß¾ûãS÷øú�SÚ3÷ MplXþgÔL¾+ý¬Äpî¥Þ oRާ²ý‰†ðp=�ÖüíãÍ·þŸ{ED¾ŸšÓ™œ/v›ÉY çñ¾°ÔF^Ç�Í„uB’@cœã­»nÇC×=aŸ!~÷Ë\Š%ߍД/ßÚ¬Ã1¬ñh|°ÕŽÏMraÞ\߃3K¨9üº\ÿ“éÁÇ¿¦EσŒ†±þÐLlzÝ[V�Ä.þ]ÇÁͧ¨‡ç`YüÐeX± + =Y,òà}“ÃõÿÑu.Z•ä@®�5ÿÿÍw®¶¶óPm8i;B!)œ MU�GÝ.jàÚüú,žk>øgÚúÛ!Oøb�ͶsþçQ–V"÷Èp_Àâ‡<×q~sA Ãl]&fÃ*n¶‡¯äÎù„ÁÜÑ%¿ú-·j}‹C¢µmW®I€×€v­aå¥M@�L=1�øÂÀM¯®›vø¹BN7NSË …B™õ¼‚n¬”Ø a0î�™¡à£•˜®ÇDÊú,ÔðçAÍmëp¥Ÿ¸1ÐÎØ[òÁE; _Mƒw0q�zÓ„+l[§~ý¼KeÈ%Ÿnwí°høÂ™žÃ;§än”›ç©¨3í^Ja½(7Þ„„YÎ}Ž‘gŠó¾ý¡õ"î§ß°#—!DÞ½Ÿ‘{—ýæ/QÛ Ö[.Ã]Žyýf(:2Y€Â¬§9†å7_4úþ†dÊ”Èý£òÞK(¸Ge„‰¬?)G¸4`I.Å/ìxÀæÜÁŠNž{3>_åù`.ƒíå7ò÷ìÔ2t9ìG,ë÷´ÞSŒ9Ê>gðT}8˃�ý­€°áï6úyΔÊ~=„Íè¦ôöX*Ó½ç¢ø(ê&ô�Þµ`èâ”Íol¾j)Ú©�Ùþ ¸àÙÀc&üwë2pzÔÊ!ƒê1|¹‡>ãÆAžÛˆ&\Œå»·Åpµ>w¯2;yž zZÞ5qn]­sÄ®žïÓÄEùò¬øž—ÌÕ'1t¶‰ãƒ�_É^ö¹¯/Ç=3¸;ÐãuPr†©ŠõV1輊† Eý@YÞ�íáO9ˆê ÷Ý%¼×åìE¼ ó?ytŽ&=<'Hþ`¬mF§÷ù¯éj&?/*õ`6§fçZÇúÜ$^©brNÉÖú¾…R÷¡ê¥­ç=ýA*Ìɳîþ˜# Ôú�9}-âßý d+ßžÐißÕ}yã}…ô¡ñl5$ û,õ[”GÛÿ/‰|�³³‡&ëTå¼8‹zå>u=¿>ZùÖ©“|Ø�;âa‹"jÈ"*²™õ¿�y�èjàÑøðÖñ}„õAq€vyCóg"ò¼<6kã:»ŠžöËBçÁÆ…GÖ€Ó_ñÄC~úµcé­ZÆhÏwºLQ`cP¬uÖÂÞS1Ô*æÝ“3~¼ƒî̇›Sö¦É ·µxÕè”�÷¹§×SRœÀ‰)„ì­•Çê‚ÞéžÀÊCG±Åy¦�p=ŒÜÝ´âaÏ�yZ�.hÞ3w@ÁÃ/pöäúx0ÅÎ:­ço×½| ÒÌ£«b¸ /gyÑógÌd+I©‰V*ª+ {Çhh}¦*L>j­'4^[«âÏðÖéÔ:©=qÊŽG¥ã§åìÑ6t†½u�tôábxžÔÃaÁÅÁvmí—2I/óvú›ˆó<¡‡€%>Oîì¯Ð¸_åÔ3ÍZÉDJ†ãùr¡–³Øy*÷3á·ˆNýº^²5ñ�àxÑð8}®??±É= /z¾È‚þ†•Î_4Šóž‡!%Vóêùœ0¤Ù·ÒÓË[œ[ÌçÚºÇ3dЙí�{=�ô�4Cå¹U–6hƱJ�ÿÃX¹™wNfÙªX@ɞߌ3vAP—g!V÷Þ¹þ±E°<;1¸àq*‚îˆÀ´PŽ&¨x'¯×9—?îÆIuûÝùÃs4nâáôª1Žk³q3MdvžÓš_0‰ñ±”÷ç©®Ôî¿ç�³Ÿó‰Çˆ˜±õ¼Ýs¿÷MÍ@ÇÅ|9°åÚÎþ)¹½ò,ìHXµåüƒzóZ>Öõ¶>ž*† =kн³ûVœ!�°‚—Žö¬àü@D»�wèü9`n £vX£7ø¢å\ó iä ¼R’û1 ýÛ“ãOýšUѾÑG–ºs^ZGSd3³6FIûšXó ŇNáx•7½ù¹xbÖõitµ§ùH ªGk™ã“õâFwÎd.füÌOg.tLÁõ¿¹¬™D•ß„WÍá¥øEçNŽ{ö¸µ”ôþ©üž£Ô–³m‚�vtÃÙ$9s¤‹ãJ„ë=�Ŭy(Îb鏿ÌÄ{©÷õWg8æhRï¥SéÓ·—ðÎqÙ™Dçpà@tÑÓõS‡ÎuΚ 1p��ôöáZ Jú¼b=Õ1»ã¥ IDATg—¦¯±|©E@Ú²l¸_{‹Õ›Ã;ÂóÖ�H1à-�‡‘LöCGsç×3[2P×»ïîÑv¯ÎärÎå©iáAÙwõ$æÛã:¹„œ¡‰õ¬Ä·v c]¸7Z>'žsÒ~¿-î¯÷Zzôâƒu‚¯–ÖŠpŒì9÷ܨ—…´ j¢n}lOZm¿=ϯ—Õ*µŸðhÎÓô‰g@Þg“[†¸|ï´_¯9C%Râx–å'µûT/P-6êÍå$�Ö&ž3´¾“<ÛZ¨nþǹ¹CåÙ:Ù™ŸðÁ×þwŒ^ÒÈZ %Î_AVÒÞÚ+œöUß›‘À¥¼û‚‹æòæoœ”\±Ú2ß¾Þw¶Z¦}Öì]ÓœOù­•ü=Ë)Ä—Ï]…·¶¼úúÛ-Õ«ã·üœ%š ï\Ø;¶ž Z,˳wM ˜ =~¶§ 0×nïü<îl6�Ù¸/åÍ¥™úñž^ð­×åî/;<¼>¯�¹â-s×Q8Fø`šÜ·~(›!ï{pLÓ(&ºFßêmîëÊxå6v“O| yn b]/ä9 ñÑ%açU“?LµƒL{ÔçÝÊå2 PgÜu¨Ú«'vÖyqГÆüQä³x‹ÉGsäó`«¼Ûb¦ßÌÆ%Gþ`´¾Í´+ð;‹œ#¡e’¿¥xrNÎOû�×/v$ãB5= YÞõIAÞ/ «Ý«�aóïÕ5Ù¼¶ÓF2-ê?H<¸Ã$µîõž÷Kâ³~uN��Ùzsðªî­‡-†ûc�—ÝmóWÀJXœÍ*Dåê©cØ;kÞ.ÔƒõÊëÅöÔš 2½àbfiá>3åOJ ìù:øx«3¸ e‡{AÍHö\,IèÄZ€Ì0РÅ\ñšN ï†;-ï#Øìeª[ã™ ¾’ >«ˆ:”ñ n˜)×…>¼2Q=;ÒDÒ®ÉsàÂDY.±i¿3/€xLAîXÖÏO²?˜dó‡ëx·¢¹É=?Ç+Å-=¯|cñþÁ]l‡cç¤ÊKA�{¼“V %x7Eúô&i]MmÌ7~ x· 靯€[m^�iójQ�¾ ³ÐO�—/‡§­kÇ+�ÖŒ?>Ì_ä»n§‡@¢îõÙòò³»L¬rŸÖy7Pîœ�{:­`”þâ9ç˜ó4N9F®{ rtê¹må˜ s®ŸlÒå=Å‚­ïQÅZ6ê xÚ½¤êãSPxx .;÷h|ï5ëîÇÞk-¦LL°¸8ž ¶ë®=¹a÷άpÐåì\§·{ <«:µé%1�îÎ질 ‘è³*A1M/HspÂ]C#Žô–5Û*v÷mÇ‘°´/æS¦áL!�ÙâÂ+øäƒu|Ë�Ä‚¨åœXÍ“×ݸ]ß›ôã{t �ŠËF#p~hc’¯N´ˆqÖh^ŸÜw[²J`£ô>]ö»ÏãÑý/¾á‰Ùû©ïþç|¸A+ø�ÉPMVÃÝXž»·"=΃Ùía5óVeh�wo¼ßjsÖ#{ ÁnŸ(;é6ëòœ…cŠûVz"Œœ_×NAñËïí}ÎeÚ™[Á&ƒš÷ý“�š/kU�¿ü�EÒqêz¹?¸k̓ꅚuë“•‡)5<Œá½i�à“ƹgÉþ{Vì°Ì´ ²íܳ|1 }W¢™·“„º$¶ÁE…™`pTóD}׎ÀY´¶5år�ríÑ·•xýÃ?/ÀÏ¿<¥&Ïð}}xqÂ×øðô6DOñq0Z¿5s°·¯=£Ø‹ûh‡§7¡­ñ›c{ÕYƒ=¯í/¼¤y^Ü‹µJ µ ]×"Ç(ãyîᆟ=¹�Ã¥ÐÊ´½7‚Ú¿‚æ)ï{nw ÷j7/„/JkÅý4l‡ïç>Çh\gùê½üæÀ>go.{�dbß¾�¹Ž¤^æë7÷÷C90xžòôßî¯�¹À3A¯·)†V\ï›É:o£ ‡ç\˜>oçÃh¯¨¥§èêÏ üµÞg,ÎìÞÁ?ù{~OPüübã*¡sk­ë>ŠÁ3x¦ ­oD.¿-åšž“—€ø¢ó8+þ‰ÿO‰z‰>×/¾3±ñ—Óºb\L³k<ó?aGrfµ%ä?¤=1LÙ˜bû�Œ‰ {Ç ÔfûÿL(>®c ,\}ÝÖ‚ËC‡¾ÚÆÒ�öäöòCaCT>uö­£spVÉ9ºì>póF“/œõ<}ãÙí¼\_ÿ¾ñõ_EO×ÏeʹÅÕ]ÎÃ#cœ¼DæBã9—±ÀácX`¾zNëÇž‹™7ëSoŽ<Œ£ÙÁ\ìVÏùÿ‚Ù‹ìüåÌá“Jß°¸Wb^– •šÏmΩÉîsøÀhg¤97¦EµÅ õÌ;ûÍ«½³Ëv݇ïr¯>’ÕWéí3^]¿´ÁéÅõ�¸ ç|·ò_»Ι´×ÖÏ×9{ú††ûÁÐäZ)¬7‚%ɤÀÎõaÞœ#.8OÔ›cÍ»<.E­ʽ±)ûøÖƒ�w-4ÌYÈúO khýÌGb>gÐp( ÖD 4»}Ax!�ÆtÌCY0Å€üÎ3§�‡ŒrxÝ�=umHkl‡Ÿ ù¯\£�õûrOß6”ÝÄ™¯g›#²´Í¼›U'ör¯&g’hj}Îà]þü�¤ä Ö|ìJG›•½|~ؘ –»š8*R•3ã"ÏüÛCé¤4Ú¼_h¡ëÞ\r¹ÂAÍ–ðÏ0rS;¸ãÑÄAà7i¶zwÙ³~©Y;…Š6_?—�ÞO6Á¾&\›5±p€½¼é9÷;¾¡‰RV7·L²\¯#ôꉥÆ=4ôuÊþm°$…Nu<ÂÍsBÌ•'OhXr.×Þ 5'å|r\oÐ=ƒ70gàµl†+´Íí¯«?½ á+Ê�ly™RiÏ&ä²Ú$ýn�ÕÑ ÑÕSÃÛ{¿Ð® P¡®áK‚ØWuˆzL÷xoÌÞ^‹ƒtÏØcx¦ˆEü…"Þ©‹£ÀÇ8}TÏ(°g¾µžùœ�Yâ…¥†u\ßÚT(3_$c`ê¢�{ÖÓst÷`žWë¹>ùk¥ö4�çp…ùötž³'ûWƒÚëŽåï^3ø ³ôí¾ÝMYì;Q j¾¡s/º§†Xâ`ÓϸªÞßm±ÓQö„^�ݵT�£’mI:Ç ÕËK*[ç~´æÐ‹ö’õŠËÁ½Ü¿A7õ¦žÞ(RÖ¼9{ê¬Z™ÜßÓÖ£³þ&|÷;«xËY†,¸‹e5}-OjçîÏJ ÒÅþ\Ý¢­Ñ PÞc„@†sZ:>X�åí3 á²³"›ºçcTŽd‹Ié�º_[CGI½G³øq×¼Ô0¯—c�^³<„ÐÐËc­µÀÕòp¢Ï}wÿÁ¹¡­õ¶÷ K„ýµEñ�|î+°½VÿðýòîÙÁË)l½sÓ©ÁÜ/úPÜ?ÆÎlÜñõï}× .( ðù mý6ÐúxU®>]ÇFïä¢ÃÇWÌÍë¨Ø;Öüñ1¾”ý`šýüÚ€=„€^*!k�gX[KǪùåØÂOZÓrFñâXca»Ö¼Zèù¹^�–ŒlóL&RçÕ@zšöOÜŸjv*¤6ç­Õú^ûq:¤‹ce2G±L©/�¶p3¬±i3ˆp:lþÍ9¥?®ÔP^ŠÁ2;¾÷·!�ÿ>WûâíôˆÏ/½oøl–{ã«äœ.çLZÏËo.�ó’úàÈÁã¡+h4æL÷þö(—\¶²Žó°A´¯Ð|J*VõQœy\'@ ¯Öy®¶ 8?àúòC�0­ŸëÕŽ÷ÐtqÀ ÇÐ+ç§v>�lÂçÈÚxü$ã«b¦TÝ¿z眒Ùüš>ÞCdÖå ²Þ?’Lõá·õäïÇzóÎ-h� ýQX­C†ÐÑ `ãá¶¹q‘Ó€ò¡u,ñDÝ9^ö‡9ú9(jµ#¯Øt‰!Kï•OE /C=ݲ†Œ>|vð4ã‰ôÇCðƒàa¯ƒ·Ÿ8‰vÖ§F.í�°^Î"qû³‰œóüRƒ— sh³�qãqübwnÆ=­PØiÀm�žÂ«G­yðøê-xLÛüg¦Ð׸wFÉÙUyI„xØÊYá« ¨7ñ®�F!ÚYó±5-æyÃ>ØTû §“é5z»Ï©¯Êá¥{µÈŽÐ3´wÑWÏÚ5à Ì+Å9•¨™òÐr6ÙlF³Èê²ÓKï×W7ð×ju9'“©%¯¯ ø,ÁÙ§¾YÈðº5Ãa ñœŸïG"ܹÔû�`*—�]Ål€íÙíMÛG]!?gPs=œ Gïz›$³û¥ÄÜüóËêN¸þ>cëÍ%¯?°€S÷Ãð‚®ó8¦@îaîEòô›z® >“ÿq mÀÁÀùñís‹>êh­+»áò;¹wÄ…ÆT‡]r„ÃÇŠ~ã‹l¾_8-Õ:ú‹Wê4Ñ"Ü>År€åyÙyAp´C.D²9ƒÔ]]86 Ïúph›ê¥�-дÓv½ù¿—ªzGÎ.éQyÕÜû>ß?/»¯Nj`”mrìóŒ°*»f´y‰ƒ÷ñi¦Ö\ X|}LöæKuà.ûÖ&·Z¸Ea®ùS@ïÇËÒ£ñ|Nµ®(°•î3Ùc¹3U×S µN¯y>"<1ñ¼Ø5síÀ^Zb¥ù¸?ë•/njo¶ê™‹ã|]YðAÍkžÑS•÷W×AUžZçã-‰lËîg«!^ZšJ½¢.t9çĸúyëÜ�ï®ýú}-Q ýÛ‰Ö§/ë“+§mš­5‰ïl^7öú³ÂÑ™o³`þwTw}àË/áâ"ŸS–7ßxÖ$îã’ï<Ys›Á§÷ b»ß¡éÇOË�ýðâUo frÞ oÞ~M9»j̺Æk ­ûéœgá¨|ò¹óTöðbê;ãˆ(ÞV|ï•�É�qhÚgi|2Çt‚g«yÿ­ADH¤s&{äç2Ðæb•4…×Jƒãþ ³ÙßÜ#ß³[ÜØ6Ln㮉ò²ðìßðG+ãS�Ž}(wöµí‡“¨×ÎùÌWÒ+ûç7Eâ³V™ÿ ðx·"Š9··þÏÿBÂ’0³W œ¤²~ô¹DüûW»r˜˜ÈÛM(¶Ã"k:ŒigO=u`àxöä|@ÞÜ8Ûªdù\9hö8æ£ûAǽ½çãU;áÏCE²¾¨óYûá¤ññ>]ž³yKà0fþþA‡æ9WiùíÕìúÕ¢æó�o9:gb=9¼‚}øê(|•˜søhàõ‰�;gUÞJ1EŸ zÐ Ýõ¥€¹87X^?DŒg±ñú5_x€éõšØ×Û¯þñA=Üø¹ª·sœ‹†ë”{ëÑæ- †ù&]âH£Ù€Ö[cÆ�IôKiííEÅó;pŽ57®Å_zÉÈ™‘³Ô¯·?ûû¿„‡#_HI Ï£dîfåä៿ÔH,õ4P’Í&2(µZâÕ?©9ÅTj­ÆÜ�Ƀ‡xgFÊÔó~Šk"ù³)KôâÁÜ^Ùs�xK0«œÑ@ƒ|8¼á"üi¢xMû�“ëÍ{·‡§ƒ{b¾ìçù½®Â³ÿ˜3ò}ǨfZs(«÷Ê’¡›K÷p¾yËÀÒeøœE|í`é;䙳Îî.öXSìœ+‹l¨r?ÚÚ-Ô)‹â‚ÝsqtÕuC8x´­µ$|ÎÑ!ðÖ׆¢Ó0"ê5‡—üa5Ü ð䞥6Qgt!6ÿ7³†QÚœ{®5¼óomñÌó|ºVây3•Õß³øã œ-Χæ-íAZ?ÑÏ1§Ó`Ÿó˜ ™¹âß/¯©O¹›§o®æö €,#Ïtz¸XƃÓ+<<Ë ]Ý¿7ç²³õ\dã€ë%-îœaÝî ÍY»Þ˜9‡ ûm#Y'‹÷l��„wúÁÝ{E‰Ÿ•P…Þ½çÍ“�®ÖÁ [jJ%ÝÜÏ)ˆ—i‰Úžuå�‘íìñèž¼%ÎxÑ$®ð¯~ÇÞ~�&©Qnè­œKrf°™b�›ê' ÿÀXQ@švvï×°(;gý‡aÄpQÏŠÙOaž|© aÖ;Æ’ú`È\߬ÁQ·—*BïŽw]°‰¥)ÐÁ¶†;4ÞqØ�7—‹;°Á¹à®ÜáÝË‹veÎèž| µá(]©SzÊ‘¶ž}kW)þ[>î­{äþT{z ‘"ætˆÝ3 öž~ßa­ˆ\n¢CëK�€£^fÿCÚ vÂ߀` ×CæÏç¶3©ú³V|çë·ÃC� €¯ž�ƒ8ãpñü(¨ý;âu‘Ü l«…ŸóC=qΘõûú¶·Qkçü¼‘3Ÿ&óLúÃLùÔ³ë«kßÛ/Ä,õFm¶îk5žUä7Š� 0úʘ4çqÛŽ=£y­Ûþ´­œQEš|'1i‡óµxРvý8@SÄðMÞAꣾ=™¼™¤¸¢ ‚ƒ¥ù=‡ÌÜÐéÖ`À挂+©ýàÉ\øÇnŨ¾«k.¯…]Ÿ*º¾áùŽQšG©õ êÕg–—ã^!SÆúÇ0väôR:-�@ðíÁÏÏœù¹ÀµÐøÙÏGóN=žV³çÏû�§>wp•×û}…bÛ?tž¦kø,µ=%%Vã�4”ŸØŒºf XF›Gø¬1W?躘Ë×¢”±Q¬2^µJøAëõe—¦u GN®þ'©ß±bÅÁ™¿Z@à Æ�E¿˜äA=�‚8ȳ™b�C¿ú„“£î²|z»uáØ†u¨)ß%J…{ Èù)D?ŸÚùc¶Áš,ž\lÀó`6Ï4^XÆœá3dîÚq.z¹ß�Á�²ŸÜßà�<\9[Ã?ï70ìƒ{§·­µä]#Zä6ˆ€ÛYøÓ{*†Î¼z÷X*êáqLE>›õ†Ÿök†ˆšŸr{UÌÂò†¶uì�‚Œ_íí—§ÖZ-ñ‘ò¿¸­Ý'ºÂX°ÆîápgŸûßMØûÁ.w=¸fñÍ”=gôúp¸š�ãl0?>…sÕ‚þðÂ1�ÃG^qH=r *`1,î}œ6™Ç¶ dààE–*êœÒü|ÓTñϰ§Å4{¯;<ƒ åÌ?Uì'£ºëMçeoœb(LbßüayºN$×%Ïõ®^CÔ»ˆâ©Õ™™³q±LûþæpÌC”óžç*±ô–aN­¹×˜õè„/¾Gü!*;c|A/›â�ÂVÑè” {÷ÄÜ“Õ2Ç‚~î Y¯ý_qj«Ù9EoµÉÓ[ªSs«�}ŸŸÑù9ïO;IÔ¾ñ•çòÁ<ü±óºw`íÚ�x³žö©&ìâ;:éâPn¤ÏFˆã)=ÀñwÄC¹•6…f·ÊFƒú3ŸX¥œyú=úî¯*ÿrœ?šÿ’øüfõœ7gUO†æ¬¸;9|Ô7]Ùͼ£9øV";1Sn—ç‰ÐèFýzº÷ bÕ[Z�Ê‹nNþéów÷[YG„ñ�zbˆx§5úó—Üdùu?— œ“P…ºì>øþ¨�ó_e¢Ë=ßÏÜ›Hæ¬Á@?Ç(›%ΙN+X’¯¶¡§§éà»÷C!ëX½µ* o´¨âåãraOâX>:„S•¹E„Θ÷8ÏõÈzÑïœ^ßþ ÔDÍXg½%—ÚôòùFŸÄw&áŒ{ñòr’‡×ܺÌï*܈79çë yf>=¤0²ç «*Á×y™9Lœ‚Ĉ3šf™\Ýàüê&Èç{ZÒÜ�ò•×yÕLÖ¾,Žsµ~û‡Âºçz‹Fì/nÃ-F÷õh5×ëÒ1¿ùü)Ì>|pKGQ¸vÏ��‚„‡6럞ÐpŽE6{ŠÊ—{ž­á{ù¡£çŸaO­,-Úö9?®Ë³â3–‘�ýu³Þö¹g^Â/h½·­±u üÎæp ÜA�kÙÛ|ú6^O~Eˆ¿žN<çäÚjÓrļF�˜†å¸x�32Xûë•H?ǨÎÒ«�‡òPtÑÍßÙ<@aï8ZOͲhŸáC�ï.•âŒ`>&>2ÔŽgÎ8“ûÂæ�|ðR*v.�‰£óX†}ð“wal~ø­-u7‰jù?Ïzõøúð“scöÞÍëó˜ç0Ö _ÜÀÅ,º÷O÷<|Î9†aø�/wôð¨Æyj·F‡>Ü[<çx:›è»ZÈà‚ÃW]سi|á—ßk 'ÙÅjðÒÐ÷¾AÝ̰šs¶—�({oñ­ÿfÀëï0’à%’.G‹Àž�à^'¨µ5HBdcðï(ŒÖ§nœÀleØÕž a2�µB}%?D� Z”“©ás€å/®kÌíYÇfkæwØ̸X·þú yßxå�c> |g³ ìºãyÖÞËÖƒv…‚~s’û®í宣C�cšYÝzíÄÏk?Ú�·7*”g�Ci?'Ĩ¼ä'îЭæWß«êÎÐ2/…ï�"ž`†j~}á•·e­1 frëÉ â7ûƒŸÍÆ·§¯g3X*šÝk¢Æç'~f©| —g>¼Õ]Î8z÷pqW‰ ·zë¾ÛÐâCÁÂu;í¿}‹`~…dóžÑç< Q2Mg�áãŸ@ÎÆ´Z£{û�ñ·žÒí×㑪ÇÑÛA(â­ !l‹{Þ'¯Ü9/8DºÜ<°?hJè³ñº5¿n hâЛ9!C‹©¾Mcô�bÎ[åñ“â÷ Öx‚È…gÞYZ—¨µU?%óšDsšç!öu*œ•^ñB H³<õf`¼Â圮£®¬`7·õ9¯šý~Ãfj¢—žYóòÉå7ª�ê‹WôôãçSeùm¾Pé©…—Wçì ãBîŽäƒmÅIæ™;Äçœv¾Ì‡ŽµÞða/·L|W“Ž?uÔ±�'×ÚfjÂgDZR€L8Šq=—ð¬æxS*ÐÊ@ïX 5óeL“Äç¹Xx'œö9œû£\ŒqnOlœ@¼Ö‚êT�ÊúöpÏÚ5ö!§!HqÊ× Âmü�Ïô«ª„½Q¨õ©×û·Ú朑ˆá3¨ þ×'aŸƒkîÇ­ï…k`™Wúe¯—sá1À°õ^N'ùÄŒ]Òlg jß·e±¿ÅöÓÐ2æpUìæ;<¾¢Á[û`·‘ÕîmêSS6÷ôû £ ”ªÖêå¸xó›T€ƒwV%{v^ÞÈ•«Ú9£pÞÜ G…+^>—æ4áJ¿ì™\xn«»óúH±Ð½éŽH}nÿ·¯èäøóù&%!>ôóÒûd'ºÜçÃH¦uš’{¼TÑæbãm¸;ÃØ›˜çcÖ¤‚Ï êןa°K„]zUÄ éšy]]f`ç~wÝvÍ{rǃíHQ`x‘àåÁ3�ìÙ‡%HNÓ%FÞcN¯ÀÓg>?oý@�{÷¬w6ö¤}z‹&Ïâ⮳~½ËÅ}œf`(G> Š{á¥úþm‘+ðjÑöÊ�çc�íô³vÂeî&´ÏdzΪ+WÒ NBÈåYêÆò¬oýîíõ�|˜¦Êpž 莕Œ<¯ÕkÆÏϤ˜¼Þl ž[Ÿ€£\\Óy< ~›«#Ò2ÍÇ�xϹ Ÿû–gÓx—ñÝØ¸§mkÊ[®ÄÜ�¬>õóZGžœ6I `¬E¡ÞwÓ}kY#MÍpŸ¼ûMù�+àâ£GØÚ`{îgßbîÞòlÆÇÖ¤ÒCAìÏÿ„£‡¥XøÁ¼ÎØ38/Ož×Ö’ÏÛC€äög·Ð>È2~¿f7?˜žtÖüw§zA µTà´¯žÝÀIükA‘bJFyFÈÓÛb›_OÄ„ÅGüí—˜ìHIT™¬^£Ùû ·§Öů¿Ȇ2S$À0Y–ˆ†�É­&oâSñå.70æv%f¾ cÑiœUê3ÿê;¾Ž–‹íuýD·ÔÐ!øtœ6Ûë:aûÖ™•@q›ƒ ×ÓÑ«.±öHo®d.ï>`€9o ›¾4áÎ�¿n$œªÞ�SÃbØÍë‰Z²hœ3O(\û�ãâ'Kî7}¦}|T[r ¹¦÷Áç@_Ô¿ ;–û–þ]¯ ¯È½ož zíM:öž¥j²Nü½‡ö*ŽKo¾§�ËróhCæ"_²Ÿ—ẇóâ롘£÷ø_ ¯¬íDëõa6Ŭ—¯\pI_Æ4Æ:ƒ9¼æ^/öÜ%óåP/ó2¯„?¸J9Æ‘ùõÿ®Gáí'íMk7vì¾{¯u?Úó¿óŠ®íÃ>bfžÉÅ7 vñÞebÚà9±W4ÑšêĽ=Á+�VÕ¤€ûëHýSLžXxÀø|Ξ¸Ó¤4Ä¡·ÔPœX®ˆ²úc eí3ËïˆH�^o࢑œ�Ö"N²¥¿z®ÄK) IDAT#™W8Ò·× û^‚ð‘KŸ#4Ð4ëF<2rYÝ`¿ú»ZÍÈîù­V52«Ïì31çÅ’± Cˆób³µ–`¨ßyîŒpz7÷ǰ©o´íË >Hý£[Ô¹( ®ÚÂý”PX à•*”ICA¿“_>ÿ ÎYú÷&£ý©ÑÎÀ¢‘ÒÒJ—٠؉ŕÌ:÷î­U&yLÎBŠÜ±8çgæ¬ïù°ïç93Ú‹ ý“p�ÕPx\›ç—™>7¾Zóoçáª&üÃ¥“an�1 ÛK@õAe>'Ø\™¯çôQ)e!�'½xãÐ=SŸIyg5w^é9Úã7¥ÓÎ3ž½w¹¼±}\G‡ºØ&.†\�ÿ�»Î9³Ï™ïš ‘±Û€çÿêY¼ó›¼ç·"ñ«XŽ÷c~g†cçD®÷,JrðãµWû¤€tÔ'ü ï«5~bÖ_ž°†2[ˆ‹8¾úøêr.Í™êâ‚ÑóZÖãAJ\·b€µsfèŠùà‡žz úYOà³.HÓ8®PVÈlØ·ëqq‘Ù ñØÊ‰Ýc“9tiö%U±µ!Ûyç8ܼ<ýÖ6N>š¢1ÏÀšw…ð'î@ó¬…#÷cÑÞˆÛ >ëÑûqhþð{xRÒÕ˜oœ‘–îGٻŖ± ‘,~hÌ6r¼€[í¬ùñÛƒn—�ªð­&·û5Îí)€wz«ã–OÇ5\f@ëå6Û,÷@g Ô5Ìœûœ?1ï‰õô‘ñÆ{ ýb*´Â“Åõ·Îž…gËœP°o5ÏŠÞ¼sìãÍ£U›õΜo–Ȥ˜¥ÐD¬ Ü"¯Ï^²àTo»Zû¯Vj¿±¼@�؉uŠ9ýÔLcÌÔÔŠÃVPMšŠÞþ®´Å“9zZ°Ç-_èrhx7ïKÞšæåñÚçÃJCS°9l‡Þ~„=^·Žu+=QsDµTÞ/Oü,žºñ8ííªDøXp nGêîßdu«1D›—·ešt–ü5÷ÿËí>o>q-â7éãö�þÁګσݺc­�̬—ÛÞzöû‚’µM-Ñ·f¿±¹ÞâKùö3Õ7îZÕç9*¯Ý„åÖÌkâp’sÞÖâ7>ÃÀ´Á”ç*™Ý#û®¿@Mv9Š]£Y}8§â—uö¾—å ôå±»záÞH)üþC }jM*ÜsðÌëõs#•w+=àå¶g¤ªç{ÀºÃ½5Ïç#2Po¼ëÄÐÈ™ÆkkV ÿ„éá€Ô<Ž¡�áX½xR~ÖìK°{ÆO�–ô3o›ƒˆ7ó<˜Ý³aü¹pw}6^`•—ëìû›·3 ï\ÉòE…¡=ÄhÞ~‡qÍæ§SïüÝO5÷\ÿZõ<Á-?w;·¤²åI7B5�)¬¾�&˜W4´ö!’€$¹ÑY›‹Í¸Ø—ä¹òš×í�aÓ#^~5Ú?Ô.�oqØ[4ÌZóÓO¶Ü�|<}uÑSœ€9…û<5ë|ÖF›š#Û¶Ïxç$ý9ßò±äü£ŸçZÞÓ¬{ojÆ…&¸d9’Ôgî‘Æ£ÏáÞo*Z6j×®&œ z.�† ­› WÎÙ}(θõÙ'&d󉾛›£‡›�=Ï‘kØjølÚ¸ñ§'É;­¸qÁkë½ËeçÎì±Y´â"©s£W*|'å‚ÖÄ ô’Ùï¯\ôZ†ïz]ÒëÃiå’‚‹Àû/ªçÐz‹n[êý0·ÂuùÚ#v=?*IT”ÂzV<õè%Í<îF´OMÎ`Åar¡öÂWž‹ >.8ü”^Îß³Ž:ÒÁ!�.ZÉùZ; Ùk}Z£¾LáþïÃsú6.lèE³ÅGöݳWª–ëÙ&mL´!ÉÇñ9û¡zµ�}¶àÃu¶„Î8ŠÌwú ¤±æ8‹ë£¸'0ãºɨӄ0“÷ìwµ˜x6uK ‰eYÜ{þXp­± žëû¼Á5\ÛG{;ÏÓS’ßEº¥aŽG–Ww}µúhÍ"|T¯emâÖÍ‹kkŠÎÙü=£qjV`-m¬ß·û4#ù R~{4u¶Ô°yÓÛÑ`>É16{óôŽrÑvö?/îµ•Ð¯Æ ÍGžn?MÞM\¹E—­·ÅEîø©ØB0îÇE?8ò:‹ßópÑêÊ͹ztÊæz:ùá]¯‹$?%ä_*xº¨ýs%q GWšÝK÷>ã­ÉÔãý¾Xž¼šá&pÐ&ò�¦™`o…ª9O� Õ ì6fXÀóM¡š¿yš!/�½ðA¬q«×B2NšqœºÖæÓ®½iSl�äA{â¡<Ä…Ùkÿ}øz‡‡JºdÅÚ½3ï• v´©¯XÔO³ÜuꀚKß8³G³¸Òñœù 9®rØ_àf‚M¿1#ß|´âóFÁ É|O=Ò†T›ØxüG£ç?pÃÿΫ„Å:Ò^�`o>•äÒ�öõÍ´ƒºWã  .5C‡éh.çe¸« ãÞùÜüëbñƒ­ìÙ�šžßð 8?oý·‹Ì‡^~V>?ƒÅ�–Ù=S¢œyÆœ }FôUìZSú>H†€��ÜËÖ±{/Mùá Æ¾´Ü¼{4ÎÅ͇deµÊÐÌ9?öeF’ýøâ7†‡‹Wѵ�hjƒÖÂ"€ÃçÎ9]Xóz‡DÁºÝÍ@»Þ=Y qº]&Ð>÷“žã©Eç~ªâ¿x¡~óilº³0-HÛ/k<%F?xùž[<ŸûTçÞûDÖžX~†¢MdŠ (ü�Ĉ«â­Îš3˜'ë¶±¨*cá‹$±QEÜgÄåƒoÿ)ìÝh£kkºØ§ÃW oç ƒ—T溳1ÆVˆk¡÷¶ÁÒÃ÷A«ðñ±Ex|l´v‰›„¥ƒÅ‹¾Pž˜p§ýñWîœÝ4S»K•°“”¦U®ßüö¡ò5ýà6=Ü”MhK_‰ÂïuSøK]«8_aÓ"ïæ ºÆ<šÞÞx¬pv¼æsÈS×È´‹§†a�,{àãë€pšÃ~ÐoõJäò" “æã©1âÓsHøs>¨g$‚pçž�ëJ¸tµ¢9�ù6¡¸cμ×ýü0ÈTÎ;'zÛ¢¡hrŸëÅ]Îoþ4ÍüÕ¹aÒ»4L�î3”†ÅS*Ò÷£ç%êtÕ~s‚aæ æÖQà7nLõÍuŠì¤;Ô­ÑÿÎ I“KÖÐê@L>ª>ÿ³VTá?=š«†}Tcƒè3¦‘Pø¢×ˆ(²ŸÿóyñÅçC`÷ Ò¾eöº"ϳW^òNÅ®©nÕñ‹§fÍEÅîQôÇ!¤óú=³¡rOê§?0>¹>“Û¿üëÁ1—sQoüpÈû¯ïËA¼¼ÿÖ«Cô¶ºÐLçö˜xÎÿ²fuÏ–ý˵¼ã“�O·h¿A —>&ñ'm�{ÎÉB˜Ï)!,WSù¡mΆ>ü\µ!÷¡ò·?÷ù¢‹†O/roÿË»—õ†£6g=,9§?Óú¯1æ¬ %9>0ˆHÖìy³ ×{å*ðh¸ÞeÅZ—lG¹æ;iô„¿1Á;f†äbíxê²àLæ Vx;#û[}so>`»iiú�~ðlž„|>䋜2g‘¼"Ôñý‚Ï‘8æb{ÖêÞ6pÓc3[»ë¹á��9ȼª¨ù�2ðxÎý8V�pŒj7,¥r‘„s:Óç3pu¼…HWY3O{r}Ñ«oÙ™À0v’Û?'`†åý?šß²ø|Ê`}ÅÍcê§Ç)ªÁž¥#îëú8±C -¸§c\ù|.3J¢ž¼ì¥Ê74þÍÊøŒjÖ�oS«ÿ‡Œ‚Î<Ü„©¿{âZaÆÇóÄ \fÇÉ=|®­©ã‚³C¼cZ©Müè ³³#³×ŸZ•Îün5‚Ä0&pk…?¥Ü1좛7uØê „õ©2o O#Ž­5Í1móøâ¥á¥W÷‚ŽÕý×ÃÞX¾ç¹ÐH¨ÛLÈ~½¨—ëMÊ·ŽŠÇ‡‹üß¶’W!¡ Öz÷¹Y39ï‹û*(³sÚž!s ‹S§JcÈ=Ãzï>𶢋w ´<¹›ø®£Aì£5™yÖþøÄzõ;èu¦¥§Lý]_>ó,Y{yCÖ°®V3 @¯ôÃÕC}Ñ(çn¿ÀÍ�Š ¼˜ÝûP‡s}Ÿ™{gâÔÁcKÕÆcà´FóðîPZÎý»"»3!É›0®qŸ%\zgíg«z©q¢Å—d>HDw8͆MxºëºûéK+\áŽažò�òZ†Á>ÿé7üËg—¿"²õç0ÜÙÅå÷æ8¨±OÖzÙK[Åßê’¼öíÃõ{vRNxè;½£²5áÔº8©s�^΃ü[Ï®û”¦&%[çyØ1-apÄ1üb±ã>ðt ÃåhëÁ†âæˆÍªÕ–×z¸ç*¬ÅáY"óý0É.¸NïhO†¿x„&.£ Ù$•ÞÔóø‰å•û·}5{jŽêbJñ¹ßˆÖ÷žó\T¶Þ­¡úZQ”j9Šh̘�epè-02£—~8W|9ùðGØtFÕ—jÏj¥p͆¤W*Èñò_Ï Qb¬gi8Å ²kêX~A®uØ™õQÎŒœ5]­¸5‚ãx…95\�ç~`ɨàŸ0“.&ÐuüÌœ)ù;­½ãóž<»ôâÎ b?ç#hÝ.S !à°tqfÖ{4œAbî>žÓÐ*YX´ŒµS9èØÎ,}_‰³ tba3=.ÍÑÉ3Éörºñ‘h®ŒÝwíJ`\W‹ÞÎqöûÁÆ™ŒMý DœîýÞß. µ +eÃ’ÑÏ¡VP‹¬ue kìÏù V^>\õ󌙗z�z�ÈâvqCÞÂ;V|l= öP¬}húHDo]Q4†ÃN`/óEÏgiñ�}r…i‹�ãω‡õ~Ž<Šá¹¾Ç²¸LœsÁÐå’ùÖ“†®RzëÀå¼[MJ¸ÕûãÇ):ÓŽøŒ‹�õgHðjFnîEpã˳ ow¼ü‰’?åh½pCx¾¦ÁL0zgiÜŽdwÖ¿„ô�˜§–°¦$·F¬ÕÓ$Ðp•4Œë&Ï|)bW¡ü BÕZ�©Ó'¼÷ÌòœØ‰Ÿ‘ûÙóSŽ=>ðÈØyijþÓÉ^ZûvΜ òô‘³H`¿Í–_‚‰öÅC'õäc„Øþè�Ü”8¿¬ãµ›¥ÏŒŸéÇÚ¡fZpã5\ß³Õ2ƒYtÆÙKÎÎÊÊíìÀ»oNêÒZˆÈ9ïšÕHzv½ö^ß#‘¸îd …˜¼.ÕuOB:wiOÞ®)Æ¥ ÓÏ8ÁÁu ™ëZa½GA~íYõy»=\|û�¢73zcɼÜé]ØWì³Cë§>ý8ªÀa9šAåšl°æ”{†¹¥Ažb‡OÄ='n Ý ÇX ;<ÍÉòÅo{rð¹ˆÄšº€[­çjgÝ´«ÿ°d©Ô<™óˆkÃ|ÐèM ¦†ä֜Ãwªy0ï8»7þ®_°ÖŸþØ7?Ÿ7ú�oJ]Øçž =ëaÿçÿÆFŠÐÉ€Òt.·Aç0}¨¢R�ÇX·¯0Äg=ÃÍÙ|æšYek&ü @EͰŸ€¿ÃÑLjÇRï«4DØgNЇ(¾·<9RëqC®|;¯q¦�ÅKœs8•7U3o =×5o>è|�Z”š)Þñr²€‡&yÖ c‹_ Òð0ŠËáM�Õvò?.ƒ0ϗ׿½žŸ*‡(g›õºÉ= ãõ‹àƒS†³Òûî º®uiî1ÌaÊÂõ=‡ù,‰pp§ŽÜÅZÄ}%®[�ŠXä‡ã“ð^Ë}ææ\4£�×û¯j݇ê?ýš>öqøûÏ!€~bseé:„±ï Ÿ¸Ã�mªV·ç'¡w^¿¿ñÜßôBΦ¢{J´Í7JˆhÃè”Í®7˜žÙ¿}ÂÓ3\ ³…¢ý$9×ù+ƒgÉ"Šßت3—ÿ�œó�dž#XÒ[ø²^½=[é�óM® ÏaÀgžØ\==å9QDkq“ë×ùÏMR�áÒ˜Œk²ñ¹pS]yZ†ŒÛgxžVód³‘ÅÕá듲ÉÐ[aÆx<çÂ#åõ¡Ð[†à�÷¹”s^×Ëñ!øá–^Ìcâ°OóêÇÇuìL•ÐÏ=Kþ8Œ‘Y IëÅ„1ïoÛÁ�!ÿjôÎ0{«³%O¡�^'`˜ìDzz^»V~u]Îó0!‡�Ó·ö Åg©ã`^ÃPË`®ñ%ž8ÑÔxåä—£ºÂç|€|ïâzlÁoºê§Ê¿Udpá<=n~–×ÇÈ4»Ñô&ã}v©¿á5rJ5öW£�˜¯äE‹æJ–Ý7¾Ú-(ˆÉ9WHqx~�Ú¾±oÑž^ª.�ï[‡¸ÀšgæÔàýl~2rü©7ôJ|îc˜êù¿ î/Ñ匕I|òŠ¿è˜ †×iF;«8ž‹ªPVÿ†vn÷=sÁ”XŽK#¾N8§Ò¦�…2øÔ’»=˜;$õ޵|LCµ‡¹níé÷àÛ7qûIÍ–9 ®ÓáϰñùÛÀ!üçÂgŠÇ¾rî3-R½³óų̀ò} ÖßúŽ·Wgž×ó=‡pŸeëÈë�Ÿ:'ÞвžS^³J¿7glë³^@GíGžvN×Û*9£9˜ê–Òdë©§?âQ¡½ù`á Ì‘ƒ]„™<Iµl†gâ»7‹rX,�ÛWó¤ý›¾d›w™.í ›hO&y=ãìÞøÖöÍÇ¥Ù=ŸõÃá¬ûˆ0×Z7Y^~ˆâÿfŒcüçäHô²›"ÆÀgN³„‘¤æ68ñ®iö4|ÄÊ;~mé 7£BÏŠ¯¹‡ •ÿ§#ª÷ôÑ}¼ó8ñ׆ߪ=bø8ý¨æ=ÇÇcÏýGkòkñ:�çÁš%kÁ·@çœÃ�²:»ÇàûºžŒÕVÇñzCÞ?‰ªÖ¦ß‰OÊ\lô:÷Iý`ÎÀyM`�á[s:%¿Qó6fÏfTñ¸]xGsfÒ¾½OÚ£{z8@piÁv¹ÔùEÜ}>Ñ�¹fÀg™À İh¡I`½x?šÎ ¨Yø,¸:F� <ÏVŒ9 ÷Ù—lž7–³p©$M˜~}ãŸl®æfYn–ÐøL­MêI¶÷P'>Žx‡!G�E¸*ï�é°¦ÿ¦EÎ]ÎWAr~±ého>𿲓{yΉˆKUv^ k�&˜&¶>6û$¬[_‡' ô²µù�Áï”.sC¤Ï®³w�Ÿ�yîC¸Ð£ª»-ŒÝ ‚ kÑ—ê\x{p¬˜)¸oÌ(ˆüÂÈ]Þß&[Ì9S×°KÍöàÒ“@¤b,kj´�’¹/Mz"—²øu¹£�Ÿ!XµY1zß�Id×ø‰žc‡,÷dÛ#¦/¥ íï³Ó@õ¨%77i’‚ЄÛ,¾ï'H¯ñ—]pÓ%ÆðÕZé=ç8lbÃ�ðÖf†C1E;IÞQåÈWØå>înî°5• òw¤ŒÌÎlJp�u‡[qÿÆÐÂÉuyzŒÞî×6ÿn¬W÷íÏñfçðÄ”O_JVØ{]âÙe^û,gxuóÝ7qòq�jñ�€õø·vÉôxó?žiÖ‹OQ> Þó‡±ç—ÿ3\îÝ;tâ;cbî�`ÇÉi?æÛm8±þâ·Æî>Á©€»k¿Î³~1h­–}¼Ã9ð3«uxÊ ˜tKƾËÏ0roñ–7àÆt�¿=;ð°æmã¬Z4,˜ÃS°½¢Éü^†Ÿú54}j( î=_Ÿ_•ìmþ€‹§á×˵-šêáEÎÄ·f$[ë¥ÖÓ$ŽÇ÷~Ø;¾W/ y{°†Õ>÷ó<X7>;xJ_îsFUc=íy‹™x}ªÏÒÜÑÕCt`]ç®8g¯ˆö“+U¼i³ÞzX'®òp–ØPž­ûÌ»{aWâÛžz^~äü@T|S©—š×Ô¿oœÁõaBo1¿ç’ù?Ÿ¯â/ùy= ÛÃËI&o9o¸—WœmÇí‰@±÷€Èhëór1¹òÌ:Þ|n—I« j¯ïÁÝWk’Ò8ßðQÌœ¯iQõsV~üØ£m¡EB¨,*{’ñLÂPû~ã·èGk^=ý:–ãkŸóà£ûŽcI¿ë§xþ&�ίŸ_íû½¢ß žÙ!v/!M?¼ÑF¾ùtžCÅØKq°÷^�{éá|Hs�}F¸\^ÄAcwN+„Bö;«÷ü‡¼Ãglß'’>¼U¢¾Ö×ïÅ`²ðšúèσÉ|áL;Gû<2ôã´.·7øOøY y¹/*È¿oŒ§ûE-Ç#ê8�øcu!CG#=wO _Œ‘œ=øø …ñs%BöÔØƒq."“…¯z®ž}4¹{Œ T|�9︘MI�¥Íü�¡æs~‰4ÆÍUzRµx`o/̼5þ÷kÜõr5Ã:h�zxôFOä‰[˱¬á¹qÅö9¢Ty“!.È4`¥~¿q˜èÉ8ì)v̸r¤_ò˜ûl¢»Dž½í†¡öxrrzéíƒSyn†É=D'q<¤¯pBÅO�ð¹Ê©Ø÷¯çê^n3ªŸVxÂG‡š Çò ¿…š1çžxø®6„C®rß­ËïæÀ\ÜÑWè]§¨¸Ñ�ºô`aåîs¹3œnÎý”þ4Ì|x¥ÖµÏæ�K¶�û±�Hð˯¯Ì¹†ã~02vñ~B¯©‰Ÿ9<ùïQx|?ëE�¹?ŒËK«:q‘Ÿ çº1¾7öÉaãÑ'gìâšÍƬExÂÏþó º„]€.yh>C±Ù›·¥‚{Æy>h€YPsø8Ÿ=ë—ëhO¹zf¿g&þ÷ÜÉÑê7Ó=òf�t€qAê\¢ô9W`ìõfX¹ðUúxî¿ñèÀËFþ<©oJˆÌ|ä}0ºBÉ­ 3/ýøl\/�¡…›àUcŸað{Ì[Fðèx‰¡6�gæzo‚P”Š®‘õž¾›2°^a ÿ_c%ÌÓMýSAù€ ›ñá%m˜ÑûÕÙx¾´Î P�w c4ˆ¹ùØÒŸÏvo•ï)¼Ö¿C˜÷©ËטŠ~ºjÄþ5 IDAT{^OGã|š˜ø:PÃwyñWW¹Wƒ5Ú~ Ÿj¶ÚðÅ2héÁ~Æ@X6 N�í©Þ­Õ€…•ð¡Âݸ9z17kø4�=!âªcxí9«á˜S÷Õ¦fµ^³Ý‚¹¼ ¥vöàûãUÅîCÉÝ à«°þCnÝßðóCŽ·=|ËÙ‡â¼o`{8æßß.'ýå^ß/°à0§~#ñ¡`ì·o<Ìí°èxû3¿£Zù< œG$ÔKªüñ”Fë®çÅ•ö•×#¡uÎCÕ`ôÂß­MpÛ*º�á¼ù³…Â¥eû°>°´h}öÑØùœ� Þ ¤Ù<.§èîCžwoj„/ëa^ë=¹<[óà_Ïð®!|�É9= –Hêþ䯓!ÁëïÈù)Nêµ®õ9 Ÿ�\>w•!ÊÏñ=>H@…tÅiîp„/‚\ŸggçävTýÙ÷sZ 1¿™þyq=@½XÇO+ùdn£ìë¸dXÞàü7|&Ú¸wâ7Õ5>‹öÝ«­¼}ëZà´Ø®4Gö’‡“<~ìÉi.Šú|ƒ§6Ü=³ÚY7[ž¿«:ïk<öMÉJ uöZL™ktÉ̾$�´‚XƹWtÖðéÁ ·~ŠOõhÒ÷pŒï�A  à)ù=ƒd8�!ÞBÔò:ôÚÁ5g}sÄZßI�3æiú$αŒçnq|Ó:�î< %wÇÖñ~FI Ÿ? ·|e~þ™bE�ˆêë�D8ñ-<°ÞØIãà€§Ã¼ó >Zé‹d…[àþ[cS–!™¦ÇË-…wvo+ÌÁÉ 0 xp–ÔeœŽ+:\f 5àð®LÜUkÏp^8Êxñ…éY ¼^¯WXwÎ`€p=ç¬ÀþÏuMzÔs±Ñx׉ä=˜ ìÊ÷Ç�Å¥KŽ3j(="Ã+cyvÁ÷K^ï¹�¹øexÙ�×Ëg¦­•?ÚÊÅ <€Ãõ꒯לzŒµFÖäιBÉK—« 0Ôš ˆNß¶€Ê�¤“%¢å8 Šf{fJÙ�›_ çHF?º¹â%C €g´g)¿g�ÔL¿;ûæ™Ãƒ z¼JÑÇó¾ós¿å8‰ æzc²€b e�îÕÎaäLæ®´›Âá£O¶�5ŽÀ™ÎçÙùŽ}^.¯ÿw Áýá�6*Íé8ãrðñÉœç?'2=°ïvÒNÜ'ϰ‘5—Bm¤3dZþû|¸¤—óƒ¼ö•°j ’éÉØŠ.Ù'n�S΃š—}^np«ƒSÀ>c\Å|ŒMg\¨ßAíyÆgPé<0üŧú7N‰½g6%ræªG>·®=c4º~Þˆîªäœ¬!Óö}~ˆøÔ«îׇ=\¢nå¦1|á9s¹@Ù ;$âaœÿ†]|'28ìëq½š3‹îœ-gRùX£>}Âc{ŒQ×ey8.Wïùb¢É&¼oýt¿½=…m™ž¦}ÒnT&áÜk¸sZZ8×zò#NAωÔÀ«M…ù-ßϹgæ¾äïÚÊ=´†‰Â€>¸oôýίŸH]¶åÀÇof¸xó»¿v,²šìÌå+›Ô�‡ÙƒžÝd¶ð1Ö¶s=—¦ °×÷h{ôÁ¶>)±<šœsÔ4½¸®Í{¬vQ=ÏÓ§*0¯û ÕºÎÒe˜¶æf‡ÞIY¿æžofÕÜg™ß„^šö¿AN”û]++ªPÝyÊ— XðItéÃ'‹±·bö¥Ùº`ôÚo|¸žÓ¨°gÝü÷gÒ‡SÃN¤û=¼% 9‡Ž›ó0©†£þ=Á~{íÎQëRûåŠRopJÏqàu<Æ5Ÿš^{¦Æ]ùY‰ý*„±øêÒÏ}ÐÈOûôîÊV�öç‹’×Ëà¡g°”¸¬.4�Û'ã³,¯ð–Â^ž:¸æm³ÒGç 9ÑúAÏ·ÂÚn�R×úàYÛ‡ªñº³}ìžPOOz�ÑØöÑ¢¸´2g"á zÑ ÖÌÕ%ròZ£™˜§s¡þj)ŒG�³°xz»÷&87ctÙ]oÏO9ü¿úì �ÂÂö÷7o¹·÷ Èë¥w¾ ·µ‡¿æ -©Œ³‡ã÷Gn"šY‚Jïáƒsçu¾n�ªqÔ¤ŸÕ¡!â£KžÌ ÂïWyÈ2àßydNþ}SŽÔ+‡Ì£“@bé!Î}°À=»�8²íŸ†¼nŽ´°«�oŠ÷™é‚߬MGÚ3,ÇN´ó"gM§«ÿæ.Æåæ ûê¦ÏìL“®ª�_—þ¹Ì7 ÷© Löйœ£þíÇÓLj-ŸûCõ³ILëÁɇCq4]ï‹q§ÞnîŽUعfuJ³­W¢ äþž=$Ík}¼xM’œ^¼Ût÷µÃÄÊÍÒcgÀ&y¯–_½êr™Ó?>( 8ºlùB±§Îmï3B]ž+byNÆ'tÒž² $¤ô�`»Ï> ìÞ(§=ùÚS¡JØÀ«aïºxvÀaí]ˆŒ_¯ÅñîC&,ñ·†ºÓS˜®Éޝ¿ñBXNH³µ¡é{vNÀbö\¤oâ;·8{ØG1qz®%xÝËj�‹ñ?‘ujëY¡i�)YG;Þr&¬ó:¬Bå^Pñ+yÎ"(3Î'gìZ×Óï}Â60Î}}€1—x˜ö&܆½Ó_ß>5+ö[×Rð ÓH†²œCVŽâuK�ÑtÖà9h�øfÑXãÞ~ZëçñÁ޼µëÛu]£3kAÏyyß‹ë}y£YC•ûär(¼§¯;ÅçµûºüöÌGFõw$^‰í¿ÃôöŽ�ÉbþÚ®÷}1Jà¡rÕÛãyç1ís Wj’ÆMYÀä^qÿÇŸt–?˜Æ(:ß³òa•Ñxv´½ñý1ïßùôM†ß<æÃãÜ⧠dÔL±)ÃÇ arríƒÒæÜÂrú@_ã{y8á‡ËR¼¹µö<¿\ä•s�ê³Þ.ûI¦49s>6f‹Î{ÈÖ×êü÷ÈE¸>Õ»ðžZ2p ‘ú²>En7†Í7$Ô¶ó8>³°Oå`Ì_)i¼ø*]ßàÈ‘xô©šŽÿÃO@ã@XXÄáƒ=ç‘°¯ŽYŸ¢Ý¯Ãt�î¬íIæ!½æLˆíl–U80{�éœù‰pìƒEÛºðNcsŠt…G/×zï«áþ]PÏ*Þa h%ù”äúåÒ€Z.øP‘ NKz†Ïí’[žù3–T�¢åáÒzÇuÎAñ�óÉ[—h1’qUÏ÷Akp¬÷[1æ6VDÌL—�¨Zk8Qpgû±_ãþÃi F�ºúДq8ÙÂ�Ï7³á=pæ®1&àžÒk×)N~Î1Ï­¸b¯ß Åì_,{ÄLÌF#8{"õâ½/Äâ©>g ºF³š)µ*Ÿ{86Xð"©ùÄw_à$KþžG€s;Ãé lˆp…¾¡áHmbÔn¿y·×†ÒÔgÖ¨»~ð�`´ò=],÷ž¸_.%–6?ÄId½$«ÞŠc‚Ö~"o/ëÊ’ÅfÝÏ%õcÞŠ†C]iv/÷Ir¤Gl´-A¾\ÛOÿÞ_åòê-¸\»g9?ˆëxýì>L \êã/q�Ms¿‘Fï9×pÇãõvûµx/Å ¿íôñ4Üx¯_ãTÊym›¾­�K ¼¼ý°†þ°¬žq£¤•wM¾{×½fL7s+ÒL¨$ÔøU’œ…øç¥/”Ì[îEóšÖæñÖÂØ©ÉÙiɹ?P™_� ‡ë93ÅŸr®uÄk§´ˆyó­dw2Z¬Ïüa'÷ ô¼{áòppxL;ãM�Ê,G¾®–çNåé-?D»8÷B­oDâM—RœÜ9‘žspšgöç¹%¯Š“3ðp™‘4ƒY>ÁÅ/3Æû|²Ò~÷ÄpçA€@}pÞ³> �ÂXFŽ Ñzûµù¯õIzŒ’pþ _ŽýqœæjÝbëÅs½Ÿ³s*`hšz¶‰e54ÜSKx.Kð‚¨y}øÜËk$ëÁÁžû@8‰×[$YÙ람½à_k�ùܢç!ª‰_"ÅûLúõ´ÞŒÖþŸßù t<’ħÏàÛ¸¶\7K�^Ä©Ó4ïærQ.VjýÂùaãvP”y~ðéÛ ÖóùózÇõ�ûèß´Ñ«³G¤ÄÊ�„&´K8½lš?N¹ƒ3"õû�EBŸ[âЩ±njÓž�ÕzùI3²4¡Ÿ:k{8jÍÄ\̉5þêÒ; ÓF2ÕqÞ$ñ¡¹9;úÕa_-TNÕÑçVeXN\î¡1&Æ(7ì9 $èû~¢lA¬UËn½¶’Ü«JëW‰s†®èEFà;~àÕkÞà éˆA�«âZØóe9ZîÔ”hèͽ«à5S@*ÜñFóìiÅ/íŽÞΤž ¬^ÖlÒ+,éË'˜°µìLÙ©Ïõ_g¶X¥ÅÓó«Ž5š#¾/ß6ô¹·žùHv�ô\/è‰yt"xüàdùbÉ™sE{Ü&/)‹XN›`™ÍÛ-æ‚Ó˜p¿Úóeoó:~1SækÆrÃ&:{ÝeŠö ]û �—‚¼¾ç™ûµáÕ½OfÕE)Æ=8~›>º#s\`s,øÎ»Ç�ùÆ.ÏǧÖÔj7~ž[°Íܺ­þÌöQ3öfâðUûôÔℹŸ ´ôþÆoçIt¯ËY!.o‰ d=UÕÀ^ê+bðÂŽÏÀ‹¡Ç»kÞ‘Úˆ7D™Gï…EÜ €5^2Ï»}œx`Ui�&ܶ ŒñN:3jįâ�Kg �—ñžÚqh¦žÿ^{.'4¼vŸÈá öŒ%â=@�ca{ºQž3*±qÅSïI½þ”¦–`ŒdÒÞ}‰ÎÞEÔ´eö”0§Õwäs–Ò‚$ã͉b©GÇ÷púÊíŸÒâÍPÜÎ}:óttzÀy�ÿõ,= 0{ÄWJƒÙ×p)m}u�0ŽËÏ9 Šßñ;í/ xîh/a䂉Éš{–³”焳àkÈÔÒ7yct™¼ï ¸T‘úôéšFüÃû@”ü县ÄwÏV[ÑL@4ìÞà‰7±9òè]MGNPþ{žèÍq¦ôb ÆWž�D©ÏÞ¬.åÂkúZ÷l…ÌŒì}¶O<Õɱ&¿ÿi_jÒ{j§|{àÞzxÇõ³ÆX�×ã‰káµ/ª‰÷œçúƒ¼sf)°TίZ>#0qá¹›Ô�hR:{¾�ç,Ї~ï…­Ô�•f%Fò[vThŠÿí÷,›ä©•«žñeŸšoŸCå>ŒãRU‡j-yá—~�¸!TÜ*Öp%¢«0Ö5¶õ$×ÌÒœ÷o¾%z¯æj½K½vÔ ø›¾EÉDÇž†×líÜ“Áþƒà÷$ô3öôíž'ñÄi Iq6¬ œ‰§�ÃÏŸ©SËsà*D“ç/�¥Ú—0=V׎‹Ú£Ïj”Zì>„IWé3ìy@í�#Wft>d¥¤Ôµ^›3{ôñ2Þ®_¤|.jÏoN›[[ûÇ››§†ÿ'@bøˆ‡8ôúã;'ÓÖlûÏ¥‡j k½æ ÝÓ�RQqöprø[rû–�·Gÿ“aƤ|¥­q¹"¸Ú(Ÿ¶D�—¦ÙÏ7IøÐ`xÝ¿ªNœgr4̹�ö99§>ë<ùõ±Rö/Ƽef³]ì>*Ù\\öî�ûK çë¥ÖígÿòÎ×xÙðι•âôQŠûžR †—†¿Îðê^ð”ÿk+†ÁZ3#èøÍ±2�ó®ÈE¸cÌ4Í-»¹EO%ul,™,͘«ÆñÁ8±Ç¿m·$.ðõ®Xª¯ï�‡rÛ€€~ø¨i|Ü¿{8Ì[²£«…sü»%˜ÞÐæ=ÂH€�ÛóSaåÌ ¸ ¾É �ýÀé·›5`�ïP„$çt˜Ã��×1é¨ÙŒñ)ãc¦˜[_qrîBh&—jñïÚZ ôôÔ5ù¤ClÙZf—„•@Kƒ©Ë£—¸®OkVÓΙ⚲%SÂ~ŽÈŸÑ~اW ¸_Wf{îÃñ%üî gÏ—Ù\qò4#6§Z=_ö�R½‘»w CÑH8¬fe¦OœÞ.:÷c uÿŸ±·[Ž-7–4�Jšë±±1ë«¶yÿ‡lIíŸÿXäVŸ™ @„‡‡G`e’LrWµ>H?ñ+0,ðø‰é[*âÌ;>fðäæã -�6Ò¡'�câ±sd³™—œ3ØoÙZëÓ�íîéA‡yçÛÞ1?/‹*x1dsùeÄnÒÅËðHó6ÇOíÕ\ö•å7ÜŸ'ggÇ ~ò=y¡g„²Žß3P’Uºnïžs³“ì§ïÊž`òß,ëým3ÁLßq•tœîu±'aÒDLçy±àÓÃLRƒÌ ×àUòktü¾žLDœ ÏS¿©Ú\XhЛƒçœÍöâOFº“~Ô9}¦E¥‚öÜÀœUr„ 3óW¬–�vÒƒ$tl&r:½V ÿ¬ˆhpØè%{vb0Þ>]Ì ó{c,V¸ïÀkœÁü)ö nªèD„] YÍè¶<%!�óOZ`».Ö“:C&Òñâ5„ ½ö?²ðš93ˆlz."Pàú–Ynár¿ú nV×§Kþ:P1Õ•¼pIÝÆ²_0^ìÀž±ó§.÷I>ÿ�hLù {Pý F�Üsç›P%àž¶8H7Àö#&¡iˆ‰¢­!Ói&Ý“fµñ®Sw÷dõ2û“vüao¿…v†@ÚSKÓË“µûòÖ�‡¢9ðó9~„a!E4ÍÞš×ðÝ\¬Žó*ëéº ÃÞü¢ÞñÙ–•xi0™(lµÖ•ÝåO^Bn àãÃ|º$÷Ö˸\šm§�æß_/±O\x mÐø„Ð2ªÑ.ëqòhb qvhf­‡MeØ™y‹cc¸äÀêZ!¯bÑûj ïûÚK~¿I°X“Éš‚3OG1Ôh˜ùç�ª9û}1˜ºgB[Ö1UÓŒÚ&·Õ§%æþ½±7Ý{',ýÐÚqØ’iÞpmÿI_mÛ¿(„£Ê+¨y¶ÅGìŸç¡Õ¥9öZ´ØÄÈi /Â¥åβfRýp¹# =}_ÍãX®trQ¡Ûâ*ð»}�k�gvÍÅ7uëL@ÞP—iÐâñp:½�¹wáflvÿßXQÌg\ sÌúdS�óÀ[=`Ö›ñ /¿B߉'ïÏrV‡Ëì¡Pˆã³K¥ÂaŠõ铌¬O=�7vu€¯ä,›×ð˾z=wo^Èä}¥Û¤ËË1îËÙ¼�ãÔpjA[L¹â·ùZA E÷ æ8´g‘>¥ tðxxÃws$í³§Hm×ï7>#é'ßCWDZUÖ7»È;õ(0yqD£¹ŒÄ—Ý0Þ­ô¹+ilt‰�žØˆ¼À~¹´Ç`&„e÷õ°û ìà¯âáN¯BÎÿâöØá.+ùžqìhÖãzù'ÀJõ-Hî·Iï 1Âæ?9–póIð$=±Ú禉oŠì‡>Y¢ NŠñÐz8öò,Ün_„Á~ùºa¶ï±™_ÆOTó¥é_Mã¿÷hÔ0ÿôZ+¹õŸ Œü•Ïá¾ W5l;ô`‰‹¦›+y@12;ó±aŸ–³®-ö{C¯7É :ŒÖ&ð̓ïŽü B´¸"¥I/ŽÝƒ¬oaˆéÃ9ÚçEã²6-’C øôÁðà^èbS"X³Úp~Ÿ—`̈Õ'<ãʬkÏÕ÷ÍC²eüb&Ç´DNxqQÇ|ˆ W1¬OœiÈ ˆA¯ê×Â<1w�ÓÀã#í|3Äœ\XáaÛ~aZìƒ ’žô¿õ"˜yŠ OÏ­5Ííå-àê4ÈdPœ·ûo ºÙ£µâ˜"ÊÚ�AïûcÛG°ÓàÁ–’ºÝs€p3ií8GÌCAõ*Í,²©7\¿ŒöþNœuç�´ ùÝ ë›X; «’%ÀµÄ)Ÿù)°p‹ÍþIýpÁÇcÛ3khJïX×ö]3]K8!°Âððƒ¼‡¯^§×àÃÑ|ùZk®WÇá7W/NÓ¾(‘lú|0´÷PÃnn–Díü´,·¦éßh õôÆ(ï{¿4/“Ï NÑS™þÖž|–(œ/Þô'³}‚›Ÿ"4¬�åhloâDûêúã<ò&F‡Û¡=£|ð¯GÎe—œðpaœÜÕ«¯¡L݇Ç!9ûé2‰µõ^2ÿåK|mîæ'·°ã±"’vL¿a³ÏM²±Í ˰ƒXo1·ß¸FsüØÖ �›& <ö›óFÀísE€œß÷ÛÞ¼°:_¹~ê9aåqÇw'û 3�’<½�]ÚL×a+�6ìñÑ»§«Ëeø"¤üÓã¾ÒC‡$´ñí_Å–û“™ñ�¸Á;u6}Õ÷0t„ÌÛ³>äÛڨƀùŒ Á6/Ïå”s“Æ' ó�šá�ýÈ鸉a�‘qó&žÎ~¹÷Úâ»÷SN\É�2 ˜~’ÛŽ÷÷ã_ý‹ìiyó¬·Ž©ƒõê‡ÃÒˆîØM&r¼ŽgÄ\®hH®\hkË…�8§ÇÔã'CÖ päÃ#?�äÎj53óX^¯�vÀVš—#s(»^íÅ`MÏu¡×ÈpP÷‘3 o®¼&Z­üþ'EÁ5�Ž5G$î:}N²�nê·–„40Z?ZìIÒiFz-Ot» }ãá±yGËZ%‰!@ÊÆZ÷Ž>ô3€ÖðÊx°t€á’ÿS!Ô¾{#o”¼IÂ1�”‚—±³}9·¾g•çËâç?$Z�?oô†—+Y‰!—çس3Ö¦8£ØÞ½{N6ùR‚ó¤Ò«µeá IDAT€¤nâ vÖÞcò4¤çM÷ÊœLOæÔcn]ø^âP{•‹£ø}jAlöÂn_×h�ÂÍûkA5^=5„…�çHê­¹¹ÈkX9“Ÿšc°»šüò-Öp¹Ö£äBŸ¦Úó·ñ£‘óÕõ3Ç|è©Ôj AtjÍöSS{¿}n—@ÑÔhs%GAÐÉiÁþŠ�ø ±§o ÂDŽõŠ�õ1úÁòœ–çÛzÃ"ùˆ¤'`²æZ æpdž=±ë=Vã/aÿofz2žôgÐõsßKEŸØ0·……L×½y]a°O ÞY2 ›xDºÃ˜‰╬Â]æÙ5‹l}1¬O åð´u6º®–Í•´*,BÏÑAö¢0û]_­9{¨Éš´;k‹ËLo^›ÛÓô®óIé}ÃÝwR¶Ã$ { HÍvsy~M‡°FsdC0<ûWnÔÛó8q@ræ çåô§.=Û¦ð×!ç�þp›9wöã ¶”Öâ5¹>ºSÜÿÁ·Þ­ïÙ#Rí—À¬_}͵ópÞÊ£pð‘ĺʷ}zWc}H†yïÐå+ï� NlÞ�vù¦+µjŽñ* ›.øCÉ•Áy’¨gi‹|þ Æ×@ðýxµîN5¦vö=S-ç_èäöÀ7,|OµWa•í9Wã»ÿøë<Õ9½�:sxŽÝÉuy¹¦Ÿenð·Çä©NÔNÛ4‘Ì2”|ý¡Œ.XäøŒå~í]·Àù‹¼'ƒE}ù|Nèá1:åkçDWþåÈz5m$ v¡îÃ6%\olvíÕ´ºH �æ¿¢…ô>ækjB´fMè!/öj8+EIø’† "}ê·«ö)þŰ¾ûþ'Ç´(ñø›ÜÅ1?Ü®’d‹ô¬ ft ÉÝßüOã£ÇšÄ ÔëõžaÄç!œ@Yƒ_žZÇAÐv‹0×Ìæ•ÅO"Ñ q �»yVóöæ°/šéÃrÎ8üH‚Ø[‡Ir9±`ßÚ-c9½ÕÚxˆ5’'jÂ7ŽÔôÖßá†ÞÀoòøsugŠÃîX¿xë�í�.Låèö$=u?1ÇJØ»s* ‡ÿ$^ч3ÕØ8&kKŽ’4�_Üé�âó÷˜ÁšÚŒ,:DÛPÛá{þ9Ü5œBÙçÓtÃ8‘õ&Jo–r~pZÀÉYž8å—OÆŽé¥F0ØöÀš¼^U;ëŒùrÌ8o1êÿòØ’d‘,ÚRO5:?ëw.jÔçøVr'ŸÈº`b W¸áðk .™ Õ%!»ÈŽ“G<ο…¢Ô!ÌØ’Œùá[õ;ÿhÌìÉéü¦Ïf 2+QÖ@®ƒMîpÑXlß‘ú!çÍýE�×NcêSÐÑ/“ëð¼XøXkÖÙqnéé°O]ï(6?ô¦V¼_.ú5íx×ï¬ñmõ�‡>â^"5?�Ͷ8„Ævj?e`ç�a¸ÙÐ�89ï­M‚~ó§Êá}/˜O¬Ú<4t¶O –ØÖ…ù§J‰ šüÒ¥Ñ݇ïÚüzñÔßeóÝ×'ç—ÓÚ«íì3΢ÚéQó6§-è·�²7”Iž£­î™pÎÔ9éÒ�;Ä‹¬ïKÍÎS pg„œm·Y/Îhél|‹².òñN8]AÈÏ7@€–�CðXÿ¯’Ñ>‡ö€Ç9‘ž|®j°ïìÔmꃃËqÕh™!Ì ;�òíÅà|ã&›y˜‰Õ˜–Ë¿[â‡/ðÔ»µH@Ÿj¤áð€AË£ëÍ9Üz‰ÆaSç£Cž:Ç;YNimÂbÄðà‡ûýó¿½ùÛ_�~k¥oŽ£JR=×hÔSá“îb¯±‹,Ïúèí[ƒÂO)!?ý“ùè%*Ðè�q¶öÕ;­`¦¹iîT ㆗ÏýÓãP¦¶£ÍÙ/ÅìÔ³ß~‘Ï:EÌõô°1 ˜îŸæÃŸ¼7Ä•ÀîÝ‹2¯NC~Ö,#øú‹&^ 1û/Šdƒ:5˸\à´%kr³xǼ›ë{âo˜j­í8±>€`”Ý¿Q9¡–á}cäÞº'ј \­øÖ±ÈEEô‹<~AÿÄ'v÷Þiȧ9Óh2AòM’ý…éGz´î �[ø,ßY~·hÖá­5yÝ×öÑz‡enù+›ý_ß7ÊýswÓðùžï»oO 9î—ômÜ>ža:F½ç®hý.äø�¸{Ñ>ר󿵲þãÓbÂO¼pí�g,7‹§s=\kæ£ÕF]^ýÔÕ³ÎëÐ}#!z\€ø4g %BtùЏ÷—ÿ@WãBw𿾽î˜Iñ§G<¿¥ß,Y a\gŠ:jÓÕZ­3x@`i šìMà£=ÈW8Þ5ð¹)C@/±û,�©¹–§6bиû=ÓF�MyâYUjqò£©èõó¼VöëÎ!nHwÜUìäñi ?cºÁbygüÓ‘þòz–1;xsRœÓA,Pö�&L³9Wý¬7ÌCÌÃe�Ú¿3øƒÕz¶�¬3qœ÷î·aÌ×Xlã?� žXM‹ÁôkTïøð/fœ›íþå›�™|öI=©-½Û–86²Ÿös2§PüˆY8f Ç_SÚäÌÀ,è'_N&g¾èaßýÖKȬ‡Í�OÆÕbŸs:v=êÿ¾èR¼ÑòÞ?MJk�+ÙÃÉruܹ͛¯X‡75 [ÛBÞs=¶ï" ÇŽþþI×7î6)1× ××öÕ,­ÿ ÿü7®Œr¼÷ÁÍYÍ~mø?óO™U¾h¶ïØ^ö¬wŸûãöõ¿Ñ‚�v�NÿèÁ§V4VëëÃnw enÛçÌÍ÷+>úÂ{4%¬D;fù°œ4çLûü0¼¯ çïT÷åþžÙ¸Éuqå‘áÖ =™¹~õO¸Dìø‡Åq9cøÁ:‰\iÛż|D¼œa÷rs5Ïþƽœò�·bÎv‹ÅoÿßÍËî]÷ù„ßNƼ¾-–Î<Çñ‰eój#×Á+Ùãšð�ûOëÃ¥<¼Áá7êWÄÃOÞ?�XuÕç[׋]ìOÿú6?\ì®ùÆ—|Åõ¾vœ`í×…¯ü0Æ›¼X�€Lå7sJzrRwGP·÷ñäë¼ï!p䫆qLƒ÷&áòýÚçS¡±{³¥ßü‡�Áš¿†Ê÷RS”8ãÌ|÷Ä€òúÕe[ùXgDÏvè#2JÇÏ5°P¼}í;(×­W3pÆË…˜qnw¢’sõc;88Õ‘(Ìø�÷âã½qö�ÑǸ<èøU”¿™Xûðp¾ëå[½ìçgžöùƽýO\´çœ†™M Ì;þ¯?¨ÿî:=àXû� úà±jÞ�ç>aMNÞ4ºõÒY´Å¯—ç²gøïtGcxÞZ_íp�÷òEÇì`^ßO]ø:.kv½ŸÍãÆ{5Ù C�e÷‡¯á{â¼íYδðç+Ñ?ñéCô‘júY3¶7ucCg~þšÞŒ[#0®©ÅÆÿp *η'É—·gëgìm¸óD×[å7¡ëh½v äüOc} h°D%"ýÂ3ö1ý´éž×Ç8rŠQò½!´zÇðkNsŽyg…²ôP*BY^ÎlðŸzb?øÁþÃìê æ®zóQT~!|ƒ� ¼+v´×‰‹¨·7r§òÔbá k8B?~bò<øy�dŸ,˻炭¢K]ü¢¿Üœ×ùÙ~9ro{ç\ïÏþ0§ÆÃâ`6WxÑèñ öéšÎ‚•;\Ó[¤¶OгŽ÷­¯Û*²ü݇{3•¸ÜzBõ†r삞ôî!=°� ýzïýÜ;pn”2:ÅÕÎÉý'ìUí>VÈÞr+HÏÙôý)úh=åÞ=²þÒ«ÕœxyjÛYÍo.+»ÚVŸëQœ‡s±JíYe}뛬rQ‹†{Xýÿà¯óœÃ?…h‚Û´�ÿHC æÒ,ìþÖoxõ�$9" œÆ#†¸ÄÇeß“vš†Äù _üšÈ^ =òÕe¼k„þ¬å¿þ&¼»x8·Ê͈Æî¼?gðþn€"ßÜYïйN#~à¨ñ­‡o†ü×u>¯ôó)Ð2NrüëßüÆ'çÔ{umw]–˕ڲ/‹4Üj°mÜ>PÓbTýùÍ÷_X(/x^ž 60Ôzý±O�¦QsÐ'‹) Ë›®hħ»7¿M0·ôÕÁž}“­ñÛcwlk÷…ë4‹#Zówm]¬óïÿè_Ï¢�ÜðÝÚÞ5, Ëp®ì¹Þû(6¸ÿdÇ6Îa |ú�¾æ™LMùM-?Üæu$oŸl9Ú©ãŽô Î7_ôâã~—n‚[÷ÊðÁüâs$Öäò=8»ýæl½&?ùJá¢ázs'Û—#ýN=éHŸ(rZc»uéûr�7úüÓå…gZ×ûå;öñ“¨g5ŒM½ æÕññ‰ü=ƒ_¾þÐð÷ÿú‡©ùmròGß»V’äyI¦�<¼ù¡¶=î—­= $½¾˜ì×#0©AUþ½¿™çÌÓ¸›¥úüÆÒµžÕå?&óbçóOÃä@îÆ'ï§Žèüû?8o~`M/×ÃÅÿìãü™%EZö|M7Éÿ*8L^ »~m6 ˆö‰:ù«xòðüæk|Þž^³ºƒ˜è¾ú0ø/îP'y3ˆÝ;|´§Öc*jã+Øt¢ßäºG­Ñø×ý]Ïþz�îDû“^î9vç ¸Únîøî�ºäˆä1^+Uâ}ý¦X^‡þõ¿Zà/ü�gEí<oÄtaÍ×yC.¶€ô4•¡åOO×Û»ÿKϲýëŸÿK½¼?|,7uýû_«½ºdC")#uþÙŠÓ/èéÏ×?}©7÷õ_4çuŠóæžÚ÷lóí¾3Õ“<Øj]ªÎÉ•Mµ‚•y¼ÑOò�€HlŒa—ôïê%Þ縨°:¯Ý­æ²ÿá r9ð3œKs¼6ùòw=Y­ŽÙ‰çëÎ4Îþâ~qZð�w&foôêU—îç/ŽãÑB°?õ@Ç{Î@/B®™ûrÃ=øôª½¥( r¾u$I|¾þ¡Žá}Fæyî™Ýä þÔŠùüÁ÷¼ž;�®|þÐhüvûä0]¢ƒÜ:ûçj³îöW]�_Þéå_úîï…Ö`\Ô¯¾]—WQuÏöë–Wu­�óYKC~Þ?±Äœï+{Þ¯&ð¿z¢˜Õkÿçì%¨5~´Ÿó¿~rß»sï{–žeޜ湓ï38Ìï÷é\Ó“µ¯\:n¿Þq~÷_þß}C/qžÎ=ô×ßþ/¬çµ2˜<7’#1á»ï>ýûúü~d§�hz 9pr|1×><ßcè§ ÝáÞ$ÀÏBËIöé% _Þ8�êĶ€ËþrbÛ€3j°ÜU¸°]<þùVä¼^2 &Ã{bôiýâ|uýëß¼~ÝÚnÜV9 v§n廂‹/êR+ˆðúý ü}†¾†g„Á? ÁמÂ@¼µ>I¿œ«Q즚šØ1ãÕá`qû‰ï9ož3û™l�ëš_Ÿ&~vØólº^^rõ'�_=ÕçâÇ ÈÕëšxÏEoØö{ôÉÙ÷0Î¥�é Ë4#Áãþ9§ÎõýþR5¸Üçù|yCÝñË‚S_9Àüì˜óŽ=ÏwCaÎ�&�äÿÇ¿þ©qø&µóQ¬½ŽÖp'l`ÃÍÕ ÚØhlÇ€�~“©˜ã>• 7],°çÙ�Œ2Í�ÁØáŒxâ»ç6˜fWAƒˆi|¨åðþÁŸqkö Oý¦y.–êpØ5à­Å9چ܊©7 tÓ¹Ñ#x«=¬Óå˜òÿ~õð>aˆWîÖ•z9,À•�'L_PºL“MŽ­Ñž õô´ßL2ná¬ÇÞÆx� Ñˈ,Ö9î“·çÔ:}1Ð=#ýî¤Q”5ZõέrÕ)3½ãz´²‹Ñžôž/6Ô­8Þ MùK–‹sè­SÁ®ú…nòWçz….ÏV<¬·k,á@_"%CÈöõm!2á�7Êñ2»¢�ÿÖâW™\ÿ2‚'Öø¯;íÞuÓ'hgWàé/êÚã©cµ²¶ü°™ßŽùâôÙâ‡c?�rO$<ŒÜ Ys}óúE›Î"y‚3ÆÅe¯Ñ;¯N0ÙSlðÞiéº[Pr¸aÁRW;¤Zóà ¢ÃýΩ�×)|éß�ÿ]Î}:ÇÞ×Û¨‰ÖÜÑ1³LÈ3öç¹î6¿ŽÃ“ÏTˆv]¯EíÈ´øëÆ8ü< 0WØàã9 žž?üÞ«®Õ�~ÉD=W¶üS¬û |�²¾yâùbÆW°j[<3J¯�{�¾xHdþ¥[c³>ýñ–/îUá{yÎGx=ñRJÌo¹dL>ò·cà+ Ý^‡Î×åͽ©‰~ÀÅ#c¯=Þ9…|ÂÀ㯑Πžû AŽW^³aÔGŽË ï…Ïó=÷0œË·{9χʂ£I<éÂßËbökÁ‘ÿ¶ë‘Õ˜@]ÓE„ŸZ"6óõûµÅu¦Xg×tƒô½éçtÖØÒ¯j~á—|bq/@ƒ(U$–ä$Ÿ{ÎM÷ú�϶À¢›ŒÉEŽ8Ó+±&�8 tN"üqïñæ96ñÞûþè�ìœL²t9¬f�áÉùãŽÍr γµ{iÝ);Xž hôÓFlÿö ä<Ž&çðe&Ïð:>;]чì,²5¯¬Xîè6“®ù”¿Ž"Ãß×KÖ¿³á¨o� ÚÞ;x]`Å̸æÕü/ýÁËÕüh`iÂæ†�^Ú7Ï]ý¢‰¼5òÜÆÉ£CKvи„SCZ´³=ý[H%J®<ÏP¿Ü÷µ-Ñ…Ÿ±³ðíhJ]ášFk7"—O,¡JÈ™+Ü#þ«+Om0Ë;`ö«×ÐUOì ï¾÷m8Fç15ëT¹¸ŽT”>ï¹ß_úÞ’˜ïó;<«÷Öo9�ƒ88Á;élK~ú|Ï%?ãÁŸ>{“b¯ýºˆ?¿ÔÑB�ñò\wŸ$+ß@=kKjß®ú8~¹1¡Ži-fny(Ðy¨1Ïðý·!÷ózÆiƒs9\æ�­{Íýì�ä ®óÞxÝ·¶—ú«%y®¼ìo^}ï û"Ðy­{ ózù•ñÒ!Já™Ò­²Ik�Ë�=W÷…Øbüs¬¹b@çžãçû=‘[¿ èòy˜ ýXàålXøÊn—¬dÀTÝï}ü†sOx‚M—Û ÂYX±Q|ât—ài–#Ó¯0ÇÀuZX7¡ZçlxfMn[ðjà®#áctî.6´÷…w¼Ž·ÞÆ4ïh¨4`xt¼¹Þµµ tTËáÑÔk¿þ˜_°èzò(§?öä"æð? BôÀ7DL¿¹æŸžÄåÉ7f¦ÕÌÞïök�žq Ïl¬ÒÙ–äÖdQ•áéå4Ÿ³ý¸Ð¯˜Vïá•ù®¥D§ktX£óDë«—ØôTWt/Q8¾Û®‘åŸm*Ä9à€=šŽ÷ÂÛ\ŠK,&a“Î~sɶظïy¡P,õAÒ´Ñe§–Í—¾£Ëœí›Á#²GËp¥25¥®›ô 3^vŽäô•Øš€5„‡ð2e^ìÇì áððH]ácsáÇþ Pñ—S²]]á¶Çµ¯¦ÚG§sS°†c]o±†Ê§ùÔ¸âËê½:á£o¸¹xÁƃtI™¼f·Qn›‚‡wÜa)�'Ù·WØ93OAi“Þ„ ׉fGx}÷ÉÍ9ûŠ„â,ƒÊ5¹BçêWÇõáäQþ9¢:Ú]‰d=&"¥y9à²fA�ö‚ÙÛÖ}ض7ÂçVXÏòqvÛÊÅgƒ©Ü™íÁk¼{æJØÿ �ýh^U–=·®pZ?KcÇl^GÄÆoö¸‡Ñôˆ\âf†'Z´ÖºýM|úáÁ%ðÓ:®fõ}ÀúÔ%¬ÿòTB‚Å+ãFîg06ºÈU¼\xydÜ{%z±ñÇàÑîr²c˜cv ʻԞÙcßUûÝ+æ<°/�>—õÎháÞbT“×!‹^³ Œã@“ß¶ø½tì.ã›gûÍÃ1Ë&Øñˆ˜r%/˜À>#çS-Äù!4âLø£�Ͳs]ß�ë(¸1Ð4S$ôM¯c³À>÷Do¸H¬ã£O>E…æä�Wñ;#—laŠ)6%ÒWöW'ÐêQ̱;>‰ü³œ–£~¨¤Nd–,ûõ œÛŠÿ ph.G˜ü� &A;[÷~"BaŽ7ÇÅ4¡s«Giȹ²w­ò¿y©õÝ{-àzÌžïUŠó‘Êå—^˜¿26]}$Æ.ç±iöD€¿�²’ Ù£‡1]ìÜ&Ïñá&6×w^/íˆÝ�bjvŒ“­Ö;‡3†³uOá6³1ksfoÌõ7ÛÓ0c  qÕPFÛÆõö g–X÷$"„·¨{f²8%«×±0[wó“WøÞ<@ KÍÄi Éý•31åÁg@¤€p© IDAT<úÛWÜË•ý2Í.ç’é({a)7«O;×â™À´¥ë .Áð7€Úf|æÙVŸëzÎÓyàm¾á—ÿìáüàxîjˆkó°Ÿþ,üz€EÃôß*¬a~¨áã�ÍoÈk~‡ó™ˆ¿¹ÕˆAGzw2LF[ô!šÀ@øQ{¤†ëİøOqD·™ãúbeý;<´k7*ñæ¤GÇ–š*Ü ¸ßëWø&‘‚�ž©7ºCï,!g)ï!÷>9X¦N4ïMú«?P_]WÐ1âwñÞæ/Ø КäGŒìV’r´ÃŸóK÷á_{aĶ'‰‹.úÁãö*ëhVPãˆÍãµiÝ”Ç7mæ 6}�Ãç¡%x{,µq•=çV-+K¸‹Ÿ‘3%Ù!é"Óð§oÓk÷Ýìõß¹هʛ“ë¹op`çÝÆ¬ÆQhïÿù')yhÿ²Y�.ޝÓ6yH·ž$Sk~òj0˱žCéXú«c0Âí‹è‚z%µŒ†wÔçµ.,{îºf°ÇŒ«c|›1ê-?öåC _ða8±¾g3ˆ­Ca&–‡Ëv]œ û’x}7ëÅeørÀãCò¾? èÞDå%ž…pÖ-¬4Æ;Ãïsm_vêkÍøäœ6w°|?u}cД^œ{ÆÚe{ø‰áÿ'žØÆû»¬ 8õà"´a :óC<ìáðâ)¶±~b¯H⟀³ÆORb¼ÖoÊßüÄ ÃÌV©ó4ŸÝÆÂÙ‡#ض¶îÝ,0¨¼>dor ,ó�Ñ.;tŒhzÖ^ÆiŸöo¬ÝÒ±šÈ›CÊÃUúð‹Á7ÄIÚÔg„ël½˜ûè�G�é2HÎIJxâ�=6ëÀo»fQ¥'ËÒz�‚Úâ?�¯Í”xåòáÖ@‹sùzovgƽ2W”˜Çä*El®£)çPžt¢Ý€ûˆ�Nׇ¸ø~¢~îGñóœ–s3†™Nl¾_T�G÷œ%Ã]ò2Ï«ôOà 1°—•ÄQõ0þf¯¦Bï°áO›ŽÖ}>ÚPy¦eú³€s~´­æ‰9ý04@0ð¸Ô%ô.÷›s : ÒqùFn|Ȩ"›b_?K¾fÔä×-W…RÿÂ]›6|ºÈø�òƼ:�”ˆ�˜¿ÔÓ‡fó,Ggxxý„Ü‘^ýh¢) CG%w ô…¶ò3V9w>€¹—No9~~yà˜k_r¾æ”ˆ!q™ a+ÚF.ä�ïÐÁ‡±Õ6ŒuŒ tÆÚÏΗ<á¸øÔ3 ©oÇëê!Ƶ[÷:Hb4¡³”'ʋޗ'Á¼™ãíšx“phm��ÌÄ<¦ ö*~ËRW)Ë©ç,íy|î¹;‘Þ5™K<‰/3i1ÇE?•©‡+k¶ÜK X£�5ë]lw�Õbখܷޙá³uL}I9ïÍ]M!VD·¢t8?ìˆ�èÖ·fÞÛê± ÜZøÞk[œóÊáNd˜øw¾ÆÉŸ³§Ÿö{‰8îÏŒäEÌþbo¾§Ï‚Þ-Ç2Ts‰ï›­ÏñÉ}–^$Î t1Bóöº{¡8=„Ft÷îÕb<6ÿÜÖ±2èݳ¼àuI–›ËA­ûµFO“Ô_ ®÷¾¶c¥›Š.Áò2o}(–Ä`‹2­OØ_KóÆž`PôŽu94åžrZTÎ'1W[úmù·y9ËÆï^pnÊ”áÖþ%ªéèœFcÖ;žïù…ðò-GöˆÔ@˜Ý3 Ç(¢ÚÉþ'GRò¼HÖä:c›6¿áÄB»}ð{À´5srÅ=;@ÖO�Äýõ}¬²½,Ä3è½)¼'ПGF€`µÏçg(f}±{ÍË3ü«×yËôŒ�Ä2îq­ns}à{»â«õb˜+¸ó±>*f¶³Â§O×�&-ÛŠ·»x™šƒUÂÆ•}«Û\—‰_~ͤö/Ÿ4Ÿü¶Mg9ñ׎¾c �<ß‘^Äv68$vSÓðôèÔD´¦ ßÕ¾^…p,…¶NïЩÝÂÉç{£ëÉl>íÝ òj@ã7Í1Ò:ìM·æÀ”(ˆ² ¡ÖÛÃj¼0§àb±È縘Éÿja­ÇþšÄþñ­©Å»ðG04LÛþ9ÒÂñYíÅÛŽ¯¼ÖSL³ŸY,P8®ä®s= &�݈Þéâ¹¼‰b­¬ù­Ñi�Éà³ lÖì×\ÆiS:›§e˜O°}dŸ '&‰š~Èæ2X¼õ€ÄÞqri¿/üÖNEÂáÏ}âDŽZxÕ¤àvÞ½Åö=8srXgÙ9œ|R§„¯v ¾g˜üÃ6�aºT$<§WhÑG2ŠÎ9Q˜Q%ÞŒ{žªv_ÍG kl0SsŽßžÖ3_`h耣qÉ‘z—Ã(jjÀIIþhhNîà C‚í«Ýíi¹M§§®bÝë8YóöÖß ¢ëˆ$·†x– ß•Ö\Žî‰59x(b”›±:÷!3scÔG|3k�XuAb¶`æ­Càþ(ص—ã­cz2§6àìÏYhÏk&ñÇÈô°æÂØœ]®Ó¿Ö'iðÛ«pç1 åõ_ýâ½5žZNºÕ*Ú¥‡¯9ùº£=oä4œ|¿ÎØÉs¹YÞjN"÷àw‹ï <ŠIãá:lÎ9g®­-µdÿžƒãˉ^|w˜¯}>KÁ¿‘æ~Á“ÐÛ[þbhúMtÆË7›ãµAîþàH‘-õ.ñæò1)0uÄv<…¢ÁyÝ42zͤ=à<Ö—`Òz}s€c¯ÉƒE6©/{£L&¯æ[{øØ(�i—Cphæ¾1AÅ?|׿}¢í4›VæÊ <íE p†8œË‘ÙÕ˜páÁ¦g±�q "7±àRØ? Ó†îèM1œ)fvèò­Æ«yØo†ÒÊÈ*çcmHºÎô§v?,'çÌØ½Bº˜~"'Ï}ILâ…´ó0íá€?¹¾BI¿‡ãª%X9Kä¨Ã™¹»&Æ&k`en*²@’Å?=W«7 š—ØÄ-äå@&*Ô7®' ÷)®áo_@ò`T¨šf‰ÿ¹Š{˜X G‰³.ä¼1Ó:ÿ|ÀóˉàÑœñÎÜé þq�ÞVïì –#àbâOYã�/›ð9 ·G²k)Ö!Í>ˆ÷j„ y®l—z[S§Ë…@Eø ãÄwÏôò£uœÄ0à>¿0©8Sø`Ö;ðó¸õ&îî�ÀˆÙŠW|òÞ^¦w‰@#~¢ˆðÐf1ùoš®fpÁ›="nЂaƒ°<ÄÀre;ç©5Tî—\Ó÷Ò_¬CÃ?*Í>b¡þãœÚËé�[65O ¼yÀ�²à^âñ…ߤ�ÉÚ¤Õµ:àY(—gRS�‹ÁFÌ«€ÃÕ5VÚfDÖæ ‹›u¸«Œc¹R“¿®œãc&ì µßqò1ÌOŸ´F7ƒ�- $Ö»ú.a±‹1‡£Y¯oîxLöå#¡Ï&ùo½?T'�4¢'ƒö¥á˜ãp`Öƒ+Çêb«ó†�+q{Ä*ã†ãóÙÖÆ:ìå£<üq@éër•ؽ–Í=9¶LOÊÔ$Ž9€æì~õ$NF¸ÿ0N^|Òj3�ãÍç>¯ûëz¶÷[}±ËDýŒ¸?{~4Ñ+Ï© xv ;ŸæÌ³žÒ[�ípã¡ÉEh3±±Ïo€} øóÕ/DÒÍ›<ó[=q ŽŽÏí�Gÿ±Ëå;ÿ‘æCm´ýÄ»'žYÕw°ZœZª¹ä�ëÀ)gBlx èÇ‚ºD,õ4¥l|P‡Gç—n½ÝõŠçTáÁ¿~üÄ^Àª_:Å£­±ÞërÍ2^öÓì^Ð$>Û¬ùOÁ¹ý‹–øé|q¡Ìù˼š‡þýÀ> ĹknÔ±Bâ߸Xë[œ‘º`ŽË–ô/õ¯6;*›s._íÆô’š¨«ç±:zO3·ò’/é �3ÌÆøÌÔ<£°ÎÆ›`:6“DëõÜóê|ìÉ÷!Ž&Þ$6QwìË}z/ÿ¯QJ´Ÿ±ü2ÀÁ0ù²ó½Á`£œøµ^Œ �w—ÓcoëܵÜ2%áa�oÞ9�öî�©ƒ6<¸ KÆÕ…‡×‡þ7ØðB¿íY;ÆÁé©\Ÿ‘ß¶Ë8N,|ælD4DÈõ)ÛÃ9ûÿ9n„ÌTdÑ®;\ÉQ”ý¼®Gmsx~’{?/³ê8ƒ£_= ÔP¤¶¹O 4ýr¿žÌ6*ᛊÌV¯/¬ß½(âÃ>ö|.Àû¥8•OÃq\¼iâ7·É”Ñ…WÿáQ<GCêÆÇT�õj¥_ÍòY8SX‹Ôd^sÃÌ¢àê‹ëµÑ“ä$ý猺?_r1žDBÞ5ç�pôñÕÓ�ûrõP�LÖá^Švg&š;Ò@cS@\ÄO¼9äÂ%èL¾ã×k* ùÙ8þÃçèÄçÜeÀ†h óH{z€Ù®› û'Æqüp¡9‰£L?lf Õ1þiÄ[�æhºÄìÛ‹š8b‚ Oã0ÛÎÞ‰•/>æ7§í@&‘Pm¾úe‘Áq¡3jÜÙ$fzlÖüWFC¢…îÈÃÉþ”(’é&pöû†º–#ýÉ�ØGÚ¸ÕTåÔË#J¼´ç͇ó•`oÈCŸÜÍïh­ýýäaûŒ�½ƒ»4ÀB�D”C¦¼q'}xë³–Å;0g‘hwØö›?ÁåN?ÇÊBØ)q›ÚîTÒÞ7Ú9›/ÑG/Ì㳂Ðâ�t3Ã×7ã l5jüâãs8¨’9u�a.®;ÓÀdyƒ>žGu;íO 2`×Ã3±†M8²-ó�T™â¸/ xöà’̳¾¸àÂü3ûúC~÷OÞäŸA6&zMyÝœ�Ù½4+•ñ=�‹‰:k)�c‘6ùäDã†×Ï^Š MNôÅ7 ð`qOOþ‹�ΤXÒàߘ`Ä߫ǺzæË H#NR“å%ç<ÎC€|Ó϶4ηœŽý©÷£¥ú™ôhªb½3­©9'/b ï;bÅK>–"º.¶”Ã:áräáZâ+á<œ¥gc e�ŸQªl¸~|×ë�Èë:±˜Ü¿æôú�)PìQ�Ú£wDök³\¥s=Ó}ç¬\Ÿ ˆ¢ß_ÎXe[Óå?:°�ЖiÓù öh;ËŸcµˆ8®åê–|ÆÌêY¿œgýø�¿2ÏZy†_ïL퀃¢øÔ »qå^,p†{$£ûÿ:o¸Þ÷ʳ8ØU®×,óD’‘�f{Í'f¶‚ÞÃdàS&o‰Óc.æÅNÉ|>ðoÃjðdšÆ£k¾™õ7õ˜œ²‡ª­f ®Ú›ó›70ŒºqwšêpÙÞ„Ùaä—Ã7÷£›íý­‰ktoUÝæ“ÍšŒ&B=ÄUYeú1C²,W#n`5ôÜ�„žœ7v‰æôÔÆ \øYÇî¤ÿ|ž!eˆˆsïÎqqÄŽÏ÷Å�\ Uðh„ƒ+ý ï¹kMÆ øcœ{oºL‘ÜÄ®'Î5�œ©ÙX49¤½dÿŽîg†'9¢ 4ÊF_óÄ­ÞrBE 8f>Ï'ƒ=76dzвu2¿µCux‰·ÈXƒ·Í'�bX“�€ öËc}ãà ^/õC$°ï?“ˆ÷RŽ t²”À{êXDæGŠNLÒ¹NˆöK�…;N×3£(÷Ãþû‚Ê «´û�sò’… Û'x¨+}Ö®œ™£ŠÈ_½k•_Wƒ shâáæ�®ñç�BˆZ=écx¸?2r¾‡Ó$²Ù Ÿƒn šÙM^çb¯-qãñhíÓ ñèãÃa"ûªÚ9|¨ÏæsÀÍExvwv�¸3?-3VßöÌ’ìÇš Ñ-ëš,3ú3îs©EÓ×h&Ʋ ßÑX_x9K1ŒÖ‹³1ßõ•An¯nç²UdrÂiÅ¡;ÚúZ’€£y5”{Ëú/z�Å‹ìœAÚš–5"<ç9çZ GIÜÖ¨�yç#Ì$áN�ò&y#­�õ|›“³IÉqF¸"ˆ5±Èe=ßöä¡ë�=BO>¹þãX�Á¬Ï�IÞø‚�„aœ»õ3ùžÿù TH~Œp% 1ù”®™ßµ†‡ýêÕb…ò‹Ÿ´ `xxx“k�™Ç'=&$±øB6omâ’Ü¡j}ö™áäö?O¦q�Γ¼ñÁ0;òçüeœwX¯ôâ½?Ü;Á2§ …#õÂ!ó¸ag 7�ï}4¯ûƒÆÃuq&7NQ¤ô›¦0<Év �Ñc!Ѿ'°có›Õ~èK„ÆD¶¤"œœ]œ=RˆgVÚjÁzWVpä9 kœ˜3àÓ㡽v¯¡µS|ÐPKèÐ�0ømÃð‹4˜Ùc®UÂw÷ëN’OWØf]Øû�-é7¶æŽà¯ïF{Ç�}lÀv¾='ÏÅ“/ZèÇ’~ÉÆå\ry_•9jõœª ~cöÕ¬Fj†ïÍ�Ýn82Ê3ƒ98ÍãœV•÷èÕ>5˜Ì±øòH:â¦ëäF †q,Ї�™¥>XZCm®Áa5:üÖŸ­yÖ[L«‰ps¯!¢Ût à±}~9yñp…¥À {ÍY@O~£öô¡ h&ÿk·�Ÿ…iO�Áb'uøo,{÷@þ¬;™ÉTÛ\ây‡ÛbžX§›ÝYS›öype“¹“õÅ}KsâL}÷ÞÆõ-ØÔ©Ë&8Î÷J8ªàh°0�Ã"¸÷˜V<ëûfÛÀÒ{r0X·‰o.Ö³÷^¨�ýéK"m3_ÀË¡ïÄšŒ|Oò³—ÍkH¿©šÈk‡sì|X¯Ö|2|ãáÖž�a6�æßú =‹âÜŒí§ï¤®v±^.åáÉ%ƒÆàœÿ‚=?èkÃxpÄ®±öÑ7ÅóñSóÛÇ7Åò¯OŽ`3yœ åრ� su-ä£ë‰O3Â÷a J>8¦#üÅ9´µ‘2@‹³~ê‡Å³W Ü cñi˜­5ÄâléY 3g&@t{°õZ xÉD½Îˆ¦kj¥uÎåù×ÉjžrrŸµ_>è\K5Ák `Ð@þ®�DÖQ}æ‹]£Õ:šë¼qTÞƒ'Ÿ†c«¿±ƒ),Ci ×"ëê0F8æÕ² cŠ%îò!ÀŽ@Y36OÈöã#Úv=8q~¹¯¾§øàòèê‰ _ìäàÃu ³:3KƒÅÀWRþL<)r¯xåŒûŸ´Ù’.ßäkxÎwûͦ©¦ ߇µ’^uÊ^›`y GõXËú"ÀéCù’�¦`ÐÅs4-Ô-R"âß�³iþˆa/Þð5„KÎâô/Ä¡ì9£5½ÄvgtrÿÔéØõV³>CNƒJöwï%ÝÙ±ý”á=á ¨ §~r`�­ï[ÃôÒk)m²ÌWk¢³¿õׯ2¨Äv/n.Ÿ 6zMB4ÆŒÉùoÌVàO.§j°ë‰gÌzì/„¿6¸4±àL4tq«¹wϸ£ÒHз?&¨k\ı^QçeÇÊp4ÇsãXÑ”‡‡>ñá^%âíÛéQiÏÙ‘BÃ~ÖmÖé‡ù–_ �'1ADâcÃÔySÇ=Šß]†×LŠ“Ïþ²ÈÌ~æy³ÆáÊ 5ä€5×p33ÖgÏtìàõ‘�ãÑÿ!D‹§Ÿ�ž+>8�é lüo¿�©Ž½Ž�/hyþcI\˜ˆKᚥ)2Þ,r‹Èµ : úò9§öäË›ÖÑzÎ12[»þU’)ˆ.q˜²Åg;ks?â®-'LÀ0¶˜�¸ Xáœ1yÓ³æ5Új¼reå%‡*Qzº$ê€�ò?ãxµˆÜ±ÕcºÙdMÀˆXÉcË2ÚƒÛzµ�”³ñùˆ |dlî–ĘôX-æ”Y]ߨ[êË—X‹ ŸÄóðˆ-kÅ^¢ú•§øäJŸ‚»4'º�O™”Žýâ×°7==ìwZvë?áìå�FÖ{Èè?ËæöŽ ¸j�Ý\šµ6+u³`x™³ñ¾öõfyÒ�PE‹Ðãp`.>cr«ןwpoðá8&ëJmà–kÓÿ¨º¦Ç\.òff|N©\••Û‰|8Z¿£`ê}ÁlÇ’@üø¶‡‡Rl#NbX/–µ¶w&îrà�&ëš³Áûó†~ÂÌ»\ÖÜ|p2¬%ŽÎé�&蛈ZÐØ�›?\ÀÎQT±'^¹?ü½¿ì±6|©ÇׯO“øLj¬…q¬'J\Ë;U\æìˆwyX�“]מìðŒÅ8÷r…ýã[ SœÞ;í‹*æÔ¿Z��œ{å&1Î$↑¹*ÈËãÇÀšÇ¼ÄmýÂ9+Æ«1†¢�À³7 ç�ë/ +ÈdoBÄ÷qšÊ^Ãq¬�è‡DmÁßܬ1Þä^=±?RžøOž$u>7eäh½½b¦•_f‡�«rì£LxȇOcП¹èÇ|'ÆÅŽe5ÑW×,çbïô�c<ÆôˆÇ™j³;u KnÇ7ù^Œðk†Ï[KóXâÝœ�˜Çu–S˜yÕ�èAO�P¼ Jylî‹C£Ò\¢_�;ÞpÙ¨(†,äU<ðg>2¬)q‰ØõäÀ X�”v8c¼ÌC}út­÷±¾âËȹ¯flÓJÌðÖ!Ðéʼn–qÁ›Ë½ñ›G³¹k‰ôÀÑSç¦qv>ù_ü“�0øb:꣎>Þ¾†Zíïrd›³²œåT>Ôa>oˆqƒ%fÍá¾úÂ3;0}ð øÆì"ôÝø<¤¢©Ì½´ögã%¶›ü\�ò>Wƒ\ï…€k@„>í&�ù&–Mê‹öná—þô[qmŠç‚Þ»ÄPö�ßð»_Ní|y>ÿM}ø§»•*ÜåæÌ²ãȬm tÜÎ}k7|¬qÆãâ �MóL¢m %À¹ŸÔÆ»NÓéÂó-#ùÞµ‰Å�-º²Æžú¢‰Á)<8yNÐ<C’�Áþðx�¦|˜¶\‡C[—Ôä(ß±�ë9$'#x¯Lä}E±~T Ä®gBˆ{×s‘+)[Ÿ9tYÏa·/ñ\ÍJ0‹– ¥kåÙçX°© N 5Çc=Èld¹èÓ}>�ó:ù ßêÍýÈ_Ç8¿‹'©Àz½ IDAT%±†7kŸÅ»¯Öû6K’\¹~m«azÀ¬U–¼!ÌägpÇ�r.þž"f#,‰•‰:p‚´f”´ÔrÀdcz“`ê=+ÿÅ&f¹LË¥ûÑ^ú Á—8æËïäÖ>e! ^kÌ<Ÿ¶ƒÎV?öùLI¨ ¬“{Œºð m qùš3�Ù³iîy˜“7Y©ÙûR»_Ž»÷Z[×6‡C‹�j­¤[»ü¦nìêC¡G'Öö­D $¹Ó�ƒ‹ëœ aãô9jO\8åm~×$佇“�tù~»1°½õ6_l½|ØÈ_z7 ùúáJŸ1™g¾'xðYžüÑ(©WçÃq‚�žÃå3†PŒûþ—:úË΢Àt'½´´ð_.{}ŽÇ¬ÅΛ ƬŽÍèØˆú$Âì³"PƒœFvf½ÈÏÚ�ÉEñ¾¨.O›½M­Ä9výË^È3\�v>óÎæÓúôä 1ÎŽBo=£‹¹ÉÙ1*MŽÌ¸�z°Öº=|^‡+¯ÒÇ©h gòõ¹ãüZ¯0Ö&„ƒÇ3ÜÇÍvᜣ1'²ù{=Vðè�ÿ‘Ó˜Å$Ÿ§Ã¾ð£?1h±û�¾rM7 €‰ÇÐ^·\Ìö/>�37µŒÿÔI:¾þôÝúÌç•ÑŽW�OøhÎ|s¼(©ó6ýAÓú�Æ›Cbså,R{p~AÐÆ°€Ì1¿5´nóã}ò|òº.HO)^ü¬–} bVr�šÑ×¼VÊõV‰ñÚ ÞöæÂzXé�Æâ¬_¦ìYLù6�ãÎ%„xç�Á árïS ñôöÚI/zYž×†üi'ÕéÍÓWÛØ¯~‚ÈG,,6Š;¹"ÌÁ‡‡D~,èöÓ…àýÁIìá$Ìù“ûh†ÓqjReK”ÓZ-gʾ3ë7åtÂÅ$®Vk¡l‡{æ-f‘¼:Ùóqð‹ëLN×v4â8›&ÈtI¶ß¬>!#\�i°Í¦ûϧ�0 çâ±¹[kø¡CÄh¥ž«ùbä²oú#'¼Ó±ßªOª³]Šl?{m¶W‚ýuˆ{*ôꌞ춖˜;Þu­Ó~IX»%O_²'(¸KÕì-&|?{š¸ØaqÿXÜÂr߸Npvæ<¬‹nº×£“ºãG’kq–Üë+©] �ùCZV¼MÉ×go©Àd²V,{L×26¯¬Me �M¬ëc1¾päŸÇGÿ›»áÒ&ŸšçHNë”-=:‰”)çÝ–s„ uÈøGnq‰�'µ-oz4ÞYAË“ ÍŽi¬øæ]¯üWÞV05lëô4±Ìz Éae ÷“a‰ _°6é¿°þf>À«L«æuáÏLÊ>ˆòÁ HÃkMMf\8Á§¯B{ï¹—ýåXãç„kD)8Ù‘¹{týD{î`ÊÇ4\cB#Üá«`£“ðs/�ü%kÜrqÖÔ¨�ب—àWÓÈ’Ýz¡ÕGüùtºRkÒâW¬\æv¢¬�I˜÷Ÿ©0±öÈØJàÑæ•¸Í ^?œë5ÞÕK¶<à�“+60ŽÒjYåã¼Ö_—9�Ý$=;q\Êô3¹ËÝxvÉ��GôFIœM‚Àï¯  ‘¸¬»e³¸ru`ÅO/€=>ædħѾä>�çjGw`¹†'¨�#ì „Ôq÷ ‰¾d÷,ÂÊõ„¢Î›ŸYØÇ–(­KÉk‡ AÞ8ìµ—½ãSåÊiØ.Þú»µ_—{ÊQÑ@¼”ÿòDk!/í“EÍé1WÓ2mFÇ´y®àé9ñ�BkrQpâH¯\¥Hd£§ëó¯ öé�²µÖ/ä☧ÓYÉåEX¼~ õmÂuâiàÆ³<ܵT Œ8žðë™Ãbm™ÎíôÑ”q5¤fÛ¨< mjsÖ¶Ü`κГsáêwH4Íi± †oãÉÎÚþàϽôm­¨jïé<{̹ùØÇcq={­MŠO@m?º¶—PëÇr;Ê>ˆ÷™A û;гqœc¼ŽÛ¹î~�ÑŸ¨àucö2èà×xÖKùù†.I8÷‹Ñ« bÔå|4Å­óÆ.* Û‹#‡$x”O?Pœ¾z…�€'ÐXÛkJ`Lˆ@¯¯][�ð„³˜ý†SþÕ4õ$A´5zåt�–Ï܉uZ�D«ÔÎQ‰˜\2C¯‡³Øž¸d½½C g½Ôî1q§ŽCNg —Ã"¼>x‹o (0¿öÌîÉ£ù'ÌoŽ�E»‰Ž�³osH‰ß]¸ù&(é[dˆæÄp…Ãt;'Z½°ßK@z¤–ìƒa-1ä>ˆï\E’Üѧ�søµ%ø}S&¯éù^+yÑÅ£aaŠò„ÎÁVt9I…:–7ôøÓaíÔ`®ý((SâRwûë"±+} õøarŒ Ì‘$+ ³ŒøÀþÇÑ3–~'~ë@Â�œ°åk#Ü©Sy–& ²&ãOßXËs5� ú©„�˜ö:]Éü«‰5vævâDl‘¨p¬u^Îhå ôuè#±¡yˆm>âœ×&2%[zNŽ�kþéÕL.�,J/ ûp¦¾ X3Ö3‘ŽjÈ6ઠ%Š�tüÏùë”Ò^ÝÑmɬëÙVL ;ÛI1Ì�àzñ_ËXÇþåŸÍ·F¬0”Å o|êëÞ�ùn]Ó:Žh~U)¦…üÌ~4<÷„w±åâ[æH}ù·Î '½v�‡+DZcYÞœIs‰øÖ‚í;ÒGrh¥¯U©…=QRçôºP.Vjæ!Sòa5¨± „3ÁkáZ|÷¿ ¾”#4—§øOƒƒ ÇtÍV|†¸Üý�ž£ù†˜ßÉ#˲§9œg†öá±…·~ss�óOñ lþ×ONwÝÆj®\Gã•ruc+þÌp>µ±&zs¥W¤¿¾K¸ÕzštX `W^m>üõ�“xß[ qhl1€kˆu¬·`<:íÜÆ`ŸŽž{0÷ˆ@úd}´Ø{¹x—wóê ‘³1Û/½]ÊwAc‰é÷„«H`±xOÀWèÉ$ÓÛ�äLôIÙþáûh1 ØE¸>iòД<Ñ?Lta=(ÊÇá&�>,õPÙ‚ ÏÑ~ ™šNÁ�_ëàeón}€9µ&’+öõê“£ä'±‹ð웟ò¥zà‰æ "¾ÇŸÈ\õ™Bä-Á}X<èaÊ·øØÇãbnŠ˜&vÑ�\Ú{�]|Î9-³i^q1%ÂX 4š Ý慨5¼yl�™Ï³—íပíñ;d¹HÔ¾ÄþŽÔž¾’4¾uØ^ÛQÎBXï“(l~CÖĺØ6coj¯ò›ãÀvµã'*q“J?ØkLkú�ÀV}FÖ}6¬úáPoŸxBÌ¡ÌøÀ g0²çƒˆðdŸmÊ¥ñ›§:N6/À½lfRNˆ»Öô+'NtT# ˜Ö'Ÿ€b]‡ -'à€kõ99ôÅn [BjÅŽƒAnz©�Ã!›ãCmŒ/ ¿ûqÊþư.—ùð6~ù>œÔß3u¬D_O¢Ù=<gC�…|b©œ?pÃkö¹ivíž±¿ø».5æ3Ò4‡«µ[—}º¤@6toï&²ÿ„2Ý„ùX¹ü$™=ç}!²Û%»bYîüNˆlëgâÆEè]ßÞÄ)BüI“ë®õ_–)›%º®~ÝSƒ06ÕnMR¬æÐŸ««`OâÏ'×Ñê/»ýÓOÂéF?‰S_¢“ïRlõå¾Ï‹Ø‡b–OßXY»s¼š/Ž<´ï©½2¦ÞÖ$[FxÞ£7ùµ¦„£^'�æP¥ Ú.§cÀ– ·„8fu�à§‘<%ÕêÄÉæ% OjL-ÄŠ­;‹åµùÜg0©o;Íõ×òŒu@x|•Êà¡Zêô Š=CsêÐRNÇã®ß9 AúèÈ�“ƒSÿj€gõáv_±§‡kÑe{°Æ ¹ê¬‡¦ýå\Þ0{1à�~Û±hò”…sºV±k3Í:ÖÐöE±î[÷T.áKQÅ>yµŒ0³çˆÃMO^-¤â¯f˜ý}Ž›æ°Äò¨išk1ÖiTòxù‡‹¹× ‡ÿ O­ÔÇP' ±Öw-ïíðÆtsèY¬¶è?0 l$îÛ9d÷›Ær“`1©cÿM(x—½y8„‹öxc\±›p±;AtÆ�&23¸Š»?t<.^FÏ7þÔ—~¦¯©·uÁ~riÃþ\³ò«©« ñ!•Gë Øû,±Ç¸IŠ¿lâxú3/Ži&×ú.«ã¬Ø´O.ô¸Á—÷HÓø”$Ïp³‚¾h:zpy<,Z.ßOf i|°Z¹ν״äÈ_£°JÆ ›Ë¦®ÍÐ@ªq½´¦gÄÛMm¬;מŸkL(×x %Þps؇[6Ð9'¯�Áëäƒãç(?ôÄ@áq ·Özä"¿5°æCñ>�…yæ|X\ã·¦æ mp•dAÉ|Ã_®ƒ;Á],aÜ{ÓÆ^ëµÆþ£þÐ}ô Ëþ ‰ÌQ¿�$ý€È)5ŸÄpý!&Ùç˶Ü+'�r|8‹ë&mØ×x›ñho,áB¸‰A„æG-«m½ñì$ã„á©÷ѹœËë=Ū7P$¡Ýw Æ8í_=ôÔ>ìÎê¸A°àgO}«ÑvÙÈ›6ì}�–ø­•< ÓÝ{`øºÐõÔÅú°F:ûåÜ×�èLþi…Óü”¾µfüã´~íü“cÙT/{ïäv­~Ü®‰9Ű²þqx¿Ëƒ!Ðu¨‡~Ýj/‰æíªY[k‚�¡˜w¼»itÕCÍÔûê2†Z[/ñ·'ɤ×n‡~“µAž’ LâWÞ]矕tßð'W‹3Ï ä‘}8”áwáà­µ`—Ì:¼.~.Íʧ|'ÏÈñ».‚œ�E†µ¢¥XÁv eÃ7–y¤óqÙ¡�ÇÑ—Âá¿4ôäYÇÀ¹¸©Ë“k&Ïoü“ÔËêü¬�îræŽ+ËÒvøxîµ´î¨h]–7¦ØV—w‚›‡^ñðÇÕggÂyɵ2†yvÜZõX÷\6»øaáÆ?P/Ì/Žê4uó�¼Æsi/4³>|S¯V|©91Þû/é�„Y—�ði?}Ø—ßë%Xí†/©“‘ð9û^‚a°Gßr,oÒÐ+ƒÌéØG¶ ÞK9‡|«‚?ŽÍöæókOÒô½:I ·íϘ²¼e o1ëá©kØÌºÄá#Æ39Á0TÑYÇòóš^4Ü[£s>‰ŸåÁ�°¾œÓž~ çYþ9 yÐ!‰“ÏҢϽÑÒ}}ù’^'üóõvÉ•-Ë‘Þå½d³ilɤGMIêIÊd¦gõ´Ú4µŒ¤äŸÿdæÚç°X+3#<<<"PÀªêå|�¤•ïôšŸ‘{f­·•'ÏÇc°�˜Ð¼™Jü8„gà�cúñ öž®½{1ÒaÑ0nB¿çP=ãô÷ñŠtíWëÊN½�$÷ç>�Œv/) ò{‰â?Ä\Ž?¸øWŒ\@?�]bæ^ÆÕžŸú$N¡g|Ê=àî'¸S©r–."êèú"3zÄsŠ/àè8އ³ËDžá˜[ãG›lyp£�Äœƒ¯1ȰÆñ‚w‹ô¬M�}¹ÇÛrr u/;�å3¯_éæÁךãéÕòÚµ6NþÔˆòŒqLâòž=°ÖáX÷“œž�«k{Üí %ïr@m#³üàÖLø ïщµ95ñ_l¤ ÙøÄ„“8öÇ'Ì‡Ë Ñ›žuë qéá]Ã7ŽÍ»Ž¿LUä¾øFBãÓ5\ÔâÁ¬‹¿jfí³¯7ìŸ~%6G'ÆÊæðr˜_÷› ¥]CÍö7�Öä^þütwžg~¸Ü3'«¿}´ÙÒ›0ÿŸ�]å¿‹ˆz×W È9¢EŽÐUÁëyÎ׎³º°ŸÞìŒè„·c½Í!ñ_ «â™º\ü1ÈNn_0Ä6ìúã~É}x (ÁÀ§&m…›Xó´1ã„íä?± SøƱAn.X3Ë5QËŒ~\)Yz—˜¬‡éÇà›— œ¹©©¹IOàÔð„@¿Ë°Ž¥ÖXIr=ýo¹ˆ…G·�Ñæk pÉ3¸éNLòÙ—&Y™Ëi3‘Z×b-srä0—ðZ%Ho\,—ÇNŒ©‰ö9@‹¬íž™Û’’‰ÁùÌ–}Ëfs}šÐn ¢Îoy“±¯G–Ê{>.§irNs&vZ‰±¯‰Ò/õÜ0[0ÜŒÍÞh—zzN‚€ ¯¢˜Î¿ú›Æ–ÓšÉ�ö^øâ¯îò™Ó}imðßAæÅ 2Un‹ÂÈ™÷דáö@Cß²G ·#^sÊ4͸‹² ýÄ„Ö�/+à;Vƒl®�Öá pv~qÒäïcDÑ>«Äàa�B9O|2mä!ïu “À2lâ‚ püÔì@ëÀÞGÇÞÄS(“éL˜ÍhŽo#ÇfÁ96ù÷±râ󥛯¥ÍÞ…Ö6Ú¥Zû\�mdbÓsÚéeG\& ‹|ep#’÷Ä�¢KÐÙØ³ÞÇNú*˜Fþ µð^<á±%/\ỘÆ·ç„ù)Eì_ò}öBŠ•gæ�œáÈ:ÕáÀ¦ÅµâaÄrì^\®`‚#:®õ³ú8“oüà¨wõ'nºÙMÁ%IÿòlSÃí'xp©4»Ä%yfßø±kÔ §Yv²Ÿ<"ùd Í·“Ô a‡6ì¹ëuóÍβæ\c\ @”Œ$&°dÍÞtÚû7´»I¯yÎöÜ]M®Q¸ÍÆ–v­Hº1;™%‡OÿdÀ¯ CfL\z+Giد”2~x¬8xQÁ†íÚå(—ý�-å!l ŽõŸqÅ×å<Íñ„;_ú÷Z»† ^�Ö} ô|pÍsÛµÄÄNÛèÂÇÚN“ó;õàÌVæ�«f²Öh£èêKÒ¢k³ÛŒÆÑ»å SŸ#8NdµL°¶ôåÓ›Ú¬÷íöÖƒFöeovG‡òØ �Ä‘«Ö“.œ‹kÀvq;zL®ñÄnÖ@ªŠíg,‡kÿjèÕo›kÛË=h^d5&(ÆÇ‡�­¯u¶†b[^âW>>zÑ~Žíá)Ö4ã'Ÿ×÷ـؘ·Cøw Nƒ+}ˆ!š¨5Ì𧱉ßI_Áææâ�(—VF><¸ÌOlã_nò¥ �Ã’wNfo°iƒx9Yñø½4y ˆÑžÜ\Ñ”ÜEØæ8 /¯·ö8Í|‹‹1\éÈ,™«ô�uÊí4"Šæh[4á;£ÚóÓâäÃ÷þ¤jX—ÐXVïüî�7©b}9X©åÕñí/¼qå¥.û]YÎe½Î{ÿ¤¾™ ÐÅôÇÑN�ó Æ8Y£Úh\)ów,‰üPl몶QµùÑc¾üÂóöðÅ팎β¸vž;˜˜³|4ò±Cβ1érHcX§îè7 p1„'>Ç6¿[o‡{¦µyi g†äêÂmÓHà’ÃG#áY+‡MÂZãÑ’<§GØçƒíIáÜl½·Â@e�9:—ßgP\¾‰Ð oã(7 â5@·³#¤|Z�dƒuaûéÜäö�ÿþ;« ´¦º™üC HHþ×Èë&&5&ñˆµ �¡æÔþµáàLRgÙ5E›O|Ö^þÄ:žÆžgnØ—§¸Åd€y½Q½7Õ…ÙH/^}f&¿µÀFq¦†mÞÌò$Iß‹oŒóTS~£]þZ00Æí�<_îÜMËzW‚Äóøè+~4T-þá w¾&Õäà4К}ôÙ¦åÎÞZ:ß©£Nr�>� ˜6¶YÜÚï¾à²¾`¼ÙÒ® iŽ�ïAl~ƒ«õP­„�¾•ÀɧCý±T‚¼Ùx Þáº8uÍÞØSXršø¡Øó\ŽYÂâ pžrùYja\ƒ\_Öñ-Yfë”;™tן›¿õ: -òŽU|ycÑÞ¾¡6ÿò‹ ]×Î='ãu/”?u' š›ÎìEÄÝÃXK g­ÉE €æÀÑ ë`Ëo,b4,Nß¡ZOµ6�=Šèƒ¯„æ€äX¼Ìž¸á¨ L‰¦ ëô=$Ÿë0*^r¥tö» a§½µáž%Ze;ã~,=^á�îõ‡;9ò\|Ò|s<ùnŸ.^ss7eêµ­y±G{É:)äê¬-Ѳ#Ûõ¢* œ­‡íj\ ØèƸ¸¤eésF·‘`rðð–dÑås*©5wž9³:'Y3¦Ý\2Ï­cøås=ÃlHû胯ÊÝÐÔ,Ç·89ó¹.ñ`I×bN��™}ÎKot‘ |âƒØ3çgÁr µ�†!CQóz›=.Õæ|Û�£8{ëªK!Ð9f9˜ùú*<Ú5OCœËqýÏL’êö¥êL¼ž€ßÀæÎó±¶ K(—k°_7ؼùßîª IDATrÒØ Ï$b?¤ú‚”‘ü¤‰†íéáÖ°l7±�ê9ws øñÃ1M‚Üü‚·îÖwF¹´aµzÿøAU¯ý"×Àª¾±›Û @œa™§ì¶Ôo�nøxY3ƒ[=a ¿=qp…8&d6g9턳žõé‰so¬1xgz´Y”(ÖC¸­W1/'”Û­¢Ä~JwŠæiÍ`]¹ ’ǹ׿Ö�¡ðif»œÓ™„Å�–öyA\þQzâ'e)��…Êž5NÒG?«B¢ÿ´uÍ´á<ÐÞ~c£–S¿�@j3¶1ÁÏ�‹XlRk‰ºuÎ>^~ †3à· /{( xÏçÆÑƒà ò-ñï³@âÕ$ñ©‹$p¤—¨­NdrmO ÖîGüÇOïåðÎ ®…Nâ¢Îäøk£0„qipFà÷D‡/ÛÛwc°ñFì gÞÏ^ƒ‘�|˹ýxLÓó Að±W=ÑwFV}î–“.ž¤B‹Ó´žMàÈð¤ŽpwX *ØdyÏžgð<°’Ã�§y�Ä·Z¡&ÏÕ™úN…Ÿ€j°w‰ux¯T–š†&‡?'9 ¯V$Á�÷â�QÌÑUÇ"3s‘�k'ÓoŸ†b6Üg%±•�`4j©n ͳó3*7óÛ¿hâCs"ÍÙNäA—û8ž…1øÏ™¹ÄÑýË¡5Ÿ¿Èv2¢Û#}Ý™ÀrÞExßœ„±ßsÃ>ñ‰=¯P9¨bÁø‹rœC®cí³Sþþ·Ðøy?Éòr§ñtš™»}F膽ƒÝ‹YGË´VÀ1l6Íü‘z›¥x«ü èvqõÁ¾ÿþÚÚÑ4ÌôvÆl�·üzÄ�î�Æûص?ÇúÃa.{†aãÆdH|ÞõÇñÄZCg¯ÅµèOÔÇî¬ÕÚ¤®Iv\]‡éTTûÊVoÛSÅ9ÖÔ¥w3l†ÞI2û,B‚!ÏŒ6¡E xüÅy¶á–ãäx8I9»¹ëƒo{4îÜŒu6’e ‡ÎSÃúS ÆfÝuxK\öü\<Ù ÌD>Þ<ÚÏiu�\Þ;',Á:j¾D wÿ-Ä%tø ó† ¢lê–—y=IXÕkf’aZͬì¿9;þVã¨Ë­íò$só�D¢œÜl?�S÷kO1}øax5æ¾ötÎó\ø’GˆÏ²¢\¸Ál¢~Äß|+¤?™w®Šž3äG”Éþ$ zi½ÛÙƒr¼Ÿ SÎeNÝHbƒ ¾c|aG_�H21q²%ôÌlgbelñ‹Ë3ð&¹ee¢"Ϭ¨� ›%š3~Ÿ�±ÃKþ—yÞÉ÷N-|ÁÑ nvç-xŒæ%…š�?1|ÞË[<€Œlé=V†‘p(QÓŸ°ðÃn ný\v Öþä°ë¹å¼÷¹ZÅ¥—‹ /ZŸY×—&ÙkÐçv#lVÌ=ïWŸ´ÈtjݺüÖ†>8ʬ4e^žS�ƒnŸóà ‚Æq.ÌÎpÛy9½%¥Þ¦+_ :ÉÉmY`ôæ¿r¿ß–+ß8çë¨('9VÏ€ã¨_oö±¢Ó0ßñ'Ê:÷Ówø�£<&ø¹9‹{~ó5W>NeÁ¥Ëf?Ñ·Ç Öð9<²'fõ¨V^Û4.ªÃ}dYæÇÇÎRHÛÚÒZ`x¼p¾¬ë±íôD¨Y1çb!ÛxµvcpžÁX4ú7Bš0çÕ�¥ijƆÙ1f‘ëíô9W97¼‰s[j®$,·®¨w^Ûí½7b"Qw×–ÛÑh¾¿Ü#Kjw‘Õ€]—i»þ(…Y}� Óø†câæý©+/àÑ+C«?èàœÖ×Nè,�?1r±ËúÔ3Ï‘Æâå/ƒÂV ãa~{ ýWûàW~sÌW:k«£“ÙÛ‡åÜs¶<ëÓ"£“ý{òÀ;‹9² °yžqM�9½û°%• N–ÜâL~Ä®töW<ºœû(M¬Œ'¯ó—“Üì×#Ð¥Ó*¹ñÍæÙµ–w½e[»©»^Ÿì.f„‹f|ÌŠ‹þôiv|·¦ô͆Úã³åÜà!*‘5oCž!œk}8Ï žËý"V…zZvÝÀ5 +¼^L‘ % @Ç:yÅöBñÏž€ÐÈV-°ÛFr°³;Öü 1{]Ö,læÔà€ÂÓ¼ccöAáÛ(·-&"6\@Ö ²9 ÌÆ[¹ÔV¿:ÊÖ£-ò„ûY@!¼övê”cv@–Q-îÓoöÄ¡Ý\PÈr6¦mÇ·üócÎⵞ&æ]äe°w(J#wòkå‰zs‘ l0@Zo ö˜µqæ ‡‰Lo`ôfmAº¸ú;÷pMìD?Á¶¡£uÁÅÈO«!&ça9ýè#Ε•𣛼í‡mÓ9¾ê‚oã³–q²þ$‰¯œš@SÒÕ'Ü[ß©ÑØð,ñ§.m^,ëwïð+ÙqÎMúÕ䮨32ëù胟„¢Éüh¿&3<Ûôõ58.¿�H¤k)Çø™Iµ1{Œd{2Ú¹€Ù³‡ûÔæÅe 2÷ß>­.S#°Åòä\^cåJ.CyòZ³l“™zõYvê|ª?®ü Ó:…X7²Ê"Æ{ë"óoíXÿÌf4$º®?¹w”!Ó“ù´页œl±¸.êðYéÔÛÎÏ|Ïúc‡†—õíÁÉb¾Ë#.]D5¦ŽèI?Ç×ô€rP´±O?îÇÛÍJû›Ï–7é³7®ð&¾,í…<Žè ozGþƒ*xÇD÷âÈóõˆsM·–0¦¿ë2¶q5£'‚“ÁZF"_òõó‹þ<>/ŒMB±Æ•k.÷}8Í•zÉe(7]¨‹*áõ‹Fë/~?cöumÅ·oæ#—ÆøXû72'ãëíž[³Ýu´X/`Á¡±sÈŽ8ŒüUT¾Ì È&ÿ&˜V®/qæƒ{(¬÷�1âô•õü&µó‡ß/FNÐ;·æÔyì}9]tà=¹ åL[¹\ÒäÄd­ZO¼©Ë$áßÁs>Dr—ý,ÕD>– ófÕüÑ_â‰HË£½r‡B“*¤¬’á·ÏQ5c8ƒÔ½f(Î�-½Lâ:M�®Ùkìh®_ÈáМ5ÊHÐ>˜0¬xÜ÷rE]ðæm�±#L+ÙRºd‚û(m­½ëôÏ0á Ô´e* ص‹Ô>Íy�-uZÇÉ#¹]ùÒø—#3 :ÔQÜÙjA¬G��)ŽÜn½„k1�‹„Á¾ùÑ0Î@ÉÙ¼§†DcçmŸ‰Kì©âÔ»×eð˜Çxg<ëÇþêo-ˆ¾›“È‘‡Õ}8 Xô, + �Ɇ3ç˜Ð€÷5ûIшD‚ä<59ˆ<±eÔ¹ ·cpÜyÌô³<1‹=Ü2¼µà?Ó L×!kZÌ={`£e c*´Ë僷à ³Ï=Ϲ½6¤'Óixõ¸W¤gãû™Qã÷‡W�R\Ž_£½œÏ”ý~¶‡ MÍ@ìôÝ øôfT`‰É3>øŒ‰s†»Yé; �1¸kog�ûðÇF.³kËüj†Çšz�«E”:ˆ‡ ©âÖkrŒ‡\ïXÝM‡X3ÂiìÛÈÍ2˜beCiŸ òy³à›ÎY±�ÜÍ…4Œù׿ùVÃñžýy½ø™ÓŸ¯•Ý©§Àµæ­]r¬)¿ Goh‘¢]t|„§;Ãë8<iP0�‹‰g~‡ƒg´ç[ûó�|'¦þÁ\èss ›õËçï�ä×W†´–{® ^£eŽoìf}_$!&›ÓÙ€þã~¹ØsÀååŽX óC¶ØÍ˜–½6§%¿ái‚!�uÀ·á nÆ­y\x^È»¡WómN=#o¯ä̡ЯçaW¼õ��/:Ľgq_=7!þ‚öG/”Öv¸›ÿ7ÙÈ~´vm׃‡ºõ¼é5;gQpM`ñ�7�µñèÙ•Ý~g‰¦¡h”3’�vƃY†‘Í9O¸j+¡õƒï…9üácoVåbà3'jY\ܱáÛP>ëTƒøÃW-¿g�Ä9àæ071øù1�­/‡ã›ï„ü. S<Õò†ÁÃH�Z¬^jp½éE[cÂSpà˜˜“P‹®Ëâg7 7úuH´Š¦?k†öƈt=ñy½Iî>ù7™eà]†cÓžo®¶ždÌÝ®ŠaÍ2·g²1xÝÿ�*X¬rý|cä¼M÷áÒ&=Aóxr€øõÎ|l3žé±±ñZ:G\ë!Ês¶šÙx—8ì¿#¬'¹µ]¨Ùê“ËqZ†1Y? Û³¡6Ûît9ûôIÛòùEì×Cf×ïùÉ׃'ʶ֊Mï6i±çÃPk”{Pû�ùj?5ÈÕrV ù³�Eã=€Oùž»ÞÇgb�–ðb%¶\ Š3qü®Î!Ün,_±s”‹†ÁñËâžç ,ýÑÿ! B°dÚsÈvkÄÛK¶{I. ºÀ¬‹Ql$î›ä¸lk1TÈ[r¡µš¨ÑŸ¼¢�X ¦ þøš7ß”GkSY[dn^Äó3Ÿ,?QËw s¨U’šÐ�ôü†^xöâÚüyGy¼¦.’&ë奤֟~´Æ‚ÃÑ.4a¼œÀ“ïÖÎê¼pã'—G¹¶õl[@q‰>qÆiÛ¹•ON‡‘Ù_`+Þÿ‘–ë ÈÿI =$¸q7ßµÑcr13¼×™yí¿ÎöaìöØšÀøÊÙýðÌŽù'zl[úÉÞv[«ònFPöŽã¾X{’äÍ»zƒ‹ßßdTÏ‹µéEÜ>aby°Z°Ž.æ’� tŒ9cÙ³µùΖ:ã9µ)æÄ Œ½§l»÷ÕˆÂùòâ-9­Ú:�×…ÈfñùóÜ€jD«Ä9·4™×y| È£T^[ÿuñ;ax¼­ê›;aÑËš3¾Ïì´¹Y‡¯©æò¿)§›¤ó5æøBažÙг‘˜ä·5Dßs(øDiíDWQ�çüèÝò¨/~Ó|ðâ\ý0¼qÓDÚÊa96 ýŒq2om€‚½Ÿ¶r`›64œ5þþ»}‚„‚3í¶:Ì]~a——0G¨~S¼ñòÙæÞt�¦øN6/þþ�Y9ò^Uð�+Ϫ4§yµÎ\x}ë=±ï; « ðñ˜oa‹/^›áhž¿zÁF—è°`ŸOÖcŸÛþäÖÍú~D%OÊ!#nt™íÉò5ž¿šh¼îøægÆîÚçn�ý6ï Öræqb>kìèÂÀ4­ÿ¦vk%?±Ã–Æç“ÁâŸïîƒW¸àÒp§ÀšCâN4{]ìB˜ÇÎÕsÖkË(àO�å KîyႨ§oG„ÍJ„ߎþúÄ™Ü={ÐÂX·#`Ö6ëZýÑ<çB|Þ!»Þ\# xÎÀƹxÒk1\„,¾qFO²¥O!<þêÁG ˇ.ÆÑ§í¸"¨ºÝï`�ÀØÈãÔ`±ëéβ{oMÖ§õæåvL1 JÖ´ÄiÍÏÆÖO×µøªÀ¿k°Ã{©�ÞS ÍsÕ¡½í—îå±sý8�ďֿ ¦$ ý8¶¥�˜æsÀGsè9‡idµó~D£p÷œåÖhŸ¼·ICÚ<œŠOÆVâö üØ£žX²ï3$ü�8� ±&�’%y&T }D Æž“×GlüÄ5Ö+­v•C ‹É:ÇÛ^Ù“�qs¶–]fqfãˆÜàèðBÜë üâ‰þ�äq¼³Ø_ÃJ™žVŸÛëG9†X¾[3~´‘Ô=¤ í€ög¥Ø�ÀÔ£Óɶ|ô·�“ ÛÊÇÄ,oI¾õÍæ¾³u�/žÃ);}È‹©Ô;ÎÓ³2_Œ—ÏÖ¨îýl ‹ÍöDþôsž÷AÍÁ-PãŽÍ áçÄ!^×M/VóryærÜx.k]ìÜð9†|l±w ör¯—ë1ûàJ4 ¡ùj/„X¿•ÌRÄ£w ¢;Wr°Ž!Ó0ÑèДˆ@[Óû½yímÖÔáÞhMèú>½]·5zŒ5&™û»¯�,!vóféhò‘!5uG¡Å8�4;®ºŒ Ôy§Ïº±+_¦.´1ÝÝŠ[“À›�GŽß<ƒ Åºªgvf§X,s,'×#¡5½Ñí}M©§½™ÀͰ4ÿH•�‘^yyn`g…mØuN®·ZY§¾óþi9HÍA½.#SkvïªÇ \]ðyskÎÀÜaLMÄadnŽiÂVÓ©5U`¼±?Iw3·‚?Ä]ÿÕ»¾õG´…Xäh±o´Öµù㦠p0²†Ï 6œuXG×®õè ª�|r‘Ãzlí-a×òÄY@5üê%ͧ'e˜ šœmk~ü®Ëy‚²Kuø¾è˜¦¾%=(ã£S8 4ò†˜ôðÌ.k’y±Ýé©5›lz2›çpœ…ãs±]O˜Žže*À¥b;õd}ð uÂ^>Ê+Ø\»ÍF¿‹9¸D�¢“×á£<ý/ý ·+8\b)xöüÄœgl}ZNgh(1Ð}ëPç€p5±Ì†y\X ÅÜÅ$î 5É©‡ðÑ›8Éé ¯±vë|²fÙܯÝáˆB˱-šSC”ùn-OV$fµÈ(.Ûñ³³öp^.#“–åµ J^aÖØÁÒ;í0@YZïks_Êáþ6x/Ü‘‹8çð3#€÷š(¦x­¼ušßd©^@LàxÓ^XË u{T#ÑÁñÛ{ÂÊïãdp6Æ##8Özó휅XgIî�_ÞæjèÑœ§ ºðMvÖáLŠœaHé÷Oö´�ZÛK‚ƒ»Ú°�¸Ãqûb¯Ój¥ü9ûèzkжh‰ºäÀr°ymÆ?ç ýXŠFsÈ�^r:ïÁØË1xÀåÖx_£Š^\8DbÜü·†XðǾâþdë9°ùá³F7;'ãü¢€EsÇÚú´A+àpÅΚÝkgæÑÂ)°¾|{âz(ÎW8Á(¸äìÞBÃÆjôçìô` _ØÒ«"ÆÞývä˜òûÅóNÖ†½Á¦5<ÄýÄv�øÒï˜ÓÛG‚ýo ãËĈÇi’ëöñgÖ:ŸŸà»C{mo/Ó«øhxbþ¼—ø8¹p»wÐ:>yµ÷ÙBÌZ†àc0/KbL—ÆáÉv÷x�Àø«¿yÌ‘ø6’@‡5390ûo‹ÄOïö¤�;Žö¨˜Ù³|³Öýx˜ÑÍi’†Ôy06»GT£Æ$o4(ÃS¼»šf‡¤÷Sº ákß·ÖÝ�óԎݹëu±{& ÁøùØÒºö!ÅÏT‡K$¬u9g×`ä?ZÞÞ G­'0z +Žy±IP¿“%ž°üp>>shùƦÏñG?béÒ8:´NîèZ­Žw™zŒ'Jqþ°d“Ó»s#‡‚Æ•~ôÿg°Kìðp –Q¾?õ£‹ÜÓÌRA¶9Eã�Á€Ün£c5<™üyÎï>jíܵí{®ñnÿö€z¢+’“ ¢09VËýöผBµ2NŒw±¬�®½9ÆI~�ïTÓ85×�”Ê‘­õ m÷¸e/Üž­ÑK%ì“v:r:Ú|8n/s抃Œ‰ü5_štˆŽJÓµ$3ŠØ7�ðñ塤ÓH�Þl¬·‡Ï¢š¾Å} Ç£isòÌ8Z§þ$•gk/´�['æÑ¯;d˜ú�oþs”‡(õ°ÍëIx ²b¯dÕÚ°ß74·ÇÎØM˜ä'd¾œÑÛÿ}#LøÕ•Q\ÿÓ#èñMåÖØ§7K�Mxói�s'>ƒ¬æh}5[\à«€Õûò�OÎ[‰d]†å,ó`šSšp…Oã©¡!ïdŒcK´)d­/{ƽ#�0¨jˆÍÎõòaÌGOƒÆéù%)6³.÷L¾õn¾Ï^Fä›s;“îH¬kRljƒ¤ZË2þlMà?Ï®=ÏÌíÙ4ƒ¥ž›/ž[L^°¿Üí¥ª¾��7i K ëûË�¢Ýk¶º><öÇ2YCß æÛYQ[ê³!lqËžð¹ïòq¬Ü̲�Gö%6�¼1?z„”Ívaç‡ôÄjï¨LÌ­\?˺¥ÈÚœØñ#?9Þ@Áòu,/Ä ãÑo D†]¯¿ÈæM-G;±»Š°O¶s†æÇÙ… ³Ö¡Ø«ÁûÞ0¹7ZN|/VkÎÿÑþj|y™ˆùh˜Ï¹´!WÇòóêhYËN_uâó²XGk Ÿ9³ȉ-ÞÜΙçÄšóĹI‰EÛÅh‡¯\'¿5�3Oú6 øï8®ÈìÈeéäÒå8£vÖá2&!çŽ6çƒDJiÙBbk”9–ß³�/ø £úÖ?OøIæw™ó¼9)æSÿ­gºÜ¡sŒ™ïV+óÔ^`ÊojK¥O¤—wj„ï4?<̺ޭkúž›S ³ºn?”ý8C™}5ž|ò±~¸±Ìm�Úîsù¢Øn3Ö»6�·q(½Î �8Z�G�2;TÏñ~²Û}2=¹Îápt°sÝ, ÏÇ3¼á–ýo�Æ÷“Ëì싨 >ê÷ó$ïzG¼å·ºf‹ô|lìÍ!BBÜSÇê&0ÏÕühXÎM„±ÌšZý&ÛÀÖljÆ5^96û`D•_2#z«�ö¤8/àgé†JnHj=øã >)ÅQÉàŠ“Öàti£ÂÖõž0Á™Ùks˜~_T‚·ÎÖÉáš87mBˆìì�SëýV<;£¼XÇ‹nýkºü@Q©1ùwß‹fÖ/ê‹‹n‘ž¢ícÉÇo挓øÙF^]ÓeoÉ=�rÜßÙ�Ö½8¸±ÀåYlýaù9dì'öÑgeޝ×Z/8ùñ­_ÆYS"r8]™Í‡@÷dòÂ6°ä±½k9Ú·øÒL¬É &•E˜-Ù¡  sµ2 œT c4ó¬ZIx¾Ù(§\c'„Þ;6¯±Ùî³€Ýõ3Ÿâ3§ì®ñð b["B›Xî¦`f,·¹Ùǰ»ûsôÞÜ;Wü[_ŠàbwF§B+ôüÖÕõñü!ƒ˜Ôä…n³™M HóÎGˆÞ•y“ä›~Gë«5þd2~I™_§ØñG^únˆ ãe_ù^n;1¤Æj´ÿ¬ÑÌT"É—5ûä—p¼�8ÞóÌ�½}-‰‰¸íºœ¬ |èbzîÓF,Ù>“z•ØwŸ?»¦Ûz…´.Á˜¹îY\V°îõrÔ6#ý_§Ð>»ùµ½µ(†°AŠÌô8ÜlzœÏ£Ä/[Z–Ýìä¶þ‹:Ì'¯fdì7 ¦“ép°p-³| Í`[ךnÍ úàCb)àôæõ0Ì¥9é̦eêÈ™¼s;Ëu÷5 ÅT"»¦ð�=‰š¬ØõíòEÙììÎz:_›á&ó°=±é>ꉃ|ËÉ<‰³� ÎÃ+�û…è·Èð­l¿®”^¸–—˜gÎÆ3£oqÏlÛOoÁ´¾=s§Ñy#Ègx‹±œÖ%Ä;ƒÁ½>míB§” 5õßÿóV~ÇÔùêÂÓëbmÞg¶ãÄ~µØG@º»ía˲kMY8=ë­±åp[µžFcÚÄ÷,�¯g¬Ý+pî-U&cbz&3QöæI{ùO@œXˆ'D÷þöE�Çz!…G1'µã8ˆcI0;g™ÊÄͧ¹º Ì '»—ùášžñàÒšœÃ{]þä¥Ñá0¦k|7*˜í�à7tÁ¡øÃÝOÁ‚?úâßñÎw’ý,@ŽÍ¥bkM㺄!4:y@î'™ãÓ¼~`ËpBö}¬uÙv`9+x*VÜôî;Ø;—<„RßbïŒ#[ÓÁ-ßË,›y—Š,ÅÎì~8Iýv$xˆY¯r¤ÕG—Ƈ»z‰7B4ˆM/¶o°}Z³moOî@S >¯n\Ψ ¦¹}#ïœT™Þ£sÉì¸5Ù¬L-§¸�¯¸nüt ]‡ÏÅRЕ‚ Oš\­�q^'ˆnï-Üt±N¶�GtdG¾÷Y,½9X¯¤¢¯gët—ÉêÖ;‰•]îÓ.ÇßvpÔa>˜´þÅ»NùŒ%—.ïr_ûá6u;8¼‚Í6œAc׺¹_dׂ7†5j¹sŒF,oª�™8½3Æë ²ç8ótGéÛÖÖã¤_T�f×ÍÅØ¶Ö7Q2º–!àîë[Ïï[Å‹cµÚ'ñz³ZŒ…žº”Óún:` ßÕc`|â†ßÎÑ7†Â½9΋àäö7väI.ßágO~c9a™Áø ?/02ë�áHÇkÍ ~Zÿõ¯»/àù…ƿ䅽¾ø—÷òd^¬L¯VÛfãƼ͛¯Sl²f ©·yzΡî‘:csäŸ:þ8Ü?úÝ7üô~�ÆgSœ›ÁùI[ßx��¼‹Œ†E•íìsÉ�À�a«âd#iΚ�áRð3 â—.÷Ù/Ò’(XgÁß7cäº'®µÿ<OP´±‡ÖÃ�|š|…ù›�-¿¹Ä^°/.¦`­Ó4¾oìl0&ÿúž|ØÉí‰Õžé':Â<Îñ,àèÒ–ÞóÄÊ@N÷xì,ÄUfíì€ú$]cœæpd�6¸Ìž\!1 yÓWÖùÚÁI&€~y^ IîÕ_r¢ª11ÇàþÁÕ…u ùàX)8u@2Z6¿ÑNðú%@�œ;šrÖæµgq©“5¬'v§g†£·#ç,f¬¯Ñ*À`›#2íC�º¢ËU¸Ö7Ðüæ^FÅOî“"ÞÇHIÒ;´ Ä0nÉì­üÉ5ä\=;“ÍÔq´+—ãEn>Ñl¸Vó¼=Œîôbû¼` 7ÃÏe×#¶Í>JÉ™aûµ›\›Ù‹ú+ý»“ú.&ynÝep’ÃYžì›\Ó¸ÇáºWqΧtƶ ¬ìl¬øß¬›µ96ñã&öæl°ý²O·1úþÚm«žåaŽÞÌÓi]øô&€{d6ëíóa‡[Ð>¤GÙ¬?Ó‘¾)Hº wÇ� NÝ\ë£wéð;Çaؾ1hÖXï©ÂPqåϵf¦+è;£�š5�»ªür9F 2˜A¶fsçz FÛ¥§Aذ>{ŸÿzüÑ÷' džÿÔY/¸ÖðÖÉ:_ †¸ 멾“'ùž_L€l «É}ùšº¾“P{³8aŽflû’kóùL¥Ó qóacÿ‰Å¨ñkñä]îë­ò‘ŒÞà¶!ù0ãÑkKÐð4îL%ê9. õ ký²[‹ùዞiJÔ’¨åóLÔU«ˆª'©ÈÝ:òâg¬Ù7w\eÎ-Ë[÷™Ðg­`ØhLûi1Ÿë«.ŠŠ=q>ã&®uW¾)ˆ\(ÝÖKm:GAz¯6íNŒsÀ¿Ĺá™®w°=òr ãÔÛ$Ø££õ‚ÀFª¡ÑÂÛ;l#,Ã:Ïz?Ç� ½µÆ_› X/�¿ù&7ü5›g>Ì®…h ìÖ’¼Ž{°@üÂÖ·$ÌoM³­«ŒK¢€4ÇR¯ËŸš' Œm‡9ö í·q~{äRžšÌ0îÍî1צӯdå>}[ÕÓ"œ«Åº§vó«Ÿg§±õ®7³Î½#׿Õx~í.q£3hI ;ƒWGr7›“cç;¬÷‚Üü=[8›ädÃ.û�Y8¸má×Ú2…¬ÀU´îõ—Ù`ž(þýüµ@IºW�m&%ºzLÔÏÛ¤TPô$ÃÑJ„g¤/×D¹»Á‡g…Cohù áøwæ‚jP§¿a@ºu@n¼öæHIo¸æpBFn†úî]±«Ïq8¬QØÓ“c]Ð;O# ^ àþ'#øå9e=4N®ýÁŒE¶óÛ¬ÃOŠ0î½öÖm,ÎR÷~8YËE,}È|AìÃ�-˜y=?Ô膃aÞ³®F{ºVøpGnΛ·3Àé Û¸SÛͳ8ÂN[á<Ë�~ßüæ®67„ö9Ç& =Á±S4k½9žM1±IA{ùÖ{ðçsÇC\>SU�¿ÿFKóàc„[±}ÐVË|y½à¬ƒtH×µÌÄzíœäÊðÜ8úÉH¯;Ûð‰J¾Ã)£3/‡AÍ!Êé^†¼md�Ög<=1GEüþq±އº¥ÏãÑyêšOjÙ÷~à­‰ë1C¸ÜË òàW}�”TÜ_B¯‡­¯x>Rk§ kfŠÉCcfÇæ¸,”=¹š?›N#Â,ØâϼXâåsî†3Mr^�ÈÎ_¬‘H—ó*Ξ‚‹:±áAó} ó÷׃äÞП:\��«.�¬3’‹±è˜d˜‹Y×ÙºÉ9ÞùÞøs¤|è´ôpEî{Îgûq7nøŽ¯qƒ¦gXø–öêâl_Í/…í¥e ÏELKj ÐÏ ©”oÏ <“g;›jqÍøÛÝ£m~×ÙÜÓ€„ê:j ,öØ´°M\æwL{X ó¿1/÷Û›igÞEãF»ùJÆþ­g¸³>‚=1lþX¢Ë[ÝøÛTÇM´ì,� Ò&¸{,!OmÔòâtêðQÁ©‘t0ÍU)Zh–ÜWï>Y¢åÅ'ÿpWéÅ8âÄX÷GItYSžçƒé©�6êÖ˜låû¸ïyîlŒ;µ³Hÿ°Gùœ"º˜7ç…²œ³¹·U8Þs�¾ëÏêöˆ½kмì[ÃúîäµYÒ$†¬ºoà˾v¤~ÒŸdz_°‰�¢Ümô7jD3V_v¶t¹Ïe*wä®Êî$ éÙ§vg—qõ‡t\�ÎNoïHI±þú–?®oÐz³18/#-)¾t±Ñß^ #Éñá�Åwm‡�ùì\Òôƒµv-ÐèÉÌðÜP[ÀémÏýZm$ô7"Æs'ºåbÍ móawšãÏ.}fýÆó¢A~k/|ûk½±ñÛz¼ØÇ‹gºˆõ=Œäw¯Ëá7ãF —Á[œ Þl=‰‹�5xn¼ÇgxÒ¦7ô¬çoœÃ¦=½}¹À«›cR´Íçu 1Ÿnð1ˆÆ{y¦ L «½ã�&Úò×!Â/;¡ù7LJeMÔ p.Ûa�æ´iqd4ÞíáÀýøƒ\ÄÉÁ¯À® ÇrÚľ\žÏfy/Ìé=„A�mvržG£±Oîøõ0´GÖ"¼�ÁÿÆCžûµÎ�eçûw˜ºNª�šô…öeƒÈdŸŸ ¶-=Âq(gîœ\'Néq�Ô_Ô2Ç=8)/ü`‡NØ ÇÝÆ¯ŸÁ%ïb˜ÍY"÷Mœý0à7&IÀ gµû˜M€ã VÆñ“ogQ>l˜““¼ Ï;–×¹…;|U±gÛÉÑ<¿i±»vA6ó�ÝpÎ) /?84¾¶¨m%ç‹™™9vE5dóÅÄq5]�Wô…�~÷ BÓ?û†9¸ücÉÓîÌ�z÷ÏX“Ý6ò¬©ëÕ;»žrÿÖ–ð8ÍÓOòí�<-f»J"c=zíó`³qîÕP0¿u\ÎÓdá–·8öl…e1ý85³…­…×�¹é°¤—ŒÎÐ7?N>öß‘šîsÛÁ)_J/ùqt±½æÔªYßp½¢áF'Ÿ� 8eÑD¬u°"!vY�úîãÛ>³™œ'•™gÃÁ‡Ï6|¼Aìpïšo¼rÕ‡ãZ ÓDÃz HLrG÷òüSãùXåÀ{r7|¼ÙàÌX Zoórk†ûœËÎt\D j1eض³u ä›ÐÑ6é†NÂÒͼ¥±ß²ËÝ<*°œœÏž)Œæû9GÇ�'<„–ѹ�µÏ`cÍE”‰ðš¨8¿<Î û^„ÃîK5ù¯óê·óò_í`ûB^p¼¨‡�\Òów©ÇIØkŒsZ—s¾ð‰£¿-h&H^LLà8£“Sqì[3°åó‹ÉÒµ^ïűÃVoÓáu$ËÔ|åsmXk¦4óöÓaçË`Znfü'?ý{¸‚¾1ÙU½ycMþÜV?„^ÛÇdž¢ü _' qºËF^íñƃ7Ã=©yÍÃ3G¾——uìŽ×:z±�3ìŽûC&+aó85L'Øp2àðð-¨7·mºñ®ëžmcÎd¥gÇ"üâs0–jx÷3qùÉ£=�ð­þ¼ûÇ\/Þ:Ûy÷6s²Ðåðò6ÍedÕËÆy~€gûãWlž>7“=û�q|ëZ¨Ö‹‘Ã1× < ÍFFë¸Æ”™œNa B/ÞËg"ç÷ç®j¾äàYp"áúWkžhËz»ž++Y€vãà ³\äÙÁ;oyx‘Ò¿ío-|¾Z§ØÊl_D£X|{Atu�à͵µÄ>QQ"‹µÞ>q©'µPÏ7Øù±é=Èp¡uzÀLƒq$Ðûü™›G€ÙÍ$"t›Ü©ëÿ“xâ •sš #zâ}…Ìr’ëàæÜ)ɺÎ_ëøp;‚3±’3Cá4YŽëJ–s1+àòÌœ&ñæ¹Ýú×ïÅ“”¶€ ”�o8Ó¡¹ºð—‡�íÑòêt ŠÁž˜ÆÂQ[�Ä,peÄM‰µF~ƒ–޳,‰ÓÕ¸gÿµ Îù82+¥½Â‚�‘\ô¡ôµƒ½ðwP×gÓ‹mšáXˆýo ÊáÏ587üzÛy„sr{Nè„D#¡hçsqlŒ%òÑضÀ;»0â[ ‰ÃnÖøûAhKoäÑ?ð…¬€}²´Náðû'Š�ƒm1Ô‘Å´B{]æo¾“HvWÿpÿ;¦â>¹^w‚Sƒr—ù±a©xTŒ³0¹žZ™I q°^¦ªÇ× ÷N“3ua“vÖž8Ö_¿@話Ëo&ùO©“Nú[›‰ 9+,½×Ü|òîY”Œ>sÿA§P­Ã9�6y®Ån>ùà&§8�ÌŸ{"ªÔœü¯ßöM‚ vÃWN°"¶Ç&–ºPgŸ¶¯}‹~pâb�Ê®^’adá×ê:•ðƒ ùíẹ§É‰‹g�\$H’á–ûêoß§ކ k.ú‡Kú^‰ôÏø åsEþ}'"4ʽ‰€«n- Ÿßy“ÎÁ9£›#È&…b™=S8Fº{sœf™žR&¢Fên B0^Œ¾¦�=µ pJ™ S’^Ö·žIØå°5yèMj%ISgyúy’H1ãÚ\ˆ`æ>¶x}·›[¯íKìRm½^ýÖ÷F|>[›NpvÚ¦7 ð-–õƒõR7¹÷Ü óžqç�‘ýX˜JdrÈè1›w gš]ºe�ïdȦ5¼1é�Ÿ�·G¢ƒ±œRU~[Åy5“S»d ¨ûÏsõÁ.žø×Ùðn-~Âl“Á–EìŸä=©Kk£Z[KöpTò³åz*TŒ ²ô� DžàœnL [Ïcÿ\ƒõà€­Â3ì¬Ú»’Úm&ŸSÚ3dçüMƒœ±©c ôO»†Ž¶-h0³EÓÍË»F\§õ‰‡¦>cÅ0d࣠-'>&cøduJ¬,8SÜ©Áy¦ƒÙ¿’z#͵­cJ›Ñ¹žêð)�½™žÓüþÉ8 BØï�µQÅj«=opm�Å�£/ï[C4•A�É”ûp5?Àõžý–ÆÎ f…SyÏ+ã€5ŽŸ›g¸ïÚ›ßs�$g<ø›/<¸Ö�äØ}ÀGßÊqyÖ»øÇå´à°?Îi ÷©ôà†¹Vdä ›kF}=B˜=HVð°:‰5޽%®ÖÍÃÁ=„ IDATk±»¹?$!\ ³yàîz¼aI [;Ú7ï´v|\Z§Nîóg�=|~C·ÆøÙÙØéœAܰs}´dONìPŽîÞ¼öFo–âD¿â=8-êó ±¶ÿÖiÍ¥îeÊ©3šLÝ1'ßÉCÊñ )lÞÃÞÞ]ÞůO®ýæ)‚Ô�w6N«ÅM#{üLž�¦ÚÞZÁ 1͇§º]‡¾œñ‡!›±¨Š¡$çR\j·‚‘š}°;9Á/ORœœ‚휈XþSs�a¹ ôó.2dP›‰¬-½Å0]öIlwŠ#á©K+6Ž‘ó<3¶×)�©œ4,2 ?uyxà?uÅy¹ùko„ »zðí¹¼¶$5[�ôÛý�N ºl‡D#ÍŽ‡Xx×å�%�Ü–=gÁa gò±.ÌQ hÎjÍ‹gŸ!ÛÚ1\^Kn3~â™ùZÁ/Âiö^/Úoß‹K/+�q–«u‰“ƒ-~íòBŸþê¯Öi�ìËͬ·Ï{ç%.Ÿ MÙ>/4Ðî¼fé« mˆçìñ{>ûðë"çÙ§~ˆÂB\8bËÇH¼8j…‡åÑB.WÚ|¦9Ïav 4HáX–p$ŽÉ³¶âÉ›c¸‘›¼zËØŒ. Ýü±Â,öùâ¶h>Öò±†ÜQR=€<èÁõÚdˆ‚^¯çÚ›«y y4 ;®|m'_ŸSqv©„íÑjŸ÷¬îpŹq&k9΋ „¸`êM<ëqXxmØá8R{ã jÞ·-S�~ÆŸ;½Íã’¸hŸâÇÖG0ùNÜ«ö$¹ü¿þbd/þ ‹.~s6ñߨ ¸7øÔ'ã‹?¼ É3(ÕZÿ¢›{z”L>»îyÙÅ-Žu›h?ï˜u9ßÛ#ˆy×|ë&ЏÌÑ ~®�?æ2ʜⳖÎårä(RT$ϯùäm®�Ùà»a"x¾õ‚@ÌÇ®ÅY[‘÷îScbýÅ5¨Dy¶/ý±v„É÷›ÌÐ×·:oØñG$÷<ǧ'Ÿ‰,}|ëÍ+;ç�g¶ÕI×G[ìµ=Z Gû†×‚�xÖv¦®í0��u×>­™ÏŒöŒ�ÍwÌ&KÏh¨Ÿ£õ€è'œ4Âákê°9 ö«ßù!�ÍgÔ¤‰­MþÕý‹ƒÒzª‘Ýò_Êb{"4»âv®,}�.K¼Öêu|ÃgæS/ QlóÑëd¶Gjó0§²™‹¢†MkqÿÊ[ú…›½5·óV᥯z+;Áæ´ÿY‡ï¸¬Û¡C—öü¹h{¡ðB³ºFy³8ÇäÀk¨=S}³)~qðØyòÛ.lóaG/�ò×n¶iFó†ã•P’"Äïó9™Ã¸ ÔÄ–0Øbê7Ù¬¢ €W×)X8›ä¿™áÞÊ•Iä öÿÉ—08oï>˜“_yݰBÌsòÁq�«äÚäZP£ †u�ø¢Ì¦ÖuØ(;3ÃÁLZ�ýaŽÛ¶Ï#€ó„±Ô·2˜M3®R:ì¾i¸©\:ÇY"Ê»ýyÁWAoj«(äKúÇ™>¨¤‡7kÓ j—)ž²†À:¨1öùJ†Óëµx|ÍiœÆÊN×ìŽûñ!Äõ•“½µ³` ¯yK8Y;Î nOŸÙx"¥�øY®O@]—Œ5ÞŽÜ^ÆwîâwÜ‚:¯žè»œ#‡ûÃÏá­Õµ=zv�Ä?zñϲë�“ÃØ€{8Ù΋ׯ¿Á; ×òäxix ®? ÷åù†ÉxúÍÅ"-)I‰OÊŠ�&°ïÈ:xÁýæÛxÏZ‡TöŽLvkKüø—¶{>ãÃ\-ÃØ5}ù¸ˆ.ˆZ#K�¡î†à\ûiÛ#·@÷Åë|W ­Ç:míG{3¹ÃšFIÒSr3Pu«üþJ$#¹= êØ`Ð&ïò³þÒK°€½:5¦Ç çb²b¶²èM²Û_äpZÅ…{54<¿í£Íì§vá‰=ùZŒ÷GCršËË8nœØŽ=Ø�—õœðáÈ�ÌhÉ^6a�'Œ�–]M‡Ðq®Å¦Ù ÖÄðo:iNíÏóY¿í­¼ùèétÝĸ=nÎg¯åh æ\�[ñùæ+6託+/ðñ¥”ŒÈÇVßž ¸üƒò,i“¸â½×m/ÚmHr9Ÿ^�+¿±ÈoóñÂÞßÒìÚÿM¿áÇæñÿyÑQþÿðÿá/ÿñÿã_þùŸÿÓ_þéŸþé/ÿø�ÿh)||€…iÄ{Hj¸•NþããZšû†qì«ÕçÁƻ޴wϳ‘ÓN/ÒϵpP9ÃlÞÄ~¹ÒþÄîãäæÚ3Z ¡ '·×µ…›vèÍ$ÃVñ‹o};÷Ää9€—ýêpöÅ;isTÖïDã¾h§.´‡È¾Ü ͇“ü}±Þu–�²ÐEÄÉ­8=¶/ùø36x0Ã)M_ØÞǪÃˮܭ�Üz +öqPœkdÔ©µÚ:u5Nx Øüvãßû,\¦Ô—ê–w»DO�˜-‹k>×Ü‘üù8ºu‚]ÞÔ´>O‹ñÔ½°�7Á4°ÕÚ´ËCÌ´K…û­€–xF9„Km²:æãÕ&µŒY‘ ó`¬Æ2ò{r%òj‡»Tß|Ì\ãÏÒ5Èœ~ϧYïŽôM[\Ïp0ø¹ê_�V·ýÆ•H˜õÎþñ²-³?§Š|xl—sº^qoï#�ûò9­â:uU×"’çj¦ÆO¯µ_ŸÁæ“¥ –ϾÒ<\+±¹ùc{ñÎY"ã»#&žœŽ€†H$ÞC[.ŸU¹09¯‘=…£õ“?~‹ßúj9Xk)Xܧna­[¯ôÔÉä$³9R¸£[° l/»ó¸®Ô¿Ü¶?-ñR7 ÃdWv¸©µŸ§OmÎí �Ê7°Yl†wkcåkFÃ$½<Á^1ßñò&ç‹ÁB^çG¡Â]?v½YƒÖ°k»ö¡Lü4˜¢g9'�?»:&Ïàùó,xÄ$ž¹«3/Ð<ŠqÿŠÖšÚP«°ŒõÛ!/ÿ\}1Ô̸ýWyж²šEQZ�Õõ÷fᆠfH ÖÖHµ@pŒ’¦ ��ç¹; ¼æ—Á¤°–›¹ùmü¹Y Í=ÈO–˜ŸzÐêtòøïQ7ÞqŹ¡.r¬š‡[Í#Dö˜àß‘´4“W/TÄL7q[ËK!gƒÙfÃÉQ@ÚÔ·˜<7á 6#}OÓ(·žS·P„¸©É¹{ÄPCþŠÎ4À»5'FH.Wžùìÿîÿk�ÝS¢;Ž”.Z1R€ê—/2ªmü5jR¾û·eyúi!­Ïú¼†³yÌÿhj焨0jXOwV‡Ã1"¢6zPn¦a±C–OQlöEGxù7 ÿͱ®™|Ž© ¢§e‹¹×ÅÌÅ<ݯ �iiîñ¥ÆàQ üµ¬Õ$“†n=�Ôq9& Žqæ ôÅ|²ÃËp¯´Þ7@ü†�‡Ý‹�é�wE§Qrðâ»fJ*Ï©kúòø·–{gõr®.�ÚS�Xµ½ZÆg§n6ëÆ¬ îõ[ÇpOG/ߌ:Nç¶sxŸ§ 9ÏŠ½Ž xgz›÷>úR¾�7e$w|.M®IÙ§íù Çe|BcŽñ“—U`›†§^lÄZ”oDš³"ñf)÷ᬖÔ>| ëù–‡ïuú\æÀÖܤ'÷üÎ}’µ64Ðí¸N6ê•Sb�£d°ôA6f «s¡Ìø±gVÃËÄïÍ2ðóù9ššG ô/4�z™Œí‹,–Õ\|NŒbÅ›,¹ðÃûÑеm¬ó¹´S4÷ô9Nt0B±gPËr*ƒyyaŸù+¿ÿüÏÿÓ_þ·ÿüŸuý¯ùÿÓ?éÅ?½¨ë?üƒfÿ•`^(äÅ>ýO¿z1��‹ÿú_ÿï¿üïÿÇÿù—ÿò_þ¯¿ü?ÿí¿ýåï…?º�ÏYƒ¢£­Ÿ3|¦þ�ÒÇŸYîGžãÔ�gTÞSOz”çÌjtèéeê'.W&bÑÁ×Mx µíü‘f!˜�Å6V`ü¬%êäô žˆ0Õ¸´±Í²îÒjÈIÀ/'ÖűØrúy€œƒ`Š_zDw†µz;ñ <¶öswí®)ë™Ü#™zü‚ì OλH°¥5Ö‰ïÍÏ/µ¹qL©‘\ôåÕ¡õrNC 2¿ã¥cNMí½éˆšÈô¨)]ÛyFîøáÙH!<ºÝúÊc¬½²²§>G[Hž“£Cçq¹RÇÎ&µ½œ¡~íPNáé'=©Ã€ƒÒJŸÁå6ÇÈŒwµž±þ.óàVÀbg+ÿí•3èóVÏùä§§TYÜéÇzp¨«éˆy#”ÛtØî2&æ­õÁ]óQ�óø8>zàs𥀮š£ƒý¡ž–+jçÞßAÈÀߘ´ýë¤Hˆ«±Ü èø&†=ô'‘ ãQÿ¾F_ht¦¦s{ÎV÷ù~í~‡º²é=½$X—Klí£;¼†×upœ¾®?åMn8yž¾Ã:Eb~÷éæ­ÃUØÙ]ÁhP�wšî¢ü5©2¡¯JâÑv¦,lžñ�&Ì}â𨿱¯ÆäúôÄk’”?q­»Z‡gƯËäP »äÆÊç¢/¿¹ÿ-;[Ë&œ!l>šµF—öÖu­$‰ƒÛ`ÁÛ±¼áã,§ÝF‡ãe¡ëPÖf3ÜáÚ�¹/7nèµk8A5æ½ë×k,ß8åä]Ï^—Û@÷B†Ïk%?™NHðõˆîá0±�­Akç”ù<ÿîM4­$°ÁGŸcãÝor;§¼‚M;ë¿ûþçÿ%O)›�÷Ów6‡`B?؆2å§ÇúÉ´^Äð7ݲAùeãÂ0«h^�‘›Ðƒp¡î«°ÚüwX§h,PÛV ~­Ñ¶FðÓs>�þË¿ü¿À=ÆÃæ]oÏLžÿÞp=î¸8ø‚¯µø ¼Ÿvðpù ÐÊÚ÷ÜÐÈ×ô’/ÏÁ7…š½|½¸!áVRÖbæúX½vÏZµÊÈ£þ†}ÿö¯ÿá©=:‡Ó'=ÜŸæI Hk0cÖ‰_y!™Î£¹qo®¿þ-ßäüë¿üË9ƒ£q¢Ú³átÜÔ·º Xž[—ÍCÄ—ãíê¶lÏ7jû‡~ìèEÀÙmÓxçÀ¸ëˆÿ˜Gö_,¸wàgÜ3�÷ß‹û›~ÄÎ*œþÿœ½ûó¾Û]Þõ$Ù{';ÉÞ!á|H“ÒVÁPI(õø‹£”BQgl;–)íT´j ¡uì8ã_`;Ò4�V­¢•hgÔ©x)¢#­¥C-„r0 �–œÈaï�x½®ë}­µîçóù¢u}¾ßû^ë}¸Þ×û½Ö}?÷}?Ïóù ~GÑF°9œºY–‹_�+gœ>Q±6çôæOOãW0ß:vฎ¹‹“.Î.ÜÞM}ÈŸsóåsM` b®Á´xÅÁöÈEræð—8vVÃK­˜�5ÙHîãÓ£ñ9Ô+Vq–nt„sž*µ;¾š×æy»=­O�1¹œ+ýûÌœT,÷\kFøätgŒÅÝ<’hä‘lÜ9üˉâ[c:ÿ—œÓyæ××gpu•U�æ m-;£�ïw>¦µ‡ÏÆòøT–ù‰ü)Í7Ÿ¶{ñ…V�®µ ð–§cà›¡¯Y`/œxÖFÿs>ï�·?ü�o»ýc_þÖÛóÏ¿ÖþàØØ2Ž�$ò^±=2zá…oïû;¿rû‹ß÷?ÝþôŸþo¿ô¾_Ò9HÇs._ã°1f:Ä÷Xû>`﹜±9íZ›È&©á£�^ëríWxTË ¨ÝËnOi]ïE�‡ ËX¦nÞ.¹ýµ�9ü.íÀHÆ[ ®´jŸ©apèó R{#ƒ-{åG.ô9WšùäŸã·æb0©Ù»Í\ &¢ýàXѨ—Œ×u²…eëáŒqÎ��œC¥`úØá�FåaN‹ËtÌ�˜)ZçÙ%+çh“?µ¨<±‚e›�‰±{åSrÚcJ޾Î�Ç­öPÛž ûÖvxÈǶ× Šc62i®ŒÏ–¸H‚]ø¿ìeº�ЃvÎA>WZÙÜby�‡Ôs¸â„C­Ñ¦)Þ yoƒEdæ=”»À»Î7¹ûuçPz5ÜàE Ã2ð -é£9 ßê:7I©ˆÝO¤™æ®/¾ {²!K�n<Î-i>&å�qâ#?}w\xåÚŽP̶‹íªãüË|ëugÍ7ÄÚäo5Ó]ptÆN»èªùr¢Sû9>LnûjŒ4ÖÃË�ëÊÌ�Ì›|&¶‰HÞý‰4²¤“õ|±[tºÖÇ8éáIñˆ#ÿÑ)½ õž¬k†½›ý7V„ƒ�‰0zI ñÐÏU¾¹#öI¢öÕ9þP :׿¼N­ëJóÚ˜Ô”ÖóÄájŽÁ•ͬsÛ’cqÊwöÕƒšu©Žc€œ#<5 &¹¬ktßGàiÓìŸóüpæîñkþ]7HsŽ‘·î¾öI3ì¢�oæ~äÚcç%®}<ÏØ�>Ò]ÏQ�ƒ•øg&ÖI�Y›wJ|¢5‘±e7ÄÖ4vÌ~úÉ#I7Ž9 ?Z?Y·r©9Ë–Âõbü. ËoùŸ~òE}ÿ&†¹ ‡rcŒp^ïö†´­³xeã5IæÃÅØÔ=¸Èy£‚�ßi’§cÀqpƒÙŒd[{Û —É+þa„YëŸú’Á VkdÑ`¶VeLca4í`TÑÂ"øârø`¸8©÷˜MÍk·Ás°/zÉꇽkvNìøØÈIÙJvòs ä3­ÇX°›y7[�»iý¬Áa×"{¸êÔsØö­5Jó¾ì—Êgö�Mhâ�vë꾓$ð7^j”ñ–ÂZé‰E›˜lÌ…å´²¦ŒT¿:h¿cÁó¾!9�”‰'†Œò‚cŸ‹ãø”›ö}8t'lœ]–Ëœ2àMn‰‡[ý€U¿9sÜjºòÉzG|?+ÊæÙ\*’X±lç�ij_qp9e›Ÿë°ì&©Â(î^‹{ù ÔKáżŒ} vD’3fæëH`­§‡µÆ�vÎM‹Þ}mbI�/àñÃ�òjÃ�uCCâû�vC–§ì4¦¬/á¢+Nãæ3[‡­œ àÚ,‘kyn^À­ãè@VÃ×úƒÓâ�|yݱ�lOŽyH€¬Ÿ†=1ÏÖwæTd~#‹Ô“pJØÚJF8 ±žœFVîH�e‹�E¼jœw��ÓO0ÇðºNRT@Æ7xõQÑ5*þcÛ1´X*0q¡EÜ3FäK·ó\?£ÍC-ê]Î7€ŸëϸDÂÈ­öº¸“Œ°Äåg,^ùªWÝ~Ë—ý–ÛÛßþ‡n¿þMo¼½úÙWé¡÷ùš– åG¼ž›ƒžm×À3Ï<}û¬Ïü´ÛïùÝÿâíw|Õ?{û±¿þ“·w¼ã�·ù+ÿûíEn"„±ø)znnOñ»5|IxıƒìŸ œ=p7rY9!ïb#¢yòµÙ²TlÊ1”u«(’A0ë—ëKøºHêø˜3`�¼n[Ìe7öko\ÙY-;6¶Ècœ‡a‰M„æ™9#ïÌsêR=¾Àáw_äI!1ÆÇ.ñÛ &®×€¨áè‚6'wãO\«æÜ0–Y#£cG£T¶ÏhúWÉ­u1ó;á­ÿò6¶z^̳ô�5#që§®kL\p�l3¾Ð»ÖcÃzPEdh{6ÆúÁ¦ºâ �í–$�: ô@c( Û¬�%8:Dˆ•:«g>k„ÆLcá8ñkîèw{5Ùuþ?¹ìxËÐøvχŽoÆÉ?ò°+"žÃÝê]»Óbgûê¼—¿šž íÜ<|c�]qÊÌvY5XÙµƒeëˆþÖâ ¨–žg z@p�E›®�°Êy`ÛdAàˆ+¶ŸÐC>À1낈‹ŽdØÄ<ÛE¤Blh²Â0ƒ=¼8WOÜñ{v0&^óIýX¼KkôøªÙ鎣dñS§úUjwœˆiê3¿1oRØáêy™ò´R–[÷„3¾öÎO ç�`ÌÞ¶6Vò’`Ås®øª9OÐ}|GØ×F÷ðsÐ+Aã˜N[Ƶ…Þ®%‡ÍŠ?v¸ôÓhî›&sÙyK�ºÑØðpooZûÆ17»h#w'†'* $ŸO|äßF¶²®�Š4ûÄ«$µ#s¯” úí�ÖÔ´ÅçlŒïcÙ^Ë’¾@©§Ûáà®ô‡È~Xê*H[õ´+VùÂO|á/\ãO“w \72½êŒsÆ­ï6ÅnA 0•�UçWe!Ûíà �ÎáìÄ46>V'Ýb”@’Ù„‚Ž•-�¡�FpPƒ3ɉk<«0HCë^Äž±êƒàŒ¹øá޳šÑ0È?ËÖ¹ƒÄ¹{–'öšœqÏ6l—IW·“�<ªE¹µD^×{lt®�â‚+íÁAæÙs,ù+˜U’{k`Nv�Sõ±Å¸Á‘¿ícJÔ+#…Ü ]H£Š­é@hp„×ì y×'hm¬×Æ<´‰>am§ÍâkýpWßÍÆÁcŒíɹëÆ:ƒ6֯Ňpª]ë’:´eâák™Ü§¢£ÍØøH†«»S#s•j‰>[ôÃk¸¥�V¼îËãÔÙpxŽ|Õ^~ð]üÆ–]xIk:²ñ†§Ñ«\º—ïÂ7ó¥8ßFêF†m¼7;xðÐ6®—1Éž¢Ý¾IŠ¿ýª®�ƒ sä©ÁØãà‹âÐ9×SݬÁL?ħ¹\Lg¹A~6ñfÍ9q¤Km#‰–ÿ쨽cÄ,ÿ®;ís†¡1¤‹ÑìSljxöe¯nVÏ@ýr3,ïêŒÌ¶6«cÜÙ6V4Å¢:‰IúÅ ÏÔ.êYe¹Çg�’—ã(W×V6æhð‰c”[¿ô^2ûm..Cu’»¶ßEÁ�¦¾àá¢8Ë/úØí»Å¡À@Ÿajxį¸<ɧR‘Žó£—hò PÎÊMrÖ YK^0õb䌈C«¹˜ zÇÀijCwÕÆ� 'àñª³m³éš‚GÜã·^ßM Áا™»º™÷¡>j Ìkò3®„‰o'[_À©ïZm+ë¨3-µ�ñÄàSx´|£`úRÓØ}Rï ?lø]{Ÿ zâJ×›C ‚ï½€¥� Ÿ6¡»½þ Ÿ~û¿ÿ÷ݾò+þ™Û§}Úëýi?Îmü¸9hºåè)G¯ ‰›ý,…, a¼Bÿ_÷ºçn_þe_|û’/þ–Û/üü{nö;Þ}{÷w½ûöq}òŠOg@‚¯ó‰¸pÏ?¯P}œ£¤SšàNžh‰\Ûnm$UʶÃǶ±£›9ñj²çÃuzW?ðèÞ± ûÚ[9–‹Ã!òfg®pÂ÷(kÇ1Gkux{¸°=‡4þ¶ ³rXǯ¦ª8úü̘1OiäQýˆŒa™èáŸq½j®Õ¦Ü<“V­:,¼xóĈœúÑœ�ºØmjS«îÁ7G ÄbÄäxÏ•Qg®<å8_8†`œØéäu™£4 #d]Ó{�ØÃQüXž•Ãx7HëôÇ=µKlú�'£ùÀ”û¥‹-AÔ6 9R1·Ezlí‡SzÞ/{ÃìùÇjµ]Ä«H£Ö2µ—À¤IûÎG�ˆ•uD…d"�÷ÚžóÜüâ'æ1˜^#Œ�C-fí`µ`g-á‹®ÇpÄvSßsçX°PcgØg`›ÚÛD1ÖùtùÅ ·e‹|–�½f†ùb.^`Pt~V]Ì£y ·uj ×Ë)\cÕnÊ›p²3?CÊ~bo^Ô»#ƒšS}Ï Å5¬Ë‰¥ÚpïRŽäÈÏæ6µPÍ7PÀŦ¶ãç(d“`9òÄ—„#²QyÕc˜eÈvÒÜ‚£gþŒÃùÐÈÏYmsÏHxÉwæQ£ÖÅôf}`³j¾�ÃÎrMö\N,ÿÔ(Ëžñ}s¾úÞNzÏÝØÅ:ÛS.£…�¢ßym=ñ.ùÈxÙ�›¶»*YÜç>ø­ÓáÔ%)†ë0èg Û¹WWß™ ×7oPçµÕz6ø�ÿm’G5{îõŸ•¾I�ñv<¼èq9_6.ä…Ðú*–¾b€‡=±ã�qšú•{¼’)qÿ6#´Ú¯É4ž´ü>ã†ØåcžØ” ̶V!{4)¬{UÖXûXŒ@úýP¢F8™Ê²­O>2›¯äfJ²Žþzpùnö]\{/…s 1a×eAÌsì‘ìÏ:´±²ÿè˜ï|dV|UY|ÖÁG<šd;"‚Ä=ç¦+¢v±’¿þ„GÙD¹è‹Ý=_Å"ý]P3 IDATÿ~5Ç0'¯•Ïι¾­!>­�ã7ËW®p ÓÚ6‡å¶í$Á|>¥¯AðU,í»µ @=PãDËÖ1ï #˜Ô¨q—ßÌ0©‘³›†H:Ì z¾nIËWïè%`æiüµ{4®¬»FöŒÍ…‘›9ðÀ_7ЮÒĪ>‰iúÚ‡ã?>nÞcÇ>˜ÊvåU¡÷çÜ×n'r®ƒ‹[1µ÷šgMÛ7OA¦ÎùšS¾¶ÊW€›[x0ºägAxYå$&q C,Ç›æÚ=²´¬Nûö›V±y4¨å|­mn“ž…µ(ði˜>š'µÁGs§äá«�Ûø‰�ŎƱã×5‡×�àX§>ë‡Su]§ø6ž!î6'gbm?Ñ3N÷kn-Þ1$Îæ’ù†´¿�Á40²&ˆ“xÕ]÷ÂwàCj>ÈÓ‚Õѱ¿³#' ZO’r‰ø:5|ôˆõµ6ÛË~…•¼<µ¶`G‡&µnýÑÑoÎŒá±ÆÓÚ`LÃ'ݨñÕtyñÍ|‘»X}×”‡j6³ êÆð~xHù°K8AÍz¢Ï±�Dƒ#ãâšï<øãu‡¼ ¯µÁ3  ;Æ´>4ᜅ=Ðã ¾ð nä›Þ~ûÿ�¿ïöÜs¯ñ§ýšû“ø®ÅóX>Ž®VßÙPCÖÞK/¾tû;÷ý·ïû~àö-ßò'n¿ôËï•§”®¿Ð Ëø%½1Ùfòa½PúiíwÌ5—ú-�ÅÑY.§Ì%ÓGO{ÙS¾^‹€_Û‚ŽZxO<ýd>ƒUß„arøÇ(/ÃÍÃÃ7RGŒ×®¹Ê�|pWûl�ÄýÕ¼~¯_ë€ùø¶6�N× ˜ {|V¾Ë&..?Ôvv¢³y·N–j�ñuKøÁ³-œ:bßCÞcú©}sinõô¼`{ï>�cTS ÷=N¾ÔM¿æ@[™pá@ï>žXŒijÊ`lÔ Çø­riè97ÁƉ [¼šTs„£œ\Çž‡lŠõÞŸk¾OÚ»‰Oå¿û8žükÕʯ9#iË5ºj)_³� Ûhòš¸y“é¡AhÂÇï>ÏÒ�Z¿¢"á>"×lyÝy,—Ø_Úï~°¼<–Ïâ½£&,Sgri[kd°rý0×ls�‘wlû®ÀÁ ÞØX7Ôßç­È–kM œâO<¼výè8öËý-rã~Ó0çJêëõ„òh/¬9úÂRMÖy|’÷ ‘áofgÙ9û×pq�Á5:r|dŸýÁ†:ü—È~8¦•wßÜ@”Éj•#X\‹/ sÃë3_§æ˜àØ9óZLMþX:[ï߃Gãbiޤ”]9;oú´ »+·:Ñl=ñø]k`­Ä#b¹ÑÜW\æfÂZ†­N£[œPÍ|ÚDÙt®ízÑ'&1z¡ÖäJWöb?‚‰¿-¾'§pÙ[›•û»×H•Ò¶qðïÄ�p?<¦.«<æ×À‰†¦¶É ãÁgw±aôx�…¸7 ÕÀ·7byÑž_MЂbøâ‘§Þ;÷û`¸ R–†ß{`s†µÒBä\\pìô÷˜%~í‡Á?ç%ë Õù Ž›Ãpswô릦W)@–Àåe:¾Ùói ¤džøyx‘,1�v' ø™Óè± ¼ø"š¶óE ‘܉{ö©!²\¨ñ»g?¡c|ßÔÆ‡x�ã?L> 9Ǫ·|Ò­5ù‡[0wÁµÔ¹U“\¹ñ¦}BS×:—º«©¸á;9÷¢Èžç&l·d/~C‰8ÈÊ‰Ž­µñ\2w¿ñ䀼îL-‡£½DÓpN¯x–v°.ç­!êx�›æumÔr=ÇÊBY˜¾‰‘±o¾ÅŽk^Wà ùÁÚ”a‡,9Ù ×úo 7ç¦R^C^or àJάÇ<”æÍ’ü>EŽsËKäð¡nÔý¹çž÷õøºßó»nŸýÙŸ©¿à›ˆgåøÿyOºSû˜æ¬ñ;ÚØ¾¤céCúðíoü�Ÿºý±?þïß~ô¯ýÕÛ‹ªµçGyR3þ“Sû}`Ü1{냻ևƔÁßÚp<°(_¯qHËq¢s¥×$çr®-�$ƒÌ5nC“ç˜IÁtO;÷‘�û™Ûâ½ežv]£ÍTy „ç¡ó÷º` CK ëu�$í¤¾dŰ€ÚÎ ½ä]§A0²¬f¤ð¶Qǯ;¾®ì¹rHŒÇÁÖù㺚サ$£DØ^†¨pO^!α„w}Ç&çJ®3àXýÙSÙ8�ò¯n ¯±ª�ýJl†>WÉ„<Ü—üþÍÃÎ{õ½ã!¥s=…\ šp®Ìc<¦6>ׇkåuÈqá6xúN� b¥ùa¾)°ßx"¼yΚ‘ÛžPÎó/^5>V›žmp’/üòuî‰oü`ÖÞD،Ύ,ͼ6 Ë„0lÛy¥`3GÑ›Æô#©ý>þ3_Âô¿Î¯ì–óÄkØ ÞŽ“ë ]³�Ç>�ØÇ‹mãá$Mh�Ø'ŽÄk-ºV‚5w$g+¦'œL×|c´°©‹Þ¨A =nR£ ]Ê‚_ÂÚ6çœñ�y¶À‰¾—cáô�˜8ô:ƒó$¯áå³Ë‘yÊ\C”w²3þÇ<�"ÄàÔyO?®ÒŽ.ãä€Cràš�ùÎý­mkLs•ÿÙZÏS†qã¬:Nsrá0šf¾íkæQ[ˇZ2/~Óöü¶ ý\ºº<Ø·Ò©Eq›Kl`ªÆF+Ë¢{à'n­;öœ‡8Ÿ¯ùlrn,àÚ6·�¹›¡íÖb­—ö‡ N˜ÓÀs½Õ_ñ¿6ôúº“o?vFÈÆöGŒCåº8gbœŠ£ßx‡ÈÝ?Z§Œ¨‹X‡£ÌN[êÈõe~gs_bæ-k}®Ë®µÐ©Aqƒï"‡p46Å)tPV‡á^ #„8/fmNf�»(–Z�h5AòÃü$~Ʋ� Æ[}û*éþ>@»£>'i>眉—Ç|¥ÁŸ.ZPòDÅF]ç+Ý=Þâ�™ã«S;bN\ühh÷2Cûî¾­÷ŸYæd w‘ øà‡· „olöâ‡KçÈÜ�;¡²‚c�€¡ót^“yO œÃ36•…/T¹YÚ˜PËkôpÝîXå³âÀëª%ÓiwÃG�þO0s¯ÅÓ<ƹÇ5D®FlWFùtþóqðØ[ßøòInñí6µJ ·>êJŠ´ÖÙ>p“ oÈ[²Ë‹®52²Ý1O’ƒQüNŸÄÓp8úêfè8[¹ù2D&?öó™ç9Ô&>ܦ^²«¯ë6õ³»6 œÍ~Šiô„N(Œ&Üy‘N>a£Ã ÐØƒ%£ ÞØá x0ØBéZèš%pÆX¶†‰ˆdÇΈ-öa’\4´£8$àªÖÁL¢~ž€?íê°æ°�µcsòŸ�ö–c·m£d‹²k7£|Ê2òâðuVx´ÁÁóg³#ú‰}ÚKä‡å5¤’;†{-ÒïìGd� ö�ó¼8î€Á�¼;5O�«}�Øœ¥–’é³ÏÎýü2è#�1ÝÎ)2×ùÒ|ì”_t–‡;þÆßAÐA™DI­ò ÇÄï¹5>µžºÙ?¯§ã»­•c×yöŽê\‹Wb›OV†xÏ1³ jºJí²†Q$'ré:÷ »lŒ€žc´ëÕ 5¯Qò_‡1ï b2i¸¾9‡nJDz'òà ´ñ3�Òñ�/ É“)où˜;:‰yƒB�¬Æ6˜øñ`+µ^º½ñsßt{ÛÛ¾áö�ÿÖ·ø+¹þ˼øË�ã'×(`ÆYY‡ 1,Ÿ¾A‡˜£ˆŸ­ÃIP²Ñ>‰,,Tü~Á×=ÿÜí-où¢Ûúg¾íö ÿ÷{õõàïº}ç»ÿÜí#ùÕ`ËŽ‡~pòͱj&k r°(ˆkMPéR#j¢ÜôãðÎuΕ€ i=¾~õÃ_L°w&ÚÓKß[×I˜_ô‡‹½|-¨ÞúªªæÌǃœOt@Ru„ÛµÀ t?©ºñ©–¹FÆ[ÿ¬ÃYÏË� Mô6œ�q½¦$�òzž #jG]ñë<ã^ ¹?Ï¿Î)Á ¥fsÎ- ué;âÌY¹¢J�bW4bª/,àv}40PƒtûØŽI µ¥��ŽÉšgÉ“Óa‹—Ü×|“X·ÊÑn½çYªÆ�6úâÚ CL=6Dxt)$رÝq�ísj´ÍÎûp; gú–��m�y‹èn«Lü™|¹¿Ü˜fRÏÙ76Ù+O87à�gï%ŠÝÎ#øR°¦ÝØÇ÷Ì ÉŠAg›Å ™Ú:'i' çÅ‘svñ&phÔî˜X'CEXÎãó\Ø1ó�܃œ¸æÝØLŸëÉ5?ŽŽ­'|­­+á"ê6vö¶ý¼'1ØGÞsš§lеp±É䄺ãÛ…7ÀJ LÛªs_WbѸ.ã'v„îälfñ~©Ep½ê`46Žt5~¥-½b�õ4pšgý@~èÊÅ©Ïk”þÒ׿õÐØq£q¥ƱaTœòëÞ–Â\µÇÖÂn¬\‰I£ŸDîº QŸùµ_ž¶qMe+ãŇÁò Æ8Zó¨ :{KŠec`j ŸàvŸ—9ȕǑŠm–|Ö�n³>ß*JÚu¾ 9ðþR“ú–“C eñ²Bæ™ñ,žû:&É µÖØÂ<®84°gýx82ó&Nckßg\`•7æÈtùX8Ù–ËËž{ƒþ p[�OBUýZ{Q((Ð7 Xº Ës�vôTß ·$Nà‰¿È�­ _?Ù7†‹­0—ÔOŒÁ¶=¤BôŒh!i4sÔ¬q5ŽË]^’÷ 8ã–s’·Ñ.2ÜÅËxê;™ÐÀJÝ�__}O�o0ü®7óÌE²S}$§ú“‹â“ç½lñó´ì›gŸ ÃÙù¤î®íØîwÄîßñŽ�ýÔmþæ99‡vYCž,ƒ«j3÷õ Úðˆ‹Í+Ç®±¬¾çŸ¼»È/8gVÔZÇ"ò¼Ì|…ßàÊç0çÓñ;¯Ãµåß/5ó’—~5Š�õÕaÛ¾ºÅ‹_ÞÅ¡ÿIE�ÄÙ9Œ¯ PÕQø.Ñ]œÇl‘%ÏÛ/—ï`ö�yæ{½Û$·uœ8A¸ˆ¿~ì½­œ÷\?0A €®�~Bi„ž©enr©UÞ™ï§ÖÊ6´ÄN_#ÙãŒ�­Ì¶.lýاÔÚ¿kˆŽþá¿ZL4o×ÃC¤å¨~þZ§­cçÁ¾F‹ }x¬8ض%fGÙG–¼�„ë�õðN.ç_cL~ñk^õ§´” sû(=d±]µ–(ó›ã-(ÙkqQ-‚°}èq^Þï.æk/Èið‹Sæ8ÈÙZçnl«K¼0n~"“Ú¢ok¾ŒO=s*;›êP>-">ùô,vµÅÏ–¶ÝëèžC R¯xÐÏ `±]ÌV'¶DYʆ›ä©‡,¼ã­×p^}®”�ë$;ÏþÇ\èGÅʃ�ÄhM»wH/Ž#` †LÛÉ<üëœãï&Ž^Áî'Ïù ðŠ—Wð•Ö§o_öÖ/¿}Ó7ê�z¼ùón¯~õ³Ê+ç8×և®Ih\§ÄVÙà§e‹˜#-D—V]…§ý!ãò¢þzðû?ðÁÛÿøýéö'ÿä·Þ~îçÿ–ðUcž4MËM "âOïÑÍpzáX®äêvGbK¦1¯�²åë�Øpíe<ù ª¡[ûûÔö6ô®Õ�³^NЈoŽ!@çH�.JbpòÚÐkøKþ”�®ïPóðB€hSþ„¡Î9¦oÞèø‘~½9e,œéÄwÀ—,òHcÿó‰°7ótJØ®˜qñ,Ÿ<änŽÑ°MløÁ\öÙh‡&ÞÇ&#òH¯úIÁ�ÆŽo„ý˵õ‹wùeRªÝ ¬™—x¿\—Ááã¼b‹ËEc¿HÖzºÿ+ÀMàÀ™ÈÙ=ØžQèß7âEžïqÙe"ßhY§~Ý׃|Îé—ý–˜^oB·§ClïÍâ�­Ð‡¬8öß^Íš>í±ÑxÕiÆrà«–äÒomX£±×ƒ£u-t^Y^¿Ø<Êótpù‘íù€|ù®¢Ðº¢Í9¨ø©e›ÓAÿã~Ò¹Öhâ1Ä.D«dLòM‘TÅgØvÖÅGÁ¼û“�ë•ýE4¡â7먺ð>±NÞ‡|Ò°¤}a¹kžJKµäur_gþG7òIg\Ë)µ1Í9ýµ2w™‡Ã�³ ¬ÙõV}ìÈkñœ@]sà–Së×ÔæÔ-[&ÕFÚ˜ÓµÎ&|¨Åe¯õÎ÷·¼Æø×%´Î6ÞÜ&ùì×ñbEªI¾Íáš_õ©£5ø{|òhNí¸¯xŠO)æ+ÀþW¸��§ h¸ÍÛÏ>îži4o»OýèƒÌFH“̯Átm0¶VF&ÿ}O&9Ÿ®Çód`vó`*åÖµn(×;æž;ôÁV‡úywä½xŽLó˹…ó•-¿3ØÏØx Ÿøø˜Ï§2Éy xÙóoøm ž“_“d“?SBûð¬nöÂY/ƒ—k’‘p�±bX"C»BX0ãö«·˜DhÚ.¹œ¦™ÐôêÇ\Ž=±¦v¡èk’çbÒ já+œÆÀKºD9ø„'À4èÄms‚•'ZJÓÛàã›À[_Hjá§ŽÊJÀ᩽ƒ/º'^¿yå v[bdÔ>Ë õBßXì<&G»ÜÕD¦¾Ñ™žÅ¸í™ro£‡„ü«>¶Ëj쮲SOMúîÚL­-§FÅï@¿Nâ¯ÖÇß½ÌÉü[çÖ©ûíIŽÉ¸2N.§,ë{.Ìs‚„ø9ß­Þá$Ö#ìXiñÃ*­º«,ùD·ç'ñ‚[î 8á†#ï`ä÷‹ Þyá›àÈÏç®aã6ž¡�M¯ñÓßÛËêÙâé5V÷=v²&SKL˵±¡ ŸµÇ()г}1?Ö?e÷6ŒXþ»ÞæbÖe[¸œõ«æážcŒcøÿ­açãdåFçêwŸ˜Ô‹ZbkŽr±Ýá ¶m%KÞ€Øèد"Ûòº9ã®>Ô bwêÁ5ûÅÔ(ç_'éñ]×FZkP”Ï�sïŽÝõ˜­»Ê£µLA™'.zIÍ7ßV§z{ï™c$‰O»>i£.Ÿœð¡í¯h1J ÛhdÙZŠ/1äׇ7x”CúÝNB GYšköö48ŽD=Öý�ø#°®k¼³á—7K2Ìyò4ø„˜ŠJ”ü@P± .½öÚkt|¥Ÿ›%·­"•;9'0SS‹ð�X�?Þ@´ˆ±ÍZÉ:�½#Ps€ÖdüGícÄÈÚØ„sŽÑ#X8’!æF2{¯KÖ&¯;­ÁžW;5‚÷yQb1t7ú²!x±eHýâßíÒKa•`` fRP_ìóP½O½åÍ9�Îõ·P›ÍÉ]~8IT>ÝƵ+׎€éÞ%·^W¢ð9 ìkM �°Éµ¼’ËR<À€Í•z r°‘ Ô>”©ë¹×±{|»ò\ÀÇ8Ô¾\º¯\{Üœ‹‹y(è*Ç<dþ®ÇÎiyò£ÁÛϰõ­¶ãØ4‰Ôª6{ìλoJÅ‘k_ŠàëŒm¼æòŒ_uæ÷IqTÉkM�“~híŸú`º’G̳¶”’ktZíZÆ/¨ðÐ$ê½Z×fsiÝü LçÇ]¿+Î}žõ+ΙÏAÊý%=¤ Rñ’_ìU…™ªU£U/,NŸ=nlKìœb ?Û=÷ê®ÇëònäæOæ3ç$ó�K¼Ø&·ÚÛÚõE²1ÛÇïŒUyyó¬ Ç·c.Œ\�bŸØÄ ‡Ö"ãȰºÏ»Æ.ö^'Øò¶eDZ-k’ó¹ŒýµÕké´··1¼15¢À ;w§¿s©<ñ˜“ØííØJP•k Çä8OrýÄëˆ jCk76ñ†c{-¼Êœ¨¤©ÑÞÛa¼ŠÓ9Ü:zÁŽ,¹“Pò0ÎSKÕs¿jâ)w1_-Ü^ö)ŸþF}ŠP�PØp.ö%kQQ%’·etô¥¨{š'Ù:Iˆ,³ÈŠãú¡·Ýø^pT‹-ûÁ:cß��S¨&ùá`ì€àê†Y˜�àLºÆhîXßéÉ(üSŸÈsb yîž'tjˆ8šl�WÓÅG�±¯›ßŰ9$Üøîd#ôb–!1廨–]bIšËøäá£|ä}ô‡5ÁP´=¯¸1Ñ,�ùJ­‰ºNðÙy øp†+Lú«Ž%a×XlÅôË´¬çû´ö¥“õb:‹û6Ó°�·j#Ë d標ÄbóŠÜc>‘…ËÞ5žK-aËDWDÝî#½êµÕûH{ =ýˆy¶�ï †Oú³.ëVÝ(ëäbo=yµîs¼j\Ö;ÿ'ÕŸ®OrÉ<�kÇy GlÎylŸ=­œèW‡Ìco§D²¯íÒW¶Œ7¦Eƒ~}é§M�.<°ËZÐVfðؘ1ÍŒ…9|m}ÄŒ?–´§ÛJ·IÈïÊÓP�l@íô]ü±·Hqì£Açã¡i8F.÷6gœ³�]çôôÁ&:>åY�‡ýÊçtÜlísQƒú²'€÷ê&“®˜Ò·Ÿ½�V‘�ÄXtI`Ça¼"Iï W™ÙÓ`p�Vâõ8E$k¹»þÆÚð›[2ä¢-óã´fÏL�•ñ„(ƒî8‘KELvsƒ4ÆáÓ1{lŒ]]Œ9®ló†Ô`‰¹aü ¿ñ7ÞþðÛßvûGþ¡/¼½æ5Ïêá`.Úñ#ß)û¥ï˜Ãz‚’B[ÇÝWÎþ”=Ò?c^ܰU+ŸŒ²µ�•ópócûøí=ïyïíÝßý=·ïúî?¯ƒv}€*s–‹éé3/„EçôüäŒ}ä篓jŸdâŸÈ»±=tâŸ&‘rqwLÏXàfÛ¸¹ˆæÈþbÍáY¿ ešÒ'·p7ruc=›ØgmePl¬Û_|�`ƒÁ�>ˆ\¿ÇÃ6Že‡‰•øèÌM*×�±úõ­ûe§¾‘e›±ª>£pCÖ¼NyûìáÐãã”·_^Œw ê_‹½wVTkÞ ç‘sãÝÙ†�ž°iíÎüVÌu“öй~5‘DO?ë(IvÖ=m,[θùœ1jWŸÚ€÷ó+-õݶ•ï}q‘œ5¨O9\ìj<+ç~ã»s½ÇbOŸÚWÖùOlæ4µª<Ý$' ­¢&áèG=ËŸXíÇ3ÛÆ¼#æà�Qûk>á�£ŽÇdh!èZúñIÎüÏ8ðé¸ÜR�dÚÖœ ø»å¼ÄxaɽuFîZíÊ»ØÝc¤‡çƒè²Ý|sos¯+ä±½rŠý�Ÿ¥,²‡¤¨µo7Ýn,'�‘œ³èJ_"ƒk�%{g7–‡+þ"6Ž�¿åaÐq(`<ÔÌ'Sj‰±WyÆrïZä\o_@Fô¬�U?ô2ÌZ"î®Ãé�¯±!¡–1½0ßûÈ,•m¬‘ñz 7Pø1Fæ�}‘M²«e¶põåŠÁ)o 6Â]Ùb ÇÔ‰m·c/³]ÇÔ% òStçÉñ¾,FÞr�•‰}ü[ó¾YRûÍèÚ;qÁ¹›÷ë>ís©jÈ©Aæd3XYø­ð5£‹†ªOyÁfbÛ›ª>±¡“=.4ƒÅÐ1Ø£:q&æ½ ¸·©/<2óцw¥õ.-Cß„ìðè�ǧÓ:®xÍ}t‹ç!nìêÏ6b/97Òácÿ1Z6§-/"r¼·Ã¥xÔ ‘Ê#ã%Mù'ž]HÆ,×NŒÁ$¶9ê‰9¾Cp¡J÷¤1oó0‚Åíå@Fò;ÙÈJþÄgï¼ð±„t]òNŽÕuÓ ±-Žnº•ËT6ÁqÿŒsØB�Öw\ÆúŒ½Ç UDŸú¨gã5—ÆtŽãg;úÔÿCžY°7ùyDá`Ç ž4'¤¾ÍÂÉ<­—�O,;:6\|°íÍ…ýdŒk�°¿k(¤…æ<†K©„“” hÖ…ؤ1ߎïO!Scý uvë7qìm‚!\ðI¾®aIâ`ûÄ5ùŽ�Ëžåæ IDAT㊱ƒqßùH烱9½0Ðv?zÅQ­zº“×ýql»©Aó¢4µôx¸Ëï.ÊÁçJ¸c´Â-þê¤^²Ô?އ¬É!æZN,>’ŽžÖ´1ñÞÃÔϺŽÍ;’Î#üwL8 W?eë9�SW¹eâ•âÕÚ‘ƒ%PÄ`ÚX“¬cSÇÉ"æ)‡C˜ó�ìš/Ê™#dz­ôã³8„Aê9ö!;¡dù!OþPîüÚJ ìdH)F7›7+,ña fyÓå5˜c�¼¢ÇvÛØ=q%šá YZð·vÄÚµå͘O1±&‰SyñSçÂb@?qÊ%Ÿ@r¦ÉàAÇÔÀop±NQø_yÆÍ¯’s!kÇäv{öÙ×ܾò+¿òö{¿öwú�z<û*ýQŠZÒ¶l¨]*�˜…¾’§É4-ó^¥wðø«¾4>mì\œ˜g tgkÌS6}Òh<â¼øÂK·_yÿn?ôÃ?r{ç·¾ëö3?ýS%Öúýfz$渾 ‘”øÏC êšµyk„³õÚ÷Ï'Âb‡¾ ,ZrP_ÅÉbŸa㎹<ÂÃÎøxÌ(x¶›4ÌKcØ$ëÂëMrgÈÁ˜c�ìcNÆ…|´Q˜}C WD›œ†qú ÙÌrr´}è)vƒãøpÃŽç'ÏõË÷DbYÇS2Fîrp|�ò³*™u®WëcPsäu‡%I´ñ§FPZ’Ù.VL-Àú$þÎó©nœ½«lí©ë÷æ·#-7°™ó¬Q’ì /³U—̸œ�M7¿úbGÿ¬£e²÷œKm¾Ž»Ñ­Á�OŸOÞLó:´bz ÍY‹ �1À‹XÕ…šèÇXè&4]7Å]‹.D-öyT½ó!Xêÿà8æ`”ŸíÆÆúå8é2‡ÒNˆ�¾²{¿¥N>\«øçZ4ífš,ëüœœcxÝšçäá¹°ÚÒ£>Ÿý‚bI"Ÿ€¥¯­�í]ËBx¼çâ™úßD¦Ë8è'¾”ž_i¥tMI¾íĹô5p‘,ı‘…cäøÈε!Dýíî&‘ä‡k‰8›Ä�h×}ù&¦·ÚŸMí%àŸŽoϵƆOŠƒ^®¬ÁDÓîhX-�}!Ôžâu¡¶x¤]|%²çaoýŒ½ÞèËêò‰î‰1Q/õñÌ:ó:ÄïëØÐX»2;±P®ñ‘�ùHgäØDÿ]³©ß(ÜÃÆÉ@#|<Àlæ|ÆìøÛ–X´‰�Al‹õ˜Ìs,_®ãˆëZ&@xSŸac[�¬\‡[ùx˜7�ma2ål[¸BŽ�ìz®jœSg{ÙäuG×vÍüöm¤Í�¹DÏëwBÃäÕÉaŽï.p "8š/†\ÐÉ€Ä3RÉŽO/Ìó®/úŸøÆ»,Ä× ;¹øØ�mòÙ|d[þØ9':ÎБ]6ë+Àúž÷òŸT0v¾ÔÞ‰Áä×¶2 ª%_§ÎWIòÂÝGlÛ|¡©aç�ö|bc®äâ ª§þçÞ¨Ô´¹?Ò¯=ñXùˆôþ]L «Ökù Þ9‡*¬ÙÊÀµNM\ޏL»–.{ã0gÇ_äÅÓº|®ãÜ<ú+Àóµôb{O0ƒÅßÝÎ '¬©`w¶ûÕon³/þ©·jB-ùÑ!ÿUXÉöºÉÃQNÒ|Ü™þGuت»„(Ó:¿�‡”:4·Œµ5d@)ÍÖXVP}uŠ¢s›kéßùȹ’¼ô3ö<[°sl,àï[t×5�MlC„µÐœ6÷«ò¼6êëÇ|OâSò¢¨ó°†Ö9|œ_kкf\>ø§/>°¹o;.¶þ}Š~­à&ç¸Ñ‘›oˆÅë2Ÿ ¡Ðø»’�ä­Qmêo{»ç˜Â�cØï wb$[¸à©1ßþ¯>X^ÇDqú³Ü$nC<kÏ�„–%úbæ�éSo‚(~b˜ Ôäþ´öŸý¹o¼½ýþ�þ¨Ç[ý‡4ž~æ)Ûã ~ÎS&wœ6T!·5úiÍ3NºÆ€èç™�~ôc·÷þí_ºýùïùÞÛ3ϼòö;¾ú·Ý>ã3>Í_9¾¯gq½?âd¾ßµ=,±«,a•—D:ß~èÿzû›?ù3·oýÖ?uû�ü�Û‹ú+©¬x¹¸NçE= ôƒI�‘Y(~Îõðé\"¿Ì…19Vy-Ë5¶µ NÖèAáͧ R5ãŸ9‚Ì5_sò×”‰q­�‹4þÉÝ@Ë­œ 7ö ©>&R;›‡[�!‰Ö¾±ë8èòÕ:^¿‰ß¯µáI¼Ú§×h…ÏÔÔÈwFáuæœzcf^Ø`¨mëîQ„ÖÔ‚k_? Xµ¬ß~hÐÔ“3zfwÎꬣš˜áˆÎÂÍYž©sl[—®�‘Tc~÷,Çe~oÝ€¢Q Ç_qÖåŒlCf£àõ¯4y.fÑÿ䜒ݫ_kéßc6|0‹-V÷˜õL>äŸsrYÚyŠØxò ÁÙ·ëfF+æ>~’'¯9þðÈšop/P{|”9Bm;¡$Æð2Ÿ‘Y1›­?¥é_¹I6)²}«<ó—ÈG!ƒÇðŒ#^Y‡µ%†ú3¬M"w2j9í�½šÓ<}�çN^àé7t|®‹o¶Zçœôã¦Ý•ƒ¤ƒƒ³–#9ô­Uá°XxØÑ&ò6jé¯Ï‹ËzÈ/el¨Y-+ cMüSÉXÏÉ«GAŽiê_=¦¶èô8ð<é5nwº�Ð_*ÆÞómþµŽp›Sâ\¸²Ž—XÐ�©¾N ¦Õv L·xÑ%‰;Oùké¾Pp€‰uÜ‚Ñ5É ¦Ý}>;ÓÔŒ16—º¹†ÚLøÕï´%i;Š“uiÇ ˜$#u yÎߨS·cŽjrç±vrCŽëïs¥4þ«ÏÜßèA�œáļò{öth¡OY�«ëxlJ¨bÔº¸ðÃ�$'Ð*|íZÆ&1ÎØ8OfË~ñ�dtýço‚SЗ뀡ñ»y8Ñ HÅ_ îðLJÙv>8N‹TƒÚv¯g|äÃð Á´ÊýÐÊŸrà�€û.ºbùâCr|Úÿ ´Œd׬�5NyTÖñ»NâÄôï9ŽwL§zÛóĺô�øµFOó:1R5Wî[š^ý äF8/½Ä/ßW½dzî|Í�‡)ckc¤]ZÏ!õ)çÚYfÌdnùé*É?¢±·¾pûœ‡€;šýŽy°m'¨Ç|ð=ùž6 sqÃöàØ¾„]Úüb{Ú¾¸ð0›Á©„:¯­«g�_ÛÉéÊusoÍoÁ½PóÃ@ýÏ â<Zø±Á¼|Î~kyó‹Wuó*ÁªÍeðÎJع&FñW�1mæSsaÏb7.y€›ýìÒ¬bÍ$‡È$´~|ê.erŠcóc´çg€fTÒï2à&þÏ$@i#nÛ¾}*ëÛ‹=¦¶Œ\¨[Û™ÌSÓh™ëû‹Iû:¼vÌÇù€Óz&¦Ï­\„ÊaÏ#V ,Kl`߸¯ºÊÌoša%c_\HÆ|7·`€³óÅß�à„ÜZ[D⸶DÅ îÎ…¸�µr\ú âßÅ$n�é(_g)HÆË×Âô;ŽZ�Û€+0Œå��R3ø ÇñÌ7�ýG„Áµ†OÖÎc¸�ñèbÂ5 -�6tx 1€c=ñeÀ€p1‹B�!_kDã§õG=þ©òŸ¾ýÁ?øõ·Ïóo¯~öUŽ��ëX× |NƒÈØt îj’—ÿ’µ#ûÌ�¸èuãƒúðíÇþÏ¿yû¶w¾ëö£íÿ¸}œ?@¢Ÿ§_ùÊÛoþâ߬¿6üoÞ~Ãç¿IŸN|Õz`™9Ê:/,< bÚååÁ²' mW�ù„ÓÇõõà÷þâûnßù]ßsûÏþóo¿}øÃrŽÄãã’ÊŸßH�¨ çY6/*ÖsÅC+нøÂ b¶žÂ]ßìQ>3—X�-ÍÌ"+€H„vögìú«ÉÝ4»�ƒÎEç›c`M„X6q».¬¿�)k8¢ËÚT¯>FšB›³YMŽ©xõGÜ댼¡Ã§Cã[.b(ÿðvaÏëè`Œ�mìk¶8Æ�zS³ûf.s={Ío[bÃ�7\òǧ²>Ê•:¬Öî]¬`תFŒ;óêROŸ¨mønì6‡«ñ™_¾¯ë ½6Þ¯="¥íØÅ¨æº?¨OâÔÎÌ%ºp\ ÊE?ËSv9Æx@ €š¿ýûõ«ÖŠ@·á´Ïœ&VBT ›úÓßµ[ÁïMb6nǸ¶Í|óZÙùË”<wähÙr´šKôà˜ *šÃ»œã³æGuà 鱓‡çù÷‘�=»ñ¹Ä•¬ÇRדM´uθu·ƒëuÁ^ªb¤¿ë íO=cCîwÚºfŽ´ºj_ÜÆ»bóÚpÿ8ÚçÊÿÑ܉ć󾎹<+бÃSá| €¡•uÜ%f> =keX9TÞüBZ´"Ò_y£¬ßX»¶ÔaÊÁÇÎ䀃ì¸x*öàWoۨئé�0‘”øawÉáp'ŸÖÆxUºu|ü˜X†gK…Êk³+8ñrž]$¯¹¸u²ÁÏëDÜÊoaêu†×šhõÍK<ë¢óüÆÈz¬qžËö¨qª°ó“õ쓳gAqòInÄäàzd†—Üîý"Ýy‹ÖœÊÙâŠ~æåANØé}ík uÌ…ÚÇWNÈïã´þ§oð¤¹Ç°Y†=ÕØ�´œHìà îÛŸÐ�Õ¾_ûŽ7߃�žæ8È„ß\Ëßõ˜ÚXfmÆþÄ Î©xlRÇsþcÞ]´O�:ïkå¹.ñ�Ì�±�©bFôÙëeÈÓªatöÇ£„raž›œ�Œ3~¼ö6s³Çf¶ÈÑ¡�\èÓN]$•¥.ؾ\¨Í…ùú‹Sû"´ë&þòV»cC¤þ#BñļŸ2;ó ¾Ž!ýdÞ“Ó>Wæb2oF„礱yØ™‚Öil)X¿s;ÄhÆe'~XÁ±5bÏõ~Ê!rôóIŒ»}* »³8é·Ø�w¶oÞ»^hÃͼÈy¸Ç7qýF„/¾øñÀyÞÎxÉÙJ‰ó©ÍrÎÞ‘4Éåäùvô‘Gs|É蘣–ì±µBÍöC |N¿Ij¤gYRs‡]sƒkyòðÆñx‹Â[6Î1ŸÂcDër=h‘-¹´1}èhß]}xéfÓ©YWžŠ3cã©Ï¿Ü°°žˆ’Zs=òê×¼æö¯~ý¿vûš¯úŠÛ§~êëõi»§ý +„Ë�c~&†ã×™ëqàræµÆ’Û\6¬Á�}ü…Û¯üÊûoÿõóoßömïº}à¿’79áŠÍüPEŽß7½ùM·oü†o¼½å-_¤O(>¯×ð|}q.k ¥ÊÚ¯èžçÁ Søñ ïïÿ þXÈ_¾½C=ø'~â¯ç®éµÄ7€Yp­¾äÏ@^¿¼è7m‘çZÐöȆ1 øØTÁÈ—ÆØ9´oi6Y]²™ØH™scƒ!ßÚ´+¾l‰Ñ›Z&ͯ�Ä=\§yÜȉµb8ì^+°få3\šxysŠXɵ±î÷ñÑÃà§_iŽÔ2…2î „‹:ȲA:ýÃ5’ô|óZ;®•i4 Iâzj«:Zñiia­O[¡;PÐIÂÚ°Æ*6é]5µµ«ogØ3µâl�Ë&{÷7 ŽûéãnC»˜Éä¬ubŒCŒÌß|�baÖÀ±¦a×0kôÁVN½ÎÈÃ5ò#*›«OkNÙ^×W5É®£Z–S×ôÃgÖ†-É@T"Ö7é—<�ù ëDݼNܦÎ/¬²�W0£äØë}ì)o­�÷¿o,ç:ƒùnývì3*ýÜ�BRqgQ™}&ar~¬?Ù¸~ÚóCýù×vÎQ×kuñÍ=8ñ^ÒuÆi_» ¨P«bu0€)³Ï¼n¹Õ§�³Ëã›Ñƒ·žó�’\ÂejÌÔa &N¸„Ã…Ï[}×N5HMd?2Ððkí¬'×Á¯�mæZ›>Lí|œ¸ÃÐåþ®YtöjwríÚaozÖwa#oaÔO¾Èè�“ö¼IO¾ySg^S•²´]¸ ccì Ódã:Jo• ƒæð3^œóR{›+2}çþ–ë6ÚŠ¹â%·EÍVÙÏIOò—ºHµ©ËÒä°oÑ7ÿk2°;uÝïp��¦ÅÖ¾yÂÃXöL�áæÐøÐ§O¦ðJoE£¦NòA�"¤|!ˆ‹‘ î$ãäÅ4x+Éh#æ8¾àžX¹I_9ÞîËŸÅæO0Üçà4õÂÍ'Õ÷Gâ'˜k‚{B3áºvøÜœ§XGà„À÷¼$½ÏÃ/6z¸¿aç…éúHÔÚ2ÅØ{³]൵!L¨ƒqè\šµkމjjÆxŸ|ÎOµpüOÛö�/N=Ïõ´l&Þ©[|ÁÍ ¿&äÜ4Ê'>sabÛþÌ©1\µÎÑÌq¹ÇfJcCTMÈ)¸Ž{èlÑzv��>mb­›Ú9A¢ïœ´^Î}3 Ù³9!yÌÆîŠ Åæ‡ø§¾ì¡kÕ’wHÔú‚è�7FKNÎý£·¬ñ„6jwI'ìœÏì,¯q;.gK*7‹Íƒ›Þ™ç�w›®X›Lkå‹AÇ�Y9»FK7±™»%;1sa x±Ù¼q‘Â~y±ñ¹R7ÈäAK.œ¢³��sÜ–×ÕŒë°ß  c›xpƒë Gæ›c‡OÏÆ%Öµ+Wt»Ï)žW›ÈêÃ^Ú冚õ‹3ŸÔu¶g-õâ‚wåçFlè-L�)ÄìD§+m±×z!Ì•^ŒGn^2`˜¢E}n‹ÅÞ_Ÿ×Þ_sjrIû¨9ÞgÐMŒ'×5Q­/c'@ÇJ¹FÎx×7ºòà´_{±ÕÙ´  9ÍšÙLï×_ŒÜÉE?åáñ<¬I(rí áE‘xØÀM÷S~@0_sšÀŽâÉ—‡ZUSÇü3Zò܆Klcž�-½Î%ÖëwÙñW ©×oúMÿí�þÛÿ–þ¨Çä�z<¥7™øQLæÀ¹‘È]L†èÝL8ÝeÈÆê[ο/Ý>ò‘�Þ~ögáö­ïú�o?ø?ÿíc/|DØâ˜d a®MÞjK˜Oyýëo¿ó_ú]·þk~ûõëÁ�q@F+wu›«å§�úŽmíx8Ç_þ¿~úgoïxÇ»né‡~Pœ?æãÝî.…ÙÁ?ýÌ3Î…O².úIA `¢uÁAu5vXö?r®÷Žq"•š›½1èu¨•ûØy]&N×m½9¯;<(浑?ürµ� ¦1à•9q`CÖ‡µ”¯“– m{l@98±Û:ÆÆG¤Öz<õ´jéׯ9W ëÞ6Ý1S)ä!q0•ÑÐ1µ‰Ušä;“sìÕeT‡ ½‹k!Tv8Rç‡uêH/íZò�è¶£.$y>ÄÓð$Bçl‹§„ÖÛRƒîk\GÒ:k$“ÎU¼ .uë¨qE’îcçœïÔ„´m‡ô‰ô /»¾™F.›Ï‰)Ú‡Ô³¦8÷ûþ–5É3&P¶ß‰¹û)'8}£ÝÔ€®Â¯’3–îjÓ5}Ö̺£±É›cèòujzÔC¡>VLê#yò¶Ùlv=-nWoœËù2ܱéÁÆoÒóCŸÌ· ÁÊlͧ9{ïzD«#—©Aí‹“šf½­º•èá^ë²ê„³xúØ™s%¥ —Pµ�p¼l?z§Ø[âjóˆïiŸ(ÔmÒñèÜäžl®+j³ápÖ|Ç rùã�¼Ô™¾#žyˆ«íW2”ï×jضph-óæ¯;;–9 S.\B¹]°Ú”Ë}®X¢Kžwœ­0 ‡¨]Þ¤çú*Ï3àP|>² Oå‹åà>b¦ŒÇFÊGqßr§ñGµðýÎ<ä|ri37ö¿(äM�ý;]lȨ}/fá×j²÷L6Y<œÄç«X:`˜èeg›q ©ßØVE�‰C‡m}àg¼ëäŒñ¨:ç(Nâ´‡1,NÀå´óõ:öØi׉:2RøL4ºÛc÷±ò‹ñ¨× ’:"­Â£ Ç.¹4˜úľØT7üZû['Ï!Õp]H�å�îå¼ûÀ¹^wÝ‹½øìÏšœ}ë@п3–ãC&à«l§î��\ºLò@('ÈÊ.ö7Ô'˜ë§ OpOqi¬Ø‘ìí¸‚ÝÜν ÇæÇµß!9b ²ñ¦=�->;úâ†(qÙÇàä´õ�¡´1r^ôõÏëR$'fã�;ô/õ«XFØ›ÆÙ’é5ï{Å!¯oöù”qëwïvÈ}1é‡ç¹Y¬íãXä.€;Œú¬ýè³~r\»6vÄ*8÷ÇÛ½âÈJæ;:ç¡ø¯Ü%Ï:KN~÷y„ rÓh^æ+Ì*½›vcÒ¸ÔMyqñ†hZnÄtS«w“á¸ë\Nà¥�{wbYý`SŽ ëcάbE0šÃ5fD+Ž”< a]æfq..pÃEƒ’rý¤¶Ì£–eCŽ xÝË\ª’eü#°ÍE¦šêA”/¬U[;2õ # &øš/|‰¾‚ià6‰L¿zÜUÖNê´r4áÁµ6οuè^`¼î¨ ~@`¼ÃgåŽLaÃ$Æ(äm†„¡·–Ã5Ü,ÖÆ£‘ѳ¨%çg5u�ï|B¨¿ç(ºØ²&çmB¼Æ ^B màû P°Ža”úß›b¾R_£ýš¯ùn_÷µ¿ûö9Ÿó™·W½òÕKµ"\ÁKÒ¦Ò5¶rh‚‡�}0�¬|¼,†[ñÐñð“ß™÷þ|ðöý?ðC·w¾ó�·_øùŸ»}R7¦üÔ¸~*k’²õC_9äUÏ>{ûG¿äKoÿÆ¿®¯/Ÿ_.ßmnOâ8…3kvv¹÷—iÁí£úzð/ÿÒûnßý¾÷öŸ|û·ëS‹0ÿÌA>¡†ŸZã ¾<_·ô@ªkžšÅ—}.Š]Gyw~νŒ ¨–s�"T9kßp§ìüähã…k¡ü®aŽo?´NqºÁó:Áaœ>²MkõË»>Ý×·ëÕy—ÿ%~Z#–sº`è:�qó¤$åê9^¯a½òE9D[FÛ“+?:×1Ç6£¾“wRk‚f³p7xmÌO×OâCKMÏÚ†›b—ÛQ‡bžûà –8²žüú‡Ñ¥�©ˆKœæ~'ŸÄ€'k)M3#ƒæ_ÜÊs µ[Àæž8ȨdµÛ&~Õt©}$ZóŠbò•Pæ€$—à™#®ÀÜOžÛþˆ%wÛ,î[_ð:Gé³ÝÍ5l^DZ£ãû\/ħëá.vß17î]oÃß)2Üs´Õ[ö�c¯3x°Çm+Åòq a†(Ý2¶x¸£ókŽ÷c¿j1nÇ.ö¬„™0"ºÔêå:¾1æºÒ¾’�Ü0�Ãp^‘?iK€'Ø�V,¡%�9㞣îãó^{ü©T=<_z¹º€E¦y ^mèx,yëÍ£òû=võuÿH1qrÍ–\e⢠(Þöpj�ÕÅFºŽ›Dã ÷¸ œºwÝ´Æ–ÆTç!>ðÀý-­ök ¼Ï6æ©·ÉÂñPžþ{Y_Qp�y=Áƒºr¬ªþ=WòºÃ‡œG9(€#S"îA©ó=Þ>GUCèíû€#I4Þµ»¦�ùé\üü hqÙ® s„§|θØ3Æð±ú¯ÜðžG»È¬ J?Iìk[7ÜWø>Bñr]1 Ž�~×g÷æÆ'QO!0‰ „wv²¡,Ñ«<¥ñÈzÒÿ^\¬É-Œ¡‚§m�Êàçb�;j�·©ãáoÛs/ŸeÛÜL9“âß½%{ÿÀaàã—ØIñžáˇ´N'l€õ 3¼0Ô�m¸ØÆï¦~6צLj m+ÿækYBÑ}\Ô‚J½8vbc®Þ-Q;OŠ…<ÞMfz¾I°Ñ=˺X�ˆë'Žn)LˆŒhàŒ›úá“w„i|ÎÜ6[éù ¾ùϚɑ IDAT��,ì²MíˆUÎé×4v�ò^üë+å€Â�\ù‡Ž½1¸©åa*Ï}1‰ån+ÎÅŸq1¦ŽlË}ûÃá�m‰ 7ౡ‘¿ßÓØ¿ó‘ÚŠ+›bvo“Á³L1Zy׃„ئwئemlñ+ôH�B°ç<Åñ“wqÎ 5Œ‘,ü.¿Æ Ì’kÏßHwŽG‡�̦]qò#7b™oŽë�S½Ø×_uÒ¾9›— ÕrãWR¿¨®›9õóÕNß³?ŸÄ�q/&qñœ-.òV(™¥ö�“$äÎÏó'c§`C;ŽM0B²6ÈRùÖ_^}ã­ã‡›n.0ˆ·9âG?¹Ýó@Ìäbó±OÒ;±êû�¥^à�åøòÖkR/ÜÀ¦–ò]öé§qºÖ%ئ`õäG¿iÅMÛphK#Ó3æøÀ#0Š£:•5™cµ:8Îü5f÷à¸ß¨RQ„ø ÓÄ}ý S0‹k{ØÉòѾ7Røa*X< K­K`ê‡× ¢h86Á]!ÔƒcË?ø‘¿ä¬%Ö•Ü>÷óÞt{›ÿ¨Ç[n¯{Ýsþ}RŒEÔþBxä‡ÌÝÓþpm—ºÁ§õƒãG?úñÛ{ÞóÞÛŸùö?{ûÞ¿ð=úäÜGKç9ý§Å‡‡V³6#u�Z‚¦&œç^¡O,ÊX¯ßOûÓ”/èwr¾|Ó¯{³~OàÛno}Ë—Üžþµ·§Tƒâ8(Jâ’ó`“û%?êµ÷ö×^<Ðüà>tûáÿí¯Üþ½?öÇo?ûs+ñD×ù`.»W¾êYŸŸ_øøÇô©^#Éscb“èÈâã¼›ûÝNþØ‹úØAûyˆ(—ÎÅJG&«Æ_ç!½æøØá þ�š¢ÌÜ”ÂøÙ·…C‡Oó:úæ n�Ðq»®dž7b›¼r]É|‚´Ÿ–NÊÔl|†xç½5³­|à¿î!?A�ý,†M\ó7"ã`(5oŽŸOžï‡ÙÒ…l!l¼æ"®Ã^õàÉ¿º!5?„�´`•#û´¬�Ž)ÞÓ}�q¹f»Ç.^ýϹÂ6qƒµ¨¼/ë{X°ÄNNY{¤ØóÅÆ³T†¹©Õ!= h¬2yò>Á‚¶ë`û•ÎëIHW›¬•«Œ|yˆAR¹�˜x2Ëܳn÷ClÊ…m3+©J®1jl«¸ZôèFFW»Ô›zòÆSbÔw×>s2ÔªÞ{ƒjx¿·ÅÌ©æ}-ͱÛ5ŸõÑýÔÀ²ô]K?<¿ù÷¥š 8Ó8ƒÀ×í¡2±ïíe—¸ãW°û}þ\Ðréù£s†›Ï•:_2ß~ „ÃÊ7ÇÀ=|pà0ú±Ç.5Ї¹’ãÄv¾�õM2>k+L×Ⱥ¹ßñu¥®5.Æ�ÍÞÂ%¦%�ˆ¹E‡Í~`3öƒÞòÁ¶TœVn‡œûFjK-ÑŸ<ß·Åó½)õ</l‹W¬ÎcÇ'¾uµ�IM(:~¹žê±c¶ÚÞÊÚö[rí•Ë)ŇzÏ-ÓGsÔÌ6ÔÃs»L4¾áÈO:ïL-k¾Œ&Ò§¼»Çêì3¾´;Îañl„Vèâi®Üƒ“ƒ9jm:Ÿcž;?x&³Á õþ@&C­3…19Ò_„ €w~®Ãø­ʦO'½ÚŠ¥q$Á#�Ʊál딣sݾÆ.˜x�vÇDîY‘œÂ..“ëòõÅvJjnÜŒàë6Šú•XìÕbëVþR]rŠ©O�¼p÷ݦÓ&¾[r„¸ YNÚ;—Ä�ÿÁ¥5ó~h׃ÊöcsæF�ò)¦ÜxcO}ë·‘ŽÞ�-²’½±Ž9H¡ð$"ÁËmÈîwæù}ÉëäÙü¼^âé­q{„�»u‘2v��|ˆÁ¿â.^q1Veì™onh¹ù¢{q4%ñ ߘx@žKŸã:ó=Bâ� û6LÿKÕZß¼hsÏ;ó|"̶ùö�ZÜÏÚ ÞªótÆ>ôËÅú�4&.ÈÔ<Íü¹yàÝÅ9v|‚Œ}¶Ár¿¾Ú›Sºc\Û€<ºMÍ�s¡ÔöZklIf¾yÀÀÍØn ßxÐMt B¨uDû°ƒZ]}¶]ÈÙf]tÚA/ÖYËÄñ§Öd”se±„BgxègÅ1läåyÝã"gù:¶úÉCò)råHŒ=òŒ±:xH˜7KÎOb9mx†QüvqfîᨠÜ&¯Å�úL•åsÎ+èÃŒ-|ûɺø.liùK«y8'4;—æ…þ ú!_ÇG=d›¯ÝÅÎéªû´~—ß—~é[oäío»}þ¯×õxõ³¶ãØ Qç6n'9Æ´C¦žÄOê/<ŒÔpç¼ÀõøÑ¿úc·oþæo¹ýøOüøM¯Rê¸äÚC`äç¬áﺃÜ|NQ?”:ìøã%ÏèM¼�}ì£ú]}üžÏÌäó¯û”Û×þË_{ûê¯þŠÛg}ƧûwzÉ×ñZ‹ÁÕÎHì“�C�À–‚7]ÿ!¾ÒüÓúzð»þÔtûïþû﻽À§ÌÕ°Ë'?yûøÇù$2çÌy�$Šp½Ve»÷vµ-="&<[ÖM8d‹h�±èƒT–:oû ˆL·ü¨š_áâ×ð|Ê»û¹í<¤ÒÁßo>…Ÿ"AÓ±ñŸÎÁc€€*’áæS9üûZÂqOÿQ§…[|qÑOãQØÖyȆǧ#Ë5õ‰œmX…ù£Ÿò¢^˜å{ꉇ<¿z‚s%ŸbBF£cƒé#ë˜þÚ씣KK>�xB—‡œƒë<ÕM]™oÕ’7û©µKžG-[\;'áÝøÁ¿æ‚Ó)O?µ:åÍ¥ö×¼±÷‡2´&?É×-w1Åæäƒ?¾Åf¼[lßç%Ÿb®Ð÷8Q´®÷pÌ@æ;/PD­ÎÏ®S¸„Õðf·œÑ´ÝsBÙÆî8kÖëX¢Ö,|û´uͦX‡Û�åOë¬:²ö󩬮òص�ëPŒ÷*­}eö9.Žà®¸ø€Èñ‹cB‘_Žßkw¼pt‚t®:×,âl Ÿº�bçÙÄÏ\³ñ)Àüj™€Ãu%h—zI”ºñäG}“çô·„Žø•Ÿ}±?òè|ç]Ï�Zà�/­ÇÑÚ«ÖK7}ó:}<v"MxA¬àáœb£eìލÏñÍuÕeÝ 3±ï�õ`ßsöŸ¹hÉN^Í…I¸——~ÕaŸZæ`®Yª ¶÷>`U¶x÷!W´gº¦^§�ù »­=䮥ŽW(cò÷D®X䨡ög¼‰rÙØå˜“Áïœ×U1h½Fç kþp÷·UÆfÅ?qÕ_�„²m[ô‡ ÅððX cëwâç¼@,[®§r|´±¯úLÚ¶£Àó‚wÕF¦“ŽÈOPµ÷Mmí¶r™¢æD.ãµ°Nç˜Ì±?—ÄÉ÷±ÉÂÅ'¡N NÐ\¨åÐÞ &��Ö³yçÌÕ±ÐM»ð¾“•oym]BæX8î³å+t�¼Ÿ¦Üõn›¬£-ýà±Ö‹Ñà&ÎŽ±ùóäY<ÀÍ­<½�Œ:r0ñµÕÖ¸1<¶sò Ž‘f�í5ŒÎ~Âv÷Tä°‘ìIkû�¼µÁEüX—Üôq`{eBé]P­ ¿{DüñmIþŽž�q`-ÙÒ‘ƒÙïyIœÖŒjúÂ\¦ë¿ëÜOáâ‰Ûo[”ÿŽ1:Û¼$Þ¥½ÊÏ5G?PðÅż»Hqøg®<ýïTZ0›gìâNÌÔÅ� ÝÜyǼÄ67àä–V§¬ù\˜g¾ÇÀ;xæ�ö'Yâ'�%‡œ›˜vèî>^ÌÁú3Žã$ éó5(YÓ>vÄÇ}¹ŽŽ¹K»Çœ±Ô®¹�|ìã·° �Kµ~ y¯ÍxÜ”ëHÖ(š|Ù7bÜèXBõS$Á…/QSªnÁ\¦Ö%wuÝÖz¨@{s—±ðwÓhŸœr^!æ4þH¸ã_¶å[>*uS v«‘%;O×IüŠõÀwüœ‡}ƒ›ZÎÇù ›v¨Õ›tã{�±˜ÈZvËæB@ ªG¹Q>÷‘É-Ë*�S{ŽéÅ®Ç7†Ô±¯×p-vüϜܱ·›”œk­©×¾öùÛïûºß«ß‹÷ÛnŸúþ¨‡~¯7KòõœÙ<‰,£ãa žP/L’%�ùŒÛeËC–ôG=~ù}÷öîïþÞÛwþ¹ïÐøxŸžùL¦Ú»Vêg½œ9ÊũàæÆ´Öæ½~+yŸÏ¹ù¦Î¾‰˜äžÑלë—ÿúëÆÿŠ„þ:ÿuc¾ºÕv@&?'*m÷¶ßý8O×q?¤Tþz�þEýõàÿò¿úooßñÿÅíoÿâ{ôðUÂÿ„k£ÇsŽO×”�‰d=O©Pvþ3Žf÷3Sv†¹úd}WfÛÙœŸäðzÓbïcgÎC&ؼÙOãüž–µ�¹¤T9¿Z‡I}Ô¯GzYÏY jì³&2çÅ…Òù]sÇMN?‰±P?s’Hár­ h-w×v–ÃÖ*zìSCO‘-·l/yr-äBRò{ºÏ7 ¶ay%r`‡ÇÄKn©“9¸¶±dÛ\Ég¿î¡!ÿžqÛž+rã¸yŠ7u½F=�~Ý߯%b¤Ö×xS�´Ö©éÕÞ µi}±]ÜÇNçuFæ´1Ëën�Úà.;~çvó/Æa³ê}ÄìÅcÆþ“ο½'‹ǯ¨”‹Cd�ë­yˆÕÐ&xå¾¢õ‘ÑĪ9Øûa�pWÍÒ�C­YG×ZAã;¾†ÄдÙÀ/¶à¹1¤/y4 GW‰m°~‚|éó+®rïHÛë#ë×B‡ËzlÛjãÐCİ iÇÙHqê®yn›E×"€œ×Ûãá9†'ãmó•¶s‘¡cízL±®ø·rj_ûKÝÍ?\ f¿t&± |ý+°Üï þ�#³âÆ#çïc»æã`@‹B7àV?@w¸vEã¶Ž�8vŒÕ€ÏxôÏuUÞÃÃ阌€$ëº#ÏÆ@M&ÍéÜK¼xîÚ·Jƒgß;î×é Zæ ¾�Ͷ]±¥Ö ÞzÍ8ç¡*öÛ's“:€éêuÇ¿ó\ÇoDL„å?óub?Ö?¹·´Ø-¾ãtŸ¿ Æ¡~Ãr©³&ý,€×]ÑN,ø&Ød ùç~Évþ äBÏbfÑ,$÷go0i¬.«X>Ør ¹Nò"…3xgkf’U3 bUŸÚÝ�ǯ>£ƒ«¸çÂÀ®_/X�‘ˆÂ÷D.¢6ǘø-noø­1Êq—íL=±Ë·Ø�í½×�Øõȉ£¶ðL"HK–¡lFâù$þÕ÷¢ÇGjlÎ8e¬ê*ësŸ +d/JꚈQ®xB3âá‹l/^`a£õ'­Ê¬œÍ²Ulúyˆ¡õÎ;µe3y>ðƒl±µ_'Q‰ÛïžÜb<(‡ý¶Îâqʈ‘iG~Ö±Ã; óÀx|Úrt®‡kƒQb ~j¡NþÙ¦õ±ù‰�›í´Q«]xf|y8ñœ$+q�ü:wRxþϘ µ|‰köƒ¿yt]bU~²wb°çâÂ1t‚<߉øØ—8#;r¡!ÇÎø7Þ5ï�r.,Ý{ &'ð¹0g®ýNN‹gCTïØßqØxôb·sÚ~Ô>�7™é�Aó�ß¶<´BrÿN­m�Kž©ÿåSX…8öÌMkÖ¹}‡ãXin�n¿£îùÖ�X^wz®¼Ë¿“¾ùÌÑ]÷0 /µ–¬û‘YwlV)ÈÀ æ›–ß§è®j_=ãô#‹~ÑÓðœÆÑšgki?…bìy·³P£èé¿B!?Ø1æ<´ŽI•ÎzàïàFmËÄ ¸Uê6¶ fƒ.l*`¤)’‹D)Yuö’¯ßÕœû¢�O*êaŠ£X8u%QTáœÛ(x€…~ü\®[>ï�o¾ý»ÿν}Ñ?ü…·×¼öÕ�~õ•š9Pà“�iÒMXÏ“EĶR— <Þøùð¯~ôö3?ós·oùï¸ýðÿðí�¿¸Ðó˨ ú $ÇsÀóàLÊ&Í"9Ȥ6 Hžøæº/Rù„/P…¯çM\=Àò§ëiáæHyÙí�o|ãííßøM·/{ëç¯ûŸ$Ü%¿qew¶ÌÅHV±ˆ’õº ˜r½¤¯àƒºýÈ_þÑÛ7ÿï¸ýäOýÄí½†›‘òp€M0Ü�üš+6ýoÌ%‹­¶âáiYäø8u£Fo�ú&µ Ó€øÓÒBó§gåÙùÂs© šýÝw„á¥ì44GàÕ'_Í<3Þõê0m| àB°sNç!åyÍæ|câØ>^dŸ‡œ=.Ç€�0=ÓÎðHLö©=X‰SzIV{§d ıà:y>ÕâÌÇ¢»£Nf¦ì1=ò]ÖKw¯Ç!Xµµ…qj § Ú—�Ž'æœ×ïÌõi—k=ê júµï];ü¨aµ±‚AØ·UΘþµ�sþÀâíø‹0^w �œ¹ycóG™˜U\CqǦ1ƒn~�ÙËõF£¾YBsÞé ¯sŽî²+.Â’ƒ’<ó[Â쇀±M ¤< y]ôÃÔónœ‹û¡‘ÞNtïŒ{`º ¾¹�åê�b�kW‡ŽÇov®¥Ö$˜þ”¯ùϱ†�Æð胃Œ"7„ür¦�ìá‰ìkí$ÐÚ蛋íСL¯cå!ÇÏõÓ³£”‹qûaŒrX1&¾v�p …ò8÷ø×Ç�~9å<´åÑò1PjåyuâF ÷t%�’ÒOµ²eÐŒ»ÄtäçrÇgû ¼w~x.Ûþš×� îc>ä“X.…º�ãâ?Öv³0¹@œÂð£yqͶ®Ñy³dØ•k}Ï)À¿zÇ2.=âÅ0±è·�)ÃûµhíìÐ� oœŠì�X÷:ðKµ{lÚ¿îyž‘û[8æþãØ^Z�ªŸO2pâ9¸2I¢!ÛOQ0sƒü½d‘»øp±ú2.®õîg?BiáaKiµ!ÍxÉK‚{uBÿ$��¶>1ÃxáËæþ€)4û¯ç™ÏZkŸ÷û“°>Ÿ÷ÞkÍ5ç3Ÿ9×Úûì½Î>çÇöÊ]pÀžwHTåÝdäüµÔíØâX�q®ÃžgNñµuŽu¨vÅVûäÑd޾«ýAG~:Æ–#.õ=ip÷в½s')ÇfëÅx°—?Ç{Æiþ¢íÅsUsóAÊ5Æò¥çä²Ô«ñ¡ç2þ©'Þøí|ë>ÊÖþñô!tDt� 5'�„åx,­7õK_‰Á{ÞYQÞDô;fÍQدXO៎íÃߟ©±,ÆèAŒw\û‘ºÇóÒ¿1pc®Óß|bµóÞã»ðòv| åN\LbxÁ›’úà«rp5�ºnYæÀÚ4ï!2¤:‰ ì3çÊ<‰‘/cWoí­Þãzuužz¿b‘AÝÚ¯ äþ.³k#i%n9^¾C4󢋩|¹<�?Úä¦xçá`#®Ž}Uo /|¥³ç«‰iÆké Æo–èÂÜsRÄ}>¨³¡à&~]< ~Ï3Á 94zcd†Ëox…[¹O¾Õd\Ïâ¼hãE1ÝäÐöxËMèìùIˆÆVƒ=2昳-ì×<ûÚÛç~ÎçÞþÓßóÛoŸòÉŸ¤ùxz>Z‹Þx¶ÍÔÙÝ·Û5r|0Þ.OÐE‡ÅrÔø¡‹÷½ïgoßõÝÿëímo{ûí]ïzçí©—ë\­ÓOþòºbÇp—Qâȱ”ñwìÐë9¬b>ñ—¢ù¨6çJ^ÃyÂ××lfEŽçz’Ąܿ0üáÛë?îß~ëoùÂÛ|Áo¼}ÂÇ¿áöŒ>.½ç× cƒí“ŠúíÊýãDõ•?úU8¾X(ûà‡ž»½ó‡ßuû†oü¦Ûßú®¿å�,CŒ~Sƒáøók¶v0yg¸N[ÅÕݦ¶0Ñæ²±Ô®­e~í™EfÙñnNœÓÕWÑ VýnL$e: nNBx�WzÏt�‹½Ë…_‘Òu¿ÍÍSL,bÌ�z](¾Œ£(‡Ù ‘»=Ùˆ‰šg¬ë:ØfÙÚ>xNï@Ý^ÞÓä&Å)£Þ¦ö!eXrµt#ߊ£'Ũ$‡Î%“�"´(ñ#cª=vÝ£ã7"æ\Éœ7OÆ:'¿K.;~Qšíx?Iœý’w>œâ]k‚È5xô9§CÎ7ŒÚgŒãÄœ‰Ñ‘ïüçˆT¡A‘ fmZ¶}>*·›èeÞÓŽjôõšm�÷½£«ïòf®í§7‹Y‚Ũ<Þ¼m�Ö½ŸxÕV{�ÁkNîoÕSWUú{Çñe3¾Æ¿ç¢? KN;�˸ šâsÄØfÁWç*;ûú8øyjÒ4@ûã�UHÖÙðXCvØ•s÷åsÙ˾sßç-Ùïcgr)+ô#.p›ùÐ’qsxàÒsÏñòžŽÆÏÔÌÅ8+/T­g÷oÒhõÓ4°¨çø9±Çª=ÎPµÅêC�‚4Œ¶þŠÅ=±‹C›øš�k¢^£Gz·m.´_seêh–óæ� ×Ë®ÐÊãkŒHª°ã¹?väb°jÙ˜O*åjîÓ×89 ÎþQËMŽYĨtöÂ'ÁåuD0yª>=L"RÔ¸r€gbSwr—0bôÓœâÑ€·8¼ì)™U^VÌs3tòª.2Šs2u·µq$ïJ8J8üÛ]MGwŒÏ%•kŸïµâ¦6¿0΄Kˆ—҈뛶ë6Òç²Yz¤}&�ß~âµ·Ž8ú�yÍÍó)¦5f'ÇÉÅÂà,èÇŠ-ª¬ûvv�œ2±�ñ#ÆŸÇ[j¼saî$N&NýK¾ ©BJÿ/1YÄ  “g÷KÑy¿·�Hã£*»ÓWâä1ïÌ÷ãgBÖ¸ƒ¥rߎ4ØÔË»~Ñ_ïÆâ°…üÜV}tªª¡¶Ont¹èí»‹†±}.óN�ĹŸÆxÈžkN 'þŽü”g÷ö5�чžœÛy7™s¥Žñ”3Py´ž| Ãæ x4©·ÔvÚQsÃyVmáM—¸Ð´�=ÅNÕýåÜùE¹0ê‡[3Rû0q‡úÒê~û<ä;@û]x‰Úøk.Ò*ôh¯'Ï•KΕĉ¿ÍƒZ¸:› ^Ò‘ªéô¬<ª�;K‡NõÙ#óHkt˜Ï½!æØAñ±±à?ã�bëÅÒÞ¹�'�܉÷ØÇ-­PÍvV9úŽ ÝwãòÞ† &MDgFI;jË ÎÎRùU»áR‡ôS&ª‘OÎçþ¨‹horÀy3šñ…ž1½çõ\77^Qû—·Oø¤_rû£_ù•·Ïþ¬·Ü^û:ýÐ…Æ}vIç&�žmLªº+U¾ÛW{ž°û ~÷_¼ç_ܾþÞ~û›óoÜž{^?êÁoùªß×äu€9DaO<4×q,aæºUL†þ¸¢›ÑGнòÐãƒg¾[ïé§Ÿñ€,6�`¬1ÇÀd.×{ŸýÙÿÞíóñ`ýzð«_õÊÑCg @¶Ñž:ålß×G?¼¥{Øs½øÂ‹·ŸøÉ÷ÞþÇ¿ñÝ·¯ùº¯½½ÿýüz0‹p'¶•acÃ?ˆ¯�Ý3Ž­_7Ã%ö;ÖoúÂ2±á¾f[ŽñàæàäõWê¶`üÐÝ)€ÚÆL‚„b%ô)à»~§�.}úk~Úµ�ùÝ_5¢±f~é_íý› úô¤ºÜoà ~εûìVúâÖ�<ZÎyô�!H²É0eºW‚Ê“w8î7éÏOé ç¤°s 6úæ…¯©Ÿý±‰îš•áˆß;ÖèŒ\�øE jØd£×èœvÿwêô%ÓÎ9>±8L�$oÔÔa“©£|°Þõ‡ýp+.u/¦ú¡ žT¼¾³üaT6ÚÛ9•ÖÙ£!ü‹¬²ßýÑŽ½M���©l™wë�‡¥I,è09¥«>ÅÇñJ'Pîv8R)—´%0ÖØ€¹bÙºàåÓ ôl/RêÆ›×F¿îØSyt‚Xeù6Á%_š£[Îq×xQ °”SgÈÅ~ÅÞû>i�óÐÒb|9gw×t¯ãȺ;þ¤mtSN>ž×8°6á½rì4&ç<(Ôñ®ž16hZå³ÆØ¨ öàW+=Æjo´MIÌ£ùˆ·c+<_ñDÇ÷áØt®I•:eÓEcËÓItñÕ}B agؼb ˜_ÿÙƒ žþM¯!í7îÍâù|O·a·öÂÇ2.¯XöbX9o[}Ǫôd IDAT}£~¿;sCŸm´wÜ:v¹þí§Ck[›ÆZ;ÛØöaüËÖ•XNh‘Ì�˜§�S÷Êà^�ŵÇìÁiNŒi°Ag"Ð‹á”æray²DaÉF·mïG¯²â±çu‡1çcÊ~’÷Ä$.ÍWçesÒ^r°öwª#J39Oìôw)PA±'`_4â@ƒ ±<Å”±èl¤•¼ñwèƒÕ˜[¿5ë-Îx¥\Œê¦'­3ÛßO9Èö¼¸8m]Ç—^�ˆ…äQÌÁµlV»“ààWµS'ïʶp{@9OY|óQÆõŽããäƒ�•Ïqh¦'®ä¬µ<îpÕ¿}ª@ûh¹î‰ø¹$ÀŽr¡F 0-;yžÜAâ<¨«{îkWN'ôîùÞ÷_°L6±sƒ§dæ#ÀâJé\3'çkS]8‹³‚�xmGcÚ[7¬á¸úâj«(��+æ<Å´/.Ç™WA¿)]À#Ń�Òîum¸”%™iþƒQº3ÝÍ»‹‹CÒn!"®\ Ý\®ø�ÍØÖŸ|XÙŒœŸqX0s×É»3/7,°ÈM 7÷gÙ&~l®|‚rÍï‚7'‘Ìÿ‰'º=¦8ök|‘Éíæ#çʾ3?ÇŽ»�¬€×¯1G>þÎür+¦œW 9eÇKv›‡3ohí˜e!ÿû‡+ò q¤Ôs6ûÊqÝl Œ�©ÈªùP-ý8w)×ì›ß{}TÍ×<óåÜ]Àh~Ò_½ìããʺÙ[išPl�ÁÑ>šÎºÛ꯮±}£”xgž’…éûy“öºñÀ^@gFÊŒ=†£ˆpÈŸùò‘T•ᔣËÙH^Ž^{|ó098˶·wýènÎEÇ9By‚êYOÂP?íj-ßcäs¥Îëä’yiÛ“ã@§“Cdñ-?6…%õlËÕÅ7�I‚2B¯‹V¬_#ŒxÓgžGÛÞÄž7ç;ó`c[m«BS’žo(—NýIŒ_Ëhœ\dWý.–Y1Fc›æ$òtJ} Sˆñ“·ÃÇqÉÈÍоԗûû¾"Ë[¶ç<ð æzAlÌknÄ`û‘5<Ö;áé1æ²Á…ʃøÆÿš7( ôw>'áƒ_Ÿ “ë @(§nÛŸD r9ÛS¯ZUFïÇ%,TST{`½óÿ2ˆrp„`Õ“ ¨m§#åÈœþTŸY ît4�n¡NEŦ®Gýž‡Èãõug &N°‰¹¶–Ö›6O_t¬y ÛJvÏc·À›M÷w‘ÂfëãG­…]>Ë©µ­2µD“¨àv�ªÅe_ý3ËN6}gÞç ññ¸ úüK>v. n¼êîL»;¾†/8+8êä8(Y,"¹9uÓææáåü�çJþƘ׼‚Åîv{öÙ×ݾ苾èö?ï?¸½á ç_³µ�q±h¨ Ìâ’¡‰ÖЉ…娱mŽ«vo£.ÈŸÓ�z¼÷'úö­ßömúQ‹oÕ÷ÚýŒñ´Ÿ^ãµ×R”�÷ §‘ìr¤×ÿ58uÞ¬m=øƒéw…éV½¹AýR“§ÿú`or¼€*ð[�»öÁÍ—�ðrxíÇ~ìí õñàßö…ÿÑíã?þ{�ñ2¦ã—àV®¤Ü÷Ó¦œãô’ò˯¿û]ï¹½í/ýåÛw~ç_×Ó•éE]ç×r•`rF,OÊMå[Ç%N�9�ïSÅÂÖyÒ˜‘Gr°àíAÓ>ú­E\÷�Z”1´ –-ž�CHîÆW⃃ Xªæ\Éue¾�ž“’x]�Í© º‰cˆ-Õ}N(—Ä0¾‡{Ç 3x0ß+ËœÜÀr�÷þbúr•$kî�ûÅ“öGüsÞ·oá³÷¼C·þºG¤:™2N‰voƒÚ“ŽÝG ÎÇ1”0’îU‰¬BôîÊ#–hÌÎÚÚ 9WLÛ¼LÖ _D�²ìÕì8Yî¹ñ0gÆgLmÞ9ôPÏàƒù`¼ñ AþϱÃ9É×èàJ^?à\óŠÀRm‚ÑX�R$� udñØrô(åaƒú•Ü.¬ ­�õMÛ⢉üâ³-çéD:ýIîÉRgÅÒð÷ÞáoåD ¹ �,r;_=aeŽl±vÜ®�^† Á¨8¦ÁŽDÛi—Oå÷mä縤¥ù„4åSY'—ê5¾b˜‹­glÖ¤ÀÓÃRý=yêÐçpÎqÎ¥ÎC~�-üMq¬ª?3*O=ûqÿŠ�e0Àkà`í�SõS9tÌM˜ù’T.̹¬ÝÄ.vÓhWß�— ¤!`£¨¯Á¥OVMNñF¹“ÈŸìË­±æ™E ›âüL+‹Êüžc{¿ �^öOL‘&5Móˆ'~£Õœq3Ãwz�uj!C:¨JîÓ­íèõÉAx»ˆG}ÕÚ<ÔmÞZ÷ЫíÙŸïjÉÅåÜËÇÒ�SvÆ 7ôŠ �Óμ +Ü¥‹pð±#„´ì܈¾�TÍ»‹\LÎGs¸a§¦“½�/5–_ü;†‰Å}³9¹—gûp;ìkç±”í.ùãã¬s\jg_êƒ×º˜@ù¾4ž•bZ ©P)ï´f+�¼#ÆG€g¼ÝÅ0?…¸ìçXšvqÖX—S;î÷í¿Û?Ê Ûê ξ¸à#mtò7åÔ=ëîž¹PÝÆ$=òLyòé½Yx_±’T]ms#–EŒ.‚Q?Œ³¹/Ž1³ð7�pÊÀ¥~b$ŒÄk8Œ�ÇfsÛvî˜cŠE+]L›^{J ›öhu¸wë»,­Y‹c�QæM°h|Éãá×�#ëx‹ _¸3FÉ_9=ÌYÈy¸ÕEÆ@¬›#4–RìV“®Õÿ$9¸PÃGÏCõ×§/iŒ;�›Ç°þF>ÌÕ:Σw\QÅÌb;*ÆÕž¸áH>Ï›äv+Û¸/Z¬�<¤ÛŸfôöÐ )äCR°#’ÈšÈÞèöE/ï&óqËa…çzæé›ßüËoü�ý‘Û¯þ•ÿÆíÙ×|Œæ±žÖ)p÷¡×–]uü¬œ‰´Â#ð¸/Ðæ5%^X`ù¹üüíŸüÓ¾}Ý×ýW·ø��øa~hƒø•OŸ''3Ç­ ùàßü�¯!í>VwT¬g¶±Œ®áð Ÿ>á\ó °Æ[ -¯Ð‹V<ÆÓ_ä˜ó6#8ç 1|u˜(¸ß ds³a—ŸsÈ|AGÈðÏœÏï‹3µèÃ1�q|ÆYqÀL‘|„ãÊâe³ T›ÛOx5‡íï“çýª‘Ät¼KêáZyâaþ.ZŽe÷«6Dñ¿`!'vj§ÔiSÂ?8©ófhƘ@r¹¹™/jOP(™ Ôª°÷›CûÙ¥ªK”X�ºæ¼ ó=Ýš ù”„¬\º£˜q?ó¶p*+í:nÍaŒ¯˜èÝ/Ç6Ú {l,âI+-®éœó"Ÿ$º&^§î`¹îÓ¾ôØL\³m�bn.� cJÝ�,¯;]ðÝyìñm½s“Ô]C¶ŸðÊüS}ô˜œ–ƒ.õ=)ß\“¯'&eƒ-ßé žïÎÀŽgǘ9Sg³—í¦ík/Ò;?ÕŠ¼¸wh«™¸¤¥ÿ½fóuåÜß§ç ¶ã=CCƒÒŽ´v~$'æ¨KõF>ê�öãà p8¶9q=áãÛ!”â°~ÃòŽôè{‡á.ûXj`é+ö-̯Ÿy¤Îk8ý—7é�4_¦Fæz}·{ç숫¾ïçuô®³¦ÜÂ+é)n÷Œ7Ç k9W¦çž�iרû‰£}µYû‰­êöΣ¬˜â*óÄ}éÏ5:Ñe^&ÿÎ�9Œ±Ä~ÓS²Žx­�ÖÚ}¤¾¥¤ÊGÔ³4tŒp�®ã¯¸8ïâ^ûî­|ØApýˆ“g rÀŠJœ‘_€FÖ„ùÝv’‚êeÅ<àdR¢Þ“DqÒcßõkt[Ôißþr=ûÀ”Ü“Wò3Æ 9ƒ,7~ºýÙëÐE·8í;„³î¤^>�uð°¥4¢b"+.u }(:ŸÄ­Î;b,Ze�½N¹¥ï8mJ÷ƒrá:½ÍWûÌlx¨~ßéCµ<¹˜Ì 2‹k"2ìà¶0ˆ˜¢ Ñ¡6cäÆl:=÷ÜŒ� 4þRò˜ ü´»Àa}>N‚ÿrÂåΜÒgC:§4Žàμ*wÑá˜ÄmäËfâ]ü¬×ØgÑ�·×t!ÉIÒqH>èva:(ÐUY¸#ÈxÁ‡^mÄLJþ}îФ”;q“XÓ©­¸óbC/‹¹àxÛªþáÙ}ãÛ =”cøŽµ oŒb²_ym|¥'�ÂÏ 7ï�„ãi¨� ÇxVħc¼¹>zŽùé%^‹‚ÚPg òñ‚|TÃ!Kµy»×w{òBý>ç�ÚúW¼Í©ó?¼‘Ã-ÚÄ GòÙ7"ÐÛ÷æ31ö¸P3u%wÑ ×m»èÆxcicWýåy0Dóf Oµôâbû©aâ Ïuœè]tÄÛžâÚ0ôSì64"˜míË´��÷zŽÙcÂ|æ£x9YU�up½»Δ�ŠŒi㬛b WÜê$ç3.ãó”á"í8[}6²¸Qå‡Å<_˜+@ž¦dà8>YüÍ_ð[o¿÷wéG=>å“n¯Ô�z€“‹µàž[�£×P¢°œŸ«ÜÎ °eôi‚¹}^£ýéŸþ}¯ßwݾé›ÿ²žüû‰Û ,è&Âz¡¬F^7 Ê|ã<”v÷R”‡-WÕo4دú°ñc"]ð +R\^oáÃx¿\çô^|^Ç‹V9‚ésÞq‰Œ79üÑG@C͸­[Œ\ÅsMNÞøÆ7ݾò+øxð¯Öǃ_£GÞTPû{ºÔ7©°*qfÜõCZÍ‹nï×G­ð¾ãö§ÿôŸ»ý£üƒk(„à)®ËÍýŒ �Ø{A×Ê;÷Q‰CbK7[1aÎCÌûµ¸¶¸ÅëÀ9nçFvƒbN˜qs M`.ÍçDùÊSxô59Âç×?þWÆyÈO­i0þá/8Å„îŠÍÁ¥zŽI¸1àCR¢#•®GkÆïàA„_üÖGΕ ?ÅúÜœgçÓ¨v�Œñ±;Iët†¾l@Æoǽ_ŽžøäO]ª.ûèS»øC°|´Î}Jü—oZí“–ªà¥¬J³ßú½®ŸszñQŒ�æ›xëþêËÚll$«Ô|Ån±<¿,,N|îfä5<çÊØ–­Œiçlú…Sß³¯¯ÌQÙ·_•]yà£åzâ|G~¦­ ó’ësÎÝŒÚeâº>d®Ç˶‰~|žR×m«ZùwïN,éÚ¶¨ûü­s:â<Å”þ¡±°V ©tN™'y–àŠœðÝúv"$)ù53òê%º·õâZ¿¦'_Iá°pS8ˆ\V™þQZbWj'ó2êå�>Ø”}­‚Aö¼þ±Ø²§O;'MŠÍ‘ó×¹Oèü7wÉ Kª,nv@.�@}8ŽÄ8î¶FtüÆ“”÷ 0ÉÇ‘òìוËÅ Éóc>'÷kÊç>–ƒ«ª 3UxêØá�:WòšN£çã�\^KrªãL¶`¶ÿ£Õ›G£1&²¯m=ƒ}ŠjúŸ_ž7KdD˜îB1"JÎvoPºEg� äíˆÃýUž¾6­KÞÃõ©Âb*^œÜY—seü]ÖèŠõìëõ #ˆ®·÷"£6åé™0+8½²håÅ?‘qÆþb+<úÎÕþúð~¨ïh'/¶Æ–²eå¯ý´yX³ÏÛëä®.h‹[Ž'æé‡z²Á„êtø±(òö“nЧ²…ƒ0Ü=Ù“:qpq~þ²O¹çÂa�4â�8N .Zôï¾ßÜ–µµïà”còC0¼ Î r.&�‘$�»á¢µæÃȈßò1Òî̳;ÇÒœG;ò+íÆ³ùE+ï̳ˆ¡'0|=æ»$Ãa�óŠ+t�¥ø™¨†~íÙ¯qèØ@ç9)à…ÛO|zƒÜÄä Íññ(o+ÉJzLóîG|Ù5è¤äOøî¾ÌÓhl"�'ÂxЉ‹I•Åëœk�[áÅlÍKU�ÆË>Xc9ÄçÙóK\k>J™ã#p}‚ÔyÈ‹œËÿÄk�}KõÜn£ %TåæøÔ{¨ƒvynKÉà©Å5ò»MVæõÑpï/þòwÁª 9Âmã —¶=.êªvÞmÒâ97bºiÆ–R½´˜7©¥¿Ö÷zÁ<ú2—ŒÆÜ á<¶õÙ¹‰lóå¦;jYÜÇzòÑ€˜_– hpTXïyMÚ³P_’Q72� †Ã*K¶$ᨠUæ¦ÖV4/év~Ê=y ‰ŽñÕ¯ /;¶›øQ{úíTP§=u^¿‰·jè9ìÕO´Þ+ÆÓÇÆÉüZ9³#ÏX�@X›Jlì `k�:®KÆM¯‹ìù.&êÏëÇ3>ñ?ùö_þe·÷³?Óß?÷ŠW|ôõh¼r<öî?ºšÔ‹óbúÓž'©~þƒÏÝ~äGÞsûSæ­·ÿãû¾ïöÂKÏë|þŒþôTË ¼îð$‹K5”i¯‘ÆqóÏE;jصtÎÓnŽlƒîqcÃáf] :>ðNt½î(�}�o^‡Ì韱¨¯Œ}ÿÂr;c�¶<³ð?è½æ5ÏÞ~çïø]·ßòŸ¯_þÅú’}-‘‘Oeï&æÍ„ƒo™m+Cr_—‘ ª�—â]ã#/øj²_¯ÙN î6>8¬œµUB3è FjQl]û‹�–ä8×è,bì7m3—ªwÚTöpŸT6í-˜Ý‡öŸö#“�ÿêŠ_³”=<³àÛ¯¸:±6†Ó9áÔ†ö5aOÁEë�{Î?V~ê„Òî³R…³ˆ!œ;†T7ç‰'–�¯Ô9g¨_ÿŠd×õ?�ÆAñ‘~ç,åëŒ�z‚ÍOäŽ�½Æ9vÔ‰ð³ÈãH�q gôÂM–Ãiq’Žÿ¬›_y&Ûº¿Ñ¨×/®É_c³sÚƒç6~π݄ŸÊø¢z–Ø;1çE'MSDÁ ÍÌIúua÷øÄ}Ó”À>ÔåJh¼ÃÑigžè�ïIðÎïØ"Oÿ®yG�'û@S¯U–ýäæÞ‡û…7°g«ÞX*h›}’¶£Ø}Ìq¢M©œÖúà^'HÖ1ªEõí£ÜÙkž˜l`�Ilª?⻳ßu�yÔœÇÓB€y ižŸÅ¨ýC»0YßhLG¤�3œ”à2�åi� gßI^¢Ø«à4L‰/)÷iÓÉã�­ �*Pi? ºCo&“•ÚqìI/ºÇÄDõ,탥 €>AÊØ' é«šñŸ¸L˜É“£öµ‰—ØWf°vÔÉìÍ gê7WUr£“ÅÔ÷1xပÄ÷x æÙ‡ê:w›L{Ëw°¯ûþ´³à« s/øÖ¿fÆá’9Ù¸bUð&Û.‰¨¯Äåï–ↃF ¤^ é<Nsºtñ<ÇŽoº?Ì;Œà/„q¶9!¯ì­0êìVŸêëØ³Òlªäfý\ÇŒ?ìå Jnr°›Ø,…Ÿ¼ILÍã½b�¤Ö ö2£â~{:­Ô�okf>ä(•/O|²(û‹¹k Ì¥…õ¡Šÿ+~ýë›z¼~ùx´bæ{üb,�ñ¦ÈËp*5@ãNãöåøKn¿ìÓþÕÛ«_�_ -޵Q?¸Ú�qÔ»]§.ùêjÁˆçeB…Ø^ÐÊûßÿó·ïý¾pûê¯þšÛ;ßùÏo/Ó¢ÖMóåúú~=ôX̂О#ÈÁeo<Õ©¸Éƽ0BFÛyç\¤,š¾ •Iy y‚:šotvŽ÷ ãÝëŒêg1PPq¯ÊÆókê…e\R§0õÍ|Ê4ê~�å3ßòoݾìKÿ =˜�Ï–á‡K—;¾‰1]Á½ûÝAŠxø�“Ÿúé÷ݾûþßnoý𝹽÷½?±ròÒù�Š‘y_ìì�ýJÂbz£—|G Bùxm¯ Ò4foHÛ +üR”Á*xo9Ž( c©]LÛ99Ä ] Õ¦ÎžóP�ïýñÁQà¡à1¬¿â0`›ˆý÷5,´ë •æ$y³€$N…jîwüæ·ÏµX](]‹_ÔIô¾�fs™ãjãÖÖœmÆ&1ø;Q¸„­.rH·Lb]‹ðÑGB8ABL#ië�,tëg°ã“FN@�:Ø9ù£çÝØ/ÑÙ~R})§æºÓ…~›t4:¨®G°re®ÈîJmº—�ãD Åñ(ÃɇEÞ$þ­ß.š¹¸àE›wæ+öÇM³@ˆaùå¾É±úo'î©w·j®Å‚;–Põ }üqP£—w›ë˜X~lŸ}.lb©m!"v»¹Ãåë6|‡Û¹Ñ€ùâBœ{PcÆÂ•Zc]ØŒ!d†�uϱlÒ ûÆ„Èvß¹º�8«cÀ‹ O-ðã}9ýŸ}g K¾¨3f*v–Þq.#ôô7¹h~èÞ9É‹ :þu>›ìñHþqÇ—žç)Sì?j‘ßÇÆ»å» ÃÑMg%mÚÈ¿ŸDö“¼+§bEÏÃ+›øõsìÑÍ;âÕÈk\ÇpŒpá*O*|dQ\üÌ‚/šgÞc9�>+$“°dûHŒ±m5Lfö`Yõ"Ëü:d2ã8Ï›%ÁíñV«�c$åëÖa•óH÷±mŒåZûÚJ[ÕswÔ×Å$Î¥üŒiÎîit¬+€aÖ1\ò�š93ô�XeÀ§}Ÿ÷p¥3‹Ï›cXר Ú˜Ñ:ÝþÏ9Ò˜–±\º_ Í1ûe#C™äU×X’3/óÎ<ÇG¢0� Äzã'roå1 €‹ žüŸy4çÛÁØ<–2­øk‹B!`gª¾ìöÚ×}ìí‹ÿï»}ÞçüûþQ�gžVN¥·°TÕÝŒùOÆë,ޱ²‘6eúy2ì9=Uöã?þ“úˆï·ÞþÚ_ûv-.}HOŒIAÀ¢¨}beÎ/ð 7àêÆóxꆞ‹^÷Û�ôfotß\8cÓb,5ØwŒñ)I(Hí#´ZüpE^wò±6pòñW0n`YÕ6¶s›Äð¿ª$cÂŒNì äl×;,>õSùxðWÞ>ã×üŠÛkŸÕ¯ó]�p£~ïI¶B²ÒC:ùèÊÁqžTgü>ðs?ûÇïøg·?£�ÿÃôƒ·—ô¦zÍ%×[ö¡ æt†’.ºÕ· )ÑóyHùêu¶ñ[«Z»–ç…ÂêÒÖ?p°ê M™voÈ�?sÇýÔ|b«Ç“uÔÁyÈOø2ŸŽdRmîíÃïÆ ¦W‡£cOèë~°¬„•þ`KQÝ�ñÿíO®?Ô[¶ŽOö›ç–Û>R«G{·ac‹ÃÃø7ÇݶA6Ç– ú´4×kä«17&öå¹1‚¹#’í]åØQ•z³§}äH}ÅÝã·G¹³-:Üx÷{ÌxS,Šª}ÅÚ¼¢Õ-èÅ]ÔÌ (a‰¶�½²Úïý5ŽÊ™“,¼¯@Ó›|¬ó#>jqî+\Á©S2óºë«Jņ¡ÑŽ˜!ö›Y•«›ñæþÖ}Ø6;'<6ÃI}bV—•-‹èùÂat&ÝiY}�!ÂüØXîÉú“»:.˜ö°ÉEç-ƾ…¦}‰Uú>ÇÌÀ¬”7ƨ-׆ûÛó�ÆÕA¥ÁÕ4³]³¼ahÎa›‹„õޏ¾`N¾–�¿Ê{Lq¬ç}%k‡Ïúaï\ †u ^S5Ÿ?¦µòՏް;ÉËu@ÍOõ�#$ýgNÂ�×Êz} `ç¬cH×äêÄŒŸð!�õ‹¶`ÖÎþ$͸$)¸Ÿ> úþÓ"ÿ‡õZËú�\OÙñ,É�=òú\:ª˜Ëì-ØÃÄb6÷²{¼êd¼y“~>á¶©4ܹ¶]ë X’T*ï¸HjäÅý ŒnãI.óI/žsÂîÃñMßëS¯åG@¦ôÀAÐ:@Ë€�›¾'‘[rì8¨u’ôÅ…Ùå ’CÖ>P� ÿݺj! Œn}”W&_TÚwÏŸÞ3ªm3È”<Õ‚›�@(³SÕ9ª£=¾\F¹]˹„ÎÝÀÕwc°O@ÆßÂ4°êæÒïÌï‹Îb¢V¬1ñ®¸Í‡÷é oÜÇTn5“_tc˜ù£â>9¹®ï¾3hnu û“zc`nÀ–ÿ�ǺŰ²%kLê¿@ô)¦¾ÛÔøc¾ñ�xQd7Þí5–0jK>6tÌ'ÖªÍý^ÊÑ“ ½Ø0æ]2NõÇ•}�­?æÜ£åÞFJø 4'n\6€E±9Aà�Æ[ïÌKµjÍå‰}‰}©¬û'ù�ªcƒÎÿX!~ø¢�<¶ºyàBM¹ôw$ðtGÃ3ž6Rä_8§�ÎÉÍ騾xx¬ ”Ü]ìíôÔ?tèS�y§6?\±5x÷ôÜ×·¶kÓ½óbâËî`¸ ›gö~ÒGûëÑŒ¼ÛÄ“œÏ¥�AËøm3#³Ùos!ß}‡›ð¥fçwã$©Ä™çh7õ˜¸„‹~ãI7báI§ÆWÿÐ8I`çXÙj8‰�wi‡¾Å'n±ˆ�Õ�$�¶]ÀÑä\‰œ@⺘-Ñ]Dhª8wÜù6 dÆCÑu�‡•i»¦ ÐGQeåAØœƒXLËB}z¶ú1jþ¸1‰#›9®Ôo�qÖóÃ:æV ·èê¿´gÑÌDzäoúÔ_vûì?¿ýª_ñ¯ß>æ5¯ÒG€�…"&›@.°97;…¤ÓEýQxB[â5ÿùQ�w°pôgþìí‡Þñ}ÌWOîêõ­OÊ‘K sŒäø&.?XgR@‹§nêÔ], ,Ût-xÁ,¶ú§ÔWPIß&.Aíb�aÆnŒ5çôÜ<È£àÆž¼QÐã¯%í. \òP=Õ§íÃuÁ ÃBû°ûð핯zõíwÿ®ßí�â'¾ASÍ‚6äÁ¸æŽ$JøuÿøcÝ/þ�“ þ?ø¡çn?úž»}ó·üÕÛ·ÇwÜ>ð�xzTÚDl¬Á&'É·ä\\KÇ!\ö?äÒoä oÛ@T%;?[pÝ ˆ•h[käÖ§Ïj±7H´`2µ¨DÍÆîÓ&Ü…Á/hçõ›~a1‰CÿYòá!Iso‹ú¥¨‘w.r }óz“f¤ãÎmæQojóñù(wq厃Sbb‡ õÅ1cd`mbž•±ßciñ2ûá—áI&öuFÏ�£ ½ÝºFx›¨{÷&X×vZ;ïÉçzRN+¾±\0f;ýøU¾5ÞðaãÊ­AmïV1ãà<ÈÈðŽ(µ¤Óùâæ%¾x±RÇóC™€Tr�¡cWçT0Z‚½}U~�ÂWï#•åq¾p‰*q6¼Í‘Pgþ;ç¹ßÉ“V\Õ±ªõßý# 5êÍuÙÖÜûÂC̆ìà£sïYe�b¥'SõÇ´sy¬öR§/&År‹&æ’AïA¬CN:œ32¿£—žÛxx3Ÿ„¤x8OrÝæ\ê½÷ˆÑŽÎCŸÓ;Ðû\U}b¸êÿ»Ôî1®§Cܱ£7ו|ŸÏÃB=&Ñ[Ev¡ß·V^Ü¿ûl'YçâÊ]@ÔíNˆ ®™ïp\|Εh�KlP!ö–γ~š£b1ÝÛ?ÀT"«Ó|‡ìø�9k::��x¾2ÁsÒo–DÏ.,8#£·û6V¥)¶W}G;�v¨™ª¶úï9¡JÆ( µ%?Î¥Hóúèñ™<:F[ føvü I}g±Î¼¾ZnYLm.鬖c±v8¤�¸�ÊSv Òa¿›Õîm¤wÑQ?)´êÜ,ò &8“Ѩ(P‹üPÊ·y,.z®œ¬o«�9ò_»‡xÆ+U�I0ÔÐÆÿ9ù„ÏbYÚYñ±ïØ.]ÀôÉ­„Ù97$rܬúáÆ}gоÓ±ã�­’·úR8›œv–¯Õé«"{7nm�(Äd|!ºŒU|üzñ\Øþ…±9&àvÚû޵äi¿cN瞇Ÿû¸H¨L ”ÂáAµ%±Ó^¸ùhÎ\\hQ(ñÔ0ù€[±ðŸlþ„�tôÂþ¡€ø,ë\:p^Wàœ+ 2ï6�O~Ð ÛÆEmÇ£¦9�xéIÚÇàºu¬&{ÊOß•ÛqÎC,¦öû3åÈs.W=4Ø÷¬vð’ ÕËÁ&w}—®xgþ“`ô‚Ø7žü49Š ü5ë,QÈs?<‹IÁHL‚J®\þåAéðX©ÊØòý"�·ôO“ë,pæª�†«çÈܘÕ®ONW¼›´sàœO\`š[‚´ 6œ+³ÈÅd¥°³�âáoꦕ¤�Œ¾ÀùFeò¿Õ¡næ�_§�­À§ô1ßœ*¤§Š@^õªWÝ>ïsÃí÷ýÞßqû”OæG=^!n,ü‘Ïø0,xm«^ÿ–™àèþBv‡>d/臣ÞûÞ÷ݾã¿ûë·oþæoÖ|ü$w«\ÈÈQñãó ÍÅC~æ{þù笈NþF;L$* O}›jŸ›bë*Àî»(€Þ޻֡8öa;�ë�|æ;áx Ž_;¼~Ü ýUšxí¹Í‚_ ÿ{^809ñ<(Ö×~!ª~18¿|¬ò·Ïú¬Ï¾ý¡?øÅ·OûT}´{>òRÆ`¨NA6ÅÝà2ºÎ0ª‹rƘnù_þöß»ý…¿ðô��ºÉ?@yº«¹hŽ‚)ü±h¥ó$dxmdðÔ#åÖd6UjîEâ±íÞ>jH~õÏÙãWuÀѸz¬'ØñæbßX~éÅoéyÜÆ¯±q®¶ÍK¯2>ü,NÈ`§î.í>u©¤mk£T�ãœ78Ÿ#Ë“ÈÃCÖÕ1–ôVŒÄkä™ KlGË><=7eƒ^Õ¨ú ·ä ù ß<óãSè×øÅ pS ¯`F×bmŸhvîbS�ì¼â“�c߉.Z´s¿ÃÂ~çd‘NÍÊ>ÒþIúåwpÒùÑ-u5>¸>V<Þ:vàz>Ý#�G5i¼ã£þú¤B�b·U…„´Ïx5gÓV÷5ï3Ÿ±Ó_îos|# z=Ñü9ÿ}nÓù¡çêh¡ßC§bïlFH^بàξã+:Ó§ -/Œ dgSlKyp´mp·©Í)®=2ƒSÙÇÞ£¸Òóñ­1ï‚V-çqt•idÊýô‹ÒønN´Í©×ïÉû›VÀ}_o–°žÁë¢ת2Ά‹�U{À[jí»çSž›�E·ãï±¢ÕÝL37ú 78æ�©10]ñÒ¿œ6.>œËá½üœ¾ÉÙ�-zæ>¹‚2e3átr¥ßëï¬ íáSMÿ‹¹â–M±±§Äf8-Ñsß�,VÇö8Ð’�z“Ž�½î¬\>ú€ŽLJ ø´%/ÿèÍÜK¯·h¢ÓýÑu©º¸S÷ù\V>v–p‚ä\’‹ Š\¿P²ÎÇѽ- :ƒk{ŠÑ b1ô.Î}ÈÍÃÊ“ŽÊ,/bH''ŸøÚ8F U‹K¼Õ n›E ² ‘º8KÓ1 ±¼¤˜ƒ ûóFÌ"Â픂…¶k`4NIîõ¬4ýØ=à‚ð(AG°kÁˆ¨ù‡\úÝ&]ôRCc:ÛôwsÅ^¥¼Ó�t$VÇ9½P3&zñKOc›n·É%ý’ÔÅŸ –âp¬íÀw© ê*«ih·1Õ9<;> SJ£nÜ©ÇN#ª ¿C2O19?ñäíªbwä«sá1ìå'1óö‚G£:ƒ½ð¬˜øüŽ˜[èë±ã<\Æ;á'Ø‚ ȽŸK,c÷.ɉ²J �À~ÊɃ'‘½ˆ1_0œ¾Ü, ~ÐÖµí~?6Ñ%Qžc,¸µí—ÜÔî1rü×77bð„@ÏÓŸ°¸Y› žŽdÑ|ж0ÜB4‚‹^0È�s2 IÁB=1�ؾ˜éŽ7ZÄ€=zƱpmTQ_º‡})Žºë>¹y8ÛG­Êh@î\ÓT�\rêÇV‘%V�qk›Ýp÷ÁÑnÕOücNíÐ @ÅF¬¦nшN¹r1I¹¿0¯ýÆ¿ó+SîÉÏÜŒX…pAÙ †¦ý œ=Åâ ,L%“¶Î¥Î—ŒwcLØRˆùzƒ�fb v±³*&®SI]&«¸Çú�,(}X?êñKo_ñe_zûw>ë-·×}¬>ªÅÎ=ŠìŽa0:Kœô;6Ï/õ8Îtµ=ÀY¼ùÀ?t{÷»~DOû}ííïýý¿sÓe«Ö'µ(]m^—sS×ù;Õ‡¿§Ÿy¥õžî9猋sæ±vq�úâä¾�‚ïå’[æVÔT3ó�:Ý¿6nj3c¥~>ËyÒ79óº¯5.“ÉåBÖŒ,ÐÕ©Ÿîë…6c–8"eÁ×:ï SóŽíÉ7Þô¦|<ø×~Ưò¯¯§>Q…eêä5 Êp›tD#j�ÈŽnW÷ŸûÀoÿ÷?ùnoýs_{ûÞïÿÞÄj¶bLŽÈsþÛ5›Žçs"ëÓu㴉єµ ¿ÌÀ"÷vQªÌÃjiôVæ¢ÛZ-Uðw,R“&š|Äú¦ÅvŸÏ=uÜI—›\uè/ kÜæŽ³îº·Šˆz¼‰gH³#Ök©í­ ^ÜÜç‘§tÌ#äœnŒSGr7WÇx�°YŠ-P>îâ,½}ƒ¢ãWÞÓ«�øè˜ÙÓ3D´ïkøþpø[ .Šï>þÍesK-ÛakŸË•½ãù^'|67Ú”ê m)™‹á�ƿĭ8/|Õ1eë,ÉT¶Ÿöì=öêGeCMãÞŽû]£ë_?Y²q’‘븗æ³&ô>ãS½“ËYgLÇ”è§]b'§\gpìd¡eŒ]ýv?Ü�×Ì£(î~Úø!žûz$ÚÖÍivW/÷rd,û Úç d,ïýÌóÈdð|:88Â….—­“9®dŽçŒ7Ú™_z�”/éç«„úZX[oMˆLÛÃ}”ÅZ¼0ÒßÙ6Ž0V.�bá;ü²™cǸ�Kž¬�àSNíÊ©«Ÿz}PoqΣK¤ä0†ÛiCÝy­ÀéËÖƒ×â’ŠóxðMu³sÀç¼~”ãýÞjòkŒ×�ƒð ΕŒ9‡ù<„ñ/ @«aà?­ñyôåüúœ0ZÃ餕üŠBú)S§/‹k:·h¼yMD¶âV=ùÉÞt‚°ªÆ-Ïâ�Žwòež‡]ãÃÖ×0ôUo¸!rôè°ž¡k«ó5Üq�qÙ†"V*’óà�‘Ðv)‘-Q­D.ÂÁ;eèÍ ûûnæb©ÄêçôaNƒA=7�£ù¿VWŸËð?1Ó1ÛÑ[ §ÍAÍÅ…lýX/>Î=ÏK"�5ÄL€qca8¯�ð¦ÿžcež\å òí‰àAæ;³bŽ«æ²ã—Ñ 22&Eû†šÆw{Ú*|f"’“)�õl›Owzèï@ÞQ5x檪ýˆCå…2/¨©œœÃwókc��¶–ñ�7÷<ôÃæ¼çƒ~ÿ±´xU]Ñc|uBпú,ïr#•P!®àŠ2~q²�.hÔ�C�ÛÈ"ùâ8Z‹yªÿK½Q˜›�—ÝÞòkßrûª¯úŠÛ›?õ—êɯg´X‘HföëU=(¢Tޤ<öþ�>&²á:rü¨ÇÏþìÏùI°¯ûÚ¯½ýØ¿x�VLôšúsL7.Æ/ž¸+Gpñ<Ç@`¢¨'1Ìÿ©Ûó/<7zyJˆ<ø†œŠ ú©’£È�Ÿ²èðyØ}Ûž�¢îf·ÌÝ jŽd®·¸âkXÌÔ˜»œãX~ WÞ}ú*ï˜uYÐM9ôÁ9±z~˜SäÌô ¶úAøØ×¿Þ¿üùŸÿ¹·Oüø7Üžæ{­§Î=žìŒ�kKúÂq´ž`‹ïçžáö£?úã·¿ô-ßzû¦·¿]¹âIò,𮛞�ÜÀòž®×}~\ŒøXX$G�ÒÄ�¶…–G#ó =ÚøêØƒ±G;y³ÿˆm$ß7xQQXkÅÑkôøQ¾¹¶!§‚ªû�9m2Û�!k[}œàŸÍPËøJPÓ³?J†:ô9é|¡k6J^wrì›Âáxò¥Î?/Т£B8g�Ó›cú¢d]ãn §£ÄÁ˜Ú=WzÑŠë Éœ�C->Á<ûÆQùá£uWïâ;2P¶¢².;ç ÜÜ?εÜÔæ;¯×Å:¹@2”#ˆ…ß¾ÑP‚r¾;º1Ë1αSû臰|S«yÉx{Î#Fí(§þ¢tô?*s�žœ³8K='Ùtb¢ž¡.ö\i-Q•ý_cvØEC[ËÊiù´YrúØÜ=e—\`.A8äž ìž‡–îÁ© RÎ1¤NÉÜK¿·þ’>&SgîÉòF„_G=—ŠI^j_àá/Ò–ã¯ñЩ?ì9Ÿj¿rw§»1Æ`¸Û_ÆÕÊ`{ñœÅÔ}ü×Gd6²­7Ò³‡æ´ƒ�¿3’£i¬Ú ¢¿P³�ÛÆ½Û`G̾¿ÕucÝ@÷�/ÌN f;Ú12ÛÝq§;òðt<¼øýŽÑ¨»Ï÷dpïè2ü8öý:/œ’s2P”Ùc×ÜŽ�Ç𮾬¤ïøk£Ž3ÌÆ„¾_wôú¸Þ,1G±xjÆ×\c w�q»èÅ"^´Ôá"e;l!mOÝÁžòX{ëdY�Œ„²À–2¸Á£méÃÍ}ÍÉ`,þ@Ñ.dëæ£‹ ¿Ø¨× ›Ùö}p¼Ÿ¤(™óh3Žè6Æ¡—‰M×hŠá_8[0c€­òÈ@çñúbåž‚Ë` “vt7ÏÆ´x(¤ªÿÿÀ2à òâÌ“¾ë½ûˆàpª¼>‰ô¬ÓOÛü ÄœÞÙ»£hÍ׎Í8Ú4·`öâ‚�1Rã>”-îè,Þ8ÏÅ=ÜòÎUp7w[&Ì€Œ�cC‚ÁôŸS9q<5/yƒí\ôÿ{oØÌ¤ƒ«{³‘Nû”Ë}Üç8÷‹lœ¬¹=xèܼ ø—q ‹Ùü�®œfųïHúÆÅ�WùØ×΢LÿÑç7"8væÅ�IBW¹ãÕ�߯ž1¨¯û}€®: ÜyoÎ#�ïPÈ…7b;1ÑÉGGvzvîæØ8è—ãöHm+xLÔŒ^µó…óʶ µ;g|q!Â9‘kÌså�£–^ŒvÒƒÉæ™­TÝ�{ëÆt#HŸc“c|�·ºbyØ“ô˜\÷Bñqcýw± Uj3]m?äƒÊ)�õ¯_c¼¤s"^™c§†ó¯æâE×ÐYû¨gŽIÓã%ÃŽ›s3 -§êà�-øé ü]žRœÙØä|Û§Þ8²ÏÜ£½âã[W€r͂ڇoó1¯¹}ÑïÿâÛoú Ÿsûø7¼Þ‹;k�PZVoZ�Rý";uÔo•ê«Á’©¯œcèÔ…žŽ?ÿ¨Ç�ýÄí¿yÛ7Ýþ‡ÿþ;o|`Åc_ÀÊ)°Ô[žBèªpÏÕíq³€G§úY<,ñóx‰ÌÛÙxÞ`”È\« ¿®I2_½¾°ïù½¼áš×ÆÄ UŠ×q wÔ�‰—Pññlœé¯.)è#K»s`ÏÍŽïɹ~lÏùByF¯ÝÏèU~‘ž^ã׃ÿÀø}·7Úõqýz°œÄŸ]b¾ˆ;î�ä8™[cgÕì_ÐBàû~æý·¿ów¿÷ö_þÉ?©� ¿W8³˜Á;êÃÕÇ�ŽçµO“óç¯õÀ}Ç™€æv IDATµ›éw-}VˆbLÙ&j‰‘~Ê–;'ø_=äÉ‹|Òቑýº£Në EQLÚµìƒAïæJÞÛÆâôŽ¢EÞ¡×^}=€[_ï6.ó„ó9 }™¿?ÓÖ!&ôs\:¾;x©ÇyõÓÒbŽR=&‡ ì»ø£½Kæ.|Q�UÄ�E_®Ùʉý.Á`iû"ßzÈ›Ïx&ï©Ukë Ù~‚¾c�>cÇèøMzÅöðûqƒ¹â©«a[¤°�Ÿ²»ö!Í\©¼ù¸‡´G ¦$§\WòÉ’Ü“áÏrtÃI‹“KS�1±yPÖ]½ù¥ó#ps~Ë\ƒø#—]¤ìàߥЬ>:ÜϦ #\A¦‹^Ç:z—ªÑ·çʼn5ÐÃcýˆž®«o°Þ�íäÒšv1‘ÈÓ©íÐÇ?c})wMó•¬û‹î4ºˆñ¢¾:Šs‘1dž<�mÓ'û.Gá¬#›~à�'œOÝ•ÆÔ½…{S¬-'oŽq^ð“k𲯌ºißq.ÄPÍælµÇ¡kßäRÜK“=¥ù ~rÅïoÿå|âÉ:lTÊO«tìËeé©â>avO_ý�uÖ›sSFñ …þóžŒëôKñX)B®W'í¿÷Yÿ«ß•3φ鮋8É ˜˜ªÎ?rà½äø'—èxñ\êÕÁˆ8À89X&±QÙØÅÃwšñ=V\æAWùÙEðjüÐåO×EÌM?ðÀ›‹ƒQu (}�MK[\<ûúOJ·Œô4;ëÛ!5ô¦”DÛ÷û0 °ŸbÂJ ®‹áÆn{¤'—Õw�³:¶Mm½?â¯I绘ø®ò^l]óž¶íÅì�­{pJáž{!ܯ83Ö;6û@�t‚Ëàá€n½»8¹lœ˜R.\œÏÈÑG×evÔ×üªSdú×bé£×ò¸ ;⸑–�w:¬`ÿ�FyÕÕømLç~œ�‘Pů¼Œ;�eå×�ÙpìpÑ› sN�w‡îò7±�Òë2²¥>¾‰ç’·e°4ŸXÙø\ñKNº©áÄCœä�S”C‘/\2?f v¾¥KîÀs(âí¶}j�÷ÄÙ:vŽóPÕÖ~å £[½„¶sJò\ªwØ,*ÏÌ»j§\õ+o¾˜œEJäÍÅ5§}ç¼ØK-¬†Zù&WƒÅîIå$÷¨N€sq‘c§S&\kP¹=Ü/‰*�ÉNÌVÜ¿óè²O¤Ì€q„zæÑ €ZXã\?õŒI°Ç8;Ûµ³lÂIdã>Zcäs²q»�R�Ó/²íÛæÍâZô«�‹óÁ�N^¼Õ^õk£aJ¦‚`ÆY™xØÝŸgB­z Z.("eNöâ"yÄj� upOlô3vôªÌ;‘è0{Á7vZ˜çŒñÆ7~Úí¿ø\?êñ¯Ýž}ÍÇèXà†ßÖ×MÜ Dâ\Ù©ù¨íÔvôáò’ž<|ÿÏ}@¿ûŽÛ[¿úëôãÿXŸ�à˾õ””ˆøœ&ýd׉ًÌãß‹xv!¤dQ-dxCœž×¯{^¢!‰U÷>Á¥Ï[+lÒð­M‘±Ù:K¾`ð<ü¥FtBuú'ýF£ÎC^È�ßïg=×kIü±¥¯‹xFFeb¢/s#ú�+�/ÛÍèZ'Mç�E!þ±Ï›a/ÓÂðÓîË�B|øöæ7¿ùö%èKn¿î-¿æöº×>«ë�ÐWl>–2ƒŠ£]u-ÉÞw}Õ ò.¿üŽòÏoþÏýíû¾ÿ÷Â.À Õ4·_®ˆþês}:ß`‹Ãµé�}zô$””2ö!2;¥ºmf%¥Îp‘LûíSMµù¾Å§øqñ›¶R"×'f³¹#´GÚ}RÐ>êVØWÇ…¥+�Ýâ�Ç›xSúCœ‡è[ß=+�öaÖœ€—¹UŒÓ؆õ¦þhTn �ntO½ê6†è#Õ<ÓXsìøAó¯ïcoCô)‡||F>,z/bô;=±Y¹½Ã{,Ž14¹É'KzO†¿æ®¶áPniU†.='us¹ã}Ÿe¸Ë861ØèŒ:s5 û´·Ãðí;6猀±Ýç݀‘bUªª CqOºÝ¾(!±‘vÚŸjë:c®Ù®½ÁÞ²¶LüçÒ³47ðN,êvá̶­½OXQæüÊwÂ1�úÀƒÇ«v÷A�h€`çX̱¬®ŽÙÔŸÇÄ4óÉð&[ãð:Ì]½ÿžîô‹©1bsáz“’Ýo»qÑs˜Ç~pZ¯ÏgÏÇ%QnÅ�—>˜ÒË×cðtc©ƒsý²7žö'ßò,ï3ÎÚV�µ*«n¼Ñ<òÅyrX¯Qú×xðñÑÊ=×òç¾®]9¼×yЮùžî,^°�‹¼.zð©Ýð:T\õð<Â5ÇWÐO,çRùdNòúž\Õã>–M¹+F-êW€íQZM¼œoeɧ߲:õe>ª“;Ùe2öÝE€ÝQj‹¼–É|°(ÈZ·`6ä²ñ ‹´ô�†� Éò½VzAà�»ñÒÆ&(ŒýceðèB½¹ñž6Î(Ö{8I ¥lÏÉ´˜>¶ñNÎvÁ¸L‰–¶£Žÿê[UwWᮿ@V{„·âꛋ‹¼›ìUý¿Ž{Ò{g®{`ãž—¾‹¯ø=ûKµ²îïå¼»ÈF|��ª\|–Kò•üxÎ0Ç’4Û9®c|-l:¾ÝË•ÉýÚ#š±[j³ˆalŒËãèç¥p½S§ã¿b(�[Û,àr“•üyÁÓº¸Péâ¹çæÀ¾ˆÉá$ë"džóÒoÓúÓ(î#{ó;x÷G!¼Ð27]Æ®ír´+‰Ÿt+·¤—'}ô¯í­ù°ÖÜ­Q’À®¸¬µ"„379ä•\&Dz“!a{�­êp(õâvÞ~m‚½@°ªáE'ÂÑ– müöØnO>ÆÈÜ|QOÏj]géZÿàE{�)-é÷]¨`�0î—6áèÝÌ‘ÃÏ=§ä€r³.̵(ýa}T�Ü5ð•K‡¤Mkq¾ÎSåRµc?Ûã–”™Ã#f}ã©‹çèìùUç�Œw½¢2…ªsSÁ´7^pœße3>””@i?˜^˜Qã�j³˜€yõðÙ²ê#£kHæwàežæò�z|ž~ÔãwÿÎÛ§ü’Oº=óÌÓò—Ŧb²_y¡ØnóXÃK·úɽmÜÀhËÏ:KÏ¿ðâí§ô£å[¿ýöíßöm·÷þÔO艨<Å^,£yqžË—¹BáÞà9…|•³1~�3VEué¡z  3NTóºõ!ýzð�ÿøOÞþêû×nßò-åö�Ÿÿ9QâÆ›ï"}ùíCü sl×l‹ýY*”Ž”äò²G,äç \:'üŽƒ£�ÓÈŒb¹…Òw¿íXdÁ»±¡cŠ{Œ_›È7×­«y{Yƒ¿�1Ï/9‚�Ë­SÿË`*ásJÃK($piq}ÐöÕ}Þxê=YÆn[–3zΫ`vì`‚×}[G 6D£þÁαàEY}…éÞšp'—ùž×snëì Æ¥9ÿˆ:Šù¢+Œ³íã`åEÄôß2Çøá÷ë½ÆÜ�ƒ‰gç�ø�›gÒèœr÷5¿F}BL(:vÏÆ¸+¿qN×\ûžLƒÖ8 Œóvðþ,™ùá_Ú2 vÂÉñ2|¬¥/@S>�Uïxs훵 Çè£ÙUîa×öÄ…ÂÇÙÆ�¬¼ðç1Sl®«Ý±b¼ €§|£s€IžëœA"7*É ûÑ�€¼c¼¸]”ˆÕú«‰1 `E¯ ÑÂÆ…A./ןÚe�¿…& €piê|1Bp�\ý#_�L‡ƒŸàr‚ÌSL=¨ŸdüEO ÷' ÷]~÷8Òô�5ýþ¥ÉûÅž PNjÇ@�ÝÂ?rR{˜:Å8” }—|ZO} <1µ­½›§Ýô呸<æ ?´ì_î€2°n/wºOh:–á‡bÊAwdkÝrÁ RA°Øb}õyNãØcV\NªÐeÓ9tæÝækí¬°Úù^yY@¸4—ÔrvA(míÊ[Õð`JyW¿\7ç^Êõ?¾Ó/q¡žà� ßÕ’O.€êÛ{Ù•Cyº�ÃÁvhõSÞø“¥óã>ò½/°Fma¬6V39Ë�X|òQ߃À#®ägb(ù¸5tó�øàØíè§qátÆÖùiÀc_n^½ Ä‚oOâ’Cïra%Aó¹ ƒœ—´ÛÓ\A „Z�wH2rå¨sÊKéT]nj}ÓÇ¥úîs³æŽL½¸àâA#ãšèÚ´VA$»å~qXSÉQ¼(åØáÅf^ÉZÃðÄo‡ø(§ƒûîuÃß1 ô)õQœ&nºW¾¬¬1çc âØQš­¾ìç"·÷ÅÃøä�b=6“ƒÚ¹s6èÞÉÍ@2Žoº:/©[}òh®µ=q.þ¥•àâHúÍ™M› ÷&ª¦5}[…~rlPá#mãŒ7‹\±<|Ø86 ’�9T8öX¬á«Ñø0¾ÆBƒ¢õøäÛW|¹~Ôã×ÿºÛë^÷Zýê,•Ä[ìlü6åËXÙäÈG*"¡èŸíu¡ôý¸Ã¿óÿ»ý¹·~ÝíþÁ÷ßžI I �§Æ0XóM†ËN#qVîãÛz™µ°|⯟ç‹Î{=„¼ç_‚I�(@ï> HLŒ�ël(ni}c.Ò97ÑA‹øè×ÿ]×¹’ÅW�™X7‹ë#ÀG5vý‹«p`›ý+wrÊ|WÕ•gòœ*§é›ƒéWGüÀ[æ„À"ñ+ô`rõ‚~QÙ¸2¤mÚ?­þ·ü›ŸyûÒ/ýƒ·7ª>üêW®Åe|Dô)P ¸Ÿ—¦å¶›~zOba^½ï}?{û»ÿûo_ó5_{{÷{Þí\ò«Ï¹8g~ì9Òø³ ÕÜį_F½”Evò‡ZÇ5}Œ‘¦5 €`ñO{“´õçkt�+/ «s}!xxlïk4掊m“$úpD‹×%Æ-ˆÓç[aæ–‰�]ãBZᆣøÈ' „¯óPüp.JZZæ,ÿvkéé?ù06Úú 臟MÀèˆÓGŽ¢Oõ9ó6 B>Ÿs“—L dlêü«ÏbâûôƒùæV_‘aÓ’8ƒYÇ™!´g¼}�.¹DnKõ5¶êÓ¶?k“1²Þp´n)àF`KJ’–'s.纂/=éèußäÒF‡ZçIE�§ìSð´Ì5þ.×|X{'aÓ� ÒÀ�B[hÚç “,bh¼Wð‰3yØ\VwP¼}˜‹§ïJe÷€™¾óî=kpíw ¿ô‚¾òȹȸCÇ86ÃUq‚ë<Ç•õŠ›øÕ"ÂCeïßu}ŠÑ`P¥\}FÆ9Ÿ‡2|�áûïábãŽkt×ÖþÁ3�%/5%w sìl@½eu'öû`ŸûÛ~|þ0^>ìè²ägÅï ¥Ž»¾Mç#õ9¼@c v>µ‘OéXáä‚/•rðÞmmì.>Ï~ô1»Â Ðt¢ïê—S÷µèv¼{�~�o0m|¾Ïžw²=yœzÔ/½(Îp¢¿~º?eÔ]j'í,® —…J]WÜóYqË0fAnþð˜y¤~rô`ž<"(µM­[¡ ?$”}O–@38t‚…f¸PsÐSÏêG@LÝ9˜©RÔI¬çno n-3‹žå=ArC«'â À’Ðà]°êB˜e°N<ô¾\nû�|T¬WÚj!8=ߤè]Z|÷F ³Ç :{`‡Â�vš É‘~Š•X‰y¨�›¤Æ#Yû±k�‰ÈFO�ô�ehl¿Ž5|—>†×yP¬þ©´Ï¾'øÃŒ…ŽÅާ­ˆÅ €ôŒïâoá¶:GtÙcS^­³·R6jÌÁ&'ï˜ìfž¦¤_¥ó¸Ö‹ãþËõÀ&pŒËzÛb³°ÆGt%�K«xcŸ#RÇcÞ$8ؔϊ ãG±4Ï<Ö6J<‡«ä�·\NÕú¤�:ƒ�w›�÷cŒv‰Àè>R&–³gÅ3±àæ¼XãØiÙg$é‰ �Ä]žnë‚'™^Ò#Ò~÷Åþ“29%6¡-7‘Ûƒe¶n„B'2tRÔ6HX•§s%“ýDÜC;üîwæyòæ^G"óÆ}*C˜XsÓÕ1Åí–æ«m±T÷Ž»òñÑ&yÕ¿¼ ra.Ž2ô1¹n Aãí1¤ã’:[ð<îçbÀ¢^ýø�ÕÆ§�„À=\ë¯7b;œÓñ‘Î=W‚ÒØÉe«FüC*ñ¶ Ï«er P0e`›gö!]‚úq¼7xƒ*¡ó¤½sæ‰0}8�ÚQ|Ü”#€S¾Æ z)ÈðM›J is®d�«¾s‰VJ쨓:¸^d�hÿŒ~¨áWýêϸ}ÕW|Ùí—¿ù�·W¿úUÒ©¯�èXLT@ì[ª¸äÙ©S]í뺱°ò¼Þ~ög?pûîïþžÛ×ÿÅo¸½ç=ïº=Åk¿0rütiÑüÎcÐ?\µÎ=Þ#·Fç±rÉ¢U?âiæ€þäɘáLýºÈnâJи%ïöß\h_>f„ªd V‘¤§`Θ±ÊƘ3Þ<�Q.¨U¬Ž÷á6HôQƒ(;ý™mUb—c†º¹¢'¿Á�UAÀ4}ÁäšíégfPcjŽ \ÒT¬*‡úÿÆ7½Ióî+oŸñk~¥?Ì/ßš‡ £nµ £=]“­15:)6ÅáÑVßK/¾tûyýjô?ýg?|û†¯Ûí{þÎ÷hq�/d�rc¦Yò�¼,nêè¦?y VIÛ˜CÌoªrn58Œ`|Ù#òÎÍ·äp\E]ÖEpŒœ;‰[÷Þ†$«]軚RK íËœqkô­FðFËë-®c%?ªX­áµÝE gèl¹”UNYêö˜Noc³�tŒ6VžZã“%¼9Æøí²#™ˆ§+ºùʬRj'‡±àj}åTb×%ö[—ïž…Ÿ�ïMÑ^—/ò9¯Ë•»ÆcúäºãRõ+¤É]㣹ÇH×3Üïhnr�Á¼ ^âtXãÀ;ùó¬#ÄǦ}ÏÇ $¬Oú9^°_yDÉ<퀎iáHM7y£1Ÿ�{Uoæ'z~=F_]ŽÅ½ôpÎ-‡!/çQôX>±%èÁw•�9mί±Þve ËNõŸ�ôç¥C×¶kCàâÊ‚‰Šð’o«V„||¯c§ŽsxgÌ"ëü³æ¨;öP¯ð§:¹8x�ç§æñ”-Ur]ÙOéèºrù 1Úû<$_ä >O ê2q_ª—ÞÓ®\Ì-nâc%uÏ”òÏÇ©Y<Ïe,‚æ7>ë§ÎivüX~ðt{alÝ2¨9‘jbdž4%ÿªÏ9…ñæÏzOSî‚~í[/¯úІÓhm·32•ÕpH–£b,ú(PôŽqR!.ž�µâ!—(d^ŽúS­pRÝqW粟D€�±€°KæúcSÞjV�®päz†så¼î4ÙÓo?²·Ý8ðXIÏ €ì`Š' ŽïLç…”e³‰#NâdnX�”Â81ìnžæRy˜ÄÅm¸t";‘Xû‚”¡ËŸ/pQ5‘(âëò €6Ô•À"ƒÛL Ø\õ­­@=±ØwÛÆ;CtñO¾Ì}½ v�C¥>0ºa{Ê—(O(á¼B޶ž±·êðßò 9þÑc’æcŒyw1yÞQÕGã=¹—}´ÛÚãwÕ�orã8²±°\GcúƒçI¯ŽÔ<ÅÄ"†j,ÔΘJ¨ÿç\A£ÔéË�46ÎJGŸö?ð‹ÞQ²È;bõ5û–£Ì“¾Æq`ÕWc¹�ÕŽ‰óoþ ¤UÈUËȽˆ!ð$Êû’éåøçxQ{áº%Ë3:b{å-ÆÀxLëèi¼9vXÔxû"¯@ÞŸ~8Fõ"  �Wa‡ÿa€z]âKÕ:w1Œ›¾^ô�Ô žøÏ¹2ŽÎX›“rc×O©Ó× Îœ‡�Vž®œ¤·Íå£X¼ r>Ÿ›œP ½Ó`ñƒgÆcû°â4O€­á)0jÄBéx{¾Œjúæü*/â]Äȼ” ]m°OaŒ#ì<¡•þöÑ÷Øt»sÆÜ;¹\õÃY(cÜèpq1¿l©×Æ­Sì7�S óèÌOûá3ÿqX4è5_ÆCì&Å~�LNr>‡§ŸX›ñnŽ V©w~gQáv{µ~Ôã÷ü'¿çö¿ù?¼}Â>.¿Ø*îü ¡LzðßúŠAJ§ì>fó¬î <˜,ž|PÑä\ÿëoxûíoÏ÷è鿟ÑâN€½PéjŽuœ�< £MǸ±ç8UÇ(³Xd-ÀùÄûÃzÂ÷iQÔ¯k°çÌÖqJÆÑÆ¡ª“ª ùJ=¢ÊéJ.à µ‰e™Hwt¢9úDµ»|Ã�ž|J“>v¤êX{bpŒY$^ÍMÝ£w­‘ sÃ9²?iæ¿ ±WÑæb#9xœU�"vòýêW½Ú¼žþCáG‡0<.Úó€Ø:·îû°ž6}ÝíwüÇ¿óö›™‹ç¯oxcØ1¤ðËžrÔÇUDí�ÖÚ’^kž×�†ü˜?ü·o|Û7ê#ËYdËüàü¬§I4ÀS:¶œ·)¡žqJl9æ2Ö9A²í’*Äýäî tôp¸r®)ñæšÅµàÓO ÕsUüóq.bƪdUÕ“2QšÀiÄÚB-‹$¼2øc2´5'ó��p´AaŒ2ž¤ ·U†¾¡$Vs†n™SÍ‹¹ÌMjº< °»/�—YºÞÔ¦S¼á'ù †9Q7´S&–±[aÑ?±±ú{LÚ.Ð \`òÔš1˜w¼!Z5³ƒÄ8ð¾Xì‡ r«DWÑ�f�>ÆÆ!óû O­qnæ“%çùñÂV�‡'?ܨ„Ûcñlîèyžc¿¸Äš-½Åé)u9Ï"†ßÓkx]a¥zÆŒù–kJìz|¸O:6�Î]YöæU%1lYø¯}™ë<ÑMŒ>¾u|-ŸT(ãùŒto¥×ã~é$*•­üŒ¾³ZRLíkl±› h¬óu <…ìäÑ�qH£ŸRŸ=ž�VŸºÏÃÃõéßóÅìú”Œ©*‹ÿU' €¼9Æ€:a1ù0)åU•íQš@×� Y¸»ƒö-ÅÌú2¼k¬ÔºYÏákõ=à#¥S&ÌgÜhcßâ9ä¶æ‚?âŸ@ÎE»oçÀöãyœ|ñôc]o޼É:Î¥¬�«#¶ØHÇÈÁôÖŽÂÝkCÂðàG\‡öC?Õ³¯ùCvöŸõSßõÅY­ÖñÍØL€E¢JC§ˆª¶´QKKZÒV P’(Qø(˜¤Vêü—*ý§T©C ƒÑF iÚ@+ ¥…Dqm‰h‡ù,¶±‰M|ﵯ};~c̱ÖÚçy_'êzÞw¯µæšsÌ1çZ{Ÿ½×sÎsÊ¥nωE¶ø|,›Xm?cû¤·b—Ϲ +Ë[â³ËKªãX D<Ÿò~ć¯s9ÄÇóðœ Ô€mèþÚN�› NpAaŒbN´Gî<ÜéDoŽ3F�b2&ör�Û£úèWÇþ�ØháFè¼¹XùÀω_¿3�Å]1r�MpÆ(×£F'eµëX9DŸµ‰á ‚*F%uóÞ|ÞÁU»<“}IW¾ÉæÊ%Â%On/vÎjv5úœß”}3É(%š¦·Œ†îØZMêÄj+”)‹ÄÝIIÚs ?1¬ø)ppê› _þþX~3?>êõxÔ§ËGqOÙëßj7qWcó¯(;Ï‚¥fœpÙ,Œ"½µ9jH¯ ?œîõ¬I0y·Ð`ûõÃ�°±»c�¦46#éÒżù¢i�,ëkìšû½^-w.÷/žüîºÉxs±øá<ܨحêöÛOäYDm2ÚFV¸xÄÀÉar 6ÀQµ'| IDATJ6ÏÙLeS`yõØrSña‡‚c±fQÓqôy°oîѵxj÷gyúY‡mƒÊk¦o.Øô ¯‰kJuу/kׯSÿÄ?ðI·¯Ö»ý>ù~’¾Ù÷=ÀÏ»®–m†ƒDaÕÆG6"'"hNbŒ0&†½±AïÂúm}©ÇOþä›oÿÕ×~­6ýöÞêǃ-b”x¸ÁÙ® ¿êP¯1©·½uÂy6pöÚD§ßú|~ °Ãö�´¡Ú¾7×øæTR±>&ê[´d�ÜÑöfO¬d¤2¶ÆV›k�Y¢×G¾\ÛŠ|çÝÎCkëÑY~hÓźnFfy7|»€×;±Ã8Ô1æZþŒ6¹Ç —¬;tz� ×èbCîý6OØÐ‘ð�~Ö¿|ûÊ×}éíãùxðË_济Ý"Œù¥L²�Áƒî?G’µÀz|×»Þ}ûßòïß¾îë_{Ë[~áö¯ëâÃÚcÃ’x¸EÞ›¥r’µ¤$ç�L2Ôü¯l×9—Ý÷ÆÆŠ:`Q;¼9Éa>n­ûµƒ´6ÔÎÕä ºâÌxÎ_Ê%ʶ³Ì'œm°‡G68 Q(c±.X—ob8ææÀâ™’Êâ—Üã?YKN- ²›ñ¡.2[¹±ù?vœ;ÙÌ}%XÁo�ᆭÃjcõÔ«©C¥c¨ÄB³Å˜RºâU/þ«ƒÍ¹èwñßÇÊõQp»bÚÚn1¤¬k’[j¥ãÀ0š«®ÇŠÛóÉeÓJkEƒàp�ê:¬ »Wg­9c­uµÏúÌSä�¹uµwœKâØ}ÏÆy«sÙyî ,µ`¨ál»L&ý{ní·®�jÅ´Âz¬ÝÖ_ç¨táˆuß™ÊX zÚyDl¿™ç¥56k^ÕïšÉ\dí˜æ2ºkY°ŸÐß!åüé|ŸçFfi1žµtÅ;ׄõI!¥ü!3i=×v×"ckšF/²#vM°ïÙ4×üy ÔNLw³Ði¦Œÿví¯�û1ÀÌCSî×]©1¼â4Žú&¤ù›k%óý‰áð—µ¹c[ë¥XJ,ß±­Ïê·†ÏÙN2s®6ÇçœòšOæÛ¯ßf S†ç‡eqöP¯Qžâ‰S&½scNè79†žØVv H[Ï&¹ÿ#Ï·�æeøár?çj<¤ç ¹Íõl¦.‘ßñ~B[8'ýóùV/0MÁ Õ3kM.€ ®aŽ…ÊRL7ýi{\‡QÝR TËy�DÖIìøªá@ÑD=*q•Ý×+JLõ¿±l½¶6×,HüiLÿXˆxõ7ŒIz–“¯‘.¹Š&rJs‘þ,ÐYxæµu,ž/ÈêTǘ~Ûèô„éŽ9@æHq°+o 9¨LÔ®ïí«y ËÚS·,žGlŒú-ñÊ%7r½Q{`/åW2àÕ§ý Érù¨Œ`Üžn͸˔™7ª<Ôæ-ÒçocîüÆîçì«í²Ó2‚]•Úðr|²YcàœVË qçîüçŒÓÂÓÞ¢¾°þ5¶ú-pýn™Ó6µ…MÃ’ñýû"ÙÄ`èÔ+‰1YÕèÎudõ»XF«áXÔóã¯.Ñ ½JÎ dæAk£ºñwaœô}Œcƒ­z[뜱•'&mŒèü]e5RíwLqÓ­k&ÕðoštƒažÄQøwQ††sû3NíXŸƒL£ëãüÙ¦×VlÒ%—píÍdm¨{î6þ“§Ç¤Ã�ceEΛÿûy½Ð?®Í„Õ×!Îñõà‰±7¾�ï@Åq³ŒÌ)ãp"�]—Œ["9mäŠ,9`d4ìF8v€˜ùž‡Z>2¶|8Ú Ž/P(Û6ý›[« w×´Y_cº „Fc=Ú ‹v7Y»ºQóµ’5;z™G¡×&åüå/ùíßø×ÿØíKþŸ½}ÔGþnõŸöC™1åÂ^B§Ô] .yv�\/Á³sADg¥9˜\»ž{î½··¿ý·7}÷÷ܾÿ{¿ÿöOÞýÎùÛƒà¦dsÌü<æÙëI�M1λ?Û qóºË�=äÍ'¶ýÒ6­(Ùpæ%>;�E[Ýü–ž†˜A³…WTF±Õ!U“ùâ'< FÍóÊœk]²å�ÏËalÈÏÄ äÄŸwî©gyÀ8Òç¡Üù&&µíƒZ?𰌞ºµI’Ç÷’¨™;^¹_{©>Rþ2ã¾_ï¨#z#¢{W" ¾P4j/®ŸTœ¯yÍkn_ý¿z¾=ø•š£œ“†õâ·.WC¡XX ~©ÔcjóàÈǃîçÞrû†×óíû‰÷;B³ŒäAyâïnRØ4ÌšËýí–È£qÚä7z©ÃY®­t·^$ãàÝÌw?¥Ã|­Í”åP�‰Ó i’>Å~gó_žtT¬#µhNCcv7#8ˆ úÓR³‹ B9Ñ—OÉPÍØƒ_sœ©€knDžÁŒÎÎÓ¶‰.La²m�—SÚp@×ä‘xôK6S×/K¡lŽ'Yø”¯›:œ¾+Ûub/—Ô�7Z‡3„wæŠùæ¾’s™ù¦ô5Ùm�]Ø_ùÖW1Ë'ù2‚á°^è;S­ÑSi¿浑ûŒã#þcnŸwqï€xôüÉ¥|ãüËyqr)’5ð"Á8žTPq~0×Ükøµ‘5•µöjñë"›N]Ý�5Ç‹ŠÇïqÔwp±ö—€ð®µ±9ngÍ ’•Å0Ëhå >åbé˜:”¦,¬‰éôWl2œü晌{ˆ~Œ1úÇÀm~NLçXc‡ï¡à z6«SrÅ«�uÑžFåXÛ6›©œ7\/ësç`Ÿ»ÎQ\ÏþÍ$× \ÔÏÒ]þŽFXŒÇ}>×)^?8Ïý �8²/lñÙº^j›'I'¿Ú% ÇÚ(BêÇá&QÛ/zœ;\‡ò©,�;Mù¸7–çIÖ^oQp:–Î6»2ÁãÃX—lÖ¯ó/XÇO^ys‘_Òk��S#˜œ9süÁ£|#·DÙUà¸&†UVú=_¬8¶¦b¯�Ù<ï/žlÃkq 1ï8‰§èè¾Â€£j†(ß;»�n$RtTªïí$gzÐ' Ÿè�ösï»>MÝãNRÆçÒÕ¢r²Š;|ã*Ýåw°º òUÏù;fðX ¿�Iv÷g pmYõ¥±õQà*µß¾XžøŽ]|(Þ´R>³AÀ�ø^ˆV@‚.XC#–57ï±vÄÌ\�Á¬ä:Ù‹×%[cvë“ú¥ü @ýø…û~¼ HžE ¼Þ8Ï·1ı¹Žóº‚¸ñ‡‚ULJ}Ïø@,³ñrßÏœ  t²¨s‡k¥úÀ$&õÓPŒßÝ'9@ÿƒ�›ÈUÙŽã®ÿú/®ß<¢sgmbà¬TŽºx­Q·Ö_mÛ×0œ,Tÿ¬çbˆ"_ ’8×&;~¸²!Ĺ³ß8×2ò#ÇEcì�;�£\ðñ?å"Ÿù¿ä òå«VsÑŽŸ;ÖzðŠ©xëg�‹ÃÉÓìX–¢±8€ïr %�É�ý¯íÆ1ã¹·d�ke~6tmËk¿ü˜cm‡×¸gØeå[ý§ïÒIN/¸ñ°ôxÞ’Áh¨:À¹Gà:„,ÏdQ3Gš’çÞ £˜ºqÄ�ëĺߒq½Åj+g­Œtbftù£s±’K™Š?ýœk³U€èé[€7gwÆí›.*U®SjÊ�³"�Í´©ü›;=0~@ |‹ŠP}z4OÒàÅÿögõƒÇâè�ŒA0–N êbg¤c^(êx’e“›bmžÀ‰Ý±N ]ä‘ÔpA¨‡+Ö##Õ]µ²p�eÁyÇœ› ½Ðôf YK}6w s’qÁ• ­£€Z‡}‚¨ÛØ<¹RÆÞzšûÃ]æÚ QŒœTÞ´²Ù$ð N…ñ#uPV1—“²Dm:.‹#"¯ƒÎ…Ð�˜ÖÍ…?zÛóxÚš×Ø¢Ó>>q‹{çQþìI}œïÇŒuŒ¡JòɃwÞÅÔ $˪¹»ú@Ž¡þSSÚV½|#ï8íG•ê;aƪw>ÈÅKx¨±nZEçׂ.çø/&Xllo|2ïôÑáüæ—¶/vƒ0L…CÖ¹ƒç†Ç½vÀS< [aw]ɉڳ>5?” o'¾V“>ò_»l4ã&Y—|Ë/¼xGÜOúÞ<H7¢ƒÇ~|9|ØXüÌOÿÌÛ—ù—ÜüíÁÏìè"Cw<Ðè�çüóù­ë^x67�8óQ‡äs@¬Ð6ulüL¯ bÈƧ»�=ØIÔ8"ä“%À:v%bç3ÊŒu~̧¸nâïènžD xuݰÌk²ñ”âQKI`™ožwòîYÙÛ'8”¹®âÆù ¦hÜ®2K�¿‹'æ±Ð qF'2s ÐÒ� ¿Υúù#¶à£Ò¹¿¨{,÷ø¸©©±ëbB‰�qÓÌ\IÕ¼ç9siÑ€`¸°�Áµ˜çFߟ4Ê'ÏÚX69%{ ¤cßíSÿ2q1ŽÊ&œÂ[ØL.½W ÀùÅ'×´ÎÝÒu¬Û¦~Ëñ¾Oø“ƒb�”öW:3<~�.çŒûʽy(e-Z_müƳ+Ç·pR¹�ÉBÖ ¯™I‘+àZ¼&€GOÂQ{€Å|“KߣkÎ%ÙÜó;.vŽÖ|ËAs‹ž/Ÿ´ lûmk½ÑÝãáŠo ¹Væý‚½@v£ùBÒvsИ,ï=ÒfjÞåRÄ0)¯Ô;cã5[¿3U×"b§8±iÛ7²É œ²XEj•Óq$:Nb)€'ùè/ÝÁÈGBóñobÃö�¥ ìi4v– ÉW¿I²-: äßÂr «ujËçFdéâ¥úí"Éðofâ¦Å´]˜3þñMNq^~V'':®v¬§mF¡ŸÅd 6öæ©Æå„9wÌñ%½.{ðq»â«d«=ܹ ož1RñÉ„æBe5~åjfã”w*η$ùcâŸU ÆÅëXû«ž\œñ0FiÌ´-“¸óàÆ¥±g4óbÃÍ…>Ö6q?9sèGƒ¡Ž�éÞù3g£Ø¬‡rÌ=ÆÇ(s£æwÞpsÁ‹¢äI¡lgNßü:]�àºtJ ué/ÕÕ;ÞÊè¦p.s3ÉG¦tîð±¶eKc)ŽþT ïNGrcéÁ�óGN¬HOú�HåÜéßÜ›?^x_�ŸÄxøi3`üIJˆsŽÐ_Ê« #=—aoYÌmÂC-ïóƒ˜Ïp‚·xNÿ´ÏyM†›«°ÈÑqásq¡eû°ý¼8ycD‚œ·åÂo“3ßû#ßÅQ-µõÎ :cvÏÇß TçŒçÂ×Xð!F,²þ’Hú*– K7(Ý<çy  ËS»xñ‹ÜêE{›l¾ÇHà;dÓv®q•¶<4ùæBùöu™8\ ¹YÔ5Ô¾çz¸Â9›ãÛ}ݨ]MºçÿzËFK’øRå�<2ßœ?½1ÿ�W}èí‹þ£/º}Þÿ}‘‡k#&ïÃç 8Í\Ð}dš�«ëS s¼DìwD=ûìó·_ýÕ_»½þ¿YßèûCzðÖÆÍSÏèZþ‚7*s.‚!ád>ókì¹æÃ1ë)œñ86’¤�@ò7ýЛðVÙ¾hçÚˆ³ìq�ùá¦79/ðÚ# G§ ½A"U ~;Ç®#VìÙÌ¥•f0L?n‡Û˜…ã̹ ÑÈP“­×Ö�4ßlXOªÎãpò»ÃÀâGµ¹‚$Õäp�¤´Þ�CÌÈ,gxpF>V˜Á9R{¯M®çúVé—?ƒ3©÷–àØBu¨dc+²øé8d�ël–ÃÂ�†ÖÈǼöµ·¯þª¿xûÔOùCú½³•�oî™TÂKíI¥eê«ËTz¥æ1cïׯ5~Ë/þò훾é¯Ý~äýÑÛóÏ?'¸€Á†u6ÙàÈ|À¥¥íÇÖ£èõ&ؼËQxšÏ9<…KéÜk„–»ÝCŽ�©¢æV2É‹�ÈÉU×ÓÅ0Ì£ã ×JdlúSz®áÐs�Ïñ.ÿ’–’YÖª9eF~´]œÆ†cø�Áô×»˜|_™k�ã7߬�rŒeò°y:¡äê˜z‡b©ã¤51ÐËÐK£ÆX¿þSêds-ã`Ñ”k,v{�DO}ýÛç‚ÚæP›è?Ò^Š�×9d­¡è ä|JP¿)ÃÄ“«’D”¹S»,Šú¶m/1Έ ñ?ó_ìeÓ_Td4öE©¬›©yŽà�³<§uÝJKØg^vœ3&@˜¢sÏ ¥ù.–…ˈFKrÀÊb¿I¯kº�ö8]XøÚâ´4¶\cáBœÙÔë9uÖ¨÷I|”n§‰è˜"­�Þ³9—¾¦a¯19#-=,ñ£ü¢_9~Â;Ìâeˆõ‘\ÜûeB¼>ú .Ç3øENgœâß"R_Æ>ØÈÈùÃ:î§{DZ1‰\xçÜô~†ú�[ÆþY–Äi$˺ãÓ¯ &· ºFל˜r|]ÆŒ]³ä2ïžÍ;q…•qÜJYL|¦D›uC­ŸØ ?m)u^�µlvc“yëk#ØÞð•ñy*ÖƒºnLðÁh8/çWø«07ê;“óðÀEõUß%×¹óx´f¯ˆrF{m[?°Å\ÜóâÅšÍCí¼Pcµ99šÊä­~Œ7órêzg9QãÌ›918˜®«lÛ ¢çÿü¶IíõP›b¼Ëd7òäØ÷ø¥UÓáù¨uŽD[å�›bu$ Ù ðoåyÀÑÏes¤»ùع"?{\<çPoVˆ JVèXê+¾TFÇr $à‰|½ØHÞ¹¼äÁ>¤¸ÈÈÇé÷lƒýH=ÉWþhSb˜yV·<Ôuý]jgÝÓ§U4º‡àÒ‰e�¦=*½­ê¦ÞÙtŽ냇œó±±E£¼Y‹çoS‹=8“ÿÄ^ƪ×:úbë3ðb¾cŸŸ;þÍ|ñÁ¤œý¼³®EºÂ3¢ÍÊG«ÅC9°b�µt"—›ð< n®•{Ó*ïjÉù·íë®ë·‘ŽîÄ·�N�v´FÏU8�M?$U eú|)™ÈMo†¬2zæ\‚VŽf>„6?”¼1úõcúu¹ÆØØSÎÒÚõkDp-{ÉíɧómŒÿq¿ïöº¯ø²Û§üá?x{å+_‘Íé´´ ÝR hèUF¼`ïkȌ辖 0yð×»ÿéíGÿÎOÜ^ÿ ßxûå_þùÛ“/Óùò[ïÉœ;ºNòNEsÖ7«³)-k³OxðÈºÎæ×Õmαàl½ž©w õ@ÃN©X)RN'÷ü¦ö}âyÿK'™¸ÀmcÄr†ŠÙöì¼j˜ÍÚ.ÕIo3¿³–¤Ê}‘7|}=×;­Ä�fe8wÄ� #(€orÆd¬ùÁuí¬&�uO£k—Xæ4$q•66áç¡Ä"…b²îy }¾QÙ<Œ1öLŸòcN^ÌWüÙèvÿæD[jÃ7C¯þ°»}þŸüüÛçý{úxðùíÁ@“ß)½Öý™šª\ëGØó7¾=ømo{ÇíÿæÿtûŽ7½I×ò­â—w^°˜cJ6¦Ùd®ð· 9Fã¡ÙùÊ£Ö5ÉG±ü‘o¡ãŽ[7ê@b.ªÐgNú‘IäÌMqÜ>ü;g!ßÖ ’­èg­˜ñŒô>ƒ{¶ó#ÀpºO|¨WSdÿÌy0ÊXEv†S³öv³ÆX/}íA(Ž~WËõ#À�Ý<¥•œ$¹—1‰’‹Œ¡Ÿ’x¦‚ãM¬•.¦¯Ôy9âˆí¼Pëgý�0œþf÷E̛҇_†ÏPïíjG»X‚°³‹ÃO†%ƒ`ƒº C”¡¬:ë#›”ù Éu³ÈÚ:˜ÝÔÈ–›tÖ±„ª¿l`i�3t¨…¶ø¨a›κQãZ©› çRã{ÌFÇ{œ´œ}Y«‹?#­¶©‡êÇÓ^÷÷v‚HZ“óŽÏÙ ;%×»'ƒ7£¢‘¸ã󛱿¬L=øŽ…ßøõ�^c=¿“Óè•›Éü @¿ó\˜ëº2ø÷6 5O'…Ý~‚‹ÈÝ;sjœU“"ÔPmA¤€ø{Š …ã(ró­ŠSÒ”}ºjÀŒ«yâ'ÿ¢}â[ÿ¹6øµ¹÷¦™âä�j|©Çgó¥þÏÜ>ú£?RóÕ¦ËØ–‹ç'Sv?ë!ø‹‚Ã9crNgRkšÙäxîù÷úï¤}û›¾ûö7¾ïûoïyÏ»'oÚ¦ÑßnS:oô¥/ÚLåá¡€ÄáM iPƒ™sò"�¨Ç!¹@×"ÜM t@¯ÿ‘ŬÁ\ûÁÌùŽ;â:¯C¼p½«m’R$xÀ�:~Èeü[`ùhObËÕ6öwœÆ8�ûX˜ Á‘�Œþm8¢Â»c.][päõ¤Ü¤×ü@‹±¡§tþ“CCY×-ëê`¹Öžü£Š6¬ÓèíöSO¿Üòçž{vøÄ·ùJ˜u½Â«m°ú:¸õ“ãŒÕ~YGÒWÍǃ?ë3?ëöe_öüíÁ¯xÅ3‹›ç ‡Ò=ç΂‘ƒ=)¸Óñˆ§-m¾äÝÚøþûoþéÛ_ú/þòí­oû�lÜØÏØ©Ma °Æ³’µ×uÑ:z Lj|aþ$ º^ƒ�¨¤Á6œWäÑç–j«8Ù¦°òN 6›¼ÛoÏ-�Äÿè¨fÜidâÁ¦sïw1©ýÛ³h0—!Øsnèfã”â঒OóI¹€'‰•‹1tÊkÜY1ë ç’�çÏ%d½e�¹þ¨÷øwðS¿c 4Tàà¦9Æî!^tÃÚV:¤çùÖ}%¦ýfË䬖m }Ê©C?òäëž ã”ÊÓÞ9÷à1^½øX×!Äl'?ô<çRÝV»ÕXÑ£8g áÒmN¾ ` :pàž�k#¿ÔyPÀ¢ØŽõ�_Ìœó[n©Q”ÑØ™Ê�Ï5hàžC~±Œ¿DË\-J0ÜD”5š5)�å{x=Î�‰fбð²•gçLWvè£H^<ß:Ö^ÁòÅø$d¸yè‚qç{lw,Ï'A-Ž��ûÚ:`‰wç'ïäO/Ì †s^�âu}:¥OüÚ] Ü·>ë\“ ÖžGÜ_¶¨ÊÞïâW.ó7'÷Q÷q3PhÚù¥ápŽåL™qçãÈ©ª‘t&ÆPüáëJ>Áæ]¾ÌwïÑAgæž|`�Ü<ä™ÜÅíÞÇ'ïÑ|#çŸÜ4Ö½ú-�¥"Ó€_㪢Ѽ¹=:Ñr©OäõgÖÚú0ëG-W‡Ò¡Uë7éKøˆñK‹±œ$È'êä‰ Äp…§7„4–oç»ß\Ôœ9GSGv °À©ŸåŸ�GøPÎtO»û˜ò›ùܘߟ;õÆìÇNîÁLÍ$‡<2q/ŽÑ­MtÔSÜÀ·ðŽ0¿ êæbÙN¾¶lDÆÿ`Øøaü ¤‰•®gò¹øªéÞÌ7¼ó�ÃÃúŽÁÓ(;ϧ¬ƒªÊÀ=Ì—=:‡{Ì�ÙhËQ¯CŒÎ†àýÜûÝÒ:òwy²¡³ã!ïpK ê½½} ßS]—sLw^è”ws�ÒºX7¤¾¾¶“sóa`0©âC­!dÜæZ6V�škGý‹Û4Tò@�<Òö›ªÊ%7áxú�þšÛë^÷å·�/õxõ«ôñZ½£R˜÷HèPÎØðT¹{ð€:ª«sb Fì|ñ›ÿ×ÿý³·¿òß|½¾ÜãgnïQ¿œÓ»ýø;ƒÞ�@7*àís‡ @=äøNæ•£ûë§=YŽ…µÝÚbÚkF嘤ô8úoÄÁ=Û¼{€|s£ö¾õQFÍ ù·m¬ccÑÌ�Ú’c9öÇÎqyuÍ¡@»1õu½ê0Öv³¹®5¡|rîð�ã_v�Ïa`\û‰úXcBåßYÕæk¿ 3rã�‘y»(² ÁŠŸš2ß´ßûü󪛖}íY÷j²é&úä€~‰G»ù»\ËÈ56|ýÑmÖÑóû?ño_úÅ_rû´Oýd}�ˆ¾=˜Oh |Ï—ú¾/n r0]�vãh}ŽsN<Ëǃßò+·oý¶7Ý~è‡ÿ¶¾ñúÙ.Çà8ä§›Øô[Ûíçœ?ÔJ7¿lûá ×LUòÑsnÅbÜyÒ5Âçä m®e“—òê<$™Fr>šã6/²Åœs"ygª3ãCî¹E ô, ßA—mx�¼£º X3s�)G‰ÝÍŽ©Z˜ºô‹¾îä¡6> Öù¢^+NÜæGœõcÿ«ÆÆYq®´ˆv>âÏkMU†_æ›yÚ¯;'ÏjÆÞ„ ïÃ÷îÜãRŠ G‰ äèDö8¿Ìwj¹Wc{0ßugÌí!¸ðA~Wª:âÌI"ëq¯U”6_øsíàÙ1×Êþ©t¦ ¤âu½ ”Ü›÷ä\X/yrß0:Ì`dñŸ5|G¾FÔ”±Ç­Ï±àüfÀ÷»(XÇÚίWÔÈ Ç(¹wn¢ê~š²ýÅIîo笶Æ9ýº||Þç¡^Bæ<×ñ´ñé¾øIüŸ¸i¹™k,z‹*å3=UÛÝ\§®˜èúuƒ×F9ðŸKl»Erì]NsµW.ÐÓÿs]µm^\±�5pͱ~–^'�ÀÕæÜËóÝЧ¶F^õ_Í&åJ£þªw_Çq`›‰xL¬œ;ºñ ® àêª!}]�í9á›Cñ×ò³„iC]b5Ζ�Sa��rÇ$gïÁ×tÉî_wÀ¥Øçä=’ãèXòzSÇèCnƒsÁ> ¦Ýùñ\2ßsîø:º®;?£:E]n¬¿˜íƒOrNŽÛ§^e%#™›IM0;½$ÄÆsXº±.^±œ´Á>ƒj(çÜÕæRøÆšAcñÁô)oª™ @nòâá´ÁôìŸí�uÕÅ}iY±ËùÔìÅ¢/Z¾;—¬ùMs”ÄL²ÑdC$-õOM9sjxdúɨ3�£ÁíצêKbaòd,E³~í p)ûíÇjÁ“ÒµQ^êÐ~#$ç§nm»ØÏ5X;lÅy�79v¼“p÷Ž�‚‘)­Ýc+ÆŒ‘ƒèQ/~ÈÈ%þ Msd�«Á`Œ‚-s On$³‘1˜ÖÈõ=ØH>>ïc®&ãà3îB…Ý] O=ô§5\ݱ빳¾%éQøÛnŒ‡¸}0À?8I¿£g£á)ˆ“Ó…6êwßä8�ÊK/�¾™d3  �›JJsbz¥à‘ê§îšô�÷ý�?ú—Øö&©_èú®Í7¹Ìྙ„qÛËÑNÀ08}ЗîÊcˆÙ„¹TB–ÜÓK?þÜÓ0J°¼á«vn&‘_¹� µC‡2\Ü^Õ«ë7k ˜µ‚=9>!¢ê,�«Æ“yÊÇrƒ�-ûÁXÿ¹)ZïäüÎ�9Šl›ùà6vü§´Ý¾…Fçát#åH^É[ìI*½—}Õ‡~èí þäèÛƒÿ�Ûk^ó;o/ÓGæ/ø(×h꺀¯Ku¦[Ùz|Ìö}:O~óïôǃ¿õ[ß /ÂùM¹Oö?,i'/z£×u€àžwòiXAú�çZ“ÑÉú'fJí:?ô[Àp¢�süV?ÙBKº£>=ç1"é“ì�ï½Ôù`møªÅù�˜@Iéœ�‘øãõpç¹$vã¼?6EÂyôNʱ»âÆop€ì`îÙö»½à[n_?Žs\:_’7ïè-ÚŽ éæH�Rn £GØaÓ’çòÄóΰנZìõÈâÕ8\kþ;çVmçehf j`úØQ–ܽûCÖ$Ø—�^{�º7vß¡ Ú)Ùüwbíˆy�^ªá¤íã¤ôËä1çÅhžî烸s­—.ê�¡m×ñiŠŸ™‚A0ÖÀÂy ^9è§tºiÆYÎuvÊïÛ‹O¹Ž‚ý6�“±"?d'fùÂÑ÷#z0G;ÂlÎU·ö¨ø‰�å”Y02�ÃEjœgžsºw<ö±VÑ͵løÞÏ·œ—záYާ?ü[_•Kû«ÎUà䇞û£c'¿(˜CŸoý,¡×Hì»�Å50”3Ç�ÒCgњθ…О—Éý‰Û\`F9ç…ùæüéµ²×½¦19ÚÎÍ0©.¢ä䔌Mc6!i�3ßÓ/_c‰!HÍ ym$w}·tôîr—ªèDrâã—ÁûWÞ'‡Õ1¬ô¹‡£,=0�?lT*—~—ì�Ïã<Àãò@” =rè2A8˜H<™ü¦Sʣˎ9ßy§•j9Èöê¶3Æéëq6RÇ„rÁ«m†Œ•IÏ$#n¹@â @n”C�ÓßøµÃ¯O¬‰ÌKñ;ºR8횉øŒ�_€d£\ݼ<ªºüpc'ªñ }•.š.täŽ!Ã+'ӽؒˆ.¯…© Ó.8aôÞÞ (Ò¢`ALö\ ,ÿZÜóBnþG¾ÝG^£»zaÎ\0ì ¤{“’ß>Hæô·>éoŽå6^T5à-ØÈOûá&$ãÎIO{¼Ò²¾Oj.>º€Ã“|{άˆW“N“c¹Ó.Ú-¿ŽM¤Ú¤?øž_gcã&�çÍäõãÔGº³óZÌrÚõð�`å�AÅËHßÅ24\‘ŠK¹pî<ð’^ ùí"8QŒýö,õ5~ÉuDž£Çû3ÕËp;+r»p5X¹#”ß\ÀOcó´ï˜ºk^hx98΂¦¼ÉôAž¬f`ó!?]AˆíFkŸùæc«œ;šo_g2·¬©p©œ§lúÒAyæ§sQU{2éJ¨ã¿y¢Ÿ�=䔸êºÎͤ>L.½ �ŽŸérn†ß%WKÏl„ŸsWNF–nbOLðìÜÕ'zÐ4¬h#ïoæy}tRF¾”ÔpÌØN¨®LzDjK5ؼ/ŸRæ]í³ÇÁ�BâÈkó3ϼâögÿôŸ¹ý‡ÿþçÎß7ÓüJqùÅ·ŠmˆK?Ö™GóƒÀ}�ð)¿ëó%-|ñÁ/ê�Mßðú¿vûñÿQ�뜧x‘áŠUMrH^»ñPX懿ÈM¹7¥C»qC©ëÛö‹xæ ÝÐëßT« c¶ Gû.IŠŸ<�¥”†Ë8¯ßÌß ˆ‚µ¨µN‰ÁøÓyÅ�ù4rW3†À¶Æš5¸æ0\¿m-›•^¹ÈÜ‘5Ò�¯ƒÇø‡'¯Sæ?ö^,4•Ú+±4^"— ÷‹Òãúã2zÍ9ÖuM+÷˜p|RÖ�o!yŸ@¤ï¶[Á'~t²&’#û´Ž˜â”¶¸ÐÛ¿R‡~ß­ƒº¬“úC�_|~Ú§~úí+_÷eùx°¾»qa+—Õgä•©>ó’÷Ôž�Š•_ò®wÿöíüÔÏܾö¿þ+·Ÿýþ¡Uó9"^7Áóµ0Àæ>]baãŠx¹Qïyª½òeâ6ÿQΰW’wâà?2iõH—\\‡,�P¶þE£zë϶ÌpBÊÜ€¿úr~£ Y ]b¶?‰j›Ä™Ø¢«‰ÛÄcœÁä<“µãç�ý‹åâ3^n9ß›�`”ó ϹSìD´Ê8f¬ëlÊEÿ$8¼ÑAuoåOùÛ�“9küŒ]ðÕ—YeѸÚiÌ‚ŒåxÕoî[‹‰Ï'ú<“Åç$ó3ÞsæË›ñ ¨�‹Ä“>®±hŽ"](éúxƤñÅ9ó–ï6Üßþ¥­8æËÆð_Èúh׆þ¤Òž—ݸv?Ñû¥à[–\� â{=¨ÏŸeB˜wõÌÝ|¶Meý2'àQº>hg]q;˜p@³×Mt/eô"Ë5ÈsçÍTæë¢½|#=ç²k9¼Î1u¥ÌHø€™Î\6}:)“ÍÔ|J"oÄ‘ÎØT§9ª­N0Õñ˜áÇÇ&¦!Î÷È­?9Çf´mn^{/RÇß À÷ϧ œÔV.ÿ3ÈRCQ:ç$<Âu8ž1¯¥ß8ÖU°e§sǯ;~ÍÉ߸¯þLY†q�Êï"›–¦ë;n¶&oÈéTY͉Ø*m£G.)—¿xbxôчâàÇô­&f%tèc bŒ_¼=’1ôxÍá<Ëšœ_Й£îÍéX¨²¼ñ+ý4JØ®Í8æç„”Ö Ì8~¼¢GÓÍ;˜ìôzâG·Ä.ÁΠð|bO 7J !/âú)ÆXÍøhJØ…¹Æ…'ÙšäãA¬¶vlßB91Ëqxœ|Ì@ã„X®¹Ä&% K<ìî¸cŒÀজÿÝ1_xõ�?  ö*ìÊ�œ‹Èíx®{ó<8,[ã À±ƒ ~ð¦™84€ ‹_û‚â„�Ï �b °²Ö½âf27öãÀªÓÚ ýpÉð�«Y‡å]÷÷ãÕ5Y›ZâÖEŸyÉÃ7ŒçMMó¶eä€Ûpi΀=óa¹%W’ɳœƒŽaK‘•bé\tÞìo.âhyóÜ“)ìðÝu.ƒ3¹A–ñ䵞ãÔ%¡cÔ'Þµ1èñŒ¡“G¼“ #o´îòQÑg 9ê3¯°öæSáÒîQ›£nXÁ§Ô(8—Ë”yâQ/6"à _\b~AɱÐÒ9t´ÏyhÄCÀ—ŒÙvj^Æoþøƒ÷纖•}Oíq<x1 ×4ýÇŽ× —ˆ§ÿâícï'Üþóÿì?½ý‘Oþo¯üúR�'~„q íëm‰-+/:¡pªÏÌQÈý{ß÷ÂíÝïúíÛÿü¿üØí oø¶Û/ýò/èK=ô®.½{ÿHçƒ7#¤›ë›D9ŸŠÃ8ů�lbÈ–�Öz³Crè´àªùmj®—á›:ÎDÒÞÖ™ÛÈ a°p$AõÒÍXs~X£å< KIvéÖéxc¥ÆÖ€âésdý¢œ‰M:q1޼ޙ¯Q’MüT· m™©qËy½3þZð‹F,üK[)ìü󄿣ü �/‡T5‰æ½Ça`øˆ‚ºÌàÿ„^¿áÅ늱EÊÃv<Š ¢}j•©B5ë®ÏFOVݱßa#ÑŠÓýæÊçuE¯%ðó/–—cC‡GÓ°x?ÄE âv)?SŠ/ë,|iZÜ5y­‰‘ó< üÉ ]‹Ö›p$$›öWëǾ^*¡‘_z#(Wc˜ˆU�éüŽ¡óç¡`AÚsiY�Ë!¿°›ý q¯�¾ûÎán/ù—Nâݼq3žiz=!0¹_ç›Gs¨Ìë]ýt�`˽žÎwbé8T¯¼>¢�ÞYŠk>3à¬8qBœ|]¸Hï>&ÛË&{ØåžŒ{çõTÖ¾ß -k>O᧸5wÎø1¸ùŒRÛ'â5¯Ì;Y‰o�©�~²Ô1 £…�ÜÜ‘óêJ£úÔ.Óhî«�u‡¾r&Åæ6lÆ”|ê'›Ñ©?äËÇj9“ˆyÁÇN¨úOŸº²xɸRx×àKõ®©AYü«ßü�·�{íGÝ^ö²§÷· Ö謹¦•!ÜœËr©ã‚€Qšìø;f¿ñÿ¾õö†ïøîÛÿÐk#ð9YĘ’ Òö»þ¼™”xpáù›XBŠŸü1öœã¦2W話¸È>î«�Ÿn¡JÁ�}m8fsË*ë`Þw¹É sÄù"|]Ï]Ô‡/Þï±àÃFö?±Gäsö|£ÆhÖç‰oÕsŒ:x\–ü£DNøAB¬‘{#Ãqò‹'a ’ªŽ;.õùi~Ð9ûÅ�/;ô8ýí+þ"K i'/r¡9¯Ûá@,٠̽Pt_ê�µ'v|“ëðÍµŠ¾ó߉G?ÙÀ#çšW?D…�œØ5¨¤È¸ôçž,ç]ô­åHWŽÑ}ZÚ_ð§þÔíßýãŸóàãÁ6f€Çg+ÏG;÷µ™�–€uêj®^ÐCÀÛßþÎÛßþáÑyþÍ·ßú­ß²B7l�™¢ÇÚc~³âóKîRèÇgêô‘Ð÷}:†Oçݺ'Ï�ÓP4æ ;uú[œøf(ù7®º^{¡c{Iü�qlÑ+�±^(ÙXŠ9f®SÐK‘Õèº/�ŒÛ ^d)‚šK>H\›ç�öT ¯èpŒ¿ð$WôS¤•ÖA�èÖ®j‹æÙö¹!ÇÄmÚ‰]0]¦r›<”OFWQ»(Kcó¾™3?á =nU_×ÂÀ[ÃÜÈôÉ‚ü |Õ- kkŽÐ´=Uè<öüW`ÝÇtr� ‡ߣØ”6c~ärl ñÀ?öM„”®8EWmÃQ>ÀNñ6ý1¯N³GC¨ÁºÉ¦?4˜‡Äv¸0XÖWpÁqO ‡ÃÕD LœŽ°þ§KüøKÙØË¼| ~KSºë_ˆ§^qŽ˜Aü'æ­c[u—½‡ª»¡1eYT äè7wåi…òRÇz®Ù±«¯�}ô¶zâš<ĦíZVCQ+ŒïuæðÚ�xæä� ƒc·™"ßJd÷w IDATòI9Ç5‡c´uÈýجö���±Á‰ç*÷p¥oì’9jÇÏàÁ£�p²Üãhî¼y¬àîäû[�ÁhÝç¿¡É|c„ÛæÄèx‹¡±æÃ.ðUŸ´éØçª2>|ªJ7%-û‘ ùKÝ|�³E\ª‡È|ü<…'>ì5¯]6n©¹á"/þgä. ”8榹'`[Wí.ãÅzÛ>5Qü�¬bÜš�x8 H!1€)˜d1ìº.ö"é�ÿ²]ާq‡õHަ†;Ö£_ÎåSîwuÖ„ìV,`hùQŽýàmI^pj¢�m}G„pâ]ãQ�|H©cMœ[ú1c´[&ç£k=`Z$@–› d=�JàgjàóT£�H2ûI×s¼â¶LŠVBYÿÝMÎ.˜ƒ‡BüçY›À£[çrá ‡ò‹š…Yƒø­ƒ*qk„dÚU•­%� ]ȳ&¥„žÐ:ç‰ýwì2�c´â1ÎCFMîÅÎ*�9„pÌ2×5µAñ œÎõšŸ…êhÕ£n©ýÈ/Zê\|�VòQœbÄ2ó,´Yoñ$ã·Fšvý!1¢öYǃ³œ·-­–BMîe§�=Ö5™‡²ú>y>°ÃA×��ˆAÅ¡D»ñ#®}ëS¶ÚÂd`_ Õw0ÀÒžM é5ïà¹Aè9Ö™Nǰ9çÅ~@•Bô·mm€p©€2õ#ʹK ”ÆQ—Áä.çNÏ¡‚Ÿv[V¯ —½xñZ¹hñÛ`ú’ë]¯|ù“·ïûÞï½}äïùoüÁ¥zv7+»ŒiHìV:)¬³}âñM¦¿ýÛï¹ýôOÿÌíÿê·Þþñ?ú‡·—<­wN¼OŸ ð͈Ùæ£„œsÿôöê‹t¾îë_û©Ÿþ)’jþ~gç¼ w’C0»îxG!k,*8Î<%vw'ñå9C]¯ÿ“`Tœ¯õ®Ãê&-*åpúD^lTÏëŽl«“û#�»¦˜µÀ\Ø=×T��¶ÑÙ% w¸Äf�Û�º­ �®•âã|AhbÛüª[Û뚇ÍÀºÂ39Ø›�;Ýr]61Š}ÞÛ&¾37öãh7>-tÊ¡ñX>ƒ½¶ÒEäóša¹Y¿ŒŸ¥¹I>®ó½9ï}}x˜Ûbi±¼SX÷hD«òÓÆztL¤»bG¤ÎµÎ<ŠõÚ™UR_¦!^ÉÚ�_y!¥ÔÿYÖqˆöÄÿõW[Vkµ‡)úà¶ ÝùX®Fïմ«> ÖGÙ4²æÒ]N0Ïpp"p—R‚¸Ýx^Ô:çÝÚÙÚš4pÒ‰”ùçºrø_†qs•K6®$[âA\“åÑ:²ã`ÆÝØã1Ái³åЫ‰g£˜X7¹žÛktq=üÊýÁ|®øsnTb>Wfœ~ùµ&¦êƒÕ#†Ã{s „éà\çàÑ>¹gŽLñX‘'O‹�°y­î0�Íü¥O¿ø ;Žûž[éÊãa1Õ‘uÀN©—‚ºÑ©ÿêVÄp5Ò8Èý|ƒ´}c�í’.÷<äà‰ýð�„²ËJÚðoŸÚ¬X‰Xå¨$Õà�Æ“º9ÍGB'q·‚MW؆›E\݆º&©É Ü&)ŵåMbëq{©ëßÄÈ[(Ï©öø ni˜$Ã9:ƶÎ5ùMÿC}p³Ç¼ˆçŠÍ¶ç†’�Zr#uòé¢)vûårÖÕ‰¬ù#f9táb¾ Ô ÅóÉ0úðâac_8™Ÿòñßµ’R?z÷À·ýŒt押֜ŸF�i—Ksט·|&æöõPqy»ùlv~3ÍAòâžF6é¿~€$�úiNšïI¡¡|â9—ÂrÎq.]üÓÈÇIüàØ�ë '· �^ØJ!Ríøõàe ^ÒDÃòÄ\¢ÓæÔØc£­Á'ôUîpYo7?ÐÚ¬uË}^*¿¯k§´þ÷Ú»¿|JÄÇ x€ðßHà¢7<gpwÌ` p懼”|òU>ÅÀj—}>T¯˜é?ŒÁ­|œŒ¯ùÍ]c\±È¬xf*ËíÖ|b�ܱsÑë“R|w¤»cŒ$:ä}®çŽá±èï9mޝë©Ü£Ýc¸”;~¶^®O§ÿúb€_±¨Ù4àHüðÚ#¥3VôwNWñ"¯ ¼Í'¾’‹pbœRØ[f4.ÃÝöÏÇ”�¯wã,5ŠO{^,.×dÏ¡«!ñ5ýyÐ)zäA~žzÉûo?ð7¾ÿöû>ác½yBn†‰ëuˆÓÝ ¬±+lXôÁ)_ú64ïÕ—¼ýíï¸ýõïûïoßõ�ßy{îÙwk#ò鹿ŽH—kgJæÜsVŽr˜9”s©ª›Ø�ôŽw5éõ1s��5Æ}³'«øÀZyqŽ„¥®õ!N¡¯ç—®ý¡™½â�nÌTê<É^óÀæ×ô“ÿ2À¬ænÔ§›_X�JÌp0vÎýHw»Ú‘°^Â-˜Ì�c”šcÔzyZï åcþx­ðªs™÷¹`ƒ97Ó¬µ8ïë›Ãp#0¯“êL>±ð\¨öë'ß7ú!+m˘œè_þ“æxæyÇ&%îú~GÍC/TæèŠæ£õwõñàOùCúxð+¥“¿1tE�'ó!©j³2÷-C¿rÛÒ¡Œž›j³Îž}îùÛ¯þʯ߾㻿çö=ßóß®¿“™|é>Cñ¾À}¥æœ�K0¼& ¬ÈxíÇëÒYþv-CÆM\­É0.—a:h'¯˜�S¿þeÈ>Ñ{ô|Ë^øq•uk8#wÓØ¹¬ 6Ž‘ ¤{ö¹ä³nÝ¿·ó 8\Ï»î…pF ä’òÁ±œFÖ|ÛÆ¦´ô¿Y§M¹çiu­1ùsþ�ÀðÁÚÞ¦‡�SÇGkÔï¹ t¸êìóå*/°(™#:#˜8ÈUeåK�{ôý1ÆÎ15úÕÝù�˜‘Å/×5Ët°Õ»�­pÑnÌ[žÖcxòwºy§4ÏdÁEÓ0ªƒÎà?òêã‘´lŸ[�¡ú¤}–-ïµ ÝÎGÛ:¯ô  ×J%çp¤í!ÚHü•öõ™U˜sµ#Ôµ9d Õ"G6ƒ‰iûKŽ:ŸÌw?>ncÛúÛWxß÷qSëcÜÖ»‡8œñ=ª}Ȭ¾ûðÓÉ#7ÜKÌŸ–¹s”9Ý<ÂIh(¹Jð×\Œ^âÞ9³É>ŒõøiX#e¾™«rl^�ñÏk„q¿¾FæÔ? ¦qô“7m/)¬ôŒ_W �ÎØgÝœàÌó­8<øsa6}U´ eßY‡Î—FNž×vrgNƒ—scHy ×$�Âë÷°4{C‰xço‘2�Ó_¼®ãмƒs?•µÆ¶m×ç:[ ‰‡¬Kqœ5)C—e·æêŒÝ®peóÌd°þI*‹ñ|A|Ô`î}>R.¡å^ †ÊÄ©yoÏè£dwr&‚‹+»7“¨`Ë"Å��Þa­ÅTžÒ"½ÑÇfs4¼ù7Z‡íÖVkùޏ>©uƒä�rp“¦îÂ+¿ÇaÚâÊ\$Yh†Šo߈eAgŠ—ìæ>Ò³b!z¾ÅϹdPæÜàoœÍ›„]ä“AËfÁ7wõs9q¤sÚïèˆlrwä((—|‘�äùÆ)]€ >£5MrêÖµS\É1~r%ù”Âãt&¶ØÉBz´ÏùÌ ¢Þ%ãœlb4¾êm|É«1¸‰&¢ó"CÎKü®Fõ+§äoçı $>àÌþqîûo븽Ýù¸28œÏLPyÞ“æ ¿?(ε~±ó»nxðæ!G7kÎ…á&çVçmÜ ­ÄK‡ØÏwÙ ƒÐ}¹êaŸ›«®o¬dŸ|¯^×µréKѳ®’sdCÕ±€AÏñã¸m´¶bH/6λÁ».ƒ;ãzðö¹£Æù6F g ÿÍWøm»M0y(ßÖÁÁKæ:<SrÿèÕ�µí³ÖÔäû¸=æFíÊLæ�sFe»šÐÜåXa°¶°»/Ääw;hˆxxHF­±¡�]þ“n&ý°8¹rB2nlúûÚîwF1OlT°i‘’w,UFýâí;ÞøÝ·Oû”O’O=6å¤�'5�×µÂtY2õÎvFsä�GïyöÙÛÏÿü/ݾþõßtû?ÞüæÛ{߯oîÔ_sâ�8avê>’SØ?9ÏÐ�9Îzˆœó¹óÍ ïù7£|ß!#¢õæÒa¶Á´Ï ¨xh´Ý9艊#ˆ NÒuc $ O6Yü.½Ï¨ßÄûÈf†Àl»>SŸsbÙdí±F¦mZ¼±†òNÄ—ø•Ùh!Ÿä~ýåœ×äpâš,r¼ÏÛ¶IÌ‘çbLãc0ÓrÇÔ/©ñO‚}ÝTßPø| °çýÓ`Št�¤š9ÙüÁ’•£NLÁÊ˜Ž“{sXxÒá>‰×6Úùñ¦²¸R«<õ´¾¹VØÏ?÷,NÜŸuù¡új}ñÎpûŸÇ—ï|¸tŸòùAÆÊÇ :€æ<®dF˜µ_Õ}P�1ëàýÝÍw¼óŸÜ¾åÛÞtûkßòÍZ‡:wtïˆk2sžû!ÿâ°™Cè�Mtø0ç9¯ÒVÏÿf©ãuí¸ÃŠ�a~øgc”ç5;"‡Ü{ëÿRáZI^ò‹ÆÃF²ÉÎà¦Ï|Ä? ×byxÀjE. X† ±²¾C™Š½·Å†¹%Ÿ¹G׺@ÅŠVžziÞó©+|„Gâ·É:õÔ‰í^#ßG8’KÎkæ‹ÍqÇ·sQÛbÓ¯EeéÃwÅ$rHë½§nÅWß³‰ë óec ç‚Ëäah•R†|\ã¢=•Òv ßÕŽqEä X"•\æu�Gß«–Tòd$5½fŒ9þp�|õƒLŠëÜá:T[ò­*9º©ÃÂEìéI~>³Ÿ™^Ã(Yo¼NçÙ¸XVë\DSGâ" Î¥€ó‹'X³´†Òb¼d ûn.k¬úÔ-@„Cò5±Í}…ãšùŠs‡³á{ÿºg]_IRs¢úC>ì÷0#£Eå,N?' ¶,ÂL½’�Y°”D¯F7“g)ΣdkìÀ²Þ}¿ÆC™ áá�[¼ècO°8˜GnÌ#�”û�ê¥2“0>韾²€�DîÆjÛ³c]ÌíSW–‡œcãˆãq8çB·ëB,öâ~ij ,7…›˜ÂmŽÀÍP6ó±ê.w8•…1•»+W=ÈDÚ£§^r|ê$׿k´˜ã™œåAŒß.êÁÔ*;&úáEMï%ÉôÀŠQ½ˆÇèƒØ:Ž‚Xõæz¨ÕÅ1ëqFKüÓvÚgþ67rwÄS;j•Ž9G¯ðœ/çei¯ØæÜ‘˜oçk©ÊÀ;�'¶Ç�ÕLî!„ï>tÆv¿À×OôîâbðÀ¦Û\ú�só¢àåA~³VšL)CÅö•¥¾r8Ƭ�vø-Ö¹Î#«=J´¡Ô\²!Ôw1E¾Ós¬yû�­|pâÒí�ãÑ™2ýäšN=8W´G-Æá˜›ë¹S< Ûn]YG{œœNÕ–Z®°,´­ðÚöés£Æ9îD®éuéá\ jí5Žþ­”yعÇBjq‘öØÑÙz1Ž^®PøWÕú·6 ØLÕ7Y_ ÅÆÐ‡3rתݠÎ6üÀŒ9p_7ty7×_þKÿåísÿíÏö&ØšÚ.û« G�âÝÜß«/cxç;ßå¿=öÆ7~ûímoý5}©Ç˼éà ÉÃŒM=_LJ’¿‹Ì:ê“L|(>Dèç¿Ä6dã¡ œÃ<ÔæÛçó¥ØÈ^ µÝ‚Á þ“HUa€(-‡¨6ù Nt:µ%yëšÚ’þv]ÜÀ‘�0¹e³­vr±gsj×¾L5žW)0ÖkdìásèÛà5‡Ò¢ßñ˜X†çSO3oï•­ò¨¹rdXìÀä5 @oÂÊŽ˜Z¼6±˜›VtR&FuŒ·»ë¼°^ €h*oë¼ÑùýäSz—¢0y`t~…æ|h NøÇC gV‡`¡vô¥#ÕpÞ:Ýø�ó¬±$¾rþÕo|±&yçZ®çÉ%œ²Aü—éï~ƧæíÏÿ¹?}ûø�ÿØÛ3/™m@`®¥0á9Ó¹dm,]b‘ð±zøõ_ëí³ÿØçè��ÏŠK6Ù8'—�§®êÕÆÏ\á_kÀ¶~.…®¹kÙ#ž‰X|Û �yýù¾’ @}‘¾Z“à‘›õDõ)˜'O{.Â? >r�ÞЊÝp¶Os`~öù &eÑ[}ütÍñ‹'¾„ëy>¥SýzƒËÚ$rá¸sqmÇ3Ç!>°Ë+c Ä6óÖñÚ%&?ïH/›©ØœãBÒ;þ­3qs ñpt°5§Iî•#¾ð&;ý¸íÓÕŒ›£Æøâ †À4¶mQGˆ…Fðܽë_8TͶä#›ØÔ×RÁÅ@*Yïèrγè×ï»çÛ+yDR,èwŽågbY<¥†æCN£Zj…lßFÏÂF Ï·| ȾÏÈg=ÄÛiCPSöœ]åŒ6–Ö¶X\ªß:xÄ ~q×/éõYݸ±y‚ æè öòµü «‚5•?Öçi:X ›NVa×¹ýhÈ�ãÏ~ê\x^—z�ËuÒmÒC{;ÀpâfKã‡ÃY.~¨UKÔs(Ãc¯*ŸhÌ3ÙÅ×éÃ6By€Eqÿ|=×Z/–óÅ}�®Ëá™cw´ñ·C5nóÄf¯=ÞL½;wö|@$>lìîÆ4u�»ÉiÝcÙ)¢m¥ç� NòJüÄç{6©çWÌðAß KÎïË1·p§€Å?l.9ôh>úÆ»æ¸x§ïðl.ç .²k¬Åm[IGsøäš#—Ú�¶ ÁN h‚©-³ ‰±áQLä�-ÙÕU JYÆ3�d«?*oÁªa ÙUFßm5^¤áø"Dky³!òA÷lk¼]�ÈrÛv2‘†úÔa¬å²(ÇÀŒq-~‹Óœ839ñ¡¦PèÔõ ]|nõ¨Lßœ…™…fF±ìÊÝ5&æÉC™ÀÏ–¡¬I\í[›—¹‡†�&Ô•ðƒÁ„Ù8�Qóå|Ô~æ_C,“(™³Ç³õ&~��Ûƒ gÀ0‹ý©„¦¥£#®Zt6A¼lÞ?©ã× `Z©fÜó;1áä 0UœÓ¹‰1i/?£›qªñ¦lŽÉo´çÌ·9N gx†£´Ä±óÁôW×í±¯MªúM!6�×&ËX5C¦8ìU2ºtQ—0&(Ì!ò•4Pò8£Y~PcÓá@�µ…CÄÝ̧k»RNx`ÉัAd•€¥b¾n¸;¨Ù÷èï8Èw9•Åi\,8Ðÿο;Õ‘ùt|ȧ£=Ÿ<¿ƒ‡ÎÎÇÒœ†…¦šØù:ìѬ�ö³âPyQ\œ^ç=�Í;>[*kßC3^Ô0‘†ÝqØ~‹å¸æ£Ý#ñí6ß(ëødÁOKlÕÇ™ÿõš$àÇþeàõ‚é6w;:Ñ×øò—£Ì˜›øðëÙ�˾Jxt"ŽÜ>> ¹ÖyU>‰ájëx,’j6Ù\a#úÙp”� ÿl%çÁÜèƒSLjÖ.ðz¼kÎüçzíÍ1´9É™‹ã!üðKîÅ&þ¡3yyòÉÄ®™�;'¾ÎÀâv{îùço?öw~DÿôöQõ‘·/ý’/½}æg|ÊíU¯Òǃyp‡"ŠTÔ¥<2X<Øž'¤£<ö‰ùùE€ä�ÆòŸ†ÿÙ×iã\OÌ@Ûv]£±™Dìg­À—Í.Ö`7™Ï¬™ä/íÌ�Ûæ¢C‹šÑ‘@xÍ�,L´š–K%œ‘²ϾՑÊÑ¡ÝwÉÖ%šŒç— õßÁ�f}∟\ÓäTmJyã¯ÖܲCO€,/|–o|£m0RÀš–Cc9ñ+§>ˆÍçs¡…=vÔ›Ûæk�Òv~É·‡†‹y �nb`4ÌÉUË5GÈ3œšä:¹ãº®¼Mp�ƒ‡�W\,öØ¡iB> áágu<�ŒgíÌ„YTõ·°Šu²YÄkÞy\œJ�øÈ|œ›Ä+>a.üÂl—¶—ï T{‘e>0 —)‰s¥ÒBÆ"OþÃ+¾F¿Ž�?éKLÚÕLmÿ;®�,]iàcLOs�y½HV.×ñèפq™‚…†>ÀB§ó†çæ¼46Ÿýåkqň²A@ßøé˜ôÃq˜Ç¡o¯…5º+f‡3 �öŠg®½ÎƒÝ'Ö� ]XoÂñu@õÄ0•4È“nÒF°ð‡csX?èS8z>±›âùSù²“¦-½Že>ËçôëÛ¤ ¸ñˆå\w 3jõ6ŒR%4ΉY@„• tÍѽK¾$ hvÜA:JkÇ2œÑ»–æÎÒáYz¶Í€Žpá8e«/»5vçÃy“Uýøš>:Årí@Q!¯j>™Àfb2”£xiõMêÐ1¨XДºÛJInú¨¢Ñš6þ½ˆŽ‹Òº #�’ ½pËÑ^„÷â‘ šöIÃ�¢Z{á´gv6€&Aç˜\mÍÅ]>��¡;Ì�ƒžÊõ¨æ“iǵ𢉭ÇmŸ‰6+ÌPµ“klbG=.=ŠŽý3n ®�Æ^aãõãH›ÖQ&gà�ÒÖÕðÞv÷8í—ú”@šµ1-äP(ù.6×9�’1Fª@¯ØÜ êÊSÚêË1~Ì÷ or¤}xÑX$kÍõ7/Œåˆê&Çyº›!D㪳♆]Ð7wÑÍÝæ&ÐVTÛK=>–Pä:>ãÕ7ß#?}G ñûÆãú\ÔÄi(Ûò þàV|àWX…f;çZ€æ2Â̧†.ª°æªwæØNëq(X´º0 0”V:¯Žq5–Ÿørèl›YÁO¤«›Cäû·Ÿq¶P„±T*¥*7�Ž_”éÛ7¼‹ÇK¨Ê1ÙÇ—˜ÓO.‰sŠ´w¼‘g><@*U”OîèiY°×òÙg(¾&ôÇÞÆxLlCF°¤tÎmKr˜Qç¾—0­íLÍĉò(%Fºá‡Î£µ¤v/ £€†�çøÀÐàV‹¦q7fÃ�¼$¯ð fsjŽz§ö»•ÕkäSÚ„û¢/ü·—ë]EXPŒ³z?£VXM70„úÔÄÈ7ˆ¾ë]ï¾ýÄß}óí[¾å[ooùÅ_¸=¡Í½éE9œ zØÑ;a:O\ÿÒ±ÊÍ•¯[tTœ1£¶UœfÍgí£¸ò‡§!둸bcziÒ=Çà0<üX,`3…ñË=_=üp&~ÑØ‰o¤«]g^ä~*èösçŸØ Ï614ÿz4,°ç‡ø›Ÿx™£|åA®BÈ?ŒÓ—Zq¤hÝ�#eæÂU|ƒpœ‰…#}SÁKç¿kYÇ@SpÃu±ððɸ¸�®•Ñ{‰nÐ}5GTsGIQbã²mÍWë.xè[UZjpÕm+¡dàºá]Ã×DÁ ¶èñ�OŸÿœ ØÙïðáìÐ Êjñ€¡O"èèÿê¯þêík¾ækn¯ø¯Ð·áís?÷ß¼ý®ßõ·§õwÇt¨ªq”rKŒò5B$lžÆÖ€9KîÍКã×\ëš" ÿ §o~ãÒ÷\óüÏp¼É¥leØ¼Ž st›µ4ë8ó‡¼r“†É©s>›Œ¢ÅµÂqâtÈÔ‡iI[sšë1šìðM™*íé\p<}ûC.ª8Sȯdœ÷ò•xñƒ:c„2zãßÃÈ$´=ê*É 1µT)m½¶ãÃ÷æ0]Ž IDATu7xmé5¡Ìуq*4Ç„¨’¶\»q´zÜJ¦gLË^ ñMænoÈcyô³Ve�|ÆÏÂÑYîºë9ú™pùOÉz1VÝ!Þã§y�u‡Jƒ8ù°|�Ñ"òHÉ/¶–…ú欺óÍEß¹~7öûh_ æ e�:dÆ„7|ÈçÊã…–•­�è¡y0§]»Öè¬6<“×’b¡Ô?ír†È2#†‰{.!+/‹î1Ðÿbà«íÆeÔÑ +áz (ìbŒÍÆ�—¥e¿êátJæ ¼Š5÷ó¢Òùô T6¼ï5âqºVƒ~ä¦ è ÇÆ| y”¾±É'>æ8 MÒ¾ÚÑç¨ÒJ·ü¨ñ•q§iÙà1_rTëÌ݉M粺œ÷”Æë2î#=6ÜE¸÷Æ?ÿ¢iì÷œ%—è´Ð*>LöH4‚'ù`Y >9°1’ÃrÂAæ4É.¯W‡×±³ÕÒ�?sIÓÇr£ã8ÕCpÑ­ ô§`ãûþ»ÀЩÈú`6Fµ‘ùÃâV< œßB´wW£QŠ™NSr'.] •Â&³H8�öN+äLšµ>“VÌŽ�«Tµ¯ÿQJÕÎ\ˆÐý¤Cþ×Ûl`™¸Cý¾ØŸŽž¬;ƶ(Û¾>ãí�ss<™;uÐè4Y{:p™ÒÜÛ“åjÍ`ôXXÕŸLn×ǘÀŒ?öÕ¡«‹š1ˆS:ÆU;¹‹ìämbs°Îð<íÐw¿ë}°ÇÎx§ïeµjª”(T\|ÝÄÐMêwèÛ¦žºÙÅÃlìkÛqçA3à€+ç‚5¦˜ÖÍ_9(6‹¯1¤£Î…ÕF—l{.‚�ñÁ« öت]iÉ÷â‹:ƒ+£jºD¶ô*¦¾`s^„†¬_Ý;=ìš—b ýP(4xŘÚù¯²d�‰a·ÝÐÁ¯ft¦Üq£¸ò0*ôžô×»>‹ûœ:2ç�®“Gðz�´¯á@ì6ƒ£±-±,ó!ÆJ:ö$¼}�aþІ})¦<œiÀ·fóÉàHk>‡Qˆ.£bìl2ÈVBm9ØÎs%ž¯|Õ«o|Ä}8#ÖŽu€Îȃ¯›3¶xIü>}´í­o}ûí¿ûÞ¸}盾C7oú¦S½V±Ù—ä[©©ü�9ÎÈ•ÿK FÆv9¼Ù÷ñ�1褘ÍŠÌ/$³f:4cb5ñ–L¨ï¶jòrÎ#ªF±/ü/ù£C|è\ôÔÙ2�ƒøÚ¾‡’Ñ;† 7ÁÛkÔsÈÀöâ¶EˆU·¬×ÜÂaЂ/mý3¶ùL'æèbùA\ã;�iÛçÄX®¶I kCÿfè[.·§8un¸Ö©TÜ6r:êïÂêÆ6>ø¿æ }É=Óð&xu�!ŽÔˆÌ¥ÿ�¯·Úv½Êú®ìwdïdg0!ÈG´¢¢2H"ÒTª0µ–�š„�V)4¨!€Šu;ú_É hI'!H˜a?ª-N«C•Dg:µƒ)`q@Q,Qa“ýÕãwë8Ïó~ÞÏ÷y®ó<×:ֱ޵®ë¾Ÿû¾ž�W¿‘f¡�ÔÜD„râøç×áÚè#éæš�œP8‡›€¬mµ>òX�=hÅÒo~eK ÝäïY>t=ýôÓ×;ßõm×»¾ý�×oùÍŸî_~ík>úzL?Ñ+Zséèøè›ô;ŠC£{ot ûïŽz#žýSy¶+ýˆ&ž=’éÓ”+±\2P¯ô[çvPZב|ÒöDAé�뱌lñŽ_<ܼtÓ·Ã×[}ö§¬èi´\7Ñ+¶\ä�Í_£½M¦M"ÃåQ5ÚLèá ,º%‚ë€ R ÈEGä‰&Ì6>`Íl¸çñFy=Þ¼+M8R_X¬bü™È§Uc�Ygt3GMëñcœ•;‹å7enØú¦Îpoتïû¼¸S©Á\T\òh,÷êÕò—ûvn?¸¨¸&Øçó¶|žáÐ'“÷b;J0܇áäÍÿ Ï ëk Ï"0 ç ý© ‡o†r¶?qf”ÑuÀ½®“Ä•b?ޱG{ú�þÚÊ™õ±CKúS¼­Î¥šìG«�$ÑÞç ]cÕ¾˜}žÈ9Ü#Ðõ#‹Që$�>Ç›4½âhF ñ³�©ç‡‹Ng?‡#Øco˜Ä�ÖÍÍzëßv ¾f²PÜöÝ”£�=õwFƒ†±¼vЂµGcdiÆi×úÂ)ôÄyßšÜP¹˜•�n‡hN2�ÆÚ¬ Nz’èˆè(°Û€l˜X{ÏZü]k3{‡˜¢œÄ�Õ9JM¾p–«¸-aY,ŽºË+‡MŒÑPü¾€åtEØe\Ðál,(êûá†Èœå.Ç®™°£�Fc!NŸÊ-Á¡¢‘sºgÀ ïZëA3,æˆFr¥.öáîECrñ,®[ÞÚÙXtZu¶8³Ì¦õ3ƵÕNÊKwk^:ÐÚ«ã¦t žr•Ûal� E0IG¥$†~ãЧSÍr:ÞzÒƒrÁW¡åò|ä#ê4ƒIOduΤžAãk`MŠu™ff gíÞûM+ Ç ˜G�S�™eÕÔÇ d<4NèêâÒqÝdϪÅÞh] �y¢L4vû†[�èΑQ’˜í<9´0WŠ�Ñΰ-Üähý㟈ÈKn0©Lt6×âarDÉË537 ‰OÍäßJ :ón‚ÁˆÅ¡ôùÑšÙ&Ã!žΟè¡=ËÎ}E™|Ô¹{²µ„;bY›GÛÄ)d·k³31H¨N‚ìÇh÷Ö  |P;Ì>K¿¸®\Ñ6Äh.ÓE°I�k¤{ÝÌ€3'GLNGŸp7®éÀQër¸f¿ø³†]OåÂ]™øH±Ðöéàä™Ö¯$¾J?‘ô_ÿ®/¸Þþu_w}ÌG¿Öo°yO‘Ç·n«èk‘Ï \“sšÔIøø 8Þ2ˆ©,í¥o°6ʘáåçM{[åðÕæ\[åv=Ãå>o<‚MÃY;7³ôÊ9 ·Ï–›3èRD»=¡‹ÏD�C�ÆF·³­øž«³ãª †åYîäq®$ð¹ ÏAs$ð�*¹>Т­ÏÅ8z~Ì/ˆ÷ t õC„�4R›Ô®¥¶Zã7Ò%úÍ,^ÅÃÍ_Ó²åf0n.åb& Ÿæ÷ÑtâˆÅ9ySd=â  lš|0ŠÓ†µ¿9eA‡ord¢šøV,¯?É‘^¹0sG»¾¯¿[JúüŠW¾âú“ÿýŸºþð×¼õúåûý nj¤2/¥ôvfç:ÕÈ>:­~ xø\Î�Fóq†ÊÁ¬O&´·¶Î›¼ùKH g‰/«á§Ÿ¶÷°w®Af§õI™œ�›¦\«0Ù-»ÙK¡}úÌ<ߤ#Vîð+bÕBà¼ÊºõQƒý‚�íá!ŽOŽáX¿&ž$ñÍõ�uKþDö'ßVGq½…;Ù£ 75«- |¼946úF¿óvțǕ�I'¹Á%§Uk÷…”›’-k×~Óâzí´Ù¼ ÛÉ üfŒ}Ùî^?Ëá¼[¿}Ñ×ùÙØIê`Ö`*„ù\Ã9”ÍÒ‚mÍ‹_îÚÎh÷ ]6ÖSNftgÈ[rUO)˜‘M¹~ȳÊ�Uû“og§óÁ+³cË‹}R·&+.;¶öº~çÃ9qž çü)ЩpfØÆÖ&ü¬9��ß{ù;;÷ì5)ÔÁö[âY8éÊÅRkðpfcZSDEôͰn,I¹|éCÕu`š|N¨}ûáž�Ö›š‡[1[[œ¶›YìSËÉqÚÈç /kj÷×PV7�Pç+k=žuC]¤{R·¹ñ14U¿u4¦ñ‚D¯ ¨Fãé5–O„d„½6ãl•Q¾öÀû±­óQ¸Œ;g\æ¶—õ\ï=wc�ã_xìǦkÍðšqîå°6u2qXµÓLõ·Ÿ&÷͹¨á>hæ‡ M’|wXƒ0ç !±> hI¢œ˜p‚õç4}h­»ø“>y¼¾1³Õƒ_س„V±‹}x˜(“‹×çB«+ƒa‡ï˧7GÆ,R“ßdÞã:œ(}$ÇæÁÁá ÌßY¿…IƒÏ�8�¶†Õj:øìͪ©&f_<, ѧ͜ڣ÷Rë“DÐ\§=3cñÈt×ìÑ‚Ÿ‘ë,6öν(YD‘�ÚâO,«® tR^ÂuŽæ³^‘Uwì2ÔæDgä-ŸÏ™§nⳆ€ûðÝ%<` �átâ Oâ ·m¾[á‹ óáȶÞ8kšH“ ж±O»ÝÖë±Äw檑™OÇcÏ ÔºÍ±'WÀºí-=R·Ð@}ƒó¯³°Cƒ‰³Þ‚†W~Ç …am£„ÀŸ76A ~4ÆFâêcI°æd˜˜œÿ�¨ L£uÔ5ÖL� Ÿ'ÄÕóÜ]\û'Ýô¬CÎ[9ɽ‡üK¿¬ÞRýŠœé÷Ž‚Ãa g®£?°Å·´)fK˜óiÃ$Lè–•píYhŒ°µŸ¼®ßijtö‰ãowu$6ù¢+ž<.HÑ\±›V¦I­ÝЙ®Á¦oÕ¶¹á›žjIŒ¹¼>xAÉÝðeoC¶çrY¢køk]bÇ@Î0#ÅŸþU”º™Ó÷ÐfíÛö†úæΔä:øO ^þò'¯7üǯ¿~ý'~ëõ£?úÏ®oùsïºþ·ø~s£_hô9ìU}å1íD䙕ft²‹‰½Zt¯­¾˜à5Ñ×ÿ ü~-CdåŠa�µ¹ÇŒ]ç¦9t�Öøü»‡h:cµž/¿£“øÔ½2Ê”ª –5rWžÜP2ÈÎvˆ²Hå=qŒÎå�)ýÁQ'@Fzp׈6pþàyd¾“Üœ:è#yã ¶…Ÿx爙�ŽöÆvŒvg‹œo�í9ìõÉõà 1t2¸Ùןœ³�8½HfÐ'û„E !®uxÛOrù·4ˆ]}ȹ‚¢ê€ [{v¿]ø;C´Ž)7uY�qʽnVùÇ §‹ùûB¾™ \IyÞú¤×½îú}_òÅ×ôË_{=ñÄ‹ý+ÂЬZÎÜÁÙv‚î¬��‰^W¨µã°tìÙä¼j��<úðO×ÏãÅçÊaéÛ"—�A/ü'´n^ÏÊ� A¥ß€ÈEþY“P“ãt(–ž ì¬=ç-]ãù�=ÿ°ødgó�'$¾2µ\=Á>qáeϹdŽ´ùU˜xgµ²æ:gúæª[æôxL ñA¦ïJ?k>=œº¹æœØMöaö£u¢ED}ìêW>s³o’Ó�õ®=ûô„x®�è4_[e êˆeé´a,=Ž×µ…öëú[:«‰ØrÞj>ûÏÆåÚëäH½·˶¾À»?~ÝŽžÑkEðd´v½&šß×âÉmå!•Oºk°n/Ÿ5M¿vïœâ¥§7ã4øµP˜ÀìþNÄMìàÄ%ºçyÈ5¢ˆ�yÎÐ*¡ýˆò䚯à ãþUìä>¹ÛKCškéîcctþ»ZVŠ£'7Z‰éé²vòȆË5ØŸœ8ÜÀQ›ð{Y„pnÝôoÕ»ƒVÚÃå*7ó5²:p¹Òàgnî!蹨þžÏq§ÎÉaåâa8NvsbÓÇÀì¿É“�kRoY¹‰�˜õ¯=“Ò1Í=Æä–½<­ÑtP3aÎ9üà‚)çävŒ]ÑÈ~°­ dôóÍÇ�mM-Ù'fûˆdÌ1vûU]5¬è“ºG�^3ùQšéÏÙ r>nNQv ˜ ì�êË%.Ã|t0Á`L7"Ì–pÍDãZP�)v´fŒÛY¬pÄ´Çtƒva²”4Û`ê3»ì<9�áEÏ ÇiÛÆ[7ä|ì”obÈ¡õìR«¸|ÒKzÎ#´x(«íŒÉûWÕ%Àò»ó‰l|©‹©~zÆœ®fr2|¹w[®\'ô\à©Ó=ŸÚÝ#| Ÿ)õ;€ ¸äÄ_›·:Øç):¦¶âª�Xf%!5¹Ì<¾Æð¢µo*V­ë¤%ž'¿å«&ó†Ì\�™œN׃lÔÔÚÁ/­Nu±smúåc£=“v²)v®ßá쯸®ëO›_¹È!‚ýkì™z¦&×IÑlýÓÃÚgn°sŸ|‡-•5»—©ÓùJÄ<­Áµë$¦;‰kpõóðæú“-¯}M ±ó‹Ï×…`�Ó¨�ßÔl­'yáõj½@%Ë`¶:ñÍÀ1ûh©ƒG#‡™ávׄ:gÅLúxÁ Ǫ¥XbKÝáRÇr�M#ñ¬Ü?»ÝuLVh{V¶%·—xI zîŽäsî-* UKê_úÕZ¿k%¸×S‰zÝd_¿ê˜ŽWþjç|Ø×z‡_ûeWz+@7^œãÐØ=Ë>¶Y ƯúÜk]Š�‚1»í¡Ó‘sº°!AË?h~‚Ühå™5 [.ý¯žý_íÍr»ÍynÀ0R4u@³px>Ô?® þÝS^úÒ'®�ÿø�»¾îëþäõ“?õ/¯ïü®ï¹Þ÷¾¿,(ϯüï§Éß~Áà·ÍâFc~RõxîSÒõ|Μ–kpŽzî{ÎÑéO�/TÙ0®H›),> Ѿ?ùf>ãh°‰×u)ÍŒœÏ¬½G“þÑ—›14Ø#ʼ±cOtD£5™ÉVVår\ ¶9Ó �Ec&Ìå´â5Çhp*°õ4Ư`Hä¾ý`]÷ºÎ±Ñ3°ýú‡M£ç£1ÆDuR B�q³_1º¾úæ ¿ëá37 ½†�ž(&7�¹ÊR«ä˜~P%1Äùጽ¡†<ú4/Ú'¤sã3ÃÊ×5@¬'^3¯3ø|Vÿg9ƒAs¾>þØ×ç}þç_oúíŸy½êU¿äzT¿ê››s¦ò¡šÑ³†5ÅÃㆻOLÁ‡mÂ"W~3(Öõús>!¯ßLh �>‹ež€œCÛœhl“ßý;ܘ£'àœÿ€�c F#Ö¾žñy�Za¼žÃo)ÆË¨ÙÜ^æ<Æ‚öN60(ÌæTT²îÞ)#+½7íš<àNR´ÀM›¯Ñ¹nóÐÊã$=I\µ7�©´ñcÖÎÑ·R&.°9_Á4vûÊ,»EsS·ò¬°—|…·ç0­<}©›Åäõx¾ˆÄöên¿N-“Ã�5«e®º�=µ‹Ã.éσ~1PgpG ¯ð½Ãʱ•pš¸1ØPï´ú’üøñ�#×�ó+EŸƒé…cüü^q2äù¬ñë]º <¦¤ù§K!�í‘Ñœ¯¿û±þÛÝžìœ^Ñ—‚ÐÁ³WθT‘’š‡- §ÑÚX‡†FÇ\C€LèXv+F®›Ì™ ªç.™Ÿ¼Ðkÿä­Ï3ýÖêG^zã2Vlx]‰sﶦ®¾g,"i�˜ô–áÀcã´®a×-Ño<“M…Šwމ+>½…GŸSâ³�cÈ�=¤lØf�{¨6ÈlÌ�OÿȽújËq½�ø`Çäéð»sn)«®ÉžB6¡%»ÎØà,O-h›”.Ñçu¾y•¯iòN­›yL}=àD§÷X+úNnÙ-¿6SŸsè| ×®;y WœûL�õܵ0Êa~RkÝߎˆ˜9GDޏvúñ¿o2%C|d’†:�vf.$ ÐàW ̦ ™oþ†žÜ~13TNZ>âGocÈa3?©‹^&˜ñ¸iÚtï•¶/¡ml÷ž…3Wk2g/8îð§ÞÔD�hlŠòÆâìI1½ÀëDL]€ð•Ûó\Àû»‡gó%^I’gtVí¡©$ß9ÀÊÀ@ýž§¼»Øb`mÍÆè`¦3Î6¸çÚI&â¸Ñå¸Ñ`0¹†Ü§ÁŽ�UcµkŽȦ—æÕn®'â·çÉh‚o~Ç»ŽÕ4†3ÿÒ%ñõ�v‡©ÕÁ9æOka<ÎYû\�æ™ë9ú°ÎYDZ�ê\¬;�Ñä%ÿþIžÆÈÊ\æë´Ö�tÒä­û,w6,ô¹G;ì'Þõ@=´ ñÖ_¡ôÂGX¾ðî‡KÊ�<­Õ31ã6Wùeu´üî+;t7±cr�’s©£7”³–¸î+@ôÆwúYk9›Û³¸L'ÈŠ•!µÕƒÓ$V* úˤm}‹s�ö ¥pͬɷôOÓ9Rj�£Ÿì dÎÀã3°l,d�#³7°¦0°Ö1“÷çù¨9zåö‚ùŒÑÞ£�ËìVŒHàñÞ1¨‹Ö�ë®fç6:\D:Ö‘X¨gÝ\cËvÍ[±Ù¸ï1-RsUoçôD7üBøÛa, I©K8ÙœrÂ\‰Ö77|ÀÍsÅc�=z½úc>òúÊ?øe×ïþ¯¾àú¾¿ó÷®w¾ó]×Oÿ«¡¿¨_2Ðã3oÜu3DÌþiY%뛜~sFÞ4õ�`ŸãH´^\+_Õ®ó€_Zžkº>ÊvMäµ­çirÆØ aÐ`eômêèÐùìÖ‹B¹º`­Í8¤œN79û|9ñ¸á"W~Ê8µb÷*iŒ¶?/"‰by»VLôfÂØ­QÍÕÛþ¯ë§¹ ®\¢!_bʄ˭¿˜í�}óËPˆ §çC:ôMÃw·¹!¸Fa„QkªÐ4kŒp‡@&#£„écãk7}¡ õF!UKcϵmˆÝ“_#Œ|<^¸!ø¼þã�—<ù²ë«ßöÖë Ÿòúë©§ž¼ïýE R¬ðÈgûrηÞi÷ ɺñøÜñúBÃ=�]ú°o2®)%ÉOì\_Í#ë<ž�7 Ħ/,yl‰éü5!¹å£–2 +½Œ¶’SO›QQ l|ckš(j�ìèApí£k50ù£#ô¹iÔxÈsŽs>÷õê:&7|Öá×h“sä Ã}Œ¼¡³¹žnfFËð "� —9�¯{YfYýg<.w�ür �óOÝsžCcÃh‰Åýže¸ƒáŒ¤+7�µ¬Æ§–l�¾…ƒý¾6gk�Z£sÒj—œ†héÝ:LàL>�œ4 êý©Ïh³v÷$ÁÔÈëâUžàÉÑA¬w}1`Ó'“æ\+½�•}|“G‰«Ý=‰�IÿÚ#?œoêÐzé9q“;y‰ ÓЮ\ì÷ŸK’ÜŽÔíèÉ~ß‚öL®�ƒÅ’‡®t¸q廃aÛ/å†édóZäy£q­k;fCg¿Ì7ƪQÿ0¹ON Ér›Ó�â&Žøö¤}ˆV€To„1¶¸ÀØìg©�¹Ôže°.4Z“ž—¸I37ô�Ë‘›ËÛ;‡Ö-Ê!.¿‰0OêÇÇÈOi‹íæÈWê ›Ò^õ)úŽz4O=£½P—?ùè[j$÷BtŽP–/ Ÿú&˜©MT@øe‹@7@%õ�¿Çã<éë"1ž”;Oxqø¼O_vb„Ž`óæ�ë€u¸÷u17… #6[—-pO³Ìá�#(ôÖË9A£åìzÙÈĬs£ÁïìHÛfyNÖvRÈà×® ¯œãgBg.ÛÉÿÈÃ÷®W¾âîÏÿÜϾ~Ûþi×ÿ£ÿóúú?ýŽëŸýØû¯ñ¿ë)“XÎ oœ™óÓ»�Ú©4\ÃÉésGŠÉÍ-ÄþÚ!LôC�£‡ôUþU1º›Ã&ƒu˜°r®ë#…¬p4ÆÀc”^T4^Û­ƒ|hö,¬¿; €HÏ—(xeÃ\ Þ*ÃÒܽ•L^S‡R‡„ÖÑ:ñÎE>WJ|Þ³´•çHóùcs]"Š&Ûêã’sÔŸÊk¾œG¢h˜×"SOürµ~zê硤‰VÛÐa2¿¶_ïWF<èË`¡j?%¢bÙÀõ§ŠzÞ€[®Åšaļ†Ìº9ð6ÿªÍ2ÀÉ7‡}ó/—�Åð{y"#ÇmNþìSW¿öo «Äñ\‡Ý�QñèÍg-D²/gopsÕåzJLØ£…ë+ç…èŒò“<`·ºˆÝƒçAäzÃWüÌ5-Ñõ8QZÂëj{rˆc°_±1%Gâ·+¼½F\Är–lâ þŽ÷2ãë&�‹u½Ld¤åœmƒX9_‘Ãæ6�4-¬3ä|òÔ„\÷_öJ[%ˆÆjŒ¿ Àêi01 6|'¿•8&€(»Å/�ˆNžKÜÅ7ÎTΗk/í°µé³4Ô*n^+£›k`ùîÔ”\ÑeP¸n¶Ï G®ieït`¦�•ÇŽÄ׿XN‚ðdõù8x±Z«Î53C¨ r¶ôÜÖ±z6:Í%ÇyŠs‘Ë­x’žõ¬µ$ÿÁ9*3µO˯¯9i¬°õÉT^Íîí�÷FÍKœ£ÅË9m:ºœœl±M¶¬ˆ‘¿ù˜}Næ5)1ίÈÀ†amÔh†!Z—~o Æ*ÿepã6ð$É:YT³„CâYGŸ¯Ñ‘u<ÆŒÝ!†Àÿ ðNX*üd`ß™( ìúÌI~Ö2¯ƒ*61çÀ}7ó¶CÌ# ý²ÌÞ g]�às“ä$Î37{qFõà!åõˆ†Û91ô%7äú@f€)3t6Y‡¹7ÎÑØÜ£r Òž�}ây¼µúusO,}àÿ ´–ß&ù¼¨±øùBá²Ô $ÛAÛ姞łpN¬q¤ºx#§÷€[#uóB�t §õ7}òõúOú„ëÿÑß üæoþ¶ëûÿþß½zX_žç' €ê› z|øfr”ؽp qõ1,ÎÚy|“ýôœÁ׿QxHŒÖŠu@ø¹ù÷|æs~ PÍÞF¬Î?Ï)6¸¼^ì×Úr}‰£çÆ9L<1vGG,ÀEHÉW#+µÉzIHÎåÔºFH}ø�µž] 0cCÉMI„Ý6C—©ûÄ͹·�G^hÛš—['8_ûGCE8i±/>ùÇè‚ œ;3ñ๹¤Ûk:¯º”ø_aëó“§ðÜÌ"�SPO’š«½&,œs3Úå8_t ‘Yë<ãç¦^ìÌ\ËêúCù³Ú¾Q©½µËËéxã?Gÿ�Îï¸>âU¯Ô¯ù><7ݨQþ#Üý¦&¡öi²^×äÍMŒ1'‡ÖÖ85úë"jZ³$'¼$aæ×•é©jqžœûœƒàÁ±¯ /Ê5D뜙”Œ,è ']ìÓO|©·¡øÒï°D2ÇhÉ7ø‡ß\S—)ç&hó2«Çƒ“O&V€˜}ηÛ6Ì}ë ±i¡ùƒ;ø‰¡7ó¸ÝyážJNÍÐ#4ºW6èp$mÛVçxãágeqŽ“ÿì7�×lÜæX«BÆà<¶¥Ž³.맃TÏŠpmN‡$[rÍs°€¿;Üh겉4qñ� ô¥=‘Ý=ÖáÓ{‚îò¦\�‡!Áò@’á¯KZözÚóÀ‚š±PI£è6 S‡kŸQqûX‰ƒ]± Nä`g³¨µïcæ–ÛD-;"8 tžŸ^›Uí ”;Ã:L¥C‹›ä 8-ûÚ ¢|¸Íƒyâ}Í@<{GŒ®æ…^>·ÆpCøªExóštrA<øȊnE4¾œäuÇì‰éœ‘n,áŸç6;·ÀGÍÞhïúè‡zºyLy/˚õ(fáº�oŸ·Öã*çæ›õMŸ×ºý’¡ýKg´lg‹[õ¢K� ™Æ®slG<¸Å»°©×ñšC‡òyßóïþ2ˆäæõ‘uƒ“ ž �™Üë›YúÏóçÝŒbŒmì×ÁÛ©³˜ø|tœæ¦^e¼ãh˜:™ðw ›-s~t'´9'A­{cwƒ¥07…IŽhÃÉá3C0B¢’ nFUA4ÆB ñ|ŠpÌÈî á WÈšçÔi¨ü÷Ùp4Og¨0Ÿu#åð…ö“Ô>0ã3ÏøÈã‹Gsý��Ÿù¨Å±oL¾-cÝö"$Z¡ ÊÞÚ²õ±*’ ÍJ¦˜—<²BÞ=ØŽQlÖN� úÞ~ÍìüNÆ HòrnT‹_„¹Çïºä*Ÿ³�Ã\Ã#>p77àˆÑ?>ÌNf4¯†(>¨B¼Ë c™ˆŽq깄Ž`'º3ñ #ÿŠ‹ŽÖQ�c†hH­�H^�ûïxáçóà4¥WÉ[NSŠ-±MrÐ;¶îÑ�8ûÇ5!í…yˆäcå5“�ù©�ö+ô€È�¾&¨Ùh#ÖÊF�OÐ1¤©nñ%V†‘R wX܇›^($�É(r;à–.`ò×NÊÆœ±úl�Κe冈Ü@p›²æ;lð'Éô¹q{ÞuH,¯ ˆ™óÚð›2F|Ï¡+¥[Àá2Õñ˜œ¯Aàh“X97åw݃Yý\£‰˜þhösp¯ÑÛœåBú´#Ý5ñpɇ?N&µ%O®7ÖŒS;º—FóЧŒØÃI N éÚŠ‘•�—0ë= ó(›P®m=†ÍÁOöE‘²3lJžµ·žå Øàz­³í5ÈÍ?h¹!Õ<÷øÏPàbhvxv;íøŠ+ܰnKî35/õ¶ÈxOšø;�¿æãÅõö·ÿ©ë§ôwßó�ß}½÷;Þ�ç6xüµ!¼º/¨¡ŸÔ�<~jŠ›„ÎÓk=0Eï‹#ç Œ?í—SÉÝwÅ�ãz›Ö-œ5ËžÉC-þiæðçÆ!¤S!ÔÎo)Š©‘8¸²GCÎupE¡Jû´4œÃ �ÖË�R£ð·Çešs@�yL˜œ‡ææ£úçüPQ¯Á;µ¯áÊ•tIæ:Ñ9±~¤YÜÖ¹µ4©¼Öl, x|àp ÌUÄ2:Ðé±&âìöì7²`uCÎÍfL¾ñËVkpœö�á ‚Ïÿ`:'Ú�ã�´¸EŠ�ªÉJ,¿æûÔSr}Ù—¾íú´ßò†õk¾Ž„ÎÕ?,&a ·f÷«_ÿÄ|p,óØÌ3�½¦§1V7)ž]ÁäÚ��¬ÓÇ Ô¾®çˆëlÙ’Ø&‰ì7ûr‘#2|I³±£=̶ïÈá1 5­ìÈás£X÷Ð<“{Ãï„ã Ù§1}n ûZÞožnÙQ_.ðÑáÈá KŽA¢½â’gi—¾øáJ­ÄMD¨fxغbËžõèK£þ3v`«5GL!í{(ÓÿÖ�cȵ¸¤`è’‘#Õ & X3’�Ë Î2ùÁÏs¤Í‰ŒF­�œí)8gͽ4bw¯!Ú±Õ sèzææ)&>Ž ´h)<ç“z†åxŽæ%‘ÃBî­PqÔ¾óPàaɪühG!<Ä­oRp~È 3vù}cƒ¸ÉÆ„:¾$Æ 1Ù› N?_$�}��$¥ö‡ü|mõqEht5%9‚Ç>×þžÿ|ŽÇ߆Of4ŽŽèœs…$Ù9c`ø×µGrµ½©rëŠ5˜Ûœs.p¡Qÿ��vdÎ%1~ÄÈÚ9zs�| TT|Êiœ–l‚F{`ð6ËKoŠÊÜ-sÄÝÄî}ꮪ†{t,Ìp¸æ»­\ñcO_&@“WÒS{qqàÅ©Oâu¹î”•žÌzÅÍÞa:äÒ#>ŽÄko¦ØLıx­2DK^«ŒW�^MÃ$!\; ¹P’Ö|ÖÜ Y§s–¼å‡Ok>ó.dn�Ö7ìY‘D†á«ìF7Y”1Ý0eïcœ(�ÐÀgyä,y¹QSh'o736™¢ÂMΚK7noó$ZOf÷BK¨n}À̱ˆ‡QùàsÞbÑ ϲk�ȉÚ~lÂ]Ÿ”ñ†ê;¹ç´¹¿»â®°‘z³ÚÇ}aë%óèQâj¨·³5¹Ö#ßàÃ&¾“£krx4¹¨›À|4] HÒU�W*o{.†>¶�i¿Ð±5€Ò˜k<Öô“ÏØÇ¡É«ní�¹]×¾.os.Þ”ÁÜ8Ì�býs±ÂÍlÄäfMÎÆÓxHcÍCç,Ž™ók²^k ŸcMB„Èœ³Nõ‘g’ ÇÚ[Ôr”ß‹làwã ‰�cthá!�~Q4;%HŽ!­NmosŸ/0Û¿UvêAôLæjÈœyÈÕ`­²ãú€œ™µœKaGŒÁuËïïH—~ÅÃÁc�!gÞÝ=Üžc¼·NwYa�†–�½žÛ‡ÊÌù€ëö¼„89ˆ ƒ÷ÆÆ’þâ¯¶Û‚Ü bWŽ�$þö·×:Ì»gŽŽdéÚuàsmåMFÇÈnþÑ–ú”uô×·ìÎëìÆ„plgša±DÞAOìÁð¿^8TF¾žò¹®=¹v(Ñ^/Mž¾‰þh�¿ø±ë5¯þ¨ëkÞö×ßþÿÆõÕ_õÕ×Ëž|J´ú®j�#�7é×"ý·Óäãæ&6ÿ3gˆ­mjõYãOäRçJÝp÷máŠ?øÀ‡Ë²Ë,æj©æŽR YN­sžGä%&óu†™z,s0žL6†áÊM2ÄšäG¯½‰ŠÊ�Fú@�ù˜=Xü©Ã›~âR_‚í?×8çË�£‰”�77ÔàÆÞ$õfNô%™÷œo´ó/JqÞ?â׬ndå“1MœŸ KÞÁÂNž]bã¹t{ ŒäÉOÏp]òÓ®¾Vu³Ýqºnïéï^¾úÕ¯½þì;Þq}ÏûÞ}}î›?ãzÅ/ùÐëÑGÙù¦·P‰ÎV:Ûé—a©A”>ïj‹B[îÌ;\©ï6^_&ÐJX?/@åç¼3D@ôy½­þ•Ö`£¤¥sÌ�u Iz ŸþU‡“‰£t, ôõ`Fí0PŒ>ü¾@¢WÿfÑýy¾&dÂy ¬+á!v™….—VŠqr¬Ž×Ásx°!-¼Í.ŽY9�vƒ6¾•G|ñk¡‘>uh+†|t09²NÜ>&·÷^¦‚3‰§ HAJ0*y|zd?ѲŒð›ƒzîú†ÂSž—f©i´k¾�+Oü'ƒqN1Ïc‹ Ž*ÃXí­mô—ó5ÈÛª‡¹ÿ(Õeæ°XÝwÙÆ|&ѺúwÎp§7i±¿£mck^²‘ßYµÆîcmÚÔ¿ƒ¸�ÂwkkÏmm<„Çf9e{˜¨Ã¸±¹>Ó”KþÅ[[)´ŸkÆÅ�A&8³Üxr6×ö&x¸²G�)ˆ±Oösm˜ ƒ_˜„ß,®�<öäÚõ%¾jÄ‚ºj_:Û·r�N¸ˆOï‡OØò |íÍ_]“ÇQI<ÎŽ“ÛÚ§áÖf LÆ¿¿‘/�õ¹êóqvש¥c›�™¸CgäÁ”|³rXwÕç1bÚcvæ‰Ù¸Û403Áµ¥œ��g…pncYgœ½áÚt,<|“±˜diÜ„›>ÇPó2u;ŸÍïlä'�s‹F\í¡cœ$öbʼq;šõ€1Mº³‡ßí½>qZ¯(­ók\¼Q… V¼h²8À!Y©b—CX;ÒšFôØ0'Ò~YТ€~“€lN�ŸÀæ°4ÿ”Lúà_·VüͺôL}¶k�ûFÓÂÏ/Z‹ 2@J° g=á�8Ç•½(pÝ GÜêYØpxœœN.ö­‘5Ã:Íöü㣜jƒ ÛÒGôhÍMsX–¿{Œ~ƒEÙj™= �”—:­Å¶ÝÇÈæžàƒ¬9º–)±ãîf ƒ ’Íïó�ý·�æMqŠ à¶{&¹ƒZçÁÆb4÷üØ^$ÍÝ|õuæÅø–m±I4÷Ÿê+Hö¥A3eÃþ0t½úaTêidêŽ0{ºX<»Ž&áÍ…û[Ã`WˆìÖl±±¼pt(R}.ggô÷§R(ÕØ`»;¸øbëg ùj«÷vסÍÀ]ʬ£šMq±ÞÚéÛF¦ö‰ Ÿ0‹³\Ì9ç¹~h~s âëëNþ?QÐë0¹»µ—?ù�ÇQàXÌ×åÊ�•ꤾ^¿F¶cr½a²ÐÌÔm|óMMëñ1Ô­mÙ74ü¡kÎ#?•c Å ãL.¨›8Ë{;¿ ŸÀÓO ±ûÜä 5ò\3Ì„¯G×Û ú;Om�óõ`>îÒ¥mv<¦_}üðÿ°ë‹¾àÍ×gæo½þ÷üÇ×7èïþèûÿïëÞ£�éï>=§OŸcñ0»úÊSWþfk®Êu¾È'<޹qÃ>ŒL7—™3¦:¬‘þñù‹ Ç11Aæú ÏA?÷_ÜÀ¸f<˜š¯&áAm—"ò›}ÅLPØÖÑ×$¼4e Í‘[ºèóÒ%&¯nñ,N­Üyzã˜5£½õÔ&<ú]¿l¬19[ñը؅³Í�+Þš;SèÐný;_oøäVN´õõejE¦B&_â‘ge²Ûï‡d³6ëO�;~â4ÝÓc3ßl†_—µ+ÿ3ög~Æg__ü{~çõQùþÏqø)X�ÃÆüÛ\�̹>&ˆ©¾ÎØÆÎùøà3Ïê#¿~,£0žǬAè,�óùáFçÔÚë±b,¯[õ` �ާ@¸Ç7’�˜ü#Ã�O¢ýA¼Œš8€Œ�=7òø›~\ðßI™sfûù ¹\Sƺ–$r~ï¡ iæ$ÁþI˜´ÊKr}.lÓŒ‰À^ž_æ&y›o�·9:‡ÖÞw›#ý÷�Nþôɺ¥‡Ü ŸW Àï…í­+ #C§t¼OIH8�Ÿˆ/G}�×"°íé[öÑGMÚƒ—!»ÎxÀ"d&æ5²×46µ™ÛŽ`Ú‹„ÎszÇläË6~&´¬¶™Û�ÆgEœQž±9¯ƒ.Áq}ðMc.“dWÝ<k—>%«¹M”÷D8î°ð!\ÐÔ‘ëÂÙÀΰñûú�­{»EŸs@-4yrý•…¸©wLÅwÆl†#w‚ê9j1‡ôzÖÁÜÓ·°è¢3ïM®ÉƒþhÍlRˆå·ÏÏo·‡â‡hk×Úý!ûðð€Ct*�"àZk!°ë[s€^0‡îžœçi¯áÙ q�|UTú¬á˜|&ö1ãµ®_—=^H±š=� íêß VïÌ#º;ÎuϾõ[~šó‰š#~i”í�0ý“&dUë$e�ìRWg¹pX ‹ÉÞk%qlçrznÓ–Å?†7\«ÃÑɹfã5…i˜Žñ±o-5®œùÕ™[Íè×M½Úå–8ÄOÂÉãɉN!²"„ÏS¤[ ÃÆo¹m0¾Tƒƒ»mrè…ÖˆvN 1'ž¢££ÖΈíxa†Íø‹ví ˜(X2œDKüâÕóÅáÈäcgnÍÀ¢{6æÎÎu³L.†±â@ÿˆkÕjq“Ï/0°Í‹%E¤~G†Τðžå0§^rSP°³ß9ɡќdˆ¹6O.“szä@ì¹ÙI‚æ0— Š#Òºç”Ãóè� ›xÌáßzà%H£³soìlƒÑqå±%A'o{„DbS Sr9÷ä²Í<ÁùkúÔs•&¾yìƒÃ ¤UÉЕYãNt®ûZÌä7Ïpø¼t u±š·Šä\ºÅcƒÍú ™ëF™6"zô‹�—¯öà kOÐ2µÆ;‰‡ò?4µ†u�ÌXñ÷…jqqÇç>#di¤?¹þSŽcÜ´@ŸØøÝ×�¦¶òÒêKMôx³J"â n8l×úœ{ÞWXbuS£’pψd|ïÀ8‹œ�EN,ô™âï0¹CÃ-ßn”cé3Ìy#æÜö“å�@.&¡§uà!M†0 £Ÿ<ý¶"�ú ž/D Ëœêuƒfge×ü!~%‹‚¬‡`ñùƉ¹”�šd¯NüIéãl&Ãð8‹ƒ‚)?�5ã!�û2ç.¸éoÅÞ»^þò—]Ÿþ›ßpýÆßðë¯û±ÿ÷ú†oøFÿ�À‡yôâ?sÈM«©_ñnšŸÓÍM×—žÑ/÷ŽB¢|f²Ë";ž|ƒ‚Ósð­¥`ûw,‘ìZ„'Êl×AÏìÁ¯sÃzšp?×5 ÙItò…g,«¡“Ø“ "’#gTLd\Ñéà}HÀÂ>ºýnaP§~Ó~®'�þ5Ö ö~ÞØ¼Iž ð�‘j£uú·‡2ðzA¹0¯çí‰ ’«]#c¹¾-ýÒÝÞÑØ›•ô§×·y}FØZ/5Š^ z!¹‰Ø@¸û› ¸íט'^òÒëË¿üË¯Ïø­Ÿv}臾üz¤7â’Ðt‚g±¤2yO¬ÖºÝmÍž õq�þüÏ?}ýÈ?ýQý¥�ç®×}â¯]¹\FƒyE@4cù*s~ª}ŒC’Ýî• ŸÏÐÐy½hé�øšcpéñØíŸH­Û››CçºçÆ7^ åù`ÎWæIì)‰°ßͽís}|¹®<ÎrN Ýƒ ½Ù–¬b°„u2‚…3ös·–<{„Shû–÷Än};Oúboû¾òc՘Ѵ öís�\5×9Ó˜áM¯âÃ|;b \GçÛµ¡£ßÄ%®ç&õE«ÏkjÆç¡9ñ³?&÷ÎÀä³û^€ù á^­�ëͽ™×~=OÄ;F¬6\x‚Èš¢Ð­pï>…ÛýÚñ…‚"Y‡K–ã5é€Ãm²‰µa]ˆB܇¢³7‘‡ï~=dn<&ÛË͵WQ»÷Í´¸Êמ“zõÅrs¦™Â±˜†ÅôÕ¹z2I[‹;·ä �0­Ù´:€s „îYˆV¼«Çu§n¸5œÂú¢›¸jJ.@Ûæ ð1ܯÎCt5Î8á­iÁVq1r²ž×…V¹µM­Ïïyl_Š•Áák¯œC†žúvÖJ@û¿ø¬›˜#´±�q?¢h:Ãp——×…h\玾“e8bŸhrN=gœS.®Áž_üK›õ„Ú¼Ck=³>§ýüY �Ãuƒ›þQ,Y,³ô£1%�,±{Goþa`(ÖßÌžøÖnæ?™4‘GNޱÙtH°"�Œ6~øJ“å=bWSæ›xwsneM6t Ÿ>qwj�¯'‡f¦ª#Ö‘‰õ ^�Ãûä®…ùÆ¢«ÎÌÊ› q#ON0 clÚÝëâ3R6…¤o©cÕh®]Ûò;g{’„:¢˜ê·FÔ¤Ž]iŽLÙÆ:Zm¨‘|ÎNmæ^7÷ø¡nÍ-&/ì›üÅ™›',d)W®*å§sØ<õ‚O®f1—6æ°­Uƒë/®,¦¾ÔSÇÔ($«ž¼ÑGXô­œä�‹ÃŒb»_® 0tΓuîXbÒƒMrçð<ææ/wobQ‰ÁмËI>Í«uσ¬á•mú·Bº°TæÔ»zÄyÓ¯„'.øôý9WÓ,ÒÁ=ðüÔþÅ B¾³ß+È ‡'©Fà °�¦Ês17·ä¯>'²w´²v¼ž…à[9—‡‡ë‹6üÕK ðý‰ þ¦Šm:äÆEw²+~}]qøXC ·ÖK×6ÚéüΙ¼fžˆªË¤†l.b«-s½ø±Gý+�ƒ\x­Á4>Üfm¯$¿ŸB Ñ¡NâKnýÔÔ½]OÎß |ÇŸù®Ÿü©Ÿ¾þâ·Çõ½í¯\OÿÂÓÆöÜÁ‹n÷Jë{ˆ· û¢u*?ÅËïTt’|S‹í+Ç׉öíN}À¦µC‡�›Nˆ#T:F{¯&:¹ IDATº�iÏ Îj'ôÌõ4‚xΉ&ô曇&=òAŸó7±V)€Q<~s¢jÆpxWì[~ÝZÿ›ò‹æ`0|N¿½ôv^Y`r»>¬Où×^'„µÿ3Åv¤l‹ox³´‰˜"#îÔ8oØy è½â¹sÎøúé×ðEq¸Bè‹ÚÏèZ‰´F+ÚIíô«¾ºaí¼ÜÕOÖ÷ê�ùØë�ü᯹>á×ýªë%/yÜ7µÍC )5 �å±0íÔvÒð+†µµ¨2Í8žÓ;ŸýÀ¿»þÁüÐõÎw½ëzÿûäúÆw|£c¬yòjB~†5ÅK»Þäì¾=r® -Aú~áËO@߯{$ _"�àý©¥ÊVÍf6£¬zü¤vñˆ3ŸGþ#�±†æÐ>ß„ ^gÔ nZ`_}±ŽSAœ—šÎã˜ç˪L¡ØpÍcÄyŽX–ÍU³["×-Þò»ÞÝ�‰¶¨R嫞(­ SSoØ¥µñï€ÃßôÁ5¤§öª¡h8ûƒÝq£Æî\mXV¸äñáZµi}Õdå\O5ÄkŸo:%Ëâm¶Ò?}M6ߨÉåíîËõ §€„�6%MÇùHÚ㘊\ƒÂ[CŸ‚`T«[,ãîÆøʆãhr´`o¹|.ÆÆd?q®†šØçc€•Í‹¸Ø‰KôÄ—Üp¬_6HN"£¶ìöÑbrbÜë}fŒX„åD7®w)‡båþø‡Öí<¶Æ¥ySF“gçc4‡È±�ªð®Éi v�ůµûf+ÔÄñáCöƒÀáYåÆoï\=ØÌ§ù&8…WM廉CŸLÍ•æqh®9S®ó�µwγ'¼B!0¥,\óœóÙOì7µ‘¬’ä³–3_sØžÍÒëlú”±µ”‡\­“p×ï|éÄí‹Xòø†®7¢ˆëyö‹œ“ˆ)#ù¬[õ5gÌҢ綾9onšÖ9š@ÃÕº:;nTœSkò9$xâWÄž9 !·rNÿkB–>'Ë�,2gEmø§¿kzvp6²ðå9+fŽ©Èt×4›¸ô˜‰¾œÏËÂ:Åb£67_WÆIòÖG4$ã:J -ä„ö&ÃŽiߢbŨ?&–˜ Ò¨0ðæ GYF£Ã7šA”›Z«{^HÀÖ5ºV’óæÃEgb×`clÐýÝÉœŽ)`Ï2ñk·oýª¯½>ïÍoº^÷ºO¸ž|ò¥û†Æð-îÆË^þœ+QâS;Ü­ó“Rô76ð]C‹??eñ¢ëñÇ_|}ìk?úú£_ûÖëË¿ì÷\óo}ßõÝØø¹Ÿûwþ{€zÏâ‘_«ÌOy5¿:KÉáêO ¹·nltuOþõ§HPƒØÔØ7yàRˆ&%J�F`ð5ç󤜻¨ØÁk‚žif�+§dX#y͵% ×N ²ÓvVûj$Û&íŠ1ñÄ/ž}]Ö¼Ö�v§œ+Ôý�ªúx´6'A å›ÜæãÆ}¶/<'’þñfA½ó?B­ƒ™<\äš_ÄÍ6ðáçoF>$[‡oÖÊM \hͳâxÀ¸.–‹ÇK ðÌ*8@º9ÍÿX­õsÖ¤̺©þ©ÿé§_ð-_z}ôG}Äõb]³¾Þ¦TøÝµ&–uŸþ_Ôv'†þл~ðÙëg~æß\õ{ÿÆõž÷¼÷úÀþ '&‰zROåa3v­,Á=B«Gdðâ ¿66>ˆDM …jD+uk?e/ïPDH‚Ü'ð}£çÇ 9Ð ÕÒçž9B¦ìþ:=¤NÄ¡Ñ誑kKÜÚŸ¶zý5¢Ž)À×¥bZO4°G¨ªÞ7õ5 ¿‡¿ÔÞ|1†GVmUaìåÓäôÃÑ}8à.¸]¿°àc„“]Ù±nv‹�8}$o"úM �¡�6¿içë²SM�×ï¹m;³�㘖ì¥2¼+ ú…Ÿ$Ú·'=/F„ZÒúN0çzX6EˆÇïÂÇ—â4ÌyÆŠËÏ]œ‡± ¶c8«ä‡ì]óÚXV¯¶|ŽÑÁçÇ›ätüvvµqÖ&2'�®�ž¤?Ì~�M´Î'kÞG×äÁ5š¨‡ƺ޽;`¢w1¬øƒ [¨ì¥Üp­#™þs.ÓÓÌ˦DûüÃ=„Šq�ª§svïÀÉ3¹O>âøwð¹�%¹37îÄW£¡èÑ¿\“GÙÊo“¬÷ ^ù«¡®ðÐÕ<áW¼Ô­×WKô$X“wr¶ÇwJËV\¡ÚA­%šÞ n´, ,ç|89 鳋7u¥Þ0÷?˜I_€ &38>Ór ¶l�?ÒåÖOaû5³ ‘�É•5ÿf©ë$.Œu„¬æ:�¿œÔq»NÙî0Ž™¿»{@�ií²»ä0Ã9x�pöŸ°;IE0iÇÖ¿ÍVqn s80eÃlA=U0Íw/²… «4CBÂy^RÃÏ“Á�oN7îÅ´·,Ã[:šg¡‡ ÊèÜÔ9µk^^ð® [ÜΛ‹eq(€œîØŽ\ýãÃC=  Ý:FzËpZÞjáµ6î�æÁáÆ=˜·Nìç8{a»iƒº=Ãá›I0D­3ø]k¹]‡Y3T¤8N{µ¦Æ$@M¹°“§û­Ñ°m‰ãÎù Žêߊ»k˜sá¾b×°]z<"Ô§Á§$Vë]~-¨QoaÆ›iáËË9+¯cöù$";I�ÑÞ¦ôš5ž^ µÅ“–ôÍ^mÑÇn. _ûû°¬Ä÷œšÓ:Ð0v/ ËY§ñÃÙ@ÑvîA[‚úÅ›tpúœÒƒÇÛ{ÿÞr6Çz“²˜ˆ FµLðw°ÊÏi�Ý!QÔ§m¯•þP…oá¥]n›Õè*C�‚�+J‚m^lqn¿ß£§vKm|gEñ&€­$ßzÊ·ëÆ’}©#÷—Vˆ&¿Ö5r½ßVÖÓô‚ÜØÉEÎúà‘û'�ê·‘œ“}šÌç”Íè·=[g�ð -lŒ�/øÐã ¥‹ÎÇ.ûpäx«ÅèÄ)æ®�ˆèÍ\‰à¼�Ïé!ulRÜ-eÕ�ëÝ\ø™ë�üѯ½ž|ÙSכ߸¦ëMoü¬ë•¯ü0ÿçû¦ÊÐ�ˆòo8Ƈ�cE®ßøB&ÅæJÿí´ÿðW\¿ë‹>÷ú/?ë·]?ðü°n~“~ÒéÿÒ�ÀGý" ´;¬`Þ¬·Nfþö¡{/Ö ^ìçõ±—²óº�ç³¾yÏ Éd ÈpQh¦n[V‚)lPÔʘh«M<6­üxÖªñ€E¿úI*Løe¬½u@RŽ9ëÎA>ìöCè¥ÀNÎä„@ûáñLLÊ—Íys«yˆ »c8Ñ‘æ±À›f×# ¸IÊM;„´ÆxÏy•‡7¤ÐئµŸËì›Ü8Að“y‰�Ï!xì¤]/F—©ƒ>øžJÒO¥A¾.â‰ë÷}É—\¿ý³ÿ ÿšï£�>’ç¾ÈJª®›N­�öµÉÚç P}ãïùæ×àჼ~â'~êúÖoûöëï|ßÿ¤›‘ψ‡©°?å˜Pí!»Ãc&%Žçnîšò¡CL²æ¬jIÊ1lñ�ƒCý‰KY<Öu‰S HÌ+í}sà'¯s’ C»„š¢¯sXƒwƧ®bOOR|{½{%+$®Ó Ö׋@bÊÓµö~£§Z„#M¾I¨7@Ì×b´ñÀª¾gls�F+:¨¬Y ³$­‚!7æÔ왫ëÄwg"LÔe³ v¹bÝgÛX¢‹a-Ô`ªeñ�óGðî»Bà]iN:3sM쑞ò(¬´ÖHO²¶O‡ö€ç¨õ“ŠNt$Yä[êl>`»ØgÔŸrjÕ,.žƒøP¾¤Èõ°nâOý˜pÓ°ôœçý-²“nøæË ¼ZJæøf&Fë|¸×í•iîaÎGŠº{núXÙùÀÁB±“`4€]7—®.¢Éåúœ„ÂÞê,Ô"É‚C½E§þ1óÏ<,!3¡þƘB¢YvÇãÈg{ �L[‰vÙŽ ‡M¾|³#%GôMÐÒè½A:Ñ?ð7µ“B#p?N1£ ÉssaEk¸&ú·�Ç6½y¥¸£§¾y)Ç}Hqâó{°¦’/9òYß©iÖ±ÏOz3Ñ�…xÍØ58ç]vÉô`¶ø¨ — n¼óñD/¤ |Øë<ò»pøŒ•›ö3AØ=[šàϱ/\á�<½È“‹zr.…r˜îsØ(ƒæÄÆé¸2”k¿ÃiNk»SƒivnŸ8 Ög5Þ$²Ó�é™–ö3KTؼYþÅ³íµ­ˆ3LGÝ^[—^ÐÍE¿ÆA'ƒXѳζÚÜ—žgb“Ó…›CõùZÀ­µs+®7©w'¶ú`1‹vöš×"H¾êªN» Óp Sç}›~a&R9Íâ¨-[+ÕÚ73;°d;ÑA~NùijŒ;ýrÆgüx;9ÐÁ³‚Jîy ,Ⱦé=6í1�ö‹ý-vTÌl´Ep“K¬·"©Îº�BQëÜd‹i™î.Ð׸õbÀÕ‰Ãv0F�Ô@Œ¾™á7²{£wðŽÒ¡çƒ¸D�ØrÞm8Ó�{^ä³J`¹|®µéõ—:ƒéu�/ !FÏÍ�;›9äq=qÌí•Ï�óÂn-<œO¦Ô99äqnždÚ=Ü×}‘çü¡$:ñÊ\ø¬Q_'r Ëù QêÏuo³µ°¢ÿ©±o˜e„ÒäÆz=6|q¢fr–_ÖÜ4ÈŽà jç'•Ðéœf�OŽX¬yâ›t!Q=Öi®ÄÙaÎ@Œ'TŸéÔ…ñ9ÄçøTròÛ?õÉsÏ=ë›kÿöß~àúKïþK×{Þû×oø¤×__ú¥¿÷zÍk>êzâ‰ÇusmL”‡Ò­|Íaj b6í‡o„b MåÂõ°þ‡Õý�§®ÿìÓÓõ†ßøºëGÞÿã×Ûßþõ×þÐ\é'±î½À *ý*°~=Ó/®¤íùç•A$¹FøÆ#ééKÎ!ןöOrÞÌ=ÿ|n6Y1*3×VD¢‹ÇM{¦9ˆÁËÊÙ²qàyS˜È\ŸYWWv\K||ð:š^Kù5×Í_Ïn`táL&âñ¡x–ƒäÆÅš¥n =¯_ÿM&a£Õî£ r»ŸÆe ¼º&ÈÞÖÀ}+§£‰äÖ¿öè´G«n6Í B¸°­�,mñ“¯çdÍ8�£Ça Øqr3Ë?A*�sÎ7�_ÐßüÈ�|õõµè]¯ÿ¤_§_ó}Â×dhM¸ø—¦.H¥áSTŸ¬Ý?‹Š åœv„>ûìs׿ÿ÷?wý“òO¯wüÙoºþÑÿÃë¡G½tj¤1o$ÐÊ'—eÏ)}ð(Qv“›Íc9ùXfpm(�ù°p®áΧ×Káh�tĸw.|ò '«± ¡±“Õ!ÎYÑãÔž¯}è2×rïÇ0×_«Я‹ÙòΗ6Æx½íؽ©cÜ©…^ïx§.îð9Ú謞a “sïÇŸ”L†á¾eÔ"=­…BˆONf>ϱÎ�pÕ•š“mÖ„=ïµ6·}Ë9)µ¾›$nrrS‡.ÆžÛp—jò[ÔæËjï××f™b%Nפ�ssâ;´žÏËQ£G ´^`D©û7Ì/ÞÕ3ñF{2ǿ㪨=OQ6JõJ?Îðóµ�hr²Ás]£~>ŽÊrö9‰޽zÌ6(­ó¡=vn ¨Wú—Ôáw„–É9tDÈQµk*Øì½Z÷šÁ$løHïñÙ´1Ô†y mι–Uû¥‘=Ÿ36.¯¯Ð¶i¼+ çrˆÍ‰Ù8žKFxã]ï ðF�øMP"è#¬¹šs ¸ÁÜäÆ6Řö$•¡<Ìæ™L.ŽcÖ, ™Ý¬ïÆßØä÷ TÂÐã>jsŒ[{4—Ó)ýü‘€¦n8{c¦ÏJP—s­{cm'²ÝXï«.ž_ú¼5°ö–äýŠ¢>ý³^â'�uh³cÒ§s?íä"ªí�ýX¼É™D½*,)¾—å¯aóF;Ìwæ€S ïÝXjá\iöû³±ãEnò{§M†Ís~W«——Œh€Œ6íàÃè"‚05ÞRLƒ˶¾*ÈÊ!¿ÛäF,Ý^øÉ}â}ºÖlM$äC›µ× XÞìÚm É1µ•§‚Á{qk�&™ Äæìg¬ÓKìpöך8ñÂ;¶9AâÚ#̆8éŽ¥Š…!Ïø™­‹Â`NíÅ»ì4,j–�®ÜÖG1R3ùF·¿ÛE¸F%°0÷a_eÒ§»>~g×ÁzñÚº¶#èy2¹×гžCZvmò—LÇ,“3Æh$AÉ•>,ãÒ©…qÖ0aÕÇÖvpÕ íKÛÄ; z0úLþäËÍ¿Ú4Ï�~!/$MŒc�òW“cFì® N‘ïvOa²Žø·ó¸äŒó5¿åp�ä�\^cÉ8#šà›—àKÐþà�²¬ÊpÌ78ðqîZ{ûÛ™ ŽSØ’pòxC”ͤ1ÔySp®>²õ%ç¢CÇpt K¼:êÉ,ñž Úºo^4rçN=Ãâ\;wVåKòu^µ½Ñ†’@’DÛ¾)rkVŽþÄN¾ó~÷�h¸vO\ wrZûP[º é)Ýͺ×Lêtz˜4ÁrnÎCãBì:_îåQ¬–Ù¡»Ü�Ç3=é�!è9t"]yƒ.*‰r¿E‰à»ýXýD„Xs¥¸dth¿î�4'Šs ´$*\ì @ÿ4Ì9l×s�þ¶“^~}øý¤Ñýã¾þ›·|…þNßK®¯øoßr}ŠnÄ=õÔ“7¿Lºö¶/*-É3ª¯ù\« ’Ñ9;ë`ù𽇮—>ùÄõ‰Ÿð«®oý–?}ýäOþËë/üÅw_ßõ¾ïôß+LŸz£hóp�>¤ûçDêæ�¤mzâBWúA&|êƒn¡¿=Âcß=eƒcg9õS^>sÎC$r•�Ö““7i%÷ÎK½ç:€Ÿ(�Ó¦�xë?ý€¢ÜŽ×Æ90 çÁ²âÕð{Ü¿®–b|n›{tV+˜žûÚ¢Ž¼ÒDc4òbÖ$Î]Í L¥÷íï½ÀÍß]jãn¾�6þø¤fzJ^Öéúê ãCº¡üÉŸü)×W¾õ÷_¿L¿’þø‹óMæb¨Ã½í¼6ƒ¨lm�Tv®^*,ýÀÎüŒnüýìÏ~àúÛÿóÿzý¹oþýTî¿ÒÿŽ­›Ý?’7?ÊIZ^3pc ý¤ãºÄ¾ÆÁZŽÍM 7Í8ýO×ȬÀÃ݆k�µ:'»cçëF°ú4 îå€qâtÌí$ ¥Ý5*/ú|?Ș�ÿüZEº¸ƒ¯˜ýM4âÂìU¹4O Ëï|ôÙ–œ#äð,1)Ð߈.{üòEFù0ux�‚ÃÏVÙ67û+c㲨>¿¸‡¢Z£É ‚OŒN±k § Îˤ˜%ðùü´£Ø¦‚é£cÒ§àE¥×½#â¹"‡Š =ÑêuÎ__3²OŽ‚4�¾öJ¯MÍìıÏ=îóh”±Žq<«Ô6˜ô™XRçÆu·ÔCé\Yýú”'/.�ö¶{øl.žËÈ|w' æÑ7ræu^x)Œë6�ýiÑP¹]ÁÁ‘\pÏy•!ž�6Ógb°,œw·J×sÎäô¤ JL,bR·cÚ­oŒáÞ@vk¸þ1i˜/ôÓWÑù.¹ihí~Z´Ó«é?:'GÏÂÚû<)nrÃ0©ö<ýÇ×>ÝÌ}Í‚ÿNžÖ;Mãc’Ñ-ñå:À S5Å휞>bæÇ~•Có1O–:<§W¹æ¬iôX u\Þ É —0K#ZÔ=YWërOÂ`?øæq¼T9±¬ËNs�ehü®îàOþ8S—ÖæL,iæëƆô~9YÈß{V”Š3ž½¿Æ �ÝÿAžfl¼¦hRË NùàG¿Á9P%êoꨕ“ùÉ7$Þƒ%ðÂ`+aí†c¼!IºD`#¶c༙qCÉãá,~òôÄ6pc&¶xpû@ŸBM(ÍPm{aâp“Œ±c *u$~ammÞ³ÆG­§³„xôb²–öOdÞbØÁqâ =ð­ËÁ²£Á1ÅÚ±7Ñ”½ëšó®H#m;´›Ïqç"Þüé¥Z«  á�tZk÷–žcò�)±·ü±ƒ9ë`}w¸ŽÁ´Ó/gvHú·÷åi ‰M]õ%0¯ý‚{k«>[$Íדz`M èapî…I@WÂw܉ä~µäsVŽærOðAÊÄ9`œ69ýbóô°ýhÜšïÄ•**'Ms5H1¾¦3fo)`áÔ¸Ñ&£iª×~Ãö¡Z&ßv°r’Uw$YióÐÇOÝ#ʼÁ�÷Ç/î*šTÂ圆¿Ü®~s&WfŽ{äÚ²‹Cã´ô_‚ìÜ]•�7ÊÜ´HG7A~p+Õ!´\/ ޹>ë'”�4¾F0­¹ðô±¡xð ¬m}Ǿür3r©7{ü<Ùk$LxxL{ýËõ­ÓÁymÎs�¤¢:X…1Öž&£¦Ÿ0ÑÁ*¸æ£žêÇ›}­5Yuä|ñ»9L¥ƒ?òS ¡¿yÙo©Æ+ƒ(¶FªàͲÍ+¿÷5<½w­}ñx^HdíºGÈ#úßw]’uC�ÿ`õÙg>¨Ÿzzäú×?óÿ]üOü a¹>çÍŸsýŽÏ{ãůé>öØc¾†Î¾›yò¦¾‘©é†ÜLhgÎd=K‹1Béã ý͵×ê§ÿØ÷Uú;�¿÷úÞ¿þ·®?ÿç¿íú…g~�"×O(6Ýz7îæù›DùZÍOòò?ÈR»0úäz$'×tÿà79iÊòXoÃÉÒñ,xÌøu2å�×/̨Š©;…öù¸�9(„ò5Ãß 4Óüä Ø|0�wX<¤ÊlXÃÈpNï²³íŽMÆrÐE#²ù&�Âј¸Ívâ™}Þ&õÆZDb­ƒÐôœ˜<¼ÎJ'ŠÃýcÉäuƒO7ïü<ó"É›`‡é)äÈ Þ<çiÇì¡:}óLœO<ñ’ë ¿ð‹®/ü¼7]¯Ð¯¾?¦_óe´wˆ$…ëó'ôò||ÕŽ6wpúR»gÙžÖ¯ùþôOÿë뻾û{®÷¼û;t=?í¹ù¼n :x=—¨¾éS¾.Ìs 6åÉ7 ¡¿Öw“-)Gø@¸^ée�ÈyX@_'BçºÕî¬E¶ µ{�LM`<ù2ˆŸÇÈpcß”ñ…Z�;}ê??0£ÅwCÌ9¶YQò;ikäÍ|T0§žîá¬ä%vd|ú²cXM¶ÝÕÚP5qœC¯=E'ɼc³ß°ŠÑÛmCc†™½\µÃeËE ßp˜�þ\'D�ù“!áfÐÓŒd›s?¶Np¢ËýCȤgQ4ç¦3—Øiˆó¥UÕCòÂÇçîAˆœ¿J¥ãf/Ht€Å93v×7bgi0ðÄ8Ç•=º&ê…–¯ËOüÍS>ê!ð¬õ¸á¹W{žûû8fOLò£Ád�ÉŸÍR²§–]F™ˆÝzñÿ"Òɸs:/-|CjÖLŒå—HDsó»Vcb¿ a31®x¸{Ã%çP¤·“q'ÏàV?õ¹S¤ ÞqöAÉàF€iŠ—Ïy§iåsÐøºfŽF1T›óÛ1uä|D·`ÅÉ`-³/gkA×H¡¿}JôL±3çúK]å²:øÂ0šÎ|ÎqÛ¼À}jAޱáóûbŒqàõH …Ìyñ\œ'¿í+>¢sRB±Ì®_1S^$L|&é1çq‰—ÜL‰f9E˜¯çgÅ5†Et³]¶Yûõ¡^ƒôë%~s ™5Q²)ù»j‹{4�wðöŒÝ5Œÿaº`Ñu’l>W1§ö-Á+Ù¬—@m0ç®&¢wLNÄìG€ †çf;‡Ã×-~af�^|΃�š˜8`Ÿµ/èÚ]w6­|@f½�JÉéY9†ø¦ÖÉf›s$°Ú9ñÍ'¡Õ«y2UÙ+¹©%¨m`Îý:-ìL4Uš[SÞ”S~âÝŠ2Ož,Ü lŒ¡šå˜rîî¤EÔ•Û±¼ÐT.ñrt8)Û ×Hüißm IDATG“|gïlFýÍi£í:��i n�ØVÎɃ�±°ëÄÆ¶ðA圂nÿ±_Èå<´W­)G‰~±SÀcâÔì‹zï'å�æÆu{´,™¬™ãÈ̾’9ßrÈé'uãwsÞOzAö(q˜c¾Ó7ë´¨ç‰~GÉÒпÁ<×ÏðÀAÊÜdÛ™³š¦�P|ÞtaÓçzb¸sîó†KµÏÊ=3Ò)äE¼Vcã¬[[mDiMÓ�ÏÔš1{ lÈІ}'Û9Ç9 _ç«Ç6Rz†sÎÚþ:³t~ìëÎäLþˆI¤ñ<Ôæ½»¢M?’ß©&O~úK¹‚]ç?`ûéƒí‡Ä¸ÑÖø8{M:FÍZ!kAFmôgÌ\K0r �VMæ’ø™�ßÙCbvÚdž۽³㙇ø ‡C"ÆœéŸ|ÿ�~Áõ5‰7œ‚ÜãM7?½&ÖçŸÕ¬ÿ-ø™g®÷~ç{¯÷}÷û®_ý+åõoyËõq÷±þõHÿz°0Ö ŽÊpêe„§­>G›u°îe¶ç„¯3�é×!éG¼òúâßý…×ç¾é³®ïÿ?x}ý×ÿ™ëŸÿÄ�ù'¸ø" ooÀæ§Ô7Þ`i0å?˜—s”,9ž}sýÒ2¡þ_X­óÐgmððpݨ—Ï5Z„/狈©S3× _{]°K­AÓµ{Hœ8ýÝ`ÍŽicMG£•ƒ5l•4ZeÉ;ìfá%¿öê>Èæ‡¼ªˆ{íUz‘\Ü�5â×"&å×4ô#ØÌ}>§®O¿FÞÿA޹^Ðß¹|Õõ¶·}åõ©ÿÉ'_/{Ù“×#úÕsŸ¬|Y{;öä­ ÒlíØ,Æš0M*ן�î¯ëµÚÏÿüÓ×�ÿøO\ßøMßzý½¿û¿ð_[KZ¥X~ãšÒ³ÖÇ�fò™ËäZrÍ+~k��s…4t-uî‘ãtS�”|LQßÚè©a:Š"<̾¨–ËäkÌaL¼=»–åW9Kt0ñË*_oˆT»ûíº‹Òäu¸CÑÏpߘõ9•˜“|Åe¶Ñ…Ó¢Èéþ99,vg8Ú;©LKÂÃ&¼åLìxÈwÔoh4æprA¤©Øô£½�Û"¬›Èá�gs?´_}0WøËA}f{Eð*FÜ¥g�8œš!gg®�YÕøµUÖÑ0=°¯\“ ªÒ‚ù�ܹ4–®©\ì5l¿c‹ÇµµßÔåõ RFKŽW~–³ŽšnÊMü^CCŒ¯ ­‹{ô¸§2î"4ìçpr±^ÁÛ5ð G�&kÅ7‚oµË¡áë«ÅÙ –¡XÛcßô~¾g3rRߺfäêJøv¼ó¡×2­G óÑ—áw*¤ ã÷N�ësà?Åã€ÓMá¬p– lpëßÂ�ì‰ FGï«_õ:‘îûðz¯CÎ ]É?ׂS#xì·|¼¾ö˜ ¿x¶ìXDîkwêã|£§ý+µ�5§ôÌ5»¯•d±{ñ‘VvøÆ¶zE“’8è“vÎ%�åu�âà t°Ø.—cA ÐiN…Tã°�Iÿš·ëÛ·þð·„Ä>í‡Ê±æŽ)ÌãD/D „Ïh�Ý3‡k gL"ïÔï×2Óã]' Gogï¾àΞcþ�4k¾Øšt”¯L`M:)NlIÁ¼‹o ÄÿÏ×»@û·WÕ}ûÞû¿/ä�øH¢¢DŒAS%!i5chB T�c†ä)ocIÚŒÑ4MÒG¢AÆðcÒJM/øH­mÕÆ6cÔX“bD�¶†*B¹p¹ÜWçgÎ5¿ûû;÷¦ßsÎÞßïZsÍ5×Úû÷Úç÷;gŸ7Ö–Øáð]Ó¬dФüØìß®¢S;ÜÎ56|®Âú¼.áx}±"$áÇ.L¢ØS€Øª®þ®íŸƒÈÜ5)Ìû‹œ9ÙÁx ÑHP’‚•¹ó¤·€"£ë|\I\N*͉á‡'øc}1¢§9Bl&Žƒ¾�7.Gy:ÇÈ$W6‘™œí�Λ»a«®€\—µ¼5C¼åEõz¯¹k�'–?ñSª�›O�Õáóhë a{ÍÍí^ gm—ÚÂÄþ3ñ:vµ7þb¿ðK³¤&×mRä'Ï]÷\œ°0m˜EmÀôlšô þ†��eÜX­ýxSþÁµ6Ç‘Pß­/¢æ8™Jñ¦FÇCŒÄâ˜3Çù¸‚;�¬³gÍ< È  ç™YÒ…gùb4âÜ o9DâTäÑWÏçàw'á™7\=_r̈Į‡FIHI®I-÷Õ|0ϰ¨s�XE˜S<9%^;Ý%-Îr“›¾eÍþÄ'jeà x ¼Z\2E+yâ¿<¿ �±¡§†êÿÊ—šˆ1§ö„“‘‘9³jE³�w ‚k.æÔ¶ÆÔÖcP=Æ, »èw/û·£ÄTéFxƒÞö˜Ç<úxöW~¹/à¼ûÝÿ÷ñíßñšãþåÏëcŽ×|Î÷¹ 3©±ÇØ×´¦VFÎÏÈ»¡„´H|t4ëÆí\h3Vøœ¿pº[îÓð÷ÝGhÉÇŠª§9—ÐpšiÎÇÖ9õ^«röôkΞÔGÄÄ9µ!lFt§~»ìMB|y'¹ |@9¿a†ÔQãÂJžô•†G�€`ÝCók£�ÍzÈ—{ë^æ¼7Œpx‘Ö?z'ZáÛùÑÁGÚÁå…‘Îgk%ÿá÷iO{úñWÿÃWOýìϪ¿ï÷ ¿ðN_´~ï{ß­¿ïGnéÕÏ5i†Ã1ô@_=GœÖ¾ö(iè—kž¸h€Q‰Ñ ±ÏÇà �‡ƒûd÷ß^êÛ$ð@lò�¶O†Ø�óñ|>íðµÖYQ!�FHœC»M‡/–7Á"¡/ç0?á w°¦SýSÞ9‰Ém\øŒ×&e@€Xošjöɽê‘`ngfh¬óÔã£ëEò'Ó™¿:Ò·Üã/¹òøâëÑ¥i¸L;›©u™’'1°åx·…®»)œ+ܧ‰^�q‹V“Ö�¿×5ÒÁFOîY:×ÔӺ㊦–E¸Ñ\܈À¥Ÿgîqò„_QšΞ±¶I6vÎC»C=óX&h8.è¤ÖÑ ØqlæøM6ïvN´h]mõ£Áу]Z¡¶ÀX.´Êwj˜ÀÉÛÊqºœûÈÈœÚpÁ(1»8J@yF3‘·öѦµŸË+A4O?°lÌ=’¾«1UÐfn™8¯È»r�/ç[ä¥]ÑdM{ŽR¬cq“ŠzÆÏšy‡kÀg ¬ã¯†ÖÖ~6îܧ�¬÷ü¬ù…Wþ¢¤—‰[›µ®†-sã;ç#^‚VìÄ“¢ÇÄ&߇0ÓÏÎ?ÌçØÂís?9€®A@îfW»µ‹Èù}®h.ç^?yy�£‰Ï»`P�ßÇ“@´ÀÌ«Ù47ÎQ�<øSƒ¯ ÙŸÿÒWšüI‚yžx’&óz®'Úæ[Ú§Ob[#½U^q“�ÀÑÔžÓ Kfœ}µ-¶L|<„cé�� ‚� ˆN— Ž!öA@t“1·{lPèg5;©�•õCˆ$Æ�ÚxÎZ#y2ï6Ø ¼ õwïX-�zQ‹2¬0à‹µøèaŽ3MY½Á¦¸ë‰¥)«¿++q³m?ªÍ$uŸ°i{ƒV>¯eòoôÅmÞv‰%Ùâ„¶êWþà}¬ÅÑxJc®]öÅç/x&†s˜n8Ǽ5ÓkÍͯˆp•—°Î­} ­&0#¢Ô51ÈgÍ'²ÜàZ·#0¡åx(\t =¼Åî9÷¸5ŸôÆŸRFZ~V_Y·ï` Ð4›•KGñB„'ç½C¶ ¼gÿã ?K×ä*.?Ñ®ΈFEÎ�¢ãÌ•m“Ã}гqlp{Ìã,ƘnÎbvásM–dÁU��…›Äå8ŽCä˜WE'ö¬«/Âwû(Œ³*£“‹gš„ç°N4ËœmÔ>ù³N-PëRBm ÄSMØÃßZ˜�Éz\—ÅÂ5ýC.�FÈ9ØõÛ_ܲù]NÚ{3cJaZ�B»\h› W“á¼S‰ 'D£Ó”²{¯'<ü÷à¿ñ·þ†þNßmdzÿij�oxÞWëÝyOòóÍŲ&L#&W–Åâª&ß¿jÁWtÀ”¾Ç ¼Ä�zO\õ#jÍ'Èù"÷ô1ú²`žuº4ÛyÌi-§†ø/r™!ýóqÔWô™¼8ô×˾Ú5[É€ˆÑëŠïžhÅ%²­Š`”ɘfÉãx:`¢À1Úï«Ô> .ò„×1Šõ1q¦S”9† ¢€2Œh}¶�OŽoœ�9íæ+Û`W¯é¼ÔB®³~Ó '×(ÐJ©Iê"òô´è-�לŸ½‚úŸL)3¹œÉ†QšoòH# q}Ú7*1vÅ·ÉòTÀödíáÒH=¹O�E[õÄö>ÇS¦Æ9i€Ž?7[œ¹—rö<Št ±h°gä*“ìÎ=ÇïØÁ°ƒ ×Ò†mžã,c¯ß d+'$úYÝ»a78¡ÂÛc€mðð«½1èÜæ;´±�\áÎt©Y}$”wVu:^ûH¬ÉìL–‹q~¾‚.MÊÌœ/ÏïÓc^HH¢éÊ“ãˆBÇ‘ÈsÃâ~Çì­sòXBnY Ÿ¾Vîñ-¿<Æ‘Û/Òªaˆ9@ŸÃzµô;óʵÅ�׺&¤l»vç?)=kLî³/kà¼óZŒç�aìÔ°èТšsQ_ÓM›ÿ Ît @ϳ‰9Ù´\™‰B áIÁ̽.N{½ù–k8ˆóAò�_^(+tâœÇDsÀ _B›†+us]ê²�Ps±:GO”¤@óf�fñuU×~P±E®¶âX'ÂêYOIG[ðdvL9ðÔ•ÚPÈ8OèYV.ÇÙý�Ý šûE쎵Lxg̺Kï§Ì­Gú\ר:±&ßiõ̹‘4'5Jýo½¶$‡`8—\«®ðÌy¸¸ˆáØ'GcLÄÂuˆt4`Ú±í²¹}FL0`[;s†{Ìdò9N9Üc†¿šfoRÂ\$@�©×Sêq¿ÐúCnÃ9™ÁéËu�Cn–Ô¢±ëu ýƒ_» §kZœÎšÜL�w-tsâÖ8/–Á;Ç ‡–Xó�6ë6Œ¸3–Ù¥œø0gaõ²â¾ÑuÄ%Ë36´dœçmK¶¦gÃgÒ:…‰Bœ'�xf­œ]·ÇµÂÅʼnOöT“•¶¡Ûp "¬¯«ŠI|yRËÉIfFŽ�óN Ïwy|ÞHGΟcpçŧè5ÍÔæXko>² ?{°©-þàÉÈ�!-PœË«p¦f– -×oYöɱ�ñ“ãü¨˜j™=”ÛpO çì¦ÿOL´j�\l9‰–‡9Î6�tÀåÙˆ¤ù�鹓A±ÁŸ§ZÉ·xàÍÅžÑ=0D*._8sQŒ‹-¦–'k¾`·/€EÇqÜùÑ�êo˜ýÐñÃÿømÇÓ>ïiÇ_|å+õ.«Ï>Îæc•|M³üÃkˆ��wF'£�ÜhêÅÁUZñÚ�tÌóÖ[o>>ë÷}Æñ×þãW¯|Å‹�·ÿÈ�ß÷}oÐÇ-ïô…#ÿƒbôC^~òd ýõZIª•4Õ°¤á—½ï*¤Ñ%«ntwÊÍÞ’ÊFŠ?6Ÿ±ùxÆëàáÎ>y£íèäô‰‚ý'Q„é±ÔyJ=¹˜OÓ4Û¤ÆtºèîuŠ“<½Áœ¿P˜û2æù†#é‘8{nPGÖÔ€q9¹X´‡ †Øˆ“0;ÇÔŠLÈßÊÓèfŠ”ÔŽÖωßD�.„ë{ò²¨æe²<@ÍS½¬9†³¶ŸM�k¸¥m\k¹XR ãp&ï€ÉÀŽs6ÏX`w&M4fÝ$­¡šRßÄ�'(ßqcYZæ6qðÖÕ`/ ýŠ—~ §JÐá”è'á$ï«Ì¹«Ð¤œŽí¹@ÜÄz?KÍ“…Û þx¦™¥Ì;ªèE²e^è¶áXÇ» ‰]­›uÏ©u,Ð,Ÿ�­_ cÙôœI?«»¹àj_k³vk8c‡oåE´R°ÙòÃ6º'¯€²$ ÆÄfjÁ6ƒãÛu‚µ+<šÏóáLO’cäi"«nªPŠtò¯Ö«eÔØÏîí‰ÛšºNùC›šáfÆ~´47¦ð�AÚðgŸƒ3>ïÌ#œåò~�”‹¼Øˆ¢Wy’�á,UÓOò….­ëÚz‘Úä«Ð3ï¢È$„Öfì<©p¦É·×1pKŽ{ïQã‹y9=ºñ¹°{ÖˆíòBP¸ É1a?=›ÂÜRŠ;™vâ‰79£'yA¯/–•h40=ŒPkN°{|êÍß°b ${"s^Õ†Y-CžÁ:ÉØÔ_;£ÃSmÊÉ:çAtx-¯²1õ¬ò |ô ‰'£ëü–0‚ 6\é+Ö~âK"�Ö™ylÕJáÕSÞ³nYäwvαDØä†ÓK&V¤úÙ77¸Ð8OÈ þ7lÄÍ7禾“qƒÊÆ�~Ì®¿söI™ xò³Ó>}�Œ=Fmç|2:Nç'nxN† êÏcfÎ5<ô×ùô"ô:=‹`] ôðA®!w¯œÿê]ï:^ôÒ—�}ìãŽ<ÿùÇWê#ºŸòèG7ݨ§ð¨Ñ �,}9ÿó]yÆ�ï±!ûºxc�Š5*³+Ç-7ßtÿ÷?U¢oñ`÷!R’O1C‡Ü©ÅÓlÐ1øZS¯Ó]ø°½Oÿ¸ãc¿ëxÏ{õxíw¿þø…ÿýç%í>�_œþtÄGÍÏKóÁù—:ûQûûuºQƒ‹„×IS’ø…ZdekmLiƒ°di,¾«5Ò3r_¿…c#–T1×»s ©+7z’ŒÝ†�Aö›»HÇ"V8…qþMtº´Â…XüàòX!®* ÜS€ÙjH�”:‡kÀí™ëwª­î›%uµZ;VM™Nm€øçÏ»Ê>[4�«çk��kWTÆÆ‘‡�ä”Ó= gþË0¸ZÏxf'íú".ØR»ªmkƦE¦^èléýž/<©‹ð‰'vr[›_¹&G¹ÎtŠq.í ŸXûYÌq¶£úDâœò…•¸5 4ò§YŽ>¢àà"¾âlíE@â6Ú]CoóôÄ´'Ÿwp9:±°FÉ9 “ìÁÔ=ñ,™žµÁ…<Æ“dñkå1I\÷âi\öŽ ÍŠq›'ÖFçeÆ9Ã"†Æ¦7ñÑà …Öc(¿ðpµ“ö*Ö²ö\«éù¤rÞæ;á3“çµ¶%Ï:–ÌȦóÚgÊœYzGmhµ^ 3’eÓS{SL�¢r,âfkƒÛü*"=th’¶Ô᫜Õ6¿2]zGó8�ÇP?�Q’Ñ:„òS7Y÷™Ÿ–ŠM?8WÀŸþ© ˜�´Ø¦vŸÕ~X»B´w\ä^âÁp gÓ8âÙ ‡/·iÙÈ£¯Õ+û’ÊxHáÖèñ�)–ĆÙ�‹�1æO>Ö—Á üþ"š’o×…”dV õŒ.¬Ö¤5 çÈjþ ÈÜÈkð<9uc,à2ô$¹œY:y`MÍZ¯l#ÎmæqÕé\¬ü=!Wc} �oÙE·tz*Ba¦]ž·!ÝãÍ�E AÛ^S†µ±EëÞÐ}Žõ6|²uM¬Fó‘‹‹Zë@Û ¿AÆ.¦qY«óL.ó0¶]WMS…»t‡æÄ9ßàáò §½àî5Y égö[ŸkŽU_ î .çµ-|íUbÇï”—œ*ؘM9,c0h£9Þ“hð6ôdZÆ©cÁåÞÈWsx— �'—J[~ç˜9¶x,àb}æ\5‰±5"­}L|¶õïšv¿çÕ6¿«.‚§¦-‚Þ0¦¦ò_Øì´Å/(¦rÅ\�¢©�`³s—BÒí¸ ‹Ù≒€~Vh¢1èêE Ç£}I¬lŽ]áƒp7MúÝ']MŽ9ߌ _(KÀ~Ó(!ëôšß× mëÏqTÔwð¥�å•ã• d|Þå¶„%? só=-xÜÕF¯ŠL_r^§f¹¬7LÅam_™†�m¡Õ(ÎY’Àðäì¹�¶D+Þþ!«Q{÷MÎ<)çyì�Ñöv -Œjk=Tl£•cV?¹hTOÙ`ê€?#9XÆ’~ž}êܦç:=ãšQu¶VÒäú±2Xü~A΋þéÃ~^íº8F³®PóÆvŸþ>Z{år(¤å±¦=˜jÌ»tùX/Lx7�TéÇÓx…�=™¸H ç¨4ùI<›í�ãCþðñí¯yÍñ]ßóºãO|å³�çÿùçŸú©O:n¹åf¿[¯ú̓vè§y í¨Û�¡¬Ò@“+�ðÞxíÚñým¯zö×;Àþðñ+¿òéï~çñÎ_üÒ-½Šá¶Å fßWà‘þÜ~E;½ [§�dêÞ®E¢ðÃÁscXó¥=[å`÷_ù�«Á¡bb„÷\Ëu¿ÃÜŒì•g¾zdX3”‚­ò³ –@_PÂ…ÝšX„sÍ”NXbBÆ$#i¼µÁ8ͬ�:#d¡/–²öâ5¾Ð��$'et:0r”÷~.šñDS�wvR8ÇìO>û«Žoyñ �§|šÎ5]¾àùíâ|?Ù¼gy§ôÈîÃÉ=Z Õp/8îÕ…¿ßýÝ;�ú³ÿìxãßrüÚ¯½ï¸GÚxî ¥ÒM ¡ÜÖ‡Þ¤:/„Ëñ@ü`îã9kpl�’ ¾ØìøS*‚|Qaü8¡¦häKxzØ9¹” IDATä!?ü¹ø˜óAȹ4;bóeM¼o?ÜüݾÀÃäÒ˜?ÇlñÜøî{z�¿=¦ŒÑ×< C=þJ¹µË´~¸lOæ£^¦nŽöêå~±lˆæ‰EãðšW<Ö /ÚæšÐÎYÿ[?< |Ô¢ï‹už‡Äh°^N^is|˜šÁ•/ll“Q7ˆä9š ?N>`qÚŠ Ú´§é}WéTnט�o¼lĸHlú)GÒ$Òy'ž¹9Üá ÓW{aØ…®³‡`rû×ýÏ}6pòTÖÜ� /Skª6ǾÏ:µ`§ƒmÞµNœÝ3'ÎCưj5øÒ B;WåÝÒ,lê�x­irNp¸Ä@] xˆI�ô(cÕªeü å@N}y½ù“[�ÉQ¦笳­-L (Z81ý4—Ey£E ÕTû;É€ÝPÖ¬¥)6»9~­›ó%6ˆ3sÒ2w�§×oú¯¹ë#žã1� Wr,h†{ÕÄñЗñò{¾5Õœp7ÆÆÃ2µ1‹=?fË)rÛà�¯ýÁïs¸k ®:W¼bS@ýxÇ$ wú"ƒÓWãW‘¬as�ž“‡X|²V3>lÀù±}š³PP\hà"€LëšÝ'–¡/óœ¶ýE5_$îr‰Ù¹™0} £¥€!Õ™h|�K„ÙS.&Ç{ÂÆ”ÍÏyÓc¹ãšoEí)� =w{›kâvrW”�29õåš+E{êlž‹·µ]ôŒè$v¦LÛË•üÊÄ œ#œi�¥»'�[Á$uohXBàFÊ1Š —A¥'§Ïî†C·�ÆR_{�½Il+g/h˜]nË‚Tý‹6þ.ž> éì�lû+¶hÄo"ópàç~]LôÇ•h¼Ö››ÈåD–Zøá�÷÷ùÂÆ]úÇoÇÇwü°>üyúhî+�/ü‚§ÄÃ|�n—âbp“´ßœÎ=ö\,åæû¡ýöñ_ýÐ?>~à­o=>yïÝǵ¹È­sAç¾Dæoij=QF·¿šS„²q1 ½�.plZƒ¦¤u/Jÿ8'L_"Çcs›Ùó£áN¬Á¿Ä›ã…._„äÅTNgç"¾¿ô[ç�xh[}¶kí^ÚéTæ÷Ì6âÄ_QQµ¸/O2¢8¿çÜ ‹‹K^üŒ)kãźÎ:Ço\/³©µñE4j¥çÊCÍä³fÍÁºsd}õüM‚l'@»Œð2O/N¾æ3n‚�‹ûaQPX¢ A´…8ª�uQ„¶,\ÛÄÚip‚š1“Çþæïžž4‘fÛm)¹œù̇áÍ_CphG'ûÖ‚áÇ#s|Î:FùE$€({ÏØà“ ™>òËRãŒñRøÞÖzMåvæ+vaJ#ÜÕ|Æ^là!@?þN]zF°jÚJKäž:'O(ƾ·ØU]2®ãëô8vÒô¦zðYÃsÛ7aí±{°s)Æ}VÀ~Œ¢ërk:mªŸÞ£G%Í&~jpþÉS~ØTçð­ê\ïY5:ÎÉe×m«Ç¬¼{mÁj«8BñEÛÌçx˜ã wyáèÜr¶š]€‰å.ðÕrÆm:D ““]ŽFÇZNV ËñËÚÚê-aLnÇ,­ÃÙû�é§Ã‘åvêaÍCÃ;c²ÎCfKõâ‡ÖÄ.ÿ˜[¶—�1·­½¶ògO?ðæ˜jªµuÚ ›2igKàÞMx­óú4ý›<#üÀï'WZBj3 ™kÒ$w¨É„JÆ�(ªOšÁ0VcGŒmlàÔî*~ñÁ/îH13Ì9sŸ$Ì-EOž`u.j  fh÷VOÀ©wOâ|(‚xñðdDdb{|€äɬŒ›�pÔ¹+Ó[8NŬfmÑÔª �Þ$–•‡1x ˆI6ާÍN_Õu�ھхuÀIÊÖë¢xùàL�†;¨ü‘5unø“g8ÕÐæ1'ص'M]¿ Õ<˜Ö9~4AN}h˜˜„„WdÀݳÍ.ƒðù¸Ï/˜ŠÂ�ÆâÀDøžOë‡älº�Ã+–åà~ƒ[5‘ß}•�ÛCçh[šÌðàÍCùÝk×¶ãÉ®\hYÓäœsŒõÂ?@¼Ä4°{ÙlÖöêñ6Úàdd¿ç‰]"éyävØPm$ɹQ q­ûâYÞ3—{©5ø*å²ûÁ�u½©h­YÊ•c8‹Â]ßèïAFs/½ †°òF*Ð%üö$%8m)}"Ò’á²M1Î5@ªà~¯-$ŸkÇf|6µau_¹4ƒi®týòïÚÄŸãìe‚jÙú{î 9údÙE�Ågòkª¡'~˜b›—¼=Ê�?n¶bToóz8½°bÌTtj�Ø ^öÇÜú›7ÇrG•�‹7×ë“¶.ºÀJ\�;hßÖ›�& Á;ÎÝq=dúI‡ß&t¿òž÷/Å·èbÜ£ôñÜ_õ§¾BïÐ{ôqãMú@‚¶Ø�@4çqgÙó®Åà ´�ƒàÝpò[Ó‡?üÖãs>û÷ý?ù+Ç+^ñ¢ãŽwüØñ¦7½åøø]K›ÀC'ƒTu'/LÜ6©1T°äÂYj8û •l9‹›Núº‡{4ôn¡ÙG}ú®ßÇ`pöu.~´$³öM{žÍ.Rý .BékM™bG.Péuà‘:(rå‚c.vŒË,Ö1ùÀç—( ÈQ¤=lœ'- ÝöF„]é1}`ð�_ô?s�'>ùÓŽÿè/¿úø¢g<ýx¤.(ß w|®ŒpÏ lµ`·1_3WÜ ­ÏñÒ9`>úþ‰OÜ}¼ÿ×ãøÞï}ÃñãÿÝ?ñqä‘�‹ï Ëqàc½ÔB~Ï!/¯¦¹-aHâtÎÇ‹Ï3e•Ûˆ%là"í9áÖì~A<ØÚÍ+ ¿¬‰x‚æ>­ÈŘs Gÿþ`Ðñ­@aáÇ—s�üC0PvÎá¢jCŸè³fè¼R öÁâ5®�•5˜'÷�sÀâ4A³�€œ/óÓLZë“?ù‚YÇ«!öŒ�Ÿ¨±EKè�×|û walzyòk€nÀÙ«ö# á.ß~ì`)ûyŒrž“1JÝßݧœº;8ãÎ÷z£;8zš\xöñÁÖTÍ(¼éõ]Ê®;±€™  ïÖ”¨Ñ>çn×ZµäÓ—7çúâø tµ_æE†_¬�Ü®wU‡ö\?´v9KDzžšn3Æ)-°�}ç Mùa å.ßäk¯[pq«NˆVÐL¥Ãõj ®¹›SNуÏL,§‰ë­†áAtõlQÃÅsõä…ìÌIP¨ÿ´ƒš<Ó·1¤¯èª�½F·íu�‰÷SO8´u P(jêÀ–kQ¶ãBSoßøÉ˘Ê“µ°y¦$‡ÂBèECÀ“X?Úz4†u1Ö$+°D“‡`ü½°È¼\+/ñüL±ËOp$ií”I˜Q5ŽÑ\˜æÃdöiVcÏåù¼p‰�¤“S“Ô>OÎ'¾Ο”ö¸sÓ“QvæsŽ­·0Ö Ù¤ä§v®'ÒYD…{§ ´r̦®.íáaÏhºµÎA»ÕH&Ç j†õÁ¹áp9Ö•+1µ›H‰Â™ørW§y’@SÀàçq8«�Y­¯u³v®l–ž=¯)·�cÈ’dîgÝy¬O-ªyúBî}d968gº`cc͋뾠\~Ûr£?ÿ>š‚„w¯�þèÉ_µmù–¦ÚØ{ h-l)ïò�+àÕÃYÆ¡Æø¨8o¬Ø)É㯾ä™ô ¨nêH�“9¬Á콇²Ç*QŠÃ�0ûü%ó-Õkâø‚e%Ô�œ0<ÕµòPœGΖ\d‘ÁÁñ a=™Rî%ȹrŒòbo„&Ì=p_®Ô�{ióÜ5î8�ç‰6ñ¦‘Ë@\r{AùÝ;¬@g_›- Ê1e™ÁŒãÃWû†Ç;µ!/:lÔnöàÎÚYe˜kÀöë0{¸RK�ôõ\ŸSêêo±ãOHÞ˜œs>ª2_=ðW'{ìŒüb}Ù_±å³IññìÜ6>ýP­ã¡8k‚&fÖ°ébyî¼ó£Çw~×k�×ÿ½ï=þè~Öñò—}óñéŸþ”íãÁè"ËhÒ Üï›Ç|07ü l’ü’=ÿøú?óÕú;�ÿÛñš×¼öøàß\¯\ò€>V*è=Fã9>øyGƒú?ÓFøèw2׌XÞñvÿýd˜Ä异 Ò9œ˜XS›‹ü¼À£¯`{̬ËÐÓÖ8:Ä—õ*ŽxÇ‘KÃ�Øô•*d´ ŠÓWùsÿ…@üœ[¶Œ6ÛážpßpÆ ©^'�¼ �+!ywÚœQ\¯‹iÔ 艫.ò=ë�üÑãå/Ññ{>ã)Ç­úHù:èr~S�iäŒ1»‡²í€­ —ð>zçÇŽÿã�¿|¼æ;¿ëø•_þ¥ƒ7}ÒßT�Ù\¼Îï M�ˆ çä£vno™Qk9¦Ÿìs|xR/³"¸{(­þ³.Ä ìÐ3³ÅòŽUç°7™9§xܲ'sr¢¡ªðèg©„öØ9~p¥I_<¦ñÕsh}äœ›á€ø'ŠhGiâ8¯Ãh}•–Pa˜´×©·ýp«Ïý›aîþ½§Öª¬|÷6œŽXífäxvÅž:¯ç3U°S÷ÊÁXâ<áq¬P0à’¯¬ôÛ1£Çëâ{üwÌÉsÂÚ‘câ~^äg² ›äĽT.æÚT›ÁÆÅ6t¨Ê€a?–9b6©8u¿Ñc_ðyc¿È·÷˜öoyR® pÃhN6ò5ßD˜›yóл`–èÔG8¹sÒ±",삺gòƒa˜#ÓÅmŒ<‹y47_²…Ck= º/ðš5:Yœ–âÑ ù"gNÐŒ-NÛ&a4Æ2uæ9¦½¢ö:Xç1ÇžÜ�ŽM Ã#3BzL‘?œ çžQxj+÷Æ'Š-õ®±a°y¹¹c˹µën_{‹3·Hv 4_Û›‘­[8Õ¢aÔ0‘ÐÌk³W›)ÀñØÊåùø!®'ÉŠq3UJo{Â=&–y‹B¹¥6÷æ×\4Ç/´Ѓë=³1ßè¶6äÊÕ&ºãšß`Óhì�÷àÌR­�8+âÎÑ…²ú� œ}çö<ñRK¹Ëg¿Â•¨CùH9ŽN‘Ñߢ¬/Xû4áÖ :‰ÍÐ ¾Ñ‰­zŒk�ò»>ùá°–¥†ŠÇ»æÉ½C€=^àœ_Ü~l$©Eœ¹Ö¾l3‰&ÝÒdmðŽ^Gx½¨C‚S#Ø�ÓõÊRŸ%0…GŽ3>mÛîLà7÷<IVoÉ×›yMÛ³<é�HÃz¡É2E»ýk3ÎY÷zI�Õ÷<ŸZQÓ€¤�bHz �„¹f‚XSEâд=ò~Óª)÷O'f|2À�'±ygÂâq@R¸g¤gØ `½ó‹”1.® ÒYes}ºÕì#Ø úµw^8œxe—¡Fb#Æáš²Jÿs¼O¡Åe2Ç\;GW£'= F£I²ZȽÉm“mH=}FZ¶æeï<üú¼ë;yæíâŠ%¼¡iÊiÒkŒááK$1S“H{|ëóñ¡V „y�Ű7Ä’Ë…Us¾9—ý„&¦hÇB6ÁÞqLt Iφ}áS¤¼3ˆç™ +ó€YË‘^êB˜LÄ}âw?õ?ÿôñ?þÔÿp<õ©Ÿ{¼ì%/=þÐÿ�ã¶Û‘¿¸ž´†¦½ä¸¿ì²¹]V�û´ðmýÚuð¤øÆë®é?Å>æøw¿ê+Ž?þeÏ:ÞõËï=þ‹ÿòÛ�_ú¥w攎]ï¯W…||ÂM´77É•Ô÷�I>Ç#™È}Ó¢Üù}_™^ºç˜Ä ³‡©µÒ2ç‘5Ç›Ã1 "zǬdö²› ²Ì²ÕÂüZ�nì}ìг��ÔP×.ü™TFùs„3·fƒb÷1Mæ…o8ë›Ò'Cv©èè�žo.ÛÈ7þmàÊcÏѫќÌÝ[‚õ�šS üËQý³¯6ÛÅrr'Ž)Èv­išŸ –Üù%y ˜üÒØYƒâÎ\âÖ(·ƒ�þX'sƒØþ‡û·sïzgîN }4ï1®k�W&ëmÆÑÅn_=ç§ùOñÎ)ÆsŸ0kÐ4ýÎ�kÄ[ÖKãÌq7çAÿ¦ãµ6¸MJ!¹ãšÇCn›Ø‘«©baÞØ`9ƒ ™04οnÑô!3)I6†Äú­�ð‹×n¼±è·¾¸“òÞøÍ�o²;�š´O‹o´ÛÎ|~œŠ:DI¼Çh¢>†ÕAkÜÒ½Z¹ŒŽ|cyž»Hcˆw�£ß'7:¤glåÅ…–åƒE6ã½—_òÚ§b#bëSëàŽŸr²Y¼‹ñšœ†–ÕÚ¾“Ç®­Žr°·Æi„µÞÖ±m5Û­Ü3ìG3iæWóNzçYsc1ql£ÁšX›( v¹Ì9­a0ÎMŸÚŠÁ�„É‘ùe ÁŒÐSsîtãMCå[ÂÉå:��W!ç“d;&ê}8t¯ONå”Ù½#=?«|;XŸw:Rí²VÜh[8WHa´<8ô…Šý‰Œ} Þö?|°¬~­X5ì Sg4Ér8Ö+ì*b"†U.îJ ðeRÜ t�ã2T 8æsüýѪl+Îh‘ç¤Þpe[•=?Á¥h ¿óT”lùûm®ÆµÑëÊZ0ThÑü4#ê8.“ÿ\ðH&ìA1#}ùØ£‡è̵Þn—à+ƒš&³ó¿œÍ>qò£a½®9\&´»�?µÓGÞ%åêì<_œB|êf`9ô�†x¾§ó‹$}…‚ek¯`6—\Xzíã€Ã!llÁ­±®“ '“þôR˜ö“Ù“\Nä ãüá/S¢²£³9?ì×F$}aÃ/ÔîÓ9­®ûÜ¿ÆÉÌTxÎ7ÞUG½÷r%Dòßwï=šÇ{Þóžãö¿tûqóÍ·Ïÿ¦o:¾ú¹Ï9÷¸O9nºé&Ýgù :êIá ÚÔf’Ùô\ZçˆìD¦²pí±„��nÞ¦¿øoý¡/<þÁ[ß âðþãï¿áû�ûñwX3ÇÙï Ô9bù *Z˜÷ãµð28Öš;NJÉý:Î9•*¡Œºñ#l æ=/}!˜lV3ëÆ%Ho9¦ÈI69�aòxg2t“¸ùæBH+Vq½­L8“š¿Õgf­‹>”ví4$�Kœ ×qAOœ/æˆã)ŸúÇðm·_ú%ÏÐGÇîw‚è; Á/ÄBlrÀG!Öhi¾ÅL^qÔ^HÓ°?ãmZ¾à‹¤©‹ãx<�š¹kÉ9@?Áœ0E*®vâêCGç0ѧ®£–5Ú[Ú3'¶Ö3&uËá|ìÁàoõLÈÃh-ÎQ£¸Í~� qËo\WDœœ'jj˜¾ìv²ìÕ!´�/î·1ü¶5gúa±q \Ÿ š³r5øóà—õxì[2ýZ<ÄË®¯]6új›7“W;‡Ú?Ù{€àМû_À#Dl™4�ó%ÖÑT$i>9úæ�ÄBa’á‚—[�µ-Pø\6Õl&:’ë$ùLC°Fïg¥šxÒû\YIÉÐ>Ór-ó°+'€æ« /«g‰±ÙøÊ}VìÌû\ T9V#‚ÔÎa¯Ž·ùV­Ä_j%Ê·0WsìzúKÖæsœøàL™âçß“~FÊ�ð®£9ŒÑ¦ú—®P,�¡F1�&ò`0�[oeÛó9�; ¥ zzÑaŽY¯œ&:cƒŸ­û�¯d²3-åäìóSò‚žÌÃ»Ö ´ŵ‡ÖÎq(©BƒI Ø÷z°Ö†½ÜN¨¼Î¬=üÖ5Z¬‡›¾Ø&Ï{yÌ{e³ò“G¾…UÎý¹D+°*RË¿ëuíbÕæ"|ƲРÛ⼌ÉSã53·rhÂËùñYÝÂ1©¥Zš‹�¶+x¤géåíØ¯½a]p3¶äÌ l öfá Gë% 4i´Ÿ° >|p³3Xä9OfÀÙ=1Õ¢f¶q•DZƒ ›™Ú.T…:~{ +1û°ÖÑãhÝŠÊ~â£'Øyë©b¸ó^u‰tTg¦…sic XÅc ÈIãcPa'�{¬x$ “Ml&vRëÀ=­@CGNÂgQZÇ7ü&†;kÍ4ÑX­yún.ûÉpò¶FÛì9¹V�ƒfâÅJù¾à½ö ŸýÖšcdžÖ5˜µ7%¬üI;s Λ9륟 6�¦Ö9Üåu ¹ -a°p,¿L â’B~’ë¼/Ÿc…—\c1æ<Øüá´Dkïy²"Fßιæ£ßr4w,:I�/ícÀÏp-£¡çYlƒY=Æt¥œþ6×Ê=�hûêt X8ß³ç ò؆«ZåÔp3û IDAT:Ïy^£lú–®¯A*PÝɤ“��Æ”�2W||Ýb^\“rܽMæÈµçë¢ËCà/ †�{°žcFVú"‘TD\ô2/ qZkçH°piï8šä;Øô�Ûa´\΋qΔÜ1†º ™ã¨˜/¾“<Ëöš½Ö1Ç·…D/Sm ;c¨íî…—SËéZzP¦²�Vò؇žúà¯]6-Á\œÏƒ[ó36  ªí|1pÉ™Øèü�ÁçݪÛ8`‘å%˜Èã¿yD\~B¤9ïr[ý�Þ�õ#¿Ó�)}æW0â–ž¥ŽÚ…� „å‚€òñQOŸS‡.ºÜ}|ßßÿ¾ã-ßÿ–ã�<óYÇK_òÂã3?óÓŽ‡=ìVéR m,ƒ9š šáõ*µ¾Ä$ Çl.  P´Þ þGèï~îSßñ·þæ_=nÿÖ—ÿíÛôx³þNàÇ>þQ_¤‚‹‹ä£\µeÍ/_ü"R¶õK !ü[oÁÜ Ó™~¼l]´¾Ž\Ìå<Îó9ÕÍ×䥷n„Dh–yŠ46ëáÆDCLÔí5 `î_¦*�Çìð¡™‘lÔî ³Çöø°1ÆN¤c°…¥ëþÓÞñçwõ)æK¾ô™Çí¯z¥þ^ãgúc¾`Î-‚eìrq±®OSk´ٴ´ Ã'¦ýýØÇï:~õWÿŸã;þîk�þÏNÿÍW]Ÿs®ÒøŸãˆÅŸXÑqáö��1ƒÈ태ÜøÁŸšc=ûÔGÂy¾ØÖØì¡è¶N9}�0´2¡tú)혹m0özb9·îÃàŒo—ÑãìrE¯okªËC»b™�Ÿóû‹6ÐÔÒÛ/Z/Gò¤óȯo;̧־(³Oˆpf/°ù�C|QG=(ˆææŠ?æ}î(Ç®L®",Ö´]Œ¿¹Éíõl �ûä¢ò¨UÍ™§WÌE5Ø­¿ã\Ô“1µ5{t$ÞgFrÎ}¥QÚøÜ%™z÷cÆP„o„°›Ú®¨Ç‘Ý×-¾Ñ„ÇÙá÷í…½Œõe®ÕÖâ”^€Ý‡%›31=7œM:ÓSVŒ-!+ç8Ä=&32\S ¬ç¿± ·oGZ©…á×1à1pzAá|��M>»£÷’3¼�ÝϪÖ>™ìn?ëkz'rc<’æsMdÅ-Þbµç1È8ß8ÍÙ�1œVøBn[ûF_‰"µ{£UöᵆПq^öö²ˆ ·xÇ}Q’�ˆ^Gü© Û'$1Ve¹&¾÷­Ö ßà�ßü`„˜¦¢ÀcІ9'S]í?(çkáÛšXœS�Õƒ~(pð©KkøH‹kF{¹ò�/=Êq1TqÕ]_9ºßh•f´Òw÷a¼Úµ,âSÎt™ÑêœS�rVs÷ÆÚvÇx%r¼»‡œæ"˜y\Æn=s®“xòŸ �Å*C�#³Kå8�áº(g+`±Ð~³ÏjzÏåvpèÌ'NêÃ-ÚÜoáV]u›|üÅ /\0¤M�â?Áøùa”lb/ûø{0Ú$ìn¢öf’Ù�s¦ý�‡›hÒ8¶©´�šÖƒ¼âY>acnëJCY×çÄ2ðwЏ#_z¥.´;F�øÌ�¦ð¤M>…ÍA}‘³kÇ MzT ïÄœ›<úÖ.©‚w�ü9� ÉÉ u8ÞÄ6L.ù† ÚšVN–½ú“3 5�é~3ÏqÐÒ53/zl×6ï=-�¨m¾ô;.D˯$Õ]·µêM�C÷ø“[“ˆ[!éSËJÿ]ËÔ9‡öÄ[ÌÚø…ùɾ%J-Á%;¡ž�ç&Á亪 —_+°šØcc?*–6K"ˆ19œÑOH0E@5œýÉy»øªg¨Ì·Í“bËcƒÖγ;Ìó�çB‚`@õ¤fó„Â5®¨hbi]Šñ±‡Æƒ çÔh·<Ûœè eSròû o­r1¦‹<Õk‚án,NL«çî°ëHvö ;ñctžœ±\Ö‡mø=S­}"�fqNzç#6:°w&[=ž>)§ Ôï-¼vCØè›fLáYµŽ6\�ÎÂKcµq×Ï&må_öa`í:t§ç„y¦íú­øØf$2¸–³kÐ}üùä<ýJ¯&)‰ݯ…ødƒÿÄÛ�ZìÖš´ú²–Ö|Ú°óBØ�YÂJŒ3\Ý´¼¹Ð#‹k&4ui’o¯±öØDCò3_c¦æ­Y{¦^òj�‰oǪ5Ö-œ¼Y¦6˜8¨òkÉ/Óö–s7?ãÉ`4» ÷*-À�cÌîºëÇOÿÓŸ>~êgþ§ãÉO~òqû_üÖã™_úEz—Þ#õ_VùG è,G¹c¸¨Ó‹ø[V�CkBË”çIÏuÇ-7߬w =ñx鋟üÙ¯ÿ}Tùg�ïþîïöG@ïã¾k3Ý×£ ˆºPÅߊ£&8oÐñã¢.öñçáz¼ÒCÞ-§´Ó÷ M²Y‹6ø|~p-Bƒ²xö²”GtD>0·ªÃàc’s- Ðã/.Dõ¾š¸¾ò±_�æÉí§58íÄ#6ºœ…�Æä–/³…1õ\à”›×Ø¼3í]ä}ÞŸýsÇŸûú¯>žð„ÇêÝŸ7ú£à&špž%­¾,G'çžÞ¾««×}Ò†cö»ýØñ¿ü³Ÿ;^÷ºïÑ;@ß§¿é¨8‰£¦Ü uü ƒöý…Ìqoþ®Y¸\ç;¼d–�ó@XÂ>W8–"Ím�¾œÅÑW–œ£¹]Лéq.d~ÙL¾‰-TgsËG¢£Zº(Ç5š@^>?µ^ÍAÞŽ -&‰‡û�ûhÐ ¿(B�%å¼ÀåóÑ�yôXxQ/NM’ûÄÓ>8–5Fmé³Ç)/kÙ᜻<çdøÇïÜfƒkn¨‡×ºšmËžc^=„»ö 8Ú§™ÓKõzTl­M ‡~غÐÄ0ÖñŽÍ;Úxýi÷} AÛ®>s‰sÂÍéKÎÝä÷ <, ¢þ£ÖoŒÜK¯‚i/ºDLu6öö‡yF£œÜÇ<Èu—js<ãÍ}+Åñ3ùÚ@LÛ0¯¸ó H9,1õÛǺrÃVÖÝ^ûŽ]1ýï9¼—¦äH”1ÒR©N¤ õ€oŽ]FŸÃóœpå†'N+¢Ây‘o<ÌÍå•ã£5Ï ¦ìÛðj°67—lí¯/ö`�;ZàÓtf%Ùö.b‚ù™Âh�ã�Ÿ¡Ø‹“Óüàf˜“æÕZ{ÇN~ôå‚|˜¢ýà몮™3;{Ÿœž·^ö šz9&ë7 ãÛ‡øPË�‡ŸÖ.FãÎ\+C`YjN�Ã2 ²ãI²}âñ^O ƒ%4'B9ÑŸtÉ6Šk="•à Œ7Ø>/àJÞÉ)wßáÐ×=ž‰$8œŽCw€¹2r¬ÁDZú0Ðòâ­Ï<Ô19°7¸‹¹rN V¼ñÊ_¹‰ï°mta+¾þÄfU-^µLèG§¹œK<Ú_ålBÂïØ½60ÖÃfDš8“q鋹åO¼£›.FóÎÔD›¾ á¸ä�S³EÅ>f[ŸsŒÉ¨!làlÇ•vcq? 79uL”ÖÈ*‹ƒ´ |«›ë—mæÄ$vL)/ßî°òN6í“ö‚«¶d@†©=wa{‘“Åp2ñy�ÀÁõöÐ ™héphcûÄLádZ,ø ÐÎ:\'~@ã3vDˆ)ú«{ÆYW-ìsd¬A ÐÏg쮯ðjèzÛ»î‘`UÚ Õ©Îs‡€›‹;­1¥ç¡ã&XÇ6SÇŽÑùÆÞžO‰ní‰8·ª‰+PN�ºñùâuO>¨Ûý {?*äc€Í•ÁýÃÔ�ïþù‡hò]‡cs›€èüMe.šÏíE7F³~à<^ýWþ²þIÈ­º÷¼ãÏ|ís�'>ññÇM7^óŎ˺}Q§BP˜�µ&^ãÇ86p¬ñutÍ-ü�·Ç=öSޝyîŸ:þäW~ùñÎ_üåãoÿíï8Þû¾Û=¯Ó»¸¸¯rÏsíý]8_£óä¶Î„\ˆÎ9õÀ9àȈ0=¿ò \ÂsÛÐ^ K/q1úꚴ梊õKw�—s�œâ¦£ÏÓ�˜��ÆCÍá.ÒísžX¡uòcsŽ-hωßÇSù°óCŠyÌc{¼úÛ¾íø²?öÌã‘·é¯þ Ë·âwÝø>>ZØ·äãûòtÈkǰ™A>yϽÇoýÖïwÜñ£Ç÷¿õŽßùÈoÑŒè…sÈsLDª¤¾àâüìmVÀƒ\ðC"þuHƒš¯P4vm§0þ(£8�¼¾š›}ñë¾´@“#çìühâöAœ¿Èéd ì;ËíÌ`õãzv~ô(¸�‘Öµñ#š\‘‚Žô„×1>뉋!Ϩv +Þ]ésFó<�Ðá½q3%.Fï™»ßÚÇn)Þ  hb²×V6nÑìz½~ m~Œôƒ‹—[oˆ“ß½3WŽŸ)@ޝkbO~3zà8µQcÓæ>v°Ã9rÍŸ9Ý£–rDSò&-áÌ>µÆW}õ§î-Šl@œ†Ô‡C=.¢ìŇãEûë×^�ŸÑ½™tÜs£²U›¾^p>nsØô“×ÚèÁ”0÷yÉÄC@riwÖ’zÜöº`iX§¬�Mƒ_(S;û<I’P°ÝuÅšãÄYþåâ´°*tzä6Ë}ùÌ;ÒÎZrœë¶]Hð±%Àz/z�|á…Ú™�õêýÎ�c¦ì<&lïM]Ùëö ÛŒ{ ,š–ªµÈ=B�IÐãxêDê`€)Þe¥Xçq<�ÑZmÝ›«~ÁB'Ü¿'ÿôÐyÒ�•YRnR˜ú–&q¾lI5·¼ 1÷ÊX³h,+‹©+=¼x¨«ÏÎÈOd³Ïy >lî“{ãú£“.�=côeáû›§î�h!»5C‘ÅP(ÃÕ� ÍmMn²·ør•ß:(Xˆ78ÔÕ×5¼Ëæs¨ÀÚó˪jéñqœ°® ôÂBL]=öáÒѲ†DñîÏÇî8Í«þý¾²Xö}\÷qìEÉJ@ÿX+ˆ9q´?ï´1Ǿcœ\XÈ/ƪ"V/u£¿þ:ýAqLÍ3ó‹x|5š_¾þ–ÝZ< » ñ›. 4<4râÀj˜¦© ŽªæR\cö"7Ýу!'vcÙk­s×6õYÇGÔHïM<ùÝÝÎã�kjí;4õï:LkØù¸ Ÿ‡¥Ë©¹ #—X0=,ħ§¡)Wž‹ˆoàI’œ#§¶hÚâgú`;‰ÃâÞ,bÈ¡ëª>ç�7ìŒO Ê™»�àV/ÄÝÙðû~µúÊñÑW´ —ñ ž8ž´ñ"n´™Û”ámýpñ}uôÓ¿‡‡ �^ˆÏúÌ'ëÁ­ÚYS'·ÍâÎý=h†_÷ß5Â~â8·;rHo]ÃéR޹#Þp­(ój-í¶ö֚їT{qÃHÌ6Uàô³|)4¦h!¸½=c§/MgVº(0Ø×~´5«Óá ¯'Z: ÒÒªìÛ7 ~|Äò¥Ç,æŒ=~C�[»=�S€âxð/-õãñ©áðƈÁG«Ôplô„�wd…15;Ô½…B_<ži`â§­_ýöD‘€t/dãyF^ØŸ/}ÎL6s‚÷ãå}ó‡$‡þiÈ'Ž7ÿ›õ7Ù~àøâ?øŒã¯ø–㩟ó{�‡Ýz+'¨ûN<£z˜»ÇLÈ‘¢ÌgÓ˜§4›.c•“ÞsaêQ�z„>šüEÇ?üÁ7ï{߯ëï¾åøïò'Ž{î»Wïþã¿ôÎù� e&Ž'æÜŽï»�s ìù»ƒ`˜ëùWÞèunóRÝûY£;ØÅ‹”.€N“¯k­˜'8> œ×ç jœçJáGƒû .J–+V.r×A}“p�·\Æ�Y>a¨§©ó:½Kòf½»ò žþŽÛoÕñ´§~ÖqëÃnñ?¹0{䙃¼.mlVTôò�ñ™ÍZÃˋһîúäñþ÷ÿÆñº×ÿ½ãg~úgŽ»ïù„âr¬h—Ïqùhîé'žLw8W;sHˆ�+�ˆòoG±�ñÑ©~ iâNLt´ŽðÄÊyæ™Àø;ˆí2缘\bI½dI63›4¹­Q®xÑŸ\ÉKíDXÛm/Ñ{\`‹;ä2JÅÜæÁ£»ùJœÚXmX‡j"îâXuÆ>ú–´æ35‰�£N~¢g„F˜ïëâÃ_¢ó|–û²ñkM~¸2ÀV'–é¯Aëña¹•éù™‘äú,ÐÑŽQLìØøöÙü§N¼®‹=J?úXe=Aù1Œ?HöÝ#ÛE=Ξ(�Û÷êöÞáÔ›^l‰y¬4ƒÖ`/0$×(÷ÝçcúqêÇü 2Ø–|yRÀãÕùK'ûöÖ·y´ÙA|Yçâžà\�ÁuÖdÈð^œÓ«çãT êúë~X2ô…=¹/Š´”øÎ¬<›Ù�a*xô“Ûœlæ N« ¨�¤9”W'ùùZƒého}=pÕŒ¡+Ô4Š-¦¼­Áõ/Ý'.bÁ×E¶„t™{r˜O^ŸO¾¿ÉÜLiÈÒ–Üä\¦¦M^¯¢ÄY³4˜kò쥢_<~è‹o¨\ÇU_®ßˆtÎW.sS\8Šl�kÝ aœ(žè¤¡°\âmŽh!LÚ¸oMJÝîh>±¬{VÄwx¦up±v¬s<`Y×f 8&O>úm˜;ª‘û¬Î݃®�(¬þ' $*¹“ÎYÔ†¸íEU\“+ãJ(GC>3ைÚj¯Oëõ[¹±%šæ�WdMKìÆSmÖb»Œ8j¾ÆûŠ1s/†«},JgÏ4{±ðq2·ÙX·G�øTA›0pºÿÄÚ6åLü$ƒ¸–ág׎ÿŸÜZƒt†ž”�„ƒxçŽQÌí#›°Ì‡b­#<1à= ísÛÑÚ~Ì�?�&ÒHI¾Ñ•dɸê.¸]Ìèœ8ÛÀ-µ§N}]Úµ;p|Í•<]™ðR'¢Ñm=ƒ³†áÔ¾��l×˃ ùÑhoŠ«k4Q‰�#¿¥žp ô[ú½8dé 1¸±ú8ìåºv t»²NSk#›×ŽŸ|#©Zõ¸½î¦!î‡è¼fـŒöÈœs§Ÿz„Úbðç¶rêlOÜ«:ÿþW(ãÞ:»Ø ·¨­Îȳ/4â;‚Ñ¡/ª83Ê)P×9*è%fHåm�}Ýež~úÛ&âX7Wx¢�ÐdsÉ,äpÚç'§ ¨hD[b{Î\=ÖÉ[õÑ‘ìNe¦r`ßçd±ÆÈr K#`�¥ÎÓS³+æà/ø§~4ò½l¹82çÉĦÎË~œ±šÞ$ù¨!{grë��wÁ Ù騨jYõ;?›pq.vÜ€­Mó)�µqãÝ‹èîùàpïìu8ûü­9\€Püœ€ú†Ä•q[ÇÅV6¿ ÑG.îçþxÁ ¿ùxÒ“?õxÙ‹_|<ëY_r<úQ·åÝcð8F¨}¾%EòÕ™ý¤†Þ öé_{kÄ âÅÉ#þ°ãiŸ÷ÙÇþŸý5}<ùåÇÛ~øŽãÍoyËqÏ÷8Ö×`õÎ@°ôÝ<¯áOÙñî&×cÆ(åYz’4ç95¢ˆ�¼¨fdí©säyxq¦RËs±`®iôÄGÁÜö{.ùïñù"ÕeÍÑ­~qÏÄ�ïœNMüâÙ÷Ý:uNb»á¦Žï¹_w¼è/|£>Úý„ãf}Ì·|á9·è…Ϻ“zP(óZ€í±`ÿ€ø˜ï�»ëx×»Þ}ü�oÿÎãÿÕ¿ÔÅHi}€wòN0éVs¸¿Ûý>÷éíy^PŠnkÖñք۟/|$»Ö|D8µ€‹Ø¬á£/ñÓ· úÎAü7襵»&¸zN½>Î µJ^½3†¬ð'{r°§4‚à-eƒù䜛³�p;ÕþÄŽo0ì°§wøNÁ×'�ô`;uê9÷%÷qÛ?íN¾ò%ô‚Q^/X{B^Ž!<1ï �¿+—ÐÁ‰=5¶î~ž+'lI¾_ì›È³µàíÜ VWaASƒA e«e,Õ“<*Àýl ˜XA|îËݲ»9ì¢;Ïe2w¬íÁ{ Õæÿ¢Ñ²¹êÔõh9k:·‰ ?“kOÐs$~²å˜¢!¾öm߃cŒPsŸøÓÅYlƶÁ!‰¢�PL?WPÈ7ºó| ÀhÐÉ[mKƒ½D‡'^dæûOú2…FÃBi2±¾�…?º9ÇrŸjE[€ð„ŒÙø¹ÃFÿq1à ®÷´Î1š¼¶gbõ=�ý&êXÉ�Áòµ?sr.(`ðèØñPž~@£añ�MNë<œ#©©¼ðd§_Ó ?\¬¿0ŒÃ�©icÓ©uiJ`ð»î}nVD)ÒáõNéw½š3®Îñ7_Šç¾RÀ±—òR»ùGqKóž=øCiµ0®j‹uê$ÂAceÎàØjä6BGFfaâívjð�?nõbåáyeïÃÌ+­­cï•1�]ZFëÔ‡ûäGjtPgB£×¹ÇDKí %£Wæ?ƒȽÎ%Ìb˜Üë“pò-8õSÊÌ9†ç¹vß�ï'¦ú' PÅ–t&."·y„aѳ÷zŒç¢š<ºÇáÇéFz®ÕHlè]« X1¹¸Îµ7zbzpÁ…eðòGGIÃ…‡Ú¬ OzÑGüä­VÛ&�Üâo†pyeP¼lY”üáÒ�lý�x°ç kçiè0íÇ,ÇçF�qÄo=²û ß,ÇVîSßoŒ7®É  •i½�ÞS?éåÙ�ÄÖ^íÇ(fâ:ìªðáYÇc`gïèÙ–cÃîvÏݳµ%ê‰Ë‰4óœç”c³f/Y­µQ†Ÿ­Fïëò?xi"¾gÌáâV’9¦´/\f‘»OÖOV'ÔF¾›  ˆPøÁä‡'±Œa …û’#B_&T;æü-»|_0v9æ®ÁüøA…cë±m%ï™c‘;)±¼ LFö™éZD‹[ý!‹Üyzk|p±‚ 6úùÍýæñ×ÿ檿wóñœ?ýœãž÷µº°ôD_Xâ1v½¡ŽÐì©QõyŸühó…;” Œê åXßróMǧÆSŽW½ò%ÇŸÿÆç­¿øáÿ¦ÿ¹ øk×üW¢û¸Á׎¿G¸Žcj€î@ÙY')-Í;1ú˃Ø}‘©E]é;çTï[¯ ëžÈ£ë^s¾0Ñ·„Àwýu×Ë…0. ñxpêp @bÕ˜íÕ:O8e Ÿý×�}Ü�—½ì%úõ—�òÇ|õñm„é›»¸Kߥ91´ÆqÄ\ü§Þ�|äNý=ÉŸÕ?˜yÃñ�ßø5ý]zqƒ5 #h9;§×"gîÇxòNÀÔC^²²��µæ÷Þëz¯×»Dc5ØýeŠÝYHʘ=;~8¿éFÌ`ÈyÚÛ3BÆÁ›4¶1O¼—ÞÀT.ŽØ~Ÿb� ¨i¯11V$Bkç¹�0IW¬ñ[l²ÍpÜšOeÒ1LÙ…[s3(ÆtZã6Efæ4¹7©çªvð¾�ùFVÒð›;7HÎ\¬’¯ïJ�®?Ú(Â}7—no9‡ð1ÌàzöuælÛ£î±%fw=�I×þœ˜ó˜pŒóK1Їs§|‹T4y˾}´W›Ö½k<3íz¢ßèr4œØÎQí{UõÚ‡CÌé0#uŒC¶ÅfO IDAT·1ÝÄ—:sŽó‹Ž^Ø!  qÑ�!±6ÃÄcÄ%ü¶:Q„7zÛÈ̽._Ï©$3_ibšmnc§ß‰Å~ƒdš #¢ñ×Ú¼HžÉÕÞäxÎý6|úÖç6fæcŒä‡;ÎÜ6Mƒ5|šøø‰¨¿ˆ#ÒMÄìLä¼–<|øª)u‰Ï±&Í¡sN|úæQ�5_ÁŸš¨ÍvqÃã’@.í¯Æ1WtÄgîjÝÞýo¯¹R©{AOôňVg ¢k0àv~Ö ÇŽööŽpzïM}ÃGò±o:iá¢�C4wá^®(wo4ãf˜‡f†ûÈc½Žê‚�ï>�Xœ£±|ÖUZ¢õh‡Ù<j`v!ì³fj³ú¬1zfr›_‚íZ ¹ŠÅ1àÔ¨žhCczœÄñû˜ [LâØÊ¿ñîÇÐ<[€�Ñô#9… ŽÖ=÷q;ü~Ó†yr\ê¿ÆÄé«ûÄ› ïM‚°c8}@âƒkQ<¡ä7‹áM\2"ÚÅ*�'ž J逯Í8mÄøæœ“×•xšhÝìT“~’$>ìyq@‹÷±cãÔiäu>TÑ`ú@ß½CÍ·d·¼úCîA²U#÷‰Î nïŸqêìØÈÏp¾LÍ1Sïšu×™cž|€r.îÇÒV<êWþ£ Úl-á@–~ÐãÛ!ÀúâËX êÚ^Çj'/Î)RöüÇIÆÒÁzúvÁ;Œ0ȳØG÷œ«+~bY»~Á–~a…�übó[‰Ù“„ŸÐj®ãØÞ4‡ÜØ·€ž—͆sÖšÀçüÄ1¹½§V §ÎÔ1hëpÛ;< ®îk ÕÍ.ê•Çp9§–ûp¹M=‹ö ½ ¯[Ã|Uç®ÍµNÞæp~mŒ“Þ¾Àïý�kP¥î+¹õS<¾iŸUTö‰Š¸àçþ„x´k9‰ºx&ÓÉ‹.‚ïí‹`þkkjÖy¢˜ „s�éáÈbHš?A宎ô€cÕw æØ£ÝÂ…_ºRCþ3í¹§ª¶MW€øÂlŒ¹{’Â*çMjÂP½ø9+Rp«ê9‚-Îh*a©Cû¹ïº?N­\ªÁö¤2ž)ÕÁásEýbÎñ±MûÄ;!¦Šò9º é >ŠšcvîWÉk^.’èb Øy|óc“æ´ÏÇ„fãôtŽU�™ùz"7©öÔ/¹+ž|5P#Ã5)‡sûä¬.½›ÎS–OÜwéãÁ?ô¶:Þöß¼íøƒ_ø…ÇË^úR½Cﳎ‡ë�z×xÛÂB¹ò±¾ø%•3 0Ç´:ΰòàg€¸Q�ð �ìñu_óÿ�À_äïþ�ï8þõûþµÿs0˜ü'[éUàµé‡k–8Þ�¥öš‹~1øÛ‰ ð¾_ÓZµÛíþJyg½¢epáçî»?y|øC¿}üà?úGÇÛïø±ã#wþŽr“_aóÀ¹‘ì2|á3ÌÞ* WÏ+î_üÌ{Žç¿[‚¸õE¼ü}WÝWËjO¼·Sâ¤ÕÇŸc�âêä¸t�D«Ñ¾Ç 5>gd�«·íưÖÑö2ÿÀDýãyuMmè&�yÐ¥Ÿ$†½öä.oôGhòãWñ!cežkœzÅy! iÜÖ=�Xãì—ª–;%Ù¼v ÿ”gr “xC2—Í÷cZ-=!"bp¬æíåûf<·ezÛ ÂR>Ç\ð4€%íóL–΄më�s&±hl|»#PêŒh&�{N×7¨ëõ7M¤i×cz’ƒròÑôwNµÙÚKìk€ULœ`¹D¤úóØâXa{»9}gyŽSBú7ׯ9û›‘ãJ.„4Wte½Ç Õ,èA¹VÝ2rÛñмdžõX]o•L;ƒƒPƒíâÕÜ)Ç–sAþÁÊ<±Ä$ªz/÷øÔOn×ÔÉ}ÁÕ§ç�:‡9Ü—`�7Mˆß¾ôuHµ•ב‚p»bTº_/Å´i‰ÁÕœ¥É�ÔØ€ÎT‹xWÏÿ?ÂÞNb`ñ< ˆí}°PâgoȉÃÉó fEÁ™õ1T¹~æé`>9e¿C‹Äg?æiÂȺ… ‰ªáí'Ï"ó0™fˆÍ9êÌö8,2¯mêÛ.£‡‡Ÿ´Õ‹GÖ*�)ß-Îs·è2Ì~7*\}æ·©0y"—Œ{!lüyŽàg.ð?[öŬûdmXùfœžç© k—¦7¦lÞ¬‹>ôäÇ#„‡›å“ƒu3ž0Â+kÌM¦äaÿÁY¿­D‹?6¤…¯ß²†D±ßr_àé7¸úzÂ}÷»Vüì¿ü—× >ó3¯g?ûÙ×'|üó¯ÿ°½žñŒ·ô;ñrápVLdèh5µ�IÊ%çfê3Þêé׿û!p}Ûÿ ×+^ñ+×Wÿƒÿîú‘}Ùuÿž`®<î¸áGÍø‡!ëóïw1©œÖgn <¢?u¦a�--=ãÔÆB�-Ç�x#nœ/'¡ébÈÃÐ'pã�¥Õ÷C“šû…„có'­ì-bÒƒqÀVO íÏûï¿ÿúàç~ðõŸö)×;¾ãÛ]Ozà‰Ú+0hpâ ÞDUSœ§#«nÉǵewìP“÷ïè?H¿BŸÏø•/úºë'~üGuñýÙõ¥w‰> xyw£p  >Ô�›Ý]æì»\ôcdÃÄžsʶ/P~ÜL^Ðã|¹¸*?*À¼-õœZ‚o¥âÚ)V¼ƒ´/¸»�hÏdܚ̓“1 0­kÄtßì¿ûî×�2ÙzÏè]Ÿô÷ˆKn.×õ‘<ɰ̳ç„ç:iA_År½ˆ×è»úØb>äÇREßf\Ç‘½êØç”ê´fœþѰ�Ãuã‘Ómk}°©]-œÇ¦e1öÎdäΗ›Ûó�}À÷óëÄ.>ÎÅç§üÔ1¦Õ¶ãÖÀñŵþØýA-zÖD1y9'‚¸Ÿþ}Æiã,| @Æ^GG³fÍ‹µTæ^µøƒ6 ´¯3�5ç,ê/]óÿÿýkçXr:óüƒl¦ ;&ñyœøfj£³w‚‰=ãpO�VÌ;qÑÒîÖ¸öÑ%ß³–sPCŽý<•zÍ�“ÓºyÎ|dèBÖ£shpoËÒgíˆQ �CÚ±±o=Ïqë{kt8k%?.º¶äÓÙï׳¥à 'W¹ƒ™ãWNᑸÈi¦/GûFäcp‘¶é±#!uÞxÒÙW5QoyÍÕ;žÈ�r›;FHÁbÜ\#[º¨œ_eˆöø´G>xzRò ¶Y+H3á%\�¶´øx™X,0n¡,€%«mùÀ TTŽÁ¹ò×ÓqÕ{_ÖžfS£cM’Gã<^/[ìO‡ÔØ(ä‡+måS‹¢�ŽZp•¶úéŒù„ÏÚιœx£Â`<—ŒpØçñšœFFcìã€9°êcÕðˆ™<ð³òʘ=èÏꃬ³þ*%Ÿù1ü¼o×KÃô}‡ºwq[±R’ˆ‚ ý�ç#\4HŽŸožjûâÕo3Ç–V¼Ìö1IaÏOŒãSì£_,ño¹�ñ�SPüù'Ñ—OÞg#fyGVâ7ä<ØâYûIflã#CðæzŠ FýÃ3Ø~ÂÖÎ÷gÍÌ 'êPŸÍ-œ€ò çÚ··ŸL»9뿸�![‘væ7ªÈ�‰ÿìE Ìv zòàÝ Ä!FâÝ�°ž¬˜ÙŽº¥41°b†§<ÐRŒpÕwçÀz{]¹H�zç%ÖàÁoäs§~»NµŸþäQÕãúŽR�é*VjBX�ÈÇk2ü,>7±õ‚¦inD@‡¿Á$uÄ®9Ûn«—üŒqŽÃ+!IÕyåO=¾Ë]ƒÉ�h‰×ü�»nø÷¼ÙcĘfZp¤>L‘&¦U+?d}÷ñ> 7aPÓò+FñèÑË=ó;qm‚˜Á´a˜Ùáß8Ô¡c<ó„Ê»Dòø&™T³pÐØT錡ÓÜŠÏ:ø7së|Œ­Wíáᦠ478?^“>7(õâ•Wüm’ß­OU�Ãü6o§S3Rs£Íß&ÎcÂsba¢s¡kHè5fOâÒZbƒ±pôyq¤˜ÔxL�­Ô�z,¥Þ•“ÿK,òKŒ7ûjÕ@ÇÅ�Ô´ˆ3Ö|¸Ò\÷ª±þ|‘ ž<¨#¿-äóê¹~ø!Û÷ÀzÐØŪ®ýYWdÝOô©[,©`/ª…�~Â.>õ+FüŸÏFó;ÍÄç¡>‡‹4�{¸ýò¯üÊõwþîß¹¾øKŸx}Äó>R7ÿÒõöoÿlÿٮߩE8§æä3ÍB�Û#®rd­Ý’ß±áFàSŸúäë½ßç=®/ü»ÿõõÊW½úúÖoÿŽëþÃt=ø¦ßUÎÔ÷ÑëAÎMâÿ¨æ­ õ¡Æ©áœ Ÿ¹kwpIÙ`Žú6SˆJ@Žg-(¼÷ToÎqcˆ›>è8Ïy¯É?ðó[dbL›çõØ<å)O»>åo|Êõ¼?ó§®·ÑMæ¿4ßÄ´O½˜=DÃK\ãб0õP°Cf…DëféëßðÆë'_þ3×—þ½/¿~ñ~^7¬õN?_±³`𯨵T®¾>Õ<õxtŒ‰ÿq õÃ[{W_ìÐö�ÈŽ*ܬ‹;þ,Eðõ™�´ä|æ û¨çÃ<$’!_¹Q­‘æ�òY’úⱘ5 b›Ž Ζ§Äcò‡ÇçÊG´ÎYëÔ¢Ïç¬÷z>d¯œHšó'ÔiÔ¦Ãmg^[ìú¸ÆcŽ9Üå%Ç5ðù<^}ma¼òPþ¶bbïz<ªÏ¼ÛY6˜)FæXY0ù‚ÙëVTƒéb‡½oÎj}ö5:8i�ì½7¹ìXÞ6¼‘ÝÉÅ×1èÿ¤é¬WchfÕ½D¤\²!öú[Úl§fR6+cq€3Ϫs×´±=Ÿ˜f­êk&ÍYb»§ñŒI]!)-uo<ã¡+¿b&hÃ¥w�ð ø´>öïŽÿÊGvÄd~ú2®,ÖÀײíõà WŒÚ†Ï"b` Á€”Êps¬®)\xå,´ù”×ÉÑ!Àž¿j;¯+óñ‡OcíØ…ªEgm…MÀp�“²Æ‹Ÿ$¹Ÿ4öó5Ï_óXó ‹U°�EœU›‰c‘@³smñø‡±_œ[v(%ëy‰º¬5ÒžÔµó®7>çõ¢a³Éßåc{Ÿ«(@ûlö›tù%OuÓyZrw~˜ç¼/Ñõ!1y~s~'§»ž{a´ “‹à4uNw}—ÇáØ´Œ»î¹¶t§¾…À¶§sì}®SZŸ�:+4Ñ3J4ÙcÖ.õ èÎeÀèà›Z‚—EÍZc·À2ä¹Eüˆk­Ô C¹{$~ÛFrâÅŶá vÖÏkFîú¬µÉZ‚'™Î•èûü `ž+àÀXFv^¡ìGŒûüdˆ¾PCzøL ̃m¸ëÅ›¢­1š\ä\°äíð`ØF.ÅbîÏ`9 g? òö‚D °lÆÝ$‘S¤Èèi¾ˆE þpM!³˜Þ@+arró4 Zñ˜‡ ÅŽv³ÂJ'‰»hÛ?‹ V[¬Á7Ç8ê`\j Ææóó¡~«È˜‹2šù[ß û¥voÂ9ý&2¾Þ¬ãÄñozÁÓÏã5âÙF8]çæJaøí,=ºü7Ã�’=>±O®ÅÁrau,&Õ;Wck÷˜~ji¬.>‘)þì|©SñѯÖL¯¹a¿ôµçÜ ¸1Ú%~ÖjÙ¬°UÓ¡1l‡P îÏab­…‘w°§'6�é�‘ïqôQY׈Ã;¨ç¨¹™²°�…Äqd« ä¿tÃÁûTäéZl°q/§ô€á \tð6'4Œqòa%4ûžbçf úàg,ü>þ óØÉz³æ¤àÇ�”Éc�d›–¹D ÇrÍ�ÏQ y,°ÆÌ±H=�•ÜïFf`lvžäü›09æñë`‰µðs !Œ�L"RMØ+±E˜a¸zmÀuÃ7:l¯æ´8ºbRë�0üiéúq·m¨Šü�Ре="5¶ë!mêçÅÜzÎGDsžÈ9¯6^1¥™L’{x(8RùqÓÊcïÖu²¦ãÇI{÷Ù.)Öž‹9ß8Ðv¬Ž‘š—ð±2,B5B’/ çAÞ±’–èM5Y5ÞèðE©CéÂT_2¶›7¶Láž'úqó0Ÿ¿¶¨ì›¿ÄøÝzéw¼DüRýçÙ÷½>ãŸ~½ï{¿§nÐ=E¡ ßDׯéÐ#<ûÚLoSšƒmk#¹õÂà\û€Þ÷ÎúœÀÏù›/¸þê'}Âõ}?øC××ý×_¿þ¿&ÿìÙGÕ X!7áô\¯Ç7g¨_þ–-ñ8Oä\‘½Å‹–œßZÇ�÷úx_™�+hbŠC½óÎ(=t“‹¸¬y°uóO_03rxD}0³r“øÍ×þÃïr}Þç}îõïÿ~¾ééw¬Q‹ÐHUα$aU�5Y5•ÂczåX{8>ôàÃ×këu×wþÿÓõMßøM¿&'~x �gy‹œ¯Îs6þäÁOë!ðÚª?m;† ë‚M¹2NVº¸Ö; ã¯Ó=ˆõz\cÅzáÈßœ}�JÊÜøc�“kÎiÄ™µ÷ïþøÇ Y+‡�)ô€ÛYÜLR¸ÊYuÉ%Ÿ[Ç Á‡]‡pîþbL› ÎQ˜ëf�ÆÎÁ1eíï奼Ê'2bW–¼á$0¥à§uu,áòJ"ºý¼C±,C|©0<Î ¬Š@ƒ)Íãý\Qx†GNÒö¸15 ¯pŒ?;~ó£Z�z©%DjKm¤õ¼йA|Zâa þ’’ØÄ+FuØñdhvî�kÜîud*¹5¢ùzR¾Øàîx£3÷XcéFy¾fÚspùÈ&ßÒ‘-ñê'‰ñe;Tý´Œ%rõ492÷×}žwŠ�¥š°m)›9%ÙVV(mÒŽX+ŽÁ«&¸PPÊÖ¬´unk *§ï¹ÂµÔˆuó�Œ@?æˆOαŠ#Â~^¦q°6•¬±é!¼<”¿¾1KÏ`ÆH}ÝgŽÊGÁÀ fl”‰Î}4s,�æ±Á›8oóé"E¼ôkÈõº¥k[ƒ “õ¡­½Mœr˜˜zŠóyÌq½8²&˜æñF÷.cðh¬{¡ºµ/F–¸y cŸ× xQÿ<¯ÞåW [#¾±ãÚ}wÈPˆcêúê;ïànÉ&uÊØ|Èsêï�WÑœßé6lh~¼ªÏuA²_¬T<ì›GÞù;ð“DÖ@.½Õ£Þnä×gÏIG$ÌÝRkŠ�=m×(VHΜtÀòy¦öÂä:ÃMã®CÄçgøÉ äÓ¨‰M$h˜»óÞ8xŽdÆÃ8 rôå‹håK|žk�×�ž˜À ]‹ b à5ºÈàŸž:§O>‰²÷W4�]Üu>š×^Þö‘¹m³‰*–ÁÜã£Ç¸ÿ °‹ejcH7†=¹LEžÉ<ˆär&Qôc‚]´öðÁsÙØCv«øvÛ› ~´úÓÓ©~~-Ûl êW�ÆÈâÖ/`·¶™¡‘jQbÖÏãjd3á–Þ¸:lïJÔ/Ü Snâô�GÝœ‡íâdžäÔ´8a?_Ž" χHyÚ[xè:^´5°|â¯Y,c^ϼN½r¢7¨Ìmå0öÔ¢9Çæ£:ÌOþÅñÉ ‡ �Zh&ÿÚÚ˜�ÈÛ¾ÛîOëcŽä¤¯âžumÌêM½k§@½XÙepðDY¶h¬„Ën+x ×>i1íç±ÝúÖp m8˜çØþz2X±ÍÈz‡áå|$Bo›½nöE�›<ºN8¡ïÜ©úXZý©IÃð’V“ø#”_”›TžØ­ZØ5.¨¬ã¼Øb6:6Bkíßöaª¬á8˜ÎÃ(± ‘�å‹;žœŒ‰|ÿÄÙÖm@NŽá×ôÄB6€„œy Ïá¶‹aÎef±'Û—œvÛQ�¥’Ɉ›N¹Ñìh8gÌÈ7ÀÔ+üºžþ…‚cœÄJmˆ7È+± ȸXa/Ô$Iäwø†øh²®®™õ ÚÄô ÛÄs D‰'åІº¡aÛàבÚÇK5¶Ý/û¢Mà|ÏEÛmmžÊE_öŸgmøä‰]Rn Ž\˜Ñà;Ïr¡¤ßTó£-y%VméÃuYÙ'Ï3ÅÕÙÌ/rô_m]€Ä*tdÁe².Â36k¶ãß¹"»hÍ"ñ0ź| ÷d.Eõ`g$\üƒ?_Ú>þ%”l¸øüéŸù™ëoèóŸùÌg]ÿñ'~Òõgþô‡]oýÖÏðgøùÆ 4Ïæ  —›^q’'ꬮg|½D0'êÂç>ëYo{}ü_þó×G}ÄŸ¾~ò§~öú‚/ø¢ë~ñ_‰ç´ìm0Œ77}šŽï ¤–›³970÷E«S[jPºÖá3 ]7Î]¾¹D-õÅÞù!\Ø»¢!× ¼˜Ô/%e÷ýó“ç<÷C®ÿô3_pý‘wy§ë�'=q0¤Ä�x%Ññ�¾uZæcßšúq9Ä}�1z8¼é÷º^ù›¯º¾æ¼øúÞïû¾ëMþ®,¹IÆóœbÓÔsÕC�›ûÚ/1Ÿ‘ãÇù7~’ÄÆZzçß`ó Ö’ó-,bä|C]á<ÇÖ�Xy,íÞ5g}À’MÖ€E¡•—†2hí–ÊNžY—sçá¯wµl ç*Ÿpƒ´Ù›—G:µÔÔææqƒSdº ›“¥æ pNqþš‘›S’¬üÜý”»cJ¿uñ7/ù€åñlšÌw hZær˜€•KkYðoLsHYœŸ_Ðqs~²Ëéædo¼ÑeÎ,øéÏVÍÁöö•7 ¦.áQ¢JB|%•b좎ìf*™ÏÅê4ÌS.ƒ¯µÃ-øÒ™xüÐ, Û=Û1b0{Ùöø8ZÖúáuØAJsø0êã©<ÀÃ$VòûÔ†ùÆ gìÁA=CÙø1¢¿øÚä8Œ¡ñD^õUø@g�¤I1oF6?$x˜ÄžŒÐ ipÕÈùâx+?ÇÌÏõ˜Šdäí×XÖ³�öÍ qql;$>Ðúš(ŽQ,÷~ò@«æ$B©q+ö^ž/û¼däñÁ®û9õCÏÁÆ M¢e3²Ìá9L›�‘}Ã{÷œCÌán4¢mØBÉq‰ÇÏG?À6·(}áë˜øÖ�ÆáDßk;ä(6Öïè³®Û05ˆ_ã.Ìð�¾uhìiÎÓ}¸/Ž£7Ä�µÙù"ü昭ÇÉO Û¸”â¹ý—OíÊÿ0L�nP§v’ùÜšœV fêT&pó&óÖ¬}9!ƒk�Q5S›±)Ú¬íì7ìpÑó}sëàO3%íþB#¯ ²µ ±ê»8¸NþÄ_Áx¢>ß&Ú Ž’x9ÊÖ`w€ øÙW`׋ éü›±ÃŸØc˜„@Aæ¸7‹’¸¨Òò@é¸Òä²f·)¾oÐ$Ê�ÞesXÚµÄá5J—Wö\$1®Ok�;‹áõ]X¬EÒÔèóÄCÞÖ™ª'‰Yù`‚’ Í(5ó<ÓÄ€{ Ì IDATØf…ÍQCH®£› ˜�XøÎá‘Hs¥Þð_m)–dqÙÅ£Îj5wŒÙÕ¡7rãbì:„ z· ¿VIö)Æ„!s} `lÙ5ÙBëímS‚+½c »0ÖϪë1Ž�ÄÃN�A^º£�:ÆUû±#»¥¯¢¾…lWޝ¾Vmñ—­cÀ ?˸8ê]CL*Ãn’�.€ä7�2�†¯8y„p·o ¤‹]rŒÜ1dìÔí±=íA=7ñåçU¯zåõ_ô×—åW\þa~ýõ¿ú‰×;½Ó;øÝzü¶ÿlÁp Ï�»½phÚØ­u[ìï»ÿÞë­ÞòéןøãϹ>ðßùæëé×—}Ù‹®û_Tyð‹¾ÜÄ2jä׺¬œîås!/Ö4’CcóxéÅ¡y¦FjØØ™¿uþVLüïUï÷Ah¼ö�O7„ŸúÔ§_ÿñåúKûÑ×Ò?=yâî·ŸÉqò†{0‚Ö³\áµl™Œóªzpcí�¿ó»×ÿýó¿t}é—}Åõòñ¿éÝ£ºÖ6ñ‹Fqî_ ´†€�Fß±ŠzΣ·¥ÕÕQ& :×è¨5Ø(!Mk,�ì#ÎG›dÿaéõÄÞ�ã»õØÐXpÙÑ\K°V½. †!f]±w“ |÷‹zI%k.íq7v‡¸¤³ÆCrHî­‰ƒŽÕŽÎkì‘oÜg}b“üÓ6¾y¸xÔñXê€ÖKž�gs0 SÌLã‘cì¸5µÇ�Ÿýžõ_¾ÃuV#õÔ‡ï¼Cl3ÇÈ ~³®ÊgS�Okºã&ˆí|˜ùÔ¢v‡*Ð1¦ÙOæ±EÍ>k�ýX0éáL×½?ÌäåÌb_Ÿ™Ü¶ru¯ƒÍé¿ï ÛuÌ£j(¨'~­—íÄ-íˆí ™ÇOš6÷�ÏÎܘà€]YÈÊÏu»ÀÀÈæuÁàcÇHlÜÀv µŒ]Û¬IS©Y   ˆÃ¸s Ë¡×Ö:Œ0õe¾N3¿!¹j$Ýa"62ÀFKÙxõ_üä`ÿ„ÄÄÖÔ'ŽçDðyl W{n_LA3H  ÆÉ'�?sÌk�Ì×®Fp�xîͺÍ^ ºeØÛrRÆÂ !2Åôs⦵ ÏuÝfÙKWs`‚o0ÉÑð³m4 ¿É‘ùݦW1Á40iï‘"IpÜÈ�gl æ5ÊÆG¡æDqÐ’#6ùà`¥±™,„íòÁ¥môèb›D�6ztjD™ò×;½lÊ öÎÿÑÜ}œ1 ›¸Á7cy�·ŽŠë±æíc¯íQ^á°2²Ǥœ#3$GiŠƒíF�Ìž;¯b G“9l`†O‚yfìÌã|YM¢è—ÍŠ«®3lÌÜ\¢çhžèÉuü«mž\³-޶ÚØÖù¤àƒ’ŠȲtÌÖ©üà�låäБ 4¿}Z±±‰¤xé#r·*c8GÔS?›œãú + �ÁmÎÆ°~Œ…�¸ç•±}GëZ2/¤…4¾ø8oæ‡ã³µ7‡1Œ_²%Žãëà^ôÃEÜñS;Ç1hàô�•‹b^�Ê×ÿMl½:Lp« æ$d9~ðR8SšúàšedDZ{÷†ïÒ“@òõ7ü ø¨–9rìôƒ[±—WÙ¸æÅe}&”C¤¢ƒC}Æ'¶Ã¡\Ì °±“‘™š’dÃÍñ±±õ2)³lèT¾-1™¡©ÏŒé$;}áš<Ñ�>‰áXhÆÎVŒÈ>£[?|Œ%Î�EßKF´E?³®¦•:½áÃÓã g�é‹Ó›ÖÍ>%?˜×„Æ…šJƾ Fæ±%71nA9|õžLøáh+ÖŒ ç¬3c~Ü$“—ÃB«.Ù0Ìëß}ÉÜã: ‹€ˆoã“ ‰U”K§XŽ'£Æ±~RVÈòé˜~ÅÆ^scÌAoü¹>ò₽="c""oÒçñ}Ï÷þ“ëŸ|Ïw_ôÝþèõÙŸõY×ûÿ±÷õŸó߃áà|‹žF¶ÖÍúZ†nêëº1™9¶æcßÜ´zÊSŸ¤?K~¯ëEÿ‹®ßÐ;Ú^òÒïÔÏKõ�,Þ87z&gÝèâh(ï7øpãsnjJãÚ™›|æ&&õÚç»ð…„åòç P3?ò%o„²ó/vTã·ùCϺ>ÿ…Ÿw}Ès?àzúÓžª¨’ÚÈ(íÈÛivŽVãÖjÕdÜVG¸6ç ‰dØûóý^ÿ†ëŸý³Ñ?TùÚë×ý×®‡õ'Óæ¬?{3Ÿ�)Ž<ŽüŸ“É,Âò;s ¨SÎ`»fÖé0q#;÷bxàŸÜÐ!;Ï4q¶(° õ4§!&–×–ÏåC¯‡ô`Òˆ½Û$ˆ†µYz‹¥¨™ ÝfÀ9ãt<ëѽÐx8#[õNà‘ðÂÅz`á5Ï%­ƒcCtâ{îCëÊàT zûÆþvôy�Â{ Ã�  'YtèiåWŸæ°t¶âvz¼{÷ï°ï I_¾B"˜æÄŸ²‰3¦˜ìÖØ‘ 2œë£ pvÊeyᑵJm]G#+ƒ:§‡uØ-æ+öÍ –©ã©�qqÚë‚Öù£#‡â dÖ-êÃÔRÈÖ~€xà<=Ò!û 97Iý §<‘E'F6Y‡UÏI29T=¤óˆøŒtZXsú)?�j70®ò±ð͵õêsÌZ°âF5â¬@X]êP¿±Am[º5˜Zº@KnžCô ¤â�·8÷¹o ’k&¶™s@C”àÓ4„s1ñÇ֜շީÁàjRù‚© ®“•€3~¬½ýÀßÄ$cûuã²;>aÔV-ÅüsufßÖB�P¬5ñ²/—�|⚉Vbˆ!ÇòH½K]/xò® WÀqBF;âÛ¤vÈ36_�S+äñá&’ßÅfÉQKær2§8ËWX#M!dä–ÜÖLÐØ9Q40�ñµ¼šXù±éZ!¯n‡)ïhàiÀá®rTkÔè‘yr ¦S’x`¬c"ó`Úo®zZL‡A‡}ñ$t€±š©÷ø¢%cEÊãiŠSN•æ5äØkáäh®7uÞ @j´nü‰omˆ„{ðsl=®ßþY%?~‹½rêM¾eo”¹)$›Œb‹Ï¢9“)‹±nê<õõÍlÉC�˜^?y�X:ò‚�LR}ahOÙ/…ñŸuœw°ÁùæIý™’…çæ* õ<6ý@]ÏX’ãR¾•çq)qIéæÖ8Èï_ýÂ/\Ÿ©€ÏП?ÿãž}ôGý‡×Û¾í[û¿Úöqšwm…¾Ž%÷»�^/)lSCõpj3‚^o=ñ�'\ïòÎïèÏ üäOzþõýÿô‡®¯úª¯¹^óší=pŸÌ x}å¦_Þ±Gœ«p÷+!r´ÌçUE%8\ÔòÜ—Ï“óg>ÊŸ[Z¾56ïó¾ïw}þçý­ë=Þý]¯'éÏ|ùç&^£#c�=â•ßaã< ­”ŸŽfæŒGî×.ÊõAý™ï«ÿß×^ßþÒ|}Û·}«nоAŸÙøDùMù<ªÏ¸2¤5à±Ê�Obù¦Ÿ€¼?ì›ÁTËÞ�r�Ìl†? á„ÎqÆxû›õÂcm’‡FÄœÏKÇy[™}Ë>|Ó¸ù‡aˆ§ãôŒË;cëÇo9Ø'zsv%4—̘3‘H±ü¢Êæ8"„CÆ|s˜±j™üÔcKÛ6¸F²K. øÞ¸°<~‰'‹•¹!JLz^ðõ�-�'6+`l€Œ–.�_édØ_2F_ìØáëXL�æzƒí8Á)%ck'Ç®Õ/(:.¸XbÖxƵØÞÐ %Ž’ëË{ÆPÀI\Œ««}ä%S/у! ¸ (ðô Ûˆ‘mö¬ýp¤=~¾Æµ>v­%Á—hÒ9(†±ã˜7aW®|Ü@òÆrß ç)¸æ£¾k¬­Tì]õ±Ótžß6üÓÎbœÍ·k€"ÌÁm-Àˆ-BûñÃ(@æÇ~™)ö×Q£®²�ïâ�-Vx<"5)¼'xÜH‹ÜôC]̈ÇóÙ .YmÜ<kΑßÉ£±\¬Äc¯}Áº¿4á ~L >ž9 ñ,yhj.H›ƒ�q@¦9Ž�ãn}rD驱 ƒ$µ2Hê"¥9.û¬ºŽãâÈÁkü–cðá@|}�®uƒ:RärZ6³Ž’™Ÿ-bçáÌñ=k“8²[øèǼ‘;’Ú 3ëup5¾|ìV››'6[˜“Ü&CdãÄÐñ¨Í¸û%ÀQáOkü¾»ÛÖ¸ãe7ûÜ»:lü\OÌÛr¬ïðÚùs!6û¶6N'û¬üŒ#;_KÙn‚xÌaæBpæ‰Q8£§ÕfûakÍði�ljÍd†¥÷ƺÀÙ¾§éŽ3Òá;Ö³°²BU_ÊüyÖ-Rfcwä›Lr 1,c×ujîÍ î}|#‹œ•ßu_ )Ìú·¾‚ñÚÖ¿>á‘,OÞ©Y$ñ3a¤ö+�e9œ¶ÅÃŽ1?Í£ŒKî Òè±!/›S— C\Ú¹Ç0ž›S9.W¼ìÛÃÆ‰Žz ø¨)�ÏTæ‘s–%Gl`ÂÇÆ×àÁ\Ã9Ü p‹…×4‚“ŸŽLܼ j\“;8 ¾Ñ  9ßÂðÇvä»1Ó—DÉÞ/Ç—SlcOÞiìÉð‰l„‡·¾}ãÒb†/ rL ý§›m ¸à³×M�ë½Á؉¸)fôšóäü×û³ÞˆcÇgßs�.‹Ô^óš×^_ù¢¯¼¾öÅ_w}Ð>çúÌ|ªnνÓõ¤'?àÇæÌRrŒÊ©›i:!pkŽ‹ÍiÏ�7>'ð™Ï|›ëãô9�ñçþƒëå?ù\_øÅ_rýÊ/ÿ?×£<†úâU˜¼C‘}BÎ«Ž ¶^(OÎ�KÏëÃÆ ~ ‘„B­ø,Â'èÏzÿüÇþÅë?þ/_ÏÖgòOLRÇ�7XmYsÓèwzd´Ê§tçãÜk'ÇGôÞô¦ß»~ý×~ãzÑWíõ?ðƒúÏ©4üg]ýèŽÐÃÜðÕŸ;bñ¨ËÄȇ�ë<$»Üø‹QöIãB³{Æl¼Nä LÊŒ¾¾Ù;Ìbœ�–ÃË`ïÇøÊ%-ΫÍþÐh¦öËçnÆ�½Aëžö¾^|Žç…1<ëéõ̘HGÿCã<ÇÜ0`ßðÜïç!<¤ì‹^¯1"é}l}5æ®E6˜§K6ºþ²u+Á?0O;ФSC™kҸ Ç�FžŒ?<|``ÎÈø¡&[Ÿuµ-æð/T9X¿\ܵÕ|ôÞƒL•ŒEˬäïµ»‰¹ÙµÆIø ‰<�=ÕÄyØ"ŠÈ¥W!׎k¼ll]®'[çÈo�å[Ï&“šÁ1{­^å'N¹,ÖµyõQÇ«ña®6]&ä�í¶q]°(úlš˜¶…[*™š£±Tý€8yJ®ÇYŸ±JKßkol:ƒPÆŒ½Î÷ôž? ­ �@›Q±JË,Í-L—Ü>âiA½H²µæ«þذOèåUS¦&k±‡RÆòïåJ\À@~ðÁudõ o‚ñ3ÁfXζáñL›ŽáâÎX_؇÷mœœw£Ãέ†šò<ÓXQÆÊ繉çXƯ 1c¯£Ä®•óeÍ~¼Õ¦{3z"ñE|Gí"`8/ÛÕÒÐãØÔÆc�Sóm/]ruPFFì¼ÊÍzkÿ`OöÁRßr²|ÀÌ�}v^Vb"¹1=–÷ØÁ ›ÔK#éÍ[ò옄£5¯Ìö±u‘©�Ô9ÎÆ´j©…ÏE…±Õ ÜO8@eÈr�|"±46gðÏ6yPƒ�“l Ð5Ô•î60j«3^AF#ID_«�7ã–Qì–Íã „A;%8è¸Ñ7� kç¦ Ã.–çøYy�"ÕHÁ™¢[QÄ ÄTmIeãzYVé!ëœà…Þ…–x;À3É&6*ôGCç'�˜Zã'�ƒÓöâá–5Y±ñ€šû»è‘Ã/~M~ñè1›±³Ö:QåGžBr>òç+ØñHö’‚móÉ6jewõÈ{áØ m›ú †˜ËßùLœ¾û1"³èYã±ã]R(qå…U&Y£è«V~A#3,ñqŽ<þãj3ë&úUW�+ˆû8ë:‚Ü”H-]O‘òÍÿããì¥õMaïs€@?zœjˆšlr#¦×¾¤¡/䮋<Ózï‡ñ[°Žñ’ ¡ˆ¶°¨™ö67§�‰^?¹'aÛ|NîऻY 6d€Ý´ð$炚ŸÚ�m3¥w½Hzºp��,våW‰­ñœ‰ÛÇ 8«–ÒÙß�u&XßiÔúލSã:V-ÔßÚÜaã3õXnE¨Ÿ¯ì\°:©·‘8Ù)t7DVqg°GÛ¨Êø »6È9cµ‰˜øÄuÒÑqRÊüVÞ”à|&/ig!Vœ™;G�ûÜIlü“'¨{C9®ùm<üZ“.�Oæ°7Hã@8oüŵƭi /¹�#Öº ·Oäð!›/¾pO[˜šfœccbU›öÕ9? ÉÕÛ3�I^Žg"ذ^§llЇ_ê*÷U˜Œí;dŠ¿ófƒ�ï²'æ´à‡GlÛ¤ÆN]y"á¢rÅY¸¬[b´76œ•ì•úºÐú j c¸Ú»1‹��v÷o¿ˆB–ƒëYw)[‚öÅcnP ‚ÆÑX¶ÖCSk|qbm%Y+°ôC ÚÈk·s,éð¯ž84×þð[¨G=Ú5çBbãlÞælücŒ?1öEí<ž»nàñB�¦±_¬H„ÕÝ7b@CXódÖ‹D\‹6uL�Ðk¤¾k�UsM�w„>x‚äEŽ1;‘q q��û€GÎvCí6¹¯í´~Óš`ä1°Â�²#óÉ«þ�±_MO›Ö«/@ŠÛuÁ§u¡–½x£-z^ðçbUpjÃlçØz'iDÂ5@Û�ŒÊ [Œ4ç{Éãh^Ë9v•5¤ÈöÞCfín9æE¸ãiý clÜÐKÙéÅ»¤–Óã_tŸxOä‚·ƒ—\�^�0 |¯ÞF‹ŽXÁÌ:ë°-^¸`›‘óA™�± a,‚ëz"v ÇÎêÞ9¾´³žÌÃIÕ“CuëÆäDî¼!{ŽŸ}õ ]þÇdăKã_ü¥_¼þ³Ïùœë)O}Úõ=ÿ®�ùèç]ÏzæÛúÝrëâÖ\ È@?mçœqçS¯½žgåü¤�0î§§>åÉ×ûés¿ú«¾äzå+ÿõõ-ßú’ë%/y‰Þ-§w-ê]€¶w>‚Öœ\¼v­‡€x眯]tC-¹éÜ¡wÔq£ó=Þó߸^øyŸ{½÷{¾›>ûðɾ!Ôüoòh>gn•5§Î§Ÿ�KÁµ§Á󡇾^÷º×_ßýÝß}Í×~íõÚ×¾Zç…ûÌ7çlUF ÉÎáŸ|x.çK¾¬¤\Âã¼A|±MD‘/)È58IbÝ8Œ;æÓâŸóôˆð-†ÔÉL\Ø7˜›¶(�8<§ „; u+Y7½|ó¸ñ1ßãÆ§=°I?pp0r à•CjŒ}jËžyQã›ðö㽚ì[3Ö’Ú¥—Ž0sÉKh(�mÛ=aßR›ÚòU™}ðåsœÞšÚÚÀ騆4Ü„qÂp}ùàƒêf櫯oøæo¹þÇü]×ï¾é�â/__¸ÎYDçb¹êñ»G?ÈÖÍ?©Y%ÿó‚I‡Ë>ÎLNá~h3Þ Àáœ4Í#çɈº ªkÏ8 œb\ÍÛÏS">. ‡˜/?Öü³eŽt€ÑÚIFÌþ?&WJL&^8 o”~á¶ôy>Žƒ=Ùæ<=„±…z¡F¾Æ�|P2túµ%¾{x>Ñ õ>ÕtË…ä€NG%ŒçI|¬F¨�”ÊÂÃ`"B×z�a‡thL‹øyQòöÆX {Óór±ºeÎDÇàfšœÂ#7á9M†`¿uˆÌÔ±ÊI­D¦ïœáÚ|‰€šÇýnØÝ¶ÍwµøF–‘Æz¬$æÒè“êoÿ•“4HÁî�±êN&f9\7eyÏaEm®öˆÜ6±Ûû©\è·bJ¦< IgBµÉ:¤žŠ…N*亮lsDÌdÇ9?�)pÑ%Ûkž×Øñé3‡áDMƒÊ�¶v�u5€eøæõ•äB œo×ô?1ÃûN¸" ¯C+ÇrC›kEžD‰‹¾ycãšÊLü\ ÏÒ1[>“Hâ̺€kyMŒÖ 0‚°�¡ ªd¬9ýø{ÂÜy„¯†¦“;‰ã%"çäøÖgc‘Å'ôl~£”X¹¡Z}5¹ðC’úOέ—¹�¼;«Ë¦Ì ›PkCñ ÞcRˆ=£¤‹½s²F3j�[Ü*[Ø]Óy"_6 Žý±ë�ð›20+)ÇxŽÄ©½k:²"§ÕŽq¨c_®€“q“ÂjZÜ3±:6ÐD•\O£š†›!vWWnŽ  À›iÅÉ5ñ¨Ÿ› ø�9Ç5� ~�¢ž‘œñ–Pwÿ)viÜ`!¬/Š£!^>ÔSó1 ÷½Fñ¥ýtètÖi šõAåZ ö¸$ ðº 7ÏÎ}�îÈR¨S@o†ÈiÖ =˜œÀ½4ó›ò[k8~I#Hý¬™bŸöøõ";uKáu0s‘@1â‡nÓƒ%ÉÕÆöÏ/v"GjƒÄÙGóf]l¡AˆjZtK†Ô~ót$t±åè:,…Ý¿<çœVáöü¿P¤‹š#«f‚c³é5ÐØÙlxjìöú˜�ü³×¿øÉŸ¹¾à ¿äzÅ+~þºÿ‰Oº}8Ïmoq/±ríãçwå÷€nT~Æ >ãzÞŸýS×[½•þÌ÷ pÕƒ�S2‡+'GÎÁë>sßàÒØkÛRF§à­±lyÇâïüîï]¿¨?gþò/Ñõã?ñcú<¿‡¤Ñi©¶×½ª¿ö:Oâæ’(ŽŒ¸»€÷†�Í�hư‡8XÉþ�:rI0LاvÇܨIÐ9é íJ0ÖØ|751dG±f_Ò|œñ¸X^>vÓÄŸ¨¸÷òÎOÞ ¹ðm~{” Ckà— ¾ý >*Oиñc¤Ç¥¿0Ñ\ؼ(E–ÇJ°ÈÇæ†ßèÇ{œÍÝRÈ�'+i,ÅÛ\]-[Ԍަ® ü¬ÌÁãáÔçÎØ” pS#MÁK RdF¶,°Ÿ =ÚäX,KlÜT–u´6¸ËfNHC=Õódã ÷žçŒ"»ÔSŠÆp†­3p<6ü>†¼Ý’ÇÂq:çZ%@ÃØÏa ŽÄ£°©K‘ÍTìôS\õpšT'/|l KÙú[� 0Qáî1³Øí~ bÆÄÍ82M-à&H¼Ÿè <öŽ!­â$Vê’_ff gû6 Û´ ãjÕ‡sk#¦“ص³ÿp1ËÚ€þ1O>ß#.Þ½Á bhÄÌíz¡ÎÀ†,R•kü™CŸŸõ6E„4%çWÊ(iôÄÖWI­…rrIµ²…+·hÀÀ;þŽ9°K¯9Í:Ëö“+¤Ñ˜(iöc Å­\θ¶Ag‹ÛÃÆŒ–9£] qg¢fÝדø;îÉÿ¥@'_^.zAÕoܽð2Àf!��«ín>K©�õâV;ëÈ|5Ç‘ 'Äú� 6S>s4OËᕽAÓ­�ëÚ�¸•oÌð±ßà¬1ª©¯Fi’5«\(G›©áªRߨ‡¥‡Æ �äòj¼ßQ‡ý 1Æõ`8&~ü Wjh'f“¶ Œ]ìæ¾Zy¦$²cÀűýl QÖ'5’޹½£gFÒXI èÔÈ- ™Æsîu��íËA˜e¤žú0O¿\4/V­­“¸þ`eÝÒÇ?Få©� $ÿØ÷7´C@~8n~Æ!ž!Âþ­n}»7Ñ¥ÄO âpÓ,¶Ò;.€2áÄ­óc¸‚�†Ím ' “+óݰ¶�Œ�\Àñwí5Ihu¹­Ûzì¨xùJ0€wˆé]ß¡QÅÂÄã„sO©Ý$·Jóûõî±4M0à}Ïõˆ¾2fî ´<…·eá€n1”:•™½à|3ïF†4`§|Õ�ÊÌ ¸áh¼I(ë"Û9÷"¶/ÎFˆ{�,ÌvEc=ÖÁç϶\í ¢�â&[ô¾±Fmäÿ˯xÅõy/ü[×Óžþ–×GäG_÷WþÂõvÏ~ÖõÄ'>as5‹ø–ÎÚ3Ò‘4`–U¶ÃÎÁ£g,|N 7ñþäŸø`ý³’oÒçþòõ¥úü¼Ÿúé—çFšøÞ{ŸgøæëÝßó½®ÏþŒ\ÿÖû½·ÿÌ—HÀp0´©¢I°Œötìx¼.{ܱµ}Xæûú7üŽn˜þ„nü}…þÁÇ/ëfŸj¨rrC‹Мb±ÍZ¤ =ïæt `nÚ!Ç?j¢õ=qB¸ÚRÆÄK…*Çí·ŠÃã_Dl“ cópçžJ~êñ䳨 ¼öïQ@ôù%Yêš=® 7~�íóùÌJcúG�]Cãš©i(¶8¨=~ÚRûìí-×H<£‹¥ýÈcpëï9Ê”ÏzWlæëf4ä>Í#×ñÈÁ‡«¦æÊ‚Uw'®³°}¸/ ÙÁ·uÖ$²ö�u BˆSóÛ³dZ?hc?Lã'ÇBHÖ0¶øÐRG<³ÎÆÑ´xÔËþ¶–ÂA_}Á¤z� T[,|MÛ¨À9Ü•�¹j>8ÅàHÇÝZ4__Pºwc ¦Äv£“_#Zì¹1Q ¬c|Ì•Üù’ÈtÉ ”|¯þñÁƒï½£¯�ú¢bhΘØg0fCdàSLxõ—ÅnxHé–˜Kï„PT«ò0çÓï®ý¸…Fb$?œ˜ïZ¶Ž®Ÿ1‡¼ù2Vw\é¤X�+leb~~¾åq:u³œ� ¨Ÿ^Ó˜ƒihn±#câkšP¶Ì¶¡ì9®9ÿkjçá2˜Ë>ÖëØüÍyüŠã×°X:J†³Ö%BÕ˜yF^cMø >Šø¯\»sÛö µUOÏîÌÍ¡œ0æ[sÖaì�É̼8HÇ]|/nb´¸à‡íf=á6X§~åhá`°pjÅ&�Ž‘¯œÇÙï×êWçØúÈÉÔtHDP’rß6¾42N®˜�=½®é˜óÅwÖ‘kD𓆠Ð-=“kñoùFjWÁ æcBĈR}tD¡5ưXq–�Ìý Ä7«øõˆ�¹ùy’8þ‹íð?n‚lÁr€Ì�ŽœS U½Ae‘o‘bzò&œø-¶¯Ÿ¢®3uWº)¡a'Íhœà¼{ ì”�/né-�©c@dz¡úbâhm¬ ¼UY ñ�èµ?:Æc§XkñŒÅ\1œ$PÇÁ,v*‹ñÜ0Zþp‡(7ÿè¬pØ.àÉÞËb•˜ÛR.¯eŸêˆçV­±k>3�§.®Å‘·Sõ!y—ã²Ê¥y;¶—ƒCɰvK^þC²òúC}Õ{ƧŽà¬É¤‚…cÂÃ\¬Ü<*›”dN­�:<ÞÜØà�œ{â?jÖ\鉃‹_ 8Vâñ§v†»ðšGåá¯rg¼Ž{ÖQëèÚÝѯzŽ|¿°ÎM­ò*V’Èìn],¥ƒår›ÒìsÉá}k7s ƒ5GûïiaÑè§~;^çÑ ªÿ®©¤*jjwè`^Ƹ!Ñð7—Ç–³Ö›ûqžp8Ù.î¬Å¶�Æáˆ¡˜8DÆyŒÀO¾2ºõ_ñØÂ6½i‰¬øy–øFcžfIž£ÖÍüHÂy´ôˆà†—™§7Þ EemmË'¹oÚTÀœ½#tèÃÆÆŠƒ�>S›/GfÃÞßñ±^Pë —ÞüCçÌ,Ó(Á#Ö±ùKm‡-q¨�¾û¢Ì�AÍQ¯:hüûµÖ½aÆÐò;N'½èIiˆœÏ3ö-ƒ�¿ë¡óÑÔ{PRâBÞ¹�îM›ýˆ±³Õ�ҘϹã†>ÝÀ¿æêý§s(¦ù&Ý‘R†�wÃYœŒ±ÆÐÁ‹u>€�ŒCùx/BÎúö?NÀN9pÍÅü·_ÿÛú|¾o¾¾ý¥ßv}Ð|Ðõ©Ÿú)×{¾Ç¹žòä'ù[T×õŸ#&ᘖ§Cͼf2q«M8Q¿{®§=õ)×ûý›ïu}Õßÿ’ë7_ùªë[¾åÛ¯ïúžï¾žû�Ͻ>íSÿšÿt˜?Söo·ÇË Pã6¶ú6†Ž52ï!‘ÁÞ\1´Ÿê§¯òAÌMºõ.É×¾öu×?úÎﺾñ¿ézÝë_§œ¹¢Á:/Át­§ç&ëÚK`S\<ˆk®f57ÿð…#ŸÈ^ª]|úœ…œs_Úøhb$œ úÉ-‰Áx)Šceš\13w�Å�ϱ÷°ŸòŽ9œØbè4rÅ tñ½W�7¬f8•­€ûÈRcx8Ë1<óMšpãcFð”¾ÏsSÜ»uD¶ý4¶ Ù6²a'£‰)½±'aפÓ‡)aQ›phŒÊA$3Ûø�±Å–êÆˆéŒØb¾q¥»ÏÀVÊÔÖ$žÒhÊXÙ„±äë†C„Á/˜I.G|ÅÛú!¬m4wÆf,¹©v�‘µ¾erã·ò™hÁÄ.†©�|Œ 2|7.–‡‰tõ›Í ¹ý§?óÄ–F…Œ ÷0‹œ91§'¨¹é &æÈprFØxÕa»õÃÂø£«°Ö±q½‚äÛüÇæ4󇓸E–æ'½ýÐéÇzbµ¥ðÜkxæE|÷·1µinà=ðl¬0ÀÈìwŒ�7Xr£e®ÁÌéÃÕjàpââk?´Â&FR‹/fÐ×oë“XøÍ”ûØ¥Gvr¼ÁÇ…�±[1‚]ÿÄZN‹òƒ²dun¶·Ëf/ZûL“ÎêÔeáZ“}é¼4oþØ8¯¹Å ùÀú… ¬V~ ¬ J�Ó/l,*¿Ã¬>¸«õ"1.Î݃yL¡¹9ç-LcœÑö;bZˆûÔ�r·vÔâ¶e޽]Ì ‹-�={25j°jýì%Ácëh�oßý•XË"«àÕœÌ�ŸÆÞ Òg;ŽÈi¸&/yžIlb­1Só¯<öMÉØm}°m‘ˆæ’W1ËLFÞ—¸ ãÙv° ΜdkD«í5¨(Ö©¬¼F`|au~Cn|æ…ª}G�c§¼8–‘{LY蹪­kÀü&î,_í’2N_lm¯óZÖvÇ’eÙYEÀž1ùë("�½Éœzqã�šˆ.P=øæ~Ÿè#ÏÃŽ<7O$ “P/C†ù!Hê‰eò‰n�MD:äg-[7¤Ñë¥ÿ¤Ao&ÐGŸ ‘?ô懯ýñ½~äÇ~äzæ3Ÿ¥?þôëßûãœ?¹½ÿ~ãQƒÒN=`ùøm¨-%|Ò ÞqïOzò×»¾Ë;]ÿù ÿæõYŸõiדx¢ÿQ œSåm3*N{ g¬aZ#G8½×UznL½é÷¼~õWãzÑW¿øú§?øú3ß…Åú™„_ëï� Ò=ǹÊ7é„É¥¹±Ý±¦Ù{ JŒúµ‡ ã¶-qXÖ5�ÿ^”/{c'‹Éi2ö‹„ :]ƒéàÉDªiÞ=øÙ³Å—Ø!0Žƒ·´†ÀPxcí÷ŸrcÜ–Ôvß]¥6‰S"ƒcO;ψxà;€k¡÷�:Ö’£g¢VÆ­Y¤:*Ln@f½©™}ïw,½×EôqÛMÊú!tLåhàq¼á�=zãÉ1ü×(Õ~±Uýj6}÷Cû¾ ªNNÈ;¿‰Ý‚qÙç—8Fì\ýÌ/d0a°sBJ"^/ôþÖ};GŸém9‚ŒÍÉ�ÁõÜ>™óBfÅX©ù`)€k0t,=]ð>uF‹OÖãPÂÎ9$Ì“C÷f¡È­µ7€ L»É Û¾ó$šxP?÷€ø{¤)ž¤A[ê5(‹xÚœ:iŸ¡qŽuÝvéíÅãInñ±‰Ç©„�r R›þy`¡ë:Ö4Wø&6hipÊ(5ÄD2j哾¶èJ+d%ö7‹®ÉhÊC½}LîD)=gà\³'ÂÃRrêÀŸw¶ÅC³M"*Ç#ÉQY-YrE.‰çÉÆžJ1€ÍñºÉs茈ùäd>z¬pÃç-¸ñ¨ç£ü"åÑëþû0wÞÑÆ¨õç�=úÈõÛ¿ýÉï÷gÛÁÓ¹&<»ÞDÙñ2ãH*m'_d¾ ·þ0rÈP·-x.Âqã;Ÿ IDAT‰wúñC\+“ª ºA¨?g}øa}¦�ä}±ûªW½êúoþö«›p\ÏûsÏ»žÿqñzû·¶þ鯔“þ;¤l»FçØ<á§À„1�¡è®2©Îæ²èÁú}N ?7ÍÊÉš‡VXÇô\’Ùó6˜úr£äá7_ox㮟û¹Ÿ¿þžþÌ÷§~êåÜ1õãÅ¿ˆ˜ÞWr¶?XTräÎ ‡=×È*í|«÷»àdšºÁgÎÂÃ×)�g ×8/,2Æ5ãB}­º{nÿˆâ´ñü¸áúˆˆÇûÔñ%˜úâGÊá’LPØR'ôÙØitøñÜÙ\¼Ï8ÓÈ{­×�FÆjÙ*Z(À›ëÃ@ê`ͧ0 ¡Ç2ð5mÝ嚃¡·9Cdɱ5 g®oQÉ8ЂñurÍ5ï/"˜Ûlž×ƒ?Ç©cD%53Åp\M=/Ù³ßÚpoLâô²s_=’àAÜa×ã*óÀb“ÄŽ0Î?1‰}r¡6šKÜsZbÕŸžÞg#¾‘4¨�õby¼v.Ø4ßàõ´ïx4êR7‰Ø ÓÝRÍ—~ü$Z\mŽœAr,ŸXÙ€Æa¶ùd/PÚæIçÁ&@ãhx’óTõQO£?ï�87Ù'G\±8rÕ”3Lâ 9tXZ‘øš¦u .íÒúä¹È"Àˆ ‘±_¹á¨oæÉoÀ–xŠ­ —O+hS@´÷Àw� ЋïÇ{´¡PAPþ‰z(&\ùÚÀHŠÁ—kÀn«Î P˜ïÌÍÃqa–@ÖOøìÉÿÅq•+pÙ/Üe™]m’õ¯]±ÍßFÒ¸¬Á1G¡£ éËÜÆ.ç©kÖ¬w÷²4×ibVÛx…ãLMÍ}0·_ ·ù�Ôõñ¾°A°b3È%O‡ÌØüÍê6”feÔÜœOº^®“æÖÓÏ&mYïY}ç9ö*¬ñÂÎ4õÎÓ2ð$û1 X9­^{ÍÁÜð‰÷R–»odVTÙ˜µ}ü¦´©fh|ý3üÕí¦ëT%u‹¹lî;X-H• Ž^°‘Àj¹PqʆAJÜô«ÝšÜדŸqÆÕñ ƒ6gŸ$ÜP‰àwCÈ®œ‘ ]˜ ;yÊ>Þ nü‰[�™Š‡qÊGê1AiãνyÆ®µ=ûÅC/.Àå‹jkí˜×¯ºö˜›‚IÂ2MíoÜ%…‹¾9‘96Ĭ#jg,¿Åy¿ùˆõ F¾í§N£½gq“½«ñÝ›a8ºFµ«Ÿœ–Ƨ/¸Ö ƒoÜôí)¶nÓ/œ1(ÖJ1ÖãÆABÒΛGb�Ó˜Úæt+‚èYa«d©‰_„‚<ŠÅI°®óÀ{mdd™lÛ£^<ù’�»…/:Å$vðB"ãÉörÆ6ç†c?Ù�m'Gª·íT‡„:œŠ!…Í\à`w;ÕבW„«¹Œ£œì{{t'þˆÇΫTÌÆ¾ÉqøM4Y$ÖÎ#>Ûšùò,¬'ûküË_üH¾ièÛå� rÐÁ„%†¿\OlcWPìS‡Ø¿ØÅCü)÷~“¼øAÒ±…œ–¼:[½íÂyï´åÆÔÌ÷: Ù˜ ×~Â]Ͻ½YÈt×äŒ�FíŽ(7Î>ÑÈ�+‰ˆÏ»hp_ü5¶4*ë}h#¬ Üáf¹ñ3Ç·¶Ô;u: =[0Ìã�÷ª�¼[rñM?=Ýsï}×?÷C¯ÿâ¿Ôgè=õ©º xŸÿ¤•›˜Ü ãGüú¯ÿæõÂÏÿ¯®ÿýg^.TÞ�¨âjä½÷ù ³\±B‰:MÃ^ȸ¹°4Ãyû€O cšwžsW¸Ü�Êšt~>׺qóPŸÕ÷ÐC^ßñ/ÑŸÃ~Çõ>ïý>úG/Pÿîú<¾§\÷qÃVaÎý²ùNœòg ™áÇÔ›;|‘ªÕ¦=²â´Ç ͽ·åTwsbnƒXÜdyXëó[¿õÛ×÷ÿà]/~ñ7\¿ñ¿Êf%ñ€ �ÛJ®ÑÄ'ç6�­ßq`2,ÂQL$! ”›€�#[ñoÅÅ÷.æ`@ SÒ¤5MsŠ(rÀÅ.²ÏU'ö—�lÚ>òw-‡ r A4WMÈ‘Ç87¨17Âiæbã�²%— xwtÚüË0ÜŽz¹#u S Å7êÜ0”ô<†÷5ä@n¾q”ÃÌÀÔßüÆÜ¼Çlé°°_�c~ê]­ecèÔn|[ßÑØ?d6ObÁ©_¬ÍÙfÑo+G]¶¸Ã“þ´iL°×ºÀÕö•á¯`Ò„dsP1ŸËn²È/bi BŽÔ¹ó›P¶©apLoŒ£á>æ-› †iÖèôo=�Mî˜$ozykß *`Ö›zØObT;väÞWÆ‹®1È _öcÏ\Cï6u�͉�Þ1Vµ~é§3&`’ÆÕ1±è�æÅ_~ŽC< }`<ç&¡×_¢H�ÇÅ­Sg¶’½óïlÔpÀt–s©ƒÑTò®ÕÔ¯µ°ûâ0`A¨ÈØ_ntˆôŒ§_9²Ä5sûUn9½XÛì«7l¤Å|×'P½;Ý@³ˆ�וѶ5t¬Î3‡sŽF´©œKxÞ!¾ù†±c/ [ªS6ï$¼&xƒ±ÚwU�íG9 ÇÖÁÚŸ³‡lÿ p¾«Øïô‰x  Ù'¼4ŠÖ{í`½î¬$ýG'"#U$©Ûùì“}ùä5,ƒib£½ÚïR88tÌþÆ÷26ù _OêC‹âB}Õ‚ýZ“æ`1AÖ�Fö£Ç¸r¿ä໻舺ҧäê™ ó{ªºš˜ME Î’¦>Aì’-}!Æ“³�Koç„Æ xyë_XÙ§CúSÞ9‹}âm­cðŽ™²Ðaõ"}¡—9Å•ãäÖ{j¤�;JÌœuygë<œ–i‰a9,éÅJÞ=$`F{n‘æ—C¹·VòjÀ�¶®½�Á6;eãi€jŽjÁ�v¿ñ±ø¬Vskæ] ™¼ñ5U ¾ñãö:À �­{ÜÂæsÁÌư€,�6íp¯®Ù—3|‰K­×5zHŸø­ÿ&Îç ¼Ï)b’(«Ë/{â#8ç)¨£e¢ä¼û-ÍÁyÝÉkâ鯮‰E ±ŒÆW­,“Ð ’O�k#7œÂç‹¢§kO‰á㺓õ$ W¼SÚì5‹‘óÂàx|{^íãÐ^³NïI›¾/¬45„|Î ›ÇT5ýÁMÝ|ÒöpÖÙS/7—®½³ãÊn·{Ù/ŽÈ %3ü _/ìRH²çÆpü|¡c¬�cŸ˜øìѲ|ÔÖó –ÁOöñ“rÜØ{å­¯<¾î«ÿ�Ç×}í—>Þñ1MøâÉA<ÌŸýÙŸõøž?ÿŸ<~ð‡ôñÍßôÍ�÷}à—õÓ€òð·Öä“‘�ûѾÕ5s|èŽ�k/m¤þ”îú¼N¯EÎ=Ú©+µ�‘]ýÉߊâ:ÐOöéÍŸ/t#�¿ØÿÞÊþ±ÿùÇ_óµ_óøäOù”Ç×|Õ×<þ¹Ïû§ïü„�÷ä¥f†ÏS’mÕlÿ8G}œ4Ö`Ä3:³_y<³»û-£y"ÃÎÛ\äüà?ôøÅ_ø¿þ{þÂã{¿ï¿ÒOiþßâž›³·ÿZæ'õÎãÆy‘50úíž+s®3í B°é~q?íyØ\“"Á+…[ØxʪÍpÆ25×îh¹ð‰¦�¶Ìömj®vì×—ˆ!i8×¼Š÷ÍœÉíÉ€ç'þü˜’°>ž¬Ññ€'˜Õ,ñ³Þ¬6\»k¤–!Êõœmº6¬"a¿/³…o½IK"¸�@t,Ö€qGµ×°ŸÊÌHnô4/¨ÃÕn9vj4ˆGSÎÚ¼@³Ÿ*s >« ¹ó�ö§Ïí!<í­9}PN¿F:Õìè=Üä6‹çžOî+1ô¶2%[믞ÎxË¿í²ÍPÂÇ $)-åh¾ ÀÆâó1aYß>XÑz®–ÖÔ]K×ð"ÒY?Ÿçm•9×ÉáÍ÷¢é¾†ªß³xnŸÑôÓ¹’6ŸÏ0¤›Í@Þ3Kz«õ­Y¤æµÖ+Ò˜|��¼ÉÓÏ£)9=sø­·9°•¸Ø›Ó±> A ÎßpwÀžÔ ]9A)xéÏõ�þ …ã ˜˜-˜Þéš¿{羟tË”ó¾0N�,ýIë§œ³É}‰‹Tö×5¹Ý.¼G›íÍ¿`KŠàS33õ5Î<cßÀâÂf7Þ$o/<�§ë´2Ú i¾ú 7}“·]9?øsEiAºë‚ØŠSX’h"×k?¡Ã‰[ƒŒ³´¯›(=f<ú—[�Ë7\e[N'áÚWé†/®è¡>ÿmèÑ>5«[ª…PcVàÔ¡½¹Á´6°{óMJFŒyÀ`›c´YiΓƒŸâYÞ¼ Ì­¼Ð·ñ2�&úU,6ü1JÄr�úoä¡v-ùvøêbÏèì)0º^ù' 6Âhˆ¾à÷|Þãíüs B3ý~^|<.?ö×}Ìãó?ïw>~ëó}�¯ùúß÷ø_~âÇóBñ•üúáä®Fòf}ñŠÚõO?&Æ?Å!÷¹¦7ýé`ì‰ÍÈu›ÚbÄßÜXr3!Ýà[ðE ²Ëßè ËßÑ?ëø#ßú-�oÿŽ�{ü3ÿô?ûx÷»¿ôñé¿ñSo×ßíóße„HòÉ[îÜe|é\eÕM˜×¸­Ó‹ÀXõÁ;`øê›£´~]79ßÿþ<þ�Ÿþ™ÇŸø¶?ùøázÏãWuöïëÆ�åé`{Ÿž¤n÷¶|Õäžå§Üˆaôs_¶µÙ£CúNqÎe·V�¥N Ãk#ÝqæÙãÓ�¯ÿ´.×ÙtC�eÐåÓòŒæ0ô8š�Zi*ñ@ZnîbŸR™ü3{ðvL_²Æóæ#gñÍ|õXÓÈX¶Ó…ÖÊœü�w¯ó«eBúØœì“üœ¿Ö�ëÈ}_ÔôÕ„Š]P¸ïš·/æ=Æé°ºG�ôòSºÜO?ÚCj‡«š{í�‡ÇN^gÊ'ªžkÊÏž8§:&ï™ÔƒYƒèxc�©ý#€ó–wçÇôÖqgýôšÜXЇxAš% sSãô5†î]ÛSÎ €mò€Ev¹L(XîäññÄŠ‡ÚàÈãÂÑуÎÕã\²¡¢øóúã9—CÂÓú­ÓE>˜å³/šœÈáG'¼ÅÚo~¬ál-®îõh¡½{¥Å“bGÜøˆ÷ü¢?‘?|Æ…Ô &%i�ÎìÒg}®Î¡uT³a岞ˆ²iˆ­¯±šGöd¨|¨Äà\W­u^¨�nâh`ulœêª˜Ûç_’*h8ÄxÛdt»f½™Gk¾¥¤93j«ß1Ó<¾®h ÚŸÆ™P›ÆÛn°¿5�'®MiÏRFfÚ±¶Çi®»˜;émNÞò:\²l8Í™™ÊÁÜ&ÛÎa4BàêšÚpw˜ÿ†áÞk‹ mÆ6p¸€Ö^=Ö)ëc¶ÆÏ «¹ý�òã}®gMÎà!ˆ=ûé�3˜Õ¼Î+Z0ÕÊúiŒß6­�[àöu²o=Ã>ºÙE‰Y‡Ë±h}B•¯vOMÍmødç­µÙ_!Ú8+û 0âì±7ÿ,á¼/&Óçhƒ«½¹gâœoúÆ´¶!Äß¾mã'zàmNö ëB/£3k÷€#}f•xVðq¨žáj™Ìúð¯ ß¼M"ßa �Ž;¦Ü£w=ä-¡HœÇkÉ!öàâs„– ÅÚ�/v)òosTe÷Sçl}Z:¿CU¿€4\p7¶ìØü\6y ×,CR¹ŽE&¬§/ÚÌ€'µÀc¾`^ÛÃû¦†N°H‚a_Û3W•bM­µPû36ûæÆÎSöî�}ãgí`bék¶‰KM±] �zøÖÌž�j‹¨ãY¬äñÛ#ý ÎÌÄeMÜÓ¸BÓóò ÎFtÜqÑf›éYµð{0>/õ E¹èkÞÔáZ„ǧ}šÍ#£ýƲf$öÔ'‹kµsu™ùˆL쵟dÁ‡2]k®î8r¼Õ:Ø¥€ÑmíTB­ó�îÅ�pæÓ –W^}åñ'¿ã;ÿò¿øù��âæ_Šu¹îÉèb�Ú”T˜·é׃?ñ“Þùøª¯ü rã/½Kn¤Eõ°¢™ýSzv¼|^èM âÂÅMÊ®aºÃØLÅïüSO}ˆ�"ÑAÍÑú�_ú¥ÿçñýÿõ÷>þÕ/úâÇ»¿úëïù¡õÏ}íC¯?eC óß6Ä0ÆörMy¿Ç”`“k3÷ Ê#Kÿšïßÿ�¿ößÿàãK¾ôÝ�/üÂíñC?òƒ|ÇÄ?ÍùV�Oß¹O�½Õ�Áüw^÷I5óÆç'zÅ7ªùø°þÎ#lÃÛ›‘—£‚R‚æ)3<JÏ[«_ny{æ�áâ`wí‡/Ö;²ëg®ôE9\ÿìŽ@˜·U†Ø;Ïoä´g$‡&Q–…Sã¬Ë(ã•“>ä1zâ�MZ¼íyÀJxÞºçÖ™«`fC°†}L¾xz$ic`™11t(¼Ø‹ æ”…öÖK{aô‘«iZPzìð3æMÞÄi ®Áø“‹u‚Éw†psc:-xqMM9ŒìÑ|ñؘ}ì¬ëg>Ÿ»àȈ}heŠFëÎÒìM€�š?ývßBçºÃ‘ô´^<×2qhÙ.O[¸ƒ›kö«füÞO¬€v/€ÖîMc;;6¿�Vã&öi}Z•Sœ$Ú’$Z¼I^Ì®CšÝ�rß|Ôã÷ dâCØê G��¹¿n–lÅâo«ð„4çäâ@a@R�æà‰l½Ç Öd=øê0`pæôù ?)‰ó;}|9¬¡fÍ^‚×"yÏóÕúDÂzسvo&·œîÑ…1Wu âZGgØX#ór'�“øæcµŽ¸5ŒHïßk‡ßäá!¤#׿<ˆ´IŽxËo®«^¼½ÐŒw¾ó#$ë ÛÚrs#çÖ�Lk´÷SßÍ\¶'ĈØçyxÊW9ý„ Îø’ß4ÄIZj° ác®�Sn©qU:¡ä•ÓßQAÎì+C>Q¶3ß=s.‰€Ãu–g¾f®±�eø³€�¼¸ç1Ù7ºÌžë‰óÖQ.r[ÿàÂTëbç~^ÎÖÒï*µö#ftŒ–0ަž78ž[A¹é•àúÊáºUK5;x;†&ÙL#»æœr0Üø¦\n Èô k{Âz‡©ŠÇ=Ì…á¨BwúQ=Ñ‹±Œ˜ -ù±Ð–vU›|¾Ö4K¼¿#¿ÙѦ¾ðm¼óã•ÍŸÌÈÉ;9޲ɏšìf×p1ÈÁ²çÆZdZãÏ:}p h:;±xcݲ'Ç‰ŽŸ/´“·õ…�ž“à á}ì;ß9 ýl~…©ØÚ«§û<ôW}N?Bµõ¥IC¦½U×SÑÚ7�çÚ¡fåv~:dÆÊ›×1äzc}t&"y¹a†4é¹³_!Írc™s‡ÿ¹ñs>£”Q¼Æ(µS#£j˜=ÄãµkÕJ{–.Ñs´ʼ¯ëfÊSzÊS¨) …ÛŒ·ê?ÓÆßó¤šÂÌð�Íæ•ÉËÁŽ15É›¾`‹okÕOËê§~ÆãŸ|×ç<ÿ“ŠÑä:fÍ zÒW7éàù„w~‚lü!ÿÅ”‘creÛÙsz’úŽ?1É£µ€Q ®ú�ŽtNôµfüÜ|Ê? YHõÁM´<ß$šÇg¾¡ç!Ý(³Â_ýÐãoþø�?¾þ¾þñIŸôÉ�/ùâ/Ñ?ùüǯÿõŸ ›ŸüC�ÑÒY[è_ŽÚ¨·ëiQ(33Za®>žw?ôÚk�¿ûwÿþã{¿ÿßù�êñ¾÷ý²{£Æ¯sðÚ‡5y`yy£”«È×äS=¹®dô;Îä|þ\FHâ9W üp:Ï�E{¸Ï9v:Ç;°v–±ç .à½îž9éYùLìóù_ŸD  Z�öØVcµhöR¹ýGÀ(Þ· O~%Ø|æ·œsHMæüæ7Ü$Y>JåÍpƒ|N¦§iÄÄ^úì¶XK4Ý9çè&EêOQp$�÷ì6‡áI29bQçÈ¡qŸçÔ$~^Œè!Mž#†?!‰½r`æºéy€;ˆc“$䜯àBúLG×2ŠA®9½¨†öD r‘RÏ+ÌŒ>ǰ^>ópýtäÚ±b�¢?hkmAqs—BæzXMõòÆÚ.¶ÏîÍĶþ3ŸÚQ4OcPYt3 ·Yמ>'Wêi?TœëãñÃèk™¾nÂækÌvgŸ>L×¶/­Œ~U7Nzúdƒ)TÀíÉhsRë¨8–ÄZ65ÅSk�ð8b0žl öˆ¼zsO®¸ê‚‚|î‹ó<c¯)û1Ùãâ7gM ɹa�Z¼²Þ¤&ѳ«Åäùç.ì£ kì’z2ÐÍc½û1{¢F˜=5‘�´øŒ˜Cà1ºhÎ_>Ǻ?� ð²¹ïZ·Ï»¯�FjDN’ôëZ×%’ž¥¡}R¶zmÆšÂ=wsò_¹ì$b$ùœ{´‘ѵ‘€w^¿�‡Ñ>‚™Äf;C‡Ëk¬Ãá9?í]Ï‹ã¶7b†�Ùàp?­ƒl²T+½¹g·^A �Þ¬äÆMØ.ëjs03’yÔÌóTx/d Š!/#G/½&�s¼ð ³�K£`Ë[�r¯óä;„ÊZ,[ÃslÜÖ7�¸÷lŽâ2çÀ x~:aæ„C�‹ ¸•¹@?¸*œ"ˆmó566b®<áWìüÞ6>Fÿ®àj1¹]ªk­1<ñq‰Íß8x•;’k 278Öà�a“Koåì Œá R”ô }°MÁ‰‹/hrb?óÚ•óÔ"=õª}°9¬71ÉrrúÅFò4õ�c#}a¡pëU¬ç4Ë5á hêu 1Òè`ÜZW.C"iû’¾wr9ÀqŠ®æ§Ÿå©fç7®f=!!Ô« gÞIòžr OHX˜µê†´ðv?ÀÅØ§µ;´`b Ý„zßbò‚?OôGDΣYtà±çV[`(žt]çtµ °õ�$ö÷ð‹k¨§úáõo¼AöÃÛøæ¾Ùˆ÷u)¾ú“‹ä óyå0ÛÓu;ñ&EÏyAž—GU·á,©�W6»çM[Ñ“}8 IDATßhÔìÿ®ˆ@£ïI³ûu”†4¸ö †Ôë•iÒe—7†Éãë:nÍQØÚ•Û½‘AsFgvRáíä–%j�lá[æZqÛ¨“ ý­�Ùyt¤wÜ,síÄ=5+8›È¬\�][sɇnS ͤ©qX,SÔî×̘� �×9ám�…êX’¥çÑߨÆÍ“’\n<{Dë]××r±×›ÏŸ³‘0ìØøÚedŒñl}™ {b�±,;÷;?tÖË5|þ °5D±øÀL^(YËçIóɇ0~u;`óh+àpóÁ?!ø¿ïýk¿|�x½û°â=Ž�þ¨�²!¼Zš››#ù 2œø2ºW{”Zë+vThÚÌþŠ�è�ß>íy~«wŸ°ê&`øá®×Ñðbå1ó«qpày'–×;ç~áñÇ¿í�?¾í?þöÇçÿ®ßýøÚ¯þŠÇg|ÆoTíú‰Éy¬ÁãA‘vö˜j«fz³¾D$\x¾{ÿ~åñ·þo?¾û?ýÏå¯|ÿãú!‘çÆôÖ7„§ž¬u­ë-?�N"$émU ¶ñjqQl®Ö¹ùCÓC÷šX}$×›qÊN¾Ï:&ãÄ^õGªí" n5'Ï5 ø\ 6�wÎê<<>÷¾Ðn-#›xï¾ûù:Å@ÛçUÝÕbs÷:UzK<(fƒ[/›ã ¾ý±×¼$»%DQC�²Ëk@pÍm€@EÒ #À.ý<ÆFÍþ*_sžsT/½ð¯Z*#ü¤5cLvÅŸ¾„Ô_Ÿ!¼äZu�ä‘/,R:u³¯n½—ÏáÚK&6ìÙáÛÙˬáëÀñb2Ѭ 팇ž¬«-¼‰?˜Û¶Ø‹÷Ô‚F'÷lÉÞcï ¬‹c�¸äÁ~ó4VsÞ'ò%žÛÖ^Q¾Ìî“^`&×Ü´™¾ñ+¬á¦ê"Vç‹Þ„) ÇÅ2Qòb¬-ëîê˜ØÃ‡n{¯C£äŸž¾·–“#6Ç+�¹i$Û�c¸7§öNÓD‘�>³À«U÷Gkxz-ao¯‹éÜ`Ïäš½ãdºÿÎòC*˪¢¢aÜ®Ãb1œv}Ã㢀ñ­�á©å†îBæ½’Ó�µ¾0 ÿ>>f-=àëOqoqnã’E¤jýãä÷y�í‹)ˆáMq}>ØÍÊ!Ýp³&fÎQÔ€JÞÀÒS(÷æ5Jë!fÆè‹C¶æ¶øètŒ\ܸ»þr˜Ï¯ìÑ{â–`XÌehÈö˃fmF¦#|ãÚßq /üÑ�ü‘Ç‘y<9Ò…  t.|2Y+|Âè `[‡o»�5èpzxz 1v¨¬Óœ'Îä:cÞðÔ~Áñ‚<®‘g¹¶â;˜ÝmþZ„šØµŒþôáp„¯)A3&ØkÕÇÌyâ¼hc‹ö§±¥~M�è™uR÷ú3yÓz#À`„“žéÈë†'mlÆwÛ‰× &}oÜ8äs6Oý‰��ç/0ùº ã)‹ö'nÜz›C0›�(›DnÒrhöþ U¾^[MeÉWœËŸÇãúó‚Ï6ÿä³}¸r�Ýçxz}a5u¼QtHšûæÖšÂék½mWk`x|~ ò‡žóÔDñµ˜µO`¼õ+.<Í/ Óò]ÕXfÛ'Ÿë€”0ëɺ7]�_|�[cã¢/)Ò#X!¶¿&OÏ”¨\AO3Ø@ÀÖʆ)}²«õvØšäÌÍzï`ÛñF ®Ó7vQÑó�%ýÈÊEœW“Š™à>ZUü†6Î:NuF°§ïâÙo6Ìy¸u›C��r…ÓïhúŽúäœÂ¦ïh�ó9þhÂCòL/Ä›Ÿ„ã&Nnˆù|$È7ú°sãíý3Ê6¥kZƒ¡Ç¯¿þš{ü¿ÿÔO=~ÿ¿õýÑïxüÞ/ÿŠÇ¿ô¿çñIŸøNý÷à·ú±k"äL¹=/Qˆ]ŽöX3}úÐk¯?þÞßû�|Ï�<þôŸùs�Ÿ}ïO?ô?=tè:“¾<'ð7ûÚËPø ÷§\ª“[Ì®1XÖÝWTnRïœ=ë™,<°µo¬ÑðýÓêS„¹á`ηÂlÐÇXpé�¸MîPl¦Ícj¯‘ùÜž¨|Ž6¿®«|s–dõBÂ5Syð $ºy÷ŸÀlBËLâ{î“k�šðÐEÃÊAIG^í“Àóî Œ/\:¯`ûÁRŽj…Âg&àÔ#lÎWS¤HÝð8Vç¦ÖsÎÇ7üÄP¿¯) Hn†mN Ë€n0öˈ$›ÜK'¦­ŽðíÉrGÎóÓ©Á ´±ÐâpðM�ùúÁ‰mÄaþžŸ`mN Ÿƒ`d0ó|-Uű‰Ëõ²½—±Ú3ƒ›s+bj×Î\É‘uüÅ)À17NõÙf)*AÈœÏy,'Oöç(>m¬K+_Ï4]É�Ÿë ­¢ÞÁöÜ—O~=ppo0�v9„|ñ«›{>د¡Ø=3Ù­`4eßsP¾Ï$’ᡇrêsî;Ää`F§÷µ±ÅÎwý™Ó—b@\8wØŒ',¶ú:èü5rMŸk ù‰ÅO"&eš%{»Ê5÷âɱ-dÙô ÂÑî:wùµœ–AoÑx<±÷xÛ‰™=“¶î‹b3Ûd>G7…£ŠIOðçGoX[ƒÛ2ºŒtÖⱼџ„îó%ÛÚİóÔ{ãð1^öaÊtÙû¸®xLj۾y}ÈšwósÞÚ[“Í>éܰæt}Ök´¼Ô˜<9_¦€, g”¯{fl<ç ·ª0_ûáX¸C«g6D )xþh¬ý:Tžè®…У¹J·6q.—œÖ/[9Š [¢óù�×=zMx܆…Ãþña6�sj3ñ£ÑuÖ"¿&ƒÇ´ò±vš1østkd&^sõ€Ïë9ßLTÉš°³·OAöiß‘Oà!ßxm½&!Ð÷_7— á–¯xçg/nâ°¥ì5€8|&]p”|>y:ñŠxçÅ-¦Z;ç-Xëp(`Û Å§·jñz8s-œóe¼bý¢ i“WëÆÃalðµfÏra뀦rŽõ–7µO¾æ±Nbe/¯™†Ä8|°ëýœk6I æÖR|­ÛÖÂÚæÐø<ØN¿,¿ô=\ÎIÐ`G”ÌÒ°6÷ˆÃr½Ô*ï¡™¸^“Ö¢pø| uhþ['êÄZÝ�¡¾¢½&'Ž!xŽŒ»—Ž«»nË*”̼0<çOfkºð;}’ /êæ5m¾PsH{D�°“…Gê˜ú¦.#¦À\[£‰zzýø‹B»âo¯Ûf©P¿¹ã¡¾¬†S{s— ÑŽ*WôéM3C¼.H&÷ÀÉVÃVcîøøâ%êæ­/sò²3ÃF­Ež/´Ã�ê‚Y­ýxÚKèž¹‰Î5{Ñ'p±ëkÚZä@Òö:ç—î8Vú0 <Óo„0Ÿ¹×!½°F‡ùl.ΘƘj}Ò¾>7Ä�Ö�ÞF•ñ¯ëo·‘uÌYdnR‡ö§nð ´8¦,â¶M_èáˆÝÄ8λ„ó�Ýðzí�/ÿ²/|ðO#&óhGýEîÔÂæäÒy¼Æ}åU}Óë°=ÇËì€ô“À®Kû{&@)÷."YyòÏy³_ôP/$­;9ÃË «|ño‡ýé¸×ýwÿø©?~õðžÞò….>sc熄žÓ>ð�<þ”þ&ߟþ³æñ;ÞõÛÿú×~Õã3?óÎæÆiÌâtÏ<§vIÛÏþÜÿùøKùûßóÝß­›~¯?>ò#?êñ–Wßúxýƒ´òæÆ!ã&J×þœ„YžšˆqÏ:¸m¸¬g/Dó¹‡D$Izª½ìf mê„€8j72.dSBòÜN­‰Á�s]i‡Ý=ÀŽ|Õd“ƒï²äB�ëèà—Þ³]|¹I|ÿª§@8\ {–zcDïÄÚ‚qÂ.&ýÎ.ñ�cÁÆ ÍÊ`í¤�½º-A0ìÑ¥¢lë:ç6¾&XêÃÚ'•ã«E6öð;%±öÅæqÖÆì†�;cÚr†´·°0õ:ÞXøË#ìÉ»aæÄÉÍK®h­Íd+Ï[\�p cYôt1Ž�n?¬'®¹R'}Ï×B¦ ‰Ÿ‡ðƒ -¸ zÓ{ãÐ1ç±ÛøàHØY'ýz9š„ª§— àmeDw—ðÑ0½Á— ¤†n& ã´~£r̬µÏëôøWU‰] ¼ëƒzžr„Q6gÝul\Ó©1Ú­ ¬Cé=ðaàÝDžñŒ;üÞLfnÌÁrL<œ;^˜É…&ǯÑzÝçM´µ÷<Ýš_ÚÂ×ú©sÎu^yÕ°ý˜4åôvtm¯´HäÀ‡v>: WÕ‚yóìã#ïÓ6Cb-ÞcJchƒ{%£|Àn{×wnhaŸ„^a8¹É<çÓîbwtÏ—™®œ¦§§á!ç…Oá²Æ”µº°¥îÔ“utX{¯ƒ4b¹×çÃðOÁæ˜<ö\íS"Ò~2Þ:x¬¸éQY-¶£nê<Æ…ƒ™g2­þæ÷<ܬ}n\\"X6_g÷«âÞò”HÆÚfO@^œÚ�zÀeûkÍ“<ÆŒ®pÁÍÀ l¡ÀðA¬?ˆ”aE{"ìñÙdM¹(ñó‚„“’ø�›,9É«÷­7†y‰ïE•¹ÀäEûŒè¤Ðp­g02›‡XÖw,ëÍ�Öò޽¾ôˆ^‘Æ,κ ðyH@XW‰«À¡ÀÂ5A�‰gM$®ÕƒC£ûαæh‚ànê™[‡‘†¨ŠÉ½>a�{{‚!µX«~C}"�†[Ö<ÄN|y“'½?a× žŒÉâMjÒ?_¸Ñ ~ÞªM0Æúµ¶.pS7dÕèyë¹Ähi<¦æED!µ‘7 ]‹û3E¡ëyh?2¡;Çiù2âÄ+‹œ¡žµ2£±`ͳ$#ò�x•Úéc±m�œbœZ“¸„=GÒ<¥"Ž EL/‚4Ñe›s‡3®ÔrË2�#4úØ?zMªªd 6š‹Ç»£g�ÚÈEÏóperÞuÒólRü(H~3ØÍùñnÕS\⾜KbØÓ;é!«®™Ùd,Þ& 6¹Ë�?A ÂL|ì­§\Í¿”,ôb‚�<áa�=üèf‡­7YÎ�tÃl'¶?ÑT]xþî�µŠÉ‰a {s‚X½¹o¾4ÁÃÈÙb5ñ!ÖÍ'§ph‰ n"ã�sD*EsÃÛø;1Ãí7!Ëxcu0 ¹Ó;!µík8§ÏÖ ›Ë‹ldà}è§–>ý3>ëñ�üæÏò ÍÅ Ö\ZƒïàWb}JºÐÃMnœýÐÿ ýS�=^ÑŠ9Gùb´kâácO/àYû…¼õÄG-½Á–Xpñ¡„Áþê¤×î“øó+±|1}äò!áÊ]®»úr�4Fv×W?Äz÷‡Òñýê4rÐè7ò(çkºÑû×ßó×_ñî¯~|Ñåã½ïý9s�…Óc&¶>�ìõAoÿ‹¿ô½ú©¿ïò?ûÐ_g”M.ñºp7pÍê%oS#ή9/¬9gªåeOà2nêœ5œcýÅe6©> ÙèHLs&/zdŠ]¹=ŠÙÛÄĽ²€86ú›dñÙÆ‰´/±ö+&¿~Š f áB•ë{¤åúšx óq[|�bG€Y‡ExôÆ?ù‰Vl2’„Á’u?lœƒù ÇãI'|GŸ#1 �&_s®?@óké> Ç[Ö‰ŸžM S”Ø;îµó 7]4;þÂóœMOC–Øî£ÁŠÐ`£¸Æ:‹!å'1†ps¹¢[íž)JãP¥ÔW&âÐ�áÍd»‰�'µ^.âÝg˜Fãaš•§˜¬µ/ä¢z>W8æZ—Hêo?9KÚM$ÜÃo‚ƒ CŽŸ¸Ö W¨’cH‡óâž|Ž#D¹Ú¯Í/Ì(ÑŒFyLá,Y˘:åd�Ÿ  ƒÇ&ó¤Ô$Û­ýÛöı�!Ÿ @lŸÚ´L^ÖÙìÜ6+6�能诶[ÄD•KQ·oµ›Â�öoïÄc¼â‡6qÜ7'¿ÖáŒÂ?Õ8ùÍ!8’«‡yóp|Ω<æÄ7|�Aˆa´V†LàɳX?ÆHxÃŽëp\ìÍéND_Õ�¿æÚš× éÛ¼�tž4 °êdF¾ŽY¾ä­»öζ·ñ”Ë}¤!hÑlZÖœO† Øys5cŽ øËeüªÔùG÷Í�÷ã›ÉùW´yö=4›>œ{06Þ‡Íc¢´ž:7w ·^•.ÜI h"�ëÝBá€èż1‘,z¿¿ "ŒxÇ�gD–®Üö×蹞Ķa4¦�áµñj{ëÀ^Õ4 @£VÌÐ3Ëø_Ë.oÜ'KsSGù;Õ'p;<Û™ãø©Wä�— -”ÝùwÆ/ËÔ�Ù——P†‘Ô<ן$Ñ-@y’‹lÉç=}˜^l€I ¸îÅhÀærß:ÎùLœc…©¢ ‘e—5Qÿ]Ë@šöœìÆCërbîz8:¡�7jk|k)†)Ö®iÌâÔ‘°;¼-Zo±ßº€È–É}’k"ì³61ëkoÁѨ$ƒ:˜£/ÎÖCh>6©rîš73±êÒ�F‡ îãåà9õ*$_ h‘ðˆã�¹ph0ÍÒû=ˆI‚{~l6®àñM|kƒ¬uóÅmn€Ì¹­•ÜóBŽÆ .çd…$5Z¤ûô$:(¥¹«5¼ø±èÍq�Íž|½©a\EmÚÔqtÅá\Û07r4ÁŸh$®º&26Ç¢Š‘ó λ™s^m‰Ãhœôü¥½ue†+=šP¢ÖFt?²2Ûò’iŒº½h«`r�ó‚`cäp…’p9DÜù²¿ìø��I¹õÖþç= óÞdñázJdôX³¶ŸFÈ 6áàç}ÇµŽŽñˆ§.njE'Åoí^[è¡“Í•�¦4(ù}}¯› ðßüý�w|tþ�$®�$ÐN˜Éµ~M¿šúc?þ“�÷üðÿøø¥_z_þÞŸpïýÙŸü‡ô[ýÚ¢?5ï˜'¸ÓëÌR)�ù87 š«ò¾èC:}£°ÍÈõµ4þ¸È)ƒÞöÓ!õ37Ç^×ßgt×d¨¶û¦±ô”çAÛÕ·ë†Oìñ½Æ�: ðߎçþ÷¾÷gô_zßoØ÷ØbcaPôœ3�^}Ìã€{C÷�=r 'ÜùuÊs“/ñ‡¢äs?L¬PׯL…èæ&Fc‰ïäÅ’aØÄ˜Sf_§šά7§�ÜLI­Uó`mcí² ±êEÏ1ù >ºF±¶¹‘f]pO:òøcø#.~yf�ãÙV©w�`ˆ‡ÒÚ«Á3IãÒ7N ”sÔœQN„6¯�ñl­l«áøçz—³@Ú�i£wŸ†« Îëø˜¨•73�€�ýb´îÄe�ǼáóbUÆ6§yu0�ÅD�étÀj p¾“ЏóÛ:É><�ë§>ôW+<ì“{S'»\sn;\�¸±í^ÜóVNŸ ù»_ž$wmw¿L5™ˆ¡O'ÓF·)ÖÕzðÛ8­[ëŠÃ ÇèuŬ± c.Ŧgƒ÷Áqì2°9º†Ùa¼§à|-Œ9ùæÌR+35ùùjŒí¡}Í1>&´¿™¢à ä:v-42…aL…àõÚu4‰æÓsÜçZt¼ü†2Ó[3Ü„ÌúÁÙV;îY'×<‹�,×hÀí7nÇ•ßûÑ3¼`Ñ»š±¯ÓÓŒT�ü{.Š# k“¡Fcrا5|í�£y­m»Ô{&XŽ©ýæ½×“ß&×þÖE:÷E€Îhñµ>B±[ÃæDa‰gf’?y,=ÕDìøkGSkL£m0n},ˆ³ ±Îhol©$mªÿÑš8ûzþT¤hrÝÞ';)öºaÝ£ÇÓ(¬D’ööÀ/Kk·Tî^FÀèW,0ó£¯wüÇ©ü¬Œ¡¦Í“lÖØ™r>ãKåeÇ/í5œ…sæÚeÐÜXóO/ñ÷|?å¡Co4zsFóM¢HsŽèQvÔ>q웫¾ôrìà í�ç#À¦dµÙO�ùB·õW£ƒEáýôùI×ä3n䢔©SÑÖ<ØÚ§-ÆòÀ$GÆèÀK  IDAT¹å7š�eBÌij–‰ß~Ùm9ãͼëBC Crz9(Ÿ“p&>õç8±³Gêɯ¬ÆÔ°æÖ6¿È.¾p¤3O9�˜{ léw)™=’Ë-³®ž“º'¦XàËÁHù‰¡ºãÊùÌy�§:¼ Á⦙®ÀÍ0“ûB`ζĕ“]{Çlûèòó(�ö6qÞXB;\ÙëeHšÓ„èõ#¦A»Çí'ùyœ/‚øÂ7âçZ…#ç½1™ `Fs¾ß:šR‡ØN>G—Â9³É5×3K<õeÎcË�ÅŠlXy èÄËá‡k�óúµ zÝZ¦ïÏõÀ;=’&½1ׇ¿ ŒYlÑQùÌý›qÄ!gë„o>ôõE‚o¾ó{†`—…öÓ<Õpj#­z¾¶låUÈãïø˜Ç»Þõ¹çŸÊÄy¾×>ôÚãøÑ{¼ûÝ_ùxUßîÓ?ízü»ßüM�OýÔO~üÛßôï?~åƒÐ?á‹pr¢…q ÅÖ¾�ÒƒHÞ§U(‚,�¾ÆW r.’ ßËakUêþ§À�é *¨P–›b|þÖk¸Fz¯�«sè)IqoÉy¯+–-—™¢xtÎ ?tÛ2æã¥?|1›Ï�„~Ä+F½²×:Ûá6M}‚¿‚¨Á[eÒÚ[ƒÁO ¦¡#*uáÚ1 §Ðy½äXã�~m|¾™ózÏ›ÏúÌ�s9ÉÍ`\Äx¿¸F¾mÝÃä^GOþNéϯ,æz”_#Ôž÷Ø3i‡ÍÚݯ‰óO4yˆós¼Â¢¥À©i¶~<7V3ò<œŽCÏ Öõ®½ýj óŒ%:%À'�-þ¼%›¤Ó�RbÇÞ5V™�ÞÃ6 rT‹ý*—6®qööí!'ÛZ©åÔ1ñÓÄ' W 9ðñù5¯™Ú·äHœpñù<Êqz—´N¿j²ˆ¢áÂtåÞ�_Û]˜í•l».q “ßýÕw]†²9ÑÀ•œ¶º½öt~RÇH�ö ÚáÊc&ÙÄ3×­Åçd4¬I�Äpíðvzªõp“Ãjœäè·?ª|þ+kÓä=½Å¤Ø£ýyýäO&ãŸìh‡g†µjmSíÔnrz-¾¼®Ük�BH‘ºƒÃÏû�U/z¼Ž¤9;cû+ƒkìü¢ßÑ>š7ùêK�V…Ó9�¸ð5—£xàÌp¯çñÑÔŒèA‡ ‹¾ãÐ:ò³|—¿8úù«~‹þ®t"¢99W£8dAîc²£yZ��³ª—¥ÖŸqNrÁð»Æ‰»b\Ö¥°=ß!K¶+3RôtxœqÉÊ“@%¾íO5Œðõ¿! '(üŽÓÆâ4Ûܽœ}°�“0ÚøU&W9/ ÜSžë­É6Ág œÙ˜è¡¡«{LËã$Šç !†€9‘‰°F¸¦~ Î5Œ­;#5g½Ç—:åx3ÞÍqk‡Mz3ÍèèÅ{úƒ?ª ŠNüÅ>_,Aã[;Á2Û¦Egüw 6‡µ NAÐi„"{Ÿgøã:~ CbýâIO“{�WÜ“-I;’ ñå&YÏKëeNX{Á}‹–yõ•ËPYéÁÄ9_/Jü؇'/Àʨ'õò™f`=�ëcî O·Üxˆù˜$âudñ'¿` ùÖ�™±º-)Pì® �È¥wùï–¸„Ë/pñÅä4%4nG^°˜Ñ¢'^fÇËf¹ƒ5Â8Vh�ŒÑûí;­ˆ%ˆ1q}!|ŒêµÉàk!ŽÄÚVÃÉ[.ð‘ڞ¢a²ÌG¯=–šç×á"Aƒ‚.>Á ãÞ etf�+~WˆQƒ=–­ÅûqâZÅ]m�&˜žÉ¾ãFãËkèN!·†0H ~ZèÞ€øYò‘xÎiöÄ�Õù�¡`§Ö²:¦S«ñøVà Ê�N²ë=ܹ®à½ó°¾sã¿c†Nlásí£/çX‘`âú..©mÊ9¤Vü¥—ôŒ/9«1NóK»½¥uGs •ãë›d®ÕŸoõO5ÌGh \zà Ög—õTc,åe÷{¿ìË÷±[GæÐ¸§\Ÿlïÿ¯<¾ñ¿Ñ¿6üúk~ü­Ÿ}ïãëôßo?ô¡>^áœXÇ|ᮚs�£-=ao.qöú/·BÏìs%SK�)ºÑñ¯˜ÏÏÝè…„yžû¼ ÁÈD5›óŽQ�nÃ4ú~¬hýæà§ì&9ôºˆª‚p¾Èj†)$Á©q‡ö¦ ܾ^\Q~ñK?õXåF[o²öP|ÁaiﯟŒÙ„½>Çç¸çëiµXm¹Ï¹;9QyìÈ'¤ýg�?/aM�˜R°Mƒ7r¯{àr˜4ë-ÿu1<ñ'Æë9OÎ}Az­ÄT­¸�8É¥ š¶ŠØ\§b;3öð¡1õ8·/†/€ë8Xç˜p2—¤y˜É£·~N$&šrƒ¸�!"Ú‰P&?\¤ã½1€…+7@®ÏïÜèqmJí",·Ù€ðræóDh�¶d#:ù²o±³ŸµÓa�¡G¶Æpˆïå*œÔQ²p¡£‚Ðí8S Žj´ï ƬÑu2TF‚wçšÌ¯CÓâ�,æhŸ�ƒ`pùáã=UGtq<¯=³¾oNBd*3¼ÙA¤ð†îZÄè:Çmp”1s®-ìô#ßp56ŸéœÏ»ãä03ϱ¾nB,uغÎ5�|°ðÁQoZž¿¥ìLñ:™z0=Ä“ë.±Ùc#zŒ0MÍÆ²uYåK¿12Ê3u±×{ø¢ T‹ØSvÏKã6×:�ÍU…ÆÁf-15Y3ø,j.îô¿¼&fIds½ªu]³Hóm‹ü&ØEù¼{/[­ì‡Í)C~êÃrkæüÃù̺d¶ƒðO¸9Œ#†…“Íù û1g“�«Ãœ�FNÁÆÖ¯RüÜl=@4NwØ…¨¶­W9#¯qN6ÅÈ?£³7:„ù²�áè��ÀÞú±k8'qäh.ò_{Ü|êâ1B.mó¡=5ˆJXç&X ?M¸®úì]¡<?×�ç ºüZ>Õ!Ds„›XB;šcß�MHú�Í©=ÁÝ7¥o¢9<}A�1äÝÂn~9^l} Ÿœ©G Ÿ¯:Ä>¶»îD6^³á3¦[ Î«oj¬á:—�?sU€öºr´ïO3å¼s>×AÜWŽ^uе÷»8ý1��¹.õ}Î÷Ø!·D–mr�–&×Å7 ‰†Ñ",±|2@sø†[À½öEÃz(š5µkÇ5�~˜â:”¡\oÄÛÑzÉCd£§i…M^tR³P^†›u®xۭ̉/köä>5±?ܶ¤îÛ—õ¨«ƒ3žuÄΊMÊemukã:Ð[Û&h?ãH®¦?"¨•Î;fÛl¾ÜUÌyÇá>éÀ[ÇÛÞö¶#j4ÕubŠ&OŒœ__'PaBÂÄaÈcÎå-ùÛ¿ªÿbû;ÇoÓ?îÈß²»¤&Oà^Ã÷�_ù _ ¾¢Ï‡üÄ ÆWßú6}È\¼„d(�wëKkЮ­ ´°þϺ~ì껼ú©·7óóÂÍ>|¼Àê‡_¿¨|–†,}KždÏQi­™�Ÿ�'=ü Cû áFç_íóàj¨ŒqP)72߬£/³>yut~&Ç ‡±±ú{‚:GÍ7ýÌaXrGâùN¹5ñ|ÊÍìƒÓ²Z=Œs€µmban+,ûGy…—öÔŒC§°”ÖÜöùz¹�}$\8zø:VèÔ‰fƒžùÉ9çƒëd¯MkB ‚GÍ`¸y^Ÿ­,c�×þÍëvçú‡‹ÇÅÈ  ¹Øá`¿]oþç3É_³ólŽ8ôˆ“wÐ ­¿ˆÓŒ‹(wÿbÒkbÝ#\øF£Ï“ÖíÉGc¸V˜íŸ˜`gc¾¹9=¤•ì?= s±ìÆyåˆL©£‡£™uØc€¯Ú›5ºÙM�¹-Õ¶ðÇø¼Æ–^`ïóI¬‡-1íy¦‹¦êí¢{zÝ:Û óÀFƒ-Xj;®TŽÔvë//ç„‘£f/æ\‹Ì1¶µ?Éã 'öî/ÝpO´¶ÆÉs2ãæj-ኢð§F€ù8בƒÝ ³-×pã9 ²1{i×ã·|t“�­›=wÉsðZ�É0àWžõé1�u¸aÜ‘”îU5ÕGÌ¡ãú™Ï™ä¼|¡¢h†/S?q‚­FBvàdÐ@Sªd·¸äl­'·-f z[K’Ù>6€DìÌr>V‹ö¬Ý'€—.×¿Ž°Ð‹â–gŒÔÓœöµÓ›Ök'hþèL–¬Á8ÇæÌ5ÑóÑ<î}¹À¢A«íP§>|àH0Ø‘o;p\njíÖ}l�oºo<³S]cDÔ<®éòãh¯šly·5?ë…æôHëùzoe«fF4‹Éd‰Áæœ_æD½q??µnG3 ìçxí× ÑMQã;xÌ£÷ƒÐö2:ƒ‹†k…2µÜÁžæ6ÜÅ~¶ÛC/ŒöðS ˜m×$ÏIEONtö rÜFTsf2„+¹r$BVÐÇä÷ë9ئµP=½õõˆ�� [âÎ9«iN,~¿5xòMž“ ë2çžhaàÀM‡?çˆJV衲Ɯ<€“Ól®³y«…÷º¡9%5U´‘¶ –|Ì'MÖ§G£PFlíoT›DhâÍ�•µQ]>?ƒ#mùg(ñå!çÉe;œFä¯9]4„u£MñòÇ5’k¤r$W@Á|PÿÅÕåx;q°^C£°Üä2‘Ö°ïO|01,C¹Ò‡â¢‡äØά›iÔ¯õiÝ.!u”G.âÞ¯ÿrË?¸Hï“�_Éà† z‰´Òú ›æ=ðøfùg}ïeò¸mëòñK¾Oþ Ÿöø¸�ûxy>¬ÿ�+¿~*ɵÉrÛ •8¾0„7m:Ó¾6Cs#Pv|Üpó µôÇ=Rpæô)8­y—­Ž}³Y•k$ºVxë@ÖãÔþÃþ»„ìqVSfþf!½®–è`[uÅŸä·Í7¨ Õðä4p�M‹Q2íêS�Ü‚£˜ý|" =ï`µ5Ù8>Ÿ�‡³ø�±»˜@Ê k:ís‹(Ñ'k¦ÑÀÎeüUƒö\WûE8¡ pDìÉuÆä±aÀš6ß3Aø€Ý‡ŒÊ£ë’ó“p�µ üòVÃd†Ô€¯oæ ©0˜Þøƒ13…ŒM…& xÞ{!êÞ+Óúí=IÔǚ٩qbž[E¯�p&�™R‡¾®²¯ºp*ŒPâaÀ`.a˜Å3ÞÉCq‰KÌDæ\h è͈>¢øÈ�sv"šê ±8Zëp*¦I†/¼á‹Nv ÞeÜ��> iI:ðfl&g¸rÞ¢9Ýc1Ggü9§•œ—dÛž÷à°Pcµb‹žæØúqÁ»6è޳k–c�îƒ0EW­Í;”ò—‰H÷áC¹çÝ ˜ë}|w®Öd—ȉë8ú@Šò'CÓÚW^œO†º\˜à_ÇóÚÎÁ”³9©“7�ÑãÕE.Ü$ð4ÙÒ£™e6$0Œ Ñ|bàÚ¯ØèýÖâ$/7F[çàrÍnbYÀ‘b5ðlLL¶sÈOf±JÀYÏÄÎô�Ë�ÆC°£ñÅG4m¿©¥ñš­‘ZG³9ª™YÅ´_^s˜Ñ|ø …“5çâÂa»÷‡äÉ'êrv6VÐf]nqbìÞ5*¯÷øˆéìøØZš:€§ç·¾r€ÁΓ«²ê§æÑßäàøŸûk¼:ÜøÚÌÝ‹Í6éZÝ£Ñ"† “ë¾rt¶¹µ)ãUfâ½ÅéÍÌ 6@.½¹ðbð£`âh~lá‹+M·Å°y4›ãͨ]¸ÊC†‹ilLs¼ø«¾ámÌz`Î Ûˇcò`g´^^l»¾ù‘pŸ—ž Á€xBa•“(Ü9û£üæjÞ�[¶ò¬Ùû+žQE]o=å‘cym“ÊöB¾íùàÊÓ¹5yoˆ7}Ôš&›ùg¸¾ƒŠ3:Æú"îæ¹×K;‹­MYZ²mÚ?i7%è‰FüæöÏm¨(kD'Ä_X¼¡×No¼‹jë…Ëý¿lN{¶7Ž _mÑR}|‘ï€;ˆy?u¥_?PlPê‹Ð³»SèPÜ�’ua}üÈÄedûþJ„3ä€oüÆMœ¾ÜI�øúë(ú¼ …c €ƒðãÔh×>RbcW;H×åv3ÈE�õM_+:ßýµŽžwó\xçÕþüJL¹eÎæðù@§Øò_sú|Åã¢âªÄ‰ 6Û !{¬,Ñ÷̇ƒÒ’;aÉO¸â7ÐÁpî¹õõŒÅ"5k½Ûöìð·«»µ¶ïíéø‰AkRèÝSëž ‚Õ€2·‘z½Ä‡�¡K"cBØ’óÜ|ÿ=5¦$šÒá‘=ßeÏuG¨k²Þ ï=çõþ¨ø÷FE Çþgîç}c‘ŸºËˆ�iÚø|û¾÷½ooæFGåòçHÔ;ZÐL#.S6K¹Ûs>R[_ `'\B­‘_=|›þÆàw}çŸ{ü–üÕÍË=~ñ~ññž÷üÈã/üÅ¿øø™¿õÓºKðx¼U¿Žì›¥’ÒÇDåŠF”ke£S¸wä$ÖÄůñrÏ�–yPžÖþ)(ûâ OÎGbÜß^%‚À»c8º§×¸™áášOFÎã믄ÿù à¸I‰| ôö1ÊÞñä`íláˆwhœxý£#ü‰ wÀ¬‚K&¬ý©.¿&»>¿¹¦Pœþyß^i¦F½¥w£"©DN¦Î{ímf¯7×Jc7,9¨ÇדB˜ùBÐ]iì®L�.*¹ls!âÑ…ðtt&¾ÈuŸ–~ÁÇz„üZ“üГ4ÜÉ{àè¢ÉþÁáÓ[ÎËhHe¢ÌhH-£O.Ǩþ#ñZÍë^Ÿnæ»4D™5×f†qÀùÌH�‘B½‰"œ£Û±'/[væ&lý�/©Û³ìm7xøæµçf~K_qôPºoH–øä¹*™k%ððÀu莽ó(™œì@wFGF4.¬ç<—ÅgÐXs|ðZ‹&G®©ô=ºï¸(w ZöüôõXë�¸©mòQ§•pHMÄg„—8F^‹Åg8ð…/ ½åÂT>rÊn—SPóîç7E¤&yúø¶­×KúH\koŸÈæ¡”ÍJ>ûçµ vK˜yqcm=p§]ÉKÝÝ'‰ŽÎSFñyvÉBŒûæ É"[b¾íT–|{ÎlÛfg€Ó5©‰™öj‹–ÔB–sîöð`1ú¯¾8‡Å‰ç:7ô4mžæ¶ žÃèIªMšøIíЦáŽ(oû·ûò&¡(‡"8ŸÅ.çø‹ ¯Œ,®ákA6ŸVÙÍ£Ù¥Lî区=þåTónú^g¸žyÎvß»5’X™Û‹1�é"�î Ô„«ù\Ãq-§Óyì»Ûއ!~V·†\gs^ ÂZ²s-^±I"÷m“�Ø­ÑçàœŜӗÜî<Ä8Dx>[ËÄšc4a¿‡ÏAõ*nó5¯fxµ 3Ÿi% »`H tØ’Ö¡‹•«ä,o¸Óà~¶>AäÛ<äî�‘¸D{.†h³o\žßÄu¿ˆ2u‰÷é„A4o¦ÕXù›‰t­7Œ-Ã>-]v5±!GÇØ›¯g¡n“¥¨ÕÝ#•Þð1oÄÅŸSK¨u(OuÃL-þU� ywÌDÍ¾ÜæØ¬4‹†f—ÈáÅpß <3U¿%À¡7­�®1 „ŸP×®\`3„vn–PQ�ìÄàñߢ@ºl^˶5OzçÀ›g™ü…�lÖ€qa*Æ8f0ö®§u&O¾°J¢smƒÝ_ôB5|þÎ’ÖÁÄX¹ÆcBOÒŒÙcë°Ì@P§æôVÖÆì" ÷“ØÆÃ5›êòì9¥Ï¹èîÌù"SQÕeqMpiqìy;5„kµMÁ9¿øÂþ©œÖ˜ðë|õú’c1,ô!×{ä½À ™¦ö¥ùãI l¹6JtfªK ó,™Io_c1èC…¥·ą̊=» •Þ°šâ¹ÏOzyüé[+:ö£ˆÃ5ý†£×SÎÕ‰·�ˆì¢&fö=ÏÖÌ&ï¶4ñÁ o•±H�ò¸8ç)y¥/Gp˜]ƒ…4gÏŽ®™­Çù“EfãÐ|¡¯ÈÔ¤·”šúÝ!â ´z\Ÿ6è$“�óBÍH|ŽLe„�Ñšœžf‘í%Lú.�ó|“ýrÓˆ/˜¾ëOÿÙÇûÞÿ�RàÞkÕ¹Î_úå÷ÏÍð…Jô•Õ5ªN«²~n†Îu¦>tø†Ñ„¾ÔÅ>½ «{*Û+¯¾õñ9ÿØoyü·?ð�wý¶Ïyüº�ùèÇ;?þcŸý›?óñ_þE�¿ü_þç�ç~“nþ½rnþIKãÉ w?`G'þm¨Öœ¦Þ¨Ý~ éÓgdÖŽÒ ¸ÔÌM8ý±þ+poÊ j4ǧš¦n’›S{ÉÚ5x¾rk£ôå›$ÔqûãN ëúYG5ÑÞþ±:3&ò]²óçfK!0cuh›8/ŒÚþ’“u1Ö@ fÖLn“1Ù‘ÃqΛp@õæw]‡Æ[Òð“Øƒ¡çüŸõx B~�Úøƒµ-: ]v4l×ùÙW!Ïv´Ž^k  É,щCcªõ:Ø,Ç=9ƦéæÁÊžD™Ùç|U?^áÒ_vÉMv_{XdBwá@ðÈu�uânг† y1…Ý-‘§³—g'äÆMÀQ*J{¬/±ñG_ën­DÄÆÍpøÙÇFN�7vACéu8Š O‚ó5ÏU}™Á�ÑÞ «è¤wLôÒòæü;eNꉃBœ˜®zŽÞ ìí2¼…8wkr®!vœCø“ƒÏ�çsejRl¹˜MjàküÈq׉f†|,²±%c =2 }bjœM1<î'6�1iåj&fø�S”Ú轜™„ˆè Í„ãâCÃÌ @UÎÛð˜/y‹%Îè bö2­Ÿ®™Í+pÎd�‰Ê¹9±ÍSMANï'ç© )z“}k�­�¹Ø›/ŽòT¹&pǬS{­É±yÀŒ?šLÎ���ç—p™�§‘€onù3"¤ùk<â3�t~��ÎHÓ ÜùóB‹Ish¾ýéMH")€’N 5›¿vãûØ¡Ìôîôæ&‰¶«/Ûív÷LÿDºöÎ6ÍͶüq•Q†4Õ2¡6ë¹xÌXuoÑC:6'Ön3tŠ}>‰‰½“9#Ô¡åîš?ïæpì.–o�k㸑Ïä›}8‹c®ðmÀ8˜…àu»µÅ}0N’„>ê�šÃo}7—Éa?O8‰~JI0“o¹%™æu¯³¶t×OÞö¼ �¥y"A ®Þ>é~pð&6Ñ/¹S‰|CŽßk‹„��MlÞ ËÕW `¸,¯¼ŠÅߺÃb1iÛ¤³Ÿsâze<µ� l•c,²Å½Hƒ,~é! kë>ØS“±ÕYgØÂ£µëcÜ€MX�gß`fjÿŒÒÁum.êϦ8ç å ŠY ìB§A‹!Þ=Æ;?2¢�Ó¼÷É#’<Т‹7Íî/¾uz³0¥ß!XÚñ9Të`š_™»jÙr$Pfó*CôÄ IDAT�ZN¼À…Y0ÞøÝ§Ð~A!Ï‘ºÏ\"¼A8|=϶^W`Ìbw0h(ßÉ�|ÍEÊÍèFÍnÒ¤ßbšýÑy¸É͸µDûÔ&JâÍlžÍH”c‹¯š[oÁ¥çô2œ©q(ZI)mQCòž=€ñyŠÿ\Ÿ—_Ü@¢++&¼H߸²M‡–‰³yfi ò›�y°ýä ŒsÔ7ï!œÔ^²v®`Á0L5|å�Gp�ˆÔ®acˆC²+f‚úScÏç7‰BЀ/MX0'n„V°¶‡OŠ (‡cˆ>ý0@ =üÌÏüÔãoüOs~¢ ®çø¦aþ Ÿò‰ºÁ¦¿÷Ý9¸V^œù I÷w~E”T½¡Fü™Ñ:›7±¿¢_OöÍCAÀ}øÃ¯=þƒ?ôï=>íS>É7 ÅÎ�=þéÆÇ|Ì;_öÅÿÊãÿá?¢ïÔ¾®¤úuŠW_µ¯_€�oÎӇ衜ðåïÅ¡9XrãuÁ d÷¤½Ê•ÕJÊ_ú@¨í€œï÷ùšk7Ï¡aOž>·‚éµÕkÛÕzá0Íygjýï�znoûe„ hƒ3}[{ˆýäm~l³®N™£Ž—=ÛsWb9V¬Äe.ipÑ>6Å6>ØÄäXLv“æ¸>êJŸÆ•4³á|×Ps:èøƒmo‡ ÔHqAíÝd”½ì÷e´œÔÇ›ëñ¬¤ñ¹RoŸ¬§‰æy®5çwuj±ym$óK[Ы٢�]ŽÎÁ°µÅàœïþ`ˆõMØsîá¥ñ8£úËÞåvŽx¨‚!>}cÕsÂÜ5öaõŠjí#DšÁG¤s8 ŽàŒ-؉!Î5%5ñN¼õ˲v¼@ȯ‰zYÛ� í`|ÿìãI`ó?ÄB˜þ0z‰?žì�q€á­b±a¶;ŸÖ�›o0`wÙða7¿á/Œ¬½�Yûˆn½n4¦Z/÷tJ)T?|Õ/ŒÙIã1 Áú yÖáóyQvë4`@âÁfÞae² £kÂ=^¹&òað DC– \£ûæf]{(aO¸&�±ÚÓ+«DÏðº«/X\ú' aèI`ï4Ø›ot2�op�Ûâà÷4\Þ �y‡Øk�ªé¶âjdZVg\¹ø.è›B„N/záaEô£S†¼¯~Àn==�̓�·\²Â�­véóÉHº'}浟ҦW$„qâáæ=ƒ¬ú fê¶ëìè<øê·aD{zÁÞ6ËW-ñõoH0aòz½ÜUðƹ5 Ô€ä2aòˆ·å>éP?�þ²&ïsníF»gBH6½$¦4ÖÂæƒŸ7ÙÍ{9±!ÌÛ¯ÙW°{->c�ËÒnžõ5<îK7˜ÅÍšô pŦ˜`y"¶˜¬‡8\ÖÖÍu âú’ÅñÕ�œvÈ~´j´µã`+¢ry>µ„AGãѸ–Y\· ÀÌú˜2=[£óál–[{h'ç�ørNL‚›žà­°ƒb˜C;rÛöDÖ󳓜 óá<‚`_m·ÆÍæðp`óûä—[c ä„?œèJ,¶gF;Û`ÇqzRÇ·_–‹n:‡%×›l¼Ÿä“"X›'5•¸�ЕÏ)¹y«Ñ”£Ål€CHö¬/÷¬ÛkˆªÑ.:2 Iº¶¶ÁÊ·CG;úΨS¼ºI´CæäÛºxމV×ï\±½Ã☹&¥yþ�{ûã,h<šü“o+dÇýÒçŠHÿZëÖ¨üz£š|�;/–¢;Å¢/ñ$èšXÌoyõm�?ô-ßúøå_~îeÇ·Òµÿ‰ïüýôÝ»üOCz“…›k°ÓûÞ ò9wž ⫳¶Îx¸Ù×›n`}.tSÛ[tƒïUé|‡nò¡ß7Ý7®Ç²<oûG>¾à_ø]�?ñíßá_¾­Ôǹ`æ&R>¢Ï6ÓÀÇO;ñÏ6Àö¦�jó¯Ù“¼É^YÆAÍE!õ±žf9ë(ÈÖþ.‰›L’ ‘Góc fпˆ[¿ã¡:IÕP|ŽÏîü´aðæÖµÌQ;ÝÇŸŸkÕRÛî듞ʘì)xE4Ø™‘ïù9w8yŒçZ¬Wf _K*:ç|ìýg2里�~ñÿ㨘òÝßpHäpŽã&÷2+ž^àãOU]bj³éã²\ìZ§ñ×îºC5þxœoìžVCâ‰cø<Ùm;›‰ns³|4[Ÿ{é ©uã·kß½kqzÛ�<íØð?k v´ dÎP=7Ö´á6@Ëp‹ƒÅtx—¦æßÓ5\Ïovèu}qöíqúÛÇ5H0ú°�‰-íŽ=�̵.§mÖŒ¯“Å…+uè ÿÌ7¹¦E¹ÆÆÐàÿ—¯·�ÙvKËúîýî÷}7{ÏÌÞJ;ÀQm ´mm¥€IMŒ"c4BG�éJµÒÖÐÔ?0ý‹jÔ6ml4”š•!-Š_£�&6m¬hÕ¶203{öÇ»w�ßqœÇZëºß=]Ïs_k­óã8�ó\ëºîû¾žûyž^gzÞŒqkgsb_åO>hiášqŽø„7óÚY7¾G :ýš²¼ä²­ ¼k‚¼¼¶ÍŠäü€Êó[,r®Æ-ÏC­ æã2¸ckGØw…3ß±7j� Ó{lÑÐŒ|$êpdÍ ñ`y²ÉÌtüéúˆ×Š ç=-PáUr?ï3ÆâJ,}‡Kö‚³%δkÝGh·9�Ú#/ÿÉ�¹14G”jÊ¢z k-èí��üŠUÓ­|ü]“@ ._f 'l&>‘]�5^¸Œ�ŽwxHÈƒŽøÆÊ¼Gä§ÿæ>˜…&u8@Ž1½šá9Øærb6–û±Eßl¾ $½ë–ˆ©çAÖõÐ<±Í Ç=‡Ó<ŠFˆâ´G�Ð×8ˆO HM«œ~á�μ‘Í|—~+Ù?í ä±S¿öÎäw&.kö�y€ƒ}òalœ;Žeµ×I}qÆ?²«kê_F\Xw›¹¹Ç:cm+Ô ×ƒUçuõÁù`AM~�׬}åŸÒ?Döñ†¢žóIc(+#âþRήÄÄIí1DÀ[›#œ&½‰tÍ�3ë$[Ùᓵ¬?=âô52÷ 0îãd/„ßà€î5!XÇ­ö@sˆ=¶˜›Z\FgÉS¶Œkã!螌 ¼¦kl&½UêÑ9/>À©Õ>QÎXh @¯Ž:gècÇÁ<Â…ƒ9�ŠÚµ^@fr¨‰Ãx~àè@ƒ%jHuˆÕœÁè8–£‡ÔÍ=øËŽ#/Ss|Ëäˆo‰áº–`ª××iS¼ô Z÷öµml×05pË11ðBùiS‡æu­Ü ²Ë%ãÚbÓ<0a>;çò5'ÙœóÆhå— �¾mF>±ÐŸºÎ“qrÇ;ãwp.·d®ÙÔàì˧ôø5wËåg,¹ë¨çàz9fÚu² ìh!³J³÷÷U]ŽxÁe;N,æáðe5\ª bâ¶ÈòêDÆV ù´² àä6‡F–cwê0=›=á„ eÉó&;¸øíÑ$ŠäóÄwa‹��Æ)ØX)àe“ªßè”sùŒ ¼Â}Ÿ ¸•Zí±c\ù8…Óü‚ £8ñ)†%¨1#Cnò[ø‚ر³1Bþš€ÓÕ–irâ8œ[»(–w÷†{N ‚%ã@˜6–Ë®~ üWs òH&Ö�¬cãHÖ¹}ÂË‚ëÌ­ Ô Qÿ®J¯s4ê·˜u9{éà¶yÉ»94ðÊÛ¶6°ª°r^¾õ…–7© ¸µŒˆé¸®1¶£—yên+,ý ?LŒ‰J× BŒŸ�Л1<ÑAþããX–çÍ‘Ál–'‰Ð§.ùè6¦¥W4úr^5ZJ¬ãõ´NòMj<’Ý%F'S§-&çzmyFq#óp°fá”›øó†L�èXB+|[7KmÃ(xyzwèz”úâb;Íœ7ÒÑtž©äÅVïáaÇð�a�gí0³�Î-;'s©WÆ]Ÿ®%²‹Á1I}öMˆÌK¬<^;¤ã4½k>ùcVot›9XäsiXœ§£ '†`âË׊0�ŠqBËò±q\�� Ã¥[RY9òL®rdù¾ä’Úg?{Ç‘±¼§5&ªÁZ|0ÁÔnŒ›95Qõg®ÄN]q¼ ô£kÔËÿ-ÿªlþCñIJ¿4»IÆ�í/xùsoï|ñ%)„ÉQ2n¤8WÌçbtùdÿdd}R¨Ä`9œ£×ˆë” È'ÿíVÿ”‘;rÆû(0ðÔ럀|ëoý�·/úù¿¨¯¨ì G?cb9ÄØ`Ç'ÛòÉ?ÞDa,Ž3­Ìó î9ÖÏù‹:ûƒºÛEdRÒ-ÜâïuM¼ú‡ƒgò¡Aýä–›‹§•›g¥ä„$1F€à…/=>ý$åŠOœÁìZ3­ž›·jΦel[8«kC¾k”ºY-9{ÂXcŸ›±3�£_‹ÉN7�Ïs•Zd½ƒç›Êº‰‹ÜñÉÍI$“Ø–¾ë`ÎòëÞí�ée)»àDbc;£"ü$aj®øê‹±ñc�ÒµL=e µp '¯MÄ©ú1´9iŒèFÖuBTÛð!pb££5&ãæ)�‹“_‘·…‡.5fx°�ƒ�õÍ|ÔêòkŠØ'yú¼KöC†ÿæ~°=ð!6–ë€} ×U[Û¢sUåBÙ³š?G³€Ïv7×Ô>¡hý.ÉqaŽÖd46gG3ù ÂxÏcƒdä`MNöÒ‘oø{Î1švßV�!âr»âLŒ‰J|·Š5I |ÐdÍ’ ˜á¹J½ÊþÁÃöŽ­ sC}D6:ÆÐðÞqÐb!‘†oýG(ãÉÙiø ƒ×ÇÎÉÉvüи >qÈRÉZßp Ü ¹ý*ƒß«–ž0çÖ`ÄÓC‡âš*"©í ÃmtÓœÓ@-_é‚wàš{Êã�Ÿ€YC0jæ«A¡sÄšÛOã�[åè9x~pÈÐ=q‰w„ÉT‘40ÿ¸xœ|¶?6ædˆ�ãüäW{bÙRöü�%\"3Q ³ó >^iޱÆWÜÔû8\lá‡|°ÊgÙ ¿š(ꎼáh~bä¾ÙÝôžåÐX“/äõŸŽe™ŒË-vã�à…r>Ë÷0aXœˆ'÷3ljo~Vûñ´’ÈpL“ŸSÖÌtN[´‘MYb'1±œ½ô1Y¨©œì„<ôOŒDn�¬¥-tô‡ /M’ìHD88L£gt~ÖgÙ¢˜fW:Uªo¦Œ1„ #26áÛý‘ã•\‘à8¸¼!࢜'ôËzÒâE£òJX –64¨ptüÖÂ2+ÅÎ1ŠÆGæ“?އ›,1:°èd¯±c…¼m…Bê{�ñ[v`y1<– ÕÉ8à{Ó…3xæÊøà²kŽxp&Ÿq»8?ð¨m>£ ’UóŠj躀qÔÎ:ÛÌ¡à“üøÏOƒç‰1"M>BºK9Ûæh×3>ØSÏöÆ?ιÀ„+¯Dzƒ`óÛñxRçFO¸É¿7Öœ‹8Ùxi¤ž°ÌžqŒ—¬¶¶?r¯Ü<ì¿HŒÙÂUÌØ%0uàEur˜µ*—‰O¼Ô…3µùïc ª» ¬ñÔ絉V‹f'(dƒa/ b9òåšÐЖ®˜ �gÞ òf Ù„Ï›A:Fð‰M£îÎl}�ŒjÇÎ<^ë§ZxrŒÎ  .›ÖyBf>¦pJ›�äQqD–>£Ã}ëlã $þûÕ¥ šƒK—iaeYû®SV_“«>x ³uuíQ´™¶ìÎí&/=T™ú?Xz€®LŃ\–q€½ò“CSj™º~k=[õ¶…ÊÄ7°>HÑúÚ}bň£°z„¶1Z�ÉP’Á.óu× <ÏÐËæ�'úÛtmå‚Z±u‹ÉãGÜ£ÅÔ]{°#lj(…5ô‰Õup�„m{éŒ#GzÖ�ëØúDß«¯½†kÚ71ˆE{þùçnŸÿòÜþÁ?ø�Áxr�X5µ¬N6I~AÉ‘eçÆÌ7ÿ†o¾ý_ûÕ7Úoꀅs�Û«¯¾zûžïùÞÉ €é¶¹d‡œ_zñ]·?ñ}ßsû5¿ö›nŸøä+©Ž¹ÊŒ›J´±o­"<Žc�>©P7Æì3WнoR ,v»¼µ§�¾¾î¢X¶iNØ ¿k‹.ñ¦&Çœ$À�íî Í�2òÅ,vÄFåX@Èvðó'\Ç&9dq�ö‘9‚7‰�«ñ ïk„¦£÷uGSü‚SÛb=¨ã€OciØ”ãa�m'¨9øæà[Þcð`Ý×ܯÐ9VÖ”Zøº¾©yÆÊ¸8¾¸qãÅ×MlÊ 70™1#EîÕ·¿æ`… l3Ç…çŒ"yƒ� œ™Ñ"É•˜±·ÂÈ£ù�c:)îÌwŸÙøa4¼2cI­Ný[«kî�_®ñÇ'þÄEtj.¦i¼1J k–­+Æ´ØåuiÖ*²À$Î/^­z0ËÁ+fY9AÓþ“Vs¾ü¼/ì’É¥’æ�ŽsÈ?DÀJ~Ũm棫P=5¢™§Œ†Š$Š…“p½7S†ÔÓûü#y[+wðxÒIJ€š¤%r¬‚3г«±ÌbSÁánEpôÞÄE«pì.Ó䑜\Oû»NRvʰã5  šë¤Eΰ^"ÇÅóâ0†ëu¬!0Ü�½åµ�È{‹k&c–]¿�/‹âÛ=]dc€`\7ßÎyöq½á!WMû¾Ê[=9/&N&÷6<”oÞ7îÌy†[rMÞ9ߌ¦@­G�Haê !ôSûʱ3“lüœ‹q9 ý~jËVäGâS·u�'?üUŸ:‡fp¥µ÷Ä‚ÁQ×|ê»lf÷ê `óˆ�u“»%×ùOüU ìÔ²žB‡ÇÈ=¶Åqý¢1�×zRì0fk—l'�3ž@‹…7v´‡›#\$gÚ9+!释\'±RcÃÚ~0ÿYÀ“DÃØ†‰xx1J¨‰ñÇÌ®¦��Zyë’´ 0xPm¬¼vÝ�j°i¾‹¯d¾J,G®‘«Ò2r.úéþzÑzøÍp¸mŽ›+@€¦Öê\™ÃÇ9-ç pÜòŽRÛ5Ó@ö�u—ÛCP þ±G ;زw^&#ˆÚ{ÃØú'†1%Ûrl¯±wâl¨õ$Qð6‰À0/ï#­ÅÑ.ó…·¸Û ‘Àa+y¾ÃÓ†YçpL+‰íà/8§&á†ßÒÇkO£éþwï¼9]g].@DÏM‚Í-ëâñö6ÑîH4Ðì±Äu ÉŒÁ!$9yî‰ôm#Sg+ïsé µçS;Ê€'t»Wcdæ#mú¸²?IÁ8ƒ�,-õ^ö«÷ >Ùajl;Mä�9ní};Ùn Ù͵ˆ½ drK¿óX{¹A¨Z1lƒ¾/ÆPŽ CŸ#)„§î�<³çZš Uç–Ò¸³Ö� ມla-9bú†Z9’9¯Ÿ.kœ¼FÌsůgŸ¹=yƒçþÔ—×E4ì}~‚ Ÿü£Ý¿F —6bC¸^38È7cO̵¶Ö,ÿóæZ,#GMK�ˆ=‚ˆ}dOès‰Ž“Xć+kMé �ðgΗ‘46™„ >Ø«Ù�Ü3>c‹Z‡ϰ g�­:~bTÙ©®&&\û©?cØQûÏỏeý‚ó€\äePì°ÉÛ¨DáܬŸ%=È?BM~O´¦œƒ¶—œÔzŽå\Í>#…öæcžs@©N8éh©^ÜpFO‡nôj ÛÎ1j?äd÷ƒá×­2ØZ;ãR—Ù ^g�õåü٠൱$±í/ß°Ž>6ƒ1_••+¹Ð¦SÜÔÒ8Ö>ÜÁîÓã{ʘ︦^ x¨¡Ã‡_EÓšÒ¢sà1ƒRcá<å´¯ávCÓÁŒ›QÄæƒÉU<Ä2Û¼lÃáÎAÓÖc½ù 9ÝËÒ1%oÏÞþàú5„1òÓÀm æ¹aÉGnc7Æöõ U!·ñŸðUmÇ3†M“›±¥fq �ÚÓK>Ð;>#j�ý´üp—mëØ|YOrÁ¾Í¹I–ñ›88Õ ,͹æsmÈso8=µ§ ܺÀ;Zì�ÍX]ñ‘D±¸1Ïúö Õ¢®‘ØoÇj4+Wœî¿ y”"ã%ƒœÉÖ|鳪å�žh–É�¾×—³ÞfäÀÉf¡Ãæî¾XóüQ|Haß\qϳ¾'nm’È‘W(„Gž~�±Ì6U„A íº}©ÌRŒŒ®Ûo@× ¼e§±a\ …¯/00[ó‘ÛqdÀóÞ\óÉÉy�GsŸ‰q\ÈQ�´pÎZƒáøèá0¶­Cçà_âaޝúÚÔ¨Þ´¿F&DâaLí¯ÐIaæÈ7b÷<¿4'Ǿ Ô@Àá¬ñQŽƒ¯ûšO¶@'&@Õäxr³˜ jÎ`µr¥|® á¹N ö�g{Ä ÜˆMÉgÿ @,0AbBAw¢8Ræ¦p™¬Å(`ƒ�',ðÜz£��” ‹í^1Œ�¡ìœ²…¡‘^�`cÿá´æpÒ~ö5 œ|º!v<¿ñlÉ|^°3ïxáûI4QÖfbñWä`7¿r¨þ¤´lȺäNüyH ±YI]fs,Øø6ÖÙ;®pÜ„å˜L9Øm®éL\£*ÔÆ6šàU›øÇ÷ €¼ùÔöçØ©�ÉÙÖv‚"BÇÐ0åáM]š‹cX«Xú*OÚc|,”, Õ;#jÏ=B«MÆvÁÞ¸èm7þø¦ þ˜kò‘ÍæhÇ?¹„Ï‚Ä�-¾„`3u¨-{Õ^´›Gb¹¦’ﯜ_I9Xæ,0ãé0å�[p|‰Š�¶u�¯ûÀ IDATcTt¨*÷ñ›ÚsÃfµph<Ÿ]Ûå¦�{=®ä<.Y›%6Ž8>çÞ¬¾XÆ¿Â*JǹlÃ��ÿÆÅ>>ÈÖºY<ò¥—¥D~èIn·sŒ´s*“œÖzMlæ+–<òtüê N|3J=v­�fÍŒ³MQ¨%{-HfzxÎy¬!c@™xÆ9XclýŒ°^ûðóMZ‚”ksol!ÆÜ@fÌ5Ýú¯Ÿû0K톴ÝòüäÜœVjNP}ÈXÔñ‰Eâí\'îÖÂOƒõÉ!ØZANYS¸ñI9çA\é±É<=c'«#:W]®´“.zs’o€ˆôÊ+¯Fdë`Ì0¶èÁ¯Z~É—~ITP|ˆw<ßð•Ž7]þ ºó–þ³ïw}×wÜ^àæ¤ôÍi�¿Õö17‘ÞûÞ÷Üþ·ÿýÿ¸½úIñ$®ì^ÃKKÝøtáƒÛWþÊõö5_ýu>¸©Ç­#Ÿ+7M„'�9hÄœqäè½óæ@oÛÆæÉ“üÚ°�ÆÏ\ʼÍs§B“òÆÇ…F>Ý«ìÓv~žˆ™-á“@¬jZDñCæ›rdì/G’xÖ,(]ŒR'„ƒ½%ÅÑ—Ññw@Ïâg\â_ß0Ðý¨3už×’˳—s»¯5ÁÔÏ‘ÚCÜ8íÍ?ŸKöÍšC“X‰ÇÕ¹æÜG&|8¸% Ù#Í9*Ž^'÷$¾[×ÌT~ÄÆ¡$JLT’›Ïÿ ¼o`Æ«ÔYóð5âhÁ gc GrÇ–GöþÈ8·ô•=Åš6v¾nhœ5%/à§u,ë`-g‡—Év0ñ¶ÍÜ=átå`â5žœb?pÑ`S—SpŒ�àá>þ` >¨5ƒŸíFÐ|±ICÏH||'˜–3ÔÀ& tÖ[Æ\¹¦`Ð"OÌä«£å±3x,æñyHÜæÃ,Ø;öÕ:ò“oÚǾ<ƒ6|[´‰±¦rig4sY¼Á~*uê>R Ö¢•\àYŸ®pø]ù5ü¯­~À…cõäDýé|ÈÜjV}±e~Á°¢¶hë“u ÉÀWμ¼XvD0ÑÚììÆvi C3‡ ƒ3±O9¾5—â -Ê.  ˆÞ×;ÅÛb Ô¹*ð5LÌß9?òªšw¹áŒ+-uƒ@¬•Á(Â;µAùYËÆÜã‚JÆ|ÕulÌ1:b»6Hƾá±q›®Ð&~à9n,¯~uPO?Ç˯ùáçÇi?×øÆMmZ£99—\®Í~–Û™#––zd®ìZg=¯�fâ¡O+ÿ-—'ù�¾vZ÷pp..ãòÁå—²àÌþ”]ñíãMÀèh–á%ßÑ·—À†Á!Ž?˜`éÀ¦:ø›×œ–l>+.ØúÎÃÒ÷+a€Á˜¾«Ül{l��½BÇ[PÕ\ôú©_ êö¤öNÀÂÃOvtA�?i�ÝPÌÐóÁÏ‹‡xÅ.?m±ñ4~À'®\ÖOéÆ}ñ$²|ýà-Ñ¡|Ì#Ä|tCfù©4áyQ—@,lóc1vÜ€Ÿi"±~8ú“F’€oC!—I1: çbÙ(²ðšvA®ìÂÏêy�zpÇÆ¤ÏøÄ ç:±n¼àÍF7ó=ë圅ÿ]Ç¡g¾^†% ¦k^.>A$;_\“_jWìÑëÍ¢sW¼Ò±‰Óì•¡�.ˆF&8@µÅ 1èó h€]W Î<�a£Ö7þȱ-WÞاjõÌÓÖ@Sb2O¼àc…\ßz$6ãØd�óÈ£Î8î3@bó‚¿<sûð ‘§ù±¢i‰ŸYÆØ—;1ÈŸ=–OÓ‚½sÓ‰~É�$/1ÆïÞç¿b‡Eê� ¿æ¿=õHœÂ¹ù°�³ŸÄŸ'+é“Gpr ’NS~iÌÒÑpÎ)ÍcAβ±Y♃ôïØàaœø&.þäP@Åqd�u}�9˜|zó"þY9p‚‰]âáSÌø^ñ¢sXâïþô‘Ž’—÷ÆŒóêZOöŸýäÛÑ0Î1&¶ý3ý½ŸýÙ Wßðᆊ÷Žì’RÎAø?~üÈ71ÈÏ©àM]7û~߸}Î{?Ë¹à‡ ß4lá`¹Æ�>¼}ù—}éí/ÿÕ¹}Ý×~¥ÿÎ_Í'=41Ž1žñÍÅoÿÀï¾ýõùáLΘæù.ùd[Χ7;5{ðÐ Ê’f&îñí5"7g„¥µFþð!ë¾o¸H¤FîÙ[åyŽ^?œÕ¼ïÕ{_RÆ Ã[~Mš6œ=þ„ÓJ>>~³€-HCÙ½ì�­Úçf3k$+>Yà׋3—qâÙA Ô<’ƒçÈ:>}™®Ö—:Ù—s!ÆÃk'¯¸Ê†øÙIr™ù¦•B�?_òkáeσe²?qÜã˜0çgkCœ�׋}}‘\‚a”ੇoš«g�áÁ�嬹A†^»¯kaºŒœ‹¥vj6œŸäèOªºžR¿Åþd}% u·Ô�õL&©%*×]¸EvÏ�ø²Ï5$ÚflМkdálž™»¦Ãƒ1Íç�úsÍ£J csp´ÿ€ T nöƒ÷…ö�N&1òѶöÁ�½/Õ.~ª—ÖÈõ§ð vÏárO fÊVÕ%ßœ@ÓLeÈwk�¾qÉ?–‘Ûrê…¼µ7+€96®ó‘ó4ê¹Çу7äQ‚YŸèÂÄ�¸•/ЀÛf¯Et�§¾‰ÝKD9 Pj&¼„%NöÁZ·š�“ˆ«ívůóU7ܸîØÛc-%#nka´œN 'ëÍ£ÂCHË›Ä${ͪÁȘ#ç@¹µÇxíOó‰M0Ë£Y»Ög×DqçœH-eo¬úiê­ŠÿÛ¿F/Ÿ¬Uâè´1ÐÎþ›‡-fÎ8-X{¥ʵ }Îj5æêýÜã5F8 ÖËcá)‡ºØÓSl,Eþ™gòz Ô¹î\ý<]8\ö§�Æ/pbƒ4×ÉÄu-†·éØcûúµÅ ,n^‘f:z®ó½V œ:¸…_žœë5r€©™pÚœ#û }9¶õFyÓ˜pÔóbZ(jÎ5Õ?,˜iøË<ÌÿÈ� †Z¡Ä/6&97ö8Xªƒ¾„bw ³Ïk2«AÁlð5�n|­�ÜÔŠ Ç\/µ¿¹X ?1�ƒ]$—×:BbADS:ìÏÆ¿Sîñ8à&ÿΰ{È ÿJëédðÅÏ<g“1‹�b Nr/¶Œ\ëS o2’û"xÔ×ÓãÐÂ!Já®±�;žl‹€Ö 5¼Ç®]å+†òö™Gñãȉ)­±ÎËû0�T§ź,ÌØ¶ì2µ¶«yTÆ'".¶§ ã¶âÜñpmtð wg4Ë×;ÅñÇÊp±�Þ\<ÍžÐÐz×åà°œFFç ÜJX ¼Ã �¯Ö<ã,PÖÂV¶½J�ÑL¡}‘7ëýìñðÀ^î��<ƒ·x`Û…³ß ¢™Æƒa‡Ë¼Üè‰_žWŸ¶O½àVçñ†… ã‹�Àé“€Ç\@�}ÚÆƒ#ô'ô¨6qvŠÛ‹$SêHjy­É¶5. Û)ÁMm¢Y͵@f8ø 3Þ…á÷)Z!à Óý¤fdÅíM‡âhû³üïáOùŽZp¤aCK�=|ê`9Ôç)ƒIÆüÚ[^,lKçqÚ1–-qË3T�ñÂ$¼Êó“ãòA!S–¦-8�µ/ƒà"}V7Hpn®¿…±Õ�»¼‡3þåÖ�¥�²sså,Jìr¯õÎ;µ ™ò`½Ûø”¶}AŸ$[“b«>é“›œÔ?¡~äÅßþó).¾¦’÷d8?`®uuÝ {rñs)ÎÈè�ÍS ‘Ô~Œ’|>|ì_YÅŸ}äkQyù¦þ¦$¶`ˆõåWsãmÏa›Ûz<–¨2t\ãsdÎk ©“×–4%£D\‡de ®}Þó+ÚÓ �© ޷¢o­ÀmÙ±©‡E¶Œó<“kmnÆEgòåÏúû¡ö"f홓¯˜çØ:øFã8Pmòb‹;n2é 37ˆ &«“±E@~ ßגª†íÉǵäš! u&oQëƒC�håÜÄE9ï=qpC�ó°58“ã¸ÝÂhn½–<ó(×”í‹sýäÂ^ðâmO 4­y1¥¾p‹,6Œ§>d•½°k¢Òù:„ žh–¯k�`b£-cÏ{Ùa/àD މӸš´Æõókß×܇;°hØwœ¹�Oq®MíI¯1ñ€éÞë‘üÿYo0ynä5p[ùwN��åêaÝÒžñËëô;Çå{­Ûi‘qíVL‰Í‘×èÓ¼b>¤Ŭ^§,•N'ç¯6ñ¬æÚsK]�µæ¾Ýí1çÃ…T׈ÍKC±Ú§X;‘ÍMÅñyl ²7Nvï)&× ¼ægÍkSÍ]¼‘�ì\ YMûÁ©�ö¨‹3ãuscwž¨�÷™Äôü8¨]Æœ¶»°nµq¿‘÷9SB' ŒO1nf’#¯{cÌ06ÿ¢î«$Ƈ–sÁÊø´gÂG¾s£N­ØŽðÉ>ŒÁ~«¹tÁÑ»9¥Ó.[2"ÛÅqؤ6fâW æÌÌ×ø‰™=:¾ÊÅ{ œ ÊŸ�¡Ýï5»�½ tÈš…µÏ)%Óu|V×ÛS�Ïý|áx¿ÏÌõMüúÔNÆèuÈ1Wβ•>/×7WJþ Ø.DÔÔõÂÕo&]€‰Ž&y-]ý�ò³â1/¬ÁÎI¢h%ÒÄJfŽkˆ(4D»lZfÓ°9|‘ú¼}×$6ãB@û©8†æþû2‰žòÁ,‹79û§�Ž-Ù‰§ë¶}C’H,kN n×X®qN ò�45QOl§"� @"ßÉÙzŸïk¯�‡c`:é $LÕY…òO¨Œ,dÂu<Éb¨F¸-Er‘$ò£ÇÄÔôäÑ›-͵5ØNFð”:ÅwïÇ” <;üPab¼Ù$¹ ^j#ëPþþ4§u9³ —…}@Úzâ‚[äÜÀ¯áä�Ýâš8ÅÌA5rvÎ>FÙÀøòfƒ+¤°‚;âñrß Î29qA§1ä¼÷ŒqÆ�×Z˜ˆxÈøžO­&À2T“Â."³ŠÍ›QÞ´‚c­ŒèÛ’œ¼×ÜÏ ›Å>–¡¯ó-2T]«†Êœ\ÎëQ¢L'Kn¸�wö1| Ž=á<·L\\·ëžj ‡¯Ÿ]ön Œþ\›Ø¯o¾õÄ!úBûgõÉ,ŸwàPWÒ˜ç˜6¼¼F^ô¨Â]úÅA•F8us­5³üØÏ�;îr OÏA�¶Md¸÷¹>'álbGÏÍÓ±8¬JöæÁF ŒçŦn*�ÕøÛ|S4`]ð,ÓÌ×+¯WOVå .ìíÛ[¯Ë�Oä…�c ÌýàE9õÑÁ{Ù)8`ž1SöAñ'%5dÎßÁ¤Q ~å»gtóÎ×1ÅÏZ¤7I¯zØ•Ôp®L2Ž “룹̼7q³ƒirïB™ø@ÒÈÁCÆÁþóÜÁD"ü›kóvœ!l< l„O¸Ú� h´´Æ‹4’Ô‚qâ7'ËáÅž4?lh,Í‘5Ö$T%Û1m€W‰*Î[oêŸ-™›G\°1ƒgÔ³V#Bg!;øŠ_è%‘p›5 šãƒÝ›Ù×çëÄÄ4åzAYeâxÿ˜ØØËxs•½&ÎÓ΃…L_ñ'/ ®puàÓ1~Æ?¸„µ…=uB$Ö,{r¼H| “\!/xi0x�3޵:,]žÐøaC èVzãWá\©!u! £Ú"sááォj5_¿™ ³! ¨?öˈ$Áí„_ã쯮¬v‡}þ�Àç}C)6ç*`fÀy;I†×ø7þX¾ÉÞw3Z‡îYrÄè, Óê¼ëˆñ0%êÄÞR 28˜¨�Øv¼7@>E�>’c,/×ÖY»€ âÄñÚõµ¨d‡¿Í]Ÿ}-6¤ƒÇ´<ñËõ0¾Ðq|äpU[t:°P`3Uˆ_R˜–—æ¿Õ'�ôY7Weø¯Ü…ìúMH9û¾ùØÞ1µNÔdät—FñËÏÎvI~Öß�Ÿ¸€­ýØó†؆©ŽÌ¥Zõ’óĵåìUû->8¦’ÙË%¾Sª�s-÷x¢‡ÈÀÆ(㟙PŸÙçxuÝ�`?�Ôë™2:󧉪'/êíÕà gÛêäL!Òètä¶&¼Í‘£”Ű…²p{Q.D}Òã0Àgí÷TèÔ!� ��%kéü¥ù›úû;ÁH‚D÷Í¢±õÅQô ŸÆó˜8FÊ€É�ïø¹šBöÅØÅžØË9¶ä“"\Ìx2ç…Ý<ËÀ¨‚ à ›Öš1¶OvÓp-z„Ãíâ'Ë“s6Fý‰Î s¿˜|cžì’_1S÷©ÅøãÀ‡”Ÿp¤¯Ÿiy ÈLú§¹Fç,l‡_[óá�ubþæüAv×íÀKe”1ë{ƃ•@ˆÜ@á[«%¿1L7u^²Î§§ŽÄæ .Dõ8ãpä‚�PÇáœ‰Ž‹Ê=¯½ßàŽ?~MýÈ•qæ~á?z¯7o4[{ªoÉ=AÛ1¹æ¶k¿Í%±Æè°=%Å@¦U�¿¯Ë+.òmãõ›5ä¼é ˆ^Ô×Í‹·ñÇ×hâíµ0ÿȬ$¹MÎÍÓ¦áHŽ©Ky²Ö©{;#¬Ã×JO6\ƒ²/“Q¯¿÷±˜³g€m-éÍÍÈ©k9õùTÖ'>IÈ,<Ü|B—9 ÖtÜÀÉü ×sYƒêÈ«5ê‹¥à`󆇉3�“3xÍ+!ðK‹.9�ŸM/q‘¹–"ê§pÔÃ¥cÚ5I,�ÑF¾÷’=FÇ>›Ú6h<|ŒwŽ`Bk=ácQãáŒ>Ï;âÆéÑá~áÓçMÔ´ÜT‰�o>è¹ û=ƆçŠ\·¼Dq]±™Z>\ª†›ãi³€Ùç 8½ñÆë®'~¼Ù ¬y„�KcM8è)À¼¸úF€zxRã�~ô£c¹;°Á0·Cñ‰®Ó¯¿þšÿ{0½®ÀƒÇC}j€Ÿvc÷„ j¼î Töë¿æßºýâ/þ¢ÜHQ vCÞ8Ë�˜ö€—™IÞ�þØ�Ý^yýõÛoûmï»ý?ð·_ø ¿ÐŸÜ–á̼î`ægþœÛïúÝ¿óöGþã?¢õÍþ{V?E&ÿ\„zP‡½ß‚�Ú’c" srÿÕWŸ¸†°æo²6 ?yC#Ö|;j>9 Ë?€@ã3OæÄd}‘ë–èSAyn|íµüýCs� }ö¦þ±‰jîàÍþ•ž•kà$|ä ìU$kz¨26Í ­cÊq"Œ×!=‡#Ç[ó·žÉRt|óäatêÂ\ç€PÊÜX�5:šJG-œt9ço¨±¿³¿l眃¬ú|š¤ubL *N{ø›ŽÅÈùÞózYvo>‘„˜:xOk-ž`}Œ‘g æ´ØVV� o “µ˜¤Äy³·Lð°}FÏ;œ/ë'@}ÉE„y>¨uŠ:µµ9z·ÄqPͱGE=vöós¼-†ŸÝÔ?£O«ÑòžŒÑÕŸµ'Zê$ý˜Ð-z±à*Š…rÇ]>RûÚ ÁÞc‰Õ ŽM-ç5Û¶;±Üìc3Ijb­‰½1êwZ$Ï‹ Î8…žVDÆÉ�ê…_¯CYšÔ�ñ†(V¸´¾ ÞñÀ}º�ßÏËrŽV° ÏÆàu%OS}-¼‰cŽÊa|Š0Út'·cìü&^c-Y�äGŒmwFÊù­«º®AÚz¸£¾-ƪ‰Î§þÄ¥o\õµE”ç(za¶Qy ­ wÄvN’óŹC»äkß,[íú:Ž ·ôÂëùŒÎ×ßÉî:ÏpZ›ªÚ�_¹ð¿Ò|óW7�ÑÚ7OÛ ï”3~�‹«ÂÕ1Þ¹?4 Ëb`Ø_²óÍÌö—':ÇÐŽ‚ùÐÝñõ$µ°°“A“°E±xð $Ûu.læåLQØþO¡ðÑc½�Å GdéÔ—k|’ &8Ç7#Oí—öß±±½kÁÁÑysn�ǤÎÐu^þäéZâ½›ówÍ‘I7ãÚº§N“CI;7ÀåR.È<6T°ê�ˆ¶Be\“ l²¾Îùp@Žžæ®~²±Ee²¸â¡;9.ãØb &Ô%uA|�Ñsê‚>¢µ&žç`ЋpÇB•“mz&ù×./¸q”Át\ü&.|ÁÃ-ãÖ‘uRÇfì†CcL5 á8ÛŸâ�ɬSãnÛêᑱiÛž¹rSì|²gãâ¿9ä…‘ß|ɤ1Âaû0ç+ò`dÕ7µXÅÛ^`O~Ž]ÁØej€¯úÁgåë1OPÈbC~ÎÙ¯FáGÛ}òdŽÏ\ÏlcÉe�Xì�àÙ*iÔ7oT3&ýpg ±üDŠWìšGs)ÿô`ˆ›mu  ãy¼æàϽ†é~?¡œ±S¡œ·ñ=yv£ï<š=\’“qV~[>1∉:àCë1&ÇÆ �zÑÇ·¼X@4J„Ö–š±î|¯µ Æ’ao ÞL}­t�Ë‚óÅ.s§ Y[UÞó) VÔA_¸œ¶R¹�»á°‹0�Ãz˜s8ëÅžÙ{ Ì\wÄÔ¼zÝΞó^õ>N¶¡¤±÷dÉøÊwzÆ<ÌÉcå')û¦§¯Ç²d�y~iÞ+7ç3P†D ÖÇÀ›s)çÓ¾ø&È‘¡û¬Ÿ'‹*õá\­�‡N�{à‘~Å›uoë>ÔÍÀe.Y9s³/-=¯‘ym„‘¼tXçÙŽ‚�8Þ(ˆæ¯™»Î°Š—^*®_Zæ]o,§9sn2·¯0½gš#aFç~âÂÇö�…6\Ì›ùE¡qÏ�ÚXlÑï# <Ú2³‘j>ÐÔg?"ì<¼&A!wî΃çëȨ�¯ó&¶ólt{)$ê˜ìs62b<íWûöÆ“]’`ÐVàá*>,´üÄ3¹´ß{ŒÎú1Aš¿,&÷Æ#oÖ£óÉÇÓ^Oʯ½”ÛA“ÄvÎåpÉùäÙ†ÐazòJ[ƒËüä½,儜/Zl<šñÈ}>3ÎÃö5eøÂ ß´b^ò“žΉ¨vˆ“yhX�1…‰Ÿóéu>!ß<'˜eŒWñd<âg^ÄÁ\àÆ2j3ÎyI,çV IDAT•iâJ'r0€ãµ!U ¨!šOãîX–ØøÌ#�¨“’±­¨r$žŽçäâë×Ìú€y­ÙÆnþ˜Ìu»!ðÑ×JÕN±oÖ;Ï�ûzg|¨v¦‚Ø@;Þ®oâ�#šñ™Ã�G_HÖXÀÙΉ‡»ã éÚÚËÏ_v’çSbÙ]ö+–ãéš=Ï᎗“ÛÄLü�S çŽÇÁ?÷€¨'Á~s¥N©×ªÓÄ«m8ßñ0Žå¬bÒîûÊ,§>¾íÐËÉrõu"“°…M\ב�çœì/säƒ�œP¼bœ3B׆ŽÇøj‘¹MàÃCëã×3&N_wÔ·?ì­=ä[çð&üÕÀуÖW—)åçjc5‚$È<àô´©A-ö¼0rY6 ¡:-ÞÀkPZ!ë1ÀÏ –Æu¶Ù KÖä1ÁÆ_Øb"l»Ñ#Çg½X[ñÇ¥Iâ_?| ßbDŽÙm�)-o$èæðA׆ˆæ\á\@K…ˆŸ�˜“ɺð³ËÅI€àÔ}6‘FV¿u&Fð#ó›z˜ Èž[ƒƒ$Ómx?ŽÙŒcjqÇö.ØæcÜÌSƒk\°i¡\r« â¥8OqG¾c:<ín¹~zᯠY~‡³}ÇFPa1GqÂζ˜aÀ|ì�-šÚ £éȨºˆÙ”-=âɉîSµ`}*-Û¹‘l­ ñ\÷# Ì‘¥e¦>DÂpã}êñ¸¯.>ööÐ#§FÞÈQ_]æ†ï¦�íð±o¦^ ð+SodjÍ{çRèâq~4O9x(ý3PÖ‹ŒÆzÒnHt‹›FŒ�‹Ü\ÇÙÇÛͤ fÖܹ8Æ�åÄ5Ì� ŸñÇԭ̸²�r|2Ø1a4<¤õž�Ú Ûþ€; 1äÿðÔÉ8dMˆgá]ãÛaùŒm…“Qy-ÅÔÏ ¯ÏÌ›»¤Òhµýb#[rpëõ‹ µà+ñrã¡ð½¶¥Ï“»ßP ×öŠ�¯k²j–úLPGðX ®‘úõb^Zç3e=Ƕ“/ù$v°…‘‰„í&Šº£á§7p–„ïV¢kâªÑÅîvûÛç¼}øÃÿ«_ÈXV›éñ£Ñq£°Žpomt.ØIÎ “Þ4ñM"�S_ñ¯Õíå—?ßëç¬l:â1L½oþ/Å?ö?ý­ÛÇ>ö³~Îæ§é?ûñ�ݾù7þæÛG>òSyV¬ø:ÀûÝï~ñö;~Ço×(7PV­Å —¾iéÍ7‰œõì <�ZûêWºiŽ� ÃsÏ�…»Âáì"h\=þ4Þˆ2NŸq †–ý@íç&"Éêë{wÉV0²±5GÆö±šš0�f’³¥ØX‡ ½›$’³þpçÁNÝc¸sá…4X¼6U(ìùÛzØûSm\­Qþ;49ò2™kp°ùä%Ÿ¢bίd÷o4öoôyÎSÏÜÆ·ŸÀScço:rå+u%nòi~¸6æ+èæN““TK æÛ½mŽv4_#ðž÷ÆÄԱ̗5Ê:&R�r$âš�zÂP[ÎG熾ÀðZȹ×?)2¦:»…¯Ñ–ÍÖÆ6\­ŽJxÄ1zµÄòÈsÎǶçͧؒAùÚ+DŽñ±µÅ×6™E_¹wûá›Ç"'“¾J*uÕW>c3¸NVx£’'©s[óÌÿ:úò ó¬r§f=ëT;úæ†29z€ÓT†Š„WŽVI‡/Š3ú®gb’Sì˜[€9>]ëͩ~Ù”Ÿ�šà^ÍY´ñ3_؈°óÑ“%—ð Ì:4L9:7i9·iœ/. )»0â…Kø<-!<Àµ”\¸êðŽ¿á5 §È‚­q§¸µ9·àR‡øŽ�õƒ�¿©3Ó{Ðûy\{bmü€“‹óòÖƒºpíwh©"Äÿƒµx ÿÆà†”kgèã<*þôËâÙg°™o¶À>6“ 6“¨¹É×¼¹1ŽxÆ�{ÛžµÆêdnòs?rHøµÏã|{bF§‰�›‹s8Ç’£~£ÔÔqÑ�kð˜�­3 �¾9–«™Íë7é¦>ÀœãâÓ_cÄ®ùY'lÃS×g°Ö«àt��Æ<²‰S¬¨G7“vðlC0u¦9—µ¸Œm9Фy®¹,x>>ý’?dô�ŽGd³¯†ím§‰+MBy1cðXàÕYN€ˆ@3öbœM:d)Öž[7ú± 8²úºv“± µËÂ3·÷ÛXÌõ Ã†|j‡µ=&�™¤CAêÔ‡)mÍ¥«%‹«=åŠs|8æÅ$}(|2·~¡ל›×À×áˆ_®–ƒO<ÇÔÑÊt¹ÃnÍXH^}ûq 7ç7rç#/×óUNR©ÅÙª“DÎyêŽqã`®ÅQòcr©_çù‰SßÝω@�†ouæ&yâ€ÜXpe"�_¤õÞÜuÃö "¿ä¾ê�z§6^+|ÕÊÇ“6gÆ&”7fœü´rµrôÆ`ìyro »YN|ÙÜ=� ýøk>¡ž°«YwÚ›üBVÎkâÐ9g cl<0à±<1?š�í—\²wŠg„•PÝ$]É ©¶Œ1¶Ôh"+Œßx›F¹`ÿò¥ÇÇ¼é­æ€�'8¥æ8_ÑOáâ7vã¹ù�ñë!¿è© Æö@gOœçNB`»¹EÖðñMÅKLMh‚\<Ib¤u?uÞ¾ËW Øå ­°ðå|6\âÍØ~§Ðª½Ÿfjß9ćJ°çqy\뼤 8GÂí|j#,}™;v×É › 'ýö³7œ3>N<ÇÕ$vFp¹Žà8›NÆùÖàŒö‰nt˜ëÊQìÈ�–5šÉÅ}×·ÜÓ'—xo"©YPñ3'õÏ2"Ÿ‘¨ïxœŽ¼‰�4¶Õ§·â*W|ö{Žx÷uDóIÌp1ˆCØ{0;Þ9\R¼N¼>a´ó�‡ãj¸MfóØ’ÀâÀcš†WœC7&{-* ‡ÀÌ_Î×¼vŒElö^¨}Üñ÷Rɬù¬õÂuÖqyÉ,ãIï¶8Ô £QÉŸ]Í4«GÀ`Ô¦^Æ,Æ×Ø� lflŸ �Ìí°!®ã“‹¾ý¼q# ´ârò�…ŽÉaö8\ÆW»_Í9ÏxÍ­é� ÖïMf8±:‹™ùŒÈ?p·sr^Üîj¼"f>„ö8q›#(Ñë(‡eëx¨wŒUƒvw\ƒˆhkZÛöºí¸šºh£ü9¬ñFënW×a}` ®~þt.Øå5Ð%ÖÛ� ÜÜÀÕ#üNBÀ‚s²!B2¦�Ž7 ¨·#Sš@à Éà¢zÃ*Î¥17®úò‘\9�úbÖiÙÑø~k‡ŒGhØÖEŽÉð¹$½}2o~Rj|vèÜär„ŒCa½3)œ$j zZŽRµ±§ÈÜÔ1Ê›Ÿˆrp+ccC)“+X k"ImQq-{vbÑym„€5H¸�gÝf,]ñƃ|'”ôç~°Ò^Š�ájÌÛ‚i?‚bh/ub…WrHZE. ùø¸«�4Ä7ù‚•Ô�7¯©?ò¯mæ‰ ôžc7uZòÈÊaÙJ캂m!µÂ¶ œH ÌsŽà­xà²×s¿'O­† «ÞrL¡Ó¾ã‰ËÏ)U–0sn!uÀ8Úðå÷°ÔÙ4èñBÍ{`¸®1.vgâ s÷Ts'¾9Ø?v Y¡Žã.(ê“ñ¿t`ÒüI@½: ®¿ª�Î\°(ãÞ’ÆsêD¼¾@Iþ‰½l´÷?òS?yûéþÓ·õ_~ÁŠ„wƒ çîëº蘶ÉßaÃ\Zo$ÀÓMŸ´úy?ïûoö!ͪG #Ÿ4|ýöCé¯Þþƒ?ü‡�›‹¹ã?|I@ÿzñ?ü‡¾ý“ÿëŸÜÞñ…_ÐK¯øYí¼�Ëpãoþ’_ò/ÝþÞßÿ�ùvq£é‰nþpÞÿ}µÅ PWE½‡©·Å;#éºï°NM¨[ëo<'YäôCQ5Îu©eä—ֈV™9œ×ÜÊ =™ƒéŠ“ÀXcé¸ê"Ÿ®·×uÜò–hНs§û }ã‡=kBcœ5¿^Ïj1óÕ–«N&(›èkí×Àp“€=-óc�¨9¶ÆÌÖ˜9zjϹ'-=Ÿ…3Pü¥Ïø9·w¾ó^wþ;ðsÏ=w{üøñúUá�|ä#·ŸüÉ̦Öß÷cs³1篻Û'¡,òëuF®­)Xn†ãvŽùAâì�¼Þ·ƒ¤þ§®!Ùއ‡ÖJ'WöfÓŒç¹ê‡B߬#_|»¹N3”ÁZçQÛ.®¼¬)£ Npÿ°òÍ¿øóDÃ�øÏûÜ—oô�~ðö/îíÑìù€íõ'Þk¯¾zû;úðíøŽÛ?ÿèÿ£ˆy“N=l²Pž*ÁÈ3r†÷j#ö|öÑØ¹j¿#¦Þ˜ÒX“6d¬ �œÑX¯15ä¿RK½Q2n HÀAfžÆ‘¿(Ž"Ê{à/bëäÄÕO¿È=ȉ¡É J͉Xc ˆ'�¥™Œƒ‹QZ×­Idž1ùzÔ®óà&1‹AØì=äZ¡·xVrS_”æyTã�0ž³rÒ—¥ø F¹¦¶áåý:öè“_bJ€3ÿÈ8:ŠõŒMdúÚcE3+›‹Hx›Â²HTOí³k”ºOR×µý#y·|æé:ÓÅq8¸0)Ò*e¶•nb…ÓĘ®ç()wXÆo­�A¦:2Ì^–¯™ØÎØA4®�Tio··än:v¼ÞôK Ém¤«}ÁÃ/!V Ñƒ�c^÷0¼¼Ÿ`íÌQ×$õàxç¬XWn«¤ ŽÍ}<£ å14GöröKxÁGXOÓ^ü‹çë¥3ž¿ÃÝ´#X>k.áÛ£_†«a£FaÞœ,sK­Ãe“L% ÇR¼½"Á4¶€m/ÛÔÛh¶]8šµ6`Á]í­sÑi‡&EŠ™TÑ "ÑÇÄ–±“üäcXi‚�ßĶ„±EÀxÒµ¿ñwåà5œy±é‹¶j#aóó‰¯å o¦¶½†'ñ¶6p\Ü|åƒåÙ–1¤H ©Õ0nüqJÅPp}FOç~m±¹Ÿ9`cÞ3?ÔêèuŠ#dä‰!4¾y £�ÄoÎM^ÆÔÁ'W–¡1MÈž ãCÃ.&¶ŸídŒŒ•Pƪ¼‰D? ~/Ûº"N1ðÝÅÝ\À6î+gÁ dóLÕdÞ‘…hû„ ÈÔcr˜Y®Cßlå‚)k–ó‰ù8MO,$¾ zID¦.ž�{ǸxŸKî5!Bùã�\²k�ƾÁöùc®ƒþ9ÈM×Qäà²Zc/Aü‰;bóëzáv­ N€Õ–¹Z\24Ž8ZF4þi¬`¼[ŸÊ1æð'†ö›]eg,DúÚ|¢7p¥O,šßqB¯ïi©agéGëxúOh)†UûÍÓq?¡?ÙCš4ƒažÄWÆP:ÏZclw£–äe�ç =h­_æÜDæ†Bâ�½·Ò :„Å�S¸S–ÜÌà¿·ž þ†k~Qh‚mR\=våÈÍóž_àpƒ ç4~Æ•,çSÁ”ú\jí  /BT8DÏê¿÷>÷¿ž ü‘@‡2Bþ ~þË·ÿö¿ùsöãæß«ú›€ׯÿðÿð£·ïûcÿ™êΧõžõ? É ÿú”ÕKúäÝùüq€È£t‰£19þÓöÿê¿öþ.ñyÞL¸Vù1‹ŒÍ›�±Ûß¼ý™?÷_Þ¾ñ×ýêÛ;^xÞ'}BQ+®Ñ¸ægþ ®­oÉïŸqjænȹáˆ<${ê?pÀ.ŸQbÇcÝ´1B¨‘£ß´†Ø™h˜€—ñ)C…ÊÂNÈ5ãù$SË|ÏÈÏE9X¿ä+[ì|=ŠŽyoÈ�‹-­ñ\CdŽ,6–K×¼6t>Âàº/LêÂÜ7…@¤ì[æÔ=þB^2ä賯éÃÇë91tþhíÀù¬÷|öíþÁï¼}é/ýâÛ Ú+¾žƒ;Á“+x9—=záö¯ýòåöC?øçoáÿÒíû¾÷{õ�kû_YnÜQ?�?ŠåO‘âl‰é;wÃbæ}ÍÀZö&üyC„iÈiY7b"#*cF±AOëœqkŒ‰åÄÕW×ÒcíCÚh°pf>¹ÐaÓ«¼n�™mq¹k}2ONV¶fáꄜ¾ûÜ~ÖŽ~°Ê UmOÙ¸¨KmWaœ¿Eä�98±x�3£R;Éû¦µ¸ äõÔŽcˆ[9HJL¯§˜4w^ŽQ–EÕ.Ïöé¹"ËkŠ:Ö¾}â.{w©‡u°ä4ŸzÀºRvX3‰bï�¸�™žÄnÀƒ,fã„{ΉÁ'Ü%ÖÄ·el=œçðãdüem‰Gààb‰ï$Kަè˜{}À[k,§œù�Ðì‹‘9• FX �‹ÈƒúÂsÛ¡r½–høL>õ"‘ØÎwŒIP9._¬/“í~Åoí1aá•}抰(�[s™©xd„=û+5$¯ÈÛ ü«õm¬¬Y_¯$¾BÊ¥Ž!Ü�¶nÙ™¢â› ÑÊ0ãúº/Oö;f$¬¾XIêvñmp|Ôš¯Çæz�m#ìÆþXnIirjqë„ñÆ7æÛÊÁ¯�Å™µÎK76p¦¡¿ÔVv à.¶÷V™ŽGà`ÕIÔSÉGL°ØKP^-Š#!¬zFÃ�‘ùÃ$[cL´ÖùÝ#bb¿Y‡Cä†ÃI­6æ ש1°‰ýà5·Ö^Ű!r]NÌ]ãU[DciŠg©1ôZç\ TvÞvCÄŠ8ÖÆ³ÈC6¾Œ�!0M��=¶<`’�É( ;¶ë<µ6FæÚŒä0PÌßõdvÆ_Aʶ±Ê‘8Ž…émóX\°™‡«xrûòÂÇU©�°=„·GÌõ ôƒ·x3:lì'»Ò”Æ�Xæ(W—ØÅ�ÅÅ©ñQ�~ø Ety!‡çInÎAB8˜èÛC¢ip[C:]��|:†T}ß®}±cõÂ#Œ‰ï|ˆ¹b53Âz¬ÁS¶c‡µVÈL0ë½næ­€ãäøA·‹s)?Iil&öQ‡ûx{î·Ét ¿l I¬ 3E¼ä—°ñ—sléMFN“y®É7Z޵S³ Ãûzi™íî­Q­§9â…®ÖfP Ðζ™ÜœÀ° '�ÀåX?p 3>ÖaƒƒZºÔy .­WÚ¿ÔÑ7š„Ás 5àà@káºÆNvá'µ- “‘�Æ‚Ïà!Dö´å/9v¨9®úI FQDyº{€Þðã0�‘äòüéxñõ›ƒa@縀á¿Aa7óQ2�ØŽ1˜F�T$¹ÁŸWYHÞºý³ÿûŸÞ~ægôB4C„ôl­8|ʱyÕ†¿ˆ kD£¦ž#Óƒgóþ‘M{L²â©wòød/¼‰‰]lŸæˆ%kUœÄµÕ´)CóÁ IDATðcb»&‚XÀ`»•®æØñµDö,œÁEÙ¼Æå0ƒ«›àXgÏ&ró3¸¬Æ”)篧ú֙׆¸‹µµnø+‡Ö=×8ÿ÷ÁHÙ Å7ô‹OÆ1é]Ÿ~ûî~÷í¿þ¯þ´nèýË·w¼ó}ZÔ¯ÒÃ[¶ ç5JRáIÌgï3>ã¥Ûoú·Ýí¿ÿÁ¿xû_øE¹I?ò¦'J×BkHBÆÕ`ÆÅ'^ÛªŸø¶6É)®Á$«¹ÖÑÄ_ëL>Ö7µH�c1Á±¶sÆŽYTe«�ÝâéOºJüÔÓ62v|t|-縛€#rÞ:´žààß ­ŠR�èÙo„ê\+8»ñ'�º<Í\Éa—zŽoñ7d05ï5ž²N ††›œÈY{³¸…Iå…‹�€1ö±`t3v޶¯œ=V瀄O$ ®ÒÝ�¿£a>Ä\›°MLÆiØW{Â>x5¶Æ Gv6­Ol°m¨ýàPûmjm›%ôlh/œÆ,�Ô ù¹ÆäÍ•a8€yÎ,Ýd~µA*«À„,’æ½rµwqð]ë… ¥"¨ˆ…•BÂõ©Á©�šçA‡°é­0D±sv¬Äl'ÿúÁníu°'lƒ# ÉZLh÷ó’ ‡ÍÛµÿ+ð„0 ú6築c�Uðê1ë)¡ãWŒ˜²âºG­éaáü£K|ñ„G¹Ô¾æ­ßSñBtÇ*/ú%Ø«Ï?�¤\=íZ‚áþNhN¬/p $s>•A,«ÆAó´ŒÊYÆ«èOîÛÍ]^‹K¬˜Â{÷·^@rb–'è¶âéarA^�ö¡4šO1‹±,YsM@ªM}*_ä :>�&‡øS7Ëðz5cÎMÒ„'N¹:Ïå|χ9‘xXçübÕ7Šà>ÅF&Á^÷íºÓ冭ù Üøä×�„Mµp&p=õ£,¯x= ëR>­Š¹5šåcÐ𛼛ƒ}fM“Ë™íäŒ><†ÍÈF®™å“ãØ[¡ñUïøÐÌp�­“ÒÐ6Å¥ï:öT«L þ†=hîk£y‡ô6Ó¡²qq|ÉÙÈ5ºŽ™NméÉ…¶rÔÜz Qä±p-hPŒ®-9iÀ'ìçi Õ·Àñ'~Ó%Öd§É 5<öáPC›8hpS‡Æ6Â�i²¯ƒå£”˜È©Érp½Ê×> ×Þ#B6¬Ùõ7¨ 2÷:8F†³‡ô¬µ6¬~íÊ…‘˜{�kêºé7øò»¯—tˆ\sõnð3Ž#;º®_T8WGÒ0F4©ÙÔ(‹Çþ°[Жi6ºÚ§¯U°S'ÆÙ;xbˆý˜íykUDz´}€tÙ«ö±³dJ25˜ ˆ9(éí“‚¸¾5Ë$lê/ ;;Gƒš–‘±+¢ÇyŒš»mÀ• 7çâ’œð!?Úi‹ˆý°ö8ùÚ*µž”,‰/ŸF+–,m�lðËßùÊ|%@œš¢ãÁcÊlyÍÀ7¯yAZ×›““ý%ܬóÆ—_�ä†C…ñ­7u“DŽ/¾ëÅÛCýÓc¸Ä+nuRgoIÐø�Ÿ{¤ÿòûå·ÿüOþIý-+F÷æí¾áëuã-âßsÕB.ü£�¿ò×~ìö×ä‡e£Ê‹&©ß7ü”ùøM�„ÉQŸÈÒß´†úvzÓfL])GoúŸzpŽÈ7é¼þvÈ|†¶ižÈ2ß Ò5®¶ì�Ž1ƒžÛ9ÑêlÃð‘±'ÈÒˆçüœƒÆD&¦¨qÒw¸í5œƒDŠMh6÷aÝ,Y7»ŒÃrÂ¥7U|^kn ƒ£M‹=*›ä#®Ú“ìËä wòWüúð @nj™¹0¤ãƹq³ëÁ³�ŒÃüÑãG·oûÀï»ýÐ÷çoßðu_u{é¥wú†Øã>D©Á�T·Æ##Æ£ÇoŸóÞ÷ܾó÷»6%ŸŒ2|ïÎï•!`©�Ñq!qõ ‹±„ÎÙ–S‡ØÙ8+Íå `Ž\Ÿ@Ö×ô¨âc“9H¢¼xÐèVÞžŽ^ÓàÏ£¹Ön\O’@©Å—‘9ÈaÙ^â¼ãÚÆµI�v¼Üî Çå3©Ecú§¸¬Ö µç�: ÏÁÅ®Í?XÌ�k´±ƒIí[¯#Ç §&EVo9kqú{LJ;³3¿Œ-]`®ÙàLÔä®Å1^ÎÙ!%޽c+¡¬‡ ’œÝfÙ+~÷XžèÀH‡6¸ä—/ËlÀ¨XÒûyOs¾8:ÆÀÑ’[Æ9–weÌ1̃ñ¹ö0Øs2o ü3f´Æò÷$9Êb‹E ëÓu‚›Çè3n {¦®Ïò‡øÙÊW²ÉéBSb\WŒE&¯…‚UèÚ¬xŠš´ÅfÇkç!­æ+—íVw÷KLQà A —Öœ�5"Ç.Y�d „aêv‡wra|â_HðÝMP$ŽÄ kW]do܉=jóÏ~²³1¬»Ååð‹=ÑÒÛï[£Ë «P–æ¨�åæhyÿ3\G¾ã$FoÉ5ºù»ŸùÉ;Ö¨v ò8[85÷wFøû!ÇÚ£¦èÁZsÔ϶G-G›Dß®á“ï•Ã2ƒSýˆk;úì�|F³Q �Ö¼,Z9Äf^™QÅM3Kr˜A½2@<6 ù8`lÐ9MÆnƱ3Àoé �¶I”iŠ/LÆ3g­†«Xƒ¿¡gT{Ù'rûiHïå�¸ÎmâáP¼tsAŽ ŸÇlâÚ@‡à‡µÇÄ€ã4cbGäCGG‘˜Qât�ëµÖoÁËrôôõ[jÁÕ/…GeD«mØ`•O£o¸ $±5Çž�`06®‰ŽdÆð1'‹Æ/²1 ¦&Ž:ððø“ñêc D�h)5»ú/t˜ØÙ�ÀÓˆÕúâßæñžšSí°Íi„ÎÆByR44¦NLlÎ9&|ù�S»iu8|\Ûëë!b;ûö)WÈ|n:ÈàñM¡ò0›‚p¶ær"§†uT›f0èÀ»5+‡c|ÐrÕèø* ¤9ïÎ%Xý'á•@ òú­ 9ác>Û…?ªš‡8¶ÍÉN¶LYëè<ÎeÓâËnlþ›õât̰—T[ÓkïVöƒ­¹TËı]ýT,ì<öóš©_±èÛZe ˜‚V²ô£]ÙÜXîÈ[ÿ¶ŒaüŽ‘†“©“i�ÇIí4ÌI‰Üâ1Á?~3e Æö§ {´÷ßÏ“¿';iÈGÔ.mj ²|p¯dX£EÖ­OFN*ˆyÈmC‡.‚å÷pÊN8ôü«ÅÜ? ¦¾ð ÿÒ /Èá3iBk[ÿå…zþъ·–ÝóUŸ¨Vrøo½;Lö˶.˜á Ê@—BNŸ?tÌ9U4_�Ýg}‡.”•ØÜÚíØÍi}h^Õcch^z¤Ëøx|:~l®S¨ÖkóÁÏèõÕyBS?›É].—‚YõUoó¶gÃï E»–�~¶ÓSs€9σõ±�i�‹<•?FOÕhò€ã&ÙŒ¦©$Ì纸ûJÆBcøÒ«t?ÇüúS^C,¬ãtP¾yI�ŠÇTöà€lœãئÏE«—7Å W¨—:¯GuÑZòób�=„…5#±S"A"1Ñv»aࣥmXNÛÞ‡F<^„ÊúÆd½6'³{›%äc†Ñ×�ŸL‘«x[Ì!¥8âY#—Uò„× ›2yЫAsþ’K[ƒ¿a}2Øk»qEìL;~ý$󨃼ú }ü.gáW’Ùf¯ÍÈC‚GóJž\ÑŸüYûÕœ(c½t =Þ5‡+^¬ónnòñð@ŸÞ Žm’Ø0ñhQ›cûq.#Tª \ Ï“SípèËu†íAïó$¤ììyä¯í ßySK[çG{ofX'vô2Òìùs÷Ù @%üº${^eõ˜þ ê»<÷Ý®ÿàýß÷ú�ù¯ûÐ?y½ësßY¯þóëöÌÛT0ùô‘LFÛeð«a„0(B7ZÞÿýÞûú3ÿéG\¯ûž×êW&ßC¯.|ªyMâádÉxã›Þ|}ægéæß}ªý‘Çôj@H鯋¾Ùôk€´ &ÎOÆ<èWö.LÏ�ó &¿<¯Dz_'" WIM=‘ðøÞÆ_ GªÓlmC€1¢·o¸[±SVfû Èp=N€¦ãæ’Ý[39|m7ðˆ'9Ï[Ȍ⪇Å\Ç­Õ}±hGZê”à8`¹IÇùñù‡¹…À­üš¦7Ác…;ßT²æ›.?S{D;?ÁùÆuâȤx>>¸þùý˜Ü”¸WûÇtóïžëEøÁ×+¾üK®ç<ëÆ…%G(‘H;™ÑÈ@‡Kж7ríô4]ËÏ|æ³®7üÆü5µƒ|}5÷0–w%(9óäöÒµðñI4I±jR_îÑ¿>û —y%hñ³‡{h¿úT»&Ùðêl)BŽ~ýÒVbXÒ[rŽÙŸßR£Ãa|m £Þ­3Ë¥ywy4æE…‹ë%.!<š×ܲ¬°IžiÔâœÜ¶—K9¬+”>ZË`1€÷yUæìW¶#2ËI51¨ÅRk0å¯0€j4‚•× µ[ßD¶ËUÃT BÃÈ9†1–á¶ËdíÒ±û�³ F�6A±ÉEÐÄm|Š ¡B¯k4[GÁg5C]Í{EŽùºØ¶Ö»d¡Ñß'hbÉA£¹û¹- èÖ@ó\oÙs]TAôqm§×F˜Îð•ûzÒ@ÃbÊ5OŠ—‘ÜšF&+ÿàíI÷æz›0O<‡°bœ{/ÃìóóxaLк5 k1Ä  #~bö¸‰)ÎJ6†ˆAŸ�%pq69 uIzc§g¹‹¢úC@ÌŒÉa}2qÝ­ó­}Üsl¹|�B£|� Ïm�VíÕ¥¾~xÀé4á\>»Å‹Aï=Åæk‚ìÿГ»cÕ5¶rÕïùÐC䙇ºwŸv”íJܾܯLÀïÔÇyl¿68;l*W¸snn4X¤Ëýì'Ø6÷àè>Káz;ì7¡Bôûë¹S,3£=ðÚF2h1ö|¬8³ûS0K'NºÊë8BÝ_(À‹ŒÖ~>B’ùá¤û5A>¿› Z†ËÏLM ™8÷Ïlô$ÒRöf”vÆ{–ü¬>9wžàaç@a44[5'm4x½ÄÇãsÀ'9Þ­ŃŸú-a|¬ccÖuY·ìÝ#ÍÄ”§òðÆË^èê©&HЗfÖºfŸWí’ Ðð‚½û:jüôßy@»CWÌ𱽫qáG’ó&¹IÒƒh¸ `�#ÖÓ¨ÕOÙòµ~²ª¬â:Ëåq»ŸØMQ˜kåó7_$ˆÙ§—kmþ¨¹²Ùžâ­1ü!w;¸•„Em�9;}rô8Þ‰Ã=d�XÒ:F�óã1,ñ� nõØ Þ˜|ӆϤ,4⯎\£ñ’*7”‚°¿¹M‰¯×ÙCdô\7N ÕÍiëg•Eû.¢šƹ›[8°çüâ«16|¶+?JlAÁ[;,^Bo{>Ø�a¯Õ*{lË?¹5iD‘щѺ@e›ŸÎƒÃ^49ÔP‰•M#ùYx{æš u�q ¨þÓŸrNBt߈XyVþZóuÔ†ÖžŠ¼[Ò·Í3cï…\³&3_éÚ“ƒNœá#¯¹m‘ ÞÊvfmµ‡+sñÌô>vrõÆ4>=‘´ò—çuŸâs=�_@°µ�k×NÞÑÆ“P´ç'–�]ßòÍß|½Ç{¼@7Ìò7ÿü$Ì C„þšFþ³ïßøfÝy‡ü­?ˆùº$ŸµkAØCúg"Ÿú)Ÿt}ß÷¾îúØ¿ô±ze ¿v‹ é|ö6_�è×q_ûºï¿~ö_ÿ´n(ñ*/^íE�©›¸¼ï|ô4çðíþç%÷êUb`¨ØšjCcþ‰Jüâ½Â(Ì�Ý)íu³”xÞðÚŽ˜Yw±!^Æ 6Î48(8yTóÉé5‡#§á²›ƒïzô^êØøj"ÛˆØ~€9¸8Ðí'”ro̰õ'jÎ�®Çé`Gl= G‹bÎÆñ0÷„aõÛØ©•QNòòV6땳v°„¸&ÇÉÑ,Æ¿Y1qšOÖ�áõ°¹ÖÄ4vç‰/à ´Ijïìª�[†UGÀàIµ¸Öm±FŸ‡EÙŒ©'G9yŸ>î@kŸøSy�ƒÇèhª™o0§o¸*û‰óZç37„ α¹&éò _ 3�ýˆÅLlë.çhlg€Î^KiðÂá|«•Q*ïd®Çsð"®ÍƒkABwƒ%_ΧPÄxâÕ <ÉfT7HáݶüÝV¹ÖÊa‡�´Ó …9oÂ!]+Ÿí]¡Þ[HûN¾ð»š»ùÍî ¢kojT„CçúÒêô¤œ‹~‚b?ºœ8ð`¢x­·É¸æÅOMAs´ÛÖÇBœÖÆ2±¤ÝDã45c]Ó¥¾à�—ÜzT‡eZ½ÉÃD:Û±´Ù ‡}´Gð6Ÿ67ûâ5ÏÒÓÂ(ä„XÀÖ4[ëÜY@üp´Æú!¤K |ÅÕ–}ú�Ób–¦úÌàLÕ¸úSÍ‚4ÌgXnrðu >û!o ËY»ÿB¸×>Âë,ö�è¨õSŸþìëÝßý]õßrÒ¯$߯›xÂðuù®¯¦æšù-oyëõwþîg_¿¢_Õõµ0ª«ƒdn•âßå]Þùzñ‹?õzß÷y/ë@zôŸ#d£Â7éÕ_ù_¡›~ü ”›9ðŒˆ™HEÎüŠl£•|ïøìwô¯}eLݲŒv|à}#vòB�^Þ¬‘DÖj›¢ä8õ׌wÖÁª#Œ|£+>³]¦Cߤ¶ÖÎËB˜äŠŽReæCB ‚5Ñ�¹1¯ÄãS»µb'lzs›[\F}]˜Ë+õ«»ºÑ�?ÿl…_ÑÍ«¹ÆÉáWjfs‘Ÿ_ίÿòkÀ½¦Í§ÔŽWÎßýÜ{}üÇþåë¼ìï_Ïzf^ù—¾Ø6h‰åëp´¶a™Y›êr¦¦ö•ù·»í‡¯{&¶ù‚Ãî¼Å$}Ýúñµv°Ù²'¿¢¬#9lÓÒ?æÌfNÜ+ÚTý uv-"$…vnbö]Gt Žâ gùÀz`�oÅ�ù‰&cpkYü ºs‚l–-L@95PN¶>Ù^XW›xÖƒ—'eæ –žñhŽ- ¨Ì2Œ&_€>c· u2¡ss>‘`Xùïø�ÖîÄÙ®<‹×¢=¸‘ÿú×ÿúõã?ñ¯®oý¶ïЯ4ï„‘ã7Úî½þâGÿùëŸóùríoûÉþ1½ªðÇþÕO^o~ósãD_Ã[ƒ{&áþ›jÄéæE^ýqhçñNô�Ò·•_ÄÕ�8 êgø&ÔêÞ'Îy&9øýñœØó,aíy´øÊŽÖyƱ&«õL^êd™z´XFŸLŒ1³r/lœØcc}æBL÷| %Çý_}òõÒ—þíëé¼òO ¡¬‡Éµat­,f IÆËŒVê=ǹ’~�œŽ†Ë«èQ€ûŒ¾ >ãÊ·tYKxn|l¦G©µ^Íê½= ÅwǶE~n®ëã+KÏð„KªF´ð°Ã#Å>Œ‚Ã}œ“í>ÜÑ[tËsǼ ·) �RÜC­±Û7ö`7nëhŸÈn«š“}ÌíÇÎQl@Öa&ìØ2WÇ × ¿ApôÚÅ)FïÎå8¶ò5“õEœvÉg´¸R—I Ð¨ŸzO{Öù*T›œ ígqÄ$ot檈œÎA@K³,®QöÎ[OµÀ«k0Çhƒn`®«°›sœ¥*Øy—qqd!»â}ÞÄ·ë„ó‰FzjÏ‘75ÔDm‰¥©„Îä•@œ‹ ψP oK�>_`«�¼¶O¼}îY ìÑ`©=Ú8k„‰³®kóCVÞ`Ìíåô¥¡†Ük©=ê\~“:äšc-ÕŸ:9OåóZ&.´ Ï3µ¢eô4ƒç ®e0KÓàGåýܰˆC c®kRè­ZMHm¤ðâjwê‰s¾j‘Ífk!БCž(›^È_-`áÚÈÃÃûY‡dŽjTû fq°žá<4Ô$6xi¬  Àt8§¬XÀl�V7‡ýƒ!6ÙXi /ËâYCF\?G�);¦Þ\æDÁÉͺûÎðœvök¬>Ãz4d&é­ÆV¼çúç<€M‘,û¡Ws®Ù;ý°˜y L÷è²8ap�›�5lÓ�˜Óï“d{Ù&ÄÀ”†-—¡…yš|‚{â‘Xû‰àºÂ°åqäU@´*ï4ɱC`5ÃéiÖ�º7s"!ö']æÉØ *oŒõµv> ò6þÑÀ¬{Ãf.’ØÜÑœ¤HÃníF+“mø–:H3žíÄœ:b1½¨àÙXb¢ƒù°³¬ôw¬éyjI½®Ó¸€Zõ/Šá;ë1ÖaZ�±}K¼DzÀVƒýÔ0×Åž!î…#Oí�ÇfÌÄ;Œ\`ôhŸVŸëP ­áÑðd�‡÷i¢ÇÙ�•Ëlðí7ã†öÄ�kkh®ÁÆF‹Ôy'¹�KÃ`–^ö* ^ …¹Ê76O²qs¢-p?ŒÓ�÷%4^5aÆGœ1˜á1ÆÌÆf/µòw°îù3Hs‰L@ûq­UÞ›§$FNtiÆ ÆÔ¶ö±æ(Rù�{pKÇàÍ4âA#Ç�Å·9Ü0ÃÅŠóäÞ&(=²�¼òë� 0މËŽF#Œku~"å8›}@‘Y‡¿”7×Ë*(k™¢�…eXGkÀçPÐZ›„GP3…#†ôÙœ«'àòu¢}oè©9}U¼‰é �ÅØlˬ-«b GÏæ ¦×,Ю¡7¯çÔé¼w0û'ûB`žY ßá~MrãÂæk€ZxŒ-1 &‡µQ× nž0ˆDÿÏÚÆg,ŽÜØe7¦~ ùzUáÿð?}•ÿ‘‡ r&g5º'Õ¤$îǽàùÏ×M ý+À˜O­‰üŠ1ÿ4„u¾1cA,ŒüzšãcxÜqõÐu'ÎúTô£üsqåúÈyZÍ)SSÍlÓ÷ãMΣœÃž{ÿ—G#M±…äÚÀNЦ1BÆÖ}áÏ͵¬ý¹°ö|¾çæÛ¼j,.ïÑÆõî‰[äTAnàåoæy˜{nê ¥k5çiÅî%šÒU玂ø›ÿÅÇ}Âõ7ÿËO¸ž¦kmäãʨ v{§£Is¶Ü8·øÀãzýµ_ÿÍëå_úr‰á‰hÒC‹*Ë ü0Uƒ¥øÐ¤3Ëæë¦@ÌŽœÇÖ½0¿gˆÙVtƒØÛΤ…ö䣧�©î†À»òjaŠ„Æ!¯±‚í>W=ÔdÌùʵ½xŒsvs[Šc¢$ž{F4/ÞC“aã 7.Ñg�¥ñ|Ô=öb8¯ÔÑ œ“l›¶êÚ/(3\ £1}±ß>ˆÅ2É良éÙ“ _¹2 àö™ytd�xð'Ž]ý�×™$íOcÁG‡- —�]Ï‹Vô�þ ¿œÖ"Z°Ãɺþb„dù€¶FsNÞeký¶/Q³3%UüÑ–uÎQOjmwEàRcPÙ׊-ú±èÁûêµOF≻{žŸ XÖfžÖëÊõkœ(� *ôð~Ö$wü§k*Žè¹¬÷'Lk9s˜± Aàè×Ä‹�\àñ�µ²¯Ïaìô­¼“Ù„j.-6ï8iìõ5/³© ¤8F}Ìg¿4ú‡®á!Þ‡¹×€�á™S6çHjí_Î�8EeÀq&0gÁ=m³ai œå°vÙÑ“_qÍz Å96HW*Œ!t/XÏkøw#[Ðu;Á§î!€1ÁSÛDšÒ¹°ø�km�-wÎѸˆça+ ‚8z œzn×À’±ú¹@b7g‰…ö‰)^)6ŠÖiÕ"k8/÷ò5¡æÄoþºÈÓs‰�=µš(ùØŒ¡7ùÀh$u>v®Ö¼?N¢Íu¤ùª,vg3/ß qÒØ§Ìѱ`A|ôÅn-"Ç]²7Ùmè± &øj!¸v=¶Éþ[ kÁ…ûF\ÖÕÒ9 À·Ï�ö~;Ó)‰�ˆÒQNkó$·æ}³ÅÐආ"Hö‰47�ÃÑ�l½¶…Ð|¬óO@nÆà±­ó$›×‡/µÌu" =¾>[ÍÌäq_eï GŸ£Iò”'ëf\ZãÙØC'°ÆO!Þóqñs?ÿK׫^õ*ëãÎOüÄÿëWæ9½Ã³–ZpÓç~þé†|‹×I8¤ÖŸú™_¸~é~Î7WUN´¥^êâ�÷Ý8uJ9žÿüçÝòwðÚ )Ó½÷qCK Æ173ú±·¯l}ýÎI²£@î-šKX>ûS¾<�ŸÆízXÛ®\ο,ZøMsoð7ÕßK\7 ]@°èá }Ä2ØsñÊÅÒv-zCÍ7í›zÜÕǪˬaäh2ˆðpØÎ}ìwíóJ?㢓Ðö�›ZÖ0$éƒòëf vFýÌ^+7rŸùôg]Ÿòâ¿q=åÉÇ�òûÛ2Ö4žöeÙ¦»“þy‘-£1óïþîï]Ÿú’ϸþí×÷ˆWŒ â�Öê®Ä[K�ƒÏ‰jpfëæyªúàX~UÓ—†.ýxUææügÇcfÃÔ ¯)´çÄŸÃE��^—Ö¨CòäzáãÑr…ô 9é!,5$þqGóš5u�˜Ädgy©8¹�ß"m)í(̹ H>½›KÛhÏœë#ù²n!±£=ZÖzšrjƒgGÀÏn÷Êúó·¦–ô¯y™s=šl6gøVâÎuƒ=u®þ5Hsu¡}ô_Á»–¤-¶ú)9Å¡ýWÆhˆÝÖEšléé``˜+Ëö|ZwÔ? ¼3ܯ0nŒšöÇ¶È õwi6,4/ýõ¹²AF½óyÓÆ‚®!ón:yÖaa0œx% ír��ƒÁÇç”Z×9tØÁypÜjƒ±ÑÔ§5±Õ6óÞO^ƒRz¯#L›kë‹&°7þvo~ùˆŸpÚK˜GgisÚ¡E*<‰ xÝ·`[~å°¦E_4À„6O9Ääµó*žÁÚÛT—¾kÁÄÈHÙ.ów_×ã-ÁÄÃ{âL Y‡u`­žÑ“(ÚýØÓ§ð–‚dαúp›Ó¸öƒ"f´–î™Ï|è_�ÝÖ²µ�Šaæ±òˆogÂc‚íÈe?šf8ÏI¨u¯«j0´è§þiÇη !/=¾ ³Ï¥g¼û Í!ÊÖ;ý'?FçìÒÞ3w5 çz�ƒŸG‚)a…L=™¢#Gge¼Ök ¸pQÏЪ Ƚí>Ћô(û¦GÎ3ÉÑÑs²c£#< øPœÍZ<»¾‰:|QH؉‡ ®�Î;+¾@»îcN�VDc¸Y“W!�uÆ”%NþêÀ„Ð ÈOÎöe & °ƒaÀÝ–±�#ÞIN=dÛó`k‚3ìÁàÅ'qîÙ|# ¾äêLˆ×²� “F˜‹c·¯oF×¶;ª‚üx`<ê��ý8öd{Ì·ÇÝ[èæÌ2\åsÝp»¦\ÓØ¬Ã'öˆ¶}„.ðF2“”ì\Û¸vóM†ƒ $flYï�´¡ÓyS«m åxòCåf ጠ�õc[Sjfÿ{¿÷Æëï}æ{Ý£W[ù:Rø+ÿñ?¹ø›€K¢pÞU;läÔ°ô,¯G~äzå+¿F/¦âW*£npmÃ|l„Á#ŒÚ=öÈõÂï2 ƒïÎX5Z\^è›J ZëÆs�Œ;ýžu&@^1ÏÌèÍ* pù²ó ›_½eÄqCͼ�™IF ·{!"¸ö�¦þ VwL'­ ~ƾösmü`ž’Ã[ݬs=ukvþu�}ÎÚYûU~žóë¿ØROh›^‘Î>n‰C7�ø•a^�Éߨã†âêaÄptÿúJBm®GyÛõÅ_ü²ë9Ï~¦y¦P­)g„ç”8Þ6ö<Œa©Í@�ñ–ƒœ3úÿæ7ÿþõ9Ÿût#üg(¨itb³†fÎ]¯;¨3‚º þN^‹–Íý?(&2˜Bs'åx¢¹š ®Ÿ Ök‘2l­Ùsd$¿ªqÊ̬¸~½1p°¬­ båÙ7§ÃEB÷ØAê­À+ÇÄV_úFä¨f–æå£Çé‡p¸5‡»WÙÇ2œ&óÁ9‡�W_r(–sîw*vø 2fÅL-µ Ì#|s½ÉWíõ—;ˆÔlŸø;Ìá Ÿ}¼‹O¡¾ �Bâ¤]Z•*Zpý!:&Ö“¥ø ´æ’®¤¼Å&¸›�‰›˜377=M6VEi¹GB´BÂZoflêÕ�Üš³k߈M�±;…–õ'OAbÀƒd3ßä‡fâÍ!gràÈ^kÓÆ¾l†l,[:’Óá„A äìóÒlDÄ. á“s3Åv„L]±$6×uùÑŠ�2ŒY’+l3†cp2ÃÛƒ ÒlÊ�Êc#w ¹âÌa÷iþ4L^å¹Ã[=(e½x„ó~Åš\áCÛák<¨pŠ �âäãoñ0rÀ'?ÒŒ!fqŒ�ì~cÖÃŽ&ÖÁD%ÖG̲ÃÍÐ]³svði vvNÁš¼03{,@¶PaZ˜10­4Õ‘ÝŸcÏ2µy±="7V}KFŽ8»K>s ˆìôk˜Z8b\ú´5ŽCµžNÌ ñÂëOŸáo¶ÅE `0³\üÇùÉ�Î Ë+&�Ö³2�ƒWb´Æ[SÆÆƒ/ZmÊÂ¥\€ÞŽ'²µý„×Åh67 ؆n±Ž¿y�m¬BVì)idj_±qù˜¸dá¸x´>÷Õá‹sjѾá÷c€78ÙØ ©ºÅÓ|¶-^Kó�8Dzƒ¢±Ú¶‘¸e@Ì7„pZKmFæÂ%Þo­°E8è¶0NA CV,®±uƒl­“]Á[Xjqè¸+…\k˜H;ÙÌß“|¶)>}YQY4­vgbØNc›ÃÊY˜�Ó†� m¼OÖ0œž â‡I“-Ãí8­mÕ³)³ VÇDMìXÛ3÷BøsoÈä(I´v—\ì'nè�‚ÀÉeg¸—v‚ÆûJÊÞš±×Êx .¥[7n÷~|�G8˜˜çÈ”æ–Ì6šoNÅIQE®Ïµî×ÝޱΡ|k ÃälŸ¢+yI,„¹®÷žª }ކ®×MÏÉΗÞ8‡BÉ CŽ0d8n¨±°Çd´æäš�ÑV×537ç9 ­ZZ<ó©Áçuþl †ni”Åß “wâ“Nù¦:‡6ÇâÉÂuá§ûaîÃ7ør‘£T­Ó�•?â³ðòís@®bœV†`½ñab•|ôŽWU¹Ê0p­Öz™¡57sGÏ¥à£cyÈi>4;xò !Ǽå-ºÎõª™3Á‘¿=Z)EñÖ·=|}ã7}ëõëox½þ^Ÿ |ó+®ŸúéÿçúÅ_üeßH&j%â„ëÜãA›mÂÑ_þûï/ýò/‚ßÖ�Á½S@o*´&þŽŸBˆºÞý/¼Þë½_(8�b*…œ¼ÁC„nÒTWåÚþñÍ×95�CÞà ®Çû'9 x wóÚ cDT;¯òëà† 1ècœ5æUв§ˆr�MŒ'šŸ~ÂhÝ2ŽÇ‹iº89'ܹřsº9({n$¢A¿R�›]<�Í£7ñ˜{óU¬yè=9µð?Ψ.±ÃÓ¿#¸pΙ‚¹þãÿèO]ü¢÷7΢% ì®gÄ?Á„úá>­€Û'ˆ¸ÜßòÖ·]_ý5ßpýÐý€^ù§k��eå"pÃ7çKí"Œ‹oÖ®‡ØÉKí]ÃÉy1Æ=%¨“Râ�Å Ñ�ëPûjò‚`zTq. r †¡}|ÙÚáÍL^ªöÉ`Îþ`lYr ì”�£c’8Vœ ±;6PZ³e=Þ¬jœ�ìý�C™Ù�Ãs÷Ù�Æx£«¸$J6ëácÞaA¤r,èe—ùÌÔsê°'<ô\à ; áòˆÀÔæ´¿pî‰qÄàï¬�cÐÅ:õ™½ópžáIìàá2f–äCÔ™›ÈyÇ £íÁ±ßçåw«3±¦pº`Í>:áw ‘”| §´ªæí9…§Þú°ê’MkCìžÚ‰­aüäóÒ­¸dÀ¬ÙË�+zå¤þܬ¿ÊˆY*™Ñ›ìvµ'­·ýÆéŽ ÓÔÈ..Û­Ù+ä»Hwp ìRd«²Ôh!ö'š¼{,7#|¸×›†‚ÎH¸m²}ɪ�UqG!æ~ 5‰©|¨ææ¢ÿŒQ±0,Ší:çŠó@‚É{æÖºua>\Ú˜zi%sZ|MîD°™~¹™Ñ ÝîÉ�c+ëh!6^ò9ÉI»8ð¡g3ËuUß ô…°±ô LÏÃYœ[güµo‘í…û­-ªÙ^ñ—;*§Né€_ âgvñ»¿r޵Ü{ïðz.<·(Å.¿¦îÙa¯(ó¼Ó–àÁÍMð÷ølárä+*� È&…°.ÊÍ#�Ç¿¸6ΉZØ é4…±µD°ØÎü³7´ø¦v‡©còP“Ÿ$BgJŽÎ3ñ>¥]Ã�wÅÖ˜ø´iðL.­zÓsi'�ÑÙ8Ìá´ÓëhLû&åÊ=Ý.öäWsN²Ünr�#Ã1öíøzÍ ¦8Í;?v.ÎÉPB0µ1§¤$ʾýÓÒC¶Å[:iÜ< ÛäJRöæÜ†¤¶“˜k‡ç‘€0ó,íIB�Øo± j>ùÍ?ºîÜPèÑü¢É¨�½âÊìGσ¢d°m1LüÝ >ÅZ£9!×<¹ÇÎãÎh]í•ã;@Ö"�vúLžÉU.ãÛ‡h¯Å(¦„sžØϦÓÖá3à®ðá9 2¸ä —ÖPÞ[O›¿ýH\‚[{Ñ™}e¸áÖð‰AÇìá¤ä¼‚{0áÉ:¦ÓÞúÑÆõG˜üz_Aí73o+N�¬yDØÆ­#ôK[^ ºŸÇXw˜‡À…Ïu»z2Æ$/•ì±BÅBkô(NïÛ‹­?|é«!Ç¡ýAKóÖÝú:cw¿„ÝYÑœ4â9{ê=Âú†|}úß}Éͯ’jåô&¹ÈÇ[n<…¬”Ñ–ó“‹°Žjn?KÌçµ^ 6÷rò»ð•Œúäh�†°¶ÂàÂf½Î²ý�aÐW�Õ$~©°–XœR+jØyÁ²œCÑÂC7¾ˆ¦ôÑòwu³Êõãó+á8qp‘V>^ᇟ¿Å¨‡oJ#Ô÷Ýwÿõ”§àŸ³Ì"M§Æel™Ü_c£¡<”Ðxfp'û�»IN‘˜u­€µw ܼÆzgr“ŠØú“:×ñá`Œ# L>î#Ëóuò¾ûï¿þÚ_ýÄë5ßùí×ë¾ëÕ×û½ïøF!çn>’#ÅÉt½ô3þÞõ¼çý1]/ÒÞ¾Ê Âçâ´¡“=~Œ»3¶‰¡&ü\ë?ªÿPý²—}¡k‚Ã�{»«&bôMàp:¿Öεl£ÁQs LþõM—öä€Ý½ÕÆ9ÁÌš}‡}³é9EßêÕðSÎzx±âÎæÍµ!#ïøV!)Æð%­ÊY^A¬%P'ªNÇ �§rdÚ àXùRSg1üibù˜É0Ÿ+Ð&ºðbÍ ~ël¾zƒ7fG„öIž �ѹz0½€m ËÍ·ëAó9’#u®ó F„ͧè’<ሕ#l]ÇSîls®¹SG"åd¡Gò†#šƒÜy«ewºŒûšFŸç3rýx]MX²Î蘚¬mqÈ,u•58ð �žsÁ:ÀŽ9y–Lc2‡ùTMĆ2– ©©zèW_Ý0ç`H¬CëG \WùÜÜÚ8Ï<8GŸïÙWG³Þž“›Ü Î'ô�0óëÐì¹BNœ=Ë)â®YÜ1=ÃÖ�™ºÍ‚=MpÄ➸íRnm–_h¯KF4ò€qÓ ìlG�½‰6k�똘£ Ýúå_X�ª¦5í¹¾0»¶!Ýz1àO?âÞzÂíͦ5²®nÛ9hœXru¿°Ë°}%WÖBë�\91;—€i=ÉàcÚ?WpÀ×$’“;Ü=³“q¬µ:Tµ=7±£4�Ün°ð>IMrœ�ø¡ÜÅ¡Ïè•a؃ x”²³!‡>.¸úÍþ÷aü„ô‚)¿qŠ57']ãÈ$güµÆ�LVàá]`-nêXó{=œJï‚à"©,àgNz%[5&· ¶Oë ‹FÈ=ßh£^’\œ M‹Ãþ£&C’®Ô�á 4å kŽJå*È1½pžڼ»8€"Z±Ÿý$'<Ím¤øÝ?ÙÁ;o)¿øÏø¤H*SÊÙ1>¤#�‡ó®Ä芑Î+z«§ëÔ�¯ ¯mb?œçnó�‡ú,ff�Â,c9Ð�Ÿ¶Ù¥…ÿþÄp…/Ü€‡RÇ9tç3O£ä966ñIŽŽŒœ§®ogvƒ#ÌC{¯»önW)ã7ïW ¢1ðèUq×ç+e ožI;&z“þ„ ÖaÌôYkŸïɲ!,±ñ9”ÓçS¡³Øüq¦�©ãÖGÞÁˆÃkí1%¦¶¹†ÒT4@9X35ÎN³õY‹âôɯš4t ]=Hoà›\†��ÅíÇr£{�E§`³8XÈVŽ([h¼ù˜óÊXSQÅ4…)BE¦¶qLù=¾bë}ëŒkQ˜+³z‡-#½èN6ŶV|ÜLk.‚z.÷7BC´rÂÁæüøÁÄ –|>‚—qäNÏyvñŸi}³M~ð_~ÿõc?úúÕÞ·E{%y«››8ùg>üzÊO½Èò¤{ô7Úô�îÕßì{LÿÔ„Wq}ëw¼FÿàäQç)•ókã>Á{p8þð£Šå&ŽÕ+q{äºà¿š'£¹ÉÉ“ö|òõÀ„~ò´¯Ìpâ¤z…®gb©ÍþÁ×|þ†ŸyÒ�Óh¸Ä —Ñžu�-}ÀÆÎx¢'¯¾Ë²EXëF7ƒ0cÉÍ:mØ3Ûæ=ߘ*Žg­¼kæ_oü1¯‡ì¹é·Ï/1êoRþ­Où[×ÿú=¯½>ó¥/¹^ðüç^ÏzÖ3®÷~ï÷tOÈÙAn÷D¼ÏxêÓ®ÿì£þÜõ€nz´¯æ<Ÿ-ƒÇei.gë,?³Ó‰‹<�êÿì¿þÅë%/ù4ŠSÝÜæ¼§†¼ŠÑ'…ó˜WZ™WïnxqÖkx>~±W'$^¯T%ÝWÅ*¿‹Î¤Î^�œÚÃI0sìd|öb§ÿCM7³óä0ý˜xSM�„¤6Ö¶â×Âó±7ZûƱO”Yd‡~¨0ë6¿ÜÌp¶>dGíð�†|\ì™k°ƒUväöC–£MËODÎÖæm,>h¶&+‘‘Þäcl%%�L©Dj€?™¢ k°½ž°›Ä͉É}ˆUÇÑà†ÙxsÛ~‡oÜ¥o¼Í[3ů~(y>×*˜xöJPm䊣6EN¿ƒÇ¯`Öv´æš–¸¨Mï ËÇÝ ]¾²i»µ/Ö•k׃ß1wÂ\Ò¼¾Üée�9_ À¦‡Þ›Ó©•#1¹ÜKcÅ•>0–Ãìà 4n©xÜïønb†(Üæo^|Çš¸Æ®HÈbí‘·xㆳ4pû¼O?X;†°æ>ÖÆ»Ë_±æ@0ü$Ô;zŠ· l+6Øèˆ^÷žž£#|3ªâÚщÝã\vîµï8‡îxòÎΔÄLA3KU‡]Û•;hë:mÑI7†ubøüÓe�𑬵Lmå,Stj7þÆRv¸"(ê±"·s|ìcÑ^À–ŠÑ¼²ˆ½»¹çü°îvÖVï²±ÐÀ>(¯­¼ÌäŽÖ~dÆ•7$èKfaL„ÍDÍé[ý�«;Žõ�µŒþı­`þßfw¶Ï¤i¾…´�œ§& "Þ1zâÕ±. ñ‚#†Áܵ ëpX‘;ö{ê7‡÷ª m®#ñÔ�}ØšÁ5wÄì¼Öî�‰Ðd®¥u/°ߚݫƒ LÇYWmu¯zäÈ…™¸ò²;ëK|k6%X8-›¬¬«ÍhzPA¿ß¬_NóÁÈØ<[‡}ns:^¦£ß®—XÇo.ÒÙNPyGÃl«Dx6´ÚVß+¿s~p9 ý`0Í#µÍ^øBv!¡Fë žà½äºŠßÚà…/ËÙgÇí|Óëœw�Z“±ôG¸­†›o&š(r}ÐÔ:—̴~=áz¢\åjrí{ í‚ �“+°3G0§oÕä8ù��p�øéiEÎúس± Ü­Ãâ"ï9Á–ÇšÅø—K{¿o{z|¾ùÝš"(Ÿ#ЀžhaMLâ ͵opÉ £qp&rir,vÆèÉæ¶77. ˜\èj, èѰMÙâã­îh�fÝ1N± Ÿ¸*ÖpÈ•o\ÊýDst:Z§nÏ¢&QI¸Z„ÀÁ¢w凲>ª¿Ù÷ˆñ¸Êk2Ç`é¥P§Ù¬ÇZËøe/0ñ¼Ã‚Ûën×lwBu GRrÌ7 ±¡Çè%ãI¾Ñ:7òdËÇ >bBÄÄ7óÔNÿ‰µ*9†Ú|^ƒ‚¸ÂèLí²x`c7øæ²­Z”A¶6g6ë�оÁ¢Í„•÷:×r²öœ¤6­˜¬%$'‡ÁòsGnðæt¤yw/Ê…/½ %Îgú$\\“ßLIŸ”Z§îÄn? ê±Å5ðy£}.]ùóƒ“Z™ÕM9Mµ›Ìu˜{Î!ùËDî8üÀ™7¶þtÒ}G阮qÌèò‘zãÝÃ1øÊ™¹Ì8xMwÒ„oñ—ußr:ÇØ£ysFãˆrجI6ˢϭ¯s`l:ícGl¢r®H.ì£bò�×˜Ï á«Ø-^—���Ú”dÅŽ®d«HƒQnÝÖ$W×n46Ä· Nšvy˜žäóo8ã_¡³MŒCGï¼HæLw޲ÛUºÁ¹Ž%¾›„^)Ý«¥KŽúrž&µ@±iì8Jt ûuîຫƒø&€A{¾š¬8›’Ä601{·{:×D]óàüúM$T{â!°®'àk|4ºcMä¹­mé?8ÍÁ^óVÇ`Ü­Ýg@@«W랥øí†ÈuÍ.ëá#Ÿë0ä@«õ;!V�Æd·úC¼±c¿™Ÿî+ (þÿo àÕx˜¬‘=Lœ7„»n÷ãD¦¦ý*ÙÍíXÊ‘}wá`G�ü0IåpÎ@�ÍŸŸGoà9G÷á!¶¡\¿žƒ@ÓÜù-}H ·m6õ¯î(¾8'€xâ�ƒˆ°–³YXV)lù†"X'§/ ÖÅUˆ;œ'ÇhD¹ UÍÓKúÂ{<%Ž¥xv2ŽLëX Ê•³0ÇÉîoÐVs&mÖ7{á�ÖnÐÂd�®RŸšSÏv1�C·ãîöƒa›´žv?`u®å�¯9W;d¸TÓ8q¥§"ÜÒsÄUȾ&©¦è["Ô‡ \&³9sÈTžåK¯ÕŸŠqd‰¢ r„J³ÙÁ˜Ÿ~ ´¾d ±±…Dk½ƒ8¯/±µGH`0Í‹–^¯‰h.Ïsò’w޲õ‹&Üðñˆ*² þYWÀaGš‹I Ç=[~àÚ#'ÜàF�gÖÍ9ë �#Æãäv÷„0=È|Å«Z 5ÜuË�(×Ò7ÜÀG‡si_y,¹a¶ö$9†{`¾ÍÅ«©Ò§¨bíó¡¯#¹ùO_’!§¾ž;S!�aÊéjz5à#�­µçæÎû½ï{]öÏ~”ÿ6[¾Žå›•G~«nÝ}ßÿöƒz%ß#w‚�­›º÷ ûƒ?üc×?ü‡/³VßLœbø8á&÷2ø\8êÕ�\�>§ôJø‡ßö&…­ô=þ�ë¬é-ð–ëó¿à‹®'éUŒ9G)Ø}6IâV_ÍGÏéæ'_füðx§�ÏÁ HgêIŽuTœ¹¡‚Ã7šâÅÔ±0cˆŽæ&_¹f²6ÆöqjBÇìöìo>s�>çOçèãy�kR¢Ìù•^ß„Õßìó+4ñÍMCnú×…ÝL®ÉK¯î{Îõ_ø…×k_óm×_û„�ÓÍåç\÷s.Ì=š5ù&Žçð¡Íä}ðÁ‡®÷ù/t>º ï*ÄÎÈ.?n¬ýú~ózñ§½ôúè�ùøë/|ÔÇ\þ£>úzÅ?úŸ}#�ÒÜ\¦¿ó;ÿV7É?ýzëÃoÓ“ò\ë¢p~nˆBÏ+zýëð§Ïdað*S}ÚâÁöDÃñ>1émžç²žZ”kˆ%x¨\ÿ*Þàì&·ûà€Ä ¦1é(j»Êç+ö!bËáÓ8äóÄætLò¸x‡'cžÓ«­Ï‹å/KM!"Ÿ?ž"ÃÁ‰¯Œd¾Úѱíôoú$Žb‘PfÈçbmǬ`ÞŠÇ ŸÏ6ŠIŽ>×q Î‘ŽÅ‹“Ê�vüA±b°‹=ñ±Oî üy}éÆ}Ì�]óâO}›ôíH/À¥�·ÞéµÜ»·ƒp2‰ô;šûHN»tصL¾�»žojƒVíë\£/Ž4)z†ÓèÐ}¬ãД4é•×sNOœøÓç1BÏ÷t †MüëZÇ3¼'&eçš»½é7âîjì¾s5-x?ÿl]« ™F‚�ôÄZlìõÝÒC ;}$šþb?t˜OpèÜo/` ×ÝsBl{TŽÆ•ޤ´%Ä`f¤—:Ú�𚣱ਚy3H¸õ€§ü웥ºmŸä«>âæÈìý, sqØ»f¶¤ª™<òEG¶ƒ²­ù™«·³} qâbà7ß!Ê6z£·ˆŒÓJˆ}éç-· Gaæ° ¥ðŒbçÕVãŒßˆøìç@^ú¬áüÕmËq€¬ßbßQ³w„á ¤Æª%Ò”'8Ž©9ˆÃþX9’igKœÅ¢Tοn °;†¡iˆk´6òíWA´·D5:çP¬“È&ŒBÈLÍćcp gðÑövxbÉ.-XþX¶íYorwòÔ›Yç ‚ˆžªž³Î& áª—ý:B3˜e›Å2K=L�û¶jT†}fuÀ›S¿ù#7̳¿úÎ9äIŒ’6ÌÜ2q“Ì=99\\ÎÙúÉ¥ù–jÇ ãn+ÑÏÿÒÏ]é?ÿË×?ùºo¼Þ¬WE¹O‚[÷ÁýÀƒ\Ÿô7ÿŠn…È8vXïÓ¯£ãë¾þë¯ß×͵¥µ±ÀYž7G~òÿþi½ì³TŸ~•Xû‡u3¥uóMVnĤ5$LOéMz^Ïý÷?pý‹üÿMC÷yšŸµ ¹ôã?ùS×/üÜÏšÇ÷Ç%β&gÐbižää'¿{„k–5×Ó‰Á¯�dgÑá„Ýh3¶Æ£Ÿøä`<~lù&ó¦Hv-9ÿ“CÜáâì�œY'‚Ë*6ÎÉ�3ŸSøÜÂM¿} †M¼ÒÔ¯Ô ÁTþ˜qô�ÞåúÒ/}ùõÝßõí×Ç}Ì_¸žóìgꕨzå¤ë(f<¨_ëNå¯Þû¤ëÙÏyGÝH|¦û*Oz¬¾¸‡Â1·oбçzzã›Þ|}úK?÷úñŸø?¯ßÓ+_Ñw�~¥ý[¾õ›¯�ú‹w}þ}Éõ#?úã¾!þÒÏú¼ëßüÒ/øz÷µ¨k”ë”_£ïѾ۷ž k%q ·Ë;0Æ©—õ ÷òsŽrž:§<�±ƒ@ƒÇù–Ù£²‚T„>è{xœÅiÚ[ÂÕ5ýÎÇbr{|ì* ±å&z�ÑØý™ÁQöû3Žõ¡0ƒþpSvG� &¯]TbØ[Êà‚-_unÆú™‡vg�ÓrœWù<Ï7œàS7±ì уܣÍZì¿u�A¶ÖØxìaº’ÈÌy«¬É²5,G8¬IËjäú}ÎS²€ÝçÍ*Å“�wƒvÎr™(¡Ž¿)E–ƃó¬†ùt˜-Ù_|>ß º××�¢"(‡¿vzÀZŸ«é ½è>s)rUŒP Gí\×¼uäã‡=@yæyÛFÈZ›î¾E’D‹ÒŒÖêïÖû& ¾ÃDÚX3Z:¢wçMœ?’k£‰ÓkËsCu¦"Ê=¨qæÄÍ5b[zR%í={~¨b­­­’‡«¶Îí�õ*†}j`‰3X¶>çÀσ18û'_y )WgÂ8wŸ\c'&^%ÇÁíÆE^öÎ'ºòš;þácrìyn‡ç¬ÃxKCÜŒÅ-i“3úsî\¿¡²NÞ»µ™m(}îÜgK|œO‡îák-Caв_Ü•º�¿¨#�M"©©ñ ÚþlCB¤ÍuÎŒŽUëÝ"¨ìà¼'[sæóBÈ<Ü[P¦ÀšáÕ,3ÛœW=ŸÖÊ ?Q Å4~ˆNžÚ·ÈàM@!ÞföFÁúS&)Îø’;%Ï~|L+|ÒA<£¬�S|}s�­`B³êÆzOqCvrÁ8§cia޳‘ø{­�4ñ öŽ‹5`ÔÂ8…ÖgÜ\õ¯8ü.Vú1ÜÐ-�Z:FÎUËÔ–ZÜâµ[ZVÌ[qظ§žõƒj„8‹ŒÆ´¦øå¤5•‡œÕ îž¹PðwcÞš‹-çØo4–€ÔèV 0äš^× ‡ÞZ4FWu“ ³Æ e{¹ßç±Ïc�W~ò]ÃŽìR³”`[õKÇh‹®y³0/–“¿Ü“Ïý[QªV~žì´ÑDâɘs4{tú7óSTP|³â~Ø�bÙ;½aÔÚ6áÜ‹šc¬€™§gI±l+�5 Áðå\C–ÚüMõ_8å,ÜòõI£´OÌÆÂ+ßLü$Kqăï#1ÅW£ƒ—0y•Áìœvί'q|ü£�G€ÌìÃ¯Í p,sβ޾òûìÊ™³\ìä&©~ N wLÊ7¿’†œåèÏ|ƒ¥U肉Òh¯÷ÔHœQ,,Á‹ œ©µ�™Vl� b¹0ÇùÅf¼ÜJÙªAŸÏÓxf=v´³‡Z¤êýj0 Œ PÞÇp¥«WtÍ=`ÆO¼bü�iÐæó? ]Ñ/>sÄÅ‘–tD½çä=còvís=¡cÁÒ«ÖÈ7uèâ&JcÊÁ+µ\�ôãú |ÿëiO{¿ vÒºF`í“B3Ì5j;SC®\²ÿ¹�ü½ pþîcC ]k—•fqpÍ}ÅWþãëWíW®{UÃc÷äo8òËõËxÝ÷|ïõÚ×¾V×Ô[¯ŸÂuN–ä¨7ùê9r~Ð`ôðùÖB½%ÐGçÎvrl^ yxí±ÀÂu2Ü¡vøÁE‡™ÙarL!ÔQ»�$’“8æ _)ZT¶ç ãóh‚ª/yÐZ¬ÙÞ(h®ÁínM“0KßìSϰM¬Ï™üézcì÷$ OÖnŒ–7ÜÄ£Õ³BçkJTëh<»œä0ö^«ÁÜä LÇ{ìÑKP¯â;NÞÚÌF:×y°³ÜvZf¾fÀ™¯AøÁb/Góržò{ãÀçœ&®½Ñç|w(D^àí obcÉY"¢ù•4ï‚¡!ù@'îv?|¸”¯Úùüá¾ã†ï&'¶eví<9´­=:Ú�¸úØY7_' Œ¿Çg›0=—Τî�¯çû†[øÐמÃÀ)œž'±�Y g�SVWòùh;:2ÊÏ5ÉGµiá:�Oj-§ßã;uWlÒÌ>V}'v™�U:5²UÁæ+1zcë>€!(ò£'q}¾ ­ýš\Sñ³ÇÍp®é-tA{áCl6‹aí�~lM˜ÕKph¶„!e÷6OSÁÛÞCÜDx‘pYŠ2µqM>ÓÍo¹�9AÂpAy0Ï^d+ƒüÆ(v=?¯½ŽôáX² ­È«9×í¯q��iŒ¶üå»ú'¸cç¹à™çíë8Å8îà#µsÔGj>þÌ?>Ûø¸$À„øHA‹o‡þÔ±ÃdkËŽxb\„fܬ-,Ûðà³5Å—Á³ð{¤©Øk5?pƒm†bv!@bݧ§ì±Û½ÇGBúQè,°ª ›|(?åP¦¬âãèØ¥%Ä‹C Ÿ xïô˜/DD·�>OÍÁ" ÇŠOjóâñ…øE³ IDAT0¶1cÒ“ƪm�{+ ÿÁeh*Whr7ðŠ&Üwÿ“¯ø�é_k„š^´&öàùgÿÍK>ùzDÿ<„,ð�EÞ¦_‘„ó>ù~äGÿ¯?!Žsüt‹�M^‰õÛ¿õ;׃ò°˜Ÿt½úÕßá¿íæv´¯Â´¤çRÿí?ÿ3úÓ7±ø<©ºùÜá8o X)ÁOðò@7�Ðh\Ï�ÂÑ"sbXø=רö9EbI‰cV;9}Þ 0 @`�s$ Ã^ï-ñ‰!"ÚùÖ5ØaIבkÕ^‘¯:{³+ñô, ìyªÂ g?Äû®ïúüëk¿æk¯oþ¦o¸>üO}èõŒg<5¿/Ñ‚ Çå›z_qìõÆ�iò»ö“ÿÑGÞz}øòaóëÆ‰‡Æ­Q�ĸTsàÆïw¼æ{®ï~Ýkt¥ˆ]7HM¬7+¨Ë¿¾¬kšø{ï»_7¸¹)˜ÏqÁ‚1LÝMÁžšâ;êCÏ]AÚ»Î;"á8ã7&òÈG¦œ&GE®sY<Џmôt¥„wï(3ó�ðÖ&OµyV\fÎ9 jóà—${àÒ¢‰=gã9�ÞC[ãÌÍf’�“Ýp×Ï;Ù™xÜ™œO°°&ÇÍÞ½½kJ¹Î ‘“¸[n•…cÏ.›¦QÑfðæ³¯16€[ ÄpLÌÑìdl¯‰�xŽ\!§ð`Ž+Æø vTÖÁ°Ní;?¶Íž|Íåozo²ŸØ¨"6ö‹I‹ö­j6k-E¯ b=çÈváe_YbK\ø\“ `OO4ow0D¯s?9 Éòâ�K¨ò8Ÿ£l±Ã+á;XbkªAÆ /͚ќw÷Î/lNêp{"Bo¬ÇÜDíÅÊ7 8<Ì—%rÄ“#œ¬ì+¹léE°‹ +#ç€=$ê·ÒÐ>}Kž �ýÄv O´èذÎCà\è#ç1¼36§ÞWeZÿpx o2vöàEJ’¤Ü˜¤Îêf —žåE’Öü7âÜ’ î@ÉÇùæ >Ÿ¡s,uó+ª k¡íµoh�g†ksâà«7ë>ˆ'�û†Žc¸×³GWnš€Î &?H4ƒ�}"»ò‰’5=Î8r̲²-nÐûhf…“v÷È`ø¦-=ɬg¥Þ»§ÑÃüSþ+3¯ÔS]÷Þ£¿åwÿõ'þý÷¹þé7|ýõmßòªëC>øý¯§ê™ü}GŸ‹¥!zˆó;2xC€Mùœ6ÑÔ-¹¦_ùÕ¯ôM>_#ºîÿ?ÆÞÚþïªêûþßÉ?ÉÿŸ„üåêõ1/ÒP«–ãØÜ®™:!˜:Ñá�lšÌ/;KŽ÷^– �6Ý{1›°:¶ràpŒxË~W2ô±iãœãà†>'_eĆòÎÚ¸äp]5¾7�¥NÜølŸuô:­µì8°’§{T¡áí�e½w‘Þ;hú3ÔšãÆÖžsczà¤�6{:a­³ýÄÛ»ŠŒ˜ÕgòNÂaQ\0ð@Å-:´ØäZÕ›Ù ´ÜVjÂ=ª‘8†"ýØÖR`³Õe-Âc¿±�%v†|vO²…Åèð‚¥Ì˜E&€Ö㎕û¬€º†&�9ˆ±?X»†'°ØýuE$9>“j§”8Ùr\brJóÝ�Úx:^ÞSó ÉzŸS9ÆP ‡¯ãêÓýRþ·)„ï ð鱇i–… >ôhrk�AÃÁƒÏsµsGÇ[XpÑNÐíhMÖ5üÎÇZ7ìöM(”Ĭ2²3&!ô†Up0}*�“’aôz–ý6Ÿº©;Éà4s×J²ECtNB™£mõÝpl˜qh ß-fƒªÑ˜4Å'{ÖÓ$&xv�æ�Ý:uŸ¶%cøsYs G2¤ÚuaZ9£µ8vz2‰¢‚¤ºñkÊDø¼aî-¢¬|f®mÂzà—½Z©,C¯3vÓ‡@Ü-t�&Hú±P8Ù¶8–%oŽ�[€Ö-xÌp‹3ÅN|FÝáí¶u€_͘˜î“{x„r�`F¿“L 5µr,LAÆMöCkuD¯üå¾:´œ~²Šð wT1çÞ6|ô[7+Þ­Òá7wÆškØ,g4 ¹Vr»VêÀ\óm® ‡ÉyšÛî±/TAø~ôº% Ÿ|0š§yíC·¾€ºïÀ&1ØÇËgNìÕo¸öò5G²%_âK¨ÝàÒûᛄŽß)ÝðLYæèqªV`Øl?9ŽÔ«ž%Íb\·û²ú¦oD‹é¼íÐÎ&ìù‚VU³bCÊ-%íá\ºŽÛV,d<pŸu9ªÔ�0gì† æÐ¾Ñºz ›u¾óÞÍ7¼£©EÛT’�ˆÃÎÖ1 ¿÷›á•d˜vLËH~Ü£w�íQ΋�76z×~æ1 »„ôÀÁ ã&í!ÿ>>]ÇÇ}Ôåy…𨓫#Ç+çJô–C˜IÆý˜\­£Z˵¶Á+×¥;8’/:jç�°±�� ²þتe÷@dè„”;´ÏÓí€ÃȘ-®¹EþrßA»ÿRzÎ786ñMj›­µÈ7ÏuX«â\¼ì ‰bãÙ7–ciTö±�Ž®cMïµõOß�(Î;c­…Øs¡¦v“…g‡%†ÇM~Y‰áGöhý¹ŸûÙëWõw>¢Øê™_½ü˜�ú(qÊ@=þhö=“Ÿ‹I½7듯/>èÜSqjíZǶôá`88 àøŽVç’®æZɆ;º=&‡óA}tœ—òmLÖ�–‡97îËãòI'uàãΰυ=ú’=6à“�‹y}§›Ž¦HžºžùŒG¯û°�¼¾õ[þÚõ-ßô�×ÐË®g=뙾`çŸä“@£Då~­zëœ;ïÈÛy€K°ÎÝ÷|·÷Я™Ïÿ¥ÝÃňûˆæÉ‰™ €>p‰˜ ?aÜÞm ºx\1?  Ëàóó€ð��Ow|xL"ëùa[…´ß†×Íu°tn-Ðì=9 Ñ}GrLŠÄƒ—ÎgáÑ!Ÿ‡6hì'+ì‰MF|ÂÊ¿òN"øÍgüþ"9é Ï!@¡v|¨Ù%NÆè×]Üc|&2b^_‹ù±Ï×Y4 Ë�Oµ!¦;¬;öÜ2ˆ�;#G|±�YýZHâƒÛ< £$ð—KžIcŸs/Îç>5Ánq¨ÇQ‘^ã»øu,F \à®ÂËì±”7˜ôÒ`ððÝ—iøè«‰ÛÅû)�ó��=1÷xls_\4ø5¡'Õ„ÂSqðQ9YãqýãH¸îá>âLFÃq]kïcaO“wÞýƒOÛô:áNðô8zlpî�ÇŸsîj˱0¯I†1i½±6š7yªH�OøñÛ{Ã!˜í=öÍ_¬ç\Ñ2–Á‹AÃ:fTìÔÀà·ªyŸûa'E�›Ï™Å“Ø››³yéºk.ø'í$Ð4ÎzÖ¹ МíAr?åhêòjEŸ×§]ëê¶íÇ�sïÈiâÊIm€G³·Â¥ó·L+®Ì'ÎÜoê6jÒ$ÕÆ”&sìõ’ë&Ÿøw�‰èÞ½&¡Fc°ÙïšÂê}5ižÇ�k î33uñÉ,›cÅ}õ™TØ…±�ýàfßÉ5°±.rEsL¼“Õ«Ìò‘§ˆ®­Ù¡ñX }ã‡íŽ?±ðz]bƒ‹`ÖTF8¹ý%‰9áº_Ò&,“åC3— É³(œzçcÕÁ‰mÅc|GCyÐöŒY²eÄg.4Y׽̉�ݘ!8‘«¢©'š‰ìwÌg|íØÐL¤£eÈúä’­[;…?Ž—OVâkkÁšoð�ž\ÇpÊ”½ãè£>´^3l;ú“?9H½´‚5w0Á hìÄ™ 2‚4böþnþÖXã“ñwî�¶ðG”·“Îh_ÓCåÈ™º Ï±�(ñCVs·%c?k¸øÆçÉC>^·O“«\%"}øü1{á©'Ç [ls¡äÏm"Œ‡åíÕ‡ÍaÒLÞô"ñäè>yöùYnóÎÆº‘3šc^m£»±Ö©;ööM¾ ‹Ï{ƒ½/�Ï—©9:ÂeKos.cʰK…1dž£7 ö‹$۱خÀ§‰cüºØ€Ic�CÖ3•:ÕíØîs¦÷B+×½Ç&¾Ü›TË9^ÝvÏ€Á°@®Ëå¸Àâ³F7ŒÚž°ƒ±éM1xK¾kWÁ~bÀEsj\”®6^‚­Fwå÷y0îh­ò‚îcnÛ‹‹_vÁ€º¯+ÆØœÔ0qñ�•ìŒÄh!±šÜ?Üé— C ­a�³Ì”{÷jº£5p.hüZãì%ëêØÇ):ñpQpXšŠ#—ëa�åêWfýΧ¼ûÉ9ˆË?5È7öüs„g²Oy𠹟óØc^ûèCŽK>x~èÿ?}�ÑFÝ�ÛœP<¡_­|w½‹ð‘‡rnp`èÍ‹^ô‚ë/~Éé‹@Ÿs�*Éù¤Ž›ÿ‰ŠÖ¨¸_ÿ¼�þÕM2ÃßÇ/zš›„áÏœÑUŽ}ld>�•ã—;�yÎ?,N–$\`ôñÀLâ·7jFBe î)]Kˆ`³šy šÐ³r,ü‰ðlêô7ºrª9™Ó«Äai|–ì–v»â7k¡’<(ë1‚Ëç¡pf¶ˆmõ18òz–¸äŒÂ Š>ó+gÓÇŸ˜Ô)†.nú2Ç4’ag霭•Ç æ‘<‹f"žèK/¸ÏØÜ³;1äsëÎ °Ø:óìäFO˜0LÉ›‰OZ³÷Í$l>ob}\`žÕ1êÚ’Ä�Òμ«Å>Ð,×`ÓãrD _{»=dŸ3…pîEÈaÛö™cZ´�ýØõ<¶Áú�`‚°£>íÝÿõýW@¥Y=t�ù¡¾ö0â Éë�ScSyž|mã�~R:­@þt-õA2>5¯˜cnÇJ‘çdí9žÝ[�8éor°'6>…g¿]£ mGZà&?v¯'˜5£svû¾9 ô11Vhr�â SböcÖ‰N'3¼R¼û)ëê©Üµ×N­`Ò‘Öw^„ÏÄÈ<7œwµ;lòN ®Û±QY¤Ág­r™×ÆÕ©CÄößõúXŒ¶‘€•‹¹ÇÌhéO�r'¢…!IÒàœcìCØq _¸°± udÌlP8YÞÕ‘¼Šõ7©»s˜DtPSn›g’Ý™³µ$½�¶\جIâŠwqÜÔ2õ€r‚ãmoãïÕÝŽ›½7º[ƵXA­9 i|;ƒž”„ü °ñ� ç@ü2šŒ¹l\dËÅ' DÓ¢~D·�ªRö«Îûº¾òk¾NïüeYÇ.rüM“LoyËÛ®xÙûo 0@£Á�ýðû ë#>âc|!ª½ã›UNÝü*)߀‘• y7#u‘ëp±�%ÔÖ¡‹\«~UÀÚï6>ÀàÑPð‰£Züظí gàjWÜ„“‹%Ü Ÿÿ^�ÇÀgz?qY¹À5>šÎoBMdµ5¸ûÄÌñG—f¾Å$Ò~5’cæ›/ *P¿+KïÒßnüÔOýtý ÷ß¹¾ô‹¾àzŸ÷~wýÇGrnµP9µOÍ2¥âä1ßl™rüô7%uÐÚdó¹#-üs‘�úðÞ T€ŽH>Ø÷F¢!~ëüÍJ£\ûíãsõV!ŒèMßÑЋ…ñν¹[�fê 9I1ÉÙWˆ× ö€�úZ«cçxû8l¨Vâ”8>âKíc`Ä…ll±Ï±lu£öÖß�5OÈ@èOj™?/-hŠó6ˆ^‚OO'\±æÐ=Z’—Zb>û…ÉjÜ£‰7ÒhDzâ9"™Ûq��=cvÞ´/5älû±{�µð‘‹™U³SkÖÄ%6°×xãÁ‹HŸ9×v\íNB>ŸcÍÎÉ­êä�éš‹k‰ß÷­‰˜¬§3uM�¨mnSWYZ Zky;ƒÝlÁÆ Ý,e¨b,]kåœÙÇ“µï×]lf¥ç“1rÓóòDH¸3'ŸØ›wTâ°²5ÓqãenÝ�vAä¥0‡5¾аÞÚXo}½;ÜÐçd¥éuGžjh]F‰_CV[ëv†Ø.ÅMš…Ó~�erö�gÿ²ˆXÀ·{ é=ö]ôÛì`ow/·hª§q]ÜéÖ’bFz· ºy F,½c³<°ñ‘¿­iò·z$°w>¤!ÑHÝ'�üC²6DÑÓCŸ1K�ÆAóÉèØôeúcj§'#Ga‰™ÔåÖöÆ®}sÝœ]è²¶è2&TŽXå“=âw~cnÑ+ìX$W"Î8CœûV'Ï�;Ç~ŒÀƒ�šZ³±i‘5µb¨ZêXµ`.0ph¿×Ê¡Mr’¸Ú¦*ׂS¯¹ÈDFgodŸxoåÌÌ}™…p‘Ì Œ÷J°�ðî½OsXd ¹o:8u³6ò9 <öæ®¶™wp%O²¶Þª ¾¶èA‚ÓtÎ5ŒÄ&_Êæ�ô’pŽj¦îÁfä@ÚgCt-œòxM¾# ÂƒI}„¦žä5;>Ú'ó£?9áöµ8N~MÉ�íyoÊ ³üáÞö¬½’ŸBRƒ�l=𣕛ñCl¬êšh»fχûeÝÃiËVèh3ÇYWý„"€ÑYK÷bbÉ{¥ô8à®ÃF Í @ëôUöË6k\§¶·¹B–súåjØ)6?Kìq¯<É»m+êNŠÚ£�ž#3¿†džgWKÛbëeÑžù˜Ñ°6mpžt×ã· ã¯ê„F“�@šØ 也uiœŒw’1è7ÿL„ þ}@4U�ºëE ÄÈ˱ÓÍ<ifïÜÓgÿº5i&ж˜sòÜ·6¢aøsŒluìú•;1L®¢Gk$½µŽŽ^ÀŒ~b§ù9ï|QT¿^Ýÿ(LŽGt‘ïýá?|ý]ýíÆ/ø¼?u½»þ+ôùNÎS§› }–¨ØÖœæŒÊÑokdÌ`é^6Pšžóøó®ê]¢…Å¥�Á“Ý\æp¾Õ×2ßdóŸnÁó\ÛÛzË)ï.¼�<2vþ¦!=à¿RCCL{æ:Í­c=XüëÃ�ÁÕ¿„ŽÞ ñ�­c-µpqô˜µt°Y;éô+�{ÙˆávÈÞs,"ê¶Ã5áw>„XŒÎƒ�Ý} `¶Äìƒv~fm?ÜCæà¸WNm÷9# Øø0'AØe0öà;1æ,x4´�›l¾N@I:Ýõkn2oò¬Nýs\¥ _‘7ú�ÿö.~ã~ÄçžLcâ‡-5§¦]¿a„Ë�ÞøƒO Ħz«yj5T¬A 8‚½[9Wï&Æhî4nñü�Ø-ÅÜ3ÇÍÂÑ0ç¬\�sM¬ÑE²!Ôž!&Ýïx̽0…Ý÷ -ÔØ‘:Ùñxmm~¬B‰]xn½Wõ¬Ùš6k" ÃpÔ ±n‘A #«ðD§ŒÚ`SÜIkœl­ÅLƒ¡Oµ'ÇìGK²æ~'ÒFÂé>Ö ¾Ñ2|Ä¥�·_ݵk�AAûuÌNƒö‹mEŸød妑¸ Ë�¶j7Xb�½™»öÊ1ß\‰Á¿j’©¶Ê·öÆ‘{»EÚ4 IDAT—r'}ê mµ'çœkI'hò9§B~âV¾9_6±`[{s›¢ý0€;�á^|9Yâ›û­dÀV×Ð#é¦s¤=Ó�æqé—´àw} ¡–aíÉÎÆæ-0X`:ê‚4<Ä:R¼­l{ãyòbwn‹Ú*ÖÊZH5Là ÜCþŽÝóØ¢/¹¥ ¬yœ¬ažy.ã÷¦x !l¿È€àH¸Öa·È7¸ìyrˋͫ;—¤XþöI›ÓŒÍ½ø0ˆ“=ó ~òç 9�ºñiýh³¦­©w5'm˜wws"C/¸<Žª—X× ¹Ã¶Ñºô±×Øû¢Å�]aÐ=ŸîƒÂÆj]Íé­ 3Â1=—�}k_D¶Å7asL­Z|² ¤Ä°jäÅî1ª' ‡OK¿0[sZ²öÓ²ƒ-Ë9hž° ޝìÜf«SëiêŠjD3Çeå!Ô±!(¯ÌáDƒ\Äå8D–9úÍïä4TØ;²MÅ]íæ:{™Ô®£˜In�v¯~\�pñI|¾i]_W{4�Õa© <·•¢�n,¼h¤ƒ’˘íylM�$çðyÆ>½]ŒÄÅNFjy{l|2ŒÖš9±X7¯9ĉŸ‘ÃNpó»ìæt!Žœ¸ýõe8Ls„ç1ÌÎÝG4$wí¼—dº½¥LžÔ=q(µú±¿¶Ê¼‡Ä—W¤€cÕ¤xSìè:˜Íͯ„få‚ùƒa. üÄŽNì ÝÚók2}=PŽ•ÄÛSéáxX¿¾›œä¡¨ºøÀƒ�\_ú寸>ò#?äzÁ;=7”rWÛßø¦ë9Ï™¿á¡sǤK1×û¿ß{_Ïxø™×[Þú&¼Îõ€.Èüù/üBýØ�ÖE§‡uÁ†¿³÷Ôõ£?úÚëó¾à ¯×ÿâëýK8Hqk³¼‹íçÍ¿Š–éïˆ-Øp°Î°h'ñc̽ŽÖöı&–8^«4|KJýc‡Ÿº|Œ'·/ �/íM™¥Ã¡Å(ll¶'XKŽç+g¦CtÏ‚wYráëA¿»KÏV²Ý¯_ù~ÞõŸñòë“~ÛÇ]Ï{Þã~§¦ùr–“ÌfÄß p’ãŒkp± öÅ7ë”Oƒ_;~�wy7ýбÞ}ÊÀ<ø.�sl¥‚ÿ�žÿÜëe/û ×k^ûcʧÞÊÆ¼ÇúõQ&�/(;�ö>ž-Èqô¿öÌÕ༺óEZ@ÈÌtϺ5àvïL Ì#DEú<²ožK Þ!®Fmms&Å[Ä´KFråÈ;±u�wæpPγHÉâ­“ ?pE/¼»/}}ᘖÞº1 �÷á:`Ó7¸s®*`l¬Ñ"–ÎÍ=tÕ ªýc½}ìØ[±Vh!6šðU‹!ärÑcÕ$d’2Y¾ï½3Ž~+&9 >mM"íRÛÚbYbwæŒ~9í_µ©.´rœ—•s¤Q>_{Al¥1Ïy—œÍOúUFø£è@ù5žhÈ\Þ­©ÏgYK7ž‡Ub•ÊeL ¾)Køè0 £>yl²\uB˜ß8Ke !÷‰ŸÏIÔ”Eì­ÖNíœì©‚œwÏ…ò‡*9·¶X]_çøæ^4<�‘?ÿÒïÌ1¦6tÁw bµåæïJÄ\ºkÈÌÍ“™ÞÆáã0aô`3kÙ-Våˆ_�µ&Ÿp‹×Ùd¿9ÆŠï±"7ø«ÿ{úªÓ¸Ñ°ðNêTî¡K eêCƒ>ú}óZ;¿Ç?zHŸ!¤bɽ5¦F$ÆàI6�é‘,„YXˆ†kÈÙîÁ¦¸‰« ×>`÷lñªCÖæPs¥'Ckßq“`H[Ïàü©3�®5[ø …ó^[p›ãçfÙ–ÅÆf}ÄØW+óäñjx©sò¹Nm8'ŒŽËèDN¾>_â<™þLÖ5VÄEªþ�V6d1£×ôb^ÓO4±þ.¢Aû GköضôÞm/!VPçÌoïâr}bL„½Ø†Ð]hI2s “ìw´P4:à‚#?9�FwlðäožÊfŸ6‚ëhñâñxqçÎÞÁØøÔéŠ'BçºC°KŠŽ–î]699ÏAžƒ‹ucÖGǤO´°Œú×bìí+¯©ƒÝ|,†¶ñàÖ–ë_v“]“û,ë9À0Ì­yd°Ú<ÓKc >t¥~›ÆèÜà '8ßFå’5qpB˜lˆ3T펽—¥!Ñ’ãµñË^¶EµDç^Ç ô”øä`-eš\;¤�Èw¶»ÏÑ]Ž™A!|‚R;ëìÑ‘[E¶‚Á; =äWר NîpÝÚ ?ï š0×jSù4Úgx±v–;ÆMhÙX/µ�oÛïÆ8wëgz¬˜# >°1%*ÀÙ- ˆ—û­>©r|Y·¯Ì9ñõ'Ìé{8å7U¹öãÔœN&}¸á2xÏÎ5@øÊipƒª`í'eé¾ À8ük>j‡»ÃzfKø`’ž[»f‰ˆŽØXû]-÷I >~ýú¡taW9žÔßiÄøN/xñõ…ºèú½ßó×ø}¿ëzá ž¯¿¿·59ÉÉP�~òÖdØÃàµ1ô2ZÀÅ®çI.Ô¢F^ŸRûG|ä‡û ¸3ÆÑº;hÚxÇ?ó�\Ÿÿ9úzñ;½ËõìÇŸ{=þÜç_�>úl�Gºi~ð¡gèWŽuQY¿Â~ÿýüS™û®'ôŽV^£ö# ÔK~¥‘®'Þœ7zéŽ}æ|I17šÎh,<¦·wï^Ü»N:ÃP~ÎW†‘ËÒˆÑZnÒ4·ƒrG®�\ð»7 Ëfò²&O�ŠŽ™díAÏm÷Ǽá‹ì·JXÚ¨MJ’IºG_²³Ã«m (¦ü繓pÕÍÜu¼É¹µÁ»02§¾<Ï“g”š„N§ŽhÙœˆ,~P†`+*v4íŠ-»ÌÑÊqÇ]°hβsüÉy^ì ÞÞ&&ÐTñmDóœ­Ý¿­;ál™áßcó&¥;l÷îgÑŠ<5{QÇÆ«øœ+»~ú‘žtÆÎÓpÌ~ïö œÇZÌqA§xÝoóû[zc­[_oŠbïþ"°uØìýÎÉA ¨ÑÛ˜ÎxbnÙ‚—Á42xyÖjGÜø²Ýqâƒë 'ylcL œ­7îC·£«ËÇVfED†ï R§ÚƒF΃:a wfbXáom3&„ÍŠ×zå jùR=G]‚»&Gǹ^šì8K5G#¢qíV)í…<ÄËî:œ+ùRSªûíÕR½ýú ÖQÐZÐÌ“ÃZ°ës¤ß•çwÐÆ¨ŠÍ—Þ8ÉáþËØ<Û ÇÅj¼Ç𖋥܄’³5±ïËC¸j �™} b¯¶i% ·Vwò8 kö´ß*ÍRøá•¡Ú×ëÇ&ŸÎ=xÀ“@ M9Á O‰rYH­M.¶Ú)Òöò@Ç…ÇÁx3ûÃ\ \¾&dÚóÎ)ªœåàdô€Ë<8åî…s »pyÁÝNÎåwA`åt^L*—¾ö5·uLZ;^>?©ìКø~{FøXCËîé�'&ÇSx‹ëɸ8´po�ãd ÿНž¦eÆÖzŽÛ r†Ä0Ý•´{fb87t/÷:Þ€Án€sñŒºf?ñXÉû~ïûÞ¾¨ô¤H¹Á?çÀÎc*ãþë«¿ö«®ß¤w¾Ç»¿‹ëðaÓÝë^÷/¯—¾ÿK§©%Ëu‘éS>åw^ÿÛ?ùGâ½ÿúôÿà÷]¿ýëõ°.Þu¸møïµ\üôßýÉ×÷}ÿ^o}Ë[õkÄ�¤põaäB—DÛáÇ?¯\1=Ò žÆ`u9܉DŸÁâ5ÜÖáŸOáÄ�9#Cg´�cÚç¼ZåfÌy³áìKÐ9Þœ×(lpõuÍÅAlœíÇ _ðÂëó>ïÏê¿=¨ß­éwã5±8z>®ôÖêÍ]À¨¢r1:Ÿk×J}'FÆùu\œ1ú!úû:^ÎOoôA��wî G d!g.&¾ÏKÞózÕ«þJÎqá8Ö|àÝ–`ø/Á| yB3ë_ýÕ7^ßõw¾÷zõ«¿M/ƒõOOÌ­^éÜQ¤êŠfr3:wÞj9û¾ÚY3rÌd—~%ù b�3<ø9>ÄAê㊄…CA¼ð1¬iq�cQ‹ây¯±Ñò§›ãÆJŒ8lïZFìúL~¯c«e•¯µy®=y"Œüà¸óZÄÎçÂäs’yëD»ÄÉ� (ÒÞŒÆÙIóƒÃ<9ŒÀ 6H¢Ä\݇ÛÀÁ°.c2s�^´˜N¸ä…ÿ°Ï×àçXç€À];Þ qž`ïîòߎMŠï›.,jâ¥Vº¹´dj »Þ`£­˜<ÙõøÁ�Ú£rjÖHI²ò~ ]1Ë�Eú—e7áyç¾ÓkÝÜcœ‹}ü“÷Èï‚'bXâÖp_еŒ8sl¬Ðò�Ë’0ÃSJ´Ù´îÚKkTb§¯ã¬%5a¿1á[ûJ®¯‡©e(²iŠ”�×2T”�Ùö«"9]¢µ ¼·7~»¦PO2˜ïŒ�53¦R_Ì;f^ë�-7d(YSWjbùnöí.ZCÎ�`ÁyØû£¸€°'μZ›‹Ð ©½ÇÔ1´ìèY¾ [¹‡ßÙæXü2ŽÉJ—®Cqp3ª“xk�õôîŠi˜ms½QH½ì8Ÿl�9@v_-RNtæëkºPŒë&ÛX·ø'·8Âh ry„g&SÕ3ÐÅ1IoŽ=å¶Æâ©ãééÉi[B©mó[[ãA&h4ïŒ( ¥ÌA0ËzY3À;dâMr+ …5¶³ Î;8/<øbb¥�U÷¾82Ú´ç@õÀ$Ȱ ²ê2§9Æáu8V²‚B“X´éf‰tN£03iÃŒk©—7¾ˆ²b(Â�ÅÄi㾓Ë̉×Úul„ÀÒ�¤ä §=Äè£<¾Ú�Î"H–oÞ16‡+ ·n|XËDÂæ.¡ó*�ýΓx4¿§låOö©£6Ï£¿ø3™ ûX7Fsâœ� »Fl!Þ¶£VÅ®Úá DÝä`+½0ä>,¼‚ôéžpÐ<8F,ŽsšoݦCƒ0ÞTÖƒü�ØVΠ’ÉÇqå�Í™Gе²ž[r)ªM•+ëØL5±M�[:¬q×’ü"!Ÿšãå~‘‡Ñ:d¯¹³½Ú¬= nppŒgÌb•s8°õœi½»U9?7‘±±ú¾1�ƒÌ±ë1LLÎ)üío´6bb¼mšê/6]Uì‡,GõüõfªOÍàá�‡ûU·MáM bÜÚ/ŒfWâ¨g÷ˆã{Ðä !3ËÙeÍóúð£‘5ñåK AÄ&ó k/H“/õÂÓ¸r|9xöðˆÐÇÌu¡ˆ[ é½Bn8-l€¥c6OæÌ�©Y¸ÕNÜ@ÄÕZ]¬�IÄ7í\H™´5¹¦µa1\9/´™ä®{€†�ËJþÖlûy;Šã M û$�ï±³O½ôÜïõïz}õ×|­.†èRˆ.–¬kÎB»^ñßÿÐÃ×ýů¼~ERàêE•ø�L>ئ¶Åž²|qñ=ßóÝ„{êúàú�ëåäøW?]ßÄÙ®›_Kþ |Ùõ‹ÿ×/M=auŒpÔñ�.*½üåT�W½ÃMš–F. ò÷ßü«¯sÁ• bÜÒÇ¥¼Ô±4ko¿í»»Îª¤|}Ï+$çܿÉ›“T“®39œW.kr%цÏþÆcMÌóÒZgr/¼ÇMÚT'ÂÐE×÷z¯—\ßø ßp}÷ß~õõñÿÎoÑ…ÕÇ|ÁÔúÅI Z”uÕc:å‡Ã…b €›fÆl³Á6Ç 'üo{ëÛ®Ÿø‰Ÿô ëâHþ^:'únìèHŒ§�sÝ<ö¸0Ì»F}T·g=z=Gïdåâñóžû˜~]ýy׋^øüë]ßù…úÛ†/ÖEê÷¹þäùõ]ßñêë÷ÿÞßï÷ëœ/’öG¿hà<áXO¡Õ”¼Lmž"×Ê|œŽ=FK{½Áà±áç$¶�&å`´É±qÈôbŸ;´jñhÝóÄï�<à ¸u�ƒ >NxØ`c¡ÛùîÒhL<÷Üpx?¾t@“œXîýÚàä b�HÉó”sð¼&„íJQ¬û €Lš{¬ÊJÒ Ôõ�Í¡`~÷Aûí3Àý‰-ÁõÅÚmÓ9c¶ Ô4þ`âX:�_5Ø4õ°Îñ$þÎãÓaé0܉/Wö‰UN§=D ”µ±ð8ãå“�ºrnÄS¹Îô/WŽOϱÁj *{îó:+¹z~&ÛôV¸\ÏÐàϱbÕ¼Ì :Ö5 4Ç Æð¯ãb3¹¼ög®É¿)pj`à\ôF½ã{Œ¬{Ý1î׊rLíEÏL�>},Î_Hÿæ±€�ÛÒ¢šüa…^EË8}gëLŽE-Ð)Èšãž>…ÙÞÍðù˜®œÛO[VµìqÆá5ˈ_¹z~�Ëk4´´j©mf×ÇZ|+ι&–´k››ü"˜ýÒ¤˜Ð&†{çû҅ñšYª¦jjÃpÇo0¡ñ6¯ãEÞ ,ÁºOº›„»�ò£ñù›í“ °és±OþÄCæzœÂîú8ˆÃ¿Üâô—ÓvüGTò9�`›írœø­O°ð&09àaàsÇ\;s}:ŠBü`Žá #�Ôw?Ø�Áó1¹µ¦$P‰˜ÀyÔ6ðö Ø¯ Û�Á²Ý\ÂYà€ìLóËçv©%Á ¡)…r@Ç`süÖ¥/Žá– ®ÿÐ /ÔÑG~k­«qÍ7Ù–¸Sok8_ÐYæÜU;:Í픩Ä> ¼5`2]ú 7ZT}#OP43qkºQ iz[ÎC‚}f£…ë‰aq†ˆLè™ÃÞ^8¯�Z‰k×*àÔA8k6¸Eä6Á×zÅÂ}Ž‘Ñ|ñÊ7Md`X�WÉãþ��É9Êá}“:XþÙk»Và†“É5Îl»î6ÇÒ}˜€ lLyÜ!Åc;†+½l\€ ݨ=ßÉ|Ž]AMÑ}ÖeÔrêïùƒ@÷vìÉ3õ8•î&%>6žµÎ7‘§à´mhï&¾<$¤"OØSsI�z°ŒDeפiÙ1/:gM<çR8“7œZó!‡àž“Æ…ƒ«üÉk€^yYX‰A Ø 8ZsòU{på!†³.òΧíð„:�2ì\V9YqØ«»�ÏâÈ2¹ F:<Ö¢uÕ¡ù†{ÔTã�ßå‹?ýÙÚþU¹»k³mð�NŒEN¿VÚÍ“öÃÛü!Ž_WÌ~� ý\¹§Vß¹kSBd§sû�{uÝý°ýÀõ¸úûBÛ¹›ôä<Ø}Ì=¢¥5úüÊa[5´ÿ­É5Wó±õFÖ|zíÈÂ\­ã³ºöÈ!‡ÃÁÃ!2*o½ÌFê®vç/‰†ÊyEƒ?}‡lÄ2b÷Ò8Ö8ûÁA9üe€SÁ0öëŽÙ¼Æ®…ðÍÇu¯Coþ t_ +çÄ‹¼áw†$š%š=à%ß|8$XKµV1gOœGñ$ÃÞ¼MÓ¹ÊØŸìp;¯àÕ~CjÑqëhØ4ýÒV¯: ´E’¾ò‰Èpòâc‘¸†Ü Ë?A 5°f'Ï�ÑøÏÒÓžéÌ×Í U;Áö´á¶àK"7Ô¥™8oá­Õ�›ØÂ#Ûn¦égv°1Ö§ÿסõh3ƒ8ŸHÔ·ÜkÔÒZ{gÊß™½’+Ç7Û,ª×2ƺöÛ®µqQ{í{â#9šƒI^Lr(\±Þë®{0„[Ä‹kÛ–¿‡bš”œ/ììŒÎ€¬G6-Í1ÃäÄGõ1‡ÄäòbâÉëô,2¢mzQ£fs‰/90N Z2e6›5îœÍ°´5¼Žî­âÈ�>÷«Ä$®7` ¼—‡>§ÁBe>ûcÄï>1p¯¼©H¼ó�ðìsôGO¬-ýI¬ «YGŸH½4$ñÎ7œ§™â£¦PœÇ¸Ìxò×¼öØ£—K�ñ·Zr>4"Ì凴± ‚r?ÙyÊ[tÝó¢[á;®3�¶kŸœÎÃyO�fߌp‘D°¹�ö†më€%;³VËî4@”£¹ZcÏ�؇×qÀƒGxˆóÍ|¹+šœQRB,(k·Æ8ë?h J�ŠÓG0ƒXœ£NóÅ_~Ž�íi‡ós_|Gœƒè%çÊ`˜©C.~ðq¾³… ÖËœß=Ô|a?Èeëî�ˆÁ¬¸ùxÊF fרjnûŒ“ ʅÅ!�Ï©L>y„Ëy##ŸãËQ#«þ[¯~÷“>ñã¯'ÞöV×Õ^œdüWÝW~ë+¯ÿwÚõНúŠëµ¯}�þ ð›õ«½?<üáêýªC†géZ_ñ•_~½øÅ/tÝtpÓXù´Óúût¼ë°Î)Ûõ?¬¿ø™ÿɬ‹‹/’Týr§.Ôø]‹Üç¶ÚèY{î>M6÷òà^ùf‘^Ï;"+ðõ¸ØÔº4¯|r8ïø°‡“ˆœwéµe/bŠÍ…ùÛçõÏpAMMïöîïu}ôoú`ýmÇGõNHáqhì|cˆ™6K“µ çyBïá!ưbÁÉH¿ß¬_ÛþÉŸü™ë/}ùW_ŸøI¿ýúïÿÖ·Ë9º œBŸxâÎEµÑƒçÔ|l<.Mqø°1lgqø¼e?:Yr!ð]ÞõÅ×W½â‹®Ï Q]? IDATüŒ?&¼ÞáêÿÌ…ÙüýÄôš ƒD„p÷/úV¾rÔÇËqévsñ×ë[NújV‘� ZkÜÛ£U<î91ÚúüZ¢Ô•¥}r�qaiœ‡•ãë|ÍI<>ÎElÜõ¶‘x’örp¼ö»¦�áN®ôt8´wHX¯Z‚kÿ·†ò %1 KL¸¬5³· n–ÝfŸóhÙ¼ö‘F÷Ý<�=HH¥±ë»]Ç›{úÄhþlb OsÙ®»hIŒõÕ1³c¼N¬˜“üˆ GÌÉŒùXZ“rhí¥@Á�V;&!kpÑê•k_ûÊñ5<¦þÖÒ~”ÏœZ¦þàd�÷è´˜Ü#ú¼°¸¸GO¸¨i €ôf[»æiÎþAeÂ0Â�±Ï+ú�?H³{ßmÊ[‚áXœZD…jÊ"¤›ÉûÕ{0Î5kÓbÝÑ8m~¬ÊÖs`b'6‰ïº3Vô"ÔsÖ9>;ÄÜø—ÐM°òÚDG܆ˆšç–14ô˜†·qÌî�ì^³/ç„ÊXØÉ —Ç{Ȱ«µ. ØÎšËƒÍjV~±5‡âªËñ&<œ$®Xsg{ãÝQ6‘Ó¹'ïÒ1îQxêðº„Ê�Œ³¯á®N±³+©–S¿/(Ž}Gs,ÍYB‡oãnzÖq»G ßdqGÝf3ù@ƒmÔ`Û‰ðiÍžÏù~oz\ÀÉ�6}/¡Ð!Iú�¿WÒýò7ÊJ|POۦλmW<¡7…5‰ÄÔw×jŒ/< í\nº€Ñ‡–z@NžùU)—4‰÷7�É’û°{-š4Z;N–©§ùÁ¬L,ä÷4Öú¬Ï‰�Ô:y8Šú¬öXÏc”ƒûĪƒß7wt1x‘êµ}¤c,»×ºY®É·Á= èy?dx¨ý¨qišú–¾©γfôø<©‡ºvðk�§Û΄LqœÏYC6 HÁ&VÞõ"CuU{óz>ò £9½^bœxíêsFî’tühYÐ�+±üÊKêÖÓ³¿{3Lcéþ�Køñ¯º¬Åîh`_Û`'Ü ®/€°Ö4ª§/jÎ\¡$cdË�©¸k Þð Žþ̺ðÞŒwÈ¿s»ûN@kÚsz›Õ”{õ[(Ö|j^}¨ ¸fGðÁ¯-}å–Ñ£=»q,NÂQ çÄî”Ä 8öÚklr¥£ci£ [¬2+{ò—ç¬ÞµâTýÆÌVç à®Nj‚'!|S6 5»^;b…7ñ‰i~"ÚüiWÞEÃ9Âų¾{È> —8IaÓŸÆÛ¶CëõE6 ‰å…?Ï7‚áC~÷‰:@É^íЭÍö1T_ëÖµùš‡pÇ€Ø9óÎòØHëÁ¬›¹Y+Κl‹£9¦y£ÿÌ¡c—Ð� 9qæ•u’Ä^‰XøFåÄZAµlK§o~ó[­•çsþ–šûLŒGŽëÓºÀöàCÇq~èág\_ÿ ßx½éMo5ä§ÌD!Fƒ Œð²÷Ó¯ æ‚Túz–>™ªïmoãWG_{ýóñš›oäìOÙþU_þ+ìW¼âË|± ¸ø§Haø˜Ëè‹ÄÒì×!Ú»vùÉ] øõNM%"W´ÒO.éo–0ƒ„L3{ãšv-ñ ;Çf�ÃK¿Ã�c‡.rZ›p` Èù{1>7¸à#ü£�>K½È?B±6ô޶ööÔÚõ9÷k z’/B—Ýz ÎxJçË›Þô–ë_è¿8Îç|áõ»~÷ï¹¾ó»þ–ÞQª¿ó¨z‘–ëQòæ7ÿêõÿüÒ/5üv¾“³Nηj´®:4·.›�ÅíÔ ®g=ë™×üŸv}½Þ-ùˆÞ5yÿÃú;…“€ÉÏcZÄ$Ñ„¾ß‡Ûù}LGß�äíêê~û†0̱œzn0GKß&WÏ“¤áÖyC0Ä��+U8‡ìÅtfa"(*ë˜×…‘D4ÁÕع'ãƒ+|{vÎmTÇmÇË�7��*¸Í×ÇN5„�{zo™ºï€#ÇKõm•¸šÑЛ™"ŠPhFYú˜;nT{³½~¬˜ó¢¥5v댥-`N×4£iL6òîsüc[-vÀ²Ò �Ür|–ËFÛÇ, sŸ¶ qFÙïv¢Rª}sLý�0}žù�RípÀïú”Ð2˜'oë!ôü!zñ�+ë&·y›4ˆ[ÍÁ$‡<ÓÏCŒ¯¹F¥ÜÔU»ùð×Úa±˜¬9ŽÑãÇYê%:Ç'¾µÖÖy†`iA�ty¸gTÌG´x51‹M‰swpÎ!=vµF`90LÌÜÀÉ=j+~w¨š0¼­Œ™Û5À§=Ï!Îú}?‰7Ö‘@1KWz£{q™§ Ñc½Î›ó±zMYÍš�‡¹qUR ü²‘ƒÕuö£ÖJ@gý¡ÓëEw`ˆbô&Œ!AÓl-nü.vìNF¢ñu±0òLkm?�¹Ç[é2ñYˆ%9—•6ñ1Àx�v>úk½qO`x—â6£9’ÅŒ‹›cRÚN.߯ÏN54U£¡Ø@¢S71QÇœšÎXâÔ¶j@Ô1Ìٽӌـ:Nsyٟ늰†rw†Áë%nçÃ15–5µúÉvæ�ßZš¿>ò¶l¸¢Õ‹é ërÙ>wåÉV`>W ýWÌÛó‘ZHeÑhí¹ X=8V®žÖêyfæÙq 9ö‰ �ã"Á†rÖ+Ÿî#BÙΞ¸Q Ú�T€83%`Ûˆw�‰wp¼¯=„‰™A®Ì‰·½¾I¹¹âH¬"O]SG° ¼'¶ø!oõgBô 's‘ÈΆ[ëMžq…#QÔ�g¤�òÜï5;žtºÇ¢ú´LØĔǎ¡Î³¢]c˜°qÜÏaйð^+"¥ÆÄ ÇÙPñßÁ¯¸É£ýÎØ:à>Ï­®ƒä¾õ€$Oos�Ð6[òŒÄjE# 8Xî %Áã5ÎØà‚å¹+> ˜Ç óŒPwg]>>djõŸ¿!�i؆«ïÎ�+Fœ]£×mí<ÿø {ÝøúD±p¢ÁÇ4:¤^0ŒìW­ãçïà�^ç_êŠ·šœŽ”8ëüšË}þûuŽh~‹“żÃm€I ÑNÿ#5:¾ÜÛüÙäÞ4Öû´þÞÞ/ºG0óÏ5Tu¾)ˆcÁßr{Jÿ%ø)½s‹¿Èß!~Jïg~æ5×�r‘N�R�úYÌx¦þVÛúpØ|î>’E2²=0qAñ;¾óðE¤¿úM¯tîxç�V8–ø�/õ¯½>úŒgø×:ýÎ7aø[qôŽ¡"%ñß \_Ñ «ÆŸób?;ç±W±1qŸÚ¼Ò�jq­f×–|Íi7ņ MÁÒ|'oÖõ3ç?)£I(ÝùqÞúì×ßµ»óÍË:ÿ¦g[ ô!»o“Ù=ˆ�Ã�qöBèø?å¿ ùüð¿¸þäŸþÜëÓÏï½þ—ïû{þ7:ßzàL >ðàõ?õsSwÒÜäRަÇn�Ìhk}gmÌ¡ÛG,{z÷ŒG¹>JÿÜæ[¿ù•×óŸý¼ü ¼ó̱çs‚ˆ=hCûswöcÒ:ñÉø¬|.N�=Zçu׼ޱOžõœähÇWÁÎ1üÄð©š8GœË&xt“�LŸ3àòy.#šÜYz¤›±VÝŒ Ô°4Í9=q$Î(î4“uFro{óÀëãéÜ;/üÂ@$3<ªÈzÀ4ž5< QþÁߊªA|lyü'Žx{�qNã‚EÈ­æ±Oˆ�ßä2Á¢Ðë� Vœ×…̱i0øj5ˆ XL€îåçkžáup²‡:6Ã8X8zzq¸µÌ〞У‚§ßªb8ùZ‘‘>ïdÑS_�šR·<†4~hãÍ´tα x÷ÈØ³ÆÐÊë A�±s¯œ~¤Š,=ØúW£#.˜­ M=æ+´ˆÓ'~â8´Nm¦Ô:½ÏŒ-�£�o¾d¯†ðä1œµi'_su†—57?žÜ8¬;oýÕ·ö�ÝèvMc÷sgƒŠõ>ý„§Ãë”@k<Ú'dì¹~bW¾#Ö~¨±M l,=û9;|îõ\ï°. Ú6ÿ�D[U ö çÔFÎUcÖ°b#¯�Ï%’�Ñœ>F*FšÙ§žÄÀ…Áùf¶eòc j¬>±p%-Ñ©ã‚Uk0y÷=8×”ììÃ:=âñ'ôÔnmhtÞþ\ŠW÷"|ð~þP8Hmø/hç€0‰bÝRŽ=ÅMP£Ùexi�^l�8ž¢�WÎþtƒôÔŒÝOáäד5¶w4Vž4cr›hï‰7Ͱnl—¯¡Ix⛾_`àr¬ò5–>á÷ɠ㎎ráF®[3ØöÌÂ5ž;/ºTkµ�¹¬5-&ŸÖæà®ýÖØWRmM¦ͧÆ}6 §½ÐqV¨�8‰Y\+Š<"&…�3m3Nû0µ'áI41Úšì0è†s9æ�7Wõ sO,Œo¾ôž|ÄäîÙ\§°á…Ç笅Dû’�S›riMå�ãÇy¼R7²ø£ñ‰É#(ÇÄNÚ¾Ë2¹ñ��†˜�Ÿ»)}ý”kv�&q°% ÇQÉO Ñ�@?ùiÝõ9rÉOºàXP –œ+¬¬—y¡¹b>°âŸ^°UýúXy³ð˜Qr´êÏïƒp\XòkÅ®“Ç=$áŒæcëµxÁ(C!ážø*½�K´u;Ñ„ò¸Ñ5Šõæ&bቨÁzjÎéÁÁåz›qæ—`÷×i_kÒ±…H�bD½÷×�þŽ¿¢ ˆo¶€sN>ã™�‚¶Æ\ÈPŽg?~}ñ—}Åõ-íõ÷æžjq·~D‡HÐÚ×þ°¿é�oº^õß}ûõÍßü׬çÇìÇ®{ÍO^¿þÞ׃ ø¦b..~؇þziø«×ÿSÿùõóÿòuòK·ûÇ…ÊÝËŠÀ·Ö¢£ì9N>þ®cŽ�Ÿ‹çk¶¥Ýêšómcó¹¤uÎ2Ð˧Õ_½‹ Ž÷ƒÒÇs³5�.¯Ì´/Ô OëÄk­ã“=FÚ’lŒ<²æ»%jqß\¤³WFìa³å¸‹€Ù5¿ñ�o¼~äŸýØõµ_ûõ×kâ5×}:µÑ»Ÿw å´V�hJÀ9ùôõ�ÿñ^Ÿðq«ç÷Êî('û®Ñ‘ýÔÃfô³‹Uœ —G³¹ ךÿPü’—¼ÇõŠW|éõì³®ûõ÷ �r<¸ÐÍXú½K<ùÉcå«Ï)ü3þƒ-±~ljæ�µyŒkÖ¹Ä1Î1G:ÏV|¿ •Z”ãÏóé$Õ´ð¬gh”E`>âÕÄʽÒÝöa77wŽ»ßç%H`ä2Z8´9†c¸þ�`yÀÛ§Ùϯp)‡_˜u Ã…Ÿ©þÔ Ý/ͼ»õi‡Š‰@¼”�sm6®:X,jwb»MìøÙka».L~lÌZ·}ž(bíÙéf›IÎÕãÃѾ&«/Wí¤%g4M…æq«ÓÕs Üd¹9æ<§ jæ<×Û`̜ݮ£ºÌåèÉ=}‡Mk°‘»c’råóÖ±ø¾í¯¢äç±óÔè…Û=¶ÄÉ6yÎ×îëݶ‚lí#Ûg}ÕQ¯ùø:—Fz`¢á¢—y3¶ §f§ëZñ–tè[Çn§ÈãeçB¶IŸz޵µW›ò …q¤µÞA?ëÇÔ5üëk…ŒÞYŒyd?|Ž6Žbt“Ó¼š×BFtÜÇ‹ð1ƒ;ãŒwéi6ì|´F3çÉi²nž„®}ýh0·<'/›öÈ*ÛçŒÈðu4ž¹*Ë/²XUlŸãÍ+«û€êëÓkýFHŠEXNƒ$ñÁ?ù!‹$â†3JÑ`ÅâZÁF®ñ´<àäÀx#(:Q…óâ1E:AÀ³tíZ£5'Ë—™=¬®M›¥]£§Ap,œ4 óLžE:/H'dáÜ&aûÍZ©H¯TÊîUùGøä¨9 ö¶ß,Ž&b\8ÀVêûU§1¸å·['3ëÙlv8«òhæ¿rð�ÁXÇv¥n ‡Œô3{ ìý…›H�r ÑTrÌ�‘#"´n9îþµ0,~Ôb ¾:øƒØ öá¢6i;Šñ‹ #0ß,¥ë%D }€Ž‰i8åE£øýCð®åÐ�HägUìeLNÖáK-9±ÀºVE÷HMˆÄ–:³žD¶s9M]á>ÃÓÑxèXûñ{¬Iï¼ØVP6®Õ1ãàä!¶*àöcÏ¡Ñ�x aÎ9�5IY�kÕIÌý÷åÂÅÖ¾Ï+òå1¾‹T¶h� ±J§ÚÜcÆã±ã<&µ““ÿÈÉ`2mdÂêsq|N!Ñí¥sS{ÂA9pؼN@¦÷Jž[¬ Im>^ô¢eDhÝ~9ZµÒoâš·¡f b�NX)\þb›ÌÎÙÚúìèoSq®cz»eòØ+TŽóæ½"W#¦6sèÎLJ`©‡°]¿m€eëùóàýº�oçO¾i5…Ž+½¸÷œÚäé J;’kåÆƒS9'íÒÆ®†2;�ãÍ’£®aýx>‰³95íw4ù,QTp\ø/Ú|ºs')µòM¼ÏeùŒ�ë|AtKÅ¶Žš#™V»r„#ÇÄ�½pãðæi�óY½JÈŠu :©Â`tµOØæñ­cóøc�_Ïþó#è�‰±‹;FÖäúùŸÿ…ôO±ð< þôÂEþ BÞñÅ7àyLÓ‘éׂöç~úzýëQÿìãÙ*Eâ®0!ÓêKíš§%ž‰úýC‘ozå«®Wû·_<ø°kDߟüìÿìúË_÷U×Ë^ʯó§Û<\´|ÉKÞSÿëëó>ÿ/\ÿô‡Hÿ½Dÿ±ø)êÑÅ’5¡ú‚y.C>zÊ…Uúœ¿ñ±ØÐ×þšÇð¹ø¶*NnOJKŽ™@÷é–¨�y|¤oŠük»Ht¦r“UƒIùúõÔz¤w�ÔcØÓú§.±†æÎ4w� È;é0­Rú9O5óñKÿïÿw½ü3?ûú…_x�}é�tPÃOêׯY?�w|²vUšüõ…?#½ÿìGþ™U›ã&J>]fîá\hñ ^ ¥k‚¼o°fŒIëõÚ×.HCðñzê}ß÷½®ç¿Ó ¯_þå7`Òù‘ã–wºê¯¶âÐ -“g;Ƨ‰ ý~½ëš…ôs Iu㚢Z@_òšLG´Kt³a�=Ç:Ï Æ ëç Í óµÆÒHœîIÉ PYã¼ÙåÜßă[˜ña˜Q º¸±·FâÃW+Ö¶kÞ_+È3 û÷úî*±pO ùèV>××)âšÇ£É}!xT‘W‡´?ÑÝÞ9n\];¯6Áåë/láƒC„­Åyè‡Ì^7îèÏpáJ<Ø»�:‹W?Ç׉¸h+ëÑÈ“|ykì$�>¾à'£_ãã=&²8kê\*|¯cƒÃ\Gòrás¾y+tŒ¾O�¿æ²o­}®Lƒ|Næëº@~í>3„Q‡¢KîÕd֜ϩ\ÝS›#E9óÎßžçøØ×…iÈômøà�¢]Cm”à5==¬Ðd;~ aòhreÖù§æÁºêIªåÒ½_ýÆŽÚ/‘ïÉvýfÔ’�Ô5 §Ä:À}¬v]øyŒ‰Ikd–ÙÇ/ÄÙiš„ &qi„ž¹(­4 C#ïmt6û]+>#ã5œÔ²Gø¬îÎ׉ŸVût†ZÒÂ�i®×]èƒkB´ÆÊKÂñ�п*cÈ“iR;hÛ;ºkib‚_[òäņ ^LJ’@ü„[üVß”\è¿ÖL<¢;XnÊ©lµ\mèëm4^N\)Ô7�=­_*¹wÎÖœœÁmþ°�'}ºý¹Bô¡¿88À˜ÕáÁò´€9 ùF�WgÕ‘Ì!ÁÆ7Ô:vª\9è_3Ä_ó$þ¬m3bÁq ¹c±ØNÝô@!2�,¹ŸðèHo‹Èññs1åYÒ�\¶¥îaœÜåȬSm çÔn÷˜o¶òMèSúFAÉÞ]K5@…¶ªãº!¸«¥yá[åjq�Ž;56®ä}¸×Îì?jpÿ.Pä‡è®¶êê\^fl|ÛϹpä<ñBwÕ{Æg}âZDgÞÙó°cýõqž—ÑÎà ¯x¶–ñ©=µ�ѧ×\<Òs“/„ šs]ïä¡£„…ï‰[õ㦃ó/�ãm¾�WkÂ=ñÄÛ®§ýw÷èi‚únêO.õÉë4>%m>²ò´^9ÞÿœÛº ô¹ŸóÅ×ãú�»r'¡QC­v(žúgæâïîAöôƒüC ýC‡7s¡ê~ÿ×Vþ®ÞÛôOB¸`Óã%ïå<øÉŸúÙëýÞ÷½�O–¹„>Ý<Ž™þ±å›€7üò¯\_þН»þÇÿéïÎó 1y¾Ë}o¾>ë³þÄõµùk®úõ/õ»¶Ì5Ü]£õE/|§ë þÜŸ¹~ç'ª®ÿq!ê~õ7¯‘(ÚÏQÎJÿR{þ´zú„bàÁɱ§ßOè‹:ïëë,ÙZ]d1ºSÇî­úo¸þ›„Úûü‘†'Ôožsé;¹Yƒæk;Ãç º39…nû“Ò—cÏ1ÏylZuœn†…‡†gHšÀœ=µ0V=]Ëîןƒ{Rz_÷ºŸ‘~úª*é�‚àgOÿøF{Õ�n|scŒÖ?ÿú©"óÖëúµmœøÉ?)RŸlŒêé¼p¯5Ú‡‡˜e_„²•KDóLj öG}æõ‰¿í®o}Õ«üŃ(¡{ÖIJl�èŠÙÈEb}æµ[OêµP�7sŽ·0Z÷Ü+5ûÚÎ5~’GJ miØõžBû cµ�6…Ó½§®Ž~3ëçs]‚Žßhq(ò༧/‹ÌÏ.ݹ–•ëVbꬌá^Øa@76^#òøá9”âøÈ§Î7ù‚ãÐqdKºdd1ù«Ýóð€ˆ€È×Ü$m\Gë@±xÀÇ;Áˆãõ/{Ž1óݱ¹ïzºw…÷Ô‚õ¶¾SXc;ËGnC˜³ïk!Îñ*ë9Idõ2£³ƒ=Ï©�‰BÚRK‘¿ö|Ö�>€O.ç”`?÷ª—èò÷;JAžö-‰;³�Ü=n­çïw~¯|¼Ü4mضiÍógú_Ý÷ëÆ Ó¯3`И¶¹ýާGåÔŠ>6�fïöc¥`°ÖÄj)'†ÔÛ¨¥ ôR÷þÚw{>&˜Üåï\;³åB¨Q½[ ½©ž«¼ã¹ü‰'Ö ºªFí|�E¾~¿ªØ «ñ˜Cƒ6£œãÖ_´�·ÁÑß]fŽM^׸�É�¯m:;¯'õš�qö Î| GÃJ u4�¯}çO?º÷*[ ;¶˜Ý¿ða÷ùà”ºÓ'×]ò\É×p9�ï^GŠž­×ÇC;kÎÓr´ÞÌáå~‹8�+Œœ|ŠÕÏç8o¯g4Ÿ‡ŽfØ 4@ßHºêù1nó7úhñ“/äsyùìÉêlÄ,¾}\L•»Ð÷ûkOâϼ–©8>Ì«8Ö>4ºs:Ýñ—º·fxVcNÖ‰6‚ó IDAT«8LÄI©MògαÅLŽ3ŸzGຘ!QññŽ/æ¿ÿ}ßýÛÿÖovM«~²!íí t��ÿôûgÿÜ_?ð�þWýÆ6߬ ‹ó‚‹w|#}]Ï~΋üÏD,B{´,ênl¿ïz÷w{—ëßýøïúÞ¿û=úû�sALÉú ZÎOŽk8>Y¥ÿú9[úª ©þõ3„JD”Y^ ¡"ªaÜ8ëÔ2_çëΓªëö˜“›ã·'‹Šhä]'ƒ|=Ê»ñãóÅ5º’óÅ!¹³üàÚ4(ÑÞǪϣ#ÄKB¨Üîç"éä"G{h›HáôEHás>ªoˆÓpuÖ˜¿óø†7¼AïÕEêUŸ@gN‚Ø×¦ÙK4Íhÿ]O�š ánbÖ7V&àŽ¡Yb¹Èÿñ÷[¯o~å+çkWô«›E..ç$îˆT-OèBº�å¼®$�Ž[”å<Ó½¹ó<–¯[¶Ù<Ân0¨¡ÇNî9çnxPNˆÝW¹Šw2ø[{Ÿ* ‡y‚¦Ê>o—“ô=WSÏäˆ:<‡të�¼auç´„ˆÌäÄÃ]Î!v>¦cç¹À{¾>ñC<3ƒÒqòãFÑÂ&&½lm`[òí@0œÌX³¶Ä4uÍh?5ò<ÕXŒûîÚ†„ £ý÷ä—3ïPsjУ(ºm…ÊÏ!ÅÀÉóÁÞoœŒiìÌ æS`ÿ\¾ýu2ÊéÙÖ�úàƒÆyÐ=fã×W4ŒpÝ®kËl3í|àûý?вë'9y'jjÊ._ó†*:µÉ×õ#‹Ò¦®Ômøoóc/N+û™ó¥5Ï­Úãçcý*êùBÑÌk=iÂaMä½¶úܱrÖ4hïY3âë:3÷P[çÊON'Œw–ÍiüÄð¸˜�3£Ù«–‘/Ü:Gøú„]¶V·„ìÆNÓ!X'öJˆuÆÑ ¦ Ozªt@R'G)ÞÞ ‡Uj‚—/:‹wbÉÆM{2-вžŒÖ ¸·"�7zË×øÔI ¹±(Ê6ïÇ7œ�à¨n×5}¢¼ÉA�¸œoðûãà!;y𹋠5Öêó$‡µå í“|Š'¶ºÉsŽöÃ:ˆ�ŠiMîjXœ8[«90hÈæx—÷Ôjûh_)1õ†óЪRÝK÷oâ\³ªqõºXú#=®?é �yzÄb4h¹â&'Ÿ$×âÆFcÛêW ñäÍrcˆ0áM™ñË^�Ä<Ã[Ÿ×§1NbϰÐÇ Uoº±i:õÝþ5)¶u&’›¸H½‡ ÓÎß”¡ bÉ‹f¸A³™{övÊ&xÎ3âNmµÛ¬;C=÷μ¡°)ùêm~í­{‰#W°™ð�EZî>ák,?ÅÑzùc¯Æð†«çvÃáçE Öé@ÄÇgúTOfw±ie¢îr´{M“Ú$p$Ûb¢¹}ÝÚr<-×Ñä#lâÆžá{ÝÁo.ÙªÇ~û†Cq4†zy±Á€›>°J¬Î‹w™ˆÉ1I.mÀm0©\ áËÚP‘òu3«‰qëäá�ƒú¹÷2i�ÇÌŠO=Æ¿²L¬xø ÿYò´÷×ó©#0ËÁ§ëÚ廉ác"V%µ7õ¬ÆŒ?�pæ" ýädj}úúK_òÅ×cÏÑßc›þAåÒŒNl¤åŸ{ü7ßôªëmóÎ1òÃiE£ÅµÊÂ;×pø¢ Ây � °?ñš×ê§âì!¾®z‚$ßòV],ùßþ·¯ø�0ÿøAY^|'î¾ëßüX.Ìü•ë¥ïÿÿ 0¡«o†lr?ôðC×g¾üù–XŸÁ9h@ûÂqãÃy\Ú"”Éu÷XÉàcƒ>ryJRG³‹Ëê$á{=ÊM–ã‡%¹œÏ¶–jyp>vƒŸR ó`² �Ÿ�maRܦ?0òûn:Ÿs®dö¹(Œ/b¨o[gëIí�>ùÄ[®Ÿúiý 1B†ûZ²àFÞæÖ\ݲ¦@:VÝcp8ÆòX¿¸Þù�_x½ðE/ZÏo�ëãÁáG"Sʈ¦S´�™!5bÈXœ{ Ã3�_{⟜$ Þž«áÂÇÈyržS㉈gdì'Ïy1À¯EÐã¬XÚ³ã8NniAwÉóü÷ÁiFøÝ!ç¾ø�žÉù^¸ápŽÉÉÆ5œ?ýÃÆ61üpÂN,æH�x|�/äK DcKLÜY“¾ƒ¥7žßN,öJd¾·ö‰�<å"»#EpO�2Àûÿ3ööÁþ®WYßsr^NN^’^ðë)DgÔñ�Òj§Ú)­ b`´0TЪ�FѪD¨"ÆJFp¦E�u´ÅÈ?ê8S0…�Ĉ‚@Lj I ä$çüÎ9Iz}®k]÷}÷ï„öÞûûÜ÷½Öµ®u­õ<ßýòìïÞÛˆÈÞI’M~2RkÞçAÞäCyBVî!]ù�U ¸­)}0öà^¹G¹j‹,oçä¯=ñ ›o�Gg�އC *ßÄz"æàg=†Ö‹7�‰‡«T ÝGìã/•ydGcjƒp’îHŽÜÛæn éé‰p2 ßv6Íé<À:rî'¶×6×`kïÝg’’vžá!sb÷µh~œãÏ5ìY@òײù�'Öc¶xNiðñ¦¹uÐClÕG.†mš»·�¢g”Çȱ7ÆüЬŽäJ,ÐEÚܶÍ�ÿ9©åj~kW g:º4‡8ÈYŽê8gª4æà_º°ì�cÙ*põŽî8�›8‰ ñºÚÙ”Ù9Èy¼­¤S{ð¦Hÿ§aæ�†ÈHÎôcj‘ÇÚFNð:N¼Œ®Æ) faXe—Ü9’ðà8pðô¾ØèÒ‚ž�“ÇzÂuï':Š×}Ü„‡Âk½h_[‰²Ñ‘¾’Ë XC–:ÀÜä²�)'igèÉ¡xbüÓ+8±›sGØfûæñMl3 ªfâ³Þ€d—ê© &¦ylŸl„òŸ%±ÕÂ�:³bÁËæ>híY&å‰Í^ùÇÂ��>cw½'7“{3h¥Á×z·fú QG®ëêE�5‘SÛµˆö3nÇGH÷™wŽˆô^á‹_0Ö78íÉꈛTíËp-_£±gXûøWß̘|dHT9±“x÷É~(�2°ðÛ 9¶ìcÏyK/훹�Ì€;é’ q©Ù´àFc0„K|?(7yáìæÙßœ9’ƒ0õF¥�Ib­ì­9ëØìµÇ�T™ékzq_;‰žW'‘�ÜÑ="'G¦øi [~–5jg'Vr³Íûó‹öh¼y˜"ç: Vë#�ÿ ¯bzø±ëWþÊOZ߀- Åhª–Ÿú÷?s}Ï?øîÜt3?çOú_ÎËèò¯FFŠûå¿w&Aÿùoý¬õ«¹‚zìyx܃Ý^¥úÃÿò'®oý–oÑ+°Ò« ùÉ;7Útð¯/úï¾ðú3úu×Ç|ôËüy<Ì÷Ï^�þc_õÊë—Ò'oªÑä³à¦xeÙ¨1êÒ$ïe£xöõÁ&QÁdÍ1qG�œ¦riwr°O�ã›h È�hlé;¸Þäe�ÔÞ¬^—�lþ[‚cX?\&ÕhpéìS¸²B‹¡“ Ö™åC‘ALcæ¦Jn|ËK|¿~£o8)S"ø¼õ‚<|ý…¯ÿ†ë�ïúǤž@}.KN'I³Æfºî…_ÄÌž¥…ÂwrbW¬õ±Öxì±G¯ÿè×þZÁr5å9‡¤¹É7ùOJ¸|žù8²òåÚ!vß”"Û„Ï9Yh_MÎYh¹-#1ŠåOZ­m�X¼Î^rpÐÈq/z “×8sæ!Õ’ r¥gp‘3×{¾n7·ì+†N&,³žÈ ”;9 `wðL)+–êZžù'h‚ýu‘Ö@ÜFg^f˜®Añá-œ�%�s“ÄÆãöÖ¸¬ÛÛǹ9 t¤œ³ŒœóÙÜLQa^-Ûk V¹x·tÅ["´+““%'ËjX•L>±³â˜°ßjø¶Õ—$ †º– xÓh¶_úšß7n»/¾Q�í<%¶j‡$.}#†GÎi*#¾Qh€KB¹ ²OÏYS5âìõ'z7'×¥û/@ZUŽÌ>_‹?‹i©2˜õðrNóv�s¾­(d¤¶¬ïÍ_9` À¦ ±ëzêETq L'Òo×/?qvë@˜Ât§Ý4&€ƒè „7Úצ/v×áà9'�‡òˆÍº‘�9kf=à$Oë¯Tõè*Wð¹£a�)Ÿy\» •Íí6w1'ש»\á÷Î5f?Ç©Ãý¢œê’�Gû–üÓX¯µ‡9Øp²w1ƒ×¾xm¾`9–�<à¼×ŠÁ*ß™ƒƒÆ?€ {pŽßc´»'£;’K,p�]Ãþ›Å¡Ÿ¤ƒ8ô1×ÌÇÇÖZª|¿~~ˆÍïð­BX;#œ,[¤Y" ?dr§0 Á4pˆŽ¸YÛPë��ØyLP¢«fèçxgï”Äë�h•�TÂæÝ5-  ±Õ¼0³°¯xÙÜŠ%V“ý`Ý,Ð �®—^ ¤x¸Òq‡ùÐØmIÍê܉‚sã4µ¿šƒÜõÉ;ŒóE©>÷�?Àär8�FÞµ©†Öx„Y³¹QÖ<&ˆ6åt&=¨qilÑ™Ìôç]•„s8tÏX )ËÕ9�x�S¹ÀùI†SïùäÉK±‰ÔÀæ$ÙÚ$lmô̡െ¯ú�-8'˜f*Ä1ÁA(3bÂë…lÚÆ}b°/ǀ؟£{ÍÑ31Žãy†C‹—¥ÞÜ8mçÐuüIA ¸Œ‹õö˜®Á ù&Îäw9’Ç­¾:Í™„8í5¥ö¥žoeâ­jc5Æ:}¢²…ÌÍ“UµTW"Ü?÷Pû|�oïÎáàuÈyh>x¢�OÄË*›ùâV‘œ¾¹Ëù�§@y£c?ãr‘c$$—sN^Öù{6ã5ÁñM!®:ø˜ ‚0uú ïlã°zû¼ØèºÔ  ב%›`Q%§éÝißýKHtùú‘ IÏ_çô}ð‘ã<ûÚówtèQc› = Íškêº~êßÿݤʯÉö›òhéçv�&�ç)_ù¡>òͪ{ä1ýúägù×(—&ÅD±,¦ÃÐñ±ýíoÿ¹ë�ü‘×úæ£>Øû†þš‚<êï/ûøO¹~ïïùÝ׋Ñ|ŒÈµŒœ¹$v: 84¨ïaý­Â�x\ÿ”„ýô©�ãÉóй×ö"™8_sœk†‚8_¹b‚“±R°æ¬cŒ±%&@4ôÕűGož'=‹«xrµnÍÚ®¨¢B«¡£g ËÊR «äÁ�ýÙ6~Î7,9W}>Ðû5Ðã�ƒÏ °N~%öm?ý¶ëk¿îôÏ_Þ/\"9ºÇ"Y²‡§®ƒùH‡.ûÛéšô„Í�K¸>Šœ£Ìù8“D®­Áx?L~rsnr~rþX“†kƒgå�J§Ž}^eo,¤Ä¦/î&‹XDÉëŽåœ§›p #ù¡Ë¸�#A´E{T�©ÝËšÜÑØ¢ª}ÏÉ™º“¯Zr}aK�’{4iãÌó9¤×b¾@Qj:í@+2Ý—è†)¸]G²¤GÔi¸ãt€}âÙ‘‰‘~deuh”«º3:…Xç(/û¦öä �Áf¥Ç Öº[·�úî>}‡}jz—'}:u“nãG®s$«fÇîDZ…;<¬y$QÎqEÑkå¸ï\ÄðHC¸km¯ð”!yH€%Öm‹V¬Éyú“íný£À@L5|¤…3Ä÷7"¾Áî¼�…ƒ#±Þq(דž%ºµ§ïÄ‘j…VæC \zã}�韱ɽ}³ßi7öÑXNjgxZy¨©z­s´_ˆf·NÆÖ‚Ÿa|ÔåJáMF'&n¥N¨u‚i^›ÀŠŸ@ö76ô­�Èä¯i¡‹cŽ`ë4n|ëüùñ»7`NñÚ§©�á‰Úg€±OŽeœÞ dõjØÚ€]/¹fr®äÑÞǾ¼ØŽ}b ܈‘-‘¶qt<{Šï󜿚5·vŸ¿â>x|"­É1,¡ÛÖ7™dÇfþ•/‹noxLŸ˜Ý…è[ÜÉè#:ÐãQÝ�ÑÄ×DÞFÀ‹, Ø&à·Y1àxc_Á�Á…{*„m×Ãá=‚¨¹Í£s˜P{�´ 1ùµžhtâE“ÙÉëGö±õDofkÛÌÙ³ –­Z‰mO =š��:]ëÔáƒqIƒÛ Wz6‹ÝˆÏPÅ0;œ û²¬ixdœÚÜo[crDO.¶¡0¡{*Cçúˆîy´’¥A‹¡n.rûm¾Ñ�z“š£=´]±P­ØÉsæ7®ùè…û1¬ŠOïö|òÒò&^ôS+Ü#žM„°Ò8Î';Λ¹¼¾æÆg]ÂÕvæE­íŠ+1 ¿ÊÐ5EKŽ“à&ò ™šÏÁj¸7r£'>‹I0R�´õÛ`ÝÅŪ !°}÷½©Ï3×! ÔléªiçˆÞ¼rÊe0�uóa´à‚©7WÁã`�Ì]÷³å-3ríu\¬XÊM�ܰg¸½1hê{j×^‹•‹ $pF²¢Ý}=õÁ¥(ëj'&ñ8Æ8&66;ëñ¼ûëRsüæyÕ¹&ŸoÞ wr±ôßFôßÕÿF7¿æõ¯¿^ñò�^zŒ;³“îx@ÏMŸ?õ§¿îº§,â¿ÇJ¥²ó 6®’§žzïõç¾öº^¬_e&v$¹¬É±†üÐ×HxåÝ{ÞóÁúÜöìó ³ÕÄpò*E¸ìÕ!WÌA%§_5Vq�ÍD}2`z.ƒ<Æ€ ƒ†±^æ%Í…ß4:pÓ¬úò¹%ϯÚÌ£ÃfÇ’A(.R²„?"°�÷yH° "÷˜y^÷WÄ¥SûÎõ(|Åéü`ÿÇÿä]ý;þÖuO¿Š¦¹­‰}¥ c´Z¬¶vqðâÎdöh¼6î¡ö.iÅÉ� £æ—½L¯4Õœ_C‡�úÁÆÁÆb:̸¬UÎÞ0$Ÿë–Íóä´4à¢æœ÷ÖŸ^·æ,�h÷*Æ-'ĆG~™’‡„¦ƒqü‰4)&G÷¾žwâĘƒC9êþ!ñê¬-ö�]Ç9žPüûótxƒ+ïpN-íáŒð�s´4gŠˆ|燻ýa]LÏÉ-¿4ŒŒL3q‰Šc"}+C"JGl³úë þÉÆ×õz�=½+¯u þ³æ‘ç8×3†Ököá��‹ÌŽRŽì¶-ù F0ºWÚ³>÷{K]7PG')¼æV(|·ußèK­±q„3=W®E[‘›39îÓ9\«Y¶s˜VúŸØe´½Îž f’31ëp—rÕ“™zX•ªÔæ"ûÄ¡cs$�ÂäM ¸=?8!¬ÓéÀÞI8Õp†—dkobß=MD.›ü@L ùæ$7ù ÀÐô³#sìÎgyr=Ù6ü«Öá]ú $¥kÔ†}‡¥PþÎVd´Q›ybF¿kÐvÅQ£ô!Õõ4©‰u<ìí‹�sh�ãà ®yðÀ"'QkªF³ •õ½¡«¾Æ…ûÆ­sìÏéÖ ãĮߘïæ©.À»äê2É:„Ó?о±A8ùdwÛð³;¥ô{‚1-ÐDÓ;�ÑDzc]osNàKÍSÍäê£ñÌtï&iŒ¹k–ç€èÝÓ„+ÖZŠH;óK±OÔAV¤ý‡ýî²'<�X<2¸§«Öµ…‰˜6ÐbBäXóÝMxg·N=«vawî]Iü©p[£?ôzb°�³Úà!®ÜµO­èH°cÙS{ušk°Itôn®P0ËwÚˆ+a9´îÂ,ž Úsua9×ìÃÑ Ù»‘ºÂòuIâL &½Ñ—£–úð7÷”çr-§‡ˆj€ó\ão —rêݹði¤¯¼÷A<Ï«©šÑÊwŠ•½‰½ã¼ã¬iy¥x×Yíž³ÁnŸup=Jl °Ž\sÑåššHsk!´¬7tª!×-Ö}^Aïö ¶Ì‹MßиJß? ]þÌèJf‹½uÎ.Úٸʑ6'n*Û6 z3^ߤÖZ±ý¦)ù&7º¥cŸ³œ+rZ_B³…ÜÈö&zª‰ÀS­ÆÊ‰?ÙrÖH™sÃÆuS@†øÈÅØœg]ñEOÖ“B�æpF4Èæk`h{þÉUÕÀÀ¢Å”µÀκûÎÍËN×=ߨe[5Bå°Ä¦¾ê8]ôpFÖa<ÌJ›Þƒ —0ÐÏöCcÒaC7Ûá€Hc»!‹�©šz“#ÇGˆ¹Ø—sÅÊŸ|õhžendÌõX7ÔÇžÍ5¯"“Ÿzáõ�c¦£' §¶±µG'îÕçuånCe€Ïv«­< ãù·Pmceìóã„Ò>uÁñ¿üÅo¼~ËoþÌõë¿ÂßtίM¤Ù}Oÿ÷ïü½7^o}ë›õOyô+–zðÅÿÅ)ô…çW}埸>å“?ѶS�õb€�1üĹ÷´ææåûÞ÷¤�Ø©å1vµíᾎ©«ç(¤ÙCl<ͯ%6=÷^d_Ñá`ßÜÎáÝîùTøê{o*RSþØ|’¯<ª¯qÎW‡I6[®Û§Ÿ¾wýìϾÃ=2dj9Û„¢ÕO-Û¸å\³µ)x>—øó‰6Hð5Ødš5¨ þæBvnª¾á¯þåëMÿ÷éïædÄN…Ž!Ü}Ã>ZÃeÇ€÷ù›àNæ85àðóÉópˆ›Z^ò’—„OëÞ¬$·Ó"„LJÖ†x jï{ûDb/y±ñ&ǰÛvÆ:sY3dBö|×̰&?œË.’œ§�³ñůsemð„.9»gôNžFzœ¼äçÝ”Í:ûÄ;‘}sþ’Ê<ðY7�á=ÊvK±É�çoÏDcµ¤þ…u¸AV8ExË"<îq÷q$Æëô´u/Z©RÌÙ'0€ú +h*†3ÈIq`6¶\É­ÁGÿêËhÇG-Ô•~ÃP>ƒB9˜íK'–fºc�§‚Žë§•©¹’¶Ï;3oì?r4í>n[V©¨k¤Û\™#/5ž+N‹I¯1Ò§×,WtÜÚSßÄ-l£4Oíæ3. º¶œoâP6ñøº\ϧiÇwâ"¾ÆNj®ƒü³\v8v猞$DG´h¿rD ù—496Í•/?Ì�Nc/ Ë釠E Ã㜆Ë06sßnl‚&G+øƒßyc*&?Áì…çh1ìG`G?ì–ŸE/Dx†Ó‘¬Áh¬GêúìŸÜ~#%:¢ež°Iy IDAT;¢ÕôôXïÉ”\x­�™‡¿ÿŠ�|ÝKÊC Pûdšz 35âˆUÓŠ'ü‚o'·µš*<¸ñgÊ"̱³Æºz§õêûT›ÞL^ˆžg¿x&ÿɹCæœÊ0²¶‹•xÖÇL­cÒ¬÷ý%õ8Ú|`^×î(Çú¸!Ú�iüÔiïrÈIòÉðÚT9ˆ£\ šê>€Z‚Õ„ÏþÁ4Ó:›ªµÝIŒ]ö°b„Jc{âØäyÿ¼9PxÀõ{/Üàck]§cxÄ0‰Üç!â“3¼ð¬< ‰o(59Íä^ÖŠCµ¤¦p„€ŽÖàf#�ûïz8x첿<£S†E‘�—î£Í¹^vî›+6 Y°®z¢Á{Ù˜ù/¸+áH4ë!!Ÿß̳9šÃuvã`·†ô.礞?±×Âõ’}lãå®´šÐCŠHb­�¾°q@¹þ‚#ß8ô›û„ã?Ô}ý_ø‹ºù÷êëýÓ�û†Âý�œfç*@ûw½û®¿ú†7¬ë‘´`Ý_­ÿˆÇ¯ÿê¿üÏ®‡/ñ®"Ÿ{µÕh&b°Y:‹®gôв§Ÿz*H껑›UÃbªRokËÖSÓþ¼6ôÊMš�JÚz“ݣϚG«9EX7y}]°ÆzÐdL2û×e•$¿^+ŒÞ†N§RÿòÑ¡X:ø/´¸~ñ½O^oýç?z½öµ¯»Þü–NÒœõì[Cú›�Ií­¯?mü9XÂzœMCްekhÜÔyfŠ%”yT[|Χ¸Ìh�Êrn»nìž_J³1�©¥©~ä�6ø\Sµ”J�¼;Ødn«Ct Çdq“DY�ýXHznvߊR^dÀ~ÑÝÔÌ~im\g–Í:‡ØîŽÑh×óùÁo{ó­^.:” 7ñKè¤XP-ü9dxq;ú¦–ät?W|SRzÍ:Ù›ÿ¶oÕL~³†š­Fó '[øÐÂZsÖÁa&kêÛ84¸'á:b¡G¹Ø[4 2»oZ2›ƒƒu…ƒõ¤>»½v ¤Do0† ¾µê+Ÿ…4,‘²+a¹ê°Ù—œ‹7Tæ §íØÌkYã}¤°ŸÞyµb¨…ÜXÛ—@Ïœ©Ìü4‡ÞÇÛC¹°N”h$÷iË^Gqò¼­�ä0¿×¦Øö6j²÷¹!“0#“Âä„ýDb9`'Û Öþ°&¾J †�(±†8hÍW�FÐŒø²Çx6ßë38¼Š‘Q±DíÈqjٵ2ÔATÕX©daš_qú&Ð¥7ã'À�SHצxx;ó¯k.õpYQä<øÝä&Ÿ¹¡ð/ÞÑI|uEEÐØàbm6›½%n¾áDÏŠ¥¾•£á.ü¾¹Ôž‘@.‹ŠZ×${r úXŸñc7 °µ ]ungªh>ÃWÿÈÇc‘LªÖØT ·¼Z,þ pÍÉ’ó¢7ïæé9Ì<ŒLÄ®mú³âG‹¿ˆ7øywó`°4‡m²»®áÆŸt1¤²Ùg<\?C\†lâ$G5¬|Æï¸FÜ̇Nìî•ù¶nkqPÀ«‡ôuÅÏÂ9ÐoO^Ñ0¿VÉV#Ueíb0Œ±üÕÔJº€Ëâ¸ì|f´_ýк=Œ¨}]4»u¯M¯—áƒËu¥§Óñ �—¥“¸�5ùÜÌÍÆÔ_8sáåJŸ�HFpA¸¢¹‘�7ˆž�U§ãz(.X¬YUƒvN¨ý™ªáš9ÍáØ I‡m0Õž˜Ä bq؇Ž!cß¾’;¶Žž³šN_m`‡�uøíQÍa¡G¤eO¹½R@c˜�°#˜±9ÈkŸK)/_›Ûq‚¯ÚtÎöÓ1à µÞ�Ä\ �¼vé¹#“q�äcÔN�­³|øAåÚœ›8.Ob³-#M·ÁÚª„lè%87zˆ«× ùœBFëð Š›mú[�j÷Z¯4+Î7ÿ¸ñ lù†ëƒ×øýðúÍ¿é3t“î¡�¬…›‘ZîÆþ‘/{ÉõéŸþù©8᥽qôÊW¼òzá [Ñðc¡Ã²×é¥Ë'©¿!ú‘û®§Þÿþ”ÿ<2ørÖ ©d¸O½n|ÍílÓÄmȹÐ~5’Ñ1°Ó… njq.v>1PÙohMTùˆÙ£qé›5‰Œ26>þ»37\ßø=ÿøú¼×|áõE_ôE×¼ùûý±¬9¯8VÞ»û·5Êþ þÖäF Üü£“sɈnw4½U-”ÊÇ_¿bP¸<÷ìõÁëáë‹¿ä¿¿¾öÏãõŽ·¿Óÿ•z(Í.g;N˜WÏëˆK˜|Æ4¹ ƒbZµx_¬›ÏhæºÏ�vÈ’ch÷d‚Íe±�êÁqÎ7›ùØgÇ÷”¸¾~xè÷rxG€Ï§Öþz˜<+b ™Al¯¯low.Å6-ˆ¬3 ·AÓwo[„ÑrÅ9 $þrC3TI1o´ao×�Ÿøâu®ímw-Ž! ¹ó™• µ6 ñ“~­K1Vq…Í$ÝE´wz>OshÅ¢T+'Bf`ã­Ã»ÚF‹ý?Êœ ûÒ=è…mé†Ã»œ#׆¨H ¹†ã$(¿ç#ÆšÀ›K’î26Ås6Æð3@µ@gÊ‘sÕ¢Øøu”1ƒuØ{j¥§®ù†>›u&&{S$WN˜ Wޏå�†ðc‚w=ðUkϾA­kÊŸl=�*"Bx”‹ÙÌ2¶„ÐJcG¯`4k×”@ƒzÍi «=àñ(óA•ÿ @óNótјkæÄ¥ª#� ŽÑ"IГ’O<:ÄÕߌÑEàm“JïLï36|'Þõ™5 @}jà–j(—ã Çy¢È™x/m=ÚÞÕ·rÀî†Þ¨ŒÎ‰ÖtòGW2Y3}×»s[­ì­sN~sy6užX«îSüô Zîí¡}‘'óäV¾b7¼Ö ?zÑ¥±ãµq™^ÞåÍ.{…8.“‰ëöÜ<ËO=Ó“h›ó˜Ñ)·M)Ý¡¥µXš¸X³þæ–95° Ö À´{„qdñÎØ1‚_CKï5·/`“Kòï{fpð¢dQÎSÎæJ®r”sjr�° f.t>íÌé$üû§ð¬°Û� Oþs Yz>zASÀ"#±¾¸â&à©IÜv¬Å 0Bbg¾ Õš7¾¸«Ý<ε*?ÙG kô‘+¼h쵚5.#ñé|óMžjuèðÊl{l0¥8ò1¬t;c´s‹—¼h:ÆÚÇw£µüÅD¢Ò'7æ­cjÆŸäC×*ÁKœØõ¿{1r°{Lž¤m/å!FFãœgð¸d¤äñzã^Ú‘Xh×èfñÌÇ­¬ºŒ‹²e&ÜÉÇÚû’[cú�ÉqΨPòb õxƒž§U³ãõ÷Íô÷ËÌ£}ó¶n÷@œ¤9GühÚläZ"ä*_bµ³Ïåôõê<áÇ� ÆÎ  %Ö 5üÑø€n¾Ðxb{ͼ@¿Šëz'üõ ”ê9òÐÃ^¯zùÇ]Ÿ÷¹ŸíWþ¡ÜÉàgÓ<ØÝÏ å#�ûs>÷zã?ø‡×/þâ“þ[ŽDñð‡çPLÍ�è]||žð犩»uœzI)»1¬gì#ç†x!Ê2c¸gµ¡âìE 7-vBʉ+CÞš 3N€ÍÇšJçÁ‚š &ŸÓ±Ý|ÉMÏÈÓ™XwR6“™Ÿhòd?ë(´yÄbe+7î¬Y\ÇÆ~ùÊ?_˦ínîÔ$ÝCC�œß1šÄl¸¹l!:ýõçD¶CHÞj± .?À;8}+.¦Û£pÖ4ø:}n–M Ö<”{kÔf´´&ë1T}|*ϲW˜©è…Áš!ŽL^ËVÞ•7Žmg¯ásàU8š�8†5 k6=Ü¿96�]\@8W‡Þ…™óhÔøý¹¯1hŠ,Òx8¯°ð-m·�ÔÏ‚ ÁMÝž‡²)¼Ý:aí¦Ù×_€�þ¥çê•>i�Þ鉳Œ~°–<3V­Chlýý!¥*ñ|y?â¡÷œ?»½ºøšwô8¹‚‚ bõ:^ÇÉz(¦ .Á:E{žµÅ T{^ÔcÑ‚šC6ŸŒ)ŽX0`‰·ÕQ³jiÓ¯ó|h©�ˆžì0a‰�™'áªI€pÍ5£Ë~ÖSoyÐÇcùYë�“•Y†§½6ÏÃÉWˆÕÞpPÓˆ{#Ñ–èÖÌsÑ?ª$©K]!‘?0l*Ð;6ë@~ÖŒXµxïŽÖ&D€õÈzó$ ݸ–žµïâŠÖYAÎ/ßÒ1ºW–ä™s1"H•¸¢f¯íYpÇ#¹ìE 91¡ –5Ç­…m+‡ÌÖ!ŒuK˜Û6¡D�£Zˆ/7ô«7¬qØmr‡7îäZ2ÂaMMhÒhrª±Ó7SôöšÃª ÇÉ«w³Åð ëô Æä”ü�ÇÔœe”˜ÔÂZQ>‘sn!s®$´VÓl7}˜ö6Ö†Í$œìåg ×ö¹×2Ñ �I…ݶ;ûj¡‰áXJ‰®ŽÅ‘¢BOQŦ5ßÜX¶å’�ï4Ÿ—uº�­Åù&ÖôKlYøÚÃ`\ÅL®~°ÖÖ?©í›Žó¹Øó™~9—b{ž#}q¨ûJoL-WR ïKOà}!77\/¡Ö«FYW¼×Ñ{êóÇdÇ[�ðÇ*k²0Âï¤ì–­¸} ŒW�€;Q<¥ö¥g|&ô:}ÀAþŸãL±E‡w³›8ZÉëG°Í_�›a¯âËžï¿£�Eô²_ùfëÔ2k¦TËâ�õJ»ô.×�› ýØ|³J_(¥}\Òßëû†¿ô篗<¡WJ¹câÁ) ®]K�#_í�ynñ÷ýžxü‰ë~Qÿ¨CŸ|ùÛvü:(ŸoŸ¹w/uT(h¾ööž~]ô¯|ó_ó?ûà•nüšë“O¾ïúgoyóõž÷¾ÇÏUúEO�Ø�'½NÜK?ŸW Îè�±çKˆÇsÏ=“Wwµ^‘“&µÖ�‘�¾þ˜µ5y o¼Æ«�;ÒD�äÍ9—zí}ÓEØPsl�¸~öo¿þì×}ÓõÎw½ózó¾ÉxÎáƒòëÔp V¶Qƒ9²(WŒÎ­å| bÖôš Ö tFKlîÇø¯±ýÜà��ºÎâ¶Ù‡t <-î?óç^}ë_û¸ëkþ쟺>ñ?.}Wµðà¦oÖü Éœ{nö¼êU¯ÐMí™Ú‡Ñ7i–Þˆ¸Ô/Ðc�êik͹^޾Œqt—j@—Ï›wãTLΣöM¾÷÷àTþÆ%Ê„LÌìÙÚ”�Ä{äc“¯1Û£÷Ö0gI¸ò;܀—EÏï¡ÉÌ1žm¤×$3õn§7~Ôv°"slÑŠ–|¾Ý¸ž¯¢‰XýÃ9ƒ›yþÄ3þ|´è×üiùÎ^ýÎØóᘜƒ›¼M¶r6?ú;j«ö}îbÓnò4÷Ê!ß K–XY9_ý¸—ÏýrO¼[oùÃÆ€ûœÜj÷J$èrO5ó®OhäÜVÍGVF¼))¹¬ÅöèŽcbÓ<¶îahžÎ9MúӮј2Bàu1N5î0òq“UûÑÞ�BƒDt~B'~äSƒšù8M¶5v–éݼŠÞ>ˆ;ÂQ.[›R°¤˜„8§_=ÏÌŽv?—ÁEω3wèc|±r̹KoGÕrN©ÉE4%p]È‘ˆäÙZ,aâ &ƒ÷ÍK¿èÍ9î³!jr�3¾!vmŽæç�r³aÄè¹<½6pׯ:}fr#G¹Avs 6=Ïõm¬!s½+_m4y(‹2–fmøœÚsØ¿{Ò@ÏÆ††ò—ÛÄ0ϹÙÂwþrÛ=¼ÁmRÁ×—Ï÷.ÇÒmíp‘§5žõCÞþÔO°ñ,í]vã›>âÖ›õT¨eÅ¿êžX&×*Q#Ù–p$Õ²«ÖæÆöPE0>¯ae›Ls¯ž8H0õî8'"ø‚•¬=OŽ9ßöæïæØo<H‰=Æð»N™ƒÏÍ |ª­¸×72Š·^ùÓz% þ |ä©Ysz3RFO9`;N¡ÁäE _ðÒk}Él¥”ÃlÁ2× ³¹3SX×`G⊱äÁ³öd˜áeؾlHñN­Ãh!}öl.‚ 2qaÄ®ÕÂì.€‡>9Ñ=„h¸ÎÉ¿u Ò­, ycØáyÙÓsmm›Ð¸D =¡®kêq_‡v†{Œ_ï7T Çõe¤{ÇT¤9מ½Å‹�/8Ñ� 2ºO¿àb� ýHågN\»l¸·‰­2›8oS�kœþ.eç›2bû°·ŸÓ6æ¼Xbõ,[» ¸FO÷ø�;#L='Õ:.£ŠöÆÈë•9‡kùo1<÷7ç á¶7‘ø d›™ó8çÔ¡ÛoÐð´¿ÜØ ŽÑzÒ71Òp‚Ì÷€þ›ê½ëMßÿæëã?á㯇ükšÄ84‡�³aùØc�éx<¬_¹ìM¾ØÝkzð1#7]ž½þØWþ1ß¼ë+ áa˜62V pø9E~xŽ–½è…×k>ÿ5úoX5=¤W§ñÍÅÓ÷ž^¶ôKŸc´˜Ëaq|P7ŠþÞÿùèàÏ_�>úBµ€ÿü”q9ÿ…Z�Ed…©ë} ëÓ~´ež6ˆ BKjòuj F=â¶¥pcÁká3]Ìp�|£È�­œãž_H±‡‡$ÜkéMBk—ó*æõî�ÿï*–¿Û‚üº.7Ê8Ç X5T³\íÙr�¥¼^fD»&¸Ý?fz—¾ø$d°6¸¬OPlºugnìvhòçTzÀ+MÑ¢Bßþη_¿ïK¿T¿f®_Çæ‘¾=òèc®åY®½}@7€Ñû‡ÿà¾>ïóþ›ü]J4è­u8ŠX|ƒÁ mO¾ïiŒ}Nùé…Áƒ§†ÿ¯�Nòñ`‚¨ÜÛE2Üòye¿ÀŠsß´ä¹àX­±CÓam˜Ê‰Ÿ~ ó#ÏÝé�lçÇfë!frï°Y¤Žä°Ž¹àÈ�u¸½Wpô’oÒ×µ2y�ë¢?ä � —¹D�›‹,ŽÄeË‘ÒS8Ø;ñóuˆAR•ÓŠ”ÅDÑ–uì6Ã>1šu­·Íö:~ã¨ëfTÇaß:wÿˆµ¾Ñi˜r[½‹}Õ)ÿ�®Ùç&W|]šó Õç:£Î-P•œZ2öša<ù1Îu‹D°1±™±kP¬lÆŸÅä1¹‘RëÐ;„k»uôúÈç ‰A³Þsž“º}dGÖ »jÜ� ÅÒ‘kipL#}稱œá:³ùœ6°'qxŠóyšÜ¸rÎ&� ¾Yq¤p]ÂGóä=úœÚUssVšfÃ&æ\R{»%r÷Û_ð¡å òòÖ-!ÉyÊ÷/[AyÎÑ–`´ ¤=˜uöá'>}Ñž$M[,´åPQéÍ1Ÿç<¼c*Žp8pøðíó§u$Ø@Ã{HýÄ�Es®�ì?>Ëåã!r&pé±¹bJ7�¦—>(·)ÇÞ×Õôʨ)2M$Š•ã:]Ÿ¾…#­sé¿Ädå>�͸“Óº§5yyÜ7Û™Ë×ÂÊ—(GÃ¥­+Ò¡Ÿ'û¢Öx“gÒFoο=A>ÿ0fôµOkv}�h´o Ðâ:y¬ò€mŇ,íƒ_Q‡s/&.çiáf`·�µ->´Ñ‰=ì,[Œæ†0{�M|UÔ‹%Ù…ð{v›5+ç$¶ü¤âm8oð²ñÂ_„4¡EÈár/óÝeñk•î «©oÖ4ÕW#r¢isDå>®¼–{m©ŸöFMÏKûIj<’4‡D¶›˜G’¦ZƒéÑúÎ~¢yòAîøõÖHˆÏ‰‡ÉB0³È€§O,¬!djföÎSƒ �Ç"4c×:}g1%07Ønød,Žþ��†®˜‚L¢Öåoî‘!Lm•‹8lp·>¸£·Yµ{POÓN™Ðí·Ù Ÿµ®£…-hvž­ƒ<Û±{»V>7DMŒù—W¼£¥\Su8'àÄK~§%9‹Š`m.ðkm´öéáªÀ‘{©�r˳�÷<7é&ÈþÅÓç�ðÌ0°»·:’gËywÒˆô±×CLå*ú±…eõt"s.vP¹zÎÚå‚s‹1×1�:û•ukh0ZD'gV›óq�ñ«¨ÐÚ@FíYgÏ'ïæq_µc¤6WÃh©¢1z‚»ÑZäZep tFÏ( ·c4³Ö£]à&÷�þè¿’‰åcQ®— âžoÀ3ƒzœÄ“ ö7˜MplmÁ%ô8$9N˜ûƒeè\ßàÌåÈ8²ÁZïꋯ}™Œï†¯6�'–¡9ke˜$v±®ð†{@ öQ$k¦Ü˜á_Ôál"¼@ñ/ÚIJ·o0±j£Øè¥VDa›>?ËPæ.>žl¦DöûÖ�]#áK‹ÅÊÜ8×þhöÆ› :Þ·ùÖùÀo@~°ärδӚZÎ aëyÊš¨V}�3yãݨö´=�†[ÞĤ×]gÖq4²BÄóÿ IDATOlrºZÎÇ[§%D‡ý[†qŽä Hê„uy\OâËk°bÚ‡²ÛŸ�?v±ç½¿7ðjâ^ìÌdMÏcH—:£ K5 eCˆæU àŒ^mØ7gç±­žÕ>ÌÆ� LjW�lhsŸÆ�îô-yRDÓ�˜™�ô¨Ï5Ãâ³ÓKÒ›¹±l#>õËnº�¨½í‚Üê:¯/;MBï6wbºïŒ•wxÞ›;:o9εØ:›Ìa6û‹!¿Öà–Ãrm¢¨ªRGRp£ÌcJʦǼ0gùŒk]°ÔÙúj–�µlïªaX„°õ1ÙÞ×ú‡¸±Ñ¾öÐóØwva9l{�ƒ¯ó2´!ˆ­ƒ3OORý“ÄÄA;�E×v‘ksŽÁ_±Å»Pôð8âÐÖ"—}rÔÇŒ®úaèÚ‹ê[üËëLEï‹ÎfõEÌG=Î'ÛÒ(>k ¬å‚ÁµjNœÛ…�}¾xgo;®ÑŠîl]á-·°í](öÅIõÃÉ:,£g4#&š' ožÑÁšÈry·8pm�éî¥=qmrF‹+LÜôœ}‹+Ø%<Í µGyñWWç"Dé›ð9g$Wbá*v†õz¥ƒM$s,!wÜæ!†*ËcþáñÙPH5�Í«†Öt['Y«oµ¡)qÊ»tW$áÂÀ½L¡”aÛ¶ö >ÊêÕãÜì§Gæ¶xÄ„ÓXqØ`¼Ôª`¼G`Ö#= Æ¿Ê4?‰ ëJl í“… €Öêàu¨,yŸ‹~òÆ �Öd`D‡v'ɰÈïZ4 �Öí[8Ù�­ý—¾0C$%“‹9ŠÛÝÐi"Ÿ˜VÚá0àöL€ä6·s!©œ>ÅÈV�Ž�Ö Áòœû6Ƕ÷>ÆÀ²vòئïG2Ö¸âOLo¤[˜½¹­Ý”K^rPóÊU‚Ií ˆ­�áÀcßćƒW„ø<ÕíPƒæsøÇ“}9³Ø©¸:{Ž’oú¾¸’'ÿx®­0.^r»ƒ�Q¿ ‹Ð:â~“l Ü~>_»Þ4EñEÛNL%¼"N·k®·½íß]ÿößü¤‘·ý½Å³ã?í¾@7㜠¾A¤›ºùWÍ�<úèõ©Ÿò©×—}ùÿ°þiH™¶R)ÓæÌW ³Ï­ø‹gÿò—ôõ±û*Ùô¦/?èW¨©ÕÁ7ÝÆNOž§5~E›UÀõ÷þžÓ�?nfÂÝ<=—íaftÿ)Òk} o¾ ”—o숸µ8É¢»õ7_¼=¢Oo€9‘û|–pUР£¹‰m.ÏÀµðÞšýÓgõ“áöƒIíÖîulàîBÖ«MÕ}@s 5Ыøä=‚°ç×Ca™zYj}sSe¨Ãν~õCº 8ù<¤ß¹FßøåÜP7|õqA6 ßû½oò�C¹2f1­Ù—M[^!ùCo~‹kâ׊}� É¬@þ|þ•ŒÚ¢|n$(×B€¥Ê5€lÊŠòá½á8x4'CYešX¼ 7Kätv¼mh|Ñ�z=O.Ïb¸V�öâHÉÆæ…6Ű_¸bNü¶íž®à¤©`Â&�ϧaTƒ®Yâñçü§?öÝÒŽŸN�c’ØC°xƒÚÜ ‰qÓòy—åÝó|ráï×ÄЕs¨‘*¾îÖ¢†á¾µ{·Lùx·Ö�Úè�Þä¥ZnjÆÎ�(EaGª¸Mˆ gú‚›49hüÍoc>ž�´%ÅÚÚЋæœßq3MÞ�p†$³¿‡pu×Ù™²Ñ²ç©áÔ››Òpʘ0×쵋["ˆK_E­5¼»éIÓ3üyØ3É{CƒØêŠÐ`utŽåC‡eèÀš¡%9Ö•‹‹dGGÈÏ›uŽ[Sá³/ Æ.@sb†äÜXŽœá®ÝüäFÓÁÑ^YªìzÆ0vS—{X»f»ˆ6ÐÎäe��•c�š«v{‚|i�Ùš‡«‰j#Ø5(q2šN»^¿btq±s,w8…-�¢¬£qCaÌ|ít&kMäqÞ:G�¹~ö~pý�¢“û5¸9á`‰Ls�Ûêÿà—èÝ|NgϹ¡æÐzmÆæa–{½°'¡ ° 2ÜÉb>$ÀMFg-[Œ¿€ª»DÄX¯ïpùåÑpþÿGAäµ>â´pê”Ó'´¹5û­vvc£¶ƒÉ¸vrÊqžòGšôîౌ @TXjI\væBqÞ­<yÏØX4¦È8Ûs ‰g‡¡¼c4é‹?FuO1vÛ68ƒtp_esO&í��Mc:/Íø‚†›7óÄdîœG^pŒU“¶¶­’ïøe7/¹'±µ9/œå··ú°†¹Üüö _mî‚óÈ™YÏž¼Yy›Dæòƒ#<𢩺7nÇ�À=M8¹G±ÅuíýèsH9´q®Ó'-Ö� Ö³';o¼ç0¯Ôˆ! Ê5³i€×îX4b<û»6ÜŠ3–x‘�|·Ú9ç®wÖw�ößõ9½ë›žˆ-qeÍlùÈm˸³›\-ξä´ÖSŸ0ÖÒšÙ“S˜h¬£…dNžIŠÉ<Ý'Þ�”]ï3ÖB{181µ“»»r¥ K{]+Ît:d€]½.µ™ñc˜ó><å¶œÁ7ÚÕ:XW7ëÒo\¸+‘9zz3 ­±5M�, ø%wá 7¹ÊÑu,:âÓÃ7e0*0*é7†áÏrõ©õïšárü€™´7V¸Æä&Åì›ctçÆœÇ¸ÙöYŠI+'²Žô?Îö?µû&ÂâëǰpLåZ‚…wqéWrøåÅ¿ýw¿[³î9“Óp‹Î,ðpãìA?œŒ€ýµ;óŠëÞÓO]_óú¯¾^úÒ'#Ó'i­ãçïò-]ã³kü�=úÈõ¥_òûô9S7pðωä•}ĆC ô7oÏ#ÿøÃAw…p¿à�ýŸi‰_7ŸÌ[÷›]vÖ§`ç›ü©{ÉYZƽbLGb†Èžm›m~™6Œs¹6þxY·÷®WQœcœüÌ6q¸øM,ïØãuE¼¹Æ'ÇI7²Ïióo`4ú „x@`…Óó1�yÐŽœãøò̰nx¨aÎ)áÄðQ†ç¾š¼øSu>ÿüñ@Ù\§`~Ù'|‚Âé›\Z¯-!ŒÃ†f®×ŸüÉg¯&í¯¹û`%Nä�5Ae.òëÍOÏFÌ9‡ŽÖ#ksg·´ÊAlzÆzÐL€´ïy"5cX¹7[ÃÉ^Íl+­ÜaÕ¨�×+ÜÆØk„WþÆÈ9ãHÏ“¯Ùh†ðÒjš<$dò3³êó�Ü{ƒeåÓ¢l<|Þl\ž…�+8zV?F{t¨x°uH—÷ÛxDGs¡ìônzƒ¨©†Ô7 ±j„ÛzªCÉzýE'ȱ‰8¹ç˜iýÄÉÍ<£Ó{§›ƒëÑa³�oŒÓylðGu ´*ãV?Ç®èÑr¤9¥™œ¾~U[®ãôdåjNÑוËÄïÚo�ëk‡•'$Êà�¾öEA^÷Ä-ða§WHýÍí ,(:´©sÆÔ˜`@Ü<œWÛÓï>`›±0ð’d¢ yFN£Œ]ùeå‡ ]9�¤½e€·Û0žAä0Ï7~¹Ê]Nöp�+§1îöêÏÚGG¸ò1¯Ú°Å®ôpDNrÌÑÂÆNÑÕèüäs ¡YGlµ�Ó“Ï„947¾s`ožœ§xÍi‚‘^¤WgÎ$IÓÀ%¾SˆÍY…îU�fìÄÛ_¾;3*í·ñò;§öÌ]ƒc4Çxrþ„ŠÝñ MŸ§¯ Dz:ù]ʬñ¯aGv]2[ÇÍ‚“¤÷š;çËà`7`̱·Öè,xüÄ`Ò¼tL\ãõì-L¦¬PÀaöÒðÆ(ˆ8o+P ëù$†abo¶nL�b�q r¾�‹|3»hÖh‘Ñ©ÁV[qÌG[�…Øá4èàr F “ÏrøÑáøÉ�×Ú:WÇø¹øŒ!:ýÎ!Qت,ðÄsH0�/æ‰ÅP¿íÚÃs¾H‘AçÁ©$y…E4ÁA”cÑcùbkñYø| 1Ç7v¾`³õFŸrëQµ–0Z‡s»¢”F¸–‰eÒÃ\̇Ïðkhííp�Ýõ›!öUoÀ+ºvòÇur FB'MHÎׄß�bEsÊ9‚ §×^7°óÌ"=[hÅ¡ÓÉÀz…ˆCûbkg¶Ä;Mb»è`7Ü“fì}Ö÷õròAïGÚ¤þ±/­É��±ÌÙùxÿ¡7!ÿ�ÊÇÛíè>½qÍΛä}^�ò< ‹z³HòLF7…uyçüL-ÍM×ÞçÇ‘`q ×ÐåÜdæÉ>¬‹Ïµ�ªO=`“\ìj‹=}Bck\!á×1Þ<Â5ñ•0y¨×(\÷̬yXrk!–Çð0é†�]y’¿þ=ÇŸ>okV­û´Û†–”àì~¾X ¯È9NƒlD9vôªÚ'�ûÛPùˆ\Û|<ôõ‡£yÃÒ7…"ÀauÓ'yÍh7k-úM¾ÝŽ8Ïk”ßöÔYpQóVœJ—ßAzå³ëã�ÑHåhƒÅæ•€ß÷}ßw=«_¥u˜ãÖ™ðPø•s¼ �›�¼šŽ›f¾ñ)rëÒóçsçïÒ?Wxåð<Ð\Ú®ÁÍ”þÃÿÊ7l$·hvjxåá«_ýŸèo>dv¾áÏÍ›k°Ýѯ}{ã_UžÜ¨Õ+¸t#1ÿœ‚yn9gR‰<ó1Á× ÖÉ‘NÙz-b5Æ6¿��M�Êàsó„=…ÓÛæ.áí�ÞDõ¼Ò\j³.“P;7‡«&çˆ�eÈim2„ÁòŠÎõ«Þ£y�ºŸžd£‡;�ùÏë5½QmJè5óÉ£µ5Áf}åJØÜŒU‚› 8ô&ÍKfx>îæó„ÝýzN¯*}ùÊåòåZáØwÌš|ïÿS×Ï¿û]~`½a¼B  N%ç±®q”›µ× àöªxƒÑ=ƒZüŠ_~O@´wæHAÌÖána´ÇbÇÍæÞ‚�nëfñW�qâK2Å)°µCK\¡Ù‚£z>Ó ØýŽ�?ìñ�LDF×Ñ×áØiƒwAÖº˜i�‡9´ WæÔÕ55ôÁŠu×Áh³\Ô–(¸Œ1Ewë,=AƒuÇZuq7�c0yÊÚê­5x|Ôµbڜֺö‰KFŒ¦pϾÔÕç²&�¶7pmœcë›íô7áØÒK ö¦´%ëÌ ,ú˜Ø³Î6²R cñ>ïšÎ3�S{ˆìmŽñ‡ÈxÇÌ>llYÑY>s-î‰y“ 2;ŒZ¬)&»Œ5¬Æ É×:³Þâ.ÿ%¸èœõ¢ Qms�i�&ç‡Sbº^Lø«7�7�5:˜8‚ÁÑ‹U¬¯MíO»áæNþä ö>Ó¸¤S9΄˜&sØ?¶DC-ÅÀ³†È]Õ¢+ÉœÇ4å;qO†ðÆVÖÍåõR͹‹ª¡õ,£skòL^�‹ÑNvl‰óŽ^¼5h[c„L'ç=4/tÁ9¼É#“?�]Ua"®_7Ø5ñæ˜dws›�Z¦N`Íïújo Œ,‹·Y‡º]Ëè%´vóžuÈéÄò^¬5 ÆœÁ¦c©Ð±Â!Pµ$ó�=¤&&ù±tj’?Ëh2Ððø"[kýˈGµ�[jÏÆZµ\õ›ˆƒT³³ó�ׇ<ãˆZ"ª}¼ëOŽÛ¸t•X=='_Óšwtƒk “Æù]ËÒ‘6¿M@0šÉ.¸-9Æ›¼È¬uè�oôV�ë5F¦\ªAkS6hæh¦†Æ3WSæ`Î@ì4;Z³ê°ëÔy�›$q +2Œ™»Ý¹ðÉ*Ãé[yd]kΛ=˜Ç"“í�sž‡%vªljÊÕ‰,ù¸ù‰µÕ“æQÌ´×7—éðë�ï~çõä{ŸÜ76Ñ¡a]'1¯üÌÏüõºÇ« ^p=¬›q½Qø!½ÚêwëŸ*<ü0_/ó@#ìè³M~•÷Çâ__ßô�ùºwïÙ ÊÄÑ_ôiÿ²—½äzõgüú� )7ò|cL÷c´¶Ghç:òß ä› 0cçã&qëZ3¯œnV|ç¹$Ž=nCLfÖuÈõ›­`÷�Ä�yúÓX‰1‡ù-ŒÑç�h¢!`�lz O¾P}ôX¶ðkãuZè:œ b|zŸ~ÐÓb÷MDÁ¦ ·I!§mLLæoîbÇ^έMúu³5:‡¬®qnÄæ|a?0ÊÑ��Çüx4>8X¹WÖ¢ëUÿ0ä£>ê#ZçÂ"ƒ?‚Œn׳ûùoþíÛô7ùû“ùÃüp²*°d3ÏG¢äŸgúÐâz‡ÜÚÈíqFM*B~¨{Þ ·Á«}X:´ð{ �¸mÇyÁÚ­Sy£Ïh �ÁËçZ jt®Eø¹&Ö{[9xô•�ÝSWJ…¯œär2'e�k%ü�e¦sƲ&d®�t”ÎÁ ¥�$g1¦ÉeH0†,š‰k¼9’wRËB—гBV’tõi6ï\piD»«‘ ¸-P˜Ã‡Á€v„!‰™e'Üþ lµ�9²„6tç^ŽbÊniw`l>',�›8v0M•z@ŒE±Øª‘�;,ClɃÏsŽõ1ÄÂPJÒè\1hôº^×tD?aÖ°�Në8 ‘„ô'üƒð¤ªÒ…¤’-‹æêM„„�95goI†§š�D‡t�]ûѸíéyˆäm/§©‡¬s(ûl�ç®Ü®Áqc¬V~Ïùc ¹&ÈKæV {ó¼Øv½êáAo� [âÑ=o�kl¢z ŠpFsš9ƉݰcØ;ÎõÈt.ˆòNa+—×:,½Š1Î}XiJ•¿ø&\‹M‘ôŠ‘Çzål½«¥¦RÞˆ�ƒÇÞZ¶×áÓÒyÇvö\Η¢µ6¤8ˆß1¢} vF‡–ÍY~ö¹8 ²$áñ€x-s�•ÄM¿Qܸ"ˈÕIbÛ'Cû¸âA†gk™è­M5Rué¹£ËðKˆ½ª.!°ê S&H£�ÂâœW,ü䙪¬¬¾‰ÊÔ…­~â¤Íœ€è[E³ÄÞ¸òÆÊPx Ðᦚ.U j}š‡·‡i†£Ž1E£ µlßÉÍfíáú´òŒÔãúÈL;®18À¯¥Ç·öåÛ²(.cll]÷™7Æ�]˜„ÞäWtµÇ‹&>a’|¸'~õµ&`éW„³.öÎ\ h×ýžùU¢Ä'/Ï×)Úº,JqGÎIVNäEÏ$¯†Ú¡7ÁÌS3¢17<Á‘Ÿk-DÆÔ7à¥d{1²CŽº†ê&TÍ!šcíÊäžë}‘€�Yê( ßðém�­ÝVò¨”Ф&Ÿ‹%ŠÈÛë1j6/ñÕÚ~ÀÛÚokålÁÊ‹øì¸eâ\ƒ¿£‡ë\Ë´¶`w˜apÁò9Ç 0_kɆÚYízm_I@ãš¡*#:±G®‰îcQ©·ñ­ÍçØ³¯¸²t.žÜ¬}¾åDw17ßÊÁ7 x�u`飩<åöl²‰vð{›F™ˆþö:rÅy‘™� 3ÚÇeS oÂ[oh4hiS|oâ˜*!aUNn€ðh~�… nÞk[¯#fÆÒ«=VöêšÜ?ÿóï¹¾ì+¾òúÑÿ‘ëÝïz·ürÌ/*$<¢‹Ÿÿ¯QbÝÚ™›yÏ>ó¬ë„°X8¼6;½i}þºp®¹ü�8“GîÁ1†Ñâë…žŽ‘í!¾Û´1~ˆÉÏ2Aúü” ÷ôo—ŽÓŽ8ýAG0 ‚lúÎø³¦Ea›Wl*o9eõÚ1£37TwM`ï›Æ\í Ö´ò»Ö&Kpú¥³U’&î¾rÇçS¼ô}9×&µ�}^i ;ÉCfjï‰f‘|ÿÊW^ùQ/[ç‘f5´2ÊÑÚ(�W“~çw~—ž*VÿTFNf0Ñ%PÒ¬æ;›zÂ!oŸÙž½òÁ�7^jjÿ óد %ãäl0ð°ÏµˆEÃÆ,IØó3,k.HY'žD<¹f™; Í|¬ÔYþØâ°FÓ•¼ªÔ6fŽ`yt­åØâÍ< o¬Š¡ùÆî:d8ó‡),¬£W‹ql¿½Û?ØÖzª�Í9ÆI]çÈç?0äÃNžËz»yE2=ipfð¬kÒbržÌf¨QÚö\y™ƒ8È&4d�.G6Ö6QE¾vÊA-Ä8:&Û{ë™lâ@ÃqmØV;ÅÝ^¥ŽD,uävì�xøy˜d¡gkò‚S é~44(†aOé+ûÑ8~L5·ïãKŒ±[a[ÇâÕ¹n»g®Éÿí8l6ý@• ïÑú ·›m#ç¤ vji>÷(k�úl!nz}Ó§ùâÆ˜‰wìMaÅÕ:«¯¶³¯[Ìâ>sÛxšKsÏÃáÅèíº ÉÎZÓG;µ÷7.«YiZWµ�ºÁدx§³vÓ4÷¼C¹F~•¬¼79#RÀBø§’^¶¬ƒe-³X´8×!» ÌО¼‚Ú”ë¿�””s¸,+Ox°£™ò]€÷{ݸ�¦Aï|pܼòÄzÊž^_û8ñPjí°Ä͵?Æžë5$p¹¦0î3ds-âÉ]«Î‘a¸ûNÜæ"u$ozœ,�o+;ßöw8äÄßG„ÑϲÌLð¹Ô¾º�-^öó&58”pbJâ~;ùÁÁE÷Ì�›½ ²nxM{A° ?Ù¬Á΢ÉãD6¸�ìÉ'Ž„¥»’ îÝÎEœ}=x»¾¡^L‡è²‘Ï7eüê,tÍ+Lâ^M½abéâj�®O<Ìøü-8ÿÊ…æÿëM? ÿ˜Ê?k8†ì@óH¼ ï›þÒÿ|ý†WÿF½ÂŠ¿Ç7^½ïc^ñrÿ�@3(ö«,àã»wï™ë[ÿ·o¿~îçÞ‘ªð–¡: 2aåϯþUŸ|=ª4âÿê+"žÇüC†s´flô…·—¾ôÅ×c�=æÜ¾á§y›<ªÈ b†±-4Íút-»!ë`=‚snœ[1aÕšá')çÚ>ö/Ћeæ�¡åh˜õ²•.ú£vœj�§¹:Ë`ßêå ´ùö€„ÑŒcB— Nô µk鯳¦ŽÖ’&à“Å�Äî8ç°)¸Ô¡ëAð²ÓWUä¯íR[®¯ Ö¯Ššº>øÜ3×kÿèÿx=þø‹  „Gíð®!»w½ë®üÁ|4´>ÿé 8†‡ÉëÎÃÁ6Î+£½Èù˜þ9�žèÛz:È…a/AĦn6e"$Ú=³�±Vn2Ë|?ÿ ‚õ�‰ë·Ï¥B–]°±Nö|¬¯@� 8Gj5Ïif­rœ£}&)¾VK.8œs‚²�9W5,ƒÝÑ0zdåähmÌ©�Ð8ËæY€hJ/Œ2 ‘nP�Þø:8 &G˜Ç¤`VÍW9ûq#ûZA�ú¬/ñpœ¨Ízs݃º…A9‘ãXµ±':ç#� [T«F/Îüé“Ï™p7å±—#œpG§zÄ��œ<´$Æcf�ý1@[fpÑçD@jæÎ6,¶ò¢¥ë'ä•°R;¹£Y–‚î®M£}1Î…”»LЮ{¹ëÃ’wŸúº»™�MùáÆ™Â8'†èì%ø°X;©&×J)"÷/¡Îä£åmô7À IDAT.z´C¿kCΉJÛKÛÁ¬ÀY³¿ƒíl®0af”¿:0Ÿkb²R¼ÁOʱm‘eAþ1už­'סUs§¦A®@"v ËŠcO=Xw_ˆ –Ù¬ô¹QØxpW$¾q›Oûæˆ'¡äl¾Ú™ïb‡î«\¶÷"7Í–ásl6²°°¿k¹×H?è�bçEipÝÕÑ€Jbt(/j*Æ�®Æh†Ûƒàsh›³#\ëÖÇ„$ã â¤h ṆÚ{‘ØÍAl-ÔŒZ¼7¸u‚�„`wœˆîe·$ùd7Góh†Ê8rà×øX3[%Xâò>Þøµ™‘‰9|âí#ûª²Kîa¨>¹®#Ÿíƒ±0xæÍÁîs‰3„ÇXlÂÙï:&ÇÔ}òqÔ;Eeú:BÈ&qéÑ’Ît:ëê'^N ²„ÑN¦Œô¾ýˆ_*”Ïk@ ›Æbzƒ³ò,~cÃiýJWHVž�3UOË&ζrjNÝ1àã‘nÀ«¡É¶crb…,š•@Œƒu.鬶ÎB³r�/¾c=ÁšQ ž8ù8Î!³%«ý>W%]vÔFŠ€Ëµóc¿0­ <æ¶ )›ü/=Â>s"eäDs¸ÀÙoº^/μrGŒûzJ> È2ç8õ@Ÿ‰s0ˆú´}[F_ž�pv/l*"$c_„›¿×ÆŠÔX ·q‹“Ì‘¡™EG×An_ÙÏ^»{–^ø?I–¦´n˜8eç|;¥f¯�‰¯× ¶6köá/5y` ÒZ&§Ï¹Í\““sß~ÜÐë®­Ï‘ËgÎes]ˆ—,Ꭷž:˜Â+<~˜‹`¢ó¦ ‘š¯º·c‚YzLËÇüùÉ 1ÉA¸žKø o>±ç~:vrÔF<Ÿ»üÐÚ2±Ðð^æw\ìfæ‡[ÅõÕ•‰Ó�;}½¾íÛþúõSoûkµÃNùÁé]™<ó*´—¾ä‰ë¾þõ×—ÙWø?ã2f8ú“j­Árï-oý‘ë;¿ã;ôkÀôêºþæßü.ýªîùkÀ‰–œ¡'žxñõiÿñ¯s_’G×ÿ–žˆÄeaMúBÝüû˜�yEê�qýð€ñS„‹‘ɶÁ™þ¥ß]û¹f<çc'uϦß&œí£×¤lZ-úSf$9Ç¢,!x3š‚�y™ïø�íÔ@méwɼ§Ùù/¹í%×fl¹¡¶¸ÑUmg‚±¡…¥gnV&õåz§_ÅêQ]éoȰ­˜ô@¯¾û¿Á¡ÿèƒn®òÃdù&2ëu³<�dåWØ?íÓ^­ëè×ø¦2ÉɳÉ@R=ÎT€ãZû§ßÿC×3ÏÞóóÆ_sJPžûÀs okbÖùŒéYÜ~$”ZìÖäÎõV „<è �ak_�ìg4¾[:À–)yÇ®)ZôMŠxÁ0r�°€´Lô!pD�ö‰>"¼„‰ÁšÀiɃu<Þ,|}F˜ðØÍ„KvÅ[ж�I^ð†;GlcÐלæÄÀ“ä¹NñEHažEŒ÷©qÍNcJ“¸£Ýއ?¹šÕÉy„Æ6´oL®�`íÈR­ +çI–øšj�áË™ìº?lеá/o›óà·ƒùš’ =R+ââôMQL¹VЊ·çË($Ù8ê1ܬ�Æä39»÷K|ƒS¡ù…ßúÂÑŒÑÖ£©Qæ[¼ñŶ¢™Ýו›xlp(Ù`�m'(˜šj» ÔœMç³><äéÇÁv¢ØEcÜìÌ·ûäºäé تcÌöYÃˆÍ ÑrÙ+Ün÷j€æ\ý!`%bÂÕ2¯&"á+Ôþ‘K’¶öõü?oåNlðí#ZF–`ø’$öá6€µê0sâv|5W#4'ŽØ<ð+»ë6m‚#€ïIsÝÞà�7þÔµÎj.bȇ}x�‰Qõ3ÞÁÎMÕàÊn�þÞ<¯^!Ð× ”(œ%OBÄ̬¥M6 N®æAÉöãà]ŒqĨ#£ç ˆ÷J¸ $?ì]¸L`ÏÒç&óÝoNF‰{Ü¿zzÄ7Sz" Îçt½÷}ï½þÐzíõŽw¼+vàŽÐbÖì‰CÏO<~}Ák>çúßþm×'ýòOÑ« ó�AŒIa,=,ßy²G¯¢úª×}•ÿ¹:xuß�ÿÄ�]ïü¹ÉŸÈ¯½zøá¯/üÂß+!ûãóXë­}Zzÿ_¾Þ<Ö¶.«îÛõµÕaCAQU˜&˜Þe�˜€±eÑDNÙ‰éLH„hÊ@È("² b;Ž ¢0]AAQ�Á¶(ZAd�„Mˆ±ˆ™Þ]Tß¾�/ã7Æk­sßGÖ}g¯µæsÌ1çÞç¾s÷=÷^t�vþxÈÇÿ…�3Ž?þAÎ>—ø¾³»ï²ƒŸYI]¿—Z÷›�N3çŒûÎ.b±�;çžZ”ÇŸ“´WŒ5)&ù1An¯´Œ&â«�õiï¾sâgçøjèçJ|á ûxF/s�Sß´!x‘/~Ö£Ÿ×¥™ºÚ߬s^ÛAhnG©¯‰áæë“yôz¿xîõ¤Çïû€œî“b@s½°ðM:nJÃÃ=|=í)O¿¾ìù_z=í©O±ß)8$…8¥V˜:èÑ›õãò/{ùËEþ o8úÇ‘‰%ÛPÏîÓ2ºdʹm&0ûv ³ˆç)½lGãÖ‘f£ašn»öîƒÙmÖô¼ƒ:�8LÇ7\_³ hZ J¾¬Ë�ƒyžÀ•Q>v¹naö`Ò#zc³†ÉoØ@›;�#¤Ó¼®ô×¶°�Ë|Ô”ÔÆ‚Û1!eßë3úÀl> wܶ…Á#:ÍÖ.ûåÝä dÀ`ÜïÌ<ù³¯ŵÀ![ušGÆÎÖÀ¹Èó%\OìËlCPîT@4F…VUÓPx?×µr¯ôï\Ú1ë±1Ÿ>àȯE”*1%0©9f5vû¹U\·u6¶£:të>ö¹ ä–ï€g-¤>çœçÆG‘ cÒÞê¯Mjxú‘Þa�=«ÍMvÆÅæ%M ý«6ž÷ѯ£u‡Ë9©S£š èZöùà†Gb‹Ìz4Øê$¬‡-å×Ê/Òk̔ٸmC~ÿd�Ö¼®÷XEe»‚g›ijqÑÅM7~ÈãâD¡J;=Òð´Xl¸mîU$øãm±lðjj(39� ÿ�A^Ñ)†¨Û±m‡&ƒOìÔ¤PQ91“`Ï1û[-9ù­Éý{xí ëjò¬„ÎYÌl—öÅ'ÖòlKÝÉaŒ¤bkþ•œ¬%j¼MuK1Ö;ù�ñ”ì²}@…F ËîvO‚;€¥©xc6¬5ºnåY•Ûö¥f×?u�Î9&¯û�FâO õa×0ï¬gš:íLœÕäÖD˜ã[SZ6çiü>rô ýˆnÉnäY¯YoþÂqåœïœ!–vfk�µpîônV¥„5ÐÂË#ƒ— ) pØ<Ø|ÁšM{�YvmÒÉ–êÅ:DòÑ'|˜ÜWç $ýBC÷Z�oø€?¶‰äcŽ™‹]ô.v ¾ÿ½^§?’b7Î4¡š|OÒïä{øz¿÷{ïë_õ¿YÇoÿÎïøMûÝè#�Mü˜éüï?t½æ_£4òŠÜÌCÞý±ŸœïE‚>$¶7ÚæÆÏûüé÷Ò�ÀG´{üºÇb�vhèƒk[ë}�>¨›CùQå›AùK€2Èsj¦Ì~sŠõ:×â¾ëÐvxQßÌ�=¦w2¢®.’.Ç£ëð"Æóz�™ç’ï€±ÕØ$=Ï1çšñšìÀŽ“¾—Éãú†jóÈ7ÚzŽº7_ÈoŽ9_‡IÀöÎ=–ö›š”sRØ~Dºgw}Îëwý=t=õ)O¾þéwü“ë%/úÚë_ø"ß|ðAþ(ÍþÑ`ÿh­xǪw¢ìéwH>¢€ßöm/ºÞý9ÏÊ F%mžÕÎÚ–c+ûÍÿðÊë•¿ù â݆©�w2¨•‡[©X÷ÃvC�yƒÏÏx\dŸŽú™sí5�çŸkˆëdðš¢NŒz°ä"ð¬µÌ1³åyÖo®×ïëf(æx$²±ÈñŸzš8žà\‘ �"Žõ¾å„Œ…œØæáZ'Žú{íå9ÓënB„[ÛÎ#cûà‹mëâ|R�rœvÖü(o0‘7¹Ã›ßÿɺcjUÊôÔ3Œqõ…‹Î0NöXÓ·¬AÛïÄKT‡µjSµŸ¹¬C\\S»?GžµDÛÎÝ0Fs*�_|¾§í­Fðp乨kè¶Ï­w ÆOf>Çž#©—em!tîåŠÌ4ïPç|Ú§ f&ú¡ÏÚK=çÿ{΀Ÿ¢õÏ16j}[X­šá%†k¿¹ ñÞ¸@�Äm¯ªÔ¢¬wk†G#úgÃÞ,ÙÃÝñt¤vb°rå|¥Óìý„®rë¯øÆÍLL]‘=ú­†µ€â.v™NÃhTèh!€™#_ûÎM`š‹>tØ®ýíù#QbÌ��m>HS¨çÚ–‘ø²¶OáŽÏŒ2Nkçdnä"Nöô݇câªkÍÓ§è¼&ÁIÄq vÍéµý€‡màp¹†‰�w_ÏÖ²Å]=ð×Õ\=¹hr¬û8ÉM‹l èÅFN–©Xs¸ÞéQì8ë�¯�pÌ(7�ò÷~}òdMq^êý5 ³ñ3ƒÙ"…c¬2æÇ$Ìâ¦Ç1xù}âkœt¼6'4M8éwîá&vNÞÐä‚Xváh1­Â_¬Œ±0²zíP­9 lœ´]ZfѾB7 ,쉄CzMÅlîýdKcß!Ç…1ý_š\»Ø6Ø)-NºZ'xÞ[C`>Â1¼ÅÛnZ+�ΩŒ¹œ{ó¸fÁÍ1=1vCÌ`íŠõ\ßè§~xGùŠKçìoz÷ŒM¤:¾ë¶ =Ú.—á³9jÂO^Æx³/ž�¼$“>îžù:¦Þ‚ušÉ½1ûÅ\î�“ øê�×êhõ6�Aœ€Æ4OøÂŸbtŽ$B_†æY2õÜ’ N»È��‡5ws>*m"d˜€%uhÒÞÜnp ,—mˆ6! fdLÐ�1_Œ°áá]C,¸&³‡†ýš½o‡Q=Øvcf“ZÁ¤0g®Ú±Dk¡<é߬!Ò¨ÞžçXq¬•ÝæhÜ–†£ÁûüD[ýA¡¯3×çx8ˆˆnfâR='¶ÄÔOúêÃGø¹òÝ_ê­šj0“�ûÚmŽê Fçm�§¸èÛ¾ òtjK‡zÄ ¯"*+Üp®†i麦v0øšßû!È/^x»~Òuï^~¬ÒŽ;‡3¿]!Y\p8Í}“OyÖ;tÐ]r“tªâ �×£Ÿ_ÊõãÿòG¯o}ñwè�No)Y-ÁȾãAÝXyö³Ÿy=ç9êzåo¿òz‹~¯Ÿ‡$¬³¿tÅõÚ×¾þzÑ‹¾Ù?©À ÿ_ï=p}Ë‹_|½ùÍÉÝëÊó$…óiO{êõŽïôÎ4Ù¯gîñX-Rü79iŸ‡ìïõï&wb°/¨6†qàa‡-±cR.P¹‰_¿¡RyúEÛÃ?j¢æh2gÂ(Šó”T'\ŒsîyŠ-ÿ$’~9Âç·~þ•XÇ›ž:ðWCr&j˜'.¹ëoÖÌ$q=l�spL£Á.qÑ÷$ŲëóFXðK/ûcp�< Î�~qåã�½åzá ¿ñú�ÞëÝ®§ëZøO>⃯oü†ªo×5õ ~¥ß'«$äÍxH7«ßþÖ·^/}ù·]ïþ§ží…+Åä^{Õ03u¾ýÞ½ë¯øþëAÝHäF#ÿý¤§ÇóK:iøÔVl´A³6×Ôt¶àïà�ý2&4‘sdÖè²é™ žE—…õN,la„�±kçs�•Ps³ÂöÀö�.~±Z7²ñ™-.1t¸¯³¡¾JN­qÔ†Öùg²¬†c'g¾Rì04ÝÌ­‘9¦ƒF†hǃÝÚ�«¾ j ôžfLC°wâ$�u–Ñ\�ƇòfïúÍÏ~0‡/¸ÖÕ:àœx§š8­W:2+bõ„]Ff÷W6¿[µÀ¥˜AšPðh'gÞcËpLCÖì4ɵl£Áÿo‰æì®Å £C£‡xûV�ô„çP˜7ø¸¡ Ar†ÉÞôAMñú€­ŒÆÙ:Ø�º¯¬GÖk:ë5ì¬Á_Ó…ÌõkiíÎ)Xµ¤J2dÏÎ:Ä›�h‚£}1Ž6}l&ŒÓ¨öÿ™cW̲™`Zó²LÍÔÏÃw š`5…¢ ò^6æŽ&/vsh®¯æšÂ®�o—hŠ3á¼ÃDZ°4¿õ¸ÑfÛž‰ƒ£Ø tt=²ž¹ ê|ù¹í&Vý;{c>HŠse4ÞX׈†pœý©SèP'�ÁѶñ¡Ájm0À®ÉѵIí"ÖñƒAsêÒ‘½ú„EX²f-œ¿hZ„2Êêž&uÖ%X88�ß™¢ut°ïë¾óP{47TÆv bt1[‡l �¶)Øê•Î7¾ÚŸðrÔçF�žæœð0©1,®j�ÏqÞïó¹a²¦C¿K;8Q}~�èÚ¨‹�%îHbÎ㆚›GêY žm¸&^6¯æ:òõ´�3á«Cë®°pÞÉ·Dõ¼SWGßh±kt¦Mä˼o–BŸø‚[`ìë|)kÎÃ|÷·ðûfâóhΓŸ¶`ßMÉ:½&’=ƒþduZ·}mss;ž6Ö¬ôÀÏñÚI|ti=qà2ÀäQIg^öµBŸØå"£ŒS»¯L£&u%L$×í™[nm›û\í~ "±Ä»'XL=yÑV¦É Ÿpä\lgá=o‡8Sù^÷1¯Gdzm�–SnÍþÇ»xù<œ½ƒ ík�óØ~…/ x§œK«Ž•wʪ¸ç|y£õÜà£>§’=/‚ j`rïôššݤâ{^’-i†Y8tÓ·¼ðú¾ïÿáë­o››y”eklúGyäúäOú$ý5á7_¯ú½Wůt\g�4s3ôGü§®7¾ñ�×c¾éG=rp#C¿îU¯úíë7~ý7u3Gšô/çÛËpéøš×¾Ny~W˜{>/÷Þ®w` vR¹pçoniyúÓŸ¦¿d¬wªÆvÓïB%µO¯Ç¶òË ïÀÔ_~õs75‚÷ù9æ\wá4äÒbM³†²£yœ¤FùÝkfå‹.8 䱪u„uL¬åYcâý¹„¸\gæ7†ŽðE<¿ð=õX¯„5·5&4©Å¿zŒý�ÓzxžÛ¼ü[= §œüóÞh¯m´éÑïí{ÜþÇ®oøº]æß'7úd{衯ÿ°º^ü­/¹æù¢wÂû$ÝÔ-Rÿ±›w|‡gèwLþ³ë=ßý9ú1ây>·7Âr#�ÌÄEˬ‹‘ì_ýÕß¼¾û{^¡›¼úó7ºV›sBlþß ÇÌ�lä0ås~“N+Õh‹—9ïkx¼ \>\aáèkƒ½B–†#Üapñœ(ìÄj‹|ø÷ÿ=�CÍY e"Nöø{.ksx•åÄ q%<ŒÄ²¡ßɵ×àRq3°Ïh®Äb‹;š‚âÈTlq8ÊT>àz_œ�ñ,Í,�ÑsQM¶q Ÿ¿è½Ÿsó�«àbAûêꌶ}=QË®'½#õTêy²côÈ7WǪ ý=wÔ`Ï>8fÿh,Žœ�\-JF>?œØ›–ˆrI]Êœ8¯�Í®ËJ,Äq®S)*�pÝ\;¦±­òN»¨Ê[kºt:ÎV8nFpµË©¾A)í®ÍEíþ§Þêüä˜\'ËmZÛHÃ.ºgs Mžñ™'kŸc‡o¢uNB{sÌ5SûÛÈÆÑ§^R„àŸŒg�‘ ß�æÉvH·¿Ü¸YG™¸æÓ_'™øN~ÍIŠ# 1 ³`g Æú´^¼åŸ Dç!”>|�U�-¡¾mHÛ“’ŽÇ½2™Ä´9‰Î±û‘眩œ)¥„šØÎ$FÕ˜>¶Ÿ­*sDK4h±óÆ¿ö£±ç×F/60ck=¢07ô¡[”%ßmpöÏ çñH¶Ì •þ«Vr¦®�#$½ÀŸ,·1Bûßôd…šÑ\ŽZõ…¨›)É…~`9¦)s›�’Ž~Fš›�Ír…�þY±Û'�ö�n(´×¿=DØ4¶þ»'ò,L²±¸Í ¹¹ªa æc=‘g^¬íóÆçÉ6ß Ðš‘£—Æ.<¦wÑ+,_„êØ¯C4x±HñBáß¹HmÎ?ê&?t¶/æ ÕÒb)\ ÎF€A0%6¢¢!| ;±å†p4UøÌ‹þI¸ù‰Çtô‡û–ÉèéW9wòÁS-Ë�q�ä2²Ž4«O–88‘[�¶k>‚Î>¸mãCƒ—¡qÍSæ(Qb8j_ûî�î†'_¹žö`XÜÇæ¨Ö�aVSgkÀJÌ<îP®ÄÙ}ŒfÜ7yV° vhÕ–/NJ™ëµ;ˆoÝ„¦ûɶƒ ôv÷i ¹7Ú™3µcn9-þnüÝýHp6àBÇÖ–zÌ5þòæ< �ò¨æ¬ûŸÃy]¥ÇÄ ãšX§mÿ©#xøÎÑÜc:vÁ›ë}ç0ä ”óÞ î©]·ç×çiÎq§_)U¦0@¿™A†?þ€ƒ)³ñ„<çˆ�›S~Ñ‹]Äë|7F¶ö,Y˼ä8¿¥¬°�µ·véPí›ý ›ü¬wìá0ºDjÞj`?^æšòùОžfУÀ#²vrß®s’jÅ—K3ÃvÖäWâ|QhG“Xsz“¡F렘Žòßö:xÎ ¼[#ÏX8wú¬qýýð×ýð¿Ô;xû‚ŽTë 7m1ñã?Nï�zÛõU/øzÝÜ{óqã@¸÷ô£¿¿ôË¿z=ÿþÛÎ�çž)ÜTyT¿Ÿí%/ÿNý1ýh¯>ü¹Iš›ˆßý½?¸ìtïíú‘å×[ úWY-ofÎ ?ú›ß�œZíâ`ržw]§¿l½æðEnö!v8…høaž½�ô5P÷+™å©-¡ŽÎïïŒë¼†œw‘Ð ®ÿ®1gÍ´òÈ\{—�Ø9ò<šèÅY_SY² Ó¡ßqìkÓìí�Úéö\ÃU�ª²–^‡Q‡¾íìv¾‹§×v_þeÿú¨�ü�œËU/7º>øÏ¼Ïõ-ßòÍ×{¿×û_ïôNϼ~äÉú±ßG¯¿ñ_}Š~ì÷ë¯÷|�ÜüsŽÕC§ô9¢Ån3³ÌÞÇ}½IïJý‡ÿèkÄùÈõ$½ÄÜ7Æz çu§eÀÝÒ¨ÛØéƒ—2ö÷ucáZ7¬¸™ ¾9ŸÞI¡ü¶#Vc&/°ûSty IDATc šŒài¡í†n„VJp 'C5iQüÊ«n�œÐ�{t”»ß•£…1ÞãåVìÉ“¸ÄÀŠ_rƒ¸õÌç1píæAŽáNÐYbw°Mc5oL;ŽE�å˜=aˆÔÖ©3çdgaÕ|9Ñ<nt¶í‹Æö»öû‚àÎé[±nÜÂʸ.¥Éz�ÔDÝñ-¾‰k£ÁøBsÂO<êÍ×â(oDrP3dç›;nòŸº,kaoqÛ,;@�ê&].Vb&ßLg]Ž‘ÙdÈY›š¸”ák¥�%~LØWOd\ÚdfÿèµáÐU,öö·éµ0oû¤£1ÕãýŠr"×ùHLñ&ñ�>æ»ö¤àz™GlŒ­¡¹ wŸ+vb»� |ú[ºS'ƒc]—"îäÍ»@8G�p²ÄXàvÀóGúصÊ2-˜é a…õ¹n¿£á¸n@•$'ÆgŒ ªa7Âí²ñhÌ*të¯'XµÉï°á [ '//Ôz^0gÍP²äHþÆ€èð† Zuƒí¸©M›Ó fúPÎC°¬g_ÒéE*Tœjá¼o}£yõ,�íHónÌ ð$~œMºxˆÖ½7$¹³µµg`µvs]MNj][ôÖèL|ú�¯ý&GœA³0Á9� ^Y—ŽØÆjò}mÆWMžU{F„¡Ë–u¸1 .:‰sOD´ê›sšÒ ón-ˆïÄÛËar‰Ì:F¨ûUÁhíúÙ)DÿµYG®¥áÂ7‘õŽ¥ŒFdç/6FÚ¹Þº¹ˆÝz½s­[ÿò ]$'f:¹¯�¤64?F9%:�£T6þ` ùßvïñëüÒ/Ñ»æ¾ùú¸�ýsú�{¹f¨z=rþÝ]¼ï¡wV=ôÀC×OýëŸÔ»¤~ðúôOûkz·ÝÃÉ,�ÄüþïÿÁõyÏû"¿¶¡<ÿÑVÍøxð×YïéÆßýð\õ?ÿäëc>æ#®‡ô×^“SÚô»Ö^ùÛ¿§wz½È7Kxgæƒú]€¿ø‹¿|ýÙç~ Ê–:Dw3x¾ò£¡¼Ã­ï 5nºBÏr.ZÎy=zÎóuXýÿ‘6¼ËŒX;¼ M÷h´çy¶¡„ •€u èÍ·Ö”Þ7è<�b›xO K­ªOŒöd¶k�œß ¹täºÍtY›p‡ÊƦ—žj¦¸¨Ý=5Œ«…k»ŸÏ•EÿòÅ�v½ jŽtc ü��/øü/¼þ³Oþ‹×£Ü„£å2Ìqù/RмÏõ²—|�¯jâ†ñSžòèõäGù‘l ÓLlרÝ—wL<'~V±ú~áç”3_�›sÙkÄZøÿ;âêÃþ<÷ÁK:FÎgփݜEZ>e漚€ÿÑÿÁ¬}pôP¸"B»A“ŸÇ<�q34[sv®…°›C~a¶vùô¢E,% NX'§ãf½ãñm>dä ±ÛÉÁ9“»}g†ŽIW×Ò„}Þ €cF΋ëU_ø±òÔ”ø~^Œ.ëèÏ ]l�ïžÙ’ìhÏnë°fÁl=ÄÁ©áœ®.93&û`±ÕeðVŒiŸT^“g)2ˆøæeÛ`XçÓ‡É�Þò5ñ±MâÑS§V–ä=NñW¤NÒÀ3.¶œ'ÖÔÛ8ö¹žc9íø’’çùÀòá!Ž\3ú|3Eûu×¶Gbµ�ñ°î™×øè3ð¹vÏäHéãŽàµùcЉ2X­tfðÊæÈÃ^C{×}ÂeéÖ˜sã8üœÉ±X/Mê¹ fCýÚHˆ£#È~×Ôâðo~`¶k^¯sY~Óìk |ÊeL{�’\Û0d,¼¶‘Ë1ÎCOB„®hÜ8wq¨ªVtïb€œGk¸¶nCuhãÙëÃ=Q,>ôNÊ_㙋c}êv`Û‘²@3¯:ðu‡Oíù2N¾P9t`"ºzÐÆhí쪥uÙ¬‚“�¨c� !Ú°fØÎ>­Æ¨ÉX¶·=mèÒMÈ1ðsŸÊ¯�ˆÕÞ6%K§µ£àÆç�y ?×…e5º¸°exåºÃ‡•­?Åô €#™N±ˆp3u‚w^.ÖG ²O.fkj/W‘æ*eùJ\^Ùk*¤s/‚ûóúF̽´ôÚåx#u7Û‘ÓY—1Øc~Ç‚#‘ŽôJÓ–çM…âí×…¾r‚×ci û\Ô¹h ·VË7qDX‹™¼^Ú-ΤÎcv ¼í—Mx48`kŒ¦tBò¸t6ü3·‚"ÃP§¦ôo‹Zx‡ÄŽ�•gÈg�…�÷àmÍ•ÈùD‘¼ ë¹Ì9à ‰©©äNJó™ÂÚŒ…�ù0kÊtž@áäaÊ$Ö±zdµ èó¢À|Á4EÌ$t ÇbÌí#sb¦Žˆ Zkô, ¢dÝ›rrÉ�sÀ‚Â[Dø‰�LL�†à`tÎŽcë~Ö”‰éš½†ìΗÝ:Ö–º’+–¿¾HO@Þ�!Ö¥ŒÔÆ»¨;ú�G8>a§_<·à­Þä _8Cš:¹Á¬~Ûf†ñ�ÒCѺ2�%hMÍ4–ÜL$Ò†ZK5ïpXÅm½èp]bÜQ©‰di2íƒRŽö\µ¶±¬¸23/£8ª7øžrva¹o싊ÅÔ�Ú'—õû&âûË‘+çÓùÃhÈꑜ ¡ ½F$$wæW~¤Ä¯Ù çwøLð®g�òƒG+AüÑ‹žÿIíüÜÁ7)¤cúâ]»M­ƒœ3R/{zšG}™§×ˈ²¨ uÖ0<þø×ñ\?óÿ?úcùC„UýdtVs•ó¡ë+_ð•×Oüäÿu½þ oôïMã ë/ý;Ï¿^ýªßsl¼ çE—9¤•~¨[V×ý_xýú¯ÿ–ÿêêk_÷†ë7~ó·®ïüî¼>ó3?[Ÿ‡ôëÐÇô;Ù8ŸÿÇ�ÿ„x¤*rÄ£¥Ö©Äô¶ñ—yÖ�c÷šH½ kUÁûhžè2jøÝ{waÇøuÄêŒ>ÏpwXcB¼öa‡,[øÖÖ}`×3a½ÃäºÇZ$ØÉ(\vý#Î<†±¾×müû¹Y{à‰ qâL'óòĬ},«Ùǵu,ƒAØ9·¬IX þZC×½ü/ÿ‹¿®sÿ__OyrnäõÃà¼Ãÿ n?ú¨þÒ¯þÂïŸx‡§]ïø'ßaßü Ž ºžXY<à;%¾æ5¯»¾ü+þ?�‹N0ƒ’Ÿ#ô‹¡7=ÙÓÞØ×%ßHÊ76m÷y›^XÉaÕ™9ZÇ”bø3¹lAØMÁ¡«ß47 ¹6†k&SØ+¦±±Í¹« G؃Ӟg� !Ó݃=û‡‰¾/›É–…�ñF‡âÙ;ÍVþœ‡ÄØ÷Üì óهĘ�›‡pÈó‡rÚ³è Þ0ç›U&¤D×Ô-£oê2wqš]ûÍL¥¤¬]Rþ›�µE–ÔlŸCÏx|»7^¹6™Wœ²NHzKÌôáÀ9ù¼~ŸN¹§|«Š°­-ܱGåïyîsïðæëè1ìvõ÷Õ§ ãAV?�ûÿÊø6Ãô`ú€=C+éº{\Y'ì6¸=uel€‹»©Ç˜dNep êà4øµïi(bÁkÐJ½„m€ÏûÖj›Y­½vl°1×t½ÑÚõyf°û9¹?Á�ÃU ¹&0 �‘ë«&íÍ/1Ž)¦µ²×_(Aþ…‘øá8ë÷ëÀÉI¾|4lóµþÂÍ3›Íi•¶²ÊÛüß#²¥Tó!zöèí°´64×âp¾CHêðb�· Mþé…m£‰d«Æ#ï² \í¬\³qô>©0ù£ß{'b¿q6Í!]é&ç2!ÁKüœ‘šVn Õz†8^ë¹gʶ¿[²xÖ“ÑÈ•î‡ ¦†&r�Üø°-(ÀÕü¼cÐ+[L²]¼‹¼iˬa>•ï�lýάíäfhÊw$³åh¿^°%¾öäÙØÊQ±DÂòø˜”¸fi4ëÔ5Z'Ê\#rQåDyßËJî¥e:¤}%€¢úê\Z›{Y“b’Ø¿Eæ¢jLtËw=L?=Z¡ò�; é-1úWMTÏ0gùlÁ[ëÜÛpȺ´X㩹l=ð­kÈîàk»™‡Ûׄ9v­æÔm~·øà Vv.°É}#©ïxZšF�ÀÖ&âôhjG¾úã>h͟ȧ>ÚwÞÍgO‡" +l¶�¦öÏ„:�CAŠšüuÀBÌC®¶Iåi“/„~5 dù´–)ÖìGŽŽc%#ë*€ÁºY(zÕç}ÁÆ—ú€6Óκü¢À›ì éuß<;7µ™!ÚÒø[Av’!/Ò#*ý��šÂU\ç茞œG¯Ã¤,ØӜȘpë4&ú¦lkåè ¸lk—MKbÖ öþ"#˜¼“hb9Ô#.r³0ÏàœsÎùp§‰«*ׯ÷ZXqZ$W1hÛRNú¤N8 ÷æ´­T‘¬ÖõA†Õúbwœá\9“Ruö–_1Zw ¢ïb1FŽÕGG“\xÙ¹±Æ;¶ÌjÔç‘-Çäô;¼"É¡ÑÐÞ¢ò./9´z¯³Uéù@–0¹Ã@í}qÑ–ùºû�ú\£)l®%[JŠ9ý™@6¿Óaô¶,zòÖ{\Ÿ÷yŸ{½üe/¿>øƒ?ÀïÈs 9?<¯~õêÇvï]�<™wá=t}áÑõÌg>ëú„OøÄëÏôG^?ò#?vý«Ÿú‰É§Ý›÷çÀ¡ˆÜìÑÍRq=À�AýµÖOùŒÏ¼Þçý>ðú¿ñk×¼êw¥QàAöý®8n²=~ýÒ¿ÿEÿÈ0ïRt»­‰e®Ùêå]d�<úˆÿÈȺ–T5°_½ëzzUlfz¼k— 2pXûÂÂÃ=¦QÃåbë\-{̆|qŸ$ʨ-üøì‹dŨæÔ‡pkåy‹­¸ð­ÐóbÖß”Æit˜tДÎsuÀÇàãžÊ‘üŠD³µ|¢ÑÅžk�›¶ÿéGÜõ%_òúã/OQø† iäíŒ?õË>ZIG=º…“:ƾ"Ów4‚}ÛÛï]ßóýÿâzÍë^—Zd|\7ô�\—Ÿøà1þ�9§çÞ­›\FåÜUTjâœl|�e<�âÈç5z+‡9up±a›¾O>â›+×x8OM†Èì~iæ§_Åì8jWžu.e‡ƒ>Íq'Å~ãÑ>Ÿ«°kP>ín.“aÏMô@“ÛeÚž\ÑâȤ<ðX§ìÕ[>×âÄkÐC7\li�{ÌV{ŒÙOï¬ÉÃPúa´‚¿Ô/q}n—¡=?çØ“„lCCc°í!Oâwrag…fÉjâ–V8oùÒ?Yeæk]ÜA48ª\Xæ8ïؤÒ9K¥æÙ‹!ÑÜÖãRlåkÍý®ÏD‚çÌs€]ˆâv¾C„áÇž\úH§ØD.=éÇ3M½݃yá%Æ2œ?ý#K|ÍS¡h·+_“ îì*Þä0»yhÍöeÿ¶Gg®Ï}‚ê³nÛÅ-N*à¦(3õ0ÊcoåÛ#Ë"ƒ&w© ߎY™oœÆŽóÁØ}Í¢Ýó9o%W,>B«åL[[áI|®Å‚!šûFùå0˜¤ósX/7ðÌc_WXÖ¦™ËdÕªD¦™ÜŠ_RG^üµI„áV ° žèL¿068a©4ë…‚ÉLZx­z¦)¦^e¼BV}³v� ÐFÚ¬Ûöæøÿ­Iÿ“×<œ«|3�ûU®;b ˆv®_�ðæÜ©cå"î¶wx¨ÕÏâéIë¢h¼csÈ9±÷µBga r]l (û¬WŒìñ�–á¡.¾ñ3û”ŸØŠÄåu‰Ò¬ðŒ€b½[(Å5¸pÄšãÔRïjê…ŽMÜHx°VwšSY©­Ä{§>1ÊëM<$·Ç„ZU¯/(â]G³e¶áÏWæ1é&¶Xgä_y’]¬Íí�‚å¼ ´ �z¢Ïµ”gL„ÇvÕ¯�it`®–b£"qÄ8¶ÚÛSsbè\F{áÃê Î�§¥Âó/axí_Zb‰¹ç½óˆck\ðCR17×—ýé„SŸøÑ‚)1'ü¼8½Ñ·¸ò¤®†Ôd˜\dÏa5-f»g§É”•0Ù ³zfp™Ò@g½í×FíxxzZ›Šyaá×æÔ¾rãÒfåZXj`\Ái![âñuÐ[­õH\ìÖ=r8ÎaQçw•Š«z¸VWäÎàâÛ¹ÉkŒb¢•©a%»³ýVÎö„óC áúLNËoiÓÓrÄ*ÄäÏ�¡‡ëc@9–5Ï_ç·ôâÕu² m¤Z¸µ7ž˜ôåìé¦KN3±í±³BCSû:–Ø¥‹˜3.:6Š^6–¢•ó\âSgÖ.ˆ”S¾˜ˆøŒ<ö�6å�žbËÍ´àÊùCSmå *âáNôW#@öywYScb°£¡:(-ñ�I”'8kÑ:ïÄÓNkÞ±ˆîÞz‹n‚|ÞçþõþÄOë¯ü¾Õ1°”�˜_û�ßÒ^7îˆÕ�Cæßÿ½ß»þé?ûŽëyëó¯ïý¾ïŽåô;+ôBÌñ$RkÒ-�ëÝ}o~Ó¯Ÿû·?sýá¾úz@7þxç_“`ÿH�ûZýQ�7¾ñMH²(SfÇYtè?õ¾ÃÓÿäx’�îÁ|Ñgz[ ºL<†òï>ç¦-ý²Mø8%:š\kܦqýõùÜŒ&‡«_Õ�¼9WÅ3£“¼ÕEêæK AŸ˜|ÞÔ9Q.ì<Ò03õàL<ÇöÀµm³WËg¾[M'�ÅVŸ{¨DþBSÎ÷ýÓtý½¿÷·ýn>ÎåÊ7½#>š7ó Æi)Ö½ÝðÍ96_÷Š¥'¿õÊß¹¾Yq˜/*Ü_:ª„m×*sº�è©W„w4Hô¾ÖÏG$'ŽAØ5i€/ s²ónc}É1|àŠIØŽS²0çXœIˆÖ?çœ9}šZçDÝž3²&ºÇÛÙâšÚXâ;ÜG Jj³äÏžÚzLÂQî³ì¸ô^S—_\:/Ä¥3Óg¶îñÂ&Ȩ@‰ŸÞ/·ÖE¬úaÖ@‘ºpÄy^Û¯ŒÚŸ9ØT’5¬ÐÖã½õ�—ȹFcjcÆ6úΔö‘+œœÛù0/pj€7yI�†ÔÖ\àvLðáÑz©yÇ¡¯¹f^u5'å˜�u„ÛwXlßP“‚«ÙV ¡ £|Ù⃫ulPúÖýæILÄÒ#ñNîñhJ½gšUn Ýg!„®Þ N¾Ã©eûÒoˆ5Ø“¿\Ñ”uR¥Û0çC×�Íö`�U÷Åd“ÉÖkϳµ;ÐÔ~¸ž`ÚW0´ZÝÎG.�âœúÈßóØ(ƒ'ƶjBk=ÊÅúÄ,n“Äw—ß=µ$Ej&¾}0—bÓwåIÌFNç]zˆÕpïÆ«5¶âàk?Ì5Ø!Ĭ ÍI4£>3O�`ÌmDK#>çfÙ‡ ôi#‹sN=Þ˜b�QQËOœŒbò9Ü–Ê·?‡¢ÙU#Kt†«< ¨�oØY–X5è]VÎË ]ê¶^á˜O 9Œq�BäoÎ{y"Ç7÷¼S ÊÈ}dØ0Å0Íø‚<ðNa.únÜÐ…l±Å 'xs4×�Áσ!s€%M‰Ïƒ�ôn,&7H;̲ ¯É{ªØu!âDíh8y”­öË.!pö„‘ £qY¬�ø§~×k ‰\ÜŒ¼a«óØk/&ÄšÒÇèp¿ø.ø| ¿1ZáÃת¹fãRO‡S¾H �¼Ë{Ö ¹±  Fúá®�ü"Èf¢ûn?í qôlÇøesÿ+ˆÖ#1¾ápîá€ÚÍ΃]£çòþø$¨=è“R�ä(˜p ã¾ ƒ=»Pkif‹OKŒÆbÖõ¨k‚ð¡Àc ovÞåZ XòE_½¼‹Ágɽߵ+q9m¬´?QlÎóDìàz]Emé u¨&cð" ½ì¤î“¯攣ši¸fÜZW‡pk]ÎÍìÚ%ƒ·(ÉzæMçîŽ]WýúBF_L¦¡áquÍ#ޤ£QK‰«ûÈ(kèÅé'¶ÚÞØ„‰Ñ9�ÊÉc=s‘gÊwk›1Å&TrH3Nnx½µþÆ™–VdÈLN†y,šënSÉÝsà 9oðú‹{Ç¥c·±é¸r°^}ltHŸr}  ½µo`Þñ’èc(Eœ¦é�M:œµ²YPêªÓòáœø’šÞ<øW´³»wcó»±rbì 6_x¸CøôàPŸ÷¼Ï¿^öòWä�|Øž›u¿ý»¿½à/àÙá\ܼað®(~L÷IúÝ|üþ>~Á’o4Ù=š†‡ÞyÉóD~ÿØôcza¤w¹è~ó]ròå]˜.Îe¿õ­o¹Þð†7¤2S{GjÐNFÞåø®ïò.þ}rtÔ9åj §ý‚ªš°žÃxcÅ>ÏkbV^õ67is6V÷Ñpž‹€¼lpç::3j=ØøŽÀË5^z×-_ë l)q°µôÊ»Ê!@z�õJ¥…{%³õ ¢!cÛ˜óÿ–Oú¶«o½©FÎô”HJÕ9×ÍÞg>ã�¯oøÆ¯ºžñŒwÌ9·7‡êöNï}G—wûá>"‹u©¡R ¯ÅÑýæ·¼õúúoxñõ8¢ïqýÕ_]äk²œäàÁ�³¢߸„I÷hÖL²sNøàœÏ _x²?�Åט9ÃrúÿoånYfç dóàcÄ$ªH;­Ãþš•(ç#Z X‚àʆ>°$[cذö~Ä3GÄYí¥vÙg쪈X»×œÌ§-5–oà0äcªOì^û\L®Æßzµ1MêÂWsëÇÎ`“WÛØŽ>�P0ç®ZQÔQ~EÞT®ô(èTÈ‘øÎ劳ëô 2Xxòˆžî«ã6ùXM™Z°8†Ú˜¡›ƒc¢ÕhŒê‰^–\ sÐ`ì>'8Ðof,÷÷oÌþ|ìz C�†öùz|œ£úäÆ7Ã2¯­Ó¦^M+vqŒÏ©Ê46¶,yè/õ°ï�Sûþ?•þÀqÅÝ™Ëq¦×Žœ×­™žÊÌAÿnJ°'1ŠíÃöÜœµ6Ç‚Ó … Éi‹cËë7V�ÇÀÁ�^ç�¯q@Ú˜¸¾«û¦'Ð,ý?DÜ ¿ Î Kxfa\9âZv¼yŽ:ß}sÈÎXëà¼æÃxÖâ Wí!iX)<3Qá6ì@xÄšs:†sJYznˆ%îœÇpY“Ï©Ã�êÊóœˆh _ýð`gøX퇽'¥º]*Š]dp`¯aföðéÃãðÛ50¦ºVÇj��=´Èr;½wáüZ/ i�¸µþ}#0q$s–&¥V=ôyÈ%FÈ.é>gºfÖc¨½FÐ.chÏ©±²µf Kq9šcø w³)¢�e¸qƒ%"ümˆ‹�yé#®’\'yé'jOQ¸÷öD•ÓRuH}3�~sp²ÖåÔÛè$Ô¾õ'`¶þMeNãiQŠ1£{Á¾9g�>k&9>fôáŸ47ÿê'uè_kU„FlŽŸeì9:�œ®u�;W©](•}úÖ|îÉèÂf}à5ŠiLÔo×vÃç¬ÉŠðÁe1c47üZ(>ç�FÝ¡z"]+ìà‰… ßÒoÂÛƒSI{óV(çÒÜxÈ]&A“gÊ´‹p-vœwc× ]Šêð‹6‡-çp�Ë�ÚNA­%ü·±+¡œ=�¡J1Ôº¿yÑXÍ,�pðÌ:×\ê›w-­ûÚKo¦g†`çO¯á 1Ú3ÖÀ‘úÃÉúìÎÄk*§ýÆ(h5NZüÉ?š0Ç5ÙLîL+“¿�´˜ô<ªaQš:¶�>‡YG›Ó· cÛèX«›ò_îÔFs¨¼=—ÉsH±¨°ƒ¡Îj€Ãu¯äY´÷®ÓÄåiy—Jõ•/œ£QÆêA¿GÞËoc‡du¬ ™È„s <(�¨5ï,:�Âøg“ϵ7±“†šb˵¡èïMŸÖ‚.øüŽ:€ }Bf€­7Q(¾þ?f§ð~žYĜڇ�kŒ'y`æy>ìÆbŽeô‚\ÕmaÔä{6Ñ��›w_õÕ_©?òüL¦Þ¹ IDATë÷_õ×ßô¦ëçþÝ/]ŸúiÿÍõ+¿úËÒ‘Ïèð�S(qå]×GíÂÓΉÏñÚcå/ÃÁþkpöqîóÇ<|®d£ü±Êê3㬙,ŸòiŸ¢\º‘ûƒDêk”(�…Lç¹%+up�Ô‡B}x»±-=oÎĺçÊAÌMÿWÝ ¿ûgò8±§V‹L^»²‡/1áÇeÏÉ1ëðŒö „f\S^K�ë…]Oï&ûäH\9Û›ÐÏ—(ñÑìäPèÒ¦uêOm“i¢&áêMö‰�µôGuµ¦¿Ñ¨ÞMCÈ�â=¢ƒ:ÍüÖH._§`޵cæsëŒÉ Üʯ ÇÛ��Z¯ër©‡‰Y×!Šaêî0î®ìØÂ3uØ q©Ùïôw|é-cÉZ‰b 9؇c+ûç°Æ1»¦XCcqþ;ù !œÄ)À¹`|äð?beç_ܱcÆã^¥ç9ÿXç¼±®q„·ðe€ Æzeêí‡ÏV‚äÀä·èÅ/ÚVš?´8œkâ͇oG¬Ú{Ë$ðÄÛí´)¬“úÝoñTm´å:±ç�—\g¾Ä’ò$VJŸ?Y§ÁŽ„,Ë& qím(´ïóJaª ލˆæðL¼«t¯S°-û°¯½Ø–ž qÏšÀtoE®yJ2yÒjbu±|;EH©¯š¬%'eê[�ßKù‰2Öý!Aø¬óìy\7G8â{÷ë@U¹�ÇÙ@ktLÀS¦˜V­ão2æjSÌüÀ¯v€‡d&€äªÛ©˜Zá˜äzݲÄ T‹“É&a=“g¸ì#5ï<âB´ �„ÎÏ[;>ÐŽÓ2— ¬<¶ë2¾H; ³î»'®Ä™Ê‡#zÕZGN”%çWs¸Ò^¶c]¸Ì?ûÕ÷Iå½Ö¾Ð\ ‡ár¿pN�ô.$¹+¬5·—äK˜ã»\±2€wxë»ÅæÉ@\ô«yÁatþÑêšµÆÆù3ž½×àaÉÀÖß©Î{ÙÖç„Á&IÖapÖá-gb“|âˆ{\XW�ˆÎþÈ�e78a çhÂ™š¨•øÄuÖN`g¤>,Á×¾g±˜7É8ö]/»/B~¸yÄÖþ™ŏ‘/´ÝSÁsSµ,ÜÐÃ%1¦ÊÌ>Ûó¸aIèøM¨Eþ)$5óÅzh“ÓçÁ¶\'éç‘ÖËj!GbØÇF\¸Å3�œ“Vz§c,tÕrC‚ÛÏ©­-Ô“Cº}SEA«ÞE25²r�^pr–k«{ùÎÎÔ6ýg:ùñÂá^ƒä¢«ÜÌŒáÒŠS²t4¾0ã°0àÉK�¡áú,„à}EùsáÖŽ‹¾¦1€µ~’ˆÃhý«ÆØh˜qÜdÙ�4ÏYP‰k¨f ¿>¬”ç—Á™ª�\ÔÆÍ˜Un!€½”ÆØ Ó!Ô*Av»ÌM�¨HÝ8ðA©“n;äÑ'jË;nHÕž f!þ™%£ÚìÓž¹6¶"|XÙ–ë™kŒ6ð¹ûƒì• ¹ÛïQ6\ºM Co³!à ׈ÃÉ™¼±·¼ð5WÈéûc×�þØ�\?û³ÿæz泞uýû_úyݬK¯x ZœlL³Ì–jb•jü£Ëdò`?q“Žz�þ¨Íëó8Ÿ)%½§wR“Áä;bXãâ&‡蟽žþ´wÐ%y‰œ×¯·Foô§øÒ‹MÆÞ¶©ÉÚàAØ18‡kL~°Î5±Ë,öyˆ´3=œkt䜟š�»«+2–Ùús…»GšýŽE§“P8èI’¥ë¥˜¸Ö<[&΋ÿMº�§>>Wé÷nÎu�ßTS=¹:»^ò²—^ïönϲݴí3ÔÍ=û™nÏ» îy±wçá\\ÒÁúMo~Ëõòò�×7½è…zWÞüÎÉ¡Y·Ø]‡oh+‡7åüxº‹^Öþ‡¼ö‰qp¹dqù|L©t=ð®rÙ™ä6Ø›ñ¨NúRž4Çêf8�—&gókË5êçœ}¹–Zþ¡YsDÊ”zä 7êvÞùk¯Žì«3;H�aî“¿ú6+Fuš¡µkcÿÀ76+æŽûtTÊÄ&KËîõHÎm¿ž‹Ôâ+U7—üÆ5×`ûì:ô…^<îå0Y„Œ6MC§À„iƒacL_R)Z±Žî”áRFÌp‘còø$�P Þᣠ¾àà�¸†¬=±6JMYÄÑV:Ÿ82ƒKNë&Îüb �¦,ÂmFc¬ïh$9˜ óÂ9Õ'ÇN¿ÌWnrÑSç 7�¸ƒË 8ÚÛä’3'2;V âMˆO#¹@ìøxìu&⬹¸xÑ2˜7"¦ûÑ:<)Ü#Eo—'Þ¼Šµ­95C‡­cZèÜh4¯µJ�÷GÌ€¿t3îB0y-'œº‰cw‚’jÖ7Dу©©à4$p×è”ÕjLc?ó¹O§ cè�B”h÷,=5ѤeMhÃÝCrˆµ©¼84çœ'‰¯­3n*D1•�k)ç'ðÑ9±¹A·‰’�¾Ãqæb};–¶1[µŒûœs�4&ñ>ʶz$ƒ¿lÅ­˜ÄN'hÉÑãù"Ã�æiæ’� <Ë&Qíž>·:ʇá (€ŽÔ“~.½DM {æ5Ìó|cµlØ·¦òÅ�Ïßá=Îó7\ËÝâÆ i$; ÙÎ7H?¼FcjÃJ_¢‰(ú^_Gã«Oñà¬DF¯Wƒ«¶½®¸ž{gs ˜äÄÆ°fóO¼ÝGO´Ïµ=MÓ¸r0÷§âuGL½óšOz–E~êF"�ÜÐ ºj”�Yš2Ö¢͇ ì_ý+Ÿp½ô%/½>àý>Hœzg›¾õï.�Sàœ›ô€¾Qƒ�A R1ÖXŸöh3UîóE½bxzôý‘~òÕ¯þýë~þß]o×ïÐã‹s"¸áë“dæ]{äÁC,\üÓŒlo¹Wò¡ÉÁá k¾!â¿ø«/ˆãú@Ã>ù‘á³PR®™Ó?ézÇwü×gþÍÏ7<ÉÑk³ Öce€ vפÀÔ…hìñ¹OÆ¡GçmjuðØÁ»­7AˆqÝ„ÜÏ={Hà!ÌÍc>ÿä-iŒÚ_L¯söe„!úY͵ÄrFê•Ç¢cl.﨣�‰a2žöˆœ\ §øÀ±³}Éÿµ_óõ×û¿ï{æÝ¬+V�S8ygß¶`úcÎ4{©øvŠù ú]’/ü–—^/~É·*ÿCú£7¼ëO˜‰ó }Ñô<ðEG¯cçW�ıžØÚ½­MŧÿdGŒŽº¾áÏMeW@°92NžRÁ³>oõ|Õyh¶N‚'wöºÊ¹�k} õŸ×‚%ë�Ï®`è!+Vºù!Ö ê[I£}$�œg÷‚BŠMQ>£Ëh¹Omƒ2#¹Ñ³5)Âx» 4û¢3v|7u(ðˆM=5~_Q�ü7DáSðQì¢G«ëšºË1(E²R�Ú`bg]_õµÝŽz¹®væ ×"3×AÿŸñ7?Ë7áàØ‰Œ�&ÃÈÞXbµ“.»×b\tV¶›Öí7çúæ|/òÉ[ÌæͽqâpÛœ}²°nŽ�kþ !4M)ÊËTL„,sKÌ\}Ë= 4ŒŽNS×FNlkl¤¿Vlx‚9çC³Â½­î/[t/Ô± @Ë8Ø©Q¶':G|ÎŒD‚w^§ôt\™‡ß­Ó¡é¨Âç`zZÍ®¯ '@N æf=þuóÈJæ ßPç½ “¬h&œ|Cc\òŽ¥Á�[س7XÒ ï4n˜ÉGFûÀUXglŒÈ2O ,CVÍÍßý]Ü&‰Çõ͵’üˆLÝ ¬ËPeò…€M£íÌß²ðW ع†§³é9tk›¨#fõ�Ô‘8÷¡ cº ëâÀö¬¡èèŒê¼ÐZµ  kk•!õOÄ'JG½†Yõ¹5™óÝ„HÔñ,jˆÒÔ4)ÉYàŸ¦fÛ'˜Q(¿›Ã¬á8LÈ9„†/þˆ6|bìÍ}ã c6û7j?dáÙºIé‹-+÷°µŽêœ<©ÊðtŸ9<½8l›°’¿¾‘”^X²«Áàpµvòáf^Zï<2K¾¬Ì�/Ú,Àñ‚Ø– FòÍ€Gbes?¢&ÇA˜¬èsžïJEtj6ú7šm“‰yõøÆ³§tcØŒOsõºné,Gu–ƒx²û‰y×bs�k‘;7.½0JRl+pïý¢yB·»*ƒÓqq›wæ5biuN›Â³÷ SM 窃9fJÎÛÖ,ÿêX ¼ko_E2xò¹G2´×ý„´©’”nðVë}9¹q5lq«Oàäm?Ö4_ÄšA‰Ðȇ¿p�Q»ÆuF'ñ̲ñ‘lãÂ=#1a[ë"þ´ï/¨�MË×aÐ1Ï3¶ðìQÃÉ•šXoº’£zUDt•å®—‚ý "ëpïXß�tÜØ:¹g‰sýÖ>:d®í€)D©±×¦P꨺lŸ&8-Êf‘þ°ªÎñ¯3 „à<¼î;ºòH½ñq„/š¨�}4OçªÅÂX¯?œ•àmúÒž b&jqrq‘x™½h]„Òûb@84üã¨Ü\|L7­¶î8Ø/bçÁsõéOÚõç>âƒõ—w_t½ü¥/¿>ôC>L7”îéw×é…‚€¾6¤±kß°—÷Âþðõ<¡—.yžDþœ KóâïçN®sGý 8ïÑ¾íª“?þ1&‡èÀŒ=75jgŸÜ©'míS;›ç°têFLoÂ8¿n2êÈW¢z ù­J6[=ßDú�~ øã>öcô+ÝÔ?õ::è58Ôœ�ý³´³=Ž­ù­ü='¼+l Üâí¹ä˜'-X÷“E¥8&vŸ§:f>cÃ[bòP#6Ÿx[©8ï£CμÓj"^¦›ƒµwÏõ¤ðMGñ€çÿ·àÞ~¢C^]G÷®÷|÷gû÷áùFƒl–±%[¯{yæc-1•\÷ *§×\_®¿Ç¯×¿þ�×WÍ7^ßþí/×ó-×ÄÛõ;,ý_âÜ+úÅ� ë/Rûwÿ 7ä?ôÐõÞïýÞÚ�ØCó@¶ÆÑ±®»unÒ=ónñ°H/=»™S‡\­91$0|és.÷P>¬É9ðù±r‰ÊÉäp0±"“}]·0NüJêQÖ›Í㛆ƒwÜè1= EB!Œ}­ZÎÔâói,šŽç²c,qV{JŽö{bGÂʉ‰*Ú:É‘ÏØ`b_Õ%s» à[úÁÒqÑÜ\{Û~â¬À3:“¡¸ðº&›8ìž…/9<\“=·>ß C§×JK±®Áü°—o¯¬ÑfˆD0ØPe—‡·:°×äÞ*ArÉ6Ú¤ÇØÎž§¯ Ò·j_<£?<=Rw×·s2%—õ8bšû¦OØMðÂȆžì‡h&àöMdš`ãy^í7¨s^ƒ˜ÄIn<¹š?lsœP|^£Åaݨ‡�¶™Š ÄvkßðÛ¦ÃÉÛµy”ts!A�ŽM²^û+&N÷ lýä�¯ÃëêZºý >z _·p.]?6rÕ ÿwU½)‰¬ø‹9sÄ9–6V[¢^›æd>÷jŒÞ+' —ÎÛ0s}'g×áž]ëÖÖ¼˜'Ôù§ÎAtê¿/ËêÇÝŠæ\¶og½®!×iËa¶לìöÝÕ³„ ¿r<×=ã5‹Z­ ‘U»ë4"}c.Ýäc¬zµVGtU›óú š–¸œ@NÄÜ&=|F@ä$Ö*Q)zá¡Þ"‡ØÂQ\ǤŷÄÂ…¿„¬‰™¸(Ø~7Zý28Œ$PXÅ^§ :�×|²{Í~0kç:†ïàØìpÍIžQMÄZÇŠK.ò�Ohbœ‡Å ® -zë€71äH¼C�:_ˆ&Ú5´5.¯ãGY’ø«Ë§ÈC·Îµ%Š¸áºƒÝz'O`ƒN.�Â5·Æœ|ìS'ó±µ¥¾eιĬµ/ͲòO{C'ÿ ³¶01†‡~x°È96âYú?Z<ÃA6×äýM¢]ã(jŸ{H¶\ÎËbU®ñÕSmåœmª`cÁ¨>¹ƒ�.j˜xçÑÁ35çZ 7Ι|;{=JcÏ�ûÕ“=ä¹f@1†Œh‰Ên˜¼©<ÂX;Û¿öĈõf¨Ö¹#囓gFÎYl@ÐÉ5pW/9\×ð¬òÚ�Mε1²zåÎ9g�Ç?7+¢1©+EO¼B£Ñ(�šØ;éElζôà3bBĻ©�ý2˜Ïø‰ßþÑaD�c6…ÌfšM¦j¢þûoš© œ;óU·ÂI^^ðö4q ‹ÿ;˜Äs—y—žûÞØ‚úü7‡"Öþ™o2¯=äOûáØôhí^/Õpå‘wiñ‡Ð�À§^þaϽ^ôMÿøzÙK_r}Èsÿcݘ /9ðû;éÄꣽõóP¹x·¶ìçæÔT/÷í  D¸eéOêC)ü±�_´Û�Ï}ТÅy >môÀß067š8ÇÄ®<î8ýŽ>ûÓãzGâ9Ï~÷ës>çó¯OúÄOºžùÌg™óžnÒÜ{;7‘ϵA€7©§û”¢w'ÎsxôVÃH“¾ B%í: -–\¹mÇ0xnØZàXûº ÕçœN¡ßÉ M­Á¹'ÂrÐgØå¨Íé‚2׃ÉíkAŸG2ÌfN4øy`휭Ôi1D¯Ùî‰ö5…�ÆLŠÖ@`®k9ôÏð‰i­>ßzÎ׉sk›67çAqØk¾@îYj=,l—ƒ™‡'-dJm>n»W@Î5˜>aŠ È79ƒÓ~÷q»(¹™‹Q3\‹›r0'IŒ' X$‡{’¥Žñ <ˆ¬ØyЦvG¦�<ÄmÞÁ!½u•Z¢›øÉº0øý¨îáa2žºΚAÏÌ9Bcµ+ˆeOÄú}»Ž%>ð„w×ðѽöV{®­¹±“�Ž?ö,SëpŒïìŹFÅCV£Ä8üý#±Ølo±´Î?SN¢’ëà¦úá�waûÅ$†�™,Å1ç{9&mÒ?­ãMCÔ®ƒ‡æ5Ö)GC­m¼Ž_œÈɉnóɦ±ÄØ®/îeiœÝç38öí/ÐÃͧ§¼›J™P ©9q”m.E¸ÖjUÐæ%BÞ&!u ‡³¥†#hüa)(–R9ƒóÛÌèòwÖe®­xë ܽ³ØÇ~®ñû¼Áyd÷i<˜ÆìsŒSjýÕŠžßÅ�©µÚë±™Ff½$OmÝS#Oþ8�}ÕUÅDI^0™ÞŸ8LF¦ ‹E Õ'Ÿ�’/ƦÀ㔕¶kÍèâº1Nûum±û c�Ø|ƒ :™6|±Ú郉wÞéms@‹N±ÆŒ®¼™zš07J,güþâÄ1V.2Œãhì �za57‡ÔGëN•ϽÓî�Q òÑzxŽ^W6/l‹G!íeããËuÉ-Í“è¹äKÆb;ƒO€ðÒ…<à²60²šÃMòá¦7Á‘ÔDZ=‚!µ‚+v1Çj{g©Ü»gÖ;Ü©5}±Bëuë¶jp_ƒåºÐ›~²tX»š>n¨éÄZªvˆð n¼Ó�ܤ¢9ò6ø¡Ð.Þœ?w„å&ÞÓt#ðC?䃮¯ÿº¯¼~åW~ýúê¯þÚë_ýôOùó8¿ï�G¾Ù'|näpq®¯ÑÕÿ‹�žojîR¬Ã¥ß'�ºæz±òôü¶÷­;åpÿtßüÄVȹ¹GòžsßD@ çÉp|ü.®7ú+±z? ›*Ïyö»]/ý¶]Ï~Ö;¿Þöö·_oz㛯ß{Õ«›so3z5“Âë?øÃ×Z—ß]8àÖÄ9 ?1,Ìy®þ–˜ÜÄñ�xÌ¿M’ý0Â?”ža2VvÎå‘Üûu}YF´˜P$N¡ó„µéªßy,Ó¬q$ð�óí¥v¹!e«vš�´çÚÑò‘;=¤ŸèƒƒÏþ˜ µ¹�ó&ÌQÁé�¹|×+¾ýú+Ÿü—¯�üÈó�ãn¾ÍMžc�d4ðÚ`áác8ÇæÂt�gÕ^_öåÿðú™Ÿý×z‡¨^Š»�Ü<çD3Ï+ì½1 åC=|}ú§Æõ©ã¯éfô3ô»;yßd¹ïÓŒ<Ç`Goò8T#®u ¸:ÈT:%º§í;}–AäëuŸý©ÇÈÁ³æó`“g¯÷[ ý0õ�:ÌéCêÃÝÌÝ3ûÿë vfÀ ’·øhÀ Ø›—\éÓ­œhÄçó”ŽÔä�×7u¬å«–p$g| ^ck9t-ã"]ø½¨ÆhJßGŸAÛOزæÓE–Å BÆ.Ýú:Äž>ÑÆÌ¥Ç²I­u0½S0.�õÖ˜ûýÿÈÉQþö49Àòàÿ¿¾CupòÑæž•(}]ã±Æ�I¥Ô.°^“ó@S6äeÀãµöĦw$ 2¼Á&@8ÇÂ¥1”™Ò÷ôÐ`´ò7uùÓ±yî¡Ï†™š±ÜÑ®î£Y6ý³ÍÊÉý"õX¸›ýl4­sNþIê­›k£µÎ9$ªþ•ã rCÙõAäS›s:0u3\FPæÔ™Ü©9PȳwŸ†³Ñëá3çè'³ÍÁƒZ²Ð±º…óR¾#9Ü„��¾– ÑÐ /L|$_ô{Örõ²küH’†j3F¦Îñ Öµs�zÏõ,zö-}v�ÙuíûLíCæ]÷`éÌ&?¸àÔc¢×ÜšáiD�Øî3ƒÓ7œôá=oøZÿn<ØæjüÚ{±3Ä>ºk´ÿ°yj…<}Î9 &»'ÃåÚò:Ýg�A„‹5¯Š,Üä „›G›¤¹í©?¨u´øÆÏäµIwR’ŒiÅz!¼íp`ðaCã¹›ÉTâêZu W8sòÊZ­®\�gJ÷d€0³÷‹GÙšcét�^q'™\އ‡øémv‰ã¸Næ6k'‡MÚ‹fi™^˜{ð][ähá?ñCÃVŸ­.LÖ2ȼ¹ 6Gbž^ë-1Z0f¦n/upØŒ˜ýåÁµÖÉ�^)´Ï   Qcl´kìòƒÊhO¨5ÇÃ%9x¬UX×;z“§âç êxË£™am¬É‡)\ô$Úìgï8À“¢ºÚkjGåÄ0wIZ‚]{Ènø�d£�PK‹×áÚ@ ÖIÄ]†Õ˜m«>\΃ì„1}hìò,ü¼¸Â![òi! çùˆ"›ó…e‰4/îŲÖabã÷9)tÅ6AB+v¿è³Ù²Ò«gÞœßhG¸�9LLúuØ�/I�·Ö^7[{Î{0=ñ€8G IDAT³W´óù0 Žž�/±ƒ§¹zàjä…[´„÷�“.Ñ£]†p$'~†õyÍ!ØL„ÃÐ9P_øƒ0Éä>›É¿¡•Qò¡9ØçÑ:œ[þ(ÑÀÀøÆœ@6iï�Ò`Õ¿›Ø#û}KŠbÌ´æXãâ.�F^ 0çšë9yýë^sýÛŸûyßDXñwh±÷�3Ô—3iZÄú‹¡§=õ)×sŸû×7|ÃW_¯øçÿüúóý±ÎéFÂ䋇\oÄ0òÅ‘ØZ‡�vùÐ<È1Æq¸¾"’zXÓ3sß±´ßÕ�½œ›yàç÷áeŸ§pA°'Œ6þ1blÜ<å�È�ý©Oyòõíú‘èw{Î3ý«‡yè¢ïòÌwº>èß÷úÀx_ߨqì¦Õ±‡ÿ•¿õJ÷*¯!Zõ ®-Ö–¢ýZO?EfpB8ÏÙcs,|dp$›cÓðSå²ÔÃ×3_ákÀµ}Îfgßx¢Ëð}°1ýv²ñ˜O}-Å…ɲµ¤– BS™gM˜{TþiŽæè$.9êÿ ù¹>ûû³?çúþïý®ë¿ÿ‚ÏÑ+y×ë‘GžÌ““éÐS§õW“rø†›såsyý}Øú,ÍÎaR<<í5È`¼ûߺdEø«jûr�D‘×r-oà©û$Œ%YõšsG³öÄ ,â¼ÑZR;ºLÏÏàj›€g]ä±&¦>çkÚ`ìÕëØE�(‚[gõ§cùäXëæµ�ƒÃ®{¯£Ëç.ýËs!Ø¥K¾Í_¾y®[&ÈôÓ«¹Xq5ßiw~9Ê‘1Ïïl¬’œèñcìžN�2”;ù6P0×ÄäÍÊ&¹WM1Ó�ÓõÎw;Ò–˜]�Y�ìŠwvYÓ°Åࣕº—¬ÆÔ•¶§Mkj›Ï‹û*Ëê/Ïᜇôª¯{¡â|0UYèý Ï…Ç+«ê�~˜Î¦Ø �’@Èð±ä¶È=s&°7oÎ8ðÞ›¶%ÞÆ,Œ�÷ÑùÁUÁ .ÇæÉæ§)}lkV.Ó±i.µWËPFÑp¬xp~ëøôP ¾ø…#�°Ýœ |ôº£Mª]®àƒË[TÖOÑŸýêàPO,JuÐîÇÎçˆÉCìrœZ}®3V `¢1ŽðR»¡ƒ‹îr�6mÓƒô½¤«oÍebİØOÞä+Hs—Âíïä˜<ÄëQ~ŸK3îX÷(ÄG]Ô7Fòï��=�È9‘, É.ç ÿ²[ûäñÚ¦1nipd|²ñÝX_’ZNmø×f±× óœC¬HV-ÆïórC#â[yønŠ‚tÕá—ûMß@d8ÆBkÁW¿í¸Í,6tp>­�ȧaJîçì¹€m÷\¬z8#!qhLâ:“ÁVÝ·ºÌ¿™u$Ë”2A¶¹‹ÅL´J£ î†ÌÌØ-ÏÊ—Š0¥—ÜÐJ�‰_g.ÙÛ‡ò™ R?æÜ 5Sû�;¼OºþÎßýòë5¯}]b*cæàÍêsTw,h,g>çp3ì¹Ï}ÿëë¿ö]ßó]¯¸>þãþÂÜüÊÍx?WõŠ‚ÏOÜ }@?N|÷šaÏ�C߀њ½ëT®U?VãÑEp‚kq»#Ù¶oÓ F“+ñä¶édø]Všýn{¿züúKé¯g¼ó3R'CGFp¾ J°†µ�9pí1çãé—¬ \Ï©¡€XhxÉÌÔë~)¨{4ô†ú;²æùr^{ãmf‹þÞÐ)vó(÷ê# õ8R9TË|ÙÄÕ€©eámŸlÜhu®x‰éƒ´ TIo<°w�¡kf?ОZPc>1ø=�ú´OÎ#¿Ûñµ¯{Ýõ�¿ö›ýyï¾NŒ RäƒÔæUú#n÷ „S¿oyë[¯ÿ÷çñúÜç}ñõü¯xþõú7¾!á|��Çîñ¹`úïžñ®Uýn½;ðyÏû[ºñ÷ŠëyŸûßê©Ï¼¸͹’{úeh4$erk}3ª‡¹¹´ZšÑχõ3£|òdEBçŒy d�o9à Ž™Áÿ%ΡµqΟ\½L œ_ƒ �ø›8’2"iøÉQ;3ϕĢu�YöºoŒ!ò¹fc8$/Ìæâ0ñá³gòËuãA�›ˆu{®s2uÜ’à�¦p�Ú=öN¢ëßL7¬þ:dûvÿâhs°b8§yç¹³ŠÃ_�{wt@˜}5)¢uípÁçúh¬ÌíÛø±ôüƒb°Ïk“ji!–,Л·Œë¬a_Óëô`sÍ9¸ç‚,ŽuqÕTy _´ÀSv:ÁžGp±j«a¬Í:(OS- aªŽkÊ­Õqf¼=ô›yÍ ¯±•Ĭ¡Ìž—volj§KÙOmáMlˆá.…/3öSgúâäÆá«òá'~¥&ž�áam-ÿaïlÑVVg®Ë½—ËSˆ"H‹†(D-S¶š´QCÔh[énŒ"ȱ´äáEŒX¦‚I%j•­ (hǶ¼HÐh‚ÕvR1mL§»ÓÕ‚"’’‡€‘7r¹¯ßÿ˜kîs/éyÎYsÎÿ1þñÿsîµ×^gŸ³¯r¨NÎ*œÌ+ÔL»<1¯ƒã4Ž^ÌfV»eø;gTúi­Â9Ü#g-˜sÅûä¬�ý Is\æóãÇ‹M6£c&@4�_Us¿À²èZ玿†¯º“{ö$\‘ùk̈•è‰_,ä±Sœ­9®å\{dµŸ‘dá·P4b:?8�¿ÕROC6›v™UzW•�,qkŒê>õ„Q©|¢5è®d¬ŸÓÓ1¼º–šû>Ìb<è2çïô�ÂÄHÆëáé¯]ä°$á5Çwµ«câOlñ¯/".¼5Gì—‡ç°AŽ].4/®ãÅÛ<ˆaëôYô…?ûÏœì1Ü §X‹Ûè‡Jâ³ ‰MNüì7kðXp~kú@*õÃ'vƒ5sÇ A±Yø ×—ëèà 'P¢]±-‡ˆ&Õ·Gnµ.Î,?ÀN<1G¯½”øMØå—²EêµÄŸ) ìWŽøÖ{8Ø‚±ƒÊ6Çt4Í¥B':÷SÃivGCCš}ž"™Î^xâ7k6q P…]V£‚Ó¦+vâ˦¾'yA�øæb•ºf?𙓩÷†1nØÕv¥I›B(ãNÃmÓÕ®†k>6[OïÛ&˜a/lÃ&^üS‰¿ã›�“*¾i˜rì,—Í镚7¯Ô)xލ!Û:ÖaɬщP_óÀqZ5òß]zYãøŸó`ûƒÓßÂà�öyÁ“ÕsdÛ ]=}ŒOV yÇÕo\ñ•gkN¡ßYàç$ÙúS‘ı�ís�«Xè9FS#nZpÓ$¼—jê�H‰5Üísèð½äh asÎÈ:—#(ÄO+–mrâ‘Z>ÞµRf¤ÑV’Ø5{¶bJ©h‰Ráp‰ ;&àú¡åƒîi±“oËéá)?û,KÉxó>óÆ?<ý£ß·¿ã�›^û+ÇŸðß|X€›q3ÄÜ83Ý; ¡�Þ<Ü|ä#qüÈÿ½ã?¼õmÇ÷ÒŸ:Þð†fÞüi0ܱ§‘OómÈ›cZo„îö XààÇ :»øŽ4KÌÌ}ÓL>y¡HŲ!}o��ÁO1´Nz÷ 6Þñ!½[ _š�ÃÁ“Пp³6K�+œ?ò‘?=þùÞ�ëóÚycÇ<` hã³vÈrîg”ûHN¾ñŠP-y‡+±yþà_R¬6ðŠ.4ɇ`ãÔÎzç�:µ¶µ 7Üá�\êKÂÈWkJ’Y.½ãÊ þéñ`Ž+ñsa�¼XÍ|ɇ±„ÜÌK«zܦ?çFÏ·l•X û‹Zßð»ÛÇë^ÿZ½ËóÞÇw|ûS�ûÞ÷>>ÿzbåšn@¦ƒG9$Ç(Àä?¾ûÝÿñxÙO¾òxíën:®ãOv¯Ñ‡µ�›Ìà{Ýõ×ϵ"�Þ¹z7ÜýÇSŸöÔãk¿æ±Çîÿ‰þSßUz×ɘrãG+—ÌæX�zþŒðØs­Í&² è(@ÛH»Y~Ö»j”–ŠPk~öc%xÚN‡žMfL—hÐÎüÄ´™ÎÉa'x+µIEwQ­èꙃ.èàµyƱ#× ÙW† â2÷¾ |cƒ€8çã»òôáŸÞÔô—W¹ÚÀºõç©Þ‘ƒ•˜ààÓŒÅ_{<)ª~~>FŸäŒ�]·ÃƵÿ:Çë#YóM?F`vè€{M€nŽå}† ®œ±Rw^7t?6Çø¦Nà¿ì�`´Ž&¯y>·�!d§~""–äxÖ/Úb ÇÕîØ]ɹ-V¬K.ä•z#'8 g¼LþñGÞ¶ü¢rão%/£Ýα$2œ3ÏÀÂM†�~A–MÉ7-uf\Œhö4ŠÞ.]wO|HWëý¾±s¤Qª#,Ü'–×¥9Kƺԯ}Ö4{ þøÚnÆ­EÖx ã.Ùú^‰êâ?Æ‘c;¾aëc©ùyÙÅÇò±-f]ÌaœÝ×�ñ¨Oó²�¡d© ¿V42ÄøÖá esG-)IOvÔ£m�4XRÚwŒ–�übƒD#ê¡‘g:¤Î ´Ðaä6Ëý(JM ˜ß“­:«\×bý´«uE\Ùêå´ðˆ=µN�‹InvÂi8‡b"?lÛŽDÎlÒÛm°5å£Þéƒ6ñ™Bçïr‚—¹MÜÄÁhŒå’}j�®ô?û[Q!9 ó,‚ )@FD>Ÿ8Í…´À†”<ü[…‹ôêgÂ43o‚W?r lãó(á?þÄ¡(¼x>OòøÇo"Mü36çnútµ 0" n‹¶ìBW’C�1³I41ÿÈQ× ½µ'?r(.(V[ãñ° œ¯S4á˜çèŒZÙ0¬›£µ.—P W3ñú׎ •'ç'ƒk® îºXñÒO\^Á”¼8œ1�<±ƒ9Û-¥˜*¬Î¹ YjŸ$Ê<¹´:—üí#šØt»F(ÜÒ§ŒÉ‰xàÔ&s¢ï->›lÆŽHj’óâãl©ø‹‹Õ±'lGñ°ÝZ¯ìïê]W‡¬�óЧp99@…@§œˆ‡Ô1ðÊã»ÛË™}ƒÅÞÈÆûS ì‘ é8\è.÷[÷ÑŽrŽ“°¦RÓHßÁdÝss¡1®Æ¬­×�½ØÖú¨÷/�“5˜º™!á‹S3ªqTÊÞÒ¨3è8zxå 9ýÓb[cèJsÉ\£‰Ùz«�5‚ã=ïyÃñÈÏzÄñ÷èŽw¾ãÛŽû‰—¿þ뿮ǎnž‰¯ë ‘;ô¥ �©½ù—’³ÎÜÐÚ×Çžã”?a$�®#õ2ÇJ†ë’�¹ÿÎß|¼ï}¢<¹ ~~4006øÅ—H³þÞoŽ>{ˆ&¡¥v:3‚§:róÈ{zê‡<˜6ÏApý?µ§ö\ûÜîF9&ÚCÔòŽ;nMÞñúù–Ç=dk ?Zx‹ºóë <ÅÐkAO£ÈùT[Æ| uà\ÆÞè~@wW­b¨8OŒL�½¡:y_‰«þ¿_TÃϳ& qÅ>pxÕ?þŸŽ?xË[Ž—¼äû�ûëæÛu×�Ÿ® ŠÛFË\x0ÒÆ€}ÈŸûþÚ?ÿ ýÿÌÖÿú¼ý¸—n,‚ÏŸ§³Ç஫ð©sÞñw÷ãÏxúñ7¾Jï>UlêrW5À—¸‹�ƒë Õ¶¼6ê�©ú?z×{Ž7ÿÞ›d(«œ(üA7w\Ë Z¹ëÀ2s©w»4r‰ÔòœÅµ^H}³ÙÚXõÚË:Õb+—9z??{Ú/V5פ.`ÊÏ{„uÑœ½ ujcÜúx¡'Å‘µ»1¶ŸööJʾ²Å\ý8wϪ`öElª”ƒPüÕÆ‡ªÑòôŸ\öZö:%S[bèŠ52×FºÖbïÇÅ]q!‘ó�ù¡`Ãѵ笸&’çœ2õg.aâEïó놈³>Ù‡™;†0’™0õݺ¶¦¬)úr²~ðáž±oãÑçõìp�bޱ7Üw>€Æ,u¾ô‡qûµM÷µ/ew=q]»Õ0Xƒ^"bLÎå´tð5˜»†ñ^7°õ�¡1²Á´Á¶— ºê îHsP/wrÅ?k`¦Xbu¶™¦.뾩È{nœC*€yšŒó}Ö A�Ì#¸ñ‡ž/J;'­b]í—µpžÖ»¶Õr®äùžä•ÑÚä#K~äæ© û65Êþ³zèx¾¦~ô<Çœq’‹‘ú\ËL¢}ÿH42Fi]�UKøª®Q€îs¾†Évlxžr¼f½†n´p%ãJ¨CÆgœsîšc=kJñàHMó|îAÖýA¡º¶Ä‡×uwºéÅ©à„íƒ5¦%J_ò®ö»Æþ�Ò?×å€ óζòLÐ od’tÁ.‹*c5?S?ru²ŽØq+Ø’ÇG¼m»¿�®úbhÿ’ƬÀ…ÊE`/F´55OäÙt%µõ ÕX—;ôà� � v/¼,Üè8 BÙTì©ö‘Z0¸E”üô+[ËA|N¸^›ºJ̓ÒHLE‚è›Ú2#»¦‰�ec™’–�ìZCtv3 l|É|ÁßEl‚üI3¾ˆ›§¯í.ÆŽ{W^á‚&5Õ—¨¾$ÇüÎíô‹î4òš5×cg(ßÙ]’«:ÇŸ` ý.ã/íÂ…oyž{ƒúïòŒ«×l=v�å±È�7¯¼¸;Vêœ]ïÇÎàWN”bíã«2t¼h^_䣉Zñób§'·¬gê#¤|ÇŽx% dÃÌsÌyÌÓ»iÌÉ=8;'àr"¯íÎ)ÎÅgvbæ rðkøŸêáBq¯´Ö¢bΕg>‘®ºŒÑ]q¬?ýUÌ]×q×¹XÍ¿úÿTïwÙøÉ2k‰mc’!ç@ZÖ€QÏÁŒc›5Ž]9 kîàËcÖP?Öc·í P–ŸŒ±ó�xp‘Sü%œ´ìÕ@ïL^Ü˻Ө+?áP¼@¹´FÎÅõ"ÄìWÌ8Ð馵àK¢Þdoú“‰cd]8टÉÉ×0ô�¾-&äÄ5 ¬Á瑘ØQo÷NByéS®fo²N`þ¿o~ãñÄ'?ýøñû‘ã¡y°ð87'íøZÝŒ¾�FÔBù0ÇžwÑé ?=Võ�–Ç5”nb£!×¶k§&K†™zJºäã �£=ù�i’y­äCÏc¹sÜXö&õJå\lóáD—×LÅØûƇ£Q ŽØÐj‹Ì�‡+\®Úä9?‡úΞó¶œ[¹«và¶…‹â׸Šé‹‰:¬Oóž\Ê#xÎVżÖçtÅ9½³^å¿]{EOü‰…UãÕã®t•5v}G­‹8ÖÎXâ*Aaï²ßMŒ Òÿ�ÏtòHœòÃæ®Æ\gDŽþ.b ¡â6œì§ó¹VU\hË&ÓìSËuX‹¾ûæä^SKíIÏÁÚb0¥5Vf™3./Æ­ã‰}åØÜ©­d¤™¼°Ù†ÎKàÚ�Ô"×éØ\å„loÕïñ›cñ] M˜×~f†ªïÕ<÷yím«Úq®œeM’-Ÿ*ëgçÒrœRœË-öÌÃW½ÎÇ~íïó´-9l¸¶´Ì¹ÏÚs-P´�à ›«óÙ¸D‘S§Ì*[„V6h.‘c‹Œvò:çç9™ ‚»éĴЖo d˜™3ž"¶.vò¡6àLÌbÔÈX™ ò³Ú`¯Ìöž×ráRC�Ï}E½ülx'›‘Úvù_¬::äW{‰,£??K¸ü4êuË~Ά÷Øo½s·:Ýô…¸}8oý¬‹_Âw�Ã(3ö6ÇŸ÷k =0ðE9ÍcbÁÌñN-|1Rã1ó&,)Ä”áôÙÈS.ðyµiÎ/5x!e©/z’;1–%vòÙ}[/ÓFÇ`šcÊ›ka7ùÓr /+á3y£ïŸB€´l¥w,0Ttÿo(Œ§­úLŒ^Ì™|±›³lÀí ß~BckĬ1øc›Ô9ÜÁ0o~c‚ÝÖüd¨x½`ă2ìv—ù�:_Ð+æYÉ3)˜ûkÆË�_ôãO|t­�†å@I¸éMóŸy©—‹> ã‹hêÁpš$’r¤i¬Eöþ!–¥‰�:7¶ÅÌŽG…ˆƒZM„»?¦>.Î$Ñ}8)9\ %Ažá;ï&µ©¶ØéÉ‹"ï=©jeˆ˜Ú– c\.Î#Ù-yf\ïq VË{Èøp¬(sVuÇh<Ñ÷¬EíÇ’¨ ñ�hö�¨� †XŒ¿1®‚è;�{b¨�oŒÍÕƒCXT´äçAœh OCÚ8ã~b)"ÌCµ+ ¡cÍZ¼0\pÄ[¾Záb¿¥}¬t4‘ÙÁ8ÀK6 ‘RgöV/Ès’ÌÌe¸à¹Z€†ÖpÇF?Pi�½ÝˆE}ª3X\iãhnS‹ó¹HÊ9 ‡¦ð¦Œvƒ¶â°ƒÌÁà>8ˆëŽÞƉËŒ[Y^À6>¶¬x³…Ìì1¢e]îæOÌÕ‡Uè][ÜÈ1Ç@;÷µ'%+âð˜s3±ÛµÇœˆÏ5\Ú¸nNTïÞ’î¶ãÖãmïxÇñ·ÿøãÑŸóèãÆïy�>¼âáz7Ò=Ͷ”®çÑ¡‹4qŸñÇ9rãäž÷¸áxøÃþìñ}ßûÜãiO~ÂñòWüÜñË¿üúõ‚Üç%É»ŠÜˆéò‰OŽì'n†S÷Iì½Vó]åèºC\Û©Ï�ıBj¯™n„`C£VpðyŒë€‘[+Ÿ÷}àý~ Û¸õÐÄú@œªmÆÁþÝß{Ëñ[¿õ[~@q¥A<ž{ˆÕ56gé~8ì½#\ßì?ù·Ùñå�dæÏžÓÓÚõ×äbÚØÛE+%ß`ý sI„Íó‹Ï9s}±8ym !3öã^s_C¸‡[³Å²]Íõ•Ç#�qu±ó/Ÿ©…|²§“�Ÿà§´ ÝŒ;ëá<"v^ظÆÂö¸úž£·³¨mpóÚ«šó%¾´Ûn»õ¸E*ûøoyÊñ_ñ׎‡>èAºay½ß ˆ7¯× ÒëÔ_«wòKOn.óÉÛÿò_üæñ›ÿú_×êÆ7Þn¿íczèÃeØc“¼y~¸‡n~ë·>óxìW~Ùñ‰Ÿø þ°ÖËf“︬üœzu)¿ëãu†¼šÇ²¡¿Eï‚|ã›Þì_¼WïDÈyÎ _cxÈÁ¸bé‚Ëtâx�ú¼RrRÕÆˆ`â—úUg¿ÑŸëbFZ!§2Ä›pÍ/nÔs¿Í7k™$>»m(F¨ÙZçb�¦ÌsŽÜ¼f“]ò‘Ó8ðîMâôœ?p1†“¬Ì¹î� IDAT„×XÎÁa®à4&&äÛ…[ì40_åµl5ðXæ^ÙLx`V³Ž™ÃTûOŽ<.8?º–6B8Ïc²òŠŒL“äDÔi.|‰l‹ “b2§aK/9¹ø¹11wÁ°Óøü%�j9p7´mÁÉËë‹P "Ãó\Nä>þáŒ;|º†&£ ÄÑVƵ. ôV�‹ÏŠ1<͵|»nlH™NÞ䜵Ô} ÛÄ× $+Ù)@¼ðnà $—/ÅÃÊ×&^mÍ#´uâ�/Ž"Ý ÿü›oÛ¨£5>bÚÎ˦’í½�.$BP\ï)âKçZ‰Gžÿñ˜Ú(©­ÍèÇyü$X…~Å_q#?1†áØÅ=ëÛüè›Gk g ld4gÌO›}´�à6Û"öc`ß+ã…1J0EƒÛ¼ {Šáu&ã¹k†£Zyz<óÖØ}ÓŸkAÜä�Šf,åÂýÏu˜0èhäÔ„¹�§ÝFUJÙð\82|Ùx–ön3(wËd»Ç³éÔûªÜ˜Ž3x²ñ`*>�;V G¸Í5A8$§P’sM']À“#›Ö8;8cÉMýpd7¥W�g¾|Î<¸ñõ.‚ÄŸçb·‰�ý+ɈÑ]ד‚/¦‘pÇ‘L$MFn‚æ^42ž&ÊDúÓ,SÀš©ž–ÙGž”Ö<ñ[½OÌÂÓ½/eÝÍWÇÌmd”æ¨BQš»­¢ù‚ÖäÂ&vqºØ\pÖ—Ÿx©™Lið ›3׎ÛSO¹Æ@Ârl}�!9OvüV±O6°Á¯õ2ÍÀ5‹ ¼—�bå‰w”ê¼éññ&q¸K»ÁÁý4êä ­wnbŒžÆÇ6S7÷}¬Ø`Ë_¾®#õÀ•X ÷ɘ±kèA8ÙmK�7ýs;?¡ŠköÉÆó “Ÿi—3A¦\|¤ _J|“¦Á ¿“#Ucb•3¼àËzóBq[ãoóèÜûDK³ ÃÚ¹O¼Šc /åFpÙÄ� ‡<½¤ƒ#6ÝKĵ 8ð?³ÐÀ¶>!M�^¬aËwìx²O]ƒ�1ÞýŽ•¸2]özeÙMÌÌgðvž¼ÐDçÇ·k ç!ŠŸ¾æéüB~a1.‘qÌŸ•i0mÇÌØ9É4\�ÑNT"B׋õÆ6ûrê’WçøŸø=_T{b6ά“§õ­uæ—ø{¼ì‹yN1sΕ¬ejÙøˆ“jÏz]æÈ<|é—b5»©ßýZ7tm+R—½{˜/|EOÀ:Ìy(ØEJLYyÍ«k¬Î±F–ÇXHÉ#Ñ9X€ç/µGŒ$Õ�´5@7ö‡þ7™oè$åw^Á}ËÙî ŒÐ½prÞS?Ðð^÷ùü©Ïg®E}o¥.wÓ§ÿßÇãþÖ7è�€Ÿ}üíï{Ññ¨?ÿ™~_nÀÃ@€míŠ HD¯�çcCÌ{Üp÷ã3t#ðû_ôüãO}Òñ3zGàM¯}�o¦ø"dl{¾ c߀Ѻåݺ1ôM'Ù$^j›óÉ‹çp;ºÑáOS '´4*^|fçz;Q<ö471áš‹üàä¡/ž¥Ó��ÖO¸°§|ÄäÏ-ŸþÌg»ùOu³HïúRŒÛuc©7:±á‡Çq¯iˆ}Ù”£n÷Æ)7žŠœ˜ß& Ý’Ò_[gÙ8ÁÙ” <ü°±HóÛtÓŠÇ *scOÂS¸ý4eì5uCÞ:ˆÚÖÆ`$¾nÑ>OçknÓ™SëE­ÃJ˜èu�¨){Ñælos�¬÷}ï{ßãYÏú¶ã+¿ü/÷»ß}¯ü�Îm¿�Œ’ s‚omJaáN˜Ü|ó-Çoÿ»ÿçxÒ“Ÿì›“¬Ižcˆ!ÎÔ[ Ü:ûð<ï�&(ûcÉH\ÁÉ›V®:cï¡,4¶åv]}Œå˜Ø`Í~Ñž—ÌkfiäÅßç\äS,fÔÝ�_{ªq̰¶ážó;ºâKNnäœ/ü‚•ój~A¶®…&F¹dŸœ¸ø†I€9š—úÓ›jN;Dbn¨Ú¾3\Ôö¸ÈŽ[ðÜĦá‰f8)ÇÄjÄÎ[#Öî’Ëòu€bÑo\5 5ðÐðØé>Øñ/¼ó¸ÒÂy-8EÌ2!8ç5Xb�r¢p–gÙÂ]ëan#)hÅÄ7±©k´“‹:dˆá‚�Ÿk%äÜ‚((9:Ž$ì%bgŽ�¦N=ësÙKk lѤ~§Mäç±Løå×&»öeüN‰›zz}ˆéXzÂ{Þ2Ì�ßdŸôœes?û‰>�Z Îɪ朣ý(´ÿYÂÇI´ÜÒ‡£U’"ËÚÌYR3”©inßÁÁ÷‚_ç(j«þv®\Ë<·@âÜS˜Æy 9/ì;ŸýhHûõ— æ„MãlÞðŠXXÕÑÛ0¦\‘s÷úÝæ—€<¾¿À…0èë~J.—µ°Ý8e­9|Z7ìW‘ÙååµôŠëwH+!þ]LøËg6“yd „æ¨Ï;èSÕ¨÷œšK4â:\<§H.çì:pT_ãMïåpZß}¾D¼ÇÈêÔ::!n£.—Õ[.;}%ä™Ió[’îpnüµõuòì78N²¶g&.‰Ÿû}¬ PJZ ÎD^² 0E² Éêˆ|'¦ñÙ Ò'%´™ÙÏW~3¹¡‰ËœïâºÀv;y­¸²�F6z Ï7xŸ2ò¹|«mtÉ; …¤¾Œ³xS]HYfÞf®#üW½ðšÔtÆ+Q¬lŸc Š�Â<¤Ü_ô§¶çû\£äm¸`R¿Y' äR›Ã0ɳ¸®TÔjç’`pPóúŒ�ŒeÓ˜¹Öã‡ÎþÈuaVn—u ú­�ݦqølÒ�xc8îVñá„6íÜ\Çý]ÉëÓX6/'/Éäé~ÛÇQóØ™PqÀÎ8aBÏãæ‹Ob3ʘ€åž©Ë8�ÚºÖšdß$¤ë# ¾æÌah”¾±¨z9Mí,Ç\òð ZíÈÅRb!/‡ì#ì¥Ð©ûåã4¶A=�ÃGŽÜÌ£Y·"ÅòRæÝ½ y¦äà¼RO×p]›1mw朘ñõ²á¯3[âè IÅY±¼ÌÃáôHÝN;èÇ¡²ŸˆÑæñu]zRƒ‹ž:ž•(Ná²ÉÇnƒSšqýOèԻ˺bQôäÅù�«žR×'¶ª‡]6LñÈšÃ_cjw =TУ;cŽÂ�—¶–[ .Àt~½SBêb-Ä\?uÔ&>¢·h` _¹X‹Ò²8ÇußÖ�çyÞQe»â‘³l|cP¾À^ü€gŸ»oÔ'Ò~Ó¾Yï|Ìñ‚ç?wÝô/¿Æ×\›®ú"Ë^4UµÒŸF\)oàFàg<ôøÞŸ£�ßr¼âçþÑñªW½J7nÉ ;Ùt­¸Ðןìýž\dà$H‘\[c¿Ø‚pòM N,j©cž‹a�4ÂdšÍã±s®¾Ý¸ùG#íïÿ“ãCü°njÞàøØE#åøŒ©,½mdôþ|ðxöso<þä½ïµ/~þÞr�Ë€ás­oÌ,t«„sf×¹y£±Ìf›ùÂKþœÓ7ëX'=~Ü G7u3\±}ÎÁ2pÐWÏC¾ÖÀ¡NÈlàc)1 P²˰ˆÜ2^ìñ8OnôÞã2v�ðÅQ?vã@ûÔâ‰g½`ƒSž¹8†ËÜD’‚›Æ4ÿ‚šÇ·d|eOJ¡ ·«ÈÜ|šc÷/R_¾häÈ‘XŽÇŸ*|ÇÜ\cÝ »{Üã^Çw|Çw_ùW¿Tïø»Ÿ÷|t ©‘Ë ƒ¼Úž´Æ}ì`o;â�1çþôü�ï|—þüü•Çk~ñko$Ç®m¼à™›¡ÔÈë ö€CßS£aãxÍ:1±!w,ðñš Œ�¦�]*BÏ_ðÍãÿ`u?ØFÂØƒ”52ü}Ú¬¡�ÅáÉÍ룩cÐk± Ÿ��1~XÑL=ày9Ú|Ïüâ¸öë>@Nk.œÉ;ku3±\¹ä<&'µÚ¹IFKG´­ÎÁ5‡q\Üà\Ÿ;ÌP6[DŒiÈ[û¬m8XéCr ßÅÅ~¨7Ü�„{øÓï1OÌÄO쌣³µ“ÔHêÝ?9�kY.ØÔåŒ0u? °µ´|[›ÚÁW6ËÌs”p…O!`Ê8ûÕ“UÓÑEè#k_tÁ:k€,>uéµsç)uŸßÌÍ0>Œgñ)NpeÀó®ÎÛžùÊÍZ¸H^Jšµ®™9þ¸Ë¹¦F›@…_÷�M%µê­vE°ÈÕÖØáÐñL¥ŸDÇÏI6Žzæú%ñŒ¬Ñ`M¬óÜ.¬¨Æ�댳œúË>s‰Ò5îÿæ=+Ö¼é['G?ÿKl‹=mˆXÁ×`Æaa:‚ /‡bÙÿ ¥¼�~Ž‘áeóº;ñâ‡ï/ž[â„Vœ¿ü'ÆGS�„qÁaü×™¡__æW{£–'14–¯ÝKk°ÐÙ¿sõÎSÀÎŽè´×“º•Žˆ¡~ꪙã`Ç�¹� ]Bsœ8i#‰|ŽÖ`ÀOâj¶ëƒ¹µ]âÖzf&�ð-�Œ]Öåëø®‰   àêƒ$c‰øJ®Î,é�øæ�óÙš—×ì{T®LÇ“­6»¿eæ—™¹¿Ý®±‹a@`·µhVØÔ×ùÛ8‡«ÜŠ»LÀ¤~¡1üÀÔ¬ñWŒÚáâºã·`;¹-Ïú¹úš›þØãÕùÉûwæãã¸á€ÕÜg¯¸¨Õp�U÷”e:b~Vž˜ÛØ ß˜¥.X.OÞgާ%œNù¢ÖxÉå §–sB®¹ë,{ôøàN,¾"@äeÞÖqƒ­qdÆZK»Õ§ê±ÁgTîð£–:xN’û¨/Î1€œöøL3ö¹_’ :G®Õnì1ae~™9z ÈÒ³zâð$‡ø0K-ÂÑr©!µb–µž‰lá/X%1<;]ÕÙöÚˆ«Ÿ® ýZ«Ëž"ìNÌ“²rWÕá”uõòŽ" Çx¢2…˜ÑL•4á;ûºØeå=Öî =XÁŽu±KÞröwH|ÇÑ:¶FŽc˜ø’$_eXýêÁ›G®ñ¿Ñ›$4¡’ê‚‹¥ùoø€yÍñýûï�ßøø'ÿû¿ù?�}ø#¶kÝ]ßÁ‚9›')òC}&s¬�zÞøÐ‡>è¸ñùÏ>~åõ¿t<ù[žª?sÔDÓUuÞ5Ÿ®=Ís¯QžO‰çßÈÆ|Õu¦îì³üƒ‚Âä{é’ 7tÀ¬Ÿó@êÅŸN~×snÔ;'ÇèpkßíÝÜÕ»FòAÄM†[n¹íxÿû?xüè�ýäñoÿíoK¡ÀRæF“ÖAAûf‹½xæì™y†£k¤:À±{©|±…³ožh`Û‘�è}Å ÛjvöóÎ/G§˜:öi㛉R°÷b]â‚ðÌ©îd­e# ¾ Œ¹Ý舫rÐã_¶}¼€»ãÓØ+ÎÈЙ� ÊXÔ†wšÐ÷q”úàÁa†°€‡ŽÖIÿ›Ž]{òÜšƒ€C|ÖÌ!i~Ÿ{Ý÷øÞ¾èxÝM¯>þë¿ù5ÇðIz7VlZóqˆW ”¾2õ~,(ÀZcÉnÓþãÿ¾õ?¼ýxñþÐñU_ýuÇ«^ÍM÷¼uÞ‘±8±Õ¹Ñ�ågÕ!›kuŒ°Ã:øü©Ü)Op¦F¶ bür½Ïg¾<’ñð÷s«ÆDmC²5ë¹Ç7[â�vó�¡_àãžÔjêË<|ö}Iôx1ŠáЊo=vlÇ·�H’sÎÊãuÝØ4"|Â㬣,‡‘Ê—>1ÁÆÞ¾)—ybZ¯xpNºØñÓVß™WÇñÁ7�G|�#»ði5ÄIBÓÙ¹$9T¬=”E±’ƆiŸày¿ÅaŽÈ£»ÄF}Ìöáæ¡ò“Sêvrk�–ye©þÄ<»—½åÌ’ˆŒ4+˜�! dÖWÖµ=MZ›bGDõ‚ðu*ÙjŒÒ½&3�z‚;G°Œ^S÷„ãYW‡dâRC|9ïœ5’�[|M…¡#¨óxðä·Bmø±ñ@ËTò¬gàãy˜˜0u% zâZ?ñ°Cá�®xò›l4‹ÖÜš°úÆ£µ ÿèbŠoüc³qp‘Ù'ñ?ãA`ò§o,„ún3×á_™õõ·“`ݳãÅ;Ç)ÞØÇ"�kûHž¾€òÄgü‚� »ÁßÉ� ãH·j‡]ãžDã½ð£¨é­cy§£máã:ŽZx†”¹iÙÞÔãlÎOÓ‹¼G ¶ýÝ3Ž�cN®ËÑyãKþꈃnùMìe'’Æ\¯6ó²pX;7Põ)À5F’^ÿ `Ù+Èܨ³Ý89°«¢ÌÇeÈw&Ìj‰ AŸT¤sP(^ ûêmr…]½ly¦ŒY �,` 3ËS‚ê}ã �›·q'¼;ÁáïÍ©Y èAÌÍ×éK(0¡Ç@Ã1ÂÖ"5°©mu],QpÝÖ|\Qàø¦Ùø K57o?äã¸0%s\óý$9ÊIœý[—©ñܦ;' ÅŸ½™‚áà¡ýe7Ë7ª6þ�ÁTcbóâTøÜ¹Yãšx1Û¢ÞÛ¦ Ú`nò N»ï–4ßEÔº¹{�zñ8ØgUމ[R l4Êm\\×€¸vÛ£/@ëŒ�ÝDqg<�FÈúµ�5{K#}wï„[8;nÉ?{±k³~3E˜¥Oœà\>à;8Gâ9 ×xí9kÐÙP‡±�»¥´òÀcÏ_¿�Þáì}F»´oL9(‘¬'цµd-–g­ê§øº(v&®©Ÿš2“ä ¦}ZŽÄÚsÂ),ÆÇ �9üÔ1jë4àÓÎÇÕ2nB2œå€ZÀ8/„NÝ­[vÙÇÊ/üPX™B¬ChЖ²MNrXùx?y^Ècg‹‘‹9zj¥—º¶ä´dÙaêƒMœ‰ë*ÿé‰þ,Ó¨üŽMÿÐúwÞø¦ã‰OzÒñÈÏü¬ãE/¼ñxÔ£>ó¸·þG 7K FÒÊh; “Z9¶Fïó‘dp÷»_üÙ‡~êñ]ßù­Çÿ¸ãçÿÇÿåø…_ø½Sé£>¥R2Hóü^ßESHd~‘€h®±=foÈ€ZógŸØž­6Ö�çÔ<±Ï¾;o”p^¼Uÿîßü¿}|ã7=þxðCz<ç;¿óø’/ùÂãî{½s+ÿZ€5»UnóÞ÷¾_ÿgí÷�7¼á Ç?ÓÏ»ÞõGè=ÎM-žûDŒ8½ù—œIŽü¤V¬Fj=yq—ÞïF“_¬%­7«˜¹®%¬�ƒ”Õ# 'l= �¢/ÇrGF|8GÃi(¶Ö©}%¿ÐÚÍ@Ò°‹³2u?ã†CçÄ�rU†O8!£¾<&0ð÷اR‘à�H`˜§úȤà[ëZ|?åKÆÿóóyu¾yå='{ (ÿùºN<æ¡ùݯ¿áxþ÷>ïøË_ü—ŽOПúö]¦ŽNLÚÕ>ÒäT}mF·x‹,ûécÚ«ï|ç»�W¼òçŽ×¼æ¦ãOõ¸×{@}þšXÔ!5"Q?ÿ#ÓûH·¦ö¬ã ÷cNþJ“æsÕpÏ߯¶Öq¡#†Ç€MËðÜ»p ó, Û�;‹?ÙÙ Ä) YãÌ—Ô@ZSd:Ðs$gÆá“Øe}ì¢Cp>>©Íuó9$ç.ï¼¥Ã"�ù³×H0 BÆÌ:ǖ֞诼C¿ºÉÎXä�“ãb5œ±Gd%Y¬9rûMô8Ž óñÍõD*P‚è£@Ã>Œá“¾˜„èõ?Îõ·¡kÇ]žŽÄ´_cY]”Ø¶Š™qTP?ž\œ¿äæg½Ìî&xzÎÀßX�<ºsm¿}íˆ+§Â¶»98ŽÇb$»Ô§4Ï%ïuÁÕk,8t]\µÁØën\�’Žjt«·P‡3ö>DÛ\¨ïª�ç�Tƒ08(€µ§�³7Ÿ{Ä:ß¹ÇZÂà›uÔwÚ8(~•Wã°k"­Ç²$®+Wuå´àNÚ%æ|è:V¸©‰Mìá<¼ï<=ã1-Õ§(Šc~µÞ–Mu…óλkX¶áE‰kϽcàl¿¤ÔÉ챇‚9Ä$±Ÿg:û¢×?ß‚«çïÅ{aHÓ‡€¸# 5ÐÜ y+N¯6›º#·’ÃÅ<þ»&ž¶ XÊ jð‘ÅŠ8³UH„j뱬/¹ïñWÎqÅÙAº`�‹šÇ²ùŠ‹s·pjÇØz 9¬æ-æ¾'ÌÄ’ õ/ô4熎IÜ��z�/BãR¯i‹§æk,µ×U€‰££e4CÜOÆ™q,§lZ? 0—ë\tÉȱÀ4žv×�áÆwaT¶ç_èpTÛ}ÁDÏfÏ Í豫½}ds>q‡0 “ { z€7O’5ÆÝ²1Ðü‚êòu(Œq÷Ä®ì©àëZØ®>¼;€ËIÁHØ—O:†©OÜl·8&ìD£–pÉ´1‰»·e#ñÉ){¾û{ìÚ‚ ¢ì„O|—ÉVö]âWrZ±/€ƒB]iûÅ=óÈñÑ0À÷â'÷h[¬iyÑ,Žö×aÇ1ž<¤ô‹xé.1ËžU×çñ€.Ìä~Ô…§…oÍqh5/ùÂÅæKo÷íà;Û�Áüª®nç“Nò±-JM}“Åã©‘dÎ5ðÒ°¦1î‹üÚ¢“12uøf}¡�5nrVa,‹À~æ1kLLiFê$¢S(ã\›a5aÀà XsBs¹†`n¥~Ø�ïpc­Rc^xÏcÉ8t-íFÓÈû\åSiêbtÁ“·ý±‡'MÝv�›ØÞwuÄ¡¾Ã¾`p�ÐOÚäFØïþÞïO~ÚS�‡}ÆÃôn¥�ÏýœÏ>o6EùÁc¦á0\N¡2h àÙZÝ �Ÿú©Ÿ|<û¿ýÖ㛿ñqÇÿüꛎŸÿþÑñ‘Ø e}AÇ'Ï)¾i"€ÞÐZÿVŽpÑOëã{–+O0Àª^tG‡˜µñMNÈŽMÔŽ/Êy«„ø¶?<žó¼ç|àŸ9ž÷œç_ôE_p\¯\ø¿…ÿú·þÝñ’—üÝã�ßón­G° à$Tg­IÖƒ|hȲ†tvÁÆò‰»ä©7;ª9&'—ÞÌAL>Å<÷ µ¿hšŸ¢YKuåÖ8­/8ö=McµÉ½JÆi‹·õ䡺ó©%²å‹fϺª(¥d�”U%†]Æ)ã)g !ë®;ÚÄD£ùAŽ qXŸ¾£/¹K¨o7ì]Æwèqo¿¨fÍrN4¶ö ÿ�‘vÏ{Üûxö³¿óøÒ/þÂã>÷¹Wþ·¤oZ½òóu$VëŽÎó!³�q@³þïå;ÞñnèΫõ'öwðà Ÿyìð؇QXiìyd¤ØzøÅ‚â8mðãÇŽš[3—x�à:Œ2�½n#³~‹­a|ì0yb[ úiÛ0ø›‘cÈήUË:Ò÷qbñ:œ5•½l ìç§ ì§•Dè}~W;¤vÄQ“©­9Ø(¾¶A­iòÄ[fÂõªXR{²Ä{ZjÀžÍ/òúðÌ-Vcl‡x®+†%=qãŸµÖØ|ƒ­ðÌ^A•_~ŒÜ¼±Ý8³o¦ûgåêÜÈGöqY}ãLdw˜™'ÆØÓ ;m‰ô¸dM˜cßk@̨!»q�‘Z(ïÔî_,¡Ó½I‡îà{¿Ä\†Ü�—vð3À¿ mròП授dïïú¥îáÁxbØ;ÇÄÉ $ 0¬Ä‚5· Zù3e¬Ÿ" nKý0ˆ_ÏMæ-ÏÙmè ¥~NI6æ‰BmßHž¸ž%ÌØš”Ç/8Äðk)y�E÷fYu°áÛ]ö¶>¤5ÎUÆ`t¼°k7¶9OK‹Ümã³ÙžùÖŽ^ Ëo—K²â ª0ÕW¹$7j±9ÏðÜOƒ·Û�¿ðÜ®Ú;ÆFGsâÑŠÙ1â>×"êµ4¾}G†û±cê =Myú!B)XGdôäïáÈ–SXgpXÚ^Âr)Cø`ù�Á�u^–­¼†:ê/s¬�Î9¼ Î\l“àZZ;‰£Á(X^;„Ó‚Áb‚£/0jÔ¾1¥Ð‡€ÄéÂHN�¥U__÷‹Ø0µChôPà[ÓJ êê‘%Ú ÆnÉÀb´kÙIá„ŧºøÅ™óAÛø»óÒ‡'ªâ¸vËTª‹1õò‚Ëæ ¤æ]T[æàœÐŒ55Ô°ÄÍDÀ›'šmÔ#ãÇRù‚ÕEÇ.¹2"Ya˜ –q z¨”‡�¬Ç'˜ž®ƒcâÔVW£�pÔËv3ßù¯ÞÒoxæ!ç¡xî…É #1’Ñxƒµ­ IDAT¦©L`uI}êEnWx/¿Ù¨å¾ü6Ž“e¢;µG|¡_žÈwžP˜® ›Þ,ˆ=~JËoÒZz[‰C ª'ÇŽncjjŽvŒ�Mœ´ì©…1À&¥÷~´îíoÅb…o9�‹]4 ãU\ÞüŒëH:ÄﬥØJß\2\ðeÞZ3)WÇ#×q¶ Œ�9ŠŽùNH«—«­uî¹xd ±“=>ö³“#/¾Á lhy÷HÆ€$×€ab®\¤Šˆ×Š –ZÄsÀÆ> îÑ™�™‰qÚ°\ l‰9F|WC|ÜN=õ­ÇéR¬ÇǼ3w–g=fÈ|�q‚ÅÓ0ÝIš°?7#7Tyb!™q5&ûÒ©â¹¹žW¸}�V¿8Ô¯1‹›<¹Ø"trA—µábŸ–ºÙ"s[[ÁA?±ëÅ‘g)Æz.0 ¨ð|à1Ö9�%?¥p•¤2²ôqS?|è=ÔÁ¸º âæ3kù{o~óñ´§?ãø,}XÈó¾û9Ççü…Ï:îuï{æ&Hàp8ÈQÍ¢Ê88 ;VOlÞøàÊñíÏzêñ�ßð7�×¾îWŽ—¿üåú3äZÏþ€úñá pôu†óD&9ëÆ Þ�LJkì­yî2ƽøÏ88» û MÐá�@±Ø+ïùã÷/¸ñ{ÄÿÅ·[o÷»óªLs/?½ºÔ«>ÈÀ0†wÍ•#1¨9Lü¸D 6�ó£töµœµ¬MûàÖÇÎR‰îÂIJ8À¥Å?\Â!¶´ƒ_ƒ3¢øeo3¾¬sä9Ÿáüôy|ä2Fr‘³þî%j’WÄ~|¸�GÇ•ÓË­ÿïÎøãn±39‘·›&!ný‹W]ÊÕëUkÎy2ç®;±kŽûßÿ�Çw?绎ÿü/}þq_½SôZ}¸“é“ëpizÖ,<˜žk�íuê2âÃ=>vüѽçøÉŸþ™ãu¿ôOŽ�~ìf«®Õ;zýHþasæÜ¤=Fñ¨'}ñqn\0FÆ<Œ3³Ó¸¨»Ó;„õh_Ù¤Nœ_õX�-áéi+gÉäaÛ=çàô¸ô3ÆIä’ïÇN:87züsR“2ƒÍÎ/õ¢©Oø6�ƒyþÄ»-Ñ X‘cKÞp–ŸõöTê°ÐÌõ�ó‰­ äßP�ÒѲ‰)8£;ýÀI,ûBcáe"YÞçÀxÉÏÊ3vpë×£XÒ­k"Åm¨ô Mfcï~ÇIúp½šƒc4?¹€éshƒ ¦k �ýÚ¹Ïõ¶q¦&€4Ks‚¸r0¾ë’ê®<\¨8K†où…¸{rJB�ùYBz�ÆÌ+:< <¶ñБA! � Ü¡6f ÃmbX!%ç1uÄ]{`aá5av™Æ©�å„£†æ®Ø~—1 «I+¹×gdñÃ&�9¿‹É.çÞÁ4©œ2›œ‡Ä,f9N¿×ص”�9Ž}(¶0Sñœk;‡©mûƘyñÚ[ŒãØ­½2koN˜.›:án2Á©žjŒÓŠ;×Ô£nù+tëåØá°Dæ‚=±Ž4se õÕÇpÇPp<$ÔÆT>ˆ‚œÝ¦XØasÅýb.0„ÛɧÈ6ü²&0by ¿\óIgu↙|•ˆó×õן«öŽ&yÆ„7­5Ûv~luÀÝù®\¶yLIÓiõ^Aòåúá'37°zc±ºÅY:SÅRxוI y.´wÖØÐ&XoøYFQPÍå�é¬Â6ö´ú0¶Œ %ÛýŠA2'Œá4|ïÔ® H†áèŽSÕKYâ¬9®GÏLñcãânq091º8„œG® q5ÛjOà†¥u€Më…J,â‹ë} óš8¶è ¥[ñ5Ýí­—œøRûrC·êwW~vî�„0Ò=M}2l¿Ù ΘšƒúzØšb€2­¥DFýÇXÚSò�©w§Æ¸ábP?\› @æÕeíã«‹þ%F±�‹…ZcW¢ÆDí|Єe˜Új2«±5w϶Cíc%.TGH'Çs-ÀRõSïõРë0ÐÝ+æäG‘ÿ¯¤±s—ÖIЮÍï<ãâ·�—°\—…�/Òéƒ9À×öd*“Œk�Žqn,4÷È$$žv@ïTàÃ`¤:A¢É,'î…\R�"ËlæðZqUt@3.aäU3ªÕðoèp¦±'�ÑÇ!ñ'fò±½@è f¶IºÖLÌ“‚ÄœœV"šÇl0šÉY¯€ÅÏüë`…*#—憨Ðg ©¸ T[ìâk 8&ü`$ær•±–qáƒòÒ¯ØWååHœŒÃej<1Ñš=ç#’rm.É3–^.<„Å{€±·&j¢Ž©/J,– å =LøpróoÖåàû*2YoØž·Ó ´žò‚Ÿš¾IòŒg=ëøôOû´ã{^ð‚ã1�þó~G ñ&+ÓOа¸`È‘Ñ�-ñИ¬î~÷ëŽOùäOyÒ7_ÿµ_}üÒëõxéKB7Õnö� ¿ƒ÷hÁù�ßs@LJ5\ã\87î®÷œ QÙô1MµÄᵿ{3L8ØVrÉ —áäŠ ÍYæ¾ #¨œs‰:_«.ï¬I±ÐÒ|„ŒFâ¸2+?*gÂRçŒØ1æÓ§[_dŠ,ùi0Ñi�$ôe×ä…­™x.4MZך”é~Á‡JP:I0ê †oœ ¤ëÌg¬†�7êHÖVÎû|ôYÏ0Ëu“�åŒÕ%‡Tè¬ü²¸À“?/F‘ÜÔÕ·øçÆÏýï÷ÀãÆ¾àøÂ/xôqŸ{ëº)íZ§»äúv=)U×éTÇ 6–kÂMŽ[o¹õxû;Þ¥¯8~ñ5¯ÑãŸÜdT¥ôs«>ÑÙû '�gŸ½ÉXE^9™ˆðáb6øAÚþAÄzL-¤ÛY�.Å•­D‰� %¢Øe/Ÿst¶×؃µïo|r£Ç�tÀnrÜÄ·Ê8±ñQçÓ°¥dÁ'FmÃ;ìFænç¹VBƒIÈ=d«£ß&cvÉ}|Â(ó¬ÕެÓwªmÒ7’ür‚YÑé!s4Ï+Nê!0Û �]NŽYCÕÅê'6Žlz:è=Š1µL�™�'ѧO¨½M4kÌØiêÆãð¤»qP„¼û2v×/äˆ^SÉ�3LÒæy0F;>,7ÛhÓ%?ÁM¯žÝà—…#׊ðq°~É�«á#õY æSÓ©ó�ø9¦Ò/[B‡NþöÑ$µ¦S4Ù¾‡¬…”ù66:p–b"‹2:�³‚mˈÏcÞÏâã8,ð�\ÁÅ\Ì9¿ Û‰½d3Oâ‹¿§Ð5€¥j]å _BÓéx‚bì¬Í\Ç ß}n”EivÜJG¬¯ñ å¶ÛûÊ‹;²U Ïc•XÔ( ½þ²^IÆEF$ÌD î¶Ãyd‘[íCò³·kP�å3�×`žó`¸Œ±Á¿j½O´öØ*ÆYC‡•«m€lî3NL[y�3Š=¦áË 2Õa~A‰­Ï}S�òwÝÐá¶â @ümã\ð>[ãXÕë MZn?fŒE&Á*ÞDšÔ�sÝEÍ&”ùê¹û:“#€‚5!jR"­µýÌ*ýù€'åúL©…5�»Z —qƒ>ñ“Ã�f8Dx�:¡$' w¦ßq4N_», >Í}��kÒ(¾ã8Hånx ;cŽ}„¡f³X»–ã“€ƒ™:kC9y¢TëÅ á×rònݤ w7†m'Ç=6¾aÇ(­k‡Oëä½�Œlä2 /\Nóµc–ç Óã‚Sh¯Øõ'g(ØÿÇÓf]ÅÑUäŒqkBB#Þe+–lÝNWMj·î‰Ð7Ö…­&kÙŒ¾ñ´ R�3�ôŽ_<õ#–’ÖQÄl.Z7UyzÔ¹ö"´[ ºØ,(Í‘y%÷ë¬çw¿Ø3:Nþ>Eõf· hrñ�ñù˜¸p“µ'`ðCX#W狥氭S,0Hœ˜¦4ûÅOç¹å…º68R×1P¶’—šñ Ï»%ˆ›–<Íu$é¹/„¢‡«àÆØ�=a'Û`G;Ç•6üã—wí!õIÏdÙW`m,3ó“‘w^Ö©öÞ[\Û…Œó_z9wË{ÇG7©NgrË̓r,³`tF/â^ÿÊZ)òÕä‰dq‰Vóúe3'ÆFƒ�Ì\cï;&©²úŒµo&ŒCDÃ(»6Ø2‡¶4Gr]|GJëS†¾±'‰ �““F~q”s‰ÉktSéÍ¿ÿûÇSžú”ãá„þGà �GëFà}îsïõb _ÇÛ{ÆQ3w¯Ï¹n®)4á¢8×_wÝñÉŸò€ãIOü†ã¿üýø'¿òkÇK_ö2} ï¬wé„çSGÆì[þDøV.È\WÌ †®[jAB>ÌÚÂ.sŽŒƒ¹áƒ½_8ªÏ»œó…x¼Xa=ŠIÌÜà#B¢$rä\keëé%8�±R?KËÄ^ŽÉE±{Ñ3f¥³¦øÑN]ê8BŸêrˆWá@·ÜXüOA}È…šqÔ»B8Ø6óú#ëys¡b7N°3KɨñÈk­ƒÜÛì¢IóÆóÞ´-BÇ�ÞÂm\½EćÄEM „81’�h|a›/ìãcM¨“¿èçqÃ;9¯™šñXyÀ¨Oº~ÁñŸ÷¹Ç½çO}ñ«ùÃú =%ØVQÜèBÝSûG7œoÎÿø{éOþÔñú×ÿÓãæ[nöRÀ/Án÷ÿ¢$ŸÜL=s ¸²”.µI By/¡±o Á %�‚†1?j௨øX(ÁØÑwرáŽ=¡¦Ò2; ÎM¦<.}S@†ÔÕ­þø.!ã¨KynpV§ïd"ˆÇÑ]ÁǼ*õæêÅÅ…Ç&ïöå1™LsŒC8Œ|<üòØp®ŽË¾¤5®2_ÃØZ]ŽcÙ)ùÑN�&ëÝú/{@¶ ?lV,#ô" Ÿàgž#X‰8s¦n9 ¬©ãtÝÊ%ÚÔ§Éw0³Ê�>ñ2×&.{l¹ [ŒƒQao|ò å5g¦¾�bµ6]Ö«~S°;ÿB¶•�¸˜ÒVÍýrÂØFÓGgZì¼:û¬Ÿ�—qZê×ü*�¾~ñ4––×…B` J�ËóÚ„”ý.ì¤_y&ö?uË-vSçõ!ç�ú€/S)‡T ¾P¬\CÙš|0c‚Øq‚ZZÿß^ç&Í ~†m6dïH<öc4ð™ C>ö·�Ô o,r›<ÉyÙÆ(ÐuXIaLj©v‰Åó‡¯=¥ÇÂPœÒì·É±®½cÌÓ²÷GñÒkÎYÍ+½n^†�òg”†]¨g¾Š´ù Y1¯Èá U’tÕÓ»ÂA7Ÿ%é ‚®V¿ÌÖqå�dŠÆÐ1ѼB± ê"IÖ-î…Ææ0™Ù>þ¨h‹3c#¾µ,�+;óL ‰eíVm‘«¹ö2¢÷�ðÊýL,¶û1~ç¢ï'ìš§@‡ÉÈJ͉2ÈåˆMêù¥Í@ g,œ£úú/þÈÿŒ[Üò78Ù6=ÇÝÎsÙ 4½ÿ„µ¶ÕaìÐÖ�™Ó‡�°ŒÅ'¶õÞÖA¢Å7jМ¯q+¯¹ÌÀ!V ´PÝé‹= ËÖ!Š|>A8à â¤` É|¼–)a[<�³N’…�ê™ý´†ä8€ £X@u0#8±}�.ÍûCC{8£Ô…kmö¦§ Üu[r;Ùfñ7êî†ñÆw†¾)‚ÊX³¶xîöµÍ®IUÌÙöñ%7öK3­Ü°ïž¢ÇÜûaÙ5�� >lꇩù9T˜žóZb]Í&þñƒ× 2t­Ðp ëäÈ 2G¯ãÒÍchœ»ßƒ‰/®è·Çø¦ÎAQ ž¦®ƒ'Ù ÎøÚ~®Î€žo)<8ë[yb3þúr]Aˆ¥õÅÚ5`Hõ3�©Z냊qæyìòÂÛ2 éìª8 ”m…²‹·947ï¸Oýéê| �cN}õ*ÛÏýȈå?«7›‰ø–?øƒã)OÚñð‡=üxá�7ñ1�:îÍ»�äg¬Z@H𣮚–˜úfÖ/¼®¿^7?ùÇ¿ùqÇ×~Íc�_ùÕ_?~â'~üxßûßçórnRàÚkóçŽÄϽƼϹk2¼Ûr¼€2çs�EYéÈMÃ}o1Æ…û ¹?ñ°›'ZrÅŽô|ù楙&Çbu pó�i=Adm%\½éœè“ØcÖ^œ©r÷*;öj§ÇÍŒ|z,‰rÝ“ØJD ¾®-4p0æ‡F¼s_àã?�u=æƒTϱâbŸÄIµÇxWš¢{¸ÊzâÝ©�óíÄ`@ÎpB†=Ñ�s°™1Øü¹¯vا?ôáÇóžÿÝÇc>W7Ãõçñ¾±koùãó½w¼Ès£Ýà+¶ÍÅTez‹nüñŽ¿Ÿ~åüòë_|ä£6&{ о!­õñ pøéÇñåK ˜4tÍUŸwòÿÿ0°ÙêÇ]â`�ÖýµìµÞ‰ ¶·!Bù8–HPÇÄgì™ce Ðå/Œ%§¾háõÈŠðà:Sl‡›J–w×b�B¬ûØÀç*ˆCXœ0o ‘ÒŠá›@æÁZÕÇhIX¡y{sj@Ûí³uƒ ›Ô ÑéçÈ:„5ˆ§®ùr®h­‰šFÝ;&¿«9T7yJmì�'ž¹Îyï2'|ÉçÄd˜k�}ÍN懗 =¹øÇ¦ç[‘$Ï“wð¥pmC2áá‰:8h‚šfÙL°Ù^,ŸxèeÈ^—/çuã%ŽÖY$;æ˜'XcÚXûÓ#hì˜âU3»÷Ïp‹1,ÂßÖñð:€H^ G�2—óªeyÆÍñSßðs¬8&mðN fÇêÇÇ!=íÚANØrCzËFâÀµ3íÉ'þµ¥eË?.= ÊžçqrÄ…ç);ÚÊØÎý‚\"8ë"™aÈ=' ²œ·@ÅÓ{Á!²;ŽSDW€Å‹˜å b2’)N˜�MÖhx¸®h`VÐø"3›±™©1‹ÍÄx㛈6¹À‹Ó–[ ÍË:”§m‡Jã„‹5iøKd¨)LßÈ´ÛÇ Ã°sžC”˜åÈÇ»5˜éÕ®nå )ÇÍÆXœÄ#û k¶|î"†}kù+¸oú9ȹöå°t�$gᦶƒÀ_ÒûÓ˜<_¡àn|°´L"šì{#5Ÿ,°Õ&ÎñÊÈì2Ø×ËÄÆzÉ–v åæ ã‰u¢£Ÿdš¨DÈhæ aÍQï°è»0ŒÝ°� îÄÀi2ÙƒÎØT„¶ÌÇÇÎ’T°�KÇ¿¥1Ç^¤ƒ@ËÂz8‡`v¶â,‰ ·dP~\c”XLõe½¢ÔÈX8žHIa8JŸsâØ0' Á"‘bu�AoÙ̺¬üåÄX_Wý˜‡Æ¦s|‚‰ã1$ÔE,°iæ’¡LSçòÞ}m¬ƒuØá³ðÃõ2qtNéí/û„ ð¾hçU¼¶€¡“"ÄŸqÍL‡‰¹V[�ðD%nq‰“í¼PP¶Ô‚qJ%Îö³Äãé¹1ƒó^$·–v^€ Ú&úà“L8W¿‚UàZÔŽx½xD–š,SÏsñ†LARs$ÒE •$*Eá°Á�üÏ5&î2Å3·äŒ÷  ÂW?åj¨W[ûH8pÄó®_LDÈ7¶¡�›h†#P¦÷^¬´Î6îa6¾ ƒ�Uk}õ¿Â.s¿À"Þ@¥V2�À>£¨/u2/ìcf2¹À•2µö½ùWüîuðÆÔ¶žW€¿Qz7õCblÇ¿B�¾àxÏH6ò N”ÁPß™AtåŒi÷%QðEGƒS÷‰ðXqПq‡ž–(ØŒ¡|ÍÎÉÊ_Fœã¥Ð!X<ƒÁ^ãâ!û%˜·é‡_ÜÔeøbÃMAtÜ|Ú3ž~|¶þGàsžýìãóþâ_¸¸ˆ µ\¿H,Qz~èö~È»ùu×]{ü™Þ_ÿðë�¯~ì—¿ö†ßðŸ¿ç�ß� Ùݦÿû—Þ òN@ýé-7T¬µ&•Ÿ¹§µe2{”ÑNpøåÅ'ÞÁáÆ'ñÖ�‹Ùk˜“`kŒGÂçÝYžÄ$ YžñƘŽ0&²5ö±ÚÚÈv}$£¤®SÛ%·èÌ9µ — ‰RUn16¹QX¬=õ§|ÜèK“=Øú¢¡ ï<Þ,œvþÁˆ5ü<”;#¶A¬PdÌ>%þ$š?e§ñøãº†}i{@ ¦n0ÂoÞùgî²QÏcv|À§/~ñ÷�ùþ/潜#µ (X€ª9H†ë(bL Ó±«ysû(ÿãOŸêûòW¼ò¸é¦×·°×Í!�Wö~Ö€ç_åË•¿œû\ °i!“®¸‹ ¡­“¯ÆøùK=q¼¶¼¦jv÷^p]SOçb”ÄÌ É*5ÙÇÀÔy̱>¢`öuÁ(ÖLsr JzOFrŽSëø�Ç\l��íx3ªË5�¦b„±í{ê�ÈF°ß‰ -ÀÉ¿s+Ö!µDœx18±c±Ü<89 :c'Ïs^o$Ù.³d'arÞÆ)Ød�m±Rƒ³샑©Çmoàú\ÀãïªÒ†àýåèÔ'F´d Ôª¹ÅÈ4¨Ð±s0? Ä8„©'îµYéJ ¸Á£³ r ïÖØðþÄ c¦Þö,¤ lš:+Љqâ †ü™ç\–ùv¼ÄgNHç‘`““M¡�6|Â{»UkcÇ2ÿЧ‰k?×4Rb’ænÆFºäRN�ö½…Upã\�{—1l_{À��åhùðb|!·r|4Nl‚�Ûv=áä,îaé%˜6«ÅFª„:ñÕÂlüm‚)²‘c›ïÃsoÎ�ÎyHIÔ®ƒ½\—ÓæÇ™ñÛŸmݺ.Ø“˜kl'£ä€ï–£9K3;RHA„ÛÙoÒcOÛ¹kbG›£é’?rt'aöE‘�Ç ’D&×ÊA«õ¹Ö ÖÞpßk‚O[}üËWóPSï|Äñ‚ç?ïøüÏûÿÿ3|�×Ä1`Çê«iÒMŸ‰�þÓà>ð“ŽÇýW_{<ö+þ‹ãýßþÕñþá?8Þû¾?Q n†Äb殞^à<àsÛpµ�tÍe2ñV¤F ÕÈ�XŠÌlñŽŸ<'v×÷|é>Ásr‚{n&ËmdŠU!®ÉèÂtã×S—�1ÓÀH¿®o„+<ç¹â�±2°TÇ IDATšºljRlüWº3H^­abÆêøëh9Ÿ2,á% ùVìý�T{Y¦¶àà'ÛÛ§20Ð]‚‡;š•øÄ,F9 ‡¼�ýP´«äCÓ\ê‹Ñ9Æ çy~)–ZGºáé”Ð’“G™V\ÿñG»»Þeíd66É/“b:¤Dðlýkï{<çÿE}m¤rÝÂÌGÇ‘1_è2? ˆ¹dõ²îyûöu±dW�1%Øç¶g‡Wº™ Ô·cBCfrf´þ4çb½'ŽÁ[€ã¹Ž¯¹œbä“kN­ÉÛùƒˆÁð n98Ñ€Ùjb›yŒ4wSဓùÔ˜ð„YQ’ÃxÇÅ“éat6}>²_OF²óšþê@è6Ç™:4²2v?ù;73�w×KºÂ�YštÝ«Fš4fâ…O°QbÈOÖŠ!"– )mácì*3÷r“mçŽ9ó�É’·~¶²°½'¨sœb6Ìh˜¡Â:Ž™wê^‡ØMf26‡!d©ÃI öú1¿.º�âŸP7pc‰Ú/ôÎÓ�ï­¨‘Ÿæ½³™VuÖaü‚Ñ|Â#Çä2©„³p½ŽcЋֵï�Cž^¸êÐwó$?é®4§*‡Àƹ˜€ œ½Œ!Iêmò˜ý&«àåÜb"ƒlkH©¹>.Ɖ…ÞYoµÏ�œT¯üQÅPæK¬Âv´‹BàSÎã‹ /Žg©�”r^P§\‘71€Êº0Êúš›n_/´´äÄš^˜êܼèÎcjŸÔm437O?}‰ ß=‡µNê�*öÔÜõƒ±¿ HìXà F'‡õÀL2óF9z¬°ï»Òˆá0ÃÑ/¾ ˆ� ñs—ÜpwþÔܦ ±ª!â>ꬋŸÆ?ue÷5çS‰ë›{ºÁÀ½mäKŽPËÍyWJµLtÀÙ‹¿ÿ–ß÷�À‡=ìáÇ÷<ïyÇèƒü§Á|*ñ…ã³¹H™NÞÍõ5–þºë¯=îÿ€û_ÿuýø²¿òÅÇoüËß<~ôGTŸÊûnÿ 2q‡âQS×IÂmx—í‚¡Ô { ^ؘ£Œà‹„þboYg%#c¤6©+^4j––¾ÄÌ»±òŽÌ¢#:£©¯†ØzßiŒ[–‡žÆ;?¼Æ±Åp”yÚ²7Êø£ÞIæ&ŸâÑûü(Å„³IjÆðÄ·bâYŠƒµ)OøG–\v=+íSæXkÞ¼øª�ãIâäî= Þî}¡gÃ<!H¬T;t9]Ã�6}xÇü�?‘äëAzÈñƒ?ð·�G}ö¦÷ð�ñ�ZÅ!N—Á gnZ:TO1=.€ â{óÇò©¾?óŠŸÕ;þ~éø¨þÇŸþ Ÿ„\7öÔíz¬š8Ò“y9i¶03¨–z2¶ÞÂì/¯µåøb#¹ ‰IÊ™}n;éwl<É"ñ¨#ró±e3Zp‰ î2À¹eyÌÄÎÙrîÍÍÚHz 3ç9âÖ¿²Î{yáøŽ‡Ø­DÐ ñ÷؃Ă_Û‘Íçy¬6wîY¿J;P@ ëÿqyÉ-6­X±Ò÷æÍŸ(w5v|Axh#›X}eb`¯?ödìÂÚÅ22ðn[ûA¶àKë˜è™¬VþƒÝ…’GžÇÊ dpNgÖÒ éz�×xQ÷Œi4'qÊ=µMñòìëX!=äÊq! [Vvëy^¾ ’ëÙ G×LváoÂbœù¹Ÿ£%>áÈŒ&›@HžÇÆ„¹Ðż©q†Æ˜âxÞƒ©õeÃXr×Ã+lœÜ¸‹îÂÞ¢a rñ»Šyzlæ‹Wrš¸wâÖ÷\¦±¯ÀV®à2?ë�(öî5DW®^[ù‡uöÞ¶=­Àûœ×d¹¥h€�ólbMHyN“O÷2uwíGæ¹§VœbN_ýLmV•»¡k~æ0)¬œ–åÊ1õ;aÃ!tØB�cÖ~—‡úÔSÞ{íítnfO¾ãd–ú€3~K‡7êDðÑyrÝH~öÂhoašãÈ…ëºiêµ\âZI:Cs0›Zx™•=Ù;9:4î7¸ËÕYóàà l[H3x¥FŸL!ƒ¸M::‰ Óú\Îå{sTLRô¾¡ €�Çnó=Á“²ù`‹bxsÙnIù¢Ïöò(!\1îóÄD„‰uÆî6@îY5Y˜Hƒ 8‘‡Orøè‹yr’�Á'¶ÝXp¦­n‘ÖmaÅv¶�1±çç®9mbìËÝ�´×°kbîÂÊr66©&Ü)'q:ÞD¨<Õ!k�d »¥^H]ϟ̺‡S}†áÊkã5è�XV&1\¨—×'–¦Žõ&CSlïþ ¨ep\ÄCx†S3ÍZgçÆ\_ sç=¹à؃m[HîmüvZ6·À/¸ívÀ”ƒÇ›2QÄ]²^48¬!‘Ë—Ÿ=¡Êxç1Èêò8QV )¦8óœàFïh\@a·Úø›ç �° •XÛqö˜]”ÉCL·µ0Ç»4ç�°÷tˆ{M0Ç�ñÎ=yGl0ê‰|ÈË�¯�¾¾'3/Èð †G3¢Yž‘Žƒ£lŽ|§ú”Èñµ«¹„Ó”ä,mÄ$ŽF8¼ã£æX­ëžBÄL˜f  ­i}Æ@r[�uTœžì7ùv@Ëâ·×qÊ®¶Æv~›´¦˜š+5ß°ôç^ÜGž�“—òø¡:må�PÒK”› Ž5ò|Ù€ù,.ÿïÆ^M”7ÎLOîkí„�1õÃeØ ¿8ªÎšóQ\8ñ饨ñ‰?ŸäDnª©ÇÐøàSj�%>ÞúÖ·Ïü¶o;þÜ#þÜñÜï~ÎñŸ¯ODÕ#øæâ"êñ›1|šÃ “û¥žÜ¯½öšãþ÷¿ßñu_ó׎¿ò¥_tü«ßüíãÇõ?ßöö·‰]jÅÍ×Å%¾çÄPFpõ�A 'v¸Ö˜ÑÐѹ�~ )Yê\hW¼xèè`¶³Hóþ¯µX©²<Áâ [ÇeÌgBpôšf˜Å÷»-¥Ó7ó0¤ÑÕÔ‚‘1yöÚ˜+F�}š½VWúÈÛ+‚L¸Ø1ïäyŽ©Y ‰jA-ó©¹È{5–;Â)©ïúf„V‘¼þF¾ùDgf®�™ÛÞ<€Õ�×Gïøco<äÁŸvüà¾øøìG>â¸×=ÏØ'C‡’cæîQ¨±NnWç»Îñø4é|¸ÇË~æg�×ÝtÓqë¼ã~2Ð7�ÃÛo¹Eõá‘Hã±y~p‹×Ðq,sUud®o ©�8¶Íuìrœ %¤Ž©©ÒWG¬¶A‰�3’¨][ÒÕ�¸Lä7AOA÷5„�âË»/ø ÌÿÇØ›Àê»�Õ}ï½¾öµÁÆf ³ $ @ !!›™4-Mµiª´U¥ª*à0x3„ZU-C�ÁÆ ‚Ò6ÄŒŽ™Z¡ª  ’”AÚ@166ؘ”&RcûÞÿ½týÖzÖÞû;ÿ¿£îsλ÷~†õ¬çÙû{¿÷{Ï÷�“#¨ÓÎ8à0Gr™%ãf?S1È`ZÌ`ø8³Øx­nkbñœjKÖQóæo.xó=r3~šÓT,ô†öš:dŒwUDnð†g�n �À\R°„CxþR2/v–¯¦¥TßÜüÃ~ƒgÄqcóË|²×¥:Z¬æè.cü“C‘îš�骯bUk[V$ïY„jÍ£ã�S�B(†¹Çh81¡ æ±o@áÇõi“ŽGJŸ:‚·³4°%Mr¡b8~x �_¸‚7õM±lvøv.ÑшïËL£Ÿ11}®Õ<—/k•mD…Å'”¦gBËNÞ�ñHSÆÜ”±dÌ“O±ÙÇœÙGYEÓiœ�Jî™xµ×u¤Y…ÏØ–cùÂßØŽŸ8᜵ÇÝØ êª9:×��Zìv_Èi]«r@lŸá½Æâ„�ù¡SqÛd�åz0 †ÅïØa—¡L³h+p-£Æ,À´òõtüéLÇòw…eë¹Ì”‡?n@Û.kÉܹ�Ø‘'~9âææøÃS‚@…¯mñÿ¡a—Ø$†sDŠ�lkæ6¾sˆÅ-ÞÉ)tvÌÖ|•o \^ë~ÑĶßMì²Þ£îöµ„ôÕ©ï¸P,ñú/À+y´X®ìkŽ\ ¢è§‹R­)I^7F.Æ`q¢«î&ÖØÓ » Æ™³¨�gPZþ÷�­Ë3±^´qÑ,ŸhäWüö¤·Q4�3¿=ž(�% G5/j¡¯ä¶,¬£ÔlKƶò©µìȪW PŸf{S¹‚ÆZ|eì’6öÀ9rAÆ ‘ŠgŒ ë‡Í3ö±vž°îz™(X1¯�§Òe>ŒI.�@»–h$Œû�‘m—ññ\^@ëgÙ ŸðÄ…“y�}o2¯±Ã2ÇÖ£=Xk<†Í§øˆÍ_ý’ ¯qÙ9–ož¾Ô¯I,OücjV³rcnNÕ�­§®Eó¢Oýðñ:ŠañÛ'ì ¡' õb ¯3U�ol4« ß̘ {}dæÇZòeÐÄJ�ðŠ_ 4³m`¶¬Äô )ÎZ™:×ah ì�bЙ‘Û`|#.(ò¢ªwbð`x\8JP™±}˜xsAP>†HçÓß07�¨ò8ðر/ù‡Ób(£Ô5½ClÏ}ŸN²úÔüs-ȵ<°I<¼"Ï ){;_FÆô!5H-„g{¯ñ nç»õ&O´@²p#7òÀcï:qãmœÍÛcŒÒbwÔÄN8£ŸX6ÍØaoŒÆŠó.pž&‰¢1’yÎ��ˆÜA—RŵµnPÔq“/û‹8ÁÍþ1 n‚Pknnê<®çO^ËúÝ6ŽojÑóܨ€é�v´bÐÿæoýÖõ¢Ïÿ[ׇ}è‡]_úò—_Ÿðü�ó î? iêÐ_ôfì¼%dêu ?r³ ¹ó}Ï÷|�ë/Ög^ŸòÉŸpýÜ/üã뛿雯ßyÃëÅnòÀA?æf„ÉE:Ç–º¸ywÚøÀÃî;‰Ž½ ¼ ¢b§uw1ÆÜþ}ˆß™(<ÄÉÎnö�- i0ÐÁXü&@sLjÚú`À�›£óq^͆®}<Ž!šÕÂ7Snò>"d+†U­;>ÜÖ󧉢 úÖ·}L’Kk½j‡k}æF|Rq+wL'—ÅS†æ3¦ìab$?ê¨ó©ˆä¾yó��÷‰ÖPï¬óµƒn.?ïyòúê¯úÛ×G}ä‡_ϘÊÆ\&¬Ó¼áv3Ðt�f^çéßé¿ñ÷¶ëÕßý½×k^óC×㺩ǾàïÍwÐþÔ’ýózåFþŒÛ:N{t5Yz +�n4h¼á¿;¼¾Ì©£ÐmK¿ê'5ëwPó<�ÁJMâ/�IÈ-½í,ÃYìO컌ãe/ ,åÒ›'ãY#˜;–s`äpå„™,ìϸ\Òg[´i‰Ð}ëe™ÔÙãp 7×Mص3—yÇ'ˆc¡”´|#_µwM7~YF'óàDÞqy‘eôcdjŽñ�׿¯•ÔÔÊ2â3ÍîصVÐæïüV<|À¥ Ý^§ÃOòÞpÂ+×qr”Cóg_u­±Y hï—Ô¹1kïð6&tޏ’—“㈜×>K‘<¦!™D@æìYÇ—¤}÷/‘W3³ä4ºÂw�¥QB­ô‚›}NÔ,‘¶Oæñ‰Ò¶åÑ^*´®31&·R7®/Š?<2Õ1ØÔ[®' ]¦ÖcËw\V=«[±6X&[€ž<×� mº„Hœp"? g7D/Áøg¤–1Û:�îð—¿ã™ æ×}F\7Ìf옑ú¸r-ï%•€ïS.œ�”ˆÈ…f¬Ž­›=&µãVók]†õd ÁÕÛN²æ/ô‘kÂ7ñêc6g4Ž¡ƒ{k‡[p±kžŒi«6öA`©Gss’â|Übu_+†­OD&Ž `×µl‡ÌŠ¡^ò® 6Kjë`ón ™ôc%]cóñ ³ø6$õð O=Žâúf}A†ã,ÕªUe›ò=⩯ŠÇ`$MÝП²ì§` ·º03f⌱¼Ó�§ý ›¥x Vƒæ�csiîÄß¾´ädõ ]0Ê)uÄsårÀ z¨ÝÈqÐO/¼�sÌ-Ζ=€�ù~Éãô±R\º¶áyærë#ý">µÔ‰(„†Bj× h÷SC(žd¼2ÇÉ8qÃÏ¿|Kñ(‹cÀ…që¼oðñî"­+ûU6¼Pïs^`ò�ž«oÍì¦.ªËåõzGàçáú�_òÅ/½žÿt#�œ ›w±�ƒa=p�$9JãüƒŒÎš‚Á;Ÿóìgéï~úõI/ø ×ÿö‹¿|}íßûÚëÍzG Èš//*B^Ñô8Uâ)oýø†Š%1Kó‚T^ŒÁr7מö�¦Ù3p'�£K?s �!ž¬á„É^a¢Ÿ�µ#8œGrskpqšõLý‚ºŽ›ÞyÐX P~ÎKræü¬u0 y!ר”œ HIRc›<Ñï† iA±dnú!Om5Àر6?ô¸GcµEŒ6ÐÁ€éàAO3vßÎÀ ã'ë�œ}š�Œ‰W›~²s¶ø`Ãw•‘à€8§A×™9’Øz•탑ÅêÃÏ6# n°,2„ÉÛ~¢ÈµØƒ/“ +7p9Fæª!òÆ—ÞñŽ9ÃAÖ=öáé=-ÍìW¹ Fmk�}\�:Cç@Zxg\Èp@7ruÈø��FO°ÍwiìÛ⇕ësøÔÝ ;V8 4G“¬u-ÚÓ*|ë¾ø˜{¦UNÜNm”ó. '¨Lö>ÛRü1ÃÌã"I$wé ?‰ HkºÝ©xã‰öúEn8#nä•«ãm;§† ¨EŒ12|Óðc²ý;nÆPbÙØñôÙû£e©ìÇ[!ÎRÃ�†ìŒ_^ûºÕVkœ]KöP}lRŠLš–z®“ç0Ž{`J`9¢êð÷&ÞTl˜kˆµ¹1Ð’Ö¿E*/ë³éĹ“ØöÅ(XÞcàJ„Þ�A@ÔŠéÞO²áw…àÊß´VaD�»øAÊ1~Çñdo9b¹ÓÁ¶]e’'Ë­Çõ¶ÕbÛÌÓDp—±£dmM“3}â¬|–�$å‰ÕÉËu æ­Gós>¦*ÔÀšuZ5911ÁT~¶#¤¾w¿Ù/PEݵ“œ¶bdºê°yh¦ôÃl,Ó-n¾x62%¶óëbg› H’5h0'dqË+|¦Óg_Ó¡VK—#¦#¶îðš±q¹j?캨Ë÷Pã\#ò~Ž……ääéÜl RüÔ¹­øGÜh¬_'EÔ “‰ÁÔÏYólžÖs×n²U«Ä.‡+ì5Ï·}í/mì&Ÿ£PÍú£G–º%¥?Ó.WìL€úÆ2¶‡ÔÙž7öš¿ÇXyÍc;àÑ'P8Þ““àQ#^õ`,ÁúèÍäsæáz³oF–Ÿ1†\jšx#Zyû&€|È”F?Û×¼�õ¼`‰š4âîQê;‚ŠåÓ#'Ïœ°WoJ¤ˆ˜²slg;�€Ñ uÊ=]Û pí­oíÎXtÎäž9xóÛüWÜÁ­/ìÂwö…C÷üü®k/¦Rû膚óò‹?ƒ±Ï“¶;ßñ±u±cçý¤ZÇOì´w�%VŠ•ýlä�!&FN�ƒÛ1¸ØS™”¼9§ý-/ËÇžå#œ[nÄÂtú` eœ4²˜ÜDVcz¿È·A0ãƒnìÉKm\ö¸\ :FÒ&ÆÎÍ$¬–zE‚h=�(¬É”ú‹:˜z1Ähš|ý\A‚–8É™šå¦à˜S#j~ó³à|C‰}g²ÚçóÕ;£ôßOÁ3¿¼³›h�æ‘„� “3bÞQ…\1©ù÷î]?òÈõ›ÿ×o]ë ¾àúÐç}èõr½#ðõŽÀg=óÝuóŽ�‡ŸoÎ4Ÿ¡fÚæ?pç|W\ô}=呇¯g?û™×_ú‹Ÿ|½àþûëÿ÷_½¾ökÿÞõÆ7¾^¼¸�™?Nþˆø4¦×Š¿cJj¢bî Èa$ ìãÁpä\8FΟ:YˆÜôðÞÓØ"0ôe;¨lùa'¹ë ¬…¾hÙÃô̱ i|ø›uÏ»ÿd°pv�X®ñ%öˆÑ7ÔV@pй©mBÜä–�wÕ}؇~Äõ5úçù§r㯺<°½ßÚK¾ÄõA\É·5)7jóØ;¿ÞúÖ·]¯|Õ«¯Òõ½'®½t~œé±Cm½®AØy$2VÒ) v#?×Á‘�܇�­9h®+Îz­%¡®M?n ŒÌ¹©Ï·sÝ¦Ú kºø6Žð¢6i�Â#rd‰o?#tÙ1¾#¶Èù‰Ÿ3Î`ÅFG™š‡êk¯r’‰­F¢÷ÔÁ˜šëÇËŠLbh"ÅQ ¤qc4ÁÒ�Éd@ iöð(Æ‘9•‘îš!ÀkûìÇ¥8IœÚo½=ÊMÁ-´mõA—œÑô5@× ëN ”³ Šÿ-n¹•ÿ8ÝØ­<�LháË!š÷-¶¤(ŽˆïBèÏÁq#OX05×÷æÍ˜ú¢ 7 ª�7xÙã™Wê&≠^;*5Þ’¬eì‘’ .Û ÿÆÁ¢-ë‡Öÿã®�ÃÆ×ÀiÇLû€7<5/,¨9ðåW‡]b…[yÇõ·Ê»�Ϥ1T]«K ýå]khݼ·œõ‹�ãWw[¥Ç¶ã5(J50ε+)cK_î6>–S}Ûçа~Éaæw�ëkŽLÔ¦H33ŽÅGøwø•‡ [|j‡¬u騸N<]ØÃ/©•K09¦!�G%(Å«=’¹r­¬ëW¤®Éª³l½tpÖuB?µæ{H8 ž{æ2¶Çl-Äqm̳©ÖxÙ£Ó�Ó˜±�*§ßæbûS?CEX Š"5`ä†Y欛Úà'ýàD7^ê=‹±�\8ú›\“”¼æ¤´`7š7Vq 76g‘ðª�}Šƒƒ”æ36¶ƒ‹mÔkl,ÛÂyæÈãž ÌÑó&1¦G®ÖÍ þÉͺásWg^Ò!·�P¿=œh‡oqÛC°¾�ÈÍØºˆÅ•Ö¼<™š0Æ“–£ØÎ·€4GlhŽó’|cÎhjY²<ˆ¸ 0 &ÌÜâ%*ë€QZyõE�ë#ÕòŽyɹµ$îo¨ØM\ûŒ/‘ŠçxS3�?/<ËÙÂÎľK¯Ø®ÛÔ‡1ØèëçXIÖ!œîøuŒ}üR£²Õ¬Óꄆù͘ãdx’/nêŽR¬|ÑÁËÚén �lZ¹ÙÍr‹}HɹaáàÆ_ó Œ1v8ªõF"!/~V'sßvu(0d­qà2ßN(6ønÓ»†r\rau ñ«ëÂ#? Fqm°­¢œx«kLi½®©®aäšØ`œ8šb Ÿñö3\.Î2&j¾]tà…7s€cyÛ_GcÛº\†ëØÚç°�¶~n\«ç°j©ùyƒ1¨1‚›ù^œš÷ý|ÂÙÖIÀÎÊFÎþÍÍûÁp»Gű¸Ð'ãa;8ßm‘Áœ9oÙ¬¶ÎBúào~ ÅÆkÁT­uIv��CñmnÖŒþ&¤yJ�°añ¡�‘;0vaZsæÎG>'k»Iâ¬ÖÉò YhÏðQÄrö� .–ˆÁ¹^ŽétòIEÂ�Ý0ä& 9SÀ IDATìæÙNx|tQvºÙ÷ú7¼áú¢Ñõ¼ç>ïúâ—½ôzá žï¿øˆtûE?àú)Ñö¸3v}‘�=|Ö;ßã=žy}æ§½àzþÇÿõK¿ük×7~Ó7]ÿÇoüúä\xw3ÿ=æ®arñ;v%3¶»Y©ÉÏmì©Hk~¨œ7�ÿþ¯kh¢PÓ"˜=ÊÀöš{Ù'ùȲžŒÁÉMŽq<eÕ “¡î¡Æärˆ ’ü@ž5YÍÙ¬¬4~ž·¹åæ(,¿D÷É�Úq."^}Ò—£]L4rã[”ÀðyÎŽÝÈCN¦¹�e^cdæ ùè?ý1×W~å—é?XÈõ ½ãoÝø[¼‡]9�ΚÊÚÛì e%›x½âUßuý¨þÆß“ñxPF)˜¡ž¿» .7ªY‘¬ ½£]cËÙ·ƒ_m÷rÖ žCŠê4p&ÆCü£µh±0°eËäÞ¦ñš2`Ö©8F"GùòeÝÀÄ|95!âìèsN‹Â¯Èæ0V3ÖÊæ š„´áà™½—:æq“G½¿ÅR>µ€æ>§ŽÎk6,fý˜áÇóJéÕ§Ï:*€‰N)¹«\0 O‹$|‘€ÃžI¬±s8ó�îl]ëÖ|üâÀ$ŽÅ¯]ëTy±W¹ÙVÛnÎ`ž„2Žoå�–Y7Ðâ‘HÎK2î§Y ,À ׿0Šf«õZÈh6­^“¹N³b~$öúiœ<ÔÈ¥�c#íj~ÆXn…?k96cœ\¢GÃ\–¶Ûyf¸Ø¶&ÆÓÛ´ìÆ·ØÁݘÕÛ²®‰-]û•aÍOø±Î5îLÌJàøµ9¬·ÈyY¿CœxÇ“„Á,¶éÆŒ-B�7û¥ö«ÛwÜJ-ý8�yö¼˜H¹¨Gúœc£CP[�£{ÉÍãàžõ–`âw¾üQ9Øp‘!Õ¯~ä‰'«zðw­CÝ®Ûæ®ÑÂ/_ã㜧ð G®ÿˆ³[8×CRYŸ<Ä�B;¿ÁèW°ÀäúR�Aç}H>c§ÎMx¸bvæç˜Ç:Óp‰—†Ks®£ ë;ëÐ2¦9'ù¸~µwñerâ­üë'»Ênz]lÏö¡ÌÌe‹#5xp`ªfëù¹Fšû:°üŠ!S°I‰¼\/ª¬¹~~€ÖaD¨Úp ÁÔŒ¦ÑÈ=�¦.é!ÌsH€†°TÆ¢Ò˜WL �IOÑÐÓ–M¦[/[Å¢…‡'xH�1üm%È‹×è:wlùÑïMмá•Qü= ¸˜è«Xh¸ 6œhÓYÇžÄb¨¯ø[á’XîDÁ]˜ØÃÀiË�¹ú%3ÇB5°\²í!è�l¼“ü‰4y�ŸcOÇæBMßÉ5Šæ ¶ÅÃWŒ`n;k m.ƒ_©e ½,È‘“NIRÎØ�ˉ19*˜ô­�ñÆÏ2«Ç. .p#W7mˆ£_²P²AùÔÜvò_Óé´êoüÖÚÍœÎ2ãD¸jfßÃж̉7{�± · ;\܆c罨�æZ2(ïw-˜ºÅÙÃ]»ˆ õƒä'ž±‡×YÐÂ<¸«®H ƒÔtc‡ËYƒ½BDÑþÃzæñf±ã{òày;Z±3˱uܸÕ&Ú �1hÒùEÛ™O£$žqñ2¯ªŽyJÔì1^Æ*KqŽÉ¼·v– 3iojÌœ:,öï|úU!æ2�ýZ'éZwc§ŸÔ+ ÷h¬ed;¿H‰Ö7HBṽÝWKYŸ¢Ã³Ì÷ÈBIg/ŒšõX.®!yÁãÔ%ÃÁà°†þÇàÚ‹¾�6üxáõĽÇ]�‡ôNµßyï/zéK¯ù ¾¾Tÿ5ø…Ÿøñ×{<+-N.çð‚PõI:GâVŽ)�:Ïæ§~òó¯?ÿç^uýʯþÆõ ßø�ׯÿú¯ù&%uæï“|Aã²ï„îÍ*×!‰ÊÀV^O?b<§ªŠê}´y¬ú»ª§â ãÅ11ʹï¦É#0u�oÀóƒ=uä]aäÖVäËÍZšßÝèÑc 5Ëæp¨‡¹óÓ€oÅHü[„Ôvúää\O=õ˜yªs^64Ò² pnj:ªmí‚u¸Ð€‚ƒ�"âcë¿÷æß¹âë;O×mCåö¯}ìÇ__þ¥/Õ»Q?èztnüÎ¥èàÁ,'ÏS¹ž…íc¨²wòŽ¿·¼íú®ïùÞëð5þðäï`²Uün=ŒùVÔÐé—=CÄꨉ¹Ð—F¦ñL04/“ñE/9öàq«ÊzÖËÄ{-mFs46>ø«(q"1 ~ÆÐ.ÁµÁ`ú.‚âièPèiŽ—ýî\$8Le�™ÍqÔ¼zO @+->àŒ©Qey'&–56îÖ]¸ÔŸ}&öóa™ŸÙm,òP$ÓâqfQ¶ï âž£Jy°®Óg½ƒ“xÎfq°ƒƒÆ×þ:ø!ĉQŽq_ÜײÈý¬ÆäÓ_àÇîJ.~†ÝÔ(7ÀkQÚüÁõÌñËœ¼7nà„Ÿ€¸©1¹¿m¿Ö}ìì‹}âÒ¸ÃÕšõ¼£khÌ#.­U~™”y?Ÿx󏤿äf´ÕgVù/ ãǧy¶®Bc¿^iuŠŠµËP8£2x@vy[‡:Î&²±x°Éi74Ò7É­ˆ\žü•á`ÄÖA�¡k4Ï­Á†O € ç•Ë sÌv.ùÜÊÕzËÀ–|Îãn[’$nâ$é…+8��Þ4C]pÍäê Säjçk"¸¯6~ÍyáÙRú¶ÍÄ8%¯_ÅæŸ‚Wä~á &‚;¾®¹*vCKd¦qÔg¥ë´10óIMÃ¥±>>¬IjÙÕ,x9NšïÔ1X±·¯K!ãi{Añ™EWp­/¿ w®Ki£b´�bê=#­|[£³OLŽÞ{iy§~�{sóT�³ý]âûµ^Šaþ<Ÿ®_^{1(À0Õ5ã™ÉæQë#À)v•Ìùæ2Ľ0œ¨†`A²¨ì®-QΖ¸ÂJ´eP†CÎnÈ'NaÖ¢/� 4<ó&ïD ¡»‰%Ì\Œ£“VJßyFNLý`Ÿ¬Aÿá¬ÖíܬËal'‚Yå l¸M¬ÊV �ÃwmC¥Öaw6hì–ßø„¹&ƒS}⬷ÅÅ�L'”r°/*×&rû™)rlÀA�üèSÏæŠ„®ë<ãêwU;ke«’úqÑa»Ukw\Ýk~ s3tL›úš 8Ííìá¡yëSÄmÕ5�•ŽÏ^ic$@bdäú�zRô S¼F‘µŸñ]þ2ªžek‰6�X1y fÐææŠ pŒ;Š`Ç0rÒ˜õ‘{h5`‘L„ÕÕg Ö`ì‡GÄ·®õ@Ãj­ÿJdž¬¬�&S ®Ó¤‡Ô¬1—RFãÑ‹9¦Îµ%¨ÆV¦~†óÆMY+l¡Â Ÿ: Öy‘¿ý`G(}ö ÀÂöDÈãë2h<=Ðæ¼ö¦ÂŠÚŠ=˜Iltöï/:°FnÔé™u�shûx)¼!@Ó¤^›Â��­1dYÞõ_âr‰Œ�܉› ÀØêyâĈØ7ït²½„+O0‰�$k’qäÙ§Á& žq0“ä0Ù`©¦|™o�·_„1^{_¾ÆE&SÆÖÅÍ‚ä†`sÄ9ω~žÔ½%..¶­é /7#’§ü%Ô¾úh%)¾‰&©µ� Á�›LÊåM¿÷{×Kt#ðyÏ}îõÒ—¾äú”Oú„õÑ`,Ê;ŽF״䙘ÕÞß{/(7~á þüõ½ßýÊë×í7¯oþÖo½~ù—I(ÜLãFAþ«*ð§™­4ïÊáo}ói=…–ÞLýžíe¬ � Fúf/!çŠG N’Í|ÂkÆðÃGúÅQóÕ4ú‘ö;?ô­ ÙàÀ„½“ÀÞ CÖ¦–«Æñi^ñ±9(Šs¾ÀAnïš5†l}Õf²Ù_£J~D”�/v„Z�uO7ÿ¿ÿèŸ_?ý3ÿóõý?ð}Š ×J¹9ú±æã®¯üÛ/×?ùø ÿ�?×O~w›÷VÏ™ðœŸ6�]“S&]eüs�ßË\ßñ�ßsýäOüäõÎÇßî¿¥ÉÃýÞ÷°öuIÝÏE<Ä©iþýNjW›ÜTÇVMñ©ƒ‡scp¦VZ–-i4ù4-Ö„17M.N“¯4Ìé ŒñÑÈ]{G# rœeÏuZÖÈ঑W¬ÀëË¡\,BP«ô·1ò.®èL~†¶Æàº%X¨X Å6%¸îÆØ®#4�eP¬æ?cÚfH[l¤UŸ±tì䙺Â%¼düâ`. ]C©Ê'ÜÑÄ/œ“Ÿ­*·×qñúLWä5ƒžg œµ·Í93Õúåá’:†Gk»¬=pÞ�)€½/Xá€ÕÕ�`×F�çÞüZ3-âåÝDZ#\³r5fZ¿òRO`·Ø›‡|77Lˆ‹~âa¯!2KÑÁŸ9üíc15âXiø}ü ‹RÁüh©¾Áp¸Ù 1ÌGž °q,ÐAþpHÐÔ/fÛ¿ñ*�Eü''Û{$Ñaø†{íèÙ7ØŸ> NºT¿ä±ùÖÄ£îè\û˜kn·qu–“€ô¾q];‰úË9 Ûõ©míÔ;ÞÔŽ3uo€Csš}Û�Ê›\cÈQ®ÚüG+RAhàá€ná8à(¦srbàk´‰¹k§ ¶[Æž—/qVl0\TùL�ÑÓjCA6øÔhfãùð¹­•,À! D ÷ÁÃ×ÜD#Ûó{8–—á`¹G®Üë°\½¯eˆ;†Í£½nXàÖæ¸äÆÞŠ)Es`ߟ©‚ãùžØ®ƒä�|Ê’a<Œ¯Ø‰c“WA²Ç©+ÿã‚Q׿’Ù/Æq®¼ĨÌ}'ƒ_½,�ÅÁ½ ä4Å#=ä®Lû“/28>xоp£…X6õG_cz{ËùPèfðSòšc›ñ$¨‰×~0зØ‘�oV™#R®‡ yìæCóBÚX&‡¢!†ƒçÁtý¶ø°Düµ7‹eΟí€ÖÍ~S›êŠÁ¼'Rì|“»åãCT=x’Mþ+µÂ‡69¬ZI„ªµ´qîÖp¢”—cH¸<õ2þðDo-ëS%|ô¥ .ÕMžõi¢‚[8@#o_›‰)ÍèÃÁÉZVäAª aÕ�OsLn©sðÈsÿ퀂?×pñIM‘;æÁ/ñkH�°-Nú̾å?†6«>u^5’.1‚åcÃ1eâüæŒŠÄæô±„ÀùÅÜ�k ˜Õ!š•1ÒÀ×ÈkŽÐQ#YØÕG å/ý›ÁöY0dc ËØÈ§ØñOAâ�0�qŽ‹—`ò—Ò”tXöŠé½#°[ß gEÇŠy×p=žŒ‘h;füOÛIO±wÌX~=ÔŠ»ªNêÓÂ1 g­Ïº$SÊÕüÌ·ÎgïBÀÎ+Ä­?f¾ �ðlXFM5>¡dÿÔÛ<›<ý»µ:vŽ>c¤šëÛ:Ç#T‚qthï×±µ°XvÕdq†1SËuøã§è’›jÖûÕU]ñ·uja«©‹¬]#ùæÆO”`p³�s({lÞ½ö†7¾ñzÙñõÜy®>ü²ë“^ø|½#ð™þ8ïY‹ŽéM_á'�R¢Cæè¸qðLÝ|þ'üÙë;þÌ7]¿ñþÖõu_ÿ ׯüÊ/„ £'øo°òáÝu~þW þϽàúò—¿øzîsuãïѧ³<<¹s(7âv«u‚NÊrƒ÷cúç¼ãïßþÊëµÿðu×Ò?åaýŸ==7Ïïø�z‰w_œå&ÀÔ1�5´Á¦Ïc0ÉÙ|\Øè™c�ߣ²/±s®‚0vXq®%âÙfͰѹÃk! ÛÁ|ÁFçJFC4 ¤ï¹ycÄFs’Û|Å &ºZ3ºûåBØA ' Ì'PÁÃÿÔ×§q;7_¹„ëä¤eÃØÀÁÅos›ãÛ0·õ“‰ñO,LávÆîÌ¡{‹³íØ ì|ÛÙx³‹§§Ø5Vš 8¡+~«ö–„Á‘Ì÷)lÅaã»9—A¯-±:£o\G>{l.6]±›±Ì�çØñp}=¯dLËRµÅàÓqÓ”7»¹Vl0ÝØI×S>Æ:þ °}4þûNì •Á�¸Œ6ÝÒÊÅãú2!/Ûê8r¦^ o›D‡~b›®Æ-,½qð;ÛF;|mépXìæ¼˜D(Ë�ßMùc2:sÈ3”¤v�ŸÆw1mPùÂÎ-ÛÑ_gHý›´�ºˆíL'öóÓŒ°•¯â®¼W|ü[¥zÚCñËŒàM‹¢]�ý¤7¿Ù*œ}äÑ0ƒáši K°�é0;Pò—‘ë„£l9ŒÉâf“àN…2"Æãïü%3Œ~ûÝ‹p�[¯›œä—šÇG.Ò—ÞØ€ ¯Æ]òD9í.nR9./ Þuq/.Šž|l5냜üÚ4ÄÒó1¡(°!ÆÙÈÍõwçj¼XÕx¸æbƉN°o ·,ã‘jðêÓ¸©G¥ïª§[7U挤 _l(ç’“ÏP1 XǼµ¼Áȳ� �À7vr-úäÃh�/ÿjÐô­sì‹ÂLz›`Q_ä4´`ì±Â‰PjêzÛ2óç­XÖÞø‘GŒîË›‹w5ãL1¶kã´^ØU&¤¹°_˜}Á<&®�Æ®cÂσ!ÄHø„{b A8.—íÎ@¢—ÁVÝN%·*A–Ùö„‘Êáp’vA`œl¼¦Q ôº…ªŒ'Ž}dÓÇ/žÎÕzÉÉË1 ¡±³Õ æõ !ÿÓ›±?×Ć¯È«/‘ÒñÍ ­Ù²”[_4KÚÆy’? ‘ÈÁðãK û(츹ÆFxÃïþîõRÝü ü ÿ�ÀOý”ø£ÁÜ„#ža 27$˜4¶t÷|F‰KÝ|Ö»éÆÐÇ\¯~Õ·]ÿôŸþöõõÿÍ7]ÿäÿ¢uØù£¶æ˜,]{Í�!<*l�mÈé¾pÈbô|Ñ8Fì‘e䀌}Á˜Ë×èù¸rk‰ö˜R{/ˆ†ðJ3CllΞ#—¬1<•ľ‘ï}€•šìˆa[÷{„ÚÀ ºúH3%0ß ¨‡¨ÆE‰0úXXâ€ØàÇ ¦{ºáöoûgz·ßß¿þþþÒë]Bó¢��vÜŸýøë+¾ü‹¯ù�¼Õ�?ï±�rè€MÍŽHº®²m_·³GGm{œ�úþ¡ÞUúÊëu¯ûq=ï²ïõ¶yªÌyÖ—ÖÍ7ÅÈS#ãHS?��yÆÜü‹†.^ØT +æÌ…w@ 7CéP¿ô�ÏÌzbõ—½ÉätÆ>4׌ž`yl¾C ¶¸Ø}0ì�ÛøÕ.5(˜«³üŒ�J~Ø9N´{¾¸°Ù{"?»Þèa‘ÖøžÉðß<³*/–98'’$JñŠ.½iÂ�~l‚ÕÊcö®-ÊŒm+Yö€Oh„QO/ É×vzå:1ëuŸ—9ØnÅݸ{DFPDû +O}5óÐÁ>礲å›Z´V˜2õ ØÉ«’ùwx�à�•�}lX|5ŽgÀþ¡ï»äa±-FÛ?`e4É[˜C£- À[q„i›‰Ã½¹ÍX�çqa€º-pɶ—9±È[pÝ\‡Œ+‹wê-,}UÑør>áTÀ—ÕzšH·p'O.^mm8j¼ìˆ2Àåá¸ò§_õ³Ø;&½vWßÚ3O-Ð%Ïq^A=²Áñ‹A°¨áo%“›¬Ö`°m'»Æ¯ÉïÌðÌ î Vv÷d<Ñ@»/ÞM® [ª�ˆëŠŸÉ�kÄk>#oým(ãÅ¥Ÿ\ŸÕ‚7¢ö‡x®«Ï„ÁÃeñ)W×MÖúæEÈ->h ý\c ç0¥vù.Ýä>8Á fØfýÙ«7ø2Ù\ny4öév´âkDž>OI†x ònbÄ6õ&L8ˆ¼iusóŤ¶¹IÓœ·3˜ÍÏ4€OìEpBåÁ ƒaSZYññût3!“²3S€±_5ZÃ�9-ëN»pÄFVÉeç_ŽÁ‰ôY‹ŒážšSKdõl¬Í£|b·ø[7�©œ£C^û…$çĤß…ÈÄÀPé©Öòy|­7NÄ]÷e=0tÉýÄF˜\[—®A°bï{6 «äÛxe»¨k`ÎzÇR.¼h�Àõ—Uu ºÙ‘1ÐFÀÑ/tåz÷¯±8` ‹þGn”,‹`p3�» ²ƒgÖxÏe”Šù�ÞúÄ:t-ø/²]£È°G<6¹þ€29¾éÍo¾¾äKõqMý³�/úÂ/¼>íS_èìÁßOk|ò0où´ÁymHí¦™{lÖM¢g¾û»éFÑG_¯|Å7_¿õ[¯¿¾ù[¾õúG?ÿs¹1ˆ°‡©o˜8hPyÑ_¼sƒ.¹%¿¹®RžüÇcd�ó{yU:Í5p,ü L\~RçQ¥Vš0_µ³)›;¾Sf�0ô$ºÕ‹…ìÇŸÍ¿£13Œá&5‘òÝà•õŒO“‘…o9æ…ïélf†rx©�ðn̶¦ÂÍ0>bûV}Äö»¿÷®ù‘×\�<í©æÃÍí§=ò”ëùŸø‚ë‹_úº‰üþ¾ñ‡¶Ï4‰eü¦Þ¾NôÂ5eWð7þþàþðúŽïxõõÃ?òÃ×=�ú6µÀ0çN÷„ǹŸ˜Ô�@"Ëó´eè\[©ÕûxØ[€ÆþÁ¬Ì½m©5FÑL‡Sg’Pìû·íÛdåGZä,À=$Çüy›:ö¸¦öɽ‘oÛ e¿€o;óäP_ †GÆK7|©:õ£ußqóB³‘1Ú/ÔO~ÄÌ�Öm;©»ÞYQìüváG›cóOn©qñj—y ZîŠ?"K<æ±^·ÔæÄÆXv˜rM �‰1:räÏ…mL {ç©¡÷)n²¬Æ³Ñ¥¾áUN±´Ëàs>È_ZÒ@Ž‚ôŒ{” ñÝFl}­ØÒebtíé�OÍ262�£Ú;@ë»%5æà;šy|ð©^(ÆG‚�Ç�alÐ ™6øí ·¡4±ÊÌ „l Æ` ¢Xë.u×ÐqŽ*D¯Ý0qŽ Š™á#}J²Ï.ÈZßø`sÖ§>{€•ÛûÝañ #ÜS§¹¸€¤¾ƒ[Èfíº¶ÎEÃÝÿØ÷ ^É�®ñŸ‰DÌÕØ{¨ö­[9Y�­y×¾SðHÛ²_láù¨–.ïì FİŸñ뚦G;ÿrI›š X²CM~v1y|ÑùÛZûÇÿ"𽩛ª/ø¤O¿^öÝøûàðßø#¦Qu Þ ·ŽI cìïk!“ôGùÎǸù‡×·~ûw^?þÚ×'¯'Àwýê�›,¾)&Ù$>r_Ì�¬±²º0pâ±–y{l±—üíupvc�Çq%_ž7“7 ,ró s¬™õÔpÖ—¸{%±�Õ8/ó�^ c…Üz.'Il+-"Œè·"ئ�í"×1û!ø�Ìhns8#ÂIÜ_VÄYÂ|«›s¸ØEž\˜ì:ìqeè÷óÕ8'À:ÿnF£ #Qkjà Àš:1Æl�Hrl½Â§ü Ææf4Ë%ÎŒ¢ÉÓçi|å>ä†vvI¼“?ãp¡O|Ëb4Jm]9Ô¯slšOe­Gƒ˜²„<~ÐemgßI ^,Û•�{9ÎÞݺÍ^[~R'Žö̬•9Ù�Z�_Ûui;ÇОÉW~¸2�.êØ·F¬‡ô8T$¿ø¤þ ‹5ÐÃ{�ZgLsBpØÒ|иÉßpšÄEFq‘pM„/΃ô‡�!Ð'?›úÆ, `|Y „ýF:x™��™£cJç¶Hj6È�IÖ“Øû|�€íàšÆ®¿¼dn˜U'üÄçUÈkšÎ–³Ì= ÚØ­1ƒÀXG”òƒÓ®ÓÄ2€½ÃGs3#¶ê�0óxaÆwÏ-'/üǯýpˆ?êŒ|Û@ÛŸÔáÖ±µ¡V­ 5àyººlƒ½s�²vkœš0a}¶lÅ@hŸÔË9JfLxO ¶Ñ n­+aÞrU¶â Ó×ݼ‹j!¿£Žvò=SCSìb˜ÛØí¦Tü‡•»Án=f ú¿5˜nó?¾qpêÑ(c‘D<j¹gBƒˆí‹ŽBc¿V+QiÓŸI7– ?LÐ÷]†q ÇÚV–~E“•Ç­�g7øX:·ðJƒ&Ž ï‚{Hf›(“Ü}¤&Éùhb~ƒIß ³ô‘—Sãa�Km·?§èÍ?|›ˆ1ª;â6>½ý†A_>úÖ„Ø0ðÌ Õ—«�À€¤Zå>aO›¾u!ÖjÅ\‚‰©¹íÉ­ü‰{Ì]߯�}9Ê1n}-—½kse6pø6&8Ä…ôÁ»ÜŠõØ OCNblå“iˆßäïã‰jâ:æðH|^ì㘪“áVjÄuƒÇ&ûÇÜ]�Œzì ¸åŠßºá?|Üé€ÎÍTäÃdlÂ3“Œc ³²òš2³?hÒŠ{b3–Ï€žAšã¸{'Â.ìz Ï�4΋4àïÞPÉz C¦±·«}Š;„­0ʼnß”€ØyW…CÄyyj¯¼h“Î/æ3ù úlÆo=ð½ÛFçÌ3vHâhyÑ—ØSXi‹W[rrâê‡q¸ÇÖ/|õßHvÓ��qýÃy"¾¡3±$ÚùÍ|lé~a®žtsÏ·Þ�!9þÕ‘GbjÊ`�Ìœ ÁÆQ +6s5všcx‰ ­�ø÷+rìN\gȸÑÃ|·äÙÈœ‹†^ +G-&e»^ gµll¶ ÝXŠßÄnhá�£75뛋ý¼èŠö-4‚ã x1Ÿ­�jfk;¬t„Îû�îáë-ð×Ë¿ìK¯Ö ~ñ}ÑõŸþIú¿Ï¼áF ¦Ø«í}32”4õµ É6%›p#íÝt#ð£?ú#®oüúÿúú�×ÿ®oþìÏþ¬r 6Ÿ@ê;µ.Òq.ì;Öx—¢“&ÄäKÖOÌ;ÿà˜sjn¦9¸¹ì}H¹àI»›4 Ö`š ³¾¾ˆ‡¿-™×É–à'÷¶�SåÄ¥e= .ÌüDƒ­·µq“wb†ú-’"–™Ù7ZòëŸÿ‹á¿ï÷ø¿|ÇõÆ7¾éú–oyÅõs?ÿ¿^�>ãúx­>Ò+ÿGŸúèõ‰/|áõ’¾ßñ÷4½°7 OxšÂÏ)é@MiÙ»&ÁÝ#¶xéÛõ}ë^¯|Õ«¯ùѿӵf³Üì�'yÇ"Atx‚W±¾i~é&ò=í þ)Î^³_ƒ)ùÜà �è…¡–›xŒnQä– ò”ÁÜÉ‘™y3ÖÙóÕ±n\âP/»÷žäŸ“à‹R ¾ç¨5°gÂé+UÕXscâKžêÉ«6¨Ó2â&Ž£Œ"³X8¾üjÕS›ë€MõHÃÙ¡cµž7ç—78жôiÆìº½ßÍò°ž9ñ%Íž60ÐËnñsø6¶÷äƒ`Ÿæ’~ÉbÇk€ØL^ +\jÞ½)°´YÕb�PÏ×6kZ#¬kë�9¶´Î¼'4Ùx[“€·ÖC_Bâà—Ÿü²)ò³zÝ,Ê�PŠF@~FŠƒ�ƒ],Ö…ñjÄ( ˜ÍÞ›†à Ïk�ùÆ ,6È Gx~l“�°’a[Ö¦²†bNìb­yåëÖQ‹�Ý9Èsâç¥>LF3vèË'cÉiñqØ ”¶NÚƒä|##ŒüŠQØÃõµÇ”¿Fä"Â7¾Ëj¨¯b/…ÍíVT�1ªÇ5_q(M†ð¼i3_x�ܱ¬53®œ-µÐ`KŸ_b§žÁ×;[”ô\ÀÎ ©om­cI`ý o¸lû&¦zþe/áuâYcØ6.˜Mì\ÇBáÅ‘“x�QÛÊm‚]¹ÛùþC‹V””/v– ƹ ‹æñŽÈ•BËÓ�ïÉküàc㘬cëàxâ;å°y~bO¾ÈÖÝ{£”}ÐŤRH ‰1¦«'ÎÉ(qçÁÕdägFFhÅf�ø0'k°NšOq­ÃoQœ˜%7˜+à†—1¡/ª0¦‰¿' Úcq )œœÄžÚæâzê@­á?¶ŒûèÍá–#|ì7Ü ÀáàTœÚÅr”ÌÎ)>!�{žÂæñe%�í†çŠÂVð˜Å¦†äÁü¸‰X5ä\ÓééÛl^X¬_R&^ô�mŸˆŒ™�ª#ö„p_Ð�ZÖ3=8Ž çûðI ¡Õ$4ÅmŒH¥�»¬;slg¿1@|Š”9ªUOzPÌyaQI{ؘ¥É8òŠ›îØ®e¤�ïß”Ê7{ Îè“·Gh¸¹zˆÒm×™©i,®ñ9^ÆÎ2„aé‘厩 Ú³öv¶g‹æ äáE�cøÑø‰N\,�÷Ê?º‘:±uA~¸�\ ÓƒÈÛ×yO…ñ/('gë4L/Å¡«#~~Z`°@0Åø¶e/"‹!ÇÔxIà¹ôëù›Á‚/3pÎf½_û³?ƒŽÌvCcyÄ †má$[–[ÜèÍÙÁ°ŠÔïàÃfŒl¯ñ“ú[ýý³]„Àãež6¹‚Î�Gn;>à„kßñµâË;þ“+±¸AÄ þ²¯øŠëÞÿý¯¿øÅ×_üŒOÑ;Ÿ¥�×rÁ/#}Ë«áÓF"ó%^¤wŽ8b¤Üàw>ýú¨�úS×7|Ýu½áwÞt}Û+¿óúéŸúI›ä±š9Ï2~Xÿð!Ÿ­#Nnp€™¸@[Oü åÌô L-JGJµ³>KO=¢�žºå$‰ u¤FË>PJIvþRlóa®¦IméŸ|BJ¡ç"™k¢v�äh¿ä�è“ùÁûäš8¹9;FöøÐ$�ÁÆùéÿñg®§>íÑë—~éŸ\¿ñë¿z=íÑGíÀþÓ{õnÐϼ>ïsÿÓëù¨¯nü9`ÌÙ�ã7Ÿr J[vS7 ¬’Üyv.ÓÇ{üzË[ÿÙõmú¨ï�ýè�\O>¤wüÝãŸ×„²Ñü1�ÙÇŽù„ÖBËÓ}íz˜;Ö‰‹ŒFçÑ>ŒÍ\Ø.õ´Ã;î`å1ÂZDÜÖÕ±�¹Ï-PW[ñ­ã\†_”Ö%E×6ç$œðL«MbÊS5A渲ëþê,çÁ5VÇÝ +S˜…-½CW°tìÇØ�ùöy(µ%w¾“CðÂs?·'xÂÄ;¼g޹9W‰°ÝôÑYGìá‡íظ�ƒ,ðó7¹i¼ê7›×ëâQƒÛœƒkïEˆ|¶®þHwÛ6�c8Ú(úú.?qéÍ: medFÜ{ù9¿Ì’Îd¢ Ämœp)Ö–§>™»Î.𩛸hUW‡Ú8ÅM,ô[‡©ã·öÝÖ%k|b”ÃF¹“óLí!£¼®neîF/nû»£òo� Ÿ\°HεµbO–“N´’Ž/ŠÜÌe<|îÔeJ lpLpÝ E (wö�ìš‹ákìÏnðÊUüÀƒ!àÍc*SSo•·¯FzleõdˆÂ-þ ^æ¼ìd�šnâÁÁùH³¬°0ÄèN;eΓ#Nò:âLàÖÌ1…»qð2biX[ÜWhÞÛ'òE­ÆÞ@àè+èSg]õÜŸP6Z\V\)Kú£…!¨Â•;ö…ƒŽ±æõ<9Õ¾XŒL_€ôJž£[Ó2š&hð Ï© uã9ž˜æ‘¼�3u¾ñód°&Žñj{Ä·zìØ9– :TŽC/ým“Y¨9o›`fÇÃÚ1Èk®3gnC`Þã½?PU !ä ì¹1bT@±Ǹ~èûQ ìø".ÖAãoÌøïÌ4ÎÁïÿïp¢Ûœh]°¥SlåðtMœ4Bù¤óÑbù<å)ú2úzòÞüTã›vb¡8ðN;òFyÇ;öJÝÚ¬~87—˜Ùpç"!ÿÑîá§<¢ ÏÇ%ÏE!�ä>õšŸÑÁ¬ìÄwŒ‰Ë˜f+sgÞ±:tÝÝ;g4�Ñ‹ Gô©raÜ϶»±‘Wvö¶OxçѸ�W¼»óågþ`‡£F©Ï`–*uäâðÉ'¨¥”³¾Å_ýá·L)ƒ¹ê ñ}mlj룱u|¦âƒÈs ˜?E^Ç[÷M#p:nŸEqé$ÿÖ+ª�KòCªˆŠ5Û×±©%|B�ïõØi¼Õã Š˜¨Ý΋›~øÆpާì»&AËãmêûøæÜÇNshÜ>V@ºÍóÄ“æNþ©Ùiÿàl–ÊÙqÌ �¬ "L¸s®ä\ÏyÈïâ’Îê#&>p EÇ$vűÒzÎÙ±³Lãq]¾¬Bd³—êL_ãcÈ œ‡Å“=ÉGÏÖXÔ$õL~™oËÖ þŽAÏpüÈ'ħ³¡ lç%òalj©ÅSô.&öã“zw�oª�QØ l¾8ß® œ&ùRÙ0æ^·O`Ý ¸N=u¦Ùo’æ|îså<‡Ûbr¥¾á$>"œqžûÁ0ÞàÚeüÀ3-aŒ|Äeƒ¿„�ãu±/_úhðû^/}ÉË®ÏüŒO¾žóìgÅÎmƒãøY#§çB%šk+==º½¶ñ•È:äïÐß�ûÝ7¾ùúŽW}×õÓ?óS~GNæ#;þ¾ß½{üy�á¨ÆØsDâÄùœÓGY¥Õã§{ƒÞ.�€\ííïxçõ×þú �Öþ®¸*ýã þyÅÛßþ/�ãÎ�$âÓ�â1s~ûX®3™w¹$O¯ã¬»i ^ò"·Òk_èŸQ§‡tíîrÎz¼|Ögý•ëE/ú›º ü'®§=•ý9@åQ\{OÞ“os°é)ëx0È‹wî½å­o»¾óÕßsýƒðÝr”‘¾×M¶Yß>¦¨_Ö57ãžúT®+óÜèǸícS[¸§Æg- 9æj®sÄ+¡„Óq0b¨£òïºÐ»>2ƒ'ã¾S1±õŸŸªÿŒ¬ºò¼cYïØÛÇð8;ŸÇ¶FjÂÔWof$.’±·M0N]ì÷º…çãpRóø©Oƒ#µÌ5›iy;G ð;‚{jŒ(’³^ ÙóÊ'ñ¦fµq ·Þ$K=÷yÌûTû›çÎëæH.úJÜöÉ“Xm]'÷Š[^x϶zväSÿÚ1¯-ôá`™õõóŽÎ×OòŽOcZ#[ø9š}â�Ã%ãIáA\ÁZMC£¬„o1Y‹XçÎC´'}í«VͺhÌ”yG–­íÆ@šYÖÉØÐ‰Sr8äK‚FíÌ{‰»¯Éà8ëìñkƒØ‰Ô¦­$¾¿[ÞœâÛSÖÎÉi�„œSK=ßp=´Ü28±ºfÈ6ÏÄldlÈÿ¶‰û[7ÀáÝò€-éüxpŒòžçwÕ3ûËŒ‰RÎÛܘ‹Ë¡‡Æâ€û�Oðì'…y”Ø`d/ÇŽÚъɜ׎ܠç<ä¼lá¡G­ÃÝœQ®¼™œ¼ˆ=óÓæWß>º:|‘°Þ\'?Â\pÄ0†øªîÚÍ w›`-²å„ŽŸ!µÀ%sbê„…¤åèá.[òÁ‹o¤Ž/co7éñ[EÆd|âîÿòï~Õõù/úœëۿ󻮟xÝë®{zQEîþ‰óëÀSW½€C=ؽp3¶Œò8—½Ù³÷äÆ }~4öG¡‚Ú`çuŸ»ù_ºsƒÙ ð£�±Œa«Æ7ãÚ.¼ñež”«¶Ô‚ èÎÜ,�|ý[÷±á‚<ïH|òúËÿÖ_½>ïó>ûzÿ÷{Ÿë©ºñ‡Ü 0ŠN3¾zæ#÷Pcç?1l~ØÂ=Ü}ãï-oÓ»>_}ýø�ý˜nüùÖŸ”ùÅ+7z¹Ùãó¬ìƒ«çŠ ŒA »ïÀD•Ÿ`@Õò }dÒ ]zÓDÇy±dÛÌ#bè‹k'¾ÀÚýxȆú†{-ïU™ÝÌQ#ÇÔá|¬;€-üÑlýZ€x.¤-=îõJ?j\ð=˜¤ŒZxwP&r—Çìð-õù\ð…UaÍ쟚$A"†Qê>5ÃW>½Ñk,f± s�H¨AâÂs‚"#†§‰%‘[M¢Ü¹zrQ<æáà ¾0OC�¸Õ5v>9²NÛq1™#<¶Ý�Ê8©ò2®M9ž7åÎúyŸ:îx(LÎЗŸ¢9…™�\ö]–”w w�’|ê¾ãPKrÕA-¶3ÞaH$-*VÉ5€Küoõ72T ;>£†Ž'L�& Î9Ç9˜z¾)öC!ãG¦+ß@ä¤ôå�ÑrYñ˧µÆöWŸw”8úJ­<Ø£MG@¬ÆÿäÞpÂ&�1˜|›,âQ/92Æ$Êågã[5l‡„Æây™«™¸¨ÌGÞ·zç¬MŒÉÇ©´—½á&ÓñK¦�Á‘.µ±š�€ªÕF²£aOç^^>1ã«8þ’rÅ8‡Øj4ûÏZÑŽ]o‹V&™Õ,»‰hÁï=ÒÐÎÚÚV1Ï'�p‡äý-˜ƒŒ „§þ+r™¬\ÊSò`«_µÃ.ç×Ù/¢ˆ»Ùg6/üTφ½{C/ñ•áºÑF‘ägž'îQ_#—ñQ×½gø ãÊÜ&ª£¾šOl8ƒô%Nê1*Ùß/~ÆmË‚Ý"'Ö>u¿€6a<‘æñCO^íã ]oSÙUWû".¹Ádçk‹ÄìcUx$ûO‹!¿y.Ï"†S|d¯¶– cõYmô}g—†4§V“Tø™DÌ p;ƒÇðú�@âÎŽŠ-¸|á€Þs°KìL|Ôø§·¸<�NêŠÅÄÀ¶1%s-±Õ7Ï¡ëilqóŸåÐ{>yÂ3k‘|”7�R«‰…“=ée•ÅÔG0ùM¼ª.~z÷Ýïýþ[®¿óÕ_}½÷{½§þFà‹¯ý3?U7õÑ`a–·/ÐH(;èpC÷.šùÊæQÝüð?ù¼ëïþçzÑçüÍëU¯þný'ÚqŒÞ�2ÏLžâgòóœàÎ�2�/”æmõ©(¼x�¤=«(Q¤`°ƒÒ,Ó�ÞáMN½ë0sô©9Æñeµ87]úoÎC�,wŒJìøxE?±±Egë÷a˱WGml³rwÕé¯üÕûúüÏýìë}ß÷½/þÆŸX¥1 LèDvŒM©ì‡?Üb:ôÆD)“ò`ºpîúáM>Ø=¬õöű?�r62ë2µx^c—_êÑÜGßç&&�†_ró¶é/! c†êú`>ƈ~皨ØÔ×5ÿ5GeüͶyØïAsLM¬.æi+7¶áéw¾ðöã6ìiï‚ã™®yÞg[G£87Sp}|Êá™ ŠH³Zwt¼‚ÆÇ©ÛT“µF2:ÇöQØ•ÖÄ'�Þ8cœºÖj"iФ|F:]ç)þˆÿÑsGªõ¶‹$1²Wƒ ßp>k�µ|M.ü°I³c$�'VKßÊø¨F>^ÀGs¸èÅ-�0Š·÷ö„Mö^Æ'íÜ“‹¢ðšcíΑ%fì²gôØ©ŸÛXø‡£Gâé:JÖlÎ8s$¡ÄKM…áE–—¿�¶ÍÇÖ©ÖcGïÎÊÇ”‰ ·¸´‰²å&ÕÅeêYKüá²ñ’´à¤fjØc™i�•´F|œšÆÇ ÌÓØ©M¸aq¶áqJÝÿ5ø=¶`J9˜ë®é¤¬÷Ë»²Ç[âñ�!Þòûo»^ý=ßwýðÿÐ|ŒR^B7ˆü.8aùŸÀü1Fù>öØ;­o¼ÜØ”¡êÒüˆáÞô\7È�6�Ö’ë9ãѧ?ãúŸ~òÇ®ç<çÙ’Q(ÔÒÓ©|ÆüÖúïxìúwþÝÿzóï½9v:W>¢�®ò1e>îÁ _\�Z¦ƒ_ÅÀà‹\õÅãÃÏ­­¬Xjhá›ür;Î�]¼>÷sþ“Üø{ÀG}Éi¶Ç ' žÖáAo­1þ�ñ_}õ7þø¯¾¯û‡¯½Ryëoü¥ÎC†¾qGÏ �ödçÜÈ ¯µfÚ—`ÜÓóŽ} ¬qZzGF½߲Ş…7@¼lf¬½o\Í;ÈÄi3ù°?œ?ép{�‘8`z�x\ÿDK^<{ƒ´ò²Áß)ìÔîübÓx‰é›?ì�ž+¹fKu ’²å¹‚Dóø Ÿ)—íË?¹œñÇÜÅéÀÄí®âEéw…êñÃëΗ'V8c·cßvâÜŽ±èŠÇ?>ß%3v‰[¬ë—½šZêcŒþ“Gy\Ó–†íxÖ̸<Ša²qý¸�®ÇLægž²ø¤Æ@4gz®ûøÓQäq�ëÊÁ˜PÙG��_Ðßõqó*/ñ\kÝú�-éÞ$€¾9÷òqËý©Í!ûˆ4â ßäËHã‘7¿Ó÷î¸u² ÝN®•�ÆÏá¼¾åc«|˜õ–Îy�í9¶¨Àå{Ës¼VWN›, neØBµшkt?ýp"r®• ¦'%�w,ÃX�ݲק´Sgïâ¸í㻃,;L»ÏŸñÀÖŸŸ`;l¸Æ§:Žá²ßq³74¿Ùcä·k³¼·›EÝ7LºÇ™?i¦Úé±sÖ¤µÆþ”ßø3¡ ç´)¾k(®åç^ÆårîçO¹¸&‚u/ÿ^[öÏßÔß¡‹‰»<&–ã¸FpÅOÚÄŒÈ #ΚÉôlplžÉqûã!]WâÂcÇ×tz<ÑÖ/y=;��Çæks“ÀdÇEgÛ“_É.FÁu"ÿîG€ãµiO¬Õã¡÷x/ý @ŠÆäÅètz0(Iø×‰›ÜBG”ذÐÁ¼Ý,]0'5]œ3>Åhò'þØS·³•÷M‘ÏâÆØø dþ€rî"ÙlêÒØ›«ú;Œ'F—¦>ÆÑá†Ïá*ÍlÛZ²ÇäžZr3UOˆÇV9¬œ©‰'‹Ìðã6·ä2qFî'q‹UöÍ9æ"žZr�Lñkw·‡gø›°i›�‰†>mÆc"Ñ}òî‘¡ºë²kk® å›Šæ µ¹h—€—· ži< F+Ž÷C¶©©˜æíIÛ•¡Ôà”\¨�Îjë&†.$yì¤B!3–¶³Ä±çŇÐîÆX†àbëd,ýWš{­L3´¾Y×ñézî±Ø)œë(À¶å VÆŠM†ÙûËä¾ Aé.×$½Fçk·]Õ}ϽWWBº�¤+*vR©ä?p 0Ø�@DÆtj°‰1�TŽ‹†T%ùBa„h…@–Ô Ü”S‰“8.'q*ñ—|¶Q  Ðmu3~c̱ÖÚç}¯ª²Î9{¯5›1ÇœkíýìgŸ§ÉãŽåw7kްן‹X61nŒç·rÃÕú¬¡âàÓ~mOý~¶tnžSŸ{óµÏÝ�æ¥oR¬re┌�µ&DѬ<|®ÝL5¡…Ø&hÿ)Ø2�ÕÆ��VK.¢™0vc„±¾eÂôª…{XRÏ,ææ7Æ'_ØJlW.Ôj²±¯‹#Iñ/胇?Ü[ˆ-ž|RÄÁÖ~è&ò8àï_ÙË 9À�øæ•˜Í8s0—]r_�¢3˜Â(–ׄA#¬ Hš“툩?7jAclºÃCcœà[YCl¥ Û;§Èœkñq)0ÝÊMàN�'>f—pzžÒøŸ¹­º,\{¢¹�¨9Ô¿–®‰èýÊûM~pš¶t«¨Õd�iC6–5p“2P3WÙC½1®kg'tMÊó[úq‰fo‰kˆ¸Æƒ®aæþÀ4ÙÌíÂÝP;Þ¦—ü FœÁ_9Ë®¥‘zr¶ñ�‡Ôÿän�‘ðËzÍ ð�ŽŸ|žûrA\‹hš¿ðí?X(E6qÎõ�w=Ãz¼¥'1ðÉ[àòüì¿óîõäyJ4˜`Ë¢ÕÙúȉY³è“"ÂjÛò�‚‘¦f”wß–´Ó‹Ÿ#¸ÀT35„ýâc‹Á—Àüâ¿ãÔ',·Üo§‘iâ”{åo{j,›„r©cioâ±ÇèÇ™ øë+AãÇL#÷ü4˜$Ȱ¨Þ¢ÂÈÎöXM £™H�ìaƒU—Mz°‰›Ïs‰aä~æj b]8®ì¡Kæ5‘½[1p¶'ÆTÏǶ`bÅ#¤9î¼vÎë8­Œ|syn*¡Ì üua«cŽžo’Ç„v4ž`iý0qxðö{¿ÿ‰Û_ÿá¿~{Ó›ôÖ`}kð—~ÉêÕq�¯·—{¼ï³-ð¨ÈÉ7V9¯`{ÙË^zûwÿ�ëöWðûo¯ÿÎo½ý�_þïn¿ú«¿¢�O™'æØñq7~û²ñ$¥P<‰wó·­2Ì«êbÒ)ë\Hz‡,cê~•K¢ÖÛNÛz”ž'{'ÅÇXp[÷ŒPŒ!üÀa<\r­DEQ §±Îó„[ŽêÇÜù†ÿDPŸšü…oùöÛw|Û7ßž|òUó®4s›áÈot¶¹»¯ õŸ}æ¹Û?ô‘ÛOýÌ[o¿ñ�÷kJô£1=ð^¡Ôá˜ò9^ªU'3Á[W||S|òe.|�›Í<ñÖœ-Æ9!½Ù¸‚mÖù�Úæ�ÜX¡a×m¢`ÆHXæÛ�5æ:(™G ã¨.c‰“#z’ˆ�:î¶öØB{[qÒã�<’«ÖÀ¬y˵Yu¡_”j^‡Kftcæ-•Ûfc�kÚr#‚Ê÷ÇžvÒÞ¾lìŒá™Ã8D<<¢O�ÑSW�7y'Œê �1v#®¹†æç1›À!^íú8Šx¥fàY}á4gæÍÇ>úe�ç|F|°=ù³Ã¼18É»±†°¶òÀ(¶”2`‰Ÿ=ÿ`ßÇv0ÌY8ì¹ÔÂæzs+5'FÇÈÅúæ�TæŒ7t —  ¾zñßc�gìMÁŽÉÜ–«Ô{Ûçº/g³S*}LÇË S¾ú0šä²ó7•ˆ:î›k§ªøÁB#LA9ŽáÁ¥5î•¶¡Q½Æ#k�z,de8ËTC$4úY«‘xë ;¿ŒCÖ˜ˆN¿`Q7)Œ› #+G°šÖ¹¤Öx �ñæÇ®£ ÃМš;&`5GûÉÞø¶@;ö0y,Òï�‚PßõÁY üÖÉÈ,¦=„^iGîõ§¨øë\ûz0.ˆmsŒeØ·USÏp–ó`2Æe!ìhxÛ†þÈy?±1,øÐ·¤qJ5òè��õkžÛ6œŠ!=)CêÓ4«ý@ÛrÁÅ%1†6“—åÚx­odå=æ�·±Eà¬wGä¬s Áœ”›98íãè1öã‹ö�Ç^õÇý1=-òð$–È€¤t° g@œ¾"lßå�k“Ãq1Èé‡b6ÁZÝËN3îÎ wpîÈä’÷åæü‡¤uÀüô‡ ­úrÂÊ\ÑÙI<×ßœ‹$V²·~kÎqãr‘L=ómrëŠ<…];‡p]rd3ù–�Mùwhî‹Øøœ £ëü4/üI‘ÿ&ó ÓoTžRX×"9ÊAÂð¹Î9x]ío,ÖOìѵ¥îð8ÖNkOðiy«FþSkÖ¢TŸÚ°w¹è,_Å\ (° —Œ´­mÒ¼ŒÍ2²ù‰¿æÊFæ[€û’™:ûQ;ìw#¨2�(K)ºÚ�ûí“^ëXßê#ÐÉÓä+5æåhü· ü® ˜v¿òë>3èܦާßêßÃ�¸ÂÎàïW„í·„"_x& (³®VŒäk%vËiÛG\‡sD¶�/—ªúÔÒoÍ>¯¶Ú-q› ä½¶ãÝã`çœùF»}‰›Ü6rzá»Ýü¾â3ok‹Ob`µÖù ÇÕX;¸yÍ� 7ù-9Zû˜y+h£‹×y\öq‡såþïâàÚB°ê ^¦v\8Ôþ¤ëzâ4-\2H­£k]<‡Ä— 2ÿçN}?îðìÆù¢ãV+ÿp oPƒ‰^ƒ@§Ob�JJàôd©ÝGzÙ^xš�«„÷ñÇ�'$Ê Ž]!­iý2÷h ÄžÿY÷ã×qõøD67 4.^ã ¯=²sÌq³Þ¬ãÛ ¨± +öáoŽ·/`·Îuv "6.ýÌ@$Ù†'}ükÛþì%f¾}š‹‹Í§>A7_=iÞÿ±'î¶aÔ]›Q]Ž[j®Ÿæ�ËÙ�dèh-oŸˆõ3Ë35·¥m»H»6CÌxlÌO{çä¹@Z^Ó€2e¸û¤~áV?ö©e_ïcÆ9Äç÷uñ¸yXË\܉¾Eæ¾,©ëص6Ô0 �Òöü�À~z\”í¼eLbŽ7õŸR/0ʉéY… «ýŽÇÚÎû-s¹MÃz (±ÎBnqs­7í[Ú—–˜»ßuM¥cHî´á VEþ�c—Zî½ýpä—ÚÙ†;7p|‰yúÉ¢Ž9€ý7 [sc8P—×<ùäí{þò÷ܾìK¿H77†±ñµêL3׎ ®Æ®6è}Þ³Ôjáä¦ÓÇ>ú»·_{çûn÷—þŽnB=£¿gõD‡'9i|ƒ0­9Óït>·.^Äsè¨å^(7s¾ýãßzÿí ½õyùL v]æ-7y ðoÿëeçsΕÌ7o¿ë«×.çtG4š{­¯ÐoXð^×…ŸÜé›Ö�Ù×}çënßü�_›Wüé­Ù^û­1´†é^"°Öu¢ì=7ØÖW¶˜Ï=ÆoÏþ©Ÿý…Û{Þó.}N1¯"¯ï«Ò¨¹a´§ydôgÙØÒv§5÷Ú“ÝÃ/}™|ôgRÇÌìÕ´q¼•—ø*ÎX`e›®Æ«ˆ|Á8eŽÂð´�pÏ0Ž?6<6rŒs옣ªÇ7• ±&¿ä‹qqôÈãÃîb;DlkVË2¹ ¿§åysžÒoç_ŸmS·D]øe®»ZˆŒþéë<,\æGG¹fÓ¹2וZ`Süø' -xq+vcE^±…CÇ3)O¹ñç¹C0‡µ¡æ\‚C,þiË90Û‚-€µÃ¡þp6‚öwæ¶´V c—ù¨O°ÃÕ¨lÔv.¹�©7zþ©Ã?fT·õÄ{¼ú»>øÐ7õLŒÎÁJÃ�ÑÅi<µŽñ…ã�9Øqòܱ7S}”‰ÂÎ÷”Öº‘•w(Gx¦(IëQ¼®Ï× =~]O¨ðí?Œ}ͦqn¦fN[£œäpòltç¹hÄ÷ß Ç8CHÄ?¹ÛQŠÅóˆÉqù’ùö?ÇŽ(†>l×D�2ÇÓF2óžØÎ;�܃sİ;²Z>J�Oðô?†Ž›Väl*/DZ lp§!]óÇ«þÂ¥Bö'æˆaD-³ˆ"ÇÇÍdÕ»ƒác—L&�ìï]�?önàª{×ßëvL.>²o-÷[üå|Ôt±%Îà£rBf4:ÛÙ)â7ÉçÀ0æÆVÖ:vgÆ9v¸˜�t`²ÕÆmîúU~î?�Mu«N'�“¯j‘:éäÚiŽ�•³xk/°“�yEüc¯úcXj@JL1O'”Â$»Ú§ réç“+RŸÈ{‚<1× ä&.Ô�i›,æáj¢çÿ?Mx.Ž|Øs£…æÍtï:¡æ†�à[`ühkLß|ÓL[upý$͉$vkrdzö›£1Zù&7�ÿÜQ§£Jž‚'4˜qím*¾ÇØ9ö´,‡ô;žÑ%æer‚$‘� ’ª¸^êÖ÷Þúm®µ-÷EM±ZïkíœÏɃåk×E5Ë«E˜ïü§O”�ó{®&ÞÂ>kr7—꺜î¼ÊOÄ:G�S»’îJ_oÊjð‹—} J°g½Í:Å/µW6æ¡��wäöŠÍ¸Xwk[.€rìøbRŽk^K”¨Š]Í/s± ÒÐëXx1ý‚m ïB´þÝ ™D.ÎÏxØ\9J g»Xb8åjí" ô‹¿í&†ñ³�GUv�-ç¼ÜÌ«Öʇ:´f6%Ø’?rmm}dÂÕOÅÅ ³à®yщ·QÍ\Œ $9^..äLJ©ß“w�ãË(2»½ IDATºìmüÇŒ’¯¶Us ´÷pbäÀ�^vÉ 7|ùÇSÿZ¬9î DÆqiÈIÿXÇÒã|MèØ,nc\xäO¿óÁÅy_ñÉg„¥¥Æí³çܹÖÂ}ä(µ ¯3–x Õ ¾�'´=F¤Ùk[[^ù×WKçqGA E´t—c«¯D æDi°j�´±-›¤ª7¶d'Fí=ZŠäÄã1"Î眇¸0Ï“nþèÕ]:×çU‚<R_Ø–+/*Ã7?þØczkð¢·ÿ‡úܼ'ô…"û3_CuÏõî—W*=rH!˜ÎsÏ>ûØïü¿·w¿ç7noý…·Þ>©W:·eG­xÕ�jD=lb·ð�W|]wì©™b¢{©¾ä|àÝë3Ë�B™ÖÄk>Ÿ|J¯Ô—m|èCô ³‡¹á«Zò @nñd¬\2—×ueüÁ̬S+q3'"Æ_æ‚Wd¾îuo¼}ó7|ÍíÕ¯~B¯øã³¾V¡Ž5S†íNþ£Bäܰ=ݧŸæË=òï}ïûoŸ|VoÇæÇïGßï¦ ~½I×�s@;îMA‡±�ô÷ .±ÿ9&%7}}Ç ÀEÓ¸3‡®•úÖsÜOaÊçnMâ+kâßm�Qgg¬æ‡p É9=çJ>k˜ùÈÉ+¬OikŒ�ÅgÏÙŽCØñG§$ßC±À7Îä[‡s¼\W"ï«¥éï*’ü&¿­_´%*fã1¶wÝ3»+ñ2É©àOËuç!wøüY¤ÍtI’ü؇Omö8~­Cr Ôí¨½œwnÅ–Þ ‰*Cnú¸æúwò¾r=üeæ›?8» Àʳš0Eëú”8cõáAKct-ñØ÷õÎ-‡m¶•mÉîm¿ÌûØ;x­ðÉôÒ·¬ÝK ÕV�#<öpìäpc穬мùvÜè{oCçŽ=!ÙÁ#ëa×®>]ØÝ{½À|Ï—�õ�ãžd{¶ (‚h²¶+»cÇ0äl—¹»ÃoÕîô½·ßç;Ô29,hS/š9ì”F¥¶Ënx¸v#/—ÊpZþt¶â¾µ ߘVνÎ(/ ÊmÕlðöü\�Gû–j�{ÙO¾‹ž¨V¿d8O.ùN7LÝ£G¨¶-îô…mà' ‘+il¸FgÎ}ŸÀÿ©Smâeo°�+¸GúöÁ³ýä,Pé‚�Îõ1ÞöGNKw0´Ÿû;Y—“9ðDí�üË£@wöÍñÙ?Í\3ô1‚¸ó­}÷p&v[ï ñØØ|È‘ë™ú°¿Û�äÙû”§èN& ÿÕ–% _8M Ý!sÃ:Œ^¤ÙVŠM„|Lf–Æ×xeñ æ�÷iŸŽ(,±óÈbOñ¦ó²¡ì`›. � “Øc鸮^­^ب¨m€–näΗ>Ô�ÆP»~FÈ6§Ö(¶ýÚjì›§÷Œ ä>å7œv~ÔB˜8Ù>ã±fçº�,7ˆUC46¹è§�zo›QÆö¤«�kîÑé×<ÆlÕÎR xX*zjÈÊÇw]8æàÆG =É2#“5ŒÇÅb?*ó$Ô >ýÔLø�µGLÜ‘›b¹Êa›g]…Àã§=6†–³ÿ+67|‘ûˆñ4°~S‹ÃoÉä´ørh7>8i峨ÀÉXhÃ;CË.s<…aÃà ëÌwÌìŸWZˆ©ì_^�o 6[ÐùÊ+T�‡_nÞumüBãR+k6d 4Þœ³|<ž±Õw¾œˆ&î¡V-À׺Dsn+V� ç¬CÖ ±R‹)¥?g�Ú%TrÆŽPä Á+Ìšg$)ÓÖµøñdÑš™0ÛÌ Ô-B2ÒHòæ•RÁ» ZßìϘ°b ž±&¦¯&¸-̯x(d¨ æCwüÃ}%žFìÞl“P>á®ýâI?u°¨öR…r4,ˆÊ~ëÛ§vÑ�™¾``Îc-»°MÆB°!È®8v˜qRïÁo!¤w<9%¼Õ„nä› £ ‰pñVýÊ ?ðñE½áÍÞüäTÙ„³Ü±±–åÛÄÂ&Þj¤0�'nò=ð€æ�Ææ Ö�³]¼ÃPö}…³ý{¿ÿñÛ�ü—?rû‰7¿òö½ßó½·/ÿ²/ö�©‡ôvU3Ÿd¹r¤¿Z¨{ØeR–µá\Í[[ÿØ¿ñšÛw½áÛn_ÿµ_u{×{?pûéŸþ)}‹ðÓ~R‘Xâ†ÓðwÏo^éHNž3:ké>kW�i>FkG JÆü…]àèÔ<IP�‹ÁG¯Yqˆ‘Ç 9�ù ¡˜rõÀØš?_„>x{äÑÇnoxýë•ûWÞ^ùÄã~ &˜»žH lb1¬Ü}�ϸÖ!%¯ëŽ—nüé-·|3óO¿E¯ø{÷»ô XF”çÀ…k¥¯ì#7Zpw‚Y�äQÙ¬I�]7(X‘M1s‚r(Ö}l|÷o=æ�âÂГc}…ELç)™c B.ösMƒ¿ÖÃîæßºæø0V–Ö ˆ‡{lɬð²|&ËØÃÏæiM†ëöóäŽAëç{¸-¥® ØW0¡N_É“·PL -¹ªiƒ jÈÒæÒ¡Ò 6ì 2v¨+ {Hí%¢}ª~ê=þ4äX•£Kß¼°´ ›àtìq2‘*}öF0ƒŸ5ÏœJ“(ÕÏÞþîǹÛo XMV5´Œm¯ŸEäj(›Øªö �rÐ)fd³‡»„©/ö ŠOrKœ:ÖfìB›QoŸâȵ†üÑÌ%ÝÙîœÔ;4â c¤þ¤ãpØHx®ëhê w,ƒ•çŸê[†ßÂÝ]Ÿ@§rx‡3Ç6hàó8 _ àsãCÔ klð“¡ã€J­ubï¤ 8û°'¢z¸^šDî® òëP~~‚=ùŽ©Ý/8ÀküÐëLÇTìh¥9ÛAF†»¼1nbœ}8`Š5ÉãññGôã{© r;ÓÙ]â´öØ/Ÿ b>ö‘?ó–÷ô][tC:c{ÄGÑ�p°zì.Æ.ÐÆ„߯^öR6>¸e…O!Úïô57ÛÕß9çŸñÁ5G dÈØcWÛâ„Gäœò\œÔjkL'y·­EÇr÷}ž�Ð`$|¸ˆTq¹&˜²ÛeÂÎ×–Üá=E��t™»æ òε�󟘫6w †mñ%W5ì�c~�ç'ˆwðõ�^«ÀlÂÉXUx¯�ƒ8'Ö�mtÆvI7!�lÑ{±/¸FºH`ÒÚÞ.é¥�Rë‘À¼l¼7.ˆbRˆúÖÇ¥â\lÔMÂêù—\dà„bgdÙòSž+gLæ»eCMÈ{|Ö�`/dG}l 'Æj—ð ¥?>6dƒŸv`ø¤eÅävØÖfÔ³Û99 œeèüÌ?}ŒGú2bìùT |­ï>ih4ͼ·�¥XÂx�[§~PhnbJ?X�‹ðª\d`›Á£ß\àÍÏp?÷ =eÃÇ{wbq’wz`¥ÿ ³´ú1nŸ.u³³„>«ÅüädóÁYù[ˆ¯Ü¸â­S@xá$�¸Í'‘®\öŠM!ÊœÅÝBÆ<`–ÇHJ#…³U©aÓï€1 ›tl=.K;H7&§‹½$ˆ.Oà0fŒ¹?ÐôÀ¶¯.ˆŠëƒÜ°µ<0 M¬AY|PQÿÝ2·\Ðñ”1:[¯H…ÌàüÕ.|OØäS»†±Ñ¡rÄ{¾ê™m&,ø;� 3µÁ6Ò`8’`£ ¿ÄßQ$×�q}¥žöQu\ ç w3ecIjâ¡6(¯¨h2gh¥ó¯62uE—9�øïãdDì¤rîcƒ µVÂ&‡Ô"æ}êFÉØÁÀ¸Ä¥Ùh8Ö~ÄèÜØË—1§[„eVÙ(ì­MâfÄçØrPNNÖ”|±:bÑ·qd`ÇB µ`æ18sûÔ!xصN YHÕL:Ý];�›“õÚˆCÎ-ä1jÙäfNüYV‹Ã¬©ä#…¹‘£WuËÜOŠ@r±Â“øy²47 �•žÓ2ñy¥ÿAåFàõßü×·Ÿý¹Ÿ½}÷_úîÛWü¹/¹¼"Ð7¶z.WÜEøè7J»š„Û�Ÿù™¯¾½áußrûÚ×þ¹Ûû?ð÷o?ö7þÆíùžóg-rÛ±|íè\’Ò¤ÅIÇ5á€Ü¸ò^ŸY—–=±Ü~c°øDÏZÞsЬ¾™;n¾äË,ü6mô~‚ÙxFÉyÐ7 ‰›ã‰=úè#·¿¨z¾ö+¾Ì7VùæµÖ¦6P¥FÞ§þ‰Þú%Òu»ìÔyJ7þ>òá�Þ~þ­o»½ó]ï¾=§o&–>âö)-¤\7² íÑs°¹¢9û0a¼|¤'C?„`ì¦|‡4{×Oؽ³5cl–_µ^4–±ˆæúÈ&fÚm{s…�YÁ=½UcTjŒñóþqþ&ÀêaY9ûÃS‰ÊÙÊscó1ÂÔ14vˆpi�²ÚÊÄc뛳`j°òR?7k±�6Þ[yÈ©®m�›m\;õ£sb‚ƒ[|›{�Óëü¸¯MÏaþ—AIœ@ Áégzƒ•êR‚©=#K‹˜gC·,e³æÖ^©«ãJWjŒm7�»ÁmMòO/YùD‰fób´yQ;fÕ…cÚökþkM[&è²Fð‰ïkÉ9—ÛŽÆ6�;uÆL-¹%’Æì(ydtÚœ¨Úômç›kîiSé]‹Ž›Ñ–ÔG2 “gð=F-Âb4z»Ÿz[$;t�g*{æa%Gm#[7Àº ®šÛËQ§W,² d£aµáÒÇÜõnxÎ<]0@õz¬ìzœj(Ž«Hƒ`r ’Kæ{ëqWâ^ò”,> zŽíeç{0…XÙÎi| =ó–Z¥Ñý9(©£˜1ÎùuhÉùÖsE_?—¸®ëÈ�·ñS² ´ü¬ˆÜ¸p‚_M‰2ýÌOòql1±ªù8!iÌýX‡õÇš~cL]„¬Zy0xu¾Ø·ž¨;ØÓM^ªh,¨Ñ¥·Æx”›lˆã[Jê;Î<ès:À‡4ùó–N 5¡uÌx$V¼Š�ŸsbM>9ílò8½±<îgár\”¸fÈôÇjé§–¹Æ”œ/!›$˜k«¨öo€Ú¨’ší*›}'é¥Ü~ûÐùjpi†› úIHF{ß-v-– àR¼;^¤Ü5…‹~GýrÄ޼t}_æé;­w0wìíO $ÄÒ`Ó°;ùœ±ª·¥6øÖ]\ „¡sΫÖàȇ›Ûı7‚sœ|‹Å¾¹›âà™·tðC´8qqÏͧÉ?æÙšÎ2Þ9ƒæWcÌ[¨>¥—›3*oS«;|eÕ±g¼ëRž(àpɵš'2ì\_¯±D`½‘—ç[{Ï7ÿòwºêsr_KË ‚lªeü8G—úÛ ‚컭ꨡU{7{ž¬æåæy+‰ŽKŽŸPd<7Z„±ëv•—sê2gž‘Œ\Ægݲ>„7‰žÔáà·­*/¿}^ûð*b¬Ã Y 0\!† UûÜÙ,}0/Ú¥Ü#vëåæ~{ù¥Þ÷¨L¡%›5ŸqH]vx¬Üêdb:›¬0WÃ,-jÍ¿EQç! x{A RÛë>óS™pô»Ÿ”O á¹øyÌ(ÈIisèú­hpl©ic/íáž·|sìð…Iw“§±Ð5ééîµ4ªúÛNÿvý�Øá=!¶]È-ɉùÎÛÚúöùýß÷ä`²ªCy’³úYë�ϱ”5S‰‹Bò.Ò±Idûœú„jÂäÏyè|kºîx7Ì}ç¸�2rÝ‰ŽƒäUA«¯¦17kèa+×Ã6Ä2èc£kÉ?Þ”7õmξ1¦‘qêãìèÎG�+n›Ÿ6a_×�:ë,k1ô¯FÚ§.œ”;¼Uù¥ú¼5Î…ÜàíXäÌÄ;ó£ß¿p W>«Žük^óäí»Þø}#ðÕúr ¾h¦ðºoC<ù{?ƒrÅÇKæàN>ÏëËBø¦â÷}àÜ~ìGT·8sãU»ä®ZæÕ];.ÜóÊÇ„Ì @å¬W-¾ü�Þ>ðž_Ó7Ïg–Ô÷pO�ÞŠüôí«¾únùèGœçs>Sñé§žº=çóŽÃ�}’³ŒÑ<ï§7ØðPóñÒÛ÷}ß÷ß¾ê+¿T¯øÓ—­¨~kÊÃÀâ¤1”2¿0d�]@§Ÿ²|¦"Ÿñ÷3oyÛí¿ñþÛ3Ï?­kÕh®eÀ]ׯÆÕÆ¿ÊF êÛÆ¡Ü{®šMF=6Ø)s%À>�µEN¬S.Ðó6FbØÆvYãåÐ5ÕÚbÆYƒøJ6å™`³+‚™_üÎÔ ¥×Ç0C¸êøŸ/nëƒhŒ‰>øÓ²-Nj@þÔc0ö—±|ô‹Ì¹¡nþ‰æèÄÇ*Ìd›ë Ž—ãc[†P­ÙÉ!á /<,ö& ”Íq‚ÒyßrΜ/û€p¢öäqÊ#!XÙÕ¯¶j’Ó5wl¹FCcòÏõ/óÃ9½õ:ó9u/d�JûÆu¼H¬©eæÝ•¶e}¨1¿ŒÓ®v­�çbŒNÿ‹Ÿp‰ôö_XoîóÛûæÔØ~÷•YźàñŸzg� 6f'wDþâ[›�kßNÍ|óœÇõUÅÛk´X“áÄ_a«ÖþÊíT¨¯Ú¾˜þIJ�ë™<}NçŸa:v¸ÆØm×dËÒ;ñîê'·­iÞ[—õœyMÞYEñÉZ�Ä9Q¯¹fÓå9x|Á|4ÀÏ8g-²«>wdà4¾1Öâî9?sÆ·SX�I-9Wú~óm`oé�-‰·ø¢³4¸à1¾[G0öÚaœô‚Ÿ ƒ?…9}èÑæ�"h-DÊõ.X÷!kØ“wÕÝ“%zÚ}ûırêá¡6 Zûî1ó5ºt| ˆ¯e¨3ãÅ7¾Öäӻϗ€ÜÇhl¯;ÙG ·c0~_¿¹¡äœbÇ#võ?üN‚5=÷MÞû3îit§¿|Z˜Ñ{’ý¥¹Pût ©‹Í®N>ù×çŒ� r×gêɷ¶Ø­Ö!m¸¢ïÉ'O¼ýíN÷oá1–ÃËr¯—— Ó\^ú#³=0¯Ü{¸±ÉgNþ2w-ìôib ·7!ÝîĪ~ÅÆèàfy<K;õ2ö£'}@l Îù Ž)è±7_ê0²û¬Eç]ƒÉëmš§!d‡½_i¡>OHû:µg'ø¥Ÿø+Ž9íºcM mŸ"Óu³s>×þ΃µ=‹0Qä 'ä^K› ¸9^�ÑŸ›O%w?†ë‰�á¾è67šŒ+»Í‘¼ƒg4÷é¥&•±¯ÈóG}ebŠí_ŽYýÁ©ÆLÎ$eÍ¡gMòYr¾ùÇ?žœ¿nÀpÌš/¯:K;`Ì7kíÜ„‡w(9ú“ú²�7¾á»n¯Õ�,F nŽ«�x�ajÐÔ—Áèî#çj?þñ?¸ýýøßëíÈoÖ�¹?Ô1Æu)À-7i /Žð¦ÙëbŸ‹hÍÓg¼ü‘Ûo¾ï×}[·‰�½oð AjûÔSÏÜ^û5ßxû¨nò�¾D„z>ý´n¢q“@±™w(?¤u–ù€Ô›u#=õ~ùË_~û^}ËòWè­ÔOè[–V½V;x�W)Ð¥ç½õ#K,O¥ulàõŒjö¡~äö–·þâíÝï~�^ñ=njy’‹ŒÖÍ=ÆYY£éóÊvä¹YÕ|MÍœfSÞÿmçî§�³NC7óBB;4®…ü8î‘6òñ«Øäªk Îä‹.ë²PÐ1mÛ13™ø KKìäÀuƒ›‰ÛÌdŸˆùÿÌsêQnƒ,_CxßóàŽ‹ë‹Ü™>C›X�¶Émχë±rØ8ðM̹f“oÿ9æzp‚%4˜ãïh‘Ò-Nü2î?E¬ÃÆ>¶vžèдï‘8ÎÆÇ™ã�kK>˜ç0v§ûFÝS“A©–éwÜÑ™2)<`ôvþ]]7Ž-Ž|é ç–Ôrìǽù Ÿö›;¢Äs¸Ùtí1¬ûo©imâoW¹ø‰·^¯3îbµ Ý£O Âá´�Mc¦&Nd»È¼óº×—läZ9¸Õ]ŽÍwb–Ë5^ý©aΛ\h÷ÖT²)�-´)ÿqØÜ� ëT'¿_ùä:#ç¡›´D†\lvLîŠÙ GÎ1†WÎG«Ü&<º†[œ4\l¶úȱ¥χrìø|lË˦uwRÃ×´¤=6q×®<̳|ÄļκSsŽiÜöèò¹Íú7�Ï•Y á�ܳ®�4/õdˆ§‘K[}îÚX_3h]|®üjæ ò¸#°ó^Aó"×Î;IóÄ%¦×ã!Wwׂ¾xÔû3¿b5FãRoû9 bø\¹ŸßDF�‹Çñ%rZóMíà32¸(Nxb݆B};'R‡k?~x€Áµ×Lþg‰®!ò\*5Ħµ(odnž«©¯å9ÚëŽz:® ï±m.vªmL!ékÃþ³„:&=m¥[y©w?Ž—o¶ñ%€$&6Р ¸ r´Nü’“éóM¦¾¨°;“2ñÔV¿œ˜€žVêk|Ÿ8��ý%¾�´‘�'h|‰W<|h`øÁFýÞl±btôU(Ê7Ü3H9€1¢ýò®\–L�”à`“‹QSâs3ˆÿôûA›‹[Ú$´xI´úÃeÇÄ! Í=@§¹Ö÷ØG¿ò“mçmågŒæÀB䈾‘(£K̃ÄÈãCþmåt�Ÿøg¾ó$9ÿŒà µt³uëìÃ]§J3G‰‡ßÎ+2È•}®û3þœ‡ü$T“­óu¾›ðàŽ²‘Í“'é.Ì5þ Ä[~²·µdͧ6Þkc9×Å…^‰áø³»ë€eÃ0-1dîv]‰Ýbg;§Ä<Ô±ì»,­�rGß0ÑMžLSÓí—¸÷n�z$¢¶áà4'îH¢›ü±3 �Aé9F¬3ߌ�”‹3tÅc¾ÁóF„jŒi;z’6Ö GÞsV¯°Ü9'·‚o{‡’Xö8xÁ……ŸP$9å‘ÿz—¼æÆ�ôïnæ—ø ”ºÀs² ÷pEÞøðj¬¥;ªQ¹ca­¸Ô5j™kÌ¡Üøô¹@Š<õ"ÖCz;jo�l\8èqL¸ô\+­ŸW¿úÕ·7¾17yEàùжÎ7îp88K6- ]Ô•áDÓ˜XÜlûø'þàö�þñ?¹ýø�ÿÄíŸø½qˆO^}I=y…Yò7´8òxÁ7Ïþ½÷Þÿ`Â\küGôÔík¿þ[nùę̑±&sìÌ @æ¦ÄÙ«9.O|5þ }ùÈ÷ÿ÷ß¾âË¿øöøã�î/S‘Ž¥á|ñ9ú™ÍYÃS~Ö­ògôVßßÖgüýâÛÿöí¿þ½½W7(yÅŸy i®�²ÓxŠísëÔÙ2'�‰`Ük¯ô%GO³nÛYæ<‚ÍšUO[ LJ¾×œö¹Ñ2<� ±¸Ø9q<íš:üVáAŠj]ÖìE4öqgËñò<7ŒeË:bÝø•Z{L�ùÈÎó î„qg乑[ÊŽOówx�^¬!�,[pÞˆˆ­wÁ£‹¯_�«�o¦Îü«ØvöÆ^3Üu&Lj³y =Ü™‚F�7òCîÇ“éO�Å‘zžÿX.lrŠõª«±*cOqv$©eöè‹W]}Gß|ð©Tiÿ€¾�›uéc�cךضŽ{�8¥nŒk{Ý#?kÅ߬%G�dæÀZ9\õ!L ûœ¬¯RŒ�!Öæäé:oiáS|„§&:K]¤äß´Í7~§¾8Z“~¾³_ÅtÖ(8{¾–NîFwιžu*Î�¶cÃW£†6ø ÏÍlFOxm©�k)£¾›(ÊFIÄ? ${åkþmVRšR×ÄXL[%Ó u!Ž Ö85(�FÂÊ(8?ЉwHŸ&ÊÿâÞ}ŒPÒ6#iን‚Ép@­:,Cäº ¹á'‡Áof°«M@J û`ËB¿¾!¢|; X¬Årð¯Obý0˜Gä‘(Æš¿ 3Ç'ï�™ƒ�¯¾€áÀhÏoã._i®’òÄI'�âã þª¿†Õk¢ÀAW�Ap«ŽÁ§í3—^[ñgˆº»ëJj¼s•Iùj=š^æf#{w”/Ê”aìg¾—ƒ]S‹ÎÕE—"„»-›�`®¥�ðá0søLg¹I[áÔòT§äƒ¹CÛ'‰yèm„Ǭ Í�ºçUÅk\ÌÛÓ5¾¯nì7…$Ôãˆbà }·îY°ëN,ð±7Oyà¿ñe°ÖÀÛwmG6^/µw"`И/y.à'<£Ø±#¾^4j˜–±ûŽ$8�q†®çî'­EgÙÅ¿|šíì¢ëÉ.ÇÙl\'làhÉlcãËMc·ÿQ ^‰G/>±Ó¶IZ�aÜ:—ñ¹l§Nü7\x&v©ûYä'·XD8pq••¹Ü Žs�´w› œq Œ7hþg‰®^cxNQ%™÷Z&~âaŽÇ`ó9_‘H|Cb&>öµ‚¬Ï3q0øáÆO,ôêž,jüÞ˜V<&?lóÖÁÎ;œ°Ðß$ldð‡>n¤†­‚¬Ü¤HNã>0Ç~¢ÐsŽ+7YìØ¦° ý̹aŒË‰½Ä[îÑð3Çn�=öèíußñºÛWõ—ß^3o 6GžšBãl€ŠÇ@œšôGïÁôŸÓ[yEàÿðOþ×ÛÏýüÏß>¦Wè‘»KOs•±ö©[^ÁøÒ—½üöž_ÿ%½úî mn^ÔÂÒ©‘ÆŸüäS·oøóß~û�ßùcúƹl¸˜ÌÛœx]ÆÅ JCµyäÑÛwÿÇéöe_ò…úFåGüöab`WV`ªtÔ¢­và%:ÒvLG ÝÓÏ<ëÏøû…·½ýöþßøMÆŸß*-Ž¥|ë!|Uk¸µ¢Ó·ù‚Ã_0½=ÆCL;xÇŽøéã¶ø!Ûq[ƒr_ë4µÁµ�6«.êŸü–œ¹Ù…�×™‹ÏH�\fï]Œ5bNÎ]§} »˜×ÇP“·!$¹w¬üS5§áE‘\»òC6íÔãàfŸ3¿:iŸµß9~Æ/×ðƒFóÄ=sYú³gã@ßk“`L„°r[†Â ŸœûðÔ¸¹ËÑ\,¾‚²áÀ¸_Wz6៘µGE+ÆY¾ÚƒŽWã®ù±çÖ„Oúu=‡‰l°È][��#Ç >›_|ËËT´±;nɸ�EÕ©±;aÔþØ&ÖÎÙl–=›;¶½�¶9¢Ok]DBØóú·§ŽRÖÞ|Á*Ò/>•�á’ßñ‘Üë ±ú¶®«eÚœcdxþÔó1~pÙ¹U×ñà0XÐqÜáe< ƒ/oÿ2"þRix„‹|Űõr-Ç tŹàšWÈÝ7‡á9Ä!k¼c%f%7ôƒ«©nÊ)EsÊÍspV¨"Ž<õŠú´/SX¶8;Fx–ïÉÁ2óZAÜ=r.9¿õb¸¸¦fç±Ñ¸ñ¹g®AR^9Vµ‡‡ ‹c¯)в‘µõº¾Ú7!±LÞýçxåìO ¹¤Î�Ø\�|p¦&©Õ�ÒÔñ;š±‡+âÆÏiá'»Ý©7ùXaBØÉjìMòŽ}pB œ'ÈWý#Á`2üÖ±A,�â°ä ´®<«=�&WŽà€ñÊÏÔ @·�—ú2~1XV ÷�·M캠, ðfq8�â¸d­-f�4ŠÁE»›ì=!ÅH˜ðŽEëdY'š=mM¦ú)¤¡€¡,äø�¾x²¿CŽŒ–I¾óç`è⑾\j»ÆPáÂϱ9P;Ù(�Ïž³ÊÛ¹L K6Iœ®B0>»¡ž8Ë61Í×uÀ£²q5 ÉôsáˆåÜÄ8u;õôBµPV&´ó�Ӥåwdù8\�¶h"ó`+S÷©ð3�'àòP×ù—…¿çô˜»Xõé¾èçXýÔr?©R×Öë €žVÙŒãæz¬f’/»$JüG©„" ˆ×šCÔ–Zð¤t�´_sÚb,> b¬ë#ù² ¯=Ùc#ŸF´)fRÑohÐkCfá�”þœ3Ô?íÑÖÖ¤îàYgTzwš TvÌǨýæ[×p’Xµ*ŒóÌLC”‹ ö�ûAÐÔ´»5@j­k^&¹usha.ë€}š-¾nîÆ¯êŒ¹ÁN>ä|¶`dŽ\”q0›SÌ#®WƒlÆL{oZñ 7Îù¢²gs¡—'r#o¸–Þr »s¸°¥-£ÖäÊè{~‘™»4†�ø’ÓÎJMÆQh[<8äæLÐÏÏëFüÏcÏF!§Ô%s·0‰-^]ƒ­{êÔ<ÑOapã…Þ08Ùùz8<èË lþàä›sôá =%:9ÈcÚ^;Å屓½ñ¿êoœó‚Љ X(±å­‘CIô#̬³n�>òÈí�¯½?ãîÉ'_•W ËÉ3Aƒ»›ä1²�öbÀ|˜¿?øÄÞþÇÿùŸé­Á?uûýßûÝÛCú"‘|BtnŒÜ^ö²—ÝÞýk¹HœÔõîÚ]MúOþÑÓ·oü–o¿ýîïþ®†9OraÎ HÿGlý¹¶N$7ØÑg ~Ï÷üåÛÑÜžxü1Õ+�WÀ®5å…`b7ëÌVCÅŠæiƒ f¯øûЇ>vûÙŸÛí·~ë7uÏ�Ï.S<ýðxˆ)O$ºVž§¯W‘xícÃϬKê��œ�£fc¾{Íõ¦2u´z|¦® HÈ6¨Á¬¾™'Ï×äW}]O”uLÏü‹�9!0’®o°àÁú¯%’7án‰º¹AÊqBK~0œFÒB¡øtm`»©Cp—'`Žfípò8c°a®ÚÒq\4ÄÝÜ�tÚ‡¢×vú….çijwÇÊ9ÞCop¥­©_?öm§Ù©c*™—>æX¶r Ö‰Û¥5¿ WL9&ks •˜ ¿^›Ûò—Ê9a2E:ùŸ<{Ý>†xÖ ï3ÙXôi7`ïœO¬ô«‡ÖÆÌÜÃ?¯:ßsh+»Fv×oóÞ´l9�vŒ­ß½pÚ9_­9 šœ.Üu|ºÇ­X©ǤoÌt…¾§®Ékc è=ØgÕ®6ŒÂ¥ë s®µ÷ÅSìsHˆÅfc4Îö-Î5¬#™~ó¬Ê”z>‘}eâä:jL8åxµA„tí3²!-ÇùuÍï[Ó t`æñD‚>8‘­ç;¤]ì4ô8Bûú: Ê}¸°±p~˦É"ó¶kŸ²:àÂ;Ž�®Y ì+;Û ñ *XHE—$Œ¼r�H�¾ðx±‰o;0¸VR[xëõ@6G¸œ­¸ˆ;ß%WŒb®O€Õ—õÄk¾õ ŽÉ¹6u9èE¤Dúx…`q-e9l¾ÓelZºZ§$¥æøÚïñ”Åjmf®Œ}ÎA ;!�Y\çúø“ÿ¦r½³•‘ÇqQ-'0~3.r¨F¨4ÉyY/:Aö§¾&3Éx|pZÉßO?²p'hª­œ¤çg=ð‹×‰‡Îo/Àf¾$À\4¶�ìÕÕZek —Áï‚<÷ãf_àV‘R»} ž6,.¿bDµ¿Sê|T0@VÒw M“��˽ÈÊ#5SV˜Ž+¶×½}B`c.Žù0öÀèØ/Zt8Ñï›ÂÔ4RUÂëO(ú Ç\nr±œB©cP›DûìS[Ÿ õróÌ÷~%“‚Èmû…ˉ ÆÑPa>í´?ûÕ³ïzÀÑËÅë|÷£—V漊i½-]±ºÎôäu�p ÙJ=SîÚÅ'Lv†g›Ú˜Îªcy�XÛ®—·„Âд8o(Š~»¦\{ P;o]¡§5çŒl‘î±M­¶ ëa�Á`9TÇͽÕojy^œ‡kìÂÁä%C2‚ªsÉ~!òÊâ—bµŸýZÓ8Ș9E÷ýV >è\:.^êhC׋ÞÖ—c�î•×6z°¯þŒS·Ä ž�º‘ s G.ÌžÓg­Ñk¯p"—}Ã9^ëaµ6KYÁìkNÖöÔ%vþsyÖáÉÅdž@l.©ãÆëÜNpϵy°É�ùàf{,"§—èz1 Dâa±cšŸŽoß\“üžóÐ . 3��î6Á&ÇŸNØ>)¶NÀŒÃ“5Æ�›DŽÉ[5Öñ3oŸWÀëÚJέû®�˜š|�E3q²Þ³î Áš²-æœY´ã„¡9²§+'íÝÓšä‚wnp£Ä…ÁHM¡Á�ñ7·­ËgÚ05‘?9c×ùë+!�äKG¸žü‰'¿}§^ø _ÿÚÛ“¼5øü–[ŒCÑ;»Ø+óƒº JÕWæýø?ÿœnþÁÞþ—ú¿ÝÞô柼}ðƒÿJs³?_ÏÇ�^ñÈc·÷½óWô ÀÇsœ/€äŸRR¾„·ìcu®`òaßüåfR摹{ùË?ãöWðo_øgÿ´^ñ§/÷P¾‹'%i#ôŒïæ¶â×¶~‡uF_îñaÝøãïxÇ;×güq³ñ¡—¼ÔÇͳÏè³ ‹£}Îï™·Þ̰^›Ì%¹�‰Úl:Çn<;�Û&þøŽ%FÆbìµe yj áÏ9(\’ X¾æÑžuԛЎ1¾`%æQ”¬"ɇ•TÌqm;ßŒÝØ9 wŒÇ»®ß\Wê£'|ÜÌu›lˆq·­ãÆŠ»á¹ýª�·"JjT^g$p¯xHóÐ!u�t´� s’sfõåË>›ËŠ/A߯˜I £�cWm�Ó‚ÕñÎ%ŸƒâC^ñ·=BcWŸØn®6C©¿¼:^µœç;ˆ»ÖÒOŒò‰Î®+-#—~‚M½7¦ <š§,ÝÙÆ9¹Ü›#ç!ÿÃe8Æ©¯1Е75m}�›ûÃfs²t´`èx‡Í�N»[+Sç!½˜ãÛÇøÉCnjåÕ}¤È‹›�–ï ö«íÞïØ×¹)VŠ ö>ßð€¼Ý2Ÿq_,‡×€�iÉ1¾Ô]j¹m¶mì_kS‹øwTì`ŠÌø¡ONpä1ׇæeN6�¹ÉjØäêî=Ê -ýO×®\6ï3÷á¯sƒþH³^WžqC2‹7.ç[ÑcPy÷©‰×Ã8J€ÕÞÔàű0÷g>ʱŸËŽ,œÜ›� ®ƨ6›_%]p�VŤPÅpzƒAýü„OüœšK þà#2Â蛿ñÇÞIŽ;ýÖ¸¶ÁH-l ¦CÀ{òŠ•Ãh̘ÌÀÔ!<›7Ö0ó® ùí�±‹œ­�éLÛ>Ö�j©Z+Œ'eñ��ÿ+dï�A×^ãzNý=æ’È4'H¹ªoüq÷LÌÔ ø®úiåé� äÅÚgOë>qL9›™Ÿè/æÒoþ¡Ü9E™¦6¹ˆÏÅQˆ?)1Ë#1•ºÁ¥ÇsŠá¯\äè{êvÉE5ä8K#"µ>r”ÊhŽqÈW·œú„†ñ®o Â‘;CcªGX7�Êà…l©LÈ�–=\m|Figõ�|ÈÚ�‰Çzˆ„ªe¬8„òñ‚Vgð!®cKGžÈÖ“9à¥?ó£� i·*yf¼Ïë@m›b°‡±óFm‘&Ñ“Snž´Žá�-Ø8 ^`ºYš­19Í ’ƒjàZŒùÜTctæá±1ᣦ�™¹†€Ožè¤Í<•ñÐ2»äGœ9>Á\yÇxBRÝV­54/0‡ hÔ�¬ûJ7Çg8ù˜ë¸èrrnD"ýxjLH«‡œÀÓ¸OòZsrãj1Õ+î`&ðž‡k—=OôDJ­ë÷õ ¾?ñ柸½ýíóöú׿áöu_û•·×ðŠÀ~Y”„G>ìáMNpô Xó=*¸ëçÔãÄM¯'ômº_üÅ_pûÜÏý¬Û?ûçÿçíÇ~ìÇõʸíÏ€yžÄ ¢ðãVQFÞ–ËqüöX!25ËÍ 3ä+^ñÈí¯ýµÿâög>ÿ?¸=öè#zâ«›2*”±6ÐîÉǹœ6Ã¥>Ô¹ý‹Ï3z«o¾Õ÷oï{ï{uôóYžd"Olòy‡ô™ÛÎûÝr¾ ùÁÇÁðÚm=.!ÂF?­¿×µ|ð`í4ކ7ú%i‚ËQã�¡tXlÓÞÇ•…ÂÝ1sÌEn-\b”Ó9($:óìÚu/"�ׯ0¦ÞŸz!Ÿÿ—Š&7"æ¼*­13ÊVVùµ ÆÄ<¹U7–“K´Ùgàs„ÄÈr¾�oì,t Ë_sÜ¿6»ä Nî±�¬µ9bc‰Bp §ïxF Û4Ö󜶄“sÕ9§6Ì¢W·5Š÷ƦöÒég4�™ú™ÖP’ÑÁ7å)OЋ!Î/äËÄr¸¿¾Í=Ñœ×ähî@:NãÅß�Q¹îçœÂ1ãès \€IŒ–0ÀRL+–-m{ÜRÆwøf16¦)‡k‡ÞuB|æ7x~Þ‡‘tgßðÅ@ûKÖÇm³dìþ"µîžWÙê×8îÆ×þŠÑ:Ù& Ëwq71”ä,ü–Þ2]spͧF Õ‘ßÙ6�ØÁÆs?F>˜gnÖißk…8c«Ž ™«Œz“ {¯7ó²UŽ_žHä¢×܇øÊ£ér±Ž|‚O†Ó·‘lý<+츸ÏÛo†�°¨ ?ü†É� ŽÍd¡>øµ²y’»F#d—næ.&ë�[lئõ‰ƒÞ¶&:HŠß‹£,—�\yK0¹Í÷$˜Ç‘*ÿ‡n¿ÿ‰OÜÞôoºýÂ/¾õö†×¿ñö�¼"P7/ß‚+³�›ßB iÈ›�k¶g-[ag¾|„�_ôg?ïö§>ëOÜþ÷ÿãÿºý¨n~øÃ¿-çnÏêí²ØË@aeƒÊä9½ÒÎbƒ¾ë¬=7þ~è‡~èöŸ÷§n�<úŠýå3t'1 §Q_Ð5rú–3ÐðÔiüÔÓÏÜ>ú‘�Ý~î-¿p{ÏûÞw{Z¯@ÔJ Ÿ1öK­É¼E9k·O *kÖ©&fö‘&8ëv�Ý� ;çmµF–—ãöó±…Mó˜zÅ|¶ÄkÙ}qÒ.8rÎ=ûFŠ>nìYç×'ç »¦òO~p’&Ëš._‡‘¥Èôlš'Ô4Ïo€2övcª¥//ƒR±³NšÕæ"ó)7 jo¢gòµB{ò®69|¬iÈ xñøé±Ñè‚I/ýôŽ­)»qwޱ[õ'Ïálúö-Vt«Îæ—WKSƒbc]ßÖ©|/p²Ë8¸á”jZ.|ç¦É„}­�‰Ž!)s|klÙ¸ñWkX›iñéúBÞë)ô²‚Ä`—›s”<øao"1ÆAmEÈp�ô�Ϙ|FºvRQëÈ]u÷‰�Z×ãÐAXüù¹.&}œ_Àt†ûìS‹mÐüŒ,®7|Pj!ÄÄ>3 ‰Ìmãj-a'ÌZskŒ?-8¥¾ ec„@xÈËð„¹=„X>~„½nÔèØ"/è%x¦�©nð�ËO¦™ìŠP ŒS›‰QÎÈAÐÆ×rôá�@{s•íª%�‰’«ó¦Qð¾èzÓ75½Í²�Ø´Ö…á›x‡™tû]»Sf¸áÎc!ñö:J°p@¡±þœ/¼&Pq­Â>çÅ=yØ|×`TÚ¤ëý�“›±àÊ%så™D›Û^R¬¹7Æ]œå1bu?I'4ÎyÄû�IœpÇ?h0÷¸ùÛ6øÕÕÝixá»I # ZÛäf‹‰»ãÅf×Ö<¶Bš¥dÅò %Fr &õ`Üæzˆéé‹.>‘ût%¿ìã™Ê¤Þ®±ÀnäF,¨†”sã%-Ž ëÝã)ºá¦o&hîd.�ìb =ãô&^bÚÙœÜëxĺxá ÅdW.€xqlzÆ–æRÌÚ ØÅ^V4Ìò9Ÿ<÷œ¬â³0Ï­Ó²¥ò]þ†¬@j¯Ží<ž|ÀæUB,¨ÏyÈÚS÷í§:`„  öÆÓ~škª~¸ÐE÷ipŒ�Ó˜­ÜÆÎc<øòñI j˜;å¥F�'/â8?%ž²H(Yj;s±˜¹Ž¿AfsÖ ØxÎOÛ‰u²ú·ÜVîgد�_“ŽËÛ˜ãÓþÊCN曉oøì7 F3gÊD˜ç�ë.ω•±)‡˜8Ø8G"ÁÍ-žJQªÔþz\ÄËÌKŽ Æõ†Ë¸kOè]׉ÁÉpŽAQÇ!äÒ¶Å#qÙGnÙüÑÛϼåm·÷¼ç]šý<þ‘à›ºLH&ƒ/(áÚ0ºQ*Ò9­s•¨³�ÀsjIÇ¢9~±ý�Â5ŽaY.“g³Öˆ(ܼ5G{Æ#ÓÎ�µ�þh(¥a¼WO¾Æ�&ÆkT}èÚvP‚¬-�#’e~ím 6=í¹ON]+`®æ~9$~2�…t¨Áé?]ðËÚ:AÂÐ5 X6šª‚¨ƒoDc§]O)v ”×)‡g0ÙK1º +ÿK"R:ZtÃs„äЖºˆ.ØÙûX8fƒ-¿€g%äwéÀA¿6sˆmÜb¸pŽÊLÃ=Àæ6Oæ˜íT.±è'bãâÓ>!‚Ñ^øMÎÔÕ¶%�¸ÙÛ×Áeå5O¬Ì]lÊD–s}äZhŽbg´™úå¶9]eÅžý¬í¤¤ê IDATŽ¡Æ�8Å็¡îâŽU‘:uмÙ]봥מ3±)1½n•dó÷IÒãv�af®aÔø÷ø·›ÄÈŒ§cƧ_ëÔϲnê�ÿtiª¦ã!Á8×üÖÚ±Ž¢åZi]?ø†ûÚ^€õ¤A`åh�„#£KÒxÒñܸ_v+Šù8'xSGrö�šáê\±|õ»ÑÇ„íY{ Ò¨m]¬Gì­×>ѽðTo~Ò2ߌóÄg³º5XŒì¦?@Ú�¾öSþ¬�‹yU ¶'~ÿƒ‰œV]�ƒsÓ†ð\kÜ<ì§sÇ3íÄm�И]ÏQÇ.Þ4_ûˆ¢q”ÐÄ?c¨o€·&׋£aï__“±cƒVnÍÓ¡LëxØaˆaÇ\×·~½Ñô©�M™o‰š+{Ëc—!T»ÜŸÚ µö&ÐÍ¡GÄÐur�’ÖØ¥fÌó¬Uz4E“½ŒJØq2¼÷lœ—‰3b–”ûä3;¬P-c×ûј’7`Ò>z×J×5ñˆÉ äAîVûâƒÍ´ ê5LßW<2WB]XvŽŸüdkZÆÅ;2wͽàìë¶Ó0'¼h�屋ùD1:7¤xüø'þàöæŸzóííëí·ïø¶o¿}Ó7~M^Èx¨åܪ΄G–ÓS[A1ÉÍ0ÄyÂ%%zù>¤Ïà{Lß¾ûùú³oòOþìíÿþ—ÿOÚ^r`BˆÅîˆÙ4¸AÄ—f<þø+o?ðŸý§·ÏýœÏÒ�¿WèFã|ÆŸ\íÏÞ�Ï-¶É�]ûSwžøæË=>üá�ÝÞò–_¼½ó]ïâ«=Îľzû‚eÁ]¬-G�ã7ð.¿ê §ÊÁhý;ŸÞKÞ\|ŒBÚ-u`ê±ãÕ‘p�:6=gôèr.ÌŒý[¬ Áe¹ãÆÔ²rMܦŠÀ&AEØVb�’_,R{Ù¬ÇYÙÁì‚$SFØö¦¥‚Hˆ”ü=Ò~×1j´pÚ6A· ³j^,ü±è\°wªÅ.¹Á}âÀ³91ÙãÆ¨xê®V?¬ÀM¬¨wßÞ m%¢§_e™�Ó¸°°3qR«ì{�±e\LÄÍS=dݺ2ƒ›z#Gl[uË2 µa¯äªÃ'mCX¢Î_|â†Ïãf=`k›4¯§¤¼®�(¨Q=²7C+;'@sYT»zŠ@0­ad¡ß5¿ã pØ3>o’[Œ‰[®O2wâ ÕuœÁ$ÿ´Äè(û!0qSÇCƘOÎåǺÇJÍ|5ŸGjüèGpÙÍú‘ÌyL*Mt²ˆ‡{N7H�‹úc³9 W9™ÒÐJ*¦qæƒ:¾Â˜ ~ _¡.’jŒh8/`é1ôòÂ3ÌZ[©='òEdTÿä é^·C¡¡dªÒsï)°ØF‘\j�-?Óˆc‡l$¶ˆŸ{(q×ݺÏÒ¸ã@lœìCM3— »ìõÃutŸ£ca—Ùö^AeÄtNiøÎ‡Vd\]‹e+ð+Yûk4¶§¯¿å[ÝÃE&A�cÆxnl‘Ó®q$ýšhù`ÃÝ€¡ ãí„áceJ˜î -<1Š‹S<è¨×<Õ¯ý’\ð3Wœù[Ä�ÏúG5[ðk¯®‡ˆˆÇÞ²]÷eKpá8M¦^Ø•ylÞ aR:‚Z;ç'×}ì<;ã|¸§›…†üÜdb½ÆöˆœÇwxÖf¼ÆU6øƯ8â‡|aHYÞȸùš¦‘k~ö–ñÆ›¸Ø´¥n³¡´¿_>ø+Þg,K ÛZ�28Äeݨ(NùpÌÛ…œ£}ÆAòð%�ÈØ-“K†žÔjgk�±Eá˜ËÑÚ˜Xf+Û´>e½ò”µÃ¹~J¬y–>¬°ßôåç{òÛ4îô†ï©ëe(á¢sÂÍ;Œ›÷6c£æøéÛän½ºËÏý)ðÄI°§Øì´ç‘H­uó`mÆ­€¬Ñ¨ÑË%µ\Éê†Å(¯‘uíÚV.É Çq´Q‹á�7± tj�yù¸+Ä>x‹^C¸ÆØ�ðè|MlH¦ó’Óªkù’üŒ�ǪgY€3ÿ`YEWŠs35”ˆ11ÄDK8Â2´´vÚÚ§hôw#óSƒoÀZ‹Ö \Î÷kìDZ¹I‘Ø›‚ë�XñM¨kÄÍ¥9LNcr™Z˜]èÙ `2ë-»Ë׺±Yç+y•=þD]~Û¨â:ñòO9z3”ì·¥ÄçEc[‚ÌÔElúk®Cļ¨s°fþác‚x„ß•Ôhi@%FÄ 8>î MlJ96ƒÍqß�ö°Ïq`�PæÆE°Ø'|ŒOÞ`%þ¶…ýâ+±×Ðg[òøñžÄ¨ÑÄÂNÝ3Çö¯ü¨3v“7}ýáë¹ :Å7Ø�ä="ÜÀ[Éš/HmÆöx˪cßuäœË2+vñª}1®5“�ÃÔ·{�¿:û•Zb_ÝÔdñ,*æÜæ:‡äÇu­T¬Á+.‘·=sŽDˆ„÷ ø §-rˆÑ5'jlëùÚ ÄÖuKÐÔ­Ýíç~À‰ZMRïé‰#;¯âë'~ð¹Ú…ÿ–ÕÎ1Áé®\mÿ3®Éq\¦.B™xà��?üÝnNtéðqMdÐü(9iÓ°v:ö®=Æb˜yWoùmÌá/MÌoWÙ?\̉ažôåC? É×Ù›ÖÐt,¢Ÿ€‰n1Ûî¡âÏŽÙåð‘³áºÙ¹Ê!/d€›ÜµÉ :j)A¹Jß¼mËÙ}à±Wýñz'²dZЕIL‚v.ø)Ÿ¾±µƒ@æ[Tø OSÒøÙfúà5^}[�Ä’´‚ÜÝc86ælì<9Ä”¢º4²cA°I!Ó÷‡÷J¾¿kÀ„c6“�.ìÈ _Úož(wâ�u14lõÝ F/6Ò{5ì˜|êù©O=çâ`´r‹i죈DfÍ¢˜Yd�ÉüGvé§>Ñf»tÂÕÜ©³~ÀgL{Hß 7jé6ñ—Ý‹r28M×µ\‚î<®1—�‰%,[×80޹„#õüÔóú–Cê8Í} �›ý ’X1K¾›ßP ¼üФ}aOjÉQÕÜö£À™æ›c‡'s|fÐÂ9%¥+Ÿx^·ðïƒcr•ääd2WŸs´ø]ì!¾qŠ^kÙz±O Ø�˜îKÜ:oÝaK÷äi£7¼2NÌ l‹„'ç~ãT�oÖÂ}¹!öÅèÁã·„FÏN"çæÅv†¶ÙsV[ö´>Y%.µô¹RsN}k‹]û­ï)3 Ï‚´‚5mƒ0âàcÔd£�x¯Ÿ® ,Ë­)Ÿ‡ôVFß0Fã3¹;qÑÃ?{|XÛf${Ëñ£-›m_Œí?¦¶M$Ó ŸÉæs¥¿A�söÑÌq�ÉqA ÊÖ¦VŒ¹yMë9ȃÙcI߆PŸZ¦>­Wí_¢Z2ÿë\Õ57›8úIv»Ö�Óp ¿¡´v© <’‹­Ú÷@¦S“®�Ì¿âð£W€å\™ó¹çoÐßÀ$_ú×ù`œyGô;réý„'®[t­A×$Èõ-òØè±®5v=’ƒ\’|ã®à’K¶ñ]੯�÷Í7ÞâèuA}€„›‹ÉN}Ö ¸©Ëƒ·‡_ú°¾@ãÑÛ7}Ã7ݾ雾æö™¯yõíaOÃ75°Èûn?�W:g¹�Qèoh,ù©»õ-ÀŸ|êö?ýÓ®Ïü÷ü~«ïaZùd”­yZyHï[jæä™gž»}DŸñ÷Ö·¾íökïxG¾ÕW‡'Ÿ¯HÒy[ofÏs¬De41LU[­KÖŒ¿©Ø¯ —mÖ�£F`å]…ZØP8Ò ‹}xdG~àä4{…�{#iÿ ¾æ%z öÙgŒ�ºñö~á;Ú©£Os$÷êŸufÑR{ýN|?©«kýMRæLš~{#›s%��þöÍù óÓ–ÐÚx§^ 2Qîu›y’|êãý®Ò}‚]t×Ç‚øÊt5ÊÉqÄãýçùfêyÀ„Š­õöù“‘c”©Ì�Ç÷ÆgŸ5xÄk>é�•åéÝz=à1üy®+ýO‡´!\=×&}Ê7É̯Æn ²*�€1 }ûáW¿ÆˆUÖ)ýâ$´j©ë_jñÜs¬KÕmBv}ïºØ7›Ú0ZvV•Ï]œ‘_Ò˜@ÿ ³­.Ö$¯ôyÞMW Ö܆ŸËà�ýqÊ�¹&kóŠ_ŸÄb娯fA‰}ü6nx´¬®Ñy¥2ÿ%Ò ô�m±·ØùØ3²õO%d(½O¾åqη Öæ^|òð|Ë&Çk|�¨‘úàÁ›_÷'AsÃôžÿ]£{ ¶@)¤Š�nkS®×8å]µLêñ¹c»ÀOÇ™<0˜XÌkò%7qZyw2QmÕ¡¸¶K-9¿ôv‹SW×Ñ9ÞÅ>°2‡ÐÔ�ìÖúÃWÜ]{u³vcלº_:ü“œ#ÿŒ½O³uÝUÝw„Ê–ä?½¸ƒHòøŽ+ÍTªRNåKÄCÜJ\2ÁÄI'ÝØà§w“˜JƒÀî$06$z_½(ã7Æs­}žÇ¯{Ï^kÍ9æ˜cνϹçî{ïóäûÛçÿú|ûO?Ò ‘vô¾×Ž¿u¢×=}›—cì»oHu�žÛŸ×šÄ×¾çñ e~Î*Ãuñæ^Ž­µØ.׳Š+ÍôåÆYÂh©=ä ‘† ÃûŒüŽÜ¾G—9õ w÷‹8ösL��!Ûö6–=º¯óãÆXã">\äË&ýÓÏîgÜß“]qW//«u}þ _ú ?�qOºÖˆò‰n ÷Á€õ X3\ààm•Ï/f`d_þ‹óˆʸ»W\›Ø9€+Ƙ¼7‘;š¶raAÕ&o¬¼™dp!6�ã[š=†aì˧}×g>6êo¯šZÊ uЙáèX>¾ÉГ†>öDú�‹1íKg÷æÑçÆDHÓx†¥±Õ°ó…Gëæ {õ‘K#ÃoÒT 8F4\q6&–�^L®jžÔâÜÂôš"?Ÿ%óžC “Kqh$E_xÊÓxkuožA_-É…•á5æÌ[¿±'Àø\è™~-è±ðõÌû 1Rš¯š‘Øó÷ãØÂyzÃ>õb;:!Jƒ¥ü$>¸òøôZ£Zòu'1ÉOl8½p/‡+ô„9Gó×8ÓÞ¡€GSÌh»Gù\Ì:£>2Ðx´½sÁvøZ«Ç|ûm|òbHq‡*ûõ9š‡sí÷lÖx½Î Ýyï4t& =Îë×BÇå:KDˆ’O}ȯ�¸J’Öqç�>qúMk ÕOpëêõ�þœ©çJì ñkÝçã‰ÈêÔ¦=á�ëŒY×$�|ßˆÃÆÌ×±×ÂÖ/¾êò¹¾ä™bzáTòå|Ìó ßmÔ�Ã9ÆŸžµ—ó$@ôm•hpœü�[ã•Ì}g ŠPÞ) óòh]ÞÐ&ÎõbÐ(Ÿÿú…÷&hã7éádÌ MìcïÖ/K9�Ç)›¸¬hÕgKgã0öò­\Šó‡îЗ=hæ9cLß §lå´.ÍeÎ Þí ¦ ƒ]y ŒoÝQk�ôR( –æW!r”Yì'×bÈ`; �9Ùô(Å7¦f͵[Öe‡‡×F~áAÏm”á=Çp—cg=ß>ÿ…?÷ÚdïJ2'“ /…³(ù+Ç r2p"ò™“üV~*Ð ¤|Ä%Gì�ý$Ñ~Ó öè‰äpøŽ²±ç"x�í›ùÞÂ�ê‘v¡iZcsñSºl®(ØÑݘ`å/X†à3W?8ìä·ÆûN€`ð_{Ûʈ]£Zad€ïφðÖ_cs|ÈvtæÍ¤_Èú1mP0Ê‘ Åæ¢^ÁS£ñÊÂS“¸î)§¶ÇŒãÂï8z•Hÿ��Ë÷Æ«pùŽ¿ýb–ÕÎÉêÒAêxG/�hß|²¯æëù„ßÜ’=ùœÒ,f;”$öÓ›Xt,Ά{C†^TÛÄ\}ßÐÚ®À~ãš/ÜJ7¾­‘½âܱ43IÇnë�kó=œ—�¥bÒóÉéãê’Ôôøùm}I^­�òK¹½6v Õb°ØåóƒŸX¥ºnÜ<²¡}â’¾y­”3ç[çÃ9É‚”Èz  ‚{úàÀÎÿeEÄä'·Gàô3<Aˆný¤‹ÞôÞ™ˆ{È5ñÑp0c“�ç€ýpðI –kmÃàâ3×»ÂÍ�0"u³åº™*¢ô9,>n@xâÑÚ@SØ ¼&áã³Ï“ìY¯€`?Èc–„›ÃJãߎW€÷¸Ç,B 8ý“>oS|ᄜ‹Šà Ÿ{¯£Ý0íW¯¹†wâÀÇ×�ü¥ç|Û®øô‚7íY“ÂY94~�,4Ž\d®\Ö öÔè ²[ýÜ™z#Ô‰£æFû考�*Ì oõµ ÃþPLÀâäÍ–|©e‰O>°œ<ý-,ŸkÔ !ýF®ÁÿºÈŸéþ“_û'¯¯þÂ×_ßýãï½~üË_~}鋺 §Ú¬ÃŒâ¬�CO²Ñ^÷³Oø·oÄ•ÇÛÈ7±§oîbÓ³�Þ¦YOêû/÷[¯¯|åç_ý¿þÉ×oý‹ßÖO©sùšâ†-=ã“1¼ÍÃû™ûOps Ÿsmb‡²P™ËËÔÁ¾œh4î¼Þµï9•«Ø»,bÁT³½¤ºAxÁñ¡k+7„ò #隣3êš…8¸º'ý͉?Æú´C± ë!w¶þ†ÐŒ©3öÉ :¸¹ÆyÑ•©Ç‰5ÃÐ&ï�NŽdà8vÏ©½¦ä£'à˜×2®sƒ{~ó‰x1Îsœ˜øæ1ÿʉIg ½—·þÉ0ÍØÚâÚm›zªõqnŠ…~xœ'¥�uz¯\|³Èë Åú\æ¼ä¦ƒ�Æ'>$û°vrLJÛŠ‰W«å¼¡¸ „c¯‡°,? ߘÖì÷lW­�œâZ3×_ÖÇŒŒÄ£õhÉyŸÍ`¬Õk4Ç—ª‹‚¯;zä/`æ— ì&?£Ø™k^J(÷Á&ÒÑ“7§‰ÚÁÇ´Ü5ï)=Øy~ÓÇž8RóÉs¯ô:ß$õ6ëü`äCûé¿ÀŽ?˜æ@Ç]7kß(”×NœW ^:Z»ydŒ†õzá¾Ø\{ F®;?¸ ܘ�µþ¸mã|KÏã½Ð”G^ój&Zï<§^ñ£‡m³& Ë{¤–ËR=KÆÖ 56÷RFò?¯±æˆÆ”­ð8 �{=O‘ Zõ†óØ‘}ãÁx�f +¯—ù« zY-¼f¶vãóQY›rz ÐnsÚÅ‚¬ÍÑè-žjŠÅbãYk�s´ø\¢%®ƒ12‡ÍAìm_{±æ´&rÀ C ób•7û×6§ç[›4R„~d(ŽÉ<}q>­§$ã¶¾b'¯Št¾>º.¨)÷÷ÇœÎ/õhíkRAy=wB6—°0Þ}N¬þ:î _ú‹?ÝFlâ.¨ìêv‹[ò&ŒýÅS°šwŸäÒº ÛµIM.nÖåšm›g3¹ŸâŠÚÜò®5 |m‚B‚ÙœÌ8ãÇìq¥sþÚ¯ù¶sâ¸Ø2´ýkíW¾k»kÇ(·ýÂô‹Í=üåÈŒOªÃæe?â‘äüw�wü¬ÁBÀŒpçç|3|7ºìO>ð|0<ß\“À½#§³ü`s1—¡‰†ïÀßòÄáëR<¾!4Ú¢cøDw?YJWLÎ…¬N+ë;ž]㎋91”�xc&Æ{ö‰=_¸kw^Ÿ‚ "Ú ÷Ëç³1õqí`˜"¢Ð=31®¹F#ƒ-†{^dêçv~�[3#ù•wöØY¯®À6w9Ç|M!h~ä—£¶€OMBLQëo‚$ ?!]OÓ8:·�áæèµŒQsfjŠ&‰†´ÃlÝx.6(üíQ°þ-9yŽ£�óq°h!ð�M}qkøsÞ s+LߨÑײ4>’îÈ5É74y~G>i]LWõáÈzV+±©"~¯±©îý¦É8üDm¶í)kë$7ËøAÄõP¦ñB‡I‡M«G;óçLþ䨌 OpVø��LààG¸lýáž>÷†EhÚÒµé\ ùlµ�àA]–p¶wÖàjv”0}~û·Z0j�³×!<Ö·W3˜¤K ŸÔéo.XëƒÏ«ÀÍ_ÎÔ—XêÛȲÛofÄo³>¢S¸iþô*¼øÊMÌ|º?Ž#MR…göô¯Ï-Ö 2{#N¾‰…/�ûïè 9¿ÿýÏ^ÿô×ÿéë¾þ‹úsÜO^?öc?ê�ü/¿NœeDŒYöä*  v}Pi­ÿ²ã™LšyÿüçøRš÷ºŽ}½>ýäÓ×ÿý;¿÷úo¿òs¯Ÿù™¿ùú�ßÖoüé7î¨~¡Q^û IDAT~ûŽ?eôF):±ø¡×?^gÞ{Œ�×J|ŸùÆ•âB'�bØ(Qf›F/v>#tCñ5!»mäe¡½àÓ׋Â:z½˜J`sŽ“5qyîÄoê5�âÓUô�ïþ†œœ'äo}•³3zX÷£®Ã¤y Oÿ‰çM/é—%’[<äðÞj¿›9®ñŽ™}Ï.x¬«\ƒ7?$7Ï-±ó^Hö| oÝÓõ¦ï,.ôïPÜ í°Æ:Á 6õÏûWôD\ÜË7\öåk]ô’¯•ôèôžMHÂ[B!¼äP–¶»5ÄÀ/Þù`®øY?{÷ÅiM²q¾a¢µiezæ�ŒòWx³�®Cïäàå�‰ÞglvµqM¦žÜWV~á[æ£ÑÏw¶£5´°òaLYóÜëó®×{øM2qÝçëQ^Ã…˜„îOùfÉÉÓ��&þÝLêëù� ñDÜï›ïö9gråµ!ï}Áú‡ô£Íº“eq@‰l|6a!š­c0uç:RÔ…3QÈv™ áGgßWæ|»aA ô½öÕèžæ¼æòšXíÉÀ¹´hì}ÎÞmLx=ÃïÇõ¾²=B¨{­Ådó*±ä=þëôȘ6ôõòÄ6ûÔàå…èÖlÚŽÛ7)…CÓָʄ›53Ö><¥w­F†Ø™Áp"àîÁŽpƃŽôÌÀúÇæœðª�ùþ6¯Aî±€ƒÉ>ÁìïQ+E�®k¸/ÚÛj «sÞË—¨î’÷fÂãï#Ðîê\Ià'ï\˜éWr¶ o>GßZ'Öç�·obÑÐëÃñW>ïÁË{t¿ž«Î±Õïîž4ç"nþ¸y-v6áÛcmún»a¼¹È±*i‹&Ôy ñuC†ÓkÅŠÓÏS8>/ ÚæâFCÂt|Ž6kÞ€ÅOìÍë9âgxnÎ&©Óu‚™ Z8?Ù¼O¼ jü˜î‰X¨N˜EZyHŨF0µÞ¶Û^y æVþ½Ø‹w®n&g_4'ë}ñ™7ÚµwÓXÛ¬û®#ë¾Ü?±Í}Vf[äMã5ÝqTt÷f5ò¦×q/5≬ì·%DÃÖ¨\FÛ:ì6$zL?U’÷­­œ"ΓÚ|ê„Ö[¯„×›øì¬Dµ9§m6Ï °–ÖB-]ã~;OÅŽzÖ5ÉH¿XA’±:lþ:=Ë‘‚š'zµ¹‡­óŠßÚÈ99p»[W1y³€oço¤¯Ö)|ù:_©¼TI3ý"SktŒP•��úB£‚K¾ô;ìÆ!_˜ó€—®KŒ “Á´æÅ㓟r2˜. Û>v°ÖtŽ(CÐdýÀó[?MÆÞç·Öä`ËfT±Ü’{ÍÆ0æ�-s®¥!WössšDÔ½yñs32xâóæâÜ2÷Ð=z!G¸MšC…±›ry«9oÜ�Ó{]ê@·n»}ä%Z@þí-X|“rè’k7 M‘õÖ¬õóS@†d±BýH)·Öé’AÁÓ‚Ñz®ë<ÏÅuÿt(a £ŽSxê‚ÄŸÐ9QëXâp^\äe”ã~ Ç6PÍҧד'$7>ððšî‘Ì,Y¹'æP,–ã6Ú8ٚÀ�9·Õž€ÖÞ^ÑÅSÃ`·�rpŽùO_àú>ÿ�N�ƒ¤ü�­z…òoòo~ç;ÿÏëË_þ±ü�ÔÛ­î%[÷dŒé›ˆ5Ð]ll:ól±ƒ±´ØU|q÷<>rùÆß7ïõ·~öï¾~ò§þÆëÿâ·ü@8Ÿ©'nËÌÐGž�$ÈM{bµ7ɬ'71ðó £¹tL14�Tç ax÷ü@±°ìðz 丯›˜cƒ‡xÎmE;§ö¼^Ø/L®á!$K@Áç×l@ÆçœÆÖ�KÎ…cò²gXŠ®£Ñt±]XmÌ!_w|C˜Fpg}­0Pz\µTÔöÝ9À’OÊ_ É|ÁvWÏw÷o¾îäÏ‚ÁŽ&‡…¤\ö8©`c$7£æ®mD7ŸæŠ…ÍS\®�Áh"†÷y�N=à™Ù¿$abl`çºÈ.ñ¶ÛËJ�\3=O„'¯‰^Cýå1À�S#qÁúœhÉì¯á ôÜÃGc’×Ñ:$mÁAŒÿ sØF^Bz_`ö~Œ¯=mŽø:î%7Çýƒz®\;å=ž«ú5wyÎÑgÔĸõ>×%`N_!E_ûƒ'Þ¹‡†So0>ZÃéõp´ó$¡uø0)ƒ©9Ý=}µjžØ.È™ó-Gß³ F<ã=uãW¿A†‚ö‚±²Ýûꣿ{Þ‰6H��y´ Wtæ^ANX=„£¯y^=c ;×-¾è#¦±#¨mè©­yíkŒ7@ò‘ÜÃ+›{‰&‘Úš×ÜCnÛ„UVüâvá“È²ä‘ ÂØóÑü­3Ö'•°Ûƒßë.!æð÷ù<ä2ÿ•Çœâóë ¸uŽÜžK#¬Öh�ðœñ&ǰ ”wø7‘ý~Mº°¿½..wc[ <`í·Àì±3À·±ähÝZ–×Ö+~µR_wàÑk%£¼aÕU>4-®zf6¦±ä‘½ñoPo7OcdmçëÎü�~jyð—¤cÖF¸ÏQì'¨ Bl1ó¾MÅÜflùæanr¢G¼�]qÃEa˜[´ñ2\ÏY/x=Jç.ñ&}òº‰~s�oÄ.º‰VüÄñD@DóxžZ›ª'%ûäîÅPß­‘“×twÔ“ Ktjï'Œe¤?WþÆo¾‰'ÖÍ‹üG�cMÆÀÔ8óÕ> zh› kôMJ=í¤+iHÞÑâZf}ó;«3Œ9[k²Î}tì:€š//àrö�Ú<©¨ÅÍmûÒÓû¼€Òr·a}ì¯ <ì�Ë9d߸ò˜¿=×ìåи6]—9ßx2 ½så¥9¶#aHÖWñk¿˜I†��ý^÷"qOß} !Ê¿ÅDÓö†Ðú²x¾ç|™ÓùMÍŒöxb­'N•çÉžcY¶‡à°¾×H¿øÂýþÓä»�dLñ&… ³Fçìζ9±çÚˆ¯xtw=±L+°¶äÌ5uÌ×åÄiŠžS¼¦bçцÎçv„9R9·=$—=×|Û´6%qØ©‡ž'O{�FÎ…¿ñö3u"þ–ÖyÌñysæÚĤœÑ}üÍïÜrúëP“=`ÖÑá>È�Nž;þÍðíñ×2Ã�éËkzÛÂÌ€�£±¶1+×~£±®,¨!9¯Ü´’]àœãê"c‰jp?|*èÁè¢ÈÒ+±; ë‰?+ƒÇWL¸ò¼ã†‚Þ\TKÈœËy&/¹y¾“#ÜÉÿÔ�íןÑ#¦‘ሯ¶í¥Ù£/ù„æÆ4¹}£’z4àŒÀèš|Ø÷5XþèóbÄELu‡+¯Mô ½fÎÍÆô…|Ä�ã›AFb:ç7o¸¨7“Cäúg=ŽZÏ/þcŒ_ÿg¿þúú/þÒëßü›?Ñ¿¨ßä?ê˜ßu*’$%É´ÔÆŸ™í›²º6°b�µ¤ŸÛïËî|@±é�Þï}ïÓ׿üæ·^?û³ÿÃë¿Ò¿ñ÷�ßþ†¿a÷—X�_„OOZú¹Q WzÉ\”ò f÷ógîç7 Ût9—ùºs“†]ékçÉÙÉDÝL®Ýæ,�k4àhT¨«½“«Ë†ƒ®v~ËÔ×,×óbÑ«¦íL´ s4"<[=¸Ô\�ãBWìá²Ð¤0‹{¬ Ž˜{ÝÄí£¥Ê{‘]ËÄ<sÔ8z×ߦ¬�ù®¡ý=õå .|!síÖw8¨#×\}�Á¤cô"Z'cK»y§#AçØóï82]µ‚ >ï3Ä©×üϘDÛ¼›cùvá€Ô›9]×õÁ±fg—£º:˜”T�y­¬†ž›ÃyÅ%P¬Ï ÕÝtåòþq¸ã¢³\ì’éä³Õ“÷B9ßà¯rÅÞúçZ˜|Ñ�|àS×ì¹Ö›í¤sdí‹\ŒöÄ>°ÅÞ¯�y’SAõ}Œ% f¤}Å6ûž—úÌÏÆúSø|ýNò²‹¹™ê›”ô+ù{mF߼p—çÒŸ:ʆ9“³Hˆëœ¾\\‚†·19ßìüœ\œóˆ€91i�sŸ¯llÓÌßÄ,c5 ¯ƒ®ùŽe1¼,¾!Äaštk”/[4�qkÞ~È•þÃ9}*Þ¾‰S´qœ�´ñÚ—ïç¸ÒÇéøÑHœÌ`"5qÕÑ”É\m�¯òÌq²qfxƒŸ<¸°éë7ÃßG\,Ö„F0z¸O$°éâÀ’·açˆñoÃØR¸Á:�tåõ;ï1Ò~d_w Ö‡ñ¬;Ëøù?«€N>‰&•‰ eئ ïJ€�u÷ֳ秋œd¿Á1{‘ …ó,ÇiØj΋0è0”ÅDYlÕU«ù‰põÌÉå "¬÷Vö'wâwo´(Dƒ-QqÔ8Ë9Lÿš‡ù*Í�m¢Ì]~iå‰�7jaÁŸ|C§>¢ìp­E ç,¿°�øCc_Ôƒýw™(¡æä7ASl/H÷Éš¹–È�k*ýC\ôßuÇvìÜXj„'|Õiáõîónû|ç˜É=�UÜ0¥An):ý‰¯v-áêõÜ™hC†Çz´¶xî5øæ G~EÚçÀ×ø8kä(ȵ`�xk$¾õ(£Ú‚‰�5Ãsck«Ýˆ©CÀÜÄ`Ï› /&ù«…ºBÎPjÕF¦jšð@½)/3¨5kësS»g9¥�ZÜ£yÁ|@F„c'?~ÇÈçÞOÀJwÌ•Ø~õ� |â¹ßè$ßèfB—yðÆ‡ÆôR}$\‹cŸzàº×AU¯‚Ì 1x� OloG' w›'ŠäãuH÷ëPoή.§#1Z49˜ÃÑP¬ýÖl¯òîÐ2ý?6¯Îf§!ÌzX¸�êmÐLÄà³ÛÉc‰:6ïÆŒÃáð>õëø˜¯±d,3¹ïüÐø1¤ô2&q3fÎÚ�N£*nó%úF–=·ž¬{, 64$ž »—œóÔü]ÿ¨}LÃb["šçð#ðæqn7aj¤ä–}±ƒëµ‚Ù½T“ò¦è ˜å�ã¢yæ–£ÿ6¿^inìQ�­gvÖœ ÷ŽÈ3‹åó?¤ÿDq{ÓjðÍk×E€ÖŸêOƒ]ÿFà/þÒ?|ýÁ¿ú£×—¿ücù{ýžPò“;›LÝÆ³Í~`—YË£ÝzÁðhÁmŸèÆßïèÆßßúÛ?ÿú™ÿæoêõý†ÿÔ—×ÀÏé×y³|þ„—2Î QjòÇÔ™Ú©98'OãÔŒED¡Ñ7­´÷^A,>}¶ßðµ%]`³“jäJtK|¨/מ¹Š‡p0Íѽ9?/×åÞ„‹éÃúœŽ@Ydg¤£‰½¸F ðÇ6¡cH,ýð7‚¡5ž`m;†~Ý!7ãŒêº: V6¨¬Ù::'[ÔWYæ°¬ö© ߉- Oßt-¡Qa-w°2kúì²g €MðìXFq1Xƒc18³×6Å^O~{3:Ѹ ,µó¡°“�¼¹ª1:ŒMMŽ�AÞæ¶Áûĉ[0~€”†gQ€ô¸ÿM¸øà+öÉßLZ«§ìÌ7Ï»=ûêl¾=? G;2ùÆ–Þp ²OMà[c8ÊÛšÙ£ƒãÑãµyìºC¶��Õ6qÃÛ:òu‡kRф㟅g¨¬�9�sn´Çä¸ Žiì²Müe AÃ˲ù½^N ª\¯A þWØj°º™õ°.6¢K.}økxí«A[Ÿf®Iãü:„eø?û›Gk>9·è)÷#'@�èóÒëÇ~0=ÏQ=1“#ÏïóËa`Gøç>Ù,ÕËj¬�Ù¹¼Æ�«Îævû7Œëœ~Í="~°Ü¾'&çžµOÚfwŽnJì¦v£ùÒê|©À¹“çô`¿ž7†Y|y�®¥¿6B» s ”èÃ7S5;^�š÷ßì ­¥Í³äÖž !RŸ¬«µës‚`ó"!;¸k”O Á…H®ƒ¹®fó ”Gµ€ÑfFg¶ƒƒ7@ÉŵÕå¨Ö†6aáp*ÖfN}ÅÅÊ1ÞiŠ÷wQ ¨‰ô‡ëXä§]Œùó˜F XLt֬Гó,µ8æÃœØõ›­6ì—\G.P}QPsxÏG¹£èhªªx°…X{â½yà8o^ÖØæñ*k¬#=üÞs35wõ �4¾F‘1î•£fô)ÀçÞ�´qòã¥f-ʱ¹euå2ðú3FFðTIÜç‡(½ ó<Ð1þœSóÙ·HA¶¾p¦w³�k1=:®ç·õ%ÇÇhž�‡xòÍLMÅÑ/ÍØ«·ñï³y žO\;¼âÁk�ÿ”Ñ_ÏÓÃð:"1¡°Ž±FŸ A˜óÈK e‘p ð¡šs½LHÜÚl\…*KÏ÷Þ ›¾Dü]cÏ ¯ iøôÓO_¿ñ›¿áÿ5øþÕwô�úÓà/}A7Âô|힨OZwhÝþk±>—uƒX7nzd÷Øèó'Ÿ~ÿõÍoþîëç~þÒŸúþôë¿õ ÿ/�Ÿ“�k?76SK_Cà¸oª¢¦ÏI|Ôí7®ôÂÞD` â½Ö¿¥È78z�ƒÿ%N>ç yÎ 6Ûãëùf×ñ�MésZ]±Ãçs{Éô~òÜ×17­øÉù¦Æó^8ÙW!"F‹?ÔKèHá4><,U•Çaá9֮ʿìÊÅmÛǧ&¡GKóÄ?=áÄ(�'Ò&õµ-â�ð„ð¾ÙåŒ_�¹^Ø‹›œà´ÍM f=Çe —Øs0‰–<ˆL¬7�CìŽ{"µ!Çm3÷ê68f´1йœ²óøuÈçûÜ'¶ºá Ù]ó°OM‚à?ã¬o;Îï†Ñ™žÒCß´‚Ôï3’h¸Ø‡¿)ƒ88Ó3¸GBlŲ¶¢±Å‹Öª=_3é#¾ Ö9§yMÙ†Ë ì‚6 zþ?ô¬SK$¥Ór8×N¯½8¯kѵhožžß¼¿óû_9âû°ž¦†“sŽÆ^óԛŢÑw¢Ià×ÇË=³õ§˜«?áå·Æ©É¡Òºý&cúÆsÈä 6ozqtùÜiËùiÀ½&=·&GûÐ\³!p|áìÍsa€]Z‹õ,»ý4`p¶³¾G÷ƒîÑøbÇŽføîzҙѨ×!®€ÔÖ`Í�—Ïç“9HïïuûB´óÞ:0V£>ÛX5pÀ{Fykáý¹o Õk²¾Î�\5Îìó«õ^Ò•ë#Yñ»>5å�MÛÌ‚½1­ïNC¼~ÏÆ‰ ªÃWlùÙ¯žq&ÇÕªž$°ú¸Góa« kïÑ3ëú•Ð9sƒuÒ'Ãh-Ùå2ª}l1g½šØ+È\>”Wó„æºh 8ü¾v4ˆáü}=(V×Á=ª[ªÕBp}$w#¯Pï]FЏD9rö½¨ƒD¯ØFÄ^²µñ Müä ÉÈY²ÿ`ü�»”Ej k¾ÑWÜòŒÆÆZ+QtÖº¬Û½@“Æ®Ñ~]°Ö‰M �sÄ”s¿ž’GÃÓÈš ;š-)ps;¨@8Ür’›¡5:°oðpO\bd\zOûª?Àð‰R8,ý·‰¼“a/{‰—íÑ[ƒäˆ>¹w¤O0uq)éêQ^ûęܩɺ[­ë7 ó�E{¢ÇWÈð£syO)MÙÞ¼±L'Ìf�DСZÏö© öþ=¾<¢<ý�ºDÀ—C¾a‚ëð\çÜ@’Bò�ÆÑ‡~x«Ååw²#¬o÷N$|&ÿœ®œ?bcÏ My7€Îáé�É{])�Tjij2ÑÐZã<9Aˆ*;¢³ç…oj"Qäÿÿ§äjö¬k¢w]O2±·P°Œ]Ë L Ø(È#ä¾>¯WŠYµ:Î:1쳚Þ8¶ž\Ÿô%½‹�µWh'‘ñðŽ ']¸íÁÌâ.¤š �kùs�Ü$Ñ1¶[‡yuðu®�ú¬Ž½ Û‹äŠsÍŠç-hyNll±$už[n€qE<;«°£Å½Qþ¾ŸYÃ=ž­Ù嘂k�¾EeŽ[¿¶UƸ� ƒýŽ·µãæÄ¤‡ár&= wrhsó¹Î%'iܘ±,WÏUµ…Q›Ïç’¯Åvzöʤ„Z—ú óS[Íïë H*ó|bNl‚ÀÕ–kÁçK¦Çs˜Æ\õs.ÀÇj}˃-‚˧ßóÌuIšÒOJ�‡í|ƒ|ÕÙZlÊWÍ^“ßcAîÏÔÅÆ¿ ²µõEþáì F¯øÙZG �zÁCRýÄæ›Dk7Û9ô¼ …°h×R{L±±PN?§mÅ€En’O.âíÉ>ú‚=±ËÎ2¦t,ÖS¦äœP5`¹½ùÚ+"dï¹–Ç蘘†›ÏdÓ(g ÆVõ§.£ží’β¹dwËàJ&P>¬;0éÃçG<�÷Œ]Йƒ@Öúè(;fcq²žx£93 <ª¦× {0¦�ÚLê4‚fãØ¶Dåv�7ùh"±øm"ÖÆé‹ö ‡3 1y‹¿øB"ö·›+܃Úo�±h«ý¼8¦üòÕž;ßåŠL¸ˆpŽ˜¬Ç)ïÚ´ž@ø»iÕ·6㈼'ò+Gmá(c€îÛ#7ˆ`ÇïÔÒÜx+{æÔT¾ÏáÏéO€�ßÑjØ'hø�ƒ0./X0h˜¼pîÔá²`Dº©3ßk‘-'vÆûŒ­¬gÜq¬{²Ž_–rágͧ^ˆYçO5&Îñ4ËcàÙ“Ÿ8>öÉf¿qFòq¢ÝÇ9Ö�]æp­>ök½¸Í98Öå¾B­9ƒ'“uSÿÛ_ûtü77Öô%ù"~ Š—7èïãc9mC¡?ÓK ‹–ùx¯«9ñ&xbß“âÝ:…!Ïü4¹¿yE1°$Øp6|1cè9~XÒæZÌžˆã °àó<É5©Ÿ²�wåö÷PMΙк¶ ÕÌúñ”ÔzcèÅûhï�»üìóÓ&¸ïó]Îo`®oô`º8w-½d Û³ÕxÎÓÔW@ÓÉÑþ Ñ?µëÍûmBØ7µó%1 sŽØïc1ØzÎî¾áCØw'ÂrõŸK G®Þšæz4Wë* 9 É> )Ý›ü±Ä›\ð;ƒ2e ü�ËíöñÛ7Jç;£Ø{nNìÊÓ"zÂæ áÑ"5Ldóuée8ƒ3ÉÎcjŸhO¾&ç›%ÎMd&ÖœüÒ³û°L–ä�Éîw£› gíG{�XöáŽÍFùøºÃ ~n6OWàYë(«òƒáœ»àŒ�) 㺮ñd7<“Ùøý&Èñóõ[ë÷×!kR|¾‰ ×ø�Ôzeó‡Å@È´köÁ¸9*™ÏónÆ”p“náýƒ´8�v^xÒ-Þ“0â»p+è²i™¨*²\닊 Þ¼œþ·^lÊMŸ>?ÿʾÏL_?ÒËórñ(�žiˆlß×�C~ï¾þK¯o}û_¿þÃÿrþ�@¾¶QãÄŒ$s8»Ë &°.†ºóoüýîëgŽãOÿ«¯þs®�}-k[è­Öî±mìãÌÄMŸü™\pV5u%ÖzÍ1>|$‰K_[†—H~Úíç±ÖþÍ5aÑë>Š(™Ar–8÷Z•/MÄ™a»zn@°Fføk7–,úd0ÅGÜ1~N¿yƒÖœïè239Ô¡šw\™½WÞñzêajjlØS÷�GWk0fêôâóÆÕh6ˈ øéCôµýŠ-²Nßý:g£xôY >/çšuÖF“Ì`÷Èÿ´Œö¾y¾iXTgŒ>êIc‹ð±…¿¯ìÒ[ñLðž ö2z¯õ­×…Ø�ìý¾RÏ?=IŒ…{(YºŽ£w4N?,‘‰íuÙ£ ¥ÅL݃·v¹Ö?zË#2xøÍT#y­Ô0“MNcЇÛ5d³L™Ž¿8“„oCb{ÒLOsòÇÀ÷O~ÏF.®Ë ž¸iAò—¤6±£gê1�L'îÒÆÒµéõ�ïß6gðr]#xø¾ÌÛ”EÁ1ïû4ûyî Ø>™[>__wž&•�Ýš(íüô%B„FzÉÈ{tzÈÆåÚZ‘#†L»ÖÔ¸'6>mš³¡�°ž}êÏæƒV æïo%¬ï3@–šº­m¸ÊY€ýÄŠxkP<ƒúï>cÇø•‡¸6­³¯%滟ßÄðÜÉ9qÎ\-�c_íÔàNk¾ê²}jó¤š:âÒÑŸÝEc9­�œ£‘=_w‚ëôôp4Kq~îM”åêðè«€ïÚÌ Ød9èØ\Z÷ƒ~0x�N/õŠ®s®Þ³Èeýͯ¹xé`?¹f-1æ–#6ÛsÀ’lvùP›õ]=¶³'DüÈÈý+~Y Z=ÔÓõaŸÕÅóîk~ cÃpœn¶q¬!éç³&<}îøk#×¥ø8Gç=©ÃÍâ~´nÍùàøWH·H¢H7c™@›|N4më4q~j¥˜=øÀ]x¯…¹98¹7Ž0Œµ�éÚàŽ’cŒ�Üg…*Þ‘wÿ-¦2È«éÍלÞ+@{׬÷ Žb)ãMÛ˜ŸŽGýphX/üzÂä$§/ŽÄØË��Ç�§ûƒi-oøž{ü}0vrFÅè›,ô’Á yywF�?Q1qZ6��qè˜k!½Loã¢Þô¸{0äâþ©Ëù±U?©àŇÑ4ÇÉü¬°˜ÙK6ÁÝsŒÀG;9EàÞ�ó$<œ&päö˜tŒè›¿ØÄæãèáòê(=¤¦oƒÓZý+ÃÚ»7KÒÅÌŠk-‹sÎó<Í¿Í#ܼ™$²7Êv8ìÝžZó­³×½ªÉ8fêc“7j†âûéu‰…æ‹¶böïtÈØwkšyþ:œCçinÇØ{FׯÈMÜ<ÿ£ÛDZBëÀùö9Ýó}úL$u»—Ö”}ú‘x||Ž{“ƒ[Äɇ“b°èÁŽf!íÇ+Ppñ @õÒ¿¹469œ6ÀáJìMßëÕ<´ÙmÜ–9oô*‡³çàóÛ¨ ~K«Xnäæ9Ïj˜S¡H9ŽƒUï>×oJZ¼!M­—(-M;y”ІèJžô³9—ÓÏoÍ~£¦9¼É™ª‡8ô£›†aÁÆPãÔtŒÖY]¡>Ç ¿Ð0ù�š5æµÒ°+vDc>ú. î=.b&Î7�mˆ�Zó<‡daZ¢�ÛßCt+'ç\޼ée…‹†m:ÚÄÎ~{ξCpëSPóÙ51¾óÐB®¥sôzϵ§óí€ÑXz|þ†S Sªzá¿)>b°õ,¸Úó? ÿ–þó�¿¯ÿ5øÛ¿ÿ‡¯ÿè?øqý¯Á_òŸ»/$² hÚ¼SOŸOÍÂoŠñ¿úþÎï|ëõ•ÿþïúßøûgßø õ•?½åå& ú¢7Z³'Q¿VµÁ:#sö‡ÃÅ�;ÐÁÉÔÞÛˆ¯Iœ‹|æSHÊ$�€cDiöáãb¼?ð²çól÷œ³‰s]8Çúdžrñu‡un~¢àäaš;�–Ö9GläÛóè ÚÈÇ8{çÅ2zV¦ølÇÐ$ZÏ›|Ý™>šìŽ<‰ Žo³qž¬“�¼ík>{9h‰Ø¡89Ë'�¾Vòݧ•0?8lD”±¿‹¬ûÂÕÄŒ.»| ßy-1É4zã°ïq¢�88ß2ì7bXµ_½É2T9oɹ]‡“|ísE„�l½6Ž¿žreOácÖ{!¯Åî÷l¹&÷9 œ·fK€$囸”· Ø�q÷¡7™B”œøÅ´)LæE*Gî •·ÑQrba‹íè³­y5¯Î+gâ8fXecdªê^èù>±èäÌ×Ùîë’í?ëò¹w²uÔÞ½çËÈýŽkÃ.°ý×ÞKôhá˜ùºÓk­y-Bõ6•gù°e|Ž?ÖÀ›µeYAPØdKB„à*¹×:ð­7ëî‡üƒ?íå�'žáé±ÖTÛû,òä‡|ÍwT&û} õ‚óÅ#gü7B6swz¸GŒÎÕ=ñóÍæIÓ|3Égˆ®‘\1X§x€×:Îé›`9¬iòú<Õõn3gòúIví+ÅyDØ|>Úß½Y Î}a/’hmµköy�mH™Â?§ßewíí³kpŽG=þGy«³X"HRNÇ#nÆ©%ýÆ\lcÓS!§^cæwï7ãÔ²sR/ñ·ã0ÙÎB^×ÂÂÛPÉ4Å~ü§6<É1Ot$*]ǨvR�j'çÆ-t«£µ¢�sçsš7ihóy0†âX訉ôåè^Ü(&ôŠç¹.EËð'þŒ½!ìÈ8}B@­õŒÏ•;„~Ü}ÀXŽü™Rø¡pnãïNž‰†ar=áPÔåÃÏ@“å ?}ƒÝvhןýIYn $cŠ5¢”™ p5ð‡0<Ø3Ìí~Åf-v‘ŒÏÖõ¸ŒD0¦�“ÓûŸ×Œ=É•=¹ðñÞð±¶gì¬Oü8£HžÄø:XŒLt·£+f03SÛʼn/œ“?¹ =ä‹mþÄnêÙ,‰1ŸÓÅŸó-üûih£�Ñhàæ¬ÏçÊZF?x«µæ k†ùBg³=âäÔfÁ§Gy�ôL¥�³iŸz°A8߸ÊÖ>ìCâ^n.b”¯–h.°s\<{YÌA¯õC°y�Ê{†ø Ý»c±Mˆ7Èf¿¯ov×k¤×ÎÄ­¸ÑC<,ÄŠ°q†ÉÖ}´Î—äƒ8^SlŠì‰áûð´$Ï}¯Iò§ŠÌÆ=ö5`¼~ ×ÞÞpÐ?îþÉgŸ¼¾öµ¯¾~ù—éõWÿêòú/ÿÚöúáþ÷ü[‡è£n^7è7(x|_ÿÁ‚ÌüýϾÿúÞÿûÉë»üÇúw¿öúÕ_ùG¯ï}ÿËE¿½È7ù‡äU5À™b•›ªœ}ÍÌú´�sÐaÄ85üÚÖZµ7>|šÝCÈäðŸT«~o €&¹étš)÷hbÅh/�˜™XñÁíÏ·÷$É{4¤�ÖHœÆi6ÏÃï¤:(R)ügÿžIÌÐ1©Í#<«ï²Çž6�ØÞ$°ÏœÃ ¤#ArôZn¾œ~÷@6»Å¨¹5½B ë–,aì£36ï·¾ðM‚I”F‰<“3 “9~rÇæ½ÀÎéZë›ü&JÔãè€Zxó…ÔU=µq ‰u|ÆÈ�ÏäfÆë¡…ã´Yóq ³|;§‚mß3‰•ÅŒô[ræ\$�Ž$öo¶×7‡‡fdà¥Åvνâä8 ÝÜ]ãG{Î*ê‰¸Ž¿éàÉY‹ÿ¶c©ÎT…wiMM‰ö×§ ¶†‰�I1Cí„D‡K –ú\—X©�x´Íõ°uM}&Bœƒá›óg‡NUò‚%…Ã’|÷íAÔ‘Ø2aE¿ë•±Ìឺ&‡s Œ‹$ØùÑpgi6f¾fóõi¾t¯ÆÅ UûCØèÑGYÉ%LŸ«Á [Äåû8ô1ô®ÓX'_�“ b,B±Âq­2f:K�ñ×PñxïüèÓåj"c|2¥§a6øúWÊ„[‡¡&°~8ÆW¾î�ƒh0:)̵Aä ‡ ILN©yht¼­Â{’„ÿö‡Âú’{2*Κ¤{u)î£ º5Ü’^y)½§-šå–Ñü¡{%fF÷[Óä8~Pe<œD6&,hP$yuý[N 3ŒÞj¢šéÄÎqŒ˜ÏtA¨Ñ£ók³1Å'üëw´c\»ð]»Çz)²vá€z †÷|þA…<¦ÑÞ×™ü¾h"ÚXöŒ5‘�ë/YÁN±ÆÎÚöeÉÎYãè�MÁ îušÙqVÛ çô‰¤Ä½©d 2UÓ¸x^V.i'Üw¦ðšn²i¦,uï=ñ2›ÅߨœoÚ|sR¶dz³"5DêÔõ1Çœ¯š?µ¸GòQGÏñÀ¦ÎÇø&gyÜ3¾qYC¸½­xG ödÕ¼\²ÚÏ!ÊêyNƒ¾œ“°5jýPécû—åÔMì®õhi®¾C\dá‹’Ó/ø³ŽSã@â £ó\5�Ù˜w_{\¾ä24Éœ{ö䯿�$%9¨Isyï´�Êy66­ç �{ÅvÀÌ霤HmÓŒ�3¼Alàè+·÷8mdçßt5g•»òäÜŵ5Wt”b{�7ÃÅ—çÌq¥G]3{@Ècbcû¥ÇÙÝç`Mnö£±|�[ú�ϯ†�Yæ¨3 ¶»šk@8Î ò„~JH�»ÎµQèIöì 盄n�æ-iRDc®TpÁÃê(kMÞØöh=h00¼Ibˆ2ŠÚ•lˆÉعdñƒ…(×¹—ÈÿÄWËû&­¶;ˆËC&—.ÞÜ2èˆ�“ÃF.¹5 r$j÷¬¡UMÝDµ¡`§Qé&9këŒiDël^d'WoöæÍæÓÃÔ�…UøO4=À†¶äˆ!áµ¶êh#Ç= lã�bú^0ɘÉ׺ñ”ÙÊ×èxàèÀßwƒy=h¬_Í„%éÑ�®D«Ûaz­Ìw¯ä‡ÿjqnðç<Úìͧá³×üäsF›¨…�Ík»‚‰æ‡×ÀDøuÍñ3óu*\éI³(â&�à}M†Óõû=…j¥FÝijݼú³`�ïïö½××¾þÕׯþ꯼~â'~âõ#?ò—^ßùî¿þàÛ¿÷úÃý‡¯?ú£?zýÁïÛñþÏÿ×þɧŸ¼>ýD7û<>÷ú3_üÂëSÝìãØÍo'æ7 ­_šöÆ_ÊQ×mttkŒVê¿áª#6Õc_*昺²ëý6Œ?Õ¯œPß¼Ô/"›—›�Í……:˜}ˆ �Q÷òͧâx£L° Õ1˜F�|ç\Ã'ÏðåÆôõNœô#ùNÉ‘¸êÉÖœcÏöA£ÁõhB¬G_ØpŽ^åª~òdP+â<9kk$büð3|!HÐøª)çI�××ÄtÝ œiY’³Û©MS swkª3’7{ãtp9îGjÁî‡<‰ÓÑüâÐ[¢†s€îi¬Ó'6Žá�~8¯Ìç:°‚$ \¾yßß¼Æë ±¹´HZŽô!ï]­•td2 ‰YOºÅ�ñ¼¶:ÍæéùµÞ깆+ýO†’'ÞÉH"sÆ,˜,¨ñlÛ›á3&±­²A‘Ÿ£k3—Kl>q4öè”QЉü\k%¹0ÔæUÏeëƒ ØCóõú>yrÚ²'=©ßq.…Ì^ä|�6X|þ4§öTlÔ☕YÙøu¸ß‡j×ç¤ê´ûø’ƒ|�<‘7×IzÔ¼×I7ľŽFîLÓ‹Ý=ò¶Î%ت†K¤=Ïý!Æö{(}3Vë\âÒtèãyÓ×SkÎ Ø+>ͰÍv)Ù¶î¢yçúšæ au �÷å½©Ž ‰7ÕÆúùª˜rݘ½..ëTr×c½#($ëÉ—–Š_&WP òߪˆß9¯|í9þͤ…i¤{Òà>~ï„Ù“Ÿ¤>fiDý·ó@ª‡¿œh .õÊFÅÑÞ@¼ã¶ô]'|c¿ÜΡwîäˆÚ;ñ )—¹kL`j�9¸,_õÉèÿïb\åâIY—[ ¾/€ý®Aˆ”½s„Ñk°fúAn6™¿A–4{Üý&æ¢�›] HHŸ8'ŒyInÜ¥ÐÜ쵘鄘Çu™híbJq±9E¨.ïµt²kßVÉÎ MO8ˆHÌñ´«5Ñ#ÈBhTµ½kÁvaŒ\<Ïø=�SãVí!æ€kÍ·æImía¦ŽôæÆõ"\ÑW¬}r9¿ä½ìÞË}yóÌx†sÛ;û+6µµ�†ï!¾Ù*æ*߯­EŽÞˆBƒû29œûM︬(¬Ñ•s µ¬$³™5gòšk„ Ì ó,FF­áÃÞ^ †圿êiŽ^Ð^„õ¹ öÎ)ªh†ØDFkuÎ\HØúÐaG«…íjd}óöZ"6ßt�ΰMÚLæLèaŸqzž=µó�½5®Mÿ# èIæŒrlœèXŸ\ìSmH£ùÖ3I+>¿Ùr§Í•ߌÈy-£)�h,â»(�õÔŸm®ÝÁ Ü|xñå›HÙ‘Ëcn´7àˆNÏ“ÍØ‡Í�¥樣GÕØùzdã°ôr6ÎUü{³DùzÃ|h5)““àó6”,yîèƒñ~�Û²AH™%H ˜  O?Fù43ÅyQv¥Vøá)8º'ÇŒ&Yýw´:sŸæÓûS@WbÉYqí&ïž—+eoê…?¬ÏõptZ³¸¦|ó²ÎþÔæx¶~-XÃiÞÔH®èOÿsFyá%I–hÀĹoœfG¬¦³zCš{gÇQg¾‘"Gêf1àÔ£1ä¹×»wìÄ(©ónòèîµµ}ø‰%i‡Öð¨oéà•·0fô26(¡AczÊ¿“‚AŽÿÄRÃr|ÈÚr|0ëSŸLv9ñ\ÿÀœcHÂx¸íÞj EçÑjèðv=ÚÏ ‘ƒb£É)µvœ¶¹ƒ‰ÎÌ3�™v�682Ò7­'nÌXßÁ% s6fÖ®ý3W3ÜÁY‡"½°EÐÕèr}ˆ=> gqåo]î«ñ§áH>Ž`°å›ÊùZ¼6ÖtG>#ÈóYËÎu*�T™à`d‹qùž›hzó®;‚‰Õ79Ãá= 5â~Å‘›ÿ¼WÖ ·¶þ_þt×|žYwÏŸŸýgú÷ÿT Œÿ3ÝDD Õ‚>ö<¢!ëjy¯±v°Üüã#Á^Íú4¼ŒzÄvÿVg8þz�®ÛG.FŸçÄøê˜4£"iõÑZ�þ«É1¿µO@Àvåjaì`Æe›Ê©Ùé IDATOt€½®*n²•Të,Sõ´&fpŒ| IU>çØxL/ÃtâñÏ ×g¼VzݯL¬-ß³wޝÆÌ±‡ FøÍ2ëîã{Ô3yW“’9ŸÂ™ý€ËtÑí�–)1Ï­ÖØüf¬³7&sqæCކóí@ßÈ+ï¸@MÇâ¼4>#glIÇnÉjNî^'‡“Õö©¤]¢è6¦&æÁ:^ÛôFsÿÄçâúÿ»¢K‡ÎÑZ…wÏÚ¯û|¹o&àSÔ\$.›¼øøJÊÖÆ9\qÆ]>ãð_Ю›Ëû {ó¶/`l›\0¶'?Ä¢‚ÚÉbŠaé!ÇJy$·l=ákUÂß .ò#|M,ÐaüžŽØŠשë¿O káXG�f“µ»hbÈÏÇÉž8Çf^yËmóX÷`R,V—dÊÑAL¹(8üñ7vó+Èžjd¯µ¹OY¦n>¸ë²ÖI½ºGˆuÌÚ¾©'¦œ£Õƒü�š„l"rèÑ|“²ìWppË=(&âV§ë íч–«§Eâå÷OÁÇaù7ϧSð7gyJ�ß5OAÍé™rÐaÕY;¾6üŠ«ßœ°ãÂgöÑé!û=»¾äo2 ¬¿{Íæsž!|ã]éÒgbžý°M\„Z‡VÀé ÖgÀL’Õ#„MƒUÑf4f�öà[[œùʉQ6…5Õý0Ž–ä<×xZ ë z »ÑrÅ`›Ò „äÍ1ÑÅv�PÖŒ,Ì«uô�½y†ûÆj½8ÎÍéUõåœ��BM-µ›²ùµI8¾‰rVÜOñ÷7æpö¼0ûCpÛ&‚ºª5„¹ˆKNôyíÌñ“ß< Szq Ñ’}ôIºdbvÆ0ª7ûÉ8LØNÿ‚A�ê·ÞÆ�7ÚÉb� ôíŒÇë©yy\lâ¬×û1*1dd.ôdÐ­é˜ éßÄ3)ȼYêȹô¤eÏ«0˜ ÔšÎQ*ÏX HF Ñ¢ãÅåõðP÷]û�9›9Í!G}=P„¦Xöù@ uõ<±7xòîšP=ˆŠòÇ9ûpÔ訛Pç¼¹B<7Åò†�Œýú= Cütu˜c©ƒÁfÌÍ­uãü<‚@¶þ“Þj_Í�có‘(¹Ý-ƒ�<¥í¹Ompq-põ·™HøàŸ€ë!7q ®6¹þ�rBs­�‰/×`×3ü[ÏÔN×Òº¶ ÜNJþôÕÚ-ÞN²�87"ySߘ…áúÚÞÈÙ²™ýPlm�b&o†3ÉpÛ‹? À/›¿ñœ¸bå€Ö›ØaØ|�íVnŸ® &Sr™$ÿÉNBÚ¢ðÉîÐÛŸëäÑNâ\ò+pÈú}]^«È’�=ôŽ–Ñ»ºw®¦�z-µF”X{%3?j¨ƒó¼ Ý|&0µ$sz�ð´ïÖá<`‰ÆÌúñÊèÍÛkB'®T­Ïžu.\sëï{+\IŸë9¹lUYïQRÁÀú|méroëöØuºÌÔjýqb›Á]Þª}À‰mµ?’u?;óšs®QÛΫ%­=õp�V�__,¦˜p Ž�†�ÜñàŒæ[ûÇúFÐÝG“O‚è1� “AÓ”™þï>5˜óföøº^ HÞp`É噵Fû²Ž5\Àˆ –úà5dû ¼¹g¶ý vÀ5VŒæÇ@ø[ò‘7¡‘ ®>J³t �ךmÎã,S¹'t\flýßZ¬�Û1ò ÿ„cõh{ý¦°FÍÄ3n½å°Ã¹ÓD=š÷–¤9ªÑ•~ç1¯dvÞÉAÍpœ‹ŽÕ$™©ZàŠµúMㄓDZ¬ƒ]ÍÆØ9¾MóèsòGÐá9ç1™ë}ÚXÝýá�sTÞiÉäÔ4#ç<çÍl’ÔȉKÃièf8ÙNÙÊvű>šGNkoøè<5äOû r×O]ˆ².÷ïæÇ+?9™½q2*(v‹‡Ù:Z Ö¬Mà¹éGá'wëhÄŠë•)ëZ19ìp͘¸n�� ;£sÖé^åò‡ìè|C:áe4œÐh�D“ÙçÞŽaN|€>V1|ð¸ÿÅ‘ó&ÇÂ`ìl킗źµÈp<¸÷�Mx÷ÇþÄ'w48¿nAí÷ Z§cÜXÐ�ìi€ÙëÞ4Ÿå 8£x߀#�ÌSù>ëÍ´4sLéƒiÄ“›iÕ¥yQøL-›€z„ë¬Ã;7ó>Ó¾Êsór>üA\õ±zBßÉ6ìÍlôeûÔâÞ¢K_�ßèu–©[ødeOòìXNúðbÖØÆ~ûF›û��ÜhÐGû`š±ASmÉzrâ[^NžÑ›¾{GçóŒEC1·n—(à]c€96>ÚhÉ€”6É–O[Û+6]Ë�X#ÎÁ~ê°ƒìlŸJ@|®ÇÁ¸oá„£yæk‘þ9X¯8fPu“°nÄ –ŽeÓ˜â'i"ˆIðŠÇ“K‹ú˜›~s ç­=oi!†Ëô£;ÍàBóq\p€åI?)0ÎÈ~ž,²Á5Y ñ;ú­+ªr¼ê# ñ …§c"\^Ì!OŽè„ب@�hÙ”7NÎô—3“Lcâ=µg˜©ÃW­L�¹‡ÓŒ•oîÃ÷‰KâP^½…êW„‡c€'$Fúº’­ç‹\`#Q0åÚXˆƒÌã—þr3Ï• _ú•™5¦ðD^ÓùfÅ8†Õ‚Õ¶É;šÖq¸€¸ž15‡µ‚ÀÚOÙË>ãÆöþö¨„æÑž伱䉎«H0ÉÐ?^\3Ú‘„77ùÄx°÷’¤Õ‚g€ +æ‰Y�{ˆ&´1 ¾(“kñÎA8u°IŒùw_;QåÆv�Ë®%,å ¬ÞK3½¹ù’¿<ŧ¾ô±ñõ‰Ñ&_¡VœéÉèQE€7÷ù±y"†›X=¶Ç• —ŸÀ$Â�‰µ}Öæwâ\³ùxcÙ×ß^ƒ¹àé‹!c2¤†Ì6ш†³œuò�kLé;ë>î%ØÁYDce�=cr­ýu@ohHc) �­ó É9/æÏ`ÙÜçŽlöc}Óá3Nœ9Bb!lyhäÜd�šão<ØœÛ`z.!57›!´;bE€yEdÁ@Zƒ£×óATu²ÞÎ ÍÕ£ ^6�9evˆ“zˆñ2?ò#píAcÌbb8O¬ë—³×•qòsþAaçæ ˆ�hF™³N ²éµ37Ãr#Î7 ĵýƒg¸¸!×ßXóšß²óo×%¯ÿ”wl¾Ég<ùtS“µüOÀÜ|‹>þWàþfŸkC§‹âà…¯a몙]ã`�Ô�¸ÄN(xåðà ü] KŒóè¸Áœ©»ù}}ÿÌ‘è9.—™sXü\§¡˜œÐ�X´ørØÔ] 9X/º¶^)Õ…ˆö\CÁÂ…Ö9d�C0Çé8’öú³“%ü¥›•ä†)¹r-õùŠö[“0`uîÓgü}n¢�u"Çwíª=ù�B,Ÿ Uˆ½Ž^ Ô휡5u{×àÎäãDaÓrûgÓfÈ™5NŒðÞ'·U;ÜÍÇsH(Â=SGFtêÉ/*øO¬H}Ìýz—XBð9V bϹ�<šðû¡0çKøØ¢º—ü|ï$ÒÿÖž‘É'>gäzÉ<£sv9n€¶( v²NLûïð ‡üž ø�Ÿ:ÜûˆèŒ;¦UÏר)¦šˆM®S'eH{ªkpÉåðì´rákì\‰øõÙ2GV½Öt©X; ë­ÀõÌùÅþð5qŒý N@©›^B2¸'Üìø{>¬WT�%Ö½3oàpº¯‡€©}°âbK�Cpæ›p`ÉçœØ›�õàœÛpñïÀF¯MÚô<°/¶5°g�T“kfmjÏñ;VÏáji `YûƒÙr’_þÂr‘EAd¬¹“1\×ø`‹ÙX Nc±É™ºH§k›|€ãOîjLxŽ'›é“€xÜ­�JHŒ™yGêw�ckŸb›ùü[ÅðÇ{…Yƒuí²”gaÈÚœ“¿Ñp°.”ÝaK,VÙé³5ÈCÊ:e+wø‚_Rá4œxbáÑáµpèfÝÜøƒ;è] Ûîæ u8äc„‡üccÉX×tíåÉ/¯¿ø„¨ ûÎ `2–{ÊãFÙ#|"êj\.ò4¨b›cÓß•¯þDÝ C^Æ. ³•Ø´þ˜AöÄ:¬ ¨c„÷ÄvY3ØW1o‹Žõ;YTGyÊé7dÚ4†xǶÁœ¶æ` Nò�2´Þ±µ‡7êÚL%w�˜ÁØ&wc±³æ#y‚D¤u²ÕÀ×Gµ8çU4<æÞœÔaf`ÃŒ†õiuÅZGq‚‚Ãï1Ó’L� g�c3O­¶Õ]í�/.¢Ã Ç×ÍfõLl¸-Bq�×¼Ž¿œáWŒðÿco·äZ®$éMW�#Ý�d’éB6fzÿgTw�–þ€Ì,õ€É ÂÃÃ#Ö"“drW]35ØtHŽÏ8ì¼Õ†Ðãt¶ìå:ƒµq³ô¿/±~ÚÜ(Û÷�òì†ë<&—ÜO²-É·>™C~ö©©ãl•Ç÷ÚOŸ(&çŒùáÐÖ:e:rÎ:1Æ;ä��Ï|^rˆíð³¥Ûç“Íù³ÇçÞѵ#@/`õ\ž›#¬‰~�ÏÔg &}2ãGŒ7Ä9(3Ëè‚/c¹ìAžî9¯ñïܸœF%çsž3Ò«Bz^Ö©ÁBš%ºžl¤5öUÚbS“ñø\«[•=ä\“;¹¦˜ä‰VÄ^-ß|xZ�ƒã·j-¹î}£$‹ &y½r4F÷Jó[+± æO]¶wú‹É±d’õä 6ÜwʘYvCt0„ÍzX—ìð/GêG€ƒªÓD²É*�™N2íì~°ã#¢~l¦Í9óg4¬ÿ�…·&¨ÇÙÆÃ÷޳ϱ�;ý>ïïY¼ÁY/�wå‹-ÿÄÐ<ĵœ1�Ëš^}Z;¶¤®ê+nÏeãq»„oHÏ‚¼ð§ ÌhãÞ|ÄÇ_yäwßÀè~êÌøŠ·í�SPÎK Î�Fûpòj—Tè¿w8Àp'Öe<ÖˆlΟ¬‡ÃYrÀ¶| à î‚NÝæŒ&x=Úâ\1‹¶Î£"ãµ¼~ì·?pŸâ予q"¡ÛCœ1†FË–. øäû îäA4ѲޔêÇ´tDZ íÌÅ–ÖNϹ�œ—̯ßì»ìhÜkï!\7âO_Ëíã÷“ÍyÞ¸ëÔ�<7{ÚŠ}c¾�ƒü—ÞåµCI}²ØX€Bµž¯½8+'ÆäÆ´‘s!ÿÆ= 'nPshïÑùGÃãÕ ªÈÿÝ9ŸT�ì¤4Ä’�£×háM›lôb/ʉ¨*Ïöc$(â¥0f<ó¸·Vé˜×/’í­Ï¬ jx¦Íx «As׿ÚWtÓvt \ã3¿-É®XzñŽ»O°÷ƒ”��I3‘ýô=Üã[?~ù &|zŸˆèÖ ¡°º÷`®ç2ƒäs<1èÏM�Ù…ß_€o`I<�05¹ß¦FùÅe½ZD·6»ciËò9Vv‹æZÃç©C±é“üö-7Ø«‡#šbc“ð�ssÌäúïpxªõè9±Ð/ îÛ³Ä{÷«ñ§ˆoLX’_¬Íkß•ËÜMëºDóúW€åÜD|Ίo>vw„~ôW³Ûƒ>v¹ÙË éZ®/cL™Õð;>_òïCÇé‹9¿ý§Ùf'×åËß|Xwž{!E9xÁæké F`Ï"FÙ“3Fû{®¯îäšîÞ…}a´ŽsÒ®ø B>ׂG[@54Mõ5›õÇ‘ZκšÉàdŠƒ0‰Í·s5å0‡] ÷²çÜà•nKÇ#¾ÑY›bmã¼ûœ[b޶®áæ¿»ÞeÊ9ÚŽ¸¦è•Êâ|d[ÍDä¹�ëÈçXŒ#œÓçNfŸÀP˜ ,G5ÑÖë!úņ‡šð¸6sžÃë@¤æb˜¬³�–¯¸eE"18iÈy>øäà`ÒûœÛ£«îTÆF���_ާMqYøޞÙ=mÀÝMà4kÅ`÷T ŽÅ]ÑNΚ&vÇ“ë)þo]ڛχB¶Ö U©o�ŠNÓŒŸ~ë =VNßKGü�+xs%0´9+>‚á))>Fíßn´½ïcÙ-ËjME¾Û—2É�º×g$°Nö�cϲ9ß#Ìœ«‘TM~±ƒÃyô•ߌ8Ø?ñ#ŠŽ©àú8n?x3û¯m¢²X@£=Ï'•íú¦ÛµÖq:Y®amŠXKó̼ñùVk�‰È®G�_nÌùk�[qÇwÐ\©ÉúߦÒåÇѼò›÷8bwŽizê·©œDÎuê€Ø�hÞ.ó¼ÓþÕh ÝÝSg¹¬Ú€­?|Õ>˜câ–pXô‡Þ0ç‘Å5´~|Ñ·ˆŽ£ù‘Òè{öa±]“àùÙCE>Ò4˜¦aÑ„¶>öe¨ý�Þ¦¦iáð‘âh˜ ¾B—çðˆÿ‘sÌ,Nñþ¦âuÁŠ'ØÚoî5ÌNÑßûä &š“ÓÜç䤎Ý_x“ Jã©ÂµRON¬O"fû†î^[ã|N¬ƒÆrN;NѾèÑúäµY…èù´†0WúÔ+\É¢9[r1b»zΪ9�“ÑÚÐ=.z7Žõ„, æ­­±#ÙL=zx¼n^“é0Žåmz‚� œó%ýÑZ'(uTûå¶7Aó׸¼v|ùNœ‚Ž.³>œ\Ð?oÌò¾~óƒw\sH÷x9�¯àS�Í:¸'ôØLš}ü@Ð{î 2o¸‰7 ÷ üx©ckVL6=Br90½²s‡ûÒœ`v'&½V7¯¥ö}Î :ÕDwÖ1¥›ó£ábÀÉS8ëŒæÆ+Ó­#Þ¼ÀH,–d×Þ}‚Oñ²SgêIǨ¹û“qyBóÄ-"U_-«¨\Äõœ¥FraË”û®ùÖ›u˜q$†Å²bs&Í ×ã\llyxS;k�ç·üMÖóßÿ�°óÄûUM<�®Žø?�è~sÆ;ÞÖ+&çòá÷˜CÍõØaiÑ—<¬Sç´ÆËn«äÝÎýTp"afï½^ÚK¸ñ’ì bt‡ÃŸÏˆgàK/Jhè)vnÂÝ\¦ 'np›µ«hó°.¼@±9ç<€ýç9>pÖ€¥×aë æž}ï ¤XO¨ƒ™]RÂÚuü!ò‹'zoðŽ"Û”’Z‡Ëóï;l�]¼°¸/o÷°&Ý?Ê$ ÃdYfßµñ�¯Ìô¾þÚözÌ}‘­aÛ}sàµò»Æñ#îÔï*ív!³û?5SßléX¸óœ‹�sµ°öx5»&êêõñûG‡ÂÌS*ûÇ«ùêA1ØÚÞ8üß ð2:ec{ù�_{Ñz˜ÝqÊ�å�-æ4mÑΞ>}ŽhNÿV“ûHR/‚‡*=‚Aw¬‡Z GÐ�l=ÄÑ!±Ø±™{àÎØ|?äþÑcØãM²“³ì(: IDATÑs±Ý°‡8(áõÝŠ”—>Q”cR]iRkñ«ó‹t¸+p·EWa*l_— ó‹òÿ8ö˜�ÈÊk•Ð7`\;¡É^â¸Í¼²aáñ¹tc 27Tä×0«–Þý";w+ìI€ë*¯khnœ`�‹O–3Œ­£kq<~> ä6%O²,4Öë¶¡qZ§C^82Ñ©!qèLOÆc}M¿b[.×D~4¶§ãvlX�oÜÃx¦j×ð‘óКW‹õ˹ø7Ƶ=óøŒ+Öu4&âf[>æ—ÏkÙŒSÌécsÌ®­}ä=¹mẠ)çQ“Mxê¨ 6ZžœÃͽƒÜÆ[�f$Ai�¶µæ}í¥ñtxŠ' ¶ÕçÙ9ž¨åxft öŽ»׬˜qϵ§\�‰ÖôÂÙ©åæ¸œyãêCP~r$ĉMüÃ[»nÖxIhkÚx_¿×p„7çŒ Ð·øB³^{_Öo,È\k :M!�å…¸‰31réÇ3ìRo×ÚŸ<2íŸRáEñ‹w~™vžˆ‹&®éÖ3yÉZ{{{|·×ô„q¹´¯fìã÷šB4¨m5³?õh±ZÀì~üNµŒOì=6/Ë×¼VsÖĆ!=×"ÃyZÓ4�Õíè3RÀòyBðáZOKæ>Á�€õeÕÜþUƒ¦÷<íŸÍ;MV§âœfPš%)w´kÿ¼ˆ?Z  N&Ý£˜=}�kŒÑä–auo˜ï»†`B>Ï}ƒ»Y�¹úb?i„u¥].P…l§gÉä0÷êàïõŠòõšüìý¢œ…âÇo]Ö†½£µ€1óêpì­ë]¤½¹�müËc%Ùyu�$µ9ÙsC0½HòâxBtƒOÃ8ͼY†ëý¦Ÿ Ö›kÆ×†<¬U˜co¶a­¬Øu=ùŸëjΛÆÌN§ùígÖ7 ·ÆO~ë#VWé:±�1ê©)€ø£3uH—OæÔ…ãFç[~Ä/¬W¼xWÈr9¡îuõÙ¯u®wéJ¤i":Q•[íÛÂòÞÛøÏi$r²&–�n-g¹å8uFGð„€N¬ã©q…Õo7Þ½]Eó]ÅXÈ�ï:Ôä©öä“Åî'§r,½µUßT†#ÙgKžè›vb÷{-²«Ã›�Bܳå?3Þû8]µ)ƃ)ýò7ÄÓµ$+ùÞ~Òˆ«j9ú,2ë”{ç1¶ð’'zØßŽ)?9}'PÃ=tx³k|k³¯¶® Ææ 6rØXfl‚u*D;2-Ì—D»Û¨ç»=­#—þäI-è‹0¦z!/kò!kb¢v>f ‘œ›Öѳˆ@OÞ&…Öd—1)œìèZ`Y�Ì‰ÅØ;€�ñðV;¤Ó… nRãÙ›"¶õÎ`üÍ “Lò½G§µ¡×Â!n |«É_Ipœ§Àè =y¢' ®¿Lë¼ÍäX:-vîGƒofC¦mròûÆ9MòU÷±E€¯2ŸÎ�œú9ZV»cèÇ�ù�±¦Ä‚ƒw3œ¡6‘}Ó}æÖûò:_5á>ZMX ~<š�\­¹yX2=pƒl:½ÓÎùRÖÅ[¯µƒqüðšÃŸ£9Èç�K6 îƒu&…`ÎkÍZ±?¶�Øï8 (6ëp9w À¾¾‚ˆ‹ã)ÇëyœƒÞ=¹NÎ"«þ9×lìÝpiÔõööôœEðã{$t#“cq °óU,ü~�Äh3<;v5Í®ô”`jº1^;OlìóúnÌÅÏþ%LJVÁ\«ÂôA|“ ̰Ù–ø6"=c_ãØ¿âÍ4¾ÎÆ!È‹pÜ,±²-9Î ©ñh’Ï~0ð}åÀtÆeŸk>1bª¨4ålBqpe¬ˆäV~óÙžØÔ‘…£SÂh/¯±Ôm«ÒË-þ ßò‹Ão ‘�L‹µ‰Ã“Çño트ݿØ�‡ïŒl4ðAyâÌøwó:бY™¡-µèÆ955Y”¶îÕ% &ïɉÀÕ­Ù8æÖî>B¾ùÊâi:Žo|N¡Í3Ÿ<ŽÌ¿sœ|a_þÓ à 5u¼µ(t>-n ²ó&ÍøÐ;l¹Wƒ]Ó_ÜÍ�!õÌe‹ò^ÉQ¦¸áéÀ­,b¤„k«Q®¼à_ž>6”Ó9ÜC^�íNÈeË_·‹ÿêu¤æ‰i˜ÅɦŸô?yÞlñÉË$é ¸u±BÏ4�=ç߃".oÀô঱¸4 ÚÌg?€ÉÜðe�‡çŸIV–œ†ÏEu-œ™óœ teøt3Ʊ`ÓÕ�†w=°m‡%9zÖ¡åÛ�LP/á = Üvi‘ž=`P«E óâVÔ”Àáó{Í*¼óg™yÎÍGŒŒp<>‡hö`“õíij sò%(Ø×ÅÁ/j?ñ$ZõâÓ�Éæak·ãÚÎJ‹­/Üï"½©=´‰Ú�ˆA?WfˆY6Æß”óGïò³Úü>4 7ž"Nîò@bés�àëÿr›ÐápRçÅ7R991(îdÔb¾10ç<\ ØÀúz6ÔÖ÷ÄhLã]‹ë‘"ÿ ¸ø.³Vóºj³vÀ°ù@�%ú##?Íñö£aÆ!É=4obM �(Ç8ç·�<�>l;'¸<΢{Mëˆ-O<ûŇSDÍrŽr¡ÆÒÚMÄÁá­#û…«5¬É»ÛA^Pt­y YËäôßÂl9'¤¸ÈŒrë&¼7C´ŽW»jbö`æN^þ“±úx×ÁNNk¾6þæ„ÄåHjÀpš>Ÿ[̺¿‰W¨üË#ÄçŒ cÌŸŠc%UbØ{�”u¿›þà ŒÓ'�f­Q íÞ¨×÷®‹]ÁH;üÆŽ;.V±„³ö°þ[›žÈæ²€ xùg‹ûðÛL8‘ÃBÓ–(ãÀUö7.sŒ@š`‹ �ZU§³°Õ�ü`Èa-ŠÂn¼5œ±Z�3af³�ÉÅÉÀFL9b$]«£X0χI>Ç¡5œåðÈƳq¯êp>­•Öƒø£E ßpÊìT í\Â;ô±Ùèx–‹ÃÚ±Õ`ööÍà¤À^ ÆôØñ=l¶Õ�šm±~Îy‰!èx-ízõ‰xΓÒO-ðàoì†-®Oýxj0nÉÆeÿ)9Ä8϶$Ö€¿¹¼²LYH 퉻9ˆ„jÿŒÁ}'»ã¼Òæáe2Ž 7òÏ!\'ø“f‹{Þ1�uVN˜O�öð™ó ÝóìÕ§}ù†�Œ-™±Ÿ!2LÛò: LÁ{ÜÄc0>¸…œo[úæü„»GÒBÓÍôâÍwë¸×³q ¦wedy¯jÂ0vwb4ðÜL ovú—ݬ¥x¸îÈuOO¬ÌiÞ5òS�sU l—Qú¿ûÍ{ö‹Ðìåö�5¨]Œžô3µ&’£Åc=½Bbb@gì¯y‘¿˜à‚MOà�Äfι4�ºÑ>„=XÖÄlгdÂ(^klîÆïŸë$&Á©o1›Cu`.M4ÆF“5Ñùˆb)P”å\�c}Fkøoœ#F^Iù© ÃuðM[ßÚqÒciMÏì“?�š¯�JJÑüŽ5™]KRú9ع#É>ü§^”êùÏoxø .ƒ“Ïféxñi@}¯#´Ðoðáb�oóå[}dó± ÜëA´Þ‡€ 0pôÊ|XÍÓ¿œO?ópvK/|“mçĽü€ ±SÈ'_c>¶[£ƒ޾�ßq¹ Vïâ?ÇN�heÉÊäÕc,ùýÁœž×l'oП-_‡û(AýË–üP¯´N4ä9ua‰ƒËç’8Ý6*}Û“’†„³ãɱÜn¿é™}Öë‡í3î@:ƒ¼ÆwíØ‚§ 97zÅ)ßîpåJMòx�Úš>âÈü¢|Þ±µ®JÂ�;v90ñ¸:>ÉV’qa8½ÈûßÅbûÊaB͸˜àmj°ÞãÃüأڇ󾎄'ì-…íòßˉÿkoìç]bîùÖŠ|ô»s¹sã8LÔàÜæcm˜ÏøàÀN,�üÐ8/ïãÆš*z„_Où=äs)°£|ã…#ç)yØÏ·Â÷•ךéÑ·V⻵°×�k½0ç„Ûqã–ß<Â8F)°¿q³“ßêÍ×5œ3ˆC±¹ŠI¼6gñ7ÁĽ_RZÛN�)_›êM½…ÓP´¶‡xÁkoι bÈ¿±¤ùC»9 â ÏB\ëwçä –µýÍóæÍëÈHXÓl[O 7G‹æQîG’Ï?~øˆ¦¨§ Ž„l6Š*±¿ )°�Ø¿>€ö¥í2jÛvóËéÐÁ7+ιµ_Fê‹.|Ü4¨Iv0;^׈}FV„8VÆé`o¸Y'W"‡cç<"ù_¿=äC2b„ñ̺·©˜n°«q'È‹D9 '·è¿s%ßш]·3è[tzz‘ãŸ/œ‹Ož›.õ@o.V§Ä8XעݲۂÆ:ˆuŽJy×&ëÁvÖ�OŽ8ßò°Þ:&Âá"`ß|¬­-T=â@^×%Fš7.–Ô/ßê7®~ g€Õæµ…³9˜ ³7,':ú ]®éNà´~Æ\l¯ïjšÝ=²m5*þP±8§¡ ‹ÅÅššèßé·{<·n+ >´üã²Ç€/Û‡;Úß³'ÿGOM¿—Ï!¸0 gw× ­•÷d�Í]ö٨׸`ñ»hè‡ K—r0ž>{ûYcÊ Q'¸�F38áÙ…£Òâ;šñE¨õZFð¦4Ç´…ÏùÃÀåuŠÏý‰™®ÔŸóºyn*êúwqØ’›3øcØä3q¤¾<Ä^åK¤ŽP»ÈJ}hÙïÃXÖà6ØÃu?zÙx€ÏyÞ>piîå`^yyÊk¯9è¾R<£‰EÁvR:f»ß‰e1S©x8.ÜwO6ØÝ³7ðâ—‡7ŸÚÙ†=ç~INÍÿô,ççq2ž1Ù`ÿmDÍŠ�–;  ~ã©ëó�)ò&„¢ƒ»^{c<8>µµö£'q|x:T^pûúðaÿ�¿}(g :X§üÎÅ\ÇÉ-›œÉKºbÁe«:µñ‡Š|ØG^þI0q�›;ü6­Ør‹Ý„:`Û¹ßl.e¨Ö©[v»V|@©!|¶ ©× {¢�ñùTÊÆ£…XÆt{­CͶ[OeÂÄžß«ù�<Žè‚(÷íÓ3ðNmpÈžhCÓ:EÁ£gcšÒ¿¢Uìä Iê·*­×kÚä5›ßPô’0°ÉlJYî€LoÝe©[�ðDq%¿Ž7=ö6aze‚ô{I¦Ë[x=`l�r$/9–ç¤7.o ç[¿ ʹ„;Ú÷CÞ¡�–5Çs Ô„}ÿä–;Â0nÏÇ-ŸÖ»F0/ßÎø2˜Òû„9޽G�>ˆGFUF#ßváÆ 8>os‚b:G}ÀÌs«Æ9Oާÿ¶ÚGÒ£ÉXܫ𞥶^;*:@ýrÎÿ¾ñ÷s\ugŠ&À¾‰$–\Ïè�Ǽ�Ùû¹Ö¹w(tÛ0Ö®\/x\¿>GF7Þ76L'½>Ä�”ZÜ0›§7½F?w,43ǦÉ9Žxéè‡'(‚;×yùîiK^9œ`ْƱr™G®í§ÎçßvT v~“ÊÆÈµ²sUNI) ÷Œ»2¯¶ûcÙzœú5Lzwc²É"wjf,õÝó°*|$¹8sè°š§ÅÅ¿kêcP+XÇuo.ÙPâc¼¹ù�š^E-7 Ç—²„n­Ý'·8칇é9–j´ÝÂŽ‡Œy¬éºï*'ã·d¶é¿�ZÑ(�èìº|hBq‘ت‚{½]l⟞ˆUX×+à|JsrÍž§ƒÏ2\Ëý県·ú`†sUxWT„t´�s²zäÆF¾Ó/>û²ÜŸŸ €À«3lÚ; þ¹#廘 Ì|Ø^ÞSh˜à'†õkCÏñ/yçvå!v5œÙMP� ³QkÍÌ�çhÃ$Ç4”jNE^¥/˜Ë{m3rA²^ÎÍ1ŒŸ9 \}Aßµiʹ®½ªVϽPSãÑõÄAƒŽS š{,[׎ãKqãM>“pì¤X�Œ·jõ¥y�§…9µF×=•õä‡Óx§Ä‘^GY‚¹Vâá­?µ¦¦Ï܃^CãXÿ—Éšw­ß{§M^âó@¾ åIô)>ç*ìÍkèÜYÓ/µðÓ“ é=¼ŠCsà Y¾ºËÄ”þÒôÔ©…GúD\N#vƒŽž�Ï> ×z Ì� º€iÊyIMÔÕËæÐ‡[ö;tÇfnâ'M£Õɉµ/œ^Í ¾yÁ^9˜¾†óP“ì†Ùÿ•ÿ+æcK¬îŽxë~@ŸõE†c¦KØV~%Êm8o‹õ9Ùº¹Œ–jpåX'SëÏùDssÌæŠe§!VòS§v>oZ4äÌØùžs_¿cˆ‹ÐÍfE§Íñ™Ïuj/G4^lέ`o8¢ pࣶ°ÿœÉ®AÚ z_|عƒx-,gõœøkßètí:M2Å®¸1®ÁÞ?›E Ǽf!öM7ß Wð.ª],æ9ÈÂ÷šÀXÆöÚ6u“ûHœn¯>t¡g!ù�;^D»ëxÖ¾œì§…ì\‘W@c±¡k>ó5Ùø w˜ã¬éj°ÃÛiUä0²›3Ñ®ãôZ6ò&çíÁåkPS�^ ÂM¹}I‡›ò[cY@³=��id~û�úœ_ðzj�ÉköСW>ýxàgã‹ã[”&Ç;Ë«(±ÆŽ§ú“¯|¥A�±�܇ßè,ŠŠOqº»Fb“kaÁ·gi9uÅ—˜áìA4¤ã%¶m°;8¨XûE‘Wá«mô=|¶‡º6�).yào8�Õüc6è–æÝÞd¢—�hb¹îÖs5h|›ˆíWÏ®(ÃÖ¼IåæL 8ב µžs2^k’7üèl¿Ã¢4$Ê|f¶3ÝŽõ´nç[ñ½:•£_ˆZØÔ…Ôµ”7kU¥DÖÒœ-¨DL­¹ôÂ7K÷�XlF"úŒåäW�P�¿ý»WrÀŸÂíroš)¹ 4-d޲aY§-˜`]Ÿ¸ 3?a\¹b =7&0§[ƒ¢ùƒÏ ðߢ”Ýç¨~h¡ Fj_ÞƒÁˆ^°oàõ�°üy�\ælçƒýÄÛyÁ¢Ú5”]4+÷ „~h`ë`¤ž>—X³¼r£�0ë�ƒtÆäC/ãÜÀä±Ðë hGI`üZ:5ÌåŽÉ{È¥ãœÃ{‚qëžÌÉ3ÄáÄçaÝ6;Æ6\& –µ˜[Ó>4M|5ó¸…×8-{=2ûC7ÈÌzà< J.Å >•)3:¸3à�šl—£ýuŸ[¨àí³q#áœéñ:Þ™k#Æ&juᦣ| ~‡À‡±Õ@P|ÁSnzâ‰ãçá^=žÅµ§�éb½‡zz5¿9†e®@9€Þ5;ùÉíe±¬=ºÐ$á± FîW߲ͣ™8³-øv²éxŽ,�'®bßš…�Ïùµ`½˜åÅ’DYaçz"‰Ï‡�Á¤ÂÖ,{ð𚯹Œöï´$6yøàÑŠ{£çG€¼[;–.Â{Ñò9Ø‹CÓÞçàwœ]ðg¤?Ûi–+�©à÷| bØèª×iT°2‰’%UúàK¢}ø#ŸcW¿¹ÂÍóÒïü~ÄõöaŒ£-Nnö9›¬ÂŸo+Þ‹Ôõëºß�ó‰·©¡ÆŸ\‚‹?ú¬Yùcä8 L]ÓÃ>õDÞŒ�LµíÚÈ–N¯¿ðyýè!Ut4ÜSpÁb #¹°wé}úÎëÝ«UK㙃w´¥^å†4÷�ŸPƒCf‡Çmász²>|Fé@,(j\=ÓŽ2òA˜w:§ÛÁ'Ýœžís áõ9KúS38ÆæôȦÏ0‰âv†uÉ¡t�ãý�ß÷ÞÅŽ¤t«óGíÎG"4.H³÷ëܳwƒƒ[/Ùéþ›Jt$Y5lÆÆmq¬VŸíä¶—ƒ½ÙÉhÜ| ƇWZÖ/È�‘« Xk(=|ø©mÚˆÇNMv›àpn|:°ok5ðé>©À[CzáôaXpùÂÑ�¦T(Ð’Â3rbÇÛðûéÉ«ßkt¾1ÚÐSÒ ÝÌÖLþÙN\ãqL1x—Öf[ k~£bY,ó»ÆûÚ´õ«,„1 gZ2{-ܰKª-bsƒ@È&LÙ÷ÁÇÞüý6�™„Î;¯Ï¾š¤@k\1�7ˆˆDé×ÁÉ ãÁàBŽ'zµE¿�â?½p-ë õ­/&waÁqNðòT÷¶ïÅ�œâ—söáȺËj8|å£%áÀ«cµØô؃'Žåry¬GFc+(qÚ¸—B~IN⯽çµñØÍ¡žMCz•쬓Ÿ­aóãÓ„6ðœ�³8ù�¯¹Á¹�ÏwàHIá0Ö6T’£ÜšÌ‰UÄ ×±%foü“+z›¿1ÀocÑG¾3ÈÛÜŸØÏœÆÃûètN¨¸C·¶-Sê9ù‚yu’�À8ìEðÑþ”ðM4 އCcvôš^Ýö&î`½h�·šÃ¦玀ãƒKŽÝ�0IoýÆ`\¦;ÃIlÚ+;Ú³9=çú¢™7ºÄÄÑø7ìÆPÛ¯® ÖßhkDã®"Éwš Þhº3tèèCfú½ÑÕ]Ï´ ¹½1§Að�‡yd�æ ¼mí‘0ë•gÇ„š½?¸© °)÷h•ÇßBÒ~uà>çÈ|D2Кo mO Ð6z½i3¹’>SÝmr&_0ÉuÖ`Hœ¬Ñá”æÉ9Ê>±$Êyç1`!Ž'ˆ-‡_�Ê"ôVM- wN©&AhzÇá<„”¸ IDAT ²ñ?¹ò¶}À~`=Ì�h¬Ãƒ¥Wøt/äÌs\õ‚Óˆ[ǃã|vCÏŒ’-ü�½æõË.!v~¯?æVü¨N%¢6^X÷FÀãÓÚ¢ôyT|ø©8΃nÓê¼8ê?>4íFNqÛç‚v=„²µI¼ÛkÆÁÍN Š°Úº7Œ×-¡È¹5™5þùÇŸ®;zƒ²W‡ôŒÄÝ›é˜ì·Çåq»Wé6aÒ׬µ+ç¡ÜjéŠàóóê¾R>}`™›Ü]¶9iͲ3´IoXfmÖ½›TÆh¨®D‡B ÓL^â<ˆéÞ±cñì2Ρ«w :š«ÕŒVÁæ<ƒŽòk-ÍÑŒd-+úÈ–-Z&×½of»�3¼D­6\Ö ×�dŒ— Lw~®õ.:°[‹B¬Û¡±ÁË8ÙµX~ì§|lË8òæ'.ƒÌº5MÈZ†#ä’;p: øÄ¼© ¿¼™:”'V ×¢�Ô 6OÝÆ†’›‚¾„_F/’{Ö<îŠ §É/Áí«0½ <ù�„€C/æ—åÆƒjMË¢4>/抟#B�-Ì-k>\LÌÎ'Ø�¨þîóž .2:ÇÌõ KlÑÜzF®™¸Ô–:Œ_ ŽVÁuÎã>;z™¬a}Ä·•Q¤ �ºß?Œf¸ÑÇ¡ó�´�-Ü©-&CœàÚ§ý3b�Ã5؛ٚ»R¢éhi>0âá¶óíëõèõ®¾²tz°æõÁÜWHZ—¼dl¸ûèJ¯>ÿøSåíáíc®·ô­×\ºû|ЉH[¦ž‡n›7ñä=°³8š°ÀeŒ"¾Áòù·H Ä® k÷R†ÓS@g@��ýĺyÁOãà‡C†i¤ÖàB4»cš+º øq>…¾¹Vç�+ÑÄøV'Yß:¡w– ›‡b⻬N>¼ð6°hk³v4¼¢¶'è9G§nrLƒæßj5–¼]ë=�Oh–h†óêà°†»†Moj1:`üÚ¦þ‚mƒ,8~GóŽ,E+'d¥p„߀Ȇî4À ïLÞ"ß’/ÏÄ`ÞE¬9)ô`¸øšòü¥á}¥AENÊ%}ãü¢}` Z;FËU0ÍPn túm+ÇþŠç& �ÙR=àÑ”ñ§g²; 59§ Ã'<ñS,š6šÎÛõ`õ Ö¬Ooì° nîæw¯†Ð\ÖV’qºL Xãƒö„‘'áUl#ô'çPÆÓèõî‘ô†y÷/¡°»ÏI.|8Ð�|Ë=¸Õ–üàèéðko»pbÐÄÐ<žEI†ãŒ•Í':>Çx™klxÏã~�Øj7?±Ú»nó¡M0K�¾´B5;žClÁÝœZi�Ž\ûŽÃô•ûåtˆ²ì\8×윇PÌ’Iqp<~êõ.û�Ñ¡Øsž>ö �?.ޱŸÉtÖó¥AN> lÀl�¹4'ò¼bñÑK%lÂSûÀè`4�ðø¡?£>öÖPrgµ/Ž\g‘У°�cN'öê\÷"£8Ó#ît/D“³!~­“e4±mç˜"¢K®ƒÔ}‘y¶]°ûÜ|`h ü¼OˆtìwŒ·[aeðÐÑ2YuÈ@MXÐùx °öà9qð¸žLé³l¶CÒ<áLí'‚¨3FOÌîîÃAdAßÂwo<6<:S‘Åôý«!Ê9¹Då)«œ=z³m*ž<9§úÖ—l‰I)ƒPš-s˜÷Ã`røC_Ïuø¦Ëþ'ÉåÞXç²$s%¾qäšÈëf”ºTËc@?þ##øþa!µÂWžëRg.Åð µö}þ†Ÿ>Dƒz~f¸ˆ“ã_þg¶,“¡tn_0Á%¤Þ¦î©q%hZÿ��’ÏœÞ'nÜÚ[d‡!j.AŽ�àw­ÀãxÛ´†_‡Ýíï^���p)4�@:A$ò,Ðkò€Ã9.c\Î1åcýÿçAk)ÎÑ0äF¸%nl©Å 1iø\[ Æ,a@¢¤¬öŸ,2�X>Ë=âÃQÒ«n�ƒ™?2ø®MxˆIÏŠó¾8\ œhðÒ[}PÂÿä/òB£�1â0ÄxVÝLÁá'Ø·]kÅ9B¢|k~4Üüì>Gj7,ˆãZœÌðEÞ�ûG=Ù W÷NÆÎfÖ`}מ SŽ? íqeí_ Áùò]YW+ç,ŽñÏäz“ŠŠESsÚ§pãÚŠk�Æ =ü€bÌ P�NZ…/ûtë:‰“ZÓ�(„�¸‹Ãâê,-èb¨�á_ ƉQóÕh¨Ó`s­zîcœ~N‚ü~ýZÎh˹0Ü£Ë$Ó^y©1žÍÉX¨µY|¹§½åü¬Eð\kšè±óÒ’L˜ÔªµÈYû.Ç«78ð¹v¾BÉÃCÞSsî- 캯g@‡ÅííŠÔƵÔ>ßÕÅõgÎ_ð©?Ź‚¬ÆWwpJï`æà†µ4(Þש„ŸsûŘ‹|¸Le:ž¼á3f?óItŸvÜÆ:a‰(Œ„¯6ïot9-ÌSrjƵΡØãƒgv79Øè6ks+‚þ,¯fkwS{½Õk îm¹…Imå+‡mÔÇ!F,äbäˆi÷°Ägè öêÔ&ü ôŠÝ¯ãûÿ}àÖ_ 1>µø¼°ýr¡/ûö ²ÖI¬Þ¿ô�–6n.¸$ì=Räï»YO¹ßá¢\ãÿØû²aÍEÿ|.Bxó,bFŠ8>/Ïa�øó¬vͼ֓q²¤>ç7¶W¯×ÂoÀ‰.ß©‹uûÄn9§}q¹6GŸœo…È9Ã2¹ Y6ö9±á¬Ý˜è;ÈjFµo² – š× ìhaOŒõa<Ä£UýVs² Ñ„#C Vå<Úx·Ëë~ËçÙB“ÏÚWñû\¶‘œõë0lÞ[•ýà²Ø<ŽÍ`EáÑÓÛvÝÎ?w"©K ª�Ó·ÀåÖû'ìÅ�œ¿ø�ÂiÑ‘šÃ-ps›Ë±¹&b_ψ3�`¨|ƒÌžpÅŸ~Ö<íÙ6Ps9Ps¾6§Xf;wDrãµéðñEï¸Ú¸Þ5¥'B»Iri„O±I& ý±«¾¬Sg1ëÊžÔiÝt˜«~Ø—ÿ}Sœs0²åb¿;EÀ9�ÁÇ_�ù�Š}70�e´§äøJ’:›Æ¹¡†r5;®œon8äʇc ´4Ê+=¾i�Ñý—¥Âd.fÓpð]‡QàãyNƒJ½É89|RáC ³ÞTš s³Òýð¼ûádv_Ùðòƒ¹u¥oäÈJ\‚œÙ‹Ò/_¶�qX‰$sï˜5°èØÞ�Ñ5¦"M!.fûSÚ!âP~Î ùÌ+¾]óC3OW÷žœÈ®¿Èĺ¨cq�ÚùFä4¯0Àt÷5ß�ÔCIµ{ú½ÇbÝ3!¨…ŸÅãoö4>½Kn0ùvu%†÷›èÚ‡”¬Í-;<¶ó{©ýrÜ0äÒ‡€`(ãŒrÂã!ñœ·”/ sN{r*9•Ï5HÜy¬R£B\og(szý ÀÞÿßÍMÉs›4gƒ×4QÃzЄßmõ ‘ñ&/�Å€g½¸£@ԬǺsÐŒ½Öm\²pÔÈü$úZS“ŸÃù­oöè�þØXò2¼—!Ìprý$%yHÙô%Hì¤,ÎÚ´�ÏZy-?�Ù9‡P$Çòx«˜Yƒ`¸cËR[©í#�M1Km= ë²[kìóqÝ3ÈÈ-²ñÓ»Ï>û©-øò‘ÞõCHëE^KAjñXÛð€ÑÄÑ~/uÈõ– h0wñyê3ªf;n¸W#¦7QaŽ­‘d­žBa3ŽÝñɨ;Ï�X= Òε2»ÁâÕ1«Êö Ãçdz·>à±vcš%ÆôÙ'«šB‰Šr®#Œspÿð”käæ9ÉšÏá‹ïÕ;ãçŒ K[Zν×òµUÁ�£¶å=l&)�óæšq�|s¡LôüöÒå óz»¶àµËnE¹À`ÃcR§þæ<œå¾çºœN²¸p;FñÓᘧV§¿“¦žœ'tý,Ø\ãd~øLñ„¤¾_X´Ù§‰¿� öø¸9}@‡Hxe±Ìx8gú›Ùùèõx…wͱ˱µæÕ‚&ûÔa�Zc·µš±�Ó½6˽¾ˆ%dùã…Ë­Ù!Õݹ݀›ëè¢ÁkxöÌ,u·é°lÈâlÕ†Øg€)•gõÃö0šã Ïó­"}L¢‘Ÿµ%TƧ$!#ó8Ï~uõsôÚÖš>¾èÔ&3[ÈØw¼‰Y¿{CøÄ5aTb¡&œO¸òp²‰ïáRÌlã¹–›p¶pܼùÚ¶öm3M¸Z�Ç. 8¤Û-O?àÃÿ�Ùžf3Ø'G<ÔÏÞ¶8„I_v©Ó(sýŽs�×;„3uÙ¶aü³ñpû¾Û¿1.¾575ùf]9M.ª�÷Exr08Ú'l0b~áR­æcWrõ�{d�íCùñìE–Øv$?œ»[LÌÆP ÃyXœØÚ¬MÆ“ P´ ÇkMá÷6‡¼õˆ¢¹��ðébÆ�ÝonÀ G@‡ã´_йž9\helØjŸƒL®-ç09ß¾€ÄЬS7È89ÀâÍ�Å÷à¼#;3ïX¦ÿÅ8q' íð]ÝPœëÜŠ`©\Ic‡_<Öì)ØøbH¢Û{Þ€Æêîù¸xò³ËãÀ/Ä,�Ÿ…'jSKm�Î5 XsÃp[–¾Ú†¿šrÝYŒ*‡PëÈ7<P>¿óÛbcV¡1Öu‡±¼åÈV›™kw fÙ5™'‹PD_4LOÚ–ÇÒæ› é§b lÙ’ƒ˜ô9\¶IÌ`¶¢‰$o¨×ÞÖhŽ0ú()vg<ßNO¬hÈœØÓSbÀ@Ǿie›ž h °YŸyxÌàF¤M¤&7î8�ï©Õ�гóÉç7 y3µ8¨qOc[aæ�ƒõ àC;�© ?cçャvrº¿èå&">XK,üØ£éèb¯; ˆ16eÿÐŽ×1i�‰q\hÌÃõÀLQN$»f×Y`7ž96.!­-œ±ñE*RVj܇åŽÇœ$éM5¹É|°·ÿyF¿™Ø\ŠŠÆWY…KCy(Iþ0ËÌ?æWÎÆA÷Ó—ÖL$z=+ÆÒÊ;}!hþÖhNغ'îÓWÄ8ðžG°–Áì8ö¹ùCElŒêÞ¢ªi>×é Qì黓PWj ¬9ÏQ€‡¢ë°87z ûG‚ãIcÝåcùP´¿»jTøPž]*ÖF÷A ëhüàûo»ukÛÖàX“Ë<��Dllš?Ѿ»ÔDƒ;Ë’Ôñ˜(hì»cñ‡52ð˜ö¨¸Îu߇ö„BEÌ;\¿y!ä'· ƒO_ÒwC‘(�ùçyn[ïpùº£Ž&¼9ñ:xôÙ ¯µÿøW#øäÔOx‚F“Z}ó`×ÅÊØ”¦a]?•ú¼qaÅ6×|I kÕº¯Uá±úýúH’NÃæ$~G ø‘u^o³Ñ`êR+‹Ïû,äé¹`eÔ¥i åzíáÜ\ã'^v §Z/¤�õÝœÔqcÆx9Pr{Q»å…Ã~×"Ÿ…`ÑG˜`ŠŒ÷(×ÅÕ|ŸëÐ>®q û#6ÿl 7fôË}öîPpøvG2ç,#ö³•yÂGOû­f@"Ÿßñ—&t݃ñùh–MÓvö,ˆ±L-˜#ÙñIù™äÖY¼'ò3lx¼³?×øjZ¾ÔªñÔ×T^ ä¸êZŠ\o¹ö g€· ñ-Їux ó�¿y™Ã#Œ×áž›[ Í夿[_6›ˆ!Š;9):?ÍGƒÄúæ9±ÁR×7GíŸnÍE.ÈÞÚ´8ZÈ{r·"é‹´XÊŸF¯LþØO‹R÷ò¢ Žæaë¾ÔÏÚÙ ·~§Çál4Xs—qy£»vxÄwjx¼‹$žµùØl 0-Íõê7Ôº“¦ûçy- ÌÌ Ãí'h{ +,…æ"Oa4IÊäØ b‡ìˆ¬Pó('pýd<¾ÙöõHx—�ùƒ§á!ªÙÖX¸Ÿõ4>D— =醿 ÷BKjàfžöêÇÉÓ“ár-·1Š;¼Z®G€#At•¯Ý�eŽžÇo,,p™ NÝxqÀ[4·±ò*€›ƒuôZ>¿‘Un4!a¹ØLçÈñ“{öÌÙc?ºXwX¹¯`y²�ž!߀êév’Ï9´c½}#fãü»­àäsºï¾×È6¦ä0&‡åu쩹`A🧠i/˜ˆñÖ…»'åHïòø"UxãËSkj=iƒžfâ3Ö÷hy_B]ütÕ#y¬ËdÚ„¬‡&×é=çjUG ~ûº£×„XKC“7_`žXaVC³¸7ØO=áâqEN?Æpèg,æ1Gââs/Ñ –™øÈ©((x É�>éæšÌ•Ð¸AuTø tñÇTC–¾W+ûÕsz*Ϋ*}w¸² æJpM®‹Œ}S{óF×›ƒÄ–ßzˆån$ ð`Ï:ßÌÞùÂåþ½‰£ê¾°†bÚäúܳ}bšSœÎëR¤‚>‹W‹'È¿±sVÛ>DÀ}û,n¸lÓcg1¶è0>ÙW¥ûŠý»˜�ÙÊ�eׇk0wôš”8y ç\ÛàØ?ÿü‡óçqsŸÐôç®%‘ìñOЛË$t1?þ@”Ì`Þ\îKíYç¶ÔsöÃöÇñÇŸù.øù²ýI… Yù$¾¡^/Wxòú.|çÀ,柳¼»¿ ƒ�¼»v½Ÿ�ß;è�Ûø%œËOr^¦&ÞTDÈz‡ß¾/Î}ëãÅÁtŽÆ8Ié=K9·Ëz²X:;�æüÌ!�ìÜàzôæš%3ØÏÇÍó œ<iþ~�áþ˾–šC\Ñ·tØÉúŽœ/yñq—äŸ0òFó"׫q²§Z×0)MF†s“àÄ}[Zìý<AŽåfÎ7Á‚ƒ+|yý€ÕºÐÓ1î£> åÅú_zNÏï û8OŠˆN²*-` îò“f:“+¾¼F‹“ UØÏH¢Ã=¼&Òã[6~ïœÜFqÈcäl£ÈvT'�g?üúÌÎéÜ:ýu° :™ðÓ~SRÉ=Ït'½Ÿ%oNx÷˜sÓ Ïì˜j "g™ž±1&/Jb‹1ô’|ýõ~=ôöÁÚþ›€Ô\+—=O÷åh¾MÖE÷xôùx|dü¬KßžýÇŸ:ßù6.t½ÒN}眢Í{ž?ž3㬠Ë=Þ´±?“Ã1�Šlwã¾]Œéw î¿þ#¯‡^�î EËOŠ]_Ù4oZãÚe‘ë€Ùf<ùg:³}ì¢suÍO^Îw¾Ý›Ç5˜�‡hš>ÍðU «Sû›»ÆÎ}wšòXK`ººÀ…ýγaÉë!ászE]éúÐs”åÅ¢ãßh•‡¨ô?ñæSð#)˜qÉ&þ\«Ý\àˆ÷c‰yÍ6Ÿc+î]fp¿©jïº}rQž¡o.k1êæ·Fðp26{Û´Ä-[µ��¯Ñî‰q:üÖ?p¶wöÍ §e6úó˜g‹szƒ�ÛmÖY�Ã;Þ ªâwmçßN­ˆ{ó4„Çv¿Îpls­ñšY÷£Gþ¿ÝÛA¤ðºûqX^åOtøÞ\y~älþrq¾yìpMòZ��XöÍðƒ%ߣ?ɘºÉùáðE9„õocÚ~óÙ&Íþ\Céö`ù¾càâCõùO Oïÿ9ÞX¯é>#u/ï#|bt€{Œ\߉:kåç}müßÿ¯ÿ'¬Jà†Ê:q!zT‰%W‰…ãp.© àÇý„Þ ÑAÁšÑôŽeó$Ø5h“g¯œlLW<>çöâçdèb”‰_8†_ëAêèÿu. $ü^¿IIs éRøõù¸—®\Þ¾úÍ9ýc”±öž6(”Å,µùAß È;Ùi‹ Í9`¤Gø‰Ý/ãØ~9†Ñ&wïOžáÃOvr×>ØßÍä°T–ê=÷ 03v-ä*É~’ƒˆ†Åc›?¶ö{zäÊcäÃÜMÛáüyR}+×lß‹Ÿ=×%�«èÛŒ¾ŸØhŸý�‰g¸_¿pÆ{�î£ñSÞÞâk¿î«É)œ¨1šý‘òüä]Ä÷9!Ä>'ì92)뼘d›ú¬Äü«ƒèéLŽŸùóxH¬ñ�ÆÅ`ßøÖ¿ø�Ÿï}Ä¡C¹G¢yxŒ{.=¶÷.]:œš«ùìËm^ñ|÷‡xîþ¥-잣Ì+ô¾µð׿þñ$ß7DXŸ�6ñä ÈÍN_Þ~;—ë@Œpúñï�„ŸzàÊ_e÷�y>¸üS¿¸ùjÊsÁ{ÍM_ ¥81¯ M;�Û“nÆ‹›}x'oo¡ Æš ‡ô6¾¬…>_yc÷ÃÅ~õâÉ|Æå¼†ØHŸ‡èÎ G8ßùÎãæ³'‡pÉÕ�Š»µ'×öqçñsÊB“{i/ô¢�Øsí¼çC/ºrM’#½�<±ÑñRëzÁ÷ð[—°5ãªàdåœ}Ì6ÖÓp>Aaå<;¿äŠéçºÔ~Úö»ÊÂÉA¦æs Ì�³úš‡L—]rX=þÀ–ø[ŒƒÑöÇû«#toö{óÈîǾxà7æ¥/­ “‡L¨…³©êÈ~›ñoÿ>F\ŠÌÓdЇt¦+)ýäB�ü\/Õ¸kÿô]ΣQ1ù€›r–�µÞ€P…8_X};|®‘Ç©¥ÿu oʤÕÉdÛ‡™¨Üuµ¨*.´µjšNt0†[œ‘­ûõ9ƒ”¡ó"Üz�u®ëõÒäÂÿVÏÉ·™ë~�„Ÿ8îû�¡ÍïzK&·ÏçÖe½éë{ ¿�[n-© Û{.Þõ‹g½ñw5:aîÃå%.1OSe›¶¿ã[¾õ{{fZI*bù}º~¼˜¿][cO®¹vMýÑDäqÄ=ð·þõPê¬ëèWl²æ8‚7þ·ØáÎ|ôÓO¦´BD IDATFÎûx¬µ×Øú´9øœ›ág3“¤�~s®íÛ#¸ñ¯–[+Ž) 2ùR}<Öˆ³d¯›€iñiÏþ;ÿ‹9ù´ˆ zój�΃³üÔ0ŸŠ3Ç�ÿÿ3 ä˹¾ØØßʯïïV'F‹hÂò9Î5%óô®^�«ù3ÊMý4}íÖ[N hò›Ÿêd`=}„fÞääqÒóVwÿ\ÀèLŸ–vœÎfš�ã_jF�nðï÷ŠQ1%¶W°LßsƒZ©­a°”´]kÏö­ËÛ£uÄ©'ÎEª¤±ï±=<ëÉ~·Es=zºû1 v®cõ‰Ÿµ¡í•¡\Jä~úÄ=LvCpšs±ƒ¶G'ß4.ÑwÝÄ•+Kmœ[ç”o¾qË‘ˆTá‹éÆÈÉûøf£X_´þ”WåöÅÛD_E+8Ò|±jiQVž7.z¬¤î/Gx8î/`܉ƒ§µ[Ÿq|ÊПåù�·ß(ÇwU¾>ðdLý¯ô¥žÔÆ©wwNìôí¢y{è`ðÒèºÕÇûâ/Þh½kV—#öÏãú°yúù ýµ¿_�g{¾Õ²ó­øóÀ-½÷¶×àø{wèX~Ô,Þ¾tÏ+;c·yçv�Æèεñ/þš\xΗô„亹ŸðÇó?<×õH ÿ‡Ýùz}HŸ¿Aà>âàC®ÝÛƒhºûW�¯÷ì±=5ÝkÖˆÑÔO�Üó'&犜Srø1¦ùýk|Ó �)¤åÕô®�ÿ9üêÉÎM;ôÁ»ð×ùÕK?hÜ/Eúp4¾Úžz§ã{V s/'óÍ+‚ï¾HOIÜŸü²²ö_½9ßý r}&¾×òËIÜê3µPßrnæZclŸçj·¤ÌéEªJï8;w ÙÉ~®#¼ù ùæç|û9]¯3øð2á´Î×^ï\,÷øÏ¬:üÁÍ“ßrmƶš7�óc$`ýðm=vÜËrb¢q´±¶å9G Æ`F_c?òÊfŸ!y}ê ¼„ží�k:˜¥sÿÒ`¯�;ùXþŒÇ*{_;íÌý¨#0Ç{ùè]ýÓk>‰�}õ¢8¯3ò;|¹( ìð¿Íãô¬ƒûÑ9àɲ×à@2âùQ9ñ5n±ÿÆ7„dóóÐÃ1]ÉÂ9Ižý>ßcÑ|­ Îõœµ‡8IùPׇó,Ç«}Zÿзø‰çq Îv¬‰jáW}‹eÏaľ,cZ‡1ßëõ{r)J?ãâœøšä5¯ÛHaâLÙ¦�æ~ü‡“Fuäy$:çg>šÁRÇÓÐ�ÜǦZ}¾µæuÆoã­ó­ìêNßeXnËèïŠÚ¨Äêu8ç ˳þÀí�>îežKv `þî 6‚nëj¼ÓΑ¯Yçw– xWæŠúôâë5k±ø>;²cÛïš—2º#±Ê}:t  ?í¹×øµ¹ŽGßwMlÏ<.4Zïo©]¾açvùz ÈŽðË>Ò±˜³À?‡®5žøœÝOm}>”ÎüeZ˜§gëÍP  ç²ZH³´d÷Õý#Ò9 üÍÛçTÔÜÁsƒÇ7ÁdŸ|}®<¡Y¸¾åõú�¡ž àÿЗª<ìËyêzR­ßù?j›‘½¸7‡¹›lœ„­vúóç?xSË-Ÿo)}¼àÜÛÎP^[>LpǰÚEó/1Æ>‡hnœðO�s¾õÄýÿþ¡i¸Wçk[/Þ2þ[ u8É>§ó½¸"~N‹á ý§?ÿñOý3�>‰ë:Àí^4I/�X}­*ùòÛÊ6�G‚áÅ~™ qOýá"†µë‹o¹6'V¿XôB�‘U¨i}þíCbsœÿØû^[Ç>am,2Ó‘¬N¹Y扎^êŤêÎ-z¡ö1nüÛ—«kþ� nðu8€ÜWÇ\HvM&«›­`ü¸’�7µ¼˜ÈóÐp .–ÝÓf›ßžDKÓÝ s½bjËÜÝe±L9¢+�;þùO×øzì¸úÕBpåLƒ] ï¹Y¿ò8®«>vʸ’ìiI\ oâx%Ã�Ë=Íò~ÀGˆ~ð"(¿´ó\¹¯ç#“Áï8³žÕ bÓqúƒêymú·PÙsýQCÎGôÝ€ô¥9dþÏ•=ß‹}u�|¯i_¥Û¹±_Æmñô1 (>Æå‹Îícüj¤w{ã?¤Á}ÆË*³ûÆìoˆä:òùƒ¸q¬lÛ8Í¢†óž´…�?ÀðAŠúÒx<`¹.ù½“æÿÆ< PPâšæ�ËÞœà®v»°GnˆN x@�êçÍ�üÿü§4 ó¯¿ô{ç©Ñx¦½µcr­$}ÊÀ¾\ëSÞ„p�;7G›]O=Í]¢tT<ÏC<¾“�€‰�vÏ)´}Rçç`Y„øRÙP¾3©æò�ʭħØåš„]çÿüçÿ*Àþ·ÿw=}åpÝ72ôá£ÍñÍm-Â/—ù¢Ð<³ƒ‹Ïf ŸNßðå5½tÀÚνiœìæSÖÌ€•É\‚¬_^bC ÇŲf¬NÇ[T25½½ÎäãõPž+ó!¥ë<±á†»/E‘d¾lø–+cš¬Å¾Ú•s<@±"1±ÌÁáqÍzÜó>‚Áë¡kãXGg€a{z€B“cîs‡„…b9-àµ�{ÚãK.·ÓhDïßIªV?vxãíö�ç)ƒH*ðz²pE‡de°sýØ3¼w��Ó >ýë9 GÁ9oé#1âÑ5‰•×f•y=ß|ùGF,c51VúÀÞùÀem9߯-ü;F]â‰×lüAã¼þ}øÂ“äËÝ� ó Y=WkERyá7 ãú¶mO|^ÿúwÎæuFÊøKŸ�gM¢V�¯~•}|Ñ0ßm¶�ÍÒ”+þ/7ïÉÈõ—ž+ÏI ØGòî[¿ïù²œ“äÖ —ëq±ÚI{~~Óü›Í¡–š¾ø�%¼FWy.zÇ=?•ÿáÔ¦%ä‘Ü]÷«Éa-ƒ‰úÂÍ::Þùjl�}BhLDÔ\æï!çòµÜõÉYáÓyÓÞžZÎW¯}þy.Àþ¡çJ^+ýõïÿo(O׬C|Hz])Ví›p½¨Ë>Ò2NO!1¾Äëã€öðp /ŸÛäÃó“S÷ƒ¸ç„ºŸÚ�É×›ïaÞÕ°Ä[‹•ºx·ôp·üªƒ˜*Çþ°|´î ?÷¼^�ñí Ö�:¨/F£ã©Ù¾ê4¬Úl×aõåý­úæÏ]òáõ0Ì>Wàùœl9kÏW@1$4cmÖŽßY‡ìÌ?Ѷ¸ÈúÖ]/¹OTsM¶ýÅ|¸5kT>!Ýx G›û‘Ó­Anê`ç¸f³ý)›=QÃOßâ˜Éæ®é> œ˜«/\a}Y´>$×~p¦ÔÁõÅ]Wî~‰›Jìô ó¯b>·äÔ-­~mà ëÝl`g=SÄœ>¬Æ!s¼ 4ã0ãOÿ‰�§Øcs·¿MëäF7Ü®3Ò¬7Z$‰ FöñÁ�8ŒüP€�žö&Ǽr-ïѺ˜ú†sÌpöuëŠeº›—üë_¯|>;Åœ:ʵº�vÙ×_—µîî³s`cŸž»}ƱjOYiXk›ÕILÔµ/WâVkÎù!½áæhé¸ua¾ÚÐC ›_ß�1Ù9€w"ÍÑ¡î‰`ýÚú³ÇÔ³ëó=g¥5' Máb�ÁN©FûpËón&p÷ÙàÁ¾[_ôœžÒ/ß©o±›…= èŒÝz»=ÕÏ ÎWßH:cÃǯaÙìn{âÒ‹„À™oÒiu’N€sŠcßà ØÌý yð).|ìz^äã#î³ðíE4g�8HÏÃï%÷¶úÒËpì*š(‹g˜u7fÀòZìÖšù�+ëèÇf²Ìã€sÐ zÞd �áçƒýéu'H~‹f|¤,ÓbÒcøÃl8Ûœû꣇|Øú¾)&Å~·Μ·S†À¶U—×¢Oö|〰£qñ…ãàÇÃy\oxcÒ9z®1š�GY3ÁÍ€Š¾­ƦÛrÃç»&(èâïãÄç‚77¦D@Ær»ÎñÕïz†Õln‚§q´´ðôJ�?Ÿ>›CèÖCì°)Wýåüñ{qM„_NüÌ?®²Ç)Þ¼q;œõ9Î`S¿9©A�>iÙÖÚVNGkÅ ?Pî¸I‚´dX¿c„¿{AÃÀâgýÌl‰±ý‚Á¸÷;¨ˆôõ&6 öaÿjþN.ò.7×;�#z[4Á˜~ØnŸ„�>ÈZ´-¬íôyãZ`¸_šý8�»¹o¯ƒãÈ9#çÓSŒV.󭎤0fy¬êØáÉ;ø‡=ú 9A6GF�cq»âæškÜ4á«øýÞ%ßqkqw±N—‡±æ� ¿•hÆSF4FØã\í*&�?þ€éxÁÀøÖ2NOdM°›M³Kn~ÇÛ€¦ §Ž�‹/y/üO 'zyá(Íñ±È5†çæYÍ΢„©¶õÆDÍÍó'}c$¯^c«§3;Ýùyê½ •ùyt¼p«?8õ¶lcçqzÉë�'ÎùŠNÉî-u†ª×‰âÉå|§l¨�#>6¬gc!|ïhLØ$>õh‡ ³ þ½t #6¡{¿HìyŠåÕcÉ õõà:iëæ÷ø�rlü»Fn %v×’ö“ «×:ÈL¿Õ÷’x§®�˜¶Bóý]ÎwÅÇšN¢ù=YÇË®rœƒ<ô޽9\'Ïgž£:ëùçÞâvæ�‚Ç>ƒ 2×ú•˜ 1lŒ?¹1Iñ Ÿ»fçì:¹ àŒâd£w‰M/ ÷Ñ\ ‹�3ZË£‰€.Çá’½ÒI"ø€pƒžº¯2¥ï2à¾SdC÷=;ؼ`éùýùòÃüÖFÿª¦�¼ÎLaæõ˜]^Ã\Œæ×o�ø8?iî`Í÷熠tÆåzßop�½îäxÇ?öá¶>s½× õ(¿¶A&Í{ ŠZØGá—,߃Å�D›ƒi%âI^b7¦É{™o¿õ5d}´&}4NûчfHyǾ÷âæÕ“î›j7a¸†£Ò2°ñÀæGR�N§§Úæ3ï„þ© .b=ˆÕc…â{ýF­ Œ—eµ<¥ô4Ûðí² ™×HàÖrßöA þpZ;uÅàcÿÉéÊA²?¸—c AÛþäe;¼á;ÍÂg4�6öé”—¦�€"謹¡OB'áé0Ùæ§¬Àa­ù‰7-iÊŸ½™Î¶F ÅÚ^ì³&*‘1z­“›¤XƸðÙ"-in#™zX­@©-þ4¿gê�ß»òÇãD:uÀÁRðäš»=$1€x0æIʬ•õÃÙöš ¥´ßfЬ<5€#~Z˜‡!�í‘g ±â¹^Ò}ù‡ ¡÷«–‡¹Ô ��p“‹~܇¾Aúo Çú„zþÎŽkJDaùe4æ9�cõ“qÃׇk„î¿}(ûz¸¸ÍUßm8¨Ä9[“cÑ«ƒÌ,o¦‡ &ëÁtYSÝÑ`R"n$´DÒX=H>ÿÀâý°&µa×wâŸÍc–¯…ÙÏZÞÖÃMðfh½7°6Èag0àý—g¢ÝzôÝE®PÀðÎN$ƒY6ç0ÈVÒÓc÷'�A-7'¯“õ7ˆõHyd±tÿPt0œóõTöh�ßZdYo6;F'çÈx†‹È’@ßâàß±òŸëÏ¥€fûr–Šù sVj$'É>Ð ?éïß�¶ðÞSàsoÔeõk"(Ïú¶{}$áJ+Ûå¹¢õ X_dÉ�¦®˜ÇýaÄm;¡6¥\/ûDh»}yýÆ~úèk±ØˆÚÙqf{èÃ�пz¦5:ÈÒQޤ1 ezÀör-ÿ«aú’^™ô>m±ìûZØ[«É§²u~[Ó»:¹f¢ùÒ+ŵ8–{oCkßy�zÛkaß×÷²åÿH"Ø>œq8ÿ’?që :½†’×:ckCT:\Ñêª=Æp÷Fý‹½BÅí¾ÈŸç�f†Ts0e\¹]Š,ê^0™ç½ ÓhŠq)99~â’R;x� c¡‡5X�ÃË×Ï01ÜðæC+pÕ×�äTL|}¢Ê=à—s¨ Ï“Aé†EçjFÆêð¬×Áü„ ÕŒ1‚Ç oÐ!snˆ± dNN¬ýÈdTO×°&nŒÖæÐ¶ÍiÃL‘0HÒ—ÿÓ­£ŸF…öùa�dQN®Ñ,èN>Ïu]6þ½ˆÁE¼q Š5¿b\&¬k.lpQx¸¾ ¯ð×ì¹§’3±naÄ@>»Â ýú�B`Tuú §º ð [ìñpÀõïË“kŸ{å©Û+÷NM踽�²ð£uÎ6’\Ⴣ#õ€êUI N!!õäáû@\ÄG4;í÷a›ì—ß@»ÃÎq Öf×d÷}46&QátÚ’÷»\¾Ò¿>çu\�ÖéÝVï}€£ý[Ë­�(ȱûdùHÃÚé´¾^%Äc ßbLÉ©±Ùï^ª�)�q#ýWC¯³Hv=¢í7ñô˜kLiPwš1=œ«œ;…{º×cZнàÙ1(–~’ KÕ N_6&‘~¾álÂ[»±­sé4\HÁÀNòŽg‰%÷¹³ÿŽ>ŒÁ|zâ¸[±ï5$þÝCã´gßÁò  0}ì ]’Ù]¯pÎÍ5h°〕‡%œã'‡ÇpJ]p:å�ŸÍr²v?.�òjŸLñO[’·—ÏD¥ûÀ<ú¦— ðev^­©lcu¼šæeî:;zšÿøÀÿ®GõüÓ%jÔzV±Ž8x¯å¯Iƒp ÂüçyûŠÅ|¥ŸSÆwMóùÁÍW¯hùר‡!\·ù»¿<)�yCû7åÌ›ÿWßà ߋCîÜ:_6ßHÝúærEÊF|êd�­ÀÃÎúŒ74™ÆI»ÌçsyaÅÑQÚìlþú\‡Æú‘'ÅO¨m¥nú‹‡sõïÃæcœ‹‰x¬áEÄi¬.c[wy¸¶ŒèŸNáevOã6Æ‘ë£,hŠ–hšFÀ©7¹¼—®p�â¸oÔaÞsªÃÚËÖÐmG‡¾àð''÷™v®#N˱ ls0�Çó°¼ äº¸gàt`[y1ÛoÑ�Zùùº¡˜·_¶™àÊHŽŽiÏ7PɈWæ}C†t×O®7¯{ȧ1©ÿ~óþ´}½¾B³ɯ³b›N¹fÕlšžZýŸ± ç?�*CbW²=ÑŽû®þÔÁµ–Ÿpã¹~ àÇØdÑýÁ–>7´Ö`xt6M³¸¯�Sûx<óáShÌA<ôMa]ï=~êˆÔ1Ød6Çn X`w ` ãdp0|°…yÃx¼ðÊNŒŽðfíg˜Nã\�Ãûr»>pг^¸ÑÆ.Þ4h놬ˆk€âû~“O®O'Ï;Æj¹¿¾%Ou¸ŠðA|†¹¼�í[&Kâ†ßg…²f´fÓ„ø_˜tÄXöø¥Éùì…škϼM?rbÙm†Ôý`6 Ø£Ó‡�/@¶1,¬)ÎËùÙîƒ5×Éÿ¹·ùG�Ömârã²û«›xÉnþj°ý=9P�Þ³V&¿ù��úq­Ï�c¡@ð÷)Øô­hÙwÿ‚†?ÿ95~˜¨�ã¤y¶Õ|ÿ¹ÖrzîsRöµí¾�v’ÿæÇî<„ÐÇ�‘�C6Û½ç¤ÑixëšNù\…ŽŽ5�q[„©›/9‚9Px”®/À0œ³ëHKïÜ«jø M‡2 §Öây‰(~ë�3û]?ê‰å¹o²£o½Oö`cÐb\õ¥K/¹ïõ  ;‘¿Z#Oq¼N•Ë.aýŸ ;,ù¡HD::a'öôûâäyÅ…òÖÞ&^ž%285d·.ö:üW8cÇWLêqDO‰7= ‡çZd¯ø–‡šµkìáO~ÒÏ,˜Ød'Gã û(p4Ÿ²…)Ï×öÊZú¡¿aé™ûØÉlÏÍİ!=¼=â·Ç×ÛŒþÔÁ=rúl}Z ®vy±Ýu 뎘¨Êó4ÑÑ’ñv.ó9�VD}y·6Ä#%2¤‡!ñžý 募iì’ÍAìcƒëÓÚt¡±xý-¦*êÓß{´ÈáfL³7>aÏqzy¸(fžàÂß=±Ñ„þâ7½{­§andzúñ}lÎ¥ˆ7 ¸1[£¬�³úmÇF/šyl;ŒìÓŠßkAÏVí{‘�Eg@sפc½z‡ö,»?&ßZ6ëdÝ"@2‡ÆéÉVç:¶aÄëëRx y£†5‹œ�‡Ó{è Þ zÀçš7‡øzm?:vO€+ÑQ´GÅZ£|qpºžæ,ËM¹Ö%]y‡®h .»crüô‹€òù¨í»ž¿sž`×m½ÇşȳÑi25�éê+„‰šF;.æÔZªDš{­ä0ðŸI=`Û˜ÌU`Yä ¾3n3æµlÂcÊù8†aíÃÇ={ÑÃ?Ð^"MØâ­M!<î„"´ýÀQ[öh.ö¤È@l{ØçkÌJ$îgHÈb^lÀ¿l„=§ µhžÜ¶iN­ÁE\kÇŠ»6ݧ>€àj6F<뜙M@G¹öÛ;L΋CÇÅÃñî�öÀÜÖúò tkÌòQÇú˜°€Ì ã3¶e2 ±%ÖTel€öÙj¾Ý«¨ý‚sÝ5Î2B‹¬ÇO†€s µ•)V1ëÍÔ‹ Tv�9™Ëg3Ψpr†›á™Ó ZÿÜ7²ñ äŸ6:¿œ—CÉÇžÞ+(¥ÈÙ¹bŸV›mŒå|ôö}!}þ°\Ùô³¨D#ÙCD z¿É2R‘øžpA€ø¢ÏÍ8<³¹>ù/O"áàõ`�Áogß#"=M~ÄMëT$§¢ë[mh‡†OéCò13R…¹œË|©süæà�ƒ¯…‰™·3éWOûuÏ'¥Úh ÉŒ1±L>§5®j±õê"Ïo¸†ò^|~®´MÌŽKÑÙ {‰“ßú‹#ïÕImØ…ï„û—wœ€ž1M�É\Øátzª‡±„7>òMÝ–üÒâûe–MÙòkvò8p§w'ÀéÆ�]¹Ç-ˈŸN¨çw¶„ÊZçööêò÷HRN0ns+;1 ¸Fnž8Ü«'6.®5×þ‹_(ÆØ™×rÅN*bù"% ðɃMV‘ÅgÀsêõ"Š ÿÒ(Ë“?ÍÌc¢{­D«ÃIu™jŒT™Ÿ¹©´ß»¿ðoaÃ0ç#¹“3÷"»ÊOYeÎ~O" ÓkŽ%9•@ƒþ샞õÖ=[2aÜ‘Ðv)Ó>˜yZã73'ëó§�~çh8ÿr´GMå\Öá°ÞqÚdй’ ³Ö ó/fnúÍOл×öv ã¹8MŽú¹X4:eÙ{ÒSLŠu¹ìŠÍ¾ÜÂÿèûÃwuËÎ:ºÊ? ¸·&^ö|ˆYæÇ=!Äi$¥Ž�íÖ2Oo8?n#ËëÀ!Yö:†øòjr’´F9eôkÓ`‡'Æ<×݃bà·Ggÿ{Oã{A{?B|~ìÔj¼æqR›mø!ÔX¼íÚƒ=›V‹Å?ÌOÉÛhöR'òŒÇ9^}M|~¦‚à3–÷1QP¸«~/†¸÷1fø¯fç‹'š›�¦u,.çiD¯÷2ìgB,?ý øð­�ýÌg¾æLl”ýå°MAC9•ÿk��<:W¬1¸Ñ*Ö1µ°ôõóK X}ù§À,(´DN&ÓùÉ?»/"X iŸåf‚7s<<À#¢âqžÍ²Ã˱üÉš§:óxÁz‹oiu¤Ócëñ ½üÛoöo+ùwú˜}ñ—N‹Ï&´kèÍuAÜTÒ 'ʆW%Ù oŸjdpFs´7Gë÷51jÈÔìþC5ï¥yè×ÔõöŽ]�IN°‰›Uèœko6?l{n�"Ì7žÄ@ëÁlćlÄ„_K×µY¦Õ‰ÛÎ7—¹sO9ßr‘GÃüÌÞpê@j¹èáqboì žk7=~öÏXŸæø«{:®5�}ZÃ� =æ×Þ0l­Ë!p"ä ø«Ç<ŸÏ ã¨s»ÌÄÍ„æ£. ˜ó OŽ�ƒf|7^ »}ž-Öö×»Žß¸ÓyUˆ&¸x˜ë„Ô£}q=vY©•q´Zsͬo>#ÞÓ]UÇ'?�$Ègz —ÇéôڹɴS†GR°¢‘ tY[1™zÝäó¡ãzéhb±C£mÌ‹E ó6l1:è[‡$þ®ý¦¨0ô”Ís í§sé[—©Aõ¡\ÿÒ¿xÕ"ÿ©­O:ÍN1ؘ7æs½r˜] póacЧ<Ýqƒ—Ÿº)Dö±d­ƒ<šöÃeþrÎGÐ~Ÿ b#š>Ù¯'A9KèlŒµÇôeÉ -w·zeŒü ð57_xá>É]WÉgä†Ó5»ðm…Üœ¥,®�þuÝB�$_>¸²Ó±‰OÙu£‡6ëÇ;»^ƒÒËdRºú€h?º'J¾>y¶˜DFWR‚ÍTrK/q|ËRB–€wmMÅ_ÎÖ†>ŽÕò—à×>\ž?Ú˜ÊZÓc Ot£¹²l_êq_«%Ò/ÙxiÛ ÆðŽýÙJÁåÎ&p™¯”Ä-WØÂ>Ûr¿¶„#èà¸"ªËáçZí`«¾É†_·&v k9üæ{.ƒÎ0 ó굡Ïgßí�Ñ AÚ²™�èQY�#(Øy’ï®gÍĺ€îI †4žM2g ÎomªØØhˆD�½€ƒÞd®V?è>áY¦1ýž©/XG7ÌAN�"ÐJn&ëf°WJ²šÂÿQ›Üäs °Z舶pîZ†ßI�+<ªÕ×�l‰K>$a˹’ŒÙ =Ó¼û$óû ¯îUÒX¸µjÿé’6íáelö—¾pºÆ0g �ýœÔÆ 8ãõµf‘{¡õß×7™4@‹#‰ƒ·�Óc7N$èÔÎr{ç³7÷Sh£wßCµ6SZ³§ªhšÿRu!û\„® ˜é¥ös0Þëë-J't[`îÅÛˈ>,¯mH‚µ~ qa\óçŽñÍg^jšNCÒÇ‘{\pƒeš3Ûž‹‹ŽÜ¿3 LïǪü®�ýo~~ãc‡ëF¯õAßâ]3û‡ ¢Áú9'ŸÙ†¾á '<±Ñ£ø/þgÀ{êÎA 7G^ÒÓzeßu:ûøføJ®/fY4×<Õr}œ¶Í„>1©YÌ.^ÀlÓ¿æ>~0ä‹sÌ“˜o®ÞîWr …Ÿõfr’¸o’Æš™WåÇaEàsa/7¹@çú´…1ìÒ®sõC¼^೟/r­b Ø­“œ84o|÷OtØ]ç´:1�[xþMËüÖéë0S ©WvHÚðHFûǾ‚4OÈ[ø.†+ü´Óa“9O ¹éå·œ×ù9�3wœ�-ý‹Èðôá¶ky‘$sÞ&ƒyÍþјíz!D¾0{½ ë•o.�f7L1¹˜PÏûÅšS§•ù£GÆÝ|ޏ³}€±7d…¼z"ƒµ¢çá.�{Ý:;A‹+²9=5‰k¤3Qs�„5ÆÎÀNÃj4»|ރᚈ,3#)FäzÓÀ‘¼á÷ÉóòØ/³y `”Úµ“ƒÓËâ$�q¿1gŸcáNnbò&”³g�atÜÁýã?õ²¨rü³ðôl�æ¤Ä�üœÙ³­Ï9½‘M× ¾º€‚™nÛñí0÷vÂßøäÿD ‘^»ß$˜ËËgƒoÃÍ‹ô0~ã羊Ð}�i}ß_š¹Ž�@,Ë÷Î[;�k·Åy÷¼¶€¯/�6_âýÃr‘‡µ¦xÐYv÷¦1ÑšVS‡Ã5Ó �§õìcÿ°ýžCŸî5U´ÑQü×�ð’CóRÜ=ðæÆi€ŒÆö5ŒCmÿ¸vÝÈ 'á¾ï€°×áë÷صloË~f‰ûB¤ؘíÆdK/žÓ›[!Öal¹òŸ“(¾¼Ñ‚|¦uµat<ß–ÇÄb×7g× ¾[»‡VMö2ÿøñÙ ¤òá7ŠvX›¹%Òlål˜ñ¾æå^Ž¥ KÎØ¢¨{¸ ©ëÄ»,:´Yl¢ßh—B‡Äæ=‘l ÛSç“Ù³yðœ$Ç;IXë°võâ?G³Y³lÉÙ«€ž~¨Ã‡;•àøiûb—SVOò‘ô–ÝsîŸjHÓl�¥!2ºø©ß)ÅJ£ê÷¿‡Ùx÷Ï¡r¢ üƒ%íø_ÜOL¸Ý…qP<þbÍò³ÙîäXÓã‘`0VFDû<Y•8ÃŒlÿ¿‡}ÄEÀÍ081qþ€6à}Ý“–@Y82¶Íu˜æù¥g×79ÍŽ®ÃcßH¦`RYD8¶ ¬…¼†$ž³ï‹�œ¶W_î'ø…}î' aI|W>'TNìWwƒûj(#¹ªL9Y¯66œ¿�Ž}…qºqD'8ë‚?Im#Ÿszâ9Kj0…ýû+­O#¾èsÍZ/÷ž÷0Áã�†¾xOéàšÅÿ‰A,¸0ýèw)rTŠ’�mšf �äññŒ¸�žÓMÕ˜o8Z§áÎÁB­_sRçÞž-ùJÌä¢ ‡ܼþ$:! J@rûŒèÆ$‡ƒ±jß.¬2®…Ö“ñœ–ƒÜ[Ǿ.$’È“\þ¾@œu4Q‹]Mp1¢-Õ6yôåÚW |ùr¬OâuN6ø;ôfåÓ9ªÁ$xIj‘l4ÊŸÍŸó+|<Ë·´/—”_Þó‹EÇåüU‰£„ �¶à?1pñæýrM4øú "ÍcõÏ/Íd8u–­kŽ7‡pÌŽY@ñØMãÓ!~ñø(êݦn9u8ËõáONÅöXÍ ðeèÖüO.bé‘ëÞé3ö—ËŸÀD•ó/ìj:�a#G¢ VìÕàëVÌŒÆZ×+kµš“zF²zL#úàÎYs±Öص(bgfy5¤/?ÚLÐÁ¸„Ôßéø°O÷|Ö`{˜¬³Nj·æµ’˜ÃÉì�Í ,þ¼èõÇJv 7‰#ж6@m~úD–|)͵Óq²Ðá=Î,ŽOis]H~†v�aKÛ9©ŒØ¥Ç’¼µ!¾Æ­Ç�§žô&zˆMMÙ¿š ØÀn,ì¤Ñlnˆ}ŒGꜻ¢’Œ¨¼ÑŒUgFõhõáu{£”ðüIN„Ó¢+ÊA~c°II|ô€gײõýÙlôóý#Q Óæì >=ø2FpÏÛƒ…bÇ*QÂpèhAØÇ1­þÇžù§$¨IðÃt î>¬³�SpÖ·˜¾qˆ�!Óá¿<4wô,ïóC º0ôÅ\‡lÆ­¬Æd#ÎìÚ:J›å1·b­U:2ºgS“ýláÐÉf¯\ï¼›ood-?dœÃ§{�µò þ m¬Wgò0Ö‹Ë@ã²±àåbo�NùÏìMe®¶ âÐer¥¯Î7 A àõs 2N~p[4ä€åµaˆÒ[×Ð|ðå\š1k]¯–ë<µO—f÷‡€ÙLµMbgLj=ï/X~üËÁÌ5,·çˆž>§MíË�ˆsÂ}Ìßµk\  ‘jçl¢aœ ÎpåÃ|0ϵ‹;ºìÁ÷åvWĽœÎC¼gžN…Yþ°)U½ïƒýÆxØ“Ï1�ÓœøÜ\ar šˆä °¾ÐÁZKg$’�ÝSºml†yºÞdN1³Çb38ÑŇiâ±Ç,G¹}'v¯YÎŽ­WÕúízeŸræôÍäBÂE?È__9pÄ�žÿ$>WsìšõA¡k$„ðeA¡r.ÞXöˆ”(5׿òoɽ=^}>åí�k¦ ݃qìõ5ßOb냿ˆ‚¬äW’Û7áã½zp<­SûÕk"s±Ò¢}°‚1qúÇàù vY¼p}Žå”[÷Ôýç"|o¸¼6°�X‡@~ÖÞ1õ9µñô3øýÛä¿¿iF—ùEå^c¸¡øæÀ´²àcÇy1ìÈÖÔÀ«»È;ê‹ç,ðw÷‹“”؃$B~÷Ú�æ¨ËërÀ›Ÿ~0rQ޶Ì6ÇʰÿìÖµwDæ7gþÝ@Æõò�¥o|‘k×"Vy^l‹p© líýäǧÆZò£-.ç#'¯%Ü{»~hq]ŽÏš½uÉöv/ýµZÝÚ1BoÀûl÷z SŽå%æ]³?}+ #ƒz8zÝœSùÂSž¸OŸÑ8,¶;îñ˸š×.ÔòXW­!ù’aoà`þ©G9çK9Ÿ9àO«½{M¶Ç0¾5pÿ¸nÙ‰÷vl Ú=ÆŒÝ9“/ÿ0>`°ül²×¥"«‰ÝßñÜ#§ƒ¬ŒôœŒÕî¾b²í4[×vY¸Vù€§7Ñ9Nf~�â:Á$ºX'¢!%îÅg£Ÿà×OKµ˜åKdMŠG�`¸ •? mÎnRGÊ`_TyÙѶòÇ$ä-œ){l9V·cèìQPÎ2¼Ó÷K¨öc¹à)n´ÿs$é“Ú½z±Ó²Ž[x¼ôç6¶»åùy{-¨Û!œ>geæxÓ<ÜãÁBLãr}Û‡Ù›Û1 a²ÎŠs-Â%$Ï»Ý÷Tš×Ü\±€„,ï݃掾h‘±8»�ã{îÙvâ³}™®x~Ðý,Å�ÞØ8ðѯéýļÏ)dzë·Z6°{?“üŽ7þ9HÍ:õ³üÁà·]æ¿=sÓ{‘ÍïÞ|©Üægûhš”´§+uhô}€?ùtŠþØ·^­y½^¸»Næ þ§ì@ÝKÍþkÁìíˆÓKs�=Ç£ƒÚÍõg2f½X,éÀ-cò_†miüAɶŸ'«ä‰ŽXRÛßkéÒœ?zí¿ž/2±(`åœÍ½¾¥qðæ¾ñàÑÛ>|”IþAïMlþ ÂQÊÝ´ë§3;6ÿp�ŽÚ°N�?쇴 ;Ýð—oJ�ÁûT¾%”Í9ý‹°ú4ù›r¶âãŠß+b~8qtÜzXZŠû™Y’ÏQÅW5�K�×Î×5¿g5Ó£G[ å’í³÷µ!ëãaù¬­M{1Ð&ìÆK-íwqß4ÍÕü«ÛL:Q±ÇÍ 'å àÇê_~@Ö_,p0�ù8¿xç‚·ÃZœ'DĘãÆ’ÛÂaõ›LÛj5ÍX³ë ßg}‘øøÚamx„¿×#X[wf¯ã»Ö¬1õA>Î'¨ëýCãXÅ ³UNßøœ'ÞÃÎGD9\³Ø¢éO2ú¡Ù¬� v²{æ4½µ=Õ(†Èà¯f“ϵ6n÷¤k�×ÑÐðõ²G‹‘Ó²™½.ÌuhýÃo¢°Ás}b£1¬çò¦aÓ:_�‹§?ØYXÛË1³\,ÉjQ˜uú°µÜÍé•ðß›·UùvYÒ�à–¼kkÆH�ÅÔJ”ú'eÕŒ>ë$�:¬KPbîŸÿphu'�ïŸé2�)À8ØtbqdLáövj�¬Ì¤ícæäŽºÓÞ¼L]Zc¸}Ýœ˜ÌëÞp}Âpÿï~�3Zý\²åo�‰jÍ¢íúæ=Îò\ƒ7zÃÍ>C¸š’ƒ}4­ö u�¾J�(Cs\�íùÙÉ`Åß5Û°äOrÎæ;®Å2_&¯Cð[—Qðš[§Ÿx5HÍê×ùzúætœ¼`Ëáë®uîšP¥ÝÑï?Ælæp° #ý؆ÅVÈ?ø€W§uÿ'0®kØ#þè„YÝUásCÀ621Ù¹/:y§“ûBœ×LÁÁù¶öp?œÑ3Më¹!âü‰©6Øá=ÍIwu8¿üÌë™%5¾ò¢·�ÇÄÑãüˆ17÷5 Îz¸öÌà Ñ ùNÇz0-«É<þùÀÁP¥^Ípl˜£Üæoþ­áK \‘‰¶?u|>kX6k¯�”‹ÁyköonïwOÒWG9f­¶7ÁîЀ¼ûÃ5PÖ�V�øâÛ$Œ+ßGˆwçО¥cÊôí»ZBåÞµôÅ��ëz¯ž�$†Ò³WÛcÓ¿³Ìè_†„”O}ù´A¯Ý‘wRîïhœo¼²Z¨pCÃù÷õ\”–ÿt‹b÷æÖéÉ™¯b¿&›‡&â9¢ßüg©f¿1{4/�ÛÝm3æ#Åù\×_ë¼èÔ£¸ÿ-RùRb½ì�—Ó^æø?]dtð)�o¬%´¡})§µ�׃µ¯±Â¾×O� Î,R¯›\«Ó�†¸¶§PíÁNo('tHÍ317õÅØ û@Å çÓç^T€ ?ñO¨áÀ �ºöälÕ]íéQÄ‘ó•’ß$*°9J!ƒ+Ãx½f?y>«ó±®Hò»~åøé+Ä랪å5±†;מ]@Îÿˆö‡(Årؤl!™Ü™<àïoØçk©‚ÀÖú]rCí¡Å?j¨¡A@éÏ{ÿ¦_!!Åõ-¦è}ˆ­Z‰UwÅ?ÞH�Ç_"O ÉÿS‡ù¹^‡;z¬‹Ñô$°èCl÷r…òoÄ cîz&¡S…¢a:ÞÄÑ~AfagtÍî‰x¦�xÖÙÊÞÁÈ”É~-=œ$}•CðÞÏ8�Ça2@�ëÀs‹ÇrízZ›“™À”ؼƒOâp$¾zšk˜X?Z+dšá=lû÷£îLâx9„»Ùš!ù“+ëG eiXW–®Ë¶æ]ŸÓƒ`£-Ä®X쓦ŒÍÙA‰%×Á+;*#Î@AÅç–emZêÆ|õaÑÚs9ÜWÏÁ±_Ý0ºü~$ÁÑx F)ès‰�žS…>Âcóé£ýz,9ÞÜãÇa;üf’ý~èŽm5Ö­€7wÖ6%ItqÆ…­G¾Aá Ð5/^ózÇ‹3!Â`'…ÿ=@b5ˆsÚÖæ{ˆµF« f5Ø“Sò˜Øüp�¯ˆCcO"AÅOŠ=‡ j~?ÿÄpHTÄý¸Šr}… IDAT i=é¯ÀØg{Ö‹âC‘¯Œâå\! ‡Íœ”(rË/ ôuµ°axÉ?­¼_­îFì�½6ª±2¤(>öÔ”õç':ù³J>£HÀ—¸¾õÖyn6´6‚¶Ö’µzíõµDk´#›‘7FYg﮹>°£†k÷³ûD¼��ÅFǃiî0Ëeoc.C¬‰”O‹Ô-{)Éë¡©«êЬs{|¶7ð¯/œ³-voðdÀ>ŸyàåZ$5³ÒIö\W–y¼+ÇêÄs ¼)n {Žl²‡ÓÛÏÇNºm4ûif—1�ìsìºZ ×ʉZàÓC¯¡^›Ü§½ÜÞƒÍ/ÕJâX¨½÷Yœã*ݚ⃊=½øêrýÇX0.o´¨4\ë·±wjâ&\ýΣ ü×/ã Ù×Ç‘„ãîÑ™§áŠ‘œÝ@ Ù2pr>7åW¨Ë»¦- ó¸Ýž¸žaÀùP~?ªÃ-¤qrº™šÝäHrm{BÀ…ž» |ƒiÂøìQ«—Y+ç°±>gipžéÒþøNËw“‰Îes?Ù8‡fâ©ËKÍþR<þæ"C²Ä~l%u4z848ÛæSövà¯ßä„_©ÓÜ\àYë1´÷ä‚�šSgqðÆAΞǽ~Ľ~€®¥œr‡£N/Ÿ=zn Ïy� 4ËâðûI\Tæf¯cÔ ½ÙñF;�ûP§sQs›.€aÉÍšš¾Óýó´ÄxÆÍ\ûêÙ RÊ[ЯN(Ü—Ï,ãZŒöòÿ½.懠‰�ÏB;Ï Úkìö©æþµÖjŸ^ë"@Ã?�=$£Ž:ç`ëu|p™Ÿç”?øj îaÞ^$Dü¾NÙ¦7}“—šüCp±ä1þ*¿�šY²Ö±šsDcRØP¹¾ë\œùì4¹FÔK“Ⱦÿì�ÜÎowzdfîÅ·&am«q¾lȆQ_ù‹?S—c\&ØùìSþ>^«Ee>/ظ&jž0?ý2Ãw²>÷M 3з}â_ŸS Ø^(Î÷j\‹\hY+½Ý=þ÷ì0T·È<œ_<«ñÛ×Oòéá\Î�}:×Ï›î )%ça]ß vU„ƒ†¡ÊØ×›i…á‹iÎÅø^\ªêjÅ`ñ1�Öøl+<ã®Ïb”ë1^zOm{¾MšðùÁ5ÔãïpO0Â-·1Z›ÃùšÔV§LÆÉ.÷DqMðÅËÞ5àw‹'毴åLû]'Ï"Kˆ3�2]v¿däÅBÜ8€çº×wS‘Ô—7»œ/¦*æ{{ÌÚù”œ’C÷ñʘMS ”&'1yŸSÄõ-Ðñ3ïýP<àá¡GŸÄðeMÖã Ð`F¿˜õãS>¥Á'WÐÆÊ=ÏKmŸÈýœ3 :ÂNÎ9¶B–be�Ý;qìyc0qð^:ÈõÚk¸l'úþ÷1.Gê„^’?’ØsÄÇ9µp`&0³c¦'¯™ìÖj »îÓ#¾|À–8/þ?'rã�PûÙº7FþÕ:�ÞücSFìÚ5Ñì¦.î­{kã X^ø¬·¼¾¶ßë‰sÉæ|�sNØ]âêŒùta.ÂØé–Œ–þÇÞäuLÁÔŸ‹ 5á‘’™:4²´¦sÇÓ3 OÉùuµ¶›³øñ�èõ™´'ë?ëáX\OJ6 Ùdzí›õe'ÿAŒæÓĽÑ{Á<‹mNø�Ý5 ‰mÖ×ø˜ûWàw#`Ýú„B^;$wƒ`C¤â5ø>HC*Íðñ™öÄê"Ù^r¹‘ç�Žp ˜ùâØZ“&-±ßÅè^“1ÔG-ø]+`Ê1 k–ð@ɼ�mÙ�ãY~\Z‘ã¸^? ·ZBÉb‹FÓÚŸZ0hðÛz¸£IH>ˆ3—rZx¼äóÞQ:U ÓxÍ‘Æñy%}Bë1ùÐ9)5‹Lµ±Ç›Ëz8ìf48`�áà}}à}TÏ29–8â1"°ŠlëwŽbœGkë)ÇO¼(3>í–°|8ßu£Ç�ÿ³?­‡ð�Ôš:àð<ü–0”&-}Iìzá|1ý9‹­=°ƒµiíÇSzšQúŠŠºå“Éop~K:ïbçêη7Fö­({Eæ¯+ôzŠÖp.ᮞïÿG\g3¯êp²4¾Ñ»ðΨµâÙ X/ Œcׯ°ÄÈûöÊ÷î­XEc¼Nó-¿™éƒ°$à¾iÔïXa¢ªÚD>;@ë‰6¨Ê�þô¹oà�Ž$qãʼnЧ(ÿÀy…|xbè~ ͼófDÆîüàsäÇÜÉ[í[ôú?Ý-Ïê…u…Sª]ëwïºu"¹Ù}ÚÝ—¶`œt�µïa™Í¯ó½Äÿä%'üiZècö¦×)|ÕYF‹iþý•¡qµ1…§†Èw˜—·ÇÌ™º‡o¹x§Ôðl)ÃùÐÏxû ]�­Å`­SôÒ;Ʊas¥ãBø¨�^ïáÈ–¤Nµmiœ=኶l²6^'C 04×Î8Øpl>ãâã:3¢06Ö$þÕŒG_`°àãûiøpâØÆc3Z·Ïs„†k v¡¾7Á÷0¯qºæzŒ ž£Š¬>lo=`][²å ¶!à'ÂkìØ0k°f›×ˆh²½7²¿–§9øÓåÍ�ÿJ/m$)ÁMXsDŽæV³­IûÕ¾½±äÀÇ¿Z>û%ô^oÍ—fîim„p}ðíº‚aä”YõÅzoÊòÚ“5P¢Á‚á99XçzËî„bó\pÚ° ¢=¦ú¬±!ÎÆFád“á¸â)ýôçÓ8mî5v=¾>›¯ÆÔ¦�Hcmí1Á±ç¾þÕ1YMŠ’ák"Þ$ö°±#¯ç½WŒ‘™_Ü!ˆ�›äû5�‡ýÕ…mñýžá_¶Ë|#~¶fhs;™r¹Ád­3_ìRÙf¦d6l@b�:ë¾YX®õ?¼­y“C9•,מh¿3¤ëßö$|ëI â’×ÔlÐöÜ×¾>U;Õ¹×£q¹Âo»]ìg›ØìáLÞ2$!–ÄÉÆó˜zÚ�àxð.�‘=^žô21¬S°Ï{ úéa¹gYÐä ÒÞ;\k‘çäCýîÃD¢xó3E›ëŒÆ.žãËaž,—Ó˜7¯õÄ^¾¤nÚüp¼¹^÷úŸë�Öè��ØÕDœó–À¯ý‘Ú�+d¹¶o_´†×‡˜p]}l¶§´rÄšóâØ±¶6ôM£ìQ›óÞ>ùù^ �N]¥7Í7=ã¦ÞJ ûro�²™�ùöiïŽâZŽbVƒ/¾b—Ë=ËQÎTä4�î'™éém0xÈël:°1œÃ‹(ד¸‚^O°:�­'æè7æÏÉ]!�küô¹¶qTFB“w4äæ¹Æq±>$”‡ý¿³Åø�:Sìœgò…¿]14G‡‡'¤àƒq¿Ò"6~:¶B Wb!Ò°–òÅòïÏÓÑ�+~hñŒ“ýÕ™‹G­R±ràã«s½ÞWÒ÷¤_ÂtvÓ¸è益Z�5RðbÈi-3ˆ}mџͧ±û&x�ƒŒgËÓú‚kûÙ†O4ƒÊ =]÷R¸9Ù¯V'Ø>�ö}5ÔØét4Æ<¬õp—&M<­Äf½~€�~*Æ=7aó°[îÍw »| ýõ#Çc-#x¸­a5Ñïâí#P´ç�D9\§òÇWݯgfE£ŽŸ”�æñ¯?©‘ y³ŠnòeŸú�óä¾Å6"Œ«ÖË‹ï»~Ù™Æò(&þ—­6›8é¨Pt�f™÷h8¢ÝAòصΪú�ßN8Ìtð,vo¾æØ°üÍñi¡V ¨ÒÓó¬™}]¨£RvméÇ夸1xû«-Ìu&Èçã½æ=Îgéxaò†—e”�•µkÁì#àó›—W†½ÑƳsÀeÆ\7l³Ó±íà!{´/O¢õu›u*^s�¶ä Jk„ÇYC³Úž aû@[«¶²kVÞÈõ¯š´G§¹MZî®I“dæa�;ZKí<_¾äÍÝY�¹Ùãâ¨/ú>óìBäZ„·nÓ6�×µOÐl%I IÌ厉®¡ ¯‘µ8G­Çí9ÕD�ìzNîs5ÌlýÛ§Ü]í¯]Ó;¼æýÀìûžý&Á§ŸÉZM6W´o<.¹–ïð‡1fþPr5ýõÃeóìæk‚ÕŽû†ñ3¯ZÏ·:ÁßÚá:‘GÜ<éÛ>8»:„áûšYÔ9}Î&šózâ É ^¸õ•µ§âÇѺÆd–¸¥ž—Cë|@gÊèr.-5û!Šõ-ØØù�Þߣ�ºq͘ܗÈsú]‡Ôi0@aäk÷ÚñÅɹZ‚s°máùΖµ Øìè¢1‘Œç‹³MÛ]wÂæ_‰§ó ?å¿!qˆ/5ïCÔ=§c÷Å"ª|ÎIÉýØÍƒ4r‘ÅgÛ‹—Ó½í°ÿé!Âè±åñ^± —9ÿÆ~lökö¸üá±kx %J»£‚X›uš.V…F å¯HÙ¾ceož}QJ8…1ú½’íL¶ïDÏÒ‚ÔP»ñœ¢Ìß×ÙyK_ñÓm»è„”–s1¹v–à ½ýx±1B”˜à¾úÂñýµ¥ü͛ؿçætÑ«á �ù½ŸÆûö}=�6êœæO÷™ÄÇ5Ͼ:V›eþê0¶m×Èù,àë¡Ø/œ'C‹®ÿ²ÿ¤ó¼Ôéê½ÂMI¾C¤¥1<—6[åXuÔ9jö·†—Q(¼-<ôèî÷¨#½ÎÜáÀuöâžÎ’˜æÅHNú°^ ›e|Ô¯*s�_¿˜ ž¹k¸¬ëe D0«½¬ŸÆtxŽÉg÷¨q6ˆçÃä:ž6xôKë%©â¢76‹x¸Ö‡'�!Û�7ûdE�Ëi •ïò·:A:jukþ�™†Ézs¶­Gû³':pi¯Uõ-æÜ3"ŽF_øã>Þë§PãáûÐ.©óO‡ ‚j§cb„«Iç¹1Zó§-H8·õÜ�PÈ:ŒƒÃ ´¹L¡²1¿Æ`æY'ŠŸíÑcLÚã<Æ$,ñMáiÅCœ�v¡sp¤®øÉS°]lhÃÈ�–õ>0€ öq'†s|œ�¯±‹µ¼µ_¼ÌΜô!*Ùb¸È„ýþf»*âÍg}ËÖ”Ð-Ú¿¼µg#£bWçú4z”ºÐ§ ]�Æb§�&lÖ".sàk^|Ö¡ Xêp-Ä,gã†ßLœc�ã?¹ÐÞT™ûk)cHêñÛËa™)7\”ŠZv|Ëi•Ë¢pÄýpX<†iûY’7µ3üƒVy�ßÿ½¶Ók†r!ÿ‰³«‰cN/b¥&ËiY¹ l¸Žåg¥/r$OÀÁš5…–Úÿ©ƒÐêüå.òiŠ;ŸkÙp�‰gÕüíçîcs÷¬¨Hk>ŠiærSW"~Ï¿„ëñ ÌÄ e=ÎU}À÷¨æÕ’ í6AXñ;ÏúaŸOf[O´ù®óCx°Z 1"3.-“Ò<Ç+Ü!n‘{!cˆs�Åó�.¹‡#w�2§Oô¼¿É¶?L<'òÁ½évÇ¡á·7wÍ¿7Ý) ã[¢›`-\4¸wøC‡þõͰÝjLC?ÄÀiyéy8bw�Fgpðœ‰ÞµK 3\ÓðÍ�szìîŸf(+ß+âù;Ì-»ó1C¤±9xz¢ÕsL'YáÐä}ÓœØÄ%sypÄอgòžÍ´¶¬Ï@0%bþ ʰ½®ô•ïÜnëYã/¦ë£6…<™ÓÍ¿ŽÃ¡iNŒst}>\Ò±=nç=é]ç’�5Áæz>¼ˆúWªŸïÍ¥¨ë§íôVáëƒU¡Í‡Àͳ\Àý3‹ž'ZXÄÕ‘mbªvžÙh?'…r8ž]ž?¬½Eõüó]k—Ù{YÓìxôh Í’Ñï}î£ûEB@xžüÄáÈÌz½‰Æ8­ÇÀ=ßd]�©í`C™>­2�;ùÂa›{*kcFaœY‚=¿_ï�†”ë�©\~Ö€Åeà$WiѹGE`¼@| <�p4ž…—†Î˜«ÄuÁéû¼.ëô5N¾ïC�¤&_ìûÏØ ÆFâŒfÕ&ê-b9lçΰ0Ê ™àÆS¸Í®Qy¯o�¹Ú�âô\×ÙDdœõétĹN»gÝgnàðÚÆ—Z÷êxÀ“·yØ.‰9ØÛûÙ1ÁrYÜ~öÓô÷Öm°îƒzjæA k®�ë¸$¯^aôÈ8Ñÿv\0Ó³k?jÏ£3K4°\ŒÍÂäF«mV‚Þéh¬ùfÞ{NÁšaÜï°ç| 1w©0GHŒé•—Ú‚Ý‚þn¸Çl'k³ éy WËo®cb±ÍfLZ‡¡Fïw­´Á¼œ›eb8ö±Ý’E7©ÝhNŽy’>×@NÅ|ׄµC¯6ì×~×øfÀÅ'Ï{}öï¼þ-'×wks°/;þ kÒ4Å3Nv/W¼àSÃå2GlÃ$MïIÉê:'`×¾'Axÿ8Í»VŸ&y Ö˜¦Ô8[òfÇ:à`(‚\›·oõ=¼Ÿe,_ø|HÞ¬—5e?Žó?Ï?sòE|«hÓÞ9b7÷Êו:¶×œV¢'c×tû𥿳¾tÔ>ìÔ ™O—|\ƒí[®j4o/Ô«Ò1Âô;¬³8XÀLqÈHÛÙ[ÐìÃhvó538»pæ+Oã©ÅfÁ‹$ßÐÇæ ø0ào�䈯[û†9]68 ÁXï¢0Ço>rwñÁ®¢i‡�zInúÛ_Þª8ž­9­[Vsˆ›\¹ØÍš$Fç‚Nmú±]._”Á�Ùs^ìèVE;t~ó@ÊBãô(Ð1;ù[‹Õ¶¯TEæF‹„èa^£�;¶E)As Ðñi™Å½–yµÎÎŒ 8#çë6é9ÀDacmNí|#Á7&ù],uŒßxN�Øž$ñ`ö‡ÍZ˜V'ëpH‚Ü?û—ôÃÀ²¾gƒN@Žå0ÞŒÆ5„1×L>,ÅçƼL®Å¬·àH�æé·Ì?c|Bqm b-Gµ9$’ÎÈÿ©i½Š˜º*gõ[#:HõÖx|Ñ8\j]ú�Jê‰×)Þ`˜ðô$¢8Y«';έ-K›×wÛ…“s½Ì �ïO¹r?fvÏÒdÇ�Ñ}ë.ýƒÎß'ñ®[®ÍÁÆgý­Ù~ôÃÃoÆHÇÙ�ÛûâÀq3á|ëY”f¯- vöϲ�†\Šgχ®Š™…f?ÿç¿þ¥=;0­s>¸Ïê…ƒ5aþ@ñtGÓó-S§­šˆa`NÎ…)¸Ôë- -Å'Cî4“¹ãkÑz:íá¾XÇd‡n†ÏYJ5²Éìu}`×/Ö` vlèð`ÆÏ‰¡ÉzÑÂæÌðdãù‰›=n—±Ž7¬âïÞc=rÒ–;Y›Ô„ .øÕþ=–{œÁ}Ö­\�ø–ÁyÉí4$Ò`û4(Úd´æú­ÄA¿±&øø³Í½éx8üüCiTÜl~j$U4Mè§§ ] ø}í¯{^D³§Î/ÖÎÆ%ß|ä6ÁއÃ6 ZôöwÀøÀ§Aç4iöä¢fÇÕdžãº��œy­àb¯ý!½ž¯ÿÊ/f÷s˜×ú ÖÏw«=B4ÄÞ<ßÁÙ€øBXì²Óï3£•‡øoh‡hr_.ÂX'+za�ïZ²çX¢í5ÃiŸ×áq;bÛšœñ8{(Mû?B0ã'OÇ»¦öÓaþé„}¾k†*µ…ó4ÍŽÙqê½G:íúŽù]öœ..Ë@£hµµÖÚ�7Ny½Á~_­M³kioNhÿú±`[aÀ; æ®mÑÚ_±¡mæ:´­Ñ]UNÜòbÖZ:±ûÞÔv×g{càrØ›ý„|éƒGÍã#�-±EYrò¡­sƒ¦jp|ò}=#æý7›ß~>ù*syšs¸¢göÔ²¯)%˜éÑF}á}j¹ BÀthör\é3ˆYX{—œ´î‹¶pë8I >¬Œ‰·ƒž$Ì8'é¡õõr¦Šñõ‚»ùð�S3û%ú|[9¯6Ó g>”7qBÉw¹›ü3™ žË§5š©%õ0–=±Å`Moø™-¯çkÎå.ƒ¶q¬~Û‡E6=†dãYÎÄ f:sàŒÆi{ks-ÊCþi°œ<ÞüNÆéö?xòÀK,óÖ"rÐøÙ°¶nÍ‚ûÐÊuc²�ÙËÄCn# ³ÿÕ©õ ÷~<É)Ç1^0èZ{Æê°çÍ%¹Ç÷7X¾f1Ž]°‰Y¼�Jäë¼ Œ_ç¤1|ÞÖÈ~ר<œän>ö ÏÊUJ“}˜¢4±šÝÈwBžx³ößœu³’ûriA.÷?kתç‹Óˆt?èà°0=™l*žEq-ô„Ùõ%ù�N\ŠÙZ³�6-ãŒëÎa½mèÔHAú«6Š?}õ‡S^|ÃJ³¨%y­B1ð„Ùè[ïæ™�=ŒÆ“‹}mx`&㺈&ŒAT^sf–õuüð-Nyœ[MÆtaÔŒa¾å“Ýfí­Rs4åÚ.Þ½ "åAß|©�<�ãÉ·žÄ�¤õG³u ;™]S�‹Ãö®aˆ¨q%ÿáÀ÷š@E+2‹¥}yÃók�¦Gîryf]r8.Ç�lJN Øá(�kÅD¯ÄcmÆ•6”‚Ó§pÁrCË‹Q¼yL•õø�'þ8÷Pá?¾äl€ìøö€ï盽önƒõà}öÓk*tÅÿ‰‘áŒçÁcFç´>9ÂD Fð‹÷Föíåva.A R[0±5î ·D®Ÿy¹`/tJ¾:°’~†(òR@§yùçgÞš¼á›%×*ò}RJÇuÊÐÜ:Ù£ÿ_¿fÞ_Ä““¬ó‰Y–ý˜ë .ÏUçª?úZƒC÷fލ‚ãz[LÃc÷FüšÉâ¾)g¸¡ùâù+z`fÛUGý÷>ªmÜñÆ<¿A/Ǹöƒ%zt|ÁÕ¨‰á@a×8=?¸ý�œ<bá}-\žU;Þ<®"ùâé½FöapsžyÏBõCúãf“9\=Ýáç{êÚ=“²ø^òp„í´_qØ'vÛôoâ‡k ðÝVŒ>|¯Ãìäg—«\ƒOò“çDöMÅHÈÈ×ö²´žþyqT™$<,q¾w�!{FI¶7¶\ã]ê&6¾»î²›¼[_®æo]M�žÈLR?'Š%65˜<¹¼äyWâj¤FvÎrvà�ËE”[…½¾­™÷|»¿ð}î]ò «•ß=~âˬ¾¬Îgïe3ot[kc×íÕëñŽ­ãY›ëñ—û²i¿çŽÿ3ªÐp¢ðôŒ­¯Ý.øú¨,Ã׊ñž>LÍL¦èç^§÷¯†ÂqDö;Ö&b>}ãIJ׭½ ?_5ÂËð½ª>M»m«Q›�¯é $¶= Æ84á¶«ö�Æõz,~>9îÑ üôCàµç1"°Çˆ:ÿ¼Fgk|¢¼#ü^êË÷§i<·«+¶/ùö™é?éÒŸÆ:?1‰síàcË—‘&(Ò¸Z™ÐâãüÄ“/<¹–©É¤àÚÓä2|)ìKL®Áò _c$’}øb>»ÖæMÖEiê¾ÔÀøg¿Ûãéæxx=I­�$ÚZÜìµ'ÓS³óüæ&ˆÄ,wz6åá\÷z`?ùì zçðéì~}uR¶�[b‚«J=½ä½=icy^ÿ*¾BXÿðÅ ×KŽÇÛïïg©Ôd á:¦sb+c|Ø•—ãʃéÓ”ïY‚MÑÁئhÙl¯xæ=\ŸN¶aoÝp~K”@Ú�&¶Èl^û›”k6gûˆÓ#: Æ|{û ï7LÓhÛ  å~;~qrG» K:"MàÚáÿ©C¹¦y\—^ ÇŠîG+ÄþJ ÖtAèø6ÖM|%‰Èëñ²On0¶+üfü@ˆgÝq«'ײ2Ÿ¿xló¿µ8w1 jäx›s±ŸÎä@§¯Ðõö—ÇâÉO)"·˜æôzÀ_|Ä×¶>xˆCqwÇñ}|¾i¨ˆ)ÿ3ã=~|äë|ÜÝ› Ë…<|‡IcÌPcŽËìÚŠ¨ô1¸ÐŠÝŒo¬ »^ —® IDAT†™~có½‚%œF0Îbí·Þxokó·;¶ÿi­0Ó�Ï. _ñ¬<Þô¿ë?/$EÎÅÅ¿½}ÊÏÞù|\ÈwÄÌÙräur\¨�°GytØ&§ý`<ÊqÂÌ6çÏìþGpÚçÄh•ëmTâžDArÆÈ\|ÕLÿèÖ“á°?ÌŽ'ÔqqÊÞ»ŽÔ�Íæ]Ÿ2Û†/÷� «wuØn‡:ŒóWÆÒ^~û„q{LÂ)‘?Û'ßÙ‡´®Y[Ƕ?s„¬æsÉŒíËš{ĵIàú=�w<Ô.Cµ‹ Übm7A®L°ÉØ.ÓÃò:°þ…GDòá t1¶ôóÕ’µ¹¡˜D§fbã°Ytf18³Ž\›ætrÈpàÓIKøÀq?æÃIÌМMë‡{ȵ�¯é8²æ¡™±˜p@†Q‡–äÏ`æh+p)v-Wwð=+ĹFȮܗ(�ëû•9ñp^ZÛ8ÕYî sÞëØâ¡] ±q­é)4Q6Ðw¸÷6®w GÆ7´sþ^‚Á¢¶�.¬„[™y”ÙE`c€ÿbX'_íšöÜ«†ëĈ<’G.cfý´ä—Ú²ð‹Ã¬Àê|¢»üH}Û‹9ÊlWóH4¿´aJ�¸ŒÕ‚sk‰&ûaјH'φ(T>LØ€‘xpeëØµÈVìÎ¥]ùnûbÍ]À€„,FùR+¯Œœ÷\8‹AÉLE!²p„w:¹7–g©£™ÎPª8Xè˜fðwOaG€`±±É=Ç~GØì’7AÌrcsS‡û•g�ñ7ÞΨ#ôSÿ¬íHž]ªá6Cs¿áe£˜¯b *<7q¶Þ³œfCÂø˜¬‰žüÄ‚­ÚhO6²7/ >,kã§nš4G17Ü4ÉWs�Ç},‹mÄ‚!®ëdÁË*Ú¼îg�¯9Œº\‰ù°Ù»6åHP¦¨ýÖÓO¾Œ"4Á‚Ö”(vÖðfÅÆ¦ßYNü©½˜á W�öj0~AÏ ·ŒíG¿|«Ù²¹<]Ÿ¦ê@Z¿ÚÀãÖ g âhÁÃ`ÁÎþ´ “”à˜é!Ÿ±1Ìæð‘'Úƒ“5ãD±]_þøºe‚#º^l„ý­á!�ÇÛ—ãŒUQýšöC:䎗9òÇÓç�¹9•£û•:÷oà2îˆ?œßµ š|ÑWS»ý¶—uä».ô- ›§Ã³ðÎ!>æ…o‘X;“~‚Ñ€«Äúƒ ͹^™µ ˆX¾tßOS qÃÃþÑý/ý'|üg|ü5ßì¡3‘yè…óÉt¾$ŠA"ñ›KïìüA gé("o&×�Xs�)Ò*+u\­øJá"Ì \¾w¦GYü}bÿ&‰ìî´fÜ lìM©E8èT_þ%~Îæy°á•'ÎpÛ/â„�îèïk ’ïžnM�‹E#>br×f»A¥i6ðÄæMSü_íñÙχ½$l.ÓÁ_=”·@ã×Â1ÄylîÆœ¬eßsù°˜ÇÉ\Ü`ÝMì!ðã‡_æx6¶žDãE/œ Mæ^äf9øç}fó‡oyŒ5c4š3’ÀsÏ[õ˜ŒAåŒÃZfUÎi†‡{�ÒßÒ=Ÿ‰õó€k¸C�sé¬^î>»¾ '^¾zý}RöÔ?°`b߇AP]/¨Ã¸~ØR_SØvxì$gï^KC|yýŽXg=Æ®�5³¦˜râ[?ï~2hz�Õ‡‡ÃC~†óÏlñÙЋ�c\ÑÜ@OPNG 9sO:že2f€æC�uHÊô„`rÚ{ÁZáâA_{d6¬}U8Àðj&–ÎÓ0ó‘Û7SŽÑÁ÷a½œÏÏ5úä¯`ðä9Hž|_ '÷~îwðð¿áeûjèdÈÁW±±}É™ZÈ¡•\ß}‘pÓÈÖ£–”lg`& Ûpz%ƒ±Ue°Ö—¿kǀу´ï+Ž/©ZÞÅw:õ\ë’ÌÍüA´©ˆ×OMÞèÞ6Oü~AÎt/炎….÷í—~suì:�¾ú™HOüò—u¡�kœë\:Ӥω[Ìj£à­­v�ˆÁ—¬É»bðÙmâïŠãnà§ÕúÂw½ ¹s]œySƒ3ÏAÍ^“U'Ÿ ¤¶rZ»sÚèžàËÏ4f¬?«Ôœ=¡?{saTÄG.ŒlÚ»Z¯¶I… ßµõ€Â¾¤3'±Æ Ù�óÁ’“Ἒ“׎ ‘¥9‘ãÇ[¼cD“zL¦S‡°M—]Pó˜ÇÊ¢»!®“\GüTÀÈNël�; ¬¥9VÛ�þÔí­y”q×bý°sö[�Øá&”ƒuö&Ó.†R ûן/âc8•‰…× ÿŽÔ)ëjÕ2ú’mZ§ÈÝü;> øé�xSí€ µÜõAC¹�áÛÁÞ.øñÕ�] ˜Þô_vŽP ùdÑŠÓÛ~áúŸ0ÕoNãb)"0f~ÜÄ‘G#9X×&ßhlÕþ¿õæÈù‘S y "Z~pÂïHs¹ ZO[jbŸß6Ží½´Æ.^€iƒ }»Ë<Ýö±Ñ5Ö@m:Œ1§Ö#D—~ðþG]F/yósj~†#˜|ïÎn=]¦¼©9à�ŸUÆV—Ë•Ö)£3D.~ŽÐúû™W¸j!¿0ÉòÅc¿ûƒðÿkÁ*6ïþÉí~S³ÓæÃ@xÉØ"HŸÚaM´ë�Ù÷Uõ-ǧ]ÁÓo­ÙŽL=P£lIÖs×FR®1)“Ö}dÃö^�Í UøX ?ÎþcIÆ8êâ‰Z/­Õ/ºI˜Vijg59)m“=VÖ—ëÝöÉÆàžø”½Ë«mÝ–åµïwÎwõÞ‹’‘^ÓPHü”(Xµ”"&dV$Sð’ˆXQ,¥ ¦ H–Ó’)dEðQ-DMQD­>k $£i¥€¸ñ=l¿ös¬uN:öÞsŽÑ{ë­·Þç\s­5÷Úçpìðmh5ZX“‰ae”׸+²5»ù8/,Ä1Ä&ޝ ¦:z�{Ž ¨ Ï´ÁN-|½ÚË>œ—íñhxDY’7h÷7þŽ˜`=Çõ=ü�®O¢QÜWÇew�¬£/`ÉCòGËT»þ‘Ïxb(�8¸zނέ�·öW¼Áa ¢©5=púÝc×¢é/¬cñ·ÛÊ ˜‡‹„Ù?c|�¥³C‘ a̦ÔÑQ;¶ñ;ªÚm'Zß/}‹#69_|À¹h�YÚâ~ITÚRÜû1qt67·ù.mï]zÁÂÙ/âP“Ü™Ãîžp��˜µÀ‰�£"˜X-X0jª<.—|}íŸ|Ã?ðÙùØ7Cï;fXëP´ZXÖš:v¶Ê\÷±<^û‹Gm€þˆ>4q~Åx¤XH¸Ëåºê'…§­Å©l”UûõP_Ý—…¨;H ê‰\ ‡/ ØyÁ¯ÍS„âÓ¢¯ÑœÇêoìÌ|Ÿ–˜¼ç›¢<÷Îoœ]Ï]GçÖç,„:37 ¨ ÎÙĨy>��=7øxŒ,ŸÌMp¼ã'Ÿðût¸°…'oìá69²^®;ïbù´àüÖb=üɱrjnÝÒr¸™´Jv,SCtasï�1ócΕQµOS<9Þœæf†=7س¶[spÍÖó8sA=°?#‚ÅŸ5zuih˜¹�õÀ«±Ú„{ͯvï´­–å±½fãó»ëé£V“”ç¬ø’“ucÍIÍ|_ûä¾€ÐÚÞ˜ƒÿø| «ó¢ÁšÃ±ç™¤ÎÈÛ/¯¡®;Yo_7§.Ä«½Á 4_Ÿ×|Cˆ‹€ËS¼k…O†ÔòÙc«�³+¿v̼R<©y”Üû“ì1sÝ<ùòÞã÷yÍ®}ÏS0Ä�Çõ¤ýøP?Ž<>ç 8?øgþ\7ÂÃ6åìšð|ÌUãõOx�öãžõÉ_ݯyÃ;­×É^JéÒ×®Û;ir ÏÒ<²RÞ´˜á‹zCŸS&5âX­9E¦×\½¹”Ÿ_LYëLjO-0ꇵ¾öØ%‡h=¼ëüÒ?sñ€]ƒ íó˜‚õ½Çþ‹~Á|³5Ox¹¶ `½„ ,Ü®{h´NÓjèþ³ÐÄ�]»Ó¶¤9ñމ±,§&GœÜRÀÙi嚎>Dï´cšßµc«0‹6%ÖÞ±¦æ:?ÿ³?6zäã¾_ö¨*;%Tßwsxþ‚yÖËB­³2Ÿ¦�Êð6N®Ù|Xà;F¡à`�oµI¯X1Ú ê<)Fòîo èØ œø˜¿ðëymúî �ç»WŠÇ&'þû±ÕŽÞõã>v³MÉé;Á×`ÙG˜d¯éo ¡ç%•÷ÄØ]˜±84¬|��i6ï�é9Ϋ8ï9ÈÌ‹;6Öp[JõÁ´¦4yk´Zfcò©1î(Ž·¡€S.“<�Ç´þ„_>^̤aÍšG{l��‰d–//º9ðQ§°äÃnŸ{T¤�3¬»pCç>Ø%ÛéYò†[N…»ž�f¾Rf©Øi†só:Ía;94V{°6ÛüË æ}ÀÉôÍÙ~]!ÆÑcµrߢáðöxk™¼03qîF7÷­ÏÇ®~9X8÷<£ñð0eþ,+£ç9Ñô@àåž|ÎUÿ¸GóÕýtx_ÌõÍr­Op‚úÊað‹kÛKC>÷çp±¾œä1ÛpÌþŠCÌÿÇq÷Â~,º¥¼5Ú<þÖÏJŠK©Áú˜½k�/Ê¢ù€~“ GrΑ>‡-öäaŽpgrÃ㺄A7lü€­sÛð­†�G‰#-ØõÈQ¶™`¤e çÓ‹tÞ Å/h]?ÁóÆ ²²Êéoc¦?–ä@ºÌç&úÓùrìƒóÇëѪ-úá+�µé;J‚·p”£iØ%Oˆ=§69Ø1™ÿÔ`+UôxAb"Òœ$!€ ïCz þ­}VÆ“+?3b¾7��ï±Ç–µoXàÔ}ëp>×@æ¶§•y—Ÿ=×…‡Ã§nB®k‡NìøÎÍH8}ó÷•?Ç\d|;Åô’ƒº»„ÕűåÇ×ÙÎÍ?BL”Ãàó«1è9IÌkf;B8l³gÈŠH™¤ÇÜ>Þ;öZpŒ�O±�šÄ6îîùÛ [+¦|™ª) Üù?±W-”@¤u8]ù� Ѹ½'€$‹§�øù¾×ÂS§ä&>ù(c"ìcŽ\Grœ•ñ>–Çß땹!×�Æa8ìR)ñËg®„Ä.”)çÇÿâ½w•Ö˜Ÿþ…×YÌÁ:Ï•ÉM ?1çüy<¤Öçº@ý‡ s?…hé±.×ëh0<›¢‚»·Ëîxâ”ås©î՞˧@¼®õ¬b[/¶2›¥RÝéÑìqª¯»s=K�“–/1·ÎiÀyÉÑuõQ8çÝ™?&ôpŒ«¯\öÆ ÝB¡‘/ÑJb½ôëô^ÏŽosL�Ó;šä±Ü ö2M Ó#Á½p_ämjŸ^/ÒäˆÖ¹;?¬�m 2ž:SÓ´Òz¹ã2<{b¬á¡)™½™?Dé Ó` çêrþòØv怫i1â\œ‰B)o†u5ÏôχlmѲŽëÆ�`Ü vúB†Õ±§OúƒÝµïæyr0Ð`?ñÓeßLåìqvOðå¸Oß^ÛGSh­«1±GïÑGúiÕ|üHbþHÛì‘‹Rø^,±Ý{æ{]g­èIà+¸ii/¬Cvàwé^Ëž'ÎÕ]@\„ƒ‰bùÔÂWþÿ‚ñtøÀ~6oö¦V¬©õ„KóÜÀòáIúà�Ó‹¥ƒ“™â‡I±[]¹nÌeéf5®;¿™BúD5hõ%«ÌÌ7´gq¦Í´?'Œ‘†)Z°Y{ý˜_šLC]Õþ»'—îœ D?¶Åɘ¯ýòOÔ|`­€( wò9ÿ6ȸb,6éòhp"bš01ô£uÙwá�[ âžÏiFù ¡©Ÿøô:=G>ãæ"#:Òë­O�:OÏhÀÎÓ£åÒËø¥ƒ?g9¾LÖ�“³µ$2ýž®êÞÊz©Ñÿ® FÛÇ@=2ù„NÜaŒ½nëï…8˜¯Æ„—dûSñ¬®¯ÅT¦Cœ§º¢×ëH%ëÜs<'(}ï'œZ-&$–Å WýéÿöbÜêÄÉ÷ø²zè@G«ýt¾Çúx³?ËÑœÍÃÙþLbIÈ;òòÈŸ¢tê­ŸCžãêpY¥;™„ÃÑÔ+Szå®åJÉ‹¦Òºs3( 03àUö-Ön,å­Àõs¹·ZØ'|[­Çç Ô>ñê²ÍDxÇíþ)ü~âçÍxú’›‚¼ùþN:y<1·d4UDnà÷ü/šHn=Q‘PÞ”ƒ"¾ìý>Áו/k"ü"s,{â£%s-=œ\ëq­ ­4ÁJ�…ðÈ”á°Oc§ÕÆÈOmÖ >ç]­ò=Ø&#Êavj1ý0kX–lÖÍZsíÖïS/t ‘á_ûa=——|²{Ô�³ÆIÞžðÁ«¯å?së G°ãa?[=Žwæbú’V!äÏ%�l_ø/³�ŸúÄuÅ×4ís>Š ÝGWöð 3º;ó9Çœ~è?¶-Ž}ãdŸÊÕ^'yz°DB;i(€šÛòà´¬ä†Ùi—ß¡(IΕDÞܘ5ç=óhX*gÂn[1 “s�Çvþy×k�Å4ƒt™3 aÊc‘_"åº|½KŽt*4¹†�g¯Â¯êÑO®Þ¨A÷÷ÔMõ>AXkJ úa6M�G¸½¤o×Â7¼ÊñÄ/*CÃvÈ œ¼= „«××rËšøUÈ*µz¢�®£êU~;„D[«7Õ™°¼ð¯5úéCOxCÒõô"Ç5&vï‘辌“}iO>ç αäO°‹õ �†Dïñ9Ìpë}�åŽÙnt£CgWþÄ ÕáxùügËÕKo<Þö«%׃�䘦îé§¶ŠwŒ ~.ŸÎ`Ý® öëÉ�íÂy©ÕSóƒKÀ4ÀozʼçÔ9ø´3Ç·=[ <Ì#$lx3fÇKÞÛ¯3÷Ÿá ²¾Zc¹~ÂP­�ÖdZŒ3Y¯2B«Ao™ûì9 ¬¦Ðœ2Olí²&îZcÓË©NÉŒÈ ³ôTR_AC�›¹ééð²#rp®E¯‹TDŽÏøä³›ZŸ¾ÜÚ\‹Iš!ãN¸·wüq zàÌõeŠbþ2Þc±)b¨ŸØcK^]ÃAn|Zxœ“×L×÷8"Ö|Ö‰]?ØšÐX,ú>y›ç¬ËkÎú¦Ì=rž`!Ǥǡ åsßÀè„æ+ß$búÖÓâð­¶å?v¾3‘œzöÉqrj~Ççý°PªÅÿ¢™€GûòÀÏ\`¦ŠÐÚÇÝ|鹜Ø;<×|ü³·­²À’áÇfwži˜ùt4pñÚç6 �{}r8ÀØóôÁõ¾¾3?µ(kß»‚›vÏ‹#Ï=œË›rã‡'ß74ô¸Ëm§ë˜¶‡{}È @!›Ã Z ›ÈÂ$Ú7¹EÖ¶d¦¾Ä;¥ñf?'„þü�¸þMøøO,> ÑF±> iVMÖœxók–ùliì|äpNÜ%X®ØÇvÅkj_{ÐE^¬˜''ü"Ž.jR`”%Ý£V3ê·°;0ó5¥îyEŒ¼CÄÆ*#öXrßP¡�ùõÃN° 9ê[vŽ=XóOß½We{Žrkk®æ÷‹Ï*…±§ÛøAîgj;­ëο#½‹»Êf;�ð#1©ºf)’îÕj¾Y[|ìMáÄô0–쳆Ëfa7|㣠|¼™šŽ¬áÉ8DtnˆI _Ÿô¿ÿ‚·ÞöŠ(|ä‚ãéí>ªèw)ázòuèñ(rûíâñ9- aNŒQ>9Ç‘ëBÞÀR£ì¸üÓ›h kxaµ|MëE|Ý:6€E‚£Œ›ÖN­-_‹?n?²žTª{ qˆ´ï±|ôÕèfí-õ]| ã7Œ�˜JìÜ5Ì"Üô®6kØm|’,<øòcdjXäeocwÞ¡ï`X]`©IxnÒÓ§ÖV#HŸŸ<¾ �•Ú©Õ}»¶²iÓ9.y3Œ#Çc¾<ŒOîÆÛß 8¹rèÄ×ÎãÜO¸ ±xgјdö‘-Ïó�ü@î"à\”'‹9°g~°˜l §—Úäv VÑ…sW»�«GÕt}î°ƒO.h¿iL°gœúš‡Çõ7߈ßâ£�þqÌèYòWÅK�²±Þˆ†e”;Aê;ë=ñš“}ã}Ì´ŸgâÞ9Cà8 �¶LÜÑiîùå ȎШX¢5ˆÙtsíW#&~¬G¯…ÖALÄ%/Zób«^øöœ¾î¸  ¶ÃãÏÆu›;yN°ÕþÔaŦnûaˆ1@{ë‘Áµ5ôoŒà4ÅqL¿Ìã8\’ȱTm4™¾`¸b4'K£:»ŒšPYXžœ¸«s<ä±r×’¨SÿjRÆÃ'pž>™p|£<¬õe>™]»×±„iOü–²8ß±Ù¦;ŸãšŸšR×sÌÆ ç¸À`÷½-t[/ Í× 0/>¹g3öÚ¸Œò’‡l®¾c˜cKš¹^ö¹&ñ*ã®KŸMG"ùîâ€zÝ„à(pxü+œù4¶‚ŽM“}jÇe˜Äš�× jtx4W4ô…6-€õhð_�•j¸€':~7�x4èâÃ5þ÷úœÓºÔ/ÎÖ&g‡�:ÌQÉ_O‚RXO¨å$ÌñÉÉ.hô .äÍ–>%’s ކ¾à2qOžsŒÑnÓè\¶×^öÖ‘²ÃU§vy"{Ù�þ«ÇZsÞ¼p(Èú” Ï�]4ûèqáYU…æñÝéÑ}¹…Ù°CMH^MnÎ[ÛŽµûÓhz—êk¹ƒuAÄèmMòvëÔÌ[Øò�ì;.EjûÙ ‡ŠÛ:±Åàõ;ÿx á<_r€¥Ž}bÅD—?àôÉñ$jŒ§"8úØbJO8žsF‹—á°““ó‚8 ×9¸Ùaò�‚Ùºw/üÊ6¬b<7w–ðýEOpâÚjšãiªðå(CÙhU@Ô²8³j=öS«ð³�c�-�èkÜpŸ““@?{¡4›Íyœ-Þ¥Ë<#šwÓêÈG«Þ$ Ïý¯É©Á¸Vó´¦ç^óc¦‡dõ“| ÄÉ”<ø°kÀ¯['ö±7®Åx§zŠöFYg‡Öõ%æäÚo‚í—ƒô«œej?-[·ùe©qq,Á{_÷NÛà�$ÍêëŠ<ïýtgÆ«Âw¾“ÿÖI\z:V“†¹ØÄ$Šùj8}<Ú¦™½ðY>„K\‹y|p0ˆ—ë‘+ÂRkë~'7ûÌ¡Üã|RI+ìÜÀfB.kéÃ÷dKx”›ý˜/X^Û=0?¾¶†×pöj˜Ÿ]|9&¹ÁŽíÑ™hÁY‰“†Í×qæ5)ñå“mó¥<Ç€8}±>˜¨zêj}Íhþ´‡�ûÜî0aÇ-Zs8.RœãóçOêÿQFði$|¾‘Ò>R;$h[²ù¸¹%Ÿìù¦)Š�@ñúš.SÊêzåw ^óIúz¡·-“¼a€R`Ï,¼Ñh‘Cq^Žo1 Ëã&Óµ½Åˆö�ÿýØD•PžtE½Ö¤øë˜�/J%BîbñÁm~ÙR½Æ Hd´‰“ðúâ1q^ï(ؘÆÜ£;\ïZÀÒG?þ®xÑ;·6Ê•ëòSê¶ /z°¬×Y­ÌøÍ;»‹–ïƒ97•¼OíX<º£êÙ�žÔ�w¥ÜéÉ0ô‘ùâmä­0¾±Vž ÖloaæÓÞi©“sÏ�‰9+Yé“—ií…XO¬ØÝLg‰7\9)È@ò§Û¯Mˆ_XÅ»A} -ŸýÏ ª£«¼ãHñ�_p­È·AN›rÏ[†.O}÷`MaÍ3/OøØùZOýæÐx´çÄ3ë%íä4­0òAOΧ&À/Nù7·?u›¯rú`Aæž[“-Nj[_xº“q�&“vã Ó‘d‘ ÞAî\9š1W{‚’}fõÞ:\T4‡�اÏÖý¢< „×ù£ìPØ;žc}&G‡’²9 ©è~fÔ}zÆ\Çj/`ìó±ÓoÀ¾á¡™ZÝú„^ðÊíL=âòIuN×ö¸ä¤Àl˜dئiåÇ¢ëMÑ‘sÀIËÚ7HäK»tr@ QþŲ´nÅ’Ä;'Ü£‘:çdßšoÓWæ‹;ŸþF©O�¶U+sùR éÓÞófÀËH˜Ì¢Mj-|ññ`­@K,|ƒïh‚‰ØöÛöØ~ûh`ÖÉã´Ðsaô8æœK=ÉŸ{Ô ç§x­©ÁæÍ·Ÿû£uÞ”$—o(È·›ƒš†ãÒ‡&óV\rø©Ì¤ô)ÿÁFph³¾ñ"Í$°G{jçñg0¹á‡ÏrUoÞ\×Zí³˜ùr#ÍâlsNrÛ/Œn0îf¢gOúµëÃJ°UÑ“£ÓPÙÁ‘a7Ñ@k™ëÁÄ[tvã2ÎDTÿs®„Ÿ%%i"àuéÚXà8GS >6vÓ …AÛ=Ì ¯ŒÚù`²gòܬ ÎÙü¬hÓ†XSûÄîo¿ýÖüß}÷‡ß¯·;‘ã$pñ"£ñ›“wsçl�éó£•x9ìcªFÐ ö¼!Ì›}Žoy#�|¼ôcBا~g2W’k+ØŽ9ø“§"bµÇ½ËZLe .k÷OB0jä`-·ýpèXèÓ‰ßÿ‡¡\œ­ 3u•`ß�&|ãiw¬æ¡ŒŸE/e|íyøÂ¶šN.ëV{=µÑK¿‰48¶$ïu„r솚­MPöäò 8ÑR ôeIOµŽ+ÞáàÉÚz5ßc�Ç»}=Æ„�v2iœy5g¹7ÂÌ�Ÿ‹š'ñŸ0™}3@Nn¾�'Ê„C›€ÓER¯é±†uúb Á�±{åËc&ŽlIŒ«y¼�6óÔÇtœ,……@¬—F(•€_ ðçæË�¼ 6_…i·ºˆ…&*Ƨµù;7‚öMzŒ†ƒ“ûzÄj|ì™ '=†7‡ëq?‹1Œc8aá¹9 €'Y~OJ´cìºl3XUÎu„åCi©Fk�Òž3Ãõ“­`ŸYe€ÓvÙ`VzÙ{.Û â,1Nçú­ÉÆY£¾þ.&QùF[“&6ÄiÏyä�[°Ú‚–ã,Æ5P›ÖÍMõ7Ð6zp0‹P�¾�êë9Ç)\ÄY›pOW±>졇.±ú’òRrÎwç[-«KtëÇòQAFói‰Ãú;g�5 vÇì¤Å a†ö>÷*®“6uÄs45»u!9!ň¾eo½3º)¤'Ñi�RášN¹9G[ù§åØIíØJW|Ò\½oßl·¬h8ëãFF¸œwŽÔÖâà%M羚lð1¢§Çªµ»FîXKï7n[¢Ä qk5—ÖÈs>&ðècFJZ£?ÙPà‘þ"s¬Ö¡~³7 8|#¿sb™Ù›.R:Ïj޳`Bü˜´˜f{ºA—¾öFøÁ7+uh#®—�~ŠÏ5 d à­[þ=p a=.jåݯÆÁÈ™ƒhóÙìÉÆÁ �º3´vÖòcñ³¶O¸Ö«É gb»0ŒTî)�8_læ:îð¤‡'³ñdOï˜aoŸ ŽòGNƒ�çÔõ›M>ÞèÁ}ê0#úpÖÞ:ÀlÜ9o­¤cì\ZŒùdßÚ â¬Yµ¤5OcXâàÍùÁáØ¦½Ä´ý¿u súœWØÈ?½ðÀMˆc‰a4–)öófΚlÄUEc·!Þþ9oíä#G2=;›º1¢T`-!AÈ' èìÜH�V:²>€'x0'¼›³Wµ˜ÄÙb+dýôå«¿ áq �Mc§MKÞH<çIô�‡¨psÔ‹ =;™‘vù< á‡ÿéoŽ¿�ÉK,ü DÏ^„€›>8œ«Í5§³Ðžðž�NX¤2ˆ%†¯ÍçÌpwæ2�ep£Ì/ºš;`>Ù#DߌÁžž;$>üúI Ñè˜Ã¬sä�\j‘Á\8šÃhºbý‰þí?]�±³æº¸?EƒøÕí²àz¹î§Tl�Q3ÿ;1b| d¯ŸÕpÏ}cÿÜL‹pÚ83dÛD“]OîF£9Ï.`9R*NóÝ&~Ž4&}ªÂ’ãMϲ"\ñ(ÈqtäO/dDX6ÿrËÑŠ!ìq%C¾í·Æž€Ã/s~Ø’fý²=Ùl Gß\æ£Ìa|rÂïŠÝĨ?Èja*ÿbX&�#£ÕFm„ã¬ÌÎ-GkšÎŸZËŸs�\ª Ð ?,ŒÜüÎk c1‚×ðMëm0$ˆ`1çñçøíKR�=Ú€ý .E\ØñÛÈ\+ϵñ·²ÇþôNIÝÇ�žqÁDÎiƒ—…¾}q‚77Ò‰Û°UÓ~\ëuˤF^rôÎqˆÞòÃj‰´àA¥ás�…S9‹¬^Ä'cJæ×p‰ô²Ô—ãŽ6_áaIÝ\ƒb‡f�0ÝáHZû*#)Sö+,^Ùµ•‚ð\*ïì„«¦Ôó\#üAòMß¾†þ�{ÇР̽|ì]›ö®—5×l9òœ‰£šJ±ócÀ•3ß9N¾¸�a ¾éI®âÜÀxGWI9\Ãô�Üôk¸£öG×ss&ùж«±yÍi†lª‹þ“ÂvŒÐà$Ú¸^¢)çTt0ªøÒ¹æ�ïð·zŠÐŽZY•[Çé‡ïòͳ‹=†û0ëqÞsÅÜÃ)ÈY?>ë•d> A=Ìâƒ�b’#þ3‡s¹ Šà“‡ÃÞ¹‰‚óõµ[j�ÏÌÀ?� æôÖz®84èË–ëõ  Î�/ºÈÍWä乄yÎ?öÂæŽ Q~܈#¹Çës§À$Ý*÷l‹ö)�ôr=*‡y brHOô™àêHoX\øã'¾>Þ|ÐXåuž ƒ^æV1)âv� Æ-Ã^ÇÆÜÞ€¬Š§ÇçœÂAæYý�÷¨AõêCCû„Ë’„‡fÜãÜ~Ág¤7±k›¥µÜÚ`Ü:܉>sBÐá|ZûfeH-ãZ×ò�) ίĆðôرÈLOá4Ž¢áÒ˜¾{œŒ‹sˆc[ÝI2ôz4�¹¹Fû¸”]×mš~󷬆†c½b5,{†mÔÔ:îø ”Yû‰ëÈßxÌ­&ήO-6¦{ëí±ó|¤ æž/£1€èŒ2,ÖÒZx?¸÷_ÖEM÷(n¦ãN~´úO€�Ç!§¸5B3ÙŸu(#fô@ÚX�€Í•$¯·çô¨»¸êŸ“5æ ²6¡¨#i-‹óåZ)-˜mM¬·ÚÐü@k‡G8Ÿ8šÃ�ýyY;iò±BŽT¼…Á+¬—\à™h°]ÿœ£qè®)ŒÛ'Æéš­¶ÜÜ!æÁ¢1_ÊN.ç97ü S.kñœÒÄXW÷èAxXðuV ¹xò:CîL¹�Íá ÎvÌbÀÀnEgylîßú£ý£º@¨Ê�%/¶„_}î?:u±É�»v@þ�“ç…Zc×ÓfJK‡HÇJ_@W§µ‘Ïy t¨skv4ñù€NCÂÁÂòäé7ˆZnàËa{×ÚYo �«ñEØâyá�¾Gwh\ŽktªjNKÖº/VV_.víÓM GU$CyÙ5¥¬&ó²¸Ö+[Cn³¹yqš¼Ö‹VáÏ zq=~x3žcI¦ÆôÅ™ïdñB1ÖÔàÎÝGÍoí¹‰Ž1P"? ð›Ç¢¼úŠ-¤ÖRÛúBò´ XߨM^uɶ›Õ«/y›N' !ªú�üSáã &oiÕµÀŠ©ëœk·ðü}ÈñÍ4€s(z·Üîï&åìßRAƒ5±Âði5®Cœcäà“wßèø|’ ,¹ÝÇÇä’;j0ˆ~÷�|�î7báÑÞõ9 Só+ç¸üb¾×c¹•X}CÁ@o¾XØÂFƒëh�Äižx¦ vOµìÊ<†Þµ,2¾€Õ�oJ2ýNÛ4—ºj†H1­u<Æa'· ú<uºÖÄ– �íg¿ÆØ“~R¸9 Ê&08Ïœcõ¼±x¡rÒUÚç†Ûkü˜¯û}2ÇF,I¹!ê󖵂 =gÏë¾ÆdOÝ{‰oÇ-’rÎ{ | —2Ç­IŒ9ê Ô£ÇÇ£AÞ9:�Žo‡‡Ão2—Ò;Å‘ÆÏ1ü§¼W,:ð£ ^ö ?K°YßöÌÃ�~ˆ˜ëØÈ‹U?ÚçÍpûg¤Ì=€}Ò�øô?ì ˜€±¸p»žk 'ç.&´»&-8wœ3ËÔž°s`q¨ž9âæÓù€}�‹éþÔkßÖÐ-'L¾¡×óƒ4·� ’^eÎ7 dòwøØf,¿yd2Ò¼,R{¡î-s°®]=üøN7 bœ ••˳l®»v„§‡‹ÊçÌX¦U“’“'|€½�ռĭGŽ÷:[’}%xGn_—9Ö:”úJ�È™›rÜ”`Ü9ÏZA<¾ç&©ŒéYˆÂ¯3jVF-”¯Ï®Žä²Q^€aaô•š±_üê`"vN„ÇNM×Ö›ñ¬•›¼fg�Û�•~FŒ=ö•¶#¬ñ[™øãò9ê4”Oû‡«µ”,q_å˜Ì>Óçx}ásžæ?=‰eÄëÅ©é²Ån° á éò˜ç¶Ó@ƒðó:‘ë'ÉŽc�R/¯'‚øDû:.;µºï}Ì�Ns£àœ&ËÒ&\$¼Ÿ W2†HdtŽŽó+Z’8¨mÝÏ�Gt02`óšM�sÒ5àq�V®újyíÆÇo Ö j�¥5¯6ú½Õ’>*ÜØj·_6×ëœÿ°•røö&p+>¯9°Á5=ãxú)�jô¹B­„£…´Ú1æëò…^C»�Åóú‚¯­5)!»àOïÉo4ôšxLÓEdõæ=J >ñžgÅ)]¹~ŒÏy×sŒÔ®q8κé9yýz.¬®¢X8Ö+“�¯ýLÅð!ª}Èœ½6õ²z´hî>F"ð¶2qíäá ìXÍø_4J[iÿ£ÖÛèíV†W,p,«–z]æ_&ÕfÜMàb/ƒ)b´63òÙÙÖô;1¶ W8ò°ñ¼åÞqNy5Þ ¿ˆ|òXóø·¯ å€gVK~ìOžÌf·ÎæÆ}=©Î‘i¾ÅúÐ$ÃÄZ%XFObOµ |¤½ØsàKø^ žAêx³¡õt@Êœm´{ ù/ 1j{ç˜_{ϲmg¨6Ëè‹—2%g©úd´ÌöÁK0±oÜèôy²€{O°K$~ŽLˆcø¤Õtn¯oh9fʹޝúôËGÒ¯÷FY–NG“„â6Ÿj>7ÿVŸŸ|ÑÝ\x'ôã½VÜ×µ¥?”±±o.ç¿ú‹2œî="%fisÏ™{­=¨¾RËâØbø´Å› IDATŒõ†àÒ»ZMZ€žœ’XÞ …?ÝtèËHq]üèt˜ûèä^/uÛÒCÉh~×.×é�“`Ð�Aá&ÿnìë\pâGµö–FϲŒ®%’í<˜n‡6h� ¡3&ÔyŽQ«ôdøíAijp)Gò¼ÏztMk> °*~³ØV�íæÚqÉ›ž»gW[üFjœ´jbÒ,m9®8êËÌÈîÅƹ˜ºåÐu˜',´€að0Û§ÎÁòæß~‚{¼¸¡gü‚|Ý„.ç<ÄXª®³ÀvŽØÀ±½Ü¼) ¿iWîÖŸ²}f;>lùÅKò!ñ{}ZfzŸœéO;˜,ýOIÄs�‡Ö}n°æs6E(T&_»D¶7’ûíùéâálå&"í\ÆÎg{Þìš“°ö”@4‘Ø7Z4çÓŽ¹‘©cy®9N4ÅÇAÜ£§^…{Íó“óã[ê²×«ïðhâ„ôJ`òW@´ =o"]#`hMr^|ãƒh±þs¨k˜ÝZ4…¹�€~rÞ1_�½ò4ˆ]ƒ[üZŠþ²4«&<¦á[ßysžÁ‘“N– ¨ºù3â‘€1ÙH'Í©•7Ô¦Q�9µß5èG=FÜ_?XC=ú÷ÿäûþû<x>bðxó7þõˆ}úÌ^�Yôypebå2·2¸Öwj"\v?–\–âI/¹Nÿð�÷ºÊE‡âš^“ =~Nmƒ°·5QB´Ùb{Tuº ×¥h˜z¯¾^«‡üÉ·‡bèm´¢µî8;#„Žï8ÅçnåV=ö o¬š/7ùö¸­&µ;/q'³§]aO 9Z‰ÿ¥¿2ðXp¼ëj>sÊ\îÌâcžÞqÃwza]‡ƒ&ÙpÑ„ç@6u�VG�‹Ì; •{‹4 Ò8¦µkÜôž^3è«�èÒl~Ñ„5Düòéº@޵›cYì‡×¬‰'åá—ÉáD8wë«1çÅó˜_Ï`:½š4ó&~¾ÄG�Ï5ê!˜}ı:Ãý¸ËÁã€Bæ“m½Ã³èMàPNr�yüå��ÇÖ�7ú aŒn‰pÁÛ/xŸ‘ÖÅ`O~Ž[qÞ÷ZéÄÑ�4ćŸýnî­_p,÷r¬>"—+±˜i¨žMù=ŠqÖ¹sE~÷)u¹aœû rïèÉÛ¸X ¼­Õ5•w6(Ü Ó=ùC�õ°ûÓ[ pyP NÍŽãcí|ì#-»¿ãÞ}µ®<Ç(ÿå_OÌÙ\/»ÕÉþ½=ð ¡â\³‚¿ªa9 ~zÂÒŸ¼…|!Ñ5‚c¤Áå +ó�2Ö¼Öðhœ¨‹ÁQ§|‹wù—�Æ0ÎÚ«®ÁÍçpLK ²®hÔOµIã4!85N_F¢Ø ,6™‹gWÃì†5þУá Í ÂÁ k]�8B“ÀðÀeÓ³R^DE7v:;œçN ®yH5mK ýÜÔ[?ƽQĶ’É“r.(æCÃü:ª²/Y4²„Ó¼í øá2Ç´ëÀr´Ÿé+Çi²“i¶rƒ�gcÜÓƒÝJ+wzNþüæ3}:v(‰ñ «-d*�E§"‡n�€Š›öÃÄ�Áo9õ5ÂÐplæ �µ…8:=§ãÒü¢uø<±ÿYƒöXýX#ýå Bõ ¢•mÉ›'ÂÏKÂóä1EáM¯±…Ç1Æòæ‹zRëM+¿Ð Dëñ *~ÞH ”h$*fçé"M‘™7v“ä KqîÉo6ˆð©!°�±7O¾ñžóFù9OsÓ‚£Å�ºö1=jíòT‹ðšŽõk_°;à‹ í;÷c™t2ñ¦z7&œÁ±„´S„Y–& p,S²ÁÇ+?ç þùî‘ô1NÿÎpDO#kÏ!d�¾~ëÕ“ß3µ&|¾¡»kŽñ âÄ2¨wsï“$6毡hz|äôÇ¥ñÄf�-xFž[RbnÔ¢‘·Üi½ç58lí•9RWz©låE$ßñÅb='÷~ú„íæÌ¡®Ý|�G™kHLª¥—Æ&åÑpú.÷±“YÓçÒczŸÐÎ�:ÿÃáÁðø÷ú$ùäs€Ë¡ýtN×!B®£™kΘ{¤d )®Ùc²ëlä³[1èÓûŒòâG–Íàk8_ŸD®°‹F(ï»k]Îk×åd]¿ÕÀU·yµÆÄ˜~/„YWROPsRdBÇÒGê7[òÒ“æ?‰ÈÕŤ,—=´\æÖcÉä�ÏÓæ¡NGW~ŽÃ£ëñ%µØ¦ËÙ˜;\h×W´¶~ÁfÃ�ØóZÔyå|åP¬žS×¾Ü ‡OÆ£m¸·\Ë»û"—Ûsa±ù9mÝŸ\‹¹üp¾›÷¸®úxþ`ì¹Ó*"$ÂQ�kÕÆ{ù?ç @3œ-ÔZ¿Œ« cF{.&.¨6's–ƒNg ×pZ'op™?‹b9´h*©â- éXmáå`_oÒç#›çT ¶;‡¬�dx“!³§lÐÔì‰èÚ¾à|RI«Ÿ—Þ)]P�ââ˽aÆÚµ�ùÉåœÍí59F¥ø|�O›ÂEŽÔÀ…‚0�`ë…§&× ­i±h}ãv[üâê(*Ôµ¥(‡b>õŽOÆçÆLü'ÏÍ#ã´îõLvà÷$XgT&’È«GóO�—°f¸×ñrûa+Ì´³z ¹¸æcÏh«½w S*àvf“@Ö-µ,O#‚„ãîµ�lÈ–a?Óî˜b÷›1ÃÆÊ…¹ç O 2/oØt´­ûáÛ¿Y�Ñl6'6‘“´>ÁÍÈ.zó¦kõ³30ko½IÔÀ×yñYNFA‚ ¡€®Ð²G#9²ÇëS€·�(™�>.ìã0=«l¼Ö~œôÁ›J0á7 ¯=aÞI®åY˜_©žOŒ-s�‹Ä=ùÑU&íð Xùæ�2È&˜¶ü¯œ×XëvØC½Šõñ;xå�ߥA^¦zÊÉ+ç§ü"¢_üøFF9¨á›ot¤n­…^�2¿EõÒÇKö´1€ó¸ª©.Þ’ˆƒáÜ~Ó»ºb÷VМ��7ÜP‰˜ôD6ƒ¼nÒ“ËçkPra>@¡#1í|s³�Ú­Jss:_óÔ–þé±ÍŸ{ûù^øå±ôâ-gŒõÐÄÞ±‘*ø±XŸùê35ÄõŠq}Št§Vr€gí�6 ªg„—}b€s,qŶòƒÏù4,°ŒåÛžt‹9—s$÷ê»o–+;VGÖ\홇+µ‘ãá¶n'ÒKÓ�C«cÄ„1K3ß§oß”—Ï]±)õŒ‡kP‡Úø\²J-}G§r÷¾ Œæåæñ˜Œëc­¶‡!~¬ FýÉí(Û½n#Qúr�Q}ý†¨à³ç*ÁÚüòïBüŸa?>ÛÙXÁÑóßk‰rÚA¶à�³¹¨ç±L-`ÿ£>©X¬LÒFƒIëÌ9µÓP Ñ1ñ/¯çxÙ'vRÀû:àÇ@YTDú®¹¿AaËM#×$š›è`m¸{¼ú wƒ.‡IXÍ86Žø;þÝCKÓç^ÇS¿.*q ÞzI >%k›—aOïn‚MÍVNPyžÓÇ$:í0m.öÂýÖD>”_ûžË¤‡Þ~•s��©­AÝóqžº¢ö¯R2”Î¥e1\çј×ÙàÛǯúýúî®joÄ3ŠsŸd ­2~ƒ´™Ž[`ç£jS.ÌýK>ìÔÔÊ<Ëæ´�È ’ðm½óIap§uÆ4Õ©ù)Áö‡ÓÇ�Ä¥Ü5êäÄÇ Œˆâ#Gȼ>’ä/ǧ!ŽYp9ï m½Ø¥\¾è¤Æp>‚- xrubmÊcmìmw"få±5siñ{ÍzÇoÙž—6©ïè ÚUè<ñ;NÃг|ã´y8h&¯×‹•=^Cz dãxèkûÓ?ÀÕ3^GÊžã×½�aúЬóœMhj·þGç`M©…Zýc»Ktì±§uMg?øì•9söð lÊ1,Γš9ÁôÔŽÌÝ3YÜ7ü}*³çj8C˜ke3úçÑ Ø˜ž·&VÀÈn¡Ø,ððX+Æ�æYõ�ƒ¸•L�8/º"–¶(6ž˜rÈ®¥ÑÄy¬5èP]½ù—°ƒ>ù¢¡¡ìLÓ~ì_n¦ï­œ¶Ù½¦^~4VŸ•QËTÇÝ·pHµIÜ©0ñ/¹úªå0h¶ãhŒI«ìjLÒÄ¿ÙÜ#åâÛÙáð¤9ËžXùòF—?sËŸáý}ÿo~ü#úO|þ¬‹O˜ç7Éù7+NoÛãÒæ¬9Þyc¿^¸ÎбNk“€í-‡7Þy&äÈ �í¥¨Á‰Ñߎ.Fz�99¿âšþüœ�Œï¾ûîã·û·?þ·ÿýuídáko#™óÍÆ¹Ô$KzšÒž7¹Ï `É‘ DõyžiK—�;ŽRŸ©»g�íÌÏŸöî¦Å¹lÕ]ѱSñ{ýƒñô‚cº>˜‹þkä8eÏÝûp% Ä)c“ëºŘLJ`"ÏÖ�ñÇÆ¹Ÿú¨^Hñ.k÷ σ¹Ò¹_(=¦ö?œR1×vÈYGóái<�C%'½ãÅ:)Èç©öòµrÓ#GöÒ�†úøʚΠФÝúŸmâ2'[ÍŹ6öüÜ<`qå:Dv‡9ÙSˆŽØ×v?ÖpZ\j}êoM: ÚèÑá�ûfé©­\Ö(<òl“J¡�ëT»bÛãVÁÑ‘¼é½Ç³érçór !>ôýµxü‚Y•Ï r°6¥¬²¸sǶúÌà;`Ç– óæÝv4ÙqÍ©ºç6¸Å¡�ÓÃz”fXâr£ÿá¼¹Îë ñìúÒ*±™Q{ ‹þ<ŸÖ†žTG²¬'oõ¶¸q‚½Ï‘iwÒ€Ì� kdª }� /f÷:þ¦ÁxŽ“û`�ÑÆš˜…ûÜ‘·«ÉÔXFOŸ×ƒpÓŸ â…RS'�ÝLmÓþŒÆÉçÞNžQ:Ÿ|ùx.ÄXyä@i-JÌׯ‰—é*}n·L‹¼Î³jƒ{üáYݾœ#¦²Í2™u2eÓ…ëÔÀö85–×ÎCx(�9yѹd¶;›ñ.G]ðßl—Ìî[j=Ç æ¾�i6Q„V“æI7Y̧}û�ƒÏÕmŠ�zÇ>ï‘ÃCãpU#Ç’`¿¿*OjI× ¡×ð2¡�Êý¢(Hø›ªlÔšêP G*½&Ž12âeKŽ OˆìùO@tsa%ç ÜA°“’¿Ù€œÑXð9¸ù-ÛÜ£–}Ûž\vh#kajLlpº±ðcïM¯ %k8‰{‰µ‡4Š”Ã<š[9ÀÛ¿…ö©Ã‚ O<&ý0&Ëpkîüãvlr'°Ñòg]9ÈL1vç½kÇà0‚v!˜MÀö õt½Ú?=cQo÷Ãf/~MÌVí>/.Ÿ°Åx^Åt½ð¤"réG«õʼÄÂÍÐÜ5‚ñ☃ÁÏ—xOŒBÍ7?g°(¯g&‡�œÛrðºs=~sÒãí¦C'è ‡íŠelÞô.MsxR·õQË©#ÑöÍîý aA¤|»“3nòÎ%wMÚCúê�m½|ZðüöÛ©;^+P<Ô±x¸9{là‹�=Ö)ƒuûÅ`FzÞZè³ûUÎ�íá„þŒÕlkr¥ÞåÕ 2MÓ£ux:ÄL„F—ëäj¢¬äJ›âªµPíâñ‹%âîãvÅ+М‘íì6­nó Ïq?9Ð)ès¼�îôÊ1 ¼ûΞ»¨3DAÚ¥ùW…:a{ôå�jþÌ /t?þöãÏÿ³ÿÜÇ¿ðÏÿ3?ÿùß-PEhö¬Cô¬I¸œøîIêsF6`j‡ÃK°oy\+¾cõË|Å�¾ˆ×)ª‡ÝóB] *r5Œ£.–ôû·þÑ?ûñ/þKáã¿ýïÿëüO‹²ç<ð‡Þ,}òV›¨‰g�Ÿ†èµ¾fÙ-Â�Y?õ˜¯Ï—\¯„ò×Îz»E¸2x’?A†'õ-ßgÝ áfî÷ßåº ? 2ö˜Dë4g?]äöMC´¿'\L7ßë—!š/ŸkK{d�þ}bÄ*àG}’ _~´ëX=�®¾‘±?=�oy�“8r=Ú­Ç>¿ó Cµƒ£—,ÃÁİæ<`oŽUÆB‰Œ·Jp웋œ9WÀé¨Yh¸ñ‡ç¾þøX�óáß [Ôíf}„:™Z,àÚ€—zY¨aý/Ÿ´ºovžô"ýæ›Ï¿ñÏÇôþÕ�_üâç§JSW¹WJæëÁ½¿ÄXIƒ½Ó†@ ¶p�“ýs}ÆÉ7µÏœï3b¶ŸcEÏ©ü‡ýþàW¿û»ÿÏÇù_ý7ÿñòŸ~üÎïüŽ~I¢›•ŠËùA|˜�¯ó¤{òŒüç‚>ñ¼ë‹¦œ“ÜØÌczÇÄ!§ò€ß¿ñɧˆ‘À�ÌÒV%,bu½^Ê"”·Ù¤‰‹eŸ~ÇW>‰>^²h(Àù4¥Nß”áIšˆæõyÝ9½ææ}ãïC 6š:ÇDS™¸v‘@ß>?áÇDo4מrÑ™!½êŸ %.ï‡â¡.D7mñìxÌôßÞ‚«Gž’ß°ÝüË ÌœêáPóòPJ=hÜ_1äx/}5M’¥&ìþ”8œª×'Lìnô$66·Uþõ-¸d´�þ'k0ÌÓ_×F_ÑX ×Ìäu¤6lÎàÈäA¹– u 9&�+Á[¾`gT€ $¥À›Gä¬Q£˜Ã!Ëy‡#"L`2Ã&«åÉ SY…ÑùŹC ÷@vËì9ÍÚzÎR6Åω‚kì�72ÙïÝ—ùã"ÐëÚ®5¸¤¾¶òOÿñ#¡HÅù®‘^ÙéuÞó<õìø³çÇš“Êø¯mÖ–àÑß<ŠôSVˆf»o™7Íwù`ÃnÞ£¹Må'!Ô q$‹—³kc»cž —þ‰‡ãàþ9¨”ÄH—Ï#ócϱߌýÑã£íÊ=Mh¦/Ó”¼Ñh®«°Ïiõ5�s¯½:öö™ø—Ñüظ_±ÇÃ{¯ÆÎåëqC¾Þ‡yà­Ãd?Õ¸ÎKÐÕ®I@„1÷ì^¯Wɹ4OäìæùzÏ?/ú/]ŽuØ´’�ë¶Ÿ ÉÙ‘ã¤ÅcŠF™¬,<ŽQÿ¶_ûœEZ×ðŠwb­Ÿ ÎÁ(ÿÝ0ò.†'[~ÃûÃ÷ß�?o�ÛÚŽ ‹eψrXb×ñÍO<ºTäN’ûðFëUްŸ>}ë?èÓ99”Yö�ôËxø« {´¾kÌú‰«�×Ç*ãE+ÚÏo—Qyôâ‚Oc|/� ÷DýÝor°1ò‡<ªþ&t]øõƒÉ=ÁMŸŠFîƒc¾±Øg�%¹ØÃóéóO­‰cÞDg¿\ì3èq§ÛE\V›?pË×~+Ø\2ùX‘0îÔËø±3´þæÓgáõbRŸ¸kÆ=më 6s4ïøV‹ýÚx-§ûHß/¶zé˜VsT7sâx1‰Îõ?Ï}ï?‡~Zr<횸/üó9Ž“ì¬ó+šÌ»8A9Oþæ=Êã½Ùži{éGuí\¡OÁ¹h×ç3ž8ïœôRŸ&ѱþñÇýB ~ ‡ïéYó$‰k —GdŸC(Lè‡ë-4áZt½cÄ2óú¤åÛŸþ-¾�OÞ$„ÞþÅí_ÿø­ßú3ºù÷3KùŠóùF­ÉrH®õæ§¶bnüËœ¸Ñë"r lL�_©�†²ýšÆÛÏ� ¿i: bóV~>õñ»¿û7>þ©úÏüŸÿ×ÿññãwºç›SdˆŸcà7–ZsMÿA�s8}\8IR…)±aZ�Ö¿œËœ»Ï�(‡:Šá�i�¨cøè×Bi6�×Ü´á í7¾±ËµèÿðWÖf ÕwæÄ½O.üLRëÇ^¯ Ñ�ºsÎõyÉ‘ÙÜq`¸Á±?åã±Ãó&}tCíú<õúQ—»‰Gè©q1”EmÄæ8L£øîf;€^¾Ûs|è¥5*ü;õ’±:Ç“cñhY^ƒÝßôνnž{~8[+|p'OXØ.ß�‡ÞynÔñæù›O³fPsG¹é #Ç„ù0™¯–[ƒ¯Ã½�ž÷¿ù›ÿÀÇ_ý+ÿ®?ÍgÂ÷ÍM�oköKÍzöÚ|<¾†›m1ãPüz¶T†ÎÿŽ/OŽ{ÅðƃOíq3ð¯ÿõ¿ññßýÿãÇ_ùþý�¿ö×þoõ7Ç…Sh7tøÅóûød%`Óoö{ÌÄ–SñyciŠÛâ`=WóÆJ8xlçy‡×è\‡ø¥Aî<�#ÜÉCiÓ·soUïSAüû…óðø™“;ûœŸè“Å4l�÷26ôð>‚O‚þêW dz稊ãÜe,µ½�ùîÅ<¾ÙÏ9Š´hÞ>ùÇO7'¹žÓO;ôq5�`Yöx¸5xžbL‰8sÔ2óõ™º� NØñ½Ž¼Ù5ÙãK€ÌôЯ+µæ9üh, 9/ôKx¥�*qÉãD§ßh”]ßÁ]�&ÖÜ»>Ýæ:/õšÂÏKêå­qÇ ßyÞ£´æ·4(\oõ±FÐÓO+ÁÞÿ¸’3ïoõÜíã�5õ¿öðÊí¤à4îù‹¾ùôp ö6Eý¸ÏM§tÍý×5�\~ͦ0ûߨÂsßq.àE±äÛq‹†!³¿jM¯æ7÷Ž �›=ïð¾k~ŽóŽïK.Õ´>·c¡h:Á{Ž}ßó»ÿ/=sN‘£õé%¯3t¼y�®/l|M‡˜–0k*Çô,¿cIPM/ø‰á8oÀÓõ2¸'Øê‹�û¼¿Õë#=vÈç\œ$Ð2Íìé1-D¶Ôt¥µë±?5[Œ"~üÉ�SöÄp¼yŒÓG?ç,1<-ô=÷ñt¹n;6¾Ñ‡Ø IDATòµ�žèŒ>0Îsú¨I{–_RX/ß9‹qéd° §§%Ÿ&ø™7Ïæp�ÑØÃ/ÇüKe¬xxþ†kï˜ÃwMðçý‹ÿ�ˆ[ÜD¤¶^BÓ¸hž�ý𹤿YaøõbqãEÇý±Æ?¾ƒÜÎâ£Qû$K†%2‘�§\Ÿp]“ô Í\BУ½/,"Þ GØ3d� aûâBÈÃïJ®*!€õ`¿ù#ïxÙ�O‚Æ=k�{-óâAÀ¶a>Y˜ú …à ;æÄ榆7P' áZ�Ê{ 2ébBº0'§Uòf´ùŽNÜnFC_4(§Ï‰;ÆØ G? [ux“Þ‘¹½¹˜ï‡OM°ð7X8LNCÃñpˈ]8çM8–³Ú—Ûr„;�6ç\‚”±ü>–1±Ýr¼ÇF~bœ_MðÉ—„·Eø4íÔH´‹÷¤Óé�Ã=: ­’0–òùñ±óÏžäüÚùÖ4§Ö¬Eä~Ì;¡É—Z°¹Ø6_¦–ëŬoìß0;�8�ŽÅb½\¦,´�º^£[ó—=¦)ö0ãÍ®´ñNJ žóÈZ/_zÚh�±y6EÏ䱿è9ùâ7Mpš£~ë×|çëtзu¯ ‰õT“„_×¼ŸýìçöÏüC?ãæ_GêÛªÜ,§KûI½ÍCŸ&. Ã=¯vb%<>&Â��©Çì[7ÆË+þäŽý°ÐC®½ûçDp±<~ùË?þñoý›ÿÆÇ?þçþÜÇwߨãKý<ÇŽOUñ”èÉø'¼ÉñÑñ›H?g>´ñõ‰åá ùnäê8éù¨ÒR~cLn³„ÔOÉ.‚5Å¥©KóVŸÖy¡ hç«�§y>¤–}jŒ#òhfm’r:“æŒöí˜^øqB ú 3:G޼ˆ¶å²Fá¦gÇdköÓn>èÇþÑ/!¹;7�æ§ò½ˆÓÂ|ÂìSt`=ŽD�˜ÔƒûSïÖ5¨é‘Fjöôƒ¦rº—sS[çšLû…¨Ý—oy°'WúÃÚ\ÓanYš{bàH_ˆái,$§6{Èóh›Ï8wÜ8L‡QËß�3ú…�®‡®TK문x”¢Éy�HH·o éa8‰à}Ãs©ØÜëH{¸§Áx!ôíôËç~¡ÀÚLÚœú€ƒ‹ßbüúšÈj*— Ú˜3NëðëV]ü'À!Ç{%¼“˃_è�u8�p gÞµŸhâj°åÅFñ+:ù>�UFj6Ÿ ¼´…€­‹!2ÐpìŽòýæ%‡Ù\ðÅB…Q“ƒ­ÃyÅæTLEÆÊ÷Œa±�5|Û;Ïô=AæçµÙŽÑjØÞDå²2°¬}V_5Ëæ¬rFaë99yïãíQA›§Î$�.’âG’l¾¯½ºõ¬O(¿†ÌãOîá‚™GÍÕýÉíjá!†Û€ôH¦®±ŽdÃ^ð6XÇ?Xü"q¬ke©ÄÌï¼³!*v‹+’ 4[žs®ÍÝÝò9â²ù…~µ$²8¾#t=Iȱõrfmä‹öF¹Î£½y—gšžšÉ™Ü<$ya}÷ýÖB¼ã÷~ÎÚœ¦²»½´]!Ä”õ3¬Ë1² zÜÊ DÖ‘»-òˆ /–_†”+Þ:åâšÅ:¤žØ÷ïo}ö !§§„’Ï"` {ž,Øï9ÄùØ4Ö1„ûÅcßÍ×aro~þ‹_|üô§?]x+0sEωפòâŸvBOèÅqÇÊ•'Þñ\{|ŒÃÏâGoû87îqr½µŒýxj›‹XúÊ›žç~ùË_Ó?0ßO¤©ç~ˆ =¹3ÏŸéñF¼~~äNµ4ß×ød…›Í lj||ûüQ4cÇÏsmäV$hµ^âí#ÞˆçMvñ&6XiÔãÀ¹d LyŽr NYÙßkCi?«¬Á¸g·ÝoH@8‰‘¸]/YI�•¾ú5EjãOUý '�â]x*Ës QÔlå,2àF‡{_]ò$ß@¼ÀÖã�viœOkA§/)ñþî?œxòýÆ»¯}’ã¹ašlÔ”Ç�³Ô�㛬°‡ž}ÞdСdôùd’ØœCvëióV ¼ÎD�äãÇÿ6žØ²7Ûût‘ùË1G[ã§÷'ÙÈEìÎë›T¡AL@ÅÒ:sD·6Òç 57RÎØÃŸœOà<Ú‚³®™Ý×l—»Zb{ë´µù™Ÿ>²˜ ÄI7¬ÿØûÛ?þÕå_þø“ïŸüø÷þò_þøƒ_ýÊÇŽ?‘ݱ¡–o~ȹ�û­ó•ó�üéµù&[�¿§Æ¼ ÀN\âïcãóÎM}²Å}³`"äðרgøu¡\;Ÿ­»5z.höÄk®cMÎý¸ŠÔÈö}Âã�ÇÇ�ÇNæèÁ¾ó10”K»øa&;}dîË®ü u�ÐWâ8@X´Õ§ É7}ìïGάÁ™¸8²­Fæ`ðÓy¶çñ­ !ðçZ|k[¢;½ü«¤ê Ü�5ùx3{®yÕ>?Ï�Që$®”0X£Ûƒ?— ™\G ›dJ¾Gìô¿<„`+iˆ0rƧŽ;¯—ü´W¼vþEÒIbÕpõxS’Μۤè'ÊŒa“áz¥óá Ìaá�–X{×µ¥ÖÈÅ�—øjJzûz‚í˱Zªa9´÷TfZêã3_ó° cû^ì{3°:$ðñE¿xœ‡:l�:¢b 0µã{œOM ¸ëã£å8‹%Î:œî©ÅN°´qÊr_³”ƒBí¶&MÌ—lÌÉŸÊR;¾Çb|×®‹44¤¶q›ºƒ}8\#v~†a¯qú€ƒ^4¹yeÛlxäiMØ6\«øœâ*â>ðòÅx¸sN$6Ç-X“÷·ùËÁ.üoÈ ðÌ“åJ,ö:/�C?û`V·÷uæùF×Ê~Ù \|ì^bÈñGä~±p­‡O_c|ôƒ‚–èæcï• «P‹uüÁ;ªç÷ á‰ë�йÜ˹=ñÓ9Ìj!Åç=)¡Ž ¯ý¬i¼0 ¯ƒí×!íÉÈÁ͹?Ùy¥�/žýWmï›ÄR:8?Q1Ów40%vNörM‹lò8&;pÌ€gâ­ð çr /¤b4Ãbì']ô@ûzá)=aR;¯¶a+Úxi{ßðtxãOxB=6‘Oß•)�r{‘ {‘å0Ö~ògxØ:®a¬ÓSÍYx÷1&¦�ž¼³ñDvJ4²þ2E?ñÃò´ 4À“%ýãbß฻Xí„ÀÅ‹=Í} 5zÇ-zbÎä:zßøy‘u˜˜ž˜K–e/®+‘û‹\è¯7zÃá͹ ¯¿‡¿žÅÆvy§ÇSGrA^¯ó›i>.�}õ!¿¾=‚Ýœ>ãH¶ù0¹»öÝ\Á]æœîÒ°“Ý®sb,Oòâ5µQyqäŠýôÊ/zv²žZšÅ}Ù<ýuõZœ˜—?9žõ„Ë"�<ÆùzF{aXìéÙ¥�ÓÄ1Øvœ £ô*ÜÓé^q`‚a·æ4HFÖq¢ÝoJd`>��F8ðßb*"°kçdÕ\LŸ7Æy±ŠvòJÌ»Hå„ooúò�0'‚ }Ès~£ Iç�qþqoŸq(w¯GÔe8ûân8ç#Çüÿi£!¥ãÇÍ@úöí·ºYÚó´o¶è!ãWòÃÁ›âvN‘ãG]ÐbZ‡7Çe¶£-ÀŸOê|…‡ ù&� �—[Ÿˆ4úOsÄÃs7§IôôX€õ9’<œ[Ãßn¶ÚïœD‡1`ç—‡—A�+šð‹!ÔNÒÞäχ¤ ¹NÿÔO˜t®5ˆÝyÙ[š÷VEÚŽ|Jkz0N“fþ´¾Ç�>VìgÊ—'ßÊ•ÇYj” Ac«QÙ]�Pëw¸'4aÁ>nò2¨/µ2‘ ô£þô n4ñã¯ÍÜk�ðÐ_S›Œø¬³G#¸ééuÏmèeð�ãœ$�=× '—Bî94¬¡b¯ìî»2€1Œ¦‹±�� gåÉøX,߸m3êÚ”ß7Cª�œæ¦ËK~¡OJÿ“ÿÄ?öñë¿þëºøT¯þiýÙÖ÷š¤—œ«z «cÄÈùðÿ2ö.@÷}uyßþ_¹#w„  ÈEn*AH¼W­±JÆF�E­÷&‚Æ(M#ˆÜ´‚Ɖ6 ú¼ £¦f&ŽÚ‰ÑÚ5jšFÛf:«6^"8 —ÿú|žçû¬½Îûû9“õ¾g¯µ¾—çû|¿kï}ÎÞïyφŸGA¢¶V™ŸŸOá Ñzm« X»­îpá)YâÀ…5>¶üK–8ZÛÚœ#?1W=f€o8« üÆ—§n~ïûX4ïƒDâ3>/"t`qãµ�¨ÍñÝýª­ò6jGéØm½OKŸôNl©\»›U‹p<�üS3Ìô:…¹œ×rÀ×LWÖs%滑†c.|.S�©+(ô>‡+&ŽÁñ§±yÈlGŠF�ü©ÑE]k:V Öõ5Ïßðäýl@þU4Ï‘I¤dÎ9 1æ|¯!hNv&ž#~ôñ�†1µiOpß×�ÚÂÖ2Ü0ί‘‰*êƒK�˺ wwpàÀyÉ<ì��=²¾nEgîX |dL’çžàŨœ}»8¸¡£äDƒÓÞ.ó‹mõPô>B>#tíf,ÆÆóz™|r$f¦pŒqâœsÏ׉�¨^ö‘ kᬀÃ# ‰#úA’µÎs‹y#Fr†Óé—Œì%yÖâÄ‹¶¬šC°’#:ò÷ïEŒÔ0³]x9¿|…¹b¯ÍXÛLsÇää�Ê›s_X¸€Ø—C{/{<©ZZêUyú®S,²F±õVìbK|òó¹]ÒÐ@—õÐàJ+ãø7>”=öÙ�£vÖÔ¹¤Æœu$GrPòfgM8¯½|S ŒÏõÅ(¯!%OñךĻ~›(ÆbÎ`2K�ËÔë=âË<‚ž<Ç@]P‚»0›S\’.“ßx›ÃJçr��;á´Ë8Å»Ph’߬¥O„±-NÅZv©…OLÆ åNŒŽ›ù?ì¶lp˜lP,_yyºé47àØê9ö´¬†sÒ|rs8˜lm» ‚_tá¼`,çóö}/þ šÝƒ‘"-¡ÕååÉøðÂ`w¤±o'©Ciß|íO<+ý¢0'î™�í0 ÿY—"ÿ'÷5›âŸ5þKkã§½§Zw.$/ ‹Š>ƒ½æ�H²Î>Í1†ÅÔD[OËñA§óÖÍ.u”Ö©Ehûlx§ˆ÷lÇ\OˆW°ê¼ãŸ²�œ†9; @áÄë ÞMà\:òRYï A7‚+/@¸dÛ#Gq�¶óÆfÍ ´û¡7jšãHøÚl &ÐòÕ`nÜùØÂ£ºúLŸŽuís�¨Éž<�‡DͧýI"9ä\lí“/G†sÎ�s Ô¸7ð¸Èe¼.ø)†€ó3b’û 7ÒCŒ Æ}ÿ'�ùW¶~mÉî$̵æ’ÛŠÞ¿©iÖ6¶P ‡v‰ØîÂ~ 67›M°“3Ï�Ofö·‰|Á"Ö…ž‰ZuƋȶÎ#³±6ÜnsÎß9 P±ÂIÆÎþ#òí^;õÚN÷¾×­ÇßøôO>~íWŸwüü/þ‹ƒ�}õ'QË�Ïâë>v&™Ú‚O¬]QËׯ³µo¥æØëÁ9â2z(Pr)ß¾"áXh kéÁ³z6或8&qÖ1ùÖ/721‰­æŒ�Ë�/nÂY0árnó>ÃŽ¢Æó6-בalú c}7àáÏþÊY±¶9O7;øã™L¯£d÷ðydö‡{oâèØáØŒÓê[ÏôNÏt�_êZÖŽqÎcZ6Ì“¿Ÿ¦6®þ={çVRzÈFI´J>f]¨y.S_#(‡Ú¸ÖšàÚc–InJ†™T10V9Äœ3Në‰Cšë yê \ÇÓ̘cCךƞ{Ò|×éÓx•kýºß‡í†…Áänã7V0Æ„NN纑2ñ®mì :çjäõU?êT˜rÁ ;7)ÑÇ/u"îî·!ŒÓU=â�{ö=VØò¸´™¨+N¸e¯‹×DdÊÿ”g”ú˜½é�—†žMŽ­;ö¬ÙÞúù”–^ÑÕ®ëg>B¾¶>X6¨FƶÓKÑçü¡{Å`î‚øõn¸qþ¶OKd—–º1ϱuVkËSqmÑâ,ë9†4�>˜+•Í~4öëˆÈ ;=ÌÐ>§õ9 ÇqR¿³–L}΢x4pWn[b¥á »ÂŽ™ö,ÓñdoXŽ?—~l56ÎG\Zö�A\œ8¦õ¥MÒ›³-µoMŸxÑ�3iŒ–P—qkoÅ ÌM7êsö”Ó™Þ™×ê`ø×qÊŸâ—«ÍgÝœµ]ϼ~Œp­$yýî?B‘¤~óš³8Š-›{ëµÁÍ ˆµàUD’-þ ¬Á±·ó”¢rlÑ%QÆó¶-Cä-� s]&‘wÖñ%¸ÿÍ©$$7îB•àJ[üÇ=m™³“1§òR@]2 nÀ`fv~‚¿ à»Pa•„õšŽ¸ÚŠw-5¼u°U‚8VþÚ^ZT²òàÚ|8ÛIÙÉh-&Ô ?ÄÔ‹–pU@ë­äB„fC©“7sµ„€íÔ ƒÁÏ‹�±�£ì4}×RÇ ðñ*Žƒ[8Ÿ9\9¡xý[hq6Žw¶®ƒ/ðqV̤°p½oØ�—ø¨c.éöÅñ¸Ià߉ûpdüÌ~â a…I‚M.šÂ1âé5é>2éÙÎu”­¿}OŽ^Ë8:^¼5Äßu`×LcÖÌþ¶gƒ?jòœuÄsÆ6ÀÝh±3޼\3ÇGŽ&Ê—ÝÆãÓË0ÝÙÏi�‹/�Õ¦èc…>5²*Šø/'Y:×�Å }ÀY àk^¼Ð削TÌsj"ì®Olåê;a̹¢‰47ãÌx‰÷�ùP÷ ¼¨&Obª i…vËtø²ï;®æ2Àfßÿx1~ÖƒðÂŒiÎ�cbð}*œœ°©X–Žž÷ߤ;û’@™ =­}äUO8ß6J×­�O"mÆS†sm¶µÝì­�Ü<Ð  ×(^KÖØ6Ž3/�«½üc{Û–ÃÄ)æê'&ùûÂCö¦5„�çNçbÉø¦Iösòùò Ìšñ<>wêËÊ“ÞÄ üàÛ âÒú„¿ÖÙ(‘ù¼*ßÔ%оC¶Z�ð׃§?ï×9 Hh6Ç-» ¸ÁËI�£»ÙÏFT®8K¬µ"”LsßX6�ðr�îFG�©#;¿æÔ!üËØ²I,bhÜç=)›?=üíÓýØq-’+˜“)u@V_¯…ü86ŽÁVô`ˆ�yÊ�‹ü]SÓK=7¡3ÄÆ ÊUùL™lÆë�ɉ•°LøFpyˆ(éV"ÔC2ê,ÃuœÊÇ7�áÆ‡s+P‘JÅõÀÎa”H°cß…›óC.ìi¶œ9þ¬0 ¬¾PøÛ7NöF†‰'›\C·MÎÜSéÄVælqí#N<ÆõÙÆ~y1v1?;OSÞ9ÖgǬLîÔï^÷¾õøº~õñ¿üÒ/ï»ëŽ$H¢´‹„OQ²£Öç—Ý€ÅïUù"ÜõcžŠU¾ À<”´ßëÀÆŠçÆœc’—=:”=v´®½'ƒÔõ=õŠFÌ®;ýÔ ûLtÉ2A�[¾³£õ]1>o Ã9–}ŒÚð ³î˜šßò3ÿ~nu™˜òõ± ø¶êføL>v¤ê s ÍW\b¢c›ZÎë jš|ؽY 5ÎqþÕÃà4ØÎcÆò²_Ÿì¶Ö–<Çß\ÙhΦueÎËÎÏÖ‡sJô±ó1jþ2#®ûM×D ö¹ÞyjnSK)‰*� ¸3_páYÕÖw�!4Ù�·±¯KP£¦Þ/½Æˆþ AœðÇrÛ™°9!Ç�¦ä©d^Üg.ר¯¯d’æXò£6öüºnœçû`Z?®Ø�ãkpú"ΜÜês®÷ðÂW?´…‘� ç%9+r½ 훲Ék#.ÓÆ°Þû*ĉ9±… ÇØEG(Ï1�’úÑdŒÌFÚŽÂãwâÉ.‹éÚûëÄ›—Á"”õMË>dÐÄA¥x;>4hØÊÝü°¡a×ç,ø^ý¯;²XXö¶æÌÒÀ5XeN<*Øi‹´ÎeR¬}a¸ÙÖO§óº‚µE½�çÀá)ð ŒS›ô S2û…H,ð_W‡¦ÆX̆ξ^ÈÔÜÄ”Î÷p á+û2M2ø‡½ôsŒ‘NVèÀ‡ñ>!ß  OC%¿ú¬Å7÷¡ž1<ÌAþøÑÍcíS˜°ÆŽ²<•‚,ùmÎű°œç†ÛüW nkG.Dq«æx„+eá×Jƒ�|o“b0g݇RïÄèó• e ÙÍ^@”B¢= š˜"¹ æ”â@jÃľŒå_™ê¼(/X4°Í¸¹[ 0ÂÝÿzöõMá÷ ðqZ-³Äc®kZê ?×\}ùʵÔä’Ÿ5"ö\„ùMÂä W1Š•�D›UE`ãÔ»¾˜ì¢Ní³düôÉOÚ‰“9ð¼ØÍN/s>^€Jè<Ä+U1¤õðJ¬‰‘dlŸŒQ"sޝ1k .Æ£b}.Úe}bX,«´“Õ/ÿ*–à Âá"žæ¾8*÷lPpnÊ7-rŠñÅ ëÛ²õä«oïB~÷=wißԙЉÉHÇ;g%jå‹Eï%¬«„¬ûŠ“uem‘uÿJÔ_cɽ?høþ{^ÚÐ9*c ?�Wæªòó�rsî!^mìµ|43e0²Äº1¥\s%9ÐÁ@v>çÑ.ìœóiŽ��žý% *4ïØÁ¾-qŒêœ�ä¨Ã?–—RóH¢Á„º|áá?(ÀY"."°½›¹cÇð*ïn�™ÏéøøE%„ô»êà¸Úl ð±ñŸöÔ››m&�ÚŒº~Ä]âÅæ>¦á3üÉéfq¼ñf½ƒŸZê<”12’}0èóºäÒ® IDATœé›…¬‹=çñïSÉ‹äÂ_9òÆPâÄÇÂ0v.x© '5gl‰{¸²sàkquq±!6ì#«m6»Œ×vU� J¨¹ãè³Ôbo® þpØl»v¶ÅgÓaûÈG>ìøÆ½èxÅ·~‹ÏÔ”ç|‚SglÀ ¥6'ÇÎ!f;Œ6Û•Êp=í‹/zQ<ߨR,¿Ö�¿ó¬ðç�²ѯ1m(ÉŒlãi!Ž?†Ú¥¿ó¼–ó$Æëü$³KøQïõV8ä¹Q¼%ãÑ|e–ó‡ÂJñÐ�‰/¶1Â[ÅÛ5áX´L�Ký}JúãØ#ÃÞœñÕ„wíß|߯޹ŽY“qsœÈ!¿1�Ü<|\Q^?ƒ޽ñ˜s‘µO„Áò'/cÚGZ�§OT³�È,ÿé¤z³ŸÑòÄ’ñlɉ¬[šñ+7q&ãɶ4÷21CªÏèeù’|ým«ªÕË*ÂW4.ÎΈ í8?lª‡&XæÆ>È4¶å›5ÛýÐk äãw¬y×�¼WÛãvœä¦TÖÒu¬¿Ì�0`¥vìSÐ+Æ_20×9‡Ü÷>ïÔìüë(6P€ÒO‰Þë¹×m,ÕÕ/ûKÎcC€\ËEÃ~ë3ÇéYG�ƒ®öˆWÛùÇÖе•Èûþì{€ÄcpNƒe6ÁÂ9¶œ+oÒµ#²÷¿Þ¥mÿ<7¯ãM2löýs sKaRÈë¿÷Zù¦^¨dK}z ¬¹z"=ÏúuºŽ›{üÆ„(œËšHo™za™û‚Z&0}ZáJ5=3Õ†éYÈ8ik¨™ñZ#×a9ÆïõË~Žä“¯óVDs7Î9¾À&‰ÁóH ©§ÅÚìûce×ö怵ü/î_)Xr?9ï{U¸ŸŒààø­‰óñ_j6X n’&²Ó9fö©U'É|ýÍ…£Æ>Ÿ ûÔcŒ�Së 4,BNŽ~’ÛæÖ'�6úÍ ¿¼0A«&ùЛˆÙ:v•`”L=Œ)ù4L=Ö¶ ¡a$eT¯½_cpA*Ž|-±|€Ï£¦�qF+b|\c�Œ°2¯™$ŽHoãêfB\v ó±l|P|<°‘ˆ *õ^XŒJ=ó˜¸÷_+F_�ÕŠ·ËLJ™Ã;8c9áË>°óè¾3˃…mÃ…m¸³~!·X¬Ab¬é™Ûˆr°iâΟŸÀ"ðåÅ1d}Ô¯óÜø‚—"ÀW�¬3OTçÆñ`L°bìÁeÌZò �Aã¸�+ØÄÉÍü›˜j®1ÿÖVH`5yΈô‘˜«<è»oðBÛŽ€-zG“#¾ðw x‹O›qÊ„؃"{¿t™ó@f¼žOdËs•d b£_ƒTŽ`ÒÂ;ãl£�ëj5–x³n¶~Ú§~üñèG=&û¤,nÖþPûØÙÔÎ/Õ=^A…Är¥>tÙK!5NK½ÁjÑ\ÿ¾ž�Q××.rëþk¢ vx鹪Ðf›(±‹0dA<kþÙmN~¬ûNwë$ðÀ·ÇÇ-ߦܸAQ€!°ž»4÷î+_ç2çÆ4¶PòÇ�_^«�æþÐÏqìóŽl9æÙ·Ož© ssöxd=¾áê×p)GeεÏÁ:Ï[ƒ”g,²vžhãó qºg7_p 5§9ÜŒs®¡ðCI|›­�k�¾›ÀáôcLóëD=4nÁ\¸Ä,[pô°Ï¥FúFKNæ‚ñ­KäÆ §¼VMÞ+� ÌÁqÂ"œ‡Ä…[üñf“`žÇ5°hc;ó‹Ç)¯)ŽzŒÿ˜ŽRëÅ“¾ÓÏÚÅ…ý_¦<&õµ=�ƒ XÇ+þ¦ÃÞ8ÈôØÏí§ÏEk Mf3œÖ8ˆJÏÜB�} ì•? ¤2XÅw� ?ØÏF¡Î¸-†ãrñ*?cNNÅ÷tÃ1&i€£Ÿäª‘¸è¥¥5ð]á¤ðűEÉ8×kå/ÿe›¾ÆåT¾ö§žH®¼à¾lð*™«:[׬µ<ý/âXLžu�À9Lý9û8<’ÚhΟ²,KÒY—ÆÁ6rü0³ŸÅ’�Ÿ;ìfŽ÷é9â�\ø² ò(ð Pœ…ЊFœ:‚º·pB‚osZ1JiØÈÚ±æ7¶¶“¯±!C W¼ù3~(‘³õƤùʦqm'Cᘠx;¦C0‰Ò–ÑÅ)z?!Û"ëNÄÇï´g q¬È“¹ö^Xò²ŠXä‡eqË=€öe ¶xgö#W·0¢Ž¹Œ–ò}ÒqSn?þå†é9�ñYœ%ViS?æ†,nûÁÇÒUB®ç�»îâbÖ§w¦~÷ÇF.å5Ÿ‹]ëb47ݹ¸Ë 8@Ì*)jê}䩸Õ? ÛLɱ‘›¤Ñ¢îÅ@×Ù±¤ìÜë­9´ø¬‡cg_Ùm� pFÜô2_qÄ—ØÄ…Ùî‘— ÙØ&ÇŽ|("Ê\Ý oⓞä¨] é9-ݨÏà’Â~Ö±��aˆã@’!FÈ€Áb†=¹;v¶Ã7Ÿ5£õ#–æ­/¸�"Zc˜‰prc 7ü/­ßnCÃ7Å‹Èñ5Oça3m+¤l&Yç2ccÏþ$h׌ú- â©9.ëD�8’‰)�™ºiâúØ bį/«Xs^󱃇3øƒ–šÿ~b‚Ÿ¸Ñ•Z}Ð!ÜÞúâÉ…s#¬ùµ.0Þî>µAaÞlÆÛp£cl¯à_œ—ªŒÆÝ ×ÐÔeŸµ‰˜ñ}õ¥ O}êS�ÿðG¨³&}æÂ1t¶©É™'.Ñ×Nç,× 2måäø�¦æŽ‰¡¹9�� YX¾xÒ<ØP™>lÆÀ€�?uñÉ2äœíò³¯égÇÏç‡ÀKÛźœ`ÜùØ ñòÙ°:\µ¨ ¨’l˜£ã!!œàVq�ïî7(ò€Øë§ÿÎåL%» *Ðë\\ô$ê²�ä4µØK¦AŽlìåG¡K˜`—7é`8 — liª”®<‹…yoèM4©ˆ¸ºLRÚýæÄ›±s™ðtÝYVŒÉÛqæ•y{tøhY&�›ƒôÛÞøÚ YÇ"hkSñ ØDä)<#+†Ò9Vc[ ä¹fÉ C=pÚøÏsr©êy•§ßHƒç‡±VæÌÀpó‹šcÆ¿kå:(¸a›ÓÃQ�?Ãa/ÙÊßF—›=OÆ4Ç*y÷à„ ÇKj°³ŸZ�]pŒÞ…õ�Lµàç4³�óÝüQØ®'ûæ<±’2IÎÚTĵMžc³j êTBávÖÙ ‡Ô490î‹1S”V~@Ÿ~ÖÂ2bœ91ÊÀa¦>ñ°°kƒÈõl¾›M†®¬‡ÐuF|Í_ë<†µll‹� î�q¸€{ß{ÞsÜqûíÇýïw?¯Q\ꤙ�mž*ªŒÛ�<ûÚ©»fŸ�ª�̺/­xW𞜲ß0ÐCq �gú“ÆÒñÄd}Ìm/Qù¸fÆAÎqÜ¥›{¿ôË¿¦að”Àгñõ7[ê˜á tIdžó0åß2¹ ^Yùb^v š})kÅþ�ÅA¾Ù75pKü Gµßkc#mzAxK€Ì7y¸¢vËqɇµ'.sý;_  ñ»õÙf7HÇs‚1 Àº�I#÷H\äªh`×ÚØW~å�Ž67)¦Ÿ¯5öºØ½^0ú4æYÍ1ˆ…·L½�;¿€,zúÐé›SÿF 9p“À± §–c¥7õÈ1±|#�»3Ã11hþg�››ãù¼š:ðï{7:.7,”;1eo>⽋/‘0¦nÌ�¡q.Öø—ż+1ûþúöaåÌð¯é`pƒšF~~ñ9¹“+~ù÷<ÖUY€L»ðÍâ/ßFäE³êäÀä$ŸUKË““ƒ°� 5™º´<„¥<¿t²ÃéD1°5oàÒðí˜~°P¹IfÑ.¯}MìWCÁ�¾.効ùJoÔf ÒI˜šä°P2_P¸fàà©Gv öñÍ3öSÙñÌû¦¬×­ú¢|{!`Ž+ɼþ˜"TË;l™¿ÿ¸×½îeÿå+ýÝwÝå}Üåd?ÁÉü•…§ +û™´úM í ºáæwCËþÎ;îä®ÁܸÒqëkqfÿãæ½o()W°º¯u¿Ñ—CÖøÄ%·~S°Qtžqí˜L×\èáeöôš[&»„Ùú°_õ‚¯ø§Ã6›?:Îyr4ïøö:Øi|̃úG§o`tŽÁUá§fê}£Ñq‘çã øFe'a+lemjÚŒ¿?–BûCþàŠXþ˜QjOÊ#Å•|~Œ§ØÇ/:‹ZC&2@=zà4ôv}{.û«ác‹E¬¢±–�¤‘g²�-ÆZÃQ'ª|MaÖ—ð�£&Q�Zô²åG:óó|tð]óÉŸ‰k-¸ä­»c[9­¹ìˆA3æÔ:û€E9½æ6n0âkÑh"°tc«L|èkØœyM±Ž LbÒ9¶}0«ÎZ “™õ9fÎ5šº/šzDlµáÆ/Ð&JrMœãѶ³ñ>c  U¯IÖ£˜kŸ°`¸¸Ófb28íà¬èÑ¢ç+-k0þË·1lXëq¢£X`é—ƼÚcJ#?‚Æžq0±ßõݧÎcmjiCfÎIƒášŽ-X<ÄKçÆž×Ö¾,“â—§ŒÏʸaPÅ;ñ4Õäk¼Ï¶r;EÎÛ9:Ϭ§ç› €We{þá<Á·ºy-!¥ßµ_ÃS'櫹3m<²äw7àˆ¡_¯™èiXD–1²øžý.‹’´ëÙ* 5qìp†Ãè臅E=E Å•µÞC:~z�6f1’:ïÜ "�AðhÛÌúÄ.yŒ|B«µå¤%ñ¯-®´«sä‹ZaÔÖ� /;±b(!Z'Öû​ljϳ#xŒ2â¤FEicëvNÙñ£sìäÌ.e˜ÁÏOÀ’V ϰ™üsÅp»3:–�ñ!>´&&mž|bÕ)umvŸñm¬êAŸ�M˜ GD==" <ظ,g©e;èƒèx£2VÆÅž|� ¤Õ¾VÐ+¿¸œü±:vG�È“ì?½ø[˃ÁØ¥–âÃÜñÜñ‡Ó˜ÛnÕ ðÓÏŽßñ¸ûߨþ·ûßõ]ÿýñIŸøÉÇó¿èùz'¼ž«Dô܇uls±Úç'�¼÷=ï;¾íÛ¿ýøý?ø}ËÃ3>Ô$ûE>· þ�õ�C×ÎŽY?Œà•6Ï—“CdhO d‰¥Ëä‰y“8¾Ÿ‹}–Ðçÿ­/8žÿü/8n¹UŸ_È ÙÐcK.¾ˆgî¼n8þìío?þë/ýªã/Þý®DQß@¯•.‚±•pö7èÅ-·{øÃ�ç=ïoÏzÖG÷Ñ&øæù�¨ZcÊ\¿à%?‘uÌ·DÀ¹ÊÎ_pÁô¿éæ[�g<óÇ—Ù—O~âãõù�¹)¾×\=5éú#Ÿð§Ü«6çŽKòÙìði›FP:Çá2NˆËqó3?÷óÇmoþ�ã]ï|§ìØÉ•“Ï!Ø…XÅõùEzó&ñâÚ­:½ô¥ßt<ö±�ÕáÂ|ü�'ïsž||¾‘Éoüæ¿9ÞòÖÛŽ»îÌ;´M_~O)ßõúW}èƒ|ÑT“½ë¢(7"äÀÅ\.„Ó7ÿ–ŠÜùL¨6ܱ öH§N #µ÷éôî»síÄ•±~)‹K8¶éR78¿q‡[BL<>¼ýwï÷�¯ýº¯ÓEÖŽoøú¯=>ü æçµe;¾W;ò~ì‡þãã¿øœç‰ˆŸic"RËWc×�ù¢‘ÞÇâ��ÄσA^4çæ^Ø–±I~ÑGúíÍ6Ö›5á ‰ùÐG/úFÝä}àý×ó4~«Ôh‚P[âÞ|‹>¿Kï(SWÀI:Ö‚|‘ǃüÐã9÷qÇg~ægñ”'ÒÍdßì’Ιaç‹tø ܱœˆi$§ í°©�Âíbß«ð}¼ 5>•�ÁXñ¿õ[^z|É}áñ’óñ»¿ÿ; )^,›_×ËŽEä…®um-S[ ä}pΣ¼[Ãû™|îsßûO{úS�/~þó�§?õÉ®7<‚—:;a´æì¾­Ó™_gM|¯y�7¸¡3GÉ;®}õøC��þÈz¼þ;¿çøÙŸûçZs½óLkMƒ›o z­N®ÐÊú¹ ¶½f›ñ4â62Ž®Á¨öeÑꪛՋNÃó4<12¸|&üX>hUm™&-=sÆ®~OÇîâÆÍzÕ]ç8ÖÚ¯+qp¼¬ÄzG�ln¹é^ÇSžöÔãK¿äKŽ�~æÓünÎ�ù`X“�.L»~¡3k-.>N†Êεö ™Éäûî+©C˜2N=“}á+¿üùÇçý—ŸsüÂ/þòñ=ßû=ÇŸüÉ p8 Ó‡Ä�-ël_xØõáyáýaàcŽÏûÜÏ>î}ï{Ù6ês…][\ôªÿµç<ûø¨g~äñ¿÷Ë9»‹wàù�ÄH‰=\Ðy=Z7À šZÁ Žy@qö!ùÑ|Ѧ·yãòèG=úxÃ÷ý“ã#žô„ü1`b£Ã—ø“wÎsÔòq�}Œ¾0æƒ�?Ї¤_óƒ=ŽŽ–�C2º]ÉšTEÝÉ�9yż Ô\¶ó<â1<‘Ñl–øv�Ô9 t=°8ò¼Ö €4ü[78´…�,%‹ ýÖèš¾â°rƒAbÜXÅt ¥òZ [7Õ†Ÿ‰n dL¶x PÏ– j 'þ˜ƒ›wiÆ£õ=cßê˜1ð£6ñ·õ6tÑä̱þAI>X, ÃìŽä‹ª:�5¯¬µaÙtŒpkŽWíg­µkÌ~/[müá`´˜kÂï ´æ]3b´fÉpYe [ôè­±b3¾h"XL”¶…4¾ð×(þxÉŸú s�L³Áp�p Mïø¸ òëj%:ç ý’)¦m°ÙÄ3Å6ö%n1ä„%¼ÖŒ�ÁÊÕ1I¤Èö|‚‹­ÁYÇUó�•ÆðEMP«QÈ3±áG &’çÁƒT9Æ—ö¬Ô>؆0%¡¦( IDATó�r~ð âà Ųál6+ ]~òAίì9É™ÉXGmÙp�:Xã-#C¸w½wÿH 1àÆÆ×M¸ÉŸÙàÂkâÅ(yr£9­±ùŽ®z`ã`ƒ1Üw �zº‚Mï�5³±}lMoªª_ŠIÛ‹ïÅš��_ÉxÛO<³¨ƒ�1mx3\I[~ ìk^(Ò+DL¸’ع�©™'Ö8‡€$�ÃW6rôØöÚHç“©À(.=Ú²�ë‚Ü:,N[]snmöõ‹> |Œ»�]Í�mù�ƒpœaÜ8ÄÞn–!œš`[oÛâÂc­.«Åp0箑íÉ5Jó&­<–¿Æ½åP±ï€O@çì1û[Ö»ëűûщˆL°yÁœ•PÑ+5€“ìþÈ'Y©b7×’ 01¿«y oÇ„‡‰nýØï5iæ3i¬~Ô¼sYò´¤"þ™‹÷—'xt}ág›áÑ\ `Ò�` fÆ"žæŘfŒ‰Aœ<Îf™Æuøà u}×`íu8Ç�#{¼Y›JMþ�º�Z…"m£›<›¸ÓåÅšx�†ì¢nA›p€òÛ”`P�<¹u=Ìæ546T GØzœÊ¬jx „_Ù‚Åÿ"ö«ÿú_Ÿð)Ÿ~<÷¹Ï=ò�‡�©UoÜ `þúÉ_’Yíê}QoêSKaó!ùü«ì]ºÉˆêF}ÓâßûÚ¯:óWe$,‰Ÿ¹~�Žú�ÓŸüéŸ_þ_}Üqç"Olý»î�wéW¾x£ßˆÚY#?Æ^¿É—�ä†Xï~¶,ýݲ}ϻ߭w°é_5Åû^ºç"Û(¯¹ !Î9ÿ2÷¸Ç=æøª¯üêãMßÿFûcæwa#þäêœçÂÆÕF�MìiÝßX/n8]¬'8“{`ïäÜcËã&–¶º1uÏíÇ·û«|óÏ9Ñ´É’”€Òuû�óÛÇ»þâ:l„3µâ…^oÝ,åqÏûìÏÕ»¿ðxä#~Üç>÷ò¿ÒåµDòmúÅÛ|-Yõ; �yL}w?é¸G�Ý´%c.9¹¬æy÷Ñ�‡§>õIÇÛÞvÛñ ¿ô+Çk^ó½ö=ú—gíËó. òdݨ cn\ß­±÷+nn”›b gyå+_}<ûYÏ8ð€û·z?:÷G† Û"³¦äêµ”Äy¨÷kõN,—ßÄ]¹;¨Ÿ¼�7ö­ÖË�wš}°¾Íö[_ñ’ãs>糎oüÆo8îÔ¿ë�· pMóøæ_Q¯QK@ÉÚ:n ¼{é_üÂÿz¼ýÏÞ! ìÛԞظæDðœº&Bÿîœ×6±W7þ‰N¾´ÜxÍþÁä0…¼õÖ[�g>ã#ŽûÝï>Æ2}¹ºg®6Í¥¨�ñy¡åËù®züü/•¼;Ky`Ëù„wš½ô›þáñןû±:&p¾+t[—…A�N’Nfä&"¯qm˜3Æ�ÁøÛFãžsÑŒbÙQóýuüÔHjÏ¿±?ô¡>>÷oþ�ãÓ?í�_ÿ�w|Çë^wüÁþ¾oxrîñ×~9B‡À‡n’ßÇÏ®k¼xj(Œ¬*Qmž�¶ÜHÿäOzÎñÖÛÞz|Í _p¼û½ïñs y¹M\ÎçÆãqóJ;uÆù£1ø÷iž§}ÜL®ì7¹OÌópúÀñð‡=üxã÷½áxÊ“ïõs,RÇýÌ)¬‡ÊË7‰¤¼8ÇK‰+X§þÉà\YHÉ>ƒ Öp7ŽÁ‰ÿ9½~ìg\üâmt­k]ñ &¾‰Sš`hª”ˆwAâC;o‚ÔÀpÌ+ÅókÈz!›f#°Ld„Øgè�Q IPüYg$j;ÛS}¹;Ë#s\ÓÒ>Óê·æ�TÃfÅC„‹‰¨80®ÞžÈäºM†sê‹z—?úNµj­~%`6j¾`p½œvY9Ó—·õ«s×8ÚZrôó¹êG~]çeo›‚ëŒïVtú§ž°_)÷dÈzŒþ:-´£`|ñ²u’ÚâË+È-³\"VŒñ1nc�µ š»rÙ[ã;‚_È®ê�‡žàSžÞRB?‘˜ùŒŸ±f). ìc�žéðG5‡kêgóÁvý1l~×ø¦$˜oªñSk¼a“Xån\­%Àžš„�t¤ ÎH7ð.ÿ"½~ñD׸6 �wR­+SÛ"“½^¹—Q.4@¸~+njÃ~©Ap̹#%ÁdëXè]øú–Úgû.©Fs‹Ÿp¥L¢ÄÄy¼6IñШMoî.Ûëè-;9®cEÛàí8‹—lœË»x¸·Ò¤J>p§¹b³Z10’'�•әè¯ãxê�x1hlÅߤgMM‘b˜Tx™)¤³ÁIÍrÖuì"ÅÕ²Ôi<Ç剤ˆ! Øj81Ý]�Åk>É»<ŽÃ ”±D� ϳÞä'ÝE lhð� Xfl Ff½¦­:FmnƒfLa¹¾…Ûú„IVøùÆ#B5¤öÓ4û$Ü ´±»ëÎ;}£î~á_úE"6±Ûs�‹nø7†í¸Ð±�#i�{q�J_÷¯œˆ/ˆ^ia(!¼­KŒ·¿ãíÂÔE6A¬ÓæÎdá|È©¹_Œe>ràBîp�˜`s覛ôηiµcºA8¾M†ì-ú××/ù¢¿}üè�¾íx�.LÉýFáë£æœƒÿ…T̹ð åxú3žšs¶=Á˜æüX5üßþçï<þáK_ª Î<¿CþfÁóÃqçñm¯~ýñéÿÙǯv–�™s‡yoLC;}Ç»MÇW\-–½]¤»XÍ �RmºJ`¥U§rd7+ŸêÌg}æ§úX_ñU_süñü#¯@~ä9G ’ý{àD’k_T�ß÷{�·þà�OùðÇž7&ìêä´¸ï¼d°¦3À.­Ë;é—­l¼ßra/¡sgS Æ}ç5ÖÜþšß÷>÷>žûœ¿züô?ÿgÇË¿åµÇ¯þƯèÆqŽ¥|Ö›Œ©ƒàð!ûI÷µ‰�`5q›¿ù›ÿöøÙÿéguó^�Âï2´Ï‰‡<7�çørb;½X7Ÿ-j×i£ ñ‘¾>Ì´TŠsÏûï>¾àóÿ«ãkþΗé³Pï›8 ÿ^Ö˜cs§ò b±#œ~´kH¤ãEyó9s÷Ö¿€ßöæ·Oz‡zŽG[ªÛ™ú�Ã&ö°º¤åØ­µõpÙlÃg�á5Ùíj/×ÝÎTzbø¡?ºpóòS?å¯Ïúè§÷_üöÿñ[‰ vƒçµ”“×@ò®-�;玽ßo\À²Ïá¦õÇ<ûÇm?ðýÇówþîñÎw½ó|>¢àò½‘à:Fb@ŸÝ 6r¸€‰-äœK¹Ý‡ Ÿ‹ú>àUía~ØñýŠÅÍ?Î�è];B 'ÎfíƒÆ>Ž;ôÙ‰o‡nxW/Ö¢ÞŒÇÔ'/˜eÍгŸÓh¬M„>¶Ð�SòK.®¤k¾^Ç["GìO(ʯðȈ°ÛE'Ë9×'D°@f®§7ãÍýCøå¦ÝdMgz`1L¬x5X!•^†Î1‰ÇßÃx1-š±-Ÿµ(ç%LsDV>í— �Ú`‡ëˆ{ùÀkÊ­û8f]z#/Y;x¹O(p[[ ÍŒ¶h�ÓKí:Çzê*±lƒ5Ʊ: öÚ��oÉlɺ_¡áÇaÅËëÒ\%wf@Û/1V¶Í#îC*]ñÏ ›œÊò;¸Œy,ð6Ì=g³ž¶ǧ6ýC:à[8Ç�¤ð‰‰ArGa{™¨[ƒp+ä:Åcl5�|Zã.c™ô Ök3 ýø]è¯bnóúcoúÚx?‡\#æÎ2žËÉ©kßs^ ÷l¼yÔ/óvå»c㬡 ŸµÜxÔ6ø©¡3Ò@viæÞWñ×ó<–�•6Ð&­ûµý©âöÌäÏÜ\¸/&'À$5¶טÛ(âÓúµû:¶bøP´­ì0®ÓIiI»A@-ðâáÙ_²”‚ 4ú}\Yc/\ìy †�Gi¤âIQß&k¿‰…Ìzp ŽnüЙ“æÒ§ðˆˆï¥´,&àUŒÚ177¯Ól4k]�j fsAÚqqÃ#ÜëÅ8qÝ3žæ4Ç%j FïXL¨ãäˉ»Ã�Ÿ}åi<»Æ(yì3vÌ^ô‰uAEpõð°åð >[2HÛs1ûpÀ$é¸7–òhfÍñM3'>û£‚Lúá51ü$icáÈtuan~KÀ|›ÌЙUÞ~×uì8™ôxY$Kþ{Ìå‚܉žúUQbŽ)À»º«6˜�‡uã�¼‹“åFì‡>ìÁÇË^ö2Ë—ø’™½\drN…£åxâN>¶g¬�Pèí£AzäÒ Á¥jò·—nâÜs¼ä›¾þ¸ŸnðH#$9KÎÆú%ªžw4ýÄOýôqû�·ÇGAòbþªÿq÷ñæÛ~ðøÏ?ýü/|æ8XÀuµYÍæŠòÂWzϱ™Gò4é�/ÓŽew¹O�þ:­¦ÜPø�yôñƒoù>ý»Þãµ>‚×±ïø&®^Èy͸¹0�©cnˆK÷þ;ŽÿñŸ:žòÄÇé_ìq�`×áÒµÈ^BMF}1 Y¢ƒÑ`ß}Á&è¯ØÆ›�Sñl~*oÑM�Gè_‚¿åå/>î{‹þ5S`>èØØ÷½ ÉÃ.ǽfBý…Þe‹ŒwËQ_¾<…ž›rÜ€ç…3ýþß°CŸÅ±-v<´™9¾}DfFãá5�!Üs7ûêŸýÓã‡ä'|.Ûë[Îäd·ñu*ldÌ;œ© v-m �wükõƒøàãÇ~ìG�'ë&17í0Í€× /m¢>m? å‰q ÆCœôd¨Ž£:‰Ë¥=ÊåŸ [Òñƒ1Çk÷�‡<èxýw¼Vÿêþ _ïâçó®À¶´†77Ún<Þ¡w€òœáç!°dv{ðÛÀiq“€ú=ãiOÖ;@ûì#Í•}fÅeß�ƒ�_öóžƒÇ¾Ä>è}È2ï"ö±ƒdyðCŽÛÞrÛñäyç<àéb‹—ù!£M¼Ûuóï§î_wÞþ^ÛE­}cý®Zác‘"¨®nêr 0ÃÇ&ŠÏsŸ$"’ý.„àË™{ŠT‹bÑØØZ‚:.– o ~b!ËkŒ+v™»öFLœÚÆR[(XŽ'7÷¨6¼îw''ö§�cÂÕy 7ú¼æè~Žº¸pHøÔ�Ûà‚UÛEENà¶^è=w‰ÓýxPÓT lóÓ¨¹!7®�›ú¡Iƒ¯eæH ƒ˜ƒE L+–§¶Å >øÚÖ„,ö|ÅEó±‹!aÓ4Ðoë ÿ¡´‘ù‡}x°VÎ�61ðħ~ê÷|"ÄCÄqǨ51?pÕ�Á�¸æ"̸†@e±ÜrààÏxt¨hø/™u58±ÆTÖBQp~â³ÙШA¶ð˜29ǽ9%Nq�NÎä©GÐÆµÿÔ÷ŒáÑäI ûLHta<˜Ò;ìI£~cçz`£‘ëä^›«MÅ oØ=1#ƒWQF-pç=×2+Î 19g¨)­Þu܌ǀ$W½Â/yØÕq�ú~tŽ"%?®–ÆÆn­BãÔË­>S]ç±jÑ:Oí¡FK/OýÞ¸\‡Æœ”êX×Êéi«—E8ËOpœÜè<'a' Ò�ä# è�(À"žãKO[sO˜¥˜‰ÛòEvÃóÙ9ðWk1m'¸ßcÙúü÷50ªl3cÚaòÛuåµÇ�Aô�-õÊŸŒ7;³ëlësƒ]ÚN½Ÿ)ø¹½O^©ô™¿9 ð:­ö—x1ì‹Ç_ðL@½}ËiôåY\‹Þ†k��krº‹uQ§ê´Ñœl®rö\jÇ>Í2ñjC=H…ù’�¥cL¼Îx'h}ÌHbA§y;7Ç@3mÜñÁ޼ZƒšèŠßŠáÚËœÚ#ñÕýj¡9†µãc|�ó/`¡H‡¼\§&î8¶¸À]¼ãN1 ™Å¡�jsPÀ �§"žÇ\\cñYkd Ú/z»z³Bž¢È}1ìD‡Ò¨S{ äÂ&ÃÄa–Õ—Uû…³Ý±ÆFCãÞ ¢vˆ»?•ýcšýŠ«ZÄØføŸóÀ¾×»]g]ໞº ㆑ÿí‰}ÒXwÇüøÿ¨s>�ž÷��‡„ÂÐCXù&ÓÌáLÜÅ!�á½OZt©°§g7áhœýT7îdÍE$7}ÃQJÎåü›/<àéÞNº8°LròdÌ;<ü'5E• 2þݕ׮÷Ü}ûñgÿñí–7úÅ‹üµ‹šü›è'}âs�Ç}ȇe=,Í�¤â ð>B-Ôún$Ëlùbë‹Ø¹ Í ù3QCF#<5Ð;�Ä�‹aþ5ú+¾ì+usë¯$jì\wMˆƒ›çÙ¿¨ÃýÑŸoüþ±k©è¾E{“þUò¾÷¾åøÉŸü©ãc>úú—W¾Ð"˜Žî�ðÚ¶9K@óúVN\ä<�Í|ÙŒj7 È×úWuM¿œ¤ÙÇv^ õÔø‘üˆã¶ïûÞãYõl[¯wUÛççÂÇÿ©úRc¯Áq×ñ–·¼M_Üð¸ÜÈjnø©y}(¼Q[Flýø¸£µ†¶’ýø0]8`ÑÆß¸ØÅØòd»ê+›½¹†פâÊ>Èç¾úµ¯UŽb¤ù~“ÞhùôÅ@æxÂ={E"öćç{ôÍãœxçÇÜ,O¯¹Þy¨½[»²bqsO¢Ð!öÿõï[_èñ[þc0u…e96%>bâIO~üñ–ÛÞt|èc>TAõo鬷øpã,7ÏrÌr®Ìy‘›Ëžôá9¶Ëgï/Ü«4ø|fí›Þü#ÇK_ò?gõç|É'ë‹¡Óƒ>pä½M«-;�-bäG,�inâ3W˜[b©6øÒØï3Z[σ]®û¾Á8Ï­—Ž­ 8`¢ ï3VHäX£–¦¼¸ðZ!¶¾· ½òeÅŠëˆÖÃ!ö!¬Ìÿ4;s6LÕbh[óçeéf>C=Üã3Í#Ëcn7ºÚÊï2O)P‚Ï °ê÷:WÑZPï‹óÀø{ƒQ¼Dï»TCæÜw¡¶Ö¯Ž"‚̆#¶©q0Ï9#X`­ƒ]µ–üLÍè�Ç‚Xƒ€haÜËýIälÏö‚çÌ]QÙ”Sr”òbí>á—‚ª¥Þ2`ªî»ÀÛ í»6’¯qm# u ÆcÈÈaÌ9´Ð•Kyצø«žì>FŸæŠó‘a;¼Vâ·Æ‚Çž{Pê‹Õ4 ‹ç×òŽ?¾ÍŸ,7;<‚Î[F”š×¦ÀßùØTfíkÍ?²µlà$’°²³ØúÜ$ÝjŒgŽeÏ]ÍÓQ­ÇÎÏÏüEÚãåhòS€&’š ¸l+HqœB0÷Ä x.%~A—Ø�YeŒã[íeÎR0K«uû áîšbL.ð¢9^e!K�BĈºLm°ç‘ÇF[fi³p�ÒË!¹ÅŽœ›·û8®ˆU }Á�T“¼Õ¶�Í9Š.멟ä3ô¶;MÖŒBp2LkîÉ¿qª• ¢™6×ÎÍopÚÙ†BÊÇë:ë̪ Æ6¡æh.Ûn‡‹ÆNØ Ç¢¿ðËdFúÛxñæ¬�¬Ê»üL">�aîа-0J«ÛMlÛbÛúÛÜ ¡Þ~£'•½-ŒÑcÛÜÚÛ¾~£_~U³û©Æ¤áTdË æ½•ËXšó®?Ç0ðŸ9ñ‘Í4öµ�qM‹×X°mÕ§.H†T_Üãg‘ÌWo„ À}ñÁx8¶&íQÀƒðŽPÛq„™¦`ò‚> %p¢»elq½ˆoÌ‚³E{áŸkJM’�{“Fêuž“ŒÓ5Œyêê�,¾P¶ÿ*œ,;öí=h!ÓE‡.ƹÆNšÄã 윓 ñ÷SÃøA0Îk3H¯ízq9œ�Ÿp�PçÆ9uäæŠð�Z²®¡_äã!YÇ`ø¦ 7ü„Ṝé�ƒ8WV nÔô÷÷¾Q7+Þ»ˆ¬u„+NmåO=¨Ï{å+_¡ Níºàê…Ÿo¤Ès°È=˜b6cß�ðÅ�|�›u"”mR ßܨ?´‰ÃÅnü¸P¼·ÞuôŸÿ<n–©:0ÔE¾ü§›zÜ¡ÏT|Ý?zÑÂo¸@ææ›>püäOü¸¾óCsÅ Áóz¹¹O,‚1w7ë¥y*�1·]*$=ëæ†Ë=µ±npAI½‚wu»Ç²n=ŸÏö°‡?äxýë^s|ðÃ¥šRË©©œz¬ä, �{Žïþîï=žùô'ú渥[.‹ºÌÁêëêALç*#ó`xT=¢êÁ-¶ÍQ"[ŽÕ ê±éظ®ÍÔ·±}ì³?òxÆÓ?Jï´âK)Îc¬6òñ¾tFc/8ŽþŽÛïÔþ«Úb=²ßKªã›ïÄåßÕ\/ÛÈY=k‘Ì#6ÂÕ>Ú�¼)ÇáÌiüà烾;¸ë!å:ÏåªÀÚ¼¡úð5•¨Àâ¦ã2'«üˆ–è�Û¡—ÿ6}ÖâC}ƒ Gãpù"› Æ“µº�Ù9j¶Ö«'b›sÆ ü‰aì1`¼Û×fõ…ëâ„Ì„磸;Ïú¨§ÿë¿QúÜ0'w?Tö©ÜHÎñÄ}ß|í ôÅ3ÿóqÇíúL×áÙ|álðmLÙ�©õÜðã³Woûþ7è ›ž(]H'ÜØø\ �y�—Ž»ãâã‹I‘»ÿýp¼éÞt<é‰æçœ«¯¯KÎ5^ à'á_¼ë=Çë¿ûŸ¯}Í«µ¯éË’ôŽÅ�ÁØÏªõŠ2⯟ª#“Øz¤¶k`õÎQòˆ2ær|ûéíR w`eà©=&ž¤gjšœ ïkµÑÑ=øY™!oì“Ñ( ¦úÄ?ã¬xÀ�_¯Ÿ4›Ï˜9 ž²ÉÃÓ]…]=:7õAr2�íÉ3öš_��0-†ø$wcqÙ&äªiÉb5cw•«wˆËXY#BN ]ðÚ�Tb¬í*6—ì\˸ŠG¿t›ï¢0TœÃÁç¸rNø#R�<Ìâbƒ>û"=çìØ^1!À¿õAFÌ�〙§&(¢sN6–^Íé 2sÙÒªó˜¹~ʵµAǘ¸Í�¹�5[ ˜±¶æØ3ߨYR]ûÅCƒ¾ÞslK‚mj-;Öƒx WôômSº%³ÇØ›é%]»õ�u'†ŒÈW‚"_SéΚž •YÌŽ¡ÙÊ]œ<®+=<]{^K¤]Æ�qc`Ï8k3×"Äî 8õöÔĸһOÍ1flÁl¢Åwj_¿ÁÇo�Œoð,%Ø<o]»ÁäZj]­¯HPÎ$¹’0’?�3¬²vC‡éIw¸� QI‚ÆR¤*2s Ó£…@ÜBxŒ®vÀnv¬­8öÕ<ý†…M}òãù€1nÃ_�Jè�§Þ2lÁ ë$#j~¢I‚Ò�˸²Ý× 9Æ çˆÍl½åEn[kÓ¿ÄTo޵L­°ãçš¶Üµæ æèÏ8§Cã\Åu,×"ž>è:3f'ŽÕÚŒp:ãkL¼š_Æ”ÔäÙä@F`kêd ÒØ;¾\,™DÁ=Í!9+sŽÇªªå$—i®�äí-ö\¨øÙ7?²D�ߎRŽþÄó:ŽnåŸ�“Æ'wâkÆ#$l,öå¡„ðûÀ`;:3ÀxWêØÚÐ�𶨧ù58'®UK“ÕIž/ IDATps˜‰I)Z�k± b¯±Þ:Ä ßʉ}Æ·ë…"C‰XÅŽ‡tÀ'µ!7�ã²ÁÆšmF'‡Åe÷“ ­=v†­]{,©)È2ðEùyg.Üêo¢·í¸ØŸñÙrl4 ’âb› gdŽ1Æ 5Ü�a;q¨×ûõnž{t�lŽºèr`)ŽÁF�Mœ\câl‡WŽôİ_ö§Æ¤?ÇØ�ÝÔ`œ—�糩/>ü[ð¿þõ_9~ù—C4ób(ÇܸÎ:Ä7z^x=ýéO>žóœOÅ�_þšÞ<ý"N¼zƒ0ÜNFÔ/âeì%ŒYnøÍ�*ÍÝ|‘tÏñÍßü²ãa{("f+þÌm:æVJÎúþßÿÏï¿ðó?ãú€�!Ÿax˽n9þÛo|‰¾ 󑾉apƒgŒn¦F޵òP6'Ÿá18¸ï”Ö ´Ðñ�´ÝÞkq› õ‹Ò< {®9IÆÅ˃ô@}Þ7ëïRÛþýUîÜœ"(õxÒãŸz|Ì_}æºù·È(nC/~Sâ,î-´0ä±ñº&ézÃʼeϲwkÏdÆåm¯bŒÝkîR,‡+ƒ=ÆWúía±6ð¸×½o=>ïo}ÎñЇ^^_+¾oX(Ö�z'¡ã¢”/ÿöû#?òÃÇÿ¸erRËdRŸÎéÕàýçï|×ñÒ—¿êxÃõ‡9ðÎÃÙý¶8T nrÒcÜ�ÑPg×aòçàùϹÈ1uYŽ¥1 PM‘ ÇÖöˆqó�&6ì6ÏW‹~ÛZhŠ·›ØøhhÍÅ1ì/¡y€-=ßœ8­±-^û3ˆbnEbÃ=�˜·uûÈ϶ÚZj ðö696°,}>8ÄKå WcÞ[®ÎÁþc‹Y8ÁA#ûE Û4KO•mÁöú ƒs½’uýƒ½ƒ)"‡ü‚ü8õR?²î/Žcž›ÍÄFbs0ù¡X¸ŸÂ•=?µ‰g09O×ý¸ÚvñÀÔqãCœ3G³Å>åUw(Rµz;qÙgF1ÁÊyñ¼ðQÃÖý¾�c?×`ê€�1ÕÇ‹Ajd>L '¶Ë2¾3-—ñ]öûÖ(?nÁÂ'6¶ûžÆ> >>gS»î#�_mÚ×®°ÈS“Y ¯vêÙ?°Ûy·öÅ´‘&¸¹ â<Ô»¾Ë?W9!]µ»ÂÝÚg!£fz`òйÚmt {ÙÊš<\÷˜²5Wmk¿bœ&椞ãT=„Md)æ)qBCBHdX×ôWç[ÁÚÍOß•ö<6[mó&‡�Ç+'·Žje›^H;î"üÄ�ŸUÆ…Ñf(õÅŒ|6L{kîb ³>Y#�w¾ g{çX¬ö£_�ä©�$&œ 寙µ†å°*’¸L²¨ñ ;tÖºOæ¬ZGÝlå‰|¼XIl¹NÌr2˜7¬}~fº¨=–Žf‚§§G„ÜEšlhá8±‹Tì¤Ì VûöôjíÇf™ÄïÖ»†Åè‰ÄŠ ¡ÑïõTAC•-ÃÁ�ͩ꨼»Ø[vxT}l l[hì5Îø À T 7S%@h •$Ç"aÛj£†có‰HsÐÐsúà0¢uÿ$‘-œÄб·†ÊgÑhnÇ‘O¼D{Ö»°¨ÓðwdǶ‹Ô“&AüËæ¬Ëð/`mé9N‰£ž›b6d_P3yG ¾ŸWÆfÙÍšN‹3Àjl½æuSÏ ¥ò³ ¾Ü#™Ö:§/Neã³nÆÙ$F+Ÿ±mžÉ�mÞ…Áó¥uø ¯ïÊçË79ÉŸÇ 7/Å+Ž?ÓçUaï6\'Ôâyî#¹ð½Ï½ï}¼ø¿ûûÇ­7ßêòæbó<'æ8ŠðzSÏ­ºÞàó˜õ9q™.>&nÈýÎ]p>á±O8>ù>n½ã3§ ›5ž”"9Žw¿û½Ç‹^ô"ݨȻ¾Ø‡p"·›þןû1þ·b܈EkŸ‚È,¿bÓbÓõ]²Øçc«‡÷NèŒ]ËùÄ« ‚Åo9ž7ÑâBv—�w™>C7põ¨ÇøpÜdõCïrâÆ¹ëŽ÷ßòÊ—ê›�õÙŠÄk¢8ž ñuùÁeãÓÜ*ÃV­E{˵anÖÓ³N×dARèá@zlF¶ÆÈi6P︖Øô¸Ÿú¼›Ãî!™qÑ�qcL·á€�3KtÔèö;î° L>CÔ¯c�Ôù={ùÿ¹˜Ëïü˜8&@Ðâçg渖s¬çâ’˜È}œ«çæQ�±œ#‚ ÚÕ¾ùîÇ_nöbRqÒÃ7žãU¯z�¿z(B gB¦qÌ?SÏOÛÓo·“4v ÚŠuNÚÞ3.7tÛ¸y#¦yÎ@6ûøAôÀã‹¿ø‹•ÎÚWç"È5Æ^­û*áî¾ûýÇë¿óuÇw}÷ôeá2€W›Ö8ˇãÀ� ï@|„Þ½û�^÷Úãã?þeË»Åoö»÷|£¹Çð¼óÏ7Ëâ/f¢.çázÀ�·¼õÍz—3_æãÛÌ+ä—ÔÚÏœç“?ÕsÅ×|Í7?õ?þ¤s`ÿêyêB ø06sñõI"Ó† ó† ç!ôüÐâŽæä075껀õyrù0dÌ…©ãƒ &ìÇCdô]Ä纆ϸGn¿ñÇV?yÎ5,àM@öƒ¥A¢õü§ùø:–õ9OL ‚ãm=Ó#§5Ç͵ÏÑÆlHÙ’ÛÄg ð+Kã]!âjOliØÏÐóHÇG\åH Ç Ç'xцç#³yr»0b‚IÌÜ»6²7/äè9rý4ÏÆ&M»O¥â Æyº `WmdÔ×d؆Ï3^��u”Œ¸j­mnóhÍݸ•Îv f°jž 9üÐQßÚ3ŽCäÃÃ\ÆÆ^²‰¿»wÈÐ4nnt ‚~ÆÎ6àáB|5c�ž1üWoÍía/BÆYg„'v¸]à-ÿd31*)ný̯Êö͇yÇ“y9ÑãP&ž]‰gÝ&sÍí/ J=œ¿p¯‹�™ë†-פd™¡jgI6]�gò@»tL�ºw '�!1<±Uëºî÷ö*7ÏáŠ,¯8*(�’í\†òtÈàLc •ÐaœÖ~¦¶««±ªP®íá1\\€=¾ì–ÿî;í�½Œðe1áTŠ’6 çyÚn°ƒ:ÙñÄ×raJí¼·¸æ] óèäĺ"Ù¦EnkZÂðHcÂH¹9¿°±Úó‘c^Y¿6Øx"ê™§~±JÞR §©ÇçÂÆ’b¨ö'ÑŒñ¡Þ’{]¨)>#Lo¾âÅRÂÆ—ÙÂßdÁdÚÆÁ:‰[—XĹ:çµñi LJ/:;Â:[pÉm÷½u¾q±›\] ÉwNŒû`tÂ;cÙkE°ïFã´K®å¾°…¾s Öò‘Îx˜Œ~ù1¨Ÿ^ ‚›–5]sÄ<&¿1º¦kœ”eK ޝK[àMäÜz8u݆°µ§l�µÍw6"É0<#ž¯Ü1ª��¢Ç·×g [{©M—ùµ'îÆð-<È­æ@7߯në½ÙóØ|ö‰!°änàPÍ&<|~\àÁæF9熘l¸Wsñ™1/èóÈ—ƒ¸Òùݤ²“C0„çÏdxzÿ1Bµ„†²›»#p]ÀœqÖÄÓ³f>×#0¯IÆ»}ÆùWÀUïÁ&;ÂòY†þÎwo~Ë�wÞu—¤Ô!È6vãGT+‰yÌ£�/ý²/“lÎ=øÊ±ÿZz®{.ìr#Ð ÞD?7("qžõs¯xþQ<¿sœú.ËW¾êÇýï¯8“ßò¼.gr½çøõßüwÇýñÿ§Ï?T®ZnnwqÁy“¾ÝøiO}¦¿à@M©Ò¶c8ÇÔÛUó=.c5Û—Wçê[l(&&΃™6nXÆ[z�£/Ol;îñÔš ï;ƼîÅ/þªƒ>§N}W>ûõÍ·Þr|Ƨ}öñø{l.ȉ‡ß°sa6^y�YŒÙNÜúUæVˤ³Á;§6_Ór¸Äz6’[EÏ`9&ªãHVÎV˰uÉ ´`¸ÂÀ&77‚aÁ` ùynºé£/Íð—}üfÝ�ásþüY}šs£ÙŸá¦›1|á7Pø¬7þ�ž2<|ãQznÞðà†moÒ2޽pÑs<Ózz=ô&/íÙë‡T‚’^ï`››õ“͵ÝäF^3j ÄîÔ Í³éf€jõ÷¿ß�gë]¢•)¼‹ØzÛЛñ¡P�ccbäqÚž#tæ2"ÏáH ¥àôÞntØÑwlŶ±ýè3ßÔ†C�šög}†ÖàfŸ÷Í®yHO\sÃX>œ-¹¡ûC?üCÇ‹_úŠãíoÿs?Ÿ ¦]ÍÍ2ǃ�„©+΃õ…$ßöª—ŸõYŸ-g¤Â'¦=Þ8Ÿm™ø2ƒŸ~?èþ8ÞüæÛô¯ÄÜüãÝêiCÊÎ~D¼ÓýÿÃû ¿äøW¿öËÚ/ó%/~~Ý ´axˆ?© G�Ayåü—çë“Gö5t®8ÔYÃøIDþ³_ŸÄ��¤Xö,è'BŽc¤ỉXÉçU«^jo4'½ù0¯;H1’§ž «½ðy~×�aHd5ÉfŒ}ÚÔ¥6_æ'…�Êa0�Y~Æ-ÉÒ#Xü¬†r‹ÁÚ÷]f˜Áù´–¡Óßy�ZòšK59�cÁµó�‘MÆ1¸MwN²V>Fr²»¶¶ƒS ÷3™Xåm*ÂcÎØåEíÑÛNë¦5~RøWµâ1¶'=Èù¼Ù�ÖnÖ­u!FH„�#B*ؼÈáùÜk8"nư[% 7u/cÀ ´-�#Þž�a¶ý¶keËÁÁ—¦ÐÉ?ûds„�HM`x�ãpsZ‘$p39iÆØuÈÀ³}ä]’ªµæ:(»ÕJÝõ‡û`Ž£ú²ûjbØù§ü‚]Çžey5t6 z éàY,>üt¿J0÷më�Ì~æ´[œu0¸†ýN¡c03ζ~Ì\“Ñ;6`Œ­oî¤È�ÖbÚxHîAb•­wŸhæÉÿ1ÈîpYpTÕwìù"7ñ[øÚÏüÒ·³ç ªÜÿ²Ø+G‚O¾eÔé¨V3/ÍÔ{‘Ql51DqÚ�3µ]>–u±4·Í¹iNσa«D,ÙÚd÷b+Ej5€õ;@¬2v±G;MŽøf ½µÂxÃ�±çô» N¶¾v“/ö˰u Šë²ù[Fý2nÀ®¥#L°Ô"9£ßùa@‰3°†EH1GænÓo¼%-ïZ1/GÇ"á³ü1†¯æõ_úƆ8©NM­ÿÿéz°ë¶ª:s_ä^Eìc4JŒ}óXV%ƲOŒ�‰c$AT@Q£¨Ø€Ò‰€h4šÒDš»Ä›Ä}JKQГ²Cl{� Ò_¹-Ôxǘcíu¾ÿw}ÿÙk­9Çs¬¹ö9ß9û?ß9„Ì\ó�åæÌ â߬Ïqä ·q™·Î™8íÆ ËZÊa­Pxo<Á™@ÍgU;„¼½ÉîMìYäó…M¾ð1óšÊ t_Ï–kq“�¤Ë'=Á£9”Zzªƒþy÷µu&`ˆÎ=ˆ&R8Ýj6z–õqÔÏìŸ5Ò´Æ�fgDm©ýh /ºO^(¨K‰O™«aƒÏøÏ™ë;>kp b¨¯ýXs1NÖÀ“éyB ­mÖÆž2?¹âÛæ¾@˜9G^HŸ Y_Vvª¬I·ujÒe³_4a%˜ÛgšwïÄG=ŸµT¸×%>8ÐC³.°k¾ëœñËpÃñ]ÿñ;Ž—¼äw]+¤lr L«‘žTêoÔ…¢ý³O>î~·{è ,òç£ã¼ðpMÖ|.Xô<¤.=‚UŒ0¾°V¼Ž5_.ˆ|ä‡ôñïþ·rÑ §Ú,w&étÝ5}Å+õgk�}Œxùò}^/Dž7¾áöãÓü ­ãn£“øÔÓL3¼&‡ì½°Ç½o'šç¤°'4ÃC \Ý#p¤£Ë;Hå~§?sÊ<\�Îp ÷*�Ó¬9hÔ`†1èÈ…§÷|�w9ƒ'©ýúväÏùìOó7 7²u4ФC¥Àúš¯IPw»¾|â/ÿòõÇëôY“¯Õ;0_ûº›�×¾V7õ¯Óíæ›_ïñk^ûºØ„ã�即xżÆ7ùˆ×Íï´£hPR¯QëÈ‚*EþAŒ�îæþéýÐbü‚Í<Ô…}0óÉåà5õÀ5ŒÏËã 7r¿äÈýÏß(® îwèâ3ß:ÎÅ÷Ûï¸M7Íuñûíê¹Pýùø"۱ɇ�˜;ïdú7è.ÎÏ>ÀáwùY¯TÏ—¡ÿÍÞôÞÇCò Ÿï]Ž5ïk™ÚìûèsŒçÏœ#ò§ŽêuþðÍ¿þÔë3AßT5‘cU‡…Ûù�: Œ¨ÿÓž|<>ú&{ògNŸÙí}K{_�] [óÛÀö)ñ޳qˆÀ¿7æãem«ø™�ý˜�Íc“æ<†Xy5'Mߢ˵æ¹?ýœã ¾èËŽ?þ“?óz÷”[#:ÿêúñùúþÇÅ—ÿì�òºü¹’â§ñ°Öõx½š*丗.þ=ó[ùA]ü,xù\—$6Þ;óŸ'/yéïŸòÀO=~ûw~{wù�Ö´'‘ZóÚ�÷#5±dc¸o°³ÝïˆÑ­@Ìjó÷Ð ~�›¹áâÉY“ýCžjKLH« ›F0šš¢i6¾quÏ,Ÿ¸kDƒ#“«mr•£ç:¸1÷zÅ6�stoÕb}u1é¸à™/ü¸ÏÕÔ9�ÏûjKîœ?µ5ó¤Hœçz|f†=9º,ƒ¦-.¶Å–1H<úiÁÔ×—­A#ý+Î}L˦ÁÂWQ2‡Û.©\`œÉ|¬íl��ßKý1BdÅ*trŸ±µ »E¦¼ŽLü Yh@êö(~?§*qW7ö&»”ïµcÑå›Ôh£µ÷dÃ`ßësQ8ƒ9lÑKLã09÷Âgü©²Wù_/$'ÈÔ×OBc U†,ÚA“XEÀn7HÝôoÏ·âíÍlù£Zž,¯‹9 ÙÉg¥\øÇåbÁ³qy '›${V $k Ôšå飌– Š¥÷ôŒ]9½á8u£3–#üÆ¡Á'’!æ…R¯G½ÿ\E8žSœzÀtÖSÙÛΑ)+%Z6ÜÒ¤ÀÖ�o³DùižK[uÅJî�}½¶øXÿälÞ5­²jRÞò®UŽÈì�&Æ4#uÍ~]ÍžGç5¸ÛžÈ*‹rwmäÜyÌ-µX xýÐÜÛèiq9†o#¼ÀJ»Û†�å¨I4ŒY]5&\xjpµð²U85MS@@ø¬ÁëªÜÖÌ%0iÀ;Pcž,ù)1&Ú¸V븺FªùJÍG/OÄWÛÇòwÍÔæjdäš¹×ÌüBlÚ`uܼ°mMW®$VØ‘Aï885ÁÚËóc÷mçöE…—øÄ‘.lêõêâ wŒX:|Ža”ÿÍ]:HäÛš�M™$$Áj­� ÄËa[H äOÛ0C-:¯eò”Ïël‘ÀHxÖ~æäÅ4/îx�aíøyR|ƒÏý¢OcÜ4¿àÏ&Ê=NåäÝ9#¯Æ3‰$yýâ7T`¹Ùs�N '+ csÂ…¦Ö.’œ•PÙÉÅštÁBƒöè¯xÂñ¬ïþ¶ã^oΟE¢bZBœÏ晓ÜÛ¼õ[OxÂޝxì—‹SïV≫B CŸeMKVòËÞZ¦æ8:yG‹:Šã‹¿øóŽ{Ü=ë’È!98ÙªctûíwßûŸþëñú[oñÓ‡ä /g-_ñ¾ïûž«V'QFëØ…´—ƒ:pÁêåzgO.z�“ÌzÑ@³G“žk} GýôÌÀº]áv¹tî©Ö÷»ïÛøÝ|Áž!ŒL‹ �ϸ±ËÆ\Þ tÃòN~ßßëÞos¼å[¾¥uvàà\óï Á}‘Å1!'SìÜGnѼò¯:~üÙÏ=þëÿÈñš×¼*ˆ…Ë}%\Äâ¶»ê]E\ÄÊ}Kï\›;¹i7ê�šìÕm·éOl•çÝßí=ŽG}éo¯w¢Þx£¿ 7@Ž :-³ÆÓ�û†Ö¤<\DË}=�Ý#ˆr¯u[e8ó°~ße{üãã‹|d²�ôîõÙƒáB=÷_X‚ï.;ßÇ0ŒO. MÜpØ/Œß¢óäÿßÞ÷xÇw|û¬qt ê6[ÏrŒVæÑ#ƒ8¼`¿ë ïn<Ž�úÈË9Ô˜éË9)Ì»CÈÍg§þÖ‹^züÚo¼Ð{˹È7oóî:Æ|Ë·{í=ï2d�ú Õõq?Ê鱜’ƒe_ýŸ êY2š‰§³7»çq“Χ)õ)M@—áºy§×£¥ëC>ôCŽþ‘6(çHÏç‹é}þhÁøùW^p<øÓr<óO;Þyþ פ“�±s2¿ÚF“ïMßôžÇ>âáǽï}ïã™Ï|º?‘‡ó€óå\/öû–Çw|û¿?îÿw¸¼øç…Šoxý{‰¼Í£áºþÚo¾øøÔ†.Ê¿Öïh½Cç•~!ùw’ K°ÏG6¶ €«Mœ}a ½k¢AûÄâ¸Ý†Ã²Ô,ûJïš³f7õ`ZõáÏ}üĬ&®Â ÝKz3².5ç°ïêÊó<‡ŸmÜOônߟ 7$÷n³êÐøæ�Éq¬o&æðZ‡oîƒÔÊuîŒG�ãLóŃ�Ï_2¦¯–ëqF<1jSwâá1·Œdð¿ìáÒE¾®}Æñ‚d8ðtèËc“çþ0Íéõ˜á³e¯Iñêw[@².æá]auÌúˆÓ®ÚÍïÊ˦y^öÐË´Õ* Õó¦Ø/Û^Çî�Ÿ—N‚<<“Oû©×Ä…:¹[wBz^Vƒ¡Ø1(Ÿ94n®öÄÒzNvÜ=p¼&ÞÖ@ÌÕr°VÛÀkìµ£�2y“a²ƹ&ÔIsê•ÙíRϤS@r(–m‘dèÇ—xb˜±á£#!;Á H”PªY uW×i0˜«/C…h]zÌu/[°uª§qÁ=­ë† �nr»¬ð�ÖŒ‰ ‡6ðìÉ·¡^ä­F"Î}Š®Æ–ÍXòˆÇ>žó{[ÏË™—p0ªõ ¨‹“‰²BDºÎ ‚Õ°³ÁmÁéÈ@òàÎdÏšEWO„FøZÈ,ÆD¼h$\·Ðr¼lĵñd΢ê;-ÈÏ î¬›´*M¾Áè�X°9¢Ã¢È#0xûÀ¢]­ùÝ`{Ó…kt×8�Cá¼Ò¡š=ÀDâÞ:'{µ”~á%ªk"ˆâmŒ.ÎïƬqÝÓY÷Ô„X¸™·U¯m5oy1- ™4tXZïã–mÖæuµ5×´�Dì øSÐèK2{'ŽÀR‡KͲ%äÔK:Å:_5lóew1!'`ò×2Ž{É·é.CPå³mø“@ÿ€y½Cd§©ÛÒ1€#M�9÷üÃ1HQ!”éu$§ÿ§mÆ86 ëHí'€šõzà©ò™uT“Ÿxʘ9‚P3\ÆÃ.ûhMÂÁŒ­\¾Å³KÃÓÚ/&®y&[êk§,6Êc†7q‡(މ—U‹÷ÅB?qÌã‹ëÑóWx8ÖºÆîù:<\Èr¦æªž½v¤X£�qxhÁ3çœÎÐçC¹m“Ý/<´ÿ/€°–@çÉ/ù¥”MRóÁ%©6ûÉ�.èr_è�wÌð)øl#Óò†v¤žpÑx{ƒ.<òû \Ö€ë.µôDPÊ �~(Û¾¾U—É”¹â&ô·^ôÇO=÷gõçm©wöð¡îqxßFw±dª�áñát¼Ó߸ÿñûðû¶ó–!õà‰‹~`C¼©oôš ‡Z9÷<ŒíÕØ~þo÷×ïw G@"±lòÍúuŸá7ßö­Ï$¹âr!#yô&ÇGýý�:ÞüÍïµ8géÎ×±ùS’hS.t}Ë3¾íxÖ³¾G{–ç¹È>ä¹ñÆ»ù³àxGW}&™ƒs°¾0ëó2\X}AÃõÒZTç�úÿðxÌ—‘.¼¹_x¦Æ0äE2ÁðÃxÑLŸ %xÉ Æû®ÁÚ£|Þ«ú†˜w*¾ü/^qüÂ/¼àø¿¿ç{�—¼øE¼Vƒ=œÖâÛ¤$ò‡4cÛÆ”Pëár7Ýt7_¼í¶ÛŽ_zþ/Ÿúé9¢Û'~ÂÇøËM8[ƒöÎ4>óáÿBïìÔÅáò˜ã‹¡‰ôE=Þ­›w>ê]‘Òsæšûø`—låàwº/êÏu‰éEtóŽK^\|ÍS¿öøðû@ÿöPXãry܉µ'?î~·›”�û‚.ɺïÅ& ÎïŒõ8DÍG쟿üåǧ}úgO{ÚÓŽ÷y¯wÓÅÏ|ƒ®B\öÀqæE…ÚØÖ S�ïyÏ»ýô|.!Ÿ3ÈUþD™w @½ïwß·=žþôo9î¯oö;ÿœÄŒæC>ôö5•½šß¦oLÿ9Ý—ÿÅç~ž.þ½f.þé3-yL—Ÿµôœö¾ˆÈ/Bé§n¬cogLjÙßi®"¤j^»…%²å,&^¦®çDz‰E'zϵ®×ƒà5ˆÎç¯Çð­¤$ÉZÈ3RekçÇSr€s¾äµÀíù'LKëQøåœLá«'­…9…:y£s�ØîErì„­àó¢ßä²n�Õs_lMvE衲ü»�ß$6F[Xçè@jMÔ–Zð±çÅâK@³hõ�Û˜5Yu(`â'åòGvžwZ¼�'w4¡ñ“Ûúì¤Ý‡ÔúÔ•8dæÜkýÖZÑjйs/½ôâ!<“Ðk_¼Øqmú3I¼×¤<Žîf´ÍáÒ¸Ÿ3H=¶õov†Ñ;:gÁžé`îÁSDN{ø¼þê±ð€j§oK}2?ù˜§ðñ/¾ÙâgŸÊcÜšÀýÑ�±N ±›p°gÎæ(IP\g°’á/Öè‰Ää™0ûœwò‹ÜžW¨9Ø‹&ƒ­äÂFc?œXöDL|Ö‚–‰Ã­I ƒ…G­õ Dü}Œ²“ˆk[ê':t[¿�€Ž¶F]®ýÊ„v †_ÎÇ:@ÊåÿHqBˆíµ/¸Î;#‚&‚…�åâý:�¯´Dngan[çhÛr'@�úÇÕY¾QŽ#¶zü 8®¤V0x~Àñ‹—†º¼°b’ ÍU-`ŠMï鵇)xhÉO-ÓÛž±¹C/lê¹£]6ù».snñ`«³qÕëÜŪ7v@~Ç„xÁæ‡qnäX{?q¶uSGEu�‰ç˜vUVr¡„ž£UEÚɳö!ÜMŒ¥±2ÍÙÇÁ¢×”å [ä3 Þ€§L›¼fôÌz£o�!$A+§"£ä¬v“7W{Ô[Rt‘’‘ëSôo²s�.³ûàZ ÐpÖ=D¶6úµ–¡ðšë’jÜÒb�©çZÛÆ &œÔpH¯v¶ë°â lâËòx]bíè´QE7ï"6ÝJ"XrV·× ‰ Ž…s#5nüµcÛ –%ñÍeB#k!wô)ñúÇZLÏØÿ@emh×\°M_[ðÙl^.Ƙn‹Ž?¹f ë,)«áC_Dà&–Ühãçj3fŒÄy¯˜ŠŽŒË½t9?â&ÿÒ–wåÌt-4�ëæß“›ïò` ›)F#ÍE=·’¬¡µP_ 6�Ýà ¯/0B£1¿KxAÿUOþªãÏ_ö~RH®kê7Ë�ŸÅ÷¤'}•^hëEé‰ÇK~ûÅlº8xÇ c‚#Þ»è‰&ºŠBß[¹àÍÍÊÊgòî6žëdψËE‡œ;äâ³õèo»õöã™ÿîúl²¿øü_Ïy=ºS·ÑIÇ�Ey¬¼é¦fø©ƒ@úçwÑÉ´ZãÇÀt5‡$ÖŸÝ'úÔUvÕ‚ó>7|ºM®â¹@Cê3ñÄÂçøru^ÌÆ=yàë�XQ_4r­Ö±zìÔ…w¶>åkþµ÷‘Ï.ôù‡�wêÏ—ø)Ÿ¬?!×…0ñ·ú±+òŠOß$ûª×Ÿóy�<^§oLöûŒæ\¤ÔYáZ³VÝt“qèþ:7à ¹å,’Û¿Otÿ’�?³æ�¿wè¢*ηð¾þ–[ü޶Ût¿}¬>àÿèù|Aæ…frOóyÎÚdó:2ôF Ô„ó0µÁ’ó†sgµ9ÉÌå…½ñx­þ,þaŸù°ã¿ÿ�_ð…6Ÿ“�ËÝ 2±�ƒÃÕw/î® Îÿä{<髞ìÇ_.@ò“´·xó·8žþ´{üÍë]ü Øâóƒÿ·êqóÇâgއ>쳎×Þü:ïÑÜ'§y7]âý{>µ)ç·®‹y2ñš¸ù±~° Š Þ†9¤ÎLÂ=ZÙl5ðüPÖÅ^y¼ð†1[kn.÷µC'Ž<þœ1^‹0n¤6ΩÈ3öÔƒª‚ñêºN\"vqØíñoòL�Åk¦'GÜ“WS×#Á`’Àæ3«ñk®AëW¥ž˜Æv­Ì!$Ñ"Ƙ©MÔ|0è§í6°u@?t­A]ÄU§û=H1„ã<òµ^�`Îò³¸+äBoqÕ\ õ{Iš˜Þ)Tìh˜\L¾êjMÉÁ�uêñÌÍ’,ÞqåÂà—æ2$Ô…ÕÐu²1x/Ï™E0ºG 8‚4=׬uŠ˜cZfxÞCÙð“= [P{œj]§q³/ŒËµ4~�¾Å¡Á@„IM«ÌÕs1èD\O#ßúØcM=LJÆêdÆw]$e=³éÆ% �ÛŠ/ÉÄ6f­}8Ψ!hGšŽ·>¶sukÔ<Âv¿Á^pt³®âÐv�SÜyŽ�û楊£q~}4Úª‹ ϯ±SˆÏ€ ¾ŽXÜ_‚¸=\AE³ïCN ÂTžÙìò.Ü–« *f'«mšôó„)´ÄGMù‹·uËåõxeA „P -µÀ!VÝÎkµåŒ²]Oh(·këMd<ûÑõ›¯áÔnnIžÆ­;<…c�˜ºYƒóŒ¡9Í2ÑÃC<Ík[c,9é¬È„Y‡ccè:Aý®µ¦eÍk]2;—)ƒ±†�Wµ² 2n´‰�VÍk·3ÇGÀ²6÷ZËò@©ŸÑJß[’ ¨œÄ/Œ =Ï ñx´;†ñÔ±OŒ˜®u q¥›W“R,Èiñ�6Û4ž+�%4G*—ºwì<“,y܇Ð9œJÖ”8;Wþ™5Bý¨Öüá_\:’P†˜¶ã¨óÆ3¼­=1' ¸Xšw=8޽ Ü÷‹ˆâÑÓÇ*^ xÝj«¡ë!^ž„7þÌ4QgSĬ¥LøàÙõ¤Î ìt¿_ØS!\vk̺èœx|Û8¼±‡1çI𓃠áš ¹b¯6÷“ ¨Ïery’¹‡ýÅnÍqVGÖ¡`áé =^¸V_Ï£J=˜©°ÒÛã“öò1”|Êe-h„ Ù=ÎTvÙ¤›/\—d+fÙ «>ê ,¯Ó ½g|ëw­¤SJ’E/½šã2´�‹ ïýžïzüŸøÁ¡“/çwcxGëÅæ‹šäb†j&›_Ê–âàøsâÄ2?ô!ú�öç_…;\¾½†2�L×�?1|Îs~ÂïHL๪Ñ]n¼Çñ×Þö>£7œ¬¯k\ÔPGö5þ½ßûÃã �œ/ˆð&¾xÆ‹~_ú¦:s>ÉÇŸ»z/ðkîóŒ.R$Žw׀לÏwÓE 0œYÄÅ'áW˯ýƯÏyîóŒañ‚ºÞûØ«ÆÞæ…%u÷>̆ó®È6!:T¾4øÉí6¹øœ¿¯xÜ“ôY‹/—9£¼>ųý¬�FÇ;—Ø-–,å|éþÒ¯Ç?y{^sîœï®6éñªW¿úø¹Ÿû9×ÅT’‡ÆrU®}Î-ºÞÞ[åãüIãwlËÐÞ2PŠÚ�wœØÆÄKÆ¿0öáœfêYæq¹ö3¦n^ç�6>³lãÔxxd÷:0ù¦£æ¼Ãò?>ë?¿ðó?«óV{Ç&JOö ŽŽûé[i³Í·µ7z3~r©ýëo9žüÔo8þäOþÐÚÑ‘wùq8÷>ó�??µHÝ|�XçŸ�¨ “¦¼›–ZržñæŸÜ×VKBï-6%rítÿºMÜ�~ÔãôY’¼»1Òè{¾Á› `Θž?E_þ˜W¬¦‰ñ C(|ÿ…n4Þ®o~ô—?úøÁúQ]œ¼Uú…š\m>&[ûŒ�C‹æ7ÝíFý)ö‡_÷/¿ÞÆYÃýî{?}¹Ó·üÙ/˜ÝàVó:2\ãqyÿò/o9¾÷ûèø¢G>ÒŸKÉ_ûÅK-ý3}ùbG~˜8 2ü±1iìžx­kb`ñý–Z‰$÷áÙ;¯8vç@€é©ÄØ­­ãñ¸�þq5qF¢!4g¬L¬ÃÓÁ“ƒýš5±Å±âO¼9W:*ÑÆˆîĤo†Æá[Ç ö‚ §ñèYë JçDÇ�ßã ¶§99/Í£s©\ÌW%ŽØ¡9��ûÜ\.nÅT7k]ë‚kê`XAL6­ü®p“Íu1¡,èq7ƒLlë�\ÄliäÊþ,¼¶ÉUN´0Ö �½íDkßÑd¾�ú·¯Ýhr8~ F`ÿ[~×n¼ÄvUÑÎùbF¢-9s.:IjA=X�Z{ð‹‡qk„=:¼¯®gâV,6³%,+‘eÓã±L�n>sg�La®œûÅXƒôºv%�„{ ð1s€F©Þ4{"òE1G—ò ¾:gª.Zà1ÞÅjÂú–�ùd𵢓 9&üŽɌDž˜°�!üõ{Ç’cDAÕ]ôÉ£:uÛq$;2ì[‡ÝWMã\xÙÏs ±ä·V3A$æð±o‘=ñ3qNBœæý%_µ�vò”ã¬Âä骊�·Â“Q!zb±?R… PE¦D¹/—LhY|%‡,0¶¯±Ì°ƒ|ƒ` a˜8fãm�]XrsK˜Q€åŒM6<œŽ¡–üÏxr1_™ä»öD)wúúc�tà4%ùU^%��3ŽÈW›¹ 3!P“º‡5k —µ@G�šçNßìÁ_jpÖ_‘U ®XòÂËÜ£&q8uÄ©›û²&cß„1O×½Í÷°îK8³öÖÅ> ª7~ë­}RF9o˜»åžoª…þâ`\kÇÊUû¶4�ܼ~·ÖpŸÅomîù¯¯cúÖ2iÀ?&﮳éPa 8Ã5-üÛ€fHÆÑ8:t’Ö1õY(“b4Ö?›±–{ ]£ë`"âtk¸Ç™¤v:×üDp¸&5XÿÒ=HŸz�ç¯\‹áWgY:ø\„qj•ç±zÛ/�8ºè%\ÿ|SüJ«A²‡�|àgvá+Yñ§FñaâÑ­žäV­ü¯n¼¨äƒùq2�žü)¯¿QX8ëž¾ŠVŠÌâ4wí¦·ñû3yP`|ò�z¢Nãé�5Ûß13¯Õ${âÆÕFžÜHÈ“Œg=ë?¿õ[/ɟ𒨋lÈ̳ïÔd»»>“ï˾ô‘zg ï¤ËŸøE–Ï 7¶Àr:vL­o¸eá´~ø¾÷|×÷:þîßyþ×ÒäÔ6JÍ"–w0=ñÉOö,—g9¿f½óç\dÛžj˜‹œm”�9üœŸm|iÅçÁ—èBÂí¶Þ9ߦëGGqçã)àÙn~!¢ç~~“É5ãñ'#Ÿß– €\ÝÈŸM {ÅQj«ÖôÓ?ó¼üé_„&må*̘k�¨Ü×ünBÌ`ð‰3Ú˜gÙnñ·Óç­úsÁ¿è7ýŽ3¾ñp>—M^!`rãó~Ìœ‹§w½Ë]ó»…ûŸ.y{ÇE`RÌŸÞ -Ÿ×—‹Âë"‘°&%ÀšJ4âé�;×c£çwÈ©·L ì @£5‰Ñçƒr„3õ/¬Ÿ_Žkkªk¹ì¬ã®ä‚×yL Iy™kìsÒ¶8 ±{ó¾»WcÔs�ùgž÷sÇw~Ç·ù|x}Øî6ÎîçìÅ5-2gŸ9w¬[cb~é¿~<ç§~\v]È�ÇÛ´Ãs¾K­NN%�!óÊïû‰ÈØ']Ì®å�¥œl¼»;~.,R?‘Ž™uP^ç_ô’ê~ó?ýX5:û8åm—�fý¤c. ±|!­5ˆ^ïF–*ðºð0<æÔ·éfŸ1¾QïL¼õxÊSŸr|ûw~Ïq³.¢÷<5yóvŒ¦Ž•ñ&}žç‡~ðßöŸ¿Ó;½“>cð[ô-Þó™Š÷À£>šúŽeÖô�ÖðŒoýÎã)_ýTïÍ›è�ª¾O±×�>bÚ<ö7�œÌ.-2$YB5öýIÆÔðÄS l¸.N’0ŽÖ0ñf™Å,Å%<÷zŽæT¬¡ŠÅOK 58·'9¬u gÙϦd�Ïn¬AƒN5Ìc¸Œ5\`8ò1Æñ!á¿â7;t]Ì©ç$ Üv¿ó)èôÇbl¥ÑÃKGÑœ¯¶yì³ìLÎyÖ:óH8±æµ÷„þ¹9 /¿Ç³&ÙÎZ‚‘aÃyŒ ûÈïõÚcÖ/b¦Äs³y‹Ù7Å¢ñÔ2`œðyé/´àW³ÛD™ƒ1¿yåØyÌ71M#œc”Œs„k]ìÎòÍ7†`Z r©­Z˜[ìãcà5Ù–1óÞºæÔO"Ñ �¯†c4²·æO’Uƒ k@Øãµ&¦üÌF´†äÖ?TGÁP,ÿŠÔß��V[f1Í8«ÈÄ0‡ŒÃk½‚¶{®ˆcR’p&2qŒ£Ë#7­|•íµ—+EH‘î2½w' ?¾—hÖÐ<{O¸²f¸fõ�ͤ*—¯†=~Ï“…‡CœðÒîÒA<¡;Iâà’9Pú±S¨ó¹y*ï*¦ «ä[Ðcˆ½Ð7ùxrÐP©Xú£©RÉI.¿ÇGk ‡ÑeÍÉeãh¾«Ã¿?x&§OXÿ–,qÑÓ$­ ìÎ<üKƒaQkwKÏü"~üµµ�¯š;W˜ªÏõ"÷Ê�èsóš4ª”1{?ðä6ºÇm¹®„èš“'�ÆüX·æÕ/‡!ÖÂxp+á²�çVz™Ýº^� ½Ž±ð�­A»†æ`-äS?CÛ6ÍÂï9=ö‚%¥9&m×Z›(Ý\W�*©œûáZühÂ01ðy^B{¶ÃhšniJ>"ë9y­Õ|§O…i犪ð¦B׸»Fà]GaíÉ¿´ÃLð–sq˜r�Ã$ÂÔÂaVƒg=yœ˜Ü§M�&à$�=¸p seîÔØboúÔ#u©�QZŽž¯[¬†¬a_5ƒ?vX‚Y{µÅ,›2G±ñSðD‡ˆ̤ûEdyª£±`£ºÑ¡—ž)Zã³YÜ@“¨–ÖXú‘0‰æ�Sì�}Äu—�üâÑÜÙÕ“§+�ù9'x¼Ö­‹›LYkÍz1ÇhxèñãÓ�ßY¦ 1�}ü“üÎb/aØKPæ2q±ïÞáíŽÏÔŸŒõ"ŒÏ[o¨Ô{zx½ûœùÏ’„�?ecgo×·Ò~å£o2Õ7Ö"@ÿ¼÷@¹a²ÿnpÿ›þ¼î¥¿ýí/ï`‚+­ucæ:)Ÿ×4ñAbçœTì•bð­¶þ²?õ¹Ó‹¼°/�ÏXÇ%GâIÉ"Ýg‹püìë·]°9?S BýœaHòäí8^øÂú][ðÚÅ f ¦±²¯†¥õ�쇴cª �ÆV¿m+ôl„¬ýœCÔ.¿“Qã;©¿ü¼‹‹o±E3GÀ¹W>›­l4bã—Ý>.>p‡oØå›nsQž‹;\ J¾ä\ÏX;mj@=ÑèºÖng&ι=&˜‹£Ä1K½@›ËõÔH5èù̘Âù"Òž?vÂC+Ö®ðŒ-ÝVè pÞ¥s¯ñžpÍí)”ÂxÏ5¶Í©å‹õ�à�}ÌW¨öPr¾*R7ÖÙµy²Êk_]{?znÓç8~×w}·Îa¾øs®¬ºøŠŸsÛ­ûK.Z®/äÝ©‹h(‹{î̹¥ÑíHwv1‚Xúy¼ýæoþæã•¯|µ8X#õfÕj³e±Ðç‚1óÖNj„ÏçÃøÌV›'9ËÏu¢tüÏxúñÔ¯ùÆãÕ¯~mêII]u³6Æ›&Q“Ò�/Éù?Þÿ}Žÿïž~Üÿþ#{5>_t5ësÀøScr?åk¿áø}6!õá# ¼Gò­x^{èÚñ8Eó¨§FNU °�‡êcU[èL±;Xv/4õsÜ„`÷mËEÜÐ _ÎéÚ¦¶šVÅ>2Ê´ ­wz%‘Ùkkñ^��sŒûÎÔkÄïÐæíZãtàÂ!ÅHË!W7c�Þ“¼¦Bíx’'{IÍ1é&šeÞs¢ñ�áXz%²Ý–ð‡_FÔ#ÿYX�-)ÉË¿¼ò-Å�\§ ˜r$TòH€³lÛ#Ãè±§cá2Ìú«Ùñv 8œ[<öŽmÅS ê÷ÚžµÃ> ¦Ñ¢øÙñ XköCÑjÝq‡q‰G§ë@¯`Ç€û%ÿÄœ4e_‡6D´ZŒ'¯óȃ¿ãR•£ó„g ÅSô8Ú9’Ʊ¤]žS4Ýèr8ëåõa[¹Œ"K¹6•&5‘—*ºà0‹,ñÇ¢£´¢×|Šj-Wlõ:Ž4ú5æ>í}ì ä4ç–k†ælãIî1¹tÛ5.=Ša-}žn½£m$�°ËZ99º‘cd‹m8ì#‡~œ¾ÞˆXc±‹ÑÃ| ˆ,n²Áq6§0‰GàhôAï9öÐ3“õBP¸f Ô\>Ê“àpv<¹<%5ƒ«ø-aî ±c½éuy6£ÿh¼ºyÙ´`²Œ{Âd³Ñ씊ÎI]ã� O:ôÅ&ûš4­.Àððcý›º¥‹€Õö•³\8‡Ž]‹ÑGœ%iÞ¼ŒÈC`ò=׸Ǜ¢<:,ñì»±ø¹MNì]«¬5ã<|x“[:Á²W‘åja9ßLrgÀŸŸ|u=^§UŽD@‰5Éi6ŸuÜš¸V4e³/�„æÈÒ>9Š™pO�ÒüKÊ ›ó¡á—çK¬†l„Ήâ ŒŽ²È<~Çn8“ñ;Dó$±L*80 4xhÃw±/6ï)ôzà_º6“§9sr r5a´3ÊsÚê²_f°ç>a ÅA B÷<ÕŒ1K�8k f�bAÇíǪ»¦î6žf&‡m8DA.k›Ü¸Ï m€vÈÇ}“š«Òšˆ«FûÉÓóãj8ðùÅ©'&�Cœ½�‘™¬ª$ÄF¯…Eòn#ß½Ycýp��Ü]Kö‰èä×[“_-‚^ÛÆØzÁ—6÷Y&ÔJ¯ß™• £„–cxÆâyb­[Ó0ˆ]ï°�2vòéö†»/~鋎gÿäóŽOüø�öçJ9]S¦NÛÃ÷c>ðSàÏÄãs£øœ6½œ÷zøàbë÷¸HbÏh„Î,�¡5Iï@ù§ÿäÁÇ;¿óýÇHhaX5j[ë“ó/^ñêã‰_ùDÇ€á-�~‚Èþ:ˆœS¨¶˜,'æèv„` ùµÌŸ*¢s=h<|§Æê¥%�ã\° @·¦c§àYÍ a€½ 6|Y øø<®›_óqóÍ7ûó•PCzpjsLNå�&^€ñN;]8Õ9|ÞÝX�œŒ³ªË1)ŒÒ€/]øÚ¯ýšõí·Ä¦æŒ¢{ïY›ÏC`M¬Ã3�†â˜Ù61þsQpTNç_„˜4ÂS³ôI„{$fÆTC.PRkb0X¿ÇsQó•¶rÈnÖá2L±èmíÊÛ|KàM’ý»Ídsþ…Ù}Œ›Ó ?�®‘œ+÷¸ª­|è½Ç=îv¼ßûÿ�ãW~õù:Ï•PÿúØêsU9ˆëþP¢õXI~¸G'=Ü݇—¿ü•ǯè›p1r½ƒKˆ¼ãÓ ^í#ûݺqîqÿ�ƒæœ%#V6òsá™ÆE+8rÎ&ȱp1ŒåxùËÿüøÑûÉãŸ?ðy¬÷†r7·Ãe»" Ⱦ†×õ!@·üŠ› ›,äÆóða .¤Ü)Ý7?òÿüÈñg/ûóã©OþÊã>úój.а_\tr4w�~M¡Ö„ûá}ïóÖ'Èy¥Ùtš=’-¼;ò¯|Õñ¸Ç?åxöO=Ûõcgº¿¦0u`¶·î�ˆ !í'.…ødÎ(phBê\T<�…8R7bÙÀ�ÞŒÁ)åðôÌkZëã<·,!ÕÊcòøjÃ�%u½])ž4,Þ€]3\1â5Sx©ƒ÷×ÙL ~p`lôµ —‹€iƒå¼è9ã:cW«-³€s_:Y6™ažXsÊR™æëA臭áK†j·�É�{‰&rÁ}Ž3cù­ ˆË×:Åï ²¯Õ›^‡eˆ¯Ÿ~à3§ãtظËgY`³Ñ†x- IDAT!QT×µ¶t<©‹&àáCBcgLî/®4l‘ëú$±)@@Õz•³Úï|¬©i�Ìë#ßÕæ¬2[¯õ1 |Tm÷�«š;×Z›‚y0#V¶®Ïœå�5]‡*¦×ÉQ®S¹ã_µ…a´T;Z&5 Õï¹Ý“ç Y?ºÃÉo?vêAÀë°�]°Øì#Ë]›ƒ7izœIm”u=¸Q 鿤EáqÉsµh²«#ÿš€’W­&O0ʰ6gs_í�ÊOÿ+NóUWYZ ›wœ�Ð6pç£bMª‰’Àã-§–M«MsHë¦6£OÚ³&–p(xÇÇÍ�uªež±O*¹S}»ƒÑqURÐøc9ó8Fÿã—™`v¿»ý J~ÿ¯™0Õž58BÁ° ™}ç$Õ'6Ð+s­µ¸ͳVõ©UæÉ›‚‚j­ät�¬íÚÜh2ÔZñ‡ ûÒ7:­?n¯éRŸ^* äß•Z Ã…ˆ§¬ÎÉoë‡lVu®ÑÀxÒîÑÄDøß0aª¹=¸u^ÙÏ>à>Û�zcu0ß c')öèó‘5˦šâ¼h ³©üñ;9”Ž'ïÙ·㼦 ‰Py/b�ö {tÿV W²!½&F"µ÷%õ"|E§pü[MáÔÝ H#‡op,îa’×OºÁzŽMMãDŒ1²ÈØ�͇aì¾Þ×qžûغïQ;ÿT�‰eÑž³A•,+©€»®û›½Ì#×à{î±&^Œå\EÙÖä̧IxCŠ^<ñ^H?6´àoÆ­yœ×…�‰%`ýÎ̶ Y&=?<“ÍëîæS\þÇ]¿5íObüâ[ÿå×ÿ«ãï~Àûoÿöo‹êH]yOÞ�η~«·8ÿøÇë³­å (¼“KŸ=€u6Ô™×O F$`4~ Þ¤‹Q{ØƒŽ»éOÜ ¯0‘�šhZf¾œãY?ð_Ž[oÓŸÔAÂ2M b T ŸåÕæ=Îû,Ü™jÉ€�™÷ͬ‡ßAø¸é™kkl^?‚9qüö6Îý1>èDfÍ2÷?‚ü%ŠæÂPñÃÇÞYõªW½ú¸Ï}ïã¹ÉBéa.3ä#þÔÂùÆ;õär»"Â5Àõxþáº÷½ÞÌçKù–Ë ä2÷ÌÓÈÓµîrM+ì…_óò®Ä£­¢;]R__@)¹ü¬!LYç({˜çd¨Š=5@£æ6Ú•ùð9ŸÌÅГÓ5¦DÚ>Õkâ�K¡gc-ûÜSq÷1ý:~ðÎy²xÔ xæ7æ¤ÞsréÿÆÛßðuO:¾ô˼à×YWˆ’¨Dý¥‹¥Ä!Ïñ@övEâ_ú» wªÞ²â¨[ÈÅÜ<—Ë…§Ôvø±qÊ>MN±ìç‡ÕÃã~"¼~0?¹Dä¼òñâå?ÿçÔ2üã\LÊü.6×PÑáƒRíFþXã™ZúªÁ"™Ò6GüY»mè‚3÷e?„è�€¿ø ?<â ¾øøú¯{ª{ÿšÿ¤¾´!>Oš•c@g�dìõâù’”?û³—�ü’Gé[µŸ¯?mæO»yçmö�˜Öx'ÊZí€ó]^åYØ{�{\÷{•DŸÏê YvFxï+ٳ桟Ç)b…Ïyû;ÚLì©KüÁƒ3(úgƤ~ŸA“cñЍ~ë¿VÙ:À­ÆÕŒácÿÑàœî ˆ^û¨ÔÖ&ÖëJÉ†ÙÆ9§g !ºpûuúù �CROÖ1ùÌí¬­´ÄŒÓ£a.PìŒ.Î WiPÐàu”1a´ËørŸû?X4®›‡£$ƒ(ì*‡÷O!hî^ûêÐ@–=�ñc%ÕH6Gë[;¼Íëz»ÔgÓ^Ìd½à¿€iÒdƒõ\桵5ñ ¼B¬uÍʘ`ÑÎf\Ô�pÚ•¸¡MèhŸ“dà[='ï—ç9çt÷Mmü»€¦7ž(5™V즛u ✖µi"¾ZƒIšÀð�4Í#Õ!{Îú¢@ë£÷¿¸5^ùgŒ¿ÚË4Ù’“9Ík¨Nõ\&ÐÏËôûB¬‹ß“ípæÁ˜õç)Ck!„þåuh5í�ózŠsÖ¯çþöá+Y]+a‹ª  NÐx:ÇádvâÏ(òsïó'~'FˆI8Øâ ò�b�¯ýņ�Z±’¨›‚D0ÍtØlÅ77Ó˜,û›˜^8Úž3˜3ÛÜ9T¢¨M4Ä96” Œcj¼çËy®aH�µ7‡¬¬½7°¢ßªó‰@¯Ÿ½¡k·áe­·€’‡ñ2v´ŒÛÚc3Ÿ†áÞcw Æ@â•[fÍ»–eí†-uŽL:AtP6/P,péüæ—Ís=3îž‚¥áÏ»¨<]t¡G4Ä^ÓB:ü l\·…‚;§¦�^lsk®êµ¨ö ú3Ü6ì`^Ë_ßôo¿õ¸õ–ÛýnWs‚ü|àü‡|ðïö®ï¡ Ï+r¡ª¼ÔÕµµ–é ¹vMÔ‹1|SꣾìQÇýú%â·dèæšNoNüñGü§Ç·>óé~Œ¥2Èž\Ý–6»@Å_^Ò?7f<ñœ1§­¼«�ûSZíà=&·¹ÃqŽ£Ëq¸4ÈãköË¿keô:tä�J`9òyx{¾I�ÅuÀy“'ÙǶÙçšטу‰ÆšK=Xž¼y?gÌa¿#kžàÃ�íV[ã‰ÉÅiúœ;ý6]úò§y¿M—‹£ŽCجÝðR[uiõÍ;½.¾ød0œÔÙ­qÂg¯H“=dŽ›}òz½|h)]Ç‹\kNÒæd<Í»M"µé2áX¼úÝg�¸e/ÿïÀ³�|³÷—?ê‘|�®â¥X?^�Ãüܯt†¼4lš€»ÚV-ä¸ív=žÈàõkÎzàg¯iùò\ˆŽo.òKh3æqÊ+Rüiå£ ¢9:M{ÆI_󡕸Ûõgå^ÐícÙ¶´†ö³3ó{!A`à¾hLç†vnìAÖ&WYôÏÜtáMWA�éc >ý3v¼øÅ¿“wÔ?º¬Ã!:ŒÍ=6tx¢¡ÆŽ©O½5ÊÎþýÁþÉñ�‡~öñ½+óÆoZØ,²p¥î¹/ÙèUÄGn³6+ˆÇ(äJ?žÙƒMÎÝó3÷åÔËxÍ¢XOê|ò»®Wk��Á: ¬Ã$(†ƒvŽI’82³_Ä1ž¶&áÅj|c‰1~‚èÌܰ¸;q “ói0\·anxýü[&ÃǾOKC �¹Ó¼Ò[f‡³f€LÍy.Û©/XuLE�5—Gçñ€e®•6(dH³s^ÃyÆîIÀGY2?u¿;¿Úûܹb4W5I1™ºê)­Ðq´ƒ­Šížu9æT@yœ8‹n/#zÁú‡ã3N¾4iнà³Q  ¤N¯7›ëøæ·0Ðä9{ræç¨ß¨®7}²Á~”'fۗϸ8ªŽõ\ïuv\Nô{LáÊ£¡÷¥óË5R¦Ë†aêIWÙôÞK¨�µ~ˆ$½«]ÌÏèbºgÄ·–e¸“u`/Sž¬È\O‹@ß››Ðýdh¢Šö‚=™�çfJ嘒¨wRç@åóZG„ï›OÌF®w ŒØmŸ>œuË?ûcŸ x³Ü1ù$a<@º–s5º[ÁX/ëÕ®æ!¶µdܶãð{îS·ØdÓ5Ükê$YÃè±ÀôÍë±æ­cãö¾XlÅ_¯‰A�¼³æjŒÉüœmç¦èö*{~RC"ì[Ák`{Y»Ž«=\MÜœlUqV4y‹ƒÓXìU3i—]:M=û>]è6Cp«U>áƒ#¯óh^]ÕJzÌ®|ã—“ÿëXö}íö7vzrìsO>¸ª~°§Ôœ‹�æƒÆÙp\Û&t__òpŽOŽF�…×m;GPÇÒ�2+fÒh�š:ßpYãDwÍLâu±f¬X&�éj§~Á,®•\u Ù–—c†§{`Üâ6È‹(¶Ü™ç¸ª,Òò°ðØ—ûNêÓŽ�ÙŠE*ÆêuRmÅãõXë%Mê-¼/R˜E€…ÉFÎgãË(™Üò?i�N*ÁÈefå"ZuÙ¤r:° ³6(ˆÏÍÐÂNê­ K̹Lû9êø“[7.nò¢TdÏþÉ;~í×+/üÝ,håž5ˆÚ�ÚßKï{ÌW|¹/®a÷;«ÔÃ8OxÎ@VcŸÀ9ÏäÓ�û¾õýŽôÿžÞ™Ã‹X�c8‡Ýrë­ÇÿõÍO› 0«MÇÐut�cÔj½n|ƉÞu”ûâœÎMþD fûX�æaj뢮iÉuÚb÷Ú‰UCOö:clèðÞà/5ð˜ð·6娟ÞmrtÚ�\ ðž1–—õ:Ac•,¿a{ª€¹5Šfp±ÕîPð�ÎeÆýÁ‡^~7ûLT"Alm7jlÚ®K±½`yFˆ—0�ñžß+“�ëЋ/kÜùu1ÿ«^óêã3?볎ç?ÿ×ýîÞ°*jt�YÂk“ie— )à¹Y8cøÏ‚;�êÒòÐÏ:~÷~OÁoŽÇ€¹ø::½¤®Ùlû:�Ãb¢Ïk³'g¦¸Ò–`ìÔƒ^‡�Z»ì^ï†Ícâ2«¶Ô6ûö­WRœÜðµ5×�}â9¹gÍüάû&6ÂF'ZhYG.t6ΞV½±ÑXÓ¬N³hÉ<>ƒ*±½¸.^ïš{˜TLÂR Ÿ“‡º9›Œø]Ïáœå\ìÿȱ5E5;VÆápjM«ß�`§p8„ ‚Ý�ÁÔ¸6Á¼_mL�Éçóxáöu?äNé:T—cÃxi æ3Þ±jî—ë­Å¥ÎhféYs°QⱆçÞ‡Ïùs6r'?6¯“Aù«áЉ‡Ë¶5áâFþÅe[‚l“èd%I°‚À6|̦)¬kq±ž‰…¾=ï^授<™'†8n´®§Zl›ÿ°*gó8@ì‰cks1³>0“e Nê<£'‘ç±xsø ˬUƒ¨Ñ>[ãÁt^>´a[šg<2/¡�Ã�¦ÖÕaº@Q‹\“2ȶÖl‡ØvMØÐä¦Þ?�ï ²­½X~E9¹^˜Ði )†l’’µGì%(1KØ2Π|µ3¿/ß*€E¥ àÐ:KΆ cQ—sl›¶5/A¶‡m�€Õ7¤ksLðë[kEz¬s¶ ¾r&´ ¤›šö½˼åm¼k­ïùÔ„ |¾�&ÑÊÆfvÅ&gO.ò6'¨þrk|ó’ dì^ÍìÉ©ÃùáÓ­êÍíy5 óè6'kÕÍMX7M±´.ñq” ¶Í�|Æ:ü,^" m.ø''ýZÛ„ÚV-{ò[™Ãó¥^ KøÅ:¶PS J[f§#vpRÇé- ;0Ýøßî®G–Ëަ¾ûÃpkb½îç Îò¥ N\„ú�’>8˜©96ÃýHîæoŒy&Ìch=}ÒŒM݆õXóÖ$ e��Z-=¦½²ç¢Kæ{,xæi+ÑhÖ“ó4j2ïVâ]œ4p£Ó#à+`,æ†Ec´ØdQŒÂøí•U?ga\#¯}ૃ9×H"± GB²K±�kÕR¦•G$Ó+æ´Ã£6I,A Êf¾1Uó f=—<þ²ƒÉ›uÌE3ÅYw) ¹nË»jœJè„=®ÑÄ`�ÏÖ dÙlƒ[ëœ9øÄÌ‹c¿àcœ¹a$ŽoZåÏÃû¸¯<^ýš×eùÎi”K6e³!Zjß{½×»õ>zÊ–/2ñŸ°ŠŸ5íbIé9>^ñn.ýß“žüD_LÄïª+ÿÊ£ù] ax1÷›/|éñœçþ¤¢U;ÿï&¤ìûö:áÎÚ¨rö‹€¦.©ÂÖrÉÕFpøÎ4rzšäÐdËY¸5ˆj‡bãg“ÊQD,øì·œ´ÕÍ V­3Aôº5?6›m»Á™y—ÛcºQ/»£ÓÛ¥ƒ_X�oå3�ôñ3³ÎÐÚ‰«Üv¾`01ähÇ•ë:þâæb·û”Ðçõ·®Ü÷N‰k·“ótdÞ|wjßuE®€ÄNü Ó`a7nêrê=ã&Mº‰m-bÜH0hºó„w3*Â>ÓóŸð�ôgý÷QMJ€?9W“mÏm/éË;�}C/8à6~x5á'iØ�ì…c0úÚ—Öã 1@rŸÇc1¡�,ÅòÎOLùûpXÇ ;nܚ˟oކåw½oaòT÷.ëø½®%ërˆþNËkôŸâ󹞷êÏ�q<÷¹ÿã¸ÅïÄâé ¤m ;_šêl/Ðíz§ð/¿à7އ>ô3�?ùËôÙ­7úÂ_þ@õžrŸ+_ÃÛ;­ôäÚ$ „ìp€L¯í*2=G�„]ã‡-õ)Â4h}1Íü¢‹s@MSטÇfjí[Þ_’èe1j§ú¥f8�Ž�›Ä2é–<3 Ÿ¨àõy*‡Çªµçèu¬â—ÆãØ4ÜÚ¬­Æö ¼>ˆ«¦¦Ÿ. CË^c&7Úh°Ä˜ÞºÀ­ç‹€@ïûšfmæ± =¿4Ùxœ¨¦ÄâYõä[÷k¢Ü9]õ §ójÌ´{ØöáB§}ƒ ™�²_ž„8w%iøˆ/^Àb©udaQ›QÙã–†á¬^÷P34�/IpRS×ix•ƒ7‡cŵð2 …y÷fðÕAÌâð˜D Î~ôáò!¼#ÄùOý!™Xx˜òÜlH÷Ú êÔh­„‡À|6ó’ǬkñºÀ9iî3ÄÔŸøá»Ùйâ2F‚ñ³ºfvNÍÊwú†h(èzîP;Zc.¸¦ŽlccvJ�»°­“ãbXÃN­Uœ¥q�òŒˆú.‚5Áîøé%~l²zœÚ^hýËF*ˆ·u�ã3³î‘ GQ—Æ|©ˆÏ!Å©/¿ÈŒ�°²�—š"kØæFm‡á-¢›æE_‡Å®M!éq1ëf.ùV�€ÍŸDäÄ}ÈQ®•Ó‹H–3×ðK?miÖÜ4êÑMÃl©èpg”!Ѹ€‡ ìyŽm#Ï<;¿ôt5žæÆbkÃVÍôƘ(Û<Œ澉ÑXÇóR0säEBp̓?kõ"\Vl»@ÎãvÉcì%¸ÒË¿æÂ Gû—tµAW&�£íäÎz}Ý^³П¹ÑE‹­JRgÏÆÿ,ÂAá?ã½Dó�·ës*q¸Ê]Ñ '?Ø®¶úl¯{p.]¥š9Ž�k~BìÕ ŒBSÎÔ`1Â]~kN?crмNÆžn6Ÿ›†øpâc³¦ò),5 9k³«O(²Ç{]sîX«À‰a¿î‡/)}¬;€ø7w0ódÕaÞz¶眰9_F>߆<ëU>þmõE�÷„²·°K—úc³2sÅ2m�ìOr$'‰'ƺ�‡¤j£Ù‰™Ú†9á–QÂ…Æ ³NfhŒþ“7�ƒºLçI⎅sãù{ÕÑ£¾ðaÎg8ÖÚ5®Žó®ÀÓêcšsIØÌ wiZ/&<ÇÿÝßÿÝã‡~èÇŽÛo¿cá\^ë� J‰G�yg|÷»ÝíxÄçÎqÓ�wsܪ¯@^«¼‹£"LµsPõÂüÿöï÷¾ïá1¬…¶´g)Î� þ×¾öæã O|b4éË jwä`Ìažï;^ N i[Ž«.ôøÇ}Ô7fô^Í:„!¶¾«û‰=ìà™±–{ ÀGßHâ<Í€œƒ)UC\0] ¸ã"Üį~×bÎ Žt}ø›/&�04ÇÏø¬�Wl^•¸º†j2ÉVô\‰ÇW¿{ùœ}Þ9øóQ¿òj¼(}"W}Œ› c5¾­k±.¢ó% Üÿr�E>òc?ßj|ÞŒ/[°'¾¼‹ ž‰åBÖ²K±ìUåjèæŽî½žÁpÃ΋4ÞÍû÷ÿÞ‡¯µù]bÊç^¹½dÂͱyVâºVbøóøY*7û"{¾¸Ì;ë‘‘¥dmŒÒºŸÌò3x ãÛ<¿Ûwa-¦+ëÓÆÀùhê³þt9ïœë㉵È�FÇÐC¢àÜöµ$³W%�ÿÌn�o½í6ý'ÌcŽŸü©çùœ�ª±}í\’?¶;¤ó¿ëÛÑñˆ/<^£/j¢&|ë·^ }ªËÚ²>”ìÍk›ußæU0e°'-Û4â;&ïI,Ö‘Åiºrd¢s›s°lIÙ/‹ÉyÁ’6€ ¶Û–Ú'z/üx’û\Ÿæ£ïâ²��J÷¹¶žk®ûî”Aƒ�zíâa:tê'™ÀÄʱÚO‹ù?6ìkï~'ˆQC¿É�- Çõ°ØÌ«Øµ6Ã9X`ÓiÌ?%)¾ùÐäÆ51\‡Gµ1g�}å kÕz}ˆµz½x[Ožoìý’8ü=U÷Úe & (t ‘FcÇ vŵ9·pòX×äK=æqB8c�“˜ÅÁJOî˺žu_> $ùp0_C Z;ìk €[sÓ¯6býº(`µé‹÷-n„R›yÝ.+Êq…oõöøKBœ0]ÇÁ±Ç©Ejà K2N£¥9ÃßܶP¯igMØ NÐøwmá�#ºGçâÒZö}Ýò€‡ßqS/TœJ Iþ¬+Š�ÎZ4ˆüÙâ¿Ö‡�=q»¸×)þ¬ö L.D„ƒ˜î‹m¾†+Ï£×<:d½«WÁ‡jÏÒŠ„¼€w\¿Ï8&ÒÍWI#'¡ ëZÿ"É ü=±z±¤y> qèÓæ”üïGŒ»«þsó•ƒõuS‡ ºmíοñ2�ê£ä»¯Ô6KºæM®ƒ|ؘ;ýjk®q׌�6�»£ƒéñB“|ÃXéàƒ˜5± (.…žlç9³�ŸvúÏ\ðPƒ@V�45GD’h´àè™Bž!Äm[Op™ò‚%u)«V�ש©ãºZpIj³Ž� §à2êO`³ÔìòÝÙ#4ÈáÛ°2¥mÒ/êWP9Êfžj ™rw:ôÑ9EÅÛ ‡ì¹Â$§^›éÎ'yþ¬7¿è›s@¸uÎMÖ‹š¸`G'¹ g.= #9ƒr%7êêg­^S(Æ`˜'7ߊuþçÁ颟}D†Žx=@Šã…!þoú7ßt|ÄG|ÐñŽïø×5xÊ´óá§#bÿ°‡=ìx†>��}Ãæ'ŒÖe�¹üuìÍPßyÛ­Ç—|é#Ž7½ç=0EýÞp�W=Ã;uÁïÿû¹ç¿÷{/•�\ùÆf¯›û„@©à ’ð»Þ˜?/6õ¾�©%¯®Ïõ#µ|\pi‹�Ši±+ ñ ¿Kt¬Cãqo'ŒމÖÀšzÁbHì }Œ‹ù´5^„q�ÿNýIà›ÌãÊ]ôç€m8/ìþ;ñ*ùèÓúm¸`È"6-]Ô…¦úËÙ9Tä ç0¹˜Æè‘Nݸö+h´bWb~x§«P¥™ûþ\€>‰Câ5‘a8›ç¼ß"*ÿ~þåxÅ_¼ÂØ<žÆg€‡:(?Ÿi˜¤ò89æÉ§E¢�¼ü`''|\|òÜ…0«ÆO~ÎÍ{é³üÞÿýÞÛŸéçÏRÒš&vÒ™{–6\êdà]rïöîïî||yû�œûʈçtXöI6«Î2Ã=ä¾?@ †5Lã‹ûúpÓÉ·^0bÒÜ¡ˆ³µ«œž ÓÚunõÙ›jÙ¨Zˆán�k‚<×Ó°ïjÆGKmeßзlmµµvùICÜDqA7Œ�‹v¯|Õ+7üUÍdâÃÏxošSãø�<^óº×ø ?ò™‹'ˆs›ÿ“Þf˜FÜìY÷.ëÊ9p2(-�#ó¸hLÃäÇTX/ +zuËïËàÔ± IDATŠL 1ε;Çy\fW½R×\÷¿Ôg „pžMÀ ÈNnÓ¯¹°äÉŸ s¿Ôã<áï‹Éš[™ÏÏE¡k�ÕA cwS³Ýgr :ÙXµjc¼øÆ>i6;:©Çx†Ûëf úqýÈ?8¯ Ou¨ßy�#|DxÌÐ1ppÓ\›uÌ´<øÐA›ê�Æp¯u}É� –õòHknîSÁºÃšõ¯üÔi‰8‡6 Ž»œµ��Öp7Wm�£[s�Îy´ýµ`ß³–)ËÊë½ÂXR×%g³.M ÁcÚYw�6cw¯ÖØÉÐ~ö”ø“ÎlÉrã×Úù½dó䣖ù`Va¨íOªö1>^œƒÀö*zb!Kñ3wÑ7Á‹cr™K‡½0`HbáÖ�bËéü€ü/‹K¨´‘bîjÀÇ×"ÓžË�yŠEoûh!™Oçnä¢�l™›F‡ý›/‘Š4¼˜Yb½òq2ôeë‰,æÕçúÈ瓼+Aí—½ù°{=ĘèÚ=³ù:k‡{‘4 µ‘Éã [-˜+èjœañõägßÝ”$çÒ™¯áô4çê„ÙSžY³èнÞLœp}¢N:ææ*V³Æ'Vã°‹`4ãºO®î­Ìi„áS‚®o<‹�Ì™à�ÜJ¬‹gåÃ=ͦ µi0‘6@ÙÈOsþ ã5ë(ˆ^b®{¹â*jË3¶®½=œ¸väe^jUÖr:Ò‡T‡¡´ûX«\1èþ‹W¼êxž`½@rm\ì'ûFB}ÇÁ¼³1{kSê§á:‡mMëÅ_Ì”6|¾?%<ºB�cùzîNê ¯Y[óâ #žàÏù½´âVrÊÄï ð+‡fûúÁ ϹžS³óÌœKæV yh¤8e­ñÎëš�¡5'ã«qƒ©^Rø9–É4æ÷4ñ¡Y¿ kƒrµÉƒÏÍdË«AçïT>íOÿôe¾XA=¹±~?~ �‡�±�¢id rú[ŸŸÿù_<¾ÿ¾ßïš…3÷«,˜±÷O}xbÇÖûŒÅá­ÏvÍÛÌ3ÖÖ/ÅíûÚnxÃñ®ïünÇS¿ú+�·{»·�?ó† ÞsQasìzuïðºðÏ‚¹ŸÒ ÕÐ�QÖ³xß ÷žƒ¬Yõø|ÿgO˜O]J5=ûq§s;X©a Þö:´†Y~,&øä�}'Å5 [Ò¹&ø�uξ`·/Ê2>›×*Žêk~Ÿó¼`n"òŸz¼ãs^M¥xGá}Ñ—Ÿø ã?;ÞëéL×Ó�#Åv¿¯� –Ÿýð‡/xÁóý˜Ì:rÑ�û¼j!0ï@äw Zxœ‰ž›¨�õõT.%RŒë9þJJ¤ü:YÐ0å*âÈçA�~h«WÐYãÑ7Ï ƒ�r;— ¦ˆÏy ¨óL¨Œ‚q0Ã-nÙ I¤×Ü|fÛOvEhÄB÷X+“ºå—� -š\·FcoMÌÄš5ˆìÉ·‘õ|;팚Ç\=L<œøóºg‰'OñuÉŒ¶•sù‰»wm¥*ëX�£/5./uë$ÌT¾ ÍKª ÇGÎwIWÇ _Ú„'—w_Á^þÅi3_éá¥áŸåeÚsÑkÙ0K»l53bÌ/Æhñq ž$cµó$"ÄÄø]KaÍ=¡§Æ�cHÉ3]P¹" <2£g°áGUú|gØâɺ©7öœ®\«Vöí¢çü¶U£û®wz0Øù×Z5ïo©F[ë¶Nó4Âh(Wsè,ÏÞá2ÏB ¹æ»†Z­ÝòSO¿ÙÖýBéÄ´ßëZæ¶\M92<õù v«Mq^§ì­-q&Sç1sÀ0ô‘Á؆ûÐØ,í•�ûö„;/…äÜa “”kn“KæŒ.¨œ”`ÇÀ—ùœÈ“caÄëØÐ'[�ø°ˆƒ‘ͶmºÆ¿t“on!Cú¦�¡ü´¦Dቑ¯£¶qpÑ—C¿´ùß7âG­ÈÀíºT2b�[‹ ù‹¼%˜¶‹»Àèrµå‹ÔfLjƒl3…Ïæ9‚ µAV$ŒÆæ•¯µ]õ[ã4 œ݉‰ú8¼gÛ¦–Þ{'Ž5qc:˜™`îñÕO¾‰A?-¹/9²ž“›…*‚õ:,ÒØ@­˜Œ¯q6Ë«ñkMc— âÜÔ%÷¥M³ ‚‰™Æ°5ðºf�Õc!²ïü^:¤Í­ñFÎZ7š^6ø7Økbe?ã:&�±;ûÁX5ÒØñ{aÁõˆ‚Èk.@ýZ#¶¤“N´b8ñp\èÇM³ƒž‰‚Ü3î€ !nîÎ Xh‚#:á1Z°¹F�/fk5êÓ&.¢ºèåo³`YÀ%fL¶a1ÖÀˆÜ5iõÄ·NÉGÀÄšwÈM Éü�8¦§ŸQ©µnÕQ$ünæ*�,æÊãD×|ú7�·ð†+Ù–„°Ê7^¹£1ñKœì¹3õäÅ—€¬Åë!ÌåËxÈÕù9PÞÆ…À…_7+”Ïë)Þý8íÐxÖö3?óìãWõ7ýŽ©ºNbáÔ°‹bÈ™ßp¼Õ[½ÅñèG?JöùfÎqûâ„É;“òΫ{Üt÷ãŸ~Ò?ÖŸ_yšâΕ¤&ÍÏ;d¾çû~Ð*}DØ%‚¡4e×»?S‡7¹+Ol3ö`?(ÎëaM4Š6cjœó3k°¿8 Z—#¬Ãe™5?8ÆÁÇê‹ÀÄûÐyñ¾-…ÁŽ›\ˆ³¦$Ó,?WÜ6`m™&Îï^+c^’o@:§ƒ¶ùÂ(¯ÇAyÍ3.ˆò<8üyupšΜ·ä` w.Jé|ãΘ»/ý½ß9>åŸ?èøéÿö?ýá‰ÛkQï¦õ‰Â7—wÍo8Þò-îmˆ×ïQÎ ?&%zެQC¤Î�—|ôs0Ž9�¼Zo×Ôx\Äû¡7+v*Íý b“ºO¢ÃõAmÄÏ-àgË:¨í¾ó‚C×€Iá,cð>É—ÿ`IþÔ/€Ž­o%Î ?ïWìÄÉ)»×sž±¶7ßð¯þõñ >à¸ç=ïn–^� ˆM99ª×b×$ü¬‘µ¾÷{½ÛñÝÿá;õMíï~Ü1î�/Ò”™ªWjÉy†/ç¶6¯Úq²Éî9~ê‹�]f赚ø§ñ�ÊoMÍì\ÕŽìÙ�Ú¶Ê|æÏÅÌzÏÑÚµ#}oæÇf;9sI�6½ò[£�Ô0L'xiIPµÇzÖk �ÅÃÄlG™«•šrkËš7ƒ­!t´ÖefX.òÀ]þ¿ “œ!\üfš$ÞL¢g^sgïpÇJ:lZÂ¥NÖy®ëBfÑœþ—ü3Wç‘Sr¾æÇ’业o¤®î¿¯gèC|¯HfÄVŸ—A̾溡ˆ–˜üÈÀúü�!>×¹pèæ'ØÖmÞô'bò‡×»œ‘œ…—w¹-¡EI~|XrËú£+zO�Š™4^·§¥T֬ﲞ£B]+–Pr”¾Øcñ¶z8Ÿ9mâʳüBÌþ�Ýã©Mk$ãÊíÇ®5ƒŸÖ=ÎŒc4ÓŸªÃ§,Ò`ÝÅ÷yZ¹È‰n´¥{ƶ1fàdL¢ÓÞÌCÎÍÈx_ßæºàqmq*~ëÖs(“¾ìZñhGñþ�ƒ{(Èl²%@û'ÉißE:$qp�͆rq;yjîIl1ÄÚ=z.*t¦ gãÛËO,·lž^D´¡ïš’ ¼ŸŠØš•\ΫKÖhmÆÁ’oÇè—=-æœ@6p®zü¿œvœ9¯êêÆ¯¼@E¼×ÝѳNrú$A8ós§=sØ´ˆÕ�®—Æ–þJhôÏ*ˆE>&6‘‹“)@J?�±ElüÑs�³{0³6ôÒX[FÉ�mÔ�=šrÄ~Šã::Ñì‹lå…§Äð¹FäÚëÔÄê›Óq[Ûµ±WŸ»°7"¥F‹Û.“Ÿô£¹µ‚››_Ш'>Yã©þæpk©Q @êel-2ÔF½x¬¢ñB Zµó4ÙJ ÿt³FÇÇëh;ð·:ÓØgŒÏî1ŠaÂæ1ÇÛÜç­""4ëØúa`ÉùÆãÿèßùíß¶4ó"¹/]‚û å íõÉZ*¾þ Þ‘›�µò¸ŽWØôí&ØÛo»Ã·Ûn»Ýß\zëôžßÛm·«Ç®¹ýØ5¿eú[o½Í±á¸#Xùù JÛ”£Ž—�ÏI3Ÿ9îðüVÆÊ…î[ÄûÊW¾úøÁÿò£ÇÇ}ü'_ýԧ؇nÿÉ¥kÉb´rŠ¥¾Ž5tMèñ¡TøÝ�� Û¥‰–‹ó®MÍÙ � ˆºåœÑ9:z 7õ瀡îõ;ØW€L>~j”ï÷ÆúäL!™ûò�îWoxã]Ž_ú¥çˤ„$P·z i~¼ÁÎmküñ�7Ý”XùzŽ;Çà\'�*~æQ&#ùhäV˹'¯Auâ�Ï0åÿÎS`uç>ÅýǬŽÍE*%wÒe,ßbL£‹MžÛåÑ„’n$Ci}I�àÒξšÛÒ| Ñß¹÷ƒ‹EJ”ûnôÜtãMÇw|ÇwñaxÜtÓ�¢Éó¨¥9#²ÑÒ±q6p˜œˆÑ?þÔÿ�ôqÏ|Ú7òÁ¶+N´EKÎc£´Y«03²‡ñºB€Æ®ÅŒh¦%P ÜœWÃ=•ã¡R òwÚ€áq§û÷Æ»{&£Â9…0n„iL¶äklçÞ7Á{Ÿ]<Âç?਴y7e¹­w8“Œcò&cnÉë=Ð<üÁ9÷ÄÝaìÕ{rÀË Žx5‡±8ù¹ œÑ³G„Å$ 5ÈöyRɶ/&\;…¦­�«»ö_@þéVNs Í=9OBã'As^úÏ`ì¡Ã&ô¬Ùv81ŸÔ“'÷�ºÀ&®zÔÓˆ ¹§žDÜocÑêe8_5Z•C«”ž˜®�q×aÉ^)Y½‡\ÚôØu ÷ô¸°;�µ:™››Ç›måY¶ð,»cœfQ’³zw€Îé[/À®ƒúê7YHlk%àvꜵ0xѶjCÖ Iê]hsoôÅþ(¼Ó¹ÃëüYKü€|ö^w§¸š¨ÃÁŸµ�b8”qÙ…§Y³üëµÏÿÏØ»€í»–e�ÏZëÏZ‹½¸ EÜŒ›Ô¦²ŽÉJkÌMs¤ÕLcVÖhnJ P(RHE7 ²SD ·©¹9š™¬P ÑÌœ‚QÜ¥ˆkËZsþÎó:ïç~¿ÿÒæþ¾÷¹ïûÚœ×y]÷ý¼›ç{¿÷[<ê•A|-›˜þƒOk`4¦†{žp,Öy}èäu®e€ÍW[jž€á[óQÍñxo)Ö($°#c¬u¨=3šÅ:Ž¥e æ¾Iëʦ¿€«óà&ÀE¡e�®1�¹žˆ­dÁ*.ƒ�>ùà—èì7€Žµûb£æ †÷"–!5öB�O¹:–b¸Õ&³piµA·�ÁcDßï;þä“ÖZÀ+ö ¢óúl½YaXë,õh¯GóÜi¯®ysÞB¸Öñ�šãêx6‹%Ó/8ÖŒ‰k¾ó´ ¦L1üÊ„|þCðjF�ßÊŒ�Æ”ËÈì æè÷XŽPý.hÌDºÖ_s3ª° Š;F þŒÍýª­s‹-GžqsÑö©ô„1÷X:£"_¸2Z‹_2�ûü›(ž¦÷¦Ç¾mÌeê·Gªÿ¾ž§Cjb{bí R\æ~Éë×ú­û*Ù,|Ò úÊ-bo¤6%D¦Ÿì�Á²�œÔŠÍ¿É�´k3oÓ�ÒˆÜÿÒã|¨§ÖO/º?°îšs±¢{?hQN'¾l$gN+/�ñ8�äÌÄÎ%G=ëfôek¨ >É»i=\ÜÁ›˜•¹Ü�ó8Ôä)n>$õÇ!ÀuˆfYy1½½ bãclаoÓ0UC®[ó+Ä›9¾P$9ïhóÜ6òã‰éÈ~¥£�yu܆´t&t<.±æ)Ur‡8!š‹ëIRëâįþú¯ÿäûôøœ¿ý×õ¢4Ñk|ÛàÍ~V‚ÂÅ7Éô _ñä/?>ë³>Kq©!6¾B²Ó;¦ôî§÷øÿãŸýSëßMiÀ½ ¹¯ƒHÈ…�¯ÿ†çø³õ" ö¤´5ÇÑ…òáÅá�z÷Þï8líÿ«Îš“-µR“àÝE”'»lëá¨øì4&Œm–-6¬ÉEËûâI÷�åj>CŠ„õë¦ Ïëˆ=²é<žX^[�aßw�‚‘:Œt6ÜMã!u|á7ûñªŸýY¿Ëˆ±åBëÌÅd8³¿i¹¯Ò¿vjOñ®/æ´k7]KÍd¾f nêùrlÞõ.}IÉÔž­csé»@©©×Y~î¼ëÎã—~ñ�wÞþÁ‘ŒðZ7sG¢^ÄgLlÓ`È|k�{}O8cr~¶ä\Ô?xÄØi™@øŸxÉ>u)Æ Ý‰ï`dÁ?çØF·¾Ñõ‘ûð@s1– ±u)l¯úÂs|¥Zí–[n>nÖíŽ;îH.c´÷´üð×<÷DP+¦ðïÿû'¼TÖNo,ÙQqÞ¥Æ~Z˜‚p %𻵮Ü'ç¢~dI&v„ìùäŠC±¹y=¤Ç×çŠoÖÅMYàvÑ1¼šƒ¦ˆú®Ëî¹Ý 2ßÇ�¿�á,0Ñ0ÿsÎöÁÞçáï{¼ð…Ï;Þ_Ÿ¡J-˜5Lm:�áÅ\=¸kºÍãoë9hÝtÃñ^úCË×?ã«õ¯/<¾ë»^ªÚ«@áK¯ƒû<ŸýÁ~&‘|† C¤ÝLH Y Ù-Ùİi¼ Ú¼KÖÕ,Ô,ÊaH-2ÌÕ ´(·…ž¤tóçž4!)OÂL4sbWäƒËn7Ÿñd�žt0È �VCï˜ê=&AbhâAn~òµÅ¸|h^\ûÅÊ¥ÇfZùtN¿ãµŽ» Û„ŽU±S½6ll�‡ž#ÛÖrq*‹Æ8{é'÷ùÑ”+}ò0\p¶N’IͰkcëÅ�è³¾‹‰-ìcn:˜«Ÿ�ŽZª™Ÿ†­…×Oýf]bc(LNÃw°ÆÉ�í‡Tã‡jj#ñ1ÌÕX�FAOëœáä}âÛvÛáätæaŸÁÜõ v:g]™C,áŽ0x!wæ7nâ¹bÄd€ÒY·ÛÈ­uÂ"¾³ï€œ½Òü�2¸æ+‚)Íìcó"Š:ã¯a[ 3¹×šýäÅž|ýL¹Nê‰G+V{ «Œ¾§D†ÆŠC¹¸Ç5üõãlŒ¸ö‹À”ò¹'ÁÂî¬s0kkZ /õt0«‚¬¸2H]c¿à˜c"Å¥!tPK¬Áe®š3$jK‘©�24<¤'ZkQ÷HÇ>¶H'÷ a‰ãŒ<ŽÆ#~ÙW¶´ÈBMyì¾I/ RI,—64&In-Æà®Ž˜j—u�,r ¸£ÆH¿PF.}bM/Q1]'.°a§û ×JJ�ûøƒj5t¶ m_Xà‚Ö%Oäo:žóÜgþ“>îø zäÔd¡h‡òH $U­þà‡ýwÇ'~Ÿ?^öò%«\ô¡¾\T½W_Øq×�·_þO:ò`]¤¸œ¡·ÊÁœ ¯ù…_>^ùÊWäB�ð›�Ò÷ gøÃ3ü‚¯üd|MuŸ¨cMk 3ÑQÀ©¤ti|QÊ„ì\æjxù"D",N¾0"ÿt Âõ’“cRÁ¯6c‹·1þ/ÿ×ÿúøµ_ûaêl�Ž|ÙK5¶­¤ÌKð®‹ôÕ™£”]'ÇÖ5}9É5ýkø»î¾ë¸[·^d2_9¸ú©/2ð¸¨þíö&ɸïŽ2yž÷ÿðòÝ©Ôø4S7ü¶Ö<‚¯ øºøÉ˜¸]sD`pÖŽäÞƒTªëJ=ü„^*8úœÅNkÁAv¾ &]/"ÃÆvö±—õ~ðƒYͼ×ìrŸ nš|nÜ­·Üÿø]ýÐúœ¹1{ž-Ùˆ�m9t=Èã‘\ÔRqÙƒ¾/þcG>à a?³ß{Û÷RV9 9ºÎr\õ±lî••h÷ˆÄáãÆóÞã‘�|¤/Vg oTg •¥dÄå—=ûð¯­ÿ(P8@ˆ¼�„¼|?%Î÷Þ$<ïÑ@>þxò“õ.è÷x˜óÇÏöTDCJÖx Ý6÷Ûµm_›ÐÏùA­ò�ÿàq�>>è?ðxŠÞK~¬�v¢ƒñØvÉ©{8h®Œô覑§†ÅHÞÊ~°‚Cp°$ÔéŸú!¨¨À„“‡§íÐU-à ´ÉB¶ŽßzBLú ·ð°Ç*{Étt`»ð’{‹ÓäD¨+­‚`^Qº>a,Í"Ç ë�˜ñj…Ñű'WøR7ÿ‘O€®çPp.;Ùš»eÅ‚†ð`Y£unà×¾©-ü©��ëš<â4žéÆàŒ?b´Ædë1Z®c‹àtÙ7ï%7ÓÆI †ÇÀØÞ ß=[^1ðÅL?¦L~-L”H§­ã¹vCuÏA¤ÌS½Å£+‡ê’”™ÀFœx’È(þãþH²‡ÃÅ¢ý sûPð NbMŽ1k:zB™—æ¸z¯œÉFh)Ûqõ®%aûÌkjŸ4Ÿüp ö3¦ Æ’Læáºß“ç² \0Í-q— k§Ç�¶©­‹có ,“Ń:ª­Xšæñ[’‰C-l~œ®Mü<‰z¡Oô^W›T‰ pÀ&�vg¾Žg«ó°d8L+ÇJV^5 0Ê„´ÔîŽ; ›0¾¾9_‰]gL¶ØX÷•ûñBÖ~ÞƒAƒ›èdÒÖ†—@~õâ6‹ù¸š!´dˆ'—AÀn|-+°!ƺ¶ãK¼2Á‚›Ý„C,Æ)„FøÖôµYòÁMçø6ÂFö€/±ðcĘfœN"Šœ<§UÿO„Z%¯³~§¿-ɱ{rŒ7p��ûßøìà''Yˆ«ñ™ƒ•ÚÁ«úȬ&’ ¢×Ôvôö…?†@�ƒ‡‘F4µÃbo‹ó& ~æÂšÌ“tä­‘« Wô¶'¢¤™AÀ]±±¡¦mŒÎÙþâ ¬)Œk;ù#Z.2hÝ.äžÌÁ…nŒ¼cæõ�ß¡eâ9¢{pÓ$•Þ/¢ÑØ6yX¯¹ëÔ~¼Œ«ÚÐrWž�]ëÈüý[åS¾æŽw¾ó¶x¯ØÉ/Âe¾Ú­·Þ|<ö±�ò‹ÿóÉQ.–q�ð“>î/ùêû­9úG8…JN�}Ç;Þy<ýk¿Zvq cè½â"HƒÙœ\«æ0¾�O”%û.ƒ³æ\„Èg¯Ñãg¹zþõ0ïÊE@ä<¹ñ� ²‡opқIJgF7‡�åó¿](2×{/ºäLá̶Œäe>ìcjjÌÑ«³�ƒ3¹�æ0«&‡ÿÝöÍ¿õ&ç ¾/FêR/lðbeñ�ñòÌ^áç¨ðÑ�Ÿü陿/x*¾CñJ€�'�[ÕÁ‹€Ô³`ךgÊ�)è,—„o<¾ûî{Ü[ådd24RËÔ}P�¹AËcqq8ǹ[çH÷ik{�Ïåƒy‹Œ;�’C‚#Ð|. áë:H¼|F�Ä¡U“Æò‹~ sa.<É)¤ºáx€Þ}÷ßl[>¶Õœ²Ü©oæ†)�zðÓ¸¢Â—[Ì,æ€-B~ö°‡÷à씬 瀿QW¶Ž#—®CÏæ–É"ã9w€Wc}}ª¯o°d B`æ5€QDÞ7ŸòÉŸì�*À§ÍÃ+y «�9iM©/À+GÇ Îy ÉYׄ`_ËC|¸Q­ÐõúÌÏüìãé_óäã½ÞóÝ£4øö9©9^ÌI.Àß~;k„Sü<´`0:†pÇ>ð�÷?>ýÓþÒñüozÞqË-·ê;¨ra�õp½D`ýàê\ºÒ,nŒ™´'H<n|ë5‘f¸ ÷;I¨á`²~ ¸n�½ÿ$«-@6qä㨨…÷Y¶Û… ¾ÔÞä<ŽŸcÊèòò•£�¯â³1�ZÑŠ#)nÏи;Šr"×b ÖÎæ5>æŠ�Ún e—ûÖû<ŸóÇä …³tàC={"ØHèV½->uá.~q'�j—Ùô÷?ìñü"?{*þØ,nPºFóóÂYÔ¬ks!ï³mqVÀ‘™Ã©£­µÊúœr/À>5aq,üOßÔ÷Ä=Ï E•e9³6¹ïÇå!=v�ÇEÁ‰?5±§iµÌô3yOD[Z®‘uÂ8ùy$óøÆæjMÍ ¿-oó’Ÿó…ãÞhlñSNNEà#³ïæl,_y”m ÍU«·¸6G¬#~äü±4·ØLÄ1´gÆäa?¦�Õ)gŽ9‚©çR¬±}Õ9S,k…یۥF¤ZÙGÏS¸åwÁèb²ƒÈ]õÅ�ˆÖºœ-´î<"Æ áÜhRX�,óó¸I¼7Zr•PÁv[�±ÍâjT,Hµ!3`¶ÕÐ ^µC®Þ ›eÇfÁ(±¼�56üÖgCa8m‹�„ËøúÙn0Ãq'Öņ˜«2r8‰ŽÑ²%—á†l%tiwæ6&ÃÞ䤛ãnþ­áBj~øÿeYxÐuŽ`7FCÐÇ·‘’ëïÑŒW}Ajk·øZ¥aâ_â]ukX÷2]y�b­08ë [>ªEeñÇ+‘N¼Éœ¡Ôê´6+éÇ$8CÚ˜;O*àa.p"ÔZ»ðŒ¼µ�Íø­ÈòV˜3Ø ‘ݦDK~zo�šKF °Œg9Ñë,�†²v,fWx�ÜD4º ì˜SˆIßµ5®±°IsÌI– =~B�ªŽcgÑ.Ûǘƒùzë×\x_alËà €œ\l{Š=ª.âìåâEB¹H>Hú.lÀ&ê+~êeÇ«^õÿøxäÙ}Wαå8yM®�xÄ8>û³?©÷gëÎ;‚ûEŸ¯wñ¯xgm×ZYªÃà0å_ꕯ:~õW~Yù×¹ÄrmÄÓûBC*5K>6öᬡ—»Ó-ŽcJnÉÍY¾Ü—øßE툜ó�µÐ؇{ÿ“Ð\´Ê l术è[c÷\$0:lÇ^Bk°ç‡¹Ó;ÀÆ}s@cÈJHmXçý¢BllˆñE[çÕÊ5u½Kÿfëý",Ö‡v¿k×|aÇ¡$g%lzÈÓ‹7É?²p”Rñ»û¯3`{¯‚9üéƒ?ØÑ$§¶ÙD£e‚{5¿¼@&SS›3ÃࢪÉ)Ó»æ 9+=ÿîLM¼WÍ3Oâ�]ÉÌI1]nM �,6â‹ÙØû…Ô�8`è†_Ð,µL<ô�IgÐݘÑ­¡„o¯§@»G¸°Ë;»ïÊË�‹AŽCÂþ†ãý»í'ü¹Oà]¹Ï 6Ì÷Çjüã› „�ç³ìÀöy“PŽe{|ßø€Kë…`ô”ìÃÿàY–*NýBþø`çF®ñ‰¡}5{йlxÄà¼Mv=¸‡gí¸hÇ¿³Ó¾üË¿òxÌßû¼ãÁáß´cw%ä*-!V îίÿç×ÏøúgoyËÛd'OÉüÅtÄÀÂS�ù7ï?û±}|÷Kÿ±Þ…ý�õ.ÏÖ¶µábIsw„8xÀºÕމÆ&$¿p�±C�½›óØ´DÎeàåךøÅ6>ì¹â"–ø»`Èϱ³ñõ!Ì7…L eé¥Ê¶g¤Äqlœtüx~ž4Ø‹vȬÖt±«Ílcœ“ £yå¬Ñ�}Œ|ò\IÌzÙšŒIÈv †|m 2 h|cß6ø-vÅØ´È:>é fÏ |˜â?=cÿ¸G†è)œ¦®'«ÈÖÕ6‘.ž´JßnÂ\,€p…šÇ%KOÀ­™Ã^5ž¸Ñd·p”Û¥—Ô± gMw9Q/ôø3nŒ�ñªË'âÆ²µ"”×`€=6Bq<ËÑ•`D¶7žó‚_üb¿ñ¯Ÿìøn‹/wÁ«©q{ã±h“—¹G²Ùɦ±FçZM½¹r`nw˜˜QŸXŽeÜ8­·ßž±Ðë¶×�x†ýÄ´xjÁØmÓ-C|äÔÆ�sàxácã3D¦Áž»=˜àµ>®µæ0nÀ#OäS7ù!>Î[.{ŒâÓçìÁÖ 1múÖÁÂOb¡l¾ÍRs§Á8M‚>m[Ù)ŽÒØÛŸÀº¥>ñ¸¨�E9WlÉ2&¾Üç|Ã8�9D°¡ÕX~ñm¸ÿ 5�ÝГV?øê‡#mÕÉ3For,÷Æ7 üÄÑ2(aÇ‹ ÜáÖ ]ñ|!ÛiÖøídq]8xà¯1獛YÏ¢¤oèò;£lv›‘Ïϰ÷ b¿0j\¹4.Þ—¾Œƒ‘üÍãÍÈÒ ±mù€etZÁ´=/t¹é¡ù}ùWøKo/ðäÄ„táÄ7ûþõ¿öWô­¢ïAt®ê¨¿çøÜÏù¼ãýô¯�­e}—¿ƒ¯çßäú”¯ù sáMhæoÓáŸ|6y/–Hoݼ°t½ €·9tM˜ï¹hŒo/„ÀÑ�µ L˜ú3œµ˜z‡[n¾˜ÑײcO Øe?3¦±Ÿñ ‘�±�0¿ª�RS»Wô¸åxÁó_xüå¿ø?éóo��b:®1l–ù‹.ؼ›õµ¿ô«Çç~îçëóYÿÉñ¥OúŠãÍo~‹ð©Áe.ÄsÑ>Ô#�îw¿kÇG|øßÿ½ß}|˜¾!˜½Ì¹ÄsDö§÷¨ë\üœÓðd™ŒGn|B‘?œ$h-\néc…`æœLj©uQ3·BruçÅ«`ê]~›)g³ ×…\6ŒËç2‰µüÁš`ìG¾Î 6pÇÐmâÚV>�ߘÎÍ©�¾{�bƒ¤†#-ÞRgàµÈ‰µ|f°:x$¯‰kW€uÓ¸1Ó¼– Û‡s='+ÔmäœÖ ~‰»ð$s¾K0ö Q¸D°»˜Ë~©]&Ü�u”åjI+úÆ+ÎÚ3ø›@FâðoågËzÊÀ6ÉlW“CkL½­²Krè,|}sKœó‰˜�7§Žˆv¼±Å&þxh®X¶á\7˜Ìd‹Mjtb«:ûƒ‰ÀTdŒ0µñ(6R9†�rÀ½8í·zYˆv4úëôÈá¼î‹O›àã©ÆÂ¨�ÖŸûÂ"rn愾v×A  ƒ=µªÍÈ™¢o³+|�uV¢Ù9Þæµ|𻘠8[ý‘ì1“Çi·�ˆ¾ÛºÊÛyŽ!znÎ5b37òPã±;ƒTµµ‹6ª‘óÔ2çÏfÒh8 cª9n,LÇê—Y}ÝiÆj@¶Ü-~„Yä…){<¸Õ¾ñí7ÒØ×wyJæÛ|Or?q0ö†OLÇͦ—`ù˜Ôf(n±w¾“Ÿ}À×�Oõ´µyë\¹0V–޼©¯|…[,«-:㺞[žÍ™Œ6o c�­vyšépwƒ‹}nwóÏpr`’tÃ�¹šs§>p‰ñ•Þƒƒ©c›Åò+?\]ÐÈcðÐç¢Ä"‘(3%.C¢»Ço&àYX=uÐ-Ü#„»yß­Cópg07ìÆÖùkZ�c D?öØ@Í9Ž ]–ã<Ñ/Ž ÊÉ|e›'Ûq,|ËË<'Ö *«�cq[?ó*fø!uC‚kÇZuDk,^P¡;Ûˆ-°½ò»/¿ü«Ä™ë‰ yrðm4“óá Ù=›¨‰G}AQÔáˆÙÜVý ?&‰ë*Ÿмˆá–ø‹�i ¼ÙjYßô™sŒŽÑÕfû+Bxíxļ~­ˆ9òáM Ù‹m`X5æç žÖ³ÖÓã®Û¤cáÎÇðè¹HÄÅ?ÇŒ=“?k�Œž¸äs™«IÉÞêOnrŒoÈG�رíÆàóâð|ðôZ*ÞE�p±,=cZ/J…2ö6Œ†—ç±·^±\[©�“UÉ+V·uÓ Àßü¯¯×Çÿ€¿�ÑeOuá/m`tñï!Ç?|‹�_zà­<þ—ÿùSŽûéâ ­ûΓ–åÐ*ÿnz÷ñÝß÷Cú—7ýríPêÖ‹@­Iû:¯‹ŒA�Ó:jà:º Ìi›nk‘}GÝù<¾ëmÙ*ÆÜÐcçuùÃVŠÝv±ÞµoqÆ.û$ŸòÔ§ï¦Úÿ¬cñ¼Æ3i]�1? |ÑŒ}�L{ûÜCcdM­ié ½¦/qùäOýd]oº; æ32‰›xÂÖoþøþìqç‚»Äo(rIªÑ¡çìxæ3¿öx�þ%Ù­æŽîA˜¹:›uó�Ò{•ýŠ[•g™˜°ræb꽺à÷ ã;¿ó¥ÇŸú“å/"1.a40¼Ì¯FÞwé¢ìÏýükŽ¿ýÙŸw¼áMo´é+^ñŠãÑ�yüñÆ7¾9÷7H7ŽpÛ[j,ž!íýúïÿ¾Çw¼äEÇ'~Â'™d ¦Lzÿɾ1ÇÌ&óXq%f®‰¸°7=ƒcÑ[lþòqj—Ž‘�ݲ^«/ÆÞ Ñ%Orký6ó‚•"u`욺8q«]€˜� ]ëÔ0ëa¼qZXvÙÖ‰’L™ºæûë+ïâ4§ÆœyäŠ7 ÍÙiŽ ¼Ã�S“Bý†®;c¢×í¢6ã¿|†÷¾Wž6hàŒ�ÇWââ3"¬Õ$!Çklwz'çYL±F¶µÅ Ý&¯�ûᔸs™‡W3œí[‹Ô_~.Ú&k.öŠ«I5‚Ó_£á~rnåáª;nÈc9ü�»^á¿MçE¼Ä4ä¸èk ÁFŽ`ÔKÓØšÃé—ø�›Hž€§ßÕn€�ÌýØ…ÿ‰]çØï¬Ω vöÝð�g®öò+Ny€áðÄÍ4t´é ãü"¼Krž»ïÍ_âE¬4ñf²93ÂÀ$w5‘‡!-_GQ@sÓ•ƒâ#Ϙ^�jÀ-5Á>©)ûWѤ†ų¹º›½>t\A�K,à)÷õÈц±“ÆêóáÚc%YT±_yÙ\OŒÉã ¬Œ,�ó×/øÒ¼'<ê�ä¼(„÷[|lB­."&WtZ�¤Àz*®~bË< KSË6¨¬ßxª³�¡f¬â�(:\XÓá—S™X^“刋Î)Ý÷… ‚†ó”ð>p™Œ4¥|»é¼�—+}¸EF#·A,,è[G "kŽ|�>?¼Ðî>åEkÖ§ˆÄïƒd/| œï'Nh‡\µ‰?aM±œS ÜEžñZ«Ñe�d&0¨ß ¾ùÇ_ø Ÿx|è‡| ÷Z¢å( 2Üò¥Nû1âøÐþðãWÿÓ/é‹?¾ìx÷w·Ýãt¯ß lί{Ý=¾õÅßìšsŸ‰Ynupd§ÞT~têXÇ^ô?/ HÁù¢Îû%>¶<ž`‚�z°ý%.: Ô¼Ø|˦…ØiÀµ¥{õ…!øô¯½†l0ž0&’À¶ÁDk® &˜äƒ’õ/¶º8ôÅ_ü½ûîÃýCÉÕ|BÉcß×"´³CXž=M¬ÆÄï6ÓÔ¼Š1€6ó9¦#ƒø§opþ{�zÌñ‚|SÎÚÈØwGìS“lH .IåE9›B-ïrã]Hüsñ5õ4sà~\?]· Þ¶A—ÇG ½›ÆÔ@—…ô¯™3o³��"Yq&‡46pÿû�´Ð-UðjÃsCç21ÃB±˜K‡]¹_r0  ~Ûn˘}E¿èZŸñö}÷½FøÚbŒzQzK9ðKÏñ¦7ÿöq—¾øžáÍîâqô7þ˯wÜ~§ßÙ[.åš©VeY«ã¸õÖ[ŽÏÐ;�_ÿºß<¾ÿ¿×ûÍyÉ€ìÈÝy˜û�õ;óög_..ÊÆcjÇž0ÂÈ(¾Ø +‰=ô¡ïv|ÛK¾åxß÷ý«.åIïh˜ª¹Fö#ü"÷>Õ¾]/ð“51ž è—w•"ÿcõQÇ3žþ5Çû¾Ï{ë‚—xcj,: 6œ � ¥æß¯ê§ÿïã ÷x_äž­ÛxõÔÖ/<¾ñÙÏ<ÞGø¾¯3•Ôt·‰G,«5‡2y½ç{>ìxÆÓ¾êxÞ ?ðx±îkÍ[+µ’ÀÊÏ`ÚªoëIP‘õõqG}¹&Wþ=÷°î,ò…Lx€[çà.?c£ðžøY/΋SÞúÚ¸�‡˜ý4Æf…ÄÙ¸áí%K®‰}A°³ ^º­ÉøØz4ÑQËóñ^2Ä…[`#À]Í 1õóÌË8$ m•ß\|þ ˜VxjÄ/¹tMpô¸Æôö­MÞa5˜B›Îc+ˆ0n£,ßì›è÷<#_@+fcoAœSç]³ÎN±Ï<ÖcVö6Dê1kÉ\ú•?5œZÄX>œö£ÀsÖiùsÔ;¢äuÒáƒPÍóÍ/ÒÂÏkãõÈËé261)¯l^ö3 biVçʬ‹:Ö`tLñ屔ǣ>WIîÒP'Û‡ñ5„}¢ÛdNî2ä"Ù)� ÓìÒ °Õ°—®B'\Œe4ÉÁËnȆ‰Ÿ‘-'ið)7ø4Þžœ+8Øîv=aš;g 5šáŠ£9-1ˆíè§L£p—œ:ÚXÃÁs�¨ ^j'‚§ñÏP4T×�‹Åƒkñ`øIXcLPº‹xš_�^mÌÖN±JE5Î/¦jÃYõÂk¤:f�^ÄÁþ¸ ˸›]žp€�–¸„M`üÝ<ÕA-Õ<é³v§Ýò±5 oûY ¿í!wjûÚ2oG7^¸@kH9B1F¬¶¸›ù)ßy·.ô¾XRC›SoîÁã ¦Ÿäa3Ö³.»Ü4Çk†®‚Æ3üȹyÆ+ŠeKšÆ/£=¾vAîÐ:Ʀ¼ŠåshâŶ,™� »õdÚPÁ¶Eó �]Og›5]2jÀ+aßug±2» œš':ØìŒå'c�ÕætH¼æ @rOßéÄg*ˆ» »ä«`wŸ`K-:/nŸ‹RÛà í�ÚÒÓw�sA3rö‘×úÚî=cã©–ô¹h€_äåC^måcÙ9."±ßd9…÷:3%?¡±ÒœýW\ùó„}Û²y™×£À ãt­ÑYØ€4ká5!˜qcç©j‰]^Œ%41`Zîge ͱ±¢®¾oE“$ÛŠwb}õS¿îxþs¿îxàƒxM|éÛ<Ç 9:ÿÄ/}Âñ,}fÕŸüè?îàG�Sô„ à8î¸óÎãëŸù½ ì]~§µ µöžè®§#Ùûªì¹ˆ„†u\9MÍêß>µ/ùàèÜ´ö7ßï½ñÎ(g/À£ø°óÞê§KàwÓHîµRãÃÇ»W¯¯£p�™w �”#öÜ'ßO±?í¯þµã³?ó3übýZ/@Ô&7Ö€¦å¿ÏÖ}Îs)×Pö7êÝ|øÁ£ú g°¶8ÞYÚK\dúßþÖ_=þÐúÈã‰O|¢/L`ªÒxß~Û;µŸô®8á7o-ŽÊ‹w�ÎÖËï„SÎØûÛ{¥ç¢+z× lÉ‹gõº@Ê»äîåB‹Ö™Öϯcïó”ñŽ;nÓþÉãË Z›õ:0ÈÿjÎ+ÍÉ¢Ð`Ä«\ÌyøÈ¿”<~›oñ‚Ñ–j�Øì½G$ÛûØLÜή¹_ˆ½9ö"*�ÆžºgYrîzþ zýÚ¯ý†öOì’¿j Z¾ãíï8ÞòÖ·Ö7w¸ÑI ñââªï—0ÜðÀ[�Çés?ßñŽ·¯ù_-{.'WÖÒÖ·<8àÕ¹(ÇÞÊý_åvBÝù IDAT‘ [0×¾Ö.|ƒôøÀãYÿû3Þéæw}Ê”u²ÅºðµgìÆ–ûÅ>×¥&®Ør`ønL|?Àó9É?ùS>õxâ—|ññïþPÉ{užÎÉÆÄ—xÐß¡/ûøçÿòåÇ—|É—ZÆ9Â}‚s5Ü Ç/¾öµÇç~ÞçÏÞs�ü€G¨¶9€ùýšãÈ€ØÕgF>|À#ßïxòW}¥ÿ8Ź¢¥W—HÎò “4“{×]+û„ø<®¸îøéƹ³Ÿü¬ yIêIfÎåoË)ZkÝNMÉÝÐÏ]†c^±D¹çÈ£x]wG6ˆØ ÃÔ çvÆcúÄCæ½ZÊÐ6$»µ=ÖnÙ{P&rüqm¾øfRLrΘzò\WÛáh t˜ú`€Ëämpòz‰  *«¥.L#µŽQò—¯Ý9`§Çh-î6•nÅ'[í!ÛÚC‡ø2£U?Ï1ésîVŽu9;Œ ëø×4~ä¾k®Ö6pd¿GçõèZ8·Ä…“1Õs¾ô> ¹\[N8âfÍ#H�™âC¦§®š ÏúØ~dX{ÎI�_gÔ50üWq°æ×#Í�ÃóLž_�9‡ß؃‹¯üÒ&÷y`IØ™Ð!½¥ pÕVÜ/r…ƒ ‰ œmÀ�°5À ¼À–ü�ŸŽÆöÜšÁ ~1Ñì­q+#Šeê½åâ@'¯ažÃ±&EÑŠÁ E\9šµ‚�•]¨gëƒ JÂbc.SÏ`E�™Ûn+ApëÇ|3�޸à lã[Îóo#ú@=¸Uäçjòkþ]ãßöÖË í¿œ0t(( AÀ‹>½bS–X›µOrMhÈkrc|³2Nï4yë—á&�?p—G�»…èÌoNL³ö <¤ßqÇÓæ=¬XSÚs. òupºÔ%28ê  ®Iôk¾ûØ„'Ñq¡yñÔó�f÷ÞÐG 0TshõŽ»£„+©Nœ®WbŒëkkA€Ò6¸Œƒ`…ôdæóF][>ìíCcRÛ›×è7ŽØuÏÄQ’­v»¯s‡ûèÉ#9F„Êñb¨Zê�„þ·!=Ùr.ĦINìäâÒÓ&Ê”3šëެ�Ï#ž¥aYl,¥Û¹E4 L6[Û©˜páÝ}¶Íué7ŽëE>Êû°¾+®ùåÌAL˃¹ê‚Yž™¦ž8©¦~ÂŽ~.ð&ž?'ɵŒß$™Jg^hp#ëê5µÏå\²íÏg¼(¸±Jí Ì>R>ÄW“¾°[Ð9=ÞîY"ù9Y›—-Ì)ë‡Mö(ö„” t4(8¶KGlû1 •ƒîƒnºá~ö¥þ­ù'O ðA§ÞXŠÓ^R7ó‡:ýdewWYà/kàªaßÐÊ�qjÁHò¹¸y,¨ÉeâcKË…Dáa7�1òîò¼øCržK?¥ÀÙž5¦|BÚ)M:Nôšóî¹&$9럳?”÷7ê´/„ïýõXãZL­9ÓèÑ›«…:LêëE¹Dùâãµøú~HyòBÙ÷yÎM:ýRçŸý¹{üÌ¿ý÷ÇÇÿ¹?-[\²Îv¦<pÃgê"Ã�üÈ;žý¼o8¬‹FÄYÅ ´q*k¹¸óê×üÒñ¯_ñ“þ—9^ør!ç¦küû0wæ"Þ åÈ}ŒïE‚®ç¢fo›^÷ªÑð{Àî|Ë7¿°çžWS{^<ÒŠçuam(5’~¯“õÈú¡¬>ºáxä#ÞÇïîás{¿– µ'ìŒ+Z„ÁW»I˨ûÈŸó%ëjnrn\ëÀ¼ëaÙN(>ÓìO~ôG?ú#?([Ö#žà�{,ÂÐ˹ ‰KŒ×ÅœS~Úaƒ_/&ò%.{à§~úUÇ—}Ù“dËÅÄœ·ôèh¹ø”±!ê!õ û™î‰Øÿ«ÁG{>ïÐ�úÓÿÂ_)ïåñyTr¼¢÷ c;T¶ìÀÐÏÂÆŽæ=r�O¿Ž çûÙàJ-_ýêW×ôNSîÖ;PxÏ=w¿þë¯;ÞO{Ñ/Ð 4½×R à¸Ác9=D˜žòUOòš£2U-lÇ.ˆäÞ;ãWÝ‚b#@|ìèoÙ œÖ}È—^pÁét/“¨ñ‚¶]1èo»ív]{—ëâ úVé\ˆË>' ö?ÔRO͵Ç£}þ[ŸñWýGŸ·²ÝדL9²·Ý~ûñ}ßÿ£Ç³Ÿóœã~:׊­3Ù.)EΣß|Ã�¿ów¿àxž.~È€ÏoŒ°Yq4Öï9·ÁÈ4~Àn=>í¯üÅã�xÄñE�{Üñöw¾C°Ñs€yì�65½qsõ\Ú׎…å!“v÷‰¢ÌE~ËU›òòcš&¼ž°í¼ ¼Šeåv€ ÷&ì-èøá9BÉѰ&@ÃñðGÔ&÷Ç^›áŠJôÜb*4óÓýdL¥õy:ñvLâî­°gn嘋@y~nöÜkfr þþ¼Ô\Ћ¸·뇶ó)š²\vª•ñ«aÎ…ÞZfÈÄ:+z�.jÖã –l‡:ÎÔël‹³Oùc¿GE^ 4uë`åm­çÒ—/½cÅâ—›*ìkáÞÇb,„™ºÅ®o� ß²º'¬)–Ïä+x„�µdMwŒh$‘Y^;J²cH~î¡Ø9ÿó°8Û/€É (Ö�¡q·¦È½æ†ÏÒD' =Ÿ½iþðÆù¾°õ9ÓvƒuasÂpqôx P œ‹qÏ7\›¦ìÓô6ç>É|™ÑsFxÒ|~ WêD³Î±g"±kX'[Íaç¸øÔ0x> {=�V›˜jíëUøÝ¯ãä™=„,>:2�Àk˜aD’õ~û*†Ï‹›>yjÉ)ÇÜŸ Aãó�"�Ÿú¬Ç3Ù\ÜÆê× Ýáú„ZÀ{ôdxŸŸr²Ã|†¾ðÕânŠ’¢R?°kÐ$“Xž0R&îpi)˜ÆL�ôÝ3F× �(éŠé'£ã³01H_Ôfƒ%€1î#V|‰…³ÂƒÉ`Vq¹”Ÿ´•aÆ$›$cDpKƒå|Ð0ç„ò û/Ð'¶˜–‹ÇÒó¼78ª·b™Ñ">¡YžT9��±ý³Nf§ à'ÒŸÜÆÜ3¥B@êDCæ|™GþŒ±U3 ʯ͈g $¬ßÔØöã >jS�­ÇãꎀA@¼ßlWÐ1�ŒÈÀ XƒÓÞvgÔP”Ø0áÅOì™×/„³GŽyOèöµ?y ðÀ?žä9�òF¯~A,}øY+é{ƒ¿øÀVá«^cÞI^íÁ³FJôngf6N5|\|’…mp\S#ß/�“CÛfƒ}:H ßÜÀˆF:GŽ’7g�]jM\×?9.¿ÑáŸ\Ò�³¤sUŽœDj>W�¢Œ¼ú—|‰�r0ÀÓ–áh]ηQÊ6ܼn“~ñ2€mÈYsË}kï¤Ñ¸ym[�Hì²äÆ!€Ð6ß9M†yɹàk•ÜÄ#´Ìk=¸ˆ]öv¹’±(²O|zná ää’aü´ævqäõË|�)x"|¦P§Ln9gðŸ¸ê]/ùsžðÎêæø¼[éÞ›üî7{H~- �ÁÖ¼ø.ÙŒÙ_² =´ŒO+›knŸ<öð""uH©ƒßuvãÍÇÓžþµÇùÃ/9Þë½Ü)úÊÍaáDõæ›õYf7?xãg*‹í>pf:¼ý·O}Ú×êóÎnÖ…Þ×IY ¶ˆ×ܵ€cäÄtý”CÖôèý³K �OFÎi -!“wØC}C@ýˆ{Æ7ÛåºØèC¾W×`éïCW0|šëµ.Ât¬f¼ø¯ù½ªç;|!ƒç`ñ$›?ºÞy{äÍÏ�v<Á^<¯Ž~º¦ýò`¿#4ÌmjlsÈÈvvd¶¦ãHÅÖOaƒ4xð"ñÿ?m01mìOú„�=^ùÊ¿tüË—ýX·�ñ8ïXGöÈ»ôŽ[Ÿ‡Ã{¹1Cð¿Ý>dáEj|¹9÷™E2—ezŸBг×.ªƒúgï%öýf’o鯚Y†Ï4ÓÓ|��ŠùÝz'å¿û÷?ïZ°~ê <÷êâ×­ÇüÓ9>úOðvºÝú˜û¢;NÖ‘)±iˆÑã×¶rÝ�P27ÎŒ‘ý~óê°£Éÿ\ Æ•I…ÎFsФiTnûQ£»û®{Ž—½ü§ä§ç¢¯’ÚkéÇÏ4öóðùŽ_¡/Nú¤�ÿXÙ‡=`å<×uC‚Ç‚ßÕ;.Ÿÿ¢o;^ú�ßé‹��•$Îs¢{XlŽ7ÿÎ[ôNÀ¿s<ï¹ÏÕ]>ô|·u™Ã#Ëã¥î«o¹ßñg>æ8þñw|ûñYú¦·½í­~LòE<.à±>:×#©çÒ('O«cÓÇÍy¬Èž�?cÚþæ–£#GÃ-^ Ÿ ÅÀ4Ütq…sÜÖr“çÝ'¿+tÙÄ×a%Öû\—çQq0‰‹«z6u!—é”L¸úSlüÜbrÀ¦5i^9¿ˆ4|&\p‚›óÜFÝ$`Ç4gá£|€‹b#ç)À}éÇé©©ìØZâÈ‚õ‡\ ÇZ1æ�ž”O�cbrtOç@"å˜ØÚƒÒŸ¼³ÖÖKŽ+·¶¼,”Ç.îåyXj†+œ»¯0Áu¶³ý½§…ãܲR±1]˜$˜�>$9û~ cB8µ¼ž ÝÈ38iœ©× jïûÐM–úµEZ-k—õ‰ÍÂr lqTï£NÕwÏ9Ö6Ϻ'�_Ø_X² ÆLKGÞO’Ýè=<ˆvÃNƒ¦o9"�Üûl„ÅaêMÁ Xá;ç¾âd~®±i®øLX‡§^‘wå/1º~ô}ì³uÜ>8=|Í’߯F*Œ™ÞO¶åd?Íø-v˃}õôö– [OÕñf�dçÐ:hâë~EÆj�k[Í�+scøÉ9Vá·>¶`öF½à:I~�—±Bˆ+D‰Ï|€ÁTC—kQôóv¬ÃX�Ü’ �VUo£Xÿ"€Ž`Ý�g�‘EŠÅæcÕJ<Э…lÓ¨NØ‘“;Šlx …AA¸PÕwù[ØÊ¡ÙÏÙ HøÃ‘iÍNBX†z_TÙ|vîøvÓâÕÄÀv�t𢉠õ¼×Ì‹2Zêd;ÏOîžêp=ÏÛpŒmå|~JXÀsGDîÌãé=çøÈ˜{ä OlñIœ®¼<ÝÑ£ßm‰¾øË1y^ïC�ùÍÉî€[ý×O*´ø'@ùáwÈjpîËõB $Ç`ÓðɼGçk¬HàÔs ÉÉãŒQÞèø«n^)+ßÏæHÁ1]3µægÆ^_|jG óîÙòrÞBôƒjÌŒÏ!禞‚K~òFƒ!{OZoæü;˜+¹ŠÒ½yÚ¦ÖxÚ�©1šb´‹ˆ{BÆÄà’í“ßD°ެ7=ï¬è«ÑÆ,‡ä„‹Ù©?ñ‘ò‚•:DŽÌÀ-ßò@N;ç8‚»÷¶Ð!ß0jc?ÙÑÙÃ'5°ñ�ãÙ2Ùy;7‹».äšœÂg÷/ꬕN[êpâËf^à™ZŠ“9òN„s—¯Ð²Ü[ÎµÈØ^ ìt¾/Žr=Ÿ“ôvuÞ‰uÃÍ!7È® ¤¯¦Cæ=oeä=·fil¯ áo,þ¢Çü�ãeÿêÇôަ·›Kþ½8‘}ÿ¡¡ßÅD|xø&�q˜�Ûž��ðñ—g9 Vy¸jéàyŽôKnWlÊAvêà^¶´Q{<¢Ë[ÌU'¬1–óïþîÛ�ÿô«¿¢ �w�PbHr»ëÆãe?þcÇ›Þø¨ãú†á³M¤0X`šÏº·Ïu¯ÃØÐöš ¾:ÖÜõÛ}ÔŸÆr}…c(:/îÂ"ú’öoyëÛŽ½ðEÇ�wÜ>ôÑ.”ü.}ïxþ7=ïø¨�úÈã~|ùŒŒ�»_ð‹Žÿð^1æãbËÙ8ÍþÍÉvžã£û?=6:ž£«9k©ã¹ÇÃwâF7xÊö‰E^cÜìÆ&ròæ}øežØÅÄÞ>}ÎÆø¹Pø�Çðé~ ÷ðh,rwx)7¦‹0úë9^r£6èÎï Rˆ|ÑLÖ¦|èiÄ£5¿ÌŠ—Zžœl©Cœ|4và ˜AÈu{ÍmYp-ð<#tLÖ{î'Ï`gžX'¯ûžŸ!¥z­Sò¡ O¬rLM|*_hôZç9:çØ™/8góÎ]b\â^ÚÅÿäö´®Güë·)mXßì+ÎojžZ^ñ ,ÈkÄ ¯m"Mì® ÚÄ;95:ZçÁÌšúÅ«y)¥_°�=ºà¤f›ü÷N—±ÙªO2NÂ%¶õ³Ñlñ¹p!='CäÓ£[ö“×ä;ÐÆÄ·98Ž9œ<"›<„¦oŠÚ_‚`Û9J>öR¬½‹?¶=Áí75!ë†n4r³N}âZj�ñj¿(`\ˆH‹25†?¼“1¹±¿iõµØµ�|Ñ /1ñHœ�_ó³vò�sóÅ{°Ýg ÌòÌe7ö~½XÝ\‚™Úßµîâéxàó`ÞØ ŸøèÂéùY~cgÙeÝšC0 b¿p}p¢"Lx1|lÆr8ì>7§žç¶—¿è}ƒ°åË¡YŽOØc‹OØâï?z˜Vüƒ¹a{?gn,áµÞ��<çã¹—½0�µ¹Š Cx�´cËy”8íFnÃß~—yw-ÊÉûcö²–Á5Õ<9?çÀisž>§ñrË �\<6.y*Dà¦þÀÁß Êý¬ÆŽé^c°ôãÏSn½ d��^ìÜ­?ƬòæÛ,ïÒçK¹ðYpqýý/~ÛàÀ7;‚ .·æ�pš¼¥#ÿð¦œÉoÕ_=~ø³ÒÀ›Zyý×qY ×ÔHk wºNê»FpyzìbÛÔÃd2æ6ôÖcýÎmìÌsä#Å!-O�@•ƒ™D#´ ù©Q†dµj€ÏÕ6öˆsÁ¤×ƒÅ¯;Œ‰åø«>¯ýå_Ó;z^âuõóêê5×>Ó·,ÿÀ~�þµûç\7GŒ`†/Ä‹Y6Õ¯ù öܼ jp¥#ãÖ˜ 5vmQLÆ6Ô@ú5–/6�ã Lpún>ÞGÿÖØsˆ=N]¸uïpÎк7Š¡�Cãƒ6Ü3ÂÁò’•b®Ÿñ±óŒáZ±éÏÄÝî_#A6¦×Æò(/ø7´T¶×+[:�.hé¾èŸþÈÿ©‹Äú�ÿ<‰ç¾�óŽÚø¾R¯>ÿÅË^!].†ÖýܤÀ<ä™®uc¼'Ù¹z·{ˆ¶Üκe�\ìI iòíÐS°t»j Ö²›%�‚ûùÿÉWoxÃë}ߘç2œS:o¸ïæ~G{‰‹ƒØ~À#ßÿøÎ—~ûñÇuá­ïvßœ‹oBÔ�ÑMÏ~|Óoýöñžð¤ã‡ô‡¤É…½;ïºÃû”ûµ»u¾²¸gŒoãï1|Ž­¸±oýê ?7zýúþ{ðŠëstr1;Û^Ö <ì“yWxr´lòê|ái�ó²5ƒWnö3§M‡ ¬±IÇ;¯Ÿ~ÉAs‹"·ßØÄ¹Úpöž6ßȩљð³ÎØs_4ºG»ææ�mk1˜Öû|§v§/k›õ­lÕ~¦/þ~?”:ÈŸ´&~ú¬Ke,ø{mfíVò¬‰ÜøØß÷ÉpŠÝ¹Ï¦¶alœ® 9(zø ÎÅ"÷“µç6öüqülìÝp¤¹‡øÜ°­=}BN hÙyca¨xålÛ`æö·él/<Þub¶ Ã$1ÆÕa¯®ÔÊÉ„O1A OluãÙ³xÁnùã3sFÜÐss,úiËMâ©ü‰Q[”Ä6�‰aб3WG[|™·Á׸³¢Á#.y¥¡OŽ3§“½m Y¢k¸´’Œ�GLì¥õqôJÇ ™à´vŽk['»únã1j3ͺ@,s{çþÌ]¶�jåaÌ$‰S’ÌqpÅÇ>#ßuOàDÇ_ÛÄ�4,#"ëcãõ™XŽ�X·‹uƇ6½kE¦Þí·M �:�¿¸¸.Î%qö¦CfnVê°Á\Äunü%GǰD™Kâó ¼Ì±KÊ©•ãØ]бY±=ç°ëgÂ,ÜŠ[OƒÅ¨œ±µÈeǰv�óR;ü¬½Õ±E¿ó vtÉ#÷CËxìŸæÛ\“4`yC)�-ÇÚzÍáAs\zb9D•cêJ¬3¯8sF.ãͨ ¤³ÙSÁ‡b¶>–�Ou+9äA*{lóÔ^?d2DíÖû„Ä—­¤hÁbÌ_YùÌK¿c�ÙFz.¤Øoð6X,Õˆ•øÎÁ\ðF<:Ïx‚ÆŠ>ié»öà§6—õ‡ÐEÂÌ…©Är9Ÿ¶‰\Ù8¶ä“wý† ñx!xÖòz2 }û•_ý }¨ÿm“òNØ T›ž�nê›»õšs!âû~ðG�ßù�ß™Z'¤Kæ5y2R{çï§>äÅ�øç<É�Í4sƒgyXŠB¢MÆè�·Þ¦#_n+gIì?¦š_`JF]—ì4-Ü`dš×Ð tš62¬mÇÔá­o{ûñèÇ|Ñq“޵ʿq—ºøÅá\(åß;÷ø/<^÷ú7HïΜ‡/yõ¢œ£Ç,D4¦F®róA?ãʳ.qÁÁr¦›íh-ò�n۬1˜ŒÞrºV­/söôÍ7ßâܨ.4`ü—tŒG}-Æã¶QùDÙ˜5ízx^?º�Cpò±IíèG7†+· H}ÎùÕ®ýˆác07Ö…oÛþÆç<;ë/Çìþ°0{Eç{æ…ßü"ý;ù;å¬fR^w„ó¦¿ÏzÙ £´U¿ŠL¶÷W¢;óÆeN-ÙŽU½à¬g“Ù¶ È¥_vs…–þwôæ³±j"Eû~÷ý1�w‰}ÌŸþ3Çw|Û·ô��ôãE÷«Ã”4÷1Ó™s?øúß|ãñù_ð…ÇË_þãú3KÞ¹ÂÚ€aüÕò‡" 6z…�Æô¼HcínÓ»~¿àQ_püøOü”.êê�U2¸:˜v4T 4o,Î…÷zÏw?žõ O;õ¨G+/8a6HÒ×�±5Mjì’Cö=ç"7°Ù³~¼‰“¬ƒëûmðÔ€r è>ÇN±É{^D–3µùPŸó¼[¶àb2¯#üú%AýÜ2¨!4<ãD½Ç ’ÖüÖ¼%ðýŽÂ9ö$�ŒaƒÔÌó‘£ÇÝÞ×�žüC?ùdÔm3XÁYš+ȜĬ}ü+ñ‡×näqm6 †®a92·�Á´èß\£�7sôûz¸¸ÛŽ5,ßb”<ß¡¾ZéP{šºS“‹õû-„}àu•»ç`Ù81N¬‰uЦT IDATh8Ñ¥ÅÏ<�;;^ÍbÐ×ñ5F7RŸCÅ@¿öËØ ëù“µ�5Çâ%PbTës{HØŽ"3×�Ø´½ãÉ#Ê1[;ØGÞ™”/XŒ¹Åá1#/ýÐ_¶ÈŒQÅØ”sûØüøD¼ �`Ðí7›–œ»òS+ßX#A¬å [°b¯äÏüÁ1µËSà q.ÚĶ~ü�ûò—pâз>ØóãFí =ýè,c¬›ßhG¤9ÖY½,Ò<Þu³1ô`цØÈZØK�g§�ݶx̸ܸœÛŠe›XÈÇÇÆrõQéжx« ’E�Ødì<<<ù™  jÍß|-‘ŒæŠÕÀ3¦|s)±ËŒH°¾Â“HND¸úqÆ+×Ñ!­L¶;‡à†›q$Øm­ÇÇòXן™ùë ä«^VP‹‘ŒÞ9Y†Áø8ÚÏ*uN±;±É“”4¶{Ü}ŒÖös´µ}}çÅ0u”ÝÞRÛ‘HezSC¤µ†�ó`¨Í˜øñœ¤nF#q»ÚĨk‚=�´\p™èíR“¯¾ËO¾­MójÌ®yÀ�¿ãÉÉøθ¶ gŸ}M!‰š§C2S‹Ëüæ•XÒV9\Æ*ȉ¹™ÎPºü.ÕuÖ Ú\ š'�5‡´ÆîR rrZ%+}ýãu/b¾ÀF|‰œ»sîà"�µ`Ös¼öH’Cê“ø¥+É$à‡F�­¹Id¹Už$çÀd�Øi\?Ę9®ýs¿Òz˜sH-|÷;Œ¸µ7Œ0y1¶œÂnȱ÷þ·�&ÓÎ3Y&Ɖ!~r¤žX«¾ók'gg\ÁÒ{#ãŸÜÏ‹~¹¯ÄÄN!LdÂè 0‚%WðÒö¦!m¸�Dƒ–Ì(�þ-ì玟ø‰ŸÖ;Sοš_ä?±à�Üë,WûûP^Бzò~ÝëÞp¼øE/ò‹X¬]Îúg P}‚”yê3\‰3±ð÷úƒyŠ—Þ(öæàÛ*É’Oä(áèþŠïÅtx\¿Ýîº1ˆQ……²h0²+c”zòåwÿø»¾ÿxӛߤç÷êß§õî!_0à/¯\È�×Ýwé]Ÿ÷Üp<ñI_åÏs­oëɨ½Û�af4 \ä5™‚±GÁ&ÔµGm[zµÎÝ[0ûÄZLݨÕ&òþ°N‘{ z�‹ko ób<|†ìe×í1Çž¸åÞ Æð°ll�ÂÆ¹1m#¹û+1öºÙUX+o ŸoæÉøòN¶›ô¥Ÿñ7>óxö³¾öxï÷~�ù7a¨Ÿ{�ð+,qä\NÄæ]Ö¿ªo_þô¿þ7�Ÿ×¿Ûòåp¬A/„uz-äΜwi£ÇŸžweÆžÈùÃ�–îxì>æøgÿÇ¿8n¿ãÎU�æ]7µÅÕc¾ÀåÁÇãûÇ3žñµÇ­·ÞjnNÂÖ9À©�Úäٳq1™ ™|±S–G½Ôpï…ƒÔ¼Ñen°=rìÈÂãr¸þ­‡¹8|x\ 9¸G­·eqºR; -ç0à·Ã�—�Š%±ô£§Æ‰u8¯Ø¡V•°u-ÜÄ8ýÀ£YN\ßâf�DÞóšäõ_æ‹+¦æƒu¸Å;Gû.øñgPŒ0�Ñ^ã%X9ñâOÞ3·z3^ù‚5q_ÈÅ—<¯E,8ílïé:YjæØ3¾Î@‚à;ïGÏØ|ÊÿÖØcŒˆ¡äeÆ|M4Àß2Y—þÔ¨r¯/pj‰Çhˆ�~Ü!\â¶®hí �Ë×~µ¬}1nÌân1Nòn¡cãdWã@*؉Ç4œè½Ìï£9YØ^z×£vƒÉ´xKU¸é“W8œu‘5µn½@×Ü�µ!7æôØ `Ž(V>"w|ìhUbjs,.&µÑŸ¯OÂ¥PÖ:�$¾§‹ª9¸ŸÐä²òô7ϲdÇÁ²`ü“‡$ä¨Ic`C|׊ü„Pl1˜úñ_2ÿ1ˆ?w5œm²cZk!w쎉7óÞL$'‰0Á…ú�Ö1Dðø!!~=6¶Æõw�~â€ASo ôÒ¹8£ó8Vá€-�q �Ž|1*æã»xšÓÊÛ«l¸ô]Œã’\°‰kÅ™"+o —‰e“›¤Í¯ŒW­Ú‚±Ä›gÀÈÛCÀqåÌ|ƒ 1ש2pl/A7dær޶蘞3‡q×ÄãÉç´�LXž iƧ�Æ5TßZ dÜyùÚtq1Ëå][órhk _û×Ï"YkÞ ²é[ì6.ŒWÛu™zhÜÜZ.ìC…f9cßt¹•ûA>ÅÿQÂͺ‰U,䆻\«àÇvÅnÙÃ×�êó¤`‹ÃL×®N¬§ÙÏdÆ®÷Ù7Wí%ŠÖ\ï5F}�nü�{ I€&ùš£‹4ë?cº+󱵜Šu�]Öú¦j& ˜©äôˆ‘IQ `S;sE«_û›± }\¶<¿C:jïĵí”zòc ø # 2õ͉°áÄhj`N XXúÀØÊ¶ì^PõÁ˜w\xÞ =/PP‡ü EÂ&´qû„ÜïÆ’³c*®×Ð}ßí&vúåb�¹Èö�9u°œÜk¯‹3´�YŽIHŸ'MÕ`°:,µ‡Ç ÇSžö4ÿËš/"6¶1FNG�ÆFÝ““çÝ¡ÏÕzÖ³¿é¸óî|¾Q ·úðb¸m_ç}lg™ßïœD• ŠÆpÐ\ †úMÝÆÅrt±– vÓËÐqdÃ3‰ñ¿¯NI–ù®µ"hÂÑc$ÿ±ƒ§1IR¿{ÁpÇ^ªÅkl2¿$“Ø‘­ýirÎ„çðw𥧖šl6ÞëÌÉQ ×ü¬2B·…cÆ1ž}#ªNpgîlÃH6ª7ÎŽ314s=Ñ£i^·1Où¹oì'»e®~Á1ú`hª¹%Ö#^s”mì.dL$¿Àc*�~í¡ƒ3W’æCúq�Ç:ØžÅHg¾.¤� þx£yj膬ƒêŠÛ9¾¾ó8èh~'g›ñbÌ'¦óc.ÿÈÑ%Ž‘âyrÃv�U>p°sŒ“¸½I¿ä ?ÚªG¦–]w�-¼hí3 Wã_Í0ƒÍ¼9Ї«,à„’¦©}Æß¼¨�oúìñEt –c|åm÷€Q‡-€‹Ì|n¶¾Ž`P‹ÍÅ0pýd¸¡‹/xÆœXk\glÀwŒ)6¶ÃŸ!8åã¹l-Cg?¤Ø!�} ’¹…spØÆVŸ¹ÏÕÜ5¿p’t �¾ybʃ®ç6�1XÜÊ »,ê(tÏ ²úѯ¸ètk~µ‰Ï�×pÞV«Ö·8ꘋ£„¾D:I¤ÁÕ#88ÎqÆsÌáÜÚu|æAj—ðÃ/)ô{Ú ËO f�ð݇ðºÊcÄöÄÂ9�ð®�lí/ìîËÖèɵ¸ã—ú(˜3´©l7Òà:ãø*¢Œ·Î¶Ãvbîrtj‹çм:s]l¢SÅ;ýͯqbq^q§FØSÇU‹Û·TŽØ‚™w_I7f×qœxVјw}QŒ�_œZ \mžÃÜWI^Lc`Û¸Ö#8&fñl#áи§Xòͯº ·à�AÕÙ³‰ågL bGMà\�6x« nùm©‡º�æ„fCxÉ'Ù¼X Zs¶�d.WTK¤Ð�ÞcxkpÆ)/Œb¾ˆ‘¡óœxÐÀÙtfo>"ÆúIS/æ[ÜyÁ‰ÿ4Ë5ÆÇcëyˆ2qŒ6~Ëyì¥3¡•8sU…ù’ż%«ÎyHOÓ¸Ô¿õmo9^ò­ßé/2Y ìv#æjÆÎ0<-4“0”Ï«_óKÇ¿ø—ÿ|=&A‡ºäŽÓúÑc–Ý‘a$bt�áÞö‘1gôÝ+¥À8¯Ð9Ÿ �kšklU¬¾{̉Tºù¸”�eý%&þ½/hÙ¯šãæ8(p×íÂFôÔáíoçñ ÏzÁñMßô×’ðg¿ä¼ ø¦vìiþ…‘wwݨ‹;O}ÚSôm¯ÿÌï€ês,á:½ÇžA+ @÷Vuåí7pÚ< ±ŠÜÓÖ|;ß}ËφW¸OÎYr¢ù×Vj’:tïØ}ìï ꪬØ.ª”pYÁ™¼MƒXv8`ÁìA1Ö6÷>ÖŒŠë�=-øêÏQÔ!FÖóïö¿ñ¯;þá?|‚båâ•?ëTW�ˆÕ=Óq±�}rç�w_öä/;¾èq_rüæo¾Áï„#-óM´ß“_!®ç;·å/á}ÈMŸÜz³àœÛ��‹„àl­­Ï©“ïëõoð÷ {üÄOþx¤2¤ܸøÆý-7>ðã?î�Oû+Ÿz<àþ·*„M\c&~;×ÒAÍ;rÿÍ«þýñ7ÿÖg¿ýÖ·ˆj¾Îu÷ý{.Pé¹Ï‡×<HϹ�kDOã[fiL¿ê«Ÿ||Ë‹_z¼ó�·�–µ‚Úp¶áÌ{?‚l¯Ï-·Ü|üÙ�ùÇ _ø¹Hâ8#»çнyr¶\�¨KîçtŸ£×-¾?VL^Ãäñˆxj§<¾‘Â(\SƒÆ~ç8ÖîvÍsïƒFì=ùP! äÜŸ(®òÁÆ¡ƒç4nlCŽ{Ç—Ðõ‘¼v˜tL\Zr=÷¤ç°úºCW–ïðƒZò– ¿ñõxŒ“óIB6ì/ôDÖ cÀ6œÇq¤4qÖ1y´ÉÃj;‚7¼ì»•žl쯞Ø+šÍ+A Éaq— ¾ž�¿Ç’“ãÖŠt�ì¼z …ÁÜ·F‘ýòO?™Ç€±yï|ê»õPO¬ò"ãWÜå² ƒÆõËØsøò³åxjíb®å‡Äq†±9Í5[/çà¢_ÍÆ™A�¼ÛŠ¯Êø‡4»`Œ=óÖJÛH·ó±“Åw�™ –ùÔ© ËÃc[áÜ!ÀòÅÄ�MêwxŽÞѶù™Ÿpxœ” GüÛ’[fèi»>’9Ž[õÍ“û\Tf?ØÆ¥nÜÑKyFtˆ�œ�ËÓ¹Œå’Q+[ažQ±Ó5[�÷Ík(µ‡c[<ó²l7dmòXvñ§3L–ãè€Äo2$Í\í,ÔI]ÂÕ*óÎR°l0Œ6ØÌݘ ciL 4ú8䈪v5COë(íJ<Ährîã3t*ñdcÜ3bô>†ƒÙþ6oW9/ÖG)BY^ \Йyƒ^8bzÖ{n�M¼Œ‡Ûp¢¶Œ/0°�Ã4ÆüþdÜè pác×-ÖÂbpB¯œÊ7øÉµùZ&æ�æîÌÒŒ51Â<“`Ëfò�‡Il³űˆç˜Áí¸µYxQç88{×ÇO(6ñÆ>%C  @+¶'ÈÊ MÁ¤µ·¾vÎÇê‹5X\±ÙsBÃ<°ñZòQ]`ö… B¿f Ãòwn«²˜$^Q/t�pPYª÷:Nt𸭼W¼¸àÝì]H[X,Ô*[ø‚¯ñø1FvÖeô°Ë™ëu2áV†ûØ‘â<‰IÐâk@ÜÉ{Ï·cëÌ-~S«ôØ‘ÊjP� ¢æd�„à-ÝÄÅ·vþcFã%äEK`ÜGkÝQýœ½mÐFíZ×uíý<›-ol4ËáÅ‚úà‡œ±™lƘ¬�ad ''%µi*ÆáK‰ø2¡`¡FŒd©©4SY6Ì81lE�ð AN‚› jÂ†ÍÆýòìg÷ÿýþÇq®uÝÏÃLÓyß×:Ïóxùÿã8×Z×Zë¾îûJo°õ�Á0¯å“ž'Îà�׿Ñe¿CýÔ®û2wÆpêk¸Çžñh\ÿŸþéŸyüÙoùs�_ÿ¯}Áã§ÞÃßÛì9†O†RŸ} äÍþpTž‡ƒâDö×¾û¯=~ÃçÿÆÇw~×÷ø«ã|²”�ò£"#³!˜æ>t›¯Ü>öëò$__”yá`G´u92  XÇúh72އ÷åÓqß÷ü­Çç¥ß÷ýß÷x•ÿžÏõ¼èÀy%〿5úOÿôO{|Tн$º¡ˆxŽ“Iféðiçw~Çw=þ­/ùíùïÔ?Ÿ_~u>ÝÇyª“éÊ®µ¿lÐñ‚+y³fö8Ï[}¢øO¿þ�>¾þ?û&@€ _6¸ ¿ fx§eÌ~ÿ§>ó—û·qå”óêñ=¼oëgùLjhÔc�?€‘^£-âÝbbËWÿ3}1î|6‹Zá˜ýa Z—NVÖ|:ë¶µ#|yb?dêªÜá‚ÀÈ1Q›>Ö£ŠŽ�ïî§]¿±E<˜SºÌ#pRÅÀa)-òuX>¨ˆ½±‡w!b—oÆeÉôžqeÇ /EóÀrkœh{uSÍÙÈš 4ºŒ7·7{ÞMTín×8Ù¯Îõ:¦iðï¾Óñºçþ”£°!q®¿¼߸5Ùr›Úæ±v%­ûS&|ï9-¯ÊbhH‚´mý—û‘Ÿœt@Zlzd™5NúäÖSƒØ¬Žø;¦÷ö✾ØU¸}²­„4d‰ê­×Ä\Ñ—Wm àèZÀýfKN/Ûú<ÉSÙÓ¸“;ã]wµÙXœáNü|oæŽ�,ùÎÔFïµàä‹°õÓYôÕÔLy1¥vÄŸVQmV¤]Æx’¿à�1áå×O×óh4ð༼MšeQj‰7k²|Ï|0#æP×ïÊg¤“«.QZ8¼ó$ǹJ8SÆn¥íB-©—@zÄnY‚Kp2/ˆÍdO˜Ð\,lŠïå×9ºî0hnÚ —Ãr¼ißP€o¸j»9$MœÈº3µ;_õl—á‰5x[ò{ýšRñZ¼ê¹±¹Ñ2ÛÚ 7õƒqÅÁˆ¬ÃÝ­>FŒ•kŸMý"�~kˆ�rfÃdlŸäwŸŒï:÷…œ¸¥!Åž6¶Í~ƒlœî/Ôîâ N­ïr‚}ƒ¸û´þ©�õ¹[½þ‚Ló¿Ûߘ2¼Ùc»1—H=g­‡7Y¥µÞ~eèi•g›8¼\Ù§ðè*h~±!¿¼N|j·`¨€ƒÇb³nõ_Œú®ºB'ó{»Û7¾kû,šì…?¸ÏúK~)Ê8š…|îW<µ`jÚÔ…6î+£§m¿“5?òÅÕûýI×H 2G­™2‘ID׺ ”ù[�péz@ØõùúX9¡­kÇn3„°jÉÚ»Öc[„ò“ê¢!JƒË6ñ3ßs÷`¬žÞuŒ�9X „w Æ×þº_Ñ—êæ¢õ|*᪻5Îð•Wßž¿¯ö?>ÞûÞŸ;ñÁ¡-ÞrP>1¸Iûñwÿäãw~Ù°jˆë#ŸØsÆqfÜ6ãÌ·BµmPøÓX`sÕò�:l[3üÁ9~�VÏÜ7êJ7»—ÿá—E>Iôn%MœÈw /œB仜¿¥õ—¿ó}ü�ü�üªŸ²1séÍl/fZ‡+xhI�Ï™7™ÊZ+ãmP`¢=¾äÛ5 q¸‹€=sLd�ÆüÞÖ¿gÝ8­/z 2×vÆ‹U]øÈ®ýÊ–¹ñëƒüZßOþÝ¿ÿøî¿ñ½�ߟŸûë>/óë[óðÔ·øé,.¼øÄuÞšÐÃkÃ%�Äš¸â ’ÑÚ_�†R��>‰Ë\®Ë}椆�0:�-çÚżù ’g¶åua¯y-šr�«9xñ4?�XA)Ž#�7¯ ³<5^ž/x­­¼Ä 6[ϯÑÞ|�Ƴ‡!B`‡[f;¾sj0Ž~Ân ÑÙy[*öªŠüG­)_Ýgu, Q˜o¿ÀD–¶)8›¢‘�Hb?å|1n>8<É£ó ÛB¯ø0^�ckÎw<;OÆ´cëì…`}�åà¸ÐwóÁ[˜Ö‰ÙV¤šþÊ3q¯üý”þ`O;µ™9DwÐb ¼Åj¯mò˺Œ`Wc¬—§€�×-ªØæ� "g¬,³�¿k‡^%<ü{N¯Ð˜ËCóØ2ï–µ†^+,ÅÛ8 CÌXŒ ñÔ™c=uZäpÃm ÆÉ¯gÑVïl°àápbt^{�²Ùú¾ep´Ù:X^Zß 0Ýâ¼Å0·.ð†³/Ê`Ý1ÆßlF^Ç n�Èé¾nˑޚ6ç]¼%_¤ÝN“Ö{l£´Ž*© üT2èžÛñEcö›‹çKÛç95zj€#z ’É9j 'Ú=Ž.gó׌€^ùéÍØæVT‘³lí3Ê57vFãcmib*j&û çþÓ×�!ç“ „õGNýŒqïÝ'EVG9Ä•u"F±‡oMÅ��Fæ">DpDGKg=FàL÷?G#}–çš�çøÜi¶¯ç ˜�ܾ0üÐ?ðø¯ÿÔÏÑ¿ûøª¯üòÇ'|Â?ÚØ(qûÃ%sÎ[?ñ“ùO�ÿÞ—>~è‡~0¼.ª¸øð…úå«9G8�yù<Ã#$垉Óíþ6ÅOŒÀØlÓk»r0êƒÅÕöWµâqÿäLò‡{3=Þõãïzüæßò%�ßý»¾üñkÿÅþñqóÑr½/TN‹ŸsüS“ðS?óøª¯þêâÇŽ°g†x IDATÕÞÓf›Óf,î`¸‰p¬{ßgþä®ýÇ+“cäTƒË¤9uÖ7vbá f;o²xÅñ\£buß§ƒÓØ`êùzußÄ·±Ð—ëà!_'Lƒš÷¾÷}�¿÷÷þþãù¶wæW¦ß™œò®ü#~µ�5mò=ŽA.Iáϯ1ò+¿4bqÙz_7æüçgöï·¾òj>%ögó÷Ãþ»Ç§~ê§<þ¹_ý«ÿ¯ù5�_ñË?Õ ðÑùÕÇ·å“P~:'8=n[/rÜæñæ{{¤‰©ö¼Çk”- 1^ð�¡uV¿’U³2cd|­ ¡>òxOtü›_òoçÁ<²_iß`ø0¢Æïÿûý•LþS²-2SÁ˜E¦¿ª³¹˜Qõ�ÃÉÃÁ%¾LînŒ{ÂÆõxãfލå¤k™Ü"Ý¢Wϯ›¾ë]ï~ü¡¯þÚÇwþõïì'm-‹zÞZn�玉ͱJþ»nìc¯¿žWÙ_þÎýÐãK~Ço|ƯøÌÇïýŠßýø§?ç3ú)º©£¹³É|ù[€­Gi¾ù–š¾ì³R�5î;^ç•m¿òí9†Þ“O@þOþ[ßøÍß”–ó³³îüóŒ`'Oâðµ¥Ð÷¬Gþaúø[?�ýê}�·çcÐj ›¬Æ:fV~`æïœ~à9¦þ‡Ç×~ÝׯÌ?~î1iMâ„ç>ÎÍÈ<ïžÆüê± ?× ¶Õñ°�s@€ÀËÈ[Ú9¼éþÌ·ü™Çûò«À_ñå_öøG>þãcV[üiLOQQ‰¢J|zýCüës­E-ÆWŒæ£]@éA#þú’ûÔÈ õæˆ;*s’ðÄ×— ¤ÕÃ+öÂÄߨˆßdüÊ«oÓ�?Ê�;ÔÚ›ÚÖj6%ñT›�·f/çÈ[_‚àz[ 6/Æ´Í}jùzn$¼8¡ny7—çäÔÔ_ȩ̈́yÉgç/û†m  àn[(8¶,Ú¸ÑãæNðl A¯íÆaþ4^þ(¦éu“[«1ß Ãý�ÚÀ‘†�µêœñ+áHíü -:Íbø¢õPºòt~‚b?1”uNM\cOÓjøŸvøe|ê4Ø"ÅþÕì—×ß¿¹rZ qà�ïÊÙ`h®FHÅl†V»bžø(o<·æÊ†7¨¡Øc'Žäu/‰û%c Ô¾EÚ:ȱn(®6ö—€Ñ$ò¦ºb*zzn2xµ–8ñ¥­Ý›ÅÆ(¦X7/°wâ it{¾˜žùĨ3@÷F°r¨”uëzsl8ŸJ¸Z×TŽ#„÷Á¿ �v±—×ÉtrÜì§vKÉÔ6ϦÙO,EÁ1žZ¾–OPP“'Œ0ØýñjÓ!ó&!ßô·¶3äå>�P¤Ö׃$> ˜_ûÔOüÖßú[ïøäwøi£Ç®ë'|òâyhó§þäŸz¼û'ߥ�î‰÷¾ ÑäÝùÈSª5(?oÜx£Ÿ}?b½h¦=9¿’÷ÅW^ÉûNT;æLmoz|Èÿ­ +ßI!2B¿áó~ýã÷ÿ¾ßõøØ<|CkhóƒFί}èÃ�ÿü›ÿäãÿ‹?&>û �*lhœ+y}ðƒùCöGcÆùZLlåHB|'–Üyßzõ•Ç_ùö¿ðøä_üɱŠÏØdxµø8ß>SþØþ_ù®ÿ-ÞÞÛ‡%ñ㜲ýÓ>íñ«þÙ_õøìÏùìÇÛßþöæ>¶–Oÿ¤ÏÜÏ3Ž$bâm]\OjU÷¹ºé×AT¿ûéæ®v ÞŸO§ý7ú¿}üŸ?ðý�×ó)¨ž{¹X-¶ëÿ‹>úc¿íK~Ûã3>ãŸ|â�)|àëþÈzÍœX‡3zÖôÉm0ç-úݯ;¯l}ðï>1k1пÙxeô‹ïõsìù»p?òÃ?òø«ßù—ó™ë¶boÍ婨DŽùM•Á³¶!;em~ðÊšu—KŸý" ¯»xˆö1ó±y0ööT÷Óg[ë]#òäa³×�+áÊùˆó=\Y3ÆW¼o•_Ïåš\?©—µ5¾Åé±ÇüW¹t½ Ûx̯ßþôOÿtôsŒwìÂ\vŸ¢4öEÎã¾ï„ËÛßþ‹Ÿú)Ÿöø¤OúD÷£®gö�ÄÙÚàÃDâsŽ Ÿý±ÿûñïþq¹q�JÍv¿¹ÇÛõ\>ÔÔ[6Ë Ax5ÇãÖçmo˹5×B‰éÚJ³ÓóÏ<>ë³>Ëó¿ÚËq͹’÷4êÁÚQgjùJò~%çÏä¿ ÿ¥ïø‹�wÿø�‹EÜ¡"±­±ÐQ³=¿eØFáÍyˆ5†c�ë3Vvò�ý•@܉9qMË`oË£5sen°A¸‰¬'\#¬}°LŠõæORd¿áZȳѯ-õWi„ûøòèŠ=4Ç >ÆËôîΘf½ÖaíåË,5á=üÜ“á³d.ã ë‚„}•㪜ÞD¾nô·Öü/Ajf¨§xu`͸FdžPsìavͯ­QãD€é6ìÇUQƬ?�ºØÖÞùNªêvA˜Õ‡}�ãÛûFöË…2·Ô&_â�ôWÑÖ@õòXùÌkS¬¨l®eÁžù£Ü׆÷qïÉrþâo²Bbã‰MœáGêáÞËØ{\ÅdÜ=û›ÿêïq�Y£ñ�î~]‰ŽÖÚeý‘…”ㆫ²|mÎëëõU얣ƃ»x+£.ÄiÌæAŽ´ÍÃõÎ1βy?¨~*6þo/cßõ/kx×�ñòŠ U9šÛ š\ ï3 WóßæaÅu çSër³^NOý/Àÿæ–­ÑéG¹y¬-µ=Ø®ûmm˜§qÜpOà=8¸4üXë³´®+ç}"åëã?ñç}ÓÖ�¡;…‹Wñ!»D°ëã$;‰H›è Ü‹ˆ,òë×C«%rÛ/ócCü—ó•Ño¼•M"å÷Æ'­‹Ë]̬´o¾„7x/ëvš…ó ó6ïpŠ� ±$|àM»ŠÛ±òV’ƒÀºÅLëkÓx46'êÉÅXÎ>¦B¼"�á­3‡Á&ÇÛÖËî¬]æºü×4ýâ z·˜9ùäÈ‹ŸÛ ò¥½‘âpj5xØc±z²Èì…-v´;Žkïæ='’šÛòŸ€¼ùr"ça7-Ê—^bU{¸ÊmëŸr­ï±¬ågRàÜòX[×<È-CÖÛäíB ƒÁ8ùŽìîï!3ñpp_§"“5ö�ÃŒ—ßöú¸�,µÌzç‹7îÅb~b€³­.;kLg£x“ø—ñ}´ç¨Èî>k228ÀÛ¾©g�Ø…ß­u«-7åøÜ›¶OE}¡7Ïr%¹» JšË‰ YsȹԋɼÙx³E-mX´Õïù#Ww»°€«q §ÍÙ9�+“\çïÚ�c„eZîoÉ s/zyCÌõ¤iwQQ6*y¬íîšn|ýÙDzã^¸xz2²–î�9]ç3?ûñ�ßô �w|Ò'L`�í†sÊм2 ÿ‘ùÑÇçÁ¦6¼—D�ÀüJb2t® ..Rgnj©c›hÚíÃ-äpߵŧû5­>êñ—¾í[¿Ø€7† -§ÑØ�õÁ|zê÷å×<¾õ[ÿçȈɖwœ2 oë•¢AMàÇMN’‡.Úv�c�£¾„Æ “ûš­~¼ç&-‘ç�û0'©'V¶u[_9dÃ׫¹ñæfÿxü9–y’ýRx�O×=Y†F¾bD-O.±âX¨K4'ä};}ë‹ì js¦”s|xÏÙë Ïé¸éÚXž¶�W P|€Ñ±bßâo¢1̆xä�ª�âÇÑŒ^“(ضQ^xpñYþw»ƒ/ÐTÚ¼Wîl¦ÁßcÍž ]Ñ8‘Ûi ‰ˆñM…Í+9WR@°¬p‘f¿—Š#Ã+í%.²Õ1þÿÒ‚q( ¼ ÏΗ\kp|ëñä÷l{f/ ÈˆÆðÝÚN­Ä»º¯v½ÌIãú�q«ƒ)÷œ‡ö ^£ßÖ§i®Í •¾Ö»gÉ4õ{L9�wÆ sÖ{ê:¹çB àHŒ=vÙÚ0>ï½-Љ´16÷»ßƈ±¤LÉÉóæžšk-v iŽí½¿=וáÓ런…vÂg›ïåu¯U¬ÞжnrÓë¥V@Ý`ß‘osyŸû[÷ËÛzh¯|Ë‹yø.7Õ,퉯r®íæ¾N !/;0h¸KlkÒ¸Ä챓缯½N³AF|u”9_¹“(P±K’-/:�AšnîX!£¶½è‘®à³¬ktHŒÓ+J»¸ľù_}$ž�>6-VÞ¤sAì~ó'cìªÀÈÇ–ÙÄó'j3¾s|÷8ïÃ?ÜÁ™�£í¥yU¼÷?3Þ,$ íÙ™r�L«l°•d?xZ#ò'/CƒÀq;1+ˆdêT™ÏE¶7»èiÇ4¾#h%³5Fyk‹1AmkßþE‡‰¦ä˜ËSÓÌóÆqs�IpF¿8#®!Xy•/æ¨Ï Ô`xà»xÚª-?üĺñ;¶’Âûædq`Ìk|åz›‹-7È–ír]L×:“åuäu&2®m„OqB_ÙÊáLw¿[\x‚39CgI꾋Iœ»Í¡3TÚP0@4ÁÇ éÍ‹©ØÝÑvÄÚƒgÝ�Ì‹ëóåå¯õDÌ…ÜòÞ&GÒËWc§ÏAnÛ5ZÉö„ÒîL4ÝAeŠB^n%‡Œ™Š‘‘ñ'g¤ƒµƒ€ñ`-ðvŽ,­@G¶1Paû4ß7¥5ŠoÒ„~øÓÄÀˆ˜tñ�3ßÈÔçÍX¹Å@û\S×Ëø‹[(dþªý`~ä#ܸÔÓ_£ËùŽ4Þ‡8?ú+JÄ„÷Ñ+7 ¦u^Uc?iêt¹e®mbÍÈs*qàZníÍuàäšg0j·¹ƒÅ 4+lžÊ…ÿ*iÎûЄ}4˜ïøÄO|üá?ò5>üóÁu\l’Ëh{†[ Èøu¸?üG¾!ŸâÉ'}¸‰Ž ž|í�¸¼ÉÏØÈûw¹Ìo€áo�”Ñ>Dwí²�ûtL�[Œmºe¶”‡J/Ýó­>±RÇ Õý#vøq½BO®è;«’NÎÆË¾D�žfm¦·±'?Û[ÊafÚÖf½«Áœ0ðeC߇Øã¹žB0yß GàT,æ®Gúà 8€§1†»÷&Ž�Ñã·=a½OÁ¨Õ9ŒÇ_[y£Ï…; Þ+79CÔ–HÊ 3nËsqèÓÀ ¡Ï÷Õ6–|:ÙýEÛËrFÏÀb͵ }ň½`»Zj÷8¨ÇŒkƒÛË^M¦š¯:'q™ÞuèiVÜz¹v*ÀŸã×yã×zvÏ ÆPÞ753#áœW·ñL!“]§ƒŠÁËvO7ºN‹äð)l‡Ý6&ªo\ëܪ- )·A9_oà­8tìé�­¿b˜=sQ8t8ÉyâuýÉgäØä»µGÎ÷Å û�ñ.c»1ÁÀ—oÎÿm`1ê¾×Q팹fcsÜK.‹;E¶n“[T¾ÇríàÜà‘`P:È®ü9ßôØDO½�WÁô&óÆ$µ"œæI9²�»¨Î±C2ÞXôÐ1¯t\s¤5eÆ�+Xàp]S\f@Ôv9î�îÏLÀïÿ{$ŠÙ-mDXÙ‰3|SxŒ?ÆËCßáH¾Ôö|²Žñ r÷ï>£¯‘kuláã½ÃJnú‰!ãðx:î0#‘å³YÁ{¹¡ËôÕ‘]*úfvvÊI@ÜŒ‹Ý$ÉË87Ã4äÜší²(0`tvÆu .üâ'”þÌ2?;ƒÂ«°jÑ'F‚íÅâÅ_]Mƒ¼àâw¦gPMª^Óþlô+»±�ùà!¿ëîü+;Þ½_Æ\(û Á:Ýt²Žïî|D›UÔ�wÁ)*-õ±tdÔŒ '•Ë7WØb§~[Ë­ˆ‡ºubLq ~B`p&ìsòƒ�ŽéÅéTsëqü€ˆMNþˆ’›Úr^ÝIXa’Í8­­5Šì¹Ž3N‚gsøX`yl}v}îµc¬?˜ä ö"ÓƒBC[}:¦ªÄ2Ílà‹Ød2 U\su:0A“Å�^©Š ÎpL½­XÜ!·^&¦‡u¼s3Äp‰®Ü¯�WŒèÈC˜ÚalŒ�äÉNü[{z0ê§Œ*P¶9,&–%ä(›ÉAáÈ"BêÞåª�àèÊ Å‘L‚Ïš)Ý“IÐM>PòO<ÈNþ8›Ô7_`ã µ?˜—ÍY àN-.|ôr3K™ú°à#Üx¦³Skˆ ÝÄ[®+Û˜»OÔ¼²žPé¦6BƒïÚ CKoÈá'_ÊcïpÌ/NùðŒ½¯�)9I?}sDrfÜÖü3SQ|3À�øÖ­nÕÂy­+³±4$í¹ð67tÔ“lyxà�ÛÄ&Ÿ:øºÿäë¿ì—ýRù±|á:ñ"¼�‰�Í÷ÿÍ|¼ó/~{~Ŗ"kÃ!â¬ÍÆ|¾ßÇbš�¼öƾ¼aÒœ½éN~ð©ÅÄÜn=z<»aÐjäqbF¹ÁŽï™£‘udå™<è'1xà2 šä¿žˆ™ÛÇ×õG–±„fì#óÌÛ|áÙc˜ü0Z¼ºooÄhRË•cÛ}­|ùõI[þó+ÁÐë„M’ˆæ”5™X<è£nWkmÖŸ”'qʹ¼ð�DM�šêrmÁ‰ 5LfÐ_s*w͘wS>@�^zØðZêZë3ê’âèQúqqP´ß¡™ õ™Œù­)°ÏjV9â�N[}Öø*ž_c†¥µ|™£_”Ó/nôÚÅÝŽ_Ç�yžhòiŒ½6ûïøyœMN1KÓ:þ; búåa¯°ÑGyÖ€)-.ù,’îLßÑÕ� ØF fË—‡ý�Ãã“¶ñ ªÿœ#6¾×�j<æ­íåÛpËFkË-ûië¶ù̼fѳ?fW‚//ö•ÍŒyI²«�º¬^ˆØôÀŸ÷Œ>¬7yçì2ÐgÁ{Q`}Ø »_Ÿ–s#-§×ßšO¤æ#µAÓc‹9Óáš¡ZƒÄu`Ÿ�o8™'úm?çÝ£ N.NkLGÓ‰ <¯¨ð£'×üLA!Œ\Õqõ\ª/ú6õPÉW>³sq£væ°– åq‘Ùâ—x\‹u Èmê��”X÷P›}èB»dp÷ÃÃãnÃx]O…‡š\È-Yš?C£=c{ʃiXeôt‰„(ݧ³–èÚVNí¶DrL:|*;^#Û§&«À2¯xà°€håÊ M@ºYSdÑ·®kZî¨hîŸ:^v[÷­Ñm÷…ø‘Ÿã‰¿óæ{é–*f÷š�zÿ¥_Áb‹;EºÇ€Ï]§=ùÃ×2 ð©¼x#§=›u™xµ�7ë®ÅRFÂ.G?˜Èär2˜Åì\W͵¾rmÜÆ//½Cü(N|pÒ8¾òûŽ †_äë6µÝ¿_ï>‘Ygó_æ6<7nÄ)Ü÷‡óÊ|?ž`wžAõÿH€X‹°£è‘‡~º­Žo9¬üø-æÔ"N×ùG㮕1°eíÄ>“ã¨FSñ�3ëÝ5‹w|\ƒXû-ÖòEÓwÎ{¼çn[ÌúÃäÖ&¥Ëëækü˜ÃÉglØH§|Ìñnô`.O¦^™C`…›Ø¡yqG'ž‘»èóI] ô†6h‹¥ËÈê©�vË{,íŠ]¾+R÷­ÓjÒ#ߺOžpè`cpê�ul—{Ï›7‡KžãöÒ=óÄ&øÀ§v» v½F®í¬¯d5üÉàäpb‰³6Ôc^9ô¸°y�Bpëþ7þƒÕ=î¦du?&æ=^v8Oì‘Óg¬'“¬2vçÉ“N@Hø~!SÑèuj­i¸ó°t6ÔrsR†Ø›It#ÉÍ_u±oêÌÝ2Ûýåê`ãj?9¼µvÆ‘ˆA}ó:7Љ/þðqß²€Ùïrãê�5>Áúà«¿òW~Ž/*"©?:jomáËztÉ÷½?÷¾ÇW|ÅïI>¹™óW~›#58u ·8°¯ì-éWï^Mš6Ã�ß›Ù^SÀùCóë5çÆvm¦ 7ùöÆLLòj=;~ØqÓ\—ÆáA õú0ZùZ¾�²øq˜ØØÌò;ÂNPGHjÞˆ6á):¹VÇ�õíYsÖ”Öσã§úXƒÌ÷“¥†‰ã8Æwæ“9ò)½Ó2––=³ÿ¦o=.[æà¼î>w…z+;—˜Ñ%yjÊš4f0UÇLq³±E»î@ ­5¢ù+ d5Ãk��ãU—rW8¡Îß„ä×ûñc¿úpæýϨ€ñ�sú�½ gÞ\ßê¢9ùUÏ1wl‘mÛš;�UíºÆ+߈͋ùò`½£µ@ äP•Cö_�»´�°ÇK"ÂÑ÷p쉄Mö!{d­³@2,G¹iˆäçû˜î÷ñÖŒY£óIÖfb5pmàT¾LþÖ£´Tì{åeVÞ¯ù÷”êoŽÄ÷¨®åŸ4Ù}xNNÕ¹7ðü’ ¹ƒäz¸ƒY[u™kÛòÚ¸˜;�|¤>ûë�h{,«ø:ëÝ9kàCÕìnÒ;E”êpÃ&J»%ƒñ„ml£õ›Ù¸à• ¼øš—6Jô¶ôbdâºðþšºn-¬mtâÜl‹Kœ)¡†m±‡&…Œê¦Ýó¾»®:ÅoætðÓI¦‰ºuiSÝ”õ”_Aôæ<óºCo¾+m^ñðY¬ë´ŸX<Û IDAT9‹Ÿ�!œp\·‰—ac¼ÑoÓ¿âÆøæ¤É@ÂàZæ÷‡Î¸ùã‹%Òpòr_�ßyx8��¼·{NÖt¹`”q¡{Îb|xƒs›ë;Ø®ÕMg¼èMÇ1b„�]øÌ}E¿ûö[’�1¥A5-^óþÀõ;¾àÈï²È¨ºÅ^šLcgÍ�‚e"Úd¦N©zÕk“Þz%_Æ*™+ï¾ÁÅ2£sy•ÿä¾h͇ܢc¿y&ÇLùøìº¯]c]qÄ4Ê'ãL´jà5µ5í±ÊI71š/D"Kç>ɹ”à|Ïú`/¾xo›‡fF¼ÉO™K9 àN×xÆ\azcŽ“4â¼õZ¾û©:õñ9°¸õeÜÉôéàsoâÆ÷Ègs€¼p’[-_r¿cR3¬ÊcÞãÇ`ùš—×�\£åœëâ:=¡9Yý¡§È�Wù!�Q­o�¾µºF€-ÁÆg±n¦¿ðp1oq7áS¤ØK|R3ÃbFæE"0îoÚXÄouy₨à71XúUæ…QÁ6»ÍîÃYÒØo.�“í` 9¼î®è·&7ù ê2:Úb3½Ö`•ë¶>­Å L®õ®oÐ{A©üæ»h^ÙÚ–aYm•ÈW“ÀÜ7µh�Ñ=ç o°¬ eH�Î'/D-HÔøä5s õ—CcÜ1$‡­^øÕ¾±‘�ú#Óü⺵Ô{ñÖÊåSn(VìÄœ^ÿäGŠÔÔ.›²(ÞÁX¥VÝ ã›øúÜðC˱i ‹oOþ±X}†[Ç«/�Þ�=¡.¾eœ�ãNŸj¿"µuÒ#P×:Á$ƒr$_ÚŸª ãR=m謭ñ•¥2¾±µ.­ç .¡.Là)ÔÁ"°’®“|wݦ¯GxÄöî%ÂçF.ÊèÔù˜�¿ëiùþš,VFçãhwíW„>ö½Ç)¯rštµA4Rm¤Èhö#ÝfžN9= ¿Åò&ç¼”MßœËýpŠÁÅ¿�Àúîñ3A"»ï;�[›(ðÂÀŽ›øg]–_×wð6P,±€n­�¡•ÔË$/}¸é>Jô¢`”WÚàùF[ÉRËl#�IöIÅ�_ÁóX1+·Á†¯øñýæÇçý«Ÿûx{þ!²½1½#Kû›ì¿òW¿ûñãï~Aã‡:_ä…Ý̉²Ž¼¯¾…[cÆèY�>ÜÉ…\n(­ã-0‡À^œtxìúÞM†áˆ¸§ÍP¨­I 9œX¼Ú3|%E1Tl.¾µz}[ÐâÔ9âè³[’2]ùÅwÕp«ë`J°ö©ö<¸àδùÖy±^ç×8uå! 7™­0ËnËo¹>·ØñïZ¿­ŸˆO#–õÏ”ž¯þ*h”�_ó,ikl\æâèlþ –#žA‹žùâô�VT¶áå^Ï!v¿‹¾|ÉŒ<<âïÁ}8Ÿªë:O,vŽyùÅ>c|µ!pê¿<˜Ù¢o~œ$i2ï0Û­Uý7zjÆÞÅØ�ê°‰$fÆÎþÀCJpÜ7¢#÷>k=@Ø8>øËÜxƒ>¿’�l[V`Çß1Þ¼šC¹ÖÔ£¾WnqiŒè‰i\ŽNde¨ô³_p~j·¾Åí>šñøµö9^óƒ…¶ÖÆ2·H›‚±îò­Ye[¿òÙ5凇V4¸òÕªì>TÎ,ž³0±Ýë¬[0[÷Î1g„ _Æ´ÖooÀ�VükCýn«ƒV>`��ë"†Z±Š¿ücŸ‚X_úØŠ‹(p1á;ñ™�ÑÚV×}Žœ«_˧�ë_ßl;È~0Ñ3Âp#Ççòì êX+Úò8xˆ·ú9~àq £ñÅÿ¾o›’ÂlœlŽéõ)»B›m#8æì'Ó®\*x::*¸sl"Šé2SPß³%îI(`ÿë:i‹/vƒA ÐÙáèˆ#ÔˆÊXìS}ÏØº/Ø~úG„{°…&Ïy- ýS‹€7hÝ2Ƙ±-±íoë„ úrB�­õ;¾µS‡ ³µs»‘»Ö~÷¡í××Úqާ zk§¨õÊ•ˆ³—üZã®�õM¾K™¹öxR‡4JC³ãxžë› ã;vÀ=ó;Žvø�Ü>Q6ªÙúžU_ìÉn91ò�B SKó“ÁÚ27Fg'^Ü{ãh±Üã-'Q{‘ÐÄ{m¨D$®n±Ùc@®ðùá?ÅéU91‘»�ÜÅ�Æ·ÖY9š{tààê<öK>*/ûk.*xã.1Ó‹Ç^®,åªán†~ž 3ãÎófž˜øßmL~ÖOŒï›�<¢?À G !LÛë«ÍcåÇ_‡ÌòÍ¿ZÊ÷ÅR`ûç€wâ·XWÁˆ"ð…qKíi»H'Öø=Œ9Üð2Iø”4¸l£ocŸèqÄÛX\¬�x·6Þ¨ˆM°›ñ Á�×Ì·~Ëø‡kqÖgwLyÀ›–<–Èk#ÙÉ£†”b|FàÁæØ=…ژカwߘ0E½yâEìÖ¤,ŒwüÂmìkW_lð%^!xÑNœØ;ŽM=/1nõ8¡c‹¯Öª=!ŽlŒöÌ7œÌ� ÇvH>éÊkqÆÂN~¬Ññ¿�§rD¹ µ*w@à`ÚâÊ‘OešŸfÖ‹Qëw0"Çïe-É ð µ6èlÈÉ%F ÷¦êÔt«­ [/Jè�hÖ”9|Ò^Öïä�×8Þëxu“ÍëV+ÁÃÙŸ†Öá‘Á¤3ˆTsj…ä`¡‡w:F™2¾lÑw^˜†øæËŸ’écLÄ©í>ôl=E›@Œ‡ a˜ sÿÜ—„&6Ç6œ¯kï0~æå tìpáÊo]ìÙ<·b®ìy?# »>b•ˆ46y5åàŸ�­<|V¿D܃óÌSeb4¶u› °ÝwM¿©‡Xº©qö�7s¾‰W¼Ë·Þ®Op¶Où£÷:“þäJ�mÓsRôºSR£ZĕŖd%@ì«¶}Ó›O>áô/ÿºåñEÿú?>êmùØËÄj½&ÿÜäŸùœÏð?þ ¼}ÃRí;ôpùS?õžÇüª¯Ê�j0·7—ùÎ ›ÔQŒáÞ›øGº9eXŽÍ—1eá| S†¾‡ÌÚ¡·ªÑá£rm5®x`²4º«\ïr¨é6âE»¦H"�€`¦î²—ƒê:1÷aO§±o-ŠÝõa*Wp‰uZ0(9¿˜SÛgýÆÄ <÷cÅÙ\†6“K†gý¯|ão¿ïsdÔ°æ&“üRìÝH;¾¼_ …MM9”¬I !®-L¶ÕA^ˆŽ¾µ_^QŒC×^Äܦ]| Îú«Ë”õX®Ø}³~­Ûb­ÝÖ.Wƒ|÷¯•mžÌ»îàq¼ðÊÀ��y‘Óp;˜Ô0|øjŒÆN 4ÛñÁ:ûܲ•_ÆHãü ]ññçš ïiqíy6¶÷k|Õã�æ§ÏÓ7¢nkŒ=·®þm̓qÙŽx:9Ç´(õ©/ùl¼¯­¤Mž¹o+BϹ¨®ü�YË•åŽý^ø™ ñ»å®¨ÌËmj¿¹cË:ðµ~™o–F‡Ät�j4±ÊdÏSͧ­ê‡É…~}ˆvµ�O)ê§ý˜*Ñ‘Í`¥ïù,’ƒa›HL—ãшƒÏu?­n呸v?…õîof0¨Í©- šneàjù“m¤Î¹ °1»7ª� ¿@»ÇÚøÏ¦øo:ûG³þ÷Qà¿|‘Ëî™àåWãr ®k‰,^‹½u\]ó"mgäZ®¼úL—>ø¤&~äËYxs� _oRaÍÄg,&þr-V‚ŒÜùl–ÛÊÌ!vås2zò=\ÆŽ7Ÿ §’" ÞÍ~íè§<Q‹ +B|øjÛþªrü[Çäû-¸²Ñ[ t/šŽ£|ar»ÛQ$|ÕO¼è‰kì{öhñyùÀTù›p@Þ2 >QŒp?"9QJB”Ûæ¾‚/ÀwG�ø­ý$Òr>:„÷d3Þq I( 6Æ)<Š´ÙglwÙâx÷¸uªýr¬[Áa™B˜õÈ×%ËhäbKP³³CÍ,Ý�_|æ´á…ÝÁ�x ”yáAä»e`lpïöȃ´ø0Æd×YÔ–áðXªcB§N½øªô^|Y›c?9i~ÚŽéùÖ~.&kR;¶OØQö`Q¡NÎ °‰|1F8ïþÒBÄŒ÷\ldü$“q¢nžÓ#Û7MœV íÌ9‹ðÍI¾ø$^ßùe_¶+·/ÁKÉHÜRÈ“qøzjÖ…Ëiãk3yo]ðÜ Òêu.§ànò^Ü­Í=lÝJ2ò SZÒãUß©;Àš0d¬h9�5^[úÍoÜ'8�ÀáBd뎬õêEþ˜êùˆYMÛ—Èð+®õ#¶ˆÙМWß ìT�¼¶�¯ò wíº_¨#ôuØüvŽÆ}%„_â[FäW­1îöÙ$hUäO­úT‹0Êk—ñ­@ͤ;¶ú í¨\bväõÍ4²s5¶ø�†ÑcË wÞWtÂè¶o»pÜüp¿�idÕ›ÔíOÒñ™Œ10�Ì11«œ´™Ñ@ÔtÆÈ*¬T´8`wšÂÌŒ?vÜ8¦y“–YŸûkÿ¥Ç×}Í||ìÇ~´r6ÔÛZ) fìŒ_W¥Ð'«³6÷yƯåfþOËÿxÏ{~Ú›¾æÛš°G,Cæ'^Nôpó÷dlÈ–Û!8•¹F³8Ž‚ÿtûT‰±%‰•·NWµp®ì|Bm¥2³¼¯¾r‡ A–וç®Üyº�’§7kqk ƒ;tÀ®Yq˜÷¡`cp9a]«Dæòò(Pq‚iåÙvrzcÇ|94/Œ†Œ¾lŠ�_E]›«¿ó®kú°`̰iœ=^6Hc £µa_D¿œ¶�Ä}Y¥ZjÒ<ðLë³õ$Ïb…<Ò*ÔÁÚ>åžóxâð ‹3ô/oT‰µpæAŠßÙ�ás=¸ÂîùØjYe_[@àÓ‡=Q±Æñ× œ[þ#ŠG�“Én®•!vA‹¤mÔ®öô´«–8÷X_™Há'6}q®{çÖž|º`ô܈ä�f}u>‹ë¹ާ�]Ðùò<)ßÄ9u 2vô¼h‹Ñã8Öjä Îè½Þe–z¾ï' =n… ¹$"Â’\Š7Ñ0\xˆ‰_Æ®?:�Ú-¼ºSÛÅMû:õaR¤ðû³�L¼$9Æ7ƒÚÃ>`¸µw}Ĭlù^T�·‘Ÿ×ägŽ5`&çСçÞæ2Û"d$Æx!'>_|oý˜7k,:ÒÏ4lÈÉÃ} Kb`ùÖÚ5oàhÜÑuŽk1\[¸S» ·•V'HGÀlh0°mÏdÇ‹”\'ÚæŽ <èj/VæÝgUŒ}ç›Ór`ö�yX?ó8¥uM:îüÂj>Nw¿NåGynÐ6vŒÈjÿ¿Ú俾ÂÆ í¬Ÿ²Æ:õƒ×œëÎ>»þŽƒ³üvšóTëBͨ¸k4�—ÂÒIðbÒzoýž{гxâÇ—¶àJ üÄ\t»_ÖGVº®[—å¸ù^°é’²|gC¬Ž»–+G÷çiú”êârýº=SÜÕÇ9¾§.êâ^r–ëÚOj¦oìÌbY£‹ñ¥-“^/Uf<”±©~ä̉«ß�×`áÒˆ±ÈÎCŒ+rcaq?†�»‰Ïmß1äwȬDóÆ@VÕ¤ƒR¾å îæ{ÙVÏœ¦-ÛÉ¥·1ͱÙg"h�-~¼¼¯ÜóÆå`|ïi7·í±!ÖÎ Ò«wá 6¤°Åùè9?E¼c»ž(BmŨ’´@KÆ@ÑͼV];€:âb³~1‘ÿôO;‹¾å²;o1�]ظÖobÅOYÏNÅ2PziFyßÉ :âj“ÍiÁ„ûΉ�Ÿ€Í©>Ãa.,1G~ÚLŠCœåÕù‰=øð1²Êh'&˜[—å¡n‚¸ÞÛ-�µ¹eNÒ¼¡™òU«1Þ˜@âÇ›¦DO‹@>Œ­ýÍF:É7:±Æ®ãẺé1é*�%¢ñ  £c¯¹Ük·4�|qˆ•¯æ´VD¹Ú=w¤ÝW.Ûåö\Mœ:{Ö•85t6üôì±UÕUWÌÊwcb³ü´s^X¶Ú UB€à4›ra†fÓ�5¢6á²sÍ€H»Ë¸Qc¶9n°hf@ÏðfwÙ¿fj\ ¦^ÚêŸ�õAÃè›G¹žä/RWláŠ�qnÄÅŒª‹ç5]",bÇÜ«J‘Ç&cícCÌáýÌ—YuÚlÁ ÛUÓ•$ÞÄEr.L—ƒ[cj!§[º�íÀq1K·6ü•d,½Í-BrSÆxxÑóp…‹E÷ÓÔ'ïƒÇ¹™so9þ‡\y´¾èð7²vÌyT0¢È|l°Ñ¥å�c}|?k~5ç-ù5NbÉã «ãå%P¯t½0� 2ý”âSÿñWÿ¾ÇÇ}ÜÇ o‚N‹�¹H¤ÜáL[.Æò�ÃãÇ~ì'âOüWJ™cæC¿ä´8‡/ÎÓÐmÎë§9ÕÓmÎ÷ý÷ýtIÿ‹m×ã§Z`H šfMœƒÜ:‚ 8€K-úP°?EåWVû8ùGõ8}‡÷¦mr7v¸±çbu-šŸ×0CpiƒºÓÈÇqæðÚ:Zå˜� ÚXéØ0�ΚžQõ®u tk¨‰—ü­ú´{Ìú±¶�»\4$òÐð¿ÆfNÛ˜r¤Žü§Ôäo™•_°–ÿä,yãƒsTäO±¦0DÞHÙŽ?rdL—³þØÆ×ûn Äéš¿qü$˜ÇMícyò ÇâEÅnʃiò0‚Ìò½Ç““ɱõ–±ü6Wþ6'‰t‘îxdœZ~ĵ¢ÂSBXæ Éõr@�WÆÙC¢o¼öðKÃÔþÚÏžêW­ç¿ÊÁlë¨@‰Ã§¹^c�9vÔgS®ñ1Ör` Œœ~¹3þ ÏCùF"ÏböGÇlÍN´±ˆŒÖ6b4Ž·ý«:ŽU–°úA@@sWi çðÖ‰Øqì¦sØ뎡ˆÑùC™qÛ_».�ÆÄ]p;Ž­¾ˆsí/+¿á­/`yyÝsÏ\ù¡çÀŸ·M |]káØá±6L™t~ýàBͽìÚ÷ä„=BU»!󱺋åÓýml1ŠŸ5Ÿš\\°b/¿ôã·6aí®šbOÞøl†Y!œ y™o‹±°Ì#Fãü×ðÙGsÉ×Ï<ñ?rªÇ�ú„ç×»§ìþVëtÅÀþjÏrÏEGÝQSæUºOQg¦pA^‚§›¥¨ ³åK¯2¦ãwæxˆÉï öcÐHgÛýÿÖôØßñ°±ßz¯SÊÏ´ckÌøåà^y{¶A›—C|å£ÅÑa§~×c µ1ä„üî¼€Ë9"Æîj�õÊöˆ—Éá`�Û™ßr=²;>ö-ƒýâž@ã/�Ḻåè�þ[rŠV}|ø¯q{^ÙüõŽ‹ãbà¹\núSË5^>™;”S•Çm€( qýG›÷ZkØ}£ž�Í�ÖrȰ´0NkGÄ—­ë½9tÙjwÖxÝ‚IÍÀB·>».>Ð(€ºu3>o\ÞµÔMÝ®}|¬Ó¼¹A˜uh£?HŠpƒÇ%uÕÆ|¹Åfx–ßàM̳{ÀnöÍï²’ÎRbÂÅ+íNo‹�|Ô®ƒsr"DsíìfåBaçÛs¸^v<ÔÀžMš8v;òLà~ÍÐR­6óŠo%—ò]ÇC$.ðß÷Jbc£/<ÍŒóMnžç—þû�w¼ã“Šs6nã ‰èä‡ 0ä6€ãwŸ¿ÿý|üѯÿc�~à×Od5¬½0Á17�;føVþC€a’+Ãä»~’ eøó¡ÌÞ¤"À�‡Tpâ½roJÉì ŠåÓйѳz™ˆ“y?ÁLFÉ…¿øZŽoþ›qo }¨‰§ ø;WÄÞ@$¥Ù7rõoÏY7 æ·¾ƒGwåÇ~0õ×�y5I¹å1¥\žh52¸]Ùª³(n \O´wYÈœ<á9E.í9>•yuv¸qµ¶1Àu=³ŽûUÌ›p¬ß<ànœÍ xòªì,ðM„�S�ù±ÃžaÚþ½Á;ïjb0ûs#ù�‰}+sp9'Ž2n¼G·¤n;ui½°W—ÍšÆÆ>Ž�ŸðŠqÝ#@¿1bŒ½µŠÐb˜×ës\C|?J-wÿÒ3> ²5n&�aiý3¥õØsT;d`"’(3ÊÚs³ v¸ÐóM xð~÷ÖüÇtŽ×tñ‘#ÓóP¼Ž®Ñ€ôýj CÚõÃ’—Œî�Ác¯ñMP9ꑘԮ E.8X÷P³Æë8úÛ{ã´Z|Ë›xÅ1ròß÷cDWsb³ÚfP]"sÆ$m}qb·E€¬ö²£Èt›giUz8Nœr§™DçC&c�að†°”;Mü$¢£„£&ªÒ7�ÓÇ¢zœjC ¢å<ÉÍžŒÁ™úˤ �3‹.8î—ІC÷‰£'G�À -®è�W˜I¹ú§ÖŒÝŠJºùÐSBR›m;;i—Ró8üíwœ‰@`!ÙFžÆ:ú1ؘºe“ù�Çú·Ï a‚ë€ÃŽ`7`ö³Tš,>GÊ1�¯õqlà‰&ç1sŠ xåkãayüÎ8²Ø..64}äw'£bôø$Þr:ýø<ÀfjºKvôìѧ#×°¢r{1v= A„ÁÚ܋޼Æ7¦ãT¿LÖç䫺u~’Q¤4±®h!Å{›µG{xÈy”\kŠ•90=¢Âkâ`f ¢¼Ë„Ï_Æ{ûàŒ)¸ÆÎˆ<߬‰7Î 8¤­íSí"ÊAGÍQÈÉecôrÀ7/-°#2Æ3ÇÙð£»ç|×5Ž–ò\ŽÖ�“9ðqð<ÊÈïÖ^ùÈÀ4ÜÓÔݸ(¼Íµ‚ÄÏýÛ`D´¦»òqÏo΀éÛý€±ïó³^èÓ€>ÍÉHü<Ü„ïäkÆv’™¤–ÔîH€»C@`"yá�|%ccì ÝìGpôÝ]Ä›„–‡>˜‡Ú£W¡"66L¬*6ÊŸ|‘¯Ó±Y9°÷VÞÍ©uw0ÇÙà ´ò�ŒQÛ «[¾[c,°\kqýi1^|mî÷\x,Ë�zFvZïÉ RZ³©zx#¯ß®Ù‰vªˆÆã@ˆ²mP#ïÆòø%ÿØ/9¾Ê‡öÒ‰aÛöÑÄ™Éè–/`ßÿ7àñíïü6cæNß‹ÂM�ñ:ïÜf-ÝDæ ^mÑ6g˜gtóç•Wº_ºOð¾†/ßâ.iC¸9ï׫jkE¦>¤£‡kŽ‘ÊÑ ¬¼´‰ýÈTƤu¯²Ðª£Å­¾o7¯‹Í�þ“ŽY ã'¯2HÏàö^Ý\#lqÆNh¸ìúÀ…&R8iž9¥ ¶6'Øñê±¹c{œÖ+“CƤøÛo޽>ûkåý|òÁ%�ääÈž}x�¼W‰ß‡ Mè¶Ý+ |«qpcTûS³á6Q©ûŠ©D·D-ë‰Ðkã~àù2Ÿ�˜¼zÓ:NéV®Žy^°•ÁY\ŽIe� 4“ÄÅH'î IDAT}ÞÁYìîÏÁ.ð\¡¶J¤Ýqù”c€v¿ƒ¶­Ì—¶Ú]„Ä¢Ö®€µ)å]3PŽ_}ÀWìæÉ±6DY³+޾Äå˜ÎÄúu©AU­ü;ǃ):à¦Þ=ø*s»úÍNáÉ!,ñ2mùí )tš �X$YÝ%Cåy "ÊfÞåä‹gÊs½£=õ¨%¾æAÊ•:²ŸÄÃÜ4*—%<ƒâN‹ þÖ$­7òúމ†J؈Q½¾áî{ Æi×¾â¦Ûzìq¯P[<€$'â×–wù¹Öj&>ƒ8{¬.ìÅŽO9”]½4$2\$f^òÃd<×|xZ<âçͯ¾«,4Ti`‘?_²Y,µÑ¸�ðÅä¸çÀòBONÙð ?q Ñ}M51Þ„(OóÅ7 ’oÂÁìÞŽ.ÞhËÝamñ‘By[hŒáÂ|['ÍŸ¸­[ZåãаDV#œV—¾º#:ÇIòµØú� ã»�p8¿hœÛµƒü§ë[\ÌO^›2²|mÛ ?“Óö`Ò¬m†øÐwg㫼ºŠ—K}pGƒ+s£ÜÞ [ó,&¶|#‡·}p–ïò„ÇÊîøÊÆ›{~Á hË�žëTåúÆ`8á³¼Í cÚ’Ëpõˆ—Ÿ2|ÍMcÉï&ë¼EûÌñcM½qž›Å>€BתèÏdbxþ_bmìò/2h¸7}ޠʯ|ŽSœ²Y™Ø‘ *Úh;ÁÀÖZn¼rÕ±)ü¹ÛÁóx/øM¶ÞÇðf³ºI¯Óèîç~þñ{¾â÷ÎßJã?Šæò>:QÉ+6­mÁ¸�Uv²»qÜ P¯ó×F%�UÌœWqÍJ”W_ÍÏM}@x5œˆ®¿7ùèÓ¯ôØÊÙ¼ØO®ýã’k"œ›óšíѰëå~¤ÏX%7Ï­ Ø}˜ ×öàÁýò¹Ó‰#¨s8ˆeâû•Þœ¢cŸ4/scM—Þñr‘¸Æ?ÖÏ(Œ‹SÌÍ{È\uÊÈK?LàÁq²æRûEÓvòg>68�yùÚOìéÌÚb3^—/\’ãÕÖ‡*oë#/xÒ\Å=v³OdÞ[„¸öÅBŸ‡âü-Á×øUXòÖ‡r¡FóíÚÆW„û€«~õiެ'`›“m¬8­Yg±£ž®.Îè,éØZ¿õOÏà ƒ >µÉ|æ¹_¨¿°â O÷§Ý¯<9”pôËOÔå6!ðkÌÖ`çÖJ®FpÀE,x2v>}ÆîsÿµÇö{³?S °htÆ[§È¨Õ©F™ûÉ™x4|}Ÿñ¸æ‹v[cn ÞÏyðÌû|ü¦þÔ`9á˾Eïxb`0‘.¿ÁPƒŸ¶—¯ NlníÚ?.Ü5)¯[=Æuwxa{ªqƒnÞ¶š¹_±&õÓ9ÍRaCmóíqŒˆ69k·�;öq0/\7œ\ØDã8ÃÕ1Ô°Šûx9­±tâg®ë‡Ûºc³~=Bb0±N½ y9gx™\q40Ƶÿmm°ÕéŒqƒ™Þµâ­Qd Ë�øN€M÷N¯3ìP•OkÆqk¬Z`”“é•g¬i&;·�™vô#°†øN³fÌoóÐa�±ƒ¦×úìº-V×'¡À5h =W®ý®Ûε½…°¶JåÆuk¦ÿ ¥fb4æ•oØÅ–X˾˖bqÑUûÕâ5~ôÎ:€×ZÉ�9‰«®es¸Dµò�©ÓlVǸÅI�Ë•o95×r­¾y/"_œkÛ8#¥‹›¸Ô.~k�Ü@]Þ‹�LŸh믆ß$pcþë{ �'þ6ô4Ù¸N�CŒ{ÞkO¼Ï ÚÓÞ¤÷„£Ýé‡ÁG‡gûb¬�ÒÍ�ZÆŽÍÖŽi&Ó¥®÷Ÿ€Tc]jÄ8/.nNõ(F¼Æÿè˜�"j»ñÀЭ=¾4d««d�wöÜ~ŒpVwh­%x7L-™Ó”3 nº<œ$Ï‹ÿ OwC]³A¶ò¼aˆ‘¹u .0Íáp°ñˆý}‘˜T±»¼’ŠG –1.«K·Ø³"S¡àNªø\ù¼àÿèýé5=ya?qo;<ãÀX]6~’-F�è©—ÀQL Åb[Aç‹þìÿ„… ãð”K„[Ãõ±ü6búY#"oõŒ®ÈµÁÖé±30áµ»5«_túßzÕ�“ß »8�òiPBŸ‹ÈÍU T¦P–f1䪾:ì—ÇÆEÖ_½`Íš+²ûÐy ¬ÛÔceö–%ZbG@oìLúðkƒA¤©…v1?œ|“ÍÄ'‚ÜãX#6ê?Â¥Ýk±yWƒnŒj¹b±³áûMã`èy=9ø…4í �{= WÐçØÈt½q×·p®¿?ªéúô§6ÂñÞ—ÏrÐà4i ·­³ùG&ÇáÐ �a4[£õ!ä1=fËcâODòß‚€ÓŸœ¯šŒó}â� ÛSWŠ&Ð(ÅÎfIE ,._ #ÑmÖ(XÜ<âš[©ú,uû[ \'¶˜E3nnõŒ*olÐM¿´�²ß³Ÿä·êÌ�ðSÕ7¿{“ “·äcŒ³ÏœðŽ1í œIÐ3É óÙE�ž6´œó·÷¾ã;ÿúã‡ÿ¯2^�ŸoÌÖ~ó)PV* t¯Ì§!È�Ú }zÎÃý£ÑÅ?×3ƒ®5ù6¬¬¯Op�°%÷–S¯AÊ upï]Ö¶œ‡;¼G6Ìá ÑÐWÝõiZÕIu˜¹n™Ô?ó4?ôÄ”MÛ‚0‹î<\jtœôc¿!*_;ÎÐrM uôƽx4¼¶V¾‡GkÑ<•eÓ5š}np}P4¿öMqø[{Øí«9’Ð:˜ô\ë OE0Æj SƒÈà“W hÃh[}2Ãvâ®öŒ{HeMÙ÷R;qM¬é4õ¨Ÿ‚!'u±Á—ÙÅ"FyÌúxë냉Øi=v™„|¿ÃarÁ�œcÑ)Êžº/hÂ� 2â`[Gc&IÏŸbj‚!ˆmIa¾®%¨'CZφ a¸|H“_ïÞcG—Ù(~€²¯Ô Ï~ÇX‰Á]»˜ÈÇÍ<6=ß•¦Û=×6ŽÉQÊñØõÆ! —‹<ª¸ñA:ûãp•qò—z H�]â¶–Òö-;µYûû“…œÜÀÅÔ¿O¹k�˜‰Õ𕻥¹åXR¹ZkÛ¹câX3(.ª˜XZJ»úåJ½Þú áÉí)ëu±×^¬Å¤Ç>æØ5aX©ntÿ ·ú¸PQ/·ó‰M|åÄ’ î-†Í`ðAÍNÐúÕMŒ>þª~`c½ex+—‡ÉIÀР§Þó–g‚N›ÜwºÒ‡¤ÅZpC#I^£j]׊:ö¸®$†ØÒÎ�«ÓšÈ0spv­KÏÄ …�µÌx×|1î,Á“w„w9ð#på³¥h:¥UM-j°•”#cƒ_¹31¦¾-¯½Ï�ãØÛ!r_D÷Ÿ1jYнûâæ.OöoND7®Æ 8“¶yÞó å­^Ú5Ç.së `Ú…F¸Ô&>…Š ÂLF·#ÖÁÃ=v]/8Õî[ Øí§8qXÿ»Þ¼Ü¿†“EÛÈ`ò_ûrß\†Ô03®¡™¬RˆøûÏå¦É-fæOm󨉪»¯µ"u‰vãŒÉc׿kk&/b€ñ²-öæh ÂÆð öMS?àJø¾|¦Š°ÒN~ëp10x×oÏcd½Xô�È�©t畸]ü9ãÈN[¤MâùÆvU’‡†%¶´éIŠéirk;qŽ÷M5»®Ý¸lL\[¨âP^.ЖÏ]·å Ù�@Î�Ìs‘7±ú‰Ÿ˜Ì¯„=ã^¹ ;J¸Ð6Êæ¥ð$&±I¥8]ƒX‡Ï‘¡×‘»EáÄ©ýè&ŸãG.¾ìƒwa\°ÄЮω,_˜K^ÆìcXüc‡ßØabþ7 Íï¤Ñ�þò'Ò�ýä‚\¾øfC=0-÷ËO;9hÖºàì@ã*Ï{°6Á Íxºe®N±›Ã§„ª× …)÷��lº7ÄŠq°ú²k?ùhùmhsQÁ&-îp¯]FKeòªQ€ùüÅ8Ü—F�ÅÒvì·p´coÍ´¡Ž„:lèàƒ.¯‹ç⌆£gH;ýÆ”Fbq!†ûèî‡QЄ¤�¢ß¯åÁZã•OÕ3=¶€ÕÖš×ou1O൸Ù|�i³4¬róB–Ö1žÍ§k\Ý¥gDDjñàÏèù£Å/¿è²2Ü�Í<†;6�£)†#ôcßsðLP¦=Ív2u:²VÑàPH»òظڤHr ý§ˆðfh½½ËXKúé Xøj›�*ã¬I<¶B�]ħ—4ó ‡6ÿõ÷GìÝ�ÿè+¿2ºüYèÜL°\ÜcF1¹s_åf.Ñê3ƒ^uéœÞàúþYB³ËߘsÇonÙ\kˆýÀ2Xhlf¼.V0Hƒ7ï­™q”GÂÝ÷XÁ­yæAÑ$\‹ƒS$ð‰éUŒ{õéõBbbƒ¥ë”ͨv³˜À�8‰iÍPR«| /,–¸òiMþ¡ÉðSGÞÕ5�"ÊÏà�õ-�ñ²+:óâ´¯ ºÕŸ>h–Çö˜ëÆïTøúz!£î#Ç«û!ÑÓŸaK˜=dw€Å‹Q×·û–û²|1æE½¬‹û[@ƒÆMôòê~™pÑc÷Úkù/ÂÚ9�µH<œ3¾Øò2è‡ÿÆÀò›—ì#“›¶$&r›š-îëë>­mŒ°“Ödp"g¾R\¸¾ÜzQ6y|œÚm<Àï‘ÇéØÖ}غ¬¿}0N¬Äd¼ªÈ\Xºvâ‹"MëÕ°µ¹bÖòF�8�L¨–rˆºuU›ôývì\sôµ¯r¶•ÑK_ÈbƒjærÍ~w„¥3o«!~¥g�w?·™@Ö!ÓòV€lâE�É©_ƶ±‡#/[Ö‡iÞØo¨â]KØOqŸµ‹B×Ù çZ[6ÇnÁ¹_¶†3w„sð:Ó¬òlïët³@£M7× ÏÙÉçÎ…ñ”ô¸NÊBlí–Ó-ÜLÓÉÕáZrݶ>'ªûklO,3Y.ì7¸ò6U@Ø÷®Xúܰ‰mÎØENŒòÉà –ym^(žðý$?ün1Å‹»m{,�x”5X³rÒ¨þøÍôHÄX3ú¼šÇß:ãêµ…ˆqO|¢¦v‡ñÖÏ·‰³k!P6úÔ{E7>“Áøã+ÿ±|ïÒ;8�MaÆø—cù9_Þr¨MýާxCÁøæ'îì3QžšP¢Êuðt�¨SÛæbÝ�ŽsÛÌ«2€Üõ{ð±mÄ £seÅZI)ŒZ¾ŒÑ>W»ÙOyˆIÛyù+>Ÿ¿DYì#Æñð3FÎÏ‹½VåÜü^êÖf{Ù´4b“ 1�ã+œó}°F¿®ËQiñ"?*ÖoÖp­vÿ#ž1£ç‹÷ü�ÙfÀûTŽ´…Îà´u8AžÀÑ’Læ¤Ø7´Ñ#·íÂÍ”nýwœž\ò>4Qkq;íæG†$‹Ýò=4pæÊå°2äóBô†8qr[°5Ø'<ÑŸ1½yMo­0CZíµ�ìÆðÆwµ7kµ|âטôŽD׋ú€n4ôÏñë‹~u½ÈÖüøî6 FY\}‰31Ä—[sq´¾Í"[ìn$ȾhŽoó2Ä¥Nk‰ÝÊtd“Å¢rq]òûx”ËÚM/§áC^Æ!<¾ƒ;êÎ'6ñ§ Ðö¦ |Û à¶µÇ·Y:Ьo€±÷fÁXäÓ™k±2‘vC¼á¸èú¯ÕïŒ�2ƒ‰£(8R‹¬9¤�¬uß ZÖ|ëwŒñÇ Ëî>î ŒrM×–Þñ À§±w4[ ÄF»[�[5_J»F£Ì’i‡mñŽ}Ãh¾›æ‡ÃJæ+ÎÜLn[¬ÎgmW{pZ×TÄ€ciŽÕ#ç«v‹¤A&Mx÷Kìb¨=–Ý×d6–•!‡ÛÝÖ N¶ÄkŒ��{ç¸çÆÑéö ld‰o0ÌÃ1Ø™‡Hq©Ïus_Žk»9÷˜Óø™TKÐ|�ï— �6FO£«N7µÖ'XÔJÖ JÀlÔNçK.Ü”9WûáåûbÓ«Û}{““÷û~þ>Þù—¾ëñ_øE�÷¼ç=Ö‚_q4öàíú[ÏÉ�Ê ?µ˜äÇ�éÈ…u))lˆÕ‡yüüÏýìã½?ûÞ:a3vµÎtçc—›¼öÚ‡ZÓ© q1+·+5æ“7Ô«ù c¡Öµë€‰Ž<ðÁŽÖŸ~BÜ“ð¥gH,¿FÞXà$¡Íi{ÁÙ¤©Î&¦î§¬A0àâëÔ®|xhÐHä=Ÿàâ¡@r*_bÚ0ôr~J±÷56霃õýéjýˆ;|hM�ù¦Ë̉¸Îjæ;ëWšvŸ^ablåÝŸ?ìC<ä]K[ËÖ³œ'°gߘ¿o8ÇÃÖ)ú=îðëBEÂpÜz‡ó^çr4x±NO&¬çО\5UÞ�üŽrzíµ×º/f-hågö‹€ùM„ѹü£·¦•³¿p¼o›Ȭ6àZ“âïÜÔ�b ãvÚØ$į¶Ê)뀩/IF6õèþŽžÁ-Öòl¡¨:‰µ§vÅ/wÇÁØã»î b›|Äc½xp¥P@ÕÑc›M_#ÇÌužØŒóÚÖØÍ‰u¤Ü®ãŒÚÓŽ×ÚL°ž=c0rpd3s�Qß•m5ÈÈ üå&ô8ÖOxsC¼û¸vÙ°æóî$>úzÓ”'�“~©LºòBï±£†9Ž·z2#7ìxVEº¶ÜÜVj�«ŒAq"oëÓJ¼0/èáí©þÎíÄ¢Rdÿ/gï²sk³dg­½ÿ]…�…�8ÙD‡–/ D÷�Ü€†!@Èîq)HÐ. ·L‹“²�2¦¨*—kj3žgDdæüÖ¿Ë‚œß|ß̈#FD¾ó¸¾µVfüC멺Á�¯ù!{øOÜðã~‚ݽéÉ7†É$Øî¡+IÐò~‰ l”XþMayf2ùºz�3µ«§`É�v,\>|Lž|Îû�¶çÏúVÔ[Cë–àݧ=#‚ùjWžO�äõºŠÙ¾n^ֹɇÖ¾ïàmh\rÅv³ÊÝ|ãXþkW/ys«ÞTƒø˜Î5åhƒ£ñ‹iJr‡/{õæ³ëæBðüó,™1ð{S¼ ä®÷™’A“§slÍ}çcþ ªv jÜ~)ç‰Ö{®Å¨˜z�ûО(ø²fm{^¿À´Ã=†>oSó"бÞଇãWÁÀtót~h� ]/Þ„3ûÞÇÁÅ;"WÉÝ©±WkÉÈt4�ÎÍN¼_jH‚¾ Ã¿�Kâlí!hD1W4~îÇÞøsûYgòf‚Ãõä‘sÀ;?Å<$Æ%†ÛáÐÿ²æ:ájFölâɽ²ÚbÖãáò«ë.s/°£{{Ä>¸ âîZ\ˆ!ûè×’¥Æ`òÂ}x—Ãø«fk{¸Ø­÷"½ëåóœ˜�5Iþi`ì‰©Žæ:sûRÛ“RÃr/öÔ\ø9}$ Iµ÷w5¯çjmŒ×ñ¹Ý‘¹­´Í»‹ùX«a<[tsGÛW<:¸™\8NÍ‹�}û!.˜¥ÏØ–~ .ð^â<>Í>�Ñä’O²ƒ_Ý„~ô5€ÅÉØó¤[m¸Äy¾Z¶6üÆÆ…Í×íºIJv|äÍ]üÑR1Öj|׉Þ\®næà�Y½ðH�›º—ÿõ£Å‘ó{½›s“ ¦ñ"F²†t¥¬æ~häƒkstT?gGX6Ÿ@sb=�²h×8´�³u-ÌüóÁÛ:ÿßÿÍÿéÛ/~ñKa” ¿×È™/܉›X°üÖßÿú¿ýíoÿæ_þ·¾ý¥¿ôo|ûýßÿãûBùèEûÑs?î——o3-–uëíÈÓ#ö²Žžg¾ñæÎÛŒÿð¯þ'ßþŸßÿC? «95Y£Ýš&Ͱ¬ðüþüá·ßùoþk_çj[€+ó‘{¿ÔyuÐW{›�^oÄÞ$«Ÿ~çC}æ°sÆæ¦§‡u×µ_rÈSx¹ˆhoÊÇq¾ ·ƒMì‡ðD¤)ÜÎß IÜ!²^8Ðä=S4dN¾\ÛäÚÇZ±Ý;ˆ¸í—?ÄÝÇ\5û^0tErì ^/X7÷ä•otÅ)£'y³N ¬‰óšŽÃêÒš°ù¥‚5[kôzÊüíŽØ¿e'¹#ÚúÍÓ6îoËÙg¿ š÷½Á2N] Þ/æÌ5~ê`<�V³F¬“kq¬½ì ’è^�¹A’;Zø«Éü5Mu¥t08Í4çÙw¦*Ôö,×ýÓ͸dzö+F<Û¯ Hä'§ýNŸsSsäÆÒ} ùsöfÞÄa÷'Ö$ï[³Ícb‹0=µfãÊ‹Vÿà"6csÀf’œÐH}~‘J\ò·Ía‚7d 5P?qŠÅ§VN<>æš³ï±á—ltÀÉZNüå‹Õ¹\±±×ð�U†9&¨–àïó< ßÛæ8ÜÄ ïÉ=οéÆz ä^mí¾^kÖdôè‹¿Ùñ{Ç>ñÄ!`—ÅaÚ $;?¸IÇc ÉšÍóC}»t‹kñY‡È4¤ËÄÇ+)1¼Ê©¹‰nãÔ(÷Ípw¡ñf dH‡é=¡¦ñÁŽEžåBÛ¨¾¡c;Ü“bµ@µóFܧ.q1a…oïÄÉ/«'®Óã_p©5þ7ÿÖòrÃ¥½<�»=Ô?u–[E GóÑïÎË׃Qš ?3¥Ì¡'µŽ®ö¨œ<m�n.¥$‹û=yFëj©†ðÛ§=W¥®Æ­qù9cÃÏ(Öi×5×�Ô»„¹ìq=}CÏjXûa›`N§Çé‹kä€ï¤úî^k’ÜåÊÔᓇÕehI¬—8‚m_fq'zðFl/næÄÇÚyÎO½˜Èí9¬HÎutGLƪMsþ¹¢?óÿÙ¿¢À�Ú˜$1h’œp0Ö¾çZÔNÈ?ü`a§y,ví¿)Ïú7_Ög#¿ÆÌÚ?¹OJ^$)!'êÛ&8G£ÎÖŽm/¼L;F³¾µålã=úzÉ%çÍUf�2š°©éé ܃„Ä7‰¾ÉZkl[Çá~'ËÛâЗ[kÇ|r±È ÿ«ÁØØ÷ÆŠà§üu3€©çÇpð‰Í¹òjÁº|{·,kóœ@Î?æÛ}ÛÓâŸ\I´öOk¯ž¹öWË-ˆ=Ûüäno$D]`š/6 «^+mù‚_ˆ¸§gXúÓ>vèÂæmø°–·±õ ‹7óÚ¸¸Õû•ëÀV7ýå6Z·§âý|HýI>´0x»5ŸÞ#�\ÛL¿öMòØ—ìº�C¸9æ�.~´Û þéi6]í¸âgÀÙàǤ=Ò�bª 0»Ô²`}‰Ý¿ZñуÉsújŽÙoD�4g5�.ó®F““¡C]g…ÞÏÇF‘p®æÙ�¸WuéÝ&´Îrmnò±ß¼Xî—¾p¾�|Y` ±}Ž*¿ºXWRˆ±ö`°C„Þû؃õÖE ˆëã»õKZ¨µdýö–[·kø¾àI±3çæ˜ç�„�^ø%M~àÏã»úøÀýíÛïüõßùöþ¿ôíÏÿóÿì·ògœ×¬‰zOî›ùÃ�žü½?úûþ{ÿê¿ö¯ûÿÝß��¬<.ý2%˜­ÅÒÇÜ‹�™®ròÈL ÏAï~‹/RÌâo …¢çÖÉ_ÿÃÿø7ó^àùöÿâ¿òígóž &®œhTâ/¿1ø—ÿíçÛ_ÿoÿ›ù£œýr¨Î+·{޾ PùÔ¡öÕ{lÝ5úáoÃ$'iÁòAÙ<„Ÿ IDATëÀÉ•7Ñ °ôëì¸ê:þƵx{¼DAüÀ^~Ó‹ÇO«cøa&GnäP*p#r ¸ŒÝÃÝÓ@Å{–¿8ÖŽ*Ÿì;†qgrsöùÙÏ~kþÚkµ&ÆÜ‡·¯MýðŠ¹µ°4ÝÄžõ@GJiÛØÄÉ—ˆœýr®ÝW«‘~ŒÎÜó…š{;°öºÒ «"{§±Ë-$Þ�O?8¬ ÍT�Úr@·ùRÒ¿B,€}mã6Çò „ð%Åþ®»ÐVϧß×}¼˜“Gi9·7ØpVöî¯á<Y]°ÌÑ®N±íÁ~)üö®£uçæ6P`˜¨têi_õ 3>½ ­v±ó[‰}ŸÁ?c�� ßz`n|«½æHlnÀ¤>æ8–ÛádQ|«ÙsH¸õKpÍÙçÊ&°çuMì�$ÿɃ¾Éɹzçü~É÷§PU' u˜Ä÷ŒßýŽ›ëò7�r€ŸMú„ŽÙwojž/°±µ®iîH{‘äÙ}«F^c›çß˼5ÕÚyeb:ôL^÷ŽEÝÅŒo9­ÑEqL_~訳×WzIÞ/p�__rá›.4RM`æîùĂõ}ɪ1ÚK¼:Y{žçÖ®KƾÀµµµ£6³ž<ë;0y!ˆGžgy~uãÃ'  ­±1µXMyrÞ³ùE8•”g˘�5k8—wÏå¾�W±‹#„9/?øžÔÖ,+îì7Ì»uÚ‚2àïL#Èþ enŸü«Wøê&Z_sn6IÇ/&�ûÞ÷py÷4Ï'Æ–7fºv”;+päf“Y>×ñÝ(!b°¶Ì*@踗ër?G”ûGøƒ}÷Ê h!~Ã7ï –§“¯Ê´fsZË!ˆY=C›�–‰iž‰Ñ½ékïßèµb³øP5ÜOÏ Xüsþð[°Ìöü>ùœ—5�É…yÓÇF#ó¾ô·ÿÌ?úW\ÄÉ8ÍtÛ×"X¯¯³.sÜ7<5ïƒ�Mɾq™CÀä_Á5‘Ÿ#Ê*Q.ãÃsð×Y®§ž%YHùz„Ç'ñ,Ñ(ßÍ“ú„îE‚ß‘™‰¿%·Èå7QØøá<0Ÿ©‘/'>.nßÔæã; –¯$…žã‰YxÌMàhb²º°ÍúÈe2ƒŠ¦*y~šwÄîÅ(7û]–�36:¾lM™Õ›0y�»'Ú 5nÄ‘ïí]ãð�oߨñ×XZè¤Ìê3ºLK)7µ©9ÈoÎõ…/wä�HÇçµo Øa±í~C°R{uBÛćwr­žÕ÷�_̨hŽå™3‹ËyŸH¶ÿ„ªWŽXySäÁæCÑâ›bUVïÖùbÌJNåÂ^ì:çYßܱ“»×ÃÌ¡:ýÞðØèeßÝýÆÝ-éqõ•ø¤Lìp.qIâ‹�Ü82™ñj<±â8,¨çƒÕ_�Äð…ÉŽƒÙž¼kk Ã_À‰“[î‹_ò=/g0�+áÙÁñn/ùâdÞ\„´1ÄRCSyît³x†ó¤O-{Dæä_yú\ñÖ°\œ÷š_rã~™C ºnF4g6¹ö ru0ш76×Aik7Ö)ÞWSƒäÀ?¹øÃ1æ>WÆþ÷ó%Þù_ýß~÷ÿúýoÿò¿ø/|ûùÏé_çýÃ?ü£o{ÿƒ?ü{cë™ÿå÷oý­ÿýÛ¿ÿüÇßþÚ_ýkßþøç?÷Ýx P·)*Ñê�j\æ8¹µÄæoÐà‹77ÞðføW,S-•´Í÷Lï¬ã²F¾˜û�|™÷¿üÏ+?|ûÛÿÇïæþ~ûÝ¿ów¿ýÝÿû÷¾ýÞïý¾¿!øûðGß~÷wÿη÷ßû�¾ýgÿùú�¿âù“ü¿ÊFWë˜ì9EcrûxLÆþÖNs«“ƒÅTy5µnæì`ãã÷‡X¶ý€Ï~¡B¬Xøã9\¢¦Wî/¸@ú.ÂÛç¡ý¦ѓNïY×D`¹1`3_¦«¯Zk*A�–€3ïqú…Eu¹ñâ ž7Ð|ùÌsöœçø*’˜0s�[³ëz«qpš*C�« ¼ù!W.üÜØ]êšÅœ| G[®+¤È‘x9·/:ÈÃ{§%SQqMl°¯eÄçFMü4b×M²8%bÊè㬿9Gœ#\~xÈ‚ýöù²7ÇBÅ�/¹ÐüJÍr{<ð®}\‚­fŽNáhªjoOúÁ°…´âÓ_¿‰j`µ� œ_xBܦˆïä$ñÄyfÉû�YˆKaéE¯•¬ùɽk(!Uå@wR/uðÚžyÃ*OW2X,Áž±¦ä!~õÖëD.ÃêÝ,ÛÃÖRFu$àøö¿KXÇšübõ_·ËщŸÛj3q�l¼ØX¦}�¼yˆ o“&P,ó8èsz¿\;M9�‘jœ~C0èè[®·½b<˜ è‡Ë88a}Ìáô·a“{ŸÏ_Œ¤�–“$ø6 KæÁÈ—Iy9/ºr©ccu[]98 Åe¹àãÆçßg@¤&2³�úœ¯Ï%]@reo°å~qaá9 ”‡ÂY,¦ø:µ)‡Ï:ÎÍ+š=°—±NÄBâúæ1gÒðÜî™<«§ «ë•‘?¼;?ºÄÙ—œÛÄžç¶ŸÁ…/×Ô&gpzŸL¬ß¼Ìw,žµ9Fs%÷cxך™Çxzùj<8j�2’>�ú�;kæ¬_(ü«v%|år=A`wââ[_ãg?ïÔ£ªFëâ1.ŸÂ½îÞ˜©Zƾ†\P÷âØâ÷|ÝYòÞ»½Äí˜Å¶ûf½£ÓØ*7î'öÏýÓäû›ëÎ93^µäÈ×-Ÿ ù“&^øÁØ›¸ñ~€xóþ‰~²k6l‰Ù?qÛb«3ÞøÅÿæÖGüðýt>`üIþdž's›™ùƒ¿›°šñ)5çà2SËÑûÆ zÅ×°˜—:éåÑÉ¿‰´l»ÁbŽ•ÕÕ1•ÛæÐÀáéžlÿð�ì§£~A9ÿ�ßà�…êmÙçéåÄ õÇi÷âkM7× oÂ+}lgŠÝzÞ3öÛ¯øMŒì÷×Ü<ÈÕL&6³û_;>˜övXžà[oœøŸ±×5�1ø‚ûÄÇð¦÷§?ð›¹&ÓB�„j{¶uîLÌ9}¯¾�ÿH~|Ë#í`¾�oÎæø‰¿©ÄüW\—¡>ãÑ…mù¿j”Ÿn’8¶=.Ÿƒå_ «ï#hìØ(ƒ'qö�¾é�xú씃yÛƒqÇøŒ5>þLåûá̳q“[öû‡ì7BØó¶ÇçøÌ1ñ�ÐØ½N‰«@ÀZo«²{ñ7ž™—C&?É^úùÙËöfGpïcàU¹×A;ÏóB¼æ'rr’¬ÓÂÊúq$®9bïÕãu´Ï•¿Jy|ûÏ8:&O?,õ·:vrXüZIW}͈Ä!ç4µóZÖ¦ÅdóÙbA{âñý33ŒýF§_Ò乓çÐßþ­ßþöýv¯‡�á¯ø./oH~ö3~Cø'ß~þÇœ/kààZçÍ>ÿ‘A¿�°†ÉoâÌWÏ=SÛcw²å7ר%Ÿƒà¡¬Ü¨�2–+ÏY8fjДè~õ«>–ñÙCò„ºÑΗO¿øùß��¿þ÷˼~÷O‰)îüOò‰áõžlŽþŒçÊôðù”±úàQ‡ÖÑKÊ tøW&s&7:ᥦ[ UiqL‚Ó½ß÷³·Ã_àà³8¯;¿ê¿k�u„Ëž†�çö¥±šK ÇìöŒšÑØpÔž¾÷C •Ð/oÑÑkë§ß~+×Þ/~ñs_ûz}ïf&ÈCÙþÀm2¥U`M#?yéSâ�®ˆàèa)X9¨&âz˜z'Ÿ½Ìü—¿üyŽÕР“̼ÈCmüærn\#°Ó�­áì�Z zŠ)Ok‰ÕtŸÏæð±gzsüÖoÿ6™úïXæñê˜Ò–wßk’/¢ŠÉ‘ë²ûq5œ¾Ä¿ïk�!6£Çâ¿öD}Ô܆œëŽçrã3ï1xŒó¼²šà¿g“L¢Ý;%çð�ÙZ"¨]¤ SÛ×úÓ³ý²�Üé³·œ÷ý8ωع.¡¨®[óцo8<ëàœk"ç•¢‹¦•ðØ­eqÀãÆÐ7«…ìuÁ—”\—<ŸÛ¹mŸNŽÒäx;“4É‚6'IGÛòØ›ùLƒ0ÞÏÖ½:�ÖÕW_ߣ“ß×ðÉ…,zÔARƬÁ$gý§ˆ'Æ>-ÅÆn¢9ÐÁ­þæ¹}Í,æó\é{t®AC�~d�Á™v߇£€ïì»™ •…oÜqf‚Î>§ÿz;¯÷c~4ÕÚÜŠ\9=ãóG|Ƭ3˜—ãø~C,Ÿ#âgÇL6ut1õ±4ûyœXÓ“î Ñ×CÐîW·ÿ>¶¼.¨—Üå(Æ~ê|®ÿùlËžsMò<ô›®/Cç7-31ßÚN†©mñoHc·¯^y«-ç³ßÉ‹Ný9(c$Ôö©gkÁ·°íûŽF~Æã;o²�ñüI‰^f™ÐGFßWîfh²SŸ·éÄ‚z{0) ~ãÖ.–×½8O¿áȽ˜>/}­×Ïd|Ž˜÷¾ÇŸÀS‹Y‡kûõøÇýq"'¹wìuʺ×ɪü¬»5¯îj&æg?ûíôƒ?À»ÿNô×àvl>ëáζQlÜž7æxΞSÜÛcÆÎ{fþæåöðÎØíK™\eº´ÞX¹ÀŒ~56šäÇ‹ñ+b5̓œ…£Éh†½ÈùñgÞ�ÇDÓ{Ö5þÕòƼÿ%=0ñj_~ÓL¾B>òÂç¦WWO_�Ñã€3ÃãòÚeÍõM-òòf/¼»ÑœËþ ‘RÉ^"fľ9ÇÛ7ª}s(§öíéÍ�ùQ<¨Úì“€Ùß46Tß>Ük@4ñAbz@¿ÍÓd\žÂìA<[óPçÔú�o|‹ã¼oæï47+¡Ÿzëu¶:EÑl'Ý÷Ѻ¹aÚaýãÇæu²y{ù८á_’�KM¶-ëÖÖfíµg®`|˜gtÉܰ8ß'&îÕfz�>|»š‹ÅG\n‹Ãûò|¬õ•“ü¿æÿx×F¼Sùf¦T¸*½¹FþÉ·µ¿ô8ÉTîÌÍù¬7Ïr´§±n“›Ú\ê ¹5_~9–s û,„1É o€šbØ|[Ü9î9…Í~O(–Ÿ¤—ÛSRpç1^Ý 2ŒÍ'§sÎ^¼/0•ÄpŠf¾Üw¿±�ožk˜ïºxu5¬¸`D) „ðÉ„ãY]#è��akÇÑ ‘“74ó�ãð4¾Ékh*�¥UÓ#ê™ÒNÊõÅþ]œPì+¸‰ƒi7—(m±çu úWÜô+¯¢[W÷Q<¯÷K@âþø�ÿ(¿Í÷ÇÚ©·_P²ÌœúéîM‹¤Øö˸¶O­u4OÀ1šÿžÇ˜“…�)iªìr‹öšåË?ò¸„ârÝ¿Æ×زôÚ q¿˜âƒ>¿í÷ ÞžáL«¾Öwj¥/•`>|úÓ¬']\[Äù!:è½ÃÇcÏrVîÜÊË.ãf±w΢�Y$ñå 5 .<¬_<,¤ÁÈÃn+ÀN(é(  >¡  u"xN>h!WzÉó3 ¦¾Õë_óÚ�&|û5/ã QDé …7ƒ/DI^z:¶3iŠÛ�᱆ØÐÔ99¨?Äí)úüÑv$‘Q“1àÂmݱ1ñ>G=b¾Äõ‹ê°Ç £*Cïì»A9Ø‹˜¡ãol^ü^+`Α–¤¿pïsðæ(Æ(Ñ쿺söqãs-i°v(çY—\Iy´lˆ2šé¼Oí0ºç�bÛ‘9õ“M^§ñ�å¯ÙZ!‰ó5Þpr¤ÿ\K½$ˆ^rÖÏ’| øóÁÎ\,©{®K ¬û9×Å䄉Á5l ëpmŸ–ŸÔfµi Т56bÏ<Ñ«.çëŸ|­!„M<8ט}U¼>Žp—~òEò±m8ÈæhŸ$\ MmBÍ@yتeêê{ýƒÙøL~š¹ýXã“û¤ª®S ÑñÝ?è ·<×äj��ÞÑžï&Ý–Ð|¡(wâ&wóµ–}ÿÚ °ƒƒ¬¥4~È墖¸…€·k@ó„b2§“ÁìþͳfŸ‰Ó¿¤û¼œ�ÆÅsAöYúÎõÉÄmn4ï5¹9Þs{Zaå.‡ÜC÷õ=ñÛ�c¸sn�òtñÕþÑ7ú™Ä·K@ÝÕè†Ìôd‹�ÛÖ¹²´ §}¡w zéczã™3ÈéDÉOØð�-w"ÏucÔðÝ@O<�¦8š�ö}m}«(ãÄ­Øå ùöõô)¾B«õpÓ·0ò.Þ|d¬ NyÇF5AîÌÿ³y­ˆë¼Î0/6 #{21ö™°o-±ƒ]ÀÑU쵩1˜å'áÖ Š¼’Tý볯›³B2¶«3±ä€‡:Y2gJŒ¬ûþ#F–¹´sl`ä–Â.ˆžXðÆó´ºæ™x sP#ØØ’INž¾Ç2ø†ˆ}û½Ü“û"‡.Xô<ö�ª•Åpj�F/±œ ŠÏ×%×½Va›¥I_nKx8›#ÇüüÌÅFr>ó¼Ñ͈�¤ñIŒ8†Áœ;éf¶°}ƒ�bÅ�ß8¦¬3<ßµ6qÓP ä%ÿ…LÎÇðpkEòÉr¥â;uLø¦ß‹iÌŠ+vÕnÚ»ËÊÚ™£“7†è�8gÑØ©€"tiͶÁ3õM÷ØuÁ)HXgÄyìvh`ëq=¹º§¯œ.dK®mÈX«${`˜Hy¯…S/luOdq0=9®3éÞ6öݳ`ÞÖ°çªòÚ½o½ i�öD‘"<7¼šØ›4xs/Ï>Ú�P�ýCŽ1!AÔ µ€Šž×òUŽù¦jäyÛ~âѽ\#ª¸üjœûrª)1SédРҷg„2¬‘IS»õ,澩çMú`lj^2¦ð ]M}â|û»¾�³ Cnÿ`ËFHo/Èñè�˜I�ýBÜ`�E0Ïå±—TuÂE,ãö¼ëí_Ws ÉiÀØ/q r &àh2_,#1Ë­mÃÈZAêÙ7¦¨�˜jhæÄ28­�~ph¦Ú6ÏŲb4'h·ÜIpz·×Á2m�ÅXÝÆÔ¾´”^ÓÖLIœ]v¿T›{ C‚íÔ·á¬O?Á‹!&ö‰©fBãŸüÜø€ÇF©“unËµ×ØÀ:£,Ä&Q_¾m¡xÊCf|Ù KYñÜŸ!ÿ¯ûWÁý¢ëOÂ6%2ñM}‘áçgþ”¾<¿…ÎA¾ÖF-Ѿ�£œ7f 9m}k±×çF9pÓ“”ß:1„ ¼o¸b™6¿I‰;Øúì‡éPÕÏ$QVB~¸ï!´å·^zKl†ö]C³_Ú&aÁwÀ·Ç&H ¼û½1íá¤* ¬·/ÕÒÞú¡¶©�|g$ÕùØmnò÷‹Va«'±ûz[žíáèUB¿´´Vð-Ê:íJ^ëè!7\[¿p�‰Ïœ¼ÜW?gµl99çK$Üà:§ \Ý #ùá4OœF±9ä&<�I2[çæØ0µp}ó†‰sï‡ûÓÝ^ˆ{FsŒhøó.ÉËcK^4&¡©‰¥$6UfN�z’ûOòm &AéGë[\ó´‡Ö÷~hw ÁðÂÔšsæù ê4éÌEttKùúgôè>¿qœ/ìø·]‘/à/_ò¡œ>¢–÷~hñ˼ä;¼ØÈ?qìû¯~’=RS?C@ Ø;̱Ïw}O±ûÐsÁvÐò˜5·{ _,9óž\\WäÕ‰†£™Ùè~%�=�ËÕºç±ßj؃ð®'bNÜ|ùìo4Åï…Êhé�Ço77¦LÍüêîs~ù{}4Ô|^ wm”M Ïì…‰3ïëÄêÌþÍ�MþU^sZ�ÔSÄr¯|s}´c¦®¦›Åæ¢ÐìéMì�/îêä¹é'yÜì8è㧺Ú6¢bšüÌÞ±©`,·Ä>1™nä~ïƒ; ÖZ/\üÇCØæ ßðæ4­QØ;N•ä êL i\<ä’5‡½@Hsz�Âóð­c›à#Eë¡®›¯Ê^m‰†wn ý¬”¼††åÈ4ƒõzÁ·ÎX}.á°#Óõ‘ÉxÎ ‘sÀÊÁ0œ j˜1êyâ?Ö -ÙÌ«?¬í'î,ò³Ú»_˜0òCB&uÀ³ï×ä^íÿE�Þ<»h˜ÌÞÞ�kóÊÀ;ájì ë$ëI0çîÇU´œ²]³uóDÜ:F÷¬B84F…?705¡sôñʬíÄ–l5XKžà’œs —£è‚ŽÏ�çqöµ6´Ú‡9cÕ �ºªÑê)F�xa Vªà�„αR÷œ·ŽÝ§ÊnQÔ¢'Ä&Ÿg¼;÷ é÷㲌½j˜/5«hÒ Ù ¿Ã)�{Æ›¹™î±Eµ¹ä à%ÒÝh–ÌÍ;tB›Ù—Øåo|ÞAª¶yλº sM>¤­xa#Ý~éa  p›m5?�wìLÔ­è~åÍÇríÙØ=¼ºÖô›ÎU¹:©eÔN~VZ\¬\S÷öeù‹éq˜N¯lÒ!ÉdhÝ~R-·¾oï\›ï¨Ûtç ír,/6RÏ„h1é9çöhUÆ¯ŽžÑJCŽÇ‡¹µç "Fˆ'—g|›“øåÜÜ›ß;´Ç€œWÓÁ¬�|�å\±*™àF¬�ü§'‡Œð‰Ûæßz1Ÿùæ®Ñˆ�j" w°˜>s|ò-Vħ†y츶u¾¡r¾††}hĽ׊¼²T/ñOépî0gýjØ:ËԨϾžH!}nùŒ2 ©D}„ÄÒ¹û<ˆEÞ³�íõßÇÒy„'¾·lé4£§�äÙêܼUU-ÎMðô"áê†ozt+•wŽ[ŸÏãRÆ’3Sr2G¸“_{#‹é\Äróˈåa Ù4:áÊ�…³áÆ­P†=±—Æñ�Ý? âœfý¢*7²ŽÃ;ÿÿ¾ž©j>ðÎYÃGmã#?_LÀqÆô6X¿xC+�¹Ó“} ÄFœº’Hë5Iˉ©jëMRݽ6ÿÄ„=~ñ„îå��ßLzungéUëÞdno¢woFK',øY]ÔŸ/+yÝ�êøÔ>g ö!\Ö “YÔG Ð3ê¨gâèÙ–ÇæˆÕü{]bG»#'fp t\Þþc\ûÌç†Áo²-‡ébÛkhßwØ{5'8aöC\zÃ_›®ÕgÍñ£úÕCó÷Ì´{áDIض{”=–‡ý�¡_L@3û8¹¦mÿftyÝ'–¼ÄœÁ;#X£¯«é‹ú�¨ùõ ‡ë›3dåw2ßžÀœ/‚À¿k°û8A¯\jÊ"ãÔ :³çôQCõ1¢¦?c¦&‚š…<ë ­,$;:–¹l¸àè¡::6XEÔyŽ­­õ™ùƒ„®¸PVÎáá´”Á\þÑD§ *Þ\…L=ƒ_X–æ3YXµWC÷f{Ø€úoý»&ýp"&?»¿.[PaÐåîãwqwMàÂÐ’uFO2Ë­18½âéYVчFñÅ`6c¤ÒI9\=û˜Ž¶&=û²û³õÃýa‹}q¬}³À‰úS ‹Á-kkÑËvì)O‹�§€êðk#èäšçœ!RW´¡—¬ê;1踘̈́šêì¬u‰�AíÃ�Ÿu—[Hm¬Þ>uëÄn_Ìï|cMRAéyýV�´»^ÝóÍ)}Ü\8ÑØŸœz«ÿÑžœs£Ű˜ IkÖ ñä‚~rÐçõeî‹øp -=+IšÕ„{?¤èxør£æLbg5YcGO�>uïüd«æšs,¿t€£{¯Þ8ˆ\nˆÙ¾mŒaY‘ƒÿÕ ý ò èƒ[î)§µlÌôƒ�êÃݼ¬‰ånµÛˆ‚9žaެ,cðÒ``prjBMf‚3÷ÖмÅ_Þ)ÜÁ«5T;ß4xù®61ÞYÀpå¼µ3Ãæ—CþöYðÆ#˜œœ¨Å…dÑI9’/,ZöF¨éðç¾ÚÜ“=s:àÎ¥­÷Î/q²�Ó“ºCB)=\ßÑŠü$8˜­*GA>߯Òýk¨àÊ�ÓÙ=œ8Æ IDATXÊä ?ãÚ☜õ¡~¸œ¡³\D’×^[¬R´2‘Ó;xªsÀq–kðå¶ùά0¨5î´“2fâ1pß�¯?ùb4ÿ¹�œRC#ŒgM ¯¿œ«z“ÕŽó<¾8¦~µ\èˆÂýËÔÖ‘eFt ɽomj‰^Îç¹H¬ƒâ¹g4V´×¼<œ&neí™ÚÁœõEK$O´-_….cÏ?%¨a”¡îpïs§>B7sFì».ƦÐâb°GÔ—öa¥ lkÓ¾Á=Ó+òmížI‘;¾»‡½þqX+™‡ê\³pa#ÞIæ!7‡SÃÛ~6ÀùðD~€ (6KÖ1W[1§¶âÕØ\Ë8±25馞�â{å�ƒû>ÀyS+>ês¨†¨tò©7fâpç¸ùêÈ1˜æ*¸¯#�·îI8Ÿó©‰ÚüQ¡X ;ëÛ‚y<@&a!*ÐážèêaÑ\Ì=¦ÑP;•¾Õð‡ºmvܳ漑�Q3½cÈÈbñ×zl¢äkÔ¸=-ÿö�jG‡ü“xì{S6XFF…{‹pQê:@ÃYÛñ5¹dþúº¦W'€ÑÖ�q]Ûé\¸OÖ=±¤½uµ°ê³šC°«9o¯–²*æÆ—“H{ çòú䃕gޏŒŸñYœdãÄ¢ 2™ñkÇ=þ hlœßq 1BhE¸Áãû‘â â´?N§rñc›µÇ©ó¡í©÷èšdÄéVWæ“ßß`“q8»üQÝ[ß‘Ò7zŽÒܱe‚oumŒ5*ŒÎõ+�8céWoÆ‘S¬™ù³–ÉwCK•#XYx3>¼: UX¼œs_}ô혰$?<Èn½N´‹ á�ߺ—X‡æ€Ç‘ÓÎouµ-ƒkÍ{Ó׋#§8C ’²Ò(¾y6FžšIvx–Ï€/bÎ�XRNŸ˜Û'Ïõ�pp$ɰŸ€w€ßÛ»_D´ù"™ž™µ6x]gNäR ‘š‹Ù7P#‚°Ñ&?¼a© îÞco  ?ctîäkŸÑ½µ4Eµ¢×½''cU®YŸØšÓ<ïÓÚý¢–Xn9›'‰½ ,øôK"®û€gÞÿ@aWÃ}ò{k7ÉÄv—iX£Çú?œ‡—ö‹æêŽ1Ž· ƒ•/slê�;øSKÖû!ö9ÀM€cžG˜¯i¦jÏ|kh¶�ìêä$~ÆCS¸ôpŒüÌ&’>˜�óáÕ0®�Æ×Bìèâì†kÒJЪÄg ñ3úÁ¥bàmzþP¤žŒ�±±�>¸ò×4´gÞ/iJº¥õ‹‡hÊýð�¾ÞQåÀ�¡&.áÎý|`_Ææ§G›—3TŸ˜Ó³áÞ\bètð�Ÿ¦¨TÇk§!ø>†ýâ¥y‰ÌˆÝ/bræ¹¥_<�‡^Öß+¥;¢N±ÔÓJ#˜ixØ”LL É¹yá„éÆ`²w—#îé¸Vâyœm­øÔ–/$¾M ¼Ú �ƒÚZ÷ôkbùÂÅ/³ßûŬç¯÷:§U»õ“¯u&I|{íù…–>ü�¦ì±×[Ζ AÆG-ö�½»|ëï—¬o û5ÓæÔQÛüõdRÑ3�Yýi-`b hŸÃDF§¦ n­ö€>èKzKeì|éÈ^ÆàZÚžr†Êžéu!‡yä ÷ˆÙnÃO ûÁd¿|1&–âŠÉ±#xjÛ=9=„l|kÛ/ý­ 6óCÓëÌ5©�áòÁÁÁoÿQ>b܇Ìí)}Ú‘©¹‚ñ\¶õž³×2+b$~û›ë—¿FÙ¾”“¸Û£É3ùèKÜ-"6ÒWGë%f{,R0àÚðŒa:g�¤õPí1lŸSr6ÿ„鮬Õß<©ÂÜ&à˜Ç¬}NÁÔÎ�Ü}Í��Qž¨{¶£ç]“�z ãyßžåL¯Ø‡¸zç”9Ø�eþŽ~Žn“´½\Í$ó¾‘'‹Ë^Scx,ô1!f¸áÝxâ£5åzh  íö¡)šsr›Ò‰bÖØgÍ»û3¶«¦@|[»çáDë­3Ø!¹ññRc~&%iÿôñpÈžøÍýÂ÷òNFó±þwu•ÉøÔòÞˆ—ûM¶äÔ ¿£�#r s¹W�EZǧAí˜|Ï<ýlìFA0‘/©æ`Ì AÕg6xgåE•þ±Q™ú?3±j àÚoU€%‹€ŒM1ËM‘bß<™ïûüõÁÏèsZþó¼m¾¬õ ñ?ÚpL1·ÑI¾þ:ŠÀqqê÷PŸ€9È’¨ÍeÕ?«Ÿ‡‡dÊÒä³\>š�7/{§“È8õêÏaê€osÅ:üåñb ¹òtæ0ÉNÌøqãbè[þšÂQe8yÅíë‹ìûBTž{Áïz³@ßf&$†þjÈúì?óç Ð^ŒVÙp mµDžžÙôó¯Na£éò„Å@gÓL_>y �¦¯ÆP ¹Í½ø»·¨~ûG�Ðâ6ËÓ£îQ1Ɔ»yr=h'Ïé+$ Nÿμ['ñÌ7‘9».ÇæJX°rO¬œR7ß"­ñá;ÜcÛ½Øøê~нD�w~Ž­û}¬€i¢Å+×…È!"^ÂN&��\^“ÿ#¹‹»ýt=r¦\ˆ'pG-}|­ñ%hќ닊ìÛÖ‹QûMàãu’ÌÞ¿ú7)×áiÆî½ùÀÊ+sù�’„I±õË`µþ=ëÐWÞÔðŽA=ä,Çç9Þ¡þŒ­|y«0Ç^{çš’¾ˆö£ºà9¥“wâQòÎY3–×®ˆRéVª<=Ï97µ`Nœ{æ‡ïbÌEm Û€QRFã±€Á”I¯­,ö ¥ÐòóiÔäj\²¨IWËN�1o“I$}¹šo‚'¥àH¾„Ÿ/º>«Yc= 3O óf'çRc:£¯‘ù‚ÌM_µí>W͆´ÞêËLþÚéôå ÌHÍ|²¼÷‹jÂ^XVÖ{W™MÑ_îи�€›÷&ðÓ/òlîÅ@nèÐŽ:ýĽºxÎî—€WGÎŽéKêò–Ïð|¨Þ>ñ¥z¼açZ$wnj�ÓÞ“§¾vÝ}H.2í{.¾¨³Îü¯ÊÖç—ˆÕ ÆÉ%Oýð•óÖ¡¦`ìiöеœ+Ć`'ñô’ü�£›E1Ë;ª±1×�f ÄúÞEÞņjÞç@°ÜÌŒârÿLV¬¢rÎÈ’¿®úKþݺìû»ºq/ÙÏÜ�fbCI/ÔmfédõŸyžY a¸åÀ§QôŒrL,Ý<°Ô�{?ˆQ«,ÐU{Œü”Œ�‰‹Ÿ±õ`?ú�jjŸLÄ‘»áA’µü¡g7àEÃ?DÈB‡�…*{òjúô'~j¦‹Í×zØóýb¾ì9.ÓØIl¹3·7ÔÀ—Ú¹®Áì—Tö#’öZÅǰ ‡ɱ·Òë•}®¬ÝAf?qÉÍc~uíù艇ñ¾oýXó[¤ùùåU¤µ‡Ã‹¢éHœ«îÚŠ%…µš«ZÀ¾šËOå«§g4�œ•ù�À~&>>Éø'yþ8Çö&ûô•¼Ã¾©'°š»'èb�3G‚ËSlmøn[§ù‡Æp��Ø£¼bү٠ʢƒŸá8½­ùé5ºN�ªXí¿Exâ.$3ôw¼±kã¼å×?׿×Üä=¶ Š­øÓÇ5\`zRÛ³$Û'®ººgFA” „›¤\x_¨–äÌôW;àõSGŸÜ¦Àƒ9"É—Ÿ/�'ô2N?Y&8i´ùøf=Ïg÷ó:QŸƒüå‰l{@LMó97Ižë*œzˆiÐr¼üº8ðúÛÐäjˆ¹c}ñkJ:Àhõz‚€;Äœ÷=Óæ�Ul¯kVÖ*YÖ«•H6 ·¶õ©³ª7Çö ]«oi>0É+)s/}kÅÖ5³õRªŒåÅ5ƒœçË6!Í^Ïóý²´¦òlüi¸†Ñpr›Ÿ¶eõ^�8eãP7B —Þ2:ѧ°rðžÊ?ؤ³NsPøcoBúâ5@¾Ô|ü£cJ°˜%'ùr;t«÷Í¡“ë+Š=y¸>ªeÌ,rÏk+v†C€¼3‡è® Ä6¤Ò€û‚UW`&ÎÑ3÷þ𠧼إËì õáš<;Qú¼¸á…<ŸPY©£6æ½ÍšFìÄÝ\Z=ÛJ„/ã<�]ahÌÀur>È8¼6¬ãØ Ì@'Óá‘,K¤¼nnnÀEÔ‡wˆžxù§W¥xã)ÛŒIs,‡ë¹î¥Ï›·ºoý͹„œƒå„qŠ;äiÿäŸ8zG öµ±‘º¨�õ½bLÍûx°=“Ó̶ è  ¼wâÍSçÕ`ˆ©ö:·}0OhªO}`«®ZÝO4ÿ5@ãu7;=ØøÎÊKÌ�óŒÙ‡á6ódR‡‘jÈ: ú¸©o²ªCœ_� $“‹ýäºï¿µT¸è×þÕõþf—ÔHÕÔ*¾×þÁb-ÆŠÈSœ VM‰Æ¶½†g?œRx¥æàš&æ뎬HJ.ϱê4²_Fuúô§½¢Þ÷þ¦JyCb\3-ÎZbG'­•ßàZýø|£+zè9R”îö�RZ ¶Õný‰Ãkê¾¾/fuûþ/ûHîå$Xã˜+E⬾hÁ­` K$q;àC—XjËPt¹ë�®3&t{á—½øÇ¾Ï¹Ø©ûf: Nˆ'/£G2åöh«xôöñ¾½ ^± ö12,ì—Óœ­)¸)ËÇù:>s‘›|pª;Aœ�£)´`ÊÙªxxrƒÉ�¿•–!þVZþʧþÓ¿ò�Ÿ*Ô£VCs˜a:c¶3멆!—˜bÈ£€Ødʲ¶�¥Û¹wí€ø¹öýÂŒ(ûe’€å¯Öö¿±þ»qó<½_¶%Ñ'žþ%~óAªl4 KC¡_�ö)9yM»YÖ®Ž�lÜɱqÉÛߢ Çh IÁbë­~\®½xÆ7Ó2‡œöòL�SÜ@Õ°ÚV«ý ÏÑ1`z ÆúÌ4¹âÇŽŸës�²ÞLJ>âP Ç]·6=ÅÝÕzI±Öhì%�y1äøš KHä‘È„ŠmžÕHx5“w^L‚þ~Ì,k A{? r·_d ˜þ-^·u�XB¬Ãyk^üŠè¾6&§¸N}Â{ÛdËÍE|9 ÉŒÚwnÞÃ" "ÉrÆvŒÄ¸[a«ÕÜæÍ!0(–sõÏð`‰}îœàùîK ïsz¥|å‚'#f<\¯^ðp#ŽÖÜâ=ˆûÝ0®�ÝÿÐ oùž &׿kÝ—±u‘cžlb¯£™¼2È“¹ºÚ¬K638_]*%>C8“/7ô,þk­†ðh`ãvG[àZ3¼ü¡ÁE”{òœ>Ä/çƒ+ïô ïS°ò‡û®Ñ>Ë·E‚²×Ó#øN}µ~ñÃñc'û¹4ŽFê‹m5|ôfÈxí½#È^@Ïè-ß ˜f?'ô‚³>öǾL—f¾üÕ.þ­c ‡ÚŒgR–}߸u¿ƒü>‡;^ïc[üµ÷½þÙƒàIÉ~2ئͥrèÉ�9€ŒóW€7�ÖYœóslñ·qc»�; ü²¶ÈDC3œkRk}k&sî|„Ï2§z[öµ¶뽺QDeDQ£º²ªÖa!Gî›Wüæ¥y¤Ù3SÖ3x“³Ã‡epðÒLMo·¾p.÷‰»um®;£Ä­. û^}wgnäîËö¨{‘ê·v(ßû²áô‹rи¸õÍÙÌMŸ®Líƒu…>x¸åìÞHŠôa}jXz|§ðCý拹5mdרÁ’áö«B¿rœÈ¸íÓ䮆¬«µ\X½—Îpq³¾Øâíu88Ÿh0¤F}™ïY2°¯ÍüóÅЉ»ÜÖóh�Ã¥<Ã×Ǿ•ßi­Û¬±b�m§w ›D»^›š�#<üNÉèðZtB[?×Gà‡.“ðœ�Ýus éüía -9AƒÁ¶{Å^8ÞÎzü9ÕÄzœÉjÙÜðç,õòŸùö®×µ~¼5”c¯%Rìœ4Õ±‹ætzm]ö¹ñ ÏQAÞžÀ¿ù[]0MVü]´‡¬¡a/õ�r0Ý=zÌÀÎó)Üñ{z‰nôwx­;8hÚƒfÃà sû (wÆž‡ Ü;ˆ%äàœjUzs%†;ídù`)v)Y-±û… s>8á<>Öê‹o¾˜i_à/üÄœØLÈ£¸\L@5÷ÚÚ/LÌEÙ#Œ_¬c;Òsÿp‰Ô_¾¤Ÿv�¾)/ßô©÷ �i�ú˜·îží<ν 怿9;_úá_ÝÌY[[‹œÉ ¬p‘}¿är]~'š÷†� ¯ï=Ë>êâu✼çÄ—ðw¿üH~s£ýæÛ?ÝU#_HG¾ÀÌm¯gÌîɤÆ.–¼ç ¿ÌÙ"¿$Ž®C?¤eÞZó…X´¡cô=âÌàì~s�Å´vô5ÁÓ³‹—#~ðw”›µù'·««!•PÏô¸ªÚÖÚë_þ¯6ž“õ±©åôiˆšÏÔ˸&[U(K,ùçË]�î#õÓ;ÜH�Ãë+õÔŸZäïo­ùå)µŽêuOÈÓTGÃ~ÁNŽüäÞžÁ·Ü'903Œ‹ÆèTS~ûÖzbG³_N•¸‘GÓ­qHü+Þjg�‡;$Æ-ç^ pÛqôˆ„£/çݯ7޽AÊ2kÏÃUÞòPÇæ!ž<ë7(ùËÖzƒé0C¦èVÐØcYÌꌧ²áç1F¶Ù+¯'ôå1ä5SF{ã¤kwî—¦ü;�çÀŒsg½u��\õ—ì\ËCëô¬Ñ5:sßzìk [sŽì{µÁrlj³Ã7öæïnT­m6'NbUÏ: î_oæôÞ/Üå7�+ž°¢åŒ�bC¦RƒÙ3t^#ÆÐ ¿{þY;>,sƒsn„‘sÂ!Êýêq‘¹Åä &Aƒ5¾óú>#™V8æ�gºý›”M°¡Ò5jWº‹°à“¬¶¸ZuÑßÿ�TKucW§߸úÍÏtà„n¤¸¬¶žÌL³1¬Õ�˜“C‡Ö°1ÇüÚɲÌM®�­·×õ’ó¬5$pcǽKùq#œû ´Ë›3æÎã<�£17ë<ö`È™õñaàg¸s`!¿8Ãb­�31KMžêÄ%‰¤ö|a”wrÆÁzñÔ³œœ±¯o9Ú·]IL†‡ésÓ Ú÷†c~\ú94Çf>æÁ7Ìj¿ˆ§k Ü~Ê›ÃÔ»îÖµ«Ï³ H7Rè?£ö8ìU iÂæX¬yäµWÅß5Š8ØÊwp5µÖý2Ó½ ÏñïA&ø‡ò`Õ<{ºº9ïëɤ{i,a{;Œ?WÃó÷E)Ξ ®h*lÄŸf<Å,”¤TÐB37o–SÍ ph›@2Êûø—ómš¶`ĺ¸U�&š•z‚c}c–{ÇLJñc¿§€áøZö~˜;PHO²É0uÌÉ|-¨)ÿÓ³¯É–:´Ö¶ç±O¶K:y·þ2…mG/–¬WwÎøÅlOåŠLæ÷R¥'³‚bñÃ÷Ún‚7½ÓYl½1 lÈî©ÚGï©…xà'¤€Ý}T¾zN £�³†óÃZêøÈ�ˆÍ5Z·ÞYó„iÌà˜wM_ž510ÄÃøqÒ“çVSIÿæ@ýtù¼yk=G¤G�¹¡O¸“GÜØ¼—Wð3N]ÀHè�.«£ææš4æ¶Þ'lkD£}AJ²,ÁñÅ^@ÎNš÷è‹Í‡Á´þ‰~ÆCîØ™4põÕ[~Õ”ˆ�ÃÏúæ^.ü€‰ &÷ÞÚˆÅ�§µWî‹÷g$V-œc~9–·h=ˆV˜z3°‡[Ç“‚ºÔ”¥æ€­½�£y7Ïöaù�§?"KÔøMôê‹;ø}1mŸÌ<)ÞùÍ-_vˆCîݦZ7™çúÊ¥ÿ©‹¿Ú�‰®ÏFZ·_„`?È©ÞpÕN£ˆÛ¼d÷7óEÿkç~`®f»ûôôÊœ2ª—ã”áëÓGIÉåàÑÇ@:ìþ¦ ³©Ú¼ùaµ=¢'jí®±¥ûE�ÜØâ,_ÏrM>ôxÞ/Â\QsÚ?,X3Úv}ŠŸhý²„/r#ïö]ܵ%nu’›7T¥²ßØé“y“ d4.³üпrW§ÜÉÓÅÌYÆa��s°;ž±ÃéYäFã7èÌÛ_̱öG¦£�øMm­O‚¤ÓÞÏ„ÇýK̹&H¯¶‡ËÉ=kŠÆÕ²5°¦ï«sûHehÅÇæÄnµ1rKoFãðq'ÏÞŠ£ù~¹.®yè ××lk>Þö1Ç5©$Í<̾oE4©gXC¥DCk³^R#Ÿ;x’ÿýŸcÍ‘XìÖOÈ|)=vω­žë –áµ,O9ïsâ>ÿ°Þ½õš@§×ôð夆±“ÖÇ%ºå­vríž/¾�#xÀ/×ì§¥ȈŸq84¤;èËͽçù1�¡óÜÔ��Y"÷:±ÄYÉ䯞vì,ç›ÀžšÛšÐ�ÑëtŸƒÃnC&†Äpïhœ“'}ã/–kd|µø]Za@S•õÖÖë ׃çÔÞÁ£…ç9ºÆÝ»Ý2÷6kuÇõìÚì‘Ôíoc0P+÷;C¢'¾Íh{Îã|bI§v“€�PÛ›BÎã6sãb“ªý§? û”ó©yéõN-…‚ NE4°Ó#~–H4·ç5r&IH'{2ëµal^#ˆÈ>ùX7÷î’Þ§¾Y ­Õn=ué?pøsß½]=ÚÝklHr…mÂɳkœ“þ½7):ylw¨uV§GqÙSι¹�«7+|ë‡å`ÞùIãÆF‹`KÐÇxø(‡&P 5µ!]°F <²Ô¦Y»Z‹R÷Ñùàân<“â‚9µ!¡Í‘§°us¬¼Úe�t2ÊÑ_/Ì\1Xu�õÁÃZ¾ö‡ªÉᘓ½Ødü®6B†º±sÄF~©r°§ø\@Ñ«÷ô¿°FÁ!OÑr•nÛ—9�}]ûjМƒu±XÒÍsìäÄ6¼ò|è]ÙÁÀ7º™Hi¢;>íákªj ޱgæäF–òÕ6½Ñ�]Fñ0°þ™T" ¢CíOdæ>¾7© ²-–y/©?þ Â+˜ 3�ˆpNÈ¥•Ã]¯ ñ3·•‰ÝÂßøæHÔËé¿Ñ|ÊÊÔåÌÁÃc–Á9ßCÐÉy.¾ŸX¹úDL®~±Ij>6×§’Ɔ?Îý·~&>zÚM.4¯àæ/ã=Jƒ®Ü|sìŒ=wuëú°¯öSßĤÄ9þrAž<Mþø>x˜L:û(Ú«àÒ��) w<þÓ×`xCÊZxÂ*àDÃ…�?AŒþ¹FE-À¸Ö]ìzÔ2díQýˆm¢Æy9Ï8}åß옔ƽ(VçYÈü’…ƒ7Ÿ|бæ¨j¦hT'‹ð¬öúЋß&cKî<%òeHA‰×�õŒ`èº1197\GÃF/høÒ ™ûá šÕ¨ ‰± 40f�ÎÓwmý ‡½ûoA34ñ#†SòI;ùx}âÂQþy IDAT}Ÿ# mÈ5'tö˜øÑ�žònÎR";ƒ¶Œ“7óí»Q[ÛÔ@ ûêjÏQ)›cáAè)ŒYk#~Q ú‹-׽ܴ Ã~¨Ô˜¦*�_,#^¸åŸ žrˆÈ­Ëk¦DI¾×O‰Ìx¯…ÑœëØ¼dPW+#Ë~nM›£_†ôÚ‡™œF%àè‰øùk£0p KÚDç½Ï!^£q7QC�_ºÀǨ³ÞÍÕÇIõ[#IŸÑç'|ˆ«>¿, îÏä2vk°éÉ6<øœÏ¬&xåN®v©gõÎ^]?²¨#cxW}eÀe­pçÖ/‰j<±ØúEßÔ¿!™g¥èiïö‹,¢À’Ø: Ȩ24Ÿ5%çÖÁõ†S„ÅæakbnÎùzÓ1îs$L›Ÿ}æË^RìðÊ q,žsiT£>z´šý·˜¢>XkÏZÙØ Ÿd{?5â1.ÿv"gÒmMhåÃÎØÚw_èmç!BYpä§�ÜÚáxö}i`p,Oó©vR8Ø2ú)KbuËXLøXð%ìLi¸ñÈ­?ˆÑ£®©Cmb„Ë©F)>Ñäºû‚í¹?tlÜäãËÀááÚd°œôY\.´çYăi¼>ì_ûÜed $Ôa�ðŒakÇIÛìÔ ®zØßþO×m<«•c„æt%ç1ÅCj“�c9÷yg”5÷be9ª�:о3«ÿæƒicš·¹×¶øhžÇ?µ³×bµ,>«Ô,Â×&–Å›ØgòÔÚçáò,¶gëÆ‘åö@þpZvø¶¦ã/QŽìE¯µÍé^aSÓÎäâûØ<棙ÊN¶Ž©i9{ŽóÔ�ö›s5­Ú ÅÚÍj}ÕþÆìëÔê¢ÐÕ…[<½ú’?üÝ%@3'nøûZÜõ"à]ž£õäþįžÍMüj²¾`7+vuPw†JÙÇœä™/¨P—pЯÇ×è±WÌD™S�¦+ç÷5%7fÀé*6çœ}/Çnæh°ÎÌ«cüpå~Y»õ›+ÕñäÞàÍ|ö;‘Î%­¨Lï^�o¿Aâ“].ÖÍkbèjŸ‹²11¾ºE•Ë”òÖ¸Ú©ksí¹ÚMg¢o�Æj›¾È�rUWžt>µP$oüâÏu<¹¾DÁ?{ ýÁ¼úóy¤¦ýwJOì£Û¹&OŽVò³-œ|ŠGÈðÒÅ�Š#†À�cRY†¡œ6`xý 4_°2LjÚH–gÌb9®�Y¬äŸ¶¯1Ú�€ÑræÄ8y�Ó¼ ›/ŽVÖ•OÌŲ…¼yÊ—€ÔLžˆ}ƒ»ysè™cÆbgI=úñm 1ÀÉ”xÀÖÇjf±t_1EB½µ­åž�vjå'dª’ôÃDݧæ,§1 tyÐ�áCcLå…n‚à˺AêÍ3$ãÛÇˉO‚—Š…ûdòP&\橳ïÍxëþ\ßMèrˆmKÊÀ>õ ɜך[«ÖÙ립L®bÞ£5ÁË]ÿä>EàÙ×îÕ® ”û’ßÜCðö§zŒ®mD¹Gæ�¬þžwOÈĵbÆ9÷¡iüRäàkgx­à‹ÎÉâ©ÜM<èkŸ'Z¶¹UÑ轆7~ë|¹·ñêTC¼9Ÿ˜«Ñ9:XÑS(ª�s{6´lmã·yr—tõ˜[ZËÅìŒÄk•D1œ¯ÎîÅr¶‚0Ìw�F…ïüdqÂóß·_çŸKH.5PÃSŸ¹³n�ô< üËÉ:ãö¢îiH¡ñÃ�ýŒåu¹\zÊÅû©£irÜn˜Åê4LgXÑ?<«�e­œ“÷Õ^®àÆ¿¾û‹`A´d¡LÍGˆï�byü›°\F}ð3Ç?öçþ™_ïk)äÕâ,+ÎŒÍò¹‹{ÌK‚¾ÙÉ ô¾) ›qÙwöúb;æ “Ú B[bÓHlhvƯ1‡Æ5lׂ„°þIÞ�1ª1Û7ö›“éŒÚá»Üå¼ëB›C/,¾¡_–÷¼½¸š¦ˆ§¶¼£1d¿ÎŸ2¶+’> ó“íµ_ÇêŒkS¼ÓᨎíëJ_ßÍ´½ÚýàO ée?}<€OPõ¬^4}ŽnlØ"Î@—ƒ;v½Øµ/võ±N_ò¦-Ç}å[PÎÚçJ]_€q€’m¸–ŒM%àµdišRCé†_n­Òrƒi|cãI?} ŸO¹èÏj8ioeÏruyÑB½ÚÀmÒÅõz�¹ZïGLü»¿ÅË$/}X>¬}ì¤^ÃÍëέiûr¹›K6ŠÏ¸õ£q´b?ýn/ fç$kµh¿‡‰KípõóNžKym|â†Îš@~òÃö©™ÚÅÅï'¾ØcÛhûyޚ˟cÜhô;Ÿƒö³ý6)‰3–‡sãðß=©ýú„¹?‘+úˆ¹½+Ï s"ß›g×Äó\9ïCpj dù8oü§.xà¸ùvÎ™ÑØÎ?ŽK®®­ã"ZÏ­Ý^†”ç¡ûkù[Ûæ^­{þÉ?ñOýùÔµ HÄ},C»uì‚r¨v‘Çgþ _Øñ‰¼Aþ¯º_Í ©¾íýi[ú¥ÌVéödæi›çz}k[!7޹Ñ/7Ø�[üi#“p÷MøDm/Xã^‡·¦zöxùÈQV8É·}Óg.%Ô>Z€nŽJ|®mhøS»¡˜ÅìsËË ×òÍ o˜íX�Y»ŸDNž“n0øûÅê 4ÓWÃÖ =Ø�È?F3”ãjbÖ Õ´!«¯_¾Þä!~@M´œŽÈå£Ç|‰Æ5å}>Œí>àÇ'?„Ö/9Ö¾¦�c¿„ØßÆ�£ÂzY¡%cõî/?$ÄοýX}ù`g8ú›~eâß“ã_õ9뫉ïsS÷�Úø0u•ìÿæ tíÒD!uìoÑûTgVóe�;|_²�sêS=äáK„êéªÝøWƒ19\åÃ1µ|<~3Ö—¼o\}ù­ÉôŽ:ÈýuDOnîrâØ›Ö:»45°º¯�‰H äØ/\VûÙ“" nb?÷­Äã³OYw èŸ@Ááž 'ZG/$‹—dæ…k×ò6ßîéú7�ÜñožþUõàçúܽTKpö_æÕ¾Œ1dl�È)†3uàÜ‘µÏq)fq-*«þ\½S¬¼‰W÷û¾Fîî)zÜóÑGŒ} '4ÄžŒÁj´O<¶+nuÚ�˜¶~k-k»åtϰ7ÜËÅ’ÂÌŸÅ>TÛ},�xÑóü3]Ä·×Åj�vs˜¡‰˜žÚ:}QÔ„š½V¸FDIæãt4®^¼;ÖÖ’¦Þu~9/vϺI6:±ï¨IÖ5µ—YQû;>øâØõžûòc;<�†Åîù�9šÄ/âîc-[Ãg/v/OÎ ¿‰k]Úð¿u®Æé‘èøßí}C +ç›{óm1C9Ùo^0\ûzÙuû¶sâ—ŸùŽ^ŸÜ°íhöZ[k¹Èy4A”À7ö¢Ÿö ä^�ű2YþeØPóÈ…g#gû¾\ÏÍW[ŸSä�aö¨ð¼MîñºLœwÄÑã×Ê™ØÕÚ‚&ëPÞ|ÓcîüÔô#¹· êì@×.':V»ŽñæštÖ=,fu/~Ï¿Ìíýc3y`+b{÷æŽï+L ¿áð¦ˆJ5HGš,wþ¾ 02÷Ô½>óöy´€J½˜S*åíô¥Æüýº½îþðÞµüR¿ßçÒ“|ÆFÀÖ{ÞG~´ºy /Î ç”ãÿ'ÿ¹¼ÿ™?QÛ¼HÊœØýMBwó¥‹ÿ]wãGØv>æFöðįcóøãƒœ¿ãóóµÎù#ßú^�±}ÅPø¹ñAÍæŸ|ŸºzÔ¶›´îÔa•Þxò¦{¿œÁÌ›"~ƒä“·5§;%ö´uË'ìGæÕü¼áƒè©£¹_Û¾¹°vêÏýôúÍ“ íIìì gû�€³Oë7îð§z*ªõ2ÏØS“oÓK¯ËÛKpË·gl1æ†éSµëÑ®`kšóÖÏòô-\ekíúr˜ 1%%ú�딽vçêÀ¿ÛÌD®†Ak‘;Ø­‰ó;ŽÎØÏµ59_ì'x|3N\Íµåø™é:­rj¡æ“gò^¤êÏþa7ÖIf_j)zòžÚKߘ7±ôL_ü®×êžýSöýËÛçšî%1½À›�sö˜ÇÏC>¾é ή¦šàf›©¼ëÛ~Jª‰KkTãÔ1¹šØè3^.®K?Dæ9g?è|m— -çº ?õð'ÿ\3ÔH†þ�Æœ«Ÿs#t9?:æz‘Â…KºDèëŸ&3?¿å �H”)ŸK`h³(G› û(-nb°ƒY\{PžægÜ~mL7Á£)½Üqz¹†ç¼¹8£iõ¯½&=O°ÚÞ:Pê@_&^»j <óŒ>§ç}¿Ñâóe¯ûß”sk6X‚òïVu ÷¿×[²�·šÁík~ê¨Öêá±ÃëàjÜšál,=ÎoéÌ¿¶úûÛYåá¨�žL/ÔŠCžêr™Cå¼yXóK¿œz~–ßbóË_þ¢-Î5¸õžÎ˳y¯­=òõá`GϽ8z"ŸºæÚ[l;'Ž5Z`/g¿4ºn½Ã�¸Û焞Ç5Ìì鼯œù求’™´Å•ü{ •»:ù2ns©5ûí°“bÏsÌÙ#!…QÎÎ×þE79‹l¹ÑÖõÅ­®ò•‡ÇŒº¯JxÒgHXûœ>ïÿøm KŽcßO23 G©O­XoÇ™Óö¢¹6²�…·Î?öå“-èw;�ìã+¥Œ°ö±¯¡ÍS¦Øç3ÌÍ;ž•ÕesL൧ø´mÌîE×ô-½¶¾å±óËÓ(¯WçnB‚‡÷ãùŒdwCO^õÿÖ‹m÷‚Çès=srôKâÌŒ3�ýBCls- iÓ£oxà·ÿ~‘ÞŒêŸõgæUâ匭ùaË€;62ZS×êfÃÐÄs±¼&x±Ëá¹4‡ÌÑEàä›ds ç\W«ci6–3cýk×–Ç7ƒß¤œ†™“\íýg]ËePb]§?c[ÿæÜx´¬móîy1jàqƒrú7¯;Ì�ß×á\�?r^Ì×3Z½ž¿Ä,®æèh‡jkñóm¬¼†ccl?N/kL E¬_ðØÞÚ°Ÿµ éù̉‡k5vÝ' lg¸àµ²¿Æó‹¹¿ÄÓ[úÎx95Tr¦÷š×vbŒO$ˆ«­LÖ15=9·{Î~ænÐÉÁòÿ%ìí\É‘$½Qo¯nu¡;½ÿKjvºWöÙ€`��dp777÷2If֩ƿܶëù§/«gܧ ðæ~tÀ4¾ëhæygNzIÒæ=�·`ðâY ÑòS<>ưÞ<‡—óïþ�Ú—¿<ïÑø:œ<®öÑK=ÛþžËt†` ¾(,2qJüZ�á=?‹YX"|]’ó¾Çˆ#µå=e4åùGx¾§AÃt$†¾ÑÂ¥]?ãÍñõcùÝ/×)¯ ~Žç/> "¹Y¢(ûÃ%=ð?çñýßÿ�^ÿ¶2P?‹ çÿ®ÁkoÜb…áBüº¯ ÑÊ­†Ðœ3~yàœ–­ß™@R¿o± “b9 §4à{嚣õÂ-ÕÿÔŸH3þ¥?݇ß?1ØÏ¢£<Ÿ^ȵºÏ UÂfX¤0訞$¹üØÕ+ûa;„h ÿ „@þ�èŠbVT$³œÎõ£`”ú‹ßºî‹óë–ÜzÐþ§·V¡lÔ–ó-Ñêåÿjïñ�#ÙgHŒ¼´¡ý|«¹€Ü>³Ñƒú{®Þz½s(ŒÓhï6ÒŠÆñ¿¼¦ƒV·7ï0O:LÑ?ÎÅNïôlŽ ä?=²^Ϋtú¹ó¯óĶü']r{srÔñÙÓˆ ÚO~òºAshÖ>Ðú1ËÌ‹Î?þ‘ÿ4çß¼1ßp RéºÄË9ʉúKAòbdlaÀµ`’ÍÔøÿ4þ�ÿs¾ ðz×7ŠÿÔ¼XÍ^Zó’°ÁºÑý‹uPýÏúÿWsCöÜáµ�h£Ù³›-ò\Šžÿ÷=‚Ç/ü§>®µÐr]�ódÊ:JO,çûúå¿þמ;Ó“~þê†òï¯×ñgÞëR~F80r�§Âàfl�ë KìgÒsÛ¯§~3™/D¬«½‹F3¥� O¯Û •ëüL!·^óþ4‡ù�´– ±˜Ÿ>ÀC�~£¦õ¾¤ 6 q½ ôš ŽÔR?¶b’[èö).¢;Æ5ÿC�7ÖZ„ËóûË’ÕËÌóÿˆSèÎ36¯]¹r¯/ÌŒùÅÏm¿dÜÏü' ze»oºó8þm²ü�ÿéç�{éø%ýæszi9I6´íkºO”Fu]=hëÀ~=òyR —¡ÿãŸÿÓ=ûÏÿüeáÉ9–›—ëÔû ¸dtZÍF㸦�Ù60ŽíÖÆ-†Ùp —Óï‡Hïî0;ÀÓž«—s*Ô0ÍÇG¨9x.ä9Áö­£n#9œÊÅëZeó/FáµÎ¼gû¯ÿúOy`m Ùh~üÎǹ -ÓøoŸÐÈ/U%c¢F݈%� žãÄ>8|ô’Ÿ=¼1ßs|çÂ2 ïõo4çüÜ_ß,ŸUq¯¦›ûÖ¸<Ãù5byîð:DcИà‰6½ã^èxì€6h¸fotÀ¥f'Pº‡{#=µZ™Ôe)•>sžþùÏÿÓPη¤c™OÞÇ.Œstó-�õš%ýþS=IÃ×êðqþ3ðï<O/ÿãÿà?§NO��%Üô¯'ëáíü¿×Ù²Ö×¢Ç�>�æˆ==°]I±ñ¼åƒ7ïxŸá<²OÓ!1árŽ<^±¦ç2ãAÊÑ‘÷OnP–½ù`Çü§±ÿø_úeÉ_QÓEdœ¶:ÖÏ?ñ×ÌÖtUŒ#Zé ¯Ôšë�&�ì~ÿ›ÿ|þßÿÞû_‹Ž~ç3ÕÕqs¹IfK ·9OkbrËëÄa¢×o�¿û›�Uþé âóZ›y©�“÷w£9ÿÂo9Ò wëvÇ×ÂhOìËõÄ%Zñ¼VêáÏd<÷CZ7;tÔ÷áµ->×¢e‘©�MñÄOóËc»ß<�øF‰9à÷û žß¼GÇ'›¯‹"A9εÂ>ãhŽÀÃ_‰ƒy>¹î8åŠ-õ­Àã .ï3èà¿yîÜôÆé`�;_¹*¨ Î51s9Žs„šeÚ@p¸íøê't>ß??ã»u²/}d÷{‡àâ;1º–Ó{¦ –÷§~÷Í� ŽŸ3ÆT;|æÑÞŸÉønH®Ë (ѵ¾Ïþw³{¬Ï"Óöðxqy½~*&}HoÞPêñç½åómž;àßq¸áì5ª«ù?þ¹ƒ'`€&ìä�9Ÿ‹ÆdìŒF7‰åyí7k”5–-þ]@ЧÉÕv~³&ˆuÛÎZ7­Ï7¼hž^r„2Ú°³×�ðÌf‹Ø'Þ �V*$/ãÍÅþ4rK�ëãfb,EãB{pù QèøùÒf´$2çÈ…µ¥v4L»Ï v8�¸‡Å‘�ƹ˜lÛ#Ü vÁÇ œ¾—‡�›o3Î3œ ^Ýx�•#µiÊ%«°`¦1ç‚kªO¼2“θî͇ð�ã"Î9ůÁxöèÛù{5½ëÄ¿BÌëÚn?òL#ÇÓkgÕ¡PtÃXîô˦àX 2Þjïz ×z6óò'CŽË½swò½ºFP°/—†W¬~÷Rx?g© <=n�ù€røõ‡yš‰7…ããåøˆ8oΚç­Ê�ç²çœHýtJ±ãâ6+à«ìÑ»ÀϬ(D?#_<× 4|~“äprްBLÞˆî<£eçÑñú—m=—ÑÓ_Ö‰!+?3"�^˜,èjb³^ã'¿ëVáä³ì5&;Ó&–U©%Ú¹·¿�^H’ûh\W™B£¨;üW,w«låoqYƒöäó�7¥ÕjUøZoU–1 �O‡ÅÀ¤¯ËcÄþ‘Ø�»XÇV’"KÇ,ü× ëuv£Q„ØÜsïÉýÑÚˆòæ7Þϵ½)¢ÏÖ/ÿþò‡LØüY䀗xÎÉyjo¬¤Î·Oø�>ÅíË?¸§u˜‘ÛgÞúK(�;þsZ}]å/ p§`¸Æ(LKáü"ü�oÏ !ú?I-'7á��׿,õ?¾ž~ç!NŠ6]© IDAT}uï|Ó€}¹7|ù"¯{ª•ñÔ&¿ÿÏŽh¬ô€.œºûqó;ÖìŠ1$8Ç#šÁL KÝ’s»ì]³jó1>ÐWÜ>�oçêê®B§X-ÄRhHn8X¢Á޶ ¸\sœ§qÓ+Ç?ã¤Á €)µÐwÒšW°ÃS”qùB9xÇ 4>�o�÷¯’‡·yì{ÖTÑÌሠŸ�è—N'¿j:¼‹¯fë•í\ªK]{F€nYƒ•W�[4þ‰ó,ßDz›ŠŠ��¤¸à^ãœ~�sÒÞ¼héþø¿6òoh½"gëXpÄï;íÃN«¶ºl#^8ÖÓÀ< UmMν ØV�Ø_Ìr>ܲŒ]‰% 7Úy£¬ ®c>üд^-“1¼üxêj}w®Ã¥,`ë`J™ØO cÒú—ógÂ.pZ?ÁÖs$:Áp‰¼ñhᆠø­á¸o^(§Õ\h/{êÁ›À¬8¯Á8VXÏ>"){H¯9ë‡ùÞ}pî -Õ�lOm9€-zB�zóEÌÛÓä$ 9X�]ŸbŸ�ó˜œ>ŸÅ™#®û=î¤Þ`Ó'>Ôú|×—¼7—V>×üϵûu{Dœ>™Ók?ørˆˆîÈÞ�€Îcú=r´‹€³/[Ž0ä˧ oé±OGëóù9š\7=ó"zO—õ<Ï-ù¦ ÝѾ|ÇŒ&ëÄ¿sæ… ºEÐÉ6>(O 8GSk¯ç\‡ü[‡ý‡Æ…pœ_ƒÂM­A’Çg;¹-¬¹vóX}7É‚`ðM¾åDaLΦ¥nà�×±Z ^Gð_^×n>ÈÌ(â�+FîK_“ ‡Çdë…ƒÍ�çœ'”© â7¬Uÿ5fuã‹=¸W»ûa<×7¨ôÙµ>q9?ci½ðã¸ieæu¸¯O•ÆóÊç]œîw4\7ŸÍŽ×ÊX¸d°¶sÔž˜Ôrë:­mÿÁäÃxòÁå\ÙB+î(!Ÿù¯Ñüx±[²0ôi#5EGÎ h a–kçk3î¼þÇîo†Ë®ÞêÒ\ÞàÿŽÃY™ß=FzrcàÊ—y²wO4oM›©K¡~˜$19G07L“Lk¶¨½1pf¤_ ùècƒÝÏ«­1 “ù(bõíG4'ÃI¥­í6ËzDÀið¯;¼c€Z3¦ªØÒ�à&qïOˆ�ÏvÖ†aa$ÞçC莼GXìËO\¢Y1ÂAö¶)‘·†jU~ç×v?ûp§6­ìt€mQ‰ö\—ðÙˆwäbœ^dë|Y> ƒ=¦ð“\#ÙLÖÔC0îyÝP¹o夞\‡î@Qwm_ypN»ÂΠ³ï=‰šçh€Ë‘!¸úð«×}VÀæ&ÎyHÞÔ›Z±§‘7þåÿ> �÷ ›Ã­7?rÝ;j3ßÑÖôô…eô¤ ©P¬pËݳTùçm4s$ν¤aÜϺ۩ڶCC" ƒ$‰5EGóþÄûHòá·=¼=}ºù°¿ãÆÉj1²tÞÏâõdq«ë;§ÃŸïbR 5êÀݪ o�Ìsⵓ[Žs|güë�õºÒ–þóEè·w>‡ÐTS8²Ý§-Üg¸ð‚ ò‰—w³‰fW2žÑu.„cõÂ6­ÖHòxˆ Ûì3;�6Ä�¦�·€2Ütø›Ýê3Öš•`7ËL9;ÞƒÓúO«7Ütó4^“�»Ü�Rñð€i¨s›–Ñ^»{_9N‰ýOuqy°^.§ãËå©Âü¢xo¥w}tï tãù!îãkßn$Òr®oÖóäÁ>>·Åï<Ïâ‡W‘oŸ][ź%ö ×Fm>ýrSÄ|$ÜzV—!,;y¦ »µj¶Fv$Ÿbí �õ~|„#K(�ÏW|h�¢ä &ô§ÖC"¸ý› 4‹©{�Ë0mÖ_ ž®IdtÍ8;Ü»aÎsÓ_xÙïlƒ|´Ûxiƒv¡,‡_ï|hS! ÙL»kÆ‚ÿƒ Žã_G€¹Dsì4ôTäšùðoR‚4B”%=i]‡_ž˜Bĺ‘}ÂÇô?þÍDrt“Ã\#{tú<‘··å°½øó†•dеFl4Fë�mÉ™½¼»IÏ ¹¾×Œá÷Š^–óˆ5Õ­‡6˜%õ/‡q�Åë®…åp¬åEã8]¢œ·TòîᨢÇ÷:<Ÿþḇš…²W"^ç�ÎûPŒ9~z%›Ï]?˜z{™øû¿ëwÞ&g"é4�j=“ñh¨=>eá‹T4£qph ž/cÉ%³ ²J¬@v}a©¾è%�û"S<$nšdóå¹Ýpø¡‰/Jøw)þÒHqðñð— ¯1»óÕ¸ºROjdÍX�ÁÛd›}øõPJè!×%á¡@Úd×m_6€fø‹£õbuÓ�‚0ŽCx`Ê­JÓÃ$‚ºOl4 Ïç l¬7V'{8×|Î�õkÚèwÎóeU®Áq8®>·Nˆ5B¥hMÏ­\AÚO¾FŽÛ´óWŸùòNv¿IŒ9{B¦‹Ù×h³çFN¾|MîåçKÍ}Ñn�.Â\ˆah"Žqt—�½ùéƒ(‰`ÿ/>49>3ëÛ/ï^Qºç?ŽÖÄ:eH½l.qáßsƒœë_#ŽÞ„É{®É"¬�5Ñ– Ø©Ãþœƒ='Ñk ¼G¤ö1ÐÎr—=ç�ëÄZµ¶n_3ÉKç›kÁaÓ">yrh?eàÞG»g)¬±ÇF\écx“qŒÛÕ·- °.GÏoåz ã™ÄYëÚak¤Ñ…N0ؘ³–]X_r�5ÚC<#{˜¦›Îÿž59αœ sz2WzfïÁ-/¼~�4�':HlKŽÆ±T�~Ž  ·È|"—š÷e-|Ƙ‰>(Ö÷ÌöÃfQ^d�[X²$½ Ú±v�Lj¯ìåÍÊ©ƒ tí-ç<ç š¬�õZ;uœ¼Y�õÛ<Ñ +‰8ï]cȳ¨÷W ¼!@ÇÍǵš‘> 7?Ùû9,@êòø9y£ÌrsGâ²·lÕ²~”B±qs9…ÀÇÁ#±Ý¨Ž> òœ‰mÈr ž- ´¶úÆM/.0ÀÒp‡ÀiÇÈŠ<`£tHнƾZ\ 7Np7¹—I‡ß£ù´N?cˆk1g×ßê´i[¦/þr’#•_=âšæ)ZÎqXÆ?ô[�甋í;¦sÖ£WΛ“d÷j þœ Y´±^�í)~øÁoíþƒÁ®ç…–Ùâ;ˆ[ìëI_H˜Œäpä…¦ózž\0Õ×9ü?v z˜œ‡,ÎUëB„üâvnY]_âÆ‘w1´&1[¼´EtiûÖŽÝfX’n]QÛral³NÃÄ¥GNrù(¢vDZ^aZŸ�vi˜Šlµc±Ár{Ã6Bv~H>èŸut˜ª N= çñävGhýœ(zÅCõòGm&yE û̹€s!^³‚”"¡UÂ^uæI >7b°�ŸõÓ‹j5n~×�€²‡—þ’G·ðißž/·{Q$ÄN^ŒœñÅÆ·íAXŸõŠ©É=um¾æ4‰ìƼüËg~ñæwÇ'À‚4ƒ³rëת9=ƒ«ž3ãaý3–�P‡7.Rs®Dj@àýý˜&×aba¥ÅvfÙìC_ý©NPá§Oîû“’óJ j7»4ØX@üeˆ#¸h°_@^„Ï8yb1­mu0ÉèÛ’È–~•]g4(æyŒø*>¶œ½¢v35þ‘6?ÜÍG�1‰L²;á 7±Ø=4;qzÍr�ìú™èÅCR¿x]‹Øú5±Zm»žœß:ˆghC¨GÃÚn9q±6„Å '.õÉ2=n˜°2�Ú¾«Íˆ¨Í&àöØoÄ!çv…ue#á§ßŒ¬ Éä\W;œ<8§æ—_÷ï€Ì„r˜[/9½º¿�Úá×coÜç§N÷¿×ñP¹Ö3¬®§6ÇJ™Ï-æh�jbý¥‡°ã}¹Íà�ý²RF'¯ÍuÿÍ34†ãÅæÇÎ#_òDøìƒa eÊ ÆJÊ[³T±æ¿dêk çè÷‹5tñÅ!ƒ82G&ãA �שè<ûIŒC ¸ÕŠŸÕ&¯�/GÉ‹kQµ®¾O^x5Üó§!HŽ»ójQ$âv–x©=gC3ë;¢J{Ë×Aþ{–8úý0Ää…oZr>“`yü‘®§}QÕr�'*‹5³ÃŸÑí½ J’T¶¬Ž£=rÞX½šÄå½�ºÇC”CœÎKåv>0Òs‹·_’-¦¡å �}Ж§ûjGÖ~ý¶ýúò…d{M¸‹�„š‹ºòW•Vo‡œšq{ûÆ)1·Ò˜ÎX‰¸Ã×0kléAݾ�ØnrÍŠ8rø|jÍ_ÏÆÖs«í¾¬z¨„!¹²òÜ5¸ôÞ0ÜûÙºâÚ³3Q‹õäégòK¾Äk¿¥Ùýo¼k—Lj'±!cík¢Z¨rÚ÷EL‘§'�Œ³$ί?Õie¶´Ñ*†d<ä­F¶æ0cHÜ_–zÛµ›9‚ý¥1ñáûå²\áÁæw]=6EAÎS˜Ï­µZ(}mLÓê´£÷V…¹Æ¥“ïêÏõ¼÷—П~¼D^C�Üæ¥(¤zœ…v¹ະÈt~A€™<îD/ŽTÀ\¯á «Û®Š ¢vÈ þâÆe« }ü]FS6ôÈ×Ã4a>BYkã½’Õž”>…ï÷øæºñAê)Åôoöõ€ÿñ¹Ñ�-ç9Ï/ÖÙ�4±�Ó°ŒS3e­v•´¼Ã]>9]2 Æô¼¡q:ïºIWÎåK®p-¯c„uŒBØÛ6]òþ “eq6Y«%-©Ä+ äVp8ëÇît`ñ�Üð$®Ìö³N@(ƒMõ² ¬ËýB™ØÕúÖµœ{­±Oàå�ß¹é‘y’ÀüZ2¢%ÉÝ#Ù¼£¦Ü�vç�íSs:�•ÞÕ48‡éu·äÙ9l/§#L¤fC÷òµ½küD±Kßr�Œûa4ßöt*˜^røÇ-" š’,1ó�ý¾¸‚<î$~1^·˜ð€ËãÆÂ³;*œì�_ñܦÝ § zœœP#ŒÁ¢¹N í«ùìÚ«ÝÜA„»z7ŒUE¦¬_¿qvù`Ê»­-¼œXóŠs:mŠüïøìR—Z /¸´ç�ÎÃg‚äÎvu\ë��°Œ“Ÿ…8G_LXdvÎÅì Î^ÎI<±DðØùvŽ&ÊZÇî g€�/ûm¢%`¯ åÁò‘8/”Á�±�K�ÕæYþ7fPWPßpó5…ãRéå èð­‡Õý¯~Ò;8!g9ëéM'7ð>\^:W8zø�}P±Îоö³a×OŠË•ú¥€×Ý*ë£!¼éÚO¾“³™·W²“϶Ʀ£öÕør˜×Òò‚ ΃i’—ñ§�p Å÷¨:ḧ{”–w=X|(mK잳ጠ"ëõƯÞä§�¹-£\ôŸa,ýÙÞ EWÀå2Ú1Któ¥–Ã?½å'þhjÝ–Î!¹–,6�‡y«}yO>G”ݺ‰¿Á‹Û_;·/¿œ§µ²FøiåDXÛ¥³o}ÃÏ>t¥Î_jXîÃ-„µÉíÿŒdž\o¿ÃU'ÜJprÀ?›³Â«kO_0ù> ”€M+ÎÂsnˇÚW«~ˆûé´À0–/"½Áp¹olûUªð¹ŸÖëèS€Z£3Í÷ÕB"0Ëu®m9Јª â‹HpºÛN,¾}é>üϹvžäZó&ؼ,-nݨË9jŽ@ˬaíŸÛâ�Fs¸Ù'VÓ0Îשõ5wUR×A=bŠ“³,0RÌÊ÷¿äE‡cH¿GAÿ¹½c‘6›õ�p/?#HÎA¸8Zwi×PŒ×KŒÑ­ ÉйɶúNŒh½µÔ…{"ŽÖ&[rcÑuÕ¿l<ù†Ã+RbÀ˜K!Ñ¢ë‡:û€ÇÚL¬@mä‚Áw‹óÒg‡†gŠ-vAï`chó™›ówí»7ÍI~ÎA€‡ÆÇ†€0pd·&%€#% CŽ®�n-Ÿû[¿è�Î�C÷eñf»|3[ÜôÚgj#»n{�Š,`=q‚F›Éc.ì85n}Îæœñ„3~,ÎÜ/cÃ;ŽR™Ïj$†[Fb³¶R/Ó§aêýlµ!ôc ‡ë•/¿Ì‹âq2/ÿÑØPÎCùeÎe‡øÖÇco!WÌ8Ý›¤¼Z1ñ…ƶ\Œ¶Gcãs ñÜD_t�= ×c_ž{Ñzœ9�å²\Çè`2á&ÇŸ†í¸x,1ÛßP÷»÷é·kJ£çx&U{pËåH0oüU踷–Ø€ÂÖÇ2hS³a¦IOÓÛhA!ÑÄ"q17ÓjYNÏ8àÝ ÉÛX#îÚ@V»óÓJ­…Z<4 c›íÎ�Ôçüôy‘(‚Ükäe„ϵc@¶b±ñÌ^ü³›]ÆðR|{«Øí½lÿeK8ñ*ßÞß³.¯=¡µÍ@®!ä/‡s�;5-ˆ¸8lñ<µaÁ ¼¬0 ÷Z�Äv�£6¿6WJ¨cŒÄ„ÅD^ƒ)õÕa7žâË—¬·ÇØ5kÄÔÌùC;ìs>¦Kç¿3”Øûkî½�»‚ Òœ&µ*Ÿ˜b&©)×l­ºkóS z«�ÃiWìñÓTHƒ9ëìu„kþ½¿8“;'€g¢øúýÂκ�e:�ƒF˜ô'5`2þá o"¨Û�ÆÆL‚®Þ`ÉšªîhÐÍÓfcÍößy=®f9×Ûß8öûräpP 1è­šéÍy’3Ò’šdð‡FûGü[›IëgZ?Xã#ú­sùãÒ¿&‹8k·/áÑ@Ÿ¸)9—®êÇf ªù>9eDãÕ”õÁôd½u\lø ÏxúJ\î�²;Ogó[�VÂ탴c kgÓŒ…­M˜^{à{9f<äÄ ªµÓ´Z�w¨Ñ­Çö7ß®I;ùܳWòlS7-¿ýÝ~uÜú™XúÚ¿ìq-CvžFç&þ©m>Aw-¡{ës-B…Ý'%AoœÉuêÐz±ƒ­öåÛ<¬öÖE �ì9tXÛ6laqçºr„1 JZ óµ§Àõ5v9°q#öcöÔ Ø»‡³h.þ— ¶|©u+ØoÞ_]õpY;B“¾}MΘx]qqÉ¿Ä7Mü‹¸&rù™ý±Sôp1)£N ½3�0¿×„u?ç¿uú„šÁ{[ñ{ägþåq rÞ­Éú¢ÃºT&koÿÝ'MŒ`\óEß}Nš<©3|Ù¥ÈÅËj»­;Ûú´²â Zü:|(Óz(ÀI_ñšöÆÔz‰E—fpî Hmœ]³³»Ó¿öÚåØñ¡¯JÒ¬pbu>åæƒ~}aeOrât;š°��G=²‹  qpg•XðÞ‚ãâuŒU°ý?SÁ? h†Y›ùçîÌs/ÊnïÏèIô%ƒÕ êü¥ Çê°]«wï�æçAIÁ°O¿Ÿs+R>×_I–fýVf‘>÷õ/·µ/‡|)IÙŠsNr»Bür�³Z´ó4PSq Ù×Ö|Äh!nÐ`}c–ataB�ò —_&XlÕBœŽ�mãó3 #ytó_åA§ðá^�à~ûŠ&³6ÖÉ‹6Ç@X-u:ɸ6­ç@ÔZ¹áfè‡ë*¿û®çÙlÁ2½ŸOæax× óÅáóÓ˜&´n¯\iÎù¦¶ fíèe_çê°¶ âçõ\^\’uQƒY8�ˆ} ›ä 8ÔçÅ’èXüo<×Lò}JUô‰tÛ‡7§Oc™!ÏãúñÌà Äíæ°á^Sl�£â\çÖ�Á¸Ï›þˆWw°Î œëh¾„-˜>@�‡ÛK{4ºȆ—'¹ ÃÂç%°ªÜŠ Êr€AiÜjòyw|Vkðγƒ8ˆ·Ÿƒ…ÙX€MÎÃášÿùÙSÓÑÂ>xÄë³£„¶;¯­Ù2«�é=�ཇç`²ðQ~úãúdpß’ÒqÄÿÖ¾ÂíüÎeŽä²VXˆV' 9æ‘ #¯^\gÈyømL Kìf3Oyë6ù=r ¸åsî¹Ë%ªˆ»x—*¯eãæÞÂM>8u‹][^Gô°ÏIY£NÍ‹ÇþŽà*̼`“œëÒìžZïå¤&Û�3ȚͶ4›Á¯M¬š99µŸ¾×—€©‡æh„«J ©õ(nxL'á–ßuO–Žêw©ítêÕ5<ó bf<òùœhO|Ö©ß9 Îë[7TŒ�Jx³zó PèmFlŠì ’ ¿“ÅlQÀÁhŒÆLÈò«înÔœFúDfE`Gó°[.+îqN`'xpKˆ�V�Ôtcã¼eXÏ£!¡�}‡OÜ¢OîõmUc;ºîÙìÅ}˜ôôÉ5˜ªÝOxx1é¶XsI]ŸmŠ3F‰¹8ü âvËm%â}ëD7†1Óç}õh=Œ{Í"ÅŸ Ï"n•ËæúÖÓÍ�Mã�z‰²6Þ˼`BjÍ,I:¬å\p¬g¬]Çz à'Ü;[jœ×ù[¸;pš#ƒóÂQ�Ìíí°Ìhˆ}øCèB—„5o&6\ŸqòâïÀ–áÌÇãÚ¨a4¶!©ñæŽt‡°®ƒíMçxôMs\:ßÑ…Ë›jQ¿"#záöåUœû†�=7Åbs& oY„òÎ rhá@~Çyš·^­ÏopJšœñ£#ÄÚ‹›úÃSAÀ¬Eæ™YÛžçâ~ÔQÜrž j¼IÏZqΑkñò­W=?¬W`\Çrê�ŽÃÒ0 v6aéõ)o\Û£`×  |Π±ÌzêÂÎÃ�®;a·ŸnÖ)ßý 9tgðÁl\èØZ‹ pÆ&Àþù‘˯¡Š?=¡æá<'þð+»3„ãqZ |IîLÀl?oe†ÖÔùŸQä:sÊRâ9rõ½~:.z—z’ÿÆšòë‡wΚÂùœ *]­k@³¯çj Ó§™¿dÊ@gêñå ¢ädÎÃõ[ô£Íùz¤œh¤z‘å?EGG�Jèµ¶ùB$|Ó±_š.¿í‚l�—¡ìÖ€úçÛòkW„‹&‚J µO��´‘q¸Ë—¸yMi.´8“f0Óv™°•“™2䯵æ3C§‡#\ ÇZh­KåÞ‡?èÚèK ¡NЪ›£Ù±‡ ¸­Cœ¿¸>ÑOÌË‘Dæwž[¬÷K9O.Xr¾¹®ã‰—~ZŒõ¶ÂÖ�ÜFótNvl7àX�Øð±'•k´%_ü™#MeÓγoÊíŸOBz똆�ë[y]Õ£7¦e¹6W«¶æ­ðÅ Êš.Üjó%æ8)jL/ÃXÉ*?Ý}]Ưè¸-›œN‚øzœ'Ù¢ëxDÙÔÁìs®Xs›*ùq’‡uhíëUø×ât÷žü¬} VÚ0.‡Iµ7Dù­¦9�»$ì-ЂÂylÄ2íã IDAT7ê̲qŸO(|�œä¨ÓÍ??4�@܆ÿö3œé/r÷œxòÈh‚èrNL¶¦ïðx/,i AËkköº´Ãž:•kÒ�˜Z ãØÀ-À§>R¸”½¬Jˆ4G¶>:¬~ æu¾ÇŸCrh¾éY§kéPûµ°ßsÖ>_$™OXǦrÛ}¨Fó­~ÅxÌW±‰—‡‚7†e¯õ9ókÎ9šA³·n–ÚSËaæ¼<_t#§î¶¯Á:½_/d,<·p$Þ{'WœÞãy,ÇÙŠ«ñ;oó±÷R€dÄ’ÑðU‡½ìÇá5ºQƒ9Žè4ºš»^ `Åìõ’`sÀ£Çxˆº©þ ³x×%dhó܈´h{#Qü厺ì�Ï}ŒÆh7b|žÈ�„Î×µkù±[ÛãÏù–U5ø�¯|˜ÌW˜ë2ƒ×�cL²×ÊñÆ-׫(Á‡Ó{[ÏÁ9–@yON#¶k`bu¯KØñð½�];ùÎFïomhެµ!˜0Fô§uq 9)ùa�0]�õQºuz¾ psj q¾XÑß?‹æèTÇ’i»:Xêa-† ‰wÚ 8ß‹†ìöÂuh qáRÌ7¹`ÍíœFzOÞÄö}ꜞÀWNç´òÄ|yíÈ¡uºK]û·†‹Õ ÿå{b»´6ò²°þ?a–]¾j – šÈÓê´äSùÛMSú!ÿx �ŸpÖ‹[=ãÅgé>6Xàô$ûõø¤€ŒGJ)Ÿu´™Ì}Äééõr$â�~kËдýé4VËvÌ®YþÌ9‡^ƒn!ëÅÑ‚øË½œ®r4�c{B�.Öôµ�ƒ5&z[a‡3my’Òã�?kë»,ä V1öõµ@µƒ{ÃÆ«uC®Ad§¯å6Ey\+k=òv_†”XÓrž|�M¢Žº ãÔ8oóàƒ'u/¨äBKöу&G#$ð“áO¾¤”' cÜׄ ¢,éMÛRS&ËYjÁ@ç�U6D«sª"r4¿‰µ¦N›XOÄprð£õ.¨¶‘—ÜÁ­þðÁžnFðm{–K ßÑ àó1ïÃ�•Ž€xòU#æ÷ Þ¸B<­-Ifr;>g_/>¦ÀBÖ9˜æo,¶ÙI퇦ôj©—¥oãÂ�SÃñÛÄDö¥'úá±þý¥5{¬4"w÷7ÑD~jö ú¢‡ÈÆi³ŒÍ¹jÀ¯[¡ÀÀ”7¾ðä‹ b„6abL턎Lî,�z÷RáÃÃDç×ú'P³û(51Ø;§yXÛ˜¼ ³™ bŤþK/÷F^Öd”µ•9ŽX�¬ì%·á¬FGâe„¥ËÐiãÿŒG�/£1D@XN³8©�ôÄyÑ>5UÄDXcS»£mWQ£y¯-~¾ÁE�Oö>õe‰ß(©½H~EX)z…çá�l¬œ1 ƒXÜþÀwF—þÏm�Õõèk‚¾$ÿ£ÚZÌÆ—¸ýâÄ~AÝ.rþN†,ȣǸöoç…‹;@‘Gž¾ç�Æä¶O1¢81O^ó¢uÜë)mã˜õêa—sj‡ç {òô9t¨´Hn˜rÇB’¼.Ï”ͪº\¹·nWð�¡kxëÒÞ}@‹z˜ÜÍXQ£COe™âŽÙùwÍ‚õu «@Î#²ÒÚéVíÜàü'´šýÌÞ±áªcî:AVß$Ön«jÐÌ=#‹–R›°Î¥éqdy…ï>®»î7kkœ'±œÜå8½YRÙvN’?9ˆ%ÝlìÓßä#ÝGŽÍ¶àã«7æÕõáSØ/:CÁsh˾BâåH}ÌÂ1zpHù½-ΨÇ AÜÐzû» ‹ßüry­£s-'äøèuo ¸{Yš[î l¸kºxåäî‚#d:®=yw„¸c %ŒT²Ç7žEàÎ \r%ι¨Í ‡ ~ðì›/ýIjÄX_j1ÜÔ#;u0ÒCž[%’†Õm@@±)dúOØø ¥V¨Jw8j4·�O­ì’åX,”{Óz{¤€Åxùîã î Ü;ß2FpˆeüŽ[p¹„yu…[>Ál Zž]ƒÄ�;?ÎÙØc{µœ,:äã·/ÁÄÆÜçHòé†ãÔÆ¾ƒÚiXb�@Ó6|zqö�ܿ抩@MÖPÖQ„£Éð¿üÞí—fR˜†ëË‚}hw€CVÛ›§^ë´ý9÷øräÁîZ{þ-À#Ô�`OŽÆP Ëç5MkŒÎ·œŒ¦ÊkÃtñˆå “/%úÜàÜ´n‡Wë¸ÐG ø}_#Üës¥Zã[ìüð%M‘r`K­ °W™øKtd^ë×Sz±ã “é„Ë?"|FxBí¿;’¦°ŒÈê°VŸýÑìsü çwØVóÎ¥ ùäÁdù~&!hÍ9&�÷�ÍâJŸ±§/%d"—s'äÑõ\wÙ§g=ž^S˜þ yÎ…F¯j7s׿Jª£Ýlò3“?#3Çô.µà3‡Ï#xN”œg�NÈXmW½ìÂ{ 7+÷«ä¦þù\ºÁ€>AÕÔxpÒ~`ÐÏ|%¯‡é.ù ÄóCJðëß~ÖÌäj‹†è7õhï\ ó,¨ópÀ ¿÷µû[Óq�ÖÖ‹ïñ‡Æ­+ϲð Åüzü±ÿX²} hšúĵf÷AŽƒÓÂ=Ÿ6toÔ·í jð*ã´N‘óŠè/çt\ò½Ö{O,¸gFˆs^ÌñËæNȎ펂-€uLìú—ÎS5?$,]—P°kÙ‚O¦Öj 2-Úõ—7¶&®-þdÏ\G9‡Þµ§¶UGMeAÞåeÅžÙ×j´Ix³&$œÐ nªcw­¸ž±úÍ%¸ùkÆa©)Ú’õ¦ÐÞ~Ðb;AÉ�~‡¼ÌTõÑuhE*ÏàÒ'i’$�qÚC�:Ðq…ä¯r Ö;ÏZ–y ÍäÉuÏ–óhóµ•ÀÚ к䳖Иcœ1Uß™¢™÷X€É�nüV4 sòÃÏuçм~ìË QbÏ 2ÏG¡—ÃÝ�cÞ|À�ß¾}zŽmç†5ãp”¤ríCó©U–ùÈprjaÌêÇœ u¿yØDìNÔ]rõK=xÊiL7LÆUû”"M,c�Úî¯S§°çË�D�¿0�[Ûa§7ñ-ɾÈE©ï�aÉrÀc�2§É�8RTh¦Yå&Þ\2Á¼|lÂÄÜú#Óy°íK)×dLbàñX^ùÞê@ìÆYUÛbs7°D¥c�_ÅsûWÿò®UÜú f_t¦Þ<Ï�'Mó» §xEÉÇûóô6B¼žP™ÀÀÿS½Igøãú “Ík|>‘ð”Oûœ�ûèø¢×Ðàvþ‘8ê„ÒÖW^Ôê‹eçMÁÉèüÕSêå£>Ö~Mñ_ÂŰp?/YsÝÚ3QÎã\Õ˜H,°< €dƒý�cÍÀëÕÁ^ŽB‹ƒêrÍg=«Ç|á„”ãÚ5쟹™�[œz ÛìèØCxóËŸÿÖU8xØñÌpÚ+„ÝC¶¦°ƒßü‡Íæ„ êkó�Íð‰&õ÷®¹œ{ëÍe�Î'„>=2U÷^ç)dŠkªV÷ƒ+("ß¾^íâÿÔ#.ïá²VâÇ£Õra–¯jÇOE¿ö z„› Æbõù‰’ïÐú\@Š17±~&2øâ7aþîÜ“Àqðh>{¬˜vöMh.òïV™2 "ö™q„Ífã¢-!9Ú²ekD¾ìèû C omàÈãs°¸%¶¤¨\î�+˜°¹Òj7—É’Ç‘p‚{0Ö¶äÖ l4g†Öbï,™Í=ŽHLó¼=ÀÀ¾q®q®ê‰CgñšNm¬å¸�`@x¬oÔylÃ’*“5ußœÁà”�»è~u€q/�1JAïÜ¿Öç®{�¿ÈŠö„¸Æ(ùßQÎˆŽ¸ãަt¯žåÇ·¿@ŠëÑKfd>»Ô±­f“k¢¯Ê óÀ«izv‘aJ÷±qëAæøgÚåIô07÷X5 šó£åÑ@¼Æ$víž¹{} çkS‡Ïçt^êä|.î;Çîó š `rFFS9Ç´jÞïöÄÀk½¦CUöäpbrtLóþS0´X„Ü©]å7˜ÙÈ1·01¦^Ÿ‰d„׸I†a£Ëï—*õ[ŽÌë¿õŒCóΗõ¾üÓf[®_ŸR´V–ûÅ”iˆ—oéüù²I\ý’)1hÓûÙ¬ÕFÛ!^[Öá5×rú×<²¹ƒ ÍuÀFÙOüx‰K]ùrk�ˆ½ô™›<ñY¾WKLð/'yù ¸ä÷Œ¾è ÄV[z¶¤£ÀZRCòÁÇ&©´;XG­XrhtÊÆ1ª@¹&{³ÿ ˜´â¢Þä ÅŽÎÊ�qreþ}Ä à'›nh�„ÉGAøÜ=±O¨óaal@÷á"‰Ý'ÍY4ujBžô/™g1/’\ Þø'gz1<ò½ûU"×ÑÙ‹oÿ®åxÎÿ8ÎLˆŠªS#)2[Á=ØGÏÑòMÓC_Ý[Žù2œº{Ö®ÊX6Þ yÃär-ÐX[¡ÚbJ Ûù/J¬:¤�Çaü®�ž3ø$ŒÇ­!˜ý2�LhçÅ¥G¡çXup5±Œ´§B´‡obÃW&�wN"ycœ#kCM¢˜Îûeœ�îÚjŒN¢>Ã9†‰z½º¿©àÈÙ¿99?ò§hã�Í6}”)áùòT˜¸9—›¶ › �ó�­·Þ…ðüŒ”gcô†sµÆ†àŸ8¶Çv®ë‹”Ow§1LJN?„|ò/w0׉_‡ržð¦¥= Ñœ–yºbàsäÂd~¯°�ˆc“]÷Å�Þ`|í=7‰rT Jàˆ.h(~Þ†2¹ ¾3Ð[Cï©,Èñð¡Â½°·P ëÛôÕ {ÝH5<¹Ž{]ÚQªÓ3wXž’hkÎñŠÜG§áf³ ÷s,‡’=½vÇœãÃüœŒ©ÅÿbÜ—jËQ‘u±׈°Ê¶sˆÜàÒö~¸¯t¿/½Ê“¾ÔÖ8Žå k�±Ù«ú]ÇÑ•kÄ�‘Cóz>Ìø"€#þ}Iøb+ÑXSQ¯ðëÅjmóùÚCy¦‘\z°/|˜ßkÕ|Õ§¢>Þ¢C‹ü€¬'nd˜I“Ö.¬¤�ˆÒXK:#¶‚ç�áãr¨NXOþäãT:ÞþH¹û«ËÚÞ ayvRLdÑ©Éõj!§y|. d™L’m(Î1µ½¹«ZÈïI!Úª‰�æ›[Ößk°!6;.m8Z|ޤépÂÿ�xÝšºô ahÌ‹Ù/W8¢Ûkø»x¿¸8}øé›åHù¦Ž å¦ßd“}ZˆF,º\¯öÆ.¦3ØÈâl¦Zã³Ä­ßü±]ëöÉ*>rš«Ì­ÿú4m'{û ×tš£=Ã6Ÿõiû~ÐÀ7ÎaàI‰-ϱß‚sþ‰e¸†q‚TÌzçài Q|àŠÍ*š'7�#8×î]óuMr×­™XÖÉß@¦Ö IëØ§�­kL¬Ób³S€µY¹WæR8ÏíäÛ_ІÓ9œDÈÐÁ”0 ,Ç™ûÞÃÌ–”.Ê=«ƒMâ7‘è a!݃h¯Â�ó|j>|â-µ}Чhçä5ƒZ}Bt�øÀj�U›ã;ý§›ÉŸçªAOÎÔÙ¼8BPø’ƒ€p,�5-ÿf¹§8‘6m® mørدÉðOkRœ}Ì2b¯Fæ,s´«¯B +#ël¥¡f&ê¤/'wñìÓ¯ð×lÞ‹½ü>OÔ9w»¤¢<|a †ëƒ?Ðö_fB’]|ñ´/›ëZ_„W >××™»bç°ÒÙìp™È—c´GË^› Öá¼Î6éabјº¬•µ{+þÀ¼˜}ÜÌøÑq{9/*cO\ìh}÷Á,Æ;Ç)”{ÇýòŽØéu¿ü‹ Á’ƒý_=b¢·\¿º'~ RAQ3ûh\~Û0KÑíO#dwˆÕ±Gül¹f¦Çµ›«õ�5ÜÄÒ¡ÃÛëÊtñ;Åp�7¿Üœ h؛Ƕj9“‚7¹Îy!Í�¥æ�¹³¥7ƹm>ty(ÑÉS¼§ºÿè{p©J䯧®…øM7,Nj$f}þøá+Áf[”8ðGŸ›Ì¾q–Äy.+öws“µ;ßÅ Ÿ¥ÂñB1½æ+?(ìWëM°^O«q"bö ò Ù/G{ÓC%Nh|rŽ�¶±fX¯_ÅêMãöÃ(ç´Îæ÷x–'3‘÷9ä|¶4瘟ÞÀ'QGYW»ójOÝŸVB3<}¼þÅ'.,MIäB4ç†íæb—±·g†ç×~ú7Ú\˜ø­³Ù;9þ`íoºcÚ“ž¢–'Øe R¶ýüÂ�ñmÊÀò¿÷�‰ýý:X<ÉUÞ+žá©9°ä—ÄOÞü[kž~Âd6%Í’ãzB-CŸ˜³¹¿LÇ�-±À)�(=P?ŸÁ‚°*'¬Ã•§0¿¹ªý�úŠ�+QÞ|Ƕü̺cÿ4ÇyÔæÂQ.£YÇŽpÉF³ e³<D £ÛÚ lÍf�.‰Üîg†o&-^®ýpǽòœ[›å8¿}$qÇgñ\Ó Î{4èŽ~’h~yNÜéƒx¦�ô‹yûxlÆ’d†}èÜ2M³Ï-»¨oq®?âÄñÚ »œeqI©c ©ô®!Zœ¬™�FâË…¾ø—]84òx†ûd†j2äb“É¿$á<˜á<ìÞ£ïö¢°¼vB¦=³0=qîµtG«‘§ŽOn¹Œ¡¿­ÿ�JrT×7›Ãé[V3Èÿ‹Ù_ë�Ç/¼”“’æD©0>êrê+Ò¡>}‘ÿÅÔGp°x¡iÿ‰¬DžÈ·¼ÓÜÌNn:\ú='•©ãK¿�ÇëäI“Üg‹aŸ¹— ¹÷ƒ$Êd§—ä5c©Hû˜Ø†wü°#7 Ë¡=|G¸pÜO�n.k5Ë{x’ž%¹n¯¬C¾ÕéèÈ9_,ÈÉ]£ƒØ øµãvd^/Ö±©‰¨”†¸ä@Ç‹e½~Ü>~ú²ö¤Äh1‡ë¢6'õþó�6–:½Zg[-.$µÔNÐYjquÞ¾À¾|ˆ“>7RS~yÛ}Î ã^T¼#T¨ë²M–KAû!ãêõÒYíçÚµžù±R¸Çæ>{ÏuR:çª~ÖøyØžÜè%Ö1õ§–äðy´}àKŸþ»qâA[jßͧýoqÅ[¯xýŸlL|.Lë­ˆ,MæhÒ—+ìc Qu`È›AäÔÍ[Y˜áåÁ0ßóÅŽ5ÈÓj#*ëð³'ù倉©EyоØÝWü×j L�;gõ€ÎˆnÇɰÌWG,éŽå4djƒ+Ôft’μ2ÈNlËiœzc}ôðG£ÿJʽ›C³î'^ùð�7¼Na�yëAð.&çŠÚ�=�x`Â…d.½Éí_ÒX@|+·;my4Ê‘:c_Á7m""5¥zæ.ážVY*»9Á¦¡ã&e1ë5¦\3»#“:]+<–ËáÚüþ@¾Ó{¹Ñ wlW:ÍW*çç`H8ѾzÈ·_²Ž=áyÿ™¹;L°�{‘8Ñ}äƒóË DžËe‘/n~òGSêóˆ†kF,CÔøÖ3|N÷HpŸëõÁpy“TF8ŇU»¦}çõ̹�J”�ô“0âúˆÖ%6¹o �¢mµ™Û!á¶òž«}8¥ê£5ic¼<)gš´ËýöÌåCuLzמ‚k,~¤9hS©�ôä)9ñØÓ“Âüpšœn«ŠÝüÌø<ßDÞsÇ2+øÑmǼ'̺v®I¼õø*æ@Q/éßk�Û‘úå7 ¢R8b�&¯Wö£;ü`³|ЬAGX‰©=z˜�£¾µ2­ý—gµ•üær½ÍµêôÃ9`zI€N§²®Oç†ïßô‚pøÌé)úèol цÝñ¢y° ØÉ_.Ä$ô÷Ž\²ø¾s)¿öñMCtà˜6Öôdû `­ö Áåã<‚[N1%Qþë1�Âß<ø^rÖ2øÃ”jrè3æS£!>¬Géaì¬É�žôw×ZlBi ÎÀÌ$p€<û¥tuç:p�%LÓt/º¡yã�_Býæ'ÝŠw²MÁ(έV‡lþRòþ…]z}��Íšpu ÉÄ3Œ^Fûdâ/7ëC6KÁ¶G횬óÄ‹ë_úPEúë>hÃÞãÔVnŒâÎ/­’|¹ƒGz!"÷ò¥_á8”ò;7*”¶�;Ÿ)™§ÍBa®®Ná7�³ëÀ9Ü5 ŸIíÜ_9Ú‹ŽoOa… ç2°æ9›s{ò[¯T‚½„^ƒu”�ã™Í.�«A¢IžÄ¢ÃâÈ…¶Ôæ5^¹ýðºý±-q2›w<ÓÊy±<Îq÷ãNi-.£s@GWò±&.¯=>{Ñ+îÓ»Öb Š9ùž%0w9ß<騞HжQ.Rí<,- ‰_^ûK~®SxÆ!^~±7ßæõÇ)‹ÅvýOîêZ¼�ÞÍ2®.8Ì#_øP µ~ÌÓ éÏ×tú}æ°›KË™"OÎX8Oßàþýå&>°y}KÔUˆ7 ¢‚Ô±ýÒ‹‡§oâãüØJIß½¹ÛçÃ×ów±Š.¶(Jžô#õ†ëö(Ø»ÈÏy‘®« õ9Nº¾"1´w°;Ãê‚#Ù¿>º¨•XîåX¾õe,¶¿Ñ~™A„ïv˜ØÌãt„?TR,ÃEgyŽó½Éæ¬ïœ,Ù#Ô5 •Æn'nÓ4zÞ(ì$úæhÚOóÆÃI wnO~xƒ2xþ™ L\föælŽôD™l âÏc'éã5>Á,Oøø¸ÊjŸfz‚Éq­Ñ�§'ïEl¤ÀÉ£ØÏÐ6qäŸ#ÙX‘cy7¿´ÔzFBÞýœßbÒ½ÞÎ.Ŧÿ—ï©8 Iª»5vvl‰¢=³à×ÍÎ 4˲þ-+LøÌ9pAîÍê§µqZ[�¬µxøv~djØÖùäU˜qƒ6Å3:�Çqâ‹YZû†)¹^â Èqåa›”��äLÞǨ¥öc²¸á-kåN"g 4Òs>Á¬Öh‘$p»”w�o$‚Ò‡Àví;]ãñ„/ÖÄ’œL{†y½ª�5Ëg‹ œ±h±N'¾üUpo÷´'1ú-º3{�ñ¬&Œò½ù �têd<�³61ðEVã˜|^ �~÷±6÷g…7�”½Æ�·›p.ÏsÖAæ<¯ü0ä˜s˜ë= ÷P³ë‹ pãlºIrBìË™�¯/]³LðŸ8CB†ý<§ÐàÄè¨ë0Úàe¸àó*6dŸó’Âi’ëØWˆf8Žøä‹!ùË’’i²^‡M{|1…Ϥ:xg=³¯/#IÆiGt€ ¾ò¼Á½q‚ÅïÝÒ²a½=‹³'?‡NÏE°î§6øèdFrP­›Ò 8Ö'4ÖÛ9ÏÉØÆËì/Œa·k%AŸšÔ¼æ‘Ç<ûÃÜÂÁ¼ûfaÉüÔ«É«äÜudÒvµ9þÙ—óÃn¼� H’%Ê;\‹5.h÷ÓvÅòÁ69o²BåÛCiDP¤›Îp|�© Îó_±‘/û½wÁN¼oN’k�½¯›ÚÅšGeyQÿ¹þ‡g È ÷™ÀcoxcÎúd_tÈ|ó œâÌŸ>¦†’:ö`²óñr°%fùQ·‡œÃ‹­êúÆÁ6k°ÆøÎ@ôØù‡.ïñMŠÖ�Ê�ÖrãŸÆä 6µx�Œæ;’ÌçaØô"É’¿AÄ3¬%¶`eZ¿ÝlEÙŒ(¦Ó|椊V#QãOÒ»‡k|§~§¤O#l?Øû«ãækÌ;ÁÝ~™B{âO�Hֺф/ù³~c¹~�ëáƒÓzÐM}æÀŠ\˜Þñ^£¯=k}µÚ�øö鬩§z\õ‚í/í¢!Úc�† У“ûoÐmË6ãUù~k³†CT~¦G[âŽ) xËíT¿½Ý¾º’g£կ…ÂñŸ(Û/f÷gÜø’Í%³sJ¸›{:7¿x—¡ÿ:å€Gyó‚<±ÑØ3KdëÆ�¦Ê¾^ÒÆo^øõ`4Û5šõÆø¶÷¼¼s’ŒÜ<|ë‡ø�æ³ ¼à¦?4¡’Þ Ò¼XæáÉØ6ìF7ßlƆÅÇ›GñÏ»—}SÃjcsðW+šý˜xÖo,ë�ù¨áŒd̶Ü©.ŠÌ«7sSóË.ÒöXëi€ñÕïz(6¸1À;fUëz°ä5˜¿g~OŠ7…6ÍiÃéèÏj|Î=—bÁÂåMzl_ýÕx°hkm£ÂÇ ‚ÐÓ[³ÿØÞ@ÖÏþÏ=–ÊŸž”Ú“¹ø^¼ë–.l–¥¡XsJ¾ lz˜ÿø0ÉÈ=dá ?q�³��ã*XZ‡_@µ ^¸t[{¿é½¹ "wÌ{Ä‘½ãqŸçàû…IÁËèÍ­ý{~\í0èqb‚å¡ö¡;ÿYÝ~{t½Ô˜˜š±T‹s¹¨j2�5ÁËû&ÅMàŒ<1¿ûÚË7½pB…ÎÄ…˜µ;ï4W… =„Ǭá}xWû{Þ/&@òl°&wú8«ær¢ê p8Œ�Õºµÿp¶f·F6ÁÅ}#ÜcHc6obêònàAw#üó:}B¼Vk†#{h]è²?Ѓˆ-±ãŽ^ ž�}TKAeåþ<ßèQ>¬^å ÆsêíΕ•�¯Í±†•¥¹ÙÝ÷í‰p«‹<;/9SÂh½vŽá?y�€W,’C{®�äѬ„„nÎ) óØ"³}ÊÃH/½;«ò%bñÁ¯Î{Þñ‡/ܰtïyõG0åôtcó�~±¯>ºžå ^nèHDë^Ǫ$¸½ôRëpEÏ­#�î#˜‘c�õ~�cvôìx áìr“À5yi´^îÙwžBkbÅÜ÷†çP×dž]gÞX!9ÇëNð…%n ®/)V‘Ü8ί›ÂÂá<ÖB†ÿfÌïÊvƒ¬\ê ÇÜŽ5:×Îp̹·Ç €íÓ“ä¿åÒ AzNg'Äùå\w©õ�= ãy]c¥ûúÇ+%X£Êïð'WÉÐÄ­\^Èuú”´ Æ^žk§ìŽyð,E{ÆüÌÖ[Ï0àÇáÄÆ�Œ7Vçpµ.PÖä:*ŠÅS¿#m„§ú�KëAVîfKþÅXÎż´‹Áö»þ­kq¥S¤\Ã�­F2Ífìçç³Ààôøðˆ‹rbwîõOûõuLظå¿/8`Âãô´þ t �ÅÉ·“mÙÄ VÚWœãd�÷åAPâlÕN8ݘ7ð¸pœ|EÁ7"ò’ìIè½Ã”‘ØúIÎðœµyƒá çÃÇcÃõ;Ï—#œA|ë=±ZX®ë¸½D3ÐÛÛÖÒ@Çë77/Ú‹Y<^÷²¹«=g¬ÞO0g-ßò¾=5‰<Ë7ßtàÿͶåFßg¼çEÄpïJ¨›ˆŸ˜gÿò&Ò )–fx㺴çfþæpìÕà:Ö„Šd;¿apºЋ¯¸-ÀZ�aàκväA¨û8ð;¾±ÓjŒlÖ'ÎÌÁ.GfŽÏ€¸äÎÿÖYÇ8Ÿ¨,-õh_Y8¢á`’Ä¿)¥?ôduàND€û`t4š#x4pc´]^`gXâošÓ+ÿC G°ô2}LMÊðœó•–¡ö¿{N4ÌZËñL®Õ4F7ó· WÿB©ïûoôÜ�ýûeáQuêP÷…•rR÷)k˜† "Ƽ ¥7·#˜vöé[в½õ¥¦^’€/iy @Ô[?Qñ}n<™_¾ÆS×®ÛÌÑŽ�aíJöùðD~juÌôbëH¼În¸èŽ-k‘én?¼æNÐ`Λ’çÕ�" À80:;¥¼ãÓŒ)J’#5:èsØY'v¼¼0ù:’�d”ý€rnya9ç`Î\²:?ºç?=U™*5� X°`�íüœóÞaщHGü©˜2N)ö?ç»é¬DñDk.ÖWO–­ýɵœ`µ ,_¸ $h×á*àë'v†ój9¾"2 óIÏæcx㞀wêr¨4�Èú…×Íç‚Y7[,=˜ˆÈcºEâ˜+§ñAé8®$Õ–Íô¥Ò±áKüo½–�~çÉaÜÖ&Še<�Ñ2Ÿ¾óÖ8yÐà><¤Ñóð³$ÞyÅ3üìsnùàÒÝÐ�³Øç•±¡2ÙáÁKlx…ÄØ¬¥ù…p>»'šD�ÿì÷r§6bÂíÚ´ÆŽ�Çñ§ÎPÌÕ™ó€…xíÚÍ!_êhO"sèp¾ø©cà…)Ì óêȘä‘éÁ•Æ0—¢œÓûð}ôà4�æ"fpîúx¿òÖŒ�G˜šœOxò'–`è@ÈêéM~îGÛ pšý~+ì­?¹8ŠÌ:’"׃×J¹ÞwŒµvÍÄ(–s´ít¹6ÇâéÂÓ£ÐÎùYâ†ë‡xÆYx•<æu�ë"~=�åÔÅæï±XênÖ °Ö¸ Ï’ëÂ{?;KσoEP‚Ñ!ÿÛ.²‘è¥õ>¨´äÆ÷ؼÛ�„º‰ñ‡GîíÝ òYh‹]ƒµÀ§6ý`—u±M|ó/ /ÄÖh òÁ¹.´ÂØdœo9z9¸lû¢‚u:¢…ƒ²ûÕëüèÑ.û¥çí’ûü!ƒ]põz O‡á'†:ç!ìâìxâ@¹&D¨ÚsóNÓXxŠ�èf¤{s}ÄgÐﻣ”2–{Ù†÷Œ†êbOĉk|Îi4O¤kï‰eíXXÂiŒXN­Ú( >r-~órŸØ–Ð ªÄ8ØÛØ–S»��qºî§F,ë%5KÄ‘Ÿù½UxúS>r¹–Ÿ^SÜòo½tæo\ÖÊ;'ÚÚ3Ô¤§q..öhüÊáÚËåüZSƒc4�þ6¡1ĵ^p®g‚ÊEy«s¥Z(üö=yÞ+ÞxÁ;‹™áÍì5toÝ §I§Å\–昼ãîº9×yƒäÿÝS%9½²ð�¢ñhƒX¤Æ«È¿øªÃv׉�i¥ýDÙÓ–|ÀDZâ5ëxÅN4Ÿ‡7Ô_GSWØ—vœ„>m¸�Þ.Í OŒVÄø—pFkØst>4ˆ'gZ}µ»9ÖSkpL�‹%mR;Ë›  1nË.o`hµ¶[(`ZsŒYèæÇ=3éó¸&ë�m5$޾$Æ5¹ÐòÐ,Ýç7~´ô¬X|NœG �+Ç¥áV÷�¸<£fR$�ŽË·¹¸�¯lƒã<`_Jô�ý9‘—ò“Z¤ET@yø½Ô'÷=ç•‘ë@›ÕnÎÆçºÐ† Ks•°±EZXò>žÿ�°3QŽæqpÕ¾ÿ+ï�‡$wæ¯U·-‰A�vçè$32 +ZK‰¼Áðè![©k�¾WobfMRï\ÖI =ä× E8ØÊÀ“ÜKnä}­%(̸"]Yï5dî`|.s“Sk7‘&_gƒ@̉Kϲ% úCP¹d9šecMkã=:S‹kÇ¡RœŸ ž&˵°Á”Éi—ãð°x´@§qøì/μr2ó‘Óétï=»Í�f_óm•|¬Î‰²>5,GÆþ#ÐgÔ�:dÕ~µƒófôF®(Ÿæöl)¦îÔÇJ°jd=îÃE>Ðv . éküë3¾ðäº9Ðù3c~�Áƒß®L\ØàÅ,æ°ëñ[HƒX„~sc) *ø4Èg^8Ò4­†szFl�±Kÿæ29ÎØ&€sF/.»UÕÓëÔNþ�dÖ¦{¬óato � 'sÖœà’ó¯Ð'Aµ�êãz„ <3Ã[›«�,¼ã^ ×6¨ÈÌP§¯[²·w 2mu ç­|å´Y¶ÓrTÐóo|îÝô¹¤ÍëS�³u&à•_á,oÝIôj�;׊…†Ã¤qµ®–qó}½9°'÷iÚÚ¤ÕÓH£‡Ww{gÕöhÛsj!ž·gÞËQÄ©%1ÉÄz} ˜ÇßQ›ˆâOMð÷¬ ór]½Ö©büš7Å”à´þÞûÁµš·ºFá;Žú¢ñ^ö©Â “¦¿hd 5ê˜ÆG-¡Wâm³G'bÍÃ8Þ>£e‘VW�³1c“1¡óù\ vô�Éç¬.>«WÏpë×öîs¿þ¸ñ‡ÔzœëéM²C ­Ã–öoügæ¼àó¢ó¼ÉN-Eƒ¡WÚúúuoþ¬êdçÈï“�0QnÐŽËÔÚ@2$�©s"¾Ç¡$ì‘>ïëªg‚ '¤ÇâNÎÙű<ž§‘>7QšÁzcuùB;‘WÆsQv±Á¯ùÓœ7¾!¿¬a‡ÛzäpMцüÕô™éh'XÞ’g=„ÓsȲÖt‡|Ç�uñæÒÆ�u ºj:ÑA¬³Ö~¯sjIç¦=X_ß¡ûÿô£8ràgÖÀ’‹kÎ rë^פHú¤Ç†SäáÎie¤VžÌÏ7¦sßPo±ÉÞŒ·É®‡ì³¿ èŽG±Çng<°ï:&èž�ÙÉeK²‡PK岦“$šNÝ{Ñs°!6Çê‰É9Ì?ún7àÝ.çî�!Ò3(ObY™i+~8oZòjèná8¹äÙ8}hÐç:"‡‹€§×NÌf4™Kû°‡àA%Dqˆ×aM¬5Ì�ëÁ;©ö†8DïjŠwÊCøje=™¸÷[¦Î<ü~ÊÉæü›[ÎP™DèxÎ�ÍDŒŽ„¦ž"w âzÂw5¾z³V.%Iß±„~ú_»}âÚ½³Ù¹—ãp¡D:,¥zÀXüô¢æ×)¿q•н¹á8p‡?ëӌƻصQ˶,¢0ùúÂìZ ¤÷Ù§uzÀ}OMŒ0­~GFy²¥¯A–u ÚÃË¡¼PóãG¢>×áÒ8*¾ò‹ù‚È}´à±!b] 6òmœmx/,Ç”°“£ÂU‚„QÅ?0Ÿ"Üðpx8a5c¨Ù½ë&k*Î#�)à\#÷ÃI•rK¦×�f›ÂsµçõSim‰­ó!=Ú¡âõí׸6Žè͉X8tœ|øTn¾þbûŽ·wÖe=áŽÎ ‰[/Y»‚’ÍŽbÎ×똔á¼XÄ•{ ±N;3\¥0¢é´&_ã'þ] &zbÍž^§.T… W8w14;߃'ÂãáÍ¿!‰UFHÎÍÁëâŽÕ·Ú˜“6Á©q}À6RÍ]cVëe•,g»¬K @b©p}ÉsøNpt›_<‰nrŒp‚ö‡ïì³È½zñ«èƵ�à\r8-'/"ÁîVêÀzOÑVøÁ)Þë›"”‡¿\nF@p߯gI¦4øyúȽžÅ6¯ûƒ6S=¹µ·æ8ÂGLí®ƒõ[oý“ó$™uÖ¹¼Ä;E t(cù]„K²�äò�Áœëÿ´‰+µ‚}Ç»C~×Yˆý»Vhs|ú_€ŽAøè7¯Í,­wyØë±žeFìì8^˜ÕÔMÄœÚÈ¿¾cue6ý‰ $9‡g†i¼Þäô@P.”B­MžÕȺŒ¨&éÙ߯==J^4oKrxMn.ks Ô„ííçõt¥4Î V‡èøS?Ó6íŸk«íôã�oé¼�IŽ�’㮹¸côåÞ½ôöÓØ4àj”®Ôà+AsÒwôêðç30…„ ÿêS æ€öcùИß4UawŒß(ÁW'�ù–X}²âç�Kb@ƒÉémÎ1ka”rì÷´.ÿr¢ci|A»õ8Á›ÃÆËq™¬ê­âDQ?¶Î­E³o¸ âïÚM.Ój>•ÿ­c5Z…ó8Š“\ÿ¥wÛK|¿u�÷ÎrD÷ìÄm�ŸJ½G�Fúqs`™ÿ)ßXNãbN”�Ç¿Åê?{-°Y¢ÖGvWW›=‰2“„¯÷–lQŸóJÏf')€2ÉårY»¨›‹˜=ÈêtÂ9Ÿ9îýì­õÆoL÷ë "JÞEÉ ¹h&GN6.ôX¬ÌöÜ€ÛqGÐóõÅàÜð3:}4—íIÀœ“óè`;¼à�ÀbÝÑ?=67À«®aˆñ 9ühn¢öSÎ�û9õPì‘8þê­DvÉjµUz÷W£!vˆû“DÙkm›v§Gö|³Në,gq™îkÈûÕ(hø1ìzƆe0ÇZS5P‘&ñ½Î‡àÃ(þ<œ©±oÏð2V8_ƒ/�Ûg¬8À¢žÄC,#v÷YÖb’Rœµ,¡·:1/¾pÿiŽº�)i^ ©–Gª2õ÷D�¬Î³™‚ªýÄÇÖÂíûfùôHb¹=�0œÓy|Êï´4 ÑÑ1=aÖˆàéIJu¸¹Øð„{š0aG§y¼·õ\¿·®ð\âDÜ#vZ£ ƒ‚¸öÌ ce2£„�Ÿ…Gî7°Ž³=Wó¼ *_$“s5š™“ðáÖ\¿1^?£–Tv=-C'òîÏ9­�°Ž«)=ÆLc×àÖ»Eá7èâò“çK÷-†ì©sÅaÍpOE‘~% ö0»{N>cn꫽˜“�”lô|Õ†Øó­)$ ÂŽIpÙo¥w Gxìœ÷`÷ƒÇ\ß_^ý€*i!®æ<…ÓΉ‡â‰Á×’/ ¿ë*5쟻 zîFêH¥˜k È•¢�ÃTG’Õ‘ú“þœÁ�)œéõ¿øR+¯~x©M®�¬º÷ H,wüѤcÈÔ‰g8°M—ó ìÐƯ^iÏî#Pû�w7¦c9Á›OçÌáxób±ïžD7ô˜ïO2,Ÿ½OüÕ¹úïס+QáSWî�G„–�%SšuÒü IDATæ¬á]mÄãûö%y¨ic•3ûµ ¯žëM®óÐhºßž’ƒ�«—íâf4§µÈgà6p=‘,uDÇxèýÅϺÚ6ÇÞ>½œP–×¹ *�;õI¯ OéÃ°é ¹|=¸þõlØè…6X-”0uŠŽ4�$þí¡ã'ïÄÖá\>ãà~ìÄu�mñ¾ži˜aî ½(ÇáIíKÁ µÀyŽjf??3ù‰s²çµ{®qÌÓ³X0ËaØ£ÝØstŽæ±¨Ûþ„f' l=óî±/ÿ×”œ¯�ºsÝC½{Ì�k£ãª%}Ÿ§zðÑ' þìØs«³µ>c†Õ¼žbg}ö"XNâ9¼‡¸c•8ûÉ£'ëÅÑÖó€22Bð“ÀKÓÈÆpEó <ÌNgBxO2'QœsB¯5Z–ç¡uYDpÇDñk€½Ãá§9YO&ytÎÒmíÆcÿ3> 1Ø@®é¶ÉÎ8 å:{ù–o@G4V°±Ñ“¬8^"¶‡?Ž�[œÞsþaIìòÈ>?šÆEBì«uìkäñ�»s„òÔ›nÕ®ÉüÞæ¾AI:‡OÞ6`ý ßõùIÝJ¬Ù1àUSÛú™ý ‘Ù|®K³½¶ Ñ%Ì~4‰íH'/`P³|1Ik œ`=g5]C¸)4¼µ;ÜÍk�­Ýkø›ÛµÂÂØ— |îóðÂ:§|Ì>HädØò…ú0®™jV+³ŸIrS#¶ î¥�¸™s45û‡`¼6µaNŒûümýÄËvüâ·´ÖéÞ��;Á-—cšÃ“ áA•ÆGç’<¢Ö€ Ýwà%yÖëšÒ¾Þ¿è{ÆÑ¯ÅÂ[ŽP¹·£—í:NÇ,8Ll2¥é³Ñóán‚õÒ1:±7¬ñ³Ã‡ý¡8®§ÕÜ-KºõˆÚqC&À!ËÂp£_ßMÍ`u\ÞnðXÄÝŸ:eŸŽÝGðXQáócO{¤Z¾q d÷ë„¥>öÄå)&Þ5+ÏúúË“¥÷ÆjåP‰=×ýNÔRßtz/E£t¼œË|82ÄÔ’Z¹'ÃO­ "%x®ãîМØ#¤ñ.†Hkº¹¹÷š•™%_4dÜšDç÷˜´êaÝJqyÛOü€.g4�ŒW–™0˜K;t8ÖYÏ6­re€ÝZ³k~öw™„­$=GfÞ˜YÞ Ëíµ≮‰GßbÞŽiŽÎ ÈMÌ^_:=dÿÍw¤&mŽŽ| ÇÍ÷ËãK¡0ÿàõ@-ª¹=ížq2Ÿ\«NG#Ö†àóm¾ù5[‡÷Ñ]·vJÀdQ§6÷úxÁqÝx×ü¹Ws@Yˆ†<Í¥>ÚY½n¯§±¤¼!ÊÇ�¶L±f¯öÝË€}ýÛ×(HOw=ìW!çÖKú걓SÊþÔ2.ܹßVÄö8xú,{ëJol[¹Àt¸_š®9’[øœ<ס‰Ï«ãpæä0Õcw/“Ë}{®y#Õž®Ãõjkºsíñípz±é&8:¨M;üë¯}:Ìô×pj�"áéQ{ >†±Yè|5`b\œ7ßœîE¢¦ÅéZñѼ>É‹‡1¾V­QÉlµ>k�ûj@Ýä'^�aÇbM­Àja�‡¢èÁ©aÝŠõÿ§À^Ç®:OߌÕéw|òÖ‰MyRç @/c9½Yüfu*ø_µaC—}@GLì6ž‹y®…{£À|41Q÷"C:ò¸�§ôÎËÚû£Y¾5nÊ|IÃUjOK^7¥<.â];´áã|˜e{/øãX”æ‹g½Æ±XC¨aœÆl_'&N·‡8û} K+¶f׿'¼qÖŽc1y·|é�ø1 tîÝÉg ÆÚŸþÜ>…}9è+yòÍþ—É)ñ7·ÔÌpž/¼Û+$ÄÇJƒàêöþ9 ?°ôLÞ'Î4Ô3£|®‰ùI�%t®dÉË�Z/8Ë$qào½&-6Yã3å£ÂÓÛP©ääû´åÚ�£½lŒ±  ¼“×8Â^¾½Îâ²~¦ÍÖ£œglIô›øx/ý�yœAØ’-ݯŠZÝpºÀ˜#Ñ;//^À‹ýæ]dgãÈñxª8Žõ&fÖ ¿L�áÈ7w±ÏGþ…ƶº2}ާ¡p¹×“1»V Èv|ôô^*‡cL d7„¬è–ýôÉIW þ^SÏzo­<æ0ur»&ço­¥%$R^qXË¡9žëGózˆ5TY‘—c=4V Ù—ãÉ�ŸÁÙ±ÞÝÜÙ6@“ƒÉ9ð<š ùòÓóƒ//W~1��æ"Ø#«? ƒíïPÔˆËÅ>ýŒã¿ôo~0ȹÁr_ý†»øÛ'Ü_î=È�ÇaÈB!­�¦°/¿¹¨e�þ Ä ¨yñþS.ÜzÜë—šmKPD“ Èi9)^o6B¼)�~»òCÞls_œÆ Þ'¥2gø»”¿¿I‚.M o)Æ\Ú×Ñ­í¬÷Ÿu:HÆ'&×N¦Úrî54/µ)öÞG\¯ŠÐ”A�³×*§+I“„>1Ìw*‘GþÌÎÑÆq‚3øÚ[¯uÁå\è n�ç¾·{–zœ—Ïû÷M%ÇHâÁÙÐD[×ïx»â§>À¥ÌDœð¯Ñ•*ÀÖa4ŸÞMcÃÈ_úLò1°o½ÅxWK�€Y‘p<ì;äs?u::lë›Á' ñäÄILð¦–áædÎ÷óÒávZ¸‚ñÂëqЮ[~{ê­“ëúæA ~òµ<ÏÁ$ú¼/ÆØÚ½{äzJŸR™ŒíËpcÍHþæâßWâéÐôÇiuZ^š�U#Ñ, \ø÷Z¨÷LöÃÅâŽÕÛÛ#ò^`t‘!:ßxz‹h÷F8r½½`ϰÓ¤gçcï7Ù`MmÑn‚êr ÏØ6-Ñ\òS‹ÙNMA² ÿ"“•zÐ~ê¾nWqcR“k}0�¤ÛGC×!D~j{u r¶ò4øjÆi¡é,q†Æ†7#uÎê̾׼¶¤�%Àìº�ø�ÞscýF¡ãÀ÷�üÄ®—7õ3kõ(«=uã]Ïáô‘ª«�œ€u ùJÈÚfFn"¬Qó†ëÅÁ0WȆÃå>Y‡Qòͽ|»Î–gÎÄ»·rXЫI†¤·N£Ï�&šÍ¸ƒ%ŒDh Çz¶XÛÉ×Á>Áp_w¶?Ï<®Ý=ÌzʈY^lOºÖË'÷b¹úÀx´FÖ«…¦[ͧùͧ°x¯Ç®â�n`£'k°Ÿñæ‡u)ÇþC«¦jJ�*i ΃fâõ°v8>è›õàÍò€ØWÿ4�ãÌÍù»¿ì­Õ#AÑB�âËúè¢÷àç[�vq:ñ©×vbìßù^Œq`w0¾¥•‹z}\h«)¬Ä,5‚Gv†÷bCšÙíd¿E}ÎýØ@c;¹à†ŠÄüÕkΈ˜›ÄÅ`z³Â�ö×a­/çšW³‹ÒÞÝPgú¦U{{ê6½¢ÅûÝ¬ÝøOKOZgúž¼fÐä> ºõ�­oz.G4i9–O:>zé¥õ^€ïoouk(vù(Ãc¡ÚÌ÷›×íË0�öt$Чò÷�ƒD`7_4ã|âÁk¤�§{Ü>>°¼½çœpLK pì�¬_|„$ªh×=¯÷µ Ÿºnk\€uiîß…^¢rø›Ž‡ÀÑ"¾Q6PSïnàÅÝ�éMoðÝûÖç$.=×Cký‡rùg"8²_ýÛ…ùÆ{bž®¤–ÆÑ°3&$:É åú´�4Z¸ÖÅã�¦×ä1ËŠÍÓb‡CÆ �žú¸ï>8w\g/ÎéÇ3NTN½{œ0gò­<ª¡nOæ†>ŸÃ‹“ýø�;.|þÁ‘Œ¶ƒ÷;ÌûZ·û);qŒÅ�'ùŽ÷༠ÇSw�“žþ˜Õ¼®CA«/ˆG» ¹Þ,=–GóÍaòhNs­g~\¥)ª-O÷÷x{ñƯ¶5¶¤Nl?5¢s�Ú¦�wvŸÁiàcÏLÌf| |È¿kƒÝüä÷„Öå˜Í\²ŸßÄ!ö“êCJ»ã7T'lgfãTYt]ï±eáDzﮮ»s -<_Ô ÒÂþc\ýû©ßÞ�F§üO3œƒ½¯Ö]ò˜Ã¼FÓNㇱbøŸÁΗ¬ùæ"&ߘ„Ëšp*Þºÿ«Lì7_ ÷F€ÿ\­­IÜWÕDÓ”Íwz¨ s�›>OW8m~NCZbúóUº€ê•.ç41ƒ0Ó;ùšÙ³Õ¯§šzƒ§Û=Ef¡.$Ëq�†GRw ÃXC8ŒãÚé9ÎÄÆà>š{ÌÑBaãíšþs`¿×ÂÐ{Ið;apç>.§ãåO|ò„áæ#Þ*—ß› ¦)9VÝåÇÿêsÅ/®,ŸZ—†"Köòâ3‡æq|fÙÁ~l2}bÀh,O¥"ü;FÃÇGÀ Ê70NJtóO_¢ùj2ÌFVÕ±ž@³ÎYqä^¸žÔâ±9Žý®yˆÐ@ýÌî+ÐkJ� MÏü´¹€ß4%r›ºfza»oŽ-péÇsbPœÂúúQ­6Y_Àµý’^ +zeÄá£LîíÆ ó'ÿÊ'oHšŸÈ£Þ…;›×.JÏ7‡ÁèášÈG}Ì¥$Ä~LGCô‚AMx£x(rèÌÂû,Nl ÏÖV¿d’wÎí±Yœ^à±멉é 5ˆ¼|lW¨û$PjÀ[±ÐU×v³V�×7d’{…ìØu€$9¨“Àô »×yî!A‚#Mäãë�ñ4Ö‚BmZƒ4Ü ¢xý=ÂäÑäLã}`¾„å›Ù½ î餾÷âË»-YÞš½7ÏÙÀvJ“ky\•(vͬÁZ’=qäãÉc!Z;jÑ´<ÀÇ;|æQu9Ì£M�Ö§LZð1ù2¨Çîž)ZޜˀoZ‹ì^kãgãOø—b¨s= &÷ƒu [¸^Éh½mŽ?g—ûrÄ” «ƒº–·ÞÓ[4Ì·¬MýÄ>BY§sØ©!bDZX¿ýc-“ìhõÊŠÁÆ w^WÉ{¾>‰ÛùÒ£Äa./CîÏM\‘×DðR5� 59ÜN-×êÛm ¡z‡¯ƒ=±fVÎÀÇ“ØK0®óñ ÉtÇ"Ö“ã±£XM¾&ržkÒbØCk(Òsu¦§7_ÊaÁòj›¸øLÈÛkK½µË|Ó°†ÄD«øú}I4GgAžÒO¼¿>2n?´ÇÄñôáH§ O\j~ð‰ôôI;×ãìm:ÚH³:H6úóš±@ø¨�kÃŽ€8ÏöJ´†õðá/ót¾|ñ“§A�ÈÿGÛ¤(‰yQƒŒù�LÇ1?aî•8Ó³‰ ÒkJoÒ§ñÀ›¸ZÀZk°×áÝz´îOìcw™êü«gXtd-b¸Åuz ‡Qø—clã3Œ`†`Î"ü½>E’z 98³ ÅGã¸A¢™ý›®xÇ=ØÃ×ü�@–¢Òç6ó &‰�#ÃÎÉyÏ…+ß´¾1¡…PÿSbûx{:nßN¹a 6åå<ß°¾Ú„=³×‚;VšÜEzE�NøS£V³×÷L‰«ãO½5œ+˳6×’éðM¶Øãûæ´.ù¹†¾O&öØ#ÀÖ‘//˜æ�JÛ‹Ä— ®¿—ãe÷ä¹ýÒÇæ†d‚ã¥h'¨ òËÚæ‰µ�´÷…EèÃeáÚ;ùK8Å88Ìóiö¾v§ÂÇ�my-\ø¦íY;–qó 4mÅ·ìã%G|6ÖN„£?qá§w÷í ²šÐ ©t8:uðX.Á²€/gë"�ž»6%´, Þ59r�ᛯɠ2f¯ÀæA#¹Âì~ñE�\Ø›¦ù†©�â ®\âK½ !ÇòÍGN?´šé ˜žÌŸ5 ×A}5nቋ–û&1AD¢—)þ+[âÆ’ш~ž½Fp`è¸ö"Þ=±¥©æ‘HqmW;=ôдv¥Îäfí^e½oßí+�Oÿz�ŽÖ+?œÍ½|.xbàâÏŒ”ßœŠežÆ§ÆÈåþ,¿{õèƒíÕñÈqVŸ3Œf4X£6Ó(ç¬�iغµ×Êþ’ãÞËŽŸVXA– ÛL’kŒIG¾‰ˆÝyœH{›6à ôÎe>vÏŸŽõrˆé=ÜÀÊ3úÅœZÜyþlïõüí"w­˜§³ìßWßå_Ì@¯üМ"þ�=n×vêKsÍ�*üÅQše½ÖüpÐÈð-�ýí¾£HóY Cn�ÐìüªÏ;ޝ"OÄÃÉ<�'Èë�‘Ý }žñ'á›k�"•rZÂGzõÃ/#odoæ“l¸zšÀ÷wש&¼é)ÊÒñí­'‰'­3}˜&ZÔHôôÈŸƒ‰yRz¦‡/~ �†Ûm’‹øI6Rë+/¤—á¡ÕÒÕ(‹øÇÃ]o½®„„Í ×€ÕõâG½/ù‡‡I´œçë�''¹r%È•ìÝK ~Êb§…ÝÚÚ—Åm“b\ƒ7Nàl—ã]“#ƒÀê!oÁ›‡zgÁ;I5@p9Hœßl¶Ñ>ÇJˆk¸'.µC¡�N­Y`C7ƒºrr�r½}_›û'Ð7Îö<,dòcœÌôÁ¹ŒI®Ø]Ž|ù2Þ8ø%êÃÂ4ã«t›½& P&­Í¥-~ê¡ÎŒÖã“,ŸãZW]æzâÑ®ò[”$É.LiÚo¸jªëV´ß¨ÑL h�lb;5A0œÁo°^œ\Ó1ŸRûú2޳bBR²Ó«Zež¾Xt>б^Mæ/ õ�èË&×|=á¡*¹BÖc{“ËZ€Ú^ã‰Jªh,ÕýÅø:7Î=EƒtÛ0qMl^N:þ¹&>oncßÝZ ¶ÅØÐ6îDYÓ÷Ç*&}MŒ}²3BS‡DøÅé^°Ø°üÔÎ9ˆÑú�â± 3öÆZ·6™AiÈ�ž3Š·´”xõ°ß:±P@.û´>ˆ•ÿOŽ&œÎn3Á¥áj¨vLÇN�åÛ „ñæußìþÎOÌê„�'šç·Oû£û>.o1ÖY³w€w¸�By_½^§}ÖÖësýª¾oŠÃÍâ­û]·Z¡]m^Éöø²Þ›}§&F§ÆjÈmWZø ‚-NmZVû*]5€§€Ëçšñ…%ÞKáÚ®iøà �ÆrBΗ!.ë}ê÷¼Ž³vžð:JÎÄGþš g}‹­Éaœ\{°÷°ÙŽ|Ó£­žµ9〄MoÞ­w­Í&ü‰9±÷µÕ7+Hy >ÀÞØ-Id伂\ZÿðÈb!-D“Çò0·Àม1%néóÉ=¡ó»AåY¡¨r,áZû&¾(t­© ˜éhÂñ¬¾hLD¾È©Äh¯Ù?ý'‡ |ñI>.~a»Âl‰®`Œq1é…ÌÒè5yï}ã©3>âÙéÑŸÜqJýƑþò$—€?úì65̇BíÈ N?Ü×oç_Ÿ©It«í'�ìpøš•Çý|WMzÙøÓ�pXq…¯Þ«˜ÜÌè’Æpd>äs`;<§1]wYÇN ‡µhí<š�¶úM0?™Ü/“Úu¨Á“¯\¸ª¯Zh£-ÇŸÜæ¥^=7¦Ì‡¯¸æ(–ÚΞ¸�PÃï‰�ðèS_®Kaß½¦�ßõ¼¾»¦ÑÒ\¸àÓß;\Wm_kt3Èõ­Ï�é,éÝFøHËÛÿ·oñ›õ`‰8×@y¦“K±JÆÇÒw7à×…cTŠ3¯ë„Ùž�3Ÿk‹[Ã×_¸ø’�4®äG‹I™L"8;Â38´ÀýŽí�“$×ùMKGMcÁè8q¬Ù{Õ<ÖóMY¤á^û$ jðµÁ¥Å´­6§7¯$Ö©³O¯ÑV— µ®!õ'‡èrÂôÌñÂî›òS®ÿM°±É:E¥Ã��a K{ó²–)}É�9Ã<ÞߺµJ�&=Ô,`c±¯W.WZSƒãÔné|ÍØ™4÷…µœ$p6_²õZ;¢ä˜L¹4 ôµó2ýßyƒÔú–CÀ„Ùà×›üè}¿v˜þüo¾îà�›SQë9&÷¾äÓ�k°ioîÌ­±Ò¨‘c:À¸îÃíî6>= ã`œëZÛH=€Œiؽ‚?žœÙ%G2“ƒBèÚj_’ôÀYŒ“�i‰Ùo3‘)4#n jTøñ£§9ѵU³ñv%Í(̶ØlþÞÑŽÂÆÛ{•=Ã’T‹ÿÐ%‘}KÏôÆhã?ÎÒ å£ )p©:› >íï›êå7gu ãûg$šßû‘¨Ð–P››¶´¹ 0æÅOl¹§†Úνd8ôì„¢Ø;G¶qÛÍVcúk‹énÄ�žép-×ëUô–N0³ÁŸZÛmN Ó—lj˹ÑÚäûá ±7Ϙ\ž”Çì8òrÄŸ×JöØÀpÀ‡÷ì'ÁÅÛ̶¦ä€IÃ}Õ,ß·v{ïɸ‘4è3U‡ ÑÁ‚u¿m-“P‡ó£3|š?ö¢Ýùñ±>µ>qþ« ö"“štæcô ·Rñ@�Ø ãqÚyCXÞøþhtÎp䃹,˜p=dv~ÜÚDKsSÛ¡¸«×>=  ¦0‡Ñpþ„M§óüøŒ­íàZë« œý⿸£Ê ìÉ!0:4Þjbyx^¡„¸QCÝ:áH€ø²,ñÊækÀBƒËâzXxßåvÆOP`å³¶;˜SÆkW)õ&4Æwgua�ËdîÆo=Õ "Ú°³I~÷ Ž}Ðú–›Þíµ=kb'Í<æ\OÌŽ¨;Ö‡½ç¿V‘Û¹4¿œØ|P ãG‹¯�ÌŽu¡Fi/ ØÅÅì3¶qšµqÎÛäŽ[,~=�>ø¿ÖÏÎTå(­¢C´8æ}�9j“ˆûƦOÏú�™ÁpM$œL>÷Ô@ï^¬ kÂùLØÙ•DVÅú�Pa&¢ÎL�}Å5ÁÑ3]䨅ó�_"l¾8~ó�:aMò¥>òëßn!SNÖwÅWÁêE;xæÚ²ÇøŒ³aú¬é��'Yœ•óÊtæiÀ·üdž¤}bJ-ðûA/ôðõ3:³sŽšq±w Æòiiþ¼ ;'ók.Éág?ò̓9LFa(�˜õÓºÌ+PÙæ÷Z�U`DÖÝqt`"Ç8Hû~�Îg\-?ŽbàùÉKëX<óû Ÿ<6ì[Ý­××P6ÆŸ,`y@áÊÅÔåÉ9ŽÎv·¼äØxs�>7 K¸Éë£ø¬…õüµã;xÛ¬ 6öÎsâ]T|Öƒï=´µ$%…ûô¢ûŸFæÃ)í|tkóÄe¸Ÿµ»žïX Ö+Ó¾±öõT‚÷ºó�þå^ÏmGçGŠð4]_ÅÀ�çõLöb=?<ñ’«TQq IDATk½0‰NçZR³“:·ó·÷æÂ‚0øbøÔ�Ra£·0Fî”×p*Á3oðØWïx)�ÿ´¸×¢p ¹§ëôC´N@§DD?žh{u_�¬œR8Ç™;=?²a �ó�kÚâÁ0¿ãÁ{QŸÖ@�¦c:œ·¼óVŒ±fÎ 2Gv5`²§Fjž[Ð#ÈÔº/�aa™Æ»:3óðú–Ô^s�ˆ!ÓíWðq؈0ÂÇ–ù3 ®Í=nLPÔHP"È×– ×ÿøqÌf*‚4½#ÄsX¹I†¶lN$ðLsîméÔë‡a»ÌèH<>1hÓ•±œò5—½µ…g9˜=˜åD™íÑ�Ðgá�WæHÿ± –{Bü2FÝ‹�ѾÎÔcà3-5¡×é aÈN nûàpÌ8ŠÖtz)XŽåë<÷î0=\ùÏ1HeôhcˆM,¾³‘Òi}ª•þÜ}ò‚‹�ó©UW¤y¼Þ¼Å7ühw ‰‘ëŒ7/k8w< -ý{-ØZí"î ~úý»\ðomíÙêc›ü :à‡ÛüÝTOtذÒ6päÝ¡.±±ÙÖ2pÄ�;žž+ØyC Ò@�»Î òPƒÙ eõ3ÃÊàöZœ-½IF)Í g4€»÷vrÛ„ø`‰<Ãi¢Ç•›cògî},îÒ™Âë‰$Êñ{M%KêÉšó·÷Oð|Ê1ž#§á'ßq4þˆr°™r™¶‡@ëwjõuøR·–7ü4ø^5Å奇 Ï`!bÏ÷>ŽýG®bÀ‹…ŽC#µéÛGb±ëÝp燗æ�žQ07£ÿ¼þh©nüµ¡mùl.ßÑüàˆ 5usÿ`yû‘0³×a¬Î%€ÄëẄ‰ŽÞ“¥¹®IñD™Nçh„Ä s´È~°`¦GV×%'3ÆæXksNhååИ~ߨ�EO×L¾éžýÍ#L»á stM?×Ì:…½˜e|õDo�xs¯QÍáv¿=‹ùœµ89-ªÁð¢kÚ¦™™GžSKjj™¦Ö:.ë"aÅÈÆÃ9±ïZñ±q‰­ƒ`r`ð2ùÆg›/�ãà].Ç� ±»¦H4.(|4+¾iÈ|ùñ Ïá ƒÏ¶uomOÒ�×})κ¦]Ï“sk&ÇúzôЃ7TûøÆ²Žù^Ë'LK1E3&Ój îã¤1­Ù­¸q‰E¦`˜ ±£ÆEͬñï7SŒ,}pÝhòêði!±ã#Ö=ÂÕ°e&×ñ?Nâ½õ a"L®åå0ß@3lNø·Ÿ\·Ä9J§hy¯—�]|æ/çâ£{Ü'XÑh&–^¬¾ÕŸ}²Opç?×YšÚÛ¦'>c9¢Ãf�¦}ù¬– ¬ÊùØç~&‰Ðþ qh¸°ø0Äóó&mŒÅJ�MŽÑl~³ì o›Ê;,ÙóLޝE»ŸXï± ¼‡{-[jÇÞØ¢v=Ò7�³ë´šG¼É“Òg篘î |:bž¿ ãü˜ÁëñÐò€{�ZkÅ(ülÍ«ž¶+Þó…Ø7m ¼ûê„ÛZY(Ä€Ç'[x/�غî”ú´aCÎÆ½&Š<…eðf†²^ßùMùV›s—7qKòÌå�4ú¢ž“»¸Ù›O!.×®Ü'ÆA¥ÅÉé5`ž·Ïì7ÀÂåÛ!¹Çü€Ü#y—{yàJ×\x“Ši×Hja9ÓÍÏ‚u¶¼‘9.lÓ�Ö[SCv-�÷\ÏÆ’‚#ÙÒÂ6²ÈN¾Uig�É «3ç\ߣбΠr~ç lrÈæÊ.È�yc÷Ùåã5z¯³¯¢ÉJŽÃ†¤¯›X˜©É'ß³ E¢ÐU,�›·F,ÈŒŸ�íÕ>ÌòÙ_c¿YÍ‹üáÃòîÝ/ ó?·Òœ.Ì8ìÑ6æ4ÙŠay¶$Kò"°»GœÓMžÔNŽÒ‡ãqìØ2ÔM É±hÇĉë�XNÜácq{´ž×òŸ !Åuûæ$‡óà¡´+"Áßï�÷¯ãŽ]n‡+tºé‡‡eëÔí`q¦æëë'qG“{/=á}Xâv­ÄÉZ72© Ä óøpf�߸?Ƈ ×=«Ý:ps�TO÷ÏIˆè^3Xß#g.ü€Pûk11;×f™S}z”> [™ÐÐõ÷Z˽�7+¢ÍMožGQ™Ð�úôDÛr0ûhÀ§G²MwÝÁÂc¢X“pxá#.õì –¸ŒõG0ž=!®€c»†i{—ñ© ²¾H¨/—ý­Ô¸£ÝÛnÙ‰=¸f^ÿ®]a®ÕÒ‡ŒÍ’%îc|‹÷€ÆUûhÉxèwú,?oêiL?3^x^.ûjŸÃþ§Ž•s|'kµá?CÁÄ_,:|”j%˜Ð¦§k>:`°Šü`ôéMÙ“7嚟 .l„ÎE–,ž¢,�Þ"´NC×0ÿ‡ªFö�ç‹M[]ŒV|.䛃8À ¦ —-|Ê—.öåpXó åÙ¥´a? ~q®¯úÈyòl±<ªÉ7L÷¯¾+½Ÿè�ˆÔ>.¶¤ò[AOª›=u:p€>+¿ñ�j0Ÿ¥lJŠ#f= Ÿ"ou7Êâ<. ÖpÍÙ>™~–ä™ÉØn�Â’ x 7þV×Y;û‹n­Õ“œåwÑ{ üÖà�{ã\DIÇS–h`•P×aL‰^2¥µ¿‰Úò51õµF¸�÷€ˆ®sÞk†ãQF¼L¹Ÿá�,|`í'9ø4|=•+¾ãºþí‰k)ŽcKìȆ›ËµéKð`_œKÐ ~×1Žâi ø?,¤Š3ÈòنŹ¿˜á怄t›?Yc™gh½~ÅIG"‚rÜc0¾{ôð@t´Å18Øå…Íö9O vŒå¢?ì�6"'ã>_e®ùÂwÄ1’0?<È 9|}dræÖò­#xÓøÄ^ÑL:\›l0j’ãÅáÉ=ÃÌp>øÎ�ª]¤ÚÍϺÇÜ¥H¤±b=Ô\óÉ¿¸é#�ü«#}�šå¬@|Œcýöffãj?“bÎO@�5¹óOï©= &£Ãͬz§ÅBåÅç|¡3>a‰Åà¯1T=°>£i¾ô� �ŽàcÉÙù•,øz ±Š«#4RªXë³Ñ•– _4ƒ¸×Æq>v´‚7—føâ—SÔÿkßÍÞ]ϼ uÌ /Ûðÿr?P¥�€i†oº\nqÙ†”»\*A¸2ÐÆþZl?[Š-TÓá�­­Ëo);8œõ×6_æôc\'ìI<uQ7ûà½òzœWÝÍ™V´*{½FÜ\pú7»^»Ö„äH|oÿé1þý°ë3§äÞ×ܤ³•?wgm\ë‚™·76½_â°†'¹èéOú—܉JÏÜC04wó›¯þ7öâ‰Ù ˆþ4³› S¹V3p;ÂÐÞ6»k;ÁAsvW—ωø‚üÇ#%»!•Ó^O”É Þ¼Ž¹ñ¤açúj^ê·&Ó = Û¸o¦1˜ôa¹‰_™÷›†³!뮿ÜÖã2°«Æ üsO›žÜ'7v�Ë+�õ–Š Â…áé"Ò»[WâO œ@¥^ÏfÀŒ^8ˆ›öÒG¿©Ê5òÄ ëú|µxõѱ ÉÃo=‡;šâÛL Ö3û)jÌ 㺔DÏõÉaòg>ñÜËC±;p ƒþ¬Gé±é4æÔ˜ÌoHnòaÊ|ãY[ÏôcØ@Èç¾[\h7·¶ÓJ*2D×ò‚JÞQ�wuÃÄsAo ë×wx´@Ò;ŒµQšy.Jr Jæ‚¢Õo5¿µ³õ8KNpç½f`ß| 9à2ŸÅ^�agNc 86v.quN7vòwl�l:?¾›7¹9øç:ÈŒÖþpäØwI±»Ù^+슨4XÌqJ�S·ÎlËo¬|þÂÄ[Îéå\¬ó¡|µ·9ØEˆ‡·Õ Øir²ò,b3˜Ï0Ïñ†Wþ=—vU»ÄL›ë.?½ÝãÃËF´0ª“YØØô8qžu\9£·1øypÃŽNì\Cr9‘Ø<åOi01¨é^oâlL#´4S7òƒ¿¼²·®åi¿ìFšó›Ì~³p  Ù°cêl/›{Jí³¸Wø?K³-5Б;ÖßYÝËÁ)LÖrmOÿñJ«÷î³Ö{]�œ´ÓÖ9ÕfóÆ=Z�°‹ ÅÓÖÞ�WX/u2÷ü!<ù׋p ì2 n dWÎO^86 MnstO8œ&´l-?Ž—~ôòôø�kv¸ÖÄÏø%YlíÞzíÚ~4€õX†gûä E1š–Òh9×ÏÃÂb c,·]e´O}Ñãô��ì »öô}ß$bç±z2äHÑož '¸Rc8z¢)Sô˜¿JXgÙŠ˜F/Ja/xÈHØÙk Nãhô£§ðØÀºŽÆÇ‚dè};Ð0h4ѤÄáÑãÞÆ©x­ö®Y™£9ú£�wä:z/óÞ< ß¡¾)n˜V®‘™¸5ˆ í“"½0—#ò¼„ïÚüp•oµ ‡|Ìï“íÚ8ïÚ5¼‘p‡� {¶ jœ§­E8Žùßü¬Sk­"k¨ãšªª™e,ðgý”íòÙ'·`ŒÛžËÞ²�HÐås�²ó¸5'ž3¬„1¢‡k'´~µÿ=¿ïec¢ƒ×5x¿¾YdÇ{å¸þÓ'äp"°<1t81¼ÉC®ñã1„9ÍH´CÂ7 ü¬a÷\]¬¼©qY’Ðö÷ÈÚ½�~à @S5tƒ!ùlwc| �‰µïp†^Ê’¹þ° bëÿ•�4Ä$]r¥W¬ÉÉ׆YCÁH]¬¢Å]cÉ4áŠæä WŒÕᜂ%7¼\‡\ (ñÅj×g\´ËžB£'qŽÇF¸ù´Òœß-&ÝiÞû榻V^sŽÂ¬:™~~+H Éà æí=þÙÀõªlrX)Ѷï”]Ϟȣp9i®×b]»ÕJ@Á§ ][›Ä<³Mòk¶ßå=qóËÙø9éÑ[HËžd(-°š¡0G»GjL"–gËxšËb1nœGÑùºÜHbt4Ô-m¬Ý]»WÅìŸH¡ç˜ÒË܇þíЇoĹ>%hŒùY{žÔ‡'Øô¤>¬ò|–Dy(eÁbYðhûøéÈÁ�kIÁùÍV9fs‚÷$P9Í…KûtFk¹ÿÓÈ5†š{€ƒ|AÛ/ÃöØ|ñX;úÉÍp-à[ÛÑ2â�¸4|5k=3ÀUŸu%ìƒq  0-ÌO<¡ãXŒý¤ øõ8×DöÔGäÏØ¡Ÿƒbسd¡=üÎ![x 0 £žúØd«NË �)âñNc”9l8ïòæ7‰Šk®£†úÑÏ(íÖã6ÓÓムãh㾟o9=àÚ�ŠÃqcmj/"Íòe;ù~cýu2Z¦§õ9«yv�¢Óõ%§UTæj$�¯my�×iž^®™�ö ½%øD.‚’Ûÿü|†¿Z°@ü:töðLˆv«}3ëm.ÇU¯ƒ‰)f|Xϯ¨ ç¤w“À£b¸’;ªBáØ>b´£ü£o"°[ œã=ó ±Oö‰=qˆ”�\§(¯oa@’¿È¿¼8×Å¥³7¯5.ÞГ…ÝÄ2 Ø›6Í{üèl‡ –½Zœ‹ žCü|íÖ­U8¾Èw}ðÇp-Н.ìY†¡(÷m÷p2#*LSbøÉ5¸ªæÂ�¨Îåd:1––N„_-¢“k9þ'Xñ¹§‚CƒGì³ÎrÑ€„q¶iSÀé™aë“™Ï 5¹Çî|j9¨èŠ}µ¥‡Î¯ÜËiAŠCù§ÁõÉ>ŽÅ­/¤2æ”ÿÃë€Ò€‚ûÔˆbÑUûËmú†^f¸Xk˜Wc“*ý B˜Öv8à‹°AL›7¢0=µd{pËCîùõíøZ늞4ò£÷¸E²Xë9-®“s±¶îÖz }ÝÍa®‡€ôE�$%1�]ïì³PF´n·™k¤õxfÖœã#=GúÒÙ¶è„7ÌÁmo«ã¥Ç S “D Ïzi§NüÑ«…sÕ¸Õ‚uµ$/߼瞶éëŸn¶¶h!|¬8Oó­/ŒV÷ÌÞ ptL[¯×ó\'çS’Á¨?ß<&×tîzeöçLE¤W2(˜øôƒÕã³›®,ƒ¼)J�õÜ•+áúг¿É«˜Ø£Ù×Ö½ ?Ôž‹tœÖ<~ãd#�»wé^®DfOX0ôXU•u|ä üÖEGØ3ë¡Eéeí0‰­“"¸à £uÁ£cy4;6¯5_ÿ’ÜùëK^l¯}×aQ©G ¨×ÌZ=Lœd¢ºz4gïý<•|‰ÊùÍ{xe¼öü¹ _]ð‹OS~X®�é—#{xÌ¥yžÜ èz[«|G7{F¢àöuÑÂy´‡7½9°D€å!à4OGb óÉv¡‘Þ%îjpN´\“ãÉÈßKvÕŸ­°ÇêWw~Xòpié7"EПx Zî̸{æŒÉ¢ÕRêõõmÝ«ïM ïåŽ~ík¦�w,²N;´¾ddÒ~}À?öËE|†5±­3j/içÓƒ“‹×ă«ˆÄÄzhTJÒŒ;ŽóÄ)È_Gؤ\ûœGˆÆî?oÖL6q‚×Ü)ê'† ®ø)�äž1>£nóÖ*CgN/ò92²ÀUýØ’- g¬K Þ!n6+�åX½÷zÉ‘¸ÜßќÞ>|QÙ‘þæò”´í_T,®Õ­’õØrŽ˜Ü‰ÆÓ~”ÛÍ©îésOd3Ÿy °Ò®O^=¬ûä4жé\V×rŒ2µ'Žs®�îks_»¶)ŵHˆl§oàk;õ  ˜fpÎ�~ÞãÇ—¤™›rxàŒì³6�–—·vø°stÍÞülxÀ6ëðçžíÑwFõjOäbÂ�ߨ4_r�†p(t9É¿XVÓ 3#92;æ‰]ßf_ìÔž½r¹MäÔð,ñ´ÌïÌ9�kZ€À»PÞ¯^€IÀ*µ’‹ñä!f½£ÖZ¿sÚŸ0^­5�ßׯ&Þor­åÊç?Å—ÏÜÕıâ¬Âó~•ÿãK¶`Ïi– Dùƒ¶í°�VNÖ+ÔÛÇGlM'ÎMy9ŸqÍŸ/”¸ÁªLÔGcã—m³ãwRÜÁ׿wd±ŽÒ�:Á·<žÛœŽÀ|6ý»;0?¹Ê5ígv´Nò9Mjý'À/¢ÆŽ+×�xõÁçØiцºzàB÷“ÖŒ¶•›éðyÝþcÔXÕá‘Ñvæ¼xØ.ûfKBCúÇ3 .€±‡šô¨Ð`©#úÇÃÞ6 ¿/&šër (a÷šñ�ÉèX€1¯ÖÖ ³Ó<úá2·lÆ·Gq77¬�öåp?›.4ë 'oq¶édJ±Ð8çXtò@[9Kq&ü<¡a˜“E9S§¬„§ûO/0vFIÝš:\ïêð“�À9j3ל!öNËôÐ <\—VÑ_c'×ñ“�û9`Žsš£PôRN‰Š?:Ü Nò�¶Õ83Å^¨ãL‚o£¼ÚòÆ 5Ý� 郯þ´ññeßûfzàëc ÁÉîßLI’Ô&Ûò¡ãôkZJçòï5•ú>cÚ¯'zñ6…æ¬à rÚN^ä€ $8ÖÉÅ9=+®~¸†{8îùdOÙÍ·= ¾©¶ c‰«¹ƒv-ÔÃYǾÃv×ÚñĨpût†êè·�FqøÑh�ñ8ÿ2¢%:„óZ ÈEø±¿šMß4¬ ÿÝ“±ŽÌÑq± ëήT ›vbâ“æ~<7Æ�rÚûi݇4‹Õ�†Ä¶Qš\ouG::Ë+/Ãùµôÿ�ÊkïÞ!ü3~ã áj$$Û˜�?oä ÿóZw=Q¨£˜³J_ÐaÞÆ²>…31¦�ãˆWͼÞd¶GrÒÉNïmì§¶DU»éŒo¨³äôX´Œ^gt¯ÆÔîCê¸É›=¯k‡«|xv½–øÜQ>ã°ÓAæ?Û$‡×ÑA/ßÜÖ¾\rL£çÐ"åˆ'Ökaž^Oòæƒs\ÆV“ݵ¥î$ Þ‡a2 yöÍÛÅ|먃:áÏ›iÑãx8ĹÜÑ.£°±WK$–—»ˆAppXÈÁ~×� 8¸CÈlˆç‹ƒƒôðÙÛþð8‡1ÜãÁ�ѯk}l™n“¡©øÈkŒZ†o<©•ˆh”×R+1~ý²¯šÃ þÖÑ�¦hÈþ9“v©mnY£Maî‰ÖKƒ‹ïuöµ Ì·oè7‚SbgoHcIpsŒè«!ZGÀLPxR?+ÊT§%–z©Ç÷¹ñ˜öã-.Y¸ ¹W½†ÍCa3õÛer »¸0i�º!˜µøÃ¿ øõ;¨+äù-Ç~½'?ž|æ„:pVb8IÂs|àºä}Ý·ŸÂ|ë@×3F?Þ[°3“?ÜZ[c°XÃb5Ÿý±Q#:º²>×&§g9V̥̾hB¡}¶Ü“kÖö)Áœã7²±³Á³5ì¬iëZë<ÄìûMHÐÌuöBûÕZ;�£O6ï˽5¡ʉà#:dÄŸ_<›ÖÓä0¥·Ø­ N-ß¿T<¹#ÝùwfÂÈÇ Žg|tÎG*"•ëă�pž>¯‰£M8¾>ãxb5ÞõzéúâÎ×4 êUÐ"`~¹ÆgÄÓpž·^÷q¹4“Çø óšðÕvkrh Ç«ˆñkãŽj[Üö'Çã7�Oá"ß4Ôÿ°Áþ)ç‚ɣäòyàcݽ'Ûê&âñ§9ˆ>)•ðÁl­™\&ÿäg,ˆ¬ó#¢N¤CøBڑ›åh}øâ°V^<®ÑøbÄiÍ)�¤ÁÂhˆNJ;´ý•q.4w,‡ƒjÏ7ô—ÅhùÒ7ÏùðjsxY?˜D«k*ËÑ %LJ89JC&hÿÍáko!Å’R�¾.ÙÆö¬ è,à§ÖS'¸Öˆ162SÒoïsðƾùjÏl]où2P”ǘðqØzú(ocÐ˜Š¢g\®Ç•F3ñùZxõÀÎÓC2Ÿ½ âç‹6ãdÌŸ€Á¥Ahë ÿ¿M‘`Æãì&±ç�MgjSˆë~jÆÿ$¹×ñÓ Ù‰÷Ã|é³"çh§kiŠéœo}™YãGƒ4øš¿ÊñÈǹ¬Ç¹ëùf|†Š¸{cáw2jL.Kã}fbÐ –Ú\|æJìÚ f�aÌkƒL'oýÔk[o|R˜VV¶²ðàõê>½Iºþ}m€cPOX²·ñs gLÃ4B[>‘çÏcçVô3¬‰~°® ë«Þ^Ð d1&ðéê¼×Ë*½‡•à ˜=ÌïU|,#%¸ë—C�›Cž"ßýü^7â\-~8!ö`G\b“+6k;}à~2T'-Š7[áó[©6ÛNèå�ášüê»uá ›W¥q�ÖápÕ�7Â�çÜû�ŒÊ=UzÆBîŠÞ¼0Ý#ã±¶ÏZ�/À?Zpå.¿q·'CÁº¼þx�@ òæ?�Y[*Pˆ¼ÎkK`ÎK<$3al™‰¯nâ�†‡Ur{8ùG(‘tÅý4‘ö@œ¯6ï޼Е‡å®Å­ÅŠäI|Š˜†Ëm@u¬G¶ùôèboÜ�í±;à«„RVfê3Œ>’ÍE”‡úå´Äؽ,ÖéƒMP¯þ;Çžkd}ÜÜ$QÒrÐÂ5€b:êªÖåKóú‡.±çZW@5ïëÒ [®ór²N‡,6‚7 û$Q«;¼g¯˜Õfle°†Ï¶K¦Õ,Ë›ÙØÆÂ—šœÍù!S±²ØÓÄX£GvbqŠN¿&5ã�ß=Þ:pl°pm@oqä¸=Xý~sŒùX @‘îŽê�}w°!k4Ü�‹©ßðÓ8æôJñåc¿ƒ‹óõ+‡‹Ó4áˆÀ|ö©�<«ÅùIã7/’�¡Nß BÆr2óðpV«%½H=Ц#y`Ñ0 Ì -Î:a±×ç uÇŠ¾8—¶vÕŸœ“¨›ú^kãÇCè¸ÓÞ=ÐLÎôã Ê%n¯¾�±ÅUÎõÔŠ}}ú>‘<ɉ&c_NÖÖlñεôâï ¸› Á7—íæ2™è� Œ"tßæõ¹æ?¹~õÛ /xü-ø:–?[9y.¯I¬ØÑré·9 IDATïýܨ¢+u¾ZÈÔ&¿üIzzßm'®}~(r¸ñÈçê²Ù¬YÖiäµFZ†õ u7v¬öËìJ5Ö:Ò’ 88Çã\²ƒ=ýÅßÌð +³‡k©0ûç`Ž˜Äs4‡™|ÆnýîÅѰ¼[�Ø|?‚F¾Îê×�à4¬�YGÓ'N ´Ì~ª8m¥ÆÄx¸°q r1Ï5ÍûEæ$Çb2wG þŽôùƒ˜ëSWÅÆW�ë±ùh^žÖG¿l× ÜzômòIµBŒmþ Àåë‚­Èh@„ÇÎòí�ž$_âxpZ¬í›-Lñ´'7›Ö»#˜ñéȪ½/skÿ›É:d�®q¢ÿÓ@œ>y’ˬÎgöä8™¬ù‰í2Èçlíq¾�.rW¿?Q �ù¡Éúž¯ƒKpÌ¢Zg9l¥wŒõ@K,©)>k( ç]žÊÝòù:´\Ÿ _ÇåÂh×õûÈŒÛᦠYzTRô=±-¬ÀóÉ  °ÿ|±Ýø�l<øæpþ?ÉI(cµøµ vš5¯UàÞþZ6s'çò“¢— –ÛcvgæIœo^0î•bÑ�±�[vèÑÊšø$ÜO¼�Êèë ÞÂÍtèižÆ³Ë¸÷Âläd0-_¸`pC�3$ Ïj½Â0ýáLÎñ¿¸'á˜2+¦)§/Øp‘Mhïpè»¶øï¾ñÏ„ž·¦ñ¾ù¸>Æ(n=Áï¾ÈV¯-‰ËÙ}$†‡6'vÅ vû�zÒ|1Êa~±ßXxÇóæÍ¯µˆ?ß4›u8žxz§Ç;ØYóÌšîíÝÔ6×@vÙ’Û‹jÎeŽ%fdÀ TDjŒãæ¸5 ¤‘kd”s ‡§,d÷ç~ #¾°ÔZ¿¹í5`b‡Qø¸ÞhÙ}T�SË| “Ç¡‰wNLZ°–<î+µØ2N¿ÐÁÓ ¬[GOz”5çqÙâ|ׇ.™Î[eÚê¬Î7køòu彩c˜Ô9Úôg;fr¢Ó5ÛÑ{OäÓWji?NïÒ?|é{j<\®1l¯Æ£O9çKDÜNP#q‰¥ÖûoÞY{šKk ÉÂó?ÿÝo0*Ê÷†}­Ó•É �÷¾Y^k;zÒ289y”ÛV§v‚S¯ÝØ1Çå¬7§Œ¶Ç¹>Œöí¹£ ¾õ%¶éˆÿ¾–óæ‹Ç#Ú#Y©Ç*ZG¥7Éí³"zO�ÌOúÙ{F¶hŽz`ßA>}q~ ÀÉv Ôä|+«kt#Ã}zpøÑð;b‰¦r R:mô¤þWGê<½…Ýù™‚cž?™ÓË@…qz°°³á`Ÿx-ÌåÝǬMs€qôé­ö£Š“³†bì`-˜œ’Í{és²yÀ|°t ƒ ðõð¾¶ñ(§}2�Ûýö°°oÜ®�{(‡÷`ž/vî³b—ãAXΣ—½{A\>¿@{Ú#ÿå£'‡À\Û“w#5òõ\®äIZˆ?¿œµ`ü Úeûú¸¯î“6qÖ¨²LÇÌoæõ†šÌ¡…k:`©Óq$mâ,³q9ŒQˆg8¬ªñn\õÙ—œÓúÀVlz´ñ«'}Uþêœ>$ÇcþƶW&ïÉõÏÐÞ]]dj�nÇe^5ÌÓut6Êv8-`y;/fø�Nö·¸ÁL›Uù„]p 26rf[H°Äºò«„ÂÊó‰rØ4†ŠÜ‡ìß<î Â3‡‡XïÐÔÄË;LþzÜ59MŒ­ñÄ¡'õ3üž pÏp^ãpiW¿_cZÛ†€jrè¿ô968gÐ-äŸ&îå<›]é1ùn¯D'Ȥ–‘@‚�� "lŲ~‹‹€ìmPDج½ìËÏ^D§Øuxo+ø¾ÃÖâì)¸D S+ŽgÍæýÁîØ'ðw µl—¯„åúÍí>µŠ"µsö0+îÚ«]žIÃ7?¾ÑýoʪÚÍÅLOàZ `ö¬Û1tÑz-ûucò¥†@}#kiίž'þ§Ö£«¥›_ñÖ ˜µ'�‹YŸ°3.G9£"ÎÇŸžÈ ÚÇeþöÇoŸNßKóLC{{z ;z®¶ìžp/�Ç!å¡ëu¹ Ÿ�à´Þr}¨ZC”Ã}­_�K ¯9±¾ÅÚÕÖê>!¬ÎÍ‚ÃùÍybì¥q%eï3qW×tÚX»3³tôÃÛ± �MïÿÐÚ‹V?:Oƹ¦ëz}ëÝ7y&!h�´^¼·oÁr¢eœqMPHîõÊÞ\åÿPA~¸„J‘ž#Þ$ïtºnj.ðô–<åtÊC„�úÅcHó½~Ù‡+[[¶$Ÿëñ9L󙻚ìñz Š:}¨Ðîñº¦ÍåÁ¾žM×f÷≋zxxÃ'otÅj~”^¸½ÕéëxxÀð°€ÔÊòäŠ/¼—›¾¤7ðkÈ6Î\¯˜í2§Ô½è;k c”Ä#A¡$ùäB—1©ëä~Hp»“ô~Rí©óÁ4g¸ƒ_>Ó*ôpš›SØBîÅØ3Njø,ÛzŠÿWó�#H;�ùØ@/ †›b¶ï·–¤G�ŒÔq÷¹NÚ7‡•ñ[65Ðvßì›î8FÈzMðúž–;M£–«dé’·×°¡é š.×YI–'®ùÁDqò�óô‰`ö9µÖôÀ½79Þ2¬¿XÜråÏxMuaÕ(ÂÍÁoÅôŸB(÷ji¨­9QÖŽ}9?ä±@Â=×|º5;^'?ø8ý¼#z'ȵPîþ†Ÿí:5ÛÇŸZSw@¹kZºJ¾ òNw´b—�‡ýñ…™ß>P{¢ƒ=B”Έ6ýÙ*ÓO—#+ÓOYû›¾Ð1Ë×ø¬³¹\SJK¤FmÓ²ÙdE2Ÿ§+w,¡~½gÂ`Y†+}ºúÖ'‚@-ÃÛÔîúÇo ð-”EódiüÖ«sʃ§Xåtå¦ùƒO>dý«»šôLûí4û«£éP'®çã�ÅKMDÚ?løEàâMŸSeY#ëOŽ:� Ÿý©í “×õ¥7 �ÏqÏëΘòW7½Cgb�ÐS�¨`s9/£à¡©mž�M1gIœ5d_5`€Ÿ‡Mµc¶�¸Øn DµiNOÊã„É buÀÂØ5ÏîúÝçC‡"MO×èqÍ×™x¸±{†›‡ýé{ço ÖP.8õ=õ<~°æg&§u…»G9å1Ü_ÝÃ9Ö 8:Al¯Ñ<‹›Í~yÉüÅ9ÄåbÝ4çs lþ¾U�|5åàâLÚô0©µ1LçrñpCµz/F´} ÎÔl§ 2’¹6W�søß°xø­ŽùɆZ£Í§ÕŠ ÷ååá¸o=Øþk”NÇ·Eçr9O×ã_Ϧ{/ÖvõH3úå}fø‹M8®Å®Ç–»�¿„Šy¿¸ƒÏ:�X,šÇᛯ‚î1š�ëa6Ïè•¶ÏtÂ?.GÀAN�ñ› lâŰö˜EÔÑØ Ç >¶@Üú®Þé0^>Y?:\GsNËðžÁ>÷ËÕN¾ 0U߯Y¾à‹”(ëT£¼§fãÂ9c¤Gìú‰þét|cÃ�å°žÚÒ ¾‘ гZ㣭Qý‹ßëjÄ­»Vb|Ðd¼9Í÷äq¬¯ÃÐ�S&÷ËZ.‡¿(÷öçžzC½–ÿ實¸ó�ø‹'‡u3-ékvéë®ßí¿¼ãaÖ‘~Þû��<Þñî�O9±­W‘°3ÎG—s�Gfãî Ñ &L:è/ |§n­=ð¾q«áx³)‡=é�)‹•9=Nß{‰²†ô"±îpE2ù“¯õá?êÉhÎÙÌñAX§æ =é9kb6Ö Û,»Ú;Ýž[ÕÂÂï$a·Aàq�wïÜÂæ~“j1Hç·^29ͽ{ã|×ìmÍe!°;rÒ“|æÄ­a}ÏŸŒ¤Äá{Ñ'Ïl¸ŠçVÂßÃÎjxûÌÚ¼Õ^yOŽ¥‰–Ü7Q¬í9ÞI“;vÎ"lþÌØ’Ûý_Á@Bqcš‰TNb/O½qØ[ˆ‚'ôðj]kCŠÃh‡»âz²JîÄ„Ç×+ {tq?™2±î…‹‘‘9yv ìÑ)ug‹tæ‹qöñaïµP‚]7èÉ—œõ‡mo#hÊÉqG²i_žä‡Ûóš9áDl“h[`iã bm¢©X™Ò{æøÁ3¨�—âÚ„†üö7o6cpŒãË�¹_Ÿj°zv5€áI¦å7Sí·±üðè·‰ú½á¬>¿ë9ÿû§_«¡HC\†uU«¬þ¸HÔ·ÏÄ»8ÍÑcŠD´6°ãLo¢ÚH'§7îÒcíæÖ ÷I¨­ßLÉ}aűei óÕè)µ¡ÄOMþŽ"ÄÁÔì{Y¾%¸½ Ðñ7yßøîýu¸n|xžØbœB<<¢ù ~×p1^›Ö\“8”"li?Vúßù Öóo4¸è`Nû3&�'›{ÔàøÐ’ÀƒÇ�¬Å¥Î'ª¼Ç²ýxæ�¿ÎØGªs¤ä\¯©Eƒ×âÚuƒî~ü¢m‰�Ž”Ãe“®¥z,gÚ>øçSçG:¸WÉM g=ÍUœÌÆ“ÿÕ@4ƒe·®4äóBèzð�ºÈÞû8ÆTW¬±±¿ƒ½ûÁBãÕ—kAÆPfcѹ �üøBSMÛa¬NcžžXkƒ«™|ËuYÂáÞ|CÖ¶æ�NpomJ�údçë%>ûub¦oÎôBž]p&×péZbÇ5ßé’ù³›cáEìFÉï ôuÂM_bô„þP¤ñ/~àï>|_û¡DÚH‰ã_m§¶·7I Àh5t1Æ=„«›˜­_Ìl��ùñ;¡ýf­ç`›‡½mQíû=|�ýp�&NìþGËþÈg©âh7íö!$Ø–SÔÁá�˜¹I¹µ…UüãóQB‹Æä}9åÃ}ÔNÈcŽÊcâAßƈïÁâß?ÖâäÁ8ÌÓ6Û~OFýɾorÖ—Ý�°N»/†6Ž�&÷çC éÐuuè÷ÁAXQŸœØÏ�G[ü;è5üg/Ÿkà·`øÂZ¾ÝŒ£¹ù±ôƒÑO?œÈÞô–Ú7EìÏÂ;79ùb²¿áˆ¶�ùX¸­ƒ8±4Á°øåŽoDì·8 |ؽF'úàŽÇëìkiNh휠ᰯ}.—é�ß¾ï¢7?\ÖZ é›â¬‡øè }L?’;± šPåIyŸZl·„Üá”øóM’õ‘™úž±zÉÊçKâ–ü$‚< Ì8ÇÒ.ù¬¸†×ÇÎ=ûÎ(X¾×÷Þ·~Í— )äæXžäÌžµß¬xòL™ÐÉc5gGVÃ¥#K¼;càèo¹X“jÔL®,¼ÁБ}ô ¥×ÉÿôF¸ÐÐ|K; ÙW+dù-Vt0ÚöFÚ‹£((Ö‡ÕLbaÙ°E¹}Ÿ EÁŽ5Q•׆5T7Xêfp3–kqÁ^êÐÔïØååze Rú„½Ýrl¹’¤×}ªG2™L&ÝèRï:>ç´üó+k÷ È\"<<<+Éd’»ª9¡wÎg†yµž~Ë䤪ª¬Nñ*O¸A'¿SiiÎÚ²Wc+÷H; Ñëkãb0ïá ãB]V_]Í)#Þ£wyjµO…fN)Ë…2Æzdù®eož=Ž47g€UÝ@üô…G°¸Q•þvW�÷lðÃÁË>sŠˆ_æ kÎË�/¹ ˆ�ØôÄNsOKúû½¦ž?íÓ7§—\”»>®¾_Øä¿<¥n?ÖŸÜCŸ¿HU@0I¾Å­Oo~úE�ÌŒ S =j5>ƒ#(Þ„<…I>r„Ós–±±&ÆqÓÄù…ÎÄÿ‰Çubp¡’¹)mÏÞ‹Ï}0[rC äÅï@´ä~DtŠ€#Xº†ŸXÍz]”¯™Á!Â>Í“ðj 7Øè/œÖÄ›QúXd4®¼�ŸðŘ¯ä‡Y©SrD ;F÷±W”ñᤘ s4Fc�hð}Æõ×þçš Nˆñ,§%ÞˆxëvjáÒù›ÚýíZ$f5†¥ö_ɉ['Ç%;ß+1Ù¼$·ûlGGWá†yC–#¢µkZ_qÙ/siœkÁ/³Ö~ó¯Ú¦Ñ[¢L˜pî‘ä9Þ8ž­ëÙž™úøa9óëF3û´“|òà7§g\`:ࣨŽÓ+ñúµF¡±[ž¤->½5÷Ê dgÁœuk3öæÌkÄ…„¯|®±œ—?yÇ{R*Î}�aµ°ßã²*ž4çÁ/ÒcsMð8·gä—µâ¾5_ã1�%€ Ù¦|xY>Ûñ›æU'Ý` #+o±´IéÏCVn�ö"øî6çîë®oý÷¼ˆ2�$ Ãü¿«‹sÙú·k6¯Uöå/DS5aÐH²6ÚZµûæÞF÷îâVÉjZë`Ã7,Úñ�û|ß�Ñi£#Œæ9L[7[czXéMzåDÃù|È}µú™±%w0K$þ§þw-ø¯Ýzä‰6 —ëÜS²V€bƒ3× 9ÑàmþÔúðìl4Ê(Þ}eKæ&ß{;ì·^—¨áoƒ.Ûןscã Ÿ¾Éêa^­Æ¹ìoŽõ0A©Çk]Æ1ßkÿÿ ¡ÛF^m8ê?5ý.ÁúÝ_šõ4RóÑ ¾!MØ„›Ïy~„‚6ƒ=üp™'Zþíߵ簚*Öãç †®p‚5®Ρ¨È^ü«ƧrFVêK¹²’.ÅYCë<±èD»‘€[S÷®Å묦Ó@Ù¯fü>"auú31ìV'Oê®­Â4\Â0»pÇ“­š\.üÔá†)+œ§¨ÙŸ¼òEƒ]»Ó‰Y†S¯ö©‰]úï7žN2tÜøˆÜæÖA!äДSäê{ßø4Èç×Ô³õrL#D©§ åN8Îõ¶æÆ'¿}4‚¡Íñ;½.uá3ä\¼Ub�ꮹ¦`âÃã]¹Ø[Œvä/Î ÓÁ!Ÿ>S7.°oS³ï«Dæêô�x‘ˆÖ àòem À]Gú´¾ Ïÿ-‡c‰�þ{�oiãkÚùçOðóõ©_Dz5çz‰)_ç꼇ñÑœzMd¼yóß "Ô­µ^Ä‚‹f/ðÉ–.j†Rƒ=ä¡ùšš|‹£æõè2„ƒ »×¹å�3ŸÉµbDÌ¿·_o/Õ4ç¸èå¿óõ€0Åž3¬~´NÓåfàF°‡Mr)ê—;kÇ£†³|†û#œ�z5÷bì¥ûzR58·Ã²>5:Åò ƒšˆ©ž©- ![æ¨ÁFlKÓ–€õLêô%'À–ÿàü|·¿çy²ùøzìHÕ”>¹åÇ#îjÍl¸.É?Ÿ²Ø‘Š‚¹|'™¹ê½àQ•ؽ>‘ç®óu"ÚÉ—œ¹o!þòÊ–^Õ RøË ™SÁêñ_iÓ ò§ŸÄsûuzyTÀ¿¼0D·çëë`2³· k#ËãÃŽ*jÈs#oæ%š/MQ .Í�K룧ÏSWiXt'kân_œç64ߛ֡ÑHNÅl£ç?ƒ¾Ú!²¤Ÿøöõåž ÞØ-;h ­�öÑ“XÎÆV]âg—ŽþñÖZÆqÑ]5�Ð"VO£®Î±À—õ¾¿$„³’¹¢‹5ȦÿÆYç°šñ¡˜ÀÄzWÜÕŠ5ñðg˜Ø_¢ò5Nºüš ªÜ;àŽq®÷r¾¼Æû«ç7_[øZ·‘ž“TñÆ…ß~ël‘ã=ÕúÛç(܃qæ~>E„—€¤pŒ{ˆçÈ@{xįžúÏøb¿u³�{ÂE]æÔÅ$l£ÜºÔÈœÜ<§«UæËw¬� âÞÂyxÐÂÎ�>³¯(Í�Ëïï»áàìl‡ÉXù5r.©oþ(«?Só´'²qþ t<ÇŠ¡yè+š\ob j,Å€ñý¤ï©áM�à¢O+žsíò�så”îWò¤7‚{D3x�ÔŽt¯…Œ­Hó±®·{vÓì•¿ßUCÔÛÂ…‚•Fz‘u®9ƒ J®z¤i<ç“N…çîG&]éËBÓ â‚�G«|&Þqô_zìŸODAŸ2$h¯Yžsðk×�N‰, %’ÞG;{k a!2ºi$Ju9¥š±:ß‚:WËû³½=‡‹¹‰'1[ͱjÛZÍ; ¨0,—Æ,Îó©^"š#+][oÉR•ÍææšÚïôªÆÙ_M‡#‘ŒÝ³znH‹U+vñ›W¯“òZU\)'Š|•™þä?É êƒi~±Kâå~4‚8voؘ¿ V=zíâþ/Þ!è§°äfF3c÷3k0|_(“ý®OÌö“O¡„;uh>œ/D¸<Ž}ͯmëÍÀ¶Þü„ÞåOžã�ýqƒÉ¢Ë§>Ù}F#`Î ƒ˜»6üÚv õþõ¼šþ_.cN㛿ç D|j\ ÁÛtud{Î/q÷–Û±½X‡k�Áíp£Òóƒ5|“ùž+pK-ÏÖÍ&âMuúh¬´�š“éøŸ°Q˜70%¬5’Âí<©w_ˆ¬-E%¦çŸ^D·sþMÇ|I¸tÞMÈ“;t}ÅÚÿè´Øóu ‡/1hÜà•y¶ÈÝó Þæ�I_¿"L|ZäÓo�u�nûQÚÛ¬Änm5V*çpîUìö’É$ÞÊAøw/'³¿“:˜´ûú°0Ás’>Yôñ³ùá`ÿ¼™l¾ ¬=½™rGç{MµÚËÎ0u‹žû»'çs_ЭÁz~©QDòáu�A¹NÛ”:ì2~Í,¢±¦åÑ Áœ‡º¬šGM߸†„ª#\C‹¯Àq¤®H`m;d�×Ê#:àŠÅç.¼¡Mæ³V`î ¹Z—�¹4�õúùD ~þ* cóeL.$9ÿØwµ ÇýÁ›W‰VÕÑ ¯áº^Ja6×èni›–ô¹"ÇœûT1‰ºœƒ�ÓÇLí!�û™‰ì9±:ù/d¹æLDs¶ìâY¾†¿±ãÆvïwÞ<É}ù¯þóéÑ·FßK#SºÅ¯¨!"J¦‡Òû|"¹GzA-Á z<ÆËhßu†ç©Íl»ìþÊÿ˜²&g�y1ÌUxsŠoçeÙˆ5ºñÁ[~h %a~Ý�>}¬?ø\?ùœãª•;Hð~íµ<ö§(bÅö£¯3m¹ôÃÎbÎ_ã·H¹3m»[ò§N'*}}Ú%Çõ¹ÝÇ^¸&ÒÜÿnâ*H�r?…éô©yá»9ࣆÓ¿Ýwø.¯7.*5+#¹¬q0ŒîKݳqšÐO�"«9_I8÷›¾™ º{k”AN£_]å�gQÌÏp¼‚6Wrs’ì|=®Ïá½Qos �¥Çx§3�šó“Mf‚=Êrˆb=8¶§>–ï}lÈB0ó$¼1#}g†îIgÇ˹õ朇î•”¸òÜÙó(ê’§§¬i™„�¸ì‰€z®ŸŽ™‚„0÷ØÍ�µb:ƒÏsˆ¯WÑçBK›³ ÑîUS=þ›ãÍÇšçZµÖ‡×¦ºë:Ï1Ž&‚†ÓçåÆü;þ8÷¨oö5*¦6ÖÚÅ`„ííg¯†`Ü‹?ØÓëË[²³|‡/t¦½ÜŠ'7ºã±4H¶ÿÆ_;º†IßܘsÞÄÙ¿Ä:êïX+6ÏÎØÍc‰ð¿êY‹J«2?»›Öˆ¶ð“H«édÞ8€hy]ÎaÜ|xŸ3r¯v7O•8­id'öÿøËúà×ïe²DàWÏ¿ýÛ_ÿûÿùÿwÃsªå ̇,;þu‡ÎsØâ†�þIhìÓ´hðu1 .´‰×ÞÛibC.= Ë‚�s„8ÙcC‡}' Í‚Ùét�ÂÕBÈI°8r:€üyÂãbíoR aïØÅÁe› ̓é& ׆yÙ�¯Žs 2册ã`�÷áZˆï8ög)òh±³Ä v:±ŸsÁ¾‘`ƒsBŽ:ZC"°p>‹Ÿ£ùÌã¬FLóqf9ü½KÔ¾iüàcî°º½X×Û3÷ ÇëÞ×þ®�¬gßœË=ëöÑÇßxjsg¹º^dŒ IDAT´çiëÌ¢Ž>P;3�WO"xþ=6WÇY�{jØkà¿mëòrÿ(f/äÂkZ]¢‰yvŒ_N<á‰Nyƒ§áóã‘b>˸µ�µÛæX¬Q”ðEž#›¶~è²ç2û‘:ÞŒãùµÅë8rù9«Åá’Z¦3sˆðù¬ykÇœxVJ ÏiÜ×#YîxxÎéÊ6 ^-ä§8y0¢½ÎaCbF0–1œ¬æ¨›‰ž †?]ÑÛø/.˜Ùk�gòó|¢Ê²}\ï¡b4½k³Áh¯¸˜}õgwøšþÅ�p÷âaq P®G°!m›]3©Èؽ#èH´½fs´!>oÙ‰¼ýOöÑäPÇÜ_* ÉΣ•÷ÑΕA.¾ÃSDMsdÞ_2P±|��ÏÊxÁNî­CkƒsÂ¥¯fæ{Z¢‡ÅÕ•µ£}vy0'q¶=}Ac!bi‚Ø—ã˜�S>ÇåþŠ8”g~ £ªÍ_“12Rx0"s¨ÌpÝѳ3Êô±7Bd3…KK W뇠~ÛøM±>X33†ÅPëØz›œ™?š@9šÅg„m5ãP-áÂwp«-{{௜ï�ûIc.0Óå¾›û\œ xï�W¾³ ðV¥=ÜI˵÷ 1ô5Tž;Þû`—ÌÏW(§¾gx‹I §±ï ø ˆ•Áäx<‚ Œ{'QªG˯¯ üµ^0£ÀÏ;|NQ“{ä¿4�GbíÒµB„Ñy{z!8(ηÎ$6žà:œ§[ Äucìr} . ¼ú¯/KL¶g8çµ±²*-ÎkóûÎr7ß½'ÍHO¬«|�Ø,Ýr2N Å“³ë0¼èåÄá"ˆˆ�r{¦aÎóæF¯#öRÁ�=4W‡ö®s¾éÙ~¹{žl×4$V`âÚ Û´·FÙ ÚæïÅÚŽ¦¿ K„eØŸ½¯Ó&»å? åC@.z 8Úƒ’!D>½5'+uùþ|B]÷�8@Àyz�AÃ9•Û\æ‘-åô½#ÔfYpøF�7å)„aV¯È9+v×µ�fÒÞ³°Ì'¿ì^7vëÕÁ>)œIËîÝ@<Ù³ÚpÍÝ¤Š«o|v+ÔØ1¬b+õb¦;±éÁË3íØÞ}ÎÅQÿëËJ£gÔ»š§�™a\ÎÚ&ßLà¯o±«q8ý#ƒ�š²½}Œ1W8ΛÎ�cÜã!ÞÏuñÞû£÷$q²/†Ô‘Á½qÇûü±¼§6ön‰‡ Á²Á½–‘‹áIFks‘pÌéˆÄ¬'i„c§¥èÔ´X!¦ß`�’#_×ê|úP1ª'o^‚‡¤,Ù˜³Ï©œã7œc ²‹Ëüç?ÿGÿ‘‡vÿúçq°H%R0kfÒB´‚냫mß$Á`ÿÇ_)ä¯ûçê·´üõ€¢×ÄGìÓH¢HÝ›„µÓa¾ÇU⬘mr*À1h€AŸÓð×ü7;ÿ¥^øÉùð}òÚcž¶|Ÿ?ó<×zcyÙ/÷lùëŠWë£SxzûŸ©ú'ûg!ãý­Wä­5÷(Å‹èæÆ{ôãØ` ¾¦£UõÿÚͽ8Íýõß\ÛÛˈùÑ´˜?r¾¿YðÑQ+æ×Ò£—žZ¸ÿI÷�ü‡gþz äºÖ÷ÛËÙÍ,Lî�¾á˜Âìòýº=òÈ{’ÿÏÖøþ>8ïüõzJêù©3OŸ!†5ýà ¡|�]¿xŽ ÎßzÒK‹+Wj š«ïH×yõßç"ñ.O¹×KrüK_;v_®gaÒ—•DOüfzÖZ¾¦z¦¾ÜEÕïDQüÞ]~®8I¾Þð5ˆ¾pÞî%¼Õï{å“óö&é�Ø�¶Õöæ >ñé;¿u%.ÛlÆžÁùþõ:o�5gþŽr£È9<¹Q€æÌ^ãǦG¾îÏ—Þú_pý»y5}&»9ͬøÝÿù/}Tgr{’Ó<Æ÷ú.òjnZom¼‘}¿æâO¿w-Žù %@¿™§9|oä?ýòO­©Ë5À£�„¡3]KÈß½bôé:ÈMìrcßþbH‰#ÌÉ5>ðø3g}ÿzàŸ~Ò¾qú¾þæsÀ´Üg¼øÜ�ãY�Æ÷Ö`î ú½Îw5Zû¹Ü{~} o4poðóŽ¿VêõÐ{¯ÜÜWïÕð{Z‘.ÓfÞJÁ ;�•©õ� â'{EðÚ—zé#h�q±j.­6ˆûüU É´ºâOŽ·îq�$?dï¹™\îŸ@ÑÆ‰¢ˆóÐyó] xm™>c6Àó³²¶.ÂòË£Øõ+šƒŽýµ£uAj™7r&ìRc|ð­ÄùÍÿhLdêJãª4ÒÌ}]_h¤¼Þ¬·×wGûßQ²„ } €ï9|ïå¼óóö+&ßzÿ¿ú\ød—¶Ôï_×É{ lïÝwýf�‘^óuˆ÷µå79÷}Ï\¤îáiúåmÞi�n%îÔ�àœ)JÁ»V´.?aû¾�éeúvôÏ8¹W}ñÜë½'SÃ<ãúÌ?<‹E_´5º‚ùYb_Ïé=xø6¿=s4_½‹Yßåi?nÿÌí~…Û¼ôæ{󰆓ç7ã_z�ñtÚ¨‹¿ŸËnΞí/'šø®Ï`ÍàMøÔŒº(qÇî }‘ @¡îùÈÍ/ðôàžä¼¹?ÂfY%~ùÁüõ¿ýÿ×Ï“ Ò¢E>îÒOa=¨Ä kõÇa~/8á×ÏÀ~B­÷#7âѸ¢¶fM†?þ䃎ñiÿ½AÔo`Œæñ“i7Ͳû°÷á/xGRoä‡ÚºOUìÇgçÑZƒ}‡™ÿ&‘úøžƒu £ùøþP;°ih‡”ÿæHOBöÑ&ˆû×ß®hp?4G§¾Ùø…n¹ðk¹sÉFxõ�†ä‹:çzjÿ&ŒÞÕ=ýð0¶?1>ƒîšïßõÏ”yqá/>ò'ÒÁ·AÚ†4Ž3Õ$Óõý-szÿúsx.çâ‡ñ�[úŽ�F149‹Ó£ ¯�ԶހǛ‡¸Ü'°Eyqx5À“=9£B6�øä³OK›uq>í~cöõ >3©—¼¸À_‰›À<ˆpþþ âû)ùÂÅa³ñP¸¦£ƒ(ꉹ5c´(ÍãÒ–øw6£pB &9Œ­f÷í9Žt*xq®ÅRÂí#|4vyþÚŽo4„hŒ#ºc;÷�ŠýO×?i6§bÖ»p¿ºF 7äÔ$Ÿ:o53vùÎù E}¯Î_=«Åz�ý"vož— ÛÝèò°ÍˆsoìÍ&îIp©•¤¿e�ÉÖ1¸óœcõ{vÑH@p¬Æ³:3ã�öü¢.ùˆçÍsæ½°0�œ|ÆUdžÁÃj¢ÇÈh‹ÖB˜[ß„0þêÙ>õ‡>Jé•Ö/WþÚh_Óƒçk(«`?ý5„‰óöŽh\Öã±Q—è<;-šÈ>úÓ¡ÀÝo¼ò™øEZj0ªdùás½: $}ùx¯bn¿°_Ýá ‚š3âgÍ|ÿ~¿7ÞóyôönÍÑ–ätî“„~%'÷ «éŠž2Y"yòæ¤{%[bs?@I¬Ÿ;"úçùÁûÕG5ÁÁ>}=¨-ý3Â\Ó?y,$¹+óíwtËrb^'çi.ð�/\&tðr'ç¼äwá'or⿹,S¦Ê-i0Q†Iûæ=u=H–œ¹uðýñá/Ì“s ‹|¶ä~9Mª-^4Üûþ£�BD€–ÕN軿µÍýÂZ†‘_ڂ׆Ҹh€Ë ?yí„5\òD’! ‰OþÝœ÷üŒƒw9|&’5yùþ蟚8ú¢û휌èϺW™L?ˆÌëÏ©ç€N�-åå»kj]î½Fß÷�P‘ÌYÉfÓíi¹®§áCÏx_Ô][Tªvç5­7Gó›�71øž7Ïõè_NßÏl4 †U©<㛩ìÓ�{šëع× ÷—76x£“>æ^úÆ,ñß^—�|ú@óΗ5¶åz90’Aa¾$§ÖMkŸ�Z£Ðy�Á›z“‡t›L¶å(‘PôèòÆŽ6>цóÕ‹|`ÿáðkR“;hcáÑcßó:Àä°7{4M7BÖ;Ïðš‹ùŽ�ÆÆã5óó(×¹ÍfJW¯‡(ÀïÀÇ÷rÈ4¸þIƒ�Ç¿Ý�“ïUÝ:Ë;$ùÉÀ æºëÆî¹#d�‡°�‰ƒß 1‘oë–î³ÜŒ Z?_Šß51oÜ«Ûòåäu#ï»�‡7®ÌKÜ-êñðRx¹M\\‹\¯_†oÇÓ£å_ž;œ)çœn„Êzwö�æo2DOìÏöÑÝFDTù¹ÙgÈæ‰EÓ¾Vbßý6ÿâà[åýC¼äËwUDr(ñ’±J.;Üô5Lj'ax|µn �Àaì|€Ÿ‡sÁbÓ}/³;\Ýð½£{òºaó»ÀÍkŠŸðCÕ|7MøÆi»0|S‡b½Ã†îê.˜fó t’u!>÷¸Zýƒ¬™ˆ¤º�J,9ýÐ6ßàcßÕz•|ùQÍç\[3I†s]z²¾{8sßÖŸÍMå^N¿øô +[Ír:^}Äç\`ðk~¹gÈ~<¯6s—“i|äÆsÂnléBÊ5°<¢#|Æ ‹ÜÏrû7]ä‡5÷Ôå™à^í’Ü¥°”WÃP�\Àß¾„[WÞp¨ooF¥›Êu8œ¼yX«þ”ã`�¬.Y–âhsO t­Æd›+aÕ÷Ñþb´¶§J¾�[›Í\®ˆÑØõ£øÕêɡОó|�!W×RŽ�SføÌì�$´Ý˜rRÃ}“K š|«cÔýÖƒ�‘7XÉ;¶ÖQMᦍÏݱwøÂ›µ<å*}±‹‡ |Y‡¥¶È5~:[2!ŽË5Öå#0eÅ¥}åKIÙøEˆ`A*rùI/H~€O|| ‡&{xÖ³ÍxÖZÛ0T×z……þf/NSeOŒ3‰í«;¸¯ÝHè<¢ˆez?ïSš¹“ïûšF_^¼ó;ðéØ<¬ò<»=‰Î–@cºGfu�Ëõã`Hȯ–<ÆpýZ-Ä«PÐå`�Ëá �}˜ ?ý.g–+yŸç{4#7_‡ÐòÞ?kÞý!ÝR�ÿÔ7}rûþ Ìéƒ#÷jŸ3úÝG›t~}Ó�˜h™æÔh�|£;¥ó¬5ø ᪡gAmœ¸pòßIs�å ÿÏ÷ßÚÞSWbÈ­5”¹§ÕçsÓSA£.’h€›û’™8ff…½gýÖdÊBQ3)Æ<ý™–äº8Bñù —5ãòãçþè›^ç³Ý ¢ž¸d޹©Ñç™ûÏz�ñ'#ëPBš5èòÙÆZ9¿ßsô u~ØÄ{8´�_ä¹5§—ñóCâz5³ËE†àòì0fÃr8KŒ�{ÍÊú�.˜ á=óÆdôCÖ%g£ˆäƵz­ÝàõN8Ý÷59‚çýIK0›H52´F#5Û^\ìéõ‰½‹ËçÄÏV˜ÝÓÊêÄ7_ÈÙŸG@º",ã½M�ðåg@üØÕÉ5s9K,Ï‹4ÁŸ=g ã}^‚:ÚÊ…?øø¦“HúæÁ{ ?>“Ƨ'‰ù±×{¸å�5:Ý@æ�—¾é#÷92Ü›új9¾Bž3Q%œ„˜ŽÔÃ*ëý*±‰—…øÆÝó­D»G'OìñáqS;›mÃ'"x¤Ñ�÷Ñmf?ÇeGÞј|ë¡qòaõµ9ƒrGÌk¼|a/BÖía�¯<6cÁ°ìîÐÛD,Ó'až<¹§y9€ô˜w�Û¶i�ßo„ ” çùÔyüá{^YfúäUGî…±…è쎎%è|ÚãåϽÝú¦�èwí~Qãpš£ Ú$¡ÿ,Øœ�j#û0"Øÿ”³-ƒ . ÀF¦’ž½l˜"²Ráêòà¼8L ‹õŒ÷0h©ž…³Ë<›ÀðýqoQõy#ï'ཱx²»Õôé�8w Ñ~Î „‡¸XôMãæhÊ]9í1Ùžè M1âÆæw¬eÛ>è´Ó13t&ÜäŒ÷Jæo^â÷âxy“(Öð•Äz3~`O æ—�Ü'?½~cÌXÞðß/¼v.,<æ†Nѧ¹HS1`óÂ=6k/Æ\àxX‹ ’ÑüÓ§zÊ r\ŸY~8¸Lísò˜È@Qƒ>õXm¡(Ö>]6îcBØ3ŒaúÇtN[r‘7ÜcèÖZSC®eñtc,ÆæÓÖ3”¸þ¤A>ÁñÁàjÎúNÆòÁ@8b�Î''q±‡w<ÓK¦³Ä�‹—MÆ´<æÈ("Zkßã_üæÇ•ø0MÊM®™ß¼GÖYLB¾¾m·\eíz“u‚Ó£¾Vào�ÖkqQðk"Oï_“~'s‘Ôp«?¸Ù}ö‘ãh3�£aàâ6³ùO, i‘^ê23tÛkñÄÉC:ç;BFѹ÷Øœ«‡Pë0G×'R ìzë*Š‹mN¹qp]YéQú8}1K3,X3Ÿz0˜Óøëûæ˜äù~=Œ­$Ú¬gG«£Æ^|~Ô—üz~yoFLÈó•š—ëßz„�ž¿¸Ä�-µÅ¿¿¼0�øà¦CÙÃU~ ÀgKûóôR÷mˆöÍZjs(dÑíölµöÙïEç~˜ÁúÕ�e#uC’7´¨;½´¶ˆ¯NÅtÇ`Ì=—hÜ=ëlxJYzÏpp¶š–© ›Â…®Õ1 s"r[ÛìÆ€(*AÚÃNÁ›úkÓn~ô§†ë£†ÄLOø¡¼õÉÆ§·'&ÎåÒ9•ïOk‚kµÏ>^è »ëË›9è‘}š§­ðŒkqf‡ÍÃ@á5TÕi}†ç:6°‡öÞ[Âày¹¢%xâNN‘foՊʽ[êÂÏf= ‡ 0kœ<ÎWÿrïÇvµZ�ÁäO-å9^xs/æK2¢½–P™3=(?vœ8ú Anç—.Þ`lx}žr)ž ¨·_ØØ;ÆáÑX.j?£êeJ݉C_¢£Õpâ‹ C¯Lø Ò\F‡ìzlŸ\ÚK‹í�ÔH’Aë:ìÏåá“«œÖ@úäaVà¡{5¡0þ¸‡š¶“^ ã0tÖ'‡‘¸`ôæÍÞÇÒej.Cm—Û4Ÿ-à¨ÉÓæ}“ÒÞ&]ZL¡Õ]s}�Fw9Mc"Ü{ üôí,Úš¾áçAËÝöÒX�ly³:ç½üãø¾Ivï‡ù×#ª˜Žå“6&·÷/ÞD&‰ÁVÿ{ßÄ©;5¿Z å±sCÏ?g‹c‡ûÓõr^ïÉ�5_ߌdd¨~£ÊK{1o¯,g�ÞUÖÍÑhôÚWÀȘ=°Kí‹¿uóξ™˜ü%÷B(µy®–nøÁ“5÷HΈGry†—e·#óËa3‘Ĩ5=Á��7$òWDå)\§u…£‰üÔÁÎç- ©Ë²®Ë橊©ªã6Eâ]—xLí<5­Üî3±Ã?),íåÐzz�çÓOJ—¿¥˜ÛÁõ—Ø8?;oôÐ3~hoŒsÝxXç¹ôZQå{ØþÂÝûЛڎ�•ÖÖ¢‰™Ç¸d8ý°£@Cz¶„<¸ôEFáá^Ÿ°Ü¬ÝÔ°`]‡/‘²™g1/„¬¹ÂÑ0×a¥ºP“ù³ ôøqžØh}k‘S1`èCy0zÄÆòú¦%‡Ê„ÕC‹û×YG͉‡gÚÀïu1r÷Qs·Ž7f½tipðšh BoÞx’Gˆ\Ѹ:r5~;ðwM\å›ß±Á#É?0)Fî;ägäc#ÌjO 궺k,p�{ )ÑŠóŒ!ùds".ÑêD$chr}ò¥×ØëÓìP®^ÌÞ~¬P|bc2·qá5TûØ ÑX?¼%ßïýi¨cy#q9ÓÛ ìWNb‰c¤?Y¯_ܰÓHÖÉ©7ùëEËKäûû [bÆ �˜À³²go=o¬¬_¬¢ <½Á¦cóâ6žÝWèw_“çç—ͺȴç[˜¾\Ȉ®ð°ŸTn¼¯ÝÆwÊqhâO¬¶ð^lü«ûì„yû'oÏöæX]·’T¡fìû—2vÈ`Íî™Äùl‚óÆ²švx–ßöõxŒ«Í=Î%]ßø›3)§d‹O^‘Sl5/þÄB˜q]6>= ÐGx;Ç|ô,r¼î/dŠ'çìN䚈íÌæo/ð±\\Íhl¢…9‡YŽG³ã4¦¼öoøœ=jÝüù% ~ úÃäSÓÕ¶‰g—Ú [�Êòh�WW:ÝÇtÏ'½¡L�ÍÝšóÃÛz…[¾Í ©tk|b‡È|je‹=bÓܸ͎XÎ#vµËû�%ôŠ3¸dõTìÜ !a¨K8‹5ìRœ}«Q!ާøyM|áó?<ò��'Äú)º†’Ç»Å?C~9ðñaâ™�° fþDØ`Š#’Ý‹ÿÛ>…an†ÛTŠÁÁ@»?²=œ7šÝö[#ŽÄÍ်iðú0>Í`o­ °Ñ½Â2¾<c@ÓþÝ|^k¿˜7§«è?à·ß¼ÓÿáýÁ9r?N‡ÌÇŒÇW3=ÇÞýr1O{D§²�~¯›jqÓxfxý9`âˆ]N°ãÍúD[CÞ¸ø7Ökœ{ üGOäìM ¦£Ú¬eZq>ÉrÛ“[ùÖŸSG¹XAó-~1dß þi?%8_#X ãs¼9Ü) ïÍ� ù¦ÙBAøá¼¢ÁßÛÀkêxû_óª%zøðX@êsކ`c¬«ß{È­Ïã¼G�íh¦y/êW³’üäñ>ôæMZÂÅt wrÆä+幎#I9üÃÕ�~“G°OŽ„•S›³ï“’…eõCæ�âÛ�ÇoA¦Êú“¼Ûf÷ûõ¸üå\’ðj›^k4ÇÕ2Ìô+÷Ftøkí)"¾xtmÍqÇÚBMi‹tWEÈ�cý�óA4ÿ]{,ìgK~r?áò×þ‹ó~ߟÄ!÷€ï¢X;I®æ´_Rbæ!‡Ï¢hœ¾¿ ÊÎ4À‰÷&1VïÔyþ¹îÊ8Éî×Oˆø!>?0 ‚±øÔQó�c¼mŽ1ï_Êî{AQ¹×Ø“êÞ['¼$´WˆrÇ´Mâ¬Í—Ø›>± ¼û奘©íÜ2¢Íþ&}s§ï„-:R�lNf1´&üÌ{t鼃i^_cºÜàn,öifÅum—÷Ùƒ²Ïîp;Ÿ\¾¯Œ£Çäjl»“¸ØÖ#JÌîˇ;ãŦ7‰ñ:! ŽvÞŒHÌÎ÷–ér19†ÜsãÍä6?àðL<Á³æËôÝ[‹L›Åfîð Kø4>6#s!~®¿pb IDATyØ6KŽ�5¦Q˜ús?b˜hª®Cž Òì§æô’_œ5·§ô‘×óæ-¹UÉOhöô¾P­f‚{ô'½Ž‹¸^£(Ømsmðø±9Pú!d¸ë×´ŸKRËüà› ¨×,ôàÓ¶ ˆ>]å°ïä!T¸’OG$·*h ©Å"rž$b,Wgðú€ß�{°‚×4ãX‘Ø’#W5ÞäpÌ…¯gÖŒm¦9V{p=zVÐW{ÎPàCÁ•ᶦÖü€Lg$0=†o˜Ï’<“às"Iè‘Ø��G†W¯‰µåiÑõ™—ŒÐÈ5Éí×t¸,G©m¶ã䨼�mg‘{ƒý…øÞŠ8ãx3Ýør9íìWÃâ™ý�ž½aôäõx´M‡…ÚÙxMÍñVSîÕé7×Û¬q‰dÏŸœËcưnˆ8¶wOÔ¤éÇ΋186W[8І¼M'Ö2»˜/NFïé�âÑ {µš?ŸÕœèSò$·ýAØß‡)éäÕÚÏfz!'>Ö{ƒýäöG·šêÉ\}x_}ìG}ø?:Ä­¤@­Á«ö65ÙódˆM#aYsmßpósß`�£¼ÄCÎ�OÎê9³ ŠíÚ“‚O^s{]ìËó‘¹ ÷$<8óË~:œìç2߃sžÙ?ye;\øEï}×0Ÿ¼ÄÉ^i¸OlÑ©_Si@–"†ño8‰l²Ü|��&އ†x½Æçå/æÉV`¿è• =Ælnë|ƒ± “ÃtpáœüÓ60nr°ïHI¯Åkb†d6GóÞõ„ßÜ 9þÎïa½|pà³>QLã‹?–pÜÉ”óxl†uŸÞŒ“{þã±jë 7ãô—�Mº0«~|=­³vÜ«CXêYîÃç:!….ÙÝœD¥/��œåßlÙVçIf½c�÷¸ãgXÏÓœˆ•ѹñÓ¹yò×’¢ýp¶æ=qÉ`×gùèC‹ë-À;ÑGoµ+7Ã�&?.Š(»–èe¢Mf,88ˆvÈbnˆèãâÃöÚ ‰Iㆂ°Î¶‡&@æ .uVºœ_ô|â>¼wäÐc=:I�Ö‡ÃuPÛq•Ç.{s¦†Ô­>‹¹Ð0¹…ͽÉeÈÍŒNk ÜÿPk?ç‘p§Ÿ#"†'·öÓά–®­É`1†ÈõíkTÀ‘ó`e†ær-ZŸ³m>pqFöÕa.È6"ã·þ4Ovô|ÇRÛn>¡v>zaì€Ùýæ+Uz3Þz–‘Ù™>NæCûi<%±Ï«K‚óT£5¸Ò8ô½ŒãªËÖði,G6¾öòøßØÆ¡oäúås«6Ô%•ƇÓÿxÁ̧Èq~€Múˆ÷?x1ZOÌæ#v¢�öçæ‚á?ù‹t‡ oJ!qâX�5Îyr¥ÁŠ4lQ9tøÌ´¼Í=ÝFM+'I ¾áÎ;ÖÓ^^¸‰±|zDOˆX[oyÇÏ~ïÑmCb#-Á€Ó`ÿ;d³¾b½.æè.þÕæä‡w¬›‰æã$Oñ`Á½¼“†„‡!¸—¨]}%'QíçËßœãϜ܎“ŸyƒåxfÛœ<Ý5¤§Ð˜œˆÕæìÉÑû‚<²Ÿ|ë`ø‰ÃNé`اt ©ÁÆu¾lœ»´þaˆ5yçàã÷.yXÖkëAÓ©CoÓÇ€`O‘!Áž7¼“Äu’šE q¼k=>ÆÚ—ó\óÑ¿ð¹Ø[`ø¸ºgõïûÒê´/Â�8=0oú��±Ù]\íYó¼¶!mÉ’@IJï?¼¸h$°=eÉPÍoΨ1;sø©c-rm/þâû|�ži޶ñ¡ó®ÝJÞÕrò:±•ÁÊxëaóú”�œ!ü™±'ge·žì¬³\0F_ðá´Õ1ɘëú±Ú—Ûè%ÒæåX<±¹G’ز«]žÁ¬…Bçr¿åÞ>@Φý3]9åLáù§�kØeÿáÁ‘X¯”dyÂo%/¤L¹÷¦;}OËp,Æ‘5ŠéøjKl †¯ž?†£/�$˽•šèX¾ÆížK›½ŒÀÉbÇ:ñî4–"éñJâï˜.“(EËÉv¼ëC"ÈW¾öæž9l†œÐYD6]±%Þë5Mó0ËŠ¥«éÎY‘w¹‰‡6sãG#ý¶ L^Eãr›Í„í5G¼#Á{Y|V` ^´Ð[æñ¦wh+s5Ùåuþût® ž¯æéÈl&¼=‚ðå'gÖI:=p3Ð�Áì,uDv7ÄÿÍïHú Ÿúob1¢Í+ï�“¢!IdØÏåj½€Ë'¨—€=㇈ZfU€†Â¹ZÂOíä'GrÎY_jʘ°½ù“*äæ�¿õ[¢öÏ ˜ ù•Èô,]Û_ïÇU§ñøe�Ž8bJßcQh©lÓ‘šn\Vß´äye€q8ÙóK'é8£vûŸµÕÁÚÑ÷âÞSKX[òׇÏwù˜›ÚÿcÑ&x™4Ÿ3Á~ñ`¶~b�‹ýã÷ýðpøO|òV”9Âc5‡ÝÞ{ƒ­ü>OùŽþqÐùÅÈ<ÿ¡šÇéMlýßÿ¦¬wàsBb‡[Y>Blãˆ/2„a«W\b;Û³ðtÕÉ7!ô‚uZ´.gË×å¼ó‹AkPä‰[ÎŃyp‹øÕy„·†¯ïZ¶ßzÜ—Ãï°ƒy±¾qLZnbô¸˜ ƦçZhsÌö@¤yçcÎÕ~ÂáVÔb±7|¶ëŒöÅ´r€ªûë“?}Æ=Î)pê,“9dóÇR%7üËwêY¾&uŽÕ.©[z‘Rœ½ŒåÑ¢Üц/Ù‚Y>ƒìQÂöÑêÈõÄmn °½Xó�«zÉ'Û™Üs0µ¤?Ú¤Ïñ:r†9Ç í쯯œð¬¸X;§i²',œ,Æ .:L¯ ÷‰ã2Eñr]Q±w„ãÝ%ccÇ÷Žtñµü}½š¡?ñ]ó¢Ë5OÏÂɃfXó`:dllòåí�óÈy° À’“Åâ¼Çv‡ß0ªga|mæDWu0ùq)´1ê—  \Û‚ÇôÔãó¶Q þçWÏ™/PÅQŸ±æÊý c>Î~2¼–/¹¦ ôU—¸Ø’*8o\Ñ4;?ET�ç ?¨4–ûpˆv:È0{”PÉÍ|šÎ½Ž7ûa‡;{i$Ïø-ҵ䟪QolÕ^Ì^½IŠ\ÙÚzŽr¹.Úa`´Ã _lèyc·Žê«5výÚÆ-í7œz”Ú=Žãð&Š0ÂAf4åájmûEûï\&v~r9�‹› "°n$oêŸl×Ö°=³rðoúð/UlÁ¾Q¬rÃiv]Ò¯à¼N£$¦êô¼¿+å�«ÁièMj ¾öMKvþúe,ë<ئNV©/¹³Æêaüî‰äu¾ù5ÿö+(Y÷1Âs�“‘Ú¼ô{x¨O`œü�$&xsx‚A=ã8í›êÄapž„è:B3`Õ€è›7¶æ Äa·çpZ®éªX4`³M£Eó§ H/Þ Ù¦©ñ/GÒ(Öšð06Ü�Ù¢°ŒÍ*6nÁýbab˜M‰Vã¸ìS�hp4u²Ò'XlÁÒÏhÚŒÝØy&y³¼ô.ƒÎ0CÙêÎîãe¿ìs2óâþjYpêô¹ÍÄ Ý'Ÿ6ÅÒª¼HO”Ä}8Zå”f¿éßPìv¬v4+˸d›=Rõœ7ŒäýãPHpŠáŒª1\‹P~-óý^3\;ù²?ì[ s´‚Š&V îˆ}1˜]/Ç¢v¯DƘïý(F§AkãØó(/3y§õéö çùÙÖœ—ϺËw¸êfr?·7c@Œs™W—æ^^°ï:Á%tLÖpðÁØm¹¸“#Pç.ç�¨êFó´ÏùNËË œV%f ôr8S‚1�wG#;s³ˆ�LíæÓ{6ÆËÏpmºvëœÎ˽¦ð çlÚ¸ï�K̸01ÖSÏ*òÔ³zË ¥}Û뇮|ò:CÇêuNx–Ï›ozvãË|9´ ¦uá7ŸÅØ©K9³ñkÜàìŠYžÜ¸rhFT+>šLByÍ3Þr[±Zoç´{á>ŒE]í~3ôø¢×u>¶Óoøû˜Û:µY¿2§·…¯Æžopìý­®ñ:Ì„­ð‰fµ+¿íÌ�£®Û㡽³],ý[6ã;=Wë|8Êçª~ ð,“÷Ó¥ ™/wubûÄË`!eû¿Øäè‡ÿQ'» þW•xI"AëO"]d|rAìò’/R©„ø×Sôà¿Ú\‡YaÌŽ™á9aYÛhשqZsã¬ÂÒu‘Ù”åuåçóá·�û  Ť®êøà£ÁW åu¼‚vÚ‹7n¹•ƒ±˜¬ÓS'µ¿=Ù¥,�êT†œ_1²»Ÿ Ú¹ºµy{iŸ¹akM"r}@lpÔ£!{ÞhØ q,Ä9*=¦ó| ZJü[xFj€c±¤÷èüj;ù˜/ Qç|q–o\˜:8'r9_—›ü0gëÓŠ¸÷¿]÷ü IëDòÉr¸ZjÜ�f�NÃ`#'îÈzIØ¡¹Ä–þ½X¼Å(rŸ^J®=X¸GDZDðŠC+d·ï7Uúr®¯‚õî­ ˜û‰p“1‘‘Áºg»ÜÕ’Áÿ4€‘>ô¼ÂÐJ4ðÕîÐ#^‡.c6ÚÍ>-?ö¼0"G?´|j²åá‹VìÉ�/þæ6Ê8g¨c á ¸DÏÍwUi£Á}bÙ€,ì=zàZ^¾Ú7 çóthƒ©Ç~HJÔ¥ÏùŸãÁ/œ(»f(‡íwí�B†$Z}oÐ âä°%r\;1ÙÏž'€å“ž¥ûâä\â\õW�o®àR£”zÛ{@kòŸ­“ �€c\£’ìl÷§—ÑóæQ| �h`~‡ãÀi¤'dt`ŒØ»Ïu4Ðþ–s³<‘|¡æAxPPm¦­uÓƒš)‘Õ²<ÆMu=˜á¼®ÿz1¥åöLqΧÙHNŽÈO¯Œš`¢„Iäc4g¤w·É£G0ðõ<ÚK÷¥ùP‘‚d¨ÍúŸbɧG á:™µpUô¨kÚ:Ðs€^…Ñ�ø±›³zÒ0U|wÆ™§öcüÑí�ãˆÞĸßz�} ÉßDYÖŽK�î‰Öƒ·œø\Å­©‰SRèÜ<ãÒö˃m}´M¢âCÐ�8M/ßú™:Ì”BŸsÃÈÛÑ&›{öm†¹qè È`|Çå=y×Ç>X‰ß hÚ_8¯—Aæ¾²¾·—Íê™–Ôa YiÃîž­?O¾?§ùà¨ßû×Ržø…ì¾µßF‘š—¤éã´n6 \G{|n,?ÿÇ3í�'>ü® à3ðó»´$Ö‘U«Y½þS\%RDñ„ëÿ0º_ âÜ�Ef÷I붆râ{ÀX,úðÁ7®ûÛ3¾ŽcýP6V«Ï€Ìr¥^úuó%àû|‹JW}ùœc|5Ÿ¼á\¼ßÞ˜|ù[ê ïåKnâl4°1§éI´ŸÜ‚ŽÃuI »ðd?;|t0EºW 6`�fŽ}x£#ýX>ÏËò‘þd�ÿjcÎÍ5*)³ã©É…"ñ˜ ª-Q˜lÒqsSÃuüý¼nÄÅ’|Ö…"÷bg"5’8ùdõ/E”Ïzzuõ+ËIr†gò9M:¹rè#Z™#fjã2ã÷,;cuÓ ¢çy\hÊýÊÖç8‘ä}cc5‰cg$6âï|~è”Ñ:åʹÐ+«Çá¸h¥çì§T|dÖØñ�öÍ+ÎU‹g¿L/˜ñÀ "ùÝ#íym„�åJÜ�ÜŠx ¹‘½Èê�îÕKN¯5[ç¨<§æÒŵƒ³Ð&!™ü˜Ý{Yìšì¬1уõ•hÆöœQøeœÓ î)�»uغd³EÉÈG 3�Œà¨{’Y£!:ˆF{çÓ¿‡'Ù³ó›™^6s³MíL3•J˜Ï(f¿Ü4­mºœø,î›D—¨˜'Þß<¿ÄÙÖÞLÐ#úœÿÑQ{=v¿»—å'&ý­üWb7wm­ºìÜ}˜¿¹×ô™r6`¢Ó­‰<³7è嫉Xr3’›dôî矬ƒ‰KÒµ)ñÆ» âRC�žv‰Æ`fk˜ãŽígáÞÎF:Ò+�Ú áýºZN_ß™V’×m› »Óá3xYÂ?,VÆæ0w�KëÌ™�“Uë0 Ü—÷Ɖ~rMÇ|쓊è¬�ÿâ°ó†œ½Ô‡_ìyX—׉P0ÜW,uÝJFy4È=¿ aÆ¡1»£Ã0ÿx²‡Cø9 õ#1Zz�ßµŽ×Ax3¾œ×vXˆ˜ùôá®mæÂ¨ßËE.'uËq¸1š çÿ7¯{`®§wãÕ û´ÿKróô1/¿×ã†3†ÌŠåÃÙäøN¶+Ü7Mxl#ï°~qeg5sb+Éf[ ! 7ñH¶á£%ºÊ‹N ØÞÚœÞ^]d r†ØÀ$_RxOîâ©ÛÜãTŽOŒiÂŒ=Ú4±V̸Ù2@ú€½ËŽÅלXg3buaÿ­Â}k‹s^™Ä¹pÕíÕ0³mOØk³vœÔ�“ñh9µ)ÈþùJB »�q™ª/†€lÿ©5LN•t Ôf88§s·²ó( šŒ{rç  ³¹ÀÅý$¢†éwb.Ï�š[mœ•çs1¦5Ën[õ°6?vi[™‹»ºq9˜¶çÞ#“L<˜,¤¹b'¼É{rT{�áÑzѳ޾´Mß’Û2®‰)õ8À Ç±Íúòδü›)Ákͯ¦Ùˆsާvç!5YŸ2›Ë* óçÒ²õ8ú0¸–Þ;lÛ›õ•íÖ¯VÖKàÜèÐgéÏ‹_Þ¦(¯#޶ùøaéä $)“Á¾i­É~â)Ëoб8Ìvk‡ÑŽŽÖ¥Y¯àÊ=|kÃëJÔ^¸�ƒsY½7]s „ïèWáïªÛO-h6k)†–3ܧ&n:¬»|Æ>¸aSÙíÉé{Ù=�`ôi£Ç©��ëº\ÊŒ ~Z9q�1pÎÖõňÂnïÞèô† 93K³¶Œ[7¨åÆ·sh�*äbk;xaY[¤BµÌy�>ò×1—ÿø¯”òcsh]Äj•†Z‹—ºœ–ëö$øàz �® »€=05ar™ø/wr„ß½Õrõʼnø–'1䡪œ7ØËϺÿ>;¸€eÅ _™}„6'<Ñ[b®ý«Å4`¼(?[DyÒZw·žbëϲÁæÌÆïžK&®p×%Vòä!qÑÏNÃÀÄþMC=?a„5÷„Ê”?Ü(px“’™¡|]yr¾M(ÄÄÎìYJ?X¯Ìþ<»@ÃiN­Å‚ßc>¼�É=ÔÞ€-Þ½êÚÓOa€i¿~æØÙ öÓƒjòš$º� œË��\¹g�hNþ`&>c\×Q ×�‰Lüýý§»æ®¦Ø•sà W×R¼µh0Ý~¦á^:Ö—õ˳›‹‡$Ô¨}¸gê<^3³§gA&öÚVA¸Âp¹!´íöá׋s.i#;kó ‡ï3χ½­ÿÒf„Ïì7Æ…ãÐÉ“:0ÿ£Ïû'–ethŒ -èÑé³ `Éãñô/®ÁX5 OAQ˜ 6s:²OÁÛ~ç Úºô˵�a°��ŽyõÎö¤š.L'¶º“òXOÔê"Ûo±ú|{=ü'‡ó…Û~Å®Ws³‚´_õ1ç>¯O{ÿì'ŒñãaOÌb5›k<ä�Áý’ͪÀ‚ÓãÕo Àþ€�+È„uäye›Çä`^,û�%Ý Ð×FDžüM§\ýˆÉf.ØÞYkkYa‹“äþ oú†…‚553ƒfjm–`j°Ïùú®:FöøˆÝoTjgbÌn 1�ëtùÐj}× v\`Ùža½ø£ õŸC–Ÿóiqnfi‘µ§°/½‰ÁÂÁ¥Éìgh¸sÎG˜×øÐäž;M kDyÙ��~úS¸žPö}𩃞²Hæ_S‚a¹íúè¨$rô‡8g¿À“÷˱ã�ã�H{}.gè·Û?y#'ž#_Âe IDATæj?nNÕÒs�ËöÍ£"&ÎÓû7FFëH-Ù+ÖQZÛ=¨2nûá67,Px›Ê=;§²œÃ�‹ܫ͘·©NðŽ].ù¿äë që_9çµ@|ú‘ü ÇÝW“ÁÊ5uD³7®yÚ¡Ã8:µFêìlÂJ#¤Y³i]8>³’ÍOy Å^Ÿâ9–Õ<ìÉ} Á·º‚AØ£AÛq�M.­î H/Ñ üƸÖgs <ÍØ3 :ËáRù†ëÒz® üÝ¥ž×â^#?îdç©~û¸´ZFƽ—,ÃÀ`žáˆe°‡%õškÜÛÊò=7Îj ãØgÄRæô]kØ“˜ džfcŽ;:؃puY�B19 ñ3φe9¼^=aô5,ÀLpB²� ¾wx‹«!ôŒ�Œö>êÂ{p(¼Ã<ÔXÛ4ÃäÈçáw/í û䆄=êÎVè΄r“Lbü]›þY©Rœ¾àÐXï—k6&ÚõÜ8ªF>n�‰}H NA–>¶g¶²ÞјþáKÍ>w�Wp„¦�ž¸µ 2ðx_·]ÌôçžÏ=aB¡èÇ“>Iñš›¸T²|»žñƒszÓç—j™&Ûûƒß¼–ðsYWOÆøÓë9|‹êÑÚ¼gÝ}}§/2ã¡Ý'Ë Ÿ_  n7 ‡ Ï"¯e©ífv/¼+gB ÜCËù°º?É�'Ib´5sÍÆhý¢‡ žxrvy¾Ív£`”ʈÓz#±¥ˆ_.Ç/¡B÷—ŽDYÛW�âˆ)çæ¨³¯OŽ?˜yzÿ®0›ñÈ= ?õZ�6®Å8`²CÌÃ#1Û%Nîú£•œðitš?Æ{uo‡•ùͽ˜oŽB¡œäq.¯õüYÂ3à‡{1«íä2Ÿb”&5p¶ph¬F-í3æÑ°Z d»ú†ß:�Å´–™7¯5§/hÐÃ<i»mœ‹ÈÊãçMuäÿÜ�ΰR~YlH�­ 4ÙLc˜CòØÈ›?–/�êƒu÷Ö¦uj¸1B8�c‰Û^ÂÁºVlvpé:KÛ‡1wãhD|áιâµ>ËUÜ©W>ëíõÔE =òÔÞw�‹q¸²flhÒÇfël�Õ)?{ïN ÌÁˆÆköX¬·ëa<n¾è©fE9epÁM‚Ž¥Ý'ñÁ¥ÞÓ#LJÝØçCgâ®ß\¦•š;«…à?Œã\¤æ>¼wY8Ìà+9ÇWûü]lV·'ì‰ežï.-@ø÷/-‰øà�ý¡¦õÊîRzÔ&n±œ3$lÓxhŒ£ éòü›�“�á.{ŒZŸ6AaÔp.XîÈ”^K¹P­?5™IŸd£9&°9x+¡“ý ¬‰ÜmšԸ—‡qór$WË ×“ßXâ:@}ÖMˆ Ÿ<ÚלhÑc¿•Y.çÐ?5Ýme¦óeöc‘ÞⱘŸÜÎ×<Ô•êƒC>Ût™[kè)Â=´Ëg·D¥¯l‰•-VÃC�Ï`7Œ]ó{Žg~ÂÜσ±!=tÆ‹D1Ù][SÚû³~Õl�¾mçRØQR-,€®ŒíÃÛ�ô åG×ñûL챟þ@Oô'çlrxxj¾“\ÜÁÀ³GíÆÒCr9_æD4ùo/±»j6ßw×áx)ÂñÍAÎåšÖÄŠæÁ†”«ŒÃjñÅ•w©ÍM^`Ìé&ϱÆ3kX�rÓ‰3Nmà;:’"µTÃ|ÌYß±‘]™C\�µáKžü¥Ý¸Ì„ï|@”Ç©³{çþ©%esÆíGL¯?5pvŒè ʽQj”­¹ê-Sú5ì|¿ZcÏóšÛâE­êœ@Ó[×øæû”…ÓDêÖ wpÌdŽ7L÷®Ûuù’tÏ2®?ÆÆûŽªëô‰®¸j'„Ö9{g×"hbÁån x‡örœšV4§Ó–¼º*¬­Ëúäv–è[“dBÓ¶¬/›~AÇG¼y[ŠðùÁdî\ÑE<Êr˜q”!Ž¿\žä�¦ ´¾Št­ì(ùä–:¢×½2qöh9e�,¤‘_JºíÜc©e2§{ Á‚$>ØØ¸ÆZŒ§æÙ_[�®n/´n™•X �[ŰXoQ¯¶�~�_´&Ȫ¬â$&§-fÍÅɼ„{÷Ø :ö›Ûç^¸GljNúsî—â]¯×ùË”œ)üäMŸÞ7Œ8Øà1«/ô,1‹wOŒ‹>ã‰%N³µÊ¿ÙÑöåÿÚÎ> ¾oþØÎ ¡™¬æÚ=„Ùø´ Þ_˜=0æ¼²§†`²ïUÁü ŽVsÍÇœ¾�ˆ8§¿±öLÀâ Gè3–î˜äö×‡Õ ¾ ôq¼ÍÞíÑ-<}²"ùlïªôHîÑl¶‰M NIœ5ÐCøòHÅwMOG^³§§_ï!þ„ølíR ß NPÎÚ~ŒíÇùïjŸšãšVÒ Oí©_/–€¹š´œËík M�M›y1è�«½be¹^t£iZ—Òž_.¬ÕäeÖ7¿Œ“�Ÿõì5ȳ\™_¾`$3¼;ß;'Öõi9në­íåyÖ>�W¬s‰»9®�>LéCãîò|`}Š~-^»FâJ·šßäÄ­¾Í PPs=O /»Ï}�ô �5N8Oßä|ÏÜzGóA Óˆqi}öò­gàXû_£.¬Ãd½«ï)áò|EP<‡“AOþr¥ª[±§7аŸæÐ^›S5™|à`Ú¸üäÖƒ™�—S6çŽÙù´žfâXC“Kö¬1mœ�s%!iŒA&YÄ�W3Dæ¡k7ó;~ø:ŽŸ}ýØVÃW'åÓ«ŒÛž8®>@¤ö'Â[|“¯¯‘uùÁ¿œãÞü’µüK+Ži?ßoáv®·!T¡}5Ø£µmäÇ ½s²©6›y_¨¿0tü|š§Ñ|PÀõ‡Ù|Î×<Õ�=÷’"ɹṡßêÉ;ÑX‹&½êbÃ~rÂ5>ÏMÜOB™¦I 㢱¤¼VŽ7KräŠýðÖ8šÄTì¹Þ¸×:þÍ ü$ÇËGÉ)DÁøg΃)‡�W‰ñÂØ²iXqóÇz|Ö2*bßy‰ëPÓ>E:Æ øÛ¯‡:g_<> €»LJ®]‘·þý¥¢Á±]z0~¬¡–ÎÕ~¡×&ŸûþÑñm4\—ǼåòÍ;^â›+wÄsUç.MTøs¢ÁÀC’öÀôæ%&}‰—Þ„8{Áƕڌ1KhÁ™/³5t*YòÀu'Ô×å·~'³ÐæÑºBNOŸØ-á€÷—ÛšU»Ûëd½1;ûæòr˜B�C6Ì'àêNŽî·i,:<سÞìžr\ø¨Õ¼ŽÃ™ðöò@µû,¨u4É‘:�Üïób»"—„µòo¯x÷>t¶òÍñD-L³;ÝýÑä¸ÍéeA+()¹v´~vÍ;OæÅ¿VÙôÙÓþ�¥ÖCæ¦hÇì�²?qÊù˜‡÷Lÿpò ÆK¢]ÏcèÕé¸ì;š_üŸ´© 9o~�´#Ú¸wbØÙΟ¹ÝÙ¡>)¦ê¹Ú_G1ãe^>PQEM²‘­‹¦j³ë¾�ðEìa<ÛÖF^÷l%âý§>öKètF;{´ã½ÔñåkS´ôùWÌZ «†œ?Å`¾O�µ¸®¬“ÕeÚ¢Ls`¾(Ϭ}ã¢[&ç• uŽýµ®cåw}²¡œÞðÁú3Ê�mýK,Á’|»’_Œ8õpßX—>\й&¯;ä8‚ÌÚÆËžÏ©Õ�±Û6’êÓX³hûd–ôãÆî/ÚÒ|×éõ‡÷Æmµ^=aOÿ|þç ÁÒ«<*ÉYÞÔíN²˜{>ÍWWüdÁ}~˜T4ûØ”«oò³ÿ΀by¤Çé�££„¶«õå .xXÞ‘=¾ñ½uO µÑûa”Å{ój…:üQ "mŽÿ• tLº*Ñô»Ÿó(¹ò÷}#Ô¼�ÃdàQãÍÑÃvk³›U>Pn€ÞTSÖpÞàZíøñe–Ghþ xÂz‚Á‡6]µLèp�5™Á…±žuw˜YÄΛíüƒ«DÄ^¯¿F᯻B†dKÝ©•lKü®Ã}S¬B‰ŸðЭհxÏN*@s¾>øƒÉâè•1ç§6NbŠÂe\,X�n-†8èðÃæM‚¼>ñ�kƒD0³›_ÜŸùµi�ûÉ2e±«›#>µ¾:YÓµøNyO¬ll8V÷$õ,é®ñâàÄDûä:kBø·Ðzɇ·ë½€a8Ânoa'ÔǼÐæöBÅŸ=›îm[.Öˆ@dGøÁ±­†"�s½ÂÚçfGÜ>â×SÚÜ0§f¬–VŸã�5¸ñ}¸‰AW‡ëÒšy<Î+Ü|Ûš}%Ùáâg}ß[k¶ŽŸïQÖròC²‘5P³h´Œ]Ö@ÎÖk|ÃÞZö„kQ g¡$ãÍ–}H¢#}™– 6„éqpZOßpÖ¶`ú®1ü̳ýhS�Îã\Ä÷áøæ‡Ù¯wÀž‡ p ‘áBƒÏ¦ÿz�ã˜5à[¾ÃgGŸ×³‡8OŒ äØk0û¥Ë 4û@§†×^u�¿ûù­/›z¤¿ï-ñO°ÑDˆÐàzÞµ¥üMŒØ?Ž ³3b1‘…¯¸“íÉë0öz½<åõ ÐõÉ/¶aq¼ë�i¬×Ø+hºÆóÞh¬oµZ-×ò–ßtå· Ú/vÕ“k�….ÿêcŸ¼ô!cšÃ÷jŠyˆ;œõ B~lD.zùÂP]«a³c lÙ§‰8s°è˜wzlF‹q–�^FØÑ(z£ôÔS ±?&�@aÒ;6ßQ¶*îõÔ8WÛö4NZ-s}µü�’ŸÍ@¤¼ý¿V­à…ÓŸa²N–Ù~u ë¾­—†H@õ^Í­¤ºSs{[Û9C×$Qé\ÞÄ–Þ.UTqži‚?îÌå4ó»Æ`¨Œš¹°y”+5Ôf_È®Vù°£ÉSÖ2뜶Ò|&|Zn[rÏ’VÚzN€ôÑ»¼½�{ñIÃó#÷Gö@e|âk»y†á–w1Šs6¤Myo®êa�Ü1¼­¸´R¤fZ9Ã܇§ŠYÓeË?si"í¿cz6Çk5¯Ñ>”§.’ᄄrãÐèšëþ$¯¦'õÿO×¹hDZëºöŽõÿß|ÇÁÄCRµ³Õé’H‚ È*;‰ã$Á¨ºòN¯ä³úÞ±qj}æøFâòe¶p$+\©ó«ÓI°Ä<©ƒM·³ƒâçlbã°ãŸÆÔ SfF<ú©“¼ýÛºýÅQ(| R&šÓ»°x¦‡“%×탊ɥž©J�Ì\úøÈ2«ù9ÂiÝò¸¦Él´^üѬ=¢s¯âðèÈÞAgh�Õ:uê(ŸçU}ž�HÓoûB¢^ð_ŠÅ‘sxj×Y·Î¸�¢Ëº>è9Š5&˜l ªVzvr|æ')‰WcÃf¸¡(¦Ó=\†%z§8×åb‚UKRj¦¾ñ>*‡0šŸ]G¬lºžûdÀ� w¡™³ xÞ�ß9¾˜D¹ B%l<è_L{sï¬âÀ,ºmYKîÔ8yÊ!/\‹ Ýz+KdónöÃ&Îsô.,½W¢5W;î‡!�4ÙûC§óWƒ•H½[3„î“ü‡#º!™~Øä gßû8È=‡Ü) gsSØÇÉPd·aQ!¥žß"KM#r�ßiÑt"®»ù½¼Ã¯^0™�úGÿ™Õ½¯4>¹«œ™~ó©â̧XçÂM›ë˜œ¢÷ã,üp,ð@æ Žg�ºRË{P¸DTÞ›ÃlkQ^8Ij¾ÆÎ†PË8`Ø«ËA?¼®¼$ÎSA"—ŠÀÅBi^åâù& ø�·û5O8H&×x—Xê/žºPûÕu‹-ͳÝóm7,§6Ckоœ³SãÄùÔÇ¡7ó°¿ySC˜e÷Ú³½™áfi—.ð _ØB¾·ÑfÎv‚h±Û#>ÍÐÿ„Z´I~5ûoo�LzæígEò#{²ƒ»œYp¦ÿ“™8Ö¹$¯œhmôÜ6Ìû¯‹ãÌ»"ØÃÄÇV³áÞ{$„äów’ÎÇþê�9^§7gmÏ@‹›šÜÅ—ÇŽsd:;Wyäp^Nt� 8sëd}ͳ;Æ€ÓÚ7�Ø(ž¸ßµ£á>‡×IÏ<ºmiA÷X>×ÕÅÏž¬û�Ù½…ÄgšèJ¬ìÿò92.‘œ bä|òVc9Ý-¹‹›ø²æÙ'ù¼ÉÛ[(w²˜lø=ùÎ``k®ñ«­Ýó ®õ‰É&eëê�gùœ\¡'%ÏØHû‰›ÙXnkyr§µ÷•^ oý7e ,Nk¨nzÿ,ù§iþ„(ãg¦èAØ%X3çÌ;¿1ÉÙø~XU>Ÿ8È�*”üªÁ“—õ†¨ï *î[iµ0Á½x6‚Ž#ùÉM,gs4\Š?{)¬µ/¶rŽ^N¬qÅâ ç(8g%2l³�amâàþÎ Þæ’›¥ìNdçÊóNänMΦ•ÍñˆR–¿˜Y“‘E%ú ë|èçåhõºŒÖI@+z´;8DüûÓmvñÉŠA͞ĎÉ5÷‡SFƒt0û½·Ê2¡Ùfë®㲸 PJ ¢h‰:3¬sàã…ûÕåûKJ)r¿C l´%Á÷Aö`A…»”–¾¾,¦�ÜÃÜ#K/�V›Ü[Óâ�>SY,uµn!ÅzŽÖç©©9yßóËÏ™…F`ñéä:±sVdC%~ﲿkOW0p®×qÃ|–¸È°‚õ÷‡8óÏÑk¢ñG÷WÛz˜ªÒ#o|\8ÁŸXBŽs̺÷nXô³¶û,Â×N-åÈõfù;VП¿øUQÐsØßœ~/êÁ�í’ž˜³!&ã[ ¾¿ž4à÷i={,æoþþ­<"îž¡jù~Q_¯ße± tz!µº¿9åPŒÜô—ÏyÉͳäÒ\ôƒÏiþ.Ïê‡/õ²ïŒÿ<ç«M�'ïÍÖ:ÚkDCRk»�R,,z¬ÝíܹP+)¹bóâGð‰»&ÈÀ¨ôÑžrlN®s9‰<’û®�í¡ÆÔʼÉ=õí¶8#À@ÆÏ®{•�¾D˜hwl>Ê6]ª¿<&xªœÙÈ—óPp¹cÝn¬]bð¸~5L‹¹]AšÒ9œÜÛòro~&Bì9K–}¾|®IŒ·3­6<`£k«¾å1ÛÐ�@¹?N”éÒíç�áç\jîQ 2%%û‡Nä÷½²N‘¿ëkÇôâÜŸ{ñžZÃn�³ÖãôLtš.Ø®D ½éc8\Ë3úòÐ]çOÞæ”AŽy©Á[k¿>²¡|Öð.\\"p´òtú¯[¡s¹¼Ú缿[ÇSR-Ýp)^r·®ó0;çñ˜kò2,“=؇<üÀÉÓݘÑt'ø*?xçþ`cV%ÆÞâÈ�.+<¬íœ…ã7&¾w‘"§µœ¼ þ �º?ë×ó±¾cs©Õ²‡ÍÊ©_­hZýà“sžž~ù^ ëýä�ïü#Sµ-âûüàâmNåæœ |@ïØühŽð“4-ïÀ9»ÞQ–Üšëv;…=Ä’'-Ô:ürZOû{©=E—8?ÉDú ŠúÔÈ«É3iW9ÂŽ?÷¨xåY¼�…ùá>…ƒµ&áí­�ð®çh‚ÖYÖf t½Ä ²ÊËY8­£¾ôVÛ ¤‹Äs|jL[y 4$Lº–c¸úׇ9‡æédÜ)M@‘/ñc_rrÈjøBÚ×'³¾Õ™ â^ì`µMSp…}~uQöƒr›OèÃãº$ËËæèòö Oz¾¾÷¼ùuúç'zü~¸×÷ãÒñÎÖ}ÁÈ�Oƒøì³?ÁéÈs*é\õÆ_>b™k²‰¡'+5j(00«í¤‚Nûùx2öÔq[¨ÕÁÏM!ÞDÿfYæð‚TDëæêä/˜×kx†@QîefNx=3Ò<4aôZÞÝ“èqgÖs4!–åÞ£+\qz†ÀZ¬Ú£Srïë¶t¼ëÔ«;zèƒ÷ƒm ¾ÈbŽÖ×Í[ŽT¹‡Ú݆Có~m…�·!ßVJO„9?»q%uG’=�y‰Ø½øÜø�cè}o’L�mm�EüÊPéø–1%Äc…àå9ä–ðœ£ÑthŒG�žʽPÂáÝpâË»ÿ’GÌç~ÿºp^n4'þ¦Å—Ï9ÑI^õxf™#9`/Åj›˜|K¥C�]ßÐàfùÃ�¿LæøWùÒ‡“äŠ3Œbmè[ÏôŸWyR Ðå³â¾?Í›»ãþB(÷°÷kB¢{÷”ó4à>f“Üž‹À™µ0�n¥ž~¨lM¥IÍN¹`Î „­b¨Ì½Yz·¸[Ã�ßÏ%«g]áž82'<Ž?¦ÜždþKß|Óm&굟í®¥æd9‚dv±¬«‘ÍrŸÏèm‹Øjá ‡vD£ÑƒOÄLç)>BsXuòõóSúW ÷Û5€Èvä®0g-ê–Ř[/ýa/÷Î;¹ÑÎ5/ê®#XY®³óü^ ‹ýGôÄœbÜåƒëpº÷'¢„0j¸nk~кn(üèæÜkõµ�íðSmJÝß8‹fʽŠÞìœóýõãIO9¹Võø\Ý ¾öÕ…k³™ÖøáÝúj4.©eX?d6[ñÝSX8_ûÂ'.u9{3y9zßáJfŸº—�¨Öë@'®×'›¹ó²®% þ÷¾|°/°¸=ïµUÐÿæ“°~6*`¼˜V øÑïÞðj¡ïŒC‡Ý#Ú!ßx#íØ)šüoý\?u|H~5»V+ßžžQErÎç’$xŽÍ·žòLgL7›Ú8„‡n³Èp&FÃ/×9¿: …ÎxÅ‚{@îs_ o€ûJºµÅޏ‚ºyô&많ݺÈLpî‘~ÚÓI¨E�Ì‹þƒÇ€Øû\‘ê™[üiuØÄ]ç°kÜW²ó`|`ÑðÕ£<~v«eo‚µãÒÿŽÈ¡í}–EŬÈåàOÕ«+Ï|ñ��ðÕ–6è;ÏYüã¢òêꨜR¸;«Œk˜{:²ŸzÖétçŸâú^Û×Wô1êÍŽ¬5`ëºX $A¸2C[ám>OuØïzȉE céwøœWVyмé'?N®£K½�ÿîÔÈó0õÉ€ÿÎüú"[ttyÆE¢œŠ-ÿ‡ÙþôÆõCb¶à¿üοÞ2³ÐúMd ò¦IÞÐŽº\8Ÿ‘�¼Õ]mïÈ5X0tõe ޹J0­óÁó�¡ž'=¾—×½¹Ñô¹úaNÿø6Så IDATÌ+ÏNêëå{_§¾ ¨ÛˆuDø„ƒõ ûÔ:¸Ð¤¦æa�H(g’o®u™2µÝ½/r’¯_?Ðr/>zŠ f9ÏìA³ˆkWv8GZâ�®h0 iÊjÉ>È,¿Æà ·ó×4.â‹ë|s['áÐ=ç3'f»bÝÝ7gKîåøÓUz¶8A_sÜ›’ßvªè8Á¸ö ”‡•ÈÿàKüê›ÄÕO�·ÈüFèbî€÷é×i§€ºj¼h3ð·+o}JÅŠDéÑa½³{v¼'¿ñGËdéYò<¶ã‡H bÔÑNÖò_H›×_d„à-GÝaLçx©%$oÖÓÜò7€a>öO�圩¶º¨T­ž�Š*æäs*æê޾Ã]NmNt¾rŒÿvƒr9|ê6‹Ú݆yÏè±>ö#TýÈ aÑrüêÓf\L¹$Ž¡ÞO¦}ÍêĹß HîœÝ=µÇº¹T¼ëúës^D<¯62=­ò/÷Ô’ü›³ûÆxfUÄ'¿¹åkδ“ë×|ˆÓ"Ç|wjÈo|ç †e½;3è\ “:쪟-{œä~ó5v³€ážúGMÒOvó·g÷@ä¿Z]?³t’‰n½GÐr£¥iùüBÊ<9ёڣ—õåg@NJâÑ"ss¼ÚH6ƒ‚ðpÖên�­¿_´¢žºƒï•üÕ3Âr—꽆ü'_ÙnìÖs†óÞï7˜¸zzp©�ŸøÛ­ñÐ,­”®¡3;¯ƒ{J¦N¯ò�b' Ôò8`Éá¤a¾Z¼ßÖNMc:”ûW*ùØe)þ|a}uz.|÷�c"Ëxà�ž_MOZŽ.Ä%ø«7 yÄIñ%¹={v Ýzà6“æ¸L5–ž4ò=»�Õgw¢·œ¦�=¸x¸æ„æÌB.cÊ1|`ƒ·BgFŠÖîЫ�Èê¤63»=Ôw‹ç;kEÁ§Š÷Ì€ã~jèhg£À«Éffà´ä£ô´s>1tÞÁc³û+ãÁ ïçÉôÁ“lŸÔ‰üÎ(vî÷ÎE’ž)J7ÒóÜD{$õ9ð³ ‘ôëê\®Qº<Ûb§-³è3¨X濌äžßó°\O!¨ñ§v‚ñ�j]8É/ŠHVúáüÕÐ"ÎÏ9ý¤^“»EµŽ^�Oö8lÍèO>ÿœÏ5ó>TN’¯ýgi¾<3KŸ*´9™ÖÀÍÆe¶ç÷Äl»ÿAt[\ò\úþ�V9Ä8³´�Ó;þÄŠ35EK¢-VmÇ•é{Œ{o�&ÿù�p¢�3lZ¦ËùjÈ}û>kµšöI¿D‡Ö0ÄYÇøáR’§¶)NÄ÷N‰ëêœÛÅñ¯?8Å­ñu™ r6Ça5×îMì�\»ˆ?9ãR)¨~éŹäagÖÉ¡\yiózó/7¡Û‹'¢`¾Püôe7Yè�ÚÞ ´Ëwêø4KüÔjÜ ”¹Û‡/>¸ùâڿ+*`tðëT}¼Ë¿Ù»4½5­›Þ&6’¸†+[Ä…csŒ=ý¿©ð$Ï…¦ßnÛ««õÁƒïgÁ­µ�åXÏU”Ë裡½Ã@Cœ–‰ãØœ§3þ©'tNlàyÑó™'<Ã#]¶û_ÁRGo0Ä—çðÊ'L±pí3¼Ì�Wo2ç-Ÿkš¿³þb¸)÷Øšã3ÄPN ¾}Ç㲡¢g­öûÂlà-÷ÑTÄW×MãD,-¶öHó��{Z©îq8h$ðæ;¡Ð †3k{¬pìÌþhl8}¥oÖß›–°˜ç\hnöÓ§çùEœzÂùùd/îp×÷É”AÜ9ô=Q€>@ÙÜ m[M»1âaÏÐ}|ÏœÍÙÚ.+ s À½7ö4:¿"_­MôÜÁ’»uxäSLŸ}Ò4ù‡C RÞëÉ%åvx¼ˆëíápöJ̵ëY¤ægÛ�³Ótûî—›µº/6½-Ê÷7�|Åöý„{n6)M[ö•¯øæßw÷�%}ÜŽ#ƾÎBç–È®¸m'ëT<9y°òO7'ý�К¡ýŒ·c\þ®èŒŠüÆù/ÊÀºvûMnñ¡¨Qy§´ß€ 7㙞'¹Z©{síyƒÅ¸–ý :ýí�sÚØý¦KfÇk=v�뢖®ô6~ï“Ð|ÏŠY`×÷êÈÒkU{³O ^´êÈÕ'(ßÎuL‚TÓºN,}† IoœY7Žæ¹"6%ÖƒÌto÷iͼªe)Ô}xâ�‹~ÊéhHBç-\ó, ¾äZY�õá?ø‡#¢x4fn?ôe¹µÑa�8—¬Ýµf“¼7uuv_WjÈa�8!Yô»Û­‹çí9¡§9ä­n9�}4¼>JËç§·»áÓÛ~ÈÇYS6UWMÞW‹¼†à\o÷¯õ­@¾`l rꆆŸgÆt óÿõ§|ë/ûårQ.vUŸ‹çžFkP«iŽêuD¹áÅQ~.‡‘¨Tä¹ —3"6ûJ ¾k+h"=§ä†”„’ÎQíõ—Ø~3æ§_i–pÔ-a|ԩϮ̇n(yÊ6†#¼Ù÷ ²p†6¾ðàY1N;›üÔú̶„3�ÙJ�Ÿ�gzD÷~ƒ¤ýH$§N4ÊôÏ!Ï}2]ËŒÎ/XùhyÙS)9ä3;yôÃóéu8‚iÁ„žå¦7|¹ß›�¡iÀüÖ–�œ2�i63ÙZ|zolÚ‚¤¦1�Ûó�?ý ÷ÄÆßìS3rW?ÏümÅ|¨tÍ ,!µ¢‘bJrMøR|³“Va¾¸äQÂeí­Ãfá>O…0œ´²ÝpØ—ÖòÇwj)¶{¹}¤á†%s`_>œ«mt-4¥¸ï@浡c¸p«IJøT�³Ér_]Ë'czY­üºV‡Õ±·º�‰†è€‡ y�jÖCbæ ͳ—XVtGÏÑ­ÐüD\KÁH”G|ð2Ç«_bø©ß呇Eä»èñëy­ð¾�å<½5-wm![eÖç†ÐµQgsØ-0Ìý '��€ûÖÆ™ò�#ã~!s¹ÀHbmçœyrbMk,{||3vNM¬ôÒêIµÅ ¶Qîž(S7}gw§Î™çb©’’�3[°PïR¾ �àcqô\~yÇÅ|¦Cçô£MN×z¸à‰ròȓܘëÛzêÖ_Àâ*½ž¨±µ{JÌ~$:'üÃ�ãó¸°Ûœ¹GJc«»bói9=ñ¼\ÐSec7Îeu9à›„Æ”Œ|ê¥�ôf3ÚÖ/5W÷_:\-¶i²ã±[Æîw¾v¼5Ðɬ™k‰ÚÓgbùµp ƒÑ±–w\¿uÞ{å¹4㫹õ©­ub!Œ¿t¦,…S™zÓ°Ú‹˜ëíSŽõH ¸¼NßñœüÖ&c1bxÆ7Œwü;tÿàÇ÷‹3|}~>¦®^rüŒ°;¡zýú8ïy†è�’™áÁ×Þ} G§0Ó½ž¼?3™$߯&r÷âgG¯^@3‘êÓæZpW//|s‹Z?×§i‚ïvIÂb>¼Ý=L–a¨//¯+Ê놻»±Š;Y?µR™¤é`ãׇ‡P9Ì©~òãm=ü5~³Ù‚Ûí�ñÖ¡Ëó üS;‰|û)kšž‰ðs¥ÎfK{ú±—o?­÷.`¿±àN_OœãÚ¦—ŒS3¿¡RÀ ë<ê·n0ÁBŽÎau° <š¢#¦ˆµ@ éäÌ÷ô…>¯ÇGÚñ£S€ÙælŠçÜ4ã&gxüÖQ¢£é�äÀFŽ×02ì“›øú Hµ<Ë¥$iõs¯’硜$Hg°+OàÔŽjÅ]!Õ5î7}9§ÔÖõôôÕýêäÜÞwFWÖfçj�s:C!‹¾Dqp8>½*Nkž[ki‹¾“ ýYÁ*­<ÌÕŸž™`/—³:¥òn®„^½îÇߥ„7/k£/[ßD(ŽZrÞ[õ,ŠâòÜ}8LÁ%Ù‰?Júã7—©+£¥ŽMºãÊëÙûH•0®åZªô¹Ý}ȡԣãqî�³œ�¤=²Ô¥357B9tÆÛúË=ðÜXXÍr{=Í$ê †åE�ο<¸Ïí8¹Gˆ³2SA§›á#žÞe»”.>®.à ~=¾º‰$v%ãZ9e®™l<ÞÚF4Ú_ºÕ Gð;7ã™H¿ÓÄÐ8NŸÄæ›dâ>GÓù_=‹M�lZà}Ÿ™áx¬2(®¿ñs—,Ctä9m<6I^á1·²Œ-Øö½¿d…çúnN8S¥äÚVG¸‰Á‹»öÎÞ›ˆ9cð_ù; ¼h‰Þ¸¥ÀàeÀÀóÀNÍ(ŒEä™ 1§†U¯&²Ùk;õJi*ŸuYÕiž¶Ô›Ž¡²ÏJvôùcÞZ‰þÅ]ÏTt_£)¨Ô q¿�ƒFcú“…CPôz9-Vž›Ýƒä,Ï:­/½¥F8ƒ­œ>>gêUïÅÚ=ùÆ­ãh7½ˆ�V®–Þšæ¥dçà&ÛÛ[.8v=yÓ·ïü ü†öÂsózŸ�(o¹ž*S)sÕõI}Ïð»Äë\õÌ�ëj '‚Qç{ãCôÝ¿´7ƳnV�'_��N4Òr¾.¸wOÓÊ Þó(ê{úþ�•/:ÆÙJgæƒÖÓ¿Áá·&ѱ%@ëšOñiO„ PŠ™Êjà‡w0ö”Ì¡çã’×q§ˆýwðÄ ÑÂËÇN)”éÔ€yP~AlÜ“&�ó·V¸r° ï½»rM@¢¶߃u­Îƒ�uê?zÇýÎÑàr9‡\½Œ¥7øN�F÷ÙäÜyp*fuÉY=B£ ö°WÇ¢ÊQüÍ#qºæ§ò±èMîÑ>€öåo¿uÑu{å솩¹üŠ]»qÏ\k‚¿é¦7!ÚBýÀ~uàÐ÷JžÒøáutá¦NkEp£h¶?Y®·ycÛ�è Çe¨|£¦0=—ÂÃÙÚÚWà4ž}^2l­…ßÞáÃÿúÀ²PpbÖ?þéÛžœ‹1¢:vHúôö�fP�ÏzL÷aÑ�ú5„½¹ØOZz|ãàì;3Ï#„áS^ê–_yþC ùPWæÓïÇŽð’c‡‹¿¢Ió ƒ–×ˆqnŽÉòóÅøla½?Q/|´¦híI¸Œ:½Îêu\~z8}X´.ò™s$*ä�® Æohû6ì‡×>aYÃ�;åuN‡M3ÅsÜ ¶ãÌ{Ò?Z‰Ý|è½àãMžÁ/„ªh‹ç^‰¬îÉq�pøá0á}€Âö7ìáð$¨YÍŽ /¾™èu�Jšãwdóp\~Xßå®é_Ë„ȶ§ú)¾yZëüìÏš†�.Å©ãâNé¬Vçð™Þ]ë©mQ«©�ãúiÆéáÖʯ™çøÑ$!Öà"&6W´ß:„7â%"�O…¹¡c*UªßzuöŒ–;EÌšbç6£$o8Oí­çVl¤BJb“S&†9Т—{CÆîÏ?¸ u¸8 þ‰™@×úÜFŸË‹ÿµrû§MäkŸôȶîr8^ìôeWÂY:×tì ¹÷3±'n¥ÒÇ'úépÍþ?ætá¿$|œÈ*ñ4ËuSÔ0eú3l[Ö ׃·/ÿDd üËa]'ä¸Ð–ÿ¡Vl+*®õ»4jÞ¾(î‚—ðsúGLùéW@sÝÓþUƒ ìôk³üD}ÿÏ_é”,[¢gN-(»ü§ÌQ”/¢.µ áI#•GÍÍi#Ëø±ƒ¡ÇÌ"±;$,æ²7$ó$ô˜ÑÏsSÓ°°Ó™‘p™sÎ8\_&Õ<séòp‚�sûFxµ—@,OÚ}5QåÖa,ÍfEŒ:FYÏøÖS¢×ý\mä5£±á'–ÚèžöõD˜ÙÐ[bIȼKéKæ©™¶üyGgê¸öP¢C¤®óâ`½÷‹¦_-d¸wí÷sl뚃Kr²‡øÐ7ô;ÓålÓh¶ P¹k…9 aΫúÁ8€–(ˆö‚NJ)sqõÞ\9ÈŸv²Ê“ç#³_/|ÂOžQ¶9MgTà޼ŊÀhŸ-î@Ï[8³''$Áî q|Î{뜢r ’P®»5þƒuŘ�ë8P’ž£'-|)'9÷;¦Œ1ËêÎ Þ~ì5ý¾®µŽÖ”pê,ÌÑýk2�Ï5ökÕE òwÿÖk¼Aòs–éëÿ`„—ìñ�×NˆFGkœõ¦&ÉQZw̶\Y `Dp8ÈaiVvë’Ú@®g¤Ëýóvç%ߤN•m—êØäCëÌ�¯u#óñŸ„äù>+l½!/á?âôeêKŽgÏÊj’ ‹^w?°çç|Våí˜ÓCR²–ùË��ö›ªÓƒjƒƒÏo¬ ¢X8Y|¬ä´]®ø¦ß(ƒO®{HZ½šãä­êÚ pŸ4‰èšf¢'^{}h8dp6ÖH. âçä™xãKüÕD�xƒ7A/ž_uàÚýï~‰Áï­Ü²/þÖŠ†Õ’õ�¥h9áý`k¬_›Â°º�ÃÍLÔ´�]Ÿ{¬í^hÍ_ÃùãeÏß MŸ^DlQzŸØÎrœ¸É¯¶i´64T‡g¢¹Œ‹¸—89û^Ô¿®”ÇØ<ãÂüA$_à|Ð�ŠŠ“ŒŒb>Óà8^ŸKPE‚áο| bñpÃ{kçæÎ �×â2à=™øõ¶=, =§¶´Ë†iy¶ë{èÈÞgø‹]Y·Èqúu„K`×&¸|0pÎÞ^ÿôeî䣱xmP�GC¹pÍ&—uv[º¬‡ÙÏníå€û,ùÌ#JXs¦Ï¡¿¶”ºþÕÌ x<Ñæ¾ª“ZëÇ­#x÷|Äļ í·x©’Ù=ÉA {×û‹I»NW¤–§†@¥9µÉsχ·�Šg}w¸Ñ—YF±ørûίÍï¾Ês¡>¹çÆß�yÞ†´ï¶cøîŸu2ÿ½¥Ú݈ÛCÚZÎ6¡ÓÜô锟Bv×'Lê¡L÷ ßy;áêH^{YZg+3=rX®Dæ8�» Ž€ÜPÓ7æzÜ0fÙPkÒxßlû~x!¶îÖGgx²V6úœ Fùo<³H2šdo6®„írî•=þô“ç² |8 Šì¸‡õÜ:%Åumúf7§±Ïw[;‰Ï-—ƒ¾yŸ/r>á—p±¦b&z%ä3‹óP¬ó·ffI69Ožˆý 8Ÿº‹Q›¬œuum eÐzN÷¾åÚK€C¯°rKàÄڳݘ¾€V÷Á¦÷d¦Æ! «ˆN/ݸIt1çCœj‰nFXûÎòDìqî´ç~ úH/½ídÞÁ�EP†ýÎ*õÇí˱÷èfV)Ì ±W-÷4LÁ·V›Ñ ·3äKmX‚SŸûÞíD(æhÃßÕL-¬x‚ßÕµN ¹Ä¬Ï]šœù€!À+ ¬Ôg·-Ó9\0ÉÙ,©Ï™^ëð´ØSóËEå;P+�ñ»î\ÀºÄÙ“û"n8^îyÁFf>ÜzëbySQ¿¶Í|ûæìLQÏL¸‚ã…Ï)…KÝÕÌN8šçz瑘|Ÿ5,{°yîú¹@.(!53zIˆ*¿úØÀ¬ôê&/LæiÏc¿ŒÕÔðÚ2<™p¢ó¿þµ~C[0úaÛ/Ô}µÀ'Ô4Âg´®+ÕCôʽh›nw¼NÌò~3[-1]O Ÿ±„=Dµµ§KæLž ¨Š#»õØoLÖÕkF;çsª¹ˆÝ8 ãÑa¼ž™ì”GB/>ä®ç‹x{¿ËÚ>´»ž»$ÚÜ™}ò¥¿x /äŸR×8Œ¸H~ŒâY¸ß¿‚Ë|Þ øpßÁ€S\BýëÿÕ÷ž÷ûOm¾—_šÜ‚.æ\Y°¯Ü�WœÎ�gxæˆÓ¤¥g²ÔJ^§Ë¹7Mô¼Å" Ü^Ä��Ôê³MšÞ‹CãúækrV.½§ƒ½p�¶Hzj€CÛÉ¥’|u‡ÏYäQŒÑìQó—û…ËKVJ–ÞÒÞ{ž[s§‡›¦Ówm&ÇkðŠÄkL{›ÖNÍ"WÃF‰Žb´ÿ¼É=š\*š9¶rYbqåžÈqÃÚ\M,ñ¿ ïú'´39,_u±n„!ÇQ:->ßÙ3ë™Ë stµò\à$/ßys’*}úÊ}R–°ÀÜ?$H%_XJco9÷¾þÁa¼šÇÙ9`tölp­÷b>óòç�¼gM¼,ì�íèÅ5žØž5ÂÆWKá*õ°Ð‡Þÿ;šX¿,08�.šÄ™€mÓºmO8¿Øßüò:¿ìÄß6ävm_KµŸv„SÛÃÉ'ñSÛj fh¾ø°Zï<Œ\-8õ磃pô†[_쀞e…Ã7]ì‹?)™oã&lfMT:3hÝÃ=Âi36N´³‚EƒU,˜Ý]”o´ùœC¹/ðŒÓÉ…Å›Zöï"μ®~ú"ÍštXëŸÔe™¾5ì·FUó<û¬€—?­)³üI«²Î %k+s~âäÑ {Þ­cÞjï\ÃpñØ›:¨N»PG?Òë*௷ ºÇJLçvòäË)Šô ×xux)2Öîæ8—KW:K\ïoôÉó}òAi:ïÞÉÊ¢çö‘Áêwç¬üG{Ï»¯Ö_`8ÀþrOój™OÚ<«3Oà«Í–:‘‘«˜: sõ<Š!§Ï; Æu¯…²kMçºpbfq|Ìü�ŠÖטÌðÈy}�k æTR æ>˜iQp°$FN1$þö‹ïŸ‹r­ï¸w/Â÷’†aš‚£0½P¾Øç¼ïüÔ>ý)C‰ÓꙈcõý‹#ýœà¹-±)–<ÕrH¾éÉx—M™=*°£7š†ƒ6ؠħZxâN1ÏŸƒùÁÖa;³hŽ6NY“¢÷>.3œ¸õr�Ì_¸râj]Ójlž¥áˆ{‡‡¬,»(®Å™žS/q s,:(³RCÜœvå-g8S#LŸ™~yvbÿéß$$$)Zcؤô¾¥gp¸O]ëñ4Úg8V�ÊY%“1Ž2áé=¸ÏDzLÎ2×78¿sE¼ÓEN0©N ÿí*ÿ¸‡Rø®|1漈Ô{rŽ&ŠhMORxÞëŽ ÚL\1‡#½ÄT’–æ#ýèP‘‘Ü�+1¶× dܸ" u’Í\ƒ®„*̶]Ö°<Ëظ”8µðQo5?XsMÕ‹*rt€ðÕ=†#¸W’¡KfÞsÄÇc>ÚmXÚlúú|<·7L5ç,Oîôƒ¬hËî�œÇG¥ùF�{€æûîUì;Ëi£üQ2¤&¿~Û7Ç8ƒ\IQ(!Љ)À!á.ÿõÛÕ#“âàß×V€X队áÅgF�·@ÊÔF3²X{ëØÏÑçËqO-ÜýQ†iº_ð©$�ñ¤dx¾+|ÄãŸm þ”j’®ó÷žÙ.Q¶WÔæ‚=W®'×êÎVܶ/>£g9Ž»ÃCü`ðSÚsëÌdqWdø¬ÿ¥¾i¥»Ì+//ÍêŽÔyˆ§‰æyj›lhv†åo¬(=µÐ\…¼ãªãÞh$Ty^t6<Ä´ÞØW¿ƒÔ‚âÕW¾øs_‰óc2§¸óûüp{ ÎçíZÞÁc C‡Ûg0ö�lÑõaÙp5¡hÓðëpÖbËyãã…† £Ò}5ÿ´šP—`ge_ŽéÞÅn΋ ·0Îy1gIÄ[7¼¾žùüÑO?Ó­}½_>9þ3/ÜÍ›�=¾« Ûš†•FëŽø¯~uk§çÓ^.8凢µ.¥Y–¯\Íw�3`†H%lŸñi¡õÔÒs~ú1Hz™6ÛíÓ<»à{ü²ÎâlîãÑ¡XCµ¨ßšžïá˽ÃÇáÖ!„b23@á-DA�ñ§1ûæUÈN´V.åOèv|®i ·.§`§Fk¿ø$ ILçP‡Õœ3C\IðüÎá |×é‚‹†³±ì8Yòó:ïú¨ÎåÜ«bã7O±#%Çyææü°è88nW/n5Æ=Û5Žàyµ+o�P.nN«›ÞpôÓž…$×5ÑÑ\¹¼6s[;è‡ÍXKü€�%ˆÑJfÎçêpq`¬QvùÈÅ—™Ø8<”~ñƬÅ`¥÷ä{êþú�ƪì6 '½=¯¶�àõ½šÄâzzÂÙå{ÓZ4†æÏ’Ï=ìÊ|Îl.–¼¼È~ï­+8{¼Æqo�"Õ�Ïþi Ýš0pyîq8Iq.ú.k5Ãàù%qg¤D©>¿¾•ùÌuú•’IpÍ´tP��6ÜøIY± Ó8þÕ»÷ ½/ÒŒp­–8'ߣÉHV´Èr_á‚wZÙÉG[ö°p&'{ÏÅN§Òq IDATÜ©’û^òã SrsÆÿÆ2‡ñ ÏîûJq-÷ ´|‘?:“£ºÄ…³–ê=9ÎJ/ÔO¯áîDŒBJ¾çK�é‡cóáœE^ôE�-‡Œ)íýx[´Ýù‰Ï,êû|üWË©çrÖ±ûKE–çÇ®÷fƒãOÜ[¸�/žïJò§.ÃÎAfòààõe¹ÖÑÚO)g*ß³&RÌÉ)z8W‡Zï[!iÑ�gHWÒyÐû¡Ê~8©_¶|ÞÍ\[új²Hñ—l9÷�CË-ňõ¶üûøpʦžÅq1ÞXG²¾�“q—¹j‚ W¯öe¸{jH™xö;Û£ÔW»áð™³�ø8ô,?TþO8§òð§Â›Ð B©é|M]ÓMÆ›=mìç>—Ãùæyêë蜖>g èÕpí8ܳkXü�Ñ0ˉY� û‡{ózꜛ~i©zÖòoýG¯z¡¶_ži8Sw¹ñ¦qkk­W§1̬áÜ:óí½™føß2¬åì%8ùµÍ }ïîÕ=ÎöưÉao.<§~¹·²¾uGàjHq’üIZÇøˆ×ü_¾`Ð}kÊ'|䔞Ûa/NtŽN·wÎyïþúà׃”ŒœèHhg�2Wîkª'¬ëÎE¸ŽÜ3¾ùÙµ®þÞƒòù™\ÜŢ٩̓Dñº~ÒV „GgÛ{·Ä3£Kâ{£Yæ3¹Ô–žrdÆÇŠ÷ˆí.Ž‹«³œÍ©~m‡ÓIçÜ¥‹‰9ìží^ï9M™ä®‹ƒ¿ê·ãO~æÝpûǧÊçgÕc�댽gêáSßµˆk9Öšq î³2‚9©'Õ2ã¡N©A”ÿ<‚Å5u‰óÝëòÍM¾‚ ܧ‘²C£¬V ¸6âw²¼[q÷y—ÓœâÂOÎê�íçìðÐÃ)::í«sçˆg¿I^Æ›;m¾gÔ5‡廵n^49Ê!fþ:¯¼T]�„§“>‘?eØáÚ_Ç¿<›#Øä¿¹ÔǶŽ1ì[(¼åÂAm๪6gç‡�+sA_ÿÊ_kAÝ{m–äef·–¹Ú#ç¬Åg/�ÚëmÕ//5ù\EÏ©[&ûÆW퀼Ä`ö¸IàÌ,ºïÇøÌ(x§û8. øSËeWÚt_–<�šÀÓö0˜ãÌðpo&�föèÙ3/÷oų¯žãæB/–v.À¸Ø«7þx–#GÜ �›n²–-{Gd‚sXN{öðÑ?ßöä1Içáv(³µ–å6Åš�vç�r¦¡g^IÅi€ü”~þ ',ïç|òÎ=#¡9 wO,Yu�“|¸Ü‹Øû7¨xLJ/ý˜°d_œã¢\Z¦9äʯ¦¥ �qG4“'ׯNψ˜Þôf>sNŽ®YÂØÅÅ«÷KøÍÅîr³$Y:zYà 4É«Kf! Ï+šRÐ3#­õ‰íóY(’ש©4kÒÒwyñrMò?Xò óqéÍ:Æanùg æ�¤¾9ªå€.–“˺·€­‡ùèå: ±YdøÃïP­GîVž=Y4G½à:±‚S/Æb—© ò3;8O×Ë90—fÆŠüjxÉìÂV½ Z±õâ9¥§õçôþÁN¦˜ëÞÏÇ™ Ï[k3ðY5gû„­Ÿ_ã£7§8kópM ®™BÐo·ö“vãyv“§Æ­sȽç"â”Ü=×:Ô+Á[Ÿgò8�«înGóô3ó}GÝ0·¡G¿%„o˜-样ú0$øýèt½G»¸XwðÇÇá[ꆨŻÜú_ópüú6N¿rúWTɈ¨9r„ÂŒý.ÛioMŸp± D‹ìÃ0®ãH=ó¬™aHž�}þg÷ãGìñ¥Â½á g_nOÔA_�¾yã{z@ÎY«‰=ÕÜïÚü¤b˜z"[Ï>qe®²Dpþ�1å|æ4FŒ±ŸX°>µõ¬^w°©É(­Âùœ±Æµ~"yÙ(©æس:'b“}ç ÖÒ„iá¾�Ÿï»0Ög�R¢ý³d‚‹æ·fC¹˜dW±ÎºŒày+ÓB”ü·¶ùž>߸¹EäÊèî/ërùy·kD²uLË€Ôy9f²ri ;÷�¹Q·šm›¨8Ÿ=5åéeœ”ÆžufbW# o?`JÆùæQÛ5¢°ÄÙ�ù.pÑ*¦'øžÓSß­ç3N‹—˺äuÇs�ÕøÖ Dßçuºá<ýºàSø=¿yá”G)h±® ¬ú1˜Í¥»gk]ŽðÑòhZ,Œ¾¾ýáØ<ž‡'3äc»bÄ÷Ö„Þ5;L¸òO´yÝÒÃî3]™ÁÐeØë:©5½þŽÄ‚R.ÙÑ¿·‹D%ÁëÑ‘V>ËD8ôæGˆákuôº»÷½4pæ({üë’Ž11$w…,P†>x‡ñÁ™ßG]ØI1VÙþLpk�“×[Š'ˆx¨—g-µejì}ë…°Ñj 9r"'qç7ébà 6¡V²¼ö­³µØR~®²×/>ÂèbE»�Þßxƒù.8Èõ®3ñ½SÃòÉ+‘—lØŒïÌç£Êòu"5¹ÔÓŸˆ³Â5În¦ìÑÓçú©¿yŸ{–Î=„ëC¾"Oa#Ê9|øq0=“bºº™Š}¾FyãpìÔÇ/ORœÁÅ}±÷fÌ^_uüü¹#½OŠRóÖM“¾ªÞ8§NûШw|Ø_qsNsóÐ:½ßòésß}M ÇŽF/õÑ×8¦{Õ�1¹œƒ —u}wþðÐÃ?%sàYÑóî[§3ÖÇ ³A¿^ë}6·Å­Œ ±Óyk;”°¹(eýsï)æYMÊ6L”lNÃ^>ñöçç)pµÓGçdÏ%§÷ÖöwÁ5n—ç!Gg;Ÿq?óΨ)DU¶ì6lï”}QÏ[Øüaaî±JʈZË9ð.8ÊGËx ØÉWôG×zÚNœÿÈÄv±Ò¶±®b÷f'ãÝmÖîti°É"ñžlM$»9IhkØ;+-70¸£5X®ÍRÉ=TÔ*~'@âÍCJü®ëÈdé†v�¤ ­ë�šŒW|zN1ÇÉ h¡Ô{8Íÿô~4Ã_n4½)ƒâ¼-Ókî)îò_ž³•‰@>÷á‹)Žæ“w<9œy´¾Ë üƒ}ÍïÿúœùÑ«ßBqµÙxÓ+ôº¦c9ëÃ÷’9ªX`Ö·Ùùý|(Éùà Ôûø¹úázå–ŒôAJúiõƒ'âtï«[CœŠíÑäð’“÷øðY‹’ו5=6šk�8�Á»Ûzs&5é)4ÞÂiã>u‹ušEGË8\è½ ü ©kGb«1h?ë¦Ù½™°g&ÕÙ$êœY=½�sz"KäÂXƒÖh;èWóòÉsí�ÔÌÒÉM<Ÿ#Ã8ó;¤÷àÙ¼x�7¯—m~)î~¶µ„ÙÝÝ»Ï�.8½VÖZô’~|ÒÊ?÷F$þ… Tðí=›ÝK�jÊO�ržfZ+åÊÑç¢Ù„\Ÿ½ït M}ßuv\à”KÇÝ&JÍF[å÷ L`²{wS*xµ§Áù‹’.�òÞnˆ0 Æð�: NEŸšiÿ.F½%NÏAäYÎ<Ëï\{6‘.ùáäO?$XAŒ¥ÓæiæO¬õÃ=³[‡G›ê+‘øå½÷ÉÉD�§çÇ.O¾‹Ð·PcùB ½‹…kµÌ;]H°õ„¤µÓ~Vô`Ò¼Z„¹ü8Ò_Œ¶ç€Æ ÷åðÉØø¾³Z�ÎNçÚ�X®ÍEFu¤þêp,Ͼ#K~8ü& Wxt–/ØVrXœƒ™w—Ûc<Ý}÷e×yºg óø¢£x>õâWlð¼ y;O?êÁüoyEÿ4U)&~C™‡¢ÔòX2}‘]Wò¾Ï+f‚U"ig�úkcÊGîÕ‚SÜrÜ��pcª%ò|¬ÈVMâ{F6'ÏZ�ØÑÁõø‰‘÷hTØ”Þ�b€ÍÀt°þÕ¨iMÁdž`_|pÄR{=áçœùúì´)Ô^ÍÎTl`žžä¥!å{ÆÔ4µIê£Fô:Ǻxæš+QWs°àÏ�{�ÇÛºò&ù|"=‹bžŠ<éöF ¤$‡î›ˆ‘3š¸ü‡..^e>tñâË÷Aç~£‘ãÅ(ñËOOÑyãΓŽÕ;qr¹]Y²/Ö9óyô8£ög†@Cwîú„"¸ê9£Q¸é&gyŽÏ¦.çéc4èm‰ŽÔ6—-uÓ¼AlúH¡0.ïo뉛ïœü º©:ÍçBëwdL 9œ}“Ö`mb^ó³ëm¶ò ò¯ý‹‹®9%ã`ê<ƒ^Í·çùI·ð“BÜà–§}õPN ±ùöPn.ˆÝ›$ ®Ö%ìxÞÔãÝM'þÞXç>|ä°ìbçõüî:F<—:oÌwïÔ¹ÞaØßÍÖ ­õ®Z1>Ád^c`ëîúH˜ÿôFþæEc�ýž ‡á9¾xù í2¬U»ë)f€¼ÌŽ\Ï›$ÎG_F„cÉÿä*/<¦h,½g.õ··X¹…_?2Aypê=½›+õ׋!Øôûòš'\p²Ü_ Ä÷‚hîƒE´ÜwÏ.¥ótX«0-õÕB²ÔZ=k-×)PœëÁížpÞÚK�ms@‹£ä *ȱ¦]Nk8sªPô|ûj …¦—þÂ¥C!ëÛ8ü„G±âæÊsæft&¶ŒÁj²·�éiõ“áŠ&“ûŸ@{¼ã[�î}ü 8z€øªÿÕÇ,i%"ÔœýÍ)1cÈïòšmܹ9�Ô qûºøcÑ„¥ý’¨ND­wðþÂ¥¹Òëb®QÉîÍ0øX³Ã—À¸.® `(9ù9‰�Ÿ»v6Ös‹'5ÓsÐùø~ïOüé;øäú~�ãÀ±j·¾a2×Of8žÞ¬Ìk÷§œ¤W ´ö?¬1¸èà.û¹ê}º÷,èõZ——Ð"ÛѾ.’û{¥Æú T¹JY_‰'ëÜ+G£{ìhßZÉímGˆ ¼?uѽ5½Ãįù”ÿvv³¦ñÔ#IrÐûâWãîhó¼ÔbEÓË4¼yÞ6ÐþOŒ’xg.ŠÕ‡':U¯8òþTG ×舣 kfu*™g©5Tt\©Ëy£|ê¼~8Áô[òBóïØ æF5+'-mÜM19q¿È 2�Ò;—ô¼>‡I<9ûÍ=�8é]™]Œœ3cM�-ª’‰/ÿìÇMŸ,u{°åp䃲É}3œCæ8¾oš[µ™ú¬z”ÌÝ._5)Ô0×óŒPÞìÞsÝçò®Bའ~kÑ«D˳FÊ÷×í×_‰ë°Ø;ŸÍfu]ÖzSkñïl®®�¬rS”|NÖšÈx ?×Õ^Ì»ûº<àÒ{òpÐ�{êM=g¸í;G ¾Æˆ”ÉåÎź¢èðÕ¸[óäý̹ÿªFAåч�?�oFÙÔóD•ï õ-¹E­åˆïù· |nÜó�¹ÎÍz㘊ý³îj b¹pÈ—:}8Jg];³“ ~u½Çv>rxÇÑçÂÊj=rr;ÈŽÏ)˜p=kó ŽÏæàÑ ¹‘Oª Vd‰Ç_þéÍ­“œ�å?‘¡rü‡»‡u` ¾9|~�„Æ‹÷²O ¶£çdÅ%³Ì²ŽS,>8÷‰Í⇤yÙĦõ3˜uIû|`@ÇÖI1¯ʉyqœ¹ÇßšK Ïý'�AZõ�†9à'®5_tÚ?š9÷hª³¯æ)bvÇÐC�ÔtoÁXìðê�˜Ëårê5®Íú毠Õ'iúÛN´ÎPYâËñY‹eU[¹½Qo±b1­7påÿr ÐE:ù`<‘zœrd z.³kÚ—œglrøÇí¥Öû¤go .ZQl#¬}³g6'}ï_ë'e8ÎË‹�ÞxêÒ³—÷ëó=hÌ¿¹ÑÙ³À¬¶õÔ�üŒ$<æ}޶…57×qAI.1;oà˜$˽çãè¶Bää¾�ª²´d“{´ !n¶¬©O fF¢'QggÚn+3Vì$™ÅxPîK‡ó5®¾�3mïý‹�™�_„qo;ÊÝñäj�‚Žï[ɬÌ>µÌN’Þø7_êr¾ÉÇûE<8� YŸU4êOBÍk—àL2¦è 6]œYÌb+G ܵpp²øÑ¤èîœH{ÈÌRªýâ/}Ã=Vι'×+Ô‡Ÿ+d„Væ½Ë1ŸùÁ�{÷2É{ˆ„kÄ•ÐG pÙ÷oo•Zô�78¦‹øîéf6çõ礃 Wøa;«¤ñ¬�Eó¬Oɼé& |uȸëÄžz„?sÕw ¬?xà F'½¹§ë;´Es@ùð·î))m¼�î™ÅÞ7p¯Å0⌧õdž£¿ ¶÷@~×D;,2¢ÁÉò,‘ތȜZkz¦º—¡åu§hÚ»˜nT£ÎY…•âºå¿°ÌóÃ9yΈaÞs#”}·ö>r[épr˜‘3ð=|¨¬jÀ4åe\Ô³¶õ»ßÔÚ~üû÷-S“º¹O)SºØw~�‘k5™u†É)&È`Ð ~«<¡È=\È;ñrŸ4sÔšŽORKx&Ñ`´læwxš3•ŽŒÏÎ"›Ç,‡=å€ÈÏ2·þ=Àý]]; ò‚ï�PòŠ.¦$ åï-Š@ÿdK½?J\éëüzûáz5(~Æ1,4éçj>b7ç#¡¼–æzÂð9õ‡wMükW>{ÐQ.v‘<'1,µ›÷Æ8óÉg>ÓçOJ œÖåÿƒS‚}äðƒ]ËWfQ]vöD ÎÉ�Žcϯ :–sê«Nj¡É+{4üÁ“hò0L'úXÛWèÄIsß·yѶj±ñ§\üÉÄד6ÏÅͽg†`λ¹ÀVß|�þù­—¹óêýp©£¶Å&ìphÓËÏ®ÔãÛ¬ÜCón~4#wZ£ÖSo‰¹h"Ôµ–?,!¯öæ8Ž»Ï&¹·Åüá2!½é£í}6F|¯½ñP nó#[Z|.Oe�|Dq<ù«ÇD+|>ãßJ([ëËì3ÀMI"�ÏY¶ÎóÓ£ »€O¾ÍæFj °ØpspÌì{¹+~•Ž¬Ôæì)±�ÄXÀ¹*î €­¾äÈ›´�Àù u”©Ñ$œ:ÒG'*óJ|>ÛrÅ;¦ìW_9ölR¾| „#—‘{õÜøðŒ¬½¤åCIæ—=_ KâåÛÑ¢Äòû÷™8Ô:8Íx]~K—h³yó>gçm®�iç:NJDïŠlç~å̵ÒúâÔ`pºò±Ù¿Òqž-%¾óxLzp\$Õè ©Ä]‰Ëç}_î‚ìüÜ›¹L�çÓÚ>'=µ£æsM]\}Æ…·&êŽG‡ÍíÌJá£ï­¡œ`“l f/ÙS=ùq¸¿§&^fp–ëÅÖ+~¸Tà™ãMý.×2—ÆH˜ïuù»†ÿðcž!×—û~Ú|{ÜÊ@øÓKþÊ7jî�ûo²Á²\S¸ùíTÈx4ë<Çz1>a¨xÂ9�ÖEÞzôIí7Ëuê‡ îßõÖòÙ¸ àËû2S œwéxà„N÷£ÜU³-ŠËrùsz®ÕˆÞä½ ‹+ë7½Á¹çŸªÓ�‰•Ï<º xÜÚóJ ãw¿é±p‰ÔI˜úvö¾ÚÅ=Øõ ?]Øß•Hrq-8R÷‹­²Ò“rÜÞÖŸçܾ9»v}Ç&·¾éÏy&Ì\škŸÎäó®#Wç¿9 ØPsÖÎòŸúûdçå±ï+©J´y¶Ýa›\’â¿X“þ^¤Á)/~º¶Gbpøž�”0‡ÌŽ•–Ë=ÜB<œþSE¹\²švN�^ó€1Íb_áÛnk3ÜÔ"¾Áîˆ|yDbü¨—Ý㦅_š…¨Iîìi\‘ù§ÑšpŠŒûŠŸëâ„v6×1zxD8_®®Dl?‹p“¼â?{˜pîMý8÷ÁŒýàj®¹�§Þ]ä¬û›Ÿž@­3Wkm_‡c7cqó£•:ЊßçIÁÿh]më×ìÁ=ÿé¡FiðyÉf­öÑ£0ˆi5[yÎÔÅúؼõ ”ýö±²ð̿ڦþh[!À‚ èh IDAT/5gêCÒšó[± köýÎ`îe‚p°\Ÿ¾[CËÀ&†• ä¥mï’m,ÜMþ`ìKÌ=<ùàÖ—çðITc/¯12—ã‚„[ÛÛtÈŸµ¿.õæ��. ¾9PLëC#À+žTlîM5`Ép®á)D‡­ÌÐ1»ZÁyðŸÊ:»@x_¨;#¸_î‹lŒã‚ä­�Ïk‡í@óJb¸†><nôS@Ð'¸r!�‰£o¢|}Ñþ—éO�5,ªðiÖ®;¾z´ÝÞV[à�M»g Æ-€©|iαÍÝ�?Ï¿ÄéY¨i]§ÿÖ$ÿB–Õ2H;G®Ô;Óð:Vôiǹã¤NtóNÎX—p0G£óï|úÎéÅQóò‰¤.ÁPo¹ìߪ_®`Ái9æƒ.äE;–ço:jºH¼ó•Œ ,ë½Oæ‹Zip0ù†·£ÞV<¿ OÒEp‚g¹·—iK}ãªÇÙ'ühÌ‘C¸äxgàZº \W�6 ßs\—!’6Îσ †Ì=$íð*ÆÙ÷ª°Zò�åÜ‹ü;SþâñÑ?%TÃ颹÷-NköM˜б²ïþà[§æµT@ÍóÑçðøY‚aØQ<˜äèjX€Ó}b^‰åG v¤]Ýßgõ IãÊáy /<åL=ûOá�šK‰Ûµué™Í÷A»Ø}î�!tr}_Þ\b•xz«ÃÏ…{- åHrž™ÔôT�ø^¸W¢‰¿¾S7tcp\`礖µÃÿÔŒ›²ÉŹÇäù9·Õ˜žYi=¼˜,835—ø#ò軨.ÙNw)u9‚?½ñðþYŽË·Ý¼Ô�ÂnÌ—.PØ(DçvãŒð쮄÷~\g&PyYOîç\ì'þ�3ÌÄ‘qºi_ç¾ `Uh+Ùî&Gý:éVŸC›¡òS¯úçˆü>'¡ýýõÌÔd?ýÀ‘„s}mŸ×ˆ·ÿ£[þž}O8÷}ªbÝw~>‹ÝsÁ> ]üå˜ÜUÈŒÈ;eà)×E ·TöbnRƒ�¨8X«‘½ûãœÂÌœ1 hË}áŸîÁG'¦€�S×)T�6Ó•ìƒ]N…ÍÜî‚Ê÷êxëœóø»¯)碵xÛż7Ëx0^_‡E€?ˆ�°çA¾ëÐs‘Æõ'}û$Þq�Üpx”ë˜g •,ó¡'ì”þû§VE:ð-àœÎ�³Ù¹©dÁá¬yÆ7ÛЖX>ϳ٩QÖöCMҦμŠÑ"ósLŸô†�ûÌ“ìqGŽIL“™-±N:ÇiGvê‡έ{‚»Z\ïé[YÖ—à¸GµšD‡›ïµ­î$£7ºÌ*1 í'OÏ�ÞÛpQ�燂áÁëÞàžžäÇ&æ^èCÎs6)®Þr!Óz{XøO.8 ˜²\­¯W}ÖÞvfî’Õ5¸sàe’C$u÷ž7<[N°gN»Â�döžd¤�KǃÃÏû3G+kODÏZ͇ë�Y1s>ó‘ëÐ)žú)ά<¯rÆg÷#è‹ÿjÓ§Ó—gyð[ŸµÅ tšíÉñùþjIr�Ì<:êf»$�SGxõ~ï_Î.XÀ#ÌÙN¸s3*x÷†Ýôô•{žþáB£–.ž�÷9n.óä‚©åÌä‰guü\¸&øåp¿ðGØòÖ÷t/þõ#ð”6;ñ{n¥Ð·y»•+ìø8?n…¾”îÓçb5rz8ÌY<´é»Ïeb›{¸U4é2Kßããðå–sÁkÔxk»šSè|Ѹ78š|uZµ9£NôMϦæÚ<å’GÁĶ�œü˜ íSÚ<×—l§hšŸZË#z¦Ö ú×ë�pÆ7dè[CÁi�ÙÌ·aH_ýÁ´?ª›ìáv"É`ßÛ"â'ÄÛ±Ö·ÃNyÃÏQÃ6µÚ]øúŠCµBáHøå:>Â1<“ãG£–m�{¨�/´¥v@ûHíÔÐÉÏdÌÔ±íWÖæÒÕx{ ÃúÒ¾5Ü“ÊÿÇžˆŒ'ý¼¸oÙœVžŸjóÈ1"À=g¢ËrP—'Ç=˜ˆ€üpI±‰x-]v¼½s¯óÝ[D¡8s Ý–ÏrŽO~ëø4›>áZ¤_m!ÛwþAåô¸smMüëÓ­=u œ6ùW <µŽT‘`9n> ¦Ì|GþÃwFiîü-—dõj.%,÷Ë‹MÌùÌ5@jËPÖâ³§mö¸°Óî>¡ÕÛ|­a.ôÕ~5¾¼ÎWðÕÒÉQæM³íeñ4…Ž€<ß rM«—Ë÷"ZÑ‘úWgúªq´5§‚%þju@—[NJÀéåÖM€º’‘0p5Ídÿp?qb‹¼ PkëžæÑ.Žù·;Êàx³pÔn¥åtôðK™sHkž¶qn6Óã~MYDsØŒÉ!N�˧ԳàZÉW€Í+ŠvÒGîUhªØmŽØ;eƳëXmGsqgžXgÂü„罸í×^7«ûëºû1éZp k¥1h8ð⛟zÍÝ<0·6‡ÕŸ¶{“�.°öS¯oÇ�¤¯;�¤5^¶4l&0N—éæ`Ìö©ÐÖ"øÃãkœùÇ×|Ãaýî’¸†+½ êæÁ‹c7Á;¾½Mjp’ì�¾Ì`0ö_ÏÛëbäîLŽr¢ñ¯¥2G×RÌ8í©M&ò¹‰×³þtuN"û+Z .VK8WgcOhcŽÃ§7¡Í?u¼ø}8ÁÁì<ÑǾEˆ|ÆV¿!õ/®-ÎÌ 5dx&�*˜eO‘›9Éæ¨ÆDé/á5·@«³Ø˜¬]Æ·%X[Ÿ/ ‹çÞ�ˆ3ÄçϽLªã©Ï¿m"pçâ¬ê S4æWåh:­vkš «eÒŸKcã1œ9-‡#¶Ög6hÓËš�©tÎ-1NöµæöT#`ø�9ÎÖÑöŸʬ~J  >ËVA¼¶�r½`yN€­e6;ÿæ¿÷lo=÷ovH.¯OÓº]€£f ¤ùô·Ø|®ˆâpº^¨?×õc§HöدTñ}Ó!ýá۱ˆ×¯Íÿ†Ï$ÚMð) ËùÔèÁZ2ìSéÆ" óY5&(jmš†r ŸY sH‡÷Y›•û^pDÂÎý¼‹»ÈÊ3éfh¯ƒÂhw»#qNf@ ³è0 .‹¿|'¿}`³R= t½üEŒqíý<0æ[k£Ù}Íw“ ybÙwFÓk)dÊ·v|ÌΟ“á¾v~~§fÓ¬=’:k*àÁUv¾xÊç8;x¡.p¹9Æ#Uh›në$GK€×ÿrdJ2 ýé<ÎÔ/Éš4ixOãöýeo·ÙŽ$ëuÏœk™Ìdº’éý_òôŒüó+«úH™ @„‡‡G`e’L²öN”ûQíëUj˜8í€zÛÕ7^ÜÅ›–3w’ÊW÷…—{qxî•‚5Åw{uï—Ùž\Gg¼ºX=Ëåÿ�º;wûhVT€ËIÖˆC&óB‚Ùã=ûå<þá ü`¡ò¹›@€§ïOŒë“ƒyy�öØßí¼Ñ71uFh§ôï ¶Fsš{pÄä$dÊ“2×Ï©sÂܼ“° Å²]Z{LÚô Þr†+½4%˜âO}¥q¬Ä'cqÞƒ!¶c7ÉGKu9ÿ€ÓrCçÉܘ�ÅzÀ~:–ƒÙ¶å†™<ñ6°=öp“q:Ú‡M0Ë“&u¯/ñGïeµ.ñ-“•À¯ñí¡ZÇðæƒ p>¦óFx —�ǦØü%ƒ²¯‡&)虜æм‡{X ±fòêƒzƒ¹Á¬6N?fp³ÎÆ‹“C�pÓ‰q:—Pþb,M·÷XDÃ&§üb­0óøüuGs‘ïj¥_ð­fÈ4ËvþA‚XÎqQ!Ä.œõü¶“•éËMþÄ�÷j'LÕ"Lþy_s¡͆Íÿ]›€L˜H¯9—E%ÿû§…ù�ÇçÓ/’4V…YGµåbëIyÁ²\Lõ ÁŽÆÆp¡íÃrQ[~Iàb~ëõZ|®vÖz 1ù.WV\-àn½ŠÍgåÃûºg2]ÓáÙä ËEþy^xÐu±æn<ž7×´æìum~sXÁÓ°^¯§¦Óæj +�':�ÔŒw˜«ð¿Xf�‹Gž'~n+=ò.“Ú=_sñ1¨,qy3+÷óüw�/v©<ò¶`öý‹ÈÀ“XlKÌ­Õ¬rݳ�Ɔ{~P·'¥ïN#lq/Ês³fU1°�þ»!G¸äþ`ìWŸŸž¾\G6ÌÚ\Ý©oUº‡g¾··Ñ•×®ivYQX"jö/ÖíÎö:»N®–ãšRÙ__� ‚ÃGŽ2ʦ‘¦6]OÑ>qàr&29ˆ9}É*÷kÖßëÒ/ñxÐüÖãµ9#y ¬³”Á·_ŒQM*ß§¸ÐnüÅ™® w®l?±0[üóܱ(ñLœ–eÝÂÔ\ÌK<¼ À¶|عRõ-�‰Ô÷—5Õ$˜ãÈðÄ ÉÚKÃÄ#¹û<ÙÞ`ùï9E¡KFm�‹CVçÀ‹1 ØeŸÕõº%Ê5Ý…y²>x6NŽÍèŒ�áÈ~Z6c=ë—Sö�ÇjN_j'§>ÆïMÊýŒÙ�#M9µþò³7N:�2‰¡w__Ÿ³ W±Ò.·Æèê󣜠©'ØÄîj]ÓZ]?q%Æ|°mB¡§î5ÇiqêáŸÚªã†Úar� ©.’{m>ëâï´:–FÂÁl\*Ø>6]©á�kkÇ5°‚/)ZÆBÌ�Ü3M[[¦�æzL忦Sµ86�¦1Ýâ�]Ng墇ýâȨ¿�áÌò0[fë!I´íë’_GiÈRy´až3Ò¼ðœ¤Ȩùv°‘ä‡Û[ýÁÙùâøM:ðßf+d)½Oz¾yrÁ�›¨[ìße³V)[A¯6l-а®Z¡®gqlªïdz÷ÆEã§éü,*œ±Ä–Ë®æüOCסŸºšC ßXjr_å›l×÷ÈÚòÆ^ž}Qw ùTHX¸Êä¼çŸj8'Ž{ãýæä6òÇÏ7µp½ãÜ3Ž{{ÍÑÝóÇ~ž8ØF¼™8jÐmÓ—µ<Ò•ÎQÖç…d`Yßþô°Ž�þž¯%è’³¹ ØÝ“âæ�3ºPÁ7�# µM@×ÍYi°>œãµ~YÙ‡iýJ¶(±¦»3x>~óh»ó¨¦å-Eö=/¨Çm΀Ì-.´,Ô¿kö{$õý?ä:v?H4Ïr9¦Zi.š\w5Wª§iˆ«8<�ó’xö6:ìÔM®ô:v7QØõïí�×ø,ô©]6†µIÏj³ÃÎhpYò�ËþO�iÖ� '¿%ß>˜ñ¸2SÍ~ò+)Ñ\^ÙRw¿L|îÄ= ‰ÇYd÷Ý&™<ÖI nÆÍϵù¡ýÀÍe�ÄdWÛk¶�“Éš¥—AëS|Ïœåí�¦Ó)‘�/�àNjÀí죇kÕEŸX×É 8œ¬áß¶Ø^²3�Û=‚TÖÇc®;ú²§Fù!]*‘}ì,~ï÷htF7“Êî˜)‡È^‡Ç}z±!oµs.ÃÁ~ûJîž�¨±ƒÍxri .Ô°ê¬ ï= ñP”/°òz¥çPßlˆKò½šÈ5y¢çbržÛƒ„í¾VSuØ#†À½;âºãkøéÍ€äžQ8r&K¢ Í>}½çÀþö#Z! "ãYÞÎÏ©ÛÛ‹^ÝÖ¥ä9ƒhs²�²'ÎýÞ>¾éò©(!9ß>›½9®êÄ:ïÓs¤ó€–{fà5ftoWíÞ‡`<Ô´{`øóu@¾�õ÷< ~~,÷Mvïêƒ_•(á/þêB\è° ÜbÄ3œæM:®n™ÍçäñÜk©Èéì�&ªÿ ¶K)<ÖhX¯W¬?ý•?ÚWSâCÒõq]ž�Ÿ ´çâÌ‹�äÏ&ý¹çøöƒÚ�mOYçC$åŸ+)þÜ�Öšów5Ý|Îï&¯váˆÓãõ9|876õ§_źbòÅMºú=î@>~†Ï§‡ulÇîá¦É8×·x—Wé8„Ø/•Z évæð�±Z1D˜]TÁÿ¡–ä#¬ÒÃk ŸG8½ÅÄÇyc>täá3ÇÎ’z°;¹:—4ø#Žt,9±°'7Ã}ÔlNö[snÎq±rÙ?1ðŒ ?#pg¿+}A×ri‘5z›o>‡Ò�ÿø0>ä‰mßq�„‰gk›òx˜·:œ·:N Ù|âžxü/|½ÿÕ:Íå¬mëÛLÚ>‚É•.“ÚêÇÁ¼µ`{£‘xÇ#ûÚW2ïŒo">ä�2YBÎ{ŠAàâ͹Ÿ<÷la�mÚ¦áó*ß“ ڦÃ(OÀ³ÿKÜÉMNðORçÀŽ‘M1ì�ï%g=Œç:ïqý@_ããÿæñ–%$Úps¼·¢ýãéŒ�¥kEû�#µT³=ºø†3>OXçvmHüé[ˆ!,"½Ù®FçX,üg´O¼ðBñxœ‹˜|¦ˆOyZ \ã6¯HæÚ º{<ã@Êfþòº—Â|ô{/è#†Ü¹'m0zºsÎsk‚úx5Ÿbá*§ 7ÿlÒ„P‘)ç$‰mÉœMÖÁ†Ïv_býÔ)8<¯vrL÷Z�Ž`=£èÌEJÖØ“Þëå±Ý®8W£@‘æ _üËãúfãµ.|ºw1� @¼[ä8‰ÓÊ£ík�Là˜þèV‹ô ¿K=ñ‚øj³©Ä2…&çÊÖ5Ž7ÁGç=cØí+ÕÃKx1Âõ:Ùóx‡÷žCŽý……µÔup‡ýÁ3Í—ÃV§ž� k0Öæ™à`_í�fJ@V®âžC�šnŽÝÙ</ÑN:ÒÄž‰rŒ<áÇÇü9C*��çÜä%¯#¶¦pŽ'g€VëµôÈ/ºÂ¯oÄe n÷OòÙ±$N X6&t ·ÚŸZ�dµ9Pa÷ü Yÿ£¡>¸õÔzâÿ¼Aä’6ÃÉ„qþè¾hXF4�׃Ռ=|NGÖ쓆½Çö2°~sjl¯fxœ>Íg6yû¡ïZŠÎ+è~±`q–J«è'¹�Ÿ”�—­ú—¼¸Xç­Ù òŽíssij³wðZ{q‚ůØÑ=«ôeZ€½çÕ"§ñÌæ þÄ€¯ðÍf�mq`·ª�˜¢Žv¥eÊÊ·µ‡ ÜøW{âÐÈ=´xójc†@yóØÄ%”Nã­÷5B²ñÚ?<`ŠÓ”ÿßH –‘­¹öœ¦âÛP©9pöªª6›KΘ›·ÆœS¸�¦iƒ¸pYaÃ9‹¦•1êm—’"1¸®Ž~%ðÚ ì©÷¼ò�z ñþáûIqÅ£yºÉçš´X_²ïÏÓ¤Xû!))­‡¹ãtp}Â.ü‰5®¹&H6×�ϤϬ%g“š°ûßpCn(~!{^°ëÓuó‡5öŒ^]ÂûÞ°¿äöd]ÐKR®ÎøÝgDiŒ§[¼VÜ;Ü+óÝŸõ ‘#5¬E‘F�Õ³À7kù‰�ÆØBÐS#É£¥ÖO®Æ?ÞÙ™Sýµ°?úÅô«ËRüúnvÑ_�k^ÎÈMK"^Ί˜Pœ7!·.ù§1µÛŠÛ±æeém^@DW…yq%˜ÓÂkëÚ ç²l‰N-ãq¿ªo:žÐŠZL_£Fø~�ûçÉãú"ОþZWçC Îc[}›ñ¯~Å{0ŸY¼ç_bñ5=˜hÒ–X‹]Üø�ã›_[¾×8}¯ÝaÎY´O¶+ÇyÅß|¾¿N¾ä‚ïÜѯ>b5&s<ðÂ÷) í”$À�î›$\GäÏ£a± g3ÅyÖ¥Éö݇‚†bìlìhZ¾©ò™ä�ë‰;ùÆ�†u1ƒÕƒ96†C6ç•)sÞÄçoh›»™õÑts ˜Aî³ìÛyÌ«Y¶ƒ.ýc±ös +,±ãDÓñçÆÛ~}Ø~|ë‘íèЃ›É=ó¾oàŠ:>�­ÃK­Ÿ¼æ3Yðä5L–ì¬òJ�Ÿ\æõ6ùõæq~;’ÞroôàBf‡c"­9›ÛÈ­¥5ÞŸë¾é™¾�%ÙOWâVµT³¤î›×o¢*§y Z0½ µÚvg ©óñÂè,2úL–õÔÔh Øý8ipݱXúÆ&�-6[ž6|ŠM–oÝ·ö^ML§o-qÎ<¦×EãÔ,‚}Äáë©X¢¬‹†²!—æ¥t?ÿu¤žäÀdš\¯¹Œ±8&õnzOR÷EÎáöj€…ºŒ&œm2a7ŸS±æGoR£×Ä2¾srˆ¡÷°AuÞkùøêô´Ë‘>ƒæ†Ûâ5´Õ‡†ho.Wôî]Ÿˆ­ï!cÿö…çx¢œÊ‰ÜùtÀ{pÎ^óã/Å�±WìÚGÞ÷¿hZüãsâiN¬õ='»ˆ6ÃágŸjxÝÐεj�Uëô™„Rˆl-�´±Ž"ÀÃøsϯú>©×ýbžÐžzÈ»l-KsÝ‚¡qhähCnçHA¡c«‰LÜz0Íéá¸MZ^l�`«KyÃ#›“ÆÍswÆŠk±WC0NÃÒy™óŠÄêŽ Ü%<î‰AÑJlüõèúk·b–»ßt“ƒÖ‹¬³_ ³™ŸZÙ3�a.#ræ‘G²ËŽqy²ÿ›mÜøÐ5ÍÃÆž¼¬ÃJÔ�¤{޵íÚé »œƒVÈɳëG«cݹÉIRær²ë:=6°yní—‰ÇJ~FøÎÖ6#ìcÆut�÷Ù/7çµøÄ6£6ÑmõM†¹¹(VŸ<ö×Ôäf¤V¾¦±þÞg¹ß¹cæMà°üUnúÛðÒä�Ç�Ž«tÕ‹x-ÖÙg ßnDËü×ñïÕ¨‚“k8Í,SÞ-êå°/ ×,úÆÃƒYk.9’Ä];kcÏ®û/°¯�á�»:�ð^�–éİÁÚ 1ü%Ÿ®±kòPcî—èNjNï˜Ñû¾Æ¦/Ñ’>4wõœ^hŸRHø ÙÛ<ÚØ Ê܆ërÂöÜà“ƒuëåùêï/¨‹•ÎaZ ` IDAT~c½ÇÛ^LËþ°¿‡üæ¨vÓçͦ|šV×Ñ#Ø‘g‰O�µ»¶BX{¿Ùq Öd¿ò%g°è$Ïb×kì†ZÚžÚXH¸Ü7è:Ʊ½gÒCþ:§µµn®æÙV¼µtÍ´xKyxÏ÷Õ'®hõÊ�èØ:‘Ôž×bÞÙ\K»'Y:kO�VÕXÆÿT 8̹³�(j�}›¬qf,N ªÛv,“½Ô Ÿ�Óɦ!e,/˜rz.œ™cí�\ ÿò2¿1S0}Ì^��Ì�ÑPÖÚKú˜^Kuž€êX]ÚvyjÄsµ¬øãžèç{CuY?üž—È÷þ|§¾ñžd�nñCÓýÙë¼üìÿ¿ýÿ׳áÆ7ÀWvÄcÉ ª;z#È]-nØï^üõŸŒçp�AìÉ8^�x�w=?ü­êšÎêë£ø™¶|ñ˜\{ƒå¿þë_‡í¯ à¤a8´†Ù¾Îàþz¥´ ùÍu8b§þè”jpë‹ÿ£˜yÂ�šÐ2Ù4^÷\qV¹ƒY³¯¡6L#õ,àâó÷óÑ7~ÿù?Œ]/}o-Ö´"Ôç4 ÓB�Ãφ¬ÕO0š4ÖŸìzmüo^ï�’^zÿüy4”öá×p t4ï|oÝ䟖DÒñ2ž8“†›ýå÷þÉ_t’CW÷Ýó.ûŒi 6Z¼&HñÓvðZ˜NóÁá|°d3nÜŒáÿã?þ3{=wÞš :9�SÛcìÉm𴼯E–ò‰¯�Jøò•æÖ$ƒsDíÿÅy7æÕ:‹ÿ�ƒM®÷˜°»§2®?¶Éîü%KýÅׯ4<ÈüŒÿÞ”¾1wäXÚÞ`À§Zæ�ÿp`ßÙ½š*:Z߬èF¶ŒÃ5ƒæcÐ?ŒÊö/�÷j¿Ð��-ìòÀ$DËœU}Þ�O ÷îµÿ%æÔ-Qî‘røŸC‡¬½i=>e©b­L±ãH¸?Í:ÚÆ¯ÈÓ“‡<©7üþ«+áǪŒ:×õÃx8É7=^ad8sVÊãÿ>™î�3›¯ ’¶À+42Ї7²e¨Ï ƒôYÏO_®9µ‡pÜ-cTÛÀ†N/µÈÔ×;ì¯Þé”ÝÃâ·I^bó¼É}ukú[­Ä&§UMHÛqïÁjÛY—ôrÌW)¯æïVc_+ÿë_ÿ3íÁ«ÆyV¯%>Å’ïWö0Ÿ˜Ëx¢å·¾â"=¶C*ºõm§ž7ú^h‡×Rsþâ6†@”ÎéhSèR¸ŠËt9ٷ‡âì. «Æ÷û áþë_÷{6ç„4ŸÑv7ç{Q>Å5guZ™qæ´)q½ŠljÎyñD®žýrÍØzs ^€u”@éWOæK¼¼Ñ¤¯iÄb[Ør"Šñ©S{çýç?þó?ÿSÏ}ýÖsœêàMöÆhoË4m/7#z²öÕñvè®xµQ ½ÎÎíÏh®ú¹£×óå�Há{ÏМ'ÔI ký鑺Œä]ŸþºözÖÏ…"ü„%–+¦õŸ× Öï/î~BãØˆ´ó|k¹ qŒ!~~0Ä¿{a÷Ê`ì5}6ð>o^Ïù>#õæ„A,kÐì.&6®³_‹V®‡Y~þ‰&K¾gQ/GkÆG‹}>°eã=ÛýÕ(=LçËßsçy¥ËædÇž×¥:þôÏñ%xpÕâ3WæÔ}£@�ÏAfÊŽºœÌÕÙ¯§¸—ssm¹‡_ÝD_ž=†#Œu†fëT„ŸßDj�cUá·©B—ߘp œ Ìž‹YÚirá Î9'££ËÍ_¾÷å{™~Ý™¦¦ªjЦ´y¼�±1Nn­ßžØé¶´^üàqL<|ttîþ¥¿ôï}ù›þØJòËK|Ô�ç/ø ënÝØvï°~ñÑ’ÈÕzüÄÃMiœŸB±Éñ¦ W‚À½÷Ú…:ØÄ±¥’Çÿo–Ñ“¤ãƦf^�ÚâÛ/æ_Ýӻإ�â‘3sçu·JçØ:´9ùÝä¾Df_‡ØùO :5¥/}ìýòwî+ß_q®–iÂzjþ3Ñe¤¶ÇỎ{9nÄYýóÿ?ÿoäúÓ�¦K9«Ø ¥}¾!Ù¿~Ö‹9– A MGŒ°ã˜ßZb?˜W×…s–8sM ©µ®Œá¯‚*'?äLÇ´^l²è=·SÓ�™ DÎãÚÐ�¼ÙÉžž†5þ<ñŒ;òÌæ¸ •I€ÕöåŒkq¢T;]ä8}øíK„%ë©©": ²ÐsbÖ;ç8:Ÿ”ËÑ„¬Y ²}5A¼5\í”˸ìÁÁé/ÈÂzó“Í·Ol‡[®Ø°röŒ\½ÒÒïÎÛŠýtãÉRC„ïý 6=Š{y³îO–¿×Óc49ýwÑ_í냬]6SLô¬Y–÷h &á¹ÿòßšÓ‹8£µ²ä¯Íöü®Hç]y`Ž]«áOoŽœ�ðõò»Nž²w¸çÇPݪÃ/â§Ú¼óè¬ø‡ÆlÀÕhþÿjÿÅÑ?ÆÍ}ØNÏ”ðúñdDo~Hƒá÷‹ËÉ…`mØC4®ã7Ý7~½h*OÖZ’ô 18w23þàæ^·�ÞFsød¬¦Õû'—�î�òq>–çj«–Џzv¶¦‚åéÃ�Ïüh¸w,†Él‹p¯Ö„}ýࢽ²Ëc{œºöl¬ 8}½ÜÑà ã#ÎÉÎIÚs*³ì’Ù�?¼à–ƒ5Ã{fï®Öùj¶.ôé3‰ç£·ù»s {ê~¼äß±³ýίfÖ¿\ìùË�ý…ÐZ•.$ÊëÓŸØZÍX–âœÇ«áé–q'¾QÓxë?t,†Å1¼mÒh^izí¬¿Z¾”Ó²ø/òßïÆ¿\ gÛü��ñÆüÿÊ{zÿžV²ü5§ð ý=›f^Ó—ïÅsÔ~cüçÌ_L²¤Æ­™_¾íwgáPòð_ßíÉxçÛžùo6ÛÅ›»àÅüÙRû�kÈ×Àiß=ý›Ã1‘¹õ;Fë}ž6æáÁŒk3þ;~òËŽqc½³íoÃ/†y¸Ì|¯!ÎÞ/oJáYð÷1n×ú@ÆzW§ÓíøëDÞqùc€É/"äúéàßüÔrpòGAçÅ×Nü^3§û�ñÃ?ÛËÖ4M—>�û�™m¯§Óûr6,±ºòŒ|qRqx½£ Is~lF­µO$þú†u_žxÛÌ—`ûÓ@þTvÆ$¬ÆƒýàŒŽN‚¦�ÊÖÃBÎä:Ö‰põõÞ(³üÄŒo‰Ò\ÝMkr&‰U„œ^?yúÅ}X‰I?® VËÕ;ÉD\¬WçòñËÊþŸÿüO7=ÿžzÐ4ˆÒ�ha×hìxò7‹)t!›q³þŒÇ¹~ãßš¦õ7Soðë·Þ¯†Ð^PnLbo“àù¾üÉzƒEš®¾ïòÅ‚ k½Iœ¢x7úá i⬕%1½ô—qÚÕ�}B¼ÖN`S¾9Ø|Ìï°Fœ�ï̽ûoþÊáûæçÞ`¼˜h (¾WÓÍýÄ¿1¾ÿÔÕ›‡{*O°û—¿Z£÷{WÿbîSî7_åBóýí“y—Ço:æ”’O«tPš¾4WŠúîÐë‹g~Cb�û+‡o¼ëm}©Ah§»=Ÿyj>/8ŽECú †õí|&”ÆÙÁß‘ßÔòÃHeáZ¯—÷ö/þé÷(C_XïÂð÷«s<Ä2*Ûœœ·ž‰²ñÜÁÏcõ„ÿ­Ùñ(‰ Åe}57 Õï«Æõgÿ·«sñW"¸µÆvoø½QÑÿ�üOØ�ãíÿ1>‹?ýº¯YÜ–¿Ô°¸h a~S›õü!ˆžõ,ˆ\‰Çî„+Aó°›ß˜?ÖÐC¡*†y5�)µ–óö_Œœ˜Ÿ3'Xƒ{õ;Ø§Ž¯ýßïÐpy~â_±£��¿¼!5öÿ6Ö;fðJžïå˜-x<ÜWAØG§ºãÞµcýzNßôÜá^\Œt dÏóܳ²¬mÂMÃ/§ïb_Ç»N‰±”Òõ¾v¼íkòÐKõ…¿ Ð@æ¤ØÀ^øÝcÓÀ|~ØÞ®FcùËJ“1§øñ|x›Ï¼‚Ò£‰±Þ¤üùki!À­‡ÓôËïxÑX�5&ó¸ B‹p{åøhzk˜æÆ!Eþ !ÿe]ê½÷µ‰Ó‡ÖHèt³öÑk41^ül¶·ó÷=û“ËuË Ž{r1íg$Ÿ³Þ= ÖùÀ@Þ^�û�½�ß‹ó>1Ñþ<ÅI…Ö¯õΛ×Jì|ÏÁçñô|¾ŽVÓ´i»ûã�Y°Qs²ñ÷yZad8'yôð÷/Ò`�ÚGâ½7oyˆ1A–O;bÿ¹®Æ� ’” Ÿ¿¿.·cDˆRJ£IÏ×ïå¼Á¾<ÅÂÅ ÝáÀù$ÓîÖ:xæÐ$îWûé™qß¾ããu$ÿæ¿ôòzöMÄï¨�þ]ÿ¦ÏÊžïkæS׃qªí7cìúó¯tdãþyï) þƒ—‡¾�ÁõôîÞÞ£Âèßr¦³7Ï{>Æ™YpÎ�Xõ]þ>£¾ßiçûÆÿbî>Z_�ëñÅü¹º˜[ëPÿÜ«š÷¬F•¾\½V mÎS»H‚ñdó÷;ݹšØ~3ºÇw(l{cù^ˆñßú~h·5qÁ¤vÿLye\²g…N?‡d{×�|ƒÙ¡’Wz–ïÁæ±C—Äå½!ñûE›šø>'ÿ"Húl"§Íÿà… æ¦…û›&y°ëß  jÏY†Ì`X £%ïaÐ ‹3”ËÊ |æW\n¦”n*_š“õžÑ-ÞÅÎ4öÝ”›ó F´˜&?û¦–ìsßBÒ¢™=¤}üúço¯‹óñ'̉•ÜêÅäî°×¦�r½çEÏ “$óx*à?þ‡~¨ÝWf·nØÌÀó¯�=/QÙ]ìOŽSçGÓj%F¦ü“YÜ´|£}ð¶å83Æ/âÂÑ?ŸyË›øÕÌÞçÆÌ¦ƒÜpͺ£ž¦Íø}®ÂûEÕ÷œö³.9‡êÎ^uh�Vž(èpF&Û9;j²éèÌazãx÷íხ1ÉŒÖýÖDŽÃ'}ÿõ?Ïs�xüðÀÓrÕâû·oZ›O|Èâ 4ö&ú¡3ÃK:ÏΫ•>ƒËy�ç ÷>øêc�/XÙãvüú ¹Ÿ3ÌÜ0‰¿$÷y.sŠ+§Ó³qÜý!�~1Ö?ç±%çÔ{ÔµÞ¢“=÷é­�^¤¯ùaL>}rê2÷§èôw½†k|¨Þ°Ý gyj†¯Ï­ƒ˜ýˆÑB:søüšŒ¸æÁ¶ûk!×›{xç·>8ôGWÎkXza\ö°ÖÖ32$µÂË8ÿüoÝ”ôÖÏ ùâÖ¤…9b0çœ�×�•…kâÒÛÎPLþÀBÈ9 d\õ”�^fÙ3k�¹_I ~ØàÊó‡cçͺ|1kKðÎD+—¼\ÀãÎr_˜á!ŽO;ü†Ðò˜„ pŒaá¨>™9oskC½! †x¿×cÞ:}†KµÐgÎ=™ï ¨Áo´ oiË«Y{¾Xü׿ò¼‚會×ÈÆìàS¦_ dG›ªq­n¡IžÊÝ�û€)JÂ�ºÂ_yå^ýë?þÅ÷@” 3O±ÿ­zJÎVƒÞ’çŽs_Õä:ÀÀéºòf´_Ðe<¯Û«cºV½i¹�2_Î{n„[ǃc©XjðYÁ# =õ'êÓÇ^'ìçboZ¡ÕVͼ¶Äwz²{Mv»pkØßïmÇðì´63=ñ³[­…÷Ûì[ŸV‚éî ñüó?d�¿wR^¼ü²ÕR‹µâï—ÒùX›½µîðå�ƒ™šè#÷e†KaÙðí7ð¬ÃÄŠÁ«×KsK_"(ÔÛô‰ׯQð¯Ÿf ¥a?4æã|93¾§ôÖKâPe´ù©�ó&}Î:<éI¢Ž¨Þ§¾Ï þp*&Á�øNË{ä®bmãæµ�µã”{ÏŽ/{v®å8 …:ý�ö~nð\�ú4·,êƒM¾7H™¤Žmþ’v¢q¾²›\éU¬¿W1“ºXêüý|›}^ÏÊ|��í©?¯KçuÓd”’ZïÏÍK�ªáþj9Œ�ø¥%#UƒÇ>¯¯Ê¯Áé÷Â{o`e€‡‡×aÆ áM½D+‚~pŸóá¼÷^ §tÈÇp ^©þsI_K{ióªHhzxÌ%+›’8<6àC—b,‘D‰Ý׊‡J>j–Û¢šæ÷Œìºø�5°§>K ¿0ï÷GËš™ü¬À«Ëâr=]ó%бSdM$Ÿ¯¹º·` “=]ÿSÎ×L(Ñéû_sÄŽSÔ3km·/<|"1еÉeA¼~Ön“¢]_Cठ“wDˆÁùzj“8ø~iÊ�õ×quÌí{I6æÝ_°sÿ~ÜÕa,<ì;ö\„«k(Æ(ß@¬¸?rîþ^œÜ.[k¸áÓ×}aŨ‡[F Hq|ƒ ò rQ´?B´ !<¿ØÓÂ� ¶6BSL ˆ[Wc†…Ú(àg'»ÿiæü�K.´ÁøŽ»?!rï…åE²v7§~ðÑ›¿ ,™íIp€ªxqš­dvbXÿìÍ sþò»/­Ù=[<6èü�^rûä°5®«˜½BIyžðå4¾b>"~û}ô�/wÒ’Î=–'^—Q-˜dGy#»7»\§nAÛ'ÅÎãÍñ{oåŒõÅB<{�mýößjDJÎ#Þô"èƒ�QÉÝÛsV—48Æ›ÂBXѽm;ý>}(È^�émæh}o�hÿ£H+7ºYVjî{Œ% îíG_ˆÊñr[|eÃçxÓE‡}SÞjñ­Ç™!<6îÞüO±ä*UBœgµjÃÞ˜æ8çSŒý¬•k yÓʶÚfv«8óÃ¥©ô`Ø5Q¸l�NÌÓcfûéYbMd²ìÝ�úüEŒu÷ž¸4¯#X‹Ì9 ¼Îk32¹©�� Ÿ©6ÌM´ú카εXh.Ó±j¡€Æ0¹.›Z»Öyí.脆ms·ÇÏ‚7D8ß×ËÜ›1Î Qˆ�žÀ}¾ñ|6Û ñ4,Vû? eÃ\¬çrïþH‰Ï^[í‘åzÎûAVcl\ó¼9;ˆ_ú`|½XméÑêu+W|¯.m‚(±Ÿ�›ësœëÀÖsv8Â%·ÃÙËwÖí‰5$£¯¹O!I’{Ææ=±�†h³¹™¿\G“ÅÀ€&¾yì™Øb+ŽîÖ£ìo¿øàŽ¥-ˆžÔºä±�Soü§gÖ¦ÅÞgyÝ ®=KR!ݽa÷íǓƥFËžgÁÝZgo-†5:Ý™³30דïå0¯H,Ùe\ñÄ�Ü='ržñѼ±ÅÆ[Sr†ô¾x£>œ©çå<‘Š ¿®¾1Àæ -ö®{:Z¿m#Pž[í˜Â ä•á�¸J÷u ¸šSҷϘn.ØÑ _4„׆ËmÀÉû¶$*Ül!ci-†­áöækòÉ®ÞÏãìÒ×$åê:qˆÛ¾ƒæp”k˜ÃÜ<³ÃcNø–�Þ,—f¾¦Îuu¡qÕ1Þþ_€+ø%F€ Ž$¼Nˆø¤Ð¾Tü“o2È8.'°˜¶A9ê®Hrú›#ÂhØ#–h`�fùÑscšôpX—Ë9´nzÙq%—9?šÎư†KAþ«7â´G|~”è8ž±Þ™«±Ö'Ì �Ê&Ï› OΣQèÙ@‡õÍ,ˆS‹ÖÄ�3\C—Ýao¶NÌ�³&Þõ‰ë¨2ϸ.¶YT�î#è�¯ìã™N3´Æ±¥–ÜÔ‰›�?m g<ÔEtrÙ¦í49®@¸Í_ÒDèz“ þÉ Oê·ŒöÑF슻µÇ_4YýÞrinfê` ÑØÒƒø_½‰Ò<4Ìp•ÿbñ³æa{y¨5y㻘PÝ~Œ¬9.xwó•tƯ?Ìæ’÷ø â²ì…0æ9°¿½Jíä“  §¸Ýžâí|.n�NéŸh\t<±ÖW/»ì8Ø2\ç_y¦³¯¼V..ÿòCøÐ…Lfi#RŽSß¼Á½þÕX¾‡á$^h¬«C»ÔF}OrÐg›3€ÁûF„;c‡œìøÄËÚ(ûwÌÀÑ{ï… (Ïé18ôËî Íicê×.c€eØ^^™|ƒz¾} R{÷ËB„8V£]r¨ËR¿bˆÛ§ï5£Àç*XŽå1ð^—ûœ¿uÅ÷¾¦&ˆÜ wLOzï÷[Ò%Ç¡5Ó_ÇÈpîu$k_IFxã]·ÿÊ Ã ;:)}ŒÂ–cÐÍfù4<ýM¡©7oð¨Ván¿‰$�¬éÆúezŒµ“TÛ`°g\­³P3œ`/.Þ»Ü/–ýàã'þÍýÆZ€ŽåßþÎßÀŒÆÈ�¶>¿µ�%}ÌŽjÙK<ìßóoù�ò)xqØV[ønO`”í¦1þ“Û¡\Æ�ϰ`ÏõúC(f݇æ?±ÃÈ*’ñ\º­öÚ'rƒ–³ì£Z~ïߦŒÛÀÑÊ÷7¿) ÷ç~Q�é%g}zB€ˆxÜ#Y?¯˜í yîë_øÇ�~{àpÇfEz³½ÌrE üãÃFM84< úJüw÷ò‹ÿæÏÏ.ŸF�G§#‘ÓúÝŸ €l*ñÖ÷ôM`†_`z£à0×íC�ëEêÚ=ør]-ä¹ÒËÜæµýp(vo o[ÎÄžš¤G{ìŸÞ×�ZÇ”Xòg¸"ŸÞa˜ï ÷öà m¬Í)ì�×j”øn<¶%>l·flª é ¨žIxr�lg}å+7h ¦z.Êh�ù¹ ëâ˘ÿ]¿{Àšdž…?ay>c›·‡µiúô�„NëÓxØ÷±55ñq˜ÄNXB-Ä|‡J=œ_‹Í—«6èW×Ë;M˜KHôZ!ͨLôe†š]ÇúÍkßÖë�óPЉó­%âz5$þÅÛÓ8ÖȰ”7˜å€Õ"�†ß}€©Â!úàõ#‰øÃ–☠aÚú­9úä_ßÕ^¬Ô..Koðlã°¹µ™B†éÉ>�\‰Y\H—,>ïí^¡E‹õسpþƒ8ìÈñZxMV›<ŸËúcg09(á#–‡F:Œ­¾ÕPޤLÁ&<O>k/Õ�8gR ˜ÕJÞñîW,ÓæxëbÅb3ëncÔu~%sZ�|3˜ãa‡GˆÄy°W¸ñ~r¾Ì�…ãg<ˆèlŽk¿Íq}ïŠ&áåsa(Ò€G#}ðÒvß ÚÚ»F0 _J×sjk®öÑXˆ×£øÁ,>Ù⟎٘sð}bkšgv¿©éªoWXE„&MMØë»ß4Å6�yó@ 8÷—ˆíÖ;¨‘wµ!š-Iïm9œ’b rõÓOzAøX»Ëìyx$µæ·Ò¢]lN£ÛBˆÃ­ß¼ÓÿÁ·óØÁRÎÇÖã’KjmN*8šs®P´.;ˆŸüÖÈl¼�â‰/»^!o>£—¬ØÊòÇ ùñ=š¦-Ó9¬ñOT$ƒ®â`Ç'c±Ë�͵±èJ¿ˆ~>ñÜ) IDATfSUGzr½/žµ¹©ƒ†t|zvtÝ\‰,'ŸÔŽCTp¼œ˜Á¡;¿Dh`Í‹gå8ásÁq˜‡¸á¡˜íjyü¶ëÍãØÔ'6�õ�urÅñ[Ãá¨Á›mANŒŒ]º/F‘¦‰¼ÒÚ[õù[u»\ó(òèìzœ§'¡N¿þŒbð€/g)Œ×%ùf4Ʋp¸|ä0�!ýç6™ÜA‰(ÖDXæ�×<²òM$–Ûíøô_íäŸÍÄ Qä>¢N§R\߈óžKv‡+HrÌ�}‰Rœ–ãÇf<3~Óæ9ƒÏ¯},4r÷éú¤·­†ÔÆï…×\f¬n�òµ%óíË%¿¶Ä»—åó½|þyhó1mƒ¦ôáö`µz÷ó™Ì±®þÀ±?uŠ'5˾ò~ë%>A\W¨OfÃ1Óˆ¤ï€MkM˜Þ¯Ñ‰.~£Ol|¹ïÂýÉ[Nü„œ0»‡ä5…Y³´�Öå/6÷K¸|·D¢®ßÝ1Ûóî öö<¢óSVç·PãŸzfo)BÀ7UÙš…ó®®?…5->S6zfRf|KY^g²HSõ2Ð7`t®Qjáü¬8¶&«i±ñðÆž¬‚õëË 1ÑQçŸ<§3­&‹ #d~=�ßö¼Ö9 >}nQ~ýf~ô  #÷;ïÌ��Gþi¸½Õ^DzRñÙƒ¶Ì&aê’D W"ñpú]¦¦;Pl#´~¨LݧFÛuAê¼\§·JKN �ï¤az’<ø ´Ý:lx.+>¦h¹yöæÇÑ- Ó{ú6¶�D¹¥+85æ¾8>R¿éµ†­~¼¹–C¶Å»îÙáq;ïú¶ž¬ÌôULŽÎœœ˜bŽ™ßVÿâ”/øäPôéÏCF¾Ã“UâÁóñœÍ–èï ¾âdÂ�'Fð¤açÝ÷É×ÑÊ} ^ƒ­#;¹à኎Ìw�P‡—ëÔNŽ Æv„u˜—ŒÂ€Ãÿæ?<Â#>S¢Ñ!!‹–�.›Äê#öæ’Í{È:²ç úŸw˜m\½B§ÖàO^9Žî ùŽÆLìI}�§'ê³w55ŸóW~ë ÍÑ6�ûóÝèò=òÜçâxë-¥8“ƒ=1ž{uE=õAP¸Oã޽öà|vÄý âð‘o1Ÿy¼ÌÂ�_Z½\"7ßߘ…üÂ;v–hrzbÇËúÙ7$0”#¦ãô¾¹Ñw¯—wØ„‚Ç;Xjm\möø’{r×=_±fLRHö<‘ 4¯Ö ÝS4�•Rø×_�ø|XÚŸB`LY´vúWÃÃag}n€Öœ¡õ{NžQã[£ŒÃÁNx˜�S?PQh¹��Ópöøc~`ÉÄìÞ˜—‹¿° kó�˜ýðßÞЕ–áÜY_@ú»‹‘ýÉjÇÎ û>(ûäQ/Ìé¶äŸÆº-ÂÀïvU5±w=bûS»Súìw`³]fóò � J\bÍu6P«u5&’þ E]¼1ÙáhéwÏj[ü8çKob5†þ³-Ð=€£rÃÓ °â:�<±ç 3’ÃÙ'¸ ôÎ1±í!ž ê÷\ƒ‰7ÇòÔÀχ‡p·Öe†7%¶õ2÷ä4¼ùL¶�ù<ÏN2­§Í>`¾Ìwò ÿ#].}Ðjh/–�=~Ær�­p-�’�Ø’A>ÿ`bS¸xr^øÂþ2ßO' £Áá·NrëÃuØõø�ûG��@O݇Χ‰'¿íÓ3žÍhàÝ"Άßt¬ÎÌÔJrV‘1ìI³<†úŸíÚ¿ú?nÞ;%óšË1š(oøË&§wô}àÁ¬s9;‹ýÔ© #¶¬/Þ¦ã¢O'¿Àã#”¾Ã€&Åö tÂa|ùƒÍ&ý‘ÅäÑ<r¹ÖÆ¢ÃcœÞ§(®^bÉ$|ék>“Hgã½u2Vði"œ‡.WSó—Ó^­ó[Zƒ1y¤fá"=«×¯Q¸Ü»ÅÉð,CR2M© @@ƒ�ÿÔŠ|Q{ãár,_´Â4ü0/”Ù ƒ‘ñ°û Ÿ–öôuІ0 É–ëM”´QWz÷@»û² ÅB÷í™°²ñOêòß÷/?fÇtƒ‘½õ¦¦ô‡­§Cñr¦áaB]¢Õì¶�¿Z x@ë‹F°ðgø w Ð Äm1EùÕoc ˆ^E€çC‹äh{¿ ÷á…ÓAekÚó‰ �X³¶¡–äÂDø»<«�[˜rxÂççì±&p½fOmMá_Xy_9Ó &Ï+eó¢YHƒIì䈛$ëøØå *ýM[d�FëY|º÷zmÜó‚¸à`FÂðø/;™“Àüç‡Clz$Œ™xˆ~j·Ç_ÇRmNÄô°»9Ý‘º®Rä—:lâ%‚ü©=Ö@§ËŒÑ&Gi«~-Õë•í¯‰í�ðõ‡™ó6È¥›¾vbMÉý1ì›B~>õz‘4ÂF}0'Æ9Œc•áìK8£æÙ‰d=ýÌ>Ÿ ½ý–9,s@¿øÕ€—ÔÆ<þåsa$08ÓÖá� ùOžêaÿö™¸aÆ¿½ÏAbœ¿ºÁç~& q˜—�4»OÓç€XXÎì(¸mŒ}ù0-:?F4_fçYMä¤i<6 ~÷Ø‹'éj´p²¥w„¥æ°%§{ ˜Æ›î9´é¶ž·XÇqq®ÔØ#fcGêZW�cѪAÔpê ‘>eí=>q‹¼ë•a\/&|)$ØD¾ÊXŸ¯�%N×Φ I9]–I´o.@ñ‹߉²£{©¤Ï2ñ˜¾«� ëw«Tc¬ºfé=Kò™KÀã*ÎDˆÅ›,LËŸ�éÌÃÊ<íùë7JNçõEkƒíQºþ’]ÛÓ—ìw� ]¯~ÃB<íÆ€ÕÀÿR³÷ºÜî”TD¡ ðø�K{¯™ú÷~ÆqÑ÷¨à=Jè‰@(M ug'/Ò €æ_ap�'l1©1~¡,˜Ò°�‘5>ß´ò9Gýiü‹—£úÂǶÎU¿Bf÷\Þs�ð/Žåóæ.†Y‹9 ÃlcnÈÃKùö›²Ó7ãÛ©rœ'K ØZ�5¬·³1ï�˜#µ‹×_ ÆÐ cð3F”�¶3Ô/Üt9·Ìx¨ÉÈñÔ�}ò'®8žaŽg6Œù·Ç2A =Z/fžÎh?ŒÂ¾@ÖzŒƒ¦i–œÁ4Ø4]7þæ¨FŸgÖÄ †™Ñéäžùö'ÉŸ^nîêóîôf=2gÏÆ¶J~cLJ6ë“"†íÔI|L²Þõá†>†!ÕÚ}=áÒÎèavTöZ:o1ñÏzZÏšØ=X~´¦çW{â­³üÎMmpt¸®L-Ðòš_¸}غþÏ89óæ*}§›ð„ýܦO¯&¸_=hÚþõ}ó¡ù×r¥œ¾ ƒŒ»sÿ?€¨3w ÖB.û4?y£ qŒëüƒ_ÞcÿrÊ8<Ñì³59Žj1PÁMe*´³÷#=¦è�¯C`8ü¹Ÿgÿ#që[â’0(ËèùÁRk°ëKiº×î„P‹¾dO�ìçÌ\çóæXE¿ùn]ühIŽ© ¯�–¿œWèr}GÉIí/A½½¬ßD¼ŽεÜZq 6rFœÇYÆ›Àôƒ¤ÖÔ.‡l¬‰u §ãˆ!°Á¡Ð5èm—›=Òx¸G {ûëüîÉ8’(ö¼!}³ánÖí5·Gž!‰qMÎ3•Vg¾˜sϦ^bò½TØË-¾`s.—3¨oþ«/ýÍ~£BÙÎ_Hìž¡ÿñºÖnŽ Åç›êè]])c{ê¸rØf .rØwzRíßó+J¼»'Ȇ†âCrùì{‘@¢|/Ç)cæ‰ÇZìâ×f½cÞÙ�yéÁa¿µÉI¬¹ñ4W)í5õøâ«dX._l»:§Ây㌵µ:5œ½ŸT”µnn°ëÁf­¥®[X´kÏyÜ:¢78|%ÔÛ�±oíåž&0Öˆä;×~ï…1¡>R½¾µÐÛPå^U,BùÔÃOMÍòY�//ê„5¹|òáÒ �ë|‚Wƒ9ª�èØ1]ÉcªÏet¨=}dC¬æÙ– �ó&°�ïûç~&Á¯ô¸‡š}Ì2Z'¢Œéy²G�±M µÏjÛS`€Š¸ÃqÜ“ßaZÅÁãúàÔÇt@™uÎ92LvìˆrêæXó)¡5êuMn×Ä´5zÜ_bEâÛo6vÎaÂÖ<ÜŸÕƒ_¼ŽQ"ç|c-:j>܈ú}oøÖÖíDÄ¥†ÃEþi:È‹ñ8XâëÃkü�šÕØ.á"þ Åhùìl6mEeÊ.½}‚ìŒïU�4~H>2¸¬ÔÙÁêÏìÂò?£(˜Ï9«Ú–Î=}°§ïà4œÍ=S¦õxöéz4Y_ùnSé"‹s¿ ãÃ’ÜÈãM0ž/LÁ~ëÌ.gdÖS‹É±vè»`zÑBŠžµ�Î÷k0AQqõœ=&órFMÿq¶,ÛXïŒF )Ð^‡�+ðè_�&ÜûØÖ-³¹¸ 7[†Ïû£Ç@çºó{Ü7ÍÀÁ›ë^ #“ÆÇ% ‰pcÍÌlÁʸd ö Ö `uˆ÷ à-:1#r~çêmFR‡×£2Blv¾é#Œ¿\²FðÏM'ãø~çKÜ0àaïì~ÃL¿ÜaœUûóC Öãñ àg€Xܰãû£‹M€"“³oÍpø ѪqþÒЛ¢·iª˜}å Eç§WÄûqûqlíÑü³N�ZåSûêðLj±»zé$ñÌFõ9²56Ňƒ:2î=M̹¯ä6‹8\鸔nÏ�õž�‰YIÃXö=’Ü×å /ù2láüÌæ‘{�åz«Ï5À0’b§æ³gc±oM<ëå>v6ªíøØ�ÃÂFˆ¹ð-v•Lçfù]c�«÷„±‹¿¸ý°ÀÆÍæ˜7GkvˆìlW+6Ë×…Û‹‡ûÊâ/ãä8sV7î†>šàr‚�žü6?gñÖU IõÃÕ8ju¾¶õÕæ\ÔœÔ�º_Ó]Óãî:Ÿˆ:ÜÃ-<–msMå#j=xïQìß‘óž�þÿšN§¶Ïõ{oîbÝ'…ŸÚ eo½ðöÌÅeç‚�‘ù�ÏY›D¼ø‡MU¹_|/ÕjƒÖ§þÆ­©ÇyŸ£Ó–ü7ë’Ü_‘Ì$šoM©Y–~� Ãê-ËÒž>Dë­“³ËÌÂ…%8ެ}�†˜Ð}ŽCÑ}r¾»? <ôN˜TN×=5òpCn¬+~d]Aɵý=ƒòرú‚J�[oÿ$PþÓ\…ؤ5˜ë–¡þÊWT¼ìß¼³C;;}–Ø£7­�ްÌþÞ?føê —̧ïÙ‘©6{³¶Pxc›®Ä>6–­%5c°ñ›˜íõ35·Ç9ø|òzM?yà,8Z¼‰�«ã Ø½&?¹4Žï`Bew9�‘{†Ët¼Y bÇ&þÎÙûê˜ðØÙÜB/Ëá×4´�Oy ãêÏì¦#mÃöqÊñHËkåD�×É¡€.ßî�Oå^ø(ñûCþR4ãòX­tšFzºõx#Êg$×ÎïÕu¨¼H|x¿l‹›šœ½v|ªIÑvÿ“Ô2,lëAxä�Òºˆñ9ðÿ¿Œ½‘澿ž¾¡Îm‰ú3†SÔä�Ÿ”sïLšWãò#ßö༯á’è‡öp_‡•éMào/|o`$' 4¥öÖh!ä2ÄlGC¹_IPìÑbf¹Ì¼(ï­å5×ËdmC» m\Û-ÌÁ”㣥±vÓFCÍ-“gl�ÛKÙ÷MW¼ ô©1Lé›VéÌQÜÉe–�.ì†cZ/k>ˆ�=¨{ñy/Êõøæ¾ùïðqF÷ò†#°ÞÜÞËK‹þÎÓAÄÍLåX–×IÙý¼‘mM„ý»dèªÓ‘ºL7aéñôáõí•@ �%–ÝÉ«5±Ÿ³Æ†ÁgS?¶Žõþô@iIé,ŠAÅgÈù‡Mâ_;ñ Ð^Ã1cN"X×¼^w¡¸ #¾X÷Šº4ò^Oòøû1 ßòm6:—åòZ~±ÊF—sW¨a¿÷Fõ£¶úîŸÔ_ûS<‰ÌëÅ–G4.Œaö6MÍM!І…3¸qÁ.)që�å�«YŸø4ÞAñ[`pGAc yq‡—}’]Ÿ`ç·Öœx`'ƒ5³÷›€ÂlX³ì™4óOÓô˜SAë‡ãïž�BÕ3ÆtŦPëU2²fe[Ãã†!ÏôôˆaÙ³¬í¼�é`ÜÉB~ÖŽÖ|r=¸d 3ù–Í,Àd_ê Áò°KÉ=æ÷,Ù<@ÍŸ˜Xƒ Ž=9ˆ§½cí\Õõÿ¨4OŸ1¡=Wóƒ…³y¿{†3½prçM~H>ÜW�8†k0—“AëxêÈG¦cýr�áJOäxzlØÜ£žƒu‚ÓãØu+t¨Ãýyp³{®>—.ã4¿8ÛŒM@%EK�x¢q¤ôл}Å2á2�«ãŽ`zž/3»÷NÙ¼¯ƒ$§w]/GÝÉ¿�#àÂÀ=‹¡úe"Ÿ{ŠYÃ'õü%Ùêc-óß­ Ç⦇}^Çð¿÷ë�0çÃX­m¹ExÑx5$=†Éà:]k¹% R¡£Xa³¿Ìw}`d;P8óÒJ¼Ü™\Šu|jïâz¿ÉŸûá�N|ŠMMx?8ÓDœûpòä̰}ua®ÜÕwŒY°¹P<©)±ì l}¿vô'-©=ÄÆ ïzLC1½´ë|×ôc9°ç‘Z>8q×>"àÛÒþä“Å6Ïø5¢W@ÀÕ�Ø]|ô §&¾wÙPZÌŸøa oΙ˜‡eöºµ(�õ0}ÿûÌÍÕ&ðÜäGA O*­©Í}¬†äÅ¡Ñéhˆ5×úŒa]}pE/áù í�S²Õ6ëØòΩ�’Z–]ÎáCѶºýÈyú=­xÏ­²úºz±w(šÌÉagïeüì«kzÆÓðö!;çq�ó‚ų%ß«ih§¯@Gu4›ð­6bÇ=;9°% cAà=ˆwÔÕ#ƒPÚœ}7–lÏh?Ž_®õûÍÁúÔdíÁAoŸ®ã Þƒ>ZLöÆî—<•1�sä˜<·Oß„�¿AϳxçKv_Q½¦w î·Œ*õ!Ü×Ö{OSÛá<àÃå~§r×7‰¢xÞb{‚×?Çs‰oy²v(oÉy®¬®ÅžzÞ<ïz³�z_ÊÕ#x™í�ýi [ù?{lÄ ÏƒëAZD¢‚Z%Äm`›}6üåÆä¨a:›¡kçþèùÅx/•žI€Öæ}µœü]L‡f¿ñEüò,!¬Í]­ÚŸZg_ìr,…:f³—w=ƒ1)t}ò`{Çï�ße¾ ­Sóæpšÿ=a›“Á<®A‘åÜ£qyOͱ$ø‹§f—àšp4N—±ö³Ê€ËþîWëü̯¥8»çMËdÍ®ãCòÌ=4  ¨\/ñèkoæÿ�í/Ö¾RÒ|RÜzwœž»8e×ç8£ƒšÐý�áãØ_š_kÇÖ–qtQ§w7ω'Çèi¸íµW³qÖt úÐäa:]dK4÷{Ö«‰9ëT°,‘„1|ïMóö&ÏËkÿðè/þè`/¿c4/·éÊÏ7”ë˸ݳåþ4)BÀÙM"}²Ou]Ûo‡}`ù‚6~Xȱ}þiÎ I®/'NÇ‚áYûQ&Ö±ç"þ¥Èh«Õ±­Ýë÷B­ÅOÛëù¾8�ëÅní^›‹sÉ#Ô{>*š|ªc1æk]¬Í¡½çÓ £¼ó9Y°ƒA-a ÙÛ˜Üc`þüð‚M úÕ™ìõ(Ïña·cØØ0Hõ³•6‘]ïVÒ¥X§&…P…|8ÏÞÀàÊzbNR²=÷¹ùÌY EMÏpÒðæ/Ô^_bÝ™+ÁœJˇS Uû|O=Ê9+é÷µàZ——,AæÜ³%æh‘ŸŒØ2Î"`£hº’gÏÅËÎkgÖq½ø,Y{ŸŒÓ¸]: È�ÎÆœ¸³hà»ôúô}Òð´CŠMŽlÈ;û¸²§&¸©&õFcúö>c\D™�øÌw’ U�çj>ð,×7p7=Âo°Ù}(:«!~Cî+vCÀg¼÷É�M†HN¾Õ¿“€pXS–‚þåŸZ%?ÞelGªƒ€xRÛ›Oô® oýc³¸è…5Ã'‰?]KnÀGƒ#–䵿j¯}Ú° ÇZpx ™µqVND7ÖÉkQ@ Æ×L 2tÆp9[9ò&ìqÉw¼‘7—èÌ31š“¾Älo�˜*£DŸú4•y[£Öö[z°æ~xNýâòY<>¤ZcGWžôdùVñð�¯½È2‹ â¿ë®J�øÅtnœóÑ!j‰(÷“ýj€W0¡T¼‡ƒT˜ˆçò3ŽîÇî`ÃZ$¦¦;Íql æ{§¦úhýMkÝ0:Q¨a ‹kÄž˜ƒó"k»¹Ôæi\Ú¤÷SiTè Îþá4©ä0.–(!-*½ÇR}ÏœnD‹µ•‹÷•ÙâÌg OSÌ�.}¤ VyýIÿ¯6™G~jÁ@®¹Ø“^[]Ü©Ý~­ùðº³7¹L ÿ îÄ�X çòRHš³kE1¯6bØ›M<è˜Ù2ïž™õoÿé±ió®Íß‹%O5è#øèñF—ñ_„8œ¯æÔâ8‰„m¸qÁþü+Bp·Ô(�ͽ1³ë1\[Ÿ×Búæ¿÷OÃØçŸT'©ã!´Ž ÉýaóNämVa KFô�fuác8__ ö}8ì{€[ïY[‹'€é#XÆR{^ã6›0Èõ‡x››,²`Gˆ·ì1Çî�S{OråíV0 ÀÓÄÇ6³|þá’µ†1,l¹«yx¢ë6? +vÎ)Û3(dnkZaÅ|ô½q¬Í§¹ÅÃeöî�„»9e_®»tGyÏAÈLÜá_Ýä‘çå2ƒíHÏlÌ…ˆÏ 3ßrö6AñÉ_¾·s«ã†ï¿A”óLç@žû$îši\þáÎöØÈo6ÏZé3µ~+^=Ì[—F=“%ZoˆÜOŸ`‡ç½7¦‘|³¦WØ’OÑðn–Û$ñz;{ÎV˜Õê<Í•3¸r×”>z_ÿ™šÊ:e$Gzy­¡º_êzµÁ�ºêÞpªNQ}þ¢¤y°ŸqÚ³E⨞w°ÛÑ$Ÿ,…|°OXz–iÆ�xÍ>xWÃÍè³êÖøµ]¿öE¹X`�ߢ­Šæff|ó�s³u:`ñ——˜=À» –ú`d³ÿ.Žóµ‰ØoÕžGzÔ¼¦tãÞzCws·&8SÃæ‹;¹ Œ¿Ò¢û†S762\}äqâzP®¥8(¼¸¦ÂZµùøË±ÞŒËyä»{z¦à8ÌîžvO¯-¡ûó&Üʨ¾œ‰ÂÿЋŒsLu5¬4%û�9ˆuÊxê\îSà¾F:þ�¬Îö…æiãÈZ/ªe¾ÖKHè!Nÿð½à²_Ó]�P÷´vM®ÏYò¼Þ_8…ê{Ÿ[©êö_QŒ¢gÔÔÏ‘¢U âh—ë$çÄ,ÖeÝÚµ3-_uµúÔ Ô9$àé}LA_,Æ�øIIæpÅ~cÀç«ÖzX©‚.*˜õ Žyçàê¶»uÁ} ÛhÆÞ>ÍìµÞo®KÕ7C r/Ňmv-Äóa³ØœJ‚Åà¯Yg»ÅÅ£e÷ëå“MPPwpVN“©†àþB˘€pw»^îl™8Cɧ~�ræ"f{ÂÅоTû08<~À¯M´Ô�¶‹Z^ìXëaÏG‚äÉsŽ=&k>`H2Þ¯ÇÝ>i›ókÖ'­�çÐY¸5Øñ66)Áå�ö­Çé_�Yó|KÜ™åÊ= 0ùÏz¶;“ †iØy¦Æx²ÈqûJv¿+‹0¹'˜!G—pú^,ùˆ’CŸ©•ü�_"kª� ;¼ *?æ8ŸpÓ3�6j&\htx×Ë6›mfóœÜçÑj_+ƒ o¤µÆÖá²¼ŽÝ¼Þë²Å:™×‹ÎÞWR âbÏF³Jê†9u2§¬€-™7¶Ñ;÷CdËiJö&÷É¥¨Õ�1¥ÅÎã|}v£�Sƒ3÷"ßòP„1`Ûƒ³Fí­—9c|¹VÇë0\ØçØ:¬1kcØ£C„)#ÚN )*,#ÏÎ׫!œ»b7ÿ£e¨™õéAs–àýYSôQ´?ƒÒšy~ûhù¥ÿôg½:®“À üÆ4_Dh#òÅÒ¼­svÚõ–j IDAT)ˆ�õÈáìËk{hr�oíXáNßž³~»åI.�«†¸gh3Öi;ˆ‚ÅúíÅÖÜ/—M`Š37[9n„Özƒ56YqÔ‰� ) O�©Ÿm"6!ÆšfeÿÖ¦ñ›×ýONTsdÜŠö†n|þ•|­?ù²ßÙc#‡g°ÓÊßja׫i6ϺŒ—ýx<¿ ^oÌY›'‰q^oÆRn—7µ°ðb‰�.0˜ý©‹ìXÆ }2k³@¼`‚g|fùÖá¸!âKÔ�3Çû§•‹aÖ°&¯ž‹òŸfcnÌÁzÑ>”ÁPÎÔ�8g™]¦Ë¡•ìÛávpÞâWÙ8¶Gqì�MšÏ�qOøcûY8Ž:eßͳlf3§¬è±À{.dæÖä=yœß»Ä>3o8ùíT|µ[SmŸ =²|u�§ Á´wᬢ׾œPò!_ºðɈóA²LŽõhóP›]×ú5£öobÙ_Ží€ýsä2¿Ñ4„Q>o©YcµÝYñüw€€õ1Íœó‰ô¥Gá2Bq«çð’Ï)s¶³Ó â?ƒ¼31ënƒÄ{~ëh :§Ùîr,Þu‹-|Ñ1^lÉ˪kÍO˜#Ã)-@~êØóffï�á?¿7q>«™sRs Ÿòaf˜Ï~{±˜Ã¿i'©¶ÖåDq/®´¡—9ƒ�…“ùb¿i»Í¤Ü#3�aOìí ½]/úÖ4ûÛ£0õھ͖óÝ®JŽL-ø´.²GìX,)UçË_{hì,7?ÂÍñ‡Bùl¦Þ úà,uÔ~{ûÑ�ÃüØSÛo-¹§×u‘F@úqÏ Üoþí“ääµ9ø“ —sºc¿gM¯âëóG|ËŠÏnáš±Ó-zGž¸†ÆþŽè��×¼A›3»ûÅâ£øÃQºzV˜â±*ïÜàbö—.Ä®ÇËáØýóã£Ç5r�±�eî5íÞµÝâpX6öcá\ô(8|yDÛÞTMý%ñ” èAüékÖŸÜhñCîú`£áH0zÁÕÂ5sÞ‹ÆÆúÚ´Ñ –bf#t-Ç&‡Poâì¼@Çõ8…%ïá$ 8Rš2±¦Ð%¯½ÅØ5æÕdDóîLw6øH‘ˆÔ$f'Ö˜ƒHÀî;ûN¹}Î!عgq[ÿ4„°WÞ”È_}Go”XƒãÆYާo}˜sèO_¯�˜Ê0Œ=°Õï³ý &œßçÇÉ£Er[è&ãêÄ�M�¸p;vÏ“¹±÷îðÏ ç/~{F¹Ø¿öÊ`ºg˜³šú‰-°”ÓI-G� D:æM­hã�„ð¹Å“¾DÇáÈ®>”E›ÏÃâc³ÎrNËåJÐç~$oŠt;‰·]ofj+/ûqžµ|³™MÃ3wmNz9ŸS´°ßÈšÎ�N]¿x°ßXe¨Plg°Ôã­ÁîBs4…3÷Š3’–×õc±cû!ѳ5>ëûØEiV×ô:^>býèÏË…öäABêgE�ëÅxÁ’Ї‚4çÃù\‹=x 7¯9ݯætBCŠkÌÑAÞ Ø?µ�¹N4Yá Ð’�Mñ§.­Ç'h|ÄÛÀ°„Jvó¾yÀjœ¾j½>a;ú)©~3˶áï‡Û\H½ùY��Ozy:ªƒÝÍ v� n»ñ1ƒoeÎãúI£@ÛBa,K׬¼áÀ"vŠìØz±ËéFüb–HöÅ�G‰Ž”ÈJŽálssµzò/_ü)çpREµŸ"¯3«ö4uêç7öµX]'ìñEÇO·-Ä�Ñyøùoô¥�‡«õ¸†Õ&'¯ãÅc»p›±¯?ü0ó“‡!¾[[m˜û ) hMÑ· áåˆ(ì]$¬³ÁuÚ&Û ý¬Šo~¢·†kÅǶ+7ú_Fuºèi.ì6â/qÎø}ò æù9(Zçac/ìÑU?_,Ž­àOMÓ©™œ'ïø5ï·ŠÄñ0_×Ë¿8|ã[²S0;JhÅå÷Ÿb�Ϲ—L³oô‚­é7}/^~ò­ó1cc~uû¼Sîù«‹1Ä—÷WúrEFÎ×y’ÍfT:î'Ø5Å“ðç:3…+Ë̲ºcŸ�Ý]£�½9Xû,Ò�£«ÚVÏ+ÕñôÚqS”^¾¶ôø›7ýK,þô±ý´ö躬Y%î­#5àuZ>z’ßÉÓº§œN»z½�Tñ²¿�+zYÈÊcCë`‡g–…NõàŽ–x�8.i |ðоIÖþ¸·€Czý×~Õÿê&ÃÊb �k¿FÒœ‘3D¿Ær0ëqÎl…ÝgJ`‡6ÓOí Ó¸N|¸ÓŸÆZ¨Ö‡�~òxmÁbóÙ�÷Á×h¯Øšœß°ÇkýƒÕE_1íêx ëư¶ k0“å=X»n’Ë{Š¢ÜŸ{Öž\ö—žá¯ãÄ<ÀßåMÝ7fPðoó¹³ užƒœÙj÷,gSŸ>�sñ“±}Îîž¡ïƒþÏ‚½šóJ³†G·«¨¦¿Åœ³sÜ·ßÔjò¡¥úɾóo˜|ÿMNÉÂSŸI¤ªš¬Åo˜”:Îü²v½Æ—µOÐlÑfGöUï©ÇŠ³Ñ [£åî£×®ÑTobÏÙâz�Brj"Kþ_þë-è`µ€Æ\&+ç·ÝÎííÍ' à©ÉºOCpRÏØ2ŸÿvªÑÑ€zHùÎÇä:ÿD՜ɗþØ�]N3”ÿ«AM‰¹ºs·ÈôùÀÓGŇ]ë ÷ÞýR çÞëþÑ™¼à/·¿¦)Æ©QÇл>Ð’úÉ–0¼Æ9ûÓ8|©KvŸÇøÊámmıԃ¸½yÒ½¼jRê[s?5”h=?³ÓkG0ŸçMþØH�oœaý&vÊïš{²‡Ó9 ªPM—o6qš–\É9üî�7†çû(é}¢ïÙ¨+JŽq“�}ÿš»ã}P¶­�ØÁ Û×ê'o¬ŸHsKsOá±� =e.×–D†®w�„ìµ½|«åÕöS?Õ䨿g Ës‚uóie?2¿áÙÇâsxzëZˆñøD‰ã»7DÜÖ+ßò�ce¥²4ìÙÛÿÆýæÏÏ›ÞÈÚ~A’3Þz*ã4ÊiÑr¹ÆAÇìžàÆ¿¼‹‡Šû<�¯ÚvŠú<'›>ž7ËÏ pò¾zDpíŠÑýŽ�¯FïˆuÈÅ{%£ýÊo?|ÿ Nt¦g?Y­?g‘+ÉÎê‚I Öí™5¦ÅÌ)c1ø ³ÝHLîÉÎ#6„s²DQòfNÚèqN.ð{ÒÜ\¾+Y{Q#µ?g°5³“• :ðz̾9š¸:å+_Ön¼wÁ±÷ùVG]ŽÐ€d$R—@Ó†{9?“c(4ŸšU~‹²�Áhä†PqÊe —(´ßñ6ý?u�‹¶#·­D�Üÿÿãx%µëA²å¹Ô¨I…Bléûµ^O¶ÇïÜü° Vö¬eŽQlwJ‰¹éÌôÍÄ Ðì˜w¿µxó¶+›ñ!1ƒ\LÕ¹úV�!ägŽàÙ¯/"0W€º6äW7üKmJj$TO÷ïO<õ™Û´*ɪþGþ#n8Úó�‰Íçß0,‰i~)Áðqx…_ =±�O}ÃQ]Àvœ|;Fïò½™ç;Wsí¾p|àAN4GûxA2e®£ËiMaørßûð “°Ô¥kÓÉIbûiˆ#d;fúüáwsm«â6"9":õ ¹r Ýû»þ&˜æXyÝ–ó“'¹ îðâÊÄ™ RnO�y?ž;¿üÄáY_³¦Yäs§ðïÍžû}æ�óüâSyz¹Þ†Wy“8ðŒÔOºusÅÇUÜæÏšLùœÉÛ"­a(Qy�%9´¿z;G†À�K 5Ú†¶Önœñ±…9™€±…ÏëÅÆ$?„MþƒÇÃXÏX§—•ÀóÖ 4´ c¯ ⑨a™SS><_I Zß–§! _Váî9Ëã ÊÃéï·qê�4³äòÌÕ¾Ÿ8‡L=ä·]l9g±€ %e÷²*‘àû$Ÿ¾ŸºSÖSKHmê² M‰ƒ[h¿‰°ÆÇ5}§‡­Æ`@´ƒ !Xc½6C“hݳ ¦ ¡˜é3ûL~x±Ýûty»5…$�;ßý;‚ñk¿O�S~jMÍ.ÿ9c¼Ë�‰=øÇÍRë_-à>1Ø[‹{šq’OOæÙõ:"™¶Ì~tOôöćÆêüèK BŒ£ôä‘áã3äs9ÜX•û³—ɤ„ñÃ0îú]W}G“`‡×ëÄ�åÞõ8<±$/™Û‹ |=¼G‚�ÿSŸÀÿ‘k üÚLÿ[ó˜�>œ_ôJš±Qí¸w×Úµ¿³|'§|Ÿ\qcºþLËãÜ^l˜Êï“W�kƒÃ»³¼妦éD÷‰[ �Zâßžøc­¦NÆ�ŒA¿›+›0ºO ¬|c¢ñæ1“�©ˆŽd¤vÆÔº»•ž~ßMF÷PÔQ ˜§Û‘“{‰y#ßi/[âãAÓâ¡óÏ¡ bᅩl²Ç7~÷ ¨ž¬Ò¯†'4ô�ù¯žš-×c?‘Å-ßfÇ’w<ÎgCRÁÉÖטÌi\Tr=~§M­Ç¾Ä%×s˜Ÿ¼æu8’—ÕFtlG½[wV,u¬¶Õ䟭V— »'Ì~ášst?ÿ‘œ`9 f�F°"I.ø?7¥¶\’|©-vËk.B6LÉÅÌæèja‹= ª oœy1t8÷b™yç5¹òN^jÚ˜lÓkÅŸ."5Ÿøƒ¼?cäƒ ¹c Æo>vΑ½™Db�{�~öäpîì�½F\,S¿“èî‡?ÌåÕd÷´9zd]ÜfBð;&FçÅÞAþÃÿŽ=ç÷í……‹~®1ø,È žXÇjÿ–×5ãÆ´ò’§šÂ–ZfKˆ³D“±a�>SYK³O†f"íwjÚËДö•—å`Z}²c^-f¡àÓim® ¼’Œû¥%�¹>F–²38âyL/÷]¹–›©šçhs°>½/{ëhœI(¿žø¦ßÆ^&ÛœØ^qrÞ¼%kœë0ëD%Çá�J'?¡YXKkN}é‹õM�µ¤?Ð0n/ôEÝ=ˆ}W``Ðð�Z_^áN™’t°`ô\x]Ï0òy?œ‹« °Æ§þ&±žêzû�}x GG¨¾ÕCâ;LßÞŽçÕ¾¾Í·ý޽رÁ›yùHÝ{o�$Aï.±MvrŠñÞšù?íú~y˜‚%ïó©w [€hòc™_ž¬>ø'ÁÓ÷²û}z$_ïGý[K8SË|ë1ãB[éÚˆfôÔp ¼âÿØš¿É�ãþ÷<�w”}Òû—�Îk@´¦<­/u±O~«ÅW]&ÔրþZìÀ™Á62fÑ®¾NK(…û”ƒtÀs¯ä> _L!•Ö$g~ÖÁOö77ñR6ÒSäðÎÞ˜&NƒòÜ–Un§á²;£ó­)g¬{…–õû´:R›[ñÄî“ã¿Ü—d>]†uRçøìÐåÚÀ¯¢ ™Å›˸2/’†THØ­íËä œ7ñÓê€ =«åtH5ÎéÞb •gðÔȸµ ûé¹ÕaWÖ''Ä`0Ó{w ž/0xÏÈ}°½ÁBý¹ŸâÁ~V, óà}B›Ç™:cìî.öôX<[[±Áº,ÿwcüb<[s¹�Iè㳞q9=N}‚ο &wÛé@\¨fËÝý=‡åë'ôÉ¡§µ²6Ayý óÖa€ñ í“ßhtØ­‹ «ó7¯……Çå×6©c7 s˽r¾cl¸ô·6M„-ëôyMÎr h8 5€Q³ðÖR;¶qNãfÂì£Å­ÞáñŸFœ>KŒì‘>NÛã1bý¯Ûh,6–‡g{2®Ax].ôžúÊcíâ=vkÙÓí(åä[M¦xsL;‰£Wÿ³™��žÓ>]øXc×c~{sr6hÑ(-Ä�xŽÃjƒõÔgd¹ÀÓÃhaÇh}Mò/ábŒGqί‹cÈ�¶büßàÓÞ5¬Æbö?1´ÒY£óý0Lü}j¶M‡Á§ábcO=µ{Ÿ¢�OOÿ’QüîMhLº_lÏäå[.ÛÄ3Œëé~6%:9±íIìY?¼æ\ðìè}ñÞ'¯=Æ¥&ç3X$ãq4%÷áÕö Ù܃Nµ‡ÆçqâÂèÕ&‚FkÚÞ'Ï¿I²ç{rX‹¡žs(5qìõÌ¡’ˆœȬ½yErŠ)±Ø]Ròe ‡F{ùæ3ÏâIHGÄ5Ì´�†§õ1Ÿ˜¬^iK"-1àÌãڽc“®ÎÁt�ÑÕ½ÿ €Öø�žÃÕxü7SpNtûLü‹Á�oheµ/µ£ë'¯Œó­ÎUg]W~Â÷Õ¼XbÌ}XIðÖV½²‘×;øÆÙy_cs:ü£!¹þ�z°qx�-ɱï1¬Š8iìS±×#îêGdžùÆ)¿!Ä Sx 'ü¿uœH÷K‚å˜ží­•ü•0?z†ASÖé¿kPò¬.ðËËxà<±­9Ûµm½Àýát/š‡¸&™¶#|$ÔRPJÒ•Es‡k²NŒtr ãõ„.1•UƒÃÞMyÏ•ݯ·Ó|zã¤Im]º€™uÝ�åÁgåß¼¸aü0/ÉésÄṵ́П -'ÿÎÔ·o¿czb ¹|ß¾PsxÊAèh—¿†å{ÝÓ} ] ƒ_(ä“+‰¸%%šˆ_ŽAÐáÀG,Ï[#Ûi1T!«oµ”â3 WÆæðc#~�‚n.ÁRø›Ûj�ûjÛ¬¹?3M›)÷Ü—B¢¥—ø/§�WçI—<òšÃó¹¤÷Ù6À½íë?¶‘æÞæk›�_�®o4žÓ‡ô(\©7œçÓM��'pÕ“­m˜Ï¾kíÑàÑúŠéôÓ ™ý Jìî¥ÍøˆçkìZâ¿8ÅvÒíý¼‰ãxûg£f«âK€YÃç+Ó[[JÊ}´ü+öît¨Î°\~mìŸ>ˆ½<ƒ¬¿z�H¾½~×›ôûåþ­éÖþžšVú¢Ãõª%özÙI‚ǰáˆ_Ðx×›þpᛯžÂmá`ïÞ‡Þ¸qŸ3ZP˜dã�ÓšÁ:=ª!Ö…ÔÝßšžûÌz çÑâzìðeŸÒ&ö|AŽõ"5Zïú¡š®V⮦²È„­ö�›ŽÕà2u�œwàÍNXÛg`ikk3�Xù§ê^‡ÏKÀî­\÷H¢d\†AA ,h¹ËãK^ë*™Ï!¢“Mšs–DÍq甼=ùÊ­%q­&Åúƒ%79γbà@†û*(~†mày<<‹7¨žÖ1íš©7ŒárœÎ1ü!Ê{Ç×>?1àïÈ¿ˆrÞr�ÏZtŒæq;n0ÃÙõKß8ó;�KFÒ ¬k‡N› Ñ:t惡7sµOIÛ—0˜Up9¼’ópÈ�³‹þ¤­ÄéÁ_jáçB ÎwT3ö½Ÿ˜ ºè'{ÿ¢pq�Y�É ù²�Áöó©éZ�4øõÜ/µàðïINô­ß›ÓÅÞ~\ojŒ&ëÇ£ù°ÙÞ<ï~±¸�x&¾±'þ,p¨·¨'ûé›] |×’Xâ7¢u»Ìx‰s¿êr*;dp}u0UïfŸ»sÐsþfS›`Ä€C›Ýp2ÆÍ:ßè·°‘ƒÿ[Íz™‘½×Ϋ�¾ Um>^´x8·[m}ŸF _8wcžÈŸ\XÆA ·ºÍá“}~ê‚ÿr˜Çºnû§r@Çé9D!ÄI°9¿¼©ËÌ ª•'8<öV/Üc öã3ÃïÞyë�·µÀ9žg'þ‰k¶°’»ù£Vªˆ¯i|ËNŸŒ£Ázu(È6b­i9™íbfáM×䈆ñ±_(¦Ï¼É ëÕ Þ±ºðÍ4»S‹méKPÍ·c‰S>Q±:)›}«·ÂѸö ï]fzÀžø‚ƒ—û&»}²2ó0ý„�‹û©%.´-þæ§÷Ð�ÃhbFØúξÜE¸Nÿ ôpèÊû�õ­”CI ÷XÙ芿åØVœëÀ§á $OŒLmu0M�ºèàc`qã1¤=89 î{=Ý©oRÈíûð9Ñí&š»<Ñ>¯ŸZFŸ¼N:Åa•‰÷°åã^È7 �GŽºì›‚Ô…†§>£í‰uubnZÿ®DÝœÖä�ä"Üu”ĵ•<ç§œ2¦Sú"Øox¬áØüÈp-¯nû§ææÀ ’÷Ósh`¤?]·ìÖãO:½5�sæS×>Y¦3Ò½~]<úÑ‘H@´†bnAõ<ëê+†^M1¬o_CHè^�æu"éi dõH-2šÇŒþt¼<òG9úz7þåhœOQï‡p>裇œf6Vf¸á\WBN�`­œlç llÒ�A$.u¸ýN®òµ�9‹™~ZÓxèwòp øÄ�‡û p,îÆnçÀ0$n}½¸›tg9ÂäHmæ ¡µEŸ|ä“Ýšêg²ÍûøòýP !€°Ä´>⿵žûï“ýf¹t&„´#õã7ÆiÕÅÓ@ÙÕlÆÆi+}<†±÷(¬Ñ\ø‹™ÄÊ:Æõ"_~ÐÉÿ”Ãy¬/:ÍtS¾‘y =}šÆä!)wL’Ïw ¨Éwuöàz ðÆÅ*$�ô„ £­‹¤µ}±Óà‘ãeö ˜ žé¾¾qÔÄ×`m²y7vÇ¥Ò>8NýÙý Ož‰ÀΞÚ7VÛµÔ#L¾”Äæj’o÷‹™}i?A'ß§ôÙ~”*ÛeœS{›ÐøµÁã|3È&†ï×+~¾£Äðß÷…ôVŽÇ÷ö:l'·Â©!.H»Ýô`RqkÐ글¡Ôtf/{x!O>×z½„}ÆÑ8ë�ßflÕ»ü̧/ÖX�ÊåûÀZ×>�ç/ã>èí¸�ƒ5ßø!²Š\€?1'¶¤Ñ'¨bnϵ~j˜nÂç¯q=ËjÁçx†ç«#_Ÿ›ÇÜŠ÷ÏèÜ2 ‘QÎ�Ùµ¡‡ áX¥Ÿ¶øòÈHŒðèkíGã ÄÆÌÆéic¢!ùÍW­¯¶xÇ€Lñ‡õä®-=Â^Ÿæh»iºµPÐ'/FN>[YP#FN—¹‚Žäeoâ§Ùb4Šó{¸ä9cñ>ccî¹¹hÙ|>âôY*òôè]�¿Ìæ�pµŸ:…�îúT”ó 7?(ùÞœ†4_x×9yNœÃÂ&ÛÎ|òäd·9á`˜›ÜÞýh(ç/ÇúE­û ¸Rdj/§ÕüîUzLœ{½ŸàÖe‰ˆC€DØÆ%wj1Kc½Ëz6bðiÖ׊ÿÓšÍt,‰Æ±µfa�LKÏ#Á¾Ð¶KDûi~ŹБ’óŒ¬}‹/C11‹÷<�ø’ ì‚ý’=þ^{d›îäÁšz<ÿ)Fˆeg&Žá¹kVƒ7¹¤·¾}¡vϨ3�œ™×Ù'–5gÁüÚá´v`�ÞÛ«ïzóß¾±àÊM–9z‹j=§ÄîÕAç}59Â?ôÝÜÆ ›oœ§ù“!ú¼_PÀIœ¹ ýæ²ý"®|�œ! Ø=m”ïôí ‰[óáâ=ñ>+­Xÿ¬oŒ×Ó ðbµrhüÊÓ_Ú.×~¨vi‹_mŠÜy-?=f~îç&6ãX%ÌËwl⎠¶OOó9s’/e³p×[¹� xxÞf¾Ú£#À×N¬µ:E¹žþ„\z"74Ť'áÅ'õó˦½>ˆ�ë¥1ü\ÊÁÔâä|rí L'ìîohà>1åÝk0”¿:ï>|wŸoZ³÷Y[xîIäDþ0û*ã°;ßñ]ÆôŸ/[3½ªØ?M¤ _}æñæÇá_ìÅvÏ$ÜîKu®Kå÷AÒåàh,sÞc/ç8îLìÞ÷²ÞyÙQjzÃRÎÏõËw° íûg‚Ñ>�KènœlŒ”Òû þÓ—žÔð tÌ⼑Ú¨¿)í²ÎF�î«w¯‘äN\ïÅð9azÌ îÄj?ìúMŸ“[ù ó/¿‚Ë4Ç#HŒÖýò&B�Ö—£Ûžhp­ä#á4§_ËšùÏÌ0° á“`3Ÿ±\ZacÁ¯f¸¦Éª9ªE6°üsbõ§ÆRÚáIDATöP�Þ/׫‡õìŽM?1†ƈâ>/VÆmo06²,'x–Ô:>÷›>7Í>ûæ‘ÇfߛָӮë/Öø)§Ÿ7—…ÌÁGg÷&H<þ{ÿÇ��aí¼ö´6Ún?9Ü—ÞÍfÿòg'mF÷ܺðG€ôÆF÷–zÁ/žò?4Їs?Šlsr¹Iµ¯/¾×n%†pÙ™°ÆF¶Ñq—wvï‹þgìÕ·{›ërHÎÉ<\À¦°SïçkT":$õã`]V1†b¤'½ûç}f¼òMÛjÎL§/\pþÙÛ#¥Ç¿xú¼ÜÇÞì©�{]º,Sß<« œ?�Z¸Ì.wr†ñ¾÷ CÛãìb7W—æcmž½¶k0)Ð� °®Æ„ÃáZ�×Û[=­þóÉs…Y.sˆ¬e¶3›gsiµ´O¾dÍJðî1˜âÐÏóÖDþÆDQ6åŸïœG¼º†óh¯}8ÏËû«•}u¶˜PôÞ&5d/ÕM¹{¶¢ä;ïþ�+ï7MN? Üö­j´j¸^´õ=-uÔ/Hr]õbþòÚä¹·ú¾¥ýúeX÷ä`�ÏüÚ3ØgÕµ6Ó¹ÙÀç’÷£ÝÏéÕ)ºœæmB§é$Ó~†>k{u¹r�žW½·Š‘ÚÜÞv%[¶Y˜oy•$üîR%ñ=rzKQÓ”Ù>—£µ?wdÏð§7ªE¤~.v„V‰> æƒÃ®�Í'KoàœMkë~ôkȹ¼œç>܅ʶûV¢’E“So䋸Ã/»×Õ8¬móy–åÙï¬f >1äöª¯E9Ðcâ^„Gé;�çØ—« �Ѹ{xC`�öAŸîFîöË`@ξgáüŽÆ¡¹´&z ®§èz¥ÿG ço4 –×Ï(ÕóüMz÷¤:páy³h}·ñ"ƒ¥†k°ÆÞ58—lÓUœñË1 ÄÊv¾Ø+žõ“{¾ÕC*FúÛÀ'ž>EYpäy÷ÄÎUgÈßdyhÖŸôT×õL Æ;ØPå1&5CÁ/·w'†X+@¹snɃO£y­­ýc ?hsNƒù¦3s¸A”)™WÛî�³ÿá"ÿưæ)Žüæ£(þøoÿnnöø�1Y4φ‰µÇ8cOûh Xß³÷õå^ê5š~ Aù¦C¤;‡OŸ”/gÁù/׸ʵþL÷ð„{-�{Xqf‘EZ“õÊïoîÉí�®Ä™› ^ÛžÔÙ¯¯p‚D�Š<˜¦ÙÛw–>Þ³1Þc&>—bx_î7cÅZµp™ Ÿƒ“ ?÷*¦çÞ€ûæ(T~la$ ëÔŸ=ë}ú!gþiØ'»‡›ÆÕwrˆ~¹~î1Ógeè.�{¢µßªÔA¬ÓÝ kvÉÇj�ÐÏü@ŽÏÏé †ûèÕCœq€Æ9*VZ¹ÆI˜r%/Krc Ëk?¬äpãÃe(Gj/·û’Ùº…IìÖ%|Öášb‡Álèë}xÝåwÞ{V?Õ(.õz\¦cåèlF¯uy|h6¾u ÍÁá¼ÏèÉž*ájŒï4çO7Gù¸�áðÒ}xõ`Ï}›ûM>z‡ã•«yó e¹|5¬·üÀiWýf†JûÙ?ŠªÓ¾WåÉÍ"S“³a§Ñø�×d›."ÝýÂù$?º§ž2F{jÄ6œ1¢É{—àðާ,àý>!*3ú뉜ٱáGúy=æ—ß½tÒèq"òòà½DsD±ïº÷òoýãœÝ´ÉŽ”®rÿ�|ꥸŒ}Ð`º’S>]££Ð!¾öcÿlÝXA­Cþå·¥_ks~|Ý•ßu„5šO�üúúLFò03´ÎžM|Ì©A.ûÃñê�„Ì{fA mµ}yƉ‘?}î<2sOÇÀV†ÈÕJ®Ö‚ÙyòÚ0&ããê[Î ^³ú{‡Û€ðŠ/yóz¸É¬¿Q ÑŒÕý±…´a¯æ$k&ÃNÝ =çì˜rÀÙ ç̦bƒÔö}’Õ”Ëᬟ×Ä´£':ÈùärÆíÍv4¢gœç¨Ä¹¢̱ií~33æ³¼ þÃEO¢£Á•Ý멽}ýûÄv¡:ïËо¼I“¿$É÷ØÎoÃ%RT±sGÑt=üímÎ'ñÓ—^§¾ž×y4ä¾kÏÌ£lÕíÜãV/¼§.×’òølegmµÄèÞ /ñ÷/A—2©)œðél¡i¿Ù,7€›̹¯úú1rú¡ï&zÁ܇–Yý« +Æ9µv¸Åkݙۧ¦j¤¾ßœ‚眴PŸrDTqÿ´Á¼áµ«³Í,|¾�¦}} túÚ^ Îʽ/‡‘Âêjé…É}Û›Uù’·I˜ÔËbåÐ@^FòÁõ¾Ìm~T;µ/þÚ^=9=F“ô»l´°o¯Ÿ¾ã%Žï}òý�îÅÿüý×_ÿý×ÿÀoÀä�#ÔVIEND®B`‚