@rebasepro/server-postgres 0.15.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/PostgresBackendDriver.d.ts +1 -1
  2. package/dist/PostgresBootstrapper.d.ts +0 -11
  3. package/dist/auth/services.d.ts +2 -2
  4. package/dist/{auth-users-columns-JJ8ngvy5.js → auth-users-columns-CgyPWQ18.js} +3 -3
  5. package/dist/auth-users-columns-CgyPWQ18.js.map +1 -0
  6. package/dist/backup/backup-logic.d.ts +20 -0
  7. package/dist/backup/backup-service.d.ts +6 -0
  8. package/dist/backup/retention.d.ts +11 -0
  9. package/dist/{backup-service-czK-OAuG.js → backup-service-BZoixhVl.js} +56 -11
  10. package/dist/backup-service-BZoixhVl.js.map +1 -0
  11. package/dist/collections-schema-version-BMeu3cgv.js +81 -0
  12. package/dist/collections-schema-version-BMeu3cgv.js.map +1 -0
  13. package/dist/{ensure-collection-policies-D5PtQLyR.js → ensure-collection-policies-BVFb2olB.js} +4 -3
  14. package/dist/ensure-collection-policies-BVFb2olB.js.map +1 -0
  15. package/dist/{ensure-collection-tables-BHUjQ-z4.js → ensure-collection-tables-BY1pHRD_.js} +2 -2
  16. package/dist/{ensure-collection-tables-BHUjQ-z4.js.map → ensure-collection-tables-BY1pHRD_.js.map} +1 -1
  17. package/dist/index.es.js +65 -21
  18. package/dist/index.es.js.map +1 -1
  19. package/dist/{rls-enforcement-BDBfuTD4.js → rls-enforcement-Ch0T6OwW.js} +7 -7
  20. package/dist/rls-enforcement-Ch0T6OwW.js.map +1 -0
  21. package/dist/schema/collections-schema-version.d.ts +32 -0
  22. package/dist/security/policy-drift.d.ts +2 -2
  23. package/dist/security/rls-enforcement.d.ts +6 -6
  24. package/dist/services/realtimeService.d.ts +3 -1
  25. package/dist/src-BBFsDaeA.js.map +1 -1
  26. package/dist/websocket-BVgDVO-V.js.map +1 -1
  27. package/package.json +6 -6
  28. package/src/PostgresAdapter.ts +14 -0
  29. package/src/PostgresBackendDriver.ts +3 -3
  30. package/src/PostgresBootstrapper.ts +82 -12
  31. package/src/auth/services.ts +2 -2
  32. package/src/backup/backup-cli.ts +49 -12
  33. package/src/backup/backup-logic.ts +31 -0
  34. package/src/backup/backup-service.ts +42 -8
  35. package/src/backup/pg-tools.ts +12 -1
  36. package/src/backup/retention.ts +11 -0
  37. package/src/schema/collections-schema-version.ts +103 -0
  38. package/src/security/policy-drift.test.ts +25 -6
  39. package/src/security/policy-drift.ts +14 -6
  40. package/src/security/rls-enforcement.ts +7 -7
  41. package/src/services/realtimeService.ts +9 -1
  42. package/dist/auth-users-columns-JJ8ngvy5.js.map +0 -1
  43. package/dist/backup-service-czK-OAuG.js.map +0 -1
  44. package/dist/ensure-collection-policies-D5PtQLyR.js.map +0 -1
  45. package/dist/rls-enforcement-BDBfuTD4.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-users-columns-CgyPWQ18.js","names":[],"sources":["../../types/src/types/entities.ts","../../types/src/types/search.ts","../../types/src/types/relations.ts","../../common/src/util/common.ts","../../utils/src/strings.ts","../../../node_modules/.pnpm/object-hash@3.0.0/node_modules/object-hash/dist/object_hash.js","../../utils/src/objects.ts","../../utils/src/sha1.ts","../../utils/src/policy-names.ts","../../utils/src/plurals.ts","../../utils/src/names.ts","../../common/src/util/entities.ts","../../common/src/util/collections.ts","../../common/src/util/identity.ts","../../common/src/util/enums.ts","../../common/src/util/resolve-relation.ts","../../common/src/util/relations.ts","../../common/src/util/resolutions.ts","../../common/src/util/policy/sqlToPolicy.ts","../../common/src/util/policy/securityRuleToConditions.ts","../../common/src/util/policy/policyToPostgres.ts","../../common/src/util/builders.ts","../../common/src/util/auth-default-policies.ts","../../common/src/util/junction-policies.ts","../../../node_modules/.pnpm/json-logic-js@2.0.5/node_modules/json-logic-js/logic.js","../../common/src/util/conditions.ts","../../common/src/util/string-column-length.ts","../../../node_modules/.pnpm/fast-equals@6.0.2/node_modules/fast-equals/dist/es/index.mjs","../../common/src/data/resolveDataSource.ts","../../common/src/collections/CollectionRegistry.ts","../../common/src/collections/default-collections.ts","../../common/src/data/sort-dialect.ts","../../common/src/data/query_builder.ts","../../common/src/data/paginate.ts","../../common/src/data/filter-dialect.ts","../../common/src/data/buildRebaseData.ts","../src/schema/search-column.ts","../src/schema/auth-users-columns.ts"],"sourcesContent":["import type { SearchMatch } from \"./search\";\n/**\n * New or existing status\n * @group Models\n */\nexport type EntityStatus = \"new\" | \"existing\" | \"copy\";\n\n/**\n * Representation of a entity fetched from the driver\n * @group Models\n */\nexport interface Entity<M extends Record<string, unknown> = Record<string, unknown>> {\n\n /**\n * ID of the entity\n */\n id: string | number;\n\n /**\n * A string representing the path of the referenced document (relative\n * to the root of the database).\n */\n path: string;\n\n /**\n * Current values\n */\n values: EntityValues<M>;\n\n /**\n * Why this entity is in a search result: which declared fields matched, and\n * the text around each hit.\n *\n * Present only on rows returned by a search that asked for it. A sibling of\n * `values` rather than a key inside it, because it describes the *query*,\n * not the record — nothing in the collection declares it, no form edits it,\n * and a record fetched by id never has one.\n */\n searchMatches?: SearchMatch[];\n\n /**\n * Which driver this entity belongs to (e.g., 'postgres', 'firestore').\n * If not specified, the default driver is assumed.\n */\n driver?: string;\n\n /**\n * Which database within the driver (e.g., for Firestore multi-database).\n * If not specified, the default database of the driver is used.\n */\n databaseId?: string;\n}\n\n/**\n * This type represents a record of key value pairs as described in an\n * entity collection.\n * @group Models\n */\nexport type EntityValues<M extends Record<string, unknown>> = M;\n\n/**\n * Props for creating a EntityReference\n */\nexport interface EntityReferenceProps {\n /** ID of the entity */\n id: string;\n /** Path of the collection (relative to the root of the database) */\n path: string;\n /** Which driver (e.g., 'postgres', 'firestore'). Defaults to \"(default)\" */\n driver?: string;\n /** Which database within the driver. Defaults to \"(default)\" */\n databaseId?: string;\n}\n\n/**\n * Class used to create a reference to a entity in a different path.\n *\n * @example\n * // Simple reference (most common case - single driver, single db)\n * new EntityReference({ id: \"123\", path: \"users\" })\n *\n * // Reference to a different driver (e.g., Firestore)\n * new EntityReference({ id: \"123\", path: \"analytics\", driver: \"firestore\" })\n *\n * // Reference to a specific database within a driver\n * new EntityReference({ id: \"123\", path: \"orders\", driver: \"postgres\", databaseId: \"orders_db\" })\n */\nexport class EntityReference {\n\n readonly __type = \"reference\";\n /**\n * ID of the entity\n */\n readonly id: string;\n /**\n * A string representing the path of the referenced document (relative\n * to the root of the database).\n */\n readonly path: string;\n\n /**\n * Which driver (e.g., 'postgres', 'firestore').\n * Defaults to \"(default)\" if not specified.\n */\n readonly driver?: string;\n\n /**\n * Which database within the driver.\n * Defaults to \"(default)\" if not specified.\n */\n readonly databaseId?: string;\n\n /**\n * Create a reference to a entity.\n *\n * @example\n * // Simple reference (most common case)\n * new EntityReference({ id: \"123\", path: \"users\" })\n *\n * // With driver\n * new EntityReference({ id: \"123\", path: \"analytics\", driver: \"firestore\" })\n */\n constructor(props: EntityReferenceProps) {\n this.id = props.id;\n this.path = props.path;\n this.driver = props.driver;\n this.databaseId = props.databaseId;\n }\n\n get pathWithId() {\n return `${this.path}/${this.id}`;\n }\n\n /**\n * Get the full path including driver and database prefixes if specified.\n * For the common case (single driver, single db), this just returns pathWithId.\n */\n get fullPath() {\n const parts: string[] = [];\n\n // Add driver prefix if not default\n if (this.driver && this.driver !== \"(default)\") {\n parts.push(this.driver);\n }\n\n // Add database prefix if specified\n if (this.databaseId && this.databaseId !== \"(default)\") {\n parts.push(this.databaseId);\n }\n\n if (parts.length > 0) {\n return `${parts.join(\":\")}:::${this.path}/${this.id}`;\n }\n return this.pathWithId;\n }\n\n isEntityReference() {\n return true;\n }\n}\n\n/**\n * Class used to create a reference to a entity in a different path\n */\nexport class EntityRelation {\n\n readonly __type = \"relation\";\n /**\n * ID of the entity\n */\n readonly id: string | number;\n /**\n * A string representing the path of the referenced document (relative\n * to the root of the database).\n */\n readonly path: string;\n\n /**\n * Pre-fetched data payload to eliminate N+1 queries.\n * When present, clients can use this directly instead of fetching.\n */\n readonly data?: Record<string, unknown>;\n\n constructor(id: string | number, path: string, data?: Record<string, unknown>) {\n this.id = id;\n this.path = path;\n this.data = data;\n }\n\n get pathWithId() {\n return `${this.path}/${this.id}`;\n }\n\n isEntityReference() {\n return false;\n }\n\n isEntityRelation() {\n return true;\n }\n}\n\nexport class GeoPoint {\n\n /**\n * The latitude of this GeoPoint instance.\n */\n readonly latitude: number;\n /**\n * The longitude of this GeoPoint instance.\n */\n readonly longitude: number;\n\n constructor(latitude: number, longitude: number) {\n this.latitude = latitude;\n this.longitude = longitude;\n }\n}\n\nexport class Vector {\n readonly value: number[];\n\n constructor(value: number[]) {\n this.value = value;\n }\n}\n","/**\n * Opt-in full-text search configuration.\n *\n * ## Why this is opt-in\n *\n * Without a `search` block, `.search()` behaves exactly as it always has: an\n * `ILIKE '%term%'` OR-ed across the collection's top-level, non-enum `string`\n * properties. That default is unchanged and will stay unchanged — declaring\n * this block is the only way to get anything else.\n *\n * The default has three limits that no amount of tuning inside it can fix:\n * it cannot reach inside `map` (JSONB) or `array` properties, it has no notion\n * of relevance, and a leading `%` means it can never use an index. Collections\n * that outgrow those limits declare what they want searched; collections that\n * have not are left completely alone.\n *\n * ## What declaring it does\n *\n * One `tsvector` column, `GENERATED ALWAYS AS … STORED`, plus one GIN index on\n * it. Postgres recomputes the column on every write of a source field, so it\n * cannot drift from the row, and refuses any attempt to write it directly.\n * `.search()` then compiles to `@@ websearch_to_tsquery(…)` against that\n * column, which stems, drops stopwords, AND-es the terms, and ranks.\n *\n * These are stated consequences, not hidden ones: the column and the index\n * appear in generated DDL, in `schema.generated.ts`, and in `rebase db push`\n * output like any other declared object.\n *\n * @example\n * ```ts\n * const talents: PostgresCollectionConfig = {\n * slug: \"talents\",\n * table: \"talents\",\n * properties: { … },\n * search: {\n * language: \"spanish\",\n * unaccent: true,\n * fields: [\n * { path: \"full_name\", weight: \"A\" },\n * \"location\",\n * \"questionnaire.certifications\" // into the JSONB\n * ]\n * }\n * };\n * ```\n *\n * @group Search\n */\nexport interface SearchConfig {\n /**\n * The fields to index, in the author's own words. Nothing is inferred: a\n * field is searched if and only if it is named here.\n *\n * A bare string is shorthand for `{ path, weight: \"B\" }`.\n *\n * A path may address:\n * - a top-level `string` property — `\"full_name\"`\n * - a `string[]` property — `\"tags\"` (every element is indexed)\n * - a path into a `map` property — `\"questionnaire.certifications\"`,\n * which indexes every string found at or below that point, including\n * nested objects and arrays of strings. JSON *keys* are never indexed,\n * only values.\n *\n * A path that does not resolve to one of those is a boot-time error, not\n * a silent omission — a search field you believe is live and is not is the\n * failure this whole block exists to prevent.\n */\n fields: readonly (string | SearchField)[];\n\n /**\n * The Postgres text search configuration, which decides stemming and\n * stopwords. `\"spanish\"` stems `auditores` to `auditor` and drops `de`;\n * `\"simple\"` does neither.\n *\n * Defaults to `\"simple\"`, which is the only choice that is never wrong:\n * a stemmer applied to the wrong language silently mangles lexemes. Set it\n * to your content's language to get stemming.\n *\n * @default \"simple\"\n */\n language?: string;\n\n /**\n * Fold accents before indexing, so `auditoria` matches `auditoría`.\n *\n * This is not cosmetic in accented languages. Postgres stems the two\n * spellings to *different* lexemes — `to_tsvector('spanish', 'auditoría')`\n * yields `auditor` while `'auditoria'` yields `auditori` — so without this\n * a query typed without accents misses the rows that carry them, which is\n * most queries most users type.\n *\n * Requires the `unaccent` extension. Boot fails with an explicit message if\n * it is not installed and cannot be created, rather than quietly indexing\n * accented text as-is.\n *\n * @default false\n */\n unaccent?: boolean;\n\n /**\n * Name of the generated column holding the `tsvector`.\n *\n * Only change this if `search_vector` collides with a column you already\n * have. It is part of your schema once created: renaming it later is a\n * column drop and recreate, which rewrites the table.\n *\n * @default \"search_vector\"\n */\n column?: string;\n\n /**\n * Also match on trigram similarity, so near-misses and typos still rank —\n * `iso14000` reaching `ISO 14001`, which no amount of stemming will do\n * because they are simply different lexemes.\n *\n * Adds a second generated `text` column and a GIN trigram index alongside\n * the `tsvector`, and requires the `pg_trgm` extension. Costs write time\n * and disk; buys the single most common class of failed search.\n *\n * Also changes what `_score` means: the trigram similarity is added to\n * `ts_rank`. It has to be. A typo matches nothing on the exact path, so\n * every row this finds has a `ts_rank` of zero — ranking by that alone\n * would order the results arbitrarily, which is the failure `fuzzy` exists\n * to fix.\n *\n * @default false\n */\n fuzzy?: boolean;\n\n /**\n * Similarity floor for {@link SearchConfig.fuzzy}, between 0 and 1. A row\n * whose trigram similarity to the query falls below this never matches on\n * the fuzzy path (it can still match on the exact one).\n *\n * Lower admits more typos and more noise. Ignored unless `fuzzy` is set.\n *\n * @default 0.3\n */\n fuzzyThreshold?: number;\n}\n\n/**\n * One indexed field, with the weight it carries in the ranking.\n *\n * @group Search\n */\nexport interface SearchField {\n /**\n * Property name, or dotted path into a `map` property.\n * @see SearchConfig.fields\n */\n path: string;\n\n /**\n * Postgres weight class. `ts_rank` scores an `A` hit far above a `D` hit,\n * which is how a name outranks a passing mention in a long description.\n *\n * The four classes are Postgres's own and there are exactly four.\n *\n * @default \"B\"\n */\n weight?: SearchWeight;\n}\n\n/**\n * Postgres tsvector weight classes, strongest to weakest.\n *\n * @group Search\n */\nexport type SearchWeight = \"A\" | \"B\" | \"C\" | \"D\";\n\n/** The column name used when {@link SearchConfig.column} is not given. */\nexport const DEFAULT_SEARCH_COLUMN = \"search_vector\";\n\n/** The text search configuration used when {@link SearchConfig.language} is not given. */\nexport const DEFAULT_SEARCH_LANGUAGE = \"simple\";\n\n/** The weight a field carries when it does not name one. */\nexport const DEFAULT_SEARCH_WEIGHT: SearchWeight = \"B\";\n\n/** The similarity floor used when {@link SearchConfig.fuzzyThreshold} is not given. */\nexport const DEFAULT_FUZZY_THRESHOLD = 0.3;\n\n/**\n * Sort keys a query computes rather than reads from a column.\n *\n * `orderBy` is otherwise typed against the row — `keyof M` — which is exactly\n * right for a column and exactly wrong for relevance: `_score` is produced by\n * the query, so it appears in no generated row type and a project with a\n * generated SDK could not name it. The runtime accepted it, the docs told\n * people to use it, and the types rejected it.\n *\n * Kept as a named union rather than a loose `string` so the other half of the\n * guarantee survives: a typo'd column is still a compile error, and remains a\n * 400 at runtime rather than a silently unsorted list.\n *\n * `_distance` is deliberately not here. A vector search orders by distance on\n * its own and overrides `orderBy` outright, so naming it would imply a choice\n * the caller does not have.\n *\n * @group Search\n */\nexport type ComputedSortField = typeof RELEVANCE_SORT_FIELD;\n\n/**\n * The relevance sort key. Valid only on a collection that declares a\n * {@link SearchConfig} *and* on a query that carries a search string; anywhere\n * else it is an unknown field and the request is refused.\n */\nexport const RELEVANCE_SORT_FIELD = \"_score\";\n\n/**\n * One field that matched, and the text around the hit.\n *\n * Returned per row as `_matches` when a query asks for it — see the `explain`\n * option on `.search()`. Answers the question a ranked list otherwise leaves\n * open: *why is this row here?* A candidate surfacing for \"iso 14001\" because\n * of a certification is a different result from one surfacing because the\n * string appears in a paragraph about something else, and the score alone\n * cannot tell them apart.\n *\n * @group Search\n */\nexport interface SearchMatch {\n /**\n * The declared field path that matched, exactly as written in\n * {@link SearchConfig.fields} — e.g. `\"questionnaire.certifications\"`.\n * Map it to a label for display; the path is stable, a label is yours.\n */\n field: string;\n\n /**\n * The matching text, with each hit wrapped in `<mark>…</mark>`.\n *\n * Built by Postgres's `ts_headline` over the same normalized text that was\n * indexed. With {@link SearchConfig.unaccent} on that means the snippet\n * reads with accents folded — `Auditoria` rather than `Auditoría`. That is\n * deliberate: `ts_headline` over the *original* text cannot find a hit the\n * unaccented query produced, so it returns the text with nothing marked at\n * all. A readable snippet that highlights beats a prettier one that\n * silently does not.\n *\n * Contains markup by construction. Render it as HTML or strip the tags —\n * do not display it raw, and do not trust it as plain text.\n */\n snippet: string;\n}\n","import type { AnyCollectionConfig } from \"./collections\";\n\n/**\n * @group Models\n */\nexport type OnAction = \"cascade\" | \"restrict\" | \"no action\" | \"set null\" | \"set default\";\n\n/**\n * What kind of link a relation is.\n *\n * The discriminant. Every other field a relation carries belongs to exactly one\n * of these, which is the point: a relation used to be a single open interface\n * where `cardinality`, `direction`, `localKey`, `foreignKeyOnTarget`, `through`\n * and `joinPath` were all optional and any combination typechecked. Which link\n * you meant then had to be *inferred* from which fields you happened to set,\n * and the inference was ~200 lines that guessed, fell back on naming\n * conventions, and swallowed its own failures.\n *\n * Most of that guessing produced bugs rather than convenience. A `many`\n * relation carrying a `localKey` — a combination the old type permitted — made\n * the write path stamp the parent's own foreign key onto the child row. Under\n * these kinds that state cannot be written down.\n *\n * @group Models\n */\nexport type RelationKind = \"belongsTo\" | \"hasOne\" | \"hasMany\" | \"manyToMany\" | \"via\";\n\n/** Fields every relation carries, whatever its kind. @group Models */\nexport interface RelationBase {\n /**\n * The name this link is addressed by: the key in `include`, the tab in the\n * admin panel, and the path segment of a nested URL.\n *\n * Defaults to the declaring property's key, or to the target's slug for an\n * entry in `relations`.\n */\n relationName?: string;\n\n /** The collection on the other end. */\n target: () => AnyCollectionConfig;\n\n onUpdate?: OnAction;\n onDelete?: OnAction;\n\n /** Presentation overrides applied when this relation is rendered as a tab. */\n overrides?: Partial<AnyCollectionConfig>;\n\n validation?: {\n required?: boolean;\n };\n}\n\n/**\n * This collection holds the foreign key. One target row per source row.\n *\n * ```ts\n * author: { kind: \"belongsTo\", target: () => authors, localKey: \"author_id\" }\n * ```\n * @group Models\n */\nexport interface BelongsToRelation extends RelationBase {\n kind: \"belongsTo\";\n /**\n * Column on **this** collection's table holding the target's key.\n * Defaults to `<relationName>_id`.\n */\n localKey?: string;\n}\n\n/**\n * The target holds the foreign key, and at most one target row points back.\n *\n * ```ts\n * profile: { kind: \"hasOne\", target: () => profiles, foreignKeyOnTarget: \"user_id\" }\n * ```\n * @group Models\n */\nexport interface HasOneRelation extends RelationBase {\n kind: \"hasOne\";\n /**\n * Column on the **target's** table holding this collection's key.\n * Defaults to `<thisCollection>_id`.\n */\n foreignKeyOnTarget?: string;\n /**\n * Column on **this** collection's table whose value `foreignKeyOnTarget`\n * holds. Defaults to this collection's primary key.\n *\n * Set it when the two sides are joined on a natural key rather than on the\n * row id — an external identity id, a SKU, a tenant slug. See\n * {@link HasManyRelation.sourceKey}, which this mirrors.\n */\n sourceKey?: string;\n}\n\n/**\n * The target holds the foreign key, and many target rows point back. The\n * children belong to this parent alone — deleting one deletes a row.\n *\n * ```ts\n * posts: { kind: \"hasMany\", target: () => posts, foreignKeyOnTarget: \"author_id\" }\n * ```\n * @group Models\n */\nexport interface HasManyRelation extends RelationBase {\n kind: \"hasMany\";\n /**\n * Column on the **target's** table holding this collection's key.\n * Defaults to `<thisCollection>_id`.\n */\n foreignKeyOnTarget?: string;\n /**\n * Column on **this** collection's table whose value `foreignKeyOnTarget`\n * holds. Defaults to this collection's primary key.\n *\n * The mirror of `localKey` on {@link BelongsToRelation}: that one names the\n * column this side reads from, this one names the column the other side\n * points at. Without it the pair can only be joined on the row id, which\n * makes a natural-key link — `auth_user_id ↔ auth_user_id`, a SKU, a tenant\n * slug — inexpressible as `hasMany`, and it has to drop to the read-only\n * `via`.\n *\n * The column must be unique: the link addresses one source row per value,\n * and Postgres will not accept a foreign key against a non-unique column.\n *\n * ```ts\n * applications: {\n * kind: \"hasMany\",\n * target: () => talentApplications,\n * sourceKey: \"auth_user_id\",\n * foreignKeyOnTarget: \"auth_user_id\"\n * }\n * ```\n */\n sourceKey?: string;\n}\n\n/**\n * Both sides hold many, through a junction table. The target rows are shared,\n * so this collection owns the *link* and not the row: removing one removes a\n * junction row and leaves the target alone.\n *\n * Declared the same way from either side — there is no owning and inverse\n * version. Swap `sourceColumn` and `targetColumn` to describe the other\n * direction.\n *\n * ```ts\n * tags: { kind: \"manyToMany\", target: () => tags }\n * ```\n * @group Models\n */\nexport interface ManyToManyRelation extends RelationBase {\n kind: \"manyToMany\";\n /**\n * The junction table and its two key columns. Every part defaults: the\n * table to both table names sorted and joined, the columns to\n * `<collection>_id` and `<relationName>_id`.\n */\n through?: {\n table?: string;\n /** Junction column holding **this** collection's key. */\n sourceColumn?: string;\n /** Junction column holding the **target's** key. */\n targetColumn?: string;\n };\n}\n\n/**\n * An explicit chain of joins, for links the four shapes above cannot express:\n * multi-hop paths, composite keys, or a join whose condition is not a plain\n * foreign key.\n *\n * Read-only. Rebase will not infer how to write through an arbitrary join\n * chain, and guessing is what this type exists to stop.\n *\n * ```ts\n * permissions: {\n * kind: \"via\",\n * target: () => permissions,\n * cardinality: \"many\",\n * joinPath: [\n * { table: \"user_roles\", on: { from: \"id\", to: \"user_id\" } },\n * { table: \"role_permissions\", on: { from: \"role_id\", to: \"role_id\" } },\n * { table: \"permissions\", on: { from: \"permission_id\", to: \"id\" } }\n * ]\n * }\n * ```\n * @group Models\n */\nexport interface ViaRelation extends RelationBase {\n kind: \"via\";\n /** Whether the chain yields one row or many. Cannot be derived from a join chain. */\n cardinality: \"one\" | \"many\";\n joinPath: JoinStep[];\n}\n\n/**\n * A link from one collection to another, as authored.\n *\n * A closed union: pick the kind that describes the link and the type offers\n * exactly the fields that kind needs. See {@link ResolvedRelation} for the form\n * the runtime works with, which has every default filled in.\n *\n * @group Models\n */\nexport type Relation =\n | BelongsToRelation\n | HasOneRelation\n | HasManyRelation\n | ManyToManyRelation\n | ViaRelation;\n\n/**\n * A relation with every default filled in — the form the runtime works with.\n *\n * The authored {@link Relation} and this are deliberately different types.\n * They used to be one, which meant no reader could tell which fields had been\n * supplied and which had been guessed, and so every consumer re-derived what it\n * needed with its own chain of `if (through) … else if (localKey) …` fallbacks.\n * Those chains disagreed with each other; that disagreement is what produced\n * silently wrong reads and corrupt writes.\n *\n * Here each variant carries exactly its own fields, all required. A consumer\n * switches on `kind` and gets what it needs without a fallback, and the cases\n * it forgot are a compile error rather than a wrong answer at runtime.\n *\n * @group Models\n */\nexport type ResolvedRelation =\n | ResolvedBelongsTo\n | ResolvedHasOne\n | ResolvedHasMany\n | ResolvedManyToMany\n | ResolvedVia;\n\n/** Fields present on every resolved relation. @group Models */\nexport interface ResolvedRelationBase {\n /** Always set: defaulted during resolution if the author omitted it. */\n relationName: string;\n target: () => AnyCollectionConfig;\n /** The target's slug, resolved once so consumers need not call `target()`. */\n targetSlug: string;\n onUpdate?: OnAction;\n onDelete?: OnAction;\n overrides?: Partial<AnyCollectionConfig>;\n validation?: { required?: boolean };\n /**\n * Whether one row or many come back. Derived from `kind` — kept because it\n * is what most consumers actually branch on, and because `via` is the one\n * kind where it is authored rather than implied.\n */\n cardinality: \"one\" | \"many\";\n /**\n * Whether Rebase knows how to write through this link. False only for\n * {@link ResolvedVia}, whose join chain it will not invent a write for.\n */\n writable: boolean;\n /**\n * Whether the target rows are shared with other parents. True for\n * many-to-many and for multi-hop `via`: what the parent owns is the link,\n * so removing one must not delete the row.\n */\n shared: boolean;\n}\n\n/** @group Models */\nexport interface ResolvedBelongsTo extends ResolvedRelationBase {\n kind: \"belongsTo\";\n cardinality: \"one\";\n writable: true;\n shared: false;\n /** Column on this collection's table. */\n localKey: string;\n}\n\n/** @group Models */\nexport interface ResolvedHasOne extends ResolvedRelationBase {\n kind: \"hasOne\";\n cardinality: \"one\";\n writable: true;\n shared: false;\n /** Column on the target's table. */\n foreignKeyOnTarget: string;\n /** @see ResolvedHasMany.sourceKey */\n sourceKey?: string;\n}\n\n/** @group Models */\nexport interface ResolvedHasMany extends ResolvedRelationBase {\n kind: \"hasMany\";\n cardinality: \"many\";\n writable: true;\n shared: false;\n /** Column on the target's table. */\n foreignKeyOnTarget: string;\n /**\n * Column on the source's table that `foreignKeyOnTarget` points at, or\n * `undefined` for the source's primary key.\n *\n * The one optional field on a resolved relation, and deliberately so. Every\n * other default is filled in here because it can be: a table name and a\n * column name are derivable from the relation and its two endpoints alone.\n * The primary key is not — this driver resolves it from `isId`, then the\n * Drizzle schema, then a column named `id`, and the middle tier does not\n * exist at resolution time.\n *\n * So `undefined` is a sentinel with exactly one meaning, not a field a\n * consumer is invited to guess at. Read it through `sourceKeyField()`,\n * which is the only place that turns it into a column name.\n */\n sourceKey?: string;\n}\n\n/** @group Models */\nexport interface ResolvedManyToMany extends ResolvedRelationBase {\n kind: \"manyToMany\";\n cardinality: \"many\";\n writable: true;\n shared: true;\n through: {\n table: string;\n sourceColumn: string;\n targetColumn: string;\n };\n}\n\n/** @group Models */\nexport interface ResolvedVia extends ResolvedRelationBase {\n kind: \"via\";\n writable: false;\n joinPath: JoinStep[];\n}\n\n// ── Narrowing helpers ────────────────────────────────────────────────\n//\n// Consumers that only care about one axis — \"does this list many rows\",\n// \"is there a column on the target\" — should ask that question rather\n// than enumerate kinds, so adding a kind later does not silently skip them.\n\n/** Relations whose target row carries this collection's key. @group Models */\nexport type ResolvedForeignKeyOnTarget = ResolvedHasOne | ResolvedHasMany;\n\n/** @group Models */\nexport function hasForeignKeyOnTarget(relation: ResolvedRelation): relation is ResolvedForeignKeyOnTarget {\n return relation.kind === \"hasOne\" || relation.kind === \"hasMany\";\n}\n\n/** @group Models */\nexport function isManyToMany(relation: ResolvedRelation): relation is ResolvedManyToMany {\n return relation.kind === \"manyToMany\";\n}\n\n/** @group Models */\nexport function isToMany(relation: ResolvedRelation): boolean {\n return relation.cardinality === \"many\";\n}\n\n/**\n * Defines a single, explicit step in a multi-join path.\n *\n * Each step represents one JOIN operation in the sequence. The `from` columns\n * refer to the previous table in the chain (or the source table for the first step),\n * and the `to` columns refer to the current table being joined.\n *\n * @example Single column join:\n * ```typescript\n * {\n * table: \"authors\",\n * on: {\n * from: \"author_id\", // Column from previous table (e.g., posts.author_id)\n * to: \"id\" // Column from current table (authors.id)\n * }\n * }\n * ```\n *\n * @example Multi-column composite key join:\n * ```typescript\n * {\n * table: \"order_items\",\n * on: {\n * from: [\"order_id\", \"store_id\"], // Multiple columns from previous table\n * to: [\"order_id\", \"store_id\"] // Corresponding columns in current table\n * }\n * }\n * ```\n */\nexport interface JoinStep {\n /**\n * The database table name to join TO in this step.\n * This is the table you're joining into, not the table you're joining from.\n *\n * @example \"authors\", \"user_roles\", \"product_categories\"\n */\n table: string;\n\n /**\n * The join condition for this step. Defines how the previous table\n * connects to the current table.\n *\n * - `from`: Column name(s) on the PREVIOUS table in the join chain\n * - `to`: Column name(s) on the CURRENT table (specified in `table`)\n *\n * For the first step, `from` refers to the source collection's table.\n * For subsequent steps, `from` refers to the table from the previous step.\n *\n * Both `from` and `to` support:\n * - Single column: `\"user_id\"`\n * - Multiple columns: `[\"company_id\", \"region_id\"]` for composite keys\n *\n * When using arrays, both `from` and `to` must have the same length,\n * and columns are matched by position (index 0 with index 0, etc.).\n */\n on: {\n from: string | string[];\n to: string | string[];\n };\n}\n","export const DEFAULT_ONE_OF_TYPE = \"type\"\nexport const DEFAULT_ONE_OF_VALUE = \"value\"\n","const tokenizeRegex = /[A-Z]{2,}(?=[A-Z][a-z]|\\b)|[A-Z]?[a-z]+|[0-9]+(?:[a-z](?![a-z]))?|[A-Z]/g;\n\nexport const toKebabCase = (str?: string) => {\n if (!str || typeof str !== \"string\") return \"\";\n const regExpMatchArray = str.match(tokenizeRegex);\n if (!regExpMatchArray) return \"\";\n return regExpMatchArray\n .map(x => x.toLowerCase())\n .join(\"-\");\n};\n\nconst snakeCaseRegex = tokenizeRegex;\n\nexport const toSnakeCase = (str?: string) => {\n if (!str || typeof str !== \"string\") return \"\";\n const regExpMatchArray = str.match(snakeCaseRegex);\n if (!regExpMatchArray) return \"\";\n return regExpMatchArray\n .map(x => x.toLowerCase())\n .join(\"_\");\n};\n\nexport function camelCase(str: string): string {\n if (!str) return \"\";\n if (str.length === 1) return str.toLowerCase();\n\n // Split by hyphens, underscores, or spaces and filter out empty strings\n const parts = str.split(/[-_ ]+/).filter(Boolean);\n\n if (parts.length === 0) return \"\";\n\n // Start with first part in lowercase\n return parts[0].toLowerCase() +\n // Transform remaining parts to have first letter uppercase\n parts.slice(1)\n .map(part => part.charAt(0).toUpperCase() + part.substring(1).toLowerCase())\n .join(\"\");\n}\n\n/**\n * A random base-36 string of exactly `strLength` characters.\n *\n * Not `Math.random().toString(36).slice(2, 2 + strLength)`: that has no\n * guaranteed length. Base-36 of a double drops trailing zeros, so the source\n * string is short about once in 36 calls and the slice quietly returns fewer\n * characters than asked for — `randomString(10)` returning 9. These values\n * prefix uploaded filenames to keep them apart, so a short one is a likelier\n * collision, and it fails at the rate that makes a test look flaky.\n */\nexport function randomString(strLength = 5) {\n const alphabet = \"0123456789abcdefghijklmnopqrstuvwxyz\";\n let result = \"\";\n for (let i = 0; i < strLength; i++) {\n result += alphabet.charAt(Math.floor(Math.random() * alphabet.length));\n }\n return result;\n}\n\nexport function randomColor() {\n return Math.floor(Math.random() * 16777215).toString(16);\n}\n\nexport function slugify(text?: string, separator = \"_\", lowercase = true) {\n if (!text) return \"\";\n const from = \"ãàáäâẽèéëêìíïîõòóöôùúüûñç·/_,:;-\"\n const to = `aaaaaeeeeeiiiiooooouuuunc${separator}${separator}${separator}${separator}${separator}${separator}${separator}`;\n\n for (let i = 0, l = from.length; i < l; i++) {\n text = text.replace(new RegExp(from.charAt(i), \"g\"), to.charAt(i));\n }\n\n text = text\n .toString() // Cast to string\n .trim() // Remove whitespace from both sides of a string\n .replace(/^\\s+|\\s+$/g, \"\")\n .replace(/\\s+/g, separator) // Replace spaces with separator\n .replace(/&/g, separator) // Replace & with separator\n .replace(/[^\\w\\\\-]+/g, \"\") // Remove all non-word chars\n .replace(new RegExp(\"\\\\\" + separator + \"\\\\\" + separator + \"+\", \"g\"),\n separator); // Replace multiple separators with single one\n\n return lowercase\n ? text.toLowerCase() // Convert the string to lowercase letters\n : text;\n}\n\nexport function unslugify(slug?: string): string {\n if (!slug) return \"\";\n if (slug.includes(\"-\") || slug.includes(\"_\") || !slug.includes(\" \")) {\n const result = slug.replace(/[-_]/g, \" \");\n return result.replace(/\\w\\S*/g, function (txt) {\n return txt.charAt(0).toUpperCase() + txt.substring(1);\n }).trim();\n } else {\n return slug.trim();\n }\n}\n\nexport function prettifyIdentifier(input: string) {\n if (!input) return \"\";\n\n let text = input;\n\n // 1. Handle camelCase and Acronyms\n // Group 1 ($1 $2): Lowercase followed by Uppercase (e.g., imageURL -> image URL)\n // Group 2 ($3 $4): Uppercase followed by Uppercase+lowercase (e.g., XMLParser -> XML Parser)\n text = text.replace(/([a-z])([A-Z])|([A-Z])([A-Z][a-z])/g, \"$1$3 $2$4\");\n\n // 2. Replace hyphens/underscores with spaces\n text = text.replace(/[_-]+/g, \" \");\n\n // 3. Capitalize first letter of each word (Title Case)\n const s = text\n .trim()\n .replace(/\\b\\w/g, (char) => char.toUpperCase());\n return s;\n}\n","!function(e){var t;\"object\"==typeof exports?module.exports=e():\"function\"==typeof define&&define.amd?define(e):(\"undefined\"!=typeof window?t=window:\"undefined\"!=typeof global?t=global:\"undefined\"!=typeof self&&(t=self),t.objectHash=e())}(function(){return function r(o,i,u){function s(n,e){if(!i[n]){if(!o[n]){var t=\"function\"==typeof require&&require;if(!e&&t)return t(n,!0);if(a)return a(n,!0);throw new Error(\"Cannot find module '\"+n+\"'\")}e=i[n]={exports:{}};o[n][0].call(e.exports,function(e){var t=o[n][1][e];return s(t||e)},e,e.exports,r,o,i,u)}return i[n].exports}for(var a=\"function\"==typeof require&&require,e=0;e<u.length;e++)s(u[e]);return s}({1:[function(w,b,m){!function(e,n,s,c,d,h,p,g,y){\"use strict\";var r=w(\"crypto\");function t(e,t){t=u(e,t);var n;return void 0===(n=\"passthrough\"!==t.algorithm?r.createHash(t.algorithm):new l).write&&(n.write=n.update,n.end=n.update),f(t,n).dispatch(e),n.update||n.end(\"\"),n.digest?n.digest(\"buffer\"===t.encoding?void 0:t.encoding):(e=n.read(),\"buffer\"!==t.encoding?e.toString(t.encoding):e)}(m=b.exports=t).sha1=function(e){return t(e)},m.keys=function(e){return t(e,{excludeValues:!0,algorithm:\"sha1\",encoding:\"hex\"})},m.MD5=function(e){return t(e,{algorithm:\"md5\",encoding:\"hex\"})},m.keysMD5=function(e){return t(e,{algorithm:\"md5\",encoding:\"hex\",excludeValues:!0})};var o=r.getHashes?r.getHashes().slice():[\"sha1\",\"md5\"],i=(o.push(\"passthrough\"),[\"buffer\",\"hex\",\"binary\",\"base64\"]);function u(e,t){var n={};if(n.algorithm=(t=t||{}).algorithm||\"sha1\",n.encoding=t.encoding||\"hex\",n.excludeValues=!!t.excludeValues,n.algorithm=n.algorithm.toLowerCase(),n.encoding=n.encoding.toLowerCase(),n.ignoreUnknown=!0===t.ignoreUnknown,n.respectType=!1!==t.respectType,n.respectFunctionNames=!1!==t.respectFunctionNames,n.respectFunctionProperties=!1!==t.respectFunctionProperties,n.unorderedArrays=!0===t.unorderedArrays,n.unorderedSets=!1!==t.unorderedSets,n.unorderedObjects=!1!==t.unorderedObjects,n.replacer=t.replacer||void 0,n.excludeKeys=t.excludeKeys||void 0,void 0===e)throw new Error(\"Object argument required.\");for(var r=0;r<o.length;++r)o[r].toLowerCase()===n.algorithm.toLowerCase()&&(n.algorithm=o[r]);if(-1===o.indexOf(n.algorithm))throw new Error('Algorithm \"'+n.algorithm+'\" not supported. supported values: '+o.join(\", \"));if(-1===i.indexOf(n.encoding)&&\"passthrough\"!==n.algorithm)throw new Error('Encoding \"'+n.encoding+'\" not supported. supported values: '+i.join(\", \"));return n}function a(e){if(\"function\"==typeof e)return null!=/^function\\s+\\w*\\s*\\(\\s*\\)\\s*{\\s+\\[native code\\]\\s+}$/i.exec(Function.prototype.toString.call(e))}function f(o,t,i){i=i||[];function u(e){return t.update?t.update(e,\"utf8\"):t.write(e,\"utf8\")}return{dispatch:function(e){return this[\"_\"+(null===(e=o.replacer?o.replacer(e):e)?\"null\":typeof e)](e)},_object:function(t){var n,e=Object.prototype.toString.call(t),r=/\\[object (.*)\\]/i.exec(e);r=(r=r?r[1]:\"unknown:[\"+e+\"]\").toLowerCase();if(0<=(e=i.indexOf(t)))return this.dispatch(\"[CIRCULAR:\"+e+\"]\");if(i.push(t),void 0!==s&&s.isBuffer&&s.isBuffer(t))return u(\"buffer:\"),u(t);if(\"object\"===r||\"function\"===r||\"asyncfunction\"===r)return e=Object.keys(t),o.unorderedObjects&&(e=e.sort()),!1===o.respectType||a(t)||e.splice(0,0,\"prototype\",\"__proto__\",\"constructor\"),o.excludeKeys&&(e=e.filter(function(e){return!o.excludeKeys(e)})),u(\"object:\"+e.length+\":\"),n=this,e.forEach(function(e){n.dispatch(e),u(\":\"),o.excludeValues||n.dispatch(t[e]),u(\",\")});if(!this[\"_\"+r]){if(o.ignoreUnknown)return u(\"[\"+r+\"]\");throw new Error('Unknown object type \"'+r+'\"')}this[\"_\"+r](t)},_array:function(e,t){t=void 0!==t?t:!1!==o.unorderedArrays;var n=this;if(u(\"array:\"+e.length+\":\"),!t||e.length<=1)return e.forEach(function(e){return n.dispatch(e)});var r=[],t=e.map(function(e){var t=new l,n=i.slice();return f(o,t,n).dispatch(e),r=r.concat(n.slice(i.length)),t.read().toString()});return i=i.concat(r),t.sort(),this._array(t,!1)},_date:function(e){return u(\"date:\"+e.toJSON())},_symbol:function(e){return u(\"symbol:\"+e.toString())},_error:function(e){return u(\"error:\"+e.toString())},_boolean:function(e){return u(\"bool:\"+e.toString())},_string:function(e){u(\"string:\"+e.length+\":\"),u(e.toString())},_function:function(e){u(\"fn:\"),a(e)?this.dispatch(\"[native]\"):this.dispatch(e.toString()),!1!==o.respectFunctionNames&&this.dispatch(\"function-name:\"+String(e.name)),o.respectFunctionProperties&&this._object(e)},_number:function(e){return u(\"number:\"+e.toString())},_xml:function(e){return u(\"xml:\"+e.toString())},_null:function(){return u(\"Null\")},_undefined:function(){return u(\"Undefined\")},_regexp:function(e){return u(\"regex:\"+e.toString())},_uint8array:function(e){return u(\"uint8array:\"),this.dispatch(Array.prototype.slice.call(e))},_uint8clampedarray:function(e){return u(\"uint8clampedarray:\"),this.dispatch(Array.prototype.slice.call(e))},_int8array:function(e){return u(\"int8array:\"),this.dispatch(Array.prototype.slice.call(e))},_uint16array:function(e){return u(\"uint16array:\"),this.dispatch(Array.prototype.slice.call(e))},_int16array:function(e){return u(\"int16array:\"),this.dispatch(Array.prototype.slice.call(e))},_uint32array:function(e){return u(\"uint32array:\"),this.dispatch(Array.prototype.slice.call(e))},_int32array:function(e){return u(\"int32array:\"),this.dispatch(Array.prototype.slice.call(e))},_float32array:function(e){return u(\"float32array:\"),this.dispatch(Array.prototype.slice.call(e))},_float64array:function(e){return u(\"float64array:\"),this.dispatch(Array.prototype.slice.call(e))},_arraybuffer:function(e){return u(\"arraybuffer:\"),this.dispatch(new Uint8Array(e))},_url:function(e){return u(\"url:\"+e.toString())},_map:function(e){u(\"map:\");e=Array.from(e);return this._array(e,!1!==o.unorderedSets)},_set:function(e){u(\"set:\");e=Array.from(e);return this._array(e,!1!==o.unorderedSets)},_file:function(e){return u(\"file:\"),this.dispatch([e.name,e.size,e.type,e.lastModfied])},_blob:function(){if(o.ignoreUnknown)return u(\"[blob]\");throw Error('Hashing Blob objects is currently not supported\\n(see https://github.com/puleos/object-hash/issues/26)\\nUse \"options.replacer\" or \"options.ignoreUnknown\"\\n')},_domwindow:function(){return u(\"domwindow\")},_bigint:function(e){return u(\"bigint:\"+e.toString())},_process:function(){return u(\"process\")},_timer:function(){return u(\"timer\")},_pipe:function(){return u(\"pipe\")},_tcp:function(){return u(\"tcp\")},_udp:function(){return u(\"udp\")},_tty:function(){return u(\"tty\")},_statwatcher:function(){return u(\"statwatcher\")},_securecontext:function(){return u(\"securecontext\")},_connection:function(){return u(\"connection\")},_zlib:function(){return u(\"zlib\")},_context:function(){return u(\"context\")},_nodescript:function(){return u(\"nodescript\")},_httpparser:function(){return u(\"httpparser\")},_dataview:function(){return u(\"dataview\")},_signal:function(){return u(\"signal\")},_fsevent:function(){return u(\"fsevent\")},_tlswrap:function(){return u(\"tlswrap\")}}}function l(){return{buf:\"\",write:function(e){this.buf+=e},end:function(e){this.buf+=e},read:function(){return this.buf}}}m.writeToStream=function(e,t,n){return void 0===n&&(n=t,t={}),f(t=u(e,t),n).dispatch(e)}}.call(this,w(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},w(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/fake_9a5aa49d.js\",\"/\")},{buffer:3,crypto:5,lYpoI2:11}],2:[function(e,t,f){!function(e,t,n,r,o,i,u,s,a){!function(e){\"use strict\";var a=\"undefined\"!=typeof Uint8Array?Uint8Array:Array,t=\"+\".charCodeAt(0),n=\"/\".charCodeAt(0),r=\"0\".charCodeAt(0),o=\"a\".charCodeAt(0),i=\"A\".charCodeAt(0),u=\"-\".charCodeAt(0),s=\"_\".charCodeAt(0);function f(e){e=e.charCodeAt(0);return e===t||e===u?62:e===n||e===s?63:e<r?-1:e<r+10?e-r+26+26:e<i+26?e-i:e<o+26?e-o+26:void 0}e.toByteArray=function(e){var t,n;if(0<e.length%4)throw new Error(\"Invalid string. Length must be a multiple of 4\");var r=e.length,r=\"=\"===e.charAt(r-2)?2:\"=\"===e.charAt(r-1)?1:0,o=new a(3*e.length/4-r),i=0<r?e.length-4:e.length,u=0;function s(e){o[u++]=e}for(t=0;t<i;t+=4,0)s((16711680&(n=f(e.charAt(t))<<18|f(e.charAt(t+1))<<12|f(e.charAt(t+2))<<6|f(e.charAt(t+3))))>>16),s((65280&n)>>8),s(255&n);return 2==r?s(255&(n=f(e.charAt(t))<<2|f(e.charAt(t+1))>>4)):1==r&&(s((n=f(e.charAt(t))<<10|f(e.charAt(t+1))<<4|f(e.charAt(t+2))>>2)>>8&255),s(255&n)),o},e.fromByteArray=function(e){var t,n,r,o,i=e.length%3,u=\"\";function s(e){return\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\".charAt(e)}for(t=0,r=e.length-i;t<r;t+=3)n=(e[t]<<16)+(e[t+1]<<8)+e[t+2],u+=s((o=n)>>18&63)+s(o>>12&63)+s(o>>6&63)+s(63&o);switch(i){case 1:u=(u+=s((n=e[e.length-1])>>2))+s(n<<4&63)+\"==\";break;case 2:u=(u=(u+=s((n=(e[e.length-2]<<8)+e[e.length-1])>>10))+s(n>>4&63))+s(n<<2&63)+\"=\"}return u}}(void 0===f?this.base64js={}:f)}.call(this,e(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},e(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/base64-js/lib/b64.js\",\"/node_modules/gulp-browserify/node_modules/base64-js/lib\")},{buffer:3,lYpoI2:11}],3:[function(O,e,H){!function(e,n,f,r,h,p,g,y,w){var a=O(\"base64-js\"),i=O(\"ieee754\");function f(e,t,n){if(!(this instanceof f))return new f(e,t,n);var r,o,i,u,s=typeof e;if(\"base64\"===t&&\"string\"==s)for(e=(u=e).trim?u.trim():u.replace(/^\\s+|\\s+$/g,\"\");e.length%4!=0;)e+=\"=\";if(\"number\"==s)r=j(e);else if(\"string\"==s)r=f.byteLength(e,t);else{if(\"object\"!=s)throw new Error(\"First argument needs to be a number, array or string.\");r=j(e.length)}if(f._useTypedArrays?o=f._augment(new Uint8Array(r)):((o=this).length=r,o._isBuffer=!0),f._useTypedArrays&&\"number\"==typeof e.byteLength)o._set(e);else if(C(u=e)||f.isBuffer(u)||u&&\"object\"==typeof u&&\"number\"==typeof u.length)for(i=0;i<r;i++)f.isBuffer(e)?o[i]=e.readUInt8(i):o[i]=e[i];else if(\"string\"==s)o.write(e,0,t);else if(\"number\"==s&&!f._useTypedArrays&&!n)for(i=0;i<r;i++)o[i]=0;return o}function b(e,t,n,r){return f._charsWritten=c(function(e){for(var t=[],n=0;n<e.length;n++)t.push(255&e.charCodeAt(n));return t}(t),e,n,r)}function m(e,t,n,r){return f._charsWritten=c(function(e){for(var t,n,r=[],o=0;o<e.length;o++)n=e.charCodeAt(o),t=n>>8,n=n%256,r.push(n),r.push(t);return r}(t),e,n,r)}function v(e,t,n){var r=\"\";n=Math.min(e.length,n);for(var o=t;o<n;o++)r+=String.fromCharCode(e[o]);return r}function o(e,t,n,r){r||(d(\"boolean\"==typeof n,\"missing or invalid endian\"),d(null!=t,\"missing offset\"),d(t+1<e.length,\"Trying to read beyond buffer length\"));var o,r=e.length;if(!(r<=t))return n?(o=e[t],t+1<r&&(o|=e[t+1]<<8)):(o=e[t]<<8,t+1<r&&(o|=e[t+1])),o}function u(e,t,n,r){r||(d(\"boolean\"==typeof n,\"missing or invalid endian\"),d(null!=t,\"missing offset\"),d(t+3<e.length,\"Trying to read beyond buffer length\"));var o,r=e.length;if(!(r<=t))return n?(t+2<r&&(o=e[t+2]<<16),t+1<r&&(o|=e[t+1]<<8),o|=e[t],t+3<r&&(o+=e[t+3]<<24>>>0)):(t+1<r&&(o=e[t+1]<<16),t+2<r&&(o|=e[t+2]<<8),t+3<r&&(o|=e[t+3]),o+=e[t]<<24>>>0),o}function _(e,t,n,r){if(r||(d(\"boolean\"==typeof n,\"missing or invalid endian\"),d(null!=t,\"missing offset\"),d(t+1<e.length,\"Trying to read beyond buffer length\")),!(e.length<=t))return r=o(e,t,n,!0),32768&r?-1*(65535-r+1):r}function E(e,t,n,r){if(r||(d(\"boolean\"==typeof n,\"missing or invalid endian\"),d(null!=t,\"missing offset\"),d(t+3<e.length,\"Trying to read beyond buffer length\")),!(e.length<=t))return r=u(e,t,n,!0),2147483648&r?-1*(4294967295-r+1):r}function I(e,t,n,r){return r||(d(\"boolean\"==typeof n,\"missing or invalid endian\"),d(t+3<e.length,\"Trying to read beyond buffer length\")),i.read(e,t,n,23,4)}function A(e,t,n,r){return r||(d(\"boolean\"==typeof n,\"missing or invalid endian\"),d(t+7<e.length,\"Trying to read beyond buffer length\")),i.read(e,t,n,52,8)}function s(e,t,n,r,o){o||(d(null!=t,\"missing value\"),d(\"boolean\"==typeof r,\"missing or invalid endian\"),d(null!=n,\"missing offset\"),d(n+1<e.length,\"trying to write beyond buffer length\"),Y(t,65535));o=e.length;if(!(o<=n))for(var i=0,u=Math.min(o-n,2);i<u;i++)e[n+i]=(t&255<<8*(r?i:1-i))>>>8*(r?i:1-i)}function l(e,t,n,r,o){o||(d(null!=t,\"missing value\"),d(\"boolean\"==typeof r,\"missing or invalid endian\"),d(null!=n,\"missing offset\"),d(n+3<e.length,\"trying to write beyond buffer length\"),Y(t,4294967295));o=e.length;if(!(o<=n))for(var i=0,u=Math.min(o-n,4);i<u;i++)e[n+i]=t>>>8*(r?i:3-i)&255}function B(e,t,n,r,o){o||(d(null!=t,\"missing value\"),d(\"boolean\"==typeof r,\"missing or invalid endian\"),d(null!=n,\"missing offset\"),d(n+1<e.length,\"Trying to write beyond buffer length\"),F(t,32767,-32768)),e.length<=n||s(e,0<=t?t:65535+t+1,n,r,o)}function L(e,t,n,r,o){o||(d(null!=t,\"missing value\"),d(\"boolean\"==typeof r,\"missing or invalid endian\"),d(null!=n,\"missing offset\"),d(n+3<e.length,\"Trying to write beyond buffer length\"),F(t,2147483647,-2147483648)),e.length<=n||l(e,0<=t?t:4294967295+t+1,n,r,o)}function U(e,t,n,r,o){o||(d(null!=t,\"missing value\"),d(\"boolean\"==typeof r,\"missing or invalid endian\"),d(null!=n,\"missing offset\"),d(n+3<e.length,\"Trying to write beyond buffer length\"),D(t,34028234663852886e22,-34028234663852886e22)),e.length<=n||i.write(e,t,n,r,23,4)}function x(e,t,n,r,o){o||(d(null!=t,\"missing value\"),d(\"boolean\"==typeof r,\"missing or invalid endian\"),d(null!=n,\"missing offset\"),d(n+7<e.length,\"Trying to write beyond buffer length\"),D(t,17976931348623157e292,-17976931348623157e292)),e.length<=n||i.write(e,t,n,r,52,8)}H.Buffer=f,H.SlowBuffer=f,H.INSPECT_MAX_BYTES=50,f.poolSize=8192,f._useTypedArrays=function(){try{var e=new ArrayBuffer(0),t=new Uint8Array(e);return t.foo=function(){return 42},42===t.foo()&&\"function\"==typeof t.subarray}catch(e){return!1}}(),f.isEncoding=function(e){switch(String(e).toLowerCase()){case\"hex\":case\"utf8\":case\"utf-8\":case\"ascii\":case\"binary\":case\"base64\":case\"raw\":case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":return!0;default:return!1}},f.isBuffer=function(e){return!(null==e||!e._isBuffer)},f.byteLength=function(e,t){var n;switch(e+=\"\",t||\"utf8\"){case\"hex\":n=e.length/2;break;case\"utf8\":case\"utf-8\":n=T(e).length;break;case\"ascii\":case\"binary\":case\"raw\":n=e.length;break;case\"base64\":n=M(e).length;break;case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":n=2*e.length;break;default:throw new Error(\"Unknown encoding\")}return n},f.concat=function(e,t){if(d(C(e),\"Usage: Buffer.concat(list, [totalLength])\\nlist should be an Array.\"),0===e.length)return new f(0);if(1===e.length)return e[0];if(\"number\"!=typeof t)for(o=t=0;o<e.length;o++)t+=e[o].length;for(var n=new f(t),r=0,o=0;o<e.length;o++){var i=e[o];i.copy(n,r),r+=i.length}return n},f.prototype.write=function(e,t,n,r){isFinite(t)?isFinite(n)||(r=n,n=void 0):(a=r,r=t,t=n,n=a),t=Number(t)||0;var o,i,u,s,a=this.length-t;switch((!n||a<(n=Number(n)))&&(n=a),r=String(r||\"utf8\").toLowerCase()){case\"hex\":o=function(e,t,n,r){n=Number(n)||0;var o=e.length-n;(!r||o<(r=Number(r)))&&(r=o),d((o=t.length)%2==0,\"Invalid hex string\"),o/2<r&&(r=o/2);for(var i=0;i<r;i++){var u=parseInt(t.substr(2*i,2),16);d(!isNaN(u),\"Invalid hex string\"),e[n+i]=u}return f._charsWritten=2*i,i}(this,e,t,n);break;case\"utf8\":case\"utf-8\":i=this,u=t,s=n,o=f._charsWritten=c(T(e),i,u,s);break;case\"ascii\":case\"binary\":o=b(this,e,t,n);break;case\"base64\":i=this,u=t,s=n,o=f._charsWritten=c(M(e),i,u,s);break;case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":o=m(this,e,t,n);break;default:throw new Error(\"Unknown encoding\")}return o},f.prototype.toString=function(e,t,n){var r,o,i,u,s=this;if(e=String(e||\"utf8\").toLowerCase(),t=Number(t)||0,(n=void 0!==n?Number(n):s.length)===t)return\"\";switch(e){case\"hex\":r=function(e,t,n){var r=e.length;(!t||t<0)&&(t=0);(!n||n<0||r<n)&&(n=r);for(var o=\"\",i=t;i<n;i++)o+=k(e[i]);return o}(s,t,n);break;case\"utf8\":case\"utf-8\":r=function(e,t,n){var r=\"\",o=\"\";n=Math.min(e.length,n);for(var i=t;i<n;i++)e[i]<=127?(r+=N(o)+String.fromCharCode(e[i]),o=\"\"):o+=\"%\"+e[i].toString(16);return r+N(o)}(s,t,n);break;case\"ascii\":case\"binary\":r=v(s,t,n);break;case\"base64\":o=s,u=n,r=0===(i=t)&&u===o.length?a.fromByteArray(o):a.fromByteArray(o.slice(i,u));break;case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":r=function(e,t,n){for(var r=e.slice(t,n),o=\"\",i=0;i<r.length;i+=2)o+=String.fromCharCode(r[i]+256*r[i+1]);return o}(s,t,n);break;default:throw new Error(\"Unknown encoding\")}return r},f.prototype.toJSON=function(){return{type:\"Buffer\",data:Array.prototype.slice.call(this._arr||this,0)}},f.prototype.copy=function(e,t,n,r){if(t=t||0,(r=r||0===r?r:this.length)!==(n=n||0)&&0!==e.length&&0!==this.length){d(n<=r,\"sourceEnd < sourceStart\"),d(0<=t&&t<e.length,\"targetStart out of bounds\"),d(0<=n&&n<this.length,\"sourceStart out of bounds\"),d(0<=r&&r<=this.length,\"sourceEnd out of bounds\"),r>this.length&&(r=this.length);var o=(r=e.length-t<r-n?e.length-t+n:r)-n;if(o<100||!f._useTypedArrays)for(var i=0;i<o;i++)e[i+t]=this[i+n];else e._set(this.subarray(n,n+o),t)}},f.prototype.slice=function(e,t){var n=this.length;if(e=S(e,n,0),t=S(t,n,n),f._useTypedArrays)return f._augment(this.subarray(e,t));for(var r=t-e,o=new f(r,void 0,!0),i=0;i<r;i++)o[i]=this[i+e];return o},f.prototype.get=function(e){return console.log(\".get() is deprecated. Access using array indexes instead.\"),this.readUInt8(e)},f.prototype.set=function(e,t){return console.log(\".set() is deprecated. Access using array indexes instead.\"),this.writeUInt8(e,t)},f.prototype.readUInt8=function(e,t){if(t||(d(null!=e,\"missing offset\"),d(e<this.length,\"Trying to read beyond buffer length\")),!(e>=this.length))return this[e]},f.prototype.readUInt16LE=function(e,t){return o(this,e,!0,t)},f.prototype.readUInt16BE=function(e,t){return o(this,e,!1,t)},f.prototype.readUInt32LE=function(e,t){return u(this,e,!0,t)},f.prototype.readUInt32BE=function(e,t){return u(this,e,!1,t)},f.prototype.readInt8=function(e,t){if(t||(d(null!=e,\"missing offset\"),d(e<this.length,\"Trying to read beyond buffer length\")),!(e>=this.length))return 128&this[e]?-1*(255-this[e]+1):this[e]},f.prototype.readInt16LE=function(e,t){return _(this,e,!0,t)},f.prototype.readInt16BE=function(e,t){return _(this,e,!1,t)},f.prototype.readInt32LE=function(e,t){return E(this,e,!0,t)},f.prototype.readInt32BE=function(e,t){return E(this,e,!1,t)},f.prototype.readFloatLE=function(e,t){return I(this,e,!0,t)},f.prototype.readFloatBE=function(e,t){return I(this,e,!1,t)},f.prototype.readDoubleLE=function(e,t){return A(this,e,!0,t)},f.prototype.readDoubleBE=function(e,t){return A(this,e,!1,t)},f.prototype.writeUInt8=function(e,t,n){n||(d(null!=e,\"missing value\"),d(null!=t,\"missing offset\"),d(t<this.length,\"trying to write beyond buffer length\"),Y(e,255)),t>=this.length||(this[t]=e)},f.prototype.writeUInt16LE=function(e,t,n){s(this,e,t,!0,n)},f.prototype.writeUInt16BE=function(e,t,n){s(this,e,t,!1,n)},f.prototype.writeUInt32LE=function(e,t,n){l(this,e,t,!0,n)},f.prototype.writeUInt32BE=function(e,t,n){l(this,e,t,!1,n)},f.prototype.writeInt8=function(e,t,n){n||(d(null!=e,\"missing value\"),d(null!=t,\"missing offset\"),d(t<this.length,\"Trying to write beyond buffer length\"),F(e,127,-128)),t>=this.length||(0<=e?this.writeUInt8(e,t,n):this.writeUInt8(255+e+1,t,n))},f.prototype.writeInt16LE=function(e,t,n){B(this,e,t,!0,n)},f.prototype.writeInt16BE=function(e,t,n){B(this,e,t,!1,n)},f.prototype.writeInt32LE=function(e,t,n){L(this,e,t,!0,n)},f.prototype.writeInt32BE=function(e,t,n){L(this,e,t,!1,n)},f.prototype.writeFloatLE=function(e,t,n){U(this,e,t,!0,n)},f.prototype.writeFloatBE=function(e,t,n){U(this,e,t,!1,n)},f.prototype.writeDoubleLE=function(e,t,n){x(this,e,t,!0,n)},f.prototype.writeDoubleBE=function(e,t,n){x(this,e,t,!1,n)},f.prototype.fill=function(e,t,n){if(t=t||0,n=n||this.length,d(\"number\"==typeof(e=\"string\"==typeof(e=e||0)?e.charCodeAt(0):e)&&!isNaN(e),\"value is not a number\"),d(t<=n,\"end < start\"),n!==t&&0!==this.length){d(0<=t&&t<this.length,\"start out of bounds\"),d(0<=n&&n<=this.length,\"end out of bounds\");for(var r=t;r<n;r++)this[r]=e}},f.prototype.inspect=function(){for(var e=[],t=this.length,n=0;n<t;n++)if(e[n]=k(this[n]),n===H.INSPECT_MAX_BYTES){e[n+1]=\"...\";break}return\"<Buffer \"+e.join(\" \")+\">\"},f.prototype.toArrayBuffer=function(){if(\"undefined\"==typeof Uint8Array)throw new Error(\"Buffer.toArrayBuffer not supported in this browser\");if(f._useTypedArrays)return new f(this).buffer;for(var e=new Uint8Array(this.length),t=0,n=e.length;t<n;t+=1)e[t]=this[t];return e.buffer};var t=f.prototype;function S(e,t,n){return\"number\"!=typeof e?n:t<=(e=~~e)?t:0<=e||0<=(e+=t)?e:0}function j(e){return(e=~~Math.ceil(+e))<0?0:e}function C(e){return(Array.isArray||function(e){return\"[object Array]\"===Object.prototype.toString.call(e)})(e)}function k(e){return e<16?\"0\"+e.toString(16):e.toString(16)}function T(e){for(var t=[],n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<=127)t.push(e.charCodeAt(n));else for(var o=n,i=(55296<=r&&r<=57343&&n++,encodeURIComponent(e.slice(o,n+1)).substr(1).split(\"%\")),u=0;u<i.length;u++)t.push(parseInt(i[u],16))}return t}function M(e){return a.toByteArray(e)}function c(e,t,n,r){for(var o=0;o<r&&!(o+n>=t.length||o>=e.length);o++)t[o+n]=e[o];return o}function N(e){try{return decodeURIComponent(e)}catch(e){return String.fromCharCode(65533)}}function Y(e,t){d(\"number\"==typeof e,\"cannot write a non-number as a number\"),d(0<=e,\"specified a negative value for writing an unsigned value\"),d(e<=t,\"value is larger than maximum value for type\"),d(Math.floor(e)===e,\"value has a fractional component\")}function F(e,t,n){d(\"number\"==typeof e,\"cannot write a non-number as a number\"),d(e<=t,\"value larger than maximum allowed value\"),d(n<=e,\"value smaller than minimum allowed value\"),d(Math.floor(e)===e,\"value has a fractional component\")}function D(e,t,n){d(\"number\"==typeof e,\"cannot write a non-number as a number\"),d(e<=t,\"value larger than maximum allowed value\"),d(n<=e,\"value smaller than minimum allowed value\")}function d(e,t){if(!e)throw new Error(t||\"Failed assertion\")}f._augment=function(e){return e._isBuffer=!0,e._get=e.get,e._set=e.set,e.get=t.get,e.set=t.set,e.write=t.write,e.toString=t.toString,e.toLocaleString=t.toString,e.toJSON=t.toJSON,e.copy=t.copy,e.slice=t.slice,e.readUInt8=t.readUInt8,e.readUInt16LE=t.readUInt16LE,e.readUInt16BE=t.readUInt16BE,e.readUInt32LE=t.readUInt32LE,e.readUInt32BE=t.readUInt32BE,e.readInt8=t.readInt8,e.readInt16LE=t.readInt16LE,e.readInt16BE=t.readInt16BE,e.readInt32LE=t.readInt32LE,e.readInt32BE=t.readInt32BE,e.readFloatLE=t.readFloatLE,e.readFloatBE=t.readFloatBE,e.readDoubleLE=t.readDoubleLE,e.readDoubleBE=t.readDoubleBE,e.writeUInt8=t.writeUInt8,e.writeUInt16LE=t.writeUInt16LE,e.writeUInt16BE=t.writeUInt16BE,e.writeUInt32LE=t.writeUInt32LE,e.writeUInt32BE=t.writeUInt32BE,e.writeInt8=t.writeInt8,e.writeInt16LE=t.writeInt16LE,e.writeInt16BE=t.writeInt16BE,e.writeInt32LE=t.writeInt32LE,e.writeInt32BE=t.writeInt32BE,e.writeFloatLE=t.writeFloatLE,e.writeFloatBE=t.writeFloatBE,e.writeDoubleLE=t.writeDoubleLE,e.writeDoubleBE=t.writeDoubleBE,e.fill=t.fill,e.inspect=t.inspect,e.toArrayBuffer=t.toArrayBuffer,e}}.call(this,O(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},O(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/buffer/index.js\",\"/node_modules/gulp-browserify/node_modules/buffer\")},{\"base64-js\":2,buffer:3,ieee754:10,lYpoI2:11}],4:[function(c,d,e){!function(e,t,a,n,r,o,i,u,s){var a=c(\"buffer\").Buffer,f=4,l=new a(f);l.fill(0);d.exports={hash:function(e,t,n,r){for(var o=t(function(e,t){e.length%f!=0&&(n=e.length+(f-e.length%f),e=a.concat([e,l],n));for(var n,r=[],o=t?e.readInt32BE:e.readInt32LE,i=0;i<e.length;i+=f)r.push(o.call(e,i));return r}(e=a.isBuffer(e)?e:new a(e),r),8*e.length),t=r,i=new a(n),u=t?i.writeInt32BE:i.writeInt32LE,s=0;s<o.length;s++)u.call(i,o[s],4*s,!0);return i}}}.call(this,c(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},c(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/crypto-browserify/helpers.js\",\"/node_modules/gulp-browserify/node_modules/crypto-browserify\")},{buffer:3,lYpoI2:11}],5:[function(v,e,_){!function(l,c,u,d,h,p,g,y,w){var u=v(\"buffer\").Buffer,e=v(\"./sha\"),t=v(\"./sha256\"),n=v(\"./rng\"),b={sha1:e,sha256:t,md5:v(\"./md5\")},s=64,a=new u(s);function r(e,n){var r=b[e=e||\"sha1\"],o=[];return r||i(\"algorithm:\",e,\"is not yet supported\"),{update:function(e){return u.isBuffer(e)||(e=new u(e)),o.push(e),e.length,this},digest:function(e){var t=u.concat(o),t=n?function(e,t,n){u.isBuffer(t)||(t=new u(t)),u.isBuffer(n)||(n=new u(n)),t.length>s?t=e(t):t.length<s&&(t=u.concat([t,a],s));for(var r=new u(s),o=new u(s),i=0;i<s;i++)r[i]=54^t[i],o[i]=92^t[i];return n=e(u.concat([r,n])),e(u.concat([o,n]))}(r,n,t):r(t);return o=null,e?t.toString(e):t}}}function i(){var e=[].slice.call(arguments).join(\" \");throw new Error([e,\"we accept pull requests\",\"http://github.com/dominictarr/crypto-browserify\"].join(\"\\n\"))}a.fill(0),_.createHash=function(e){return r(e)},_.createHmac=r,_.randomBytes=function(e,t){if(!t||!t.call)return new u(n(e));try{t.call(this,void 0,new u(n(e)))}catch(e){t(e)}};var o,f=[\"createCredentials\",\"createCipher\",\"createCipheriv\",\"createDecipher\",\"createDecipheriv\",\"createSign\",\"createVerify\",\"createDiffieHellman\",\"pbkdf2\"],m=function(e){_[e]=function(){i(\"sorry,\",e,\"is not implemented yet\")}};for(o in f)m(f[o],o)}.call(this,v(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},v(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/crypto-browserify/index.js\",\"/node_modules/gulp-browserify/node_modules/crypto-browserify\")},{\"./md5\":6,\"./rng\":7,\"./sha\":8,\"./sha256\":9,buffer:3,lYpoI2:11}],6:[function(w,b,e){!function(e,r,o,i,u,a,f,l,y){var t=w(\"./helpers\");function n(e,t){e[t>>5]|=128<<t%32,e[14+(t+64>>>9<<4)]=t;for(var n=1732584193,r=-271733879,o=-1732584194,i=271733878,u=0;u<e.length;u+=16){var s=n,a=r,f=o,l=i,n=c(n,r,o,i,e[u+0],7,-680876936),i=c(i,n,r,o,e[u+1],12,-389564586),o=c(o,i,n,r,e[u+2],17,606105819),r=c(r,o,i,n,e[u+3],22,-1044525330);n=c(n,r,o,i,e[u+4],7,-176418897),i=c(i,n,r,o,e[u+5],12,1200080426),o=c(o,i,n,r,e[u+6],17,-1473231341),r=c(r,o,i,n,e[u+7],22,-45705983),n=c(n,r,o,i,e[u+8],7,1770035416),i=c(i,n,r,o,e[u+9],12,-1958414417),o=c(o,i,n,r,e[u+10],17,-42063),r=c(r,o,i,n,e[u+11],22,-1990404162),n=c(n,r,o,i,e[u+12],7,1804603682),i=c(i,n,r,o,e[u+13],12,-40341101),o=c(o,i,n,r,e[u+14],17,-1502002290),n=d(n,r=c(r,o,i,n,e[u+15],22,1236535329),o,i,e[u+1],5,-165796510),i=d(i,n,r,o,e[u+6],9,-1069501632),o=d(o,i,n,r,e[u+11],14,643717713),r=d(r,o,i,n,e[u+0],20,-373897302),n=d(n,r,o,i,e[u+5],5,-701558691),i=d(i,n,r,o,e[u+10],9,38016083),o=d(o,i,n,r,e[u+15],14,-660478335),r=d(r,o,i,n,e[u+4],20,-405537848),n=d(n,r,o,i,e[u+9],5,568446438),i=d(i,n,r,o,e[u+14],9,-1019803690),o=d(o,i,n,r,e[u+3],14,-187363961),r=d(r,o,i,n,e[u+8],20,1163531501),n=d(n,r,o,i,e[u+13],5,-1444681467),i=d(i,n,r,o,e[u+2],9,-51403784),o=d(o,i,n,r,e[u+7],14,1735328473),n=h(n,r=d(r,o,i,n,e[u+12],20,-1926607734),o,i,e[u+5],4,-378558),i=h(i,n,r,o,e[u+8],11,-2022574463),o=h(o,i,n,r,e[u+11],16,1839030562),r=h(r,o,i,n,e[u+14],23,-35309556),n=h(n,r,o,i,e[u+1],4,-1530992060),i=h(i,n,r,o,e[u+4],11,1272893353),o=h(o,i,n,r,e[u+7],16,-155497632),r=h(r,o,i,n,e[u+10],23,-1094730640),n=h(n,r,o,i,e[u+13],4,681279174),i=h(i,n,r,o,e[u+0],11,-358537222),o=h(o,i,n,r,e[u+3],16,-722521979),r=h(r,o,i,n,e[u+6],23,76029189),n=h(n,r,o,i,e[u+9],4,-640364487),i=h(i,n,r,o,e[u+12],11,-421815835),o=h(o,i,n,r,e[u+15],16,530742520),n=p(n,r=h(r,o,i,n,e[u+2],23,-995338651),o,i,e[u+0],6,-198630844),i=p(i,n,r,o,e[u+7],10,1126891415),o=p(o,i,n,r,e[u+14],15,-1416354905),r=p(r,o,i,n,e[u+5],21,-57434055),n=p(n,r,o,i,e[u+12],6,1700485571),i=p(i,n,r,o,e[u+3],10,-1894986606),o=p(o,i,n,r,e[u+10],15,-1051523),r=p(r,o,i,n,e[u+1],21,-2054922799),n=p(n,r,o,i,e[u+8],6,1873313359),i=p(i,n,r,o,e[u+15],10,-30611744),o=p(o,i,n,r,e[u+6],15,-1560198380),r=p(r,o,i,n,e[u+13],21,1309151649),n=p(n,r,o,i,e[u+4],6,-145523070),i=p(i,n,r,o,e[u+11],10,-1120210379),o=p(o,i,n,r,e[u+2],15,718787259),r=p(r,o,i,n,e[u+9],21,-343485551),n=g(n,s),r=g(r,a),o=g(o,f),i=g(i,l)}return Array(n,r,o,i)}function s(e,t,n,r,o,i){return g((t=g(g(t,e),g(r,i)))<<o|t>>>32-o,n)}function c(e,t,n,r,o,i,u){return s(t&n|~t&r,e,t,o,i,u)}function d(e,t,n,r,o,i,u){return s(t&r|n&~r,e,t,o,i,u)}function h(e,t,n,r,o,i,u){return s(t^n^r,e,t,o,i,u)}function p(e,t,n,r,o,i,u){return s(n^(t|~r),e,t,o,i,u)}function g(e,t){var n=(65535&e)+(65535&t);return(e>>16)+(t>>16)+(n>>16)<<16|65535&n}b.exports=function(e){return t.hash(e,n,16)}}.call(this,w(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},w(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/crypto-browserify/md5.js\",\"/node_modules/gulp-browserify/node_modules/crypto-browserify\")},{\"./helpers\":4,buffer:3,lYpoI2:11}],7:[function(e,l,t){!function(e,t,n,r,o,i,u,s,f){var a;l.exports=a||function(e){for(var t,n=new Array(e),r=0;r<e;r++)0==(3&r)&&(t=4294967296*Math.random()),n[r]=t>>>((3&r)<<3)&255;return n}}.call(this,e(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},e(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/crypto-browserify/rng.js\",\"/node_modules/gulp-browserify/node_modules/crypto-browserify\")},{buffer:3,lYpoI2:11}],8:[function(c,d,e){!function(e,t,n,r,o,s,a,f,l){var i=c(\"./helpers\");function u(l,c){l[c>>5]|=128<<24-c%32,l[15+(c+64>>9<<4)]=c;for(var e,t,n,r=Array(80),o=1732584193,i=-271733879,u=-1732584194,s=271733878,d=-1009589776,h=0;h<l.length;h+=16){for(var p=o,g=i,y=u,w=s,b=d,a=0;a<80;a++){r[a]=a<16?l[h+a]:v(r[a-3]^r[a-8]^r[a-14]^r[a-16],1);var f=m(m(v(o,5),(f=i,t=u,n=s,(e=a)<20?f&t|~f&n:!(e<40)&&e<60?f&t|f&n|t&n:f^t^n)),m(m(d,r[a]),(e=a)<20?1518500249:e<40?1859775393:e<60?-1894007588:-899497514)),d=s,s=u,u=v(i,30),i=o,o=f}o=m(o,p),i=m(i,g),u=m(u,y),s=m(s,w),d=m(d,b)}return Array(o,i,u,s,d)}function m(e,t){var n=(65535&e)+(65535&t);return(e>>16)+(t>>16)+(n>>16)<<16|65535&n}function v(e,t){return e<<t|e>>>32-t}d.exports=function(e){return i.hash(e,u,20,!0)}}.call(this,c(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},c(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/crypto-browserify/sha.js\",\"/node_modules/gulp-browserify/node_modules/crypto-browserify\")},{\"./helpers\":4,buffer:3,lYpoI2:11}],9:[function(c,d,e){!function(e,t,n,r,u,s,a,f,l){function b(e,t){var n=(65535&e)+(65535&t);return(e>>16)+(t>>16)+(n>>16)<<16|65535&n}function o(e,l){var c,d=new Array(1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298),t=new Array(1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225),n=new Array(64);e[l>>5]|=128<<24-l%32,e[15+(l+64>>9<<4)]=l;for(var r,o,h=0;h<e.length;h+=16){for(var i=t[0],u=t[1],s=t[2],p=t[3],a=t[4],g=t[5],y=t[6],w=t[7],f=0;f<64;f++)n[f]=f<16?e[f+h]:b(b(b((o=n[f-2],m(o,17)^m(o,19)^v(o,10)),n[f-7]),(o=n[f-15],m(o,7)^m(o,18)^v(o,3))),n[f-16]),c=b(b(b(b(w,m(o=a,6)^m(o,11)^m(o,25)),a&g^~a&y),d[f]),n[f]),r=b(m(r=i,2)^m(r,13)^m(r,22),i&u^i&s^u&s),w=y,y=g,g=a,a=b(p,c),p=s,s=u,u=i,i=b(c,r);t[0]=b(i,t[0]),t[1]=b(u,t[1]),t[2]=b(s,t[2]),t[3]=b(p,t[3]),t[4]=b(a,t[4]),t[5]=b(g,t[5]),t[6]=b(y,t[6]),t[7]=b(w,t[7])}return t}var i=c(\"./helpers\"),m=function(e,t){return e>>>t|e<<32-t},v=function(e,t){return e>>>t};d.exports=function(e){return i.hash(e,o,32,!0)}}.call(this,c(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},c(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/crypto-browserify/sha256.js\",\"/node_modules/gulp-browserify/node_modules/crypto-browserify\")},{\"./helpers\":4,buffer:3,lYpoI2:11}],10:[function(e,t,f){!function(e,t,n,r,o,i,u,s,a){f.read=function(e,t,n,r,o){var i,u,l=8*o-r-1,c=(1<<l)-1,d=c>>1,s=-7,a=n?o-1:0,f=n?-1:1,o=e[t+a];for(a+=f,i=o&(1<<-s)-1,o>>=-s,s+=l;0<s;i=256*i+e[t+a],a+=f,s-=8);for(u=i&(1<<-s)-1,i>>=-s,s+=r;0<s;u=256*u+e[t+a],a+=f,s-=8);if(0===i)i=1-d;else{if(i===c)return u?NaN:1/0*(o?-1:1);u+=Math.pow(2,r),i-=d}return(o?-1:1)*u*Math.pow(2,i-r)},f.write=function(e,t,l,n,r,c){var o,i,u=8*c-r-1,s=(1<<u)-1,a=s>>1,d=23===r?Math.pow(2,-24)-Math.pow(2,-77):0,f=n?0:c-1,h=n?1:-1,c=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(i=isNaN(t)?1:0,o=s):(o=Math.floor(Math.log(t)/Math.LN2),t*(n=Math.pow(2,-o))<1&&(o--,n*=2),2<=(t+=1<=o+a?d/n:d*Math.pow(2,1-a))*n&&(o++,n/=2),s<=o+a?(i=0,o=s):1<=o+a?(i=(t*n-1)*Math.pow(2,r),o+=a):(i=t*Math.pow(2,a-1)*Math.pow(2,r),o=0));8<=r;e[l+f]=255&i,f+=h,i/=256,r-=8);for(o=o<<r|i,u+=r;0<u;e[l+f]=255&o,f+=h,o/=256,u-=8);e[l+f-h]|=128*c}}.call(this,e(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},e(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/ieee754/index.js\",\"/node_modules/gulp-browserify/node_modules/ieee754\")},{buffer:3,lYpoI2:11}],11:[function(e,h,t){!function(e,t,n,r,o,f,l,c,d){var i,u,s;function a(){}(e=h.exports={}).nextTick=(u=\"undefined\"!=typeof window&&window.setImmediate,s=\"undefined\"!=typeof window&&window.postMessage&&window.addEventListener,u?function(e){return window.setImmediate(e)}:s?(i=[],window.addEventListener(\"message\",function(e){var t=e.source;t!==window&&null!==t||\"process-tick\"!==e.data||(e.stopPropagation(),0<i.length&&i.shift()())},!0),function(e){i.push(e),window.postMessage(\"process-tick\",\"*\")}):function(e){setTimeout(e,0)}),e.title=\"browser\",e.browser=!0,e.env={},e.argv=[],e.on=a,e.addListener=a,e.once=a,e.off=a,e.removeListener=a,e.removeAllListeners=a,e.emit=a,e.binding=function(e){throw new Error(\"process.binding is not supported\")},e.cwd=function(){return\"/\"},e.chdir=function(e){throw new Error(\"process.chdir is not supported\")}}.call(this,e(\"lYpoI2\"),\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{},e(\"buffer\").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],\"/node_modules/gulp-browserify/node_modules/process/browser.js\",\"/node_modules/gulp-browserify/node_modules/process\")},{buffer:3,lYpoI2:11}]},{},[1])(1)});","import hash from \"object-hash\";\nimport { GeoPoint } from \"@rebasepro/types\";\n\n/** @private is the value an empty array? */\nexport const isEmptyArray = (value?: unknown) =>\n Array.isArray(value) && value.length === 0;\n\n/** @private is the given object a Function? */\nexport const isFunction = (obj: unknown): obj is (...args: unknown[]) => unknown =>\n typeof obj === \"function\";\n\n/** @private is the given object an integer? */\nexport const isInteger = (obj: unknown): boolean =>\n String(Math.floor(Number(obj))) === String(obj);\n\n/** @private is the given object a NaN? */\n\nexport const isNaN = (obj: unknown): boolean => obj !== obj;\n\n/**\n * Segments that reach the prototype chain rather than a property of the object.\n *\n * The twin of this function in `@rebasepro/forms` could be made to write onto\n * `Object.prototype` through a path of `__proto__.x`. This copy survives the\n * write by accident — its `clone` always spreads into a fresh object, while the\n * form engine's has a \"preserve class instances\" branch that hands back\n * `Object.prototype` itself — but `getIn` still *reads* through the chain, and\n * handing back `Object.prototype` is how a polluted value is read out again.\n *\n * Closed on both sides here, so the two implementations agree.\n */\nconst UNSAFE_PATH_SEGMENTS = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n\n/** Whether any segment of this path would traverse the prototype chain. */\nexport function pathTraversesPrototype(path: string | string[]): boolean {\n return toPath(path).some(segment => UNSAFE_PATH_SEGMENTS.has(segment));\n}\n\n/**\n * Whether writing this single key with `obj[key] = …` would reach the prototype\n * chain instead of creating a property.\n *\n * The single-key counterpart of {@link pathTraversesPrototype}, for the many\n * places that copy an object one key at a time. `JSON.parse` creates\n * `__proto__` as an *own* property, so it survives `hasOwnProperty` — and then\n * `target[key] = value` invokes the setter and replaces the target's prototype.\n */\nexport function isPrototypePollutingKey(key: string): boolean {\n return UNSAFE_PATH_SEGMENTS.has(key);\n}\n\n/**\n * Deeply get a value from an object via its path.\n */\nexport function getIn(\n obj: Record<string, unknown> | unknown[] | unknown,\n key: string | string[],\n def?: unknown,\n p = 0\n) {\n if (pathTraversesPrototype(key)) return def;\n\n const path = toPath(key);\n while (obj && p < path.length) {\n obj = (obj as Record<string, unknown>)[path[p++]];\n }\n\n // check if path is not in the end\n if (p !== path.length && !obj) {\n return def;\n }\n\n return obj === undefined ? def : obj;\n}\n\nexport function setIn<T>(obj: T, path: string, value: unknown): T {\n // See `pathTraversesPrototype`. This copy's `clone` happens to contain the\n // write, but relying on that is relying on an implementation detail of a\n // different function.\n if (pathTraversesPrototype(path)) return obj;\n\n const res = clone(obj) as Record<string, unknown>;\n let resVal: Record<string, unknown> = res;\n let i = 0;\n const pathArray = toPath(path);\n\n for (; i < pathArray.length - 1; i++) {\n const currentPath: string = pathArray[i];\n const currentObj = getIn(obj as Record<string, unknown>, pathArray.slice(0, i + 1));\n\n if (currentObj && (isObject(currentObj) || Array.isArray(currentObj))) {\n resVal = resVal[currentPath] = clone(currentObj) as Record<string, unknown>;\n } else {\n const nextPath: string = pathArray[i + 1];\n resVal = resVal[currentPath] =\n (isInteger(nextPath) && Number(nextPath) >= 0 ? [] : {}) as Record<string, unknown>;\n }\n }\n\n // Return original object if new value is the same as current\n if ((i === 0 ? obj as Record<string, unknown> : resVal)[pathArray[i]] === value) {\n return obj;\n }\n\n if (value === undefined) {\n delete resVal[pathArray[i]];\n } else {\n resVal[pathArray[i]] = value;\n }\n\n // If the path array has a single element, the loop did not run.\n // Deleting on `resVal` had no effect in this scenario, so we delete on the result instead.\n if (i === 0 && value === undefined) {\n delete res[pathArray[i]];\n }\n\n return res as T;\n}\n\nexport function clone<T>(value: T): T {\n if (Array.isArray(value)) {\n return [...value] as T;\n } else if (typeof value === \"object\" && value !== null) {\n return { ...value } as T;\n } else {\n return value; // This is for primitive types which do not need cloning.\n }\n}\n\n/**\n * Deep clone a value, preserving function references and class instances.\n * Unlike structuredClone, this handles objects that contain functions\n * (e.g. CollectionConfig with target(), childCollections(), callbacks).\n */\nexport function deepClone<T>(value: T): T {\n if (value === null || value === undefined) return value;\n if (typeof value === \"function\") return value;\n if (typeof value !== \"object\") return value;\n\n if (Array.isArray(value)) {\n return value.map(item => deepClone(item)) as T;\n }\n\n // Preserve class instances (Date, GeoPoint, etc.) — don't recurse\n if (Object.getPrototypeOf(value) !== Object.prototype) {\n return value;\n }\n\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(value)) {\n result[key] = deepClone((value as Record<string, unknown>)[key]);\n }\n return result as T;\n}\n\nfunction toPath(value: string | string[]) {\n if (Array.isArray(value)) return value; // Already in path array form.\n // Replace brackets with dots, remove leading/trailing dots, then split by dot.\n return value.replace(/\\[(\\d+)]/g, \".$1\").replace(/^\\./, \"\").replace(/\\.$/, \"\").split(\".\");\n}\n\n\nexport const pick: <T extends Record<string, unknown>>(obj: T, ...args: (keyof T)[]) => Partial<T> = <T extends Record<string, unknown>>(obj: T, ...args: (keyof T)[]) => ({\n ...args.reduce<Record<string, unknown>>((res, key) => ({\n ...res,\n [key as string]: obj[key as string]\n }), {})\n}) as Partial<T>;\n\nexport function isObject(item: unknown): item is Record<string, unknown> {\n return !!item && typeof item === \"object\" && !Array.isArray(item);\n}\n\nexport function isPlainObject(obj: unknown): obj is Record<string, unknown> {\n // 1. Rule out non-objects, null, and arrays\n if (typeof obj !== \"object\" || obj === null || Array.isArray(obj)) {\n return false;\n }\n\n // 2. Get the object's direct prototype\n const proto = Object.getPrototypeOf(obj);\n\n // 3. A plain object's direct prototype is Object.prototype\n return proto === Object.prototype;\n}\n\nexport function mergeDeep<T extends object, U extends object>(\n target: T,\n source: U,\n ignoreUndefined = false\n): T & U {\n // If target is not a true object (e.g., null, array, primitive), return target itself.\n if (!isObject(target)) {\n return target as T & U;\n }\n\n // Create a shallow copy of the target to avoid modifying the original object.\n const output = { ...target };\n\n // If source is not a true object, there's nothing to merge from it.\n // Return the shallow copy of target.\n if (!isObject(source)) {\n return output as T & U;\n }\n\n // Iterate over keys in the source object.\n for (const key in source) {\n if (key === \"__proto__\" || key === \"constructor\" || key === \"prototype\") {\n continue;\n }\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n const sourceValue = source[key];\n const outputValue = (output as Record<string, unknown>)[key]; // Current value in our merged object (originating from target)\n\n // Skip if source value is undefined and ignoreUndefined is true.\n // This handles both not adding new undefined properties and not overwriting existing properties with undefined.\n if (ignoreUndefined && sourceValue === undefined) {\n continue;\n }\n\n if (sourceValue instanceof Date) {\n // If source value is a Date, create a new Date instance.\n (output as Record<string, unknown>)[key] = new Date(sourceValue.getTime());\n } else if (Array.isArray(sourceValue)) {\n if (Array.isArray(outputValue)) {\n // If the array contains primitives or class instances (non-plain objects),\n // overwrite the array entirely instead of doing element-wise merging.\n const hasPlainObjects = sourceValue.some(isPlainObject) || outputValue.some(isPlainObject);\n if (!hasPlainObjects) {\n (output as Record<string, unknown>)[key] = [...sourceValue];\n } else {\n const newArray = [];\n const maxLength = Math.max(outputValue.length, sourceValue.length);\n for (let i = 0; i < maxLength; i++) {\n const sourceItem = sourceValue[i];\n const targetItem = outputValue[i];\n\n if (i >= sourceValue.length) { // source is shorter\n newArray[i] = targetItem;\n } else if (i >= outputValue.length) { // target is shorter\n newArray[i] = sourceItem;\n } else if (sourceItem === null) {\n newArray[i] = targetItem;\n } else if (isPlainObject(sourceItem) && isPlainObject(targetItem)) {\n // Only recursively merge plain objects, preserve class instances\n newArray[i] = mergeDeep(targetItem, sourceItem, ignoreUndefined);\n } else {\n // For class instances and primitives, use source directly\n newArray[i] = sourceItem;\n }\n }\n (output as Record<string, unknown>)[key] = newArray;\n }\n } else {\n // If output's value (from target) is not an array,\n // overwrite with a shallow copy of the source array.\n (output as Record<string, unknown>)[key] = [...sourceValue];\n }\n } else if (isPlainObject(sourceValue)) {\n // If source value is a plain object (not a class instance like EntityReference, GeoPoint, etc.):\n if (isPlainObject(outputValue)) {\n // If the corresponding value in output (from target) is also a plain object, recurse.\n // Ensure the ignoreUndefined flag is passed down.\n (output as Record<string, unknown>)[key] = mergeDeep(outputValue as Record<string, unknown>, sourceValue, ignoreUndefined);\n } else {\n // If output's value (from target) is not a plain object (e.g., null, primitive, class instance, or key didn't exist in original target),\n // overwrite with the source object.\n (output as Record<string, unknown>)[key] = sourceValue;\n }\n } else if (isObject(sourceValue)) {\n // If source value is a class instance (not a plain object), use it directly to preserve prototype\n (output as Record<string, unknown>)[key] = sourceValue;\n } else {\n // If source value is a primitive, null, or undefined (and not ignored).\n (output as Record<string, unknown>)[key] = sourceValue;\n }\n }\n }\n\n return output as T & U;\n}\n\nexport function getValueInPath(o: object | undefined, path: string): unknown {\n if (!o) return undefined;\n if (typeof o === \"object\") {\n if (path in o) {\n return (o as Record<string, unknown>)[path];\n }\n if (path.includes(\".\") || path.includes(\"[\")) {\n let pathSegments = path.split(/[.[]/);\n if (path.includes(\"[\")) {\n pathSegments = pathSegments.map(segment => segment.replace(\"]\", \"\"));\n }\n const firstSegment = pathSegments[0];\n const isArrayAndIndexExists = Array.isArray((o as Record<string, unknown>)[firstSegment]) && !isNaN(parseInt(pathSegments[1]));\n const nextObject = isArrayAndIndexExists\n ? ((o as Record<string, unknown>)[firstSegment] as unknown[])[parseInt(pathSegments[1])]\n : (o as Record<string, unknown>)[firstSegment];\n\n const nextPath = pathSegments.slice(isArrayAndIndexExists ? 2 : 1).join(\".\");\n if (nextPath === \"\")\n return nextObject;\n return getValueInPath(nextObject as object | undefined, nextPath);\n }\n }\n return undefined;\n}\n\nexport function removeInPath(o: object, path: string): object | undefined {\n const res = clone(o) as Record<string, unknown>;\n let current = res;\n const parts = path.split(\".\");\n const last = parts.pop();\n for (const part of parts) {\n if (part in current && current[part] !== null && typeof current[part] === \"object\") {\n current[part] = clone(current[part]) as Record<string, unknown>;\n current = current[part] as Record<string, unknown>;\n } else {\n return res;\n }\n }\n if (last && current && typeof current === \"object\") {\n delete current[last];\n }\n return res;\n}\n\nexport function removeFunctions(o: unknown): unknown {\n if (o === undefined) return undefined;\n if (o === null) return null;\n if (typeof o === \"object\") {\n // Handle arrays first - drop function elements, then recurse.\n // Only object *properties* used to be filtered, so a function sitting\n // directly in an array survived — and the callers strip functions\n // precisely because a function survives no deep comparison.\n if (Array.isArray(o)) {\n return o\n .filter(v => typeof v !== \"function\")\n .map(v => removeFunctions(v));\n }\n // Preserve class instances (EntityReference, GeoPoint, etc.) - don't recurse into them\n if (!isPlainObject(o)) {\n return o;\n }\n return Object.entries(o)\n .filter(([_, value]) => typeof value !== \"function\")\n .reduce<Record<string, unknown>>((acc, [key, value]) => {\n acc[key] = removeFunctions(value);\n return acc;\n }, {});\n }\n return o;\n}\n\nexport function getHashValue<T>(v: T): string | null {\n if (!v) return null;\n if (typeof v === \"object\" && v !== null) {\n if (\"id\" in v)\n return String((v as Record<string, unknown>).id);\n else if (v instanceof Date)\n return v.toLocaleString();\n else if (v instanceof GeoPoint)\n return hash(v as Record<string, unknown>);\n }\n return hash(v as object, { ignoreUnknown: true });\n}\n\nexport function removeUndefined(value: unknown, removeEmptyStrings?: boolean): unknown {\n if (typeof value === \"function\") {\n return value;\n }\n if (Array.isArray(value)) {\n return value.map((v: unknown) => removeUndefined(v, removeEmptyStrings));\n }\n if (typeof value === \"object\") {\n if (value === null)\n return value;\n // Preserve class instances (EntityReference, GeoPoint, etc.) - don't recurse into them\n if (!isPlainObject(value)) {\n return value;\n }\n const res: Record<string, unknown> = {};\n Object.keys(value).forEach((key) => {\n if (!isEmptyObject(value as object)) {\n const childRes = removeUndefined((value as Record<string, unknown>)[key], removeEmptyStrings);\n const isString = typeof childRes === \"string\";\n const shouldKeepIfString = !removeEmptyStrings || (removeEmptyStrings && !isString) || (removeEmptyStrings && isString && childRes !== \"\");\n if (childRes !== undefined && !isEmptyObject(childRes as object) && shouldKeepIfString)\n res[key] = childRes;\n }\n });\n return res;\n }\n return value;\n}\n\nexport function removeNulls(value: unknown): unknown {\n if (typeof value === \"function\") {\n return value;\n }\n if (Array.isArray(value)) {\n return value.map((v: unknown) => removeNulls(v));\n }\n if (typeof value === \"object\") {\n if (value === null)\n return value;\n // Preserve class instances (EntityReference, GeoPoint, etc.) - don't recurse into them\n if (!isPlainObject(value)) {\n return value;\n }\n const res: Record<string, unknown> = {};\n const obj = value as Record<string, unknown>;\n Object.keys(obj).forEach((key) => {\n if (obj[key] !== null)\n res[key] = removeNulls(obj[key]);\n });\n return res;\n }\n return value;\n}\n\nexport function isEmptyObject(obj: object) {\n return obj &&\n Object.getPrototypeOf(obj) === Object.prototype &&\n Object.keys(obj).length === 0\n}\n\nexport function removePropsIfExisting(source: Record<string, unknown> | unknown[], comparison: Record<string, unknown> | unknown[]) {\n const isObject = (val: unknown): val is Record<string, unknown> => typeof val === \"object\" && val !== null;\n const isArray = (val: unknown): val is unknown[] => Array.isArray(val);\n\n if (!isObject(source) || !isObject(comparison)) {\n return source;\n }\n\n const res = isArray(source) ? [...source] : { ...source };\n\n if (isArray(res)) {\n for (let i = res.length - 1; i >= 0; i--) {\n if (res[i] === comparison[i]) {\n res.splice(i, 1);\n } else if (isObject(res[i]) && isObject(comparison[i])) {\n res[i] = removePropsIfExisting(res[i] as unknown as Record<string, unknown>, (comparison as unknown as unknown[])[i] as Record<string, unknown>);\n }\n }\n } else {\n Object.keys(comparison).forEach(key => {\n if (key in res) {\n if (isObject(res[key]) && isObject(comparison[key])) {\n res[key] = removePropsIfExisting(res[key], comparison[key]);\n } else if (res[key] === comparison[key]) {\n delete res[key];\n }\n }\n });\n }\n\n return res;\n}\n","/**\n * Minimal SHA-1 implementation that runs in both Node and the browser.\n *\n * This exists because generated Postgres policy names embed a SHA-1 digest of\n * the security rule. The DDL generator runs on the server (where `node:crypto`\n * is available) but the Studio has to derive the same names in the browser to\n * tell a policy it generated apart from one it did not. `node:crypto` cannot be\n * bundled for the browser, so the shared derivation needs a portable digest.\n *\n * SHA-1 is used purely to name things deterministically — never for security.\n * The output is byte-identical to `createHash(\"sha1\").update(str).digest(\"hex\")`,\n * which `sha1.test.ts` pins against `node:crypto` directly.\n */\n\n/** Rotate a 32-bit word left by `n` bits. */\nfunction rotl(value: number, n: number): number {\n return (value << n) | (value >>> (32 - n));\n}\n\n/**\n * SHA-1 digest of a string, hex-encoded.\n *\n * The input is encoded as UTF-8, matching Node's default handling of strings\n * passed to `hash.update(str)`.\n */\nexport function sha1Hex(input: string): string {\n const bytes: number[] = Array.from(new TextEncoder().encode(input));\n const bitLength = bytes.length * 8;\n\n // Padding: 0x80, then zeroes up to 56 bytes mod 64, then the length as a\n // 64-bit big-endian integer.\n bytes.push(0x80);\n while (bytes.length % 64 !== 56) bytes.push(0);\n\n const hi = Math.floor(bitLength / 0x100000000);\n const lo = bitLength >>> 0;\n bytes.push((hi >>> 24) & 0xff, (hi >>> 16) & 0xff, (hi >>> 8) & 0xff, hi & 0xff);\n bytes.push((lo >>> 24) & 0xff, (lo >>> 16) & 0xff, (lo >>> 8) & 0xff, lo & 0xff);\n\n let h0 = 0x67452301;\n let h1 = 0xefcdab89;\n let h2 = 0x98badcfe;\n let h3 = 0x10325476;\n let h4 = 0xc3d2e1f0;\n\n const w = new Array<number>(80);\n\n for (let offset = 0; offset < bytes.length; offset += 64) {\n for (let i = 0; i < 16; i++) {\n const j = offset + i * 4;\n w[i] = ((bytes[j] << 24) | (bytes[j + 1] << 16) | (bytes[j + 2] << 8) | bytes[j + 3]) | 0;\n }\n for (let i = 16; i < 80; i++) {\n w[i] = rotl(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1);\n }\n\n let a = h0;\n let b = h1;\n let c = h2;\n let d = h3;\n let e = h4;\n\n for (let i = 0; i < 80; i++) {\n let f: number;\n let k: number;\n if (i < 20) {\n f = (b & c) | (~b & d);\n k = 0x5a827999;\n } else if (i < 40) {\n f = b ^ c ^ d;\n k = 0x6ed9eba1;\n } else if (i < 60) {\n f = (b & c) | (b & d) | (c & d);\n k = 0x8f1bbcdc;\n } else {\n f = b ^ c ^ d;\n k = 0xca62c1d6;\n }\n\n const temp = (rotl(a, 5) + f + e + k + w[i]) | 0;\n e = d;\n d = c;\n c = rotl(b, 30);\n b = a;\n a = temp;\n }\n\n h0 = (h0 + a) | 0;\n h1 = (h1 + b) | 0;\n h2 = (h2 + c) | 0;\n h3 = (h3 + d) | 0;\n h4 = (h4 + e) | 0;\n }\n\n return [h0, h1, h2, h3, h4]\n .map(word => (word >>> 0).toString(16).padStart(8, \"0\"))\n .join(\"\");\n}\n","import type { SecurityOperation, SecurityRule } from \"@rebasepro/types\";\nimport { sha1Hex } from \"./sha1\";\n\n/**\n * Naming of the Postgres policies generated from a collection's security rules.\n *\n * A rule without an explicit `name` is compiled to `<table>_<op>_<hash>`, where\n * the hash covers the rule's semantics. The Studio needs the same names to tell\n * \"this policy came from your code\" apart from \"someone wrote this in SQL\" —\n * without them it treats generated policies as foreign and offers to import\n * them back into the codebase they came from.\n *\n * This is the single definition of that naming. The DDL and Drizzle generators\n * both derive names from here, so a change cannot silently rename every policy\n * in every deployed database while the UI keeps matching the old ones.\n */\n\n/** Stable digest of the parts of a rule that determine what the policy does. */\nexport function getPolicyNameHash(rule: SecurityRule): string {\n const data = JSON.stringify({\n a: rule.access,\n m: rule.mode,\n op: rule.operation,\n ops: rule.operations?.slice().sort(),\n own: rule.ownerField,\n rol: rule.roles?.slice().sort(),\n pg: rule.pgRoles?.slice().sort(),\n u: rule.using,\n w: rule.withCheck,\n c: rule.condition,\n ch: rule.check\n });\n return sha1Hex(data).substring(0, 7);\n}\n\n/** The operations a rule expands to — `operations` wins over `operation`. */\nexport function getPolicyOperations(rule: SecurityRule): readonly SecurityOperation[] {\n return rule.operations && rule.operations.length > 0\n ? rule.operations\n : [rule.operation ?? \"all\"];\n}\n\n/**\n * Every Postgres policy name a single rule compiles to — one per operation.\n *\n * @param rule The security rule as written in the collection config.\n * @param tableName The rule's table (see `getTableName` in `@rebasepro/common`).\n */\nexport function getPolicyNamesForRule(rule: SecurityRule, tableName: string): string[] {\n const ops = getPolicyOperations(rule);\n const ruleHash = getPolicyNameHash(rule);\n\n return ops.map((op, opIdx) => rule.name\n ? (ops.length > 1 ? `${rule.name}_${op}` : rule.name)\n : `${tableName}_${op}_${ruleHash}${ops.length > 1 ? `_${opIdx}` : \"\"}`);\n}\n\n/** Every policy name a set of rules compiles to, for membership checks. */\nexport function getPolicyNamesForRules(rules: SecurityRule[], tableName: string): Set<string> {\n const names = new Set<string>();\n for (const rule of rules) {\n for (const name of getPolicyNamesForRule(rule, tableName)) names.add(name);\n }\n return names;\n}\n","/**\n * Returns the plural of an English word.\n *\n * @param {string} word\n * @param {number} [amount]\n * @returns {string}\n */\nexport function plural(word: string, amount?: number): string {\n if (amount !== undefined && amount === 1) {\n return word\n }\n const plurals: { [key: string]: string } = {\n \"(quiz)$\": \"$1zes\",\n \"^(ox)$\": \"$1en\",\n \"([m|l])ouse$\": \"$1ice\",\n \"(matr|vert|ind)ix|ex$\": \"$1ices\",\n \"(x|ch|ss|sh)$\": \"$1es\",\n \"([^aeiouy]|qu)y$\": \"$1ies\",\n \"(hive)$\": \"$1s\",\n \"(?:([^f])fe|([lr])f)$\": \"$1$2ves\",\n \"(shea|lea|loa|thie)f$\": \"$1ves\",\n sis$: \"ses\",\n \"([ti])um$\": \"$1a\",\n \"(tomat|potat|ech|her|vet)o$\": \"$1oes\",\n \"(bu)s$\": \"$1ses\",\n \"(alias)$\": \"$1es\",\n \"(octop)us$\": \"$1i\",\n \"(ax|test)is$\": \"$1es\",\n \"(us)$\": \"$1es\",\n \"([^s]+)$\": \"$1s\"\n }\n const irregular: { [key: string]: string } = {\n move: \"moves\",\n foot: \"feet\",\n goose: \"geese\",\n sex: \"sexes\",\n child: \"children\",\n man: \"men\",\n tooth: \"teeth\",\n person: \"people\"\n }\n const uncountable: string[] = [\n \"sheep\",\n \"fish\",\n \"deer\",\n \"moose\",\n \"series\",\n \"species\",\n \"money\",\n \"rice\",\n \"information\",\n \"equipment\",\n \"bison\",\n \"cod\",\n \"offspring\",\n \"pike\",\n \"salmon\",\n \"shrimp\",\n \"swine\",\n \"trout\",\n \"aircraft\",\n \"hovercraft\",\n \"spacecraft\",\n \"sugar\",\n \"tuna\",\n \"you\",\n \"wood\"\n ]\n // save some time in the case that singular and plural are the same\n if (uncountable.indexOf(word.toLowerCase()) >= 0) {\n return word;\n }\n // check for irregular forms\n for (const w in irregular) {\n const pattern = new RegExp(`${w}$`, \"i\")\n const replace = irregular[w]\n if (pattern.test(word)) {\n return word.replace(pattern, replace);\n }\n }\n // check for matches using regular expressions\n for (const reg in plurals) {\n const pattern = new RegExp(reg, \"i\")\n if (pattern.test(word)) {\n return word.replace(pattern, plurals[reg])\n }\n }\n return word;\n}\n\n/**\n * Returns the singular of an English word.\n *\n * @param {string} word\n * @param {number} [amount]\n * @returns {string}\n */\nexport function singular(word: string, amount?: number): string {\n if (amount !== undefined && amount !== 1) {\n return word;\n }\n const singulars: { [key: string]: string } = {\n \"(quiz)zes$\": \"$1\",\n \"(matr)ices$\": \"$1ix\",\n \"(vert|ind)ices$\": \"$1ex\",\n \"^(ox)en$\": \"$1\",\n \"(alias)es$\": \"$1\",\n \"(octop|vir)i$\": \"$1us\",\n \"(cris|ax|test)es$\": \"$1is\",\n \"(shoe)s$\": \"$1\",\n \"(o)es$\": \"$1\",\n \"(bus)es$\": \"$1\",\n \"([m|l])ice$\": \"$1ouse\",\n \"(x|ch|ss|sh)es$\": \"$1\",\n \"(m)ovies$\": \"$1ovie\",\n \"(s)eries$\": \"$1eries\",\n \"([^aeiouy]|qu)ies$\": \"$1y\",\n \"([lr])ves$\": \"$1f\",\n \"(tive)s$\": \"$1\",\n \"(hive)s$\": \"$1\",\n \"(li|wi|kni)ves$\": \"$1fe\",\n \"(shea|loa|lea|thie)ves$\": \"$1f\",\n \"(^analy)ses$\": \"$1sis\",\n \"((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$\": \"$1$2sis\",\n \"([ti])a$\": \"$1um\",\n \"(n)ews$\": \"$1ews\",\n \"(h|bl)ouses$\": \"$1ouse\",\n \"(corpse)s$\": \"$1\",\n \"(us)es$\": \"$1\",\n s$: \"\"\n }\n const irregular: { [key: string]: string } = {\n move: \"moves\",\n foot: \"feet\",\n goose: \"geese\",\n sex: \"sexes\",\n child: \"children\",\n man: \"men\",\n tooth: \"teeth\",\n person: \"people\"\n }\n const uncountable: string[] = [\n \"sheep\",\n \"fish\",\n \"deer\",\n \"moose\",\n \"series\",\n \"species\",\n \"money\",\n \"rice\",\n \"information\",\n \"equipment\",\n \"bison\",\n \"cod\",\n \"offspring\",\n \"pike\",\n \"salmon\",\n \"shrimp\",\n \"swine\",\n \"trout\",\n \"aircraft\",\n \"hovercraft\",\n \"spacecraft\",\n \"sugar\",\n \"tuna\",\n \"you\",\n \"wood\"\n ]\n // save some time in the case that singular and plural are the same\n if (uncountable.indexOf(word.toLowerCase()) >= 0) {\n return word;\n }\n // check for irregular forms\n for (const w in irregular) {\n const pattern = new RegExp(`${irregular[w]}$`, \"i\");\n if (pattern.test(word)) {\n return word.replace(pattern, w);\n }\n }\n // check for matches using regular expressions\n for (const reg in singulars) {\n const pattern = new RegExp(reg, \"i\");\n if (pattern.test(word)) {\n return word.replace(pattern, singulars[reg]);\n }\n }\n return word;\n}\n","import { singular } from \"./plurals\";\nimport { toSnakeCase } from \"./strings\";\n\n/**\n * Generates a foreign key column name from a given string, typically a collection slug or name.\n * It singularizes the name, converts it to snake_case and appends '_id'.\n *\n * Singularization runs *before* snake-casing so that acronyms survive: `toSnakeCase`\n * splits on every capital, which turned \"URLs\" into \"ur_ls\" and then \"ur_l_id\".\n *\n * @param name The base name to convert to a foreign key.\n * @returns A foreign key name in the format 'singular_name_id'.\n *\n * @example\n * // returns \"user_id\"\n * generateForeignKeyName(\"users\")\n *\n * @example\n * // returns \"category_id\"\n * generateForeignKeyName(\"categories\")\n *\n * @example\n * // returns \"product_id\"\n * generateForeignKeyName(\"Product\")\n *\n */\nexport function generateForeignKeyName(name: string): string {\n return `${toSnakeCase(singularizeForKey(name))}_id`;\n}\n\n/**\n * `singular()` handles real English plurals, but its final catch-all rule strips\n * any trailing \"s\", which mangles words that only look plural. Guard the two\n * cases that produce a column name nobody would recognise:\n *\n * - a double \"s\" ending is never a plural marker (\"address\", \"class\", \"process\"),\n * so stripping it yields \"addres\";\n * - a name that singularizes to nothing (the literal \"s\") would yield \"_id\".\n */\nfunction singularizeForKey(name: string): string {\n if (/ss$/i.test(name)) return name;\n const result = singular(name);\n return result.length > 0 ? result : name;\n}\n\n/**\n * What `generateForeignKeyName` returned before it learned to singularize:\n * snake-case the name, then chop one trailing \"s\".\n *\n * This is here to be *detected*, never to be generated. A database provisioned\n * under the old rule carries `categorie_id`, `addresse_id`, `children_id` or\n * `ur_l_id` where the current rule expects `category_id`, `address_id`,\n * `child_id` and `url_id` — and the boot-time schema ensure is additive, so it\n * would create the new column empty beside the populated old one and leave the\n * relation reading nothing. No error, no missing table: the failure is silent,\n * which is the only reason this function still exists.\n *\n * `ensureCollectionSchema` calls it to recognise that shape and say so.\n * Returns the same string as `generateForeignKeyName` for every regular plural,\n * so a caller can compare the two and act only when they differ.\n */\nexport function legacyForeignKeyName(name: string): string {\n const snake = toSnakeCase(name);\n return `${snake.endsWith(\"s\") ? snake.slice(0, -1) : snake}_id`;\n}\n\n/**\n * Truncate an identifier to what Postgres will actually store.\n *\n * Postgres silently truncates identifiers at NAMEDATALEN-1 = 63 **bytes**, so a\n * name generated longer than that is not the name the database ends up holding.\n * Anything that later looks the object up by the name it generated then misses.\n *\n * Byte length, not string length: NAMEDATALEN is a byte bound, and a multi-byte\n * character straddling the boundary would be cut mid-sequence by `slice(0, 63)`.\n *\n * `TextEncoder` rather than `Buffer`, which is not a matter of taste: `Buffer`\n * is a Node global, and this package is imported by browser-facing ones. It\n * typechecked only where `@types/node` happened to be in scope, so\n * `packages/codegen` — whose tsconfig is `lib: [\"ESNext\", \"dom\"]` — could not\n * compile the file at all, and both of its suites failed to run. `TextEncoder`\n * and `TextDecoder` are standard in both runtimes and need no ambient types.\n */\nexport function toPostgresIdentifier(name: string): string {\n const bytes = new TextEncoder().encode(name);\n if (bytes.byteLength <= 63) return name;\n // Decoding a slice that ends mid-character yields U+FFFD; dropping it lands\n // on the last whole character that fits, which is what Postgres does.\n return new TextDecoder(\"utf-8\").decode(bytes.subarray(0, 63)).replace(/�+$/, \"\");\n}\n\n/**\n * The API name a database column is served under.\n *\n * The wire name of a field is its property key, and Rebase's property keys are\n * camelCase — `displayName`, `createdAt`, `photoURL`. Columns are snake_case,\n * because an unquoted Postgres identifier folds to lower case and a camelCase\n * column is therefore reachable only as `\"authorId\"` forever: in hand-written\n * SQL, in psql, in an RLS policy body, in a dump, and in every third-party tool\n * that ever touches the database. So the two conventions are both right, and\n * this is the function that crosses between them.\n *\n * It exists because two sources of field names never crossed: a foreign key\n * derived from a relation (`author_id`) and a column read back by introspection\n * (`user_id`) both landed on the wire under their column name, while every\n * hand-authored collection next to them used camelCase. One API, two\n * conventions, and no rule a caller could infer from outside — those names are\n * also the `where` and `orderBy` keys, so it was not a matter of taste.\n *\n * Rules, in the order they matter:\n *\n * - **A name with no separator is returned unchanged.** `photoURL` stays\n * `photoURL` and `id` stays `id`. Lower-casing a single token is what makes\n * a \"camelCase\" helper destructive — `camelCase(\"photoURL\")` is `photourl` —\n * and this function is applied to names that are *already* keys.\n * - **Each following segment keeps its own casing** apart from an upper-cased\n * first letter, so `photo_URL` → `photoURL` rather than `photoUrl`.\n * - **The result may still not be a JavaScript identifier.** `2fa_enabled`\n * becomes `2faEnabled`, which is a perfectly good object key and still needs\n * quoting where one is written into generated source.\n *\n * Not the inverse of {@link toSnakeCase}: `toSnakeCase` tokenises on case\n * boundaries and would turn `photoURL` into `photo_url`. Round-tripping is not\n * a property either function promises, which is why a column name that a\n * property maps explicitly is always read off `columnName` rather than derived.\n */\nexport function toWireKey(columnName: string): string {\n if (!columnName) return columnName;\n const segments = columnName.split(/[-_ ]+/).filter(Boolean);\n if (segments.length <= 1) return columnName;\n return segments\n .map((segment, index) =>\n index === 0\n ? segment.charAt(0).toLowerCase() + segment.slice(1)\n : segment.charAt(0).toUpperCase() + segment.slice(1))\n .join(\"\");\n}\n\n/**\n * The first candidate key not already used, or a numbered fallback.\n *\n * Introspection turns a set of column names into a set of object keys, and the\n * mapping is not injective: `user_id` and `userId` are two columns and one\n * {@link toWireKey}, and two foreign keys can strip to the same relation name.\n * A duplicate key in a generated object literal is a TypeScript error, so the\n * whole collection stops compiling — and a duplicate key in a `Record` built at\n * runtime is worse, because it silently drops a column instead.\n *\n * The numbered tail is what makes this total: a function that returns a key it\n * cannot guarantee is free has only moved the duplicate one line down.\n *\n * Structurally typed on `has` so a `Map` of emitted blocks and a `Set` of taken\n * names both satisfy it. Lives here, in the package both introspection\n * producers and the admin's table import can reach, because they must resolve a\n * collision the same way or one database describes itself three ways.\n */\nexport function firstFreeKey(candidates: string[], taken: { has(key: string): boolean }): string {\n for (const candidate of candidates) {\n if (!taken.has(candidate)) return candidate;\n }\n const base = candidates[candidates.length - 1];\n for (let suffix = 2; ; suffix++) {\n const candidate = `${base}_${suffix}`;\n if (!taken.has(candidate)) return candidate;\n }\n}\n","import {\n DataType,\n Entity,\n EntityReference,\n EntityRelation,\n EntityStatus,\n EntityValues,\n Properties,\n Property\n} from \"@rebasepro/types\";\nimport { DEFAULT_ONE_OF_TYPE, DEFAULT_ONE_OF_VALUE } from \"./common\";\nimport { mergeDeep } from \"@rebasepro/utils\";\n\nexport function isPropertyBuilder(property?: Property) {\n return typeof property?.dynamicProps === \"function\";\n}\n\nexport function getDefaultValuesFor<M extends Record<string, unknown>>(properties: Properties): Partial<EntityValues<M>> {\n if (!properties) return {};\n return Object.entries(properties)\n .map(([key, property]) => {\n if (!property) return {};\n const value = getDefaultValueFor(property);\n return value === undefined ? {} : { [key]: value };\n })\n .reduce((a, b) => ({ ...a,\n...b }), {}) as EntityValues<M>;\n}\n\nexport function getDefaultValueFor(property?: Property): unknown {\n if (!property) return undefined;\n if (isPropertyBuilder(property)) return undefined;\n if (property.defaultValue || property.defaultValue === null) {\n return property.defaultValue;\n } else if (property.type === \"map\" && property.properties) {\n const defaultValuesFor = getDefaultValuesFor(property.properties as Properties);\n if (Object.keys(defaultValuesFor).length === 0) return undefined;\n return defaultValuesFor;\n } else {\n return getDefaultValueFortype(property.type);\n }\n}\n\nexport function getDefaultValueFortype(type: DataType): unknown {\n if (type === \"string\") {\n return null;\n } else if (type === \"number\") {\n return null;\n } else if (type === \"boolean\") {\n return false;\n } else if (type === \"date\") {\n return null;\n } else if (type === \"array\") {\n return [];\n } else if (type === \"map\") {\n return {};\n } else if (type === \"vector\") {\n return null;\n } else if (type === \"binary\") {\n return null;\n } else {\n return null;\n }\n}\n\n/**\n * Update the automatic values in a entity before save\n * @group Driver\n */\nexport function updateDateAutoValues<M extends Record<string, unknown>>({\n inputValues,\n properties,\n status,\n timestampNowValue\n}:\n {\n inputValues: Partial<EntityValues<M>>,\n properties: Properties,\n status: EntityStatus,\n timestampNowValue: unknown\n }): EntityValues<M> {\n return traverseValuesProperties(\n inputValues,\n properties,\n (inputValue, property) => {\n if (property.type === \"date\") {\n if (status === \"existing\" && property.autoValue === \"on_update\") {\n return timestampNowValue;\n } else if ((status === \"new\" || status === \"copy\") &&\n (property.autoValue === \"on_update\" || property.autoValue === \"on_create\")) {\n return timestampNowValue;\n } else {\n return inputValue;\n }\n } else {\n return inputValue;\n }\n }\n ) ?? {} as M;\n}\n\n/**\n * Add missing required fields, expected in the collection, to the values of a entity\n * @param values\n * @param properties\n * @group Driver\n */\nexport function sanitizeData<M extends Record<string, unknown>>\n (\n values: EntityValues<M>,\n properties: Properties\n ) {\n const result = values as Record<string, unknown>;\n Object.entries(properties)\n .forEach(([key, property]) => {\n if (values && values[key] !== undefined) result[key] = values[key];\n else if ((property as Property).validation?.required) result[key] = null;\n });\n return result;\n}\n\nexport function getReferenceFrom<M extends Record<string, unknown>>(entity: Entity<M>): EntityReference {\n if (typeof entity.id !== \"string\")\n throw new Error(\"Only string IDs are supported in references\");\n return new EntityReference({\n id: entity.id,\n path: entity.path,\n driver: entity.driver,\n databaseId: entity.databaseId\n });\n}\n\nexport function getRelationFrom<M extends Record<string, unknown>>(entity: Entity<M>): EntityRelation {\n return new EntityRelation(entity.id, entity.path, entity as unknown as Record<string, unknown>);\n}\n\n/**\n * Normalize a value into a proper EntityRelation instance.\n * Handles EntityRelation class instances, and plain objects\n * with `__type === \"relation\"` or an `isEntityRelation()` method.\n *\n * When `propertyType` is `\"relation\"`, also accepts plain objects that\n * have `id` and `path` fields — these are relation-shaped objects from\n * edge cases in the data pipeline (REST fallback, stale cache, custom data source).\n *\n * When `targetPath` is given, also accepts a bare id. A relation column is a\n * foreign key, and the REST layer returns it as the scalar it is; only some\n * fetch paths hydrate it into an object. Which form a caller sees therefore\n * depends on how the row was loaded, and a caller that only accepted objects\n * reported half of its own data as a type error. The declared target is the\n * missing half: with it, an id is a relation that has not been fetched yet.\n *\n * Returns null if the value cannot be coerced.\n */\nexport function normalizeToEntityRelation(value: unknown, propertyType?: string, targetPath?: string): EntityRelation | null {\n if (value instanceof EntityRelation) return value;\n\n if (targetPath && (typeof value === \"string\" || typeof value === \"number\")) {\n // An empty string is an unset foreign key, not row \"\".\n if (value === \"\") return null;\n return new EntityRelation(value, targetPath);\n }\n\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return null;\n\n const obj = value as Record<string, unknown>;\n const isRelationLike =\n obj.__type === \"relation\" ||\n obj.__type === \"reference\" ||\n (typeof obj.isEntityRelation === \"function\" && (obj.isEntityRelation as () => boolean)()) ||\n (typeof obj.isEntityReference === \"function\" && (obj.isEntityReference as () => boolean)()) ||\n (propertyType === \"relation\" && typeof obj.id !== \"undefined\" && typeof obj.path === \"string\");\n\n if (!isRelationLike) return null;\n\n return new EntityRelation(\n obj.id as string | number,\n obj.path as string,\n obj.data as Record<string, unknown> | undefined\n );\n}\n\nexport function traverseValuesProperties<M extends Record<string, unknown>>(\n inputValues: Partial<EntityValues<M>>,\n properties: Properties,\n operation: (value: unknown, property: Property) => unknown\n): EntityValues<M> | undefined {\n // Handle null/undefined inputValues - use empty object as base for mergeDeep\n const safeInputValues = inputValues ?? {};\n\n const updatedValues = Object.entries(properties)\n .map(([key, property]) => {\n const inputValue = safeInputValues && (safeInputValues)[key];\n const updatedValue = traverseValueProperty(inputValue, property as Property, operation);\n if (updatedValue === null) return null;\n if (updatedValue === undefined) return undefined;\n return ({ [key]: updatedValue });\n })\n .reduce((a, b) => ({ ...a,\n...b }), {}) as EntityValues<M>;\n // Use mergeDeep to preserve class instances like EntityReference, GeoPoint\n const result = mergeDeep(safeInputValues, updatedValues);\n if (!result || Object.keys(result).length === 0) return undefined;\n return result;\n}\n\nexport function traverseValueProperty(inputValue: unknown,\n property: Property,\n operation: (value: unknown, property: Property) => unknown): unknown {\n\n let value;\n if (property.type === \"map\" && property.properties) {\n value = traverseValuesProperties(inputValue as Partial<Record<string, unknown>>, property.properties, operation);\n } else if (property.type === \"array\") {\n const of = property.of;\n if (of && Array.isArray(inputValue) && !Array.isArray(of)) {\n value = inputValue.map((e) => traverseValueProperty(e, of, operation));\n } else if (of && Array.isArray(inputValue) && Array.isArray(of)) {\n value = inputValue.map((e, i) => {\n if (i < of.length)\n return traverseValueProperty(e, of[i], operation);\n return null\n }).filter(Boolean);\n } else if (property.oneOf && Array.isArray(inputValue)) {\n const typeField = property.oneOf?.typeField ?? DEFAULT_ONE_OF_TYPE;\n const valueField = property.oneOf?.valueField ?? DEFAULT_ONE_OF_VALUE;\n value = inputValue.map((e) => {\n if (e === null) return null;\n if (typeof e !== \"object\") return e;\n const rec = e as Record<string, unknown>;\n const type = rec[typeField] as string;\n const childProperty = property.oneOf?.properties[type];\n if (!type || !childProperty) return e;\n return {\n [typeField]: type,\n [valueField]: traverseValueProperty(rec[valueField], childProperty, operation)\n };\n });\n } else {\n value = inputValue;\n }\n } else {\n value = operation(inputValue, property);\n }\n\n return value;\n}\n\n/**\n * Relation reference types used throughout the server layer.\n * These replace the 50+ manual `{ id, path, __type: \"relation\" }` constructions.\n */\nexport interface RelationRef {\n readonly id: string | number;\n readonly path: string;\n readonly __type: \"relation\";\n}\n\nexport interface RelationRefWithData extends RelationRef {\n readonly data: Entity;\n}\n\n/**\n * Create a lightweight relation stub for admin views.\n * Replaces inline `{ id, path, __type: \"relation\" }` object literals.\n */\nexport function createRelationRef(id: string | number, path: string): RelationRef {\n return { id,\npath,\n__type: \"relation\" };\n}\n\n/**\n * Create a hydrated relation reference that includes the full entity data.\n * Used when entity data has been pre-fetched (e.g., via batch loading or JOINs).\n */\nexport function createRelationRefWithData(id: string | number, path: string, data: Entity): RelationRefWithData {\n return { id,\npath,\n__type: \"relation\",\ndata };\n}\n","import {\n CollectionConfig,\n Properties,\n Property\n} from \"@rebasepro/types\";\nimport { isPropertyBuilder } from \"./entities\";\n\nexport function sortProperties<M extends Record<string, unknown>>(properties: Properties, propertiesOrder?: string[]): Properties {\n try {\n const propertiesKeys = Object.keys(properties);\n // If no propertiesOrder, just use the original keys order\n if (!propertiesOrder || propertiesOrder.length === 0) {\n return propertiesKeys\n .map((key) => {\n const property = properties[key] as Property;\n if (!isPropertyBuilder(property) && property?.type === \"map\" && property.properties) {\n return ({\n [key]: {\n ...property,\n properties: sortProperties(property.properties, property.propertiesOrder)\n }\n });\n } else {\n return ({ [key]: property });\n }\n })\n .reduce((a: Properties, b: Properties) => ({ ...a,\n...b }), {}) as Properties;\n }\n\n // Filter propertiesOrder to only include TOP-LEVEL property keys that exist\n // (ignore nested keys like \"data.mode\" - they are for column ordering, not property filtering)\n const validOrderKeys = (propertiesOrder as string[]).filter(key => {\n // Only include top-level keys (no dots) that exist in properties\n return !key.includes(\".\") && properties[key];\n });\n\n // Track which properties we've processed\n const processedKeys = new Set<string>(validOrderKeys);\n\n // Build result starting with ordered properties\n const orderedResult = validOrderKeys\n .map((key) => {\n const property = properties[key] as Property;\n if (!isPropertyBuilder(property) && property?.type === \"map\" && property.properties) {\n return ({\n [key]: {\n ...property,\n properties: sortProperties(property.properties, property.propertiesOrder)\n }\n });\n } else {\n return ({ [key]: property });\n }\n })\n .reduce((a: Properties, b: Properties) => ({ ...a,\n...b }), {}) as Properties;\n\n // Append any properties that were NOT in propertiesOrder (so they don't disappear!)\n const missingProperties = propertiesKeys\n .filter(key => !processedKeys.has(key))\n .map((key) => {\n const property = properties[key] as Property;\n if (!isPropertyBuilder(property) && property?.type === \"map\" && property.properties) {\n return ({\n [key]: {\n ...property,\n properties: sortProperties(property.properties, property.propertiesOrder)\n }\n });\n } else {\n return ({ [key]: property });\n }\n })\n .reduce((a: Properties, b: Properties) => ({ ...a,\n...b }), {}) as Properties;\n\n return { ...orderedResult,\n...missingProperties };\n } catch (e) {\n console.error(\"Error sorting properties\", e);\n return properties;\n }\n}\n\n/**\n * A copy of `collections` ordered by slug.\n *\n * Every generator that turns collections into a file is order-dependent, and\n * every one of them is compared against its own output — `rebase doctor`\n * regenerates in memory and diffs, `generate-sdk && git diff --exit-code` gates\n * CI. While only the *writers* sorted, a project whose `readdirSync` order\n * differed from its slug order was reported permanently out of date, and the\n * fix the message printed rewrote the file in the order it was already in. The\n * generators sort themselves now, so no caller can get this wrong.\n *\n * A slug-less collection is left to the generator's own validation, which names\n * the offending collection; sorting must not throw first.\n */\nexport function sortCollectionsBySlug<C extends { slug?: string }>(collections: readonly C[]): C[] {\n return [...collections].sort((a, b) => (a.slug ?? \"\").localeCompare(b.slug ?? \"\"));\n}\n\nexport function getPrimaryKeys<M extends Record<string, unknown>>(collection: CollectionConfig<M>): Extract<keyof M, string>[] {\n const properties = collection.properties;\n if (!properties) {\n return [\"id\"] as Extract<keyof M, string>[];\n }\n const ids = Object.entries(properties)\n .filter(([key, prop]) => typeof prop === \"object\" && prop !== null && \"isId\" in prop && Boolean(prop.isId))\n .map(([key]) => key);\n\n if (ids.length > 0) {\n return ids as Extract<keyof M, string>[];\n }\n return [\"id\"] as Extract<keyof M, string>[];\n}\n","/**\n * Row identity: the address of a row, and how to derive it.\n *\n * Postgres has no `id`. A row is identified by its primary key — one or more\n * columns, with any names and any types. `id` is something we synthesize on top\n * of that: a single string token, because the admin needs *one* value it can put\n * in a URL (`/products/1:::2`), use as a cache key, and hang a relation ref off.\n *\n * That token is an address, not data. It is derived from the row's columns and\n * never stored in them — a row is exactly its columns, with their real types.\n * Writing the address back into the row is what used to rename primary keys\n * (`sku` → `id`) and restringify them (`42` → `\"42\"`) on the way out.\n *\n * These live in `common` because both sides need them and must agree exactly:\n * the driver parses an incoming address back into key columns, and the admin\n * derives the address from a row it was served.\n */\n\n/**\n * A primary-key column: its name, the type it round-trips as, and whether it is\n * a UUID (which is a string despite sometimes being described as an id \"number\").\n */\nexport interface PrimaryKeyInfo {\n fieldName: string;\n type: \"string\" | \"number\";\n isUUID?: boolean;\n}\n\n/** Separator between the parts of a composite address. */\nexport const COMPOSITE_ID_SEPARATOR = \":::\";\n\n/** The eight-four-four-four-twelve shape of a UUID, any version. */\nconst UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/** Whether one address part can be a value of the column it addresses. */\nfunction partIsAddressable(part: string | number, pk: PrimaryKeyInfo): boolean {\n if (pk.isUUID) return UUID_PATTERN.test(String(part));\n if (pk.type === \"number\") {\n return typeof part === \"number\"\n ? Number.isFinite(part)\n : !isNaN(parseInt(String(part), 10));\n }\n return true;\n}\n\n/**\n * Whether an address could name a row at all, before asking the database.\n *\n * A `uuid` column cannot hold `\"new\"`, and an `integer` column cannot hold\n * `\"abc\"` — so the answer to \"which row is this\" is \"none\", and that is a 404,\n * not a failure. Postgres cannot say so politely: the comparison never runs, it\n * raises `22P02` and aborts the enclosing transaction, after which every\n * further statement returns the far less helpful `25P02`.\n *\n * `isUUID` must come from the column, not from `isId: \"uuid\"` in a config: the\n * config is a claim about a key, and a `text` column that holds ids of some\n * other shape is a working app this must not start rejecting.\n */\nexport function isAddressableId(idValue: string | number, primaryKeys: PrimaryKeyInfo[]): boolean {\n if (primaryKeys.length === 0) return false;\n if (primaryKeys.length === 1) return partIsAddressable(idValue, primaryKeys[0]);\n\n const parts = String(idValue).split(COMPOSITE_ID_SEPARATOR);\n if (parts.length !== primaryKeys.length) return false;\n return parts.every((part, i) => partIsAddressable(part, primaryKeys[i]));\n}\n\n/**\n * Derive a row's address from its key columns.\n *\n * Single key → the value as a string. Composite → each part joined by\n * {@link COMPOSITE_ID_SEPARATOR}, in primary-key order, which is what\n * {@link parseIdValues} expects to invert.\n */\nexport function buildCompositeId(values: Record<string, unknown>, primaryKeys: PrimaryKeyInfo[]): string {\n if (primaryKeys.length === 0) {\n return \"\";\n }\n if (primaryKeys.length === 1) {\n return String(values[primaryKeys[0].fieldName] ?? \"\");\n }\n return primaryKeys.map(pk => String(values[pk.fieldName] ?? \"\")).join(COMPOSITE_ID_SEPARATOR);\n}\n\n/**\n * Invert {@link buildCompositeId}: turn an address back into key columns, each\n * coerced to the type its column actually round-trips as.\n *\n * This is the boundary where a URL segment becomes a query parameter, so a\n * malformed address must throw rather than silently produce a query that\n * matches the wrong row (or none).\n */\nexport function parseIdValues(idValue: string | number, primaryKeys: PrimaryKeyInfo[]): Record<string, string | number> {\n const result: Record<string, string | number> = {};\n\n if (primaryKeys.length === 0) {\n return result;\n }\n\n if (primaryKeys.length === 1) {\n const pk = primaryKeys[0];\n if (pk.type === \"number\" && !pk.isUUID) {\n const parsed = typeof idValue === \"number\" ? idValue : parseInt(String(idValue), 10);\n if (isNaN(parsed)) {\n throw new Error(`Invalid numeric ID: ${idValue}`);\n }\n result[pk.fieldName] = parsed;\n } else {\n result[pk.fieldName] = String(idValue);\n }\n return result;\n }\n\n // Composite key\n const parts = String(idValue).split(COMPOSITE_ID_SEPARATOR);\n if (parts.length !== primaryKeys.length) {\n throw new Error(`Composite ID parts mismatch. Expected ${primaryKeys.length}, got ${parts.length} for ID: ${idValue}`);\n }\n\n for (let i = 0; i < primaryKeys.length; i++) {\n const pk = primaryKeys[i];\n const val = parts[i];\n if (pk.type === \"number\" && !pk.isUUID) {\n const parsed = parseInt(val, 10);\n if (isNaN(parsed)) {\n throw new Error(`Invalid numeric ID component: ${val}`);\n }\n result[pk.fieldName] = parsed;\n } else {\n result[pk.fieldName] = val;\n }\n }\n\n return result;\n}\n\n/**\n * The primary keys of a collection, as declared by its properties.\n *\n * This is the only tier both sides can read, because it is the only one written\n * in the config: the postgres driver can also infer keys from the Drizzle\n * schema, which the browser never sees and is never sent — the admin compiles\n * the collection files into its own bundle rather than being served them. A key\n * that lives only in the Drizzle schema is therefore invisible here, and the\n * server says so at boot (`warnOnKeysTheAdminCannotResolve`) naming the `isId`\n * to add.\n *\n * Returns an empty array when a collection declares none, which callers must\n * treat as \"not addressable\" rather than defaulting to `id`: guessing a key\n * that is not the real one produces confidently wrong addresses.\n */\nexport function getDeclaredPrimaryKeys(collection: {\n properties?: Record<string, unknown>;\n}): PrimaryKeyInfo[] {\n const properties = collection.properties;\n if (!properties) return [];\n\n const keys: PrimaryKeyInfo[] = [];\n for (const [fieldName, propRaw] of Object.entries(properties)) {\n const prop = propRaw as { type?: string; isId?: unknown } | undefined;\n if (!prop || typeof prop !== \"object\") continue;\n if (!(\"isId\" in prop) || !prop.isId) continue;\n keys.push({\n fieldName,\n type: prop.type === \"number\" ? \"number\" : \"string\",\n isUUID: prop.isId === \"uuid\"\n });\n }\n return keys;\n}\n\n/**\n * The keys to address a collection's rows with, resolved the way the driver\n * resolves them — minus the tier the browser cannot reach.\n *\n * The postgres driver tries, in order: properties marked `isId`; the primary\n * keys of the Drizzle schema; and finally a column literally named `id`. Only\n * the first and last are visible in a `CollectionConfig`, which is what both\n * sides share.\n *\n * So the two agree except on a collection that declares no `isId` and whose key\n * is known only to Drizzle. There, the driver reads the real key, and this\n * either resolves nothing (reported to the console by the caller) or — if the\n * table happens to have an unrelated `id` property — resolves `id`, which is\n * the wrong key and cannot be detected from here: the addresses look right and\n * route wrong. Only the config can settle it, so the server names both cases\n * at boot (`warnOnKeysTheAdminCannotResolve`) with the `isId` to add.\n */\nexport function resolvePrimaryKeys(collection: {\n properties?: Record<string, unknown>;\n}): PrimaryKeyInfo[] {\n const declared = getDeclaredPrimaryKeys(collection);\n if (declared.length > 0) return declared;\n\n const idProp = collection.properties?.id as { type?: string } | undefined;\n if (idProp && typeof idProp === \"object\") {\n return [{ fieldName: \"id\",\ntype: idProp.type === \"number\" ? \"number\" : \"string\" }];\n }\n\n return [];\n}\n","import { EnumValueConfig, EnumValues } from \"@rebasepro/types\";\n\nexport function enumToObjectEntries(enumValues: EnumValues): EnumValueConfig[] {\n if (Array.isArray(enumValues)) {\n return enumValues;\n } else {\n return Object.entries(enumValues).map(([id, value]) => {\n if (typeof value === \"string\") {\n return {\n id,\n label: value\n }\n } else {\n return {\n ...value,\n id\n }\n }\n });\n }\n}\n\nexport function getLabelOrConfigFrom(enumValues: EnumValueConfig[], key?: string | number): EnumValueConfig | undefined {\n if (key === null || key === undefined) return undefined;\n return enumValues.find((entry) => String(entry.id) === String(key));\n}\n","import {\n CollectionConfig,\n Relation,\n ResolvedRelation\n} from \"@rebasepro/types\";\nimport { generateForeignKeyName, toSnakeCase } from \"@rebasepro/utils\";\n\nimport { getTableName } from \"./relations\";\n\n/**\n * Fill in a relation's defaults.\n *\n * This replaces `sanitizeRelation`, which had to work out *which kind of link\n * you meant* from whichever optional fields happened to be set — 194 lines of\n * it, including a pass that inspected the target collection's own relations to\n * decide whether a `many`/`inverse` pair was a one-to-many or the far side of a\n * many-to-many, wrapped in a `try/catch` that fell through to the wrong answer\n * when it could not tell. Two consumers running that logic at different moments\n * could reach different conclusions about the same relation.\n *\n * With the kind declared there is nothing to work out. What remains is\n * defaulting — a table name, a column name — which is deterministic, depends\n * only on the relation and its two endpoints, and cannot fail. That is why this\n * function returns rather than throws, and why it needs no cache to be\n * consistent.\n */\nexport function resolveRelation(\n relation: Relation,\n sourceCollection: CollectionConfig,\n propertyKey?: string\n): ResolvedRelation {\n const target = relation.target;\n if (typeof target !== \"function\") {\n throw new Error(\n `Relation${relation.relationName ? ` '${relation.relationName}'` : \"\"} on ` +\n `'${sourceCollection.slug}' has no \\`target\\`. Give it a thunk: \\`target: () => otherCollection\\`.`\n );\n }\n\n const targetCollection = callTarget(relation, sourceCollection, propertyKey, target);\n\n // The name is the address: the `include` key, the admin tab, and the\n // segment of a nested path. Declared name wins, then the declaring\n // property's key, then the target's slug.\n const relationName = relation.relationName ?? propertyKey ?? toSnakeCase(targetCollection.slug);\n\n const shared: Pick<ResolvedRelation, \"relationName\" | \"target\" | \"targetSlug\" | \"onUpdate\" | \"onDelete\" | \"overrides\" | \"validation\"> = {\n relationName,\n // Normalised, not the thunk as written. Resolution reads the target once\n // and every later consumer calls it again — the driver building a join,\n // the DDL and policy generators, the admin's relation fields — so\n // handing back the raw thunk would give all of them the module namespace\n // `callTarget` just looked past, and the fix would hold only for the\n // fields resolution happens to read here. Still lazy: same call at the\n // same moment, one unwrap on the way out.\n target: () => unwrapModuleNamespace(target()) as CollectionConfig,\n targetSlug: targetCollection.slug,\n onUpdate: relation.onUpdate,\n onDelete: relation.onDelete,\n overrides: relation.overrides,\n validation: relation.validation\n };\n\n const sourceName = toSnakeCase(sourceCollection.slug ?? sourceCollection.name);\n\n switch (relation.kind) {\n case \"belongsTo\":\n return {\n ...shared,\n kind: \"belongsTo\",\n cardinality: \"one\",\n writable: true,\n shared: false,\n localKey: relation.localKey ?? generateForeignKeyName(relationName)\n };\n\n case \"hasOne\":\n return {\n ...shared,\n kind: \"hasOne\",\n cardinality: \"one\",\n writable: true,\n shared: false,\n foreignKeyOnTarget: relation.foreignKeyOnTarget ?? generateForeignKeyName(sourceName),\n sourceKey: relation.sourceKey\n };\n\n case \"hasMany\":\n return {\n ...shared,\n kind: \"hasMany\",\n cardinality: \"many\",\n writable: true,\n shared: false,\n foreignKeyOnTarget: relation.foreignKeyOnTarget ?? generateForeignKeyName(sourceName),\n // Not defaulted: the source's primary key needs the driver's\n // schema to resolve, which resolution does not have. `undefined`\n // means \"the primary key\" — see `ResolvedHasMany.sourceKey`.\n sourceKey: relation.sourceKey\n };\n\n case \"manyToMany\": {\n const sourceTable = getTableName(sourceCollection);\n const targetTable = getTableName(targetCollection);\n return {\n ...shared,\n kind: \"manyToMany\",\n cardinality: \"many\",\n writable: true,\n shared: true,\n through: {\n // Sorted so both sides of the same link derive the same\n // table without having to agree in advance.\n table: relation.through?.table ?? [sourceTable, targetTable].sort().join(\"_\"),\n sourceColumn: relation.through?.sourceColumn ?? generateForeignKeyName(sourceName),\n targetColumn: relation.through?.targetColumn ?? generateForeignKeyName(relationName)\n }\n };\n }\n\n case \"via\":\n return {\n ...shared,\n kind: \"via\",\n cardinality: relation.cardinality,\n writable: false,\n // A join chain reaches rows that other parents reach too, and\n // Rebase does not know which hop, if any, is a link it owns.\n shared: true,\n joinPath: relation.joinPath\n };\n\n default: {\n // Exhaustive: a new kind is a compile error here, not a silent\n // fall-through to whatever shape happened to match first.\n const exhaustive: never = relation;\n throw new Error(`Unknown relation kind: ${JSON.stringify(exhaustive)}`);\n }\n }\n}\n\n/** How this relation is addressed in an error message, before it has a resolved name. */\nfunction describe(relation: Relation, sourceCollection: CollectionConfig, propertyKey?: string): string {\n const name = relation.relationName ?? propertyKey;\n return `Relation${name ? ` '${name}'` : \"\"} on '${sourceCollection.slug}'`;\n}\n\n/**\n * A module namespace, unwrapped to the collection it exports.\n *\n * A cycle transpiled to CommonJS does not hand the importing module the\n * *default export* — it hands it the module object, `{ __esModule: true,\n * default: … }`, captured before the exporting module finished evaluating. The\n * `default` slot fills in later, so by the time a lazy `target` thunk runs the\n * collection is sitting right there, one level down. Returning the namespace is\n * never a thing a thunk means to do, and there is exactly one reading of it.\n *\n * Only unwrapped when the inner value is itself a collection: a `default` that\n * is not one is a genuinely wrong thunk, and it should reach the error below\n * rather than be quietly swapped in.\n */\nfunction unwrapModuleNamespace(value: unknown): unknown {\n if (!value || typeof value !== \"object\") return value;\n if ((value as { slug?: unknown }).slug) return value;\n const inner = (value as { default?: unknown }).default;\n return inner && typeof inner === \"object\" && (inner as { slug?: unknown }).slug ? inner : value;\n}\n\n/**\n * Call the `target` thunk, and translate the ways an import cycle breaks it into\n * an error that names the cause — or, where the value is recoverable, into the\n * collection the thunk meant.\n *\n * The thunk exists to defer the reference until every module has finished\n * evaluating, and for a cycle that closes at import time it does. Two cycles\n * leave the binding permanently unusable:\n *\n * - **ESM/TDZ.** `const` and `class` bindings in a not-yet-evaluated module are\n * in the temporal dead zone, so reading one throws `ReferenceError: x is not\n * defined`. The stack points at the thunk — a one-line arrow function that is\n * obviously fine — and says nothing about the cycle that made it throw.\n * - **CJS interop, unresolved.** The half-initialised module object has no\n * `default` yet, the import resolves to `undefined`, and the thunk returns it\n * without complaint. That one used to surface here as \"did not resolve to a\n * collection\", which is true and unhelpful.\n *\n * Both mean the same thing, and the fix for both is the same: break the cycle,\n * or move the relation into the collection that does not close it.\n *\n * A third shape is *not* an error, and used to be reported as one. A loader that\n * transpiles ESM to CJS — jiti, which is what `rebase generate-sdk` and\n * `rebase build` load collections with — gives the module entered second in a\n * cycle a namespace object rather than the default export, and never replaces it\n * with a live binding. The thunk then returns `{ __esModule: true, default: … }`\n * holding the fully-initialised collection. Native ESM resolves the same thunk\n * to the collection directly, so this was a loader artefact reported as an\n * authoring mistake, and the advice it gave — make the target a lazy thunk — was\n * already satisfied by the code it was rejecting. Bidirectional relations make\n * these cycles unavoidable, and the lazy thunk is this framework's own answer to\n * them, so {@link unwrapModuleNamespace} takes the collection and moves on.\n */\nfunction callTarget(\n relation: Relation,\n sourceCollection: CollectionConfig,\n propertyKey: string | undefined,\n target: Relation[\"target\"]\n): ReturnType<Relation[\"target\"]> {\n let targetCollection: ReturnType<Relation[\"target\"]> | undefined;\n try {\n targetCollection = unwrapModuleNamespace(target()) as ReturnType<Relation[\"target\"]>;\n } catch (error) {\n // A ReferenceError from inside the thunk is a binding that was never\n // initialised — nothing else in a one-expression arrow can raise one.\n if (error instanceof ReferenceError) {\n throw new Error(\n `${describe(relation, sourceCollection, propertyKey)} targets a collection that is not ` +\n `initialized yet — almost always an import cycle between the two collection files. ` +\n `Break the cycle (move the shared piece into a third module, or import the target ` +\n `lazily) so the target's module finishes evaluating before the registry is built.`,\n { cause: error }\n );\n }\n throw error;\n }\n\n if (!targetCollection?.slug) {\n throw new Error(\n `${describe(relation, sourceCollection, propertyKey)} has a \\`target\\` that resolved to ` +\n `${targetCollection === undefined ? \"`undefined`\" : \"something that is not a collection\"}. ` +\n (targetCollection === undefined\n ? \"Under CommonJS interop an import cycle resolves the default import to `undefined`, \" +\n \"so check whether this collection and its target import each other. Otherwise the thunk \" +\n \"is returning the wrong value — it must return the collection itself, not a promise or a module.\"\n : typeof (targetCollection as { then?: unknown }).then === \"function\"\n ? \"The thunk returned a promise — `target: () => import(\\\"./other\\\")` is asynchronous. \" +\n \"Import the collection at the top of the file and return the binding: \" +\n \"`target: () => otherCollection`.\"\n : \"The thunk must return a collection config with a `slug`.\")\n );\n }\n\n return targetCollection;\n}\n","import { CollectionConfig, isRelationalCollectionConfig, Property, ResolvedRelation, RelationProperty } from \"@rebasepro/types\";\nimport { toSnakeCase, toWireKey } from \"@rebasepro/utils\";\n\nimport { resolveRelation } from \"./resolve-relation\";\n\n/**\n * Whether the target rows are shared with other parents — a many-to-many, or a\n * multi-hop `via` chain.\n *\n * Decides what a write \"through\" the relation may touch: a shared target\n * belongs to every parent that links it, so the parent owns the *link* and not\n * the row. The backend enforces that (an unlink rather than a delete) and the\n * admin renders it (remove-from-parent rather than delete).\n *\n * Now a field on the resolved relation rather than a re-derivation, so both\n * sides read the same answer instead of each computing one.\n */\nexport function isJunctionBackedRelation(relation: ResolvedRelation): boolean {\n return relation.shared;\n}\n\n/** WeakMap cache — same collection instance always yields the same relation map. */\nconst _resolvedRelationsCache = new WeakMap<CollectionConfig, Record<string, ResolvedRelation>>();\n\n/**\n * Every relation a collection declares, keyed by the name it is addressed by.\n *\n * A relation reaches the map from either of two places — the collection's\n * `relations` array, or a `relation` property that declares one inline — and is\n * keyed by its resolved `relationName`, which is what a nested path segment,\n * an `include` key and an admin tab all match against.\n *\n * Resolution no longer swallows failures. It used to wrap each relation in a\n * `try/catch` that dropped anything it could not work out, so a\n * mis-declared relation silently vanished instead of being reported; with the\n * kind declared, the only remaining failure is a `target` that does not resolve,\n * which is worth hearing about.\n */\nexport function resolveCollectionRelations(\n collection: CollectionConfig\n): Record<string, ResolvedRelation> {\n const cached = _resolvedRelationsCache.get(collection);\n if (cached) return cached;\n\n if (!isRelationalCollectionConfig(collection)) return {};\n\n const relations: Record<string, ResolvedRelation> = {};\n\n for (const relation of collection.relations ?? []) {\n const resolved = resolveRelation(relation, collection);\n relations[resolved.relationName] = resolved;\n }\n\n // A property declaring a relation inline is registered under the property\n // key as well: the fetch layer hydrates the result back onto that key, and\n // it is the name the admin addresses the field by.\n for (const [propertyKey, property] of Object.entries(collection.properties ?? {})) {\n if ((property as Property)?.type !== \"relation\") continue;\n const declared = (property as RelationProperty).relation;\n if (!declared || relations[propertyKey]) continue;\n\n relations[propertyKey] = resolveRelation(declared, collection, propertyKey);\n }\n\n _resolvedRelationsCache.set(collection, relations);\n return relations;\n}\n\n/**\n * The path of the collection a relation property points at, derived from the\n * property alone.\n *\n * A preview holds a property and a value and no collection, so it cannot call\n * `resolveRelationProperty`. It does not need to: both forms that carry a\n * target — the stamped `resolvedRelation` and the inline `relation` — name it\n * directly. Only the third form, a relation declared by name in the\n * collection's `relations` array, is out of reach, and that one has no target\n * to read without the collection anyway.\n *\n * This is what lets a preview render a relation column that arrived as a bare\n * foreign key: the id says *which* row, the declared target says *which\n * collection*, and `RelationPreview` fetches the rest. Without it a scalar id\n * is indistinguishable from a value of the wrong type.\n */\nexport function getRelationTargetPath(property: RelationProperty): string | undefined {\n const stamped = property.resolvedRelation?.targetSlug;\n if (stamped) return stamped;\n\n const target = property.relation?.target;\n if (typeof target !== \"function\") return undefined;\n try {\n return target()?.slug;\n } catch (_e) {\n // A thunk reaching into a module that has not finished initialising:\n // there is no target to name yet, and a preview is not worth throwing over.\n return undefined;\n }\n}\n\nexport function getTableName(collection: CollectionConfig): string {\n if (isRelationalCollectionConfig(collection)) {\n return collection.table ?? toSnakeCase(collection.slug) ?? toSnakeCase(collection.name);\n }\n return toSnakeCase(collection.slug) ?? toSnakeCase(collection.name);\n}\n\nexport function getTableVarName(tableName: string): string {\n return tableName.replace(/_([a-z])/g, (_, char) => char.toUpperCase());\n}\n\nexport function getEnumVarName(tableName: string, propName: string): string {\n const tableVar = getTableVarName(tableName);\n const propVar = propName.charAt(0).toUpperCase() + propName.slice(1);\n return `${tableVar}${propVar}`;\n}\n\nexport function getColumnName(fullColumn: string): string {\n return fullColumn.includes(\".\") ? fullColumn.split(\".\").pop()! : fullColumn;\n}\n\n/**\n * The field key a database column is served and addressed under.\n *\n * A column has two names and they are not the same name. `author_id` is what\n * Postgres stores; `authorId` is the key on the JSON row, the key in the\n * generated Drizzle table, and the key a caller writes in `where` and\n * `orderBy`. Every place that starts from a column and has to reach a row, a\n * Drizzle table or a payload goes through here, so there is one answer rather\n * than one per call site — the two that disagreed put `displayName` and\n * `author_id` on the same API.\n *\n * A declared property is the authority when there is one, because its key *is*\n * the wire name and `columnName` is the only thing that ever renamed the\n * column:\n *\n * 1. an explicit `columnName` equal to this column;\n * 2. a property whose key is literally the column (an author who wrote\n * `author_id:` meant `author_id` on the wire, and gets it);\n * 3. a property whose key snake-cases to the column, which is the default\n * mapping — `authorId` → `author_id`.\n *\n * With no property in the way — a foreign key derived from a relation, which\n * usually has none — the name is derived: {@link toWireKey}.\n *\n * Note the fallback is *not* the column verbatim. That was the old behaviour\n * and it is precisely the defect: a derived foreign key reached the wire under\n * its column name while every hand-authored field beside it was camelCase.\n */\nexport function fieldKeyForColumn(collection: CollectionConfig | undefined, column: string): string {\n const properties = collection?.properties;\n if (properties) {\n for (const [key, prop] of Object.entries(properties)) {\n const columnName = (prop as { columnName?: unknown } | undefined)?.columnName;\n if (typeof columnName === \"string\" && columnName === column) return key;\n }\n for (const key of Object.keys(properties)) {\n if (key === column) return key;\n if (toSnakeCase(key) === column) return key;\n }\n }\n return toWireKey(column);\n}\n\n/**\n * Look up a relation by key with forgiving normalization.\n *\n * `resolveCollectionRelations` stores each relation under a single canonical\n * key (no aliases). This helper tries the given key as-is, then falls back to\n * slug form (underscores → hyphens) and snake_case form (hyphens → underscores)\n * so that callers that receive a key from external input (URL path segments,\n * user-provided config, etc.) can still find the right entry.\n */\nexport function findRelation(\n resolvedRelations: Record<string, ResolvedRelation>,\n key: string\n): ResolvedRelation | undefined {\n // Exact match first\n if (resolvedRelations[key]) return resolvedRelations[key];\n\n // Try slug form (e.g. \"company_id\" → \"company-id\")\n const slugKey = key.replace(/_/g, \"-\");\n if (slugKey !== key && resolvedRelations[slugKey]) return resolvedRelations[slugKey];\n\n // Try snake_case form (e.g. \"company-id\" → \"company_id\")\n const snakeKey = key.replace(/-/g, \"_\");\n if (snakeKey !== key && resolvedRelations[snakeKey]) return resolvedRelations[snakeKey];\n\n return undefined;\n}\n","import {\n ArrayProperty,\n AuthState,\n CollectionConfig,\n EnumValueConfig,\n EnumValues,\n NumberProperty,\n Properties,\n Property,\n RelationProperty,\n ResolvedRelation,\n StringProperty,\n getDataSourceCapabilities,\n getDeclaredSubcollections,\n type EntityChildView\n} from \"@rebasepro/types\";\n\ntype PropertyConfig = { property: unknown; [key: string]: unknown };\nimport { isPropertyBuilder } from \"./entities\";\nimport { enumToObjectEntries } from \"./enums\";\nimport { DEFAULT_ONE_OF_TYPE } from \"./common\";\nimport { isDefaultFieldConfigId } from \"@rebasepro/utils\";\nimport { getIn, mergeDeep } from \"@rebasepro/utils\";\nimport { isJunctionBackedRelation, resolveCollectionRelations } from \"./relations\";\nimport { resolveRelation } from \"./resolve-relation\";\n\n/**\n * Resolve property builders, enums and arrays.\n */\n\nexport type ResolvePropertyProps<M extends Record<string, unknown> = Record<string, unknown>> = {\n property: Property\n propertyKey?: string,\n values?: Partial<M>,\n previousValues?: Partial<M>,\n path?: string,\n entityId?: string | number,\n index?: number,\n propertyConfigs?: Record<string, PropertyConfig>;\n ignoreMissingFields?: boolean;\n authController: AuthState;\n}\n\nexport function resolveProperty<M extends Record<string, unknown> = Record<string, unknown>>(props: ResolvePropertyProps<M>): Property | null {\n\n const {\n property,\n ignoreMissingFields = false,\n ...rest\n } = props;\n\n let resultProperty: Property;\n\n if (isPropertyBuilder(property)) {\n const path = rest.path;\n if (!path) {\n // When path is not available (e.g. in preview contexts), skip dynamic\n // resolution and use the property as-is without dynamic modifications.\n resultProperty = property as Property;\n } else {\n const usedPropertyValue = rest.propertyKey ? getIn(rest.values, rest.propertyKey) : undefined;\n const dynamicProps = property.dynamicProps?.({\n ...rest,\n path,\n propertyValue: usedPropertyValue,\n values: rest.values ?? {},\n previousValues: rest.previousValues ?? rest.values ?? {}\n });\n resultProperty = mergeDeep(property, dynamicProps ?? {});\n }\n } else {\n resultProperty = property as Property;\n }\n\n // Apply dynamic properties if they exist\n if (resultProperty?.dynamicProps && rest.path) {\n const path = rest.path;\n const usedPropertyValue = rest.propertyKey ? getIn(rest.values, rest.propertyKey) : undefined;\n const dynamicPropsResult = resultProperty.dynamicProps({\n ...rest,\n path,\n propertyValue: usedPropertyValue,\n values: rest.values ?? {},\n previousValues: rest.previousValues ?? rest.values ?? {}\n });\n\n if (dynamicPropsResult) {\n resultProperty = mergeDeep(resultProperty, dynamicPropsResult);\n }\n }\n\n let resolvedProperty: Property | null;\n\n if (resultProperty?.type === \"map\" && resultProperty.properties) {\n const properties = resolveProperties({\n ignoreMissingFields,\n ...rest,\n properties: resultProperty.properties\n });\n resolvedProperty = {\n ...resultProperty,\n properties\n } as Property;\n } else if (resultProperty?.type === \"array\") {\n resolvedProperty = resultProperty;\n } else if ((resultProperty?.type === \"string\" || resultProperty?.type === \"number\") && resultProperty.enum) {\n resolvedProperty = resolvePropertyEnum(resultProperty);\n } else {\n resolvedProperty = resultProperty;\n }\n\n if (resolvedProperty?.propertyConfig && !isDefaultFieldConfigId(resolvedProperty.propertyConfig)) {\n const cmsFields = rest.propertyConfigs;\n if (!cmsFields && !ignoreMissingFields) {\n throw Error(`Trying to resolve a property with key '${resolvedProperty.propertyConfig}' that inherits from a custom property config but no custom property configs were provided. Use the property 'propertyConfigs' in your app config to provide them`);\n }\n const customField: PropertyConfig | undefined = cmsFields?.[resolvedProperty.propertyConfig];\n if (!customField) {\n console.warn(`Trying to resolve a property with key '${resolvedProperty.propertyConfig}' that inherits from a custom property config but no custom property config with that key was found. Check the 'propertyConfigs' in your app config`)\n return resolvedProperty;\n }\n if (customField.property) {\n const restConfigProperty = { ...customField.property } as Record<string, unknown>;\n delete restConfigProperty.propertyConfig;\n const customFieldProperty = resolveProperty({\n property: { name: \"\",\n...restConfigProperty } as Property,\n ignoreMissingFields,\n ...rest\n });\n if (customFieldProperty) {\n resolvedProperty = mergeDeep(customFieldProperty, resolvedProperty);\n }\n }\n\n }\n\n return resolvedProperty;\n}\n\n/**\n * The resolved relation a relation property refers to.\n *\n * Normalization stamps `resolvedRelation` onto the property, so this is usually\n * a field read. It falls back to resolving from the collection for properties\n * that never went through the registry — a preview, or a form rendered straight\n * from an authored config.\n */\nexport function resolveRelationProperty(\n property: RelationProperty,\n collection: CollectionConfig,\n propertyKey?: string\n): ResolvedRelation {\n if (property.resolvedRelation) return property.resolvedRelation;\n\n if (property.relation) {\n return resolveRelation(property.relation, collection, propertyKey);\n }\n\n const name = propertyKey ?? \"\";\n const declared = resolveCollectionRelations(collection)[name];\n if (!declared) {\n throw Error(\n `Relation property '${name || \"(unnamed)\"}' on '${collection.slug}' declares no \\`relation\\`, ` +\n \"and the collection has no relation of that name.\"\n );\n }\n return declared;\n}\n\n/**\n * Resolve enum aliases for a string or number property\n * @param property\n */\nexport function resolvePropertyEnum(property: StringProperty | NumberProperty): StringProperty | NumberProperty {\n if (typeof property.enum === \"object\") {\n return {\n ...property,\n enum: enumToObjectEntries(property.enum)?.filter((value) => value && (value.id || value.id === 0) && value.label) ?? []\n };\n }\n return property as StringProperty | NumberProperty;\n}\n\n/**\n * Resolve enums and arrays for properties\n * @param properties\n * @param value\n */\nexport function resolveProperties<M extends Record<string, unknown>>({\n propertyKey,\n properties,\n ignoreMissingFields,\n ...props\n}: {\n propertyKey?: string,\n properties: Properties,\n values?: Partial<M>,\n previousValues?: Partial<M>,\n path?: string,\n entityId?: string | number,\n index?: number,\n propertyConfigs?: Record<string, PropertyConfig>;\n ignoreMissingFields?: boolean;\n authController: AuthState;\n}): Properties {\n return Object.entries<Property>(properties as Record<string, Property>)\n .map(([key, property]) => {\n const childResolvedProperty = resolveProperty({\n propertyKey: propertyKey ? `${propertyKey}.${key}` : undefined,\n property: property,\n ignoreMissingFields,\n ...props\n });\n if (!childResolvedProperty) return {};\n return {\n [key]: childResolvedProperty\n };\n })\n .filter((a) => a !== null)\n .reduce((a, b) => ({ ...a,\n...b }), {}) as Properties;\n}\n\nexport function resolveArrayProperties<M>({\n propertyKey,\n property,\n ignoreMissingFields = false,\n ...props\n}: {\n propertyKey?: string,\n property: ArrayProperty,\n values?: Partial<M>,\n previousValues?: Partial<M>,\n path?: string,\n entityId?: string | number,\n index?: number,\n propertyConfigs?: Record<string, PropertyConfig>;\n ignoreMissingFields?: boolean;\n authController: AuthState;\n}): Property[] {\n const propertyValue = propertyKey ? getIn(props.values, propertyKey) : undefined;\n\n if (property.of) {\n if (Array.isArray(property.of)) {\n return property.of.map((p, index) => {\n return resolveProperty({\n propertyKey: `${propertyKey}.${index}`,\n property: p as Property,\n ignoreMissingFields,\n ...props,\n index\n });\n }) as Property[];\n } else {\n const of = property.of;\n const resolvedProperties = getArrayResolvedProperties({\n propertyValue,\n propertyKey,\n property,\n ignoreMissingFields,\n ...props\n });\n // Destructured to be *excluded* from `...rest`, not to be used —\n // see the comment below. Said explicitly so the discarded-value\n // ratchet does not carry a finding that is working as intended.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { values, previousValues, ...rest } = props;\n const ofProperty = resolveProperty({ // we don't want to pass the values of the parent entity\n property: of,\n ignoreMissingFields,\n ...rest\n });\n if (!ofProperty && !ignoreMissingFields)\n throw Error(\"When using a property builder as the 'of' prop of an ArrayProperty, you must return a valid child property\")\n return resolvedProperties;\n }\n } else if (property.oneOf) {\n const typeField = property.oneOf?.typeField ?? DEFAULT_ONE_OF_TYPE;\n const resolvedProperties: Property[] = Array.isArray(propertyValue)\n ? propertyValue.map((v, index) => {\n const type = v && v[typeField];\n const childProperty = property.oneOf?.properties[type];\n if (!type || !childProperty) return null;\n return resolveProperty({\n propertyKey: `${propertyKey}.${index}`,\n property: childProperty,\n ignoreMissingFields,\n ...props\n });\n }).filter(e => Boolean(e)) as Property[]\n : [];\n return resolvedProperties;\n } else if (!property.columnType) {\n // An array with neither `of`/`oneOf` nor a `columnType` describes no element\n // type, so nothing can be generated or rendered from it.\n //\n // The escape hatch used to be `ui.Field` — \"a custom component can render\n // anything\" — which made a *presentation* field decide whether a schema was\n // valid, in code the Postgres generator runs. `columnType` is the same escape\n // hatch stated as data: `columnType: \"text[]\"` says what the column holds,\n // which is what both the generator and the form actually need.\n throw Error(`The array property (${propertyKey}) needs to declare an 'of' or a 'oneOf' property, or a \\`columnType\\` such as \"text[]\"`);\n } else {\n return [];\n }\n\n}\n\nexport function getArrayResolvedProperties({\n propertyKey,\n propertyValue,\n property,\n ...props\n}: {\n propertyValue: unknown,\n propertyKey?: string,\n property: ArrayProperty,\n ignoreMissingFields: boolean,\n values?: object;\n previousValues?: object;\n path?: string;\n entityId?: string | number;\n index?: number;\n propertyConfigs?: Record<string, PropertyConfig>;\n authController: AuthState;\n}) {\n\n const of = property.of;\n if (!of)\n throw Error(\n `Trying to resolve an array property (${propertyKey}) without providing an 'of' property`\n )\n return Array.isArray(propertyValue)\n ? propertyValue.map((v: unknown, index: number) => {\n return resolveProperty({\n propertyKey: `${propertyKey}.${index}`,\n property: Array.isArray(of) ? of[index] : of,\n ...props,\n index\n });\n }).filter(e => Boolean(e)) as Property[]\n : [];\n}\n\nexport function resolveEnumValues(input: EnumValues): EnumValueConfig[] | undefined {\n if (typeof input === \"object\") {\n return Object.entries(input).map(([id, value]) =>\n (typeof value === \"string\"\n ? {\n id,\n label: value\n }\n : value));\n } else if (Array.isArray(input)) {\n return input as EnumValueConfig[];\n } else {\n return undefined;\n }\n}\n\n\n/**\n * The lists rendered inside an entity view of `collection` — its tabs.\n *\n * The single derivation. There used to be two that disagreed: this one, and a\n * copy in `CollectionRegistry.normalizeCollection` that stamped each child with\n * the *target collection's* slug instead of the relation key. Since the\n * registry ran first and cached its answer onto `childCollections`, its version\n * was the one that won, and the frontend addressed child listings by a segment\n * the backend could not resolve.\n *\n * Order of precedence:\n * 1. `childCollections` — the explicit escape hatch for custom drivers.\n * 2. `subcollections` on an engine that has real containment (Firestore).\n * 3. many-relations on an engine that has relations (SQL).\n */\nexport function getEntityChildViews<M extends Record<string, unknown> = Record<string, unknown>>(\n collection: CollectionConfig<M>\n): EntityChildView[] {\n const asSubcollections = (collections: CollectionConfig<Record<string, unknown>>[]): EntityChildView[] =>\n collections.filter(Boolean).map(child => ({\n key: child.slug,\n collection: child,\n source: { kind: \"subcollection\" as const }\n }));\n\n if (collection.childCollections) {\n return asSubcollections(collection.childCollections() ?? []);\n }\n\n const capabilities = getDataSourceCapabilities(collection.engine);\n\n const declaredSubcollections = getDeclaredSubcollections(collection);\n if (capabilities.supportsSubcollections && declaredSubcollections) {\n return asSubcollections(declaredSubcollections() ?? []);\n }\n\n if (!capabilities.supportsRelations) return [];\n\n const resolvedRelations = resolveCollectionRelations(collection);\n const views: EntityChildView[] = [];\n const seen = new Set<string>();\n\n // Keyed by the map key, not by `relationName`: the map key is what\n // `findRelation` matches a path segment against, so it is the only one that\n // addresses the same relation on both sides of the wire. The map registers\n // some relations twice — once canonically, once under the declaring\n // property key — so dedupe on the underlying relation.\n for (const [relationKey, relation] of Object.entries(resolvedRelations)) {\n if (relation.cardinality !== \"many\") continue;\n\n const identity = relation.relationName ?? relationKey;\n if (seen.has(identity)) continue;\n\n let target: CollectionConfig | undefined;\n try {\n target = relation.target();\n } catch {\n continue;\n }\n if (!target) continue;\n seen.add(identity);\n\n // A name given to the declaring property is the author naming the tab.\n const declaringProperty = Object.entries((collection.properties ?? {}) as Record<string, Property>)\n .find(([propKey, p]) => p.type === \"relation\" && ((p as RelationProperty).relation?.relationName ?? propKey) === identity);\n const customName = declaringProperty?.[1]?.name;\n\n const base: CollectionConfig<Record<string, unknown>> = {\n ...target,\n slug: relationKey,\n ...(customName ? { name: customName,\nsingularName: customName } : {})\n } as CollectionConfig<Record<string, unknown>>;\n\n views.push({\n key: relationKey,\n collection: (relation.overrides ? mergeDeep(base, relation.overrides) : base) as CollectionConfig<Record<string, unknown>>,\n source: {\n kind: \"relation\",\n relationKey,\n mode: isJunctionBackedRelation(relation) ? \"linked\" : \"owned\",\n targetSlug: target.slug\n }\n });\n }\n\n return views;\n}\n\n/**\n * Each of `collection`'s tabs paired with the property that declared it, when a\n * property declared it: child view key → property key.\n *\n * A many-relation can only be declared as a property — that is the documented\n * and only mechanism — and {@link getEntityChildViews} promotes it to a tab. So\n * one declaration reaches the panel twice, and neither surface knew about the\n * other. The form rendered a relation picker beside the tab, and the collection\n * table rendered *two* columns under one heading: the relation's own column,\n * showing the child rows, and a jump-to-tab button carrying the same name.\n *\n * The pairing is what lets each surface decide which half is redundant, and it\n * has to be a pairing rather than two sets because the two keys differ whenever\n * a relation is named. The match is on the resolved `relationName` — the\n * identity `getEntityChildViews` itself dedupes on — so a relation declared in\n * `relations` and pointed at by a differently-named property is recognised too.\n *\n * A relation with no property of its own is absent here, which is the point: it\n * has exactly one surface already, and nothing to weigh it against.\n *\n * Only top-level properties: a relation nested inside a `map` gets no tab.\n */\nexport function getChildViewDeclaringProperties<M extends Record<string, unknown> = Record<string, unknown>>(\n collection: CollectionConfig<M>\n): Map<string, string> {\n const pairs = new Map<string, string>();\n\n const relationProperties = Object.entries((collection.properties ?? {}) as Record<string, Property>)\n .filter(([, property]) => property?.type === \"relation\");\n if (relationProperties.length === 0) return pairs;\n\n const relationViews = getEntityChildViews(collection)\n .filter(view => view.source.kind === \"relation\");\n if (relationViews.length === 0) return pairs;\n\n const resolvedRelations = resolveCollectionRelations(collection);\n const identityOf = (relationKey: string): string =>\n resolvedRelations[relationKey]?.relationName ?? relationKey;\n\n const declaringPropertyByIdentity = new Map<string, string>();\n for (const [propertyKey, property] of relationProperties) {\n const relation = (property as RelationProperty).resolvedRelation ?? resolvedRelations[propertyKey];\n // A to-one relation is a foreign key the author edits, never a tab. No\n // view will match it — the views here are many-relations only — but\n // reading the cardinality says so where someone is looking.\n if (relation?.cardinality !== \"many\") continue;\n const identity = relation.relationName ?? propertyKey;\n if (!declaringPropertyByIdentity.has(identity)) declaringPropertyByIdentity.set(identity, propertyKey);\n }\n\n for (const view of relationViews) {\n const propertyKey = declaringPropertyByIdentity.get(\n identityOf((view.source as { relationKey: string }).relationKey));\n if (propertyKey) pairs.set(view.key, propertyKey);\n }\n\n return pairs;\n}\n\n/**\n * The property keys of `collection` whose relation is already one of its tabs.\n *\n * What a form asks: the tab is the treatment for a list of child rows, so the\n * picker beside it is the redundant half. See\n * {@link getChildViewDeclaringProperties}.\n */\nexport function getChildViewRelationPropertyKeys<M extends Record<string, unknown> = Record<string, unknown>>(\n collection: CollectionConfig<M>\n): Set<string> {\n return new Set(getChildViewDeclaringProperties(collection).values());\n}\n\n/**\n * The child views of `collection` as bare collections.\n *\n * The flattened view of {@link getEntityChildViews}, for navigation code that\n * only needs to match a path segment against a slug. Anything that cares *what\n * kind* of list it is showing — chiefly the admin, which must not offer a\n * global delete on a shared row — should read the views instead.\n */\nexport function getSubcollections<M extends Record<string, unknown> = Record<string, unknown>>(collection: CollectionConfig<M>): CollectionConfig<Record<string, unknown>>[] {\n return getEntityChildViews(collection).map(view => view.collection);\n}\n","import { ANONYMOUS_USER_ID, ANONYMOUS_USER_IDS, LiteralPolicyOperand, PolicyExpression, policy, rewriteLegacyRlsFunctions } from \"@rebasepro/types\";\nimport { toSnakeCase } from \"@rebasepro/utils\";\n\n/**\n * A tiny, regex-based SQL \"parser\" for security rules.\n *\n * This is NOT a full SQL parser. It is designed to handle the subset of SQL\n * commonly used in `USING` and `WITH CHECK` clauses, enough to drive the\n * optimistic client-side UI decision.\n *\n * It handles:\n * - `field = 'literal'`\n * - `field != 'literal'`\n * - `field = current_setting('app.uid')` (or the legacy `app.user_id`)\n * - `A AND B`, `A OR B` — only where the keyword is at the top level\n * - `true`\n * - `IN (...)` (as optimistic true)\n *\n * For anything it doesn't understand, it returns a `raw` expression, which\n * the evaluator treats as \"unknown\" (and usually optimistic true).\n *\n * **This output also round-trips back into DDL** via `policyToPostgres` (the\n * schema/policy generators), so decomposing a clause the parser only partly\n * understands is not a cosmetic mistake — it emits invalid SQL. When in doubt,\n * prefer `raw`: it is reproduced verbatim.\n */\n/** True when `keyword` starts at `i` as a standalone word. */\nfunction isKeywordAt(upper: string, i: number, keyword: string): boolean {\n if (!upper.startsWith(keyword, i)) return false;\n const before = i === 0 ? \" \" : upper[i - 1];\n const after = upper[i + keyword.length] ?? \" \";\n return /[\\s()]/.test(before) && /[\\s()]/.test(after);\n}\n\n/**\n * Split `sql` on a boolean keyword, but only where it sits at paren depth 0 and\n * outside a string literal. Returns null when it never does, so the caller\n * leaves the clause alone.\n *\n * This used to be `sql.split(/ AND /i)`, which tore subqueries in half: the\n * `AND` inside\n * `EXISTS (SELECT 1 FROM organization_members m WHERE m.org = t.org AND m.user_id = rebase.uid())`\n * split the expression, and re-emitting the halves produced\n * `(EXISTS (...) AND m.user_id = rebase.uid())`\n * where `m` is no longer in scope — SQL that Postgres rejects outright with\n * \"missing FROM-clause entry for table\". Returning null instead keeps such a\n * clause as a `raw` expression, which round-trips verbatim.\n */\nfunction splitTopLevel(sql: string, keyword: \"AND\" | \"OR\"): string[] | null {\n const upper = sql.toUpperCase();\n const parts: string[] = [];\n let depth = 0;\n let inString = false;\n let start = 0;\n\n for (let i = 0; i < sql.length; i++) {\n const ch = sql[i];\n if (inString) {\n if (ch === \"'\") {\n if (sql[i + 1] === \"'\") i++; // '' escapes a quote inside a literal\n else inString = false;\n }\n continue;\n }\n if (ch === \"'\") { inString = true; continue; }\n if (ch === \"(\") { depth++; continue; }\n if (ch === \")\") { depth--; continue; }\n if (depth === 0 && isKeywordAt(upper, i, keyword)) {\n parts.push(sql.slice(start, i));\n i += keyword.length - 1;\n start = i + 1;\n }\n }\n\n if (parts.length === 0) return null;\n parts.push(sql.slice(start));\n const trimmedParts = parts.map(p => p.trim()).filter(p => p.length > 0);\n return trimmedParts.length > 1 ? trimmedParts : null;\n}\n\n/** Drop redundant wrapping parens (`(a AND b)` → `a AND b`), never `(a) AND (b)`. */\nfunction stripOuterParens(sql: string): string {\n let s = sql.trim();\n for (;;) {\n if (!s.startsWith(\"(\") || !s.endsWith(\")\")) return s;\n let depth = 0;\n let inString = false;\n let wraps = true;\n for (let i = 0; i < s.length; i++) {\n const ch = s[i];\n if (inString) {\n if (ch === \"'\") {\n if (s[i + 1] === \"'\") i++;\n else inString = false;\n }\n continue;\n }\n if (ch === \"'\") { inString = true; continue; }\n if (ch === \"(\") depth++;\n else if (ch === \")\") {\n depth--;\n if (depth === 0 && i < s.length - 1) { wraps = false; break; }\n }\n }\n if (!wraps) return s;\n s = s.slice(1, -1).trim();\n }\n}\n\nexport function sqlToPolicy(sql: string): PolicyExpression {\n // Normalised before anything else looks at it, so every pattern below only\n // has to know the current spelling. A database migrated by a pre-1.0 release\n // still holds `auth.uid()` in its policy bodies until the next push or boot\n // recompiles them — and until then the admin UI reads those bodies back\n // through here. Without this they parse as opaque `raw`, and the framework's\n // own policies get badged as hand-written drift.\n //\n // Normalising rather than accepting both spellings throughout is deliberate:\n // it also means a legacy policy that falls through to `raw` is stored in the\n // new spelling, so editing and saving one in the Studio migrates it.\n const trimmed = stripOuterParens(rewriteLegacyRlsFunctions(sql).trim());\n\n if (trimmed.toLowerCase() === \"true\") return policy.true();\n if (trimmed.toLowerCase() === \"false\") return policy.false();\n\n // Handle roles overlap (&&)\n // Matches: string_to_array(rebase.roles(), ',') && ARRAY['admin', 'editor']\n const overlapMatch = trimmed.match(/^string_to_array\\s*\\(\\s*rebase\\.roles\\(\\)\\s*,\\s*','\\s*\\)\\s*&&\\s*ARRAY\\s*\\[(.+)\\]$/i);\n if (overlapMatch) {\n const roles = overlapMatch[1].split(\",\").map(s => s.trim().replace(/^'|'$/g, \"\"));\n return policy.rolesOverlap(roles);\n }\n\n // Handle roles containment (@>)\n // Matches: string_to_array(rebase.roles(), ',') @> ARRAY['admin']\n const containMatch = trimmed.match(/^string_to_array\\s*\\(\\s*rebase\\.roles\\(\\)\\s*,\\s*','\\s*\\)\\s*@>\\s*ARRAY\\s*\\[(.+)\\]$/i);\n if (containMatch) {\n const roles = containMatch[1].split(\",\").map(s => s.trim().replace(/^'|'$/g, \"\"));\n return policy.rolesContain(roles);\n }\n\n // OR binds looser than AND, so it splits first.\n const orParts = splitTopLevel(trimmed, \"OR\");\n if (orParts) return policy.or(...orParts.map(sqlToPolicy));\n\n const andParts = splitTopLevel(trimmed, \"AND\");\n if (andParts) return policy.and(...andParts.map(sqlToPolicy));\n\n // Handle = and !=\n const match = trimmed.match(/^(.+?)\\s*(!?=)\\s*(.+)$/);\n if (match) {\n const [, leftStr, op, rightStr] = match;\n const left = parseOperand(leftStr.trim());\n const right = parseOperand(rightStr.trim());\n if (left && right) {\n return policy.compare(left, op === \"=\" ? \"eq\" : \"neq\", right);\n }\n }\n\n // Fallback to raw — the NORMALISED text, not the input. Storing the input\n // verbatim would mean a legacy policy read out of a database, edited in the\n // Studio and saved, writes `auth.uid()` back into the project's config: a\n // call to a function 1.0 no longer creates.\n return policy.raw(trimmed);\n}\n\n/**\n * Literals from other BaaS platforms that people compare `rebase.uid()` against\n * out of habit. Mirrors the driver's `FOREIGN_CONVENTION_ROLES` guard on\n * `pgRoles`, one surface over: the same muscle memory inside a `using:` string\n * is the more dangerous spelling, because it inverts a rule instead of\n * emptying a table.\n */\n/**\n * A `Map`, not an object literal.\n *\n * As `Record<string, string>` this was indexed with a literal taken straight\n * out of a policy, so every key on `Object.prototype` answered: a rule\n * comparing `rebase.uid()` to `\"valueOf\"`, `\"toString\"`, `\"constructor\"` or\n * `\"hasOwnProperty\"` found a truthy \"platform\" and reported an anonymous-grant\n * risk that does not exist — with the matched function interpolated into the\n * explanation as the platform's name. A security warning that fires on\n * innocent input is worse than none: it is what teaches people to skip the\n * warnings that are real.\n *\n * Same shape as the prototype-pollution class swept out of `setIn`, `getIn`,\n * `mergeDeep` and `unflattenObject` — a data-derived key reaching a plain\n * object. Found by a property test, on the input `\"valueOf\"`.\n */\nconst FOREIGN_CONVENTION_UIDS = new Map<string, string>([\n [\"anon\", \"Supabase\"],\n [\"authenticated\", \"Supabase\"],\n [\"service_role\", \"Supabase\"]\n]);\n\n/**\n * The same foreign literals, as a pattern for SQL that could not be parsed\n * back into structure.\n */\nconst FOREIGN_UID_LITERAL_SQL = new RegExp(\n String.raw`rebase\\.uid\\(\\)\\s*=\\s*'(${[...FOREIGN_CONVENTION_UIDS.keys()].join(\"|\")})'`,\n \"i\"\n);\n\n/** A clause that reads as a lockdown but admits anonymous callers. */\nexport interface AnonymousGrantRisk {\n /** Which spelling was found. */\n pattern: \"foreign-uid-literal\" | \"uid-not-null\";\n /** The offending fragment — the literal, or the SQL that is a tautology. */\n detail: string;\n /** Why it admits anonymous callers, and what to write instead. */\n explanation: string;\n}\n\n/**\n * `rebase.uid() IS NOT NULL` in raw SQL, the clause that is always true.\n *\n * Both schema spellings, because this runs over policy bodies read back from a\n * database, and one migrated by a pre-1.0 release still holds `auth.uid()`.\n * A security check that stops recognising a dangerous clause because the\n * framework renamed a function is a check that silently turns off.\n */\nconst UID_NOT_NULL = /\\b(?:rebase|auth)\\.uid\\(\\)\\s+IS\\s+NOT\\s+NULL/i;\n\n/**\n * Find clauses that read as \"signed-in users only\" but admit anonymous callers.\n *\n * Both spellings come from the same place — Supabase, where its own `auth.uid()`\n * really is NULL for an anonymous request. Rebase substitutes\n * {@link ANONYMOUS_USER_ID} instead (a blank id would read back as NULL, which\n * is how the trusted *server* context is recognised), so:\n *\n * - `rebase.uid() IS NOT NULL` is a tautology on the user path, and\n * - `rebase.uid() != 'anon'` excludes one spelling of anonymous and admits the\n * other. This one is not hypothetical and was not only a foreign habit:\n * rebase's own request path reported `'anon'` while everything that compiled\n * or checked a policy used `'anonymous'`, so whichever literal an author\n * picked, half the anonymous callers walked through. See\n * {@link ANONYMOUS_USER_IDS}.\n *\n * Either one turns a lockdown into a full grant, and neither looks wrong. No\n * real user id is ever one of these literals, and a user-context request is\n * never NULL, so a match is always a mistake rather than a deliberate check.\n *\n * Structured expressions are checked too, not just parsed SQL: `policy.compare`\n * can spell the same mistake.\n */\nexport function findAnonymousGrants(expr: PolicyExpression): AnonymousGrantRisk[] {\n const found: AnonymousGrantRisk[] = [];\n\n const visit = (e: PolicyExpression): void => {\n switch (e.kind) {\n case \"and\":\n case \"or\":\n e.operands.forEach(visit);\n return;\n case \"not\":\n visit(e.operand);\n return;\n case \"existsIn\":\n visit(e.where);\n return;\n case \"raw\": {\n if (UID_NOT_NULL.test(e.sql)) {\n found.push({\n pattern: \"uid-not-null\",\n detail: e.sql,\n explanation: \"`rebase.uid() IS NOT NULL` is true for every request that came from a client, \" +\n `including anonymous ones — they carry '${ANONYMOUS_USER_ID}', not NULL. ` +\n \"Use `condition: policy.authenticated()` to mean \\\"signed in\\\".\"\n });\n }\n // The foreign literals have to be looked for here too, not only\n // in `compare`. `sqlToPolicy` falls back to `raw` for anything\n // it cannot structure — an `EXISTS (...)` subquery always does —\n // so a policy read back from the database arrives as one opaque\n // string. Checking only the tautology meant a genuine\n // `rebase.uid() = 'anon'` inside an `existsIn` was structurally\n // undetectable once round-tripped, and the caller read the empty\n // result as \"no risks found\".\n const foreign = FOREIGN_UID_LITERAL_SQL.exec(e.sql);\n if (foreign) {\n const literal = foreign[1];\n found.push({\n pattern: \"foreign-uid-literal\",\n detail: literal,\n explanation: `'${literal}' is a ${FOREIGN_CONVENTION_UIDS.get(literal)} convention. Rebase ` +\n `reports an anonymous request as '${ANONYMOUS_USER_ID}', so comparing against ` +\n `'${literal}' passes for every caller. Use \\`condition: policy.authenticated()\\` to ` +\n \"mean \\\"signed in\\\".\"\n });\n }\n return;\n }\n case \"compare\": {\n const literal = [e.left, e.right].find(o => o.kind === \"literal\") as LiteralPolicyOperand | undefined;\n const comparesUid = e.left.kind === \"authUid\" || e.right.kind === \"authUid\";\n if (!comparesUid || typeof literal?.value !== \"string\") return;\n const platform = FOREIGN_CONVENTION_UIDS.get(literal.value);\n if (!platform) return;\n found.push({\n pattern: \"foreign-uid-literal\",\n detail: literal.value,\n explanation: `'${literal.value}' is a ${platform} convention. Rebase reports an anonymous ` +\n `request as '${ANONYMOUS_USER_ID}', so comparing against '${literal.value}' passes for ` +\n \"every caller. Use `condition: policy.authenticated()` to mean \\\"signed in\\\" — it \" +\n `compiles to NOT IN (${ANONYMOUS_USER_IDS.map(v => `'${v}'`).join(\", \")}), covering ` +\n \"every spelling rebase has reported rather than whichever one you remember.\"\n });\n return;\n }\n default:\n return;\n }\n };\n\n visit(expr);\n return found;\n}\n\nfunction parseOperand(str: string) {\n // current_setting('app.uid') or rebase.uid(). `app.user_id` is the\n // pre-rename spelling and stays parseable: policies are data, so a\n // database provisioned before the rename still holds rules written\n // against it, and round-tripping one must not silently drop the operand.\n //\n // ANCHORED, and that is the whole point. These tests used to be\n // unanchored — `.test(str)` rather than `^…$` — so any operand text that\n // merely *contained* a uid call was replaced wholesale by the call itself.\n // Everything else in the expression was discarded with it, including a\n // leading `NOT (`:\n //\n // NOT (rebase.uid() = rebase.uid()) parsed as rebase.uid() = rebase.uid()\n //\n // A deny became an unconditional grant. The realistic spelling is a\n // hand-written defensive rule with a uid call on both sides —\n // COALESCE(rebase.uid(), '') = COALESCE(owner_id, rebase.uid())\n // — which collapsed to the same tautology. This is not confined to the\n // admin UI: `securityRuleToConditions` feeds a rule's raw `using:` string\n // through here, and the Postgres DDL generators compile the result, so the\n // tautology was written into the database as the policy body.\n //\n // An operand this cannot identify exactly must return null, which drops the\n // whole clause to `raw` and reproduces it verbatim. That is the rule the\n // rest of this file already follows: when in doubt, prefer `raw`.\n if (/^current_setting\\s*\\(\\s*'app\\.(uid|user_id)'\\s*\\)$/i.test(str) || /^rebase\\.uid\\(\\)$/i.test(str)) {\n return policy.authUid();\n }\n\n // Literal string: 'value', with `''` decoded back to a single quote.\n //\n // `quoteLiteral` doubles every quote on the way out, and this did not undo\n // it, so a literal containing an apostrophe grew on every trip: O'Brien →\n // O''Brien → O''''Brien, doubling each time a policy was read back and\n // recompiled. Past the first trip the emitted policy compares against a\n // string no row holds.\n const literal = parseSingleQuoted(str);\n if (literal !== null) {\n return policy.literal(literal);\n }\n\n // Unquoted literals, which must be recognised BEFORE the bare-word branch\n // below or they are read as column names.\n //\n // `quoteLiteral` emits booleans, numbers and null unquoted, so `a = false`\n // came back as a comparison against a *field* called `false`, and `a = 42`\n // against a field called `42`. The recompiled SQL is identical either way,\n // which is why this survived a round-trip check on the SQL — but the\n // expression is now wrong, and the expression is what the admin UI\n // evaluates. Against a row with no `a`, Postgres denies (`NULL = false` is\n // not true) while the JS evaluator compared two missing columns, found them\n // equal, and allowed. That is precisely the client/database drift the\n // shared PolicyExpression model exists to make impossible.\n //\n // Unambiguous in both directions: a SQL identifier cannot begin with a\n // digit, and bare `true`/`false`/`null` are always the literals — a column\n // so named would have to be double-quoted to be referenced at all.\n if (/^-?\\d+$/.test(str)) return policy.literal(Number(str));\n if (/^-?\\d*\\.\\d+$/.test(str)) return policy.literal(Number(str));\n if (/^true$/i.test(str)) return policy.literal(true);\n if (/^false$/i.test(str)) return policy.literal(false);\n if (/^null$/i.test(str)) return policy.literal(null);\n\n // Bare field name — but only one that survives the snake-casing the\n // compiler will apply to it. `toSnakeCase(\"_\")` is the empty string, and a\n // field that compiles to an empty column reference emits `= 'x'`, which is\n // a syntax error at CREATE POLICY time. Such a name is left to `raw`, where\n // it round-trips verbatim instead. `toSnakeCase` itself is not touched:\n // column names derived by it are already in shipped databases.\n if (/^\\w+$/.test(str) && toSnakeCase(str) !== \"\") {\n return policy.field(str);\n }\n\n return null;\n}\n\n/**\n * Decode a single-quoted SQL literal, or null when `str` is not exactly one.\n *\n * Rejecting is as important as decoding: `'a' = 'b'` is two literals and an\n * operator, not one literal whose body contains a quote, and a regex anchored\n * on the outer quotes would happily read it as the latter. Every interior quote\n * must therefore be part of a `''` pair.\n */\nfunction parseSingleQuoted(str: string): string | null {\n if (str.length < 2 || !str.startsWith(\"'\") || !str.endsWith(\"'\")) return null;\n const body = str.slice(1, -1);\n let out = \"\";\n for (let i = 0; i < body.length; i++) {\n if (body[i] !== \"'\") {\n out += body[i];\n continue;\n }\n if (body[i + 1] === \"'\") {\n out += \"'\";\n i++;\n continue;\n }\n return null; // a bare quote — `str` is not a single literal\n }\n return out;\n}\n","import { PolicyExpression, SecurityRule, policy } from \"@rebasepro/types\";\nimport { sqlToPolicy } from \"./sqlToPolicy\";\n\n/**\n * The normalized `USING` / `WITH CHECK` conditions for a single security rule,\n * expressed in the engine-agnostic {@link PolicyExpression} model.\n *\n * A `null` clause means \"this rule contributes no condition for that clause\";\n * consumers apply the default (Postgres denies with `false`).\n */\nexport interface RuleConditions {\n usingExpr: PolicyExpression | null;\n withCheckExpr: PolicyExpression | null;\n}\n\n/**\n * Desugars a {@link SecurityRule} — its `access`/`ownerField`/`roles` shortcuts,\n * structured `condition`/`check`, and raw `using`/`withCheck` — into a single\n * normalized {@link PolicyExpression} pair.\n *\n * **This is the linchpin against drift:** both the Postgres DDL generators and\n * the client-side evaluator consume this one function, so there is exactly one\n * definition of what a rule means. In particular, application `roles` are folded\n * into the expression here (AND'd with the base condition, matching how Postgres\n * generates the clause) rather than being handled separately by each consumer.\n */\nexport function securityRuleToConditions(rule: SecurityRule): RuleConditions {\n return {\n usingExpr: withRoles(baseUsing(rule), rule),\n withCheckExpr: withRoles(baseWithCheck(rule), rule)\n };\n}\n\nfunction baseUsing(rule: SecurityRule): PolicyExpression | null {\n if (rule.condition) return rule.condition;\n if (rule.using != null) return sqlToPolicy(rule.using);\n if (rule.access === \"public\") return policy.true();\n if (rule.ownerField) return policy.compare(policy.field(rule.ownerField), \"eq\", policy.authUid());\n return null;\n}\n\nfunction baseWithCheck(rule: SecurityRule): PolicyExpression | null {\n if (rule.check) return rule.check;\n if (rule.withCheck != null) return sqlToPolicy(rule.withCheck);\n // No explicit WITH CHECK → fall back to the USING condition, matching\n // PostgreSQL's own default behavior.\n return baseUsing(rule);\n}\n\n/**\n * AND the base condition with an application-role check, or produce a roles-only\n * condition when there is no base. Mirrors the Postgres generator so that a\n * role-scoped restrictive rule denies exactly the same set of users on both\n * sides.\n */\nfunction withRoles(base: PolicyExpression | null, rule: SecurityRule): PolicyExpression | null {\n if (!rule.roles || rule.roles.length === 0) return base;\n const rolesExpr = policy.rolesOverlap(rule.roles);\n if (rule.mode === \"restrictive\") {\n // Restrictive rule: applies ONLY if user has the roles.\n // If user DOES NOT have the roles, they are NOT restricted (passes).\n // If user HAS the roles, they must pass the base condition.\n // Logical equivalent: NOT(roles) OR base\n return base ? policy.or(policy.not(rolesExpr), base) : policy.not(rolesExpr);\n }\n return base ? policy.and(base, rolesExpr) : rolesExpr;\n}\n","import { ANONYMOUS_USER_IDS, CollectionConfig, PolicyExpression, PolicyOperand, PolicyCompareOperator, Property, ExistsInPolicyExpression, RLS_ROLES_SQL, RLS_UID_SQL, rewriteLegacyRlsFunctions } from \"@rebasepro/types\";\nimport { toSnakeCase } from \"@rebasepro/utils\";\nimport { getTableName } from \"../relations\";\n\n/**\n * Options for {@link policyToPostgres}.\n */\nexport interface PolicyCompileOptions {\n /**\n * Resolve a collection by slug. Required to compile\n * {@link ExistsInPolicyExpression} (`policy.existsIn`) — the compiler needs\n * the joined collection to derive its table name / schema. When omitted, the\n * join table falls back to a snake_cased slug.\n */\n resolveCollection?: (slug: string) => CollectionConfig | undefined;\n}\n\n/**\n * The lexical scope threaded through compilation. It changes when we descend\n * into an `existsIn` subquery: inside it, `field` refers to the joined table\n * (aliased) while `outerField` refers to the outer RLS row (table-qualified).\n */\ninterface CompileScope {\n /** Collection whose columns a bare `field` operand resolves against. */\n fieldCollection?: CollectionConfig;\n /** SQL prefix for `field` operands (`\"\"` at top level, `\"alias\".` in a subquery). */\n fieldPrefix: string;\n /** The outer RLS collection, for `outerField` operands. */\n outerCollection?: CollectionConfig;\n /** SQL prefix for `outerField` operands (`\"\"` at top level, `\"schema\".\"table\".` in a subquery). */\n outerPrefix: string;\n resolveCollection?: (slug: string) => CollectionConfig | undefined;\n /** Monotonic counter for generating unique subquery aliases. */\n alias: { n: number };\n}\n\n/**\n * Compiles a {@link PolicyExpression} to a PostgreSQL boolean SQL string,\n * suitable for a `USING (...)` / `WITH CHECK (...)` clause.\n *\n * This is one of the two consumers of the shared policy model (the other being\n * {@link evaluatePolicy}); the Postgres schema generators call it so that DDL\n * and the admin UI derive from the exact same expression.\n */\nexport function policyToPostgres(expr: PolicyExpression, collection?: CollectionConfig, options?: PolicyCompileOptions): string {\n return compile(expr, {\n fieldCollection: collection,\n fieldPrefix: \"\",\n outerCollection: collection,\n outerPrefix: \"\",\n resolveCollection: options?.resolveCollection,\n alias: { n: 0 }\n });\n}\n\nfunction compile(expr: PolicyExpression, scope: CompileScope): string {\n switch (expr.kind) {\n case \"true\":\n return \"true\";\n case \"false\":\n return \"false\";\n case \"and\":\n return expr.operands.length === 0\n ? \"true\"\n : expr.operands.map(o => `(${compile(o, scope)})`).join(\" AND \");\n case \"or\":\n return expr.operands.length === 0\n ? \"false\"\n : expr.operands.map(o => `(${compile(o, scope)})`).join(\" OR \");\n case \"not\":\n return `NOT (${compile(expr.operand, scope)})`;\n case \"compare\": {\n // `rebase.uid()` returns text; cast the column side so uuid / integer\n // id columns compare cleanly instead of failing with\n // \"operator does not exist: uuid = text\" at CREATE POLICY time.\n const castForAuthUid = (operand: PolicyOperand, sqlText: string, other: PolicyOperand): string =>\n other.kind === \"authUid\" && (operand.kind === \"field\" || operand.kind === \"outerField\")\n ? `(${sqlText})::text`\n : sqlText;\n const leftSql = castForAuthUid(expr.left, operandToSql(expr.left, scope), expr.right);\n const rightSql = castForAuthUid(expr.right, operandToSql(expr.right, scope), expr.left);\n return `${leftSql} ${COMPARE_SQL[expr.op]} ${rightSql}`;\n }\n case \"rolesOverlap\":\n return `string_to_array(${RLS_ROLES_SQL}, ',') && ${rolesArraySql(expr.roles)}`;\n case \"rolesContain\":\n return `string_to_array(${RLS_ROLES_SQL}, ',') @> ${rolesArraySql(expr.roles)}`;\n case \"authenticated\":\n // `IS NOT NULL` alone is a tautology on the user path: every\n // user-context request sets `app.uid`, and an anonymous one sets\n // it to a sentinel. Excluding the sentinels is what makes this mean\n // \"signed in\" rather than \"anyone at all\".\n //\n // Every sentinel, not just the current one. This clause is written\n // into the database and outlives the server that generated it: a\n // policy compiled here may be enforced against an older server that\n // still reports `'anon'`, which is exactly how excluding one\n // spelling turned this helper into a grant. See ANONYMOUS_USER_IDS.\n return `${RLS_UID_SQL} IS NOT NULL AND ${RLS_UID_SQL} NOT IN (${ANONYMOUS_USER_IDS.map(quoteLiteral).join(\", \")})`;\n case \"serverContext\":\n // Only the built-in server flows leave `app.uid` unset.\n return `${RLS_UID_SQL} IS NULL`;\n case \"existsIn\":\n return compileExistsIn(expr, scope);\n case \"raw\": {\n // A project written against a pre-1.0 release may still spell the\n // helpers `auth.uid()`. Rewritten rather than rejected: the rule\n // means exactly the same thing, the developer cannot be expected to\n // have read a changelog mid-deploy, and the alternative is a policy\n // that compiles cleanly and then denies every row at runtime because\n // it calls a function that no longer exists.\n //\n // The counterpart is `warnOnLegacyRlsFunctions`, which says so once\n // at boot with the file to edit — silence here would leave the old\n // spelling working forever and make the migration permanent.\n const sqlText = rewriteLegacyRlsFunctions(expr.sql);\n\n // Full-power escape hatch: `{column}` denotes a column of the outer\n // RLS row. It must be table-qualified, not bare: raw SQL may open its\n // own subquery over the same table, and there a bare name binds to the\n // inner scope, collapsing `m.x = {x}` into the tautology `m.x = m.x`.\n return sqlText.replace(/\\{(\\w+)\\}/g, (_, col) =>\n `${outerQualifier(scope)}${resolveColumnName(col, scope.outerCollection)}`);\n }\n }\n}\n\n/**\n * Compiles `existsIn` to a correlated `EXISTS (SELECT 1 FROM <join> WHERE ...)`.\n * Inside the subquery, `field` operands bind to the aliased join table and\n * `outerField` operands bind to the (table-qualified) outer RLS row.\n */\nfunction compileExistsIn(expr: ExistsInPolicyExpression, scope: CompileScope): string {\n const join = scope.resolveCollection?.(expr.collection);\n const joinTable = join ? getTableName(join) : toSnakeCase(expr.collection);\n const joinSchema = schemaOf(join) ?? schemaOf(scope.outerCollection) ?? \"public\";\n const alias = `_ex${scope.alias.n++}`;\n\n // `outerField` inside the subquery must be qualified with the outer table,\n // otherwise a bare column name would bind to the joined table instead.\n const outerPrefix = outerQualifier(scope);\n\n const innerScope: CompileScope = {\n fieldCollection: join,\n fieldPrefix: `\"${alias}\".`,\n outerCollection: scope.outerCollection,\n outerPrefix,\n resolveCollection: scope.resolveCollection,\n alias: scope.alias\n };\n return `EXISTS (SELECT 1 FROM \"${joinSchema}\".\"${joinTable}\" \"${alias}\" WHERE ${compile(expr.where, innerScope)})`;\n}\n\nconst COMPARE_SQL: Record<PolicyCompareOperator, string> = {\n eq: \"=\",\n neq: \"!=\",\n lt: \"<\",\n lte: \"<=\",\n gt: \">\",\n gte: \">=\"\n};\n\nfunction operandToSql(operand: PolicyOperand, scope: CompileScope): string {\n switch (operand.kind) {\n case \"field\":\n return `${scope.fieldPrefix}${resolveColumnName(operand.name, scope.fieldCollection)}`;\n case \"outerField\":\n return `${scope.outerPrefix}${resolveColumnName(operand.name, scope.outerCollection)}`;\n case \"literal\":\n return quoteLiteral(operand.value);\n case \"authUid\":\n return RLS_UID_SQL;\n case \"authRoles\":\n return `string_to_array(${RLS_ROLES_SQL}, ',')`;\n }\n}\n\n/**\n * SQL prefix that qualifies a column of the outer RLS row (`\"schema\".\"table\".`),\n * or `\"\"` when the collection is unknown.\n */\nfunction outerQualifier(scope: CompileScope): string {\n const table = scope.outerCollection ? getTableName(scope.outerCollection) : undefined;\n if (!table) return \"\";\n return `\"${schemaOf(scope.outerCollection) ?? \"public\"}\".\"${table}\".`;\n}\n\nfunction schemaOf(collection?: CollectionConfig): string | undefined {\n return (collection as { schema?: string } | undefined)?.schema || undefined;\n}\n\nfunction resolveColumnName(propName: string, collection?: CollectionConfig): string {\n const prop = collection?.properties?.[propName] as Property | undefined;\n if (prop && \"columnName\" in prop && typeof (prop as { columnName?: unknown }).columnName === \"string\") {\n return quoteColumnIdentifier((prop as { columnName: string }).columnName);\n }\n return quoteColumnIdentifier(toSnakeCase(propName));\n}\n\n/**\n * Every PostgreSQL keyword that cannot stand as a bare column reference.\n * Appendix C's two reserved categories — plain \"reserved\", and \"reserved (can\n * be function or type name)\" — since neither may name a column unquoted.\n */\nconst RESERVED_SQL_WORDS = new Set([\n \"all\", \"analyse\", \"analyze\", \"and\", \"any\", \"array\", \"as\", \"asc\", \"asymmetric\", \"authorization\",\n \"binary\", \"both\", \"case\", \"cast\", \"check\", \"collate\", \"collation\", \"column\", \"concurrently\",\n \"constraint\", \"create\", \"cross\", \"current_catalog\", \"current_date\", \"current_role\",\n \"current_schema\", \"current_time\", \"current_timestamp\", \"current_user\", \"default\", \"deferrable\",\n \"desc\", \"distinct\", \"do\", \"else\", \"end\", \"except\", \"false\", \"fetch\", \"for\", \"foreign\", \"freeze\",\n \"from\", \"full\", \"grant\", \"group\", \"having\", \"ilike\", \"in\", \"initially\", \"inner\", \"intersect\",\n \"into\", \"is\", \"isnull\", \"join\", \"lateral\", \"leading\", \"left\", \"like\", \"limit\", \"localtime\",\n \"localtimestamp\", \"natural\", \"not\", \"notnull\", \"null\", \"offset\", \"on\", \"only\", \"or\", \"order\",\n \"outer\", \"overlaps\", \"placing\", \"primary\", \"references\", \"returning\", \"right\", \"select\",\n \"session_user\", \"similar\", \"some\", \"symmetric\", \"system_user\", \"table\", \"tablesample\", \"then\",\n \"to\", \"trailing\", \"true\", \"union\", \"unique\", \"user\", \"using\", \"variadic\", \"verbose\", \"when\",\n \"where\", \"window\", \"with\"\n]);\n\n/** An identifier Postgres reads back unchanged without quotes. */\nconst BARE_IDENTIFIER = /^[a-z_][a-z0-9_$]*$/;\n\n/**\n * Quote a column reference when Postgres would not read the bare name as that\n * column — and only then.\n *\n * Three ways a bare name goes wrong, in ascending order of how long it takes to\n * notice:\n *\n * - **Case.** `columnName` is used verbatim, and `rebase schema introspect`\n * populates it from a live database, so a legacy `\"createdAt\"` column arrives\n * spelled exactly that way. Unquoted, Postgres folds it to `createdat` and\n * `CREATE POLICY` fails with \"column does not exist\" — the collection keeps\n * RLS enabled with no policy, which denies every row.\n * - **Syntax.** A column named `order` or `default` is a syntax error mid-clause.\n * - **Silent rebinding.** `user`, `current_user`, `session_user`, `current_date`\n * and friends are *valid bare expressions*, so the policy compiles, applies,\n * and is reported as a success — while comparing against the connected role\n * or the wall clock instead of the column. Under RLS every request runs as the\n * same `rebase_user` role, so `USING (user = rebase.uid())` is a constant: it\n * denies everything, and its negation admits everything.\n *\n * Only the names that need it are quoted, so an ordinary snake_case policy body\n * is emitted byte-for-byte as before. That keeps generated artifacts and the\n * policies already stored in shipped databases stable — this fix reaches the\n * clauses that were broken and no others.\n */\nfunction quoteColumnIdentifier(name: string): string {\n if (BARE_IDENTIFIER.test(name) && !RESERVED_SQL_WORDS.has(name)) return name;\n return `\"${name.replace(/\"/g, \"\\\"\\\"\")}\"`;\n}\n\nfunction quoteLiteral(value: string | number | boolean | null): string {\n if (value === null) return \"NULL\";\n if (typeof value === \"boolean\") return value ? \"true\" : \"false\";\n if (typeof value === \"number\") return String(value);\n return `'${value.replace(/'/g, \"''\")}'`;\n}\n\n/** Sorted, single-quoted `ARRAY['a','b']` — matches the generators' output. */\nfunction rolesArraySql(roles: readonly string[]): string {\n return `ARRAY[${[...roles].sort().map(r => `'${r}'`).join(\",\")}]`;\n}\n","import {\n CollectionConfig,\n FirebaseCollectionConfig,\n FirebaseProperties,\n InferEntityType,\n MongoDBCollectionConfig,\n MongoProperties,\n PostgresCollectionConfig,\n PostgresProperties,\n User\n} from \"@rebasepro/types\";\n\n\n// ── defineCollection ─────────────────────────────────────────────────────\n// A smarter builder that uses `const` type-parameter inference (TS 5.0+)\n// to capture literal property types automatically. This gives you\n// autocomplete on `display.title`, `sort`, `propertiesOrder`, `fixedFilter`,\n// callbacks, etc. — without writing `as const` or passing manual generics.\n\n/**\n * Define a PostgreSQL-backed collection with full type inference.\n *\n * The `const P` generic captures literal property types from your\n * `properties` object, which enables autocomplete on `display.title`,\n * `sort`, `propertiesOrder`, `fixedFilter`, and entity callbacks.\n *\n * @example\n * ```ts\n * const products = defineCollection({\n * name: \"Products\",\n * slug: \"products\",\n * table: \"products\",\n * properties: {\n * name: { name: \"Name\", type: \"string\", validation: { required: true } },\n * price: { name: \"Price\", type: \"number\" },\n * },\n * display: { title: \"name\" }, // ✅ autocomplete: \"name\" | \"price\"\n * sort: [\"price\", \"asc\"], // ✅ autocomplete on first element\n * });\n * ```\n *\n * @group Builder\n */\nexport function defineCollection<\n const P extends PostgresProperties,\n USER extends User = User\n>(\n collection: Omit<PostgresCollectionConfig<InferEntityType<P>, USER>, \"properties\"> & { properties: P }\n): PostgresCollectionConfig<InferEntityType<P>, USER> & { properties: P };\n\n/**\n * Define a Firestore-backed collection with full type inference.\n * @group Builder\n */\nexport function defineCollection<\n const P extends FirebaseProperties,\n USER extends User = User\n>(\n collection: Omit<FirebaseCollectionConfig<InferEntityType<P>, USER>, \"properties\"> & { properties: P }\n): FirebaseCollectionConfig<InferEntityType<P>, USER> & { properties: P };\n\n/**\n * Define a MongoDB-backed collection with full type inference.\n * @group Builder\n */\nexport function defineCollection<\n const P extends MongoProperties,\n USER extends User = User\n>(\n collection: Omit<MongoDBCollectionConfig<InferEntityType<P>, USER>, \"properties\"> & { properties: P }\n): MongoDBCollectionConfig<InferEntityType<P>, USER> & { properties: P };\n\n/**\n * Implementation — delegates to the correct overload at the type level.\n * At runtime this is a plain identity function.\n */\nexport function defineCollection(\n collection: CollectionConfig\n): CollectionConfig {\n return collection;\n}\n\n","import { CollectionConfig, SecurityRule, SecurityOperation, AuthCollectionConfig, PolicyExpression, isPostgresCollectionConfig, policy } from \"@rebasepro/types\";\nimport { getTableName } from \"./relations\";\nimport { getPolicyNamesForRules } from \"@rebasepro/utils\";\n\n/**\n * Default RLS policies injected by the schema generator.\n *\n * Rebase's enforcement model is unified: authenticated (user-context) requests\n * run under the restricted `rebase_user` role, so Postgres RLS binds *every*\n * statement — reads and writes. A collection's `securityRules` are the whole\n * authorization model. The server context (auth flows, migrations, raw\n * `rebase.sql`) runs as the owner and bypasses RLS.\n *\n * `rebase.dataAsAdmin` is **not** in that set, despite the name: it is scoped as\n * `{ uid: \"service\", roles: [\"admin\"] }`, so it runs as `rebase_user` like any\n * other caller and clears the baseline below through the *admin* arm, not the\n * server arm. Which is why `disableDefaultPolicies` plus a lone\n * `policy.serverContext()` rule locks it out too.\n *\n * Because RLS default-denies, every collection is **locked by default**: with\n * no rules, only the server context and admins can touch it. The generator\n * injects that safe baseline:\n *\n * **For every collection**\n * 1. A permissive **server-or-admin SELECT** grant.\n * 2. A permissive **server-or-admin write** grant (insert/update/delete).\n *\n * Author `securityRules` are permissive and OR together, so explicit rules only\n * *broaden* access from this locked baseline (e.g. \"users read/write their own\n * rows\").\n *\n * **For auth collections additionally**\n * 3. A permissive **self SELECT** grant (`id = rebase.uid()`), so users can read\n * their own row (profile, session bootstrap) without every app re-declaring\n * it.\n * 4. A **restrictive** admin write gate. Restrictive policies are AND'd with\n * every other policy, so a write is rejected unless the caller is an admin\n * (or the server context) — even if the author also wrote a permissive rule\n * such as \"a user may edit their own row\". Without this, a permissive owner\n * rule would let a user change their own `roles`.\n *\n * The server context is recognised as `rebase.uid() IS NULL` (`policy.serverContext()`)\n * — the built-in flows that run without a user (signup, migrations) set no user\n * GUC — which also lets the owner connection satisfy these policies even under\n * FORCE RLS. A *user* request never reaches that state: an anonymous one carries\n * `ANONYMOUS_USER_ID`, precisely so it cannot pass for the server here.\n *\n * Opt out with `disableDefaultPolicies: true` to take full responsibility for\n * the collection's RLS.\n */\n// Expressed structurally (not as raw SQL) so the admin UI can evaluate it\n// exactly — the framework's most security-critical policies must be reflected\n// precisely, not left as un-evaluable raw clauses. Compiles to\n// `rebase.uid() IS NULL OR (string_to_array(rebase.roles(), ',') && ARRAY['admin'])`.\n//\n// `serverContext()`, emphatically not `not(authenticated())`: the server arm of\n// this grant must match the server context and nothing else. Anonymous visitors\n// are not signed in either, so a negated `authenticated()` would hand them the\n// server-or-admin grant on every collection's default policy.\nconst SERVER_OR_ADMIN_EXPR: PolicyExpression = policy.or(\n policy.serverContext(),\n policy.rolesOverlap([\"admin\"])\n);\n\n/** Write operations that must be admin-gated by default on auth collections. */\nconst DEFAULT_GUARDED_OPS: SecurityOperation[] = [\"insert\", \"update\", \"delete\"];\n\n/** Whether a collection is flagged as an authentication collection. */\nfunction isAuthCollection(collection: CollectionConfig): boolean {\n const auth = collection.auth;\n return auth === true || (typeof auth === \"object\" && (auth as AuthCollectionConfig)?.enabled === true);\n}\n\n/** The property marked as the row id (falls back to `id`). */\nfunction getIdPropertyName(collection: CollectionConfig): string {\n for (const [name, prop] of Object.entries(collection.properties ?? {})) {\n if (prop && typeof prop === \"object\" && \"isId\" in prop && (prop as { isId?: unknown }).isId) {\n return name;\n }\n }\n return \"id\";\n}\n\n/**\n * Returns the security rules that should be applied to a collection: the\n * author's explicit `securityRules` plus the framework defaults described in\n * the module doc (baseline server/admin read for all collections; self-read\n * and the admin write gate for auth collections).\n *\n * Collections that opt out via `disableDefaultPolicies` are returned unchanged.\n */\n/**\n * The restrictive write gate for an auth collection.\n *\n * Restrictive, so it is ANDed with everything else: whatever an author's\n * permissive rules allow, a write to this table still has to satisfy this too.\n * It is the only thing standing between \"users may edit their own row\" and\n * \"users may grant themselves any role\".\n */\nfunction adminWriteGate(tableName: string): SecurityRule {\n return {\n name: `${tableName}_require_admin_write`,\n mode: \"restrictive\",\n operations: [...DEFAULT_GUARDED_OPS],\n condition: SERVER_OR_ADMIN_EXPR,\n check: SERVER_OR_ADMIN_EXPR\n };\n}\n\nexport function getEffectiveSecurityRules(collection: CollectionConfig): SecurityRule[] {\n const explicit = [...(collection.securityRules ?? [])];\n\n const tableName = getTableName(collection);\n const injected: SecurityRule[] = [];\n\n if (isPostgresCollectionConfig(collection) && collection.disableDefaultPolicies) {\n // The opt-out drops the *permissive* defaults — the ones that grant.\n // The restrictive admin-write gate on an auth collection is not among\n // them, because it is different in kind: a restrictive policy is ANDed\n // with every other policy and can only ever remove access, so opting\n // out of it cannot express anything except \"let more people write\".\n //\n // Dropping it did exactly that. `{ disableDefaultPolicies: true,\n // securityRules: [{ operation: \"all\", ownerField: \"id\" }] }` — an\n // ordinary \"users may edit their own row\" configuration — let any\n // signed-in user set their own `roles` to `[\"admin\"]`, with no warning\n // from any boot guard, doctor check or validator.\n //\n // An author who needs a different gate can add their own restrictive\n // rule; they cannot end up with none by accident.\n return isAuthCollection(collection)\n ? [...explicit, adminWriteGate(tableName)]\n : explicit;\n }\n\n // Baseline read + write: the server context and admins can always operate.\n // RLS default-denies under the user role, so without these a rule-less\n // collection would be locked to everyone — including the admin studio.\n // Author rules are permissive and broaden access from here.\n injected.push({\n name: `${tableName}_default_admin_read`,\n operations: [\"select\"],\n condition: SERVER_OR_ADMIN_EXPR\n });\n injected.push({\n name: `${tableName}_default_admin_write`,\n operations: [...DEFAULT_GUARDED_OPS],\n condition: SERVER_OR_ADMIN_EXPR,\n check: SERVER_OR_ADMIN_EXPR\n });\n\n if (isAuthCollection(collection)) {\n // Self-read: a user can always read their own row.\n injected.push({\n name: `${tableName}_default_self_read`,\n operations: [\"select\"],\n condition: policy.compare(policy.field(getIdPropertyName(collection)), \"eq\", policy.authUid())\n });\n\n // Restrictive gate: AND'd with all other policies, so no permissive rule\n // (e.g. an owner \"edit your own row\" rule) can let a non-admin change\n // privileged columns like `roles`. Survives `disableDefaultPolicies` —\n // see the note above the opt-out.\n injected.push(adminWriteGate(tableName));\n }\n\n return [...explicit, ...injected];\n}\n\n/**\n * The framework defaults that {@link getEffectiveSecurityRules} would add to a\n * collection, without the author's own rules.\n *\n * These policies appear in the database under names the author never wrote, and\n * a permissive policy ORs with every other permissive policy — so someone\n * reading their `securityRules` and then the real ACL sees more access than they\n * declared. Dropping them by hand does nothing either: `db push` is declarative,\n * so the next push asserts them again. Callers use this to say, in the generated\n * DDL, which policies are injected and how to take them off.\n */\nexport function getInjectedSecurityRules(collection: CollectionConfig): SecurityRule[] {\n if (isPostgresCollectionConfig(collection) && collection.disableDefaultPolicies) {\n // Not empty for an auth collection: the restrictive write gate is still\n // injected, and the generated DDL has to say so — a policy in the\n // database that the author never wrote and cannot find in this list is\n // exactly the surprise this function exists to prevent.\n return isAuthCollection(collection) ? [adminWriteGate(getTableName(collection))] : [];\n }\n\n const explicitCount = (collection.securityRules ?? []).length;\n // getEffectiveSecurityRules appends the defaults after the author's rules,\n // so everything past the author's count is injected.\n return getEffectiveSecurityRules(collection).slice(explicitCount);\n}\n\n/**\n * Every policy name `rebase db push` would write for a collection.\n *\n * This is the answer to \"did the codebase produce this live policy?\", and it is\n * more than `securityRules.map(r => r.name)` for two reasons:\n *\n * - a rule without an explicit `name` compiles to `<table>_<op>_<hash>`, one\n * per operation, so comparing `rule.name` to `policyname` never matches it;\n * - the generator also injects the safe-by-default baseline\n * (`<table>_default_admin_*`), which is in no collection's `securityRules`.\n *\n * Every UI that flags drift has to get both right, and each one that derived it\n * by hand got a different subset — which is how four policies *Rebase itself\n * wrote* came to be badged as hand-written drift on every table in a project,\n * with a button offering to import them back into the codebase that produced\n * them. There is one derivation now, and this is it.\n */\nexport function getGeneratedPolicyNames(collection: CollectionConfig): Set<string> {\n return getPolicyNamesForRules(getEffectiveSecurityRules(collection), getTableName(collection));\n}\n","import {\n CollectionConfig,\n PolicyExpression,\n PolicyOperand,\n Relation,\n SecurityRule,\n isPostgresCollectionConfig,\n policy\n} from \"@rebasepro/types\";\nimport { getPolicyOperations } from \"@rebasepro/utils\";\nimport { getTableName } from \"./relations\";\nimport { resolveCollectionRelations } from \"./relations\";\nimport { isManyToMany } from \"@rebasepro/types\";\nimport { securityRuleToConditions } from \"./policy/securityRuleToConditions\";\n\n/**\n * RLS derivation for many-to-many junction tables.\n *\n * A `through` relation makes the generator create a table nobody declared as a\n * collection — `posts_tags`, `user_roles`. Those tables used to be the one kind\n * of generated table with **no** RLS at all: `rebase_user` holds full DML grants,\n * so with the endpoints locked down, any signed-up user could still read or wipe\n * every edge between them. There is also nowhere in the config to write rules\n * for a junction, so the author could not even fix it by hand.\n *\n * The architecture here is that a junction's security is *derived*, never\n * hand-written:\n *\n * 1. **Locked baseline.** The same server-or-admin `default_admin` grants every\n * collection gets, so the invariant holds again: every table the generator\n * creates is default-deny, and rules only broaden.\n *\n * 2. **Reads follow the endpoints.** An edge is visible iff *both* endpoint\n * rows are visible — two correlated `EXISTS` subqueries. The subqueries run\n * under the caller's role, so each endpoint's own RLS filters them: junction\n * visibility delegates to the endpoints' policies, whatever they become,\n * with nothing duplicated. A public blog keeps rendering its tags; a private\n * CRM's edges are exactly as hidden as its rows.\n *\n * 3. **Writes follow the owning side's update rules.** Linking or unlinking an\n * edge *is* an edit of the owning row — tagging a post is editing the post —\n * so edge writes inherit the declaring collection's explicit permissive\n * `update` rules, each wrapped in an `EXISTS` against the owning row. Where\n * a rule cannot be embedded faithfully (see below) it is dropped, so the\n * failure mode is always *too locked*, never open. Explicit **restrictive**\n * update rules are inherited as restrictive junction rules; if one of them\n * cannot be embedded, the whole derived write grant for that side is\n * suppressed — granting without the author's gate would be looser than the\n * parent itself.\n *\n * **Embeddability.** A parent rule is embedded by moving its condition inside\n * `EXISTS (SELECT 1 FROM parent WHERE parent.pk = junction.fk AND <condition>)`.\n * In that scope, `field` operands bind to the parent — which is what the author\n * meant. But `outerField` operands and `{column}` placeholders in `raw` SQL bind\n * to the RLS row, which is now the junction, not the parent the author wrote\n * them against. So: `raw` anywhere disqualifies a rule; a top-level `outerField`\n * (equivalent to `field` outside a subquery) is rewritten to `field`; an\n * `outerField` inside a nested `existsIn` cannot be re-scoped and disqualifies\n * the rule.\n *\n * Injected parent defaults are never inherited — the junction's own baseline\n * already covers the server/admin plane, and an auth collection's restrictive\n * `require_admin_write` gate exists to protect privileged parent *columns*,\n * which an edge write cannot touch. Inheriting it would stop users managing\n * e.g. their own interests through a `users_interests` junction for no gain.\n *\n * Everything flows through the shared naming machinery, so the Studio\n * recognises these policies as generated instead of offering to \"import\" them.\n */\n\n/** One side of a junction: the collection and the FK column pointing at it. */\nexport interface JunctionEndpoint {\n collection: CollectionConfig;\n /** Junction column holding this endpoint's key. */\n junctionColumn: string;\n}\n\n/** A collection that declares the `through` relation (owns the edge semantics). */\nexport interface JunctionDeclaringSide extends JunctionEndpoint {\n relation: Relation;\n}\n\nexport interface JunctionSpec {\n /** Bare table name (schema stripped). */\n table: string;\n /** Schema the junction is created in — mirrors the CREATE TABLE path. */\n schema: string;\n /** The two endpoints, in [source, target] order of the first declaring relation. */\n endpoints: [JunctionEndpoint, JunctionEndpoint];\n /** Every collection that declares a relation through this table. */\n declaringSides: JunctionDeclaringSide[];\n}\n\n// Mirrors auth-default-policies: the server context or an admin.\nconst SERVER_OR_ADMIN_EXPR: PolicyExpression = policy.or(\n policy.serverContext(),\n policy.rolesOverlap([\"admin\"])\n);\n\n/**\n * Walk every collection's resolved relations and aggregate the junction tables\n * they declare. Two collections may declare the same junction from opposite\n * sides (posts→tags and tags→posts through `posts_tags`); both become\n * `declaringSides` of one spec, so derived write grants consider both.\n */\nexport function resolveJunctionSpecs(collections: CollectionConfig[]): Map<string, JunctionSpec> {\n const specs = new Map<string, JunctionSpec>();\n\n for (const collection of collections) {\n const resolved = resolveCollectionRelations(collection);\n for (const relation of Object.values(resolved)) {\n // Narrowed rather than probed: only a many-to-many has a junction,\n // and only after narrowing is `through` guaranteed complete.\n if (!isManyToMany(relation)) continue;\n\n const targetCollection: CollectionConfig | undefined = relation.target();\n if (!targetCollection) continue;\n\n const rawName = relation.through.table;\n // The CREATE TABLE path strips a schema prefix from the name but\n // still creates in \"public\"; the policies must target the same\n // table, so mirror that behaviour exactly.\n const table = rawName.includes(\".\") ? rawName.split(\".\").pop()! : rawName;\n const schema = \"public\";\n\n const source: JunctionDeclaringSide = {\n collection,\n junctionColumn: relation.through.sourceColumn,\n relation\n };\n const target: JunctionEndpoint = {\n collection: targetCollection,\n junctionColumn: relation.through.targetColumn\n };\n\n const existing = specs.get(table);\n if (!existing) {\n specs.set(table, {\n table,\n schema,\n endpoints: [source, target],\n declaringSides: [source]\n });\n } else if (!existing.declaringSides.some(s => s.collection === collection)) {\n existing.declaringSides.push(source);\n }\n }\n }\n\n return specs;\n}\n\n/**\n * A synthetic CollectionConfig standing in for the junction during policy\n * compilation and naming. Its two FK columns carry explicit `columnName`s so\n * `outerField` operands resolve to the exact columns the CREATE TABLE emitted,\n * whatever their casing.\n */\nexport function getJunctionCollectionConfig(spec: JunctionSpec): CollectionConfig {\n const properties: Record<string, unknown> = {};\n for (const endpoint of spec.endpoints) {\n properties[endpoint.junctionColumn] = {\n type: \"string\",\n columnName: endpoint.junctionColumn\n };\n }\n return {\n slug: spec.table,\n name: spec.table,\n table: spec.table,\n schema: spec.schema,\n properties\n } as unknown as CollectionConfig;\n}\n\n/** The property marked as the row id (falls back to `id`). */\nfunction getIdPropertyName(collection: CollectionConfig): string {\n for (const [name, prop] of Object.entries(collection.properties ?? {})) {\n if (prop && typeof prop === \"object\" && \"isId\" in prop && (prop as { isId?: unknown }).isId) {\n return name;\n }\n }\n return \"id\";\n}\n\n/** `EXISTS (SELECT 1 FROM endpoint WHERE endpoint.pk = junction.fk [AND extra])`. */\nfunction existsEndpoint(endpoint: JunctionEndpoint, extra?: PolicyExpression): PolicyExpression {\n const correlation = policy.compare(\n policy.field(getIdPropertyName(endpoint.collection)),\n \"eq\",\n policy.outerField(endpoint.junctionColumn)\n );\n return policy.existsIn({\n collection: endpoint.collection.slug,\n where: extra ? policy.and(correlation, extra) : correlation\n });\n}\n\n/**\n * Whether a parent-rule expression keeps its meaning when moved inside the\n * junction's `EXISTS` subquery — and the re-scoped copy if it does.\n *\n * Returns `null` when the rule cannot be embedded faithfully: `raw` SQL\n * anywhere (its `{column}` placeholders would bind to the junction), or an\n * `outerField` inside a nested `existsIn` (it would bind to the junction while\n * the author meant the parent, and no operand can express \"the middle scope\").\n * Top-level `outerField`s are rewritten to `field`, which is what they meant.\n */\nexport function embedParentExpression(expr: PolicyExpression, depth = 0): PolicyExpression | null {\n switch (expr.kind) {\n case \"raw\":\n return null;\n case \"and\":\n case \"or\": {\n const parts: PolicyExpression[] = [];\n for (const child of expr.operands) {\n const embedded = embedParentExpression(child, depth);\n if (!embedded) return null;\n parts.push(embedded);\n }\n return expr.kind === \"and\" ? policy.and(...parts) : policy.or(...parts);\n }\n case \"not\": {\n const embedded = embedParentExpression(expr.operand, depth);\n return embedded ? policy.not(embedded) : null;\n }\n case \"existsIn\": {\n const where = embedParentExpression(expr.where, depth + 1);\n return where ? policy.existsIn({ collection: expr.collection, where }) : null;\n }\n case \"compare\": {\n const left = embedOperand(expr.left, depth);\n const right = embedOperand(expr.right, depth);\n if (!left || !right) return null;\n return { ...expr, left, right };\n }\n default:\n // Leaf expressions with no field references (true, false,\n // serverContext, authenticated, rolesOverlap, rolesContain) are\n // position-independent.\n return expr;\n }\n}\n\n/** Re-scope an operand, or return `null` if its binding cannot be preserved. */\nfunction embedOperand(operand: PolicyOperand, depth: number): PolicyOperand | null {\n if (operand.kind === \"outerField\") {\n // Outside a subquery, outerField ≡ field: the author meant their own\n // row, which after embedding is the EXISTS's joined table → field.\n if (depth === 0) return policy.field(operand.name);\n // Inside the author's own existsIn it meant the parent row; after\n // embedding it would bind to the junction. Not expressible.\n return null;\n }\n return operand;\n}\n\n/** Does the rule cover the `update` operation? */\nfunction coversUpdate(rule: SecurityRule): boolean {\n return getPolicyOperations(rule).some(op => op === \"update\" || op === \"all\");\n}\n\n/**\n * The full derived policy set for a junction table: the locked server/admin\n * baseline, the endpoint-visibility read grant, inherited write grants, and\n * inherited restrictive gates. Returns `[]` when every declaring collection set\n * `disableDefaultPolicies` — the junction is then the author's to police, and\n * stays locked (RLS is still enabled) until they write policies for it.\n */\nexport function getJunctionSecurityRules(spec: JunctionSpec): SecurityRule[] {\n if (spec.declaringSides.every(side => isPostgresCollectionConfig(side.collection) && side.collection.disableDefaultPolicies)) {\n return [];\n }\n\n const rules: SecurityRule[] = [];\n\n // 1. Locked baseline — same shape and naming as every collection's.\n rules.push({\n name: `${spec.table}_default_admin_read`,\n operations: [\"select\"],\n condition: SERVER_OR_ADMIN_EXPR\n });\n rules.push({\n name: `${spec.table}_default_admin_write`,\n operations: [\"insert\", \"update\", \"delete\"],\n condition: SERVER_OR_ADMIN_EXPR,\n check: SERVER_OR_ADMIN_EXPR\n });\n\n // 2. Reads follow the endpoints: the edge is visible iff both rows are.\n // The EXISTS subqueries run under the caller's role, so each endpoint's\n // own RLS applies inside them — visibility is delegated, not copied.\n rules.push({\n name: `${spec.table}_default_edge_read`,\n operations: [\"select\"],\n condition: policy.and(\n existsEndpoint(spec.endpoints[0]),\n existsEndpoint(spec.endpoints[1])\n )\n });\n\n // 3. Writes follow the owning side's explicit update rules.\n const writeGrants: PolicyExpression[] = [];\n for (const side of spec.declaringSides) {\n const explicitRules = (isPostgresCollectionConfig(side.collection)\n ? side.collection.securityRules\n : undefined) ?? [];\n const updateRules = explicitRules.filter(coversUpdate);\n\n const permissive = updateRules.filter(r => r.mode !== \"restrictive\");\n const restrictive = updateRules.filter(r => r.mode === \"restrictive\");\n\n // Embed the restrictive gates first: if any of them cannot be carried\n // over, granting writes from this side would be looser than the parent\n // itself allows — so the whole side's grant is suppressed.\n const embeddedGates: PolicyExpression[] = [];\n let gatesEmbeddable = true;\n for (const gate of restrictive) {\n const using = securityRuleToConditions(gate).usingExpr;\n const embedded = using ? embedParentExpression(using) : null;\n if (!embedded) {\n gatesEmbeddable = false;\n break;\n }\n embeddedGates.push(embedded);\n }\n if (!gatesEmbeddable) continue;\n\n const grants: PolicyExpression[] = [];\n for (const rule of permissive) {\n const using = securityRuleToConditions(rule).usingExpr;\n const embedded = using ? embedParentExpression(using) : null;\n if (embedded) grants.push(embedded);\n }\n if (grants.length === 0) continue;\n\n // \"May update the owning row\": any permissive grant, AND every gate.\n const condition = embeddedGates.length > 0\n ? policy.and(policy.or(...grants), ...embeddedGates)\n : policy.or(...grants);\n\n writeGrants.push(existsEndpoint(side, condition));\n }\n\n if (writeGrants.length > 0) {\n rules.push({\n name: `${spec.table}_default_edge_write`,\n operations: [\"insert\", \"update\", \"delete\"],\n condition: writeGrants.length === 1 ? writeGrants[0] : policy.or(...writeGrants),\n check: writeGrants.length === 1 ? writeGrants[0] : policy.or(...writeGrants)\n });\n }\n\n return rules;\n}\n","/* globals define,module */\n/*\nUsing a Universal Module Loader that should be browser, require, and AMD friendly\nhttp://ricostacruz.com/cheatsheets/umdjs.html\n*/\n;(function(root, factory) {\n if (typeof define === \"function\" && define.amd) {\n define(factory);\n } else if (typeof exports === \"object\") {\n module.exports = factory();\n } else {\n root.jsonLogic = factory();\n }\n}(this, function() {\n \"use strict\";\n /* globals console:false */\n\n if ( ! Array.isArray) {\n Array.isArray = function(arg) {\n return Object.prototype.toString.call(arg) === \"[object Array]\";\n };\n }\n\n /**\n * Return an array that contains no duplicates (original not modified)\n * @param {array} array Original reference array\n * @return {array} New array with no duplicates\n */\n function arrayUnique(array) {\n var a = [];\n for (var i=0, l=array.length; i<l; i++) {\n if (a.indexOf(array[i]) === -1) {\n a.push(array[i]);\n }\n }\n return a;\n }\n\n var jsonLogic = {};\n var operations = {\n \"==\": function(a, b) {\n return a == b;\n },\n \"===\": function(a, b) {\n return a === b;\n },\n \"!=\": function(a, b) {\n return a != b;\n },\n \"!==\": function(a, b) {\n return a !== b;\n },\n \">\": function(a, b) {\n return a > b;\n },\n \">=\": function(a, b) {\n return a >= b;\n },\n \"<\": function(a, b, c) {\n return (c === undefined) ? a < b : (a < b) && (b < c);\n },\n \"<=\": function(a, b, c) {\n return (c === undefined) ? a <= b : (a <= b) && (b <= c);\n },\n \"!!\": function(a) {\n return jsonLogic.truthy(a);\n },\n \"!\": function(a) {\n return !jsonLogic.truthy(a);\n },\n \"%\": function(a, b) {\n return a % b;\n },\n \"log\": function(a) {\n console.log(a); return a;\n },\n \"in\": function(a, b) {\n if (!b || typeof b.indexOf === \"undefined\") return false;\n return (b.indexOf(a) !== -1);\n },\n \"cat\": function() {\n return Array.prototype.join.call(arguments, \"\");\n },\n \"substr\": function(source, start, end) {\n if (end < 0) {\n // JavaScript doesn't support negative end, this emulates PHP behavior\n var temp = String(source).substr(start);\n return temp.substr(0, temp.length + end);\n }\n return String(source).substr(start, end);\n },\n \"+\": function() {\n return Array.prototype.reduce.call(arguments, function(a, b) {\n return parseFloat(a, 10) + parseFloat(b, 10);\n }, 0);\n },\n \"*\": function() {\n return Array.prototype.reduce.call(arguments, function(a, b) {\n return parseFloat(a, 10) * parseFloat(b, 10);\n });\n },\n \"-\": function(a, b) {\n if (b === undefined) {\n return -a;\n } else {\n return a - b;\n }\n },\n \"/\": function(a, b) {\n return a / b;\n },\n \"min\": function() {\n return Math.min.apply(this, arguments);\n },\n \"max\": function() {\n return Math.max.apply(this, arguments);\n },\n \"merge\": function() {\n return Array.prototype.reduce.call(arguments, function(a, b) {\n return a.concat(b);\n }, []);\n },\n \"var\": function(a, b) {\n var not_found = (b === undefined) ? null : b;\n var data = this;\n if (typeof a === \"undefined\" || a===\"\" || a===null) {\n return data;\n }\n var sub_props = String(a).split(\".\");\n for (var i = 0; i < sub_props.length; i++) {\n if (data === null || data === undefined) {\n return not_found;\n }\n // Descending into data\n data = data[sub_props[i]];\n if (data === undefined) {\n return not_found;\n }\n }\n return data;\n },\n \"missing\": function() {\n /*\n Missing can receive many keys as many arguments, like {\"missing:[1,2]}\n Missing can also receive *one* argument that is an array of keys,\n which typically happens if it's actually acting on the output of another command\n (like 'if' or 'merge')\n */\n\n var missing = [];\n var keys = Array.isArray(arguments[0]) ? arguments[0] : arguments;\n\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n var value = jsonLogic.apply({\"var\": key}, this);\n if (value === null || value === \"\") {\n missing.push(key);\n }\n }\n\n return missing;\n },\n \"missing_some\": function(need_count, options) {\n // missing_some takes two arguments, how many (minimum) items must be present, and an array of keys (just like 'missing') to check for presence.\n var are_missing = jsonLogic.apply({\"missing\": options}, this);\n\n if (options.length - are_missing.length >= need_count) {\n return [];\n } else {\n return are_missing;\n }\n },\n };\n\n jsonLogic.is_logic = function(logic) {\n return (\n typeof logic === \"object\" && // An object\n logic !== null && // but not null\n ! Array.isArray(logic) && // and not an array\n Object.keys(logic).length === 1 // with exactly one key\n );\n };\n\n /*\n This helper will defer to the JsonLogic spec as a tie-breaker when different language interpreters define different behavior for the truthiness of primitives. E.g., PHP considers empty arrays to be falsy, but Javascript considers them to be truthy. JsonLogic, as an ecosystem, needs one consistent answer.\n\n Spec and rationale here: http://jsonlogic.com/truthy\n */\n jsonLogic.truthy = function(value) {\n if (Array.isArray(value) && value.length === 0) {\n return false;\n }\n return !! value;\n };\n\n\n jsonLogic.get_operator = function(logic) {\n return Object.keys(logic)[0];\n };\n\n jsonLogic.get_values = function(logic) {\n return logic[jsonLogic.get_operator(logic)];\n };\n\n jsonLogic.apply = function(logic, data) {\n // Does this array contain logic? Only one way to find out.\n if (Array.isArray(logic)) {\n return logic.map(function(l) {\n return jsonLogic.apply(l, data);\n });\n }\n // You've recursed to a primitive, stop!\n if ( ! jsonLogic.is_logic(logic) ) {\n return logic;\n }\n\n var op = jsonLogic.get_operator(logic);\n var values = logic[op];\n var i;\n var current;\n var scopedLogic;\n var scopedData;\n var initial;\n\n // easy syntax for unary operators, like {\"var\" : \"x\"} instead of strict {\"var\" : [\"x\"]}\n if ( ! Array.isArray(values)) {\n values = [values];\n }\n\n // 'if', 'and', and 'or' violate the normal rule of depth-first calculating consequents, let each manage recursion as needed.\n if (op === \"if\" || op == \"?:\") {\n /* 'if' should be called with a odd number of parameters, 3 or greater\n This works on the pattern:\n if( 0 ){ 1 }else{ 2 };\n if( 0 ){ 1 }else if( 2 ){ 3 }else{ 4 };\n if( 0 ){ 1 }else if( 2 ){ 3 }else if( 4 ){ 5 }else{ 6 };\n\n The implementation is:\n For pairs of values (0,1 then 2,3 then 4,5 etc)\n If the first evaluates truthy, evaluate and return the second\n If the first evaluates falsy, jump to the next pair (e.g, 0,1 to 2,3)\n given one parameter, evaluate and return it. (it's an Else and all the If/ElseIf were false)\n given 0 parameters, return NULL (not great practice, but there was no Else)\n */\n for (i = 0; i < values.length - 1; i += 2) {\n if ( jsonLogic.truthy( jsonLogic.apply(values[i], data) ) ) {\n return jsonLogic.apply(values[i+1], data);\n }\n }\n if (values.length === i+1) {\n return jsonLogic.apply(values[i], data);\n }\n return null;\n } else if (op === \"and\") { // Return first falsy, or last\n for (i=0; i < values.length; i+=1) {\n current = jsonLogic.apply(values[i], data);\n if ( ! jsonLogic.truthy(current)) {\n return current;\n }\n }\n return current; // Last\n } else if (op === \"or\") {// Return first truthy, or last\n for (i=0; i < values.length; i+=1) {\n current = jsonLogic.apply(values[i], data);\n if ( jsonLogic.truthy(current) ) {\n return current;\n }\n }\n return current; // Last\n } else if (op === \"filter\") {\n scopedData = jsonLogic.apply(values[0], data);\n scopedLogic = values[1];\n\n if ( ! Array.isArray(scopedData)) {\n return [];\n }\n // Return only the elements from the array in the first argument,\n // that return truthy when passed to the logic in the second argument.\n // For parity with JavaScript, reindex the returned array\n return scopedData.filter(function(datum) {\n return jsonLogic.truthy( jsonLogic.apply(scopedLogic, datum));\n });\n } else if (op === \"map\") {\n scopedData = jsonLogic.apply(values[0], data);\n scopedLogic = values[1];\n\n if ( ! Array.isArray(scopedData)) {\n return [];\n }\n\n return scopedData.map(function(datum) {\n return jsonLogic.apply(scopedLogic, datum);\n });\n } else if (op === \"reduce\") {\n scopedData = jsonLogic.apply(values[0], data);\n scopedLogic = values[1];\n initial = typeof values[2] !== \"undefined\" ? jsonLogic.apply(values[2], data) : null;\n\n if ( ! Array.isArray(scopedData)) {\n return initial;\n }\n\n return scopedData.reduce(\n function(accumulator, current) {\n return jsonLogic.apply(\n scopedLogic,\n {current: current, accumulator: accumulator}\n );\n },\n initial\n );\n } else if (op === \"all\") {\n scopedData = jsonLogic.apply(values[0], data);\n scopedLogic = values[1];\n // All of an empty set is false. Note, some and none have correct fallback after the for loop\n if ( ! Array.isArray(scopedData) || ! scopedData.length) {\n return false;\n }\n for (i=0; i < scopedData.length; i+=1) {\n if ( ! jsonLogic.truthy( jsonLogic.apply(scopedLogic, scopedData[i]) )) {\n return false; // First falsy, short circuit\n }\n }\n return true; // All were truthy\n } else if (op === \"none\") {\n scopedData = jsonLogic.apply(values[0], data);\n scopedLogic = values[1];\n\n if ( ! Array.isArray(scopedData) || ! scopedData.length) {\n return true;\n }\n for (i=0; i < scopedData.length; i+=1) {\n if ( jsonLogic.truthy( jsonLogic.apply(scopedLogic, scopedData[i]) )) {\n return false; // First truthy, short circuit\n }\n }\n return true; // None were truthy\n } else if (op === \"some\") {\n scopedData = jsonLogic.apply(values[0], data);\n scopedLogic = values[1];\n\n if ( ! Array.isArray(scopedData) || ! scopedData.length) {\n return false;\n }\n for (i=0; i < scopedData.length; i+=1) {\n if ( jsonLogic.truthy( jsonLogic.apply(scopedLogic, scopedData[i]) )) {\n return true; // First truthy, short circuit\n }\n }\n return false; // None were truthy\n }\n\n // Everyone else gets immediate depth-first recursion\n values = values.map(function(val) {\n return jsonLogic.apply(val, data);\n });\n\n\n // The operation is called with \"data\" bound to its \"this\" and \"values\" passed as arguments.\n // Structured commands like % or > can name formal arguments while flexible commands (like missing or merge) can operate on the pseudo-array arguments\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments\n if (operations.hasOwnProperty(op) && typeof operations[op] === \"function\") {\n return operations[op].apply(data, values);\n } else if (op.indexOf(\".\") > 0) { // Contains a dot, and not in the 0th position\n var sub_ops = String(op).split(\".\");\n var operation = operations;\n for (i = 0; i < sub_ops.length; i++) {\n if (!operation.hasOwnProperty(sub_ops[i])) {\n throw new Error(\"Unrecognized operation \" + op +\n \" (failed at \" + sub_ops.slice(0, i+1).join(\".\") + \")\");\n }\n // Descending into operations\n operation = operation[sub_ops[i]];\n }\n\n return operation.apply(data, values);\n }\n\n throw new Error(\"Unrecognized operation \" + op );\n };\n\n jsonLogic.uses_data = function(logic) {\n var collection = [];\n\n if (jsonLogic.is_logic(logic)) {\n var op = jsonLogic.get_operator(logic);\n var values = logic[op];\n\n if ( ! Array.isArray(values)) {\n values = [values];\n }\n\n if (op === \"var\") {\n // This doesn't cover the case where the arg to var is itself a rule.\n collection.push(values[0]);\n } else {\n // Recursion!\n values.forEach(function(val) {\n collection.push.apply(collection, jsonLogic.uses_data(val) );\n });\n }\n }\n\n return arrayUnique(collection);\n };\n\n jsonLogic.add_operation = function(name, code) {\n operations[name] = code;\n };\n\n jsonLogic.rm_operation = function(name) {\n delete operations[name];\n };\n\n jsonLogic.rule_like = function(rule, pattern) {\n // console.log(\"Is \". JSON.stringify(rule) . \" like \" . JSON.stringify(pattern) . \"?\");\n if (pattern === rule) {\n return true;\n } // TODO : Deep object equivalency?\n if (pattern === \"@\") {\n return true;\n } // Wildcard!\n if (pattern === \"number\") {\n return (typeof rule === \"number\");\n }\n if (pattern === \"string\") {\n return (typeof rule === \"string\");\n }\n if (pattern === \"array\") {\n // !logic test might be superfluous in JavaScript\n return Array.isArray(rule) && ! jsonLogic.is_logic(rule);\n }\n\n if (jsonLogic.is_logic(pattern)) {\n if (jsonLogic.is_logic(rule)) {\n var pattern_op = jsonLogic.get_operator(pattern);\n var rule_op = jsonLogic.get_operator(rule);\n\n if (pattern_op === \"@\" || pattern_op === rule_op) {\n // echo \"\\nOperators match, go deeper\\n\";\n return jsonLogic.rule_like(\n jsonLogic.get_values(rule, false),\n jsonLogic.get_values(pattern, false)\n );\n }\n }\n return false; // pattern is logic, rule isn't, can't be eq\n }\n\n if (Array.isArray(pattern)) {\n if (Array.isArray(rule)) {\n if (pattern.length !== rule.length) {\n return false;\n }\n /*\n Note, array order MATTERS, because we're using this array test logic to consider arguments, where order can matter. (e.g., + is commutative, but '-' or 'if' or 'var' are NOT)\n */\n for (var i = 0; i < pattern.length; i += 1) {\n // If any fail, we fail\n if ( ! jsonLogic.rule_like(rule[i], pattern[i])) {\n return false;\n }\n }\n return true; // If they *all* passed, we pass\n } else {\n return false; // Pattern is array, rule isn't\n }\n }\n\n // Not logic, not array, not a === match for rule.\n return false;\n };\n\n return jsonLogic;\n}));\n","import jsonLogic from \"json-logic-js\";\nimport {\n ArrayProperty,\n AuthState,\n ConditionContext,\n ConditionRule,\n EnumValueConfig,\n NumberProperty,\n PropertyConditions,\n Property,\n ReferenceProperty,\n StringProperty\n} from \"@rebasepro/types\";\n\n/**\n * Access a nested property from an object via dot notation.\n */\nfunction getIn(obj: Record<string, unknown> | unknown, path: string): unknown {\n if (!obj || !path) return undefined;\n return path.split(\".\").reduce((acc: unknown, part: string) => acc && (acc as Record<string, unknown>)[part], obj);\n}\n\nlet operationsRegistered = false;\n\n/**\n * Register custom JSON Logic operations for Rebase.\n * Call this once at app initialization.\n */\nexport function registerConditionOperations(): void {\n if (operationsRegistered) return;\n\n // Check if user has a specific role by ID\n jsonLogic.add_operation(\"hasRole\", function (this: ConditionContext, roleId: string) {\n return this?.user?.roles?.includes(roleId) ?? false;\n });\n\n // Check if user has any of the specified roles\n jsonLogic.add_operation(\"hasAnyRole\", function (this: ConditionContext, roleIds: string[]) {\n if (!this?.user?.roles || !Array.isArray(roleIds)) return false;\n return roleIds.some(role => this.user.roles.includes(role));\n });\n\n // Check if a timestamp is today\n jsonLogic.add_operation(\"isToday\", (timestamp: number) => {\n if (!timestamp) return false;\n const date = new Date(timestamp);\n const today = new Date();\n return date.getFullYear() === today.getFullYear() &&\n date.getMonth() === today.getMonth() &&\n date.getDate() === today.getDate();\n });\n\n // Check if a timestamp is in the past\n jsonLogic.add_operation(\"isPast\", (timestamp: number) => {\n if (!timestamp) return false;\n return timestamp < Date.now();\n });\n\n // Check if a timestamp is in the future\n jsonLogic.add_operation(\"isFuture\", (timestamp: number) => {\n if (!timestamp) return false;\n return timestamp > Date.now();\n });\n\n operationsRegistered = true;\n}\n\n/**\n * Evaluate a condition against the given context.\n *\n * A condition may be stated as a literal instead of a rule — `hidden: true`\n * rather than `hidden: { \"==\": [1, 1] }` — and a literal is already its own\n * answer, so it is returned rather than handed to the evaluator.\n */\nexport function evaluateCondition(rule: ConditionRule, context: ConditionContext): unknown {\n if (typeof rule === \"boolean\") return rule;\n // Ensure operations are registered\n registerConditionOperations();\n return jsonLogic.apply(rule, context);\n}\n\n/**\n * Convert a value to a format suitable for JSON Logic evaluation.\n * Specifically handles Date objects by converting them to Unix timestamps.\n */\nfunction serializeValueForConditions(value: unknown): unknown {\n if (value === null || value === undefined) {\n return value;\n }\n\n // Handle Date objects\n if (value instanceof Date) {\n return value.getTime();\n }\n\n // Handle Firestore Timestamp-like objects (have toDate or toMillis)\n if (typeof (value as { toMillis?: () => number })?.toMillis === \"function\") {\n return (value as { toMillis: () => number }).toMillis();\n }\n if (typeof (value as { toDate?: () => Date })?.toDate === \"function\") {\n return (value as { toDate: () => Date }).toDate().getTime();\n }\n\n // Handle arrays recursively\n if (Array.isArray(value)) {\n return value.map(serializeValueForConditions);\n }\n\n // Handle plain objects recursively\n if (typeof value === \"object\") {\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(value as Record<string, unknown>)) {\n result[key] = serializeValueForConditions((value as Record<string, unknown>)[key]);\n }\n return result;\n }\n\n return value;\n}\n\n/**\n * Build a ConditionContext from the current property resolution context.\n */\nexport function buildConditionContext(params: {\n propertyKey?: string;\n values?: Record<string, unknown>;\n previousValues?: Record<string, unknown>;\n path: string;\n entityId?: string;\n index?: number;\n authController: AuthState;\n}): ConditionContext {\n const {\n propertyKey,\n values,\n previousValues,\n path,\n entityId,\n index,\n authController\n } = params;\n\n const user = authController.user;\n const serializedValues = serializeValueForConditions(values ?? {});\n const serializedPreviousValues = serializeValueForConditions(previousValues ?? values ?? {});\n\n return {\n values: serializedValues as Record<string, unknown>,\n previousValues: serializedPreviousValues as Record<string, unknown>,\n propertyValue: propertyKey ? getIn(serializedValues, propertyKey) : undefined,\n path,\n entityId,\n isNew: !entityId,\n index,\n user: {\n uid: user?.uid ?? \"\",\n email: user?.email ?? null,\n displayName: user?.displayName ?? null,\n photoURL: user?.photoURL ?? null,\n roles: (user?.roles ?? []).map((r: unknown) => typeof r === \"string\" ? r : (r as { id: string }).id)\n },\n now: Date.now()\n };\n}\n\n/**\n * Apply PropertyConditions to a resolved property, evaluating all JSON Logic rules.\n */\n","import type { StringProperty } from \"@rebasepro/types\";\n\n/**\n * The length a bounded string column is declared with when the property does\n * not say. Historical: it is what the DDL generator hardcoded, kept so that\n * regenerating an existing schema does not silently redefine its columns.\n */\nexport const DEFAULT_STRING_COLUMN_LENGTH = 255;\n\n/**\n * How wide a `varchar`/`char` column should be for a given property.\n *\n * One definition, three call sites, because they used to disagree. For the same\n * `columnType: \"varchar\"` property the DDL generator emitted `VARCHAR(255)`\n * while the Drizzle generator emitted a bare `varchar(\"col\")` — which Postgres\n * reads as *unbounded* — so which of the two you ran decided whether the column\n * had a limit at all. Introspection then dropped the length entirely, so reading\n * an existing `character varying(500)` column back and regenerating it produced\n * a `VARCHAR(255)`: a silent narrowing of a column with data already in it.\n *\n * `validation.max` is the property's own statement about how long the value may\n * be, so it is the only sensible source for the column's width — and it keeps\n * the constraint the database enforces in step with the one the app enforces,\n * rather than inventing a second, different limit underneath it.\n */\nexport function resolveStringColumnLength(prop: Pick<StringProperty, \"validation\">): number {\n const max = prop.validation?.max;\n return typeof max === \"number\" && Number.isInteger(max) && max > 0\n ? max\n : DEFAULT_STRING_COLUMN_LENGTH;\n}\n","const { getOwnPropertyNames, getOwnPropertySymbols } = Object;\n// eslint-disable-next-line @typescript-eslint/unbound-method\nconst { hasOwnProperty } = Object.prototype;\n/**\n * Combine two comparators into a single comparators.\n */\nfunction combineComparators(comparatorA, comparatorB) {\n return function isEqual(a, b, state) {\n return comparatorA(a, b, state) && comparatorB(a, b, state);\n };\n}\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular state, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nfunction createIsCircular(areItemsEqual) {\n return function isCircular(a, b, state) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, state);\n }\n const { cache } = state;\n const cachedA = cache.get(a);\n const cachedB = cache.get(b);\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n cache.set(a, b);\n cache.set(b, a);\n const result = areItemsEqual(a, b, state);\n cache.delete(a);\n cache.delete(b);\n return result;\n };\n}\n/**\n * Get the properties to strictly examine, which include both own properties that are\n * not enumerable and symbol properties.\n */\nfunction getStrictProperties(object) {\n const symbols = getOwnPropertySymbols(object);\n return symbols.length\n ? getOwnPropertyNames(object).concat(symbols)\n : getOwnPropertyNames(object);\n}\n/**\n * Whether the object contains the property passed as an own property.\n */\nconst hasOwn = \n// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\nObject.hasOwn || ((object, property) => hasOwnProperty.call(object, property));\n\nconst PREACT_VNODE = '__v';\nconst PREACT_OWNER = '__o';\nconst REACT_OWNER = '_owner';\nconst { getOwnPropertyDescriptor, keys } = Object;\n/**\n * Whether the values passed are equal based on a [SameValue](https://262.ecma-international.org/7.0/#sec-samevalue) basis.\n * Simplified, this maps to if the two values are referentially equal to one another (`a === b`) or both are `NaN`.\n *\n * @note\n * When available in the environment, this is just a re-export of the global\n * [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) method.\n */\nconst sameValueEqual = \n// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\nObject.is\n || function sameValueEqual(a, b) {\n return a === b ? a !== 0 || 1 / a === 1 / b : a !== a && b !== b;\n };\n/**\n * Whether the values passed are equal based on a [SameValue](https://262.ecma-international.org/7.0/#sec-samevaluezero) basis.\n * Simplified, this maps to if the two values are referentially equal to one another (`a === b`), both are `NaN`, or both\n * are either positive or negative zero.\n */\nfunction sameValueZeroEqual(a, b) {\n return a === b || (a !== a && b !== b);\n}\n/**\n * Whether the values passed are equal based on a\n * [Strict Equality Comparison](https://262.ecma-international.org/7.0/#sec-strict-equality-comparison) basis.\n * Simplified, this maps to if the two values are referentially equal to one another (`a === b`).\n *\n * @note\n * This is mainly available as a convenience function, such as being a default when a function to determine equality between\n * two objects is used.\n */\nfunction strictEqual(a, b) {\n return a === b;\n}\n/**\n * Whether the array buffers are equal in value.\n */\nfunction areArrayBuffersEqual(a, b) {\n return a.byteLength === b.byteLength && areTypedArraysEqual(new Uint8Array(a), new Uint8Array(b));\n}\n/**\n * Whether the arrays are equal in value.\n */\nfunction areArraysEqual(a, b, state) {\n let index = a.length;\n if (b.length !== index) {\n return false;\n }\n while (index-- > 0) {\n if (!state.equals(a[index], b[index], index, index, a, b, state)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the dataviews are equal in value.\n */\nfunction areDataViewsEqual(a, b) {\n return (a.byteLength === b.byteLength\n && areTypedArraysEqual(new Uint8Array(a.buffer, a.byteOffset, a.byteLength), new Uint8Array(b.buffer, b.byteOffset, b.byteLength)));\n}\n/**\n * Whether the dates passed are equal in value.\n */\nfunction areDatesEqual(a, b) {\n return sameValueEqual(a.getTime(), b.getTime());\n}\n/**\n * Whether the errors passed are equal in value.\n */\nfunction areErrorsEqual(a, b) {\n return a.name === b.name && a.message === b.message && a.cause === b.cause && a.stack === b.stack;\n}\n/**\n * Whether the `Map`s are equal in value.\n */\nfunction areMapsEqual(a, b, state) {\n const size = a.size;\n if (size !== b.size) {\n return false;\n }\n if (!size) {\n return true;\n }\n const matchedIndices = new Uint8Array(size);\n const aIterable = a.entries();\n let aResult;\n let bResult;\n let index = 0;\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n const bIterable = b.entries();\n let hasMatch = 0;\n let matchIndex = 0;\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (matchedIndices[matchIndex]) {\n matchIndex++;\n continue;\n }\n const aEntry = aResult.value;\n const bEntry = bResult.value;\n if (state.equals(aEntry[0], bEntry[0], index, matchIndex, a, b, state)\n && state.equals(aEntry[1], bEntry[1], aEntry[0], bEntry[0], a, b, state)) {\n hasMatch = matchedIndices[matchIndex] = 1;\n break;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n index++;\n }\n return true;\n}\n/**\n * Whether the objects are equal in value.\n */\nfunction areObjectsEqual(a, b, state) {\n const properties = keys(a);\n let index = properties.length;\n if (keys(b).length !== index) {\n return false;\n }\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n if (!isPropertyEqual(a, b, state, properties[index])) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the objects are equal in value with strict property checking.\n */\nfunction areObjectsEqualStrict(a, b, state) {\n const properties = getStrictProperties(a);\n let index = properties.length;\n if (getStrictProperties(b).length !== index) {\n return false;\n }\n let property;\n let descriptorA;\n let descriptorB;\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n property = properties[index];\n if (!isPropertyEqual(a, b, state, property)) {\n return false;\n }\n descriptorA = getOwnPropertyDescriptor(a, property);\n descriptorB = getOwnPropertyDescriptor(b, property);\n if ((descriptorA || descriptorB)\n && (!descriptorA\n || !descriptorB\n || descriptorA.configurable !== descriptorB.configurable\n || descriptorA.enumerable !== descriptorB.enumerable\n || descriptorA.writable !== descriptorB.writable)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the primitive wrappers passed are equal in value.\n */\nfunction arePrimitiveWrappersEqual(a, b) {\n return sameValueEqual(a.valueOf(), b.valueOf());\n}\n/**\n * Whether the regexps passed are equal in value.\n */\nfunction areRegExpsEqual(a, b) {\n return a.source === b.source && a.flags === b.flags;\n}\n/**\n * Whether the `Set`s are equal in value.\n */\nfunction areSetsEqual(a, b, state) {\n const size = a.size;\n if (size !== b.size) {\n return false;\n }\n if (!size) {\n return true;\n }\n const matchedIndices = new Uint8Array(size);\n const aIterable = a.values();\n let aResult;\n let bResult;\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n while ((aResult = aIterable.next())) {\n if (aResult.done) {\n break;\n }\n const bIterable = b.values();\n let hasMatch = 0;\n let matchIndex = 0;\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n while ((bResult = bIterable.next())) {\n if (bResult.done) {\n break;\n }\n if (!matchedIndices[matchIndex]\n && state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state)) {\n hasMatch = matchedIndices[matchIndex] = 1;\n break;\n }\n matchIndex++;\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the TypedArray instances are equal in value.\n */\nfunction areTypedArraysEqual(a, b) {\n let index = a.length;\n if (b.length !== index || a.byteOffset !== b.byteOffset) {\n return false;\n }\n while (index-- > 0) {\n if (a[index] !== b[index]) {\n return false;\n }\n }\n return true;\n}\n/**\n * Whether the URL instances are equal in value.\n */\nfunction areUrlsEqual(a, b) {\n return (a.hostname === b.hostname\n && a.pathname === b.pathname\n && a.protocol === b.protocol\n && a.port === b.port\n && a.hash === b.hash\n && a.username === b.username\n && a.password === b.password);\n}\nfunction isPropertyEqual(a, b, state, property) {\n if ((property === REACT_OWNER || property === PREACT_OWNER || property === PREACT_VNODE)\n && (a.$$typeof || b.$$typeof)) {\n return true;\n }\n return hasOwn(b, property) && state.equals(a[property], b[property], property, property, a, b, state);\n}\n\n// eslint-disable-next-line @typescript-eslint/unbound-method\nconst toString = Object.prototype.toString;\n/**\n * Create a comparator method based on the type-specific equality comparators passed.\n */\nfunction createEqualityComparator(config) {\n const supportedComparatorMap = createSupportedComparatorMap(config);\n const { areArraysEqual, areDatesEqual, areFunctionsEqual, areMapsEqual, areNumbersEqual, areObjectsEqual, areRegExpsEqual, areSetsEqual, getUnsupportedCustomComparator, } = config;\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n return function comparator(a, b, state) {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n // If either of the items are nullish and fail the strictly equal check\n // above, then they must be unequal.\n if (a == null || b == null) {\n return false;\n }\n const type = typeof a;\n if (type !== typeof b) {\n return false;\n }\n if (type !== 'object') {\n if (type === 'number' || type === 'bigint') {\n return areNumbersEqual(a, b, state);\n }\n if (type === 'function') {\n return areFunctionsEqual(a, b, state);\n }\n // If a primitive value that is not strictly equal, it must be unequal.\n return false;\n }\n const constructor = a.constructor;\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n // Constructors should match, otherwise there is potential for false positives\n // between class and subclass or custom object and POJO.\n if (constructor !== b.constructor) {\n return false;\n }\n // Try to fast-path equality checks for other complex object types in the\n // same realm to avoid capturing the string tag. Strict equality is used\n // instead of `instanceof` because it is more performant for the common\n // use-case. If someone is creating a subclass from a native class, it will be\n // handled with the string tag comparison.\n if (constructor === Object) {\n return areObjectsEqual(a, b, state);\n }\n if (constructor === Array) {\n return areArraysEqual(a, b, state);\n }\n if (constructor === Date) {\n return areDatesEqual(a, b, state);\n }\n if (constructor === RegExp) {\n return areRegExpsEqual(a, b, state);\n }\n if (constructor === Map) {\n return areMapsEqual(a, b, state);\n }\n if (constructor === Set) {\n return areSetsEqual(a, b, state);\n }\n if (constructor === Promise) {\n // Avoid tag checks for promise values, since we know if they are not referentially equal\n // then they are not equal.\n return false;\n }\n // `isArray()` works on subclasses and is cross-realm, so we can avoid capturing\n // the string tag or doing an `instanceof` in edge cases.\n if (Array.isArray(a)) {\n return areArraysEqual(a, b, state);\n }\n // Since this is a custom object, capture the string tag to determining its type.\n // This is reasonably performant in modern environments like v8 and SpiderMonkey.\n const tag = toString.call(a);\n const supportedComparator = supportedComparatorMap[tag];\n if (supportedComparator) {\n return supportedComparator(a, b, state);\n }\n const unsupportedCustomComparator = getUnsupportedCustomComparator && getUnsupportedCustomComparator(a, b, state, tag);\n if (unsupportedCustomComparator) {\n return unsupportedCustomComparator(a, b, state);\n }\n // If not matching any tags that require a specific type of comparison, then we hard-code false because\n // the only thing remaining is strict equality, which has already been compared. This is for a few reasons:\n // - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only\n // comparison that can be made.\n // - For types that can be introspected but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return false;\n };\n}\n/**\n * Create the configuration object used for building comparators.\n */\nfunction createEqualityComparatorConfig({ circular, createCustomConfig, strict, }) {\n let config = {\n areArrayBuffersEqual,\n areArraysEqual: strict ? areObjectsEqualStrict : areArraysEqual,\n areDataViewsEqual,\n areDatesEqual: areDatesEqual,\n areErrorsEqual: areErrorsEqual,\n areFunctionsEqual: strictEqual,\n areMapsEqual: strict ? combineComparators(areMapsEqual, areObjectsEqualStrict) : areMapsEqual,\n areNumbersEqual: sameValueEqual,\n areObjectsEqual: strict ? areObjectsEqualStrict : areObjectsEqual,\n arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,\n areRegExpsEqual: areRegExpsEqual,\n areSetsEqual: strict ? combineComparators(areSetsEqual, areObjectsEqualStrict) : areSetsEqual,\n areTypedArraysEqual: strict\n ? combineComparators(areTypedArraysEqual, areObjectsEqualStrict)\n : areTypedArraysEqual,\n areUrlsEqual: areUrlsEqual,\n getUnsupportedCustomComparator: undefined,\n };\n if (createCustomConfig) {\n config = Object.assign({}, config, createCustomConfig(config));\n }\n if (circular) {\n const areArraysEqual = createIsCircular(config.areArraysEqual);\n const areMapsEqual = createIsCircular(config.areMapsEqual);\n const areObjectsEqual = createIsCircular(config.areObjectsEqual);\n const areSetsEqual = createIsCircular(config.areSetsEqual);\n config = Object.assign({}, config, {\n areArraysEqual,\n areMapsEqual,\n areObjectsEqual,\n areSetsEqual,\n });\n }\n return config;\n}\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nfunction createInternalEqualityComparator(compare) {\n return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {\n return compare(a, b, state);\n };\n}\n/**\n * Create the `isEqual` function used by the consuming application.\n */\nfunction createIsEqual({ circular, comparator, createState, equals, strict }) {\n if (createState) {\n return function isEqual(a, b) {\n const { cache = circular ? new WeakMap() : undefined, meta } = createState();\n return comparator(a, b, {\n cache,\n equals,\n meta,\n strict,\n });\n };\n }\n if (circular) {\n return function isEqual(a, b) {\n return comparator(a, b, {\n cache: new WeakMap(),\n equals,\n meta: undefined,\n strict,\n });\n };\n }\n const state = {\n cache: undefined,\n equals,\n meta: undefined,\n strict,\n };\n return function isEqual(a, b) {\n return comparator(a, b, state);\n };\n}\n/**\n * Create a map of `toString()` values to their respective handlers for `tag`-based lookups.\n */\nfunction createSupportedComparatorMap({ areArrayBuffersEqual, areArraysEqual, areDataViewsEqual, areDatesEqual, areErrorsEqual, areFunctionsEqual, areMapsEqual, areNumbersEqual, areObjectsEqual, arePrimitiveWrappersEqual, areRegExpsEqual, areSetsEqual, areTypedArraysEqual, areUrlsEqual, }) {\n return {\n '[object Arguments]': areObjectsEqual,\n '[object Array]': areArraysEqual,\n '[object ArrayBuffer]': areArrayBuffersEqual,\n '[object AsyncGeneratorFunction]': areFunctionsEqual,\n '[object BigInt]': areNumbersEqual,\n '[object BigInt64Array]': areTypedArraysEqual,\n '[object BigUint64Array]': areTypedArraysEqual,\n '[object Boolean]': arePrimitiveWrappersEqual,\n '[object DataView]': areDataViewsEqual,\n '[object Date]': areDatesEqual,\n // If an error tag, it should be tested explicitly. Like RegExp, the properties are not\n // enumerable, and therefore will give false positives if tested like a standard object.\n '[object Error]': areErrorsEqual,\n '[object Float16Array]': areTypedArraysEqual,\n '[object Float32Array]': areTypedArraysEqual,\n '[object Float64Array]': areTypedArraysEqual,\n '[object Function]': areFunctionsEqual,\n '[object GeneratorFunction]': areFunctionsEqual,\n '[object Int8Array]': areTypedArraysEqual,\n '[object Int16Array]': areTypedArraysEqual,\n '[object Int32Array]': areTypedArraysEqual,\n '[object Map]': areMapsEqual,\n '[object Number]': arePrimitiveWrappersEqual,\n '[object Object]': (a, b, state) => \n // The exception for value comparison is custom `Promise`-like class instances. These should\n // be treated the same as standard `Promise` objects, which means strict equality, and if\n // it reaches this point then that strict equality comparison has already failed.\n typeof a.then !== 'function' && typeof b.then !== 'function' && areObjectsEqual(a, b, state),\n // For RegExp, the properties are not enumerable, and therefore will give false positives if\n // tested like a standard object.\n '[object RegExp]': areRegExpsEqual,\n '[object Set]': areSetsEqual,\n '[object String]': arePrimitiveWrappersEqual,\n '[object URL]': areUrlsEqual,\n '[object Uint8Array]': areTypedArraysEqual,\n '[object Uint8ClampedArray]': areTypedArraysEqual,\n '[object Uint16Array]': areTypedArraysEqual,\n '[object Uint32Array]': areTypedArraysEqual,\n };\n}\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nconst deepEqual = createCustomEqual();\n/**\n * Whether the items passed are deeply-equal in value based on strict comparison.\n */\nconst strictDeepEqual = createCustomEqual({ strict: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nconst circularDeepEqual = createCustomEqual({ circular: true });\n/**\n * Whether the items passed are deeply-equal in value, including circular references,\n * based on strict comparison.\n */\nconst strictCircularDeepEqual = createCustomEqual({\n circular: true,\n strict: true,\n});\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nconst shallowEqual = createCustomEqual({\n createInternalComparator: () => sameValueEqual,\n});\n/**\n * Whether the items passed are shallowly-equal in value based on strict comparison\n */\nconst strictShallowEqual = createCustomEqual({\n strict: true,\n createInternalComparator: () => sameValueEqual,\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nconst circularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: () => sameValueEqual,\n});\n/**\n * Whether the items passed are shallowly-equal in value, including circular references,\n * based on strict comparison.\n */\nconst strictCircularShallowEqual = createCustomEqual({\n circular: true,\n createInternalComparator: () => sameValueEqual,\n strict: true,\n});\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nfunction createCustomEqual(options = {}) {\n const { circular = false, createInternalComparator: createCustomInternalComparator, createState, strict = false, } = options;\n const config = createEqualityComparatorConfig(options);\n const comparator = createEqualityComparator(config);\n const equals = createCustomInternalComparator\n ? createCustomInternalComparator(comparator)\n : createInternalEqualityComparator(comparator);\n return createIsEqual({ circular, comparator, createState, equals, strict });\n}\n\nexport { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictEqual, strictShallowEqual };\n","import {\n DataSourceDefinition,\n ResolvedDataSource,\n DEFAULT_DATA_SOURCE_KEY,\n getDataSourceCapabilities\n} from \"@rebasepro/types\";\n\n/**\n * The subset of a collection needed to resolve its data source. Accepting a\n * structural type (rather than the full `CollectionConfig`) keeps this usable\n * from anywhere — frontend router, backend registry, editor — without coupling\n * to the collection union.\n */\nexport interface DataSourceResolvable {\n /** Preferred routing key. */\n dataSource?: string;\n /** Engine type discriminant (set on variant collection types). */\n engine?: string;\n /** Within-engine instance. */\n databaseId?: string;\n}\n\n/** A lookup of data-source definitions by key. */\nexport type DataSourceRegistry = Record<string, DataSourceDefinition>;\n\n/**\n * Build a keyed registry from a list of {@link DataSourceDefinition}s.\n * Later entries win on key collision.\n */\nexport function createDataSourceRegistry(definitions?: DataSourceDefinition[]): DataSourceRegistry {\n const registry: DataSourceRegistry = {};\n for (const def of definitions ?? []) {\n registry[def.key] = def;\n }\n return registry;\n}\n\n/**\n * Resolve the effective data source for a collection — the single source of\n * truth shared by the frontend router, the backend driver registry, and the\n * editor's capability lookups.\n *\n * Resolution order:\n * 1. The routing **key** is `collection.dataSource`, else\n * {@link DEFAULT_DATA_SOURCE_KEY}.\n * 2. If a definition is registered for that key, it provides `engine`,\n * `transport`, and `databaseId`.\n * 3. Otherwise values are synthesized: `engine` from `collection.engine`\n * (or the key, or `\"postgres\"`), `transport` defaults to `\"server\"`,\n * and `databaseId` from the collection.\n *\n * `capabilities` are always derived from the resolved `engine`, so two\n * data sources sharing an engine share capabilities.\n *\n * @param collection the collection (or any object carrying the routing fields)\n * @param registry optional registry of declared data sources\n */\nexport function resolveDataSource(\n collection: DataSourceResolvable | undefined,\n registry?: DataSourceRegistry\n): ResolvedDataSource {\n const key = collection?.dataSource ?? DEFAULT_DATA_SOURCE_KEY;\n const def = registry?.[key];\n\n const engine = def?.engine\n ?? collection?.engine\n ?? (key !== DEFAULT_DATA_SOURCE_KEY ? key : \"postgres\");\n\n const transport = def?.transport ?? \"server\";\n const databaseId = collection?.databaseId ?? def?.databaseId;\n\n return {\n key,\n engine,\n transport,\n databaseId,\n capabilities: getDataSourceCapabilities(engine)\n };\n}\n\n/**\n * Does a SQL toolchain own this collection's storage?\n *\n * \"Owns the storage\" means: something generates a table for it, pushes that\n * table to a database, plans its RLS policies, and reports it as drifted when\n * the two disagree. That is true of a Postgres collection and false of a\n * Firestore or MongoDB one, whose documents live in a store Rebase never\n * migrates — and the two were never told apart. Every stage of the SQL\n * toolchain took \"the collections\" to mean *all* of them, so a Firestore\n * collection declared next to the Postgres ones got a `pgTable` in the\n * generated schema, a `CREATE TABLE` at boot, RLS policies, and a place in the\n * `db push` include list — where its name shielding a same-named real table\n * from Atlas's exclude list is the one that can lose data.\n *\n * The answer is the resolved engine's {@link DataSourceCapabilities}, not a\n * name check: an engine registered through `registerDataSourceCapabilities`\n * gets the same treatment as the built-in ones.\n *\n * Deliberately answers **true** for an engine nobody has heard of. Build-time\n * tooling (the CLI, the schema generator) has no data-source registry to\n * resolve a `dataSource` key against, so an unknown key resolves to an unknown\n * engine — and the cost of the two mistakes is not symmetric. Wrongly\n * including a collection generates a table nothing writes to; wrongly excluding\n * one silently stops generating a table the app is serving from. Declare\n * `engine` on a collection that is not SQL-backed and this is exact.\n */\nexport function isRelationalCollection(\n collection: DataSourceResolvable | undefined,\n registry?: DataSourceRegistry\n): boolean {\n // The collection's own `engine` wins over a registered definition's. That\n // is the opposite of {@link resolveDataSource}'s precedence, deliberately:\n // there a definition describes where the data *goes*, so it should override;\n // here the question is what the author said this collection is, and a\n // collection declaring `engine: \"firestore\"` with no `dataSource` must not\n // come back as the default source's engine and be handed a table.\n const engine = collection?.engine\n ?? (collection?.dataSource ? resolveDataSource(collection, registry).engine : undefined);\n return getDataSourceCapabilities(engine).supportsRelations;\n}\n\n/**\n * The subset of `collections` a SQL toolchain owns — see\n * {@link isRelationalCollection}.\n *\n * Every stage that generates SQL from collections starts by calling this, so\n * the rule lives in one place rather than being re-decided per generator. It\n * keeps the input order.\n */\nexport function relationalCollections<C extends DataSourceResolvable>(\n collections: readonly C[],\n registry?: DataSourceRegistry\n): C[] {\n return collections.filter(collection => isRelationalCollection(collection, registry));\n}\n","import {\n ArrayProperty,\n CollectionCallbacks,\n EngineProperties,\n CollectionConfig,\n getDataSourceCapabilities,\n getDeclaredSubcollections,\n NumberProperty,\n Properties,\n Property,\n Relation,\n RelationProperty,\n StringProperty\n} from \"@rebasepro/types\";\nimport { deepEqual } from \"fast-equals\";\n\nimport {\n enumToObjectEntries,\n findRelation,\n getSubcollections,\n getTableName,\n resolveCollectionRelations,\n resolveRelation\n} from \"../util\";\nimport { deepClone, mergeDeep, removeFunctions } from \"@rebasepro/utils\";\nimport { DataSourceRegistry, resolveDataSource } from \"../data/resolveDataSource\";\n\nexport class CollectionRegistry {\n\n /**\n * Declared data sources, used during normalization to resolve each\n * collection's engine (so `dataSource`-only collections get the right\n * capabilities). Empty by default.\n */\n private dataSources: DataSourceRegistry = {};\n\n /**\n * Global lifecycle callbacks applied to every collection.\n * Runs on all data paths (REST, WebSocket, `rebase.data`).\n * Execution order: global → collection → property callbacks.\n */\n private _globalCallbacks?: CollectionCallbacks;\n\n /**\n * Set global lifecycle callbacks that apply to every collection.\n * Typically called once during backend initialization.\n */\n setGlobalCallbacks(callbacks: CollectionCallbacks): void {\n this._globalCallbacks = callbacks;\n }\n\n /**\n * Get the currently registered global callbacks, if any.\n */\n getGlobalCallbacks(): CollectionCallbacks | undefined {\n return this._globalCallbacks;\n }\n\n // Normalized runtime layer (used by Data Grid / UI)\n private collectionsByTableName = new Map<string, CollectionConfig>();\n private collectionsBySlug = new Map<string, CollectionConfig>();\n private rootCollections: CollectionConfig[] = [];\n private cachedCollectionsList: CollectionConfig[] | null = null;\n\n // Raw configuration layer (used by Collection Editor AST generator)\n private rawCollectionsByTableName = new Map<string, CollectionConfig>();\n private rawCollectionsBySlug = new Map<string, CollectionConfig>();\n private rawRootCollections: CollectionConfig[] = [];\n private cachedRawCollectionsList: CollectionConfig[] | null = null;\n\n // Entity of raw input for idempotency check — compared BEFORE normalization\n // to avoid the issue where normalization creates new objects that always fail equality.\n private lastRawInputEntity: ReturnType<typeof removeFunctions>[] | null = null;\n\n constructor(collections?: CollectionConfig[], dataSources?: DataSourceRegistry) {\n if (dataSources) this.dataSources = dataSources;\n if (collections) {\n this.registerMultiple(collections);\n }\n }\n\n /**\n * Provide the declared data sources used to resolve each collection's\n * engine during normalization. Set this before registering collections.\n * Returns true if the registry changed (callers may re-register).\n */\n setDataSources(dataSources: DataSourceRegistry): boolean {\n if (deepEqual(this.dataSources, dataSources)) return false;\n this.dataSources = dataSources ?? {};\n return true;\n }\n\n reset() {\n this.collectionsByTableName.clear();\n this.collectionsBySlug.clear();\n this.rootCollections = [];\n this.cachedCollectionsList = null;\n\n this.rawCollectionsByTableName.clear();\n this.rawCollectionsBySlug.clear();\n this.rawRootCollections = [];\n this.cachedRawCollectionsList = null;\n }\n\n /**\n * Registers a collection and its subcollections recursively.\n * Returns true if the collections have changed, false otherwise.\n *\n * Idempotent: compares the raw input (before normalization) against a stored\n * entity. Only re-normalizes and re-registers when the raw input actually changed.\n * @param collections\n */\n registerMultiple(collections: CollectionConfig[]): boolean {\n // Compare raw input BEFORE normalization to detect actual changes.\n // This avoids the old issue where normalization creates new objects\n // that always fail deep-equal even when the source data is identical.\n const rawEntity = collections.map(c => removeFunctions(c));\n if (this.lastRawInputEntity && deepEqual(this.lastRawInputEntity, rawEntity)) {\n return false;\n }\n\n this.reset();\n // Phase 0: Populate maps with raw collections first for string target resolution\n collections.forEach((c) => {\n if (c.slug) {\n this.collectionsBySlug.set(c.slug, c);\n }\n this.collectionsByTableName.set(getTableName(c), c);\n });\n\n const normalizedCollections = collections.map(c => this.normalizeCollection({ ...c }));\n\n // Phase 1: Register all top-level collections first (without recursion).\n // This ensures that injected entityViews (e.g. History tab) are preserved.\n // Without this, _registerRecursively could register a relation-target collection\n // (e.g. Tags from Posts.relations) using the raw module object (without injected views)\n // before the top-level Tags collection (with injected views) gets its turn.\n normalizedCollections.forEach((c, index) => {\n const raw = deepClone(collections[index]);\n this.rootCollections.push(c);\n this.rawRootCollections.push(raw);\n\n const normalized = this.normalizeCollection(c);\n this.collectionsByTableName.set(getTableName(normalized), normalized);\n this.rawCollectionsByTableName.set(getTableName(raw), raw);\n if (normalized.slug) {\n this.collectionsBySlug.set(normalized.slug, normalized);\n }\n if (raw.slug) {\n this.rawCollectionsBySlug.set(raw.slug, raw);\n }\n });\n\n // Phase 2: Now recurse into subcollections (relations, etc.)\n normalizedCollections.forEach((c) => {\n const subcollections = getSubcollections(c);\n if (subcollections && subcollections.length > 0) {\n subcollections.forEach((subCollection) => {\n if (!subCollection) return;\n // Spread to avoid mutating the original target() return value\n this._registerRecursively(this.normalizeCollection({ ...subCollection }), deepClone(subCollection));\n });\n }\n });\n\n // Store the entity for future comparisons\n this.lastRawInputEntity = rawEntity;\n\n return true;\n }\n\n register(collection: CollectionConfig, rawCollection?: CollectionConfig) {\n const raw = rawCollection ? deepClone(rawCollection) : deepClone(collection);\n\n this.rootCollections.push(collection);\n this.rawRootCollections.push(raw);\n\n this._registerRecursively(collection, raw);\n }\n\n private _registerRecursively(collection: CollectionConfig, rawCollection: CollectionConfig) {\n if (this.collectionsByTableName.has(getTableName(collection))) {\n return;\n }\n\n const normalizedCollection = this.normalizeCollection(collection);\n this.collectionsByTableName.set(getTableName(normalizedCollection), normalizedCollection);\n this.rawCollectionsByTableName.set(getTableName(rawCollection), rawCollection);\n\n if (normalizedCollection.slug) {\n this.collectionsBySlug.set(normalizedCollection.slug, normalizedCollection);\n }\n if (rawCollection.slug) {\n this.rawCollectionsBySlug.set(rawCollection.slug, rawCollection);\n }\n\n // Use the normalized collection for subcollection discovery so that\n // both inline-extracted and explicit relations are considered.\n const subcollections = getSubcollections(normalizedCollection);\n\n if (subcollections && subcollections.length > 0) {\n subcollections.forEach((subCollection) => {\n if (!subCollection) return;\n // Spread to avoid mutating the original target() return value\n this._registerRecursively(this.normalizeCollection({ ...subCollection }), deepClone(subCollection));\n });\n }\n }\n\n public normalizeCollection(collection: CollectionConfig): CollectionConfig {\n // Work on a shallow copy to avoid mutating the caller's reference.\n // This is critical for idempotency (the raw input must not be changed)\n // and for preventing mutation of module-level collection singletons.\n const result = { ...collection } as CollectionConfig;\n\n // 0. Resolve and stamp `dataSource` and `engine` on the normalized copy.\n // After this block every normalized collection has both fields set,\n // so downstream code can read them directly without calling\n // `resolveDataSource()`. Only the normalized layer is affected —\n // the raw layer used by the collection editor keeps the author's\n // original fields.\n {\n const resolved = resolveDataSource(result, this.dataSources);\n if (!result.dataSource) (result as { dataSource?: string }).dataSource = resolved.key;\n if (!result.engine) (result as { engine?: string }).engine = resolved.engine;\n }\n\n // Relations are left exactly as authored.\n //\n // This used to hoist every inline relation property into\n // `collection.relations`, merge it with the declared ones, and run each\n // through `sanitizeRelation` — a pass that guessed at missing fields and\n // fell back to the raw relation when it threw. `resolveCollectionRelations`\n // now reads both sources itself and defaults deterministically, so there\n // is nothing to hoist, nothing to merge and nothing to guess.\n //\n // The hoisting also had a defect worth not reinstating: it flattened\n // relations declared inside a `map` up to the collection's top level,\n // where they became child-view tabs keyed by the inner property key.\n\n // Stamp each relation property with its resolved relation.\n const properties: Properties = this.normalizeProperties(result.properties, result);\n result.properties = properties as EngineProperties;\n\n // `childCollections` is deliberately NOT populated here.\n //\n // It used to be, from the same many-relations `getEntityChildViews`\n // reads — but stamped with the *target's* slug rather than the relation\n // key, and then cached onto the collection, so the registry's version\n // shadowed the correct one for every consumer downstream. Deriving on\n // read leaves one implementation and keeps `childCollections` meaning\n // what it documents: a custom driver's explicit override.\n return result;\n }\n\n private normalizeProperties(properties: Properties, collection: CollectionConfig): Properties {\n const newProperties: Properties = {};\n for (const key in properties) {\n newProperties[key] = this.normalizeProperty(key, properties[key], collection);\n }\n return newProperties;\n }\n\n private normalizeProperty(key: string, property: Property, collection: CollectionConfig): Property {\n const newProperty = { ...property };\n\n if (newProperty.type === \"map\" && newProperty.properties) {\n newProperty.properties = this.normalizeProperties(newProperty.properties, collection);\n } else if (newProperty.type === \"array\") {\n // Cast to get a properly typed mutable reference\n const arrayProp = newProperty as ArrayProperty;\n if (arrayProp.of) {\n if (Array.isArray(arrayProp.of)) {\n (arrayProp as { of: Property | Property[] }).of = arrayProp.of.map((p, i) => this.normalizeProperty(`${key}[${i}]`, p, collection));\n } else {\n arrayProp.of = this.normalizeProperty(`${key}.of`, arrayProp.of, collection);\n }\n } else if (arrayProp.oneOf && arrayProp.oneOf.properties) {\n arrayProp.oneOf.properties = this.normalizeProperties(arrayProp.oneOf.properties, collection);\n }\n } else if ((newProperty.type === \"string\" || newProperty.type === \"number\") && newProperty.enum) {\n const stringOrNumberProperty = newProperty as StringProperty | NumberProperty;\n if (typeof stringOrNumberProperty.enum === \"object\" && !Array.isArray(stringOrNumberProperty.enum)) {\n stringOrNumberProperty.enum = enumToObjectEntries(stringOrNumberProperty.enum)?.filter((value) => value && (value.id || value.id === 0) && value.label) ?? [];\n }\n } else if (newProperty.type === \"relation\") {\n const relationProperty = newProperty as RelationProperty;\n\n // A property either declares its link inline, or names one the\n // collection declares. Resolve the first directly; look the second\n // up by name. Either way the property carries the fully-defaulted\n // relation, so no consumer has to re-derive it.\n if (relationProperty.relation) {\n relationProperty.resolvedRelation = resolveRelation(relationProperty.relation, collection, key);\n } else {\n const declared = resolveCollectionRelations(collection)[key];\n if (declared) {\n relationProperty.resolvedRelation = declared;\n } else {\n console.warn(\n `Relation property '${key}' on '${collection.slug}' declares no \\`relation\\`, and the ` +\n \"collection has no relation of that name.\"\n );\n }\n }\n }\n\n return newProperty;\n }\n\n get(path: string): CollectionConfig | undefined {\n // First try slug lookup\n const bySlug = this.collectionsBySlug.get(path);\n if (bySlug) return bySlug;\n\n // Fallback: normalize hyphens → underscores (URLs use kebab-case, slugs use snake_case)\n if (path.includes(\"-\")) {\n const normalized = path.replace(/-/g, \"_\");\n const byNormalized = this.collectionsBySlug.get(normalized);\n if (byNormalized) return byNormalized;\n }\n\n // Fallback to table name lookup\n return this.collectionsByTableName.get(path);\n }\n\n /**\n * Gets the pristine, un-normalized collection exactly as it was provided.\n * Useful for the AST editor so it doesn't accidentally serialize injected metadata back to disk.\n */\n getRaw(path: string): CollectionConfig | undefined {\n const bySlug = this.rawCollectionsBySlug.get(path);\n if (bySlug) return bySlug;\n\n // Fallback: normalize hyphens → underscores (URLs use kebab-case, slugs use snake_case)\n if (path.includes(\"-\")) {\n const normalized = path.replace(/-/g, \"_\");\n const byNormalized = this.rawCollectionsBySlug.get(normalized);\n if (byNormalized) return byNormalized;\n }\n\n return this.rawCollectionsByTableName.get(path);\n }\n\n /**\n * Get collection by resolving multi-segment paths through relations\n * e.g., \"authors/70/posts\" resolves to the posts collection\n */\n getCollectionByPath(collectionPath: string): CollectionConfig | undefined {\n // Handle simple single collection path\n if (!collectionPath.includes(\"/\")) {\n return this.get(collectionPath);\n }\n\n // Handle multi-segment paths by resolving through relations\n const pathSegments = collectionPath.split(\"/\").filter(p => p);\n\n if (pathSegments.length < 3 || pathSegments.length % 2 === 0) {\n throw new Error(`Invalid relation path: ${collectionPath}. Expected format: collection/id/relation or collection/id/relation/id/relation`);\n }\n\n // Start with the root collection\n const rootCollectionPath = pathSegments[0];\n let currentCollection = this.get(rootCollectionPath);\n\n if (!currentCollection) {\n throw new Error(`Root collection not found: ${rootCollectionPath}`);\n }\n\n // Navigate through the path using relations\n for (let i = 2; i < pathSegments.length; i += 2) {\n const relationKey = pathSegments[i];\n\n // Get relations for current collection\n if (!getDataSourceCapabilities(currentCollection.engine).supportsRelations) {\n throw new Error(`Relation path navigation requires a collection that supports relations, but '${currentCollection.slug}' uses engine '${currentCollection.engine}'`);\n }\n const resolvedRelations = resolveCollectionRelations(currentCollection);\n const relation = findRelation(resolvedRelations, relationKey);\n\n if (!relation) {\n throw new Error(`Relation '${relationKey}' not found in collection '${currentCollection.slug}'`);\n }\n\n // Move to the target collection.\n //\n // By the relation's own target, never by a slug lookup on its\n // *name*: `this.get(relation.relationName)` searches the global slug\n // map, so a relation named `people` that targets `notes` resolved to\n // an unrelated root collection called `people` — and a nested write\n // then ran that collection's callbacks against its properties.\n // The registered instance is preferred, matched by table, to pick up\n // whatever normalization and injection it received.\n const target = relation.target();\n currentCollection = this.collectionsByTableName.get(getTableName(target))\n ?? this.normalizeCollection(target);\n\n // If there are more segments, continue navigation\n if (i + 1 < pathSegments.length) {\n // Skip entity ID segment\n }\n }\n\n return currentCollection;\n }\n\n getCollections(): CollectionConfig[] {\n if (!this.cachedCollectionsList) {\n this.cachedCollectionsList = Array.from(this.collectionsByTableName.values());\n }\n return this.cachedCollectionsList;\n }\n\n getRawCollections(): CollectionConfig[] {\n if (!this.cachedRawCollectionsList) {\n this.cachedRawCollectionsList = Array.from(this.rawCollectionsByTableName.values());\n }\n return this.cachedRawCollectionsList;\n }\n\n /**\n * Resolves a multi-segment path like \"products/123/locales\" and returns\n * information about the collections and entity IDs along the path\n */\n resolvePathToCollections(path: string): {\n collections: CollectionConfig[],\n entityIds: (string | number)[],\n finalCollection: CollectionConfig\n } {\n const pathSegments = path.split(\"/\").filter(p => p);\n\n if (pathSegments.length === 0) {\n throw new Error(`Invalid path: ${path}`);\n }\n\n if (pathSegments.length % 2 !== 1) {\n throw new Error(`Invalid collection path: ${path}. It must have an odd number of segments.`);\n }\n\n const collections: CollectionConfig[] = [];\n const entityIds: (string | number)[] = [];\n\n // Start with the first collection\n let currentCollection = this.get(pathSegments[0]);\n\n if (!currentCollection) {\n throw new Error(`Unknown collection path or slug: ${pathSegments[0]}`);\n }\n\n collections.push(currentCollection);\n\n // Process the rest of the path in pairs (entityId, subcollectionSlug)\n for (let i = 1; i < pathSegments.length; i += 2) {\n const entityId = pathSegments[i];\n entityIds.push(entityId);\n\n if (i + 1 < pathSegments.length) {\n const subcollectionSlug = pathSegments[i + 1];\n const subcollections: CollectionConfig[] | undefined = getSubcollections(currentCollection);\n if (!subcollections || subcollections.length === 0) {\n throw new Error(`No subcollections found for ${currentCollection.slug} in path: ${path}`);\n }\n\n const subcollection: CollectionConfig | undefined = subcollections.find(c => c.slug === subcollectionSlug);\n if (!subcollection) {\n throw new Error(`Subcollection '${subcollectionSlug}' not found in ${currentCollection.slug}`);\n }\n // The child as resolved, not whatever root collection happens to\n // share its slug. Re-looking it up globally both risked the wrong\n // collection and discarded the relation's `overrides`, which are\n // applied when the child view is built.\n currentCollection = this.normalizeCollection(subcollection);\n collections.push(currentCollection);\n }\n }\n\n return {\n collections,\n entityIds,\n finalCollection: currentCollection\n };\n }\n\n}\n\n","import { defineCollection } from \"../util/builders\";\n\n/**\n * Default users collection.\n *\n * Prepended to the developer's collections array by the admin and server.\n * Slug-based dedup (Map keyed by slug, last-write-wins) lets developers\n * override by defining their own collection with `slug: \"users\"`.\n *\n * Schema only — no `admin` block. This package is on the backend's dependency path,\n * where that field does not exist: `@rebasepro/admin-types` adds it by declaration\n * merging, and a BaaS install never installs that. The scaffolded\n * `config/collections/users.ts` carries the presentation for projects that want this\n * collection in their panel, which is also where it is editable.\n */\nexport const defaultUsersCollection = defineCollection({\n name: \"Users\",\n singularName: \"User\",\n slug: \"users\",\n auth: true,\n table: \"users\",\n schema: \"rebase\",\n securityRules: [\n { operation: \"select\",\nroles: [\"admin\"] },\n { operations: [\"insert\", \"update\", \"delete\"],\nroles: [\"admin\"] }\n ],\n properties: {\n id: {\n name: \"ID\",\n type: \"string\",\n isId: \"uuid\"\n },\n email: {\n name: \"Email\",\n type: \"string\",\n validation: { required: true,\nunique: true }\n },\n displayName: {\n name: \"Name\",\n type: \"string\",\n columnName: \"display_name\",\n validation: { required: true }\n },\n photoURL: {\n name: \"Photo URL\",\n type: \"string\",\n columnName: \"photo_url\"\n },\n roles: {\n name: \"Roles\",\n type: \"array\",\n columnType: \"text[]\",\n of: {\n name: \"Role\",\n type: \"string\",\n enum: {\n admin: \"Admin\",\n editor: \"Editor\",\n viewer: \"Viewer\"\n }\n }\n },\n passwordHash: {\n name: \"Password Hash\",\n type: \"string\",\n columnName: \"password_hash\",\n excludeFromApi: true\n },\n emailVerified: {\n name: \"Email Verified\",\n type: \"boolean\",\n columnName: \"email_verified\",\n defaultValue: false\n },\n emailVerificationToken: {\n name: \"Email Verification Token\",\n type: \"string\",\n columnName: \"email_verification_token\",\n excludeFromApi: true\n },\n emailVerificationSentAt: {\n name: \"Email Verification Sent At\",\n type: \"date\",\n columnName: \"email_verification_sent_at\"\n },\n metadata: {\n name: \"Metadata\",\n type: \"map\",\n keyValue: true,\n properties: {},\n defaultValue: {}\n },\n createdAt: {\n name: \"Created At\",\n type: \"date\",\n columnName: \"created_at\",\n autoValue: \"on_create\"\n },\n updatedAt: {\n name: \"Updated At\",\n type: \"date\",\n columnName: \"updated_at\",\n autoValue: \"on_update\"\n }\n }\n});\n","import type { OrderBySortTuple, OrderBySpec, OrderByTuple } from \"@rebasepro/types\";\nimport { isRelationAggregateSort, sortKeyToString } from \"@rebasepro/types\";\n\n/**\n * Sort-order wire codec.\n *\n * This is the ONLY module that knows about the colon-delimited wire format\n * (`\"field:direction\"`) used in HTTP query parameters, and about the JSON-array\n * form that carries a multi-column sort over the same parameter.\n * Everything else speaks {@link OrderByTuple} exclusively.\n *\n * Mirrors the filter architecture in `filter-dialect.ts`.\n *\n * @module\n */\n\n/**\n * Collapse the one-key and many-key spellings of a sort into the list form.\n *\n * `[\"a\", \"desc\"]` and `[[\"a\", \"desc\"]]` mean the same thing and normalize to\n * the same value; the two are told apart by whether the first element is\n * itself an array, which no field name ever is.\n *\n * This is also where a {@link RelationAggregateSort} object stops being an\n * object. Above this function a sort key may be either spelling; below it,\n * every key is a string — which is what `OrderByTuple`, the REST parameter, the\n * driver contract and the cursor all already were. Doing it here means the one\n * place that already collapses the two *shapes* of a sort also collapses the\n * two *spellings* of a key, rather than every consumer learning about both.\n *\n * @returns The keys in order of significance, or `undefined` for no sort. An\n * empty list also returns `undefined` — \"sort by nothing\" is no sort, and\n * letting `[]` through would have every layer below re-deciding what it meant.\n */\nexport function normalizeOrderBy(orderBy?: OrderBySpec): OrderByTuple[] | undefined {\n if (!orderBy || orderBy.length === 0) return undefined;\n // An aggregate key is an object, so the first element being an array still\n // tells the list form from the single-tuple one — no field name is an\n // array, and neither is an aggregate key.\n const list = Array.isArray(orderBy[0])\n ? orderBy as OrderBySortTuple[]\n : [orderBy as OrderBySortTuple];\n if (list.length === 0) return undefined;\n return list.map(([key, direction]) => [sortKeyToString(key), direction] as OrderByTuple);\n}\n\n/**\n * The most significant sort key, for a caller that can only express one —\n * a column header's arrow, a URL parameter, a driver that has not been taught\n * the list form.\n */\nexport function primaryOrderBy(orderBy?: OrderBySpec): OrderByTuple | undefined {\n return normalizeOrderBy(orderBy)?.[0];\n}\n\n/**\n * Collapse the driver-level `{orderBy, order}` pair into the list form.\n *\n * The driver contract spells a single-column sort as a field name plus a\n * separate direction, and a multi-column one as a list of tuples that leaves\n * `order` meaningless. Every driver reads both through here so neither\n * spelling has to be handled twice.\n *\n * An absent direction means ascending — the same thing a bare `?orderBy=name`\n * has always meant over HTTP. The Postgres driver used to read the same pair as\n * *descending* while Mongo read it as ascending, so one field name and no\n * direction described two different queries depending on which database was\n * underneath. Neither had a caller: every path in the workspace passes a\n * direction, which is why the disagreement went unnoticed rather than being\n * load-bearing.\n */\nexport function normalizeDriverOrderBy(\n orderBy?: string | OrderByTuple[],\n order?: \"asc\" | \"desc\"\n): OrderByTuple[] | undefined {\n if (!orderBy) return undefined;\n if (typeof orderBy === \"string\") return [[orderBy, order === \"desc\" ? \"desc\" : \"asc\"]];\n return orderBy.length > 0 ? orderBy : undefined;\n}\n\n/** A sort whose *shape* is unusable, as opposed to one naming a field that does not exist. */\nexport class OrderBySpecError extends Error {\n readonly code = \"INVALID_ORDER_BY\";\n constructor(detail: string) {\n super(\n `Invalid \\`orderBy\\`: ${detail}. Expected a field name, or a list of ` +\n \"[field, direction] pairs like [[\\\"roles\\\",\\\"asc\\\"],[\\\"created_at\\\",\\\"desc\\\"]]\"\n );\n this.name = \"OrderBySpecError\";\n }\n}\n\n/**\n * Validate an `orderBy` that arrived from outside this process — a WebSocket\n * subscribe frame, a driver call from untyped JavaScript — and return it in the\n * list form.\n *\n * Strict on purpose, in the same way the REST `parseOrderByParam` is: the\n * failure mode for a shape nobody checks is not a crash but a *silently\n * different query*. A malformed entry read as a field name resolves to no\n * column, and under the lenient unknown-field mode the sort is then dropped and\n * the rows come back in whatever order the database pleased — sorted, as far as\n * the subscriber can tell, by whatever they asked for.\n */\nexport function parseOrderBySpecStrict(raw: unknown, order?: \"asc\" | \"desc\"): OrderByTuple[] | undefined {\n if (raw === undefined || raw === null || raw === \"\") return undefined;\n // The string spelling is the driver contract's, so it takes its direction\n // from the same companion `order` — and defaults the same way it does.\n if (typeof raw === \"string\") return normalizeDriverOrderBy(raw, order);\n if (!Array.isArray(raw) || raw.length === 0) {\n throw new OrderBySpecError(`${typeof raw} is not a field name or a list of sort keys`);\n }\n\n // The single-tuple spelling, `[\"created_at\", \"desc\"]` — or the same shape\n // with an aggregate key in place of the field name.\n if (typeof raw[0] === \"string\" || isRelationAggregateSort(raw[0])) return [toStrictTuple(raw, 0)];\n\n return raw.map(toStrictTuple);\n}\n\nfunction toStrictTuple(raw: unknown, index: number): OrderByTuple {\n if (!Array.isArray(raw)) {\n throw new OrderBySpecError(`entry ${index} has no field name`);\n }\n // The object spelling of an aggregate key, from an untyped caller that did\n // not go through `normalizeOrderBy`. Encoded rather than refused: it is a\n // sort this understands, and rejecting the shape a typed caller writes\n // would be a distinction between the two spellings that nothing else makes.\n const key = isRelationAggregateSort(raw[0]) ? sortKeyToString(raw[0]) : raw[0];\n if (typeof key !== \"string\" || key.trim() === \"\") {\n throw new OrderBySpecError(`entry ${index} has no field name`);\n }\n const direction = raw[1];\n if (direction !== undefined && direction !== \"asc\" && direction !== \"desc\") {\n throw new OrderBySpecError(`entry ${index} has direction '${String(direction)}'`);\n }\n return [key, direction ?? \"asc\"];\n}\n\n/**\n * Serialize a sort to the wire.\n *\n * A single key keeps the `\"field:direction\"` shorthand it has always used —\n * short, readable in a URL, and what every existing client and test expects.\n * Several keys are emitted as the canonical JSON array the server already\n * accepts, because the shorthand has no separator to spare: a comma-joined\n * `\"a:asc,b:desc\"` parses as one field named `a` with the direction\n * `\"asc,b:desc\"`, which the server refuses.\n *\n * **Runtime tolerance:** if the input is already a well-formed wire string\n * (from an untyped JS caller), it is returned unchanged.\n * This is undocumented tolerance, not public API — don't rely on it.\n *\n * @param orderBy - A canonical tuple or list of tuples, or at runtime\n * possibly a pre-serialized string (undocumented tolerance).\n * @returns The wire-format string, or `undefined` if the input is falsy.\n *\n * @remarks\n * Field names containing `:` are representable in the tuple form but\n * **not** in the single-key wire encoding — this is an inherent limitation of\n * the colon-delimited shorthand and is not resolved here.\n */\nexport function serializeOrderBy(orderBy?: OrderBySpec | string): string | undefined {\n if (!orderBy) return undefined;\n // Runtime tolerance: pass through a pre-serialized wire string unchanged.\n if (typeof orderBy === \"string\") return orderBy;\n // `normalizeOrderBy` has already encoded any aggregate key to its string\n // spelling, which is why the shorthand below can assume a string: neither\n // `min(applications.created_at)` nor `count(applications)` contains a `:`.\n const list = normalizeOrderBy(orderBy);\n if (!list) return undefined;\n if (list.length === 1) return `${list[0][0]}:${list[0][1]}`;\n return JSON.stringify(list.map(([field, direction]) => ({ field,\ndirection })));\n}\n\n/**\n * Deserialize a wire-format `\"field:direction\"` string into an {@link OrderByTuple}.\n *\n * Lenient parsing (matches existing server behaviour):\n * - Bare field name (no colon): `\"name\"` → `[\"name\", \"asc\"]`\n * - Unknown direction: `\"name:foo\"` → `[\"name\", \"asc\"]`\n * - Empty / falsy input: → `undefined`\n *\n * Reads the single-key shorthand only. For a value that may carry several keys,\n * use {@link deserializeOrderByList} — handed a JSON array this returns the\n * whole array as one nonsensical field name.\n *\n * @param raw - The wire-format string from an HTTP query parameter.\n * @returns The canonical tuple, or `undefined` if the input is empty/falsy.\n */\nexport function deserializeOrderBy(raw?: string): OrderByTuple | undefined {\n if (!raw) return undefined;\n const idx = raw.indexOf(\":\");\n if (idx === -1) return [raw, \"asc\"];\n const field = raw.slice(0, idx);\n const dir = raw.slice(idx + 1);\n return [field, dir === \"desc\" ? \"desc\" : \"asc\"];\n}\n\n/**\n * Deserialize either wire spelling — the single-key shorthand or the JSON\n * array — into the list form.\n *\n * Lenient in the same way {@link deserializeOrderBy} is: this is the client end\n * of the codec, where the value was produced by {@link serializeOrderBy} a\n * moment earlier. The *server* end parses the same shapes strictly, in\n * `parseOrderByParam`, because there the value came from a stranger and a\n * direction it cannot read has to be refused rather than quietly turned into\n * `\"asc\"`.\n */\nexport function deserializeOrderByList(raw?: string): OrderByTuple[] | undefined {\n if (!raw) return undefined;\n const trimmed = raw.trim();\n if (trimmed.startsWith(\"[\")) {\n try {\n const parsed = JSON.parse(trimmed);\n if (Array.isArray(parsed)) {\n const list = parsed\n .map((entry): OrderByTuple | undefined => {\n if (typeof entry === \"string\") return deserializeOrderBy(entry);\n if (entry && typeof entry === \"object\" && typeof entry.field === \"string\") {\n return [entry.field, entry.direction === \"desc\" ? \"desc\" : \"asc\"];\n }\n return undefined;\n })\n .filter((entry): entry is OrderByTuple => entry !== undefined);\n return list.length > 0 ? list : undefined;\n }\n } catch {\n // Not JSON after all — fall through to the shorthand, which is what\n // a field name that merely begins with \"[\" would be.\n }\n }\n const single = deserializeOrderBy(trimmed);\n return single ? [single] : undefined;\n}\n","import {\n CollectionAccessor,\n FilterCondition,\n FindParams,\n FindResponse,\n LogicalCondition,\n OrderByTuple,\n QueryBuilderInterface,\n WhereFilterOp,\n WhereValueFor,\n type ComputedSortField\n} from \"@rebasepro/types\";\nimport { normalizeOrderBy } from \"./sort-dialect\";\n\nexport function or(...conditions: (FilterCondition | LogicalCondition)[]): LogicalCondition {\n return { type: \"or\",\nconditions };\n}\n\nexport function and(...conditions: (FilterCondition | LogicalCondition)[]): LogicalCondition {\n return { type: \"and\",\nconditions };\n}\n\nexport function cond(column: string, operator: WhereFilterOp, value: unknown): FilterCondition {\n return { column,\noperator,\nvalue };\n}\n\nexport class QueryBuilder<M extends Record<string, unknown> = Record<string, unknown>> implements QueryBuilderInterface<M> {\n // Keyed by plain `string` on purpose: it is written in place by the\n // methods below, whose own parameters are typed against `M`, and a\n // `Partial<Record<FieldPath<M>, …>>` is read-only under a generic `M`\n // (TS2862). The typing users see is on the methods; this is the buffer\n // behind them, cast once at each handoff.\n private params: FindParams = { where: {} };\n\n constructor(private collection: CollectionAccessor<M>) {}\n\n /**\n * Add a filter condition to your query.\n * @example\n * client.collection('users').where('age', '>=', 18).find()\n */\n where<K extends keyof M & string, Op extends WhereFilterOp>(column: K, operator: Op, value: WhereValueFor<Op, M[K]>): this;\n where(logicalCondition: LogicalCondition): this;\n where(columnOrCondition: string | LogicalCondition, operator?: WhereFilterOp, value?: unknown): this {\n // Handle LogicalCondition signature\n if (typeof columnOrCondition === \"object\" && columnOrCondition !== null && \"type\" in columnOrCondition) {\n this.params.logical = columnOrCondition as LogicalCondition;\n return this;\n }\n\n if (!this.params.where) {\n this.params.where = {};\n }\n\n const column = columnOrCondition as string;\n const condition: [WhereFilterOp, unknown] = [operator!, value];\n const existing = this.params.where[column];\n\n if (existing === undefined) {\n this.params.where[column] = condition;\n } else if (Array.isArray(existing) && existing.length > 0 && Array.isArray(existing[0])) {\n (this.params.where[column] as [WhereFilterOp, unknown][]).push(condition);\n } else {\n // Convert existing single tuple/value into array of tuples\n let firstCondition: [WhereFilterOp, unknown];\n if (Array.isArray(existing) && existing.length === 2 && typeof existing[0] === \"string\") {\n firstCondition = existing as [WhereFilterOp, unknown];\n } else {\n firstCondition = [\"==\", existing];\n }\n this.params.where[column] = [firstCondition, condition];\n }\n\n return this;\n }\n\n /**\n * Order the results by a specific column.\n *\n * Called again, this adds a tie-breaker rather than replacing the sort:\n * keys apply in the order they were added.\n *\n * @example\n * client.collection('users').orderBy('createdAt', 'desc').find()\n * @example\n * client.collection('users').orderBy('roles').orderBy('createdAt', 'desc').find()\n */\n orderBy(column: (keyof M & string) | ComputedSortField, direction: \"asc\" | \"desc\" = \"asc\"): this {\n const existing = normalizeOrderBy(this.params.orderBy) ?? [];\n this.params.orderBy = [...existing, [column, direction] as OrderByTuple];\n return this;\n }\n\n /**\n * Limit the number of results returned.\n */\n limit(count: number): this {\n this.params.limit = count;\n return this;\n }\n\n /**\n * Skip the first N results.\n */\n offset(count: number): this {\n this.params.offset = count;\n return this;\n }\n\n /**\n * Set a free-text search string if supported by the backend.\n */\n search(searchString: string, options?: { explain?: boolean }): this {\n this.params.searchString = searchString;\n if (options?.explain !== undefined) this.params.searchExplain = options.explain;\n return this;\n }\n\n /**\n * Order rows by nearest-neighbour distance to `vector`, closest first.\n *\n * Postgres only, over a property declared as `type: \"vector\"`. Rows come\n * back with a `_distance`; `where` filters before the ordering.\n */\n vectorSearch(\n property: string,\n vector: number[],\n options?: { distance?: \"cosine\" | \"l2\" | \"inner_product\"; threshold?: number }\n ): this {\n this.params.vectorSearch = {\n property,\n vector,\n ...(options?.distance !== undefined && { distance: options.distance }),\n ...(options?.threshold !== undefined && { threshold: options.threshold })\n };\n return this;\n }\n\n /**\n * Include related entities in the response.\n * Relations will be populated with full entity data instead of just IDs.\n *\n * @param relations - Relation names to include, or \"*\" for all.\n * @example\n * // Include specific relations\n * client.data.posts.include(\"tags\", \"author\").find()\n *\n * // Include all relations\n * client.data.posts.include(\"*\").find()\n */\n include(...relations: string[]): this {\n this.params.include = relations;\n return this;\n }\n\n /**\n * Execute the find query and return the results.\n */\n async find(): Promise<FindResponse<M>> {\n return this.collection.find(this.params as FindParams<M>) as Promise<FindResponse<M>>;\n }\n\n /**\n * Listen to realtime updates matching this query.\n */\n listen(onUpdate: (data: FindResponse<M>) => void, onError?: (error: Error) => void): () => void {\n if (!this.collection.listen) {\n throw new Error(\"Listen is only available when RebaseClient is configured with a websocketUrl.\");\n }\n return this.collection.listen(this.params as FindParams<M>, onUpdate, onError);\n }\n}\n","import {\n DEFAULT_LIST_LIMIT,\n FilterValues,\n FieldPath,\n FindAllParams,\n FindParams,\n FindResult,\n IterateParams,\n WhereFilterOp\n} from \"@rebasepro/types\";\nimport { normalizeOrderBy } from \"./sort-dialect\";\n\n/**\n * The pagination engine behind `iterate()` / `findAll()`.\n *\n * It lives here, above both transports, on purpose: the HTTP client and the\n * in-process accessor implement the same `SDKCollectionClient` contract, and a\n * helper written twice is a helper that drifts. Both call into this file, so\n * \"the SDK paginates like *this*\" has exactly one definition.\n *\n * Everything below is expressed in terms of a single `find(params)` function,\n * which is all either transport has to supply.\n */\n\n/** Rows requested per page when the caller does not say. */\nexport const DEFAULT_PAGE_SIZE = 200;\n\n/** Rows `findAll()` will materialise before it refuses to continue. */\nexport const DEFAULT_FIND_ALL_MAX_ROWS = 10_000;\n\n/**\n * Requests one walk may make before it gives up on the server ever saying\n * `hasMore: false`. At the default page size that is two million rows — far\n * past any legitimate walk, and short of running forever.\n */\nexport const DEFAULT_MAX_PAGES = 10_000;\n\n/** Why a pagination walk refused to continue. */\nexport type PaginationErrorCode =\n /** `findAll()` matched more rows than its ceiling allows. */\n | \"max-rows\"\n /** The walk made its maximum number of requests without the server finishing. */\n | \"max-pages\"\n /** A cursor row carried no value for the cursor column. */\n | \"cursor-missing\"\n /** Two consecutive pages ended on the same cursor value, so the walk cannot advance. */\n | \"cursor-stalled\"\n /** A `cursor` was asked for on one column while `orderBy` sorted by another. */\n | \"cursor-order-mismatch\";\n\n/**\n * Thrown when a walk stops for a reason the caller needs to know about.\n *\n * Every one of these is a case where the alternative would be silent: a\n * truncated array that looks complete, or a loop that never returns. Check\n * {@link code} to tell them apart.\n */\nexport class RebasePaginationError extends Error {\n readonly code: PaginationErrorCode;\n\n constructor(code: PaginationErrorCode, message: string) {\n super(message);\n this.name = \"RebasePaginationError\";\n this.code = code;\n // Keeps `instanceof` working when this is compiled down for an older\n // target, where extending a builtin otherwise loses the prototype.\n Object.setPrototypeOf(this, RebasePaginationError.prototype);\n }\n}\n\n/** The one thing a transport has to provide to be paginated. */\nexport type PageFinder<M extends Record<string, unknown> = Record<string, unknown>> =\n (params: FindParams<M>) => Promise<FindResult<M>>;\n\n/**\n * Resolve `limit`/`offset`/`page` into the window a read will actually use.\n *\n * Lives here, next to the walk, for the reason at the top of this file: every\n * transport has to mean the same thing by \"page two\". Four of them did not —\n * the REST layer strode by {@link DEFAULT_LIST_LIMIT}, the local-first\n * evaluator by {@link DEFAULT_PAGE_SIZE}, the in-process accessor by 20, and\n * the published type documented a fourth number. Pages that overlap or skip\n * rows are the mildest of those outcomes.\n *\n * `page` wins over `offset`, as {@link FindParams} documents. `driverOffset`\n * is the value to hand a driver: it stays `undefined` when the caller named no\n * offset, because keyset pagination seeks with a `where` clause and must not\n * look like it is paging by offset.\n */\nexport function resolveFindWindow(\n params?: Pick<FindParams, \"limit\" | \"offset\" | \"page\">\n): { limit: number; offset: number; driverOffset: number | undefined } {\n const limit = params?.limit ?? DEFAULT_LIST_LIMIT;\n const offset = params?.page != null\n ? Math.max(0, (params.page - 1) * limit)\n : (params?.offset ?? 0);\n return {\n limit,\n offset,\n driverOffset: params?.page != null ? offset : params?.offset\n };\n}\n\nfunction normalizePageSize(raw: number | undefined): number {\n if (raw === undefined || !Number.isFinite(raw)) return DEFAULT_PAGE_SIZE;\n return Math.max(1, Math.floor(raw));\n}\n\nfunction normalizeMaxPages(raw: number | undefined): number {\n if (raw === undefined) return DEFAULT_MAX_PAGES;\n if (raw === Number.POSITIVE_INFINITY) return raw;\n if (!Number.isFinite(raw)) return DEFAULT_MAX_PAGES;\n return Math.max(1, Math.floor(raw));\n}\n\nfunction normalizeMaxRows(raw: number | undefined): number {\n if (raw === undefined) return DEFAULT_FIND_ALL_MAX_ROWS;\n if (raw === Number.POSITIVE_INFINITY) return raw;\n if (!Number.isFinite(raw)) return DEFAULT_FIND_ALL_MAX_ROWS;\n return Math.max(0, Math.floor(raw));\n}\n\n/**\n * Add one condition to a `where` map without disturbing what is already there.\n *\n * The caller's own filter on the cursor column has to survive — dropping it\n * would widen the query, which is the silent-filter-loss failure mode — so a\n * second condition on the same column becomes the array-of-tuples form that\n * `FindParams.where` already accepts, and both are AND-ed.\n */\nfunction appendCondition<M extends Record<string, unknown>>(\n where: FilterValues<FieldPath<M>> | undefined,\n column: string,\n condition: [WhereFilterOp, unknown]\n): FilterValues<FieldPath<M>> {\n const next = { ...(where ?? {}) } as Record<string, unknown>;\n const existing = next[column];\n if (existing === undefined) {\n next[column] = condition;\n } else if (Array.isArray(existing) && existing.length > 0 && Array.isArray(existing[0])) {\n next[column] = [...(existing as [WhereFilterOp, unknown][]), condition];\n } else {\n next[column] = [existing, condition];\n }\n return next as FilterValues<FieldPath<M>>;\n}\n\nfunction cursorEquals(a: unknown, b: unknown): boolean {\n if (a instanceof Date && b instanceof Date) return a.getTime() === b.getTime();\n return Object.is(a, b);\n}\n\n/**\n * Walk every row a query matches, yielding one row at a time and fetching the\n * next page only when the consumer asks for it.\n *\n * See {@link SDKCollectionClient.iterate} for the caller-facing contract,\n * including the offset-drift caveat and the `cursor` alternative.\n *\n * @param find the transport's single-page read\n * @param params `find()` parameters minus the window, plus the walk options\n * @param label the collection name, so an error says which walk failed\n */\nexport async function* paginateFind<M extends Record<string, unknown> = Record<string, unknown>>(\n find: PageFinder<M>,\n params?: IterateParams<M>,\n label = \"collection\"\n): AsyncGenerator<M, void, undefined> {\n const {\n pageSize,\n cursor,\n maxPages,\n ...rest\n } = (params ?? {}) as IterateParams<M> & Record<string, unknown>;\n\n const findParams = { ...rest } as FindParams<M>;\n const size = normalizePageSize(pageSize as number | undefined);\n const pageCap = normalizeMaxPages(maxPages as number | undefined);\n\n // ── Cursor (keyset) setup ────────────────────────────────────────────────\n const cursorField = typeof cursor === \"string\" ? cursor : cursor?.field;\n const requestedDirection = (typeof cursor === \"object\" && cursor !== null)\n ? cursor.direction\n : undefined;\n\n let direction: \"asc\" | \"desc\" = \"asc\";\n if (cursorField) {\n const orderBy = normalizeOrderBy(findParams.orderBy);\n // A seek is one `>`/`<` on one column, so it can only follow a sort of\n // one column. Over a multi-key sort the same comparison both repeats\n // rows (every later key's ties) and skips them, which is the failure\n // this error exists to prevent — name it rather than seek anyway.\n if (orderBy && orderBy.length > 1) {\n throw new RebasePaginationError(\n \"cursor-order-mismatch\",\n `Cannot seek on \"${cursorField}\" while ordering \"${label}\" by ` +\n `${orderBy.map(([field]) => `\"${field}\"`).join(\", \")}: ` +\n `keyset pagination advances along a single column. ` +\n `Order by \"${cursorField}\" alone, or drop the cursor and page by offset.`\n );\n }\n if (orderBy && orderBy[0][0] !== cursorField) {\n throw new RebasePaginationError(\n \"cursor-order-mismatch\",\n `Cannot seek on \"${cursorField}\" while ordering \"${label}\" by \"${orderBy[0][0]}\": ` +\n `keyset pagination only advances along the column the query is sorted by. ` +\n `Order by \"${cursorField}\", or drop the cursor and page by offset.`\n );\n }\n direction = requestedDirection ?? orderBy?.[0][1] ?? \"asc\";\n findParams.orderBy = [cursorField, direction] as FindParams<M>[\"orderBy\"];\n }\n const seekOp: WhereFilterOp = direction === \"desc\" ? \"<\" : \">\";\n const baseWhere = findParams.where;\n\n let offset = 0;\n let pages = 0;\n let cursorValue: unknown;\n let seeking = false;\n\n for (;;) {\n if (pages >= pageCap) {\n throw new RebasePaginationError(\n \"max-pages\",\n `Iterating \"${label}\" made ${pages} requests without the server reporting the end of ` +\n `the collection. Stopping rather than looping forever — raise \\`maxPages\\` if the walk ` +\n `is genuinely this long, or check that the backend sets \\`meta.hasMore\\`.`\n );\n }\n\n const pageParams: FindParams<M> = { ...findParams, limit: size };\n if (cursorField) {\n if (seeking) {\n pageParams.where = appendCondition<M>(baseWhere, cursorField, [seekOp, cursorValue]);\n }\n } else {\n pageParams.offset = offset;\n }\n\n const page = await find(pageParams);\n pages += 1;\n\n const rows = page?.data ?? [];\n // A page with nothing on it always ends the walk, whatever the server\n // claims about `hasMore` — there is no cursor to advance and no offset\n // that would ever move past it.\n if (rows.length === 0) return;\n\n for (const row of rows) {\n yield row;\n }\n\n // The server is the only authority on whether more rows exist. Never\n // infer it from `rows.length >= size`: a last page that happens to be\n // exactly full is indistinguishable from a middle one, and guessing\n // there drops every row after it.\n if (page?.meta?.hasMore !== true) return;\n\n if (cursorField) {\n const last = rows[rows.length - 1] as Record<string, unknown>;\n const nextValue = last?.[cursorField];\n if (nextValue === undefined || nextValue === null) {\n throw new RebasePaginationError(\n \"cursor-missing\",\n `Cannot seek past the last row of \"${label}\": it has no value for the cursor ` +\n `column \"${cursorField}\". Pick a column that is present and non-null on every row.`\n );\n }\n if (seeking && cursorEquals(nextValue, cursorValue)) {\n throw new RebasePaginationError(\n \"cursor-stalled\",\n `Iterating \"${label}\" is stuck: two pages in a row ended at ` +\n `${cursorField}=${String(nextValue)}. The cursor column has to be unique — a ` +\n `repeated value cannot be seeked past, and continuing would either loop forever ` +\n `or skip the duplicates. Use the primary key, or page by offset.`\n );\n }\n cursorValue = nextValue;\n seeking = true;\n } else {\n // Advance by what actually arrived, not by the page size: a server\n // free to return fewer rows than asked for would otherwise leave a\n // hole in the walk.\n offset += rows.length;\n }\n }\n}\n\n/**\n * {@link paginateFind}, collected into an array under a ceiling.\n *\n * See {@link SDKCollectionClient.findAll}.\n */\nexport async function collectAllPages<M extends Record<string, unknown> = Record<string, unknown>>(\n find: PageFinder<M>,\n params?: FindAllParams<M>,\n label = \"collection\"\n): Promise<M[]> {\n const { maxRows, ...rest } = (params ?? {}) as FindAllParams<M> & Record<string, unknown>;\n const cap = normalizeMaxRows(maxRows as number | undefined);\n\n const out: M[] = [];\n for await (const row of paginateFind<M>(find, rest as IterateParams<M>, label)) {\n out.push(row);\n if (out.length > cap) {\n throw new RebasePaginationError(\n \"max-rows\",\n `findAll(\"${label}\") matched more than ${cap} rows. Returning the first ${cap} would ` +\n `look like the whole answer and quietly not be one, so this throws instead. Raise ` +\n `\\`maxRows\\` if you meant to load them all, or stream with \\`iterate()\\`.`\n );\n }\n }\n return out;\n}\n\n/**\n * Build the `iterate` / `findAll` pair for one collection from its `find`.\n *\n * Both transports call this, which is what keeps the two implementations from\n * being two implementations.\n */\nexport function createPaginationHelpers<M extends Record<string, unknown> = Record<string, unknown>>(\n find: PageFinder<M>,\n label: string\n): {\n iterate: (params?: IterateParams<M>) => AsyncIterableIterator<M>;\n findAll: (params?: FindAllParams<M>) => Promise<M[]>;\n} {\n return {\n iterate: (params?: IterateParams<M>) => paginateFind<M>(find, params, label),\n findAll: (params?: FindAllParams<M>) => collectAllPages<M>(find, params, label)\n };\n}\n","/**\n * REST wire-format adapter for the unified filter system.\n *\n * This module is the ONLY code in the entire codebase that knows about\n * PostgREST-style dot-syntax strings (`eq.active`, `gt.18`, `in.(a,b)`).\n * Everything else speaks `FilterValues` exclusively.\n *\n * Wire-format values are always strings — the wire format carries no type\n * metadata, so type coercion is the responsibility of the server-side data\n * driver which has access to the collection schema.\n *\n * Structural characters inside a value are backslash-escaped: `,` → `\\,`,\n * `(` → `\\(`, `)` → `\\)`, and a literal backslash as `\\\\`. Decoding is\n * deliberately conservative — only those four sequences are decoded, so a\n * backslash that arrives unescaped from an older client survives intact.\n *\n * @module\n */\n\nimport {\n WhereFilterOp,\n FilterValues,\n ALL_WHERE_FILTER_OPS,\n CANONICAL_TO_REST,\n REST_TO_CANONICAL,\n RestFilterOp,\n toCanonicalOp,\n LogicalCondition,\n FilterCondition,\n NULL_OPS\n} from \"@rebasepro/types\";\nimport { normalizeToEntityRelation } from \"../util/entities\";\n\n// ---------------------------------------------------------------------------\n// Value stringification\n// ---------------------------------------------------------------------------\n\n/**\n * Serialize a JS value to its querystring representation.\n * `null` is serialized as the literal string `\"null\"`.\n * Relation values (`EntityRelation` instances or `{ __type: \"relation\", id, path }`\n * objects) are serialized as their raw id — the wire format only carries the\n * value to compare against the FK column.\n */\nfunction stringifyValue(value: unknown): string {\n if (value === null) return \"null\";\n const relation = normalizeToEntityRelation(value);\n if (relation) return String(relation.id);\n return String(value);\n}\n\n// ---------------------------------------------------------------------------\n// Comma escaping for list values\n// ---------------------------------------------------------------------------\n\n/**\n * Characters that carry structure in the wire format and must therefore be\n * escaped inside a value: the separator, the group delimiters, and the escape\n * character itself.\n *\n * Parentheses are here because `and(...)`/`or(...)` groups are parsed by\n * tracking paren depth. A value containing one is not merely ambiguous, it\n * moves where the parser thinks the group ends.\n */\nconst WIRE_SPECIALS = /[\\\\,()]/g;\n\n/**\n * Escape a value for the wire format: `\\` → `\\\\`, `,` → `\\,`, `(` → `\\(`,\n * `)` → `\\)`.\n */\n/**\n * The wire spelling of an empty list.\n *\n * A lone backslash: unproducible by {@link escapeWireValue}, which doubles\n * every backslash it emits, so it cannot collide with any real item.\n */\nconst EMPTY_LIST_TOKEN = \"\\\\\";\n\nfunction escapeWireValue(value: string): string {\n return value.replace(WIRE_SPECIALS, ch => `\\\\${ch}`);\n}\n\n/**\n * Unescape a wire-format value.\n *\n * **Conservative**, and deliberately so: only the four sequences\n * {@link escapeWireValue} actually produces are decoded. A backslash followed\n * by anything else is left exactly as it is.\n *\n * This used to consume the backslash before *any* character, which is\n * indistinguishable for anything this codec emitted — it only ever emits those\n * four — but not for input arriving from elsewhere. A client on an older\n * release sends a Windows path or a LIKE pattern with a literal `C:\\x`\n * unescaped, and greedy unescaping silently turned it into `C:x`, changing\n * which rows matched. Decoding only what the encoder can produce makes the two\n * directions agree across versions.\n */\nfunction unescapeWireValue(value: string): string {\n let result = \"\";\n for (let i = 0; i < value.length; i++) {\n const next = value[i + 1];\n if (value[i] === \"\\\\\" && (next === \"\\\\\" || next === \",\" || next === \"(\" || next === \")\")) {\n result += next;\n i++;\n continue;\n }\n result += value[i];\n }\n return result;\n}\n\n/**\n * Split a parenthesized list string on unescaped commas.\n * Input is the content between `(` and `)`.\n *\n * @example\n * splitListItems(\"admin,editor\") // [\"admin\", \"editor\"]\n * splitListItems(\"hello\\\\, world,foo\") // [\"hello, world\", \"foo\"]\n */\nfunction splitListItems(inner: string): string[] {\n const items: string[] = [];\n let current = \"\";\n for (let i = 0; i < inner.length; i++) {\n if (inner[i] === \"\\\\\" && i + 1 < inner.length) {\n // Escaped pair — consume both chars so the comma in `\\,` is not\n // read as a separator. Kept verbatim; decoding happens once, below.\n current += inner[i] + inner[i + 1];\n i++;\n } else if (inner[i] === \",\") {\n items.push(unescapeWireValue(current));\n current = \"\";\n } else {\n current += inner[i];\n }\n }\n items.push(unescapeWireValue(current));\n return items;\n}\n\n/**\n * Split a group body on commas at paren depth 0, honouring escapes.\n *\n * The escape-awareness is the point. The splitter used to track only paren\n * depth, so a comma inside a scalar value ended a condition:\n * `or(name.eq.Doe, John,age.gte.18)` parsed as *three* conditions, the middle\n * one a fabricated `\" John\" == true`. On an `or` that widens the result set,\n * and nothing anywhere reports an error — the query simply stops meaning what\n * the caller wrote.\n */\nfunction splitGroupItems(inner: string): string[] {\n const parts: string[] = [];\n let depth = 0;\n let start = 0;\n for (let i = 0; i < inner.length; i++) {\n const ch = inner[i];\n if (ch === \"\\\\\" && i + 1 < inner.length) { i++; continue; }\n if (ch === \"(\") depth++;\n else if (ch === \")\") depth--;\n else if (ch === \",\" && depth === 0) {\n parts.push(inner.slice(start, i));\n start = i + 1;\n }\n }\n parts.push(inner.slice(start));\n return parts;\n}\n\n// ---------------------------------------------------------------------------\n// Typed operator map lookups (no `as any`)\n// ---------------------------------------------------------------------------\n\n/**\n * Operator tables as `Map`s, because the key comes off the wire.\n *\n * Indexed as plain objects, every `Object.prototype` member answered: a query\n * string of `?f=valueOf.x` found a truthy \"operator\" — the inherited function —\n * and `deserializeTuple` returned it *as the operator*, so a function object\n * travelled on into the compilers in place of a `WhereFilterOp`. The guard one\n * line below (`if (!canonicalOp)`) reads as though it rejects anything unknown,\n * and does not: `Object.prototype` is not unknown to a plain object.\n *\n * Same shape as the prototype-key defects swept out of `setIn`, `getIn`,\n * `mergeDeep`, `unflattenObject` and `FOREIGN_CONVENTION_UIDS`.\n */\nconst REST_OP_LOOKUP = new Map<string, WhereFilterOp>(\n Object.entries(REST_TO_CANONICAL) as [string, WhereFilterOp][]\n);\nconst CANONICAL_OP_LOOKUP = new Map<string, RestFilterOp>(\n Object.entries(CANONICAL_TO_REST) as [string, RestFilterOp][]\n);\n\n// ---------------------------------------------------------------------------\n// Unknown operators\n// ---------------------------------------------------------------------------\n\n/** The operator spellings a rejection lists back to the caller. */\nconst VALID_OPERATOR_LIST = ALL_WHERE_FILTER_OPS.join(\", \");\n\n/**\n * A filter condition named an operator this dialect does not have.\n *\n * ## Why this throws, rather than returning a typed rejection\n *\n * `deserializeFilter` is the *shared* codec: the REST ingress\n * (`packages/server/src/api/rest/query-parser.ts`), the browser SDK and the\n * admin panel (`buildRebaseData.ts`) all decode through it. Two constraints\n * follow.\n *\n * - It cannot throw the server's `ApiError`. `@rebasepro/common` does not\n * depend on `@rebasepro/server` (the dependency runs the other way), and a\n * browser client has no error handler to render an `ApiError` with. So the\n * rejection is this plain `Error` subclass, whose `message` reads correctly\n * wherever it surfaces — a rejected promise in an app, a 400 body over HTTP.\n * - It cannot be a returned rejection *value*. Every caller assigns the result\n * straight into a query it is about to run; a sentinel that none of them\n * check would be ignored, which is exactly the silently-wrong-filter failure\n * this exists to stop. Throwing is also what this file already does for the\n * sibling cases — `serializeTuple` on an unknown canonical operator,\n * `deserializeLogicalCondition` past the nesting bound — and the REST parser\n * already converts the latter into a 400.\n *\n * `statusCode`, `code` and `details` are carried as fields because the server's\n * Hono error handler duck-types those off any thrown error: a decode path that\n * forgets to convert still answers 400 with the canonical envelope instead of a\n * 500 that says \"An unexpected error occurred\". `query-parser.ts` converts\n * explicitly all the same — that is the path the contract is stated on, and an\n * incidental 400 is not a contract.\n */\nexport class UnknownFilterOperatorError extends Error {\n /** The field the condition was written against. */\n public readonly field: string;\n /** The operator string as it arrived, verbatim. */\n public readonly operator: string;\n /** Every operator this dialect accepts, in canonical spelling. */\n public readonly validOperators: readonly WhereFilterOp[] = ALL_WHERE_FILTER_OPS;\n /** See the class docblock: read by the server's error handler. */\n public readonly statusCode = 400;\n public readonly code = \"UNKNOWN_FILTER_OPERATOR\";\n public readonly details: { field: string; operator: string; validOperators: readonly WhereFilterOp[] };\n\n constructor(field: string, operator: string) {\n super(\n `Unknown filter operator '${operator}' on field '${field}'. `\n + `Valid operators: ${VALID_OPERATOR_LIST}`\n );\n this.name = \"UnknownFilterOperatorError\";\n this.field = field;\n this.operator = operator;\n this.details = { field, operator, validOperators: ALL_WHERE_FILTER_OPS };\n }\n}\n\n/**\n * Two to three characters of ASCII punctuation and nothing else — the shape\n * every symbolic operator has (`==`, `>=`, `<>`, `~~`, `!!`, `>>`, `===`), and\n * one a column value effectively never has.\n *\n * Two characters minimum on purpose. A *single* punctuation character is a\n * perfectly ordinary value — `{ grade: [\"-\", \"+\"] }` is a two-item list, not a\n * condition — and the only single-character operator anyone actually mistypes\n * is `=`, which is named separately below. `<` and `>` need no special case:\n * they are real operators and resolve.\n */\nconst SYMBOLIC_OPERATOR = /^[^\\p{L}\\p{N}\\s]{2,3}$/u;\n\n/** Lowercase, strip everything that is not a letter or digit. */\nfunction normalizeOperatorName(op: string): string {\n return op.toLowerCase().replace(/[^a-z0-9]/g, \"\");\n}\n\n/**\n * Every real operator name with its case and separators removed, so a\n * respelling of one — `arrayContains`, `not_in`, `NOT-LIKE`, `isNull` — is\n * recognised as an attempt at an operator rather than read as a value.\n *\n * These are rejected rather than accepted: admitting a second spelling of an\n * operator would leave two wire spellings of one thing, and the rejection\n * message names the one that works.\n */\nconst RESPELLED_OPERATORS: ReadonlySet<string> = new Set(\n [...ALL_WHERE_FILTER_OPS, ...Object.keys(REST_TO_CANONICAL)].map(normalizeOperatorName)\n);\n\n/**\n * Operator names *other* query dialects use, which this one does not have.\n *\n * This list is curated, and deliberately so. For a word-shaped string there is\n * no rule that separates \"an operator the caller guessed\" from \"a value that\n * happens to be a word\": `{ tags: [\"a\", \"b\"] }` has to keep meaning a two-item\n * `in` list, so the codec cannot simply refuse every unrecognised word in\n * position 0. The line is therefore drawn by name, and only around names whose\n * use as an operator is far more likely than their use as one of two sibling\n * values. `contains` is the motivating case — the first thing a developer\n * reaches for, and until now it compiled to `title IN ('contains', 'Hell')`.\n *\n * Genuinely ambiguous single words (`any`, `all`, `exists`, `search`, `not`)\n * are left off: as operators they are rare, and as enum values they are common.\n * Everywhere else the tie goes to *rejecting*, because a 400 naming the\n * supported set costs the caller one round trip, and the alternative — which is\n * what every name on this list used to produce — is a query that runs, returns\n * rows, and is wrong.\n */\nconst NEAR_MISS_OPERATORS: ReadonlySet<string> = new Set([\n \"contains\", \"notcontains\", \"doesnotcontain\", \"doesnotcontains\",\n \"includes\", \"notincludes\",\n \"startswith\", \"notstartswith\", \"beginswith\", \"startingwith\",\n \"endswith\", \"notendswith\",\n \"matches\", \"notmatches\", \"regex\", \"regexp\",\n \"between\", \"notbetween\",\n \"equals\", \"notequals\", \"equalto\", \"isequalto\", \"isnotequalto\",\n \"greaterthan\", \"greaterthanorequal\", \"greaterthanorequalto\",\n \"lessthan\", \"lessthanorequal\", \"lessthanorequalto\",\n \"isempty\", \"isnotempty\",\n \"oneof\", \"noneof\", \"anyof\", \"allof\",\n \"null\", \"isnullorempty\"\n]);\n\n/**\n * Was this string *meant* as an operator?\n *\n * Only consulted after {@link toCanonicalOp} has already failed to resolve it,\n * so a `true` here is always a rejection.\n */\nfunction isOperatorShaped(op: string): boolean {\n if (op === \"=\") return true;\n if (SYMBOLIC_OPERATOR.test(op)) return true;\n const normalized = normalizeOperatorName(op);\n if (!normalized) return false;\n return RESPELLED_OPERATORS.has(normalized) || NEAR_MISS_OPERATORS.has(normalized);\n}\n\n/**\n * Read a `[op, value]` tuple, if that is what this is.\n *\n * Three outcomes, and the middle one is the defect this function exists for:\n *\n * - the operator resolves (canonical *or* REST spelling) → the canonical tuple;\n * - the operator does not resolve but was plainly meant as one → throw;\n * - it does not look like an operator at all → `undefined`, and the caller\n * falls back to reading the array as a list of values.\n *\n * The old test was `toCanonicalOp(raw[0]) === raw[0]`, i.e. canonical spelling\n * only, with *everything else* — including every REST short-code — dropping\n * through to `[\"in\", raw]`. So the operator string itself became a value in a\n * membership test: `[\"!!\", \"Hello\"]` compiled to `title IN ('!!','Hello')`,\n * which matches, and the caller got back rows their filter was written to\n * exclude. `[\"eq\", \"active\"]` had the same shape of failure.\n */\nfunction readTuple(field: string, raw: unknown): [WhereFilterOp, unknown] | undefined {\n if (!Array.isArray(raw) || raw.length !== 2) return undefined;\n const [op, value] = raw;\n if (typeof op !== \"string\") return undefined;\n\n const canonical = toCanonicalOp(op);\n if (canonical) return [canonical, value];\n\n // A dot means this is a *wire* string, not an operator token: two repeated\n // query params arrive as `[\"gte.18\", \"lt.65\"]`, which is a two-element array\n // of strings and therefore tuple-shaped. Deferred with exactly the test the\n // repeated-dot-string branch below uses, so the two cannot disagree.\n //\n // The property test found this: `[\"ilike\", \"\"]` serializes to `\"ilike.\"`,\n // whose normalized form is a real operator name, so a well-formed\n // round-trip was being rejected as a bad operator.\n if (op.includes(\".\")) return undefined;\n\n if (isOperatorShaped(op)) throw new UnknownFilterOperatorError(field, op);\n\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Serialize: FilterValues → REST querystring\n// ---------------------------------------------------------------------------\n\n/**\n * Serialize a single canonical condition tuple to a PostgREST dot-string.\n *\n * Throws `TypeError` if the input is not a valid `[WhereFilterOp, unknown]` tuple.\n *\n * @example\n * serializeTuple([\"==\", \"active\"]) // \"eq.active\"\n * serializeTuple([\"in\", [\"admin\",\"editor\"]]) // \"in.(admin,editor)\"\n * serializeTuple([\">=\", 18]) // \"gte.18\"\n */\nfunction serializeTuple(tuple: [WhereFilterOp, unknown]): string {\n if (!Array.isArray(tuple) || tuple.length !== 2) {\n throw new TypeError(\n `serializeTuple: expected a [WhereFilterOp, value] tuple, got ${JSON.stringify(tuple)}`\n );\n }\n\n const [op, value] = tuple;\n\n if (typeof op !== \"string\") {\n throw new TypeError(\n `serializeTuple: operator must be a string, got ${typeof op}`\n );\n }\n\n const restOp = CANONICAL_OP_LOOKUP.get(op);\n if (!restOp) {\n throw new TypeError(\n `serializeTuple: unknown operator \"${op}\". Valid operators: ${Object.keys(CANONICAL_TO_REST).join(\", \")}`\n );\n }\n\n // `== null` and `!= null` go out as the null-testing operators.\n //\n // They used to serialize as `eq.null`, and `deserializeTuple` had no way to\n // tell that from a search for the four-character string \"null\" — so it\n // returned the string, and `.where(\"deleted_at\", \"==\", null)` compiled to\n // `deleted_at = 'null'` over HTTP. The typed builder allows it, the Postgres\n // compiler implements it as IS NULL, and only the wire trip broke it.\n //\n // These are the same query: SQL `= NULL` is never true, so `== null` can\n // only mean IS NULL. Emitting it as such is unambiguous in both directions\n // and leaves `eq.null` free to mean the literal string, which it now does.\n if (value === null && (op === \"==\" || op === \"!=\")) {\n return op === \"==\" ? \"isnull.null\" : \"notnull.null\";\n }\n\n if (Array.isArray(value)) {\n // The empty list needs a spelling of its own.\n //\n // A comma-joined format has no way to write \"zero items\": `()` is the\n // empty string between the parens, which splits to `[\"\"]`. So\n // `.where(\"id\", \"in\", [])` — which matches nothing — used to arrive as\n // a search for the empty string: a 500 on a uuid column, silently the\n // wrong rows on a text one.\n //\n // `EMPTY_LIST_TOKEN` is a single unescaped backslash, which no real\n // value can produce: `escapeWireValue` doubles every backslash, so a\n // one-item list holding `\\` serializes as `(\\\\)`. That keeps both\n // directions exact — `[]` and `[\"\"]` stay distinct — rather than\n // trading one lossy reading for another.\n if (value.length === 0) return `${restOp}.(${EMPTY_LIST_TOKEN})`;\n const items = value.map(v => escapeWireValue(stringifyValue(v))).join(\",\");\n return `${restOp}.(${items})`;\n }\n\n return `${restOp}.${stringifyValue(value)}`;\n}\n\n/**\n * Convert `FilterValues` (or `WireFilterValues`) to a PostgREST-style\n * querystring record.\n *\n * - Canonical `[WhereFilterOp, value]` tuples are serialized strictly.\n * - Pre-serialized PostgREST strings (e.g. `\"eq.published\"`) are passed through.\n * - Single conditions produce a string value.\n * - Multiple conditions on the same field produce a string array (repeated params).\n *\n * @example\n * serializeFilter({ status: [\"==\", \"active\"] })\n * // → { status: \"eq.active\" }\n *\n * serializeFilter({ age: [[\">=\", 18], [\"<\", 65]] })\n * // → { age: [\"gte.18\", \"lt.65\"] }\n *\n * // Pre-serialized strings pass through unchanged:\n * serializeFilter({ status: \"eq.published\" })\n * // → { status: \"eq.published\" }\n */\nexport function serializeFilter(\n filter: FilterValues<string> | Record<string, unknown>\n): Record<string, string | string[]> {\n const result: Record<string, string | string[]> = {};\n\n for (const [field, condition] of Object.entries(filter)) {\n if (condition === undefined) continue;\n\n // Pre-serialized PostgREST string — pass through unchanged.\n // This supports WireFilterValues where values may already be\n // serialized dot-strings like \"eq.active\" or raw strings like \"true\".\n if (typeof condition === \"string\") {\n result[field] = condition;\n continue;\n }\n\n // Multiple conditions on the same field: array of tuples\n // We detect this by checking if the first element is also an array.\n if (Array.isArray(condition) && condition.length > 0 && Array.isArray(condition[0])) {\n result[field] = (condition as [WhereFilterOp, unknown][]).map(serializeTuple);\n } else {\n // Single condition — must be a [WhereFilterOp, value] tuple\n result[field] = serializeTuple(condition as [WhereFilterOp, unknown]);\n }\n }\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Deserialize: REST querystring → FilterValues\n// ---------------------------------------------------------------------------\n\n/**\n * Parse a single PostgREST dot-string into a `[WhereFilterOp, unknown]` tuple.\n *\n * All values are returned as strings — the wire format carries no type\n * metadata, so coercion is the data driver's responsibility.\n *\n * If the string doesn't match a known operator prefix, it falls back to\n * `[\"==\", originalString]` (treating the whole string as an equality value).\n * This intentional defense handles values like `\"user@host.com\"` or\n * `\"1.2.3\"` that happen to contain dots.\n */\nfunction deserializeSingle(raw: string): [WhereFilterOp, unknown] {\n const dotIndex = raw.indexOf(\".\");\n if (dotIndex === -1) {\n // No dot → equality on the raw value (kept as string)\n return [\"==\", raw];\n }\n\n const prefix = raw.substring(0, dotIndex);\n const rest = raw.substring(dotIndex + 1);\n\n // Check if the prefix is a known REST operator.\n // This is the key defense against values like \"eq.something\" or \"gt.foo\"\n // being misinterpreted — only known REST short-codes are treated as operators.\n const canonicalOp = REST_OP_LOOKUP.get(prefix);\n if (!canonicalOp) {\n // Not a known operator (e.g., email \"user@host.com\" or version \"1.2.3\")\n // Treat the entire string as an equality value\n return [\"==\", raw];\n }\n\n // Null-testing operators ignore their serialized value — normalize to null\n // so the tuple round-trips stably (`isnull.null` → [\"is-null\", null]).\n if (NULL_OPS.has(canonicalOp)) {\n return [canonicalOp, null];\n }\n\n // Parse list values: \"(admin,editor)\" → [\"admin\", \"editor\"]\n if (rest.startsWith(\"(\") && rest.endsWith(\")\")) {\n const inner = rest.slice(1, -1);\n // See EMPTY_LIST_TOKEN: `(\\)` is the empty list. `()` remains a list\n // holding one empty string, which is what splitting it yields anyway.\n const items = inner === EMPTY_LIST_TOKEN ? [] : splitListItems(inner);\n return [canonicalOp, items];\n }\n\n return [canonicalOp, rest];\n}\n\n/**\n * Convert a PostgREST-style querystring record to `FilterValues`.\n *\n * - String values are parsed as single conditions.\n * - String arrays (repeated query params) become multiple conditions on the same field.\n *\n * @example\n * deserializeFilter({ status: \"eq.active\" })\n * // → { status: [\"==\", \"active\"] }\n *\n * deserializeFilter({ age: [\"gte.18\", \"lt.65\"] })\n * // → { age: [[\">=\", \"18\"], [\"<\", \"65\"]] }\n *\n * @throws {UnknownFilterOperatorError} when a condition names an operator this\n * dialect does not have. See that class for why a rejection here is a throw.\n */\nexport function deserializeFilter(\n query: Record<string, unknown>\n): FilterValues<string> {\n const result: FilterValues<string> = {};\n\n for (const [field, raw] of Object.entries(query)) {\n if (raw === undefined) continue;\n\n // A single `[op, value]` condition.\n const tuple = readTuple(field, raw);\n if (tuple) {\n result[field] = tuple;\n continue;\n }\n\n if (Array.isArray(raw)) {\n if (raw.length === 0) continue;\n\n // An array of tuples: several conditions on the same field. Every\n // element is checked, not just the first — the old test read\n // `raw[0]` and cast the whole array, so one bad operator among\n // several travelled on untouched.\n if (Array.isArray(raw[0])) {\n const tuples = raw.map(item => readTuple(field, item));\n if (tuples.every((t): t is [WhereFilterOp, unknown] => t !== undefined)) {\n result[field] = tuples;\n continue;\n }\n }\n\n if (raw.length === 1) {\n result[field] = typeof raw[0] === \"string\" ? deserializeSingle(raw[0]) : [\"==\", raw[0]];\n } else {\n // If the elements are strings, they might be PostgREST dot-strings (repeated params)\n if (typeof raw[0] === \"string\" && raw[0].includes(\".\")) {\n result[field] = raw.map(r => typeof r === \"string\" ? deserializeSingle(r) : ([\"==\", r] as [WhereFilterOp, unknown])) as [WhereFilterOp, unknown][];\n } else {\n // Otherwise assume it's a list of values for an implicit\n // \"in\" — `{ tags: [\"a\",\"b\"] }`, and `?tags=a&tags=b`, which\n // arrives here identically.\n //\n // A two-element array reaches this line only after\n // `readTuple` has decided its first element was not meant\n // as an operator. Everything longer never had the\n // ambiguity: an operator tuple has exactly two slots.\n result[field] = [\"in\", raw];\n }\n }\n } else if (typeof raw === \"string\") {\n result[field] = deserializeSingle(raw);\n } else {\n result[field] = [\"==\", raw];\n }\n }\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Logical conditions: serialize / deserialize\n// ---------------------------------------------------------------------------\n\n/**\n * Serialize a `LogicalCondition` or `FilterCondition` to its wire-format string.\n *\n * @example\n * serializeLogicalCondition({ column: \"status\", operator: \"==\", value: \"active\" })\n * // → \"status.eq.active\"\n *\n * serializeLogicalCondition({ type: \"or\", conditions: [...] })\n * // → \"or(status.eq.active,status.eq.pending)\"\n */\nexport function serializeLogicalCondition(\n cond: LogicalCondition | FilterCondition\n): string {\n if (\"type\" in cond) {\n // LogicalCondition (and/or)\n const inner = (cond.conditions ?? [])\n .map(serializeLogicalCondition)\n .join(\",\");\n return `${cond.type}(${inner})`;\n }\n\n // FilterCondition\n const restOp = CANONICAL_OP_LOOKUP.get(cond.operator) ?? \"eq\";\n if (Array.isArray(cond.value)) {\n const items = cond.value.map(v => escapeWireValue(stringifyValue(v))).join(\",\");\n return `${cond.column}.${restOp}.(${items})`;\n }\n // Escaped, like a list item. A scalar inside a group sits between the same\n // delimiters a list item does, so leaving it raw let a comma in the value\n // end the condition early — see `splitGroupItems`.\n return `${cond.column}.${restOp}.${escapeWireValue(stringifyValue(cond.value))}`;\n}\n\n/**\n * Parse a logical condition wire-format string back into a\n * `LogicalCondition` or `FilterCondition`.\n *\n * @example\n * deserializeLogicalCondition(\"status.eq.active\")\n * // → { column: \"status\", operator: \"==\", value: \"active\" }\n *\n * deserializeLogicalCondition(\"or(status.eq.active,age.gte.18)\")\n * // → { type: \"or\", conditions: [...] }\n */\n/**\n * How deeply `or(...)`/`and(...)` groups may nest.\n *\n * This parser recurses once per level, on a value that arrives in a query\n * string. Unbounded, twenty thousand levels reached `RangeError: Maximum call\n * stack size exceeded`, which a caller sees as a 500 about the call stack\n * rather than a 400 about their filter. Node's 16 KB header cap keeps a GET\n * below that in practice, but \"the HTTP layer happens to stop it\" is not a\n * bound this parser should rely on.\n *\n * Thirty-two is far past anything a real filter expresses; the deepest in this\n * repository's own tests is three.\n */\nexport const MAX_LOGICAL_NESTING_DEPTH = 32;\n\nexport function deserializeLogicalCondition(\n str: string,\n // Not `depth`: the body already uses that name for paren tracking, inside a\n // block that shadows a parameter of the same name — so the recursion\n // counter silently became the paren counter and never grew.\n nesting = 0\n): LogicalCondition | FilterCondition {\n if (nesting > MAX_LOGICAL_NESTING_DEPTH) {\n throw new Error(\n `Filter groups nest more than ${MAX_LOGICAL_NESTING_DEPTH} levels deep. ` +\n \"Flatten the condition — `or(a,or(b,c))` is `or(a,b,c)`.\"\n );\n }\n // Check for logical group: \"and(...)\" or \"or(...)\"\n const logicalMatch = str.match(/^(and|or)\\((.+)\\)$/);\n if (logicalMatch) {\n const type = logicalMatch[1] as \"and\" | \"or\";\n const innerStr = logicalMatch[2];\n\n const conditions = splitGroupItems(innerStr)\n .map(part => deserializeLogicalCondition(part, nesting + 1));\n\n return { type, conditions };\n }\n\n // FilterCondition: \"column.op.value\"\n const firstDot = str.indexOf(\".\");\n if (firstDot === -1) {\n return { column: str, operator: \"==\", value: true };\n }\n\n const column = str.substring(0, firstDot);\n const rest = str.substring(firstDot + 1);\n\n const secondDot = rest.indexOf(\".\");\n if (secondDot === -1) {\n // \"column.value\" — treat as equality (value kept as string)\n return { column, operator: \"==\", value: unescapeWireValue(rest) };\n }\n\n const opStr = rest.substring(0, secondDot);\n const valueStr = rest.substring(secondDot + 1);\n const operator = toCanonicalOp(opStr) ?? \"==\";\n\n // Parse list values with escape-aware splitting. The wrapping parens are\n // written by the serializer *after* the items are escaped, so an escaped\n // paren inside an item can never be mistaken for them.\n if (valueStr.startsWith(\"(\") && valueStr.endsWith(\")\")) {\n const items = splitListItems(valueStr.slice(1, -1));\n return { column, operator, value: items };\n }\n\n return { column, operator, value: unescapeWireValue(valueStr) };\n}\n","import {\n CollectionAccessor,\n DataDriver,\n Entity,\n EntityValues,\n FindAllParams,\n FindParams,\n FindResponse,\n FindResult,\n IterateParams,\n LogicalCondition,\n OrderByTuple,\n RebaseData,\n RebaseSdkData,\n SDKCollectionClient,\n SDKQueryBuilderInterface,\n WhereFilterOp,\n WhereValueFor,\n type ComputedSortField,\n type SearchMatch\n} from \"@rebasepro/types\";\nimport { toSnakeCase } from \"@rebasepro/utils\";\nimport { QueryBuilder } from \"./query_builder\";\nimport { collectAllPages, paginateFind, resolveFindWindow } from \"./paginate\";\nimport { normalizeOrderBy } from \"./sort-dialect\";\nimport { deserializeFilter } from \"./filter-dialect\";\nimport { buildCompositeId, resolvePrimaryKeys, PrimaryKeyInfo } from \"../util/identity\";\n\nexport interface EntityDataOptions {\n /**\n * Look up a collection's config by slug, to derive row addresses from its\n * primary keys.\n *\n * Called lazily rather than up front: the data layer is created by `Rebase`,\n * which sits *above* the admin that owns the collections, so a resolver\n * registered on mount would otherwise arrive too late to be seen.\n */\n resolveCollection?: (slug: string) => { properties?: Record<string, unknown> } | undefined;\n}\n\nfunction createPrimaryKeyResolver(options?: EntityDataOptions) {\n const cache = new Map<string, PrimaryKeyInfo[]>();\n const warned = new Set<string>();\n\n return function primaryKeysFor(slug: string): PrimaryKeyInfo[] {\n const cached = cache.get(slug);\n if (cached) return cached;\n\n const collection = options?.resolveCollection?.(slug);\n if (!collection) {\n // The registry may not have been registered yet. Don't memoize a\n // miss, or the collection would stay address-less for this session.\n return [];\n }\n\n const keys = resolvePrimaryKeys(collection);\n if (keys.length > 0) {\n // Memoized for the session: a collection's key does not change\n // while the app runs, and this is called once per row. Editing\n // `isId` in the schema editor needs a reload to take effect here.\n cache.set(slug, keys);\n return keys;\n }\n\n if (!warned.has(slug)) {\n warned.add(slug);\n // Silence here surfaces much later as rows that cannot be opened,\n // linked, or saved, with nothing pointing back at the cause.\n console.warn(\n `[rebase] Collection '${slug}' declares no primary key, so its rows have no address: ` +\n `detail links, caching and relations will not work for it. ` +\n `Mark the key property with \\`isId\\` in its collection config — the server logs which ` +\n `column to mark at boot, if its schema knows the key.`\n );\n }\n return keys;\n };\n}\n\n/**\n * Give a flat row the Entity view-model the admin renders.\n *\n * The address is *derived here* — it is not a column, and the row it came from\n * does not contain one. Rows carry exactly what the table has, with the types\n * Postgres returned; the id is this layer's invention, and this is the only\n * place it is minted.\n *\n * `primaryKeys` empty falls back to a literal `id` on the row: drivers other\n * than postgres still serve rows with one, and this keeps them working.\n */\nfunction rowToEntity<M extends Record<string, unknown>>(\n row: Record<string, unknown>,\n slug: string,\n primaryKeys: PrimaryKeyInfo[] = []\n): Entity<M> {\n // Query-computed metadata rides in on the row because that is how the wire\n // carries it, but it is not a column: it belongs beside `values`, not in\n // them. Left inside, `_matches` would show up in the record inspector as a\n // field the collection never declared.\n const { _matches, ...values } = row as Record<string, unknown> & { _matches?: SearchMatch[] };\n\n return {\n id: primaryKeys.length > 0\n ? buildCompositeId(row, primaryKeys)\n : row.id as string | number,\n path: slug,\n values: values as EntityValues<M>,\n ...(_matches ? { searchMatches: _matches } : {})\n };\n}\n\n/**\n * The relation envelope `toFlatRow` writes where a relation was:\n * `{ id, path, __type: \"relation\", data: { id, path, values } }`. It is the\n * admin's view-model, and the only pipeline that produces one is postgres'.\n */\nfunction isRelationEnvelope(\n value: unknown\n): value is { __type: \"relation\"; data?: { values?: Record<string, unknown> } } {\n return typeof value === \"object\"\n && value !== null\n && !Array.isArray(value)\n && (value as { __type?: unknown }).__type === \"relation\";\n}\n\n/** The target's own columns, as `toRestRow` would have inlined them. */\nfunction inlineEnvelope(envelope: { data?: { values?: Record<string, unknown> } }): Record<string, unknown> {\n return envelope.data?.values ?? {};\n}\n\n/**\n * Replace every relation envelope on a row with the target's flat columns.\n *\n * The SDK serves one relation shape — the inlined one (see\n * {@link RestFetchService}) — and reads that come back through a *driver*\n * method rather than the REST pipeline still carry envelopes. Realtime is the\n * one such read left: there is no `listenForRest`, so the rows arrive shaped\n * for the admin and are flattened here instead.\n *\n * Only applied where the REST pipeline is the contract (see `find`); a driver\n * without a `restFetchService` keeps whatever it returns, so the admin's own\n * path through {@link buildRebaseData} is untouched.\n */\nfunction inlineRelationRefs(row: Record<string, unknown>): Record<string, unknown> {\n let out: Record<string, unknown> | undefined;\n for (const [key, value] of Object.entries(row)) {\n if (isRelationEnvelope(value)) {\n out = out ?? { ...row };\n out[key] = inlineEnvelope(value);\n } else if (Array.isArray(value) && value.some(isRelationEnvelope)) {\n out = out ?? { ...row };\n out[key] = value.map((item) => isRelationEnvelope(item) ? inlineEnvelope(item) : item);\n }\n }\n return out ?? row;\n}\n\nfunction createDriverAccessor<M extends Record<string, unknown> = Record<string, unknown>>(\n driver: DataDriver,\n slug: string,\n getPks: () => PrimaryKeyInfo[] = () => []\n): CollectionAccessor<M> {\n const accessor: CollectionAccessor<M> = {\n async find(params?: FindParams<M>): Promise<FindResponse<M>> {\n // Ensure filters are in canonical [op, value] format even if passed as PostgREST strings\n const filter = params?.where ? deserializeFilter(params.where as Record<string, unknown>) : undefined;\n const { limit, offset, driverOffset } = resolveFindWindow(params);\n\n // One relation shape, whatever the call looks like.\n //\n // This used to fork on `include`: asking for one ran the REST\n // pipeline, which inlines a relation as the target's own columns;\n // not asking ran the driver's own fetch, which eagerly loaded\n // *every* relation and put a `{ __type: \"relation\" }` envelope\n // where the foreign key was. The same method answered in two\n // shapes, the generated types described only one, and a column\n // typed `string` arrived as an object.\n //\n // The REST pipeline is the published contract — the shape the HTTP\n // API serves for this same query, and what `RestFetchService`\n // documents — so every read goes through it when the driver has\n // one. Drivers without one (every browser driver, and so the\n // admin's own path through `buildRebaseData`) are untouched.\n const fetchService = driver.restFetchService;\n const rows = fetchService\n ? await fetchService.fetchCollectionForRest(\n slug,\n {\n filter,\n // Without this the group was dropped and the read ran\n // unfiltered — every row the caller's policies allow,\n // in place of the ones they asked for.\n logical: params?.logical,\n limit,\n offset: driverOffset,\n orderBy: normalizeOrderBy(params?.orderBy),\n searchString: params?.searchString\n },\n params?.include\n )\n : await driver.fetchCollection<M>({\n path: slug,\n limit,\n offset: driverOffset,\n filter,\n logical: params?.logical,\n orderBy: normalizeOrderBy(params?.orderBy),\n searchString: params?.searchString\n });\n\n // Compute real total when count is available\n let total = rows.length + offset;\n let hasMore = rows.length >= limit;\n if (driver.count) {\n // The same narrowing the rows were read with. Counting only by\n // `filter` reported the whole collection beside a narrowed\n // page, and `hasMore` is derived from it — so the list offered\n // a next page that did not exist.\n total = await driver.count({\n path: slug,\n filter,\n logical: params?.logical,\n searchString: params?.searchString\n });\n hasMore = offset + rows.length < total;\n }\n\n return {\n data: rows.map((row: Record<string, unknown>) => rowToEntity<M>(row, slug, getPks())),\n meta: { total, limit, offset, hasMore }\n };\n },\n\n async findById(id: string | number): Promise<Entity<M> | undefined> {\n // Same contract as `find` above: one row read the same way the\n // collection read is, so `find()[0]` and `findById()` agree.\n const fetchService = driver.restFetchService;\n const row = fetchService\n ? await fetchService.fetchOneForRest(slug, id)\n : await driver.fetchOne<M>({ path: slug, id: id });\n return row ? rowToEntity<M>(row, slug, getPks()) : undefined;\n },\n\n async create(data: Partial<EntityValues<M>>, id?: string | number): Promise<Entity<M>> {\n const row = await driver.save<M>({\n path: slug,\n values: data,\n id: id,\n status: \"new\"\n });\n return rowToEntity<M>(row, slug, getPks());\n },\n\n createMany: driver.saveMany\n ? async (data: Partial<EntityValues<M>>[], options?: { upsert?: boolean }): Promise<Entity<M>[]> => {\n const rows = await driver.saveMany!<M>({\n path: slug,\n rows: data,\n upsert: options?.upsert\n });\n return rows.map((row) => rowToEntity<M>(row, slug, getPks()));\n }\n : undefined,\n\n async update(id: string | number, data: Partial<EntityValues<M>>): Promise<Entity<M>> {\n const row = await driver.save<M>({\n path: slug,\n values: data,\n id: id,\n status: \"existing\"\n });\n return rowToEntity<M>(row, slug, getPks());\n },\n\n async delete(id: string | number): Promise<void> {\n return driver.delete({\n row: { id,\npath: slug,\nvalues: {} as Record<string, unknown> }\n });\n },\n\n // Present only when the driver is: exposing these unconditionally and\n // looping single writes underneath would give a caller neither the\n // atomicity nor the single round trip they reached for a batch to get,\n // while looking exactly like it had.\n updateMany: driver.updateMany\n ? async (updates: { id: string | number; data: Partial<EntityValues<M>> }[]): Promise<Entity<M>[]> => {\n const rows = await driver.updateMany!<M>({\n path: slug,\n updates: updates.map(u => ({ id: u.id,\nvalues: u.data })),\n });\n return rows.map(row => rowToEntity<M>(row, slug, getPks()));\n }\n : undefined,\n\n deleteMany: driver.deleteMany\n ? async (ids: (string | number)[]): Promise<void> => {\n await driver.deleteMany!<M>({ path: slug,\nids });\n }\n : undefined,\n\n count: driver.count\n ? async (params?: FindParams<M>): Promise<number> => {\n const filter = params?.where ? deserializeFilter(params.where as Record<string, unknown>) : undefined;\n // Every narrowing `find()` applies has to apply here too, or\n // the count describes a different query than the one it is\n // reported against.\n return driver.count!({\n path: slug,\n filter,\n logical: params?.logical,\n searchString: params?.searchString\n });\n }\n : undefined,\n\n listen: driver.listenCollection\n ? (params: FindParams<M> | undefined, onUpdate: (response: FindResponse<M>) => void, onError?: (error: Error) => void) => {\n const { limit, offset, driverOffset } = resolveFindWindow(params);\n // Realtime has no REST-pipeline equivalent, so the rows arrive\n // admin-shaped. Flatten them to the one shape the rest of this\n // accessor serves.\n const normalize = driver.restFetchService ? inlineRelationRefs : (row: Record<string, unknown>) => row;\n return driver.listenCollection!<M>({\n path: slug,\n limit,\n offset: driverOffset,\n filter: params?.where,\n logical: params?.logical,\n orderBy: normalizeOrderBy(params?.orderBy),\n searchString: params?.searchString,\n searchExplain: params?.searchExplain,\n onUpdate: (entities) => {\n onUpdate({\n data: entities.map((row: Record<string, unknown>) => rowToEntity<M>(normalize(row), slug, getPks())),\n meta: {\n // No count is issued on this path, so the total\n // is unknown; the lower bound is the rows in\n // hand plus the ones paged past to reach them.\n // Reporting `entities.length` claimed a read at\n // offset 100 had found a collection of two.\n total: offset + entities.length,\n limit,\n offset,\n hasMore: entities.length >= limit\n }\n });\n },\n onError\n });\n } : undefined,\n\n listenById: driver.listenOne\n ? (id: string | number, onUpdate: (entity: Entity<M> | undefined) => void, onError?: (error: Error) => void) => {\n const normalize = driver.restFetchService ? inlineRelationRefs : (row: Record<string, unknown>) => row;\n return driver.listenOne!<M>({\n path: slug,\n id: id,\n onUpdate: (entity) => onUpdate(entity ? rowToEntity<M>(normalize(entity), slug, getPks()) : undefined),\n onError\n });\n } : undefined,\n\n // Fluent Query Builder\n where(columnOrCondition: string | LogicalCondition, operator?: WhereFilterOp, value?: unknown) {\n const builder = new QueryBuilder<M>(accessor);\n if (typeof columnOrCondition === \"object\") {\n return builder.where(columnOrCondition);\n }\n return builder.where(columnOrCondition as keyof M & string, operator!, value as WhereValueFor<WhereFilterOp, M[keyof M & string]>);\n },\n orderBy(column: (keyof M & string) | ComputedSortField, ascending?: \"asc\" | \"desc\") {\n return new QueryBuilder<M>(accessor).orderBy(column, ascending);\n },\n limit(count: number) {\n return new QueryBuilder<M>(accessor).limit(count);\n },\n offset(count: number) {\n return new QueryBuilder<M>(accessor).offset(count);\n },\n search(searchString: string, options?: { explain?: boolean }) {\n return new QueryBuilder<M>(accessor).search(searchString, options);\n },\n vectorSearch(\n property: string,\n vector: number[],\n options?: { distance?: \"cosine\" | \"l2\" | \"inner_product\"; threshold?: number }\n ) {\n return new QueryBuilder<M>(accessor).vectorSearch(property, vector, options);\n },\n include(...relations: string[]) {\n return new QueryBuilder<M>(accessor).include(...relations);\n }\n };\n\n return accessor;\n}\n\n/**\n * Build a `RebaseData` object from a `DataDriver` using JavaScript Proxy.\n *\n * This is the key bridge: any property access like `data.products` returns\n * a `CollectionAccessor` backed by the underlying DataDriver, without\n * needing per-collection code generation.\n *\n * @example\n * const data = buildRebaseData(driver);\n * await data.products.create({ name: \"Camera\", price: 299 });\n * const { data: items } = await data.products.find({ where: { status: [\"==\", \"published\"] } });\n */\nexport function buildRebaseData(driver: DataDriver, options?: EntityDataOptions): RebaseData {\n const cache = new Map<string, CollectionAccessor>();\n const primaryKeysFor = createPrimaryKeyResolver(options);\n\n function getAccessor(slug: string): CollectionAccessor {\n let accessor = cache.get(slug);\n if (!accessor) {\n accessor = createDriverAccessor(driver, slug, () => primaryKeysFor(slug));\n cache.set(slug, accessor);\n }\n return accessor;\n }\n\n const target = {\n collection: getAccessor\n } as RebaseData;\n\n return new Proxy(target, {\n get(_target, prop: string | symbol) {\n if (prop === \"collection\") return getAccessor;\n // Ignore Symbol properties (e.g. Symbol.toPrimitive, Symbol.iterator)\n if (typeof prop === \"symbol\") return undefined;\n // Ignore internal JS properties\n if (prop === \"then\" || prop === \"toJSON\" || prop === \"$$typeof\") return undefined;\n\n // Convert camelCase property names to snake_case slugs\n const slug = toSnakeCase(prop);\n return getAccessor(slug);\n }\n });\n}\n\n// =============================================================================\n// SDK data — flat rows (symmetric with the frontend SDK client)\n// =============================================================================\n\n/**\n * Unwrap a Entity back into the flat row it was built from. `rowToEntity` keeps\n * the row untouched under `.values` and derives `.id` alongside it, so dropping\n * the wrapper is the whole operation — the address was never part of the row.\n */\nfunction entityToRow<M extends Record<string, unknown>>(entity: Entity<M>): M {\n return entity.values as unknown as M;\n}\n\n/**\n * Fluent query builder for the flat SDK data layer. Mirrors {@link QueryBuilder}\n * but resolves to `FindResult<M>` (flat rows) instead of Entity-wrapped\n * `FindResponse<M>`.\n */\nclass SdkQueryBuilder<M extends Record<string, unknown> = Record<string, unknown>> implements SDKQueryBuilderInterface<M> {\n private params: FindParams = { where: {} };\n\n constructor(private client: SDKCollectionClient<M>) {}\n\n where<K extends keyof M & string, Op extends WhereFilterOp>(column: K, operator: Op, value: WhereValueFor<Op, M[K]>): this;\n where(logicalCondition: LogicalCondition): this;\n where(columnOrCondition: string | LogicalCondition, operator?: WhereFilterOp, value?: unknown): this {\n if (typeof columnOrCondition === \"object\" && columnOrCondition !== null && \"type\" in columnOrCondition) {\n this.params.logical = columnOrCondition as LogicalCondition;\n return this;\n }\n if (!this.params.where) this.params.where = {};\n const column = columnOrCondition as string;\n const condition: [WhereFilterOp, unknown] = [operator!, value];\n const existing = this.params.where[column];\n if (existing === undefined) {\n this.params.where[column] = condition;\n } else if (Array.isArray(existing) && existing.length > 0 && Array.isArray(existing[0])) {\n (this.params.where[column] as [WhereFilterOp, unknown][]).push(condition);\n } else {\n let firstCondition: [WhereFilterOp, unknown];\n if (Array.isArray(existing) && existing.length === 2 && typeof existing[0] === \"string\") {\n firstCondition = existing as [WhereFilterOp, unknown];\n } else {\n firstCondition = [\"==\", existing];\n }\n this.params.where[column] = [firstCondition, condition];\n }\n return this;\n }\n\n /** Called again, this adds a tie-breaker rather than replacing the sort. */\n orderBy(column: (keyof M & string) | ComputedSortField, direction: \"asc\" | \"desc\" = \"asc\"): this {\n const existing = normalizeOrderBy(this.params.orderBy) ?? [];\n this.params.orderBy = [...existing, [column, direction] as OrderByTuple];\n return this;\n }\n\n limit(count: number): this { this.params.limit = count; return this; }\n offset(count: number): this { this.params.offset = count; return this; }\n search(searchString: string, options?: { explain?: boolean }): this { this.params.searchString = searchString; if (options?.explain !== undefined) this.params.searchExplain = options.explain; return this; }\n vectorSearch(\n property: string,\n vector: number[],\n options?: { distance?: \"cosine\" | \"l2\" | \"inner_product\"; threshold?: number }\n ): this {\n this.params.vectorSearch = {\n property,\n vector,\n ...(options?.distance !== undefined && { distance: options.distance }),\n ...(options?.threshold !== undefined && { threshold: options.threshold })\n };\n return this;\n }\n include(...relations: string[]): this { this.params.include = relations; return this; }\n\n async find(): Promise<FindResult<M>> {\n return this.client.find(this.params as FindParams<M>);\n }\n\n async count(): Promise<number> {\n return this.client.count ? this.client.count(this.params as FindParams<M>) : 0;\n }\n\n listen(onUpdate: (data: FindResult<M>) => void, onError?: (error: Error) => void): () => void {\n if (!this.client.listen) {\n throw new Error(\"Listen is only available when the driver supports realtime.\");\n }\n return this.client.listen(this.params as FindParams<M>, onUpdate, onError);\n }\n}\n\n/**\n * Wrap a Entity-shaped {@link CollectionAccessor} into a flat\n * {@link SDKCollectionClient}. Every returned record is unwrapped to a flat row\n * so the backend SDK is byte-for-byte the same shape as the frontend client.\n */\nfunction toSdkCollectionClient<M extends Record<string, unknown>>(\n snap: CollectionAccessor<M>,\n slug = \"collection\"\n): SDKCollectionClient<M> {\n const client: SDKCollectionClient<M> = {\n async find(params?: FindParams<M>): Promise<FindResult<M>> {\n const res = await snap.find(params);\n return { data: res.data.map(entityToRow), meta: res.meta };\n },\n // Pagination is shared with the HTTP client rather than reimplemented:\n // both transports satisfy the same `SDKCollectionClient`, so a walk that\n // behaved differently in-process than over the wire would be a bug the\n // type system could not see.\n iterate(params?: IterateParams<M>) {\n return paginateFind<M>((p) => client.find(p), params, slug);\n },\n findAll(params?: FindAllParams<M>) {\n return collectAllPages<M>((p) => client.find(p), params, slug);\n },\n async findById(id: string | number): Promise<M | undefined> {\n const s = await snap.findById(id);\n return s ? entityToRow(s) : undefined;\n },\n async create(data: Partial<M>, id?: string | number): Promise<M> {\n return entityToRow(await snap.create(data as Partial<EntityValues<M>>, id));\n },\n async createMany(data: Partial<M>[], options?: { upsert?: boolean }): Promise<M[]> {\n if (!Array.isArray(data)) {\n throw new TypeError(\"createMany expects an array of records.\");\n }\n if (data.length === 0) return [];\n if (!snap.createMany) {\n throw new Error(\n \"Bulk writes are not supported by this collection's data source. \" +\n \"Fall back to create() per record.\"\n );\n }\n const rows = await snap.createMany(data as Partial<EntityValues<M>>[], options);\n return rows.map(entityToRow);\n },\n async update(id: string | number, data: Partial<M>): Promise<M> {\n return entityToRow(await snap.update(id, data as Partial<EntityValues<M>>));\n },\n async updateMany(updates: { id: string | number; data: Partial<M> }[]): Promise<M[]> {\n if (!Array.isArray(updates)) {\n throw new TypeError(\"updateMany expects an array of { id, data } entries.\");\n }\n if (updates.length === 0) return [];\n if (!snap.updateMany) {\n throw new Error(\n \"Bulk updates are not supported by this collection's data source. \" +\n \"Fall back to update() per record.\"\n );\n }\n const rows = await snap.updateMany(\n updates.map(u => ({ id: u.id,\ndata: u.data as Partial<EntityValues<M>> }))\n );\n return rows.map(entityToRow);\n },\n delete(id: string | number): Promise<void> {\n return snap.delete(id);\n },\n async deleteMany(ids: (string | number)[]): Promise<void> {\n if (!Array.isArray(ids)) {\n throw new TypeError(\"deleteMany expects an array of ids.\");\n }\n if (ids.length === 0) return;\n if (!snap.deleteMany) {\n throw new Error(\n \"Bulk deletes are not supported by this collection's data source. \" +\n \"Fall back to delete() per record.\"\n );\n }\n await snap.deleteMany(ids);\n },\n count: snap.count ? (params?: FindParams<M>) => snap.count!(params) : undefined,\n listen: snap.listen\n ? (params: FindParams<M> | undefined, onUpdate: (r: FindResult<M>) => void, onError?: (e: Error) => void) =>\n snap.listen!(params, (res) => onUpdate({ data: res.data.map(entityToRow), meta: res.meta }), onError)\n : undefined,\n listenById: snap.listenById\n ? (id: string | number, onUpdate: (r: M | undefined) => void, onError?: (e: Error) => void) =>\n snap.listenById!(id, (s) => onUpdate(s ? entityToRow(s) : undefined), onError)\n : undefined,\n where(columnOrCondition: string | LogicalCondition, operator?: WhereFilterOp, value?: unknown) {\n const builder = new SdkQueryBuilder<M>(client);\n if (typeof columnOrCondition === \"object\") {\n return builder.where(columnOrCondition);\n }\n return builder.where(columnOrCondition as keyof M & string, operator!, value as WhereValueFor<WhereFilterOp, M[keyof M & string]>);\n },\n orderBy: (column: keyof M & string, direction?: \"asc\" | \"desc\") => new SdkQueryBuilder<M>(client).orderBy(column, direction),\n limit: (count: number) => new SdkQueryBuilder<M>(client).limit(count),\n offset: (count: number) => new SdkQueryBuilder<M>(client).offset(count),\n search: (searchString: string) => new SdkQueryBuilder<M>(client).search(searchString),\n vectorSearch: (\n property: string,\n vector: number[],\n options?: { distance?: \"cosine\" | \"l2\" | \"inner_product\"; threshold?: number }\n ) => new SdkQueryBuilder<M>(client).vectorSearch(property, vector, options),\n include: (...relations: string[]) => new SdkQueryBuilder<M>(client).include(...relations)\n };\n return client;\n}\n\n/**\n * Wrap a flat {@link SDKCollectionClient} into a Entity-shaped\n * {@link CollectionAccessor}. Every returned row is re-wrapped into the\n * `{ id, path, values }` view-model the admin panel renders.\n */\nfunction toEntityAccessor<M extends Record<string, unknown>>(\n sdk: SDKCollectionClient<M>,\n slug: string,\n getPks: () => PrimaryKeyInfo[] = () => []\n): CollectionAccessor<M> {\n const accessor: CollectionAccessor<M> = {\n async find(params?: FindParams<M>): Promise<FindResponse<M>> {\n const res = await sdk.find(params);\n return { data: res.data.map((row) => rowToEntity<M>(row, slug, getPks())), meta: res.meta };\n },\n async findById(id: string | number): Promise<Entity<M> | undefined> {\n const row = await sdk.findById(id);\n return row ? rowToEntity<M>(row, slug, getPks()) : undefined;\n },\n async create(data: Partial<EntityValues<M>>, id?: string | number): Promise<Entity<M>> {\n return rowToEntity<M>(await sdk.create(data as Partial<M>, id), slug, getPks());\n },\n // Declared on `CollectionAccessor` and, until now, never implemented on\n // this side of the boundary — so the admin's own import wrote one HTTP\n // request per row and could neither be atomic nor upsert. It forwards to\n // the same `/bulk` route the SDK client uses.\n createMany: sdk.createMany\n ? async (data: Partial<EntityValues<M>>[], options?: { upsert?: boolean }): Promise<Entity<M>[]> => {\n const rows = await sdk.createMany!(data as Partial<M>[], options);\n return rows.map((row) => rowToEntity<M>(row, slug, getPks()));\n }\n : undefined,\n async update(id: string | number, data: Partial<EntityValues<M>>): Promise<Entity<M>> {\n const row = await sdk.update(id, data as Partial<M>);\n if (!row) throw new Error(`Update returned no data for id ${id}`);\n return rowToEntity<M>(row, slug, getPks());\n },\n delete(id: string | number): Promise<void> {\n return sdk.delete(id);\n },\n count: sdk.count ? (params?: FindParams<M>) => sdk.count!(params) : undefined,\n listen: sdk.listen\n ? (params: FindParams<M> | undefined, onUpdate: (r: FindResponse<M>) => void, onError?: (e: Error) => void) =>\n sdk.listen!(params, (res) => onUpdate({ data: res.data.map((row) => rowToEntity<M>(row, slug, getPks())), meta: res.meta }), onError)\n : undefined,\n listenById: sdk.listenById\n ? (id: string | number, onUpdate: (s: Entity<M> | undefined) => void, onError?: (e: Error) => void) =>\n sdk.listenById!(id, (row) => onUpdate(row ? rowToEntity<M>(row, slug, getPks()) : undefined), onError)\n : undefined,\n where(columnOrCondition: string | LogicalCondition, operator?: WhereFilterOp, value?: unknown) {\n const builder = new QueryBuilder<M>(accessor);\n if (typeof columnOrCondition === \"object\") {\n return builder.where(columnOrCondition);\n }\n return builder.where(columnOrCondition as keyof M & string, operator!, value as WhereValueFor<WhereFilterOp, M[keyof M & string]>);\n },\n orderBy: (column: keyof M & string, direction?: \"asc\" | \"desc\") => new QueryBuilder<M>(accessor).orderBy(column, direction),\n limit: (count: number) => new QueryBuilder<M>(accessor).limit(count),\n offset: (count: number) => new QueryBuilder<M>(accessor).offset(count),\n search: (searchString: string) => new QueryBuilder<M>(accessor).search(searchString),\n vectorSearch: (\n property: string,\n vector: number[],\n options?: { distance?: \"cosine\" | \"l2\" | \"inner_product\"; threshold?: number }\n ) => new QueryBuilder<M>(accessor).vectorSearch(property, vector, options),\n include: (...relations: string[]) => new QueryBuilder<M>(accessor).include(...relations)\n };\n return accessor;\n}\n\n/**\n * Wrap a flat {@link RebaseSdkData} into a Entity-shaped {@link RebaseData}.\n *\n * This is the **admin boundary**: the SDK client (`client.data`) returns flat\n * rows, but the admin renders the `Entity` view-model (`entity.values.*`).\n * `core/Rebase.tsx` wraps `client.data` through this before handing it to the\n * admin `RebaseDataContext` — without it the admin renders rows with only their\n * `id`.\n */\n/**\n * Only the by-slug accessor is asked for, so only that is required.\n *\n * Taking a whole `RebaseSdkData` meant taking `RebaseSdkData<unknown>`, whose\n * dynamic branch is an index signature — and no `RebaseSdkData<DB>` satisfies\n * it, because its own `collection` method is not a `SDKCollectionClient`. So a\n * caller holding a *typed* client could not pass it to a function that reads\n * one method off it, and that method is identical on every instantiation.\n */\nexport function wrapAsEntityData(sdkData: Pick<RebaseSdkData, \"collection\">, options?: EntityDataOptions): RebaseData {\n const cache = new Map<string, CollectionAccessor>();\n const primaryKeysFor = createPrimaryKeyResolver(options);\n\n function getAccessor(slug: string): CollectionAccessor {\n let accessor = cache.get(slug);\n if (!accessor) {\n accessor = toEntityAccessor(sdkData.collection(slug), slug, () => primaryKeysFor(slug));\n cache.set(slug, accessor);\n }\n return accessor;\n }\n\n const target = { collection: getAccessor } as RebaseData;\n\n return new Proxy(target, {\n get(_target, prop: string | symbol) {\n if (prop === \"collection\") return getAccessor;\n if (typeof prop === \"symbol\") return undefined;\n if (prop === \"then\" || prop === \"toJSON\" || prop === \"$$typeof\") return undefined;\n return getAccessor(toSnakeCase(prop));\n }\n });\n}\n\n/**\n * Wrap a Entity-shaped {@link RebaseData} into a flat {@link RebaseSdkData}.\n *\n * Every collection accessor is adapted to return flat rows. Use this to derive\n * the flat SDK data layer (`context.data`) from an existing Entity data layer\n * — e.g. the admin routes its Entity data via `useData()` and exposes the\n * same routing as flat `context.data` for callbacks by wrapping it here.\n */\nexport function wrapAsSdkData(entityData: RebaseData): RebaseSdkData {\n const cache = new Map<string, SDKCollectionClient>();\n\n function getAccessor(slug: string): SDKCollectionClient {\n let accessor = cache.get(slug);\n if (!accessor) {\n accessor = toSdkCollectionClient(entityData.collection(slug), slug);\n cache.set(slug, accessor);\n }\n return accessor;\n }\n\n const target = { collection: getAccessor } as RebaseSdkData;\n\n return new Proxy(target, {\n get(_target, prop: string | symbol) {\n if (prop === \"collection\") return getAccessor;\n if (typeof prop === \"symbol\") return undefined;\n if (prop === \"then\" || prop === \"toJSON\" || prop === \"$$typeof\") return undefined;\n return getAccessor(toSnakeCase(prop));\n }\n });\n}\n\n/**\n * Build a flat {@link RebaseSdkData} from a `DataDriver`.\n *\n * This is the developer-facing SDK data layer used by backend framework\n * callbacks & scripts (`context.data` / `rebase.data`). It returns flat rows —\n * identical in shape to the frontend SDK client, down to how a relation is\n * served: a foreign key stays a foreign key, and a relation named in `include`\n * arrives as the target's own columns. The `{ __type: \"relation\" }` envelope is\n * the admin's view-model and never reaches here.\n *\n * The admin uses {@link buildRebaseData} (Entity) over its own driver.\n */\nexport function buildSdkData(driver: DataDriver): RebaseSdkData {\n return wrapAsSdkData(buildRebaseData(driver));\n}\n","/**\n * The one place a collection's `search` block becomes SQL.\n *\n * Four things describe a Postgres table in this codebase — the DDL generator,\n * the Drizzle schema generator, the runtime table builder for BaaS mode, and\n * the boot-time schema ensure — and each of them has, at some point, described\n * a column differently from the others. The `varchar(255)` note in\n * `generate-postgres-ddl-logic` is one such scar: the same property produced a\n * capped column down one path and an uncapped one down the other, and nothing\n * failed until a user hit the cap.\n *\n * So the search column is not implemented four times. It is computed once,\n * here, and every generator renders the same {@link SearchColumnSpec}. There is\n * a test asserting exactly that (`search-column-contract.test.ts`); the point of\n * this module is that the test has something to assert *about*.\n *\n * ## Why the expressions look the way they do\n *\n * A `GENERATED ALWAYS AS … STORED` expression must be strictly IMMUTABLE, and\n * Postgres is stricter here than intuition. Verified against PostgreSQL 18:\n *\n * | expression | immutable |\n * |-----------------------------------------|-----------|\n * | `to_tsvector('spanish', col)` | yes |\n * | `to_tsvector(col)` (1-arg) | **no** — depends on `default_text_search_config` |\n * | `array_to_string(col, ' ')` | **no** |\n * | `col::text` on `text[]` | **no** |\n * | `to_jsonb(col)` | **no** |\n * | `unaccent(col)` | **no** — dictionary lookup is STABLE |\n * | `jsonb_to_tsvector('spanish', j, '[\"string\"]')` | yes |\n * | `setweight(...) || setweight(...)` | yes |\n *\n * Three of the four things a real search column needs are therefore unavailable\n * directly, which is why {@link searchHelperFunctions} exists: each wraps a\n * stable built-in in an SQL function declared IMMUTABLE. That declaration is a\n * promise, and it is a true one for these three — array joining, JSON string\n * extraction and accent folding are all deterministic for a given input; the\n * built-ins are marked stable only because they must account for element types\n * and dictionaries in general.\n *\n * The alternative was to skip `unaccent` and text arrays entirely. That is not\n * a real option in an accented language: Postgres stems `auditoría` to\n * `auditor` and `auditoria` to `auditori` — *different lexemes* — so a query\n * typed without accents misses every row that carries them.\n */\nimport {\n CollectionConfig,\n Property,\n StringProperty,\n ArrayProperty,\n MapProperty,\n SearchConfig,\n SearchField,\n SearchWeight,\n isPostgresCollectionConfig,\n DEFAULT_SEARCH_COLUMN,\n DEFAULT_SEARCH_LANGUAGE,\n DEFAULT_SEARCH_WEIGHT,\n DEFAULT_FUZZY_THRESHOLD\n} from \"@rebasepro/types\";\nimport { createHash } from \"node:crypto\";\nimport { getTableName } from \"@rebasepro/common\";\nimport { toSnakeCase, toPostgresIdentifier } from \"@rebasepro/utils\";\n\n/** Schema-qualified so a collection outside `public` still resolves them. */\nconst HELPER_SCHEMA = \"public\";\n\n/**\n * Names of the helper functions. Frozen: they are recorded in the stored\n * generation expression of every search column ever created, so renaming one\n * orphans every table that already has a search column.\n */\nexport const SEARCH_TEXT_FN = `${HELPER_SCHEMA}.rebase_search_text`;\nexport const SEARCH_UNACCENT_FN = `${HELPER_SCHEMA}.rebase_search_unaccent`;\n\n/** How a declared path reaches text, which decides the SQL that extracts it. */\ntype FieldKind = \"text\" | \"text_array\" | \"jsonb\";\n\n/** One resolved field: where it lives, how to read it, what it is worth. */\nexport interface ResolvedSearchField {\n /** The path exactly as the author wrote it, for error messages. */\n path: string;\n /** The physical column the path starts at. */\n column: string;\n /** Dotted remainder addressed inside a JSONB column, if any. */\n jsonPath: string[];\n kind: FieldKind;\n weight: SearchWeight;\n /** The `setweight(to_tsvector(…), 'X')` term this field contributes. */\n sql: string;\n /** The plain-text term this field contributes, for the fuzzy column. */\n textSql: string;\n}\n\n/** Everything the generators need to render one collection's search column. */\nexport interface SearchColumnSpec {\n schema: string;\n table: string;\n /** The generated `tsvector` column. */\n column: string;\n language: string;\n unaccent: boolean;\n fields: ResolvedSearchField[];\n /** Body of `GENERATED ALWAYS AS ( … ) STORED` for the tsvector column. */\n expression: string;\n indexName: string;\n /** Extensions that must exist before the column can be created. */\n extensions: string[];\n fuzzy?: {\n column: string;\n expression: string;\n indexName: string;\n threshold: number;\n };\n}\n\n/** Raised when a `search` block names something that cannot be searched. */\nexport class SearchConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SearchConfigError\";\n }\n}\n\n/** The `search` block of a collection, or undefined when it has none. */\nexport const getSearchConfig = (collection: CollectionConfig): SearchConfig | undefined =>\n isPostgresCollectionConfig(collection) ? collection.search : undefined;\n\n/**\n * Refuse a `search` block on a collection this engine does not store.\n *\n * The type only permits one on a `PostgresCollectionConfig`, so TypeScript\n * already stops the ordinary case. This catches the rest — a JS config, a cast,\n * a collection whose `engine` was changed after the block was written — because\n * the alternative is the exact failure the block exists to prevent: a developer\n * who declared what to index, saw no error, and got the substring fallback.\n *\n * Called with *every* collection, before the Postgres ones are filtered out.\n */\nexport const assertSearchIsPostgresOnly = (collections: CollectionConfig[]): void => {\n for (const collection of collections) {\n if (isPostgresCollectionConfig(collection)) continue;\n if (!(collection as { search?: unknown }).search) continue;\n const engine = (collection as { engine?: string }).engine ?? \"non-postgres\";\n throw new SearchConfigError(\n `${collection.slug}.search: full-text search is a Postgres feature, and this collection is served by \\`${engine}\\`. ` +\n \"Remove the block — it would otherwise look configured while `.search()` kept using the default substring match.\"\n );\n }\n};\n\nconst columnNameOf = (propName: string, prop?: Property | null): string =>\n prop && \"columnName\" in prop && typeof prop.columnName === \"string\" ? prop.columnName : toSnakeCase(propName);\n\n/**\n * Classify a property for search purposes.\n *\n * Deliberately narrower than `getSqlColumnType`: search only cares whether a\n * value reaches text, and the mapping from property to *physical* type is\n * asserted against `getSqlColumnType` in the contract test rather than\n * duplicated here.\n *\n * Returns null for anything that is not text-bearing, which the caller turns\n * into a boot error naming the property.\n */\nconst classify = (prop: Property): { kind: FieldKind; reason?: string } | null => {\n switch (prop.type) {\n case \"string\": {\n const sp = prop as StringProperty;\n if (sp.enum) {\n return { kind: \"text\", reason: \"enum\" };\n }\n if (sp.isId === \"uuid\" || sp.columnType === \"uuid\") {\n return { kind: \"text\", reason: \"uuid\" };\n }\n return { kind: \"text\" };\n }\n case \"map\": {\n const mp = prop as MapProperty;\n // A `json` column is not `jsonb`, and the cast between them is not\n // immutable. Declaring `columnType: \"json\"` puts the value out of\n // reach of a generated column.\n if (mp.columnType === \"json\") return { kind: \"jsonb\", reason: \"json\" };\n return { kind: \"jsonb\" };\n }\n case \"array\": {\n const ap = prop as ArrayProperty;\n let colType = ap.columnType;\n if (!colType && ap.of && !Array.isArray(ap.of)) {\n const of = ap.of as Property;\n if (of.type === \"string\") colType = \"text[]\";\n else if (of.type === \"number\") colType = of.validation?.integer ? \"integer[]\" : \"numeric[]\";\n else if (of.type === \"boolean\") colType = \"boolean[]\";\n }\n if (colType === \"text[]\") return { kind: \"text_array\" };\n if (colType === \"json\") return { kind: \"jsonb\", reason: \"json\" };\n if (colType === \"integer[]\" || colType === \"boolean[]\" || colType === \"numeric[]\") {\n return { kind: \"text_array\", reason: \"non_text_array\" };\n }\n // Everything else lands in JSONB, which the JSON extractor handles.\n return { kind: \"jsonb\" };\n }\n default:\n return null;\n }\n};\n\nconst normalize = (inner: string, unaccent: boolean): string =>\n unaccent ? `${SEARCH_UNACCENT_FN}(${inner})` : inner;\n\n/** SQL reading one field as plain text, before normalization. */\nconst rawTextSql = (field: { column: string; jsonPath: string[]; kind: FieldKind }): string => {\n const col = `\"${field.column}\"`;\n if (field.kind === \"text\") return `coalesce(${col}, '')`;\n if (field.kind === \"text_array\") return `${SEARCH_TEXT_FN}(coalesce(${col}, '{}'::text[]))`;\n // JSONB, optionally addressed at a path inside the document.\n const target = field.jsonPath.length === 0\n ? col\n : field.jsonPath.length === 1\n ? `${col} -> ${quote(field.jsonPath[0])}`\n : `${col} #> ${quote(`{${field.jsonPath.join(\",\")}}`)}`;\n return `${SEARCH_TEXT_FN}(coalesce(${target}, '{}'::jsonb))`;\n};\n\nconst quote = (v: string): string => `'${v.replace(/'/g, \"''\")}'`;\n\n/**\n * Resolve and validate one declared field path.\n *\n * A path that does not resolve throws. The whole point of an explicit block is\n * that the author knows what is indexed; a silently dropped field would make it\n * a guess again, and the failure — a search that returns nothing for content\n * that is plainly in the row — is invisible from the outside.\n */\nconst resolveField = (\n entry: string | SearchField,\n collection: CollectionConfig,\n cfg: SearchConfig\n): ResolvedSearchField => {\n const path = typeof entry === \"string\" ? entry : entry.path;\n const weight = (typeof entry === \"string\" ? undefined : entry.weight) ?? DEFAULT_SEARCH_WEIGHT;\n const where = `${collection.slug}.search`;\n\n if (!path || typeof path !== \"string\") {\n throw new SearchConfigError(`${where}: every entry in \\`fields\\` needs a property path.`);\n }\n\n const [head, ...rest] = path.split(\".\");\n const prop = collection.properties?.[head] as Property | undefined;\n if (!prop) {\n const known = Object.keys(collection.properties ?? {}).join(\", \");\n throw new SearchConfigError(\n `${where}: \"${path}\" starts at property \"${head}\", which this collection does not declare. Known properties: ${known}.`\n );\n }\n\n const classified = classify(prop);\n if (!classified) {\n throw new SearchConfigError(\n `${where}: \"${path}\" is a \\`${prop.type}\\` property, which holds no text to search. ` +\n `Searchable kinds are \\`string\\`, \\`string[]\\` and \\`map\\` (or a path inside one).`\n );\n }\n if (classified.reason === \"enum\") {\n throw new SearchConfigError(\n `${where}: \"${path}\" is an enum. Enums are a fixed vocabulary — filter on them with \\`where\\` instead, which is exact and uses an index.`\n );\n }\n if (classified.reason === \"uuid\") {\n throw new SearchConfigError(\n `${where}: \"${path}\" is a UUID column. Look it up by id rather than searching it.`\n );\n }\n if (classified.reason === \"json\") {\n throw new SearchConfigError(\n `${where}: \"${path}\" is a \\`json\\` column, and the cast from \\`json\\` to \\`jsonb\\` is not immutable, so it cannot feed a generated column. Declare the property as \\`jsonb\\` (the default) to search it.`\n );\n }\n if (classified.reason === \"non_text_array\") {\n throw new SearchConfigError(\n `${where}: \"${path}\" is an array of numbers or booleans. Only \\`string[]\\` carries text to search.`\n );\n }\n\n if (rest.length > 0 && classified.kind !== \"jsonb\") {\n throw new SearchConfigError(\n `${where}: \"${path}\" addresses a path inside \"${head}\", but \"${head}\" is a \\`${prop.type}\\` property, not a \\`map\\`. Only map properties have paths inside them.`\n );\n }\n\n const column = columnNameOf(head, prop);\n const field = { column, jsonPath: rest, kind: classified.kind };\n const textSql = normalize(rawTextSql(field), cfg.unaccent === true);\n const language = cfg.language ?? DEFAULT_SEARCH_LANGUAGE;\n\n return {\n path,\n column,\n jsonPath: rest,\n kind: classified.kind,\n weight,\n sql: `setweight(to_tsvector(${quote(language)}, ${textSql}), ${quote(weight)})`,\n textSql\n };\n};\n\n/**\n * Build the full spec for a collection, or undefined when it has not opted in.\n *\n * Throws {@link SearchConfigError} on a config that cannot be honoured. Callers\n * at boot surface that as a startup failure — a search block that half-works is\n * worse than one that refuses.\n */\nexport const buildSearchColumnSpec = (collection: CollectionConfig): SearchColumnSpec | undefined => {\n const cfg = getSearchConfig(collection);\n if (!cfg) return undefined;\n\n if (!Array.isArray(cfg.fields) || cfg.fields.length === 0) {\n throw new SearchConfigError(\n `${collection.slug}.search: \\`fields\\` is empty. Name the properties to index, or remove the \\`search\\` block to keep the default ILIKE behaviour.`\n );\n }\n\n const table = getTableName(collection);\n const schema = isPostgresCollectionConfig(collection) && collection.schema ? collection.schema : \"public\";\n const column = cfg.column ?? DEFAULT_SEARCH_COLUMN;\n\n if (collection.properties?.[column]) {\n throw new SearchConfigError(\n `${collection.slug}.search: the generated column \"${column}\" collides with a declared property of the same name. Set \\`search.column\\` to something else.`\n );\n }\n\n const fields = cfg.fields.map(entry => resolveField(entry, collection, cfg));\n\n const seen = new Set<string>();\n for (const f of fields) {\n if (seen.has(f.path)) {\n throw new SearchConfigError(`${collection.slug}.search: \"${f.path}\" is listed twice.`);\n }\n seen.add(f.path);\n }\n\n const extensions: string[] = [];\n if (cfg.unaccent) extensions.push(\"unaccent\");\n if (cfg.fuzzy) extensions.push(\"pg_trgm\");\n\n const spec: SearchColumnSpec = {\n schema,\n table,\n column,\n language: cfg.language ?? DEFAULT_SEARCH_LANGUAGE,\n unaccent: cfg.unaccent === true,\n fields,\n expression: fields.map(f => f.sql).join(\" || \"),\n indexName: toPostgresIdentifier(`${table}_${column}_gin`),\n extensions\n };\n\n if (cfg.fuzzy) {\n const fuzzyColumn = `${column}_text`;\n if (collection.properties?.[fuzzyColumn]) {\n throw new SearchConfigError(\n `${collection.slug}.search: \\`fuzzy\\` needs the column \"${fuzzyColumn}\", which collides with a declared property. Set \\`search.column\\` to something else.`\n );\n }\n spec.fuzzy = {\n column: fuzzyColumn,\n // Concatenated with spaces so a trigram never spans two fields.\n expression: fields.map(f => f.textSql).join(\" || ' ' || \"),\n indexName: toPostgresIdentifier(`${table}_${fuzzyColumn}_trgm`),\n threshold: cfg.fuzzyThreshold ?? DEFAULT_FUZZY_THRESHOLD\n };\n }\n\n return spec;\n};\n\n/**\n * The IMMUTABLE wrappers the generated expressions call.\n *\n * `CREATE OR REPLACE` so a boot against an existing database is a no-op rather\n * than an error, and idempotent for the same reason every other boot-time DDL\n * statement here is.\n *\n * The bodies are stable built-ins wrapped in an immutable promise — see the\n * module comment for why that promise is sound. `STRICT` matters: it makes NULL\n * in mean NULL out without executing the body, which is what the `coalesce` at\n * each call site then absorbs.\n */\nexport const searchHelperFunctions = (spec: SearchColumnSpec): string[] => {\n const statements: string[] = [\n // text[] → \" \"-joined text.\n `CREATE OR REPLACE FUNCTION ${SEARCH_TEXT_FN}(text[]) RETURNS text\\n` +\n ` LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE AS\\n` +\n ` $$ SELECT array_to_string($1, ' ') $$;`,\n // jsonb → every string value at or below the node, space-joined. Keys\n // are not values: indexing them would make `certifications` itself a\n // search term on every row that has the field at all.\n `CREATE OR REPLACE FUNCTION ${SEARCH_TEXT_FN}(jsonb) RETURNS text\\n` +\n ` LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE AS\\n` +\n ` $$ SELECT coalesce(string_agg(v, ' '), '')\\n` +\n ` FROM jsonb_array_elements_text(jsonb_path_query_array($1, 'strict $.**?(@.type() == \"string\")')) AS v $$;`\n ];\n if (spec.unaccent) {\n // The two-argument form with an explicit dictionary is the one that can\n // honestly be called immutable: the single-argument form resolves the\n // dictionary through the current search_path at call time.\n statements.push(\n `CREATE OR REPLACE FUNCTION ${SEARCH_UNACCENT_FN}(text) RETURNS text\\n` +\n ` LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE AS\\n` +\n ` $$ SELECT ${HELPER_SCHEMA}.unaccent('${HELPER_SCHEMA}.unaccent'::regdictionary, $1) $$;`\n );\n }\n return statements;\n};\n\n/**\n * `CREATE EXTENSION` statements the spec's expressions depend on.\n *\n * `WITH SCHEMA public` is load-bearing, not tidiness. An unqualified\n * `CREATE EXTENSION` installs into the first schema on `search_path`, which\n * defaults to `\"$user\", public` — and the scaffold's database role is named\n * `rebase`, the same as the schema the generator creates one statement earlier.\n * So the moment that schema exists, `CREATE EXTENSION unaccent` puts the\n * dictionary in `rebase`, and every reference to `public.unaccent` below fails\n * with \"text search dictionary does not exist\". Observed, not theorised.\n */\nexport const searchExtensionStatements = (spec: SearchColumnSpec): string[] =>\n spec.extensions.map(e => `CREATE EXTENSION IF NOT EXISTS ${e} WITH SCHEMA ${HELPER_SCHEMA};`);\n\n/** The column definition as it appears inside `CREATE TABLE`. */\nexport const searchColumnDefinition = (spec: SearchColumnSpec): string =>\n `\"${spec.column}\" tsvector GENERATED ALWAYS AS (${spec.expression}) STORED`;\n\n/** The fuzzy column definition, when the spec asks for one. */\nexport const fuzzyColumnDefinition = (spec: SearchColumnSpec): string | undefined =>\n spec.fuzzy ? `\"${spec.fuzzy.column}\" text GENERATED ALWAYS AS (${spec.fuzzy.expression}) STORED` : undefined;\n\n/**\n * Index statements for the spec.\n *\n * `CONCURRENTLY` is deliberately *not* used here. This form is emitted into a\n * SQL file replayed as one unit — a migration, or `search.sql` — where a\n * concurrent build is not allowed. The boot-time ensure path runs statement by\n * statement against tables that are live and populated, and uses the\n * concurrent form instead; see `ensureSearchColumns`.\n */\nexport const searchIndexStatements = (spec: SearchColumnSpec): string[] => {\n const statements = [\n `CREATE INDEX IF NOT EXISTS \"${spec.indexName}\" ON \"${spec.schema}\".\"${spec.table}\" USING GIN (\"${spec.column}\");`\n ];\n if (spec.fuzzy) {\n statements.push(\n // The operator class is resolved through `search_path` like any\n // other object, so it is qualified for the same reason the\n // extension is installed explicitly.\n `CREATE INDEX IF NOT EXISTS \"${spec.fuzzy.indexName}\" ON \"${spec.schema}\".\"${spec.table}\" USING GIN (\"${spec.fuzzy.column}\" ${HELPER_SCHEMA}.gin_trgm_ops);`\n );\n }\n return statements;\n};\n\n// ── Telling a changed `search` block from an unchanged one ──────────────────\n\n/**\n * Marker on the comment of every generated search column this module creates.\n *\n * Versioned because the fingerprint below is only comparable against itself: a\n * future change to how it is computed has to read as \"not stamped by this\n * version\" rather than as drift on every existing column.\n */\nexport const SEARCH_STAMP_PREFIX = \"rebase:search:v1:\";\n\n/**\n * A stable fingerprint of one generated column's expression.\n *\n * Why a stamp rather than reading the expression back: Postgres stores a\n * generated column's expression *parsed*, and hands it back deparsed — casts\n * made explicit, identifiers requoted, schema qualifications added or dropped\n * according to `search_path`. Comparing that text to the text we generated\n * would report drift on wording, and this comparison decides whether a boot\n * refuses, so a false positive is an outage. The stamp is written by the same\n * code that writes the column, so equality means what it says.\n */\nexport const searchExpressionFingerprint = (expression: string): string =>\n `${SEARCH_STAMP_PREFIX}${createHash(\"sha256\").update(expression).digest(\"hex\").slice(0, 16)}`;\n\n/** One generated column, with the fingerprint that identifies its expression. */\nexport interface SearchColumnStamp {\n column: string;\n /** The expression the column is generated from. */\n expression: string;\n fingerprint: string;\n /** `COMMENT ON COLUMN …`, which is where the fingerprint is recorded. */\n sql: string;\n}\n\n/**\n * The stamps for a spec's generated columns — one per column, never shared.\n *\n * Per column on purpose: turning `fuzzy` on adds a second column and changes\n * nothing about the first, and a spec-wide fingerprint would report the\n * untouched `tsvector` column as drifted and refuse a boot over a change that\n * is purely additive.\n */\nexport const searchColumnStamps = (spec: SearchColumnSpec): SearchColumnStamp[] => {\n const stamp = (column: string, expression: string): SearchColumnStamp => {\n const fingerprint = searchExpressionFingerprint(expression);\n return {\n column,\n expression,\n fingerprint,\n sql: `COMMENT ON COLUMN \"${spec.schema}\".\"${spec.table}\".\"${column}\" IS ${quote(fingerprint)};`\n };\n };\n const stamps = [stamp(spec.column, spec.expression)];\n if (spec.fuzzy) stamps.push(stamp(spec.fuzzy.column, spec.fuzzy.expression));\n return stamps;\n};\n\n/**\n * The same drift check as the boot ensure, for the SQL file.\n *\n * Needed because {@link searchColumnStamps} would otherwise *launder* drift on\n * the migration path: `ADD COLUMN IF NOT EXISTS` does nothing to a column that\n * exists, so a re-generated `search.sql` would stamp a stale column with the\n * new block's fingerprint and the next boot would find them in agreement.\n * Guarding first means the file refuses instead — `rebase db push` is attended,\n * and the operator reading the failure is the person who changed the block.\n */\nexport const searchStampGuards = (spec: SearchColumnSpec): string[] =>\n searchColumnStamps(spec).map(stamp => {\n const relation = quote(`\"${spec.schema}\".\"${spec.table}\"`);\n return `DO $rebase_search$\nDECLARE recorded text;\nBEGIN\n SELECT col_description(a.attrelid, a.attnum) INTO recorded\n FROM pg_attribute a\n WHERE a.attrelid = ${relation}::regclass AND a.attname = ${quote(stamp.column)} AND NOT a.attisdropped;\n IF recorded LIKE ${quote(`${SEARCH_STAMP_PREFIX}%`)} AND recorded <> ${quote(stamp.fingerprint)} THEN\n RAISE EXCEPTION 'Rebase: the search block for ${spec.schema}.${spec.table} changed after the generated column \"${stamp.column}\" was built (recorded %, expected ${stamp.fingerprint}). Postgres cannot alter a generated expression in place. Drop the column and re-apply this file — it rewrites the table and rebuilds the index: ALTER TABLE ${relation.slice(1, -1)} DROP COLUMN \"${stamp.column}\";', recorded;\n END IF;\nEND\n$rebase_search$;`;\n });\n\n/**\n * The index names the spec creates.\n *\n * Needed by name, not just by statement, so Atlas can be told to exclude them\n * from its diff — see `searchExcludePatterns`.\n */\nexport const searchIndexNames = (spec: SearchColumnSpec): string[] =>\n spec.fuzzy ? [spec.indexName, spec.fuzzy.indexName] : [spec.indexName];\n\n// ── Keeping the generated columns out of responses ──────────────────────────\n\n/**\n * The generated column names a collection's search block adds, if any.\n *\n * These are physical columns on the table, so `SELECT *` returns them. They are\n * an index in column form — a list of lexeme positions, or a concatenation of\n * every searchable field on the row — and nothing outside the query planner has\n * any use for them. Left in, every list response carries a second, larger copy\n * of the row's text.\n */\nexport const searchColumnNames = (collection: CollectionConfig): string[] => {\n let spec: SearchColumnSpec | undefined;\n try {\n spec = buildSearchColumnSpec(collection);\n } catch {\n // A malformed block is reported at boot, loudly. A read is the wrong\n // place to raise it a second time, and returning the row without the\n // exclusion would be worse than returning it with.\n return [];\n }\n if (!spec) return [];\n return spec.fuzzy ? [spec.column, spec.fuzzy.column] : [spec.column];\n};\n\n/**\n * True for a column whose type only ever holds a search index.\n *\n * Independent of any collection config on purpose: an introspected database\n * (BaaS mode) can carry a `tsvector` column this framework never created —\n * Pagila's `film.fulltext` is the canonical one — and it should not be returned\n * to callers either. `isDerivedIndexColumn` already keeps such a column out of\n * the *properties*; this keeps it out of the *rows*.\n */\nexport const isSearchIndexColumn = (column: { getSQLType?: () => string }): boolean => {\n const sqlType = typeof column?.getSQLType === \"function\" ? column.getSQLType().toLowerCase() : \"\";\n return sqlType === \"tsvector\" || sqlType === \"tsquery\";\n};\n\n/**\n * A drizzle select projection over `table` with the search columns dropped.\n *\n * Returns undefined when nothing needs dropping, so the common case keeps using\n * a plain `select()` and this stays invisible in the generated SQL.\n */\nexport const visibleColumnProjection = (\n tableColumns: Record<string, { getSQLType?: () => string }> | undefined,\n collection?: CollectionConfig\n): Record<string, unknown> | undefined => {\n const excluded = excludedColumnNames(tableColumns, collection);\n if (!tableColumns || excluded.length === 0) return undefined;\n const projection: Record<string, unknown> = {};\n for (const [name, column] of Object.entries(tableColumns)) {\n if (!excluded.includes(name)) projection[name] = column;\n }\n return projection;\n};\n\n/** The same exclusion as a drizzle `db.query` `columns` denylist. */\nexport const hiddenColumnsOption = (\n tableColumns: Record<string, { getSQLType?: () => string }> | undefined,\n collection?: CollectionConfig\n): Record<string, false> | undefined => {\n const excluded = excludedColumnNames(tableColumns, collection);\n if (excluded.length === 0) return undefined;\n return Object.fromEntries(excluded.map(name => [name, false as const]));\n};\n\n/**\n * The columns to keep out of a response, by name.\n *\n * `tableColumns` is whatever `getTableColumns` returned, which is `undefined`\n * for anything that is not a real drizzle table — a stub in a test, a derived\n * or nested path with no table behind it. Nothing to exclude is the right\n * answer there, and it has to be an answer rather than a throw: this runs on\n * the read path of every collection, opted in or not.\n */\nconst excludedColumnNames = (\n tableColumns: Record<string, { getSQLType?: () => string }> | undefined,\n collection?: CollectionConfig\n): string[] => {\n if (!tableColumns || typeof tableColumns !== \"object\") return [];\n const byName = new Set(collection ? searchColumnNames(collection) : []);\n return Object.keys(tableColumns).filter(\n name => byName.has(name) || isSearchIndexColumn(tableColumns[name])\n );\n};\n","/**\n * The one description of what an auth user table's columns must be.\n *\n * ## Why this exists\n *\n * Three different code paths create `rebase.users`, and before this module they\n * disagreed about it:\n *\n * | column | `db push` (generator) | `ensureAuthTablesExist` | `ensureCollectionTables` |\n * |------------------|-----------------------|-------------------------|--------------------------|\n * | `email` | `TEXT UNIQUE NOT NULL`| `TEXT NOT NULL` + CHECK | `TEXT` (nullable) |\n * | `roles` | `TEXT[]` | `NOT NULL DEFAULT '{}'` | nullable, no default |\n * | `email_verified` | `BOOLEAN` | `NOT NULL DEFAULT FALSE`| nullable |\n * | `created_at` | `DEFAULT now()` | `NOT NULL DEFAULT NOW()`| no default |\n *\n * They are all `CREATE TABLE IF NOT EXISTS` / `ADD COLUMN IF NOT EXISTS`, so\n * whichever ran first decided the table and the other two silently no-op'd.\n * Boot order therefore chose the constraints: a managed deploy (collection\n * tables first) got a users table whose `email` was nullable and whose\n * `email_verified` had no default, while the same project pushed from a\n * checkout got the strict one. In the same table, `is_anonymous` came out\n * `NOT NULL DEFAULT false` — because *that* column existed in only one of the\n * three lists, so its owner's definition won by default.\n *\n * A second consequence was drift in the other direction. The scaffold's\n * `users.ts` describes 12 columns; auth needs 14. `db push` is declarative and\n * builds its desired state from the collection alone, so the two columns only\n * auth knows about (`is_anonymous`, `tokens_valid_after`) read as unmanaged\n * drift, and a push run after the server had booted once planned to DROP them.\n *\n * Both problems are the same problem: no single place said what this table is.\n * This is that place. Every creator asks here first and only then falls back to\n * the collection's own property definitions, so a column auth owns has one\n * definition regardless of who gets there first, and a column the developer\n * added to their users collection still behaves like any other field.\n *\n * ## What belongs here\n *\n * Only columns the auth services read or write. A developer's own additions to\n * their users collection (`bio`, `stripe_customer_id`) are ordinary columns and\n * must NOT be listed — they are generated from the collection like every other\n * field, and listing them here would freeze a user's schema.\n *\n * `id` is deliberately absent: its type comes from the collection's id property\n * (uuid / increment / text) and each creator already derives it.\n *\n * Keep in step with {@link AUTH_SCHEMA_VERSION} when a change here makes an\n * older runtime unable to work against a migrated table.\n */\n\n/**\n * A column auth owns.\n *\n * Structured rather than one SQL string because the same facts are needed in\n * three grammars — a `CREATE TABLE` column list, an `ADD COLUMN IF NOT EXISTS`,\n * and a pair of `ALTER COLUMN … SET DEFAULT` / `SET NOT NULL` reconciles for a\n * table that already exists with the wrong shape. Parsing a string back apart\n * for the third of those is how the copies drifted in the first place.\n */\nexport interface AuthUsersColumn {\n /** Physical column name. */\n column: string;\n /** Postgres type. */\n type: string;\n /** Default expression, verbatim, or absent for no default. */\n default?: string;\n /** Whether the column is NOT NULL. */\n notNull?: boolean;\n}\n\n/**\n * `email` is NOT NULL on purpose, and the anonymous sign-in route depends on it\n * — it synthesizes `anon_<32 hex>@anonymous.local` rather than inserting NULL.\n * The 320-char bound (RFC 5321) is a CHECK rather than a `VARCHAR(n)`, added\n * separately by `ensureAuthTablesExist` so it can be `NOT VALID` on an adopted\n * table that already holds a longer row.\n */\nexport const AUTH_USERS_COLUMNS: readonly AuthUsersColumn[] = [\n { column: \"email\", type: \"TEXT\", notNull: true },\n { column: \"display_name\", type: \"TEXT\" },\n { column: \"photo_url\", type: \"TEXT\" },\n { column: \"roles\", type: \"TEXT[]\", default: \"'{}'\", notNull: true },\n { column: \"password_hash\", type: \"TEXT\" },\n { column: \"email_verified\", type: \"BOOLEAN\", default: \"FALSE\", notNull: true },\n { column: \"email_verification_token\", type: \"TEXT\" },\n { column: \"email_verification_sent_at\", type: \"TIMESTAMP WITH TIME ZONE\" },\n { column: \"is_anonymous\", type: \"BOOLEAN\", default: \"FALSE\", notNull: true },\n { column: \"metadata\", type: \"JSONB\", default: \"'{}'\", notNull: true },\n { column: \"tokens_valid_after\", type: \"TIMESTAMP WITH TIME ZONE\" },\n { column: \"created_at\", type: \"TIMESTAMP WITH TIME ZONE\", default: \"NOW()\", notNull: true },\n { column: \"updated_at\", type: \"TIMESTAMP WITH TIME ZONE\", default: \"NOW()\", notNull: true }\n];\n\nconst BY_COLUMN = new Map(AUTH_USERS_COLUMNS.map(c => [c.column, c]));\n\n/** Type + inline constraints, as they appear after the column name. */\nexport function authUsersColumnSql(spec: AuthUsersColumn): string {\n return [\n spec.type,\n spec.default !== undefined ? `DEFAULT ${spec.default}` : \"\",\n spec.notNull ? \"NOT NULL\" : \"\"\n ].filter(Boolean).join(\" \");\n}\n\n/**\n * The auth-owned definition for a physical column name, or `undefined` when\n * auth does not own it.\n *\n * Callers pass the RESOLVED column name (after `columnName` mapping), because\n * that is the only name the three creators agree on: the scaffold's users\n * collection spells the property `displayName` and the column `display_name`.\n */\nexport function authUsersColumnDefinition(column: string): string | undefined {\n const spec = BY_COLUMN.get(column);\n return spec ? authUsersColumnSql(spec) : undefined;\n}\n\n/**\n * Whether a collection is an auth collection, i.e. whether the definitions in\n * this module apply to its table at all.\n *\n * Duplicated in shape from `@rebasepro/common`'s policy defaults on purpose:\n * that one takes a `CollectionConfig`, this one is called from DDL code paths\n * that hold looser objects, and both spellings must accept `auth: true` as well\n * as `auth: { enabled: true }`.\n */\nexport function isAuthCollection(collection: unknown): boolean {\n const auth = (collection as { auth?: unknown } | undefined)?.auth;\n if (auth === true) return true;\n return typeof auth === \"object\" && auth !== null && (auth as { enabled?: unknown }).enabled === true;\n}\n"],"x_google_ignoreList":[5,24,27],"mappings":";;;;;;;;;;;AAoKA,IAAa,iBAAb,MAA4B;CAExB,SAAkB;;;;CAIlB;;;;;CAKA;;;;;CAMA;CAEA,YAAY,IAAqB,MAAc,MAAgC;EAC3E,KAAK,KAAK;EACV,KAAK,OAAO;EACZ,KAAK,OAAO;CAChB;CAEA,IAAI,aAAa;EACb,OAAO,GAAG,KAAK,KAAK,GAAG,KAAK;CAChC;CAEA,oBAAoB;EAChB,OAAO;CACX;CAEA,mBAAmB;EACf,OAAO;CACX;AACJ;AAmBA,IAAa,SAAb,MAAoB;CAChB;CAEA,YAAY,OAAiB;EACzB,KAAK,QAAQ;CACjB;AACJ;;;;AEsHA,SAAgB,sBAAsB,UAAoE;CACtG,OAAO,SAAS,SAAS,YAAY,SAAS,SAAS;AAC3D;;AAGA,SAAgB,aAAa,UAA4D;CACrF,OAAO,SAAS,SAAS;AAC7B;;;AC9VA,IAAa,sBAAsB;AACnC,IAAa,uBAAuB;ACUpC,IAAM,iBAAiB;AAEvB,IAAa,eAAe,QAAiB;CACzC,IAAI,CAAC,OAAO,OAAO,QAAQ,UAAU,OAAO;CAC5C,MAAM,mBAAmB,IAAI,MAAM,cAAc;CACjD,IAAI,CAAC,kBAAkB,OAAO;CAC9B,OAAO,iBACF,KAAI,MAAK,EAAE,YAAY,CAAC,CAAC,CACzB,KAAK,GAAG;AACjB;AAEA,SAAgB,UAAU,KAAqB;CAC3C,IAAI,CAAC,KAAK,OAAO;CACjB,IAAI,IAAI,WAAW,GAAG,OAAO,IAAI,YAAY;CAG7C,MAAM,QAAQ,IAAI,MAAM,QAAQ,CAAC,CAAC,OAAO,OAAO;CAEhD,IAAI,MAAM,WAAW,GAAG,OAAO;CAG/B,OAAO,MAAM,EAAE,CAAC,YAAY,IAExB,MAAM,MAAM,CAAC,CAAC,CACT,KAAI,SAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAC3E,KAAK,EAAE;AACpB;;CCrCA,CAAC,SAAS,GAAE;EAAC,IAAI;EAAE,YAAU,OAAO,UAAQ,OAAO,UAAQ,EAAE,IAAE,cAAY,OAAO,UAAQ,OAAO,MAAI,OAAO,CAAC,KAAG,eAAa,OAAO,SAAO,IAAE,SAAO,eAAa,OAAO,SAAO,IAAE,SAAO,eAAa,OAAO,SAAO,IAAE,OAAM,EAAE,aAAW,EAAE;CAAE,EAAA,CAAE,WAAU;EAAC,OAAO,SAAS,EAAE,GAAE,GAAE,GAAE;GAAC,SAAS,EAAE,GAAE,GAAE;IAAC,IAAG,CAAC,EAAE,IAAG;KAAC,IAAG,CAAC,EAAE,IAAG;MAAC,IAAI,IAAE,cAAY,OAAA,aAAA;MAAwB,IAAG,CAAC,KAAG,GAAE,OAAO,EAAE,GAAE,CAAC,CAAC;MAAE,IAAG,GAAE,OAAO,EAAE,GAAE,CAAC,CAAC;MAAE,MAAM,IAAI,MAAM,yBAAuB,IAAE,GAAG;KAAC;KAAC,IAAE,EAAE,KAAG,EAAC,SAAQ,CAAC,EAAC;KAAE,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,SAAQ,SAAS,GAAE;MAAC,IAAI,IAAE,EAAE,EAAE,CAAC,EAAE,CAAC;MAAG,OAAO,EAAE,KAAG,CAAC;KAAC,GAAE,GAAE,EAAE,SAAQ,GAAE,GAAE,GAAE,CAAC;IAAC;IAAC,OAAO,EAAE,EAAE,CAAC;GAAO;GAAC,KAAI,IAAI,IAAE,cAAY,OAAA,aAAA,WAAwB,IAAE,GAAE,IAAE,EAAE,QAAO,KAAI,EAAE,EAAE,EAAE;GAAE,OAAO;EAAC,EAAE;GAAC,GAAE,CAAC,SAAS,GAAE,GAAE,GAAE;IAAC,CAAC,SAAS,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE;KAAC;KAAa,IAAI,IAAE,EAAE,QAAQ;KAAE,SAAS,EAAE,GAAE,GAAE;MAAC,IAAE,EAAE,GAAE,CAAC;MAAE,IAAI;MAAE,OAAO,KAAK,OAAK,IAAE,kBAAgB,EAAE,YAAU,EAAE,WAAW,EAAE,SAAS,IAAE,IAAI,EAAA,EAAA,CAAG,UAAQ,EAAE,QAAM,EAAE,QAAO,EAAE,MAAI,EAAE,SAAQ,EAAE,GAAE,CAAC,CAAC,CAAC,SAAS,CAAC,GAAE,EAAE,UAAQ,EAAE,IAAI,EAAE,GAAE,EAAE,SAAO,EAAE,OAAO,aAAW,EAAE,WAAS,KAAK,IAAE,EAAE,QAAQ,KAAG,IAAE,EAAE,KAAK,GAAE,aAAW,EAAE,WAAS,EAAE,SAAS,EAAE,QAAQ,IAAE;KAAE;KAAC,CAAC,IAAE,EAAE,UAAQ,EAAA,CAAG,OAAK,SAAS,GAAE;MAAC,OAAO,EAAE,CAAC;KAAC,GAAE,EAAE,OAAK,SAAS,GAAE;MAAC,OAAO,EAAE,GAAE;OAAC,eAAc,CAAC;OAAE,WAAU;OAAO,UAAS;MAAK,CAAC;KAAC,GAAE,EAAE,MAAI,SAAS,GAAE;MAAC,OAAO,EAAE,GAAE;OAAC,WAAU;OAAM,UAAS;MAAK,CAAC;KAAC,GAAE,EAAE,UAAQ,SAAS,GAAE;MAAC,OAAO,EAAE,GAAE;OAAC,WAAU;OAAM,UAAS;OAAM,eAAc,CAAC;MAAC,CAAC;KAAC;KAAE,IAAI,IAAE,EAAE,YAAU,EAAE,UAAU,CAAC,CAAC,MAAM,IAAE,CAAC,QAAO,KAAK,GAAE,KAAG,EAAE,KAAK,aAAa,GAAE;MAAC;MAAS;MAAM;MAAS;KAAQ;KAAG,SAAS,EAAE,GAAE,GAAE;MAAC,IAAI,IAAE,CAAC;MAAE,IAAG,EAAE,aAAW,IAAE,KAAG,CAAC,EAAA,CAAG,aAAW,QAAO,EAAE,WAAS,EAAE,YAAU,OAAM,EAAE,gBAAc,CAAC,CAAC,EAAE,eAAc,EAAE,YAAU,EAAE,UAAU,YAAY,GAAE,EAAE,WAAS,EAAE,SAAS,YAAY,GAAE,EAAE,gBAAc,CAAC,MAAI,EAAE,eAAc,EAAE,cAAY,CAAC,MAAI,EAAE,aAAY,EAAE,uBAAqB,CAAC,MAAI,EAAE,sBAAqB,EAAE,4BAA0B,CAAC,MAAI,EAAE,2BAA0B,EAAE,kBAAgB,CAAC,MAAI,EAAE,iBAAgB,EAAE,gBAAc,CAAC,MAAI,EAAE,eAAc,EAAE,mBAAiB,CAAC,MAAI,EAAE,kBAAiB,EAAE,WAAS,EAAE,YAAU,KAAK,GAAE,EAAE,cAAY,EAAE,eAAa,KAAK,GAAE,KAAK,MAAI,GAAE,MAAM,IAAI,MAAM,2BAA2B;MAAE,KAAI,IAAI,IAAE,GAAE,IAAE,EAAE,QAAO,EAAE,GAAE,EAAE,EAAE,CAAC,YAAY,MAAI,EAAE,UAAU,YAAY,MAAI,EAAE,YAAU,EAAE;MAAI,IAAG,OAAK,EAAE,QAAQ,EAAE,SAAS,GAAE,MAAM,IAAI,MAAM,iBAAc,EAAE,YAAU,0CAAuC,EAAE,KAAK,IAAI,CAAC;MAAE,IAAG,OAAK,EAAE,QAAQ,EAAE,QAAQ,KAAG,kBAAgB,EAAE,WAAU,MAAM,IAAI,MAAM,gBAAa,EAAE,WAAS,0CAAuC,EAAE,KAAK,IAAI,CAAC;MAAE,OAAO;KAAC;KAAC,SAAS,EAAE,GAAE;MAAC,IAAG,cAAY,OAAO,GAAE,OAAO,QAAM,wDAAwD,KAAK,SAAS,UAAU,SAAS,KAAK,CAAC,CAAC;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE;MAAC,IAAE,KAAG,CAAC;MAAE,SAAS,EAAE,GAAE;OAAC,OAAO,EAAE,SAAO,EAAE,OAAO,GAAE,MAAM,IAAE,EAAE,MAAM,GAAE,MAAM;MAAC;MAAC,OAAM;OAAC,UAAS,SAAS,GAAE;QAAC,OAAO,KAAK,OAAK,UAAQ,IAAE,EAAE,WAAS,EAAE,SAAS,CAAC,IAAE,KAAG,SAAO,OAAO,GAAG,CAAC,CAAC;OAAC;OAAE,SAAQ,SAAS,GAAE;QAAC,IAAI,GAAE,IAAE,OAAO,UAAU,SAAS,KAAK,CAAC,GAAE,IAAE,mBAAmB,KAAK,CAAC;QAAE,KAAG,IAAE,IAAE,EAAE,KAAG,cAAY,IAAE,IAAA,CAAK,YAAY;QAAE,IAAG,MAAI,IAAE,EAAE,QAAQ,CAAC,IAAG,OAAO,KAAK,SAAS,eAAa,IAAE,GAAG;QAAE,IAAG,EAAE,KAAK,CAAC,GAAE,KAAK,MAAI,KAAG,EAAE,YAAU,EAAE,SAAS,CAAC,GAAE,OAAO,EAAE,SAAS,GAAE,EAAE,CAAC;QAAE,IAAG,aAAW,KAAG,eAAa,KAAG,oBAAkB,GAAE,OAAO,IAAE,OAAO,KAAK,CAAC,GAAE,EAAE,qBAAmB,IAAE,EAAE,KAAK,IAAG,CAAC,MAAI,EAAE,eAAa,EAAE,CAAC,KAAG,EAAE,OAAO,GAAE,GAAE,aAAY,aAAY,aAAa,GAAE,EAAE,gBAAc,IAAE,EAAE,OAAO,SAAS,GAAE;SAAC,OAAM,CAAC,EAAE,YAAY,CAAC;QAAC,CAAC,IAAG,EAAE,YAAU,EAAE,SAAO,GAAG,GAAE,IAAE,MAAK,EAAE,QAAQ,SAAS,GAAE;SAAC,EAAE,SAAS,CAAC,GAAE,EAAE,GAAG,GAAE,EAAE,iBAAe,EAAE,SAAS,EAAE,EAAE,GAAE,EAAE,GAAG;QAAC,CAAC;QAAE,IAAG,CAAC,KAAK,MAAI,IAAG;SAAC,IAAG,EAAE,eAAc,OAAO,EAAE,MAAI,IAAE,GAAG;SAAE,MAAM,IAAI,MAAM,2BAAwB,IAAE,IAAG;QAAC;QAAC,KAAK,MAAI,EAAE,CAAC,CAAC;OAAC;OAAE,QAAO,SAAS,GAAE,GAAE;QAAC,IAAE,KAAK,MAAI,IAAE,IAAE,CAAC,MAAI,EAAE;QAAgB,IAAI,IAAE;QAAK,IAAG,EAAE,WAAS,EAAE,SAAO,GAAG,GAAE,CAAC,KAAG,EAAE,UAAQ,GAAE,OAAO,EAAE,QAAQ,SAAS,GAAE;SAAC,OAAO,EAAE,SAAS,CAAC;QAAC,CAAC;QAAE,IAAI,IAAE,CAAC,GAAE,IAAE,EAAE,IAAI,SAAS,GAAE;SAAC,IAAI,IAAE,IAAI,EAAA,GAAE,IAAE,EAAE,MAAM;SAAE,OAAO,EAAE,GAAE,GAAE,CAAC,CAAC,CAAC,SAAS,CAAC,GAAE,IAAE,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,GAAE,EAAE,KAAK,CAAC,CAAC,SAAS;QAAC,CAAC;QAAE,OAAO,IAAE,EAAE,OAAO,CAAC,GAAE,EAAE,KAAK,GAAE,KAAK,OAAO,GAAE,CAAC,CAAC;OAAC;OAAE,OAAM,SAAS,GAAE;QAAC,OAAO,EAAE,UAAQ,EAAE,OAAO,CAAC;OAAC;OAAE,SAAQ,SAAS,GAAE;QAAC,OAAO,EAAE,YAAU,EAAE,SAAS,CAAC;OAAC;OAAE,QAAO,SAAS,GAAE;QAAC,OAAO,EAAE,WAAS,EAAE,SAAS,CAAC;OAAC;OAAE,UAAS,SAAS,GAAE;QAAC,OAAO,EAAE,UAAQ,EAAE,SAAS,CAAC;OAAC;OAAE,SAAQ,SAAS,GAAE;QAAC,EAAE,YAAU,EAAE,SAAO,GAAG,GAAE,EAAE,EAAE,SAAS,CAAC;OAAC;OAAE,WAAU,SAAS,GAAE;QAAC,EAAE,KAAK,GAAE,EAAE,CAAC,IAAE,KAAK,SAAS,UAAU,IAAE,KAAK,SAAS,EAAE,SAAS,CAAC,GAAE,CAAC,MAAI,EAAE,wBAAsB,KAAK,SAAS,mBAAiB,OAAO,EAAE,IAAI,CAAC,GAAE,EAAE,6BAA2B,KAAK,QAAQ,CAAC;OAAC;OAAE,SAAQ,SAAS,GAAE;QAAC,OAAO,EAAE,YAAU,EAAE,SAAS,CAAC;OAAC;OAAE,MAAK,SAAS,GAAE;QAAC,OAAO,EAAE,SAAO,EAAE,SAAS,CAAC;OAAC;OAAE,OAAM,WAAU;QAAC,OAAO,EAAE,MAAM;OAAC;OAAE,YAAW,WAAU;QAAC,OAAO,EAAE,WAAW;OAAC;OAAE,SAAQ,SAAS,GAAE;QAAC,OAAO,EAAE,WAAS,EAAE,SAAS,CAAC;OAAC;OAAE,aAAY,SAAS,GAAE;QAAC,OAAO,EAAE,aAAa,GAAE,KAAK,SAAS,MAAM,UAAU,MAAM,KAAK,CAAC,CAAC;OAAC;OAAE,oBAAmB,SAAS,GAAE;QAAC,OAAO,EAAE,oBAAoB,GAAE,KAAK,SAAS,MAAM,UAAU,MAAM,KAAK,CAAC,CAAC;OAAC;OAAE,YAAW,SAAS,GAAE;QAAC,OAAO,EAAE,YAAY,GAAE,KAAK,SAAS,MAAM,UAAU,MAAM,KAAK,CAAC,CAAC;OAAC;OAAE,cAAa,SAAS,GAAE;QAAC,OAAO,EAAE,cAAc,GAAE,KAAK,SAAS,MAAM,UAAU,MAAM,KAAK,CAAC,CAAC;OAAC;OAAE,aAAY,SAAS,GAAE;QAAC,OAAO,EAAE,aAAa,GAAE,KAAK,SAAS,MAAM,UAAU,MAAM,KAAK,CAAC,CAAC;OAAC;OAAE,cAAa,SAAS,GAAE;QAAC,OAAO,EAAE,cAAc,GAAE,KAAK,SAAS,MAAM,UAAU,MAAM,KAAK,CAAC,CAAC;OAAC;OAAE,aAAY,SAAS,GAAE;QAAC,OAAO,EAAE,aAAa,GAAE,KAAK,SAAS,MAAM,UAAU,MAAM,KAAK,CAAC,CAAC;OAAC;OAAE,eAAc,SAAS,GAAE;QAAC,OAAO,EAAE,eAAe,GAAE,KAAK,SAAS,MAAM,UAAU,MAAM,KAAK,CAAC,CAAC;OAAC;OAAE,eAAc,SAAS,GAAE;QAAC,OAAO,EAAE,eAAe,GAAE,KAAK,SAAS,MAAM,UAAU,MAAM,KAAK,CAAC,CAAC;OAAC;OAAE,cAAa,SAAS,GAAE;QAAC,OAAO,EAAE,cAAc,GAAE,KAAK,SAAS,IAAI,WAAW,CAAC,CAAC;OAAC;OAAE,MAAK,SAAS,GAAE;QAAC,OAAO,EAAE,SAAO,EAAE,SAAS,CAAC;OAAC;OAAE,MAAK,SAAS,GAAE;QAAC,EAAE,MAAM;QAAE,IAAE,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,OAAO,GAAE,CAAC,MAAI,EAAE,aAAa;OAAC;OAAE,MAAK,SAAS,GAAE;QAAC,EAAE,MAAM;QAAE,IAAE,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,OAAO,GAAE,CAAC,MAAI,EAAE,aAAa;OAAC;OAAE,OAAM,SAAS,GAAE;QAAC,OAAO,EAAE,OAAO,GAAE,KAAK,SAAS;SAAC,EAAE;SAAK,EAAE;SAAK,EAAE;SAAK,EAAE;QAAW,CAAC;OAAC;OAAE,OAAM,WAAU;QAAC,IAAG,EAAE,eAAc,OAAO,EAAE,QAAQ;QAAE,MAAM,MAAM,iKAA6J;OAAC;OAAE,YAAW,WAAU;QAAC,OAAO,EAAE,WAAW;OAAC;OAAE,SAAQ,SAAS,GAAE;QAAC,OAAO,EAAE,YAAU,EAAE,SAAS,CAAC;OAAC;OAAE,UAAS,WAAU;QAAC,OAAO,EAAE,SAAS;OAAC;OAAE,QAAO,WAAU;QAAC,OAAO,EAAE,OAAO;OAAC;OAAE,OAAM,WAAU;QAAC,OAAO,EAAE,MAAM;OAAC;OAAE,MAAK,WAAU;QAAC,OAAO,EAAE,KAAK;OAAC;OAAE,MAAK,WAAU;QAAC,OAAO,EAAE,KAAK;OAAC;OAAE,MAAK,WAAU;QAAC,OAAO,EAAE,KAAK;OAAC;OAAE,cAAa,WAAU;QAAC,OAAO,EAAE,aAAa;OAAC;OAAE,gBAAe,WAAU;QAAC,OAAO,EAAE,eAAe;OAAC;OAAE,aAAY,WAAU;QAAC,OAAO,EAAE,YAAY;OAAC;OAAE,OAAM,WAAU;QAAC,OAAO,EAAE,MAAM;OAAC;OAAE,UAAS,WAAU;QAAC,OAAO,EAAE,SAAS;OAAC;OAAE,aAAY,WAAU;QAAC,OAAO,EAAE,YAAY;OAAC;OAAE,aAAY,WAAU;QAAC,OAAO,EAAE,YAAY;OAAC;OAAE,WAAU,WAAU;QAAC,OAAO,EAAE,UAAU;OAAC;OAAE,SAAQ,WAAU;QAAC,OAAO,EAAE,QAAQ;OAAC;OAAE,UAAS,WAAU;QAAC,OAAO,EAAE,SAAS;OAAC;OAAE,UAAS,WAAU;QAAC,OAAO,EAAE,SAAS;OAAC;MAAC;KAAC;KAAC,SAAS,IAAG;MAAC,OAAM;OAAC,KAAI;OAAG,OAAM,SAAS,GAAE;QAAC,KAAK,OAAK;OAAC;OAAE,KAAI,SAAS,GAAE;QAAC,KAAK,OAAK;OAAC;OAAE,MAAK,WAAU;QAAC,OAAO,KAAK;OAAG;MAAC;KAAC;KAAC,EAAE,gBAAc,SAAS,GAAE,GAAE,GAAE;MAAC,OAAO,KAAK,MAAI,MAAI,IAAE,GAAE,IAAE,CAAC,IAAG,EAAE,IAAE,EAAE,GAAE,CAAC,GAAE,CAAC,CAAC,CAAC,SAAS,CAAC;KAAC;IAAC,EAAA,CAAE,KAAK,MAAK,EAAE,QAAQ,GAAE,eAAa,OAAO,OAAK,OAAK,eAAa,OAAO,SAAO,SAAO,CAAC,GAAE,EAAE,QAAQ,CAAC,CAAC,QAAO,UAAU,IAAG,UAAU,IAAG,UAAU,IAAG,UAAU,IAAG,qBAAoB,GAAG;GAAC,GAAE;IAAC,QAAO;IAAE,QAAO;IAAE,QAAO;GAAE,CAAC;GAAE,GAAE,CAAC,SAAS,GAAE,GAAE,GAAE;IAAC,CAAC,SAAS,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE;KAAC,CAAC,SAAS,GAAE;MAAC;MAAa,IAAI,IAAE,eAAa,OAAO,aAAW,aAAW,OAAM,IAAE,IAAI,WAAW,CAAC,GAAE,IAAE,IAAI,WAAW,CAAC,GAAE,IAAE,IAAI,WAAW,CAAC,GAAE,IAAE,IAAI,WAAW,CAAC,GAAE,IAAE,IAAI,WAAW,CAAC,GAAE,IAAE,IAAI,WAAW,CAAC,GAAE,IAAE,IAAI,WAAW,CAAC;MAAE,SAAS,EAAE,GAAE;OAAC,IAAE,EAAE,WAAW,CAAC;OAAE,OAAO,MAAI,KAAG,MAAI,IAAE,KAAG,MAAI,KAAG,MAAI,IAAE,KAAG,IAAE,IAAE,KAAG,IAAE,IAAE,KAAG,IAAE,IAAE,KAAG,KAAG,IAAE,IAAE,KAAG,IAAE,IAAE,IAAE,IAAE,KAAG,IAAE,IAAE,KAAG,KAAK;MAAC;MAAC,EAAE,cAAY,SAAS,GAAE;OAAC,IAAI,GAAE;OAAE,IAAG,IAAE,EAAE,SAAO,GAAE,MAAM,IAAI,MAAM,gDAAgD;OAAE,IAAI,IAAE,EAAE,QAAO,IAAE,QAAM,EAAE,OAAO,IAAE,CAAC,IAAE,IAAE,QAAM,EAAE,OAAO,IAAE,CAAC,IAAE,IAAE,GAAE,IAAE,IAAI,EAAE,IAAE,EAAE,SAAO,IAAE,CAAC,GAAE,IAAE,IAAE,IAAE,EAAE,SAAO,IAAE,EAAE,QAAO,IAAE;OAAE,SAAS,EAAE,GAAE;QAAC,EAAE,OAAK;OAAC;OAAC,KAAI,IAAE,GAAE,IAAE,GAAE,KAAG,GAAI,GAAG,YAAU,IAAE,EAAE,EAAE,OAAO,CAAC,CAAC,KAAG,KAAG,EAAE,EAAE,OAAO,IAAE,CAAC,CAAC,KAAG,KAAG,EAAE,EAAE,OAAO,IAAE,CAAC,CAAC,KAAG,IAAE,EAAE,EAAE,OAAO,IAAE,CAAC,CAAC,OAAK,EAAE,GAAE,GAAG,QAAM,MAAI,CAAC,GAAE,EAAE,MAAI,CAAC;OAAE,OAAO,KAAG,IAAE,EAAE,OAAK,IAAE,EAAE,EAAE,OAAO,CAAC,CAAC,KAAG,IAAE,EAAE,EAAE,OAAO,IAAE,CAAC,CAAC,KAAG,EAAE,IAAE,KAAG,MAAI,GAAG,IAAE,EAAE,EAAE,OAAO,CAAC,CAAC,KAAG,KAAG,EAAE,EAAE,OAAO,IAAE,CAAC,CAAC,KAAG,IAAE,EAAE,EAAE,OAAO,IAAE,CAAC,CAAC,KAAG,MAAI,IAAE,GAAG,GAAE,EAAE,MAAI,CAAC,IAAG;MAAC,GAAE,EAAE,gBAAc,SAAS,GAAE;OAAC,IAAI,GAAE,GAAE,GAAE,GAAE,IAAE,EAAE,SAAO,GAAE,IAAE;OAAG,SAAS,EAAE,GAAE;QAAC,OAAM,mEAAmE,OAAO,CAAC;OAAC;OAAC,KAAI,IAAE,GAAE,IAAE,EAAE,SAAO,GAAE,IAAE,GAAE,KAAG,GAAE,KAAG,EAAE,MAAI,OAAK,EAAE,IAAE,MAAI,KAAG,EAAE,IAAE,IAAG,KAAG,GAAG,IAAE,MAAI,KAAG,EAAE,IAAE,EAAE,KAAG,KAAG,EAAE,IAAE,EAAE,KAAG,IAAE,EAAE,IAAE,EAAE,KAAG,CAAC;OAAE,QAAO,GAAP;QAAU,KAAK;SAAE,KAAG,KAAG,GAAG,IAAE,EAAE,EAAE,SAAO,OAAK,CAAC,KAAG,EAAE,KAAG,IAAE,EAAE,IAAE;SAAK;QAAM,KAAK,GAAE,KAAG,KAAG,KAAG,GAAG,KAAG,EAAE,EAAE,SAAO,MAAI,KAAG,EAAE,EAAE,SAAO,OAAK,EAAE,KAAG,EAAE,KAAG,IAAE,EAAE,KAAG,EAAE,KAAG,IAAE,EAAE,IAAE;OAAG;OAAC,OAAO;MAAC;KAAC,EAAA,CAAE,KAAK,MAAI,IAAE,KAAK,WAAS,CAAC,IAAE,CAAC;IAAC,EAAA,CAAE,KAAK,MAAK,EAAE,QAAQ,GAAE,eAAa,OAAO,OAAK,OAAK,eAAa,OAAO,SAAO,SAAO,CAAC,GAAE,EAAE,QAAQ,CAAC,CAAC,QAAO,UAAU,IAAG,UAAU,IAAG,UAAU,IAAG,UAAU,IAAG,mEAAkE,0DAA0D;GAAC,GAAE;IAAC,QAAO;IAAE,QAAO;GAAE,CAAC;GAAE,GAAE,CAAC,SAAS,GAAE,GAAE,GAAE;IAAC,CAAC,SAAS,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE;KAAC,IAAI,IAAE,EAAE,WAAW,GAAE,IAAE,EAAE,SAAS;KAAE,SAAS,EAAE,GAAE,GAAE,GAAE;MAAC,IAAG,EAAE,gBAAgB,IAAG,OAAO,IAAI,EAAE,GAAE,GAAE,CAAC;MAAE,IAAI,GAAE,GAAE,GAAE,GAAE,IAAE,OAAO;MAAE,IAAG,aAAW,KAAG,YAAU,GAAE,KAAI,KAAG,IAAE,EAAA,CAAG,OAAK,EAAE,KAAK,IAAE,EAAE,QAAQ,cAAa,EAAE,GAAE,EAAE,SAAO,KAAG,IAAG,KAAG;MAAI,IAAG,YAAU,GAAE,IAAE,EAAE,CAAC;WAAO,IAAG,YAAU,GAAE,IAAE,EAAE,WAAW,GAAE,CAAC;WAAM;OAAC,IAAG,YAAU,GAAE,MAAM,IAAI,MAAM,uDAAuD;OAAE,IAAE,EAAE,EAAE,MAAM;MAAC;MAAC,IAAG,EAAE,kBAAgB,IAAE,EAAE,SAAS,IAAI,WAAW,CAAC,CAAC,KAAG,CAAC,IAAE,KAAA,CAAM,SAAO,GAAE,EAAE,YAAU,CAAC,IAAG,EAAE,mBAAiB,YAAU,OAAO,EAAE,YAAW,EAAE,KAAK,CAAC;WAAO,IAAG,EAAE,IAAE,CAAC,KAAG,EAAE,SAAS,CAAC,KAAG,KAAG,YAAU,OAAO,KAAG,YAAU,OAAO,EAAE,QAAO,KAAI,IAAE,GAAE,IAAE,GAAE,KAAI,EAAE,SAAS,CAAC,IAAE,EAAE,KAAG,EAAE,UAAU,CAAC,IAAE,EAAE,KAAG,EAAE;WAAQ,IAAG,YAAU,GAAE,EAAE,MAAM,GAAE,GAAE,CAAC;WAAO,IAAG,YAAU,KAAG,CAAC,EAAE,mBAAiB,CAAC,GAAE,KAAI,IAAE,GAAE,IAAE,GAAE,KAAI,EAAE,KAAG;MAAE,OAAO;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE;MAAC,OAAO,EAAE,gBAAc,EAAE,SAAS,GAAE;OAAC,KAAI,IAAI,IAAE,CAAC,GAAE,IAAE,GAAE,IAAE,EAAE,QAAO,KAAI,EAAE,KAAK,MAAI,EAAE,WAAW,CAAC,CAAC;OAAE,OAAO;MAAC,EAAE,CAAC,GAAE,GAAE,GAAE,CAAC;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE;MAAC,OAAO,EAAE,gBAAc,EAAE,SAAS,GAAE;OAAC,KAAI,IAAI,GAAE,GAAE,IAAE,CAAC,GAAE,IAAE,GAAE,IAAE,EAAE,QAAO,KAAI,IAAE,EAAE,WAAW,CAAC,GAAE,IAAE,KAAG,GAAE,IAAE,IAAE,KAAI,EAAE,KAAK,CAAC,GAAE,EAAE,KAAK,CAAC;OAAE,OAAO;MAAC,EAAE,CAAC,GAAE,GAAE,GAAE,CAAC;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE;MAAC,IAAI,IAAE;MAAG,IAAE,KAAK,IAAI,EAAE,QAAO,CAAC;MAAE,KAAI,IAAI,IAAE,GAAE,IAAE,GAAE,KAAI,KAAG,OAAO,aAAa,EAAE,EAAE;MAAE,OAAO;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE;MAAC,MAAI,EAAE,aAAW,OAAO,GAAE,2BAA2B,GAAE,EAAE,QAAM,GAAE,gBAAgB,GAAE,EAAE,IAAE,IAAE,EAAE,QAAO,qCAAqC;MAAG,IAAI,GAAE,IAAE,EAAE;MAAO,IAAG,EAAE,KAAG,IAAG,OAAO,KAAG,IAAE,EAAE,IAAG,IAAE,IAAE,MAAI,KAAG,EAAE,IAAE,MAAI,OAAK,IAAE,EAAE,MAAI,GAAE,IAAE,IAAE,MAAI,KAAG,EAAE,IAAE,MAAK;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE;MAAC,MAAI,EAAE,aAAW,OAAO,GAAE,2BAA2B,GAAE,EAAE,QAAM,GAAE,gBAAgB,GAAE,EAAE,IAAE,IAAE,EAAE,QAAO,qCAAqC;MAAG,IAAI,GAAE,IAAE,EAAE;MAAO,IAAG,EAAE,KAAG,IAAG,OAAO,KAAG,IAAE,IAAE,MAAI,IAAE,EAAE,IAAE,MAAI,KAAI,IAAE,IAAE,MAAI,KAAG,EAAE,IAAE,MAAI,IAAG,KAAG,EAAE,IAAG,IAAE,IAAE,MAAI,KAAG,EAAE,IAAE,MAAI,OAAK,OAAK,IAAE,IAAE,MAAI,IAAE,EAAE,IAAE,MAAI,KAAI,IAAE,IAAE,MAAI,KAAG,EAAE,IAAE,MAAI,IAAG,IAAE,IAAE,MAAI,KAAG,EAAE,IAAE,KAAI,KAAG,EAAE,MAAI,OAAK,IAAG;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE;MAAC,IAAG,MAAI,EAAE,aAAW,OAAO,GAAE,2BAA2B,GAAE,EAAE,QAAM,GAAE,gBAAgB,GAAE,EAAE,IAAE,IAAE,EAAE,QAAO,qCAAqC,IAAG,EAAE,EAAE,UAAQ,IAAG,OAAO,IAAE,EAAE,GAAE,GAAE,GAAE,CAAC,CAAC,GAAE,QAAM,IAAE,MAAI,QAAM,IAAE,KAAG;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE;MAAC,IAAG,MAAI,EAAE,aAAW,OAAO,GAAE,2BAA2B,GAAE,EAAE,QAAM,GAAE,gBAAgB,GAAE,EAAE,IAAE,IAAE,EAAE,QAAO,qCAAqC,IAAG,EAAE,EAAE,UAAQ,IAAG,OAAO,IAAE,EAAE,GAAE,GAAE,GAAE,CAAC,CAAC,GAAE,aAAW,IAAE,MAAI,aAAW,IAAE,KAAG;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE;MAAC,OAAO,MAAI,EAAE,aAAW,OAAO,GAAE,2BAA2B,GAAE,EAAE,IAAE,IAAE,EAAE,QAAO,qCAAqC,IAAG,EAAE,KAAK,GAAE,GAAE,GAAE,IAAG,CAAC;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE;MAAC,OAAO,MAAI,EAAE,aAAW,OAAO,GAAE,2BAA2B,GAAE,EAAE,IAAE,IAAE,EAAE,QAAO,qCAAqC,IAAG,EAAE,KAAK,GAAE,GAAE,GAAE,IAAG,CAAC;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE,GAAE;MAAC,MAAI,EAAE,QAAM,GAAE,eAAe,GAAE,EAAE,aAAW,OAAO,GAAE,2BAA2B,GAAE,EAAE,QAAM,GAAE,gBAAgB,GAAE,EAAE,IAAE,IAAE,EAAE,QAAO,sCAAsC,GAAE,EAAE,GAAE,KAAK;MAAG,IAAE,EAAE;MAAO,IAAG,EAAE,KAAG,IAAG,KAAI,IAAI,IAAE,GAAE,IAAE,KAAK,IAAI,IAAE,GAAE,CAAC,GAAE,IAAE,GAAE,KAAI,EAAE,IAAE,MAAI,IAAE,OAAK,KAAG,IAAE,IAAE,IAAE,QAAM,KAAG,IAAE,IAAE,IAAE;KAAE;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE,GAAE;MAAC,MAAI,EAAE,QAAM,GAAE,eAAe,GAAE,EAAE,aAAW,OAAO,GAAE,2BAA2B,GAAE,EAAE,QAAM,GAAE,gBAAgB,GAAE,EAAE,IAAE,IAAE,EAAE,QAAO,sCAAsC,GAAE,EAAE,GAAE,UAAU;MAAG,IAAE,EAAE;MAAO,IAAG,EAAE,KAAG,IAAG,KAAI,IAAI,IAAE,GAAE,IAAE,KAAK,IAAI,IAAE,GAAE,CAAC,GAAE,IAAE,GAAE,KAAI,EAAE,IAAE,KAAG,MAAI,KAAG,IAAE,IAAE,IAAE,KAAG;KAAG;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE,GAAE;MAAC,MAAI,EAAE,QAAM,GAAE,eAAe,GAAE,EAAE,aAAW,OAAO,GAAE,2BAA2B,GAAE,EAAE,QAAM,GAAE,gBAAgB,GAAE,EAAE,IAAE,IAAE,EAAE,QAAO,sCAAsC,GAAE,EAAE,GAAE,OAAM,MAAM,IAAG,EAAE,UAAQ,KAAG,EAAE,GAAE,KAAG,IAAE,IAAE,QAAM,IAAE,GAAE,GAAE,GAAE,CAAC;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE,GAAE;MAAC,MAAI,EAAE,QAAM,GAAE,eAAe,GAAE,EAAE,aAAW,OAAO,GAAE,2BAA2B,GAAE,EAAE,QAAM,GAAE,gBAAgB,GAAE,EAAE,IAAE,IAAE,EAAE,QAAO,sCAAsC,GAAE,EAAE,GAAE,YAAW,WAAW,IAAG,EAAE,UAAQ,KAAG,EAAE,GAAE,KAAG,IAAE,IAAE,aAAW,IAAE,GAAE,GAAE,GAAE,CAAC;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE,GAAE;MAAC,MAAI,EAAE,QAAM,GAAE,eAAe,GAAE,EAAE,aAAW,OAAO,GAAE,2BAA2B,GAAE,EAAE,QAAM,GAAE,gBAAgB,GAAE,EAAE,IAAE,IAAE,EAAE,QAAO,sCAAsC,GAAE,EAAE,GAAE,sBAAqB,qBAAqB,IAAG,EAAE,UAAQ,KAAG,EAAE,MAAM,GAAE,GAAE,GAAE,GAAE,IAAG,CAAC;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE,GAAE;MAAC,MAAI,EAAE,QAAM,GAAE,eAAe,GAAE,EAAE,aAAW,OAAO,GAAE,2BAA2B,GAAE,EAAE,QAAM,GAAE,gBAAgB,GAAE,EAAE,IAAE,IAAE,EAAE,QAAO,sCAAsC,GAAE,EAAE,GAAE,uBAAsB,sBAAsB,IAAG,EAAE,UAAQ,KAAG,EAAE,MAAM,GAAE,GAAE,GAAE,GAAE,IAAG,CAAC;KAAC;KAAC,EAAE,SAAO,GAAE,EAAE,aAAW,GAAE,EAAE,oBAAkB,IAAG,EAAE,WAAS,MAAK,EAAE,kBAAgB,WAAU;MAAC,IAAG;OAAC,IAAyB,IAAE,IAAI,2BAAW,IAAhC,YAAY,CAAoB,CAAC;OAAE,OAAO,EAAE,MAAI,WAAU;QAAC,OAAO;OAAE,GAAE,OAAK,EAAE,IAAI,KAAG,cAAY,OAAO,EAAE;MAAQ,SAAO,GAAE;OAAC,OAAM,CAAC;MAAC;KAAC,EAAE,GAAE,EAAE,aAAW,SAAS,GAAE;MAAC,QAAO,OAAO,CAAC,CAAC,CAAC,YAAY,GAA7B;OAAgC,KAAI;OAAM,KAAI;OAAO,KAAI;OAAQ,KAAI;OAAQ,KAAI;OAAS,KAAI;OAAS,KAAI;OAAM,KAAI;OAAO,KAAI;OAAQ,KAAI;OAAU,KAAI,YAAW,OAAM,CAAC;OAAE,SAAQ,OAAM,CAAC;MAAC;KAAC,GAAE,EAAE,WAAS,SAAS,GAAE;MAAC,OAAM,EAAE,QAAM,KAAG,CAAC,EAAE;KAAU,GAAE,EAAE,aAAW,SAAS,GAAE,GAAE;MAAC,IAAI;MAAE,QAAO,KAAG,IAAG,KAAG,QAAhB;OAAwB,KAAI;QAAM,IAAE,EAAE,SAAO;QAAE;OAAM,KAAI;OAAO,KAAI;QAAQ,IAAE,EAAE,CAAC,CAAC,CAAC;QAAO;OAAM,KAAI;OAAQ,KAAI;OAAS,KAAI;QAAM,IAAE,EAAE;QAAO;OAAM,KAAI;QAAS,IAAE,EAAE,CAAC,CAAC,CAAC;QAAO;OAAM,KAAI;OAAO,KAAI;OAAQ,KAAI;OAAU,KAAI;QAAW,IAAE,IAAE,EAAE;QAAO;OAAM,SAAQ,MAAM,IAAI,MAAM,kBAAkB;MAAC;MAAC,OAAO;KAAC,GAAE,EAAE,SAAO,SAAS,GAAE,GAAE;MAAC,IAAG,EAAE,EAAE,CAAC,GAAE,qEAAqE,GAAE,MAAI,EAAE,QAAO,OAAO,IAAI,EAAE,CAAC;MAAE,IAAG,MAAI,EAAE,QAAO,OAAO,EAAE;MAAG,IAAG,YAAU,OAAO,GAAE,KAAI,IAAE,IAAE,GAAE,IAAE,EAAE,QAAO,KAAI,KAAG,EAAE,EAAE,CAAC;MAAO,KAAI,IAAI,IAAE,IAAI,EAAE,CAAC,GAAE,IAAE,GAAE,IAAE,GAAE,IAAE,EAAE,QAAO,KAAI;OAAC,IAAI,IAAE,EAAE;OAAG,EAAE,KAAK,GAAE,CAAC,GAAE,KAAG,EAAE;MAAM;MAAC,OAAO;KAAC,GAAE,EAAE,UAAU,QAAM,SAAS,GAAE,GAAE,GAAE,GAAE;MAAC,SAAS,CAAC,IAAE,SAAS,CAAC,MAAI,IAAE,GAAE,IAAE,KAAK,MAAI,IAAE,GAAE,IAAE,GAAE,IAAE,GAAE,IAAE,IAAG,IAAE,OAAO,CAAC,KAAG;MAAE,IAAI,GAAE,GAAE,GAAE,GAAE,IAAE,KAAK,SAAO;MAAE,SAAQ,CAAC,KAAG,KAAG,IAAE,OAAO,CAAC,QAAM,IAAE,IAAG,IAAE,OAAO,KAAG,MAAM,CAAC,CAAC,YAAY,GAApE;OAAuE,KAAI;QAAM,IAAE,SAAS,GAAE,GAAE,GAAE,GAAE;SAAC,IAAE,OAAO,CAAC,KAAG;SAAE,IAAI,IAAE,EAAE,SAAO;SAAE,CAAC,CAAC,KAAG,KAAG,IAAE,OAAO,CAAC,QAAM,IAAE,IAAG,GAAG,IAAE,EAAE,UAAQ,KAAG,GAAE,oBAAoB,GAAE,IAAE,IAAE,MAAI,IAAE,IAAE;SAAG,KAAI,IAAI,IAAE,GAAE,IAAE,GAAE,KAAI;UAAC,IAAI,IAAE,SAAS,EAAE,OAAO,IAAE,GAAE,CAAC,GAAE,EAAE;UAAE,EAAE,CAAC,MAAM,CAAC,GAAE,oBAAoB,GAAE,EAAE,IAAE,KAAG;SAAC;SAAC,OAAO,EAAE,gBAAc,IAAE,GAAE;QAAC,EAAE,MAAK,GAAE,GAAE,CAAC;QAAE;OAAM,KAAI;OAAO,KAAI;QAAQ,IAAE,MAAK,IAAE,GAAE,IAAE,GAAE,IAAE,EAAE,gBAAc,EAAE,EAAE,CAAC,GAAE,GAAE,GAAE,CAAC;QAAE;OAAM,KAAI;OAAQ,KAAI;QAAS,IAAE,EAAE,MAAK,GAAE,GAAE,CAAC;QAAE;OAAM,KAAI;QAAS,IAAE,MAAK,IAAE,GAAE,IAAE,GAAE,IAAE,EAAE,gBAAc,EAAE,EAAE,CAAC,GAAE,GAAE,GAAE,CAAC;QAAE;OAAM,KAAI;OAAO,KAAI;OAAQ,KAAI;OAAU,KAAI;QAAW,IAAE,EAAE,MAAK,GAAE,GAAE,CAAC;QAAE;OAAM,SAAQ,MAAM,IAAI,MAAM,kBAAkB;MAAC;MAAC,OAAO;KAAC,GAAE,EAAE,UAAU,WAAS,SAAS,GAAE,GAAE,GAAE;MAAC,IAAI,GAAE,GAAE,GAAE,GAAE,IAAE;MAAK,IAAG,IAAE,OAAO,KAAG,MAAM,CAAC,CAAC,YAAY,GAAE,IAAE,OAAO,CAAC,KAAG,IAAG,IAAE,KAAK,MAAI,IAAE,OAAO,CAAC,IAAE,EAAE,YAAU,GAAE,OAAM;MAAG,QAAO,GAAP;OAAU,KAAI;QAAM,IAAE,SAAS,GAAE,GAAE,GAAE;SAAC,IAAI,IAAE,EAAE;SAAO,CAAC,CAAC,KAAG,IAAE,OAAK,IAAE;SAAG,CAAC,CAAC,KAAG,IAAE,KAAG,IAAE,OAAK,IAAE;SAAG,KAAI,IAAI,IAAE,IAAG,IAAE,GAAE,IAAE,GAAE,KAAI,KAAG,EAAE,EAAE,EAAE;SAAE,OAAO;QAAC,EAAE,GAAE,GAAE,CAAC;QAAE;OAAM,KAAI;OAAO,KAAI;QAAQ,IAAE,SAAS,GAAE,GAAE,GAAE;SAAC,IAAI,IAAE,IAAG,IAAE;SAAG,IAAE,KAAK,IAAI,EAAE,QAAO,CAAC;SAAE,KAAI,IAAI,IAAE,GAAE,IAAE,GAAE,KAAI,EAAE,MAAI,OAAK,KAAG,EAAE,CAAC,IAAE,OAAO,aAAa,EAAE,EAAE,GAAE,IAAE,MAAI,KAAG,MAAI,EAAE,EAAE,CAAC,SAAS,EAAE;SAAE,OAAO,IAAE,EAAE,CAAC;QAAC,EAAE,GAAE,GAAE,CAAC;QAAE;OAAM,KAAI;OAAQ,KAAI;QAAS,IAAE,EAAE,GAAE,GAAE,CAAC;QAAE;OAAM,KAAI;QAAS,IAAE,GAAE,IAAE,GAAE,IAAE,OAAK,IAAE,MAAI,MAAI,EAAE,SAAO,EAAE,cAAc,CAAC,IAAE,EAAE,cAAc,EAAE,MAAM,GAAE,CAAC,CAAC;QAAE;OAAM,KAAI;OAAO,KAAI;OAAQ,KAAI;OAAU,KAAI;QAAW,IAAE,SAAS,GAAE,GAAE,GAAE;SAAC,KAAI,IAAI,IAAE,EAAE,MAAM,GAAE,CAAC,GAAE,IAAE,IAAG,IAAE,GAAE,IAAE,EAAE,QAAO,KAAG,GAAE,KAAG,OAAO,aAAa,EAAE,KAAG,MAAI,EAAE,IAAE,EAAE;SAAE,OAAO;QAAC,EAAE,GAAE,GAAE,CAAC;QAAE;OAAM,SAAQ,MAAM,IAAI,MAAM,kBAAkB;MAAC;MAAC,OAAO;KAAC,GAAE,EAAE,UAAU,SAAO,WAAU;MAAC,OAAM;OAAC,MAAK;OAAS,MAAK,MAAM,UAAU,MAAM,KAAK,KAAK,QAAM,MAAK,CAAC;MAAC;KAAC,GAAE,EAAE,UAAU,OAAK,SAAS,GAAE,GAAE,GAAE,GAAE;MAAC,IAAG,IAAE,KAAG,IAAG,IAAE,KAAG,MAAI,IAAE,IAAE,KAAK,aAAW,IAAE,KAAG,MAAI,MAAI,EAAE,UAAQ,MAAI,KAAK,QAAO;OAAC,EAAE,KAAG,GAAE,yBAAyB,GAAE,EAAE,KAAG,KAAG,IAAE,EAAE,QAAO,2BAA2B,GAAE,EAAE,KAAG,KAAG,IAAE,KAAK,QAAO,2BAA2B,GAAE,EAAE,KAAG,KAAG,KAAG,KAAK,QAAO,yBAAyB,GAAE,IAAE,KAAK,WAAS,IAAE,KAAK;OAAQ,IAAI,KAAG,IAAE,EAAE,SAAO,IAAE,IAAE,IAAE,EAAE,SAAO,IAAE,IAAE,KAAG;OAAE,IAAG,IAAE,OAAK,CAAC,EAAE,iBAAgB,KAAI,IAAI,IAAE,GAAE,IAAE,GAAE,KAAI,EAAE,IAAE,KAAG,KAAK,IAAE;YAAQ,EAAE,KAAK,KAAK,SAAS,GAAE,IAAE,CAAC,GAAE,CAAC;MAAC;KAAC,GAAE,EAAE,UAAU,QAAM,SAAS,GAAE,GAAE;MAAC,IAAI,IAAE,KAAK;MAAO,IAAG,IAAE,EAAE,GAAE,GAAE,CAAC,GAAE,IAAE,EAAE,GAAE,GAAE,CAAC,GAAE,EAAE,iBAAgB,OAAO,EAAE,SAAS,KAAK,SAAS,GAAE,CAAC,CAAC;MAAE,KAAI,IAAI,IAAE,IAAE,GAAE,IAAE,IAAI,EAAE,GAAE,KAAK,GAAE,CAAC,CAAC,GAAE,IAAE,GAAE,IAAE,GAAE,KAAI,EAAE,KAAG,KAAK,IAAE;MAAG,OAAO;KAAC,GAAE,EAAE,UAAU,MAAI,SAAS,GAAE;MAAC,OAAO,QAAQ,IAAI,2DAA2D,GAAE,KAAK,UAAU,CAAC;KAAC,GAAE,EAAE,UAAU,MAAI,SAAS,GAAE,GAAE;MAAC,OAAO,QAAQ,IAAI,2DAA2D,GAAE,KAAK,WAAW,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,YAAU,SAAS,GAAE,GAAE;MAAC,IAAG,MAAI,EAAE,QAAM,GAAE,gBAAgB,GAAE,EAAE,IAAE,KAAK,QAAO,qCAAqC,IAAG,EAAE,KAAG,KAAK,SAAQ,OAAO,KAAK;KAAE,GAAE,EAAE,UAAU,eAAa,SAAS,GAAE,GAAE;MAAC,OAAO,EAAE,MAAK,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,eAAa,SAAS,GAAE,GAAE;MAAC,OAAO,EAAE,MAAK,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,eAAa,SAAS,GAAE,GAAE;MAAC,OAAO,EAAE,MAAK,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,eAAa,SAAS,GAAE,GAAE;MAAC,OAAO,EAAE,MAAK,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,WAAS,SAAS,GAAE,GAAE;MAAC,IAAG,MAAI,EAAE,QAAM,GAAE,gBAAgB,GAAE,EAAE,IAAE,KAAK,QAAO,qCAAqC,IAAG,EAAE,KAAG,KAAK,SAAQ,OAAO,MAAI,KAAK,KAAG,MAAI,MAAI,KAAK,KAAG,KAAG,KAAK;KAAE,GAAE,EAAE,UAAU,cAAY,SAAS,GAAE,GAAE;MAAC,OAAO,EAAE,MAAK,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,cAAY,SAAS,GAAE,GAAE;MAAC,OAAO,EAAE,MAAK,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,cAAY,SAAS,GAAE,GAAE;MAAC,OAAO,EAAE,MAAK,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,cAAY,SAAS,GAAE,GAAE;MAAC,OAAO,EAAE,MAAK,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,cAAY,SAAS,GAAE,GAAE;MAAC,OAAO,EAAE,MAAK,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,cAAY,SAAS,GAAE,GAAE;MAAC,OAAO,EAAE,MAAK,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,eAAa,SAAS,GAAE,GAAE;MAAC,OAAO,EAAE,MAAK,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,eAAa,SAAS,GAAE,GAAE;MAAC,OAAO,EAAE,MAAK,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,aAAW,SAAS,GAAE,GAAE,GAAE;MAAC,MAAI,EAAE,QAAM,GAAE,eAAe,GAAE,EAAE,QAAM,GAAE,gBAAgB,GAAE,EAAE,IAAE,KAAK,QAAO,sCAAsC,GAAE,EAAE,GAAE,GAAG,IAAG,KAAG,KAAK,WAAS,KAAK,KAAG;KAAE,GAAE,EAAE,UAAU,gBAAc,SAAS,GAAE,GAAE,GAAE;MAAC,EAAE,MAAK,GAAE,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,gBAAc,SAAS,GAAE,GAAE,GAAE;MAAC,EAAE,MAAK,GAAE,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,gBAAc,SAAS,GAAE,GAAE,GAAE;MAAC,EAAE,MAAK,GAAE,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,gBAAc,SAAS,GAAE,GAAE,GAAE;MAAC,EAAE,MAAK,GAAE,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,YAAU,SAAS,GAAE,GAAE,GAAE;MAAC,MAAI,EAAE,QAAM,GAAE,eAAe,GAAE,EAAE,QAAM,GAAE,gBAAgB,GAAE,EAAE,IAAE,KAAK,QAAO,sCAAsC,GAAE,EAAE,GAAE,KAAI,IAAI,IAAG,KAAG,KAAK,WAAS,KAAG,IAAE,KAAK,WAAW,GAAE,GAAE,CAAC,IAAE,KAAK,WAAW,MAAI,IAAE,GAAE,GAAE,CAAC;KAAE,GAAE,EAAE,UAAU,eAAa,SAAS,GAAE,GAAE,GAAE;MAAC,EAAE,MAAK,GAAE,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,eAAa,SAAS,GAAE,GAAE,GAAE;MAAC,EAAE,MAAK,GAAE,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,eAAa,SAAS,GAAE,GAAE,GAAE;MAAC,EAAE,MAAK,GAAE,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,eAAa,SAAS,GAAE,GAAE,GAAE;MAAC,EAAE,MAAK,GAAE,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,eAAa,SAAS,GAAE,GAAE,GAAE;MAAC,EAAE,MAAK,GAAE,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,eAAa,SAAS,GAAE,GAAE,GAAE;MAAC,EAAE,MAAK,GAAE,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,gBAAc,SAAS,GAAE,GAAE,GAAE;MAAC,EAAE,MAAK,GAAE,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,gBAAc,SAAS,GAAE,GAAE,GAAE;MAAC,EAAE,MAAK,GAAE,GAAE,CAAC,GAAE,CAAC;KAAC,GAAE,EAAE,UAAU,OAAK,SAAS,GAAE,GAAE,GAAE;MAAC,IAAG,IAAE,KAAG,GAAE,IAAE,KAAG,KAAK,QAAO,EAAE,YAAU,QAAO,IAAE,YAAU,QAAO,IAAE,KAAG,KAAG,EAAE,WAAW,CAAC,IAAE,MAAI,CAAC,MAAM,CAAC,GAAE,uBAAuB,GAAE,EAAE,KAAG,GAAE,aAAa,GAAE,MAAI,KAAG,MAAI,KAAK,QAAO;OAAC,EAAE,KAAG,KAAG,IAAE,KAAK,QAAO,qBAAqB,GAAE,EAAE,KAAG,KAAG,KAAG,KAAK,QAAO,mBAAmB;OAAE,KAAI,IAAI,IAAE,GAAE,IAAE,GAAE,KAAI,KAAK,KAAG;MAAC;KAAC,GAAE,EAAE,UAAU,UAAQ,WAAU;MAAC,KAAI,IAAI,IAAE,CAAC,GAAE,IAAE,KAAK,QAAO,IAAE,GAAE,IAAE,GAAE,KAAI,IAAG,EAAE,KAAG,EAAE,KAAK,EAAE,GAAE,MAAI,EAAE,mBAAkB;OAAC,EAAE,IAAE,KAAG;OAAM;MAAK;MAAC,OAAM,aAAW,EAAE,KAAK,GAAG,IAAE;KAAG,GAAE,EAAE,UAAU,gBAAc,WAAU;MAAC,IAAG,eAAa,OAAO,YAAW,MAAM,IAAI,MAAM,oDAAoD;MAAE,IAAG,EAAE,iBAAgB,OAAO,IAAI,EAAE,IAAI,CAAC,CAAC;MAAO,KAAI,IAAI,IAAE,IAAI,WAAW,KAAK,MAAM,GAAE,IAAE,GAAE,IAAE,EAAE,QAAO,IAAE,GAAE,KAAG,GAAE,EAAE,KAAG,KAAK;MAAG,OAAO,EAAE;KAAM;KAAE,IAAI,IAAE,EAAE;KAAU,SAAS,EAAE,GAAE,GAAE,GAAE;MAAC,OAAM,YAAU,OAAO,IAAE,IAAE,MAAI,IAAE,CAAC,CAAC,KAAG,IAAE,KAAG,KAAG,MAAI,KAAG,KAAG,IAAE;KAAC;KAAC,SAAS,EAAE,GAAE;MAAC,QAAO,IAAE,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAG,IAAE,IAAE;KAAC;KAAC,SAAS,EAAE,GAAE;MAAC,QAAO,MAAM,WAAS,SAAS,GAAE;OAAC,OAAM,qBAAmB,OAAO,UAAU,SAAS,KAAK,CAAC;MAAC,EAAA,CAAG,CAAC;KAAC;KAAC,SAAS,EAAE,GAAE;MAAC,OAAO,IAAE,KAAG,MAAI,EAAE,SAAS,EAAE,IAAE,EAAE,SAAS,EAAE;KAAC;KAAC,SAAS,EAAE,GAAE;MAAC,KAAI,IAAI,IAAE,CAAC,GAAE,IAAE,GAAE,IAAE,EAAE,QAAO,KAAI;OAAC,IAAI,IAAE,EAAE,WAAW,CAAC;OAAE,IAAG,KAAG,KAAI,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;YAAO,KAAI,IAAI,IAAE,GAAE,KAAG,SAAO,KAAG,KAAG,SAAO,KAAI,mBAAmB,EAAE,MAAM,GAAE,IAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,GAAG,IAAG,IAAE,GAAE,IAAE,EAAE,QAAO,KAAI,EAAE,KAAK,SAAS,EAAE,IAAG,EAAE,CAAC;MAAC;MAAC,OAAO;KAAC;KAAC,SAAS,EAAE,GAAE;MAAC,OAAO,EAAE,YAAY,CAAC;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE;MAAC,KAAI,IAAI,IAAE,GAAE,IAAE,KAAG,EAAE,IAAE,KAAG,EAAE,UAAQ,KAAG,EAAE,SAAQ,KAAI,EAAE,IAAE,KAAG,EAAE;MAAG,OAAO;KAAC;KAAC,SAAS,EAAE,GAAE;MAAC,IAAG;OAAC,OAAO,mBAAmB,CAAC;MAAC,SAAO,GAAE;OAAC,OAAO,OAAO,aAAa,KAAK;MAAC;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE;MAAC,EAAE,YAAU,OAAO,GAAE,uCAAuC,GAAE,EAAE,KAAG,GAAE,0DAA0D,GAAE,EAAE,KAAG,GAAE,6CAA6C,GAAE,EAAE,KAAK,MAAM,CAAC,MAAI,GAAE,kCAAkC;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE;MAAC,EAAE,YAAU,OAAO,GAAE,uCAAuC,GAAE,EAAE,KAAG,GAAE,yCAAyC,GAAE,EAAE,KAAG,GAAE,0CAA0C,GAAE,EAAE,KAAK,MAAM,CAAC,MAAI,GAAE,kCAAkC;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE;MAAC,EAAE,YAAU,OAAO,GAAE,uCAAuC,GAAE,EAAE,KAAG,GAAE,yCAAyC,GAAE,EAAE,KAAG,GAAE,0CAA0C;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE;MAAC,IAAG,CAAC,GAAE,MAAM,IAAI,MAAM,KAAG,kBAAkB;KAAC;KAAC,EAAE,WAAS,SAAS,GAAE;MAAC,OAAO,EAAE,YAAU,CAAC,GAAE,EAAE,OAAK,EAAE,KAAI,EAAE,OAAK,EAAE,KAAI,EAAE,MAAI,EAAE,KAAI,EAAE,MAAI,EAAE,KAAI,EAAE,QAAM,EAAE,OAAM,EAAE,WAAS,EAAE,UAAS,EAAE,iBAAe,EAAE,UAAS,EAAE,SAAO,EAAE,QAAO,EAAE,OAAK,EAAE,MAAK,EAAE,QAAM,EAAE,OAAM,EAAE,YAAU,EAAE,WAAU,EAAE,eAAa,EAAE,cAAa,EAAE,eAAa,EAAE,cAAa,EAAE,eAAa,EAAE,cAAa,EAAE,eAAa,EAAE,cAAa,EAAE,WAAS,EAAE,UAAS,EAAE,cAAY,EAAE,aAAY,EAAE,cAAY,EAAE,aAAY,EAAE,cAAY,EAAE,aAAY,EAAE,cAAY,EAAE,aAAY,EAAE,cAAY,EAAE,aAAY,EAAE,cAAY,EAAE,aAAY,EAAE,eAAa,EAAE,cAAa,EAAE,eAAa,EAAE,cAAa,EAAE,aAAW,EAAE,YAAW,EAAE,gBAAc,EAAE,eAAc,EAAE,gBAAc,EAAE,eAAc,EAAE,gBAAc,EAAE,eAAc,EAAE,gBAAc,EAAE,eAAc,EAAE,YAAU,EAAE,WAAU,EAAE,eAAa,EAAE,cAAa,EAAE,eAAa,EAAE,cAAa,EAAE,eAAa,EAAE,cAAa,EAAE,eAAa,EAAE,cAAa,EAAE,eAAa,EAAE,cAAa,EAAE,eAAa,EAAE,cAAa,EAAE,gBAAc,EAAE,eAAc,EAAE,gBAAc,EAAE,eAAc,EAAE,OAAK,EAAE,MAAK,EAAE,UAAQ,EAAE,SAAQ,EAAE,gBAAc,EAAE,eAAc;KAAC;IAAC,EAAA,CAAE,KAAK,MAAK,EAAE,QAAQ,GAAE,eAAa,OAAO,OAAK,OAAK,eAAa,OAAO,SAAO,SAAO,CAAC,GAAE,EAAE,QAAQ,CAAC,CAAC,QAAO,UAAU,IAAG,UAAU,IAAG,UAAU,IAAG,UAAU,IAAG,8DAA6D,mDAAmD;GAAC,GAAE;IAAC,aAAY;IAAE,QAAO;IAAE,SAAQ;IAAG,QAAO;GAAE,CAAC;GAAE,GAAE,CAAC,SAAS,GAAE,GAAE,GAAE;IAAC,CAAC,SAAS,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE;KAAC,IAAI,IAAE,EAAE,QAAQ,CAAC,CAAC,QAAO,IAAE,GAAE,IAAE,IAAI,EAAE,CAAC;KAAE,EAAE,KAAK,CAAC;KAAE,EAAE,UAAQ,EAAC,MAAK,SAAS,GAAE,GAAE,GAAE,GAAE;MAAC,KAAI,IAAI,IAAE,EAAE,SAAS,GAAE,GAAE;OAAC,EAAE,SAAO,KAAG,MAAI,IAAE,EAAE,UAAQ,IAAE,EAAE,SAAO,IAAG,IAAE,EAAE,OAAO,CAAC,GAAE,CAAC,GAAE,CAAC;OAAG,KAAI,IAAI,GAAE,IAAE,CAAC,GAAE,IAAE,IAAE,EAAE,cAAY,EAAE,aAAY,IAAE,GAAE,IAAE,EAAE,QAAO,KAAG,GAAE,EAAE,KAAK,EAAE,KAAK,GAAE,CAAC,CAAC;OAAE,OAAO;MAAC,EAAE,IAAE,EAAE,SAAS,CAAC,IAAE,IAAE,IAAI,EAAE,CAAC,GAAE,CAAC,GAAE,IAAE,EAAE,MAAM,GAAE,IAAE,GAAE,IAAE,IAAI,EAAE,CAAC,GAAE,IAAE,IAAE,EAAE,eAAa,EAAE,cAAa,IAAE,GAAE,IAAE,EAAE,QAAO,KAAI,EAAE,KAAK,GAAE,EAAE,IAAG,IAAE,GAAE,CAAC,CAAC;MAAE,OAAO;KAAC,EAAC;IAAC,EAAA,CAAE,KAAK,MAAK,EAAE,QAAQ,GAAE,eAAa,OAAO,OAAK,OAAK,eAAa,OAAO,SAAO,SAAO,CAAC,GAAE,EAAE,QAAQ,CAAC,CAAC,QAAO,UAAU,IAAG,UAAU,IAAG,UAAU,IAAG,UAAU,IAAG,2EAA0E,8DAA8D;GAAC,GAAE;IAAC,QAAO;IAAE,QAAO;GAAE,CAAC;GAAE,GAAE,CAAC,SAAS,GAAE,GAAE,GAAE;IAAC,CAAC,SAAS,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE;KAAC,IAAI,IAAE,EAAE,QAAQ,CAAC,CAAC,QAAO,IAAE,EAAE,OAAO,GAAE,IAAE,EAAE,UAAU,GAAE,IAAE,EAAE,OAAO,GAAE,IAAE;MAAC,MAAK;MAAE,QAAO;MAAE,KAAI,EAAE,OAAO;KAAC,GAAE,IAAE,IAAG,IAAE,IAAI,EAAE,CAAC;KAAE,SAAS,EAAE,GAAE,GAAE;MAAC,IAAI,IAAE,EAAE,IAAE,KAAG,SAAQ,IAAE,CAAC;MAAE,OAAO,KAAG,EAAE,cAAa,GAAE,sBAAsB,GAAE;OAAC,QAAO,SAAS,GAAE;QAAC,OAAO,EAAE,SAAS,CAAC,MAAI,IAAE,IAAI,EAAE,CAAC,IAAG,EAAE,KAAK,CAAC,GAAE,EAAE,QAAO;OAAI;OAAE,QAAO,SAAS,GAAE;QAAC,IAAI,IAAE,EAAE,OAAO,CAAC,GAAE,IAAE,IAAE,SAAS,GAAE,GAAE,GAAE;SAAC,EAAE,SAAS,CAAC,MAAI,IAAE,IAAI,EAAE,CAAC,IAAG,EAAE,SAAS,CAAC,MAAI,IAAE,IAAI,EAAE,CAAC,IAAG,EAAE,SAAO,IAAE,IAAE,EAAE,CAAC,IAAE,EAAE,SAAO,MAAI,IAAE,EAAE,OAAO,CAAC,GAAE,CAAC,GAAE,CAAC;SAAG,KAAI,IAAI,IAAE,IAAI,EAAE,CAAC,GAAE,IAAE,IAAI,EAAE,CAAC,GAAE,IAAE,GAAE,IAAE,GAAE,KAAI,EAAE,KAAG,KAAG,EAAE,IAAG,EAAE,KAAG,KAAG,EAAE;SAAG,OAAO,IAAE,EAAE,EAAE,OAAO,CAAC,GAAE,CAAC,CAAC,CAAC,GAAE,EAAE,EAAE,OAAO,CAAC,GAAE,CAAC,CAAC,CAAC;QAAC,EAAE,GAAE,GAAE,CAAC,IAAE,EAAE,CAAC;QAAE,OAAO,IAAE,MAAK,IAAE,EAAE,SAAS,CAAC,IAAE;OAAC;MAAC;KAAC;KAAC,SAAS,IAAG;MAAC,IAAI,IAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,KAAK,GAAG;MAAE,MAAM,IAAI,MAAM;OAAC;OAAE;OAA0B;MAAiD,CAAC,CAAC,KAAK,IAAI,CAAC;KAAC;KAAC,EAAE,KAAK,CAAC,GAAE,EAAE,aAAW,SAAS,GAAE;MAAC,OAAO,EAAE,CAAC;KAAC,GAAE,EAAE,aAAW,GAAE,EAAE,cAAY,SAAS,GAAE,GAAE;MAAC,IAAG,CAAC,KAAG,CAAC,EAAE,MAAK,OAAO,IAAI,EAAE,EAAE,CAAC,CAAC;MAAE,IAAG;OAAC,EAAE,KAAK,MAAK,KAAK,GAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;MAAC,SAAO,GAAE;OAAC,EAAE,CAAC;MAAC;KAAC;KAAE,IAAI,GAAE,IAAE;MAAC;MAAoB;MAAe;MAAiB;MAAiB;MAAmB;MAAa;MAAe;MAAsB;KAAQ,GAAE,IAAE,SAAS,GAAE;MAAC,EAAE,KAAG,WAAU;OAAC,EAAE,UAAS,GAAE,wBAAwB;MAAC;KAAC;KAAE,KAAI,KAAK,GAAE,EAAE,EAAE,IAAG,CAAC;IAAC,EAAA,CAAE,KAAK,MAAK,EAAE,QAAQ,GAAE,eAAa,OAAO,OAAK,OAAK,eAAa,OAAO,SAAO,SAAO,CAAC,GAAE,EAAE,QAAQ,CAAC,CAAC,QAAO,UAAU,IAAG,UAAU,IAAG,UAAU,IAAG,UAAU,IAAG,yEAAwE,8DAA8D;GAAC,GAAE;IAAC,SAAQ;IAAE,SAAQ;IAAE,SAAQ;IAAE,YAAW;IAAE,QAAO;IAAE,QAAO;GAAE,CAAC;GAAE,GAAE,CAAC,SAAS,GAAE,GAAE,GAAE;IAAC,CAAC,SAAS,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE;KAAC,IAAI,IAAE,EAAE,WAAW;KAAE,SAAS,EAAE,GAAE,GAAE;MAAC,EAAE,KAAG,MAAI,OAAK,IAAE,IAAG,EAAE,MAAI,IAAE,OAAK,KAAG,MAAI;MAAE,KAAI,IAAI,IAAE,YAAW,IAAE,YAAW,IAAE,aAAY,IAAE,WAAU,IAAE,GAAE,IAAE,EAAE,QAAO,KAAG,IAAG;OAAC,IAAI,IAAE,GAAE,IAAE,GAAE,IAAE,GAAE,IAAE,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,GAAE,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,SAAS,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,WAAW;OAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,GAAE,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,WAAW,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,SAAS,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,GAAE,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,WAAW,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,IAAG,MAAM,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,IAAG,WAAW,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,GAAE,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,IAAG,SAAS,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,IAAG,WAAW,GAAE,IAAE,EAAE,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,IAAG,UAAU,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,GAAE,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,GAAE,WAAW,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,IAAG,SAAS,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,GAAE,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,GAAE,QAAQ,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,IAAG,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,GAAE,SAAS,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,GAAE,WAAW,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,GAAE,WAAW,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,GAAE,SAAS,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,UAAU,GAAE,IAAE,EAAE,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,IAAG,WAAW,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,GAAE,OAAO,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,WAAW,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,IAAG,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,IAAG,SAAS,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,GAAE,WAAW,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,IAAG,WAAW,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,GAAE,SAAS,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,QAAQ,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,GAAE,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,IAAG,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,IAAG,SAAS,GAAE,IAAE,EAAE,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,UAAU,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,GAAE,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,IAAG,WAAW,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,SAAS,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,GAAE,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,WAAW,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,IAAG,QAAQ,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,WAAW,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,GAAE,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,IAAG,SAAS,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,WAAW,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,IAAG,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,GAAE,UAAU,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,KAAI,IAAG,WAAW,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,SAAS,GAAE,IAAE,EAAE,GAAE,GAAE,GAAE,GAAE,EAAE,IAAE,IAAG,IAAG,UAAU,GAAE,IAAE,EAAE,GAAE,CAAC,GAAE,IAAE,EAAE,GAAE,CAAC,GAAE,IAAE,EAAE,GAAE,CAAC,GAAE,IAAE,EAAE,GAAE,CAAC;MAAC;MAAC,OAAO,MAAM,GAAE,GAAE,GAAE,CAAC;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE;MAAC,OAAO,GAAG,IAAE,EAAE,EAAE,GAAE,CAAC,GAAE,EAAE,GAAE,CAAC,CAAC,MAAI,IAAE,MAAI,KAAG,GAAE,CAAC;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE;MAAC,OAAO,EAAE,IAAE,IAAE,CAAC,IAAE,GAAE,GAAE,GAAE,GAAE,GAAE,CAAC;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE;MAAC,OAAO,EAAE,IAAE,IAAE,IAAE,CAAC,GAAE,GAAE,GAAE,GAAE,GAAE,CAAC;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE;MAAC,OAAO,EAAE,IAAE,IAAE,GAAE,GAAE,GAAE,GAAE,GAAE,CAAC;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE;MAAC,OAAO,EAAE,KAAG,IAAE,CAAC,IAAG,GAAE,GAAE,GAAE,GAAE,CAAC;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE;MAAC,IAAI,KAAG,QAAM,MAAI,QAAM;MAAG,QAAO,KAAG,OAAK,KAAG,OAAK,KAAG,OAAK,KAAG,QAAM;KAAC;KAAC,EAAE,UAAQ,SAAS,GAAE;MAAC,OAAO,EAAE,KAAK,GAAE,GAAE,EAAE;KAAC;IAAC,EAAA,CAAE,KAAK,MAAK,EAAE,QAAQ,GAAE,eAAa,OAAO,OAAK,OAAK,eAAa,OAAO,SAAO,SAAO,CAAC,GAAE,EAAE,QAAQ,CAAC,CAAC,QAAO,UAAU,IAAG,UAAU,IAAG,UAAU,IAAG,UAAU,IAAG,uEAAsE,8DAA8D;GAAC,GAAE;IAAC,aAAY;IAAE,QAAO;IAAE,QAAO;GAAE,CAAC;GAAE,GAAE,CAAC,SAAS,GAAE,GAAE,GAAE;IAAC,CAAC,SAAS,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE;KAAC,IAAI;KAAE,EAAE,UAAQ,KAAG,SAAS,GAAE;MAAC,KAAI,IAAI,GAAE,IAAE,IAAI,MAAM,CAAC,GAAE,IAAE,GAAE,IAAE,GAAE,KAAI,MAAI,IAAE,OAAK,IAAE,aAAW,KAAK,OAAO,IAAG,EAAE,KAAG,QAAM,IAAE,MAAI,KAAG;MAAI,OAAO;KAAC;IAAC,EAAA,CAAE,KAAK,MAAK,EAAE,QAAQ,GAAE,eAAa,OAAO,OAAK,OAAK,eAAa,OAAO,SAAO,SAAO,CAAC,GAAE,EAAE,QAAQ,CAAC,CAAC,QAAO,UAAU,IAAG,UAAU,IAAG,UAAU,IAAG,UAAU,IAAG,uEAAsE,8DAA8D;GAAC,GAAE;IAAC,QAAO;IAAE,QAAO;GAAE,CAAC;GAAE,GAAE,CAAC,SAAS,GAAE,GAAE,GAAE;IAAC,CAAC,SAAS,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE;KAAC,IAAI,IAAE,EAAE,WAAW;KAAE,SAAS,EAAE,GAAE,GAAE;MAAC,EAAE,KAAG,MAAI,OAAK,KAAG,IAAE,IAAG,EAAE,MAAI,IAAE,MAAI,KAAG,MAAI;MAAE,KAAI,IAAI,GAAE,GAAE,GAAE,IAAE,MAAM,EAAE,GAAE,IAAE,YAAW,IAAE,YAAW,IAAE,aAAY,IAAE,WAAU,IAAE,aAAY,IAAE,GAAE,IAAE,EAAE,QAAO,KAAG,IAAG;OAAC,KAAI,IAAI,IAAE,GAAE,IAAE,GAAE,IAAE,GAAE,IAAE,GAAE,IAAE,GAAE,IAAE,GAAE,IAAE,IAAG,KAAI;QAAC,EAAE,KAAG,IAAE,KAAG,EAAE,IAAE,KAAG,EAAE,EAAE,IAAE,KAAG,EAAE,IAAE,KAAG,EAAE,IAAE,MAAI,EAAE,IAAE,KAAI,CAAC;QAAE,IAAI,IAAE,EAAE,EAAE,EAAE,GAAE,CAAC,IAAG,IAAE,GAAE,IAAE,GAAE,IAAE,IAAG,IAAE,KAAG,KAAG,IAAE,IAAE,CAAC,IAAE,IAAE,EAAE,IAAE,OAAK,IAAE,KAAG,IAAE,IAAE,IAAE,IAAE,IAAE,IAAE,IAAE,IAAE,EAAE,GAAE,EAAE,EAAE,GAAE,EAAE,EAAE,IAAG,IAAE,KAAG,KAAG,aAAW,IAAE,KAAG,aAAW,IAAE,KAAG,cAAY,UAAU,CAAC,GAAE,IAAE,GAAE,IAAE,GAAE,IAAE,EAAE,GAAE,EAAE,GAAE,IAAE,GAAE,IAAE;OAAC;OAAC,IAAE,EAAE,GAAE,CAAC,GAAE,IAAE,EAAE,GAAE,CAAC,GAAE,IAAE,EAAE,GAAE,CAAC,GAAE,IAAE,EAAE,GAAE,CAAC,GAAE,IAAE,EAAE,GAAE,CAAC;MAAC;MAAC,OAAO,MAAM,GAAE,GAAE,GAAE,GAAE,CAAC;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE;MAAC,IAAI,KAAG,QAAM,MAAI,QAAM;MAAG,QAAO,KAAG,OAAK,KAAG,OAAK,KAAG,OAAK,KAAG,QAAM;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE;MAAC,OAAO,KAAG,IAAE,MAAI,KAAG;KAAC;KAAC,EAAE,UAAQ,SAAS,GAAE;MAAC,OAAO,EAAE,KAAK,GAAE,GAAE,IAAG,CAAC,CAAC;KAAC;IAAC,EAAA,CAAE,KAAK,MAAK,EAAE,QAAQ,GAAE,eAAa,OAAO,OAAK,OAAK,eAAa,OAAO,SAAO,SAAO,CAAC,GAAE,EAAE,QAAQ,CAAC,CAAC,QAAO,UAAU,IAAG,UAAU,IAAG,UAAU,IAAG,UAAU,IAAG,uEAAsE,8DAA8D;GAAC,GAAE;IAAC,aAAY;IAAE,QAAO;IAAE,QAAO;GAAE,CAAC;GAAE,GAAE,CAAC,SAAS,GAAE,GAAE,GAAE;IAAC,CAAC,SAAS,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE;KAAC,SAAS,EAAE,GAAE,GAAE;MAAC,IAAI,KAAG,QAAM,MAAI,QAAM;MAAG,QAAO,KAAG,OAAK,KAAG,OAAK,KAAG,OAAK,KAAG,QAAM;KAAC;KAAC,SAAS,EAAE,GAAE,GAAE;MAAC,IAAI,GAAE,IAAE,IAAI,MAAM,YAAW,YAAW,YAAW,YAAW,WAAU,YAAW,YAAW,YAAW,YAAW,WAAU,WAAU,YAAW,YAAW,YAAW,YAAW,YAAW,YAAW,YAAW,WAAU,WAAU,WAAU,YAAW,YAAW,YAAW,YAAW,YAAW,YAAW,YAAW,YAAW,YAAW,WAAU,WAAU,WAAU,WAAU,YAAW,YAAW,YAAW,YAAW,YAAW,YAAW,YAAW,YAAW,YAAW,YAAW,YAAW,YAAW,YAAW,WAAU,WAAU,WAAU,WAAU,WAAU,WAAU,YAAW,YAAW,YAAW,YAAW,YAAW,YAAW,YAAW,YAAW,YAAW,YAAW,UAAU,GAAE,IAAE,IAAI,MAAM,YAAW,YAAW,YAAW,YAAW,YAAW,YAAW,WAAU,UAAU,GAAE,IAAE,IAAI,MAAM,EAAE;MAAE,EAAE,KAAG,MAAI,OAAK,KAAG,IAAE,IAAG,EAAE,MAAI,IAAE,MAAI,KAAG,MAAI;MAAE,KAAI,IAAI,GAAE,GAAE,IAAE,GAAE,IAAE,EAAE,QAAO,KAAG,IAAG;OAAC,KAAI,IAAI,IAAE,EAAE,IAAG,IAAE,EAAE,IAAG,IAAE,EAAE,IAAG,IAAE,EAAE,IAAG,IAAE,EAAE,IAAG,IAAE,EAAE,IAAG,IAAE,EAAE,IAAG,IAAE,EAAE,IAAG,IAAE,GAAE,IAAE,IAAG,KAAI,EAAE,KAAG,IAAE,KAAG,EAAE,IAAE,KAAG,EAAE,EAAE,GAAG,IAAE,EAAE,IAAE,IAAG,EAAE,GAAE,EAAE,IAAE,EAAE,GAAE,EAAE,IAAE,EAAE,GAAE,EAAE,IAAG,EAAE,IAAE,EAAE,IAAG,IAAE,EAAE,IAAE,KAAI,EAAE,GAAE,CAAC,IAAE,EAAE,GAAE,EAAE,IAAE,EAAE,GAAE,CAAC,EAAE,GAAE,EAAE,IAAE,GAAG,GAAE,IAAE,EAAE,EAAE,EAAE,EAAE,GAAE,EAAE,IAAE,GAAE,CAAC,IAAE,EAAE,GAAE,EAAE,IAAE,EAAE,GAAE,EAAE,CAAC,GAAE,IAAE,IAAE,CAAC,IAAE,CAAC,GAAE,EAAE,EAAE,GAAE,EAAE,EAAE,GAAE,IAAE,EAAE,EAAE,IAAE,GAAE,CAAC,IAAE,EAAE,GAAE,EAAE,IAAE,EAAE,GAAE,EAAE,GAAE,IAAE,IAAE,IAAE,IAAE,IAAE,CAAC,GAAE,IAAE,GAAE,IAAE,GAAE,IAAE,GAAE,IAAE,EAAE,GAAE,CAAC,GAAE,IAAE,GAAE,IAAE,GAAE,IAAE,GAAE,IAAE,EAAE,GAAE,CAAC;OAAE,EAAE,KAAG,EAAE,GAAE,EAAE,EAAE,GAAE,EAAE,KAAG,EAAE,GAAE,EAAE,EAAE,GAAE,EAAE,KAAG,EAAE,GAAE,EAAE,EAAE,GAAE,EAAE,KAAG,EAAE,GAAE,EAAE,EAAE,GAAE,EAAE,KAAG,EAAE,GAAE,EAAE,EAAE,GAAE,EAAE,KAAG,EAAE,GAAE,EAAE,EAAE,GAAE,EAAE,KAAG,EAAE,GAAE,EAAE,EAAE,GAAE,EAAE,KAAG,EAAE,GAAE,EAAE,EAAE;MAAC;MAAC,OAAO;KAAC;KAAC,IAAI,IAAE,EAAE,WAAW,GAAE,IAAE,SAAS,GAAE,GAAE;MAAC,OAAO,MAAI,IAAE,KAAG,KAAG;KAAC,GAAE,IAAE,SAAS,GAAE,GAAE;MAAC,OAAO,MAAI;KAAC;KAAE,EAAE,UAAQ,SAAS,GAAE;MAAC,OAAO,EAAE,KAAK,GAAE,GAAE,IAAG,CAAC,CAAC;KAAC;IAAC,EAAA,CAAE,KAAK,MAAK,EAAE,QAAQ,GAAE,eAAa,OAAO,OAAK,OAAK,eAAa,OAAO,SAAO,SAAO,CAAC,GAAE,EAAE,QAAQ,CAAC,CAAC,QAAO,UAAU,IAAG,UAAU,IAAG,UAAU,IAAG,UAAU,IAAG,0EAAyE,8DAA8D;GAAC,GAAE;IAAC,aAAY;IAAE,QAAO;IAAE,QAAO;GAAE,CAAC;GAAE,IAAG,CAAC,SAAS,GAAE,GAAE,GAAE;IAAC,CAAC,SAAS,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE;KAAC,EAAE,OAAK,SAAS,GAAE,GAAE,GAAE,GAAE,GAAE;MAAC,IAAI,GAAE,GAAE,IAAE,IAAE,IAAE,IAAE,GAAE,KAAG,KAAG,KAAG,GAAE,IAAE,KAAG,GAAE,IAAE,IAAG,IAAE,IAAE,IAAE,IAAE,GAAE,IAAE,IAAE,KAAG,GAAE,IAAE,EAAE,IAAE;MAAG,KAAI,KAAG,GAAE,IAAE,KAAG,KAAG,CAAC,KAAG,GAAE,MAAI,CAAC,GAAE,KAAG,GAAE,IAAE,GAAE,IAAE,MAAI,IAAE,EAAE,IAAE,IAAG,KAAG,GAAE,KAAG;MAAG,KAAI,IAAE,KAAG,KAAG,CAAC,KAAG,GAAE,MAAI,CAAC,GAAE,KAAG,GAAE,IAAE,GAAE,IAAE,MAAI,IAAE,EAAE,IAAE,IAAG,KAAG,GAAE,KAAG;MAAG,IAAG,MAAI,GAAE,IAAE,IAAE;WAAM;OAAC,IAAG,MAAI,GAAE,OAAO,IAAE,MAAI,YAAK,IAAE,KAAG;OAAG,KAAG,KAAK,IAAI,GAAE,CAAC,GAAE,KAAG;MAAC;MAAC,QAAO,IAAE,KAAG,KAAG,IAAE,KAAK,IAAI,GAAE,IAAE,CAAC;KAAC,GAAE,EAAE,QAAM,SAAS,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE;MAAC,IAAI,GAAE,GAAE,IAAE,IAAE,IAAE,IAAE,GAAE,KAAG,KAAG,KAAG,GAAE,IAAE,KAAG,GAAE,IAAE,OAAK,IAAE,KAAK,IAAI,GAAE,GAAG,IAAE,KAAK,IAAI,GAAE,GAAG,IAAE,GAAE,IAAE,IAAE,IAAE,IAAE,GAAE,IAAE,IAAE,IAAE,IAAG,IAAE,IAAE,KAAG,MAAI,KAAG,IAAE,IAAE,IAAE,IAAE;MAAE,KAAI,IAAE,KAAK,IAAI,CAAC,GAAE,MAAM,CAAC,KAAG,MAAI,YAAK,IAAE,MAAM,CAAC,IAAE,IAAE,GAAE,IAAE,MAAI,IAAE,KAAK,MAAM,KAAK,IAAI,CAAC,IAAE,KAAK,GAAG,GAAE,KAAG,IAAE,KAAK,IAAI,GAAE,CAAC,CAAC,KAAG,MAAI,KAAI,KAAG,IAAG,MAAI,KAAG,KAAG,IAAE,IAAE,IAAE,IAAE,IAAE,KAAK,IAAI,GAAE,IAAE,CAAC,KAAG,MAAI,KAAI,KAAG,IAAG,KAAG,IAAE,KAAG,IAAE,GAAE,IAAE,KAAG,KAAG,IAAE,KAAG,KAAG,IAAE,IAAE,KAAG,KAAK,IAAI,GAAE,CAAC,GAAE,KAAG,MAAI,IAAE,IAAE,KAAK,IAAI,GAAE,IAAE,CAAC,IAAE,KAAK,IAAI,GAAE,CAAC,GAAE,IAAE,KAAI,KAAG,GAAE,EAAE,IAAE,KAAG,MAAI,GAAE,KAAG,GAAE,KAAG,KAAI,KAAG;MAAG,KAAI,IAAE,KAAG,IAAE,GAAE,KAAG,GAAE,IAAE,GAAE,EAAE,IAAE,KAAG,MAAI,GAAE,KAAG,GAAE,KAAG,KAAI,KAAG;MAAG,EAAE,IAAE,IAAE,MAAI,MAAI;KAAC;IAAC,EAAA,CAAE,KAAK,MAAK,EAAE,QAAQ,GAAE,eAAa,OAAO,OAAK,OAAK,eAAa,OAAO,SAAO,SAAO,CAAC,GAAE,EAAE,QAAQ,CAAC,CAAC,QAAO,UAAU,IAAG,UAAU,IAAG,UAAU,IAAG,UAAU,IAAG,+DAA8D,oDAAoD;GAAC,GAAE;IAAC,QAAO;IAAE,QAAO;GAAE,CAAC;GAAE,IAAG,CAAC,SAAS,GAAE,GAAE,GAAE;IAAC,CAAC,SAAS,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE,GAAE;KAAC,IAAI,GAAE,GAAE;KAAE,SAAS,IAAG,CAAC;KAAC,CAAC,IAAE,EAAE,UAAQ,CAAC,EAAA,CAAG,YAAU,IAAE,eAAa,OAAO,UAAQ,OAAO,cAAa,IAAE,eAAa,OAAO,UAAQ,OAAO,eAAa,OAAO,kBAAiB,IAAE,SAAS,GAAE;MAAC,OAAO,OAAO,aAAa,CAAC;KAAC,IAAE,KAAG,IAAE,CAAC,GAAE,OAAO,iBAAiB,WAAU,SAAS,GAAE;MAAC,IAAI,IAAE,EAAE;MAAO,MAAI,UAAQ,SAAO,KAAG,mBAAiB,EAAE,SAAO,EAAE,gBAAgB,GAAE,IAAE,EAAE,UAAQ,EAAE,MAAM,CAAC,CAAC;KAAE,GAAE,CAAC,CAAC,GAAE,SAAS,GAAE;MAAC,EAAE,KAAK,CAAC,GAAE,OAAO,YAAY,gBAAe,GAAG;KAAC,KAAG,SAAS,GAAE;MAAC,WAAW,GAAE,CAAC;KAAC,IAAG,EAAE,QAAM,WAAU,EAAE,UAAQ,CAAC,GAAE,EAAE,MAAI,CAAC,GAAE,EAAE,OAAK,CAAC,GAAE,EAAE,KAAG,GAAE,EAAE,cAAY,GAAE,EAAE,OAAK,GAAE,EAAE,MAAI,GAAE,EAAE,iBAAe,GAAE,EAAE,qBAAmB,GAAE,EAAE,OAAK,GAAE,EAAE,UAAQ,SAAS,GAAE;MAAC,MAAM,IAAI,MAAM,kCAAkC;KAAC,GAAE,EAAE,MAAI,WAAU;MAAC,OAAM;KAAG,GAAE,EAAE,QAAM,SAAS,GAAE;MAAC,MAAM,IAAI,MAAM,gCAAgC;KAAC;IAAC,EAAA,CAAE,KAAK,MAAK,EAAE,QAAQ,GAAE,eAAa,OAAO,OAAK,OAAK,eAAa,OAAO,SAAO,SAAO,CAAC,GAAE,EAAE,QAAQ,CAAC,CAAC,QAAO,UAAU,IAAG,UAAU,IAAG,UAAU,IAAG,UAAU,IAAG,iEAAgE,oDAAoD;GAAC,GAAE;IAAC,QAAO;IAAE,QAAO;GAAE,CAAC;EAAC,GAAE,CAAC,GAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAC,CAAC;;;;;;;;;;;;;;AC+Bt9jC,IAAM,uCAAuB,IAAI,IAAI;CAAC;CAAa;CAAe;AAAW,CAAC;;;;;;;;;;AAgB9E,SAAgB,wBAAwB,KAAsB;CAC1D,OAAO,qBAAqB,IAAI,GAAG;AACvC;;;;;;AAqFA,SAAgB,UAAa,OAAa;CACtC,IAAI,UAAU,QAAQ,UAAU,KAAA,GAAW,OAAO;CAClD,IAAI,OAAO,UAAU,YAAY,OAAO;CACxC,IAAI,OAAO,UAAU,UAAU,OAAO;CAEtC,IAAI,MAAM,QAAQ,KAAK,GACnB,OAAO,MAAM,KAAI,SAAQ,UAAU,IAAI,CAAC;CAI5C,IAAI,OAAO,eAAe,KAAK,MAAM,OAAO,WACxC,OAAO;CAGX,MAAM,SAAkC,CAAC;CACzC,KAAK,MAAM,OAAO,OAAO,KAAK,KAAK,GAC/B,OAAO,OAAO,UAAW,MAAkC,IAAI;CAEnE,OAAO;AACX;AAgBA,SAAgB,SAAS,MAAgD;CACrE,OAAO,CAAC,CAAC,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI;AACpE;AAEA,SAAgB,cAAc,KAA8C;CAExE,IAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,MAAM,QAAQ,GAAG,GAC5D,OAAO;CAOX,OAHc,OAAO,eAAe,GAG7B,MAAU,OAAO;AAC5B;AAEA,SAAgB,UACZ,QACA,QACA,kBAAkB,OACb;CAEL,IAAI,CAAC,SAAS,MAAM,GAChB,OAAO;CAIX,MAAM,SAAS,EAAE,GAAG,OAAO;CAI3B,IAAI,CAAC,SAAS,MAAM,GAChB,OAAO;CAIX,KAAK,MAAM,OAAO,QAAQ;EACtB,IAAI,QAAQ,eAAe,QAAQ,iBAAiB,QAAQ,aACxD;EAEJ,IAAI,OAAO,UAAU,eAAe,KAAK,QAAQ,GAAG,GAAG;GACnD,MAAM,cAAc,OAAO;GAC3B,MAAM,cAAe,OAAmC;GAIxD,IAAI,mBAAmB,gBAAgB,KAAA,GACnC;GAGJ,IAAI,uBAAuB,MAEvB,OAAoC,OAAO,IAAI,KAAK,YAAY,QAAQ,CAAC;QACtE,IAAI,MAAM,QAAQ,WAAW,GAChC,IAAI,MAAM,QAAQ,WAAW,GAIzB,IAAI,EADoB,YAAY,KAAK,aAAa,KAAK,YAAY,KAAK,aAAa,IAErF,OAAoC,OAAO,CAAC,GAAG,WAAW;QACvD;IACH,MAAM,WAAW,CAAC;IAClB,MAAM,YAAY,KAAK,IAAI,YAAY,QAAQ,YAAY,MAAM;IACjE,KAAK,IAAI,IAAI,GAAG,IAAI,WAAW,KAAK;KAChC,MAAM,aAAa,YAAY;KAC/B,MAAM,aAAa,YAAY;KAE/B,IAAI,KAAK,YAAY,QACjB,SAAS,KAAK;UACX,IAAI,KAAK,YAAY,QACxB,SAAS,KAAK;UACX,IAAI,eAAe,MACtB,SAAS,KAAK;UACX,IAAI,cAAc,UAAU,KAAK,cAAc,UAAU,GAE5D,SAAS,KAAK,UAAU,YAAY,YAAY,eAAe;UAG/D,SAAS,KAAK;IAEtB;IACA,OAAoC,OAAO;GAC/C;QAIA,OAAoC,OAAO,CAAC,GAAG,WAAW;QAE3D,IAAI,cAAc,WAAW,GAEhC,IAAI,cAAc,WAAW,GAGzB,OAAoC,OAAO,UAAU,aAAwC,aAAa,eAAe;QAIzH,OAAoC,OAAO;QAE5C,IAAI,SAAS,WAAW,GAE3B,OAAoC,OAAO;QAG3C,OAAoC,OAAO;EAEnD;CACJ;CAEA,OAAO;AACX;AA+CA,SAAgB,gBAAgB,GAAqB;CACjD,IAAI,MAAM,KAAA,GAAW,OAAO,KAAA;CAC5B,IAAI,MAAM,MAAM,OAAO;CACvB,IAAI,OAAO,MAAM,UAAU;EAKvB,IAAI,MAAM,QAAQ,CAAC,GACf,OAAO,EACF,QAAO,MAAK,OAAO,MAAM,UAAU,CAAC,CACpC,KAAI,MAAK,gBAAgB,CAAC,CAAC;EAGpC,IAAI,CAAC,cAAc,CAAC,GAChB,OAAO;EAEX,OAAO,OAAO,QAAQ,CAAC,CAAC,CACnB,QAAQ,CAAC,GAAG,WAAW,OAAO,UAAU,UAAU,CAAC,CACnD,QAAiC,KAAK,CAAC,KAAK,WAAW;GACpD,IAAI,OAAO,gBAAgB,KAAK;GAChC,OAAO;EACX,GAAG,CAAC,CAAC;CACb;CACA,OAAO;AACX;;;;;;;;;;;;;;;;;ACjVA,SAAS,KAAK,OAAe,GAAmB;CAC5C,OAAQ,SAAS,IAAM,UAAW,KAAK;AAC3C;;;;;;;AAQA,SAAgB,QAAQ,OAAuB;CAC3C,MAAM,QAAkB,MAAM,KAAK,IAAI,YAAY,CAAC,CAAC,OAAO,KAAK,CAAC;CAClE,MAAM,YAAY,MAAM,SAAS;CAIjC,MAAM,KAAK,GAAI;CACf,OAAO,MAAM,SAAS,OAAO,IAAI,MAAM,KAAK,CAAC;CAE7C,MAAM,KAAK,KAAK,MAAM,YAAY,UAAW;CAC7C,MAAM,KAAK,cAAc;CACzB,MAAM,KAAM,OAAO,KAAM,KAAO,OAAO,KAAM,KAAO,OAAO,IAAK,KAAM,KAAK,GAAI;CAC/E,MAAM,KAAM,OAAO,KAAM,KAAO,OAAO,KAAM,KAAO,OAAO,IAAK,KAAM,KAAK,GAAI;CAE/E,IAAI,KAAK;CACT,IAAI,KAAK;CACT,IAAI,KAAK;CACT,IAAI,KAAK;CACT,IAAI,KAAK;CAET,MAAM,IAAI,IAAI,MAAc,EAAE;CAE9B,KAAK,IAAI,SAAS,GAAG,SAAS,MAAM,QAAQ,UAAU,IAAI;EACtD,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK;GACzB,MAAM,IAAI,SAAS,IAAI;GACvB,EAAE,KAAO,MAAM,MAAM,KAAO,MAAM,IAAI,MAAM,KAAO,MAAM,IAAI,MAAM,IAAK,MAAM,IAAI,KAAM;EAC5F;EACA,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,KACrB,EAAE,KAAK,KAAK,EAAE,IAAI,KAAK,EAAE,IAAI,KAAK,EAAE,IAAI,MAAM,EAAE,IAAI,KAAK,CAAC;EAG9D,IAAI,IAAI;EACR,IAAI,IAAI;EACR,IAAI,IAAI;EACR,IAAI,IAAI;EACR,IAAI,IAAI;EAER,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK;GACzB,IAAI;GACJ,IAAI;GACJ,IAAI,IAAI,IAAI;IACR,IAAK,IAAI,IAAM,CAAC,IAAI;IACpB,IAAI;GACR,OAAO,IAAI,IAAI,IAAI;IACf,IAAI,IAAI,IAAI;IACZ,IAAI;GACR,OAAO,IAAI,IAAI,IAAI;IACf,IAAK,IAAI,IAAM,IAAI,IAAM,IAAI;IAC7B,IAAI;GACR,OAAO;IACH,IAAI,IAAI,IAAI;IACZ,IAAI;GACR;GAEA,MAAM,OAAQ,KAAK,GAAG,CAAC,IAAI,IAAI,IAAI,IAAI,EAAE,KAAM;GAC/C,IAAI;GACJ,IAAI;GACJ,IAAI,KAAK,GAAG,EAAE;GACd,IAAI;GACJ,IAAI;EACR;EAEA,KAAM,KAAK,IAAK;EAChB,KAAM,KAAK,IAAK;EAChB,KAAM,KAAK,IAAK;EAChB,KAAM,KAAK,IAAK;EAChB,KAAM,KAAK,IAAK;CACpB;CAEA,OAAO;EAAC;EAAI;EAAI;EAAI;EAAI;CAAE,CAAC,CACtB,KAAI,UAAS,SAAS,EAAA,CAAG,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC,CACvD,KAAK,EAAE;AAChB;;;;;;;;;;;;;;;;;AC/EA,SAAgB,kBAAkB,MAA4B;CAc1D,OAAO,QAbM,KAAK,UAAU;EACxB,GAAG,KAAK;EACR,GAAG,KAAK;EACR,IAAI,KAAK;EACT,KAAK,KAAK,YAAY,MAAM,CAAC,CAAC,KAAK;EACnC,KAAK,KAAK;EACV,KAAK,KAAK,OAAO,MAAM,CAAC,CAAC,KAAK;EAC9B,IAAI,KAAK,SAAS,MAAM,CAAC,CAAC,KAAK;EAC/B,GAAG,KAAK;EACR,GAAG,KAAK;EACR,GAAG,KAAK;EACR,IAAI,KAAK;CACb,CACe,CAAI,CAAC,CAAC,UAAU,GAAG,CAAC;AACvC;;AAGA,SAAgB,oBAAoB,MAAkD;CAClF,OAAO,KAAK,cAAc,KAAK,WAAW,SAAS,IAC7C,KAAK,aACL,CAAC,KAAK,aAAa,KAAK;AAClC;;;;;;;AAQA,SAAgB,sBAAsB,MAAoB,WAA6B;CACnF,MAAM,MAAM,oBAAoB,IAAI;CACpC,MAAM,WAAW,kBAAkB,IAAI;CAEvC,OAAO,IAAI,KAAK,IAAI,UAAU,KAAK,OAC5B,IAAI,SAAS,IAAI,GAAG,KAAK,KAAK,GAAG,OAAO,KAAK,OAC9C,GAAG,UAAU,GAAG,GAAG,GAAG,WAAW,IAAI,SAAS,IAAI,IAAI,UAAU,IAAI;AAC9E;;;;;;;;;;AC0CA,SAAgB,SAAS,MAAc,QAAyB;CAC5D,IAAI,WAAW,KAAA,KAAa,WAAW,GACnC,OAAO;CAEX,MAAM,YAAuC;EACzC,cAAc;EACd,eAAe;EACf,mBAAmB;EACnB,YAAY;EACZ,cAAc;EACd,iBAAiB;EACjB,qBAAqB;EACrB,YAAY;EACZ,UAAU;EACV,YAAY;EACZ,eAAe;EACf,mBAAmB;EACnB,aAAa;EACb,aAAa;EACb,sBAAsB;EACtB,cAAc;EACd,YAAY;EACZ,YAAY;EACZ,mBAAmB;EACnB,2BAA2B;EAC3B,gBAAgB;EAChB,iEAAiE;EACjE,YAAY;EACZ,WAAW;EACX,gBAAgB;EAChB,cAAc;EACd,WAAW;EACX,IAAI;CACR;CACA,MAAM,YAAuC;EACzC,MAAM;EACN,MAAM;EACN,OAAO;EACP,KAAK;EACL,OAAO;EACP,KAAK;EACL,OAAO;EACP,QAAQ;CACZ;CA6BA,IAAI;EA3BA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CAGA,CAAA,CAAY,QAAQ,KAAK,YAAY,CAAC,KAAK,GAC3C,OAAO;CAGX,KAAK,MAAM,KAAK,WAAW;EACvB,MAAM,UAAU,IAAI,OAAO,GAAG,UAAU,GAAG,IAAI,GAAG;EAClD,IAAI,QAAQ,KAAK,IAAI,GACjB,OAAO,KAAK,QAAQ,SAAS,CAAC;CAEtC;CAEA,KAAK,MAAM,OAAO,WAAW;EACzB,MAAM,UAAU,IAAI,OAAO,KAAK,GAAG;EACnC,IAAI,QAAQ,KAAK,IAAI,GACjB,OAAO,KAAK,QAAQ,SAAS,UAAU,IAAI;CAEnD;CACA,OAAO;AACX;;;;;;;;;;;;;;;;;;;;;;;;;;ACjKA,SAAgB,uBAAuB,MAAsB;CACzD,OAAO,GAAG,YAAY,kBAAkB,IAAI,CAAC,EAAE;AACnD;;;;;;;;;;AAWA,SAAS,kBAAkB,MAAsB;CAC7C,IAAI,OAAO,KAAK,IAAI,GAAG,OAAO;CAC9B,MAAM,SAAS,SAAS,IAAI;CAC5B,OAAO,OAAO,SAAS,IAAI,SAAS;AACxC;;;;;;;;;;;;;;;;;AAkBA,SAAgB,qBAAqB,MAAsB;CACvD,MAAM,QAAQ,YAAY,IAAI;CAC9B,OAAO,GAAG,MAAM,SAAS,GAAG,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI,MAAM;AAC/D;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,qBAAqB,MAAsB;CACvD,MAAM,QAAQ,IAAI,YAAY,CAAC,CAAC,OAAO,IAAI;CAC3C,IAAI,MAAM,cAAc,IAAI,OAAO;CAGnC,OAAO,IAAI,YAAY,OAAO,CAAC,CAAC,OAAO,MAAM,SAAS,GAAG,EAAE,CAAC,CAAC,CAAC,QAAQ,OAAO,EAAE;AACnF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,SAAgB,UAAU,YAA4B;CAClD,IAAI,CAAC,YAAY,OAAO;CACxB,MAAM,WAAW,WAAW,MAAM,QAAQ,CAAC,CAAC,OAAO,OAAO;CAC1D,IAAI,SAAS,UAAU,GAAG,OAAO;CACjC,OAAO,SACF,KAAK,SAAS,UACX,UAAU,IACJ,QAAQ,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,QAAQ,MAAM,CAAC,IACjD,QAAQ,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,QAAQ,MAAM,CAAC,CAAC,CAAC,CAC5D,KAAK,EAAE;AAChB;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,aAAa,YAAsB,OAA8C;CAC7F,KAAK,MAAM,aAAa,YACpB,IAAI,CAAC,MAAM,IAAI,SAAS,GAAG,OAAO;CAEtC,MAAM,OAAO,WAAW,WAAW,SAAS;CAC5C,KAAK,IAAI,SAAS,IAAK,UAAU;EAC7B,MAAM,YAAY,GAAG,KAAK,GAAG;EAC7B,IAAI,CAAC,MAAM,IAAI,SAAS,GAAG,OAAO;CACtC;AACJ;;;;;;;AChGA,SAAgB,qBAAwD,EACpE,aACA,YACA,QACA,qBAOoB;CACpB,OAAO,yBACH,aACA,aACC,YAAY,aAAa;EACtB,IAAI,SAAS,SAAS,QAClB,IAAI,WAAW,cAAc,SAAS,cAAc,aAChD,OAAO;OACJ,KAAK,WAAW,SAAS,WAAW,YACtC,SAAS,cAAc,eAAe,SAAS,cAAc,cAC9D,OAAO;OAEP,OAAO;OAGX,OAAO;CAEf,CACJ,KAAK,CAAC;AACV;;;;;;;;;;;;;;;;;;;AAuDA,SAAgB,0BAA0B,OAAgB,cAAuB,YAA4C;CACzH,IAAI,iBAAiB,gBAAgB,OAAO;CAE5C,IAAI,eAAe,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW;EAExE,IAAI,UAAU,IAAI,OAAO;EACzB,OAAO,IAAI,eAAe,OAAO,UAAU;CAC/C;CAEA,IAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG,OAAO;CAExE,MAAM,MAAM;CAQZ,IAAI,EANA,IAAI,WAAW,cACf,IAAI,WAAW,eACd,OAAO,IAAI,qBAAqB,cAAe,IAAI,iBAAmC,KACtF,OAAO,IAAI,sBAAsB,cAAe,IAAI,kBAAoC,KACxF,iBAAiB,cAAc,OAAO,IAAI,OAAO,eAAe,OAAO,IAAI,SAAS,WAEpE,OAAO;CAE5B,OAAO,IAAI,eACP,IAAI,IACJ,IAAI,MACJ,IAAI,IACR;AACJ;AAEA,SAAgB,yBACZ,aACA,YACA,WAC2B;CAE3B,MAAM,kBAAkB,eAAe,CAAC;CAaxC,MAAM,SAAS,UAAU,iBAXH,OAAO,QAAQ,UAAU,CAAC,CAC3C,KAAK,CAAC,KAAK,cAAc;EAEtB,MAAM,eAAe,sBADF,mBAAoB,gBAAiB,MACD,UAAsB,SAAS;EACtF,IAAI,iBAAiB,MAAM,OAAO;EAClC,IAAI,iBAAiB,KAAA,GAAW,OAAO,KAAA;EACvC,OAAQ,GAAG,MAAM,aAAa;CAClC,CAAC,CAAC,CACD,QAAQ,GAAG,OAAO;EAAE,GAAG;EAChC,GAAG;CAAE,IAAI,CAAC,CAEoC,CAAa;CACvD,IAAI,CAAC,UAAU,OAAO,KAAK,MAAM,CAAC,CAAC,WAAW,GAAG,OAAO,KAAA;CACxD,OAAO;AACX;AAEA,SAAgB,sBAAsB,YAClC,UACA,WAAqE;CAErE,IAAI;CACJ,IAAI,SAAS,SAAS,SAAS,SAAS,YACpC,QAAQ,yBAAyB,YAAgD,SAAS,YAAY,SAAS;MAC5G,IAAI,SAAS,SAAS,SAAS;EAClC,MAAM,KAAK,SAAS;EACpB,IAAI,MAAM,MAAM,QAAQ,UAAU,KAAK,CAAC,MAAM,QAAQ,EAAE,GACpD,QAAQ,WAAW,KAAK,MAAM,sBAAsB,GAAG,IAAI,SAAS,CAAC;OAClE,IAAI,MAAM,MAAM,QAAQ,UAAU,KAAK,MAAM,QAAQ,EAAE,GAC1D,QAAQ,WAAW,KAAK,GAAG,MAAM;GAC7B,IAAI,IAAI,GAAG,QACP,OAAO,sBAAsB,GAAG,GAAG,IAAI,SAAS;GACpD,OAAO;EACX,CAAC,CAAC,CAAC,OAAO,OAAO;OACd,IAAI,SAAS,SAAS,MAAM,QAAQ,UAAU,GAAG;GACpD,MAAM,YAAY,SAAS,OAAO,aAAA;GAClC,MAAM,aAAa,SAAS,OAAO,cAAA;GACnC,QAAQ,WAAW,KAAK,MAAM;IAC1B,IAAI,MAAM,MAAM,OAAO;IACvB,IAAI,OAAO,MAAM,UAAU,OAAO;IAClC,MAAM,MAAM;IACZ,MAAM,OAAO,IAAI;IACjB,MAAM,gBAAgB,SAAS,OAAO,WAAW;IACjD,IAAI,CAAC,QAAQ,CAAC,eAAe,OAAO;IACpC,OAAO;MACF,YAAY;MACZ,aAAa,sBAAsB,IAAI,aAAa,eAAe,SAAS;IACjF;GACJ,CAAC;EACL,OACI,QAAQ;CAEhB,OACI,QAAQ,UAAU,YAAY,QAAQ;CAG1C,OAAO;AACX;;;;;AAoBA,SAAgB,kBAAkB,IAAqB,MAA2B;CAC9E,OAAO;EAAE;EACb;EACA,QAAQ;CAAW;AACnB;;;;;AAMA,SAAgB,0BAA0B,IAAqB,MAAc,MAAmC;CAC5G,OAAO;EAAE;EACb;EACA,QAAQ;EACR;CAAK;AACL;;;;;;;;;;;;;;;;;ACtLA,SAAgB,sBAAmD,aAAgC;CAC/F,OAAO,CAAC,GAAG,WAAW,CAAC,CAAC,MAAM,GAAG,OAAO,EAAE,QAAQ,GAAA,CAAI,cAAc,EAAE,QAAQ,EAAE,CAAC;AACrF;;ACrEA,IAAM,eAAe;;AAGrB,SAAS,kBAAkB,MAAuB,IAA6B;CAC3E,IAAI,GAAG,QAAQ,OAAO,aAAa,KAAK,OAAO,IAAI,CAAC;CACpD,IAAI,GAAG,SAAS,UACZ,OAAO,OAAO,SAAS,WACjB,OAAO,SAAS,IAAI,IACpB,CAAC,MAAM,SAAS,OAAO,IAAI,GAAG,EAAE,CAAC;CAE3C,OAAO;AACX;;;;;;;;;;;;;;AAeA,SAAgB,gBAAgB,SAA0B,aAAwC;CAC9F,IAAI,YAAY,WAAW,GAAG,OAAO;CACrC,IAAI,YAAY,WAAW,GAAG,OAAO,kBAAkB,SAAS,YAAY,EAAE;CAE9E,MAAM,QAAQ,OAAO,OAAO,CAAC,CAAC,MAAA,KAA4B;CAC1D,IAAI,MAAM,WAAW,YAAY,QAAQ,OAAO;CAChD,OAAO,MAAM,OAAO,MAAM,MAAM,kBAAkB,MAAM,YAAY,EAAE,CAAC;AAC3E;;;;;;;;AASA,SAAgB,iBAAiB,QAAiC,aAAuC;CACrG,IAAI,YAAY,WAAW,GACvB,OAAO;CAEX,IAAI,YAAY,WAAW,GACvB,OAAO,OAAO,OAAO,YAAY,EAAE,CAAC,cAAc,EAAE;CAExD,OAAO,YAAY,KAAI,OAAM,OAAO,OAAO,GAAG,cAAc,EAAE,CAAC,CAAC,CAAC,KAAA,KAA2B;AAChG;;;;;;;;;AAUA,SAAgB,cAAc,SAA0B,aAAgE;CACpH,MAAM,SAA0C,CAAC;CAEjD,IAAI,YAAY,WAAW,GACvB,OAAO;CAGX,IAAI,YAAY,WAAW,GAAG;EAC1B,MAAM,KAAK,YAAY;EACvB,IAAI,GAAG,SAAS,YAAY,CAAC,GAAG,QAAQ;GACpC,MAAM,SAAS,OAAO,YAAY,WAAW,UAAU,SAAS,OAAO,OAAO,GAAG,EAAE;GACnF,IAAI,MAAM,MAAM,GACZ,MAAM,IAAI,MAAM,uBAAuB,SAAS;GAEpD,OAAO,GAAG,aAAa;EAC3B,OACI,OAAO,GAAG,aAAa,OAAO,OAAO;EAEzC,OAAO;CACX;CAGA,MAAM,QAAQ,OAAO,OAAO,CAAC,CAAC,MAAA,KAA4B;CAC1D,IAAI,MAAM,WAAW,YAAY,QAC7B,MAAM,IAAI,MAAM,yCAAyC,YAAY,OAAO,QAAQ,MAAM,OAAO,WAAW,SAAS;CAGzH,KAAK,IAAI,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK;EACzC,MAAM,KAAK,YAAY;EACvB,MAAM,MAAM,MAAM;EAClB,IAAI,GAAG,SAAS,YAAY,CAAC,GAAG,QAAQ;GACpC,MAAM,SAAS,SAAS,KAAK,EAAE;GAC/B,IAAI,MAAM,MAAM,GACZ,MAAM,IAAI,MAAM,iCAAiC,KAAK;GAE1D,OAAO,GAAG,aAAa;EAC3B,OACI,OAAO,GAAG,aAAa;CAE/B;CAEA,OAAO;AACX;;;;;;;;;;;;;;;;AAiBA,SAAgB,uBAAuB,YAElB;CACjB,MAAM,aAAa,WAAW;CAC9B,IAAI,CAAC,YAAY,OAAO,CAAC;CAEzB,MAAM,OAAyB,CAAC;CAChC,KAAK,MAAM,CAAC,WAAW,YAAY,OAAO,QAAQ,UAAU,GAAG;EAC3D,MAAM,OAAO;EACb,IAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;EACvC,IAAI,EAAE,UAAU,SAAS,CAAC,KAAK,MAAM;EACrC,KAAK,KAAK;GACN;GACA,MAAM,KAAK,SAAS,WAAW,WAAW;GAC1C,QAAQ,KAAK,SAAS;EAC1B,CAAC;CACL;CACA,OAAO;AACX;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,mBAAmB,YAEd;CACjB,MAAM,WAAW,uBAAuB,UAAU;CAClD,IAAI,SAAS,SAAS,GAAG,OAAO;CAEhC,MAAM,SAAS,WAAW,YAAY;CACtC,IAAI,UAAU,OAAO,WAAW,UAC5B,OAAO,CAAC;EAAE,WAAW;EAC7B,MAAM,OAAO,SAAS,WAAW,WAAW;CAAS,CAAC;CAGlD,OAAO,CAAC;AACZ;;;ACvMA,SAAgB,oBAAoB,YAA2C;CAC3E,IAAI,MAAM,QAAQ,UAAU,GACxB,OAAO;MAEP,OAAO,OAAO,QAAQ,UAAU,CAAC,CAAC,KAAK,CAAC,IAAI,WAAW;EACnD,IAAI,OAAO,UAAU,UACjB,OAAO;GACH;GACA,OAAO;EACX;OAEA,OAAO;GACH,GAAG;GACH;EACJ;CAER,CAAC;AAET;;;;;;;;;;;;;;;;;;;;ACMA,SAAgB,gBACZ,UACA,kBACA,aACgB;CAChB,MAAM,SAAS,SAAS;CACxB,IAAI,OAAO,WAAW,YAClB,MAAM,IAAI,MACN,WAAW,SAAS,eAAe,KAAK,SAAS,aAAa,KAAK,GAAG,OAClE,iBAAiB,KAAK,yEAC9B;CAGJ,MAAM,mBAAmB,WAAW,UAAU,kBAAkB,aAAa,MAAM;CAKnF,MAAM,eAAe,SAAS,gBAAgB,eAAe,YAAY,iBAAiB,IAAI;CAE9F,MAAM,SAAkI;EACpI;EAQA,cAAc,sBAAsB,OAAO,CAAC;EAC5C,YAAY,iBAAiB;EAC7B,UAAU,SAAS;EACnB,UAAU,SAAS;EACnB,WAAW,SAAS;EACpB,YAAY,SAAS;CACzB;CAEA,MAAM,aAAa,YAAY,iBAAiB,QAAQ,iBAAiB,IAAI;CAE7E,QAAQ,SAAS,MAAjB;EACI,KAAK,aACD,OAAO;GACH,GAAG;GACH,MAAM;GACN,aAAa;GACb,UAAU;GACV,QAAQ;GACR,UAAU,SAAS,YAAY,uBAAuB,YAAY;EACtE;EAEJ,KAAK,UACD,OAAO;GACH,GAAG;GACH,MAAM;GACN,aAAa;GACb,UAAU;GACV,QAAQ;GACR,oBAAoB,SAAS,sBAAsB,uBAAuB,UAAU;GACpF,WAAW,SAAS;EACxB;EAEJ,KAAK,WACD,OAAO;GACH,GAAG;GACH,MAAM;GACN,aAAa;GACb,UAAU;GACV,QAAQ;GACR,oBAAoB,SAAS,sBAAsB,uBAAuB,UAAU;GAIpF,WAAW,SAAS;EACxB;EAEJ,KAAK,cAAc;GACf,MAAM,cAAc,aAAa,gBAAgB;GACjD,MAAM,cAAc,aAAa,gBAAgB;GACjD,OAAO;IACH,GAAG;IACH,MAAM;IACN,aAAa;IACb,UAAU;IACV,QAAQ;IACR,SAAS;KAGL,OAAO,SAAS,SAAS,SAAS,CAAC,aAAa,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG;KAC5E,cAAc,SAAS,SAAS,gBAAgB,uBAAuB,UAAU;KACjF,cAAc,SAAS,SAAS,gBAAgB,uBAAuB,YAAY;IACvF;GACJ;EACJ;EAEA,KAAK,OACD,OAAO;GACH,GAAG;GACH,MAAM;GACN,aAAa,SAAS;GACtB,UAAU;GAGV,QAAQ;GACR,UAAU,SAAS;EACvB;EAEJ,SAII,MAAM,IAAI,MAAM,0BAA0B,KAAK,UAAU,QAAU,GAAG;CAE9E;AACJ;;AAGA,SAAS,SAAS,UAAoB,kBAAoC,aAA8B;CACpG,MAAM,OAAO,SAAS,gBAAgB;CACtC,OAAO,WAAW,OAAO,KAAK,KAAK,KAAK,GAAG,OAAO,iBAAiB,KAAK;AAC5E;;;;;;;;;;;;;;;AAgBA,SAAS,sBAAsB,OAAyB;CACpD,IAAI,CAAC,SAAS,OAAO,UAAU,UAAU,OAAO;CAChD,IAAK,MAA6B,MAAM,OAAO;CAC/C,MAAM,QAAS,MAAgC;CAC/C,OAAO,SAAS,OAAO,UAAU,YAAa,MAA6B,OAAO,QAAQ;AAC9F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,SAAS,WACL,UACA,kBACA,aACA,QAC8B;CAC9B,IAAI;CACJ,IAAI;EACA,mBAAmB,sBAAsB,OAAO,CAAC;CACrD,SAAS,OAAO;EAGZ,IAAI,iBAAiB,gBACjB,MAAM,IAAI,MACN,GAAG,SAAS,UAAU,kBAAkB,WAAW,EAAE,wRAIrD,EAAE,OAAO,MAAM,CACnB;EAEJ,MAAM;CACV;CAEA,IAAI,CAAC,kBAAkB,MACnB,MAAM,IAAI,MACN,GAAG,SAAS,UAAU,kBAAkB,WAAW,EAAE,qCAClD,qBAAqB,KAAA,IAAY,gBAAgB,qCAAqC,OACxF,qBAAqB,KAAA,IAChB,8QAGA,OAAQ,iBAAwC,SAAS,aACrD,8LAGA,2DACd;CAGJ,OAAO;AACX;;;;;;;;;;;;;;;ACjOA,SAAgB,yBAAyB,UAAqC;CAC1E,OAAO,SAAS;AACpB;;AAGA,IAAM,0CAA0B,IAAI,QAA4D;;;;;;;;;;;;;;;AAgBhG,SAAgB,2BACZ,YACgC;CAChC,MAAM,SAAS,wBAAwB,IAAI,UAAU;CACrD,IAAI,QAAQ,OAAO;CAEnB,IAAI,CAAC,6BAA6B,UAAU,GAAG,OAAO,CAAC;CAEvD,MAAM,YAA8C,CAAC;CAErD,KAAK,MAAM,YAAY,WAAW,aAAa,CAAC,GAAG;EAC/C,MAAM,WAAW,gBAAgB,UAAU,UAAU;EACrD,UAAU,SAAS,gBAAgB;CACvC;CAKA,KAAK,MAAM,CAAC,aAAa,aAAa,OAAO,QAAQ,WAAW,cAAc,CAAC,CAAC,GAAG;EAC/E,IAAK,UAAuB,SAAS,YAAY;EACjD,MAAM,WAAY,SAA8B;EAChD,IAAI,CAAC,YAAY,UAAU,cAAc;EAEzC,UAAU,eAAe,gBAAgB,UAAU,YAAY,WAAW;CAC9E;CAEA,wBAAwB,IAAI,YAAY,SAAS;CACjD,OAAO;AACX;AAiCA,SAAgB,aAAa,YAAsC;CAC/D,IAAI,6BAA6B,UAAU,GACvC,OAAO,WAAW,SAAS,YAAY,WAAW,IAAI,KAAK,YAAY,WAAW,IAAI;CAE1F,OAAO,YAAY,WAAW,IAAI,KAAK,YAAY,WAAW,IAAI;AACtE;AAEA,SAAgB,gBAAgB,WAA2B;CACvD,OAAO,UAAU,QAAQ,cAAc,GAAG,SAAS,KAAK,YAAY,CAAC;AACzE;AAEA,SAAgB,eAAe,WAAmB,UAA0B;CAGxE,OAAO,GAFU,gBAAgB,SAEvB,IADM,SAAS,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,SAAS,MAAM,CAAC;AAEvE;AAEA,SAAgB,cAAc,YAA4B;CACtD,OAAO,WAAW,SAAS,GAAG,IAAI,WAAW,MAAM,GAAG,CAAC,CAAC,IAAI,IAAK;AACrE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,SAAgB,kBAAkB,YAA0C,QAAwB;CAChG,MAAM,aAAa,YAAY;CAC/B,IAAI,YAAY;EACZ,KAAK,MAAM,CAAC,KAAK,SAAS,OAAO,QAAQ,UAAU,GAAG;GAClD,MAAM,aAAc,MAA+C;GACnE,IAAI,OAAO,eAAe,YAAY,eAAe,QAAQ,OAAO;EACxE;EACA,KAAK,MAAM,OAAO,OAAO,KAAK,UAAU,GAAG;GACvC,IAAI,QAAQ,QAAQ,OAAO;GAC3B,IAAI,YAAY,GAAG,MAAM,QAAQ,OAAO;EAC5C;CACJ;CACA,OAAO,UAAU,MAAM;AAC3B;;;;;;;;;;AAWA,SAAgB,aACZ,mBACA,KAC4B;CAE5B,IAAI,kBAAkB,MAAM,OAAO,kBAAkB;CAGrD,MAAM,UAAU,IAAI,QAAQ,MAAM,GAAG;CACrC,IAAI,YAAY,OAAO,kBAAkB,UAAU,OAAO,kBAAkB;CAG5E,MAAM,WAAW,IAAI,QAAQ,MAAM,GAAG;CACtC,IAAI,aAAa,OAAO,kBAAkB,WAAW,OAAO,kBAAkB;AAGlF;;;;;;;;;;;;;;;;;;AC6LA,SAAgB,oBACZ,YACiB;CACjB,MAAM,oBAAoB,gBACtB,YAAY,OAAO,OAAO,CAAC,CAAC,KAAI,WAAU;EACtC,KAAK,MAAM;EACX,YAAY;EACZ,QAAQ,EAAE,MAAM,gBAAyB;CAC7C,EAAE;CAEN,IAAI,WAAW,kBACX,OAAO,iBAAiB,WAAW,iBAAiB,KAAK,CAAC,CAAC;CAG/D,MAAM,eAAe,0BAA0B,WAAW,MAAM;CAEhE,MAAM,yBAAyB,0BAA0B,UAAU;CACnE,IAAI,aAAa,0BAA0B,wBACvC,OAAO,iBAAiB,uBAAuB,KAAK,CAAC,CAAC;CAG1D,IAAI,CAAC,aAAa,mBAAmB,OAAO,CAAC;CAE7C,MAAM,oBAAoB,2BAA2B,UAAU;CAC/D,MAAM,QAA2B,CAAC;CAClC,MAAM,uBAAO,IAAI,IAAY;CAO7B,KAAK,MAAM,CAAC,aAAa,aAAa,OAAO,QAAQ,iBAAiB,GAAG;EACrE,IAAI,SAAS,gBAAgB,QAAQ;EAErC,MAAM,WAAW,SAAS,gBAAgB;EAC1C,IAAI,KAAK,IAAI,QAAQ,GAAG;EAExB,IAAI;EACJ,IAAI;GACA,SAAS,SAAS,OAAO;EAC7B,QAAQ;GACJ;EACJ;EACA,IAAI,CAAC,QAAQ;EACb,KAAK,IAAI,QAAQ;EAKjB,MAAM,aAFoB,OAAO,QAAS,WAAW,cAAc,CAAC,CAA8B,CAAC,CAC9F,MAAM,CAAC,SAAS,OAAO,EAAE,SAAS,eAAgB,EAAuB,UAAU,gBAAgB,aAAa,QAClG,CAAA,GAAoB,EAAE,EAAE;EAE3C,MAAM,OAAkD;GACpD,GAAG;GACH,MAAM;GACN,GAAI,aAAa;IAAE,MAAM;IACrC,cAAc;GAAW,IAAI,CAAC;EACtB;EAEA,MAAM,KAAK;GACP,KAAK;GACL,YAAa,SAAS,YAAY,UAAU,MAAM,SAAS,SAAS,IAAI;GACxE,QAAQ;IACJ,MAAM;IACN;IACA,MAAM,yBAAyB,QAAQ,IAAI,WAAW;IACtD,YAAY,OAAO;GACvB;EACJ,CAAC;CACL;CAEA,OAAO;AACX;;;;;;;;;AAkFA,SAAgB,kBAA+E,YAA8E;CACzK,OAAO,oBAAoB,UAAU,CAAC,CAAC,KAAI,SAAQ,KAAK,UAAU;AACtE;;;;;;;;;;;;;;;;;;;;;;;;;;;AC1fA,SAAS,YAAY,OAAe,GAAW,SAA0B;CACrE,IAAI,CAAC,MAAM,WAAW,SAAS,CAAC,GAAG,OAAO;CAC1C,MAAM,SAAS,MAAM,IAAI,MAAM,MAAM,IAAI;CACzC,MAAM,QAAQ,MAAM,IAAI,QAAQ,WAAW;CAC3C,OAAO,SAAS,KAAK,MAAM,KAAK,SAAS,KAAK,KAAK;AACvD;;;;;;;;;;;;;;;AAgBA,SAAS,cAAc,KAAa,SAAwC;CACxE,MAAM,QAAQ,IAAI,YAAY;CAC9B,MAAM,QAAkB,CAAC;CACzB,IAAI,QAAQ;CACZ,IAAI,WAAW;CACf,IAAI,QAAQ;CAEZ,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;EACjC,MAAM,KAAK,IAAI;EACf,IAAI,UAAU;GACV,IAAI,OAAO,KACP,IAAI,IAAI,IAAI,OAAO,KAAK;QACnB,WAAW;GAEpB;EACJ;EACA,IAAI,OAAO,KAAK;GAAE,WAAW;GAAM;EAAU;EAC7C,IAAI,OAAO,KAAK;GAAE;GAAS;EAAU;EACrC,IAAI,OAAO,KAAK;GAAE;GAAS;EAAU;EACrC,IAAI,UAAU,KAAK,YAAY,OAAO,GAAG,OAAO,GAAG;GAC/C,MAAM,KAAK,IAAI,MAAM,OAAO,CAAC,CAAC;GAC9B,KAAK,QAAQ,SAAS;GACtB,QAAQ,IAAI;EAChB;CACJ;CAEA,IAAI,MAAM,WAAW,GAAG,OAAO;CAC/B,MAAM,KAAK,IAAI,MAAM,KAAK,CAAC;CAC3B,MAAM,eAAe,MAAM,KAAI,MAAK,EAAE,KAAK,CAAC,CAAC,CAAC,QAAO,MAAK,EAAE,SAAS,CAAC;CACtE,OAAO,aAAa,SAAS,IAAI,eAAe;AACpD;;AAGA,SAAS,iBAAiB,KAAqB;CAC3C,IAAI,IAAI,IAAI,KAAK;CACjB,SAAS;EACL,IAAI,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC,EAAE,SAAS,GAAG,GAAG,OAAO;EACnD,IAAI,QAAQ;EACZ,IAAI,WAAW;EACf,IAAI,QAAQ;EACZ,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;GAC/B,MAAM,KAAK,EAAE;GACb,IAAI,UAAU;IACV,IAAI,OAAO,KACP,IAAI,EAAE,IAAI,OAAO,KAAK;SACjB,WAAW;IAEpB;GACJ;GACA,IAAI,OAAO,KAAK;IAAE,WAAW;IAAM;GAAU;GAC7C,IAAI,OAAO,KAAK;QACX,IAAI,OAAO,KAAK;IACjB;IACA,IAAI,UAAU,KAAK,IAAI,EAAE,SAAS,GAAG;KAAE,QAAQ;KAAO;IAAO;GACjE;EACJ;EACA,IAAI,CAAC,OAAO,OAAO;EACnB,IAAI,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK;CAC5B;AACJ;AAEA,SAAgB,YAAY,KAA+B;CAWvD,MAAM,UAAU,iBAAiB,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC;CAEtE,IAAI,QAAQ,YAAY,MAAM,QAAQ,OAAO,OAAO,KAAK;CACzD,IAAI,QAAQ,YAAY,MAAM,SAAS,OAAO,OAAO,MAAM;CAI3D,MAAM,eAAe,QAAQ,MAAM,oFAAoF;CACvH,IAAI,cAAc;EACd,MAAM,QAAQ,aAAa,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,KAAI,MAAK,EAAE,KAAK,CAAC,CAAC,QAAQ,UAAU,EAAE,CAAC;EAChF,OAAO,OAAO,aAAa,KAAK;CACpC;CAIA,MAAM,eAAe,QAAQ,MAAM,oFAAoF;CACvH,IAAI,cAAc;EACd,MAAM,QAAQ,aAAa,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,KAAI,MAAK,EAAE,KAAK,CAAC,CAAC,QAAQ,UAAU,EAAE,CAAC;EAChF,OAAO,OAAO,aAAa,KAAK;CACpC;CAGA,MAAM,UAAU,cAAc,SAAS,IAAI;CAC3C,IAAI,SAAS,OAAO,OAAO,GAAG,GAAG,QAAQ,IAAI,WAAW,CAAC;CAEzD,MAAM,WAAW,cAAc,SAAS,KAAK;CAC7C,IAAI,UAAU,OAAO,OAAO,IAAI,GAAG,SAAS,IAAI,WAAW,CAAC;CAG5D,MAAM,QAAQ,QAAQ,MAAM,wBAAwB;CACpD,IAAI,OAAO;EACP,MAAM,GAAG,SAAS,IAAI,YAAY;EAClC,MAAM,OAAO,aAAa,QAAQ,KAAK,CAAC;EACxC,MAAM,QAAQ,aAAa,SAAS,KAAK,CAAC;EAC1C,IAAI,QAAQ,OACR,OAAO,OAAO,QAAQ,MAAM,OAAO,MAAM,OAAO,OAAO,KAAK;CAEpE;CAMA,OAAO,OAAO,IAAI,OAAO;AAC7B;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,IAAM,0CAA0B,IAAI,IAAoB;CACpD,CAAC,QAAQ,UAAU;CACnB,CAAC,iBAAiB,UAAU;CAC5B,CAAC,gBAAgB,UAAU;AAC/B,CAAC;;;;;AAMD,IAAM,0BAA0B,IAAI,OAChC,OAAO,GAAG,2BAA2B,CAAC,GAAG,wBAAwB,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,KACnF,GACJ;;;;;;;;;AAoBA,IAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;AAyBrB,SAAgB,oBAAoB,MAA8C;CAC9E,MAAM,QAA8B,CAAC;CAErC,MAAM,SAAS,MAA8B;EACzC,QAAQ,EAAE,MAAV;GACI,KAAK;GACL,KAAK;IACD,EAAE,SAAS,QAAQ,KAAK;IACxB;GACJ,KAAK;IACD,MAAM,EAAE,OAAO;IACf;GACJ,KAAK;IACD,MAAM,EAAE,KAAK;IACb;GACJ,KAAK,OAAO;IACR,IAAI,aAAa,KAAK,EAAE,GAAG,GACvB,MAAM,KAAK;KACP,SAAS;KACT,QAAQ,EAAE;KACV,aAAa,0HACiC,kBAAkB;IAEpE,CAAC;IAUL,MAAM,UAAU,wBAAwB,KAAK,EAAE,GAAG;IAClD,IAAI,SAAS;KACT,MAAM,UAAU,QAAQ;KACxB,MAAM,KAAK;MACP,SAAS;MACT,QAAQ;MACR,aAAa,IAAI,QAAQ,SAAS,wBAAwB,IAAI,OAAO,EAAE,uDAC/B,kBAAkB,2BAClD,QAAQ;KAEpB,CAAC;IACL;IACA;GACJ;GACA,KAAK,WAAW;IACZ,MAAM,UAAU,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,MAAK,MAAK,EAAE,SAAS,SAAS;IAEhE,IAAI,EADgB,EAAE,KAAK,SAAS,aAAa,EAAE,MAAM,SAAS,cAC9C,OAAO,SAAS,UAAU,UAAU;IACxD,MAAM,WAAW,wBAAwB,IAAI,QAAQ,KAAK;IAC1D,IAAI,CAAC,UAAU;IACf,MAAM,KAAK;KACP,SAAS;KACT,QAAQ,QAAQ;KAChB,aAAa,IAAI,QAAQ,MAAM,SAAS,SAAS,uDAC9B,kBAAkB,2BAA2B,QAAQ,MAAM,oHAEnD,mBAAmB,KAAI,MAAK,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE;IAEhF,CAAC;IACD;GACJ;GACA,SACI;EACR;CACJ;CAEA,MAAM,IAAI;CACV,OAAO;AACX;AAEA,SAAS,aAAa,KAAa;CAyB/B,IAAI,sDAAsD,KAAK,GAAG,KAAK,qBAAqB,KAAK,GAAG,GAChG,OAAO,OAAO,QAAQ;CAU1B,MAAM,UAAU,kBAAkB,GAAG;CACrC,IAAI,YAAY,MACZ,OAAO,OAAO,QAAQ,OAAO;CAmBjC,IAAI,UAAU,KAAK,GAAG,GAAG,OAAO,OAAO,QAAQ,OAAO,GAAG,CAAC;CAC1D,IAAI,eAAe,KAAK,GAAG,GAAG,OAAO,OAAO,QAAQ,OAAO,GAAG,CAAC;CAC/D,IAAI,UAAU,KAAK,GAAG,GAAG,OAAO,OAAO,QAAQ,IAAI;CACnD,IAAI,WAAW,KAAK,GAAG,GAAG,OAAO,OAAO,QAAQ,KAAK;CACrD,IAAI,UAAU,KAAK,GAAG,GAAG,OAAO,OAAO,QAAQ,IAAI;CAQnD,IAAI,QAAQ,KAAK,GAAG,KAAK,YAAY,GAAG,MAAM,IAC1C,OAAO,OAAO,MAAM,GAAG;CAG3B,OAAO;AACX;;;;;;;;;AAUA,SAAS,kBAAkB,KAA4B;CACnD,IAAI,IAAI,SAAS,KAAK,CAAC,IAAI,WAAW,GAAG,KAAK,CAAC,IAAI,SAAS,GAAG,GAAG,OAAO;CACzE,MAAM,OAAO,IAAI,MAAM,GAAG,EAAE;CAC5B,IAAI,MAAM;CACV,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;EAClC,IAAI,KAAK,OAAO,KAAK;GACjB,OAAO,KAAK;GACZ;EACJ;EACA,IAAI,KAAK,IAAI,OAAO,KAAK;GACrB,OAAO;GACP;GACA;EACJ;EACA,OAAO;CACX;CACA,OAAO;AACX;;;;;;;;;;;;;;AC3YA,SAAgB,yBAAyB,MAAoC;CACzE,OAAO;EACH,WAAW,UAAU,UAAU,IAAI,GAAG,IAAI;EAC1C,eAAe,UAAU,cAAc,IAAI,GAAG,IAAI;CACtD;AACJ;AAEA,SAAS,UAAU,MAA6C;CAC5D,IAAI,KAAK,WAAW,OAAO,KAAK;CAChC,IAAI,KAAK,SAAS,MAAM,OAAO,YAAY,KAAK,KAAK;CACrD,IAAI,KAAK,WAAW,UAAU,OAAO,OAAO,KAAK;CACjD,IAAI,KAAK,YAAY,OAAO,OAAO,QAAQ,OAAO,MAAM,KAAK,UAAU,GAAG,MAAM,OAAO,QAAQ,CAAC;CAChG,OAAO;AACX;AAEA,SAAS,cAAc,MAA6C;CAChE,IAAI,KAAK,OAAO,OAAO,KAAK;CAC5B,IAAI,KAAK,aAAa,MAAM,OAAO,YAAY,KAAK,SAAS;CAG7D,OAAO,UAAU,IAAI;AACzB;;;;;;;AAQA,SAAS,UAAU,MAA+B,MAA6C;CAC3F,IAAI,CAAC,KAAK,SAAS,KAAK,MAAM,WAAW,GAAG,OAAO;CACnD,MAAM,YAAY,OAAO,aAAa,KAAK,KAAK;CAChD,IAAI,KAAK,SAAS,eAKd,OAAO,OAAO,OAAO,GAAG,OAAO,IAAI,SAAS,GAAG,IAAI,IAAI,OAAO,IAAI,SAAS;CAE/E,OAAO,OAAO,OAAO,IAAI,MAAM,SAAS,IAAI;AAChD;;;;;;;;;;;ACtBA,SAAgB,iBAAiB,MAAwB,YAA+B,SAAwC;CAC5H,OAAO,QAAQ,MAAM;EACjB,iBAAiB;EACjB,aAAa;EACb,iBAAiB;EACjB,aAAa;EACb,mBAAmB,SAAS;EAC5B,OAAO,EAAE,GAAG,EAAE;CAClB,CAAC;AACL;AAEA,SAAS,QAAQ,MAAwB,OAA6B;CAClE,QAAQ,KAAK,MAAb;EACI,KAAK,QACD,OAAO;EACX,KAAK,SACD,OAAO;EACX,KAAK,OACD,OAAO,KAAK,SAAS,WAAW,IAC1B,SACA,KAAK,SAAS,KAAI,MAAK,IAAI,QAAQ,GAAG,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO;EACvE,KAAK,MACD,OAAO,KAAK,SAAS,WAAW,IAC1B,UACA,KAAK,SAAS,KAAI,MAAK,IAAI,QAAQ,GAAG,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,MAAM;EACtE,KAAK,OACD,OAAO,QAAQ,QAAQ,KAAK,SAAS,KAAK,EAAE;EAChD,KAAK,WAAW;GAIZ,MAAM,kBAAkB,SAAwB,SAAiB,UAC7D,MAAM,SAAS,cAAc,QAAQ,SAAS,WAAW,QAAQ,SAAS,gBACpE,IAAI,QAAQ,WACZ;GACV,MAAM,UAAU,eAAe,KAAK,MAAM,aAAa,KAAK,MAAM,KAAK,GAAG,KAAK,KAAK;GACpF,MAAM,WAAW,eAAe,KAAK,OAAO,aAAa,KAAK,OAAO,KAAK,GAAG,KAAK,IAAI;GACtF,OAAO,GAAG,QAAQ,GAAG,YAAY,KAAK,IAAI,GAAG;EACjD;EACA,KAAK,gBACD,OAAO,mBAAmB,cAAc,YAAY,cAAc,KAAK,KAAK;EAChF,KAAK,gBACD,OAAO,mBAAmB,cAAc,YAAY,cAAc,KAAK,KAAK;EAChF,KAAK,iBAWD,OAAO,GAAG,YAAY,mBAAmB,YAAY,WAAW,mBAAmB,IAAI,YAAY,CAAC,CAAC,KAAK,IAAI,EAAE;EACpH,KAAK,iBAED,OAAO,GAAG,YAAY;EAC1B,KAAK,YACD,OAAO,gBAAgB,MAAM,KAAK;EACtC,KAAK,OAiBD,OANgB,0BAA0B,KAAK,GAMxC,CAAA,CAAQ,QAAQ,eAAe,GAAG,QACrC,GAAG,eAAe,KAAK,IAAI,kBAAkB,KAAK,MAAM,eAAe,GAAG;CAEtF;AACJ;;;;;;AAOA,SAAS,gBAAgB,MAAgC,OAA6B;CAClF,MAAM,OAAO,MAAM,oBAAoB,KAAK,UAAU;CACtD,MAAM,YAAY,OAAO,aAAa,IAAI,IAAI,YAAY,KAAK,UAAU;CACzE,MAAM,aAAa,SAAS,IAAI,KAAK,SAAS,MAAM,eAAe,KAAK;CACxE,MAAM,QAAQ,MAAM,MAAM,MAAM;CAIhC,MAAM,cAAc,eAAe,KAAK;CAExC,MAAM,aAA2B;EAC7B,iBAAiB;EACjB,aAAa,IAAI,MAAM;EACvB,iBAAiB,MAAM;EACvB;EACA,mBAAmB,MAAM;EACzB,OAAO,MAAM;CACjB;CACA,OAAO,0BAA0B,WAAW,KAAK,UAAU,KAAK,MAAM,UAAU,QAAQ,KAAK,OAAO,UAAU,EAAE;AACpH;AAEA,IAAM,cAAqD;CACvD,IAAI;CACJ,KAAK;CACL,IAAI;CACJ,KAAK;CACL,IAAI;CACJ,KAAK;AACT;AAEA,SAAS,aAAa,SAAwB,OAA6B;CACvE,QAAQ,QAAQ,MAAhB;EACI,KAAK,SACD,OAAO,GAAG,MAAM,cAAc,kBAAkB,QAAQ,MAAM,MAAM,eAAe;EACvF,KAAK,cACD,OAAO,GAAG,MAAM,cAAc,kBAAkB,QAAQ,MAAM,MAAM,eAAe;EACvF,KAAK,WACD,OAAO,aAAa,QAAQ,KAAK;EACrC,KAAK,WACD,OAAO;EACX,KAAK,aACD,OAAO,mBAAmB,cAAc;CAChD;AACJ;;;;;AAMA,SAAS,eAAe,OAA6B;CACjD,MAAM,QAAQ,MAAM,kBAAkB,aAAa,MAAM,eAAe,IAAI,KAAA;CAC5E,IAAI,CAAC,OAAO,OAAO;CACnB,OAAO,IAAI,SAAS,MAAM,eAAe,KAAK,SAAS,KAAK,MAAM;AACtE;AAEA,SAAS,SAAS,YAAmD;CACjE,OAAQ,YAAgD,UAAU,KAAA;AACtE;AAEA,SAAS,kBAAkB,UAAkB,YAAuC;CAChF,MAAM,OAAO,YAAY,aAAa;CACtC,IAAI,QAAQ,gBAAgB,QAAQ,OAAQ,KAAkC,eAAe,UACzF,OAAO,sBAAuB,KAAgC,UAAU;CAE5E,OAAO,sBAAsB,YAAY,QAAQ,CAAC;AACtD;;;;;;AAOA,IAAM,qCAAqB,IAAI,IAAI;CAC/B;CAAO;CAAW;CAAW;CAAO;CAAO;CAAS;CAAM;CAAO;CAAc;CAC/E;CAAU;CAAQ;CAAQ;CAAQ;CAAS;CAAW;CAAa;CAAU;CAC7E;CAAc;CAAU;CAAS;CAAmB;CAAgB;CACpE;CAAkB;CAAgB;CAAqB;CAAgB;CAAW;CAClF;CAAQ;CAAY;CAAM;CAAQ;CAAO;CAAU;CAAS;CAAS;CAAO;CAAW;CACvF;CAAQ;CAAQ;CAAS;CAAS;CAAU;CAAS;CAAM;CAAa;CAAS;CACjF;CAAQ;CAAM;CAAU;CAAQ;CAAW;CAAW;CAAQ;CAAQ;CAAS;CAC/E;CAAkB;CAAW;CAAO;CAAW;CAAQ;CAAU;CAAM;CAAQ;CAAM;CACrF;CAAS;CAAY;CAAW;CAAW;CAAc;CAAa;CAAS;CAC/E;CAAgB;CAAW;CAAQ;CAAa;CAAe;CAAS;CAAe;CACvF;CAAM;CAAY;CAAQ;CAAS;CAAU;CAAQ;CAAS;CAAY;CAAW;CACrF;CAAS;CAAU;AACvB,CAAC;;AAGD,IAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BxB,SAAS,sBAAsB,MAAsB;CACjD,IAAI,gBAAgB,KAAK,IAAI,KAAK,CAAC,mBAAmB,IAAI,IAAI,GAAG,OAAO;CACxE,OAAO,IAAI,KAAK,QAAQ,MAAM,MAAM,EAAE;AAC1C;AAEA,SAAS,aAAa,OAAiD;CACnE,IAAI,UAAU,MAAM,OAAO;CAC3B,IAAI,OAAO,UAAU,WAAW,OAAO,QAAQ,SAAS;CACxD,IAAI,OAAO,UAAU,UAAU,OAAO,OAAO,KAAK;CAClD,OAAO,IAAI,MAAM,QAAQ,MAAM,IAAI,EAAE;AACzC;;AAGA,SAAS,cAAc,OAAkC;CACrD,OAAO,SAAS,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,KAAI,MAAK,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,EAAE;AACnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AE3MA,IAAM,yBAAyC,OAAO,GAClD,OAAO,cAAc,GACrB,OAAO,aAAa,CAAC,OAAO,CAAC,CACjC;;AAGA,IAAM,sBAA2C;CAAC;CAAU;CAAU;AAAQ;;AAG9E,SAAS,mBAAiB,YAAuC;CAC7D,MAAM,OAAO,WAAW;CACxB,OAAO,SAAS,QAAS,OAAO,SAAS,YAAa,MAA+B,YAAY;AACrG;;AAGA,SAAS,oBAAkB,YAAsC;CAC7D,KAAK,MAAM,CAAC,MAAM,SAAS,OAAO,QAAQ,WAAW,cAAc,CAAC,CAAC,GACjE,IAAI,QAAQ,OAAO,SAAS,YAAY,UAAU,QAAS,KAA4B,MACnF,OAAO;CAGf,OAAO;AACX;;;;;;;;;;;;;;;;;AAkBA,SAAS,eAAe,WAAiC;CACrD,OAAO;EACH,MAAM,GAAG,UAAU;EACnB,MAAM;EACN,YAAY,CAAC,GAAG,mBAAmB;EACnC,WAAW;EACX,OAAO;CACX;AACJ;AAEA,SAAgB,0BAA0B,YAA8C;CACpF,MAAM,WAAW,CAAC,GAAI,WAAW,iBAAiB,CAAC,CAAE;CAErD,MAAM,YAAY,aAAa,UAAU;CACzC,MAAM,WAA2B,CAAC;CAElC,IAAI,2BAA2B,UAAU,KAAK,WAAW,wBAerD,OAAO,mBAAiB,UAAU,IAC5B,CAAC,GAAG,UAAU,eAAe,SAAS,CAAC,IACvC;CAOV,SAAS,KAAK;EACV,MAAM,GAAG,UAAU;EACnB,YAAY,CAAC,QAAQ;EACrB,WAAW;CACf,CAAC;CACD,SAAS,KAAK;EACV,MAAM,GAAG,UAAU;EACnB,YAAY,CAAC,GAAG,mBAAmB;EACnC,WAAW;EACX,OAAO;CACX,CAAC;CAED,IAAI,mBAAiB,UAAU,GAAG;EAE9B,SAAS,KAAK;GACV,MAAM,GAAG,UAAU;GACnB,YAAY,CAAC,QAAQ;GACrB,WAAW,OAAO,QAAQ,OAAO,MAAM,oBAAkB,UAAU,CAAC,GAAG,MAAM,OAAO,QAAQ,CAAC;EACjG,CAAC;EAMD,SAAS,KAAK,eAAe,SAAS,CAAC;CAC3C;CAEA,OAAO,CAAC,GAAG,UAAU,GAAG,QAAQ;AACpC;;;ACzEA,IAAM,uBAAyC,OAAO,GAClD,OAAO,cAAc,GACrB,OAAO,aAAa,CAAC,OAAO,CAAC,CACjC;;;;;;;AAQA,SAAgB,qBAAqB,aAA4D;CAC7F,MAAM,wBAAQ,IAAI,IAA0B;CAE5C,KAAK,MAAM,cAAc,aAAa;EAClC,MAAM,WAAW,2BAA2B,UAAU;EACtD,KAAK,MAAM,YAAY,OAAO,OAAO,QAAQ,GAAG;GAG5C,IAAI,CAAC,aAAa,QAAQ,GAAG;GAE7B,MAAM,mBAAiD,SAAS,OAAO;GACvE,IAAI,CAAC,kBAAkB;GAEvB,MAAM,UAAU,SAAS,QAAQ;GAIjC,MAAM,QAAQ,QAAQ,SAAS,GAAG,IAAI,QAAQ,MAAM,GAAG,CAAC,CAAC,IAAI,IAAK;GAClE,MAAM,SAAS;GAEf,MAAM,SAAgC;IAClC;IACA,gBAAgB,SAAS,QAAQ;IACjC;GACJ;GACA,MAAM,SAA2B;IAC7B,YAAY;IACZ,gBAAgB,SAAS,QAAQ;GACrC;GAEA,MAAM,WAAW,MAAM,IAAI,KAAK;GAChC,IAAI,CAAC,UACD,MAAM,IAAI,OAAO;IACb;IACA;IACA,WAAW,CAAC,QAAQ,MAAM;IAC1B,gBAAgB,CAAC,MAAM;GAC3B,CAAC;QACE,IAAI,CAAC,SAAS,eAAe,MAAK,MAAK,EAAE,eAAe,UAAU,GACrE,SAAS,eAAe,KAAK,MAAM;EAE3C;CACJ;CAEA,OAAO;AACX;;;;;;;AAQA,SAAgB,4BAA4B,MAAsC;CAC9E,MAAM,aAAsC,CAAC;CAC7C,KAAK,MAAM,YAAY,KAAK,WACxB,WAAW,SAAS,kBAAkB;EAClC,MAAM;EACN,YAAY,SAAS;CACzB;CAEJ,OAAO;EACH,MAAM,KAAK;EACX,MAAM,KAAK;EACX,OAAO,KAAK;EACZ,QAAQ,KAAK;EACb;CACJ;AACJ;;AAGA,SAAS,kBAAkB,YAAsC;CAC7D,KAAK,MAAM,CAAC,MAAM,SAAS,OAAO,QAAQ,WAAW,cAAc,CAAC,CAAC,GACjE,IAAI,QAAQ,OAAO,SAAS,YAAY,UAAU,QAAS,KAA4B,MACnF,OAAO;CAGf,OAAO;AACX;;AAGA,SAAS,eAAe,UAA4B,OAA4C;CAC5F,MAAM,cAAc,OAAO,QACvB,OAAO,MAAM,kBAAkB,SAAS,UAAU,CAAC,GACnD,MACA,OAAO,WAAW,SAAS,cAAc,CAC7C;CACA,OAAO,OAAO,SAAS;EACnB,YAAY,SAAS,WAAW;EAChC,OAAO,QAAQ,OAAO,IAAI,aAAa,KAAK,IAAI;CACpD,CAAC;AACL;;;;;;;;;;;AAYA,SAAgB,sBAAsB,MAAwB,QAAQ,GAA4B;CAC9F,QAAQ,KAAK,MAAb;EACI,KAAK,OACD,OAAO;EACX,KAAK;EACL,KAAK,MAAM;GACP,MAAM,QAA4B,CAAC;GACnC,KAAK,MAAM,SAAS,KAAK,UAAU;IAC/B,MAAM,WAAW,sBAAsB,OAAO,KAAK;IACnD,IAAI,CAAC,UAAU,OAAO;IACtB,MAAM,KAAK,QAAQ;GACvB;GACA,OAAO,KAAK,SAAS,QAAQ,OAAO,IAAI,GAAG,KAAK,IAAI,OAAO,GAAG,GAAG,KAAK;EAC1E;EACA,KAAK,OAAO;GACR,MAAM,WAAW,sBAAsB,KAAK,SAAS,KAAK;GAC1D,OAAO,WAAW,OAAO,IAAI,QAAQ,IAAI;EAC7C;EACA,KAAK,YAAY;GACb,MAAM,QAAQ,sBAAsB,KAAK,OAAO,QAAQ,CAAC;GACzD,OAAO,QAAQ,OAAO,SAAS;IAAE,YAAY,KAAK;IAAY;GAAM,CAAC,IAAI;EAC7E;EACA,KAAK,WAAW;GACZ,MAAM,OAAO,aAAa,KAAK,MAAM,KAAK;GAC1C,MAAM,QAAQ,aAAa,KAAK,OAAO,KAAK;GAC5C,IAAI,CAAC,QAAQ,CAAC,OAAO,OAAO;GAC5B,OAAO;IAAE,GAAG;IAAM;IAAM;GAAM;EAClC;EACA,SAII,OAAO;CACf;AACJ;;AAGA,SAAS,aAAa,SAAwB,OAAqC;CAC/E,IAAI,QAAQ,SAAS,cAAc;EAG/B,IAAI,UAAU,GAAG,OAAO,OAAO,MAAM,QAAQ,IAAI;EAGjD,OAAO;CACX;CACA,OAAO;AACX;;AAGA,SAAS,aAAa,MAA6B;CAC/C,OAAO,oBAAoB,IAAI,CAAC,CAAC,MAAK,OAAM,OAAO,YAAY,OAAO,KAAK;AAC/E;;;;;;;;AASA,SAAgB,yBAAyB,MAAoC;CACzE,IAAI,KAAK,eAAe,OAAM,SAAQ,2BAA2B,KAAK,UAAU,KAAK,KAAK,WAAW,sBAAsB,GACvH,OAAO,CAAC;CAGZ,MAAM,QAAwB,CAAC;CAG/B,MAAM,KAAK;EACP,MAAM,GAAG,KAAK,MAAM;EACpB,YAAY,CAAC,QAAQ;EACrB,WAAW;CACf,CAAC;CACD,MAAM,KAAK;EACP,MAAM,GAAG,KAAK,MAAM;EACpB,YAAY;GAAC;GAAU;GAAU;EAAQ;EACzC,WAAW;EACX,OAAO;CACX,CAAC;CAKD,MAAM,KAAK;EACP,MAAM,GAAG,KAAK,MAAM;EACpB,YAAY,CAAC,QAAQ;EACrB,WAAW,OAAO,IACd,eAAe,KAAK,UAAU,EAAE,GAChC,eAAe,KAAK,UAAU,EAAE,CACpC;CACJ,CAAC;CAGD,MAAM,cAAkC,CAAC;CACzC,KAAK,MAAM,QAAQ,KAAK,gBAAgB;EAIpC,MAAM,gBAHiB,2BAA2B,KAAK,UAAU,IAC3D,KAAK,WAAW,gBAChB,KAAA,MAAc,CAAC,EAAA,CACa,OAAO,YAAY;EAErD,MAAM,aAAa,YAAY,QAAO,MAAK,EAAE,SAAS,aAAa;EACnE,MAAM,cAAc,YAAY,QAAO,MAAK,EAAE,SAAS,aAAa;EAKpE,MAAM,gBAAoC,CAAC;EAC3C,IAAI,kBAAkB;EACtB,KAAK,MAAM,QAAQ,aAAa;GAC5B,MAAM,QAAQ,yBAAyB,IAAI,CAAC,CAAC;GAC7C,MAAM,WAAW,QAAQ,sBAAsB,KAAK,IAAI;GACxD,IAAI,CAAC,UAAU;IACX,kBAAkB;IAClB;GACJ;GACA,cAAc,KAAK,QAAQ;EAC/B;EACA,IAAI,CAAC,iBAAiB;EAEtB,MAAM,SAA6B,CAAC;EACpC,KAAK,MAAM,QAAQ,YAAY;GAC3B,MAAM,QAAQ,yBAAyB,IAAI,CAAC,CAAC;GAC7C,MAAM,WAAW,QAAQ,sBAAsB,KAAK,IAAI;GACxD,IAAI,UAAU,OAAO,KAAK,QAAQ;EACtC;EACA,IAAI,OAAO,WAAW,GAAG;EAGzB,MAAM,YAAY,cAAc,SAAS,IACnC,OAAO,IAAI,OAAO,GAAG,GAAG,MAAM,GAAG,GAAG,aAAa,IACjD,OAAO,GAAG,GAAG,MAAM;EAEzB,YAAY,KAAK,eAAe,MAAM,SAAS,CAAC;CACpD;CAEA,IAAI,YAAY,SAAS,GACrB,MAAM,KAAK;EACP,MAAM,GAAG,KAAK,MAAM;EACpB,YAAY;GAAC;GAAU;GAAU;EAAQ;EACzC,WAAW,YAAY,WAAW,IAAI,YAAY,KAAK,OAAO,GAAG,GAAG,WAAW;EAC/E,OAAO,YAAY,WAAW,IAAI,YAAY,KAAK,OAAO,GAAG,GAAG,WAAW;CAC/E,CAAC;CAGL,OAAO;AACX;;CC7VC,CAAC,SAAS,MAAM,SAAS;EACxB,IAAI,OAAO,WAAW,cAAc,OAAO,KACzC,OAAO,OAAO;OACT,IAAI,OAAO,YAAY,UAC5B,OAAO,UAAU,QAAQ;OAEzB,KAAK,YAAY,QAAQ;CAE7B,EAAA,CAAC,SAAO,WAAW;EACjB;EAGA,IAAK,CAAE,MAAM,SACX,MAAM,UAAU,SAAS,KAAK;GAC5B,OAAO,OAAO,UAAU,SAAS,KAAK,GAAG,MAAM;EACjD;;;;;;EAQF,SAAS,YAAY,OAAO;GAC1B,IAAI,IAAI,CAAC;GACT,KAAK,IAAI,IAAE,GAAG,IAAE,MAAM,QAAQ,IAAE,GAAG,KACjC,IAAI,EAAE,QAAQ,MAAM,EAAE,MAAM,IAC1B,EAAE,KAAK,MAAM,EAAE;GAGnB,OAAO;EACT;EAEA,IAAI,YAAY,CAAC;EACjB,IAAI,aAAa;GACf,MAAM,SAAS,GAAG,GAAG;IACnB,OAAO,KAAK;GACd;GACA,OAAO,SAAS,GAAG,GAAG;IACpB,OAAO,MAAM;GACf;GACA,MAAM,SAAS,GAAG,GAAG;IACnB,OAAO,KAAK;GACd;GACA,OAAO,SAAS,GAAG,GAAG;IACpB,OAAO,MAAM;GACf;GACA,KAAK,SAAS,GAAG,GAAG;IAClB,OAAO,IAAI;GACb;GACA,MAAM,SAAS,GAAG,GAAG;IACnB,OAAO,KAAK;GACd;GACA,KAAK,SAAS,GAAG,GAAG,GAAG;IACrB,OAAQ,MAAM,KAAA,IAAa,IAAI,IAAK,IAAI,KAAO,IAAI;GACrD;GACA,MAAM,SAAS,GAAG,GAAG,GAAG;IACtB,OAAQ,MAAM,KAAA,IAAa,KAAK,IAAK,KAAK,KAAO,KAAK;GACxD;GACA,MAAM,SAAS,GAAG;IAChB,OAAO,UAAU,OAAO,CAAC;GAC3B;GACA,KAAK,SAAS,GAAG;IACf,OAAO,CAAC,UAAU,OAAO,CAAC;GAC5B;GACA,KAAK,SAAS,GAAG,GAAG;IAClB,OAAO,IAAI;GACb;GACA,OAAO,SAAS,GAAG;IACjB,QAAQ,IAAI,CAAC;IAAG,OAAO;GACzB;GACA,MAAM,SAAS,GAAG,GAAG;IACnB,IAAI,CAAC,KAAK,OAAO,EAAE,YAAY,aAAa,OAAO;IACnD,OAAQ,EAAE,QAAQ,CAAC,MAAM;GAC3B;GACA,OAAO,WAAW;IAChB,OAAO,MAAM,UAAU,KAAK,KAAK,WAAW,EAAE;GAChD;GACA,UAAU,SAAS,QAAQ,OAAO,KAAK;IACrC,IAAI,MAAM,GAAG;KAEX,IAAI,OAAO,OAAO,MAAM,CAAC,CAAC,OAAO,KAAK;KACtC,OAAO,KAAK,OAAO,GAAG,KAAK,SAAS,GAAG;IACzC;IACA,OAAO,OAAO,MAAM,CAAC,CAAC,OAAO,OAAO,GAAG;GACzC;GACA,KAAK,WAAW;IACd,OAAO,MAAM,UAAU,OAAO,KAAK,WAAW,SAAS,GAAG,GAAG;KAC3D,OAAO,WAAW,GAAG,EAAE,IAAI,WAAW,GAAG,EAAE;IAC7C,GAAG,CAAC;GACN;GACA,KAAK,WAAW;IACd,OAAO,MAAM,UAAU,OAAO,KAAK,WAAW,SAAS,GAAG,GAAG;KAC3D,OAAO,WAAW,GAAG,EAAE,IAAI,WAAW,GAAG,EAAE;IAC7C,CAAC;GACH;GACA,KAAK,SAAS,GAAG,GAAG;IAClB,IAAI,MAAM,KAAA,GACR,OAAO,CAAC;SAER,OAAO,IAAI;GAEf;GACA,KAAK,SAAS,GAAG,GAAG;IAClB,OAAO,IAAI;GACb;GACA,OAAO,WAAW;IAChB,OAAO,KAAK,IAAI,MAAM,MAAM,SAAS;GACvC;GACA,OAAO,WAAW;IAChB,OAAO,KAAK,IAAI,MAAM,MAAM,SAAS;GACvC;GACA,SAAS,WAAW;IAClB,OAAO,MAAM,UAAU,OAAO,KAAK,WAAW,SAAS,GAAG,GAAG;KAC3D,OAAO,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,CAAC;GACP;GACA,OAAO,SAAS,GAAG,GAAG;IACpB,IAAI,YAAa,MAAM,KAAA,IAAa,OAAO;IAC3C,IAAI,OAAO;IACX,IAAI,OAAO,MAAM,eAAe,MAAI,MAAM,MAAI,MAC5C,OAAO;IAET,IAAI,YAAY,OAAO,CAAC,CAAC,CAAC,MAAM,GAAG;IACnC,KAAK,IAAI,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;KACzC,IAAI,SAAS,QAAQ,SAAS,KAAA,GAC5B,OAAO;KAGT,OAAO,KAAK,UAAU;KACtB,IAAI,SAAS,KAAA,GACX,OAAO;IAEX;IACA,OAAO;GACT;GACA,WAAW,WAAW;IAQpB,IAAI,UAAU,CAAC;IACf,IAAI,OAAO,MAAM,QAAQ,UAAU,EAAE,IAAI,UAAU,KAAK;IAExD,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;KACpC,IAAI,MAAM,KAAK;KACf,IAAI,QAAQ,UAAU,MAAM,EAAC,OAAO,IAAG,GAAG,IAAI;KAC9C,IAAI,UAAU,QAAQ,UAAU,IAC9B,QAAQ,KAAK,GAAG;IAEpB;IAEA,OAAO;GACT;GACA,gBAAgB,SAAS,YAAY,SAAS;IAE5C,IAAI,cAAc,UAAU,MAAM,EAAC,WAAW,QAAO,GAAG,IAAI;IAE5D,IAAI,QAAQ,SAAS,YAAY,UAAU,YACzC,OAAO,CAAC;SAER,OAAO;GAEX;EACF;EAEA,UAAU,WAAW,SAAS,OAAO;GACnC,OACE,OAAO,UAAU,YACjB,UAAU,QACV,CAAE,MAAM,QAAQ,KAAK,KACrB,OAAO,KAAK,KAAK,CAAC,CAAC,WAAW;EAElC;EAOA,UAAU,SAAS,SAAS,OAAO;GACjC,IAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,GAC3C,OAAO;GAET,OAAO,CAAC,CAAE;EACZ;EAGA,UAAU,eAAe,SAAS,OAAO;GACvC,OAAO,OAAO,KAAK,KAAK,CAAC,CAAC;EAC5B;EAEA,UAAU,aAAa,SAAS,OAAO;GACrC,OAAO,MAAM,UAAU,aAAa,KAAK;EAC3C;EAEA,UAAU,QAAQ,SAAS,OAAO,MAAM;GAEtC,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,MAAM,IAAI,SAAS,GAAG;IAC3B,OAAO,UAAU,MAAM,GAAG,IAAI;GAChC,CAAC;GAGH,IAAK,CAAE,UAAU,SAAS,KAAK,GAC7B,OAAO;GAGT,IAAI,KAAK,UAAU,aAAa,KAAK;GACrC,IAAI,SAAS,MAAM;GACnB,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GAGJ,IAAK,CAAE,MAAM,QAAQ,MAAM,GACzB,SAAS,CAAC,MAAM;GAIlB,IAAI,OAAO,QAAQ,MAAM,MAAM;IAc7B,KAAK,IAAI,GAAG,IAAI,OAAO,SAAS,GAAG,KAAK,GACtC,IAAK,UAAU,OAAQ,UAAU,MAAM,OAAO,IAAI,IAAI,CAAE,GACtD,OAAO,UAAU,MAAM,OAAO,IAAE,IAAI,IAAI;IAG5C,IAAI,OAAO,WAAW,IAAE,GACtB,OAAO,UAAU,MAAM,OAAO,IAAI,IAAI;IAExC,OAAO;GACT,OAAO,IAAI,OAAO,OAAO;IACvB,KAAK,IAAE,GAAG,IAAI,OAAO,QAAQ,KAAG,GAAG;KACjC,UAAU,UAAU,MAAM,OAAO,IAAI,IAAI;KACzC,IAAK,CAAE,UAAU,OAAO,OAAO,GAC7B,OAAO;IAEX;IACA,OAAO;GACT,OAAO,IAAI,OAAO,MAAM;IACtB,KAAK,IAAE,GAAG,IAAI,OAAO,QAAQ,KAAG,GAAG;KACjC,UAAU,UAAU,MAAM,OAAO,IAAI,IAAI;KACzC,IAAK,UAAU,OAAO,OAAO,GAC3B,OAAO;IAEX;IACA,OAAO;GACT,OAAO,IAAI,OAAO,UAAU;IAC1B,aAAa,UAAU,MAAM,OAAO,IAAI,IAAI;IAC5C,cAAc,OAAO;IAErB,IAAK,CAAE,MAAM,QAAQ,UAAU,GAC7B,OAAO,CAAC;IAKV,OAAO,WAAW,OAAO,SAAS,OAAO;KACvC,OAAO,UAAU,OAAQ,UAAU,MAAM,aAAa,KAAK,CAAC;IAC9D,CAAC;GACH,OAAO,IAAI,OAAO,OAAO;IACvB,aAAa,UAAU,MAAM,OAAO,IAAI,IAAI;IAC5C,cAAc,OAAO;IAErB,IAAK,CAAE,MAAM,QAAQ,UAAU,GAC7B,OAAO,CAAC;IAGV,OAAO,WAAW,IAAI,SAAS,OAAO;KACpC,OAAO,UAAU,MAAM,aAAa,KAAK;IAC3C,CAAC;GACH,OAAO,IAAI,OAAO,UAAU;IAC1B,aAAa,UAAU,MAAM,OAAO,IAAI,IAAI;IAC5C,cAAc,OAAO;IACrB,UAAU,OAAO,OAAO,OAAO,cAAc,UAAU,MAAM,OAAO,IAAI,IAAI,IAAI;IAEhF,IAAK,CAAE,MAAM,QAAQ,UAAU,GAC7B,OAAO;IAGT,OAAO,WAAW,OAChB,SAAS,aAAa,SAAS;KAC7B,OAAO,UAAU,MACf,aACA;MAAU;MAAsB;KAAW,CAC7C;IACF,GACA,OACF;GACF,OAAO,IAAI,OAAO,OAAO;IACvB,aAAa,UAAU,MAAM,OAAO,IAAI,IAAI;IAC5C,cAAc,OAAO;IAErB,IAAK,CAAE,MAAM,QAAQ,UAAU,KAAK,CAAE,WAAW,QAC/C,OAAO;IAET,KAAK,IAAE,GAAG,IAAI,WAAW,QAAQ,KAAG,GAClC,IAAK,CAAE,UAAU,OAAQ,UAAU,MAAM,aAAa,WAAW,EAAE,CAAE,GACnE,OAAO;IAGX,OAAO;GACT,OAAO,IAAI,OAAO,QAAQ;IACxB,aAAa,UAAU,MAAM,OAAO,IAAI,IAAI;IAC5C,cAAc,OAAO;IAErB,IAAK,CAAE,MAAM,QAAQ,UAAU,KAAK,CAAE,WAAW,QAC/C,OAAO;IAET,KAAK,IAAE,GAAG,IAAI,WAAW,QAAQ,KAAG,GAClC,IAAK,UAAU,OAAQ,UAAU,MAAM,aAAa,WAAW,EAAE,CAAE,GACjE,OAAO;IAGX,OAAO;GACT,OAAO,IAAI,OAAO,QAAQ;IACxB,aAAa,UAAU,MAAM,OAAO,IAAI,IAAI;IAC5C,cAAc,OAAO;IAErB,IAAK,CAAE,MAAM,QAAQ,UAAU,KAAK,CAAE,WAAW,QAC/C,OAAO;IAET,KAAK,IAAE,GAAG,IAAI,WAAW,QAAQ,KAAG,GAClC,IAAK,UAAU,OAAQ,UAAU,MAAM,aAAa,WAAW,EAAE,CAAE,GACjE,OAAO;IAGX,OAAO;GACT;GAGA,SAAS,OAAO,IAAI,SAAS,KAAK;IAChC,OAAO,UAAU,MAAM,KAAK,IAAI;GAClC,CAAC;GAMD,IAAI,WAAW,eAAe,EAAE,KAAK,OAAO,WAAW,QAAQ,YAC7D,OAAO,WAAW,GAAG,CAAC,MAAM,MAAM,MAAM;QACnC,IAAI,GAAG,QAAQ,GAAG,IAAI,GAAG;IAC9B,IAAI,UAAU,OAAO,EAAE,CAAC,CAAC,MAAM,GAAG;IAClC,IAAI,YAAY;IAChB,KAAK,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;KACnC,IAAI,CAAC,UAAU,eAAe,QAAQ,EAAE,GACtC,MAAM,IAAI,MAAM,4BAA4B,KAC1C,iBAAiB,QAAQ,MAAM,GAAG,IAAE,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,GAAG;KAG1D,YAAY,UAAU,QAAQ;IAChC;IAEA,OAAO,UAAU,MAAM,MAAM,MAAM;GACrC;GAEA,MAAM,IAAI,MAAM,4BAA4B,EAAG;EACjD;EAEA,UAAU,YAAY,SAAS,OAAO;GACpC,IAAI,aAAa,CAAC;GAElB,IAAI,UAAU,SAAS,KAAK,GAAG;IAC7B,IAAI,KAAK,UAAU,aAAa,KAAK;IACrC,IAAI,SAAS,MAAM;IAEnB,IAAK,CAAE,MAAM,QAAQ,MAAM,GACzB,SAAS,CAAC,MAAM;IAGlB,IAAI,OAAO,OAET,WAAW,KAAK,OAAO,EAAE;SAGzB,OAAO,QAAQ,SAAS,KAAK;KAC3B,WAAW,KAAK,MAAM,YAAY,UAAU,UAAU,GAAG,CAAE;IAC7D,CAAC;GAEL;GAEA,OAAO,YAAY,UAAU;EAC/B;EAEA,UAAU,gBAAgB,SAAS,MAAM,MAAM;GAC7C,WAAW,QAAQ;EACrB;EAEA,UAAU,eAAe,SAAS,MAAM;GACtC,OAAO,WAAW;EACpB;EAEA,UAAU,YAAY,SAAS,MAAM,SAAS;GAE5C,IAAI,YAAY,MACd,OAAO;GAET,IAAI,YAAY,KACd,OAAO;GAET,IAAI,YAAY,UACd,OAAQ,OAAO,SAAS;GAE1B,IAAI,YAAY,UACd,OAAQ,OAAO,SAAS;GAE1B,IAAI,YAAY,SAEd,OAAO,MAAM,QAAQ,IAAI,KAAK,CAAE,UAAU,SAAS,IAAI;GAGzD,IAAI,UAAU,SAAS,OAAO,GAAG;IAC/B,IAAI,UAAU,SAAS,IAAI,GAAG;KAC5B,IAAI,aAAa,UAAU,aAAa,OAAO;KAC/C,IAAI,UAAU,UAAU,aAAa,IAAI;KAEzC,IAAI,eAAe,OAAO,eAAe,SAEvC,OAAO,UAAU,UACf,UAAU,WAAW,MAAM,KAAK,GAChC,UAAU,WAAW,SAAS,KAAK,CACrC;IAEJ;IACA,OAAO;GACT;GAEA,IAAI,MAAM,QAAQ,OAAO,GACvB,IAAI,MAAM,QAAQ,IAAI,GAAG;IACvB,IAAI,QAAQ,WAAW,KAAK,QAC1B,OAAO;IAKT,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK,GAEvC,IAAK,CAAE,UAAU,UAAU,KAAK,IAAI,QAAQ,EAAE,GAC5C,OAAO;IAGX,OAAO;GACT,OACE,OAAO;GAKX,OAAO;EACT;EAEA,OAAO;CACT,CAAC;;;;;;;;;;;;;;;;;;AEjcD,SAAgB,0BAA0B,MAAkD;CACxF,MAAM,MAAM,KAAK,YAAY;CAC7B,OAAO,OAAO,QAAQ,YAAY,OAAO,UAAU,GAAG,KAAK,MAAM,IAC3D,MAAA;AAEV;;;AC9BA,IAAM,EAAE,qBAAqB,0BAA0B;AAEvD,IAAM,EAAE,mBAAmB,OAAO;;;;AAIlC,SAAS,mBAAmB,aAAa,aAAa;CAClD,OAAO,SAAS,QAAQ,GAAG,GAAG,OAAO;EACjC,OAAO,YAAY,GAAG,GAAG,KAAK,KAAK,YAAY,GAAG,GAAG,KAAK;CAC9D;AACJ;;;;;;AAMA,SAAS,iBAAiB,eAAe;CACrC,OAAO,SAAS,WAAW,GAAG,GAAG,OAAO;EACpC,IAAI,CAAC,KAAK,CAAC,KAAK,OAAO,MAAM,YAAY,OAAO,MAAM,UAClD,OAAO,cAAc,GAAG,GAAG,KAAK;EAEpC,MAAM,EAAE,UAAU;EAClB,MAAM,UAAU,MAAM,IAAI,CAAC;EAC3B,MAAM,UAAU,MAAM,IAAI,CAAC;EAC3B,IAAI,WAAW,SACX,OAAO,YAAY,KAAK,YAAY;EAExC,MAAM,IAAI,GAAG,CAAC;EACd,MAAM,IAAI,GAAG,CAAC;EACd,MAAM,SAAS,cAAc,GAAG,GAAG,KAAK;EACxC,MAAM,OAAO,CAAC;EACd,MAAM,OAAO,CAAC;EACd,OAAO;CACX;AACJ;;;;;AAKA,SAAS,oBAAoB,QAAQ;CACjC,MAAM,UAAU,sBAAsB,MAAM;CAC5C,OAAO,QAAQ,SACT,oBAAoB,MAAM,CAAC,CAAC,OAAO,OAAO,IAC1C,oBAAoB,MAAM;AACpC;;;;AAIA,IAAM,SAEN,OAAO,YAAY,QAAQ,aAAa,eAAe,KAAK,QAAQ,QAAQ;AAE5E,IAAM,eAAe;AACrB,IAAM,eAAe;AACrB,IAAM,cAAc;AACpB,IAAM,EAAE,0BAA0B,SAAS;;;;;;;;;AAS3C,IAAM,iBAEN,OAAO,MACA,SAAS,eAAe,GAAG,GAAG;CAC7B,OAAO,MAAM,IAAI,MAAM,KAAK,IAAI,MAAM,IAAI,IAAI,MAAM,KAAK,MAAM;AACnE;;;;;;;;;;AAkBJ,SAAS,YAAY,GAAG,GAAG;CACvB,OAAO,MAAM;AACjB;;;;AAIA,SAAS,qBAAqB,GAAG,GAAG;CAChC,OAAO,EAAE,eAAe,EAAE,cAAc,oBAAoB,IAAI,WAAW,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC;AACpG;;;;AAIA,SAAS,eAAe,GAAG,GAAG,OAAO;CACjC,IAAI,QAAQ,EAAE;CACd,IAAI,EAAE,WAAW,OACb,OAAO;CAEX,OAAO,UAAU,GACb,IAAI,CAAC,MAAM,OAAO,EAAE,QAAQ,EAAE,QAAQ,OAAO,OAAO,GAAG,GAAG,KAAK,GAC3D,OAAO;CAGf,OAAO;AACX;;;;AAIA,SAAS,kBAAkB,GAAG,GAAG;CAC7B,OAAQ,EAAE,eAAe,EAAE,cACpB,oBAAoB,IAAI,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,GAAG,IAAI,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,CAAC;AACzI;;;;AAIA,SAAS,cAAc,GAAG,GAAG;CACzB,OAAO,eAAe,EAAE,QAAQ,GAAG,EAAE,QAAQ,CAAC;AAClD;;;;AAIA,SAAS,eAAe,GAAG,GAAG;CAC1B,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE;AAChG;;;;AAIA,SAAS,aAAa,GAAG,GAAG,OAAO;CAC/B,MAAM,OAAO,EAAE;CACf,IAAI,SAAS,EAAE,MACX,OAAO;CAEX,IAAI,CAAC,MACD,OAAO;CAEX,MAAM,iBAAiB,IAAI,WAAW,IAAI;CAC1C,MAAM,YAAY,EAAE,QAAQ;CAC5B,IAAI;CACJ,IAAI;CACJ,IAAI,QAAQ;CAEZ,OAAQ,UAAU,UAAU,KAAK,GAAI;EACjC,IAAI,QAAQ,MACR;EAEJ,MAAM,YAAY,EAAE,QAAQ;EAC5B,IAAI,WAAW;EACf,IAAI,aAAa;EAEjB,OAAQ,UAAU,UAAU,KAAK,GAAI;GACjC,IAAI,QAAQ,MACR;GAEJ,IAAI,eAAe,aAAa;IAC5B;IACA;GACJ;GACA,MAAM,SAAS,QAAQ;GACvB,MAAM,SAAS,QAAQ;GACvB,IAAI,MAAM,OAAO,OAAO,IAAI,OAAO,IAAI,OAAO,YAAY,GAAG,GAAG,KAAK,KAC9D,MAAM,OAAO,OAAO,IAAI,OAAO,IAAI,OAAO,IAAI,OAAO,IAAI,GAAG,GAAG,KAAK,GAAG;IAC1E,WAAW,eAAe,cAAc;IACxC;GACJ;GACA;EACJ;EACA,IAAI,CAAC,UACD,OAAO;EAEX;CACJ;CACA,OAAO;AACX;;;;AAIA,SAAS,gBAAgB,GAAG,GAAG,OAAO;CAClC,MAAM,aAAa,KAAK,CAAC;CACzB,IAAI,QAAQ,WAAW;CACvB,IAAI,KAAK,CAAC,CAAC,CAAC,WAAW,OACnB,OAAO;CAMX,OAAO,UAAU,GACb,IAAI,CAAC,gBAAgB,GAAG,GAAG,OAAO,WAAW,MAAM,GAC/C,OAAO;CAGf,OAAO;AACX;;;;AAIA,SAAS,sBAAsB,GAAG,GAAG,OAAO;CACxC,MAAM,aAAa,oBAAoB,CAAC;CACxC,IAAI,QAAQ,WAAW;CACvB,IAAI,oBAAoB,CAAC,CAAC,CAAC,WAAW,OAClC,OAAO;CAEX,IAAI;CACJ,IAAI;CACJ,IAAI;CAKJ,OAAO,UAAU,GAAG;EAChB,WAAW,WAAW;EACtB,IAAI,CAAC,gBAAgB,GAAG,GAAG,OAAO,QAAQ,GACtC,OAAO;EAEX,cAAc,yBAAyB,GAAG,QAAQ;EAClD,cAAc,yBAAyB,GAAG,QAAQ;EAClD,KAAK,eAAe,iBACZ,CAAC,eACE,CAAC,eACD,YAAY,iBAAiB,YAAY,gBACzC,YAAY,eAAe,YAAY,cACvC,YAAY,aAAa,YAAY,WAC5C,OAAO;CAEf;CACA,OAAO;AACX;;;;AAIA,SAAS,0BAA0B,GAAG,GAAG;CACrC,OAAO,eAAe,EAAE,QAAQ,GAAG,EAAE,QAAQ,CAAC;AAClD;;;;AAIA,SAAS,gBAAgB,GAAG,GAAG;CAC3B,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE;AAClD;;;;AAIA,SAAS,aAAa,GAAG,GAAG,OAAO;CAC/B,MAAM,OAAO,EAAE;CACf,IAAI,SAAS,EAAE,MACX,OAAO;CAEX,IAAI,CAAC,MACD,OAAO;CAEX,MAAM,iBAAiB,IAAI,WAAW,IAAI;CAC1C,MAAM,YAAY,EAAE,OAAO;CAC3B,IAAI;CACJ,IAAI;CAEJ,OAAQ,UAAU,UAAU,KAAK,GAAI;EACjC,IAAI,QAAQ,MACR;EAEJ,MAAM,YAAY,EAAE,OAAO;EAC3B,IAAI,WAAW;EACf,IAAI,aAAa;EAEjB,OAAQ,UAAU,UAAU,KAAK,GAAI;GACjC,IAAI,QAAQ,MACR;GAEJ,IAAI,CAAC,eAAe,eACb,MAAM,OAAO,QAAQ,OAAO,QAAQ,OAAO,QAAQ,OAAO,QAAQ,OAAO,GAAG,GAAG,KAAK,GAAG;IAC1F,WAAW,eAAe,cAAc;IACxC;GACJ;GACA;EACJ;EACA,IAAI,CAAC,UACD,OAAO;CAEf;CACA,OAAO;AACX;;;;AAIA,SAAS,oBAAoB,GAAG,GAAG;CAC/B,IAAI,QAAQ,EAAE;CACd,IAAI,EAAE,WAAW,SAAS,EAAE,eAAe,EAAE,YACzC,OAAO;CAEX,OAAO,UAAU,GACb,IAAI,EAAE,WAAW,EAAE,QACf,OAAO;CAGf,OAAO;AACX;;;;AAIA,SAAS,aAAa,GAAG,GAAG;CACxB,OAAQ,EAAE,aAAa,EAAE,YAClB,EAAE,aAAa,EAAE,YACjB,EAAE,aAAa,EAAE,YACjB,EAAE,SAAS,EAAE,QACb,EAAE,SAAS,EAAE,QACb,EAAE,aAAa,EAAE,YACjB,EAAE,aAAa,EAAE;AAC5B;AACA,SAAS,gBAAgB,GAAG,GAAG,OAAO,UAAU;CAC5C,KAAK,aAAa,eAAe,aAAa,gBAAgB,aAAa,kBACnE,EAAE,YAAY,EAAE,WACpB,OAAO;CAEX,OAAO,OAAO,GAAG,QAAQ,KAAK,MAAM,OAAO,EAAE,WAAW,EAAE,WAAW,UAAU,UAAU,GAAG,GAAG,KAAK;AACxG;AAGA,IAAM,WAAW,OAAO,UAAU;;;;AAIlC,SAAS,yBAAyB,QAAQ;CACtC,MAAM,yBAAyB,6BAA6B,MAAM;CAClE,MAAM,EAAE,gBAAgB,eAAe,mBAAmB,cAAc,iBAAiB,iBAAiB,iBAAiB,cAAc,mCAAoC;;;;CAI7K,OAAO,SAAS,WAAW,GAAG,GAAG,OAAO;EAEpC,IAAI,MAAM,GACN,OAAO;EAIX,IAAI,KAAK,QAAQ,KAAK,MAClB,OAAO;EAEX,MAAM,OAAO,OAAO;EACpB,IAAI,SAAS,OAAO,GAChB,OAAO;EAEX,IAAI,SAAS,UAAU;GACnB,IAAI,SAAS,YAAY,SAAS,UAC9B,OAAO,gBAAgB,GAAG,GAAG,KAAK;GAEtC,IAAI,SAAS,YACT,OAAO,kBAAkB,GAAG,GAAG,KAAK;GAGxC,OAAO;EACX;EACA,MAAM,cAAc,EAAE;EAWtB,IAAI,gBAAgB,EAAE,aAClB,OAAO;EAOX,IAAI,gBAAgB,QAChB,OAAO,gBAAgB,GAAG,GAAG,KAAK;EAEtC,IAAI,gBAAgB,OAChB,OAAO,eAAe,GAAG,GAAG,KAAK;EAErC,IAAI,gBAAgB,MAChB,OAAO,cAAc,GAAG,GAAG,KAAK;EAEpC,IAAI,gBAAgB,QAChB,OAAO,gBAAgB,GAAG,GAAG,KAAK;EAEtC,IAAI,gBAAgB,KAChB,OAAO,aAAa,GAAG,GAAG,KAAK;EAEnC,IAAI,gBAAgB,KAChB,OAAO,aAAa,GAAG,GAAG,KAAK;EAEnC,IAAI,gBAAgB,SAGhB,OAAO;EAIX,IAAI,MAAM,QAAQ,CAAC,GACf,OAAO,eAAe,GAAG,GAAG,KAAK;EAIrC,MAAM,MAAM,SAAS,KAAK,CAAC;EAC3B,MAAM,sBAAsB,uBAAuB;EACnD,IAAI,qBACA,OAAO,oBAAoB,GAAG,GAAG,KAAK;EAE1C,MAAM,8BAA8B,kCAAkC,+BAA+B,GAAG,GAAG,OAAO,GAAG;EACrH,IAAI,6BACA,OAAO,4BAA4B,GAAG,GAAG,KAAK;EAUlD,OAAO;CACX;AACJ;;;;AAIA,SAAS,+BAA+B,EAAE,UAAU,oBAAoB,UAAW;CAC/E,IAAI,SAAS;EACT;EACA,gBAAgB,SAAS,wBAAwB;EACjD;EACe;EACC;EAChB,mBAAmB;EACnB,cAAc,SAAS,mBAAmB,cAAc,qBAAqB,IAAI;EACjF,iBAAiB;EACjB,iBAAiB,SAAS,wBAAwB;EACvB;EACV;EACjB,cAAc,SAAS,mBAAmB,cAAc,qBAAqB,IAAI;EACjF,qBAAqB,SACf,mBAAmB,qBAAqB,qBAAqB,IAC7D;EACQ;EACd,gCAAgC,KAAA;CACpC;CACA,IAAI,oBACA,SAAS,OAAO,OAAO,CAAC,GAAG,QAAQ,mBAAmB,MAAM,CAAC;CAEjE,IAAI,UAAU;EACV,MAAM,iBAAiB,iBAAiB,OAAO,cAAc;EAC7D,MAAM,eAAe,iBAAiB,OAAO,YAAY;EACzD,MAAM,kBAAkB,iBAAiB,OAAO,eAAe;EAC/D,MAAM,eAAe,iBAAiB,OAAO,YAAY;EACzD,SAAS,OAAO,OAAO,CAAC,GAAG,QAAQ;GAC/B;GACA;GACA;GACA;EACJ,CAAC;CACL;CACA,OAAO;AACX;;;;;AAKA,SAAS,iCAAiC,SAAS;CAC/C,OAAO,SAAU,GAAG,GAAG,cAAc,cAAc,UAAU,UAAU,OAAO;EAC1E,OAAO,QAAQ,GAAG,GAAG,KAAK;CAC9B;AACJ;;;;AAIA,SAAS,cAAc,EAAE,UAAU,YAAY,aAAa,QAAQ,UAAU;CAC1E,IAAI,aACA,OAAO,SAAS,QAAQ,GAAG,GAAG;EAC1B,MAAM,EAAE,QAAQ,2BAAW,IAAI,QAAQ,IAAI,KAAA,GAAW,SAAS,YAAY;EAC3E,OAAO,WAAW,GAAG,GAAG;GACpB;GACA;GACA;GACA;EACJ,CAAC;CACL;CAEJ,IAAI,UACA,OAAO,SAAS,QAAQ,GAAG,GAAG;EAC1B,OAAO,WAAW,GAAG,GAAG;GACpB,uBAAO,IAAI,QAAQ;GACnB;GACA,MAAM,KAAA;GACN;EACJ,CAAC;CACL;CAEJ,MAAM,QAAQ;EACV,OAAO,KAAA;EACP;EACA,MAAM,KAAA;EACN;CACJ;CACA,OAAO,SAAS,QAAQ,GAAG,GAAG;EAC1B,OAAO,WAAW,GAAG,GAAG,KAAK;CACjC;AACJ;;;;AAIA,SAAS,6BAA6B,EAAE,sBAAsB,gBAAgB,mBAAmB,eAAe,gBAAgB,mBAAmB,cAAc,iBAAiB,iBAAiB,2BAA2B,iBAAiB,cAAc,qBAAqB,gBAAiB;CAC/R,OAAO;EACH,sBAAsB;EACtB,kBAAkB;EAClB,wBAAwB;EACxB,mCAAmC;EACnC,mBAAmB;EACnB,0BAA0B;EAC1B,2BAA2B;EAC3B,oBAAoB;EACpB,qBAAqB;EACrB,iBAAiB;EAGjB,kBAAkB;EAClB,yBAAyB;EACzB,yBAAyB;EACzB,yBAAyB;EACzB,qBAAqB;EACrB,8BAA8B;EAC9B,sBAAsB;EACtB,uBAAuB;EACvB,uBAAuB;EACvB,gBAAgB;EAChB,mBAAmB;EACnB,oBAAoB,GAAG,GAAG,UAI1B,OAAO,EAAE,SAAS,cAAc,OAAO,EAAE,SAAS,cAAc,gBAAgB,GAAG,GAAG,KAAK;EAG3F,mBAAmB;EACnB,gBAAgB;EAChB,mBAAmB;EACnB,gBAAgB;EAChB,uBAAuB;EACvB,8BAA8B;EAC9B,wBAAwB;EACxB,wBAAwB;CAC5B;AACJ;;;;AAKA,IAAM,YAAY,kBAAkB;AAIZ,kBAAkB,EAAE,QAAQ,KAAK,CAAC;AAIhC,kBAAkB,EAAE,UAAU,KAAK,CAAC;AAK9B,kBAAkB;CAC9C,UAAU;CACV,QAAQ;AACZ,CAAC;AAIoB,kBAAkB,EACnC,gCAAgC,eACpC,CAAC;AAI0B,kBAAkB;CACzC,QAAQ;CACR,gCAAgC;AACpC,CAAC;AAI4B,kBAAkB;CAC3C,UAAU;CACV,gCAAgC;AACpC,CAAC;AAKkC,kBAAkB;CACjD,UAAU;CACV,gCAAgC;CAChC,QAAQ;AACZ,CAAC;;;;;;;;;AASD,SAAS,kBAAkB,UAAU,CAAC,GAAG;CACrC,MAAM,EAAE,WAAW,OAAO,0BAA0B,gCAAgC,aAAa,SAAS,UAAW;CAErH,MAAM,aAAa,yBADJ,+BAA+B,OACG,CAAC;CAIlD,OAAO,cAAc;EAAE;EAAU;EAAY;EAAa,QAH3C,iCACT,+BAA+B,UAAU,IACzC,iCAAiC,UAAU;EACiB;CAAO,CAAC;AAC9E;;;;;;;;;;;;;;;;;;;;;;;ACnjBA,SAAgB,kBACZ,YACA,UACkB;CAClB,MAAM,MAAM,YAAY,cAAA;CACxB,MAAM,MAAM,WAAW;CAEvB,MAAM,SAAS,KAAK,UACb,YAAY,WACX,QAAA,cAAkC,MAAM;CAKhD,OAAO;EACH;EACA;EACA,WANc,KAAK,aAAa;EAOhC,YANe,YAAY,cAAc,KAAK;EAO9C,cAAc,0BAA0B,MAAM;CAClD;AACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,SAAgB,uBACZ,YACA,UACO;CASP,OAAO,0BAFQ,YAAY,WACnB,YAAY,aAAa,kBAAkB,YAAY,QAAQ,CAAC,CAAC,SAAS,KAAA,EAC3C,CAAC,CAAC;AAC7C;;;;;;;;;AAUA,SAAgB,sBACZ,aACA,UACG;CACH,OAAO,YAAY,QAAO,eAAc,uBAAuB,YAAY,QAAQ,CAAC;AACxF;;;AC3GA,IAAa,qBAAb,MAAgC;;;;;;CAO5B,cAA0C,CAAC;;;;;;CAO3C;;;;;CAMA,mBAAmB,WAAsC;EACrD,KAAK,mBAAmB;CAC5B;;;;CAKA,qBAAsD;EAClD,OAAO,KAAK;CAChB;CAGA,yCAAiC,IAAI,IAA8B;CACnE,oCAA4B,IAAI,IAA8B;CAC9D,kBAA8C,CAAC;CAC/C,wBAA2D;CAG3D,4CAAoC,IAAI,IAA8B;CACtE,uCAA+B,IAAI,IAA8B;CACjE,qBAAiD,CAAC;CAClD,2BAA8D;CAI9D,qBAA0E;CAE1E,YAAY,aAAkC,aAAkC;EAC5E,IAAI,aAAa,KAAK,cAAc;EACpC,IAAI,aACA,KAAK,iBAAiB,WAAW;CAEzC;;;;;;CAOA,eAAe,aAA0C;EACrD,IAAI,UAAU,KAAK,aAAa,WAAW,GAAG,OAAO;EACrD,KAAK,cAAc,eAAe,CAAC;EACnC,OAAO;CACX;CAEA,QAAQ;EACJ,KAAK,uBAAuB,MAAM;EAClC,KAAK,kBAAkB,MAAM;EAC7B,KAAK,kBAAkB,CAAC;EACxB,KAAK,wBAAwB;EAE7B,KAAK,0BAA0B,MAAM;EACrC,KAAK,qBAAqB,MAAM;EAChC,KAAK,qBAAqB,CAAC;EAC3B,KAAK,2BAA2B;CACpC;;;;;;;;;CAUA,iBAAiB,aAA0C;EAIvD,MAAM,YAAY,YAAY,KAAI,MAAK,gBAAgB,CAAC,CAAC;EACzD,IAAI,KAAK,sBAAsB,UAAU,KAAK,oBAAoB,SAAS,GACvE,OAAO;EAGX,KAAK,MAAM;EAEX,YAAY,SAAS,MAAM;GACvB,IAAI,EAAE,MACF,KAAK,kBAAkB,IAAI,EAAE,MAAM,CAAC;GAExC,KAAK,uBAAuB,IAAI,aAAa,CAAC,GAAG,CAAC;EACtD,CAAC;EAED,MAAM,wBAAwB,YAAY,KAAI,MAAK,KAAK,oBAAoB,EAAE,GAAG,EAAE,CAAC,CAAC;EAOrF,sBAAsB,SAAS,GAAG,UAAU;GACxC,MAAM,MAAM,UAAU,YAAY,MAAM;GACxC,KAAK,gBAAgB,KAAK,CAAC;GAC3B,KAAK,mBAAmB,KAAK,GAAG;GAEhC,MAAM,aAAa,KAAK,oBAAoB,CAAC;GAC7C,KAAK,uBAAuB,IAAI,aAAa,UAAU,GAAG,UAAU;GACpE,KAAK,0BAA0B,IAAI,aAAa,GAAG,GAAG,GAAG;GACzD,IAAI,WAAW,MACX,KAAK,kBAAkB,IAAI,WAAW,MAAM,UAAU;GAE1D,IAAI,IAAI,MACJ,KAAK,qBAAqB,IAAI,IAAI,MAAM,GAAG;EAEnD,CAAC;EAGD,sBAAsB,SAAS,MAAM;GACjC,MAAM,iBAAiB,kBAAkB,CAAC;GAC1C,IAAI,kBAAkB,eAAe,SAAS,GAC1C,eAAe,SAAS,kBAAkB;IACtC,IAAI,CAAC,eAAe;IAEpB,KAAK,qBAAqB,KAAK,oBAAoB,EAAE,GAAG,cAAc,CAAC,GAAG,UAAU,aAAa,CAAC;GACtG,CAAC;EAET,CAAC;EAGD,KAAK,qBAAqB;EAE1B,OAAO;CACX;CAEA,SAAS,YAA8B,eAAkC;EACrE,MAAM,MAAM,gBAAgB,UAAU,aAAa,IAAI,UAAU,UAAU;EAE3E,KAAK,gBAAgB,KAAK,UAAU;EACpC,KAAK,mBAAmB,KAAK,GAAG;EAEhC,KAAK,qBAAqB,YAAY,GAAG;CAC7C;CAEA,qBAA6B,YAA8B,eAAiC;EACxF,IAAI,KAAK,uBAAuB,IAAI,aAAa,UAAU,CAAC,GACxD;EAGJ,MAAM,uBAAuB,KAAK,oBAAoB,UAAU;EAChE,KAAK,uBAAuB,IAAI,aAAa,oBAAoB,GAAG,oBAAoB;EACxF,KAAK,0BAA0B,IAAI,aAAa,aAAa,GAAG,aAAa;EAE7E,IAAI,qBAAqB,MACrB,KAAK,kBAAkB,IAAI,qBAAqB,MAAM,oBAAoB;EAE9E,IAAI,cAAc,MACd,KAAK,qBAAqB,IAAI,cAAc,MAAM,aAAa;EAKnE,MAAM,iBAAiB,kBAAkB,oBAAoB;EAE7D,IAAI,kBAAkB,eAAe,SAAS,GAC1C,eAAe,SAAS,kBAAkB;GACtC,IAAI,CAAC,eAAe;GAEpB,KAAK,qBAAqB,KAAK,oBAAoB,EAAE,GAAG,cAAc,CAAC,GAAG,UAAU,aAAa,CAAC;EACtG,CAAC;CAET;CAEA,oBAA2B,YAAgD;EAIvE,MAAM,SAAS,EAAE,GAAG,WAAW;EAQ/B;GACI,MAAM,WAAW,kBAAkB,QAAQ,KAAK,WAAW;GAC3D,IAAI,CAAC,OAAO,YAAY,OAAoC,aAAa,SAAS;GAClF,IAAI,CAAC,OAAO,QAAQ,OAAgC,SAAS,SAAS;EAC1E;EAiBA,OAAO,aADwB,KAAK,oBAAoB,OAAO,YAAY,MACvD;EAUpB,OAAO;CACX;CAEA,oBAA4B,YAAwB,YAA0C;EAC1F,MAAM,gBAA4B,CAAC;EACnC,KAAK,MAAM,OAAO,YACd,cAAc,OAAO,KAAK,kBAAkB,KAAK,WAAW,MAAM,UAAU;EAEhF,OAAO;CACX;CAEA,kBAA0B,KAAa,UAAoB,YAAwC;EAC/F,MAAM,cAAc,EAAE,GAAG,SAAS;EAElC,IAAI,YAAY,SAAS,SAAS,YAAY,YAC1C,YAAY,aAAa,KAAK,oBAAoB,YAAY,YAAY,UAAU;OACjF,IAAI,YAAY,SAAS,SAAS;GAErC,MAAM,YAAY;GAClB,IAAI,UAAU,IACV,IAAI,MAAM,QAAQ,UAAU,EAAE,GAC1B,UAA6C,KAAK,UAAU,GAAG,KAAK,GAAG,MAAM,KAAK,kBAAkB,GAAG,IAAI,GAAG,EAAE,IAAI,GAAG,UAAU,CAAC;QAElI,UAAU,KAAK,KAAK,kBAAkB,GAAG,IAAI,MAAM,UAAU,IAAI,UAAU;QAE5E,IAAI,UAAU,SAAS,UAAU,MAAM,YAC1C,UAAU,MAAM,aAAa,KAAK,oBAAoB,UAAU,MAAM,YAAY,UAAU;EAEpG,OAAO,KAAK,YAAY,SAAS,YAAY,YAAY,SAAS,aAAa,YAAY,MAAM;GAC7F,MAAM,yBAAyB;GAC/B,IAAI,OAAO,uBAAuB,SAAS,YAAY,CAAC,MAAM,QAAQ,uBAAuB,IAAI,GAC7F,uBAAuB,OAAO,oBAAoB,uBAAuB,IAAI,CAAC,EAAE,QAAQ,UAAU,UAAU,MAAM,MAAM,MAAM,OAAO,MAAM,MAAM,KAAK,KAAK,CAAC;EAEpK,OAAO,IAAI,YAAY,SAAS,YAAY;GACxC,MAAM,mBAAmB;GAMzB,IAAI,iBAAiB,UACjB,iBAAiB,mBAAmB,gBAAgB,iBAAiB,UAAU,YAAY,GAAG;QAC3F;IACH,MAAM,WAAW,2BAA2B,UAAU,CAAC,CAAC;IACxD,IAAI,UACA,iBAAiB,mBAAmB;SAEpC,QAAQ,KACJ,sBAAsB,IAAI,QAAQ,WAAW,KAAK,6EAEtD;GAER;EACJ;EAEA,OAAO;CACX;CAEA,IAAI,MAA4C;EAE5C,MAAM,SAAS,KAAK,kBAAkB,IAAI,IAAI;EAC9C,IAAI,QAAQ,OAAO;EAGnB,IAAI,KAAK,SAAS,GAAG,GAAG;GACpB,MAAM,aAAa,KAAK,QAAQ,MAAM,GAAG;GACzC,MAAM,eAAe,KAAK,kBAAkB,IAAI,UAAU;GAC1D,IAAI,cAAc,OAAO;EAC7B;EAGA,OAAO,KAAK,uBAAuB,IAAI,IAAI;CAC/C;;;;;CAMA,OAAO,MAA4C;EAC/C,MAAM,SAAS,KAAK,qBAAqB,IAAI,IAAI;EACjD,IAAI,QAAQ,OAAO;EAGnB,IAAI,KAAK,SAAS,GAAG,GAAG;GACpB,MAAM,aAAa,KAAK,QAAQ,MAAM,GAAG;GACzC,MAAM,eAAe,KAAK,qBAAqB,IAAI,UAAU;GAC7D,IAAI,cAAc,OAAO;EAC7B;EAEA,OAAO,KAAK,0BAA0B,IAAI,IAAI;CAClD;;;;;CAMA,oBAAoB,gBAAsD;EAEtE,IAAI,CAAC,eAAe,SAAS,GAAG,GAC5B,OAAO,KAAK,IAAI,cAAc;EAIlC,MAAM,eAAe,eAAe,MAAM,GAAG,CAAC,CAAC,QAAO,MAAK,CAAC;EAE5D,IAAI,aAAa,SAAS,KAAK,aAAa,SAAS,MAAM,GACvD,MAAM,IAAI,MAAM,0BAA0B,eAAe,gFAAgF;EAI7I,MAAM,qBAAqB,aAAa;EACxC,IAAI,oBAAoB,KAAK,IAAI,kBAAkB;EAEnD,IAAI,CAAC,mBACD,MAAM,IAAI,MAAM,8BAA8B,oBAAoB;EAItE,KAAK,IAAI,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK,GAAG;GAC7C,MAAM,cAAc,aAAa;GAGjC,IAAI,CAAC,0BAA0B,kBAAkB,MAAM,CAAC,CAAC,mBACrD,MAAM,IAAI,MAAM,gFAAgF,kBAAkB,KAAK,iBAAiB,kBAAkB,OAAO,EAAE;GAGvK,MAAM,WAAW,aADS,2BAA2B,iBACvB,GAAmB,WAAW;GAE5D,IAAI,CAAC,UACD,MAAM,IAAI,MAAM,aAAa,YAAY,6BAA6B,kBAAkB,KAAK,EAAE;GAYnG,MAAM,SAAS,SAAS,OAAO;GAC/B,oBAAoB,KAAK,uBAAuB,IAAI,aAAa,MAAM,CAAC,KACjE,KAAK,oBAAoB,MAAM;GAGtC,IAAI,IAAI,IAAI,aAAa,QAAQ,CAEjC;EACJ;EAEA,OAAO;CACX;CAEA,iBAAqC;EACjC,IAAI,CAAC,KAAK,uBACN,KAAK,wBAAwB,MAAM,KAAK,KAAK,uBAAuB,OAAO,CAAC;EAEhF,OAAO,KAAK;CAChB;CAEA,oBAAwC;EACpC,IAAI,CAAC,KAAK,0BACN,KAAK,2BAA2B,MAAM,KAAK,KAAK,0BAA0B,OAAO,CAAC;EAEtF,OAAO,KAAK;CAChB;;;;;CAMA,yBAAyB,MAIvB;EACE,MAAM,eAAe,KAAK,MAAM,GAAG,CAAC,CAAC,QAAO,MAAK,CAAC;EAElD,IAAI,aAAa,WAAW,GACxB,MAAM,IAAI,MAAM,iBAAiB,MAAM;EAG3C,IAAI,aAAa,SAAS,MAAM,GAC5B,MAAM,IAAI,MAAM,4BAA4B,KAAK,0CAA0C;EAG/F,MAAM,cAAkC,CAAC;EACzC,MAAM,YAAiC,CAAC;EAGxC,IAAI,oBAAoB,KAAK,IAAI,aAAa,EAAE;EAEhD,IAAI,CAAC,mBACD,MAAM,IAAI,MAAM,oCAAoC,aAAa,IAAI;EAGzE,YAAY,KAAK,iBAAiB;EAGlC,KAAK,IAAI,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK,GAAG;GAC7C,MAAM,WAAW,aAAa;GAC9B,UAAU,KAAK,QAAQ;GAEvB,IAAI,IAAI,IAAI,aAAa,QAAQ;IAC7B,MAAM,oBAAoB,aAAa,IAAI;IAC3C,MAAM,iBAAiD,kBAAkB,iBAAiB;IAC1F,IAAI,CAAC,kBAAkB,eAAe,WAAW,GAC7C,MAAM,IAAI,MAAM,+BAA+B,kBAAkB,KAAK,YAAY,MAAM;IAG5F,MAAM,gBAA8C,eAAe,MAAK,MAAK,EAAE,SAAS,iBAAiB;IACzG,IAAI,CAAC,eACD,MAAM,IAAI,MAAM,kBAAkB,kBAAkB,iBAAiB,kBAAkB,MAAM;IAMjG,oBAAoB,KAAK,oBAAoB,aAAa;IAC1D,YAAY,KAAK,iBAAiB;GACtC;EACJ;EAEA,OAAO;GACH;GACA;GACA,iBAAiB;EACrB;CACJ;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AEjcA,SAAgB,iBAAiB,SAAmD;CAChF,IAAI,CAAC,WAAW,QAAQ,WAAW,GAAG,OAAO,KAAA;CAI7C,MAAM,OAAO,MAAM,QAAQ,QAAQ,EAAE,IAC/B,UACA,CAAC,OAA2B;CAClC,IAAI,KAAK,WAAW,GAAG,OAAO,KAAA;CAC9B,OAAO,KAAK,KAAK,CAAC,KAAK,eAAe,CAAC,gBAAgB,GAAG,GAAG,SAAS,CAAiB;AAC3F;;;;;;;;;;;;;;;;;AA2BA,SAAgB,uBACZ,SACA,OAC0B;CAC1B,IAAI,CAAC,SAAS,OAAO,KAAA;CACrB,IAAI,OAAO,YAAY,UAAU,OAAO,CAAC,CAAC,SAAS,UAAU,SAAS,SAAS,KAAK,CAAC;CACrF,OAAO,QAAQ,SAAS,IAAI,UAAU,KAAA;AAC1C;;AAGA,IAAa,mBAAb,cAAsC,MAAM;CACxC,OAAgB;CAChB,YAAY,QAAgB;EACxB,MACI,wBAAwB,OAAO,4GAEnC;EACA,KAAK,OAAO;CAChB;AACJ;;;;;;;;;;;;;AAcA,SAAgB,uBAAuB,KAAc,OAAoD;CACrG,IAAI,QAAQ,KAAA,KAAa,QAAQ,QAAQ,QAAQ,IAAI,OAAO,KAAA;CAG5D,IAAI,OAAO,QAAQ,UAAU,OAAO,uBAAuB,KAAK,KAAK;CACrE,IAAI,CAAC,MAAM,QAAQ,GAAG,KAAK,IAAI,WAAW,GACtC,MAAM,IAAI,iBAAiB,GAAG,OAAO,IAAI,4CAA4C;CAKzF,IAAI,OAAO,IAAI,OAAO,YAAY,wBAAwB,IAAI,EAAE,GAAG,OAAO,CAAC,cAAc,KAAK,CAAC,CAAC;CAEhG,OAAO,IAAI,IAAI,aAAa;AAChC;AAEA,SAAS,cAAc,KAAc,OAA6B;CAC9D,IAAI,CAAC,MAAM,QAAQ,GAAG,GAClB,MAAM,IAAI,iBAAiB,SAAS,MAAM,mBAAmB;CAMjE,MAAM,MAAM,wBAAwB,IAAI,EAAE,IAAI,gBAAgB,IAAI,EAAE,IAAI,IAAI;CAC5E,IAAI,OAAO,QAAQ,YAAY,IAAI,KAAK,MAAM,IAC1C,MAAM,IAAI,iBAAiB,SAAS,MAAM,mBAAmB;CAEjE,MAAM,YAAY,IAAI;CACtB,IAAI,cAAc,KAAA,KAAa,cAAc,SAAS,cAAc,QAChE,MAAM,IAAI,iBAAiB,SAAS,MAAM,kBAAkB,OAAO,SAAS,EAAE,EAAE;CAEpF,OAAO,CAAC,KAAK,aAAa,KAAK;AACnC;;;AC3GA,IAAa,eAAb,MAA2H;CAQnG;CAFpB,SAA6B,EAAE,OAAO,CAAC,EAAE;CAEzC,YAAY,YAA2C;EAAnC,KAAA,aAAA;CAAoC;CASxD,MAAM,mBAA8C,UAA0B,OAAuB;EAEjG,IAAI,OAAO,sBAAsB,YAAY,sBAAsB,QAAQ,UAAU,mBAAmB;GACpG,KAAK,OAAO,UAAU;GACtB,OAAO;EACX;EAEA,IAAI,CAAC,KAAK,OAAO,OACb,KAAK,OAAO,QAAQ,CAAC;EAGzB,MAAM,SAAS;EACf,MAAM,YAAsC,CAAC,UAAW,KAAK;EAC7D,MAAM,WAAW,KAAK,OAAO,MAAM;EAEnC,IAAI,aAAa,KAAA,GACb,KAAK,OAAO,MAAM,UAAU;OACzB,IAAI,MAAM,QAAQ,QAAQ,KAAK,SAAS,SAAS,KAAK,MAAM,QAAQ,SAAS,EAAE,GAClF,KAAM,OAAO,MAAM,OAAO,CAAgC,KAAK,SAAS;OACrE;GAEH,IAAI;GACJ,IAAI,MAAM,QAAQ,QAAQ,KAAK,SAAS,WAAW,KAAK,OAAO,SAAS,OAAO,UAC3E,iBAAiB;QAEjB,iBAAiB,CAAC,MAAM,QAAQ;GAEpC,KAAK,OAAO,MAAM,UAAU,CAAC,gBAAgB,SAAS;EAC1D;EAEA,OAAO;CACX;;;;;;;;;;;;CAaA,QAAQ,QAAgD,YAA4B,OAAa;EAC7F,MAAM,WAAW,iBAAiB,KAAK,OAAO,OAAO,KAAK,CAAC;EAC3D,KAAK,OAAO,UAAU,CAAC,GAAG,UAAU,CAAC,QAAQ,SAAS,CAAiB;EACvE,OAAO;CACX;;;;CAKA,MAAM,OAAqB;EACvB,KAAK,OAAO,QAAQ;EACpB,OAAO;CACX;;;;CAKA,OAAO,OAAqB;EACxB,KAAK,OAAO,SAAS;EACrB,OAAO;CACX;;;;CAKA,OAAO,cAAsB,SAAuC;EAChE,KAAK,OAAO,eAAe;EAC3B,IAAI,SAAS,YAAY,KAAA,GAAW,KAAK,OAAO,gBAAgB,QAAQ;EACxE,OAAO;CACX;;;;;;;CAQA,aACI,UACA,QACA,SACI;EACJ,KAAK,OAAO,eAAe;GACvB;GACA;GACA,GAAI,SAAS,aAAa,KAAA,KAAa,EAAE,UAAU,QAAQ,SAAS;GACpE,GAAI,SAAS,cAAc,KAAA,KAAa,EAAE,WAAW,QAAQ,UAAU;EAC3E;EACA,OAAO;CACX;;;;;;;;;;;;;CAcA,QAAQ,GAAG,WAA2B;EAClC,KAAK,OAAO,UAAU;EACtB,OAAO;CACX;;;;CAKA,MAAM,OAAiC;EACnC,OAAO,KAAK,WAAW,KAAK,KAAK,MAAuB;CAC5D;;;;CAKA,OAAO,UAA2C,SAA8C;EAC5F,IAAI,CAAC,KAAK,WAAW,QACjB,MAAM,IAAI,MAAM,+EAA+E;EAEnG,OAAO,KAAK,WAAW,OAAO,KAAK,QAAyB,UAAU,OAAO;CACjF;AACJ;;ACnJA,IAAa,4BAA4B;;;;;;AAOzC,IAAa,oBAAoB;;;;;;;;AAsBjC,IAAa,wBAAb,MAAa,8BAA8B,MAAM;CAC7C;CAEA,YAAY,MAA2B,SAAiB;EACpD,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,OAAO;EAGZ,OAAO,eAAe,MAAM,sBAAsB,SAAS;CAC/D;AACJ;;;;;;;;;;;;;;;;AAqBA,SAAgB,kBACZ,QACmE;CACnE,MAAM,QAAQ,QAAQ,SAAA;CACtB,MAAM,SAAS,QAAQ,QAAQ,OACzB,KAAK,IAAI,IAAI,OAAO,OAAO,KAAK,KAAK,IACpC,QAAQ,UAAU;CACzB,OAAO;EACH;EACA;EACA,cAAc,QAAQ,QAAQ,OAAO,SAAS,QAAQ;CAC1D;AACJ;AAEA,SAAS,kBAAkB,KAAiC;CACxD,IAAI,QAAQ,KAAA,KAAa,CAAC,OAAO,SAAS,GAAG,GAAG,OAAA;CAChD,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,GAAG,CAAC;AACtC;AAEA,SAAS,kBAAkB,KAAiC;CACxD,IAAI,QAAQ,KAAA,GAAW,OAAO;CAC9B,IAAI,QAAQ,OAAO,mBAAmB,OAAO;CAC7C,IAAI,CAAC,OAAO,SAAS,GAAG,GAAG,OAAO;CAClC,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,GAAG,CAAC;AACtC;AAEA,SAAS,iBAAiB,KAAiC;CACvD,IAAI,QAAQ,KAAA,GAAW,OAAO;CAC9B,IAAI,QAAQ,OAAO,mBAAmB,OAAO;CAC7C,IAAI,CAAC,OAAO,SAAS,GAAG,GAAG,OAAO;CAClC,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,GAAG,CAAC;AACtC;;;;;;;;;AAUA,SAAS,gBACL,OACA,QACA,WAC0B;CAC1B,MAAM,OAAO,EAAE,GAAI,SAAS,CAAC,EAAG;CAChC,MAAM,WAAW,KAAK;CACtB,IAAI,aAAa,KAAA,GACb,KAAK,UAAU;MACZ,IAAI,MAAM,QAAQ,QAAQ,KAAK,SAAS,SAAS,KAAK,MAAM,QAAQ,SAAS,EAAE,GAClF,KAAK,UAAU,CAAC,GAAI,UAAyC,SAAS;MAEtE,KAAK,UAAU,CAAC,UAAU,SAAS;CAEvC,OAAO;AACX;AAEA,SAAS,aAAa,GAAY,GAAqB;CACnD,IAAI,aAAa,QAAQ,aAAa,MAAM,OAAO,EAAE,QAAQ,MAAM,EAAE,QAAQ;CAC7E,OAAO,OAAO,GAAG,GAAG,CAAC;AACzB;;;;;;;;;;;;AAaA,gBAAuB,aACnB,MACA,QACA,QAAQ,cAC0B;CAClC,MAAM,EACF,UACA,QACA,UACA,GAAG,SACF,UAAU,CAAC;CAEhB,MAAM,aAAa,EAAE,GAAG,KAAK;CAC7B,MAAM,OAAO,kBAAkB,QAA8B;CAC7D,MAAM,UAAU,kBAAkB,QAA8B;CAGhE,MAAM,cAAc,OAAO,WAAW,WAAW,SAAS,QAAQ;CAClE,MAAM,qBAAsB,OAAO,WAAW,YAAY,WAAW,OAC/D,OAAO,YACP,KAAA;CAEN,IAAI,YAA4B;CAChC,IAAI,aAAa;EACb,MAAM,UAAU,iBAAiB,WAAW,OAAO;EAKnD,IAAI,WAAW,QAAQ,SAAS,GAC5B,MAAM,IAAI,sBACN,yBACA,mBAAmB,YAAY,oBAAoB,MAAM,OACtD,QAAQ,KAAK,CAAC,WAAW,IAAI,MAAM,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,gEAExC,YAAY,gDAC7B;EAEJ,IAAI,WAAW,QAAQ,EAAE,CAAC,OAAO,aAC7B,MAAM,IAAI,sBACN,yBACA,mBAAmB,YAAY,oBAAoB,MAAM,QAAQ,QAAQ,EAAE,CAAC,GAAG,wFAElE,YAAY,0CAC7B;EAEJ,YAAY,sBAAsB,UAAU,EAAE,CAAC,MAAM;EACrD,WAAW,UAAU,CAAC,aAAa,SAAS;CAChD;CACA,MAAM,SAAwB,cAAc,SAAS,MAAM;CAC3D,MAAM,YAAY,WAAW;CAE7B,IAAI,SAAS;CACb,IAAI,QAAQ;CACZ,IAAI;CACJ,IAAI,UAAU;CAEd,SAAS;EACL,IAAI,SAAS,SACT,MAAM,IAAI,sBACN,aACA,cAAc,MAAM,SAAS,MAAM,iNAGvC;EAGJ,MAAM,aAA4B;GAAE,GAAG;GAAY,OAAO;EAAK;EAC/D,IAAI;OACI,SACA,WAAW,QAAQ,gBAAmB,WAAW,aAAa,CAAC,QAAQ,WAAW,CAAC;EAAA,OAGvF,WAAW,SAAS;EAGxB,MAAM,OAAO,MAAM,KAAK,UAAU;EAClC,SAAS;EAET,MAAM,OAAO,MAAM,QAAQ,CAAC;EAI5B,IAAI,KAAK,WAAW,GAAG;EAEvB,KAAK,MAAM,OAAO,MACd,MAAM;EAOV,IAAI,MAAM,MAAM,YAAY,MAAM;EAElC,IAAI,aAAa;GAEb,MAAM,YADO,KAAK,KAAK,SAAS,EACd,GAAO;GACzB,IAAI,cAAc,KAAA,KAAa,cAAc,MACzC,MAAM,IAAI,sBACN,kBACA,qCAAqC,MAAM,4CAChC,YAAY,4DAC3B;GAEJ,IAAI,WAAW,aAAa,WAAW,WAAW,GAC9C,MAAM,IAAI,sBACN,kBACA,cAAc,MAAM,0CACjB,YAAY,GAAG,OAAO,SAAS,EAAE,wLAGxC;GAEJ,cAAc;GACd,UAAU;EACd,OAII,UAAU,KAAK;CAEvB;AACJ;;;;;;AAOA,eAAsB,gBAClB,MACA,QACA,QAAQ,cACI;CACZ,MAAM,EAAE,SAAS,GAAG,SAAU,UAAU,CAAC;CACzC,MAAM,MAAM,iBAAiB,OAA6B;CAE1D,MAAM,MAAW,CAAC;CAClB,WAAW,MAAM,OAAO,aAAgB,MAAM,MAA0B,KAAK,GAAG;EAC5E,IAAI,KAAK,GAAG;EACZ,IAAI,IAAI,SAAS,KACb,MAAM,IAAI,sBACN,YACA,YAAY,MAAM,uBAAuB,IAAI,6BAA6B,IAAI,iKAGlF;CAER;CACA,OAAO;AACX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC9OA,IAAM,mBAAmB;;;;;;;;;;;;;;;;AAqBzB,SAAS,kBAAkB,OAAuB;CAC9C,IAAI,SAAS;CACb,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACnC,MAAM,OAAO,MAAM,IAAI;EACvB,IAAI,MAAM,OAAO,SAAS,SAAS,QAAQ,SAAS,OAAO,SAAS,OAAO,SAAS,MAAM;GACtF,UAAU;GACV;GACA;EACJ;EACA,UAAU,MAAM;CACpB;CACA,OAAO;AACX;;;;;;;;;AAUA,SAAS,eAAe,OAAyB;CAC7C,MAAM,QAAkB,CAAC;CACzB,IAAI,UAAU;CACd,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAC9B,IAAI,MAAM,OAAO,QAAQ,IAAI,IAAI,MAAM,QAAQ;EAG3C,WAAW,MAAM,KAAK,MAAM,IAAI;EAChC;CACJ,OAAO,IAAI,MAAM,OAAO,KAAK;EACzB,MAAM,KAAK,kBAAkB,OAAO,CAAC;EACrC,UAAU;CACd,OACI,WAAW,MAAM;CAGzB,MAAM,KAAK,kBAAkB,OAAO,CAAC;CACrC,OAAO;AACX;;;;;;;;;;;;;;AA+CA,IAAM,iBAAiB,IAAI,IACvB,OAAO,QAAQ,iBAAiB,CACpC;AAC4B,IAAI,IAC5B,OAAO,QAAQ,iBAAiB,CACpC;;AAOA,IAAM,sBAAsB,qBAAqB,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgC1D,IAAa,6BAAb,cAAgD,MAAM;;CAElD;;CAEA;;CAEA,iBAA2D;;CAE3D,aAA6B;CAC7B,OAAuB;CACvB;CAEA,YAAY,OAAe,UAAkB;EACzC,MACI,4BAA4B,SAAS,cAAc,MAAM,sBACnC,qBAC1B;EACA,KAAK,OAAO;EACZ,KAAK,QAAQ;EACb,KAAK,WAAW;EAChB,KAAK,UAAU;GAAE;GAAO;GAAU,gBAAgB;EAAqB;CAC3E;AACJ;;;;;;;;;;;;AAaA,IAAM,oBAAoB;;AAG1B,SAAS,sBAAsB,IAAoB;CAC/C,OAAO,GAAG,YAAY,CAAC,CAAC,QAAQ,cAAc,EAAE;AACpD;;;;;;;;;;AAWA,IAAM,sBAA2C,IAAI,IACjD,CAAC,GAAG,sBAAsB,GAAG,OAAO,KAAK,iBAAiB,CAAC,CAAC,CAAC,IAAI,qBAAqB,CAC1F;;;;;;;;;;;;;;;;;;;;AAqBA,IAAM,sCAA2C,IAAI,IAAI;CACrD;CAAY;CAAe;CAAkB;CAC7C;CAAY;CACZ;CAAc;CAAiB;CAAc;CAC7C;CAAY;CACZ;CAAW;CAAc;CAAS;CAClC;CAAW;CACX;CAAU;CAAa;CAAW;CAAa;CAC/C;CAAe;CAAsB;CACrC;CAAY;CAAmB;CAC/B;CAAW;CACX;CAAS;CAAU;CAAS;CAC5B;CAAQ;AACZ,CAAC;;;;;;;AAQD,SAAS,iBAAiB,IAAqB;CAC3C,IAAI,OAAO,KAAK,OAAO;CACvB,IAAI,kBAAkB,KAAK,EAAE,GAAG,OAAO;CACvC,MAAM,aAAa,sBAAsB,EAAE;CAC3C,IAAI,CAAC,YAAY,OAAO;CACxB,OAAO,oBAAoB,IAAI,UAAU,KAAK,oBAAoB,IAAI,UAAU;AACpF;;;;;;;;;;;;;;;;;;AAmBA,SAAS,UAAU,OAAe,KAAoD;CAClF,IAAI,CAAC,MAAM,QAAQ,GAAG,KAAK,IAAI,WAAW,GAAG,OAAO,KAAA;CACpD,MAAM,CAAC,IAAI,SAAS;CACpB,IAAI,OAAO,OAAO,UAAU,OAAO,KAAA;CAEnC,MAAM,YAAY,cAAc,EAAE;CAClC,IAAI,WAAW,OAAO,CAAC,WAAW,KAAK;CAUvC,IAAI,GAAG,SAAS,GAAG,GAAG,OAAO,KAAA;CAE7B,IAAI,iBAAiB,EAAE,GAAG,MAAM,IAAI,2BAA2B,OAAO,EAAE;AAG5E;;;;;;;;;;;;AA2IA,SAAS,kBAAkB,KAAuC;CAC9D,MAAM,WAAW,IAAI,QAAQ,GAAG;CAChC,IAAI,aAAa,IAEb,OAAO,CAAC,MAAM,GAAG;CAGrB,MAAM,SAAS,IAAI,UAAU,GAAG,QAAQ;CACxC,MAAM,OAAO,IAAI,UAAU,WAAW,CAAC;CAKvC,MAAM,cAAc,eAAe,IAAI,MAAM;CAC7C,IAAI,CAAC,aAGD,OAAO,CAAC,MAAM,GAAG;CAKrB,IAAI,SAAS,IAAI,WAAW,GACxB,OAAO,CAAC,aAAa,IAAI;CAI7B,IAAI,KAAK,WAAW,GAAG,KAAK,KAAK,SAAS,GAAG,GAAG;EAC5C,MAAM,QAAQ,KAAK,MAAM,GAAG,EAAE;EAI9B,OAAO,CAAC,aADM,UAAU,mBAAmB,CAAC,IAAI,eAAe,KAAK,CAC1C;CAC9B;CAEA,OAAO,CAAC,aAAa,IAAI;AAC7B;;;;;;;;;;;;;;;;;AAkBA,SAAgB,kBACZ,OACoB;CACpB,MAAM,SAA+B,CAAC;CAEtC,KAAK,MAAM,CAAC,OAAO,QAAQ,OAAO,QAAQ,KAAK,GAAG;EAC9C,IAAI,QAAQ,KAAA,GAAW;EAGvB,MAAM,QAAQ,UAAU,OAAO,GAAG;EAClC,IAAI,OAAO;GACP,OAAO,SAAS;GAChB;EACJ;EAEA,IAAI,MAAM,QAAQ,GAAG,GAAG;GACpB,IAAI,IAAI,WAAW,GAAG;GAMtB,IAAI,MAAM,QAAQ,IAAI,EAAE,GAAG;IACvB,MAAM,SAAS,IAAI,KAAI,SAAQ,UAAU,OAAO,IAAI,CAAC;IACrD,IAAI,OAAO,OAAO,MAAqC,MAAM,KAAA,CAAS,GAAG;KACrE,OAAO,SAAS;KAChB;IACJ;GACJ;GAEA,IAAI,IAAI,WAAW,GACf,OAAO,SAAS,OAAO,IAAI,OAAO,WAAW,kBAAkB,IAAI,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;QAGtF,IAAI,OAAO,IAAI,OAAO,YAAY,IAAI,EAAE,CAAC,SAAS,GAAG,GACjD,OAAO,SAAS,IAAI,KAAI,MAAK,OAAO,MAAM,WAAW,kBAAkB,CAAC,IAAK,CAAC,MAAM,CAAC,CAA8B;QAUnH,OAAO,SAAS,CAAC,MAAM,GAAG;EAGtC,OAAO,IAAI,OAAO,QAAQ,UACtB,OAAO,SAAS,kBAAkB,GAAG;OAErC,OAAO,SAAS,CAAC,MAAM,GAAG;CAElC;CAEA,OAAO;AACX;;;AClkBA,SAAS,yBAAyB,SAA6B;CAC3D,MAAM,wBAAQ,IAAI,IAA8B;CAChD,MAAM,yBAAS,IAAI,IAAY;CAE/B,OAAO,SAAS,eAAe,MAAgC;EAC3D,MAAM,SAAS,MAAM,IAAI,IAAI;EAC7B,IAAI,QAAQ,OAAO;EAEnB,MAAM,aAAa,SAAS,oBAAoB,IAAI;EACpD,IAAI,CAAC,YAGD,OAAO,CAAC;EAGZ,MAAM,OAAO,mBAAmB,UAAU;EAC1C,IAAI,KAAK,SAAS,GAAG;GAIjB,MAAM,IAAI,MAAM,IAAI;GACpB,OAAO;EACX;EAEA,IAAI,CAAC,OAAO,IAAI,IAAI,GAAG;GACnB,OAAO,IAAI,IAAI;GAGf,QAAQ,KACJ,wBAAwB,KAAK,4PAIjC;EACJ;EACA,OAAO;CACX;AACJ;;;;;;;;;;;;AAaA,SAAS,YACL,KACA,MACA,cAAgC,CAAC,GACxB;CAKT,MAAM,EAAE,UAAU,GAAG,WAAW;CAEhC,OAAO;EACH,IAAI,YAAY,SAAS,IACnB,iBAAiB,KAAK,WAAW,IACjC,IAAI;EACV,MAAM;EACE;EACR,GAAI,WAAW,EAAE,eAAe,SAAS,IAAI,CAAC;CAClD;AACJ;;;;;;AAOA,SAAS,mBACL,OAC4E;CAC5E,OAAO,OAAO,UAAU,YACjB,UAAU,QACV,CAAC,MAAM,QAAQ,KAAK,KACnB,MAA+B,WAAW;AACtD;;AAGA,SAAS,eAAe,UAAoF;CACxG,OAAO,SAAS,MAAM,UAAU,CAAC;AACrC;;;;;;;;;;;;;;AAeA,SAAS,mBAAmB,KAAuD;CAC/E,IAAI;CACJ,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,GAAG,GACzC,IAAI,mBAAmB,KAAK,GAAG;EAC3B,MAAM,OAAO,EAAE,GAAG,IAAI;EACtB,IAAI,OAAO,eAAe,KAAK;CACnC,OAAO,IAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,KAAK,kBAAkB,GAAG;EAC/D,MAAM,OAAO,EAAE,GAAG,IAAI;EACtB,IAAI,OAAO,MAAM,KAAK,SAAS,mBAAmB,IAAI,IAAI,eAAe,IAAI,IAAI,IAAI;CACzF;CAEJ,OAAO,OAAO;AAClB;AAEA,SAAS,qBACL,QACA,MACA,eAAuC,CAAC,GACnB;CACrB,MAAM,WAAkC;EACpC,MAAM,KAAK,QAAkD;GAEzD,MAAM,SAAS,QAAQ,QAAQ,kBAAkB,OAAO,KAAgC,IAAI,KAAA;GAC5F,MAAM,EAAE,OAAO,QAAQ,iBAAiB,kBAAkB,MAAM;GAiBhE,MAAM,eAAe,OAAO;GAC5B,MAAM,OAAO,eACP,MAAM,aAAa,uBACjB,MACA;IACI;IAIA,SAAS,QAAQ;IACjB;IACA,QAAQ;IACR,SAAS,iBAAiB,QAAQ,OAAO;IACzC,cAAc,QAAQ;GAC1B,GACA,QAAQ,OACZ,IACE,MAAM,OAAO,gBAAmB;IAC9B,MAAM;IACN;IACA,QAAQ;IACR;IACA,SAAS,QAAQ;IACjB,SAAS,iBAAiB,QAAQ,OAAO;IACzC,cAAc,QAAQ;GAC1B,CAAC;GAGL,IAAI,QAAQ,KAAK,SAAS;GAC1B,IAAI,UAAU,KAAK,UAAU;GAC7B,IAAI,OAAO,OAAO;IAKd,QAAQ,MAAM,OAAO,MAAM;KACvB,MAAM;KACN;KACA,SAAS,QAAQ;KACjB,cAAc,QAAQ;IAC1B,CAAC;IACD,UAAU,SAAS,KAAK,SAAS;GACrC;GAEA,OAAO;IACH,MAAM,KAAK,KAAK,QAAiC,YAAe,KAAK,MAAM,OAAO,CAAC,CAAC;IACpF,MAAM;KAAE;KAAO;KAAO;KAAQ;IAAQ;GAC1C;EACJ;EAEA,MAAM,SAAS,IAAqD;GAGhE,MAAM,eAAe,OAAO;GAC5B,MAAM,MAAM,eACN,MAAM,aAAa,gBAAgB,MAAM,EAAE,IAC3C,MAAM,OAAO,SAAY;IAAE,MAAM;IAAU;GAAG,CAAC;GACrD,OAAO,MAAM,YAAe,KAAK,MAAM,OAAO,CAAC,IAAI,KAAA;EACvD;EAEA,MAAM,OAAO,MAAgC,IAA0C;GAOnF,OAAO,YAAe,MANJ,OAAO,KAAQ;IAC7B,MAAM;IACN,QAAQ;IACJ;IACJ,QAAQ;GACZ,CAAC,GAC0B,MAAM,OAAO,CAAC;EAC7C;EAEA,YAAY,OAAO,WACb,OAAO,MAAkC,YAAyD;GAMhG,QAAO,MALY,OAAO,SAAa;IACnC,MAAM;IACN,MAAM;IACN,QAAQ,SAAS;GACrB,CAAC,EAAA,CACW,KAAK,QAAQ,YAAe,KAAK,MAAM,OAAO,CAAC,CAAC;EAChE,IACE,KAAA;EAEN,MAAM,OAAO,IAAqB,MAAoD;GAOlF,OAAO,YAAe,MANJ,OAAO,KAAQ;IAC7B,MAAM;IACN,QAAQ;IACJ;IACJ,QAAQ;GACZ,CAAC,GAC0B,MAAM,OAAO,CAAC;EAC7C;EAEA,MAAM,OAAO,IAAoC;GAC7C,OAAO,OAAO,OAAO,EACjB,KAAK;IAAE;IACvB,MAAM;IACN,QAAQ,CAAC;GAA6B,EAC1B,CAAC;EACL;EAMA,YAAY,OAAO,aACb,OAAO,YAA6F;GAMlG,QAAO,MALY,OAAO,WAAe;IACrC,MAAM;IACN,SAAS,QAAQ,KAAI,OAAM;KAAE,IAAI,EAAE;KACvD,QAAQ,EAAE;IAAK,EAAE;GACD,CAAC,EAAA,CACW,KAAI,QAAO,YAAe,KAAK,MAAM,OAAO,CAAC,CAAC;EAC9D,IACE,KAAA;EAEN,YAAY,OAAO,aACb,OAAO,QAA4C;GACjD,MAAM,OAAO,WAAe;IAAE,MAAM;IACpD;GAAI,CAAC;EACO,IACE,KAAA;EAEN,OAAO,OAAO,QACR,OAAO,WAA4C;GACjD,MAAM,SAAS,QAAQ,QAAQ,kBAAkB,OAAO,KAAgC,IAAI,KAAA;GAI5F,OAAO,OAAO,MAAO;IACjB,MAAM;IACN;IACA,SAAS,QAAQ;IACjB,cAAc,QAAQ;GAC1B,CAAC;EACL,IACE,KAAA;EAEN,QAAQ,OAAO,oBACR,QAAmC,UAA+C,YAAqC;GACtH,MAAM,EAAE,OAAO,QAAQ,iBAAiB,kBAAkB,MAAM;GAIhE,MAAM,YAAY,OAAO,mBAAmB,sBAAsB,QAAiC;GACnG,OAAO,OAAO,iBAAqB;IAC/B,MAAM;IACN;IACA,QAAQ;IACR,QAAQ,QAAQ;IAChB,SAAS,QAAQ;IACjB,SAAS,iBAAiB,QAAQ,OAAO;IACzC,cAAc,QAAQ;IACtB,eAAe,QAAQ;IACvB,WAAW,aAAa;KACpB,SAAS;MACL,MAAM,SAAS,KAAK,QAAiC,YAAe,UAAU,GAAG,GAAG,MAAM,OAAO,CAAC,CAAC;MACnG,MAAM;OAMF,OAAO,SAAS,SAAS;OACzB;OACA;OACA,SAAS,SAAS,UAAU;MAChC;KACJ,CAAC;IACL;IACA;GACJ,CAAC;EACL,IAAI,KAAA;EAER,YAAY,OAAO,aACZ,IAAqB,UAAmD,YAAqC;GAC5G,MAAM,YAAY,OAAO,mBAAmB,sBAAsB,QAAiC;GACnG,OAAO,OAAO,UAAc;IACxB,MAAM;IACF;IACJ,WAAW,WAAW,SAAS,SAAS,YAAe,UAAU,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,KAAA,CAAS;IACrG;GACJ,CAAC;EACL,IAAI,KAAA;EAGR,MAAM,mBAA8C,UAA0B,OAAiB;GAC3F,MAAM,UAAU,IAAI,aAAgB,QAAQ;GAC5C,IAAI,OAAO,sBAAsB,UAC7B,OAAO,QAAQ,MAAM,iBAAiB;GAE1C,OAAO,QAAQ,MAAM,mBAAuC,UAAW,KAA0D;EACrI;EACA,QAAQ,QAAgD,WAA4B;GAChF,OAAO,IAAI,aAAgB,QAAQ,CAAC,CAAC,QAAQ,QAAQ,SAAS;EAClE;EACA,MAAM,OAAe;GACjB,OAAO,IAAI,aAAgB,QAAQ,CAAC,CAAC,MAAM,KAAK;EACpD;EACA,OAAO,OAAe;GAClB,OAAO,IAAI,aAAgB,QAAQ,CAAC,CAAC,OAAO,KAAK;EACrD;EACA,OAAO,cAAsB,SAAiC;GAC1D,OAAO,IAAI,aAAgB,QAAQ,CAAC,CAAC,OAAO,cAAc,OAAO;EACrE;EACA,aACI,UACA,QACA,SACF;GACE,OAAO,IAAI,aAAgB,QAAQ,CAAC,CAAC,aAAa,UAAU,QAAQ,OAAO;EAC/E;EACA,QAAQ,GAAG,WAAqB;GAC5B,OAAO,IAAI,aAAgB,QAAQ,CAAC,CAAC,QAAQ,GAAG,SAAS;EAC7D;CACJ;CAEA,OAAO;AACX;;;;;;;;;;;;;AAcA,SAAgB,gBAAgB,QAAoB,SAAyC;CACzF,MAAM,wBAAQ,IAAI,IAAgC;CAClD,MAAM,iBAAiB,yBAAyB,OAAO;CAEvD,SAAS,YAAY,MAAkC;EACnD,IAAI,WAAW,MAAM,IAAI,IAAI;EAC7B,IAAI,CAAC,UAAU;GACX,WAAW,qBAAqB,QAAQ,YAAY,eAAe,IAAI,CAAC;GACxE,MAAM,IAAI,MAAM,QAAQ;EAC5B;EACA,OAAO;CACX;CAMA,OAAO,IAAI,MAAM,EAHb,YAAY,YAGC,GAAQ,EACrB,IAAI,SAAS,MAAuB;EAChC,IAAI,SAAS,cAAc,OAAO;EAElC,IAAI,OAAO,SAAS,UAAU,OAAO,KAAA;EAErC,IAAI,SAAS,UAAU,SAAS,YAAY,SAAS,YAAY,OAAO,KAAA;EAIxE,OAAO,YADM,YAAY,IACN,CAAI;CAC3B,EACJ,CAAC;AACL;;;;;;AAWA,SAAS,YAA+C,QAAsB;CAC1E,OAAO,OAAO;AAClB;;;;;;AAOA,IAAM,kBAAN,MAA0H;CAGlG;CAFpB,SAA6B,EAAE,OAAO,CAAC,EAAE;CAEzC,YAAY,QAAwC;EAAhC,KAAA,SAAA;CAAiC;CAIrD,MAAM,mBAA8C,UAA0B,OAAuB;EACjG,IAAI,OAAO,sBAAsB,YAAY,sBAAsB,QAAQ,UAAU,mBAAmB;GACpG,KAAK,OAAO,UAAU;GACtB,OAAO;EACX;EACA,IAAI,CAAC,KAAK,OAAO,OAAO,KAAK,OAAO,QAAQ,CAAC;EAC7C,MAAM,SAAS;EACf,MAAM,YAAsC,CAAC,UAAW,KAAK;EAC7D,MAAM,WAAW,KAAK,OAAO,MAAM;EACnC,IAAI,aAAa,KAAA,GACb,KAAK,OAAO,MAAM,UAAU;OACzB,IAAI,MAAM,QAAQ,QAAQ,KAAK,SAAS,SAAS,KAAK,MAAM,QAAQ,SAAS,EAAE,GAClF,KAAM,OAAO,MAAM,OAAO,CAAgC,KAAK,SAAS;OACrE;GACH,IAAI;GACJ,IAAI,MAAM,QAAQ,QAAQ,KAAK,SAAS,WAAW,KAAK,OAAO,SAAS,OAAO,UAC3E,iBAAiB;QAEjB,iBAAiB,CAAC,MAAM,QAAQ;GAEpC,KAAK,OAAO,MAAM,UAAU,CAAC,gBAAgB,SAAS;EAC1D;EACA,OAAO;CACX;;CAGA,QAAQ,QAAgD,YAA4B,OAAa;EAC7F,MAAM,WAAW,iBAAiB,KAAK,OAAO,OAAO,KAAK,CAAC;EAC3D,KAAK,OAAO,UAAU,CAAC,GAAG,UAAU,CAAC,QAAQ,SAAS,CAAiB;EACvE,OAAO;CACX;CAEA,MAAM,OAAqB;EAAE,KAAK,OAAO,QAAQ;EAAO,OAAO;CAAM;CACrE,OAAO,OAAqB;EAAE,KAAK,OAAO,SAAS;EAAO,OAAO;CAAM;CACvE,OAAO,cAAsB,SAAuC;EAAE,KAAK,OAAO,eAAe;EAAc,IAAI,SAAS,YAAY,KAAA,GAAW,KAAK,OAAO,gBAAgB,QAAQ;EAAS,OAAO;CAAM;CAC7M,aACI,UACA,QACA,SACI;EACJ,KAAK,OAAO,eAAe;GACvB;GACA;GACA,GAAI,SAAS,aAAa,KAAA,KAAa,EAAE,UAAU,QAAQ,SAAS;GACpE,GAAI,SAAS,cAAc,KAAA,KAAa,EAAE,WAAW,QAAQ,UAAU;EAC3E;EACA,OAAO;CACX;CACA,QAAQ,GAAG,WAA2B;EAAE,KAAK,OAAO,UAAU;EAAW,OAAO;CAAM;CAEtF,MAAM,OAA+B;EACjC,OAAO,KAAK,OAAO,KAAK,KAAK,MAAuB;CACxD;CAEA,MAAM,QAAyB;EAC3B,OAAO,KAAK,OAAO,QAAQ,KAAK,OAAO,MAAM,KAAK,MAAuB,IAAI;CACjF;CAEA,OAAO,UAAyC,SAA8C;EAC1F,IAAI,CAAC,KAAK,OAAO,QACb,MAAM,IAAI,MAAM,6DAA6D;EAEjF,OAAO,KAAK,OAAO,OAAO,KAAK,QAAyB,UAAU,OAAO;CAC7E;AACJ;;;;;;AAOA,SAAS,sBACL,MACA,OAAO,cACe;CACtB,MAAM,SAAiC;EACnC,MAAM,KAAK,QAAgD;GACvD,MAAM,MAAM,MAAM,KAAK,KAAK,MAAM;GAClC,OAAO;IAAE,MAAM,IAAI,KAAK,IAAI,WAAW;IAAG,MAAM,IAAI;GAAK;EAC7D;EAKA,QAAQ,QAA2B;GAC/B,OAAO,cAAiB,MAAM,OAAO,KAAK,CAAC,GAAG,QAAQ,IAAI;EAC9D;EACA,QAAQ,QAA2B;GAC/B,OAAO,iBAAoB,MAAM,OAAO,KAAK,CAAC,GAAG,QAAQ,IAAI;EACjE;EACA,MAAM,SAAS,IAA6C;GACxD,MAAM,IAAI,MAAM,KAAK,SAAS,EAAE;GAChC,OAAO,IAAI,YAAY,CAAC,IAAI,KAAA;EAChC;EACA,MAAM,OAAO,MAAkB,IAAkC;GAC7D,OAAO,YAAY,MAAM,KAAK,OAAO,MAAkC,EAAE,CAAC;EAC9E;EACA,MAAM,WAAW,MAAoB,SAA8C;GAC/E,IAAI,CAAC,MAAM,QAAQ,IAAI,GACnB,MAAM,IAAI,UAAU,yCAAyC;GAEjE,IAAI,KAAK,WAAW,GAAG,OAAO,CAAC;GAC/B,IAAI,CAAC,KAAK,YACN,MAAM,IAAI,MACN,mGAEJ;GAGJ,QAAO,MADY,KAAK,WAAW,MAAoC,OAAO,EAAA,CAClE,IAAI,WAAW;EAC/B;EACA,MAAM,OAAO,IAAqB,MAA8B;GAC5D,OAAO,YAAY,MAAM,KAAK,OAAO,IAAI,IAAgC,CAAC;EAC9E;EACA,MAAM,WAAW,SAAoE;GACjF,IAAI,CAAC,MAAM,QAAQ,OAAO,GACtB,MAAM,IAAI,UAAU,sDAAsD;GAE9E,IAAI,QAAQ,WAAW,GAAG,OAAO,CAAC;GAClC,IAAI,CAAC,KAAK,YACN,MAAM,IAAI,MACN,oGAEJ;GAMJ,QAAO,MAJY,KAAK,WACpB,QAAQ,KAAI,OAAM;IAAE,IAAI,EAAE;IAC1C,MAAM,EAAE;GAAiC,EAAE,CAC/B,EAAA,CACY,IAAI,WAAW;EAC/B;EACA,OAAO,IAAoC;GACvC,OAAO,KAAK,OAAO,EAAE;EACzB;EACA,MAAM,WAAW,KAAyC;GACtD,IAAI,CAAC,MAAM,QAAQ,GAAG,GAClB,MAAM,IAAI,UAAU,qCAAqC;GAE7D,IAAI,IAAI,WAAW,GAAG;GACtB,IAAI,CAAC,KAAK,YACN,MAAM,IAAI,MACN,oGAEJ;GAEJ,MAAM,KAAK,WAAW,GAAG;EAC7B;EACA,OAAO,KAAK,SAAS,WAA2B,KAAK,MAAO,MAAM,IAAI,KAAA;EACtE,QAAQ,KAAK,UACN,QAAmC,UAAsC,YACxE,KAAK,OAAQ,SAAS,QAAQ,SAAS;GAAE,MAAM,IAAI,KAAK,IAAI,WAAW;GAAG,MAAM,IAAI;EAAK,CAAC,GAAG,OAAO,IACtG,KAAA;EACN,YAAY,KAAK,cACV,IAAqB,UAAsC,YAC1D,KAAK,WAAY,KAAK,MAAM,SAAS,IAAI,YAAY,CAAC,IAAI,KAAA,CAAS,GAAG,OAAO,IAC/E,KAAA;EACN,MAAM,mBAA8C,UAA0B,OAAiB;GAC3F,MAAM,UAAU,IAAI,gBAAmB,MAAM;GAC7C,IAAI,OAAO,sBAAsB,UAC7B,OAAO,QAAQ,MAAM,iBAAiB;GAE1C,OAAO,QAAQ,MAAM,mBAAuC,UAAW,KAA0D;EACrI;EACA,UAAU,QAA0B,cAA+B,IAAI,gBAAmB,MAAM,CAAC,CAAC,QAAQ,QAAQ,SAAS;EAC3H,QAAQ,UAAkB,IAAI,gBAAmB,MAAM,CAAC,CAAC,MAAM,KAAK;EACpE,SAAS,UAAkB,IAAI,gBAAmB,MAAM,CAAC,CAAC,OAAO,KAAK;EACtE,SAAS,iBAAyB,IAAI,gBAAmB,MAAM,CAAC,CAAC,OAAO,YAAY;EACpF,eACI,UACA,QACA,YACC,IAAI,gBAAmB,MAAM,CAAC,CAAC,aAAa,UAAU,QAAQ,OAAO;EAC1E,UAAU,GAAG,cAAwB,IAAI,gBAAmB,MAAM,CAAC,CAAC,QAAQ,GAAG,SAAS;CAC5F;CACA,OAAO;AACX;;;;;;;;;AA2HA,SAAgB,cAAc,YAAuC;CACjE,MAAM,wBAAQ,IAAI,IAAiC;CAEnD,SAAS,YAAY,MAAmC;EACpD,IAAI,WAAW,MAAM,IAAI,IAAI;EAC7B,IAAI,CAAC,UAAU;GACX,WAAW,sBAAsB,WAAW,WAAW,IAAI,GAAG,IAAI;GAClE,MAAM,IAAI,MAAM,QAAQ;EAC5B;EACA,OAAO;CACX;CAIA,OAAO,IAAI,MAAM,EAFA,YAAY,YAEZ,GAAQ,EACrB,IAAI,SAAS,MAAuB;EAChC,IAAI,SAAS,cAAc,OAAO;EAClC,IAAI,OAAO,SAAS,UAAU,OAAO,KAAA;EACrC,IAAI,SAAS,UAAU,SAAS,YAAY,SAAS,YAAY,OAAO,KAAA;EACxE,OAAO,YAAY,YAAY,IAAI,CAAC;CACxC,EACJ,CAAC;AACL;;;;;;;;;;;;;AAcA,SAAgB,aAAa,QAAmC;CAC5D,OAAO,cAAc,gBAAgB,MAAM,CAAC;AAChD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACruBA,IAAM,gBAAgB;;;;;;AAOtB,IAAa,iBAAiB,GAAG,cAAc;AAC/C,IAAa,qBAAqB,GAAG,cAAc;;AA4CnD,IAAa,oBAAb,cAAuC,MAAM;CACzC,YAAY,SAAiB;EACzB,MAAM,OAAO;EACb,KAAK,OAAO;CAChB;AACJ;;AAGA,IAAa,mBAAmB,eAC5B,2BAA2B,UAAU,IAAI,WAAW,SAAS,KAAA;;;;;;;;;;;;AAajE,IAAa,8BAA8B,gBAA0C;CACjF,KAAK,MAAM,cAAc,aAAa;EAClC,IAAI,2BAA2B,UAAU,GAAG;EAC5C,IAAI,CAAE,WAAoC,QAAQ;EAClD,MAAM,SAAU,WAAmC,UAAU;EAC7D,MAAM,IAAI,kBACN,GAAG,WAAW,KAAK,sFAAsF,OAAO,sHAEpH;CACJ;AACJ;AAEA,IAAM,gBAAgB,UAAkB,SACpC,QAAQ,gBAAgB,QAAQ,OAAO,KAAK,eAAe,WAAW,KAAK,aAAa,YAAY,QAAQ;;;;;;;;;;;;AAahH,IAAM,YAAY,SAAgE;CAC9E,QAAQ,KAAK,MAAb;EACI,KAAK,UAAU;GACX,MAAM,KAAK;GACX,IAAI,GAAG,MACH,OAAO;IAAE,MAAM;IAAQ,QAAQ;GAAO;GAE1C,IAAI,GAAG,SAAS,UAAU,GAAG,eAAe,QACxC,OAAO;IAAE,MAAM;IAAQ,QAAQ;GAAO;GAE1C,OAAO,EAAE,MAAM,OAAO;EAC1B;EACA,KAAK;GAKD,IAAI,KAAG,eAAe,QAAQ,OAAO;IAAE,MAAM;IAAS,QAAQ;GAAO;GACrE,OAAO,EAAE,MAAM,QAAQ;EAE3B,KAAK,SAAS;GACV,MAAM,KAAK;GACX,IAAI,UAAU,GAAG;GACjB,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,GAAG;IAC5C,MAAM,KAAK,GAAG;IACd,IAAI,GAAG,SAAS,UAAU,UAAU;SAC/B,IAAI,GAAG,SAAS,UAAU,UAAU,GAAG,YAAY,UAAU,cAAc;SAC3E,IAAI,GAAG,SAAS,WAAW,UAAU;GAC9C;GACA,IAAI,YAAY,UAAU,OAAO,EAAE,MAAM,aAAa;GACtD,IAAI,YAAY,QAAQ,OAAO;IAAE,MAAM;IAAS,QAAQ;GAAO;GAC/D,IAAI,YAAY,eAAe,YAAY,eAAe,YAAY,aAClE,OAAO;IAAE,MAAM;IAAc,QAAQ;GAAiB;GAG1D,OAAO,EAAE,MAAM,QAAQ;EAC3B;EACA,SACI,OAAO;CACf;AACJ;AAEA,IAAM,aAAa,OAAe,aAC9B,WAAW,GAAG,mBAAmB,GAAG,MAAM,KAAK;;AAGnD,IAAM,cAAc,UAA2E;CAC3F,MAAM,MAAM,IAAI,MAAM,OAAO;CAC7B,IAAI,MAAM,SAAS,QAAQ,OAAO,YAAY,IAAI;CAClD,IAAI,MAAM,SAAS,cAAc,OAAO,GAAG,eAAe,YAAY,IAAI;CAO1E,OAAO,GAAG,eAAe,YALV,MAAM,SAAS,WAAW,IACnC,MACA,MAAM,SAAS,WAAW,IACtB,GAAG,IAAI,MAAM,MAAM,MAAM,SAAS,EAAE,MACpC,GAAG,IAAI,MAAM,MAAM,IAAI,MAAM,SAAS,KAAK,GAAG,EAAE,EAAE,IAChB;AAChD;AAEA,IAAM,SAAS,MAAsB,IAAI,EAAE,QAAQ,MAAM,IAAI,EAAE;;;;;;;;;AAU/D,IAAM,gBACF,OACA,YACA,QACsB;CACtB,MAAM,OAAO,OAAO,UAAU,WAAW,QAAQ,MAAM;CACvD,MAAM,UAAU,OAAO,UAAU,WAAW,KAAA,IAAY,MAAM,WAAA;CAC9D,MAAM,QAAQ,GAAG,WAAW,KAAK;CAEjC,IAAI,CAAC,QAAQ,OAAO,SAAS,UACzB,MAAM,IAAI,kBAAkB,GAAG,MAAM,mDAAmD;CAG5F,MAAM,CAAC,MAAM,GAAG,QAAQ,KAAK,MAAM,GAAG;CACtC,MAAM,OAAO,WAAW,aAAa;CACrC,IAAI,CAAC,MAED,MAAM,IAAI,kBACN,GAAG,MAAM,KAAK,KAAK,wBAAwB,KAAK,+DAFtC,OAAO,KAAK,WAAW,cAAc,CAAC,CAAC,CAAC,CAAC,KAAK,IAEuD,EAAM,EACzH;CAGJ,MAAM,aAAa,SAAS,IAAI;CAChC,IAAI,CAAC,YACD,MAAM,IAAI,kBACN,GAAG,MAAM,KAAK,KAAK,WAAW,KAAK,KAAK,8HAE5C;CAEJ,IAAI,WAAW,WAAW,QACtB,MAAM,IAAI,kBACN,GAAG,MAAM,KAAK,KAAK,sHACvB;CAEJ,IAAI,WAAW,WAAW,QACtB,MAAM,IAAI,kBACN,GAAG,MAAM,KAAK,KAAK,+DACvB;CAEJ,IAAI,WAAW,WAAW,QACtB,MAAM,IAAI,kBACN,GAAG,MAAM,KAAK,KAAK,sLACvB;CAEJ,IAAI,WAAW,WAAW,kBACtB,MAAM,IAAI,kBACN,GAAG,MAAM,KAAK,KAAK,gFACvB;CAGJ,IAAI,KAAK,SAAS,KAAK,WAAW,SAAS,SACvC,MAAM,IAAI,kBACN,GAAG,MAAM,KAAK,KAAK,6BAA6B,KAAK,UAAU,KAAK,WAAW,KAAK,KAAK,wEAC7F;CAGJ,MAAM,SAAS,aAAa,MAAM,IAAI;CAEtC,MAAM,UAAU,UAAU,WAAW;EADrB;EAAQ,UAAU;EAAM,MAAM,WAAW;CACpB,CAAK,GAAG,IAAI,aAAa,IAAI;CAClE,MAAM,WAAW,IAAI,YAAA;CAErB,OAAO;EACH;EACA;EACA,UAAU;EACV,MAAM,WAAW;EACjB;EACA,KAAK,yBAAyB,MAAM,QAAQ,EAAE,IAAI,QAAQ,KAAK,MAAM,MAAM,EAAE;EAC7E;CACJ;AACJ;;;;;;;;AASA,IAAa,yBAAyB,eAA+D;CACjG,MAAM,MAAM,gBAAgB,UAAU;CACtC,IAAI,CAAC,KAAK,OAAO,KAAA;CAEjB,IAAI,CAAC,MAAM,QAAQ,IAAI,MAAM,KAAK,IAAI,OAAO,WAAW,GACpD,MAAM,IAAI,kBACN,GAAG,WAAW,KAAK,gIACvB;CAGJ,MAAM,QAAQ,aAAa,UAAU;CACrC,MAAM,SAAS,2BAA2B,UAAU,KAAK,WAAW,SAAS,WAAW,SAAS;CACjG,MAAM,SAAS,IAAI,UAAA;CAEnB,IAAI,WAAW,aAAa,SACxB,MAAM,IAAI,kBACN,GAAG,WAAW,KAAK,iCAAiC,OAAO,+FAC/D;CAGJ,MAAM,SAAS,IAAI,OAAO,KAAI,UAAS,aAAa,OAAO,YAAY,GAAG,CAAC;CAE3E,MAAM,uBAAO,IAAI,IAAY;CAC7B,KAAK,MAAM,KAAK,QAAQ;EACpB,IAAI,KAAK,IAAI,EAAE,IAAI,GACf,MAAM,IAAI,kBAAkB,GAAG,WAAW,KAAK,YAAY,EAAE,KAAK,mBAAmB;EAEzF,KAAK,IAAI,EAAE,IAAI;CACnB;CAEA,MAAM,aAAuB,CAAC;CAC9B,IAAI,IAAI,UAAU,WAAW,KAAK,UAAU;CAC5C,IAAI,IAAI,OAAO,WAAW,KAAK,SAAS;CAExC,MAAM,OAAyB;EAC3B;EACA;EACA;EACA,UAAU,IAAI,YAAA;EACd,UAAU,IAAI,aAAa;EAC3B;EACA,YAAY,OAAO,KAAI,MAAK,EAAE,GAAG,CAAC,CAAC,KAAK,MAAM;EAC9C,WAAW,qBAAqB,GAAG,MAAM,GAAG,OAAO,KAAK;EACxD;CACJ;CAEA,IAAI,IAAI,OAAO;EACX,MAAM,cAAc,GAAG,OAAO;EAC9B,IAAI,WAAW,aAAa,cACxB,MAAM,IAAI,kBACN,GAAG,WAAW,KAAK,uCAAuC,YAAY,qFAC1E;EAEJ,KAAK,QAAQ;GACT,QAAQ;GAER,YAAY,OAAO,KAAI,MAAK,EAAE,OAAO,CAAC,CAAC,KAAK,aAAa;GACzD,WAAW,qBAAqB,GAAG,MAAM,GAAG,YAAY,MAAM;GAC9D,WAAW,IAAI,kBAAA;EACnB;CACJ;CAEA,OAAO;AACX;;;;;;;;;;;;;AAcA,IAAa,yBAAyB,SAAqC;CACvE,MAAM,aAAuB,CAEzB,8BAA8B,eAAe,wHAM7C,8BAA8B,eAAe,2OAIjD;CACA,IAAI,KAAK,UAIL,WAAW,KACP,8BAA8B,mBAAmB,yFAEhC,cAAc,aAAa,cAAc,mCAC9D;CAEJ,OAAO;AACX;;;;;;;;;;;;AAaA,IAAa,6BAA6B,SACtC,KAAK,WAAW,KAAI,MAAK,kCAAkC,EAAE,eAAe,cAAc,EAAE;;;;;;;;;;AAmBhG,IAAa,yBAAyB,SAAqC;CACvE,MAAM,aAAa,CACf,+BAA+B,KAAK,UAAU,QAAQ,KAAK,OAAO,KAAK,KAAK,MAAM,gBAAgB,KAAK,OAAO,IAClH;CACA,IAAI,KAAK,OACL,WAAW,KAIP,+BAA+B,KAAK,MAAM,UAAU,QAAQ,KAAK,OAAO,KAAK,KAAK,MAAM,gBAAgB,KAAK,MAAM,OAAO,IAAI,cAAc,gBAChJ;CAEJ,OAAO;AACX;;;;;;;;AAWA,IAAa,sBAAsB;;;;;;;;;;;;AAanC,IAAa,+BAA+B,eACxC,GAAG,sBAAsB,WAAW,QAAQ,CAAC,CAAC,OAAO,UAAU,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,GAAG,EAAE;;;;;;;;;AAoB9F,IAAa,sBAAsB,SAAgD;CAC/E,MAAM,SAAS,QAAgB,eAA0C;EACrE,MAAM,cAAc,4BAA4B,UAAU;EAC1D,OAAO;GACH;GACA;GACA;GACA,KAAK,sBAAsB,KAAK,OAAO,KAAK,KAAK,MAAM,KAAK,OAAO,OAAO,MAAM,WAAW,EAAE;EACjG;CACJ;CACA,MAAM,SAAS,CAAC,MAAM,KAAK,QAAQ,KAAK,UAAU,CAAC;CACnD,IAAI,KAAK,OAAO,OAAO,KAAK,MAAM,KAAK,MAAM,QAAQ,KAAK,MAAM,UAAU,CAAC;CAC3E,OAAO;AACX;;;;;;;;;;AAgDA,IAAa,qBAAqB,eAA2C;CACzE,IAAI;CACJ,IAAI;EACA,OAAO,sBAAsB,UAAU;CAC3C,QAAQ;EAIJ,OAAO,CAAC;CACZ;CACA,IAAI,CAAC,MAAM,OAAO,CAAC;CACnB,OAAO,KAAK,QAAQ,CAAC,KAAK,QAAQ,KAAK,MAAM,MAAM,IAAI,CAAC,KAAK,MAAM;AACvE;;;;;;;;;;AAWA,IAAa,uBAAuB,WAAmD;CACnF,MAAM,UAAU,OAAO,QAAQ,eAAe,aAAa,OAAO,WAAW,CAAC,CAAC,YAAY,IAAI;CAC/F,OAAO,YAAY,cAAc,YAAY;AACjD;;;;;;;AAQA,IAAa,2BACT,cACA,eACsC;CACtC,MAAM,WAAW,oBAAoB,cAAc,UAAU;CAC7D,IAAI,CAAC,gBAAgB,SAAS,WAAW,GAAG,OAAO,KAAA;CACnD,MAAM,aAAsC,CAAC;CAC7C,KAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,YAAY,GACpD,IAAI,CAAC,SAAS,SAAS,IAAI,GAAG,WAAW,QAAQ;CAErD,OAAO;AACX;;AAGA,IAAa,uBACT,cACA,eACoC;CACpC,MAAM,WAAW,oBAAoB,cAAc,UAAU;CAC7D,IAAI,SAAS,WAAW,GAAG,OAAO,KAAA;CAClC,OAAO,OAAO,YAAY,SAAS,KAAI,SAAQ,CAAC,MAAM,KAAc,CAAC,CAAC;AAC1E;;;;;;;;;;AAWA,IAAM,uBACF,cACA,eACW;CACX,IAAI,CAAC,gBAAgB,OAAO,iBAAiB,UAAU,OAAO,CAAC;CAC/D,MAAM,SAAS,IAAI,IAAI,aAAa,kBAAkB,UAAU,IAAI,CAAC,CAAC;CACtE,OAAO,OAAO,KAAK,YAAY,CAAC,CAAC,QAC7B,SAAQ,OAAO,IAAI,IAAI,KAAK,oBAAoB,aAAa,KAAK,CACtE;AACJ;;;;;;;;;;ACrjBA,IAAa,qBAAiD;CAC1D;EAAE,QAAQ;EAAS,MAAM;EAAQ,SAAS;CAAK;CAC/C;EAAE,QAAQ;EAAgB,MAAM;CAAO;CACvC;EAAE,QAAQ;EAAa,MAAM;CAAO;CACpC;EAAE,QAAQ;EAAS,MAAM;EAAU,SAAS;EAAQ,SAAS;CAAK;CAClE;EAAE,QAAQ;EAAiB,MAAM;CAAO;CACxC;EAAE,QAAQ;EAAkB,MAAM;EAAW,SAAS;EAAS,SAAS;CAAK;CAC7E;EAAE,QAAQ;EAA4B,MAAM;CAAO;CACnD;EAAE,QAAQ;EAA8B,MAAM;CAA2B;CACzE;EAAE,QAAQ;EAAgB,MAAM;EAAW,SAAS;EAAS,SAAS;CAAK;CAC3E;EAAE,QAAQ;EAAY,MAAM;EAAS,SAAS;EAAQ,SAAS;CAAK;CACpE;EAAE,QAAQ;EAAsB,MAAM;CAA2B;CACjE;EAAE,QAAQ;EAAc,MAAM;EAA4B,SAAS;EAAS,SAAS;CAAK;CAC1F;EAAE,QAAQ;EAAc,MAAM;EAA4B,SAAS;EAAS,SAAS;CAAK;AAC9F;AAEA,IAAM,YAAY,IAAI,IAAI,mBAAmB,KAAI,MAAK,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;;AAGpE,SAAgB,mBAAmB,MAA+B;CAC9D,OAAO;EACH,KAAK;EACL,KAAK,YAAY,KAAA,IAAY,WAAW,KAAK,YAAY;EACzD,KAAK,UAAU,aAAa;CAChC,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;AAC9B;;;;;;;;;AAUA,SAAgB,0BAA0B,QAAoC;CAC1E,MAAM,OAAO,UAAU,IAAI,MAAM;CACjC,OAAO,OAAO,mBAAmB,IAAI,IAAI,KAAA;AAC7C;;;;;;;;;;AAWA,SAAgB,iBAAiB,YAA8B;CAC3D,MAAM,OAAQ,YAA+C;CAC7D,IAAI,SAAS,MAAM,OAAO;CAC1B,OAAO,OAAO,SAAS,YAAY,SAAS,QAAS,KAA+B,YAAY;AACpG"}