UNPKG

@casl/ability

Version:

CASL is an isomorphic authorization JavaScript library which restricts what resources a given user is allowed to access

1 lines 49.4 kB
{"version":3,"file":"index.mjs","sources":["../../src/utils.ts","../../src/Rule.ts","../../src/structures/LinkedItem.ts","../../src/RuleIndex.ts","../../src/PureAbility.ts","../../src/matchers/conditions.ts","../../src/matchers/field.ts","../../src/Ability.ts","../../src/AbilityBuilder.ts","../../src/ForbiddenError.ts"],"sourcesContent":["import { AnyObject, Subject, SubjectType, SubjectClass, ForcedSubject, AliasesMap } from './types';\n\nexport function wrapArray<T>(value: T[] | T): T[] {\n return Array.isArray(value) ? value : [value];\n}\n\nexport function setByPath(object: AnyObject, path: string, value: unknown): void {\n let ref = object;\n let lastKey = path;\n\n if (path.indexOf('.') !== -1) {\n const keys = path.split('.');\n\n lastKey = keys.pop()!;\n ref = keys.reduce((res, prop) => {\n res[prop] = res[prop] || {};\n return res[prop] as AnyObject;\n }, object);\n }\n\n ref[lastKey] = value;\n}\n\nconst TYPE_FIELD = '__caslSubjectType__';\nexport function setSubjectType<\n T extends string,\n U extends Record<PropertyKey, any>\n>(type: T, object: U): U & ForcedSubject<T> {\n if (object) {\n if (!Object.hasOwn(object, TYPE_FIELD)) {\n Object.defineProperty(object, TYPE_FIELD, { value: type });\n } else if (type !== object[TYPE_FIELD]) {\n throw new Error(`Trying to cast object to subject type ${type} but previously it was casted to ${object[TYPE_FIELD]}`);\n }\n }\n\n return object as U & ForcedSubject<T>;\n}\n\nexport const isSubjectType = (value: unknown): value is SubjectType => {\n const type = typeof value;\n return type === 'string' || type === 'function';\n};\n\nconst getSubjectClassName = (value: SubjectClass) => value.modelName || value.name;\nexport function getSubjectTypeName(value: SubjectType) {\n return typeof value === 'string' ? value : getSubjectClassName(value);\n}\n\nexport function detectSubjectType(object: Exclude<Subject, SubjectType>): string {\n if (Object.hasOwn(object, TYPE_FIELD)) {\n return object[TYPE_FIELD];\n }\n\n return getSubjectClassName(object.constructor as SubjectClass);\n}\n\nexport const DETECT_SUBJECT_TYPE_STRATEGY = {\n function: (object: Exclude<Subject, SubjectType>) => object.constructor as SubjectClass,\n string: detectSubjectType\n};\n\ntype AliasMerge = (actions: string[], action: string | string[]) => string[];\nfunction expandActions(aliasMap: AliasesMap, rawActions: string | string[], merge: AliasMerge) {\n let actions = wrapArray(rawActions);\n let i = 0;\n\n while (i < actions.length) {\n const action = actions[i++];\n\n if (Object.hasOwn(aliasMap, action)) {\n actions = merge(actions, aliasMap[action]);\n }\n }\n\n return actions;\n}\n\nfunction findDuplicate(actions: string[], actionToFind: string | string[]) {\n if (typeof actionToFind === 'string' && actions.indexOf(actionToFind) !== -1) {\n return actionToFind;\n }\n\n for (let i = 0; i < actionToFind.length; i++) {\n if (actions.indexOf(actionToFind[i]) !== -1) return actionToFind[i];\n }\n\n return null;\n}\n\nconst defaultAliasMerge: AliasMerge = (actions, action) => actions.concat(action);\nfunction validateForCycles(aliasMap: AliasesMap, reservedAction: string) {\n if (reservedAction in aliasMap) {\n throw new Error(`Cannot use \"${reservedAction}\" as an alias because it's reserved action.`);\n }\n\n const keys = Object.keys(aliasMap);\n const mergeAliasesAndDetectCycles: AliasMerge = (actions, action) => {\n const duplicate = findDuplicate(actions, action);\n if (duplicate) throw new Error(`Detected cycle ${duplicate} -> ${actions.join(', ')}`);\n\n const isUsingReservedAction = typeof action === 'string' && action === reservedAction\n || actions.indexOf(reservedAction) !== -1\n || Array.isArray(action) && action.indexOf(reservedAction) !== -1;\n if (isUsingReservedAction) throw new Error(`Cannot make an alias to \"${reservedAction}\" because this is reserved action`);\n\n return actions.concat(action);\n };\n\n for (let i = 0; i < keys.length; i++) {\n expandActions(aliasMap, keys[i], mergeAliasesAndDetectCycles);\n }\n}\n\nexport type AliasResolverOptions = { skipValidate?: boolean; anyAction?: string };\nexport function createAliasResolver(aliasMap: AliasesMap, options?: AliasResolverOptions) {\n if (!options || options.skipValidate !== false) {\n validateForCycles(aliasMap, options && options.anyAction || 'manage');\n }\n\n return (action: string | string[]) => expandActions(aliasMap, action, defaultAliasMerge);\n}\n\nfunction copyArrayTo<T>(dest: T[], target: T[], start: number) {\n for (let i = start; i < target.length; i++) {\n dest.push(target[i]);\n }\n}\n\nexport function mergePrioritized<T extends { priority: number }>(\n array?: T[],\n anotherArray?: T[]\n): T[] {\n if (!array || !array.length) {\n return anotherArray || [];\n }\n\n if (!anotherArray || !anotherArray.length) {\n return array || [];\n }\n\n let i = 0;\n let j = 0;\n const merged: T[] = [];\n\n while (i < array.length && j < anotherArray.length) {\n if (array[i].priority < anotherArray[j].priority) {\n merged.push(array[i]);\n i++;\n } else {\n merged.push(anotherArray[j]);\n j++;\n }\n }\n\n copyArrayTo(merged, array, i);\n copyArrayTo(merged, anotherArray, j);\n\n return merged;\n}\n\nexport function getOrDefault<K, V>(map: Map<K, V>, key: K, defaultValue: () => V) {\n let value = map.get(key);\n\n if (!value) {\n value = defaultValue();\n map.set(key, value);\n }\n\n return value;\n}\n\nexport const identity = <T>(x: T) => x;\n","import { wrapArray, isSubjectType } from './utils';\nimport {\n MatchConditions,\n MatchField,\n Abilities,\n ToAbilityTypes,\n Normalize,\n ConditionsMatcher,\n FieldMatcher,\n} from './types';\nimport { RawRule, RawRuleFrom } from './RawRule';\n\ntype Tuple<A extends Abilities> = Normalize<ToAbilityTypes<A>>;\n\nfunction validate(rule: RawRuleFrom<Abilities, any>, options: RuleOptions<any>) {\n if (Array.isArray(rule.fields) && !rule.fields.length) {\n throw new Error('`rawRule.fields` cannot be an empty array. https://bit.ly/390miLa');\n }\n\n if (rule.fields && !options.fieldMatcher) {\n throw new Error('You need to pass \"fieldMatcher\" option in order to restrict access by fields');\n }\n\n if (rule.conditions && !options.conditionsMatcher) {\n throw new Error('You need to pass \"conditionsMatcher\" option in order to restrict access by conditions');\n }\n}\n\nexport interface RuleOptions<Conditions> {\n conditionsMatcher?: ConditionsMatcher<Conditions>\n fieldMatcher?: FieldMatcher\n resolveAction(action: string | string[]): string | string[]\n}\n\nexport class Rule<A extends Abilities, C> {\n private _matchConditions: MatchConditions | undefined;\n private _matchField: MatchField<string> | undefined;\n private readonly _options!: RuleOptions<C>;\n public readonly action!: Tuple<A>[0] | Tuple<A>[0][];\n public readonly subject!: Tuple<A>[1] | Tuple<A>[1][];\n public readonly inverted!: boolean;\n public readonly conditions!: C | undefined;\n public readonly fields!: string[] | undefined;\n public readonly reason!: string | undefined;\n public readonly origin!: RawRule<ToAbilityTypes<A>, C>;\n public readonly priority!: number;\n\n constructor(\n rule: RawRule<ToAbilityTypes<A>, C>,\n options: RuleOptions<C>,\n priority: number = 0\n ) {\n validate(rule, options);\n\n this.action = options.resolveAction(rule.action);\n this.subject = rule.subject!;\n this.inverted = !!rule.inverted;\n this.conditions = rule.conditions;\n this.reason = rule.reason;\n this.origin = rule;\n this.fields = rule.fields ? wrapArray(rule.fields) : undefined;\n this.priority = priority;\n this._options = options;\n }\n\n private _conditionsMatcher() {\n if (this.conditions && !this._matchConditions) {\n this._matchConditions = this._options.conditionsMatcher!(this.conditions);\n }\n\n return this._matchConditions!;\n }\n\n get ast() {\n const matches = this._conditionsMatcher();\n return matches ? matches.ast : undefined;\n }\n\n matchesConditions(object: Normalize<A>[1] | undefined): boolean {\n if (!this.conditions) {\n return true;\n }\n\n if (!object || isSubjectType(object)) {\n return !this.inverted;\n }\n\n const matches = this._conditionsMatcher();\n return matches(object as Record<string, unknown>);\n }\n\n matchesField(field: string | undefined): boolean {\n if (!this.fields) {\n return true;\n }\n\n if (!field) {\n // if there is no field (i.e., checking whether user has access to at least one field on subject)\n // we ignore inverted rules because they disallow to do an action on it, so we are continue looking for regular rule\n return !this.inverted;\n }\n\n if (!this._matchField) {\n this._matchField = this._options.fieldMatcher!(this.fields);\n }\n\n return this._matchField(field);\n }\n}\n","export interface LinkedItem<T> {\n next: LinkedItem<T> | null\n prev: LinkedItem<T> | null\n readonly value: T\n}\n\nexport function linkedItem<T>(value: T, prev: LinkedItem<T>['prev']) {\n const item = { value, prev, next: null };\n\n if (prev) {\n prev.next = item;\n }\n\n return item;\n}\n\nexport function unlinkItem(item: LinkedItem<any>) {\n if (item.next) {\n item.next.prev = item.prev;\n }\n\n if (item.prev) {\n item.prev.next = item.next;\n }\n\n item.next = item.prev = null; // eslint-disable-line\n}\n\nexport const cloneLinkedItem = <T extends LinkedItem<any>>(item: T): T => ({\n value: item.value,\n prev: item.prev,\n next: item.next,\n} as T);\n","import { Rule, RuleOptions } from './Rule';\nimport { RawRuleFrom } from './RawRule';\nimport {\n Abilities,\n Normalize,\n SubjectType,\n AbilityParameters,\n AbilityTuple,\n ExtractSubjectType\n} from './types';\nimport { wrapArray, detectSubjectType, mergePrioritized, getOrDefault, identity, isSubjectType, DETECT_SUBJECT_TYPE_STRATEGY } from './utils';\nimport { LinkedItem, linkedItem, unlinkItem, cloneLinkedItem } from './structures/LinkedItem';\n\nexport interface RuleIndexOptions<A extends Abilities, C> extends Partial<RuleOptions<C>> {\n detectSubjectType?(\n subject: Exclude<Normalize<A>[1], SubjectType>\n ): ExtractSubjectType<Normalize<A>[1]>;\n anyAction?: string;\n anySubjectType?: string;\n}\n\nexport declare const ɵabilities: unique symbol;\nexport declare const ɵconditions: unique symbol;\ninterface WithGenerics {\n [ɵabilities]: any\n [ɵconditions]: any\n}\nexport type Public<T extends WithGenerics> = { [K in keyof T]: T[K] };\nexport interface Generics<T extends WithGenerics> {\n abilities: T[typeof ɵabilities],\n conditions: T[typeof ɵconditions]\n}\n\nexport type RuleOf<T extends WithGenerics> =\n Rule<Generics<T>['abilities'], Generics<T>['conditions']>;\nexport type RawRuleOf<T extends WithGenerics> =\n RawRuleFrom<Generics<T>['abilities'], Generics<T>['conditions']>;\n\nexport type RuleIndexOptionsOf<T extends WithGenerics> =\n RuleIndexOptions<Generics<T>['abilities'], Generics<T>['conditions']>;\n\ninterface AbilityEvent<T extends WithGenerics> {\n target: T\n /** @deprecated use \"target\" property instead */\n ability: T\n}\n\nexport interface UpdateEvent<T extends WithGenerics> extends AbilityEvent<T> {\n rules: RawRuleOf<T>[]\n}\n/**\n * @deprecated `on`/`emit` properly infer type without this type\n * TODO(major): delete\n */\nexport type EventHandler<Event> = (event: Event) => void;\n\nexport type Events<\n T extends WithGenerics,\n K extends keyof EventsMap<T> = keyof EventsMap<T>\n> = Map<K, LinkedItem<EventsMap<T>[K]> | null>;\n\ninterface EventsMap<T extends WithGenerics> {\n update(event: UpdateEvent<T>): void\n updated(event: UpdateEvent<T>): void\n}\n\ntype IndexTree<A extends Abilities, C> = Map<SubjectType, Map<string, {\n rules: Rule<A, C>[],\n merged: boolean\n}>>;\n\nexport type Unsubscribe = () => void;\n\nconst defaultActionEntry = () => ({\n rules: [] as unknown as Rule<any, any>[],\n merged: false\n});\nconst defaultSubjectEntry = () => new Map<string, ReturnType<typeof defaultActionEntry>>();\n\ntype AbilitySubjectTypeParameters<T extends Abilities, IncludeField extends boolean = true> =\n AbilityParameters<\n T,\n T extends AbilityTuple\n ? IncludeField extends true\n ? (action: T[0], subject: ExtractSubjectType<T[1]>, field?: string) => 0\n : (action: T[0], subject: ExtractSubjectType<T[1]>) => 0\n : never,\n (action: Extract<T, string>) => 0\n >;\n\nexport class RuleIndex<A extends Abilities, Conditions> {\n private _hasPerFieldRules: boolean = false;\n private _events?: Events<this>;\n private _indexedRules: IndexTree<A, Conditions> = new Map();\n private _rules: RawRuleFrom<A, Conditions>[];\n private readonly _ruleOptions: RuleOptions<Conditions>;\n private _detectSubjectType: this['detectSubjectType'];\n private readonly _anyAction: string;\n private readonly _anySubjectType: string;\n private readonly _hasCustomSubjectTypeDetection: boolean;\n readonly [ɵabilities]!: A;\n readonly [ɵconditions]!: Conditions;\n\n constructor(\n rules: RawRuleFrom<A, Conditions>[] = [],\n options: RuleIndexOptions<A, Conditions> = {}\n ) {\n this._ruleOptions = {\n conditionsMatcher: options.conditionsMatcher,\n fieldMatcher: options.fieldMatcher,\n resolveAction: options.resolveAction || identity,\n };\n this._anyAction = options.anyAction || 'manage';\n this._anySubjectType = options.anySubjectType || 'all';\n this._rules = rules;\n this._hasCustomSubjectTypeDetection = !!options.detectSubjectType;\n this._detectSubjectType = options.detectSubjectType || (detectSubjectType as this['detectSubjectType']);\n this._indexAndAnalyzeRules(rules);\n }\n\n get rules() {\n return this._rules;\n }\n\n detectSubjectType(object?: Normalize<A>[1]): ExtractSubjectType<Normalize<A>[1]> {\n if (isSubjectType(object)) return object as ExtractSubjectType<Normalize<A>[1]>;\n if (!object) return this._anySubjectType as ExtractSubjectType<Normalize<A>[1]>;\n return this._detectSubjectType(object as Exclude<Normalize<A>[1], SubjectType>);\n }\n\n update(rules: RawRuleFrom<A, Conditions>[]): Public<this> {\n const event = {\n rules,\n ability: this,\n target: this\n } as unknown as UpdateEvent<this>;\n\n this._emit('update', event);\n this._rules = rules;\n this._indexAndAnalyzeRules(rules);\n this._emit('updated', event);\n\n return this;\n }\n\n private _indexAndAnalyzeRules(rawRules: RawRuleFrom<A, Conditions>[]) {\n const indexedRules: IndexTree<A, Conditions> = new Map();\n let typeOfSubjectType: string | undefined;\n\n for (let i = rawRules.length - 1; i >= 0; i--) {\n const priority = rawRules.length - i - 1;\n const rule = new Rule(rawRules[i], this._ruleOptions, priority);\n const actions = wrapArray(rule.action);\n const subjects = wrapArray(rule.subject || this._anySubjectType);\n if (!this._hasPerFieldRules && rule.fields) this._hasPerFieldRules = true;\n\n for (let k = 0; k < subjects.length; k++) {\n const subjectRules = getOrDefault(indexedRules, subjects[k], defaultSubjectEntry);\n if (typeOfSubjectType === undefined) {\n typeOfSubjectType = typeof subjects[k];\n }\n if (typeof subjects[k] !== typeOfSubjectType && typeOfSubjectType !== 'mixed') {\n typeOfSubjectType = 'mixed';\n }\n\n for (let j = 0; j < actions.length; j++) {\n getOrDefault(subjectRules, actions[j], defaultActionEntry).rules.push(rule);\n }\n }\n }\n\n this._indexedRules = indexedRules;\n if (typeOfSubjectType !== 'mixed' && !this._hasCustomSubjectTypeDetection) {\n const detectSubjectType = DETECT_SUBJECT_TYPE_STRATEGY[typeOfSubjectType as 'function' | 'string'] || DETECT_SUBJECT_TYPE_STRATEGY.string;\n this._detectSubjectType = detectSubjectType as this['detectSubjectType'];\n }\n }\n\n possibleRulesFor(...args: AbilitySubjectTypeParameters<A, false>): Rule<A, Conditions>[];\n possibleRulesFor(\n action: string,\n subjectType: SubjectType = this._anySubjectType\n ): Rule<A, Conditions>[] {\n if (!isSubjectType(subjectType)) {\n throw new Error('\"possibleRulesFor\" accepts only subject types (i.e., string or class) as the 2nd parameter');\n }\n\n const subjectRules = getOrDefault(this._indexedRules, subjectType, defaultSubjectEntry);\n const actionRules = getOrDefault(subjectRules, action, defaultActionEntry);\n\n if (actionRules.merged) {\n return actionRules.rules;\n }\n\n const anyActionRules = action !== this._anyAction && subjectRules.has(this._anyAction)\n ? subjectRules.get(this._anyAction)!.rules\n : undefined;\n let rules = mergePrioritized(actionRules.rules, anyActionRules);\n\n if (subjectType !== this._anySubjectType) {\n rules = mergePrioritized(rules, (this as any).possibleRulesFor(action, this._anySubjectType));\n }\n\n actionRules.rules = rules;\n actionRules.merged = true;\n\n return rules;\n }\n\n rulesFor(...args: AbilitySubjectTypeParameters<A>): Rule<A, Conditions>[];\n rulesFor(action: string, subjectType?: SubjectType, field?: string): Rule<A, Conditions>[] {\n const rules: Rule<A, Conditions>[] = (this as any).possibleRulesFor(action, subjectType);\n\n if (field && typeof field !== 'string') {\n throw new Error('The 3rd, `field` parameter is expected to be a string. See https://stalniy.github.io/casl/en/api/casl-ability#can-of-pure-ability for details');\n }\n\n if (!this._hasPerFieldRules) {\n return rules;\n }\n\n return rules.filter(rule => rule.matchesField(field));\n }\n\n actionsFor(subjectType: ExtractSubjectType<Normalize<A>[1]>): string[] {\n if (!isSubjectType(subjectType)) {\n throw new Error('\"actionsFor\" accepts only subject types (i.e., string or class) as a parameter');\n }\n\n const actions = new Set<string>();\n\n const subjectRules = this._indexedRules.get(subjectType);\n if (subjectRules) {\n Array.from(subjectRules.keys()).forEach(action => actions.add(action));\n }\n\n const anySubjectTypeRules = subjectType !== this._anySubjectType\n ? this._indexedRules.get(this._anySubjectType)\n : undefined;\n if (anySubjectTypeRules) {\n Array.from(anySubjectTypeRules.keys()).forEach(action => actions.add(action));\n }\n\n return Array.from(actions);\n }\n\n on<T extends keyof EventsMap<this>>(\n event: T,\n handler: EventsMap<Public<this>>[T]\n ): Unsubscribe {\n this._events = this._events || new Map();\n const events = this._events;\n const tail = events.get(event) || null;\n const item = linkedItem(handler, tail);\n events.set(event, item);\n\n return () => {\n const currentTail = events.get(event);\n\n if (!item.next && !item.prev && currentTail === item) {\n events.delete(event);\n } else if (item === currentTail) {\n events.set(event, item.prev);\n }\n\n unlinkItem(item);\n };\n }\n\n private _emit<T extends keyof EventsMap<this>>(\n name: T,\n payload: Parameters<EventsMap<this>[T]>[0]\n ) {\n if (!this._events) return;\n\n let current = this._events.get(name) || null;\n while (current !== null) {\n const prev = current.prev ? cloneLinkedItem(current.prev) : null;\n current.value(payload);\n current = prev;\n }\n }\n}\n","import { RuleIndex, RuleIndexOptions, RuleIndexOptionsOf, Public, RawRuleOf } from './RuleIndex';\nimport { Abilities, AbilityTuple, CanParameters, Subject } from './types';\nimport { Rule } from './Rule';\n\nexport interface AbilityOptions<A extends Abilities, Conditions>\n extends RuleIndexOptions<A, Conditions> {}\nexport interface AnyAbility extends Public<PureAbility<any, any>> {}\nexport interface AbilityOptionsOf<T extends AnyAbility> extends RuleIndexOptionsOf<T> {}\n\nexport type AbilityClass<T extends AnyAbility> = new (\n rules?: RawRuleOf<T>[],\n options?: AbilityOptionsOf<T>\n) => T;\n\nexport type CreateAbility<T extends AnyAbility> = (\n rules?: RawRuleOf<T>[],\n options?: AbilityOptionsOf<T>\n) => T;\n\nexport class PureAbility<\n A extends Abilities = AbilityTuple,\n Conditions = unknown\n> extends RuleIndex<A, Conditions> {\n can(...args: CanParameters<A>): boolean;\n can(action: string, subject?: Subject, field?: string): boolean {\n const rule = (this as PrimitiveAbility).relevantRuleFor(action, subject, field);\n return !!rule && !rule.inverted;\n }\n\n relevantRuleFor(...args: CanParameters<A>): Rule<A, Conditions> | null;\n relevantRuleFor(action: string, subject?: Subject, field?: string): Rule<A, Conditions> | null {\n const subjectType = this.detectSubjectType(subject);\n const rules = (this as any).rulesFor(action, subjectType, field);\n\n for (let i = 0, length = rules.length; i < length; i++) {\n if (rules[i].matchesConditions(subject)) {\n return rules[i];\n }\n }\n\n return null;\n }\n\n cannot(...args: CanParameters<A>): boolean;\n cannot(action: string, subject?: Subject, field?: string): boolean {\n return !(this as PrimitiveAbility).can(action, subject, field);\n }\n}\n\n/**\n * helper interface that helps to emit js methods that have static parameters\n */\ninterface PrimitiveAbility<A extends Abilities = AbilityTuple, Conditions = unknown> {\n can(action: string, subject?: Subject, field?: string): boolean;\n relevantRuleFor(action: string, subject?: Subject, field?: string): Rule<A, Conditions> | null\n}\n","import {\n $eq,\n eq,\n $ne,\n ne,\n $lt,\n lt,\n $lte,\n lte,\n $gt,\n gt,\n $gte,\n gte,\n $in,\n within,\n $nin,\n nin,\n $all,\n all,\n $size,\n size,\n $regex,\n $options,\n regex,\n $elemMatch,\n elemMatch,\n $exists,\n exists,\n and,\n createFactory,\n BuildMongoQuery,\n DefaultOperators,\n} from '@ucast/mongo2js';\nimport { ConditionsMatcher, AnyObject } from '../types';\nimport { Container, GenericFactory } from '../hkt';\n\nconst defaultInstructions = {\n $eq,\n $ne,\n $lt,\n $lte,\n $gt,\n $gte,\n $in,\n $nin,\n $all,\n $size,\n $regex,\n $options,\n $elemMatch,\n $exists,\n};\nconst defaultInterpreters = {\n eq,\n ne,\n lt,\n lte,\n gt,\n gte,\n in: within,\n nin,\n all,\n size,\n regex,\n elemMatch,\n exists,\n and,\n};\n\ninterface MongoQueryFactory extends GenericFactory {\n produce: MongoQuery<this[0]>\n}\n\ntype MergeUnion<T, Keys extends keyof T = keyof T> = { [K in Keys]: T[K] };\nexport type MongoQuery<T = AnyObject> = BuildMongoQuery<MergeUnion<T>, {\n toplevel: {},\n field: Pick<DefaultOperators<MergeUnion<T>>['field'], keyof typeof defaultInstructions>\n}> & Container<MongoQueryFactory>;\n\ntype MongoQueryMatcherFactory =\n (...args: Partial<Parameters<typeof createFactory>>) => ConditionsMatcher<MongoQuery>;\nexport const buildMongoQueryMatcher = ((instructions, interpreters, options) => createFactory(\n { ...defaultInstructions, ...instructions },\n { ...defaultInterpreters, ...interpreters },\n options\n)) as MongoQueryMatcherFactory;\n\nexport const mongoQueryMatcher = createFactory(defaultInstructions, defaultInterpreters);\nexport type {\n MongoQueryFieldOperators,\n MongoQueryTopLevelOperators,\n MongoQueryOperators,\n} from '@ucast/mongo2js';\n","import { FieldMatcher } from '../types';\n\nconst REGEXP_SPECIAL_CHARS = /[-/\\\\^$+?.()|[\\]{}]/g;\nconst REGEXP_ANY = /\\.?\\*+\\.?/g;\nconst REGEXP_STARS = /\\*+/;\nconst REGEXP_DOT = /\\./g;\n\nfunction detectRegexpPattern(match: string, index: number, string: string): string {\n const quantifier = string[0] === '*' || match[0] === '.' && match[match.length - 1] === '.'\n ? '+'\n : '*';\n const matcher = match.indexOf('**') === -1 ? '[^.]' : '.';\n const pattern = match.replace(REGEXP_DOT, '\\\\$&')\n .replace(REGEXP_STARS, matcher + quantifier);\n\n return index + match.length === string.length ? `(?:${pattern})?` : pattern;\n}\n\nfunction escapeRegexp(match: string, index: number, string: string): string {\n if (match === '.' && (string[index - 1] === '*' || string[index + 1] === '*')) {\n return match;\n }\n\n return `\\\\${match}`;\n}\n\nfunction createPattern(fields: string[]) {\n const patterns = fields.map(field => field\n .replace(REGEXP_SPECIAL_CHARS, escapeRegexp)\n .replace(REGEXP_ANY, detectRegexpPattern));\n const pattern = patterns.length > 1 ? `(?:${patterns.join('|')})` : patterns[0];\n\n return new RegExp(`^${pattern}$`);\n}\n\nexport const fieldPatternMatcher: FieldMatcher = (fields) => {\n let pattern: RegExp | null;\n\n return (field) => {\n if (typeof pattern === 'undefined') {\n pattern = fields.every(f => f.indexOf('*') === -1)\n ? null\n : createPattern(fields);\n }\n\n return pattern === null\n ? fields.indexOf(field) !== -1\n : pattern.test(field);\n };\n};\n","import { PureAbility, AbilityOptions, AbilityOptionsOf } from './PureAbility';\nimport { RawRuleFrom } from './RawRule';\nimport { AbilityTuple } from './types';\nimport { MongoQuery, mongoQueryMatcher } from './matchers/conditions';\nimport { fieldPatternMatcher } from './matchers/field';\nimport { Public, RawRuleOf } from './RuleIndex';\n\n/**\n * @deprecated use createMongoAbility function instead and MongoAbility<Abilities> interface.\n * In the next major version PureAbility will be renamed to Ability and this class will be removed\n */\nexport class Ability<\n A extends AbilityTuple = AbilityTuple,\n C extends MongoQuery = MongoQuery\n> extends PureAbility<A, C> {\n constructor(rules: RawRuleFrom<A, C>[] = [], options: AbilityOptions<A, C> = {}) {\n super(rules, {\n conditionsMatcher: mongoQueryMatcher,\n fieldMatcher: fieldPatternMatcher,\n ...options,\n });\n }\n}\n\nexport interface AnyMongoAbility extends Public<PureAbility<any, MongoQuery>> {}\nexport interface MongoAbility<\n A extends AbilityTuple = AbilityTuple,\n C extends MongoQuery = MongoQuery\n> extends PureAbility<A, C> {}\n\n/**\n * Creates Ability with MongoDB conditions matcher\n */\nexport function createMongoAbility<\n T extends AnyMongoAbility = MongoAbility\n>(rules?: RawRuleOf<T>[], options?: AbilityOptionsOf<T>): T;\nexport function createMongoAbility<\n A extends AbilityTuple = AbilityTuple,\n C extends MongoQuery = MongoQuery\n>(rules?: RawRuleFrom<A, C>[], options?: AbilityOptions<A, C>): MongoAbility<A, C>;\nexport function createMongoAbility(rules: any[] = [], options = {}): AnyMongoAbility {\n return new PureAbility(rules, {\n conditionsMatcher: mongoQueryMatcher,\n fieldMatcher: fieldPatternMatcher,\n ...options,\n });\n}\n","import { AnyMongoAbility, createMongoAbility, MongoAbility } from './Ability';\nimport { ProduceGeneric } from './hkt';\nimport { AbilityOptionsOf, AnyAbility } from './PureAbility';\nimport { Generics, RawRuleOf } from './RuleIndex';\nimport {\n AbilityTuple, AnyClass, AnyObject, ExtractSubjectType as E, Normalize, SubjectType,\n TaggedInterface\n} from './types';\n\nfunction isAbilityClass(factory: AbilityFactory<any>): factory is AnyClass {\n return factory.prototype !== undefined && typeof factory.prototype.possibleRulesFor === 'function';\n}\n\nclass RuleBuilder<T extends AnyAbility> {\n public _rule!: RawRuleOf<T>;\n\n constructor(rule: RawRuleOf<T>) {\n this._rule = rule;\n }\n\n because(reason: string): this {\n this._rule.reason = reason;\n return this;\n }\n}\n\ntype AbilityFactory<T extends AnyAbility> = AnyClass<T> | ((rules?: any[], options?: any) => T);\ntype InstanceOf<T extends AnyAbility, S extends SubjectType> = S extends AnyClass<infer R>\n ? R\n : S extends (...args: any[]) => infer O\n ? O\n : S extends string\n ? Exclude<Normalize<Generics<T>['abilities']>[1], SubjectType> extends TaggedInterface<string>\n ? Extract<Normalize<Generics<T>['abilities']>[1], TaggedInterface<S>>\n : AnyObject\n : never;\ntype ConditionsOf<T extends AnyAbility, I extends {}> =\n ProduceGeneric<Generics<T>['conditions'], I>;\ntype ActionFrom<T extends AbilityTuple, S extends SubjectType> = T extends any\n ? S extends Extract<T[1], SubjectType> ? T[0] : never\n : never;\ntype ActionOf<T extends AnyAbility, S extends SubjectType> = ActionFrom<Generics<T>['abilities'], S>;\ntype SubjectTypeOf<T extends AnyAbility> = E<Normalize<Generics<T>['abilities']>[1]>;\n\ntype SimpleCanParams<T extends AnyAbility> = Parameters<(\n action: Generics<T>['abilities'] | Generics<T>['abilities'][]\n) => 0>;\ntype BuilderCanParameters<\n S extends SubjectType,\n I extends InstanceOf<T, S>,\n T extends AnyAbility\n> = Generics<T>['abilities'] extends AbilityTuple\n ? Parameters<(\n action: ActionOf<T, S> | ActionOf<T, S>[],\n subject: S | S[],\n conditions?: ConditionsOf<T, I>\n ) => 0>\n : SimpleCanParams<T>;\n\ntype BuilderCanParametersWithFields<\n S extends SubjectType,\n I extends InstanceOf<T, S>,\n F extends string,\n T extends AnyAbility\n> = Generics<T>['abilities'] extends AbilityTuple\n ? Parameters<(\n action: ActionOf<T, S> | ActionOf<T, S>[],\n subject: S | S[],\n fields?: F | F[],\n conditions?: ConditionsOf<T, I>\n ) => 0>\n : SimpleCanParams<T>;\ntype Keys<T> = string & keyof T;\n\ntype AddRule<T extends AnyAbility> = {\n <\n I extends InstanceOf<T, S>,\n F extends string = Keys<I>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParametersWithFields<S, I, F | Keys<I>, T>): RuleBuilder<T>;\n <\n I extends InstanceOf<T, S>,\n S extends SubjectTypeOf<T> = SubjectTypeOf<T>\n >(...args: BuilderCanParameters<S, I, T>): RuleBuilder<T>;\n};\n\nexport class AbilityBuilder<T extends AnyAbility> {\n public rules: RawRuleOf<T>[] = [];\n private readonly _createAbility: AbilityFactory<T>;\n public can: AddRule<T>;\n public cannot: AddRule<T>;\n public build: (options?: AbilityOptionsOf<T>) => T;\n\n constructor(AbilityType: AbilityFactory<T>) {\n this._createAbility = AbilityType;\n\n this.can = (\n action: string | string[],\n subject?: SubjectType | SubjectType[],\n conditionsOrFields?: string | string[] | Generics<T>['conditions'],\n conditions?: Generics<T>['conditions']\n ) => this._addRule(action, subject, conditionsOrFields, conditions, false);\n this.cannot = (\n action: string | string[],\n subject?: SubjectType | SubjectType[],\n conditionsOrFields?: string | string[] | Generics<T>['conditions'],\n conditions?: Generics<T>['conditions']\n ) => this._addRule(action, subject, conditionsOrFields, conditions, true);\n\n this.build = options => (isAbilityClass(this._createAbility)\n ? new this._createAbility(this.rules, options)\n : this._createAbility(this.rules, options));\n }\n\n private _addRule(\n action: string | string[],\n subject?: SubjectType | SubjectType[],\n conditionsOrFields?: string | string[] | Generics<T>['conditions'],\n conditions?: Generics<T>['conditions'],\n inverted?: boolean\n ): RuleBuilder<T> {\n const rule = { action } as RawRuleOf<T>;\n\n if (inverted) rule.inverted = inverted;\n if (subject) {\n rule.subject = subject;\n\n if (Array.isArray(conditionsOrFields) || typeof conditionsOrFields === 'string') {\n rule.fields = conditionsOrFields;\n } else if (typeof conditionsOrFields !== 'undefined') {\n rule.conditions = conditionsOrFields;\n }\n\n if (typeof conditions !== 'undefined') {\n rule.conditions = conditions;\n }\n }\n\n this.rules.push(rule);\n return new RuleBuilder(rule);\n }\n}\n\ntype DSL<T extends AnyAbility, R> = (\n can: AbilityBuilder<T>['can'],\n cannot: AbilityBuilder<T>['cannot']\n) => R;\n\nexport function defineAbility<\n T extends AnyMongoAbility = MongoAbility\n>(define: DSL<T, Promise<void>>, options?: AbilityOptionsOf<T>): Promise<T>;\nexport function defineAbility<\n T extends AnyMongoAbility = MongoAbility\n>(define: DSL<T, void>, options?: AbilityOptionsOf<T>): T;\nexport function defineAbility<\n T extends AnyMongoAbility\n>(define: DSL<T, void | Promise<void>>, options?: AbilityOptionsOf<T>): T | Promise<T> {\n const builder = new AbilityBuilder<T>(createMongoAbility);\n const result = define(builder.can, builder.cannot);\n\n if (result && typeof result.then === 'function') {\n return result.then(() => builder.build(options));\n }\n\n return builder.build(options);\n}\n","import { AnyAbility } from './PureAbility';\nimport { Normalize, Subject } from './types';\nimport { Generics } from './RuleIndex';\nimport { getSubjectTypeName } from './utils';\n\nexport type GetErrorMessage = (error: ForbiddenError<AnyAbility>) => string;\n/** @deprecated will be removed in the next major release */\nexport const getDefaultErrorMessage: GetErrorMessage = error => `Cannot execute \"${error.action}\" on \"${error.subjectType}\"`;\n\nconst NativeError = function NError(this: Error, message: string) {\n this.message = message;\n} as unknown as new (message: string) => Error;\n\nNativeError.prototype = Object.create(Error.prototype);\n\nexport class ForbiddenError<T extends AnyAbility> extends NativeError {\n public readonly ability!: T;\n public action!: Normalize<Generics<T>['abilities']>[0];\n public subject!: Generics<T>['abilities'][1];\n public field?: string;\n public subjectType!: string;\n\n static _defaultErrorMessage = getDefaultErrorMessage;\n\n static setDefaultMessage(messageOrFn: string | GetErrorMessage) {\n this._defaultErrorMessage = typeof messageOrFn === 'string' ? () => messageOrFn : messageOrFn;\n }\n\n static from<U extends AnyAbility>(ability: U): ForbiddenError<U> {\n return new this<U>(ability);\n }\n\n constructor(ability: T) {\n super('');\n this.ability = ability;\n\n if (typeof Error.captureStackTrace === 'function') {\n this.name = 'ForbiddenError';\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n setMessage(message: string): this {\n this.message = message;\n return this;\n }\n\n throwUnlessCan(...args: Parameters<T['can']>): void;\n throwUnlessCan(action: string, subject?: Subject, field?: string): void {\n const error = (this as any).unlessCan(action, subject, field);\n if (error) throw error;\n }\n\n unlessCan(...args: Parameters<T['can']>): this | undefined;\n unlessCan(action: string, subject?: Subject, field?: string): this | undefined {\n const rule = this.ability.relevantRuleFor(action, subject, field);\n\n if (rule && !rule.inverted) {\n return;\n }\n\n this.action = action;\n this.subject = subject;\n this.subjectType = getSubjectTypeName(this.ability.detectSubjectType(subject));\n this.field = field;\n\n const reason = rule ? rule.reason : '';\n // eslint-disable-next-line no-underscore-dangle\n this.message = this.message || reason || (this.constructor as any)._defaultErrorMessage(this);\n return this; // eslint-disable-line consistent-return\n }\n}\n"],"names":["wrapArray","value","Array","isArray","TYPE_FIELD","setSubjectType","type","object","Object","hasOwn","defineProperty","Error","isSubjectType","getSubjectClassName","modelName","name","getSubjectTypeName","detectSubjectType","constructor","DETECT_SUBJECT_TYPE_STRATEGY","function","string","expandActions","aliasMap","rawActions","merge","actions","i","length","action","findDuplicate","actionToFind","indexOf","defaultAliasMerge","concat","validateForCycles","reservedAction","keys","mergeAliasesAndDetectCycles","duplicate","join","isUsingReservedAction","createAliasResolver","options","skipValidate","anyAction","copyArrayTo","dest","target","start","push","mergePrioritized","array","anotherArray","j","merged","priority","getOrDefault","map","key","defaultValue","get","set","identity","x","validate","rule","fields","fieldMatcher","conditions","conditionsMatcher","Rule","this","resolveAction","subject","inverted","reason","origin","undefined","_options","_conditionsMatcher","_matchConditions","ast","matches","matchesConditions","matchesField","field","_matchField","linkedItem","prev","item","next","unlinkItem","cloneLinkedItem","defaultActionEntry","rules","defaultSubjectEntry","Map","RuleIndex","_hasPerFieldRules","_indexedRules","_ruleOptions","_anyAction","_anySubjectType","anySubjectType","_rules","_hasCustomSubjectTypeDetection","_detectSubjectType","_indexAndAnalyzeRules","update","event","ability","_emit","rawRules","indexedRules","typeOfSubjectType","subjects","k","subjectRules","possibleRulesFor","subjectType","actionRules","anyActionRules","has","rulesFor","filter","actionsFor","Set","from","forEach","add","anySubjectTypeRules","on","handler","_events","events","tail","currentTail","delete","payload","current","PureAbility","can","relevantRuleFor","cannot","defaultInstructions","$eq","$ne","$lt","$lte","$gt","$gte","$in","$nin","$all","$size","$regex","$options","$elemMatch","$exists","defaultInterpreters","eq","ne","lt","lte","gt","gte","in","within","nin","all","size","regex","elemMatch","exists","and","buildMongoQueryMatcher","instructions","interpreters","createFactory","assign","mongoQueryMatcher","REGEXP_SPECIAL_CHARS","REGEXP_ANY","REGEXP_STARS","REGEXP_DOT","detectRegexpPattern","match","index","quantifier","matcher","pattern","replace","escapeRegexp","createPattern","patterns","RegExp","fieldPatternMatcher","every","f","test","Ability","super","createMongoAbility","isAbilityClass","factory","prototype","RuleBuilder","_rule","because","AbilityBuilder","AbilityType","_createAbility","conditionsOrFields","_addRule","build","defineAbility","define","builder","result","then","getDefaultErrorMessage","error","NativeError","NError","message","create","ForbiddenError","setDefaultMessage","messageOrFn","_defaultErrorMessage","captureStackTrace","setMessage","throwUnlessCan","unlessCan"],"mappings":"gVAEO,SAASA,EAAaC,GAC3B,OAAOC,MAAMC,QAAQF,GAASA,EAAQ,CAACA,EACzC,CAmBA,MAAMG,EAAa,sBACZ,SAASC,EAGdC,EAASC,GACT,GAAIA,EACF,IAAKC,OAAOC,OAAOF,EAAQH,GACzBI,OAAOE,eAAeH,EAAQH,EAAY,CAAEH,MAAOK,SAC9C,GAAIA,IAASC,EAAOH,GACzB,MAAM,IAAIO,MAAM,yCAAyCL,qCAAwCC,EAAOH,MAI5G,OAAOG,CACT,CAEO,MAAMK,EAAiBX,IAC5B,MAAMK,SAAcL,EACpB,OAAOK,IAAS,UAAYA,IAAS,UAAU,EAGjD,MAAMO,EAAuBZ,GAAwBA,EAAMa,WAAab,EAAMc,KACvE,SAASC,EAAmBf,GACjC,cAAcA,IAAU,SAAWA,EAAQY,EAAoBZ,EACjE,CAEO,SAASgB,EAAkBV,GAChC,GAAIC,OAAOC,OAAOF,EAAQH,GACxB,OAAOG,EAAOH,GAGhB,OAAOS,EAAoBN,EAAOW,YACpC,CAEO,MAAMC,EAA+B,CAC1CC,SAAWb,GAA0CA,EAAOW,YAC5DG,OAAQJ,GAIV,SAASK,EAAcC,EAAsBC,EAA+BC,GAC1E,IAAIC,EAAU1B,EAAUwB,GACxB,IAAIG,EAAI,EAER,MAAOA,EAAID,EAAQE,OAAQ,CACzB,MAAMC,EAASH,EAAQC,KAEvB,GAAInB,OAAOC,OAAOc,EAAUM,GAC1BH,EAAUD,EAAMC,EAASH,EAASM,GAEtC,CAEA,OAAOH,CACT,CAEA,SAASI,EAAcJ,EAAmBK,GACxC,UAAWA,IAAiB,UAAYL,EAAQM,QAAQD,MAAmB,EACzE,OAAOA,EAGT,IAAK,IAAIJ,EAAI,EAAGA,EAAII,EAAaH,OAAQD,IACvC,GAAID,EAAQM,QAAQD,EAAaJ,OAAS,EAAG,OAAOI,EAAaJ,GAGnE,OAAO,IACT,CAEA,MAAMM,EAAgCA,CAACP,EAASG,IAAWH,EAAQQ,OAAOL,GAC1E,SAASM,EAAkBZ,EAAsBa,GAC/C,GAAIA,KAAkBb,EACpB,MAAM,IAAIZ,MAAM,eAAeyB,gDAGjC,MAAMC,EAAO7B,OAAO6B,KAAKd,GACzB,MAAMe,EAA0CA,CAACZ,EAASG,KACxD,MAAMU,EAAYT,EAAcJ,EAASG,GACzC,GAAIU,EAAW,MAAM,IAAI5B,MAAM,kBAAkB4B,QAAgBb,EAAQc,KAAK,SAE9E,MAAMC,SAA+BZ,IAAW,UAAYA,IAAWO,GAClEV,EAAQM,QAAQI,MAAqB,GACrClC,MAAMC,QAAQ0B,IAAWA,EAAOG,QAAQI,MAAqB,EAClE,GAAIK,EAAuB,MAAM,IAAI9B,MAAM,4BAA4ByB,sCAEvE,OAAOV,EAAQQ,OAAOL,EAAO,EAG/B,IAAK,IAAIF,EAAI,EAAGA,EAAIU,EAAKT,OAAQD,IAC/BL,EAAcC,EAAUc,EAAKV,GAAIW,EAErC,CAGO,SAASI,EAAoBnB,EAAsBoB,GACxD,IAAKA,GAAWA,EAAQC,eAAiB,MACvCT,EAAkBZ,EAAUoB,GAAWA,EAAQE,WAAa,UAG9D,OAAQhB,GAA8BP,EAAcC,EAAUM,EAAQI,EACxE,CAEA,SAASa,EAAeC,EAAWC,EAAaC,GAC9C,IAAK,IAAItB,EAAIsB,EAAOtB,EAAIqB,EAAOpB,OAAQD,IACrCoB,EAAKG,KAAKF,EAAOrB,GAErB,CAEO,SAASwB,EACdC,EACAC,GAEA,IAAKD,IAAUA,EAAMxB,OACnB,OAAOyB,GAAgB,GAGzB,IAAKA,IAAiBA,EAAazB,OACjC,OAAOwB,GAAS,GAGlB,IAAIzB,EAAI,EACR,IAAI2B,EAAI,EACR,MAAMC,EAAc,GAEpB,MAAO5B,EAAIyB,EAAMxB,QAAU0B,EAAID,EAAazB,OAC1C,GAAIwB,EAAMzB,GAAG6B,SAAWH,EAAaC,GAAGE,SAAU,CAChDD,EAAOL,KAAKE,EAAMzB,IAClBA,GACF,KAAO,CACL4B,EAAOL,KAAKG,EAAaC,IACzBA,GACF,CAGFR,EAAYS,EAAQH,EAAOzB,GAC3BmB,EAAYS,EAAQF,EAAcC,GAElC,OAAOC,CACT,CAEO,SAASE,EAAmBC,EAAgBC,EAAQC,GACzD,IAAI3D,EAAQyD,EAAIG,IAAIF,GAEpB,IAAK1D,EAAO,CACVA,EAAQ2D,IACRF,EAAII,IAAIH,EAAK1D,EACf,CAEA,OAAOA,CACT,CAEO,MAAM8D,EAAeC,GAASA,EC9JrC,SAASC,EAASC,EAAmCvB,GACnD,GAAIzC,MAAMC,QAAQ+D,EAAKC,UAAYD,EAAKC,OAAOvC,OAC7C,MAAM,IAAIjB,MAAM,qEAGlB,GAAIuD,EAAKC,SAAWxB,EAAQyB,aAC1B,MAAM,IAAIzD,MAAM,gFAGlB,GAAIuD,EAAKG,aAAe1B,EAAQ2B,kBAC9B,MAAM,IAAI3D,MAAM,wFAEpB,CAQO,MAAM4D,EAaXrD,WAAAA,CACEgD,EACAvB,EACAa,EAAmB,GAEnBS,EAASC,EAAMvB,GAEf6B,KAAK3C,OAASc,EAAQ8B,cAAcP,EAAKrC,QACzC2C,KAAKE,QAAUR,EAAKQ,QACpBF,KAAKG,WAAaT,EAAKS,SACvBH,KAAKH,WAAaH,EAAKG,WACvBG,KAAKI,OAASV,EAAKU,OACnBJ,KAAKK,OAASX,EACdM,KAAKL,OAASD,EAAKC,OAASnE,EAAUkE,EAAKC,aAAUW,EACrDN,KAAKhB,SAAWA,EAChBgB,KAAKO,EAAWpC,CAClB,CAEQqC,CAAAA,GACN,GAAIR,KAAKH,aAAeG,KAAKS,EAC3BT,KAAKS,EAAmBT,KAAKO,EAAST,kBAAmBE,KAAKH,YAGhE,OAAOG,KAAKS,CACd,CAEA,OAAIC,GACF,MAAMC,EAAUX,KAAKQ,IACrB,OAAOG,EAAUA,EAAQD,SAAMJ,CACjC,CAEAM,iBAAAA,CAAkB7E,GAChB,IAAKiE,KAAKH,WACR,OAAO,KAGT,IAAK9D,GAAUK,EAAcL,GAC3B,OAAQiE,KAAKG,SAGf,MAAMQ,EAAUX,KAAKQ,IACrB,OAAOG,EAAQ5E,EACjB,CAEA8E,YAAAA,CAAaC,GACX,IAAKd,KAAKL,OACR,OAAO,KAGT,IAAKmB,EAGH,OAAQd,KAAKG,SAGf,IAAKH,KAAKe,EACRf,KAAKe,EAAcf,KAAKO,EAASX,aAAcI,KAAKL,QAGtD,OAAOK,KAAKe,EAAYD,EAC1B,ECrGK,SAASE,EAAcvF,EAAUwF,GACtC,MAAMC,EAAO,CAAEzF,QAAOwF,OAAME,KAAM,MAElC,GAAIF,EACFA,EAAKE,KAAOD,EAGd,OAAOA,CACT,CAEO,SAASE,EAAWF,GACzB,GAAIA,EAAKC,KACPD,EAAKC,KAAKF,KAAOC,EAAKD,KAGxB,GAAIC,EAAKD,KACPC,EAAKD,KAAKE,KAAOD,EAAKC,KAGxBD,EAAKC,KAAOD,EAAKD,KAAO,IAC1B,CAEO,MAAMI,EAA8CH,IAAgB,CACzEzF,MAAOyF,EAAKzF,MACZwF,KAAMC,EAAKD,KACXE,KAAMD,EAAKC,OC0Cb,MAAMG,EAAqBA,KAAO,CAChCC,MAAO,GACPxC,OAAQ,QAEV,MAAMyC,EAAsBA,IAAM,IAAIC,IAa/B,MAAMC,EAaXhF,WAAAA,CACE6E,EAAsC,GACtCpD,EAA2C,CAAA,GAC3C6B,KAfM2B,EAA6B,MAAK3B,KAElC4B,EAA0C,IAAIH,IAcpDzB,KAAK6B,EAAe,CAClB/B,kBAAmB3B,EAAQ2B,kBAC3BF,aAAczB,EAAQyB,aACtBK,cAAe9B,EAAQ8B,eAAiBV,GAE1CS,KAAK8B,EAAa3D,EAAQE,WAAa,SACvC2B,KAAK+B,EAAkB5D,EAAQ6D,gBAAkB,MACjDhC,KAAKiC,EAASV,EACdvB,KAAKkC,IAAmC/D,EAAQ1B,kBAChDuD,KAAKmC,EAAqBhE,EAAQ1B,mBAAsBA,EACxDuD,KAAKoC,EAAsBb,EAC7B,CAEA,SAAIA,GACF,OAAOvB,KAAKiC,CACd,CAEAxF,iBAAAA,CAAkBV,GAChB,GAAIK,EAAcL,GAAS,OAAOA,EAClC,IAAKA,EAAQ,OAAOiE,KAAK+B,EACzB,OAAO/B,KAAKmC,EAAmBpG,EACjC,CAEAsG,MAAAA,CAAOd,GACL,MAAMe,EAAQ,CACZf,QACAgB,QAASvC,KACTxB,OAAQwB,MAGVA,KAAKwC,EAAM,SAAUF,GACrBtC,KAAKiC,EAASV,EACdvB,KAAKoC,EAAsBb,GAC3BvB,KAAKwC,EAAM,UAAWF,GAEtB,OAAOtC,IACT,CAEQoC,CAAAA,CAAsBK,GAC5B,MAAMC,EAAyC,IAAIjB,IACnD,IAAIkB,EAEJ,IAAK,IAAIxF,EAAIsF,EAASrF,OAAS,EAAGD,GAAK,EAAGA,IAAK,CAC7C,MAAM6B,EAAWyD,EAASrF,OAASD,EAAI,EACvC,MAAMuC,EAAO,IAAIK,EAAK0C,EAAStF,GAAI6C,KAAK6B,EAAc7C,GACtD,MAAM9B,EAAU1B,EAAUkE,EAAKrC,QAC/B,MAAMuF,EAAWpH,EAAUkE,EAAKQ,SAAWF,KAAK+B,GAChD,IAAK/B,KAAK2B,GAAqBjC,EAAKC,OAAQK,KAAK2B,EAAoB,KAErE,IAAK,IAAIkB,EAAI,EAAGA,EAAID,EAASxF,OAAQyF,IAAK,CACxC,MAAMC,EAAe7D,EAAayD,EAAcE,EAASC,GAAIrB,GAC7D,GAAImB,SAAsBrC,EACxBqC,SAA2BC,EAASC,GAEtC,UAAWD,EAASC,KAAOF,GAAqBA,IAAsB,QACpEA,EAAoB,QAGtB,IAAK,IAAI7D,EAAI,EAAGA,EAAI5B,EAAQE,OAAQ0B,IAClCG,EAAa6D,EAAc5F,EAAQ4B,GAAIwC,GAAoBC,MAAM7C,KAAKgB,EAE1E,CACF,CAEAM,KAAK4B,EAAgBc,EACrB,GAAIC,IAAsB,UAAY3C,KAAKkC,EAAgC,CACzE,MAAMzF,EAAoBE,EAA6BgG,IAA+ChG,EAA6BE,OACnImD,KAAKmC,EAAqB1F,CAC5B,CACF,CAGAsG,gBAAAA,CACE1F,EACA2F,EAA2BhD,KAAK+B,GAEhC,IAAK3F,EAAc4G,GACjB,MAAM,IAAI7G,MAAM,8FAGlB,MAAM2G,EAAe7D,EAAae,KAAK4B,EAAeoB,EAAaxB,GACnE,MAAMyB,EAAchE,EAAa6D,EAAczF,EAAQiE,GAEvD,GAAI2B,EAAYlE,OACd,OAAOkE,EAAY1B,MAGrB,MAAM2B,EAAiB7F,IAAW2C,KAAK8B,GAAcgB,EAAaK,IAAInD,KAAK8B,GACvEgB,EAAazD,IAAIW,KAAK8B,GAAaP,WACnCjB,EACJ,IAAIiB,EAAQ5C,EAAiBsE,EAAY1B,MAAO2B,GAEhD,GAAIF,IAAgBhD,KAAK+B,EACvBR,EAAQ5C,EAAiB4C,EAAQvB,KAAa+C,iBAAiB1F,EAAQ2C,KAAK+B,IAG9EkB,EAAY1B,MAAQA,EACpB0B,EAAYlE,OAAS,KAErB,OAAOwC,CACT,CAGA6B,QAAAA,CAAS/F,EAAgB2F,EAA2BlC,GAClD,MAAMS,EAAgCvB,KAAa+C,iBAAiB1F,EAAQ2F,GAE5E,GAAIlC,UAAgBA,IAAU,SAC5B,MAAM,IAAI3E,MAAM,iJAGlB,IAAK6D,KAAK2B,EACR,OAAOJ,EAGT,OAAOA,EAAM8B,QAAO3D,GAAQA,EAAKmB,aAAaC,IAChD,CAEAwC,UAAAA,CAAWN,GACT,IAAK5G,EAAc4G,GACjB,MAAM,IAAI7G,MAAM,kFAGlB,MAAMe,EAAU,IAAIqG,IAEpB,MAAMT,EAAe9C,KAAK4B,EAAcvC,IAAI2D,GAC5C,GAAIF,EACFpH,MAAM8H,KAAKV,EAAajF,QAAQ4F,SAAQpG,GAAUH,EAAQwG,IAAIrG,KAGhE,MAAMsG,EAAsBX,IAAgBhD,KAAK+B,EAC7C/B,KAAK4B,EAAcvC,IAAIW,KAAK+B,QAC5BzB,EACJ,GAAIqD,EACFjI,MAAM8H,KAAKG,EAAoB9F,QAAQ4F,SAAQpG,GAAUH,EAAQwG,IAAIrG,KAGvE,OAAO3B,MAAM8H,KAAKtG,EACpB,CAEA0G,EAAAA,CACEtB,EACAuB,GAEA7D,KAAK8D,EAAU9D,KAAK8D,GAAW,IAAIrC,IACnC,MAAMsC,EAAS/D,KAAK8D,EACpB,MAAME,EAAOD,EAAO1E,IAAIiD,IAAU,KAClC,MAAMpB,EAAOF,EAAW6C,EAASG,GACjCD,EAAOzE,IAAIgD,EAAOpB,GAElB,MAAO,KACL,MAAM+C,EAAcF,EAAO1E,IAAIiD,GAE/B,IAAKpB,EAAKC,OAASD,EAAKD,MAAQgD,IAAgB/C,EAC9C6C,EAAOG,OAAO5B,QACT,GAAIpB,IAAS+C,EAClBF,EAAOzE,IAAIgD,EAAOpB,EAAKD,MAGzBG,EAAWF,EAAK,CAEpB,CAEQsB,CAAAA,CACNjG,EACA4H,GAEA,IAAKnE,KAAK8D,EAAS,OAEnB,IAAIM,EAAUpE,KAAK8D,EAAQzE,IAAI9C,IAAS,KACxC,MAAO6H,IAAY,KAAM,CACvB,MAAMnD,EAAOmD,EAAQnD,KAAOI,EAAgB+C,EAAQnD,MAAQ,KAC5DmD,EAAQ3I,MAAM0I,GACdC,EAAUnD,CACZ,CACF,ECtQK,MAAMoD,oBAGH3C,EAER4C,GAAAA,CAAIjH,EAAgB6C,EAAmBY,GACrC,MAAMpB,EAAQM,KAA0BuE,gBAAgBlH,EAAQ6C,EAASY,GACzE,QAASpB,IAASA,EAAKS,QACzB,CAGAoE,eAAAA,CAAgBlH,EAAgB6C,EAAmBY,GACjD,MAAMkC,EAAchD,KAAKvD,kBAAkByD,GAC3C,MAAMqB,EAASvB,KAAaoD,SAAS/F,EAAQ2F,EAAalC,GAE1D,IAAK,IAAI3D,EAAI,EAAGC,EAASmE,EAAMnE,OAAQD,EAAIC,EAAQD,IACjD,GAAIoE,EAAMpE,GAAGyD,kBAAkBV,GAC7B,OAAOqB,EAAMpE,GAIjB,OAAO,IACT,CAGAqH,MAAAA,CAAOnH,EAAgB6C,EAAmBY,GACxC,OAASd,KAA0BsE,IAAIjH,EAAQ6C,EAASY,EAC1D,ECVF,MAAM2D,GAAsB,CAC1BC,MACAC,MACAC,MACAC,OACAC,MACAC,OACAC,MACAC,OACAC,OACAC,QACAC,SACAC,WACAC,aACAC,WAEF,MAAMC,GAAsB,CAC1BC,KACAC,KACAC,KACAC,MACAC,KACAC,MACAC,GAAIC,EACJC,MACAC,MACAC,OACAC,QACAC,YACAC,SACAC,OAeWC,MAAAA,GAA0BA,CAACC,EAAcC,EAAcvI,IAAYwI,EAAa3K,OAAA4K,OAAA,CAAA,EACtFnC,GAAwBgC,GAAYzK,OAAA4K,OAAA,CAAA,EACpCpB,GAAwBkB,GAC7BvI,GAGK,MAAM0I,GAAoBF,EAAclC,GAAqBe,ICrFpE,MAAMsB,GAAuB,uBAC7B,MAAMC,GAAa,aACnB,MAAMC,GAAe,MACrB,MAAMC,GAAa,MAEnB,SAASC,GAAoBC,EAAeC,EAAevK,GACzD,MAAMwK,EAAaxK,EAAO,KAAO,KAAOsK,EAAM,KAAO,KAAOA,EAAMA,EAAM/J,OAAS,KAAO,IACpF,IACA,IACJ,MAAMkK,EAAUH,EAAM3J,QAAQ,SAAW,EAAI,OAAS,IACtD,MAAM+J,EAAUJ,EAAMK,QAAQP,GAAY,QACvCO,QAAQR,GAAcM,EAAUD,GAEnC,OAAOD,EAAQD,EAAM/J,SAAWP,EAAOO,OAAS,MAAMmK,MAAcA,CACtE,CAEA,SAASE,GAAaN,EAAeC,EAAevK,GAClD,GAAIsK,IAAU,MAAQtK,EAAOuK,EAAQ,KAAO,KAAOvK,EAAOuK,EAAQ,KAAO,KACvE,OAAOD,EAGT,MAAO,KAAKA,GACd,CAEA,SAASO,GAAc/H,GACrB,MAAMgI,EAAWhI,EAAOT,KAAI4B,GAASA,EAClC0G,QAAQV,GAAsBW,IAC9BD,QAAQT,GAAYG,MACvB,MAAMK,EAAUI,EAASvK,OAAS,EAAI,MAAMuK,EAAS3J,KAAK,QAAU2J,EAAS,GAE7E,OAAO,IAAIC,OAAO,IAAIL,KACxB,CAEaM,MAAAA,GAAqClI,IAChD,IAAI4H,EAEJ,OAAQzG,IACN,UAAWyG,IAAY,YACrBA,EAAU5H,EAAOmI,OAAMC,GAAKA,EAAEvK,QAAQ,QAAU,IAC5C,KACAkK,GAAc/H,GAGpB,OAAO4H,IAAY,KACf5H,EAAOnC,QAAQsD,MAAY,EAC3ByG,EAAQS,KAAKlH,EAAM,CACxB,ECrCI,MAAMmH,gBAGH5D,YACR3H,WAAAA,CAAY6E,EAA6B,GAAIpD,EAAgC,CAAA,GAC3E+J,MAAM3G,EAAKvF,OAAA4K,OAAA,CACT9G,kBAAmB+G,GACnBjH,aAAciI,IACX1J,GAEP,EAmBK,SAASgK,mBAAmB5G,EAAe,GAAIpD,EAAU,CAAA,GAC9D,OAAO,IAAIkG,YAAY9C,EAAKvF,OAAA4K,OAAA,CAC1B9G,kBAAmB+G,GACnBjH,aAAciI,IACX1J,GAEP,CCrCA,SAASiK,eAAeC,GACtB,OAAOA,EAAQC,iBAAchI,UAAoB+H,EAAQC,UAAUvF,mBAAqB,UAC1F,CAEA,MAAMwF,GAGJ7L,WAAAA,CAAYgD,GACVM,KAAKwI,EAAQ9I,CACf,CAEA+I,OAAAA,CAAQrI,GACNJ,KAAKwI,EAAMpI,OAASA,EACpB,OAAOJ,IACT,EA+DK,MAAM0I,eAOXhM,WAAAA,CAAYiM,GAAgC3I,KANrCuB,MAAwB,GAO7BvB,KAAK4I,EAAiBD,EAEtB3I,KAAKsE,IAAM,CACTjH,EACA6C,EACA2I,EACAhJ,IACGG,KAAK8I,EAASzL,EAAQ6C,EAAS2I,EAAoBhJ,EAAY,OACpEG,KAAKwE,OAAS,CACZnH,EACA6C,EACA2I,EACAhJ,IACGG,KAAK8I,EAASzL,EAAQ6C,EAAS2I,EAAoBhJ,EAAY,MAEpEG,KAAK+I,MAAQ5K,GAAYiK,eAAepI,KAAK4I,GACzC,IAAI5I,KAAK4I,EAAe5I,KAAKuB,MAAOpD,GACpC6B,KAAK4I,EAAe5I,KAAKuB,MAAOpD,EACtC,CAEQ2K,CAAAA,CACNzL,EACA6C,EACA2I,EACAhJ,EACAM,GAEA,MAAMT,EAAO,CAAErC,UAEf,GAAI8C,EAAUT,EAAKS,SAAWA,EAC9B,GAAID,EAAS,CACXR,EAAKQ,QAAUA,EAEf,GAAIxE,MAAMC,QAAQkN,WAA8BA,IAAuB,SACrEnJ,EAAKC,OAASkJ,OACT,UAAWA,IAAuB,YACvCnJ,EAAKG,WAAagJ,EAGpB,UAAWhJ,IAAe,YACxBH,EAAKG,WAAaA,CAEtB,CAEAG,KAAKuB,MAAM7C,KAAKgB,GAChB,OAAO,IAAI6I,GAAY7I,EACzB,EAcK,SAASsJ,cAEdC,EAAsC9K,GACtC,MAAM+K,EAAU,IAAIR,eAAkBP,oBACtC,MAAMgB,EAASF,EAAOC,EAAQ5E,IAAK4E,EAAQ1E,QAE3C,GAAI2E,UAAiBA,EAAOC,OAAS,WACnC,OAAOD,EAAOC,MAAK,IAAMF,EAAQH,MAAM5K,KAGzC,OAAO+K,EAAQH,MAAM5K,EACvB,CC9JakL,MAAAA,GAA0CC,GAAS,mBAAmBA,EAAMjM,eAAeiM,EAAMtG,eAE9G,MAAMuG,GAAc,SAASC,EAAoBC,GAC/CzJ,KAAKyJ,QAAUA,CACjB,EAEAF,GAAYjB,UAAYtM,OAAO0N,OAAOvN,MAAMmM,WAErC,MAAMqB,uBAA6CJ,GASxD,wBAAOK,CAAkBC,GACvB7J,KAAK8J,SAA8BD,IAAgB,SAAW,IAAMA,EAAcA,CACpF,CAEA,WAAOrG,CAA2BjB,GAChC,OAAO,IAAIvC,KAAQuC,EACrB,CAEA7F,WAAAA,CAAY6F,GACV2F,MAAM,IACNlI,KAAKuC,QAAUA,EAEf,UAAWpG,MAAM4N,oBAAsB,WAAY,CACjD/J,KAAKzD,KAAO,iBACZJ,MAAM4N,kBAAkB/J,KAAMA,KAAKtD,YACrC,CACF,CAEAsN,UAAAA,CAAWP,GACTzJ,KAAKyJ,QAAUA,EACf,OAAOzJ,IACT,CAGAiK,cAAAA,CAAe5M,EAAgB6C,EAAmBY,GAChD,MAAMwI,EAAStJ,KAAakK,UAAU7M,EAAQ6C,EAASY,GACvD,GAAIwI,EAAO,MAAMA,CACnB,CAGAY,SAAAA,CAAU7M,EAAgB6C,EAAmBY,GAC3C,MAAMpB,EAAOM,KAAKuC,QAAQgC,gBAAgBlH,EAAQ6C,EAASY,GAE3D,GAAIpB,IAASA,EAAKS,SAChB,OAGFH,KAAK3C,OAASA,EACd2C,KAAKE,QAAUA,EACfF,KAAKgD,YAAcxG,EAAmBwD,KAAKuC,QAAQ9F,kBAAkByD,IACrEF,KAAKc,MAAQA,EAEb,MAAMV,EAASV,EAAOA,EAAKU,OAAS,GAEpCJ,KAAKyJ,QAAUzJ,KAAKyJ,SAAWrJ,GAAWJ,KAAKtD,YAAoBoN,EAAqB9J,MACxF,OAAOA,IACT,EAvDW2J,eAOJG,EAAuBT"}