From d7f7108831d5a4d5f93ec9aba3c3f8bc6ad96429 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 22 Aug 2024 10:06:57 +1200 Subject: [PATCH 01/59] add Api modules to /platform --- packages/platform-node/examples/api.ts | 66 ++ packages/platform/src/Api.ts | 109 ++++ packages/platform/src/ApiBuilder.ts | 211 +++++++ packages/platform/src/ApiEndpoint.ts | 632 +++++++++++++++++++ packages/platform/src/ApiGroup.ts | 237 +++++++ packages/platform/src/HttpMethod.ts | 20 +- packages/platform/src/HttpRouter.ts | 9 + packages/platform/src/index.ts | 20 + packages/platform/src/internal/httpRouter.ts | 9 + 9 files changed, 1312 insertions(+), 1 deletion(-) create mode 100644 packages/platform-node/examples/api.ts create mode 100644 packages/platform/src/Api.ts create mode 100644 packages/platform/src/ApiBuilder.ts create mode 100644 packages/platform/src/ApiEndpoint.ts create mode 100644 packages/platform/src/ApiGroup.ts diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts new file mode 100644 index 0000000000..ba3d845501 --- /dev/null +++ b/packages/platform-node/examples/api.ts @@ -0,0 +1,66 @@ +import { Api, ApiBuilder, ApiEndpoint, ApiGroup, HttpMiddleware, HttpServer } from "@effect/platform" +import { NodeHttpServer, NodeRuntime } from "@effect/platform-node" +import { Schema } from "@effect/schema" +import { Effect, Layer } from "effect" +import { createServer } from "node:http" + +class User extends Schema.Class("User")({ + id: Schema.Number, + name: Schema.String +}) {} + +class Unauthorized extends Schema.TaggedError()("Unauthorized", { + message: Schema.String +}) {} + +const users = ApiGroup.make("users").pipe( + ApiGroup.add( + ApiEndpoint.get("findById", "/:id").pipe( + ApiEndpoint.setPathSchema(Schema.Struct({ + id: Schema.NumberFromString + })), + ApiEndpoint.setSuccess(User), + ApiEndpoint.setError(Schema.String) + ) + ), + ApiGroup.add( + ApiEndpoint.post("create", "/").pipe( + ApiEndpoint.setPayload(Schema.Struct({ + name: Schema.String + })), + ApiEndpoint.setSuccess(User), + ApiEndpoint.setError(Schema.String) + ) + ), + ApiGroup.addError(Unauthorized) +) + +const api = Api.make("My api").pipe( + Api.addGroup("/users", users) +) + +const UsersLive = ApiBuilder.group(api, "users", (handlers) => + handlers.pipe( + ApiBuilder.handle("create", (_) => + Effect.succeed( + new User({ + id: 1, + name: "John" + }) + )), + ApiBuilder.handle("findById", (_) => + Effect.succeed( + new User({ + id: _.path.id, + name: "John" + }) + )) + )) + +ApiBuilder.serve(api, HttpServer.serve(HttpMiddleware.logger)).pipe( + Layer.provide(UsersLive), + HttpServer.withLogAddress, + Layer.provide(NodeHttpServer.layer(createServer, { port: 3000 })), + Layer.launch, + NodeRuntime.runMain +) diff --git a/packages/platform/src/Api.ts b/packages/platform/src/Api.ts new file mode 100644 index 0000000000..b95ef17636 --- /dev/null +++ b/packages/platform/src/Api.ts @@ -0,0 +1,109 @@ +/** + * @since 1.0.0 + */ +import * as Chunk from "effect/Chunk" +import { dual } from "effect/Function" +import type { Pipeable } from "effect/Pipeable" +import { pipeArguments } from "effect/Pipeable" +import * as Predicate from "effect/Predicate" +import * as ApiGroup from "./ApiGroup.js" +import type * as HttpRouter from "./HttpRouter.js" + +/** + * @since 1.0.0 + * @category type ids + */ +export const TypeId: unique symbol = Symbol.for("@effect/platform/Api") + +/** + * @since 1.0.0 + * @category type ids + */ +export type TypeId = typeof TypeId + +/** + * @since 1.0.0 + * @category guards + */ +export const isApi = (u: unknown): u is Api => Predicate.hasProperty(u, TypeId) + +/** + * @since 1.0.0 + * @category models + */ +export interface Api extends Pipeable { + readonly [TypeId]: TypeId + readonly name: Name + readonly groups: Chunk.Chunk + // TODO: error schema +} + +/** + * @since 1.0.0 + * @category models + */ +export declare namespace Api { + /** + * @since 1.0.0 + * @category models + */ + export type Any = Api | Api +} + +const Proto = { + [TypeId]: TypeId, + pipe() { + return pipeArguments(this, arguments) + } +} + +const makeProto = (options: { + readonly name: Name + readonly groups: Chunk.Chunk +}): Api => { + const self = Object.create(Proto) + self.name = options.name + self.groups = options.groups + return self +} + +/** + * @since 1.0.0 + * @category constructors + */ +export const make = (name: Name): Api => makeProto({ name, groups: Chunk.empty() }) + +/** + * @since 1.0.0 + * @category constructors + */ +export const addGroup: { + ( + group: Group + ): (self: Api) => Api + ( + path: HttpRouter.PathInput, + group: Group + ): (self: Api) => Api + ( + self: Api, + group: Group + ): Api + ( + self: Api, + path: HttpRouter.PathInput, + group: Group + ): Api +} = dual( + (args) => isApi(args[0]), + ( + self: Api.Any, + ...args: [group: ApiGroup.ApiGroup.Any] | [path: HttpRouter.PathInput, group: ApiGroup.ApiGroup.Any] + ) => { + const group = args.length === 1 ? args[0] : ApiGroup.prefix(args[1] as any, args[0]) + return makeProto({ + ...self, + groups: Chunk.append(self.groups, group) + }) + } +) diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts new file mode 100644 index 0000000000..b1199e592a --- /dev/null +++ b/packages/platform/src/ApiBuilder.ts @@ -0,0 +1,211 @@ +/** + * @since 1.0.0 + */ +import * as Schema from "@effect/schema/Schema" +import * as Chunk from "effect/Chunk" +import * as Context from "effect/Context" +import * as Effect from "effect/Effect" +import * as FiberRef from "effect/FiberRef" +import { identity } from "effect/Function" +import type * as Layer from "effect/Layer" +import * as Option from "effect/Option" +import { type Pipeable, pipeArguments } from "effect/Pipeable" +import type { ReadonlyRecord } from "effect/Record" +import type { Covariant } from "effect/Types" +import type * as Api from "./Api.js" +import * as ApiEndpoint from "./ApiEndpoint.js" +import type * as ApiGroup from "./ApiGroup.js" +import type * as HttpApp from "./HttpApp.js" +import * as HttpMethod from "./HttpMethod.js" +import * as HttpRouter from "./HttpRouter.js" +import * as HttpServerRequest from "./HttpServerRequest.js" +import * as HttpServerResponse from "./HttpServerResponse.js" + +/** + * @since 1.0.0 + * @category router + */ +export class ApiRouter extends HttpRouter.Tag("@effect/platform/ApiBuilder/ApiRouter")() {} + +/** + * @since 1.0.0 + * @category constructors + */ +export const serve = ( + _self: Api.Api, + f: (httpApp: HttpApp.Default) => Layer.Layer +): Layer.Layer< + A, + E, + R | ApiGroup.ApiGroup.ToService +> => + ApiRouter.unwrap((router) => + router.pipe( + // TODO: Build global error encoder + Effect.catchAll(Effect.die), + f + ) + ) + +/** + * @since 1.0.0 + * @category handlers + */ +export const HandlersTypeId: unique symbol = Symbol.for("@effect/platform/ApiBuilder/Handlers") + +/** + * @since 1.0.0 + * @category handlers + */ +export type HandlersTypeId = typeof HandlersTypeId + +/** + * @since 1.0.0 + * @category handlers + */ +export interface Handlers< + E, + R, + Endpoints extends ApiEndpoint.ApiEndpoint.Any = never +> extends Pipeable { + readonly [HandlersTypeId]: { + _Endpoints: Covariant + } + readonly group: ApiGroup.ApiGroup + readonly handlers: Chunk.Chunk<[ApiEndpoint.ApiEndpoint.Any, ApiEndpoint.ApiEndpoint.Handler]> +} + +const HandlersProto = { + [HandlersTypeId]: { + _Endpoints: identity + }, + pipe() { + return pipeArguments(this, arguments) + } +} + +const makeHandlers = ( + options: { + readonly group: ApiGroup.ApiGroup + readonly handlers: Chunk.Chunk<[ApiEndpoint.ApiEndpoint.Any, ApiEndpoint.ApiEndpoint.Handler]> + } +): Handlers => { + const self = Object.create(HandlersProto) + self.group = options.group + self.handlers = options.handlers + return self +} + +const requestPayload = ( + request: HttpServerRequest.HttpServerRequest, + urlParams: ReadonlyRecord> +) => HttpMethod.hasBody(request.method) ? request.json : Effect.succeed(urlParams) + +const handlerToRoute = ( + endpoint: ApiEndpoint.ApiEndpoint.Any, + handler: ApiEndpoint.ApiEndpoint.Handler +): HttpRouter.Route => { + const decodePath = Option.map(endpoint.pathSchema, Schema.decodeUnknown) + const decodePayload = Option.map(endpoint.payloadSchema, Schema.decodeUnknown) + const encodeSuccess = Option.map(ApiEndpoint.successSchema(endpoint), Schema.encodeUnknown) + const successStatus = ApiEndpoint.successStatus(endpoint) + return HttpRouter.makeRoute( + endpoint.method, + endpoint.path, + Effect.withFiberRuntime((fiber) => { + const context = fiber.getFiberRef(FiberRef.currentContext) + const request = Context.unsafeGet(context, HttpServerRequest.HttpServerRequest) + const routeContext = Context.unsafeGet(context, HttpRouter.RouteContext) + const urlParams = Context.unsafeGet(context, HttpServerRequest.ParsedSearchParams) + return (decodePath._tag === "Some" + ? Effect.orDie(decodePath.value(routeContext.params)) + : Effect.succeed(routeContext.params)).pipe( + Effect.bindTo("pathParams"), + decodePayload._tag === "Some" + ? Effect.bind("payload", (_) => + requestPayload(request, urlParams).pipe( + Effect.flatMap(decodePayload.value), + Effect.orDie + )) + : identity, + Effect.flatMap((input) => { + const request: any = { path: input.pathParams } + if ("payload" in input) { + request.payload = input.payload + } + return handler(request) + }), + encodeSuccess._tag === "Some" + ? Effect.flatMap((body) => + encodeSuccess.value(body).pipe( + Effect.flatMap((json) => HttpServerResponse.json(json, { status: successStatus })), + Effect.orDie + ) + ) + : Effect.as(HttpServerResponse.empty({ status: successStatus })) + ) + }) + ) +} + +/** + * @since 1.0.0 + * @category handlers + */ +export const group = < + ApiName extends string, + Groups extends ApiGroup.ApiGroup.Any, + const Name extends Groups["name"], + RH, + EX = never, + RX = never +>( + api: Api.Api, + groupName: Name, + build: ( + handlers: Handlers> + ) => + | Handlers, RH> + | Effect.Effect, RH>, EX, RX> +): Layer.Layer, EX, RX> => + ApiRouter.use((router) => + Effect.gen(function*() { + const group = Chunk.findFirst(api.groups, (group) => group.name === groupName) + if (group._tag === "None") { + throw new Error(`Group "${groupName}" not found in API "${api.name}"`) + } + const result = build(makeHandlers({ group: group.value as any, handlers: Chunk.empty() })) + const handlers = Effect.isEffect(result) ? (yield* result) : result + yield* router.concat( + HttpRouter.fromIterable( + Chunk.map(handlers.handlers, ([endpoint, handler]) => handlerToRoute(endpoint, handler)) + ) + ) + }) + ) as Layer.Layer, EX, RX> + +/** + * @since 1.0.0 + * @category handlers + */ +export const handle = ( + name: Name, + handler: ApiEndpoint.ApiEndpoint.HandlerWithName +) => +( + self: Handlers +): Handlers< + EG | Exclude>, + RG | ApiEndpoint.ApiEndpoint.ExcludeProvided, + ApiEndpoint.ApiEndpoint.ExcludeName +> => { + const o = Chunk.findFirst(self.group.endpoints, (endpoint) => endpoint.name === name) + if (o._tag === "None") { + throw new Error(`Endpoint "${name}" not found in group "${self.group.name}"`) + } + const endpoint = o.value + return makeHandlers({ + group: self.group, + handlers: Chunk.append(self.handlers, [endpoint, handler]) as any + }) as any +} diff --git a/packages/platform/src/ApiEndpoint.ts b/packages/platform/src/ApiEndpoint.ts new file mode 100644 index 0000000000..1b640e18b2 --- /dev/null +++ b/packages/platform/src/ApiEndpoint.ts @@ -0,0 +1,632 @@ +/** + * @since 1.0.0 + */ +import * as AST from "@effect/schema/AST" +import * as Schema from "@effect/schema/Schema" +import type { Effect } from "effect/Effect" +import { dual } from "effect/Function" +import * as Option from "effect/Option" +import { type Pipeable, pipeArguments } from "effect/Pipeable" +import * as Predicate from "effect/Predicate" +import type * as Types from "effect/Types" +import type { HttpMethod } from "./HttpMethod.js" +import * as HttpRouter from "./HttpRouter.js" + +/** + * @since 1.0.0 + * @category type ids + */ +export const TypeId: unique symbol = Symbol.for("@effect/platform/ApiEndpoint") + +/** + * @since 1.0.0 + * @category type ids + */ +export type TypeId = typeof TypeId + +/** + * @since 1.0.0 + * @category symbols + */ +export const Ignored: unique symbol = Symbol.for("@effect/platform/ApiEndpoint/Ignored") + +/** + * @since 1.0.0 + * @category symbols + */ +export type Ignored = typeof Ignored + +/** + * @since 1.0.0 + * @category guards + */ +export const isApiEndpoint = (u: unknown): u is ApiEndpoint => Predicate.hasProperty(u, TypeId) + +/** + * @since 1.0.0 + * @category models + */ +export interface ApiEndpoint< + out Name extends string, + out Method extends HttpMethod, + out Path extends Schema.Schema.Any = PathParams, + out Payload extends Schema.Schema.All = typeof Schema.Never, + out Success extends Schema.Schema.Any = Empty, + out Error extends Schema.Schema.All = typeof Schema.Never +> extends Pipeable { + readonly [TypeId]: TypeId + readonly name: Name + readonly path: HttpRouter.PathInput + readonly method: Method + readonly pathSchema: Option.Option + readonly payloadSchema: Option.Option + readonly successSchema: Success + readonly errorSchema: Error +} + +/** + * @since 1.0.0 + * @category models + */ +export interface PathParams extends Schema.Record$ {} + +/** + * @since 1.0.0 + * @category models + */ +export declare namespace ApiEndpoint { + /** + * @since 1.0.0 + * @category models + */ + export type Any = ApiEndpoint + + /** + * @since 1.0.0 + * @category models + */ + export type Success = Endpoint extends + ApiEndpoint + ? Schema.Schema.Type<_Success> + : never + + /** + * @since 1.0.0 + * @category models + */ + export type Error = Endpoint extends + ApiEndpoint + ? Schema.Schema.Type<_Error> + : never + + /** + * @since 1.0.0 + * @category models + */ + export type PathParsed = Endpoint extends + ApiEndpoint + ? Schema.Schema.Type<_Path> + : never + + /** + * @since 1.0.0 + * @category models + */ + export type Payload = Endpoint extends + ApiEndpoint + ? Schema.Schema.Type<_Payload> + : never + + /** + * @since 1.0.0 + * @category models + */ + export type Request = { + readonly path: PathParsed + } & ([Payload] extends [infer P] ? [P] extends [never] ? {} : { readonly payload: P } : {}) + + /** + * @since 1.0.0 + * @category models + */ + export type Context = Endpoint extends + ApiEndpoint ? + | Schema.Schema.Context<_Path> + | Schema.Schema.Context<_Payload> + | Schema.Schema.Context<_Success> + | Schema.Schema.Context<_Error> + : never + + /** + * @since 1.0.0 + * @category models + */ + export type Handler = ( + request: Types.Simplify> + ) => Effect, E, R> + + /** + * @since 1.0.0 + * @category models + */ + export type WithName = Endpoints extends infer Endpoint + ? Endpoint extends { readonly name: Name } ? Endpoint : never + : never + + /** + * @since 1.0.0 + * @category models + */ + export type ExcludeName = Exclude + + /** + * @since 1.0.0 + * @category models + */ + export type HandlerWithName = Handler< + WithName, + E, + R + > + + /** + * @since 1.0.0 + * @category models + */ + export type ErrorWithName = Error> + + /** + * @since 1.0.0 + * @category models + */ + export type ExcludeProvided = Exclude< + R, + HttpRouter.HttpRouter.DefaultServices | HttpRouter.HttpRouter.DefaultServices + > + + /** + * @since 1.0.0 + * @category models + */ + export type ValidatePath = S extends Schema.Schema + ? [_I] extends [Readonly>] ? {} + : `Path schema must be encodeable to strings` + : {} + + /** + * @since 1.0.0 + * @category models + */ + export type ValidatePayload = Method extends + HttpMethod.NoBody ? + P extends Schema.Schema + ? [_I] extends [Readonly | undefined>>] ? {} + : `'${Method}' payload must be encodeable to strings` + : {} + : {} +} + +const Proto = { + [TypeId]: TypeId, + pipe() { + return pipeArguments(this, arguments) + } +} + +const makeProto = < + Name extends string, + Method extends HttpMethod, + Path extends Schema.Schema.Any, + Payload extends Schema.Schema.All, + Success extends Schema.Schema.Any, + Error extends Schema.Schema.All +>(options: { + readonly name: Name + readonly path: HttpRouter.PathInput + readonly method: Method + readonly pathSchema: Option.Option + readonly payloadSchema: Option.Option + readonly successSchema: Success + readonly errorSchema: Error +}): ApiEndpoint => { + const self = Object.create(Proto) + self.name = options.name + self.method = options.method + self.path = options.path + self.pathSchema = options.pathSchema + self.payloadSchema = options.payloadSchema + self.successSchema = options.successSchema + self.errorSchema = options.errorSchema + return self +} + +/** + * @since 1.0.0 + * @category constructors + */ +export const make = (method: Method) => +( + name: Name, + path: HttpRouter.PathInput +): ApiEndpoint => + makeProto({ + name, + path, + method, + pathSchema: Option.none(), + payloadSchema: Option.none(), + successSchema: Empty, + errorSchema: Schema.Never + }) + +/** + * @since 1.0.0 + * @category constructors + */ +export const get: ( + name: Name, + path: HttpRouter.PathInput +) => ApiEndpoint = make("GET") + +/** + * @since 1.0.0 + * @category constructors + */ +export const post: ( + name: Name, + path: HttpRouter.PathInput +) => ApiEndpoint = make( + "POST" +) + +/** + * @since 1.0.0 + * @category constructors + */ +export const put: ( + name: Name, + path: HttpRouter.PathInput +) => ApiEndpoint = make( + "PUT" +) + +/** + * @since 1.0.0 + * @category constructors + */ +export const patch: ( + name: Name, + path: HttpRouter.PathInput +) => ApiEndpoint = make( + "PATCH" +) + +/** + * @since 1.0.0 + * @category constructors + */ +export const del: ( + name: Name, + path: HttpRouter.PathInput +) => ApiEndpoint = make( + "DELETE" +) + +/** + * @since 1.0.0 + * @category annotations + */ +export const AnnotationStatus: unique symbol = Symbol.for("@effect/platform/ApiEndpoint/AnnotationStatus") + +type Void$ = typeof Schema.Void + +/** + * @since 1.0.0 + * @category schemas + */ +export interface Created extends Void$ { + readonly _: unique symbol +} + +/** + * @since 1.0.0 + * @category schemas + */ +export const Created: Created = Schema.Void.annotations({ + [AnnotationStatus]: 201 +}) as any + +/** + * @since 1.0.0 + * @category schemas + */ +export interface Accepted extends Void$ { + readonly _: unique symbol +} + +/** + * @since 1.0.0 + * @category schemas + */ +export const Accepted: Accepted = Schema.Void.annotations({ + [AnnotationStatus]: 202 +}) as any + +/** + * @since 1.0.0 + * @category schemas + */ +export interface Empty extends Void$ { + readonly _: unique symbol +} + +/** + * @since 1.0.0 + * @category schemas + */ +export const Empty: Empty = Schema.Void.annotations({ + [AnnotationStatus]: 204 +}) as any + +/** + * @since 1.0.0 + * @category result + */ +export const setSuccess: { + ( + schema: S, + annotations?: { + readonly status?: number | undefined + } + ): < + Name extends string, + Method extends HttpMethod, + _Path extends Schema.Schema.Any, + _P extends Schema.Schema.All, + _S extends Schema.Schema.Any, + _E extends Schema.Schema.All + >( + self: ApiEndpoint + ) => ApiEndpoint + < + Name extends string, + Method extends HttpMethod, + _Path extends Schema.Schema.Any, + _P extends Schema.Schema.All, + _S extends Schema.Schema.Any, + _E extends Schema.Schema.All, + S extends Schema.Schema.Any + >( + self: ApiEndpoint, + schema: S, + annotations?: { + readonly status?: number | undefined + } + ): ApiEndpoint +} = dual( + (args) => isApiEndpoint(args[0]), + < + Name extends string, + Method extends HttpMethod, + _Path extends Schema.Schema.Any, + _P extends Schema.Schema.All, + _S extends Schema.Schema.Any, + _E extends Schema.Schema.All, + S extends Schema.Schema.Any + >( + self: ApiEndpoint, + schema: S, + annotations?: { + readonly status?: number | undefined + } + ): ApiEndpoint => + makeProto({ + ...self, + successSchema: schema.annotations({ + [AnnotationStatus]: annotations?.status ?? + Option.getOrElse(AST.getAnnotation(schema.ast, AnnotationStatus), () => 200) + }) as S + }) +) + +/** + * @since 1.0.0 + * @category result + */ +export const setError: { + ( + schema: E, + annotations?: { + readonly status?: number | undefined + } + ): < + Name extends string, + Method extends HttpMethod, + _Path extends Schema.Schema.Any, + _P extends Schema.Schema.All, + _S extends Schema.Schema.Any, + _E extends Schema.Schema.All + >( + self: ApiEndpoint + ) => ApiEndpoint + < + Name extends string, + Method extends HttpMethod, + _Path extends Schema.Schema.Any, + _P extends Schema.Schema.All, + _S extends Schema.Schema.Any, + _E extends Schema.Schema.All, + E extends Schema.Schema.All + >( + self: ApiEndpoint, + schema: E, + annotations?: { + readonly status?: number | undefined + } + ): ApiEndpoint +} = dual( + (args) => isApiEndpoint(args[0]), + < + Name extends string, + Method extends HttpMethod, + _Path extends Schema.Schema.Any, + _P extends Schema.Schema.All, + _S extends Schema.Schema.Any, + _E extends Schema.Schema.All, + E extends Schema.Schema.All + >( + self: ApiEndpoint, + schema: E, + annotations?: { + readonly status?: number | undefined + } + ): ApiEndpoint => + makeProto({ + ...self, + errorSchema: schema.pipe( + Schema.annotations({ + [AnnotationStatus]: annotations?.status ?? + Option.getOrElse(AST.getAnnotation(schema.ast, AnnotationStatus), () => 500) + }) + ) as E + }) +) + +/** + * @since 1.0.0 + * @category request + */ +export const setPayload: { + ( + schema: P & ApiEndpoint.ValidatePayload + ): < + Name extends string, + _Path extends Schema.Schema.Any, + _P extends Schema.Schema.All, + _S extends Schema.Schema.Any, + _E extends Schema.Schema.All + >( + self: ApiEndpoint + ) => ApiEndpoint + < + Name extends string, + Method extends HttpMethod, + _Path extends Schema.Schema.Any, + _P extends Schema.Schema.All, + _S extends Schema.Schema.Any, + _E extends Schema.Schema.All, + P extends Schema.Schema.All + >( + self: ApiEndpoint, + schema: P & ApiEndpoint.ValidatePayload + ): ApiEndpoint +} = dual( + 2, + < + Name extends string, + Method extends HttpMethod, + _Path extends Schema.Schema.Any, + _P extends Schema.Schema.All, + _S extends Schema.Schema.Any, + _E extends Schema.Schema.All, + P extends Schema.Schema.All + >( + self: ApiEndpoint, + schema: P & ApiEndpoint.ValidatePayload + ): ApiEndpoint => + makeProto({ + ...self, + payloadSchema: Option.some(schema) + }) +) + +/** + * @since 1.0.0 + * @category request + */ +export const setPathSchema: { + ( + schema: Path & ApiEndpoint.ValidatePath + ): < + Name extends string, + Method extends HttpMethod, + _Path extends Schema.Schema.Any, + _P extends Schema.Schema.All, + _S extends Schema.Schema.Any, + _E extends Schema.Schema.All + >( + self: ApiEndpoint + ) => ApiEndpoint + < + Name extends string, + Method extends HttpMethod, + _Path extends Schema.Schema.Any, + _P extends Schema.Schema.All, + _S extends Schema.Schema.Any, + _E extends Schema.Schema.All, + Path extends Schema.Schema.Any + >( + self: ApiEndpoint, + schema: Path & ApiEndpoint.ValidatePath + ): ApiEndpoint +} = dual( + 2, + < + Name extends string, + Method extends HttpMethod, + _Path extends Schema.Schema.Any, + _P extends Schema.Schema.All, + _S extends Schema.Schema.Any, + _E extends Schema.Schema.All, + Path extends Schema.Schema.Any + >( + self: ApiEndpoint, + schema: Path & ApiEndpoint.ValidatePath + ): ApiEndpoint => + makeProto({ + ...self, + pathSchema: Option.some(schema) + }) +) + +/** + * @since 1.0.0 + * @category request + */ +export const prefix: { + (prefix: HttpRouter.PathInput): (self: A) => A + (self: A, prefix: HttpRouter.PathInput): A +} = dual(2, (self: A, prefix: HttpRouter.PathInput): A => + makeProto({ + ...self, + path: HttpRouter.prefixPath(self.path, prefix) + }) as A) + +/** + * @since 1.0.0 + * @category reflection + */ +export const successStatus = (self: A): number => { + const status = AST.getAnnotation(self.successSchema.ast, AnnotationStatus) + const ast = Schema.encodedSchema(self.successSchema).ast + const isVoid = ast._tag === "VoidKeyword" + return Option.getOrElse(status, () => isVoid ? 204 : 200) +} + +/** + * @since 1.0.0 + * @category reflection + */ +export const successSchema = (self: A): Option.Option => { + const ast = Schema.encodedSchema(self.successSchema).ast + return ast._tag === "VoidKeyword" ? Option.none() : Option.some(self.successSchema) +} + +/** + * @since 1.0.0 + * @category reflection + */ +export const successIsVoid = (self: A): boolean => { + const ast = Schema.encodedSchema(self.successSchema).ast + return ast._tag === "VoidKeyword" +} diff --git a/packages/platform/src/ApiGroup.ts b/packages/platform/src/ApiGroup.ts new file mode 100644 index 0000000000..f9ea95c8a7 --- /dev/null +++ b/packages/platform/src/ApiGroup.ts @@ -0,0 +1,237 @@ +/** + * @since 1.0.0 + */ +import * as AST from "@effect/schema/AST" +import * as Schema from "@effect/schema/Schema" +import * as Chunk from "effect/Chunk" +import { dual } from "effect/Function" +import * as Option from "effect/Option" +import { type Pipeable, pipeArguments } from "effect/Pipeable" +import * as ApiEndpoint from "./ApiEndpoint.js" +import type { PathInput } from "./HttpRouter.js" + +/** + * @since 1.0.0 + * @category type ids + */ +export const TypeId: unique symbol = Symbol.for("@effect/platform/ApiGroup") + +/** + * @since 1.0.0 + * @category type ids + */ +export type TypeId = typeof TypeId + +/** + * @since 1.0.0 + * @category models + */ +export interface ApiGroup< + out Name extends string, + out Endpoints extends ApiEndpoint.ApiEndpoint.Any = never, + in out Error = never, + out ErrorR = never +> extends Pipeable { + readonly [TypeId]: TypeId + readonly name: Name + readonly endpoints: Chunk.Chunk + readonly error: Schema.Schema +} + +/** + * @since 1.0.0 + * @category models + */ +export declare namespace ApiGroup { + /** + * @since 1.0.0 + * @category models + */ + export type Any = ApiGroup | ApiGroup | ApiGroup + + /** + * @since 1.0.0 + * @category models + */ + export interface Service { + readonly _: unique symbol + readonly name: Name + } + + /** + * @since 1.0.0 + * @category models + */ + export type ToService = Group extends ApiGroup + ? Service + : never + + /** + * @since 1.0.0 + * @category models + */ + export type WithName = Extract + + /** + * @since 1.0.0 + * @category models + */ + export type Endpoints = Group extends ApiGroup + ? _Endpoints + : never + + /** + * @since 1.0.0 + * @category models + */ + export type EndpointsWithName = Endpoints> + + /** + * @since 1.0.0 + * @category models + */ + export type Error = Group extends ApiGroup ? _Error + : never + + /** + * @since 1.0.0 + * @category models + */ + export type ErrorWithName = Error> + + /** + * @since 1.0.0 + * @category models + */ + export type Context = Group extends ApiGroup + ? _ErrorR | ApiEndpoint.ApiEndpoint.Context<_Endpoints> + : never + + /** + * @since 1.0.0 + * @category models + */ + export type ContextWithName = Context> +} + +const Proto = { + [TypeId]: TypeId, + pipe() { + return pipeArguments(this, arguments) + } +} + +const makeProto = (options: { + readonly name: Name + readonly endpoints: Chunk.Chunk + readonly error: Schema.Schema +}): ApiGroup => { + const self = Object.create(Proto) + self.name = options.name + self.endpoints = options.endpoints + self.error = options.error + return self +} + +/** + * @since 1.0.0 + * @category constructors + */ +export const make = (name: Name): ApiGroup => + makeProto({ name, endpoints: Chunk.empty(), error: Schema.Never as any }) + +/** + * @since 1.0.0 + * @category endpoints + */ +export const add: { + ( + endpoint: A + ): ( + self: ApiGroup + ) => ApiGroup + < + Name extends string, + Endpoints extends ApiEndpoint.ApiEndpoint.Any, + Error, + ErrorR, + A extends ApiEndpoint.ApiEndpoint.Any + >( + self: ApiGroup, + endpoint: A + ): ApiGroup +} = dual(2, < + Name extends string, + Endpoints extends ApiEndpoint.ApiEndpoint.Any, + Error, + ErrorR, + A extends ApiEndpoint.ApiEndpoint.Any +>( + self: ApiGroup, + endpoint: A +): ApiGroup => + makeProto({ + ...self, + endpoints: Chunk.append(self.endpoints, endpoint) + })) + +/** + * @since 1.0.0 + * @category errors + */ +export const addError: { + ( + schema: Schema.Schema, + annotations?: { + readonly status?: number | undefined + } + ): ( + self: ApiGroup + ) => ApiGroup + ( + self: ApiGroup, + schema: Schema.Schema, + annotations?: { + readonly status?: number | undefined + } + ): ApiGroup +} = dual(2, ( + self: ApiGroup, + schema: Schema.Schema, + annotations?: { + readonly status?: number | undefined + } +): ApiGroup => + makeProto({ + ...self, + error: Schema.Union( + self.error, + schema.annotations({ + [ApiEndpoint.AnnotationStatus]: annotations?.status ?? + Option.getOrElse(AST.getAnnotation(schema.ast, ApiEndpoint.AnnotationStatus), () => 500) + }) + ) + })) + +/** + * @since 1.0.0 + * @category endpoints + */ +export const prefix: { + ( + prefix: PathInput + ): ( + self: ApiGroup + ) => ApiGroup + ( + self: ApiGroup, + prefix: PathInput + ): ApiGroup +} = dual(2, ( + self: ApiGroup, + prefix: PathInput +): ApiGroup => + makeProto({ + ...self, + endpoints: Chunk.map(self.endpoints, ApiEndpoint.prefix(prefix)) + })) diff --git a/packages/platform/src/HttpMethod.ts b/packages/platform/src/HttpMethod.ts index dc604b3840..d5b74a52ae 100644 --- a/packages/platform/src/HttpMethod.ts +++ b/packages/platform/src/HttpMethod.ts @@ -11,7 +11,25 @@ export type HttpMethod = | "HEAD" | "OPTIONS" +/** + * @since 1.0.0 + * @category models + */ +export declare namespace HttpMethod { + /** + * @since 1.0.0 + * @category models + */ + export type NoBody = "GET" | "HEAD" | "OPTIONS" + + /** + * @since 1.0.0 + * @category models + */ + export type WithBody = Exclude +} + /** * @since 1.0.0 */ -export const hasBody = (method: HttpMethod): boolean => method !== "GET" && method !== "HEAD" +export const hasBody = (method: HttpMethod): boolean => method !== "GET" && method !== "HEAD" && method !== "OPTIONS" diff --git a/packages/platform/src/HttpRouter.ts b/packages/platform/src/HttpRouter.ts index 5cf3ed621e..174833405a 100644 --- a/packages/platform/src/HttpRouter.ts +++ b/packages/platform/src/HttpRouter.ts @@ -357,6 +357,15 @@ export const makeRoute: ( options?: { readonly prefix?: string | undefined; readonly uninterruptible?: boolean | undefined } | undefined ) => Route> = internal.makeRoute +/** + * @since 1.0.0 + * @category utils + */ +export const prefixPath: { + (prefix: string): (self: string) => string + (self: string, prefix: string): string +} = internal.prefixPath + /** * @since 1.0.0 * @category combinators diff --git a/packages/platform/src/index.ts b/packages/platform/src/index.ts index 0e22f92082..62a2b3ac88 100644 --- a/packages/platform/src/index.ts +++ b/packages/platform/src/index.ts @@ -1,3 +1,23 @@ +/** + * @since 1.0.0 + */ +export * as Api from "./Api.js" + +/** + * @since 1.0.0 + */ +export * as ApiBuilder from "./ApiBuilder.js" + +/** + * @since 1.0.0 + */ +export * as ApiEndpoint from "./ApiEndpoint.js" + +/** + * @since 1.0.0 + */ +export * as ApiGroup from "./ApiGroup.js" + /** * @since 1.0.0 */ diff --git a/packages/platform/src/internal/httpRouter.ts b/packages/platform/src/internal/httpRouter.ts index 215052a864..dd8954bb32 100644 --- a/packages/platform/src/internal/httpRouter.ts +++ b/packages/platform/src/internal/httpRouter.ts @@ -399,6 +399,15 @@ const removeTrailingSlash = ( path: Router.PathInput ): Router.PathInput => (path.endsWith("/") ? path.slice(0, -1) : path) as any +/** @internal */ +export const prefixPath: { + (prefix: string): (self: string) => string + (self: string, prefix: string): string +} = dual(2, (self, prefix) => { + prefix = removeTrailingSlash(prefix) + return self === "/" ? prefix : prefix + self +}) + /** @internal */ export const prefixAll = dual< (prefix: Router.PathInput) => (self: Router.HttpRouter) => Router.HttpRouter, From ed8b427827dd58ba825f966e2f731ba2b6458c83 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 22 Aug 2024 20:15:32 +1200 Subject: [PATCH 02/59] errors --- packages/platform-node/examples/api.ts | 2 +- packages/platform/src/Api.ts | 37 +++-- packages/platform/src/ApiBuilder.ts | 178 ++++++++++++++++--------- packages/platform/src/ApiError.ts | 83 ++++++++++++ packages/platform/src/ApiGroup.ts | 47 ++++--- 5 files changed, 253 insertions(+), 94 deletions(-) create mode 100644 packages/platform/src/ApiError.ts diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index ba3d845501..04e935852f 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -32,7 +32,7 @@ const users = ApiGroup.make("users").pipe( ApiEndpoint.setError(Schema.String) ) ), - ApiGroup.addError(Unauthorized) + ApiGroup.addError(Unauthorized, { status: 401 }) ) const api = Api.make("My api").pipe( diff --git a/packages/platform/src/Api.ts b/packages/platform/src/Api.ts index b95ef17636..21370fbdc7 100644 --- a/packages/platform/src/Api.ts +++ b/packages/platform/src/Api.ts @@ -1,6 +1,7 @@ /** * @since 1.0.0 */ +import * as Schema from "@effect/schema/Schema" import * as Chunk from "effect/Chunk" import { dual } from "effect/Function" import type { Pipeable } from "effect/Pipeable" @@ -31,11 +32,16 @@ export const isApi = (u: unknown): u is Api => Predicate.hasProperty(u * @since 1.0.0 * @category models */ -export interface Api extends Pipeable { +export interface Api< + out Name extends string, + out Groups extends ApiGroup.ApiGroup.Any = never, + in out Error = never, + out ErrorR = never +> extends Pipeable { readonly [TypeId]: TypeId readonly name: Name readonly groups: Chunk.Chunk - // TODO: error schema + readonly errorSchema: Schema.Schema } /** @@ -57,13 +63,15 @@ const Proto = { } } -const makeProto = (options: { +const makeProto = (options: { readonly name: Name readonly groups: Chunk.Chunk + readonly errorSchema: Schema.Schema }): Api => { const self = Object.create(Proto) self.name = options.name self.groups = options.groups + self.errorSchema = options.errorSchema return self } @@ -71,7 +79,8 @@ const makeProto = (op * @since 1.0.0 * @category constructors */ -export const make = (name: Name): Api => makeProto({ name, groups: Chunk.empty() }) +export const make = (name: Name): Api => + makeProto({ name, groups: Chunk.empty(), errorSchema: Schema.Never as any }) /** * @since 1.0.0 @@ -80,20 +89,24 @@ export const make = (name: Name): Api => makeProto({ export const addGroup: { ( group: Group - ): (self: Api) => Api + ): ( + self: Api + ) => Api ( path: HttpRouter.PathInput, group: Group - ): (self: Api) => Api - ( - self: Api, + ): ( + self: Api + ) => Api + ( + self: Api, group: Group - ): Api - ( - self: Api, + ): Api + ( + self: Api, path: HttpRouter.PathInput, group: Group - ): Api + ): Api } = dual( (args) => isApi(args[0]), ( diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index b1199e592a..03f0aaee69 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -11,9 +11,10 @@ import type * as Layer from "effect/Layer" import * as Option from "effect/Option" import { type Pipeable, pipeArguments } from "effect/Pipeable" import type { ReadonlyRecord } from "effect/Record" -import type { Covariant } from "effect/Types" +import type { Covariant, NoInfer } from "effect/Types" import type * as Api from "./Api.js" import * as ApiEndpoint from "./ApiEndpoint.js" +import { ApiDecodeError } from "./ApiError.js" import type * as ApiGroup from "./ApiGroup.js" import type * as HttpApp from "./HttpApp.js" import * as HttpMethod from "./HttpMethod.js" @@ -22,6 +23,8 @@ import * as HttpServerRequest from "./HttpServerRequest.js" import * as HttpServerResponse from "./HttpServerResponse.js" /** + * The router that the API endpoints are attached to. + * * @since 1.0.0 * @category router */ @@ -32,20 +35,26 @@ export class ApiRouter extends HttpRouter.Tag("@effect/platform/ApiBuilder/ApiRo * @category constructors */ export const serve = ( - _self: Api.Api, + self: Api.Api, f: (httpApp: HttpApp.Default) => Layer.Layer ): Layer.Layer< A, E, R | ApiGroup.ApiGroup.ToService > => - ApiRouter.unwrap((router) => - router.pipe( - // TODO: Build global error encoder - Effect.catchAll(Effect.die), + ApiRouter.unwrap((router) => { + const errorSchema = makeErrorSchema(self as any) + const encodeError = Schema.encodeUnknown(errorSchema) + return router.pipe( + Effect.catchAll((error) => + Effect.matchEffect(encodeError(error), { + onFailure: () => Effect.die(error), + onSuccess: ([body, status]) => Effect.orDie(HttpServerResponse.json(body, { status })) + }) + ), f ) - ) + }) /** * @since 1.0.0 @@ -60,6 +69,8 @@ export const HandlersTypeId: unique symbol = Symbol.for("@effect/platform/ApiBui export type HandlersTypeId = typeof HandlersTypeId /** + * Represents a handled, or partially handled, `ApiGroup`. + * * @since 1.0.0 * @category handlers */ @@ -96,58 +107,6 @@ const makeHandlers = > -) => HttpMethod.hasBody(request.method) ? request.json : Effect.succeed(urlParams) - -const handlerToRoute = ( - endpoint: ApiEndpoint.ApiEndpoint.Any, - handler: ApiEndpoint.ApiEndpoint.Handler -): HttpRouter.Route => { - const decodePath = Option.map(endpoint.pathSchema, Schema.decodeUnknown) - const decodePayload = Option.map(endpoint.payloadSchema, Schema.decodeUnknown) - const encodeSuccess = Option.map(ApiEndpoint.successSchema(endpoint), Schema.encodeUnknown) - const successStatus = ApiEndpoint.successStatus(endpoint) - return HttpRouter.makeRoute( - endpoint.method, - endpoint.path, - Effect.withFiberRuntime((fiber) => { - const context = fiber.getFiberRef(FiberRef.currentContext) - const request = Context.unsafeGet(context, HttpServerRequest.HttpServerRequest) - const routeContext = Context.unsafeGet(context, HttpRouter.RouteContext) - const urlParams = Context.unsafeGet(context, HttpServerRequest.ParsedSearchParams) - return (decodePath._tag === "Some" - ? Effect.orDie(decodePath.value(routeContext.params)) - : Effect.succeed(routeContext.params)).pipe( - Effect.bindTo("pathParams"), - decodePayload._tag === "Some" - ? Effect.bind("payload", (_) => - requestPayload(request, urlParams).pipe( - Effect.flatMap(decodePayload.value), - Effect.orDie - )) - : identity, - Effect.flatMap((input) => { - const request: any = { path: input.pathParams } - if ("payload" in input) { - request.payload = input.payload - } - return handler(request) - }), - encodeSuccess._tag === "Some" - ? Effect.flatMap((body) => - encodeSuccess.value(body).pipe( - Effect.flatMap((json) => HttpServerResponse.json(json, { status: successStatus })), - Effect.orDie - ) - ) - : Effect.as(HttpServerResponse.empty({ status: successStatus })) - ) - }) - ) -} - /** * @since 1.0.0 * @category handlers @@ -155,18 +114,20 @@ const handlerToRoute = ( export const group = < ApiName extends string, Groups extends ApiGroup.ApiGroup.Any, + ApiError, + ApiErrorR, const Name extends Groups["name"], RH, EX = never, RX = never >( - api: Api.Api, + api: Api.Api, groupName: Name, build: ( handlers: Handlers> ) => - | Handlers, RH> - | Effect.Effect, RH>, EX, RX> + | Handlers | ApiGroup.ApiGroup.ErrorWithName, RH> + | Effect.Effect | ApiGroup.ApiGroup.ErrorWithName, RH>, EX, RX> ): Layer.Layer, EX, RX> => ApiRouter.use((router) => Effect.gen(function*() { @@ -195,7 +156,7 @@ export const handle = ( self: Handlers ): Handlers< - EG | Exclude>, + EG | Exclude> | ApiDecodeError, RG | ApiEndpoint.ApiEndpoint.ExcludeProvided, ApiEndpoint.ApiEndpoint.ExcludeName > => { @@ -209,3 +170,94 @@ export const handle = > +) => HttpMethod.hasBody(request.method) ? request.json : Effect.succeed(urlParams) + +const handlerToRoute = ( + endpoint: ApiEndpoint.ApiEndpoint.Any, + handler: ApiEndpoint.ApiEndpoint.Handler +): HttpRouter.Route => { + const decodePath = Option.map(endpoint.pathSchema, Schema.decodeUnknown) + const decodePayload = Option.map(endpoint.payloadSchema, Schema.decodeUnknown) + const encodeSuccess = Option.map(ApiEndpoint.successSchema(endpoint), Schema.encodeUnknown) + const successStatus = ApiEndpoint.successStatus(endpoint) + return HttpRouter.makeRoute( + endpoint.method, + endpoint.path, + Effect.withFiberRuntime((fiber) => { + const context = fiber.getFiberRef(FiberRef.currentContext) + const request = Context.unsafeGet(context, HttpServerRequest.HttpServerRequest) + const routeContext = Context.unsafeGet(context, HttpRouter.RouteContext) + const urlParams = Context.unsafeGet(context, HttpServerRequest.ParsedSearchParams) + return (decodePath._tag === "Some" + ? Effect.catchAll(decodePath.value(routeContext.params), ApiDecodeError.refailParseError) + : Effect.succeed(routeContext.params)).pipe( + Effect.bindTo("pathParams"), + decodePayload._tag === "Some" + ? Effect.bind("payload", (_) => + requestPayload(request, urlParams).pipe( + Effect.orDie, + Effect.flatMap((raw) => Effect.catchAll(decodePayload.value(raw), ApiDecodeError.refailParseError)) + )) + : identity, + Effect.flatMap((input) => { + const request: any = { path: input.pathParams } + if ("payload" in input) { + request.payload = input.payload + } + return handler(request) + }), + encodeSuccess._tag === "Some" + ? Effect.flatMap((body) => + encodeSuccess.value(body).pipe( + Effect.flatMap((json) => HttpServerResponse.json(json, { status: successStatus })), + Effect.orDie + ) + ) + : Effect.as(HttpServerResponse.empty({ status: successStatus })) + ) + }) + ) +} + +const makeErrorSchema = ( + api: Api.Api, any, any> +): Schema.Schema => { + const schemas = new Set([ApiDecodeError]) + for (const group of api.groups) { + for (const endpoint of group.endpoints) { + schemas.add(endpoint.errorSchema) + } + const groupAst = group.error.ast + if (groupAst._tag === "Union") { + for (const ast of groupAst.types) { + schemas.add( + Schema.make(ast).annotations({ + ...groupAst.annotations, + ...ast.annotations + }) + ) + } + } else { + schemas.add(group.error) + } + } + return Schema.Union(...[...schemas].map((schema) => { + const annotations = schema.ast._tag === "Transformation" ? + { + ...schema.ast.to.annotations, + ...schema.ast.annotations + } : + schema.ast.annotations + const status = annotations[ApiEndpoint.AnnotationStatus] ?? 500 + return Schema.transform(Schema.Any, schema, { + decode: identity, + encode: (error) => [error, status] + }) + })) as any +} diff --git a/packages/platform/src/ApiError.ts b/packages/platform/src/ApiError.ts new file mode 100644 index 0000000000..e1b6208e6d --- /dev/null +++ b/packages/platform/src/ApiError.ts @@ -0,0 +1,83 @@ +/** + * @since 1.0.0 + */ +import * as ArrayFormatter from "@effect/schema/ArrayFormatter" +import type * as ParseResult from "@effect/schema/ParseResult" +import * as Schema from "@effect/schema/Schema" +import * as TreeFormatter from "@effect/schema/TreeFormatter" +import * as Effect from "effect/Effect" +import { AnnotationStatus } from "./ApiEndpoint.js" + +/** + * @since 1.0.0 + * @category type ids + */ +export const TypeId: unique symbol = Symbol.for("@effect/platform/ApiError") + +/** + * @since 1.0.0 + * @category type ids + */ +export type TypeId = typeof TypeId + +/** + * @since 1.0.0 + * @category schemas + */ +export interface Issue extends + Schema.Struct< + { + _tag: Schema.Literal< + ["Pointer", "Unexpected", "Missing", "Composite", "Refinement", "Transformation", "Type", "Forbidden"] + > + path: Schema.Array$> + message: typeof Schema.String + } + > +{} + +/** + * @since 1.0.0 + * @category schemas + */ +export const Issue: Issue = Schema.Struct({ + _tag: Schema.Literal( + "Pointer", + "Unexpected", + "Missing", + "Composite", + "Refinement", + "Transformation", + "Type", + "Forbidden" + ), + path: Schema.Array(Schema.Union(Schema.Symbol, Schema.String, Schema.Number)), + message: Schema.String +}) + +/** + * @since 1.0.0 + * @category errors + */ +export class ApiDecodeError extends Schema.TaggedError()("ApiDecodeError", { + issues: Schema.Array(Issue), + message: Schema.String +}, { + [AnnotationStatus]: 400 +}) { + /** + * @since 1.0.0 + */ + static fromParseError(error: ParseResult.ParseError): Effect.Effect { + return ArrayFormatter.formatError(error).pipe( + Effect.zip(TreeFormatter.formatError(error)), + Effect.map(([issues, message]) => new ApiDecodeError({ issues, message })) + ) + } + /** + * @since 1.0.0 + */ + static refailParseError(error: ParseResult.ParseError): Effect.Effect { + return Effect.flatMap(ApiDecodeError.fromParseError(error), Effect.fail) + } +} diff --git a/packages/platform/src/ApiGroup.ts b/packages/platform/src/ApiGroup.ts index f9ea95c8a7..b392e90a90 100644 --- a/packages/platform/src/ApiGroup.ts +++ b/packages/platform/src/ApiGroup.ts @@ -7,7 +7,9 @@ import * as Chunk from "effect/Chunk" import { dual } from "effect/Function" import * as Option from "effect/Option" import { type Pipeable, pipeArguments } from "effect/Pipeable" +import * as Predicate from "effect/Predicate" import * as ApiEndpoint from "./ApiEndpoint.js" +import type { ApiDecodeError } from "./ApiError.js" import type { PathInput } from "./HttpRouter.js" /** @@ -22,6 +24,12 @@ export const TypeId: unique symbol = Symbol.for("@effect/platform/ApiGroup") */ export type TypeId = typeof TypeId +/** + * @since 1.0.0 + * @category guards + */ +export const isApiGroup = (u: unknown): u is ApiGroup.Any => Predicate.hasProperty(u, TypeId) + /** * @since 1.0.0 * @category models @@ -29,7 +37,7 @@ export type TypeId = typeof TypeId export interface ApiGroup< out Name extends string, out Endpoints extends ApiEndpoint.ApiEndpoint.Any = never, - in out Error = never, + in out Error = ApiDecodeError, out ErrorR = never > extends Pipeable { readonly [TypeId]: TypeId @@ -195,23 +203,26 @@ export const addError: { readonly status?: number | undefined } ): ApiGroup -} = dual(2, ( - self: ApiGroup, - schema: Schema.Schema, - annotations?: { - readonly status?: number | undefined - } -): ApiGroup => - makeProto({ - ...self, - error: Schema.Union( - self.error, - schema.annotations({ - [ApiEndpoint.AnnotationStatus]: annotations?.status ?? - Option.getOrElse(AST.getAnnotation(schema.ast, ApiEndpoint.AnnotationStatus), () => 500) - }) - ) - })) +} = dual( + (args) => isApiGroup(args[0]), + ( + self: ApiGroup, + schema: Schema.Schema, + annotations?: { + readonly status?: number | undefined + } + ): ApiGroup => + makeProto({ + ...self, + error: Schema.Union( + self.error, + schema.annotations({ + [ApiEndpoint.AnnotationStatus]: annotations?.status ?? + Option.getOrElse(AST.getAnnotation(schema.ast, ApiEndpoint.AnnotationStatus), () => 500) + }) + ) + }) +) /** * @since 1.0.0 From 919bb4ddeaa1465c86e02363f2a10d675ddd5fa1 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 22 Aug 2024 21:54:17 +1200 Subject: [PATCH 03/59] run codegen --- packages/platform/src/index.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/platform/src/index.ts b/packages/platform/src/index.ts index 62a2b3ac88..63a3718ea2 100644 --- a/packages/platform/src/index.ts +++ b/packages/platform/src/index.ts @@ -13,6 +13,11 @@ export * as ApiBuilder from "./ApiBuilder.js" */ export * as ApiEndpoint from "./ApiEndpoint.js" +/** + * @since 1.0.0 + */ +export * as ApiError from "./ApiError.js" + /** * @since 1.0.0 */ From 2d7bf1efae2d56aff8992b82f85074c851c81156 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 22 Aug 2024 22:52:09 +1200 Subject: [PATCH 04/59] middleware --- packages/platform-node/examples/api.ts | 16 +++-- packages/platform/src/ApiBuilder.ts | 86 ++++++++++++++++++++++---- packages/platform/src/ApiEndpoint.ts | 2 +- 3 files changed, 88 insertions(+), 16 deletions(-) diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index 04e935852f..0fc1464823 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -1,7 +1,7 @@ import { Api, ApiBuilder, ApiEndpoint, ApiGroup, HttpMiddleware, HttpServer } from "@effect/platform" import { NodeHttpServer, NodeRuntime } from "@effect/platform-node" import { Schema } from "@effect/schema" -import { Effect, Layer } from "effect" +import { Context, Effect, Layer } from "effect" import { createServer } from "node:http" class User extends Schema.Class("User")({ @@ -28,8 +28,12 @@ const users = ApiGroup.make("users").pipe( ApiEndpoint.setPayload(Schema.Struct({ name: Schema.String })), - ApiEndpoint.setSuccess(User), - ApiEndpoint.setError(Schema.String) + ApiEndpoint.setSuccess(User) + ) + ), + ApiGroup.add( + ApiEndpoint.get("me", "/me").pipe( + ApiEndpoint.setSuccess(User) ) ), ApiGroup.addError(Unauthorized, { status: 401 }) @@ -39,6 +43,8 @@ const api = Api.make("My api").pipe( Api.addGroup("/users", users) ) +class CurrentUser extends Context.Tag("CurrentUser")() {} + const UsersLive = ApiBuilder.group(api, "users", (handlers) => handlers.pipe( ApiBuilder.handle("create", (_) => @@ -54,7 +60,9 @@ const UsersLive = ApiBuilder.group(api, "users", (handlers) => id: _.path.id, name: "John" }) - )) + )), + ApiBuilder.handle("me", (_) => CurrentUser), + ApiBuilder.middleware(Effect.provideService(CurrentUser, new User({ id: 1000, name: "Provided" }))) )) ApiBuilder.serve(api, HttpServer.serve(HttpMiddleware.logger)).pipe( diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index 03f0aaee69..2c7624b1db 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -11,7 +11,7 @@ import type * as Layer from "effect/Layer" import * as Option from "effect/Option" import { type Pipeable, pipeArguments } from "effect/Pipeable" import type { ReadonlyRecord } from "effect/Record" -import type { Covariant, NoInfer } from "effect/Types" +import type { Covariant, Mutable, NoInfer } from "effect/Types" import type * as Api from "./Api.js" import * as ApiEndpoint from "./ApiEndpoint.js" import { ApiDecodeError } from "./ApiError.js" @@ -83,7 +83,32 @@ export interface Handlers< _Endpoints: Covariant } readonly group: ApiGroup.ApiGroup - readonly handlers: Chunk.Chunk<[ApiEndpoint.ApiEndpoint.Any, ApiEndpoint.ApiEndpoint.Handler]> + readonly handlers: Chunk.Chunk> +} + +/** + * @since 1.0.0 + * @category handlers + */ +export declare namespace Handlers { + /** + * @since 1.0.0 + * @category handlers + */ + export type Middleware = (self: HttpRouter.Route.Middleware) => HttpApp.Default + + /** + * @since 1.0.0 + * @category handlers + */ + export type Item = { + readonly _tag: "Handler" + readonly endpoint: ApiEndpoint.ApiEndpoint.Any + readonly handler: ApiEndpoint.ApiEndpoint.Handler + } | { + readonly _tag: "Middleware" + readonly middleware: Middleware + } } const HandlersProto = { @@ -98,7 +123,10 @@ const HandlersProto = { const makeHandlers = ( options: { readonly group: ApiGroup.ApiGroup - readonly handlers: Chunk.Chunk<[ApiEndpoint.ApiEndpoint.Any, ApiEndpoint.ApiEndpoint.Handler]> + readonly handlers: Chunk.Chunk< + | [ApiEndpoint.ApiEndpoint.Any, ApiEndpoint.ApiEndpoint.Handler] + | HttpRouter.Route.Middleware + > } ): Handlers => { const self = Object.create(HandlersProto) @@ -128,22 +156,37 @@ export const group = < ) => | Handlers | ApiGroup.ApiGroup.ErrorWithName, RH> | Effect.Effect | ApiGroup.ApiGroup.ErrorWithName, RH>, EX, RX> -): Layer.Layer, EX, RX> => +): Layer.Layer, EX, RX | RH | ApiGroup.ApiGroup.ContextWithName> => ApiRouter.use((router) => Effect.gen(function*() { + const context = yield* Effect.context() const group = Chunk.findFirst(api.groups, (group) => group.name === groupName) if (group._tag === "None") { throw new Error(`Group "${groupName}" not found in API "${api.name}"`) } const result = build(makeHandlers({ group: group.value as any, handlers: Chunk.empty() })) const handlers = Effect.isEffect(result) ? (yield* result) : result - yield* router.concat( - HttpRouter.fromIterable( - Chunk.map(handlers.handlers, ([endpoint, handler]) => handlerToRoute(endpoint, handler)) - ) - ) + const routes: Array> = [] + for (const item of handlers.handlers) { + if (item._tag === "Middleware") { + for (const route of routes) { + ;(route as Mutable>).handler = item.middleware(route.handler as any) + } + } else { + routes.push(handlerToRoute( + item.endpoint, + function(request) { + return Effect.mapInputContext( + item.handler(request), + (input) => Context.merge(context, input) + ) + } + )) + } + } + yield* router.concat(HttpRouter.fromIterable(routes)) }) - ) as Layer.Layer, EX, RX> + ) as any /** * @since 1.0.0 @@ -167,10 +210,31 @@ export const handle = (middleware: Handlers.Middleware) => + ( + self: Handlers + ): Handlers, Endpoints> => + makeHandlers({ + ...self, + handlers: Chunk.append(self.handlers, { + _tag: "Middleware", + middleware + }) as any + }) as any + // internal const requestPayload = ( diff --git a/packages/platform/src/ApiEndpoint.ts b/packages/platform/src/ApiEndpoint.ts index 1b640e18b2..9c6edf8ef8 100644 --- a/packages/platform/src/ApiEndpoint.ts +++ b/packages/platform/src/ApiEndpoint.ts @@ -181,7 +181,7 @@ export declare namespace ApiEndpoint { */ export type ExcludeProvided = Exclude< R, - HttpRouter.HttpRouter.DefaultServices | HttpRouter.HttpRouter.DefaultServices + HttpRouter.HttpRouter.DefaultServices | HttpRouter.HttpRouter.Provided > /** From 072f2890b0ac59455fd75fae462d323f29183750 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 22 Aug 2024 22:56:20 +1200 Subject: [PATCH 05/59] fix makeHandlers --- packages/platform/src/ApiBuilder.ts | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index 2c7624b1db..a038aae4b5 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -120,13 +120,10 @@ const HandlersProto = { } } -const makeHandlers = ( +const makeHandlers = ( options: { - readonly group: ApiGroup.ApiGroup - readonly handlers: Chunk.Chunk< - | [ApiEndpoint.ApiEndpoint.Any, ApiEndpoint.ApiEndpoint.Handler] - | HttpRouter.Route.Middleware - > + readonly group: ApiGroup.ApiGroup + readonly handlers: Chunk.Chunk> } ): Handlers => { const self = Object.create(HandlersProto) @@ -215,7 +212,7 @@ export const handle = ( self: Handlers ): Handlers, Endpoints> => - makeHandlers({ - ...self, + makeHandlers, Endpoints>({ + ...self as any, handlers: Chunk.append(self.handlers, { _tag: "Middleware", middleware - }) as any - }) as any + }) + }) // internal From ca5c476e394ca4893ae14e37c4e3f1cbb66c46c8 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 22 Aug 2024 23:47:04 +1200 Subject: [PATCH 06/59] fix error status codes --- packages/platform/src/ApiBuilder.ts | 8 +------- packages/platform/src/ApiEndpoint.ts | 25 ++++++++++++++++++------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index a038aae4b5..eddbc16bb2 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -309,13 +309,7 @@ const makeErrorSchema = ( } } return Schema.Union(...[...schemas].map((schema) => { - const annotations = schema.ast._tag === "Transformation" ? - { - ...schema.ast.to.annotations, - ...schema.ast.annotations - } : - schema.ast.annotations - const status = annotations[ApiEndpoint.AnnotationStatus] ?? 500 + const status = ApiEndpoint.getAnnotationStatus(schema.ast, 500) return Schema.transform(Schema.Any, schema, { decode: identity, encode: (error) => [error, status] diff --git a/packages/platform/src/ApiEndpoint.ts b/packages/platform/src/ApiEndpoint.ts index 9c6edf8ef8..12a9c9e577 100644 --- a/packages/platform/src/ApiEndpoint.ts +++ b/packages/platform/src/ApiEndpoint.ts @@ -1,7 +1,7 @@ /** * @since 1.0.0 */ -import * as AST from "@effect/schema/AST" +import type * as AST from "@effect/schema/AST" import * as Schema from "@effect/schema/Schema" import type { Effect } from "effect/Effect" import { dual } from "effect/Function" @@ -318,6 +318,20 @@ export const del: ( */ export const AnnotationStatus: unique symbol = Symbol.for("@effect/platform/ApiEndpoint/AnnotationStatus") +/** + * @since 1.0.0 + * @category annotations + */ +export const getAnnotationStatus = (ast: AST.AST, defaultStatus: number): number => { + const annotations = ast._tag === "Transformation" ? + { + ...ast.to.annotations, + ...ast.annotations + } : + ast.annotations + return annotations[AnnotationStatus] as number ?? defaultStatus +} + type Void$ = typeof Schema.Void /** @@ -423,8 +437,7 @@ export const setSuccess: { makeProto({ ...self, successSchema: schema.annotations({ - [AnnotationStatus]: annotations?.status ?? - Option.getOrElse(AST.getAnnotation(schema.ast, AnnotationStatus), () => 200) + [AnnotationStatus]: annotations?.status ?? getAnnotationStatus(schema.ast, 200) }) as S }) ) @@ -485,8 +498,7 @@ export const setError: { ...self, errorSchema: schema.pipe( Schema.annotations({ - [AnnotationStatus]: annotations?.status ?? - Option.getOrElse(AST.getAnnotation(schema.ast, AnnotationStatus), () => 500) + [AnnotationStatus]: annotations?.status ?? getAnnotationStatus(schema.ast, 500) }) ) as E }) @@ -607,10 +619,9 @@ export const prefix: { * @category reflection */ export const successStatus = (self: A): number => { - const status = AST.getAnnotation(self.successSchema.ast, AnnotationStatus) const ast = Schema.encodedSchema(self.successSchema).ast const isVoid = ast._tag === "VoidKeyword" - return Option.getOrElse(status, () => isVoid ? 204 : 200) + return getAnnotationStatus(self.successSchema.ast, isVoid ? 204 : 200) } /** From c0361f871a6eae1dd697cbaf2d0e6669464300e7 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 23 Aug 2024 10:52:12 +1200 Subject: [PATCH 07/59] wip --- packages/platform-node/examples/api.ts | 17 ++- packages/platform/src/Api.ts | 87 +++++++---- packages/platform/src/ApiBuilder.ts | 197 +++++++++++++++++++++---- packages/platform/src/ApiEndpoint.ts | 92 ++++-------- packages/platform/src/ApiError.ts | 6 +- packages/platform/src/ApiGroup.ts | 28 ++-- packages/platform/src/ApiSchema.ts | 58 ++++++++ packages/platform/src/index.ts | 5 + 8 files changed, 335 insertions(+), 155 deletions(-) create mode 100644 packages/platform/src/ApiSchema.ts diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index 0fc1464823..cfe20c1366 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -16,24 +16,24 @@ class Unauthorized extends Schema.TaggedError()("Unauthorized", { const users = ApiGroup.make("users").pipe( ApiGroup.add( ApiEndpoint.get("findById", "/:id").pipe( - ApiEndpoint.setPathSchema(Schema.Struct({ + ApiEndpoint.path(Schema.Struct({ id: Schema.NumberFromString })), - ApiEndpoint.setSuccess(User), - ApiEndpoint.setError(Schema.String) + ApiEndpoint.success(User), + ApiEndpoint.error(Schema.String) ) ), ApiGroup.add( ApiEndpoint.post("create", "/").pipe( - ApiEndpoint.setPayload(Schema.Struct({ + ApiEndpoint.payload(Schema.Struct({ name: Schema.String })), - ApiEndpoint.setSuccess(User) + ApiEndpoint.success(User) ) ), ApiGroup.add( ApiEndpoint.get("me", "/me").pipe( - ApiEndpoint.setSuccess(User) + ApiEndpoint.success(User) ) ), ApiGroup.addError(Unauthorized, { status: 401 }) @@ -65,9 +65,10 @@ const UsersLive = ApiBuilder.group(api, "users", (handlers) => ApiBuilder.middleware(Effect.provideService(CurrentUser, new User({ id: 1000, name: "Provided" }))) )) -ApiBuilder.serve(api, HttpServer.serve(HttpMiddleware.logger)).pipe( - Layer.provide(UsersLive), +ApiBuilder.serve(api, HttpMiddleware.logger).pipe( HttpServer.withLogAddress, + Layer.provide(UsersLive), + Layer.provide(ApiBuilder.middlewareCors()), Layer.provide(NodeHttpServer.layer(createServer, { port: 3000 })), Layer.launch, NodeRuntime.runMain diff --git a/packages/platform/src/Api.ts b/packages/platform/src/Api.ts index 21370fbdc7..7416d539ee 100644 --- a/packages/platform/src/Api.ts +++ b/packages/platform/src/Api.ts @@ -8,6 +8,7 @@ import type { Pipeable } from "effect/Pipeable" import { pipeArguments } from "effect/Pipeable" import * as Predicate from "effect/Predicate" import * as ApiGroup from "./ApiGroup.js" +import * as ApiSchema from "./ApiSchema.js" import type * as HttpRouter from "./HttpRouter.js" /** @@ -33,13 +34,11 @@ export const isApi = (u: unknown): u is Api => Predicate.hasProperty(u * @category models */ export interface Api< - out Name extends string, out Groups extends ApiGroup.ApiGroup.Any = never, in out Error = never, out ErrorR = never > extends Pipeable { readonly [TypeId]: TypeId - readonly name: Name readonly groups: Chunk.Chunk readonly errorSchema: Schema.Schema } @@ -53,7 +52,7 @@ export declare namespace Api { * @since 1.0.0 * @category models */ - export type Any = Api | Api + export type Any = Api | Api | Api } const Proto = { @@ -63,24 +62,17 @@ const Proto = { } } -const makeProto = (options: { - readonly name: Name +const makeProto = (options: { readonly groups: Chunk.Chunk readonly errorSchema: Schema.Schema -}): Api => { - const self = Object.create(Proto) - self.name = options.name - self.groups = options.groups - self.errorSchema = options.errorSchema - return self -} +}): Api => Object.assign(Object.create(Proto), options) /** * @since 1.0.0 * @category constructors */ -export const make = (name: Name): Api => - makeProto({ name, groups: Chunk.empty(), errorSchema: Schema.Never as any }) +export const make = (_annotations?: {} | undefined): Api => + makeProto({ groups: Chunk.empty(), errorSchema: Schema.Never as any }) /** * @since 1.0.0 @@ -89,34 +81,73 @@ export const make = (name: Name): Api => export const addGroup: { ( group: Group - ): ( - self: Api - ) => Api + ): ( + self: Api + ) => Api ( path: HttpRouter.PathInput, group: Group - ): ( - self: Api - ) => Api - ( - self: Api, + ): ( + self: Api + ) => Api + ( + self: Api, group: Group - ): Api - ( - self: Api, + ): Api + ( + self: Api, path: HttpRouter.PathInput, group: Group - ): Api + ): Api } = dual( (args) => isApi(args[0]), ( self: Api.Any, ...args: [group: ApiGroup.ApiGroup.Any] | [path: HttpRouter.PathInput, group: ApiGroup.ApiGroup.Any] - ) => { + ): Api.Any => { const group = args.length === 1 ? args[0] : ApiGroup.prefix(args[1] as any, args[0]) return makeProto({ - ...self, + ...self as any, groups: Chunk.append(self.groups, group) }) } ) +/** + * @since 1.0.0 + * @category errors + */ +export const addError: { + ( + schema: Schema.Schema, + annotations?: { + readonly status?: number | undefined + } + ): ( + self: Api + ) => Api + ( + self: Api, + schema: Schema.Schema, + annotations?: { + readonly status?: number | undefined + } + ): Api +} = dual( + (args) => isApi(args[0]), + ( + self: Api, + schema: Schema.Schema, + annotations?: { + readonly status?: number | undefined + } + ): Api => + makeProto({ + ...self, + errorSchema: Schema.Union( + self.errorSchema, + schema.annotations(ApiSchema.annotations({ + status: annotations?.status ?? ApiSchema.getStatusError(schema) + })) + ) + }) +) diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index eddbc16bb2..7e9b6ce389 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -1,24 +1,30 @@ /** * @since 1.0.0 */ +import type * as AST from "@effect/schema/AST" import * as Schema from "@effect/schema/Schema" import * as Chunk from "effect/Chunk" import * as Context from "effect/Context" import * as Effect from "effect/Effect" import * as FiberRef from "effect/FiberRef" import { identity } from "effect/Function" -import type * as Layer from "effect/Layer" +import { globalValue } from "effect/GlobalValue" +import * as Layer from "effect/Layer" import * as Option from "effect/Option" import { type Pipeable, pipeArguments } from "effect/Pipeable" import type { ReadonlyRecord } from "effect/Record" +import type { Scope } from "effect/Scope" import type { Covariant, Mutable, NoInfer } from "effect/Types" import type * as Api from "./Api.js" import * as ApiEndpoint from "./ApiEndpoint.js" import { ApiDecodeError } from "./ApiError.js" import type * as ApiGroup from "./ApiGroup.js" +import * as ApiSchema from "./ApiSchema.js" import type * as HttpApp from "./HttpApp.js" import * as HttpMethod from "./HttpMethod.js" +import * as HttpMiddleware from "./HttpMiddleware.js" import * as HttpRouter from "./HttpRouter.js" +import * as HttpServer from "./HttpServer.js" import * as HttpServerRequest from "./HttpServerRequest.js" import * as HttpServerResponse from "./HttpServerResponse.js" @@ -34,27 +40,42 @@ export class ApiRouter extends HttpRouter.Tag("@effect/platform/ApiBuilder/ApiRo * @since 1.0.0 * @category constructors */ -export const serve = ( - self: Api.Api, - f: (httpApp: HttpApp.Default) => Layer.Layer +export const serve: { + ( + self: Api.Api + ): Layer.Layer> + ( + self: Api.Api, + middleware: (httpApp: HttpApp.Default) => HttpApp.Default + ): Layer.Layer< + never, + never, + Exclude | ApiGroup.ApiGroup.ToService + > +} = ( + self: Api.Api.Any, + middleware?: HttpMiddleware.HttpMiddleware.Applied ): Layer.Layer< - A, - E, - R | ApiGroup.ApiGroup.ToService + never, + never, + any > => - ApiRouter.unwrap((router) => { + Layer.unwrapEffect(Effect.gen(function*() { + const router = yield* ApiRouter.router + const apiMiddleware = yield* Effect.serviceOption(ApiMiddleware) const errorSchema = makeErrorSchema(self as any) const encodeError = Schema.encodeUnknown(errorSchema) return router.pipe( + apiMiddleware._tag === "Some" ? apiMiddleware.value : identity, Effect.catchAll((error) => Effect.matchEffect(encodeError(error), { onFailure: () => Effect.die(error), onSuccess: ([body, status]) => Effect.orDie(HttpServerResponse.json(body, { status })) }) ), - f + HttpServer.serve(middleware as HttpMiddleware.HttpMiddleware) ) - }) + })).pipe(Layer.provide(ApiRouter.Live)) /** * @since 1.0.0 @@ -137,7 +158,6 @@ const makeHandlers = ( * @category handlers */ export const group = < - ApiName extends string, Groups extends ApiGroup.ApiGroup.Any, ApiError, ApiErrorR, @@ -146,7 +166,7 @@ export const group = < EX = never, RX = never >( - api: Api.Api, + api: Api.Api, groupName: Name, build: ( handlers: Handlers> @@ -159,7 +179,7 @@ export const group = < const context = yield* Effect.context() const group = Chunk.findFirst(api.groups, (group) => group.name === groupName) if (group._tag === "None") { - throw new Error(`Group "${groupName}" not found in API "${api.name}"`) + throw new Error(`Group "${groupName}" not found in API`) } const result = build(makeHandlers({ group: group.value as any, handlers: Chunk.empty() })) const handlers = Effect.isEffect(result) ? (yield* result) : result @@ -216,6 +236,10 @@ export const handle = () +{ +} + +const middlewareAdd = (middleware: HttpMiddleware.HttpMiddleware): Effect.Effect => + Effect.map( + Effect.serviceOption(ApiMiddleware), + Option.match({ + onNone: () => middleware, + onSome: (current) => (httpApp) => middleware(current(httpApp)) + }) + ) + +/** + * Create an `Api` level middleware `Layer`. + * + * @since 1.0.0 + * @category middleware + */ +export const middlewareMake = ( + _api: Api.Api, + middleware: ApiMiddleware.Fn, R> | Effect.Effect, R>, EX, RX> +): Layer.Layer | RX> => + Effect.isEffect(middleware) + ? Layer.effect(ApiMiddleware, Effect.flatMap(middleware as any, middlewareAdd)) + : Layer.effect(ApiMiddleware, middlewareAdd(middleware as any)) + +/** + * Create an `Api` level middleware `Layer`, that has a `Scope` provided to + * the constructor. + * + * @since 1.0.0 + * @category middleware + */ +export const middlewareMakeScoped = ( + _api: Api.Api, + middleware: ApiMiddleware.Fn, R> | Effect.Effect, R>, EX, RX> +): Layer.Layer | Exclude> => + Effect.isEffect(middleware) + ? Layer.scoped(ApiMiddleware, Effect.flatMap(middleware as any, middlewareAdd)) + : Layer.effect(ApiMiddleware, middlewareAdd(middleware as any)) + +/** + * Create an `Api` level middleware `Layer`, that can't fail. + * + * @since 1.0.0 + * @category middleware + */ +export const middlewareMakeNoError = ( + middleware: ApiMiddleware.Fn | Effect.Effect, EX, RX> +): Layer.Layer | RX> => + Effect.isEffect(middleware) + ? Layer.effect(ApiMiddleware, Effect.flatMap(middleware as any, middlewareAdd)) + : Layer.effect(ApiMiddleware, middlewareAdd(middleware as any)) + +/** + * Create an `Api` level middleware `Layer`, that can't fail. + * It has a `Scope` provided to the constructor. + * + * @since 1.0.0 + * @category middleware + */ +export const middlewareMakeNoErrorScoped = ( + middleware: ApiMiddleware.Fn | Effect.Effect, EX, RX> +): Layer.Layer | RX> => + Effect.isEffect(middleware) + ? Layer.scoped(ApiMiddleware, Effect.flatMap(middleware as any, middlewareAdd)) + : Layer.effect(ApiMiddleware, middlewareAdd(middleware as any)) + +/** + * A CORS middleware layer. + * + * @since 1.0.0 + * @category middleware + */ +export const middlewareCors = ( + options?: { + readonly allowedOrigins?: ReadonlyArray | undefined + readonly allowedMethods?: ReadonlyArray | undefined + readonly allowedHeaders?: ReadonlyArray | undefined + readonly exposedHeaders?: ReadonlyArray | undefined + readonly maxAge?: number | undefined + readonly credentials?: boolean | undefined + } | undefined +): Layer.Layer => middlewareMakeNoError(HttpMiddleware.cors(options) as any) + +/** + * @since 1.0.0 + * @category middleware + */ +export declare namespace ApiMiddleware { + /** + * @since 1.0.0 + * @category middleware + */ + export type Fn = (httpApp: HttpApp.Default) => HttpApp.Default +} + // internal const requestPayload = ( @@ -245,8 +372,8 @@ const handlerToRoute = ( ): HttpRouter.Route => { const decodePath = Option.map(endpoint.pathSchema, Schema.decodeUnknown) const decodePayload = Option.map(endpoint.payloadSchema, Schema.decodeUnknown) - const encodeSuccess = Option.map(ApiEndpoint.successSchema(endpoint), Schema.encodeUnknown) - const successStatus = ApiEndpoint.successStatus(endpoint) + const encodeSuccess = Option.map(ApiEndpoint.schemaSuccess(endpoint), Schema.encodeUnknown) + const successStatus = ApiSchema.getStatusSuccess(endpoint.successSchema) return HttpRouter.makeRoute( endpoint.method, endpoint.path, @@ -286,30 +413,40 @@ const handlerToRoute = ( ) } +const astCache = globalValue("@effect/platform/ApiBuilder", () => new WeakMap()) + const makeErrorSchema = ( - api: Api.Api, any, any> + api: Api.Api, any, any> ): Schema.Schema => { const schemas = new Set([ApiDecodeError]) - for (const group of api.groups) { - for (const endpoint of group.endpoints) { - schemas.add(endpoint.errorSchema) + function processSchema(schema: Schema.Schema.Any): void { + if (astCache.has(schema.ast)) { + schemas.add(astCache.get(schema.ast)!) + return } - const groupAst = group.error.ast - if (groupAst._tag === "Union") { - for (const ast of groupAst.types) { - schemas.add( - Schema.make(ast).annotations({ - ...groupAst.annotations, - ...ast.annotations - }) - ) + const ast = schema.ast + if (ast._tag === "Union") { + for (const astType of ast.types) { + const errorSchema = Schema.make(astType).annotations({ + ...ast.annotations, + ...astType.annotations + }) + astCache.set(astType, errorSchema) + schemas.add(errorSchema) } } else { - schemas.add(group.error) + astCache.set(ast, schema) + schemas.add(schema) + } + } + for (const group of api.groups) { + for (const endpoint of group.endpoints) { + processSchema(endpoint.errorSchema) } + processSchema(group.errorSchema) } return Schema.Union(...[...schemas].map((schema) => { - const status = ApiEndpoint.getAnnotationStatus(schema.ast, 500) + const status = ApiSchema.getStatusError(schema) return Schema.transform(Schema.Any, schema, { decode: identity, encode: (error) => [error, status] diff --git a/packages/platform/src/ApiEndpoint.ts b/packages/platform/src/ApiEndpoint.ts index 12a9c9e577..3871752a59 100644 --- a/packages/platform/src/ApiEndpoint.ts +++ b/packages/platform/src/ApiEndpoint.ts @@ -1,7 +1,6 @@ /** * @since 1.0.0 */ -import type * as AST from "@effect/schema/AST" import * as Schema from "@effect/schema/Schema" import type { Effect } from "effect/Effect" import { dual } from "effect/Function" @@ -9,6 +8,7 @@ import * as Option from "effect/Option" import { type Pipeable, pipeArguments } from "effect/Pipeable" import * as Predicate from "effect/Predicate" import type * as Types from "effect/Types" +import * as ApiSchema from "./ApiSchema.js" import type { HttpMethod } from "./HttpMethod.js" import * as HttpRouter from "./HttpRouter.js" @@ -228,17 +228,7 @@ const makeProto = < readonly payloadSchema: Option.Option readonly successSchema: Success readonly errorSchema: Error -}): ApiEndpoint => { - const self = Object.create(Proto) - self.name = options.name - self.method = options.method - self.path = options.path - self.pathSchema = options.pathSchema - self.payloadSchema = options.payloadSchema - self.successSchema = options.successSchema - self.errorSchema = options.errorSchema - return self -} +}): ApiEndpoint => Object.assign(Object.create(Proto), options) /** * @since 1.0.0 @@ -312,26 +302,6 @@ export const del: ( "DELETE" ) -/** - * @since 1.0.0 - * @category annotations - */ -export const AnnotationStatus: unique symbol = Symbol.for("@effect/platform/ApiEndpoint/AnnotationStatus") - -/** - * @since 1.0.0 - * @category annotations - */ -export const getAnnotationStatus = (ast: AST.AST, defaultStatus: number): number => { - const annotations = ast._tag === "Transformation" ? - { - ...ast.to.annotations, - ...ast.annotations - } : - ast.annotations - return annotations[AnnotationStatus] as number ?? defaultStatus -} - type Void$ = typeof Schema.Void /** @@ -346,9 +316,9 @@ export interface Created extends Void$ { * @since 1.0.0 * @category schemas */ -export const Created: Created = Schema.Void.annotations({ - [AnnotationStatus]: 201 -}) as any +export const Created: Created = Schema.Void.annotations(ApiSchema.annotations({ + status: 201 +})) as any /** * @since 1.0.0 @@ -362,9 +332,9 @@ export interface Accepted extends Void$ { * @since 1.0.0 * @category schemas */ -export const Accepted: Accepted = Schema.Void.annotations({ - [AnnotationStatus]: 202 -}) as any +export const Accepted: Accepted = Schema.Void.annotations(ApiSchema.annotations({ + status: 202 +})) as any /** * @since 1.0.0 @@ -378,15 +348,15 @@ export interface Empty extends Void$ { * @since 1.0.0 * @category schemas */ -export const Empty: Empty = Schema.Void.annotations({ - [AnnotationStatus]: 204 -}) as any +export const Empty: Empty = Schema.Void.annotations(ApiSchema.annotations({ + status: 204 +})) as any /** * @since 1.0.0 * @category result */ -export const setSuccess: { +export const success: { ( schema: S, annotations?: { @@ -436,9 +406,9 @@ export const setSuccess: { ): ApiEndpoint => makeProto({ ...self, - successSchema: schema.annotations({ - [AnnotationStatus]: annotations?.status ?? getAnnotationStatus(schema.ast, 200) - }) as S + successSchema: schema.annotations(ApiSchema.annotations({ + status: annotations?.status ?? ApiSchema.getStatusSuccess(schema) + })) as S }) ) @@ -446,7 +416,7 @@ export const setSuccess: { * @since 1.0.0 * @category result */ -export const setError: { +export const error: { ( schema: E, annotations?: { @@ -497,9 +467,9 @@ export const setError: { makeProto({ ...self, errorSchema: schema.pipe( - Schema.annotations({ - [AnnotationStatus]: annotations?.status ?? getAnnotationStatus(schema.ast, 500) - }) + Schema.annotations(ApiSchema.annotations({ + status: annotations?.status ?? ApiSchema.getStatusError(schema) + })) ) as E }) ) @@ -508,7 +478,7 @@ export const setError: { * @since 1.0.0 * @category request */ -export const setPayload: { +export const payload: { ( schema: P & ApiEndpoint.ValidatePayload ): < @@ -556,7 +526,7 @@ export const setPayload: { * @since 1.0.0 * @category request */ -export const setPathSchema: { +export const path: { ( schema: Path & ApiEndpoint.ValidatePath ): < @@ -618,26 +588,14 @@ export const prefix: { * @since 1.0.0 * @category reflection */ -export const successStatus = (self: A): number => { - const ast = Schema.encodedSchema(self.successSchema).ast - const isVoid = ast._tag === "VoidKeyword" - return getAnnotationStatus(self.successSchema.ast, isVoid ? 204 : 200) -} - -/** - * @since 1.0.0 - * @category reflection - */ -export const successSchema = (self: A): Option.Option => { +export const successIsVoid = (self: A): boolean => { const ast = Schema.encodedSchema(self.successSchema).ast - return ast._tag === "VoidKeyword" ? Option.none() : Option.some(self.successSchema) + return ast._tag === "VoidKeyword" } /** * @since 1.0.0 * @category reflection */ -export const successIsVoid = (self: A): boolean => { - const ast = Schema.encodedSchema(self.successSchema).ast - return ast._tag === "VoidKeyword" -} +export const schemaSuccess = (self: A): Option.Option => + successIsVoid(self) ? Option.none() : Option.some(self.successSchema) diff --git a/packages/platform/src/ApiError.ts b/packages/platform/src/ApiError.ts index e1b6208e6d..57dc8be927 100644 --- a/packages/platform/src/ApiError.ts +++ b/packages/platform/src/ApiError.ts @@ -6,7 +6,7 @@ import type * as ParseResult from "@effect/schema/ParseResult" import * as Schema from "@effect/schema/Schema" import * as TreeFormatter from "@effect/schema/TreeFormatter" import * as Effect from "effect/Effect" -import { AnnotationStatus } from "./ApiEndpoint.js" +import * as ApiSchema from "./ApiSchema.js" /** * @since 1.0.0 @@ -62,9 +62,7 @@ export const Issue: Issue = Schema.Struct({ export class ApiDecodeError extends Schema.TaggedError()("ApiDecodeError", { issues: Schema.Array(Issue), message: Schema.String -}, { - [AnnotationStatus]: 400 -}) { +}, ApiSchema.annotations({ status: 400 })) { /** * @since 1.0.0 */ diff --git a/packages/platform/src/ApiGroup.ts b/packages/platform/src/ApiGroup.ts index b392e90a90..1922a31351 100644 --- a/packages/platform/src/ApiGroup.ts +++ b/packages/platform/src/ApiGroup.ts @@ -1,15 +1,14 @@ /** * @since 1.0.0 */ -import * as AST from "@effect/schema/AST" import * as Schema from "@effect/schema/Schema" import * as Chunk from "effect/Chunk" import { dual } from "effect/Function" -import * as Option from "effect/Option" import { type Pipeable, pipeArguments } from "effect/Pipeable" import * as Predicate from "effect/Predicate" import * as ApiEndpoint from "./ApiEndpoint.js" import type { ApiDecodeError } from "./ApiError.js" +import * as ApiSchema from "./ApiSchema.js" import type { PathInput } from "./HttpRouter.js" /** @@ -43,7 +42,7 @@ export interface ApiGroup< readonly [TypeId]: TypeId readonly name: Name readonly endpoints: Chunk.Chunk - readonly error: Schema.Schema + readonly errorSchema: Schema.Schema } /** @@ -132,21 +131,15 @@ const Proto = { const makeProto = (options: { readonly name: Name readonly endpoints: Chunk.Chunk - readonly error: Schema.Schema -}): ApiGroup => { - const self = Object.create(Proto) - self.name = options.name - self.endpoints = options.endpoints - self.error = options.error - return self -} + readonly errorSchema: Schema.Schema +}): ApiGroup => Object.assign(Object.create(Proto), options) /** * @since 1.0.0 * @category constructors */ export const make = (name: Name): ApiGroup => - makeProto({ name, endpoints: Chunk.empty(), error: Schema.Never as any }) + makeProto({ name, endpoints: Chunk.empty(), errorSchema: Schema.Never as any }) /** * @since 1.0.0 @@ -214,12 +207,11 @@ export const addError: { ): ApiGroup => makeProto({ ...self, - error: Schema.Union( - self.error, - schema.annotations({ - [ApiEndpoint.AnnotationStatus]: annotations?.status ?? - Option.getOrElse(AST.getAnnotation(schema.ast, ApiEndpoint.AnnotationStatus), () => 500) - }) + errorSchema: Schema.Union( + self.errorSchema, + schema.annotations(ApiSchema.annotations({ + status: annotations?.status ?? ApiSchema.getStatusError(schema) + })) ) }) ) diff --git a/packages/platform/src/ApiSchema.ts b/packages/platform/src/ApiSchema.ts new file mode 100644 index 0000000000..a945cb46d5 --- /dev/null +++ b/packages/platform/src/ApiSchema.ts @@ -0,0 +1,58 @@ +/** + * @since 1.0.0 + */ +import type * as AST from "@effect/schema/AST" +import * as Schema from "@effect/schema/Schema" +import * as Struct from "effect/Struct" + +/** + * @since 1.0.0 + * @category annotations + */ +export const AnnotationStatus: unique symbol = Symbol.for("@effect/platform/ApiSchema/AnnotationStatus") + +/** + * @since 1.0.0 + * @category annotations + */ +export const getStatus = (ast: AST.AST, defaultStatus: number): number => { + const annotations = ast._tag === "Transformation" ? + { + ...ast.to.annotations, + ...ast.annotations + } : + ast.annotations + return annotations[AnnotationStatus] as number ?? defaultStatus +} + +/** + * @since 1.0.0 + * @category annotations + */ +export const annotations = ( + annotations: Schema.Annotations.Schema> & { + readonly status?: number | undefined + } +): Schema.Annotations.Schema => { + const result: Record = Struct.omit(annotations, "status") + if (annotations.status !== undefined) { + result[AnnotationStatus] = annotations.status + } + return result +} + +/** + * @since 1.0.0 + * @category reflection + */ +export const getStatusSuccess = (self: A): number => { + const ast = Schema.encodedSchema(self).ast + const isVoid = ast._tag === "VoidKeyword" + return getStatus(self.ast, isVoid ? 204 : 200) +} + +/** + * @since 1.0.0 + * @category reflection + */ +export const getStatusError = (self: A): number => getStatus(self.ast, 500) diff --git a/packages/platform/src/index.ts b/packages/platform/src/index.ts index 63a3718ea2..319057ea1f 100644 --- a/packages/platform/src/index.ts +++ b/packages/platform/src/index.ts @@ -23,6 +23,11 @@ export * as ApiError from "./ApiError.js" */ export * as ApiGroup from "./ApiGroup.js" +/** + * @since 1.0.0 + */ +export * as ApiSchema from "./ApiSchema.js" + /** * @since 1.0.0 */ From 1d9ebf8afb17f2465481e62799e6e15b4b33d2a0 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 23 Aug 2024 11:39:34 +1200 Subject: [PATCH 08/59] middleware context --- packages/platform/src/ApiBuilder.ts | 51 ++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index 7e9b6ce389..8a9cee3c10 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -43,14 +43,17 @@ export class ApiRouter extends HttpRouter.Tag("@effect/platform/ApiBuilder/ApiRo export const serve: { ( self: Api.Api - ): Layer.Layer> + ): Layer.Layer | ErrorR> ( self: Api.Api, middleware: (httpApp: HttpApp.Default) => HttpApp.Default ): Layer.Layer< never, never, - Exclude | ApiGroup.ApiGroup.ToService + | HttpServer.HttpServer + | Exclude + | ApiGroup.ApiGroup.ToService + | ErrorR > } = ( self: Api.Api.Any, @@ -60,7 +63,24 @@ export const serve: { never, any > => - Layer.unwrapEffect(Effect.gen(function*() { + httpApp(self as any).pipe( + Effect.map(HttpServer.serve(middleware!)), + Layer.unwrapEffect, + Layer.provide(ApiRouter.Live) + ) + +/** + * @since 1.0.0 + * @category constructors + */ +export const httpApp = ( + self: Api.Api +): Effect.Effect< + HttpApp.Default, + never, + ApiRouter | ApiGroup.ApiGroup.ToService | ErrorR +> => + Effect.gen(function*() { const router = yield* ApiRouter.router const apiMiddleware = yield* Effect.serviceOption(ApiMiddleware) const errorSchema = makeErrorSchema(self as any) @@ -72,10 +92,9 @@ export const serve: { onFailure: () => Effect.die(error), onSuccess: ([body, status]) => Effect.orDie(HttpServerResponse.json(body, { status })) }) - ), - HttpServer.serve(middleware as HttpMiddleware.HttpMiddleware) + ) ) - })).pipe(Layer.provide(ApiRouter.Live)) + }) /** * @since 1.0.0 @@ -260,18 +279,20 @@ export const middleware = * @since 1.0.0 * @category middleware */ -export class ApiMiddleware - extends Context.Tag("@effect/platform/ApiBuilder/ApiMiddleware")() -{ -} +export class ApiMiddleware extends Context.Tag("@effect/platform/ApiBuilder/ApiMiddleware")< + ApiMiddleware, + HttpMiddleware.HttpMiddleware +>() {} const middlewareAdd = (middleware: HttpMiddleware.HttpMiddleware): Effect.Effect => Effect.map( - Effect.serviceOption(ApiMiddleware), - Option.match({ - onNone: () => middleware, - onSome: (current) => (httpApp) => middleware(current(httpApp)) - }) + Effect.context(), + (context) => { + const current = Context.getOption(context, ApiMiddleware) + const withContext: HttpMiddleware.HttpMiddleware = (httpApp) => + Effect.mapInputContext(middleware(httpApp), (input) => Context.merge(context, input)) + return current._tag === "None" ? withContext : (httpApp) => withContext(current.value(httpApp)) + } ) /** From 44f21d4d2221e216200b74759d72ffc4211c32b2 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 23 Aug 2024 12:49:35 +1200 Subject: [PATCH 09/59] annotations & OpenApi --- packages/platform-node/examples/api.ts | 2 +- packages/platform/src/Api.ts | 42 ++++++- packages/platform/src/ApiEndpoint.ts | 38 +++++- packages/platform/src/ApiGroup.ts | 42 ++++++- packages/platform/src/ApiSecurity.ts | 165 +++++++++++++++++++++++++ packages/platform/src/OpenApi.ts | 70 +++++++++++ packages/platform/src/index.ts | 10 ++ 7 files changed, 364 insertions(+), 5 deletions(-) create mode 100644 packages/platform/src/ApiSecurity.ts create mode 100644 packages/platform/src/OpenApi.ts diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index cfe20c1366..a944701f4a 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -39,7 +39,7 @@ const users = ApiGroup.make("users").pipe( ApiGroup.addError(Unauthorized, { status: 401 }) ) -const api = Api.make("My api").pipe( +const api = Api.empty.pipe( Api.addGroup("/users", users) ) diff --git a/packages/platform/src/Api.ts b/packages/platform/src/Api.ts index 7416d539ee..445f1ea7b2 100644 --- a/packages/platform/src/Api.ts +++ b/packages/platform/src/Api.ts @@ -3,6 +3,7 @@ */ import * as Schema from "@effect/schema/Schema" import * as Chunk from "effect/Chunk" +import * as Context from "effect/Context" import { dual } from "effect/Function" import type { Pipeable } from "effect/Pipeable" import { pipeArguments } from "effect/Pipeable" @@ -41,6 +42,7 @@ export interface Api< readonly [TypeId]: TypeId readonly groups: Chunk.Chunk readonly errorSchema: Schema.Schema + readonly annotations: Context.Context } /** @@ -65,14 +67,18 @@ const Proto = { const makeProto = (options: { readonly groups: Chunk.Chunk readonly errorSchema: Schema.Schema + readonly annotations: Context.Context }): Api => Object.assign(Object.create(Proto), options) /** * @since 1.0.0 * @category constructors */ -export const make = (_annotations?: {} | undefined): Api => - makeProto({ groups: Chunk.empty(), errorSchema: Schema.Never as any }) +export const empty: Api = makeProto({ + groups: Chunk.empty(), + errorSchema: Schema.Never as any, + annotations: Context.empty() +}) /** * @since 1.0.0 @@ -151,3 +157,35 @@ export const addError: { ) }) ) + +/** + * @since 1.0.0 + * @category annotations + */ +export const annotateMerge: { + (context: Context.Context): (self: A) => A + (self: A, context: Context.Context): A +} = dual( + 2, + (self: A, context: Context.Context): A => + makeProto({ + ...self as any, + annotations: Context.merge(self.annotations, context) + }) as A +) + +/** + * @since 1.0.0 + * @category annotations + */ +export const annotate: { + (tag: Context.Tag, value: S): (self: A) => A + (self: A, tag: Context.Tag, value: S): A +} = dual( + 3, + (self: A, tag: Context.Tag, value: S): A => + makeProto({ + ...self as any, + annotations: Context.add(self.annotations, tag, value) + }) as A +) diff --git a/packages/platform/src/ApiEndpoint.ts b/packages/platform/src/ApiEndpoint.ts index 3871752a59..ac6cec0344 100644 --- a/packages/platform/src/ApiEndpoint.ts +++ b/packages/platform/src/ApiEndpoint.ts @@ -2,6 +2,7 @@ * @since 1.0.0 */ import * as Schema from "@effect/schema/Schema" +import * as Context from "effect/Context" import type { Effect } from "effect/Effect" import { dual } from "effect/Function" import * as Option from "effect/Option" @@ -62,6 +63,7 @@ export interface ApiEndpoint< readonly payloadSchema: Option.Option readonly successSchema: Success readonly errorSchema: Error + readonly annotations: Context.Context } /** @@ -228,6 +230,7 @@ const makeProto = < readonly payloadSchema: Option.Option readonly successSchema: Success readonly errorSchema: Error + readonly annotations: Context.Context }): ApiEndpoint => Object.assign(Object.create(Proto), options) /** @@ -246,7 +249,8 @@ export const make = (method: Method) => pathSchema: Option.none(), payloadSchema: Option.none(), successSchema: Empty, - errorSchema: Schema.Never + errorSchema: Schema.Never, + annotations: Context.empty() }) /** @@ -599,3 +603,35 @@ export const successIsVoid = (self: A): boolean => { */ export const schemaSuccess = (self: A): Option.Option => successIsVoid(self) ? Option.none() : Option.some(self.successSchema) + +/** + * @since 1.0.0 + * @category annotations + */ +export const annotateMerge: { + (context: Context.Context): (self: A) => A + (self: A, context: Context.Context): A +} = dual( + 2, + (self: A, context: Context.Context): A => + makeProto({ + ...self, + annotations: Context.merge(self.annotations, context) + }) as A +) + +/** + * @since 1.0.0 + * @category annotations + */ +export const annotate: { + (tag: Context.Tag, value: S): (self: A) => A + (self: A, tag: Context.Tag, value: S): A +} = dual( + 3, + (self: A, tag: Context.Tag, value: S): A => + makeProto({ + ...self, + annotations: Context.add(self.annotations, tag, value) + }) as A +) diff --git a/packages/platform/src/ApiGroup.ts b/packages/platform/src/ApiGroup.ts index 1922a31351..471c5eb3d8 100644 --- a/packages/platform/src/ApiGroup.ts +++ b/packages/platform/src/ApiGroup.ts @@ -3,6 +3,7 @@ */ import * as Schema from "@effect/schema/Schema" import * as Chunk from "effect/Chunk" +import * as Context from "effect/Context" import { dual } from "effect/Function" import { type Pipeable, pipeArguments } from "effect/Pipeable" import * as Predicate from "effect/Predicate" @@ -43,6 +44,7 @@ export interface ApiGroup< readonly name: Name readonly endpoints: Chunk.Chunk readonly errorSchema: Schema.Schema + readonly annotations: Context.Context } /** @@ -132,6 +134,7 @@ const makeProto = readonly errorSchema: Schema.Schema + readonly annotations: Context.Context }): ApiGroup => Object.assign(Object.create(Proto), options) /** @@ -139,7 +142,12 @@ const makeProto = (name: Name): ApiGroup => - makeProto({ name, endpoints: Chunk.empty(), errorSchema: Schema.Never as any }) + makeProto({ + name, + endpoints: Chunk.empty(), + errorSchema: Schema.Never as any, + annotations: Context.empty() + }) /** * @since 1.0.0 @@ -238,3 +246,35 @@ export const prefix: { ...self, endpoints: Chunk.map(self.endpoints, ApiEndpoint.prefix(prefix)) })) + +/** + * @since 1.0.0 + * @category annotations + */ +export const annotateMerge: { + (context: Context.Context): (self: A) => A + (self: A, context: Context.Context): A +} = dual( + 2, + (self: A, context: Context.Context): A => + makeProto({ + ...self as any, + annotations: Context.merge(self.annotations, context) + }) as A +) + +/** + * @since 1.0.0 + * @category annotations + */ +export const annotate: { + (tag: Context.Tag, value: S): (self: A) => A + (self: A, tag: Context.Tag, value: S): A +} = dual( + 3, + (self: A, tag: Context.Tag, value: S): A => + makeProto({ + ...self as any, + annotations: Context.add(self.annotations, tag, value) + }) as A +) diff --git a/packages/platform/src/ApiSecurity.ts b/packages/platform/src/ApiSecurity.ts new file mode 100644 index 0000000000..b18aa3c4fd --- /dev/null +++ b/packages/platform/src/ApiSecurity.ts @@ -0,0 +1,165 @@ +/** + * @since 1.0.0 + */ +import * as Context from "effect/Context" +import { dual } from "effect/Function" +import { type Pipeable, pipeArguments } from "effect/Pipeable" +import type { Covariant } from "effect/Types" + +/** + * @since 1.0.0 + * @category type ids + */ +export const TypeId: unique symbol = Symbol.for("@effect/platform/ApiSecurity") + +/** + * @since 1.0.0 + * @category type ids + */ +export type TypeId = typeof TypeId + +/** + * @since 1.0.0 + * @category models + */ +export type ApiSecurity = Bearer | ApiKey + +/** + * @since 1.0.0 + * @category models + */ +export declare namespace ApiSecurity { + /** + * @since 1.0.0 + * @category models + */ + export interface Proto extends Pipeable { + readonly [TypeId]: { + readonly _A: Covariant + } + readonly annotations: Context.Context + } + + /** + * @since 1.0.0 + * @category models + */ + export type Type = A extends Proto ? Out : never +} + +/** + * @since 1.0.0 + * @category models + */ +export interface Bearer extends ApiSecurity.Proto { + readonly _tag: "Bearer" + readonly prefix: string +} + +/** + * @since 1.0.0 + * @category models + */ +export interface ApiKey extends ApiSecurity.Proto { + readonly _tag: "ApiKey" + readonly in: "header" | "query" + readonly key: string +} + +/** + * @since 1.0.0 + * @category models + */ +export interface Basic extends ApiSecurity.Proto { + readonly _tag: "Basic" +} + +/** + * @since 1.0.0 + * @category models + */ +export interface Credentials { + readonly username: string + readonly password: string +} + +export const Proto = { + [TypeId]: TypeId, + pipe() { + return pipeArguments(this, arguments) + } +} + +/** + * @since 1.0.0 + * @category constructors + */ +export const bearer = (options?: { + readonly prefix?: string | undefined + readonly annotations?: Context.Context | never +}): Bearer => + Object.assign(Object.create(Proto), { + _tag: "Bearer", + prefix: options?.prefix ?? "Bearer", + annotations: options?.annotations ?? Context.empty() + }) + +/** + * @since 1.0.0 + * @category constructors + */ +export const apiKey = (options: { + readonly key: string + readonly in?: "header" | "query" | undefined + readonly annotations?: Context.Context | never +}): Bearer => + Object.assign(Object.create(Proto), { + _tag: "ApiKey", + key: options.key, + in: options.in ?? "header", + annotations: options?.annotations ?? Context.empty + }) + +/** + * @since 1.0.0 + * @category constructors + */ +export const basic = (options?: { + readonly annotations?: Context.Context | never +}): Basic => + Object.assign(Object.create(Proto), { + _tag: "Basic", + annotations: options?.annotations ?? Context.empty() + }) + +/** + * @since 1.0.0 + * @category annotations + */ +export const annotateMerge: { + (context: Context.Context): (self: A) => A + (self: A, context: Context.Context): A +} = dual( + 2, + (self: A, context: Context.Context): A => + Object.assign(Object.create(Proto), { + ...self, + annotations: Context.merge(self.annotations, context) + }) +) + +/** + * @since 1.0.0 + * @category annotations + */ +export const annotate: { + (tag: Context.Tag, value: S): (self: A) => A + (self: A, tag: Context.Tag, value: S): A +} = dual( + 3, + (self: A, tag: Context.Tag, value: S): A => + Object.assign(Object.create(Proto), { + ...self, + annotations: Context.add(self.annotations, tag, value) + }) +) diff --git a/packages/platform/src/OpenApi.ts b/packages/platform/src/OpenApi.ts new file mode 100644 index 0000000000..eeba343f01 --- /dev/null +++ b/packages/platform/src/OpenApi.ts @@ -0,0 +1,70 @@ +/** + * @since 1.0.0 + */ +import * as Context from "effect/Context" +import { dual } from "effect/Function" + +/** + * @since 1.0.0 + * @category annotations + */ +export class Title extends Context.Tag("@effect/platform/OpenApi/Title")() { +} + +/** + * @since 1.0.0 + * @category annotations + */ +export class Description extends Context.Tag("@effect/platform/OpenApi/Description")() {} + +/** + * @since 1.0.0 + * @category annotations + */ +export const annotations = (annotations: { + readonly title?: string | undefined + readonly description?: string | undefined +}): Context.Context => { + let context = Context.empty() + if (annotations.title !== undefined) { + context = Context.add(context, Title, annotations.title) + } + if (annotations.description !== undefined) { + context = Context.add(context, Description, annotations.description) + } + return context +} + +/** + * @since 1.0.0 + * @category annotations + */ +export interface Annotatable { + readonly annotations: Context.Context +} + +/** + * @since 1.0.0 + * @category annotations + */ +export const annotate: { + (annotations: { + readonly title?: string | undefined + readonly description?: string | undefined + }): (self: A) => A + (self: A, annotations: { + readonly title?: string | undefined + readonly description?: string | undefined + }): A +} = dual(2, (self: A, annotations_: { + readonly title?: string | undefined + readonly description?: string | undefined +}): A => { + const context = Context.merge( + self.annotations, + annotations(annotations_) + ) + return Object.assign(Object.create(Object.getPrototypeOf(self)), self, { + annotations: context + }) +}) diff --git a/packages/platform/src/index.ts b/packages/platform/src/index.ts index 319057ea1f..e2cbb05d93 100644 --- a/packages/platform/src/index.ts +++ b/packages/platform/src/index.ts @@ -28,6 +28,11 @@ export * as ApiGroup from "./ApiGroup.js" */ export * as ApiSchema from "./ApiSchema.js" +/** + * @since 1.0.0 + */ +export * as ApiSecurity from "./ApiSecurity.js" + /** * @since 1.0.0 */ @@ -169,6 +174,11 @@ export * as KeyValueStore from "./KeyValueStore.js" */ export * as Multipart from "./Multipart.js" +/** + * @since 1.0.0 + */ +export * as OpenApi from "./OpenApi.js" + /** * @since 1.0.0 */ From 371f5114085defc371a5bd6e530740d6b882f944 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 23 Aug 2024 13:35:37 +1200 Subject: [PATCH 10/59] security middleware --- packages/platform-node/examples/api.ts | 16 +++- packages/platform/src/ApiBuilder.ts | 106 +++++++++++++++++++++++++ packages/platform/src/ApiSecurity.ts | 19 ++--- packages/platform/src/OpenApi.ts | 14 ++++ 4 files changed, 139 insertions(+), 16 deletions(-) diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index a944701f4a..44ad0fd0f4 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -1,4 +1,4 @@ -import { Api, ApiBuilder, ApiEndpoint, ApiGroup, HttpMiddleware, HttpServer } from "@effect/platform" +import { Api, ApiBuilder, ApiEndpoint, ApiGroup, ApiSecurity, HttpMiddleware, HttpServer } from "@effect/platform" import { NodeHttpServer, NodeRuntime } from "@effect/platform-node" import { Schema } from "@effect/schema" import { Context, Effect, Layer } from "effect" @@ -9,10 +9,20 @@ class User extends Schema.Class("User")({ name: Schema.String }) {} +class CurrentUser extends Context.Tag("CurrentUser")() {} + class Unauthorized extends Schema.TaggedError()("Unauthorized", { message: Schema.String }) {} +const security = ApiSecurity.bearer() + +const securityMiddleware = ApiBuilder.middlewareSecurity( + security, + CurrentUser, + (token) => Effect.succeed(new User({ id: 1000, name: `Authenticated with ${token}` })) +) + const users = ApiGroup.make("users").pipe( ApiGroup.add( ApiEndpoint.get("findById", "/:id").pipe( @@ -43,8 +53,6 @@ const api = Api.empty.pipe( Api.addGroup("/users", users) ) -class CurrentUser extends Context.Tag("CurrentUser")() {} - const UsersLive = ApiBuilder.group(api, "users", (handlers) => handlers.pipe( ApiBuilder.handle("create", (_) => @@ -62,7 +70,7 @@ const UsersLive = ApiBuilder.group(api, "users", (handlers) => }) )), ApiBuilder.handle("me", (_) => CurrentUser), - ApiBuilder.middleware(Effect.provideService(CurrentUser, new User({ id: 1000, name: "Provided" }))) + securityMiddleware )) ApiBuilder.serve(api, HttpMiddleware.logger).pipe( diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index 8a9cee3c10..dc33d5a423 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -6,6 +6,7 @@ import * as Schema from "@effect/schema/Schema" import * as Chunk from "effect/Chunk" import * as Context from "effect/Context" import * as Effect from "effect/Effect" +import * as Encoding from "effect/Encoding" import * as FiberRef from "effect/FiberRef" import { identity } from "effect/Function" import { globalValue } from "effect/GlobalValue" @@ -15,11 +16,13 @@ import { type Pipeable, pipeArguments } from "effect/Pipeable" import type { ReadonlyRecord } from "effect/Record" import type { Scope } from "effect/Scope" import type { Covariant, Mutable, NoInfer } from "effect/Types" +import { unify } from "effect/Unify" import type * as Api from "./Api.js" import * as ApiEndpoint from "./ApiEndpoint.js" import { ApiDecodeError } from "./ApiError.js" import type * as ApiGroup from "./ApiGroup.js" import * as ApiSchema from "./ApiSchema.js" +import type * as ApiSecurity from "./ApiSecurity.js" import type * as HttpApp from "./HttpApp.js" import * as HttpMethod from "./HttpMethod.js" import * as HttpMiddleware from "./HttpMiddleware.js" @@ -368,6 +371,109 @@ export const middlewareCors = ( } | undefined ): Layer.Layer => middlewareMakeNoError(HttpMiddleware.cors(options) as any) +/** + * @since 1.0.0 + * @category middleware + */ +export interface SecurityMiddleware { + ( + self: Handlers + ): Handlers | ApiEndpoint.ApiEndpoint.ExcludeProvided, Endpoints> +} + +/** + * Make a middleware from an `ApiSecurity` instance, that can be used when + * constructing a `Handlers` group. + * + * @since 1.0.0 + * @category middleware + * @example + * import { ApiBuilder, ApiSecurity } from "@effect/platform" + * import { Schema } from "@effect/schema" + * import { Context, Effect } from "effect" + * + * class User extends Schema.Class("User")({ + * id: Schema.Number + * }) {} + * + * class CurrentUser extends Context.Tag("CurrentUser")() {} + * + * class Accounts extends Context.Tag("Accounts") Effect.Effect + * }>() {} + * + * const security = ApiSecurity.bearer() + * + * const securityMiddleware = Effect.gen(function*() { + * const accounts = yield* Accounts + * return ApiBuilder.middlewareSecurity( + * security, + * CurrentUser, + * (token) => accounts.findUserByAccessToken(token) + * ) + * }) + */ +export const middlewareSecurity = ( + self: Security, + tag: Context.Tag, + f: ( + credentials: ApiSecurity.ApiSecurity.Type + ) => Effect.Effect +): SecurityMiddleware => { + switch (self._tag) { + case "Bearer": { + const prefixLen = `${self.prefix} `.length + return middleware(Effect.provideServiceEffect( + tag, + HttpServerRequest.HttpServerRequest.pipe( + Effect.map((request) => (request.headers.authorization ?? "").slice(prefixLen) as any), + Effect.flatMap(f) + ) + )) as SecurityMiddleware + } + case "ApiKey": { + const schema = Schema.Struct({ + [self.key]: Schema.String + }) + const decode = unify( + self.in === "query" + ? HttpServerRequest.schemaSearchParams(schema) + : HttpServerRequest.schemaHeaders(schema) + ) + const handled = Effect.match(decode, { + onFailure: () => "" as any, + onSuccess: (match) => match[self.key] + }) + return middleware(Effect.provideServiceEffect(tag, Effect.flatMap(handled, f))) as SecurityMiddleware + } + case "Basic": { + const empty: ApiSecurity.ApiSecurity.Type = { + username: "", + password: "" + } as any + return middleware(Effect.provideServiceEffect( + tag, + HttpServerRequest.HttpServerRequest.pipe( + Effect.flatMap((request) => Encoding.decodeBase64String(request.headers.authorization ?? "")), + Effect.matchEffect({ + onFailure: () => f(empty), + onSuccess: (header) => { + const parts = header.split(":") + if (parts.length !== 2) { + return f(empty) + } + return f({ + username: parts[0], + password: parts[1] + } as any) + } + }) + ) + )) as SecurityMiddleware + } + } +} + /** * @since 1.0.0 * @category middleware diff --git a/packages/platform/src/ApiSecurity.ts b/packages/platform/src/ApiSecurity.ts index b18aa3c4fd..44eece358d 100644 --- a/packages/platform/src/ApiSecurity.ts +++ b/packages/platform/src/ApiSecurity.ts @@ -22,7 +22,7 @@ export type TypeId = typeof TypeId * @since 1.0.0 * @category models */ -export type ApiSecurity = Bearer | ApiKey +export type ApiSecurity = Bearer | ApiKey | Basic /** * @since 1.0.0 @@ -96,12 +96,11 @@ export const Proto = { */ export const bearer = (options?: { readonly prefix?: string | undefined - readonly annotations?: Context.Context | never }): Bearer => Object.assign(Object.create(Proto), { _tag: "Bearer", prefix: options?.prefix ?? "Bearer", - annotations: options?.annotations ?? Context.empty() + annotations: Context.empty() }) /** @@ -111,26 +110,22 @@ export const bearer = (options?: { export const apiKey = (options: { readonly key: string readonly in?: "header" | "query" | undefined - readonly annotations?: Context.Context | never }): Bearer => Object.assign(Object.create(Proto), { _tag: "ApiKey", key: options.key, in: options.in ?? "header", - annotations: options?.annotations ?? Context.empty + annotations: Context.empty }) /** * @since 1.0.0 * @category constructors */ -export const basic = (options?: { - readonly annotations?: Context.Context | never -}): Basic => - Object.assign(Object.create(Proto), { - _tag: "Basic", - annotations: options?.annotations ?? Context.empty() - }) +export const basic: Basic = Object.assign(Object.create(Proto), { + _tag: "Basic", + annotations: Context.empty() +}) /** * @since 1.0.0 diff --git a/packages/platform/src/OpenApi.ts b/packages/platform/src/OpenApi.ts index eeba343f01..bf2986d06b 100644 --- a/packages/platform/src/OpenApi.ts +++ b/packages/platform/src/OpenApi.ts @@ -3,6 +3,7 @@ */ import * as Context from "effect/Context" import { dual } from "effect/Function" +import type { ApiSecurity } from "./ApiSecurity.js" /** * @since 1.0.0 @@ -17,6 +18,12 @@ export class Title extends Context.Tag("@effect/platform/OpenApi/Title")() {} +/** + * @since 1.0.0 + * @category annotations + */ +export class Security extends Context.Tag("@effect/platform/OpenApi/Security")() {} + /** * @since 1.0.0 * @category annotations @@ -24,6 +31,7 @@ export class Description extends Context.Tag("@effect/platform/OpenApi/Descripti export const annotations = (annotations: { readonly title?: string | undefined readonly description?: string | undefined + readonly security?: ApiSecurity | undefined }): Context.Context => { let context = Context.empty() if (annotations.title !== undefined) { @@ -32,6 +40,9 @@ export const annotations = (annotations: { if (annotations.description !== undefined) { context = Context.add(context, Description, annotations.description) } + if (annotations.security !== undefined) { + context = Context.add(context, Security, annotations.security) + } return context } @@ -51,14 +62,17 @@ export const annotate: { (annotations: { readonly title?: string | undefined readonly description?: string | undefined + readonly security?: ApiSecurity | undefined }): (self: A) => A (self: A, annotations: { readonly title?: string | undefined readonly description?: string | undefined + readonly security?: ApiSecurity | undefined }): A } = dual(2, (self: A, annotations_: { readonly title?: string | undefined readonly description?: string | undefined + readonly security?: ApiSecurity | undefined }): A => { const context = Context.merge( self.annotations, From c1d08a32fedb64c9ad136b5424583b297155b017 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 23 Aug 2024 14:46:10 +1200 Subject: [PATCH 11/59] middlewareSecurityVoid --- packages/platform/src/ApiBuilder.ts | 139 +++++++++++++++++----------- 1 file changed, 85 insertions(+), 54 deletions(-) diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index dc33d5a423..da74e89a57 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -381,6 +381,64 @@ export interface SecurityMiddleware { ): Handlers | ApiEndpoint.ApiEndpoint.ExcludeProvided, Endpoints> } +/** + * @since 1.0.0 + * @category middleware + */ +export const securityDecode = ( + self: Security +): Effect.Effect< + ApiSecurity.ApiSecurity.Type, + never, + HttpServerRequest.HttpServerRequest | HttpServerRequest.ParsedSearchParams +> => { + switch (self._tag) { + case "Bearer": { + const prefixLen = `${self.prefix} `.length + return Effect.map( + HttpServerRequest.HttpServerRequest, + (request) => (request.headers.authorization ?? "").slice(prefixLen) as any + ) + } + case "ApiKey": { + const schema = Schema.Struct({ + [self.key]: Schema.String + }) + const decode = unify( + self.in === "query" + ? HttpServerRequest.schemaSearchParams(schema) + : HttpServerRequest.schemaHeaders(schema) + ) + return Effect.match(decode, { + onFailure: () => "" as any, + onSuccess: (match) => match[self.key] + }) + } + case "Basic": { + const empty: ApiSecurity.ApiSecurity.Type = { + username: "", + password: "" + } as any + return HttpServerRequest.HttpServerRequest.pipe( + Effect.flatMap((request) => Encoding.decodeBase64String(request.headers.authorization ?? "")), + Effect.match({ + onFailure: () => empty, + onSuccess: (header) => { + const parts = header.split(":") + if (parts.length !== 2) { + return empty + } + return { + username: parts[0], + password: parts[1] + } as any + } + }) + ) + } + } +} + /** * Make a middleware from an `ApiSecurity` instance, that can be used when * constructing a `Handlers` group. @@ -419,60 +477,33 @@ export const middlewareSecurity = ) => Effect.Effect -): SecurityMiddleware => { - switch (self._tag) { - case "Bearer": { - const prefixLen = `${self.prefix} `.length - return middleware(Effect.provideServiceEffect( - tag, - HttpServerRequest.HttpServerRequest.pipe( - Effect.map((request) => (request.headers.authorization ?? "").slice(prefixLen) as any), - Effect.flatMap(f) - ) - )) as SecurityMiddleware - } - case "ApiKey": { - const schema = Schema.Struct({ - [self.key]: Schema.String - }) - const decode = unify( - self.in === "query" - ? HttpServerRequest.schemaSearchParams(schema) - : HttpServerRequest.schemaHeaders(schema) - ) - const handled = Effect.match(decode, { - onFailure: () => "" as any, - onSuccess: (match) => match[self.key] - }) - return middleware(Effect.provideServiceEffect(tag, Effect.flatMap(handled, f))) as SecurityMiddleware - } - case "Basic": { - const empty: ApiSecurity.ApiSecurity.Type = { - username: "", - password: "" - } as any - return middleware(Effect.provideServiceEffect( - tag, - HttpServerRequest.HttpServerRequest.pipe( - Effect.flatMap((request) => Encoding.decodeBase64String(request.headers.authorization ?? "")), - Effect.matchEffect({ - onFailure: () => f(empty), - onSuccess: (header) => { - const parts = header.split(":") - if (parts.length !== 2) { - return f(empty) - } - return f({ - username: parts[0], - password: parts[1] - } as any) - } - }) - ) - )) as SecurityMiddleware - } - } -} +): SecurityMiddleware => + middleware(Effect.provideServiceEffect( + tag, + Effect.flatMap(securityDecode(self), f) + )) as SecurityMiddleware + +/** + * Make a middleware from an `ApiSecurity` instance, that can be used when + * constructing a `Handlers` group. + * + * This version does not supply any context to the handlers. + * + * @since 1.0.0 + * @category middleware + */ +export const middlewareSecurityVoid = ( + self: Security, + f: ( + credentials: ApiSecurity.ApiSecurity.Type + ) => Effect.Effect +): SecurityMiddleware => + middleware((httpApp) => + securityDecode(self).pipe( + Effect.flatMap(f), + Effect.zipRight(httpApp) + ) + ) as SecurityMiddleware /** * @since 1.0.0 From f859f2353ede9a5c949b3eb5401e2d913f7ae805 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 23 Aug 2024 15:16:06 +1200 Subject: [PATCH 12/59] refactor layer middleware --- packages/platform/src/ApiBuilder.ts | 179 +++++++++++++++++++--------- 1 file changed, 124 insertions(+), 55 deletions(-) diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index da74e89a57..34053ab54e 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -17,7 +17,7 @@ import type { ReadonlyRecord } from "effect/Record" import type { Scope } from "effect/Scope" import type { Covariant, Mutable, NoInfer } from "effect/Types" import { unify } from "effect/Unify" -import type * as Api from "./Api.js" +import * as Api from "./Api.js" import * as ApiEndpoint from "./ApiEndpoint.js" import { ApiDecodeError } from "./ApiError.js" import type * as ApiGroup from "./ApiGroup.js" @@ -261,6 +261,8 @@ export const handle = () {} +/** + * @since 1.0.0 + * @category middleware + */ +export declare namespace ApiMiddleware { + /** + * @since 1.0.0 + * @category middleware + */ + export type Fn = ( + httpApp: HttpApp.Default + ) => HttpApp.Default +} + const middlewareAdd = (middleware: HttpMiddleware.HttpMiddleware): Effect.Effect => Effect.map( Effect.context(), @@ -298,19 +314,71 @@ const middlewareAdd = (middleware: HttpMiddleware.HttpMiddleware): Effect.Effect } ) +const middlewareAddNoContext = ( + middleware: HttpMiddleware.HttpMiddleware +): Effect.Effect => + Effect.map( + Effect.serviceOption(ApiMiddleware), + (current): HttpMiddleware.HttpMiddleware => { + return current._tag === "None" ? middleware : (httpApp) => middleware(current.value(httpApp)) + } + ) + /** * Create an `Api` level middleware `Layer`. * * @since 1.0.0 * @category middleware */ -export const middlewareMake = ( - _api: Api.Api, - middleware: ApiMiddleware.Fn, R> | Effect.Effect, R>, EX, RX> -): Layer.Layer | RX> => - Effect.isEffect(middleware) - ? Layer.effect(ApiMiddleware, Effect.flatMap(middleware as any, middlewareAdd)) - : Layer.effect(ApiMiddleware, middlewareAdd(middleware as any)) +export const middlewareLayer: { + ( + middleware: ApiMiddleware.Fn | Effect.Effect, EX, RX>, + options?: { + readonly withContext?: false | undefined + } + ): Layer.Layer + ( + middleware: ApiMiddleware.Fn | Effect.Effect, EX, RX>, + options: { + readonly withContext: true + } + ): Layer.Layer | RX> + ( + api: Api.Api, + middleware: ApiMiddleware.Fn> | Effect.Effect>, EX, RX>, + options?: { + readonly withContext?: false | undefined + } + ): Layer.Layer + ( + api: Api.Api, + middleware: ApiMiddleware.Fn, R> | Effect.Effect, R>, EX, RX>, + options: { + readonly withContext: true + } + ): Layer.Layer | RX> +} = ( + ...args: [ + middleware: ApiMiddleware.Fn | Effect.Effect, any, any>, + options?: { + readonly withContext?: boolean | undefined + } | undefined + ] | [ + api: Api.Api.Any, + middleware: ApiMiddleware.Fn | Effect.Effect, any, any>, + options?: { + readonly withContext?: boolean | undefined + } | undefined + ] +): any => { + const apiFirst = Api.isApi(args[0]) + const withContext = apiFirst ? args[2]?.withContext === true : (args as any)[1]?.withContext === true + const add = withContext ? middlewareAdd : middlewareAddNoContext + const middleware = apiFirst ? args[1] : args[0] + return Effect.isEffect(middleware) + ? Layer.effect(ApiMiddleware, Effect.flatMap(middleware as any, add)) + : Layer.effect(ApiMiddleware, add(middleware as any)) +} /** * Create an `Api` level middleware `Layer`, that has a `Scope` provided to @@ -319,40 +387,53 @@ export const middlewareMake = ( - _api: Api.Api, - middleware: ApiMiddleware.Fn, R> | Effect.Effect, R>, EX, RX> -): Layer.Layer | Exclude> => - Effect.isEffect(middleware) - ? Layer.scoped(ApiMiddleware, Effect.flatMap(middleware as any, middlewareAdd)) - : Layer.effect(ApiMiddleware, middlewareAdd(middleware as any)) - -/** - * Create an `Api` level middleware `Layer`, that can't fail. - * - * @since 1.0.0 - * @category middleware - */ -export const middlewareMakeNoError = ( - middleware: ApiMiddleware.Fn | Effect.Effect, EX, RX> -): Layer.Layer | RX> => - Effect.isEffect(middleware) - ? Layer.effect(ApiMiddleware, Effect.flatMap(middleware as any, middlewareAdd)) - : Layer.effect(ApiMiddleware, middlewareAdd(middleware as any)) - -/** - * Create an `Api` level middleware `Layer`, that can't fail. - * It has a `Scope` provided to the constructor. - * - * @since 1.0.0 - * @category middleware - */ -export const middlewareMakeNoErrorScoped = ( - middleware: ApiMiddleware.Fn | Effect.Effect, EX, RX> -): Layer.Layer | RX> => - Effect.isEffect(middleware) - ? Layer.scoped(ApiMiddleware, Effect.flatMap(middleware as any, middlewareAdd)) - : Layer.effect(ApiMiddleware, middlewareAdd(middleware as any)) +export const middlewareLayerScoped: { + ( + middleware: Effect.Effect, EX, RX>, + options?: { + readonly withContext?: false | undefined + } + ): Layer.Layer> + ( + middleware: Effect.Effect, EX, RX>, + options: { + readonly withContext: true + } + ): Layer.Layer | Exclude> + ( + api: Api.Api, + middleware: Effect.Effect>, EX, RX>, + options?: { + readonly withContext?: false | undefined + } + ): Layer.Layer> + ( + api: Api.Api, + middleware: Effect.Effect, R>, EX, RX>, + options: { + readonly withContext: true + } + ): Layer.Layer | Exclude> +} = ( + ...args: [ + middleware: ApiMiddleware.Fn | Effect.Effect, any, any>, + options?: { + readonly withContext?: boolean | undefined + } | undefined + ] | [ + api: Api.Api.Any, + middleware: ApiMiddleware.Fn | Effect.Effect, any, any>, + options?: { + readonly withContext?: boolean | undefined + } | undefined + ] +): any => { + const apiFirst = Api.isApi(args[0]) + const withContext = apiFirst ? args[2]?.withContext === true : (args as any)[1]?.withContext === true + const add = withContext ? middlewareAdd : middlewareAddNoContext + const middleware = apiFirst ? args[1] : args[0] + return Layer.scoped(ApiMiddleware, Effect.flatMap(middleware as any, add)) +} /** * A CORS middleware layer. @@ -369,7 +450,7 @@ export const middlewareCors = ( readonly maxAge?: number | undefined readonly credentials?: boolean | undefined } | undefined -): Layer.Layer => middlewareMakeNoError(HttpMiddleware.cors(options) as any) +): Layer.Layer => middlewareLayer(HttpMiddleware.cors(options)) /** * @since 1.0.0 @@ -505,18 +586,6 @@ export const middlewareSecurityVoid = -/** - * @since 1.0.0 - * @category middleware - */ -export declare namespace ApiMiddleware { - /** - * @since 1.0.0 - * @category middleware - */ - export type Fn = (httpApp: HttpApp.Default) => HttpApp.Default -} - // internal const requestPayload = ( From 6a502e5b631d9461cd28775402c66a8106cf4fbd Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 23 Aug 2024 15:18:42 +1200 Subject: [PATCH 13/59] don't export Proto --- packages/platform/src/ApiSecurity.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/platform/src/ApiSecurity.ts b/packages/platform/src/ApiSecurity.ts index 44eece358d..c63f56e17d 100644 --- a/packages/platform/src/ApiSecurity.ts +++ b/packages/platform/src/ApiSecurity.ts @@ -83,7 +83,7 @@ export interface Credentials { readonly password: string } -export const Proto = { +const Proto = { [TypeId]: TypeId, pipe() { return pipeArguments(this, arguments) From 1ca25462e702cfd12d0306ace7c2ab095b3fb622 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 23 Aug 2024 15:23:49 +1200 Subject: [PATCH 14/59] add ApiGroup.annotateEndpoints* --- packages/platform/src/ApiGroup.ts | 32 +++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/packages/platform/src/ApiGroup.ts b/packages/platform/src/ApiGroup.ts index 471c5eb3d8..4da27ec823 100644 --- a/packages/platform/src/ApiGroup.ts +++ b/packages/platform/src/ApiGroup.ts @@ -278,3 +278,35 @@ export const annotate: { annotations: Context.add(self.annotations, tag, value) }) as A ) + +/** + * @since 1.0.0 + * @category annotations + */ +export const annotateEndpointsMerge: { + (context: Context.Context): (self: A) => A + (self: A, context: Context.Context): A +} = dual( + 2, + (self: A, context: Context.Context): A => + makeProto({ + ...self as any, + endpoints: Chunk.map(self.endpoints, ApiEndpoint.annotateMerge(context)) + }) as A +) + +/** + * @since 1.0.0 + * @category annotations + */ +export const annotateEndpoints: { + (tag: Context.Tag, value: S): (self: A) => A + (self: A, tag: Context.Tag, value: S): A +} = dual( + 3, + (self: A, tag: Context.Tag, value: S): A => + makeProto({ + ...self as any, + endpoints: Chunk.map(self.endpoints, ApiEndpoint.annotate(tag, value)) + }) as A +) From 2da6d33c6f9b7ed856a99a57a091edcd11bf70d0 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 23 Aug 2024 17:18:12 +1200 Subject: [PATCH 15/59] start ApiClient --- packages/platform-node/examples/api.ts | 30 ++++++- packages/platform/src/Api.ts | 11 ++- packages/platform/src/ApiBuilder.ts | 2 +- packages/platform/src/ApiClient.ts | 120 +++++++++++++++++++++++++ packages/platform/src/ApiEndpoint.ts | 15 ++++ packages/platform/src/ApiGroup.ts | 2 +- packages/platform/src/ApiReflection.ts | 105 ++++++++++++++++++++++ packages/platform/src/ApiSchema.ts | 26 ++++-- packages/platform/src/index.ts | 10 +++ 9 files changed, 309 insertions(+), 12 deletions(-) create mode 100644 packages/platform/src/ApiClient.ts create mode 100644 packages/platform/src/ApiReflection.ts diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index 44ad0fd0f4..ed82d01b42 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -1,5 +1,16 @@ -import { Api, ApiBuilder, ApiEndpoint, ApiGroup, ApiSecurity, HttpMiddleware, HttpServer } from "@effect/platform" -import { NodeHttpServer, NodeRuntime } from "@effect/platform-node" +import { + Api, + ApiBuilder, + ApiClient, + ApiEndpoint, + ApiGroup, + ApiSecurity, + HttpClient, + HttpClientRequest, + HttpMiddleware, + HttpServer +} from "@effect/platform" +import { NodeHttpClient, NodeHttpServer, NodeRuntime } from "@effect/platform-node" import { Schema } from "@effect/schema" import { Context, Effect, Layer } from "effect" import { createServer } from "node:http" @@ -81,3 +92,18 @@ ApiBuilder.serve(api, HttpMiddleware.logger).pipe( Layer.launch, NodeRuntime.runMain ) + +Effect.gen(function*() { + yield* Effect.sleep(2000) + const client = yield* ApiClient.make(api) + const user = yield* client.users.me() + console.log(user) +}).pipe( + Effect.provideService( + HttpClient.HttpClient, + HttpClient.fetch.pipe( + HttpClient.mapRequest(HttpClientRequest.prependUrl("http://localhost:3000")) + ) + ), + NodeRuntime.runMain +) diff --git a/packages/platform/src/Api.ts b/packages/platform/src/Api.ts index 445f1ea7b2..9745915728 100644 --- a/packages/platform/src/Api.ts +++ b/packages/platform/src/Api.ts @@ -8,6 +8,7 @@ import { dual } from "effect/Function" import type { Pipeable } from "effect/Pipeable" import { pipeArguments } from "effect/Pipeable" import * as Predicate from "effect/Predicate" +import { ApiDecodeError } from "./ApiError.js" import * as ApiGroup from "./ApiGroup.js" import * as ApiSchema from "./ApiSchema.js" import type * as HttpRouter from "./HttpRouter.js" @@ -55,6 +56,14 @@ export declare namespace Api { * @category models */ export type Any = Api | Api | Api + + /** + * @since 1.0.0 + * @category models + */ + export type Context = A extends Api + ? _ApiErrorR | ApiGroup.ApiGroup.Context<_Groups> + : never } const Proto = { @@ -76,7 +85,7 @@ const makeProto = (options: */ export const empty: Api = makeProto({ groups: Chunk.empty(), - errorSchema: Schema.Never as any, + errorSchema: ApiDecodeError as any, annotations: Context.empty() }) diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index 34053ab54e..a152ea7c9a 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -645,7 +645,7 @@ const astCache = globalValue("@effect/platform/ApiBuilder", () => new WeakMap, any, any> ): Schema.Schema => { - const schemas = new Set([ApiDecodeError]) + const schemas = new Set() function processSchema(schema: Schema.Schema.Any): void { if (astCache.has(schema.ast)) { schemas.add(astCache.get(schema.ast)!) diff --git a/packages/platform/src/ApiClient.ts b/packages/platform/src/ApiClient.ts new file mode 100644 index 0000000000..ae428e86c0 --- /dev/null +++ b/packages/platform/src/ApiClient.ts @@ -0,0 +1,120 @@ +/** + * @since 1.0.0 + */ +import * as Schema from "@effect/schema/Schema" +import * as Context from "effect/Context" +import * as Effect from "effect/Effect" +import * as Option from "effect/Option" +import type { Simplify } from "effect/Types" +import { unify } from "effect/Unify" +import type { Api } from "./Api.js" +import type { ApiEndpoint } from "./ApiEndpoint.js" +import type { ApiGroup } from "./ApiGroup.js" +import { reflect } from "./ApiReflection.js" +import * as HttpClient from "./HttpClient.js" +import * as HttpClientError from "./HttpClientError.js" +import * as HttpClientRequest from "./HttpClientRequest.js" +import * as HttpClientResponse from "./HttpClientResponse.js" +import * as HttpMethod from "./HttpMethod.js" + +/** + * @since 1.0.0 + * @category models + */ +export type Client = [A] extends [Api] ? { + readonly [GroupName in _Groups["name"]]: ApiGroup.WithName<_Groups, GroupName> extends + ApiGroup ? { + readonly [Name in _Endpoints["name"]]: ( + request: Simplify>> + ) => Effect.Effect< + ApiEndpoint.SuccessWithName<_Endpoints, Name>, + ApiEndpoint.ErrorWithName<_Endpoints, Name> | _GroupError | _ApiError + > + } : + never + } : + never + +/** + * @since 1.0.0 + * @category constructors + */ +export const make = ( + api: A +): Effect.Effect>, never, Api.Context | HttpClient.HttpClient.Default> => + Effect.gen(function*() { + const context = yield* Effect.context() + const httpClient = yield* HttpClient.HttpClient + const client: Record> = {} + reflect(api as any, { + mode: "full", + onGroup({ group }) { + client[group.name] = {} + }, + onEndpoint({ endpoint, errors, group, success }) { + const handleSuccess = unify(Option.match(success[0], { + onNone: () => HttpClientResponse.void, + onSome: (ast) => HttpClientResponse.schemaBodyJsonScoped(Schema.make(ast)) + })) + const handleError = ( + request: HttpClientRequest.HttpClientRequest, + response: HttpClientResponse.HttpClientResponse + ) => { + const error = errors.get(response.status) + if (error === undefined) { + return Effect.die( + new HttpClientError.ResponseError({ + reason: "Decode", + request, + response + }) + ) + } + const decode = Schema.decodeUnknown(Schema.make(error)) + return response.json.pipe( + Effect.flatMap(decode), + Effect.matchEffect({ + onFailure: Effect.die, + onSuccess: Effect.fail + }) + ) + } + const encodePayload = Option.map(endpoint.payloadSchema, Schema.encodeUnknown) + client[group.name][endpoint.name] = (request: { + readonly path: any + readonly payload: any + }) => { + // TODO: make more efficient + let url: string = endpoint.path + if (request && request.path) { + for (const key in request.path) { + url = url.replace(new RegExp(`:${key}\\b`), request.path[key]) + } + } + const baseRequest = HttpClientRequest.make(endpoint.method)(url) + return (encodePayload._tag === "Some" ? + encodePayload.value(request.payload).pipe( + Effect.flatMap((payload) => + HttpMethod.hasBody(endpoint.method) + ? HttpClientRequest.jsonBody(baseRequest, payload) + : Effect.succeed(HttpClientRequest.setUrlParams(baseRequest, payload)) + ), + Effect.orDie + ) : + Effect.succeed(baseRequest)).pipe( + Effect.flatMap((request) => + httpClient(request).pipe( + Effect.orDie, + Effect.flatMap((response) => + response.status !== success[1] ? handleError(request, response) : Effect.succeed(response) + ) + ) + ), + handleSuccess, + Effect.mapInputContext((input) => Context.merge(context, input)) + ) + } + } + }) + return client as any + }) diff --git a/packages/platform/src/ApiEndpoint.ts b/packages/platform/src/ApiEndpoint.ts index ac6cec0344..af50367fa3 100644 --- a/packages/platform/src/ApiEndpoint.ts +++ b/packages/platform/src/ApiEndpoint.ts @@ -127,6 +127,15 @@ export declare namespace ApiEndpoint { readonly path: PathParsed } & ([Payload] extends [infer P] ? [P] extends [never] ? {} : { readonly payload: P } : {}) + /** + * @since 1.0.0 + * @category models + */ + export type ClientRequest = ( + & ([Endpoint["pathSchema"]] extends [Option.Option] ? {} : { readonly path: PathParsed }) + & ([Payload] extends [infer P] ? [P] extends [never] ? {} : { readonly payload: P } : {}) + ) extends infer Req ? keyof Req extends never ? void : Req : void + /** * @since 1.0.0 * @category models @@ -171,6 +180,12 @@ export declare namespace ApiEndpoint { R > + /** + * @since 1.0.0 + * @category models + */ + export type SuccessWithName = Success> + /** * @since 1.0.0 * @category models diff --git a/packages/platform/src/ApiGroup.ts b/packages/platform/src/ApiGroup.ts index 4da27ec823..2f997b4e3e 100644 --- a/packages/platform/src/ApiGroup.ts +++ b/packages/platform/src/ApiGroup.ts @@ -79,7 +79,7 @@ export declare namespace ApiGroup { * @since 1.0.0 * @category models */ - export type WithName = Extract + export type WithName = Extract /** * @since 1.0.0 diff --git a/packages/platform/src/ApiReflection.ts b/packages/platform/src/ApiReflection.ts new file mode 100644 index 0000000000..170f47e808 --- /dev/null +++ b/packages/platform/src/ApiReflection.ts @@ -0,0 +1,105 @@ +/** + * @since 1.0.0 + */ +import * as AST from "@effect/schema/AST" +import * as Context from "effect/Context" +import * as Option from "effect/Option" +import type * as Api from "./Api.js" +import * as ApiEndpoint from "./ApiEndpoint.js" +import type * as ApiGroup from "./ApiGroup.js" +import * as ApiSchema from "./ApiSchema.js" +import type { HttpMethod } from "./HttpMethod.js" + +const extractErrors = ( + ast: AST.AST, + encoded: boolean, + inherited: ReadonlyMap +): ReadonlyMap => { + const topStatus = ApiSchema.getStatusErrorAST(ast) + ast = encoded ? AST.encodedAST(ast) : ast + const errors = new Map(inherited) + function process(ast: AST.AST) { + if (ast._tag === "NeverKeyword") { + return + } + const status = ApiSchema.getStatus(ast, topStatus) + if (errors.has(status)) { + const current = errors.get(status)! + errors.set( + status, + AST.Union.make( + current._tag === "Union" ? [...current.types, ast] : [current, ast] + ) + ) + } else { + errors.set(status, ast) + } + } + if (ast._tag === "Union") { + for (const type of ast.types) { + process(type) + } + } else { + process(ast) + } + return errors +} + +/** + * @since 1.0.0 + * @category reflection + */ +export const reflect = ( + self: Api.Api, + options: { + readonly mode: "encoded" | "full" + readonly onGroup: (options: { + readonly apiAnnotations: Context.Context + readonly group: ApiGroup.ApiGroup + readonly annotations: Context.Context + }) => void + readonly onEndpoint: (options: { + readonly apiAnnotations: Context.Context + readonly group: ApiGroup.ApiGroup + readonly groupAnnotations: Context.Context + readonly endpoint: ApiEndpoint.ApiEndpoint + readonly annotations: Context.Context + readonly success: readonly [ast: Option.Option, status: number] + readonly errors: ReadonlyMap + }) => void + } +) => { + const apiErrors = extractErrors(self.errorSchema.ast, options.mode === "encoded", new Map()) + + const groups = self.groups as Iterable> + for (const group of groups) { + const groupErrors = extractErrors(group.errorSchema.ast, options.mode === "encoded", apiErrors) + const groupAnnotations = Context.merge(self.annotations, group.annotations) + options.onGroup({ + apiAnnotations: self.annotations, + group, + annotations: groupAnnotations + }) + const endpoints = group.endpoints as Iterable> + + for (const endpoint of endpoints) { + const errors = extractErrors(endpoint.errorSchema.ast, options.mode === "encoded", groupErrors) + const annotations = Context.merge(groupAnnotations, endpoint.annotations) + const success = [ + ApiEndpoint.schemaSuccess(endpoint).pipe( + Option.map((schema) => options.mode === "full" ? schema.ast : AST.encodedAST(schema.ast)) + ), + ApiSchema.getStatusSuccess(endpoint.successSchema) + ] as const + options.onEndpoint({ + apiAnnotations: self.annotations, + groupAnnotations, + group, + endpoint, + annotations, + success, + errors + }) + } + } +} diff --git a/packages/platform/src/ApiSchema.ts b/packages/platform/src/ApiSchema.ts index a945cb46d5..c3086f6724 100644 --- a/packages/platform/src/ApiSchema.ts +++ b/packages/platform/src/ApiSchema.ts @@ -1,8 +1,8 @@ /** * @since 1.0.0 */ -import type * as AST from "@effect/schema/AST" -import * as Schema from "@effect/schema/Schema" +import * as AST from "@effect/schema/AST" +import type * as Schema from "@effect/schema/Schema" import * as Struct from "effect/Struct" /** @@ -45,14 +45,26 @@ export const annotations = ( * @since 1.0.0 * @category reflection */ -export const getStatusSuccess = (self: A): number => { - const ast = Schema.encodedSchema(self).ast - const isVoid = ast._tag === "VoidKeyword" - return getStatus(self.ast, isVoid ? 204 : 200) +export const getStatusSuccessAST = (ast: AST.AST): number => { + const encoded = AST.encodedAST(ast) + const isVoid = encoded._tag === "VoidKeyword" + return getStatus(ast, isVoid ? 204 : 200) } /** * @since 1.0.0 * @category reflection */ -export const getStatusError = (self: A): number => getStatus(self.ast, 500) +export const getStatusSuccess = (self: A): number => getStatusSuccessAST(self.ast) + +/** + * @since 1.0.0 + * @category reflection + */ +export const getStatusErrorAST = (ast: AST.AST): number => getStatus(ast, 500) + +/** + * @since 1.0.0 + * @category reflection + */ +export const getStatusError = (self: A): number => getStatusErrorAST(self.ast) diff --git a/packages/platform/src/index.ts b/packages/platform/src/index.ts index e2cbb05d93..be6d6f3ed0 100644 --- a/packages/platform/src/index.ts +++ b/packages/platform/src/index.ts @@ -8,6 +8,11 @@ export * as Api from "./Api.js" */ export * as ApiBuilder from "./ApiBuilder.js" +/** + * @since 1.0.0 + */ +export * as ApiClient from "./ApiClient.js" + /** * @since 1.0.0 */ @@ -23,6 +28,11 @@ export * as ApiError from "./ApiError.js" */ export * as ApiGroup from "./ApiGroup.js" +/** + * @since 1.0.0 + */ +export * as ApiReflection from "./ApiReflection.js" + /** * @since 1.0.0 */ From 7844acab895c26578e5da34d946931430cbde0dc Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 23 Aug 2024 21:56:38 +1200 Subject: [PATCH 16/59] client wip --- packages/platform-node/examples/api.ts | 24 +++++++-------- packages/platform/src/ApiClient.ts | 42 ++++++++++++++++++++------ 2 files changed, 44 insertions(+), 22 deletions(-) diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index ed82d01b42..ca9b6a5fad 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -4,13 +4,13 @@ import { ApiClient, ApiEndpoint, ApiGroup, + ApiSchema, ApiSecurity, HttpClient, - HttpClientRequest, HttpMiddleware, HttpServer } from "@effect/platform" -import { NodeHttpClient, NodeHttpServer, NodeRuntime } from "@effect/platform-node" +import { NodeHttpServer, NodeRuntime } from "@effect/platform-node" import { Schema } from "@effect/schema" import { Context, Effect, Layer } from "effect" import { createServer } from "node:http" @@ -24,7 +24,7 @@ class CurrentUser extends Context.Tag("CurrentUser")() {} class Unauthorized extends Schema.TaggedError()("Unauthorized", { message: Schema.String -}) {} +}, ApiSchema.annotations({ status: 401 })) {} const security = ApiSecurity.bearer() @@ -57,11 +57,12 @@ const users = ApiGroup.make("users").pipe( ApiEndpoint.success(User) ) ), - ApiGroup.addError(Unauthorized, { status: 401 }) + ApiGroup.addError(Unauthorized), + ApiGroup.prefix("/users") ) const api = Api.empty.pipe( - Api.addGroup("/users", users) + Api.addGroup(users) ) const UsersLive = ApiBuilder.group(api, "users", (handlers) => @@ -95,15 +96,12 @@ ApiBuilder.serve(api, HttpMiddleware.logger).pipe( Effect.gen(function*() { yield* Effect.sleep(2000) - const client = yield* ApiClient.make(api) - const user = yield* client.users.me() + const client = yield* ApiClient.make(api, { + baseUrl: "http://localhost:3000" + }) + const user = yield* client.users.findById({ path: { id: 123 } }) console.log(user) }).pipe( - Effect.provideService( - HttpClient.HttpClient, - HttpClient.fetch.pipe( - HttpClient.mapRequest(HttpClientRequest.prependUrl("http://localhost:3000")) - ) - ), + Effect.provide(HttpClient.layer), NodeRuntime.runMain ) diff --git a/packages/platform/src/ApiClient.ts b/packages/platform/src/ApiClient.ts index ae428e86c0..2518383e7a 100644 --- a/packages/platform/src/ApiClient.ts +++ b/packages/platform/src/ApiClient.ts @@ -4,6 +4,7 @@ import * as Schema from "@effect/schema/Schema" import * as Context from "effect/Context" import * as Effect from "effect/Effect" +import { identity } from "effect/Function" import * as Option from "effect/Option" import type { Simplify } from "effect/Types" import { unify } from "effect/Unify" @@ -40,11 +41,18 @@ export type Client = [A] extends [Api( - api: A + api: A, + options?: { + readonly transformClient?: ((client: HttpClient.HttpClient.Default) => HttpClient.HttpClient.Default) | undefined + readonly baseUrl?: string | undefined + } ): Effect.Effect>, never, Api.Context | HttpClient.HttpClient.Default> => Effect.gen(function*() { const context = yield* Effect.context() - const httpClient = yield* HttpClient.HttpClient + const httpClient = (yield* HttpClient.HttpClient).pipe( + options?.baseUrl === undefined ? identity : HttpClient.mapRequest(HttpClientRequest.prependUrl(options.baseUrl)), + options?.transformClient === undefined ? identity : options.transformClient + ) const client: Record> = {} reflect(api as any, { mode: "full", @@ -52,6 +60,7 @@ export const make = ( client[group.name] = {} }, onEndpoint({ endpoint, errors, group, success }) { + const makeUrl = compilePath(endpoint.path) const handleSuccess = unify(Option.match(success[0], { onNone: () => HttpClientResponse.void, onSome: (ast) => HttpClientResponse.schemaBodyJsonScoped(Schema.make(ast)) @@ -84,13 +93,7 @@ export const make = ( readonly path: any readonly payload: any }) => { - // TODO: make more efficient - let url: string = endpoint.path - if (request && request.path) { - for (const key in request.path) { - url = url.replace(new RegExp(`:${key}\\b`), request.path[key]) - } - } + const url = request && request.path ? makeUrl(request && request.path) : endpoint.path const baseRequest = HttpClientRequest.make(endpoint.method)(url) return (encodePayload._tag === "Some" ? encodePayload.value(request.payload).pipe( @@ -118,3 +121,24 @@ export const make = ( }) return client as any }) + +const paramsRegex = /:(\w+)[^/]*/g + +const compilePath = (path: string) => { + const segments = path.split(paramsRegex) + const len = segments.length + if (len === 1) { + return (_: any) => path + } + return (params: Record) => { + let url = segments[0] + for (let i = 1; i < len; i++) { + if (i % 2 === 0) { + url += segments[i] + } else { + url += params[segments[i]] + } + } + return url + } +} From 1ee320b08e9c5b3217238d65ec5292a8b62d4d45 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 23 Aug 2024 22:12:22 +1200 Subject: [PATCH 17/59] don't refail ParseError --- packages/platform/src/ApiClient.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/platform/src/ApiClient.ts b/packages/platform/src/ApiClient.ts index 2518383e7a..8faeb002cc 100644 --- a/packages/platform/src/ApiClient.ts +++ b/packages/platform/src/ApiClient.ts @@ -83,7 +83,14 @@ export const make = ( return response.json.pipe( Effect.flatMap(decode), Effect.matchEffect({ - onFailure: Effect.die, + onFailure: () => + Effect.die( + new HttpClientError.ResponseError({ + reason: "Decode", + request, + response + }) + ), onSuccess: Effect.fail }) ) From 5d13a63b9d8f9398e239520b7c27f8c433dc39a2 Mon Sep 17 00:00:00 2001 From: Tim Date: Sat, 24 Aug 2024 00:22:13 +1200 Subject: [PATCH 18/59] use Redacted for ApiSecurity --- packages/platform-node/examples/api.ts | 4 ++-- packages/platform/src/ApiBuilder.ts | 11 ++++++----- packages/platform/src/ApiSecurity.ts | 7 ++++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index ca9b6a5fad..75127c6053 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -12,7 +12,7 @@ import { } from "@effect/platform" import { NodeHttpServer, NodeRuntime } from "@effect/platform-node" import { Schema } from "@effect/schema" -import { Context, Effect, Layer } from "effect" +import { Context, Effect, Layer, Redacted } from "effect" import { createServer } from "node:http" class User extends Schema.Class("User")({ @@ -31,7 +31,7 @@ const security = ApiSecurity.bearer() const securityMiddleware = ApiBuilder.middlewareSecurity( security, CurrentUser, - (token) => Effect.succeed(new User({ id: 1000, name: `Authenticated with ${token}` })) + (token) => Effect.succeed(new User({ id: 1000, name: `Authenticated with ${Redacted.value(token)}` })) ) const users = ApiGroup.make("users").pipe( diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index a152ea7c9a..7de15691cd 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -14,6 +14,7 @@ import * as Layer from "effect/Layer" import * as Option from "effect/Option" import { type Pipeable, pipeArguments } from "effect/Pipeable" import type { ReadonlyRecord } from "effect/Record" +import * as Redacted from "effect/Redacted" import type { Scope } from "effect/Scope" import type { Covariant, Mutable, NoInfer } from "effect/Types" import { unify } from "effect/Unify" @@ -478,7 +479,7 @@ export const securityDecode = ( const prefixLen = `${self.prefix} `.length return Effect.map( HttpServerRequest.HttpServerRequest, - (request) => (request.headers.authorization ?? "").slice(prefixLen) as any + (request) => Redacted.make((request.headers.authorization ?? "").slice(prefixLen)) as any ) } case "ApiKey": { @@ -491,14 +492,14 @@ export const securityDecode = ( : HttpServerRequest.schemaHeaders(schema) ) return Effect.match(decode, { - onFailure: () => "" as any, - onSuccess: (match) => match[self.key] + onFailure: () => Redacted.make("") as any, + onSuccess: (match) => Redacted.make(match[self.key]) }) } case "Basic": { const empty: ApiSecurity.ApiSecurity.Type = { username: "", - password: "" + password: Redacted.make("") } as any return HttpServerRequest.HttpServerRequest.pipe( Effect.flatMap((request) => Encoding.decodeBase64String(request.headers.authorization ?? "")), @@ -511,7 +512,7 @@ export const securityDecode = ( } return { username: parts[0], - password: parts[1] + password: Redacted.make(parts[1]) } as any } }) diff --git a/packages/platform/src/ApiSecurity.ts b/packages/platform/src/ApiSecurity.ts index c63f56e17d..5409a73c89 100644 --- a/packages/platform/src/ApiSecurity.ts +++ b/packages/platform/src/ApiSecurity.ts @@ -4,6 +4,7 @@ import * as Context from "effect/Context" import { dual } from "effect/Function" import { type Pipeable, pipeArguments } from "effect/Pipeable" +import type { Redacted } from "effect/Redacted" import type { Covariant } from "effect/Types" /** @@ -51,7 +52,7 @@ export declare namespace ApiSecurity { * @since 1.0.0 * @category models */ -export interface Bearer extends ApiSecurity.Proto { +export interface Bearer extends ApiSecurity.Proto { readonly _tag: "Bearer" readonly prefix: string } @@ -60,7 +61,7 @@ export interface Bearer extends ApiSecurity.Proto { * @since 1.0.0 * @category models */ -export interface ApiKey extends ApiSecurity.Proto { +export interface ApiKey extends ApiSecurity.Proto { readonly _tag: "ApiKey" readonly in: "header" | "query" readonly key: string @@ -80,7 +81,7 @@ export interface Basic extends ApiSecurity.Proto { */ export interface Credentials { readonly username: string - readonly password: string + readonly password: Redacted } const Proto = { From bf8f5a838b265adb38580590fb7933591f2d9ce0 Mon Sep 17 00:00:00 2001 From: Tim Date: Sat, 24 Aug 2024 16:31:35 +1200 Subject: [PATCH 19/59] add OpenApi types --- packages/platform/src/OpenApi.ts | 337 ++++++++++++++++++++++++++++++- 1 file changed, 335 insertions(+), 2 deletions(-) diff --git a/packages/platform/src/OpenApi.ts b/packages/platform/src/OpenApi.ts index bf2986d06b..a94c1e2f7b 100644 --- a/packages/platform/src/OpenApi.ts +++ b/packages/platform/src/OpenApi.ts @@ -1,16 +1,23 @@ /** * @since 1.0.0 */ +import type * as JSONSchema from "@effect/schema/JSONSchema" import * as Context from "effect/Context" import { dual } from "effect/Function" +import type { ReadonlyRecord } from "effect/Record" import type { ApiSecurity } from "./ApiSecurity.js" /** * @since 1.0.0 * @category annotations */ -export class Title extends Context.Tag("@effect/platform/OpenApi/Title")() { -} +export class Title extends Context.Tag("@effect/platform/OpenApi/Title")() {} + +/** + * @since 1.0.0 + * @category annotations + */ +export class Version extends Context.Tag("@effect/platform/OpenApi/Version")() {} /** * @since 1.0.0 @@ -18,12 +25,26 @@ export class Title extends Context.Tag("@effect/platform/OpenApi/Title")() {} +/** + * @since 1.0.0 + * @category annotations + */ +export class License extends Context.Tag("@effect/platform/OpenApi/License")() {} + /** * @since 1.0.0 * @category annotations */ export class Security extends Context.Tag("@effect/platform/OpenApi/Security")() {} +/** + * @since 1.0.0 + * @category annotations + */ +export class ExternalDocs + extends Context.Tag("@effect/platform/OpenApi/ExternalDocs")() +{} + /** * @since 1.0.0 * @category annotations @@ -31,7 +52,10 @@ export class Security extends Context.Tag("@effect/platform/OpenApi/Security") => { let context = Context.empty() if (annotations.title !== undefined) { @@ -40,9 +64,18 @@ export const annotations = (annotations: { if (annotations.description !== undefined) { context = Context.add(context, Description, annotations.description) } + if (annotations.version !== undefined) { + context = Context.add(context, Version, annotations.version) + } + if (annotations.license !== undefined) { + context = Context.add(context, License, annotations.license) + } if (annotations.security !== undefined) { context = Context.add(context, Security, annotations.security) } + if (annotations.externalDocs !== undefined) { + context = Context.add(context, ExternalDocs, annotations.externalDocs) + } return context } @@ -62,17 +95,26 @@ export const annotate: { (annotations: { readonly title?: string | undefined readonly description?: string | undefined + readonly version?: string | undefined + readonly license?: OpenAPISpecLicense | undefined readonly security?: ApiSecurity | undefined + readonly externalDocs?: OpenAPISpecExternalDocs | undefined }): (self: A) => A (self: A, annotations: { readonly title?: string | undefined readonly description?: string | undefined + readonly version?: string | undefined + readonly license?: OpenAPISpecLicense | undefined readonly security?: ApiSecurity | undefined + readonly externalDocs?: OpenAPISpecExternalDocs | undefined }): A } = dual(2, (self: A, annotations_: { readonly title?: string | undefined readonly description?: string | undefined + readonly version?: string | undefined + readonly license?: OpenAPISpecLicense | undefined readonly security?: ApiSecurity | undefined + readonly externalDocs?: OpenAPISpecExternalDocs | undefined }): A => { const context = Context.merge( self.annotations, @@ -82,3 +124,294 @@ export const annotate: { annotations: context }) }) + +/** + * @category models + * @since 1.0.0 + */ +export interface OpenAPISpec { + readonly openapi: "3.0.3" + readonly info: OpenAPISpecInfo + readonly servers?: Array + readonly paths: OpenAPISpecPaths + readonly components?: OpenAPIComponents + readonly security?: Array + readonly tags?: Array + readonly externalDocs?: OpenAPISpecExternalDocs +} + +/** + * @category models + * @since 1.0.0 + */ +export interface OpenAPISpecInfo { + readonly title: string + readonly version: string + readonly description?: string + readonly license?: OpenAPISpecLicense +} + +/** + * @category models + * @since 1.0.0 + */ +export interface OpenAPISpecTag { + readonly name: string + readonly description?: string + readonly externalDocs?: OpenAPISpecExternalDocs +} + +/** + * @category models + * @since 1.0.0 + */ +export interface OpenAPISpecExternalDocs { + readonly url: string + readonly description?: string +} + +/** + * @category models + * @since 1.0.0 + */ +export interface OpenAPISpecLicense { + readonly name: string + readonly url?: string +} + +/** + * @category models + * @since 1.0.0 + */ +export interface OpenAPISpecServer { + readonly url: string + readonly description?: string + readonly variables?: Record +} + +/** + * @category models + * @since 1.0.0 + */ +export interface OpenAPISpecServerVariable { + readonly default: string + readonly enum?: [string, ...Array] + readonly description?: string +} + +/** + * @category models + * @since 1.0.0 + */ +export type OpenAPISpecPaths = ReadonlyRecord< + string, + OpenAPISpecPathItem +> + +/** + * @category models + * @since 1.0.0 + */ +export type OpenAPISpecMethodName = + | "get" + | "put" + | "post" + | "delete" + | "options" + | "head" + | "patch" + | "trace" + +/** + * @category models + * @since 1.0.0 + */ +export type OpenAPISpecPathItem = + & { + readonly [K in OpenAPISpecMethodName]?: OpenAPISpecOperation + } + & { + readonly summary?: string + readonly description?: string + readonly parameters?: Array + } + +/** + * @category models + * @since 1.0.0 + */ +export interface OpenAPISpecParameter { + readonly name: string + readonly in: "query" | "header" | "path" | "cookie" + readonly schema: JSONSchema.JsonSchema7 + readonly description?: string + readonly required?: boolean + readonly deprecated?: boolean + readonly allowEmptyValue?: boolean +} + +/** + * @category models + * @since 1.0.0 + */ +export type OpenAPISpecResponses = Record + +/** + * @category models + * @since 1.0.0 + */ +export type OpenApiSpecContentType = "application/json" | "application/xml" + +/** + * @category models + * @since 1.0.0 + */ +export type OpenApiSpecContent = { + readonly [K in OpenApiSpecContentType]?: OpenApiSpecMediaType +} + +/** + * @category models + * @since 1.0.0 + */ +export interface OpenApiSpecResponseHeader { + readonly description?: string + readonly schema: JSONSchema.JsonSchema7 +} + +/** + * @category models + * @since 1.0.0 + */ +export type OpenApiSpecResponseHeaders = ReadonlyRecord< + string, + OpenApiSpecResponseHeader +> + +/** + * @category models + * @since 1.0.0 + */ +export interface OpenApiSpecResponse { + readonly content?: OpenApiSpecContent + readonly headers?: OpenApiSpecResponseHeaders + readonly description: string +} + +/** + * @category models + * @since 1.0.0 + */ +export interface OpenApiSpecMediaType { + readonly schema?: JSONSchema.JsonSchema7 + readonly example?: object + readonly description?: string +} + +/** + * @category models + * @since 1.0.0 + */ +export interface OpenAPISpecRequestBody { + readonly content: OpenApiSpecContent + readonly description?: string + readonly required?: boolean +} + +/** + * @category models + * @since 1.0.0 + */ +export interface OpenAPIComponents { + readonly schemas?: ReadonlyRecord + readonly securitySchemes?: ReadonlyRecord +} + +/** + * @category models + * @since 1.0.0 + */ +export interface OpenAPIHTTPSecurityScheme { + readonly type: "http" + readonly description?: string + readonly scheme: "bearer" | "basic" | string + /* only for scheme: 'bearer' */ + readonly bearerFormat?: string +} + +/** + * @category models + * @since 1.0.0 + */ +export interface OpenAPIApiKeySecurityScheme { + readonly type: "apiKey" + readonly description?: string + readonly name: string + readonly in: "query" | "header" | "cookie" +} + +/** + * @category models + * @since 1.0.0 + */ +export interface OpenAPIMutualTLSSecurityScheme { + readonly type: "mutualTLS" + readonly description?: string +} + +/** + * @category models + * @since 1.0.0 + */ +export interface OpenAPIOAuth2SecurityScheme { + readonly type: "oauth2" + readonly description?: string + readonly flows: ReadonlyRecord< + "implicit" | "password" | "clientCredentials" | "authorizationCode", + ReadonlyRecord + > +} + +/** + * @category models + * @since 1.0.0 + */ +export interface OpenAPIOpenIdConnectSecurityScheme { + readonly type: "openIdConnect" + readonly description?: string + readonly openIdConnectUrl: string +} + +/** + * @category models + * @since 1.0.0 + */ +export type OpenAPISecurityScheme = + | OpenAPIHTTPSecurityScheme + | OpenAPIApiKeySecurityScheme + | OpenAPIMutualTLSSecurityScheme + | OpenAPIOAuth2SecurityScheme + | OpenAPIOpenIdConnectSecurityScheme + +/** + * @category models + * @since 1.0.0 + */ +export type OpenAPISecurityRequirement = ReadonlyRecord> + +/** + * @category models + * @since 1.0.0 + */ +export interface OpenAPISpecOperation { + readonly requestBody?: OpenAPISpecRequestBody + readonly responses?: OpenAPISpecResponses + readonly operationId?: string + readonly description?: string + readonly parameters?: Array + readonly summary?: string + readonly deprecated?: boolean + readonly tags?: Array + readonly security?: Array + readonly externalDocs?: OpenAPISpecExternalDocs +} From 98fc51169428083409c1c5ed47c3afe41709e935 Mon Sep 17 00:00:00 2001 From: Tim Smart Date: Sat, 24 Aug 2024 12:47:47 +1200 Subject: [PATCH 20/59] fix example --- packages/platform/src/ApiBuilder.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index 7de15691cd..452653c2bc 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -530,7 +530,7 @@ export const securityDecode = ( * @example * import { ApiBuilder, ApiSecurity } from "@effect/platform" * import { Schema } from "@effect/schema" - * import { Context, Effect } from "effect" + * import { Context, Effect, Redacted } from "effect" * * class User extends Schema.Class("User")({ * id: Schema.Number @@ -549,7 +549,7 @@ export const securityDecode = ( * return ApiBuilder.middlewareSecurity( * security, * CurrentUser, - * (token) => accounts.findUserByAccessToken(token) + * (token) => accounts.findUserByAccessToken(Redacted.value(token)) * ) * }) */ From 42b75cd3ee5a91430d6633969fb82b40eb2ebdf8 Mon Sep 17 00:00:00 2001 From: Tim Date: Sat, 24 Aug 2024 18:33:19 +1200 Subject: [PATCH 21/59] wip client types --- packages/platform/src/ApiClient.ts | 28 ++++++++++++++++++++-------- packages/platform/src/ApiEndpoint.ts | 6 +++--- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/packages/platform/src/ApiClient.ts b/packages/platform/src/ApiClient.ts index 8faeb002cc..6232f25b25 100644 --- a/packages/platform/src/ApiClient.ts +++ b/packages/platform/src/ApiClient.ts @@ -23,14 +23,24 @@ import * as HttpMethod from "./HttpMethod.js" * @category models */ export type Client = [A] extends [Api] ? { - readonly [GroupName in _Groups["name"]]: ApiGroup.WithName<_Groups, GroupName> extends - ApiGroup ? { - readonly [Name in _Endpoints["name"]]: ( - request: Simplify>> - ) => Effect.Effect< - ApiEndpoint.SuccessWithName<_Endpoints, Name>, - ApiEndpoint.ErrorWithName<_Endpoints, Name> | _GroupError | _ApiError - > + readonly [GroupName in _Groups["name"]]: [ApiGroup.WithName<_Groups, GroupName>] extends + [ApiGroup] ? { + readonly [Name in _Endpoints["name"]]: [ApiEndpoint.WithName<_Endpoints, Name>] extends [ + ApiEndpoint< + Name, + infer _Method, + infer _Path, + infer _Payload, + Schema.Schema, + Schema.Schema + > + ] ? ( + request: Simplify> + ) => Effect.Effect< + _Success, + _Error | _GroupError | _ApiError + > : + never } : never } : @@ -129,6 +139,8 @@ export const make = ( return client as any }) +// ---------------------------------------------------------------------------- + const paramsRegex = /:(\w+)[^/]*/g const compilePath = (path: string) => { diff --git a/packages/platform/src/ApiEndpoint.ts b/packages/platform/src/ApiEndpoint.ts index af50367fa3..16b8e29b41 100644 --- a/packages/platform/src/ApiEndpoint.ts +++ b/packages/platform/src/ApiEndpoint.ts @@ -131,9 +131,9 @@ export declare namespace ApiEndpoint { * @since 1.0.0 * @category models */ - export type ClientRequest = ( - & ([Endpoint["pathSchema"]] extends [Option.Option] ? {} : { readonly path: PathParsed }) - & ([Payload] extends [infer P] ? [P] extends [never] ? {} : { readonly payload: P } : {}) + export type ClientRequest = ( + & ([Path] extends [PathParams] ? {} : { readonly path: Schema.Schema.Type }) + & ([Schema.Schema.Type] extends [infer P] ? [P] extends [never] ? {} : { readonly payload: P } : {}) ) extends infer Req ? keyof Req extends never ? void : Req : void /** From e0241ad976e54e71c9bfda5434eaf2a0d728f10b Mon Sep 17 00:00:00 2001 From: Tim Date: Sat, 24 Aug 2024 20:35:44 +1200 Subject: [PATCH 22/59] Simplify types --- packages/platform/src/ApiBuilder.ts | 14 +- packages/platform/src/ApiClient.ts | 8 +- packages/platform/src/ApiEndpoint.ts | 331 ++++++++++++++----------- packages/platform/src/ApiGroup.ts | 28 +-- packages/platform/src/ApiReflection.ts | 25 +- 5 files changed, 213 insertions(+), 193 deletions(-) diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index 452653c2bc..7b646df78b 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -121,12 +121,12 @@ export type HandlersTypeId = typeof HandlersTypeId export interface Handlers< E, R, - Endpoints extends ApiEndpoint.ApiEndpoint.Any = never + Endpoints extends ApiEndpoint.ApiEndpoint.All = never > extends Pipeable { readonly [HandlersTypeId]: { _Endpoints: Covariant } - readonly group: ApiGroup.ApiGroup + readonly group: ApiGroup.ApiGroup readonly handlers: Chunk.Chunk> } @@ -164,9 +164,9 @@ const HandlersProto = { } } -const makeHandlers = ( +const makeHandlers = ( options: { - readonly group: ApiGroup.ApiGroup + readonly group: ApiGroup.ApiGroup readonly handlers: Chunk.Chunk> } ): Handlers => { @@ -232,7 +232,7 @@ export const group = < * @since 1.0.0 * @category handlers */ -export const handle = ( +export const handle = ( name: Name, handler: ApiEndpoint.ApiEndpoint.HandlerWithName ) => @@ -270,7 +270,7 @@ export const handle = (middleware: Handlers.Middleware) => - ( + ( self: Handlers ): Handlers, Endpoints> => makeHandlers, Endpoints>({ @@ -458,7 +458,7 @@ export const middlewareCors = ( * @category middleware */ export interface SecurityMiddleware { - ( + ( self: Handlers ): Handlers | ApiEndpoint.ApiEndpoint.ExcludeProvided, Endpoints> } diff --git a/packages/platform/src/ApiClient.ts b/packages/platform/src/ApiClient.ts index 6232f25b25..8c9f306b2d 100644 --- a/packages/platform/src/ApiClient.ts +++ b/packages/platform/src/ApiClient.ts @@ -31,8 +31,9 @@ export type Client = [A] extends [Api, - Schema.Schema + infer _Success, + infer _Error, + infer _R > ] ? ( request: Simplify> @@ -65,7 +66,6 @@ export const make = ( ) const client: Record> = {} reflect(api as any, { - mode: "full", onGroup({ group }) { client[group.name] = {} }, @@ -117,7 +117,7 @@ export const make = ( Effect.flatMap((payload) => HttpMethod.hasBody(endpoint.method) ? HttpClientRequest.jsonBody(baseRequest, payload) - : Effect.succeed(HttpClientRequest.setUrlParams(baseRequest, payload)) + : Effect.succeed(HttpClientRequest.setUrlParams(baseRequest, payload as any)) ), Effect.orDie ) : diff --git a/packages/platform/src/ApiEndpoint.ts b/packages/platform/src/ApiEndpoint.ts index 16b8e29b41..6cc5934166 100644 --- a/packages/platform/src/ApiEndpoint.ts +++ b/packages/platform/src/ApiEndpoint.ts @@ -50,19 +50,20 @@ export const isApiEndpoint = (u: unknown): u is ApiEndpoint => Pr export interface ApiEndpoint< out Name extends string, out Method extends HttpMethod, - out Path extends Schema.Schema.Any = PathParams, - out Payload extends Schema.Schema.All = typeof Schema.Never, - out Success extends Schema.Schema.Any = Empty, - out Error extends Schema.Schema.All = typeof Schema.Never + in out Path = never, + in out Payload = never, + in out Success = void, + in out Error = never, + out R = never > extends Pipeable { readonly [TypeId]: TypeId readonly name: Name readonly path: HttpRouter.PathInput readonly method: Method - readonly pathSchema: Option.Option - readonly payloadSchema: Option.Option - readonly successSchema: Success - readonly errorSchema: Error + readonly pathSchema: Option.Option> + readonly payloadSchema: Option.Option> + readonly successSchema: Schema.Schema + readonly errorSchema: Schema.Schema readonly annotations: Context.Context } @@ -81,49 +82,74 @@ export declare namespace ApiEndpoint { * @since 1.0.0 * @category models */ - export type Any = ApiEndpoint + export interface Any extends Pipeable { + readonly [TypeId]: TypeId + readonly name: string + readonly path: HttpRouter.PathInput + readonly method: HttpMethod + readonly pathSchema: Option.Option + readonly payloadSchema: Option.Option + readonly successSchema: Schema.Schema.Any + readonly errorSchema: Schema.Schema.Any + readonly annotations: Context.Context + } /** * @since 1.0.0 * @category models */ - export type Success = Endpoint extends - ApiEndpoint - ? Schema.Schema.Type<_Success> + export interface All extends Pipeable { + readonly [TypeId]: TypeId + readonly name: string + readonly path: HttpRouter.PathInput + readonly method: HttpMethod + readonly pathSchema: Option.Option + readonly payloadSchema: Option.Option + readonly successSchema: Schema.Schema.Any + readonly errorSchema: Schema.Schema.All + readonly annotations: Context.Context + } + + /** + * @since 1.0.0 + * @category models + */ + export type Success = Endpoint extends + ApiEndpoint ? + _Success : never /** * @since 1.0.0 * @category models */ - export type Error = Endpoint extends - ApiEndpoint - ? Schema.Schema.Type<_Error> + export type Error = Endpoint extends + ApiEndpoint ? + _Error : never /** * @since 1.0.0 * @category models */ - export type PathParsed = Endpoint extends - ApiEndpoint - ? Schema.Schema.Type<_Path> + export type PathParsed = Endpoint extends + ApiEndpoint ? _Path : never /** * @since 1.0.0 * @category models */ - export type Payload = Endpoint extends - ApiEndpoint - ? Schema.Schema.Type<_Payload> + export type Payload = Endpoint extends + ApiEndpoint ? + _Payload : never /** * @since 1.0.0 * @category models */ - export type Request = { + export type Request = { readonly path: PathParsed } & ([Payload] extends [infer P] ? [P] extends [never] ? {} : { readonly payload: P } : {}) @@ -132,8 +158,8 @@ export declare namespace ApiEndpoint { * @category models */ export type ClientRequest = ( - & ([Path] extends [PathParams] ? {} : { readonly path: Schema.Schema.Type }) - & ([Schema.Schema.Type] extends [infer P] ? [P] extends [never] ? {} : { readonly payload: P } : {}) + & ([Path] extends [void] ? {} : { readonly path: Path }) + & ([Payload] extends [never] ? {} : { readonly payload: Payload }) ) extends infer Req ? keyof Req extends never ? void : Req : void /** @@ -141,18 +167,14 @@ export declare namespace ApiEndpoint { * @category models */ export type Context = Endpoint extends - ApiEndpoint ? - | Schema.Schema.Context<_Path> - | Schema.Schema.Context<_Payload> - | Schema.Schema.Context<_Success> - | Schema.Schema.Context<_Error> + ApiEndpoint ? _R : never /** * @since 1.0.0 * @category models */ - export type Handler = ( + export type Handler = ( request: Types.Simplify> ) => Effect, E, R> @@ -160,7 +182,7 @@ export declare namespace ApiEndpoint { * @since 1.0.0 * @category models */ - export type WithName = Endpoints extends infer Endpoint + export type WithName = Endpoints extends infer Endpoint ? Endpoint extends { readonly name: Name } ? Endpoint : never : never @@ -168,13 +190,13 @@ export declare namespace ApiEndpoint { * @since 1.0.0 * @category models */ - export type ExcludeName = Exclude + export type ExcludeName = Exclude /** * @since 1.0.0 * @category models */ - export type HandlerWithName = Handler< + export type HandlerWithName = Handler< WithName, E, R @@ -184,13 +206,13 @@ export declare namespace ApiEndpoint { * @since 1.0.0 * @category models */ - export type SuccessWithName = Success> + export type SuccessWithName = Success> /** * @since 1.0.0 * @category models */ - export type ErrorWithName = Error> + export type ErrorWithName = Error> /** * @since 1.0.0 @@ -233,20 +255,21 @@ const Proto = { const makeProto = < Name extends string, Method extends HttpMethod, - Path extends Schema.Schema.Any, - Payload extends Schema.Schema.All, - Success extends Schema.Schema.Any, - Error extends Schema.Schema.All + Path, + Payload, + Success, + Error, + R >(options: { readonly name: Name readonly path: HttpRouter.PathInput readonly method: Method - readonly pathSchema: Option.Option - readonly payloadSchema: Option.Option - readonly successSchema: Success - readonly errorSchema: Error + readonly pathSchema: Option.Option> + readonly payloadSchema: Option.Option> + readonly successSchema: Schema.Schema + readonly errorSchema: Schema.Schema readonly annotations: Context.Context -}): ApiEndpoint => Object.assign(Object.create(Proto), options) +}): ApiEndpoint => Object.assign(Object.create(Proto), options) /** * @since 1.0.0 @@ -263,8 +286,8 @@ export const make = (method: Method) => method, pathSchema: Option.none(), payloadSchema: Option.none(), - successSchema: Empty, - errorSchema: Schema.Never, + successSchema: Empty as any, + errorSchema: Schema.Never as any, annotations: Context.empty() }) @@ -284,9 +307,7 @@ export const get: ( export const post: ( name: Name, path: HttpRouter.PathInput -) => ApiEndpoint = make( - "POST" -) +) => ApiEndpoint = make("POST") /** * @since 1.0.0 @@ -295,9 +316,7 @@ export const post: ( export const put: ( name: Name, path: HttpRouter.PathInput -) => ApiEndpoint = make( - "PUT" -) +) => ApiEndpoint = make("PUT") /** * @since 1.0.0 @@ -306,9 +325,7 @@ export const put: ( export const patch: ( name: Name, path: HttpRouter.PathInput -) => ApiEndpoint = make( - "PATCH" -) +) => ApiEndpoint = make("PATCH") /** * @since 1.0.0 @@ -317,9 +334,7 @@ export const patch: ( export const del: ( name: Name, path: HttpRouter.PathInput -) => ApiEndpoint = make( - "DELETE" -) +) => ApiEndpoint = make("DELETE") type Void$ = typeof Schema.Void @@ -384,50 +399,53 @@ export const success: { ): < Name extends string, Method extends HttpMethod, - _Path extends Schema.Schema.Any, - _P extends Schema.Schema.All, - _S extends Schema.Schema.Any, - _E extends Schema.Schema.All + _Path, + _P, + _S, + _E, + _R >( - self: ApiEndpoint - ) => ApiEndpoint + self: ApiEndpoint + ) => ApiEndpoint, _E, _R | Schema.Schema.Context> < Name extends string, Method extends HttpMethod, - _Path extends Schema.Schema.Any, - _P extends Schema.Schema.All, - _S extends Schema.Schema.Any, - _E extends Schema.Schema.All, + _Path, + _P, + _S, + _E, + _R, S extends Schema.Schema.Any >( - self: ApiEndpoint, + self: ApiEndpoint, schema: S, annotations?: { readonly status?: number | undefined } - ): ApiEndpoint + ): ApiEndpoint, _E, _R | Schema.Schema.Context> } = dual( (args) => isApiEndpoint(args[0]), < Name extends string, Method extends HttpMethod, - _Path extends Schema.Schema.Any, - _P extends Schema.Schema.All, - _S extends Schema.Schema.Any, - _E extends Schema.Schema.All, + _Path, + _P, + _S, + _E, + _R, S extends Schema.Schema.Any >( - self: ApiEndpoint, + self: ApiEndpoint, schema: S, annotations?: { readonly status?: number | undefined } - ): ApiEndpoint => + ): ApiEndpoint, _E, _R | Schema.Schema.Context> => makeProto({ - ...self, + ...self as any, successSchema: schema.annotations(ApiSchema.annotations({ status: annotations?.status ?? ApiSchema.getStatusSuccess(schema) - })) as S + })) }) ) @@ -444,52 +462,55 @@ export const error: { ): < Name extends string, Method extends HttpMethod, - _Path extends Schema.Schema.Any, - _P extends Schema.Schema.All, - _S extends Schema.Schema.Any, - _E extends Schema.Schema.All + _Path, + _P, + _S, + _E, + _R >( - self: ApiEndpoint - ) => ApiEndpoint + self: ApiEndpoint + ) => ApiEndpoint, _R | Schema.Schema.Context> < Name extends string, Method extends HttpMethod, - _Path extends Schema.Schema.Any, - _P extends Schema.Schema.All, - _S extends Schema.Schema.Any, - _E extends Schema.Schema.All, + _Path, + _P, + _S, + _E, + _R, E extends Schema.Schema.All >( - self: ApiEndpoint, + self: ApiEndpoint, schema: E, annotations?: { readonly status?: number | undefined } - ): ApiEndpoint + ): ApiEndpoint, _R | Schema.Schema.Context> } = dual( (args) => isApiEndpoint(args[0]), < Name extends string, Method extends HttpMethod, - _Path extends Schema.Schema.Any, - _P extends Schema.Schema.All, - _S extends Schema.Schema.Any, - _E extends Schema.Schema.All, + _Path, + _P, + _S, + _E, + _R, E extends Schema.Schema.All >( - self: ApiEndpoint, + self: ApiEndpoint, schema: E, annotations?: { readonly status?: number | undefined } - ): ApiEndpoint => + ): ApiEndpoint, _R | Schema.Schema.Context> => makeProto({ - ...self, + ...self as any, errorSchema: schema.pipe( Schema.annotations(ApiSchema.annotations({ status: annotations?.status ?? ApiSchema.getStatusError(schema) })) - ) as E + ) }) ) @@ -502,41 +523,44 @@ export const payload: { schema: P & ApiEndpoint.ValidatePayload ): < Name extends string, - _Path extends Schema.Schema.Any, - _P extends Schema.Schema.All, - _S extends Schema.Schema.Any, - _E extends Schema.Schema.All + _Path, + _P, + _S, + _E, + _R >( - self: ApiEndpoint - ) => ApiEndpoint + self: ApiEndpoint + ) => ApiEndpoint, _S, _E, _R | Schema.Schema.Context

> < Name extends string, Method extends HttpMethod, - _Path extends Schema.Schema.Any, - _P extends Schema.Schema.All, - _S extends Schema.Schema.Any, - _E extends Schema.Schema.All, + _Path, + _P, + _S, + _E, + _R, P extends Schema.Schema.All >( - self: ApiEndpoint, + self: ApiEndpoint, schema: P & ApiEndpoint.ValidatePayload - ): ApiEndpoint + ): ApiEndpoint, _S, _E, _R | Schema.Schema.Context

> } = dual( 2, < Name extends string, Method extends HttpMethod, - _Path extends Schema.Schema.Any, - _P extends Schema.Schema.All, - _S extends Schema.Schema.Any, - _E extends Schema.Schema.All, + _Path, + _P, + _S, + _E, + _R, P extends Schema.Schema.All >( - self: ApiEndpoint, + self: ApiEndpoint, schema: P & ApiEndpoint.ValidatePayload - ): ApiEndpoint => + ): ApiEndpoint, _S, _E, _R | Schema.Schema.Context

+ + +`) + yield* router.get(options?.path ?? "/docs", Effect.succeed(response)) + }) + ) diff --git a/packages/platform/src/OpenApi.ts b/packages/platform/src/OpenApi.ts index faeb06e706..2de0a8bbb0 100644 --- a/packages/platform/src/OpenApi.ts +++ b/packages/platform/src/OpenApi.ts @@ -157,7 +157,25 @@ export const fromApi = (api: A): OpenAPISpec => { version: Context.getOrElse(api.annotations, Version, () => "0.0.1") }, paths: {}, - tags: [] + tags: [], + components: { + schemas: {}, + securitySchemes: {} + }, + security: [] + } + const securityMap = new Map() + let securityCount = 0 + function registerSecurity(security: ApiSecurity): string { + if (securityMap.has(security)) { + return securityMap.get(security)! + } + const count = securityCount++ + const id = `${security._tag}${count === 0 ? "" : count}` + const scheme = makeSecurityScheme(security) + spec.components!.securitySchemes![id] = scheme + securityMap.set(security, id) + return id } Option.map(Context.getOption(api.annotations, Description), (description) => { spec.info.description = description @@ -165,6 +183,11 @@ export const fromApi = (api: A): OpenAPISpec => { Option.map(Context.getOption(api.annotations, License), (license) => { spec.info.license = license }) + Option.map(Context.getOption(api.annotations, Security), (apiSecurity) => { + spec.security!.push({ + [registerSecurity(apiSecurity)]: [] + }) + }) Api.reflect(api as any, { onGroup({ group }) { const tag: Mutable = { @@ -178,13 +201,14 @@ export const fromApi = (api: A): OpenAPISpec => { }) spec.tags!.push(tag) }, - onEndpoint({ endpoint, errors, group, success }) { + onEndpoint({ endpoint, errors, group, mergedAnnotations, success }) { const path = endpoint.path.replace(/:(\w+)[^/]*/g, "{$1}") const method = endpoint.method.toLowerCase() as OpenAPISpecMethodName const op: DeepMutable = { tags: [Context.getOrElse(group.annotations, Title, () => group.name)], operationId: Context.getOrElse(endpoint.annotations, Identifier, () => `${group.name}.${endpoint.name}`), parameters: [], + security: [], responses: { [success[1]]: { description: success[0].pipe( @@ -200,6 +224,11 @@ export const fromApi = (api: A): OpenAPISpec => { Option.map(Context.getOption(endpoint.annotations, ExternalDocs), (externalDocs) => { op.externalDocs = externalDocs }) + Option.map(Context.getOption(mergedAnnotations, Security), (apiSecurity) => { + op.security!.push({ + [registerSecurity(apiSecurity)]: [] + }) + }) endpoint.payloadSchema.pipe( Option.filter(() => HttpMethod.hasBody(endpoint.method)), Option.map((schema) => { @@ -281,6 +310,37 @@ const getPropertySignatures = (ast: AST.AST): ReadonlyArray { + const meta: Mutable> = {} + Option.map(Context.getOption(security.annotations, Description), (description) => { + meta.description = description + }) + switch (security._tag) { + case "Basic": { + return { + ...meta, + type: "http", + scheme: "basic" + } + } + case "Bearer": { + return { + ...meta, + type: "http", + scheme: "bearer" + } + } + case "ApiKey": { + return { + ...meta, + type: "apiKey", + name: security.key, + in: security.in + } + } + } +} + const makeProperty = (ps: AST.PropertySignature, type: OpenAPISpecParameter["in"]): OpenAPISpecParameter => { const spec: Mutable = { in: type, diff --git a/packages/platform/src/index.ts b/packages/platform/src/index.ts index 208836c491..f6b1b7e9e5 100644 --- a/packages/platform/src/index.ts +++ b/packages/platform/src/index.ts @@ -38,6 +38,11 @@ export * as ApiSchema from "./ApiSchema.js" */ export * as ApiSecurity from "./ApiSecurity.js" +/** + * @since 1.0.0 + */ +export * as ApiSwagger from "./ApiSwagger.js" + /** * @since 1.0.0 */ diff --git a/packages/platform/src/internal/apiSwagger.ts b/packages/platform/src/internal/apiSwagger.ts new file mode 100644 index 0000000000..f5c6fb51b9 --- /dev/null +++ b/packages/platform/src/internal/apiSwagger.ts @@ -0,0 +1,7 @@ +/* eslint-disable */ + +/** @internal */ +export const javascript = "/*! For license information please see swagger-ui-bundle.js.LICENSE.txt */\n!function webpackUniversalModuleDefinition(o,s){\"object\"==typeof exports&&\"object\"==typeof module?module.exports=s():\"function\"==typeof define&&define.amd?define([],s):\"object\"==typeof exports?exports.SwaggerUIBundle=s():o.SwaggerUIBundle=s()}(this,(()=>(()=>{var o,s,i={69119:(o,s)=>{\"use strict\";Object.defineProperty(s,\"__esModule\",{value:!0}),s.BLANK_URL=s.relativeFirstCharacters=s.whitespaceEscapeCharsRegex=s.urlSchemeRegex=s.ctrlCharactersRegex=s.htmlCtrlEntityRegex=s.htmlEntitiesRegex=s.invalidProtocolRegex=void 0,s.invalidProtocolRegex=/^([^\\w]*)(javascript|data|vbscript)/im,s.htmlEntitiesRegex=/&#(\\w+)(^\\w|;)?/g,s.htmlCtrlEntityRegex=/&(newline|tab);/gi,s.ctrlCharactersRegex=/[\\u0000-\\u001F\\u007F-\\u009F\\u2000-\\u200D\\uFEFF]/gim,s.urlSchemeRegex=/^.+(:|:)/gim,s.whitespaceEscapeCharsRegex=/(\\\\|%5[cC])((%(6[eE]|72|74))|[nrt])/g,s.relativeFirstCharacters=[\".\",\"/\"],s.BLANK_URL=\"about:blank\"},16750:(o,s,i)=>{\"use strict\";s.J=void 0;var u=i(69119);function decodeURI(o){try{return decodeURIComponent(o)}catch(s){return o}}s.J=function sanitizeUrl(o){if(!o)return u.BLANK_URL;var s,i,_=decodeURI(o);do{s=(_=decodeURI(_=(i=_,i.replace(u.ctrlCharactersRegex,\"\").replace(u.htmlEntitiesRegex,(function(o,s){return String.fromCharCode(s)}))).replace(u.htmlCtrlEntityRegex,\"\").replace(u.ctrlCharactersRegex,\"\").replace(u.whitespaceEscapeCharsRegex,\"\").trim())).match(u.ctrlCharactersRegex)||_.match(u.htmlEntitiesRegex)||_.match(u.htmlCtrlEntityRegex)||_.match(u.whitespaceEscapeCharsRegex)}while(s&&s.length>0);var w=_;if(!w)return u.BLANK_URL;if(function isRelativeUrlWithoutProtocol(o){return u.relativeFirstCharacters.indexOf(o[0])>-1}(w))return w;var x=w.match(u.urlSchemeRegex);if(!x)return w;var C=x[0];return u.invalidProtocolRegex.test(C)?u.BLANK_URL:w}},67526:(o,s)=>{\"use strict\";s.byteLength=function byteLength(o){var s=getLens(o),i=s[0],u=s[1];return 3*(i+u)/4-u},s.toByteArray=function toByteArray(o){var s,i,w=getLens(o),x=w[0],C=w[1],j=new _(function _byteLength(o,s,i){return 3*(s+i)/4-i}(0,x,C)),L=0,B=C>0?x-4:x;for(i=0;i>16&255,j[L++]=s>>8&255,j[L++]=255&s;2===C&&(s=u[o.charCodeAt(i)]<<2|u[o.charCodeAt(i+1)]>>4,j[L++]=255&s);1===C&&(s=u[o.charCodeAt(i)]<<10|u[o.charCodeAt(i+1)]<<4|u[o.charCodeAt(i+2)]>>2,j[L++]=s>>8&255,j[L++]=255&s);return j},s.fromByteArray=function fromByteArray(o){for(var s,u=o.length,_=u%3,w=[],x=16383,C=0,j=u-_;Cj?j:C+x));1===_?(s=o[u-1],w.push(i[s>>2]+i[s<<4&63]+\"==\")):2===_&&(s=(o[u-2]<<8)+o[u-1],w.push(i[s>>10]+i[s>>4&63]+i[s<<2&63]+\"=\"));return w.join(\"\")};for(var i=[],u=[],_=\"undefined\"!=typeof Uint8Array?Uint8Array:Array,w=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\",x=0;x<64;++x)i[x]=w[x],u[w.charCodeAt(x)]=x;function getLens(o){var s=o.length;if(s%4>0)throw new Error(\"Invalid string. Length must be a multiple of 4\");var i=o.indexOf(\"=\");return-1===i&&(i=s),[i,i===s?0:4-i%4]}function encodeChunk(o,s,u){for(var _,w,x=[],C=s;C>18&63]+i[w>>12&63]+i[w>>6&63]+i[63&w]);return x.join(\"\")}u[\"-\".charCodeAt(0)]=62,u[\"_\".charCodeAt(0)]=63},48287:(o,s,i)=>{\"use strict\";const u=i(67526),_=i(251),w=\"function\"==typeof Symbol&&\"function\"==typeof Symbol.for?Symbol.for(\"nodejs.util.inspect.custom\"):null;s.Buffer=Buffer,s.SlowBuffer=function SlowBuffer(o){+o!=o&&(o=0);return Buffer.alloc(+o)},s.INSPECT_MAX_BYTES=50;const x=2147483647;function createBuffer(o){if(o>x)throw new RangeError('The value \"'+o+'\" is invalid for option \"size\"');const s=new Uint8Array(o);return Object.setPrototypeOf(s,Buffer.prototype),s}function Buffer(o,s,i){if(\"number\"==typeof o){if(\"string\"==typeof s)throw new TypeError('The \"string\" argument must be of type string. Received type number');return allocUnsafe(o)}return from(o,s,i)}function from(o,s,i){if(\"string\"==typeof o)return function fromString(o,s){\"string\"==typeof s&&\"\"!==s||(s=\"utf8\");if(!Buffer.isEncoding(s))throw new TypeError(\"Unknown encoding: \"+s);const i=0|byteLength(o,s);let u=createBuffer(i);const _=u.write(o,s);_!==i&&(u=u.slice(0,_));return u}(o,s);if(ArrayBuffer.isView(o))return function fromArrayView(o){if(isInstance(o,Uint8Array)){const s=new Uint8Array(o);return fromArrayBuffer(s.buffer,s.byteOffset,s.byteLength)}return fromArrayLike(o)}(o);if(null==o)throw new TypeError(\"The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type \"+typeof o);if(isInstance(o,ArrayBuffer)||o&&isInstance(o.buffer,ArrayBuffer))return fromArrayBuffer(o,s,i);if(\"undefined\"!=typeof SharedArrayBuffer&&(isInstance(o,SharedArrayBuffer)||o&&isInstance(o.buffer,SharedArrayBuffer)))return fromArrayBuffer(o,s,i);if(\"number\"==typeof o)throw new TypeError('The \"value\" argument must not be of type number. Received type number');const u=o.valueOf&&o.valueOf();if(null!=u&&u!==o)return Buffer.from(u,s,i);const _=function fromObject(o){if(Buffer.isBuffer(o)){const s=0|checked(o.length),i=createBuffer(s);return 0===i.length||o.copy(i,0,0,s),i}if(void 0!==o.length)return\"number\"!=typeof o.length||numberIsNaN(o.length)?createBuffer(0):fromArrayLike(o);if(\"Buffer\"===o.type&&Array.isArray(o.data))return fromArrayLike(o.data)}(o);if(_)return _;if(\"undefined\"!=typeof Symbol&&null!=Symbol.toPrimitive&&\"function\"==typeof o[Symbol.toPrimitive])return Buffer.from(o[Symbol.toPrimitive](\"string\"),s,i);throw new TypeError(\"The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type \"+typeof o)}function assertSize(o){if(\"number\"!=typeof o)throw new TypeError('\"size\" argument must be of type number');if(o<0)throw new RangeError('The value \"'+o+'\" is invalid for option \"size\"')}function allocUnsafe(o){return assertSize(o),createBuffer(o<0?0:0|checked(o))}function fromArrayLike(o){const s=o.length<0?0:0|checked(o.length),i=createBuffer(s);for(let u=0;u=x)throw new RangeError(\"Attempt to allocate Buffer larger than maximum size: 0x\"+x.toString(16)+\" bytes\");return 0|o}function byteLength(o,s){if(Buffer.isBuffer(o))return o.length;if(ArrayBuffer.isView(o)||isInstance(o,ArrayBuffer))return o.byteLength;if(\"string\"!=typeof o)throw new TypeError('The \"string\" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof o);const i=o.length,u=arguments.length>2&&!0===arguments[2];if(!u&&0===i)return 0;let _=!1;for(;;)switch(s){case\"ascii\":case\"latin1\":case\"binary\":return i;case\"utf8\":case\"utf-8\":return utf8ToBytes(o).length;case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":return 2*i;case\"hex\":return i>>>1;case\"base64\":return base64ToBytes(o).length;default:if(_)return u?-1:utf8ToBytes(o).length;s=(\"\"+s).toLowerCase(),_=!0}}function slowToString(o,s,i){let u=!1;if((void 0===s||s<0)&&(s=0),s>this.length)return\"\";if((void 0===i||i>this.length)&&(i=this.length),i<=0)return\"\";if((i>>>=0)<=(s>>>=0))return\"\";for(o||(o=\"utf8\");;)switch(o){case\"hex\":return hexSlice(this,s,i);case\"utf8\":case\"utf-8\":return utf8Slice(this,s,i);case\"ascii\":return asciiSlice(this,s,i);case\"latin1\":case\"binary\":return latin1Slice(this,s,i);case\"base64\":return base64Slice(this,s,i);case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":return utf16leSlice(this,s,i);default:if(u)throw new TypeError(\"Unknown encoding: \"+o);o=(o+\"\").toLowerCase(),u=!0}}function swap(o,s,i){const u=o[s];o[s]=o[i],o[i]=u}function bidirectionalIndexOf(o,s,i,u,_){if(0===o.length)return-1;if(\"string\"==typeof i?(u=i,i=0):i>2147483647?i=2147483647:i<-2147483648&&(i=-2147483648),numberIsNaN(i=+i)&&(i=_?0:o.length-1),i<0&&(i=o.length+i),i>=o.length){if(_)return-1;i=o.length-1}else if(i<0){if(!_)return-1;i=0}if(\"string\"==typeof s&&(s=Buffer.from(s,u)),Buffer.isBuffer(s))return 0===s.length?-1:arrayIndexOf(o,s,i,u,_);if(\"number\"==typeof s)return s&=255,\"function\"==typeof Uint8Array.prototype.indexOf?_?Uint8Array.prototype.indexOf.call(o,s,i):Uint8Array.prototype.lastIndexOf.call(o,s,i):arrayIndexOf(o,[s],i,u,_);throw new TypeError(\"val must be string, number or Buffer\")}function arrayIndexOf(o,s,i,u,_){let w,x=1,C=o.length,j=s.length;if(void 0!==u&&(\"ucs2\"===(u=String(u).toLowerCase())||\"ucs-2\"===u||\"utf16le\"===u||\"utf-16le\"===u)){if(o.length<2||s.length<2)return-1;x=2,C/=2,j/=2,i/=2}function read(o,s){return 1===x?o[s]:o.readUInt16BE(s*x)}if(_){let u=-1;for(w=i;wC&&(i=C-j),w=i;w>=0;w--){let i=!0;for(let u=0;u_&&(u=_):u=_;const w=s.length;let x;for(u>w/2&&(u=w/2),x=0;x>8,_=i%256,w.push(_),w.push(u);return w}(s,o.length-i),o,i,u)}function base64Slice(o,s,i){return 0===s&&i===o.length?u.fromByteArray(o):u.fromByteArray(o.slice(s,i))}function utf8Slice(o,s,i){i=Math.min(o.length,i);const u=[];let _=s;for(;_239?4:s>223?3:s>191?2:1;if(_+x<=i){let i,u,C,j;switch(x){case 1:s<128&&(w=s);break;case 2:i=o[_+1],128==(192&i)&&(j=(31&s)<<6|63&i,j>127&&(w=j));break;case 3:i=o[_+1],u=o[_+2],128==(192&i)&&128==(192&u)&&(j=(15&s)<<12|(63&i)<<6|63&u,j>2047&&(j<55296||j>57343)&&(w=j));break;case 4:i=o[_+1],u=o[_+2],C=o[_+3],128==(192&i)&&128==(192&u)&&128==(192&C)&&(j=(15&s)<<18|(63&i)<<12|(63&u)<<6|63&C,j>65535&&j<1114112&&(w=j))}}null===w?(w=65533,x=1):w>65535&&(w-=65536,u.push(w>>>10&1023|55296),w=56320|1023&w),u.push(w),_+=x}return function decodeCodePointsArray(o){const s=o.length;if(s<=C)return String.fromCharCode.apply(String,o);let i=\"\",u=0;for(;uu.length?(Buffer.isBuffer(s)||(s=Buffer.from(s)),s.copy(u,_)):Uint8Array.prototype.set.call(u,s,_);else{if(!Buffer.isBuffer(s))throw new TypeError('\"list\" argument must be an Array of Buffers');s.copy(u,_)}_+=s.length}return u},Buffer.byteLength=byteLength,Buffer.prototype._isBuffer=!0,Buffer.prototype.swap16=function swap16(){const o=this.length;if(o%2!=0)throw new RangeError(\"Buffer size must be a multiple of 16-bits\");for(let s=0;si&&(o+=\" ... \"),\"\"},w&&(Buffer.prototype[w]=Buffer.prototype.inspect),Buffer.prototype.compare=function compare(o,s,i,u,_){if(isInstance(o,Uint8Array)&&(o=Buffer.from(o,o.offset,o.byteLength)),!Buffer.isBuffer(o))throw new TypeError('The \"target\" argument must be one of type Buffer or Uint8Array. Received type '+typeof o);if(void 0===s&&(s=0),void 0===i&&(i=o?o.length:0),void 0===u&&(u=0),void 0===_&&(_=this.length),s<0||i>o.length||u<0||_>this.length)throw new RangeError(\"out of range index\");if(u>=_&&s>=i)return 0;if(u>=_)return-1;if(s>=i)return 1;if(this===o)return 0;let w=(_>>>=0)-(u>>>=0),x=(i>>>=0)-(s>>>=0);const C=Math.min(w,x),j=this.slice(u,_),L=o.slice(s,i);for(let o=0;o>>=0,isFinite(i)?(i>>>=0,void 0===u&&(u=\"utf8\")):(u=i,i=void 0)}const _=this.length-s;if((void 0===i||i>_)&&(i=_),o.length>0&&(i<0||s<0)||s>this.length)throw new RangeError(\"Attempt to write outside buffer bounds\");u||(u=\"utf8\");let w=!1;for(;;)switch(u){case\"hex\":return hexWrite(this,o,s,i);case\"utf8\":case\"utf-8\":return utf8Write(this,o,s,i);case\"ascii\":case\"latin1\":case\"binary\":return asciiWrite(this,o,s,i);case\"base64\":return base64Write(this,o,s,i);case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":return ucs2Write(this,o,s,i);default:if(w)throw new TypeError(\"Unknown encoding: \"+u);u=(\"\"+u).toLowerCase(),w=!0}},Buffer.prototype.toJSON=function toJSON(){return{type:\"Buffer\",data:Array.prototype.slice.call(this._arr||this,0)}};const C=4096;function asciiSlice(o,s,i){let u=\"\";i=Math.min(o.length,i);for(let _=s;_u)&&(i=u);let _=\"\";for(let u=s;ui)throw new RangeError(\"Trying to access beyond buffer length\")}function checkInt(o,s,i,u,_,w){if(!Buffer.isBuffer(o))throw new TypeError('\"buffer\" argument must be a Buffer instance');if(s>_||so.length)throw new RangeError(\"Index out of range\")}function wrtBigUInt64LE(o,s,i,u,_){checkIntBI(s,u,_,o,i,7);let w=Number(s&BigInt(4294967295));o[i++]=w,w>>=8,o[i++]=w,w>>=8,o[i++]=w,w>>=8,o[i++]=w;let x=Number(s>>BigInt(32)&BigInt(4294967295));return o[i++]=x,x>>=8,o[i++]=x,x>>=8,o[i++]=x,x>>=8,o[i++]=x,i}function wrtBigUInt64BE(o,s,i,u,_){checkIntBI(s,u,_,o,i,7);let w=Number(s&BigInt(4294967295));o[i+7]=w,w>>=8,o[i+6]=w,w>>=8,o[i+5]=w,w>>=8,o[i+4]=w;let x=Number(s>>BigInt(32)&BigInt(4294967295));return o[i+3]=x,x>>=8,o[i+2]=x,x>>=8,o[i+1]=x,x>>=8,o[i]=x,i+8}function checkIEEE754(o,s,i,u,_,w){if(i+u>o.length)throw new RangeError(\"Index out of range\");if(i<0)throw new RangeError(\"Index out of range\")}function writeFloat(o,s,i,u,w){return s=+s,i>>>=0,w||checkIEEE754(o,0,i,4),_.write(o,s,i,u,23,4),i+4}function writeDouble(o,s,i,u,w){return s=+s,i>>>=0,w||checkIEEE754(o,0,i,8),_.write(o,s,i,u,52,8),i+8}Buffer.prototype.slice=function slice(o,s){const i=this.length;(o=~~o)<0?(o+=i)<0&&(o=0):o>i&&(o=i),(s=void 0===s?i:~~s)<0?(s+=i)<0&&(s=0):s>i&&(s=i),s>>=0,s>>>=0,i||checkOffset(o,s,this.length);let u=this[o],_=1,w=0;for(;++w>>=0,s>>>=0,i||checkOffset(o,s,this.length);let u=this[o+--s],_=1;for(;s>0&&(_*=256);)u+=this[o+--s]*_;return u},Buffer.prototype.readUint8=Buffer.prototype.readUInt8=function readUInt8(o,s){return o>>>=0,s||checkOffset(o,1,this.length),this[o]},Buffer.prototype.readUint16LE=Buffer.prototype.readUInt16LE=function readUInt16LE(o,s){return o>>>=0,s||checkOffset(o,2,this.length),this[o]|this[o+1]<<8},Buffer.prototype.readUint16BE=Buffer.prototype.readUInt16BE=function readUInt16BE(o,s){return o>>>=0,s||checkOffset(o,2,this.length),this[o]<<8|this[o+1]},Buffer.prototype.readUint32LE=Buffer.prototype.readUInt32LE=function readUInt32LE(o,s){return o>>>=0,s||checkOffset(o,4,this.length),(this[o]|this[o+1]<<8|this[o+2]<<16)+16777216*this[o+3]},Buffer.prototype.readUint32BE=Buffer.prototype.readUInt32BE=function readUInt32BE(o,s){return o>>>=0,s||checkOffset(o,4,this.length),16777216*this[o]+(this[o+1]<<16|this[o+2]<<8|this[o+3])},Buffer.prototype.readBigUInt64LE=defineBigIntMethod((function readBigUInt64LE(o){validateNumber(o>>>=0,\"offset\");const s=this[o],i=this[o+7];void 0!==s&&void 0!==i||boundsError(o,this.length-8);const u=s+256*this[++o]+65536*this[++o]+this[++o]*2**24,_=this[++o]+256*this[++o]+65536*this[++o]+i*2**24;return BigInt(u)+(BigInt(_)<>>=0,\"offset\");const s=this[o],i=this[o+7];void 0!==s&&void 0!==i||boundsError(o,this.length-8);const u=s*2**24+65536*this[++o]+256*this[++o]+this[++o],_=this[++o]*2**24+65536*this[++o]+256*this[++o]+i;return(BigInt(u)<>>=0,s>>>=0,i||checkOffset(o,s,this.length);let u=this[o],_=1,w=0;for(;++w=_&&(u-=Math.pow(2,8*s)),u},Buffer.prototype.readIntBE=function readIntBE(o,s,i){o>>>=0,s>>>=0,i||checkOffset(o,s,this.length);let u=s,_=1,w=this[o+--u];for(;u>0&&(_*=256);)w+=this[o+--u]*_;return _*=128,w>=_&&(w-=Math.pow(2,8*s)),w},Buffer.prototype.readInt8=function readInt8(o,s){return o>>>=0,s||checkOffset(o,1,this.length),128&this[o]?-1*(255-this[o]+1):this[o]},Buffer.prototype.readInt16LE=function readInt16LE(o,s){o>>>=0,s||checkOffset(o,2,this.length);const i=this[o]|this[o+1]<<8;return 32768&i?4294901760|i:i},Buffer.prototype.readInt16BE=function readInt16BE(o,s){o>>>=0,s||checkOffset(o,2,this.length);const i=this[o+1]|this[o]<<8;return 32768&i?4294901760|i:i},Buffer.prototype.readInt32LE=function readInt32LE(o,s){return o>>>=0,s||checkOffset(o,4,this.length),this[o]|this[o+1]<<8|this[o+2]<<16|this[o+3]<<24},Buffer.prototype.readInt32BE=function readInt32BE(o,s){return o>>>=0,s||checkOffset(o,4,this.length),this[o]<<24|this[o+1]<<16|this[o+2]<<8|this[o+3]},Buffer.prototype.readBigInt64LE=defineBigIntMethod((function readBigInt64LE(o){validateNumber(o>>>=0,\"offset\");const s=this[o],i=this[o+7];void 0!==s&&void 0!==i||boundsError(o,this.length-8);const u=this[o+4]+256*this[o+5]+65536*this[o+6]+(i<<24);return(BigInt(u)<>>=0,\"offset\");const s=this[o],i=this[o+7];void 0!==s&&void 0!==i||boundsError(o,this.length-8);const u=(s<<24)+65536*this[++o]+256*this[++o]+this[++o];return(BigInt(u)<>>=0,s||checkOffset(o,4,this.length),_.read(this,o,!0,23,4)},Buffer.prototype.readFloatBE=function readFloatBE(o,s){return o>>>=0,s||checkOffset(o,4,this.length),_.read(this,o,!1,23,4)},Buffer.prototype.readDoubleLE=function readDoubleLE(o,s){return o>>>=0,s||checkOffset(o,8,this.length),_.read(this,o,!0,52,8)},Buffer.prototype.readDoubleBE=function readDoubleBE(o,s){return o>>>=0,s||checkOffset(o,8,this.length),_.read(this,o,!1,52,8)},Buffer.prototype.writeUintLE=Buffer.prototype.writeUIntLE=function writeUIntLE(o,s,i,u){if(o=+o,s>>>=0,i>>>=0,!u){checkInt(this,o,s,i,Math.pow(2,8*i)-1,0)}let _=1,w=0;for(this[s]=255&o;++w>>=0,i>>>=0,!u){checkInt(this,o,s,i,Math.pow(2,8*i)-1,0)}let _=i-1,w=1;for(this[s+_]=255&o;--_>=0&&(w*=256);)this[s+_]=o/w&255;return s+i},Buffer.prototype.writeUint8=Buffer.prototype.writeUInt8=function writeUInt8(o,s,i){return o=+o,s>>>=0,i||checkInt(this,o,s,1,255,0),this[s]=255&o,s+1},Buffer.prototype.writeUint16LE=Buffer.prototype.writeUInt16LE=function writeUInt16LE(o,s,i){return o=+o,s>>>=0,i||checkInt(this,o,s,2,65535,0),this[s]=255&o,this[s+1]=o>>>8,s+2},Buffer.prototype.writeUint16BE=Buffer.prototype.writeUInt16BE=function writeUInt16BE(o,s,i){return o=+o,s>>>=0,i||checkInt(this,o,s,2,65535,0),this[s]=o>>>8,this[s+1]=255&o,s+2},Buffer.prototype.writeUint32LE=Buffer.prototype.writeUInt32LE=function writeUInt32LE(o,s,i){return o=+o,s>>>=0,i||checkInt(this,o,s,4,4294967295,0),this[s+3]=o>>>24,this[s+2]=o>>>16,this[s+1]=o>>>8,this[s]=255&o,s+4},Buffer.prototype.writeUint32BE=Buffer.prototype.writeUInt32BE=function writeUInt32BE(o,s,i){return o=+o,s>>>=0,i||checkInt(this,o,s,4,4294967295,0),this[s]=o>>>24,this[s+1]=o>>>16,this[s+2]=o>>>8,this[s+3]=255&o,s+4},Buffer.prototype.writeBigUInt64LE=defineBigIntMethod((function writeBigUInt64LE(o,s=0){return wrtBigUInt64LE(this,o,s,BigInt(0),BigInt(\"0xffffffffffffffff\"))})),Buffer.prototype.writeBigUInt64BE=defineBigIntMethod((function writeBigUInt64BE(o,s=0){return wrtBigUInt64BE(this,o,s,BigInt(0),BigInt(\"0xffffffffffffffff\"))})),Buffer.prototype.writeIntLE=function writeIntLE(o,s,i,u){if(o=+o,s>>>=0,!u){const u=Math.pow(2,8*i-1);checkInt(this,o,s,i,u-1,-u)}let _=0,w=1,x=0;for(this[s]=255&o;++_>>=0,!u){const u=Math.pow(2,8*i-1);checkInt(this,o,s,i,u-1,-u)}let _=i-1,w=1,x=0;for(this[s+_]=255&o;--_>=0&&(w*=256);)o<0&&0===x&&0!==this[s+_+1]&&(x=1),this[s+_]=(o/w|0)-x&255;return s+i},Buffer.prototype.writeInt8=function writeInt8(o,s,i){return o=+o,s>>>=0,i||checkInt(this,o,s,1,127,-128),o<0&&(o=255+o+1),this[s]=255&o,s+1},Buffer.prototype.writeInt16LE=function writeInt16LE(o,s,i){return o=+o,s>>>=0,i||checkInt(this,o,s,2,32767,-32768),this[s]=255&o,this[s+1]=o>>>8,s+2},Buffer.prototype.writeInt16BE=function writeInt16BE(o,s,i){return o=+o,s>>>=0,i||checkInt(this,o,s,2,32767,-32768),this[s]=o>>>8,this[s+1]=255&o,s+2},Buffer.prototype.writeInt32LE=function writeInt32LE(o,s,i){return o=+o,s>>>=0,i||checkInt(this,o,s,4,2147483647,-2147483648),this[s]=255&o,this[s+1]=o>>>8,this[s+2]=o>>>16,this[s+3]=o>>>24,s+4},Buffer.prototype.writeInt32BE=function writeInt32BE(o,s,i){return o=+o,s>>>=0,i||checkInt(this,o,s,4,2147483647,-2147483648),o<0&&(o=4294967295+o+1),this[s]=o>>>24,this[s+1]=o>>>16,this[s+2]=o>>>8,this[s+3]=255&o,s+4},Buffer.prototype.writeBigInt64LE=defineBigIntMethod((function writeBigInt64LE(o,s=0){return wrtBigUInt64LE(this,o,s,-BigInt(\"0x8000000000000000\"),BigInt(\"0x7fffffffffffffff\"))})),Buffer.prototype.writeBigInt64BE=defineBigIntMethod((function writeBigInt64BE(o,s=0){return wrtBigUInt64BE(this,o,s,-BigInt(\"0x8000000000000000\"),BigInt(\"0x7fffffffffffffff\"))})),Buffer.prototype.writeFloatLE=function writeFloatLE(o,s,i){return writeFloat(this,o,s,!0,i)},Buffer.prototype.writeFloatBE=function writeFloatBE(o,s,i){return writeFloat(this,o,s,!1,i)},Buffer.prototype.writeDoubleLE=function writeDoubleLE(o,s,i){return writeDouble(this,o,s,!0,i)},Buffer.prototype.writeDoubleBE=function writeDoubleBE(o,s,i){return writeDouble(this,o,s,!1,i)},Buffer.prototype.copy=function copy(o,s,i,u){if(!Buffer.isBuffer(o))throw new TypeError(\"argument should be a Buffer\");if(i||(i=0),u||0===u||(u=this.length),s>=o.length&&(s=o.length),s||(s=0),u>0&&u=this.length)throw new RangeError(\"Index out of range\");if(u<0)throw new RangeError(\"sourceEnd out of bounds\");u>this.length&&(u=this.length),o.length-s>>=0,i=void 0===i?this.length:i>>>0,o||(o=0),\"number\"==typeof o)for(_=s;_=u+4;i-=3)s=`_${o.slice(i-3,i)}${s}`;return`${o.slice(0,i)}${s}`}function checkIntBI(o,s,i,u,_,w){if(o>i||o3?0===s||s===BigInt(0)?`>= 0${u} and < 2${u} ** ${8*(w+1)}${u}`:`>= -(2${u} ** ${8*(w+1)-1}${u}) and < 2 ** ${8*(w+1)-1}${u}`:`>= ${s}${u} and <= ${i}${u}`,new j.ERR_OUT_OF_RANGE(\"value\",_,o)}!function checkBounds(o,s,i){validateNumber(s,\"offset\"),void 0!==o[s]&&void 0!==o[s+i]||boundsError(s,o.length-(i+1))}(u,_,w)}function validateNumber(o,s){if(\"number\"!=typeof o)throw new j.ERR_INVALID_ARG_TYPE(s,\"number\",o)}function boundsError(o,s,i){if(Math.floor(o)!==o)throw validateNumber(o,i),new j.ERR_OUT_OF_RANGE(i||\"offset\",\"an integer\",o);if(s<0)throw new j.ERR_BUFFER_OUT_OF_BOUNDS;throw new j.ERR_OUT_OF_RANGE(i||\"offset\",`>= ${i?1:0} and <= ${s}`,o)}E(\"ERR_BUFFER_OUT_OF_BOUNDS\",(function(o){return o?`${o} is outside of buffer bounds`:\"Attempt to access memory outside buffer bounds\"}),RangeError),E(\"ERR_INVALID_ARG_TYPE\",(function(o,s){return`The \"${o}\" argument must be of type number. Received type ${typeof s}`}),TypeError),E(\"ERR_OUT_OF_RANGE\",(function(o,s,i){let u=`The value of \"${o}\" is out of range.`,_=i;return Number.isInteger(i)&&Math.abs(i)>2**32?_=addNumericalSeparator(String(i)):\"bigint\"==typeof i&&(_=String(i),(i>BigInt(2)**BigInt(32)||i<-(BigInt(2)**BigInt(32)))&&(_=addNumericalSeparator(_)),_+=\"n\"),u+=` It must be ${s}. Received ${_}`,u}),RangeError);const L=/[^+/0-9A-Za-z-_]/g;function utf8ToBytes(o,s){let i;s=s||1/0;const u=o.length;let _=null;const w=[];for(let x=0;x55295&&i<57344){if(!_){if(i>56319){(s-=3)>-1&&w.push(239,191,189);continue}if(x+1===u){(s-=3)>-1&&w.push(239,191,189);continue}_=i;continue}if(i<56320){(s-=3)>-1&&w.push(239,191,189),_=i;continue}i=65536+(_-55296<<10|i-56320)}else _&&(s-=3)>-1&&w.push(239,191,189);if(_=null,i<128){if((s-=1)<0)break;w.push(i)}else if(i<2048){if((s-=2)<0)break;w.push(i>>6|192,63&i|128)}else if(i<65536){if((s-=3)<0)break;w.push(i>>12|224,i>>6&63|128,63&i|128)}else{if(!(i<1114112))throw new Error(\"Invalid code point\");if((s-=4)<0)break;w.push(i>>18|240,i>>12&63|128,i>>6&63|128,63&i|128)}}return w}function base64ToBytes(o){return u.toByteArray(function base64clean(o){if((o=(o=o.split(\"=\")[0]).trim().replace(L,\"\")).length<2)return\"\";for(;o.length%4!=0;)o+=\"=\";return o}(o))}function blitBuffer(o,s,i,u){let _;for(_=0;_=s.length||_>=o.length);++_)s[_+i]=o[_];return _}function isInstance(o,s){return o instanceof s||null!=o&&null!=o.constructor&&null!=o.constructor.name&&o.constructor.name===s.name}function numberIsNaN(o){return o!=o}const B=function(){const o=\"0123456789abcdef\",s=new Array(256);for(let i=0;i<16;++i){const u=16*i;for(let _=0;_<16;++_)s[u+_]=o[i]+o[_]}return s}();function defineBigIntMethod(o){return\"undefined\"==typeof BigInt?BufferBigIntNotDefined:o}function BufferBigIntNotDefined(){throw new Error(\"BigInt not supported\")}},38075:(o,s,i)=>{\"use strict\";var u=i(70453),_=i(10487),w=_(u(\"String.prototype.indexOf\"));o.exports=function callBoundIntrinsic(o,s){var i=u(o,!!s);return\"function\"==typeof i&&w(o,\".prototype.\")>-1?_(i):i}},10487:(o,s,i)=>{\"use strict\";var u=i(66743),_=i(70453),w=i(96897),x=i(69675),C=_(\"%Function.prototype.apply%\"),j=_(\"%Function.prototype.call%\"),L=_(\"%Reflect.apply%\",!0)||u.call(j,C),B=i(30655),$=_(\"%Math.max%\");o.exports=function callBind(o){if(\"function\"!=typeof o)throw new x(\"a function is required\");var s=L(u,j,arguments);return w(s,1+$(0,o.length-(arguments.length-1)),!0)};var V=function applyBind(){return L(u,C,arguments)};B?B(o.exports,\"apply\",{value:V}):o.exports.apply=V},57427:(o,s)=>{\"use strict\";s.parse=function parse(o,s){if(\"string\"!=typeof o)throw new TypeError(\"argument str must be a string\");var i={},u=(s||{}).decode||decode,_=0;for(;_{\"use strict\";var u=i(16426),_={\"text/plain\":\"Text\",\"text/html\":\"Url\",default:\"Text\"};o.exports=function copy(o,s){var i,w,x,C,j,L,B=!1;s||(s={}),i=s.debug||!1;try{if(x=u(),C=document.createRange(),j=document.getSelection(),(L=document.createElement(\"span\")).textContent=o,L.ariaHidden=\"true\",L.style.all=\"unset\",L.style.position=\"fixed\",L.style.top=0,L.style.clip=\"rect(0, 0, 0, 0)\",L.style.whiteSpace=\"pre\",L.style.webkitUserSelect=\"text\",L.style.MozUserSelect=\"text\",L.style.msUserSelect=\"text\",L.style.userSelect=\"text\",L.addEventListener(\"copy\",(function(u){if(u.stopPropagation(),s.format)if(u.preventDefault(),void 0===u.clipboardData){i&&console.warn(\"unable to use e.clipboardData\"),i&&console.warn(\"trying IE specific stuff\"),window.clipboardData.clearData();var w=_[s.format]||_.default;window.clipboardData.setData(w,o)}else u.clipboardData.clearData(),u.clipboardData.setData(s.format,o);s.onCopy&&(u.preventDefault(),s.onCopy(u.clipboardData))})),document.body.appendChild(L),C.selectNodeContents(L),j.addRange(C),!document.execCommand(\"copy\"))throw new Error(\"copy command was unsuccessful\");B=!0}catch(u){i&&console.error(\"unable to copy using execCommand: \",u),i&&console.warn(\"trying IE specific stuff\");try{window.clipboardData.setData(s.format||\"text\",o),s.onCopy&&s.onCopy(window.clipboardData),B=!0}catch(u){i&&console.error(\"unable to copy using clipboardData: \",u),i&&console.error(\"falling back to prompt\"),w=function format(o){var s=(/mac os x/i.test(navigator.userAgent)?\"⌘\":\"Ctrl\")+\"+C\";return o.replace(/#{\\s*key\\s*}/g,s)}(\"message\"in s?s.message:\"Copy to clipboard: #{key}, Enter\"),window.prompt(w,o)}}finally{j&&(\"function\"==typeof j.removeRange?j.removeRange(C):j.removeAllRanges()),L&&document.body.removeChild(L),x()}return B}},2205:function(o,s,i){var u;u=void 0!==i.g?i.g:this,o.exports=function(o){if(o.CSS&&o.CSS.escape)return o.CSS.escape;var cssEscape=function(o){if(0==arguments.length)throw new TypeError(\"`CSS.escape` requires an argument.\");for(var s,i=String(o),u=i.length,_=-1,w=\"\",x=i.charCodeAt(0);++_=1&&s<=31||127==s||0==_&&s>=48&&s<=57||1==_&&s>=48&&s<=57&&45==x?\"\\\\\"+s.toString(16)+\" \":0==_&&1==u&&45==s||!(s>=128||45==s||95==s||s>=48&&s<=57||s>=65&&s<=90||s>=97&&s<=122)?\"\\\\\"+i.charAt(_):i.charAt(_):w+=\"�\";return w};return o.CSS||(o.CSS={}),o.CSS.escape=cssEscape,cssEscape}(u)},81919:(o,s,i)=>{\"use strict\";var u=i(48287).Buffer;function isSpecificValue(o){return o instanceof u||o instanceof Date||o instanceof RegExp}function cloneSpecificValue(o){if(o instanceof u){var s=u.alloc?u.alloc(o.length):new u(o.length);return o.copy(s),s}if(o instanceof Date)return new Date(o.getTime());if(o instanceof RegExp)return new RegExp(o);throw new Error(\"Unexpected situation\")}function deepCloneArray(o){var s=[];return o.forEach((function(o,i){\"object\"==typeof o&&null!==o?Array.isArray(o)?s[i]=deepCloneArray(o):isSpecificValue(o)?s[i]=cloneSpecificValue(o):s[i]=_({},o):s[i]=o})),s}function safeGetProperty(o,s){return\"__proto__\"===s?void 0:o[s]}var _=o.exports=function(){if(arguments.length<1||\"object\"!=typeof arguments[0])return!1;if(arguments.length<2)return arguments[0];var o,s,i=arguments[0];return Array.prototype.slice.call(arguments,1).forEach((function(u){\"object\"!=typeof u||null===u||Array.isArray(u)||Object.keys(u).forEach((function(w){return s=safeGetProperty(i,w),(o=safeGetProperty(u,w))===i?void 0:\"object\"!=typeof o||null===o?void(i[w]=o):Array.isArray(o)?void(i[w]=deepCloneArray(o)):isSpecificValue(o)?void(i[w]=cloneSpecificValue(o)):\"object\"!=typeof s||null===s||Array.isArray(s)?void(i[w]=_({},o)):void(i[w]=_(s,o))}))})),i}},14744:o=>{\"use strict\";var s=function isMergeableObject(o){return function isNonNullObject(o){return!!o&&\"object\"==typeof o}(o)&&!function isSpecial(o){var s=Object.prototype.toString.call(o);return\"[object RegExp]\"===s||\"[object Date]\"===s||function isReactElement(o){return o.$$typeof===i}(o)}(o)};var i=\"function\"==typeof Symbol&&Symbol.for?Symbol.for(\"react.element\"):60103;function cloneUnlessOtherwiseSpecified(o,s){return!1!==s.clone&&s.isMergeableObject(o)?deepmerge(function emptyTarget(o){return Array.isArray(o)?[]:{}}(o),o,s):o}function defaultArrayMerge(o,s,i){return o.concat(s).map((function(o){return cloneUnlessOtherwiseSpecified(o,i)}))}function getKeys(o){return Object.keys(o).concat(function getEnumerableOwnPropertySymbols(o){return Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(o).filter((function(s){return Object.propertyIsEnumerable.call(o,s)})):[]}(o))}function propertyIsOnObject(o,s){try{return s in o}catch(o){return!1}}function mergeObject(o,s,i){var u={};return i.isMergeableObject(o)&&getKeys(o).forEach((function(s){u[s]=cloneUnlessOtherwiseSpecified(o[s],i)})),getKeys(s).forEach((function(_){(function propertyIsUnsafe(o,s){return propertyIsOnObject(o,s)&&!(Object.hasOwnProperty.call(o,s)&&Object.propertyIsEnumerable.call(o,s))})(o,_)||(propertyIsOnObject(o,_)&&i.isMergeableObject(s[_])?u[_]=function getMergeFunction(o,s){if(!s.customMerge)return deepmerge;var i=s.customMerge(o);return\"function\"==typeof i?i:deepmerge}(_,i)(o[_],s[_],i):u[_]=cloneUnlessOtherwiseSpecified(s[_],i))})),u}function deepmerge(o,i,u){(u=u||{}).arrayMerge=u.arrayMerge||defaultArrayMerge,u.isMergeableObject=u.isMergeableObject||s,u.cloneUnlessOtherwiseSpecified=cloneUnlessOtherwiseSpecified;var _=Array.isArray(i);return _===Array.isArray(o)?_?u.arrayMerge(o,i,u):mergeObject(o,i,u):cloneUnlessOtherwiseSpecified(i,u)}deepmerge.all=function deepmergeAll(o,s){if(!Array.isArray(o))throw new Error(\"first argument should be an array\");return o.reduce((function(o,i){return deepmerge(o,i,s)}),{})};var u=deepmerge;o.exports=u},30041:(o,s,i)=>{\"use strict\";var u=i(30655),_=i(58068),w=i(69675),x=i(75795);o.exports=function defineDataProperty(o,s,i){if(!o||\"object\"!=typeof o&&\"function\"!=typeof o)throw new w(\"`obj` must be an object or a function`\");if(\"string\"!=typeof s&&\"symbol\"!=typeof s)throw new w(\"`property` must be a string or a symbol`\");if(arguments.length>3&&\"boolean\"!=typeof arguments[3]&&null!==arguments[3])throw new w(\"`nonEnumerable`, if provided, must be a boolean or null\");if(arguments.length>4&&\"boolean\"!=typeof arguments[4]&&null!==arguments[4])throw new w(\"`nonWritable`, if provided, must be a boolean or null\");if(arguments.length>5&&\"boolean\"!=typeof arguments[5]&&null!==arguments[5])throw new w(\"`nonConfigurable`, if provided, must be a boolean or null\");if(arguments.length>6&&\"boolean\"!=typeof arguments[6])throw new w(\"`loose`, if provided, must be a boolean\");var C=arguments.length>3?arguments[3]:null,j=arguments.length>4?arguments[4]:null,L=arguments.length>5?arguments[5]:null,B=arguments.length>6&&arguments[6],$=!!x&&x(o,s);if(u)u(o,s,{configurable:null===L&&$?$.configurable:!L,enumerable:null===C&&$?$.enumerable:!C,value:i,writable:null===j&&$?$.writable:!j});else{if(!B&&(C||j||L))throw new _(\"This environment does not support defining a property as non-configurable, non-writable, or non-enumerable.\");o[s]=i}}},42838:function(o){o.exports=function(){\"use strict\";const{entries:o,setPrototypeOf:s,isFrozen:i,getPrototypeOf:u,getOwnPropertyDescriptor:_}=Object;let{freeze:w,seal:x,create:C}=Object,{apply:j,construct:L}=\"undefined\"!=typeof Reflect&&Reflect;w||(w=function freeze(o){return o}),x||(x=function seal(o){return o}),j||(j=function apply(o,s,i){return o.apply(s,i)}),L||(L=function construct(o,s){return new o(...s)});const B=unapply(Array.prototype.forEach),$=unapply(Array.prototype.pop),V=unapply(Array.prototype.push),U=unapply(String.prototype.toLowerCase),z=unapply(String.prototype.toString),Y=unapply(String.prototype.match),Z=unapply(String.prototype.replace),ee=unapply(String.prototype.indexOf),ie=unapply(String.prototype.trim),ae=unapply(Object.prototype.hasOwnProperty),ce=unapply(RegExp.prototype.test),le=unconstruct(TypeError);function numberIsNaN(o){return\"number\"==typeof o&&isNaN(o)}function unapply(o){return function(s){for(var i=arguments.length,u=new Array(i>1?i-1:0),_=1;_2&&void 0!==arguments[2]?arguments[2]:U;s&&s(o,null);let w=u.length;for(;w--;){let s=u[w];if(\"string\"==typeof s){const o=_(s);o!==s&&(i(u)||(u[w]=o),s=o)}o[s]=!0}return o}function cleanArray(o){for(let s=0;s/gm),$e=x(/\\${[\\w\\W]*}/gm),ze=x(/^data-[\\-\\w.\\u00B7-\\uFFFF]/),We=x(/^aria-[\\-\\w]+$/),He=x(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i),Ye=x(/^(?:\\w+script|data):/i),Xe=x(/[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g),Qe=x(/^html$/i),et=x(/^[a-z][.\\w]*(-[.\\w]+)+$/i);var tt=Object.freeze({__proto__:null,MUSTACHE_EXPR:Re,ERB_EXPR:qe,TMPLIT_EXPR:$e,DATA_ATTR:ze,ARIA_ATTR:We,IS_ALLOWED_URI:He,IS_SCRIPT_OR_DATA:Ye,ATTR_WHITESPACE:Xe,DOCTYPE_NAME:Qe,CUSTOM_ELEMENT:et});const rt={element:1,attribute:2,text:3,cdataSection:4,entityReference:5,entityNode:6,progressingInstruction:7,comment:8,document:9,documentType:10,documentFragment:11,notation:12},nt=function getGlobal(){return\"undefined\"==typeof window?null:window},ot=function _createTrustedTypesPolicy(o,s){if(\"object\"!=typeof o||\"function\"!=typeof o.createPolicy)return null;let i=null;const u=\"data-tt-policy-suffix\";s&&s.hasAttribute(u)&&(i=s.getAttribute(u));const _=\"dompurify\"+(i?\"#\"+i:\"\");try{return o.createPolicy(_,{createHTML:o=>o,createScriptURL:o=>o})}catch(o){return console.warn(\"TrustedTypes policy \"+_+\" could not be created.\"),null}};function createDOMPurify(){let s=arguments.length>0&&void 0!==arguments[0]?arguments[0]:nt();const DOMPurify=o=>createDOMPurify(o);if(DOMPurify.version=\"3.1.4\",DOMPurify.removed=[],!s||!s.document||s.document.nodeType!==rt.document)return DOMPurify.isSupported=!1,DOMPurify;let{document:i}=s;const u=i,_=u.currentScript,{DocumentFragment:x,HTMLTemplateElement:j,Node:L,Element:Re,NodeFilter:qe,NamedNodeMap:$e=s.NamedNodeMap||s.MozNamedAttrMap,HTMLFormElement:ze,DOMParser:We,trustedTypes:Ye}=s,Xe=Re.prototype,et=lookupGetter(Xe,\"cloneNode\"),st=lookupGetter(Xe,\"nextSibling\"),it=lookupGetter(Xe,\"childNodes\"),at=lookupGetter(Xe,\"parentNode\");if(\"function\"==typeof j){const o=i.createElement(\"template\");o.content&&o.content.ownerDocument&&(i=o.content.ownerDocument)}let ct,lt=\"\";const{implementation:ut,createNodeIterator:pt,createDocumentFragment:ht,getElementsByTagName:dt}=i,{importNode:mt}=u;let gt={};DOMPurify.isSupported=\"function\"==typeof o&&\"function\"==typeof at&&ut&&void 0!==ut.createHTMLDocument;const{MUSTACHE_EXPR:yt,ERB_EXPR:vt,TMPLIT_EXPR:bt,DATA_ATTR:_t,ARIA_ATTR:Et,IS_SCRIPT_OR_DATA:wt,ATTR_WHITESPACE:St,CUSTOM_ELEMENT:xt}=tt;let{IS_ALLOWED_URI:kt}=tt,Ot=null;const Ct=addToSet({},[...pe,...de,...fe,...be,...we]);let At=null;const jt=addToSet({},[...Se,...xe,...Pe,...Te]);let Pt=Object.seal(C(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),It=null,Mt=null,Nt=!0,Tt=!0,Rt=!1,Dt=!0,Lt=!1,Bt=!0,Ft=!1,qt=!1,$t=!1,Vt=!1,Ut=!1,zt=!1,Wt=!0,Kt=!1;const Ht=\"user-content-\";let Jt=!0,Gt=!1,Yt={},Xt=null;const Qt=addToSet({},[\"annotation-xml\",\"audio\",\"colgroup\",\"desc\",\"foreignobject\",\"head\",\"iframe\",\"math\",\"mi\",\"mn\",\"mo\",\"ms\",\"mtext\",\"noembed\",\"noframes\",\"noscript\",\"plaintext\",\"script\",\"style\",\"svg\",\"template\",\"thead\",\"title\",\"video\",\"xmp\"]);let Zt=null;const er=addToSet({},[\"audio\",\"video\",\"img\",\"source\",\"image\",\"track\"]);let tr=null;const rr=addToSet({},[\"alt\",\"class\",\"for\",\"id\",\"label\",\"name\",\"pattern\",\"placeholder\",\"role\",\"summary\",\"title\",\"value\",\"style\",\"xmlns\"]),nr=\"http://www.w3.org/1998/Math/MathML\",sr=\"http://www.w3.org/2000/svg\",ir=\"http://www.w3.org/1999/xhtml\";let ar=ir,cr=!1,lr=null;const ur=addToSet({},[nr,sr,ir],z);let pr=null;const dr=[\"application/xhtml+xml\",\"text/html\"],fr=\"text/html\";let mr=null,gr=null;const yr=255,vr=i.createElement(\"form\"),br=function isRegexOrFunction(o){return o instanceof RegExp||o instanceof Function},_r=function _parseConfig(){let o=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!gr||gr!==o){if(o&&\"object\"==typeof o||(o={}),o=clone(o),pr=-1===dr.indexOf(o.PARSER_MEDIA_TYPE)?fr:o.PARSER_MEDIA_TYPE,mr=\"application/xhtml+xml\"===pr?z:U,Ot=ae(o,\"ALLOWED_TAGS\")?addToSet({},o.ALLOWED_TAGS,mr):Ct,At=ae(o,\"ALLOWED_ATTR\")?addToSet({},o.ALLOWED_ATTR,mr):jt,lr=ae(o,\"ALLOWED_NAMESPACES\")?addToSet({},o.ALLOWED_NAMESPACES,z):ur,tr=ae(o,\"ADD_URI_SAFE_ATTR\")?addToSet(clone(rr),o.ADD_URI_SAFE_ATTR,mr):rr,Zt=ae(o,\"ADD_DATA_URI_TAGS\")?addToSet(clone(er),o.ADD_DATA_URI_TAGS,mr):er,Xt=ae(o,\"FORBID_CONTENTS\")?addToSet({},o.FORBID_CONTENTS,mr):Qt,It=ae(o,\"FORBID_TAGS\")?addToSet({},o.FORBID_TAGS,mr):{},Mt=ae(o,\"FORBID_ATTR\")?addToSet({},o.FORBID_ATTR,mr):{},Yt=!!ae(o,\"USE_PROFILES\")&&o.USE_PROFILES,Nt=!1!==o.ALLOW_ARIA_ATTR,Tt=!1!==o.ALLOW_DATA_ATTR,Rt=o.ALLOW_UNKNOWN_PROTOCOLS||!1,Dt=!1!==o.ALLOW_SELF_CLOSE_IN_ATTR,Lt=o.SAFE_FOR_TEMPLATES||!1,Bt=!1!==o.SAFE_FOR_XML,Ft=o.WHOLE_DOCUMENT||!1,Vt=o.RETURN_DOM||!1,Ut=o.RETURN_DOM_FRAGMENT||!1,zt=o.RETURN_TRUSTED_TYPE||!1,$t=o.FORCE_BODY||!1,Wt=!1!==o.SANITIZE_DOM,Kt=o.SANITIZE_NAMED_PROPS||!1,Jt=!1!==o.KEEP_CONTENT,Gt=o.IN_PLACE||!1,kt=o.ALLOWED_URI_REGEXP||He,ar=o.NAMESPACE||ir,Pt=o.CUSTOM_ELEMENT_HANDLING||{},o.CUSTOM_ELEMENT_HANDLING&&br(o.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(Pt.tagNameCheck=o.CUSTOM_ELEMENT_HANDLING.tagNameCheck),o.CUSTOM_ELEMENT_HANDLING&&br(o.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(Pt.attributeNameCheck=o.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),o.CUSTOM_ELEMENT_HANDLING&&\"boolean\"==typeof o.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(Pt.allowCustomizedBuiltInElements=o.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),Lt&&(Tt=!1),Ut&&(Vt=!0),Yt&&(Ot=addToSet({},we),At=[],!0===Yt.html&&(addToSet(Ot,pe),addToSet(At,Se)),!0===Yt.svg&&(addToSet(Ot,de),addToSet(At,xe),addToSet(At,Te)),!0===Yt.svgFilters&&(addToSet(Ot,fe),addToSet(At,xe),addToSet(At,Te)),!0===Yt.mathMl&&(addToSet(Ot,be),addToSet(At,Pe),addToSet(At,Te))),o.ADD_TAGS&&(Ot===Ct&&(Ot=clone(Ot)),addToSet(Ot,o.ADD_TAGS,mr)),o.ADD_ATTR&&(At===jt&&(At=clone(At)),addToSet(At,o.ADD_ATTR,mr)),o.ADD_URI_SAFE_ATTR&&addToSet(tr,o.ADD_URI_SAFE_ATTR,mr),o.FORBID_CONTENTS&&(Xt===Qt&&(Xt=clone(Xt)),addToSet(Xt,o.FORBID_CONTENTS,mr)),Jt&&(Ot[\"#text\"]=!0),Ft&&addToSet(Ot,[\"html\",\"head\",\"body\"]),Ot.table&&(addToSet(Ot,[\"tbody\"]),delete It.tbody),o.TRUSTED_TYPES_POLICY){if(\"function\"!=typeof o.TRUSTED_TYPES_POLICY.createHTML)throw le('TRUSTED_TYPES_POLICY configuration option must provide a \"createHTML\" hook.');if(\"function\"!=typeof o.TRUSTED_TYPES_POLICY.createScriptURL)throw le('TRUSTED_TYPES_POLICY configuration option must provide a \"createScriptURL\" hook.');ct=o.TRUSTED_TYPES_POLICY,lt=ct.createHTML(\"\")}else void 0===ct&&(ct=ot(Ye,_)),null!==ct&&\"string\"==typeof lt&&(lt=ct.createHTML(\"\"));w&&w(o),gr=o}},Er=addToSet({},[\"mi\",\"mo\",\"mn\",\"ms\",\"mtext\"]),wr=addToSet({},[\"foreignobject\",\"annotation-xml\"]),Sr=addToSet({},[\"title\",\"style\",\"font\",\"a\",\"script\"]),xr=addToSet({},[...de,...fe,...ye]),kr=addToSet({},[...be,..._e]),Or=function _checkValidNamespace(o){let s=at(o);s&&s.tagName||(s={namespaceURI:ar,tagName:\"template\"});const i=U(o.tagName),u=U(s.tagName);return!!lr[o.namespaceURI]&&(o.namespaceURI===sr?s.namespaceURI===ir?\"svg\"===i:s.namespaceURI===nr?\"svg\"===i&&(\"annotation-xml\"===u||Er[u]):Boolean(xr[i]):o.namespaceURI===nr?s.namespaceURI===ir?\"math\"===i:s.namespaceURI===sr?\"math\"===i&&wr[u]:Boolean(kr[i]):o.namespaceURI===ir?!(s.namespaceURI===sr&&!wr[u])&&!(s.namespaceURI===nr&&!Er[u])&&!kr[i]&&(Sr[i]||!xr[i]):!(\"application/xhtml+xml\"!==pr||!lr[o.namespaceURI]))},Cr=function _forceRemove(o){V(DOMPurify.removed,{element:o});try{o.parentNode.removeChild(o)}catch(s){o.remove()}},Ar=function _removeAttribute(o,s){try{V(DOMPurify.removed,{attribute:s.getAttributeNode(o),from:s})}catch(o){V(DOMPurify.removed,{attribute:null,from:s})}if(s.removeAttribute(o),\"is\"===o&&!At[o])if(Vt||Ut)try{Cr(s)}catch(o){}else try{s.setAttribute(o,\"\")}catch(o){}},jr=function _initDocument(o){let s=null,u=null;if($t)o=\"\"+o;else{const s=Y(o,/^[\\r\\n\\t ]+/);u=s&&s[0]}\"application/xhtml+xml\"===pr&&ar===ir&&(o=''+o+\"\");const _=ct?ct.createHTML(o):o;if(ar===ir)try{s=(new We).parseFromString(_,pr)}catch(o){}if(!s||!s.documentElement){s=ut.createDocument(ar,\"template\",null);try{s.documentElement.innerHTML=cr?lt:_}catch(o){}}const w=s.body||s.documentElement;return o&&u&&w.insertBefore(i.createTextNode(u),w.childNodes[0]||null),ar===ir?dt.call(s,Ft?\"html\":\"body\")[0]:Ft?s.documentElement:w},Pr=function _createNodeIterator(o){return pt.call(o.ownerDocument||o,o,qe.SHOW_ELEMENT|qe.SHOW_COMMENT|qe.SHOW_TEXT|qe.SHOW_PROCESSING_INSTRUCTION|qe.SHOW_CDATA_SECTION,null)},Ir=function _isClobbered(o){return o instanceof ze&&(void 0!==o.__depth&&\"number\"!=typeof o.__depth||void 0!==o.__removalCount&&\"number\"!=typeof o.__removalCount||\"string\"!=typeof o.nodeName||\"string\"!=typeof o.textContent||\"function\"!=typeof o.removeChild||!(o.attributes instanceof $e)||\"function\"!=typeof o.removeAttribute||\"function\"!=typeof o.setAttribute||\"string\"!=typeof o.namespaceURI||\"function\"!=typeof o.insertBefore||\"function\"!=typeof o.hasChildNodes)},Mr=function _isNode(o){return\"function\"==typeof L&&o instanceof L},Nr=function _executeHook(o,s,i){gt[o]&&B(gt[o],(o=>{o.call(DOMPurify,s,i,gr)}))},Tr=function _sanitizeElements(o){let s=null;if(Nr(\"beforeSanitizeElements\",o,null),Ir(o))return Cr(o),!0;const i=mr(o.nodeName);if(Nr(\"uponSanitizeElement\",o,{tagName:i,allowedTags:Ot}),o.hasChildNodes()&&!Mr(o.firstElementChild)&&ce(/<[/\\w]/g,o.innerHTML)&&ce(/<[/\\w]/g,o.textContent))return Cr(o),!0;if(o.nodeType===rt.progressingInstruction)return Cr(o),!0;if(Bt&&o.nodeType===rt.comment&&ce(/<[/\\w]/g,o.data))return Cr(o),!0;if(!Ot[i]||It[i]){if(!It[i]&&Dr(i)){if(Pt.tagNameCheck instanceof RegExp&&ce(Pt.tagNameCheck,i))return!1;if(Pt.tagNameCheck instanceof Function&&Pt.tagNameCheck(i))return!1}if(Jt&&!Xt[i]){const s=at(o)||o.parentNode,i=it(o)||o.childNodes;if(i&&s)for(let u=i.length-1;u>=0;--u){const _=et(i[u],!0);_.__removalCount=(o.__removalCount||0)+1,s.insertBefore(_,st(o))}}return Cr(o),!0}return o instanceof Re&&!Or(o)?(Cr(o),!0):\"noscript\"!==i&&\"noembed\"!==i&&\"noframes\"!==i||!ce(/<\\/no(script|embed|frames)/i,o.innerHTML)?(Lt&&o.nodeType===rt.text&&(s=o.textContent,B([yt,vt,bt],(o=>{s=Z(s,o,\" \")})),o.textContent!==s&&(V(DOMPurify.removed,{element:o.cloneNode()}),o.textContent=s)),Nr(\"afterSanitizeElements\",o,null),!1):(Cr(o),!0)},Rr=function _isValidAttribute(o,s,u){if(Wt&&(\"id\"===s||\"name\"===s)&&(u in i||u in vr||\"__depth\"===u||\"__removalCount\"===u))return!1;if(Tt&&!Mt[s]&&ce(_t,s));else if(Nt&&ce(Et,s));else if(!At[s]||Mt[s]){if(!(Dr(o)&&(Pt.tagNameCheck instanceof RegExp&&ce(Pt.tagNameCheck,o)||Pt.tagNameCheck instanceof Function&&Pt.tagNameCheck(o))&&(Pt.attributeNameCheck instanceof RegExp&&ce(Pt.attributeNameCheck,s)||Pt.attributeNameCheck instanceof Function&&Pt.attributeNameCheck(s))||\"is\"===s&&Pt.allowCustomizedBuiltInElements&&(Pt.tagNameCheck instanceof RegExp&&ce(Pt.tagNameCheck,u)||Pt.tagNameCheck instanceof Function&&Pt.tagNameCheck(u))))return!1}else if(tr[s]);else if(ce(kt,Z(u,St,\"\")));else if(\"src\"!==s&&\"xlink:href\"!==s&&\"href\"!==s||\"script\"===o||0!==ee(u,\"data:\")||!Zt[o])if(Rt&&!ce(wt,Z(u,St,\"\")));else if(u)return!1;return!0},Dr=function _isBasicCustomElement(o){return\"annotation-xml\"!==o&&Y(o,xt)},Lr=function _sanitizeAttributes(o){Nr(\"beforeSanitizeAttributes\",o,null);const{attributes:s}=o;if(!s)return;const i={attrName:\"\",attrValue:\"\",keepAttr:!0,allowedAttributes:At};let u=s.length;for(;u--;){const _=s[u],{name:w,namespaceURI:x,value:C}=_,j=mr(w);let L=\"value\"===w?C:ie(C);if(i.attrName=j,i.attrValue=L,i.keepAttr=!0,i.forceKeepAttr=void 0,Nr(\"uponSanitizeAttribute\",o,i),L=i.attrValue,i.forceKeepAttr)continue;if(Ar(w,o),!i.keepAttr)continue;if(!Dt&&ce(/\\/>/i,L)){Ar(w,o);continue}if(Bt&&ce(/((--!?|])>)|<\\/(style|title)/i,L)){Ar(w,o);continue}Lt&&B([yt,vt,bt],(o=>{L=Z(L,o,\" \")}));const V=mr(o.nodeName);if(Rr(V,j,L)){if(!Kt||\"id\"!==j&&\"name\"!==j||(Ar(w,o),L=Ht+L),ct&&\"object\"==typeof Ye&&\"function\"==typeof Ye.getAttributeType)if(x);else switch(Ye.getAttributeType(V,j)){case\"TrustedHTML\":L=ct.createHTML(L);break;case\"TrustedScriptURL\":L=ct.createScriptURL(L)}try{x?o.setAttributeNS(x,w,L):o.setAttribute(w,L),Ir(o)?Cr(o):$(DOMPurify.removed)}catch(o){}}}Nr(\"afterSanitizeAttributes\",o,null)},Br=function _sanitizeShadowDOM(o){let s=null;const i=Pr(o);for(Nr(\"beforeSanitizeShadowDOM\",o,null);s=i.nextNode();){if(Nr(\"uponSanitizeShadowNode\",s,null),Tr(s))continue;const o=at(s);s.nodeType===rt.element&&(o&&o.__depth?s.__depth=(s.__removalCount||0)+o.__depth+1:s.__depth=1),(s.__depth>=yr||s.__depth<0||numberIsNaN(s.__depth))&&Cr(s),s.content instanceof x&&(s.content.__depth=s.__depth,_sanitizeShadowDOM(s.content)),Lr(s)}Nr(\"afterSanitizeShadowDOM\",o,null)};return DOMPurify.sanitize=function(o){let s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=null,_=null,w=null,C=null;if(cr=!o,cr&&(o=\"\\x3c!--\\x3e\"),\"string\"!=typeof o&&!Mr(o)){if(\"function\"!=typeof o.toString)throw le(\"toString is not a function\");if(\"string\"!=typeof(o=o.toString()))throw le(\"dirty is not a string, aborting\")}if(!DOMPurify.isSupported)return o;if(qt||_r(s),DOMPurify.removed=[],\"string\"==typeof o&&(Gt=!1),Gt){if(o.nodeName){const s=mr(o.nodeName);if(!Ot[s]||It[s])throw le(\"root node is forbidden and cannot be sanitized in-place\")}}else if(o instanceof L)i=jr(\"\\x3c!----\\x3e\"),_=i.ownerDocument.importNode(o,!0),_.nodeType===rt.element&&\"BODY\"===_.nodeName||\"HTML\"===_.nodeName?i=_:i.appendChild(_);else{if(!Vt&&!Lt&&!Ft&&-1===o.indexOf(\"<\"))return ct&&zt?ct.createHTML(o):o;if(i=jr(o),!i)return Vt?null:zt?lt:\"\"}i&&$t&&Cr(i.firstChild);const j=Pr(Gt?o:i);for(;w=j.nextNode();){if(Tr(w))continue;const o=at(w);w.nodeType===rt.element&&(o&&o.__depth?w.__depth=(w.__removalCount||0)+o.__depth+1:w.__depth=1),(w.__depth>=yr||w.__depth<0||numberIsNaN(w.__depth))&&Cr(w),w.content instanceof x&&(w.content.__depth=w.__depth,Br(w.content)),Lr(w)}if(Gt)return o;if(Vt){if(Ut)for(C=ht.call(i.ownerDocument);i.firstChild;)C.appendChild(i.firstChild);else C=i;return(At.shadowroot||At.shadowrootmode)&&(C=mt.call(u,C,!0)),C}let $=Ft?i.outerHTML:i.innerHTML;return Ft&&Ot[\"!doctype\"]&&i.ownerDocument&&i.ownerDocument.doctype&&i.ownerDocument.doctype.name&&ce(Qe,i.ownerDocument.doctype.name)&&($=\"\\n\"+$),Lt&&B([yt,vt,bt],(o=>{$=Z($,o,\" \")})),ct&&zt?ct.createHTML($):$},DOMPurify.setConfig=function(){_r(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),qt=!0},DOMPurify.clearConfig=function(){gr=null,qt=!1},DOMPurify.isValidAttribute=function(o,s,i){gr||_r({});const u=mr(o),_=mr(s);return Rr(u,_,i)},DOMPurify.addHook=function(o,s){\"function\"==typeof s&&(gt[o]=gt[o]||[],V(gt[o],s))},DOMPurify.removeHook=function(o){if(gt[o])return $(gt[o])},DOMPurify.removeHooks=function(o){gt[o]&&(gt[o]=[])},DOMPurify.removeAllHooks=function(){gt={}},DOMPurify}return createDOMPurify()}()},78004:o=>{\"use strict\";class SubRange{constructor(o,s){this.low=o,this.high=s,this.length=1+s-o}overlaps(o){return!(this.higho.high)}touches(o){return!(this.high+1o.high)}add(o){return new SubRange(Math.min(this.low,o.low),Math.max(this.high,o.high))}subtract(o){return o.low<=this.low&&o.high>=this.high?[]:o.low>this.low&&o.higho+s.length),0)}add(o,s){var _add=o=>{for(var s=0;s{for(var s=0;s{for(var s=0;s{for(var i=s.low;i<=s.high;)o.push(i),i++;return o}),[])}subranges(){return this.ranges.map((o=>({low:o.low,high:o.high,length:1+o.high-o.low})))}}o.exports=DRange},30655:(o,s,i)=>{\"use strict\";var u=i(70453)(\"%Object.defineProperty%\",!0)||!1;if(u)try{u({},\"a\",{value:1})}catch(o){u=!1}o.exports=u},41237:o=>{\"use strict\";o.exports=EvalError},69383:o=>{\"use strict\";o.exports=Error},79290:o=>{\"use strict\";o.exports=RangeError},79538:o=>{\"use strict\";o.exports=ReferenceError},58068:o=>{\"use strict\";o.exports=SyntaxError},69675:o=>{\"use strict\";o.exports=TypeError},35345:o=>{\"use strict\";o.exports=URIError},37007:o=>{\"use strict\";var s,i=\"object\"==typeof Reflect?Reflect:null,u=i&&\"function\"==typeof i.apply?i.apply:function ReflectApply(o,s,i){return Function.prototype.apply.call(o,s,i)};s=i&&\"function\"==typeof i.ownKeys?i.ownKeys:Object.getOwnPropertySymbols?function ReflectOwnKeys(o){return Object.getOwnPropertyNames(o).concat(Object.getOwnPropertySymbols(o))}:function ReflectOwnKeys(o){return Object.getOwnPropertyNames(o)};var _=Number.isNaN||function NumberIsNaN(o){return o!=o};function EventEmitter(){EventEmitter.init.call(this)}o.exports=EventEmitter,o.exports.once=function once(o,s){return new Promise((function(i,u){function errorListener(i){o.removeListener(s,resolver),u(i)}function resolver(){\"function\"==typeof o.removeListener&&o.removeListener(\"error\",errorListener),i([].slice.call(arguments))}eventTargetAgnosticAddListener(o,s,resolver,{once:!0}),\"error\"!==s&&function addErrorHandlerIfEventEmitter(o,s,i){\"function\"==typeof o.on&&eventTargetAgnosticAddListener(o,\"error\",s,i)}(o,errorListener,{once:!0})}))},EventEmitter.EventEmitter=EventEmitter,EventEmitter.prototype._events=void 0,EventEmitter.prototype._eventsCount=0,EventEmitter.prototype._maxListeners=void 0;var w=10;function checkListener(o){if(\"function\"!=typeof o)throw new TypeError('The \"listener\" argument must be of type Function. Received type '+typeof o)}function _getMaxListeners(o){return void 0===o._maxListeners?EventEmitter.defaultMaxListeners:o._maxListeners}function _addListener(o,s,i,u){var _,w,x;if(checkListener(i),void 0===(w=o._events)?(w=o._events=Object.create(null),o._eventsCount=0):(void 0!==w.newListener&&(o.emit(\"newListener\",s,i.listener?i.listener:i),w=o._events),x=w[s]),void 0===x)x=w[s]=i,++o._eventsCount;else if(\"function\"==typeof x?x=w[s]=u?[i,x]:[x,i]:u?x.unshift(i):x.push(i),(_=_getMaxListeners(o))>0&&x.length>_&&!x.warned){x.warned=!0;var C=new Error(\"Possible EventEmitter memory leak detected. \"+x.length+\" \"+String(s)+\" listeners added. Use emitter.setMaxListeners() to increase limit\");C.name=\"MaxListenersExceededWarning\",C.emitter=o,C.type=s,C.count=x.length,function ProcessEmitWarning(o){console&&console.warn&&console.warn(o)}(C)}return o}function onceWrapper(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function _onceWrap(o,s,i){var u={fired:!1,wrapFn:void 0,target:o,type:s,listener:i},_=onceWrapper.bind(u);return _.listener=i,u.wrapFn=_,_}function _listeners(o,s,i){var u=o._events;if(void 0===u)return[];var _=u[s];return void 0===_?[]:\"function\"==typeof _?i?[_.listener||_]:[_]:i?function unwrapListeners(o){for(var s=new Array(o.length),i=0;i0&&(x=s[0]),x instanceof Error)throw x;var C=new Error(\"Unhandled error.\"+(x?\" (\"+x.message+\")\":\"\"));throw C.context=x,C}var j=w[o];if(void 0===j)return!1;if(\"function\"==typeof j)u(j,this,s);else{var L=j.length,B=arrayClone(j,L);for(i=0;i=0;w--)if(i[w]===s||i[w].listener===s){x=i[w].listener,_=w;break}if(_<0)return this;0===_?i.shift():function spliceOne(o,s){for(;s+1=0;u--)this.removeListener(o,s[u]);return this},EventEmitter.prototype.listeners=function listeners(o){return _listeners(this,o,!0)},EventEmitter.prototype.rawListeners=function rawListeners(o){return _listeners(this,o,!1)},EventEmitter.listenerCount=function(o,s){return\"function\"==typeof o.listenerCount?o.listenerCount(s):listenerCount.call(o,s)},EventEmitter.prototype.listenerCount=listenerCount,EventEmitter.prototype.eventNames=function eventNames(){return this._eventsCount>0?s(this._events):[]}},85587:(o,s,i)=>{\"use strict\";var u=i(26311),_=create(Error);function create(o){return FormattedError.displayName=o.displayName||o.name,FormattedError;function FormattedError(s){return s&&(s=u.apply(null,arguments)),new o(s)}}o.exports=_,_.eval=create(EvalError),_.range=create(RangeError),_.reference=create(ReferenceError),_.syntax=create(SyntaxError),_.type=create(TypeError),_.uri=create(URIError),_.create=create},26311:o=>{!function(){var s;function format(o){for(var s,i,u,_,w=1,x=[].slice.call(arguments),C=0,j=o.length,L=\"\",B=!1,$=!1,nextArg=function(){return x[w++]},slurpNumber=function(){for(var i=\"\";/\\d/.test(o[C]);)i+=o[C++],s=o[C];return i.length>0?parseInt(i):null};C{\"use strict\";var s=Object.prototype.toString,i=Math.max,u=function concatty(o,s){for(var i=[],u=0;u{\"use strict\";var u=i(89353);o.exports=Function.prototype.bind||u},70453:(o,s,i)=>{\"use strict\";var u,_=i(69383),w=i(41237),x=i(79290),C=i(79538),j=i(58068),L=i(69675),B=i(35345),$=Function,getEvalledConstructor=function(o){try{return $('\"use strict\"; return ('+o+\").constructor;\")()}catch(o){}},V=Object.getOwnPropertyDescriptor;if(V)try{V({},\"\")}catch(o){V=null}var throwTypeError=function(){throw new L},U=V?function(){try{return throwTypeError}catch(o){try{return V(arguments,\"callee\").get}catch(o){return throwTypeError}}}():throwTypeError,z=i(64039)(),Y=i(80024)(),Z=Object.getPrototypeOf||(Y?function(o){return o.__proto__}:null),ee={},ie=\"undefined\"!=typeof Uint8Array&&Z?Z(Uint8Array):u,ae={__proto__:null,\"%AggregateError%\":\"undefined\"==typeof AggregateError?u:AggregateError,\"%Array%\":Array,\"%ArrayBuffer%\":\"undefined\"==typeof ArrayBuffer?u:ArrayBuffer,\"%ArrayIteratorPrototype%\":z&&Z?Z([][Symbol.iterator]()):u,\"%AsyncFromSyncIteratorPrototype%\":u,\"%AsyncFunction%\":ee,\"%AsyncGenerator%\":ee,\"%AsyncGeneratorFunction%\":ee,\"%AsyncIteratorPrototype%\":ee,\"%Atomics%\":\"undefined\"==typeof Atomics?u:Atomics,\"%BigInt%\":\"undefined\"==typeof BigInt?u:BigInt,\"%BigInt64Array%\":\"undefined\"==typeof BigInt64Array?u:BigInt64Array,\"%BigUint64Array%\":\"undefined\"==typeof BigUint64Array?u:BigUint64Array,\"%Boolean%\":Boolean,\"%DataView%\":\"undefined\"==typeof DataView?u:DataView,\"%Date%\":Date,\"%decodeURI%\":decodeURI,\"%decodeURIComponent%\":decodeURIComponent,\"%encodeURI%\":encodeURI,\"%encodeURIComponent%\":encodeURIComponent,\"%Error%\":_,\"%eval%\":eval,\"%EvalError%\":w,\"%Float32Array%\":\"undefined\"==typeof Float32Array?u:Float32Array,\"%Float64Array%\":\"undefined\"==typeof Float64Array?u:Float64Array,\"%FinalizationRegistry%\":\"undefined\"==typeof FinalizationRegistry?u:FinalizationRegistry,\"%Function%\":$,\"%GeneratorFunction%\":ee,\"%Int8Array%\":\"undefined\"==typeof Int8Array?u:Int8Array,\"%Int16Array%\":\"undefined\"==typeof Int16Array?u:Int16Array,\"%Int32Array%\":\"undefined\"==typeof Int32Array?u:Int32Array,\"%isFinite%\":isFinite,\"%isNaN%\":isNaN,\"%IteratorPrototype%\":z&&Z?Z(Z([][Symbol.iterator]())):u,\"%JSON%\":\"object\"==typeof JSON?JSON:u,\"%Map%\":\"undefined\"==typeof Map?u:Map,\"%MapIteratorPrototype%\":\"undefined\"!=typeof Map&&z&&Z?Z((new Map)[Symbol.iterator]()):u,\"%Math%\":Math,\"%Number%\":Number,\"%Object%\":Object,\"%parseFloat%\":parseFloat,\"%parseInt%\":parseInt,\"%Promise%\":\"undefined\"==typeof Promise?u:Promise,\"%Proxy%\":\"undefined\"==typeof Proxy?u:Proxy,\"%RangeError%\":x,\"%ReferenceError%\":C,\"%Reflect%\":\"undefined\"==typeof Reflect?u:Reflect,\"%RegExp%\":RegExp,\"%Set%\":\"undefined\"==typeof Set?u:Set,\"%SetIteratorPrototype%\":\"undefined\"!=typeof Set&&z&&Z?Z((new Set)[Symbol.iterator]()):u,\"%SharedArrayBuffer%\":\"undefined\"==typeof SharedArrayBuffer?u:SharedArrayBuffer,\"%String%\":String,\"%StringIteratorPrototype%\":z&&Z?Z(\"\"[Symbol.iterator]()):u,\"%Symbol%\":z?Symbol:u,\"%SyntaxError%\":j,\"%ThrowTypeError%\":U,\"%TypedArray%\":ie,\"%TypeError%\":L,\"%Uint8Array%\":\"undefined\"==typeof Uint8Array?u:Uint8Array,\"%Uint8ClampedArray%\":\"undefined\"==typeof Uint8ClampedArray?u:Uint8ClampedArray,\"%Uint16Array%\":\"undefined\"==typeof Uint16Array?u:Uint16Array,\"%Uint32Array%\":\"undefined\"==typeof Uint32Array?u:Uint32Array,\"%URIError%\":B,\"%WeakMap%\":\"undefined\"==typeof WeakMap?u:WeakMap,\"%WeakRef%\":\"undefined\"==typeof WeakRef?u:WeakRef,\"%WeakSet%\":\"undefined\"==typeof WeakSet?u:WeakSet};if(Z)try{null.error}catch(o){var ce=Z(Z(o));ae[\"%Error.prototype%\"]=ce}var le=function doEval(o){var s;if(\"%AsyncFunction%\"===o)s=getEvalledConstructor(\"async function () {}\");else if(\"%GeneratorFunction%\"===o)s=getEvalledConstructor(\"function* () {}\");else if(\"%AsyncGeneratorFunction%\"===o)s=getEvalledConstructor(\"async function* () {}\");else if(\"%AsyncGenerator%\"===o){var i=doEval(\"%AsyncGeneratorFunction%\");i&&(s=i.prototype)}else if(\"%AsyncIteratorPrototype%\"===o){var u=doEval(\"%AsyncGenerator%\");u&&Z&&(s=Z(u.prototype))}return ae[o]=s,s},pe={__proto__:null,\"%ArrayBufferPrototype%\":[\"ArrayBuffer\",\"prototype\"],\"%ArrayPrototype%\":[\"Array\",\"prototype\"],\"%ArrayProto_entries%\":[\"Array\",\"prototype\",\"entries\"],\"%ArrayProto_forEach%\":[\"Array\",\"prototype\",\"forEach\"],\"%ArrayProto_keys%\":[\"Array\",\"prototype\",\"keys\"],\"%ArrayProto_values%\":[\"Array\",\"prototype\",\"values\"],\"%AsyncFunctionPrototype%\":[\"AsyncFunction\",\"prototype\"],\"%AsyncGenerator%\":[\"AsyncGeneratorFunction\",\"prototype\"],\"%AsyncGeneratorPrototype%\":[\"AsyncGeneratorFunction\",\"prototype\",\"prototype\"],\"%BooleanPrototype%\":[\"Boolean\",\"prototype\"],\"%DataViewPrototype%\":[\"DataView\",\"prototype\"],\"%DatePrototype%\":[\"Date\",\"prototype\"],\"%ErrorPrototype%\":[\"Error\",\"prototype\"],\"%EvalErrorPrototype%\":[\"EvalError\",\"prototype\"],\"%Float32ArrayPrototype%\":[\"Float32Array\",\"prototype\"],\"%Float64ArrayPrototype%\":[\"Float64Array\",\"prototype\"],\"%FunctionPrototype%\":[\"Function\",\"prototype\"],\"%Generator%\":[\"GeneratorFunction\",\"prototype\"],\"%GeneratorPrototype%\":[\"GeneratorFunction\",\"prototype\",\"prototype\"],\"%Int8ArrayPrototype%\":[\"Int8Array\",\"prototype\"],\"%Int16ArrayPrototype%\":[\"Int16Array\",\"prototype\"],\"%Int32ArrayPrototype%\":[\"Int32Array\",\"prototype\"],\"%JSONParse%\":[\"JSON\",\"parse\"],\"%JSONStringify%\":[\"JSON\",\"stringify\"],\"%MapPrototype%\":[\"Map\",\"prototype\"],\"%NumberPrototype%\":[\"Number\",\"prototype\"],\"%ObjectPrototype%\":[\"Object\",\"prototype\"],\"%ObjProto_toString%\":[\"Object\",\"prototype\",\"toString\"],\"%ObjProto_valueOf%\":[\"Object\",\"prototype\",\"valueOf\"],\"%PromisePrototype%\":[\"Promise\",\"prototype\"],\"%PromiseProto_then%\":[\"Promise\",\"prototype\",\"then\"],\"%Promise_all%\":[\"Promise\",\"all\"],\"%Promise_reject%\":[\"Promise\",\"reject\"],\"%Promise_resolve%\":[\"Promise\",\"resolve\"],\"%RangeErrorPrototype%\":[\"RangeError\",\"prototype\"],\"%ReferenceErrorPrototype%\":[\"ReferenceError\",\"prototype\"],\"%RegExpPrototype%\":[\"RegExp\",\"prototype\"],\"%SetPrototype%\":[\"Set\",\"prototype\"],\"%SharedArrayBufferPrototype%\":[\"SharedArrayBuffer\",\"prototype\"],\"%StringPrototype%\":[\"String\",\"prototype\"],\"%SymbolPrototype%\":[\"Symbol\",\"prototype\"],\"%SyntaxErrorPrototype%\":[\"SyntaxError\",\"prototype\"],\"%TypedArrayPrototype%\":[\"TypedArray\",\"prototype\"],\"%TypeErrorPrototype%\":[\"TypeError\",\"prototype\"],\"%Uint8ArrayPrototype%\":[\"Uint8Array\",\"prototype\"],\"%Uint8ClampedArrayPrototype%\":[\"Uint8ClampedArray\",\"prototype\"],\"%Uint16ArrayPrototype%\":[\"Uint16Array\",\"prototype\"],\"%Uint32ArrayPrototype%\":[\"Uint32Array\",\"prototype\"],\"%URIErrorPrototype%\":[\"URIError\",\"prototype\"],\"%WeakMapPrototype%\":[\"WeakMap\",\"prototype\"],\"%WeakSetPrototype%\":[\"WeakSet\",\"prototype\"]},de=i(66743),fe=i(9957),ye=de.call(Function.call,Array.prototype.concat),be=de.call(Function.apply,Array.prototype.splice),_e=de.call(Function.call,String.prototype.replace),we=de.call(Function.call,String.prototype.slice),Se=de.call(Function.call,RegExp.prototype.exec),xe=/[^%.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|%$))/g,Pe=/\\\\(\\\\)?/g,Te=function getBaseIntrinsic(o,s){var i,u=o;if(fe(pe,u)&&(u=\"%\"+(i=pe[u])[0]+\"%\"),fe(ae,u)){var _=ae[u];if(_===ee&&(_=le(u)),void 0===_&&!s)throw new L(\"intrinsic \"+o+\" exists, but is not available. Please file an issue!\");return{alias:i,name:u,value:_}}throw new j(\"intrinsic \"+o+\" does not exist!\")};o.exports=function GetIntrinsic(o,s){if(\"string\"!=typeof o||0===o.length)throw new L(\"intrinsic name must be a non-empty string\");if(arguments.length>1&&\"boolean\"!=typeof s)throw new L('\"allowMissing\" argument must be a boolean');if(null===Se(/^%?[^%]*%?$/,o))throw new j(\"`%` may not be present anywhere but at the beginning and end of the intrinsic name\");var i=function stringToPath(o){var s=we(o,0,1),i=we(o,-1);if(\"%\"===s&&\"%\"!==i)throw new j(\"invalid intrinsic syntax, expected closing `%`\");if(\"%\"===i&&\"%\"!==s)throw new j(\"invalid intrinsic syntax, expected opening `%`\");var u=[];return _e(o,xe,(function(o,s,i,_){u[u.length]=i?_e(_,Pe,\"$1\"):s||o})),u}(o),u=i.length>0?i[0]:\"\",_=Te(\"%\"+u+\"%\",s),w=_.name,x=_.value,C=!1,B=_.alias;B&&(u=B[0],be(i,ye([0,1],B)));for(var $=1,U=!0;$=i.length){var ee=V(x,z);x=(U=!!ee)&&\"get\"in ee&&!(\"originalValue\"in ee.get)?ee.get:x[z]}else U=fe(x,z),x=x[z];U&&!C&&(ae[w]=x)}}return x}},75795:(o,s,i)=>{\"use strict\";var u=i(70453)(\"%Object.getOwnPropertyDescriptor%\",!0);if(u)try{u([],\"length\")}catch(o){u=null}o.exports=u},30592:(o,s,i)=>{\"use strict\";var u=i(30655),_=function hasPropertyDescriptors(){return!!u};_.hasArrayLengthDefineBug=function hasArrayLengthDefineBug(){if(!u)return null;try{return 1!==u([],\"length\",{value:1}).length}catch(o){return!0}},o.exports=_},80024:o=>{\"use strict\";var s={__proto__:null,foo:{}},i=Object;o.exports=function hasProto(){return{__proto__:s}.foo===s.foo&&!(s instanceof i)}},64039:(o,s,i)=>{\"use strict\";var u=\"undefined\"!=typeof Symbol&&Symbol,_=i(41333);o.exports=function hasNativeSymbols(){return\"function\"==typeof u&&(\"function\"==typeof Symbol&&(\"symbol\"==typeof u(\"foo\")&&(\"symbol\"==typeof Symbol(\"bar\")&&_())))}},41333:o=>{\"use strict\";o.exports=function hasSymbols(){if(\"function\"!=typeof Symbol||\"function\"!=typeof Object.getOwnPropertySymbols)return!1;if(\"symbol\"==typeof Symbol.iterator)return!0;var o={},s=Symbol(\"test\"),i=Object(s);if(\"string\"==typeof s)return!1;if(\"[object Symbol]\"!==Object.prototype.toString.call(s))return!1;if(\"[object Symbol]\"!==Object.prototype.toString.call(i))return!1;for(s in o[s]=42,o)return!1;if(\"function\"==typeof Object.keys&&0!==Object.keys(o).length)return!1;if(\"function\"==typeof Object.getOwnPropertyNames&&0!==Object.getOwnPropertyNames(o).length)return!1;var u=Object.getOwnPropertySymbols(o);if(1!==u.length||u[0]!==s)return!1;if(!Object.prototype.propertyIsEnumerable.call(o,s))return!1;if(\"function\"==typeof Object.getOwnPropertyDescriptor){var _=Object.getOwnPropertyDescriptor(o,s);if(42!==_.value||!0!==_.enumerable)return!1}return!0}},9957:(o,s,i)=>{\"use strict\";var u=Function.prototype.call,_=Object.prototype.hasOwnProperty,w=i(66743);o.exports=w.call(u,_)},45981:o=>{function deepFreeze(o){return o instanceof Map?o.clear=o.delete=o.set=function(){throw new Error(\"map is read-only\")}:o instanceof Set&&(o.add=o.clear=o.delete=function(){throw new Error(\"set is read-only\")}),Object.freeze(o),Object.getOwnPropertyNames(o).forEach((function(s){var i=o[s];\"object\"!=typeof i||Object.isFrozen(i)||deepFreeze(i)})),o}var s=deepFreeze,i=deepFreeze;s.default=i;class Response{constructor(o){void 0===o.data&&(o.data={}),this.data=o.data,this.isMatchIgnored=!1}ignoreMatch(){this.isMatchIgnored=!0}}function escapeHTML(o){return o.replace(/&/g,\"&\").replace(//g,\">\").replace(/\"/g,\""\").replace(/'/g,\"'\")}function inherit(o,...s){const i=Object.create(null);for(const s in o)i[s]=o[s];return s.forEach((function(o){for(const s in o)i[s]=o[s]})),i}const emitsWrappingTags=o=>!!o.kind;class HTMLRenderer{constructor(o,s){this.buffer=\"\",this.classPrefix=s.classPrefix,o.walk(this)}addText(o){this.buffer+=escapeHTML(o)}openNode(o){if(!emitsWrappingTags(o))return;let s=o.kind;o.sublanguage||(s=`${this.classPrefix}${s}`),this.span(s)}closeNode(o){emitsWrappingTags(o)&&(this.buffer+=\"\")}value(){return this.buffer}span(o){this.buffer+=``}}class TokenTree{constructor(){this.rootNode={children:[]},this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(o){this.top.children.push(o)}openNode(o){const s={kind:o,children:[]};this.add(s),this.stack.push(s)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(o){return this.constructor._walk(o,this.rootNode)}static _walk(o,s){return\"string\"==typeof s?o.addText(s):s.children&&(o.openNode(s),s.children.forEach((s=>this._walk(o,s))),o.closeNode(s)),o}static _collapse(o){\"string\"!=typeof o&&o.children&&(o.children.every((o=>\"string\"==typeof o))?o.children=[o.children.join(\"\")]:o.children.forEach((o=>{TokenTree._collapse(o)})))}}class TokenTreeEmitter extends TokenTree{constructor(o){super(),this.options=o}addKeyword(o,s){\"\"!==o&&(this.openNode(s),this.addText(o),this.closeNode())}addText(o){\"\"!==o&&this.add(o)}addSublanguage(o,s){const i=o.root;i.kind=s,i.sublanguage=!0,this.add(i)}toHTML(){return new HTMLRenderer(this,this.options).value()}finalize(){return!0}}function source(o){return o?\"string\"==typeof o?o:o.source:null}const u=/\\[(?:[^\\\\\\]]|\\\\.)*\\]|\\(\\??|\\\\([1-9][0-9]*)|\\\\./;const _=\"[a-zA-Z]\\\\w*\",w=\"[a-zA-Z_]\\\\w*\",x=\"\\\\b\\\\d+(\\\\.\\\\d+)?\",C=\"(-?)(\\\\b0[xX][a-fA-F0-9]+|(\\\\b\\\\d+(\\\\.\\\\d*)?|\\\\.\\\\d+)([eE][-+]?\\\\d+)?)\",j=\"\\\\b(0b[01]+)\",L={begin:\"\\\\\\\\[\\\\s\\\\S]\",relevance:0},B={className:\"string\",begin:\"'\",end:\"'\",illegal:\"\\\\n\",contains:[L]},$={className:\"string\",begin:'\"',end:'\"',illegal:\"\\\\n\",contains:[L]},V={begin:/\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b/},COMMENT=function(o,s,i={}){const u=inherit({className:\"comment\",begin:o,end:s,contains:[]},i);return u.contains.push(V),u.contains.push({className:\"doctag\",begin:\"(?:TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):\",relevance:0}),u},U=COMMENT(\"//\",\"$\"),z=COMMENT(\"/\\\\*\",\"\\\\*/\"),Y=COMMENT(\"#\",\"$\"),Z={className:\"number\",begin:x,relevance:0},ee={className:\"number\",begin:C,relevance:0},ie={className:\"number\",begin:j,relevance:0},ae={className:\"number\",begin:x+\"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?\",relevance:0},ce={begin:/(?=\\/[^/\\n]*\\/)/,contains:[{className:\"regexp\",begin:/\\//,end:/\\/[gimuy]*/,illegal:/\\n/,contains:[L,{begin:/\\[/,end:/\\]/,relevance:0,contains:[L]}]}]},le={className:\"title\",begin:_,relevance:0},pe={className:\"title\",begin:w,relevance:0},de={begin:\"\\\\.\\\\s*\"+w,relevance:0};var fe=Object.freeze({__proto__:null,MATCH_NOTHING_RE:/\\b\\B/,IDENT_RE:_,UNDERSCORE_IDENT_RE:w,NUMBER_RE:x,C_NUMBER_RE:C,BINARY_NUMBER_RE:j,RE_STARTERS_RE:\"!|!=|!==|%|%=|&|&&|&=|\\\\*|\\\\*=|\\\\+|\\\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\\\?|\\\\[|\\\\{|\\\\(|\\\\^|\\\\^=|\\\\||\\\\|=|\\\\|\\\\||~\",SHEBANG:(o={})=>{const s=/^#![ ]*\\//;return o.binary&&(o.begin=function concat(...o){return o.map((o=>source(o))).join(\"\")}(s,/.*\\b/,o.binary,/\\b.*/)),inherit({className:\"meta\",begin:s,end:/$/,relevance:0,\"on:begin\":(o,s)=>{0!==o.index&&s.ignoreMatch()}},o)},BACKSLASH_ESCAPE:L,APOS_STRING_MODE:B,QUOTE_STRING_MODE:$,PHRASAL_WORDS_MODE:V,COMMENT,C_LINE_COMMENT_MODE:U,C_BLOCK_COMMENT_MODE:z,HASH_COMMENT_MODE:Y,NUMBER_MODE:Z,C_NUMBER_MODE:ee,BINARY_NUMBER_MODE:ie,CSS_NUMBER_MODE:ae,REGEXP_MODE:ce,TITLE_MODE:le,UNDERSCORE_TITLE_MODE:pe,METHOD_GUARD:de,END_SAME_AS_BEGIN:function(o){return Object.assign(o,{\"on:begin\":(o,s)=>{s.data._beginMatch=o[1]},\"on:end\":(o,s)=>{s.data._beginMatch!==o[1]&&s.ignoreMatch()}})}});function skipIfhasPrecedingDot(o,s){\".\"===o.input[o.index-1]&&s.ignoreMatch()}function beginKeywords(o,s){s&&o.beginKeywords&&(o.begin=\"\\\\b(\"+o.beginKeywords.split(\" \").join(\"|\")+\")(?!\\\\.)(?=\\\\b|\\\\s)\",o.__beforeBegin=skipIfhasPrecedingDot,o.keywords=o.keywords||o.beginKeywords,delete o.beginKeywords,void 0===o.relevance&&(o.relevance=0))}function compileIllegal(o,s){Array.isArray(o.illegal)&&(o.illegal=function either(...o){return\"(\"+o.map((o=>source(o))).join(\"|\")+\")\"}(...o.illegal))}function compileMatch(o,s){if(o.match){if(o.begin||o.end)throw new Error(\"begin & end are not supported with match\");o.begin=o.match,delete o.match}}function compileRelevance(o,s){void 0===o.relevance&&(o.relevance=1)}const ye=[\"of\",\"and\",\"for\",\"in\",\"not\",\"or\",\"if\",\"then\",\"parent\",\"list\",\"value\"],be=\"keyword\";function compileKeywords(o,s,i=be){const u={};return\"string\"==typeof o?compileList(i,o.split(\" \")):Array.isArray(o)?compileList(i,o):Object.keys(o).forEach((function(i){Object.assign(u,compileKeywords(o[i],s,i))})),u;function compileList(o,i){s&&(i=i.map((o=>o.toLowerCase()))),i.forEach((function(s){const i=s.split(\"|\");u[i[0]]=[o,scoreForKeyword(i[0],i[1])]}))}}function scoreForKeyword(o,s){return s?Number(s):function commonKeyword(o){return ye.includes(o.toLowerCase())}(o)?0:1}function compileLanguage(o,{plugins:s}){function langRe(s,i){return new RegExp(source(s),\"m\"+(o.case_insensitive?\"i\":\"\")+(i?\"g\":\"\"))}class MultiRegex{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(o,s){s.position=this.position++,this.matchIndexes[this.matchAt]=s,this.regexes.push([s,o]),this.matchAt+=function countMatchGroups(o){return new RegExp(o.toString()+\"|\").exec(\"\").length-1}(o)+1}compile(){0===this.regexes.length&&(this.exec=()=>null);const o=this.regexes.map((o=>o[1]));this.matcherRe=langRe(function join(o,s=\"|\"){let i=0;return o.map((o=>{i+=1;const s=i;let _=source(o),w=\"\";for(;_.length>0;){const o=u.exec(_);if(!o){w+=_;break}w+=_.substring(0,o.index),_=_.substring(o.index+o[0].length),\"\\\\\"===o[0][0]&&o[1]?w+=\"\\\\\"+String(Number(o[1])+s):(w+=o[0],\"(\"===o[0]&&i++)}return w})).map((o=>`(${o})`)).join(s)}(o),!0),this.lastIndex=0}exec(o){this.matcherRe.lastIndex=this.lastIndex;const s=this.matcherRe.exec(o);if(!s)return null;const i=s.findIndex(((o,s)=>s>0&&void 0!==o)),u=this.matchIndexes[i];return s.splice(0,i),Object.assign(s,u)}}class ResumableMultiRegex{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(o){if(this.multiRegexes[o])return this.multiRegexes[o];const s=new MultiRegex;return this.rules.slice(o).forEach((([o,i])=>s.addRule(o,i))),s.compile(),this.multiRegexes[o]=s,s}resumingScanAtSamePosition(){return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(o,s){this.rules.push([o,s]),\"begin\"===s.type&&this.count++}exec(o){const s=this.getMatcher(this.regexIndex);s.lastIndex=this.lastIndex;let i=s.exec(o);if(this.resumingScanAtSamePosition())if(i&&i.index===this.lastIndex);else{const s=this.getMatcher(0);s.lastIndex=this.lastIndex+1,i=s.exec(o)}return i&&(this.regexIndex+=i.position+1,this.regexIndex===this.count&&this.considerAll()),i}}if(o.compilerExtensions||(o.compilerExtensions=[]),o.contains&&o.contains.includes(\"self\"))throw new Error(\"ERR: contains `self` is not supported at the top-level of a language. See documentation.\");return o.classNameAliases=inherit(o.classNameAliases||{}),function compileMode(s,i){const u=s;if(s.isCompiled)return u;[compileMatch].forEach((o=>o(s,i))),o.compilerExtensions.forEach((o=>o(s,i))),s.__beforeBegin=null,[beginKeywords,compileIllegal,compileRelevance].forEach((o=>o(s,i))),s.isCompiled=!0;let _=null;if(\"object\"==typeof s.keywords&&(_=s.keywords.$pattern,delete s.keywords.$pattern),s.keywords&&(s.keywords=compileKeywords(s.keywords,o.case_insensitive)),s.lexemes&&_)throw new Error(\"ERR: Prefer `keywords.$pattern` to `mode.lexemes`, BOTH are not allowed. (see mode reference) \");return _=_||s.lexemes||/\\w+/,u.keywordPatternRe=langRe(_,!0),i&&(s.begin||(s.begin=/\\B|\\b/),u.beginRe=langRe(s.begin),s.endSameAsBegin&&(s.end=s.begin),s.end||s.endsWithParent||(s.end=/\\B|\\b/),s.end&&(u.endRe=langRe(s.end)),u.terminatorEnd=source(s.end)||\"\",s.endsWithParent&&i.terminatorEnd&&(u.terminatorEnd+=(s.end?\"|\":\"\")+i.terminatorEnd)),s.illegal&&(u.illegalRe=langRe(s.illegal)),s.contains||(s.contains=[]),s.contains=[].concat(...s.contains.map((function(o){return function expandOrCloneMode(o){o.variants&&!o.cachedVariants&&(o.cachedVariants=o.variants.map((function(s){return inherit(o,{variants:null},s)})));if(o.cachedVariants)return o.cachedVariants;if(dependencyOnParent(o))return inherit(o,{starts:o.starts?inherit(o.starts):null});if(Object.isFrozen(o))return inherit(o);return o}(\"self\"===o?s:o)}))),s.contains.forEach((function(o){compileMode(o,u)})),s.starts&&compileMode(s.starts,i),u.matcher=function buildModeRegex(o){const s=new ResumableMultiRegex;return o.contains.forEach((o=>s.addRule(o.begin,{rule:o,type:\"begin\"}))),o.terminatorEnd&&s.addRule(o.terminatorEnd,{type:\"end\"}),o.illegal&&s.addRule(o.illegal,{type:\"illegal\"}),s}(u),u}(o)}function dependencyOnParent(o){return!!o&&(o.endsWithParent||dependencyOnParent(o.starts))}function BuildVuePlugin(o){const s={props:[\"language\",\"code\",\"autodetect\"],data:function(){return{detectedLanguage:\"\",unknownLanguage:!1}},computed:{className(){return this.unknownLanguage?\"\":\"hljs \"+this.detectedLanguage},highlighted(){if(!this.autoDetect&&!o.getLanguage(this.language))return console.warn(`The language \"${this.language}\" you specified could not be found.`),this.unknownLanguage=!0,escapeHTML(this.code);let s={};return this.autoDetect?(s=o.highlightAuto(this.code),this.detectedLanguage=s.language):(s=o.highlight(this.language,this.code,this.ignoreIllegals),this.detectedLanguage=this.language),s.value},autoDetect(){return!this.language||function hasValueOrEmptyAttribute(o){return Boolean(o||\"\"===o)}(this.autodetect)},ignoreIllegals:()=>!0},render(o){return o(\"pre\",{},[o(\"code\",{class:this.className,domProps:{innerHTML:this.highlighted}})])}};return{Component:s,VuePlugin:{install(o){o.component(\"highlightjs\",s)}}}}const _e={\"after:highlightElement\":({el:o,result:s,text:i})=>{const u=nodeStream(o);if(!u.length)return;const _=document.createElement(\"div\");_.innerHTML=s.value,s.value=function mergeStreams(o,s,i){let u=0,_=\"\";const w=[];function selectStream(){return o.length&&s.length?o[0].offset!==s[0].offset?o[0].offset\"}function close(o){_+=\"\"}function render(o){(\"start\"===o.event?open:close)(o.node)}for(;o.length||s.length;){let s=selectStream();if(_+=escapeHTML(i.substring(u,s[0].offset)),u=s[0].offset,s===o){w.reverse().forEach(close);do{render(s.splice(0,1)[0]),s=selectStream()}while(s===o&&s.length&&s[0].offset===u);w.reverse().forEach(open)}else\"start\"===s[0].event?w.push(s[0].node):w.pop(),render(s.splice(0,1)[0])}return _+escapeHTML(i.substr(u))}(u,nodeStream(_),i)}};function tag(o){return o.nodeName.toLowerCase()}function nodeStream(o){const s=[];return function _nodeStream(o,i){for(let u=o.firstChild;u;u=u.nextSibling)3===u.nodeType?i+=u.nodeValue.length:1===u.nodeType&&(s.push({event:\"start\",offset:i,node:u}),i=_nodeStream(u,i),tag(u).match(/br|hr|img|input/)||s.push({event:\"stop\",offset:i,node:u}));return i}(o,0),s}const we={},error=o=>{console.error(o)},warn=(o,...s)=>{console.log(`WARN: ${o}`,...s)},deprecated=(o,s)=>{we[`${o}/${s}`]||(console.log(`Deprecated as of ${o}. ${s}`),we[`${o}/${s}`]=!0)},Se=escapeHTML,xe=inherit,Pe=Symbol(\"nomatch\");var Te=function(o){const i=Object.create(null),u=Object.create(null),_=[];let w=!0;const x=/(^(<[^>]+>|\\t|)+|\\n)/gm,C=\"Could not find the language '{}', did you forget to load/include a language module?\",j={disableAutodetect:!0,name:\"Plain text\",contains:[]};let L={noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\\blang(?:uage)?-([\\w-]+)\\b/i,classPrefix:\"hljs-\",tabReplace:null,useBR:!1,languages:null,__emitter:TokenTreeEmitter};function shouldNotHighlight(o){return L.noHighlightRe.test(o)}function highlight(o,s,i,u){let _=\"\",w=\"\";\"object\"==typeof s?(_=o,i=s.ignoreIllegals,w=s.language,u=void 0):(deprecated(\"10.7.0\",\"highlight(lang, code, ...args) has been deprecated.\"),deprecated(\"10.7.0\",\"Please use highlight(code, options) instead.\\nhttps://github.com/highlightjs/highlight.js/issues/2277\"),w=o,_=s);const x={code:_,language:w};fire(\"before:highlight\",x);const C=x.result?x.result:_highlight(x.language,x.code,i,u);return C.code=x.code,fire(\"after:highlight\",C),C}function _highlight(o,s,u,x){function keywordData(o,s){const i=B.case_insensitive?s[0].toLowerCase():s[0];return Object.prototype.hasOwnProperty.call(o.keywords,i)&&o.keywords[i]}function processBuffer(){null!=U.subLanguage?function processSubLanguage(){if(\"\"===Z)return;let o=null;if(\"string\"==typeof U.subLanguage){if(!i[U.subLanguage])return void Y.addText(Z);o=_highlight(U.subLanguage,Z,!0,z[U.subLanguage]),z[U.subLanguage]=o.top}else o=highlightAuto(Z,U.subLanguage.length?U.subLanguage:null);U.relevance>0&&(ee+=o.relevance),Y.addSublanguage(o.emitter,o.language)}():function processKeywords(){if(!U.keywords)return void Y.addText(Z);let o=0;U.keywordPatternRe.lastIndex=0;let s=U.keywordPatternRe.exec(Z),i=\"\";for(;s;){i+=Z.substring(o,s.index);const u=keywordData(U,s);if(u){const[o,_]=u;if(Y.addText(i),i=\"\",ee+=_,o.startsWith(\"_\"))i+=s[0];else{const i=B.classNameAliases[o]||o;Y.addKeyword(s[0],i)}}else i+=s[0];o=U.keywordPatternRe.lastIndex,s=U.keywordPatternRe.exec(Z)}i+=Z.substr(o),Y.addText(i)}(),Z=\"\"}function startNewMode(o){return o.className&&Y.openNode(B.classNameAliases[o.className]||o.className),U=Object.create(o,{parent:{value:U}}),U}function endOfMode(o,s,i){let u=function startsWith(o,s){const i=o&&o.exec(s);return i&&0===i.index}(o.endRe,i);if(u){if(o[\"on:end\"]){const i=new Response(o);o[\"on:end\"](s,i),i.isMatchIgnored&&(u=!1)}if(u){for(;o.endsParent&&o.parent;)o=o.parent;return o}}if(o.endsWithParent)return endOfMode(o.parent,s,i)}function doIgnore(o){return 0===U.matcher.regexIndex?(Z+=o[0],1):(ce=!0,0)}function doBeginMatch(o){const s=o[0],i=o.rule,u=new Response(i),_=[i.__beforeBegin,i[\"on:begin\"]];for(const i of _)if(i&&(i(o,u),u.isMatchIgnored))return doIgnore(s);return i&&i.endSameAsBegin&&(i.endRe=function escape(o){return new RegExp(o.replace(/[-/\\\\^$*+?.()|[\\]{}]/g,\"\\\\$&\"),\"m\")}(s)),i.skip?Z+=s:(i.excludeBegin&&(Z+=s),processBuffer(),i.returnBegin||i.excludeBegin||(Z=s)),startNewMode(i),i.returnBegin?0:s.length}function doEndMatch(o){const i=o[0],u=s.substr(o.index),_=endOfMode(U,o,u);if(!_)return Pe;const w=U;w.skip?Z+=i:(w.returnEnd||w.excludeEnd||(Z+=i),processBuffer(),w.excludeEnd&&(Z=i));do{U.className&&Y.closeNode(),U.skip||U.subLanguage||(ee+=U.relevance),U=U.parent}while(U!==_.parent);return _.starts&&(_.endSameAsBegin&&(_.starts.endRe=_.endRe),startNewMode(_.starts)),w.returnEnd?0:i.length}let j={};function processLexeme(i,_){const x=_&&_[0];if(Z+=i,null==x)return processBuffer(),0;if(\"begin\"===j.type&&\"end\"===_.type&&j.index===_.index&&\"\"===x){if(Z+=s.slice(_.index,_.index+1),!w){const s=new Error(\"0 width match regex\");throw s.languageName=o,s.badRule=j.rule,s}return 1}if(j=_,\"begin\"===_.type)return doBeginMatch(_);if(\"illegal\"===_.type&&!u){const o=new Error('Illegal lexeme \"'+x+'\" for mode \"'+(U.className||\"\")+'\"');throw o.mode=U,o}if(\"end\"===_.type){const o=doEndMatch(_);if(o!==Pe)return o}if(\"illegal\"===_.type&&\"\"===x)return 1;if(ae>1e5&&ae>3*_.index){throw new Error(\"potential infinite loop, way more iterations than matches\")}return Z+=x,x.length}const B=getLanguage(o);if(!B)throw error(C.replace(\"{}\",o)),new Error('Unknown language: \"'+o+'\"');const $=compileLanguage(B,{plugins:_});let V=\"\",U=x||$;const z={},Y=new L.__emitter(L);!function processContinuations(){const o=[];for(let s=U;s!==B;s=s.parent)s.className&&o.unshift(s.className);o.forEach((o=>Y.openNode(o)))}();let Z=\"\",ee=0,ie=0,ae=0,ce=!1;try{for(U.matcher.considerAll();;){ae++,ce?ce=!1:U.matcher.considerAll(),U.matcher.lastIndex=ie;const o=U.matcher.exec(s);if(!o)break;const i=processLexeme(s.substring(ie,o.index),o);ie=o.index+i}return processLexeme(s.substr(ie)),Y.closeAllNodes(),Y.finalize(),V=Y.toHTML(),{relevance:Math.floor(ee),value:V,language:o,illegal:!1,emitter:Y,top:U}}catch(i){if(i.message&&i.message.includes(\"Illegal\"))return{illegal:!0,illegalBy:{msg:i.message,context:s.slice(ie-100,ie+100),mode:i.mode},sofar:V,relevance:0,value:Se(s),emitter:Y};if(w)return{illegal:!1,relevance:0,value:Se(s),emitter:Y,language:o,top:U,errorRaised:i};throw i}}function highlightAuto(o,s){s=s||L.languages||Object.keys(i);const u=function justTextHighlightResult(o){const s={relevance:0,emitter:new L.__emitter(L),value:Se(o),illegal:!1,top:j};return s.emitter.addText(o),s}(o),_=s.filter(getLanguage).filter(autoDetection).map((s=>_highlight(s,o,!1)));_.unshift(u);const w=_.sort(((o,s)=>{if(o.relevance!==s.relevance)return s.relevance-o.relevance;if(o.language&&s.language){if(getLanguage(o.language).supersetOf===s.language)return 1;if(getLanguage(s.language).supersetOf===o.language)return-1}return 0})),[x,C]=w,B=x;return B.second_best=C,B}const B={\"before:highlightElement\":({el:o})=>{L.useBR&&(o.innerHTML=o.innerHTML.replace(/\\n/g,\"\").replace(//g,\"\\n\"))},\"after:highlightElement\":({result:o})=>{L.useBR&&(o.value=o.value.replace(/\\n/g,\"
\"))}},$=/^(<[^>]+>|\\t)+/gm,V={\"after:highlightElement\":({result:o})=>{L.tabReplace&&(o.value=o.value.replace($,(o=>o.replace(/\\t/g,L.tabReplace))))}};function highlightElement(o){let s=null;const i=function blockLanguage(o){let s=o.className+\" \";s+=o.parentNode?o.parentNode.className:\"\";const i=L.languageDetectRe.exec(s);if(i){const s=getLanguage(i[1]);return s||(warn(C.replace(\"{}\",i[1])),warn(\"Falling back to no-highlight mode for this block.\",o)),s?i[1]:\"no-highlight\"}return s.split(/\\s+/).find((o=>shouldNotHighlight(o)||getLanguage(o)))}(o);if(shouldNotHighlight(i))return;fire(\"before:highlightElement\",{el:o,language:i}),s=o;const _=s.textContent,w=i?highlight(_,{language:i,ignoreIllegals:!0}):highlightAuto(_);fire(\"after:highlightElement\",{el:o,result:w,text:_}),o.innerHTML=w.value,function updateClassName(o,s,i){const _=s?u[s]:i;o.classList.add(\"hljs\"),_&&o.classList.add(_)}(o,i,w.language),o.result={language:w.language,re:w.relevance,relavance:w.relevance},w.second_best&&(o.second_best={language:w.second_best.language,re:w.second_best.relevance,relavance:w.second_best.relevance})}const initHighlighting=()=>{if(initHighlighting.called)return;initHighlighting.called=!0,deprecated(\"10.6.0\",\"initHighlighting() is deprecated. Use highlightAll() instead.\");document.querySelectorAll(\"pre code\").forEach(highlightElement)};let U=!1;function highlightAll(){if(\"loading\"===document.readyState)return void(U=!0);document.querySelectorAll(\"pre code\").forEach(highlightElement)}function getLanguage(o){return o=(o||\"\").toLowerCase(),i[o]||i[u[o]]}function registerAliases(o,{languageName:s}){\"string\"==typeof o&&(o=[o]),o.forEach((o=>{u[o.toLowerCase()]=s}))}function autoDetection(o){const s=getLanguage(o);return s&&!s.disableAutodetect}function fire(o,s){const i=o;_.forEach((function(o){o[i]&&o[i](s)}))}\"undefined\"!=typeof window&&window.addEventListener&&window.addEventListener(\"DOMContentLoaded\",(function boot(){U&&highlightAll()}),!1),Object.assign(o,{highlight,highlightAuto,highlightAll,fixMarkup:function deprecateFixMarkup(o){return deprecated(\"10.2.0\",\"fixMarkup will be removed entirely in v11.0\"),deprecated(\"10.2.0\",\"Please see https://github.com/highlightjs/highlight.js/issues/2534\"),function fixMarkup(o){return L.tabReplace||L.useBR?o.replace(x,(o=>\"\\n\"===o?L.useBR?\"
\":o:L.tabReplace?o.replace(/\\t/g,L.tabReplace):o)):o}(o)},highlightElement,highlightBlock:function deprecateHighlightBlock(o){return deprecated(\"10.7.0\",\"highlightBlock will be removed entirely in v12.0\"),deprecated(\"10.7.0\",\"Please use highlightElement now.\"),highlightElement(o)},configure:function configure(o){o.useBR&&(deprecated(\"10.3.0\",\"'useBR' will be removed entirely in v11.0\"),deprecated(\"10.3.0\",\"Please see https://github.com/highlightjs/highlight.js/issues/2559\")),L=xe(L,o)},initHighlighting,initHighlightingOnLoad:function initHighlightingOnLoad(){deprecated(\"10.6.0\",\"initHighlightingOnLoad() is deprecated. Use highlightAll() instead.\"),U=!0},registerLanguage:function registerLanguage(s,u){let _=null;try{_=u(o)}catch(o){if(error(\"Language definition for '{}' could not be registered.\".replace(\"{}\",s)),!w)throw o;error(o),_=j}_.name||(_.name=s),i[s]=_,_.rawDefinition=u.bind(null,o),_.aliases&®isterAliases(_.aliases,{languageName:s})},unregisterLanguage:function unregisterLanguage(o){delete i[o];for(const s of Object.keys(u))u[s]===o&&delete u[s]},listLanguages:function listLanguages(){return Object.keys(i)},getLanguage,registerAliases,requireLanguage:function requireLanguage(o){deprecated(\"10.4.0\",\"requireLanguage will be removed entirely in v11.\"),deprecated(\"10.4.0\",\"Please see https://github.com/highlightjs/highlight.js/pull/2844\");const s=getLanguage(o);if(s)return s;throw new Error(\"The '{}' language is required, but not loaded.\".replace(\"{}\",o))},autoDetection,inherit:xe,addPlugin:function addPlugin(o){!function upgradePluginAPI(o){o[\"before:highlightBlock\"]&&!o[\"before:highlightElement\"]&&(o[\"before:highlightElement\"]=s=>{o[\"before:highlightBlock\"](Object.assign({block:s.el},s))}),o[\"after:highlightBlock\"]&&!o[\"after:highlightElement\"]&&(o[\"after:highlightElement\"]=s=>{o[\"after:highlightBlock\"](Object.assign({block:s.el},s))})}(o),_.push(o)},vuePlugin:BuildVuePlugin(o).VuePlugin}),o.debugMode=function(){w=!1},o.safeMode=function(){w=!0},o.versionString=\"10.7.3\";for(const o in fe)\"object\"==typeof fe[o]&&s(fe[o]);return Object.assign(o,fe),o.addPlugin(B),o.addPlugin(_e),o.addPlugin(V),o}({});o.exports=Te},35344:o=>{function concat(...o){return o.map((o=>function source(o){return o?\"string\"==typeof o?o:o.source:null}(o))).join(\"\")}o.exports=function bash(o){const s={},i={begin:/\\$\\{/,end:/\\}/,contains:[\"self\",{begin:/:-/,contains:[s]}]};Object.assign(s,{className:\"variable\",variants:[{begin:concat(/\\$[\\w\\d#@][\\w\\d_]*/,\"(?![\\\\w\\\\d])(?![$])\")},i]});const u={className:\"subst\",begin:/\\$\\(/,end:/\\)/,contains:[o.BACKSLASH_ESCAPE]},_={begin:/<<-?\\s*(?=\\w+)/,starts:{contains:[o.END_SAME_AS_BEGIN({begin:/(\\w+)/,end:/(\\w+)/,className:\"string\"})]}},w={className:\"string\",begin:/\"/,end:/\"/,contains:[o.BACKSLASH_ESCAPE,s,u]};u.contains.push(w);const x={begin:/\\$\\(\\(/,end:/\\)\\)/,contains:[{begin:/\\d+#[0-9a-f]+/,className:\"number\"},o.NUMBER_MODE,s]},C=o.SHEBANG({binary:`(${[\"fish\",\"bash\",\"zsh\",\"sh\",\"csh\",\"ksh\",\"tcsh\",\"dash\",\"scsh\"].join(\"|\")})`,relevance:10}),j={className:\"function\",begin:/\\w[\\w\\d_]*\\s*\\(\\s*\\)\\s*\\{/,returnBegin:!0,contains:[o.inherit(o.TITLE_MODE,{begin:/\\w[\\w\\d_]*/})],relevance:0};return{name:\"Bash\",aliases:[\"sh\",\"zsh\"],keywords:{$pattern:/\\b[a-z._-]+\\b/,keyword:\"if then else elif fi for while in do done case esac function\",literal:\"true false\",built_in:\"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp\"},contains:[C,o.SHEBANG(),j,x,o.HASH_COMMENT_MODE,_,w,{className:\"\",begin:/\\\\\"/},{className:\"string\",begin:/'/,end:/'/},s]}}},73402:o=>{function concat(...o){return o.map((o=>function source(o){return o?\"string\"==typeof o?o:o.source:null}(o))).join(\"\")}o.exports=function http(o){const s=\"HTTP/(2|1\\\\.[01])\",i={className:\"attribute\",begin:concat(\"^\",/[A-Za-z][A-Za-z0-9-]*/,\"(?=\\\\:\\\\s)\"),starts:{contains:[{className:\"punctuation\",begin:/: /,relevance:0,starts:{end:\"$\",relevance:0}}]}},u=[i,{begin:\"\\\\n\\\\n\",starts:{subLanguage:[],endsWithParent:!0}}];return{name:\"HTTP\",aliases:[\"https\"],illegal:/\\S/,contains:[{begin:\"^(?=\"+s+\" \\\\d{3})\",end:/$/,contains:[{className:\"meta\",begin:s},{className:\"number\",begin:\"\\\\b\\\\d{3}\\\\b\"}],starts:{end:/\\b\\B/,illegal:/\\S/,contains:u}},{begin:\"(?=^[A-Z]+ (.*?) \"+s+\"$)\",end:/$/,contains:[{className:\"string\",begin:\" \",end:\" \",excludeBegin:!0,excludeEnd:!0},{className:\"meta\",begin:s},{className:\"keyword\",begin:\"[A-Z]+\"}],starts:{end:/\\b\\B/,illegal:/\\S/,contains:u}},o.inherit(i,{relevance:0})]}}},95089:o=>{const s=\"[A-Za-z$_][0-9A-Za-z$_]*\",i=[\"as\",\"in\",\"of\",\"if\",\"for\",\"while\",\"finally\",\"var\",\"new\",\"function\",\"do\",\"return\",\"void\",\"else\",\"break\",\"catch\",\"instanceof\",\"with\",\"throw\",\"case\",\"default\",\"try\",\"switch\",\"continue\",\"typeof\",\"delete\",\"let\",\"yield\",\"const\",\"class\",\"debugger\",\"async\",\"await\",\"static\",\"import\",\"from\",\"export\",\"extends\"],u=[\"true\",\"false\",\"null\",\"undefined\",\"NaN\",\"Infinity\"],_=[].concat([\"setInterval\",\"setTimeout\",\"clearInterval\",\"clearTimeout\",\"require\",\"exports\",\"eval\",\"isFinite\",\"isNaN\",\"parseFloat\",\"parseInt\",\"decodeURI\",\"decodeURIComponent\",\"encodeURI\",\"encodeURIComponent\",\"escape\",\"unescape\"],[\"arguments\",\"this\",\"super\",\"console\",\"window\",\"document\",\"localStorage\",\"module\",\"global\"],[\"Intl\",\"DataView\",\"Number\",\"Math\",\"Date\",\"String\",\"RegExp\",\"Object\",\"Function\",\"Boolean\",\"Error\",\"Symbol\",\"Set\",\"Map\",\"WeakSet\",\"WeakMap\",\"Proxy\",\"Reflect\",\"JSON\",\"Promise\",\"Float64Array\",\"Int16Array\",\"Int32Array\",\"Int8Array\",\"Uint16Array\",\"Uint32Array\",\"Float32Array\",\"Array\",\"Uint8Array\",\"Uint8ClampedArray\",\"ArrayBuffer\",\"BigInt64Array\",\"BigUint64Array\",\"BigInt\"],[\"EvalError\",\"InternalError\",\"RangeError\",\"ReferenceError\",\"SyntaxError\",\"TypeError\",\"URIError\"]);function lookahead(o){return concat(\"(?=\",o,\")\")}function concat(...o){return o.map((o=>function source(o){return o?\"string\"==typeof o?o:o.source:null}(o))).join(\"\")}o.exports=function javascript(o){const w=s,x=\"<>\",C=\"\",j={begin:/<[A-Za-z0-9\\\\._:-]+/,end:/\\/[A-Za-z0-9\\\\._:-]+>|\\/>/,isTrulyOpeningTag:(o,s)=>{const i=o[0].length+o.index,u=o.input[i];\"<\"!==u?\">\"===u&&(((o,{after:s})=>{const i=\"\",returnBegin:!0,end:\"\\\\s*=>\",contains:[{className:\"params\",variants:[{begin:o.UNDERSCORE_IDENT_RE,relevance:0},{className:null,begin:/\\(\\s*\\)/,skip:!0},{begin:/\\(/,end:/\\)/,excludeBegin:!0,excludeEnd:!0,keywords:L,contains:le}]}]},{begin:/,/,relevance:0},{className:\"\",begin:/\\s/,end:/\\s*/,skip:!0},{variants:[{begin:x,end:C},{begin:j.begin,\"on:begin\":j.isTrulyOpeningTag,end:j.end}],subLanguage:\"xml\",contains:[{begin:j.begin,end:j.end,skip:!0,contains:[\"self\"]}]}],relevance:0},{className:\"function\",beginKeywords:\"function\",end:/[{;]/,excludeEnd:!0,keywords:L,contains:[\"self\",o.inherit(o.TITLE_MODE,{begin:w}),pe],illegal:/%/},{beginKeywords:\"while if switch catch for\"},{className:\"function\",begin:o.UNDERSCORE_IDENT_RE+\"\\\\([^()]*(\\\\([^()]*(\\\\([^()]*\\\\)[^()]*)*\\\\)[^()]*)*\\\\)\\\\s*\\\\{\",returnBegin:!0,contains:[pe,o.inherit(o.TITLE_MODE,{begin:w})]},{variants:[{begin:\"\\\\.\"+w},{begin:\"\\\\$\"+w}],relevance:0},{className:\"class\",beginKeywords:\"class\",end:/[{;=]/,excludeEnd:!0,illegal:/[:\"[\\]]/,contains:[{beginKeywords:\"extends\"},o.UNDERSCORE_TITLE_MODE]},{begin:/\\b(?=constructor)/,end:/[{;]/,excludeEnd:!0,contains:[o.inherit(o.TITLE_MODE,{begin:w}),\"self\",pe]},{begin:\"(get|set)\\\\s+(?=\"+w+\"\\\\()\",end:/\\{/,keywords:\"get set\",contains:[o.inherit(o.TITLE_MODE,{begin:w}),{begin:/\\(\\)/},pe]},{begin:/\\$[(.]/}]}}},65772:o=>{o.exports=function json(o){const s={literal:\"true false null\"},i=[o.C_LINE_COMMENT_MODE,o.C_BLOCK_COMMENT_MODE],u=[o.QUOTE_STRING_MODE,o.C_NUMBER_MODE],_={end:\",\",endsWithParent:!0,excludeEnd:!0,contains:u,keywords:s},w={begin:/\\{/,end:/\\}/,contains:[{className:\"attr\",begin:/\"/,end:/\"/,contains:[o.BACKSLASH_ESCAPE],illegal:\"\\\\n\"},o.inherit(_,{begin:/:/})].concat(i),illegal:\"\\\\S\"},x={begin:\"\\\\[\",end:\"\\\\]\",contains:[o.inherit(_)],illegal:\"\\\\S\"};return u.push(w,x),i.forEach((function(o){u.push(o)})),{name:\"JSON\",contains:u,keywords:s,illegal:\"\\\\S\"}}},26571:o=>{o.exports=function powershell(o){const s={$pattern:/-?[A-z\\.\\-]+\\b/,keyword:\"if else foreach return do while until elseif begin for trap data dynamicparam end break throw param continue finally in switch exit filter try process catch hidden static parameter\",built_in:\"ac asnp cat cd CFS chdir clc clear clhy cli clp cls clv cnsn compare copy cp cpi cpp curl cvpa dbp del diff dir dnsn ebp echo|0 epal epcsv epsn erase etsn exsn fc fhx fl ft fw gal gbp gc gcb gci gcm gcs gdr gerr ghy gi gin gjb gl gm gmo gp gps gpv group gsn gsnp gsv gtz gu gv gwmi h history icm iex ihy ii ipal ipcsv ipmo ipsn irm ise iwmi iwr kill lp ls man md measure mi mount move mp mv nal ndr ni nmo npssc nsn nv ogv oh popd ps pushd pwd r rbp rcjb rcsn rd rdr ren ri rjb rm rmdir rmo rni rnp rp rsn rsnp rujb rv rvpa rwmi sajb sal saps sasv sbp sc scb select set shcm si sl sleep sls sort sp spjb spps spsv start stz sujb sv swmi tee trcm type wget where wjb write\"},i={begin:\"`[\\\\s\\\\S]\",relevance:0},u={className:\"variable\",variants:[{begin:/\\$\\B/},{className:\"keyword\",begin:/\\$this/},{begin:/\\$[\\w\\d][\\w\\d_:]*/}]},_={className:\"string\",variants:[{begin:/\"/,end:/\"/},{begin:/@\"/,end:/^\"@/}],contains:[i,u,{className:\"variable\",begin:/\\$[A-z]/,end:/[^A-z]/}]},w={className:\"string\",variants:[{begin:/'/,end:/'/},{begin:/@'/,end:/^'@/}]},x=o.inherit(o.COMMENT(null,null),{variants:[{begin:/#/,end:/$/},{begin:/<#/,end:/#>/}],contains:[{className:\"doctag\",variants:[{begin:/\\.(synopsis|description|example|inputs|outputs|notes|link|component|role|functionality)/},{begin:/\\.(parameter|forwardhelptargetname|forwardhelpcategory|remotehelprunspace|externalhelp)\\s+\\S+/}]}]}),C={className:\"built_in\",variants:[{begin:\"(\".concat(\"Add|Clear|Close|Copy|Enter|Exit|Find|Format|Get|Hide|Join|Lock|Move|New|Open|Optimize|Pop|Push|Redo|Remove|Rename|Reset|Resize|Search|Select|Set|Show|Skip|Split|Step|Switch|Undo|Unlock|Watch|Backup|Checkpoint|Compare|Compress|Convert|ConvertFrom|ConvertTo|Dismount|Edit|Expand|Export|Group|Import|Initialize|Limit|Merge|Mount|Out|Publish|Restore|Save|Sync|Unpublish|Update|Approve|Assert|Build|Complete|Confirm|Deny|Deploy|Disable|Enable|Install|Invoke|Register|Request|Restart|Resume|Start|Stop|Submit|Suspend|Uninstall|Unregister|Wait|Debug|Measure|Ping|Repair|Resolve|Test|Trace|Connect|Disconnect|Read|Receive|Send|Write|Block|Grant|Protect|Revoke|Unblock|Unprotect|Use|ForEach|Sort|Tee|Where\",\")+(-)[\\\\w\\\\d]+\")}]},j={className:\"class\",beginKeywords:\"class enum\",end:/\\s*[{]/,excludeEnd:!0,relevance:0,contains:[o.TITLE_MODE]},L={className:\"function\",begin:/function\\s+/,end:/\\s*\\{|$/,excludeEnd:!0,returnBegin:!0,relevance:0,contains:[{begin:\"function\",relevance:0,className:\"keyword\"},{className:\"title\",begin:/\\w[\\w\\d]*((-)[\\w\\d]+)*/,relevance:0},{begin:/\\(/,end:/\\)/,className:\"params\",relevance:0,contains:[u]}]},B={begin:/using\\s/,end:/$/,returnBegin:!0,contains:[_,w,{className:\"keyword\",begin:/(using|assembly|command|module|namespace|type)/}]},$={variants:[{className:\"operator\",begin:\"(\".concat(\"-and|-as|-band|-bnot|-bor|-bxor|-casesensitive|-ccontains|-ceq|-cge|-cgt|-cle|-clike|-clt|-cmatch|-cne|-cnotcontains|-cnotlike|-cnotmatch|-contains|-creplace|-csplit|-eq|-exact|-f|-file|-ge|-gt|-icontains|-ieq|-ige|-igt|-ile|-ilike|-ilt|-imatch|-in|-ine|-inotcontains|-inotlike|-inotmatch|-ireplace|-is|-isnot|-isplit|-join|-le|-like|-lt|-match|-ne|-not|-notcontains|-notin|-notlike|-notmatch|-or|-regex|-replace|-shl|-shr|-split|-wildcard|-xor\",\")\\\\b\")},{className:\"literal\",begin:/(-)[\\w\\d]+/,relevance:0}]},V={className:\"function\",begin:/\\[.*\\]\\s*[\\w]+[ ]??\\(/,end:/$/,returnBegin:!0,relevance:0,contains:[{className:\"keyword\",begin:\"(\".concat(s.keyword.toString().replace(/\\s/g,\"|\"),\")\\\\b\"),endsParent:!0,relevance:0},o.inherit(o.TITLE_MODE,{endsParent:!0})]},U=[V,x,i,o.NUMBER_MODE,_,w,C,u,{className:\"literal\",begin:/\\$(null|true|false)\\b/},{className:\"selector-tag\",begin:/@\\B/,relevance:0}],z={begin:/\\[/,end:/\\]/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[].concat(\"self\",U,{begin:\"(\"+[\"string\",\"char\",\"byte\",\"int\",\"long\",\"bool\",\"decimal\",\"single\",\"double\",\"DateTime\",\"xml\",\"array\",\"hashtable\",\"void\"].join(\"|\")+\")\",className:\"built_in\",relevance:0},{className:\"type\",begin:/[\\.\\w\\d]+/,relevance:0})};return V.contains.unshift(z),{name:\"PowerShell\",aliases:[\"ps\",\"ps1\"],case_insensitive:!0,keywords:s,contains:U.concat(j,L,B,$,z)}}},17285:o=>{function source(o){return o?\"string\"==typeof o?o:o.source:null}function lookahead(o){return concat(\"(?=\",o,\")\")}function concat(...o){return o.map((o=>source(o))).join(\"\")}function either(...o){return\"(\"+o.map((o=>source(o))).join(\"|\")+\")\"}o.exports=function xml(o){const s=concat(/[A-Z_]/,function optional(o){return concat(\"(\",o,\")?\")}(/[A-Z0-9_.-]*:/),/[A-Z0-9_.-]*/),i={className:\"symbol\",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},u={begin:/\\s/,contains:[{className:\"meta-keyword\",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\\n/}]},_=o.inherit(u,{begin:/\\(/,end:/\\)/}),w=o.inherit(o.APOS_STRING_MODE,{className:\"meta-string\"}),x=o.inherit(o.QUOTE_STRING_MODE,{className:\"meta-string\"}),C={endsWithParent:!0,illegal:/`]+/}]}]}]};return{name:\"HTML, XML\",aliases:[\"html\",\"xhtml\",\"rss\",\"atom\",\"xjb\",\"xsd\",\"xsl\",\"plist\",\"wsf\",\"svg\"],case_insensitive:!0,contains:[{className:\"meta\",begin://,relevance:10,contains:[u,x,w,_,{begin:/\\[/,end:/\\]/,contains:[{className:\"meta\",begin://,contains:[u,_,x,w]}]}]},o.COMMENT(//,{relevance:10}),{begin://,relevance:10},i,{className:\"meta\",begin:/<\\?xml/,end:/\\?>/,relevance:10},{className:\"tag\",begin:/)/,end:/>/,keywords:{name:\"style\"},contains:[C],starts:{end:/<\\/style>/,returnEnd:!0,subLanguage:[\"css\",\"xml\"]}},{className:\"tag\",begin:/)/,end:/>/,keywords:{name:\"script\"},contains:[C],starts:{end:/<\\/script>/,returnEnd:!0,subLanguage:[\"javascript\",\"handlebars\",\"xml\"]}},{className:\"tag\",begin:/<>|<\\/>/},{className:\"tag\",begin:concat(//,/>/,/\\s/)))),end:/\\/?>/,contains:[{className:\"name\",begin:s,relevance:0,starts:C}]},{className:\"tag\",begin:concat(/<\\//,lookahead(concat(s,/>/))),contains:[{className:\"name\",begin:s,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]}}},17533:o=>{o.exports=function yaml(o){var s=\"true false yes no null\",i=\"[\\\\w#;/?:@&=+$,.~*'()[\\\\]]+\",u={className:\"string\",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/\"/,end:/\"/},{begin:/\\S+/}],contains:[o.BACKSLASH_ESCAPE,{className:\"template-variable\",variants:[{begin:/\\{\\{/,end:/\\}\\}/},{begin:/%\\{/,end:/\\}/}]}]},_=o.inherit(u,{variants:[{begin:/'/,end:/'/},{begin:/\"/,end:/\"/},{begin:/[^\\s,{}[\\]]+/}]}),w={className:\"number\",begin:\"\\\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\\\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\\\.[0-9]*)?([ \\\\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\\\b\"},x={end:\",\",endsWithParent:!0,excludeEnd:!0,keywords:s,relevance:0},C={begin:/\\{/,end:/\\}/,contains:[x],illegal:\"\\\\n\",relevance:0},j={begin:\"\\\\[\",end:\"\\\\]\",contains:[x],illegal:\"\\\\n\",relevance:0},L=[{className:\"attr\",variants:[{begin:\"\\\\w[\\\\w :\\\\/.-]*:(?=[ \\t]|$)\"},{begin:'\"\\\\w[\\\\w :\\\\/.-]*\":(?=[ \\t]|$)'},{begin:\"'\\\\w[\\\\w :\\\\/.-]*':(?=[ \\t]|$)\"}]},{className:\"meta\",begin:\"^---\\\\s*$\",relevance:10},{className:\"string\",begin:\"[\\\\|>]([1-9]?[+-])?[ ]*\\\\n( +)[^ ][^\\\\n]*\\\\n(\\\\2[^\\\\n]+\\\\n?)*\"},{begin:\"<%[%=-]?\",end:\"[%-]?%>\",subLanguage:\"ruby\",excludeBegin:!0,excludeEnd:!0,relevance:0},{className:\"type\",begin:\"!\\\\w+!\"+i},{className:\"type\",begin:\"!<\"+i+\">\"},{className:\"type\",begin:\"!\"+i},{className:\"type\",begin:\"!!\"+i},{className:\"meta\",begin:\"&\"+o.UNDERSCORE_IDENT_RE+\"$\"},{className:\"meta\",begin:\"\\\\*\"+o.UNDERSCORE_IDENT_RE+\"$\"},{className:\"bullet\",begin:\"-(?=[ ]|$)\",relevance:0},o.HASH_COMMENT_MODE,{beginKeywords:s,keywords:{literal:s}},w,{className:\"number\",begin:o.C_NUMBER_RE+\"\\\\b\",relevance:0},C,j,u],B=[...L];return B.pop(),B.push(_),x.contains=B,{name:\"YAML\",case_insensitive:!0,aliases:[\"yml\"],contains:L}}},251:(o,s)=>{s.read=function(o,s,i,u,_){var w,x,C=8*_-u-1,j=(1<>1,B=-7,$=i?_-1:0,V=i?-1:1,U=o[s+$];for($+=V,w=U&(1<<-B)-1,U>>=-B,B+=C;B>0;w=256*w+o[s+$],$+=V,B-=8);for(x=w&(1<<-B)-1,w>>=-B,B+=u;B>0;x=256*x+o[s+$],$+=V,B-=8);if(0===w)w=1-L;else{if(w===j)return x?NaN:1/0*(U?-1:1);x+=Math.pow(2,u),w-=L}return(U?-1:1)*x*Math.pow(2,w-u)},s.write=function(o,s,i,u,_,w){var x,C,j,L=8*w-_-1,B=(1<>1,V=23===_?Math.pow(2,-24)-Math.pow(2,-77):0,U=u?0:w-1,z=u?1:-1,Y=s<0||0===s&&1/s<0?1:0;for(s=Math.abs(s),isNaN(s)||s===1/0?(C=isNaN(s)?1:0,x=B):(x=Math.floor(Math.log(s)/Math.LN2),s*(j=Math.pow(2,-x))<1&&(x--,j*=2),(s+=x+$>=1?V/j:V*Math.pow(2,1-$))*j>=2&&(x++,j/=2),x+$>=B?(C=0,x=B):x+$>=1?(C=(s*j-1)*Math.pow(2,_),x+=$):(C=s*Math.pow(2,$-1)*Math.pow(2,_),x=0));_>=8;o[i+U]=255&C,U+=z,C/=256,_-=8);for(x=x<<_|C,L+=_;L>0;o[i+U]=255&x,U+=z,x/=256,L-=8);o[i+U-z]|=128*Y}},9404:function(o){o.exports=function(){\"use strict\";var o=Array.prototype.slice;function createClass(o,s){s&&(o.prototype=Object.create(s.prototype)),o.prototype.constructor=o}function Iterable(o){return isIterable(o)?o:Seq(o)}function KeyedIterable(o){return isKeyed(o)?o:KeyedSeq(o)}function IndexedIterable(o){return isIndexed(o)?o:IndexedSeq(o)}function SetIterable(o){return isIterable(o)&&!isAssociative(o)?o:SetSeq(o)}function isIterable(o){return!(!o||!o[s])}function isKeyed(o){return!(!o||!o[i])}function isIndexed(o){return!(!o||!o[u])}function isAssociative(o){return isKeyed(o)||isIndexed(o)}function isOrdered(o){return!(!o||!o[_])}createClass(KeyedIterable,Iterable),createClass(IndexedIterable,Iterable),createClass(SetIterable,Iterable),Iterable.isIterable=isIterable,Iterable.isKeyed=isKeyed,Iterable.isIndexed=isIndexed,Iterable.isAssociative=isAssociative,Iterable.isOrdered=isOrdered,Iterable.Keyed=KeyedIterable,Iterable.Indexed=IndexedIterable,Iterable.Set=SetIterable;var s=\"@@__IMMUTABLE_ITERABLE__@@\",i=\"@@__IMMUTABLE_KEYED__@@\",u=\"@@__IMMUTABLE_INDEXED__@@\",_=\"@@__IMMUTABLE_ORDERED__@@\",w=\"delete\",x=5,C=1<>>0;if(\"\"+i!==s||4294967295===i)return NaN;s=i}return s<0?ensureSize(o)+s:s}function returnTrue(){return!0}function wholeSlice(o,s,i){return(0===o||void 0!==i&&o<=-i)&&(void 0===s||void 0!==i&&s>=i)}function resolveBegin(o,s){return resolveIndex(o,s,0)}function resolveEnd(o,s){return resolveIndex(o,s,s)}function resolveIndex(o,s,i){return void 0===o?i:o<0?Math.max(0,s+o):void 0===s?o:Math.min(s,o)}var V=0,U=1,z=2,Y=\"function\"==typeof Symbol&&Symbol.iterator,Z=\"@@iterator\",ee=Y||Z;function Iterator(o){this.next=o}function iteratorValue(o,s,i,u){var _=0===o?s:1===o?i:[s,i];return u?u.value=_:u={value:_,done:!1},u}function iteratorDone(){return{value:void 0,done:!0}}function hasIterator(o){return!!getIteratorFn(o)}function isIterator(o){return o&&\"function\"==typeof o.next}function getIterator(o){var s=getIteratorFn(o);return s&&s.call(o)}function getIteratorFn(o){var s=o&&(Y&&o[Y]||o[Z]);if(\"function\"==typeof s)return s}function isArrayLike(o){return o&&\"number\"==typeof o.length}function Seq(o){return null==o?emptySequence():isIterable(o)?o.toSeq():seqFromValue(o)}function KeyedSeq(o){return null==o?emptySequence().toKeyedSeq():isIterable(o)?isKeyed(o)?o.toSeq():o.fromEntrySeq():keyedSeqFromValue(o)}function IndexedSeq(o){return null==o?emptySequence():isIterable(o)?isKeyed(o)?o.entrySeq():o.toIndexedSeq():indexedSeqFromValue(o)}function SetSeq(o){return(null==o?emptySequence():isIterable(o)?isKeyed(o)?o.entrySeq():o:indexedSeqFromValue(o)).toSetSeq()}Iterator.prototype.toString=function(){return\"[Iterator]\"},Iterator.KEYS=V,Iterator.VALUES=U,Iterator.ENTRIES=z,Iterator.prototype.inspect=Iterator.prototype.toSource=function(){return this.toString()},Iterator.prototype[ee]=function(){return this},createClass(Seq,Iterable),Seq.of=function(){return Seq(arguments)},Seq.prototype.toSeq=function(){return this},Seq.prototype.toString=function(){return this.__toString(\"Seq {\",\"}\")},Seq.prototype.cacheResult=function(){return!this._cache&&this.__iterateUncached&&(this._cache=this.entrySeq().toArray(),this.size=this._cache.length),this},Seq.prototype.__iterate=function(o,s){return seqIterate(this,o,s,!0)},Seq.prototype.__iterator=function(o,s){return seqIterator(this,o,s,!0)},createClass(KeyedSeq,Seq),KeyedSeq.prototype.toKeyedSeq=function(){return this},createClass(IndexedSeq,Seq),IndexedSeq.of=function(){return IndexedSeq(arguments)},IndexedSeq.prototype.toIndexedSeq=function(){return this},IndexedSeq.prototype.toString=function(){return this.__toString(\"Seq [\",\"]\")},IndexedSeq.prototype.__iterate=function(o,s){return seqIterate(this,o,s,!1)},IndexedSeq.prototype.__iterator=function(o,s){return seqIterator(this,o,s,!1)},createClass(SetSeq,Seq),SetSeq.of=function(){return SetSeq(arguments)},SetSeq.prototype.toSetSeq=function(){return this},Seq.isSeq=isSeq,Seq.Keyed=KeyedSeq,Seq.Set=SetSeq,Seq.Indexed=IndexedSeq;var ie,ae,ce,le=\"@@__IMMUTABLE_SEQ__@@\";function ArraySeq(o){this._array=o,this.size=o.length}function ObjectSeq(o){var s=Object.keys(o);this._object=o,this._keys=s,this.size=s.length}function IterableSeq(o){this._iterable=o,this.size=o.length||o.size}function IteratorSeq(o){this._iterator=o,this._iteratorCache=[]}function isSeq(o){return!(!o||!o[le])}function emptySequence(){return ie||(ie=new ArraySeq([]))}function keyedSeqFromValue(o){var s=Array.isArray(o)?new ArraySeq(o).fromEntrySeq():isIterator(o)?new IteratorSeq(o).fromEntrySeq():hasIterator(o)?new IterableSeq(o).fromEntrySeq():\"object\"==typeof o?new ObjectSeq(o):void 0;if(!s)throw new TypeError(\"Expected Array or iterable object of [k, v] entries, or keyed object: \"+o);return s}function indexedSeqFromValue(o){var s=maybeIndexedSeqFromValue(o);if(!s)throw new TypeError(\"Expected Array or iterable object of values: \"+o);return s}function seqFromValue(o){var s=maybeIndexedSeqFromValue(o)||\"object\"==typeof o&&new ObjectSeq(o);if(!s)throw new TypeError(\"Expected Array or iterable object of values, or keyed object: \"+o);return s}function maybeIndexedSeqFromValue(o){return isArrayLike(o)?new ArraySeq(o):isIterator(o)?new IteratorSeq(o):hasIterator(o)?new IterableSeq(o):void 0}function seqIterate(o,s,i,u){var _=o._cache;if(_){for(var w=_.length-1,x=0;x<=w;x++){var C=_[i?w-x:x];if(!1===s(C[1],u?C[0]:x,o))return x+1}return x}return o.__iterateUncached(s,i)}function seqIterator(o,s,i,u){var _=o._cache;if(_){var w=_.length-1,x=0;return new Iterator((function(){var o=_[i?w-x:x];return x++>w?iteratorDone():iteratorValue(s,u?o[0]:x-1,o[1])}))}return o.__iteratorUncached(s,i)}function fromJS(o,s){return s?fromJSWith(s,o,\"\",{\"\":o}):fromJSDefault(o)}function fromJSWith(o,s,i,u){return Array.isArray(s)?o.call(u,i,IndexedSeq(s).map((function(i,u){return fromJSWith(o,i,u,s)}))):isPlainObj(s)?o.call(u,i,KeyedSeq(s).map((function(i,u){return fromJSWith(o,i,u,s)}))):s}function fromJSDefault(o){return Array.isArray(o)?IndexedSeq(o).map(fromJSDefault).toList():isPlainObj(o)?KeyedSeq(o).map(fromJSDefault).toMap():o}function isPlainObj(o){return o&&(o.constructor===Object||void 0===o.constructor)}function is(o,s){if(o===s||o!=o&&s!=s)return!0;if(!o||!s)return!1;if(\"function\"==typeof o.valueOf&&\"function\"==typeof s.valueOf){if((o=o.valueOf())===(s=s.valueOf())||o!=o&&s!=s)return!0;if(!o||!s)return!1}return!(\"function\"!=typeof o.equals||\"function\"!=typeof s.equals||!o.equals(s))}function deepEqual(o,s){if(o===s)return!0;if(!isIterable(s)||void 0!==o.size&&void 0!==s.size&&o.size!==s.size||void 0!==o.__hash&&void 0!==s.__hash&&o.__hash!==s.__hash||isKeyed(o)!==isKeyed(s)||isIndexed(o)!==isIndexed(s)||isOrdered(o)!==isOrdered(s))return!1;if(0===o.size&&0===s.size)return!0;var i=!isAssociative(o);if(isOrdered(o)){var u=o.entries();return s.every((function(o,s){var _=u.next().value;return _&&is(_[1],o)&&(i||is(_[0],s))}))&&u.next().done}var _=!1;if(void 0===o.size)if(void 0===s.size)\"function\"==typeof o.cacheResult&&o.cacheResult();else{_=!0;var w=o;o=s,s=w}var x=!0,C=s.__iterate((function(s,u){if(i?!o.has(s):_?!is(s,o.get(u,L)):!is(o.get(u,L),s))return x=!1,!1}));return x&&o.size===C}function Repeat(o,s){if(!(this instanceof Repeat))return new Repeat(o,s);if(this._value=o,this.size=void 0===s?1/0:Math.max(0,s),0===this.size){if(ae)return ae;ae=this}}function invariant(o,s){if(!o)throw new Error(s)}function Range(o,s,i){if(!(this instanceof Range))return new Range(o,s,i);if(invariant(0!==i,\"Cannot step a Range by 0\"),o=o||0,void 0===s&&(s=1/0),i=void 0===i?1:Math.abs(i),su?iteratorDone():iteratorValue(o,_,i[s?u-_++:_++])}))},createClass(ObjectSeq,KeyedSeq),ObjectSeq.prototype.get=function(o,s){return void 0===s||this.has(o)?this._object[o]:s},ObjectSeq.prototype.has=function(o){return this._object.hasOwnProperty(o)},ObjectSeq.prototype.__iterate=function(o,s){for(var i=this._object,u=this._keys,_=u.length-1,w=0;w<=_;w++){var x=u[s?_-w:w];if(!1===o(i[x],x,this))return w+1}return w},ObjectSeq.prototype.__iterator=function(o,s){var i=this._object,u=this._keys,_=u.length-1,w=0;return new Iterator((function(){var x=u[s?_-w:w];return w++>_?iteratorDone():iteratorValue(o,x,i[x])}))},ObjectSeq.prototype[_]=!0,createClass(IterableSeq,IndexedSeq),IterableSeq.prototype.__iterateUncached=function(o,s){if(s)return this.cacheResult().__iterate(o,s);var i=getIterator(this._iterable),u=0;if(isIterator(i))for(var _;!(_=i.next()).done&&!1!==o(_.value,u++,this););return u},IterableSeq.prototype.__iteratorUncached=function(o,s){if(s)return this.cacheResult().__iterator(o,s);var i=getIterator(this._iterable);if(!isIterator(i))return new Iterator(iteratorDone);var u=0;return new Iterator((function(){var s=i.next();return s.done?s:iteratorValue(o,u++,s.value)}))},createClass(IteratorSeq,IndexedSeq),IteratorSeq.prototype.__iterateUncached=function(o,s){if(s)return this.cacheResult().__iterate(o,s);for(var i,u=this._iterator,_=this._iteratorCache,w=0;w<_.length;)if(!1===o(_[w],w++,this))return w;for(;!(i=u.next()).done;){var x=i.value;if(_[w]=x,!1===o(x,w++,this))break}return w},IteratorSeq.prototype.__iteratorUncached=function(o,s){if(s)return this.cacheResult().__iterator(o,s);var i=this._iterator,u=this._iteratorCache,_=0;return new Iterator((function(){if(_>=u.length){var s=i.next();if(s.done)return s;u[_]=s.value}return iteratorValue(o,_,u[_++])}))},createClass(Repeat,IndexedSeq),Repeat.prototype.toString=function(){return 0===this.size?\"Repeat []\":\"Repeat [ \"+this._value+\" \"+this.size+\" times ]\"},Repeat.prototype.get=function(o,s){return this.has(o)?this._value:s},Repeat.prototype.includes=function(o){return is(this._value,o)},Repeat.prototype.slice=function(o,s){var i=this.size;return wholeSlice(o,s,i)?this:new Repeat(this._value,resolveEnd(s,i)-resolveBegin(o,i))},Repeat.prototype.reverse=function(){return this},Repeat.prototype.indexOf=function(o){return is(this._value,o)?0:-1},Repeat.prototype.lastIndexOf=function(o){return is(this._value,o)?this.size:-1},Repeat.prototype.__iterate=function(o,s){for(var i=0;i=0&&s=0&&ii?iteratorDone():iteratorValue(o,w++,x)}))},Range.prototype.equals=function(o){return o instanceof Range?this._start===o._start&&this._end===o._end&&this._step===o._step:deepEqual(this,o)},createClass(Collection,Iterable),createClass(KeyedCollection,Collection),createClass(IndexedCollection,Collection),createClass(SetCollection,Collection),Collection.Keyed=KeyedCollection,Collection.Indexed=IndexedCollection,Collection.Set=SetCollection;var pe=\"function\"==typeof Math.imul&&-2===Math.imul(4294967295,2)?Math.imul:function imul(o,s){var i=65535&(o|=0),u=65535&(s|=0);return i*u+((o>>>16)*u+i*(s>>>16)<<16>>>0)|0};function smi(o){return o>>>1&1073741824|3221225471&o}function hash(o){if(!1===o||null==o)return 0;if(\"function\"==typeof o.valueOf&&(!1===(o=o.valueOf())||null==o))return 0;if(!0===o)return 1;var s=typeof o;if(\"number\"===s){if(o!=o||o===1/0)return 0;var i=0|o;for(i!==o&&(i^=4294967295*o);o>4294967295;)i^=o/=4294967295;return smi(i)}if(\"string\"===s)return o.length>Se?cachedHashString(o):hashString(o);if(\"function\"==typeof o.hashCode)return o.hashCode();if(\"object\"===s)return hashJSObj(o);if(\"function\"==typeof o.toString)return hashString(o.toString());throw new Error(\"Value type \"+s+\" cannot be hashed.\")}function cachedHashString(o){var s=Te[o];return void 0===s&&(s=hashString(o),Pe===xe&&(Pe=0,Te={}),Pe++,Te[o]=s),s}function hashString(o){for(var s=0,i=0;i0)switch(o.nodeType){case 1:return o.uniqueID;case 9:return o.documentElement&&o.documentElement.uniqueID}}var ye,be=\"function\"==typeof WeakMap;be&&(ye=new WeakMap);var _e=0,we=\"__immutablehash__\";\"function\"==typeof Symbol&&(we=Symbol(we));var Se=16,xe=255,Pe=0,Te={};function assertNotInfinite(o){invariant(o!==1/0,\"Cannot perform this action with an infinite size.\")}function Map(o){return null==o?emptyMap():isMap(o)&&!isOrdered(o)?o:emptyMap().withMutations((function(s){var i=KeyedIterable(o);assertNotInfinite(i.size),i.forEach((function(o,i){return s.set(i,o)}))}))}function isMap(o){return!(!o||!o[qe])}createClass(Map,KeyedCollection),Map.of=function(){var s=o.call(arguments,0);return emptyMap().withMutations((function(o){for(var i=0;i=s.length)throw new Error(\"Missing value for key: \"+s[i]);o.set(s[i],s[i+1])}}))},Map.prototype.toString=function(){return this.__toString(\"Map {\",\"}\")},Map.prototype.get=function(o,s){return this._root?this._root.get(0,void 0,o,s):s},Map.prototype.set=function(o,s){return updateMap(this,o,s)},Map.prototype.setIn=function(o,s){return this.updateIn(o,L,(function(){return s}))},Map.prototype.remove=function(o){return updateMap(this,o,L)},Map.prototype.deleteIn=function(o){return this.updateIn(o,(function(){return L}))},Map.prototype.update=function(o,s,i){return 1===arguments.length?o(this):this.updateIn([o],s,i)},Map.prototype.updateIn=function(o,s,i){i||(i=s,s=void 0);var u=updateInDeepMap(this,forceIterator(o),s,i);return u===L?void 0:u},Map.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._root=null,this.__hash=void 0,this.__altered=!0,this):emptyMap()},Map.prototype.merge=function(){return mergeIntoMapWith(this,void 0,arguments)},Map.prototype.mergeWith=function(s){return mergeIntoMapWith(this,s,o.call(arguments,1))},Map.prototype.mergeIn=function(s){var i=o.call(arguments,1);return this.updateIn(s,emptyMap(),(function(o){return\"function\"==typeof o.merge?o.merge.apply(o,i):i[i.length-1]}))},Map.prototype.mergeDeep=function(){return mergeIntoMapWith(this,deepMerger,arguments)},Map.prototype.mergeDeepWith=function(s){var i=o.call(arguments,1);return mergeIntoMapWith(this,deepMergerWith(s),i)},Map.prototype.mergeDeepIn=function(s){var i=o.call(arguments,1);return this.updateIn(s,emptyMap(),(function(o){return\"function\"==typeof o.mergeDeep?o.mergeDeep.apply(o,i):i[i.length-1]}))},Map.prototype.sort=function(o){return OrderedMap(sortFactory(this,o))},Map.prototype.sortBy=function(o,s){return OrderedMap(sortFactory(this,s,o))},Map.prototype.withMutations=function(o){var s=this.asMutable();return o(s),s.wasAltered()?s.__ensureOwner(this.__ownerID):this},Map.prototype.asMutable=function(){return this.__ownerID?this:this.__ensureOwner(new OwnerID)},Map.prototype.asImmutable=function(){return this.__ensureOwner()},Map.prototype.wasAltered=function(){return this.__altered},Map.prototype.__iterator=function(o,s){return new MapIterator(this,o,s)},Map.prototype.__iterate=function(o,s){var i=this,u=0;return this._root&&this._root.iterate((function(s){return u++,o(s[1],s[0],i)}),s),u},Map.prototype.__ensureOwner=function(o){return o===this.__ownerID?this:o?makeMap(this.size,this._root,o,this.__hash):(this.__ownerID=o,this.__altered=!1,this)},Map.isMap=isMap;var Re,qe=\"@@__IMMUTABLE_MAP__@@\",$e=Map.prototype;function ArrayMapNode(o,s){this.ownerID=o,this.entries=s}function BitmapIndexedNode(o,s,i){this.ownerID=o,this.bitmap=s,this.nodes=i}function HashArrayMapNode(o,s,i){this.ownerID=o,this.count=s,this.nodes=i}function HashCollisionNode(o,s,i){this.ownerID=o,this.keyHash=s,this.entries=i}function ValueNode(o,s,i){this.ownerID=o,this.keyHash=s,this.entry=i}function MapIterator(o,s,i){this._type=s,this._reverse=i,this._stack=o._root&&mapIteratorFrame(o._root)}function mapIteratorValue(o,s){return iteratorValue(o,s[0],s[1])}function mapIteratorFrame(o,s){return{node:o,index:0,__prev:s}}function makeMap(o,s,i,u){var _=Object.create($e);return _.size=o,_._root=s,_.__ownerID=i,_.__hash=u,_.__altered=!1,_}function emptyMap(){return Re||(Re=makeMap(0))}function updateMap(o,s,i){var u,_;if(o._root){var w=MakeRef(B),x=MakeRef($);if(u=updateNode(o._root,o.__ownerID,0,void 0,s,i,w,x),!x.value)return o;_=o.size+(w.value?i===L?-1:1:0)}else{if(i===L)return o;_=1,u=new ArrayMapNode(o.__ownerID,[[s,i]])}return o.__ownerID?(o.size=_,o._root=u,o.__hash=void 0,o.__altered=!0,o):u?makeMap(_,u):emptyMap()}function updateNode(o,s,i,u,_,w,x,C){return o?o.update(s,i,u,_,w,x,C):w===L?o:(SetRef(C),SetRef(x),new ValueNode(s,u,[_,w]))}function isLeafNode(o){return o.constructor===ValueNode||o.constructor===HashCollisionNode}function mergeIntoNode(o,s,i,u,_){if(o.keyHash===u)return new HashCollisionNode(s,u,[o.entry,_]);var w,C=(0===i?o.keyHash:o.keyHash>>>i)&j,L=(0===i?u:u>>>i)&j;return new BitmapIndexedNode(s,1<>>=1)x[j]=1&i?s[w++]:void 0;return x[u]=_,new HashArrayMapNode(o,w+1,x)}function mergeIntoMapWith(o,s,i){for(var u=[],_=0;_>1&1431655765))+(o>>2&858993459))+(o>>4)&252645135,o+=o>>8,127&(o+=o>>16)}function setIn(o,s,i,u){var _=u?o:arrCopy(o);return _[s]=i,_}function spliceIn(o,s,i,u){var _=o.length+1;if(u&&s+1===_)return o[s]=i,o;for(var w=new Array(_),x=0,C=0;C<_;C++)C===s?(w[C]=i,x=-1):w[C]=o[C+x];return w}function spliceOut(o,s,i){var u=o.length-1;if(i&&s===u)return o.pop(),o;for(var _=new Array(u),w=0,x=0;x=ze)return createNodes(o,j,u,_);var U=o&&o===this.ownerID,z=U?j:arrCopy(j);return V?C?B===$-1?z.pop():z[B]=z.pop():z[B]=[u,_]:z.push([u,_]),U?(this.entries=z,this):new ArrayMapNode(o,z)}},BitmapIndexedNode.prototype.get=function(o,s,i,u){void 0===s&&(s=hash(i));var _=1<<((0===o?s:s>>>o)&j),w=this.bitmap;return w&_?this.nodes[popCount(w&_-1)].get(o+x,s,i,u):u},BitmapIndexedNode.prototype.update=function(o,s,i,u,_,w,C){void 0===i&&(i=hash(u));var B=(0===s?i:i>>>s)&j,$=1<=We)return expandNodes(o,Y,V,B,ee);if(U&&!ee&&2===Y.length&&isLeafNode(Y[1^z]))return Y[1^z];if(U&&ee&&1===Y.length&&isLeafNode(ee))return ee;var ie=o&&o===this.ownerID,ae=U?ee?V:V^$:V|$,ce=U?ee?setIn(Y,z,ee,ie):spliceOut(Y,z,ie):spliceIn(Y,z,ee,ie);return ie?(this.bitmap=ae,this.nodes=ce,this):new BitmapIndexedNode(o,ae,ce)},HashArrayMapNode.prototype.get=function(o,s,i,u){void 0===s&&(s=hash(i));var _=(0===o?s:s>>>o)&j,w=this.nodes[_];return w?w.get(o+x,s,i,u):u},HashArrayMapNode.prototype.update=function(o,s,i,u,_,w,C){void 0===i&&(i=hash(u));var B=(0===s?i:i>>>s)&j,$=_===L,V=this.nodes,U=V[B];if($&&!U)return this;var z=updateNode(U,o,s+x,i,u,_,w,C);if(z===U)return this;var Y=this.count;if(U){if(!z&&--Y0&&u=0&&o>>s&j;if(u>=this.array.length)return new VNode([],o);var _,w=0===u;if(s>0){var C=this.array[u];if((_=C&&C.removeBefore(o,s-x,i))===C&&w)return this}if(w&&!_)return this;var L=editableVNode(this,o);if(!w)for(var B=0;B>>s&j;if(_>=this.array.length)return this;if(s>0){var w=this.array[_];if((u=w&&w.removeAfter(o,s-x,i))===w&&_===this.array.length-1)return this}var C=editableVNode(this,o);return C.array.splice(_+1),u&&(C.array[_]=u),C};var Qe,et,tt={};function iterateList(o,s){var i=o._origin,u=o._capacity,_=getTailOffset(u),w=o._tail;return iterateNodeOrLeaf(o._root,o._level,0);function iterateNodeOrLeaf(o,s,i){return 0===s?iterateLeaf(o,i):iterateNode(o,s,i)}function iterateLeaf(o,x){var j=x===_?w&&w.array:o&&o.array,L=x>i?0:i-x,B=u-x;return B>C&&(B=C),function(){if(L===B)return tt;var o=s?--B:L++;return j&&j[o]}}function iterateNode(o,_,w){var j,L=o&&o.array,B=w>i?0:i-w>>_,$=1+(u-w>>_);return $>C&&($=C),function(){for(;;){if(j){var o=j();if(o!==tt)return o;j=null}if(B===$)return tt;var i=s?--$:B++;j=iterateNodeOrLeaf(L&&L[i],_-x,w+(i<<_))}}}}function makeList(o,s,i,u,_,w,x){var C=Object.create(Xe);return C.size=s-o,C._origin=o,C._capacity=s,C._level=i,C._root=u,C._tail=_,C.__ownerID=w,C.__hash=x,C.__altered=!1,C}function emptyList(){return Qe||(Qe=makeList(0,0,x))}function updateList(o,s,i){if((s=wrapIndex(o,s))!=s)return o;if(s>=o.size||s<0)return o.withMutations((function(o){s<0?setListBounds(o,s).set(0,i):setListBounds(o,0,s+1).set(s,i)}));s+=o._origin;var u=o._tail,_=o._root,w=MakeRef($);return s>=getTailOffset(o._capacity)?u=updateVNode(u,o.__ownerID,0,s,i,w):_=updateVNode(_,o.__ownerID,o._level,s,i,w),w.value?o.__ownerID?(o._root=_,o._tail=u,o.__hash=void 0,o.__altered=!0,o):makeList(o._origin,o._capacity,o._level,_,u):o}function updateVNode(o,s,i,u,_,w){var C,L=u>>>i&j,B=o&&L0){var $=o&&o.array[L],V=updateVNode($,s,i-x,u,_,w);return V===$?o:((C=editableVNode(o,s)).array[L]=V,C)}return B&&o.array[L]===_?o:(SetRef(w),C=editableVNode(o,s),void 0===_&&L===C.array.length-1?C.array.pop():C.array[L]=_,C)}function editableVNode(o,s){return s&&o&&s===o.ownerID?o:new VNode(o?o.array.slice():[],s)}function listNodeFor(o,s){if(s>=getTailOffset(o._capacity))return o._tail;if(s<1<0;)i=i.array[s>>>u&j],u-=x;return i}}function setListBounds(o,s,i){void 0!==s&&(s|=0),void 0!==i&&(i|=0);var u=o.__ownerID||new OwnerID,_=o._origin,w=o._capacity,C=_+s,L=void 0===i?w:i<0?w+i:_+i;if(C===_&&L===w)return o;if(C>=L)return o.clear();for(var B=o._level,$=o._root,V=0;C+V<0;)$=new VNode($&&$.array.length?[void 0,$]:[],u),V+=1<<(B+=x);V&&(C+=V,_+=V,L+=V,w+=V);for(var U=getTailOffset(w),z=getTailOffset(L);z>=1<U?new VNode([],u):Y;if(Y&&z>U&&Cx;ie-=x){var ae=U>>>ie&j;ee=ee.array[ae]=editableVNode(ee.array[ae],u)}ee.array[U>>>x&j]=Y}if(L=z)C-=z,L-=z,B=x,$=null,Z=Z&&Z.removeBefore(u,0,C);else if(C>_||z>>B&j;if(ce!==z>>>B&j)break;ce&&(V+=(1<_&&($=$.removeBefore(u,B,C-V)),$&&z_&&(_=C.size),isIterable(x)||(C=C.map((function(o){return fromJS(o)}))),u.push(C)}return _>o.size&&(o=o.setSize(_)),mergeIntoCollectionWith(o,s,u)}function getTailOffset(o){return o>>x<=C&&x.size>=2*w.size?(u=(_=x.filter((function(o,s){return void 0!==o&&j!==s}))).toKeyedSeq().map((function(o){return o[0]})).flip().toMap(),o.__ownerID&&(u.__ownerID=_.__ownerID=o.__ownerID)):(u=w.remove(s),_=j===x.size-1?x.pop():x.set(j,void 0))}else if(B){if(i===x.get(j)[1])return o;u=w,_=x.set(j,[s,i])}else u=w.set(s,x.size),_=x.set(x.size,[s,i]);return o.__ownerID?(o.size=u.size,o._map=u,o._list=_,o.__hash=void 0,o):makeOrderedMap(u,_)}function ToKeyedSequence(o,s){this._iter=o,this._useKeys=s,this.size=o.size}function ToIndexedSequence(o){this._iter=o,this.size=o.size}function ToSetSequence(o){this._iter=o,this.size=o.size}function FromEntriesSequence(o){this._iter=o,this.size=o.size}function flipFactory(o){var s=makeSequence(o);return s._iter=o,s.size=o.size,s.flip=function(){return o},s.reverse=function(){var s=o.reverse.apply(this);return s.flip=function(){return o.reverse()},s},s.has=function(s){return o.includes(s)},s.includes=function(s){return o.has(s)},s.cacheResult=cacheResultThrough,s.__iterateUncached=function(s,i){var u=this;return o.__iterate((function(o,i){return!1!==s(i,o,u)}),i)},s.__iteratorUncached=function(s,i){if(s===z){var u=o.__iterator(s,i);return new Iterator((function(){var o=u.next();if(!o.done){var s=o.value[0];o.value[0]=o.value[1],o.value[1]=s}return o}))}return o.__iterator(s===U?V:U,i)},s}function mapFactory(o,s,i){var u=makeSequence(o);return u.size=o.size,u.has=function(s){return o.has(s)},u.get=function(u,_){var w=o.get(u,L);return w===L?_:s.call(i,w,u,o)},u.__iterateUncached=function(u,_){var w=this;return o.__iterate((function(o,_,x){return!1!==u(s.call(i,o,_,x),_,w)}),_)},u.__iteratorUncached=function(u,_){var w=o.__iterator(z,_);return new Iterator((function(){var _=w.next();if(_.done)return _;var x=_.value,C=x[0];return iteratorValue(u,C,s.call(i,x[1],C,o),_)}))},u}function reverseFactory(o,s){var i=makeSequence(o);return i._iter=o,i.size=o.size,i.reverse=function(){return o},o.flip&&(i.flip=function(){var s=flipFactory(o);return s.reverse=function(){return o.flip()},s}),i.get=function(i,u){return o.get(s?i:-1-i,u)},i.has=function(i){return o.has(s?i:-1-i)},i.includes=function(s){return o.includes(s)},i.cacheResult=cacheResultThrough,i.__iterate=function(s,i){var u=this;return o.__iterate((function(o,i){return s(o,i,u)}),!i)},i.__iterator=function(s,i){return o.__iterator(s,!i)},i}function filterFactory(o,s,i,u){var _=makeSequence(o);return u&&(_.has=function(u){var _=o.get(u,L);return _!==L&&!!s.call(i,_,u,o)},_.get=function(u,_){var w=o.get(u,L);return w!==L&&s.call(i,w,u,o)?w:_}),_.__iterateUncached=function(_,w){var x=this,C=0;return o.__iterate((function(o,w,j){if(s.call(i,o,w,j))return C++,_(o,u?w:C-1,x)}),w),C},_.__iteratorUncached=function(_,w){var x=o.__iterator(z,w),C=0;return new Iterator((function(){for(;;){var w=x.next();if(w.done)return w;var j=w.value,L=j[0],B=j[1];if(s.call(i,B,L,o))return iteratorValue(_,u?L:C++,B,w)}}))},_}function countByFactory(o,s,i){var u=Map().asMutable();return o.__iterate((function(_,w){u.update(s.call(i,_,w,o),0,(function(o){return o+1}))})),u.asImmutable()}function groupByFactory(o,s,i){var u=isKeyed(o),_=(isOrdered(o)?OrderedMap():Map()).asMutable();o.__iterate((function(w,x){_.update(s.call(i,w,x,o),(function(o){return(o=o||[]).push(u?[x,w]:w),o}))}));var w=iterableClass(o);return _.map((function(s){return reify(o,w(s))}))}function sliceFactory(o,s,i,u){var _=o.size;if(void 0!==s&&(s|=0),void 0!==i&&(i===1/0?i=_:i|=0),wholeSlice(s,i,_))return o;var w=resolveBegin(s,_),x=resolveEnd(i,_);if(w!=w||x!=x)return sliceFactory(o.toSeq().cacheResult(),s,i,u);var C,j=x-w;j==j&&(C=j<0?0:j);var L=makeSequence(o);return L.size=0===C?C:o.size&&C||void 0,!u&&isSeq(o)&&C>=0&&(L.get=function(s,i){return(s=wrapIndex(this,s))>=0&&sC)return iteratorDone();var o=_.next();return u||s===U?o:iteratorValue(s,j-1,s===V?void 0:o.value[1],o)}))},L}function takeWhileFactory(o,s,i){var u=makeSequence(o);return u.__iterateUncached=function(u,_){var w=this;if(_)return this.cacheResult().__iterate(u,_);var x=0;return o.__iterate((function(o,_,C){return s.call(i,o,_,C)&&++x&&u(o,_,w)})),x},u.__iteratorUncached=function(u,_){var w=this;if(_)return this.cacheResult().__iterator(u,_);var x=o.__iterator(z,_),C=!0;return new Iterator((function(){if(!C)return iteratorDone();var o=x.next();if(o.done)return o;var _=o.value,j=_[0],L=_[1];return s.call(i,L,j,w)?u===z?o:iteratorValue(u,j,L,o):(C=!1,iteratorDone())}))},u}function skipWhileFactory(o,s,i,u){var _=makeSequence(o);return _.__iterateUncached=function(_,w){var x=this;if(w)return this.cacheResult().__iterate(_,w);var C=!0,j=0;return o.__iterate((function(o,w,L){if(!C||!(C=s.call(i,o,w,L)))return j++,_(o,u?w:j-1,x)})),j},_.__iteratorUncached=function(_,w){var x=this;if(w)return this.cacheResult().__iterator(_,w);var C=o.__iterator(z,w),j=!0,L=0;return new Iterator((function(){var o,w,B;do{if((o=C.next()).done)return u||_===U?o:iteratorValue(_,L++,_===V?void 0:o.value[1],o);var $=o.value;w=$[0],B=$[1],j&&(j=s.call(i,B,w,x))}while(j);return _===z?o:iteratorValue(_,w,B,o)}))},_}function concatFactory(o,s){var i=isKeyed(o),u=[o].concat(s).map((function(o){return isIterable(o)?i&&(o=KeyedIterable(o)):o=i?keyedSeqFromValue(o):indexedSeqFromValue(Array.isArray(o)?o:[o]),o})).filter((function(o){return 0!==o.size}));if(0===u.length)return o;if(1===u.length){var _=u[0];if(_===o||i&&isKeyed(_)||isIndexed(o)&&isIndexed(_))return _}var w=new ArraySeq(u);return i?w=w.toKeyedSeq():isIndexed(o)||(w=w.toSetSeq()),(w=w.flatten(!0)).size=u.reduce((function(o,s){if(void 0!==o){var i=s.size;if(void 0!==i)return o+i}}),0),w}function flattenFactory(o,s,i){var u=makeSequence(o);return u.__iterateUncached=function(u,_){var w=0,x=!1;function flatDeep(o,C){var j=this;o.__iterate((function(o,_){return(!s||C0}function zipWithFactory(o,s,i){var u=makeSequence(o);return u.size=new ArraySeq(i).map((function(o){return o.size})).min(),u.__iterate=function(o,s){for(var i,u=this.__iterator(U,s),_=0;!(i=u.next()).done&&!1!==o(i.value,_++,this););return _},u.__iteratorUncached=function(o,u){var _=i.map((function(o){return o=Iterable(o),getIterator(u?o.reverse():o)})),w=0,x=!1;return new Iterator((function(){var i;return x||(i=_.map((function(o){return o.next()})),x=i.some((function(o){return o.done}))),x?iteratorDone():iteratorValue(o,w++,s.apply(null,i.map((function(o){return o.value}))))}))},u}function reify(o,s){return isSeq(o)?s:o.constructor(s)}function validateEntry(o){if(o!==Object(o))throw new TypeError(\"Expected [K, V] tuple: \"+o)}function resolveSize(o){return assertNotInfinite(o.size),ensureSize(o)}function iterableClass(o){return isKeyed(o)?KeyedIterable:isIndexed(o)?IndexedIterable:SetIterable}function makeSequence(o){return Object.create((isKeyed(o)?KeyedSeq:isIndexed(o)?IndexedSeq:SetSeq).prototype)}function cacheResultThrough(){return this._iter.cacheResult?(this._iter.cacheResult(),this.size=this._iter.size,this):Seq.prototype.cacheResult.call(this)}function defaultComparator(o,s){return o>s?1:o=0;i--)s={value:arguments[i],next:s};return this.__ownerID?(this.size=o,this._head=s,this.__hash=void 0,this.__altered=!0,this):makeStack(o,s)},Stack.prototype.pushAll=function(o){if(0===(o=IndexedIterable(o)).size)return this;assertNotInfinite(o.size);var s=this.size,i=this._head;return o.reverse().forEach((function(o){s++,i={value:o,next:i}})),this.__ownerID?(this.size=s,this._head=i,this.__hash=void 0,this.__altered=!0,this):makeStack(s,i)},Stack.prototype.pop=function(){return this.slice(1)},Stack.prototype.unshift=function(){return this.push.apply(this,arguments)},Stack.prototype.unshiftAll=function(o){return this.pushAll(o)},Stack.prototype.shift=function(){return this.pop.apply(this,arguments)},Stack.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._head=void 0,this.__hash=void 0,this.__altered=!0,this):emptyStack()},Stack.prototype.slice=function(o,s){if(wholeSlice(o,s,this.size))return this;var i=resolveBegin(o,this.size);if(resolveEnd(s,this.size)!==this.size)return IndexedCollection.prototype.slice.call(this,o,s);for(var u=this.size-i,_=this._head;i--;)_=_.next;return this.__ownerID?(this.size=u,this._head=_,this.__hash=void 0,this.__altered=!0,this):makeStack(u,_)},Stack.prototype.__ensureOwner=function(o){return o===this.__ownerID?this:o?makeStack(this.size,this._head,o,this.__hash):(this.__ownerID=o,this.__altered=!1,this)},Stack.prototype.__iterate=function(o,s){if(s)return this.reverse().__iterate(o);for(var i=0,u=this._head;u&&!1!==o(u.value,i++,this);)u=u.next;return i},Stack.prototype.__iterator=function(o,s){if(s)return this.reverse().__iterator(o);var i=0,u=this._head;return new Iterator((function(){if(u){var s=u.value;return u=u.next,iteratorValue(o,i++,s)}return iteratorDone()}))},Stack.isStack=isStack;var ct,lt=\"@@__IMMUTABLE_STACK__@@\",ut=Stack.prototype;function makeStack(o,s,i,u){var _=Object.create(ut);return _.size=o,_._head=s,_.__ownerID=i,_.__hash=u,_.__altered=!1,_}function emptyStack(){return ct||(ct=makeStack(0))}function mixin(o,s){var keyCopier=function(i){o.prototype[i]=s[i]};return Object.keys(s).forEach(keyCopier),Object.getOwnPropertySymbols&&Object.getOwnPropertySymbols(s).forEach(keyCopier),o}ut[lt]=!0,ut.withMutations=$e.withMutations,ut.asMutable=$e.asMutable,ut.asImmutable=$e.asImmutable,ut.wasAltered=$e.wasAltered,Iterable.Iterator=Iterator,mixin(Iterable,{toArray:function(){assertNotInfinite(this.size);var o=new Array(this.size||0);return this.valueSeq().__iterate((function(s,i){o[i]=s})),o},toIndexedSeq:function(){return new ToIndexedSequence(this)},toJS:function(){return this.toSeq().map((function(o){return o&&\"function\"==typeof o.toJS?o.toJS():o})).__toJS()},toJSON:function(){return this.toSeq().map((function(o){return o&&\"function\"==typeof o.toJSON?o.toJSON():o})).__toJS()},toKeyedSeq:function(){return new ToKeyedSequence(this,!0)},toMap:function(){return Map(this.toKeyedSeq())},toObject:function(){assertNotInfinite(this.size);var o={};return this.__iterate((function(s,i){o[i]=s})),o},toOrderedMap:function(){return OrderedMap(this.toKeyedSeq())},toOrderedSet:function(){return OrderedSet(isKeyed(this)?this.valueSeq():this)},toSet:function(){return Set(isKeyed(this)?this.valueSeq():this)},toSetSeq:function(){return new ToSetSequence(this)},toSeq:function(){return isIndexed(this)?this.toIndexedSeq():isKeyed(this)?this.toKeyedSeq():this.toSetSeq()},toStack:function(){return Stack(isKeyed(this)?this.valueSeq():this)},toList:function(){return List(isKeyed(this)?this.valueSeq():this)},toString:function(){return\"[Iterable]\"},__toString:function(o,s){return 0===this.size?o+s:o+\" \"+this.toSeq().map(this.__toStringMapper).join(\", \")+\" \"+s},concat:function(){return reify(this,concatFactory(this,o.call(arguments,0)))},includes:function(o){return this.some((function(s){return is(s,o)}))},entries:function(){return this.__iterator(z)},every:function(o,s){assertNotInfinite(this.size);var i=!0;return this.__iterate((function(u,_,w){if(!o.call(s,u,_,w))return i=!1,!1})),i},filter:function(o,s){return reify(this,filterFactory(this,o,s,!0))},find:function(o,s,i){var u=this.findEntry(o,s);return u?u[1]:i},forEach:function(o,s){return assertNotInfinite(this.size),this.__iterate(s?o.bind(s):o)},join:function(o){assertNotInfinite(this.size),o=void 0!==o?\"\"+o:\",\";var s=\"\",i=!0;return this.__iterate((function(u){i?i=!1:s+=o,s+=null!=u?u.toString():\"\"})),s},keys:function(){return this.__iterator(V)},map:function(o,s){return reify(this,mapFactory(this,o,s))},reduce:function(o,s,i){var u,_;return assertNotInfinite(this.size),arguments.length<2?_=!0:u=s,this.__iterate((function(s,w,x){_?(_=!1,u=s):u=o.call(i,u,s,w,x)})),u},reduceRight:function(o,s,i){var u=this.toKeyedSeq().reverse();return u.reduce.apply(u,arguments)},reverse:function(){return reify(this,reverseFactory(this,!0))},slice:function(o,s){return reify(this,sliceFactory(this,o,s,!0))},some:function(o,s){return!this.every(not(o),s)},sort:function(o){return reify(this,sortFactory(this,o))},values:function(){return this.__iterator(U)},butLast:function(){return this.slice(0,-1)},isEmpty:function(){return void 0!==this.size?0===this.size:!this.some((function(){return!0}))},count:function(o,s){return ensureSize(o?this.toSeq().filter(o,s):this)},countBy:function(o,s){return countByFactory(this,o,s)},equals:function(o){return deepEqual(this,o)},entrySeq:function(){var o=this;if(o._cache)return new ArraySeq(o._cache);var s=o.toSeq().map(entryMapper).toIndexedSeq();return s.fromEntrySeq=function(){return o.toSeq()},s},filterNot:function(o,s){return this.filter(not(o),s)},findEntry:function(o,s,i){var u=i;return this.__iterate((function(i,_,w){if(o.call(s,i,_,w))return u=[_,i],!1})),u},findKey:function(o,s){var i=this.findEntry(o,s);return i&&i[0]},findLast:function(o,s,i){return this.toKeyedSeq().reverse().find(o,s,i)},findLastEntry:function(o,s,i){return this.toKeyedSeq().reverse().findEntry(o,s,i)},findLastKey:function(o,s){return this.toKeyedSeq().reverse().findKey(o,s)},first:function(){return this.find(returnTrue)},flatMap:function(o,s){return reify(this,flatMapFactory(this,o,s))},flatten:function(o){return reify(this,flattenFactory(this,o,!0))},fromEntrySeq:function(){return new FromEntriesSequence(this)},get:function(o,s){return this.find((function(s,i){return is(i,o)}),void 0,s)},getIn:function(o,s){for(var i,u=this,_=forceIterator(o);!(i=_.next()).done;){var w=i.value;if((u=u&&u.get?u.get(w,L):L)===L)return s}return u},groupBy:function(o,s){return groupByFactory(this,o,s)},has:function(o){return this.get(o,L)!==L},hasIn:function(o){return this.getIn(o,L)!==L},isSubset:function(o){return o=\"function\"==typeof o.includes?o:Iterable(o),this.every((function(s){return o.includes(s)}))},isSuperset:function(o){return(o=\"function\"==typeof o.isSubset?o:Iterable(o)).isSubset(this)},keyOf:function(o){return this.findKey((function(s){return is(s,o)}))},keySeq:function(){return this.toSeq().map(keyMapper).toIndexedSeq()},last:function(){return this.toSeq().reverse().first()},lastKeyOf:function(o){return this.toKeyedSeq().reverse().keyOf(o)},max:function(o){return maxFactory(this,o)},maxBy:function(o,s){return maxFactory(this,s,o)},min:function(o){return maxFactory(this,o?neg(o):defaultNegComparator)},minBy:function(o,s){return maxFactory(this,s?neg(s):defaultNegComparator,o)},rest:function(){return this.slice(1)},skip:function(o){return this.slice(Math.max(0,o))},skipLast:function(o){return reify(this,this.toSeq().reverse().skip(o).reverse())},skipWhile:function(o,s){return reify(this,skipWhileFactory(this,o,s,!0))},skipUntil:function(o,s){return this.skipWhile(not(o),s)},sortBy:function(o,s){return reify(this,sortFactory(this,s,o))},take:function(o){return this.slice(0,Math.max(0,o))},takeLast:function(o){return reify(this,this.toSeq().reverse().take(o).reverse())},takeWhile:function(o,s){return reify(this,takeWhileFactory(this,o,s))},takeUntil:function(o,s){return this.takeWhile(not(o),s)},valueSeq:function(){return this.toIndexedSeq()},hashCode:function(){return this.__hash||(this.__hash=hashIterable(this))}});var pt=Iterable.prototype;pt[s]=!0,pt[ee]=pt.values,pt.__toJS=pt.toArray,pt.__toStringMapper=quoteString,pt.inspect=pt.toSource=function(){return this.toString()},pt.chain=pt.flatMap,pt.contains=pt.includes,mixin(KeyedIterable,{flip:function(){return reify(this,flipFactory(this))},mapEntries:function(o,s){var i=this,u=0;return reify(this,this.toSeq().map((function(_,w){return o.call(s,[w,_],u++,i)})).fromEntrySeq())},mapKeys:function(o,s){var i=this;return reify(this,this.toSeq().flip().map((function(u,_){return o.call(s,u,_,i)})).flip())}});var ht=KeyedIterable.prototype;function keyMapper(o,s){return s}function entryMapper(o,s){return[s,o]}function not(o){return function(){return!o.apply(this,arguments)}}function neg(o){return function(){return-o.apply(this,arguments)}}function quoteString(o){return\"string\"==typeof o?JSON.stringify(o):String(o)}function defaultZipper(){return arrCopy(arguments)}function defaultNegComparator(o,s){return os?-1:0}function hashIterable(o){if(o.size===1/0)return 0;var s=isOrdered(o),i=isKeyed(o),u=s?1:0;return murmurHashOfSize(o.__iterate(i?s?function(o,s){u=31*u+hashMerge(hash(o),hash(s))|0}:function(o,s){u=u+hashMerge(hash(o),hash(s))|0}:s?function(o){u=31*u+hash(o)|0}:function(o){u=u+hash(o)|0}),u)}function murmurHashOfSize(o,s){return s=pe(s,3432918353),s=pe(s<<15|s>>>-15,461845907),s=pe(s<<13|s>>>-13,5),s=pe((s=s+3864292196^o)^s>>>16,2246822507),s=smi((s=pe(s^s>>>13,3266489909))^s>>>16)}function hashMerge(o,s){return o^s+2654435769+(o<<6)+(o>>2)}return ht[i]=!0,ht[ee]=pt.entries,ht.__toJS=pt.toObject,ht.__toStringMapper=function(o,s){return JSON.stringify(s)+\": \"+quoteString(o)},mixin(IndexedIterable,{toKeyedSeq:function(){return new ToKeyedSequence(this,!1)},filter:function(o,s){return reify(this,filterFactory(this,o,s,!1))},findIndex:function(o,s){var i=this.findEntry(o,s);return i?i[0]:-1},indexOf:function(o){var s=this.keyOf(o);return void 0===s?-1:s},lastIndexOf:function(o){var s=this.lastKeyOf(o);return void 0===s?-1:s},reverse:function(){return reify(this,reverseFactory(this,!1))},slice:function(o,s){return reify(this,sliceFactory(this,o,s,!1))},splice:function(o,s){var i=arguments.length;if(s=Math.max(0|s,0),0===i||2===i&&!s)return this;o=resolveBegin(o,o<0?this.count():this.size);var u=this.slice(0,o);return reify(this,1===i?u:u.concat(arrCopy(arguments,2),this.slice(o+s)))},findLastIndex:function(o,s){var i=this.findLastEntry(o,s);return i?i[0]:-1},first:function(){return this.get(0)},flatten:function(o){return reify(this,flattenFactory(this,o,!1))},get:function(o,s){return(o=wrapIndex(this,o))<0||this.size===1/0||void 0!==this.size&&o>this.size?s:this.find((function(s,i){return i===o}),void 0,s)},has:function(o){return(o=wrapIndex(this,o))>=0&&(void 0!==this.size?this.size===1/0||o{\"function\"==typeof Object.create?o.exports=function inherits(o,s){s&&(o.super_=s,o.prototype=Object.create(s.prototype,{constructor:{value:o,enumerable:!1,writable:!0,configurable:!0}}))}:o.exports=function inherits(o,s){if(s){o.super_=s;var TempCtor=function(){};TempCtor.prototype=s.prototype,o.prototype=new TempCtor,o.prototype.constructor=o}}},5419:o=>{o.exports=function(o,s,i,u){var _=new Blob(void 0!==u?[u,o]:[o],{type:i||\"application/octet-stream\"});if(void 0!==window.navigator.msSaveBlob)window.navigator.msSaveBlob(_,s);else{var w=window.URL&&window.URL.createObjectURL?window.URL.createObjectURL(_):window.webkitURL.createObjectURL(_),x=document.createElement(\"a\");x.style.display=\"none\",x.href=w,x.setAttribute(\"download\",s),void 0===x.download&&x.setAttribute(\"target\",\"_blank\"),document.body.appendChild(x),x.click(),setTimeout((function(){document.body.removeChild(x),window.URL.revokeObjectURL(w)}),200)}}},20181:(o,s,i)=>{var u=NaN,_=\"[object Symbol]\",w=/^\\s+|\\s+$/g,x=/^[-+]0x[0-9a-f]+$/i,C=/^0b[01]+$/i,j=/^0o[0-7]+$/i,L=parseInt,B=\"object\"==typeof i.g&&i.g&&i.g.Object===Object&&i.g,$=\"object\"==typeof self&&self&&self.Object===Object&&self,V=B||$||Function(\"return this\")(),U=Object.prototype.toString,z=Math.max,Y=Math.min,now=function(){return V.Date.now()};function isObject(o){var s=typeof o;return!!o&&(\"object\"==s||\"function\"==s)}function toNumber(o){if(\"number\"==typeof o)return o;if(function isSymbol(o){return\"symbol\"==typeof o||function isObjectLike(o){return!!o&&\"object\"==typeof o}(o)&&U.call(o)==_}(o))return u;if(isObject(o)){var s=\"function\"==typeof o.valueOf?o.valueOf():o;o=isObject(s)?s+\"\":s}if(\"string\"!=typeof o)return 0===o?o:+o;o=o.replace(w,\"\");var i=C.test(o);return i||j.test(o)?L(o.slice(2),i?2:8):x.test(o)?u:+o}o.exports=function debounce(o,s,i){var u,_,w,x,C,j,L=0,B=!1,$=!1,V=!0;if(\"function\"!=typeof o)throw new TypeError(\"Expected a function\");function invokeFunc(s){var i=u,w=_;return u=_=void 0,L=s,x=o.apply(w,i)}function shouldInvoke(o){var i=o-j;return void 0===j||i>=s||i<0||$&&o-L>=w}function timerExpired(){var o=now();if(shouldInvoke(o))return trailingEdge(o);C=setTimeout(timerExpired,function remainingWait(o){var i=s-(o-j);return $?Y(i,w-(o-L)):i}(o))}function trailingEdge(o){return C=void 0,V&&u?invokeFunc(o):(u=_=void 0,x)}function debounced(){var o=now(),i=shouldInvoke(o);if(u=arguments,_=this,j=o,i){if(void 0===C)return function leadingEdge(o){return L=o,C=setTimeout(timerExpired,s),B?invokeFunc(o):x}(j);if($)return C=setTimeout(timerExpired,s),invokeFunc(j)}return void 0===C&&(C=setTimeout(timerExpired,s)),x}return s=toNumber(s)||0,isObject(i)&&(B=!!i.leading,w=($=\"maxWait\"in i)?z(toNumber(i.maxWait)||0,s):w,V=\"trailing\"in i?!!i.trailing:V),debounced.cancel=function cancel(){void 0!==C&&clearTimeout(C),L=0,u=j=_=C=void 0},debounced.flush=function flush(){return void 0===C?x:trailingEdge(now())},debounced}},55580:(o,s,i)=>{var u=i(56110)(i(9325),\"DataView\");o.exports=u},21549:(o,s,i)=>{var u=i(22032),_=i(63862),w=i(66721),x=i(12749),C=i(35749);function Hash(o){var s=-1,i=null==o?0:o.length;for(this.clear();++s{var u=i(39344),_=i(94033);function LazyWrapper(o){this.__wrapped__=o,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}LazyWrapper.prototype=u(_.prototype),LazyWrapper.prototype.constructor=LazyWrapper,o.exports=LazyWrapper},80079:(o,s,i)=>{var u=i(63702),_=i(70080),w=i(24739),x=i(48655),C=i(31175);function ListCache(o){var s=-1,i=null==o?0:o.length;for(this.clear();++s{var u=i(39344),_=i(94033);function LodashWrapper(o,s){this.__wrapped__=o,this.__actions__=[],this.__chain__=!!s,this.__index__=0,this.__values__=void 0}LodashWrapper.prototype=u(_.prototype),LodashWrapper.prototype.constructor=LodashWrapper,o.exports=LodashWrapper},68223:(o,s,i)=>{var u=i(56110)(i(9325),\"Map\");o.exports=u},53661:(o,s,i)=>{var u=i(63040),_=i(17670),w=i(90289),x=i(4509),C=i(72949);function MapCache(o){var s=-1,i=null==o?0:o.length;for(this.clear();++s{var u=i(56110)(i(9325),\"Promise\");o.exports=u},76545:(o,s,i)=>{var u=i(56110)(i(9325),\"Set\");o.exports=u},38859:(o,s,i)=>{var u=i(53661),_=i(31380),w=i(51459);function SetCache(o){var s=-1,i=null==o?0:o.length;for(this.__data__=new u;++s{var u=i(80079),_=i(51420),w=i(90938),x=i(63605),C=i(29817),j=i(80945);function Stack(o){var s=this.__data__=new u(o);this.size=s.size}Stack.prototype.clear=_,Stack.prototype.delete=w,Stack.prototype.get=x,Stack.prototype.has=C,Stack.prototype.set=j,o.exports=Stack},51873:(o,s,i)=>{var u=i(9325).Symbol;o.exports=u},37828:(o,s,i)=>{var u=i(9325).Uint8Array;o.exports=u},28303:(o,s,i)=>{var u=i(56110)(i(9325),\"WeakMap\");o.exports=u},91033:o=>{o.exports=function apply(o,s,i){switch(i.length){case 0:return o.call(s);case 1:return o.call(s,i[0]);case 2:return o.call(s,i[0],i[1]);case 3:return o.call(s,i[0],i[1],i[2])}return o.apply(s,i)}},83729:o=>{o.exports=function arrayEach(o,s){for(var i=-1,u=null==o?0:o.length;++i{o.exports=function arrayFilter(o,s){for(var i=-1,u=null==o?0:o.length,_=0,w=[];++i{var u=i(96131);o.exports=function arrayIncludes(o,s){return!!(null==o?0:o.length)&&u(o,s,0)>-1}},70695:(o,s,i)=>{var u=i(78096),_=i(72428),w=i(56449),x=i(3656),C=i(30361),j=i(37167),L=Object.prototype.hasOwnProperty;o.exports=function arrayLikeKeys(o,s){var i=w(o),B=!i&&_(o),$=!i&&!B&&x(o),V=!i&&!B&&!$&&j(o),U=i||B||$||V,z=U?u(o.length,String):[],Y=z.length;for(var Z in o)!s&&!L.call(o,Z)||U&&(\"length\"==Z||$&&(\"offset\"==Z||\"parent\"==Z)||V&&(\"buffer\"==Z||\"byteLength\"==Z||\"byteOffset\"==Z)||C(Z,Y))||z.push(Z);return z}},34932:o=>{o.exports=function arrayMap(o,s){for(var i=-1,u=null==o?0:o.length,_=Array(u);++i{o.exports=function arrayPush(o,s){for(var i=-1,u=s.length,_=o.length;++i{o.exports=function arrayReduce(o,s,i,u){var _=-1,w=null==o?0:o.length;for(u&&w&&(i=o[++_]);++_{o.exports=function arraySome(o,s){for(var i=-1,u=null==o?0:o.length;++i{o.exports=function asciiToArray(o){return o.split(\"\")}},1733:o=>{var s=/[^\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\x7f]+/g;o.exports=function asciiWords(o){return o.match(s)||[]}},87805:(o,s,i)=>{var u=i(43360),_=i(75288);o.exports=function assignMergeValue(o,s,i){(void 0!==i&&!_(o[s],i)||void 0===i&&!(s in o))&&u(o,s,i)}},16547:(o,s,i)=>{var u=i(43360),_=i(75288),w=Object.prototype.hasOwnProperty;o.exports=function assignValue(o,s,i){var x=o[s];w.call(o,s)&&_(x,i)&&(void 0!==i||s in o)||u(o,s,i)}},26025:(o,s,i)=>{var u=i(75288);o.exports=function assocIndexOf(o,s){for(var i=o.length;i--;)if(u(o[i][0],s))return i;return-1}},74733:(o,s,i)=>{var u=i(21791),_=i(95950);o.exports=function baseAssign(o,s){return o&&u(s,_(s),o)}},43838:(o,s,i)=>{var u=i(21791),_=i(37241);o.exports=function baseAssignIn(o,s){return o&&u(s,_(s),o)}},43360:(o,s,i)=>{var u=i(93243);o.exports=function baseAssignValue(o,s,i){\"__proto__\"==s&&u?u(o,s,{configurable:!0,enumerable:!0,value:i,writable:!0}):o[s]=i}},9999:(o,s,i)=>{var u=i(37217),_=i(83729),w=i(16547),x=i(74733),C=i(43838),j=i(93290),L=i(23007),B=i(92271),$=i(48948),V=i(50002),U=i(83349),z=i(5861),Y=i(76189),Z=i(77199),ee=i(35529),ie=i(56449),ae=i(3656),ce=i(87730),le=i(23805),pe=i(38440),de=i(95950),fe=i(37241),ye=\"[object Arguments]\",be=\"[object Function]\",_e=\"[object Object]\",we={};we[ye]=we[\"[object Array]\"]=we[\"[object ArrayBuffer]\"]=we[\"[object DataView]\"]=we[\"[object Boolean]\"]=we[\"[object Date]\"]=we[\"[object Float32Array]\"]=we[\"[object Float64Array]\"]=we[\"[object Int8Array]\"]=we[\"[object Int16Array]\"]=we[\"[object Int32Array]\"]=we[\"[object Map]\"]=we[\"[object Number]\"]=we[_e]=we[\"[object RegExp]\"]=we[\"[object Set]\"]=we[\"[object String]\"]=we[\"[object Symbol]\"]=we[\"[object Uint8Array]\"]=we[\"[object Uint8ClampedArray]\"]=we[\"[object Uint16Array]\"]=we[\"[object Uint32Array]\"]=!0,we[\"[object Error]\"]=we[be]=we[\"[object WeakMap]\"]=!1,o.exports=function baseClone(o,s,i,Se,xe,Pe){var Te,Re=1&s,qe=2&s,$e=4&s;if(i&&(Te=xe?i(o,Se,xe,Pe):i(o)),void 0!==Te)return Te;if(!le(o))return o;var ze=ie(o);if(ze){if(Te=Y(o),!Re)return L(o,Te)}else{var We=z(o),He=We==be||\"[object GeneratorFunction]\"==We;if(ae(o))return j(o,Re);if(We==_e||We==ye||He&&!xe){if(Te=qe||He?{}:ee(o),!Re)return qe?$(o,C(Te,o)):B(o,x(Te,o))}else{if(!we[We])return xe?o:{};Te=Z(o,We,Re)}}Pe||(Pe=new u);var Ye=Pe.get(o);if(Ye)return Ye;Pe.set(o,Te),pe(o)?o.forEach((function(u){Te.add(baseClone(u,s,i,u,o,Pe))})):ce(o)&&o.forEach((function(u,_){Te.set(_,baseClone(u,s,i,_,o,Pe))}));var Xe=ze?void 0:($e?qe?U:V:qe?fe:de)(o);return _(Xe||o,(function(u,_){Xe&&(u=o[_=u]),w(Te,_,baseClone(u,s,i,_,o,Pe))})),Te}},39344:(o,s,i)=>{var u=i(23805),_=Object.create,w=function(){function object(){}return function(o){if(!u(o))return{};if(_)return _(o);object.prototype=o;var s=new object;return object.prototype=void 0,s}}();o.exports=w},80909:(o,s,i)=>{var u=i(30641),_=i(38329)(u);o.exports=_},2523:o=>{o.exports=function baseFindIndex(o,s,i,u){for(var _=o.length,w=i+(u?1:-1);u?w--:++w<_;)if(s(o[w],w,o))return w;return-1}},83120:(o,s,i)=>{var u=i(14528),_=i(45891);o.exports=function baseFlatten(o,s,i,w,x){var C=-1,j=o.length;for(i||(i=_),x||(x=[]);++C0&&i(L)?s>1?baseFlatten(L,s-1,i,w,x):u(x,L):w||(x[x.length]=L)}return x}},86649:(o,s,i)=>{var u=i(83221)();o.exports=u},30641:(o,s,i)=>{var u=i(86649),_=i(95950);o.exports=function baseForOwn(o,s){return o&&u(o,s,_)}},47422:(o,s,i)=>{var u=i(31769),_=i(77797);o.exports=function baseGet(o,s){for(var i=0,w=(s=u(s,o)).length;null!=o&&i{var u=i(14528),_=i(56449);o.exports=function baseGetAllKeys(o,s,i){var w=s(o);return _(o)?w:u(w,i(o))}},72552:(o,s,i)=>{var u=i(51873),_=i(659),w=i(59350),x=u?u.toStringTag:void 0;o.exports=function baseGetTag(o){return null==o?void 0===o?\"[object Undefined]\":\"[object Null]\":x&&x in Object(o)?_(o):w(o)}},20426:o=>{var s=Object.prototype.hasOwnProperty;o.exports=function baseHas(o,i){return null!=o&&s.call(o,i)}},28077:o=>{o.exports=function baseHasIn(o,s){return null!=o&&s in Object(o)}},96131:(o,s,i)=>{var u=i(2523),_=i(85463),w=i(76959);o.exports=function baseIndexOf(o,s,i){return s==s?w(o,s,i):u(o,_,i)}},27534:(o,s,i)=>{var u=i(72552),_=i(40346);o.exports=function baseIsArguments(o){return _(o)&&\"[object Arguments]\"==u(o)}},60270:(o,s,i)=>{var u=i(87068),_=i(40346);o.exports=function baseIsEqual(o,s,i,w,x){return o===s||(null==o||null==s||!_(o)&&!_(s)?o!=o&&s!=s:u(o,s,i,w,baseIsEqual,x))}},87068:(o,s,i)=>{var u=i(37217),_=i(25911),w=i(21986),x=i(50689),C=i(5861),j=i(56449),L=i(3656),B=i(37167),$=\"[object Arguments]\",V=\"[object Array]\",U=\"[object Object]\",z=Object.prototype.hasOwnProperty;o.exports=function baseIsEqualDeep(o,s,i,Y,Z,ee){var ie=j(o),ae=j(s),ce=ie?V:C(o),le=ae?V:C(s),pe=(ce=ce==$?U:ce)==U,de=(le=le==$?U:le)==U,fe=ce==le;if(fe&&L(o)){if(!L(s))return!1;ie=!0,pe=!1}if(fe&&!pe)return ee||(ee=new u),ie||B(o)?_(o,s,i,Y,Z,ee):w(o,s,ce,i,Y,Z,ee);if(!(1&i)){var ye=pe&&z.call(o,\"__wrapped__\"),be=de&&z.call(s,\"__wrapped__\");if(ye||be){var _e=ye?o.value():o,we=be?s.value():s;return ee||(ee=new u),Z(_e,we,i,Y,ee)}}return!!fe&&(ee||(ee=new u),x(o,s,i,Y,Z,ee))}},29172:(o,s,i)=>{var u=i(5861),_=i(40346);o.exports=function baseIsMap(o){return _(o)&&\"[object Map]\"==u(o)}},41799:(o,s,i)=>{var u=i(37217),_=i(60270);o.exports=function baseIsMatch(o,s,i,w){var x=i.length,C=x,j=!w;if(null==o)return!C;for(o=Object(o);x--;){var L=i[x];if(j&&L[2]?L[1]!==o[L[0]]:!(L[0]in o))return!1}for(;++x{o.exports=function baseIsNaN(o){return o!=o}},45083:(o,s,i)=>{var u=i(1882),_=i(87296),w=i(23805),x=i(47473),C=/^\\[object .+?Constructor\\]$/,j=Function.prototype,L=Object.prototype,B=j.toString,$=L.hasOwnProperty,V=RegExp(\"^\"+B.call($).replace(/[\\\\^$.*+?()[\\]{}|]/g,\"\\\\$&\").replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g,\"$1.*?\")+\"$\");o.exports=function baseIsNative(o){return!(!w(o)||_(o))&&(u(o)?V:C).test(x(o))}},16038:(o,s,i)=>{var u=i(5861),_=i(40346);o.exports=function baseIsSet(o){return _(o)&&\"[object Set]\"==u(o)}},4901:(o,s,i)=>{var u=i(72552),_=i(30294),w=i(40346),x={};x[\"[object Float32Array]\"]=x[\"[object Float64Array]\"]=x[\"[object Int8Array]\"]=x[\"[object Int16Array]\"]=x[\"[object Int32Array]\"]=x[\"[object Uint8Array]\"]=x[\"[object Uint8ClampedArray]\"]=x[\"[object Uint16Array]\"]=x[\"[object Uint32Array]\"]=!0,x[\"[object Arguments]\"]=x[\"[object Array]\"]=x[\"[object ArrayBuffer]\"]=x[\"[object Boolean]\"]=x[\"[object DataView]\"]=x[\"[object Date]\"]=x[\"[object Error]\"]=x[\"[object Function]\"]=x[\"[object Map]\"]=x[\"[object Number]\"]=x[\"[object Object]\"]=x[\"[object RegExp]\"]=x[\"[object Set]\"]=x[\"[object String]\"]=x[\"[object WeakMap]\"]=!1,o.exports=function baseIsTypedArray(o){return w(o)&&_(o.length)&&!!x[u(o)]}},15389:(o,s,i)=>{var u=i(93663),_=i(87978),w=i(83488),x=i(56449),C=i(50583);o.exports=function baseIteratee(o){return\"function\"==typeof o?o:null==o?w:\"object\"==typeof o?x(o)?_(o[0],o[1]):u(o):C(o)}},88984:(o,s,i)=>{var u=i(55527),_=i(3650),w=Object.prototype.hasOwnProperty;o.exports=function baseKeys(o){if(!u(o))return _(o);var s=[];for(var i in Object(o))w.call(o,i)&&\"constructor\"!=i&&s.push(i);return s}},72903:(o,s,i)=>{var u=i(23805),_=i(55527),w=i(90181),x=Object.prototype.hasOwnProperty;o.exports=function baseKeysIn(o){if(!u(o))return w(o);var s=_(o),i=[];for(var C in o)(\"constructor\"!=C||!s&&x.call(o,C))&&i.push(C);return i}},94033:o=>{o.exports=function baseLodash(){}},93663:(o,s,i)=>{var u=i(41799),_=i(10776),w=i(67197);o.exports=function baseMatches(o){var s=_(o);return 1==s.length&&s[0][2]?w(s[0][0],s[0][1]):function(i){return i===o||u(i,o,s)}}},87978:(o,s,i)=>{var u=i(60270),_=i(58156),w=i(80631),x=i(28586),C=i(30756),j=i(67197),L=i(77797);o.exports=function baseMatchesProperty(o,s){return x(o)&&C(s)?j(L(o),s):function(i){var x=_(i,o);return void 0===x&&x===s?w(i,o):u(s,x,3)}}},85250:(o,s,i)=>{var u=i(37217),_=i(87805),w=i(86649),x=i(42824),C=i(23805),j=i(37241),L=i(14974);o.exports=function baseMerge(o,s,i,B,$){o!==s&&w(s,(function(w,j){if($||($=new u),C(w))x(o,s,j,i,baseMerge,B,$);else{var V=B?B(L(o,j),w,j+\"\",o,s,$):void 0;void 0===V&&(V=w),_(o,j,V)}}),j)}},42824:(o,s,i)=>{var u=i(87805),_=i(93290),w=i(71961),x=i(23007),C=i(35529),j=i(72428),L=i(56449),B=i(83693),$=i(3656),V=i(1882),U=i(23805),z=i(11331),Y=i(37167),Z=i(14974),ee=i(69884);o.exports=function baseMergeDeep(o,s,i,ie,ae,ce,le){var pe=Z(o,i),de=Z(s,i),fe=le.get(de);if(fe)u(o,i,fe);else{var ye=ce?ce(pe,de,i+\"\",o,s,le):void 0,be=void 0===ye;if(be){var _e=L(de),we=!_e&&$(de),Se=!_e&&!we&&Y(de);ye=de,_e||we||Se?L(pe)?ye=pe:B(pe)?ye=x(pe):we?(be=!1,ye=_(de,!0)):Se?(be=!1,ye=w(de,!0)):ye=[]:z(de)||j(de)?(ye=pe,j(pe)?ye=ee(pe):U(pe)&&!V(pe)||(ye=C(de))):be=!1}be&&(le.set(de,ye),ae(ye,de,ie,ce,le),le.delete(de)),u(o,i,ye)}}},47237:o=>{o.exports=function baseProperty(o){return function(s){return null==s?void 0:s[o]}}},17255:(o,s,i)=>{var u=i(47422);o.exports=function basePropertyDeep(o){return function(s){return u(s,o)}}},54552:o=>{o.exports=function basePropertyOf(o){return function(s){return null==o?void 0:o[s]}}},85558:o=>{o.exports=function baseReduce(o,s,i,u,_){return _(o,(function(o,_,w){i=u?(u=!1,o):s(i,o,_,w)})),i}},69302:(o,s,i)=>{var u=i(83488),_=i(56757),w=i(32865);o.exports=function baseRest(o,s){return w(_(o,s,u),o+\"\")}},73170:(o,s,i)=>{var u=i(16547),_=i(31769),w=i(30361),x=i(23805),C=i(77797);o.exports=function baseSet(o,s,i,j){if(!x(o))return o;for(var L=-1,B=(s=_(s,o)).length,$=B-1,V=o;null!=V&&++L{var u=i(83488),_=i(48152),w=_?function(o,s){return _.set(o,s),o}:u;o.exports=w},19570:(o,s,i)=>{var u=i(37334),_=i(93243),w=i(83488),x=_?function(o,s){return _(o,\"toString\",{configurable:!0,enumerable:!1,value:u(s),writable:!0})}:w;o.exports=x},25160:o=>{o.exports=function baseSlice(o,s,i){var u=-1,_=o.length;s<0&&(s=-s>_?0:_+s),(i=i>_?_:i)<0&&(i+=_),_=s>i?0:i-s>>>0,s>>>=0;for(var w=Array(_);++u<_;)w[u]=o[u+s];return w}},90916:(o,s,i)=>{var u=i(80909);o.exports=function baseSome(o,s){var i;return u(o,(function(o,u,_){return!(i=s(o,u,_))})),!!i}},78096:o=>{o.exports=function baseTimes(o,s){for(var i=-1,u=Array(o);++i{var u=i(51873),_=i(34932),w=i(56449),x=i(44394),C=u?u.prototype:void 0,j=C?C.toString:void 0;o.exports=function baseToString(o){if(\"string\"==typeof o)return o;if(w(o))return _(o,baseToString)+\"\";if(x(o))return j?j.call(o):\"\";var s=o+\"\";return\"0\"==s&&1/o==-1/0?\"-0\":s}},54128:(o,s,i)=>{var u=i(31800),_=/^\\s+/;o.exports=function baseTrim(o){return o?o.slice(0,u(o)+1).replace(_,\"\"):o}},27301:o=>{o.exports=function baseUnary(o){return function(s){return o(s)}}},19931:(o,s,i)=>{var u=i(31769),_=i(68090),w=i(68969),x=i(77797);o.exports=function baseUnset(o,s){return s=u(s,o),null==(o=w(o,s))||delete o[x(_(s))]}},51234:o=>{o.exports=function baseZipObject(o,s,i){for(var u=-1,_=o.length,w=s.length,x={};++u<_;){var C=u{o.exports=function cacheHas(o,s){return o.has(s)}},31769:(o,s,i)=>{var u=i(56449),_=i(28586),w=i(61802),x=i(13222);o.exports=function castPath(o,s){return u(o)?o:_(o,s)?[o]:w(x(o))}},28754:(o,s,i)=>{var u=i(25160);o.exports=function castSlice(o,s,i){var _=o.length;return i=void 0===i?_:i,!s&&i>=_?o:u(o,s,i)}},49653:(o,s,i)=>{var u=i(37828);o.exports=function cloneArrayBuffer(o){var s=new o.constructor(o.byteLength);return new u(s).set(new u(o)),s}},93290:(o,s,i)=>{o=i.nmd(o);var u=i(9325),_=s&&!s.nodeType&&s,w=_&&o&&!o.nodeType&&o,x=w&&w.exports===_?u.Buffer:void 0,C=x?x.allocUnsafe:void 0;o.exports=function cloneBuffer(o,s){if(s)return o.slice();var i=o.length,u=C?C(i):new o.constructor(i);return o.copy(u),u}},76169:(o,s,i)=>{var u=i(49653);o.exports=function cloneDataView(o,s){var i=s?u(o.buffer):o.buffer;return new o.constructor(i,o.byteOffset,o.byteLength)}},73201:o=>{var s=/\\w*$/;o.exports=function cloneRegExp(o){var i=new o.constructor(o.source,s.exec(o));return i.lastIndex=o.lastIndex,i}},93736:(o,s,i)=>{var u=i(51873),_=u?u.prototype:void 0,w=_?_.valueOf:void 0;o.exports=function cloneSymbol(o){return w?Object(w.call(o)):{}}},71961:(o,s,i)=>{var u=i(49653);o.exports=function cloneTypedArray(o,s){var i=s?u(o.buffer):o.buffer;return new o.constructor(i,o.byteOffset,o.length)}},91596:o=>{var s=Math.max;o.exports=function composeArgs(o,i,u,_){for(var w=-1,x=o.length,C=u.length,j=-1,L=i.length,B=s(x-C,0),$=Array(L+B),V=!_;++j{var s=Math.max;o.exports=function composeArgsRight(o,i,u,_){for(var w=-1,x=o.length,C=-1,j=u.length,L=-1,B=i.length,$=s(x-j,0),V=Array($+B),U=!_;++w<$;)V[w]=o[w];for(var z=w;++L{o.exports=function copyArray(o,s){var i=-1,u=o.length;for(s||(s=Array(u));++i{var u=i(16547),_=i(43360);o.exports=function copyObject(o,s,i,w){var x=!i;i||(i={});for(var C=-1,j=s.length;++C{var u=i(21791),_=i(4664);o.exports=function copySymbols(o,s){return u(o,_(o),s)}},48948:(o,s,i)=>{var u=i(21791),_=i(86375);o.exports=function copySymbolsIn(o,s){return u(o,_(o),s)}},55481:(o,s,i)=>{var u=i(9325)[\"__core-js_shared__\"];o.exports=u},58523:o=>{o.exports=function countHolders(o,s){for(var i=o.length,u=0;i--;)o[i]===s&&++u;return u}},20999:(o,s,i)=>{var u=i(69302),_=i(36800);o.exports=function createAssigner(o){return u((function(s,i){var u=-1,w=i.length,x=w>1?i[w-1]:void 0,C=w>2?i[2]:void 0;for(x=o.length>3&&\"function\"==typeof x?(w--,x):void 0,C&&_(i[0],i[1],C)&&(x=w<3?void 0:x,w=1),s=Object(s);++u{var u=i(64894);o.exports=function createBaseEach(o,s){return function(i,_){if(null==i)return i;if(!u(i))return o(i,_);for(var w=i.length,x=s?w:-1,C=Object(i);(s?x--:++x{o.exports=function createBaseFor(o){return function(s,i,u){for(var _=-1,w=Object(s),x=u(s),C=x.length;C--;){var j=x[o?C:++_];if(!1===i(w[j],j,w))break}return s}}},11842:(o,s,i)=>{var u=i(82819),_=i(9325);o.exports=function createBind(o,s,i){var w=1&s,x=u(o);return function wrapper(){return(this&&this!==_&&this instanceof wrapper?x:o).apply(w?i:this,arguments)}}},12507:(o,s,i)=>{var u=i(28754),_=i(49698),w=i(63912),x=i(13222);o.exports=function createCaseFirst(o){return function(s){s=x(s);var i=_(s)?w(s):void 0,C=i?i[0]:s.charAt(0),j=i?u(i,1).join(\"\"):s.slice(1);return C[o]()+j}}},45539:(o,s,i)=>{var u=i(40882),_=i(50828),w=i(66645),x=RegExp(\"['’]\",\"g\");o.exports=function createCompounder(o){return function(s){return u(w(_(s).replace(x,\"\")),o,\"\")}}},82819:(o,s,i)=>{var u=i(39344),_=i(23805);o.exports=function createCtor(o){return function(){var s=arguments;switch(s.length){case 0:return new o;case 1:return new o(s[0]);case 2:return new o(s[0],s[1]);case 3:return new o(s[0],s[1],s[2]);case 4:return new o(s[0],s[1],s[2],s[3]);case 5:return new o(s[0],s[1],s[2],s[3],s[4]);case 6:return new o(s[0],s[1],s[2],s[3],s[4],s[5]);case 7:return new o(s[0],s[1],s[2],s[3],s[4],s[5],s[6])}var i=u(o.prototype),w=o.apply(i,s);return _(w)?w:i}}},77078:(o,s,i)=>{var u=i(91033),_=i(82819),w=i(37471),x=i(18073),C=i(11287),j=i(36306),L=i(9325);o.exports=function createCurry(o,s,i){var B=_(o);return function wrapper(){for(var _=arguments.length,$=Array(_),V=_,U=C(wrapper);V--;)$[V]=arguments[V];var z=_<3&&$[0]!==U&&$[_-1]!==U?[]:j($,U);return(_-=z.length){var u=i(15389),_=i(64894),w=i(95950);o.exports=function createFind(o){return function(s,i,x){var C=Object(s);if(!_(s)){var j=u(i,3);s=w(s),i=function(o){return j(C[o],o,C)}}var L=o(s,i,x);return L>-1?C[j?s[L]:L]:void 0}}},37471:(o,s,i)=>{var u=i(91596),_=i(53320),w=i(58523),x=i(82819),C=i(18073),j=i(11287),L=i(68294),B=i(36306),$=i(9325);o.exports=function createHybrid(o,s,i,V,U,z,Y,Z,ee,ie){var ae=128&s,ce=1&s,le=2&s,pe=24&s,de=512&s,fe=le?void 0:x(o);return function wrapper(){for(var ye=arguments.length,be=Array(ye),_e=ye;_e--;)be[_e]=arguments[_e];if(pe)var we=j(wrapper),Se=w(be,we);if(V&&(be=u(be,V,U,pe)),z&&(be=_(be,z,Y,pe)),ye-=Se,pe&&ye1&&be.reverse(),ae&&ee{var u=i(91033),_=i(82819),w=i(9325);o.exports=function createPartial(o,s,i,x){var C=1&s,j=_(o);return function wrapper(){for(var s=-1,_=arguments.length,L=-1,B=x.length,$=Array(B+_),V=this&&this!==w&&this instanceof wrapper?j:o;++L{var u=i(85087),_=i(54641),w=i(70981);o.exports=function createRecurry(o,s,i,x,C,j,L,B,$,V){var U=8&s;s|=U?32:64,4&(s&=~(U?64:32))||(s&=-4);var z=[o,s,C,U?j:void 0,U?L:void 0,U?void 0:j,U?void 0:L,B,$,V],Y=i.apply(void 0,z);return u(o)&&_(Y,z),Y.placeholder=x,w(Y,o,s)}},66977:(o,s,i)=>{var u=i(68882),_=i(11842),w=i(77078),x=i(37471),C=i(24168),j=i(37381),L=i(3209),B=i(54641),$=i(70981),V=i(61489),U=Math.max;o.exports=function createWrap(o,s,i,z,Y,Z,ee,ie){var ae=2&s;if(!ae&&\"function\"!=typeof o)throw new TypeError(\"Expected a function\");var ce=z?z.length:0;if(ce||(s&=-97,z=Y=void 0),ee=void 0===ee?ee:U(V(ee),0),ie=void 0===ie?ie:V(ie),ce-=Y?Y.length:0,64&s){var le=z,pe=Y;z=Y=void 0}var de=ae?void 0:j(o),fe=[o,s,i,z,Y,le,pe,Z,ee,ie];if(de&&L(fe,de),o=fe[0],s=fe[1],i=fe[2],z=fe[3],Y=fe[4],!(ie=fe[9]=void 0===fe[9]?ae?0:o.length:U(fe[9]-ce,0))&&24&s&&(s&=-25),s&&1!=s)ye=8==s||16==s?w(o,s,ie):32!=s&&33!=s||Y.length?x.apply(void 0,fe):C(o,s,i,z);else var ye=_(o,s,i);return $((de?u:B)(ye,fe),o,s)}},53138:(o,s,i)=>{var u=i(11331);o.exports=function customOmitClone(o){return u(o)?void 0:o}},24647:(o,s,i)=>{var u=i(54552)({À:\"A\",Á:\"A\",Â:\"A\",Ã:\"A\",Ä:\"A\",Å:\"A\",à:\"a\",á:\"a\",â:\"a\",ã:\"a\",ä:\"a\",å:\"a\",Ç:\"C\",ç:\"c\",Ð:\"D\",ð:\"d\",È:\"E\",É:\"E\",Ê:\"E\",Ë:\"E\",è:\"e\",é:\"e\",ê:\"e\",ë:\"e\",Ì:\"I\",Í:\"I\",Î:\"I\",Ï:\"I\",ì:\"i\",í:\"i\",î:\"i\",ï:\"i\",Ñ:\"N\",ñ:\"n\",Ò:\"O\",Ó:\"O\",Ô:\"O\",Õ:\"O\",Ö:\"O\",Ø:\"O\",ò:\"o\",ó:\"o\",ô:\"o\",õ:\"o\",ö:\"o\",ø:\"o\",Ù:\"U\",Ú:\"U\",Û:\"U\",Ü:\"U\",ù:\"u\",ú:\"u\",û:\"u\",ü:\"u\",Ý:\"Y\",ý:\"y\",ÿ:\"y\",Æ:\"Ae\",æ:\"ae\",Þ:\"Th\",þ:\"th\",ß:\"ss\",Ā:\"A\",Ă:\"A\",Ą:\"A\",ā:\"a\",ă:\"a\",ą:\"a\",Ć:\"C\",Ĉ:\"C\",Ċ:\"C\",Č:\"C\",ć:\"c\",ĉ:\"c\",ċ:\"c\",č:\"c\",Ď:\"D\",Đ:\"D\",ď:\"d\",đ:\"d\",Ē:\"E\",Ĕ:\"E\",Ė:\"E\",Ę:\"E\",Ě:\"E\",ē:\"e\",ĕ:\"e\",ė:\"e\",ę:\"e\",ě:\"e\",Ĝ:\"G\",Ğ:\"G\",Ġ:\"G\",Ģ:\"G\",ĝ:\"g\",ğ:\"g\",ġ:\"g\",ģ:\"g\",Ĥ:\"H\",Ħ:\"H\",ĥ:\"h\",ħ:\"h\",Ĩ:\"I\",Ī:\"I\",Ĭ:\"I\",Į:\"I\",İ:\"I\",ĩ:\"i\",ī:\"i\",ĭ:\"i\",į:\"i\",ı:\"i\",Ĵ:\"J\",ĵ:\"j\",Ķ:\"K\",ķ:\"k\",ĸ:\"k\",Ĺ:\"L\",Ļ:\"L\",Ľ:\"L\",Ŀ:\"L\",Ł:\"L\",ĺ:\"l\",ļ:\"l\",ľ:\"l\",ŀ:\"l\",ł:\"l\",Ń:\"N\",Ņ:\"N\",Ň:\"N\",Ŋ:\"N\",ń:\"n\",ņ:\"n\",ň:\"n\",ŋ:\"n\",Ō:\"O\",Ŏ:\"O\",Ő:\"O\",ō:\"o\",ŏ:\"o\",ő:\"o\",Ŕ:\"R\",Ŗ:\"R\",Ř:\"R\",ŕ:\"r\",ŗ:\"r\",ř:\"r\",Ś:\"S\",Ŝ:\"S\",Ş:\"S\",Š:\"S\",ś:\"s\",ŝ:\"s\",ş:\"s\",š:\"s\",Ţ:\"T\",Ť:\"T\",Ŧ:\"T\",ţ:\"t\",ť:\"t\",ŧ:\"t\",Ũ:\"U\",Ū:\"U\",Ŭ:\"U\",Ů:\"U\",Ű:\"U\",Ų:\"U\",ũ:\"u\",ū:\"u\",ŭ:\"u\",ů:\"u\",ű:\"u\",ų:\"u\",Ŵ:\"W\",ŵ:\"w\",Ŷ:\"Y\",ŷ:\"y\",Ÿ:\"Y\",Ź:\"Z\",Ż:\"Z\",Ž:\"Z\",ź:\"z\",ż:\"z\",ž:\"z\",IJ:\"IJ\",ij:\"ij\",Œ:\"Oe\",œ:\"oe\",ʼn:\"'n\",ſ:\"s\"});o.exports=u},93243:(o,s,i)=>{var u=i(56110),_=function(){try{var o=u(Object,\"defineProperty\");return o({},\"\",{}),o}catch(o){}}();o.exports=_},25911:(o,s,i)=>{var u=i(38859),_=i(14248),w=i(19219);o.exports=function equalArrays(o,s,i,x,C,j){var L=1&i,B=o.length,$=s.length;if(B!=$&&!(L&&$>B))return!1;var V=j.get(o),U=j.get(s);if(V&&U)return V==s&&U==o;var z=-1,Y=!0,Z=2&i?new u:void 0;for(j.set(o,s),j.set(s,o);++z{var u=i(51873),_=i(37828),w=i(75288),x=i(25911),C=i(20317),j=i(84247),L=u?u.prototype:void 0,B=L?L.valueOf:void 0;o.exports=function equalByTag(o,s,i,u,L,$,V){switch(i){case\"[object DataView]\":if(o.byteLength!=s.byteLength||o.byteOffset!=s.byteOffset)return!1;o=o.buffer,s=s.buffer;case\"[object ArrayBuffer]\":return!(o.byteLength!=s.byteLength||!$(new _(o),new _(s)));case\"[object Boolean]\":case\"[object Date]\":case\"[object Number]\":return w(+o,+s);case\"[object Error]\":return o.name==s.name&&o.message==s.message;case\"[object RegExp]\":case\"[object String]\":return o==s+\"\";case\"[object Map]\":var U=C;case\"[object Set]\":var z=1&u;if(U||(U=j),o.size!=s.size&&!z)return!1;var Y=V.get(o);if(Y)return Y==s;u|=2,V.set(o,s);var Z=x(U(o),U(s),u,L,$,V);return V.delete(o),Z;case\"[object Symbol]\":if(B)return B.call(o)==B.call(s)}return!1}},50689:(o,s,i)=>{var u=i(50002),_=Object.prototype.hasOwnProperty;o.exports=function equalObjects(o,s,i,w,x,C){var j=1&i,L=u(o),B=L.length;if(B!=u(s).length&&!j)return!1;for(var $=B;$--;){var V=L[$];if(!(j?V in s:_.call(s,V)))return!1}var U=C.get(o),z=C.get(s);if(U&&z)return U==s&&z==o;var Y=!0;C.set(o,s),C.set(s,o);for(var Z=j;++${var u=i(35970),_=i(56757),w=i(32865);o.exports=function flatRest(o){return w(_(o,void 0,u),o+\"\")}},34840:(o,s,i)=>{var u=\"object\"==typeof i.g&&i.g&&i.g.Object===Object&&i.g;o.exports=u},50002:(o,s,i)=>{var u=i(82199),_=i(4664),w=i(95950);o.exports=function getAllKeys(o){return u(o,w,_)}},83349:(o,s,i)=>{var u=i(82199),_=i(86375),w=i(37241);o.exports=function getAllKeysIn(o){return u(o,w,_)}},37381:(o,s,i)=>{var u=i(48152),_=i(63950),w=u?function(o){return u.get(o)}:_;o.exports=w},62284:(o,s,i)=>{var u=i(84629),_=Object.prototype.hasOwnProperty;o.exports=function getFuncName(o){for(var s=o.name+\"\",i=u[s],w=_.call(u,s)?i.length:0;w--;){var x=i[w],C=x.func;if(null==C||C==o)return x.name}return s}},11287:o=>{o.exports=function getHolder(o){return o.placeholder}},12651:(o,s,i)=>{var u=i(74218);o.exports=function getMapData(o,s){var i=o.__data__;return u(s)?i[\"string\"==typeof s?\"string\":\"hash\"]:i.map}},10776:(o,s,i)=>{var u=i(30756),_=i(95950);o.exports=function getMatchData(o){for(var s=_(o),i=s.length;i--;){var w=s[i],x=o[w];s[i]=[w,x,u(x)]}return s}},56110:(o,s,i)=>{var u=i(45083),_=i(10392);o.exports=function getNative(o,s){var i=_(o,s);return u(i)?i:void 0}},28879:(o,s,i)=>{var u=i(74335)(Object.getPrototypeOf,Object);o.exports=u},659:(o,s,i)=>{var u=i(51873),_=Object.prototype,w=_.hasOwnProperty,x=_.toString,C=u?u.toStringTag:void 0;o.exports=function getRawTag(o){var s=w.call(o,C),i=o[C];try{o[C]=void 0;var u=!0}catch(o){}var _=x.call(o);return u&&(s?o[C]=i:delete o[C]),_}},4664:(o,s,i)=>{var u=i(79770),_=i(63345),w=Object.prototype.propertyIsEnumerable,x=Object.getOwnPropertySymbols,C=x?function(o){return null==o?[]:(o=Object(o),u(x(o),(function(s){return w.call(o,s)})))}:_;o.exports=C},86375:(o,s,i)=>{var u=i(14528),_=i(28879),w=i(4664),x=i(63345),C=Object.getOwnPropertySymbols?function(o){for(var s=[];o;)u(s,w(o)),o=_(o);return s}:x;o.exports=C},5861:(o,s,i)=>{var u=i(55580),_=i(68223),w=i(32804),x=i(76545),C=i(28303),j=i(72552),L=i(47473),B=\"[object Map]\",$=\"[object Promise]\",V=\"[object Set]\",U=\"[object WeakMap]\",z=\"[object DataView]\",Y=L(u),Z=L(_),ee=L(w),ie=L(x),ae=L(C),ce=j;(u&&ce(new u(new ArrayBuffer(1)))!=z||_&&ce(new _)!=B||w&&ce(w.resolve())!=$||x&&ce(new x)!=V||C&&ce(new C)!=U)&&(ce=function(o){var s=j(o),i=\"[object Object]\"==s?o.constructor:void 0,u=i?L(i):\"\";if(u)switch(u){case Y:return z;case Z:return B;case ee:return $;case ie:return V;case ae:return U}return s}),o.exports=ce},10392:o=>{o.exports=function getValue(o,s){return null==o?void 0:o[s]}},75251:o=>{var s=/\\{\\n\\/\\* \\[wrapped with (.+)\\] \\*/,i=/,? & /;o.exports=function getWrapDetails(o){var u=o.match(s);return u?u[1].split(i):[]}},49326:(o,s,i)=>{var u=i(31769),_=i(72428),w=i(56449),x=i(30361),C=i(30294),j=i(77797);o.exports=function hasPath(o,s,i){for(var L=-1,B=(s=u(s,o)).length,$=!1;++L{var s=RegExp(\"[\\\\u200d\\\\ud800-\\\\udfff\\\\u0300-\\\\u036f\\\\ufe20-\\\\ufe2f\\\\u20d0-\\\\u20ff\\\\ufe0e\\\\ufe0f]\");o.exports=function hasUnicode(o){return s.test(o)}},45434:o=>{var s=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;o.exports=function hasUnicodeWord(o){return s.test(o)}},22032:(o,s,i)=>{var u=i(81042);o.exports=function hashClear(){this.__data__=u?u(null):{},this.size=0}},63862:o=>{o.exports=function hashDelete(o){var s=this.has(o)&&delete this.__data__[o];return this.size-=s?1:0,s}},66721:(o,s,i)=>{var u=i(81042),_=Object.prototype.hasOwnProperty;o.exports=function hashGet(o){var s=this.__data__;if(u){var i=s[o];return\"__lodash_hash_undefined__\"===i?void 0:i}return _.call(s,o)?s[o]:void 0}},12749:(o,s,i)=>{var u=i(81042),_=Object.prototype.hasOwnProperty;o.exports=function hashHas(o){var s=this.__data__;return u?void 0!==s[o]:_.call(s,o)}},35749:(o,s,i)=>{var u=i(81042);o.exports=function hashSet(o,s){var i=this.__data__;return this.size+=this.has(o)?0:1,i[o]=u&&void 0===s?\"__lodash_hash_undefined__\":s,this}},76189:o=>{var s=Object.prototype.hasOwnProperty;o.exports=function initCloneArray(o){var i=o.length,u=new o.constructor(i);return i&&\"string\"==typeof o[0]&&s.call(o,\"index\")&&(u.index=o.index,u.input=o.input),u}},77199:(o,s,i)=>{var u=i(49653),_=i(76169),w=i(73201),x=i(93736),C=i(71961);o.exports=function initCloneByTag(o,s,i){var j=o.constructor;switch(s){case\"[object ArrayBuffer]\":return u(o);case\"[object Boolean]\":case\"[object Date]\":return new j(+o);case\"[object DataView]\":return _(o,i);case\"[object Float32Array]\":case\"[object Float64Array]\":case\"[object Int8Array]\":case\"[object Int16Array]\":case\"[object Int32Array]\":case\"[object Uint8Array]\":case\"[object Uint8ClampedArray]\":case\"[object Uint16Array]\":case\"[object Uint32Array]\":return C(o,i);case\"[object Map]\":case\"[object Set]\":return new j;case\"[object Number]\":case\"[object String]\":return new j(o);case\"[object RegExp]\":return w(o);case\"[object Symbol]\":return x(o)}}},35529:(o,s,i)=>{var u=i(39344),_=i(28879),w=i(55527);o.exports=function initCloneObject(o){return\"function\"!=typeof o.constructor||w(o)?{}:u(_(o))}},62060:o=>{var s=/\\{(?:\\n\\/\\* \\[wrapped with .+\\] \\*\\/)?\\n?/;o.exports=function insertWrapDetails(o,i){var u=i.length;if(!u)return o;var _=u-1;return i[_]=(u>1?\"& \":\"\")+i[_],i=i.join(u>2?\", \":\" \"),o.replace(s,\"{\\n/* [wrapped with \"+i+\"] */\\n\")}},45891:(o,s,i)=>{var u=i(51873),_=i(72428),w=i(56449),x=u?u.isConcatSpreadable:void 0;o.exports=function isFlattenable(o){return w(o)||_(o)||!!(x&&o&&o[x])}},30361:o=>{var s=/^(?:0|[1-9]\\d*)$/;o.exports=function isIndex(o,i){var u=typeof o;return!!(i=null==i?9007199254740991:i)&&(\"number\"==u||\"symbol\"!=u&&s.test(o))&&o>-1&&o%1==0&&o{var u=i(75288),_=i(64894),w=i(30361),x=i(23805);o.exports=function isIterateeCall(o,s,i){if(!x(i))return!1;var C=typeof s;return!!(\"number\"==C?_(i)&&w(s,i.length):\"string\"==C&&s in i)&&u(i[s],o)}},28586:(o,s,i)=>{var u=i(56449),_=i(44394),w=/\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,x=/^\\w*$/;o.exports=function isKey(o,s){if(u(o))return!1;var i=typeof o;return!(\"number\"!=i&&\"symbol\"!=i&&\"boolean\"!=i&&null!=o&&!_(o))||(x.test(o)||!w.test(o)||null!=s&&o in Object(s))}},74218:o=>{o.exports=function isKeyable(o){var s=typeof o;return\"string\"==s||\"number\"==s||\"symbol\"==s||\"boolean\"==s?\"__proto__\"!==o:null===o}},85087:(o,s,i)=>{var u=i(30980),_=i(37381),w=i(62284),x=i(53758);o.exports=function isLaziable(o){var s=w(o),i=x[s];if(\"function\"!=typeof i||!(s in u.prototype))return!1;if(o===i)return!0;var C=_(i);return!!C&&o===C[0]}},87296:(o,s,i)=>{var u,_=i(55481),w=(u=/[^.]+$/.exec(_&&_.keys&&_.keys.IE_PROTO||\"\"))?\"Symbol(src)_1.\"+u:\"\";o.exports=function isMasked(o){return!!w&&w in o}},55527:o=>{var s=Object.prototype;o.exports=function isPrototype(o){var i=o&&o.constructor;return o===(\"function\"==typeof i&&i.prototype||s)}},30756:(o,s,i)=>{var u=i(23805);o.exports=function isStrictComparable(o){return o==o&&!u(o)}},63702:o=>{o.exports=function listCacheClear(){this.__data__=[],this.size=0}},70080:(o,s,i)=>{var u=i(26025),_=Array.prototype.splice;o.exports=function listCacheDelete(o){var s=this.__data__,i=u(s,o);return!(i<0)&&(i==s.length-1?s.pop():_.call(s,i,1),--this.size,!0)}},24739:(o,s,i)=>{var u=i(26025);o.exports=function listCacheGet(o){var s=this.__data__,i=u(s,o);return i<0?void 0:s[i][1]}},48655:(o,s,i)=>{var u=i(26025);o.exports=function listCacheHas(o){return u(this.__data__,o)>-1}},31175:(o,s,i)=>{var u=i(26025);o.exports=function listCacheSet(o,s){var i=this.__data__,_=u(i,o);return _<0?(++this.size,i.push([o,s])):i[_][1]=s,this}},63040:(o,s,i)=>{var u=i(21549),_=i(80079),w=i(68223);o.exports=function mapCacheClear(){this.size=0,this.__data__={hash:new u,map:new(w||_),string:new u}}},17670:(o,s,i)=>{var u=i(12651);o.exports=function mapCacheDelete(o){var s=u(this,o).delete(o);return this.size-=s?1:0,s}},90289:(o,s,i)=>{var u=i(12651);o.exports=function mapCacheGet(o){return u(this,o).get(o)}},4509:(o,s,i)=>{var u=i(12651);o.exports=function mapCacheHas(o){return u(this,o).has(o)}},72949:(o,s,i)=>{var u=i(12651);o.exports=function mapCacheSet(o,s){var i=u(this,o),_=i.size;return i.set(o,s),this.size+=i.size==_?0:1,this}},20317:o=>{o.exports=function mapToArray(o){var s=-1,i=Array(o.size);return o.forEach((function(o,u){i[++s]=[u,o]})),i}},67197:o=>{o.exports=function matchesStrictComparable(o,s){return function(i){return null!=i&&(i[o]===s&&(void 0!==s||o in Object(i)))}}},62224:(o,s,i)=>{var u=i(50104);o.exports=function memoizeCapped(o){var s=u(o,(function(o){return 500===i.size&&i.clear(),o})),i=s.cache;return s}},3209:(o,s,i)=>{var u=i(91596),_=i(53320),w=i(36306),x=\"__lodash_placeholder__\",C=128,j=Math.min;o.exports=function mergeData(o,s){var i=o[1],L=s[1],B=i|L,$=B<131,V=L==C&&8==i||L==C&&256==i&&o[7].length<=s[8]||384==L&&s[7].length<=s[8]&&8==i;if(!$&&!V)return o;1&L&&(o[2]=s[2],B|=1&i?0:4);var U=s[3];if(U){var z=o[3];o[3]=z?u(z,U,s[4]):U,o[4]=z?w(o[3],x):s[4]}return(U=s[5])&&(z=o[5],o[5]=z?_(z,U,s[6]):U,o[6]=z?w(o[5],x):s[6]),(U=s[7])&&(o[7]=U),L&C&&(o[8]=null==o[8]?s[8]:j(o[8],s[8])),null==o[9]&&(o[9]=s[9]),o[0]=s[0],o[1]=B,o}},48152:(o,s,i)=>{var u=i(28303),_=u&&new u;o.exports=_},81042:(o,s,i)=>{var u=i(56110)(Object,\"create\");o.exports=u},3650:(o,s,i)=>{var u=i(74335)(Object.keys,Object);o.exports=u},90181:o=>{o.exports=function nativeKeysIn(o){var s=[];if(null!=o)for(var i in Object(o))s.push(i);return s}},86009:(o,s,i)=>{o=i.nmd(o);var u=i(34840),_=s&&!s.nodeType&&s,w=_&&o&&!o.nodeType&&o,x=w&&w.exports===_&&u.process,C=function(){try{var o=w&&w.require&&w.require(\"util\").types;return o||x&&x.binding&&x.binding(\"util\")}catch(o){}}();o.exports=C},59350:o=>{var s=Object.prototype.toString;o.exports=function objectToString(o){return s.call(o)}},74335:o=>{o.exports=function overArg(o,s){return function(i){return o(s(i))}}},56757:(o,s,i)=>{var u=i(91033),_=Math.max;o.exports=function overRest(o,s,i){return s=_(void 0===s?o.length-1:s,0),function(){for(var w=arguments,x=-1,C=_(w.length-s,0),j=Array(C);++x{var u=i(47422),_=i(25160);o.exports=function parent(o,s){return s.length<2?o:u(o,_(s,0,-1))}},84629:o=>{o.exports={}},68294:(o,s,i)=>{var u=i(23007),_=i(30361),w=Math.min;o.exports=function reorder(o,s){for(var i=o.length,x=w(s.length,i),C=u(o);x--;){var j=s[x];o[x]=_(j,i)?C[j]:void 0}return o}},36306:o=>{var s=\"__lodash_placeholder__\";o.exports=function replaceHolders(o,i){for(var u=-1,_=o.length,w=0,x=[];++u<_;){var C=o[u];C!==i&&C!==s||(o[u]=s,x[w++]=u)}return x}},9325:(o,s,i)=>{var u=i(34840),_=\"object\"==typeof self&&self&&self.Object===Object&&self,w=u||_||Function(\"return this\")();o.exports=w},14974:o=>{o.exports=function safeGet(o,s){if((\"constructor\"!==s||\"function\"!=typeof o[s])&&\"__proto__\"!=s)return o[s]}},31380:o=>{o.exports=function setCacheAdd(o){return this.__data__.set(o,\"__lodash_hash_undefined__\"),this}},51459:o=>{o.exports=function setCacheHas(o){return this.__data__.has(o)}},54641:(o,s,i)=>{var u=i(68882),_=i(51811)(u);o.exports=_},84247:o=>{o.exports=function setToArray(o){var s=-1,i=Array(o.size);return o.forEach((function(o){i[++s]=o})),i}},32865:(o,s,i)=>{var u=i(19570),_=i(51811)(u);o.exports=_},70981:(o,s,i)=>{var u=i(75251),_=i(62060),w=i(32865),x=i(75948);o.exports=function setWrapToString(o,s,i){var C=s+\"\";return w(o,_(C,x(u(C),i)))}},51811:o=>{var s=Date.now;o.exports=function shortOut(o){var i=0,u=0;return function(){var _=s(),w=16-(_-u);if(u=_,w>0){if(++i>=800)return arguments[0]}else i=0;return o.apply(void 0,arguments)}}},51420:(o,s,i)=>{var u=i(80079);o.exports=function stackClear(){this.__data__=new u,this.size=0}},90938:o=>{o.exports=function stackDelete(o){var s=this.__data__,i=s.delete(o);return this.size=s.size,i}},63605:o=>{o.exports=function stackGet(o){return this.__data__.get(o)}},29817:o=>{o.exports=function stackHas(o){return this.__data__.has(o)}},80945:(o,s,i)=>{var u=i(80079),_=i(68223),w=i(53661);o.exports=function stackSet(o,s){var i=this.__data__;if(i instanceof u){var x=i.__data__;if(!_||x.length<199)return x.push([o,s]),this.size=++i.size,this;i=this.__data__=new w(x)}return i.set(o,s),this.size=i.size,this}},76959:o=>{o.exports=function strictIndexOf(o,s,i){for(var u=i-1,_=o.length;++u<_;)if(o[u]===s)return u;return-1}},63912:(o,s,i)=>{var u=i(61074),_=i(49698),w=i(42054);o.exports=function stringToArray(o){return _(o)?w(o):u(o)}},61802:(o,s,i)=>{var u=i(62224),_=/[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g,w=/\\\\(\\\\)?/g,x=u((function(o){var s=[];return 46===o.charCodeAt(0)&&s.push(\"\"),o.replace(_,(function(o,i,u,_){s.push(u?_.replace(w,\"$1\"):i||o)})),s}));o.exports=x},77797:(o,s,i)=>{var u=i(44394);o.exports=function toKey(o){if(\"string\"==typeof o||u(o))return o;var s=o+\"\";return\"0\"==s&&1/o==-1/0?\"-0\":s}},47473:o=>{var s=Function.prototype.toString;o.exports=function toSource(o){if(null!=o){try{return s.call(o)}catch(o){}try{return o+\"\"}catch(o){}}return\"\"}},31800:o=>{var s=/\\s/;o.exports=function trimmedEndIndex(o){for(var i=o.length;i--&&s.test(o.charAt(i)););return i}},42054:o=>{var s=\"\\\\ud800-\\\\udfff\",i=\"[\"+s+\"]\",u=\"[\\\\u0300-\\\\u036f\\\\ufe20-\\\\ufe2f\\\\u20d0-\\\\u20ff]\",_=\"\\\\ud83c[\\\\udffb-\\\\udfff]\",w=\"[^\"+s+\"]\",x=\"(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}\",C=\"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\",j=\"(?:\"+u+\"|\"+_+\")\"+\"?\",L=\"[\\\\ufe0e\\\\ufe0f]?\",B=L+j+(\"(?:\\\\u200d(?:\"+[w,x,C].join(\"|\")+\")\"+L+j+\")*\"),$=\"(?:\"+[w+u+\"?\",u,x,C,i].join(\"|\")+\")\",V=RegExp(_+\"(?=\"+_+\")|\"+$+B,\"g\");o.exports=function unicodeToArray(o){return o.match(V)||[]}},22225:o=>{var s=\"\\\\ud800-\\\\udfff\",i=\"\\\\u2700-\\\\u27bf\",u=\"a-z\\\\xdf-\\\\xf6\\\\xf8-\\\\xff\",_=\"A-Z\\\\xc0-\\\\xd6\\\\xd8-\\\\xde\",w=\"\\\\xac\\\\xb1\\\\xd7\\\\xf7\\\\x00-\\\\x2f\\\\x3a-\\\\x40\\\\x5b-\\\\x60\\\\x7b-\\\\xbf\\\\u2000-\\\\u206f \\\\t\\\\x0b\\\\f\\\\xa0\\\\ufeff\\\\n\\\\r\\\\u2028\\\\u2029\\\\u1680\\\\u180e\\\\u2000\\\\u2001\\\\u2002\\\\u2003\\\\u2004\\\\u2005\\\\u2006\\\\u2007\\\\u2008\\\\u2009\\\\u200a\\\\u202f\\\\u205f\\\\u3000\",x=\"[\"+w+\"]\",C=\"\\\\d+\",j=\"[\"+i+\"]\",L=\"[\"+u+\"]\",B=\"[^\"+s+w+C+i+u+_+\"]\",$=\"(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}\",V=\"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\",U=\"[\"+_+\"]\",z=\"(?:\"+L+\"|\"+B+\")\",Y=\"(?:\"+U+\"|\"+B+\")\",Z=\"(?:['’](?:d|ll|m|re|s|t|ve))?\",ee=\"(?:['’](?:D|LL|M|RE|S|T|VE))?\",ie=\"(?:[\\\\u0300-\\\\u036f\\\\ufe20-\\\\ufe2f\\\\u20d0-\\\\u20ff]|\\\\ud83c[\\\\udffb-\\\\udfff])?\",ae=\"[\\\\ufe0e\\\\ufe0f]?\",ce=ae+ie+(\"(?:\\\\u200d(?:\"+[\"[^\"+s+\"]\",$,V].join(\"|\")+\")\"+ae+ie+\")*\"),le=\"(?:\"+[j,$,V].join(\"|\")+\")\"+ce,pe=RegExp([U+\"?\"+L+\"+\"+Z+\"(?=\"+[x,U,\"$\"].join(\"|\")+\")\",Y+\"+\"+ee+\"(?=\"+[x,U+z,\"$\"].join(\"|\")+\")\",U+\"?\"+z+\"+\"+Z,U+\"+\"+ee,\"\\\\d*(?:1ST|2ND|3RD|(?![123])\\\\dTH)(?=\\\\b|[a-z_])\",\"\\\\d*(?:1st|2nd|3rd|(?![123])\\\\dth)(?=\\\\b|[A-Z_])\",C,le].join(\"|\"),\"g\");o.exports=function unicodeWords(o){return o.match(pe)||[]}},75948:(o,s,i)=>{var u=i(83729),_=i(15325),w=[[\"ary\",128],[\"bind\",1],[\"bindKey\",2],[\"curry\",8],[\"curryRight\",16],[\"flip\",512],[\"partial\",32],[\"partialRight\",64],[\"rearg\",256]];o.exports=function updateWrapDetails(o,s){return u(w,(function(i){var u=\"_.\"+i[0];s&i[1]&&!_(o,u)&&o.push(u)})),o.sort()}},80257:(o,s,i)=>{var u=i(30980),_=i(56017),w=i(23007);o.exports=function wrapperClone(o){if(o instanceof u)return o.clone();var s=new _(o.__wrapped__,o.__chain__);return s.__actions__=w(o.__actions__),s.__index__=o.__index__,s.__values__=o.__values__,s}},64626:(o,s,i)=>{var u=i(66977);o.exports=function ary(o,s,i){return s=i?void 0:s,s=o&&null==s?o.length:s,u(o,128,void 0,void 0,void 0,void 0,s)}},84058:(o,s,i)=>{var u=i(14792),_=i(45539)((function(o,s,i){return s=s.toLowerCase(),o+(i?u(s):s)}));o.exports=_},14792:(o,s,i)=>{var u=i(13222),_=i(55808);o.exports=function capitalize(o){return _(u(o).toLowerCase())}},32629:(o,s,i)=>{var u=i(9999);o.exports=function clone(o){return u(o,4)}},37334:o=>{o.exports=function constant(o){return function(){return o}}},49747:(o,s,i)=>{var u=i(66977);function curry(o,s,i){var _=u(o,8,void 0,void 0,void 0,void 0,void 0,s=i?void 0:s);return _.placeholder=curry.placeholder,_}curry.placeholder={},o.exports=curry},38221:(o,s,i)=>{var u=i(23805),_=i(10124),w=i(99374),x=Math.max,C=Math.min;o.exports=function debounce(o,s,i){var j,L,B,$,V,U,z=0,Y=!1,Z=!1,ee=!0;if(\"function\"!=typeof o)throw new TypeError(\"Expected a function\");function invokeFunc(s){var i=j,u=L;return j=L=void 0,z=s,$=o.apply(u,i)}function shouldInvoke(o){var i=o-U;return void 0===U||i>=s||i<0||Z&&o-z>=B}function timerExpired(){var o=_();if(shouldInvoke(o))return trailingEdge(o);V=setTimeout(timerExpired,function remainingWait(o){var i=s-(o-U);return Z?C(i,B-(o-z)):i}(o))}function trailingEdge(o){return V=void 0,ee&&j?invokeFunc(o):(j=L=void 0,$)}function debounced(){var o=_(),i=shouldInvoke(o);if(j=arguments,L=this,U=o,i){if(void 0===V)return function leadingEdge(o){return z=o,V=setTimeout(timerExpired,s),Y?invokeFunc(o):$}(U);if(Z)return clearTimeout(V),V=setTimeout(timerExpired,s),invokeFunc(U)}return void 0===V&&(V=setTimeout(timerExpired,s)),$}return s=w(s)||0,u(i)&&(Y=!!i.leading,B=(Z=\"maxWait\"in i)?x(w(i.maxWait)||0,s):B,ee=\"trailing\"in i?!!i.trailing:ee),debounced.cancel=function cancel(){void 0!==V&&clearTimeout(V),z=0,j=U=L=V=void 0},debounced.flush=function flush(){return void 0===V?$:trailingEdge(_())},debounced}},50828:(o,s,i)=>{var u=i(24647),_=i(13222),w=/[\\xc0-\\xd6\\xd8-\\xf6\\xf8-\\xff\\u0100-\\u017f]/g,x=RegExp(\"[\\\\u0300-\\\\u036f\\\\ufe20-\\\\ufe2f\\\\u20d0-\\\\u20ff]\",\"g\");o.exports=function deburr(o){return(o=_(o))&&o.replace(w,u).replace(x,\"\")}},75288:o=>{o.exports=function eq(o,s){return o===s||o!=o&&s!=s}},60680:(o,s,i)=>{var u=i(13222),_=/[\\\\^$.*+?()[\\]{}|]/g,w=RegExp(_.source);o.exports=function escapeRegExp(o){return(o=u(o))&&w.test(o)?o.replace(_,\"\\\\$&\"):o}},7309:(o,s,i)=>{var u=i(62006)(i(24713));o.exports=u},24713:(o,s,i)=>{var u=i(2523),_=i(15389),w=i(61489),x=Math.max;o.exports=function findIndex(o,s,i){var C=null==o?0:o.length;if(!C)return-1;var j=null==i?0:w(i);return j<0&&(j=x(C+j,0)),u(o,_(s,3),j)}},35970:(o,s,i)=>{var u=i(83120);o.exports=function flatten(o){return(null==o?0:o.length)?u(o,1):[]}},73424:(o,s,i)=>{var u=i(16962),_=i(2874),w=Array.prototype.push;function baseAry(o,s){return 2==s?function(s,i){return o(s,i)}:function(s){return o(s)}}function cloneArray(o){for(var s=o?o.length:0,i=Array(s);s--;)i[s]=o[s];return i}function wrapImmutable(o,s){return function(){var i=arguments.length;if(i){for(var u=Array(i);i--;)u[i]=arguments[i];var _=u[0]=s.apply(void 0,u);return o.apply(void 0,u),_}}}o.exports=function baseConvert(o,s,i,x){var C=\"function\"==typeof s,j=s===Object(s);if(j&&(x=i,i=s,s=void 0),null==i)throw new TypeError;x||(x={});var L={cap:!(\"cap\"in x)||x.cap,curry:!(\"curry\"in x)||x.curry,fixed:!(\"fixed\"in x)||x.fixed,immutable:!(\"immutable\"in x)||x.immutable,rearg:!(\"rearg\"in x)||x.rearg},B=C?i:_,$=\"curry\"in x&&x.curry,V=\"fixed\"in x&&x.fixed,U=\"rearg\"in x&&x.rearg,z=C?i.runInContext():void 0,Y=C?i:{ary:o.ary,assign:o.assign,clone:o.clone,curry:o.curry,forEach:o.forEach,isArray:o.isArray,isError:o.isError,isFunction:o.isFunction,isWeakMap:o.isWeakMap,iteratee:o.iteratee,keys:o.keys,rearg:o.rearg,toInteger:o.toInteger,toPath:o.toPath},Z=Y.ary,ee=Y.assign,ie=Y.clone,ae=Y.curry,ce=Y.forEach,le=Y.isArray,pe=Y.isError,de=Y.isFunction,fe=Y.isWeakMap,ye=Y.keys,be=Y.rearg,_e=Y.toInteger,we=Y.toPath,Se=ye(u.aryMethod),xe={castArray:function(o){return function(){var s=arguments[0];return le(s)?o(cloneArray(s)):o.apply(void 0,arguments)}},iteratee:function(o){return function(){var s=arguments[1],i=o(arguments[0],s),u=i.length;return L.cap&&\"number\"==typeof s?(s=s>2?s-2:1,u&&u<=s?i:baseAry(i,s)):i}},mixin:function(o){return function(s){var i=this;if(!de(i))return o(i,Object(s));var u=[];return ce(ye(s),(function(o){de(s[o])&&u.push([o,i.prototype[o]])})),o(i,Object(s)),ce(u,(function(o){var s=o[1];de(s)?i.prototype[o[0]]=s:delete i.prototype[o[0]]})),i}},nthArg:function(o){return function(s){var i=s<0?1:_e(s)+1;return ae(o(s),i)}},rearg:function(o){return function(s,i){var u=i?i.length:0;return ae(o(s,i),u)}},runInContext:function(s){return function(i){return baseConvert(o,s(i),x)}}};function castCap(o,s){if(L.cap){var i=u.iterateeRearg[o];if(i)return function iterateeRearg(o,s){return overArg(o,(function(o){var i=s.length;return function baseArity(o,s){return 2==s?function(s,i){return o.apply(void 0,arguments)}:function(s){return o.apply(void 0,arguments)}}(be(baseAry(o,i),s),i)}))}(s,i);var _=!C&&u.iterateeAry[o];if(_)return function iterateeAry(o,s){return overArg(o,(function(o){return\"function\"==typeof o?baseAry(o,s):o}))}(s,_)}return s}function castFixed(o,s,i){if(L.fixed&&(V||!u.skipFixed[o])){var _=u.methodSpread[o],x=_&&_.start;return void 0===x?Z(s,i):function flatSpread(o,s){return function(){for(var i=arguments.length,u=i-1,_=Array(i);i--;)_[i]=arguments[i];var x=_[s],C=_.slice(0,s);return x&&w.apply(C,x),s!=u&&w.apply(C,_.slice(s+1)),o.apply(this,C)}}(s,x)}return s}function castRearg(o,s,i){return L.rearg&&i>1&&(U||!u.skipRearg[o])?be(s,u.methodRearg[o]||u.aryRearg[i]):s}function cloneByPath(o,s){for(var i=-1,u=(s=we(s)).length,_=u-1,w=ie(Object(o)),x=w;null!=x&&++i1?ae(s,i):s}(0,_=castCap(w,_),o),!1}})),!_})),_||(_=x),_==s&&(_=$?ae(_,1):function(){return s.apply(this,arguments)}),_.convert=createConverter(w,s),_.placeholder=s.placeholder=i,_}if(!j)return wrap(s,i,B);var Pe=i,Te=[];return ce(Se,(function(o){ce(u.aryMethod[o],(function(o){var s=Pe[u.remap[o]||o];s&&Te.push([o,wrap(o,s,Pe)])}))})),ce(ye(Pe),(function(o){var s=Pe[o];if(\"function\"==typeof s){for(var i=Te.length;i--;)if(Te[i][0]==o)return;s.convert=createConverter(o,s),Te.push([o,s])}})),ce(Te,(function(o){Pe[o[0]]=o[1]})),Pe.convert=function convertLib(o){return Pe.runInContext.convert(o)(void 0)},Pe.placeholder=Pe,ce(ye(Pe),(function(o){ce(u.realToAlias[o]||[],(function(s){Pe[s]=Pe[o]}))})),Pe}},16962:(o,s)=>{s.aliasToReal={each:\"forEach\",eachRight:\"forEachRight\",entries:\"toPairs\",entriesIn:\"toPairsIn\",extend:\"assignIn\",extendAll:\"assignInAll\",extendAllWith:\"assignInAllWith\",extendWith:\"assignInWith\",first:\"head\",conforms:\"conformsTo\",matches:\"isMatch\",property:\"get\",__:\"placeholder\",F:\"stubFalse\",T:\"stubTrue\",all:\"every\",allPass:\"overEvery\",always:\"constant\",any:\"some\",anyPass:\"overSome\",apply:\"spread\",assoc:\"set\",assocPath:\"set\",complement:\"negate\",compose:\"flowRight\",contains:\"includes\",dissoc:\"unset\",dissocPath:\"unset\",dropLast:\"dropRight\",dropLastWhile:\"dropRightWhile\",equals:\"isEqual\",identical:\"eq\",indexBy:\"keyBy\",init:\"initial\",invertObj:\"invert\",juxt:\"over\",omitAll:\"omit\",nAry:\"ary\",path:\"get\",pathEq:\"matchesProperty\",pathOr:\"getOr\",paths:\"at\",pickAll:\"pick\",pipe:\"flow\",pluck:\"map\",prop:\"get\",propEq:\"matchesProperty\",propOr:\"getOr\",props:\"at\",symmetricDifference:\"xor\",symmetricDifferenceBy:\"xorBy\",symmetricDifferenceWith:\"xorWith\",takeLast:\"takeRight\",takeLastWhile:\"takeRightWhile\",unapply:\"rest\",unnest:\"flatten\",useWith:\"overArgs\",where:\"conformsTo\",whereEq:\"isMatch\",zipObj:\"zipObject\"},s.aryMethod={1:[\"assignAll\",\"assignInAll\",\"attempt\",\"castArray\",\"ceil\",\"create\",\"curry\",\"curryRight\",\"defaultsAll\",\"defaultsDeepAll\",\"floor\",\"flow\",\"flowRight\",\"fromPairs\",\"invert\",\"iteratee\",\"memoize\",\"method\",\"mergeAll\",\"methodOf\",\"mixin\",\"nthArg\",\"over\",\"overEvery\",\"overSome\",\"rest\",\"reverse\",\"round\",\"runInContext\",\"spread\",\"template\",\"trim\",\"trimEnd\",\"trimStart\",\"uniqueId\",\"words\",\"zipAll\"],2:[\"add\",\"after\",\"ary\",\"assign\",\"assignAllWith\",\"assignIn\",\"assignInAllWith\",\"at\",\"before\",\"bind\",\"bindAll\",\"bindKey\",\"chunk\",\"cloneDeepWith\",\"cloneWith\",\"concat\",\"conformsTo\",\"countBy\",\"curryN\",\"curryRightN\",\"debounce\",\"defaults\",\"defaultsDeep\",\"defaultTo\",\"delay\",\"difference\",\"divide\",\"drop\",\"dropRight\",\"dropRightWhile\",\"dropWhile\",\"endsWith\",\"eq\",\"every\",\"filter\",\"find\",\"findIndex\",\"findKey\",\"findLast\",\"findLastIndex\",\"findLastKey\",\"flatMap\",\"flatMapDeep\",\"flattenDepth\",\"forEach\",\"forEachRight\",\"forIn\",\"forInRight\",\"forOwn\",\"forOwnRight\",\"get\",\"groupBy\",\"gt\",\"gte\",\"has\",\"hasIn\",\"includes\",\"indexOf\",\"intersection\",\"invertBy\",\"invoke\",\"invokeMap\",\"isEqual\",\"isMatch\",\"join\",\"keyBy\",\"lastIndexOf\",\"lt\",\"lte\",\"map\",\"mapKeys\",\"mapValues\",\"matchesProperty\",\"maxBy\",\"meanBy\",\"merge\",\"mergeAllWith\",\"minBy\",\"multiply\",\"nth\",\"omit\",\"omitBy\",\"overArgs\",\"pad\",\"padEnd\",\"padStart\",\"parseInt\",\"partial\",\"partialRight\",\"partition\",\"pick\",\"pickBy\",\"propertyOf\",\"pull\",\"pullAll\",\"pullAt\",\"random\",\"range\",\"rangeRight\",\"rearg\",\"reject\",\"remove\",\"repeat\",\"restFrom\",\"result\",\"sampleSize\",\"some\",\"sortBy\",\"sortedIndex\",\"sortedIndexOf\",\"sortedLastIndex\",\"sortedLastIndexOf\",\"sortedUniqBy\",\"split\",\"spreadFrom\",\"startsWith\",\"subtract\",\"sumBy\",\"take\",\"takeRight\",\"takeRightWhile\",\"takeWhile\",\"tap\",\"throttle\",\"thru\",\"times\",\"trimChars\",\"trimCharsEnd\",\"trimCharsStart\",\"truncate\",\"union\",\"uniqBy\",\"uniqWith\",\"unset\",\"unzipWith\",\"without\",\"wrap\",\"xor\",\"zip\",\"zipObject\",\"zipObjectDeep\"],3:[\"assignInWith\",\"assignWith\",\"clamp\",\"differenceBy\",\"differenceWith\",\"findFrom\",\"findIndexFrom\",\"findLastFrom\",\"findLastIndexFrom\",\"getOr\",\"includesFrom\",\"indexOfFrom\",\"inRange\",\"intersectionBy\",\"intersectionWith\",\"invokeArgs\",\"invokeArgsMap\",\"isEqualWith\",\"isMatchWith\",\"flatMapDepth\",\"lastIndexOfFrom\",\"mergeWith\",\"orderBy\",\"padChars\",\"padCharsEnd\",\"padCharsStart\",\"pullAllBy\",\"pullAllWith\",\"rangeStep\",\"rangeStepRight\",\"reduce\",\"reduceRight\",\"replace\",\"set\",\"slice\",\"sortedIndexBy\",\"sortedLastIndexBy\",\"transform\",\"unionBy\",\"unionWith\",\"update\",\"xorBy\",\"xorWith\",\"zipWith\"],4:[\"fill\",\"setWith\",\"updateWith\"]},s.aryRearg={2:[1,0],3:[2,0,1],4:[3,2,0,1]},s.iterateeAry={dropRightWhile:1,dropWhile:1,every:1,filter:1,find:1,findFrom:1,findIndex:1,findIndexFrom:1,findKey:1,findLast:1,findLastFrom:1,findLastIndex:1,findLastIndexFrom:1,findLastKey:1,flatMap:1,flatMapDeep:1,flatMapDepth:1,forEach:1,forEachRight:1,forIn:1,forInRight:1,forOwn:1,forOwnRight:1,map:1,mapKeys:1,mapValues:1,partition:1,reduce:2,reduceRight:2,reject:1,remove:1,some:1,takeRightWhile:1,takeWhile:1,times:1,transform:2},s.iterateeRearg={mapKeys:[1],reduceRight:[1,0]},s.methodRearg={assignInAllWith:[1,0],assignInWith:[1,2,0],assignAllWith:[1,0],assignWith:[1,2,0],differenceBy:[1,2,0],differenceWith:[1,2,0],getOr:[2,1,0],intersectionBy:[1,2,0],intersectionWith:[1,2,0],isEqualWith:[1,2,0],isMatchWith:[2,1,0],mergeAllWith:[1,0],mergeWith:[1,2,0],padChars:[2,1,0],padCharsEnd:[2,1,0],padCharsStart:[2,1,0],pullAllBy:[2,1,0],pullAllWith:[2,1,0],rangeStep:[1,2,0],rangeStepRight:[1,2,0],setWith:[3,1,2,0],sortedIndexBy:[2,1,0],sortedLastIndexBy:[2,1,0],unionBy:[1,2,0],unionWith:[1,2,0],updateWith:[3,1,2,0],xorBy:[1,2,0],xorWith:[1,2,0],zipWith:[1,2,0]},s.methodSpread={assignAll:{start:0},assignAllWith:{start:0},assignInAll:{start:0},assignInAllWith:{start:0},defaultsAll:{start:0},defaultsDeepAll:{start:0},invokeArgs:{start:2},invokeArgsMap:{start:2},mergeAll:{start:0},mergeAllWith:{start:0},partial:{start:1},partialRight:{start:1},without:{start:1},zipAll:{start:0}},s.mutate={array:{fill:!0,pull:!0,pullAll:!0,pullAllBy:!0,pullAllWith:!0,pullAt:!0,remove:!0,reverse:!0},object:{assign:!0,assignAll:!0,assignAllWith:!0,assignIn:!0,assignInAll:!0,assignInAllWith:!0,assignInWith:!0,assignWith:!0,defaults:!0,defaultsAll:!0,defaultsDeep:!0,defaultsDeepAll:!0,merge:!0,mergeAll:!0,mergeAllWith:!0,mergeWith:!0},set:{set:!0,setWith:!0,unset:!0,update:!0,updateWith:!0}},s.realToAlias=function(){var o=Object.prototype.hasOwnProperty,i=s.aliasToReal,u={};for(var _ in i){var w=i[_];o.call(u,w)?u[w].push(_):u[w]=[_]}return u}(),s.remap={assignAll:\"assign\",assignAllWith:\"assignWith\",assignInAll:\"assignIn\",assignInAllWith:\"assignInWith\",curryN:\"curry\",curryRightN:\"curryRight\",defaultsAll:\"defaults\",defaultsDeepAll:\"defaultsDeep\",findFrom:\"find\",findIndexFrom:\"findIndex\",findLastFrom:\"findLast\",findLastIndexFrom:\"findLastIndex\",getOr:\"get\",includesFrom:\"includes\",indexOfFrom:\"indexOf\",invokeArgs:\"invoke\",invokeArgsMap:\"invokeMap\",lastIndexOfFrom:\"lastIndexOf\",mergeAll:\"merge\",mergeAllWith:\"mergeWith\",padChars:\"pad\",padCharsEnd:\"padEnd\",padCharsStart:\"padStart\",propertyOf:\"get\",rangeStep:\"range\",rangeStepRight:\"rangeRight\",restFrom:\"rest\",spreadFrom:\"spread\",trimChars:\"trim\",trimCharsEnd:\"trimEnd\",trimCharsStart:\"trimStart\",zipAll:\"zip\"},s.skipFixed={castArray:!0,flow:!0,flowRight:!0,iteratee:!0,mixin:!0,rearg:!0,runInContext:!0},s.skipRearg={add:!0,assign:!0,assignIn:!0,bind:!0,bindKey:!0,concat:!0,difference:!0,divide:!0,eq:!0,gt:!0,gte:!0,isEqual:!0,lt:!0,lte:!0,matchesProperty:!0,merge:!0,multiply:!0,overArgs:!0,partial:!0,partialRight:!0,propertyOf:!0,random:!0,range:!0,rangeRight:!0,subtract:!0,zip:!0,zipObject:!0,zipObjectDeep:!0}},47934:(o,s,i)=>{o.exports={ary:i(64626),assign:i(74733),clone:i(32629),curry:i(49747),forEach:i(83729),isArray:i(56449),isError:i(23546),isFunction:i(1882),isWeakMap:i(47886),iteratee:i(33855),keys:i(88984),rearg:i(84195),toInteger:i(61489),toPath:i(42072)}},56367:(o,s,i)=>{o.exports=i(77731)},79920:(o,s,i)=>{var u=i(73424),_=i(47934);o.exports=function convert(o,s,i){return u(_,o,s,i)}},2874:o=>{o.exports={}},77731:(o,s,i)=>{var u=i(79920)(\"set\",i(63560));u.placeholder=i(2874),o.exports=u},58156:(o,s,i)=>{var u=i(47422);o.exports=function get(o,s,i){var _=null==o?void 0:u(o,s);return void 0===_?i:_}},61448:(o,s,i)=>{var u=i(20426),_=i(49326);o.exports=function has(o,s){return null!=o&&_(o,s,u)}},80631:(o,s,i)=>{var u=i(28077),_=i(49326);o.exports=function hasIn(o,s){return null!=o&&_(o,s,u)}},83488:o=>{o.exports=function identity(o){return o}},72428:(o,s,i)=>{var u=i(27534),_=i(40346),w=Object.prototype,x=w.hasOwnProperty,C=w.propertyIsEnumerable,j=u(function(){return arguments}())?u:function(o){return _(o)&&x.call(o,\"callee\")&&!C.call(o,\"callee\")};o.exports=j},56449:o=>{var s=Array.isArray;o.exports=s},64894:(o,s,i)=>{var u=i(1882),_=i(30294);o.exports=function isArrayLike(o){return null!=o&&_(o.length)&&!u(o)}},83693:(o,s,i)=>{var u=i(64894),_=i(40346);o.exports=function isArrayLikeObject(o){return _(o)&&u(o)}},53812:(o,s,i)=>{var u=i(72552),_=i(40346);o.exports=function isBoolean(o){return!0===o||!1===o||_(o)&&\"[object Boolean]\"==u(o)}},3656:(o,s,i)=>{o=i.nmd(o);var u=i(9325),_=i(89935),w=s&&!s.nodeType&&s,x=w&&o&&!o.nodeType&&o,C=x&&x.exports===w?u.Buffer:void 0,j=(C?C.isBuffer:void 0)||_;o.exports=j},62193:(o,s,i)=>{var u=i(88984),_=i(5861),w=i(72428),x=i(56449),C=i(64894),j=i(3656),L=i(55527),B=i(37167),$=Object.prototype.hasOwnProperty;o.exports=function isEmpty(o){if(null==o)return!0;if(C(o)&&(x(o)||\"string\"==typeof o||\"function\"==typeof o.splice||j(o)||B(o)||w(o)))return!o.length;var s=_(o);if(\"[object Map]\"==s||\"[object Set]\"==s)return!o.size;if(L(o))return!u(o).length;for(var i in o)if($.call(o,i))return!1;return!0}},2404:(o,s,i)=>{var u=i(60270);o.exports=function isEqual(o,s){return u(o,s)}},23546:(o,s,i)=>{var u=i(72552),_=i(40346),w=i(11331);o.exports=function isError(o){if(!_(o))return!1;var s=u(o);return\"[object Error]\"==s||\"[object DOMException]\"==s||\"string\"==typeof o.message&&\"string\"==typeof o.name&&!w(o)}},1882:(o,s,i)=>{var u=i(72552),_=i(23805);o.exports=function isFunction(o){if(!_(o))return!1;var s=u(o);return\"[object Function]\"==s||\"[object GeneratorFunction]\"==s||\"[object AsyncFunction]\"==s||\"[object Proxy]\"==s}},30294:o=>{o.exports=function isLength(o){return\"number\"==typeof o&&o>-1&&o%1==0&&o<=9007199254740991}},87730:(o,s,i)=>{var u=i(29172),_=i(27301),w=i(86009),x=w&&w.isMap,C=x?_(x):u;o.exports=C},5187:o=>{o.exports=function isNull(o){return null===o}},98023:(o,s,i)=>{var u=i(72552),_=i(40346);o.exports=function isNumber(o){return\"number\"==typeof o||_(o)&&\"[object Number]\"==u(o)}},23805:o=>{o.exports=function isObject(o){var s=typeof o;return null!=o&&(\"object\"==s||\"function\"==s)}},40346:o=>{o.exports=function isObjectLike(o){return null!=o&&\"object\"==typeof o}},11331:(o,s,i)=>{var u=i(72552),_=i(28879),w=i(40346),x=Function.prototype,C=Object.prototype,j=x.toString,L=C.hasOwnProperty,B=j.call(Object);o.exports=function isPlainObject(o){if(!w(o)||\"[object Object]\"!=u(o))return!1;var s=_(o);if(null===s)return!0;var i=L.call(s,\"constructor\")&&s.constructor;return\"function\"==typeof i&&i instanceof i&&j.call(i)==B}},38440:(o,s,i)=>{var u=i(16038),_=i(27301),w=i(86009),x=w&&w.isSet,C=x?_(x):u;o.exports=C},85015:(o,s,i)=>{var u=i(72552),_=i(56449),w=i(40346);o.exports=function isString(o){return\"string\"==typeof o||!_(o)&&w(o)&&\"[object String]\"==u(o)}},44394:(o,s,i)=>{var u=i(72552),_=i(40346);o.exports=function isSymbol(o){return\"symbol\"==typeof o||_(o)&&\"[object Symbol]\"==u(o)}},37167:(o,s,i)=>{var u=i(4901),_=i(27301),w=i(86009),x=w&&w.isTypedArray,C=x?_(x):u;o.exports=C},47886:(o,s,i)=>{var u=i(5861),_=i(40346);o.exports=function isWeakMap(o){return _(o)&&\"[object WeakMap]\"==u(o)}},33855:(o,s,i)=>{var u=i(9999),_=i(15389);o.exports=function iteratee(o){return _(\"function\"==typeof o?o:u(o,1))}},95950:(o,s,i)=>{var u=i(70695),_=i(88984),w=i(64894);o.exports=function keys(o){return w(o)?u(o):_(o)}},37241:(o,s,i)=>{var u=i(70695),_=i(72903),w=i(64894);o.exports=function keysIn(o){return w(o)?u(o,!0):_(o)}},68090:o=>{o.exports=function last(o){var s=null==o?0:o.length;return s?o[s-1]:void 0}},50104:(o,s,i)=>{var u=i(53661);function memoize(o,s){if(\"function\"!=typeof o||null!=s&&\"function\"!=typeof s)throw new TypeError(\"Expected a function\");var memoized=function(){var i=arguments,u=s?s.apply(this,i):i[0],_=memoized.cache;if(_.has(u))return _.get(u);var w=o.apply(this,i);return memoized.cache=_.set(u,w)||_,w};return memoized.cache=new(memoize.Cache||u),memoized}memoize.Cache=u,o.exports=memoize},55364:(o,s,i)=>{var u=i(85250),_=i(20999)((function(o,s,i){u(o,s,i)}));o.exports=_},6048:o=>{o.exports=function negate(o){if(\"function\"!=typeof o)throw new TypeError(\"Expected a function\");return function(){var s=arguments;switch(s.length){case 0:return!o.call(this);case 1:return!o.call(this,s[0]);case 2:return!o.call(this,s[0],s[1]);case 3:return!o.call(this,s[0],s[1],s[2])}return!o.apply(this,s)}}},63950:o=>{o.exports=function noop(){}},10124:(o,s,i)=>{var u=i(9325);o.exports=function(){return u.Date.now()}},90179:(o,s,i)=>{var u=i(34932),_=i(9999),w=i(19931),x=i(31769),C=i(21791),j=i(53138),L=i(38816),B=i(83349),$=L((function(o,s){var i={};if(null==o)return i;var L=!1;s=u(s,(function(s){return s=x(s,o),L||(L=s.length>1),s})),C(o,B(o),i),L&&(i=_(i,7,j));for(var $=s.length;$--;)w(i,s[$]);return i}));o.exports=$},50583:(o,s,i)=>{var u=i(47237),_=i(17255),w=i(28586),x=i(77797);o.exports=function property(o){return w(o)?u(x(o)):_(o)}},84195:(o,s,i)=>{var u=i(66977),_=i(38816),w=_((function(o,s){return u(o,256,void 0,void 0,void 0,s)}));o.exports=w},40860:(o,s,i)=>{var u=i(40882),_=i(80909),w=i(15389),x=i(85558),C=i(56449);o.exports=function reduce(o,s,i){var j=C(o)?u:x,L=arguments.length<3;return j(o,w(s,4),i,L,_)}},63560:(o,s,i)=>{var u=i(73170);o.exports=function set(o,s,i){return null==o?o:u(o,s,i)}},42426:(o,s,i)=>{var u=i(14248),_=i(15389),w=i(90916),x=i(56449),C=i(36800);o.exports=function some(o,s,i){var j=x(o)?u:w;return i&&C(o,s,i)&&(s=void 0),j(o,_(s,3))}},63345:o=>{o.exports=function stubArray(){return[]}},89935:o=>{o.exports=function stubFalse(){return!1}},17400:(o,s,i)=>{var u=i(99374),_=1/0;o.exports=function toFinite(o){return o?(o=u(o))===_||o===-1/0?17976931348623157e292*(o<0?-1:1):o==o?o:0:0===o?o:0}},61489:(o,s,i)=>{var u=i(17400);o.exports=function toInteger(o){var s=u(o),i=s%1;return s==s?i?s-i:s:0}},80218:(o,s,i)=>{var u=i(13222);o.exports=function toLower(o){return u(o).toLowerCase()}},99374:(o,s,i)=>{var u=i(54128),_=i(23805),w=i(44394),x=/^[-+]0x[0-9a-f]+$/i,C=/^0b[01]+$/i,j=/^0o[0-7]+$/i,L=parseInt;o.exports=function toNumber(o){if(\"number\"==typeof o)return o;if(w(o))return NaN;if(_(o)){var s=\"function\"==typeof o.valueOf?o.valueOf():o;o=_(s)?s+\"\":s}if(\"string\"!=typeof o)return 0===o?o:+o;o=u(o);var i=C.test(o);return i||j.test(o)?L(o.slice(2),i?2:8):x.test(o)?NaN:+o}},42072:(o,s,i)=>{var u=i(34932),_=i(23007),w=i(56449),x=i(44394),C=i(61802),j=i(77797),L=i(13222);o.exports=function toPath(o){return w(o)?u(o,j):x(o)?[o]:_(C(L(o)))}},69884:(o,s,i)=>{var u=i(21791),_=i(37241);o.exports=function toPlainObject(o){return u(o,_(o))}},13222:(o,s,i)=>{var u=i(77556);o.exports=function toString(o){return null==o?\"\":u(o)}},55808:(o,s,i)=>{var u=i(12507)(\"toUpperCase\");o.exports=u},66645:(o,s,i)=>{var u=i(1733),_=i(45434),w=i(13222),x=i(22225);o.exports=function words(o,s,i){return o=w(o),void 0===(s=i?void 0:s)?_(o)?x(o):u(o):o.match(s)||[]}},53758:(o,s,i)=>{var u=i(30980),_=i(56017),w=i(94033),x=i(56449),C=i(40346),j=i(80257),L=Object.prototype.hasOwnProperty;function lodash(o){if(C(o)&&!x(o)&&!(o instanceof u)){if(o instanceof _)return o;if(L.call(o,\"__wrapped__\"))return j(o)}return new _(o)}lodash.prototype=w.prototype,lodash.prototype.constructor=lodash,o.exports=lodash},47248:(o,s,i)=>{var u=i(16547),_=i(51234);o.exports=function zipObject(o,s){return _(o||[],s||[],u)}},43768:(o,s,i)=>{\"use strict\";var u=i(45981),_=i(85587);s.highlight=highlight,s.highlightAuto=function highlightAuto(o,s){var i,x,C,j,L=s||{},B=L.subset||u.listLanguages(),$=L.prefix,V=B.length,U=-1;null==$&&($=w);if(\"string\"!=typeof o)throw _(\"Expected `string` for value, got `%s`\",o);x={relevance:0,language:null,value:[]},i={relevance:0,language:null,value:[]};for(;++Ux.relevance&&(x=C),C.relevance>i.relevance&&(x=i,i=C));x.language&&(i.secondBest=x);return i},s.registerLanguage=function registerLanguage(o,s){u.registerLanguage(o,s)},s.listLanguages=function listLanguages(){return u.listLanguages()},s.registerAlias=function registerAlias(o,s){var i,_=o;s&&((_={})[o]=s);for(i in _)u.registerAliases(_[i],{languageName:i})},Emitter.prototype.addText=function text(o){var s,i,u=this.stack;if(\"\"===o)return;s=u[u.length-1],(i=s.children[s.children.length-1])&&\"text\"===i.type?i.value+=o:s.children.push({type:\"text\",value:o})},Emitter.prototype.addKeyword=function addKeyword(o,s){this.openNode(s),this.addText(o),this.closeNode()},Emitter.prototype.addSublanguage=function addSublanguage(o,s){var i=this.stack,u=i[i.length-1],_=o.rootNode.children,w=s?{type:\"element\",tagName:\"span\",properties:{className:[s]},children:_}:_;u.children=u.children.concat(w)},Emitter.prototype.openNode=function open(o){var s=this.stack,i=this.options.classPrefix+o,u=s[s.length-1],_={type:\"element\",tagName:\"span\",properties:{className:[i]},children:[]};u.children.push(_),s.push(_)},Emitter.prototype.closeNode=function close(){this.stack.pop()},Emitter.prototype.closeAllNodes=noop,Emitter.prototype.finalize=noop,Emitter.prototype.toHTML=function toHtmlNoop(){return\"\"};var w=\"hljs-\";function highlight(o,s,i){var x,C=u.configure({}),j=(i||{}).prefix;if(\"string\"!=typeof o)throw _(\"Expected `string` for name, got `%s`\",o);if(!u.getLanguage(o))throw _(\"Unknown language: `%s` is not registered\",o);if(\"string\"!=typeof s)throw _(\"Expected `string` for value, got `%s`\",s);if(null==j&&(j=w),u.configure({__emitter:Emitter,classPrefix:j}),x=u.highlight(s,{language:o,ignoreIllegals:!0}),u.configure(C||{}),x.errorRaised)throw x.errorRaised;return{relevance:x.relevance,language:x.language,value:x.emitter.rootNode.children}}function Emitter(o){this.options=o,this.rootNode={children:[]},this.stack=[this.rootNode]}function noop(){}},92340:(o,s,i)=>{const u=i(6048);function coerceElementMatchingCallback(o){return\"string\"==typeof o?s=>s.element===o:o.constructor&&o.extend?s=>s instanceof o:o}class ArraySlice{constructor(o){this.elements=o||[]}toValue(){return this.elements.map((o=>o.toValue()))}map(o,s){return this.elements.map(o,s)}flatMap(o,s){return this.map(o,s).reduce(((o,s)=>o.concat(s)),[])}compactMap(o,s){const i=[];return this.forEach((u=>{const _=o.bind(s)(u);_&&i.push(_)})),i}filter(o,s){return o=coerceElementMatchingCallback(o),new ArraySlice(this.elements.filter(o,s))}reject(o,s){return o=coerceElementMatchingCallback(o),new ArraySlice(this.elements.filter(u(o),s))}find(o,s){return o=coerceElementMatchingCallback(o),this.elements.find(o,s)}forEach(o,s){this.elements.forEach(o,s)}reduce(o,s){return this.elements.reduce(o,s)}includes(o){return this.elements.some((s=>s.equals(o)))}shift(){return this.elements.shift()}unshift(o){this.elements.unshift(this.refract(o))}push(o){return this.elements.push(this.refract(o)),this}add(o){this.push(o)}get(o){return this.elements[o]}getValue(o){const s=this.elements[o];if(s)return s.toValue()}get length(){return this.elements.length}get isEmpty(){return 0===this.elements.length}get first(){return this.elements[0]}}\"undefined\"!=typeof Symbol&&(ArraySlice.prototype[Symbol.iterator]=function symbol(){return this.elements[Symbol.iterator]()}),o.exports=ArraySlice},55973:o=>{class KeyValuePair{constructor(o,s){this.key=o,this.value=s}clone(){const o=new KeyValuePair;return this.key&&(o.key=this.key.clone()),this.value&&(o.value=this.value.clone()),o}}o.exports=KeyValuePair},3110:(o,s,i)=>{const u=i(5187),_=i(85015),w=i(98023),x=i(53812),C=i(23805),j=i(85105),L=i(86804);class Namespace{constructor(o){this.elementMap={},this.elementDetection=[],this.Element=L.Element,this.KeyValuePair=L.KeyValuePair,o&&o.noDefault||this.useDefault(),this._attributeElementKeys=[],this._attributeElementArrayKeys=[]}use(o){return o.namespace&&o.namespace({base:this}),o.load&&o.load({base:this}),this}useDefault(){return this.register(\"null\",L.NullElement).register(\"string\",L.StringElement).register(\"number\",L.NumberElement).register(\"boolean\",L.BooleanElement).register(\"array\",L.ArrayElement).register(\"object\",L.ObjectElement).register(\"member\",L.MemberElement).register(\"ref\",L.RefElement).register(\"link\",L.LinkElement),this.detect(u,L.NullElement,!1).detect(_,L.StringElement,!1).detect(w,L.NumberElement,!1).detect(x,L.BooleanElement,!1).detect(Array.isArray,L.ArrayElement,!1).detect(C,L.ObjectElement,!1),this}register(o,s){return this._elements=void 0,this.elementMap[o]=s,this}unregister(o){return this._elements=void 0,delete this.elementMap[o],this}detect(o,s,i){return void 0===i||i?this.elementDetection.unshift([o,s]):this.elementDetection.push([o,s]),this}toElement(o){if(o instanceof this.Element)return o;let s;for(let i=0;i{const s=o[0].toUpperCase()+o.substr(1);this._elements[s]=this.elementMap[o]}))),this._elements}get serialiser(){return new j(this)}}j.prototype.Namespace=Namespace,o.exports=Namespace},10866:(o,s,i)=>{const u=i(6048),_=i(92340);class ObjectSlice extends _{map(o,s){return this.elements.map((i=>o.bind(s)(i.value,i.key,i)))}filter(o,s){return new ObjectSlice(this.elements.filter((i=>o.bind(s)(i.value,i.key,i))))}reject(o,s){return this.filter(u(o.bind(s)))}forEach(o,s){return this.elements.forEach(((i,u)=>{o.bind(s)(i.value,i.key,i,u)}))}keys(){return this.map(((o,s)=>s.toValue()))}values(){return this.map((o=>o.toValue()))}}o.exports=ObjectSlice},86804:(o,s,i)=>{const u=i(10316),_=i(41067),w=i(71167),x=i(40239),C=i(12242),j=i(6233),L=i(87726),B=i(61045),$=i(86303),V=i(14540),U=i(92340),z=i(10866),Y=i(55973);function refract(o){if(o instanceof u)return o;if(\"string\"==typeof o)return new w(o);if(\"number\"==typeof o)return new x(o);if(\"boolean\"==typeof o)return new C(o);if(null===o)return new _;if(Array.isArray(o))return new j(o.map(refract));if(\"object\"==typeof o){return new B(o)}return o}u.prototype.ObjectElement=B,u.prototype.RefElement=V,u.prototype.MemberElement=L,u.prototype.refract=refract,U.prototype.refract=refract,o.exports={Element:u,NullElement:_,StringElement:w,NumberElement:x,BooleanElement:C,ArrayElement:j,MemberElement:L,ObjectElement:B,LinkElement:$,RefElement:V,refract,ArraySlice:U,ObjectSlice:z,KeyValuePair:Y}},86303:(o,s,i)=>{const u=i(10316);o.exports=class LinkElement extends u{constructor(o,s,i){super(o||[],s,i),this.element=\"link\"}get relation(){return this.attributes.get(\"relation\")}set relation(o){this.attributes.set(\"relation\",o)}get href(){return this.attributes.get(\"href\")}set href(o){this.attributes.set(\"href\",o)}}},14540:(o,s,i)=>{const u=i(10316);o.exports=class RefElement extends u{constructor(o,s,i){super(o||[],s,i),this.element=\"ref\",this.path||(this.path=\"element\")}get path(){return this.attributes.get(\"path\")}set path(o){this.attributes.set(\"path\",o)}}},34035:(o,s,i)=>{const u=i(3110),_=i(86804);s.g$=u,s.KeyValuePair=i(55973),s.G6=_.ArraySlice,s.ot=_.ObjectSlice,s.Hg=_.Element,s.Om=_.StringElement,s.kT=_.NumberElement,s.bd=_.BooleanElement,s.Os=_.NullElement,s.wE=_.ArrayElement,s.Sh=_.ObjectElement,s.Pr=_.MemberElement,s.sI=_.RefElement,s.Ft=_.LinkElement,s.e=_.refract,i(85105),i(75147)},6233:(o,s,i)=>{const u=i(6048),_=i(10316),w=i(92340);class ArrayElement extends _{constructor(o,s,i){super(o||[],s,i),this.element=\"array\"}primitive(){return\"array\"}get(o){return this.content[o]}getValue(o){const s=this.get(o);if(s)return s.toValue()}getIndex(o){return this.content[o]}set(o,s){return this.content[o]=this.refract(s),this}remove(o){const s=this.content.splice(o,1);return s.length?s[0]:null}map(o,s){return this.content.map(o,s)}flatMap(o,s){return this.map(o,s).reduce(((o,s)=>o.concat(s)),[])}compactMap(o,s){const i=[];return this.forEach((u=>{const _=o.bind(s)(u);_&&i.push(_)})),i}filter(o,s){return new w(this.content.filter(o,s))}reject(o,s){return this.filter(u(o),s)}reduce(o,s){let i,u;void 0!==s?(i=0,u=this.refract(s)):(i=1,u=\"object\"===this.primitive()?this.first.value:this.first);for(let s=i;s{o.bind(s)(i,this.refract(u))}))}shift(){return this.content.shift()}unshift(o){this.content.unshift(this.refract(o))}push(o){return this.content.push(this.refract(o)),this}add(o){this.push(o)}findElements(o,s){const i=s||{},u=!!i.recursive,_=void 0===i.results?[]:i.results;return this.forEach(((s,i,w)=>{u&&void 0!==s.findElements&&s.findElements(o,{results:_,recursive:u}),o(s,i,w)&&_.push(s)})),_}find(o){return new w(this.findElements(o,{recursive:!0}))}findByElement(o){return this.find((s=>s.element===o))}findByClass(o){return this.find((s=>s.classes.includes(o)))}getById(o){return this.find((s=>s.id.toValue()===o)).first}includes(o){return this.content.some((s=>s.equals(o)))}contains(o){return this.includes(o)}empty(){return new this.constructor([])}\"fantasy-land/empty\"(){return this.empty()}concat(o){return new this.constructor(this.content.concat(o.content))}\"fantasy-land/concat\"(o){return this.concat(o)}\"fantasy-land/map\"(o){return new this.constructor(this.map(o))}\"fantasy-land/chain\"(o){return this.map((s=>o(s)),this).reduce(((o,s)=>o.concat(s)),this.empty())}\"fantasy-land/filter\"(o){return new this.constructor(this.content.filter(o))}\"fantasy-land/reduce\"(o,s){return this.content.reduce(o,s)}get length(){return this.content.length}get isEmpty(){return 0===this.content.length}get first(){return this.getIndex(0)}get second(){return this.getIndex(1)}get last(){return this.getIndex(this.length-1)}}ArrayElement.empty=function empty(){return new this},ArrayElement[\"fantasy-land/empty\"]=ArrayElement.empty,\"undefined\"!=typeof Symbol&&(ArrayElement.prototype[Symbol.iterator]=function symbol(){return this.content[Symbol.iterator]()}),o.exports=ArrayElement},12242:(o,s,i)=>{const u=i(10316);o.exports=class BooleanElement extends u{constructor(o,s,i){super(o,s,i),this.element=\"boolean\"}primitive(){return\"boolean\"}}},10316:(o,s,i)=>{const u=i(2404),_=i(55973),w=i(92340);class Element{constructor(o,s,i){s&&(this.meta=s),i&&(this.attributes=i),this.content=o}freeze(){Object.isFrozen(this)||(this._meta&&(this.meta.parent=this,this.meta.freeze()),this._attributes&&(this.attributes.parent=this,this.attributes.freeze()),this.children.forEach((o=>{o.parent=this,o.freeze()}),this),this.content&&Array.isArray(this.content)&&Object.freeze(this.content),Object.freeze(this))}primitive(){}clone(){const o=new this.constructor;return o.element=this.element,this.meta.length&&(o._meta=this.meta.clone()),this.attributes.length&&(o._attributes=this.attributes.clone()),this.content?this.content.clone?o.content=this.content.clone():Array.isArray(this.content)?o.content=this.content.map((o=>o.clone())):o.content=this.content:o.content=this.content,o}toValue(){return this.content instanceof Element?this.content.toValue():this.content instanceof _?{key:this.content.key.toValue(),value:this.content.value?this.content.value.toValue():void 0}:this.content&&this.content.map?this.content.map((o=>o.toValue()),this):this.content}toRef(o){if(\"\"===this.id.toValue())throw Error(\"Cannot create reference to an element that does not contain an ID\");const s=new this.RefElement(this.id.toValue());return o&&(s.path=o),s}findRecursive(...o){if(arguments.length>1&&!this.isFrozen)throw new Error(\"Cannot find recursive with multiple element names without first freezing the element. Call `element.freeze()`\");const s=o.pop();let i=new w;const append=(o,s)=>(o.push(s),o),checkElement=(o,i)=>{i.element===s&&o.push(i);const u=i.findRecursive(s);return u&&u.reduce(append,o),i.content instanceof _&&(i.content.key&&checkElement(o,i.content.key),i.content.value&&checkElement(o,i.content.value)),o};return this.content&&(this.content.element&&checkElement(i,this.content),Array.isArray(this.content)&&this.content.reduce(checkElement,i)),o.isEmpty||(i=i.filter((s=>{let i=s.parents.map((o=>o.element));for(const s in o){const u=o[s],_=i.indexOf(u);if(-1===_)return!1;i=i.splice(0,_)}return!0}))),i}set(o){return this.content=o,this}equals(o){return u(this.toValue(),o)}getMetaProperty(o,s){if(!this.meta.hasKey(o)){if(this.isFrozen){const o=this.refract(s);return o.freeze(),o}this.meta.set(o,s)}return this.meta.get(o)}setMetaProperty(o,s){this.meta.set(o,s)}get element(){return this._storedElement||\"element\"}set element(o){this._storedElement=o}get content(){return this._content}set content(o){if(o instanceof Element)this._content=o;else if(o instanceof w)this.content=o.elements;else if(\"string\"==typeof o||\"number\"==typeof o||\"boolean\"==typeof o||\"null\"===o||null==o)this._content=o;else if(o instanceof _)this._content=o;else if(Array.isArray(o))this._content=o.map(this.refract);else{if(\"object\"!=typeof o)throw new Error(\"Cannot set content to given value\");this._content=Object.keys(o).map((s=>new this.MemberElement(s,o[s])))}}get meta(){if(!this._meta){if(this.isFrozen){const o=new this.ObjectElement;return o.freeze(),o}this._meta=new this.ObjectElement}return this._meta}set meta(o){o instanceof this.ObjectElement?this._meta=o:this.meta.set(o||{})}get attributes(){if(!this._attributes){if(this.isFrozen){const o=new this.ObjectElement;return o.freeze(),o}this._attributes=new this.ObjectElement}return this._attributes}set attributes(o){o instanceof this.ObjectElement?this._attributes=o:this.attributes.set(o||{})}get id(){return this.getMetaProperty(\"id\",\"\")}set id(o){this.setMetaProperty(\"id\",o)}get classes(){return this.getMetaProperty(\"classes\",[])}set classes(o){this.setMetaProperty(\"classes\",o)}get title(){return this.getMetaProperty(\"title\",\"\")}set title(o){this.setMetaProperty(\"title\",o)}get description(){return this.getMetaProperty(\"description\",\"\")}set description(o){this.setMetaProperty(\"description\",o)}get links(){return this.getMetaProperty(\"links\",[])}set links(o){this.setMetaProperty(\"links\",o)}get isFrozen(){return Object.isFrozen(this)}get parents(){let{parent:o}=this;const s=new w;for(;o;)s.push(o),o=o.parent;return s}get children(){if(Array.isArray(this.content))return new w(this.content);if(this.content instanceof _){const o=new w([this.content.key]);return this.content.value&&o.push(this.content.value),o}return this.content instanceof Element?new w([this.content]):new w}get recursiveChildren(){const o=new w;return this.children.forEach((s=>{o.push(s),s.recursiveChildren.forEach((s=>{o.push(s)}))})),o}}o.exports=Element},87726:(o,s,i)=>{const u=i(55973),_=i(10316);o.exports=class MemberElement extends _{constructor(o,s,i,_){super(new u,i,_),this.element=\"member\",this.key=o,this.value=s}get key(){return this.content.key}set key(o){this.content.key=this.refract(o)}get value(){return this.content.value}set value(o){this.content.value=this.refract(o)}}},41067:(o,s,i)=>{const u=i(10316);o.exports=class NullElement extends u{constructor(o,s,i){super(o||null,s,i),this.element=\"null\"}primitive(){return\"null\"}set(){return new Error(\"Cannot set the value of null\")}}},40239:(o,s,i)=>{const u=i(10316);o.exports=class NumberElement extends u{constructor(o,s,i){super(o,s,i),this.element=\"number\"}primitive(){return\"number\"}}},61045:(o,s,i)=>{const u=i(6048),_=i(23805),w=i(6233),x=i(87726),C=i(10866);o.exports=class ObjectElement extends w{constructor(o,s,i){super(o||[],s,i),this.element=\"object\"}primitive(){return\"object\"}toValue(){return this.content.reduce(((o,s)=>(o[s.key.toValue()]=s.value?s.value.toValue():void 0,o)),{})}get(o){const s=this.getMember(o);if(s)return s.value}getMember(o){if(void 0!==o)return this.content.find((s=>s.key.toValue()===o))}remove(o){let s=null;return this.content=this.content.filter((i=>i.key.toValue()!==o||(s=i,!1))),s}getKey(o){const s=this.getMember(o);if(s)return s.key}set(o,s){if(_(o))return Object.keys(o).forEach((s=>{this.set(s,o[s])})),this;const i=o,u=this.getMember(i);return u?u.value=s:this.content.push(new x(i,s)),this}keys(){return this.content.map((o=>o.key.toValue()))}values(){return this.content.map((o=>o.value.toValue()))}hasKey(o){return this.content.some((s=>s.key.equals(o)))}items(){return this.content.map((o=>[o.key.toValue(),o.value.toValue()]))}map(o,s){return this.content.map((i=>o.bind(s)(i.value,i.key,i)))}compactMap(o,s){const i=[];return this.forEach(((u,_,w)=>{const x=o.bind(s)(u,_,w);x&&i.push(x)})),i}filter(o,s){return new C(this.content).filter(o,s)}reject(o,s){return this.filter(u(o),s)}forEach(o,s){return this.content.forEach((i=>o.bind(s)(i.value,i.key,i)))}}},71167:(o,s,i)=>{const u=i(10316);o.exports=class StringElement extends u{constructor(o,s,i){super(o,s,i),this.element=\"string\"}primitive(){return\"string\"}get length(){return this.content.length}}},75147:(o,s,i)=>{const u=i(85105);o.exports=class JSON06Serialiser extends u{serialise(o){if(!(o instanceof this.namespace.elements.Element))throw new TypeError(`Given element \\`${o}\\` is not an Element instance`);let s;o._attributes&&o.attributes.get(\"variable\")&&(s=o.attributes.get(\"variable\"));const i={element:o.element};o._meta&&o._meta.length>0&&(i.meta=this.serialiseObject(o.meta));const u=\"enum\"===o.element||-1!==o.attributes.keys().indexOf(\"enumerations\");if(u){const s=this.enumSerialiseAttributes(o);s&&(i.attributes=s)}else if(o._attributes&&o._attributes.length>0){let{attributes:u}=o;u.get(\"metadata\")&&(u=u.clone(),u.set(\"meta\",u.get(\"metadata\")),u.remove(\"metadata\")),\"member\"===o.element&&s&&(u=u.clone(),u.remove(\"variable\")),u.length>0&&(i.attributes=this.serialiseObject(u))}if(u)i.content=this.enumSerialiseContent(o,i);else if(this[`${o.element}SerialiseContent`])i.content=this[`${o.element}SerialiseContent`](o,i);else if(void 0!==o.content){let u;s&&o.content.key?(u=o.content.clone(),u.key.attributes.set(\"variable\",s),u=this.serialiseContent(u)):u=this.serialiseContent(o.content),this.shouldSerialiseContent(o,u)&&(i.content=u)}else this.shouldSerialiseContent(o,o.content)&&o instanceof this.namespace.elements.Array&&(i.content=[]);return i}shouldSerialiseContent(o,s){return\"parseResult\"===o.element||\"httpRequest\"===o.element||\"httpResponse\"===o.element||\"category\"===o.element||\"link\"===o.element||void 0!==s&&(!Array.isArray(s)||0!==s.length)}refSerialiseContent(o,s){return delete s.attributes,{href:o.toValue(),path:o.path.toValue()}}sourceMapSerialiseContent(o){return o.toValue()}dataStructureSerialiseContent(o){return[this.serialiseContent(o.content)]}enumSerialiseAttributes(o){const s=o.attributes.clone(),i=s.remove(\"enumerations\")||new this.namespace.elements.Array([]),u=s.get(\"default\");let _=s.get(\"samples\")||new this.namespace.elements.Array([]);if(u&&u.content&&(u.content.attributes&&u.content.attributes.remove(\"typeAttributes\"),s.set(\"default\",new this.namespace.elements.Array([u.content]))),_.forEach((o=>{o.content&&o.content.element&&o.content.attributes.remove(\"typeAttributes\")})),o.content&&0!==i.length&&_.unshift(o.content),_=_.map((o=>o instanceof this.namespace.elements.Array?[o]:new this.namespace.elements.Array([o.content]))),_.length&&s.set(\"samples\",_),s.length>0)return this.serialiseObject(s)}enumSerialiseContent(o){if(o._attributes){const s=o.attributes.get(\"enumerations\");if(s&&s.length>0)return s.content.map((o=>{const s=o.clone();return s.attributes.remove(\"typeAttributes\"),this.serialise(s)}))}if(o.content){const s=o.content.clone();return s.attributes.remove(\"typeAttributes\"),[this.serialise(s)]}return[]}deserialise(o){if(\"string\"==typeof o)return new this.namespace.elements.String(o);if(\"number\"==typeof o)return new this.namespace.elements.Number(o);if(\"boolean\"==typeof o)return new this.namespace.elements.Boolean(o);if(null===o)return new this.namespace.elements.Null;if(Array.isArray(o))return new this.namespace.elements.Array(o.map(this.deserialise,this));const s=this.namespace.getElementClass(o.element),i=new s;i.element!==o.element&&(i.element=o.element),o.meta&&this.deserialiseObject(o.meta,i.meta),o.attributes&&this.deserialiseObject(o.attributes,i.attributes);const u=this.deserialiseContent(o.content);if(void 0===u&&null!==i.content||(i.content=u),\"enum\"===i.element){i.content&&i.attributes.set(\"enumerations\",i.content);let o=i.attributes.get(\"samples\");if(i.attributes.remove(\"samples\"),o){const u=o;o=new this.namespace.elements.Array,u.forEach((u=>{u.forEach((u=>{const _=new s(u);_.element=i.element,o.push(_)}))}));const _=o.shift();i.content=_?_.content:void 0,i.attributes.set(\"samples\",o)}else i.content=void 0;let u=i.attributes.get(\"default\");if(u&&u.length>0){u=u.get(0);const o=new s(u);o.element=i.element,i.attributes.set(\"default\",o)}}else if(\"dataStructure\"===i.element&&Array.isArray(i.content))[i.content]=i.content;else if(\"category\"===i.element){const o=i.attributes.get(\"meta\");o&&(i.attributes.set(\"metadata\",o),i.attributes.remove(\"meta\"))}else\"member\"===i.element&&i.key&&i.key._attributes&&i.key._attributes.getValue(\"variable\")&&(i.attributes.set(\"variable\",i.key.attributes.get(\"variable\")),i.key.attributes.remove(\"variable\"));return i}serialiseContent(o){if(o instanceof this.namespace.elements.Element)return this.serialise(o);if(o instanceof this.namespace.KeyValuePair){const s={key:this.serialise(o.key)};return o.value&&(s.value=this.serialise(o.value)),s}return o&&o.map?o.map(this.serialise,this):o}deserialiseContent(o){if(o){if(o.element)return this.deserialise(o);if(o.key){const s=new this.namespace.KeyValuePair(this.deserialise(o.key));return o.value&&(s.value=this.deserialise(o.value)),s}if(o.map)return o.map(this.deserialise,this)}return o}shouldRefract(o){return!!(o._attributes&&o.attributes.keys().length||o._meta&&o.meta.keys().length)||\"enum\"!==o.element&&(o.element!==o.primitive()||\"member\"===o.element)}convertKeyToRefract(o,s){return this.shouldRefract(s)?this.serialise(s):\"enum\"===s.element?this.serialiseEnum(s):\"array\"===s.element?s.map((s=>this.shouldRefract(s)||\"default\"===o?this.serialise(s):\"array\"===s.element||\"object\"===s.element||\"enum\"===s.element?s.children.map((o=>this.serialise(o))):s.toValue())):\"object\"===s.element?(s.content||[]).map(this.serialise,this):s.toValue()}serialiseEnum(o){return o.children.map((o=>this.serialise(o)))}serialiseObject(o){const s={};return o.forEach(((o,i)=>{if(o){const u=i.toValue();s[u]=this.convertKeyToRefract(u,o)}})),s}deserialiseObject(o,s){Object.keys(o).forEach((i=>{s.set(i,this.deserialise(o[i]))}))}}},85105:o=>{o.exports=class JSONSerialiser{constructor(o){this.namespace=o||new this.Namespace}serialise(o){if(!(o instanceof this.namespace.elements.Element))throw new TypeError(`Given element \\`${o}\\` is not an Element instance`);const s={element:o.element};o._meta&&o._meta.length>0&&(s.meta=this.serialiseObject(o.meta)),o._attributes&&o._attributes.length>0&&(s.attributes=this.serialiseObject(o.attributes));const i=this.serialiseContent(o.content);return void 0!==i&&(s.content=i),s}deserialise(o){if(!o.element)throw new Error(\"Given value is not an object containing an element name\");const s=new(this.namespace.getElementClass(o.element));s.element!==o.element&&(s.element=o.element),o.meta&&this.deserialiseObject(o.meta,s.meta),o.attributes&&this.deserialiseObject(o.attributes,s.attributes);const i=this.deserialiseContent(o.content);return void 0===i&&null!==s.content||(s.content=i),s}serialiseContent(o){if(o instanceof this.namespace.elements.Element)return this.serialise(o);if(o instanceof this.namespace.KeyValuePair){const s={key:this.serialise(o.key)};return o.value&&(s.value=this.serialise(o.value)),s}if(o&&o.map){if(0===o.length)return;return o.map(this.serialise,this)}return o}deserialiseContent(o){if(o){if(o.element)return this.deserialise(o);if(o.key){const s=new this.namespace.KeyValuePair(this.deserialise(o.key));return o.value&&(s.value=this.deserialise(o.value)),s}if(o.map)return o.map(this.deserialise,this)}return o}serialiseObject(o){const s={};if(o.forEach(((o,i)=>{o&&(s[i.toValue()]=this.serialise(o))})),0!==Object.keys(s).length)return s}deserialiseObject(o,s){Object.keys(o).forEach((i=>{s.set(i,this.deserialise(o[i]))}))}}},58859:(o,s,i)=>{var u=\"function\"==typeof Map&&Map.prototype,_=Object.getOwnPropertyDescriptor&&u?Object.getOwnPropertyDescriptor(Map.prototype,\"size\"):null,w=u&&_&&\"function\"==typeof _.get?_.get:null,x=u&&Map.prototype.forEach,C=\"function\"==typeof Set&&Set.prototype,j=Object.getOwnPropertyDescriptor&&C?Object.getOwnPropertyDescriptor(Set.prototype,\"size\"):null,L=C&&j&&\"function\"==typeof j.get?j.get:null,B=C&&Set.prototype.forEach,$=\"function\"==typeof WeakMap&&WeakMap.prototype?WeakMap.prototype.has:null,V=\"function\"==typeof WeakSet&&WeakSet.prototype?WeakSet.prototype.has:null,U=\"function\"==typeof WeakRef&&WeakRef.prototype?WeakRef.prototype.deref:null,z=Boolean.prototype.valueOf,Y=Object.prototype.toString,Z=Function.prototype.toString,ee=String.prototype.match,ie=String.prototype.slice,ae=String.prototype.replace,ce=String.prototype.toUpperCase,le=String.prototype.toLowerCase,pe=RegExp.prototype.test,de=Array.prototype.concat,fe=Array.prototype.join,ye=Array.prototype.slice,be=Math.floor,_e=\"function\"==typeof BigInt?BigInt.prototype.valueOf:null,we=Object.getOwnPropertySymbols,Se=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?Symbol.prototype.toString:null,xe=\"function\"==typeof Symbol&&\"object\"==typeof Symbol.iterator,Pe=\"function\"==typeof Symbol&&Symbol.toStringTag&&(typeof Symbol.toStringTag===xe||\"symbol\")?Symbol.toStringTag:null,Te=Object.prototype.propertyIsEnumerable,Re=(\"function\"==typeof Reflect?Reflect.getPrototypeOf:Object.getPrototypeOf)||([].__proto__===Array.prototype?function(o){return o.__proto__}:null);function addNumericSeparator(o,s){if(o===1/0||o===-1/0||o!=o||o&&o>-1e3&&o<1e3||pe.call(/e/,s))return s;var i=/[0-9](?=(?:[0-9]{3})+(?![0-9]))/g;if(\"number\"==typeof o){var u=o<0?-be(-o):be(o);if(u!==o){var _=String(u),w=ie.call(s,_.length+1);return ae.call(_,i,\"$&_\")+\".\"+ae.call(ae.call(w,/([0-9]{3})/g,\"$&_\"),/_$/,\"\")}}return ae.call(s,i,\"$&_\")}var qe=i(42634),$e=qe.custom,ze=isSymbol($e)?$e:null;function wrapQuotes(o,s,i){var u=\"double\"===(i.quoteStyle||s)?'\"':\"'\";return u+o+u}function quote(o){return ae.call(String(o),/\"/g,\""\")}function isArray(o){return!(\"[object Array]\"!==toStr(o)||Pe&&\"object\"==typeof o&&Pe in o)}function isRegExp(o){return!(\"[object RegExp]\"!==toStr(o)||Pe&&\"object\"==typeof o&&Pe in o)}function isSymbol(o){if(xe)return o&&\"object\"==typeof o&&o instanceof Symbol;if(\"symbol\"==typeof o)return!0;if(!o||\"object\"!=typeof o||!Se)return!1;try{return Se.call(o),!0}catch(o){}return!1}o.exports=function inspect_(o,s,u,_){var C=s||{};if(has(C,\"quoteStyle\")&&\"single\"!==C.quoteStyle&&\"double\"!==C.quoteStyle)throw new TypeError('option \"quoteStyle\" must be \"single\" or \"double\"');if(has(C,\"maxStringLength\")&&(\"number\"==typeof C.maxStringLength?C.maxStringLength<0&&C.maxStringLength!==1/0:null!==C.maxStringLength))throw new TypeError('option \"maxStringLength\", if provided, must be a positive integer, Infinity, or `null`');var j=!has(C,\"customInspect\")||C.customInspect;if(\"boolean\"!=typeof j&&\"symbol\"!==j)throw new TypeError(\"option \\\"customInspect\\\", if provided, must be `true`, `false`, or `'symbol'`\");if(has(C,\"indent\")&&null!==C.indent&&\"\\t\"!==C.indent&&!(parseInt(C.indent,10)===C.indent&&C.indent>0))throw new TypeError('option \"indent\" must be \"\\\\t\", an integer > 0, or `null`');if(has(C,\"numericSeparator\")&&\"boolean\"!=typeof C.numericSeparator)throw new TypeError('option \"numericSeparator\", if provided, must be `true` or `false`');var Y=C.numericSeparator;if(void 0===o)return\"undefined\";if(null===o)return\"null\";if(\"boolean\"==typeof o)return o?\"true\":\"false\";if(\"string\"==typeof o)return inspectString(o,C);if(\"number\"==typeof o){if(0===o)return 1/0/o>0?\"0\":\"-0\";var ce=String(o);return Y?addNumericSeparator(o,ce):ce}if(\"bigint\"==typeof o){var pe=String(o)+\"n\";return Y?addNumericSeparator(o,pe):pe}var be=void 0===C.depth?5:C.depth;if(void 0===u&&(u=0),u>=be&&be>0&&\"object\"==typeof o)return isArray(o)?\"[Array]\":\"[Object]\";var we=function getIndent(o,s){var i;if(\"\\t\"===o.indent)i=\"\\t\";else{if(!(\"number\"==typeof o.indent&&o.indent>0))return null;i=fe.call(Array(o.indent+1),\" \")}return{base:i,prev:fe.call(Array(s+1),i)}}(C,u);if(void 0===_)_=[];else if(indexOf(_,o)>=0)return\"[Circular]\";function inspect(o,s,i){if(s&&(_=ye.call(_)).push(s),i){var w={depth:C.depth};return has(C,\"quoteStyle\")&&(w.quoteStyle=C.quoteStyle),inspect_(o,w,u+1,_)}return inspect_(o,C,u+1,_)}if(\"function\"==typeof o&&!isRegExp(o)){var $e=function nameOf(o){if(o.name)return o.name;var s=ee.call(Z.call(o),/^function\\s*([\\w$]+)/);if(s)return s[1];return null}(o),We=arrObjKeys(o,inspect);return\"[Function\"+($e?\": \"+$e:\" (anonymous)\")+\"]\"+(We.length>0?\" { \"+fe.call(We,\", \")+\" }\":\"\")}if(isSymbol(o)){var He=xe?ae.call(String(o),/^(Symbol\\(.*\\))_[^)]*$/,\"$1\"):Se.call(o);return\"object\"!=typeof o||xe?He:markBoxed(He)}if(function isElement(o){if(!o||\"object\"!=typeof o)return!1;if(\"undefined\"!=typeof HTMLElement&&o instanceof HTMLElement)return!0;return\"string\"==typeof o.nodeName&&\"function\"==typeof o.getAttribute}(o)){for(var Ye=\"<\"+le.call(String(o.nodeName)),Xe=o.attributes||[],Qe=0;Qe\",o.childNodes&&o.childNodes.length&&(Ye+=\"...\"),Ye+=\"\"}if(isArray(o)){if(0===o.length)return\"[]\";var et=arrObjKeys(o,inspect);return we&&!function singleLineValues(o){for(var s=0;s=0)return!1;return!0}(et)?\"[\"+indentedJoin(et,we)+\"]\":\"[ \"+fe.call(et,\", \")+\" ]\"}if(function isError(o){return!(\"[object Error]\"!==toStr(o)||Pe&&\"object\"==typeof o&&Pe in o)}(o)){var tt=arrObjKeys(o,inspect);return\"cause\"in Error.prototype||!(\"cause\"in o)||Te.call(o,\"cause\")?0===tt.length?\"[\"+String(o)+\"]\":\"{ [\"+String(o)+\"] \"+fe.call(tt,\", \")+\" }\":\"{ [\"+String(o)+\"] \"+fe.call(de.call(\"[cause]: \"+inspect(o.cause),tt),\", \")+\" }\"}if(\"object\"==typeof o&&j){if(ze&&\"function\"==typeof o[ze]&&qe)return qe(o,{depth:be-u});if(\"symbol\"!==j&&\"function\"==typeof o.inspect)return o.inspect()}if(function isMap(o){if(!w||!o||\"object\"!=typeof o)return!1;try{w.call(o);try{L.call(o)}catch(o){return!0}return o instanceof Map}catch(o){}return!1}(o)){var rt=[];return x&&x.call(o,(function(s,i){rt.push(inspect(i,o,!0)+\" => \"+inspect(s,o))})),collectionOf(\"Map\",w.call(o),rt,we)}if(function isSet(o){if(!L||!o||\"object\"!=typeof o)return!1;try{L.call(o);try{w.call(o)}catch(o){return!0}return o instanceof Set}catch(o){}return!1}(o)){var nt=[];return B&&B.call(o,(function(s){nt.push(inspect(s,o))})),collectionOf(\"Set\",L.call(o),nt,we)}if(function isWeakMap(o){if(!$||!o||\"object\"!=typeof o)return!1;try{$.call(o,$);try{V.call(o,V)}catch(o){return!0}return o instanceof WeakMap}catch(o){}return!1}(o))return weakCollectionOf(\"WeakMap\");if(function isWeakSet(o){if(!V||!o||\"object\"!=typeof o)return!1;try{V.call(o,V);try{$.call(o,$)}catch(o){return!0}return o instanceof WeakSet}catch(o){}return!1}(o))return weakCollectionOf(\"WeakSet\");if(function isWeakRef(o){if(!U||!o||\"object\"!=typeof o)return!1;try{return U.call(o),!0}catch(o){}return!1}(o))return weakCollectionOf(\"WeakRef\");if(function isNumber(o){return!(\"[object Number]\"!==toStr(o)||Pe&&\"object\"==typeof o&&Pe in o)}(o))return markBoxed(inspect(Number(o)));if(function isBigInt(o){if(!o||\"object\"!=typeof o||!_e)return!1;try{return _e.call(o),!0}catch(o){}return!1}(o))return markBoxed(inspect(_e.call(o)));if(function isBoolean(o){return!(\"[object Boolean]\"!==toStr(o)||Pe&&\"object\"==typeof o&&Pe in o)}(o))return markBoxed(z.call(o));if(function isString(o){return!(\"[object String]\"!==toStr(o)||Pe&&\"object\"==typeof o&&Pe in o)}(o))return markBoxed(inspect(String(o)));if(\"undefined\"!=typeof window&&o===window)return\"{ [object Window] }\";if(o===i.g)return\"{ [object globalThis] }\";if(!function isDate(o){return!(\"[object Date]\"!==toStr(o)||Pe&&\"object\"==typeof o&&Pe in o)}(o)&&!isRegExp(o)){var ot=arrObjKeys(o,inspect),st=Re?Re(o)===Object.prototype:o instanceof Object||o.constructor===Object,it=o instanceof Object?\"\":\"null prototype\",at=!st&&Pe&&Object(o)===o&&Pe in o?ie.call(toStr(o),8,-1):it?\"Object\":\"\",ct=(st||\"function\"!=typeof o.constructor?\"\":o.constructor.name?o.constructor.name+\" \":\"\")+(at||it?\"[\"+fe.call(de.call([],at||[],it||[]),\": \")+\"] \":\"\");return 0===ot.length?ct+\"{}\":we?ct+\"{\"+indentedJoin(ot,we)+\"}\":ct+\"{ \"+fe.call(ot,\", \")+\" }\"}return String(o)};var We=Object.prototype.hasOwnProperty||function(o){return o in this};function has(o,s){return We.call(o,s)}function toStr(o){return Y.call(o)}function indexOf(o,s){if(o.indexOf)return o.indexOf(s);for(var i=0,u=o.length;is.maxStringLength){var i=o.length-s.maxStringLength,u=\"... \"+i+\" more character\"+(i>1?\"s\":\"\");return inspectString(ie.call(o,0,s.maxStringLength),s)+u}return wrapQuotes(ae.call(ae.call(o,/(['\\\\])/g,\"\\\\$1\"),/[\\x00-\\x1f]/g,lowbyte),\"single\",s)}function lowbyte(o){var s=o.charCodeAt(0),i={8:\"b\",9:\"t\",10:\"n\",12:\"f\",13:\"r\"}[s];return i?\"\\\\\"+i:\"\\\\x\"+(s<16?\"0\":\"\")+ce.call(s.toString(16))}function markBoxed(o){return\"Object(\"+o+\")\"}function weakCollectionOf(o){return o+\" { ? }\"}function collectionOf(o,s,i,u){return o+\" (\"+s+\") {\"+(u?indentedJoin(i,u):fe.call(i,\", \"))+\"}\"}function indentedJoin(o,s){if(0===o.length)return\"\";var i=\"\\n\"+s.prev+s.base;return i+fe.call(o,\",\"+i)+\"\\n\"+s.prev}function arrObjKeys(o,s){var i=isArray(o),u=[];if(i){u.length=o.length;for(var _=0;_{var s,i,u=o.exports={};function defaultSetTimout(){throw new Error(\"setTimeout has not been defined\")}function defaultClearTimeout(){throw new Error(\"clearTimeout has not been defined\")}function runTimeout(o){if(s===setTimeout)return setTimeout(o,0);if((s===defaultSetTimout||!s)&&setTimeout)return s=setTimeout,setTimeout(o,0);try{return s(o,0)}catch(i){try{return s.call(null,o,0)}catch(i){return s.call(this,o,0)}}}!function(){try{s=\"function\"==typeof setTimeout?setTimeout:defaultSetTimout}catch(o){s=defaultSetTimout}try{i=\"function\"==typeof clearTimeout?clearTimeout:defaultClearTimeout}catch(o){i=defaultClearTimeout}}();var _,w=[],x=!1,C=-1;function cleanUpNextTick(){x&&_&&(x=!1,_.length?w=_.concat(w):C=-1,w.length&&drainQueue())}function drainQueue(){if(!x){var o=runTimeout(cleanUpNextTick);x=!0;for(var s=w.length;s;){for(_=w,w=[];++C1)for(var i=1;i{\"use strict\";var u=i(6925);function emptyFunction(){}function emptyFunctionWithReset(){}emptyFunctionWithReset.resetWarningCache=emptyFunction,o.exports=function(){function shim(o,s,i,_,w,x){if(x!==u){var C=new Error(\"Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types\");throw C.name=\"Invariant Violation\",C}}function getShim(){return shim}shim.isRequired=shim;var o={array:shim,bigint:shim,bool:shim,func:shim,number:shim,object:shim,string:shim,symbol:shim,any:shim,arrayOf:getShim,element:shim,elementType:shim,instanceOf:getShim,node:shim,objectOf:getShim,oneOf:getShim,oneOfType:getShim,shape:getShim,exact:getShim,checkPropTypes:emptyFunctionWithReset,resetWarningCache:emptyFunction};return o.PropTypes=o,o}},5556:(o,s,i)=>{o.exports=i(2694)()},6925:o=>{\"use strict\";o.exports=\"SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED\"},74765:o=>{\"use strict\";var s=String.prototype.replace,i=/%20/g,u=\"RFC1738\",_=\"RFC3986\";o.exports={default:_,formatters:{RFC1738:function(o){return s.call(o,i,\"+\")},RFC3986:function(o){return String(o)}},RFC1738:u,RFC3986:_}},55373:(o,s,i)=>{\"use strict\";var u=i(98636),_=i(62642),w=i(74765);o.exports={formats:w,parse:_,stringify:u}},62642:(o,s,i)=>{\"use strict\";var u=i(37720),_=Object.prototype.hasOwnProperty,w=Array.isArray,x={allowDots:!1,allowPrototypes:!1,allowSparse:!1,arrayLimit:20,charset:\"utf-8\",charsetSentinel:!1,comma:!1,decoder:u.decode,delimiter:\"&\",depth:5,ignoreQueryPrefix:!1,interpretNumericEntities:!1,parameterLimit:1e3,parseArrays:!0,plainObjects:!1,strictNullHandling:!1},interpretNumericEntities=function(o){return o.replace(/&#(\\d+);/g,(function(o,s){return String.fromCharCode(parseInt(s,10))}))},parseArrayValue=function(o,s){return o&&\"string\"==typeof o&&s.comma&&o.indexOf(\",\")>-1?o.split(\",\"):o},C=function parseQueryStringKeys(o,s,i,u){if(o){var w=i.allowDots?o.replace(/\\.([^.[]+)/g,\"[$1]\"):o,x=/(\\[[^[\\]]*])/g,C=i.depth>0&&/(\\[[^[\\]]*])/.exec(w),j=C?w.slice(0,C.index):w,L=[];if(j){if(!i.plainObjects&&_.call(Object.prototype,j)&&!i.allowPrototypes)return;L.push(j)}for(var B=0;i.depth>0&&null!==(C=x.exec(w))&&B=0;--w){var x,C=o[w];if(\"[]\"===C&&i.parseArrays)x=[].concat(_);else{x=i.plainObjects?Object.create(null):{};var j=\"[\"===C.charAt(0)&&\"]\"===C.charAt(C.length-1)?C.slice(1,-1):C,L=parseInt(j,10);i.parseArrays||\"\"!==j?!isNaN(L)&&C!==j&&String(L)===j&&L>=0&&i.parseArrays&&L<=i.arrayLimit?(x=[])[L]=_:\"__proto__\"!==j&&(x[j]=_):x={0:_}}_=x}return _}(L,s,i,u)}};o.exports=function(o,s){var i=function normalizeParseOptions(o){if(!o)return x;if(null!==o.decoder&&void 0!==o.decoder&&\"function\"!=typeof o.decoder)throw new TypeError(\"Decoder has to be a function.\");if(void 0!==o.charset&&\"utf-8\"!==o.charset&&\"iso-8859-1\"!==o.charset)throw new TypeError(\"The charset option must be either utf-8, iso-8859-1, or undefined\");var s=void 0===o.charset?x.charset:o.charset;return{allowDots:void 0===o.allowDots?x.allowDots:!!o.allowDots,allowPrototypes:\"boolean\"==typeof o.allowPrototypes?o.allowPrototypes:x.allowPrototypes,allowSparse:\"boolean\"==typeof o.allowSparse?o.allowSparse:x.allowSparse,arrayLimit:\"number\"==typeof o.arrayLimit?o.arrayLimit:x.arrayLimit,charset:s,charsetSentinel:\"boolean\"==typeof o.charsetSentinel?o.charsetSentinel:x.charsetSentinel,comma:\"boolean\"==typeof o.comma?o.comma:x.comma,decoder:\"function\"==typeof o.decoder?o.decoder:x.decoder,delimiter:\"string\"==typeof o.delimiter||u.isRegExp(o.delimiter)?o.delimiter:x.delimiter,depth:\"number\"==typeof o.depth||!1===o.depth?+o.depth:x.depth,ignoreQueryPrefix:!0===o.ignoreQueryPrefix,interpretNumericEntities:\"boolean\"==typeof o.interpretNumericEntities?o.interpretNumericEntities:x.interpretNumericEntities,parameterLimit:\"number\"==typeof o.parameterLimit?o.parameterLimit:x.parameterLimit,parseArrays:!1!==o.parseArrays,plainObjects:\"boolean\"==typeof o.plainObjects?o.plainObjects:x.plainObjects,strictNullHandling:\"boolean\"==typeof o.strictNullHandling?o.strictNullHandling:x.strictNullHandling}}(s);if(\"\"===o||null==o)return i.plainObjects?Object.create(null):{};for(var j=\"string\"==typeof o?function parseQueryStringValues(o,s){var i,C={},j=s.ignoreQueryPrefix?o.replace(/^\\?/,\"\"):o,L=s.parameterLimit===1/0?void 0:s.parameterLimit,B=j.split(s.delimiter,L),$=-1,V=s.charset;if(s.charsetSentinel)for(i=0;i-1&&(z=w(z)?[z]:z),_.call(C,U)?C[U]=u.combine(C[U],z):C[U]=z}return C}(o,i):o,L=i.plainObjects?Object.create(null):{},B=Object.keys(j),$=0;${\"use strict\";var u=i(920),_=i(37720),w=i(74765),x=Object.prototype.hasOwnProperty,C={brackets:function brackets(o){return o+\"[]\"},comma:\"comma\",indices:function indices(o,s){return o+\"[\"+s+\"]\"},repeat:function repeat(o){return o}},j=Array.isArray,L=String.prototype.split,B=Array.prototype.push,pushToArray=function(o,s){B.apply(o,j(s)?s:[s])},$=Date.prototype.toISOString,V=w.default,U={addQueryPrefix:!1,allowDots:!1,charset:\"utf-8\",charsetSentinel:!1,delimiter:\"&\",encode:!0,encoder:_.encode,encodeValuesOnly:!1,format:V,formatter:w.formatters[V],indices:!1,serializeDate:function serializeDate(o){return $.call(o)},skipNulls:!1,strictNullHandling:!1},z={},Y=function stringify(o,s,i,w,x,C,B,$,V,Y,Z,ee,ie,ae,ce,le){for(var pe=o,de=le,fe=0,ye=!1;void 0!==(de=de.get(z))&&!ye;){var be=de.get(o);if(fe+=1,void 0!==be){if(be===fe)throw new RangeError(\"Cyclic object value\");ye=!0}void 0===de.get(z)&&(fe=0)}if(\"function\"==typeof $?pe=$(s,pe):pe instanceof Date?pe=Z(pe):\"comma\"===i&&j(pe)&&(pe=_.maybeMap(pe,(function(o){return o instanceof Date?Z(o):o}))),null===pe){if(x)return B&&!ae?B(s,U.encoder,ce,\"key\",ee):s;pe=\"\"}if(function isNonNullishPrimitive(o){return\"string\"==typeof o||\"number\"==typeof o||\"boolean\"==typeof o||\"symbol\"==typeof o||\"bigint\"==typeof o}(pe)||_.isBuffer(pe)){if(B){var _e=ae?s:B(s,U.encoder,ce,\"key\",ee);if(\"comma\"===i&&ae){for(var we=L.call(String(pe),\",\"),Se=\"\",xe=0;xe0?pe.join(\",\")||null:void 0}];else if(j($))Pe=$;else{var Re=Object.keys(pe);Pe=V?Re.sort(V):Re}for(var qe=w&&j(pe)&&1===pe.length?s+\"[]\":s,$e=0;$e0?ce+ae:\"\"}},37720:(o,s,i)=>{\"use strict\";var u=i(74765),_=Object.prototype.hasOwnProperty,w=Array.isArray,x=function(){for(var o=[],s=0;s<256;++s)o.push(\"%\"+((s<16?\"0\":\"\")+s.toString(16)).toUpperCase());return o}(),C=function arrayToObject(o,s){for(var i=s&&s.plainObjects?Object.create(null):{},u=0;u1;){var s=o.pop(),i=s.obj[s.prop];if(w(i)){for(var u=[],_=0;_=48&&B<=57||B>=65&&B<=90||B>=97&&B<=122||w===u.RFC1738&&(40===B||41===B)?j+=C.charAt(L):B<128?j+=x[B]:B<2048?j+=x[192|B>>6]+x[128|63&B]:B<55296||B>=57344?j+=x[224|B>>12]+x[128|B>>6&63]+x[128|63&B]:(L+=1,B=65536+((1023&B)<<10|1023&C.charCodeAt(L)),j+=x[240|B>>18]+x[128|B>>12&63]+x[128|B>>6&63]+x[128|63&B])}return j},isBuffer:function isBuffer(o){return!(!o||\"object\"!=typeof o)&&!!(o.constructor&&o.constructor.isBuffer&&o.constructor.isBuffer(o))},isRegExp:function isRegExp(o){return\"[object RegExp]\"===Object.prototype.toString.call(o)},maybeMap:function maybeMap(o,s){if(w(o)){for(var i=[],u=0;u{\"use strict\";var i=Object.prototype.hasOwnProperty;function decode(o){try{return decodeURIComponent(o.replace(/\\+/g,\" \"))}catch(o){return null}}function encode(o){try{return encodeURIComponent(o)}catch(o){return null}}s.stringify=function querystringify(o,s){s=s||\"\";var u,_,w=[];for(_ in\"string\"!=typeof s&&(s=\"?\"),o)if(i.call(o,_)){if((u=o[_])||null!=u&&!isNaN(u)||(u=\"\"),_=encode(_),u=encode(u),null===_||null===u)continue;w.push(_+\"=\"+u)}return w.length?s+w.join(\"&\"):\"\"},s.parse=function querystring(o){for(var s,i=/([^=?#&]+)=?([^&]*)/g,u={};s=i.exec(o);){var _=decode(s[1]),w=decode(s[2]);null===_||null===w||_ in u||(u[_]=w)}return u}},41859:(o,s,i)=>{const u=i(27096),_=i(78004),w=u.types;o.exports=class RandExp{constructor(o,s){if(this._setDefaults(o),o instanceof RegExp)this.ignoreCase=o.ignoreCase,this.multiline=o.multiline,o=o.source;else{if(\"string\"!=typeof o)throw new Error(\"Expected a regexp or string\");this.ignoreCase=s&&-1!==s.indexOf(\"i\"),this.multiline=s&&-1!==s.indexOf(\"m\")}this.tokens=u(o)}_setDefaults(o){this.max=null!=o.max?o.max:null!=RandExp.prototype.max?RandExp.prototype.max:100,this.defaultRange=o.defaultRange?o.defaultRange:this.defaultRange.clone(),o.randInt&&(this.randInt=o.randInt)}gen(){return this._gen(this.tokens,[])}_gen(o,s){var i,u,_,x,C;switch(o.type){case w.ROOT:case w.GROUP:if(o.followedBy||o.notFollowedBy)return\"\";for(o.remember&&void 0===o.groupNumber&&(o.groupNumber=s.push(null)-1),u=\"\",x=0,C=(i=o.options?this._randSelect(o.options):o.stack).length;x{\"use strict\";var u=i(65606),_=65536,w=4294967295;var x=i(92861).Buffer,C=i.g.crypto||i.g.msCrypto;C&&C.getRandomValues?o.exports=function randomBytes(o,s){if(o>w)throw new RangeError(\"requested too many random bytes\");var i=x.allocUnsafe(o);if(o>0)if(o>_)for(var j=0;j{\"use strict\";function _typeof(o){return _typeof=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(o){return typeof o}:function(o){return o&&\"function\"==typeof Symbol&&o.constructor===Symbol&&o!==Symbol.prototype?\"symbol\":typeof o},_typeof(o)}Object.defineProperty(s,\"__esModule\",{value:!0}),s.CopyToClipboard=void 0;var u=_interopRequireDefault(i(96540)),_=_interopRequireDefault(i(17965)),w=[\"text\",\"onCopy\",\"options\",\"children\"];function _interopRequireDefault(o){return o&&o.__esModule?o:{default:o}}function ownKeys(o,s){var i=Object.keys(o);if(Object.getOwnPropertySymbols){var u=Object.getOwnPropertySymbols(o);s&&(u=u.filter((function(s){return Object.getOwnPropertyDescriptor(o,s).enumerable}))),i.push.apply(i,u)}return i}function _objectSpread(o){for(var s=1;s=0||(_[i]=o[i]);return _}(o,s);if(Object.getOwnPropertySymbols){var w=Object.getOwnPropertySymbols(o);for(u=0;u=0||Object.prototype.propertyIsEnumerable.call(o,i)&&(_[i]=o[i])}return _}function _defineProperties(o,s){for(var i=0;i{\"use strict\";var u=i(25264).CopyToClipboard;u.CopyToClipboard=u,o.exports=u},81214:(o,s,i)=>{\"use strict\";function _typeof(o){return _typeof=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(o){return typeof o}:function(o){return o&&\"function\"==typeof Symbol&&o.constructor===Symbol&&o!==Symbol.prototype?\"symbol\":typeof o},_typeof(o)}Object.defineProperty(s,\"__esModule\",{value:!0}),s.DebounceInput=void 0;var u=_interopRequireDefault(i(96540)),_=_interopRequireDefault(i(20181)),w=[\"element\",\"onChange\",\"value\",\"minLength\",\"debounceTimeout\",\"forceNotifyByEnter\",\"forceNotifyOnBlur\",\"onKeyDown\",\"onBlur\",\"inputRef\"];function _interopRequireDefault(o){return o&&o.__esModule?o:{default:o}}function _objectWithoutProperties(o,s){if(null==o)return{};var i,u,_=function _objectWithoutPropertiesLoose(o,s){if(null==o)return{};var i,u,_={},w=Object.keys(o);for(u=0;u=0||(_[i]=o[i]);return _}(o,s);if(Object.getOwnPropertySymbols){var w=Object.getOwnPropertySymbols(o);for(u=0;u=0||Object.prototype.propertyIsEnumerable.call(o,i)&&(_[i]=o[i])}return _}function ownKeys(o,s){var i=Object.keys(o);if(Object.getOwnPropertySymbols){var u=Object.getOwnPropertySymbols(o);s&&(u=u.filter((function(s){return Object.getOwnPropertyDescriptor(o,s).enumerable}))),i.push.apply(i,u)}return i}function _objectSpread(o){for(var s=1;s=u?i.notify(o):s.length>_.length&&i.notify(_objectSpread(_objectSpread({},o),{},{target:_objectSpread(_objectSpread({},o.target),{},{value:\"\"})}))}))})),_defineProperty(_assertThisInitialized(i),\"onKeyDown\",(function(o){\"Enter\"===o.key&&i.forceNotify(o);var s=i.props.onKeyDown;s&&(o.persist(),s(o))})),_defineProperty(_assertThisInitialized(i),\"onBlur\",(function(o){i.forceNotify(o);var s=i.props.onBlur;s&&(o.persist(),s(o))})),_defineProperty(_assertThisInitialized(i),\"createNotifier\",(function(o){if(o<0)i.notify=function(){return null};else if(0===o)i.notify=i.doNotify;else{var s=(0,_.default)((function(o){i.isDebouncing=!1,i.doNotify(o)}),o);i.notify=function(o){i.isDebouncing=!0,s(o)},i.flush=function(){return s.flush()},i.cancel=function(){i.isDebouncing=!1,s.cancel()}}})),_defineProperty(_assertThisInitialized(i),\"doNotify\",(function(){i.props.onChange.apply(void 0,arguments)})),_defineProperty(_assertThisInitialized(i),\"forceNotify\",(function(o){var s=i.props.debounceTimeout;if(i.isDebouncing||!(s>0)){i.cancel&&i.cancel();var u=i.state.value,_=i.props.minLength;u.length>=_?i.doNotify(o):i.doNotify(_objectSpread(_objectSpread({},o),{},{target:_objectSpread(_objectSpread({},o.target),{},{value:u})}))}})),i.isDebouncing=!1,i.state={value:void 0===o.value||null===o.value?\"\":o.value};var u=i.props.debounceTimeout;return i.createNotifier(u),i}return function _createClass(o,s,i){return s&&_defineProperties(o.prototype,s),i&&_defineProperties(o,i),Object.defineProperty(o,\"prototype\",{writable:!1}),o}(DebounceInput,[{key:\"componentDidUpdate\",value:function componentDidUpdate(o){if(!this.isDebouncing){var s=this.props,i=s.value,u=s.debounceTimeout,_=o.debounceTimeout,w=o.value,x=this.state.value;void 0!==i&&w!==i&&x!==i&&this.setState({value:i}),u!==_&&this.createNotifier(u)}}},{key:\"componentWillUnmount\",value:function componentWillUnmount(){this.flush&&this.flush()}},{key:\"render\",value:function render(){var o,s,i=this.props,_=i.element,x=(i.onChange,i.value,i.minLength,i.debounceTimeout,i.forceNotifyByEnter),C=i.forceNotifyOnBlur,j=i.onKeyDown,L=i.onBlur,B=i.inputRef,$=_objectWithoutProperties(i,w),V=this.state.value;o=x?{onKeyDown:this.onKeyDown}:j?{onKeyDown:j}:{},s=C?{onBlur:this.onBlur}:L?{onBlur:L}:{};var U=B?{ref:B}:{};return u.default.createElement(_,_objectSpread(_objectSpread(_objectSpread(_objectSpread({},$),{},{onChange:this.onChange,value:V},o),s),U))}}]),DebounceInput}(u.default.PureComponent);s.DebounceInput=x,_defineProperty(x,\"defaultProps\",{element:\"input\",type:\"text\",onKeyDown:void 0,onBlur:void 0,value:void 0,minLength:0,debounceTimeout:100,forceNotifyByEnter:!0,forceNotifyOnBlur:!0,inputRef:void 0})},24677:(o,s,i)=>{\"use strict\";var u=i(81214).DebounceInput;u.DebounceInput=u,o.exports=u},22551:(o,s,i)=>{\"use strict\";var u=i(96540),_=i(69982);function p(o){for(var s=\"https://reactjs.org/docs/error-decoder.html?invariant=\"+o,i=1;i
\"},UO.link_close=function(){return\"\"},UO.image=function(o,s,i){var u=' src=\"'+escapeHtml(o[s].src)+'\"',_=o[s].title?' title=\"'+escapeHtml(replaceEntities(o[s].title))+'\"':\"\";return\"\"},UO.table_open=function(){return\"\\n\"},UO.table_close=function(){return\"
\\n\"},UO.thead_open=function(){return\"\\n\"},UO.thead_close=function(){return\"\\n\"},UO.tbody_open=function(){return\"\\n\"},UO.tbody_close=function(){return\"\\n\"},UO.tr_open=function(){return\"\"},UO.tr_close=function(){return\"\\n\"},UO.th_open=function(o,s){var i=o[s];return\"\"},UO.th_close=function(){return\"\"},UO.td_open=function(o,s){var i=o[s];return\"\"},UO.td_close=function(){return\"\"},UO.strong_open=function(){return\"\"},UO.strong_close=function(){return\"\"},UO.em_open=function(){return\"\"},UO.em_close=function(){return\"\"},UO.del_open=function(){return\"\"},UO.del_close=function(){return\"\"},UO.ins_open=function(){return\"\"},UO.ins_close=function(){return\"\"},UO.mark_open=function(){return\"\"},UO.mark_close=function(){return\"\"},UO.sub=function(o,s){return\"\"+escapeHtml(o[s].content)+\"\"},UO.sup=function(o,s){return\"\"+escapeHtml(o[s].content)+\"\"},UO.hardbreak=function(o,s,i){return i.xhtmlOut?\"
\\n\":\"
\\n\"},UO.softbreak=function(o,s,i){return i.breaks?i.xhtmlOut?\"
\\n\":\"
\\n\":\"\\n\"},UO.text=function(o,s){return escapeHtml(o[s].content)},UO.htmlblock=function(o,s){return o[s].content},UO.htmltag=function(o,s){return o[s].content},UO.abbr_open=function(o,s){return''},UO.abbr_close=function(){return\"\"},UO.footnote_ref=function(o,s){var i=Number(o[s].id+1).toString(),u=\"fnref\"+i;return o[s].subId>0&&(u+=\":\"+o[s].subId),'['+i+\"]\"},UO.footnote_block_open=function(o,s,i){return(i.xhtmlOut?'
\\n':'
\\n')+'
\\n
    \\n'},UO.footnote_block_close=function(){return\"
\\n
\\n\"},UO.footnote_open=function(o,s){return'
  • '},UO.footnote_close=function(){return\"
  • \\n\"},UO.footnote_anchor=function(o,s){var i=\"fnref\"+Number(o[s].id+1).toString();return o[s].subId>0&&(i+=\":\"+o[s].subId),' '},UO.dl_open=function(){return\"
    \\n\"},UO.dt_open=function(){return\"
    \"},UO.dd_open=function(){return\"
    \"},UO.dl_close=function(){return\"
    \\n\"},UO.dt_close=function(){return\"\\n\"},UO.dd_close=function(){return\"\\n\"};var zO=UO.getBreak=function getBreak(o,s){return(s=nextToken(o,s))1)break;if(41===i&&--u<0)break;s++}return w!==s&&(_=unescapeMd(o.src.slice(w,s)),!!o.parser.validateLink(_)&&(o.linkContent=_,o.pos=s,!0))}function parseLinkTitle(o,s){var i,u=s,_=o.posMax,w=o.src.charCodeAt(s);if(34!==w&&39!==w&&40!==w)return!1;for(s++,40===w&&(w=41);s<_;){if((i=o.src.charCodeAt(s))===w)return o.pos=s+1,o.linkContent=unescapeMd(o.src.slice(u+1,s)),!0;92===i&&s+1<_?s+=2:s++}return!1}function normalizeReference(o){return o.trim().replace(/\\s+/g,\" \").toUpperCase()}function parseReference(o,s,i,u){var _,w,x,C,j,L,B,$,V;if(91!==o.charCodeAt(0))return-1;if(-1===o.indexOf(\"]:\"))return-1;if((w=parseLinkLabel(_=new StateInline(o,s,i,u,[]),0))<0||58!==o.charCodeAt(w+1))return-1;for(C=_.posMax,x=w+2;x=o.length)&&!XO.test(o[s])}function replaceAt(o,s,i){return o.substr(0,s)+i+o.substr(s+1)}var QO=[[\"block\",function block(o){o.inlineMode?o.tokens.push({type:\"inline\",content:o.src.replace(/\\n/g,\" \").trim(),level:0,lines:[0,1],children:[]}):o.block.parse(o.src,o.options,o.env,o.tokens)}],[\"abbr\",function abbr(o){var s,i,u,_,w=o.tokens;if(!o.inlineMode)for(s=1,i=w.length-1;s0?x[s].count:1,u=0;u<_;u++)o.tokens.push({type:\"footnote_anchor\",id:s,subId:u,level:B});w&&o.tokens.push(w),o.tokens.push({type:\"footnote_close\",level:--B})}o.tokens.push({type:\"footnote_block_close\",level:--B})}}],[\"abbr2\",function abbr2(o){var s,i,u,_,w,x,C,j,L,B,$,V,U=o.tokens;if(o.env.abbreviations)for(o.env.abbrRegExp||(V=\"(^|[\"+WO.split(\"\").map(regEscape).join(\"\")+\"])(\"+Object.keys(o.env.abbreviations).map((function(o){return o.substr(1)})).sort((function(o,s){return s.length-o.length})).map(regEscape).join(\"|\")+\")($|[\"+WO.split(\"\").map(regEscape).join(\"\")+\"])\",o.env.abbrRegExp=new RegExp(V,\"g\")),B=o.env.abbrRegExp,i=0,u=U.length;i=0;s--)if(\"text\"===(w=_[s]).type){for(j=0,x=w.content,B.lastIndex=0,L=w.level,C=[];$=B.exec(x);)B.lastIndex>j&&C.push({type:\"text\",content:x.slice(j,$.index+$[1].length),level:L}),C.push({type:\"abbr_open\",title:o.env.abbreviations[\":\"+$[2]],level:L++}),C.push({type:\"text\",content:$[2],level:L}),C.push({type:\"abbr_close\",level:--L}),j=B.lastIndex-$[3].length;C.length&&(j=0;w--)if(\"inline\"===o.tokens[w].type)for(s=(_=o.tokens[w].children).length-1;s>=0;s--)\"text\"===(i=_[s]).type&&(u=replaceScopedAbbr(u=i.content),KO.test(u)&&(u=u.replace(/\\+-/g,\"±\").replace(/\\.{2,}/g,\"…\").replace(/([?!])…/g,\"$1..\").replace(/([?!]){4,}/g,\"$1$1$1\").replace(/,{2,}/g,\",\").replace(/(^|[^-])---([^-]|$)/gm,\"$1—$2\").replace(/(^|\\s)--(\\s|$)/gm,\"$1–$2\").replace(/(^|[^-\\s])--([^-\\s]|$)/gm,\"$1–$2\")),i.content=u)}],[\"smartquotes\",function smartquotes(o){var s,i,u,_,w,x,C,j,L,B,$,V,U,z,Y,Z,ee;if(o.options.typographer)for(ee=[],Y=o.tokens.length-1;Y>=0;Y--)if(\"inline\"===o.tokens[Y].type)for(Z=o.tokens[Y].children,ee.length=0,s=0;s=0&&!(ee[U].level<=C);U--);ee.length=U+1,w=0,x=(u=i.content).length;e:for(;w=0&&(B=ee[U],!(ee[U].level=(_=o.eMarks[s])||42!==(i=o.src.charCodeAt(u++))&&45!==i&&43!==i||u<_&&32!==o.src.charCodeAt(u)?-1:u}function skipOrderedListMarker(o,s){var i,u=o.bMarks[s]+o.tShift[s],_=o.eMarks[s];if(u+1>=_)return-1;if((i=o.src.charCodeAt(u++))<48||i>57)return-1;for(;;){if(u>=_)return-1;if(!((i=o.src.charCodeAt(u++))>=48&&i<=57)){if(41===i||46===i)break;return-1}}return u<_&&32!==o.src.charCodeAt(u)?-1:u}Core.prototype.process=function(o){var s,i,u;for(s=0,i=(u=this.ruler.getRules(\"\")).length;s=this.eMarks[o]},StateBlock.prototype.skipEmptyLines=function skipEmptyLines(o){for(var s=this.lineMax;oi;)if(s!==this.src.charCodeAt(--o))return o+1;return o},StateBlock.prototype.getLines=function getLines(o,s,i,u){var _,w,x,C,j,L=o;if(o>=s)return\"\";if(L+1===s)return w=this.bMarks[L]+Math.min(this.tShift[L],i),x=u?this.eMarks[L]+1:this.eMarks[L],this.src.slice(w,x);for(C=new Array(s-o),_=0;Li&&(j=i),j<0&&(j=0),w=this.bMarks[L]+j,x=L+1]/,tC=/^<\\/([a-zA-Z]{1,15})[\\s>]/;function index_browser_getLine(o,s){var i=o.bMarks[s]+o.blkIndent,u=o.eMarks[s];return o.src.substr(i,u-i)}function skipMarker(o,s){var i,u,_=o.bMarks[s]+o.tShift[s],w=o.eMarks[s];return _>=w||126!==(u=o.src.charCodeAt(_++))&&58!==u||_===(i=o.skipSpaces(_))||i>=w?-1:i}var rC=[[\"code\",function code(o,s,i){var u,_;if(o.tShift[s]-o.blkIndent<4)return!1;for(_=u=s+1;u=4))break;_=++u}return o.line=u,o.tokens.push({type:\"code\",content:o.getLines(s,_,4+o.blkIndent,!0),block:!0,lines:[s,o.line],level:o.level}),!0}],[\"fences\",function fences(o,s,i,u){var _,w,x,C,j,L=!1,B=o.bMarks[s]+o.tShift[s],$=o.eMarks[s];if(B+3>$)return!1;if(126!==(_=o.src.charCodeAt(B))&&96!==_)return!1;if(j=B,(w=(B=o.skipChars(B,_))-j)<3)return!1;if((x=o.src.slice(B,$).trim()).indexOf(\"`\")>=0)return!1;if(u)return!0;for(C=s;!(++C>=i)&&!((B=j=o.bMarks[C]+o.tShift[C])<($=o.eMarks[C])&&o.tShift[C]=4||(B=o.skipChars(B,_))-jZ)return!1;if(62!==o.src.charCodeAt(Y++))return!1;if(o.level>=o.options.maxNesting)return!1;if(u)return!0;for(32===o.src.charCodeAt(Y)&&Y++,j=o.blkIndent,o.blkIndent=0,C=[o.bMarks[s]],o.bMarks[s]=Y,w=(Y=Y=Z,x=[o.tShift[s]],o.tShift[s]=Y-o.bMarks[s],$=o.parser.ruler.getRules(\"blockquote\"),_=s+1;_=(Z=o.eMarks[_]));_++)if(62!==o.src.charCodeAt(Y++)){if(w)break;for(z=!1,V=0,U=$.length;V=Z,x.push(o.tShift[_]),o.tShift[_]=Y-o.bMarks[_];for(L=o.parentType,o.parentType=\"blockquote\",o.tokens.push({type:\"blockquote_open\",lines:B=[s,0],level:o.level++}),o.parser.tokenize(o,s,_),o.tokens.push({type:\"blockquote_close\",level:--o.level}),o.parentType=L,B[1]=o.line,V=0;Vj)return!1;if(42!==(_=o.src.charCodeAt(C++))&&45!==_&&95!==_)return!1;for(w=1;C=0)Y=!0;else{if(!(($=skipBulletListMarker(o,s))>=0))return!1;Y=!1}if(o.level>=o.options.maxNesting)return!1;if(z=o.src.charCodeAt($-1),u)return!0;for(ee=o.tokens.length,Y?(B=o.bMarks[s]+o.tShift[s],U=Number(o.src.substr(B,$-B-1)),o.tokens.push({type:\"ordered_list_open\",order:U,lines:ae=[s,0],level:o.level++})):o.tokens.push({type:\"bullet_list_open\",lines:ae=[s,0],level:o.level++}),_=s,ie=!1,le=o.parser.ruler.getRules(\"list\");!(!(_=o.eMarks[_]?1:Z-$)>4&&(V=1),V<1&&(V=1),w=$-o.bMarks[_]+V,o.tokens.push({type:\"list_item_open\",lines:ce=[s,0],level:o.level++}),C=o.blkIndent,j=o.tight,x=o.tShift[s],L=o.parentType,o.tShift[s]=Z-o.bMarks[s],o.blkIndent=w,o.tight=!0,o.parentType=\"list\",o.parser.tokenize(o,s,i,!0),o.tight&&!ie||(ye=!1),ie=o.line-s>1&&o.isEmpty(o.line-1),o.blkIndent=C,o.tShift[s]=x,o.tight=j,o.parentType=L,o.tokens.push({type:\"list_item_close\",level:--o.level}),_=s=o.line,ce[1]=_,Z=o.bMarks[s],_>=i)||o.isEmpty(_)||o.tShift[_]B)return!1;if(91!==o.src.charCodeAt(L))return!1;if(94!==o.src.charCodeAt(L+1))return!1;if(o.level>=o.options.maxNesting)return!1;for(C=L+2;C=B||58!==o.src.charCodeAt(++C))&&(u||(C++,o.env.footnotes||(o.env.footnotes={}),o.env.footnotes.refs||(o.env.footnotes.refs={}),j=o.src.slice(L+2,C-2),o.env.footnotes.refs[\":\"+j]=-1,o.tokens.push({type:\"footnote_reference_open\",label:j,level:o.level++}),_=o.bMarks[s],w=o.tShift[s],x=o.parentType,o.tShift[s]=o.skipSpaces(C)-C,o.bMarks[s]=C,o.blkIndent+=4,o.parentType=\"footnote\",o.tShift[s]=j)return!1;if(35!==(_=o.src.charCodeAt(C))||C>=j)return!1;for(w=1,_=o.src.charCodeAt(++C);35===_&&C6||CC&&32===o.src.charCodeAt(x-1)&&(j=x),o.line=s+1,o.tokens.push({type:\"heading_open\",hLevel:w,lines:[s,o.line],level:o.level}),C=i)&&(!(o.tShift[x]3)&&(!((_=o.bMarks[x]+o.tShift[x])>=(w=o.eMarks[x]))&&((45===(u=o.src.charCodeAt(_))||61===u)&&(_=o.skipChars(_,u),!((_=o.skipSpaces(_))3||C+2>=j)return!1;if(60!==o.src.charCodeAt(C))return!1;if(33===(_=o.src.charCodeAt(C+1))||63===_){if(u)return!0}else{if(47!==_&&!function isLetter$1(o){var s=32|o;return s>=97&&s<=122}(_))return!1;if(47===_){if(!(w=o.src.slice(C,j).match(tC)))return!1}else if(!(w=o.src.slice(C,j).match(eC)))return!1;if(!0!==ZO[w[1].toLowerCase()])return!1;if(u)return!0}for(x=s+1;xi)return!1;if(j=s+1,o.tShift[j]=o.eMarks[j])return!1;if(124!==(_=o.src.charCodeAt(x))&&45!==_&&58!==_)return!1;if(w=index_browser_getLine(o,s+1),!/^[-:| ]+$/.test(w))return!1;if((L=w.split(\"|\"))<=2)return!1;for($=[],C=0;C=0;if(B=s+1,o.isEmpty(B)&&++B>i)return!1;if(o.tShift[B]=o.options.maxNesting)return!1;L=o.tokens.length,o.tokens.push({type:\"dl_open\",lines:j=[s,0],level:o.level++}),x=s,w=B;e:for(;;){for(ee=!0,Z=!1,o.tokens.push({type:\"dt_open\",lines:[x,x],level:o.level++}),o.tokens.push({type:\"inline\",content:o.getLines(x,x+1,o.blkIndent,!1).trim(),level:o.level+1,lines:[x,x],children:[]}),o.tokens.push({type:\"dt_close\",level:--o.level});;){if(o.tokens.push({type:\"dd_open\",lines:C=[B,0],level:o.level++}),Y=o.tight,V=o.ddIndent,$=o.blkIndent,z=o.tShift[w],U=o.parentType,o.blkIndent=o.ddIndent=o.tShift[w]+2,o.tShift[w]=_-o.bMarks[w],o.tight=!0,o.parentType=\"deflist\",o.parser.tokenize(o,w,i,!0),o.tight&&!Z||(ee=!1),Z=o.line-w>1&&o.isEmpty(o.line-1),o.tShift[w]=z,o.tight=Y,o.parentType=U,o.blkIndent=$,o.ddIndent=V,o.tokens.push({type:\"dd_close\",level:--o.level}),C[1]=B=o.line,B>=i)break e;if(o.tShift[B]=i)break;if(x=B,o.isEmpty(x))break;if(o.tShift[x]=i)break;if(o.isEmpty(w)&&w++,w>=i)break;if(o.tShift[w]3)){for(_=!1,w=0,x=C.length;w=i))&&!(o.tShift[x]=0&&(o=o.replace(nC,(function(s,i){var u;return 10===o.charCodeAt(i)?(w=i+1,x=0,s):(u=\" \".slice((i-w-x)%4),x=i-w+1,u)}))),_=new StateBlock(o,this,s,i,u),this.tokenize(_,_.line,_.lineMax)};for(var iC=[],aC=0;aC<256;aC++)iC.push(0);function isAlphaNum(o){return o>=48&&o<=57||o>=65&&o<=90||o>=97&&o<=122}function scanDelims(o,s){var i,u,_,w=s,x=!0,C=!0,j=o.posMax,L=o.src.charCodeAt(s);for(i=s>0?o.src.charCodeAt(s-1):-1;w=j&&(x=!1),(_=w-s)>=4?x=C=!1:(32!==(u=w?@[]^_`{|}~-\".split(\"\").forEach((function(o){iC[o.charCodeAt(0)]=1}));var cC=/\\\\([ \\\\!\"#$%&'()*+,.\\/:;<=>?@[\\]^_`{|}~-])/g;var lC=/\\\\([ \\\\!\"#$%&'()*+,.\\/:;<=>?@[\\]^_`{|}~-])/g;var uC=[\"coap\",\"doi\",\"javascript\",\"aaa\",\"aaas\",\"about\",\"acap\",\"cap\",\"cid\",\"crid\",\"data\",\"dav\",\"dict\",\"dns\",\"file\",\"ftp\",\"geo\",\"go\",\"gopher\",\"h323\",\"http\",\"https\",\"iax\",\"icap\",\"im\",\"imap\",\"info\",\"ipp\",\"iris\",\"iris.beep\",\"iris.xpc\",\"iris.xpcs\",\"iris.lwz\",\"ldap\",\"mailto\",\"mid\",\"msrp\",\"msrps\",\"mtqp\",\"mupdate\",\"news\",\"nfs\",\"ni\",\"nih\",\"nntp\",\"opaquelocktoken\",\"pop\",\"pres\",\"rtsp\",\"service\",\"session\",\"shttp\",\"sieve\",\"sip\",\"sips\",\"sms\",\"snmp\",\"soap.beep\",\"soap.beeps\",\"tag\",\"tel\",\"telnet\",\"tftp\",\"thismessage\",\"tn3270\",\"tip\",\"tv\",\"urn\",\"vemmi\",\"ws\",\"wss\",\"xcon\",\"xcon-userid\",\"xmlrpc.beep\",\"xmlrpc.beeps\",\"xmpp\",\"z39.50r\",\"z39.50s\",\"adiumxtra\",\"afp\",\"afs\",\"aim\",\"apt\",\"attachment\",\"aw\",\"beshare\",\"bitcoin\",\"bolo\",\"callto\",\"chrome\",\"chrome-extension\",\"com-eventbrite-attendee\",\"content\",\"cvs\",\"dlna-playsingle\",\"dlna-playcontainer\",\"dtn\",\"dvb\",\"ed2k\",\"facetime\",\"feed\",\"finger\",\"fish\",\"gg\",\"git\",\"gizmoproject\",\"gtalk\",\"hcp\",\"icon\",\"ipn\",\"irc\",\"irc6\",\"ircs\",\"itms\",\"jar\",\"jms\",\"keyparc\",\"lastfm\",\"ldaps\",\"magnet\",\"maps\",\"market\",\"message\",\"mms\",\"ms-help\",\"msnim\",\"mumble\",\"mvn\",\"notes\",\"oid\",\"palm\",\"paparazzi\",\"platform\",\"proxy\",\"psyc\",\"query\",\"res\",\"resource\",\"rmi\",\"rsync\",\"rtmp\",\"secondlife\",\"sftp\",\"sgn\",\"skype\",\"smb\",\"soldat\",\"spotify\",\"ssh\",\"steam\",\"svn\",\"teamspeak\",\"things\",\"udp\",\"unreal\",\"ut2004\",\"ventrilo\",\"view-source\",\"webcal\",\"wtai\",\"wyciwyg\",\"xfire\",\"xri\",\"ymsgr\"],pC=/^<([a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)>/,hC=/^<([a-zA-Z.\\-]{1,25}):([^<>\\x00-\\x20]*)>/;function replace$1(o,s){return o=o.source,s=s||\"\",function self(i,u){return i?(u=u.source||u,o=o.replace(i,u),self):new RegExp(o,s)}}var dC=replace$1(/(?:unquoted|single_quoted|double_quoted)/)(\"unquoted\",/[^\"'=<>`\\x00-\\x20]+/)(\"single_quoted\",/'[^']*'/)(\"double_quoted\",/\"[^\"]*\"/)(),fC=replace$1(/(?:\\s+attr_name(?:\\s*=\\s*attr_value)?)/)(\"attr_name\",/[a-zA-Z_:][a-zA-Z0-9:._-]*/)(\"attr_value\",dC)(),mC=replace$1(/<[A-Za-z][A-Za-z0-9]*attribute*\\s*\\/?>/)(\"attribute\",fC)(),gC=replace$1(/^(?:open_tag|close_tag|comment|processing|declaration|cdata)/)(\"open_tag\",mC)(\"close_tag\",/<\\/[A-Za-z][A-Za-z0-9]*\\s*>/)(\"comment\",/|/)(\"processing\",/<[?].*?[?]>/)(\"declaration\",/]*>/)(\"cdata\",//)();var yC=/^&#((?:x[a-f0-9]{1,8}|[0-9]{1,8}));/i,vC=/^&([a-z][a-z0-9]{1,31});/i;var bC=[[\"text\",function index_browser_text(o,s){for(var i=o.pos;i=0&&32===o.pending.charCodeAt(i))if(i>=1&&32===o.pending.charCodeAt(i-1)){for(var w=i-2;w>=0;w--)if(32!==o.pending.charCodeAt(w)){o.pending=o.pending.substring(0,w+1);break}o.push({type:\"hardbreak\",level:o.level})}else o.pending=o.pending.slice(0,-1),o.push({type:\"softbreak\",level:o.level});else o.push({type:\"softbreak\",level:o.level});for(_++;_=C)return!1;if(126!==o.src.charCodeAt(j+1))return!1;if(o.level>=o.options.maxNesting)return!1;if(w=j>0?o.src.charCodeAt(j-1):-1,x=o.src.charCodeAt(j+2),126===w)return!1;if(126===x)return!1;if(32===x||10===x)return!1;for(u=j+2;uj+3)return o.pos+=u-j,s||(o.pending+=o.src.slice(j,u)),!0;for(o.pos=j+2,_=1;o.pos+1=C)return!1;if(43!==o.src.charCodeAt(j+1))return!1;if(o.level>=o.options.maxNesting)return!1;if(w=j>0?o.src.charCodeAt(j-1):-1,x=o.src.charCodeAt(j+2),43===w)return!1;if(43===x)return!1;if(32===x||10===x)return!1;for(u=j+2;u=C)return!1;if(61!==o.src.charCodeAt(j+1))return!1;if(o.level>=o.options.maxNesting)return!1;if(w=j>0?o.src.charCodeAt(j-1):-1,x=o.src.charCodeAt(j+2),61===w)return!1;if(61===x)return!1;if(32===x||10===x)return!1;for(u=j+2;u=o.options.maxNesting)return!1;for(o.pos=B+i,C=[i];o.pos=_)return!1;if(o.level>=o.options.maxNesting)return!1;for(o.pos=w+1;o.pos<_;){if(126===o.src.charCodeAt(o.pos)){i=!0;break}o.parser.skipToken(o)}return i&&w+1!==o.pos?(u=o.src.slice(w+1,o.pos)).match(/(^|[^\\\\])(\\\\\\\\)*\\s/)?(o.pos=w,!1):(o.posMax=o.pos,o.pos=w+1,s||o.push({type:\"sub\",level:o.level,content:u.replace(cC,\"$1\")}),o.pos=o.posMax+1,o.posMax=_,!0):(o.pos=w,!1)}],[\"sup\",function sup(o,s){var i,u,_=o.posMax,w=o.pos;if(94!==o.src.charCodeAt(w))return!1;if(s)return!1;if(w+2>=_)return!1;if(o.level>=o.options.maxNesting)return!1;for(o.pos=w+1;o.pos<_;){if(94===o.src.charCodeAt(o.pos)){i=!0;break}o.parser.skipToken(o)}return i&&w+1!==o.pos?(u=o.src.slice(w+1,o.pos)).match(/(^|[^\\\\])(\\\\\\\\)*\\s/)?(o.pos=w,!1):(o.posMax=o.pos,o.pos=w+1,s||o.push({type:\"sup\",level:o.level,content:u.replace(lC,\"$1\")}),o.pos=o.posMax+1,o.posMax=_,!0):(o.pos=w,!1)}],[\"links\",function links(o,s){var i,u,_,w,x,C,j,L,B=!1,$=o.pos,V=o.posMax,U=o.pos,z=o.src.charCodeAt(U);if(33===z&&(B=!0,z=o.src.charCodeAt(++U)),91!==z)return!1;if(o.level>=o.options.maxNesting)return!1;if(i=U+1,(u=parseLinkLabel(o,U))<0)return!1;if((C=u+1)=V)return!1;for(U=C,parseLinkDestination(o,C)?(w=o.linkContent,C=o.pos):w=\"\",U=C;C=V||41!==o.src.charCodeAt(C))return o.pos=$,!1;C++}else{if(o.linkLevel>0)return!1;for(;C=0?_=o.src.slice(U,C++):C=U-1),_||(void 0===_&&(C=u+1),_=o.src.slice(i,u)),!(j=o.env.references[normalizeReference(_)]))return o.pos=$,!1;w=j.href,x=j.title}return s||(o.pos=i,o.posMax=u,B?o.push({type:\"image\",src:w,title:x,alt:o.src.substr(i,u-i),level:o.level}):(o.push({type:\"link_open\",href:w,title:x,level:o.level++}),o.linkLevel++,o.parser.tokenize(o),o.linkLevel--,o.push({type:\"link_close\",level:--o.level}))),o.pos=C,o.posMax=V,!0}],[\"footnote_inline\",function footnote_inline(o,s){var i,u,_,w,x=o.posMax,C=o.pos;return!(C+2>=x)&&(94===o.src.charCodeAt(C)&&(91===o.src.charCodeAt(C+1)&&(!(o.level>=o.options.maxNesting)&&(i=C+2,!((u=parseLinkLabel(o,C+1))<0)&&(s||(o.env.footnotes||(o.env.footnotes={}),o.env.footnotes.list||(o.env.footnotes.list=[]),_=o.env.footnotes.list.length,o.pos=i,o.posMax=u,o.push({type:\"footnote_ref\",id:_,level:o.level}),o.linkLevel++,w=o.tokens.length,o.parser.tokenize(o),o.env.footnotes.list[_]={tokens:o.tokens.splice(w)},o.linkLevel--),o.pos=u+1,o.posMax=x,!0)))))}],[\"footnote_ref\",function footnote_ref(o,s){var i,u,_,w,x=o.posMax,C=o.pos;if(C+3>x)return!1;if(!o.env.footnotes||!o.env.footnotes.refs)return!1;if(91!==o.src.charCodeAt(C))return!1;if(94!==o.src.charCodeAt(C+1))return!1;if(o.level>=o.options.maxNesting)return!1;for(u=C+2;u=x)&&(u++,i=o.src.slice(C+2,u-1),void 0!==o.env.footnotes.refs[\":\"+i]&&(s||(o.env.footnotes.list||(o.env.footnotes.list=[]),o.env.footnotes.refs[\":\"+i]<0?(_=o.env.footnotes.list.length,o.env.footnotes.list[_]={label:i,count:0},o.env.footnotes.refs[\":\"+i]=_):_=o.env.footnotes.refs[\":\"+i],w=o.env.footnotes.list[_].count,o.env.footnotes.list[_].count++,o.push({type:\"footnote_ref\",id:_,subId:w,level:o.level})),o.pos=u,o.posMax=x,!0)))}],[\"autolink\",function autolink(o,s){var i,u,_,w,x,C=o.pos;return 60===o.src.charCodeAt(C)&&(!((i=o.src.slice(C)).indexOf(\">\")<0)&&((u=i.match(hC))?!(uC.indexOf(u[1].toLowerCase())<0)&&(x=normalizeLink(w=u[0].slice(1,-1)),!!o.parser.validateLink(w)&&(s||(o.push({type:\"link_open\",href:x,level:o.level}),o.push({type:\"text\",content:w,level:o.level+1}),o.push({type:\"link_close\",level:o.level})),o.pos+=u[0].length,!0)):!!(_=i.match(pC))&&(x=normalizeLink(\"mailto:\"+(w=_[0].slice(1,-1))),!!o.parser.validateLink(x)&&(s||(o.push({type:\"link_open\",href:x,level:o.level}),o.push({type:\"text\",content:w,level:o.level+1}),o.push({type:\"link_close\",level:o.level})),o.pos+=_[0].length,!0))))}],[\"htmltag\",function htmltag(o,s){var i,u,_,w=o.pos;return!!o.options.html&&(_=o.posMax,!(60!==o.src.charCodeAt(w)||w+2>=_)&&(!(33!==(i=o.src.charCodeAt(w+1))&&63!==i&&47!==i&&!function isLetter$2(o){var s=32|o;return s>=97&&s<=122}(i))&&(!!(u=o.src.slice(w).match(gC))&&(s||o.push({type:\"htmltag\",content:o.src.slice(w,w+u[0].length),level:o.level}),o.pos+=u[0].length,!0))))}],[\"entity\",function entity(o,s){var i,u,_=o.pos,w=o.posMax;if(38!==o.src.charCodeAt(_))return!1;if(_+10)o.pos=i;else{for(s=0;s<_;s++)if(u[s](o,!0))return void o.cacheSet(w,o.pos);o.pos++,o.cacheSet(w,o.pos)}},ParserInline.prototype.tokenize=function(o){for(var s,i,u=this.ruler.getRules(\"\"),_=u.length,w=o.posMax;o.pos=w)break}else o.pending+=o.src[o.pos++]}o.pending&&o.pushPending()},ParserInline.prototype.parse=function(o,s,i,u){var _=new StateInline(o,this,s,i,u);this.tokenize(_)};var _C={default:{options:{html:!1,xhtmlOut:!1,breaks:!1,langPrefix:\"language-\",linkTarget:\"\",typographer:!1,quotes:\"“”‘’\",highlight:null,maxNesting:20},components:{core:{rules:[\"block\",\"inline\",\"references\",\"replacements\",\"smartquotes\",\"references\",\"abbr2\",\"footnote_tail\"]},block:{rules:[\"blockquote\",\"code\",\"fences\",\"footnote\",\"heading\",\"hr\",\"htmlblock\",\"lheading\",\"list\",\"paragraph\",\"table\"]},inline:{rules:[\"autolink\",\"backticks\",\"del\",\"emphasis\",\"entity\",\"escape\",\"footnote_ref\",\"htmltag\",\"links\",\"newline\",\"text\"]}}},full:{options:{html:!1,xhtmlOut:!1,breaks:!1,langPrefix:\"language-\",linkTarget:\"\",typographer:!1,quotes:\"“”‘’\",highlight:null,maxNesting:20},components:{core:{},block:{},inline:{}}},commonmark:{options:{html:!0,xhtmlOut:!0,breaks:!1,langPrefix:\"language-\",linkTarget:\"\",typographer:!1,quotes:\"“”‘’\",highlight:null,maxNesting:20},components:{core:{rules:[\"block\",\"inline\",\"references\",\"abbr2\"]},block:{rules:[\"blockquote\",\"code\",\"fences\",\"heading\",\"hr\",\"htmlblock\",\"lheading\",\"list\",\"paragraph\"]},inline:{rules:[\"autolink\",\"backticks\",\"emphasis\",\"entity\",\"escape\",\"htmltag\",\"links\",\"newline\",\"text\"]}}}};function StateCore(o,s,i){this.src=s,this.env=i,this.options=o.options,this.tokens=[],this.inlineMode=!1,this.inline=o.inline,this.block=o.block,this.renderer=o.renderer,this.typographer=o.typographer}function Remarkable(o,s){\"string\"!=typeof o&&(s=o,o=\"default\"),s&&null!=s.linkify&&console.warn(\"linkify option is removed. Use linkify plugin instead:\\n\\nimport Remarkable from 'remarkable';\\nimport linkify from 'remarkable/linkify';\\nnew Remarkable().use(linkify)\\n\"),this.inline=new ParserInline,this.block=new ParserBlock,this.core=new Core,this.renderer=new Renderer,this.ruler=new Ruler,this.options={},this.configure(_C[o]),this.set(s||{})}Remarkable.prototype.set=function(o){index_browser_assign(this.options,o)},Remarkable.prototype.configure=function(o){var s=this;if(!o)throw new Error(\"Wrong `remarkable` preset, check name/content\");o.options&&s.set(o.options),o.components&&Object.keys(o.components).forEach((function(i){o.components[i].rules&&s[i].ruler.enable(o.components[i].rules,!0)}))},Remarkable.prototype.use=function(o,s){return o(this,s),this},Remarkable.prototype.parse=function(o,s){var i=new StateCore(this,o,s);return this.core.process(i),i.tokens},Remarkable.prototype.render=function(o,s){return s=s||{},this.renderer.render(this.parse(o,s),this.options,s)},Remarkable.prototype.parseInline=function(o,s){var i=new StateCore(this,o,s);return i.inlineMode=!0,this.core.process(i),i.tokens},Remarkable.prototype.renderInline=function(o,s){return s=s||{},this.renderer.render(this.parseInline(o,s),this.options,s)};function indexOf(o,s){if(Array.prototype.indexOf)return o.indexOf(s);for(var i=0,u=o.length;i=0;i--)!0===s(o[i])&&o.splice(i,1)}function throwUnhandledCaseError(o){throw new Error(\"Unhandled case for value: '\".concat(o,\"'\"))}var EC=function(){function HtmlTag(o){void 0===o&&(o={}),this.tagName=\"\",this.attrs={},this.innerHTML=\"\",this.whitespaceRegex=/\\s+/,this.tagName=o.tagName||\"\",this.attrs=o.attrs||{},this.innerHTML=o.innerHtml||o.innerHTML||\"\"}return HtmlTag.prototype.setTagName=function(o){return this.tagName=o,this},HtmlTag.prototype.getTagName=function(){return this.tagName||\"\"},HtmlTag.prototype.setAttr=function(o,s){return this.getAttrs()[o]=s,this},HtmlTag.prototype.getAttr=function(o){return this.getAttrs()[o]},HtmlTag.prototype.setAttrs=function(o){return Object.assign(this.getAttrs(),o),this},HtmlTag.prototype.getAttrs=function(){return this.attrs||(this.attrs={})},HtmlTag.prototype.setClass=function(o){return this.setAttr(\"class\",o)},HtmlTag.prototype.addClass=function(o){for(var s,i=this.getClass(),u=this.whitespaceRegex,_=i?i.split(u):[],w=o.split(u);s=w.shift();)-1===indexOf(_,s)&&_.push(s);return this.getAttrs().class=_.join(\" \"),this},HtmlTag.prototype.removeClass=function(o){for(var s,i=this.getClass(),u=this.whitespaceRegex,_=i?i.split(u):[],w=o.split(u);_.length&&(s=w.shift());){var x=indexOf(_,s);-1!==x&&_.splice(x,1)}return this.getAttrs().class=_.join(\" \"),this},HtmlTag.prototype.getClass=function(){return this.getAttrs().class||\"\"},HtmlTag.prototype.hasClass=function(o){return-1!==(\" \"+this.getClass()+\" \").indexOf(\" \"+o+\" \")},HtmlTag.prototype.setInnerHTML=function(o){return this.innerHTML=o,this},HtmlTag.prototype.setInnerHtml=function(o){return this.setInnerHTML(o)},HtmlTag.prototype.getInnerHTML=function(){return this.innerHTML||\"\"},HtmlTag.prototype.getInnerHtml=function(){return this.getInnerHTML()},HtmlTag.prototype.toAnchorString=function(){var o=this.getTagName(),s=this.buildAttrsStr();return[\"<\",o,s=s?\" \"+s:\"\",\">\",this.getInnerHtml(),\"\"].join(\"\")},HtmlTag.prototype.buildAttrsStr=function(){if(!this.attrs)return\"\";var o=this.getAttrs(),s=[];for(var i in o)o.hasOwnProperty(i)&&s.push(i+'=\"'+o[i]+'\"');return s.join(\" \")},HtmlTag}();var wC=function(){function AnchorTagBuilder(o){void 0===o&&(o={}),this.newWindow=!1,this.truncate={},this.className=\"\",this.newWindow=o.newWindow||!1,this.truncate=o.truncate||{},this.className=o.className||\"\"}return AnchorTagBuilder.prototype.build=function(o){return new EC({tagName:\"a\",attrs:this.createAttrs(o),innerHtml:this.processAnchorText(o.getAnchorText())})},AnchorTagBuilder.prototype.createAttrs=function(o){var s={href:o.getAnchorHref()},i=this.createCssClass(o);return i&&(s.class=i),this.newWindow&&(s.target=\"_blank\",s.rel=\"noopener noreferrer\"),this.truncate&&this.truncate.length&&this.truncate.length=w)return x.host.length==s?(x.host.substr(0,s-_)+i).substr(0,w+u):buildSegment(j,w).substr(0,w+u);var L=\"\";if(x.path&&(L+=\"/\"+x.path),x.query&&(L+=\"?\"+x.query),L){if((j+L).length>=w)return(j+L).length==s?(j+L).substr(0,s):(j+buildSegment(L,w-j.length)).substr(0,w+u);j+=L}if(x.fragment){var B=\"#\"+x.fragment;if((j+B).length>=w)return(j+B).length==s?(j+B).substr(0,s):(j+buildSegment(B,w-j.length)).substr(0,w+u);j+=B}if(x.scheme&&x.host){var $=x.scheme+\"://\";if((j+$).length0&&(V=j.substr(-1*Math.floor(w/2))),(j.substr(0,Math.ceil(w/2))+i+V).substr(0,w+u)}(o,i):\"middle\"===u?function truncateMiddle(o,s,i){if(o.length<=s)return o;var u,_;null==i?(i=\"…\",u=8,_=3):(u=i.length,_=i.length);var w=s-_,x=\"\";return w>0&&(x=o.substr(-1*Math.floor(w/2))),(o.substr(0,Math.ceil(w/2))+i+x).substr(0,w+u)}(o,i):function truncateEnd(o,s,i){return function ellipsis(o,s,i){var u;return o.length>s&&(null==i?(i=\"…\",u=3):u=i.length,o=o.substring(0,s-u)+i),o}(o,s,i)}(o,i)},AnchorTagBuilder}(),SC=function(){function Match(o){this.__jsduckDummyDocProp=null,this.matchedText=\"\",this.offset=0,this.tagBuilder=o.tagBuilder,this.matchedText=o.matchedText,this.offset=o.offset}return Match.prototype.getMatchedText=function(){return this.matchedText},Match.prototype.setOffset=function(o){this.offset=o},Match.prototype.getOffset=function(){return this.offset},Match.prototype.getCssClassSuffixes=function(){return[this.getType()]},Match.prototype.buildTag=function(){return this.tagBuilder.build(this)},Match}(),extendStatics=function(o,s){return extendStatics=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(o,s){o.__proto__=s}||function(o,s){for(var i in s)Object.prototype.hasOwnProperty.call(s,i)&&(o[i]=s[i])},extendStatics(o,s)};function tslib_es6_extends(o,s){if(\"function\"!=typeof s&&null!==s)throw new TypeError(\"Class extends value \"+String(s)+\" is not a constructor or null\");function __(){this.constructor=o}extendStatics(o,s),o.prototype=null===s?Object.create(s):(__.prototype=s.prototype,new __)}var __assign=function(){return __assign=Object.assign||function __assign(o){for(var s,i=1,u=arguments.length;i-1},UrlMatchValidator.isValidUriScheme=function(o){var s=o.match(this.uriSchemeRegex),i=s&&s[0].toLowerCase();return\"javascript:\"!==i&&\"vbscript:\"!==i},UrlMatchValidator.urlMatchDoesNotHaveProtocolOrDot=function(o,s){return!(!o||s&&this.hasFullProtocolRegex.test(s)||-1!==o.indexOf(\".\"))},UrlMatchValidator.urlMatchDoesNotHaveAtLeastOneWordChar=function(o,s){return!(!o||!s)&&(!this.hasFullProtocolRegex.test(s)&&!this.hasWordCharAfterProtocolRegex.test(o))},UrlMatchValidator.hasFullProtocolRegex=/^[A-Za-z][-.+A-Za-z0-9]*:\\/\\//,UrlMatchValidator.uriSchemeRegex=/^[A-Za-z][-.+A-Za-z0-9]*:/,UrlMatchValidator.hasWordCharAfterProtocolRegex=new RegExp(\":[^\\\\s]*?[\"+LC+\"]\"),UrlMatchValidator.ipRegex=/[0-9][0-9]?[0-9]?\\.[0-9][0-9]?[0-9]?\\.[0-9][0-9]?[0-9]?\\.[0-9][0-9]?[0-9]?(:[0-9]*)?\\/?$/,UrlMatchValidator}(),QC=(xC=new RegExp(\"[/?#](?:[\"+$C+\"\\\\-+&@#/%=~_()|'$*\\\\[\\\\]{}?!:,.;^✓]*[\"+$C+\"\\\\-+&@#/%=~_()|'$*\\\\[\\\\]{}✓])?\"),new RegExp([\"(?:\",\"(\",/(?:[A-Za-z][-.+A-Za-z0-9]{0,63}:(?![A-Za-z][-.+A-Za-z0-9]{0,63}:\\/\\/)(?!\\d+\\/?)(?:\\/\\/)?)/.source,getDomainNameStr(2),\")\",\"|\",\"(\",\"(//)?\",/(?:www\\.)/.source,getDomainNameStr(6),\")\",\"|\",\"(\",\"(//)?\",getDomainNameStr(10)+\"\\\\.\",KC.source,\"(?![-\"+qC+\"])\",\")\",\")\",\"(?::[0-9]+)?\",\"(?:\"+xC.source+\")?\"].join(\"\"),\"gi\")),ZC=new RegExp(\"[\"+$C+\"]\"),eA=function(o){function UrlMatcher(s){var i=o.call(this,s)||this;return i.stripPrefix={scheme:!0,www:!0},i.stripTrailingSlash=!0,i.decodePercentEncoding=!0,i.matcherRegex=QC,i.wordCharRegExp=ZC,i.stripPrefix=s.stripPrefix,i.stripTrailingSlash=s.stripTrailingSlash,i.decodePercentEncoding=s.decodePercentEncoding,i}return tslib_es6_extends(UrlMatcher,o),UrlMatcher.prototype.parseMatches=function(o){for(var s,i=this.matcherRegex,u=this.stripPrefix,_=this.stripTrailingSlash,w=this.decodePercentEncoding,x=this.tagBuilder,C=[],_loop_1=function(){var i=s[0],L=s[1],B=s[4],$=s[5],V=s[9],U=s.index,z=$||V,Y=o.charAt(U-1);if(!XC.isValid(i,L))return\"continue\";if(U>0&&\"@\"===Y)return\"continue\";if(U>0&&z&&j.wordCharRegExp.test(Y))return\"continue\";if(/\\?$/.test(i)&&(i=i.substr(0,i.length-1)),j.matchHasUnbalancedClosingParen(i))i=i.substr(0,i.length-1);else{var Z=j.matchHasInvalidCharAfterTld(i,L);Z>-1&&(i=i.substr(0,Z))}var ee=[\"http://\",\"https://\"].find((function(o){return!!L&&-1!==L.indexOf(o)}));if(ee){var ie=i.indexOf(ee);i=i.substr(ie),L=L.substr(ie),U+=ie}var ae=L?\"scheme\":B?\"www\":\"tld\",ce=!!L;C.push(new jC({tagBuilder:x,matchedText:i,offset:U,urlMatchType:ae,url:i,protocolUrlMatch:ce,protocolRelativeMatch:!!z,stripPrefix:u,stripTrailingSlash:_,decodePercentEncoding:w}))},j=this;null!==(s=i.exec(o));)_loop_1();return C},UrlMatcher.prototype.matchHasUnbalancedClosingParen=function(o){var s,i=o.charAt(o.length-1);if(\")\"===i)s=\"(\";else if(\"]\"===i)s=\"[\";else{if(\"}\"!==i)return!1;s=\"{\"}for(var u=0,_=0,w=o.length-1;_-1&&w-x<=140){var _=o.slice(x,w),C=new OC({tagBuilder:s,matchedText:_,offset:x,serviceName:i,hashtag:_.slice(1)});u.push(C)}}},HashtagMatcher}(PC),nA=[\"twitter\",\"facebook\",\"instagram\",\"tiktok\"],oA=new RegExp(\"\".concat(/(?:(?:(?:(\\+)?\\d{1,3}[-\\040.]?)?\\(?\\d{3}\\)?[-\\040.]?\\d{3}[-\\040.]?\\d{4})|(?:(\\+)(?:9[976]\\d|8[987530]\\d|6[987]\\d|5[90]\\d|42\\d|3[875]\\d|2[98654321]\\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|4[987654310]|3[9643210]|2[70]|7|1)[-\\040.]?(?:\\d[-\\040.]?){6,12}\\d+))([,;]+[0-9]+#?)*/.source,\"|\").concat(/(0([1-9]{1}-?[1-9]\\d{3}|[1-9]{2}-?\\d{3}|[1-9]{2}\\d{1}-?\\d{2}|[1-9]{2}\\d{2}-?\\d{1})-?\\d{4}|0[789]0-?\\d{4}-?\\d{4}|050-?\\d{4}-?\\d{4})/.source),\"g\"),sA=function(o){function PhoneMatcher(){var s=null!==o&&o.apply(this,arguments)||this;return s.matcherRegex=oA,s}return tslib_es6_extends(PhoneMatcher,o),PhoneMatcher.prototype.parseMatches=function(o){for(var s,i=this.matcherRegex,u=this.tagBuilder,_=[];null!==(s=i.exec(o));){var w=s[0],x=w.replace(/[^0-9,;#]/g,\"\"),C=!(!s[1]&&!s[2]),j=0==s.index?\"\":o.substr(s.index-1,1),L=o.substr(s.index+w.length,1),B=!j.match(/\\d/)&&!L.match(/\\d/);this.testMatch(s[3])&&this.testMatch(w)&&B&&_.push(new AC({tagBuilder:u,matchedText:w,offset:s.index,number:x,plusSign:C}))}return _},PhoneMatcher.prototype.testMatch=function(o){return NC.test(o)},PhoneMatcher}(PC),iA=new RegExp(\"@[_\".concat($C,\"]{1,50}(?![_\").concat($C,\"])\"),\"g\"),aA=new RegExp(\"@[_.\".concat($C,\"]{1,30}(?![_\").concat($C,\"])\"),\"g\"),cA=new RegExp(\"@[-_.\".concat($C,\"]{1,50}(?![-_\").concat($C,\"])\"),\"g\"),lA=new RegExp(\"@[_.\".concat($C,\"]{1,23}[_\").concat($C,\"](?![_\").concat($C,\"])\"),\"g\"),uA=new RegExp(\"[^\"+$C+\"]\"),pA=function(o){function MentionMatcher(s){var i=o.call(this,s)||this;return i.serviceName=\"twitter\",i.matcherRegexes={twitter:iA,instagram:aA,soundcloud:cA,tiktok:lA},i.nonWordCharRegex=uA,i.serviceName=s.serviceName,i}return tslib_es6_extends(MentionMatcher,o),MentionMatcher.prototype.parseMatches=function(o){var s,i=this.serviceName,u=this.matcherRegexes[this.serviceName],_=this.nonWordCharRegex,w=this.tagBuilder,x=[];if(!u)return x;for(;null!==(s=u.exec(o));){var C=s.index,j=o.charAt(C-1);if(0===C||_.test(j)){var L=s[0].replace(/\\.+$/g,\"\"),B=L.slice(1);x.push(new CC({tagBuilder:w,matchedText:L,offset:C,serviceName:i,mention:B}))}}return x},MentionMatcher}(PC);function parseHtml(o,s){for(var i=s.onOpenTag,u=s.onCloseTag,_=s.onText,w=s.onComment,x=s.onDoctype,C=new hA,j=0,L=o.length,B=0,$=0,V=C;j\"===o?(V=new hA(__assign(__assign({},V),{name:captureTagName()})),emitTagAndPreviousTextNode()):IC.test(o)||MC.test(o)||\":\"===o||resetToDataState()}function stateEndTagOpen(o){\">\"===o?resetToDataState():IC.test(o)?B=3:resetToDataState()}function stateBeforeAttributeName(o){TC.test(o)||(\"/\"===o?B=12:\">\"===o?emitTagAndPreviousTextNode():\"<\"===o?startNewTag():\"=\"===o||RC.test(o)||DC.test(o)?resetToDataState():B=5)}function stateAttributeName(o){TC.test(o)?B=6:\"/\"===o?B=12:\"=\"===o?B=7:\">\"===o?emitTagAndPreviousTextNode():\"<\"===o?startNewTag():RC.test(o)&&resetToDataState()}function stateAfterAttributeName(o){TC.test(o)||(\"/\"===o?B=12:\"=\"===o?B=7:\">\"===o?emitTagAndPreviousTextNode():\"<\"===o?startNewTag():RC.test(o)?resetToDataState():B=5)}function stateBeforeAttributeValue(o){TC.test(o)||('\"'===o?B=8:\"'\"===o?B=9:/[>=`]/.test(o)?resetToDataState():\"<\"===o?startNewTag():B=10)}function stateAttributeValueDoubleQuoted(o){'\"'===o&&(B=11)}function stateAttributeValueSingleQuoted(o){\"'\"===o&&(B=11)}function stateAttributeValueUnquoted(o){TC.test(o)?B=4:\">\"===o?emitTagAndPreviousTextNode():\"<\"===o&&startNewTag()}function stateAfterAttributeValueQuoted(o){TC.test(o)?B=4:\"/\"===o?B=12:\">\"===o?emitTagAndPreviousTextNode():\"<\"===o?startNewTag():(B=4,function reconsumeCurrentCharacter(){j--}())}function stateSelfClosingStartTag(o){\">\"===o?(V=new hA(__assign(__assign({},V),{isClosing:!0})),emitTagAndPreviousTextNode()):B=4}function stateMarkupDeclarationOpen(s){\"--\"===o.substr(j,2)?(j+=2,V=new hA(__assign(__assign({},V),{type:\"comment\"})),B=14):\"DOCTYPE\"===o.substr(j,7).toUpperCase()?(j+=7,V=new hA(__assign(__assign({},V),{type:\"doctype\"})),B=20):resetToDataState()}function stateCommentStart(o){\"-\"===o?B=15:\">\"===o?resetToDataState():B=16}function stateCommentStartDash(o){\"-\"===o?B=18:\">\"===o?resetToDataState():B=16}function stateComment(o){\"-\"===o&&(B=17)}function stateCommentEndDash(o){B=\"-\"===o?18:16}function stateCommentEnd(o){\">\"===o?emitTagAndPreviousTextNode():\"!\"===o?B=19:\"-\"===o||(B=16)}function stateCommentEndBang(o){\"-\"===o?B=17:\">\"===o?emitTagAndPreviousTextNode():B=16}function stateDoctype(o){\">\"===o?emitTagAndPreviousTextNode():\"<\"===o&&startNewTag()}function resetToDataState(){B=0,V=C}function startNewTag(){B=1,V=new hA({idx:j})}function emitTagAndPreviousTextNode(){var s=o.slice($,V.idx);s&&_(s,$),\"comment\"===V.type?w(V.idx):\"doctype\"===V.type?x(V.idx):(V.isOpening&&i(V.name,V.idx),V.isClosing&&u(V.name,V.idx)),resetToDataState(),$=j+1}function captureTagName(){var s=V.idx+(V.isClosing?2:1);return o.slice(s,j).toLowerCase()}$=0&&u++},onText:function(o,i){if(0===u){var w=function splitAndCapture(o,s){if(!s.global)throw new Error(\"`splitRegex` must have the 'g' flag set\");for(var i,u=[],_=0;i=s.exec(o);)u.push(o.substring(_,i.index)),u.push(i[0]),_=i.index+i[0].length;return u.push(o.substring(_)),u}(o,/( | |<|<|>|>|"|"|')/gi),x=i;w.forEach((function(o,i){if(i%2==0){var u=s.parseText(o,x);_.push.apply(_,u)}x+=o.length}))}},onCloseTag:function(o){i.indexOf(o)>=0&&(u=Math.max(u-1,0))},onComment:function(o){},onDoctype:function(o){}}),_=this.compactMatches(_),_=this.removeUnwantedMatches(_)},Autolinker.prototype.compactMatches=function(o){o.sort((function(o,s){return o.getOffset()-s.getOffset()}));for(var s=0;s_?s:s+1;o.splice(x,1);continue}if(o[s+1].getOffset()/g,\">\"));for(var s=this.parse(o),i=[],u=0,_=0,w=s.length;_\\s]/i.test(o)}function isLinkClose(o){return/^<\\/a\\s*>/i.test(o)}function createLinkifier(){var o=[],s=new fA({stripPrefix:!1,url:!0,email:!0,replaceFn:function(s){switch(s.getType()){case\"url\":o.push({text:s.matchedText,url:s.getUrl()});break;case\"email\":o.push({text:s.matchedText,url:\"mailto:\"+s.getEmail().replace(/^mailto:/i,\"\")})}return!1}});return{links:o,autolinker:s}}function parseTokens(o){var s,i,u,_,w,x,C,j,L,B,$,V,U,z=o.tokens,Y=null;for(i=0,u=z.length;i=0;s--)if(\"link_close\"!==(w=_[s]).type){if(\"htmltag\"===w.type&&(isLinkOpen(w.content)&&$>0&&$--,isLinkClose(w.content)&&$++),!($>0)&&\"text\"===w.type&&mA.test(w.content)){if(Y||(V=(Y=createLinkifier()).links,U=Y.autolinker),x=w.content,V.length=0,U.link(x),!V.length)continue;for(C=[],B=w.level,j=0;j({useUnsafeMarkdown:!1}))}){if(\"string\"!=typeof o)return null;const u=new Remarkable({html:!0,typographer:!0,breaks:!0,linkTarget:\"_blank\"}).use(linkify);u.core.ruler.disable([\"replacements\",\"smartquotes\"]);const{useUnsafeMarkdown:_}=i(),w=u.render(o),x=sanitizer(w,{useUnsafeMarkdown:_});return o&&w&&x?Pe.createElement(\"div\",{className:To()(s,\"markdown\"),dangerouslySetInnerHTML:{__html:x}}):null};function sanitizer(o,{useUnsafeMarkdown:s=!1}={}){const i=s,u=s?[]:[\"style\",\"class\"];return s&&!sanitizer.hasWarnedAboutDeprecation&&(console.warn(\"useUnsafeMarkdown display configuration parameter is deprecated since >3.26.0 and will be removed in v4.0.0.\"),sanitizer.hasWarnedAboutDeprecation=!0),yA().sanitize(o,{ADD_ATTR:[\"target\"],FORBID_TAGS:[\"style\",\"form\"],ALLOW_DATA_ATTR:i,FORBID_ATTR:u})}sanitizer.hasWarnedAboutDeprecation=!1;class BaseLayout extends Pe.Component{render(){const{errSelectors:o,specSelectors:s,getComponent:i}=this.props,u=i(\"SvgAssets\"),_=i(\"InfoContainer\",!0),w=i(\"VersionPragmaFilter\"),x=i(\"operations\",!0),C=i(\"Models\",!0),j=i(\"Webhooks\",!0),L=i(\"Row\"),B=i(\"Col\"),$=i(\"errors\",!0),V=i(\"ServersContainer\",!0),U=i(\"SchemesContainer\",!0),z=i(\"AuthorizeBtnContainer\",!0),Y=i(\"FilterContainer\",!0),Z=s.isSwagger2(),ee=s.isOAS3(),ie=s.isOAS31(),ae=!s.specStr(),ce=s.loadingStatus();let le=null;if(\"loading\"===ce&&(le=Pe.createElement(\"div\",{className:\"info\"},Pe.createElement(\"div\",{className:\"loading-container\"},Pe.createElement(\"div\",{className:\"loading\"})))),\"failed\"===ce&&(le=Pe.createElement(\"div\",{className:\"info\"},Pe.createElement(\"div\",{className:\"loading-container\"},Pe.createElement(\"h4\",{className:\"title\"},\"Failed to load API definition.\"),Pe.createElement($,null)))),\"failedConfig\"===ce){const s=o.lastError(),i=s?s.get(\"message\"):\"\";le=Pe.createElement(\"div\",{className:\"info failed-config\"},Pe.createElement(\"div\",{className:\"loading-container\"},Pe.createElement(\"h4\",{className:\"title\"},\"Failed to load remote configuration.\"),Pe.createElement(\"p\",null,i)))}if(!le&&ae&&(le=Pe.createElement(\"h4\",null,\"No API definition provided.\")),le)return Pe.createElement(\"div\",{className:\"swagger-ui\"},Pe.createElement(\"div\",{className:\"loading-container\"},le));const pe=s.servers(),de=s.schemes(),fe=pe&&pe.size,ye=de&&de.size,be=!!s.securityDefinitions();return Pe.createElement(\"div\",{className:\"swagger-ui\"},Pe.createElement(u,null),Pe.createElement(w,{isSwagger2:Z,isOAS3:ee,alsoShow:Pe.createElement($,null)},Pe.createElement($,null),Pe.createElement(L,{className:\"information-container\"},Pe.createElement(B,{mobile:12},Pe.createElement(_,null))),fe||ye||be?Pe.createElement(\"div\",{className:\"scheme-container\"},Pe.createElement(B,{className:\"schemes wrapper\",mobile:12},fe||ye?Pe.createElement(\"div\",{className:\"schemes-server-container\"},fe?Pe.createElement(V,null):null,ye?Pe.createElement(U,null):null):null,be?Pe.createElement(z,null):null)):null,Pe.createElement(Y,null),Pe.createElement(L,null,Pe.createElement(B,{mobile:12,desktop:12},Pe.createElement(x,null))),ie&&Pe.createElement(L,{className:\"webhooks-container\"},Pe.createElement(B,{mobile:12,desktop:12},Pe.createElement(j,null))),Pe.createElement(L,null,Pe.createElement(B,{mobile:12,desktop:12},Pe.createElement(C,null)))))}}const core_components=()=>({components:{App:wO,authorizationPopup:AuthorizationPopup,authorizeBtn:AuthorizeBtn,AuthorizeBtnContainer,authorizeOperationBtn:AuthorizeOperationBtn,auths:Auths,AuthItem:auth_item_Auths,authError:AuthError,oauth2:Oauth2,apiKeyAuth:ApiKeyAuth,basicAuth:BasicAuth,clear:Clear,liveResponse:LiveResponse,InitializedInput,info:IO,InfoContainer,InfoUrl,InfoBasePath,Contact:MO,License:NO,JumpToPath,CopyToClipboardBtn,onlineValidatorBadge:OnlineValidatorBadge,operations:Operations,operation:operation_Operation,OperationSummary,OperationSummaryMethod,OperationSummaryPath,responses:responses_Responses,response:response_Response,ResponseExtension:response_extension,responseBody:ResponseBody,parameters:Parameters,parameterRow:ParameterRow,execute:Execute,headers:headers_Headers,errors:Errors,contentType:ContentType,overview:Overview,footer:Footer,FilterContainer,ParamBody,curl:Curl,Property:property,TryItOutButton,Markdown:vA,BaseLayout,VersionPragmaFilter,VersionStamp:version_stamp,OperationExt:operation_extensions,OperationExtRow:operation_extension_row,ParameterExt:parameter_extension,ParameterIncludeEmpty,OperationTag,OperationContainer,OpenAPIVersion:openapi_version,DeepLink:deep_link,SvgAssets:svg_assets,Example:example_Example,ExamplesSelect,ExamplesSelectValueRetainer}}),form_components=()=>({components:{...ye}}),base=()=>[configsPlugin,util,logs,view,view_legacy,plugins_spec,err,icons,plugins_layout,json_schema_5,json_schema_5_samples,core_components,form_components,swagger_client,auth,downloadUrlPlugin,deep_linking,filter,on_complete,plugins_request_snippets,syntax_highlighting,versions,safe_render()],bA=(0,qe.Map)();function onlyOAS3(o){return(s,i)=>(...u)=>{if(i.getSystem().specSelectors.isOAS3()){const s=o(...u);return\"function\"==typeof s?s(i):s}return s(...u)}}const _A=onlyOAS3(us()(null)),EA=onlyOAS3(((o,s)=>o=>o.getSystem().specSelectors.findSchema(s))),wA=onlyOAS3((()=>o=>{const s=o.getSystem().specSelectors.specJson().getIn([\"components\",\"schemas\"]);return qe.Map.isMap(s)?s:bA})),SA=onlyOAS3((()=>o=>o.getSystem().specSelectors.specJson().hasIn([\"servers\",0]))),xA=onlyOAS3(Wt(bs,(o=>o.getIn([\"components\",\"securitySchemes\"])||null))),wrap_selectors_validOperationMethods=(o,s)=>(i,...u)=>s.specSelectors.isOAS3()?s.oas3Selectors.validOperationMethods():o(...u),kA=_A,OA=_A,CA=_A,AA=_A,jA=_A;const PA=function wrap_selectors_onlyOAS3(o){return(s,i)=>(...u)=>{if(i.getSystem().specSelectors.isOAS3()){let s=i.getState().getIn([\"spec\",\"resolvedSubtrees\",\"components\",\"securitySchemes\"]);return o(i,s,...u)}return s(...u)}}(Wt((o=>o),(({specSelectors:o})=>o.securityDefinitions()),((o,s)=>{let i=(0,qe.List)();return s?(s.entrySeq().forEach((([o,s])=>{const u=s.get(\"type\");if(\"oauth2\"===u&&s.get(\"flows\").entrySeq().forEach((([u,_])=>{let w=(0,qe.fromJS)({flow:u,authorizationUrl:_.get(\"authorizationUrl\"),tokenUrl:_.get(\"tokenUrl\"),scopes:_.get(\"scopes\"),type:s.get(\"type\"),description:s.get(\"description\")});i=i.push(new qe.Map({[o]:w.filter((o=>void 0!==o))}))})),\"http\"!==u&&\"apiKey\"!==u||(i=i.push(new qe.Map({[o]:s}))),\"openIdConnect\"===u&&s.get(\"openIdConnectData\")){let u=s.get(\"openIdConnectData\");(u.get(\"grant_types_supported\")||[\"authorization_code\",\"implicit\"]).forEach((_=>{let w=u.get(\"scopes_supported\")&&u.get(\"scopes_supported\").reduce(((o,s)=>o.set(s,\"\")),new qe.Map),x=(0,qe.fromJS)({flow:_,authorizationUrl:u.get(\"authorization_endpoint\"),tokenUrl:u.get(\"token_endpoint\"),scopes:w,type:\"oauth2\",openIdConnectUrl:s.get(\"openIdConnectUrl\")});i=i.push(new qe.Map({[o]:x.filter((o=>void 0!==o))}))}))}})),i):i})));function OAS3ComponentWrapFactory(o){return(s,i)=>u=>\"function\"==typeof i.specSelectors?.isOAS3?i.specSelectors.isOAS3()?Pe.createElement(o,wo()({},u,i,{Ori:s})):Pe.createElement(s,u):(console.warn(\"OAS3 wrapper: couldn't get spec\"),null)}const IA=(0,qe.Map)(),selectors_isSwagger2=()=>o=>function isSwagger2(o){const s=o.get(\"swagger\");return\"string\"==typeof s&&\"2.0\"===s}(o.getSystem().specSelectors.specJson()),selectors_isOAS30=()=>o=>function isOAS30(o){const s=o.get(\"openapi\");return\"string\"==typeof s&&/^3\\.0\\.([0123])(?:-rc[012])?$/.test(s)}(o.getSystem().specSelectors.specJson()),selectors_isOAS3=()=>o=>o.getSystem().specSelectors.isOAS30();function selectors_onlyOAS3(o){return(s,...i)=>u=>{if(u.specSelectors.isOAS3()){const _=o(s,...i);return\"function\"==typeof _?_(u):_}return null}}const MA=selectors_onlyOAS3((()=>o=>o.specSelectors.specJson().get(\"servers\",IA))),findSchema=(o,s)=>{const i=o.getIn([\"resolvedSubtrees\",\"components\",\"schemas\",s],null),u=o.getIn([\"json\",\"components\",\"schemas\",s],null);return i||u||null},NA=selectors_onlyOAS3(((o,{callbacks:s,specPath:i})=>o=>{const u=o.specSelectors.validOperationMethods();return qe.Map.isMap(s)?s.reduce(((o,s,_)=>{if(!qe.Map.isMap(s))return o;const w=s.reduce(((o,s,w)=>{if(!qe.Map.isMap(s))return o;const x=s.entrySeq().filter((([o])=>u.includes(o))).map((([o,s])=>({operation:(0,qe.Map)({operation:s}),method:o,path:w,callbackName:_,specPath:i.concat([_,w,o])})));return o.concat(x)}),(0,qe.List)());return o.concat(w)}),(0,qe.List)()).groupBy((o=>o.callbackName)).map((o=>o.toArray())).toObject():{}})),callbacks=({callbacks:o,specPath:s,specSelectors:i,getComponent:u})=>{const _=i.callbacksOperations({callbacks:o,specPath:s}),w=Object.keys(_),x=u(\"OperationContainer\",!0);return 0===w.length?Pe.createElement(\"span\",null,\"No callbacks\"):Pe.createElement(\"div\",null,w.map((o=>Pe.createElement(\"div\",{key:`${o}`},Pe.createElement(\"h2\",null,o),_[o].map((s=>Pe.createElement(x,{key:`${o}-${s.path}-${s.method}`,op:s.operation,tag:\"callbacks\",method:s.method,path:s.path,specPath:s.specPath,allowTryItOut:!1})))))))},getDefaultRequestBodyValue=(o,s,i,u)=>{const _=o.getIn([\"content\",s])??(0,qe.OrderedMap)(),w=_.get(\"schema\",(0,qe.OrderedMap)()).toJS(),x=void 0!==_.get(\"examples\"),C=_.get(\"example\"),j=x?_.getIn([\"examples\",i,\"value\"]):C;return stringify(u.getSampleSchema(w,s,{includeWriteOnly:!0},j))},components_request_body=({userHasEditedBody:o,requestBody:s,requestBodyValue:i,requestBodyInclusionSetting:u,requestBodyErrors:_,getComponent:w,getConfigs:x,specSelectors:C,fn:j,contentType:L,isExecute:B,specPath:$,onChange:V,onChangeIncludeEmpty:U,activeExamplesKey:z,updateActiveExamplesKey:Y,setRetainRequestBodyValueFlag:Z})=>{const handleFile=o=>{V(o.target.files[0])},setIsIncludedOptions=o=>{let s={key:o,shouldDispatchInit:!1,defaultValue:!0};return\"no value\"===u.get(o,\"no value\")&&(s.shouldDispatchInit=!0),s},ee=w(\"Markdown\",!0),ie=w(\"modelExample\"),ae=w(\"RequestBodyEditor\"),ce=w(\"HighlightCode\",!0),le=w(\"ExamplesSelectValueRetainer\"),pe=w(\"Example\"),de=w(\"ParameterIncludeEmpty\"),{showCommonExtensions:fe}=x(),ye=s?.get(\"description\")??null,be=s?.get(\"content\")??new qe.OrderedMap;L=L||be.keySeq().first()||\"\";const _e=be.get(L)??(0,qe.OrderedMap)(),we=_e.get(\"schema\",(0,qe.OrderedMap)()),Se=_e.get(\"examples\",null),xe=Se?.map(((o,i)=>{const u=o?.get(\"value\",null);return u&&(o=o.set(\"value\",getDefaultRequestBodyValue(s,L,i,j),u)),o}));if(_=qe.List.isList(_)?_:(0,qe.List)(),!_e.size)return null;const Te=\"object\"===_e.getIn([\"schema\",\"type\"]),Re=\"binary\"===_e.getIn([\"schema\",\"format\"]),$e=\"base64\"===_e.getIn([\"schema\",\"format\"]);if(\"application/octet-stream\"===L||0===L.indexOf(\"image/\")||0===L.indexOf(\"audio/\")||0===L.indexOf(\"video/\")||Re||$e){const o=w(\"Input\");return B?Pe.createElement(o,{type:\"file\",onChange:handleFile}):Pe.createElement(\"i\",null,\"Example values are not available for \",Pe.createElement(\"code\",null,L),\" media types.\")}if(Te&&(\"application/x-www-form-urlencoded\"===L||0===L.indexOf(\"multipart/\"))&&we.get(\"properties\",(0,qe.OrderedMap)()).size>0){const o=w(\"JsonSchemaForm\"),s=w(\"ParameterExt\"),x=we.get(\"properties\",(0,qe.OrderedMap)());return i=qe.Map.isMap(i)?i:(0,qe.OrderedMap)(),Pe.createElement(\"div\",{className:\"table-container\"},ye&&Pe.createElement(ee,{source:ye}),Pe.createElement(\"table\",null,Pe.createElement(\"tbody\",null,qe.Map.isMap(x)&&x.entrySeq().map((([x,C])=>{if(C.get(\"readOnly\"))return;const L=C.get(\"oneOf\")?.get(0)?.toJS(),$=C.get(\"anyOf\")?.get(0)?.toJS();C=(0,qe.fromJS)(j.mergeJsonSchema(C.toJS(),L??$??{}));let z=fe?getCommonExtensions(C):null;const Y=we.get(\"required\",(0,qe.List)()).includes(x),Z=C.get(\"type\"),ie=C.get(\"format\"),ae=C.get(\"description\"),ce=i.getIn([x,\"value\"]),le=i.getIn([x,\"errors\"])||_,pe=u.get(x)||!1;let ye=j.getSampleSchema(C,!1,{includeWriteOnly:!0});!1===ye&&(ye=\"false\"),0===ye&&(ye=\"0\"),\"string\"!=typeof ye&&\"object\"===Z&&(ye=stringify(ye)),\"string\"==typeof ye&&\"array\"===Z&&(ye=JSON.parse(ye));const be=\"string\"===Z&&(\"binary\"===ie||\"base64\"===ie);return Pe.createElement(\"tr\",{key:x,className:\"parameters\",\"data-property-name\":x},Pe.createElement(\"td\",{className:\"parameters-col_name\"},Pe.createElement(\"div\",{className:Y?\"parameter__name required\":\"parameter__name\"},x,Y?Pe.createElement(\"span\",null,\" *\"):null),Pe.createElement(\"div\",{className:\"parameter__type\"},Z,ie&&Pe.createElement(\"span\",{className:\"prop-format\"},\"($\",ie,\")\"),fe&&z.size?z.entrySeq().map((([o,i])=>Pe.createElement(s,{key:`${o}-${i}`,xKey:o,xVal:i}))):null),Pe.createElement(\"div\",{className:\"parameter__deprecated\"},C.get(\"deprecated\")?\"deprecated\":null)),Pe.createElement(\"td\",{className:\"parameters-col_description\"},Pe.createElement(ee,{source:ae}),B?Pe.createElement(\"div\",null,Pe.createElement(o,{fn:j,dispatchInitialValue:!be,schema:C,description:x,getComponent:w,value:void 0===ce?ye:ce,required:Y,errors:le,onChange:o=>{V(o,[x])}}),Y?null:Pe.createElement(de,{onChange:o=>U(x,o),isIncluded:pe,isIncludedOptions:setIsIncludedOptions(x),isDisabled:Array.isArray(ce)?0!==ce.length:!isEmptyValue(ce)})):null))})))))}const ze=getDefaultRequestBodyValue(s,L,z,j);let We=null;return getKnownSyntaxHighlighterLanguage(ze)&&(We=\"json\"),Pe.createElement(\"div\",null,ye&&Pe.createElement(ee,{source:ye}),xe?Pe.createElement(le,{userHasEditedBody:o,examples:xe,currentKey:z,currentUserInputValue:i,onSelect:o=>{Y(o)},updateValue:V,defaultToFirstExample:!0,getComponent:w,setRetainRequestBodyValueFlag:Z}):null,B?Pe.createElement(\"div\",null,Pe.createElement(ae,{value:i,errors:_,defaultValue:ze,onChange:V,getComponent:w})):Pe.createElement(ie,{getComponent:w,getConfigs:x,specSelectors:C,expandDepth:1,isExecute:B,schema:_e.get(\"schema\"),specPath:$.push(\"content\",L),example:Pe.createElement(ce,{className:\"body-param__example\",language:We},stringify(i)||ze),includeWriteOnly:!0}),xe?Pe.createElement(pe,{example:xe.get(z),getComponent:w,getConfigs:x}):null)};class operation_link_OperationLink extends Pe.Component{render(){const{link:o,name:s,getComponent:i}=this.props,u=i(\"Markdown\",!0);let _=o.get(\"operationId\")||o.get(\"operationRef\"),w=o.get(\"parameters\")&&o.get(\"parameters\").toJS(),x=o.get(\"description\");return Pe.createElement(\"div\",{className:\"operation-link\"},Pe.createElement(\"div\",{className:\"description\"},Pe.createElement(\"b\",null,Pe.createElement(\"code\",null,s)),x?Pe.createElement(u,{source:x}):null),Pe.createElement(\"pre\",null,\"Operation `\",_,\"`\",Pe.createElement(\"br\",null),Pe.createElement(\"br\",null),\"Parameters \",function padString(o,s){if(\"string\"!=typeof s)return\"\";return s.split(\"\\n\").map(((s,i)=>i>0?Array(o+1).join(\" \")+s:s)).join(\"\\n\")}(0,JSON.stringify(w,null,2))||\"{}\",Pe.createElement(\"br\",null)))}}const TA=operation_link_OperationLink,components_servers=({servers:o,currentServer:s,setSelectedServer:i,setServerVariableValue:u,getServerVariable:_,getEffectiveServerValue:w})=>{const x=(o.find((o=>o.get(\"url\")===s))||(0,qe.OrderedMap)()).get(\"variables\")||(0,qe.OrderedMap)(),C=0!==x.size;(0,Pe.useEffect)((()=>{s||i(o.first()?.get(\"url\"))}),[]),(0,Pe.useEffect)((()=>{const _=o.find((o=>o.get(\"url\")===s));if(!_)return void i(o.first().get(\"url\"));(_.get(\"variables\")||(0,qe.OrderedMap)()).map(((o,i)=>{u({server:s,key:i,val:o.get(\"default\")||\"\"})}))}),[s,o]);const j=(0,Pe.useCallback)((o=>{i(o.target.value)}),[i]),L=(0,Pe.useCallback)((o=>{const i=o.target.getAttribute(\"data-variable\"),_=o.target.value;u({server:s,key:i,val:_})}),[u,s]);return Pe.createElement(\"div\",{className:\"servers\"},Pe.createElement(\"label\",{htmlFor:\"servers\"},Pe.createElement(\"select\",{onChange:j,value:s,id:\"servers\"},o.valueSeq().map((o=>Pe.createElement(\"option\",{value:o.get(\"url\"),key:o.get(\"url\")},o.get(\"url\"),o.get(\"description\")&&` - ${o.get(\"description\")}`))).toArray())),C&&Pe.createElement(\"div\",null,Pe.createElement(\"div\",{className:\"computed-url\"},\"Computed URL:\",Pe.createElement(\"code\",null,w(s))),Pe.createElement(\"h4\",null,\"Server variables\"),Pe.createElement(\"table\",null,Pe.createElement(\"tbody\",null,x.entrySeq().map((([o,i])=>Pe.createElement(\"tr\",{key:o},Pe.createElement(\"td\",null,o),Pe.createElement(\"td\",null,i.get(\"enum\")?Pe.createElement(\"select\",{\"data-variable\":o,onChange:L},i.get(\"enum\").map((i=>Pe.createElement(\"option\",{selected:i===_(s,o),key:i,value:i},i)))):Pe.createElement(\"input\",{type:\"text\",value:_(s,o)||\"\",onChange:L,\"data-variable\":o})))))))))};class ServersContainer extends Pe.Component{render(){const{specSelectors:o,oas3Selectors:s,oas3Actions:i,getComponent:u}=this.props,_=o.servers(),w=u(\"Servers\");return _&&_.size?Pe.createElement(\"div\",null,Pe.createElement(\"span\",{className:\"servers-title\"},\"Servers\"),Pe.createElement(w,{servers:_,currentServer:s.selectedServer(),setSelectedServer:i.setSelectedServer,setServerVariableValue:i.setServerVariableValue,getServerVariable:s.serverVariableValue,getEffectiveServerValue:s.serverEffectiveValue})):null}}const RA=Function.prototype;class RequestBodyEditor extends Pe.PureComponent{static defaultProps={onChange:RA,userHasEditedBody:!1};constructor(o,s){super(o,s),this.state={value:stringify(o.value)||o.defaultValue},o.onChange(o.value)}applyDefaultValue=o=>{const{onChange:s,defaultValue:i}=o||this.props;return this.setState({value:i}),s(i)};onChange=o=>{this.props.onChange(stringify(o))};onDomChange=o=>{const s=o.target.value;this.setState({value:s},(()=>this.onChange(s)))};UNSAFE_componentWillReceiveProps(o){this.props.value!==o.value&&o.value!==this.state.value&&this.setState({value:stringify(o.value)}),!o.value&&o.defaultValue&&this.state.value&&this.applyDefaultValue(o)}render(){let{getComponent:o,errors:s}=this.props,{value:i}=this.state,u=s.size>0;const _=o(\"TextArea\");return Pe.createElement(\"div\",{className:\"body-param\"},Pe.createElement(_,{className:To()(\"body-param__text\",{invalid:u}),title:s.size?s.join(\", \"):\"\",value:i,onChange:this.onDomChange}))}}class HttpAuth extends Pe.Component{constructor(o,s){super(o,s);let{name:i,schema:u}=this.props,_=this.getValue();this.state={name:i,schema:u,value:_}}getValue(){let{name:o,authorized:s}=this.props;return s&&s.getIn([o,\"value\"])}onChange=o=>{let{onChange:s}=this.props,{value:i,name:u}=o.target,_=Object.assign({},this.state.value);u?_[u]=i:_=i,this.setState({value:_},(()=>s(this.state)))};render(){let{schema:o,getComponent:s,errSelectors:i,name:u}=this.props;const _=s(\"Input\"),w=s(\"Row\"),x=s(\"Col\"),C=s(\"authError\"),j=s(\"Markdown\",!0),L=s(\"JumpToPath\",!0),B=(o.get(\"scheme\")||\"\").toLowerCase();let $=this.getValue(),V=i.allErrors().filter((o=>o.get(\"authId\")===u));if(\"basic\"===B){let s=$?$.get(\"username\"):null;return Pe.createElement(\"div\",null,Pe.createElement(\"h4\",null,Pe.createElement(\"code\",null,u||o.get(\"name\")),\"  (http, Basic)\",Pe.createElement(L,{path:[\"securityDefinitions\",u]})),s&&Pe.createElement(\"h6\",null,\"Authorized\"),Pe.createElement(w,null,Pe.createElement(j,{source:o.get(\"description\")})),Pe.createElement(w,null,Pe.createElement(\"label\",{htmlFor:\"auth-basic-username\"},\"Username:\"),s?Pe.createElement(\"code\",null,\" \",s,\" \"):Pe.createElement(x,null,Pe.createElement(_,{id:\"auth-basic-username\",type:\"text\",required:\"required\",name:\"username\",\"aria-label\":\"auth-basic-username\",onChange:this.onChange,autoFocus:!0}))),Pe.createElement(w,null,Pe.createElement(\"label\",{htmlFor:\"auth-basic-password\"},\"Password:\"),s?Pe.createElement(\"code\",null,\" ****** \"):Pe.createElement(x,null,Pe.createElement(_,{id:\"auth-basic-password\",autoComplete:\"new-password\",name:\"password\",type:\"password\",\"aria-label\":\"auth-basic-password\",onChange:this.onChange}))),V.valueSeq().map(((o,s)=>Pe.createElement(C,{error:o,key:s}))))}return\"bearer\"===B?Pe.createElement(\"div\",null,Pe.createElement(\"h4\",null,Pe.createElement(\"code\",null,u||o.get(\"name\")),\"  (http, Bearer)\",Pe.createElement(L,{path:[\"securityDefinitions\",u]})),$&&Pe.createElement(\"h6\",null,\"Authorized\"),Pe.createElement(w,null,Pe.createElement(j,{source:o.get(\"description\")})),Pe.createElement(w,null,Pe.createElement(\"label\",{htmlFor:\"auth-bearer-value\"},\"Value:\"),$?Pe.createElement(\"code\",null,\" ****** \"):Pe.createElement(x,null,Pe.createElement(_,{id:\"auth-bearer-value\",type:\"text\",\"aria-label\":\"auth-bearer-value\",onChange:this.onChange,autoFocus:!0}))),V.valueSeq().map(((o,s)=>Pe.createElement(C,{error:o,key:s})))):Pe.createElement(\"div\",null,Pe.createElement(\"em\",null,Pe.createElement(\"b\",null,u),\" HTTP authentication: unsupported scheme \",`'${B}'`))}}class operation_servers_OperationServers extends Pe.Component{setSelectedServer=o=>{const{path:s,method:i}=this.props;return this.forceUpdate(),this.props.setSelectedServer(o,`${s}:${i}`)};setServerVariableValue=o=>{const{path:s,method:i}=this.props;return this.forceUpdate(),this.props.setServerVariableValue({...o,namespace:`${s}:${i}`})};getSelectedServer=()=>{const{path:o,method:s}=this.props;return this.props.getSelectedServer(`${o}:${s}`)};getServerVariable=(o,s)=>{const{path:i,method:u}=this.props;return this.props.getServerVariable({namespace:`${i}:${u}`,server:o},s)};getEffectiveServerValue=o=>{const{path:s,method:i}=this.props;return this.props.getEffectiveServerValue({server:o,namespace:`${s}:${i}`})};render(){const{operationServers:o,pathServers:s,getComponent:i}=this.props;if(!o&&!s)return null;const u=i(\"Servers\"),_=o||s,w=o?\"operation\":\"path\";return Pe.createElement(\"div\",{className:\"opblock-section operation-servers\"},Pe.createElement(\"div\",{className:\"opblock-section-header\"},Pe.createElement(\"div\",{className:\"tab-header\"},Pe.createElement(\"h4\",{className:\"opblock-title\"},\"Servers\"))),Pe.createElement(\"div\",{className:\"opblock-description-wrapper\"},Pe.createElement(\"h4\",{className:\"message\"},\"These \",w,\"-level options override the global server options.\"),Pe.createElement(u,{servers:_,currentServer:this.getSelectedServer(),setSelectedServer:this.setSelectedServer,setServerVariableValue:this.setServerVariableValue,getServerVariable:this.getServerVariable,getEffectiveServerValue:this.getEffectiveServerValue})))}}const DA={Callbacks:callbacks,HttpAuth,RequestBody:components_request_body,Servers:components_servers,ServersContainer,RequestBodyEditor,OperationServers:operation_servers_OperationServers,operationLink:TA},LA=new Remarkable(\"commonmark\");LA.block.ruler.enable([\"table\"]),LA.set({linkTarget:\"_blank\"});const BA=OAS3ComponentWrapFactory((({source:o,className:s=\"\",getConfigs:i=(()=>({useUnsafeMarkdown:!1}))})=>{if(\"string\"!=typeof o)return null;if(o){const{useUnsafeMarkdown:u}=i(),_=sanitizer(LA.render(o),{useUnsafeMarkdown:u});let w;return\"string\"==typeof _&&(w=_.trim()),Pe.createElement(\"div\",{dangerouslySetInnerHTML:{__html:w},className:To()(s,\"renderedMarkdown\")})}return null})),FA=OAS3ComponentWrapFactory((({Ori:o,...s})=>{const{schema:i,getComponent:u,errSelectors:_,authorized:w,onAuthChange:x,name:C}=s,j=u(\"HttpAuth\");return\"http\"===i.get(\"type\")?Pe.createElement(j,{key:C,schema:i,name:C,errSelectors:_,authorized:w,getComponent:u,onChange:x}):Pe.createElement(o,s)})),qA=OAS3ComponentWrapFactory(OnlineValidatorBadge);class ModelComponent extends Pe.Component{render(){let{getConfigs:o,schema:s,Ori:i}=this.props,u=[\"model-box\"],_=null;return!0===s.get(\"deprecated\")&&(u.push(\"deprecated\"),_=Pe.createElement(\"span\",{className:\"model-deprecated-warning\"},\"Deprecated:\")),Pe.createElement(\"div\",{className:u.join(\" \")},_,Pe.createElement(i,wo()({},this.props,{getConfigs:o,depth:1,expandDepth:this.props.expandDepth||0})))}}const $A=OAS3ComponentWrapFactory(ModelComponent),VA=OAS3ComponentWrapFactory((({Ori:o,...s})=>{const{schema:i,getComponent:u,errors:_,onChange:w}=s,x=i&&i.get?i.get(\"format\"):null,C=i&&i.get?i.get(\"type\"):null,j=u(\"Input\");return C&&\"string\"===C&&x&&(\"binary\"===x||\"base64\"===x)?Pe.createElement(j,{type:\"file\",className:_.length?\"invalid\":\"\",title:_.length?_:\"\",onChange:o=>{w(o.target.files[0])},disabled:o.isDisabled}):Pe.createElement(o,s)})),UA={Markdown:BA,AuthItem:FA,OpenAPIVersion:function OAS30ComponentWrapFactory(o){return(s,i)=>u=>\"function\"==typeof i.specSelectors?.isOAS30?i.specSelectors.isOAS30()?Pe.createElement(o,wo()({},u,i,{Ori:s})):Pe.createElement(s,u):(console.warn(\"OAS30 wrapper: couldn't get spec\"),null)}((o=>{const{Ori:s}=o;return Pe.createElement(s,{oasVersion:\"3.0\"})})),JsonSchema_string:VA,model:$A,onlineValidatorBadge:qA},zA=\"oas3_set_servers\",WA=\"oas3_set_request_body_value\",KA=\"oas3_set_request_body_retain_flag\",HA=\"oas3_set_request_body_inclusion\",JA=\"oas3_set_active_examples_member\",GA=\"oas3_set_request_content_type\",YA=\"oas3_set_response_content_type\",XA=\"oas3_set_server_variable_value\",QA=\"oas3_set_request_body_validate_error\",ZA=\"oas3_clear_request_body_validate_error\",ej=\"oas3_clear_request_body_value\";function setSelectedServer(o,s){return{type:zA,payload:{selectedServerUrl:o,namespace:s}}}function setRequestBodyValue({value:o,pathMethod:s}){return{type:WA,payload:{value:o,pathMethod:s}}}const setRetainRequestBodyValueFlag=({value:o,pathMethod:s})=>({type:KA,payload:{value:o,pathMethod:s}});function setRequestBodyInclusion({value:o,pathMethod:s,name:i}){return{type:HA,payload:{value:o,pathMethod:s,name:i}}}function setActiveExamplesMember({name:o,pathMethod:s,contextType:i,contextName:u}){return{type:JA,payload:{name:o,pathMethod:s,contextType:i,contextName:u}}}function setRequestContentType({value:o,pathMethod:s}){return{type:GA,payload:{value:o,pathMethod:s}}}function setResponseContentType({value:o,path:s,method:i}){return{type:YA,payload:{value:o,path:s,method:i}}}function setServerVariableValue({server:o,namespace:s,key:i,val:u}){return{type:XA,payload:{server:o,namespace:s,key:i,val:u}}}const setRequestBodyValidateError=({path:o,method:s,validationErrors:i})=>({type:QA,payload:{path:o,method:s,validationErrors:i}}),clearRequestBodyValidateError=({path:o,method:s})=>({type:ZA,payload:{path:o,method:s}}),initRequestBodyValidateError=({pathMethod:o})=>({type:ZA,payload:{path:o[0],method:o[1]}}),clearRequestBodyValue=({pathMethod:o})=>({type:ej,payload:{pathMethod:o}});var fj=__webpack_require__(60680),mj=__webpack_require__.n(fj);const oas3_selectors_onlyOAS3=o=>(s,...i)=>u=>{if(u.getSystem().specSelectors.isOAS3()){const _=o(s,...i);return\"function\"==typeof _?_(u):_}return null};const _j=oas3_selectors_onlyOAS3(((o,s)=>{const i=s?[s,\"selectedServer\"]:[\"selectedServer\"];return o.getIn(i)||\"\"})),Cj=oas3_selectors_onlyOAS3(((o,s,i)=>o.getIn([\"requestData\",s,i,\"bodyValue\"])||null)),Aj=oas3_selectors_onlyOAS3(((o,s,i)=>o.getIn([\"requestData\",s,i,\"retainBodyValue\"])||!1)),selectDefaultRequestBodyValue=(o,s,i)=>o=>{const{oas3Selectors:u,specSelectors:_,fn:w}=o.getSystem();if(_.isOAS3()){const o=u.requestContentType(s,i);if(o)return getDefaultRequestBodyValue(_.specResolvedSubtree([\"paths\",s,i,\"requestBody\"]),o,u.activeExamplesMember(s,i,\"requestBody\",\"requestBody\"),w)}return null},Nj=oas3_selectors_onlyOAS3(((o,s,i)=>o=>{const{oas3Selectors:u,specSelectors:_,fn:w}=o;let x=!1;const C=u.requestContentType(s,i);let j=u.requestBodyValue(s,i);const L=_.specResolvedSubtree([\"paths\",s,i,\"requestBody\"]);if(!L)return!1;if(qe.Map.isMap(j)&&(j=stringify(j.mapEntries((o=>qe.Map.isMap(o[1])?[o[0],o[1].get(\"value\")]:o)).toJS())),qe.List.isList(j)&&(j=stringify(j)),C){const o=getDefaultRequestBodyValue(L,C,u.activeExamplesMember(s,i,\"requestBody\",\"requestBody\"),w);x=!!j&&j!==o}return x})),Bj=oas3_selectors_onlyOAS3(((o,s,i)=>o.getIn([\"requestData\",s,i,\"bodyInclusion\"])||(0,qe.Map)())),$j=oas3_selectors_onlyOAS3(((o,s,i)=>o.getIn([\"requestData\",s,i,\"errors\"])||null)),zj=oas3_selectors_onlyOAS3(((o,s,i,u,_)=>o.getIn([\"examples\",s,i,u,_,\"activeExample\"])||null)),Kj=oas3_selectors_onlyOAS3(((o,s,i)=>o.getIn([\"requestData\",s,i,\"requestContentType\"])||null)),Jj=oas3_selectors_onlyOAS3(((o,s,i)=>o.getIn([\"requestData\",s,i,\"responseContentType\"])||null)),Gj=oas3_selectors_onlyOAS3(((o,s,i)=>{let u;if(\"string\"!=typeof s){const{server:o,namespace:_}=s;u=_?[_,\"serverVariableValues\",o,i]:[\"serverVariableValues\",o,i]}else{u=[\"serverVariableValues\",s,i]}return o.getIn(u)||null})),Xj=oas3_selectors_onlyOAS3(((o,s)=>{let i;if(\"string\"!=typeof s){const{server:o,namespace:u}=s;i=u?[u,\"serverVariableValues\",o]:[\"serverVariableValues\",o]}else{i=[\"serverVariableValues\",s]}return o.getIn(i)||(0,qe.OrderedMap)()})),eP=oas3_selectors_onlyOAS3(((o,s)=>{var i,u;if(\"string\"!=typeof s){const{server:_,namespace:w}=s;u=_,i=w?o.getIn([w,\"serverVariableValues\",u]):o.getIn([\"serverVariableValues\",u])}else u=s,i=o.getIn([\"serverVariableValues\",u]);i=i||(0,qe.OrderedMap)();let _=u;return i.map(((o,s)=>{_=_.replace(new RegExp(`{${mj()(s)}}`,\"g\"),o)})),_})),tP=function validateRequestBodyIsRequired(o){return(...s)=>i=>{const u=i.getSystem().specSelectors.specJson();let _=[...s][1]||[];return!u.getIn([\"paths\",..._,\"requestBody\",\"required\"])||o(...s)}}(((o,s)=>((o,s)=>(s=s||[],!!o.getIn([\"requestData\",...s,\"bodyValue\"])))(o,s))),validateShallowRequired=(o,{oas3RequiredRequestBodyContentType:s,oas3RequestContentType:i,oas3RequestBodyValue:u})=>{let _=[];if(!qe.Map.isMap(u))return _;let w=[];return Object.keys(s.requestContentType).forEach((o=>{if(o===i){s.requestContentType[o].forEach((o=>{w.indexOf(o)<0&&w.push(o)}))}})),w.forEach((o=>{u.getIn([o,\"value\"])||_.push(o)})),_},rP=us()([\"get\",\"put\",\"post\",\"delete\",\"options\",\"head\",\"patch\",\"trace\"]),nP={[zA]:(o,{payload:{selectedServerUrl:s,namespace:i}})=>{const u=i?[i,\"selectedServer\"]:[\"selectedServer\"];return o.setIn(u,s)},[WA]:(o,{payload:{value:s,pathMethod:i}})=>{let[u,_]=i;if(!qe.Map.isMap(s))return o.setIn([\"requestData\",u,_,\"bodyValue\"],s);let w,x=o.getIn([\"requestData\",u,_,\"bodyValue\"])||(0,qe.Map)();qe.Map.isMap(x)||(x=(0,qe.Map)());const[...C]=s.keys();return C.forEach((o=>{let i=s.getIn([o]);x.has(o)&&qe.Map.isMap(i)||(w=x.setIn([o,\"value\"],i))})),o.setIn([\"requestData\",u,_,\"bodyValue\"],w)},[KA]:(o,{payload:{value:s,pathMethod:i}})=>{let[u,_]=i;return o.setIn([\"requestData\",u,_,\"retainBodyValue\"],s)},[HA]:(o,{payload:{value:s,pathMethod:i,name:u}})=>{let[_,w]=i;return o.setIn([\"requestData\",_,w,\"bodyInclusion\",u],s)},[JA]:(o,{payload:{name:s,pathMethod:i,contextType:u,contextName:_}})=>{let[w,x]=i;return o.setIn([\"examples\",w,x,u,_,\"activeExample\"],s)},[GA]:(o,{payload:{value:s,pathMethod:i}})=>{let[u,_]=i;return o.setIn([\"requestData\",u,_,\"requestContentType\"],s)},[YA]:(o,{payload:{value:s,path:i,method:u}})=>o.setIn([\"requestData\",i,u,\"responseContentType\"],s),[XA]:(o,{payload:{server:s,namespace:i,key:u,val:_}})=>{const w=i?[i,\"serverVariableValues\",s,u]:[\"serverVariableValues\",s,u];return o.setIn(w,_)},[QA]:(o,{payload:{path:s,method:i,validationErrors:u}})=>{let _=[];if(_.push(\"Required field is not provided\"),u.missingBodyValue)return o.setIn([\"requestData\",s,i,\"errors\"],(0,qe.fromJS)(_));if(u.missingRequiredKeys&&u.missingRequiredKeys.length>0){const{missingRequiredKeys:w}=u;return o.updateIn([\"requestData\",s,i,\"bodyValue\"],(0,qe.fromJS)({}),(o=>w.reduce(((o,s)=>o.setIn([s,\"errors\"],(0,qe.fromJS)(_))),o)))}return console.warn(\"unexpected result: SET_REQUEST_BODY_VALIDATE_ERROR\"),o},[ZA]:(o,{payload:{path:s,method:i}})=>{const u=o.getIn([\"requestData\",s,i,\"bodyValue\"]);if(!qe.Map.isMap(u))return o.setIn([\"requestData\",s,i,\"errors\"],(0,qe.fromJS)([]));const[..._]=u.keys();return _?o.updateIn([\"requestData\",s,i,\"bodyValue\"],(0,qe.fromJS)({}),(o=>_.reduce(((o,s)=>o.setIn([s,\"errors\"],(0,qe.fromJS)([]))),o))):o},[ej]:(o,{payload:{pathMethod:s}})=>{let[i,u]=s;const _=o.getIn([\"requestData\",i,u,\"bodyValue\"]);return _?qe.Map.isMap(_)?o.setIn([\"requestData\",i,u,\"bodyValue\"],(0,qe.Map)()):o.setIn([\"requestData\",i,u,\"bodyValue\"],\"\"):o}};function oas3(){return{components:DA,wrapComponents:UA,statePlugins:{spec:{wrapSelectors:be,selectors:we},auth:{wrapSelectors:_e},oas3:{actions:{...Se},reducers:nP,selectors:{...xe}}}}}const webhooks=({specSelectors:o,getComponent:s})=>{const i=o.selectWebhooksOperations(),u=Object.keys(i),_=s(\"OperationContainer\",!0);return 0===u.length?null:Pe.createElement(\"div\",{className:\"webhooks\"},Pe.createElement(\"h2\",null,\"Webhooks\"),u.map((o=>Pe.createElement(\"div\",{key:`${o}-webhook`},i[o].map((s=>Pe.createElement(_,{key:`${o}-${s.method}-webhook`,op:s.operation,tag:\"webhooks\",method:s.method,path:o,specPath:(0,qe.List)(s.specPath),allowTryItOut:!1})))))))},oas31_components_license=({getComponent:o,specSelectors:s})=>{const i=s.selectLicenseNameField(),u=s.selectLicenseUrl(),_=o(\"Link\");return Pe.createElement(\"div\",{className:\"info__license\"},u?Pe.createElement(\"div\",{className:\"info__license__url\"},Pe.createElement(_,{target:\"_blank\",href:sanitizeUrl(u)},i)):Pe.createElement(\"span\",null,i))},oas31_components_contact=({getComponent:o,specSelectors:s})=>{const i=s.selectContactNameField(),u=s.selectContactUrl(),_=s.selectContactEmailField(),w=o(\"Link\");return Pe.createElement(\"div\",{className:\"info__contact\"},u&&Pe.createElement(\"div\",null,Pe.createElement(w,{href:sanitizeUrl(u),target:\"_blank\"},i,\" - Website\")),_&&Pe.createElement(w,{href:sanitizeUrl(`mailto:${_}`)},u?`Send email to ${i}`:`Contact ${i}`))},oas31_components_info=({getComponent:o,specSelectors:s})=>{const i=s.version(),u=s.url(),_=s.basePath(),w=s.host(),x=s.selectInfoSummaryField(),C=s.selectInfoDescriptionField(),j=s.selectInfoTitleField(),L=s.selectInfoTermsOfServiceUrl(),B=s.selectExternalDocsUrl(),$=s.selectExternalDocsDescriptionField(),V=s.contact(),U=s.license(),z=o(\"Markdown\",!0),Y=o(\"Link\"),Z=o(\"VersionStamp\"),ee=o(\"OpenAPIVersion\"),ie=o(\"InfoUrl\"),ae=o(\"InfoBasePath\"),ce=o(\"License\",!0),le=o(\"Contact\",!0),pe=o(\"JsonSchemaDialect\",!0);return Pe.createElement(\"div\",{className:\"info\"},Pe.createElement(\"hgroup\",{className:\"main\"},Pe.createElement(\"h2\",{className:\"title\"},j,Pe.createElement(\"span\",null,i&&Pe.createElement(Z,{version:i}),Pe.createElement(ee,{oasVersion:\"3.1\"}))),(w||_)&&Pe.createElement(ae,{host:w,basePath:_}),u&&Pe.createElement(ie,{getComponent:o,url:u})),x&&Pe.createElement(\"p\",{className:\"info__summary\"},x),Pe.createElement(\"div\",{className:\"info__description description\"},Pe.createElement(z,{source:C})),L&&Pe.createElement(\"div\",{className:\"info__tos\"},Pe.createElement(Y,{target:\"_blank\",href:sanitizeUrl(L)},\"Terms of service\")),V.size>0&&Pe.createElement(le,null),U.size>0&&Pe.createElement(ce,null),B&&Pe.createElement(Y,{className:\"info__extdocs\",target:\"_blank\",href:sanitizeUrl(B)},$||B),Pe.createElement(pe,null))},json_schema_dialect=({getComponent:o,specSelectors:s})=>{const i=s.selectJsonSchemaDialectField(),u=s.selectJsonSchemaDialectDefault(),_=o(\"Link\");return Pe.createElement(Pe.Fragment,null,i&&i===u&&Pe.createElement(\"p\",{className:\"info__jsonschemadialect\"},\"JSON Schema dialect:\",\" \",Pe.createElement(_,{target:\"_blank\",href:sanitizeUrl(i)},i)),i&&i!==u&&Pe.createElement(\"div\",{className:\"error-wrapper\"},Pe.createElement(\"div\",{className:\"no-margin\"},Pe.createElement(\"div\",{className:\"errors\"},Pe.createElement(\"div\",{className:\"errors-wrapper\"},Pe.createElement(\"h4\",{className:\"center\"},\"Warning\"),Pe.createElement(\"p\",{className:\"message\"},Pe.createElement(\"strong\",null,\"OpenAPI.jsonSchemaDialect\"),\" field contains a value different from the default value of\",\" \",Pe.createElement(_,{target:\"_blank\",href:u},u),\". Values different from the default one are currently not supported. Please either omit the field or provide it with the default value.\"))))))},version_pragma_filter=({bypass:o,isSwagger2:s,isOAS3:i,isOAS31:u,alsoShow:_,children:w})=>o?Pe.createElement(\"div\",null,w):s&&(i||u)?Pe.createElement(\"div\",{className:\"version-pragma\"},_,Pe.createElement(\"div\",{className:\"version-pragma__message version-pragma__message--ambiguous\"},Pe.createElement(\"div\",null,Pe.createElement(\"h3\",null,\"Unable to render this definition\"),Pe.createElement(\"p\",null,Pe.createElement(\"code\",null,\"swagger\"),\" and \",Pe.createElement(\"code\",null,\"openapi\"),\" fields cannot be present in the same Swagger or OpenAPI definition. Please remove one of the fields.\"),Pe.createElement(\"p\",null,\"Supported version fields are \",Pe.createElement(\"code\",null,'swagger: \"2.0\"'),\" and those that match \",Pe.createElement(\"code\",null,\"openapi: 3.x.y\"),\" (for example,\",\" \",Pe.createElement(\"code\",null,\"openapi: 3.1.0\"),\").\")))):s||i||u?Pe.createElement(\"div\",null,w):Pe.createElement(\"div\",{className:\"version-pragma\"},_,Pe.createElement(\"div\",{className:\"version-pragma__message version-pragma__message--missing\"},Pe.createElement(\"div\",null,Pe.createElement(\"h3\",null,\"Unable to render this definition\"),Pe.createElement(\"p\",null,\"The provided definition does not specify a valid version field.\"),Pe.createElement(\"p\",null,\"Please indicate a valid Swagger or OpenAPI version field. Supported version fields are \",Pe.createElement(\"code\",null,'swagger: \"2.0\"'),\" and those that match \",Pe.createElement(\"code\",null,\"openapi: 3.x.y\"),\" (for example,\",\" \",Pe.createElement(\"code\",null,\"openapi: 3.1.0\"),\").\")))),getModelName=o=>\"string\"==typeof o&&o.includes(\"#/components/schemas/\")?(o=>{const s=o.replace(/~1/g,\"/\").replace(/~0/g,\"~\");try{return decodeURIComponent(s)}catch{return s}})(o.replace(/^.*#\\/components\\/schemas\\//,\"\")):null,oP=(0,Pe.forwardRef)((({schema:o,getComponent:s,onToggle:i=(()=>{})},u)=>{const _=s(\"JSONSchema202012\"),w=getModelName(o.get(\"$$ref\")),x=(0,Pe.useCallback)(((o,s)=>{i(w,s)}),[w,i]);return Pe.createElement(_,{name:w,schema:o.toJS(),ref:u,onExpand:x})})),sP=oP,models=({specActions:o,specSelectors:s,layoutSelectors:i,layoutActions:u,getComponent:_,getConfigs:w,fn:x})=>{const C=s.selectSchemas(),j=Object.keys(C).length>0,L=[\"components\",\"schemas\"],{docExpansion:B,defaultModelsExpandDepth:$}=w(),V=$>0&&\"none\"!==B,U=i.isShown(L,V),z=_(\"Collapse\"),Y=_(\"JSONSchema202012\"),Z=_(\"ArrowUpIcon\"),ee=_(\"ArrowDownIcon\"),{getTitle:ie}=x.jsonSchema202012.useFn();(0,Pe.useEffect)((()=>{const i=U&&$>1,u=null!=s.specResolvedSubtree(L);i&&!u&&o.requestResolvedSubtree(L)}),[U,$]);const ae=(0,Pe.useCallback)((()=>{u.show(L,!U)}),[U]),ce=(0,Pe.useCallback)((o=>{null!==o&&u.readyToScroll(L,o)}),[]),handleJSONSchema202012Ref=o=>s=>{null!==s&&u.readyToScroll([...L,o],s)},handleJSONSchema202012Expand=i=>(u,_)=>{if(_){const u=[...L,i];null!=s.specResolvedSubtree(u)||o.requestResolvedSubtree([...L,i])}};return!j||$<0?null:Pe.createElement(\"section\",{className:To()(\"models\",{\"is-open\":U}),ref:ce},Pe.createElement(\"h4\",null,Pe.createElement(\"button\",{\"aria-expanded\":U,className:\"models-control\",onClick:ae},Pe.createElement(\"span\",null,\"Schemas\"),U?Pe.createElement(Z,null):Pe.createElement(ee,null))),Pe.createElement(z,{isOpened:U},Object.entries(C).map((([o,s])=>{const i=ie(s,{lookup:\"basic\"})||o;return Pe.createElement(Y,{key:o,ref:handleJSONSchema202012Ref(o),schema:s,name:i,onExpand:handleJSONSchema202012Expand(o)})}))))},mutual_tls_auth=({schema:o,getComponent:s})=>{const i=s(\"JumpToPath\",!0);return Pe.createElement(\"div\",null,Pe.createElement(\"h4\",null,o.get(\"name\"),\" (mutualTLS)\",\" \",Pe.createElement(i,{path:[\"securityDefinitions\",o.get(\"name\")]})),Pe.createElement(\"p\",null,\"Mutual TLS is required by this API/Operation. Certificates are managed via your Operating System and/or your browser.\"),Pe.createElement(\"p\",null,o.get(\"description\")))};class auths_Auths extends Pe.Component{constructor(o,s){super(o,s),this.state={}}onAuthChange=o=>{let{name:s}=o;this.setState({[s]:o})};submitAuth=o=>{o.preventDefault();let{authActions:s}=this.props;s.authorizeWithPersistOption(this.state)};logoutClick=o=>{o.preventDefault();let{authActions:s,definitions:i}=this.props,u=i.map(((o,s)=>s)).toArray();this.setState(u.reduce(((o,s)=>(o[s]=\"\",o)),{})),s.logoutWithPersistOption(u)};close=o=>{o.preventDefault();let{authActions:s}=this.props;s.showDefinitions(!1)};render(){let{definitions:o,getComponent:s,authSelectors:i,errSelectors:u}=this.props;const _=s(\"AuthItem\"),w=s(\"oauth2\",!0),x=s(\"Button\"),C=i.authorized(),j=o.filter(((o,s)=>!!C.get(s))),L=o.filter((o=>\"oauth2\"!==o.get(\"type\")&&\"mutualTLS\"!==o.get(\"type\"))),B=o.filter((o=>\"oauth2\"===o.get(\"type\"))),$=o.filter((o=>\"mutualTLS\"===o.get(\"type\")));return Pe.createElement(\"div\",{className:\"auth-container\"},L.size>0&&Pe.createElement(\"form\",{onSubmit:this.submitAuth},L.map(((o,i)=>Pe.createElement(_,{key:i,schema:o,name:i,getComponent:s,onAuthChange:this.onAuthChange,authorized:C,errSelectors:u}))).toArray(),Pe.createElement(\"div\",{className:\"auth-btn-wrapper\"},L.size===j.size?Pe.createElement(x,{className:\"btn modal-btn auth\",onClick:this.logoutClick,\"aria-label\":\"Remove authorization\"},\"Logout\"):Pe.createElement(x,{type:\"submit\",className:\"btn modal-btn auth authorize\",\"aria-label\":\"Apply credentials\"},\"Authorize\"),Pe.createElement(x,{className:\"btn modal-btn auth btn-done\",onClick:this.close},\"Close\"))),B.size>0?Pe.createElement(\"div\",null,Pe.createElement(\"div\",{className:\"scope-def\"},Pe.createElement(\"p\",null,\"Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.\"),Pe.createElement(\"p\",null,\"API requires the following scopes. Select which ones you want to grant to Swagger UI.\")),o.filter((o=>\"oauth2\"===o.get(\"type\"))).map(((o,s)=>Pe.createElement(\"div\",{key:s},Pe.createElement(w,{authorized:C,schema:o,name:s})))).toArray()):null,$.size>0&&Pe.createElement(\"div\",null,$.map(((o,i)=>Pe.createElement(_,{key:i,schema:o,name:i,getComponent:s,onAuthChange:this.onAuthChange,authorized:C,errSelectors:u}))).toArray()))}}const iP=auths_Auths,isOAS31=o=>{const s=o.get(\"openapi\");return\"string\"==typeof s&&/^3\\.1\\.(?:[1-9]\\d*|0)$/.test(s)},fn_createOnlyOAS31Selector=o=>(s,...i)=>u=>{if(u.getSystem().specSelectors.isOAS31()){const _=o(s,...i);return\"function\"==typeof _?_(u):_}return null},createOnlyOAS31SelectorWrapper=o=>(s,i)=>(u,..._)=>{if(i.getSystem().specSelectors.isOAS31()){const w=o(u,..._);return\"function\"==typeof w?w(s,i):w}return s(..._)},fn_createSystemSelector=o=>(s,...i)=>u=>{const _=o(s,u,...i);return\"function\"==typeof _?_(u):_},createOnlyOAS31ComponentWrapper=o=>(s,i)=>u=>i.specSelectors.isOAS31()?Pe.createElement(o,wo()({},u,{originalComponent:s,getSystem:i.getSystem})):Pe.createElement(s,u),aP=createOnlyOAS31ComponentWrapper((({getSystem:o})=>{const s=o().getComponent(\"OAS31License\",!0);return Pe.createElement(s,null)})),cP=createOnlyOAS31ComponentWrapper((({getSystem:o})=>{const s=o().getComponent(\"OAS31Contact\",!0);return Pe.createElement(s,null)})),lP=createOnlyOAS31ComponentWrapper((({getSystem:o})=>{const s=o().getComponent(\"OAS31Info\",!0);return Pe.createElement(s,null)})),uP=createOnlyOAS31ComponentWrapper((({getSystem:o,...s})=>{const i=o(),{getComponent:u,fn:_,getConfigs:w}=i,x=w(),C=u(\"OAS31Model\"),j=u(\"JSONSchema202012\"),L=u(\"JSONSchema202012Keyword$schema\"),B=u(\"JSONSchema202012Keyword$vocabulary\"),$=u(\"JSONSchema202012Keyword$id\"),V=u(\"JSONSchema202012Keyword$anchor\"),U=u(\"JSONSchema202012Keyword$dynamicAnchor\"),z=u(\"JSONSchema202012Keyword$ref\"),Y=u(\"JSONSchema202012Keyword$dynamicRef\"),Z=u(\"JSONSchema202012Keyword$defs\"),ee=u(\"JSONSchema202012Keyword$comment\"),ie=u(\"JSONSchema202012KeywordAllOf\"),ae=u(\"JSONSchema202012KeywordAnyOf\"),ce=u(\"JSONSchema202012KeywordOneOf\"),le=u(\"JSONSchema202012KeywordNot\"),pe=u(\"JSONSchema202012KeywordIf\"),de=u(\"JSONSchema202012KeywordThen\"),fe=u(\"JSONSchema202012KeywordElse\"),ye=u(\"JSONSchema202012KeywordDependentSchemas\"),be=u(\"JSONSchema202012KeywordPrefixItems\"),_e=u(\"JSONSchema202012KeywordItems\"),we=u(\"JSONSchema202012KeywordContains\"),Se=u(\"JSONSchema202012KeywordProperties\"),xe=u(\"JSONSchema202012KeywordPatternProperties\"),Te=u(\"JSONSchema202012KeywordAdditionalProperties\"),Re=u(\"JSONSchema202012KeywordPropertyNames\"),qe=u(\"JSONSchema202012KeywordUnevaluatedItems\"),$e=u(\"JSONSchema202012KeywordUnevaluatedProperties\"),ze=u(\"JSONSchema202012KeywordType\"),We=u(\"JSONSchema202012KeywordEnum\"),He=u(\"JSONSchema202012KeywordConst\"),Ye=u(\"JSONSchema202012KeywordConstraint\"),Xe=u(\"JSONSchema202012KeywordDependentRequired\"),Qe=u(\"JSONSchema202012KeywordContentSchema\"),et=u(\"JSONSchema202012KeywordTitle\"),tt=u(\"JSONSchema202012KeywordDescription\"),rt=u(\"JSONSchema202012KeywordDefault\"),nt=u(\"JSONSchema202012KeywordDeprecated\"),ot=u(\"JSONSchema202012KeywordReadOnly\"),st=u(\"JSONSchema202012KeywordWriteOnly\"),it=u(\"JSONSchema202012Accordion\"),at=u(\"JSONSchema202012ExpandDeepButton\"),ct=u(\"JSONSchema202012ChevronRightIcon\"),lt=u(\"withJSONSchema202012Context\")(C,{config:{default$schema:\"https://spec.openapis.org/oas/3.1/dialect/base\",defaultExpandedLevels:x.defaultModelExpandDepth,includeReadOnly:Boolean(s.includeReadOnly),includeWriteOnly:Boolean(s.includeWriteOnly)},components:{JSONSchema:j,Keyword$schema:L,Keyword$vocabulary:B,Keyword$id:$,Keyword$anchor:V,Keyword$dynamicAnchor:U,Keyword$ref:z,Keyword$dynamicRef:Y,Keyword$defs:Z,Keyword$comment:ee,KeywordAllOf:ie,KeywordAnyOf:ae,KeywordOneOf:ce,KeywordNot:le,KeywordIf:pe,KeywordThen:de,KeywordElse:fe,KeywordDependentSchemas:ye,KeywordPrefixItems:be,KeywordItems:_e,KeywordContains:we,KeywordProperties:Se,KeywordPatternProperties:xe,KeywordAdditionalProperties:Te,KeywordPropertyNames:Re,KeywordUnevaluatedItems:qe,KeywordUnevaluatedProperties:$e,KeywordType:ze,KeywordEnum:We,KeywordConst:He,KeywordConstraint:Ye,KeywordDependentRequired:Xe,KeywordContentSchema:Qe,KeywordTitle:et,KeywordDescription:tt,KeywordDefault:rt,KeywordDeprecated:nt,KeywordReadOnly:ot,KeywordWriteOnly:st,Accordion:it,ExpandDeepButton:at,ChevronRightIcon:ct},fn:{upperFirst:_.upperFirst,isExpandable:_.jsonSchema202012.isExpandable,getProperties:_.jsonSchema202012.getProperties}});return Pe.createElement(lt,s)})),pP=uP,hP=createOnlyOAS31ComponentWrapper((({getSystem:o})=>{const{getComponent:s,fn:i,getConfigs:u}=o(),_=u();if(hP.ModelsWithJSONSchemaContext)return Pe.createElement(hP.ModelsWithJSONSchemaContext,null);const w=s(\"OAS31Models\",!0),x=s(\"JSONSchema202012\"),C=s(\"JSONSchema202012Keyword$schema\"),j=s(\"JSONSchema202012Keyword$vocabulary\"),L=s(\"JSONSchema202012Keyword$id\"),B=s(\"JSONSchema202012Keyword$anchor\"),$=s(\"JSONSchema202012Keyword$dynamicAnchor\"),V=s(\"JSONSchema202012Keyword$ref\"),U=s(\"JSONSchema202012Keyword$dynamicRef\"),z=s(\"JSONSchema202012Keyword$defs\"),Y=s(\"JSONSchema202012Keyword$comment\"),Z=s(\"JSONSchema202012KeywordAllOf\"),ee=s(\"JSONSchema202012KeywordAnyOf\"),ie=s(\"JSONSchema202012KeywordOneOf\"),ae=s(\"JSONSchema202012KeywordNot\"),ce=s(\"JSONSchema202012KeywordIf\"),le=s(\"JSONSchema202012KeywordThen\"),pe=s(\"JSONSchema202012KeywordElse\"),de=s(\"JSONSchema202012KeywordDependentSchemas\"),fe=s(\"JSONSchema202012KeywordPrefixItems\"),ye=s(\"JSONSchema202012KeywordItems\"),be=s(\"JSONSchema202012KeywordContains\"),_e=s(\"JSONSchema202012KeywordProperties\"),we=s(\"JSONSchema202012KeywordPatternProperties\"),Se=s(\"JSONSchema202012KeywordAdditionalProperties\"),xe=s(\"JSONSchema202012KeywordPropertyNames\"),Te=s(\"JSONSchema202012KeywordUnevaluatedItems\"),Re=s(\"JSONSchema202012KeywordUnevaluatedProperties\"),qe=s(\"JSONSchema202012KeywordType\"),$e=s(\"JSONSchema202012KeywordEnum\"),ze=s(\"JSONSchema202012KeywordConst\"),We=s(\"JSONSchema202012KeywordConstraint\"),He=s(\"JSONSchema202012KeywordDependentRequired\"),Ye=s(\"JSONSchema202012KeywordContentSchema\"),Xe=s(\"JSONSchema202012KeywordTitle\"),Qe=s(\"JSONSchema202012KeywordDescription\"),et=s(\"JSONSchema202012KeywordDefault\"),tt=s(\"JSONSchema202012KeywordDeprecated\"),rt=s(\"JSONSchema202012KeywordReadOnly\"),nt=s(\"JSONSchema202012KeywordWriteOnly\"),ot=s(\"JSONSchema202012Accordion\"),st=s(\"JSONSchema202012ExpandDeepButton\"),it=s(\"JSONSchema202012ChevronRightIcon\"),at=s(\"withJSONSchema202012Context\");return hP.ModelsWithJSONSchemaContext=at(w,{config:{default$schema:\"https://spec.openapis.org/oas/3.1/dialect/base\",defaultExpandedLevels:_.defaultModelsExpandDepth-1,includeReadOnly:!0,includeWriteOnly:!0},components:{JSONSchema:x,Keyword$schema:C,Keyword$vocabulary:j,Keyword$id:L,Keyword$anchor:B,Keyword$dynamicAnchor:$,Keyword$ref:V,Keyword$dynamicRef:U,Keyword$defs:z,Keyword$comment:Y,KeywordAllOf:Z,KeywordAnyOf:ee,KeywordOneOf:ie,KeywordNot:ae,KeywordIf:ce,KeywordThen:le,KeywordElse:pe,KeywordDependentSchemas:de,KeywordPrefixItems:fe,KeywordItems:ye,KeywordContains:be,KeywordProperties:_e,KeywordPatternProperties:we,KeywordAdditionalProperties:Se,KeywordPropertyNames:xe,KeywordUnevaluatedItems:Te,KeywordUnevaluatedProperties:Re,KeywordType:qe,KeywordEnum:$e,KeywordConst:ze,KeywordConstraint:We,KeywordDependentRequired:He,KeywordContentSchema:Ye,KeywordTitle:Xe,KeywordDescription:Qe,KeywordDefault:et,KeywordDeprecated:tt,KeywordReadOnly:rt,KeywordWriteOnly:nt,Accordion:ot,ExpandDeepButton:st,ChevronRightIcon:it},fn:{upperFirst:i.upperFirst,isExpandable:i.jsonSchema202012.isExpandable,getProperties:i.jsonSchema202012.getProperties}}),Pe.createElement(hP.ModelsWithJSONSchemaContext,null)}));hP.ModelsWithJSONSchemaContext=null;const dP=hP,wrap_components_version_pragma_filter=(o,s)=>o=>{const i=s.specSelectors.isOAS31(),u=s.getComponent(\"OAS31VersionPragmaFilter\");return Pe.createElement(u,wo()({isOAS31:i},o))},fP=createOnlyOAS31ComponentWrapper((({originalComponent:o,...s})=>{const{getComponent:i,schema:u}=s,_=i(\"MutualTLSAuth\",!0);return\"mutualTLS\"===u.get(\"type\")?Pe.createElement(_,{schema:u}):Pe.createElement(o,s)})),mP=fP,gP=createOnlyOAS31ComponentWrapper((({getSystem:o,...s})=>{const i=o().getComponent(\"OAS31Auths\",!0);return Pe.createElement(i,s)})),yP=(0,qe.Map)(),vP=Wt(((o,s)=>s.specSelectors.specJson()),isOAS31),selectors_webhooks=()=>o=>{const s=o.specSelectors.specJson().get(\"webhooks\");return qe.Map.isMap(s)?s:yP},bP=Wt([(o,s)=>s.specSelectors.webhooks(),(o,s)=>s.specSelectors.validOperationMethods(),(o,s)=>s.specSelectors.specResolvedSubtree([\"webhooks\"])],((o,s)=>o.reduce(((o,i,u)=>{if(!qe.Map.isMap(i))return o;const _=i.entrySeq().filter((([o])=>s.includes(o))).map((([o,s])=>({operation:(0,qe.Map)({operation:s}),method:o,path:u,specPath:[\"webhooks\",u,o]})));return o.concat(_)}),(0,qe.List)()).groupBy((o=>o.path)).map((o=>o.toArray())).toObject())),selectors_license=()=>o=>{const s=o.specSelectors.info().get(\"license\");return qe.Map.isMap(s)?s:yP},selectLicenseNameField=()=>o=>o.specSelectors.license().get(\"name\",\"License\"),selectLicenseUrlField=()=>o=>o.specSelectors.license().get(\"url\"),_P=Wt([(o,s)=>s.specSelectors.url(),(o,s)=>s.oas3Selectors.selectedServer(),(o,s)=>s.specSelectors.selectLicenseUrlField()],((o,s,i)=>{if(i)return safeBuildUrl(i,o,{selectedServer:s})})),selectLicenseIdentifierField=()=>o=>o.specSelectors.license().get(\"identifier\"),selectors_contact=()=>o=>{const s=o.specSelectors.info().get(\"contact\");return qe.Map.isMap(s)?s:yP},selectContactNameField=()=>o=>o.specSelectors.contact().get(\"name\",\"the developer\"),selectContactEmailField=()=>o=>o.specSelectors.contact().get(\"email\"),selectContactUrlField=()=>o=>o.specSelectors.contact().get(\"url\"),EP=Wt([(o,s)=>s.specSelectors.url(),(o,s)=>s.oas3Selectors.selectedServer(),(o,s)=>s.specSelectors.selectContactUrlField()],((o,s,i)=>{if(i)return safeBuildUrl(i,o,{selectedServer:s})})),selectInfoTitleField=()=>o=>o.specSelectors.info().get(\"title\"),selectInfoSummaryField=()=>o=>o.specSelectors.info().get(\"summary\"),selectInfoDescriptionField=()=>o=>o.specSelectors.info().get(\"description\"),selectInfoTermsOfServiceField=()=>o=>o.specSelectors.info().get(\"termsOfService\"),wP=Wt([(o,s)=>s.specSelectors.url(),(o,s)=>s.oas3Selectors.selectedServer(),(o,s)=>s.specSelectors.selectInfoTermsOfServiceField()],((o,s,i)=>{if(i)return safeBuildUrl(i,o,{selectedServer:s})})),selectExternalDocsDescriptionField=()=>o=>o.specSelectors.externalDocs().get(\"description\"),selectExternalDocsUrlField=()=>o=>o.specSelectors.externalDocs().get(\"url\"),SP=Wt([(o,s)=>s.specSelectors.url(),(o,s)=>s.oas3Selectors.selectedServer(),(o,s)=>s.specSelectors.selectExternalDocsUrlField()],((o,s,i)=>{if(i)return safeBuildUrl(i,o,{selectedServer:s})})),selectJsonSchemaDialectField=()=>o=>o.specSelectors.specJson().get(\"jsonSchemaDialect\"),selectJsonSchemaDialectDefault=()=>\"https://spec.openapis.org/oas/3.1/dialect/base\",xP=Wt(((o,s)=>s.specSelectors.definitions()),((o,s)=>s.specSelectors.specResolvedSubtree([\"components\",\"schemas\"])),((o,s)=>qe.Map.isMap(o)?qe.Map.isMap(s)?Object.entries(o.toJS()).reduce(((o,[i,u])=>{const _=s.get(i);return o[i]=_?.toJS()||u,o}),{}):o.toJS():{})),wrap_selectors_isOAS3=(o,s)=>(i,...u)=>s.specSelectors.isOAS31()||o(...u),kP=createOnlyOAS31SelectorWrapper((()=>(o,s)=>s.oas31Selectors.selectLicenseUrl())),OP=createOnlyOAS31SelectorWrapper((()=>(o,s)=>{const i=s.specSelectors.securityDefinitions();let u=o();return i?(i.entrySeq().forEach((([o,s])=>{\"mutualTLS\"===s.get(\"type\")&&(u=u.push(new qe.Map({[o]:s})))})),u):u})),CP=Wt([(o,s)=>s.specSelectors.url(),(o,s)=>s.oas3Selectors.selectedServer(),(o,s)=>s.specSelectors.selectLicenseUrlField(),(o,s)=>s.specSelectors.selectLicenseIdentifierField()],((o,s,i,u)=>i?safeBuildUrl(i,o,{selectedServer:s}):u?`https://spdx.org/licenses/${u}.html`:void 0)),keywords_Example=({schema:o,getSystem:s})=>{const{fn:i}=s(),{hasKeyword:u,stringify:_}=i.jsonSchema202012.useFn();return u(o,\"example\")?Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--example\"},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary\"},\"Example\"),Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--const\"},_(o.example))):null},keywords_Xml=({schema:o,getSystem:s})=>{const i=o?.xml||{},{fn:u,getComponent:_}=s(),{useIsExpandedDeeply:w,useComponent:x}=u.jsonSchema202012,C=w(),j=!!(i.name||i.namespace||i.prefix),[L,B]=(0,Pe.useState)(C),[$,V]=(0,Pe.useState)(!1),U=x(\"Accordion\"),z=x(\"ExpandDeepButton\"),Y=_(\"JSONSchema202012DeepExpansionContext\")(),Z=(0,Pe.useCallback)((()=>{B((o=>!o))}),[]),ee=(0,Pe.useCallback)(((o,s)=>{B(s),V(s)}),[]);return 0===Object.keys(i).length?null:Pe.createElement(Y.Provider,{value:$},Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--xml\"},j?Pe.createElement(Pe.Fragment,null,Pe.createElement(U,{expanded:L,onChange:Z},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary\"},\"XML\")),Pe.createElement(z,{expanded:L,onClick:ee})):Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary\"},\"XML\"),!0===i.attribute&&Pe.createElement(\"span\",{className:\"json-schema-2020-12__attribute json-schema-2020-12__attribute--muted\"},\"attribute\"),!0===i.wrapped&&Pe.createElement(\"span\",{className:\"json-schema-2020-12__attribute json-schema-2020-12__attribute--muted\"},\"wrapped\"),Pe.createElement(\"strong\",{className:\"json-schema-2020-12__attribute json-schema-2020-12__attribute--primary\"},\"object\"),Pe.createElement(\"ul\",{className:To()(\"json-schema-2020-12-keyword__children\",{\"json-schema-2020-12-keyword__children--collapsed\":!L})},L&&Pe.createElement(Pe.Fragment,null,i.name&&Pe.createElement(\"li\",{className:\"json-schema-2020-12-property\"},Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword\"},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary\"},\"name\"),Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary\"},i.name))),i.namespace&&Pe.createElement(\"li\",{className:\"json-schema-2020-12-property\"},Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword\"},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary\"},\"namespace\"),Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary\"},i.namespace))),i.prefix&&Pe.createElement(\"li\",{className:\"json-schema-2020-12-property\"},Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword\"},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary\"},\"prefix\"),Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary\"},i.prefix)))))))},Discriminator_DiscriminatorMapping=({discriminator:o})=>{const s=o?.mapping||{};return 0===Object.keys(s).length?null:Object.entries(s).map((([o,s])=>Pe.createElement(\"div\",{key:`${o}-${s}`,className:\"json-schema-2020-12-keyword\"},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary\"},o),Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary\"},s))))},keywords_Discriminator_Discriminator=({schema:o,getSystem:s})=>{const i=o?.discriminator||{},{fn:u,getComponent:_}=s(),{useIsExpandedDeeply:w,useComponent:x}=u.jsonSchema202012,C=w(),j=!!i.mapping,[L,B]=(0,Pe.useState)(C),[$,V]=(0,Pe.useState)(!1),U=x(\"Accordion\"),z=x(\"ExpandDeepButton\"),Y=_(\"JSONSchema202012DeepExpansionContext\")(),Z=(0,Pe.useCallback)((()=>{B((o=>!o))}),[]),ee=(0,Pe.useCallback)(((o,s)=>{B(s),V(s)}),[]);return 0===Object.keys(i).length?null:Pe.createElement(Y.Provider,{value:$},Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--discriminator\"},j?Pe.createElement(Pe.Fragment,null,Pe.createElement(U,{expanded:L,onChange:Z},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary\"},\"Discriminator\")),Pe.createElement(z,{expanded:L,onClick:ee})):Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary\"},\"Discriminator\"),i.propertyName&&Pe.createElement(\"span\",{className:\"json-schema-2020-12__attribute json-schema-2020-12__attribute--muted\"},i.propertyName),Pe.createElement(\"strong\",{className:\"json-schema-2020-12__attribute json-schema-2020-12__attribute--primary\"},\"object\"),Pe.createElement(\"ul\",{className:To()(\"json-schema-2020-12-keyword__children\",{\"json-schema-2020-12-keyword__children--collapsed\":!L})},L&&Pe.createElement(\"li\",{className:\"json-schema-2020-12-property\"},Pe.createElement(Discriminator_DiscriminatorMapping,{discriminator:i})))))},keywords_ExternalDocs=({schema:o,getSystem:s})=>{const i=o?.externalDocs||{},{fn:u,getComponent:_}=s(),{useIsExpandedDeeply:w,useComponent:x}=u.jsonSchema202012,C=w(),j=!(!i.description&&!i.url),[L,B]=(0,Pe.useState)(C),[$,V]=(0,Pe.useState)(!1),U=x(\"Accordion\"),z=x(\"ExpandDeepButton\"),Y=_(\"JSONSchema202012KeywordDescription\"),Z=_(\"Link\"),ee=_(\"JSONSchema202012DeepExpansionContext\")(),ie=(0,Pe.useCallback)((()=>{B((o=>!o))}),[]),ae=(0,Pe.useCallback)(((o,s)=>{B(s),V(s)}),[]);return 0===Object.keys(i).length?null:Pe.createElement(ee.Provider,{value:$},Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--externalDocs\"},j?Pe.createElement(Pe.Fragment,null,Pe.createElement(U,{expanded:L,onChange:ie},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary\"},\"External documentation\")),Pe.createElement(z,{expanded:L,onClick:ae})):Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary\"},\"External documentation\"),Pe.createElement(\"strong\",{className:\"json-schema-2020-12__attribute json-schema-2020-12__attribute--primary\"},\"object\"),Pe.createElement(\"ul\",{className:To()(\"json-schema-2020-12-keyword__children\",{\"json-schema-2020-12-keyword__children--collapsed\":!L})},L&&Pe.createElement(Pe.Fragment,null,i.description&&Pe.createElement(\"li\",{className:\"json-schema-2020-12-property\"},Pe.createElement(Y,{schema:i,getSystem:s})),i.url&&Pe.createElement(\"li\",{className:\"json-schema-2020-12-property\"},Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword\"},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary\"},\"url\"),Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary\"},Pe.createElement(Z,{target:\"_blank\",href:sanitizeUrl(i.url)},i.url))))))))},keywords_Description=({schema:o,getSystem:s})=>{if(!o?.description)return null;const{getComponent:i}=s(),u=i(\"Markdown\");return Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--description\"},Pe.createElement(\"div\",{className:\"json-schema-2020-12-core-keyword__value json-schema-2020-12-core-keyword__value--secondary\"},Pe.createElement(u,{source:o.description})))},AP=createOnlyOAS31ComponentWrapper(keywords_Description),jP=createOnlyOAS31ComponentWrapper((({schema:o,getSystem:s,originalComponent:i})=>{const{getComponent:u}=s(),_=u(\"JSONSchema202012KeywordDiscriminator\"),w=u(\"JSONSchema202012KeywordXml\"),x=u(\"JSONSchema202012KeywordExample\"),C=u(\"JSONSchema202012KeywordExternalDocs\");return Pe.createElement(Pe.Fragment,null,Pe.createElement(i,{schema:o}),Pe.createElement(_,{schema:o,getSystem:s}),Pe.createElement(w,{schema:o,getSystem:s}),Pe.createElement(C,{schema:o,getSystem:s}),Pe.createElement(x,{schema:o,getSystem:s}))})),PP=jP,keywords_Properties=({schema:o,getSystem:s})=>{const{fn:i}=s(),{useComponent:u}=i.jsonSchema202012,{getDependentRequired:_,getProperties:w}=i.jsonSchema202012.useFn(),x=i.jsonSchema202012.useConfig(),C=Array.isArray(o?.required)?o.required:[],j=u(\"JSONSchema\"),L=w(o,x);return 0===Object.keys(L).length?null:Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--properties\"},Pe.createElement(\"ul\",null,Object.entries(L).map((([s,i])=>{const u=C.includes(s),w=_(s,o);return Pe.createElement(\"li\",{key:s,className:To()(\"json-schema-2020-12-property\",{\"json-schema-2020-12-property--required\":u})},Pe.createElement(j,{name:s,schema:i,dependentRequired:w}))}))))},IP=createOnlyOAS31ComponentWrapper(keywords_Properties),getProperties=(o,{includeReadOnly:s,includeWriteOnly:i})=>{if(!o?.properties)return{};const u=Object.entries(o.properties).filter((([,o])=>(!(!0===o?.readOnly)||s)&&(!(!0===o?.writeOnly)||i)));return Object.fromEntries(u)};const MP=function oas31_after_load_afterLoad({fn:o,getSystem:s}){if(o.jsonSchema202012){const i=((o,s)=>{const{fn:i}=s();if(\"function\"!=typeof o)return null;const{hasKeyword:u}=i.jsonSchema202012;return s=>o(s)||u(s,\"example\")||s?.xml||s?.discriminator||s?.externalDocs})(o.jsonSchema202012.isExpandable,s);Object.assign(this.fn.jsonSchema202012,{isExpandable:i,getProperties})}if(\"function\"==typeof o.sampleFromSchema&&o.jsonSchema202012){const i=((o,s)=>{const{fn:i,specSelectors:u}=s;return Object.fromEntries(Object.entries(o).map((([o,s])=>{const _=i[o];return[o,(...o)=>u.isOAS31()?s(...o):\"function\"==typeof _?_(...o):void 0]})))})({sampleFromSchema:o.jsonSchema202012.sampleFromSchema,sampleFromSchemaGeneric:o.jsonSchema202012.sampleFromSchemaGeneric,createXMLExample:o.jsonSchema202012.createXMLExample,memoizedSampleFromSchema:o.jsonSchema202012.memoizedSampleFromSchema,memoizedCreateXMLExample:o.jsonSchema202012.memoizedCreateXMLExample,getJsonSampleSchema:o.jsonSchema202012.getJsonSampleSchema,getYamlSampleSchema:o.jsonSchema202012.getYamlSampleSchema,getXmlSampleSchema:o.jsonSchema202012.getXmlSampleSchema,getSampleSchema:o.jsonSchema202012.getSampleSchema,mergeJsonSchema:o.jsonSchema202012.mergeJsonSchema},s());Object.assign(this.fn,i)}},oas31=({fn:o})=>{const s=o.createSystemSelector||fn_createSystemSelector,i=o.createOnlyOAS31Selector||fn_createOnlyOAS31Selector;return{afterLoad:MP,fn:{isOAS31,createSystemSelector:fn_createSystemSelector,createOnlyOAS31Selector:fn_createOnlyOAS31Selector},components:{Webhooks:webhooks,JsonSchemaDialect:json_schema_dialect,MutualTLSAuth:mutual_tls_auth,OAS31Info:oas31_components_info,OAS31License:oas31_components_license,OAS31Contact:oas31_components_contact,OAS31VersionPragmaFilter:version_pragma_filter,OAS31Model:sP,OAS31Models:models,OAS31Auths:iP,JSONSchema202012KeywordExample:keywords_Example,JSONSchema202012KeywordXml:keywords_Xml,JSONSchema202012KeywordDiscriminator:keywords_Discriminator_Discriminator,JSONSchema202012KeywordExternalDocs:keywords_ExternalDocs},wrapComponents:{InfoContainer:lP,License:aP,Contact:cP,VersionPragmaFilter:wrap_components_version_pragma_filter,Model:pP,Models:dP,AuthItem:mP,auths:gP,JSONSchema202012KeywordDescription:AP,JSONSchema202012KeywordDefault:PP,JSONSchema202012KeywordProperties:IP},statePlugins:{auth:{wrapSelectors:{definitionsToAuthorize:OP}},spec:{selectors:{isOAS31:s(vP),license:selectors_license,selectLicenseNameField,selectLicenseUrlField,selectLicenseIdentifierField:i(selectLicenseIdentifierField),selectLicenseUrl:s(_P),contact:selectors_contact,selectContactNameField,selectContactEmailField,selectContactUrlField,selectContactUrl:s(EP),selectInfoTitleField,selectInfoSummaryField:i(selectInfoSummaryField),selectInfoDescriptionField,selectInfoTermsOfServiceField,selectInfoTermsOfServiceUrl:s(wP),selectExternalDocsDescriptionField,selectExternalDocsUrlField,selectExternalDocsUrl:s(SP),webhooks:i(selectors_webhooks),selectWebhooksOperations:i(s(bP)),selectJsonSchemaDialectField,selectJsonSchemaDialectDefault,selectSchemas:s(xP)},wrapSelectors:{isOAS3:wrap_selectors_isOAS3,selectLicenseUrl:kP}},oas31:{selectors:{selectLicenseUrl:i(s(CP))}}}}},NP=Vo().object,TP=Vo().bool,RP=(Vo().oneOfType([NP,TP]),(0,Pe.createContext)(null));RP.displayName=\"JSONSchemaContext\";const DP=(0,Pe.createContext)(0);DP.displayName=\"JSONSchemaLevelContext\";const LP=(0,Pe.createContext)(!1);LP.displayName=\"JSONSchemaDeepExpansionContext\";const BP=(0,Pe.createContext)(new Set),useConfig=()=>{const{config:o}=(0,Pe.useContext)(RP);return o},useComponent=o=>{const{components:s}=(0,Pe.useContext)(RP);return s[o]||null},useFn=(o=void 0)=>{const{fn:s}=(0,Pe.useContext)(RP);return void 0!==o?s[o]:s},useLevel=()=>{const o=(0,Pe.useContext)(DP);return[o,o+1]},useIsExpanded=()=>{const[o]=useLevel(),{defaultExpandedLevels:s}=useConfig();return s-o>0},useIsExpandedDeeply=()=>(0,Pe.useContext)(LP),useRenderedSchemas=(o=void 0)=>{if(void 0===o)return(0,Pe.useContext)(BP);const s=(0,Pe.useContext)(BP);return new Set([...s,o])},FP=(0,Pe.forwardRef)((({schema:o,name:s=\"\",dependentRequired:i=[],onExpand:u=(()=>{})},_)=>{const w=useFn(),x=useIsExpanded(),C=useIsExpandedDeeply(),[j,L]=(0,Pe.useState)(x||C),[B,$]=(0,Pe.useState)(C),[V,U]=useLevel(),z=(()=>{const[o]=useLevel();return o>0})(),Y=w.isExpandable(o)||i.length>0,Z=(o=>useRenderedSchemas().has(o))(o),ee=useRenderedSchemas(o),ie=w.stringifyConstraints(o),ae=useComponent(\"Accordion\"),ce=useComponent(\"Keyword$schema\"),le=useComponent(\"Keyword$vocabulary\"),pe=useComponent(\"Keyword$id\"),de=useComponent(\"Keyword$anchor\"),fe=useComponent(\"Keyword$dynamicAnchor\"),ye=useComponent(\"Keyword$ref\"),be=useComponent(\"Keyword$dynamicRef\"),_e=useComponent(\"Keyword$defs\"),we=useComponent(\"Keyword$comment\"),Se=useComponent(\"KeywordAllOf\"),xe=useComponent(\"KeywordAnyOf\"),Te=useComponent(\"KeywordOneOf\"),Re=useComponent(\"KeywordNot\"),qe=useComponent(\"KeywordIf\"),$e=useComponent(\"KeywordThen\"),ze=useComponent(\"KeywordElse\"),We=useComponent(\"KeywordDependentSchemas\"),He=useComponent(\"KeywordPrefixItems\"),Ye=useComponent(\"KeywordItems\"),Xe=useComponent(\"KeywordContains\"),Qe=useComponent(\"KeywordProperties\"),et=useComponent(\"KeywordPatternProperties\"),tt=useComponent(\"KeywordAdditionalProperties\"),rt=useComponent(\"KeywordPropertyNames\"),nt=useComponent(\"KeywordUnevaluatedItems\"),ot=useComponent(\"KeywordUnevaluatedProperties\"),st=useComponent(\"KeywordType\"),it=useComponent(\"KeywordEnum\"),at=useComponent(\"KeywordConst\"),ct=useComponent(\"KeywordConstraint\"),lt=useComponent(\"KeywordDependentRequired\"),ut=useComponent(\"KeywordContentSchema\"),pt=useComponent(\"KeywordTitle\"),ht=useComponent(\"KeywordDescription\"),dt=useComponent(\"KeywordDefault\"),mt=useComponent(\"KeywordDeprecated\"),gt=useComponent(\"KeywordReadOnly\"),yt=useComponent(\"KeywordWriteOnly\"),vt=useComponent(\"ExpandDeepButton\");(0,Pe.useEffect)((()=>{$(C)}),[C]),(0,Pe.useEffect)((()=>{$(B)}),[B]);const bt=(0,Pe.useCallback)(((o,s)=>{L(s),!s&&$(!1),u(o,s,!1)}),[u]),_t=(0,Pe.useCallback)(((o,s)=>{L(s),$(s),u(o,s,!0)}),[u]);return Pe.createElement(DP.Provider,{value:U},Pe.createElement(LP.Provider,{value:B},Pe.createElement(BP.Provider,{value:ee},Pe.createElement(\"article\",{ref:_,\"data-json-schema-level\":V,className:To()(\"json-schema-2020-12\",{\"json-schema-2020-12--embedded\":z,\"json-schema-2020-12--circular\":Z})},Pe.createElement(\"div\",{className:\"json-schema-2020-12-head\"},Y&&!Z?Pe.createElement(Pe.Fragment,null,Pe.createElement(ae,{expanded:j,onChange:bt},Pe.createElement(pt,{title:s,schema:o})),Pe.createElement(vt,{expanded:j,onClick:_t})):Pe.createElement(pt,{title:s,schema:o}),Pe.createElement(mt,{schema:o}),Pe.createElement(gt,{schema:o}),Pe.createElement(yt,{schema:o}),Pe.createElement(st,{schema:o,isCircular:Z}),ie.length>0&&ie.map((o=>Pe.createElement(ct,{key:`${o.scope}-${o.value}`,constraint:o})))),Pe.createElement(\"div\",{className:To()(\"json-schema-2020-12-body\",{\"json-schema-2020-12-body--collapsed\":!j})},j&&Pe.createElement(Pe.Fragment,null,Pe.createElement(ht,{schema:o}),!Z&&Y&&Pe.createElement(Pe.Fragment,null,Pe.createElement(Qe,{schema:o}),Pe.createElement(et,{schema:o}),Pe.createElement(tt,{schema:o}),Pe.createElement(ot,{schema:o}),Pe.createElement(rt,{schema:o}),Pe.createElement(Se,{schema:o}),Pe.createElement(xe,{schema:o}),Pe.createElement(Te,{schema:o}),Pe.createElement(Re,{schema:o}),Pe.createElement(qe,{schema:o}),Pe.createElement($e,{schema:o}),Pe.createElement(ze,{schema:o}),Pe.createElement(We,{schema:o}),Pe.createElement(He,{schema:o}),Pe.createElement(Ye,{schema:o}),Pe.createElement(nt,{schema:o}),Pe.createElement(Xe,{schema:o}),Pe.createElement(ut,{schema:o})),Pe.createElement(it,{schema:o}),Pe.createElement(at,{schema:o}),Pe.createElement(lt,{schema:o,dependentRequired:i}),Pe.createElement(dt,{schema:o}),Pe.createElement(ce,{schema:o}),Pe.createElement(le,{schema:o}),Pe.createElement(pe,{schema:o}),Pe.createElement(de,{schema:o}),Pe.createElement(fe,{schema:o}),Pe.createElement(ye,{schema:o}),!Z&&Y&&Pe.createElement(_e,{schema:o}),Pe.createElement(be,{schema:o}),Pe.createElement(we,{schema:o})))))))})),qP=FP,keywords_$schema=({schema:o})=>o?.$schema?Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--$schema\"},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary\"},\"$schema\"),Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary\"},o.$schema)):null,$vocabulary_$vocabulary=({schema:o})=>{const s=useIsExpanded(),i=useIsExpandedDeeply(),[u,_]=(0,Pe.useState)(s||i),w=useComponent(\"Accordion\"),x=(0,Pe.useCallback)((()=>{_((o=>!o))}),[]);return o?.$vocabulary?\"object\"!=typeof o.$vocabulary?null:Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--$vocabulary\"},Pe.createElement(w,{expanded:u,onChange:x},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary\"},\"$vocabulary\")),Pe.createElement(\"strong\",{className:\"json-schema-2020-12__attribute json-schema-2020-12__attribute--primary\"},\"object\"),Pe.createElement(\"ul\",null,u&&Object.entries(o.$vocabulary).map((([o,s])=>Pe.createElement(\"li\",{key:o,className:To()(\"json-schema-2020-12-$vocabulary-uri\",{\"json-schema-2020-12-$vocabulary-uri--disabled\":!s})},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary\"},o)))))):null},keywords_$id=({schema:o})=>o?.$id?Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--$id\"},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary\"},\"$id\"),Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary\"},o.$id)):null,keywords_$anchor=({schema:o})=>o?.$anchor?Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--$anchor\"},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary\"},\"$anchor\"),Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary\"},o.$anchor)):null,keywords_$dynamicAnchor=({schema:o})=>o?.$dynamicAnchor?Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--$dynamicAnchor\"},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary\"},\"$dynamicAnchor\"),Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary\"},o.$dynamicAnchor)):null,keywords_$ref=({schema:o})=>o?.$ref?Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--$ref\"},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary\"},\"$ref\"),Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary\"},o.$ref)):null,keywords_$dynamicRef=({schema:o})=>o?.$dynamicRef?Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--$dynamicRef\"},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary\"},\"$dynamicRef\"),Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary\"},o.$dynamicRef)):null,keywords_$defs=({schema:o})=>{const s=o?.$defs||{},i=useIsExpanded(),u=useIsExpandedDeeply(),[_,w]=(0,Pe.useState)(i||u),[x,C]=(0,Pe.useState)(!1),j=useComponent(\"Accordion\"),L=useComponent(\"ExpandDeepButton\"),B=useComponent(\"JSONSchema\"),$=(0,Pe.useCallback)((()=>{w((o=>!o))}),[]),V=(0,Pe.useCallback)(((o,s)=>{w(s),C(s)}),[]);return 0===Object.keys(s).length?null:Pe.createElement(LP.Provider,{value:x},Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--$defs\"},Pe.createElement(j,{expanded:_,onChange:$},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary\"},\"$defs\")),Pe.createElement(L,{expanded:_,onClick:V}),Pe.createElement(\"strong\",{className:\"json-schema-2020-12__attribute json-schema-2020-12__attribute--primary\"},\"object\"),Pe.createElement(\"ul\",{className:To()(\"json-schema-2020-12-keyword__children\",{\"json-schema-2020-12-keyword__children--collapsed\":!_})},_&&Pe.createElement(Pe.Fragment,null,Object.entries(s).map((([o,s])=>Pe.createElement(\"li\",{key:o,className:\"json-schema-2020-12-property\"},Pe.createElement(B,{name:o,schema:s}))))))))},keywords_$comment=({schema:o})=>o?.$comment?Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--$comment\"},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--secondary\"},\"$comment\"),Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--secondary\"},o.$comment)):null,keywords_AllOf=({schema:o})=>{const s=o?.allOf||[],i=useFn(),u=useIsExpanded(),_=useIsExpandedDeeply(),[w,x]=(0,Pe.useState)(u||_),[C,j]=(0,Pe.useState)(!1),L=useComponent(\"Accordion\"),B=useComponent(\"ExpandDeepButton\"),$=useComponent(\"JSONSchema\"),V=useComponent(\"KeywordType\"),U=(0,Pe.useCallback)((()=>{x((o=>!o))}),[]),z=(0,Pe.useCallback)(((o,s)=>{x(s),j(s)}),[]);return Array.isArray(s)&&0!==s.length?Pe.createElement(LP.Provider,{value:C},Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--allOf\"},Pe.createElement(L,{expanded:w,onChange:U},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary\"},\"All of\")),Pe.createElement(B,{expanded:w,onClick:z}),Pe.createElement(V,{schema:{allOf:s}}),Pe.createElement(\"ul\",{className:To()(\"json-schema-2020-12-keyword__children\",{\"json-schema-2020-12-keyword__children--collapsed\":!w})},w&&Pe.createElement(Pe.Fragment,null,s.map(((o,s)=>Pe.createElement(\"li\",{key:`#${s}`,className:\"json-schema-2020-12-property\"},Pe.createElement($,{name:`#${s} ${i.getTitle(o)}`,schema:o})))))))):null},keywords_AnyOf=({schema:o})=>{const s=o?.anyOf||[],i=useFn(),u=useIsExpanded(),_=useIsExpandedDeeply(),[w,x]=(0,Pe.useState)(u||_),[C,j]=(0,Pe.useState)(!1),L=useComponent(\"Accordion\"),B=useComponent(\"ExpandDeepButton\"),$=useComponent(\"JSONSchema\"),V=useComponent(\"KeywordType\"),U=(0,Pe.useCallback)((()=>{x((o=>!o))}),[]),z=(0,Pe.useCallback)(((o,s)=>{x(s),j(s)}),[]);return Array.isArray(s)&&0!==s.length?Pe.createElement(LP.Provider,{value:C},Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--anyOf\"},Pe.createElement(L,{expanded:w,onChange:U},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary\"},\"Any of\")),Pe.createElement(B,{expanded:w,onClick:z}),Pe.createElement(V,{schema:{anyOf:s}}),Pe.createElement(\"ul\",{className:To()(\"json-schema-2020-12-keyword__children\",{\"json-schema-2020-12-keyword__children--collapsed\":!w})},w&&Pe.createElement(Pe.Fragment,null,s.map(((o,s)=>Pe.createElement(\"li\",{key:`#${s}`,className:\"json-schema-2020-12-property\"},Pe.createElement($,{name:`#${s} ${i.getTitle(o)}`,schema:o})))))))):null},keywords_OneOf=({schema:o})=>{const s=o?.oneOf||[],i=useFn(),u=useIsExpanded(),_=useIsExpandedDeeply(),[w,x]=(0,Pe.useState)(u||_),[C,j]=(0,Pe.useState)(!1),L=useComponent(\"Accordion\"),B=useComponent(\"ExpandDeepButton\"),$=useComponent(\"JSONSchema\"),V=useComponent(\"KeywordType\"),U=(0,Pe.useCallback)((()=>{x((o=>!o))}),[]),z=(0,Pe.useCallback)(((o,s)=>{x(s),j(s)}),[]);return Array.isArray(s)&&0!==s.length?Pe.createElement(LP.Provider,{value:C},Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--oneOf\"},Pe.createElement(L,{expanded:w,onChange:U},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary\"},\"One of\")),Pe.createElement(B,{expanded:w,onClick:z}),Pe.createElement(V,{schema:{oneOf:s}}),Pe.createElement(\"ul\",{className:To()(\"json-schema-2020-12-keyword__children\",{\"json-schema-2020-12-keyword__children--collapsed\":!w})},w&&Pe.createElement(Pe.Fragment,null,s.map(((o,s)=>Pe.createElement(\"li\",{key:`#${s}`,className:\"json-schema-2020-12-property\"},Pe.createElement($,{name:`#${s} ${i.getTitle(o)}`,schema:o})))))))):null},keywords_Not=({schema:o})=>{const s=useFn(),i=useComponent(\"JSONSchema\");if(!s.hasKeyword(o,\"not\"))return null;const u=Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary\"},\"Not\");return Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--not\"},Pe.createElement(i,{name:u,schema:o.not}))},keywords_If=({schema:o})=>{const s=useFn(),i=useComponent(\"JSONSchema\");if(!s.hasKeyword(o,\"if\"))return null;const u=Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary\"},\"If\");return Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--if\"},Pe.createElement(i,{name:u,schema:o.if}))},keywords_Then=({schema:o})=>{const s=useFn(),i=useComponent(\"JSONSchema\");if(!s.hasKeyword(o,\"then\"))return null;const u=Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary\"},\"Then\");return Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--then\"},Pe.createElement(i,{name:u,schema:o.then}))},keywords_Else=({schema:o})=>{const s=useFn(),i=useComponent(\"JSONSchema\");if(!s.hasKeyword(o,\"else\"))return null;const u=Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary\"},\"Else\");return Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--if\"},Pe.createElement(i,{name:u,schema:o.else}))},keywords_DependentSchemas=({schema:o})=>{const s=o?.dependentSchemas||[],i=useIsExpanded(),u=useIsExpandedDeeply(),[_,w]=(0,Pe.useState)(i||u),[x,C]=(0,Pe.useState)(!1),j=useComponent(\"Accordion\"),L=useComponent(\"ExpandDeepButton\"),B=useComponent(\"JSONSchema\"),$=(0,Pe.useCallback)((()=>{w((o=>!o))}),[]),V=(0,Pe.useCallback)(((o,s)=>{w(s),C(s)}),[]);return\"object\"!=typeof s||0===Object.keys(s).length?null:Pe.createElement(LP.Provider,{value:x},Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--dependentSchemas\"},Pe.createElement(j,{expanded:_,onChange:$},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary\"},\"Dependent schemas\")),Pe.createElement(L,{expanded:_,onClick:V}),Pe.createElement(\"strong\",{className:\"json-schema-2020-12__attribute json-schema-2020-12__attribute--primary\"},\"object\"),Pe.createElement(\"ul\",{className:To()(\"json-schema-2020-12-keyword__children\",{\"json-schema-2020-12-keyword__children--collapsed\":!_})},_&&Pe.createElement(Pe.Fragment,null,Object.entries(s).map((([o,s])=>Pe.createElement(\"li\",{key:o,className:\"json-schema-2020-12-property\"},Pe.createElement(B,{name:o,schema:s}))))))))},keywords_PrefixItems=({schema:o})=>{const s=o?.prefixItems||[],i=useFn(),u=useIsExpanded(),_=useIsExpandedDeeply(),[w,x]=(0,Pe.useState)(u||_),[C,j]=(0,Pe.useState)(!1),L=useComponent(\"Accordion\"),B=useComponent(\"ExpandDeepButton\"),$=useComponent(\"JSONSchema\"),V=useComponent(\"KeywordType\"),U=(0,Pe.useCallback)((()=>{x((o=>!o))}),[]),z=(0,Pe.useCallback)(((o,s)=>{x(s),j(s)}),[]);return Array.isArray(s)&&0!==s.length?Pe.createElement(LP.Provider,{value:C},Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--prefixItems\"},Pe.createElement(L,{expanded:w,onChange:U},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary\"},\"Prefix items\")),Pe.createElement(B,{expanded:w,onClick:z}),Pe.createElement(V,{schema:{prefixItems:s}}),Pe.createElement(\"ul\",{className:To()(\"json-schema-2020-12-keyword__children\",{\"json-schema-2020-12-keyword__children--collapsed\":!w})},w&&Pe.createElement(Pe.Fragment,null,s.map(((o,s)=>Pe.createElement(\"li\",{key:`#${s}`,className:\"json-schema-2020-12-property\"},Pe.createElement($,{name:`#${s} ${i.getTitle(o)}`,schema:o})))))))):null},keywords_Items=({schema:o})=>{const s=useFn(),i=useComponent(\"JSONSchema\");if(!s.hasKeyword(o,\"items\"))return null;const u=Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary\"},\"Items\");return Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--items\"},Pe.createElement(i,{name:u,schema:o.items}))},keywords_Contains=({schema:o})=>{const s=useFn(),i=useComponent(\"JSONSchema\");if(!s.hasKeyword(o,\"contains\"))return null;const u=Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary\"},\"Contains\");return Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--contains\"},Pe.createElement(i,{name:u,schema:o.contains}))},keywords_Properties_Properties=({schema:o})=>{const s=useFn(),i=o?.properties||{},u=Array.isArray(o?.required)?o.required:[],_=useComponent(\"JSONSchema\");return 0===Object.keys(i).length?null:Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--properties\"},Pe.createElement(\"ul\",null,Object.entries(i).map((([i,w])=>{const x=u.includes(i),C=s.getDependentRequired(i,o);return Pe.createElement(\"li\",{key:i,className:To()(\"json-schema-2020-12-property\",{\"json-schema-2020-12-property--required\":x})},Pe.createElement(_,{name:i,schema:w,dependentRequired:C}))}))))},PatternProperties_PatternProperties=({schema:o})=>{const s=o?.patternProperties||{},i=useComponent(\"JSONSchema\");return 0===Object.keys(s).length?null:Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--patternProperties\"},Pe.createElement(\"ul\",null,Object.entries(s).map((([o,s])=>Pe.createElement(\"li\",{key:o,className:\"json-schema-2020-12-property\"},Pe.createElement(i,{name:o,schema:s}))))))},keywords_AdditionalProperties=({schema:o})=>{const s=useFn(),{additionalProperties:i}=o,u=useComponent(\"JSONSchema\");if(!s.hasKeyword(o,\"additionalProperties\"))return null;const _=Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary\"},\"Additional properties\");return Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--additionalProperties\"},!0===i?Pe.createElement(Pe.Fragment,null,_,Pe.createElement(\"span\",{className:\"json-schema-2020-12__attribute json-schema-2020-12__attribute--primary\"},\"allowed\")):!1===i?Pe.createElement(Pe.Fragment,null,_,Pe.createElement(\"span\",{className:\"json-schema-2020-12__attribute json-schema-2020-12__attribute--primary\"},\"forbidden\")):Pe.createElement(u,{name:_,schema:i}))},keywords_PropertyNames=({schema:o})=>{const s=useFn(),{propertyNames:i}=o,u=useComponent(\"JSONSchema\"),_=Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary\"},\"Property names\");return s.hasKeyword(o,\"propertyNames\")?Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--propertyNames\"},Pe.createElement(u,{name:_,schema:i})):null},keywords_UnevaluatedItems=({schema:o})=>{const s=useFn(),{unevaluatedItems:i}=o,u=useComponent(\"JSONSchema\");if(!s.hasKeyword(o,\"unevaluatedItems\"))return null;const _=Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary\"},\"Unevaluated items\");return Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--unevaluatedItems\"},Pe.createElement(u,{name:_,schema:i}))},keywords_UnevaluatedProperties=({schema:o})=>{const s=useFn(),{unevaluatedProperties:i}=o,u=useComponent(\"JSONSchema\");if(!s.hasKeyword(o,\"unevaluatedProperties\"))return null;const _=Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary\"},\"Unevaluated properties\");return Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--unevaluatedProperties\"},Pe.createElement(u,{name:_,schema:i}))},keywords_Type=({schema:o,isCircular:s=!1})=>{const i=useFn().getType(o),u=s?\" [circular]\":\"\";return Pe.createElement(\"strong\",{className:\"json-schema-2020-12__attribute json-schema-2020-12__attribute--primary\"},`${i}${u}`)},Enum_Enum=({schema:o})=>{const s=useFn();return Array.isArray(o?.enum)?Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--enum\"},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary\"},\"Allowed values\"),Pe.createElement(\"ul\",null,o.enum.map((o=>{const i=s.stringify(o);return Pe.createElement(\"li\",{key:i},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--const\"},i))})))):null},keywords_Const=({schema:o})=>{const s=useFn();return s.hasKeyword(o,\"const\")?Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--const\"},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary\"},\"Const\"),Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--const\"},s.stringify(o.const))):null},Constraint=({constraint:o})=>Pe.createElement(\"span\",{className:`json-schema-2020-12__constraint json-schema-2020-12__constraint--${o.scope}`},o.value),$P=Pe.memo(Constraint),DependentRequired_DependentRequired=({dependentRequired:o})=>0===o.length?null:Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--dependentRequired\"},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary\"},\"Required when defined\"),Pe.createElement(\"ul\",null,o.map((o=>Pe.createElement(\"li\",{key:o},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--warning\"},o)))))),keywords_ContentSchema=({schema:o})=>{const s=useFn(),i=useComponent(\"JSONSchema\");if(!s.hasKeyword(o,\"contentSchema\"))return null;const u=Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary\"},\"Content schema\");return Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--contentSchema\"},Pe.createElement(i,{name:u,schema:o.contentSchema}))},Title_Title=({title:o=\"\",schema:s})=>{const i=useFn(),u=o||i.getTitle(s);return u?Pe.createElement(\"div\",{className:\"json-schema-2020-12__title\"},u):null},keywords_Description_Description=({schema:o})=>o?.description?Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--description\"},Pe.createElement(\"div\",{className:\"json-schema-2020-12-core-keyword__value json-schema-2020-12-core-keyword__value--secondary\"},o.description)):null,keywords_Default=({schema:o})=>{const s=useFn();return s.hasKeyword(o,\"default\")?Pe.createElement(\"div\",{className:\"json-schema-2020-12-keyword json-schema-2020-12-keyword--default\"},Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary\"},\"Default\"),Pe.createElement(\"span\",{className:\"json-schema-2020-12-keyword__value json-schema-2020-12-keyword__value--const\"},s.stringify(o.default))):null},keywords_Deprecated=({schema:o})=>!0!==o?.deprecated?null:Pe.createElement(\"span\",{className:\"json-schema-2020-12__attribute json-schema-2020-12__attribute--warning\"},\"deprecated\"),keywords_ReadOnly=({schema:o})=>!0!==o?.readOnly?null:Pe.createElement(\"span\",{className:\"json-schema-2020-12__attribute json-schema-2020-12__attribute--muted\"},\"read-only\"),keywords_WriteOnly=({schema:o})=>!0!==o?.writeOnly?null:Pe.createElement(\"span\",{className:\"json-schema-2020-12__attribute json-schema-2020-12__attribute--muted\"},\"write-only\"),Accordion_Accordion=({expanded:o=!1,children:s,onChange:i})=>{const u=useComponent(\"ChevronRightIcon\"),_=(0,Pe.useCallback)((s=>{i(s,!o)}),[o,i]);return Pe.createElement(\"button\",{type:\"button\",className:\"json-schema-2020-12-accordion\",onClick:_},Pe.createElement(\"div\",{className:\"json-schema-2020-12-accordion__children\"},s),Pe.createElement(\"span\",{className:To()(\"json-schema-2020-12-accordion__icon\",{\"json-schema-2020-12-accordion__icon--expanded\":o,\"json-schema-2020-12-accordion__icon--collapsed\":!o})},Pe.createElement(u,null)))},ExpandDeepButton_ExpandDeepButton=({expanded:o,onClick:s})=>{const i=(0,Pe.useCallback)((i=>{s(i,!o)}),[o,s]);return Pe.createElement(\"button\",{type:\"button\",className:\"json-schema-2020-12-expand-deep-button\",onClick:i},o?\"Collapse all\":\"Expand all\")},icons_ChevronRight=()=>Pe.createElement(\"svg\",{xmlns:\"http://www.w3.org/2000/svg\",width:\"24\",height:\"24\",viewBox:\"0 0 24 24\"},Pe.createElement(\"path\",{d:\"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\"})),fn_upperFirst=o=>\"string\"==typeof o?`${o.charAt(0).toUpperCase()}${o.slice(1)}`:o,getTitle=(o,{lookup:s=\"extended\"}={})=>{const i=useFn();if(null!=o?.title)return i.upperFirst(String(o.title));if(\"extended\"===s){if(null!=o?.$anchor)return i.upperFirst(String(o.$anchor));if(null!=o?.$id)return String(o.$id)}return\"\"},getType=(o,s=new WeakSet)=>{const i=useFn();if(null==o)return\"any\";if(i.isBooleanJSONSchema(o))return o?\"any\":\"never\";if(\"object\"!=typeof o)return\"any\";if(s.has(o))return\"any\";s.add(o);const{type:u,prefixItems:_,items:w}=o,getArrayType=()=>{if(Array.isArray(_)){const o=_.map((o=>getType(o,s))),i=w?getType(w,s):\"any\";return`array<[${o.join(\", \")}], ${i}>`}if(w){return`array<${getType(w,s)}>`}return\"array\"};if(o.not&&\"any\"===getType(o.not))return\"never\";const handleCombiningKeywords=(i,u)=>{if(Array.isArray(o[i])){return`(${o[i].map((o=>getType(o,s))).join(u)})`}return null},x=[Array.isArray(u)?u.map((o=>\"array\"===o?getArrayType():o)).join(\" | \"):\"array\"===u?getArrayType():[\"null\",\"boolean\",\"object\",\"array\",\"number\",\"integer\",\"string\"].includes(u)?u:(()=>{if(Object.hasOwn(o,\"prefixItems\")||Object.hasOwn(o,\"items\")||Object.hasOwn(o,\"contains\"))return getArrayType();if(Object.hasOwn(o,\"properties\")||Object.hasOwn(o,\"additionalProperties\")||Object.hasOwn(o,\"patternProperties\"))return\"object\";if([\"int32\",\"int64\"].includes(o.format))return\"integer\";if([\"float\",\"double\"].includes(o.format))return\"number\";if(Object.hasOwn(o,\"minimum\")||Object.hasOwn(o,\"maximum\")||Object.hasOwn(o,\"exclusiveMinimum\")||Object.hasOwn(o,\"exclusiveMaximum\")||Object.hasOwn(o,\"multipleOf\"))return\"number | integer\";if(Object.hasOwn(o,\"pattern\")||Object.hasOwn(o,\"format\")||Object.hasOwn(o,\"minLength\")||Object.hasOwn(o,\"maxLength\"))return\"string\";if(void 0!==o.const){if(null===o.const)return\"null\";if(\"boolean\"==typeof o.const)return\"boolean\";if(\"number\"==typeof o.const)return Number.isInteger(o.const)?\"integer\":\"number\";if(\"string\"==typeof o.const)return\"string\";if(Array.isArray(o.const))return\"array\";if(\"object\"==typeof o.const)return\"object\"}return null})(),handleCombiningKeywords(\"oneOf\",\" | \"),handleCombiningKeywords(\"anyOf\",\" | \"),handleCombiningKeywords(\"allOf\",\" & \")].filter(Boolean).join(\" | \");return s.delete(o),x||\"any\"},isBooleanJSONSchema=o=>\"boolean\"==typeof o,hasKeyword=(o,s)=>null!==o&&\"object\"==typeof o&&Object.hasOwn(o,s),isExpandable=o=>{const s=useFn();return o?.$schema||o?.$vocabulary||o?.$id||o?.$anchor||o?.$dynamicAnchor||o?.$ref||o?.$dynamicRef||o?.$defs||o?.$comment||o?.allOf||o?.anyOf||o?.oneOf||s.hasKeyword(o,\"not\")||s.hasKeyword(o,\"if\")||s.hasKeyword(o,\"then\")||s.hasKeyword(o,\"else\")||o?.dependentSchemas||o?.prefixItems||s.hasKeyword(o,\"items\")||s.hasKeyword(o,\"contains\")||o?.properties||o?.patternProperties||s.hasKeyword(o,\"additionalProperties\")||s.hasKeyword(o,\"propertyNames\")||s.hasKeyword(o,\"unevaluatedItems\")||s.hasKeyword(o,\"unevaluatedProperties\")||o?.description||o?.enum||s.hasKeyword(o,\"const\")||s.hasKeyword(o,\"contentSchema\")||s.hasKeyword(o,\"default\")},fn_stringify=o=>null===o||[\"number\",\"bigint\",\"boolean\"].includes(typeof o)?String(o):Array.isArray(o)?`[${o.map(fn_stringify).join(\", \")}]`:JSON.stringify(o),stringifyConstraintRange=(o,s,i)=>{const u=\"number\"==typeof s,_=\"number\"==typeof i;return u&&_?s===i?`${s} ${o}`:`[${s}, ${i}] ${o}`:u?`>= ${s} ${o}`:_?`<= ${i} ${o}`:null},stringifyConstraints=o=>{const s=[],i=(o=>{if(\"number\"!=typeof o?.multipleOf)return null;if(o.multipleOf<=0)return null;if(1===o.multipleOf)return null;const{multipleOf:s}=o;if(Number.isInteger(s))return`multiple of ${s}`;const i=10**s.toString().split(\".\")[1].length;return`multiple of ${s*i}/${i}`})(o);null!==i&&s.push({scope:\"number\",value:i});const u=(o=>{const s=o?.minimum,i=o?.maximum,u=o?.exclusiveMinimum,_=o?.exclusiveMaximum,w=\"number\"==typeof s,x=\"number\"==typeof i,C=\"number\"==typeof u,j=\"number\"==typeof _,L=C&&(!w||s_);if((w||C)&&(x||j))return`${L?\"(\":\"[\"}${L?u:s}, ${B?_:i}${B?\")\":\"]\"}`;if(w||C)return`${L?\">\":\"≥\"} ${L?u:s}`;if(x||j)return`${B?\"<\":\"≤\"} ${B?_:i}`;return null})(o);null!==u&&s.push({scope:\"number\",value:u}),o?.format&&s.push({scope:\"string\",value:o.format});const _=stringifyConstraintRange(\"characters\",o?.minLength,o?.maxLength);null!==_&&s.push({scope:\"string\",value:_}),o?.pattern&&s.push({scope:\"string\",value:`matches ${o?.pattern}`}),o?.contentMediaType&&s.push({scope:\"string\",value:`media type: ${o.contentMediaType}`}),o?.contentEncoding&&s.push({scope:\"string\",value:`encoding: ${o.contentEncoding}`});const w=stringifyConstraintRange(o?.hasUniqueItems?\"unique items\":\"items\",o?.minItems,o?.maxItems);null!==w&&s.push({scope:\"array\",value:w});const x=stringifyConstraintRange(\"contained items\",o?.minContains,o?.maxContains);null!==x&&s.push({scope:\"array\",value:x});const C=stringifyConstraintRange(\"properties\",o?.minProperties,o?.maxProperties);return null!==C&&s.push({scope:\"object\",value:C}),s},getDependentRequired=(o,s)=>s?.dependentRequired?Array.from(Object.entries(s.dependentRequired).reduce(((s,[i,u])=>Array.isArray(u)&&u.includes(o)?(s.add(i),s):s),new Set)):[],withJSONSchemaContext=(o,s={})=>{const i={components:{JSONSchema:qP,Keyword$schema:keywords_$schema,Keyword$vocabulary:$vocabulary_$vocabulary,Keyword$id:keywords_$id,Keyword$anchor:keywords_$anchor,Keyword$dynamicAnchor:keywords_$dynamicAnchor,Keyword$ref:keywords_$ref,Keyword$dynamicRef:keywords_$dynamicRef,Keyword$defs:keywords_$defs,Keyword$comment:keywords_$comment,KeywordAllOf:keywords_AllOf,KeywordAnyOf:keywords_AnyOf,KeywordOneOf:keywords_OneOf,KeywordNot:keywords_Not,KeywordIf:keywords_If,KeywordThen:keywords_Then,KeywordElse:keywords_Else,KeywordDependentSchemas:keywords_DependentSchemas,KeywordPrefixItems:keywords_PrefixItems,KeywordItems:keywords_Items,KeywordContains:keywords_Contains,KeywordProperties:keywords_Properties_Properties,KeywordPatternProperties:PatternProperties_PatternProperties,KeywordAdditionalProperties:keywords_AdditionalProperties,KeywordPropertyNames:keywords_PropertyNames,KeywordUnevaluatedItems:keywords_UnevaluatedItems,KeywordUnevaluatedProperties:keywords_UnevaluatedProperties,KeywordType:keywords_Type,KeywordEnum:Enum_Enum,KeywordConst:keywords_Const,KeywordConstraint:$P,KeywordDependentRequired:DependentRequired_DependentRequired,KeywordContentSchema:keywords_ContentSchema,KeywordTitle:Title_Title,KeywordDescription:keywords_Description_Description,KeywordDefault:keywords_Default,KeywordDeprecated:keywords_Deprecated,KeywordReadOnly:keywords_ReadOnly,KeywordWriteOnly:keywords_WriteOnly,Accordion:Accordion_Accordion,ExpandDeepButton:ExpandDeepButton_ExpandDeepButton,ChevronRightIcon:icons_ChevronRight,...s.components},config:{default$schema:\"https://json-schema.org/draft/2020-12/schema\",defaultExpandedLevels:0,...s.config},fn:{upperFirst:fn_upperFirst,getTitle,getType,isBooleanJSONSchema,hasKeyword,isExpandable,stringify:fn_stringify,stringifyConstraints,getDependentRequired,...s.fn}},HOC=s=>Pe.createElement(RP.Provider,{value:i},Pe.createElement(o,s));return HOC.contexts={JSONSchemaContext:RP},HOC.displayName=o.displayName,HOC},json_schema_2020_12=()=>({components:{JSONSchema202012:qP,JSONSchema202012Keyword$schema:keywords_$schema,JSONSchema202012Keyword$vocabulary:$vocabulary_$vocabulary,JSONSchema202012Keyword$id:keywords_$id,JSONSchema202012Keyword$anchor:keywords_$anchor,JSONSchema202012Keyword$dynamicAnchor:keywords_$dynamicAnchor,JSONSchema202012Keyword$ref:keywords_$ref,JSONSchema202012Keyword$dynamicRef:keywords_$dynamicRef,JSONSchema202012Keyword$defs:keywords_$defs,JSONSchema202012Keyword$comment:keywords_$comment,JSONSchema202012KeywordAllOf:keywords_AllOf,JSONSchema202012KeywordAnyOf:keywords_AnyOf,JSONSchema202012KeywordOneOf:keywords_OneOf,JSONSchema202012KeywordNot:keywords_Not,JSONSchema202012KeywordIf:keywords_If,JSONSchema202012KeywordThen:keywords_Then,JSONSchema202012KeywordElse:keywords_Else,JSONSchema202012KeywordDependentSchemas:keywords_DependentSchemas,JSONSchema202012KeywordPrefixItems:keywords_PrefixItems,JSONSchema202012KeywordItems:keywords_Items,JSONSchema202012KeywordContains:keywords_Contains,JSONSchema202012KeywordProperties:keywords_Properties_Properties,JSONSchema202012KeywordPatternProperties:PatternProperties_PatternProperties,JSONSchema202012KeywordAdditionalProperties:keywords_AdditionalProperties,JSONSchema202012KeywordPropertyNames:keywords_PropertyNames,JSONSchema202012KeywordUnevaluatedItems:keywords_UnevaluatedItems,JSONSchema202012KeywordUnevaluatedProperties:keywords_UnevaluatedProperties,JSONSchema202012KeywordType:keywords_Type,JSONSchema202012KeywordEnum:Enum_Enum,JSONSchema202012KeywordConst:keywords_Const,JSONSchema202012KeywordConstraint:$P,JSONSchema202012KeywordDependentRequired:DependentRequired_DependentRequired,JSONSchema202012KeywordContentSchema:keywords_ContentSchema,JSONSchema202012KeywordTitle:Title_Title,JSONSchema202012KeywordDescription:keywords_Description_Description,JSONSchema202012KeywordDefault:keywords_Default,JSONSchema202012KeywordDeprecated:keywords_Deprecated,JSONSchema202012KeywordReadOnly:keywords_ReadOnly,JSONSchema202012KeywordWriteOnly:keywords_WriteOnly,JSONSchema202012Accordion:Accordion_Accordion,JSONSchema202012ExpandDeepButton:ExpandDeepButton_ExpandDeepButton,JSONSchema202012ChevronRightIcon:icons_ChevronRight,withJSONSchema202012Context:withJSONSchemaContext,JSONSchema202012DeepExpansionContext:()=>LP},fn:{upperFirst:fn_upperFirst,jsonSchema202012:{isExpandable,hasKeyword,useFn,useConfig,useComponent,useIsExpandedDeeply}}});var VP=__webpack_require__(11331),UP=__webpack_require__.n(VP);const array=(o,{sample:s})=>((o,s={})=>{const{minItems:i,maxItems:u,uniqueItems:_}=s,{contains:w,minContains:x,maxContains:C}=s;let j=[...o];if(null!=w&&\"object\"==typeof w){if(Number.isInteger(x)&&x>1){const o=j.at(0);for(let s=1;s0&&(j=o.slice(0,u)),Number.isInteger(i)&&i>0)for(let o=0;j.length{throw new Error(\"Not implemented\")},bytes=o=>St()(o),random_pick=o=>o.at(0),predicates_isBooleanJSONSchema=o=>\"boolean\"==typeof o,isJSONSchemaObject=o=>UP()(o),isJSONSchema=o=>predicates_isBooleanJSONSchema(o)||isJSONSchemaObject(o);const zP=class Registry{data={};register(o,s){this.data[o]=s}unregister(o){void 0===o?this.data={}:delete this.data[o]}get(o){return this.data[o]}},int32=()=>2**30>>>0,int64=()=>2**53-1,generators_float=()=>.1,generators_double=()=>.1,email=()=>\"user@example.com\",idn_email=()=>\"실례@example.com\",hostname=()=>\"example.com\",idn_hostname=()=>\"실례.com\",ipv4=()=>\"198.51.100.42\",ipv6=()=>\"2001:0db8:5b96:0000:0000:426f:8e17:642a\",uri=()=>\"https://example.com/\",uri_reference=()=>\"path/index.html\",iri=()=>\"https://실례.com/\",iri_reference=()=>\"path/실례.html\",uuid=()=>\"3fa85f64-5717-4562-b3fc-2c963f66afa6\",uri_template=()=>\"https://example.com/dictionary/{term:1}/{term}\",json_pointer=()=>\"/a/b/c\",relative_json_pointer=()=>\"1/0\",date_time=()=>(new Date).toISOString(),date=()=>(new Date).toISOString().substring(0,10),time=()=>(new Date).toISOString().substring(11),duration=()=>\"P3D\",generators_password=()=>\"********\",regex=()=>\"^[a-z]+$\";const WP=new class FormatRegistry extends zP{#t={int32,int64,float:generators_float,double:generators_double,email,\"idn-email\":idn_email,hostname,\"idn-hostname\":idn_hostname,ipv4,ipv6,uri,\"uri-reference\":uri_reference,iri,\"iri-reference\":iri_reference,uuid,\"uri-template\":uri_template,\"json-pointer\":json_pointer,\"relative-json-pointer\":relative_json_pointer,\"date-time\":date_time,date,time,duration,password:generators_password,regex};data={...this.#t};get defaults(){return{...this.#t}}},formatAPI=(o,s)=>\"function\"==typeof s?WP.register(o,s):null===s?WP.unregister(o):WP.get(o);formatAPI.getDefaults=()=>WP.defaults;const KP=formatAPI;var HP=__webpack_require__(48287).Buffer;const _7bit=o=>HP.from(o).toString(\"ascii\");var JP=__webpack_require__(48287).Buffer;const _8bit=o=>JP.from(o).toString(\"utf8\");var GP=__webpack_require__(48287).Buffer;const encoders_binary=o=>GP.from(o).toString(\"binary\"),quoted_printable=o=>{let s=\"\";for(let i=0;i=33&&u<=60||u>=62&&u<=126||9===u||32===u)s+=o.charAt(i);else if(13===u||10===u)s+=\"\\r\\n\";else if(u>126){const u=unescape(encodeURIComponent(o.charAt(i)));for(let o=0;oYP.from(o).toString(\"hex\");var XP=__webpack_require__(48287).Buffer;const base32=o=>{const s=XP.from(o).toString(\"utf8\"),i=\"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567\";let u=0,_=\"\",w=0,x=0;for(let o=0;o=5;)_+=i.charAt(w>>>x-5&31),x-=5;x>0&&(_+=i.charAt(w<<5-x&31),u=(8-8*s.length%5)%5);for(let o=0;oQP.from(o).toString(\"base64\");var ZP=__webpack_require__(48287).Buffer;const base64url=o=>ZP.from(o).toString(\"base64url\");const eI=new class EncoderRegistry extends zP{#t={\"7bit\":_7bit,\"8bit\":_8bit,binary:encoders_binary,\"quoted-printable\":quoted_printable,base16,base32,base64,base64url};data={...this.#t};get defaults(){return{...this.#t}}},encoderAPI=(o,s)=>\"function\"==typeof s?eI.register(o,s):null===s?eI.unregister(o):eI.get(o);encoderAPI.getDefaults=()=>eI.defaults;const tI=encoderAPI,rI={\"text/plain\":()=>\"string\",\"text/css\":()=>\".selector { border: 1px solid red }\",\"text/csv\":()=>\"value1,value2,value3\",\"text/html\":()=>\"

    content

    \",\"text/calendar\":()=>\"BEGIN:VCALENDAR\",\"text/javascript\":()=>\"console.dir('Hello world!');\",\"text/xml\":()=>'John Doe',\"text/*\":()=>\"string\"},nI={\"image/*\":()=>bytes(25).toString(\"binary\")},oI={\"audio/*\":()=>bytes(25).toString(\"binary\")},sI={\"video/*\":()=>bytes(25).toString(\"binary\")},iI={\"application/json\":()=>'{\"key\":\"value\"}',\"application/ld+json\":()=>'{\"name\": \"John Doe\"}',\"application/x-httpd-php\":()=>\"Hello World!

    '; ?>\",\"application/rtf\":()=>String.raw`{\\rtf1\\adeflang1025\\ansi\\ansicpg1252\\uc1`,\"application/x-sh\":()=>'echo \"Hello World!\"',\"application/xhtml+xml\":()=>\"

    content

    \",\"application/*\":()=>bytes(25).toString(\"binary\")};const aI=new class MediaTypeRegistry extends zP{#t={...rI,...nI,...oI,...sI,...iI};data={...this.#t};get defaults(){return{...this.#t}}},mediaTypeAPI=(o,s)=>{if(\"function\"==typeof s)return aI.register(o,s);if(null===s)return aI.unregister(o);const i=o.split(\";\").at(0),u=`${i.split(\"/\").at(0)}/*`;return aI.get(o)||aI.get(i)||aI.get(u)};mediaTypeAPI.getDefaults=()=>aI.defaults;const cI=mediaTypeAPI,applyStringConstraints=(o,s={})=>{const{maxLength:i,minLength:u}=s;let _=o;if(Number.isInteger(i)&&i>0&&(_=_.slice(0,i)),Number.isInteger(u)&&u>0){let o=0;for(;_.length{const{contentEncoding:i,contentMediaType:u,contentSchema:_}=o,{pattern:w,format:x}=o,C=tI(i)||_k();let j;return j=\"string\"==typeof w?applyStringConstraints((o=>{try{return new(Yo())(o).gen()}catch{return\"string\"}})(w),o):\"string\"==typeof x?(o=>{const{format:s}=o,i=KP(s);return\"function\"==typeof i?i(o):\"string\"})(o):isJSONSchema(_)&&\"string\"==typeof u&&void 0!==s?Array.isArray(s)||\"object\"==typeof s?JSON.stringify(s):applyStringConstraints(String(s),o):\"string\"==typeof u?(o=>{const{contentMediaType:s}=o,i=cI(s);return\"function\"==typeof i?i(o):\"string\"})(o):applyStringConstraints(\"string\",o),C(j)},applyNumberConstraints=(o,s={})=>{const{minimum:i,maximum:u,exclusiveMinimum:_,exclusiveMaximum:w}=s,{multipleOf:x}=s,C=Number.isInteger(o)?1:Number.EPSILON;let j=\"number\"==typeof i?i:null,L=\"number\"==typeof u?u:null,B=o;if(\"number\"==typeof _&&(j=null!==j?Math.max(j,_+C):_+C),\"number\"==typeof w&&(L=null!==L?Math.min(L,w-C):w-C),B=j>L&&o||j||L||B,\"number\"==typeof x&&x>0){const o=B%x;B=0===o?B:B+x-o}return B},types_number=o=>{const{format:s}=o;let i;return i=\"string\"==typeof s?(o=>{const{format:s}=o,i=KP(s);return\"function\"==typeof i?i(o):0})(o):0,applyNumberConstraints(i,o)},types_integer=o=>{const{format:s}=o;let i;return i=\"string\"==typeof s?(o=>{const{format:s}=o,i=KP(s);if(\"function\"==typeof i)return i(o);switch(s){case\"int32\":return int32();case\"int64\":return int64()}return 0})(o):0,applyNumberConstraints(i,o)},types_boolean=o=>\"boolean\"!=typeof o.default||o.default,lI=new Proxy({array,object,string:types_string,number:types_number,integer:types_integer,boolean:types_boolean,null:()=>null},{get:(o,s)=>\"string\"==typeof s&&Object.hasOwn(o,s)?o[s]:()=>`Unknown Type: ${s}`}),uI=[\"array\",\"object\",\"number\",\"integer\",\"string\",\"boolean\",\"null\"],hasExample=o=>{if(!isJSONSchemaObject(o))return!1;const{examples:s,example:i,default:u}=o;return!!(Array.isArray(s)&&s.length>=1)||(void 0!==u||void 0!==i)},extractExample=o=>{if(!isJSONSchemaObject(o))return null;const{examples:s,example:i,default:u}=o;return Array.isArray(s)&&s.length>=1?s.at(0):void 0!==u?u:void 0!==i?i:void 0},pI={array:[\"items\",\"prefixItems\",\"contains\",\"maxContains\",\"minContains\",\"maxItems\",\"minItems\",\"uniqueItems\",\"unevaluatedItems\"],object:[\"properties\",\"additionalProperties\",\"patternProperties\",\"propertyNames\",\"minProperties\",\"maxProperties\",\"required\",\"dependentSchemas\",\"dependentRequired\",\"unevaluatedProperties\"],string:[\"pattern\",\"format\",\"minLength\",\"maxLength\",\"contentEncoding\",\"contentMediaType\",\"contentSchema\"],integer:[\"minimum\",\"maximum\",\"exclusiveMinimum\",\"exclusiveMaximum\",\"multipleOf\"]};pI.number=pI.integer;const hI=\"string\",inferTypeFromValue=o=>void 0===o?null:null===o?\"null\":Array.isArray(o)?\"array\":Number.isInteger(o)?\"integer\":typeof o,foldType=o=>{if(Array.isArray(o)&&o.length>=1){if(o.includes(\"array\"))return\"array\";if(o.includes(\"object\"))return\"object\";{const s=random_pick(o);if(uI.includes(s))return s}}return uI.includes(o)?o:null},inferType=(o,s=new WeakSet)=>{if(!isJSONSchemaObject(o))return hI;if(s.has(o))return hI;s.add(o);let{type:i,const:u}=o;if(i=foldType(i),\"string\"!=typeof i){const s=Object.keys(pI);e:for(let u=0;u{if(Array.isArray(o[i])){const u=o[i].map((o=>inferType(o,s)));return foldType(u)}return null},u=combineTypes(\"allOf\"),_=combineTypes(\"anyOf\"),w=combineTypes(\"oneOf\"),x=o.not?inferType(o.not,s):null;(u||_||w||x)&&(i=foldType([u,_,w,x].filter(Boolean)))}if(\"string\"!=typeof i&&hasExample(o)){const s=extractExample(o),u=inferTypeFromValue(s);i=\"string\"==typeof u?u:i}return s.delete(o),i||hI},type_getType=o=>inferType(o),typeCast=o=>predicates_isBooleanJSONSchema(o)?(o=>!1===o?{not:{}}:{})(o):isJSONSchemaObject(o)?o:{},merge_merge=(o,s,i={})=>{if(predicates_isBooleanJSONSchema(o)&&!0===o)return!0;if(predicates_isBooleanJSONSchema(o)&&!1===o)return!1;if(predicates_isBooleanJSONSchema(s)&&!0===s)return!0;if(predicates_isBooleanJSONSchema(s)&&!1===s)return!1;if(!isJSONSchema(o))return s;if(!isJSONSchema(s))return o;const u={...s,...o};if(s.type&&o.type&&Array.isArray(s.type)&&\"string\"==typeof s.type){const i=normalizeArray(s.type).concat(o.type);u.type=Array.from(new Set(i))}if(Array.isArray(s.required)&&Array.isArray(o.required)&&(u.required=[...new Set([...o.required,...s.required])]),s.properties&&o.properties){const _=new Set([...Object.keys(s.properties),...Object.keys(o.properties)]);u.properties={};for(const w of _){const _=s.properties[w]||{},x=o.properties[w]||{};_.readOnly&&!i.includeReadOnly||_.writeOnly&&!i.includeWriteOnly?u.required=(u.required||[]).filter((o=>o!==w)):u.properties[w]=merge_merge(x,_,i)}}return isJSONSchema(s.items)&&isJSONSchema(o.items)&&(u.items=merge_merge(o.items,s.items,i)),isJSONSchema(s.contains)&&isJSONSchema(o.contains)&&(u.contains=merge_merge(o.contains,s.contains,i)),isJSONSchema(s.contentSchema)&&isJSONSchema(o.contentSchema)&&(u.contentSchema=merge_merge(o.contentSchema,s.contentSchema,i)),u},dI=merge_merge,main_sampleFromSchemaGeneric=(o,s={},i=void 0,u=!1)=>{if(null==o&&void 0===i)return;\"function\"==typeof o?.toJS&&(o=o.toJS()),o=typeCast(o);let _=void 0!==i||hasExample(o);const w=!_&&Array.isArray(o.oneOf)&&o.oneOf.length>0,x=!_&&Array.isArray(o.anyOf)&&o.anyOf.length>0;if(!_&&(w||x)){const i=typeCast(random_pick(w?o.oneOf:o.anyOf));!(o=dI(o,i,s)).xml&&i.xml&&(o.xml=i.xml),hasExample(o)&&hasExample(i)&&(_=!0)}const C={};let{xml:j,properties:L,additionalProperties:B,items:$,contains:V}=o||{},U=type_getType(o),{includeReadOnly:z,includeWriteOnly:Y}=s;j=j||{};let Z,{name:ee,prefix:ie,namespace:ae}=j,ce={};if(Object.hasOwn(o,\"type\")||(o.type=U),u&&(ee=ee||\"notagname\",Z=(ie?`${ie}:`:\"\")+ee,ae)){C[ie?`xmlns:${ie}`:\"xmlns\"]=ae}u&&(ce[Z]=[]);const le=objectify(L);let pe,de=0;const hasExceededMaxProperties=()=>Number.isInteger(o.maxProperties)&&o.maxProperties>0&&de>=o.maxProperties,canAddProperty=s=>!(Number.isInteger(o.maxProperties)&&o.maxProperties>0)||!hasExceededMaxProperties()&&(!(s=>!Array.isArray(o.required)||0===o.required.length||!o.required.includes(s))(s)||o.maxProperties-de-(()=>{if(!Array.isArray(o.required)||0===o.required.length)return 0;let s=0;return u?o.required.forEach((o=>s+=void 0===ce[o]?0:1)):o.required.forEach((o=>{s+=void 0===ce[Z]?.find((s=>void 0!==s[o]))?0:1})),o.required.length-s})()>0);if(pe=u?(i,_=void 0)=>{if(o&&le[i]){if(le[i].xml=le[i].xml||{},le[i].xml.attribute){const o=Array.isArray(le[i].enum)?random_pick(le[i].enum):void 0;if(hasExample(le[i]))C[le[i].xml.name||i]=extractExample(le[i]);else if(void 0!==o)C[le[i].xml.name||i]=o;else{const o=typeCast(le[i]),s=type_getType(o),u=le[i].xml.name||i;C[u]=lI[s](o)}return}le[i].xml.name=le[i].xml.name||i}else le[i]||!1===B||(le[i]={xml:{name:i}});let w=main_sampleFromSchemaGeneric(le[i],s,_,u);canAddProperty(i)&&(de++,Array.isArray(w)?ce[Z]=ce[Z].concat(w):ce[Z].push(w))}:(i,_)=>{if(canAddProperty(i)){if(UP()(o.discriminator?.mapping)&&o.discriminator.propertyName===i&&\"string\"==typeof o.$$ref){for(const s in o.discriminator.mapping)if(-1!==o.$$ref.search(o.discriminator.mapping[s])){ce[i]=s;break}}else ce[i]=main_sampleFromSchemaGeneric(le[i],s,_,u);de++}},_){let _;if(_=void 0!==i?i:extractExample(o),!u){if(\"number\"==typeof _&&\"string\"===U)return`${_}`;if(\"string\"!=typeof _||\"string\"===U)return _;try{return JSON.parse(_)}catch{return _}}if(\"array\"===U){if(!Array.isArray(_)){if(\"string\"==typeof _)return _;_=[_]}let i=[];return isJSONSchemaObject($)&&($.xml=$.xml||j||{},$.xml.name=$.xml.name||j.name,i=_.map((o=>main_sampleFromSchemaGeneric($,s,o,u)))),isJSONSchemaObject(V)&&(V.xml=V.xml||j||{},V.xml.name=V.xml.name||j.name,i=[main_sampleFromSchemaGeneric(V,s,void 0,u),...i]),i=lI.array(o,{sample:i}),j.wrapped?(ce[Z]=i,Qo()(C)||ce[Z].push({_attr:C})):ce=i,ce}if(\"object\"===U){if(\"string\"==typeof _)return _;for(const o in _)Object.hasOwn(_,o)&&(le[o]?.readOnly&&!z||le[o]?.writeOnly&&!Y||(le[o]?.xml?.attribute?C[le[o].xml.name||o]=_[o]:pe(o,_[o])));return Qo()(C)||ce[Z].push({_attr:C}),ce}return ce[Z]=Qo()(C)?_:[{_attr:C},_],ce}if(\"array\"===U){let i=[];if(isJSONSchemaObject(V))if(u&&(V.xml=V.xml||o.xml||{},V.xml.name=V.xml.name||j.name),Array.isArray(V.anyOf)){const{anyOf:o,..._}=$;i.push(...V.anyOf.map((o=>main_sampleFromSchemaGeneric(dI(o,_,s),s,void 0,u))))}else if(Array.isArray(V.oneOf)){const{oneOf:o,..._}=$;i.push(...V.oneOf.map((o=>main_sampleFromSchemaGeneric(dI(o,_,s),s,void 0,u))))}else{if(!(!u||u&&j.wrapped))return main_sampleFromSchemaGeneric(V,s,void 0,u);i.push(main_sampleFromSchemaGeneric(V,s,void 0,u))}if(isJSONSchemaObject($))if(u&&($.xml=$.xml||o.xml||{},$.xml.name=$.xml.name||j.name),Array.isArray($.anyOf)){const{anyOf:o,..._}=$;i.push(...$.anyOf.map((o=>main_sampleFromSchemaGeneric(dI(o,_,s),s,void 0,u))))}else if(Array.isArray($.oneOf)){const{oneOf:o,..._}=$;i.push(...$.oneOf.map((o=>main_sampleFromSchemaGeneric(dI(o,_,s),s,void 0,u))))}else{if(!(!u||u&&j.wrapped))return main_sampleFromSchemaGeneric($,s,void 0,u);i.push(main_sampleFromSchemaGeneric($,s,void 0,u))}return i=lI.array(o,{sample:i}),u&&j.wrapped?(ce[Z]=i,Qo()(C)||ce[Z].push({_attr:C}),ce):i}if(\"object\"===U){for(let o in le)Object.hasOwn(le,o)&&(le[o]?.deprecated||le[o]?.readOnly&&!z||le[o]?.writeOnly&&!Y||pe(o));if(u&&C&&ce[Z].push({_attr:C}),hasExceededMaxProperties())return ce;if(predicates_isBooleanJSONSchema(B)&&B)u?ce[Z].push({additionalProp:\"Anything can be here\"}):ce.additionalProp1={},de++;else if(isJSONSchemaObject(B)){const i=B,_=main_sampleFromSchemaGeneric(i,s,void 0,u);if(u&&\"string\"==typeof i?.xml?.name&&\"notagname\"!==i?.xml?.name)ce[Z].push(_);else{const s=Number.isInteger(o.minProperties)&&o.minProperties>0&&de{const u=main_sampleFromSchemaGeneric(o,s,i,!0);if(u)return\"string\"==typeof u?u:Jo()(u,{declaration:!0,indent:\"\\t\"})},main_sampleFromSchema=(o,s,i)=>main_sampleFromSchemaGeneric(o,s,i,!1),main_resolver=(o,s,i)=>[o,JSON.stringify(s),JSON.stringify(i)],fI=utils_memoizeN(main_createXMLExample,main_resolver),mI=utils_memoizeN(main_sampleFromSchema,main_resolver);const gI=new class OptionRegistry extends zP{#t={};data={...this.#t};get defaults(){return{...this.#t}}},api_optionAPI=(o,s)=>(void 0!==s&&gI.register(o,s),gI.get(o)),yI=[{when:/json/,shouldStringifyTypes:[\"string\"]}],vI=[\"object\"],fn_get_json_sample_schema=o=>(s,i,u,_)=>{const{fn:w}=o(),x=w.jsonSchema202012.memoizedSampleFromSchema(s,i,_),C=typeof x,j=yI.reduce(((o,s)=>s.when.test(u)?[...o,...s.shouldStringifyTypes]:o),vI);return mt()(j,(o=>o===C))?JSON.stringify(x,null,2):x},fn_get_yaml_sample_schema=o=>(s,i,u,_)=>{const{fn:w}=o(),x=w.jsonSchema202012.getJsonSampleSchema(s,i,u,_);let C;try{C=to.dump(to.load(x),{lineWidth:-1},{schema:zn}),\"\\n\"===C[C.length-1]&&(C=C.slice(0,C.length-1))}catch(o){return console.error(o),\"error: could not generate yaml example\"}return C.replace(/\\t/g,\" \")},fn_get_xml_sample_schema=o=>(s,i,u)=>{const{fn:_}=o();if(s&&!s.xml&&(s.xml={}),s&&!s.xml.name){if(!s.$$ref&&(s.type||s.items||s.properties||s.additionalProperties))return'\\n\\x3c!-- XML example cannot be generated; root element name is undefined --\\x3e';if(s.$$ref){let o=s.$$ref.match(/\\S*\\/(\\S+)$/);s.xml.name=o[1]}}return _.jsonSchema202012.memoizedCreateXMLExample(s,i,u)},fn_get_sample_schema=o=>(s,i=\"\",u={},_=void 0)=>{const{fn:w}=o();return\"function\"==typeof s?.toJS&&(s=s.toJS()),\"function\"==typeof _?.toJS&&(_=_.toJS()),/xml/.test(i)?w.jsonSchema202012.getXmlSampleSchema(s,u,_):/(yaml|yml)/.test(i)?w.jsonSchema202012.getYamlSampleSchema(s,u,i,_):w.jsonSchema202012.getJsonSampleSchema(s,u,i,_)},json_schema_2020_12_samples=({getSystem:o})=>{const s=fn_get_json_sample_schema(o),i=fn_get_yaml_sample_schema(o),u=fn_get_xml_sample_schema(o),_=fn_get_sample_schema(o);return{fn:{jsonSchema202012:{sampleFromSchema:main_sampleFromSchema,sampleFromSchemaGeneric:main_sampleFromSchemaGeneric,sampleOptionAPI:api_optionAPI,sampleEncoderAPI:tI,sampleFormatAPI:KP,sampleMediaTypeAPI:cI,createXMLExample:main_createXMLExample,memoizedSampleFromSchema:mI,memoizedCreateXMLExample:fI,getJsonSampleSchema:s,getYamlSampleSchema:i,getXmlSampleSchema:u,getSampleSchema:_,mergeJsonSchema:dI}}}};function PresetApis(){return[base,oas3,json_schema_2020_12,json_schema_2020_12_samples,oas31]}const inline_plugin=o=>()=>({fn:o.fn,components:o.components}),factorization_system=o=>{const s=We()({layout:{layout:o.layout,filter:o.filter},spec:{spec:\"\",url:o.url},requestSnippets:o.requestSnippets},o.initialState);if(o.initialState)for(const[i,u]of Object.entries(o.initialState))void 0===u&&delete s[i];return{system:{configs:o.configs},plugins:o.presets,state:s}},sources_query=()=>o=>{const s=o.queryConfigEnabled?(()=>{const o=new URLSearchParams(at.location.search);return Object.fromEntries(o)})():{};return Object.entries(s).reduce(((o,[s,i])=>(\"config\"===s?o.configUrl=i:\"urls.primaryName\"===s?o[s]=i:o=Js()(o,s,i),o)),{})},sources_url=({url:o,system:s})=>async i=>{if(!o)return{};if(\"function\"!=typeof s.configsActions?.getConfigByUrl)return{};const u=(()=>{const o={};return o.promise=new Promise(((s,i)=>{o.resolve=s,o.reject=i})),o})();return s.configsActions.getConfigByUrl({url:o,loadRemoteConfig:!0,requestInterceptor:i.requestInterceptor,responseInterceptor:i.responseInterceptor},(o=>{u.resolve(o)})),u.promise},runtime=()=>()=>{const o={};return globalThis.location&&(o.oauth2RedirectUrl=`${globalThis.location.protocol}//${globalThis.location.host}${globalThis.location.pathname.substring(0,globalThis.location.pathname.lastIndexOf(\"/\"))}/oauth2-redirect.html`),o},bI=Object.freeze({dom_id:null,domNode:null,spec:{},url:\"\",urls:null,configUrl:null,layout:\"BaseLayout\",docExpansion:\"list\",maxDisplayedTags:-1,filter:!1,validatorUrl:\"https://validator.swagger.io/validator\",oauth2RedirectUrl:void 0,persistAuthorization:!1,configs:{},displayOperationId:!1,displayRequestDuration:!1,deepLinking:!1,tryItOutEnabled:!1,requestInterceptor:o=>(o.curlOptions=[],o),responseInterceptor:o=>o,showMutatedRequest:!0,defaultModelRendering:\"example\",defaultModelExpandDepth:1,defaultModelsExpandDepth:1,showExtensions:!1,showCommonExtensions:!1,withCredentials:!1,requestSnippetsEnabled:!1,requestSnippets:{generators:{curl_bash:{title:\"cURL (bash)\",syntax:\"bash\"},curl_powershell:{title:\"cURL (PowerShell)\",syntax:\"powershell\"},curl_cmd:{title:\"cURL (CMD)\",syntax:\"bash\"}},defaultExpanded:!0,languages:null},supportedSubmitMethods:[\"get\",\"put\",\"post\",\"delete\",\"options\",\"head\",\"patch\",\"trace\"],queryConfigEnabled:!1,presets:[PresetApis],plugins:[],initialState:{},fn:{},components:{},syntaxHighlight:{activated:!0,theme:\"agate\"},operationsSorter:null,tagsSorter:null,onComplete:null,modelPropertyMacro:null,parameterMacro:null});var _I=__webpack_require__(61448),EI=__webpack_require__.n(_I),wI=__webpack_require__(77731),SI=__webpack_require__.n(wI);const type_casters_array=(o,s=[])=>Array.isArray(o)?o:s,type_casters_boolean=(o,s=!1)=>!0===o||\"true\"===o||1===o||\"1\"===o||!1!==o&&\"false\"!==o&&0!==o&&\"0\"!==o&&s,dom_node=o=>null===o||\"null\"===o?null:o,type_casters_filter=o=>{const s=String(o);return type_casters_boolean(o,s)},type_casters_function=(o,s)=>\"function\"==typeof o?o:s,nullable_array=o=>Array.isArray(o)?o:null,nullable_function=o=>\"function\"==typeof o?o:null,nullable_string=o=>null===o||\"null\"===o?null:String(o),type_casters_number=(o,s=-1)=>{const i=parseInt(o,10);return Number.isNaN(i)?s:i},type_casters_object=(o,s={})=>UP()(o)?o:s,sorter=o=>\"function\"==typeof o||\"string\"==typeof o?o:null,type_casters_string=o=>String(o),syntax_highlight=(o,s)=>UP()(o)?o:!1===o||\"false\"===o||0===o||\"0\"===o?{activated:!1}:s,undefined_string=o=>void 0===o||\"undefined\"===o?void 0:String(o),xI={components:{typeCaster:type_casters_object},configs:{typeCaster:type_casters_object},configUrl:{typeCaster:nullable_string},deepLinking:{typeCaster:type_casters_boolean,defaultValue:bI.deepLinking},defaultModelExpandDepth:{typeCaster:type_casters_number,defaultValue:bI.defaultModelExpandDepth},defaultModelRendering:{typeCaster:type_casters_string},defaultModelsExpandDepth:{typeCaster:type_casters_number,defaultValue:bI.defaultModelsExpandDepth},displayOperationId:{typeCaster:type_casters_boolean,defaultValue:bI.displayOperationId},displayRequestDuration:{typeCaster:type_casters_boolean,defaultValue:bI.displayRequestDuration},docExpansion:{typeCaster:type_casters_string},dom_id:{typeCaster:nullable_string},domNode:{typeCaster:dom_node},filter:{typeCaster:type_casters_filter},fn:{typeCaster:type_casters_object},initialState:{typeCaster:type_casters_object},layout:{typeCaster:type_casters_string},maxDisplayedTags:{typeCaster:type_casters_number,defaultValue:bI.maxDisplayedTags},modelPropertyMacro:{typeCaster:nullable_function},oauth2RedirectUrl:{typeCaster:undefined_string},onComplete:{typeCaster:nullable_function},operationsSorter:{typeCaster:sorter},paramaterMacro:{typeCaster:nullable_function},persistAuthorization:{typeCaster:type_casters_boolean,defaultValue:bI.persistAuthorization},plugins:{typeCaster:type_casters_array,defaultValue:bI.plugins},presets:{typeCaster:type_casters_array,defaultValue:bI.presets},requestInterceptor:{typeCaster:type_casters_function,defaultValue:bI.requestInterceptor},requestSnippets:{typeCaster:type_casters_object,defaultValue:bI.requestSnippets},requestSnippetsEnabled:{typeCaster:type_casters_boolean,defaultValue:bI.requestSnippetsEnabled},responseInterceptor:{typeCaster:type_casters_function,defaultValue:bI.responseInterceptor},showCommonExtensions:{typeCaster:type_casters_boolean,defaultValue:bI.showCommonExtensions},showExtensions:{typeCaster:type_casters_boolean,defaultValue:bI.showExtensions},showMutatedRequest:{typeCaster:type_casters_boolean,defaultValue:bI.showMutatedRequest},spec:{typeCaster:type_casters_object,defaultValue:bI.spec},supportedSubmitMethods:{typeCaster:type_casters_array,defaultValue:bI.supportedSubmitMethods},syntaxHighlight:{typeCaster:syntax_highlight,defaultValue:bI.syntaxHighlight},\"syntaxHighlight.activated\":{typeCaster:type_casters_boolean,defaultValue:bI.syntaxHighlight.activated},\"syntaxHighlight.theme\":{typeCaster:type_casters_string},tagsSorter:{typeCaster:sorter},tryItOutEnabled:{typeCaster:type_casters_boolean,defaultValue:bI.tryItOutEnabled},url:{typeCaster:type_casters_string},urls:{typeCaster:nullable_array},\"urls.primaryName\":{typeCaster:type_casters_string},validatorUrl:{typeCaster:nullable_string},withCredentials:{typeCaster:type_casters_boolean,defaultValue:bI.withCredentials}},type_cast=o=>Object.entries(xI).reduce(((o,[s,{typeCaster:i,defaultValue:u}])=>{if(EI()(o,s)){const _=i(go()(o,s),u);o=SI()(s,_,o)}return o}),{...o}),config_merge=(o,...s)=>{let i=Symbol.for(\"domNode\"),u=Symbol.for(\"primaryName\");const _=[];for(const o of s){const s={...o};Object.hasOwn(s,\"domNode\")&&(i=s.domNode,delete s.domNode),Object.hasOwn(s,\"urls.primaryName\")?(u=s[\"urls.primaryName\"],delete s[\"urls.primaryName\"]):Array.isArray(s.urls)&&Object.hasOwn(s.urls,\"primaryName\")&&(u=s.urls.primaryName,delete s.urls.primaryName),_.push(s)}const w=We()(o,..._);return i!==Symbol.for(\"domNode\")&&(w.domNode=i),u!==Symbol.for(\"primaryName\")&&Array.isArray(w.urls)&&(w.urls.primaryName=u),type_cast(w)};function SwaggerUI(o){const s=sources_query()(o),i=runtime()(),u=SwaggerUI.config.merge({},SwaggerUI.config.defaults,i,o,s),_=factorization_system(u),w=inline_plugin(u),x=new Store(_);x.register([u.plugins,w]);const C=x.getSystem(),persistConfigs=o=>{x.setConfigs(o),C.configsActions.loaded()},updateSpec=o=>{!s.url&&\"object\"==typeof o.spec&&Object.keys(o.spec).length>0?(C.specActions.updateUrl(\"\"),C.specActions.updateLoadingStatus(\"success\"),C.specActions.updateSpec(JSON.stringify(o.spec))):\"function\"==typeof C.specActions.download&&o.url&&!o.urls&&(C.specActions.updateUrl(o.url),C.specActions.download(o.url))},render=o=>{if(o.domNode)C.render(o.domNode,\"App\");else if(o.dom_id){const s=document.querySelector(o.dom_id);C.render(s,\"App\")}else null===o.dom_id||null===o.domNode||console.error(\"Skipped rendering: no `dom_id` or `domNode` was specified\")};return u.configUrl?((async()=>{const{configUrl:o}=u,i=await sources_url({url:o,system:C})(u),_=SwaggerUI.config.merge({},u,i,s);persistConfigs(_),null!==i&&updateSpec(_),render(_)})(),C):(persistConfigs(u),updateSpec(u),render(u),C)}SwaggerUI.System=Store,SwaggerUI.config={defaults:bI,merge:config_merge,typeCast:type_cast,typeCastMappings:xI},SwaggerUI.presets={base,apis:PresetApis},SwaggerUI.plugins={Auth:auth,Configs:configsPlugin,DeepLining:deep_linking,Err:err,Filter:filter,Icons:icons,JSONSchema5:json_schema_5,JSONSchema5Samples:json_schema_5_samples,JSONSchema202012:json_schema_2020_12,JSONSchema202012Samples:json_schema_2020_12_samples,Layout:plugins_layout,Logs:logs,OpenAPI30:oas3,OpenAPI31:oas3,OnComplete:on_complete,RequestSnippets:plugins_request_snippets,Spec:plugins_spec,SwaggerClient:swagger_client,Util:util,View:view,ViewLegacy:view_legacy,DownloadUrl:downloadUrlPlugin,SyntaxHighlighting:syntax_highlighting,Versions:versions,SafeRender:safe_render};const kI=SwaggerUI})(),_=_.default})()));\n/*! For license information please see swagger-ui-standalone-preset.js.LICENSE.txt */\n!function webpackUniversalModuleDefinition(e,t){\"object\"==typeof exports&&\"object\"==typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define([],t):\"object\"==typeof exports?exports.SwaggerUIStandalonePreset=t():e.SwaggerUIStandalonePreset=t()}(this,(()=>(()=>{var e={9119:(e,t)=>{\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0}),t.BLANK_URL=t.relativeFirstCharacters=t.whitespaceEscapeCharsRegex=t.urlSchemeRegex=t.ctrlCharactersRegex=t.htmlCtrlEntityRegex=t.htmlEntitiesRegex=t.invalidProtocolRegex=void 0,t.invalidProtocolRegex=/^([^\\w]*)(javascript|data|vbscript)/im,t.htmlEntitiesRegex=/&#(\\w+)(^\\w|;)?/g,t.htmlCtrlEntityRegex=/&(newline|tab);/gi,t.ctrlCharactersRegex=/[\\u0000-\\u001F\\u007F-\\u009F\\u2000-\\u200D\\uFEFF]/gim,t.urlSchemeRegex=/^.+(:|:)/gim,t.whitespaceEscapeCharsRegex=/(\\\\|%5[cC])((%(6[eE]|72|74))|[nrt])/g,t.relativeFirstCharacters=[\".\",\"/\"],t.BLANK_URL=\"about:blank\"},6750:(e,t,r)=>{\"use strict\";var n=r(9119);function decodeURI(e){try{return decodeURIComponent(e)}catch(t){return e}}},7526:(e,t)=>{\"use strict\";t.byteLength=function byteLength(e){var t=getLens(e),r=t[0],n=t[1];return 3*(r+n)/4-n},t.toByteArray=function toByteArray(e){var t,r,o=getLens(e),a=o[0],s=o[1],u=new i(function _byteLength(e,t,r){return 3*(t+r)/4-r}(0,a,s)),c=0,f=s>0?a-4:a;for(r=0;r>16&255,u[c++]=t>>8&255,u[c++]=255&t;2===s&&(t=n[e.charCodeAt(r)]<<2|n[e.charCodeAt(r+1)]>>4,u[c++]=255&t);1===s&&(t=n[e.charCodeAt(r)]<<10|n[e.charCodeAt(r+1)]<<4|n[e.charCodeAt(r+2)]>>2,u[c++]=t>>8&255,u[c++]=255&t);return u},t.fromByteArray=function fromByteArray(e){for(var t,n=e.length,i=n%3,o=[],a=16383,s=0,u=n-i;su?u:s+a));1===i?(t=e[n-1],o.push(r[t>>2]+r[t<<4&63]+\"==\")):2===i&&(t=(e[n-2]<<8)+e[n-1],o.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+\"=\"));return o.join(\"\")};for(var r=[],n=[],i=\"undefined\"!=typeof Uint8Array?Uint8Array:Array,o=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\",a=0;a<64;++a)r[a]=o[a],n[o.charCodeAt(a)]=a;function getLens(e){var t=e.length;if(t%4>0)throw new Error(\"Invalid string. Length must be a multiple of 4\");var r=e.indexOf(\"=\");return-1===r&&(r=t),[r,r===t?0:4-r%4]}function encodeChunk(e,t,n){for(var i,o,a=[],s=t;s>18&63]+r[o>>12&63]+r[o>>6&63]+r[63&o]);return a.join(\"\")}n[\"-\".charCodeAt(0)]=62,n[\"_\".charCodeAt(0)]=63},8287:(e,t,r)=>{\"use strict\";const n=r(7526),i=r(251),o=\"function\"==typeof Symbol&&\"function\"==typeof Symbol.for?Symbol.for(\"nodejs.util.inspect.custom\"):null;t.Buffer=Buffer,t.SlowBuffer=function SlowBuffer(e){+e!=e&&(e=0);return Buffer.alloc(+e)},t.INSPECT_MAX_BYTES=50;const a=2147483647;function createBuffer(e){if(e>a)throw new RangeError('The value \"'+e+'\" is invalid for option \"size\"');const t=new Uint8Array(e);return Object.setPrototypeOf(t,Buffer.prototype),t}function Buffer(e,t,r){if(\"number\"==typeof e){if(\"string\"==typeof t)throw new TypeError('The \"string\" argument must be of type string. Received type number');return allocUnsafe(e)}return from(e,t,r)}function from(e,t,r){if(\"string\"==typeof e)return function fromString(e,t){\"string\"==typeof t&&\"\"!==t||(t=\"utf8\");if(!Buffer.isEncoding(t))throw new TypeError(\"Unknown encoding: \"+t);const r=0|byteLength(e,t);let n=createBuffer(r);const i=n.write(e,t);i!==r&&(n=n.slice(0,i));return n}(e,t);if(ArrayBuffer.isView(e))return function fromArrayView(e){if(isInstance(e,Uint8Array)){const t=new Uint8Array(e);return fromArrayBuffer(t.buffer,t.byteOffset,t.byteLength)}return fromArrayLike(e)}(e);if(null==e)throw new TypeError(\"The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type \"+typeof e);if(isInstance(e,ArrayBuffer)||e&&isInstance(e.buffer,ArrayBuffer))return fromArrayBuffer(e,t,r);if(\"undefined\"!=typeof SharedArrayBuffer&&(isInstance(e,SharedArrayBuffer)||e&&isInstance(e.buffer,SharedArrayBuffer)))return fromArrayBuffer(e,t,r);if(\"number\"==typeof e)throw new TypeError('The \"value\" argument must not be of type number. Received type number');const n=e.valueOf&&e.valueOf();if(null!=n&&n!==e)return Buffer.from(n,t,r);const i=function fromObject(e){if(Buffer.isBuffer(e)){const t=0|checked(e.length),r=createBuffer(t);return 0===r.length||e.copy(r,0,0,t),r}if(void 0!==e.length)return\"number\"!=typeof e.length||numberIsNaN(e.length)?createBuffer(0):fromArrayLike(e);if(\"Buffer\"===e.type&&Array.isArray(e.data))return fromArrayLike(e.data)}(e);if(i)return i;if(\"undefined\"!=typeof Symbol&&null!=Symbol.toPrimitive&&\"function\"==typeof e[Symbol.toPrimitive])return Buffer.from(e[Symbol.toPrimitive](\"string\"),t,r);throw new TypeError(\"The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type \"+typeof e)}function assertSize(e){if(\"number\"!=typeof e)throw new TypeError('\"size\" argument must be of type number');if(e<0)throw new RangeError('The value \"'+e+'\" is invalid for option \"size\"')}function allocUnsafe(e){return assertSize(e),createBuffer(e<0?0:0|checked(e))}function fromArrayLike(e){const t=e.length<0?0:0|checked(e.length),r=createBuffer(t);for(let n=0;n=a)throw new RangeError(\"Attempt to allocate Buffer larger than maximum size: 0x\"+a.toString(16)+\" bytes\");return 0|e}function byteLength(e,t){if(Buffer.isBuffer(e))return e.length;if(ArrayBuffer.isView(e)||isInstance(e,ArrayBuffer))return e.byteLength;if(\"string\"!=typeof e)throw new TypeError('The \"string\" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof e);const r=e.length,n=arguments.length>2&&!0===arguments[2];if(!n&&0===r)return 0;let i=!1;for(;;)switch(t){case\"ascii\":case\"latin1\":case\"binary\":return r;case\"utf8\":case\"utf-8\":return utf8ToBytes(e).length;case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":return 2*r;case\"hex\":return r>>>1;case\"base64\":return base64ToBytes(e).length;default:if(i)return n?-1:utf8ToBytes(e).length;t=(\"\"+t).toLowerCase(),i=!0}}function slowToString(e,t,r){let n=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return\"\";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return\"\";if((r>>>=0)<=(t>>>=0))return\"\";for(e||(e=\"utf8\");;)switch(e){case\"hex\":return hexSlice(this,t,r);case\"utf8\":case\"utf-8\":return utf8Slice(this,t,r);case\"ascii\":return asciiSlice(this,t,r);case\"latin1\":case\"binary\":return latin1Slice(this,t,r);case\"base64\":return base64Slice(this,t,r);case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":return utf16leSlice(this,t,r);default:if(n)throw new TypeError(\"Unknown encoding: \"+e);e=(e+\"\").toLowerCase(),n=!0}}function swap(e,t,r){const n=e[t];e[t]=e[r],e[r]=n}function bidirectionalIndexOf(e,t,r,n,i){if(0===e.length)return-1;if(\"string\"==typeof r?(n=r,r=0):r>2147483647?r=2147483647:r<-2147483648&&(r=-2147483648),numberIsNaN(r=+r)&&(r=i?0:e.length-1),r<0&&(r=e.length+r),r>=e.length){if(i)return-1;r=e.length-1}else if(r<0){if(!i)return-1;r=0}if(\"string\"==typeof t&&(t=Buffer.from(t,n)),Buffer.isBuffer(t))return 0===t.length?-1:arrayIndexOf(e,t,r,n,i);if(\"number\"==typeof t)return t&=255,\"function\"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,t,r):Uint8Array.prototype.lastIndexOf.call(e,t,r):arrayIndexOf(e,[t],r,n,i);throw new TypeError(\"val must be string, number or Buffer\")}function arrayIndexOf(e,t,r,n,i){let o,a=1,s=e.length,u=t.length;if(void 0!==n&&(\"ucs2\"===(n=String(n).toLowerCase())||\"ucs-2\"===n||\"utf16le\"===n||\"utf-16le\"===n)){if(e.length<2||t.length<2)return-1;a=2,s/=2,u/=2,r/=2}function read(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}if(i){let n=-1;for(o=r;os&&(r=s-u),o=r;o>=0;o--){let r=!0;for(let n=0;ni&&(n=i):n=i;const o=t.length;let a;for(n>o/2&&(n=o/2),a=0;a>8,i=r%256,o.push(i),o.push(n);return o}(t,e.length-r),e,r,n)}function base64Slice(e,t,r){return 0===t&&r===e.length?n.fromByteArray(e):n.fromByteArray(e.slice(t,r))}function utf8Slice(e,t,r){r=Math.min(e.length,r);const n=[];let i=t;for(;i239?4:t>223?3:t>191?2:1;if(i+a<=r){let r,n,s,u;switch(a){case 1:t<128&&(o=t);break;case 2:r=e[i+1],128==(192&r)&&(u=(31&t)<<6|63&r,u>127&&(o=u));break;case 3:r=e[i+1],n=e[i+2],128==(192&r)&&128==(192&n)&&(u=(15&t)<<12|(63&r)<<6|63&n,u>2047&&(u<55296||u>57343)&&(o=u));break;case 4:r=e[i+1],n=e[i+2],s=e[i+3],128==(192&r)&&128==(192&n)&&128==(192&s)&&(u=(15&t)<<18|(63&r)<<12|(63&n)<<6|63&s,u>65535&&u<1114112&&(o=u))}}null===o?(o=65533,a=1):o>65535&&(o-=65536,n.push(o>>>10&1023|55296),o=56320|1023&o),n.push(o),i+=a}return function decodeCodePointsArray(e){const t=e.length;if(t<=s)return String.fromCharCode.apply(String,e);let r=\"\",n=0;for(;nn.length?(Buffer.isBuffer(t)||(t=Buffer.from(t)),t.copy(n,i)):Uint8Array.prototype.set.call(n,t,i);else{if(!Buffer.isBuffer(t))throw new TypeError('\"list\" argument must be an Array of Buffers');t.copy(n,i)}i+=t.length}return n},Buffer.byteLength=byteLength,Buffer.prototype._isBuffer=!0,Buffer.prototype.swap16=function swap16(){const e=this.length;if(e%2!=0)throw new RangeError(\"Buffer size must be a multiple of 16-bits\");for(let t=0;tr&&(e+=\" ... \"),\"\"},o&&(Buffer.prototype[o]=Buffer.prototype.inspect),Buffer.prototype.compare=function compare(e,t,r,n,i){if(isInstance(e,Uint8Array)&&(e=Buffer.from(e,e.offset,e.byteLength)),!Buffer.isBuffer(e))throw new TypeError('The \"target\" argument must be one of type Buffer or Uint8Array. Received type '+typeof e);if(void 0===t&&(t=0),void 0===r&&(r=e?e.length:0),void 0===n&&(n=0),void 0===i&&(i=this.length),t<0||r>e.length||n<0||i>this.length)throw new RangeError(\"out of range index\");if(n>=i&&t>=r)return 0;if(n>=i)return-1;if(t>=r)return 1;if(this===e)return 0;let o=(i>>>=0)-(n>>>=0),a=(r>>>=0)-(t>>>=0);const s=Math.min(o,a),u=this.slice(n,i),c=e.slice(t,r);for(let e=0;e>>=0,isFinite(r)?(r>>>=0,void 0===n&&(n=\"utf8\")):(n=r,r=void 0)}const i=this.length-t;if((void 0===r||r>i)&&(r=i),e.length>0&&(r<0||t<0)||t>this.length)throw new RangeError(\"Attempt to write outside buffer bounds\");n||(n=\"utf8\");let o=!1;for(;;)switch(n){case\"hex\":return hexWrite(this,e,t,r);case\"utf8\":case\"utf-8\":return utf8Write(this,e,t,r);case\"ascii\":case\"latin1\":case\"binary\":return asciiWrite(this,e,t,r);case\"base64\":return base64Write(this,e,t,r);case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":return ucs2Write(this,e,t,r);default:if(o)throw new TypeError(\"Unknown encoding: \"+n);n=(\"\"+n).toLowerCase(),o=!0}},Buffer.prototype.toJSON=function toJSON(){return{type:\"Buffer\",data:Array.prototype.slice.call(this._arr||this,0)}};const s=4096;function asciiSlice(e,t,r){let n=\"\";r=Math.min(e.length,r);for(let i=t;in)&&(r=n);let i=\"\";for(let n=t;nr)throw new RangeError(\"Trying to access beyond buffer length\")}function checkInt(e,t,r,n,i,o){if(!Buffer.isBuffer(e))throw new TypeError('\"buffer\" argument must be a Buffer instance');if(t>i||te.length)throw new RangeError(\"Index out of range\")}function wrtBigUInt64LE(e,t,r,n,i){checkIntBI(t,n,i,e,r,7);let o=Number(t&BigInt(4294967295));e[r++]=o,o>>=8,e[r++]=o,o>>=8,e[r++]=o,o>>=8,e[r++]=o;let a=Number(t>>BigInt(32)&BigInt(4294967295));return e[r++]=a,a>>=8,e[r++]=a,a>>=8,e[r++]=a,a>>=8,e[r++]=a,r}function wrtBigUInt64BE(e,t,r,n,i){checkIntBI(t,n,i,e,r,7);let o=Number(t&BigInt(4294967295));e[r+7]=o,o>>=8,e[r+6]=o,o>>=8,e[r+5]=o,o>>=8,e[r+4]=o;let a=Number(t>>BigInt(32)&BigInt(4294967295));return e[r+3]=a,a>>=8,e[r+2]=a,a>>=8,e[r+1]=a,a>>=8,e[r]=a,r+8}function checkIEEE754(e,t,r,n,i,o){if(r+n>e.length)throw new RangeError(\"Index out of range\");if(r<0)throw new RangeError(\"Index out of range\")}function writeFloat(e,t,r,n,o){return t=+t,r>>>=0,o||checkIEEE754(e,0,r,4),i.write(e,t,r,n,23,4),r+4}function writeDouble(e,t,r,n,o){return t=+t,r>>>=0,o||checkIEEE754(e,0,r,8),i.write(e,t,r,n,52,8),r+8}Buffer.prototype.slice=function slice(e,t){const r=this.length;(e=~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),(t=void 0===t?r:~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),t>>=0,t>>>=0,r||checkOffset(e,t,this.length);let n=this[e],i=1,o=0;for(;++o>>=0,t>>>=0,r||checkOffset(e,t,this.length);let n=this[e+--t],i=1;for(;t>0&&(i*=256);)n+=this[e+--t]*i;return n},Buffer.prototype.readUint8=Buffer.prototype.readUInt8=function readUInt8(e,t){return e>>>=0,t||checkOffset(e,1,this.length),this[e]},Buffer.prototype.readUint16LE=Buffer.prototype.readUInt16LE=function readUInt16LE(e,t){return e>>>=0,t||checkOffset(e,2,this.length),this[e]|this[e+1]<<8},Buffer.prototype.readUint16BE=Buffer.prototype.readUInt16BE=function readUInt16BE(e,t){return e>>>=0,t||checkOffset(e,2,this.length),this[e]<<8|this[e+1]},Buffer.prototype.readUint32LE=Buffer.prototype.readUInt32LE=function readUInt32LE(e,t){return e>>>=0,t||checkOffset(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},Buffer.prototype.readUint32BE=Buffer.prototype.readUInt32BE=function readUInt32BE(e,t){return e>>>=0,t||checkOffset(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},Buffer.prototype.readBigUInt64LE=defineBigIntMethod((function readBigUInt64LE(e){validateNumber(e>>>=0,\"offset\");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||boundsError(e,this.length-8);const n=t+256*this[++e]+65536*this[++e]+this[++e]*2**24,i=this[++e]+256*this[++e]+65536*this[++e]+r*2**24;return BigInt(n)+(BigInt(i)<>>=0,\"offset\");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||boundsError(e,this.length-8);const n=t*2**24+65536*this[++e]+256*this[++e]+this[++e],i=this[++e]*2**24+65536*this[++e]+256*this[++e]+r;return(BigInt(n)<>>=0,t>>>=0,r||checkOffset(e,t,this.length);let n=this[e],i=1,o=0;for(;++o=i&&(n-=Math.pow(2,8*t)),n},Buffer.prototype.readIntBE=function readIntBE(e,t,r){e>>>=0,t>>>=0,r||checkOffset(e,t,this.length);let n=t,i=1,o=this[e+--n];for(;n>0&&(i*=256);)o+=this[e+--n]*i;return i*=128,o>=i&&(o-=Math.pow(2,8*t)),o},Buffer.prototype.readInt8=function readInt8(e,t){return e>>>=0,t||checkOffset(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},Buffer.prototype.readInt16LE=function readInt16LE(e,t){e>>>=0,t||checkOffset(e,2,this.length);const r=this[e]|this[e+1]<<8;return 32768&r?4294901760|r:r},Buffer.prototype.readInt16BE=function readInt16BE(e,t){e>>>=0,t||checkOffset(e,2,this.length);const r=this[e+1]|this[e]<<8;return 32768&r?4294901760|r:r},Buffer.prototype.readInt32LE=function readInt32LE(e,t){return e>>>=0,t||checkOffset(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},Buffer.prototype.readInt32BE=function readInt32BE(e,t){return e>>>=0,t||checkOffset(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},Buffer.prototype.readBigInt64LE=defineBigIntMethod((function readBigInt64LE(e){validateNumber(e>>>=0,\"offset\");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||boundsError(e,this.length-8);const n=this[e+4]+256*this[e+5]+65536*this[e+6]+(r<<24);return(BigInt(n)<>>=0,\"offset\");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||boundsError(e,this.length-8);const n=(t<<24)+65536*this[++e]+256*this[++e]+this[++e];return(BigInt(n)<>>=0,t||checkOffset(e,4,this.length),i.read(this,e,!0,23,4)},Buffer.prototype.readFloatBE=function readFloatBE(e,t){return e>>>=0,t||checkOffset(e,4,this.length),i.read(this,e,!1,23,4)},Buffer.prototype.readDoubleLE=function readDoubleLE(e,t){return e>>>=0,t||checkOffset(e,8,this.length),i.read(this,e,!0,52,8)},Buffer.prototype.readDoubleBE=function readDoubleBE(e,t){return e>>>=0,t||checkOffset(e,8,this.length),i.read(this,e,!1,52,8)},Buffer.prototype.writeUintLE=Buffer.prototype.writeUIntLE=function writeUIntLE(e,t,r,n){if(e=+e,t>>>=0,r>>>=0,!n){checkInt(this,e,t,r,Math.pow(2,8*r)-1,0)}let i=1,o=0;for(this[t]=255&e;++o>>=0,r>>>=0,!n){checkInt(this,e,t,r,Math.pow(2,8*r)-1,0)}let i=r-1,o=1;for(this[t+i]=255&e;--i>=0&&(o*=256);)this[t+i]=e/o&255;return t+r},Buffer.prototype.writeUint8=Buffer.prototype.writeUInt8=function writeUInt8(e,t,r){return e=+e,t>>>=0,r||checkInt(this,e,t,1,255,0),this[t]=255&e,t+1},Buffer.prototype.writeUint16LE=Buffer.prototype.writeUInt16LE=function writeUInt16LE(e,t,r){return e=+e,t>>>=0,r||checkInt(this,e,t,2,65535,0),this[t]=255&e,this[t+1]=e>>>8,t+2},Buffer.prototype.writeUint16BE=Buffer.prototype.writeUInt16BE=function writeUInt16BE(e,t,r){return e=+e,t>>>=0,r||checkInt(this,e,t,2,65535,0),this[t]=e>>>8,this[t+1]=255&e,t+2},Buffer.prototype.writeUint32LE=Buffer.prototype.writeUInt32LE=function writeUInt32LE(e,t,r){return e=+e,t>>>=0,r||checkInt(this,e,t,4,4294967295,0),this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e,t+4},Buffer.prototype.writeUint32BE=Buffer.prototype.writeUInt32BE=function writeUInt32BE(e,t,r){return e=+e,t>>>=0,r||checkInt(this,e,t,4,4294967295,0),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},Buffer.prototype.writeBigUInt64LE=defineBigIntMethod((function writeBigUInt64LE(e,t=0){return wrtBigUInt64LE(this,e,t,BigInt(0),BigInt(\"0xffffffffffffffff\"))})),Buffer.prototype.writeBigUInt64BE=defineBigIntMethod((function writeBigUInt64BE(e,t=0){return wrtBigUInt64BE(this,e,t,BigInt(0),BigInt(\"0xffffffffffffffff\"))})),Buffer.prototype.writeIntLE=function writeIntLE(e,t,r,n){if(e=+e,t>>>=0,!n){const n=Math.pow(2,8*r-1);checkInt(this,e,t,r,n-1,-n)}let i=0,o=1,a=0;for(this[t]=255&e;++i>>=0,!n){const n=Math.pow(2,8*r-1);checkInt(this,e,t,r,n-1,-n)}let i=r-1,o=1,a=0;for(this[t+i]=255&e;--i>=0&&(o*=256);)e<0&&0===a&&0!==this[t+i+1]&&(a=1),this[t+i]=(e/o|0)-a&255;return t+r},Buffer.prototype.writeInt8=function writeInt8(e,t,r){return e=+e,t>>>=0,r||checkInt(this,e,t,1,127,-128),e<0&&(e=255+e+1),this[t]=255&e,t+1},Buffer.prototype.writeInt16LE=function writeInt16LE(e,t,r){return e=+e,t>>>=0,r||checkInt(this,e,t,2,32767,-32768),this[t]=255&e,this[t+1]=e>>>8,t+2},Buffer.prototype.writeInt16BE=function writeInt16BE(e,t,r){return e=+e,t>>>=0,r||checkInt(this,e,t,2,32767,-32768),this[t]=e>>>8,this[t+1]=255&e,t+2},Buffer.prototype.writeInt32LE=function writeInt32LE(e,t,r){return e=+e,t>>>=0,r||checkInt(this,e,t,4,2147483647,-2147483648),this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24,t+4},Buffer.prototype.writeInt32BE=function writeInt32BE(e,t,r){return e=+e,t>>>=0,r||checkInt(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},Buffer.prototype.writeBigInt64LE=defineBigIntMethod((function writeBigInt64LE(e,t=0){return wrtBigUInt64LE(this,e,t,-BigInt(\"0x8000000000000000\"),BigInt(\"0x7fffffffffffffff\"))})),Buffer.prototype.writeBigInt64BE=defineBigIntMethod((function writeBigInt64BE(e,t=0){return wrtBigUInt64BE(this,e,t,-BigInt(\"0x8000000000000000\"),BigInt(\"0x7fffffffffffffff\"))})),Buffer.prototype.writeFloatLE=function writeFloatLE(e,t,r){return writeFloat(this,e,t,!0,r)},Buffer.prototype.writeFloatBE=function writeFloatBE(e,t,r){return writeFloat(this,e,t,!1,r)},Buffer.prototype.writeDoubleLE=function writeDoubleLE(e,t,r){return writeDouble(this,e,t,!0,r)},Buffer.prototype.writeDoubleBE=function writeDoubleBE(e,t,r){return writeDouble(this,e,t,!1,r)},Buffer.prototype.copy=function copy(e,t,r,n){if(!Buffer.isBuffer(e))throw new TypeError(\"argument should be a Buffer\");if(r||(r=0),n||0===n||(n=this.length),t>=e.length&&(t=e.length),t||(t=0),n>0&&n=this.length)throw new RangeError(\"Index out of range\");if(n<0)throw new RangeError(\"sourceEnd out of bounds\");n>this.length&&(n=this.length),e.length-t>>=0,r=void 0===r?this.length:r>>>0,e||(e=0),\"number\"==typeof e)for(i=t;i=n+4;r-=3)t=`_${e.slice(r-3,r)}${t}`;return`${e.slice(0,r)}${t}`}function checkIntBI(e,t,r,n,i,o){if(e>r||e3?0===t||t===BigInt(0)?`>= 0${n} and < 2${n} ** ${8*(o+1)}${n}`:`>= -(2${n} ** ${8*(o+1)-1}${n}) and < 2 ** ${8*(o+1)-1}${n}`:`>= ${t}${n} and <= ${r}${n}`,new u.ERR_OUT_OF_RANGE(\"value\",i,e)}!function checkBounds(e,t,r){validateNumber(t,\"offset\"),void 0!==e[t]&&void 0!==e[t+r]||boundsError(t,e.length-(r+1))}(n,i,o)}function validateNumber(e,t){if(\"number\"!=typeof e)throw new u.ERR_INVALID_ARG_TYPE(t,\"number\",e)}function boundsError(e,t,r){if(Math.floor(e)!==e)throw validateNumber(e,r),new u.ERR_OUT_OF_RANGE(r||\"offset\",\"an integer\",e);if(t<0)throw new u.ERR_BUFFER_OUT_OF_BOUNDS;throw new u.ERR_OUT_OF_RANGE(r||\"offset\",`>= ${r?1:0} and <= ${t}`,e)}E(\"ERR_BUFFER_OUT_OF_BOUNDS\",(function(e){return e?`${e} is outside of buffer bounds`:\"Attempt to access memory outside buffer bounds\"}),RangeError),E(\"ERR_INVALID_ARG_TYPE\",(function(e,t){return`The \"${e}\" argument must be of type number. Received type ${typeof t}`}),TypeError),E(\"ERR_OUT_OF_RANGE\",(function(e,t,r){let n=`The value of \"${e}\" is out of range.`,i=r;return Number.isInteger(r)&&Math.abs(r)>2**32?i=addNumericalSeparator(String(r)):\"bigint\"==typeof r&&(i=String(r),(r>BigInt(2)**BigInt(32)||r<-(BigInt(2)**BigInt(32)))&&(i=addNumericalSeparator(i)),i+=\"n\"),n+=` It must be ${t}. Received ${i}`,n}),RangeError);const c=/[^+/0-9A-Za-z-_]/g;function utf8ToBytes(e,t){let r;t=t||1/0;const n=e.length;let i=null;const o=[];for(let a=0;a55295&&r<57344){if(!i){if(r>56319){(t-=3)>-1&&o.push(239,191,189);continue}if(a+1===n){(t-=3)>-1&&o.push(239,191,189);continue}i=r;continue}if(r<56320){(t-=3)>-1&&o.push(239,191,189),i=r;continue}r=65536+(i-55296<<10|r-56320)}else i&&(t-=3)>-1&&o.push(239,191,189);if(i=null,r<128){if((t-=1)<0)break;o.push(r)}else if(r<2048){if((t-=2)<0)break;o.push(r>>6|192,63&r|128)}else if(r<65536){if((t-=3)<0)break;o.push(r>>12|224,r>>6&63|128,63&r|128)}else{if(!(r<1114112))throw new Error(\"Invalid code point\");if((t-=4)<0)break;o.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}}return o}function base64ToBytes(e){return n.toByteArray(function base64clean(e){if((e=(e=e.split(\"=\")[0]).trim().replace(c,\"\")).length<2)return\"\";for(;e.length%4!=0;)e+=\"=\";return e}(e))}function blitBuffer(e,t,r,n){let i;for(i=0;i=t.length||i>=e.length);++i)t[i+r]=e[i];return i}function isInstance(e,t){return e instanceof t||null!=e&&null!=e.constructor&&null!=e.constructor.name&&e.constructor.name===t.name}function numberIsNaN(e){return e!=e}const f=function(){const e=\"0123456789abcdef\",t=new Array(256);for(let r=0;r<16;++r){const n=16*r;for(let i=0;i<16;++i)t[n+i]=e[r]+e[i]}return t}();function defineBigIntMethod(e){return\"undefined\"==typeof BigInt?BufferBigIntNotDefined:e}function BufferBigIntNotDefined(){throw new Error(\"BigInt not supported\")}},2205:function(e,t,r){var n;n=void 0!==r.g?r.g:this,e.exports=function(e){if(e.CSS&&e.CSS.escape)return e.CSS.escape;var cssEscape=function(e){if(0==arguments.length)throw new TypeError(\"`CSS.escape` requires an argument.\");for(var t,r=String(e),n=r.length,i=-1,o=\"\",a=r.charCodeAt(0);++i=1&&t<=31||127==t||0==i&&t>=48&&t<=57||1==i&&t>=48&&t<=57&&45==a?\"\\\\\"+t.toString(16)+\" \":0==i&&1==n&&45==t||!(t>=128||45==t||95==t||t>=48&&t<=57||t>=65&&t<=90||t>=97&&t<=122)?\"\\\\\"+r.charAt(i):r.charAt(i):o+=\"�\";return o};return e.CSS||(e.CSS={}),e.CSS.escape=cssEscape,cssEscape}(n)},251:(e,t)=>{t.read=function(e,t,r,n,i){var o,a,s=8*i-n-1,u=(1<>1,f=-7,l=r?i-1:0,h=r?-1:1,p=e[t+l];for(l+=h,o=p&(1<<-f)-1,p>>=-f,f+=s;f>0;o=256*o+e[t+l],l+=h,f-=8);for(a=o&(1<<-f)-1,o>>=-f,f+=n;f>0;a=256*a+e[t+l],l+=h,f-=8);if(0===o)o=1-c;else{if(o===u)return a?NaN:1/0*(p?-1:1);a+=Math.pow(2,n),o-=c}return(p?-1:1)*a*Math.pow(2,o-n)},t.write=function(e,t,r,n,i,o){var a,s,u,c=8*o-i-1,f=(1<>1,h=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,p=n?0:o-1,d=n?1:-1,_=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,a=f):(a=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-a))<1&&(a--,u*=2),(t+=a+l>=1?h/u:h*Math.pow(2,1-l))*u>=2&&(a++,u/=2),a+l>=f?(s=0,a=f):a+l>=1?(s=(t*u-1)*Math.pow(2,i),a+=l):(s=t*Math.pow(2,l-1)*Math.pow(2,i),a=0));i>=8;e[r+p]=255&s,p+=d,s/=256,i-=8);for(a=a<0;e[r+p]=255&a,p+=d,a/=256,c-=8);e[r+p-d]|=128*_}},9404:function(e){e.exports=function(){\"use strict\";var e=Array.prototype.slice;function createClass(e,t){t&&(e.prototype=Object.create(t.prototype)),e.prototype.constructor=e}function Iterable(e){return isIterable(e)?e:Seq(e)}function KeyedIterable(e){return isKeyed(e)?e:KeyedSeq(e)}function IndexedIterable(e){return isIndexed(e)?e:IndexedSeq(e)}function SetIterable(e){return isIterable(e)&&!isAssociative(e)?e:SetSeq(e)}function isIterable(e){return!(!e||!e[t])}function isKeyed(e){return!(!e||!e[r])}function isIndexed(e){return!(!e||!e[n])}function isAssociative(e){return isKeyed(e)||isIndexed(e)}function isOrdered(e){return!(!e||!e[i])}createClass(KeyedIterable,Iterable),createClass(IndexedIterable,Iterable),createClass(SetIterable,Iterable),Iterable.isIterable=isIterable,Iterable.isKeyed=isKeyed,Iterable.isIndexed=isIndexed,Iterable.isAssociative=isAssociative,Iterable.isOrdered=isOrdered,Iterable.Keyed=KeyedIterable,Iterable.Indexed=IndexedIterable,Iterable.Set=SetIterable;var t=\"@@__IMMUTABLE_ITERABLE__@@\",r=\"@@__IMMUTABLE_KEYED__@@\",n=\"@@__IMMUTABLE_INDEXED__@@\",i=\"@@__IMMUTABLE_ORDERED__@@\",o=\"delete\",a=5,s=1<>>0;if(\"\"+r!==t||4294967295===r)return NaN;t=r}return t<0?ensureSize(e)+t:t}function returnTrue(){return!0}function wholeSlice(e,t,r){return(0===e||void 0!==r&&e<=-r)&&(void 0===t||void 0!==r&&t>=r)}function resolveBegin(e,t){return resolveIndex(e,t,0)}function resolveEnd(e,t){return resolveIndex(e,t,t)}function resolveIndex(e,t,r){return void 0===e?r:e<0?Math.max(0,t+e):void 0===t?e:Math.min(t,e)}var h=0,p=1,d=2,_=\"function\"==typeof Symbol&&Symbol.iterator,y=\"@@iterator\",m=_||y;function Iterator(e){this.next=e}function iteratorValue(e,t,r,n){var i=0===e?t:1===e?r:[t,r];return n?n.value=i:n={value:i,done:!1},n}function iteratorDone(){return{value:void 0,done:!0}}function hasIterator(e){return!!getIteratorFn(e)}function isIterator(e){return e&&\"function\"==typeof e.next}function getIterator(e){var t=getIteratorFn(e);return t&&t.call(e)}function getIteratorFn(e){var t=e&&(_&&e[_]||e[y]);if(\"function\"==typeof t)return t}function isArrayLike(e){return e&&\"number\"==typeof e.length}function Seq(e){return null==e?emptySequence():isIterable(e)?e.toSeq():seqFromValue(e)}function KeyedSeq(e){return null==e?emptySequence().toKeyedSeq():isIterable(e)?isKeyed(e)?e.toSeq():e.fromEntrySeq():keyedSeqFromValue(e)}function IndexedSeq(e){return null==e?emptySequence():isIterable(e)?isKeyed(e)?e.entrySeq():e.toIndexedSeq():indexedSeqFromValue(e)}function SetSeq(e){return(null==e?emptySequence():isIterable(e)?isKeyed(e)?e.entrySeq():e:indexedSeqFromValue(e)).toSetSeq()}Iterator.prototype.toString=function(){return\"[Iterator]\"},Iterator.KEYS=h,Iterator.VALUES=p,Iterator.ENTRIES=d,Iterator.prototype.inspect=Iterator.prototype.toSource=function(){return this.toString()},Iterator.prototype[m]=function(){return this},createClass(Seq,Iterable),Seq.of=function(){return Seq(arguments)},Seq.prototype.toSeq=function(){return this},Seq.prototype.toString=function(){return this.__toString(\"Seq {\",\"}\")},Seq.prototype.cacheResult=function(){return!this._cache&&this.__iterateUncached&&(this._cache=this.entrySeq().toArray(),this.size=this._cache.length),this},Seq.prototype.__iterate=function(e,t){return seqIterate(this,e,t,!0)},Seq.prototype.__iterator=function(e,t){return seqIterator(this,e,t,!0)},createClass(KeyedSeq,Seq),KeyedSeq.prototype.toKeyedSeq=function(){return this},createClass(IndexedSeq,Seq),IndexedSeq.of=function(){return IndexedSeq(arguments)},IndexedSeq.prototype.toIndexedSeq=function(){return this},IndexedSeq.prototype.toString=function(){return this.__toString(\"Seq [\",\"]\")},IndexedSeq.prototype.__iterate=function(e,t){return seqIterate(this,e,t,!1)},IndexedSeq.prototype.__iterator=function(e,t){return seqIterator(this,e,t,!1)},createClass(SetSeq,Seq),SetSeq.of=function(){return SetSeq(arguments)},SetSeq.prototype.toSetSeq=function(){return this},Seq.isSeq=isSeq,Seq.Keyed=KeyedSeq,Seq.Set=SetSeq,Seq.Indexed=IndexedSeq;var g,v,b,w=\"@@__IMMUTABLE_SEQ__@@\";function ArraySeq(e){this._array=e,this.size=e.length}function ObjectSeq(e){var t=Object.keys(e);this._object=e,this._keys=t,this.size=t.length}function IterableSeq(e){this._iterable=e,this.size=e.length||e.size}function IteratorSeq(e){this._iterator=e,this._iteratorCache=[]}function isSeq(e){return!(!e||!e[w])}function emptySequence(){return g||(g=new ArraySeq([]))}function keyedSeqFromValue(e){var t=Array.isArray(e)?new ArraySeq(e).fromEntrySeq():isIterator(e)?new IteratorSeq(e).fromEntrySeq():hasIterator(e)?new IterableSeq(e).fromEntrySeq():\"object\"==typeof e?new ObjectSeq(e):void 0;if(!t)throw new TypeError(\"Expected Array or iterable object of [k, v] entries, or keyed object: \"+e);return t}function indexedSeqFromValue(e){var t=maybeIndexedSeqFromValue(e);if(!t)throw new TypeError(\"Expected Array or iterable object of values: \"+e);return t}function seqFromValue(e){var t=maybeIndexedSeqFromValue(e)||\"object\"==typeof e&&new ObjectSeq(e);if(!t)throw new TypeError(\"Expected Array or iterable object of values, or keyed object: \"+e);return t}function maybeIndexedSeqFromValue(e){return isArrayLike(e)?new ArraySeq(e):isIterator(e)?new IteratorSeq(e):hasIterator(e)?new IterableSeq(e):void 0}function seqIterate(e,t,r,n){var i=e._cache;if(i){for(var o=i.length-1,a=0;a<=o;a++){var s=i[r?o-a:a];if(!1===t(s[1],n?s[0]:a,e))return a+1}return a}return e.__iterateUncached(t,r)}function seqIterator(e,t,r,n){var i=e._cache;if(i){var o=i.length-1,a=0;return new Iterator((function(){var e=i[r?o-a:a];return a++>o?iteratorDone():iteratorValue(t,n?e[0]:a-1,e[1])}))}return e.__iteratorUncached(t,r)}function fromJS(e,t){return t?fromJSWith(t,e,\"\",{\"\":e}):fromJSDefault(e)}function fromJSWith(e,t,r,n){return Array.isArray(t)?e.call(n,r,IndexedSeq(t).map((function(r,n){return fromJSWith(e,r,n,t)}))):isPlainObj(t)?e.call(n,r,KeyedSeq(t).map((function(r,n){return fromJSWith(e,r,n,t)}))):t}function fromJSDefault(e){return Array.isArray(e)?IndexedSeq(e).map(fromJSDefault).toList():isPlainObj(e)?KeyedSeq(e).map(fromJSDefault).toMap():e}function isPlainObj(e){return e&&(e.constructor===Object||void 0===e.constructor)}function is(e,t){if(e===t||e!=e&&t!=t)return!0;if(!e||!t)return!1;if(\"function\"==typeof e.valueOf&&\"function\"==typeof t.valueOf){if((e=e.valueOf())===(t=t.valueOf())||e!=e&&t!=t)return!0;if(!e||!t)return!1}return!(\"function\"!=typeof e.equals||\"function\"!=typeof t.equals||!e.equals(t))}function deepEqual(e,t){if(e===t)return!0;if(!isIterable(t)||void 0!==e.size&&void 0!==t.size&&e.size!==t.size||void 0!==e.__hash&&void 0!==t.__hash&&e.__hash!==t.__hash||isKeyed(e)!==isKeyed(t)||isIndexed(e)!==isIndexed(t)||isOrdered(e)!==isOrdered(t))return!1;if(0===e.size&&0===t.size)return!0;var r=!isAssociative(e);if(isOrdered(e)){var n=e.entries();return t.every((function(e,t){var i=n.next().value;return i&&is(i[1],e)&&(r||is(i[0],t))}))&&n.next().done}var i=!1;if(void 0===e.size)if(void 0===t.size)\"function\"==typeof e.cacheResult&&e.cacheResult();else{i=!0;var o=e;e=t,t=o}var a=!0,s=t.__iterate((function(t,n){if(r?!e.has(t):i?!is(t,e.get(n,c)):!is(e.get(n,c),t))return a=!1,!1}));return a&&e.size===s}function Repeat(e,t){if(!(this instanceof Repeat))return new Repeat(e,t);if(this._value=e,this.size=void 0===t?1/0:Math.max(0,t),0===this.size){if(v)return v;v=this}}function invariant(e,t){if(!e)throw new Error(t)}function Range(e,t,r){if(!(this instanceof Range))return new Range(e,t,r);if(invariant(0!==r,\"Cannot step a Range by 0\"),e=e||0,void 0===t&&(t=1/0),r=void 0===r?1:Math.abs(r),tn?iteratorDone():iteratorValue(e,i,r[t?n-i++:i++])}))},createClass(ObjectSeq,KeyedSeq),ObjectSeq.prototype.get=function(e,t){return void 0===t||this.has(e)?this._object[e]:t},ObjectSeq.prototype.has=function(e){return this._object.hasOwnProperty(e)},ObjectSeq.prototype.__iterate=function(e,t){for(var r=this._object,n=this._keys,i=n.length-1,o=0;o<=i;o++){var a=n[t?i-o:o];if(!1===e(r[a],a,this))return o+1}return o},ObjectSeq.prototype.__iterator=function(e,t){var r=this._object,n=this._keys,i=n.length-1,o=0;return new Iterator((function(){var a=n[t?i-o:o];return o++>i?iteratorDone():iteratorValue(e,a,r[a])}))},ObjectSeq.prototype[i]=!0,createClass(IterableSeq,IndexedSeq),IterableSeq.prototype.__iterateUncached=function(e,t){if(t)return this.cacheResult().__iterate(e,t);var r=getIterator(this._iterable),n=0;if(isIterator(r))for(var i;!(i=r.next()).done&&!1!==e(i.value,n++,this););return n},IterableSeq.prototype.__iteratorUncached=function(e,t){if(t)return this.cacheResult().__iterator(e,t);var r=getIterator(this._iterable);if(!isIterator(r))return new Iterator(iteratorDone);var n=0;return new Iterator((function(){var t=r.next();return t.done?t:iteratorValue(e,n++,t.value)}))},createClass(IteratorSeq,IndexedSeq),IteratorSeq.prototype.__iterateUncached=function(e,t){if(t)return this.cacheResult().__iterate(e,t);for(var r,n=this._iterator,i=this._iteratorCache,o=0;o=n.length){var t=r.next();if(t.done)return t;n[i]=t.value}return iteratorValue(e,i,n[i++])}))},createClass(Repeat,IndexedSeq),Repeat.prototype.toString=function(){return 0===this.size?\"Repeat []\":\"Repeat [ \"+this._value+\" \"+this.size+\" times ]\"},Repeat.prototype.get=function(e,t){return this.has(e)?this._value:t},Repeat.prototype.includes=function(e){return is(this._value,e)},Repeat.prototype.slice=function(e,t){var r=this.size;return wholeSlice(e,t,r)?this:new Repeat(this._value,resolveEnd(t,r)-resolveBegin(e,r))},Repeat.prototype.reverse=function(){return this},Repeat.prototype.indexOf=function(e){return is(this._value,e)?0:-1},Repeat.prototype.lastIndexOf=function(e){return is(this._value,e)?this.size:-1},Repeat.prototype.__iterate=function(e,t){for(var r=0;r=0&&t=0&&rr?iteratorDone():iteratorValue(e,o++,a)}))},Range.prototype.equals=function(e){return e instanceof Range?this._start===e._start&&this._end===e._end&&this._step===e._step:deepEqual(this,e)},createClass(Collection,Iterable),createClass(KeyedCollection,Collection),createClass(IndexedCollection,Collection),createClass(SetCollection,Collection),Collection.Keyed=KeyedCollection,Collection.Indexed=IndexedCollection,Collection.Set=SetCollection;var I=\"function\"==typeof Math.imul&&-2===Math.imul(4294967295,2)?Math.imul:function imul(e,t){var r=65535&(e|=0),n=65535&(t|=0);return r*n+((e>>>16)*n+r*(t>>>16)<<16>>>0)|0};function smi(e){return e>>>1&1073741824|3221225471&e}function hash(e){if(!1===e||null==e)return 0;if(\"function\"==typeof e.valueOf&&(!1===(e=e.valueOf())||null==e))return 0;if(!0===e)return 1;var t=typeof e;if(\"number\"===t){if(e!=e||e===1/0)return 0;var r=0|e;for(r!==e&&(r^=4294967295*e);e>4294967295;)r^=e/=4294967295;return smi(r)}if(\"string\"===t)return e.length>j?cachedHashString(e):hashString(e);if(\"function\"==typeof e.hashCode)return e.hashCode();if(\"object\"===t)return hashJSObj(e);if(\"function\"==typeof e.toString)return hashString(e.toString());throw new Error(\"Value type \"+t+\" cannot be hashed.\")}function cachedHashString(e){var t=D[e];return void 0===t&&(t=hashString(e),P===z&&(P=0,D={}),P++,D[e]=t),t}function hashString(e){for(var t=0,r=0;r0)switch(e.nodeType){case 1:return e.uniqueID;case 9:return e.documentElement&&e.documentElement.uniqueID}}var k,C=\"function\"==typeof WeakMap;C&&(k=new WeakMap);var q=0,L=\"__immutablehash__\";\"function\"==typeof Symbol&&(L=Symbol(L));var j=16,z=255,P=0,D={};function assertNotInfinite(e){invariant(e!==1/0,\"Cannot perform this action with an infinite size.\")}function Map(e){return null==e?emptyMap():isMap(e)&&!isOrdered(e)?e:emptyMap().withMutations((function(t){var r=KeyedIterable(e);assertNotInfinite(r.size),r.forEach((function(e,r){return t.set(r,e)}))}))}function isMap(e){return!(!e||!e[W])}createClass(Map,KeyedCollection),Map.of=function(){var t=e.call(arguments,0);return emptyMap().withMutations((function(e){for(var r=0;r=t.length)throw new Error(\"Missing value for key: \"+t[r]);e.set(t[r],t[r+1])}}))},Map.prototype.toString=function(){return this.__toString(\"Map {\",\"}\")},Map.prototype.get=function(e,t){return this._root?this._root.get(0,void 0,e,t):t},Map.prototype.set=function(e,t){return updateMap(this,e,t)},Map.prototype.setIn=function(e,t){return this.updateIn(e,c,(function(){return t}))},Map.prototype.remove=function(e){return updateMap(this,e,c)},Map.prototype.deleteIn=function(e){return this.updateIn(e,(function(){return c}))},Map.prototype.update=function(e,t,r){return 1===arguments.length?e(this):this.updateIn([e],t,r)},Map.prototype.updateIn=function(e,t,r){r||(r=t,t=void 0);var n=updateInDeepMap(this,forceIterator(e),t,r);return n===c?void 0:n},Map.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._root=null,this.__hash=void 0,this.__altered=!0,this):emptyMap()},Map.prototype.merge=function(){return mergeIntoMapWith(this,void 0,arguments)},Map.prototype.mergeWith=function(t){return mergeIntoMapWith(this,t,e.call(arguments,1))},Map.prototype.mergeIn=function(t){var r=e.call(arguments,1);return this.updateIn(t,emptyMap(),(function(e){return\"function\"==typeof e.merge?e.merge.apply(e,r):r[r.length-1]}))},Map.prototype.mergeDeep=function(){return mergeIntoMapWith(this,deepMerger,arguments)},Map.prototype.mergeDeepWith=function(t){var r=e.call(arguments,1);return mergeIntoMapWith(this,deepMergerWith(t),r)},Map.prototype.mergeDeepIn=function(t){var r=e.call(arguments,1);return this.updateIn(t,emptyMap(),(function(e){return\"function\"==typeof e.mergeDeep?e.mergeDeep.apply(e,r):r[r.length-1]}))},Map.prototype.sort=function(e){return OrderedMap(sortFactory(this,e))},Map.prototype.sortBy=function(e,t){return OrderedMap(sortFactory(this,t,e))},Map.prototype.withMutations=function(e){var t=this.asMutable();return e(t),t.wasAltered()?t.__ensureOwner(this.__ownerID):this},Map.prototype.asMutable=function(){return this.__ownerID?this:this.__ensureOwner(new OwnerID)},Map.prototype.asImmutable=function(){return this.__ensureOwner()},Map.prototype.wasAltered=function(){return this.__altered},Map.prototype.__iterator=function(e,t){return new MapIterator(this,e,t)},Map.prototype.__iterate=function(e,t){var r=this,n=0;return this._root&&this._root.iterate((function(t){return n++,e(t[1],t[0],r)}),t),n},Map.prototype.__ensureOwner=function(e){return e===this.__ownerID?this:e?makeMap(this.size,this._root,e,this.__hash):(this.__ownerID=e,this.__altered=!1,this)},Map.isMap=isMap;var U,W=\"@@__IMMUTABLE_MAP__@@\",K=Map.prototype;function ArrayMapNode(e,t){this.ownerID=e,this.entries=t}function BitmapIndexedNode(e,t,r){this.ownerID=e,this.bitmap=t,this.nodes=r}function HashArrayMapNode(e,t,r){this.ownerID=e,this.count=t,this.nodes=r}function HashCollisionNode(e,t,r){this.ownerID=e,this.keyHash=t,this.entries=r}function ValueNode(e,t,r){this.ownerID=e,this.keyHash=t,this.entry=r}function MapIterator(e,t,r){this._type=t,this._reverse=r,this._stack=e._root&&mapIteratorFrame(e._root)}function mapIteratorValue(e,t){return iteratorValue(e,t[0],t[1])}function mapIteratorFrame(e,t){return{node:e,index:0,__prev:t}}function makeMap(e,t,r,n){var i=Object.create(K);return i.size=e,i._root=t,i.__ownerID=r,i.__hash=n,i.__altered=!1,i}function emptyMap(){return U||(U=makeMap(0))}function updateMap(e,t,r){var n,i;if(e._root){var o=MakeRef(f),a=MakeRef(l);if(n=updateNode(e._root,e.__ownerID,0,void 0,t,r,o,a),!a.value)return e;i=e.size+(o.value?r===c?-1:1:0)}else{if(r===c)return e;i=1,n=new ArrayMapNode(e.__ownerID,[[t,r]])}return e.__ownerID?(e.size=i,e._root=n,e.__hash=void 0,e.__altered=!0,e):n?makeMap(i,n):emptyMap()}function updateNode(e,t,r,n,i,o,a,s){return e?e.update(t,r,n,i,o,a,s):o===c?e:(SetRef(s),SetRef(a),new ValueNode(t,n,[i,o]))}function isLeafNode(e){return e.constructor===ValueNode||e.constructor===HashCollisionNode}function mergeIntoNode(e,t,r,n,i){if(e.keyHash===n)return new HashCollisionNode(t,n,[e.entry,i]);var o,s=(0===r?e.keyHash:e.keyHash>>>r)&u,c=(0===r?n:n>>>r)&u;return new BitmapIndexedNode(t,1<>>=1)a[u]=1&r?t[o++]:void 0;return a[n]=i,new HashArrayMapNode(e,o+1,a)}function mergeIntoMapWith(e,t,r){for(var n=[],i=0;i>1&1431655765))+(e>>2&858993459))+(e>>4)&252645135,e+=e>>8,127&(e+=e>>16)}function setIn(e,t,r,n){var i=n?e:arrCopy(e);return i[t]=r,i}function spliceIn(e,t,r,n){var i=e.length+1;if(n&&t+1===i)return e[t]=r,e;for(var o=new Array(i),a=0,s=0;s=V)return createNodes(e,u,n,i);var p=e&&e===this.ownerID,d=p?u:arrCopy(u);return h?s?f===l-1?d.pop():d[f]=d.pop():d[f]=[n,i]:d.push([n,i]),p?(this.entries=d,this):new ArrayMapNode(e,d)}},BitmapIndexedNode.prototype.get=function(e,t,r,n){void 0===t&&(t=hash(r));var i=1<<((0===e?t:t>>>e)&u),o=this.bitmap;return o&i?this.nodes[popCount(o&i-1)].get(e+a,t,r,n):n},BitmapIndexedNode.prototype.update=function(e,t,r,n,i,o,s){void 0===r&&(r=hash(n));var f=(0===t?r:r>>>t)&u,l=1<=$)return expandNodes(e,_,h,f,m);if(p&&!m&&2===_.length&&isLeafNode(_[1^d]))return _[1^d];if(p&&m&&1===_.length&&isLeafNode(m))return m;var g=e&&e===this.ownerID,v=p?m?h:h^l:h|l,b=p?m?setIn(_,d,m,g):spliceOut(_,d,g):spliceIn(_,d,m,g);return g?(this.bitmap=v,this.nodes=b,this):new BitmapIndexedNode(e,v,b)},HashArrayMapNode.prototype.get=function(e,t,r,n){void 0===t&&(t=hash(r));var i=(0===e?t:t>>>e)&u,o=this.nodes[i];return o?o.get(e+a,t,r,n):n},HashArrayMapNode.prototype.update=function(e,t,r,n,i,o,s){void 0===r&&(r=hash(n));var f=(0===t?r:r>>>t)&u,l=i===c,h=this.nodes,p=h[f];if(l&&!p)return this;var d=updateNode(p,e,t+a,r,n,i,o,s);if(d===p)return this;var _=this.count;if(p){if(!d&&--_0&&n=0&&e>>t&u;if(n>=this.array.length)return new VNode([],e);var i,o=0===n;if(t>0){var s=this.array[n];if((i=s&&s.removeBefore(e,t-a,r))===s&&o)return this}if(o&&!i)return this;var c=editableVNode(this,e);if(!o)for(var f=0;f>>t&u;if(i>=this.array.length)return this;if(t>0){var o=this.array[i];if((n=o&&o.removeAfter(e,t-a,r))===o&&i===this.array.length-1)return this}var s=editableVNode(this,e);return s.array.splice(i+1),n&&(s.array[i]=n),s};var J,ee,te={};function iterateList(e,t){var r=e._origin,n=e._capacity,i=getTailOffset(n),o=e._tail;return iterateNodeOrLeaf(e._root,e._level,0);function iterateNodeOrLeaf(e,t,r){return 0===t?iterateLeaf(e,r):iterateNode(e,t,r)}function iterateLeaf(e,a){var u=a===i?o&&o.array:e&&e.array,c=a>r?0:r-a,f=n-a;return f>s&&(f=s),function(){if(c===f)return te;var e=t?--f:c++;return u&&u[e]}}function iterateNode(e,i,o){var u,c=e&&e.array,f=o>r?0:r-o>>i,l=1+(n-o>>i);return l>s&&(l=s),function(){for(;;){if(u){var e=u();if(e!==te)return e;u=null}if(f===l)return te;var r=t?--l:f++;u=iterateNodeOrLeaf(c&&c[r],i-a,o+(r<=e.size||t<0)return e.withMutations((function(e){t<0?setListBounds(e,t).set(0,r):setListBounds(e,0,t+1).set(t,r)}));t+=e._origin;var n=e._tail,i=e._root,o=MakeRef(l);return t>=getTailOffset(e._capacity)?n=updateVNode(n,e.__ownerID,0,t,r,o):i=updateVNode(i,e.__ownerID,e._level,t,r,o),o.value?e.__ownerID?(e._root=i,e._tail=n,e.__hash=void 0,e.__altered=!0,e):makeList(e._origin,e._capacity,e._level,i,n):e}function updateVNode(e,t,r,n,i,o){var s,c=n>>>r&u,f=e&&c0){var l=e&&e.array[c],h=updateVNode(l,t,r-a,n,i,o);return h===l?e:((s=editableVNode(e,t)).array[c]=h,s)}return f&&e.array[c]===i?e:(SetRef(o),s=editableVNode(e,t),void 0===i&&c===s.array.length-1?s.array.pop():s.array[c]=i,s)}function editableVNode(e,t){return t&&e&&t===e.ownerID?e:new VNode(e?e.array.slice():[],t)}function listNodeFor(e,t){if(t>=getTailOffset(e._capacity))return e._tail;if(t<1<0;)r=r.array[t>>>n&u],n-=a;return r}}function setListBounds(e,t,r){void 0!==t&&(t|=0),void 0!==r&&(r|=0);var n=e.__ownerID||new OwnerID,i=e._origin,o=e._capacity,s=i+t,c=void 0===r?o:r<0?o+r:i+r;if(s===i&&c===o)return e;if(s>=c)return e.clear();for(var f=e._level,l=e._root,h=0;s+h<0;)l=new VNode(l&&l.array.length?[void 0,l]:[],n),h+=1<<(f+=a);h&&(s+=h,i+=h,c+=h,o+=h);for(var p=getTailOffset(o),d=getTailOffset(c);d>=1<p?new VNode([],n):_;if(_&&d>p&&sa;g-=a){var v=p>>>g&u;m=m.array[v]=editableVNode(m.array[v],n)}m.array[p>>>a&u]=_}if(c=d)s-=d,c-=d,f=a,l=null,y=y&&y.removeBefore(n,0,s);else if(s>i||d>>f&u;if(b!==d>>>f&u)break;b&&(h+=(1<i&&(l=l.removeBefore(n,f,s-h)),l&&di&&(i=s.size),isIterable(a)||(s=s.map((function(e){return fromJS(e)}))),n.push(s)}return i>e.size&&(e=e.setSize(i)),mergeIntoCollectionWith(e,t,n)}function getTailOffset(e){return e>>a<=s&&a.size>=2*o.size?(n=(i=a.filter((function(e,t){return void 0!==e&&u!==t}))).toKeyedSeq().map((function(e){return e[0]})).flip().toMap(),e.__ownerID&&(n.__ownerID=i.__ownerID=e.__ownerID)):(n=o.remove(t),i=u===a.size-1?a.pop():a.set(u,void 0))}else if(f){if(r===a.get(u)[1])return e;n=o,i=a.set(u,[t,r])}else n=o.set(t,a.size),i=a.set(a.size,[t,r]);return e.__ownerID?(e.size=n.size,e._map=n,e._list=i,e.__hash=void 0,e):makeOrderedMap(n,i)}function ToKeyedSequence(e,t){this._iter=e,this._useKeys=t,this.size=e.size}function ToIndexedSequence(e){this._iter=e,this.size=e.size}function ToSetSequence(e){this._iter=e,this.size=e.size}function FromEntriesSequence(e){this._iter=e,this.size=e.size}function flipFactory(e){var t=makeSequence(e);return t._iter=e,t.size=e.size,t.flip=function(){return e},t.reverse=function(){var t=e.reverse.apply(this);return t.flip=function(){return e.reverse()},t},t.has=function(t){return e.includes(t)},t.includes=function(t){return e.has(t)},t.cacheResult=cacheResultThrough,t.__iterateUncached=function(t,r){var n=this;return e.__iterate((function(e,r){return!1!==t(r,e,n)}),r)},t.__iteratorUncached=function(t,r){if(t===d){var n=e.__iterator(t,r);return new Iterator((function(){var e=n.next();if(!e.done){var t=e.value[0];e.value[0]=e.value[1],e.value[1]=t}return e}))}return e.__iterator(t===p?h:p,r)},t}function mapFactory(e,t,r){var n=makeSequence(e);return n.size=e.size,n.has=function(t){return e.has(t)},n.get=function(n,i){var o=e.get(n,c);return o===c?i:t.call(r,o,n,e)},n.__iterateUncached=function(n,i){var o=this;return e.__iterate((function(e,i,a){return!1!==n(t.call(r,e,i,a),i,o)}),i)},n.__iteratorUncached=function(n,i){var o=e.__iterator(d,i);return new Iterator((function(){var i=o.next();if(i.done)return i;var a=i.value,s=a[0];return iteratorValue(n,s,t.call(r,a[1],s,e),i)}))},n}function reverseFactory(e,t){var r=makeSequence(e);return r._iter=e,r.size=e.size,r.reverse=function(){return e},e.flip&&(r.flip=function(){var t=flipFactory(e);return t.reverse=function(){return e.flip()},t}),r.get=function(r,n){return e.get(t?r:-1-r,n)},r.has=function(r){return e.has(t?r:-1-r)},r.includes=function(t){return e.includes(t)},r.cacheResult=cacheResultThrough,r.__iterate=function(t,r){var n=this;return e.__iterate((function(e,r){return t(e,r,n)}),!r)},r.__iterator=function(t,r){return e.__iterator(t,!r)},r}function filterFactory(e,t,r,n){var i=makeSequence(e);return n&&(i.has=function(n){var i=e.get(n,c);return i!==c&&!!t.call(r,i,n,e)},i.get=function(n,i){var o=e.get(n,c);return o!==c&&t.call(r,o,n,e)?o:i}),i.__iterateUncached=function(i,o){var a=this,s=0;return e.__iterate((function(e,o,u){if(t.call(r,e,o,u))return s++,i(e,n?o:s-1,a)}),o),s},i.__iteratorUncached=function(i,o){var a=e.__iterator(d,o),s=0;return new Iterator((function(){for(;;){var o=a.next();if(o.done)return o;var u=o.value,c=u[0],f=u[1];if(t.call(r,f,c,e))return iteratorValue(i,n?c:s++,f,o)}}))},i}function countByFactory(e,t,r){var n=Map().asMutable();return e.__iterate((function(i,o){n.update(t.call(r,i,o,e),0,(function(e){return e+1}))})),n.asImmutable()}function groupByFactory(e,t,r){var n=isKeyed(e),i=(isOrdered(e)?OrderedMap():Map()).asMutable();e.__iterate((function(o,a){i.update(t.call(r,o,a,e),(function(e){return(e=e||[]).push(n?[a,o]:o),e}))}));var o=iterableClass(e);return i.map((function(t){return reify(e,o(t))}))}function sliceFactory(e,t,r,n){var i=e.size;if(void 0!==t&&(t|=0),void 0!==r&&(r===1/0?r=i:r|=0),wholeSlice(t,r,i))return e;var o=resolveBegin(t,i),a=resolveEnd(r,i);if(o!=o||a!=a)return sliceFactory(e.toSeq().cacheResult(),t,r,n);var s,u=a-o;u==u&&(s=u<0?0:u);var c=makeSequence(e);return c.size=0===s?s:e.size&&s||void 0,!n&&isSeq(e)&&s>=0&&(c.get=function(t,r){return(t=wrapIndex(this,t))>=0&&ts)return iteratorDone();var e=i.next();return n||t===p?e:iteratorValue(t,u-1,t===h?void 0:e.value[1],e)}))},c}function takeWhileFactory(e,t,r){var n=makeSequence(e);return n.__iterateUncached=function(n,i){var o=this;if(i)return this.cacheResult().__iterate(n,i);var a=0;return e.__iterate((function(e,i,s){return t.call(r,e,i,s)&&++a&&n(e,i,o)})),a},n.__iteratorUncached=function(n,i){var o=this;if(i)return this.cacheResult().__iterator(n,i);var a=e.__iterator(d,i),s=!0;return new Iterator((function(){if(!s)return iteratorDone();var e=a.next();if(e.done)return e;var i=e.value,u=i[0],c=i[1];return t.call(r,c,u,o)?n===d?e:iteratorValue(n,u,c,e):(s=!1,iteratorDone())}))},n}function skipWhileFactory(e,t,r,n){var i=makeSequence(e);return i.__iterateUncached=function(i,o){var a=this;if(o)return this.cacheResult().__iterate(i,o);var s=!0,u=0;return e.__iterate((function(e,o,c){if(!s||!(s=t.call(r,e,o,c)))return u++,i(e,n?o:u-1,a)})),u},i.__iteratorUncached=function(i,o){var a=this;if(o)return this.cacheResult().__iterator(i,o);var s=e.__iterator(d,o),u=!0,c=0;return new Iterator((function(){var e,o,f;do{if((e=s.next()).done)return n||i===p?e:iteratorValue(i,c++,i===h?void 0:e.value[1],e);var l=e.value;o=l[0],f=l[1],u&&(u=t.call(r,f,o,a))}while(u);return i===d?e:iteratorValue(i,o,f,e)}))},i}function concatFactory(e,t){var r=isKeyed(e),n=[e].concat(t).map((function(e){return isIterable(e)?r&&(e=KeyedIterable(e)):e=r?keyedSeqFromValue(e):indexedSeqFromValue(Array.isArray(e)?e:[e]),e})).filter((function(e){return 0!==e.size}));if(0===n.length)return e;if(1===n.length){var i=n[0];if(i===e||r&&isKeyed(i)||isIndexed(e)&&isIndexed(i))return i}var o=new ArraySeq(n);return r?o=o.toKeyedSeq():isIndexed(e)||(o=o.toSetSeq()),(o=o.flatten(!0)).size=n.reduce((function(e,t){if(void 0!==e){var r=t.size;if(void 0!==r)return e+r}}),0),o}function flattenFactory(e,t,r){var n=makeSequence(e);return n.__iterateUncached=function(n,i){var o=0,a=!1;function flatDeep(e,s){var u=this;e.__iterate((function(e,i){return(!t||s0}function zipWithFactory(e,t,r){var n=makeSequence(e);return n.size=new ArraySeq(r).map((function(e){return e.size})).min(),n.__iterate=function(e,t){for(var r,n=this.__iterator(p,t),i=0;!(r=n.next()).done&&!1!==e(r.value,i++,this););return i},n.__iteratorUncached=function(e,n){var i=r.map((function(e){return e=Iterable(e),getIterator(n?e.reverse():e)})),o=0,a=!1;return new Iterator((function(){var r;return a||(r=i.map((function(e){return e.next()})),a=r.some((function(e){return e.done}))),a?iteratorDone():iteratorValue(e,o++,t.apply(null,r.map((function(e){return e.value}))))}))},n}function reify(e,t){return isSeq(e)?t:e.constructor(t)}function validateEntry(e){if(e!==Object(e))throw new TypeError(\"Expected [K, V] tuple: \"+e)}function resolveSize(e){return assertNotInfinite(e.size),ensureSize(e)}function iterableClass(e){return isKeyed(e)?KeyedIterable:isIndexed(e)?IndexedIterable:SetIterable}function makeSequence(e){return Object.create((isKeyed(e)?KeyedSeq:isIndexed(e)?IndexedSeq:SetSeq).prototype)}function cacheResultThrough(){return this._iter.cacheResult?(this._iter.cacheResult(),this.size=this._iter.size,this):Seq.prototype.cacheResult.call(this)}function defaultComparator(e,t){return e>t?1:e=0;r--)t={value:arguments[r],next:t};return this.__ownerID?(this.size=e,this._head=t,this.__hash=void 0,this.__altered=!0,this):makeStack(e,t)},Stack.prototype.pushAll=function(e){if(0===(e=IndexedIterable(e)).size)return this;assertNotInfinite(e.size);var t=this.size,r=this._head;return e.reverse().forEach((function(e){t++,r={value:e,next:r}})),this.__ownerID?(this.size=t,this._head=r,this.__hash=void 0,this.__altered=!0,this):makeStack(t,r)},Stack.prototype.pop=function(){return this.slice(1)},Stack.prototype.unshift=function(){return this.push.apply(this,arguments)},Stack.prototype.unshiftAll=function(e){return this.pushAll(e)},Stack.prototype.shift=function(){return this.pop.apply(this,arguments)},Stack.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._head=void 0,this.__hash=void 0,this.__altered=!0,this):emptyStack()},Stack.prototype.slice=function(e,t){if(wholeSlice(e,t,this.size))return this;var r=resolveBegin(e,this.size);if(resolveEnd(t,this.size)!==this.size)return IndexedCollection.prototype.slice.call(this,e,t);for(var n=this.size-r,i=this._head;r--;)i=i.next;return this.__ownerID?(this.size=n,this._head=i,this.__hash=void 0,this.__altered=!0,this):makeStack(n,i)},Stack.prototype.__ensureOwner=function(e){return e===this.__ownerID?this:e?makeStack(this.size,this._head,e,this.__hash):(this.__ownerID=e,this.__altered=!1,this)},Stack.prototype.__iterate=function(e,t){if(t)return this.reverse().__iterate(e);for(var r=0,n=this._head;n&&!1!==e(n.value,r++,this);)n=n.next;return r},Stack.prototype.__iterator=function(e,t){if(t)return this.reverse().__iterator(e);var r=0,n=this._head;return new Iterator((function(){if(n){var t=n.value;return n=n.next,iteratorValue(e,r++,t)}return iteratorDone()}))},Stack.isStack=isStack;var ue,ce=\"@@__IMMUTABLE_STACK__@@\",fe=Stack.prototype;function makeStack(e,t,r,n){var i=Object.create(fe);return i.size=e,i._head=t,i.__ownerID=r,i.__hash=n,i.__altered=!1,i}function emptyStack(){return ue||(ue=makeStack(0))}function mixin(e,t){var keyCopier=function(r){e.prototype[r]=t[r]};return Object.keys(t).forEach(keyCopier),Object.getOwnPropertySymbols&&Object.getOwnPropertySymbols(t).forEach(keyCopier),e}fe[ce]=!0,fe.withMutations=K.withMutations,fe.asMutable=K.asMutable,fe.asImmutable=K.asImmutable,fe.wasAltered=K.wasAltered,Iterable.Iterator=Iterator,mixin(Iterable,{toArray:function(){assertNotInfinite(this.size);var e=new Array(this.size||0);return this.valueSeq().__iterate((function(t,r){e[r]=t})),e},toIndexedSeq:function(){return new ToIndexedSequence(this)},toJS:function(){return this.toSeq().map((function(e){return e&&\"function\"==typeof e.toJS?e.toJS():e})).__toJS()},toJSON:function(){return this.toSeq().map((function(e){return e&&\"function\"==typeof e.toJSON?e.toJSON():e})).__toJS()},toKeyedSeq:function(){return new ToKeyedSequence(this,!0)},toMap:function(){return Map(this.toKeyedSeq())},toObject:function(){assertNotInfinite(this.size);var e={};return this.__iterate((function(t,r){e[r]=t})),e},toOrderedMap:function(){return OrderedMap(this.toKeyedSeq())},toOrderedSet:function(){return OrderedSet(isKeyed(this)?this.valueSeq():this)},toSet:function(){return Set(isKeyed(this)?this.valueSeq():this)},toSetSeq:function(){return new ToSetSequence(this)},toSeq:function(){return isIndexed(this)?this.toIndexedSeq():isKeyed(this)?this.toKeyedSeq():this.toSetSeq()},toStack:function(){return Stack(isKeyed(this)?this.valueSeq():this)},toList:function(){return List(isKeyed(this)?this.valueSeq():this)},toString:function(){return\"[Iterable]\"},__toString:function(e,t){return 0===this.size?e+t:e+\" \"+this.toSeq().map(this.__toStringMapper).join(\", \")+\" \"+t},concat:function(){return reify(this,concatFactory(this,e.call(arguments,0)))},includes:function(e){return this.some((function(t){return is(t,e)}))},entries:function(){return this.__iterator(d)},every:function(e,t){assertNotInfinite(this.size);var r=!0;return this.__iterate((function(n,i,o){if(!e.call(t,n,i,o))return r=!1,!1})),r},filter:function(e,t){return reify(this,filterFactory(this,e,t,!0))},find:function(e,t,r){var n=this.findEntry(e,t);return n?n[1]:r},forEach:function(e,t){return assertNotInfinite(this.size),this.__iterate(t?e.bind(t):e)},join:function(e){assertNotInfinite(this.size),e=void 0!==e?\"\"+e:\",\";var t=\"\",r=!0;return this.__iterate((function(n){r?r=!1:t+=e,t+=null!=n?n.toString():\"\"})),t},keys:function(){return this.__iterator(h)},map:function(e,t){return reify(this,mapFactory(this,e,t))},reduce:function(e,t,r){var n,i;return assertNotInfinite(this.size),arguments.length<2?i=!0:n=t,this.__iterate((function(t,o,a){i?(i=!1,n=t):n=e.call(r,n,t,o,a)})),n},reduceRight:function(e,t,r){var n=this.toKeyedSeq().reverse();return n.reduce.apply(n,arguments)},reverse:function(){return reify(this,reverseFactory(this,!0))},slice:function(e,t){return reify(this,sliceFactory(this,e,t,!0))},some:function(e,t){return!this.every(not(e),t)},sort:function(e){return reify(this,sortFactory(this,e))},values:function(){return this.__iterator(p)},butLast:function(){return this.slice(0,-1)},isEmpty:function(){return void 0!==this.size?0===this.size:!this.some((function(){return!0}))},count:function(e,t){return ensureSize(e?this.toSeq().filter(e,t):this)},countBy:function(e,t){return countByFactory(this,e,t)},equals:function(e){return deepEqual(this,e)},entrySeq:function(){var e=this;if(e._cache)return new ArraySeq(e._cache);var t=e.toSeq().map(entryMapper).toIndexedSeq();return t.fromEntrySeq=function(){return e.toSeq()},t},filterNot:function(e,t){return this.filter(not(e),t)},findEntry:function(e,t,r){var n=r;return this.__iterate((function(r,i,o){if(e.call(t,r,i,o))return n=[i,r],!1})),n},findKey:function(e,t){var r=this.findEntry(e,t);return r&&r[0]},findLast:function(e,t,r){return this.toKeyedSeq().reverse().find(e,t,r)},findLastEntry:function(e,t,r){return this.toKeyedSeq().reverse().findEntry(e,t,r)},findLastKey:function(e,t){return this.toKeyedSeq().reverse().findKey(e,t)},first:function(){return this.find(returnTrue)},flatMap:function(e,t){return reify(this,flatMapFactory(this,e,t))},flatten:function(e){return reify(this,flattenFactory(this,e,!0))},fromEntrySeq:function(){return new FromEntriesSequence(this)},get:function(e,t){return this.find((function(t,r){return is(r,e)}),void 0,t)},getIn:function(e,t){for(var r,n=this,i=forceIterator(e);!(r=i.next()).done;){var o=r.value;if((n=n&&n.get?n.get(o,c):c)===c)return t}return n},groupBy:function(e,t){return groupByFactory(this,e,t)},has:function(e){return this.get(e,c)!==c},hasIn:function(e){return this.getIn(e,c)!==c},isSubset:function(e){return e=\"function\"==typeof e.includes?e:Iterable(e),this.every((function(t){return e.includes(t)}))},isSuperset:function(e){return(e=\"function\"==typeof e.isSubset?e:Iterable(e)).isSubset(this)},keyOf:function(e){return this.findKey((function(t){return is(t,e)}))},keySeq:function(){return this.toSeq().map(keyMapper).toIndexedSeq()},last:function(){return this.toSeq().reverse().first()},lastKeyOf:function(e){return this.toKeyedSeq().reverse().keyOf(e)},max:function(e){return maxFactory(this,e)},maxBy:function(e,t){return maxFactory(this,t,e)},min:function(e){return maxFactory(this,e?neg(e):defaultNegComparator)},minBy:function(e,t){return maxFactory(this,t?neg(t):defaultNegComparator,e)},rest:function(){return this.slice(1)},skip:function(e){return this.slice(Math.max(0,e))},skipLast:function(e){return reify(this,this.toSeq().reverse().skip(e).reverse())},skipWhile:function(e,t){return reify(this,skipWhileFactory(this,e,t,!0))},skipUntil:function(e,t){return this.skipWhile(not(e),t)},sortBy:function(e,t){return reify(this,sortFactory(this,t,e))},take:function(e){return this.slice(0,Math.max(0,e))},takeLast:function(e){return reify(this,this.toSeq().reverse().take(e).reverse())},takeWhile:function(e,t){return reify(this,takeWhileFactory(this,e,t))},takeUntil:function(e,t){return this.takeWhile(not(e),t)},valueSeq:function(){return this.toIndexedSeq()},hashCode:function(){return this.__hash||(this.__hash=hashIterable(this))}});var le=Iterable.prototype;le[t]=!0,le[m]=le.values,le.__toJS=le.toArray,le.__toStringMapper=quoteString,le.inspect=le.toSource=function(){return this.toString()},le.chain=le.flatMap,le.contains=le.includes,mixin(KeyedIterable,{flip:function(){return reify(this,flipFactory(this))},mapEntries:function(e,t){var r=this,n=0;return reify(this,this.toSeq().map((function(i,o){return e.call(t,[o,i],n++,r)})).fromEntrySeq())},mapKeys:function(e,t){var r=this;return reify(this,this.toSeq().flip().map((function(n,i){return e.call(t,n,i,r)})).flip())}});var he=KeyedIterable.prototype;function keyMapper(e,t){return t}function entryMapper(e,t){return[t,e]}function not(e){return function(){return!e.apply(this,arguments)}}function neg(e){return function(){return-e.apply(this,arguments)}}function quoteString(e){return\"string\"==typeof e?JSON.stringify(e):String(e)}function defaultZipper(){return arrCopy(arguments)}function defaultNegComparator(e,t){return et?-1:0}function hashIterable(e){if(e.size===1/0)return 0;var t=isOrdered(e),r=isKeyed(e),n=t?1:0;return murmurHashOfSize(e.__iterate(r?t?function(e,t){n=31*n+hashMerge(hash(e),hash(t))|0}:function(e,t){n=n+hashMerge(hash(e),hash(t))|0}:t?function(e){n=31*n+hash(e)|0}:function(e){n=n+hash(e)|0}),n)}function murmurHashOfSize(e,t){return t=I(t,3432918353),t=I(t<<15|t>>>-15,461845907),t=I(t<<13|t>>>-13,5),t=I((t=t+3864292196^e)^t>>>16,2246822507),t=smi((t=I(t^t>>>13,3266489909))^t>>>16)}function hashMerge(e,t){return e^t+2654435769+(e<<6)+(e>>2)}return he[r]=!0,he[m]=le.entries,he.__toJS=le.toObject,he.__toStringMapper=function(e,t){return JSON.stringify(t)+\": \"+quoteString(e)},mixin(IndexedIterable,{toKeyedSeq:function(){return new ToKeyedSequence(this,!1)},filter:function(e,t){return reify(this,filterFactory(this,e,t,!1))},findIndex:function(e,t){var r=this.findEntry(e,t);return r?r[0]:-1},indexOf:function(e){var t=this.keyOf(e);return void 0===t?-1:t},lastIndexOf:function(e){var t=this.lastKeyOf(e);return void 0===t?-1:t},reverse:function(){return reify(this,reverseFactory(this,!1))},slice:function(e,t){return reify(this,sliceFactory(this,e,t,!1))},splice:function(e,t){var r=arguments.length;if(t=Math.max(0|t,0),0===r||2===r&&!t)return this;e=resolveBegin(e,e<0?this.count():this.size);var n=this.slice(0,e);return reify(this,1===r?n:n.concat(arrCopy(arguments,2),this.slice(e+t)))},findLastIndex:function(e,t){var r=this.findLastEntry(e,t);return r?r[0]:-1},first:function(){return this.get(0)},flatten:function(e){return reify(this,flattenFactory(this,e,!1))},get:function(e,t){return(e=wrapIndex(this,e))<0||this.size===1/0||void 0!==this.size&&e>this.size?t:this.find((function(t,r){return r===e}),void 0,t)},has:function(e){return(e=wrapIndex(this,e))>=0&&(void 0!==this.size?this.size===1/0||e{\"function\"==typeof Object.create?e.exports=function inherits(e,t){t&&(e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}))}:e.exports=function inherits(e,t){if(t){e.super_=t;var TempCtor=function(){};TempCtor.prototype=t.prototype,e.prototype=new TempCtor,e.prototype.constructor=e}}},5580:(e,t,r)=>{var n=r(6110)(r(9325),\"DataView\");e.exports=n},1549:(e,t,r)=>{var n=r(2032),i=r(3862),o=r(6721),a=r(2749),s=r(5749);function Hash(e){var t=-1,r=null==e?0:e.length;for(this.clear();++t{var n=r(3702),i=r(80),o=r(4739),a=r(8655),s=r(1175);function ListCache(e){var t=-1,r=null==e?0:e.length;for(this.clear();++t{var n=r(6110)(r(9325),\"Map\");e.exports=n},3661:(e,t,r)=>{var n=r(3040),i=r(7670),o=r(289),a=r(4509),s=r(2949);function MapCache(e){var t=-1,r=null==e?0:e.length;for(this.clear();++t{var n=r(6110)(r(9325),\"Promise\");e.exports=n},6545:(e,t,r)=>{var n=r(6110)(r(9325),\"Set\");e.exports=n},8859:(e,t,r)=>{var n=r(3661),i=r(1380),o=r(1459);function SetCache(e){var t=-1,r=null==e?0:e.length;for(this.__data__=new n;++t{var n=r(79),i=r(1420),o=r(938),a=r(3605),s=r(9817),u=r(945);function Stack(e){var t=this.__data__=new n(e);this.size=t.size}Stack.prototype.clear=i,Stack.prototype.delete=o,Stack.prototype.get=a,Stack.prototype.has=s,Stack.prototype.set=u,e.exports=Stack},1873:(e,t,r)=>{var n=r(9325).Symbol;e.exports=n},7828:(e,t,r)=>{var n=r(9325).Uint8Array;e.exports=n},8303:(e,t,r)=>{var n=r(6110)(r(9325),\"WeakMap\");e.exports=n},9770:e=>{e.exports=function arrayFilter(e,t){for(var r=-1,n=null==e?0:e.length,i=0,o=[];++r{var n=r(8096),i=r(2428),o=r(6449),a=r(3656),s=r(361),u=r(7167),c=Object.prototype.hasOwnProperty;e.exports=function arrayLikeKeys(e,t){var r=o(e),f=!r&&i(e),l=!r&&!f&&a(e),h=!r&&!f&&!l&&u(e),p=r||f||l||h,d=p?n(e.length,String):[],_=d.length;for(var y in e)!t&&!c.call(e,y)||p&&(\"length\"==y||l&&(\"offset\"==y||\"parent\"==y)||h&&(\"buffer\"==y||\"byteLength\"==y||\"byteOffset\"==y)||s(y,_))||d.push(y);return d}},4932:e=>{e.exports=function arrayMap(e,t){for(var r=-1,n=null==e?0:e.length,i=Array(n);++r{e.exports=function arrayPush(e,t){for(var r=-1,n=t.length,i=e.length;++r{e.exports=function arrayReduce(e,t,r,n){var i=-1,o=null==e?0:e.length;for(n&&o&&(r=e[++i]);++i{e.exports=function arraySome(e,t){for(var r=-1,n=null==e?0:e.length;++r{e.exports=function asciiToArray(e){return e.split(\"\")}},1733:e=>{var t=/[^\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\x7f]+/g;e.exports=function asciiWords(e){return e.match(t)||[]}},6547:(e,t,r)=>{var n=r(3360),i=r(5288),o=Object.prototype.hasOwnProperty;e.exports=function assignValue(e,t,r){var a=e[t];o.call(e,t)&&i(a,r)&&(void 0!==r||t in e)||n(e,t,r)}},6025:(e,t,r)=>{var n=r(5288);e.exports=function assocIndexOf(e,t){for(var r=e.length;r--;)if(n(e[r][0],t))return r;return-1}},3360:(e,t,r)=>{var n=r(3243);e.exports=function baseAssignValue(e,t,r){\"__proto__\"==t&&n?n(e,t,{configurable:!0,enumerable:!0,value:r,writable:!0}):e[t]=r}},909:(e,t,r)=>{var n=r(641),i=r(8329)(n);e.exports=i},2523:e=>{e.exports=function baseFindIndex(e,t,r,n){for(var i=e.length,o=r+(n?1:-1);n?o--:++o{var n=r(3221)();e.exports=n},641:(e,t,r)=>{var n=r(6649),i=r(5950);e.exports=function baseForOwn(e,t){return e&&n(e,t,i)}},7422:(e,t,r)=>{var n=r(1769),i=r(7797);e.exports=function baseGet(e,t){for(var r=0,o=(t=n(t,e)).length;null!=e&&r{var n=r(4528),i=r(6449);e.exports=function baseGetAllKeys(e,t,r){var o=t(e);return i(e)?o:n(o,r(e))}},2552:(e,t,r)=>{var n=r(1873),i=r(659),o=r(9350),a=n?n.toStringTag:void 0;e.exports=function baseGetTag(e){return null==e?void 0===e?\"[object Undefined]\":\"[object Null]\":a&&a in Object(e)?i(e):o(e)}},8077:e=>{e.exports=function baseHasIn(e,t){return null!=e&&t in Object(e)}},7534:(e,t,r)=>{var n=r(2552),i=r(346);e.exports=function baseIsArguments(e){return i(e)&&\"[object Arguments]\"==n(e)}},270:(e,t,r)=>{var n=r(7068),i=r(346);e.exports=function baseIsEqual(e,t,r,o,a){return e===t||(null==e||null==t||!i(e)&&!i(t)?e!=e&&t!=t:n(e,t,r,o,baseIsEqual,a))}},7068:(e,t,r)=>{var n=r(7217),i=r(5911),o=r(1986),a=r(689),s=r(5861),u=r(6449),c=r(3656),f=r(7167),l=\"[object Arguments]\",h=\"[object Array]\",p=\"[object Object]\",d=Object.prototype.hasOwnProperty;e.exports=function baseIsEqualDeep(e,t,r,_,y,m){var g=u(e),v=u(t),b=g?h:s(e),w=v?h:s(t),I=(b=b==l?p:b)==p,x=(w=w==l?p:w)==p,B=b==w;if(B&&c(e)){if(!c(t))return!1;g=!0,I=!1}if(B&&!I)return m||(m=new n),g||f(e)?i(e,t,r,_,y,m):o(e,t,b,r,_,y,m);if(!(1&r)){var k=I&&d.call(e,\"__wrapped__\"),C=x&&d.call(t,\"__wrapped__\");if(k||C){var q=k?e.value():e,L=C?t.value():t;return m||(m=new n),y(q,L,r,_,m)}}return!!B&&(m||(m=new n),a(e,t,r,_,y,m))}},1799:(e,t,r)=>{var n=r(7217),i=r(270);e.exports=function baseIsMatch(e,t,r,o){var a=r.length,s=a,u=!o;if(null==e)return!s;for(e=Object(e);a--;){var c=r[a];if(u&&c[2]?c[1]!==e[c[0]]:!(c[0]in e))return!1}for(;++a{var n=r(1882),i=r(7296),o=r(3805),a=r(7473),s=/^\\[object .+?Constructor\\]$/,u=Function.prototype,c=Object.prototype,f=u.toString,l=c.hasOwnProperty,h=RegExp(\"^\"+f.call(l).replace(/[\\\\^$.*+?()[\\]{}|]/g,\"\\\\$&\").replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g,\"$1.*?\")+\"$\");e.exports=function baseIsNative(e){return!(!o(e)||i(e))&&(n(e)?h:s).test(a(e))}},4901:(e,t,r)=>{var n=r(2552),i=r(294),o=r(346),a={};a[\"[object Float32Array]\"]=a[\"[object Float64Array]\"]=a[\"[object Int8Array]\"]=a[\"[object Int16Array]\"]=a[\"[object Int32Array]\"]=a[\"[object Uint8Array]\"]=a[\"[object Uint8ClampedArray]\"]=a[\"[object Uint16Array]\"]=a[\"[object Uint32Array]\"]=!0,a[\"[object Arguments]\"]=a[\"[object Array]\"]=a[\"[object ArrayBuffer]\"]=a[\"[object Boolean]\"]=a[\"[object DataView]\"]=a[\"[object Date]\"]=a[\"[object Error]\"]=a[\"[object Function]\"]=a[\"[object Map]\"]=a[\"[object Number]\"]=a[\"[object Object]\"]=a[\"[object RegExp]\"]=a[\"[object Set]\"]=a[\"[object String]\"]=a[\"[object WeakMap]\"]=!1,e.exports=function baseIsTypedArray(e){return o(e)&&i(e.length)&&!!a[n(e)]}},5389:(e,t,r)=>{var n=r(3663),i=r(7978),o=r(3488),a=r(6449),s=r(583);e.exports=function baseIteratee(e){return\"function\"==typeof e?e:null==e?o:\"object\"==typeof e?a(e)?i(e[0],e[1]):n(e):s(e)}},8984:(e,t,r)=>{var n=r(5527),i=r(3650),o=Object.prototype.hasOwnProperty;e.exports=function baseKeys(e){if(!n(e))return i(e);var t=[];for(var r in Object(e))o.call(e,r)&&\"constructor\"!=r&&t.push(r);return t}},3663:(e,t,r)=>{var n=r(1799),i=r(776),o=r(7197);e.exports=function baseMatches(e){var t=i(e);return 1==t.length&&t[0][2]?o(t[0][0],t[0][1]):function(r){return r===e||n(r,e,t)}}},7978:(e,t,r)=>{var n=r(270),i=r(8156),o=r(631),a=r(8586),s=r(756),u=r(7197),c=r(7797);e.exports=function baseMatchesProperty(e,t){return a(e)&&s(t)?u(c(e),t):function(r){var a=i(r,e);return void 0===a&&a===t?o(r,e):n(t,a,3)}}},7237:e=>{e.exports=function baseProperty(e){return function(t){return null==t?void 0:t[e]}}},7255:(e,t,r)=>{var n=r(7422);e.exports=function basePropertyDeep(e){return function(t){return n(t,e)}}},4552:e=>{e.exports=function basePropertyOf(e){return function(t){return null==e?void 0:e[t]}}},5160:e=>{e.exports=function baseSlice(e,t,r){var n=-1,i=e.length;t<0&&(t=-t>i?0:i+t),(r=r>i?i:r)<0&&(r+=i),i=t>r?0:r-t>>>0,t>>>=0;for(var o=Array(i);++n{var n=r(909);e.exports=function baseSome(e,t){var r;return n(e,(function(e,n,i){return!(r=t(e,n,i))})),!!r}},8096:e=>{e.exports=function baseTimes(e,t){for(var r=-1,n=Array(e);++r{var n=r(1873),i=r(4932),o=r(6449),a=r(4394),s=n?n.prototype:void 0,u=s?s.toString:void 0;e.exports=function baseToString(e){if(\"string\"==typeof e)return e;if(o(e))return i(e,baseToString)+\"\";if(a(e))return u?u.call(e):\"\";var t=e+\"\";return\"0\"==t&&1/e==-1/0?\"-0\":t}},4128:(e,t,r)=>{var n=r(1800),i=/^\\s+/;e.exports=function baseTrim(e){return e?e.slice(0,n(e)+1).replace(i,\"\"):e}},7301:e=>{e.exports=function baseUnary(e){return function(t){return e(t)}}},1234:e=>{e.exports=function baseZipObject(e,t,r){for(var n=-1,i=e.length,o=t.length,a={};++n{e.exports=function cacheHas(e,t){return e.has(t)}},1769:(e,t,r)=>{var n=r(6449),i=r(8586),o=r(1802),a=r(3222);e.exports=function castPath(e,t){return n(e)?e:i(e,t)?[e]:o(a(e))}},8754:(e,t,r)=>{var n=r(5160);e.exports=function castSlice(e,t,r){var i=e.length;return r=void 0===r?i:r,!t&&r>=i?e:n(e,t,r)}},5481:(e,t,r)=>{var n=r(9325)[\"__core-js_shared__\"];e.exports=n},8329:(e,t,r)=>{var n=r(4894);e.exports=function createBaseEach(e,t){return function(r,i){if(null==r)return r;if(!n(r))return e(r,i);for(var o=r.length,a=t?o:-1,s=Object(r);(t?a--:++a{e.exports=function createBaseFor(e){return function(t,r,n){for(var i=-1,o=Object(t),a=n(t),s=a.length;s--;){var u=a[e?s:++i];if(!1===r(o[u],u,o))break}return t}}},2507:(e,t,r)=>{var n=r(8754),i=r(9698),o=r(3912),a=r(3222);e.exports=function createCaseFirst(e){return function(t){t=a(t);var r=i(t)?o(t):void 0,s=r?r[0]:t.charAt(0),u=r?n(r,1).join(\"\"):t.slice(1);return s[e]()+u}}},5539:(e,t,r)=>{var n=r(882),i=r(828),o=r(6645),a=RegExp(\"['’]\",\"g\");e.exports=function createCompounder(e){return function(t){return n(o(i(t).replace(a,\"\")),e,\"\")}}},2006:(e,t,r)=>{var n=r(5389),i=r(4894),o=r(5950);e.exports=function createFind(e){return function(t,r,a){var s=Object(t);if(!i(t)){var u=n(r,3);t=o(t),r=function(e){return u(s[e],e,s)}}var c=e(t,r,a);return c>-1?s[u?t[c]:c]:void 0}}},4647:(e,t,r)=>{var n=r(4552)({À:\"A\",Á:\"A\",Â:\"A\",Ã:\"A\",Ä:\"A\",Å:\"A\",à:\"a\",á:\"a\",â:\"a\",ã:\"a\",ä:\"a\",å:\"a\",Ç:\"C\",ç:\"c\",Ð:\"D\",ð:\"d\",È:\"E\",É:\"E\",Ê:\"E\",Ë:\"E\",è:\"e\",é:\"e\",ê:\"e\",ë:\"e\",Ì:\"I\",Í:\"I\",Î:\"I\",Ï:\"I\",ì:\"i\",í:\"i\",î:\"i\",ï:\"i\",Ñ:\"N\",ñ:\"n\",Ò:\"O\",Ó:\"O\",Ô:\"O\",Õ:\"O\",Ö:\"O\",Ø:\"O\",ò:\"o\",ó:\"o\",ô:\"o\",õ:\"o\",ö:\"o\",ø:\"o\",Ù:\"U\",Ú:\"U\",Û:\"U\",Ü:\"U\",ù:\"u\",ú:\"u\",û:\"u\",ü:\"u\",Ý:\"Y\",ý:\"y\",ÿ:\"y\",Æ:\"Ae\",æ:\"ae\",Þ:\"Th\",þ:\"th\",ß:\"ss\",Ā:\"A\",Ă:\"A\",Ą:\"A\",ā:\"a\",ă:\"a\",ą:\"a\",Ć:\"C\",Ĉ:\"C\",Ċ:\"C\",Č:\"C\",ć:\"c\",ĉ:\"c\",ċ:\"c\",č:\"c\",Ď:\"D\",Đ:\"D\",ď:\"d\",đ:\"d\",Ē:\"E\",Ĕ:\"E\",Ė:\"E\",Ę:\"E\",Ě:\"E\",ē:\"e\",ĕ:\"e\",ė:\"e\",ę:\"e\",ě:\"e\",Ĝ:\"G\",Ğ:\"G\",Ġ:\"G\",Ģ:\"G\",ĝ:\"g\",ğ:\"g\",ġ:\"g\",ģ:\"g\",Ĥ:\"H\",Ħ:\"H\",ĥ:\"h\",ħ:\"h\",Ĩ:\"I\",Ī:\"I\",Ĭ:\"I\",Į:\"I\",İ:\"I\",ĩ:\"i\",ī:\"i\",ĭ:\"i\",į:\"i\",ı:\"i\",Ĵ:\"J\",ĵ:\"j\",Ķ:\"K\",ķ:\"k\",ĸ:\"k\",Ĺ:\"L\",Ļ:\"L\",Ľ:\"L\",Ŀ:\"L\",Ł:\"L\",ĺ:\"l\",ļ:\"l\",ľ:\"l\",ŀ:\"l\",ł:\"l\",Ń:\"N\",Ņ:\"N\",Ň:\"N\",Ŋ:\"N\",ń:\"n\",ņ:\"n\",ň:\"n\",ŋ:\"n\",Ō:\"O\",Ŏ:\"O\",Ő:\"O\",ō:\"o\",ŏ:\"o\",ő:\"o\",Ŕ:\"R\",Ŗ:\"R\",Ř:\"R\",ŕ:\"r\",ŗ:\"r\",ř:\"r\",Ś:\"S\",Ŝ:\"S\",Ş:\"S\",Š:\"S\",ś:\"s\",ŝ:\"s\",ş:\"s\",š:\"s\",Ţ:\"T\",Ť:\"T\",Ŧ:\"T\",ţ:\"t\",ť:\"t\",ŧ:\"t\",Ũ:\"U\",Ū:\"U\",Ŭ:\"U\",Ů:\"U\",Ű:\"U\",Ų:\"U\",ũ:\"u\",ū:\"u\",ŭ:\"u\",ů:\"u\",ű:\"u\",ų:\"u\",Ŵ:\"W\",ŵ:\"w\",Ŷ:\"Y\",ŷ:\"y\",Ÿ:\"Y\",Ź:\"Z\",Ż:\"Z\",Ž:\"Z\",ź:\"z\",ż:\"z\",ž:\"z\",IJ:\"IJ\",ij:\"ij\",Œ:\"Oe\",œ:\"oe\",ʼn:\"'n\",ſ:\"s\"});e.exports=n},3243:(e,t,r)=>{var n=r(6110),i=function(){try{var e=n(Object,\"defineProperty\");return e({},\"\",{}),e}catch(e){}}();e.exports=i},5911:(e,t,r)=>{var n=r(8859),i=r(4248),o=r(9219);e.exports=function equalArrays(e,t,r,a,s,u){var c=1&r,f=e.length,l=t.length;if(f!=l&&!(c&&l>f))return!1;var h=u.get(e),p=u.get(t);if(h&&p)return h==t&&p==e;var d=-1,_=!0,y=2&r?new n:void 0;for(u.set(e,t),u.set(t,e);++d{var n=r(1873),i=r(7828),o=r(5288),a=r(5911),s=r(317),u=r(4247),c=n?n.prototype:void 0,f=c?c.valueOf:void 0;e.exports=function equalByTag(e,t,r,n,c,l,h){switch(r){case\"[object DataView]\":if(e.byteLength!=t.byteLength||e.byteOffset!=t.byteOffset)return!1;e=e.buffer,t=t.buffer;case\"[object ArrayBuffer]\":return!(e.byteLength!=t.byteLength||!l(new i(e),new i(t)));case\"[object Boolean]\":case\"[object Date]\":case\"[object Number]\":return o(+e,+t);case\"[object Error]\":return e.name==t.name&&e.message==t.message;case\"[object RegExp]\":case\"[object String]\":return e==t+\"\";case\"[object Map]\":var p=s;case\"[object Set]\":var d=1&n;if(p||(p=u),e.size!=t.size&&!d)return!1;var _=h.get(e);if(_)return _==t;n|=2,h.set(e,t);var y=a(p(e),p(t),n,c,l,h);return h.delete(e),y;case\"[object Symbol]\":if(f)return f.call(e)==f.call(t)}return!1}},689:(e,t,r)=>{var n=r(2),i=Object.prototype.hasOwnProperty;e.exports=function equalObjects(e,t,r,o,a,s){var u=1&r,c=n(e),f=c.length;if(f!=n(t).length&&!u)return!1;for(var l=f;l--;){var h=c[l];if(!(u?h in t:i.call(t,h)))return!1}var p=s.get(e),d=s.get(t);if(p&&d)return p==t&&d==e;var _=!0;s.set(e,t),s.set(t,e);for(var y=u;++l{var n=\"object\"==typeof r.g&&r.g&&r.g.Object===Object&&r.g;e.exports=n},2:(e,t,r)=>{var n=r(2199),i=r(4664),o=r(5950);e.exports=function getAllKeys(e){return n(e,o,i)}},2651:(e,t,r)=>{var n=r(4218);e.exports=function getMapData(e,t){var r=e.__data__;return n(t)?r[\"string\"==typeof t?\"string\":\"hash\"]:r.map}},776:(e,t,r)=>{var n=r(756),i=r(5950);e.exports=function getMatchData(e){for(var t=i(e),r=t.length;r--;){var o=t[r],a=e[o];t[r]=[o,a,n(a)]}return t}},6110:(e,t,r)=>{var n=r(5083),i=r(392);e.exports=function getNative(e,t){var r=i(e,t);return n(r)?r:void 0}},659:(e,t,r)=>{var n=r(1873),i=Object.prototype,o=i.hasOwnProperty,a=i.toString,s=n?n.toStringTag:void 0;e.exports=function getRawTag(e){var t=o.call(e,s),r=e[s];try{e[s]=void 0;var n=!0}catch(e){}var i=a.call(e);return n&&(t?e[s]=r:delete e[s]),i}},4664:(e,t,r)=>{var n=r(9770),i=r(3345),o=Object.prototype.propertyIsEnumerable,a=Object.getOwnPropertySymbols,s=a?function(e){return null==e?[]:(e=Object(e),n(a(e),(function(t){return o.call(e,t)})))}:i;e.exports=s},5861:(e,t,r)=>{var n=r(5580),i=r(8223),o=r(2804),a=r(6545),s=r(8303),u=r(2552),c=r(7473),f=\"[object Map]\",l=\"[object Promise]\",h=\"[object Set]\",p=\"[object WeakMap]\",d=\"[object DataView]\",_=c(n),y=c(i),m=c(o),g=c(a),v=c(s),b=u;(n&&b(new n(new ArrayBuffer(1)))!=d||i&&b(new i)!=f||o&&b(o.resolve())!=l||a&&b(new a)!=h||s&&b(new s)!=p)&&(b=function(e){var t=u(e),r=\"[object Object]\"==t?e.constructor:void 0,n=r?c(r):\"\";if(n)switch(n){case _:return d;case y:return f;case m:return l;case g:return h;case v:return p}return t}),e.exports=b},392:e=>{e.exports=function getValue(e,t){return null==e?void 0:e[t]}},9326:(e,t,r)=>{var n=r(1769),i=r(2428),o=r(6449),a=r(361),s=r(294),u=r(7797);e.exports=function hasPath(e,t,r){for(var c=-1,f=(t=n(t,e)).length,l=!1;++c{var t=RegExp(\"[\\\\u200d\\\\ud800-\\\\udfff\\\\u0300-\\\\u036f\\\\ufe20-\\\\ufe2f\\\\u20d0-\\\\u20ff\\\\ufe0e\\\\ufe0f]\");e.exports=function hasUnicode(e){return t.test(e)}},5434:e=>{var t=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;e.exports=function hasUnicodeWord(e){return t.test(e)}},2032:(e,t,r)=>{var n=r(1042);e.exports=function hashClear(){this.__data__=n?n(null):{},this.size=0}},3862:e=>{e.exports=function hashDelete(e){var t=this.has(e)&&delete this.__data__[e];return this.size-=t?1:0,t}},6721:(e,t,r)=>{var n=r(1042),i=Object.prototype.hasOwnProperty;e.exports=function hashGet(e){var t=this.__data__;if(n){var r=t[e];return\"__lodash_hash_undefined__\"===r?void 0:r}return i.call(t,e)?t[e]:void 0}},2749:(e,t,r)=>{var n=r(1042),i=Object.prototype.hasOwnProperty;e.exports=function hashHas(e){var t=this.__data__;return n?void 0!==t[e]:i.call(t,e)}},5749:(e,t,r)=>{var n=r(1042);e.exports=function hashSet(e,t){var r=this.__data__;return this.size+=this.has(e)?0:1,r[e]=n&&void 0===t?\"__lodash_hash_undefined__\":t,this}},361:e=>{var t=/^(?:0|[1-9]\\d*)$/;e.exports=function isIndex(e,r){var n=typeof e;return!!(r=null==r?9007199254740991:r)&&(\"number\"==n||\"symbol\"!=n&&t.test(e))&&e>-1&&e%1==0&&e{var n=r(5288),i=r(4894),o=r(361),a=r(3805);e.exports=function isIterateeCall(e,t,r){if(!a(r))return!1;var s=typeof t;return!!(\"number\"==s?i(r)&&o(t,r.length):\"string\"==s&&t in r)&&n(r[t],e)}},8586:(e,t,r)=>{var n=r(6449),i=r(4394),o=/\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,a=/^\\w*$/;e.exports=function isKey(e,t){if(n(e))return!1;var r=typeof e;return!(\"number\"!=r&&\"symbol\"!=r&&\"boolean\"!=r&&null!=e&&!i(e))||(a.test(e)||!o.test(e)||null!=t&&e in Object(t))}},4218:e=>{e.exports=function isKeyable(e){var t=typeof e;return\"string\"==t||\"number\"==t||\"symbol\"==t||\"boolean\"==t?\"__proto__\"!==e:null===e}},7296:(e,t,r)=>{var n,i=r(5481),o=(n=/[^.]+$/.exec(i&&i.keys&&i.keys.IE_PROTO||\"\"))?\"Symbol(src)_1.\"+n:\"\";e.exports=function isMasked(e){return!!o&&o in e}},5527:e=>{var t=Object.prototype;e.exports=function isPrototype(e){var r=e&&e.constructor;return e===(\"function\"==typeof r&&r.prototype||t)}},756:(e,t,r)=>{var n=r(3805);e.exports=function isStrictComparable(e){return e==e&&!n(e)}},3702:e=>{e.exports=function listCacheClear(){this.__data__=[],this.size=0}},80:(e,t,r)=>{var n=r(6025),i=Array.prototype.splice;e.exports=function listCacheDelete(e){var t=this.__data__,r=n(t,e);return!(r<0)&&(r==t.length-1?t.pop():i.call(t,r,1),--this.size,!0)}},4739:(e,t,r)=>{var n=r(6025);e.exports=function listCacheGet(e){var t=this.__data__,r=n(t,e);return r<0?void 0:t[r][1]}},8655:(e,t,r)=>{var n=r(6025);e.exports=function listCacheHas(e){return n(this.__data__,e)>-1}},1175:(e,t,r)=>{var n=r(6025);e.exports=function listCacheSet(e,t){var r=this.__data__,i=n(r,e);return i<0?(++this.size,r.push([e,t])):r[i][1]=t,this}},3040:(e,t,r)=>{var n=r(1549),i=r(79),o=r(8223);e.exports=function mapCacheClear(){this.size=0,this.__data__={hash:new n,map:new(o||i),string:new n}}},7670:(e,t,r)=>{var n=r(2651);e.exports=function mapCacheDelete(e){var t=n(this,e).delete(e);return this.size-=t?1:0,t}},289:(e,t,r)=>{var n=r(2651);e.exports=function mapCacheGet(e){return n(this,e).get(e)}},4509:(e,t,r)=>{var n=r(2651);e.exports=function mapCacheHas(e){return n(this,e).has(e)}},2949:(e,t,r)=>{var n=r(2651);e.exports=function mapCacheSet(e,t){var r=n(this,e),i=r.size;return r.set(e,t),this.size+=r.size==i?0:1,this}},317:e=>{e.exports=function mapToArray(e){var t=-1,r=Array(e.size);return e.forEach((function(e,n){r[++t]=[n,e]})),r}},7197:e=>{e.exports=function matchesStrictComparable(e,t){return function(r){return null!=r&&(r[e]===t&&(void 0!==t||e in Object(r)))}}},2224:(e,t,r)=>{var n=r(104);e.exports=function memoizeCapped(e){var t=n(e,(function(e){return 500===r.size&&r.clear(),e})),r=t.cache;return t}},1042:(e,t,r)=>{var n=r(6110)(Object,\"create\");e.exports=n},3650:(e,t,r)=>{var n=r(4335)(Object.keys,Object);e.exports=n},6009:(e,t,r)=>{e=r.nmd(e);var n=r(4840),i=t&&!t.nodeType&&t,o=i&&e&&!e.nodeType&&e,a=o&&o.exports===i&&n.process,s=function(){try{var e=o&&o.require&&o.require(\"util\").types;return e||a&&a.binding&&a.binding(\"util\")}catch(e){}}();e.exports=s},9350:e=>{var t=Object.prototype.toString;e.exports=function objectToString(e){return t.call(e)}},4335:e=>{e.exports=function overArg(e,t){return function(r){return e(t(r))}}},9325:(e,t,r)=>{var n=r(4840),i=\"object\"==typeof self&&self&&self.Object===Object&&self,o=n||i||Function(\"return this\")();e.exports=o},1380:e=>{e.exports=function setCacheAdd(e){return this.__data__.set(e,\"__lodash_hash_undefined__\"),this}},1459:e=>{e.exports=function setCacheHas(e){return this.__data__.has(e)}},4247:e=>{e.exports=function setToArray(e){var t=-1,r=Array(e.size);return e.forEach((function(e){r[++t]=e})),r}},1420:(e,t,r)=>{var n=r(79);e.exports=function stackClear(){this.__data__=new n,this.size=0}},938:e=>{e.exports=function stackDelete(e){var t=this.__data__,r=t.delete(e);return this.size=t.size,r}},3605:e=>{e.exports=function stackGet(e){return this.__data__.get(e)}},9817:e=>{e.exports=function stackHas(e){return this.__data__.has(e)}},945:(e,t,r)=>{var n=r(79),i=r(8223),o=r(3661);e.exports=function stackSet(e,t){var r=this.__data__;if(r instanceof n){var a=r.__data__;if(!i||a.length<199)return a.push([e,t]),this.size=++r.size,this;r=this.__data__=new o(a)}return r.set(e,t),this.size=r.size,this}},3912:(e,t,r)=>{var n=r(1074),i=r(9698),o=r(2054);e.exports=function stringToArray(e){return i(e)?o(e):n(e)}},1802:(e,t,r)=>{var n=r(2224),i=/[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g,o=/\\\\(\\\\)?/g,a=n((function(e){var t=[];return 46===e.charCodeAt(0)&&t.push(\"\"),e.replace(i,(function(e,r,n,i){t.push(n?i.replace(o,\"$1\"):r||e)})),t}));e.exports=a},7797:(e,t,r)=>{var n=r(4394);e.exports=function toKey(e){if(\"string\"==typeof e||n(e))return e;var t=e+\"\";return\"0\"==t&&1/e==-1/0?\"-0\":t}},7473:e=>{var t=Function.prototype.toString;e.exports=function toSource(e){if(null!=e){try{return t.call(e)}catch(e){}try{return e+\"\"}catch(e){}}return\"\"}},1800:e=>{var t=/\\s/;e.exports=function trimmedEndIndex(e){for(var r=e.length;r--&&t.test(e.charAt(r)););return r}},2054:e=>{var t=\"\\\\ud800-\\\\udfff\",r=\"[\"+t+\"]\",n=\"[\\\\u0300-\\\\u036f\\\\ufe20-\\\\ufe2f\\\\u20d0-\\\\u20ff]\",i=\"\\\\ud83c[\\\\udffb-\\\\udfff]\",o=\"[^\"+t+\"]\",a=\"(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}\",s=\"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\",u=\"(?:\"+n+\"|\"+i+\")\"+\"?\",c=\"[\\\\ufe0e\\\\ufe0f]?\",f=c+u+(\"(?:\\\\u200d(?:\"+[o,a,s].join(\"|\")+\")\"+c+u+\")*\"),l=\"(?:\"+[o+n+\"?\",n,a,s,r].join(\"|\")+\")\",h=RegExp(i+\"(?=\"+i+\")|\"+l+f,\"g\");e.exports=function unicodeToArray(e){return e.match(h)||[]}},2225:e=>{var t=\"\\\\ud800-\\\\udfff\",r=\"\\\\u2700-\\\\u27bf\",n=\"a-z\\\\xdf-\\\\xf6\\\\xf8-\\\\xff\",i=\"A-Z\\\\xc0-\\\\xd6\\\\xd8-\\\\xde\",o=\"\\\\xac\\\\xb1\\\\xd7\\\\xf7\\\\x00-\\\\x2f\\\\x3a-\\\\x40\\\\x5b-\\\\x60\\\\x7b-\\\\xbf\\\\u2000-\\\\u206f \\\\t\\\\x0b\\\\f\\\\xa0\\\\ufeff\\\\n\\\\r\\\\u2028\\\\u2029\\\\u1680\\\\u180e\\\\u2000\\\\u2001\\\\u2002\\\\u2003\\\\u2004\\\\u2005\\\\u2006\\\\u2007\\\\u2008\\\\u2009\\\\u200a\\\\u202f\\\\u205f\\\\u3000\",a=\"[\"+o+\"]\",s=\"\\\\d+\",u=\"[\"+r+\"]\",c=\"[\"+n+\"]\",f=\"[^\"+t+o+s+r+n+i+\"]\",l=\"(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}\",h=\"[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]\",p=\"[\"+i+\"]\",d=\"(?:\"+c+\"|\"+f+\")\",_=\"(?:\"+p+\"|\"+f+\")\",y=\"(?:['’](?:d|ll|m|re|s|t|ve))?\",m=\"(?:['’](?:D|LL|M|RE|S|T|VE))?\",g=\"(?:[\\\\u0300-\\\\u036f\\\\ufe20-\\\\ufe2f\\\\u20d0-\\\\u20ff]|\\\\ud83c[\\\\udffb-\\\\udfff])?\",v=\"[\\\\ufe0e\\\\ufe0f]?\",b=v+g+(\"(?:\\\\u200d(?:\"+[\"[^\"+t+\"]\",l,h].join(\"|\")+\")\"+v+g+\")*\"),w=\"(?:\"+[u,l,h].join(\"|\")+\")\"+b,I=RegExp([p+\"?\"+c+\"+\"+y+\"(?=\"+[a,p,\"$\"].join(\"|\")+\")\",_+\"+\"+m+\"(?=\"+[a,p+d,\"$\"].join(\"|\")+\")\",p+\"?\"+d+\"+\"+y,p+\"+\"+m,\"\\\\d*(?:1ST|2ND|3RD|(?![123])\\\\dTH)(?=\\\\b|[a-z_])\",\"\\\\d*(?:1st|2nd|3rd|(?![123])\\\\dth)(?=\\\\b|[A-Z_])\",s,w].join(\"|\"),\"g\");e.exports=function unicodeWords(e){return e.match(I)||[]}},4058:(e,t,r)=>{var n=r(4792),i=r(5539)((function(e,t,r){return t=t.toLowerCase(),e+(r?n(t):t)}));e.exports=i},4792:(e,t,r)=>{var n=r(3222),i=r(5808);e.exports=function capitalize(e){return i(n(e).toLowerCase())}},828:(e,t,r)=>{var n=r(4647),i=r(3222),o=/[\\xc0-\\xd6\\xd8-\\xf6\\xf8-\\xff\\u0100-\\u017f]/g,a=RegExp(\"[\\\\u0300-\\\\u036f\\\\ufe20-\\\\ufe2f\\\\u20d0-\\\\u20ff]\",\"g\");e.exports=function deburr(e){return(e=i(e))&&e.replace(o,n).replace(a,\"\")}},5288:e=>{e.exports=function eq(e,t){return e===t||e!=e&&t!=t}},7309:(e,t,r)=>{var n=r(2006)(r(4713));e.exports=n},4713:(e,t,r)=>{var n=r(2523),i=r(5389),o=r(1489),a=Math.max;e.exports=function findIndex(e,t,r){var s=null==e?0:e.length;if(!s)return-1;var u=null==r?0:o(r);return u<0&&(u=a(s+u,0)),n(e,i(t,3),u)}},8156:(e,t,r)=>{var n=r(7422);e.exports=function get(e,t,r){var i=null==e?void 0:n(e,t);return void 0===i?r:i}},631:(e,t,r)=>{var n=r(8077),i=r(9326);e.exports=function hasIn(e,t){return null!=e&&i(e,t,n)}},3488:e=>{e.exports=function identity(e){return e}},2428:(e,t,r)=>{var n=r(7534),i=r(346),o=Object.prototype,a=o.hasOwnProperty,s=o.propertyIsEnumerable,u=n(function(){return arguments}())?n:function(e){return i(e)&&a.call(e,\"callee\")&&!s.call(e,\"callee\")};e.exports=u},6449:e=>{var t=Array.isArray;e.exports=t},4894:(e,t,r)=>{var n=r(1882),i=r(294);e.exports=function isArrayLike(e){return null!=e&&i(e.length)&&!n(e)}},3656:(e,t,r)=>{e=r.nmd(e);var n=r(9325),i=r(9935),o=t&&!t.nodeType&&t,a=o&&e&&!e.nodeType&&e,s=a&&a.exports===o?n.Buffer:void 0,u=(s?s.isBuffer:void 0)||i;e.exports=u},1882:(e,t,r)=>{var n=r(2552),i=r(3805);e.exports=function isFunction(e){if(!i(e))return!1;var t=n(e);return\"[object Function]\"==t||\"[object GeneratorFunction]\"==t||\"[object AsyncFunction]\"==t||\"[object Proxy]\"==t}},294:e=>{e.exports=function isLength(e){return\"number\"==typeof e&&e>-1&&e%1==0&&e<=9007199254740991}},3805:e=>{e.exports=function isObject(e){var t=typeof e;return null!=e&&(\"object\"==t||\"function\"==t)}},346:e=>{e.exports=function isObjectLike(e){return null!=e&&\"object\"==typeof e}},4394:(e,t,r)=>{var n=r(2552),i=r(346);e.exports=function isSymbol(e){return\"symbol\"==typeof e||i(e)&&\"[object Symbol]\"==n(e)}},7167:(e,t,r)=>{var n=r(4901),i=r(7301),o=r(6009),a=o&&o.isTypedArray,s=a?i(a):n;e.exports=s},5950:(e,t,r)=>{var n=r(695),i=r(8984),o=r(4894);e.exports=function keys(e){return o(e)?n(e):i(e)}},104:(e,t,r)=>{var n=r(3661);function memoize(e,t){if(\"function\"!=typeof e||null!=t&&\"function\"!=typeof t)throw new TypeError(\"Expected a function\");var memoized=function(){var r=arguments,n=t?t.apply(this,r):r[0],i=memoized.cache;if(i.has(n))return i.get(n);var o=e.apply(this,r);return memoized.cache=i.set(n,o)||i,o};return memoized.cache=new(memoize.Cache||n),memoized}memoize.Cache=n,e.exports=memoize},583:(e,t,r)=>{var n=r(7237),i=r(7255),o=r(8586),a=r(7797);e.exports=function property(e){return o(e)?n(a(e)):i(e)}},2426:(e,t,r)=>{var n=r(4248),i=r(5389),o=r(916),a=r(6449),s=r(6800);e.exports=function some(e,t,r){var u=a(e)?n:o;return r&&s(e,t,r)&&(t=void 0),u(e,i(t,3))}},3345:e=>{e.exports=function stubArray(){return[]}},9935:e=>{e.exports=function stubFalse(){return!1}},7400:(e,t,r)=>{var n=r(9374),i=1/0;e.exports=function toFinite(e){return e?(e=n(e))===i||e===-1/0?17976931348623157e292*(e<0?-1:1):e==e?e:0:0===e?e:0}},1489:(e,t,r)=>{var n=r(7400);e.exports=function toInteger(e){var t=n(e),r=t%1;return t==t?r?t-r:t:0}},9374:(e,t,r)=>{var n=r(4128),i=r(3805),o=r(4394),a=/^[-+]0x[0-9a-f]+$/i,s=/^0b[01]+$/i,u=/^0o[0-7]+$/i,c=parseInt;e.exports=function toNumber(e){if(\"number\"==typeof e)return e;if(o(e))return NaN;if(i(e)){var t=\"function\"==typeof e.valueOf?e.valueOf():e;e=i(t)?t+\"\":t}if(\"string\"!=typeof e)return 0===e?e:+e;e=n(e);var r=s.test(e);return r||u.test(e)?c(e.slice(2),r?2:8):a.test(e)?NaN:+e}},3222:(e,t,r)=>{var n=r(7556);e.exports=function toString(e){return null==e?\"\":n(e)}},5808:(e,t,r)=>{var n=r(2507)(\"toUpperCase\");e.exports=n},6645:(e,t,r)=>{var n=r(1733),i=r(5434),o=r(3222),a=r(2225);e.exports=function words(e,t,r){return e=o(e),void 0===(t=r?void 0:t)?i(e)?a(e):n(e):e.match(t)||[]}},7248:(e,t,r)=>{var n=r(6547),i=r(1234);e.exports=function zipObject(e,t){return i(e||[],t||[],n)}},5606:e=>{var t,r,n=e.exports={};function defaultSetTimout(){throw new Error(\"setTimeout has not been defined\")}function defaultClearTimeout(){throw new Error(\"clearTimeout has not been defined\")}function runTimeout(e){if(t===setTimeout)return setTimeout(e,0);if((t===defaultSetTimout||!t)&&setTimeout)return t=setTimeout,setTimeout(e,0);try{return t(e,0)}catch(r){try{return t.call(null,e,0)}catch(r){return t.call(this,e,0)}}}!function(){try{t=\"function\"==typeof setTimeout?setTimeout:defaultSetTimout}catch(e){t=defaultSetTimout}try{r=\"function\"==typeof clearTimeout?clearTimeout:defaultClearTimeout}catch(e){r=defaultClearTimeout}}();var i,o=[],a=!1,s=-1;function cleanUpNextTick(){a&&i&&(a=!1,i.length?o=i.concat(o):s=-1,o.length&&drainQueue())}function drainQueue(){if(!a){var e=runTimeout(cleanUpNextTick);a=!0;for(var t=o.length;t;){for(i=o,o=[];++s1)for(var r=1;r{\"use strict\";var n=r(5606),i=65536,o=4294967295;var a=r(2861).Buffer,s=r.g.crypto||r.g.msCrypto;s&&s.getRandomValues?e.exports=function randomBytes(e,t){if(e>o)throw new RangeError(\"requested too many random bytes\");var r=a.allocUnsafe(e);if(e>0)if(e>i)for(var u=0;u{\"use strict\";var r=Symbol.for(\"react.element\"),n=Symbol.for(\"react.portal\"),i=Symbol.for(\"react.fragment\"),o=Symbol.for(\"react.strict_mode\"),a=Symbol.for(\"react.profiler\"),s=Symbol.for(\"react.provider\"),u=Symbol.for(\"react.context\"),c=Symbol.for(\"react.forward_ref\"),f=Symbol.for(\"react.suspense\"),l=Symbol.for(\"react.memo\"),h=Symbol.for(\"react.lazy\"),p=Symbol.iterator;var d={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},_=Object.assign,y={};function E(e,t,r){this.props=e,this.context=t,this.refs=y,this.updater=r||d}function F(){}function G(e,t,r){this.props=e,this.context=t,this.refs=y,this.updater=r||d}E.prototype.isReactComponent={},E.prototype.setState=function(e,t){if(\"object\"!=typeof e&&\"function\"!=typeof e&&null!=e)throw Error(\"setState(...): takes an object of state variables to update or a function which returns an object of state variables.\");this.updater.enqueueSetState(this,e,t,\"setState\")},E.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,\"forceUpdate\")},F.prototype=E.prototype;var m=G.prototype=new F;m.constructor=G,_(m,E.prototype),m.isPureReactComponent=!0;var g=Array.isArray,v=Object.prototype.hasOwnProperty,b={current:null},w={key:!0,ref:!0,__self:!0,__source:!0};function M(e,t,n){var i,o={},a=null,s=null;if(null!=t)for(i in void 0!==t.ref&&(s=t.ref),void 0!==t.key&&(a=\"\"+t.key),t)v.call(t,i)&&!w.hasOwnProperty(i)&&(o[i]=t[i]);var u=arguments.length-2;if(1===u)o.children=n;else if(1{\"use strict\";e.exports=r(5287)},2861:(e,t,r)=>{var n=r(8287),i=n.Buffer;function copyProps(e,t){for(var r in e)t[r]=e[r]}function SafeBuffer(e,t,r){return i(e,t,r)}i.from&&i.alloc&&i.allocUnsafe&&i.allocUnsafeSlow?e.exports=n:(copyProps(n,t),t.Buffer=SafeBuffer),SafeBuffer.prototype=Object.create(i.prototype),copyProps(i,SafeBuffer),SafeBuffer.from=function(e,t,r){if(\"number\"==typeof e)throw new TypeError(\"Argument must not be a number\");return i(e,t,r)},SafeBuffer.alloc=function(e,t,r){if(\"number\"!=typeof e)throw new TypeError(\"Argument must be a number\");var n=i(e);return void 0!==t?\"string\"==typeof r?n.fill(t,r):n.fill(t):n.fill(0),n},SafeBuffer.allocUnsafe=function(e){if(\"number\"!=typeof e)throw new TypeError(\"Argument must be a number\");return i(e)},SafeBuffer.allocUnsafeSlow=function(e){if(\"number\"!=typeof e)throw new TypeError(\"Argument must be a number\");return n.SlowBuffer(e)}},8011:(e,t,r)=>{var n=r(2861).Buffer;function Hash(e,t){this._block=n.alloc(e),this._finalSize=t,this._blockSize=e,this._len=0}Hash.prototype.update=function(e,t){\"string\"==typeof e&&(t=t||\"utf8\",e=n.from(e,t));for(var r=this._block,i=this._blockSize,o=e.length,a=this._len,s=0;s=this._finalSize&&(this._update(this._block),this._block.fill(0));var r=8*this._len;if(r<=4294967295)this._block.writeUInt32BE(r,this._blockSize-4);else{var n=(4294967295&r)>>>0,i=(r-n)/4294967296;this._block.writeUInt32BE(i,this._blockSize-8),this._block.writeUInt32BE(n,this._blockSize-4)}this._update(this._block);var o=this._hash();return e?o.toString(e):o},Hash.prototype._update=function(){throw new Error(\"_update must be implemented by subclass\")},e.exports=Hash},2802:(e,t,r)=>{var n=e.exports=function SHA(e){e=e.toLowerCase();var t=n[e];if(!t)throw new Error(e+\" is not supported (we accept pull requests)\");return new t};n.sha=r(7816),n.sha1=r(3737),n.sha224=r(6710),n.sha256=r(4107),n.sha384=r(2827),n.sha512=r(2890)},7816:(e,t,r)=>{var n=r(6698),i=r(8011),o=r(2861).Buffer,a=[1518500249,1859775393,-1894007588,-899497514],s=new Array(80);function Sha(){this.init(),this._w=s,i.call(this,64,56)}function rotl30(e){return e<<30|e>>>2}function ft(e,t,r,n){return 0===e?t&r|~t&n:2===e?t&r|t&n|r&n:t^r^n}n(Sha,i),Sha.prototype.init=function(){return this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520,this},Sha.prototype._update=function(e){for(var t,r=this._w,n=0|this._a,i=0|this._b,o=0|this._c,s=0|this._d,u=0|this._e,c=0;c<16;++c)r[c]=e.readInt32BE(4*c);for(;c<80;++c)r[c]=r[c-3]^r[c-8]^r[c-14]^r[c-16];for(var f=0;f<80;++f){var l=~~(f/20),h=0|((t=n)<<5|t>>>27)+ft(l,i,o,s)+u+r[f]+a[l];u=s,s=o,o=rotl30(i),i=n,n=h}this._a=n+this._a|0,this._b=i+this._b|0,this._c=o+this._c|0,this._d=s+this._d|0,this._e=u+this._e|0},Sha.prototype._hash=function(){var e=o.allocUnsafe(20);return e.writeInt32BE(0|this._a,0),e.writeInt32BE(0|this._b,4),e.writeInt32BE(0|this._c,8),e.writeInt32BE(0|this._d,12),e.writeInt32BE(0|this._e,16),e},e.exports=Sha},3737:(e,t,r)=>{var n=r(6698),i=r(8011),o=r(2861).Buffer,a=[1518500249,1859775393,-1894007588,-899497514],s=new Array(80);function Sha1(){this.init(),this._w=s,i.call(this,64,56)}function rotl5(e){return e<<5|e>>>27}function rotl30(e){return e<<30|e>>>2}function ft(e,t,r,n){return 0===e?t&r|~t&n:2===e?t&r|t&n|r&n:t^r^n}n(Sha1,i),Sha1.prototype.init=function(){return this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520,this},Sha1.prototype._update=function(e){for(var t,r=this._w,n=0|this._a,i=0|this._b,o=0|this._c,s=0|this._d,u=0|this._e,c=0;c<16;++c)r[c]=e.readInt32BE(4*c);for(;c<80;++c)r[c]=(t=r[c-3]^r[c-8]^r[c-14]^r[c-16])<<1|t>>>31;for(var f=0;f<80;++f){var l=~~(f/20),h=rotl5(n)+ft(l,i,o,s)+u+r[f]+a[l]|0;u=s,s=o,o=rotl30(i),i=n,n=h}this._a=n+this._a|0,this._b=i+this._b|0,this._c=o+this._c|0,this._d=s+this._d|0,this._e=u+this._e|0},Sha1.prototype._hash=function(){var e=o.allocUnsafe(20);return e.writeInt32BE(0|this._a,0),e.writeInt32BE(0|this._b,4),e.writeInt32BE(0|this._c,8),e.writeInt32BE(0|this._d,12),e.writeInt32BE(0|this._e,16),e},e.exports=Sha1},6710:(e,t,r)=>{var n=r(6698),i=r(4107),o=r(8011),a=r(2861).Buffer,s=new Array(64);function Sha224(){this.init(),this._w=s,o.call(this,64,56)}n(Sha224,i),Sha224.prototype.init=function(){return this._a=3238371032,this._b=914150663,this._c=812702999,this._d=4144912697,this._e=4290775857,this._f=1750603025,this._g=1694076839,this._h=3204075428,this},Sha224.prototype._hash=function(){var e=a.allocUnsafe(28);return e.writeInt32BE(this._a,0),e.writeInt32BE(this._b,4),e.writeInt32BE(this._c,8),e.writeInt32BE(this._d,12),e.writeInt32BE(this._e,16),e.writeInt32BE(this._f,20),e.writeInt32BE(this._g,24),e},e.exports=Sha224},4107:(e,t,r)=>{var n=r(6698),i=r(8011),o=r(2861).Buffer,a=[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],s=new Array(64);function Sha256(){this.init(),this._w=s,i.call(this,64,56)}function ch(e,t,r){return r^e&(t^r)}function maj(e,t,r){return e&t|r&(e|t)}function sigma0(e){return(e>>>2|e<<30)^(e>>>13|e<<19)^(e>>>22|e<<10)}function sigma1(e){return(e>>>6|e<<26)^(e>>>11|e<<21)^(e>>>25|e<<7)}function gamma0(e){return(e>>>7|e<<25)^(e>>>18|e<<14)^e>>>3}n(Sha256,i),Sha256.prototype.init=function(){return this._a=1779033703,this._b=3144134277,this._c=1013904242,this._d=2773480762,this._e=1359893119,this._f=2600822924,this._g=528734635,this._h=1541459225,this},Sha256.prototype._update=function(e){for(var t,r=this._w,n=0|this._a,i=0|this._b,o=0|this._c,s=0|this._d,u=0|this._e,c=0|this._f,f=0|this._g,l=0|this._h,h=0;h<16;++h)r[h]=e.readInt32BE(4*h);for(;h<64;++h)r[h]=0|(((t=r[h-2])>>>17|t<<15)^(t>>>19|t<<13)^t>>>10)+r[h-7]+gamma0(r[h-15])+r[h-16];for(var p=0;p<64;++p){var d=l+sigma1(u)+ch(u,c,f)+a[p]+r[p]|0,_=sigma0(n)+maj(n,i,o)|0;l=f,f=c,c=u,u=s+d|0,s=o,o=i,i=n,n=d+_|0}this._a=n+this._a|0,this._b=i+this._b|0,this._c=o+this._c|0,this._d=s+this._d|0,this._e=u+this._e|0,this._f=c+this._f|0,this._g=f+this._g|0,this._h=l+this._h|0},Sha256.prototype._hash=function(){var e=o.allocUnsafe(32);return e.writeInt32BE(this._a,0),e.writeInt32BE(this._b,4),e.writeInt32BE(this._c,8),e.writeInt32BE(this._d,12),e.writeInt32BE(this._e,16),e.writeInt32BE(this._f,20),e.writeInt32BE(this._g,24),e.writeInt32BE(this._h,28),e},e.exports=Sha256},2827:(e,t,r)=>{var n=r(6698),i=r(2890),o=r(8011),a=r(2861).Buffer,s=new Array(160);function Sha384(){this.init(),this._w=s,o.call(this,128,112)}n(Sha384,i),Sha384.prototype.init=function(){return this._ah=3418070365,this._bh=1654270250,this._ch=2438529370,this._dh=355462360,this._eh=1731405415,this._fh=2394180231,this._gh=3675008525,this._hh=1203062813,this._al=3238371032,this._bl=914150663,this._cl=812702999,this._dl=4144912697,this._el=4290775857,this._fl=1750603025,this._gl=1694076839,this._hl=3204075428,this},Sha384.prototype._hash=function(){var e=a.allocUnsafe(48);function writeInt64BE(t,r,n){e.writeInt32BE(t,n),e.writeInt32BE(r,n+4)}return writeInt64BE(this._ah,this._al,0),writeInt64BE(this._bh,this._bl,8),writeInt64BE(this._ch,this._cl,16),writeInt64BE(this._dh,this._dl,24),writeInt64BE(this._eh,this._el,32),writeInt64BE(this._fh,this._fl,40),e},e.exports=Sha384},2890:(e,t,r)=>{var n=r(6698),i=r(8011),o=r(2861).Buffer,a=[1116352408,3609767458,1899447441,602891725,3049323471,3964484399,3921009573,2173295548,961987163,4081628472,1508970993,3053834265,2453635748,2937671579,2870763221,3664609560,3624381080,2734883394,310598401,1164996542,607225278,1323610764,1426881987,3590304994,1925078388,4068182383,2162078206,991336113,2614888103,633803317,3248222580,3479774868,3835390401,2666613458,4022224774,944711139,264347078,2341262773,604807628,2007800933,770255983,1495990901,1249150122,1856431235,1555081692,3175218132,1996064986,2198950837,2554220882,3999719339,2821834349,766784016,2952996808,2566594879,3210313671,3203337956,3336571891,1034457026,3584528711,2466948901,113926993,3758326383,338241895,168717936,666307205,1188179964,773529912,1546045734,1294757372,1522805485,1396182291,2643833823,1695183700,2343527390,1986661051,1014477480,2177026350,1206759142,2456956037,344077627,2730485921,1290863460,2820302411,3158454273,3259730800,3505952657,3345764771,106217008,3516065817,3606008344,3600352804,1432725776,4094571909,1467031594,275423344,851169720,430227734,3100823752,506948616,1363258195,659060556,3750685593,883997877,3785050280,958139571,3318307427,1322822218,3812723403,1537002063,2003034995,1747873779,3602036899,1955562222,1575990012,2024104815,1125592928,2227730452,2716904306,2361852424,442776044,2428436474,593698344,2756734187,3733110249,3204031479,2999351573,3329325298,3815920427,3391569614,3928383900,3515267271,566280711,3940187606,3454069534,4118630271,4000239992,116418474,1914138554,174292421,2731055270,289380356,3203993006,460393269,320620315,685471733,587496836,852142971,1086792851,1017036298,365543100,1126000580,2618297676,1288033470,3409855158,1501505948,4234509866,1607167915,987167468,1816402316,1246189591],s=new Array(160);function Sha512(){this.init(),this._w=s,i.call(this,128,112)}function Ch(e,t,r){return r^e&(t^r)}function maj(e,t,r){return e&t|r&(e|t)}function sigma0(e,t){return(e>>>28|t<<4)^(t>>>2|e<<30)^(t>>>7|e<<25)}function sigma1(e,t){return(e>>>14|t<<18)^(e>>>18|t<<14)^(t>>>9|e<<23)}function Gamma0(e,t){return(e>>>1|t<<31)^(e>>>8|t<<24)^e>>>7}function Gamma0l(e,t){return(e>>>1|t<<31)^(e>>>8|t<<24)^(e>>>7|t<<25)}function Gamma1(e,t){return(e>>>19|t<<13)^(t>>>29|e<<3)^e>>>6}function Gamma1l(e,t){return(e>>>19|t<<13)^(t>>>29|e<<3)^(e>>>6|t<<26)}function getCarry(e,t){return e>>>0>>0?1:0}n(Sha512,i),Sha512.prototype.init=function(){return this._ah=1779033703,this._bh=3144134277,this._ch=1013904242,this._dh=2773480762,this._eh=1359893119,this._fh=2600822924,this._gh=528734635,this._hh=1541459225,this._al=4089235720,this._bl=2227873595,this._cl=4271175723,this._dl=1595750129,this._el=2917565137,this._fl=725511199,this._gl=4215389547,this._hl=327033209,this},Sha512.prototype._update=function(e){for(var t=this._w,r=0|this._ah,n=0|this._bh,i=0|this._ch,o=0|this._dh,s=0|this._eh,u=0|this._fh,c=0|this._gh,f=0|this._hh,l=0|this._al,h=0|this._bl,p=0|this._cl,d=0|this._dl,_=0|this._el,y=0|this._fl,m=0|this._gl,g=0|this._hl,v=0;v<32;v+=2)t[v]=e.readInt32BE(4*v),t[v+1]=e.readInt32BE(4*v+4);for(;v<160;v+=2){var b=t[v-30],w=t[v-30+1],I=Gamma0(b,w),x=Gamma0l(w,b),B=Gamma1(b=t[v-4],w=t[v-4+1]),k=Gamma1l(w,b),C=t[v-14],q=t[v-14+1],L=t[v-32],j=t[v-32+1],z=x+q|0,P=I+C+getCarry(z,x)|0;P=(P=P+B+getCarry(z=z+k|0,k)|0)+L+getCarry(z=z+j|0,j)|0,t[v]=P,t[v+1]=z}for(var D=0;D<160;D+=2){P=t[D],z=t[D+1];var U=maj(r,n,i),W=maj(l,h,p),K=sigma0(r,l),V=sigma0(l,r),$=sigma1(s,_),H=sigma1(_,s),Y=a[D],Z=a[D+1],J=Ch(s,u,c),ee=Ch(_,y,m),te=g+H|0,re=f+$+getCarry(te,g)|0;re=(re=(re=re+J+getCarry(te=te+ee|0,ee)|0)+Y+getCarry(te=te+Z|0,Z)|0)+P+getCarry(te=te+z|0,z)|0;var ne=V+W|0,ie=K+U+getCarry(ne,V)|0;f=c,g=m,c=u,m=y,u=s,y=_,s=o+re+getCarry(_=d+te|0,d)|0,o=i,d=p,i=n,p=h,n=r,h=l,r=re+ie+getCarry(l=te+ne|0,te)|0}this._al=this._al+l|0,this._bl=this._bl+h|0,this._cl=this._cl+p|0,this._dl=this._dl+d|0,this._el=this._el+_|0,this._fl=this._fl+y|0,this._gl=this._gl+m|0,this._hl=this._hl+g|0,this._ah=this._ah+r+getCarry(this._al,l)|0,this._bh=this._bh+n+getCarry(this._bl,h)|0,this._ch=this._ch+i+getCarry(this._cl,p)|0,this._dh=this._dh+o+getCarry(this._dl,d)|0,this._eh=this._eh+s+getCarry(this._el,_)|0,this._fh=this._fh+u+getCarry(this._fl,y)|0,this._gh=this._gh+c+getCarry(this._gl,m)|0,this._hh=this._hh+f+getCarry(this._hl,g)|0},Sha512.prototype._hash=function(){var e=o.allocUnsafe(64);function writeInt64BE(t,r,n){e.writeInt32BE(t,n),e.writeInt32BE(r,n+4)}return writeInt64BE(this._ah,this._al,0),writeInt64BE(this._bh,this._bl,8),writeInt64BE(this._ch,this._cl,16),writeInt64BE(this._dh,this._dl,24),writeInt64BE(this._eh,this._el,32),writeInt64BE(this._fh,this._fl,40),writeInt64BE(this._gh,this._gl,48),writeInt64BE(this._hh,this._hl,56),e},e.exports=Sha512},7666:(e,t,r)=>{var n=r(4851),i=r(953);function _extends(){var t;return e.exports=_extends=n?i(t=n).call(t):function(e){for(var t=1;t{\"use strict\";var n=r(9709);e.exports=n},462:(e,t,r)=>{\"use strict\";var n=r(975);e.exports=n},2567:(e,t,r)=>{\"use strict\";r(9307);var n=r(1747);e.exports=n(\"Function\",\"bind\")},3034:(e,t,r)=>{\"use strict\";var n=r(8280),i=r(2567),o=Function.prototype;e.exports=function(e){var t=e.bind;return e===o||n(o,e)&&t===o.bind?i:t}},9748:(e,t,r)=>{\"use strict\";r(1340);var n=r(2046);e.exports=n.Object.assign},953:(e,t,r)=>{\"use strict\";e.exports=r(3375)},4851:(e,t,r)=>{\"use strict\";e.exports=r(5401)},3375:(e,t,r)=>{\"use strict\";var n=r(3700);e.exports=n},5401:(e,t,r)=>{\"use strict\";var n=r(462);e.exports=n},2159:(e,t,r)=>{\"use strict\";var n=r(2250),i=r(4640),o=TypeError;e.exports=function(e){if(n(e))return e;throw new o(i(e)+\" is not a function\")}},6624:(e,t,r)=>{\"use strict\";var n=r(6285),i=String,o=TypeError;e.exports=function(e){if(n(e))return e;throw new o(i(e)+\" is not an object\")}},4436:(e,t,r)=>{\"use strict\";var n=r(7374),i=r(4849),o=r(575),createMethod=function(e){return function(t,r,a){var s=n(t),u=o(s);if(0===u)return!e&&-1;var c,f=i(a,u);if(e&&r!=r){for(;u>f;)if((c=s[f++])!=c)return!0}else for(;u>f;f++)if((e||f in s)&&s[f]===r)return e||f||0;return!e&&-1}};e.exports={includes:createMethod(!0),indexOf:createMethod(!1)}},3427:(e,t,r)=>{\"use strict\";var n=r(1907);e.exports=n([].slice)},5807:(e,t,r)=>{\"use strict\";var n=r(1907),i=n({}.toString),o=n(\"\".slice);e.exports=function(e){return o(i(e),8,-1)}},1626:(e,t,r)=>{\"use strict\";var n=r(9447),i=r(4284),o=r(5817);e.exports=n?function(e,t,r){return i.f(e,t,o(1,r))}:function(e,t,r){return e[t]=r,e}},5817:e=>{\"use strict\";e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},2532:(e,t,r)=>{\"use strict\";var n=r(1010),i=Object.defineProperty;e.exports=function(e,t){try{i(n,e,{value:t,configurable:!0,writable:!0})}catch(r){n[e]=t}return t}},9447:(e,t,r)=>{\"use strict\";var n=r(8828);e.exports=!n((function(){return 7!==Object.defineProperty({},1,{get:function(){return 7}})[1]}))},9552:(e,t,r)=>{\"use strict\";var n=r(1010),i=r(6285),o=n.document,a=i(o)&&i(o.createElement);e.exports=function(e){return a?o.createElement(e):{}}},4723:e=>{\"use strict\";e.exports=\"undefined\"!=typeof navigator&&String(navigator.userAgent)||\"\"},5683:(e,t,r)=>{\"use strict\";var n,i,o=r(1010),a=r(4723),s=o.process,u=o.Deno,c=s&&s.versions||u&&u.version,f=c&&c.v8;f&&(i=(n=f.split(\".\"))[0]>0&&n[0]<4?1:+(n[0]+n[1])),!i&&a&&(!(n=a.match(/Edge\\/(\\d+)/))||n[1]>=74)&&(n=a.match(/Chrome\\/(\\d+)/))&&(i=+n[1]),e.exports=i},376:e=>{\"use strict\";e.exports=[\"constructor\",\"hasOwnProperty\",\"isPrototypeOf\",\"propertyIsEnumerable\",\"toLocaleString\",\"toString\",\"valueOf\"]},1091:(e,t,r)=>{\"use strict\";var n=r(1010),i=r(6024),o=r(2361),a=r(2250),s=r(3846).f,u=r(7463),c=r(2046),f=r(8311),l=r(1626),h=r(9724);r(6128);var wrapConstructor=function(e){var Wrapper=function(t,r,n){if(this instanceof Wrapper){switch(arguments.length){case 0:return new e;case 1:return new e(t);case 2:return new e(t,r)}return new e(t,r,n)}return i(e,this,arguments)};return Wrapper.prototype=e.prototype,Wrapper};e.exports=function(e,t){var r,i,p,d,_,y,m,g,v,b=e.target,w=e.global,I=e.stat,x=e.proto,B=w?n:I?n[b]:n[b]&&n[b].prototype,k=w?c:c[b]||l(c,b,{})[b],C=k.prototype;for(d in t)i=!(r=u(w?d:b+(I?\".\":\"#\")+d,e.forced))&&B&&h(B,d),y=k[d],i&&(m=e.dontCallGetSet?(v=s(B,d))&&v.value:B[d]),_=i&&m?m:t[d],(r||x||typeof y!=typeof _)&&(g=e.bind&&i?f(_,n):e.wrap&&i?wrapConstructor(_):x&&a(_)?o(_):_,(e.sham||_&&_.sham||y&&y.sham)&&l(g,\"sham\",!0),l(k,d,g),x&&(h(c,p=b+\"Prototype\")||l(c,p,{}),l(c[p],d,_),e.real&&C&&(r||!C[d])&&l(C,d,_)))}},8828:e=>{\"use strict\";e.exports=function(e){try{return!!e()}catch(e){return!0}}},6024:(e,t,r)=>{\"use strict\";var n=r(1505),i=Function.prototype,o=i.apply,a=i.call;e.exports=\"object\"==typeof Reflect&&Reflect.apply||(n?a.bind(o):function(){return a.apply(o,arguments)})},8311:(e,t,r)=>{\"use strict\";var n=r(2361),i=r(2159),o=r(1505),a=n(n.bind);e.exports=function(e,t){return i(e),void 0===t?e:o?a(e,t):function(){return e.apply(t,arguments)}}},1505:(e,t,r)=>{\"use strict\";var n=r(8828);e.exports=!n((function(){var e=function(){}.bind();return\"function\"!=typeof e||e.hasOwnProperty(\"prototype\")}))},4673:(e,t,r)=>{\"use strict\";var n=r(1907),i=r(2159),o=r(6285),a=r(9724),s=r(3427),u=r(1505),c=Function,f=n([].concat),l=n([].join),h={};e.exports=u?c.bind:function bind(e){var t=i(this),r=t.prototype,n=s(arguments,1),u=function bound(){var r=f(n,s(arguments));return this instanceof u?function(e,t,r){if(!a(h,t)){for(var n=[],i=0;i{\"use strict\";var n=r(1505),i=Function.prototype.call;e.exports=n?i.bind(i):function(){return i.apply(i,arguments)}},2361:(e,t,r)=>{\"use strict\";var n=r(5807),i=r(1907);e.exports=function(e){if(\"Function\"===n(e))return i(e)}},1907:(e,t,r)=>{\"use strict\";var n=r(1505),i=Function.prototype,o=i.call,a=n&&i.bind.bind(o,o);e.exports=n?a:function(e){return function(){return o.apply(e,arguments)}}},1747:(e,t,r)=>{\"use strict\";var n=r(1010),i=r(2046);e.exports=function(e,t){var r=i[e+\"Prototype\"],o=r&&r[t];if(o)return o;var a=n[e],s=a&&a.prototype;return s&&s[t]}},5582:(e,t,r)=>{\"use strict\";var n=r(2046),i=r(1010),o=r(2250),aFunction=function(e){return o(e)?e:void 0};e.exports=function(e,t){return arguments.length<2?aFunction(n[e])||aFunction(i[e]):n[e]&&n[e][t]||i[e]&&i[e][t]}},9367:(e,t,r)=>{\"use strict\";var n=r(2159),i=r(7136);e.exports=function(e,t){var r=e[t];return i(r)?void 0:n(r)}},1010:function(e,t,r){\"use strict\";var check=function(e){return e&&e.Math===Math&&e};e.exports=check(\"object\"==typeof globalThis&&globalThis)||check(\"object\"==typeof window&&window)||check(\"object\"==typeof self&&self)||check(\"object\"==typeof r.g&&r.g)||check(\"object\"==typeof this&&this)||function(){return this}()||Function(\"return this\")()},9724:(e,t,r)=>{\"use strict\";var n=r(1907),i=r(9298),o=n({}.hasOwnProperty);e.exports=Object.hasOwn||function hasOwn(e,t){return o(i(e),t)}},8530:e=>{\"use strict\";e.exports={}},3648:(e,t,r)=>{\"use strict\";var n=r(9447),i=r(8828),o=r(9552);e.exports=!n&&!i((function(){return 7!==Object.defineProperty(o(\"div\"),\"a\",{get:function(){return 7}}).a}))},6946:(e,t,r)=>{\"use strict\";var n=r(1907),i=r(8828),o=r(5807),a=Object,s=n(\"\".split);e.exports=i((function(){return!a(\"z\").propertyIsEnumerable(0)}))?function(e){return\"String\"===o(e)?s(e,\"\"):a(e)}:a},2250:e=>{\"use strict\";var t=\"object\"==typeof document&&document.all;e.exports=void 0===t&&void 0!==t?function(e){return\"function\"==typeof e||e===t}:function(e){return\"function\"==typeof e}},7463:(e,t,r)=>{\"use strict\";var n=r(8828),i=r(2250),o=/#|\\.prototype\\./,isForced=function(e,t){var r=s[a(e)];return r===c||r!==u&&(i(t)?n(t):!!t)},a=isForced.normalize=function(e){return String(e).replace(o,\".\").toLowerCase()},s=isForced.data={},u=isForced.NATIVE=\"N\",c=isForced.POLYFILL=\"P\";e.exports=isForced},7136:e=>{\"use strict\";e.exports=function(e){return null==e}},6285:(e,t,r)=>{\"use strict\";var n=r(2250);e.exports=function(e){return\"object\"==typeof e?null!==e:n(e)}},7376:e=>{\"use strict\";e.exports=!0},5594:(e,t,r)=>{\"use strict\";var n=r(5582),i=r(2250),o=r(8280),a=r(3556),s=Object;e.exports=a?function(e){return\"symbol\"==typeof e}:function(e){var t=n(\"Symbol\");return i(t)&&o(t.prototype,s(e))}},575:(e,t,r)=>{\"use strict\";var n=r(3121);e.exports=function(e){return n(e.length)}},1176:e=>{\"use strict\";var t=Math.ceil,r=Math.floor;e.exports=Math.trunc||function trunc(e){var n=+e;return(n>0?r:t)(n)}},9538:(e,t,r)=>{\"use strict\";var n=r(9447),i=r(1907),o=r(3930),a=r(8828),s=r(2875),u=r(7170),c=r(2574),f=r(9298),l=r(6946),h=Object.assign,p=Object.defineProperty,d=i([].concat);e.exports=!h||a((function(){if(n&&1!==h({b:1},h(p({},\"a\",{enumerable:!0,get:function(){p(this,\"b\",{value:3,enumerable:!1})}}),{b:2})).b)return!0;var e={},t={},r=Symbol(\"assign detection\"),i=\"abcdefghijklmnopqrst\";return e[r]=7,i.split(\"\").forEach((function(e){t[e]=e})),7!==h({},e)[r]||s(h({},t)).join(\"\")!==i}))?function assign(e,t){for(var r=f(e),i=arguments.length,a=1,h=u.f,p=c.f;i>a;)for(var _,y=l(arguments[a++]),m=h?d(s(y),h(y)):s(y),g=m.length,v=0;g>v;)_=m[v++],n&&!o(p,y,_)||(r[_]=y[_]);return r}:h},4284:(e,t,r)=>{\"use strict\";var n=r(9447),i=r(3648),o=r(8661),a=r(6624),s=r(470),u=TypeError,c=Object.defineProperty,f=Object.getOwnPropertyDescriptor,l=\"enumerable\",h=\"configurable\",p=\"writable\";t.f=n?o?function defineProperty(e,t,r){if(a(e),t=s(t),a(r),\"function\"==typeof e&&\"prototype\"===t&&\"value\"in r&&p in r&&!r[p]){var n=f(e,t);n&&n[p]&&(e[t]=r.value,r={configurable:h in r?r[h]:n[h],enumerable:l in r?r[l]:n[l],writable:!1})}return c(e,t,r)}:c:function defineProperty(e,t,r){if(a(e),t=s(t),a(r),i)try{return c(e,t,r)}catch(e){}if(\"get\"in r||\"set\"in r)throw new u(\"Accessors not supported\");return\"value\"in r&&(e[t]=r.value),e}},3846:(e,t,r)=>{\"use strict\";var n=r(9447),i=r(3930),o=r(2574),a=r(5817),s=r(7374),u=r(470),c=r(9724),f=r(3648),l=Object.getOwnPropertyDescriptor;t.f=n?l:function getOwnPropertyDescriptor(e,t){if(e=s(e),t=u(t),f)try{return l(e,t)}catch(e){}if(c(e,t))return a(!i(o.f,e,t),e[t])}},7170:(e,t)=>{\"use strict\";t.f=Object.getOwnPropertySymbols},8280:(e,t,r)=>{\"use strict\";var n=r(1907);e.exports=n({}.isPrototypeOf)},3045:(e,t,r)=>{\"use strict\";var n=r(1907),i=r(9724),o=r(7374),a=r(4436).indexOf,s=r(8530),u=n([].push);e.exports=function(e,t){var r,n=o(e),c=0,f=[];for(r in n)!i(s,r)&&i(n,r)&&u(f,r);for(;t.length>c;)i(n,r=t[c++])&&(~a(f,r)||u(f,r));return f}},2875:(e,t,r)=>{\"use strict\";var n=r(3045),i=r(376);e.exports=Object.keys||function keys(e){return n(e,i)}},2574:(e,t)=>{\"use strict\";var r={}.propertyIsEnumerable,n=Object.getOwnPropertyDescriptor,i=n&&!r.call({1:2},1);t.f=i?function propertyIsEnumerable(e){var t=n(this,e);return!!t&&t.enumerable}:r},581:(e,t,r)=>{\"use strict\";var n=r(3930),i=r(2250),o=r(6285),a=TypeError;e.exports=function(e,t){var r,s;if(\"string\"===t&&i(r=e.toString)&&!o(s=n(r,e)))return s;if(i(r=e.valueOf)&&!o(s=n(r,e)))return s;if(\"string\"!==t&&i(r=e.toString)&&!o(s=n(r,e)))return s;throw new a(\"Can't convert object to primitive value\")}},2046:e=>{\"use strict\";e.exports={}},4239:(e,t,r)=>{\"use strict\";var n=r(7136),i=TypeError;e.exports=function(e){if(n(e))throw new i(\"Can't call method on \"+e);return e}},6128:(e,t,r)=>{\"use strict\";var n=r(7376),i=r(1010),o=r(2532),a=\"__core-js_shared__\",s=e.exports=i[a]||o(a,{});(s.versions||(s.versions=[])).push({version:\"3.37.1\",mode:n?\"pure\":\"global\",copyright:\"© 2014-2024 Denis Pushkarev (zloirock.ru)\",license:\"https://github.com/zloirock/core-js/blob/v3.37.1/LICENSE\",source:\"https://github.com/zloirock/core-js\"})},5816:(e,t,r)=>{\"use strict\";var n=r(6128);e.exports=function(e,t){return n[e]||(n[e]=t||{})}},9846:(e,t,r)=>{\"use strict\";var n=r(5683),i=r(8828),o=r(1010).String;e.exports=!!Object.getOwnPropertySymbols&&!i((function(){var e=Symbol(\"symbol detection\");return!o(e)||!(Object(e)instanceof Symbol)||!Symbol.sham&&n&&n<41}))},4849:(e,t,r)=>{\"use strict\";var n=r(5482),i=Math.max,o=Math.min;e.exports=function(e,t){var r=n(e);return r<0?i(r+t,0):o(r,t)}},7374:(e,t,r)=>{\"use strict\";var n=r(6946),i=r(4239);e.exports=function(e){return n(i(e))}},5482:(e,t,r)=>{\"use strict\";var n=r(1176);e.exports=function(e){var t=+e;return t!=t||0===t?0:n(t)}},3121:(e,t,r)=>{\"use strict\";var n=r(5482),i=Math.min;e.exports=function(e){var t=n(e);return t>0?i(t,9007199254740991):0}},9298:(e,t,r)=>{\"use strict\";var n=r(4239),i=Object;e.exports=function(e){return i(n(e))}},6028:(e,t,r)=>{\"use strict\";var n=r(3930),i=r(6285),o=r(5594),a=r(9367),s=r(581),u=r(6264),c=TypeError,f=u(\"toPrimitive\");e.exports=function(e,t){if(!i(e)||o(e))return e;var r,u=a(e,f);if(u){if(void 0===t&&(t=\"default\"),r=n(u,e,t),!i(r)||o(r))return r;throw new c(\"Can't convert object to primitive value\")}return void 0===t&&(t=\"number\"),s(e,t)}},470:(e,t,r)=>{\"use strict\";var n=r(6028),i=r(5594);e.exports=function(e){var t=n(e,\"string\");return i(t)?t:t+\"\"}},4640:e=>{\"use strict\";var t=String;e.exports=function(e){try{return t(e)}catch(e){return\"Object\"}}},6499:(e,t,r)=>{\"use strict\";var n=r(1907),i=0,o=Math.random(),a=n(1..toString);e.exports=function(e){return\"Symbol(\"+(void 0===e?\"\":e)+\")_\"+a(++i+o,36)}},3556:(e,t,r)=>{\"use strict\";var n=r(9846);e.exports=n&&!Symbol.sham&&\"symbol\"==typeof Symbol.iterator},8661:(e,t,r)=>{\"use strict\";var n=r(9447),i=r(8828);e.exports=n&&i((function(){return 42!==Object.defineProperty((function(){}),\"prototype\",{value:42,writable:!1}).prototype}))},6264:(e,t,r)=>{\"use strict\";var n=r(1010),i=r(5816),o=r(9724),a=r(6499),s=r(9846),u=r(3556),c=n.Symbol,f=i(\"wks\"),l=u?c.for||c:c&&c.withoutSetter||a;e.exports=function(e){return o(f,e)||(f[e]=s&&o(c,e)?c[e]:l(\"Symbol.\"+e)),f[e]}},9307:(e,t,r)=>{\"use strict\";var n=r(1091),i=r(4673);n({target:\"Function\",proto:!0,forced:Function.bind!==i},{bind:i})},1340:(e,t,r)=>{\"use strict\";var n=r(1091),i=r(9538);n({target:\"Object\",stat:!0,arity:2,forced:Object.assign!==i},{assign:i})},9709:(e,t,r)=>{\"use strict\";var n=r(3034);e.exports=n},975:(e,t,r)=>{\"use strict\";var n=r(9748);e.exports=n}},t={};function __webpack_require__(r){var n=t[r];if(void 0!==n)return n.exports;var i=t[r]={id:r,loaded:!1,exports:{}};return e[r].call(i.exports,i,i.exports,__webpack_require__),i.loaded=!0,i.exports}__webpack_require__.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(t,{a:t}),t},__webpack_require__.d=(e,t)=>{for(var r in t)__webpack_require__.o(t,r)&&!__webpack_require__.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},__webpack_require__.g=function(){if(\"object\"==typeof globalThis)return globalThis;try{return this||new Function(\"return this\")()}catch(e){if(\"object\"==typeof window)return window}}(),__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(e,\"__esModule\",{value:!0})},__webpack_require__.nmd=e=>(e.paths=[],e.children||(e.children=[]),e);var r={};return(()=>{\"use strict\";__webpack_require__.d(r,{default:()=>Kt});var e={};__webpack_require__.r(e),__webpack_require__.d(e,{TOGGLE_CONFIGS:()=>Tt,UPDATE_CONFIGS:()=>jt,downloadConfig:()=>downloadConfig,getConfigByUrl:()=>getConfigByUrl,loaded:()=>loaded,toggle:()=>toggle,update:()=>update});var t={};__webpack_require__.r(t),__webpack_require__.d(t,{get:()=>get});var n=__webpack_require__(6540);class StandaloneLayout extends n.Component{render(){const{getComponent:e}=this.props,t=e(\"Container\"),r=e(\"Row\"),i=e(\"Col\"),o=e(\"Topbar\",!0),a=e(\"BaseLayout\",!0),s=e(\"onlineValidatorBadge\",!0);return n.createElement(t,{className:\"swagger-ui\"},o?n.createElement(o,null):null,n.createElement(a,null),n.createElement(r,null,n.createElement(i,null,n.createElement(s,null))))}}const i=StandaloneLayout,stadalone_layout=()=>({components:{StandaloneLayout:i}});var o=__webpack_require__(9404),a=__webpack_require__.n(o);__webpack_require__(6750),__webpack_require__(4058),__webpack_require__(5808),__webpack_require__(104),__webpack_require__(7309),__webpack_require__(2426),__webpack_require__(5288),__webpack_require__(1882),__webpack_require__(2205),__webpack_require__(3209),__webpack_require__(2802);const s=function makeWindow(){var e={location:{},history:{},open:()=>{},close:()=>{},File:function(){},FormData:function(){}};if(\"undefined\"==typeof window)return e;try{e=window;for(var t of[\"File\",\"Blob\",\"FormData\"])t in window&&(e[t]=window[t])}catch(e){console.error(e)}return e}();a().Set.of(\"type\",\"format\",\"items\",\"default\",\"maximum\",\"exclusiveMaximum\",\"minimum\",\"exclusiveMinimum\",\"maxLength\",\"minLength\",\"pattern\",\"maxItems\",\"minItems\",\"uniqueItems\",\"enum\",\"multipleOf\");__webpack_require__(8287).Buffer;const parseSearch=()=>{const e=new URLSearchParams(s.location.search);return Object.fromEntries(e)};class TopBar extends n.Component{constructor(e,t){super(e,t),this.state={url:e.specSelectors.url(),selectedIndex:0}}UNSAFE_componentWillReceiveProps(e){this.setState({url:e.specSelectors.url()})}onUrlChange=e=>{let{target:{value:t}}=e;this.setState({url:t})};flushAuthData(){const{persistAuthorization:e}=this.props.getConfigs();e||this.props.authActions.restoreAuthorization({authorized:{}})}loadSpec=e=>{this.flushAuthData(),this.props.specActions.updateUrl(e),this.props.specActions.download(e)};onUrlSelect=e=>{let t=e.target.value||e.target.href;this.loadSpec(t),this.setSelectedUrl(t),e.preventDefault()};downloadUrl=e=>{this.loadSpec(this.state.url),e.preventDefault()};setSearch=e=>{let t=parseSearch();t[\"urls.primaryName\"]=e.name;const r=`${window.location.protocol}//${window.location.host}${window.location.pathname}`;window&&window.history&&window.history.pushState&&window.history.replaceState(null,\"\",`${r}?${(e=>{const t=new URLSearchParams(Object.entries(e));return String(t)})(t)}`)};setSelectedUrl=e=>{const t=this.props.getConfigs().urls||[];t&&t.length&&e&&t.forEach(((t,r)=>{t.url===e&&(this.setState({selectedIndex:r}),this.setSearch(t))}))};componentDidMount(){const e=this.props.getConfigs(),t=e.urls||[];if(t&&t.length){var r=this.state.selectedIndex;let n=parseSearch()[\"urls.primaryName\"]||e.urls.primaryName;n&&t.forEach(((e,t)=>{e.name===n&&(this.setState({selectedIndex:t}),r=t)})),this.loadSpec(t[r].url)}}onFilterChange=e=>{let{target:{value:t}}=e;this.props.layoutActions.updateFilter(t)};render(){let{getComponent:e,specSelectors:t,getConfigs:r}=this.props;const i=e(\"Button\"),o=e(\"Link\"),a=e(\"Logo\");let s=\"loading\"===t.loadingStatus();const u=[\"download-url-input\"];\"failed\"===t.loadingStatus()&&u.push(\"failed\"),s&&u.push(\"loading\");const{urls:c}=r();let f=[],l=null;if(c){let e=[];c.forEach(((t,r)=>{e.push(n.createElement(\"option\",{key:r,value:t.url},t.name))})),f.push(n.createElement(\"label\",{className:\"select-label\",htmlFor:\"select\"},n.createElement(\"span\",null,\"Select a definition\"),n.createElement(\"select\",{id:\"select\",disabled:s,onChange:this.onUrlSelect,value:c[this.state.selectedIndex].url},e)))}else l=this.downloadUrl,f.push(n.createElement(\"input\",{className:u.join(\" \"),type:\"text\",onChange:this.onUrlChange,value:this.state.url,disabled:s,id:\"download-url-input\"})),f.push(n.createElement(i,{className:\"download-url-button\",onClick:this.downloadUrl},\"Explore\"));return n.createElement(\"div\",{className:\"topbar\"},n.createElement(\"div\",{className:\"wrapper\"},n.createElement(\"div\",{className:\"topbar-wrapper\"},n.createElement(o,null,n.createElement(a,null)),n.createElement(\"form\",{className:\"download-url-wrapper\",onSubmit:l},f.map(((e,t)=>(0,n.cloneElement)(e,{key:t})))))))}}const u=TopBar;var c,f,l,h,p,d,_,y,m,g,v,b,w,I,x,B,k,C,q,L,j,z,P,D,U,W,K,V,$,H,Y,Z;function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var t=1;tn.createElement(\"svg\",_extends({xmlns:\"http://www.w3.org/2000/svg\",viewBox:\"0 0 407 116\"},e),c||(c=n.createElement(\"defs\",null,n.createElement(\"clipPath\",{id:\"logo_small_svg__clip-SW_TM-logo-on-dark\"},n.createElement(\"path\",{d:\"M0 0h407v116H0z\"})),n.createElement(\"style\",null,\".logo_small_svg__cls-2{fill:#fff}.logo_small_svg__cls-3{fill:#85ea2d}\"))),n.createElement(\"g\",{id:\"logo_small_svg__SW_TM-logo-on-dark\",style:{clipPath:\"url(#logo_small_svg__clip-SW_TM-logo-on-dark)\"}},n.createElement(\"g\",{id:\"logo_small_svg__SW_In-Product\",transform:\"translate(-.301)\"},f||(f=n.createElement(\"path\",{id:\"logo_small_svg__Path_2936\",d:\"M359.15 70.674h-.7v-3.682h-1.26v-.6h3.219v.6h-1.259Z\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2936\"})),l||(l=n.createElement(\"path\",{id:\"logo_small_svg__Path_2937\",d:\"m363.217 70.674-1.242-3.574h-.023q.05.8.05 1.494v2.083h-.636v-4.286h.987l1.19 3.407h.017l1.225-3.407h.99v4.283h-.675v-2.118a30 30 0 0 1 .044-1.453h-.023l-1.286 3.571Z\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2937\"})),h||(h=n.createElement(\"path\",{id:\"logo_small_svg__Path_2938\",d:\"M50.328 97.669a47.642 47.642 0 1 1 47.643-47.642 47.64 47.64 0 0 1-47.643 47.642\",className:\"logo_small_svg__cls-3\",\"data-name\":\"Path 2938\"})),p||(p=n.createElement(\"path\",{id:\"logo_small_svg__Path_2939\",d:\"M50.328 4.769A45.258 45.258 0 1 1 5.07 50.027 45.26 45.26 0 0 1 50.328 4.769m0-4.769a50.027 50.027 0 1 0 50.027 50.027A50.027 50.027 0 0 0 50.328 0\",className:\"logo_small_svg__cls-3\",\"data-name\":\"Path 2939\"})),n.createElement(\"path\",{id:\"logo_small_svg__Path_2940\",d:\"M31.8 33.854c-.154 1.712.058 3.482-.057 5.213a43 43 0 0 1-.693 5.156 9.53 9.53 0 0 1-4.1 5.829c4.079 2.654 4.54 6.771 4.81 10.946.135 2.25.077 4.52.308 6.752.173 1.731.846 2.174 2.636 2.231.73.02 1.48 0 2.327 0v5.349c-5.29.9-9.657-.6-10.734-5.079a31 31 0 0 1-.654-5c-.117-1.789.076-3.578-.058-5.367-.386-4.906-1.02-6.56-5.713-6.791v-6.1a9 9 0 0 1 1.028-.173c2.577-.135 3.674-.924 4.231-3.463a29 29 0 0 0 .481-4.329 82 82 0 0 1 .6-8.406c.673-3.982 3.136-5.906 7.234-6.137 1.154-.057 2.327 0 3.655 0v5.464c-.558.038-1.039.115-1.539.115-3.336-.115-3.51 1.02-3.762 3.79m6.406 12.658h-.077a3.515 3.515 0 1 0-.346 7.021h.231a3.46 3.46 0 0 0 3.655-3.251v-.192a3.523 3.523 0 0 0-3.461-3.578Zm12.062 0a3.373 3.373 0 0 0-3.482 3.251 2 2 0 0 0 .02.327 3.3 3.3 0 0 0 3.578 3.443 3.263 3.263 0 0 0 3.443-3.558 3.308 3.308 0 0 0-3.557-3.463Zm12.351 0a3.59 3.59 0 0 0-3.655 3.482 3.53 3.53 0 0 0 3.536 3.539h.039c1.769.309 3.559-1.4 3.674-3.462a3.57 3.57 0 0 0-3.6-3.559Zm16.948.288c-2.232-.1-3.348-.846-3.9-2.962a21.5 21.5 0 0 1-.635-4.136c-.154-2.578-.135-5.175-.308-7.753-.4-6.117-4.828-8.252-11.254-7.195v5.31c1.019 0 1.808 0 2.6.019 1.366.019 2.4.539 2.539 2.059.135 1.385.135 2.789.27 4.193.269 2.79.422 5.618.9 8.369a8.72 8.72 0 0 0 3.921 5.348c-3.4 2.289-4.406 5.559-4.578 9.234-.1 2.52-.154 5.059-.289 7.6-.115 2.308-.923 3.058-3.251 3.116-.654.019-1.289.077-2.019.115v5.445c1.365 0 2.616.077 3.866 0 3.886-.231 6.233-2.117 7-5.887A49 49 0 0 0 75 63.4c.135-1.923.116-3.866.308-5.771.289-2.982 1.655-4.213 4.636-4.4a4 4 0 0 0 .828-.192v-6.1c-.5-.058-.843-.115-1.208-.135Z\",\"data-name\":\"Path 2940\",style:{fill:\"#173647\"}}),d||(d=n.createElement(\"path\",{id:\"logo_small_svg__Path_2941\",d:\"M152.273 58.122a11.23 11.23 0 0 1-4.384 9.424q-4.383 3.382-11.9 3.382-8.14 0-12.524-2.1V63.7a33 33 0 0 0 6.137 1.879 32.3 32.3 0 0 0 6.575.689q5.322 0 8.015-2.02a6.63 6.63 0 0 0 2.692-5.62 7.2 7.2 0 0 0-.954-3.9 8.9 8.9 0 0 0-3.194-2.8 44.6 44.6 0 0 0-6.81-2.911q-6.387-2.286-9.126-5.417a11.96 11.96 0 0 1-2.74-8.172A10.16 10.16 0 0 1 128.039 27q3.977-3.131 10.52-3.131a31 31 0 0 1 12.555 2.5L149.455 31a28.4 28.4 0 0 0-11.021-2.38 10.67 10.67 0 0 0-6.606 1.816 5.98 5.98 0 0 0-2.38 5.041 7.7 7.7 0 0 0 .877 3.9 8.24 8.24 0 0 0 2.959 2.786 36.7 36.7 0 0 0 6.371 2.8q7.2 2.566 9.91 5.51a10.84 10.84 0 0 1 2.708 7.649\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2941\"})),_||(_=n.createElement(\"path\",{id:\"logo_small_svg__Path_2942\",d:\"M185.288 70.3 179 50.17q-.594-1.848-2.222-8.391h-.251q-1.252 5.479-2.192 8.453L167.849 70.3h-6.011l-9.361-34.315h5.447q3.318 12.931 5.057 19.693a80 80 0 0 1 1.988 9.111h.25q.345-1.785 1.112-4.618t1.33-4.493l6.294-19.693h5.635l6.137 19.693a66 66 0 0 1 2.379 9.048h.251a33 33 0 0 1 .673-3.475q.548-2.347 6.528-25.266h5.385L191.456 70.3Z\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2942\"})),y||(y=n.createElement(\"path\",{id:\"logo_small_svg__Path_2943\",d:\"m225.115 70.3-1.033-4.885h-.25a14.45 14.45 0 0 1-5.119 4.368 15.6 15.6 0 0 1-6.372 1.143q-5.1 0-8-2.63t-2.9-7.483q0-10.4 16.626-10.9l5.823-.188V47.6q0-4.038-1.738-5.964t-5.552-1.923a22.6 22.6 0 0 0-9.706 2.63l-1.6-3.977a24.4 24.4 0 0 1 5.557-2.16 24 24 0 0 1 6.058-.783q6.136 0 9.1 2.724t2.959 8.735V70.3Zm-11.741-3.663a10.55 10.55 0 0 0 7.626-2.66 9.85 9.85 0 0 0 2.771-7.451v-3.1l-5.2.219q-6.2.219-8.939 1.926a5.8 5.8 0 0 0-2.74 5.306 5.35 5.35 0 0 0 1.707 4.29 7.08 7.08 0 0 0 4.775 1.472Z\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2943\"})),m||(m=n.createElement(\"path\",{id:\"logo_small_svg__Path_2944\",d:\"M264.6 35.987v3.287l-6.356.752a11.16 11.16 0 0 1 2.255 6.856 10.15 10.15 0 0 1-3.444 8.047q-3.444 3-9.456 3a15.7 15.7 0 0 1-2.88-.25Q241.4 59.438 241.4 62.1a2.24 2.24 0 0 0 1.159 2.082 8.46 8.46 0 0 0 3.976.673h6.074q5.573 0 8.563 2.348a8.16 8.16 0 0 1 2.99 6.825 9.74 9.74 0 0 1-4.571 8.688q-4.572 2.989-13.338 2.99-6.732 0-10.379-2.5a8.09 8.09 0 0 1-3.647-7.076 7.95 7.95 0 0 1 2-5.417 10.2 10.2 0 0 1 5.636-3.1 5.43 5.43 0 0 1-2.207-1.847 4.9 4.9 0 0 1-.893-2.912 5.53 5.53 0 0 1 1-3.288 10.5 10.5 0 0 1 3.162-2.723 9.28 9.28 0 0 1-4.336-3.726 10.95 10.95 0 0 1-1.675-6.012q0-5.634 3.382-8.688t9.58-3.052a17.4 17.4 0 0 1 4.853.626Zm-27.367 40.075a4.66 4.66 0 0 0 2.348 4.227 12.97 12.97 0 0 0 6.732 1.44q6.543 0 9.69-1.956a5.99 5.99 0 0 0 3.147-5.307q0-2.787-1.723-3.867t-6.481-1.08h-6.23a8.2 8.2 0 0 0-5.51 1.69 6.04 6.04 0 0 0-1.973 4.853m2.818-29.086a6.98 6.98 0 0 0 2.035 5.448 8.12 8.12 0 0 0 5.667 1.847q7.608 0 7.608-7.389 0-7.733-7.7-7.733a7.63 7.63 0 0 0-5.635 1.972q-1.976 1.973-1.975 5.855\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2944\"})),g||(g=n.createElement(\"path\",{id:\"logo_small_svg__Path_2945\",d:\"M299.136 35.987v3.287l-6.356.752a11.17 11.17 0 0 1 2.254 6.856 10.15 10.15 0 0 1-3.444 8.047q-3.444 3-9.455 3a15.7 15.7 0 0 1-2.88-.25q-3.32 1.754-3.319 4.415a2.24 2.24 0 0 0 1.158 2.082 8.46 8.46 0 0 0 3.976.673h6.074q5.574 0 8.563 2.348a8.16 8.16 0 0 1 2.99 6.825 9.74 9.74 0 0 1-4.571 8.688q-4.57 2.989-13.337 2.99-6.732 0-10.379-2.5a8.09 8.09 0 0 1-3.648-7.076 7.95 7.95 0 0 1 2-5.417 10.2 10.2 0 0 1 5.636-3.1 5.43 5.43 0 0 1-2.208-1.847 4.9 4.9 0 0 1-.892-2.912 5.53 5.53 0 0 1 1-3.288 10.5 10.5 0 0 1 3.162-2.723 9.27 9.27 0 0 1-4.336-3.726 10.95 10.95 0 0 1-1.675-6.012q0-5.634 3.381-8.688t9.581-3.052a17.4 17.4 0 0 1 4.853.626Zm-27.364 40.075a4.66 4.66 0 0 0 2.348 4.227 12.97 12.97 0 0 0 6.731 1.44q6.544 0 9.691-1.956a5.99 5.99 0 0 0 3.146-5.307q0-2.787-1.722-3.867t-6.481-1.08h-6.23a8.2 8.2 0 0 0-5.511 1.69 6.04 6.04 0 0 0-1.972 4.853m2.818-29.086a6.98 6.98 0 0 0 2.035 5.448 8.12 8.12 0 0 0 5.667 1.847q7.607 0 7.608-7.389 0-7.733-7.7-7.733a7.63 7.63 0 0 0-5.635 1.972q-1.975 1.973-1.975 5.855\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2945\"})),v||(v=n.createElement(\"path\",{id:\"logo_small_svg__Path_2946\",d:\"M316.778 70.928q-7.608 0-12.007-4.634t-4.4-12.868q0-8.3 4.086-13.181a13.57 13.57 0 0 1 10.974-4.884 12.94 12.94 0 0 1 10.207 4.239q3.762 4.247 3.762 11.2v3.287h-23.643q.156 6.044 3.053 9.174t8.156 3.131a27.6 27.6 0 0 0 10.958-2.317v4.634a27.5 27.5 0 0 1-5.213 1.706 29.3 29.3 0 0 1-5.933.513m-1.409-31.215a8.49 8.49 0 0 0-6.591 2.692 12.4 12.4 0 0 0-2.9 7.452h17.94q0-4.916-2.191-7.53a7.71 7.71 0 0 0-6.258-2.614\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2946\"})),b||(b=n.createElement(\"path\",{id:\"logo_small_svg__Path_2947\",d:\"M350.9 35.361a20.4 20.4 0 0 1 4.1.375l-.721 4.822a17.7 17.7 0 0 0-3.757-.47 9.14 9.14 0 0 0-7.122 3.382 12.33 12.33 0 0 0-2.959 8.422V70.3h-5.2V35.987h4.29l.6 6.356h.25a15.1 15.1 0 0 1 4.6-5.166 10.36 10.36 0 0 1 5.919-1.816\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2947\"})),w||(w=n.createElement(\"path\",{id:\"logo_small_svg__Path_2948\",d:\"M255.857 96.638s-3.43-.391-4.85-.391c-2.058 0-3.111.735-3.111 2.18 0 1.568.882 1.935 3.748 2.719 3.527.98 4.8 1.911 4.8 4.777 0 3.675-2.3 5.267-5.61 5.267a36 36 0 0 1-5.487-.662l.27-2.18s3.306.441 5.046.441c2.082 0 3.037-.931 3.037-2.7 0-1.421-.759-1.91-3.331-2.523-3.626-.93-5.193-2.033-5.193-4.948 0-3.381 2.229-4.776 5.585-4.776a37 37 0 0 1 5.315.587Z\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2948\"})),I||(I=n.createElement(\"path\",{id:\"logo_small_svg__Path_2949\",d:\"M262.967 94.14h4.733l3.748 13.106L275.2 94.14h4.752v16.78H277.2v-14.5h-.145l-4.191 13.816h-2.842l-4.191-13.816h-.145v14.5h-2.719Z\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2949\"})),x||(x=n.createElement(\"path\",{id:\"logo_small_svg__Path_2950\",d:\"M322.057 94.14H334.3v2.425h-4.728v14.355h-2.743V96.565h-4.777Z\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2950\"})),B||(B=n.createElement(\"path\",{id:\"logo_small_svg__Path_2951\",d:\"M346.137 94.14c3.332 0 5.12 1.249 5.12 4.361 0 2.033-.637 3.037-1.984 3.772 1.445.563 2.4 1.592 2.4 3.9 0 3.43-2.081 4.752-5.339 4.752h-6.566V94.14Zm-3.65 2.352v4.8h3.6c1.666 0 2.4-.832 2.4-2.474 0-1.617-.833-2.327-2.5-2.327Zm0 7.1v4.973h3.7c1.689 0 2.694-.539 2.694-2.548 0-1.911-1.421-2.425-2.744-2.425Z\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2951\"})),k||(k=n.createElement(\"path\",{id:\"logo_small_svg__Path_2952\",d:\"M358.414 94.14H369v2.377h-7.864v4.751h6.394v2.332h-6.394v4.924H369v2.4h-10.586Z\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2952\"})),C||(C=n.createElement(\"path\",{id:\"logo_small_svg__Path_2953\",d:\"M378.747 94.14h5.414l4.164 16.78h-2.744l-1.239-4.92h-5.777l-1.239 4.923h-2.719Zm.361 9.456h4.708l-1.737-7.178h-1.225Z\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2953\"})),q||(q=n.createElement(\"path\",{id:\"logo_small_svg__Path_2954\",d:\"M397.1 105.947v4.973h-2.719V94.14h6.37c3.7 0 5.683 2.12 5.683 5.843 0 2.376-.956 4.519-2.744 5.352l2.769 5.585h-2.989l-2.426-4.973Zm3.651-9.455H397.1v7.1h3.7c2.057 0 2.841-1.85 2.841-3.589 0-1.9-.934-3.511-2.894-3.511Z\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2954\"})),L||(L=n.createElement(\"path\",{id:\"logo_small_svg__Path_2955\",d:\"M290.013 94.14h5.413l4.164 16.78h-2.743l-1.239-4.92h-5.777l-1.239 4.923h-2.719Zm.361 9.456h4.707l-1.737-7.178h-1.225Z\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2955\"})),j||(j=n.createElement(\"path\",{id:\"logo_small_svg__Path_2956\",d:\"M308.362 105.947v4.973h-2.719V94.14h6.369c3.7 0 5.683 2.12 5.683 5.843 0 2.376-.955 4.519-2.743 5.352l2.768 5.585h-2.989l-2.425-4.973Zm3.65-9.455h-3.65v7.1h3.7c2.058 0 2.841-1.85 2.841-3.589-.003-1.903-.931-3.511-2.891-3.511\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2956\"})),z||(z=n.createElement(\"path\",{id:\"logo_small_svg__Path_2957\",d:\"M130.606 107.643a3.02 3.02 0 0 1-1.18 2.537 5.1 5.1 0 0 1-3.2.91 8 8 0 0 1-3.371-.564v-1.383a9 9 0 0 0 1.652.506 8.7 8.7 0 0 0 1.77.186 3.57 3.57 0 0 0 2.157-.544 1.78 1.78 0 0 0 .725-1.512 1.95 1.95 0 0 0-.257-1.05 2.4 2.4 0 0 0-.86-.754 12 12 0 0 0-1.833-.784 5.84 5.84 0 0 1-2.456-1.458 3.2 3.2 0 0 1-.738-2.2 2.74 2.74 0 0 1 1.071-2.267 4.44 4.44 0 0 1 2.831-.843 8.3 8.3 0 0 1 3.38.675l-.447 1.247a7.6 7.6 0 0 0-2.966-.641 2.88 2.88 0 0 0-1.779.489 1.61 1.61 0 0 0-.64 1.357 2.1 2.1 0 0 0 .236 1.049 2.2 2.2 0 0 0 .8.75 10 10 0 0 0 1.715.754 6.8 6.8 0 0 1 2.667 1.483 2.92 2.92 0 0 1 .723 2.057\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2957\"})),P||(P=n.createElement(\"path\",{id:\"logo_small_svg__Path_2958\",d:\"M134.447 101.686v5.991a2.4 2.4 0 0 0 .515 1.686 2.1 2.1 0 0 0 1.609.556 2.63 2.63 0 0 0 2.12-.792 4 4 0 0 0 .67-2.587v-4.854h1.4v9.236H139.6l-.2-1.239h-.075a2.8 2.8 0 0 1-1.193 1.045 4 4 0 0 1-1.74.362 3.53 3.53 0 0 1-2.524-.8 3.4 3.4 0 0 1-.839-2.562v-6.042Z\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2958\"})),D||(D=n.createElement(\"path\",{id:\"logo_small_svg__Path_2959\",d:\"M148.206 111.09a4 4 0 0 1-1.647-.333 3.1 3.1 0 0 1-1.252-1.023h-.1a12 12 0 0 1 .1 1.533v3.8h-1.4v-13.381h1.137l.194 1.264h.067a3.26 3.26 0 0 1 1.256-1.1 3.8 3.8 0 0 1 1.643-.337 3.41 3.41 0 0 1 2.836 1.256 6.68 6.68 0 0 1-.017 7.057 3.42 3.42 0 0 1-2.817 1.264m-.2-8.385a2.48 2.48 0 0 0-2.048.784 4.04 4.04 0 0 0-.649 2.494v.312a4.63 4.63 0 0 0 .649 2.785 2.47 2.47 0 0 0 2.082.839 2.16 2.16 0 0 0 1.875-.969 4.6 4.6 0 0 0 .678-2.671 4.43 4.43 0 0 0-.678-2.651 2.23 2.23 0 0 0-1.915-.923Z\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2959\"})),U||(U=n.createElement(\"path\",{id:\"logo_small_svg__Path_2960\",d:\"M159.039 111.09a4 4 0 0 1-1.647-.333 3.1 3.1 0 0 1-1.252-1.023h-.1a12 12 0 0 1 .1 1.533v3.8h-1.4v-13.381h1.137l.194 1.264h.067a3.26 3.26 0 0 1 1.256-1.1 3.8 3.8 0 0 1 1.643-.337 3.41 3.41 0 0 1 2.836 1.256 6.68 6.68 0 0 1-.017 7.057 3.42 3.42 0 0 1-2.817 1.264m-.2-8.385a2.48 2.48 0 0 0-2.048.784 4.04 4.04 0 0 0-.649 2.494v.312a4.63 4.63 0 0 0 .649 2.785 2.47 2.47 0 0 0 2.082.839 2.16 2.16 0 0 0 1.875-.969 4.6 4.6 0 0 0 .678-2.671 4.43 4.43 0 0 0-.678-2.651 2.23 2.23 0 0 0-1.911-.923Z\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2960\"})),W||(W=n.createElement(\"path\",{id:\"logo_small_svg__Path_2961\",d:\"M173.612 106.3a5.1 5.1 0 0 1-1.137 3.527 4 4 0 0 1-3.143 1.268 4.17 4.17 0 0 1-2.2-.581 3.84 3.84 0 0 1-1.483-1.669 5.8 5.8 0 0 1-.522-2.545 5.1 5.1 0 0 1 1.129-3.518 4 4 0 0 1 3.135-1.26 3.9 3.9 0 0 1 3.08 1.29 5.07 5.07 0 0 1 1.141 3.488m-7.036 0a4.4 4.4 0 0 0 .708 2.7 2.81 2.81 0 0 0 4.167 0 4.37 4.37 0 0 0 .712-2.7 4.3 4.3 0 0 0-.712-2.675 2.5 2.5 0 0 0-2.1-.915 2.46 2.46 0 0 0-2.072.9 4.33 4.33 0 0 0-.7 2.69Z\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2961\"})),K||(K=n.createElement(\"path\",{id:\"logo_small_svg__Path_2962\",d:\"M180.525 101.517a5.5 5.5 0 0 1 1.1.1l-.194 1.3a4.8 4.8 0 0 0-1.011-.127 2.46 2.46 0 0 0-1.917.911 3.32 3.32 0 0 0-.8 2.267v4.955h-1.4v-9.236h1.154l.16 1.71h.068a4.05 4.05 0 0 1 1.238-1.39 2.8 2.8 0 0 1 1.6-.49Z\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2962\"})),V||(V=n.createElement(\"path\",{id:\"logo_small_svg__Path_2963\",d:\"M187.363 109.936a4.5 4.5 0 0 0 .716-.055 4 4 0 0 0 .548-.114v1.07a2.5 2.5 0 0 1-.67.181 5 5 0 0 1-.8.072q-2.68 0-2.68-2.823v-5.494h-1.323v-.673l1.323-.582.59-1.972h.809v2.141h2.68v1.087h-2.68v5.435a1.87 1.87 0 0 0 .4 1.281 1.38 1.38 0 0 0 1.087.446\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2963\"})),$||($=n.createElement(\"path\",{id:\"logo_small_svg__Path_2964\",d:\"M194.538 111.09a4.24 4.24 0 0 1-3.231-1.247 4.82 4.82 0 0 1-1.184-3.463 5.36 5.36 0 0 1 1.1-3.548 3.65 3.65 0 0 1 2.954-1.315 3.48 3.48 0 0 1 2.747 1.142 4.38 4.38 0 0 1 1.011 3.013v.885h-6.362a3.66 3.66 0 0 0 .822 2.469 2.84 2.84 0 0 0 2.2.843 7.4 7.4 0 0 0 2.949-.624v1.247a7.4 7.4 0 0 1-1.4.459 8 8 0 0 1-1.6.139Zm-.379-8.4a2.29 2.29 0 0 0-1.774.725 3.34 3.34 0 0 0-.779 2.006h4.828a3.07 3.07 0 0 0-.59-2.027 2.08 2.08 0 0 0-1.685-.706Z\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2964\"})),H||(H=n.createElement(\"path\",{id:\"logo_small_svg__Path_2965\",d:\"M206.951 109.683h-.076a3.29 3.29 0 0 1-2.9 1.407 3.43 3.43 0 0 1-2.819-1.239 5.45 5.45 0 0 1-1.006-3.522 5.54 5.54 0 0 1 1.011-3.548 3.4 3.4 0 0 1 2.814-1.264 3.36 3.36 0 0 1 2.883 1.365h.109l-.059-.665-.034-.649v-3.759h1.4v13.113h-1.138Zm-2.8.236a2.55 2.55 0 0 0 2.078-.779 3.95 3.95 0 0 0 .644-2.516v-.3a4.64 4.64 0 0 0-.653-2.8 2.48 2.48 0 0 0-2.086-.839 2.14 2.14 0 0 0-1.883.957 4.76 4.76 0 0 0-.653 2.7 4.55 4.55 0 0 0 .649 2.671 2.2 2.2 0 0 0 1.906.906Z\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2965\"})),Y||(Y=n.createElement(\"path\",{id:\"logo_small_svg__Path_2966\",d:\"M220.712 101.534a3.44 3.44 0 0 1 2.827 1.243 6.65 6.65 0 0 1-.009 7.053 3.42 3.42 0 0 1-2.818 1.26 4 4 0 0 1-1.648-.333 3.1 3.1 0 0 1-1.251-1.023h-.1l-.295 1.188h-1V97.809h1.4V101q0 1.069-.068 1.921h.068a3.32 3.32 0 0 1 2.894-1.387m-.2 1.171a2.44 2.44 0 0 0-2.064.822 6.34 6.34 0 0 0 .017 5.553 2.46 2.46 0 0 0 2.081.839 2.16 2.16 0 0 0 1.922-.94 4.83 4.83 0 0 0 .632-2.7 4.64 4.64 0 0 0-.632-2.689 2.24 2.24 0 0 0-1.959-.885Z\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2966\"})),Z||(Z=n.createElement(\"path\",{id:\"logo_small_svg__Path_2967\",d:\"M225.758 101.686h1.5l2.023 5.267a20 20 0 0 1 .826 2.6h.067q.109-.431.459-1.471t2.288-6.4h1.5l-3.969 10.518a5.25 5.25 0 0 1-1.378 2.212 2.93 2.93 0 0 1-1.934.653 5.7 5.7 0 0 1-1.264-.143V113.8a5 5 0 0 0 1.037.1 2.136 2.136 0 0 0 2.056-1.618l.514-1.314Z\",className:\"logo_small_svg__cls-2\",\"data-name\":\"Path 2967\"}))))),components_Logo=()=>n.createElement(logo_small,{height:\"40\"}),top_bar=()=>({components:{Topbar:u,Logo:components_Logo}});function isNothing(e){return null==e}var J={isNothing,isObject:function js_yaml_isObject(e){return\"object\"==typeof e&&null!==e},toArray:function toArray(e){return Array.isArray(e)?e:isNothing(e)?[]:[e]},repeat:function repeat(e,t){var r,n=\"\";for(r=0;rs&&(t=n-s+(o=\" ... \").length),r-n>s&&(r=n+s-(a=\" ...\").length),{str:o+e.slice(t,r).replace(/\\t/g,\"→\")+a,pos:n-t+o.length}}function padStart(e,t){return J.repeat(\" \",t-e.length)+e}var te=function makeSnippet(e,t){if(t=Object.create(t||null),!e.buffer)return null;t.maxLength||(t.maxLength=79),\"number\"!=typeof t.indent&&(t.indent=1),\"number\"!=typeof t.linesBefore&&(t.linesBefore=3),\"number\"!=typeof t.linesAfter&&(t.linesAfter=2);for(var r,n=/\\r?\\n|\\r|\\0/g,i=[0],o=[],a=-1;r=n.exec(e.buffer);)o.push(r.index),i.push(r.index+r[0].length),e.position<=r.index&&a<0&&(a=i.length-2);a<0&&(a=i.length-1);var s,u,c=\"\",f=Math.min(e.line+t.linesAfter,o.length).toString().length,l=t.maxLength-(t.indent+f+3);for(s=1;s<=t.linesBefore&&!(a-s<0);s++)u=getLine(e.buffer,i[a-s],o[a-s],e.position-(i[a]-i[a-s]),l),c=J.repeat(\" \",t.indent)+padStart((e.line-s+1).toString(),f)+\" | \"+u.str+\"\\n\"+c;for(u=getLine(e.buffer,i[a],o[a],e.position,l),c+=J.repeat(\" \",t.indent)+padStart((e.line+1).toString(),f)+\" | \"+u.str+\"\\n\",c+=J.repeat(\"-\",t.indent+f+3+u.pos)+\"^\\n\",s=1;s<=t.linesAfter&&!(a+s>=o.length);s++)u=getLine(e.buffer,i[a+s],o[a+s],e.position-(i[a]-i[a+s]),l),c+=J.repeat(\" \",t.indent)+padStart((e.line+s+1).toString(),f)+\" | \"+u.str+\"\\n\";return c.replace(/\\n$/,\"\")},re=[\"kind\",\"multi\",\"resolve\",\"construct\",\"instanceOf\",\"predicate\",\"represent\",\"representName\",\"defaultStyle\",\"styleAliases\"],ne=[\"scalar\",\"sequence\",\"mapping\"];var ie=function Type$1(e,t){if(t=t||{},Object.keys(t).forEach((function(t){if(-1===re.indexOf(t))throw new ee('Unknown option \"'+t+'\" is met in definition of \"'+e+'\" YAML type.')})),this.options=t,this.tag=e,this.kind=t.kind||null,this.resolve=t.resolve||function(){return!0},this.construct=t.construct||function(e){return e},this.instanceOf=t.instanceOf||null,this.predicate=t.predicate||null,this.represent=t.represent||null,this.representName=t.representName||null,this.defaultStyle=t.defaultStyle||null,this.multi=t.multi||!1,this.styleAliases=function compileStyleAliases(e){var t={};return null!==e&&Object.keys(e).forEach((function(r){e[r].forEach((function(e){t[String(e)]=r}))})),t}(t.styleAliases||null),-1===ne.indexOf(this.kind))throw new ee('Unknown kind \"'+this.kind+'\" is specified for \"'+e+'\" YAML type.')};function compileList(e,t){var r=[];return e[t].forEach((function(e){var t=r.length;r.forEach((function(r,n){r.tag===e.tag&&r.kind===e.kind&&r.multi===e.multi&&(t=n)})),r[t]=e})),r}function Schema$1(e){return this.extend(e)}Schema$1.prototype.extend=function extend(e){var t=[],r=[];if(e instanceof ie)r.push(e);else if(Array.isArray(e))r=r.concat(e);else{if(!e||!Array.isArray(e.implicit)&&!Array.isArray(e.explicit))throw new ee(\"Schema.extend argument should be a Type, [ Type ], or a schema definition ({ implicit: [...], explicit: [...] })\");e.implicit&&(t=t.concat(e.implicit)),e.explicit&&(r=r.concat(e.explicit))}t.forEach((function(e){if(!(e instanceof ie))throw new ee(\"Specified list of YAML types (or a single Type object) contains a non-Type object.\");if(e.loadKind&&\"scalar\"!==e.loadKind)throw new ee(\"There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.\");if(e.multi)throw new ee(\"There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.\")})),r.forEach((function(e){if(!(e instanceof ie))throw new ee(\"Specified list of YAML types (or a single Type object) contains a non-Type object.\")}));var n=Object.create(Schema$1.prototype);return n.implicit=(this.implicit||[]).concat(t),n.explicit=(this.explicit||[]).concat(r),n.compiledImplicit=compileList(n,\"implicit\"),n.compiledExplicit=compileList(n,\"explicit\"),n.compiledTypeMap=function compileMap(){var e,t,r={scalar:{},sequence:{},mapping:{},fallback:{},multi:{scalar:[],sequence:[],mapping:[],fallback:[]}};function collectType(e){e.multi?(r.multi[e.kind].push(e),r.multi.fallback.push(e)):r[e.kind][e.tag]=r.fallback[e.tag]=e}for(e=0,t=arguments.length;e=0?\"0b\"+e.toString(2):\"-0b\"+e.toString(2).slice(1)},octal:function(e){return e>=0?\"0o\"+e.toString(8):\"-0o\"+e.toString(8).slice(1)},decimal:function(e){return e.toString(10)},hexadecimal:function(e){return e>=0?\"0x\"+e.toString(16).toUpperCase():\"-0x\"+e.toString(16).toUpperCase().slice(1)}},defaultStyle:\"decimal\",styleAliases:{binary:[2,\"bin\"],octal:[8,\"oct\"],decimal:[10,\"dec\"],hexadecimal:[16,\"hex\"]}}),pe=new RegExp(\"^(?:[-+]?(?:[0-9][0-9_]*)(?:\\\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\\\.(?:inf|Inf|INF)|\\\\.(?:nan|NaN|NAN))$\");var de=/^[-+]?[0-9]+e/;var _e=new ie(\"tag:yaml.org,2002:float\",{kind:\"scalar\",resolve:function resolveYamlFloat(e){return null!==e&&!(!pe.test(e)||\"_\"===e[e.length-1])},construct:function constructYamlFloat(e){var t,r;return r=\"-\"===(t=e.replace(/_/g,\"\").toLowerCase())[0]?-1:1,\"+-\".indexOf(t[0])>=0&&(t=t.slice(1)),\".inf\"===t?1===r?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:\".nan\"===t?NaN:r*parseFloat(t,10)},predicate:function isFloat(e){return\"[object Number]\"===Object.prototype.toString.call(e)&&(e%1!=0||J.isNegativeZero(e))},represent:function representYamlFloat(e,t){var r;if(isNaN(e))switch(t){case\"lowercase\":return\".nan\";case\"uppercase\":return\".NAN\";case\"camelcase\":return\".NaN\"}else if(Number.POSITIVE_INFINITY===e)switch(t){case\"lowercase\":return\".inf\";case\"uppercase\":return\".INF\";case\"camelcase\":return\".Inf\"}else if(Number.NEGATIVE_INFINITY===e)switch(t){case\"lowercase\":return\"-.inf\";case\"uppercase\":return\"-.INF\";case\"camelcase\":return\"-.Inf\"}else if(J.isNegativeZero(e))return\"-0.0\";return r=e.toString(10),de.test(r)?r.replace(\"e\",\".e\"):r},defaultStyle:\"lowercase\"}),ye=ce.extend({implicit:[fe,le,he,_e]}),me=ye,ge=new RegExp(\"^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$\"),ve=new RegExp(\"^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\\\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\\\.([0-9]*))?(?:[ \\\\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$\");var be=new ie(\"tag:yaml.org,2002:timestamp\",{kind:\"scalar\",resolve:function resolveYamlTimestamp(e){return null!==e&&(null!==ge.exec(e)||null!==ve.exec(e))},construct:function constructYamlTimestamp(e){var t,r,n,i,o,a,s,u,c=0,f=null;if(null===(t=ge.exec(e))&&(t=ve.exec(e)),null===t)throw new Error(\"Date resolve error\");if(r=+t[1],n=+t[2]-1,i=+t[3],!t[4])return new Date(Date.UTC(r,n,i));if(o=+t[4],a=+t[5],s=+t[6],t[7]){for(c=t[7].slice(0,3);c.length<3;)c+=\"0\";c=+c}return t[9]&&(f=6e4*(60*+t[10]+ +(t[11]||0)),\"-\"===t[9]&&(f=-f)),u=new Date(Date.UTC(r,n,i,o,a,s,c)),f&&u.setTime(u.getTime()-f),u},instanceOf:Date,represent:function representYamlTimestamp(e){return e.toISOString()}});var Se=new ie(\"tag:yaml.org,2002:merge\",{kind:\"scalar\",resolve:function resolveYamlMerge(e){return\"<<\"===e||null===e}}),we=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\\n\\r\";var Ie=new ie(\"tag:yaml.org,2002:binary\",{kind:\"scalar\",resolve:function resolveYamlBinary(e){if(null===e)return!1;var t,r,n=0,i=e.length,o=we;for(r=0;r64)){if(t<0)return!1;n+=6}return n%8==0},construct:function constructYamlBinary(e){var t,r,n=e.replace(/[\\r\\n=]/g,\"\"),i=n.length,o=we,a=0,s=[];for(t=0;t>16&255),s.push(a>>8&255),s.push(255&a)),a=a<<6|o.indexOf(n.charAt(t));return 0===(r=i%4*6)?(s.push(a>>16&255),s.push(a>>8&255),s.push(255&a)):18===r?(s.push(a>>10&255),s.push(a>>2&255)):12===r&&s.push(a>>4&255),new Uint8Array(s)},predicate:function isBinary(e){return\"[object Uint8Array]\"===Object.prototype.toString.call(e)},represent:function representYamlBinary(e){var t,r,n=\"\",i=0,o=e.length,a=we;for(t=0;t>18&63],n+=a[i>>12&63],n+=a[i>>6&63],n+=a[63&i]),i=(i<<8)+e[t];return 0===(r=o%3)?(n+=a[i>>18&63],n+=a[i>>12&63],n+=a[i>>6&63],n+=a[63&i]):2===r?(n+=a[i>>10&63],n+=a[i>>4&63],n+=a[i<<2&63],n+=a[64]):1===r&&(n+=a[i>>2&63],n+=a[i<<4&63],n+=a[64],n+=a[64]),n}}),xe=Object.prototype.hasOwnProperty,Ee=Object.prototype.toString;var Oe=new ie(\"tag:yaml.org,2002:omap\",{kind:\"sequence\",resolve:function resolveYamlOmap(e){if(null===e)return!0;var t,r,n,i,o,a=[],s=e;for(t=0,r=s.length;t>10),56320+(e-65536&1023))}for(var Ve=new Array(256),$e=new Array(256),He=0;He<256;He++)Ve[He]=simpleEscapeSequence(He)?1:0,$e[He]=simpleEscapeSequence(He);function State$1(e,t){this.input=e,this.filename=t.filename||null,this.schema=t.schema||Me,this.onWarning=t.onWarning||null,this.legacy=t.legacy||!1,this.json=t.json||!1,this.listener=t.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=e.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.firstTabInLine=-1,this.documents=[]}function generateError(e,t){var r={name:e.filename,buffer:e.input.slice(0,-1),position:e.position,line:e.line,column:e.position-e.lineStart};return r.snippet=te(r),new ee(t,r)}function throwError(e,t){throw generateError(e,t)}function throwWarning(e,t){e.onWarning&&e.onWarning.call(null,generateError(e,t))}var Ye={YAML:function handleYamlDirective(e,t,r){var n,i,o;null!==e.version&&throwError(e,\"duplication of %YAML directive\"),1!==r.length&&throwError(e,\"YAML directive accepts exactly one argument\"),null===(n=/^([0-9]+)\\.([0-9]+)$/.exec(r[0]))&&throwError(e,\"ill-formed argument of the YAML directive\"),i=parseInt(n[1],10),o=parseInt(n[2],10),1!==i&&throwError(e,\"unacceptable YAML version of the document\"),e.version=r[0],e.checkLineBreaks=o<2,1!==o&&2!==o&&throwWarning(e,\"unsupported YAML version of the document\")},TAG:function handleTagDirective(e,t,r){var n,i;2!==r.length&&throwError(e,\"TAG directive accepts exactly two arguments\"),n=r[0],i=r[1],We.test(n)||throwError(e,\"ill-formed tag handle (first argument) of the TAG directive\"),qe.call(e.tagMap,n)&&throwError(e,'there is a previously declared suffix for \"'+n+'\" tag handle'),Ke.test(i)||throwError(e,\"ill-formed tag prefix (second argument) of the TAG directive\");try{i=decodeURIComponent(i)}catch(t){throwError(e,\"tag prefix is malformed: \"+i)}e.tagMap[n]=i}};function captureSegment(e,t,r,n){var i,o,a,s;if(t1&&(e.result+=J.repeat(\"\\n\",t-1))}function readBlockSequence(e,t){var r,n,i=e.tag,o=e.anchor,a=[],s=!1;if(-1!==e.firstTabInLine)return!1;for(null!==e.anchor&&(e.anchorMap[e.anchor]=a),n=e.input.charCodeAt(e.position);0!==n&&(-1!==e.firstTabInLine&&(e.position=e.firstTabInLine,throwError(e,\"tab characters must not be used in indentation\")),45===n)&&is_WS_OR_EOL(e.input.charCodeAt(e.position+1));)if(s=!0,e.position++,skipSeparationSpace(e,!0,-1)&&e.lineIndent<=t)a.push(null),n=e.input.charCodeAt(e.position);else if(r=e.line,composeNode(e,t,je,!1,!0),a.push(e.result),skipSeparationSpace(e,!0,-1),n=e.input.charCodeAt(e.position),(e.line===r||e.lineIndent>t)&&0!==n)throwError(e,\"bad indentation of a sequence entry\");else if(e.lineIndentt?d=1:e.lineIndent===t?d=0:e.lineIndentt?d=1:e.lineIndent===t?d=0:e.lineIndentt)&&(m&&(a=e.line,s=e.lineStart,u=e.position),composeNode(e,t,Te,!0,i)&&(m?_=e.result:y=e.result),m||(storeMappingPair(e,h,p,d,_,y,a,s,u),d=_=y=null),skipSeparationSpace(e,!0,-1),c=e.input.charCodeAt(e.position)),(e.line===o||e.lineIndent>t)&&0!==c)throwError(e,\"bad indentation of a mapping entry\");else if(e.lineIndent=0))break;0===i?throwError(e,\"bad explicit indentation width of a block scalar; it cannot be less than one\"):c?throwError(e,\"repeat of an indentation width identifier\"):(f=t+i-1,c=!0)}if(is_WHITE_SPACE(o)){do{o=e.input.charCodeAt(++e.position)}while(is_WHITE_SPACE(o));if(35===o)do{o=e.input.charCodeAt(++e.position)}while(!is_EOL(o)&&0!==o)}for(;0!==o;){for(readLineBreak(e),e.lineIndent=0,o=e.input.charCodeAt(e.position);(!c||e.lineIndentf&&(f=e.lineIndent),is_EOL(o))l++;else{if(e.lineIndent0){for(i=a,o=0;i>0;i--)(a=fromHexCode(s=e.input.charCodeAt(++e.position)))>=0?o=(o<<4)+a:throwError(e,\"expected hexadecimal character\");e.result+=charFromCodepoint(o),e.position++}else throwError(e,\"unknown escape sequence\");r=n=e.position}else is_EOL(s)?(captureSegment(e,r,n,!0),writeFoldedLines(e,skipSeparationSpace(e,!1,t)),r=n=e.position):e.position===e.lineStart&&testDocumentSeparator(e)?throwError(e,\"unexpected end of the document within a double quoted scalar\"):(e.position++,n=e.position)}throwError(e,\"unexpected end of the stream within a double quoted scalar\")}(e,h)?y=!0:!function readAlias(e){var t,r,n;if(42!==(n=e.input.charCodeAt(e.position)))return!1;for(n=e.input.charCodeAt(++e.position),t=e.position;0!==n&&!is_WS_OR_EOL(n)&&!is_FLOW_INDICATOR(n);)n=e.input.charCodeAt(++e.position);return e.position===t&&throwError(e,\"name of an alias node must contain at least one character\"),r=e.input.slice(t,e.position),qe.call(e.anchorMap,r)||throwError(e,'unidentified alias \"'+r+'\"'),e.result=e.anchorMap[r],skipSeparationSpace(e,!0,-1),!0}(e)?function readPlainScalar(e,t,r){var n,i,o,a,s,u,c,f,l=e.kind,h=e.result;if(is_WS_OR_EOL(f=e.input.charCodeAt(e.position))||is_FLOW_INDICATOR(f)||35===f||38===f||42===f||33===f||124===f||62===f||39===f||34===f||37===f||64===f||96===f)return!1;if((63===f||45===f)&&(is_WS_OR_EOL(n=e.input.charCodeAt(e.position+1))||r&&is_FLOW_INDICATOR(n)))return!1;for(e.kind=\"scalar\",e.result=\"\",i=o=e.position,a=!1;0!==f;){if(58===f){if(is_WS_OR_EOL(n=e.input.charCodeAt(e.position+1))||r&&is_FLOW_INDICATOR(n))break}else if(35===f){if(is_WS_OR_EOL(e.input.charCodeAt(e.position-1)))break}else{if(e.position===e.lineStart&&testDocumentSeparator(e)||r&&is_FLOW_INDICATOR(f))break;if(is_EOL(f)){if(s=e.line,u=e.lineStart,c=e.lineIndent,skipSeparationSpace(e,!1,-1),e.lineIndent>=t){a=!0,f=e.input.charCodeAt(e.position);continue}e.position=o,e.line=s,e.lineStart=u,e.lineIndent=c;break}}a&&(captureSegment(e,i,o,!1),writeFoldedLines(e,e.line-s),i=o=e.position,a=!1),is_WHITE_SPACE(f)||(o=e.position+1),f=e.input.charCodeAt(++e.position)}return captureSegment(e,i,o,!1),!!e.result||(e.kind=l,e.result=h,!1)}(e,h,Le===r)&&(y=!0,null===e.tag&&(e.tag=\"?\")):(y=!0,null===e.tag&&null===e.anchor||throwError(e,\"alias node should not have any properties\")),null!==e.anchor&&(e.anchorMap[e.anchor]=e.result)):0===d&&(y=s&&readBlockSequence(e,p))),null===e.tag)null!==e.anchor&&(e.anchorMap[e.anchor]=e.result);else if(\"?\"===e.tag){for(null!==e.result&&\"scalar\"!==e.kind&&throwError(e,'unacceptable node kind for ! tag; it should be \"scalar\", not \"'+e.kind+'\"'),u=0,c=e.implicitTypes.length;u\"),null!==e.result&&l.kind!==e.kind&&throwError(e,\"unacceptable node kind for !<\"+e.tag+'> tag; it should be \"'+l.kind+'\", not \"'+e.kind+'\"'),l.resolve(e.result,e.tag)?(e.result=l.construct(e.result,e.tag),null!==e.anchor&&(e.anchorMap[e.anchor]=e.result)):throwError(e,\"cannot resolve a node with !<\"+e.tag+\"> explicit tag\")}return null!==e.listener&&e.listener(\"close\",e),null!==e.tag||null!==e.anchor||y}function readDocument(e){var t,r,n,i,o=e.position,a=!1;for(e.version=null,e.checkLineBreaks=e.legacy,e.tagMap=Object.create(null),e.anchorMap=Object.create(null);0!==(i=e.input.charCodeAt(e.position))&&(skipSeparationSpace(e,!0,-1),i=e.input.charCodeAt(e.position),!(e.lineIndent>0||37!==i));){for(a=!0,i=e.input.charCodeAt(++e.position),t=e.position;0!==i&&!is_WS_OR_EOL(i);)i=e.input.charCodeAt(++e.position);for(n=[],(r=e.input.slice(t,e.position)).length<1&&throwError(e,\"directive name must not be less than one character in length\");0!==i;){for(;is_WHITE_SPACE(i);)i=e.input.charCodeAt(++e.position);if(35===i){do{i=e.input.charCodeAt(++e.position)}while(0!==i&&!is_EOL(i));break}if(is_EOL(i))break;for(t=e.position;0!==i&&!is_WS_OR_EOL(i);)i=e.input.charCodeAt(++e.position);n.push(e.input.slice(t,e.position))}0!==i&&readLineBreak(e),qe.call(Ye,r)?Ye[r](e,r,n):throwWarning(e,'unknown document directive \"'+r+'\"')}skipSeparationSpace(e,!0,-1),0===e.lineIndent&&45===e.input.charCodeAt(e.position)&&45===e.input.charCodeAt(e.position+1)&&45===e.input.charCodeAt(e.position+2)?(e.position+=3,skipSeparationSpace(e,!0,-1)):a&&throwError(e,\"directives end mark is expected\"),composeNode(e,e.lineIndent-1,Te,!1,!0),skipSeparationSpace(e,!0,-1),e.checkLineBreaks&&De.test(e.input.slice(o,e.position))&&throwWarning(e,\"non-ASCII line breaks are interpreted as content\"),e.documents.push(e.result),e.position===e.lineStart&&testDocumentSeparator(e)?46===e.input.charCodeAt(e.position)&&(e.position+=3,skipSeparationSpace(e,!0,-1)):e.position=55296&&n<=56319&&t+1=56320&&r<=57343?1024*(n-55296)+r-56320+65536:n}function needIndentIndicator(e){return/^\\n* /.test(e)}var At=1,Ct=2,Mt=3,qt=4,Lt=5;function chooseScalarStyle(e,t,r,n,i,o,a,s){var u,c=0,f=null,l=!1,h=!1,p=-1!==n,d=-1,_=function isPlainSafeFirst(e){return isPrintable(e)&&e!==Qe&&!isWhitespace(e)&&e!==ht&&e!==yt&&e!==pt&&e!==lt&&e!==gt&&e!==vt&&e!==St&&e!==It&&e!==ot&&e!==st&&e!==ct&&e!==nt&&e!==wt&&e!==dt&&e!==_t&&e!==ut&&e!==it&&e!==at&&e!==mt&&e!==bt}(codePointAt(e,0))&&function isPlainSafeLast(e){return!isWhitespace(e)&&e!==pt}(codePointAt(e,e.length-1));if(t||a)for(u=0;u=65536?u+=2:u++){if(!isPrintable(c=codePointAt(e,u)))return Lt;_=_&&isPlainSafe(c,f,s),f=c}else{for(u=0;u=65536?u+=2:u++){if((c=codePointAt(e,u))===et)l=!0,p&&(h=h||u-d-1>n&&\" \"!==e[d+1],d=u);else if(!isPrintable(c))return Lt;_=_&&isPlainSafe(c,f,s),f=c}h=h||p&&u-d-1>n&&\" \"!==e[d+1]}return l||h?r>9&&needIndentIndicator(e)?Lt:a?o===kt?Lt:Ct:h?qt:Mt:!_||a||i(e)?o===kt?Lt:Ct:At}function writeScalar(e,t,r,n,i){e.dump=function(){if(0===t.length)return e.quotingType===kt?'\"\"':\"''\";if(!e.noCompatMode&&(-1!==Et.indexOf(t)||Ot.test(t)))return e.quotingType===kt?'\"'+t+'\"':\"'\"+t+\"'\";var o=e.indent*Math.max(1,r),a=-1===e.lineWidth?-1:Math.max(Math.min(e.lineWidth,40),e.lineWidth-o),s=n||e.flowLevel>-1&&r>=e.flowLevel;switch(chooseScalarStyle(t,s,e.indent,a,(function testAmbiguity(t){return function testImplicitResolving(e,t){var r,n;for(r=0,n=e.implicitTypes.length;r\"+blockHeader(t,e.indent)+dropEndingNewline(indentString(function foldString(e,t){var r,n,i=/(\\n+)([^\\n]*)/g,o=(s=e.indexOf(\"\\n\"),s=-1!==s?s:e.length,i.lastIndex=s,foldLine(e.slice(0,s),t)),a=\"\\n\"===e[0]||\" \"===e[0];var s;for(;n=i.exec(e);){var u=n[1],c=n[2];r=\" \"===c[0],o+=u+(a||r||\"\"===c?\"\":\"\\n\")+foldLine(c,t),a=r}return o}(t,a),o));case Lt:return'\"'+function escapeString(e){for(var t,r=\"\",n=0,i=0;i=65536?i+=2:i++)n=codePointAt(e,i),!(t=xt[n])&&isPrintable(n)?(r+=e[i],n>=65536&&(r+=e[i+1])):r+=t||encodeHex(n);return r}(t)+'\"';default:throw new ee(\"impossible error: invalid scalar style\")}}()}function blockHeader(e,t){var r=needIndentIndicator(e)?String(t):\"\",n=\"\\n\"===e[e.length-1];return r+(n&&(\"\\n\"===e[e.length-2]||\"\\n\"===e)?\"+\":n?\"\":\"-\")+\"\\n\"}function dropEndingNewline(e){return\"\\n\"===e[e.length-1]?e.slice(0,-1):e}function foldLine(e,t){if(\"\"===e||\" \"===e[0])return e;for(var r,n,i=/ [^ ]/g,o=0,a=0,s=0,u=\"\";r=i.exec(e);)(s=r.index)-o>t&&(n=a>o?a:s,u+=\"\\n\"+e.slice(o,n),o=n+1),a=s;return u+=\"\\n\",e.length-o>t&&a>o?u+=e.slice(o,a)+\"\\n\"+e.slice(a+1):u+=e.slice(o),u.slice(1)}function writeBlockSequence(e,t,r,n){var i,o,a,s=\"\",u=e.tag;for(i=0,o=r.length;i tag resolver accepts not \"'+u+'\" style');n=s.represent[u](t,u)}e.dump=n}return!0}return!1}function writeNode(e,t,r,n,i,o,a){e.tag=null,e.dump=r,detectType(e,r,!1)||detectType(e,r,!0);var s,u=Ge.call(e.dump),c=n;n&&(n=e.flowLevel<0||e.flowLevel>t);var f,l,h=\"[object Object]\"===u||\"[object Array]\"===u;if(h&&(l=-1!==(f=e.duplicates.indexOf(r))),(null!==e.tag&&\"?\"!==e.tag||l||2!==e.indent&&t>0)&&(i=!1),l&&e.usedDuplicates[f])e.dump=\"*ref_\"+f;else{if(h&&l&&!e.usedDuplicates[f]&&(e.usedDuplicates[f]=!0),\"[object Object]\"===u)n&&0!==Object.keys(e.dump).length?(!function writeBlockMapping(e,t,r,n){var i,o,a,s,u,c,f=\"\",l=e.tag,h=Object.keys(r);if(!0===e.sortKeys)h.sort();else if(\"function\"==typeof e.sortKeys)h.sort(e.sortKeys);else if(e.sortKeys)throw new ee(\"sortKeys must be a boolean or a function\");for(i=0,o=h.length;i1024)&&(e.dump&&et===e.dump.charCodeAt(0)?c+=\"?\":c+=\"? \"),c+=e.dump,u&&(c+=generateNextLine(e,t)),writeNode(e,t+1,s,!0,u)&&(e.dump&&et===e.dump.charCodeAt(0)?c+=\":\":c+=\": \",f+=c+=e.dump));e.tag=l,e.dump=f||\"{}\"}(e,t,e.dump,i),l&&(e.dump=\"&ref_\"+f+e.dump)):(!function writeFlowMapping(e,t,r){var n,i,o,a,s,u=\"\",c=e.tag,f=Object.keys(r);for(n=0,i=f.length;n1024&&(s+=\"? \"),s+=e.dump+(e.condenseFlow?'\"':\"\")+\":\"+(e.condenseFlow?\"\":\" \"),writeNode(e,t,a,!1,!1)&&(u+=s+=e.dump));e.tag=c,e.dump=\"{\"+u+\"}\"}(e,t,e.dump),l&&(e.dump=\"&ref_\"+f+\" \"+e.dump));else if(\"[object Array]\"===u)n&&0!==e.dump.length?(e.noArrayIndent&&!a&&t>0?writeBlockSequence(e,t-1,e.dump,i):writeBlockSequence(e,t,e.dump,i),l&&(e.dump=\"&ref_\"+f+e.dump)):(!function writeFlowSequence(e,t,r){var n,i,o,a=\"\",s=e.tag;for(n=0,i=r.length;n\",e.dump=s+\" \"+e.dump)}return!0}function getDuplicateReferences(e,t){var r,n,i=[],o=[];for(inspectNode(e,i,o),r=0,n=o.length;r()=>{},downloadConfig=e=>t=>{const{fn:{fetch:r}}=t;return r(e)},getConfigByUrl=(e,t)=>r=>{const{specActions:n,configsActions:i}=r;if(e)return i.downloadConfig(e).then(next,next);function next(i){i instanceof Error||i.status>=400?(n.updateLoadingStatus(\"failedConfig\"),n.updateLoadingStatus(\"failedConfig\"),n.updateUrl(\"\"),console.error(i.statusText+\" \"+e.url),t(null)):t(((e,t)=>{try{return Nt.load(e)}catch(e){return t&&t.errActions.newThrownErr(new Error(e)),{}}})(i.text,r))}},get=(e,t)=>e.getIn(Array.isArray(t)?t:[t]),Rt={[jt]:(e,t)=>e.merge((0,o.fromJS)(t.payload)),[Tt]:(e,t)=>{const r=t.payload,n=e.get(r);return e.set(r,!n)}};var zt=__webpack_require__(7248),Pt=__webpack_require__.n(zt),Ft=__webpack_require__(7666),Dt=__webpack_require__.n(Ft);const Ut=console.error,withErrorBoundary=e=>t=>{const{getComponent:r,fn:i}=e(),o=r(\"ErrorBoundary\"),a=i.getDisplayName(t);class WithErrorBoundary extends n.Component{render(){return n.createElement(o,{targetName:a,getComponent:r,fn:i},n.createElement(t,Dt()({},this.props,this.context)))}}var s;return WithErrorBoundary.displayName=`WithErrorBoundary(${a})`,(s=t).prototype&&s.prototype.isReactComponent&&(WithErrorBoundary.prototype.mapStateToProps=t.prototype.mapStateToProps),WithErrorBoundary},fallback=({name:e})=>n.createElement(\"div\",{className:\"fallback\"},\"😱 \",n.createElement(\"i\",null,\"Could not render \",\"t\"===e?\"this component\":e,\", see the console.\"));class ErrorBoundary extends n.Component{static defaultProps={targetName:\"this component\",getComponent:()=>fallback,fn:{componentDidCatch:Ut},children:null};static getDerivedStateFromError(e){return{hasError:!0,error:e}}constructor(...e){super(...e),this.state={hasError:!1,error:null}}componentDidCatch(e,t){this.props.fn.componentDidCatch(e,t)}render(){const{getComponent:e,targetName:t,children:r}=this.props;if(this.state.hasError){const r=e(\"Fallback\");return n.createElement(r,{name:t})}return r}}const Wt=ErrorBoundary,Kt=[top_bar,function configsPlugin(){return{statePlugins:{configs:{reducers:Rt,actions:e,selectors:t}}}},stadalone_layout,(({componentList:e=[],fullOverride:t=!1}={})=>({getSystem:r})=>{const n=t?e:[\"App\",\"BaseLayout\",\"VersionPragmaFilter\",\"InfoContainer\",\"ServersContainer\",\"SchemesContainer\",\"AuthorizeBtnContainer\",\"FilterContainer\",\"Operations\",\"OperationContainer\",\"parameters\",\"responses\",\"OperationServers\",\"Models\",\"ModelWrapper\",...e],i=Pt()(n,Array(n.length).fill(((e,{fn:t})=>t.withErrorBoundary(e))));return{fn:{componentDidCatch:Ut,withErrorBoundary:withErrorBoundary(r)},components:{ErrorBoundary:Wt,Fallback:fallback},wrapComponents:i}})({fullOverride:!0,componentList:[\"Topbar\",\"StandaloneLayout\",\"onlineValidatorBadge\"]})]})(),r=r.default})()));" + +/** @internal */ +export const css = ".swagger-ui{color:#3b4151;font-family:sans-serif/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */}.swagger-ui html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}.swagger-ui body{margin:0}.swagger-ui article,.swagger-ui aside,.swagger-ui footer,.swagger-ui header,.swagger-ui nav,.swagger-ui section{display:block}.swagger-ui h1{font-size:2em;margin:.67em 0}.swagger-ui figcaption,.swagger-ui figure,.swagger-ui main{display:block}.swagger-ui figure{margin:1em 40px}.swagger-ui hr{box-sizing:content-box;height:0;overflow:visible}.swagger-ui pre{font-family:monospace,monospace;font-size:1em}.swagger-ui a{background-color:transparent;-webkit-text-decoration-skip:objects}.swagger-ui abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.swagger-ui b,.swagger-ui strong{font-weight:inherit;font-weight:bolder}.swagger-ui code,.swagger-ui kbd,.swagger-ui samp{font-family:monospace,monospace;font-size:1em}.swagger-ui dfn{font-style:italic}.swagger-ui mark{background-color:#ff0;color:#000}.swagger-ui small{font-size:80%}.swagger-ui sub,.swagger-ui sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}.swagger-ui sub{bottom:-.25em}.swagger-ui sup{top:-.5em}.swagger-ui audio,.swagger-ui video{display:inline-block}.swagger-ui audio:not([controls]){display:none;height:0}.swagger-ui img{border-style:none}.swagger-ui svg:not(:root){overflow:hidden}.swagger-ui button,.swagger-ui input,.swagger-ui optgroup,.swagger-ui select,.swagger-ui textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}.swagger-ui button,.swagger-ui input{overflow:visible}.swagger-ui button,.swagger-ui select{text-transform:none}.swagger-ui [type=reset],.swagger-ui [type=submit],.swagger-ui button,.swagger-ui html [type=button]{-webkit-appearance:button}.swagger-ui [type=button]::-moz-focus-inner,.swagger-ui [type=reset]::-moz-focus-inner,.swagger-ui [type=submit]::-moz-focus-inner,.swagger-ui button::-moz-focus-inner{border-style:none;padding:0}.swagger-ui [type=button]:-moz-focusring,.swagger-ui [type=reset]:-moz-focusring,.swagger-ui [type=submit]:-moz-focusring,.swagger-ui button:-moz-focusring{outline:1px dotted ButtonText}.swagger-ui fieldset{padding:.35em .75em .625em}.swagger-ui legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}.swagger-ui progress{display:inline-block;vertical-align:baseline}.swagger-ui textarea{overflow:auto}.swagger-ui [type=checkbox],.swagger-ui [type=radio]{box-sizing:border-box;padding:0}.swagger-ui [type=number]::-webkit-inner-spin-button,.swagger-ui [type=number]::-webkit-outer-spin-button{height:auto}.swagger-ui [type=search]{-webkit-appearance:textfield;outline-offset:-2px}.swagger-ui [type=search]::-webkit-search-cancel-button,.swagger-ui [type=search]::-webkit-search-decoration{-webkit-appearance:none}.swagger-ui ::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}.swagger-ui details,.swagger-ui menu{display:block}.swagger-ui summary{display:list-item}.swagger-ui canvas{display:inline-block}.swagger-ui [hidden],.swagger-ui template{display:none}.swagger-ui .debug *{outline:1px solid gold}.swagger-ui .debug-white *{outline:1px solid #fff}.swagger-ui .debug-black *{outline:1px solid #000}.swagger-ui .debug-grid{background:transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTRDOTY4N0U2N0VFMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTRDOTY4N0Q2N0VFMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3NjY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3NzY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PsBS+GMAAAAjSURBVHjaYvz//z8DLsD4gcGXiYEAGBIKGBne//fFpwAgwAB98AaF2pjlUQAAAABJRU5ErkJggg==) repeat 0 0}.swagger-ui .debug-grid-16{background:transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODYyRjhERDU2N0YyMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODYyRjhERDQ2N0YyMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3QTY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3QjY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PvCS01IAAABMSURBVHjaYmR4/5+BFPBfAMFm/MBgx8RAGWCn1AAmSg34Q6kBDKMGMDCwICeMIemF/5QawEipAWwUhwEjMDvbAWlWkvVBwu8vQIABAEwBCph8U6c0AAAAAElFTkSuQmCC) repeat 0 0}.swagger-ui .debug-grid-8-solid{background:#fff url(data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAAAAAD/4QMxaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzExMSA3OS4xNTgzMjUsIDIwMTUvMDkvMTAtMDE6MTA6MjAgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE1IChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkIxMjI0OTczNjdCMzExRTZCMkJDRTI0MDgxMDAyMTcxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkIxMjI0OTc0NjdCMzExRTZCMkJDRTI0MDgxMDAyMTcxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6QjEyMjQ5NzE2N0IzMTFFNkIyQkNFMjQwODEwMDIxNzEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6QjEyMjQ5NzI2N0IzMTFFNkIyQkNFMjQwODEwMDIxNzEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAAbGhopHSlBJiZBQi8vL0JHPz4+P0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHAR0pKTQmND8oKD9HPzU/R0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0f/wAARCAAIAAgDASIAAhEBAxEB/8QAWQABAQAAAAAAAAAAAAAAAAAAAAYBAQEAAAAAAAAAAAAAAAAAAAIEEAEBAAMBAAAAAAAAAAAAAAABADECA0ERAAEDBQAAAAAAAAAAAAAAAAARITFBUWESIv/aAAwDAQACEQMRAD8AoOnTV1QTD7JJshP3vSM3P//Z) repeat 0 0}.swagger-ui .debug-grid-16-solid{background:#fff url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NzY3MkJEN0U2N0M1MTFFNkIyQkNFMjQwODEwMDIxNzEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NzY3MkJEN0Y2N0M1MTFFNkIyQkNFMjQwODEwMDIxNzEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3QzY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3RDY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pve6J3kAAAAzSURBVHjaYvz//z8D0UDsMwMjSRoYP5Gq4SPNbRjVMEQ1fCRDg+in/6+J1AJUxsgAEGAA31BAJMS0GYEAAAAASUVORK5CYII=) repeat 0 0}.swagger-ui .border-box,.swagger-ui a,.swagger-ui article,.swagger-ui body,.swagger-ui code,.swagger-ui dd,.swagger-ui div,.swagger-ui dl,.swagger-ui dt,.swagger-ui fieldset,.swagger-ui footer,.swagger-ui form,.swagger-ui h1,.swagger-ui h2,.swagger-ui h3,.swagger-ui h4,.swagger-ui h5,.swagger-ui h6,.swagger-ui header,.swagger-ui html,.swagger-ui input[type=email],.swagger-ui input[type=number],.swagger-ui input[type=password],.swagger-ui input[type=tel],.swagger-ui input[type=text],.swagger-ui input[type=url],.swagger-ui legend,.swagger-ui li,.swagger-ui main,.swagger-ui ol,.swagger-ui p,.swagger-ui pre,.swagger-ui section,.swagger-ui table,.swagger-ui td,.swagger-ui textarea,.swagger-ui th,.swagger-ui tr,.swagger-ui ul{box-sizing:border-box}.swagger-ui .aspect-ratio{height:0;position:relative}.swagger-ui .aspect-ratio--16x9{padding-bottom:56.25%}.swagger-ui .aspect-ratio--9x16{padding-bottom:177.77%}.swagger-ui .aspect-ratio--4x3{padding-bottom:75%}.swagger-ui .aspect-ratio--3x4{padding-bottom:133.33%}.swagger-ui .aspect-ratio--6x4{padding-bottom:66.6%}.swagger-ui .aspect-ratio--4x6{padding-bottom:150%}.swagger-ui .aspect-ratio--8x5{padding-bottom:62.5%}.swagger-ui .aspect-ratio--5x8{padding-bottom:160%}.swagger-ui .aspect-ratio--7x5{padding-bottom:71.42%}.swagger-ui .aspect-ratio--5x7{padding-bottom:140%}.swagger-ui .aspect-ratio--1x1{padding-bottom:100%}.swagger-ui .aspect-ratio--object{bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:100}@media screen and (min-width:30em){.swagger-ui .aspect-ratio-ns{height:0;position:relative}.swagger-ui .aspect-ratio--16x9-ns{padding-bottom:56.25%}.swagger-ui .aspect-ratio--9x16-ns{padding-bottom:177.77%}.swagger-ui .aspect-ratio--4x3-ns{padding-bottom:75%}.swagger-ui .aspect-ratio--3x4-ns{padding-bottom:133.33%}.swagger-ui .aspect-ratio--6x4-ns{padding-bottom:66.6%}.swagger-ui .aspect-ratio--4x6-ns{padding-bottom:150%}.swagger-ui .aspect-ratio--8x5-ns{padding-bottom:62.5%}.swagger-ui .aspect-ratio--5x8-ns{padding-bottom:160%}.swagger-ui .aspect-ratio--7x5-ns{padding-bottom:71.42%}.swagger-ui .aspect-ratio--5x7-ns{padding-bottom:140%}.swagger-ui .aspect-ratio--1x1-ns{padding-bottom:100%}.swagger-ui .aspect-ratio--object-ns{bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:100}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .aspect-ratio-m{height:0;position:relative}.swagger-ui .aspect-ratio--16x9-m{padding-bottom:56.25%}.swagger-ui .aspect-ratio--9x16-m{padding-bottom:177.77%}.swagger-ui .aspect-ratio--4x3-m{padding-bottom:75%}.swagger-ui .aspect-ratio--3x4-m{padding-bottom:133.33%}.swagger-ui .aspect-ratio--6x4-m{padding-bottom:66.6%}.swagger-ui .aspect-ratio--4x6-m{padding-bottom:150%}.swagger-ui .aspect-ratio--8x5-m{padding-bottom:62.5%}.swagger-ui .aspect-ratio--5x8-m{padding-bottom:160%}.swagger-ui .aspect-ratio--7x5-m{padding-bottom:71.42%}.swagger-ui .aspect-ratio--5x7-m{padding-bottom:140%}.swagger-ui .aspect-ratio--1x1-m{padding-bottom:100%}.swagger-ui .aspect-ratio--object-m{bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:100}}@media screen and (min-width:60em){.swagger-ui .aspect-ratio-l{height:0;position:relative}.swagger-ui .aspect-ratio--16x9-l{padding-bottom:56.25%}.swagger-ui .aspect-ratio--9x16-l{padding-bottom:177.77%}.swagger-ui .aspect-ratio--4x3-l{padding-bottom:75%}.swagger-ui .aspect-ratio--3x4-l{padding-bottom:133.33%}.swagger-ui .aspect-ratio--6x4-l{padding-bottom:66.6%}.swagger-ui .aspect-ratio--4x6-l{padding-bottom:150%}.swagger-ui .aspect-ratio--8x5-l{padding-bottom:62.5%}.swagger-ui .aspect-ratio--5x8-l{padding-bottom:160%}.swagger-ui .aspect-ratio--7x5-l{padding-bottom:71.42%}.swagger-ui .aspect-ratio--5x7-l{padding-bottom:140%}.swagger-ui .aspect-ratio--1x1-l{padding-bottom:100%}.swagger-ui .aspect-ratio--object-l{bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:100}}.swagger-ui img{max-width:100%}.swagger-ui .cover{background-size:cover!important}.swagger-ui .contain{background-size:contain!important}@media screen and (min-width:30em){.swagger-ui .cover-ns{background-size:cover!important}.swagger-ui .contain-ns{background-size:contain!important}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .cover-m{background-size:cover!important}.swagger-ui .contain-m{background-size:contain!important}}@media screen and (min-width:60em){.swagger-ui .cover-l{background-size:cover!important}.swagger-ui .contain-l{background-size:contain!important}}.swagger-ui .bg-center{background-position:50%;background-repeat:no-repeat}.swagger-ui .bg-top{background-position:top;background-repeat:no-repeat}.swagger-ui .bg-right{background-position:100%;background-repeat:no-repeat}.swagger-ui .bg-bottom{background-position:bottom;background-repeat:no-repeat}.swagger-ui .bg-left{background-position:0;background-repeat:no-repeat}@media screen and (min-width:30em){.swagger-ui .bg-center-ns{background-position:50%;background-repeat:no-repeat}.swagger-ui .bg-top-ns{background-position:top;background-repeat:no-repeat}.swagger-ui .bg-right-ns{background-position:100%;background-repeat:no-repeat}.swagger-ui .bg-bottom-ns{background-position:bottom;background-repeat:no-repeat}.swagger-ui .bg-left-ns{background-position:0;background-repeat:no-repeat}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .bg-center-m{background-position:50%;background-repeat:no-repeat}.swagger-ui .bg-top-m{background-position:top;background-repeat:no-repeat}.swagger-ui .bg-right-m{background-position:100%;background-repeat:no-repeat}.swagger-ui .bg-bottom-m{background-position:bottom;background-repeat:no-repeat}.swagger-ui .bg-left-m{background-position:0;background-repeat:no-repeat}}@media screen and (min-width:60em){.swagger-ui .bg-center-l{background-position:50%;background-repeat:no-repeat}.swagger-ui .bg-top-l{background-position:top;background-repeat:no-repeat}.swagger-ui .bg-right-l{background-position:100%;background-repeat:no-repeat}.swagger-ui .bg-bottom-l{background-position:bottom;background-repeat:no-repeat}.swagger-ui .bg-left-l{background-position:0;background-repeat:no-repeat}}.swagger-ui .outline{outline:1px solid}.swagger-ui .outline-transparent{outline:1px solid transparent}.swagger-ui .outline-0{outline:0}@media screen and (min-width:30em){.swagger-ui .outline-ns{outline:1px solid}.swagger-ui .outline-transparent-ns{outline:1px solid transparent}.swagger-ui .outline-0-ns{outline:0}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .outline-m{outline:1px solid}.swagger-ui .outline-transparent-m{outline:1px solid transparent}.swagger-ui .outline-0-m{outline:0}}@media screen and (min-width:60em){.swagger-ui .outline-l{outline:1px solid}.swagger-ui .outline-transparent-l{outline:1px solid transparent}.swagger-ui .outline-0-l{outline:0}}.swagger-ui .ba{border-style:solid;border-width:1px}.swagger-ui .bt{border-top-style:solid;border-top-width:1px}.swagger-ui .br{border-right-style:solid;border-right-width:1px}.swagger-ui .bb{border-bottom-style:solid;border-bottom-width:1px}.swagger-ui .bl{border-left-style:solid;border-left-width:1px}.swagger-ui .bn{border-style:none;border-width:0}@media screen and (min-width:30em){.swagger-ui .ba-ns{border-style:solid;border-width:1px}.swagger-ui .bt-ns{border-top-style:solid;border-top-width:1px}.swagger-ui .br-ns{border-right-style:solid;border-right-width:1px}.swagger-ui .bb-ns{border-bottom-style:solid;border-bottom-width:1px}.swagger-ui .bl-ns{border-left-style:solid;border-left-width:1px}.swagger-ui .bn-ns{border-style:none;border-width:0}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .ba-m{border-style:solid;border-width:1px}.swagger-ui .bt-m{border-top-style:solid;border-top-width:1px}.swagger-ui .br-m{border-right-style:solid;border-right-width:1px}.swagger-ui .bb-m{border-bottom-style:solid;border-bottom-width:1px}.swagger-ui .bl-m{border-left-style:solid;border-left-width:1px}.swagger-ui .bn-m{border-style:none;border-width:0}}@media screen and (min-width:60em){.swagger-ui .ba-l{border-style:solid;border-width:1px}.swagger-ui .bt-l{border-top-style:solid;border-top-width:1px}.swagger-ui .br-l{border-right-style:solid;border-right-width:1px}.swagger-ui .bb-l{border-bottom-style:solid;border-bottom-width:1px}.swagger-ui .bl-l{border-left-style:solid;border-left-width:1px}.swagger-ui .bn-l{border-style:none;border-width:0}}.swagger-ui .b--black{border-color:#000}.swagger-ui .b--near-black{border-color:#111}.swagger-ui .b--dark-gray{border-color:#333}.swagger-ui .b--mid-gray{border-color:#555}.swagger-ui .b--gray{border-color:#777}.swagger-ui .b--silver{border-color:#999}.swagger-ui .b--light-silver{border-color:#aaa}.swagger-ui .b--moon-gray{border-color:#ccc}.swagger-ui .b--light-gray{border-color:#eee}.swagger-ui .b--near-white{border-color:#f4f4f4}.swagger-ui .b--white{border-color:#fff}.swagger-ui .b--white-90{border-color:hsla(0,0%,100%,.9)}.swagger-ui .b--white-80{border-color:hsla(0,0%,100%,.8)}.swagger-ui .b--white-70{border-color:hsla(0,0%,100%,.7)}.swagger-ui .b--white-60{border-color:hsla(0,0%,100%,.6)}.swagger-ui .b--white-50{border-color:hsla(0,0%,100%,.5)}.swagger-ui .b--white-40{border-color:hsla(0,0%,100%,.4)}.swagger-ui .b--white-30{border-color:hsla(0,0%,100%,.3)}.swagger-ui .b--white-20{border-color:hsla(0,0%,100%,.2)}.swagger-ui .b--white-10{border-color:hsla(0,0%,100%,.1)}.swagger-ui .b--white-05{border-color:hsla(0,0%,100%,.05)}.swagger-ui .b--white-025{border-color:hsla(0,0%,100%,.025)}.swagger-ui .b--white-0125{border-color:hsla(0,0%,100%,.013)}.swagger-ui .b--black-90{border-color:rgba(0,0,0,.9)}.swagger-ui .b--black-80{border-color:rgba(0,0,0,.8)}.swagger-ui .b--black-70{border-color:rgba(0,0,0,.7)}.swagger-ui .b--black-60{border-color:rgba(0,0,0,.6)}.swagger-ui .b--black-50{border-color:rgba(0,0,0,.5)}.swagger-ui .b--black-40{border-color:rgba(0,0,0,.4)}.swagger-ui .b--black-30{border-color:rgba(0,0,0,.3)}.swagger-ui .b--black-20{border-color:rgba(0,0,0,.2)}.swagger-ui .b--black-10{border-color:rgba(0,0,0,.1)}.swagger-ui .b--black-05{border-color:rgba(0,0,0,.05)}.swagger-ui .b--black-025{border-color:rgba(0,0,0,.025)}.swagger-ui .b--black-0125{border-color:rgba(0,0,0,.013)}.swagger-ui .b--dark-red{border-color:#e7040f}.swagger-ui .b--red{border-color:#ff4136}.swagger-ui .b--light-red{border-color:#ff725c}.swagger-ui .b--orange{border-color:#ff6300}.swagger-ui .b--gold{border-color:#ffb700}.swagger-ui .b--yellow{border-color:gold}.swagger-ui .b--light-yellow{border-color:#fbf1a9}.swagger-ui .b--purple{border-color:#5e2ca5}.swagger-ui .b--light-purple{border-color:#a463f2}.swagger-ui .b--dark-pink{border-color:#d5008f}.swagger-ui .b--hot-pink{border-color:#ff41b4}.swagger-ui .b--pink{border-color:#ff80cc}.swagger-ui .b--light-pink{border-color:#ffa3d7}.swagger-ui .b--dark-green{border-color:#137752}.swagger-ui .b--green{border-color:#19a974}.swagger-ui .b--light-green{border-color:#9eebcf}.swagger-ui .b--navy{border-color:#001b44}.swagger-ui .b--dark-blue{border-color:#00449e}.swagger-ui .b--blue{border-color:#357edd}.swagger-ui .b--light-blue{border-color:#96ccff}.swagger-ui .b--lightest-blue{border-color:#cdecff}.swagger-ui .b--washed-blue{border-color:#f6fffe}.swagger-ui .b--washed-green{border-color:#e8fdf5}.swagger-ui .b--washed-yellow{border-color:#fffceb}.swagger-ui .b--washed-red{border-color:#ffdfdf}.swagger-ui .b--transparent{border-color:transparent}.swagger-ui .b--inherit{border-color:inherit}.swagger-ui .br0{border-radius:0}.swagger-ui .br1{border-radius:.125rem}.swagger-ui .br2{border-radius:.25rem}.swagger-ui .br3{border-radius:.5rem}.swagger-ui .br4{border-radius:1rem}.swagger-ui .br-100{border-radius:100%}.swagger-ui .br-pill{border-radius:9999px}.swagger-ui .br--bottom{border-top-left-radius:0;border-top-right-radius:0}.swagger-ui .br--top{border-bottom-left-radius:0;border-bottom-right-radius:0}.swagger-ui .br--right{border-bottom-left-radius:0;border-top-left-radius:0}.swagger-ui .br--left{border-bottom-right-radius:0;border-top-right-radius:0}@media screen and (min-width:30em){.swagger-ui .br0-ns{border-radius:0}.swagger-ui .br1-ns{border-radius:.125rem}.swagger-ui .br2-ns{border-radius:.25rem}.swagger-ui .br3-ns{border-radius:.5rem}.swagger-ui .br4-ns{border-radius:1rem}.swagger-ui .br-100-ns{border-radius:100%}.swagger-ui .br-pill-ns{border-radius:9999px}.swagger-ui .br--bottom-ns{border-top-left-radius:0;border-top-right-radius:0}.swagger-ui .br--top-ns{border-bottom-left-radius:0;border-bottom-right-radius:0}.swagger-ui .br--right-ns{border-bottom-left-radius:0;border-top-left-radius:0}.swagger-ui .br--left-ns{border-bottom-right-radius:0;border-top-right-radius:0}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .br0-m{border-radius:0}.swagger-ui .br1-m{border-radius:.125rem}.swagger-ui .br2-m{border-radius:.25rem}.swagger-ui .br3-m{border-radius:.5rem}.swagger-ui .br4-m{border-radius:1rem}.swagger-ui .br-100-m{border-radius:100%}.swagger-ui .br-pill-m{border-radius:9999px}.swagger-ui .br--bottom-m{border-top-left-radius:0;border-top-right-radius:0}.swagger-ui .br--top-m{border-bottom-left-radius:0;border-bottom-right-radius:0}.swagger-ui .br--right-m{border-bottom-left-radius:0;border-top-left-radius:0}.swagger-ui .br--left-m{border-bottom-right-radius:0;border-top-right-radius:0}}@media screen and (min-width:60em){.swagger-ui .br0-l{border-radius:0}.swagger-ui .br1-l{border-radius:.125rem}.swagger-ui .br2-l{border-radius:.25rem}.swagger-ui .br3-l{border-radius:.5rem}.swagger-ui .br4-l{border-radius:1rem}.swagger-ui .br-100-l{border-radius:100%}.swagger-ui .br-pill-l{border-radius:9999px}.swagger-ui .br--bottom-l{border-top-left-radius:0;border-top-right-radius:0}.swagger-ui .br--top-l{border-bottom-left-radius:0;border-bottom-right-radius:0}.swagger-ui .br--right-l{border-bottom-left-radius:0;border-top-left-radius:0}.swagger-ui .br--left-l{border-bottom-right-radius:0;border-top-right-radius:0}}.swagger-ui .b--dotted{border-style:dotted}.swagger-ui .b--dashed{border-style:dashed}.swagger-ui .b--solid{border-style:solid}.swagger-ui .b--none{border-style:none}@media screen and (min-width:30em){.swagger-ui .b--dotted-ns{border-style:dotted}.swagger-ui .b--dashed-ns{border-style:dashed}.swagger-ui .b--solid-ns{border-style:solid}.swagger-ui .b--none-ns{border-style:none}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .b--dotted-m{border-style:dotted}.swagger-ui .b--dashed-m{border-style:dashed}.swagger-ui .b--solid-m{border-style:solid}.swagger-ui .b--none-m{border-style:none}}@media screen and (min-width:60em){.swagger-ui .b--dotted-l{border-style:dotted}.swagger-ui .b--dashed-l{border-style:dashed}.swagger-ui .b--solid-l{border-style:solid}.swagger-ui .b--none-l{border-style:none}}.swagger-ui .bw0{border-width:0}.swagger-ui .bw1{border-width:.125rem}.swagger-ui .bw2{border-width:.25rem}.swagger-ui .bw3{border-width:.5rem}.swagger-ui .bw4{border-width:1rem}.swagger-ui .bw5{border-width:2rem}.swagger-ui .bt-0{border-top-width:0}.swagger-ui .br-0{border-right-width:0}.swagger-ui .bb-0{border-bottom-width:0}.swagger-ui .bl-0{border-left-width:0}@media screen and (min-width:30em){.swagger-ui .bw0-ns{border-width:0}.swagger-ui .bw1-ns{border-width:.125rem}.swagger-ui .bw2-ns{border-width:.25rem}.swagger-ui .bw3-ns{border-width:.5rem}.swagger-ui .bw4-ns{border-width:1rem}.swagger-ui .bw5-ns{border-width:2rem}.swagger-ui .bt-0-ns{border-top-width:0}.swagger-ui .br-0-ns{border-right-width:0}.swagger-ui .bb-0-ns{border-bottom-width:0}.swagger-ui .bl-0-ns{border-left-width:0}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .bw0-m{border-width:0}.swagger-ui .bw1-m{border-width:.125rem}.swagger-ui .bw2-m{border-width:.25rem}.swagger-ui .bw3-m{border-width:.5rem}.swagger-ui .bw4-m{border-width:1rem}.swagger-ui .bw5-m{border-width:2rem}.swagger-ui .bt-0-m{border-top-width:0}.swagger-ui .br-0-m{border-right-width:0}.swagger-ui .bb-0-m{border-bottom-width:0}.swagger-ui .bl-0-m{border-left-width:0}}@media screen and (min-width:60em){.swagger-ui .bw0-l{border-width:0}.swagger-ui .bw1-l{border-width:.125rem}.swagger-ui .bw2-l{border-width:.25rem}.swagger-ui .bw3-l{border-width:.5rem}.swagger-ui .bw4-l{border-width:1rem}.swagger-ui .bw5-l{border-width:2rem}.swagger-ui .bt-0-l{border-top-width:0}.swagger-ui .br-0-l{border-right-width:0}.swagger-ui .bb-0-l{border-bottom-width:0}.swagger-ui .bl-0-l{border-left-width:0}}.swagger-ui .shadow-1{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-2{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-3{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-4{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.swagger-ui .shadow-5{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}@media screen and (min-width:30em){.swagger-ui .shadow-1-ns{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-2-ns{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-3-ns{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-4-ns{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.swagger-ui .shadow-5-ns{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .shadow-1-m{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-2-m{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-3-m{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-4-m{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.swagger-ui .shadow-5-m{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}}@media screen and (min-width:60em){.swagger-ui .shadow-1-l{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-2-l{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-3-l{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-4-l{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.swagger-ui .shadow-5-l{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}}.swagger-ui .pre{overflow-x:auto;overflow-y:hidden;overflow:scroll}.swagger-ui .top-0{top:0}.swagger-ui .right-0{right:0}.swagger-ui .bottom-0{bottom:0}.swagger-ui .left-0{left:0}.swagger-ui .top-1{top:1rem}.swagger-ui .right-1{right:1rem}.swagger-ui .bottom-1{bottom:1rem}.swagger-ui .left-1{left:1rem}.swagger-ui .top-2{top:2rem}.swagger-ui .right-2{right:2rem}.swagger-ui .bottom-2{bottom:2rem}.swagger-ui .left-2{left:2rem}.swagger-ui .top--1{top:-1rem}.swagger-ui .right--1{right:-1rem}.swagger-ui .bottom--1{bottom:-1rem}.swagger-ui .left--1{left:-1rem}.swagger-ui .top--2{top:-2rem}.swagger-ui .right--2{right:-2rem}.swagger-ui .bottom--2{bottom:-2rem}.swagger-ui .left--2{left:-2rem}.swagger-ui .absolute--fill{bottom:0;left:0;right:0;top:0}@media screen and (min-width:30em){.swagger-ui .top-0-ns{top:0}.swagger-ui .left-0-ns{left:0}.swagger-ui .right-0-ns{right:0}.swagger-ui .bottom-0-ns{bottom:0}.swagger-ui .top-1-ns{top:1rem}.swagger-ui .left-1-ns{left:1rem}.swagger-ui .right-1-ns{right:1rem}.swagger-ui .bottom-1-ns{bottom:1rem}.swagger-ui .top-2-ns{top:2rem}.swagger-ui .left-2-ns{left:2rem}.swagger-ui .right-2-ns{right:2rem}.swagger-ui .bottom-2-ns{bottom:2rem}.swagger-ui .top--1-ns{top:-1rem}.swagger-ui .right--1-ns{right:-1rem}.swagger-ui .bottom--1-ns{bottom:-1rem}.swagger-ui .left--1-ns{left:-1rem}.swagger-ui .top--2-ns{top:-2rem}.swagger-ui .right--2-ns{right:-2rem}.swagger-ui .bottom--2-ns{bottom:-2rem}.swagger-ui .left--2-ns{left:-2rem}.swagger-ui .absolute--fill-ns{bottom:0;left:0;right:0;top:0}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .top-0-m{top:0}.swagger-ui .left-0-m{left:0}.swagger-ui .right-0-m{right:0}.swagger-ui .bottom-0-m{bottom:0}.swagger-ui .top-1-m{top:1rem}.swagger-ui .left-1-m{left:1rem}.swagger-ui .right-1-m{right:1rem}.swagger-ui .bottom-1-m{bottom:1rem}.swagger-ui .top-2-m{top:2rem}.swagger-ui .left-2-m{left:2rem}.swagger-ui .right-2-m{right:2rem}.swagger-ui .bottom-2-m{bottom:2rem}.swagger-ui .top--1-m{top:-1rem}.swagger-ui .right--1-m{right:-1rem}.swagger-ui .bottom--1-m{bottom:-1rem}.swagger-ui .left--1-m{left:-1rem}.swagger-ui .top--2-m{top:-2rem}.swagger-ui .right--2-m{right:-2rem}.swagger-ui .bottom--2-m{bottom:-2rem}.swagger-ui .left--2-m{left:-2rem}.swagger-ui .absolute--fill-m{bottom:0;left:0;right:0;top:0}}@media screen and (min-width:60em){.swagger-ui .top-0-l{top:0}.swagger-ui .left-0-l{left:0}.swagger-ui .right-0-l{right:0}.swagger-ui .bottom-0-l{bottom:0}.swagger-ui .top-1-l{top:1rem}.swagger-ui .left-1-l{left:1rem}.swagger-ui .right-1-l{right:1rem}.swagger-ui .bottom-1-l{bottom:1rem}.swagger-ui .top-2-l{top:2rem}.swagger-ui .left-2-l{left:2rem}.swagger-ui .right-2-l{right:2rem}.swagger-ui .bottom-2-l{bottom:2rem}.swagger-ui .top--1-l{top:-1rem}.swagger-ui .right--1-l{right:-1rem}.swagger-ui .bottom--1-l{bottom:-1rem}.swagger-ui .left--1-l{left:-1rem}.swagger-ui .top--2-l{top:-2rem}.swagger-ui .right--2-l{right:-2rem}.swagger-ui .bottom--2-l{bottom:-2rem}.swagger-ui .left--2-l{left:-2rem}.swagger-ui .absolute--fill-l{bottom:0;left:0;right:0;top:0}}.swagger-ui .cf:after,.swagger-ui .cf:before{content:\" \";display:table}.swagger-ui .cf:after{clear:both}.swagger-ui .cf{zoom:1}.swagger-ui .cl{clear:left}.swagger-ui .cr{clear:right}.swagger-ui .cb{clear:both}.swagger-ui .cn{clear:none}@media screen and (min-width:30em){.swagger-ui .cl-ns{clear:left}.swagger-ui .cr-ns{clear:right}.swagger-ui .cb-ns{clear:both}.swagger-ui .cn-ns{clear:none}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .cl-m{clear:left}.swagger-ui .cr-m{clear:right}.swagger-ui .cb-m{clear:both}.swagger-ui .cn-m{clear:none}}@media screen and (min-width:60em){.swagger-ui .cl-l{clear:left}.swagger-ui .cr-l{clear:right}.swagger-ui .cb-l{clear:both}.swagger-ui .cn-l{clear:none}}.swagger-ui .flex{display:flex}.swagger-ui .inline-flex{display:inline-flex}.swagger-ui .flex-auto{flex:1 1 auto;min-height:0;min-width:0}.swagger-ui .flex-none{flex:none}.swagger-ui .flex-column{flex-direction:column}.swagger-ui .flex-row{flex-direction:row}.swagger-ui .flex-wrap{flex-wrap:wrap}.swagger-ui .flex-nowrap{flex-wrap:nowrap}.swagger-ui .flex-wrap-reverse{flex-wrap:wrap-reverse}.swagger-ui .flex-column-reverse{flex-direction:column-reverse}.swagger-ui .flex-row-reverse{flex-direction:row-reverse}.swagger-ui .items-start{align-items:flex-start}.swagger-ui .items-end{align-items:flex-end}.swagger-ui .items-center{align-items:center}.swagger-ui .items-baseline{align-items:baseline}.swagger-ui .items-stretch{align-items:stretch}.swagger-ui .self-start{align-self:flex-start}.swagger-ui .self-end{align-self:flex-end}.swagger-ui .self-center{align-self:center}.swagger-ui .self-baseline{align-self:baseline}.swagger-ui .self-stretch{align-self:stretch}.swagger-ui .justify-start{justify-content:flex-start}.swagger-ui .justify-end{justify-content:flex-end}.swagger-ui .justify-center{justify-content:center}.swagger-ui .justify-between{justify-content:space-between}.swagger-ui .justify-around{justify-content:space-around}.swagger-ui .content-start{align-content:flex-start}.swagger-ui .content-end{align-content:flex-end}.swagger-ui .content-center{align-content:center}.swagger-ui .content-between{align-content:space-between}.swagger-ui .content-around{align-content:space-around}.swagger-ui .content-stretch{align-content:stretch}.swagger-ui .order-0{order:0}.swagger-ui .order-1{order:1}.swagger-ui .order-2{order:2}.swagger-ui .order-3{order:3}.swagger-ui .order-4{order:4}.swagger-ui .order-5{order:5}.swagger-ui .order-6{order:6}.swagger-ui .order-7{order:7}.swagger-ui .order-8{order:8}.swagger-ui .order-last{order:99999}.swagger-ui .flex-grow-0{flex-grow:0}.swagger-ui .flex-grow-1{flex-grow:1}.swagger-ui .flex-shrink-0{flex-shrink:0}.swagger-ui .flex-shrink-1{flex-shrink:1}@media screen and (min-width:30em){.swagger-ui .flex-ns{display:flex}.swagger-ui .inline-flex-ns{display:inline-flex}.swagger-ui .flex-auto-ns{flex:1 1 auto;min-height:0;min-width:0}.swagger-ui .flex-none-ns{flex:none}.swagger-ui .flex-column-ns{flex-direction:column}.swagger-ui .flex-row-ns{flex-direction:row}.swagger-ui .flex-wrap-ns{flex-wrap:wrap}.swagger-ui .flex-nowrap-ns{flex-wrap:nowrap}.swagger-ui .flex-wrap-reverse-ns{flex-wrap:wrap-reverse}.swagger-ui .flex-column-reverse-ns{flex-direction:column-reverse}.swagger-ui .flex-row-reverse-ns{flex-direction:row-reverse}.swagger-ui .items-start-ns{align-items:flex-start}.swagger-ui .items-end-ns{align-items:flex-end}.swagger-ui .items-center-ns{align-items:center}.swagger-ui .items-baseline-ns{align-items:baseline}.swagger-ui .items-stretch-ns{align-items:stretch}.swagger-ui .self-start-ns{align-self:flex-start}.swagger-ui .self-end-ns{align-self:flex-end}.swagger-ui .self-center-ns{align-self:center}.swagger-ui .self-baseline-ns{align-self:baseline}.swagger-ui .self-stretch-ns{align-self:stretch}.swagger-ui .justify-start-ns{justify-content:flex-start}.swagger-ui .justify-end-ns{justify-content:flex-end}.swagger-ui .justify-center-ns{justify-content:center}.swagger-ui .justify-between-ns{justify-content:space-between}.swagger-ui .justify-around-ns{justify-content:space-around}.swagger-ui .content-start-ns{align-content:flex-start}.swagger-ui .content-end-ns{align-content:flex-end}.swagger-ui .content-center-ns{align-content:center}.swagger-ui .content-between-ns{align-content:space-between}.swagger-ui .content-around-ns{align-content:space-around}.swagger-ui .content-stretch-ns{align-content:stretch}.swagger-ui .order-0-ns{order:0}.swagger-ui .order-1-ns{order:1}.swagger-ui .order-2-ns{order:2}.swagger-ui .order-3-ns{order:3}.swagger-ui .order-4-ns{order:4}.swagger-ui .order-5-ns{order:5}.swagger-ui .order-6-ns{order:6}.swagger-ui .order-7-ns{order:7}.swagger-ui .order-8-ns{order:8}.swagger-ui .order-last-ns{order:99999}.swagger-ui .flex-grow-0-ns{flex-grow:0}.swagger-ui .flex-grow-1-ns{flex-grow:1}.swagger-ui .flex-shrink-0-ns{flex-shrink:0}.swagger-ui .flex-shrink-1-ns{flex-shrink:1}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .flex-m{display:flex}.swagger-ui .inline-flex-m{display:inline-flex}.swagger-ui .flex-auto-m{flex:1 1 auto;min-height:0;min-width:0}.swagger-ui .flex-none-m{flex:none}.swagger-ui .flex-column-m{flex-direction:column}.swagger-ui .flex-row-m{flex-direction:row}.swagger-ui .flex-wrap-m{flex-wrap:wrap}.swagger-ui .flex-nowrap-m{flex-wrap:nowrap}.swagger-ui .flex-wrap-reverse-m{flex-wrap:wrap-reverse}.swagger-ui .flex-column-reverse-m{flex-direction:column-reverse}.swagger-ui .flex-row-reverse-m{flex-direction:row-reverse}.swagger-ui .items-start-m{align-items:flex-start}.swagger-ui .items-end-m{align-items:flex-end}.swagger-ui .items-center-m{align-items:center}.swagger-ui .items-baseline-m{align-items:baseline}.swagger-ui .items-stretch-m{align-items:stretch}.swagger-ui .self-start-m{align-self:flex-start}.swagger-ui .self-end-m{align-self:flex-end}.swagger-ui .self-center-m{align-self:center}.swagger-ui .self-baseline-m{align-self:baseline}.swagger-ui .self-stretch-m{align-self:stretch}.swagger-ui .justify-start-m{justify-content:flex-start}.swagger-ui .justify-end-m{justify-content:flex-end}.swagger-ui .justify-center-m{justify-content:center}.swagger-ui .justify-between-m{justify-content:space-between}.swagger-ui .justify-around-m{justify-content:space-around}.swagger-ui .content-start-m{align-content:flex-start}.swagger-ui .content-end-m{align-content:flex-end}.swagger-ui .content-center-m{align-content:center}.swagger-ui .content-between-m{align-content:space-between}.swagger-ui .content-around-m{align-content:space-around}.swagger-ui .content-stretch-m{align-content:stretch}.swagger-ui .order-0-m{order:0}.swagger-ui .order-1-m{order:1}.swagger-ui .order-2-m{order:2}.swagger-ui .order-3-m{order:3}.swagger-ui .order-4-m{order:4}.swagger-ui .order-5-m{order:5}.swagger-ui .order-6-m{order:6}.swagger-ui .order-7-m{order:7}.swagger-ui .order-8-m{order:8}.swagger-ui .order-last-m{order:99999}.swagger-ui .flex-grow-0-m{flex-grow:0}.swagger-ui .flex-grow-1-m{flex-grow:1}.swagger-ui .flex-shrink-0-m{flex-shrink:0}.swagger-ui .flex-shrink-1-m{flex-shrink:1}}@media screen and (min-width:60em){.swagger-ui .flex-l{display:flex}.swagger-ui .inline-flex-l{display:inline-flex}.swagger-ui .flex-auto-l{flex:1 1 auto;min-height:0;min-width:0}.swagger-ui .flex-none-l{flex:none}.swagger-ui .flex-column-l{flex-direction:column}.swagger-ui .flex-row-l{flex-direction:row}.swagger-ui .flex-wrap-l{flex-wrap:wrap}.swagger-ui .flex-nowrap-l{flex-wrap:nowrap}.swagger-ui .flex-wrap-reverse-l{flex-wrap:wrap-reverse}.swagger-ui .flex-column-reverse-l{flex-direction:column-reverse}.swagger-ui .flex-row-reverse-l{flex-direction:row-reverse}.swagger-ui .items-start-l{align-items:flex-start}.swagger-ui .items-end-l{align-items:flex-end}.swagger-ui .items-center-l{align-items:center}.swagger-ui .items-baseline-l{align-items:baseline}.swagger-ui .items-stretch-l{align-items:stretch}.swagger-ui .self-start-l{align-self:flex-start}.swagger-ui .self-end-l{align-self:flex-end}.swagger-ui .self-center-l{align-self:center}.swagger-ui .self-baseline-l{align-self:baseline}.swagger-ui .self-stretch-l{align-self:stretch}.swagger-ui .justify-start-l{justify-content:flex-start}.swagger-ui .justify-end-l{justify-content:flex-end}.swagger-ui .justify-center-l{justify-content:center}.swagger-ui .justify-between-l{justify-content:space-between}.swagger-ui .justify-around-l{justify-content:space-around}.swagger-ui .content-start-l{align-content:flex-start}.swagger-ui .content-end-l{align-content:flex-end}.swagger-ui .content-center-l{align-content:center}.swagger-ui .content-between-l{align-content:space-between}.swagger-ui .content-around-l{align-content:space-around}.swagger-ui .content-stretch-l{align-content:stretch}.swagger-ui .order-0-l{order:0}.swagger-ui .order-1-l{order:1}.swagger-ui .order-2-l{order:2}.swagger-ui .order-3-l{order:3}.swagger-ui .order-4-l{order:4}.swagger-ui .order-5-l{order:5}.swagger-ui .order-6-l{order:6}.swagger-ui .order-7-l{order:7}.swagger-ui .order-8-l{order:8}.swagger-ui .order-last-l{order:99999}.swagger-ui .flex-grow-0-l{flex-grow:0}.swagger-ui .flex-grow-1-l{flex-grow:1}.swagger-ui .flex-shrink-0-l{flex-shrink:0}.swagger-ui .flex-shrink-1-l{flex-shrink:1}}.swagger-ui .dn{display:none}.swagger-ui .di{display:inline}.swagger-ui .db{display:block}.swagger-ui .dib{display:inline-block}.swagger-ui .dit{display:inline-table}.swagger-ui .dt{display:table}.swagger-ui .dtc{display:table-cell}.swagger-ui .dt-row{display:table-row}.swagger-ui .dt-row-group{display:table-row-group}.swagger-ui .dt-column{display:table-column}.swagger-ui .dt-column-group{display:table-column-group}.swagger-ui .dt--fixed{table-layout:fixed;width:100%}@media screen and (min-width:30em){.swagger-ui .dn-ns{display:none}.swagger-ui .di-ns{display:inline}.swagger-ui .db-ns{display:block}.swagger-ui .dib-ns{display:inline-block}.swagger-ui .dit-ns{display:inline-table}.swagger-ui .dt-ns{display:table}.swagger-ui .dtc-ns{display:table-cell}.swagger-ui .dt-row-ns{display:table-row}.swagger-ui .dt-row-group-ns{display:table-row-group}.swagger-ui .dt-column-ns{display:table-column}.swagger-ui .dt-column-group-ns{display:table-column-group}.swagger-ui .dt--fixed-ns{table-layout:fixed;width:100%}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .dn-m{display:none}.swagger-ui .di-m{display:inline}.swagger-ui .db-m{display:block}.swagger-ui .dib-m{display:inline-block}.swagger-ui .dit-m{display:inline-table}.swagger-ui .dt-m{display:table}.swagger-ui .dtc-m{display:table-cell}.swagger-ui .dt-row-m{display:table-row}.swagger-ui .dt-row-group-m{display:table-row-group}.swagger-ui .dt-column-m{display:table-column}.swagger-ui .dt-column-group-m{display:table-column-group}.swagger-ui .dt--fixed-m{table-layout:fixed;width:100%}}@media screen and (min-width:60em){.swagger-ui .dn-l{display:none}.swagger-ui .di-l{display:inline}.swagger-ui .db-l{display:block}.swagger-ui .dib-l{display:inline-block}.swagger-ui .dit-l{display:inline-table}.swagger-ui .dt-l{display:table}.swagger-ui .dtc-l{display:table-cell}.swagger-ui .dt-row-l{display:table-row}.swagger-ui .dt-row-group-l{display:table-row-group}.swagger-ui .dt-column-l{display:table-column}.swagger-ui .dt-column-group-l{display:table-column-group}.swagger-ui .dt--fixed-l{table-layout:fixed;width:100%}}.swagger-ui .fl{_display:inline;float:left}.swagger-ui .fr{_display:inline;float:right}.swagger-ui .fn{float:none}@media screen and (min-width:30em){.swagger-ui .fl-ns{_display:inline;float:left}.swagger-ui .fr-ns{_display:inline;float:right}.swagger-ui .fn-ns{float:none}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .fl-m{_display:inline;float:left}.swagger-ui .fr-m{_display:inline;float:right}.swagger-ui .fn-m{float:none}}@media screen and (min-width:60em){.swagger-ui .fl-l{_display:inline;float:left}.swagger-ui .fr-l{_display:inline;float:right}.swagger-ui .fn-l{float:none}}.swagger-ui .sans-serif{font-family:-apple-system,BlinkMacSystemFont,avenir next,avenir,helvetica,helvetica neue,ubuntu,roboto,noto,segoe ui,arial,sans-serif}.swagger-ui .serif{font-family:georgia,serif}.swagger-ui .system-sans-serif{font-family:sans-serif}.swagger-ui .system-serif{font-family:serif}.swagger-ui .code,.swagger-ui code{font-family:Consolas,monaco,monospace}.swagger-ui .courier{font-family:Courier Next,courier,monospace}.swagger-ui .helvetica{font-family:helvetica neue,helvetica,sans-serif}.swagger-ui .avenir{font-family:avenir next,avenir,sans-serif}.swagger-ui .athelas{font-family:athelas,georgia,serif}.swagger-ui .georgia{font-family:georgia,serif}.swagger-ui .times{font-family:times,serif}.swagger-ui .bodoni{font-family:Bodoni MT,serif}.swagger-ui .calisto{font-family:Calisto MT,serif}.swagger-ui .garamond{font-family:garamond,serif}.swagger-ui .baskerville{font-family:baskerville,serif}.swagger-ui .i{font-style:italic}.swagger-ui .fs-normal{font-style:normal}@media screen and (min-width:30em){.swagger-ui .i-ns{font-style:italic}.swagger-ui .fs-normal-ns{font-style:normal}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .i-m{font-style:italic}.swagger-ui .fs-normal-m{font-style:normal}}@media screen and (min-width:60em){.swagger-ui .i-l{font-style:italic}.swagger-ui .fs-normal-l{font-style:normal}}.swagger-ui .normal{font-weight:400}.swagger-ui .b{font-weight:700}.swagger-ui .fw1{font-weight:100}.swagger-ui .fw2{font-weight:200}.swagger-ui .fw3{font-weight:300}.swagger-ui .fw4{font-weight:400}.swagger-ui .fw5{font-weight:500}.swagger-ui .fw6{font-weight:600}.swagger-ui .fw7{font-weight:700}.swagger-ui .fw8{font-weight:800}.swagger-ui .fw9{font-weight:900}@media screen and (min-width:30em){.swagger-ui .normal-ns{font-weight:400}.swagger-ui .b-ns{font-weight:700}.swagger-ui .fw1-ns{font-weight:100}.swagger-ui .fw2-ns{font-weight:200}.swagger-ui .fw3-ns{font-weight:300}.swagger-ui .fw4-ns{font-weight:400}.swagger-ui .fw5-ns{font-weight:500}.swagger-ui .fw6-ns{font-weight:600}.swagger-ui .fw7-ns{font-weight:700}.swagger-ui .fw8-ns{font-weight:800}.swagger-ui .fw9-ns{font-weight:900}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .normal-m{font-weight:400}.swagger-ui .b-m{font-weight:700}.swagger-ui .fw1-m{font-weight:100}.swagger-ui .fw2-m{font-weight:200}.swagger-ui .fw3-m{font-weight:300}.swagger-ui .fw4-m{font-weight:400}.swagger-ui .fw5-m{font-weight:500}.swagger-ui .fw6-m{font-weight:600}.swagger-ui .fw7-m{font-weight:700}.swagger-ui .fw8-m{font-weight:800}.swagger-ui .fw9-m{font-weight:900}}@media screen and (min-width:60em){.swagger-ui .normal-l{font-weight:400}.swagger-ui .b-l{font-weight:700}.swagger-ui .fw1-l{font-weight:100}.swagger-ui .fw2-l{font-weight:200}.swagger-ui .fw3-l{font-weight:300}.swagger-ui .fw4-l{font-weight:400}.swagger-ui .fw5-l{font-weight:500}.swagger-ui .fw6-l{font-weight:600}.swagger-ui .fw7-l{font-weight:700}.swagger-ui .fw8-l{font-weight:800}.swagger-ui .fw9-l{font-weight:900}}.swagger-ui .input-reset{-webkit-appearance:none;-moz-appearance:none}.swagger-ui .button-reset::-moz-focus-inner,.swagger-ui .input-reset::-moz-focus-inner{border:0;padding:0}.swagger-ui .h1{height:1rem}.swagger-ui .h2{height:2rem}.swagger-ui .h3{height:4rem}.swagger-ui .h4{height:8rem}.swagger-ui .h5{height:16rem}.swagger-ui .h-25{height:25%}.swagger-ui .h-50{height:50%}.swagger-ui .h-75{height:75%}.swagger-ui .h-100{height:100%}.swagger-ui .min-h-100{min-height:100%}.swagger-ui .vh-25{height:25vh}.swagger-ui .vh-50{height:50vh}.swagger-ui .vh-75{height:75vh}.swagger-ui .vh-100{height:100vh}.swagger-ui .min-vh-100{min-height:100vh}.swagger-ui .h-auto{height:auto}.swagger-ui .h-inherit{height:inherit}@media screen and (min-width:30em){.swagger-ui .h1-ns{height:1rem}.swagger-ui .h2-ns{height:2rem}.swagger-ui .h3-ns{height:4rem}.swagger-ui .h4-ns{height:8rem}.swagger-ui .h5-ns{height:16rem}.swagger-ui .h-25-ns{height:25%}.swagger-ui .h-50-ns{height:50%}.swagger-ui .h-75-ns{height:75%}.swagger-ui .h-100-ns{height:100%}.swagger-ui .min-h-100-ns{min-height:100%}.swagger-ui .vh-25-ns{height:25vh}.swagger-ui .vh-50-ns{height:50vh}.swagger-ui .vh-75-ns{height:75vh}.swagger-ui .vh-100-ns{height:100vh}.swagger-ui .min-vh-100-ns{min-height:100vh}.swagger-ui .h-auto-ns{height:auto}.swagger-ui .h-inherit-ns{height:inherit}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .h1-m{height:1rem}.swagger-ui .h2-m{height:2rem}.swagger-ui .h3-m{height:4rem}.swagger-ui .h4-m{height:8rem}.swagger-ui .h5-m{height:16rem}.swagger-ui .h-25-m{height:25%}.swagger-ui .h-50-m{height:50%}.swagger-ui .h-75-m{height:75%}.swagger-ui .h-100-m{height:100%}.swagger-ui .min-h-100-m{min-height:100%}.swagger-ui .vh-25-m{height:25vh}.swagger-ui .vh-50-m{height:50vh}.swagger-ui .vh-75-m{height:75vh}.swagger-ui .vh-100-m{height:100vh}.swagger-ui .min-vh-100-m{min-height:100vh}.swagger-ui .h-auto-m{height:auto}.swagger-ui .h-inherit-m{height:inherit}}@media screen and (min-width:60em){.swagger-ui .h1-l{height:1rem}.swagger-ui .h2-l{height:2rem}.swagger-ui .h3-l{height:4rem}.swagger-ui .h4-l{height:8rem}.swagger-ui .h5-l{height:16rem}.swagger-ui .h-25-l{height:25%}.swagger-ui .h-50-l{height:50%}.swagger-ui .h-75-l{height:75%}.swagger-ui .h-100-l{height:100%}.swagger-ui .min-h-100-l{min-height:100%}.swagger-ui .vh-25-l{height:25vh}.swagger-ui .vh-50-l{height:50vh}.swagger-ui .vh-75-l{height:75vh}.swagger-ui .vh-100-l{height:100vh}.swagger-ui .min-vh-100-l{min-height:100vh}.swagger-ui .h-auto-l{height:auto}.swagger-ui .h-inherit-l{height:inherit}}.swagger-ui .tracked{letter-spacing:.1em}.swagger-ui .tracked-tight{letter-spacing:-.05em}.swagger-ui .tracked-mega{letter-spacing:.25em}@media screen and (min-width:30em){.swagger-ui .tracked-ns{letter-spacing:.1em}.swagger-ui .tracked-tight-ns{letter-spacing:-.05em}.swagger-ui .tracked-mega-ns{letter-spacing:.25em}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .tracked-m{letter-spacing:.1em}.swagger-ui .tracked-tight-m{letter-spacing:-.05em}.swagger-ui .tracked-mega-m{letter-spacing:.25em}}@media screen and (min-width:60em){.swagger-ui .tracked-l{letter-spacing:.1em}.swagger-ui .tracked-tight-l{letter-spacing:-.05em}.swagger-ui .tracked-mega-l{letter-spacing:.25em}}.swagger-ui .lh-solid{line-height:1}.swagger-ui .lh-title{line-height:1.25}.swagger-ui .lh-copy{line-height:1.5}@media screen and (min-width:30em){.swagger-ui .lh-solid-ns{line-height:1}.swagger-ui .lh-title-ns{line-height:1.25}.swagger-ui .lh-copy-ns{line-height:1.5}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .lh-solid-m{line-height:1}.swagger-ui .lh-title-m{line-height:1.25}.swagger-ui .lh-copy-m{line-height:1.5}}@media screen and (min-width:60em){.swagger-ui .lh-solid-l{line-height:1}.swagger-ui .lh-title-l{line-height:1.25}.swagger-ui .lh-copy-l{line-height:1.5}}.swagger-ui .link{-webkit-text-decoration:none;text-decoration:none}.swagger-ui .link,.swagger-ui .link:active,.swagger-ui .link:focus,.swagger-ui .link:hover,.swagger-ui .link:link,.swagger-ui .link:visited{transition:color .15s ease-in}.swagger-ui .link:focus{outline:1px dotted currentColor}.swagger-ui .list{list-style-type:none}.swagger-ui .mw-100{max-width:100%}.swagger-ui .mw1{max-width:1rem}.swagger-ui .mw2{max-width:2rem}.swagger-ui .mw3{max-width:4rem}.swagger-ui .mw4{max-width:8rem}.swagger-ui .mw5{max-width:16rem}.swagger-ui .mw6{max-width:32rem}.swagger-ui .mw7{max-width:48rem}.swagger-ui .mw8{max-width:64rem}.swagger-ui .mw9{max-width:96rem}.swagger-ui .mw-none{max-width:none}@media screen and (min-width:30em){.swagger-ui .mw-100-ns{max-width:100%}.swagger-ui .mw1-ns{max-width:1rem}.swagger-ui .mw2-ns{max-width:2rem}.swagger-ui .mw3-ns{max-width:4rem}.swagger-ui .mw4-ns{max-width:8rem}.swagger-ui .mw5-ns{max-width:16rem}.swagger-ui .mw6-ns{max-width:32rem}.swagger-ui .mw7-ns{max-width:48rem}.swagger-ui .mw8-ns{max-width:64rem}.swagger-ui .mw9-ns{max-width:96rem}.swagger-ui .mw-none-ns{max-width:none}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .mw-100-m{max-width:100%}.swagger-ui .mw1-m{max-width:1rem}.swagger-ui .mw2-m{max-width:2rem}.swagger-ui .mw3-m{max-width:4rem}.swagger-ui .mw4-m{max-width:8rem}.swagger-ui .mw5-m{max-width:16rem}.swagger-ui .mw6-m{max-width:32rem}.swagger-ui .mw7-m{max-width:48rem}.swagger-ui .mw8-m{max-width:64rem}.swagger-ui .mw9-m{max-width:96rem}.swagger-ui .mw-none-m{max-width:none}}@media screen and (min-width:60em){.swagger-ui .mw-100-l{max-width:100%}.swagger-ui .mw1-l{max-width:1rem}.swagger-ui .mw2-l{max-width:2rem}.swagger-ui .mw3-l{max-width:4rem}.swagger-ui .mw4-l{max-width:8rem}.swagger-ui .mw5-l{max-width:16rem}.swagger-ui .mw6-l{max-width:32rem}.swagger-ui .mw7-l{max-width:48rem}.swagger-ui .mw8-l{max-width:64rem}.swagger-ui .mw9-l{max-width:96rem}.swagger-ui .mw-none-l{max-width:none}}.swagger-ui .w1{width:1rem}.swagger-ui .w2{width:2rem}.swagger-ui .w3{width:4rem}.swagger-ui .w4{width:8rem}.swagger-ui .w5{width:16rem}.swagger-ui .w-10{width:10%}.swagger-ui .w-20{width:20%}.swagger-ui .w-25{width:25%}.swagger-ui .w-30{width:30%}.swagger-ui .w-33{width:33%}.swagger-ui .w-34{width:34%}.swagger-ui .w-40{width:40%}.swagger-ui .w-50{width:50%}.swagger-ui .w-60{width:60%}.swagger-ui .w-70{width:70%}.swagger-ui .w-75{width:75%}.swagger-ui .w-80{width:80%}.swagger-ui .w-90{width:90%}.swagger-ui .w-100{width:100%}.swagger-ui .w-third{width:33.3333333333%}.swagger-ui .w-two-thirds{width:66.6666666667%}.swagger-ui .w-auto{width:auto}@media screen and (min-width:30em){.swagger-ui .w1-ns{width:1rem}.swagger-ui .w2-ns{width:2rem}.swagger-ui .w3-ns{width:4rem}.swagger-ui .w4-ns{width:8rem}.swagger-ui .w5-ns{width:16rem}.swagger-ui .w-10-ns{width:10%}.swagger-ui .w-20-ns{width:20%}.swagger-ui .w-25-ns{width:25%}.swagger-ui .w-30-ns{width:30%}.swagger-ui .w-33-ns{width:33%}.swagger-ui .w-34-ns{width:34%}.swagger-ui .w-40-ns{width:40%}.swagger-ui .w-50-ns{width:50%}.swagger-ui .w-60-ns{width:60%}.swagger-ui .w-70-ns{width:70%}.swagger-ui .w-75-ns{width:75%}.swagger-ui .w-80-ns{width:80%}.swagger-ui .w-90-ns{width:90%}.swagger-ui .w-100-ns{width:100%}.swagger-ui .w-third-ns{width:33.3333333333%}.swagger-ui .w-two-thirds-ns{width:66.6666666667%}.swagger-ui .w-auto-ns{width:auto}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .w1-m{width:1rem}.swagger-ui .w2-m{width:2rem}.swagger-ui .w3-m{width:4rem}.swagger-ui .w4-m{width:8rem}.swagger-ui .w5-m{width:16rem}.swagger-ui .w-10-m{width:10%}.swagger-ui .w-20-m{width:20%}.swagger-ui .w-25-m{width:25%}.swagger-ui .w-30-m{width:30%}.swagger-ui .w-33-m{width:33%}.swagger-ui .w-34-m{width:34%}.swagger-ui .w-40-m{width:40%}.swagger-ui .w-50-m{width:50%}.swagger-ui .w-60-m{width:60%}.swagger-ui .w-70-m{width:70%}.swagger-ui .w-75-m{width:75%}.swagger-ui .w-80-m{width:80%}.swagger-ui .w-90-m{width:90%}.swagger-ui .w-100-m{width:100%}.swagger-ui .w-third-m{width:33.3333333333%}.swagger-ui .w-two-thirds-m{width:66.6666666667%}.swagger-ui .w-auto-m{width:auto}}@media screen and (min-width:60em){.swagger-ui .w1-l{width:1rem}.swagger-ui .w2-l{width:2rem}.swagger-ui .w3-l{width:4rem}.swagger-ui .w4-l{width:8rem}.swagger-ui .w5-l{width:16rem}.swagger-ui .w-10-l{width:10%}.swagger-ui .w-20-l{width:20%}.swagger-ui .w-25-l{width:25%}.swagger-ui .w-30-l{width:30%}.swagger-ui .w-33-l{width:33%}.swagger-ui .w-34-l{width:34%}.swagger-ui .w-40-l{width:40%}.swagger-ui .w-50-l{width:50%}.swagger-ui .w-60-l{width:60%}.swagger-ui .w-70-l{width:70%}.swagger-ui .w-75-l{width:75%}.swagger-ui .w-80-l{width:80%}.swagger-ui .w-90-l{width:90%}.swagger-ui .w-100-l{width:100%}.swagger-ui .w-third-l{width:33.3333333333%}.swagger-ui .w-two-thirds-l{width:66.6666666667%}.swagger-ui .w-auto-l{width:auto}}.swagger-ui .overflow-visible{overflow:visible}.swagger-ui .overflow-hidden{overflow:hidden}.swagger-ui .overflow-scroll{overflow:scroll}.swagger-ui .overflow-auto{overflow:auto}.swagger-ui .overflow-x-visible{overflow-x:visible}.swagger-ui .overflow-x-hidden{overflow-x:hidden}.swagger-ui .overflow-x-scroll{overflow-x:scroll}.swagger-ui .overflow-x-auto{overflow-x:auto}.swagger-ui .overflow-y-visible{overflow-y:visible}.swagger-ui .overflow-y-hidden{overflow-y:hidden}.swagger-ui .overflow-y-scroll{overflow-y:scroll}.swagger-ui .overflow-y-auto{overflow-y:auto}@media screen and (min-width:30em){.swagger-ui .overflow-visible-ns{overflow:visible}.swagger-ui .overflow-hidden-ns{overflow:hidden}.swagger-ui .overflow-scroll-ns{overflow:scroll}.swagger-ui .overflow-auto-ns{overflow:auto}.swagger-ui .overflow-x-visible-ns{overflow-x:visible}.swagger-ui .overflow-x-hidden-ns{overflow-x:hidden}.swagger-ui .overflow-x-scroll-ns{overflow-x:scroll}.swagger-ui .overflow-x-auto-ns{overflow-x:auto}.swagger-ui .overflow-y-visible-ns{overflow-y:visible}.swagger-ui .overflow-y-hidden-ns{overflow-y:hidden}.swagger-ui .overflow-y-scroll-ns{overflow-y:scroll}.swagger-ui .overflow-y-auto-ns{overflow-y:auto}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .overflow-visible-m{overflow:visible}.swagger-ui .overflow-hidden-m{overflow:hidden}.swagger-ui .overflow-scroll-m{overflow:scroll}.swagger-ui .overflow-auto-m{overflow:auto}.swagger-ui .overflow-x-visible-m{overflow-x:visible}.swagger-ui .overflow-x-hidden-m{overflow-x:hidden}.swagger-ui .overflow-x-scroll-m{overflow-x:scroll}.swagger-ui .overflow-x-auto-m{overflow-x:auto}.swagger-ui .overflow-y-visible-m{overflow-y:visible}.swagger-ui .overflow-y-hidden-m{overflow-y:hidden}.swagger-ui .overflow-y-scroll-m{overflow-y:scroll}.swagger-ui .overflow-y-auto-m{overflow-y:auto}}@media screen and (min-width:60em){.swagger-ui .overflow-visible-l{overflow:visible}.swagger-ui .overflow-hidden-l{overflow:hidden}.swagger-ui .overflow-scroll-l{overflow:scroll}.swagger-ui .overflow-auto-l{overflow:auto}.swagger-ui .overflow-x-visible-l{overflow-x:visible}.swagger-ui .overflow-x-hidden-l{overflow-x:hidden}.swagger-ui .overflow-x-scroll-l{overflow-x:scroll}.swagger-ui .overflow-x-auto-l{overflow-x:auto}.swagger-ui .overflow-y-visible-l{overflow-y:visible}.swagger-ui .overflow-y-hidden-l{overflow-y:hidden}.swagger-ui .overflow-y-scroll-l{overflow-y:scroll}.swagger-ui .overflow-y-auto-l{overflow-y:auto}}.swagger-ui .static{position:static}.swagger-ui .relative{position:relative}.swagger-ui .absolute{position:absolute}.swagger-ui .fixed{position:fixed}@media screen and (min-width:30em){.swagger-ui .static-ns{position:static}.swagger-ui .relative-ns{position:relative}.swagger-ui .absolute-ns{position:absolute}.swagger-ui .fixed-ns{position:fixed}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .static-m{position:static}.swagger-ui .relative-m{position:relative}.swagger-ui .absolute-m{position:absolute}.swagger-ui .fixed-m{position:fixed}}@media screen and (min-width:60em){.swagger-ui .static-l{position:static}.swagger-ui .relative-l{position:relative}.swagger-ui .absolute-l{position:absolute}.swagger-ui .fixed-l{position:fixed}}.swagger-ui .o-100{opacity:1}.swagger-ui .o-90{opacity:.9}.swagger-ui .o-80{opacity:.8}.swagger-ui .o-70{opacity:.7}.swagger-ui .o-60{opacity:.6}.swagger-ui .o-50{opacity:.5}.swagger-ui .o-40{opacity:.4}.swagger-ui .o-30{opacity:.3}.swagger-ui .o-20{opacity:.2}.swagger-ui .o-10{opacity:.1}.swagger-ui .o-05{opacity:.05}.swagger-ui .o-025{opacity:.025}.swagger-ui .o-0{opacity:0}.swagger-ui .rotate-45{transform:rotate(45deg)}.swagger-ui .rotate-90{transform:rotate(90deg)}.swagger-ui .rotate-135{transform:rotate(135deg)}.swagger-ui .rotate-180{transform:rotate(180deg)}.swagger-ui .rotate-225{transform:rotate(225deg)}.swagger-ui .rotate-270{transform:rotate(270deg)}.swagger-ui .rotate-315{transform:rotate(315deg)}@media screen and (min-width:30em){.swagger-ui .rotate-45-ns{transform:rotate(45deg)}.swagger-ui .rotate-90-ns{transform:rotate(90deg)}.swagger-ui .rotate-135-ns{transform:rotate(135deg)}.swagger-ui .rotate-180-ns{transform:rotate(180deg)}.swagger-ui .rotate-225-ns{transform:rotate(225deg)}.swagger-ui .rotate-270-ns{transform:rotate(270deg)}.swagger-ui .rotate-315-ns{transform:rotate(315deg)}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .rotate-45-m{transform:rotate(45deg)}.swagger-ui .rotate-90-m{transform:rotate(90deg)}.swagger-ui .rotate-135-m{transform:rotate(135deg)}.swagger-ui .rotate-180-m{transform:rotate(180deg)}.swagger-ui .rotate-225-m{transform:rotate(225deg)}.swagger-ui .rotate-270-m{transform:rotate(270deg)}.swagger-ui .rotate-315-m{transform:rotate(315deg)}}@media screen and (min-width:60em){.swagger-ui .rotate-45-l{transform:rotate(45deg)}.swagger-ui .rotate-90-l{transform:rotate(90deg)}.swagger-ui .rotate-135-l{transform:rotate(135deg)}.swagger-ui .rotate-180-l{transform:rotate(180deg)}.swagger-ui .rotate-225-l{transform:rotate(225deg)}.swagger-ui .rotate-270-l{transform:rotate(270deg)}.swagger-ui .rotate-315-l{transform:rotate(315deg)}}.swagger-ui .black-90{color:rgba(0,0,0,.9)}.swagger-ui .black-80{color:rgba(0,0,0,.8)}.swagger-ui .black-70{color:rgba(0,0,0,.7)}.swagger-ui .black-60{color:rgba(0,0,0,.6)}.swagger-ui .black-50{color:rgba(0,0,0,.5)}.swagger-ui .black-40{color:rgba(0,0,0,.4)}.swagger-ui .black-30{color:rgba(0,0,0,.3)}.swagger-ui .black-20{color:rgba(0,0,0,.2)}.swagger-ui .black-10{color:rgba(0,0,0,.1)}.swagger-ui .black-05{color:rgba(0,0,0,.05)}.swagger-ui .white-90{color:hsla(0,0%,100%,.9)}.swagger-ui .white-80{color:hsla(0,0%,100%,.8)}.swagger-ui .white-70{color:hsla(0,0%,100%,.7)}.swagger-ui .white-60{color:hsla(0,0%,100%,.6)}.swagger-ui .white-50{color:hsla(0,0%,100%,.5)}.swagger-ui .white-40{color:hsla(0,0%,100%,.4)}.swagger-ui .white-30{color:hsla(0,0%,100%,.3)}.swagger-ui .white-20{color:hsla(0,0%,100%,.2)}.swagger-ui .white-10{color:hsla(0,0%,100%,.1)}.swagger-ui .black{color:#000}.swagger-ui .near-black{color:#111}.swagger-ui .dark-gray{color:#333}.swagger-ui .mid-gray{color:#555}.swagger-ui .gray{color:#777}.swagger-ui .silver{color:#999}.swagger-ui .light-silver{color:#aaa}.swagger-ui .moon-gray{color:#ccc}.swagger-ui .light-gray{color:#eee}.swagger-ui .near-white{color:#f4f4f4}.swagger-ui .white{color:#fff}.swagger-ui .dark-red{color:#e7040f}.swagger-ui .red{color:#ff4136}.swagger-ui .light-red{color:#ff725c}.swagger-ui .orange{color:#ff6300}.swagger-ui .gold{color:#ffb700}.swagger-ui .yellow{color:gold}.swagger-ui .light-yellow{color:#fbf1a9}.swagger-ui .purple{color:#5e2ca5}.swagger-ui .light-purple{color:#a463f2}.swagger-ui .dark-pink{color:#d5008f}.swagger-ui .hot-pink{color:#ff41b4}.swagger-ui .pink{color:#ff80cc}.swagger-ui .light-pink{color:#ffa3d7}.swagger-ui .dark-green{color:#137752}.swagger-ui .green{color:#19a974}.swagger-ui .light-green{color:#9eebcf}.swagger-ui .navy{color:#001b44}.swagger-ui .dark-blue{color:#00449e}.swagger-ui .blue{color:#357edd}.swagger-ui .light-blue{color:#96ccff}.swagger-ui .lightest-blue{color:#cdecff}.swagger-ui .washed-blue{color:#f6fffe}.swagger-ui .washed-green{color:#e8fdf5}.swagger-ui .washed-yellow{color:#fffceb}.swagger-ui .washed-red{color:#ffdfdf}.swagger-ui .color-inherit{color:inherit}.swagger-ui .bg-black-90{background-color:rgba(0,0,0,.9)}.swagger-ui .bg-black-80{background-color:rgba(0,0,0,.8)}.swagger-ui .bg-black-70{background-color:rgba(0,0,0,.7)}.swagger-ui .bg-black-60{background-color:rgba(0,0,0,.6)}.swagger-ui .bg-black-50{background-color:rgba(0,0,0,.5)}.swagger-ui .bg-black-40{background-color:rgba(0,0,0,.4)}.swagger-ui .bg-black-30{background-color:rgba(0,0,0,.3)}.swagger-ui .bg-black-20{background-color:rgba(0,0,0,.2)}.swagger-ui .bg-black-10{background-color:rgba(0,0,0,.1)}.swagger-ui .bg-black-05{background-color:rgba(0,0,0,.05)}.swagger-ui .bg-white-90{background-color:hsla(0,0%,100%,.9)}.swagger-ui .bg-white-80{background-color:hsla(0,0%,100%,.8)}.swagger-ui .bg-white-70{background-color:hsla(0,0%,100%,.7)}.swagger-ui .bg-white-60{background-color:hsla(0,0%,100%,.6)}.swagger-ui .bg-white-50{background-color:hsla(0,0%,100%,.5)}.swagger-ui .bg-white-40{background-color:hsla(0,0%,100%,.4)}.swagger-ui .bg-white-30{background-color:hsla(0,0%,100%,.3)}.swagger-ui .bg-white-20{background-color:hsla(0,0%,100%,.2)}.swagger-ui .bg-white-10{background-color:hsla(0,0%,100%,.1)}.swagger-ui .bg-black{background-color:#000}.swagger-ui .bg-near-black{background-color:#111}.swagger-ui .bg-dark-gray{background-color:#333}.swagger-ui .bg-mid-gray{background-color:#555}.swagger-ui .bg-gray{background-color:#777}.swagger-ui .bg-silver{background-color:#999}.swagger-ui .bg-light-silver{background-color:#aaa}.swagger-ui .bg-moon-gray{background-color:#ccc}.swagger-ui .bg-light-gray{background-color:#eee}.swagger-ui .bg-near-white{background-color:#f4f4f4}.swagger-ui .bg-white{background-color:#fff}.swagger-ui .bg-transparent{background-color:transparent}.swagger-ui .bg-dark-red{background-color:#e7040f}.swagger-ui .bg-red{background-color:#ff4136}.swagger-ui .bg-light-red{background-color:#ff725c}.swagger-ui .bg-orange{background-color:#ff6300}.swagger-ui .bg-gold{background-color:#ffb700}.swagger-ui .bg-yellow{background-color:gold}.swagger-ui .bg-light-yellow{background-color:#fbf1a9}.swagger-ui .bg-purple{background-color:#5e2ca5}.swagger-ui .bg-light-purple{background-color:#a463f2}.swagger-ui .bg-dark-pink{background-color:#d5008f}.swagger-ui .bg-hot-pink{background-color:#ff41b4}.swagger-ui .bg-pink{background-color:#ff80cc}.swagger-ui .bg-light-pink{background-color:#ffa3d7}.swagger-ui .bg-dark-green{background-color:#137752}.swagger-ui .bg-green{background-color:#19a974}.swagger-ui .bg-light-green{background-color:#9eebcf}.swagger-ui .bg-navy{background-color:#001b44}.swagger-ui .bg-dark-blue{background-color:#00449e}.swagger-ui .bg-blue{background-color:#357edd}.swagger-ui .bg-light-blue{background-color:#96ccff}.swagger-ui .bg-lightest-blue{background-color:#cdecff}.swagger-ui .bg-washed-blue{background-color:#f6fffe}.swagger-ui .bg-washed-green{background-color:#e8fdf5}.swagger-ui .bg-washed-yellow{background-color:#fffceb}.swagger-ui .bg-washed-red{background-color:#ffdfdf}.swagger-ui .bg-inherit{background-color:inherit}.swagger-ui .hover-black:focus,.swagger-ui .hover-black:hover{color:#000}.swagger-ui .hover-near-black:focus,.swagger-ui .hover-near-black:hover{color:#111}.swagger-ui .hover-dark-gray:focus,.swagger-ui .hover-dark-gray:hover{color:#333}.swagger-ui .hover-mid-gray:focus,.swagger-ui .hover-mid-gray:hover{color:#555}.swagger-ui .hover-gray:focus,.swagger-ui .hover-gray:hover{color:#777}.swagger-ui .hover-silver:focus,.swagger-ui .hover-silver:hover{color:#999}.swagger-ui .hover-light-silver:focus,.swagger-ui .hover-light-silver:hover{color:#aaa}.swagger-ui .hover-moon-gray:focus,.swagger-ui .hover-moon-gray:hover{color:#ccc}.swagger-ui .hover-light-gray:focus,.swagger-ui .hover-light-gray:hover{color:#eee}.swagger-ui .hover-near-white:focus,.swagger-ui .hover-near-white:hover{color:#f4f4f4}.swagger-ui .hover-white:focus,.swagger-ui .hover-white:hover{color:#fff}.swagger-ui .hover-black-90:focus,.swagger-ui .hover-black-90:hover{color:rgba(0,0,0,.9)}.swagger-ui .hover-black-80:focus,.swagger-ui .hover-black-80:hover{color:rgba(0,0,0,.8)}.swagger-ui .hover-black-70:focus,.swagger-ui .hover-black-70:hover{color:rgba(0,0,0,.7)}.swagger-ui .hover-black-60:focus,.swagger-ui .hover-black-60:hover{color:rgba(0,0,0,.6)}.swagger-ui .hover-black-50:focus,.swagger-ui .hover-black-50:hover{color:rgba(0,0,0,.5)}.swagger-ui .hover-black-40:focus,.swagger-ui .hover-black-40:hover{color:rgba(0,0,0,.4)}.swagger-ui .hover-black-30:focus,.swagger-ui .hover-black-30:hover{color:rgba(0,0,0,.3)}.swagger-ui .hover-black-20:focus,.swagger-ui .hover-black-20:hover{color:rgba(0,0,0,.2)}.swagger-ui .hover-black-10:focus,.swagger-ui .hover-black-10:hover{color:rgba(0,0,0,.1)}.swagger-ui .hover-white-90:focus,.swagger-ui .hover-white-90:hover{color:hsla(0,0%,100%,.9)}.swagger-ui .hover-white-80:focus,.swagger-ui .hover-white-80:hover{color:hsla(0,0%,100%,.8)}.swagger-ui .hover-white-70:focus,.swagger-ui .hover-white-70:hover{color:hsla(0,0%,100%,.7)}.swagger-ui .hover-white-60:focus,.swagger-ui .hover-white-60:hover{color:hsla(0,0%,100%,.6)}.swagger-ui .hover-white-50:focus,.swagger-ui .hover-white-50:hover{color:hsla(0,0%,100%,.5)}.swagger-ui .hover-white-40:focus,.swagger-ui .hover-white-40:hover{color:hsla(0,0%,100%,.4)}.swagger-ui .hover-white-30:focus,.swagger-ui .hover-white-30:hover{color:hsla(0,0%,100%,.3)}.swagger-ui .hover-white-20:focus,.swagger-ui .hover-white-20:hover{color:hsla(0,0%,100%,.2)}.swagger-ui .hover-white-10:focus,.swagger-ui .hover-white-10:hover{color:hsla(0,0%,100%,.1)}.swagger-ui .hover-inherit:focus,.swagger-ui .hover-inherit:hover{color:inherit}.swagger-ui .hover-bg-black:focus,.swagger-ui .hover-bg-black:hover{background-color:#000}.swagger-ui .hover-bg-near-black:focus,.swagger-ui .hover-bg-near-black:hover{background-color:#111}.swagger-ui .hover-bg-dark-gray:focus,.swagger-ui .hover-bg-dark-gray:hover{background-color:#333}.swagger-ui .hover-bg-mid-gray:focus,.swagger-ui .hover-bg-mid-gray:hover{background-color:#555}.swagger-ui .hover-bg-gray:focus,.swagger-ui .hover-bg-gray:hover{background-color:#777}.swagger-ui .hover-bg-silver:focus,.swagger-ui .hover-bg-silver:hover{background-color:#999}.swagger-ui .hover-bg-light-silver:focus,.swagger-ui .hover-bg-light-silver:hover{background-color:#aaa}.swagger-ui .hover-bg-moon-gray:focus,.swagger-ui .hover-bg-moon-gray:hover{background-color:#ccc}.swagger-ui .hover-bg-light-gray:focus,.swagger-ui .hover-bg-light-gray:hover{background-color:#eee}.swagger-ui .hover-bg-near-white:focus,.swagger-ui .hover-bg-near-white:hover{background-color:#f4f4f4}.swagger-ui .hover-bg-white:focus,.swagger-ui .hover-bg-white:hover{background-color:#fff}.swagger-ui .hover-bg-transparent:focus,.swagger-ui .hover-bg-transparent:hover{background-color:transparent}.swagger-ui .hover-bg-black-90:focus,.swagger-ui .hover-bg-black-90:hover{background-color:rgba(0,0,0,.9)}.swagger-ui .hover-bg-black-80:focus,.swagger-ui .hover-bg-black-80:hover{background-color:rgba(0,0,0,.8)}.swagger-ui .hover-bg-black-70:focus,.swagger-ui .hover-bg-black-70:hover{background-color:rgba(0,0,0,.7)}.swagger-ui .hover-bg-black-60:focus,.swagger-ui .hover-bg-black-60:hover{background-color:rgba(0,0,0,.6)}.swagger-ui .hover-bg-black-50:focus,.swagger-ui .hover-bg-black-50:hover{background-color:rgba(0,0,0,.5)}.swagger-ui .hover-bg-black-40:focus,.swagger-ui .hover-bg-black-40:hover{background-color:rgba(0,0,0,.4)}.swagger-ui .hover-bg-black-30:focus,.swagger-ui .hover-bg-black-30:hover{background-color:rgba(0,0,0,.3)}.swagger-ui .hover-bg-black-20:focus,.swagger-ui .hover-bg-black-20:hover{background-color:rgba(0,0,0,.2)}.swagger-ui .hover-bg-black-10:focus,.swagger-ui .hover-bg-black-10:hover{background-color:rgba(0,0,0,.1)}.swagger-ui .hover-bg-white-90:focus,.swagger-ui .hover-bg-white-90:hover{background-color:hsla(0,0%,100%,.9)}.swagger-ui .hover-bg-white-80:focus,.swagger-ui .hover-bg-white-80:hover{background-color:hsla(0,0%,100%,.8)}.swagger-ui .hover-bg-white-70:focus,.swagger-ui .hover-bg-white-70:hover{background-color:hsla(0,0%,100%,.7)}.swagger-ui .hover-bg-white-60:focus,.swagger-ui .hover-bg-white-60:hover{background-color:hsla(0,0%,100%,.6)}.swagger-ui .hover-bg-white-50:focus,.swagger-ui .hover-bg-white-50:hover{background-color:hsla(0,0%,100%,.5)}.swagger-ui .hover-bg-white-40:focus,.swagger-ui .hover-bg-white-40:hover{background-color:hsla(0,0%,100%,.4)}.swagger-ui .hover-bg-white-30:focus,.swagger-ui .hover-bg-white-30:hover{background-color:hsla(0,0%,100%,.3)}.swagger-ui .hover-bg-white-20:focus,.swagger-ui .hover-bg-white-20:hover{background-color:hsla(0,0%,100%,.2)}.swagger-ui .hover-bg-white-10:focus,.swagger-ui .hover-bg-white-10:hover{background-color:hsla(0,0%,100%,.1)}.swagger-ui .hover-dark-red:focus,.swagger-ui .hover-dark-red:hover{color:#e7040f}.swagger-ui .hover-red:focus,.swagger-ui .hover-red:hover{color:#ff4136}.swagger-ui .hover-light-red:focus,.swagger-ui .hover-light-red:hover{color:#ff725c}.swagger-ui .hover-orange:focus,.swagger-ui .hover-orange:hover{color:#ff6300}.swagger-ui .hover-gold:focus,.swagger-ui .hover-gold:hover{color:#ffb700}.swagger-ui .hover-yellow:focus,.swagger-ui .hover-yellow:hover{color:gold}.swagger-ui .hover-light-yellow:focus,.swagger-ui .hover-light-yellow:hover{color:#fbf1a9}.swagger-ui .hover-purple:focus,.swagger-ui .hover-purple:hover{color:#5e2ca5}.swagger-ui .hover-light-purple:focus,.swagger-ui .hover-light-purple:hover{color:#a463f2}.swagger-ui .hover-dark-pink:focus,.swagger-ui .hover-dark-pink:hover{color:#d5008f}.swagger-ui .hover-hot-pink:focus,.swagger-ui .hover-hot-pink:hover{color:#ff41b4}.swagger-ui .hover-pink:focus,.swagger-ui .hover-pink:hover{color:#ff80cc}.swagger-ui .hover-light-pink:focus,.swagger-ui .hover-light-pink:hover{color:#ffa3d7}.swagger-ui .hover-dark-green:focus,.swagger-ui .hover-dark-green:hover{color:#137752}.swagger-ui .hover-green:focus,.swagger-ui .hover-green:hover{color:#19a974}.swagger-ui .hover-light-green:focus,.swagger-ui .hover-light-green:hover{color:#9eebcf}.swagger-ui .hover-navy:focus,.swagger-ui .hover-navy:hover{color:#001b44}.swagger-ui .hover-dark-blue:focus,.swagger-ui .hover-dark-blue:hover{color:#00449e}.swagger-ui .hover-blue:focus,.swagger-ui .hover-blue:hover{color:#357edd}.swagger-ui .hover-light-blue:focus,.swagger-ui .hover-light-blue:hover{color:#96ccff}.swagger-ui .hover-lightest-blue:focus,.swagger-ui .hover-lightest-blue:hover{color:#cdecff}.swagger-ui .hover-washed-blue:focus,.swagger-ui .hover-washed-blue:hover{color:#f6fffe}.swagger-ui .hover-washed-green:focus,.swagger-ui .hover-washed-green:hover{color:#e8fdf5}.swagger-ui .hover-washed-yellow:focus,.swagger-ui .hover-washed-yellow:hover{color:#fffceb}.swagger-ui .hover-washed-red:focus,.swagger-ui .hover-washed-red:hover{color:#ffdfdf}.swagger-ui .hover-bg-dark-red:focus,.swagger-ui .hover-bg-dark-red:hover{background-color:#e7040f}.swagger-ui .hover-bg-red:focus,.swagger-ui .hover-bg-red:hover{background-color:#ff4136}.swagger-ui .hover-bg-light-red:focus,.swagger-ui .hover-bg-light-red:hover{background-color:#ff725c}.swagger-ui .hover-bg-orange:focus,.swagger-ui .hover-bg-orange:hover{background-color:#ff6300}.swagger-ui .hover-bg-gold:focus,.swagger-ui .hover-bg-gold:hover{background-color:#ffb700}.swagger-ui .hover-bg-yellow:focus,.swagger-ui .hover-bg-yellow:hover{background-color:gold}.swagger-ui .hover-bg-light-yellow:focus,.swagger-ui .hover-bg-light-yellow:hover{background-color:#fbf1a9}.swagger-ui .hover-bg-purple:focus,.swagger-ui .hover-bg-purple:hover{background-color:#5e2ca5}.swagger-ui .hover-bg-light-purple:focus,.swagger-ui .hover-bg-light-purple:hover{background-color:#a463f2}.swagger-ui .hover-bg-dark-pink:focus,.swagger-ui .hover-bg-dark-pink:hover{background-color:#d5008f}.swagger-ui .hover-bg-hot-pink:focus,.swagger-ui .hover-bg-hot-pink:hover{background-color:#ff41b4}.swagger-ui .hover-bg-pink:focus,.swagger-ui .hover-bg-pink:hover{background-color:#ff80cc}.swagger-ui .hover-bg-light-pink:focus,.swagger-ui .hover-bg-light-pink:hover{background-color:#ffa3d7}.swagger-ui .hover-bg-dark-green:focus,.swagger-ui .hover-bg-dark-green:hover{background-color:#137752}.swagger-ui .hover-bg-green:focus,.swagger-ui .hover-bg-green:hover{background-color:#19a974}.swagger-ui .hover-bg-light-green:focus,.swagger-ui .hover-bg-light-green:hover{background-color:#9eebcf}.swagger-ui .hover-bg-navy:focus,.swagger-ui .hover-bg-navy:hover{background-color:#001b44}.swagger-ui .hover-bg-dark-blue:focus,.swagger-ui .hover-bg-dark-blue:hover{background-color:#00449e}.swagger-ui .hover-bg-blue:focus,.swagger-ui .hover-bg-blue:hover{background-color:#357edd}.swagger-ui .hover-bg-light-blue:focus,.swagger-ui .hover-bg-light-blue:hover{background-color:#96ccff}.swagger-ui .hover-bg-lightest-blue:focus,.swagger-ui .hover-bg-lightest-blue:hover{background-color:#cdecff}.swagger-ui .hover-bg-washed-blue:focus,.swagger-ui .hover-bg-washed-blue:hover{background-color:#f6fffe}.swagger-ui .hover-bg-washed-green:focus,.swagger-ui .hover-bg-washed-green:hover{background-color:#e8fdf5}.swagger-ui .hover-bg-washed-yellow:focus,.swagger-ui .hover-bg-washed-yellow:hover{background-color:#fffceb}.swagger-ui .hover-bg-washed-red:focus,.swagger-ui .hover-bg-washed-red:hover{background-color:#ffdfdf}.swagger-ui .hover-bg-inherit:focus,.swagger-ui .hover-bg-inherit:hover{background-color:inherit}.swagger-ui .pa0{padding:0}.swagger-ui .pa1{padding:.25rem}.swagger-ui .pa2{padding:.5rem}.swagger-ui .pa3{padding:1rem}.swagger-ui .pa4{padding:2rem}.swagger-ui .pa5{padding:4rem}.swagger-ui .pa6{padding:8rem}.swagger-ui .pa7{padding:16rem}.swagger-ui .pl0{padding-left:0}.swagger-ui .pl1{padding-left:.25rem}.swagger-ui .pl2{padding-left:.5rem}.swagger-ui .pl3{padding-left:1rem}.swagger-ui .pl4{padding-left:2rem}.swagger-ui .pl5{padding-left:4rem}.swagger-ui .pl6{padding-left:8rem}.swagger-ui .pl7{padding-left:16rem}.swagger-ui .pr0{padding-right:0}.swagger-ui .pr1{padding-right:.25rem}.swagger-ui .pr2{padding-right:.5rem}.swagger-ui .pr3{padding-right:1rem}.swagger-ui .pr4{padding-right:2rem}.swagger-ui .pr5{padding-right:4rem}.swagger-ui .pr6{padding-right:8rem}.swagger-ui .pr7{padding-right:16rem}.swagger-ui .pb0{padding-bottom:0}.swagger-ui .pb1{padding-bottom:.25rem}.swagger-ui .pb2{padding-bottom:.5rem}.swagger-ui .pb3{padding-bottom:1rem}.swagger-ui .pb4{padding-bottom:2rem}.swagger-ui .pb5{padding-bottom:4rem}.swagger-ui .pb6{padding-bottom:8rem}.swagger-ui .pb7{padding-bottom:16rem}.swagger-ui .pt0{padding-top:0}.swagger-ui .pt1{padding-top:.25rem}.swagger-ui .pt2{padding-top:.5rem}.swagger-ui .pt3{padding-top:1rem}.swagger-ui .pt4{padding-top:2rem}.swagger-ui .pt5{padding-top:4rem}.swagger-ui .pt6{padding-top:8rem}.swagger-ui .pt7{padding-top:16rem}.swagger-ui .pv0{padding-bottom:0;padding-top:0}.swagger-ui .pv1{padding-bottom:.25rem;padding-top:.25rem}.swagger-ui .pv2{padding-bottom:.5rem;padding-top:.5rem}.swagger-ui .pv3{padding-bottom:1rem;padding-top:1rem}.swagger-ui .pv4{padding-bottom:2rem;padding-top:2rem}.swagger-ui .pv5{padding-bottom:4rem;padding-top:4rem}.swagger-ui .pv6{padding-bottom:8rem;padding-top:8rem}.swagger-ui .pv7{padding-bottom:16rem;padding-top:16rem}.swagger-ui .ph0{padding-left:0;padding-right:0}.swagger-ui .ph1{padding-left:.25rem;padding-right:.25rem}.swagger-ui .ph2{padding-left:.5rem;padding-right:.5rem}.swagger-ui .ph3{padding-left:1rem;padding-right:1rem}.swagger-ui .ph4{padding-left:2rem;padding-right:2rem}.swagger-ui .ph5{padding-left:4rem;padding-right:4rem}.swagger-ui .ph6{padding-left:8rem;padding-right:8rem}.swagger-ui .ph7{padding-left:16rem;padding-right:16rem}.swagger-ui .ma0{margin:0}.swagger-ui .ma1{margin:.25rem}.swagger-ui .ma2{margin:.5rem}.swagger-ui .ma3{margin:1rem}.swagger-ui .ma4{margin:2rem}.swagger-ui .ma5{margin:4rem}.swagger-ui .ma6{margin:8rem}.swagger-ui .ma7{margin:16rem}.swagger-ui .ml0{margin-left:0}.swagger-ui .ml1{margin-left:.25rem}.swagger-ui .ml2{margin-left:.5rem}.swagger-ui .ml3{margin-left:1rem}.swagger-ui .ml4{margin-left:2rem}.swagger-ui .ml5{margin-left:4rem}.swagger-ui .ml6{margin-left:8rem}.swagger-ui .ml7{margin-left:16rem}.swagger-ui .mr0{margin-right:0}.swagger-ui .mr1{margin-right:.25rem}.swagger-ui .mr2{margin-right:.5rem}.swagger-ui .mr3{margin-right:1rem}.swagger-ui .mr4{margin-right:2rem}.swagger-ui .mr5{margin-right:4rem}.swagger-ui .mr6{margin-right:8rem}.swagger-ui .mr7{margin-right:16rem}.swagger-ui .mb0{margin-bottom:0}.swagger-ui .mb1{margin-bottom:.25rem}.swagger-ui .mb2{margin-bottom:.5rem}.swagger-ui .mb3{margin-bottom:1rem}.swagger-ui .mb4{margin-bottom:2rem}.swagger-ui .mb5{margin-bottom:4rem}.swagger-ui .mb6{margin-bottom:8rem}.swagger-ui .mb7{margin-bottom:16rem}.swagger-ui .mt0{margin-top:0}.swagger-ui .mt1{margin-top:.25rem}.swagger-ui .mt2{margin-top:.5rem}.swagger-ui .mt3{margin-top:1rem}.swagger-ui .mt4{margin-top:2rem}.swagger-ui .mt5{margin-top:4rem}.swagger-ui .mt6{margin-top:8rem}.swagger-ui .mt7{margin-top:16rem}.swagger-ui .mv0{margin-bottom:0;margin-top:0}.swagger-ui .mv1{margin-bottom:.25rem;margin-top:.25rem}.swagger-ui .mv2{margin-bottom:.5rem;margin-top:.5rem}.swagger-ui .mv3{margin-bottom:1rem;margin-top:1rem}.swagger-ui .mv4{margin-bottom:2rem;margin-top:2rem}.swagger-ui .mv5{margin-bottom:4rem;margin-top:4rem}.swagger-ui .mv6{margin-bottom:8rem;margin-top:8rem}.swagger-ui .mv7{margin-bottom:16rem;margin-top:16rem}.swagger-ui .mh0{margin-left:0;margin-right:0}.swagger-ui .mh1{margin-left:.25rem;margin-right:.25rem}.swagger-ui .mh2{margin-left:.5rem;margin-right:.5rem}.swagger-ui .mh3{margin-left:1rem;margin-right:1rem}.swagger-ui .mh4{margin-left:2rem;margin-right:2rem}.swagger-ui .mh5{margin-left:4rem;margin-right:4rem}.swagger-ui .mh6{margin-left:8rem;margin-right:8rem}.swagger-ui .mh7{margin-left:16rem;margin-right:16rem}@media screen and (min-width:30em){.swagger-ui .pa0-ns{padding:0}.swagger-ui .pa1-ns{padding:.25rem}.swagger-ui .pa2-ns{padding:.5rem}.swagger-ui .pa3-ns{padding:1rem}.swagger-ui .pa4-ns{padding:2rem}.swagger-ui .pa5-ns{padding:4rem}.swagger-ui .pa6-ns{padding:8rem}.swagger-ui .pa7-ns{padding:16rem}.swagger-ui .pl0-ns{padding-left:0}.swagger-ui .pl1-ns{padding-left:.25rem}.swagger-ui .pl2-ns{padding-left:.5rem}.swagger-ui .pl3-ns{padding-left:1rem}.swagger-ui .pl4-ns{padding-left:2rem}.swagger-ui .pl5-ns{padding-left:4rem}.swagger-ui .pl6-ns{padding-left:8rem}.swagger-ui .pl7-ns{padding-left:16rem}.swagger-ui .pr0-ns{padding-right:0}.swagger-ui .pr1-ns{padding-right:.25rem}.swagger-ui .pr2-ns{padding-right:.5rem}.swagger-ui .pr3-ns{padding-right:1rem}.swagger-ui .pr4-ns{padding-right:2rem}.swagger-ui .pr5-ns{padding-right:4rem}.swagger-ui .pr6-ns{padding-right:8rem}.swagger-ui .pr7-ns{padding-right:16rem}.swagger-ui .pb0-ns{padding-bottom:0}.swagger-ui .pb1-ns{padding-bottom:.25rem}.swagger-ui .pb2-ns{padding-bottom:.5rem}.swagger-ui .pb3-ns{padding-bottom:1rem}.swagger-ui .pb4-ns{padding-bottom:2rem}.swagger-ui .pb5-ns{padding-bottom:4rem}.swagger-ui .pb6-ns{padding-bottom:8rem}.swagger-ui .pb7-ns{padding-bottom:16rem}.swagger-ui .pt0-ns{padding-top:0}.swagger-ui .pt1-ns{padding-top:.25rem}.swagger-ui .pt2-ns{padding-top:.5rem}.swagger-ui .pt3-ns{padding-top:1rem}.swagger-ui .pt4-ns{padding-top:2rem}.swagger-ui .pt5-ns{padding-top:4rem}.swagger-ui .pt6-ns{padding-top:8rem}.swagger-ui .pt7-ns{padding-top:16rem}.swagger-ui .pv0-ns{padding-bottom:0;padding-top:0}.swagger-ui .pv1-ns{padding-bottom:.25rem;padding-top:.25rem}.swagger-ui .pv2-ns{padding-bottom:.5rem;padding-top:.5rem}.swagger-ui .pv3-ns{padding-bottom:1rem;padding-top:1rem}.swagger-ui .pv4-ns{padding-bottom:2rem;padding-top:2rem}.swagger-ui .pv5-ns{padding-bottom:4rem;padding-top:4rem}.swagger-ui .pv6-ns{padding-bottom:8rem;padding-top:8rem}.swagger-ui .pv7-ns{padding-bottom:16rem;padding-top:16rem}.swagger-ui .ph0-ns{padding-left:0;padding-right:0}.swagger-ui .ph1-ns{padding-left:.25rem;padding-right:.25rem}.swagger-ui .ph2-ns{padding-left:.5rem;padding-right:.5rem}.swagger-ui .ph3-ns{padding-left:1rem;padding-right:1rem}.swagger-ui .ph4-ns{padding-left:2rem;padding-right:2rem}.swagger-ui .ph5-ns{padding-left:4rem;padding-right:4rem}.swagger-ui .ph6-ns{padding-left:8rem;padding-right:8rem}.swagger-ui .ph7-ns{padding-left:16rem;padding-right:16rem}.swagger-ui .ma0-ns{margin:0}.swagger-ui .ma1-ns{margin:.25rem}.swagger-ui .ma2-ns{margin:.5rem}.swagger-ui .ma3-ns{margin:1rem}.swagger-ui .ma4-ns{margin:2rem}.swagger-ui .ma5-ns{margin:4rem}.swagger-ui .ma6-ns{margin:8rem}.swagger-ui .ma7-ns{margin:16rem}.swagger-ui .ml0-ns{margin-left:0}.swagger-ui .ml1-ns{margin-left:.25rem}.swagger-ui .ml2-ns{margin-left:.5rem}.swagger-ui .ml3-ns{margin-left:1rem}.swagger-ui .ml4-ns{margin-left:2rem}.swagger-ui .ml5-ns{margin-left:4rem}.swagger-ui .ml6-ns{margin-left:8rem}.swagger-ui .ml7-ns{margin-left:16rem}.swagger-ui .mr0-ns{margin-right:0}.swagger-ui .mr1-ns{margin-right:.25rem}.swagger-ui .mr2-ns{margin-right:.5rem}.swagger-ui .mr3-ns{margin-right:1rem}.swagger-ui .mr4-ns{margin-right:2rem}.swagger-ui .mr5-ns{margin-right:4rem}.swagger-ui .mr6-ns{margin-right:8rem}.swagger-ui .mr7-ns{margin-right:16rem}.swagger-ui .mb0-ns{margin-bottom:0}.swagger-ui .mb1-ns{margin-bottom:.25rem}.swagger-ui .mb2-ns{margin-bottom:.5rem}.swagger-ui .mb3-ns{margin-bottom:1rem}.swagger-ui .mb4-ns{margin-bottom:2rem}.swagger-ui .mb5-ns{margin-bottom:4rem}.swagger-ui .mb6-ns{margin-bottom:8rem}.swagger-ui .mb7-ns{margin-bottom:16rem}.swagger-ui .mt0-ns{margin-top:0}.swagger-ui .mt1-ns{margin-top:.25rem}.swagger-ui .mt2-ns{margin-top:.5rem}.swagger-ui .mt3-ns{margin-top:1rem}.swagger-ui .mt4-ns{margin-top:2rem}.swagger-ui .mt5-ns{margin-top:4rem}.swagger-ui .mt6-ns{margin-top:8rem}.swagger-ui .mt7-ns{margin-top:16rem}.swagger-ui .mv0-ns{margin-bottom:0;margin-top:0}.swagger-ui .mv1-ns{margin-bottom:.25rem;margin-top:.25rem}.swagger-ui .mv2-ns{margin-bottom:.5rem;margin-top:.5rem}.swagger-ui .mv3-ns{margin-bottom:1rem;margin-top:1rem}.swagger-ui .mv4-ns{margin-bottom:2rem;margin-top:2rem}.swagger-ui .mv5-ns{margin-bottom:4rem;margin-top:4rem}.swagger-ui .mv6-ns{margin-bottom:8rem;margin-top:8rem}.swagger-ui .mv7-ns{margin-bottom:16rem;margin-top:16rem}.swagger-ui .mh0-ns{margin-left:0;margin-right:0}.swagger-ui .mh1-ns{margin-left:.25rem;margin-right:.25rem}.swagger-ui .mh2-ns{margin-left:.5rem;margin-right:.5rem}.swagger-ui .mh3-ns{margin-left:1rem;margin-right:1rem}.swagger-ui .mh4-ns{margin-left:2rem;margin-right:2rem}.swagger-ui .mh5-ns{margin-left:4rem;margin-right:4rem}.swagger-ui .mh6-ns{margin-left:8rem;margin-right:8rem}.swagger-ui .mh7-ns{margin-left:16rem;margin-right:16rem}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .pa0-m{padding:0}.swagger-ui .pa1-m{padding:.25rem}.swagger-ui .pa2-m{padding:.5rem}.swagger-ui .pa3-m{padding:1rem}.swagger-ui .pa4-m{padding:2rem}.swagger-ui .pa5-m{padding:4rem}.swagger-ui .pa6-m{padding:8rem}.swagger-ui .pa7-m{padding:16rem}.swagger-ui .pl0-m{padding-left:0}.swagger-ui .pl1-m{padding-left:.25rem}.swagger-ui .pl2-m{padding-left:.5rem}.swagger-ui .pl3-m{padding-left:1rem}.swagger-ui .pl4-m{padding-left:2rem}.swagger-ui .pl5-m{padding-left:4rem}.swagger-ui .pl6-m{padding-left:8rem}.swagger-ui .pl7-m{padding-left:16rem}.swagger-ui .pr0-m{padding-right:0}.swagger-ui .pr1-m{padding-right:.25rem}.swagger-ui .pr2-m{padding-right:.5rem}.swagger-ui .pr3-m{padding-right:1rem}.swagger-ui .pr4-m{padding-right:2rem}.swagger-ui .pr5-m{padding-right:4rem}.swagger-ui .pr6-m{padding-right:8rem}.swagger-ui .pr7-m{padding-right:16rem}.swagger-ui .pb0-m{padding-bottom:0}.swagger-ui .pb1-m{padding-bottom:.25rem}.swagger-ui .pb2-m{padding-bottom:.5rem}.swagger-ui .pb3-m{padding-bottom:1rem}.swagger-ui .pb4-m{padding-bottom:2rem}.swagger-ui .pb5-m{padding-bottom:4rem}.swagger-ui .pb6-m{padding-bottom:8rem}.swagger-ui .pb7-m{padding-bottom:16rem}.swagger-ui .pt0-m{padding-top:0}.swagger-ui .pt1-m{padding-top:.25rem}.swagger-ui .pt2-m{padding-top:.5rem}.swagger-ui .pt3-m{padding-top:1rem}.swagger-ui .pt4-m{padding-top:2rem}.swagger-ui .pt5-m{padding-top:4rem}.swagger-ui .pt6-m{padding-top:8rem}.swagger-ui .pt7-m{padding-top:16rem}.swagger-ui .pv0-m{padding-bottom:0;padding-top:0}.swagger-ui .pv1-m{padding-bottom:.25rem;padding-top:.25rem}.swagger-ui .pv2-m{padding-bottom:.5rem;padding-top:.5rem}.swagger-ui .pv3-m{padding-bottom:1rem;padding-top:1rem}.swagger-ui .pv4-m{padding-bottom:2rem;padding-top:2rem}.swagger-ui .pv5-m{padding-bottom:4rem;padding-top:4rem}.swagger-ui .pv6-m{padding-bottom:8rem;padding-top:8rem}.swagger-ui .pv7-m{padding-bottom:16rem;padding-top:16rem}.swagger-ui .ph0-m{padding-left:0;padding-right:0}.swagger-ui .ph1-m{padding-left:.25rem;padding-right:.25rem}.swagger-ui .ph2-m{padding-left:.5rem;padding-right:.5rem}.swagger-ui .ph3-m{padding-left:1rem;padding-right:1rem}.swagger-ui .ph4-m{padding-left:2rem;padding-right:2rem}.swagger-ui .ph5-m{padding-left:4rem;padding-right:4rem}.swagger-ui .ph6-m{padding-left:8rem;padding-right:8rem}.swagger-ui .ph7-m{padding-left:16rem;padding-right:16rem}.swagger-ui .ma0-m{margin:0}.swagger-ui .ma1-m{margin:.25rem}.swagger-ui .ma2-m{margin:.5rem}.swagger-ui .ma3-m{margin:1rem}.swagger-ui .ma4-m{margin:2rem}.swagger-ui .ma5-m{margin:4rem}.swagger-ui .ma6-m{margin:8rem}.swagger-ui .ma7-m{margin:16rem}.swagger-ui .ml0-m{margin-left:0}.swagger-ui .ml1-m{margin-left:.25rem}.swagger-ui .ml2-m{margin-left:.5rem}.swagger-ui .ml3-m{margin-left:1rem}.swagger-ui .ml4-m{margin-left:2rem}.swagger-ui .ml5-m{margin-left:4rem}.swagger-ui .ml6-m{margin-left:8rem}.swagger-ui .ml7-m{margin-left:16rem}.swagger-ui .mr0-m{margin-right:0}.swagger-ui .mr1-m{margin-right:.25rem}.swagger-ui .mr2-m{margin-right:.5rem}.swagger-ui .mr3-m{margin-right:1rem}.swagger-ui .mr4-m{margin-right:2rem}.swagger-ui .mr5-m{margin-right:4rem}.swagger-ui .mr6-m{margin-right:8rem}.swagger-ui .mr7-m{margin-right:16rem}.swagger-ui .mb0-m{margin-bottom:0}.swagger-ui .mb1-m{margin-bottom:.25rem}.swagger-ui .mb2-m{margin-bottom:.5rem}.swagger-ui .mb3-m{margin-bottom:1rem}.swagger-ui .mb4-m{margin-bottom:2rem}.swagger-ui .mb5-m{margin-bottom:4rem}.swagger-ui .mb6-m{margin-bottom:8rem}.swagger-ui .mb7-m{margin-bottom:16rem}.swagger-ui .mt0-m{margin-top:0}.swagger-ui .mt1-m{margin-top:.25rem}.swagger-ui .mt2-m{margin-top:.5rem}.swagger-ui .mt3-m{margin-top:1rem}.swagger-ui .mt4-m{margin-top:2rem}.swagger-ui .mt5-m{margin-top:4rem}.swagger-ui .mt6-m{margin-top:8rem}.swagger-ui .mt7-m{margin-top:16rem}.swagger-ui .mv0-m{margin-bottom:0;margin-top:0}.swagger-ui .mv1-m{margin-bottom:.25rem;margin-top:.25rem}.swagger-ui .mv2-m{margin-bottom:.5rem;margin-top:.5rem}.swagger-ui .mv3-m{margin-bottom:1rem;margin-top:1rem}.swagger-ui .mv4-m{margin-bottom:2rem;margin-top:2rem}.swagger-ui .mv5-m{margin-bottom:4rem;margin-top:4rem}.swagger-ui .mv6-m{margin-bottom:8rem;margin-top:8rem}.swagger-ui .mv7-m{margin-bottom:16rem;margin-top:16rem}.swagger-ui .mh0-m{margin-left:0;margin-right:0}.swagger-ui .mh1-m{margin-left:.25rem;margin-right:.25rem}.swagger-ui .mh2-m{margin-left:.5rem;margin-right:.5rem}.swagger-ui .mh3-m{margin-left:1rem;margin-right:1rem}.swagger-ui .mh4-m{margin-left:2rem;margin-right:2rem}.swagger-ui .mh5-m{margin-left:4rem;margin-right:4rem}.swagger-ui .mh6-m{margin-left:8rem;margin-right:8rem}.swagger-ui .mh7-m{margin-left:16rem;margin-right:16rem}}@media screen and (min-width:60em){.swagger-ui .pa0-l{padding:0}.swagger-ui .pa1-l{padding:.25rem}.swagger-ui .pa2-l{padding:.5rem}.swagger-ui .pa3-l{padding:1rem}.swagger-ui .pa4-l{padding:2rem}.swagger-ui .pa5-l{padding:4rem}.swagger-ui .pa6-l{padding:8rem}.swagger-ui .pa7-l{padding:16rem}.swagger-ui .pl0-l{padding-left:0}.swagger-ui .pl1-l{padding-left:.25rem}.swagger-ui .pl2-l{padding-left:.5rem}.swagger-ui .pl3-l{padding-left:1rem}.swagger-ui .pl4-l{padding-left:2rem}.swagger-ui .pl5-l{padding-left:4rem}.swagger-ui .pl6-l{padding-left:8rem}.swagger-ui .pl7-l{padding-left:16rem}.swagger-ui .pr0-l{padding-right:0}.swagger-ui .pr1-l{padding-right:.25rem}.swagger-ui .pr2-l{padding-right:.5rem}.swagger-ui .pr3-l{padding-right:1rem}.swagger-ui .pr4-l{padding-right:2rem}.swagger-ui .pr5-l{padding-right:4rem}.swagger-ui .pr6-l{padding-right:8rem}.swagger-ui .pr7-l{padding-right:16rem}.swagger-ui .pb0-l{padding-bottom:0}.swagger-ui .pb1-l{padding-bottom:.25rem}.swagger-ui .pb2-l{padding-bottom:.5rem}.swagger-ui .pb3-l{padding-bottom:1rem}.swagger-ui .pb4-l{padding-bottom:2rem}.swagger-ui .pb5-l{padding-bottom:4rem}.swagger-ui .pb6-l{padding-bottom:8rem}.swagger-ui .pb7-l{padding-bottom:16rem}.swagger-ui .pt0-l{padding-top:0}.swagger-ui .pt1-l{padding-top:.25rem}.swagger-ui .pt2-l{padding-top:.5rem}.swagger-ui .pt3-l{padding-top:1rem}.swagger-ui .pt4-l{padding-top:2rem}.swagger-ui .pt5-l{padding-top:4rem}.swagger-ui .pt6-l{padding-top:8rem}.swagger-ui .pt7-l{padding-top:16rem}.swagger-ui .pv0-l{padding-bottom:0;padding-top:0}.swagger-ui .pv1-l{padding-bottom:.25rem;padding-top:.25rem}.swagger-ui .pv2-l{padding-bottom:.5rem;padding-top:.5rem}.swagger-ui .pv3-l{padding-bottom:1rem;padding-top:1rem}.swagger-ui .pv4-l{padding-bottom:2rem;padding-top:2rem}.swagger-ui .pv5-l{padding-bottom:4rem;padding-top:4rem}.swagger-ui .pv6-l{padding-bottom:8rem;padding-top:8rem}.swagger-ui .pv7-l{padding-bottom:16rem;padding-top:16rem}.swagger-ui .ph0-l{padding-left:0;padding-right:0}.swagger-ui .ph1-l{padding-left:.25rem;padding-right:.25rem}.swagger-ui .ph2-l{padding-left:.5rem;padding-right:.5rem}.swagger-ui .ph3-l{padding-left:1rem;padding-right:1rem}.swagger-ui .ph4-l{padding-left:2rem;padding-right:2rem}.swagger-ui .ph5-l{padding-left:4rem;padding-right:4rem}.swagger-ui .ph6-l{padding-left:8rem;padding-right:8rem}.swagger-ui .ph7-l{padding-left:16rem;padding-right:16rem}.swagger-ui .ma0-l{margin:0}.swagger-ui .ma1-l{margin:.25rem}.swagger-ui .ma2-l{margin:.5rem}.swagger-ui .ma3-l{margin:1rem}.swagger-ui .ma4-l{margin:2rem}.swagger-ui .ma5-l{margin:4rem}.swagger-ui .ma6-l{margin:8rem}.swagger-ui .ma7-l{margin:16rem}.swagger-ui .ml0-l{margin-left:0}.swagger-ui .ml1-l{margin-left:.25rem}.swagger-ui .ml2-l{margin-left:.5rem}.swagger-ui .ml3-l{margin-left:1rem}.swagger-ui .ml4-l{margin-left:2rem}.swagger-ui .ml5-l{margin-left:4rem}.swagger-ui .ml6-l{margin-left:8rem}.swagger-ui .ml7-l{margin-left:16rem}.swagger-ui .mr0-l{margin-right:0}.swagger-ui .mr1-l{margin-right:.25rem}.swagger-ui .mr2-l{margin-right:.5rem}.swagger-ui .mr3-l{margin-right:1rem}.swagger-ui .mr4-l{margin-right:2rem}.swagger-ui .mr5-l{margin-right:4rem}.swagger-ui .mr6-l{margin-right:8rem}.swagger-ui .mr7-l{margin-right:16rem}.swagger-ui .mb0-l{margin-bottom:0}.swagger-ui .mb1-l{margin-bottom:.25rem}.swagger-ui .mb2-l{margin-bottom:.5rem}.swagger-ui .mb3-l{margin-bottom:1rem}.swagger-ui .mb4-l{margin-bottom:2rem}.swagger-ui .mb5-l{margin-bottom:4rem}.swagger-ui .mb6-l{margin-bottom:8rem}.swagger-ui .mb7-l{margin-bottom:16rem}.swagger-ui .mt0-l{margin-top:0}.swagger-ui .mt1-l{margin-top:.25rem}.swagger-ui .mt2-l{margin-top:.5rem}.swagger-ui .mt3-l{margin-top:1rem}.swagger-ui .mt4-l{margin-top:2rem}.swagger-ui .mt5-l{margin-top:4rem}.swagger-ui .mt6-l{margin-top:8rem}.swagger-ui .mt7-l{margin-top:16rem}.swagger-ui .mv0-l{margin-bottom:0;margin-top:0}.swagger-ui .mv1-l{margin-bottom:.25rem;margin-top:.25rem}.swagger-ui .mv2-l{margin-bottom:.5rem;margin-top:.5rem}.swagger-ui .mv3-l{margin-bottom:1rem;margin-top:1rem}.swagger-ui .mv4-l{margin-bottom:2rem;margin-top:2rem}.swagger-ui .mv5-l{margin-bottom:4rem;margin-top:4rem}.swagger-ui .mv6-l{margin-bottom:8rem;margin-top:8rem}.swagger-ui .mv7-l{margin-bottom:16rem;margin-top:16rem}.swagger-ui .mh0-l{margin-left:0;margin-right:0}.swagger-ui .mh1-l{margin-left:.25rem;margin-right:.25rem}.swagger-ui .mh2-l{margin-left:.5rem;margin-right:.5rem}.swagger-ui .mh3-l{margin-left:1rem;margin-right:1rem}.swagger-ui .mh4-l{margin-left:2rem;margin-right:2rem}.swagger-ui .mh5-l{margin-left:4rem;margin-right:4rem}.swagger-ui .mh6-l{margin-left:8rem;margin-right:8rem}.swagger-ui .mh7-l{margin-left:16rem;margin-right:16rem}}.swagger-ui .na1{margin:-.25rem}.swagger-ui .na2{margin:-.5rem}.swagger-ui .na3{margin:-1rem}.swagger-ui .na4{margin:-2rem}.swagger-ui .na5{margin:-4rem}.swagger-ui .na6{margin:-8rem}.swagger-ui .na7{margin:-16rem}.swagger-ui .nl1{margin-left:-.25rem}.swagger-ui .nl2{margin-left:-.5rem}.swagger-ui .nl3{margin-left:-1rem}.swagger-ui .nl4{margin-left:-2rem}.swagger-ui .nl5{margin-left:-4rem}.swagger-ui .nl6{margin-left:-8rem}.swagger-ui .nl7{margin-left:-16rem}.swagger-ui .nr1{margin-right:-.25rem}.swagger-ui .nr2{margin-right:-.5rem}.swagger-ui .nr3{margin-right:-1rem}.swagger-ui .nr4{margin-right:-2rem}.swagger-ui .nr5{margin-right:-4rem}.swagger-ui .nr6{margin-right:-8rem}.swagger-ui .nr7{margin-right:-16rem}.swagger-ui .nb1{margin-bottom:-.25rem}.swagger-ui .nb2{margin-bottom:-.5rem}.swagger-ui .nb3{margin-bottom:-1rem}.swagger-ui .nb4{margin-bottom:-2rem}.swagger-ui .nb5{margin-bottom:-4rem}.swagger-ui .nb6{margin-bottom:-8rem}.swagger-ui .nb7{margin-bottom:-16rem}.swagger-ui .nt1{margin-top:-.25rem}.swagger-ui .nt2{margin-top:-.5rem}.swagger-ui .nt3{margin-top:-1rem}.swagger-ui .nt4{margin-top:-2rem}.swagger-ui .nt5{margin-top:-4rem}.swagger-ui .nt6{margin-top:-8rem}.swagger-ui .nt7{margin-top:-16rem}@media screen and (min-width:30em){.swagger-ui .na1-ns{margin:-.25rem}.swagger-ui .na2-ns{margin:-.5rem}.swagger-ui .na3-ns{margin:-1rem}.swagger-ui .na4-ns{margin:-2rem}.swagger-ui .na5-ns{margin:-4rem}.swagger-ui .na6-ns{margin:-8rem}.swagger-ui .na7-ns{margin:-16rem}.swagger-ui .nl1-ns{margin-left:-.25rem}.swagger-ui .nl2-ns{margin-left:-.5rem}.swagger-ui .nl3-ns{margin-left:-1rem}.swagger-ui .nl4-ns{margin-left:-2rem}.swagger-ui .nl5-ns{margin-left:-4rem}.swagger-ui .nl6-ns{margin-left:-8rem}.swagger-ui .nl7-ns{margin-left:-16rem}.swagger-ui .nr1-ns{margin-right:-.25rem}.swagger-ui .nr2-ns{margin-right:-.5rem}.swagger-ui .nr3-ns{margin-right:-1rem}.swagger-ui .nr4-ns{margin-right:-2rem}.swagger-ui .nr5-ns{margin-right:-4rem}.swagger-ui .nr6-ns{margin-right:-8rem}.swagger-ui .nr7-ns{margin-right:-16rem}.swagger-ui .nb1-ns{margin-bottom:-.25rem}.swagger-ui .nb2-ns{margin-bottom:-.5rem}.swagger-ui .nb3-ns{margin-bottom:-1rem}.swagger-ui .nb4-ns{margin-bottom:-2rem}.swagger-ui .nb5-ns{margin-bottom:-4rem}.swagger-ui .nb6-ns{margin-bottom:-8rem}.swagger-ui .nb7-ns{margin-bottom:-16rem}.swagger-ui .nt1-ns{margin-top:-.25rem}.swagger-ui .nt2-ns{margin-top:-.5rem}.swagger-ui .nt3-ns{margin-top:-1rem}.swagger-ui .nt4-ns{margin-top:-2rem}.swagger-ui .nt5-ns{margin-top:-4rem}.swagger-ui .nt6-ns{margin-top:-8rem}.swagger-ui .nt7-ns{margin-top:-16rem}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .na1-m{margin:-.25rem}.swagger-ui .na2-m{margin:-.5rem}.swagger-ui .na3-m{margin:-1rem}.swagger-ui .na4-m{margin:-2rem}.swagger-ui .na5-m{margin:-4rem}.swagger-ui .na6-m{margin:-8rem}.swagger-ui .na7-m{margin:-16rem}.swagger-ui .nl1-m{margin-left:-.25rem}.swagger-ui .nl2-m{margin-left:-.5rem}.swagger-ui .nl3-m{margin-left:-1rem}.swagger-ui .nl4-m{margin-left:-2rem}.swagger-ui .nl5-m{margin-left:-4rem}.swagger-ui .nl6-m{margin-left:-8rem}.swagger-ui .nl7-m{margin-left:-16rem}.swagger-ui .nr1-m{margin-right:-.25rem}.swagger-ui .nr2-m{margin-right:-.5rem}.swagger-ui .nr3-m{margin-right:-1rem}.swagger-ui .nr4-m{margin-right:-2rem}.swagger-ui .nr5-m{margin-right:-4rem}.swagger-ui .nr6-m{margin-right:-8rem}.swagger-ui .nr7-m{margin-right:-16rem}.swagger-ui .nb1-m{margin-bottom:-.25rem}.swagger-ui .nb2-m{margin-bottom:-.5rem}.swagger-ui .nb3-m{margin-bottom:-1rem}.swagger-ui .nb4-m{margin-bottom:-2rem}.swagger-ui .nb5-m{margin-bottom:-4rem}.swagger-ui .nb6-m{margin-bottom:-8rem}.swagger-ui .nb7-m{margin-bottom:-16rem}.swagger-ui .nt1-m{margin-top:-.25rem}.swagger-ui .nt2-m{margin-top:-.5rem}.swagger-ui .nt3-m{margin-top:-1rem}.swagger-ui .nt4-m{margin-top:-2rem}.swagger-ui .nt5-m{margin-top:-4rem}.swagger-ui .nt6-m{margin-top:-8rem}.swagger-ui .nt7-m{margin-top:-16rem}}@media screen and (min-width:60em){.swagger-ui .na1-l{margin:-.25rem}.swagger-ui .na2-l{margin:-.5rem}.swagger-ui .na3-l{margin:-1rem}.swagger-ui .na4-l{margin:-2rem}.swagger-ui .na5-l{margin:-4rem}.swagger-ui .na6-l{margin:-8rem}.swagger-ui .na7-l{margin:-16rem}.swagger-ui .nl1-l{margin-left:-.25rem}.swagger-ui .nl2-l{margin-left:-.5rem}.swagger-ui .nl3-l{margin-left:-1rem}.swagger-ui .nl4-l{margin-left:-2rem}.swagger-ui .nl5-l{margin-left:-4rem}.swagger-ui .nl6-l{margin-left:-8rem}.swagger-ui .nl7-l{margin-left:-16rem}.swagger-ui .nr1-l{margin-right:-.25rem}.swagger-ui .nr2-l{margin-right:-.5rem}.swagger-ui .nr3-l{margin-right:-1rem}.swagger-ui .nr4-l{margin-right:-2rem}.swagger-ui .nr5-l{margin-right:-4rem}.swagger-ui .nr6-l{margin-right:-8rem}.swagger-ui .nr7-l{margin-right:-16rem}.swagger-ui .nb1-l{margin-bottom:-.25rem}.swagger-ui .nb2-l{margin-bottom:-.5rem}.swagger-ui .nb3-l{margin-bottom:-1rem}.swagger-ui .nb4-l{margin-bottom:-2rem}.swagger-ui .nb5-l{margin-bottom:-4rem}.swagger-ui .nb6-l{margin-bottom:-8rem}.swagger-ui .nb7-l{margin-bottom:-16rem}.swagger-ui .nt1-l{margin-top:-.25rem}.swagger-ui .nt2-l{margin-top:-.5rem}.swagger-ui .nt3-l{margin-top:-1rem}.swagger-ui .nt4-l{margin-top:-2rem}.swagger-ui .nt5-l{margin-top:-4rem}.swagger-ui .nt6-l{margin-top:-8rem}.swagger-ui .nt7-l{margin-top:-16rem}}.swagger-ui .collapse{border-collapse:collapse;border-spacing:0}.swagger-ui .striped--light-silver:nth-child(odd){background-color:#aaa}.swagger-ui .striped--moon-gray:nth-child(odd){background-color:#ccc}.swagger-ui .striped--light-gray:nth-child(odd){background-color:#eee}.swagger-ui .striped--near-white:nth-child(odd){background-color:#f4f4f4}.swagger-ui .stripe-light:nth-child(odd){background-color:hsla(0,0%,100%,.1)}.swagger-ui .stripe-dark:nth-child(odd){background-color:rgba(0,0,0,.1)}.swagger-ui .strike{-webkit-text-decoration:line-through;text-decoration:line-through}.swagger-ui .underline{-webkit-text-decoration:underline;text-decoration:underline}.swagger-ui .no-underline{-webkit-text-decoration:none;text-decoration:none}@media screen and (min-width:30em){.swagger-ui .strike-ns{-webkit-text-decoration:line-through;text-decoration:line-through}.swagger-ui .underline-ns{-webkit-text-decoration:underline;text-decoration:underline}.swagger-ui .no-underline-ns{-webkit-text-decoration:none;text-decoration:none}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .strike-m{-webkit-text-decoration:line-through;text-decoration:line-through}.swagger-ui .underline-m{-webkit-text-decoration:underline;text-decoration:underline}.swagger-ui .no-underline-m{-webkit-text-decoration:none;text-decoration:none}}@media screen and (min-width:60em){.swagger-ui .strike-l{-webkit-text-decoration:line-through;text-decoration:line-through}.swagger-ui .underline-l{-webkit-text-decoration:underline;text-decoration:underline}.swagger-ui .no-underline-l{-webkit-text-decoration:none;text-decoration:none}}.swagger-ui .tl{text-align:left}.swagger-ui .tr{text-align:right}.swagger-ui .tc{text-align:center}.swagger-ui .tj{text-align:justify}@media screen and (min-width:30em){.swagger-ui .tl-ns{text-align:left}.swagger-ui .tr-ns{text-align:right}.swagger-ui .tc-ns{text-align:center}.swagger-ui .tj-ns{text-align:justify}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .tl-m{text-align:left}.swagger-ui .tr-m{text-align:right}.swagger-ui .tc-m{text-align:center}.swagger-ui .tj-m{text-align:justify}}@media screen and (min-width:60em){.swagger-ui .tl-l{text-align:left}.swagger-ui .tr-l{text-align:right}.swagger-ui .tc-l{text-align:center}.swagger-ui .tj-l{text-align:justify}}.swagger-ui .ttc{text-transform:capitalize}.swagger-ui .ttl{text-transform:lowercase}.swagger-ui .ttu{text-transform:uppercase}.swagger-ui .ttn{text-transform:none}@media screen and (min-width:30em){.swagger-ui .ttc-ns{text-transform:capitalize}.swagger-ui .ttl-ns{text-transform:lowercase}.swagger-ui .ttu-ns{text-transform:uppercase}.swagger-ui .ttn-ns{text-transform:none}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .ttc-m{text-transform:capitalize}.swagger-ui .ttl-m{text-transform:lowercase}.swagger-ui .ttu-m{text-transform:uppercase}.swagger-ui .ttn-m{text-transform:none}}@media screen and (min-width:60em){.swagger-ui .ttc-l{text-transform:capitalize}.swagger-ui .ttl-l{text-transform:lowercase}.swagger-ui .ttu-l{text-transform:uppercase}.swagger-ui .ttn-l{text-transform:none}}.swagger-ui .f-6,.swagger-ui .f-headline{font-size:6rem}.swagger-ui .f-5,.swagger-ui .f-subheadline{font-size:5rem}.swagger-ui .f1{font-size:3rem}.swagger-ui .f2{font-size:2.25rem}.swagger-ui .f3{font-size:1.5rem}.swagger-ui .f4{font-size:1.25rem}.swagger-ui .f5{font-size:1rem}.swagger-ui .f6{font-size:.875rem}.swagger-ui .f7{font-size:.75rem}@media screen and (min-width:30em){.swagger-ui .f-6-ns,.swagger-ui .f-headline-ns{font-size:6rem}.swagger-ui .f-5-ns,.swagger-ui .f-subheadline-ns{font-size:5rem}.swagger-ui .f1-ns{font-size:3rem}.swagger-ui .f2-ns{font-size:2.25rem}.swagger-ui .f3-ns{font-size:1.5rem}.swagger-ui .f4-ns{font-size:1.25rem}.swagger-ui .f5-ns{font-size:1rem}.swagger-ui .f6-ns{font-size:.875rem}.swagger-ui .f7-ns{font-size:.75rem}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .f-6-m,.swagger-ui .f-headline-m{font-size:6rem}.swagger-ui .f-5-m,.swagger-ui .f-subheadline-m{font-size:5rem}.swagger-ui .f1-m{font-size:3rem}.swagger-ui .f2-m{font-size:2.25rem}.swagger-ui .f3-m{font-size:1.5rem}.swagger-ui .f4-m{font-size:1.25rem}.swagger-ui .f5-m{font-size:1rem}.swagger-ui .f6-m{font-size:.875rem}.swagger-ui .f7-m{font-size:.75rem}}@media screen and (min-width:60em){.swagger-ui .f-6-l,.swagger-ui .f-headline-l{font-size:6rem}.swagger-ui .f-5-l,.swagger-ui .f-subheadline-l{font-size:5rem}.swagger-ui .f1-l{font-size:3rem}.swagger-ui .f2-l{font-size:2.25rem}.swagger-ui .f3-l{font-size:1.5rem}.swagger-ui .f4-l{font-size:1.25rem}.swagger-ui .f5-l{font-size:1rem}.swagger-ui .f6-l{font-size:.875rem}.swagger-ui .f7-l{font-size:.75rem}}.swagger-ui .measure{max-width:30em}.swagger-ui .measure-wide{max-width:34em}.swagger-ui .measure-narrow{max-width:20em}.swagger-ui .indent{margin-bottom:0;margin-top:0;text-indent:1em}.swagger-ui .small-caps{font-feature-settings:\"smcp\";font-variant:small-caps}.swagger-ui .truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@media screen and (min-width:30em){.swagger-ui .measure-ns{max-width:30em}.swagger-ui .measure-wide-ns{max-width:34em}.swagger-ui .measure-narrow-ns{max-width:20em}.swagger-ui .indent-ns{margin-bottom:0;margin-top:0;text-indent:1em}.swagger-ui .small-caps-ns{font-feature-settings:\"smcp\";font-variant:small-caps}.swagger-ui .truncate-ns{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .measure-m{max-width:30em}.swagger-ui .measure-wide-m{max-width:34em}.swagger-ui .measure-narrow-m{max-width:20em}.swagger-ui .indent-m{margin-bottom:0;margin-top:0;text-indent:1em}.swagger-ui .small-caps-m{font-feature-settings:\"smcp\";font-variant:small-caps}.swagger-ui .truncate-m{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}}@media screen and (min-width:60em){.swagger-ui .measure-l{max-width:30em}.swagger-ui .measure-wide-l{max-width:34em}.swagger-ui .measure-narrow-l{max-width:20em}.swagger-ui .indent-l{margin-bottom:0;margin-top:0;text-indent:1em}.swagger-ui .small-caps-l{font-feature-settings:\"smcp\";font-variant:small-caps}.swagger-ui .truncate-l{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}}.swagger-ui .overflow-container{overflow-y:scroll}.swagger-ui .center{margin-left:auto;margin-right:auto}.swagger-ui .mr-auto{margin-right:auto}.swagger-ui .ml-auto{margin-left:auto}@media screen and (min-width:30em){.swagger-ui .center-ns{margin-left:auto;margin-right:auto}.swagger-ui .mr-auto-ns{margin-right:auto}.swagger-ui .ml-auto-ns{margin-left:auto}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .center-m{margin-left:auto;margin-right:auto}.swagger-ui .mr-auto-m{margin-right:auto}.swagger-ui .ml-auto-m{margin-left:auto}}@media screen and (min-width:60em){.swagger-ui .center-l{margin-left:auto;margin-right:auto}.swagger-ui .mr-auto-l{margin-right:auto}.swagger-ui .ml-auto-l{margin-left:auto}}.swagger-ui .clip{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}@media screen and (min-width:30em){.swagger-ui .clip-ns{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .clip-m{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}}@media screen and (min-width:60em){.swagger-ui .clip-l{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}}.swagger-ui .ws-normal{white-space:normal}.swagger-ui .nowrap{white-space:nowrap}.swagger-ui .pre{white-space:pre}@media screen and (min-width:30em){.swagger-ui .ws-normal-ns{white-space:normal}.swagger-ui .nowrap-ns{white-space:nowrap}.swagger-ui .pre-ns{white-space:pre}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .ws-normal-m{white-space:normal}.swagger-ui .nowrap-m{white-space:nowrap}.swagger-ui .pre-m{white-space:pre}}@media screen and (min-width:60em){.swagger-ui .ws-normal-l{white-space:normal}.swagger-ui .nowrap-l{white-space:nowrap}.swagger-ui .pre-l{white-space:pre}}.swagger-ui .v-base{vertical-align:baseline}.swagger-ui .v-mid{vertical-align:middle}.swagger-ui .v-top{vertical-align:top}.swagger-ui .v-btm{vertical-align:bottom}@media screen and (min-width:30em){.swagger-ui .v-base-ns{vertical-align:baseline}.swagger-ui .v-mid-ns{vertical-align:middle}.swagger-ui .v-top-ns{vertical-align:top}.swagger-ui .v-btm-ns{vertical-align:bottom}}@media screen and (min-width:30em)and (max-width:60em){.swagger-ui .v-base-m{vertical-align:baseline}.swagger-ui .v-mid-m{vertical-align:middle}.swagger-ui .v-top-m{vertical-align:top}.swagger-ui .v-btm-m{vertical-align:bottom}}@media screen and (min-width:60em){.swagger-ui .v-base-l{vertical-align:baseline}.swagger-ui .v-mid-l{vertical-align:middle}.swagger-ui .v-top-l{vertical-align:top}.swagger-ui .v-btm-l{vertical-align:bottom}}.swagger-ui .dim{opacity:1;transition:opacity .15s ease-in}.swagger-ui .dim:focus,.swagger-ui .dim:hover{opacity:.5;transition:opacity .15s ease-in}.swagger-ui .dim:active{opacity:.8;transition:opacity .15s ease-out}.swagger-ui .glow{transition:opacity .15s ease-in}.swagger-ui .glow:focus,.swagger-ui .glow:hover{opacity:1;transition:opacity .15s ease-in}.swagger-ui .hide-child .child{opacity:0;transition:opacity .15s ease-in}.swagger-ui .hide-child:active .child,.swagger-ui .hide-child:focus .child,.swagger-ui .hide-child:hover .child{opacity:1;transition:opacity .15s ease-in}.swagger-ui .underline-hover:focus,.swagger-ui .underline-hover:hover{-webkit-text-decoration:underline;text-decoration:underline}.swagger-ui .grow{-moz-osx-font-smoothing:grayscale;backface-visibility:hidden;transform:translateZ(0);transition:transform .25s ease-out}.swagger-ui .grow:focus,.swagger-ui .grow:hover{transform:scale(1.05)}.swagger-ui .grow:active{transform:scale(.9)}.swagger-ui .grow-large{-moz-osx-font-smoothing:grayscale;backface-visibility:hidden;transform:translateZ(0);transition:transform .25s ease-in-out}.swagger-ui .grow-large:focus,.swagger-ui .grow-large:hover{transform:scale(1.2)}.swagger-ui .grow-large:active{transform:scale(.95)}.swagger-ui .pointer:hover{cursor:pointer}.swagger-ui .shadow-hover{cursor:pointer;position:relative;transition:all .5s cubic-bezier(.165,.84,.44,1)}.swagger-ui .shadow-hover:after{border-radius:inherit;box-shadow:0 0 16px 2px rgba(0,0,0,.2);content:\"\";height:100%;left:0;opacity:0;position:absolute;top:0;transition:opacity .5s cubic-bezier(.165,.84,.44,1);width:100%;z-index:-1}.swagger-ui .shadow-hover:focus:after,.swagger-ui .shadow-hover:hover:after{opacity:1}.swagger-ui .bg-animate,.swagger-ui .bg-animate:focus,.swagger-ui .bg-animate:hover{transition:background-color .15s ease-in-out}.swagger-ui .z-0{z-index:0}.swagger-ui .z-1{z-index:1}.swagger-ui .z-2{z-index:2}.swagger-ui .z-3{z-index:3}.swagger-ui .z-4{z-index:4}.swagger-ui .z-5{z-index:5}.swagger-ui .z-999{z-index:999}.swagger-ui .z-9999{z-index:9999}.swagger-ui .z-max{z-index:2147483647}.swagger-ui .z-inherit{z-index:inherit}.swagger-ui .z-initial,.swagger-ui .z-unset{z-index:auto}.swagger-ui .nested-copy-line-height ol,.swagger-ui .nested-copy-line-height p,.swagger-ui .nested-copy-line-height ul{line-height:1.5}.swagger-ui .nested-headline-line-height h1,.swagger-ui .nested-headline-line-height h2,.swagger-ui .nested-headline-line-height h3,.swagger-ui .nested-headline-line-height h4,.swagger-ui .nested-headline-line-height h5,.swagger-ui .nested-headline-line-height h6{line-height:1.25}.swagger-ui .nested-list-reset ol,.swagger-ui .nested-list-reset ul{list-style-type:none;margin-left:0;padding-left:0}.swagger-ui .nested-copy-indent p+p{margin-bottom:0;margin-top:0;text-indent:.1em}.swagger-ui .nested-copy-seperator p+p{margin-top:1.5em}.swagger-ui .nested-img img{display:block;max-width:100%;width:100%}.swagger-ui .nested-links a{color:#357edd;transition:color .15s ease-in}.swagger-ui .nested-links a:focus,.swagger-ui .nested-links a:hover{color:#96ccff;transition:color .15s ease-in}.swagger-ui .wrapper{box-sizing:border-box;margin:0 auto;max-width:1460px;padding:0 20px;width:100%}.swagger-ui .opblock-tag-section{display:flex;flex-direction:column}.swagger-ui .try-out.btn-group{display:flex;flex:.1 2 auto;padding:0}.swagger-ui .try-out__btn{margin-left:1.25rem}.swagger-ui .opblock-tag{align-items:center;border-bottom:1px solid rgba(59,65,81,.3);cursor:pointer;display:flex;padding:10px 20px 10px 10px;transition:all .2s}.swagger-ui .opblock-tag:hover{background:rgba(0,0,0,.02)}.swagger-ui .opblock-tag{color:#3b4151;font-family:sans-serif;font-size:24px;margin:0 0 5px}.swagger-ui .opblock-tag.no-desc span{flex:1}.swagger-ui .opblock-tag svg{transition:all .4s}.swagger-ui .opblock-tag small{color:#3b4151;flex:2;font-family:sans-serif;font-size:14px;font-weight:400;padding:0 10px}.swagger-ui .opblock-tag>div{flex:1 1 150px;font-weight:400;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@media(max-width:640px){.swagger-ui .opblock-tag small,.swagger-ui .opblock-tag>div{flex:1}}.swagger-ui .opblock-tag .info__externaldocs{text-align:right}.swagger-ui .parameter__type{color:#3b4151;font-family:monospace;font-size:12px;font-weight:600;padding:5px 0}.swagger-ui .parameter-controls{margin-top:.75em}.swagger-ui .examples__title{display:block;font-size:1.1em;font-weight:700;margin-bottom:.75em}.swagger-ui .examples__section{margin-top:1.5em}.swagger-ui .examples__section-header{font-size:.9rem;font-weight:700;margin-bottom:.5rem}.swagger-ui .examples-select{display:inline-block;margin-bottom:.75em}.swagger-ui .examples-select .examples-select-element{width:100%}.swagger-ui .examples-select__section-label{font-size:.9rem;font-weight:700;margin-right:.5rem}.swagger-ui .example__section{margin-top:1.5em}.swagger-ui .example__section-header{font-size:.9rem;font-weight:700;margin-bottom:.5rem}.swagger-ui .view-line-link{cursor:pointer;margin:0 5px;position:relative;top:3px;transition:all .5s;width:20px}.swagger-ui .opblock{border:1px solid #000;border-radius:4px;box-shadow:0 0 3px rgba(0,0,0,.19);margin:0 0 15px}.swagger-ui .opblock .tab-header{display:flex;flex:1}.swagger-ui .opblock .tab-header .tab-item{cursor:pointer;padding:0 40px}.swagger-ui .opblock .tab-header .tab-item:first-of-type{padding:0 40px 0 0}.swagger-ui .opblock .tab-header .tab-item.active h4 span{position:relative}.swagger-ui .opblock .tab-header .tab-item.active h4 span:after{background:gray;bottom:-15px;content:\"\";height:4px;left:50%;position:absolute;transform:translateX(-50%);width:120%}.swagger-ui .opblock.is-open .opblock-summary{border-bottom:1px solid #000}.swagger-ui .opblock .opblock-section-header{align-items:center;background:hsla(0,0%,100%,.8);box-shadow:0 1px 2px rgba(0,0,0,.1);display:flex;min-height:50px;padding:8px 20px}.swagger-ui .opblock .opblock-section-header>label{align-items:center;color:#3b4151;display:flex;font-family:sans-serif;font-size:12px;font-weight:700;margin:0 0 0 auto}.swagger-ui .opblock .opblock-section-header>label>span{padding:0 10px 0 0}.swagger-ui .opblock .opblock-section-header h4{color:#3b4151;flex:1;font-family:sans-serif;font-size:14px;margin:0}.swagger-ui .opblock .opblock-summary-method{background:#000;border-radius:3px;color:#fff;font-family:sans-serif;font-size:14px;font-weight:700;min-width:80px;padding:6px 0;text-align:center;text-shadow:0 1px 0 rgba(0,0,0,.1)}@media(max-width:768px){.swagger-ui .opblock .opblock-summary-method{font-size:12px}}.swagger-ui .opblock .opblock-summary-operation-id,.swagger-ui .opblock .opblock-summary-path,.swagger-ui .opblock .opblock-summary-path__deprecated{align-items:center;color:#3b4151;display:flex;font-family:monospace;font-size:16px;font-weight:600;word-break:break-word}@media(max-width:768px){.swagger-ui .opblock .opblock-summary-operation-id,.swagger-ui .opblock .opblock-summary-path,.swagger-ui .opblock .opblock-summary-path__deprecated{font-size:12px}}.swagger-ui .opblock .opblock-summary-path{flex-shrink:1}@media(max-width:640px){.swagger-ui .opblock .opblock-summary-path{max-width:100%}}.swagger-ui .opblock .opblock-summary-path__deprecated{-webkit-text-decoration:line-through;text-decoration:line-through}.swagger-ui .opblock .opblock-summary-operation-id{font-size:14px}.swagger-ui .opblock .opblock-summary-description{color:#3b4151;font-family:sans-serif;font-size:13px;word-break:break-word}.swagger-ui .opblock .opblock-summary-path-description-wrapper{align-items:center;display:flex;flex-direction:row;flex-wrap:wrap;gap:0 10px;padding:0 10px;width:100%}@media(max-width:550px){.swagger-ui .opblock .opblock-summary-path-description-wrapper{align-items:flex-start;flex-direction:column}}.swagger-ui .opblock .opblock-summary{align-items:center;cursor:pointer;display:flex;padding:5px}.swagger-ui .opblock .opblock-summary .view-line-link{cursor:pointer;margin:0;position:relative;top:2px;transition:all .5s;width:0}.swagger-ui .opblock .opblock-summary:hover .view-line-link{margin:0 5px;width:18px}.swagger-ui .opblock .opblock-summary:hover .view-line-link.copy-to-clipboard{width:24px}.swagger-ui .opblock.opblock-post{background:rgba(73,204,144,.1);border-color:#49cc90}.swagger-ui .opblock.opblock-post .opblock-summary-method{background:#49cc90}.swagger-ui .opblock.opblock-post .opblock-summary{border-color:#49cc90}.swagger-ui .opblock.opblock-post .tab-header .tab-item.active h4 span:after{background:#49cc90}.swagger-ui .opblock.opblock-put{background:rgba(252,161,48,.1);border-color:#fca130}.swagger-ui .opblock.opblock-put .opblock-summary-method{background:#fca130}.swagger-ui .opblock.opblock-put .opblock-summary{border-color:#fca130}.swagger-ui .opblock.opblock-put .tab-header .tab-item.active h4 span:after{background:#fca130}.swagger-ui .opblock.opblock-delete{background:rgba(249,62,62,.1);border-color:#f93e3e}.swagger-ui .opblock.opblock-delete .opblock-summary-method{background:#f93e3e}.swagger-ui .opblock.opblock-delete .opblock-summary{border-color:#f93e3e}.swagger-ui .opblock.opblock-delete .tab-header .tab-item.active h4 span:after{background:#f93e3e}.swagger-ui .opblock.opblock-get{background:rgba(97,175,254,.1);border-color:#61affe}.swagger-ui .opblock.opblock-get .opblock-summary-method{background:#61affe}.swagger-ui .opblock.opblock-get .opblock-summary{border-color:#61affe}.swagger-ui .opblock.opblock-get .tab-header .tab-item.active h4 span:after{background:#61affe}.swagger-ui .opblock.opblock-patch{background:rgba(80,227,194,.1);border-color:#50e3c2}.swagger-ui .opblock.opblock-patch .opblock-summary-method{background:#50e3c2}.swagger-ui .opblock.opblock-patch .opblock-summary{border-color:#50e3c2}.swagger-ui .opblock.opblock-patch .tab-header .tab-item.active h4 span:after{background:#50e3c2}.swagger-ui .opblock.opblock-head{background:rgba(144,18,254,.1);border-color:#9012fe}.swagger-ui .opblock.opblock-head .opblock-summary-method{background:#9012fe}.swagger-ui .opblock.opblock-head .opblock-summary{border-color:#9012fe}.swagger-ui .opblock.opblock-head .tab-header .tab-item.active h4 span:after{background:#9012fe}.swagger-ui .opblock.opblock-options{background:rgba(13,90,167,.1);border-color:#0d5aa7}.swagger-ui .opblock.opblock-options .opblock-summary-method{background:#0d5aa7}.swagger-ui .opblock.opblock-options .opblock-summary{border-color:#0d5aa7}.swagger-ui .opblock.opblock-options .tab-header .tab-item.active h4 span:after{background:#0d5aa7}.swagger-ui .opblock.opblock-deprecated{background:hsla(0,0%,92%,.1);border-color:#ebebeb;opacity:.6}.swagger-ui .opblock.opblock-deprecated .opblock-summary-method{background:#ebebeb}.swagger-ui .opblock.opblock-deprecated .opblock-summary{border-color:#ebebeb}.swagger-ui .opblock.opblock-deprecated .tab-header .tab-item.active h4 span:after{background:#ebebeb}.swagger-ui .opblock .opblock-schemes{padding:8px 20px}.swagger-ui .opblock .opblock-schemes .schemes-title{padding:0 10px 0 0}.swagger-ui .filter .operation-filter-input{border:2px solid #d8dde7;margin:20px 0;padding:10px;width:100%}.swagger-ui .download-url-wrapper .failed,.swagger-ui .filter .failed{color:red}.swagger-ui .download-url-wrapper .loading,.swagger-ui .filter .loading{color:#aaa}.swagger-ui .model-example{margin-top:1em}.swagger-ui .tab{display:flex;list-style:none;padding:0}.swagger-ui .tab li{color:#3b4151;cursor:pointer;font-family:sans-serif;font-size:12px;min-width:60px;padding:0}.swagger-ui .tab li:first-of-type{padding-left:0;padding-right:12px;position:relative}.swagger-ui .tab li:first-of-type:after{background:rgba(0,0,0,.2);content:\"\";height:100%;position:absolute;right:6px;top:0;width:1px}.swagger-ui .tab li.active{font-weight:700}.swagger-ui .tab li button.tablinks{background:none;border:0;color:inherit;font-family:inherit;font-weight:inherit;padding:0}.swagger-ui .opblock-description-wrapper,.swagger-ui .opblock-external-docs-wrapper,.swagger-ui .opblock-title_normal{color:#3b4151;font-family:sans-serif;font-size:12px;margin:0 0 5px;padding:15px 20px}.swagger-ui .opblock-description-wrapper h4,.swagger-ui .opblock-external-docs-wrapper h4,.swagger-ui .opblock-title_normal h4{color:#3b4151;font-family:sans-serif;font-size:12px;margin:0 0 5px}.swagger-ui .opblock-description-wrapper p,.swagger-ui .opblock-external-docs-wrapper p,.swagger-ui .opblock-title_normal p{color:#3b4151;font-family:sans-serif;font-size:14px;margin:0}.swagger-ui .opblock-external-docs-wrapper h4{padding-left:0}.swagger-ui .execute-wrapper{padding:20px;text-align:right}.swagger-ui .execute-wrapper .btn{padding:8px 40px;width:100%}.swagger-ui .body-param-options{display:flex;flex-direction:column}.swagger-ui .body-param-options .body-param-edit{padding:10px 0}.swagger-ui .body-param-options label{padding:8px 0}.swagger-ui .body-param-options label select{margin:3px 0 0}.swagger-ui .responses-inner{padding:20px}.swagger-ui .responses-inner h4,.swagger-ui .responses-inner h5{color:#3b4151;font-family:sans-serif;font-size:12px;margin:10px 0 5px}.swagger-ui .responses-inner .curl{max-height:400px;min-height:6em;overflow-y:auto}.swagger-ui .response-col_status{color:#3b4151;font-family:sans-serif;font-size:14px}.swagger-ui .response-col_status .response-undocumented{color:#909090;font-family:monospace;font-size:11px;font-weight:600}.swagger-ui .response-col_links{color:#3b4151;font-family:sans-serif;font-size:14px;max-width:40em;padding-left:2em}.swagger-ui .response-col_links .response-undocumented{color:#909090;font-family:monospace;font-size:11px;font-weight:600}.swagger-ui .response-col_links .operation-link{margin-bottom:1.5em}.swagger-ui .response-col_links .operation-link .description{margin-bottom:.5em}.swagger-ui .opblock-body .opblock-loading-animation{display:block;margin:3em auto}.swagger-ui .opblock-body pre.microlight{background:#333;border-radius:4px;font-size:12px;-webkit-hyphens:auto;hyphens:auto;margin:0;padding:10px;white-space:pre-wrap;word-break:break-all;word-break:break-word;word-wrap:break-word;color:#fff;font-family:monospace;font-weight:600}.swagger-ui .opblock-body pre.microlight .headerline{display:block}.swagger-ui .highlight-code{position:relative}.swagger-ui .highlight-code>.microlight{max-height:400px;min-height:6em;overflow-y:auto}.swagger-ui .highlight-code>.microlight code{white-space:pre-wrap!important;word-break:break-all}.swagger-ui .curl-command{position:relative}.swagger-ui .download-contents{align-items:center;background:#7d8293;border:none;border-radius:4px;bottom:10px;color:#fff;display:flex;font-family:sans-serif;font-size:14px;font-weight:600;height:30px;justify-content:center;padding:5px;position:absolute;right:10px;text-align:center}.swagger-ui .scheme-container{background:#fff;box-shadow:0 1px 2px 0 rgba(0,0,0,.15);margin:0 0 20px;padding:30px 0}.swagger-ui .scheme-container .schemes{align-items:flex-end;display:flex;flex-wrap:wrap;gap:10px;justify-content:space-between}.swagger-ui .scheme-container .schemes>.schemes-server-container{display:flex;flex-wrap:wrap;gap:10px}.swagger-ui .scheme-container .schemes>.schemes-server-container>label{color:#3b4151;display:flex;flex-direction:column;font-family:sans-serif;font-size:12px;font-weight:700;margin:-20px 15px 0 0}.swagger-ui .scheme-container .schemes>.schemes-server-container>label select{min-width:130px;text-transform:uppercase}.swagger-ui .scheme-container .schemes:not(:has(.schemes-server-container)){justify-content:flex-end}.swagger-ui .scheme-container .schemes .auth-wrapper{flex:none;justify-content:start}.swagger-ui .scheme-container .schemes .auth-wrapper .authorize{display:flex;flex-wrap:nowrap;margin:0;padding-right:20px}.swagger-ui .loading-container{align-items:center;display:flex;flex-direction:column;justify-content:center;margin-top:1em;min-height:1px;padding:40px 0 60px}.swagger-ui .loading-container .loading{position:relative}.swagger-ui .loading-container .loading:after{color:#3b4151;content:\"loading\";font-family:sans-serif;font-size:10px;font-weight:700;left:50%;position:absolute;text-transform:uppercase;top:50%;transform:translate(-50%,-50%)}.swagger-ui .loading-container .loading:before{animation:rotation 1s linear infinite,opacity .5s;backface-visibility:hidden;border:2px solid rgba(85,85,85,.1);border-radius:100%;border-top-color:rgba(0,0,0,.6);content:\"\";display:block;height:60px;left:50%;margin:-30px;opacity:1;position:absolute;top:50%;width:60px}@keyframes rotation{to{transform:rotate(1turn)}}.swagger-ui .response-controls{display:flex;padding-top:1em}.swagger-ui .response-control-media-type{margin-right:1em}.swagger-ui .response-control-media-type--accept-controller select{border-color:green}.swagger-ui .response-control-media-type__accept-message{color:green;font-size:.7em}.swagger-ui .response-control-examples__title,.swagger-ui .response-control-media-type__title{display:block;font-size:.7em;margin-bottom:.2em}@keyframes blinker{50%{opacity:0}}.swagger-ui .hidden{display:none}.swagger-ui .no-margin{border:none;height:auto;margin:0;padding:0}.swagger-ui .float-right{float:right}.swagger-ui .svg-assets{height:0;position:absolute;width:0}.swagger-ui section h3{color:#3b4151;font-family:sans-serif}.swagger-ui a.nostyle{display:inline}.swagger-ui a.nostyle,.swagger-ui a.nostyle:visited{color:inherit;cursor:pointer;text-decoration:inherit}.swagger-ui .fallback{color:#aaa;padding:1em}.swagger-ui .version-pragma{height:100%;padding:5em 0}.swagger-ui .version-pragma__message{display:flex;font-size:1.2em;height:100%;justify-content:center;line-height:1.5em;padding:0 .6em;text-align:center}.swagger-ui .version-pragma__message>div{flex:1;max-width:55ch}.swagger-ui .version-pragma__message code{background-color:#dedede;padding:4px 4px 2px;white-space:pre}.swagger-ui .opblock-link{font-weight:400}.swagger-ui .opblock-link.shown{font-weight:700}.swagger-ui span.token-string{color:#555}.swagger-ui span.token-not-formatted{color:#555;font-weight:700}.swagger-ui .btn{background:transparent;border:2px solid gray;border-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,.1);color:#3b4151;font-family:sans-serif;font-size:14px;font-weight:700;padding:5px 23px;transition:all .3s}.swagger-ui .btn.btn-sm{font-size:12px;padding:4px 23px}.swagger-ui .btn[disabled]{cursor:not-allowed;opacity:.3}.swagger-ui .btn:hover{box-shadow:0 0 5px rgba(0,0,0,.3)}.swagger-ui .btn.cancel{background-color:transparent;border-color:#ff6060;color:#ff6060;font-family:sans-serif}.swagger-ui .btn.authorize{background-color:transparent;border-color:#49cc90;color:#49cc90;display:inline;line-height:1}.swagger-ui .btn.authorize span{float:left;padding:4px 20px 0 0}.swagger-ui .btn.authorize svg{fill:#49cc90}.swagger-ui .btn.execute{background-color:#4990e2;border-color:#4990e2;color:#fff}.swagger-ui .btn-group{display:flex;padding:30px}.swagger-ui .btn-group .btn{flex:1}.swagger-ui .btn-group .btn:first-child{border-radius:4px 0 0 4px}.swagger-ui .btn-group .btn:last-child{border-radius:0 4px 4px 0}.swagger-ui .authorization__btn{background:none;border:none;padding:0 0 0 10px}.swagger-ui .authorization__btn .locked{opacity:1}.swagger-ui .authorization__btn .unlocked{opacity:.4}.swagger-ui .model-box-control,.swagger-ui .models-control,.swagger-ui .opblock-summary-control{all:inherit;border-bottom:0;cursor:pointer;flex:1;padding:0}.swagger-ui .model-box-control:focus,.swagger-ui .models-control:focus,.swagger-ui .opblock-summary-control:focus{outline:auto}.swagger-ui .expand-methods,.swagger-ui .expand-operation{background:none;border:none}.swagger-ui .expand-methods svg,.swagger-ui .expand-operation svg{height:20px;width:20px}.swagger-ui .expand-methods{padding:0 10px}.swagger-ui .expand-methods:hover svg{fill:#404040}.swagger-ui .expand-methods svg{transition:all .3s;fill:#707070}.swagger-ui button{cursor:pointer}.swagger-ui button.invalid{animation:shake .4s 1;background:#feebeb;border-color:#f93e3e}.swagger-ui .copy-to-clipboard{align-items:center;background:#7d8293;border:none;border-radius:4px;bottom:10px;display:flex;height:30px;justify-content:center;position:absolute;right:100px;width:30px}.swagger-ui .copy-to-clipboard button{background:url(\"data:image/svg+xml;charset=utf-8,\") 50% no-repeat;border:none;flex-grow:1;flex-shrink:1;height:25px}.swagger-ui .copy-to-clipboard:active{background:#5e626f}.swagger-ui .opblock-control-arrow{background:none;border:none;text-align:center}.swagger-ui .curl-command .copy-to-clipboard{bottom:5px;height:20px;right:10px;width:20px}.swagger-ui .curl-command .copy-to-clipboard button{height:18px}.swagger-ui .opblock .opblock-summary .view-line-link.copy-to-clipboard{height:26px;position:static}.swagger-ui select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:#f7f7f7 url(\"data:image/svg+xml;charset=utf-8,\") right 10px center no-repeat;background-size:20px;border:2px solid #41444e;border-radius:4px;box-shadow:0 1px 2px 0 rgba(0,0,0,.25);color:#3b4151;font-family:sans-serif;font-size:14px;font-weight:700;padding:5px 40px 5px 10px}.swagger-ui select[multiple]{background:#f7f7f7;margin:5px 0;padding:5px}.swagger-ui select.invalid{animation:shake .4s 1;background:#feebeb;border-color:#f93e3e}.swagger-ui .opblock-body select{min-width:230px}@media(max-width:768px){.swagger-ui .opblock-body select{min-width:180px}}@media(max-width:640px){.swagger-ui .opblock-body select{min-width:100%;width:100%}}.swagger-ui label{color:#3b4151;font-family:sans-serif;font-size:12px;font-weight:700;margin:0 0 5px}.swagger-ui input[type=email],.swagger-ui input[type=file],.swagger-ui input[type=password],.swagger-ui input[type=search],.swagger-ui input[type=text]{line-height:1}@media(max-width:768px){.swagger-ui input[type=email],.swagger-ui input[type=file],.swagger-ui input[type=password],.swagger-ui input[type=search],.swagger-ui input[type=text]{max-width:175px}}.swagger-ui input[type=email],.swagger-ui input[type=file],.swagger-ui input[type=password],.swagger-ui input[type=search],.swagger-ui input[type=text],.swagger-ui textarea{background:#fff;border:1px solid #d9d9d9;border-radius:4px;margin:5px 0;min-width:100px;padding:8px 10px}.swagger-ui input[type=email].invalid,.swagger-ui input[type=file].invalid,.swagger-ui input[type=password].invalid,.swagger-ui input[type=search].invalid,.swagger-ui input[type=text].invalid,.swagger-ui textarea.invalid{animation:shake .4s 1;background:#feebeb;border-color:#f93e3e}.swagger-ui input[disabled],.swagger-ui select[disabled],.swagger-ui textarea[disabled]{background-color:#fafafa;color:#888;cursor:not-allowed}.swagger-ui select[disabled]{border-color:#888}.swagger-ui textarea[disabled]{background-color:#41444e;color:#fff}@keyframes shake{10%,90%{transform:translate3d(-1px,0,0)}20%,80%{transform:translate3d(2px,0,0)}30%,50%,70%{transform:translate3d(-4px,0,0)}40%,60%{transform:translate3d(4px,0,0)}}.swagger-ui textarea{background:hsla(0,0%,100%,.8);border:none;border-radius:4px;color:#3b4151;font-family:monospace;font-size:12px;font-weight:600;min-height:280px;outline:none;padding:10px;width:100%}.swagger-ui textarea:focus{border:2px solid #61affe}.swagger-ui textarea.curl{background:#41444e;border-radius:4px;color:#fff;font-family:monospace;font-size:12px;font-weight:600;margin:0;min-height:100px;padding:10px;resize:none}.swagger-ui .checkbox{color:#303030;padding:5px 0 10px;transition:opacity .5s}.swagger-ui .checkbox label{display:flex}.swagger-ui .checkbox p{color:#3b4151;font-family:monospace;font-style:italic;font-weight:400!important;font-weight:600;margin:0!important}.swagger-ui .checkbox input[type=checkbox]{display:none}.swagger-ui .checkbox input[type=checkbox]+label>.item{background:#e8e8e8;border-radius:1px;box-shadow:0 0 0 2px #e8e8e8;cursor:pointer;display:inline-block;flex:none;height:16px;margin:0 8px 0 0;padding:5px;position:relative;top:3px;width:16px}.swagger-ui .checkbox input[type=checkbox]+label>.item:active{transform:scale(.9)}.swagger-ui .checkbox input[type=checkbox]:checked+label>.item{background:#e8e8e8 url(\"data:image/svg+xml;charset=utf-8,\") 50% no-repeat}.swagger-ui .dialog-ux{bottom:0;left:0;position:fixed;right:0;top:0;z-index:9999}.swagger-ui .dialog-ux .backdrop-ux{background:rgba(0,0,0,.8);bottom:0;left:0;position:fixed;right:0;top:0}.swagger-ui .dialog-ux .modal-ux{background:#fff;border:1px solid #ebebeb;border-radius:4px;box-shadow:0 10px 30px 0 rgba(0,0,0,.2);left:50%;max-width:650px;min-width:300px;position:absolute;top:50%;transform:translate(-50%,-50%);width:100%;z-index:9999}.swagger-ui .dialog-ux .modal-ux-content{max-height:540px;overflow-y:auto;padding:20px}.swagger-ui .dialog-ux .modal-ux-content p{color:#41444e;color:#3b4151;font-family:sans-serif;font-size:12px;margin:0 0 5px}.swagger-ui .dialog-ux .modal-ux-content h4{color:#3b4151;font-family:sans-serif;font-size:18px;font-weight:600;margin:15px 0 0}.swagger-ui .dialog-ux .modal-ux-header{align-items:center;border-bottom:1px solid #ebebeb;display:flex;padding:12px 0}.swagger-ui .dialog-ux .modal-ux-header .close-modal{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:none;padding:0 10px}.swagger-ui .dialog-ux .modal-ux-header h3{color:#3b4151;flex:1;font-family:sans-serif;font-size:20px;font-weight:600;margin:0;padding:0 20px}.swagger-ui .model{color:#3b4151;font-family:monospace;font-size:12px;font-weight:300;font-weight:600}.swagger-ui .model .deprecated span,.swagger-ui .model .deprecated td{color:#a0a0a0!important}.swagger-ui .model .deprecated>td:first-of-type{-webkit-text-decoration:line-through;text-decoration:line-through}.swagger-ui .model-toggle{cursor:pointer;display:inline-block;font-size:10px;margin:auto .3em;position:relative;top:6px;transform:rotate(90deg);transform-origin:50% 50%;transition:transform .15s ease-in}.swagger-ui .model-toggle.collapsed{transform:rotate(0deg)}.swagger-ui .model-toggle:after{background:url(\"data:image/svg+xml;charset=utf-8,\") 50% no-repeat;background-size:100%;content:\"\";display:block;height:20px;width:20px}.swagger-ui .model-jump-to-path{cursor:pointer;position:relative}.swagger-ui .model-jump-to-path .view-line-link{cursor:pointer;position:absolute;top:-.4em}.swagger-ui .model-title{position:relative}.swagger-ui .model-title:hover .model-hint{visibility:visible}.swagger-ui .model-hint{background:rgba(0,0,0,.7);border-radius:4px;color:#ebebeb;padding:.1em .5em;position:absolute;top:-1.8em;visibility:hidden;white-space:nowrap}.swagger-ui .model p{margin:0 0 1em}.swagger-ui .model .property{color:#999;font-style:italic}.swagger-ui .model .property.primitive{color:#6b6b6b}.swagger-ui .model .external-docs,.swagger-ui table.model tr.description{color:#666;font-weight:400}.swagger-ui table.model tr.description td:first-child,.swagger-ui table.model tr.property-row.required td:first-child{font-weight:700}.swagger-ui table.model tr.property-row td{vertical-align:top}.swagger-ui table.model tr.property-row td:first-child{padding-right:.2em}.swagger-ui table.model tr.property-row .star{color:red}.swagger-ui table.model tr.extension{color:#777}.swagger-ui table.model tr.extension td:last-child{vertical-align:top}.swagger-ui table.model tr.external-docs td:first-child{font-weight:700}.swagger-ui table.model tr .renderedMarkdown p:first-child{margin-top:0}.swagger-ui section.models{border:1px solid rgba(59,65,81,.3);border-radius:4px;margin:30px 0}.swagger-ui section.models .pointer{cursor:pointer}.swagger-ui section.models.is-open{padding:0 0 20px}.swagger-ui section.models.is-open h4{border-bottom:1px solid rgba(59,65,81,.3);margin:0 0 5px}.swagger-ui section.models h4{align-items:center;color:#606060;cursor:pointer;display:flex;font-family:sans-serif;font-size:16px;margin:0;padding:10px 20px 10px 10px;transition:all .2s}.swagger-ui section.models h4 svg{transition:all .4s}.swagger-ui section.models h4 span{flex:1}.swagger-ui section.models h4:hover{background:rgba(0,0,0,.02)}.swagger-ui section.models h5{color:#707070;font-family:sans-serif;font-size:16px;margin:0 0 10px}.swagger-ui section.models .model-jump-to-path{position:relative;top:5px}.swagger-ui section.models .model-container{background:rgba(0,0,0,.05);border-radius:4px;margin:0 20px 15px;position:relative;transition:all .5s}.swagger-ui section.models .model-container:hover{background:rgba(0,0,0,.07)}.swagger-ui section.models .model-container:first-of-type{margin:20px}.swagger-ui section.models .model-container:last-of-type{margin:0 20px}.swagger-ui section.models .model-container .models-jump-to-path{opacity:.65;position:absolute;right:5px;top:8px}.swagger-ui section.models .model-box{background:none}.swagger-ui .model-box{background:rgba(0,0,0,.1);border-radius:4px;display:inline-block;padding:10px}.swagger-ui .model-box .model-jump-to-path{position:relative;top:4px}.swagger-ui .model-box.deprecated{opacity:.5}.swagger-ui .model-title{color:#505050;font-family:sans-serif;font-size:16px}.swagger-ui .model-title img{bottom:0;margin-left:1em;position:relative}.swagger-ui .model-deprecated-warning{color:#f93e3e;font-family:sans-serif;font-size:16px;font-weight:600;margin-right:1em}.swagger-ui span>span.model .brace-close{padding:0 0 0 10px}.swagger-ui .prop-name{display:inline-block;margin-right:1em}.swagger-ui .prop-type{color:#55a}.swagger-ui .prop-enum{display:block}.swagger-ui .prop-format{color:#606060}.swagger-ui .servers>label{color:#3b4151;font-family:sans-serif;font-size:12px;margin:-20px 15px 0 0}.swagger-ui .servers>label select{max-width:100%;min-width:130px;width:100%}.swagger-ui .servers h4.message{padding-bottom:2em}.swagger-ui .servers table tr{width:30em}.swagger-ui .servers table td{display:inline-block;max-width:15em;padding-bottom:10px;padding-top:10px;vertical-align:middle}.swagger-ui .servers table td:first-of-type{padding-right:1em}.swagger-ui .servers table td input{height:100%;width:100%}.swagger-ui .servers .computed-url{margin:2em 0}.swagger-ui .servers .computed-url code{display:inline-block;font-size:16px;margin:0 1em;padding:4px}.swagger-ui .servers-title{font-size:12px;font-weight:700}.swagger-ui .operation-servers h4.message{margin-bottom:2em}.swagger-ui table{border-collapse:collapse;padding:0 10px;width:100%}.swagger-ui table.model tbody tr td{padding:0;vertical-align:top}.swagger-ui table.model tbody tr td:first-of-type{padding:0 0 0 2em;width:174px}.swagger-ui table.headers td{color:#3b4151;font-family:monospace;font-size:12px;font-weight:300;font-weight:600;vertical-align:middle}.swagger-ui table.headers .header-example{color:#999;font-style:italic}.swagger-ui table tbody tr td{padding:10px 0 0;vertical-align:top}.swagger-ui table tbody tr td:first-of-type{min-width:6em;padding:10px 0}.swagger-ui table thead tr td,.swagger-ui table thead tr th{border-bottom:1px solid rgba(59,65,81,.2);color:#3b4151;font-family:sans-serif;font-size:12px;font-weight:700;padding:12px 0;text-align:left}.swagger-ui .parameters-col_description{margin-bottom:2em;width:99%}.swagger-ui .parameters-col_description input{max-width:340px;width:100%}.swagger-ui .parameters-col_description select{border-width:1px}.swagger-ui .parameters-col_description .markdown p,.swagger-ui .parameters-col_description .renderedMarkdown p{margin:0}.swagger-ui .parameter__name{color:#3b4151;font-family:sans-serif;font-size:16px;font-weight:400;margin-right:.75em}.swagger-ui .parameter__name.required{font-weight:700}.swagger-ui .parameter__name.required span{color:red}.swagger-ui .parameter__name.required:after{color:rgba(255,0,0,.6);content:\"required\";font-size:10px;padding:5px;position:relative;top:-6px}.swagger-ui .parameter__extension,.swagger-ui .parameter__in{color:gray;font-family:monospace;font-size:12px;font-style:italic;font-weight:600}.swagger-ui .parameter__deprecated{color:red;font-family:monospace;font-size:12px;font-style:italic;font-weight:600}.swagger-ui .parameter__empty_value_toggle{display:block;font-size:13px;padding-bottom:12px;padding-top:5px}.swagger-ui .parameter__empty_value_toggle input{margin-right:7px;width:auto}.swagger-ui .parameter__empty_value_toggle.disabled{opacity:.7}.swagger-ui .table-container{padding:20px}.swagger-ui .response-col_description{width:99%}.swagger-ui .response-col_description .markdown p,.swagger-ui .response-col_description .renderedMarkdown p{margin:0}.swagger-ui .response-col_links{min-width:6em}.swagger-ui .response__extension{color:gray;font-family:monospace;font-size:12px;font-style:italic;font-weight:600}.swagger-ui .topbar{background-color:#1b1b1b;padding:10px 0}.swagger-ui .topbar .topbar-wrapper{align-items:center;display:flex;flex-wrap:wrap;gap:10px}@media(max-width:550px){.swagger-ui .topbar .topbar-wrapper{align-items:start;flex-direction:column}}.swagger-ui .topbar a{align-items:center;color:#fff;display:flex;flex:1;font-family:sans-serif;font-size:1.5em;font-weight:700;max-width:300px;-webkit-text-decoration:none;text-decoration:none}.swagger-ui .topbar a span{margin:0;padding:0 10px}.swagger-ui .topbar .download-url-wrapper{display:flex;flex:3;justify-content:flex-end}.swagger-ui .topbar .download-url-wrapper input[type=text]{border:2px solid #62a03f;border-radius:4px 0 0 4px;margin:0;max-width:100%;outline:none;width:100%}.swagger-ui .topbar .download-url-wrapper .select-label{align-items:center;color:#f0f0f0;display:flex;margin:0;max-width:600px;width:100%}.swagger-ui .topbar .download-url-wrapper .select-label span{flex:1;font-size:16px;padding:0 10px 0 0;text-align:right}.swagger-ui .topbar .download-url-wrapper .select-label select{border:2px solid #62a03f;box-shadow:none;flex:2;outline:none;width:100%}.swagger-ui .topbar .download-url-wrapper .download-url-button{background:#62a03f;border:none;border-radius:0 4px 4px 0;color:#fff;font-family:sans-serif;font-size:16px;font-weight:700;padding:4px 30px}@media(max-width:550px){.swagger-ui .topbar .download-url-wrapper{width:100%}}.swagger-ui .info{margin:50px 0}.swagger-ui .info.failed-config{margin-left:auto;margin-right:auto;max-width:880px;text-align:center}.swagger-ui .info hgroup.main{margin:0 0 20px}.swagger-ui .info hgroup.main a{font-size:12px}.swagger-ui .info pre{font-size:14px}.swagger-ui .info li,.swagger-ui .info p,.swagger-ui .info table{color:#3b4151;font-family:sans-serif;font-size:14px}.swagger-ui .info h1,.swagger-ui .info h2,.swagger-ui .info h3,.swagger-ui .info h4,.swagger-ui .info h5{color:#3b4151;font-family:sans-serif}.swagger-ui .info a{color:#4990e2;font-family:sans-serif;font-size:14px;transition:all .4s}.swagger-ui .info a:hover{color:#1f69c0}.swagger-ui .info>div{margin:0 0 5px}.swagger-ui .info .base-url{color:#3b4151;font-family:monospace;font-size:12px;font-weight:300!important;font-weight:600;margin:0}.swagger-ui .info .title{color:#3b4151;font-family:sans-serif;font-size:36px;margin:0}.swagger-ui .info .title small{background:#7d8492;border-radius:57px;display:inline-block;font-size:10px;margin:0 0 0 5px;padding:2px 4px;position:relative;top:-5px;vertical-align:super}.swagger-ui .info .title small.version-stamp{background-color:#89bf04}.swagger-ui .info .title small pre{color:#fff;font-family:sans-serif;margin:0;padding:0}.swagger-ui .auth-btn-wrapper{display:flex;justify-content:center;padding:10px 0}.swagger-ui .auth-btn-wrapper .btn-done{margin-right:1em}.swagger-ui .auth-wrapper{display:flex;flex:1;justify-content:flex-end}.swagger-ui .auth-wrapper .authorize{margin-left:10px;margin-right:10px;padding-right:20px}.swagger-ui .auth-container{border-bottom:1px solid #ebebeb;margin:0 0 10px;padding:10px 20px}.swagger-ui .auth-container:last-of-type{border:0;margin:0;padding:10px 20px}.swagger-ui .auth-container h4{margin:5px 0 15px!important}.swagger-ui .auth-container .wrapper{margin:0;padding:0}.swagger-ui .auth-container input[type=password],.swagger-ui .auth-container input[type=text]{min-width:230px}.swagger-ui .auth-container .errors{background-color:#fee;border-radius:4px;color:red;color:#3b4151;font-family:monospace;font-size:12px;font-weight:600;margin:1em;padding:10px}.swagger-ui .auth-container .errors b{margin-right:1em;text-transform:capitalize}.swagger-ui .scopes h2{color:#3b4151;font-family:sans-serif;font-size:14px}.swagger-ui .scopes h2 a{color:#4990e2;cursor:pointer;font-size:12px;padding-left:10px;-webkit-text-decoration:underline;text-decoration:underline}.swagger-ui .scope-def{padding:0 0 20px}.swagger-ui .errors-wrapper{animation:scaleUp .5s;background:rgba(249,62,62,.1);border:2px solid #f93e3e;border-radius:4px;margin:20px;padding:10px 20px}.swagger-ui .errors-wrapper .error-wrapper{margin:0 0 10px}.swagger-ui .errors-wrapper .errors h4{color:#3b4151;font-family:monospace;font-size:14px;font-weight:600;margin:0}.swagger-ui .errors-wrapper .errors small{color:#606060}.swagger-ui .errors-wrapper .errors .message{white-space:pre-line}.swagger-ui .errors-wrapper .errors .message.thrown{max-width:100%}.swagger-ui .errors-wrapper .errors .error-line{cursor:pointer;-webkit-text-decoration:underline;text-decoration:underline}.swagger-ui .errors-wrapper hgroup{align-items:center;display:flex}.swagger-ui .errors-wrapper hgroup h4{color:#3b4151;flex:1;font-family:sans-serif;font-size:20px;margin:0}@keyframes scaleUp{0%{opacity:0;transform:scale(.8)}to{opacity:1;transform:scale(1)}}.swagger-ui .Resizer.vertical.disabled{display:none}.swagger-ui .markdown p,.swagger-ui .markdown pre,.swagger-ui .renderedMarkdown p,.swagger-ui .renderedMarkdown pre{margin:1em auto;word-break:break-all;word-break:break-word}.swagger-ui .markdown pre,.swagger-ui .renderedMarkdown pre{background:none;color:#000;font-weight:400;padding:0;white-space:pre-wrap}.swagger-ui .markdown code,.swagger-ui .renderedMarkdown code{background:rgba(0,0,0,.05);border-radius:4px;color:#9012fe;font-family:monospace;font-size:14px;font-weight:600;padding:5px 7px}.swagger-ui .markdown pre>code,.swagger-ui .renderedMarkdown pre>code{display:block}.swagger-ui .json-schema-2020-12{background-color:rgba(0,0,0,.05);border-radius:4px;margin:0 20px 15px;padding:12px 0 12px 20px}.swagger-ui .json-schema-2020-12:first-of-type{margin:20px}.swagger-ui .json-schema-2020-12:last-of-type{margin:0 20px}.swagger-ui .json-schema-2020-12--embedded{background-color:inherit;padding-bottom:0;padding-left:inherit;padding-right:inherit;padding-top:0}.swagger-ui .json-schema-2020-12-body{border-left:1px dashed rgba(0,0,0,.1);margin:2px 0}.swagger-ui .json-schema-2020-12-body--collapsed{display:none}.swagger-ui .json-schema-2020-12-accordion{border:none;outline:none;padding-left:0}.swagger-ui .json-schema-2020-12-accordion__children{display:inline-block}.swagger-ui .json-schema-2020-12-accordion__icon{display:inline-block;height:18px;vertical-align:bottom;width:18px}.swagger-ui .json-schema-2020-12-accordion__icon--expanded{transform:rotate(-90deg);transform-origin:50% 50%;transition:transform .15s ease-in}.swagger-ui .json-schema-2020-12-accordion__icon--collapsed{transform:rotate(0deg);transform-origin:50% 50%;transition:transform .15s ease-in}.swagger-ui .json-schema-2020-12-accordion__icon svg{height:20px;width:20px}.swagger-ui .json-schema-2020-12-expand-deep-button{border:none;color:#505050;color:#afaeae;font-family:sans-serif;font-size:12px;padding-right:0}.swagger-ui .json-schema-2020-12-keyword{margin:5px 0}.swagger-ui .json-schema-2020-12-keyword__children{border-left:1px dashed rgba(0,0,0,.1);margin:0 0 0 20px;padding:0}.swagger-ui .json-schema-2020-12-keyword__children--collapsed{display:none}.swagger-ui .json-schema-2020-12-keyword__name{font-size:12px;font-weight:700;margin-left:20px}.swagger-ui .json-schema-2020-12-keyword__name--primary{color:#3b4151;font-style:normal}.swagger-ui .json-schema-2020-12-keyword__name--secondary{color:#6b6b6b;font-style:italic}.swagger-ui .json-schema-2020-12-keyword__value{color:#6b6b6b;font-size:12px;font-style:italic;font-weight:400}.swagger-ui .json-schema-2020-12-keyword__value--primary{color:#3b4151;font-style:normal}.swagger-ui .json-schema-2020-12-keyword__value--secondary{color:#6b6b6b;font-style:italic}.swagger-ui .json-schema-2020-12-keyword__value--const,.swagger-ui .json-schema-2020-12-keyword__value--warning{border:1px dashed #6b6b6b;border-radius:4px;color:#3b4151;color:#6b6b6b;display:inline-block;font-family:monospace;font-style:normal;font-weight:600;line-height:1.5;margin-left:10px;padding:1px 4px}.swagger-ui .json-schema-2020-12-keyword__value--warning{border:1px dashed red;color:red}.swagger-ui .json-schema-2020-12-keyword__name--secondary+.json-schema-2020-12-keyword__value--secondary:before{content:\"=\"}.swagger-ui .json-schema-2020-12__attribute{color:#3b4151;font-family:monospace;font-size:12px;padding-left:10px;text-transform:lowercase}.swagger-ui .json-schema-2020-12__attribute--primary{color:#55a}.swagger-ui .json-schema-2020-12__attribute--muted{color:gray}.swagger-ui .json-schema-2020-12__attribute--warning{color:red}.swagger-ui .json-schema-2020-12-keyword--\\$vocabulary ul{border-left:1px dashed rgba(0,0,0,.1);margin:0 0 0 20px}.swagger-ui .json-schema-2020-12-\\$vocabulary-uri{margin-left:35px}.swagger-ui .json-schema-2020-12-\\$vocabulary-uri--disabled{-webkit-text-decoration:line-through;text-decoration:line-through}.swagger-ui .json-schema-2020-12-keyword--description{color:#6b6b6b;font-size:12px;margin-left:20px}.swagger-ui .json-schema-2020-12-keyword--description p{margin:0}.swagger-ui .json-schema-2020-12__title{color:#505050;display:inline-block;font-family:sans-serif;font-size:12px;font-weight:700;line-height:normal}.swagger-ui .json-schema-2020-12__title .json-schema-2020-12-keyword__name{margin:0}.swagger-ui .json-schema-2020-12-property{margin:7px 0}.swagger-ui .json-schema-2020-12-property .json-schema-2020-12__title{color:#3b4151;font-family:monospace;font-size:12px;font-weight:600;vertical-align:middle}.swagger-ui .json-schema-2020-12-keyword--properties>ul{border:none;margin:0;padding:0}.swagger-ui .json-schema-2020-12-property{list-style-type:none}.swagger-ui .json-schema-2020-12-property--required>.json-schema-2020-12:first-of-type>.json-schema-2020-12-head .json-schema-2020-12__title:after{color:red;content:\"*\";font-weight:700}.swagger-ui .json-schema-2020-12-keyword--patternProperties ul{border:none;margin:0;padding:0}.swagger-ui .json-schema-2020-12-keyword--patternProperties .json-schema-2020-12__title:first-of-type:after,.swagger-ui .json-schema-2020-12-keyword--patternProperties .json-schema-2020-12__title:first-of-type:before{color:#55a;content:\"/\"}.swagger-ui .json-schema-2020-12-keyword--enum>ul{display:inline-block;margin:0;padding:0}.swagger-ui .json-schema-2020-12-keyword--enum>ul li{display:inline;list-style-type:none}.swagger-ui .json-schema-2020-12__constraint{background-color:#805ad5;border-radius:4px;color:#3b4151;color:#fff;font-family:monospace;font-weight:600;line-height:1.5;margin-left:10px;padding:1px 3px}.swagger-ui .json-schema-2020-12__constraint--string{background-color:#d69e2e;color:#fff}.swagger-ui .json-schema-2020-12-keyword--dependentRequired>ul{display:inline-block;margin:0;padding:0}.swagger-ui .json-schema-2020-12-keyword--dependentRequired>ul li{display:inline;list-style-type:none}.swagger-ui .model-box .json-schema-2020-12:not(.json-schema-2020-12--embedded)>.json-schema-2020-12-head .json-schema-2020-12__title:first-of-type{font-size:16px}.swagger-ui .model-box>.json-schema-2020-12{margin:0}.swagger-ui .model-box .json-schema-2020-12{background-color:transparent;padding:0}.swagger-ui .model-box .json-schema-2020-12-accordion,.swagger-ui .model-box .json-schema-2020-12-expand-deep-button{background-color:transparent}.swagger-ui .models .json-schema-2020-12:not(.json-schema-2020-12--embedded)>.json-schema-2020-12-head .json-schema-2020-12__title:first-of-type{font-size:16px}\n\n/*# sourceMappingURL=swagger-ui.css.map*/" diff --git a/scripts/package-swagger.mjs b/scripts/package-swagger.mjs new file mode 100644 index 0000000000..42f173a7d6 --- /dev/null +++ b/scripts/package-swagger.mjs @@ -0,0 +1,22 @@ +import * as Fs from "fs/promises" + +const jsBundle = await fetch( + "https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js" +).then((res) => res.text()) +const jsPreset = await fetch( + "https://unpkg.com/swagger-ui-dist/swagger-ui-standalone-preset.js" +).then((res) => res.text()) +const css = await fetch( + "https://unpkg.com/swagger-ui-dist/swagger-ui.css" +).then((res) => res.text()) + +const source = `/* eslint-disable */ + +/** @internal */ +export const javascript = ${JSON.stringify(`${jsBundle}\n${jsPreset}`)} + +/** @internal */ +export const css = ${JSON.stringify(css)} +` + +await Fs.writeFile("packages/platform/src/internal/apiSwagger.ts", source) From 9425e0b82f8614912432a9ead7e8068836607660 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 26 Aug 2024 12:52:41 +1200 Subject: [PATCH 34/59] fix bearer auth --- packages/platform/src/ApiBuilder.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index cb458d692c..d592e4deac 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -491,6 +491,8 @@ export interface SecurityMiddleware { ): Handlers | ApiEndpoint.ApiEndpoint.ExcludeProvided, Endpoints> } +const bearerLen = `Bearer `.length + /** * @since 1.0.0 * @category middleware @@ -504,10 +506,9 @@ export const securityDecode = ( > => { switch (self._tag) { case "Bearer": { - const prefixLen = `${self.prefix} `.length return Effect.map( HttpServerRequest.HttpServerRequest, - (request) => Redacted.make((request.headers.authorization ?? "").slice(prefixLen)) as any + (request) => Redacted.make((request.headers.authorization ?? "").slice(bearerLen)) as any ) } case "ApiKey": { From d5695e5e6fd89b0796b31681d7a0aead5c9089f8 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 26 Aug 2024 12:54:10 +1200 Subject: [PATCH 35/59] fix import --- packages/platform/src/OpenApi.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/platform/src/OpenApi.ts b/packages/platform/src/OpenApi.ts index 2de0a8bbb0..935d5932db 100644 --- a/packages/platform/src/OpenApi.ts +++ b/packages/platform/src/OpenApi.ts @@ -10,9 +10,9 @@ import * as Option from "effect/Option" import type { ReadonlyRecord } from "effect/Record" import type { DeepMutable, Mutable } from "effect/Types" import * as Api from "./Api.js" +import * as ApiSchema from "./ApiSchema.js" import type { ApiSecurity } from "./ApiSecurity.js" import * as HttpMethod from "./HttpMethod.js" -import { ApiSchema } from "./index.js" /** * @since 1.0.0 From 8d0202d9fa912045c48800d1e2d8411478b809b0 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 26 Aug 2024 12:57:45 +1200 Subject: [PATCH 36/59] fix lint --- packages/platform-node/examples/api.ts | 23 +++++++++++------------ scripts/package-swagger.mjs | 1 + 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index 9fa1838ec6..3b56782abf 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -100,7 +100,6 @@ const ApiLive = ApiBuilder.api(api).pipe( ApiBuilder.serve(HttpMiddleware.logger).pipe( Layer.provide(ApiSwagger.layer()), - Layer.provide(ApiBuilder.middlewareOpenApi()), Layer.provide(ApiLive), Layer.provide(ApiBuilder.middlewareCors()), HttpServer.withLogAddress, @@ -109,14 +108,14 @@ ApiBuilder.serve(HttpMiddleware.logger).pipe( NodeRuntime.runMain ) -// Effect.gen(function*() { -// yield* Effect.sleep(2000) -// const client = yield* ApiClient.make(api, { -// baseUrl: "http://localhost:3000" -// }) -// const user = yield* client.users.findById({ path: { id: 123 } }) -// console.log(user) -// }).pipe( -// Effect.provide(HttpClient.layer), -// NodeRuntime.runMain -// ) +Effect.gen(function*() { + yield* Effect.sleep(2000) + const client = yield* ApiClient.make(api, { + baseUrl: "http://localhost:3000" + }) + const user = yield* client.users.findById({ path: { id: 123 } }) + console.log(user) +}).pipe( + Effect.provide(HttpClient.layer), + NodeRuntime.runMain +) diff --git a/scripts/package-swagger.mjs b/scripts/package-swagger.mjs index 42f173a7d6..ef0e713d8d 100644 --- a/scripts/package-swagger.mjs +++ b/scripts/package-swagger.mjs @@ -1,3 +1,4 @@ +/* eslint-disable no-undef */ import * as Fs from "fs/promises" const jsBundle = await fetch( From c494ef6393ca6509268710b53c090567e2dfe90a Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 26 Aug 2024 13:02:06 +1200 Subject: [PATCH 37/59] fix security example --- packages/platform/src/ApiBuilder.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index d592e4deac..6db3f30d5a 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -571,12 +571,10 @@ export const securityDecode = ( * readonly findUserByAccessToken: (accessToken: string) => Effect.Effect * }>() {} * - * const security = ApiSecurity.bearer() - * * const securityMiddleware = Effect.gen(function*() { * const accounts = yield* Accounts * return ApiBuilder.middlewareSecurity( - * security, + * ApiSecurity.bearer, * CurrentUser, * (token) => accounts.findUserByAccessToken(Redacted.value(token)) * ) From 94bf41140565c899c985e8cbd8484d0be5f64e85 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 26 Aug 2024 13:33:59 +1200 Subject: [PATCH 38/59] improve OpenApi extraction --- packages/platform/src/ApiError.ts | 15 ++++++++---- packages/platform/src/OpenApi.ts | 40 +++++++++++++++---------------- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/packages/platform/src/ApiError.ts b/packages/platform/src/ApiError.ts index 57dc8be927..6aa7562a09 100644 --- a/packages/platform/src/ApiError.ts +++ b/packages/platform/src/ApiError.ts @@ -59,10 +59,17 @@ export const Issue: Issue = Schema.Struct({ * @since 1.0.0 * @category errors */ -export class ApiDecodeError extends Schema.TaggedError()("ApiDecodeError", { - issues: Schema.Array(Issue), - message: Schema.String -}, ApiSchema.annotations({ status: 400 })) { +export class ApiDecodeError extends Schema.TaggedError()( + "ApiDecodeError", + { + issues: Schema.Array(Issue), + message: Schema.String + }, + ApiSchema.annotations({ + status: 400, + description: "ApiDecodeError: The request did not match the expected schema" + }) +) { /** * @since 1.0.0 */ diff --git a/packages/platform/src/OpenApi.ts b/packages/platform/src/OpenApi.ts index 935d5932db..7bca0aab0e 100644 --- a/packages/platform/src/OpenApi.ts +++ b/packages/platform/src/OpenApi.ts @@ -211,10 +211,7 @@ export const fromApi = (api: A): OpenAPISpec => { security: [], responses: { [success[1]]: { - description: success[0].pipe( - Option.flatMap(AST.getDescriptionAnnotation), - Option.getOrElse(() => "Success") - ) + description: Option.getOrElse(getDescriptionOrIdentifier(success[0]), () => "Success") } } } @@ -264,10 +261,7 @@ export const fromApi = (api: A): OpenAPISpec => { for (const [status, ast] of errors) { if (op.responses![status]) continue op.responses![status] = { - description: ast.pipe( - Option.flatMap(AST.getDescriptionAnnotation), - Option.getOrElse(() => "Error") - ) + description: Option.getOrElse(getDescriptionOrIdentifier(ast), () => "Error") } ast.pipe( Option.filter((ast) => !ApiSchema.getEmptyDecodeable(ast)), @@ -292,20 +286,11 @@ export const fromApi = (api: A): OpenAPISpec => { const getPropertySignatures = (ast: AST.AST): ReadonlyArray => { switch (ast._tag) { - case "TypeLiteral": { - return ast.propertySignatures - } - case "Union": { - return ast.types.flatMap(getPropertySignatures) - } case "Transformation": { return getPropertySignatures(ast.from) } - case "Suspend": { - return getPropertySignatures(ast.f()) - } default: { - return [] + return AST.getPropertySignatures(ast) } } } @@ -348,8 +333,8 @@ const makeProperty = (ps: AST.PropertySignature, type: OpenAPISpecParameter["in" schema: makeJsonSchema(Schema.make(ps.type)), required: !ps.isOptional } - AST.getDescriptionAnnotation(ps).pipe( - Option.orElse(() => AST.getDescriptionAnnotation(ps.type)), + getDescriptionOrIdentifier(Option.some(ps)).pipe( + Option.orElse(() => getDescriptionOrIdentifier(Option.some(ps.type))), Option.map((description) => { spec.description = description }) @@ -357,6 +342,21 @@ const makeProperty = (ps: AST.PropertySignature, type: OpenAPISpecParameter["in" return spec } +const getDescriptionOrIdentifier = (ast: Option.Option): Option.Option => + ast.pipe( + Option.map((ast) => + "to" in ast ? + { + ...ast.to.annotations, + ...ast.annotations + } : + ast.annotations + ), + Option.flatMapNullable((annotations) => + annotations[AST.DescriptionAnnotationId] ?? annotations[AST.IdentifierAnnotationId] as any + ) + ) + const makeJsonSchema = (schema: Schema.Schema.All): OpenAPIJSONSchema => { const jsonSchema = JSONSchema.make(schema as any) delete jsonSchema.$schema From 8cce69847521c18bd90ca137c7f9216cb828964a Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 26 Aug 2024 15:32:08 +1200 Subject: [PATCH 39/59] multipart requests --- packages/platform-node/examples/api.ts | 11 +++- packages/platform/src/ApiBuilder.ts | 27 ++++++-- packages/platform/src/ApiClient.ts | 22 +++++-- packages/platform/src/ApiEndpoint.ts | 5 +- packages/platform/src/ApiSchema.ts | 73 ++++++++++++++++++--- packages/platform/src/OpenApi.ts | 4 +- packages/platform/src/internal/multipart.ts | 6 +- 7 files changed, 122 insertions(+), 26 deletions(-) diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index 3b56782abf..c6ac5375fb 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -50,9 +50,9 @@ const users = ApiGroup.make("users").pipe( ), ApiGroup.add( ApiEndpoint.post("create", "/").pipe( - ApiEndpoint.payload(Schema.Struct({ + ApiEndpoint.payload(ApiSchema.Multipart(Schema.Struct({ name: Schema.String - })), + }))), ApiEndpoint.success(User) ) ), @@ -113,8 +113,13 @@ Effect.gen(function*() { const client = yield* ApiClient.make(api, { baseUrl: "http://localhost:3000" }) + + const data = new FormData() + data.append("name", "John") + console.log("Multipart", yield* client.users.create({ payload: data })) + const user = yield* client.users.findById({ path: { id: 123 } }) - console.log(user) + console.log("json", user) }).pipe( Effect.provide(HttpClient.layer), NodeRuntime.runMain diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index 6db3f30d5a..a347baf6ba 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -25,6 +25,7 @@ import { ApiDecodeError } from "./ApiError.js" import type * as ApiGroup from "./ApiGroup.js" import * as ApiSchema from "./ApiSchema.js" import type * as ApiSecurity from "./ApiSecurity.js" +import type { FileSystem } from "./FileSystem.js" import type * as HttpApp from "./HttpApp.js" import * as HttpMethod from "./HttpMethod.js" import * as HttpMiddleware from "./HttpMiddleware.js" @@ -33,6 +34,7 @@ import * as HttpServer from "./HttpServer.js" import * as HttpServerRequest from "./HttpServerRequest.js" import * as HttpServerResponse from "./HttpServerResponse.js" import * as OpenApi from "./OpenApi.js" +import type { Path } from "./Path.js" /** * The router that the API endpoints are attached to. @@ -54,6 +56,7 @@ export const serve: { never, never, | HttpServer.HttpServer + | HttpRouter.HttpRouter.DefaultServices | Exclude | Api.Api.Service > @@ -75,7 +78,7 @@ export const serve: { export const httpApp: Effect.Effect< HttpApp.Default, never, - ApiRouter | Api.Api.Service + ApiRouter | Api.Api.Service | HttpRouter.HttpRouter.DefaultServices > = Effect.gen(function*() { const api = yield* Api.Api const router = yield* ApiRouter.router @@ -618,14 +621,30 @@ export const middlewareSecurityVoid = > -) => HttpMethod.hasBody(request.method) ? request.json : Effect.succeed(urlParams) + urlParams: ReadonlyRecord>, + isMultipart: boolean +): Effect.Effect< + unknown, + never, + | FileSystem + | Path + | Scope +> => + HttpMethod.hasBody(request.method) + ? isMultipart + ? Effect.orDie(request.multipart) + : Effect.orDie(request.json) + : Effect.succeed(urlParams) const handlerToRoute = ( endpoint: ApiEndpoint.ApiEndpoint.Any, handler: ApiEndpoint.ApiEndpoint.Handler ): HttpRouter.Route => { const decodePath = Option.map(endpoint.pathSchema, Schema.decodeUnknown) + const isMultipart = endpoint.payloadSchema.pipe( + Option.map((schema) => ApiSchema.getMultipart(schema.ast)), + Option.getOrElse(() => false) + ) const decodePayload = Option.map(endpoint.payloadSchema, Schema.decodeUnknown) const encodeSuccess = Option.map(ApiEndpoint.schemaSuccess(endpoint), Schema.encodeUnknown) const successStatus = ApiSchema.getStatusSuccess(endpoint.successSchema) @@ -643,7 +662,7 @@ const handlerToRoute = ( Effect.bindTo("pathParams"), decodePayload._tag === "Some" ? Effect.bind("payload", (_) => - requestPayload(request, urlParams).pipe( + requestPayload(request, urlParams, isMultipart).pipe( Effect.orDie, Effect.flatMap((raw) => Effect.catchAll(decodePayload.value(raw), ApiDecodeError.refailParseError)) )) diff --git a/packages/platform/src/ApiClient.ts b/packages/platform/src/ApiClient.ts index b07198dddc..6eb4c8f21d 100644 --- a/packages/platform/src/ApiClient.ts +++ b/packages/platform/src/ApiClient.ts @@ -16,6 +16,7 @@ import * as HttpClientError from "./HttpClientError.js" import * as HttpClientRequest from "./HttpClientRequest.js" import * as HttpClientResponse from "./HttpClientResponse.js" import * as HttpMethod from "./HttpMethod.js" +import { ApiSchema } from "./index.js" /** * @since 1.0.0 @@ -122,23 +123,34 @@ export const make = ( Effect.flatMap(Effect.fail) ) } - const encodePayload = Option.map(endpoint.payloadSchema, Schema.encodeUnknown) + const isMultipart = endpoint.payloadSchema.pipe( + Option.map((schema) => ApiSchema.getMultipart(schema.ast)), + Option.getOrElse(() => false) + ) + const encodePayload = endpoint.payloadSchema.pipe( + Option.filter(() => !isMultipart), + Option.map(Schema.encodeUnknown) + ) client[group.name][endpoint.name] = (request: { readonly path: any readonly payload: any }) => { const url = request && request.path ? makeUrl(request && request.path) : endpoint.path const baseRequest = HttpClientRequest.make(endpoint.method)(url) - return (encodePayload._tag === "Some" ? - encodePayload.value(request.payload).pipe( + return (isMultipart ? + Effect.succeed(baseRequest.pipe( + HttpClientRequest.formDataBody(request.payload) + )) + : encodePayload._tag === "Some" + ? encodePayload.value(request.payload).pipe( Effect.flatMap((payload) => HttpMethod.hasBody(endpoint.method) ? HttpClientRequest.jsonBody(baseRequest, payload) : Effect.succeed(HttpClientRequest.setUrlParams(baseRequest, payload as any)) ), Effect.orDie - ) : - Effect.succeed(baseRequest)).pipe( + ) + : Effect.succeed(baseRequest)).pipe( Effect.flatMap((request) => httpClient(request).pipe( Effect.orDie, diff --git a/packages/platform/src/ApiEndpoint.ts b/packages/platform/src/ApiEndpoint.ts index 12e5d47239..e2fca86514 100644 --- a/packages/platform/src/ApiEndpoint.ts +++ b/packages/platform/src/ApiEndpoint.ts @@ -2,6 +2,7 @@ * @since 1.0.0 */ import * as Schema from "@effect/schema/Schema" +import type { Brand } from "effect/Brand" import * as Context from "effect/Context" import type { Effect } from "effect/Effect" import { dual } from "effect/Function" @@ -141,7 +142,9 @@ export declare namespace ApiEndpoint { */ export type ClientRequest = ( & ([Path] extends [void] ? {} : { readonly path: Path }) - & ([Payload] extends [never] ? {} : { readonly payload: Payload }) + & ([Payload] extends [never] ? {} + : [Payload] extends [Brand] ? { readonly payload: FormData } + : { readonly payload: Payload }) ) extends infer Req ? keyof Req extends never ? void : Req : void /** diff --git a/packages/platform/src/ApiSchema.ts b/packages/platform/src/ApiSchema.ts index ada64f1a21..991702406e 100644 --- a/packages/platform/src/ApiSchema.ts +++ b/packages/platform/src/ApiSchema.ts @@ -3,10 +3,19 @@ */ import * as AST from "@effect/schema/AST" import * as Schema from "@effect/schema/Schema" +import type { Brand } from "effect/Brand" import type { LazyArg } from "effect/Function" import { constVoid, dual } from "effect/Function" import * as Struct from "effect/Struct" +/** + * @since 1.0.0 + * @category annotations + */ +export const AnnotationMultipart: unique symbol = Symbol.for( + "@effect/platform/ApiSchema/AnnotationMultipart" +) + /** * @since 1.0.0 * @category annotations @@ -49,6 +58,20 @@ export const getEmptyDecodeable = (ast: AST.AST): boolean => { return annotations[AnnotationEmptyDecodeable] as boolean ?? false } +/** + * @since 1.0.0 + * @category annotations + */ +export const getMultipart = (ast: AST.AST): boolean => { + const annotations = ast._tag === "Transformation" ? + { + ...ast.to.annotations, + ...ast.annotations + } : + ast.annotations + return annotations[AnnotationMultipart] as boolean ?? false +} + /** * @since 1.0.0 * @category annotations @@ -95,7 +118,7 @@ export const getStatusError = (self: A): number => /** * @since 1.0.0 - * @category schemas + * @category params */ export interface PathParams extends Schema.Record$ {} @@ -103,13 +126,13 @@ type Void$ = typeof Schema.Void /** * @since 1.0.0 - * @category schemas + * @category empty response */ export const Empty = (status: number): typeof Schema.Void => Schema.Void.annotations(annotations({ status })) /** * @since 1.0.0 - * @category schemas + * @category empty response */ export interface asEmpty< S extends Schema.Schema.Any @@ -117,7 +140,7 @@ export interface asEmpty< /** * @since 1.0.0 - * @category schemas + * @category empty response */ export const asEmpty: { (options: { @@ -155,7 +178,7 @@ export const asEmpty: { /** * @since 1.0.0 - * @category schemas + * @category empty response */ export interface Created extends Void$ { readonly _: unique symbol @@ -163,13 +186,13 @@ export interface Created extends Void$ { /** * @since 1.0.0 - * @category schemas + * @category empty response */ export const Created: Created = Empty(201) as any /** * @since 1.0.0 - * @category schemas + * @category empty response */ export interface Accepted extends Void$ { readonly _: unique symbol @@ -177,13 +200,13 @@ export interface Accepted extends Void$ { /** * @since 1.0.0 - * @category schemas + * @category empty response */ export const Accepted: Accepted = Empty(202) as any /** * @since 1.0.0 - * @category schemas + * @category empty response */ export interface NoContent extends Void$ { readonly _: unique symbol @@ -191,6 +214,36 @@ export interface NoContent extends Void$ { /** * @since 1.0.0 - * @category schemas + * @category empty response */ export const NoContent: NoContent = Empty(204) as any + +/** + * @since 1.0.0 + * @category multipart + */ +export const MultipartTypeId: unique symbol = Symbol.for("@effect/platform/ApiSchema/Multipart") + +/** + * @since 1.0.0 + * @category multipart + */ +export type MultipartTypeId = typeof MultipartTypeId + +/** + * @since 1.0.0 + * @category multipart + */ +export interface Multipart + extends + Schema.Schema & Brand, Schema.Schema.Encoded, Schema.Schema.Context> +{} + +/** + * @since 1.0.0 + * @category multipart + */ +export const Multipart = (self: S): Multipart => + self.annotations({ + [AnnotationMultipart]: true + }) as any diff --git a/packages/platform/src/OpenApi.ts b/packages/platform/src/OpenApi.ts index 7bca0aab0e..a8501ff631 100644 --- a/packages/platform/src/OpenApi.ts +++ b/packages/platform/src/OpenApi.ts @@ -231,7 +231,7 @@ export const fromApi = (api: A): OpenAPISpec => { Option.map((schema) => { op.requestBody = { content: { - "application/json": { + [ApiSchema.getMultipart(schema.ast) ? "multipart/form-data" : "application/json"]: { schema: makeJsonSchema(schema) } }, @@ -504,7 +504,7 @@ export type OpenAPISpecResponses = Record * @category models * @since 1.0.0 */ -export type OpenApiSpecContentType = "application/json" | "application/xml" +export type OpenApiSpecContentType = "application/json" | "application/xml" | "multipart/form-data" | "text/plain" /** * @category models diff --git a/packages/platform/src/internal/multipart.ts b/packages/platform/src/internal/multipart.ts index 343d3ec91b..1705c5aeb5 100644 --- a/packages/platform/src/internal/multipart.ts +++ b/packages/platform/src/internal/multipart.ts @@ -103,7 +103,11 @@ export const withFieldMimeTypes = dual< /** @internal */ export const FileSchema: Schema.Schema = Schema.declare(isPersistedFile, { - identifier: "PersistedFile" + identifier: "PersistedFile", + jsonSchema: { + type: "string", + format: "binary" + } }) /** @internal */ From d955f7662ab71601a09cc98fed02df014f6b4955 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 26 Aug 2024 15:43:36 +1200 Subject: [PATCH 40/59] fix import --- packages/platform/src/ApiClient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/platform/src/ApiClient.ts b/packages/platform/src/ApiClient.ts index 6eb4c8f21d..62caf6f8d2 100644 --- a/packages/platform/src/ApiClient.ts +++ b/packages/platform/src/ApiClient.ts @@ -11,12 +11,12 @@ import { unify } from "effect/Unify" import * as Api from "./Api.js" import type { ApiEndpoint } from "./ApiEndpoint.js" import type { ApiGroup } from "./ApiGroup.js" +import * as ApiSchema from "./ApiSchema.js" import * as HttpClient from "./HttpClient.js" import * as HttpClientError from "./HttpClientError.js" import * as HttpClientRequest from "./HttpClientRequest.js" import * as HttpClientResponse from "./HttpClientResponse.js" import * as HttpMethod from "./HttpMethod.js" -import { ApiSchema } from "./index.js" /** * @since 1.0.0 From d3311957883f8cd9783cdc3cf3c4f0e45bb6b080 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 26 Aug 2024 16:28:29 +1200 Subject: [PATCH 41/59] add some jsdoc comments --- packages/platform/src/Api.ts | 23 +++++++++++++++++-- packages/platform/src/ApiBuilder.ts | 28 +++++++++++++++++++++-- packages/platform/src/ApiEndpoint.ts | 27 ++++++++++++++++++++++ packages/platform/src/ApiGroup.ts | 34 +++++++++++++++++++++++++++- packages/platform/src/ApiSchema.ts | 16 +++++++++++++ 5 files changed, 123 insertions(+), 5 deletions(-) diff --git a/packages/platform/src/Api.ts b/packages/platform/src/Api.ts index 61e4944a15..983471e85a 100644 --- a/packages/platform/src/Api.ts +++ b/packages/platform/src/Api.ts @@ -2,7 +2,7 @@ * @since 1.0.0 */ import * as AST from "@effect/schema/AST" -import * as Schema from "@effect/schema/Schema" +import type * as Schema from "@effect/schema/Schema" import * as Chunk from "effect/Chunk" import * as Context from "effect/Context" import { dual } from "effect/Function" @@ -36,6 +36,9 @@ export type TypeId = typeof TypeId export const isApi = (u: unknown): u is Api => Predicate.hasProperty(u, TypeId) /** + * An `Api` represents a collection of `ApiGroup`s. You can use an `Api` to + * represent your entire domain. + * * @since 1.0.0 * @category models */ @@ -98,6 +101,10 @@ const makeProto = (options: }): Api => Object.assign(Object.create(Proto), options) /** + * An empty `Api`. You can use this to start building your `Api`. + * + * You can add groups to this `Api` using the `addGroup` function. + * * @since 1.0.0 * @category constructors */ @@ -108,6 +115,8 @@ export const empty: Api = makeProto({ }) /** + * Add a `ApiGroup` to an `Api`. + * * @since 1.0.0 * @category constructors */ @@ -146,6 +155,11 @@ export const addGroup: { } ) /** + * Add an error schema to an `Api`, which is shared by all endpoints in the + * `Api`. + * + * Useful for adding error types from middleware or other shared error types. + * * @since 1.0.0 * @category errors */ @@ -176,7 +190,7 @@ export const addError: { ): Api => makeProto({ ...self, - errorSchema: Schema.Union( + errorSchema: ApiSchema.UnionUnify( self.errorSchema, schema.annotations(ApiSchema.annotations({ status: annotations?.status ?? ApiSchema.getStatusError(schema) @@ -218,6 +232,11 @@ export const annotate: { ) /** + * Extract metadata from an `Api`, which can be used to generate documentation + * or other tooling. + * + * See the `OpenApi` & `ApiClient` modules for examples of how to use this function. + * * @since 1.0.0 * @category reflection */ diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index a347baf6ba..a8ccad9d37 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -45,11 +45,17 @@ import type { Path } from "./Path.js" export class ApiRouter extends HttpRouter.Tag("@effect/platform/ApiBuilder/ApiRouter")() {} /** + * Build an `HttpApp` from an `Api` instance, and serve it using an + * `HttpServer`. + * + * Optionally, you can provide a middleware function that will be applied to + * the `HttpApp` before serving. + * * @since 1.0.0 * @category constructors */ export const serve: { - (): Layer.Layer + (): Layer.Layer ( middleware: (httpApp: HttpApp.Default) => HttpApp.Default ): Layer.Layer< @@ -72,6 +78,8 @@ export const serve: { ) /** + * Construct an `HttpApp` from an `Api` instance. + * * @since 1.0.0 * @category constructors */ @@ -97,6 +105,13 @@ export const httpApp: Effect.Effect< }) /** + * Build a root level `Layer` from an `Api` instance. + * + * The `Layer` will provide the `Api` service, and will require the + * implementation for all the `ApiGroup`'s contained in the `Api`. + * + * The resulting `Layer` can be provided to the `ApiBuilder.serve` layer. + * * @since 1.0.0 * @category constructors */ @@ -182,6 +197,13 @@ const makeHandlers = ( } /** + * Create a `Layer` that will implement all the endpoints in an `ApiGroup`. + * + * An unimplemented `Handlers` instance is passed to the `build` function, which + * you can use to add handlers to the group. + * + * You can implement endpoints using the `ApiBuilder.handle` api. + * * @since 1.0.0 * @category handlers */ @@ -238,6 +260,8 @@ export const group = < ) as any /** + * Add the implementation for an `ApiEndpoint` to a `Handlers` group. + * * @since 1.0.0 * @category handlers */ @@ -446,7 +470,7 @@ export const middlewareLayerScoped: { } /** - * A CORS middleware layer. + * A CORS middleware layer that can be provided to the `ApiBuilder.serve` layer. * * @since 1.0.0 * @category middleware diff --git a/packages/platform/src/ApiEndpoint.ts b/packages/platform/src/ApiEndpoint.ts index e2fca86514..8c694a9065 100644 --- a/packages/platform/src/ApiEndpoint.ts +++ b/packages/platform/src/ApiEndpoint.ts @@ -33,6 +33,9 @@ export type TypeId = typeof TypeId export const isApiEndpoint = (u: unknown): u is ApiEndpoint => Predicate.hasProperty(u, TypeId) /** + * Represents an API endpoint. An API endpoint is mapped to a single route on + * the underlying `HttpRouter`. + * * @since 1.0.0 * @category models */ @@ -322,6 +325,9 @@ export const del: ( ) => ApiEndpoint = make("DELETE") /** + * Set the schema for the success response of the endpoint. The status code + * will be inferred from the schema, otherwise it will default to 200. + * * @since 1.0.0 * @category result */ @@ -385,6 +391,9 @@ export const success: { ) /** + * Set the schema for the error response of the endpoint. The status code + * will be inferred from the schema, otherwise it will default to 500. + * * @since 1.0.0 * @category result */ @@ -450,6 +459,15 @@ export const error: { ) /** + * Set the schema for the request body of the endpoint. The schema will be + * used to validate the request body before the handler is called. + * + * For endpoints with no request body, the payload will use the url search + * parameters. + * + * You can set a multipart schema to handle file uploads by using the + * `ApiSchema.Multipart` combinator. + * * @since 1.0.0 * @category request */ @@ -501,6 +519,9 @@ export const payload: { ) /** + * Set the schema for the path parameters of the endpoint. The schema will be + * used to validate the path parameters before the handler is called. + * * @since 1.0.0 * @category request */ @@ -553,6 +574,8 @@ export const path: { ) /** + * Add a prefix to the path of the endpoint. + * * @since 1.0.0 * @category request */ @@ -584,6 +607,8 @@ export const schemaSuccess = ( successIsVoid(self) ? Option.none() : Option.some(self.successSchema as any) /** + * Merge the annotations of the endpoint with the provided context. + * * @since 1.0.0 * @category annotations */ @@ -600,6 +625,8 @@ export const annotateMerge: { ) /** + * Add an annotation to the endpoint. + * * @since 1.0.0 * @category annotations */ diff --git a/packages/platform/src/ApiGroup.ts b/packages/platform/src/ApiGroup.ts index d8bdc33f4e..4ec769778c 100644 --- a/packages/platform/src/ApiGroup.ts +++ b/packages/platform/src/ApiGroup.ts @@ -31,6 +31,11 @@ export type TypeId = typeof TypeId export const isApiGroup = (u: unknown): u is ApiGroup.Any => Predicate.hasProperty(u, TypeId) /** + * An `ApiGroup` is a collection of `ApiEndpoint`s. You can use an `ApiGroup` to + * represent a portion of your domain. + * + * The endpoints can be implemented later using the `ApiBuilder.group` api. + * * @since 1.0.0 * @category models */ @@ -138,6 +143,11 @@ const makeProto = => Object.assign(Object.create(Proto), options) /** + * An `ApiGroup` is a collection of `ApiEndpoint`s. You can use an `ApiGroup` to + * represent a portion of your domain. + * + * The endpoints can be implemented later using the `ApiBuilder.group` api. + * * @since 1.0.0 * @category constructors */ @@ -150,6 +160,8 @@ export const make = (name: Name): ApiGroup => }) /** + * Add an `ApiEndpoint` to an `ApiGroup`. + * * @since 1.0.0 * @category endpoints */ @@ -185,6 +197,9 @@ export const add: { })) /** + * Add an error schema to an `ApiGroup`, which is shared by all endpoints in the + * group. + * * @since 1.0.0 * @category errors */ @@ -215,7 +230,7 @@ export const addError: { ): ApiGroup => makeProto({ ...self, - errorSchema: Schema.Union( + errorSchema: ApiSchema.UnionUnify( self.errorSchema, schema.annotations(ApiSchema.annotations({ status: annotations?.status ?? ApiSchema.getStatusError(schema) @@ -225,6 +240,9 @@ export const addError: { ) /** + * Add a path prefix to all endpoints in an `ApiGroup`. Note that this will only + * add the prefix to the endpoints before this api is called. + * * @since 1.0.0 * @category endpoints */ @@ -248,6 +266,8 @@ export const prefix: { })) /** + * Merge the annotations of an `ApiGroup` with a new context. + * * @since 1.0.0 * @category annotations */ @@ -264,6 +284,8 @@ export const annotateMerge: { ) /** + * Add an annotation to an `ApiGroup`. + * * @since 1.0.0 * @category annotations */ @@ -280,6 +302,11 @@ export const annotate: { ) /** + * For each endpoint in an `ApiGroup`, update the annotations with a new + * context. + * + * Note that this will only update the annotations before this api is called. + * * @since 1.0.0 * @category annotations */ @@ -296,6 +323,11 @@ export const annotateEndpointsMerge: { ) /** + * For each endpoint in an `ApiGroup`, add an annotation. + * + * Note that this will only add the annotation to the endpoints before this api + * is called. + * * @since 1.0.0 * @category annotations */ diff --git a/packages/platform/src/ApiSchema.ts b/packages/platform/src/ApiSchema.ts index 991702406e..1abe906b00 100644 --- a/packages/platform/src/ApiSchema.ts +++ b/packages/platform/src/ApiSchema.ts @@ -116,6 +116,22 @@ export const getStatusErrorAST = (ast: AST.AST): number => getStatus(ast, 500) */ export const getStatusError = (self: A): number => getStatusErrorAST(self.ast) +/** + * @since 1.0.0 + */ +export const UnionUnify = (self: A, that: B): Schema.Schema< + A["Type"] | B["Type"], + A["Encoded"] | B["Encoded"], + A["Context"] | B["Context"] +> => { + const selfTypes = self.ast._tag === "Union" ? self.ast.types : [self.ast] + const thatTypes = that.ast._tag === "Union" ? that.ast.types : [that.ast] + return Schema.make(AST.Union.make([ + ...selfTypes, + ...thatTypes + ])) +} + /** * @since 1.0.0 * @category params From f109bcc9f84709cde1bf52066afd2259908e888d Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 26 Aug 2024 19:57:09 +1200 Subject: [PATCH 42/59] ApiEndpoint.addError --- packages/platform-node/examples/api.ts | 2 +- packages/platform/src/ApiEndpoint.ts | 32 +++++++++++--------------- packages/platform/src/ApiSchema.ts | 32 ++++++++++++++++++++++---- 3 files changed, 42 insertions(+), 24 deletions(-) diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index c6ac5375fb..04483dbddd 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -43,7 +43,7 @@ const users = ApiGroup.make("users").pipe( id: Schema.NumberFromString })), ApiEndpoint.success(User), - ApiEndpoint.error(Schema.String.pipe( + ApiEndpoint.addError(Schema.String.pipe( ApiSchema.asEmpty({ status: 413, decode: () => "boom" }) )) ) diff --git a/packages/platform/src/ApiEndpoint.ts b/packages/platform/src/ApiEndpoint.ts index 8c694a9065..320f66a3b5 100644 --- a/packages/platform/src/ApiEndpoint.ts +++ b/packages/platform/src/ApiEndpoint.ts @@ -391,13 +391,13 @@ export const success: { ) /** - * Set the schema for the error response of the endpoint. The status code + * Add an error response schema to the endpoint. The status code * will be inferred from the schema, otherwise it will default to 500. * * @since 1.0.0 * @category result */ -export const error: { +export const addError: { ( schema: E, annotations?: { @@ -413,7 +413,7 @@ export const error: { _R >( self: ApiEndpoint - ) => ApiEndpoint, _R | Schema.Schema.Context> + ) => ApiEndpoint, _R | Schema.Schema.Context> < Name extends string, Method extends HttpMethod, @@ -429,7 +429,7 @@ export const error: { annotations?: { readonly status?: number | undefined } - ): ApiEndpoint, _R | Schema.Schema.Context> + ): ApiEndpoint, _R | Schema.Schema.Context> } = dual( (args) => isApiEndpoint(args[0]), < @@ -447,13 +447,16 @@ export const error: { annotations?: { readonly status?: number | undefined } - ): ApiEndpoint, _R | Schema.Schema.Context> => + ): ApiEndpoint, _R | Schema.Schema.Context> => makeProto({ ...self as any, - errorSchema: schema.pipe( - Schema.annotations(ApiSchema.annotations({ - status: annotations?.status ?? ApiSchema.getStatusError(schema) - })) + errorSchema: ApiSchema.UnionUnify( + self.errorSchema, + schema.pipe( + Schema.annotations(ApiSchema.annotations({ + status: annotations?.status ?? ApiSchema.getStatusError(schema) + })) + ) ) }) ) @@ -588,15 +591,6 @@ export const prefix: { path: HttpRouter.prefixPath(self.path, prefix) }) as A) -/** - * @since 1.0.0 - * @category reflection - */ -export const successIsVoid = (self: A): boolean => { - const ast = Schema.encodedSchema(self.successSchema).ast - return ast._tag === "VoidKeyword" -} - /** * @since 1.0.0 * @category reflection @@ -604,7 +598,7 @@ export const successIsVoid = (self: A): boolean => { export const schemaSuccess = ( self: A ): Option.Option, unknown, ApiEndpoint.Context>> => - successIsVoid(self) ? Option.none() : Option.some(self.successSchema as any) + ApiSchema.isVoid(self.successSchema.ast) ? Option.none() : Option.some(self.successSchema as any) /** * Merge the annotations of the endpoint with the provided context. diff --git a/packages/platform/src/ApiSchema.ts b/packages/platform/src/ApiSchema.ts index 1abe906b00..3f4c4eef1a 100644 --- a/packages/platform/src/ApiSchema.ts +++ b/packages/platform/src/ApiSchema.ts @@ -92,12 +92,36 @@ export const annotations = ( * @since 1.0.0 * @category reflection */ -export const getStatusSuccessAST = (ast: AST.AST): number => { - const encoded = AST.encodedAST(ast) - const isVoid = encoded._tag === "VoidKeyword" - return getStatus(ast, isVoid ? 204 : 200) +export const isVoid = (ast: AST.AST): boolean => { + switch (ast._tag) { + case "VoidKeyword": { + return true + } + case "Transformation": { + return isVoid(ast.from) + } + case "Suspend": { + return isVoid(ast.f()) + } + case "Declaration": { + const surrogate = AST.getSurrogateAnnotation(ast) + if (surrogate._tag === "Some") { + return isVoid(surrogate.value) + } + return false + } + default: { + return false + } + } } +/** + * @since 1.0.0 + * @category reflection + */ +export const getStatusSuccessAST = (ast: AST.AST): number => getStatus(ast, isVoid(ast) ? 204 : 200) + /** * @since 1.0.0 * @category reflection From 027a032b8fec8f4be18b3b339347405a3e6b3586 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 26 Aug 2024 21:36:16 +1200 Subject: [PATCH 43/59] add set prefix to apis --- packages/platform-node/examples/api.ts | 10 +++++----- packages/platform/src/ApiEndpoint.ts | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index 04483dbddd..f80c328fde 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -39,10 +39,10 @@ const securityMiddleware = ApiBuilder.middlewareSecurity( const users = ApiGroup.make("users").pipe( ApiGroup.add( ApiEndpoint.get("findById", "/:id").pipe( - ApiEndpoint.path(Schema.Struct({ + ApiEndpoint.setPath(Schema.Struct({ id: Schema.NumberFromString })), - ApiEndpoint.success(User), + ApiEndpoint.setSuccess(User), ApiEndpoint.addError(Schema.String.pipe( ApiSchema.asEmpty({ status: 413, decode: () => "boom" }) )) @@ -50,15 +50,15 @@ const users = ApiGroup.make("users").pipe( ), ApiGroup.add( ApiEndpoint.post("create", "/").pipe( - ApiEndpoint.payload(ApiSchema.Multipart(Schema.Struct({ + ApiEndpoint.setPayload(ApiSchema.Multipart(Schema.Struct({ name: Schema.String }))), - ApiEndpoint.success(User) + ApiEndpoint.setSuccess(User) ) ), ApiGroup.add( ApiEndpoint.get("me", "/me").pipe( - ApiEndpoint.success(User) + ApiEndpoint.setSuccess(User) ) ), ApiGroup.addError(Unauthorized), diff --git a/packages/platform/src/ApiEndpoint.ts b/packages/platform/src/ApiEndpoint.ts index 320f66a3b5..0344fcc2c2 100644 --- a/packages/platform/src/ApiEndpoint.ts +++ b/packages/platform/src/ApiEndpoint.ts @@ -331,7 +331,7 @@ export const del: ( * @since 1.0.0 * @category result */ -export const success: { +export const setSuccess: { ( schema: S, annotations?: { @@ -474,7 +474,7 @@ export const addError: { * @since 1.0.0 * @category request */ -export const payload: { +export const setPayload: { ( schema: P & ApiEndpoint.ValidatePayload ): < @@ -528,7 +528,7 @@ export const payload: { * @since 1.0.0 * @category request */ -export const path: { +export const setPath: { ( schema: Path & ApiEndpoint.ValidatePath ): < From cc80fde8994230d512de843b2cc3d161b1613adb Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 26 Aug 2024 21:41:35 +1200 Subject: [PATCH 44/59] remove Declaration from ApiSchema.isVoid --- packages/platform/src/ApiSchema.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/packages/platform/src/ApiSchema.ts b/packages/platform/src/ApiSchema.ts index 3f4c4eef1a..5214f51208 100644 --- a/packages/platform/src/ApiSchema.ts +++ b/packages/platform/src/ApiSchema.ts @@ -103,13 +103,6 @@ export const isVoid = (ast: AST.AST): boolean => { case "Suspend": { return isVoid(ast.f()) } - case "Declaration": { - const surrogate = AST.getSurrogateAnnotation(ast) - if (surrogate._tag === "Some") { - return isVoid(surrogate.value) - } - return false - } default: { return false } From 810f5fb90ef0bc8ed17e0fbad8ef00b367a34bed Mon Sep 17 00:00:00 2001 From: Tim Date: Tue, 27 Aug 2024 16:06:20 +1200 Subject: [PATCH 45/59] send full response from handlers --- packages/platform-node/examples/api.ts | 16 +++++----- packages/platform/src/ApiBuilder.ts | 41 ++++++++++++++++++++++---- packages/platform/src/ApiEndpoint.ts | 19 ++++++++++++ 3 files changed, 61 insertions(+), 15 deletions(-) diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index f80c328fde..d1dc51183f 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -10,6 +10,7 @@ import { HttpClient, HttpMiddleware, HttpServer, + HttpServerResponse, OpenApi } from "@effect/platform" import { NodeHttpServer, NodeRuntime } from "@effect/platform-node" @@ -76,20 +77,17 @@ const api = Api.empty.pipe( const UsersLive = ApiBuilder.group(api, "users", (handlers) => handlers.pipe( - ApiBuilder.handle("create", (_) => - Effect.succeed( - new User({ - id: 1, - name: "John" - }) - )), + ApiBuilder.handle("create", (_) => Effect.succeed(new User({ ..._.payload, id: 123 }))), ApiBuilder.handle("findById", (_) => - Effect.succeed( + HttpServerResponse.schemaJson(User)( new User({ id: _.path.id, name: "John" }) - )), + ).pipe( + Effect.flatMap(HttpServerResponse.setCookie("token", "123")), + Effect.orDie + ), { withFullResponse: true }), ApiBuilder.handle("me", (_) => CurrentUser), securityMiddleware )) diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index a8ccad9d37..0ff8d8ab47 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -169,6 +169,7 @@ export declare namespace Handlers { readonly _tag: "Handler" readonly endpoint: ApiEndpoint.ApiEndpoint.Any readonly handler: ApiEndpoint.ApiEndpoint.Handler + readonly withFullResponse: boolean } | { readonly _tag: "Middleware" readonly middleware: Middleware @@ -251,7 +252,8 @@ export const group = < item.handler(request), (input) => Context.merge(context, input) ) - } + }, + item.withFullResponse )) } } @@ -265,9 +267,32 @@ export const group = < * @since 1.0.0 * @category handlers */ -export const handle = ( +export const handle: { + ( + name: Name, + handler: ApiEndpoint.ApiEndpoint.HandlerWithName + ): (self: Handlers) => Handlers< + EG | Exclude> | ApiDecodeError, + RG | ApiEndpoint.ApiEndpoint.ExcludeProvided, + ApiEndpoint.ApiEndpoint.ExcludeName + > + ( + name: Name, + handler: ApiEndpoint.ApiEndpoint.HandlerResponseWithName, + options: { + readonly withFullResponse: true + } + ): (self: Handlers) => Handlers< + EG | Exclude> | ApiDecodeError, + RG | ApiEndpoint.ApiEndpoint.ExcludeProvided, + ApiEndpoint.ApiEndpoint.ExcludeName + > +} = ( name: Name, - handler: ApiEndpoint.ApiEndpoint.HandlerWithName + handler: ApiEndpoint.ApiEndpoint.HandlerWithName, + options?: { + readonly withFullResponse: true + } ) => ( self: Handlers @@ -286,7 +311,8 @@ export const handle = + handler: ApiEndpoint.ApiEndpoint.Handler, + isFullResponse: boolean ): HttpRouter.Route => { const decodePath = Option.map(endpoint.pathSchema, Schema.decodeUnknown) const isMultipart = endpoint.payloadSchema.pipe( @@ -698,7 +725,9 @@ const handlerToRoute = ( } return handler(request) }), - encodeSuccess._tag === "Some" + isFullResponse ? + identity as (_: any) => Effect.Effect : + encodeSuccess._tag === "Some" ? Effect.flatMap((body) => encodeSuccess.value(body).pipe( Effect.flatMap((json) => HttpServerResponse.json(json, { status: successStatus })), diff --git a/packages/platform/src/ApiEndpoint.ts b/packages/platform/src/ApiEndpoint.ts index 0344fcc2c2..ff8c3ce943 100644 --- a/packages/platform/src/ApiEndpoint.ts +++ b/packages/platform/src/ApiEndpoint.ts @@ -13,6 +13,7 @@ import type * as Types from "effect/Types" import * as ApiSchema from "./ApiSchema.js" import type { HttpMethod } from "./HttpMethod.js" import * as HttpRouter from "./HttpRouter.js" +import type { HttpServerResponse } from "./HttpServerResponse.js" /** * @since 1.0.0 @@ -166,6 +167,14 @@ export declare namespace ApiEndpoint { request: Types.Simplify> ) => Effect, E, R> + /** + * @since 1.0.0 + * @category models + */ + export type HandlerResponse = ( + request: Types.Simplify> + ) => Effect + /** * @since 1.0.0 * @category models @@ -190,6 +199,16 @@ export declare namespace ApiEndpoint { R > + /** + * @since 1.0.0 + * @category models + */ + export type HandlerResponseWithName = HandlerResponse< + WithName, + E, + R + > + /** * @since 1.0.0 * @category models From cf6c1debb8cb309bc5e00673d650bfd14d0afaf1 Mon Sep 17 00:00:00 2001 From: Tim Date: Tue, 27 Aug 2024 16:26:38 +1200 Subject: [PATCH 46/59] support cookie auth --- packages/platform-node/examples/api.ts | 15 +++++++----- packages/platform/src/ApiBuilder.ts | 33 +++++++++++++++++++++++++- packages/platform/src/ApiEndpoint.ts | 19 +++++++++++++++ packages/platform/src/ApiSecurity.ts | 19 ++++++++++++--- 4 files changed, 76 insertions(+), 10 deletions(-) diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index d1dc51183f..dd1d7d435c 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -10,7 +10,6 @@ import { HttpClient, HttpMiddleware, HttpServer, - HttpServerResponse, OpenApi } from "@effect/platform" import { NodeHttpServer, NodeRuntime } from "@effect/platform-node" @@ -79,15 +78,19 @@ const UsersLive = ApiBuilder.group(api, "users", (handlers) => handlers.pipe( ApiBuilder.handle("create", (_) => Effect.succeed(new User({ ..._.payload, id: 123 }))), ApiBuilder.handle("findById", (_) => - HttpServerResponse.schemaJson(User)( + Effect.as( + ApiBuilder.securitySetCookie( + ApiSecurity.apiKey({ + in: "cookie", + key: "token" + }), + "secret123" + ), new User({ id: _.path.id, name: "John" }) - ).pipe( - Effect.flatMap(HttpServerResponse.setCookie("token", "123")), - Effect.orDie - ), { withFullResponse: true }), + )), ApiBuilder.handle("me", (_) => CurrentUser), securityMiddleware )) diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index 0ff8d8ab47..cad8dfe593 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -25,8 +25,9 @@ import { ApiDecodeError } from "./ApiError.js" import type * as ApiGroup from "./ApiGroup.js" import * as ApiSchema from "./ApiSchema.js" import type * as ApiSecurity from "./ApiSecurity.js" +import type { Cookie } from "./Cookies.js" import type { FileSystem } from "./FileSystem.js" -import type * as HttpApp from "./HttpApp.js" +import * as HttpApp from "./HttpApp.js" import * as HttpMethod from "./HttpMethod.js" import * as HttpMiddleware from "./HttpMiddleware.js" import * as HttpRouter from "./HttpRouter.js" @@ -571,6 +572,8 @@ export const securityDecode = ( const decode = unify( self.in === "query" ? HttpServerRequest.schemaSearchParams(schema) + : self.in === "cookie" + ? HttpServerRequest.schemaCookies(schema) : HttpServerRequest.schemaHeaders(schema) ) return Effect.match(decode, { @@ -603,6 +606,34 @@ export const securityDecode = ( } } +/** + * Set a cookie from an `ApiSecurity.ApiKey` instance. + * + * You can use this api before returning a response from an endpoint handler. + * + * ```ts + * ApiBuilder.handle( + * "authenticate", + * (_) => ApiBuilder.securitySetCookie(security, "secret123") + * ) + * ``` + * + * @since 1.0.0 + * @category middleware + */ +export const securitySetCookie = ( + self: ApiSecurity.ApiKey, + value: string | Redacted.Redacted, + options?: Cookie["options"] +): Effect.Effect => { + const stringValue = typeof value === "string" ? value : Redacted.value(value) + return HttpApp.appendPreResponseHandler((_req, response) => + HttpServerResponse.setCookie(response, self.key, stringValue, options).pipe( + Effect.orDie + ) + ) +} + /** * Make a middleware from an `ApiSecurity` instance, that can be used when * constructing a `Handlers` group. diff --git a/packages/platform/src/ApiEndpoint.ts b/packages/platform/src/ApiEndpoint.ts index ff8c3ce943..0e05d638e2 100644 --- a/packages/platform/src/ApiEndpoint.ts +++ b/packages/platform/src/ApiEndpoint.ts @@ -9,6 +9,7 @@ import { dual } from "effect/Function" import * as Option from "effect/Option" import { type Pipeable, pipeArguments } from "effect/Pipeable" import * as Predicate from "effect/Predicate" +import type { Redacted } from "effect/Redacted" import type * as Types from "effect/Types" import * as ApiSchema from "./ApiSchema.js" import type { HttpMethod } from "./HttpMethod.js" @@ -167,6 +168,14 @@ export declare namespace ApiEndpoint { request: Types.Simplify> ) => Effect, E, R> + /** + * @since 1.0.0 + * @category models + */ + export type HandlerRedacted = ( + request: Types.Simplify> + ) => Effect, Redacted], E, R> + /** * @since 1.0.0 * @category models @@ -209,6 +218,16 @@ export declare namespace ApiEndpoint { R > + /** + * @since 1.0.0 + * @category models + */ + export type HandlerRedactedWithName = HandlerRedacted< + WithName, + E, + R + > + /** * @since 1.0.0 * @category models diff --git a/packages/platform/src/ApiSecurity.ts b/packages/platform/src/ApiSecurity.ts index 218838559d..ffded1186a 100644 --- a/packages/platform/src/ApiSecurity.ts +++ b/packages/platform/src/ApiSecurity.ts @@ -62,7 +62,7 @@ export interface Bearer extends ApiSecurity.Proto { */ export interface ApiKey extends ApiSecurity.Proto { readonly _tag: "ApiKey" - readonly in: "header" | "query" + readonly in: "header" | "query" | "cookie" readonly key: string } @@ -91,6 +91,11 @@ const Proto = { } /** + * Create an Bearer token security scheme. + * + * You can implement some api middleware for this security scheme using + * `ApiBuilder.middlewareSecurity`. + * * @since 1.0.0 * @category constructors */ @@ -100,13 +105,21 @@ export const bearer: Bearer = Object.assign(Object.create(Proto), { }) /** + * Create an API key security scheme. + * + * You can implement some api middleware for this security scheme using + * `ApiBuilder.middlewareSecurity`. + * + * To set the correct cookie in a handler, you can use + * `ApiBuilder.securitySetCookie`. + * * @since 1.0.0 * @category constructors */ export const apiKey = (options: { readonly key: string - readonly in?: "header" | "query" | undefined -}): Bearer => + readonly in?: "header" | "query" | "cookie" | undefined +}): ApiKey => Object.assign(Object.create(Proto), { _tag: "ApiKey", key: options.key, From 2ac26feea3f056f4d1fef7f63fedc3335eb5fadc Mon Sep 17 00:00:00 2001 From: Tim Date: Tue, 27 Aug 2024 16:39:21 +1200 Subject: [PATCH 47/59] fix ApiSecurity annotations --- packages/platform/src/ApiSecurity.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/platform/src/ApiSecurity.ts b/packages/platform/src/ApiSecurity.ts index ffded1186a..19776be607 100644 --- a/packages/platform/src/ApiSecurity.ts +++ b/packages/platform/src/ApiSecurity.ts @@ -124,7 +124,7 @@ export const apiKey = (options: { _tag: "ApiKey", key: options.key, in: options.in ?? "header", - annotations: Context.empty + annotations: Context.empty() }) /** From 48bd32915ac368768eccb95163e649eedc4f599b Mon Sep 17 00:00:00 2001 From: Tim Date: Tue, 27 Aug 2024 16:45:45 +1200 Subject: [PATCH 48/59] secure cookies by default --- packages/platform/src/ApiBuilder.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index cad8dfe593..615392a963 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -628,8 +628,12 @@ export const securitySetCookie = ( ): Effect.Effect => { const stringValue = typeof value === "string" ? value : Redacted.value(value) return HttpApp.appendPreResponseHandler((_req, response) => - HttpServerResponse.setCookie(response, self.key, stringValue, options).pipe( - Effect.orDie + Effect.orDie( + HttpServerResponse.setCookie(response, self.key, stringValue, { + secure: true, + httpOnly: true, + ...options + }) ) ) } From 6bc4fa0b8c608433313047bd135b5f3eea8efef4 Mon Sep 17 00:00:00 2001 From: Tim Date: Tue, 27 Aug 2024 20:10:25 +1200 Subject: [PATCH 49/59] rename modules --- packages/platform-node/examples/api.ts | 80 ++-- packages/platform/src/ApiGroup.ts | 344 ----------------- packages/platform/src/{Api.ts => HttpApi.ts} | 152 ++++---- .../src/{ApiBuilder.ts => HttpApiBuilder.ts} | 223 +++++------ .../src/{ApiClient.ts => HttpApiClient.ts} | 29 +- .../{ApiEndpoint.ts => HttpApiEndpoint.ts} | 140 +++---- .../src/{ApiError.ts => HttpApiError.ts} | 18 +- packages/platform/src/HttpApiGroup.ts | 348 ++++++++++++++++++ .../src/{ApiSchema.ts => HttpApiSchema.ts} | 8 +- .../{ApiSecurity.ts => HttpApiSecurity.ts} | 32 +- .../src/{ApiSwagger.ts => HttpApiSwagger.ts} | 10 +- packages/platform/src/OpenApi.ts | 30 +- packages/platform/src/index.ts | 34 +- 13 files changed, 730 insertions(+), 718 deletions(-) delete mode 100644 packages/platform/src/ApiGroup.ts rename packages/platform/src/{Api.ts => HttpApi.ts} (52%) rename packages/platform/src/{ApiBuilder.ts => HttpApiBuilder.ts} (73%) rename packages/platform/src/{ApiClient.ts => HttpApiClient.ts} (85%) rename packages/platform/src/{ApiEndpoint.ts => HttpApiEndpoint.ts} (70%) rename packages/platform/src/{ApiError.ts => HttpApiError.ts} (80%) create mode 100644 packages/platform/src/HttpApiGroup.ts rename packages/platform/src/{ApiSchema.ts => HttpApiSchema.ts} (96%) rename packages/platform/src/{ApiSecurity.ts => HttpApiSecurity.ts} (73%) rename packages/platform/src/{ApiSwagger.ts => HttpApiSwagger.ts} (85%) diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index dd1d7d435c..cae0f46559 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -1,12 +1,12 @@ import { - Api, - ApiBuilder, - ApiClient, - ApiEndpoint, - ApiGroup, - ApiSchema, - ApiSecurity, - ApiSwagger, + HttpApi, + HttpApiBuilder, + HttpApiClient, + HttpApiEndpoint, + HttpApiGroup, + HttpApiSchema, + HttpApiSecurity, + HttpApiSwagger, HttpClient, HttpMiddleware, HttpServer, @@ -26,61 +26,61 @@ class CurrentUser extends Context.Tag("CurrentUser")() {} class Unauthorized extends Schema.TaggedError()("Unauthorized", { message: Schema.String -}, ApiSchema.annotations({ status: 401 })) {} +}, HttpApiSchema.annotations({ status: 401 })) {} -const security = ApiSecurity.bearer +const security = HttpApiSecurity.bearer -const securityMiddleware = ApiBuilder.middlewareSecurity( +const securityMiddleware = HttpApiBuilder.middlewareSecurity( security, CurrentUser, (token) => Effect.succeed(new User({ id: 1000, name: `Authenticated with ${Redacted.value(token)}` })) ) -const users = ApiGroup.make("users").pipe( - ApiGroup.add( - ApiEndpoint.get("findById", "/:id").pipe( - ApiEndpoint.setPath(Schema.Struct({ +const users = HttpApiGroup.make("users").pipe( + HttpApiGroup.add( + HttpApiEndpoint.get("findById", "/:id").pipe( + HttpApiEndpoint.setPath(Schema.Struct({ id: Schema.NumberFromString })), - ApiEndpoint.setSuccess(User), - ApiEndpoint.addError(Schema.String.pipe( - ApiSchema.asEmpty({ status: 413, decode: () => "boom" }) + HttpApiEndpoint.setSuccess(User), + HttpApiEndpoint.addError(Schema.String.pipe( + HttpApiSchema.asEmpty({ status: 413, decode: () => "boom" }) )) ) ), - ApiGroup.add( - ApiEndpoint.post("create", "/").pipe( - ApiEndpoint.setPayload(ApiSchema.Multipart(Schema.Struct({ + HttpApiGroup.add( + HttpApiEndpoint.post("create", "/").pipe( + HttpApiEndpoint.setPayload(HttpApiSchema.Multipart(Schema.Struct({ name: Schema.String }))), - ApiEndpoint.setSuccess(User) + HttpApiEndpoint.setSuccess(User) ) ), - ApiGroup.add( - ApiEndpoint.get("me", "/me").pipe( - ApiEndpoint.setSuccess(User) + HttpApiGroup.add( + HttpApiEndpoint.get("me", "/me").pipe( + HttpApiEndpoint.setSuccess(User) ) ), - ApiGroup.addError(Unauthorized), - ApiGroup.prefix("/users"), + HttpApiGroup.addError(Unauthorized), + HttpApiGroup.prefix("/users"), OpenApi.annotate({ security }) ) -const api = Api.empty.pipe( - Api.addGroup(users), +const api = HttpApi.empty.pipe( + HttpApi.addGroup(users), OpenApi.annotate({ title: "Users API", description: "API for managing users" }) ) -const UsersLive = ApiBuilder.group(api, "users", (handlers) => +const UsersLive = HttpApiBuilder.group(api, "users", (handlers) => handlers.pipe( - ApiBuilder.handle("create", (_) => Effect.succeed(new User({ ..._.payload, id: 123 }))), - ApiBuilder.handle("findById", (_) => + HttpApiBuilder.handle("create", (_) => Effect.succeed(new User({ ..._.payload, id: 123 }))), + HttpApiBuilder.handle("findById", (_) => Effect.as( - ApiBuilder.securitySetCookie( - ApiSecurity.apiKey({ + HttpApiBuilder.securitySetCookie( + HttpApiSecurity.apiKey({ in: "cookie", key: "token" }), @@ -91,18 +91,18 @@ const UsersLive = ApiBuilder.group(api, "users", (handlers) => name: "John" }) )), - ApiBuilder.handle("me", (_) => CurrentUser), + HttpApiBuilder.handle("me", (_) => CurrentUser), securityMiddleware )) -const ApiLive = ApiBuilder.api(api).pipe( +const ApiLive = HttpApiBuilder.api(api).pipe( Layer.provide(UsersLive) ) -ApiBuilder.serve(HttpMiddleware.logger).pipe( - Layer.provide(ApiSwagger.layer()), +HttpApiBuilder.serve(HttpMiddleware.logger).pipe( + Layer.provide(HttpApiSwagger.layer()), Layer.provide(ApiLive), - Layer.provide(ApiBuilder.middlewareCors()), + Layer.provide(HttpApiBuilder.middlewareCors()), HttpServer.withLogAddress, Layer.provide(NodeHttpServer.layer(createServer, { port: 3000 })), Layer.launch, @@ -111,7 +111,7 @@ ApiBuilder.serve(HttpMiddleware.logger).pipe( Effect.gen(function*() { yield* Effect.sleep(2000) - const client = yield* ApiClient.make(api, { + const client = yield* HttpApiClient.make(api, { baseUrl: "http://localhost:3000" }) diff --git a/packages/platform/src/ApiGroup.ts b/packages/platform/src/ApiGroup.ts deleted file mode 100644 index 4ec769778c..0000000000 --- a/packages/platform/src/ApiGroup.ts +++ /dev/null @@ -1,344 +0,0 @@ -/** - * @since 1.0.0 - */ -import * as Schema from "@effect/schema/Schema" -import * as Chunk from "effect/Chunk" -import * as Context from "effect/Context" -import { dual } from "effect/Function" -import { type Pipeable, pipeArguments } from "effect/Pipeable" -import * as Predicate from "effect/Predicate" -import * as ApiEndpoint from "./ApiEndpoint.js" -import type { ApiDecodeError } from "./ApiError.js" -import * as ApiSchema from "./ApiSchema.js" -import type { PathInput } from "./HttpRouter.js" - -/** - * @since 1.0.0 - * @category type ids - */ -export const TypeId: unique symbol = Symbol.for("@effect/platform/ApiGroup") - -/** - * @since 1.0.0 - * @category type ids - */ -export type TypeId = typeof TypeId - -/** - * @since 1.0.0 - * @category guards - */ -export const isApiGroup = (u: unknown): u is ApiGroup.Any => Predicate.hasProperty(u, TypeId) - -/** - * An `ApiGroup` is a collection of `ApiEndpoint`s. You can use an `ApiGroup` to - * represent a portion of your domain. - * - * The endpoints can be implemented later using the `ApiBuilder.group` api. - * - * @since 1.0.0 - * @category models - */ -export interface ApiGroup< - out Name extends string, - out Endpoints extends ApiEndpoint.ApiEndpoint.All = never, - in out Error = ApiDecodeError, - out ErrorR = never -> extends Pipeable { - readonly [TypeId]: TypeId - readonly name: Name - readonly endpoints: Chunk.Chunk - readonly errorSchema: Schema.Schema - readonly annotations: Context.Context -} - -/** - * @since 1.0.0 - * @category models - */ -export declare namespace ApiGroup { - /** - * @since 1.0.0 - * @category models - */ - export type Any = ApiGroup | ApiGroup | ApiGroup - - /** - * @since 1.0.0 - * @category models - */ - export interface Service { - readonly _: unique symbol - readonly name: Name - } - - /** - * @since 1.0.0 - * @category models - */ - export type ToService = Group extends ApiGroup - ? Service - : never - - /** - * @since 1.0.0 - * @category models - */ - export type WithName = Extract - - /** - * @since 1.0.0 - * @category models - */ - export type Endpoints = Group extends ApiGroup - ? _Endpoints - : never - - /** - * @since 1.0.0 - * @category models - */ - export type EndpointsWithName = Endpoints> - - /** - * @since 1.0.0 - * @category models - */ - export type Error = Group extends ApiGroup ? _Error - : never - - /** - * @since 1.0.0 - * @category models - */ - export type ErrorWithName = Error> - - /** - * @since 1.0.0 - * @category models - */ - export type Context = Group extends ApiGroup - ? _ErrorR | ApiEndpoint.ApiEndpoint.Context<_Endpoints> - : never - - /** - * @since 1.0.0 - * @category models - */ - export type ContextWithName = Context> -} - -const Proto = { - [TypeId]: TypeId, - pipe() { - return pipeArguments(this, arguments) - } -} - -const makeProto = (options: { - readonly name: Name - readonly endpoints: Chunk.Chunk - readonly errorSchema: Schema.Schema - readonly annotations: Context.Context -}): ApiGroup => Object.assign(Object.create(Proto), options) - -/** - * An `ApiGroup` is a collection of `ApiEndpoint`s. You can use an `ApiGroup` to - * represent a portion of your domain. - * - * The endpoints can be implemented later using the `ApiBuilder.group` api. - * - * @since 1.0.0 - * @category constructors - */ -export const make = (name: Name): ApiGroup => - makeProto({ - name, - endpoints: Chunk.empty(), - errorSchema: Schema.Never as any, - annotations: Context.empty() - }) - -/** - * Add an `ApiEndpoint` to an `ApiGroup`. - * - * @since 1.0.0 - * @category endpoints - */ -export const add: { - ( - endpoint: A - ): ( - self: ApiGroup - ) => ApiGroup - < - Name extends string, - Endpoints extends ApiEndpoint.ApiEndpoint.All, - Error, - ErrorR, - A extends ApiEndpoint.ApiEndpoint.All - >( - self: ApiGroup, - endpoint: A - ): ApiGroup -} = dual(2, < - Name extends string, - Endpoints extends ApiEndpoint.ApiEndpoint.All, - Error, - ErrorR, - A extends ApiEndpoint.ApiEndpoint.All ->( - self: ApiGroup, - endpoint: A -): ApiGroup => - makeProto({ - ...self, - endpoints: Chunk.append(self.endpoints, endpoint) - })) - -/** - * Add an error schema to an `ApiGroup`, which is shared by all endpoints in the - * group. - * - * @since 1.0.0 - * @category errors - */ -export const addError: { - ( - schema: Schema.Schema, - annotations?: { - readonly status?: number | undefined - } - ): ( - self: ApiGroup - ) => ApiGroup - ( - self: ApiGroup, - schema: Schema.Schema, - annotations?: { - readonly status?: number | undefined - } - ): ApiGroup -} = dual( - (args) => isApiGroup(args[0]), - ( - self: ApiGroup, - schema: Schema.Schema, - annotations?: { - readonly status?: number | undefined - } - ): ApiGroup => - makeProto({ - ...self, - errorSchema: ApiSchema.UnionUnify( - self.errorSchema, - schema.annotations(ApiSchema.annotations({ - status: annotations?.status ?? ApiSchema.getStatusError(schema) - })) - ) - }) -) - -/** - * Add a path prefix to all endpoints in an `ApiGroup`. Note that this will only - * add the prefix to the endpoints before this api is called. - * - * @since 1.0.0 - * @category endpoints - */ -export const prefix: { - ( - prefix: PathInput - ): ( - self: ApiGroup - ) => ApiGroup - ( - self: ApiGroup, - prefix: PathInput - ): ApiGroup -} = dual(2, ( - self: ApiGroup, - prefix: PathInput -): ApiGroup => - makeProto({ - ...self, - endpoints: Chunk.map(self.endpoints, ApiEndpoint.prefix(prefix)) - })) - -/** - * Merge the annotations of an `ApiGroup` with a new context. - * - * @since 1.0.0 - * @category annotations - */ -export const annotateMerge: { - (context: Context.Context): (self: A) => A - (self: A, context: Context.Context): A -} = dual( - 2, - (self: A, context: Context.Context): A => - makeProto({ - ...self as any, - annotations: Context.merge(self.annotations, context) - }) as A -) - -/** - * Add an annotation to an `ApiGroup`. - * - * @since 1.0.0 - * @category annotations - */ -export const annotate: { - (tag: Context.Tag, value: S): (self: A) => A - (self: A, tag: Context.Tag, value: S): A -} = dual( - 3, - (self: A, tag: Context.Tag, value: S): A => - makeProto({ - ...self as any, - annotations: Context.add(self.annotations, tag, value) - }) as A -) - -/** - * For each endpoint in an `ApiGroup`, update the annotations with a new - * context. - * - * Note that this will only update the annotations before this api is called. - * - * @since 1.0.0 - * @category annotations - */ -export const annotateEndpointsMerge: { - (context: Context.Context): (self: A) => A - (self: A, context: Context.Context): A -} = dual( - 2, - (self: A, context: Context.Context): A => - makeProto({ - ...self as any, - endpoints: Chunk.map(self.endpoints, ApiEndpoint.annotateMerge(context)) - }) as A -) - -/** - * For each endpoint in an `ApiGroup`, add an annotation. - * - * Note that this will only add the annotation to the endpoints before this api - * is called. - * - * @since 1.0.0 - * @category annotations - */ -export const annotateEndpoints: { - (tag: Context.Tag, value: S): (self: A) => A - (self: A, tag: Context.Tag, value: S): A -} = dual( - 3, - (self: A, tag: Context.Tag, value: S): A => - makeProto({ - ...self as any, - endpoints: Chunk.map(self.endpoints, ApiEndpoint.annotate(tag, value)) - }) as A -) diff --git a/packages/platform/src/Api.ts b/packages/platform/src/HttpApi.ts similarity index 52% rename from packages/platform/src/Api.ts rename to packages/platform/src/HttpApi.ts index 983471e85a..1beef41f9c 100644 --- a/packages/platform/src/Api.ts +++ b/packages/platform/src/HttpApi.ts @@ -10,10 +10,10 @@ import * as Option from "effect/Option" import type { Pipeable } from "effect/Pipeable" import { pipeArguments } from "effect/Pipeable" import * as Predicate from "effect/Predicate" -import * as ApiEndpoint from "./ApiEndpoint.js" -import { ApiDecodeError } from "./ApiError.js" -import * as ApiGroup from "./ApiGroup.js" -import * as ApiSchema from "./ApiSchema.js" +import * as HttpApiEndpoint from "./HttpApiEndpoint.js" +import { HttpApiDecodeError } from "./HttpApiError.js" +import * as HttpApiGroup from "./HttpApiGroup.js" +import * as HttpApiSchema from "./HttpApiSchema.js" import type { HttpMethod } from "./HttpMethod.js" import type * as HttpRouter from "./HttpRouter.js" @@ -21,7 +21,7 @@ import type * as HttpRouter from "./HttpRouter.js" * @since 1.0.0 * @category type ids */ -export const TypeId: unique symbol = Symbol.for("@effect/platform/Api") +export const TypeId: unique symbol = Symbol.for("@effect/platform/HttpApi") /** * @since 1.0.0 @@ -33,17 +33,17 @@ export type TypeId = typeof TypeId * @since 1.0.0 * @category guards */ -export const isApi = (u: unknown): u is Api => Predicate.hasProperty(u, TypeId) +export const isHttpApi = (u: unknown): u is HttpApi => Predicate.hasProperty(u, TypeId) /** - * An `Api` represents a collection of `ApiGroup`s. You can use an `Api` to + * An `HttpApi` represents a collection of `HttpApiGroup`s. You can use an `HttpApi` to * represent your entire domain. * * @since 1.0.0 * @category models */ -export interface Api< - out Groups extends ApiGroup.ApiGroup.Any = never, +export interface HttpApi< + out Groups extends HttpApiGroup.HttpApiGroup.Any = never, in out Error = never, out ErrorR = never > extends Pipeable { @@ -57,13 +57,15 @@ export interface Api< * @since 1.0.0 * @category tags */ -export const Api: Context.Tag = Context.GenericTag("@effect/platform/Api") +export const HttpApi: Context.Tag = Context.GenericTag( + "@effect/platform/HttpApi" +) /** * @since 1.0.0 * @category models */ -export declare namespace Api { +export declare namespace HttpApi { /** * @since 1.0.0 * @category models @@ -76,14 +78,14 @@ export declare namespace Api { * @since 1.0.0 * @category models */ - export type Any = Api | Api | Api + export type Any = HttpApi | HttpApi | HttpApi /** * @since 1.0.0 * @category models */ - export type Context = A extends Api - ? _ApiErrorR | ApiGroup.ApiGroup.Context<_Groups> + export type Context = A extends HttpApi + ? _ApiErrorR | HttpApiGroup.HttpApiGroup.Context<_Groups> : never } @@ -94,60 +96,60 @@ const Proto = { } } -const makeProto = (options: { +const makeProto = (options: { readonly groups: Chunk.Chunk readonly errorSchema: Schema.Schema readonly annotations: Context.Context -}): Api => Object.assign(Object.create(Proto), options) +}): HttpApi => Object.assign(Object.create(Proto), options) /** - * An empty `Api`. You can use this to start building your `Api`. + * An empty `HttpApi`. You can use this to start building your `HttpApi`. * - * You can add groups to this `Api` using the `addGroup` function. + * You can add groups to this `HttpApi` using the `addGroup` function. * * @since 1.0.0 * @category constructors */ -export const empty: Api = makeProto({ +export const empty: HttpApi = makeProto({ groups: Chunk.empty(), - errorSchema: ApiDecodeError as any, + errorSchema: HttpApiDecodeError as any, annotations: Context.empty() }) /** - * Add a `ApiGroup` to an `Api`. + * Add a `HttpApiGroup` to an `HttpApi`. * * @since 1.0.0 * @category constructors */ export const addGroup: { - ( + ( group: Group - ): ( - self: Api - ) => Api - ( + ): ( + self: HttpApi + ) => HttpApi + ( path: HttpRouter.PathInput, group: Group - ): ( - self: Api - ) => Api - ( - self: Api, + ): ( + self: HttpApi + ) => HttpApi + ( + self: HttpApi, group: Group - ): Api - ( - self: Api, + ): HttpApi + ( + self: HttpApi, path: HttpRouter.PathInput, group: Group - ): Api + ): HttpApi } = dual( - (args) => isApi(args[0]), + (args) => isHttpApi(args[0]), ( - self: Api.Any, - ...args: [group: ApiGroup.ApiGroup.Any] | [path: HttpRouter.PathInput, group: ApiGroup.ApiGroup.Any] - ): Api.Any => { - const group = args.length === 1 ? args[0] : ApiGroup.prefix(args[1] as any, args[0]) + self: HttpApi.Any, + ...args: [group: HttpApiGroup.HttpApiGroup.Any] | [path: HttpRouter.PathInput, group: HttpApiGroup.HttpApiGroup.Any] + ): HttpApi.Any => { + const group = args.length === 1 ? args[0] : HttpApiGroup.prefix(args[1] as any, args[0]) return makeProto({ ...self as any, groups: Chunk.append(self.groups, group) @@ -155,8 +157,8 @@ export const addGroup: { } ) /** - * Add an error schema to an `Api`, which is shared by all endpoints in the - * `Api`. + * Add an error schema to an `HttpApi`, which is shared by all endpoints in the + * `HttpApi`. * * Useful for adding error types from middleware or other shared error types. * @@ -169,31 +171,31 @@ export const addError: { annotations?: { readonly status?: number | undefined } - ): ( - self: Api - ) => Api - ( - self: Api, + ): ( + self: HttpApi + ) => HttpApi + ( + self: HttpApi, schema: Schema.Schema, annotations?: { readonly status?: number | undefined } - ): Api + ): HttpApi } = dual( - (args) => isApi(args[0]), - ( - self: Api, + (args) => isHttpApi(args[0]), + ( + self: HttpApi, schema: Schema.Schema, annotations?: { readonly status?: number | undefined } - ): Api => + ): HttpApi => makeProto({ ...self, - errorSchema: ApiSchema.UnionUnify( + errorSchema: HttpApiSchema.UnionUnify( self.errorSchema, - schema.annotations(ApiSchema.annotations({ - status: annotations?.status ?? ApiSchema.getStatusError(schema) + schema.annotations(HttpApiSchema.annotations({ + status: annotations?.status ?? HttpApiSchema.getStatusError(schema) })) ) }) @@ -204,11 +206,11 @@ export const addError: { * @category annotations */ export const annotateMerge: { - (context: Context.Context): (self: A) => A - (self: A, context: Context.Context): A + (context: Context.Context): (self: A) => A + (self: A, context: Context.Context): A } = dual( 2, - (self: A, context: Context.Context): A => + (self: A, context: Context.Context): A => makeProto({ ...self as any, annotations: Context.merge(self.annotations, context) @@ -220,11 +222,11 @@ export const annotateMerge: { * @category annotations */ export const annotate: { - (tag: Context.Tag, value: S): (self: A) => A - (self: A, tag: Context.Tag, value: S): A + (tag: Context.Tag, value: S): (self: A) => A + (self: A, tag: Context.Tag, value: S): A } = dual( 3, - (self: A, tag: Context.Tag, value: S): A => + (self: A, tag: Context.Tag, value: S): A => makeProto({ ...self as any, annotations: Context.add(self.annotations, tag, value) @@ -232,24 +234,24 @@ export const annotate: { ) /** - * Extract metadata from an `Api`, which can be used to generate documentation + * Extract metadata from an `HttpApi`, which can be used to generate documentation * or other tooling. * - * See the `OpenApi` & `ApiClient` modules for examples of how to use this function. + * See the `OpenApi` & `HttpApiClient` modules for examples of how to use this function. * * @since 1.0.0 * @category reflection */ -export const reflect = ( - self: Api, +export const reflect = ( + self: HttpApi, options: { readonly onGroup: (options: { - readonly group: ApiGroup.ApiGroup + readonly group: HttpApiGroup.HttpApiGroup readonly mergedAnnotations: Context.Context }) => void readonly onEndpoint: (options: { - readonly group: ApiGroup.ApiGroup - readonly endpoint: ApiEndpoint.ApiEndpoint + readonly group: HttpApiGroup.HttpApiGroup + readonly endpoint: HttpApiEndpoint.HttpApiEndpoint readonly mergedAnnotations: Context.Context readonly success: readonly [ast: Option.Option, status: number] readonly errors: ReadonlyMap> @@ -258,7 +260,7 @@ export const reflect = ( ) => { const apiErrors = extractErrors(self.errorSchema.ast, new Map()) - const groups = self.groups as Iterable> + const groups = self.groups as Iterable> for (const group of groups) { const groupErrors = extractErrors(group.errorSchema.ast, apiErrors) const groupAnnotations = Context.merge(self.annotations, group.annotations) @@ -266,16 +268,16 @@ export const reflect = ( group, mergedAnnotations: groupAnnotations }) - const endpoints = group.endpoints as Iterable> + const endpoints = group.endpoints as Iterable> for (const endpoint of endpoints) { const errors = extractErrors(endpoint.errorSchema.ast, groupErrors) const annotations = Context.merge(groupAnnotations, endpoint.annotations) const success = [ - ApiEndpoint.schemaSuccess(endpoint).pipe( + HttpApiEndpoint.schemaSuccess(endpoint).pipe( Option.map((schema) => schema.ast) ), - ApiSchema.getStatusSuccess(endpoint.successSchema) + HttpApiSchema.getStatusSuccess(endpoint.successSchema) ] as const options.onEndpoint({ group, @@ -294,14 +296,14 @@ const extractErrors = ( ast: AST.AST, inherited: ReadonlyMap> ): ReadonlyMap> => { - const topStatus = ApiSchema.getStatusErrorAST(ast) + const topStatus = HttpApiSchema.getStatusErrorAST(ast) const errors = new Map(inherited) function process(ast: AST.AST) { if (ast._tag === "NeverKeyword") { return } - const status = ApiSchema.getStatus(ast, topStatus) - const emptyDecodeable = ApiSchema.getEmptyDecodeable(ast) + const status = HttpApiSchema.getStatus(ast, topStatus) + const emptyDecodeable = HttpApiSchema.getEmptyDecodeable(ast) const current = errors.get(status) ?? Option.none() errors.set( status, diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/HttpApiBuilder.ts similarity index 73% rename from packages/platform/src/ApiBuilder.ts rename to packages/platform/src/HttpApiBuilder.ts index 615392a963..ee36da8213 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/HttpApiBuilder.ts @@ -19,14 +19,14 @@ import * as Redacted from "effect/Redacted" import type { Scope } from "effect/Scope" import type { Covariant, Mutable, NoInfer } from "effect/Types" import { unify } from "effect/Unify" -import * as Api from "./Api.js" -import * as ApiEndpoint from "./ApiEndpoint.js" -import { ApiDecodeError } from "./ApiError.js" -import type * as ApiGroup from "./ApiGroup.js" -import * as ApiSchema from "./ApiSchema.js" -import type * as ApiSecurity from "./ApiSecurity.js" import type { Cookie } from "./Cookies.js" import type { FileSystem } from "./FileSystem.js" +import * as HttpApi from "./HttpApi.js" +import * as HttpApiEndpoint from "./HttpApiEndpoint.js" +import { HttpApiDecodeError } from "./HttpApiError.js" +import type * as HttpApiGroup from "./HttpApiGroup.js" +import * as HttpApiSchema from "./HttpApiSchema.js" +import type * as HttpApiSecurity from "./HttpApiSecurity.js" import * as HttpApp from "./HttpApp.js" import * as HttpMethod from "./HttpMethod.js" import * as HttpMiddleware from "./HttpMiddleware.js" @@ -43,10 +43,10 @@ import type { Path } from "./Path.js" * @since 1.0.0 * @category router */ -export class ApiRouter extends HttpRouter.Tag("@effect/platform/ApiBuilder/ApiRouter")() {} +export class Router extends HttpRouter.Tag("@effect/platform/HttpApiBuilder/Router")() {} /** - * Build an `HttpApp` from an `Api` instance, and serve it using an + * Build an `HttpApp` from an `HttpApi` instance, and serve it using an * `HttpServer`. * * Optionally, you can provide a middleware function that will be applied to @@ -56,7 +56,7 @@ export class ApiRouter extends HttpRouter.Tag("@effect/platform/ApiBuilder/ApiRo * @category constructors */ export const serve: { - (): Layer.Layer + (): Layer.Layer ( middleware: (httpApp: HttpApp.Default) => HttpApp.Default ): Layer.Layer< @@ -65,7 +65,7 @@ export const serve: { | HttpServer.HttpServer | HttpRouter.HttpRouter.DefaultServices | Exclude - | Api.Api.Service + | HttpApi.HttpApi.Service > } = (middleware?: HttpMiddleware.HttpMiddleware.Applied): Layer.Layer< never, @@ -75,11 +75,11 @@ export const serve: { httpApp.pipe( Effect.map(HttpServer.serve(middleware!)), Layer.unwrapEffect, - Layer.provide(ApiRouter.Live) + Layer.provide(Router.Live) ) /** - * Construct an `HttpApp` from an `Api` instance. + * Construct an `HttpApp` from an `HttpApi` instance. * * @since 1.0.0 * @category constructors @@ -87,11 +87,11 @@ export const serve: { export const httpApp: Effect.Effect< HttpApp.Default, never, - ApiRouter | Api.Api.Service | HttpRouter.HttpRouter.DefaultServices + Router | HttpApi.HttpApi.Service | HttpRouter.HttpRouter.DefaultServices > = Effect.gen(function*() { - const api = yield* Api.Api - const router = yield* ApiRouter.router - const apiMiddleware = yield* Effect.serviceOption(ApiMiddleware) + const api = yield* HttpApi.HttpApi + const router = yield* Router.router + const apiMiddleware = yield* Effect.serviceOption(Middleware) const errorSchema = makeErrorSchema(api as any) const encodeError = Schema.encodeUnknown(errorSchema) return router.pipe( @@ -106,26 +106,26 @@ export const httpApp: Effect.Effect< }) /** - * Build a root level `Layer` from an `Api` instance. + * Build a root level `Layer` from an `HttpApi` instance. * - * The `Layer` will provide the `Api` service, and will require the - * implementation for all the `ApiGroup`'s contained in the `Api`. + * The `Layer` will provide the `HttpApi` service, and will require the + * implementation for all the `HttpApiGroup`'s contained in the `HttpApi`. * - * The resulting `Layer` can be provided to the `ApiBuilder.serve` layer. + * The resulting `Layer` can be provided to the `HttpApiBuilder.serve` layer. * * @since 1.0.0 * @category constructors */ -export const api = ( - self: Api.Api -): Layer.Layer | ErrorR> => - Layer.succeed(Api.Api, self) as any +export const api = ( + self: HttpApi.HttpApi +): Layer.Layer | ErrorR> => + Layer.succeed(HttpApi.HttpApi, self) as any /** * @since 1.0.0 * @category handlers */ -export const HandlersTypeId: unique symbol = Symbol.for("@effect/platform/ApiBuilder/Handlers") +export const HandlersTypeId: unique symbol = Symbol.for("@effect/platform/HttpApiBuilder/Handlers") /** * @since 1.0.0 @@ -134,7 +134,7 @@ export const HandlersTypeId: unique symbol = Symbol.for("@effect/platform/ApiBui export type HandlersTypeId = typeof HandlersTypeId /** - * Represents a handled, or partially handled, `ApiGroup`. + * Represents a handled, or partially handled, `HttpApiGroup`. * * @since 1.0.0 * @category handlers @@ -142,12 +142,12 @@ export type HandlersTypeId = typeof HandlersTypeId export interface Handlers< E, R, - Endpoints extends ApiEndpoint.ApiEndpoint.All = never + Endpoints extends HttpApiEndpoint.HttpApiEndpoint.All = never > extends Pipeable { readonly [HandlersTypeId]: { _Endpoints: Covariant } - readonly group: ApiGroup.ApiGroup + readonly group: HttpApiGroup.HttpApiGroup readonly handlers: Chunk.Chunk> } @@ -168,8 +168,8 @@ export declare namespace Handlers { */ export type Item = { readonly _tag: "Handler" - readonly endpoint: ApiEndpoint.ApiEndpoint.Any - readonly handler: ApiEndpoint.ApiEndpoint.Handler + readonly endpoint: HttpApiEndpoint.HttpApiEndpoint.Any + readonly handler: HttpApiEndpoint.HttpApiEndpoint.Handler readonly withFullResponse: boolean } | { readonly _tag: "Middleware" @@ -186,9 +186,9 @@ const HandlersProto = { } } -const makeHandlers = ( +const makeHandlers = ( options: { - readonly group: ApiGroup.ApiGroup + readonly group: HttpApiGroup.HttpApiGroup readonly handlers: Chunk.Chunk> } ): Handlers => { @@ -199,18 +199,18 @@ const makeHandlers = ( } /** - * Create a `Layer` that will implement all the endpoints in an `ApiGroup`. + * Create a `Layer` that will implement all the endpoints in an `HttpApiGroup`. * * An unimplemented `Handlers` instance is passed to the `build` function, which * you can use to add handlers to the group. * - * You can implement endpoints using the `ApiBuilder.handle` api. + * You can implement endpoints using the `HttpApiBuilder.handle` api. * * @since 1.0.0 * @category handlers */ export const group = < - Groups extends ApiGroup.ApiGroup.Any, + Groups extends HttpApiGroup.HttpApiGroup.Any, ApiError, ApiErrorR, const Name extends Groups["name"], @@ -218,19 +218,19 @@ export const group = < EX = never, RX = never >( - api: Api.Api, + api: HttpApi.HttpApi, groupName: Name, build: ( - handlers: Handlers> + handlers: Handlers> ) => - | Handlers | ApiGroup.ApiGroup.ErrorWithName, RH> - | Effect.Effect | ApiGroup.ApiGroup.ErrorWithName, RH>, EX, RX> + | Handlers | HttpApiGroup.HttpApiGroup.ErrorWithName, RH> + | Effect.Effect | HttpApiGroup.HttpApiGroup.ErrorWithName, RH>, EX, RX> ): Layer.Layer< - ApiGroup.ApiGroup.Service, + HttpApiGroup.HttpApiGroup.Service, EX, - RX | RH | ApiGroup.ApiGroup.ContextWithName | ApiErrorR + RX | RH | HttpApiGroup.HttpApiGroup.ContextWithName | ApiErrorR > => - ApiRouter.use((router) => + Router.use((router) => Effect.gen(function*() { const context = yield* Effect.context() const group = Chunk.findFirst(api.groups, (group) => group.name === groupName) @@ -263,34 +263,34 @@ export const group = < ) as any /** - * Add the implementation for an `ApiEndpoint` to a `Handlers` group. + * Add the implementation for an `HttpApiEndpoint` to a `Handlers` group. * * @since 1.0.0 * @category handlers */ export const handle: { - ( + ( name: Name, - handler: ApiEndpoint.ApiEndpoint.HandlerWithName + handler: HttpApiEndpoint.HttpApiEndpoint.HandlerWithName ): (self: Handlers) => Handlers< - EG | Exclude> | ApiDecodeError, - RG | ApiEndpoint.ApiEndpoint.ExcludeProvided, - ApiEndpoint.ApiEndpoint.ExcludeName + EG | Exclude> | HttpApiDecodeError, + RG | HttpApiEndpoint.HttpApiEndpoint.ExcludeProvided, + HttpApiEndpoint.HttpApiEndpoint.ExcludeName > - ( + ( name: Name, - handler: ApiEndpoint.ApiEndpoint.HandlerResponseWithName, + handler: HttpApiEndpoint.HttpApiEndpoint.HandlerResponseWithName, options: { readonly withFullResponse: true } ): (self: Handlers) => Handlers< - EG | Exclude> | ApiDecodeError, - RG | ApiEndpoint.ApiEndpoint.ExcludeProvided, - ApiEndpoint.ApiEndpoint.ExcludeName + EG | Exclude> | HttpApiDecodeError, + RG | HttpApiEndpoint.HttpApiEndpoint.ExcludeProvided, + HttpApiEndpoint.HttpApiEndpoint.ExcludeName > -} = ( +} = ( name: Name, - handler: ApiEndpoint.ApiEndpoint.HandlerWithName, + handler: HttpApiEndpoint.HttpApiEndpoint.HandlerWithName, options?: { readonly withFullResponse: true } @@ -298,9 +298,9 @@ export const handle: { ( self: Handlers ): Handlers< - EG | Exclude> | ApiDecodeError, - RG | ApiEndpoint.ApiEndpoint.ExcludeProvided, - ApiEndpoint.ApiEndpoint.ExcludeName + EG | Exclude> | HttpApiDecodeError, + RG | HttpApiEndpoint.HttpApiEndpoint.ExcludeProvided, + HttpApiEndpoint.HttpApiEndpoint.ExcludeName > => { const o = Chunk.findFirst(self.group.endpoints, (endpoint) => endpoint.name === name) if (o._tag === "None") { @@ -322,7 +322,7 @@ export const handle: { * Add `HttpMiddleware` to a `Handlers` group. * * Any errors are required to have a corresponding schema in the API. - * You can add middleware errors to an `ApiGroup` using the `ApiGroup.addError` + * You can add middleware errors to an `HttpApiGroup` using the `HttpApiGroup.addError` * api. * * @since 1.0.0 @@ -330,10 +330,10 @@ export const handle: { */ export const middleware = (middleware: Handlers.Middleware) => - ( + ( self: Handlers - ): Handlers, Endpoints> => - makeHandlers, Endpoints>({ + ): Handlers, Endpoints> => + makeHandlers, Endpoints>({ ...self as any, handlers: Chunk.append(self.handlers, { _tag: "Middleware", @@ -345,8 +345,8 @@ export const middleware = * @since 1.0.0 * @category middleware */ -export class ApiMiddleware extends Context.Tag("@effect/platform/ApiBuilder/ApiMiddleware")< - ApiMiddleware, +export class Middleware extends Context.Tag("@effect/platform/HttpApiBuilder/Middleware")< + Middleware, HttpMiddleware.HttpMiddleware >() {} @@ -368,7 +368,7 @@ const middlewareAdd = (middleware: HttpMiddleware.HttpMiddleware): Effect.Effect Effect.map( Effect.context(), (context) => { - const current = Context.getOption(context, ApiMiddleware) + const current = Context.getOption(context, Middleware) const withContext: HttpMiddleware.HttpMiddleware = (httpApp) => Effect.mapInputContext(middleware(httpApp), (input) => Context.merge(context, input)) return current._tag === "None" ? withContext : (httpApp) => withContext(current.value(httpApp)) @@ -379,14 +379,14 @@ const middlewareAddNoContext = ( middleware: HttpMiddleware.HttpMiddleware ): Effect.Effect => Effect.map( - Effect.serviceOption(ApiMiddleware), + Effect.serviceOption(Middleware), (current): HttpMiddleware.HttpMiddleware => { return current._tag === "None" ? middleware : (httpApp) => middleware(current.value(httpApp)) } ) /** - * Create an `Api` level middleware `Layer`. + * Create an `HttpApi` level middleware `Layer`. * * @since 1.0.0 * @category middleware @@ -404,15 +404,15 @@ export const middlewareLayer: { readonly withContext: true } ): Layer.Layer | RX> - ( - api: Api.Api, + ( + api: HttpApi.HttpApi, middleware: ApiMiddleware.Fn> | Effect.Effect>, EX, RX>, options?: { readonly withContext?: false | undefined } ): Layer.Layer - ( - api: Api.Api, + ( + api: HttpApi.HttpApi, middleware: ApiMiddleware.Fn, R> | Effect.Effect, R>, EX, RX>, options: { readonly withContext: true @@ -425,24 +425,24 @@ export const middlewareLayer: { readonly withContext?: boolean | undefined } | undefined ] | [ - api: Api.Api.Any, + api: HttpApi.HttpApi.Any, middleware: ApiMiddleware.Fn | Effect.Effect, any, any>, options?: { readonly withContext?: boolean | undefined } | undefined ] ): any => { - const apiFirst = Api.isApi(args[0]) + const apiFirst = HttpApi.isHttpApi(args[0]) const withContext = apiFirst ? args[2]?.withContext === true : (args as any)[1]?.withContext === true const add = withContext ? middlewareAdd : middlewareAddNoContext const middleware = apiFirst ? args[1] : args[0] return Effect.isEffect(middleware) - ? Layer.effect(ApiMiddleware, Effect.flatMap(middleware as any, add)) - : Layer.effect(ApiMiddleware, add(middleware as any)) + ? Layer.effect(Middleware, Effect.flatMap(middleware as any, add)) + : Layer.effect(Middleware, add(middleware as any)) } /** - * Create an `Api` level middleware `Layer`, that has a `Scope` provided to + * Create an `HttpApi` level middleware `Layer`, that has a `Scope` provided to * the constructor. * * @since 1.0.0 @@ -461,15 +461,15 @@ export const middlewareLayerScoped: { readonly withContext: true } ): Layer.Layer | Exclude> - ( - api: Api.Api, + ( + api: HttpApi.HttpApi, middleware: Effect.Effect>, EX, RX>, options?: { readonly withContext?: false | undefined } ): Layer.Layer> - ( - api: Api.Api, + ( + api: HttpApi.HttpApi, middleware: Effect.Effect, R>, EX, RX>, options: { readonly withContext: true @@ -482,22 +482,22 @@ export const middlewareLayerScoped: { readonly withContext?: boolean | undefined } | undefined ] | [ - api: Api.Api.Any, + api: HttpApi.HttpApi.Any, middleware: ApiMiddleware.Fn | Effect.Effect, any, any>, options?: { readonly withContext?: boolean | undefined } | undefined ] ): any => { - const apiFirst = Api.isApi(args[0]) + const apiFirst = HttpApi.isHttpApi(args[0]) const withContext = apiFirst ? args[2]?.withContext === true : (args as any)[1]?.withContext === true const add = withContext ? middlewareAdd : middlewareAddNoContext const middleware = apiFirst ? args[1] : args[0] - return Layer.scoped(ApiMiddleware, Effect.flatMap(middleware as any, add)) + return Layer.scoped(Middleware, Effect.flatMap(middleware as any, add)) } /** - * A CORS middleware layer that can be provided to the `ApiBuilder.serve` layer. + * A CORS middleware layer that can be provided to the `HttpApiBuilder.serve` layer. * * @since 1.0.0 * @category middleware @@ -523,10 +523,10 @@ export const middlewareOpenApi = ( options?: { readonly path?: HttpRouter.PathInput | undefined } | undefined -): Layer.Layer => - ApiRouter.use((router) => +): Layer.Layer => + Router.use((router) => Effect.gen(function*() { - const api = yield* Api.Api + const api = yield* HttpApi.HttpApi const spec = OpenApi.fromApi(api) const response = yield* HttpServerResponse.json(spec).pipe( Effect.orDie @@ -540,9 +540,9 @@ export const middlewareOpenApi = ( * @category middleware */ export interface SecurityMiddleware { - ( + ( self: Handlers - ): Handlers | ApiEndpoint.ApiEndpoint.ExcludeProvided, Endpoints> + ): Handlers | HttpApiEndpoint.HttpApiEndpoint.ExcludeProvided, Endpoints> } const bearerLen = `Bearer `.length @@ -551,10 +551,10 @@ const bearerLen = `Bearer `.length * @since 1.0.0 * @category middleware */ -export const securityDecode = ( +export const securityDecode = ( self: Security ): Effect.Effect< - ApiSecurity.ApiSecurity.Type, + HttpApiSecurity.HttpApiSecurity.Type, never, HttpServerRequest.HttpServerRequest | HttpServerRequest.ParsedSearchParams > => { @@ -582,7 +582,7 @@ export const securityDecode = ( }) } case "Basic": { - const empty: ApiSecurity.ApiSecurity.Type = { + const empty: HttpApiSecurity.HttpApiSecurity.Type = { username: "", password: Redacted.make("") } as any @@ -607,7 +607,7 @@ export const securityDecode = ( } /** - * Set a cookie from an `ApiSecurity.ApiKey` instance. + * Set a cookie from an `HttpApiSecurity.HttpApiKey` instance. * * You can use this api before returning a response from an endpoint handler. * @@ -622,7 +622,7 @@ export const securityDecode = ( * @category middleware */ export const securitySetCookie = ( - self: ApiSecurity.ApiKey, + self: HttpApiSecurity.ApiKey, value: string | Redacted.Redacted, options?: Cookie["options"] ): Effect.Effect => { @@ -639,7 +639,7 @@ export const securitySetCookie = ( } /** - * Make a middleware from an `ApiSecurity` instance, that can be used when + * Make a middleware from an `HttpApiSecurity` instance, that can be used when * constructing a `Handlers` group. * * @since 1.0.0 @@ -668,11 +668,11 @@ export const securitySetCookie = ( * ) * }) */ -export const middlewareSecurity = ( +export const middlewareSecurity = ( self: Security, tag: Context.Tag, f: ( - credentials: ApiSecurity.ApiSecurity.Type + credentials: HttpApiSecurity.HttpApiSecurity.Type ) => Effect.Effect ): SecurityMiddleware => middleware(Effect.provideServiceEffect( @@ -681,7 +681,7 @@ export const middlewareSecurity = /** - * Make a middleware from an `ApiSecurity` instance, that can be used when + * Make a middleware from an `HttpApiSecurity` instance, that can be used when * constructing a `Handlers` group. * * This version does not supply any context to the handlers. @@ -689,10 +689,10 @@ export const middlewareSecurity = ( +export const middlewareSecurityVoid = ( self: Security, f: ( - credentials: ApiSecurity.ApiSecurity.Type + credentials: HttpApiSecurity.HttpApiSecurity.Type ) => Effect.Effect ): SecurityMiddleware => middleware((httpApp) => @@ -722,18 +722,18 @@ const requestPayload = ( : Effect.succeed(urlParams) const handlerToRoute = ( - endpoint: ApiEndpoint.ApiEndpoint.Any, - handler: ApiEndpoint.ApiEndpoint.Handler, + endpoint: HttpApiEndpoint.HttpApiEndpoint.Any, + handler: HttpApiEndpoint.HttpApiEndpoint.Handler, isFullResponse: boolean ): HttpRouter.Route => { const decodePath = Option.map(endpoint.pathSchema, Schema.decodeUnknown) const isMultipart = endpoint.payloadSchema.pipe( - Option.map((schema) => ApiSchema.getMultipart(schema.ast)), + Option.map((schema) => HttpApiSchema.getMultipart(schema.ast)), Option.getOrElse(() => false) ) const decodePayload = Option.map(endpoint.payloadSchema, Schema.decodeUnknown) - const encodeSuccess = Option.map(ApiEndpoint.schemaSuccess(endpoint), Schema.encodeUnknown) - const successStatus = ApiSchema.getStatusSuccess(endpoint.successSchema) + const encodeSuccess = Option.map(HttpApiEndpoint.schemaSuccess(endpoint), Schema.encodeUnknown) + const successStatus = HttpApiSchema.getStatusSuccess(endpoint.successSchema) return HttpRouter.makeRoute( endpoint.method, endpoint.path, @@ -743,14 +743,14 @@ const handlerToRoute = ( const routeContext = Context.unsafeGet(context, HttpRouter.RouteContext) const urlParams = Context.unsafeGet(context, HttpServerRequest.ParsedSearchParams) return (decodePath._tag === "Some" - ? Effect.catchAll(decodePath.value(routeContext.params), ApiDecodeError.refailParseError) + ? Effect.catchAll(decodePath.value(routeContext.params), HttpApiDecodeError.refailParseError) : Effect.succeed(routeContext.params)).pipe( Effect.bindTo("pathParams"), decodePayload._tag === "Some" ? Effect.bind("payload", (_) => requestPayload(request, urlParams, isMultipart).pipe( Effect.orDie, - Effect.flatMap((raw) => Effect.catchAll(decodePayload.value(raw), ApiDecodeError.refailParseError)) + Effect.flatMap((raw) => Effect.catchAll(decodePayload.value(raw), HttpApiDecodeError.refailParseError)) )) : identity, Effect.flatMap((input) => { @@ -775,10 +775,13 @@ const handlerToRoute = ( ) } -const astCache = globalValue("@effect/platform/ApiBuilder", () => new WeakMap()) +const astCache = globalValue( + "@effect/platform/HttpApiBuilder/astCache", + () => new WeakMap() +) const makeErrorSchema = ( - api: Api.Api, any, any> + api: HttpApi.HttpApi, any, any> ): Schema.Schema => { const schemas = new Set() function processSchema(schema: Schema.Schema.Any): void { @@ -808,7 +811,7 @@ const makeErrorSchema = ( processSchema(group.errorSchema) } return Schema.Union(...[...schemas].map((schema) => { - const status = ApiSchema.getStatusError(schema) + const status = HttpApiSchema.getStatusError(schema) const encoded = AST.encodedAST(schema.ast) const isEmpty = encoded._tag === "VoidKeyword" return Schema.transformOrFail(Schema.Any, schema, { diff --git a/packages/platform/src/ApiClient.ts b/packages/platform/src/HttpApiClient.ts similarity index 85% rename from packages/platform/src/ApiClient.ts rename to packages/platform/src/HttpApiClient.ts index 62caf6f8d2..2df911e3b3 100644 --- a/packages/platform/src/ApiClient.ts +++ b/packages/platform/src/HttpApiClient.ts @@ -8,10 +8,10 @@ import { identity } from "effect/Function" import * as Option from "effect/Option" import type { Simplify } from "effect/Types" import { unify } from "effect/Unify" -import * as Api from "./Api.js" -import type { ApiEndpoint } from "./ApiEndpoint.js" -import type { ApiGroup } from "./ApiGroup.js" -import * as ApiSchema from "./ApiSchema.js" +import * as HttpApi from "./HttpApi.js" +import type { HttpApiEndpoint } from "./HttpApiEndpoint.js" +import type { HttpApiGroup } from "./HttpApiGroup.js" +import * as HttpApiSchema from "./HttpApiSchema.js" import * as HttpClient from "./HttpClient.js" import * as HttpClientError from "./HttpClientError.js" import * as HttpClientRequest from "./HttpClientRequest.js" @@ -22,11 +22,12 @@ import * as HttpMethod from "./HttpMethod.js" * @since 1.0.0 * @category models */ -export type Client = [A] extends [Api.Api] ? { - readonly [GroupName in _Groups["name"]]: [ApiGroup.WithName<_Groups, GroupName>] extends - [ApiGroup] ? { - readonly [Name in _Endpoints["name"]]: [ApiEndpoint.WithName<_Endpoints, Name>] extends [ - ApiEndpoint< +export type Client = [A] extends + [HttpApi.HttpApi] ? { + readonly [GroupName in _Groups["name"]]: [HttpApiGroup.WithName<_Groups, GroupName>] extends + [HttpApiGroup] ? { + readonly [Name in _Endpoints["name"]]: [HttpApiEndpoint.WithName<_Endpoints, Name>] extends [ + HttpApiEndpoint< Name, infer _Method, infer _Path, @@ -36,7 +37,7 @@ export type Client = [A] extends [Api.Api ] ? ( - request: Simplify> + request: Simplify> ) => Effect.Effect< _Success, _Error | _GroupError | _ApiError | HttpClientError.HttpClientError @@ -51,13 +52,13 @@ export type Client = [A] extends [Api.Api( +export const make = ( api: A, options?: { readonly transformClient?: ((client: HttpClient.HttpClient.Default) => HttpClient.HttpClient.Default) | undefined readonly baseUrl?: string | undefined } -): Effect.Effect>, never, Api.Api.Context | HttpClient.HttpClient.Default> => +): Effect.Effect>, never, HttpApi.HttpApi.Context | HttpClient.HttpClient.Default> => Effect.gen(function*() { const context = yield* Effect.context() const httpClient = (yield* HttpClient.HttpClient).pipe( @@ -65,7 +66,7 @@ export const make = ( options?.transformClient === undefined ? identity : options.transformClient ) const client: Record> = {} - Api.reflect(api as any, { + HttpApi.reflect(api as any, { onGroup({ group }) { client[group.name] = {} }, @@ -124,7 +125,7 @@ export const make = ( ) } const isMultipart = endpoint.payloadSchema.pipe( - Option.map((schema) => ApiSchema.getMultipart(schema.ast)), + Option.map((schema) => HttpApiSchema.getMultipart(schema.ast)), Option.getOrElse(() => false) ) const encodePayload = endpoint.payloadSchema.pipe( diff --git a/packages/platform/src/ApiEndpoint.ts b/packages/platform/src/HttpApiEndpoint.ts similarity index 70% rename from packages/platform/src/ApiEndpoint.ts rename to packages/platform/src/HttpApiEndpoint.ts index 0e05d638e2..0fe3cbcfc6 100644 --- a/packages/platform/src/ApiEndpoint.ts +++ b/packages/platform/src/HttpApiEndpoint.ts @@ -11,7 +11,7 @@ import { type Pipeable, pipeArguments } from "effect/Pipeable" import * as Predicate from "effect/Predicate" import type { Redacted } from "effect/Redacted" import type * as Types from "effect/Types" -import * as ApiSchema from "./ApiSchema.js" +import * as HttpApiSchema from "./HttpApiSchema.js" import type { HttpMethod } from "./HttpMethod.js" import * as HttpRouter from "./HttpRouter.js" import type { HttpServerResponse } from "./HttpServerResponse.js" @@ -20,7 +20,7 @@ import type { HttpServerResponse } from "./HttpServerResponse.js" * @since 1.0.0 * @category type ids */ -export const TypeId: unique symbol = Symbol.for("@effect/platform/ApiEndpoint") +export const TypeId: unique symbol = Symbol.for("@effect/platform/HttpApiEndpoint") /** * @since 1.0.0 @@ -32,7 +32,7 @@ export type TypeId = typeof TypeId * @since 1.0.0 * @category guards */ -export const isApiEndpoint = (u: unknown): u is ApiEndpoint => Predicate.hasProperty(u, TypeId) +export const isHttpApiEndpoint = (u: unknown): u is HttpApiEndpoint => Predicate.hasProperty(u, TypeId) /** * Represents an API endpoint. An API endpoint is mapped to a single route on @@ -41,7 +41,7 @@ export const isApiEndpoint = (u: unknown): u is ApiEndpoint => Pr * @since 1.0.0 * @category models */ -export interface ApiEndpoint< +export interface HttpApiEndpoint< out Name extends string, out Method extends HttpMethod, in out Path = never, @@ -65,7 +65,7 @@ export interface ApiEndpoint< * @since 1.0.0 * @category models */ -export declare namespace ApiEndpoint { +export declare namespace HttpApiEndpoint { /** * @since 1.0.0 * @category models @@ -103,7 +103,7 @@ export declare namespace ApiEndpoint { * @category models */ export type Success = Endpoint extends - ApiEndpoint ? + HttpApiEndpoint ? _Success : never @@ -112,7 +112,7 @@ export declare namespace ApiEndpoint { * @category models */ export type Error = Endpoint extends - ApiEndpoint ? + HttpApiEndpoint ? _Error : never @@ -121,7 +121,8 @@ export declare namespace ApiEndpoint { * @category models */ export type PathParsed = Endpoint extends - ApiEndpoint ? _Path + HttpApiEndpoint ? + _Path : never /** @@ -129,7 +130,7 @@ export declare namespace ApiEndpoint { * @category models */ export type Payload = Endpoint extends - ApiEndpoint ? + HttpApiEndpoint ? _Payload : never @@ -148,7 +149,7 @@ export declare namespace ApiEndpoint { export type ClientRequest = ( & ([Path] extends [void] ? {} : { readonly path: Path }) & ([Payload] extends [never] ? {} - : [Payload] extends [Brand] ? { readonly payload: FormData } + : [Payload] extends [Brand] ? { readonly payload: FormData } : { readonly payload: Payload }) ) extends infer Req ? keyof Req extends never ? void : Req : void @@ -157,7 +158,8 @@ export declare namespace ApiEndpoint { * @category models */ export type Context = Endpoint extends - ApiEndpoint ? _R + HttpApiEndpoint ? + _R : never /** @@ -295,7 +297,7 @@ const makeProto = < readonly successSchema: Schema.Schema readonly errorSchema: Schema.Schema readonly annotations: Context.Context -}): ApiEndpoint => Object.assign(Object.create(Proto), options) +}): HttpApiEndpoint => Object.assign(Object.create(Proto), options) /** * @since 1.0.0 @@ -305,14 +307,14 @@ export const make = (method: Method) => ( name: Name, path: HttpRouter.PathInput -): ApiEndpoint => +): HttpApiEndpoint => makeProto({ name, path, method, pathSchema: Option.none(), payloadSchema: Option.none(), - successSchema: ApiSchema.NoContent as any, + successSchema: HttpApiSchema.NoContent as any, errorSchema: Schema.Never as any, annotations: Context.empty() }) @@ -324,7 +326,7 @@ export const make = (method: Method) => export const get: ( name: Name, path: HttpRouter.PathInput -) => ApiEndpoint = make("GET") +) => HttpApiEndpoint = make("GET") /** * @since 1.0.0 @@ -333,7 +335,7 @@ export const get: ( export const post: ( name: Name, path: HttpRouter.PathInput -) => ApiEndpoint = make("POST") +) => HttpApiEndpoint = make("POST") /** * @since 1.0.0 @@ -342,7 +344,7 @@ export const post: ( export const put: ( name: Name, path: HttpRouter.PathInput -) => ApiEndpoint = make("PUT") +) => HttpApiEndpoint = make("PUT") /** * @since 1.0.0 @@ -351,7 +353,7 @@ export const put: ( export const patch: ( name: Name, path: HttpRouter.PathInput -) => ApiEndpoint = make("PATCH") +) => HttpApiEndpoint = make("PATCH") /** * @since 1.0.0 @@ -360,7 +362,7 @@ export const patch: ( export const del: ( name: Name, path: HttpRouter.PathInput -) => ApiEndpoint = make("DELETE") +) => HttpApiEndpoint = make("DELETE") /** * Set the schema for the success response of the endpoint. The status code @@ -384,8 +386,8 @@ export const setSuccess: { _E, _R >( - self: ApiEndpoint - ) => ApiEndpoint, _E, _R | Schema.Schema.Context> + self: HttpApiEndpoint + ) => HttpApiEndpoint, _E, _R | Schema.Schema.Context> < Name extends string, Method extends HttpMethod, @@ -396,14 +398,14 @@ export const setSuccess: { _R, S extends Schema.Schema.Any >( - self: ApiEndpoint, + self: HttpApiEndpoint, schema: S, annotations?: { readonly status?: number | undefined } - ): ApiEndpoint, _E, _R | Schema.Schema.Context> + ): HttpApiEndpoint, _E, _R | Schema.Schema.Context> } = dual( - (args) => isApiEndpoint(args[0]), + (args) => isHttpApiEndpoint(args[0]), < Name extends string, Method extends HttpMethod, @@ -414,16 +416,16 @@ export const setSuccess: { _R, S extends Schema.Schema.Any >( - self: ApiEndpoint, + self: HttpApiEndpoint, schema: S, annotations?: { readonly status?: number | undefined } - ): ApiEndpoint, _E, _R | Schema.Schema.Context> => + ): HttpApiEndpoint, _E, _R | Schema.Schema.Context> => makeProto({ ...self as any, - successSchema: schema.annotations(ApiSchema.annotations({ - status: annotations?.status ?? ApiSchema.getStatusSuccess(schema) + successSchema: schema.annotations(HttpApiSchema.annotations({ + status: annotations?.status ?? HttpApiSchema.getStatusSuccess(schema) })) }) ) @@ -450,8 +452,8 @@ export const addError: { _E, _R >( - self: ApiEndpoint - ) => ApiEndpoint, _R | Schema.Schema.Context> + self: HttpApiEndpoint + ) => HttpApiEndpoint, _R | Schema.Schema.Context> < Name extends string, Method extends HttpMethod, @@ -462,14 +464,14 @@ export const addError: { _R, E extends Schema.Schema.All >( - self: ApiEndpoint, + self: HttpApiEndpoint, schema: E, annotations?: { readonly status?: number | undefined } - ): ApiEndpoint, _R | Schema.Schema.Context> + ): HttpApiEndpoint, _R | Schema.Schema.Context> } = dual( - (args) => isApiEndpoint(args[0]), + (args) => isHttpApiEndpoint(args[0]), < Name extends string, Method extends HttpMethod, @@ -480,19 +482,19 @@ export const addError: { _R, E extends Schema.Schema.All >( - self: ApiEndpoint, + self: HttpApiEndpoint, schema: E, annotations?: { readonly status?: number | undefined } - ): ApiEndpoint, _R | Schema.Schema.Context> => + ): HttpApiEndpoint, _R | Schema.Schema.Context> => makeProto({ ...self as any, - errorSchema: ApiSchema.UnionUnify( + errorSchema: HttpApiSchema.UnionUnify( self.errorSchema, schema.pipe( - Schema.annotations(ApiSchema.annotations({ - status: annotations?.status ?? ApiSchema.getStatusError(schema) + Schema.annotations(HttpApiSchema.annotations({ + status: annotations?.status ?? HttpApiSchema.getStatusError(schema) })) ) ) @@ -507,14 +509,14 @@ export const addError: { * parameters. * * You can set a multipart schema to handle file uploads by using the - * `ApiSchema.Multipart` combinator. + * `HttpApiSchema.Multipart` combinator. * * @since 1.0.0 * @category request */ export const setPayload: { ( - schema: P & ApiEndpoint.ValidatePayload + schema: P & HttpApiEndpoint.ValidatePayload ): < Name extends string, _Path, @@ -523,8 +525,8 @@ export const setPayload: { _E, _R >( - self: ApiEndpoint - ) => ApiEndpoint, _S, _E, _R | Schema.Schema.Context

    > + self: HttpApiEndpoint + ) => HttpApiEndpoint, _S, _E, _R | Schema.Schema.Context

    > < Name extends string, Method extends HttpMethod, @@ -535,9 +537,9 @@ export const setPayload: { _R, P extends Schema.Schema.All >( - self: ApiEndpoint, - schema: P & ApiEndpoint.ValidatePayload - ): ApiEndpoint, _S, _E, _R | Schema.Schema.Context

    > + self: HttpApiEndpoint, + schema: P & HttpApiEndpoint.ValidatePayload + ): HttpApiEndpoint, _S, _E, _R | Schema.Schema.Context

    > } = dual( 2, < @@ -550,9 +552,9 @@ export const setPayload: { _R, P extends Schema.Schema.All >( - self: ApiEndpoint, - schema: P & ApiEndpoint.ValidatePayload - ): ApiEndpoint, _S, _E, _R | Schema.Schema.Context

    > => + self: HttpApiEndpoint, + schema: P & HttpApiEndpoint.ValidatePayload + ): HttpApiEndpoint, _S, _E, _R | Schema.Schema.Context

    > + self: HttpApiEndpoint + ) => HttpApiEndpoint, _H, _S, _E, _R | Schema.Schema.Context

    > < Name extends string, Method extends HttpMethod, _Path, _P, + _H, _S, _E, _R, P extends Schema.Schema.All >( - self: HttpApiEndpoint, + self: HttpApiEndpoint, schema: P & HttpApiEndpoint.ValidatePayload - ): HttpApiEndpoint, _S, _E, _R | Schema.Schema.Context

    > + ): HttpApiEndpoint, _H, _S, _E, _R | Schema.Schema.Context

    > } = dual( 2, < @@ -547,14 +627,15 @@ export const setPayload: { Method extends HttpMethod, _Path, _P, + _H, _S, _E, _R, P extends Schema.Schema.All >( - self: HttpApiEndpoint, + self: HttpApiEndpoint, schema: P & HttpApiEndpoint.ValidatePayload - ): HttpApiEndpoint, _S, _E, _R | Schema.Schema.Context

    > => + ): HttpApiEndpoint, _H, _S, _E, _R | Schema.Schema.Context

    > => makeProto({ ...self as any, payloadSchema: Option.some(schema) @@ -576,25 +657,27 @@ export const setPath: { Method extends HttpMethod, _Path, _P, + _H, _S, _E, _R >( - self: HttpApiEndpoint - ) => HttpApiEndpoint, _P, _S, _E, _R | Schema.Schema.Context> + self: HttpApiEndpoint + ) => HttpApiEndpoint, _P, _H, _S, _E, _R | Schema.Schema.Context> < Name extends string, Method extends HttpMethod, _Path, _P, + _H, _S, _E, _R, Path extends Schema.Schema.Any >( - self: HttpApiEndpoint, + self: HttpApiEndpoint, schema: Path & HttpApiEndpoint.ValidatePath - ): HttpApiEndpoint, _P, _S, _E, _R | Schema.Schema.Context> + ): HttpApiEndpoint, _P, _H, _S, _E, _R | Schema.Schema.Context> } = dual( 2, < @@ -602,20 +685,78 @@ export const setPath: { Method extends HttpMethod, _Path, _P, + _H, _S, _E, _R, Path extends Schema.Schema.Any >( - self: HttpApiEndpoint, + self: HttpApiEndpoint, schema: Path & HttpApiEndpoint.ValidatePath - ): HttpApiEndpoint, _P, _S, _E, _R | Schema.Schema.Context> => + ): HttpApiEndpoint, _P, _H, _S, _E, _R | Schema.Schema.Context> => makeProto({ ...self as any, pathSchema: Option.some(schema) }) ) +/** + * Set the schema for the headers of the endpoint. The schema will be + * used to validate the headers before the handler is called. + * + * @since 1.0.0 + * @category request + */ +export const setHeaders: { + ( + schema: H & HttpApiEndpoint.ValidateHeaders + ): < + Name extends string, + _Path, + _P, + _H, + _S, + _E, + _R + >( + self: HttpApiEndpoint + ) => HttpApiEndpoint, _S, _E, _R | Schema.Schema.Context> + < + Name extends string, + Method extends HttpMethod, + _Path, + _P, + _H, + _S, + _E, + _R, + H extends Schema.Schema.Any + >( + self: HttpApiEndpoint, + schema: H & HttpApiEndpoint.ValidateHeaders + ): HttpApiEndpoint, _S, _E, _R | Schema.Schema.Context> +} = dual( + 2, + < + Name extends string, + Method extends HttpMethod, + _Path, + _P, + _H, + _S, + _E, + _R, + H extends Schema.Schema.Any + >( + self: HttpApiEndpoint, + schema: H & HttpApiEndpoint.ValidateHeaders + ): HttpApiEndpoint, _S, _E, _R | Schema.Schema.Context> => + makeProto({ + ...self as any, + headersSchema: Option.some(schema) + }) +) + /** * Add a prefix to the path of the endpoint. * diff --git a/packages/platform/src/OpenApi.ts b/packages/platform/src/OpenApi.ts index 162218bb5d..4196eb32a9 100644 --- a/packages/platform/src/OpenApi.ts +++ b/packages/platform/src/OpenApi.ts @@ -251,14 +251,43 @@ export const fromApi = (api: A): OpenAPISpec => { }) ) if (Option.isSome(endpoint.pathSchema)) { - getPropertySignatures(endpoint.pathSchema.value.ast).forEach((ps) => { - op.parameters!.push(makeProperty(ps, "path")) - }) + const schema = makeJsonSchema(endpoint.pathSchema.value) as JSONSchema.JsonSchema7Object + if ("properties" in schema) { + Object.entries(schema.properties).forEach(([name, jsonSchema]) => { + op.parameters!.push({ + name, + in: "path", + schema: jsonSchema, + required: schema.required.includes(name) + }) + }) + } } if (!HttpMethod.hasBody(endpoint.method) && Option.isSome(endpoint.payloadSchema)) { - getPropertySignatures(endpoint.payloadSchema.value.ast).forEach((ps) => { - op.parameters!.push(makeProperty(ps, "query")) - }) + const schema = makeJsonSchema(endpoint.payloadSchema.value) as JSONSchema.JsonSchema7Object + if ("properties" in schema) { + Object.entries(schema.properties).forEach(([name, jsonSchema]) => { + op.parameters!.push({ + name, + in: "query", + schema: jsonSchema, + required: schema.required.includes(name) + }) + }) + } + } + if (Option.isSome(endpoint.headersSchema)) { + const schema = makeJsonSchema(endpoint.headersSchema.value) as JSONSchema.JsonSchema7Object + if ("properties" in schema) { + Object.entries(schema.properties).forEach(([name, jsonSchema]) => { + op.parameters!.push({ + name, + in: "header", + schema: jsonSchema, + required: schema.required.includes(name) + }) + }) + } } for (const [status, ast] of errors) { if (op.responses![status]) continue @@ -286,17 +315,6 @@ export const fromApi = (api: A): OpenAPISpec => { return spec } -const getPropertySignatures = (ast: AST.AST): ReadonlyArray => { - switch (ast._tag) { - case "Transformation": { - return getPropertySignatures(ast.from) - } - default: { - return AST.getPropertySignatures(ast) - } - } -} - const makeSecurityScheme = (security: HttpApiSecurity): OpenAPISecurityScheme => { const meta: Mutable> = {} Option.map(Context.getOption(security.annotations, Description), (description) => { @@ -328,22 +346,6 @@ const makeSecurityScheme = (security: HttpApiSecurity): OpenAPISecurityScheme => } } -const makeProperty = (ps: AST.PropertySignature, type: OpenAPISpecParameter["in"]): OpenAPISpecParameter => { - const spec: Mutable = { - in: type, - name: ps.name as string, - schema: makeJsonSchema(Schema.make(ps.type)), - required: !ps.isOptional - } - getDescriptionOrIdentifier(Option.some(ps)).pipe( - Option.orElse(() => getDescriptionOrIdentifier(Option.some(ps.type))), - Option.map((description) => { - spec.description = description - }) - ) - return spec -} - const getDescriptionOrIdentifier = (ast: Option.Option): Option.Option => ast.pipe( Option.map((ast) => From dde225968570b836080605859c1e352631bdd635 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 29 Aug 2024 11:54:53 +1200 Subject: [PATCH 53/59] docs & tests --- .prettierrc.json | 4 + packages/platform-node/test/HttpApi.test.ts | 379 ++++++ .../platform-node/test/fixtures/openapi.json | 810 ++++++++++++ packages/platform/README.md | 1140 ++++++++++++----- packages/platform/src/HttpApi.ts | 12 +- packages/platform/src/HttpApiBuilder.ts | 1 + packages/platform/src/HttpApiError.ts | 31 +- packages/platform/src/HttpApiGroup.ts | 24 +- packages/platform/src/OpenApi.ts | 2 +- 9 files changed, 2085 insertions(+), 318 deletions(-) create mode 100644 .prettierrc.json create mode 100644 packages/platform-node/test/HttpApi.test.ts create mode 100644 packages/platform-node/test/fixtures/openapi.json diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000000..27b720e322 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,4 @@ +{ + "semi": false, + "trailingComma": "none" +} diff --git a/packages/platform-node/test/HttpApi.test.ts b/packages/platform-node/test/HttpApi.test.ts new file mode 100644 index 0000000000..4455195759 --- /dev/null +++ b/packages/platform-node/test/HttpApi.test.ts @@ -0,0 +1,379 @@ +import { + Cookies, + FileSystem, + HttpApi, + HttpApiBuilder, + HttpApiClient, + HttpApiEndpoint, + HttpApiGroup, + HttpApiSchema, + HttpApiSecurity, + HttpClient, + HttpClientRequest, + HttpServerRequest, + Multipart, + OpenApi +} from "@effect/platform" +import { NodeHttpServer } from "@effect/platform-node" +import { Schema } from "@effect/schema" +import { assert, describe, it } from "@effect/vitest" +import { Context, DateTime, Effect, Layer, Redacted, Ref, Struct } from "effect" +import OpenApiFixture from "./fixtures/openapi.json" + +describe("HttpApi", () => { + describe("payload", () => { + it.effect("is decoded / encoded", () => + Effect.gen(function*() { + const client = yield* HttpApiClient.make(Api) + const user = yield* client.users.create({ + payload: { name: "Joe" } + }) + assert.deepStrictEqual( + user, + new User({ + id: 1, + name: "Joe", + createdAt: DateTime.unsafeMake(0) + }) + ) + }).pipe(Effect.provide(HttpLive))) + + it.live("multipart", () => + Effect.gen(function*() { + const client = yield* HttpApiClient.make(Api) + const data = new FormData() + data.append("file", new Blob(["hello"], { type: "text/plain" }), "hello.txt") + const result = yield* client.users.upload({ payload: data }) + assert.deepStrictEqual(result, { + contentType: "text/plain", + length: 5 + }) + }).pipe(Effect.provide(HttpLive))) + }) + + describe("headers", () => { + it.effect("is decoded / encoded", () => + Effect.gen(function*() { + const client = yield* HttpApiClient.make(Api) + const users = yield* client.users.list({ + headers: { page: 1 } + }) + const user = users[0] + assert.deepStrictEqual( + user, + new User({ + id: 1, + name: "page 1", + createdAt: DateTime.unsafeMake(0) + }) + ) + }).pipe(Effect.provide(HttpLive))) + }) + + describe("errors", () => { + it.scoped("empty errors have no body", () => + Effect.gen(function*() { + const response = yield* HttpClientRequest.get("/groups/0") + assert.strictEqual(response.status, 418) + const text = yield* response.text + assert.strictEqual(text, "") + }).pipe(Effect.provide(HttpLive))) + + it.effect("empty errors decode", () => + Effect.gen(function*() { + const client = yield* HttpApiClient.make(Api) + const error = yield* client.groups.findById({ path: { id: 0 } }).pipe( + Effect.flip + ) + assert.deepStrictEqual(error, new GroupError()) + }).pipe(Effect.provide(HttpLive))) + + it.scoped("default to 500 status code", () => + Effect.gen(function*() { + const response = yield* HttpClientRequest.get("/users").pipe( + HttpClientRequest.setHeaders({ page: "0" }) + ) + assert.strictEqual(response.status, 500) + const body = yield* response.json + assert.deepStrictEqual(body, { + _tag: "NoStatusError" + }) + }).pipe(Effect.provide(HttpLive))) + + it.scoped("class level annotations", () => + Effect.gen(function*() { + const response = yield* HttpClientRequest.post("/users").pipe( + HttpClientRequest.unsafeJsonBody({ name: "boom" }) + ) + assert.strictEqual(response.status, 400) + }).pipe(Effect.provide(HttpLive))) + + it.effect("HttpApiDecodeError", () => + Effect.gen(function*() { + const client = yield* HttpApiClient.make(Api) + const error = yield* client.users.upload({ payload: new FormData() }).pipe( + Effect.flip + ) + assert(error._tag === "HttpApiDecodeError") + assert.deepStrictEqual(error.issues[0].path, ["file"]) + }).pipe(Effect.provide(HttpLive))) + }) + + it.effect("handler level context", () => + Effect.gen(function*() { + const client = yield* HttpApiClient.make(Api) + const users = yield* client.users.list({ headers: { page: 1 } }) + const user = users[0] + assert.strictEqual(user.name, "page 1") + assert.deepStrictEqual(user.createdAt, DateTime.unsafeMake(0)) + }).pipe(Effect.provide(HttpLive))) + + describe("security", () => { + it.effect("security middleware sets current user", () => + Effect.gen(function*() { + const ref = yield* Ref.make(Cookies.empty.pipe( + Cookies.unsafeSet("token", "foo") + )) + const client = yield* HttpApiClient.make(Api, { + transformClient: HttpClient.withCookiesRef(ref) + }) + const user = yield* client.users.findById({ path: { id: -1 } }) + assert.strictEqual(user.name, "foo") + }).pipe(Effect.provide(HttpLive))) + + it.effect("apiKey header security", () => + Effect.gen(function*() { + const decode = HttpApiBuilder.securityDecode(securityHeader).pipe( + Effect.provideService( + HttpServerRequest.HttpServerRequest, + HttpServerRequest.fromWeb( + new Request("http://localhost:3000/", { + headers: { + "x-api-key": "foo" + } + }) + ) + ), + Effect.provideService(HttpServerRequest.ParsedSearchParams, {}) + ) + const redacted = yield* decode + assert.strictEqual(Redacted.value(redacted), "foo") + }).pipe(Effect.provide(HttpLive))) + + it.effect("apiKey query security", () => + Effect.gen(function*() { + const decode = HttpApiBuilder.securityDecode(securityQuery).pipe( + Effect.provideService( + HttpServerRequest.HttpServerRequest, + HttpServerRequest.fromWeb(new Request("http://localhost:3000/")) + ), + Effect.provideService(HttpServerRequest.ParsedSearchParams, { + api_key: "foo" + }) + ) + const redacted = yield* decode + assert.strictEqual(Redacted.value(redacted), "foo") + }).pipe(Effect.provide(HttpLive))) + }) + + it("OpenAPI spec", () => { + const spec = OpenApi.fromApi(Api) + assert.deepStrictEqual(spec, OpenApiFixture as any) + }) +}) + +class GlobalError extends Schema.TaggedClass()("GlobalError", {}) {} +class GroupError extends Schema.TaggedClass()("GroupError", {}) {} +class UserError extends Schema.TaggedClass()("UserError", {}, HttpApiSchema.annotations({ status: 400 })) {} +class NoStatusError extends Schema.TaggedClass()("NoStatusError", {}) {} + +class User extends Schema.Class("User")({ + id: Schema.Int, + name: Schema.String, + createdAt: Schema.DateTimeUtc +}) {} + +class Group extends Schema.Class("Group")({ + id: Schema.Int, + name: Schema.String +}) {} + +const securityCookie = HttpApiSecurity.apiKey({ + in: "cookie", + key: "token" +}) + +const securityHeader = HttpApiSecurity.apiKey({ + in: "header", + key: "x-api-key" +}) + +const securityQuery = HttpApiSecurity.apiKey({ + in: "query", + key: "api_key" +}) + +class GroupsApi extends HttpApiGroup.make("groups").pipe( + HttpApiGroup.add( + HttpApiEndpoint.get("findById", "/:id").pipe( + HttpApiEndpoint.setPath(Schema.Struct({ + id: Schema.NumberFromString + })), + HttpApiEndpoint.setSuccess(Group) + ) + ), + HttpApiGroup.add( + HttpApiEndpoint.post("create", "/").pipe( + HttpApiEndpoint.setPayload(Schema.Struct(Struct.pick(Group.fields, "name"))), + HttpApiEndpoint.setSuccess(Group) + ) + ), + HttpApiGroup.addError(GroupError.pipe( + HttpApiSchema.asEmpty({ status: 418, decode: () => new GroupError() }) + )), + HttpApiGroup.prefix("/groups"), + OpenApi.annotate({ security: securityCookie }) +) {} + +class UsersApi extends HttpApiGroup.make("users").pipe( + HttpApiGroup.add( + HttpApiEndpoint.get("findById", "/:id").pipe( + HttpApiEndpoint.setPath(Schema.Struct({ + id: Schema.NumberFromString + })), + HttpApiEndpoint.setSuccess(User) + ) + ), + HttpApiGroup.add( + HttpApiEndpoint.post("create", "/").pipe( + HttpApiEndpoint.setPayload(Schema.Struct(Struct.omit( + User.fields, + "id", + "createdAt" + ))), + HttpApiEndpoint.setSuccess(User), + HttpApiEndpoint.addError(UserError) + ) + ), + HttpApiGroup.add( + HttpApiEndpoint.get("list", "/").pipe( + HttpApiEndpoint.setHeaders(Schema.Struct({ + page: Schema.NumberFromString.pipe( + Schema.optionalWith({ default: () => 1 }) + ) + })), + HttpApiEndpoint.setSuccess(Schema.Array(User)), + HttpApiEndpoint.addError(NoStatusError), + OpenApi.annotate({ identifier: "listUsers" }) + ) + ), + HttpApiGroup.add( + HttpApiEndpoint.post("upload", "/upload").pipe( + HttpApiEndpoint.setPayload(HttpApiSchema.Multipart(Schema.Struct({ + file: Multipart.SingleFileSchema + }))), + HttpApiEndpoint.setSuccess(Schema.Struct({ + contentType: Schema.String, + length: Schema.Int + })) + ) + ), + OpenApi.annotate({ title: "Users API" }) +) {} + +class Api extends HttpApi.empty.pipe( + HttpApi.addGroup(GroupsApi), + HttpApi.addGroup("/users", UsersApi), + HttpApi.addError(GlobalError, { status: 413 }), + OpenApi.annotate({ title: "API" }) +) {} + +// impl + +class UserRepo extends Context.Tag("UserRepo") Effect.Effect +}>() { + static Live = Layer.succeed(this, { + findById: (id) => Effect.map(DateTime.now, (now) => ({ id, name: "foo", createdAt: now })) + }) +} + +class CurrentUser extends Context.Tag("CurrentUser")() {} + +const securityMiddleware = HttpApiBuilder.middlewareSecurity( + securityCookie, + CurrentUser, + (token) => + Effect.succeed( + new User({ + id: 1, + name: Redacted.value(token), + createdAt: DateTime.unsafeNow() + }) + ) +) + +const HttpUsersLive = HttpApiBuilder.group(Api, "users", (handlers) => + Effect.gen(function*() { + const fs = yield* FileSystem.FileSystem + const repo = yield* UserRepo + return handlers.pipe( + HttpApiBuilder.handle("findById", (_) => + _.path.id === -1 + ? CurrentUser : + repo.findById(_.path.id)), + HttpApiBuilder.handle("create", (_) => + _.payload.name === "boom" + ? Effect.fail(new UserError()) + : Effect.map(DateTime.now, (now) => + new User({ + id: 1, + name: _.payload.name, + createdAt: now + }))), + HttpApiBuilder.handle("list", (_) => + _.headers.page === 0 + ? Effect.fail(new NoStatusError()) + // test handler level context + : Effect.map(DateTime.nowInCurrentZone, (now) => [ + new User({ + id: 1, + name: `page ${_.headers.page}`, + createdAt: DateTime.unsafeMake(now.epochMillis) + }) + ])), + HttpApiBuilder.handle("upload", (_) => + Effect.gen(function*() { + const stat = yield* fs.stat(_.payload.file.path).pipe(Effect.orDie) + return { + contentType: _.payload.file.contentType, + length: Number(stat.size) + } + })), + securityMiddleware + ) + })).pipe( + Layer.provide(DateTime.layerCurrentZoneOffset(0)), + Layer.provide(UserRepo.Live) + ) + +const HttpGroupsLive = HttpApiBuilder.group(Api, "groups", (handlers) => + handlers.pipe( + HttpApiBuilder.handle("findById", (_) => + _.path.id === 0 + ? Effect.fail(new GroupError()) + : Effect.succeed(new Group({ id: 1, name: "foo" }))), + HttpApiBuilder.handle("create", (_) => Effect.succeed(new Group({ id: 1, name: _.payload.name }))), + securityMiddleware + )) + +const HttpApiLive = HttpApiBuilder.api(Api).pipe( + Layer.provide(HttpUsersLive), + Layer.provide(HttpGroupsLive) +) + +const HttpLive = HttpApiBuilder.serve().pipe( + Layer.provide(HttpApiBuilder.middlewareCors()), + Layer.provide(HttpApiLive), + Layer.provideMerge(NodeHttpServer.layerTest) +) diff --git a/packages/platform-node/test/fixtures/openapi.json b/packages/platform-node/test/fixtures/openapi.json new file mode 100644 index 0000000000..e7eff096d1 --- /dev/null +++ b/packages/platform-node/test/fixtures/openapi.json @@ -0,0 +1,810 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "API", + "version": "0.0.1" + }, + "paths": { + "/groups/{id}": { + "get": { + "tags": ["groups"], + "operationId": "groups.findById", + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "security": [ + { + "ApiKey": [] + } + ], + "responses": { + "200": { + "description": "an instance of Group", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["name", "id"], + "properties": { + "name": { + "type": "string" + }, + "id": { + "type": "integer", + "description": "an integer", + "title": "Int" + } + }, + "additionalProperties": false + } + } + } + }, + "400": { + "description": "HttpApiDecodeError: The request did not match the expected schema", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["_tag", "message", "issues"], + "properties": { + "_tag": { + "enum": ["HttpApiDecodeError"] + }, + "message": { + "type": "string" + }, + "issues": { + "type": "array", + "items": { + "type": "object", + "required": ["message", "_tag", "path"], + "properties": { + "message": { + "type": "string" + }, + "_tag": { + "enum": [ + "Pointer", + "Unexpected", + "Missing", + "Composite", + "Refinement", + "Transformation", + "Type", + "Forbidden" + ] + }, + "path": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + } + } + }, + "additionalProperties": false + } + } + }, + "additionalProperties": false + } + } + } + }, + "413": { + "description": "an instance of GlobalError", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["_tag"], + "properties": { + "_tag": { + "enum": ["GlobalError"] + } + }, + "additionalProperties": false + } + } + } + }, + "418": { + "description": "an instance of GroupError" + } + } + } + }, + "/groups": { + "post": { + "tags": ["groups"], + "operationId": "groups.create", + "parameters": [], + "security": [ + { + "ApiKey": [] + } + ], + "responses": { + "200": { + "description": "an instance of Group", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["name", "id"], + "properties": { + "name": { + "type": "string" + }, + "id": { + "type": "integer", + "description": "an integer", + "title": "Int" + } + }, + "additionalProperties": false + } + } + } + }, + "400": { + "description": "HttpApiDecodeError: The request did not match the expected schema", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["_tag", "message", "issues"], + "properties": { + "_tag": { + "enum": ["HttpApiDecodeError"] + }, + "message": { + "type": "string" + }, + "issues": { + "type": "array", + "items": { + "type": "object", + "required": ["message", "_tag", "path"], + "properties": { + "message": { + "type": "string" + }, + "_tag": { + "enum": [ + "Pointer", + "Unexpected", + "Missing", + "Composite", + "Refinement", + "Transformation", + "Type", + "Forbidden" + ] + }, + "path": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + } + } + }, + "additionalProperties": false + } + } + }, + "additionalProperties": false + } + } + } + }, + "413": { + "description": "an instance of GlobalError", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["_tag"], + "properties": { + "_tag": { + "enum": ["GlobalError"] + } + }, + "additionalProperties": false + } + } + } + }, + "418": { + "description": "an instance of GroupError" + } + }, + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["name"], + "properties": { + "name": { + "type": "string" + } + }, + "additionalProperties": false + } + } + }, + "required": true + } + } + }, + "/users/{id}": { + "get": { + "tags": ["Users API"], + "operationId": "users.findById", + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "security": [], + "responses": { + "200": { + "description": "an instance of User", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["name", "id", "createdAt"], + "properties": { + "name": { + "type": "string" + }, + "id": { + "type": "integer", + "description": "an integer", + "title": "Int" + }, + "createdAt": { + "type": "string" + } + }, + "additionalProperties": false + } + } + } + }, + "400": { + "description": "HttpApiDecodeError: The request did not match the expected schema", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["_tag", "message", "issues"], + "properties": { + "_tag": { + "enum": ["HttpApiDecodeError"] + }, + "message": { + "type": "string" + }, + "issues": { + "type": "array", + "items": { + "type": "object", + "required": ["message", "_tag", "path"], + "properties": { + "message": { + "type": "string" + }, + "_tag": { + "enum": [ + "Pointer", + "Unexpected", + "Missing", + "Composite", + "Refinement", + "Transformation", + "Type", + "Forbidden" + ] + }, + "path": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + } + } + }, + "additionalProperties": false + } + } + }, + "additionalProperties": false + } + } + } + }, + "413": { + "description": "an instance of GlobalError", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["_tag"], + "properties": { + "_tag": { + "enum": ["GlobalError"] + } + }, + "additionalProperties": false + } + } + } + } + } + } + }, + "/users": { + "post": { + "tags": ["Users API"], + "operationId": "users.create", + "parameters": [], + "security": [], + "responses": { + "200": { + "description": "an instance of User", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["name", "id", "createdAt"], + "properties": { + "name": { + "type": "string" + }, + "id": { + "type": "integer", + "description": "an integer", + "title": "Int" + }, + "createdAt": { + "type": "string" + } + }, + "additionalProperties": false + } + } + } + }, + "400": { + "description": "Error", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "type": "object", + "required": ["_tag", "message", "issues"], + "properties": { + "_tag": { + "enum": ["HttpApiDecodeError"] + }, + "message": { + "type": "string" + }, + "issues": { + "type": "array", + "items": { + "type": "object", + "required": ["message", "_tag", "path"], + "properties": { + "message": { + "type": "string" + }, + "_tag": { + "enum": [ + "Pointer", + "Unexpected", + "Missing", + "Composite", + "Refinement", + "Transformation", + "Type", + "Forbidden" + ] + }, + "path": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + } + } + }, + "additionalProperties": false + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": ["_tag"], + "properties": { + "_tag": { + "enum": ["UserError"] + } + }, + "additionalProperties": false + } + ] + } + } + } + }, + "413": { + "description": "an instance of GlobalError", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["_tag"], + "properties": { + "_tag": { + "enum": ["GlobalError"] + } + }, + "additionalProperties": false + } + } + } + } + }, + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["name"], + "properties": { + "name": { + "type": "string" + } + }, + "additionalProperties": false + } + } + }, + "required": true + } + }, + "get": { + "tags": ["Users API"], + "operationId": "listUsers", + "parameters": [ + { + "name": "page", + "in": "header", + "schema": { + "type": "string" + }, + "required": false + } + ], + "security": [], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "object", + "required": ["name", "id", "createdAt"], + "properties": { + "name": { + "type": "string" + }, + "id": { + "type": "integer", + "description": "an integer", + "title": "Int" + }, + "createdAt": { + "type": "string" + } + }, + "additionalProperties": false + } + } + } + } + }, + "400": { + "description": "HttpApiDecodeError: The request did not match the expected schema", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["_tag", "message", "issues"], + "properties": { + "_tag": { + "enum": ["HttpApiDecodeError"] + }, + "message": { + "type": "string" + }, + "issues": { + "type": "array", + "items": { + "type": "object", + "required": ["message", "_tag", "path"], + "properties": { + "message": { + "type": "string" + }, + "_tag": { + "enum": [ + "Pointer", + "Unexpected", + "Missing", + "Composite", + "Refinement", + "Transformation", + "Type", + "Forbidden" + ] + }, + "path": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + } + } + }, + "additionalProperties": false + } + } + }, + "additionalProperties": false + } + } + } + }, + "413": { + "description": "an instance of GlobalError", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["_tag"], + "properties": { + "_tag": { + "enum": ["GlobalError"] + } + }, + "additionalProperties": false + } + } + } + }, + "500": { + "description": "an instance of NoStatusError", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["_tag"], + "properties": { + "_tag": { + "enum": ["NoStatusError"] + } + }, + "additionalProperties": false + } + } + } + } + } + } + }, + "/users/upload": { + "post": { + "tags": ["Users API"], + "operationId": "users.upload", + "parameters": [], + "security": [], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["contentType", "length"], + "properties": { + "contentType": { + "type": "string" + }, + "length": { + "type": "integer", + "description": "an integer", + "title": "Int" + } + }, + "additionalProperties": false + } + } + } + }, + "400": { + "description": "HttpApiDecodeError: The request did not match the expected schema", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["_tag", "message", "issues"], + "properties": { + "_tag": { + "enum": ["HttpApiDecodeError"] + }, + "message": { + "type": "string" + }, + "issues": { + "type": "array", + "items": { + "type": "object", + "required": ["message", "_tag", "path"], + "properties": { + "message": { + "type": "string" + }, + "_tag": { + "enum": [ + "Pointer", + "Unexpected", + "Missing", + "Composite", + "Refinement", + "Transformation", + "Type", + "Forbidden" + ] + }, + "path": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + } + } + }, + "additionalProperties": false + } + } + }, + "additionalProperties": false + } + } + } + }, + "413": { + "description": "an instance of GlobalError", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["_tag"], + "properties": { + "_tag": { + "enum": ["GlobalError"] + } + }, + "additionalProperties": false + } + } + } + } + }, + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "required": ["file"], + "properties": { + "file": { + "description": "an array of exactly 1 item(s)", + "items": { + "format": "binary", + "type": "string" + }, + "maxItems": 1, + "minItems": 1, + "type": "array" + } + }, + "additionalProperties": false + } + } + }, + "required": true + } + } + } + }, + "tags": [ + { + "name": "groups" + }, + { + "name": "Users API" + } + ], + "components": { + "schemas": {}, + "securitySchemes": { + "ApiKey": { + "type": "apiKey", + "name": "token", + "in": "cookie" + } + } + }, + "security": [] +} diff --git a/packages/platform/README.md b/packages/platform/README.md index 8bb1668fe2..cbf2df92a4 100644 --- a/packages/platform/README.md +++ b/packages/platform/README.md @@ -8,415 +8,543 @@ This package empowers you to perform various operations, such as: | **Operation** | **Description** | | -------------- | ------------------------------------------------------------------------------------------------ | -| Terminal | Reading and writing from/to standard input/output | -| Command | Creating and running a command with the specified process name and an optional list of arguments | -| FileSystem | Reading and writing from/to the file system | +| HTTP API | Declarative HTTP API servers & clients | | HTTP Client | Sending HTTP requests and receiving responses | | HTTP Server | Creating HTTP servers to handle incoming requests | | HTTP Router | Routing HTTP requests to specific handlers | +| Terminal | Reading and writing from/to standard input/output | +| Command | Creating and running a command with the specified process name and an optional list of arguments | +| FileSystem | Reading and writing from/to the file system | | KeyValueStore | Storing and retrieving key-value pairs | | PlatformLogger | Creating a logger that writes to a specified file from another string logger | By utilizing `@effect/platform`, you can write code that remains platform-agnostic, ensuring compatibility across different environments. -# Terminal +# HTTP API -The `@effect/platform/Terminal` module exports a single `Terminal` tag, which serves as the entry point to reading from and writing to standard input and standard output. +## Overview -## Writing to standard output +The `HttpApi` family of modules provide a declarative way to define HTTP APIs. +You can create an API by combining multiple endpoints, each with its own set of +schemas that define the request and response types. -```ts -import { Terminal } from "@effect/platform" -import { NodeRuntime, NodeTerminal } from "@effect/platform-node" -import { Effect } from "effect" +After you have defined your API, you can use it to implement a server or derive +a client that can interact with the server. -// const displayMessage: Effect.Effect -const displayMessage = Effect.gen(function* (_) { - const terminal = yield* _(Terminal.Terminal) - yield* _(terminal.display("a message\n")) -}) +## Defining an API -NodeRuntime.runMain(displayMessage.pipe(Effect.provide(NodeTerminal.layer))) -// Output: "a message" +To define an API, you need to create a set of endpoints. Each endpoint is +defined by a path, a method, and a set of schemas that define the request and +response types. + +Each set of endpoints is added to an `HttpApiGroup`, which can be combined with +other groups to create a complete API. + +### Your first `HttpApiGroup` + +Let's define a simple CRUD API for managing users. First, we need to make an +`HttpApiGroup` that contains our endpoints. + +```ts +import { HttpApiEndpoint, HttpApiGroup } from "@effect/platform" +import { Schema } from "@effect/schema" + +// Our domain "User" Schema +class User extends Schema.Class("User")({ + id: Schema.Number, + name: Schema.String, + createdAt: Schema.DateTimeUtc +}) {} + +const usersApi = HttpApiGroup.make("users").pipe( + HttpApiGroup.add( + // each endpoint has a name and a path + HttpApiEndpoint.get("findById", "/users/:id").pipe( + // the endpoint can have a Schema for a successful response + HttpApiEndpoint.setSuccess(User), + // and here is a Schema for the path parameters + HttpApiEndpoint.setPath( + Schema.Struct({ + id: Schema.NumberFromString + }) + ) + ) + ), + HttpApiGroup.add( + HttpApiEndpoint.post("create", "/users").pipe( + HttpApiEndpoint.setSuccess(User), + // and here is a Schema for the request payload / body + // + // this is a POST request, so the payload is in the body + // but for a GET request, the payload would be in the URL search params + HttpApiEndpoint.setPayload( + Schema.Struct({ + name: Schema.String + }) + ) + ) + ), + // by default, the endpoint will respond with a 204 No Content + HttpApiGroup.add(HttpApiEndpoint.del("delete", "/users/:id")), + HttpApiGroup.add( + HttpApiEndpoint.patch("update", "/users/:id").pipe( + HttpApiEndpoint.setSuccess(User), + HttpApiEndpoint.setPayload( + Schema.Struct({ + name: Schema.String + }) + ) + ) + ) +) ``` -## Reading from standard input +You can also extend the `HttpApiGroup` with a class to gain an opaque type. +We will use this API style in the following examples: ```ts -import { Terminal } from "@effect/platform" -import { NodeRuntime, NodeTerminal } from "@effect/platform-node" -import { Console, Effect } from "effect" +class UsersApi extends HttpApiGroup.make("users").pipe( + HttpApiGroup.add( + HttpApiEndpoint.get("findById", "/users/:id") + // ... same as above + ) +) {} +``` -// const readLine: Effect.Effect -const readLine = Effect.gen(function* (_) { - const terminal = yield* _(Terminal.Terminal) - const input = yield* _(terminal.readLine) - yield* _(Console.log(`input: ${input}`)) -}) +### Creating the top level `HttpApi` -NodeRuntime.runMain(readLine.pipe(Effect.provide(NodeTerminal.layer))) -// Input: "hello" -// Output: "input: hello" +Once you have defined your groups, you can combine them into a single `HttpApi`. + +```ts +import { HttpApi } from "@effect/platform" + +class MyApi extends HttpApi.empty.pipe(HttpApi.addGroup(UsersApi)) {} ``` -These simple examples illustrate how to utilize the `Terminal` module for handling standard input and output in your programs. Let's use this knowledge to build a number guessing game: +Or with the non-opaque style: ```ts -import { Terminal } from "@effect/platform" -import type { PlatformError } from "@effect/platform/Error" -import { Effect, Option, Random } from "effect" +const api = HttpApi.empty.pipe(HttpApi.addGroup(usersApi)) +``` -export const secret = Random.nextIntBetween(1, 100) +### Adding OpenApi annotations -const parseGuess = (input: string) => { - const n = parseInt(input, 10) - return isNaN(n) || n < 1 || n > 100 ? Option.none() : Option.some(n) -} +You can add OpenApi annotations to your API by using the `OpenApi` module. -const display = (message: string) => - Effect.gen(function* (_) { - const terminal = yield* _(Terminal.Terminal) - yield* _(terminal.display(`${message}\n`)) +Let's add a title to our `UsersApi` group: + +```ts +import { OpenApi } from "@effect/platform" + +class UsersApi extends HttpApiGroup.make("users").pipe( + HttpApiGroup.add( + HttpApiEndpoint.get("findById", "/users/:id") + // ... same as above + ), + // add an OpenApi title & description + OpenApi.annotate({ + title: "Users API", + description: "API for managing users" }) +) {} +``` -const prompt = Effect.gen(function* (_) { - const terminal = yield* _(Terminal.Terminal) - yield* _(terminal.display("Enter a guess: ")) - return yield* _(terminal.readLine) -}) +Now when you generate OpenApi documentation, the title and description will be +included. -const answer: Effect.Effect< - number, - Terminal.QuitException | PlatformError, - Terminal.Terminal -> = Effect.gen(function* (_) { - const input = yield* _(prompt) - const guess = parseGuess(input) - if (Option.isNone(guess)) { - yield* _(display("You must enter an integer from 1 to 100")) - return yield* _(answer) - } - return guess.value -}) +You can also add OpenApi annotations to the top-level `HttpApi`: -const check = ( - secret: number, - guess: number, - ok: Effect.Effect, - ko: Effect.Effect -): Effect.Effect => - Effect.gen(function* (_) { - if (guess > secret) { - yield* _(display("Too high")) - return yield* _(ko) - } else if (guess < secret) { - yield* _(display("Too low")) - return yield* _(ko) - } else { - return yield* _(ok) - } +```ts +class MyApi extends HttpApi.empty.pipe( + HttpApi.addGroup(UsersApi), + OpenApi.annotate({ + title: "My API", + description: "My awesome API" }) +) {} +``` -const end = display("You guessed it!") +### Adding errors -const loop = ( - secret: number -): Effect.Effect< - void, - Terminal.QuitException | PlatformError, - Terminal.Terminal -> => - Effect.gen(function* (_) { - const guess = yield* _(answer) - return yield* _( - check( - secret, - guess, - end, - Effect.suspend(() => loop(secret)) - ) - ) - }) +You can add error responses to your endpoints using the following apis: -export const game = Effect.gen(function* (_) { - yield* _( - display( - "We have selected a random number between 1 and 100. See if you can guess it in 10 turns or fewer. We'll tell you if your guess was too high or too low." - ) - ) - yield* _(loop(yield* _(secret))) -}) -``` +- `HttpApiEndpoint.addError` - add an error response for a single endpoint +- `HttpApiGroup.addError` - add an error response for all endpoints in a group +- `HttpApi.addError` - add an error response for all endpoints in the api -Let's run the game in Node.js: +The group & api level errors are useful for adding common error responses that +can be used in middleware. + +Here is an example of adding a 404 error to the `UsersApi` group: ```ts -import { NodeRuntime, NodeTerminal } from "@effect/platform-node" -import * as Effect from "effect/Effect" -import { game } from "./game.js" +// define the error schemas +class UserNotFound extends Schema.TaggedError()( + "UserNotFound", + {} +) {} -NodeRuntime.runMain(game.pipe(Effect.provide(NodeTerminal.layer))) +class Unauthorized extends Schema.TaggedError()( + "Unauthorized", + {} +) {} + +class UsersApi extends HttpApiGroup.make("users").pipe( + HttpApiGroup.add( + HttpApiEndpoint.get("findById", "/users/:id").pipe( + // here we are adding our error response + HttpApiEndpoint.addError(UserNotFound, { status: 404 }), + HttpApiEndpoint.setSuccess(User), + HttpApiEndpoint.setPath(Schema.Struct({ id: Schema.NumberFromString })) + ) + ), + // or we could add an error to the group + HttpApiGroup.addError(Unauthorized, { status: 401 }) +) {} ``` -Let's run the game in Bun: +It is worth noting that you can add multiple error responses to an endpoint, +just by calling `HttpApiEndpoint.addError` multiple times. + +### Multipart requests + +If you need to handle file uploads, you can use the `HttpApiSchema.Multipart` +api to flag a `HttpApiSchema` payload schema as a multipart request. + +You can then use the schemas from the `Multipart` module to define the expected +shape of the multipart request. ```ts -import { BunRuntime, BunTerminal } from "@effect/platform-bun" -import * as Effect from "effect/Effect" -import { game } from "./game.js" +import { HttpApiSchema, Multipart } from "@effect/platform" -BunRuntime.runMain(game.pipe(Effect.provide(BunTerminal.layer))) +class UsersApi extends HttpApiGroup.make("users").pipe( + HttpApiGroup.add( + HttpApiEndpoint.post("upload", "/users/upload").pipe( + HttpApiEndpoint.setPayload( + HttpApiSchema.Multipart( + Schema.Struct({ + // add a "files" field to the schema + files: Multipart.FilesSchema + }) + ) + ) + ) + ) +) {} ``` -# Command +### Adding security annotations -As an example of using the `@effect/platform/Command` module, let's see how to run the TypeScript compiler `tsc`: +The `HttpApiSecurity` module provides a way to add security annotations to your +API. -```ts -import { Command, CommandExecutor } from "@effect/platform" -import { - NodeCommandExecutor, - NodeFileSystem, - NodeRuntime -} from "@effect/platform-node" -import { Effect } from "effect" +The `HttpApiSecurity` offers the following authorization types: -// const program: Effect.Effect -const program = Effect.gen(function* (_) { - const executor = yield* _(CommandExecutor.CommandExecutor) +- `HttpApiSecurity.apiKey` - API key authorization through headers, query + parameters, or cookies. +- `HttpApiSecurity.basicAuth` - HTTP Basic authentication. +- `HttpApiSecurity.bearerAuth` - Bearer token authentication. - // Creating a command to run the TypeScript compiler - const command = Command.make("tsc", "--noEmit") - console.log("Running tsc...") +You can annotate your API with these security types using the +`OpenApi.annotate` api as before. - // Executing the command and capturing the output - const output = yield* _(executor.string(command)) - console.log(output) - return output +```ts +import { HttpApiSecurity } from "@effect/platform" + +const security = HttpApiSecurity.apiKey({ + in: "cookie", + key: "token" }) -// Running the program with the necessary runtime and executor layers -NodeRuntime.runMain( - program.pipe( - Effect.provide(NodeCommandExecutor.layer), - Effect.provide(NodeFileSystem.layer) - ) -) +class UsersApi extends HttpApiGroup.make("users").pipe( + HttpApiGroup.add( + HttpApiEndpoint.get("findById", "/users/:id").pipe( + // add the security annotation to the endpoint + OpenApi.annotate({ security }) + ) + ), + // or at the group level + OpenApi.annotate({ security }), + + // or just for the endpoints above this line + HttpApiGroup.annotateEndpoints(OpenApi.Security, security), + // this endpoint will not have the security annotation + HttpApiGroup.add(HttpApiEndpoint.get("list", "/users")) +) {} ``` -## Obtaining Information About the Running Process +## Implementing a server -Here, we'll explore how to retrieve information about a running process. +Now that you have defined your API, you can implement a server that serves the +endpoints. -```ts -import { Command, CommandExecutor } from "@effect/platform" -import { - NodeCommandExecutor, - NodeFileSystem, - NodeRuntime -} from "@effect/platform-node" -import { Effect, Stream, String } from "effect" +The `HttpApiBuilder` module provides all the apis you need to implement your +server. -const runString = ( - stream: Stream.Stream -): Effect.Effect => - stream.pipe(Stream.decodeText(), Stream.runFold(String.empty, String.concat)) +### Implementing a `HttpApiGroup` -const program = Effect.gen(function* (_) { - const executor = yield* _(CommandExecutor.CommandExecutor) +First up, let's implement an `UsersApi` group with a single `findById` endpoint: - const command = Command.make("ls") +```ts +import { + HttpApi, + HttpApiBuilder, + HttpApiEndpoint, + HttpApiGroup +} from "@effect/platform" +import { Schema } from "@effect/schema" +import { DateTime, Effect } from "effect" - const [exitCode, stdout, stderr] = yield* _( - // Start running the command and return a handle to the running process. - executor.start(command), - Effect.flatMap((process) => - Effect.all( - [ - // Waits for the process to exit and returns the ExitCode of the command that was run. - process.exitCode, - // The standard output stream of the process. - runString(process.stdout), - // The standard error stream of the process. - runString(process.stderr) - ], - { concurrency: 3 } +// here is our api definition +class User extends Schema.Class("User")({ + id: Schema.Number, + name: Schema.String, + createdAt: Schema.DateTimeUtc +}) {} + +class UsersApi extends HttpApiGroup.make("users").pipe( + HttpApiGroup.add( + HttpApiEndpoint.get("findById", "/users/:id").pipe( + HttpApiEndpoint.setSuccess(User), + HttpApiEndpoint.setPath( + Schema.Struct({ + id: Schema.NumberFromString + }) ) ) ) - console.log({ exitCode, stdout, stderr }) -}) - -NodeRuntime.runMain( - Effect.scoped(program).pipe( - Effect.provide(NodeCommandExecutor.layer), - Effect.provide(NodeFileSystem.layer) +) {} + +class MyApi extends HttpApi.empty.pipe(HttpApi.addGroup(UsersApi)) {} + +// -------------------------------------------- +// Implementation +// -------------------------------------------- + +// the `HttpApiBuilder.group` api return a `Layer` +const UsersApiLive: Layer.Layer> = + HttpApiBuilder.group(MyApi, "users", (handlers) => + handlers.pipe( + // the parameters & payload are passed to the handler function. + HttpApiBuilder.handle("findById", ({ path: { id } }) => + Effect.succeed( + new User({ + id, + name: "John Doe", + createdAt: DateTime.unsafeNow() + }) + ) + ) + ) ) -) ``` -## Running a Platform Command with stdout Streamed to process.stdout +### Using services inside a `HttpApiGroup` -To run a command (for example `cat`) and stream its `stdout` to `process.stdout` follow these steps: +If you need to use services inside your handlers, you can return an +`Effect` from the `HttpApiBuilder.group` api. ```ts -import { Command } from "@effect/platform" -import { NodeContext, NodeRuntime } from "@effect/platform-node" -import { Effect } from "effect" - -// Create a command to run `cat` on a file and inherit stdout -const program = Command.make("cat", "./some-file.txt").pipe( - Command.stdout("inherit"), - Command.exitCode +class UsersRepository extends Context.Tag("UsersRepository")< + UsersRepository, + { + readonly findById: (id: number) => Effect.Effect + } +>() {} + +// the dependencies will show up in the resulting `Layer` +const UsersApiLive: Layer.Layer< + HttpApiGroup.HttpApiGroup.Service<"users">, + never, + UsersRepository +> = HttpApiBuilder.group(MyApi, "users", (handlers) => + // we can return an Effect that creates our handlers + Effect.gen(function* () { + const repository = yield* UsersRepository + return handlers.pipe( + HttpApiBuilder.handle("findById", ({ path: { id } }) => + repository.findById(id) + ) + ) + }) ) +``` -// Run the command using NodeRuntime with the NodeContext layer -NodeRuntime.runMain(program.pipe(Effect.provide(NodeContext.layer))) -``` - -# FileSystem - -The `@effect/platform/FileSystem` module provides a single `FileSystem` tag, which acts as the gateway for interacting with the filesystem. - -Here's a list of operations that can be performed using the `FileSystem` tag: +### Implementing a `HttpApi` -| **Name** | **Arguments** | **Return** | **Description** | -| --------------------------- | ---------------------------------------------------------------- | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **access** | `path: string`, `options?: AccessFileOptions` | `Effect` | Check if a file can be accessed. You can optionally specify the level of access to check for. | -| **copy** | `fromPath: string`, `toPath: string`, `options?: CopyOptions` | `Effect` | Copy a file or directory from `fromPath` to `toPath`. Equivalent to `cp -r`. | -| **copyFile** | `fromPath: string`, `toPath: string` | `Effect` | Copy a file from `fromPath` to `toPath`. | -| **chmod** | `path: string`, `mode: number` | `Effect` | Change the permissions of a file. | -| **chown** | `path: string`, `uid: number`, `gid: number` | `Effect` | Change the owner and group of a file. | -| **exists** | `path: string` | `Effect` | Check if a path exists. | -| **link** | `fromPath: string`, `toPath: string` | `Effect` | Create a hard link from `fromPath` to `toPath`. | -| **makeDirectory** | `path: string`, `options?: MakeDirectoryOptions` | `Effect` | Create a directory at `path`. You can optionally specify the mode and whether to recursively create nested directories. | -| **makeTempDirectory** | `options?: MakeTempDirectoryOptions` | `Effect` | Create a temporary directory. By default, the directory will be created inside the system's default temporary directory. | -| **makeTempDirectoryScoped** | `options?: MakeTempDirectoryOptions` | `Effect` | Create a temporary directory inside a scope. Functionally equivalent to `makeTempDirectory`, but the directory will be automatically deleted when the scope is closed. | -| **makeTempFile** | `options?: MakeTempFileOptions` | `Effect` | Create a temporary file. The directory creation is functionally equivalent to `makeTempDirectory`. The file name will be a randomly generated string. | -| **makeTempFileScoped** | `options?: MakeTempFileOptions` | `Effect` | Create a temporary file inside a scope. Functionally equivalent to `makeTempFile`, but the file will be automatically deleted when the scope is closed. | -| **open** | `path: string`, `options?: OpenFileOptions` | `Effect` | Open a file at `path` with the specified `options`. The file handle will be automatically closed when the scope is closed. | -| **readDirectory** | `path: string`, `options?: ReadDirectoryOptions` | `Effect, PlatformError>` | List the contents of a directory. You can recursively list the contents of nested directories by setting the `recursive` option. | -| **readFile** | `path: string` | `Effect` | Read the contents of a file. | -| **readFileString** | `path: string`, `encoding?: string` | `Effect` | Read the contents of a file as a string. | -| **readLink** | `path: string` | `Effect` | Read the destination of a symbolic link. | -| **realPath** | `path: string` | `Effect` | Resolve a path to its canonicalized absolute pathname. | -| **remove** | `path: string`, `options?: RemoveOptions` | `Effect` | Remove a file or directory. By setting the `recursive` option to `true`, you can recursively remove nested directories. | -| **rename** | `oldPath: string`, `newPath: string` | `Effect` | Rename a file or directory. | -| **sink** | `path: string`, `options?: SinkOptions` | `Sink` | Create a writable `Sink` for the specified `path`. | -| **stat** | `path: string` | `Effect` | Get information about a file at `path`. | -| **stream** | `path: string`, `options?: StreamOptions` | `Stream` | Create a readable `Stream` for the specified `path`. | -| **symlink** | `fromPath: string`, `toPath: string` | `Effect` | Create a symbolic link from `fromPath` to `toPath`. | -| **truncate** | `path: string`, `length?: SizeInput` | `Effect` | Truncate a file to a specified length. If the `length` is not specified, the file will be truncated to length `0`. | -| **utimes** | `path: string`, `atime: Date \| number`, `mtime: Date \| number` | `Effect` | Change the file system timestamps of the file at `path`. | -| **watch** | `path: string` | `Stream` | Watch a directory or file for changes. | +Once all your groups are implemented, you can implement the top-level `HttpApi`. -Let's explore a simple example using `readFileString`: +This is done using the `HttpApiBuilder.api` api, and then using `Layer.provide` +to add all the group implementations. ```ts -import { FileSystem } from "@effect/platform" -import { NodeFileSystem, NodeRuntime } from "@effect/platform-node" -import { Effect } from "effect" - -// const readFileString: Effect.Effect -const readFileString = Effect.gen(function* (_) { - const fs = yield* _(FileSystem.FileSystem) - - // Reading the content of the same file where this code is written - const content = yield* _(fs.readFileString("./index.ts", "utf8")) - console.log(content) -}) - -NodeRuntime.runMain(readFileString.pipe(Effect.provide(NodeFileSystem.layer))) +const MyApiLive: Layer.Layer = HttpApiBuilder.api( + MyApi +).pipe(Layer.provide(UsersApiLive)) ``` -# KeyValueStore +### Serving the API -## Overview +Finally, you can serve the API using the `HttpApiBuilder.serve` api. -The `KeyValueStore` module provides a robust and effectful interface for managing key-value pairs. It supports asynchronous operations, ensuring data integrity and consistency, and includes built-in implementations for in-memory, file system-based, and schema-validated stores. +You can also add middleware to the server using the `HttpMiddleware` module, or +use some of the middleware Layer's from the `HttpApiBuilder` module. -## Basic Usage +```ts +import { HttpMiddleware, HttpServer } from "@effect/platform" +import { NodeHttpServer, NodeRuntime } from "@effect/platform-node" +import { createServer } from "node:http" -The `KeyValueStore` interface includes the following operations: +// use the `HttpApiBuilder.serve` function to register our API with the HTTP +// server +const HttpLive = HttpApiBuilder.serve(HttpMiddleware.logger).pipe( + // Add CORS middleware + Layer.provide(HttpApiBuilder.middlewareCors()), + // Provide the API implementation + Layer.provide(MyApiLive), + // Log the address the server is listening on + HttpServer.withLogAddress, + // Provide the HTTP server implementation + Layer.provide(NodeHttpServer.layer(createServer, { port: 3000 })) +) -- **get**: Retrieve a value by key. -- **set**: Store a key-value pair. -- **remove**: Delete a key-value pair. -- **clear**: Remove all key-value pairs. -- **size**: Get the number of stored pairs. -- **modify**: Atomically modify a value. -- **has**: Check if a key exists. -- **isEmpty**: Check if the store is empty. +// run the server +Layer.launch(HttpLive).pipe(NodeRuntime.runMain) +``` -**Example** +## Implementing `HttpApiSecurity` -```ts -import { KeyValueStore, layerMemory } from "@effect/platform/KeyValueStore" -import { Effect } from "effect" +If you are using `HttpApiSecurity` in your API, you can use the security +definition to implement a middleware that will protect your endpoints. -const program = Effect.gen(function* () { - const store = yield* KeyValueStore - console.log(yield* store.size) // Outputs: 0 +The `HttpApiBuilder.middlewareSecurity` api will assist you in creating this +middleware. - yield* store.set("key", "value") - console.log(yield* store.size) // Outputs: 1 +Here is an example: - const value = yield* store.get("key") - console.log(value) // Outputs: { _id: 'Option', _tag: 'Some', value: 'value' } +```ts +// our cookie security definition +const security = HttpApiSecurity.apiKey({ + in: "cookie", + key: "token" +}) - yield* store.remove("key") - console.log(yield* store.size) // Outputs: 0 +// the user repository service +class UsersRepository extends Context.Tag("UsersRepository")< + UsersRepository, + { + readonly findByToken: (token: Redacted.Redacted) => Effect.Effect + } +>() {} + +// the security middleware will supply the current user to the handlers +class CurrentUser extends Context.Tag("CurrentUser")() {} + +// implement the middleware +const makeSecurityMiddleware: Effect.Effect< + HttpApiBuilder.SecurityMiddleware, + never, + UsersRepository +> = Effect.gen(function* () { + const repository = yield* UsersRepository + return HttpApiBuilder.middlewareSecurity( + // the security definition + security, + // the Context.Tag this middleware will provide + CurrentUser, + // the function to get the user from the token + (token) => repository.findByToken(token) + ) }) -Effect.runPromise(program.pipe(Effect.provide(layerMemory))) +// use the middleware +const UsersApiLive = HttpApiBuilder.group(MyApi, "users", (handlers) => + Effect.gen(function* () { + // construct the security middleware + const securityMiddleware = yield* makeSecurityMiddleware + + return handlers.pipe( + HttpApiBuilder.handle("findById", ({ path: { id } }) => + Effect.succeed( + new User({ id, name: "John Doe", createdAt: DateTime.unsafeNow() }) + ) + ), + // apply the middleware to the findById endpoint + securityMiddleware + // any endpoint after this will not be protected + ) + }) +) ``` -## Built-in Implementations +If you need to set the security cookie from within a handler, you can use the +`HttpApiBuilder.securitySetCookie` api. -The module provides several built-in implementations to suit different needs: +By default, the cookie will be set with the `HttpOnly` and `Secure` flags. -- **In-Memory Store**: `layerMemory` provides a simple, in-memory key-value store, ideal for lightweight or testing scenarios. -- **File System Store**: `layerFileSystem` offers a file-based store for persistent storage needs. -- **Schema Store**: `layerSchema` enables schema-based validation for stored values, ensuring data integrity and type safety. +```ts +const security = HttpApiSecurity.apiKey({ + in: "cookie", + key: "token" +}) -## Schema Store +const UsersApiLive = HttpApiBuilder.group(MyApi, "users", (handlers) => + handlers.pipe( + HttpApiBuilder.handle("login", () => + // set the security cookie + HttpApiBuilder.securitySetCookie( + security, + Redacted.make("keep me secret") + ) + ) + ) +) +``` -The `SchemaStore` implementation allows you to validate and parse values according to a defined schema. This ensures that all data stored in the key-value store adheres to the specified structure, enhancing data integrity and type safety. +## Deriving a client -**Example** +Once you have defined your API, you can derive a client that can interact with +the server. + +The `HttpApiClient` module provides all the apis you need to derive a client. ```ts -import { KeyValueStore, layerMemory } from "@effect/platform/KeyValueStore" -import { Schema } from "@effect/schema" -import { Effect } from "effect" +import { HttpApiClient } from "@effect/platform" -// Define a schema for the values -const Person = Schema.Struct({ - name: Schema.String, - age: Schema.Number +Effect.gen(function* () { + const client = yield* HttpApiClient.make(MyApi, { + baseUrl: "http://localhost:3000" + // You can tranform the HttpClient to add things like authentication + // transformClient: .... + }) + const user = yield* client.users.findById({ path: { id: 1 } }) + yield* Effect.log(user) }) +``` -const program = Effect.gen(function* () { - const store = (yield* KeyValueStore).forSchema(Person) - - // Create a value that adheres to the schema - const value = { name: "Alice", age: 30 } - yield* store.set("user1", value) - console.log(yield* store.size) // Outputs: 1 +## Swagger documentation - // Retrieve and validate the value - const retrievedValue = yield* store.get("user1") - console.log(retrievedValue) // Outputs: { _id: 'Option', _tag: 'Some', value: { name: 'Alice', age: 30 } } -}) +You can add Swagger documentation to your API using the `HttpApiSwagger` module. -Effect.runPromise(program.pipe(Effect.provide(layerMemory))) -``` +You just need to provide the `HttpApiSwagger.layer` to your server +implementation: -In this example: +```ts +import { HttpApiSwagger } from "@effect/platform" -- **Person**: Defines the structure for the values stored in the key-value store. -- **store.set**: Stores a value adhering to `Person`. -- **store.get**: Retrieves and validates the stored value against `Person`. +const HttpLive = HttpApiBuilder.serve(HttpMiddleware.logger).pipe( + // add the swagger documentation layer + Layer.provide( + HttpApiSwagger.layer({ + // "/docs" is the default path for the swagger documentation + path: "/docs" + }) + ), + Layer.provide(HttpApiBuilder.middlewareCors()), + Layer.provide(MyApiLive), + Layer.provide(NodeHttpServer.layer(createServer, { port: 3000 })) +) +``` # HTTP Client @@ -500,7 +628,12 @@ const myClient = HttpClient.makeDefault((req) => req, // Simulate a response from a server new Response( - JSON.stringify({ userId: 1, id: 1, title: "title...", body: "body..." }) + JSON.stringify({ + userId: 1, + id: 1, + title: "title...", + body: "body..." + }) ) ) ) @@ -2183,3 +2316,402 @@ const handler = HttpApp.toWebHandler(router) const response = await handler(new Request("http://localhost:3000/foo")) console.log(await response.text()) // Output: content 2 ``` + +# Terminal + +The `@effect/platform/Terminal` module exports a single `Terminal` tag, which serves as the entry point to reading from and writing to standard input and standard output. + +## Writing to standard output + +```ts +import { Terminal } from "@effect/platform" +import { NodeRuntime, NodeTerminal } from "@effect/platform-node" +import { Effect } from "effect" + +// const displayMessage: Effect.Effect +const displayMessage = Effect.gen(function* (_) { + const terminal = yield* _(Terminal.Terminal) + yield* _(terminal.display("a message\n")) +}) + +NodeRuntime.runMain(displayMessage.pipe(Effect.provide(NodeTerminal.layer))) +// Output: "a message" +``` + +## Reading from standard input + +```ts +import { Terminal } from "@effect/platform" +import { NodeRuntime, NodeTerminal } from "@effect/platform-node" +import { Console, Effect } from "effect" + +// const readLine: Effect.Effect +const readLine = Effect.gen(function* (_) { + const terminal = yield* _(Terminal.Terminal) + const input = yield* _(terminal.readLine) + yield* _(Console.log(`input: ${input}`)) +}) + +NodeRuntime.runMain(readLine.pipe(Effect.provide(NodeTerminal.layer))) +// Input: "hello" +// Output: "input: hello" +``` + +These simple examples illustrate how to utilize the `Terminal` module for handling standard input and output in your programs. Let's use this knowledge to build a number guessing game: + +```ts +import { Terminal } from "@effect/platform" +import type { PlatformError } from "@effect/platform/Error" +import { Effect, Option, Random } from "effect" + +export const secret = Random.nextIntBetween(1, 100) + +const parseGuess = (input: string) => { + const n = parseInt(input, 10) + return isNaN(n) || n < 1 || n > 100 ? Option.none() : Option.some(n) +} + +const display = (message: string) => + Effect.gen(function* (_) { + const terminal = yield* _(Terminal.Terminal) + yield* _(terminal.display(`${message}\n`)) + }) + +const prompt = Effect.gen(function* (_) { + const terminal = yield* _(Terminal.Terminal) + yield* _(terminal.display("Enter a guess: ")) + return yield* _(terminal.readLine) +}) + +const answer: Effect.Effect< + number, + Terminal.QuitException | PlatformError, + Terminal.Terminal +> = Effect.gen(function* (_) { + const input = yield* _(prompt) + const guess = parseGuess(input) + if (Option.isNone(guess)) { + yield* _(display("You must enter an integer from 1 to 100")) + return yield* _(answer) + } + return guess.value +}) + +const check = ( + secret: number, + guess: number, + ok: Effect.Effect, + ko: Effect.Effect +): Effect.Effect => + Effect.gen(function* (_) { + if (guess > secret) { + yield* _(display("Too high")) + return yield* _(ko) + } else if (guess < secret) { + yield* _(display("Too low")) + return yield* _(ko) + } else { + return yield* _(ok) + } + }) + +const end = display("You guessed it!") + +const loop = ( + secret: number +): Effect.Effect< + void, + Terminal.QuitException | PlatformError, + Terminal.Terminal +> => + Effect.gen(function* (_) { + const guess = yield* _(answer) + return yield* _( + check( + secret, + guess, + end, + Effect.suspend(() => loop(secret)) + ) + ) + }) + +export const game = Effect.gen(function* (_) { + yield* _( + display( + "We have selected a random number between 1 and 100. See if you can guess it in 10 turns or fewer. We'll tell you if your guess was too high or too low." + ) + ) + yield* _(loop(yield* _(secret))) +}) +``` + +Let's run the game in Node.js: + +```ts +import { NodeRuntime, NodeTerminal } from "@effect/platform-node" +import * as Effect from "effect/Effect" +import { game } from "./game.js" + +NodeRuntime.runMain(game.pipe(Effect.provide(NodeTerminal.layer))) +``` + +Let's run the game in Bun: + +```ts +import { BunRuntime, BunTerminal } from "@effect/platform-bun" +import * as Effect from "effect/Effect" +import { game } from "./game.js" + +BunRuntime.runMain(game.pipe(Effect.provide(BunTerminal.layer))) +``` + +# Command + +As an example of using the `@effect/platform/Command` module, let's see how to run the TypeScript compiler `tsc`: + +```ts +import { Command, CommandExecutor } from "@effect/platform" +import { + NodeCommandExecutor, + NodeFileSystem, + NodeRuntime +} from "@effect/platform-node" +import { Effect } from "effect" + +// const program: Effect.Effect +const program = Effect.gen(function* (_) { + const executor = yield* _(CommandExecutor.CommandExecutor) + + // Creating a command to run the TypeScript compiler + const command = Command.make("tsc", "--noEmit") + console.log("Running tsc...") + + // Executing the command and capturing the output + const output = yield* _(executor.string(command)) + console.log(output) + return output +}) + +// Running the program with the necessary runtime and executor layers +NodeRuntime.runMain( + program.pipe( + Effect.provide(NodeCommandExecutor.layer), + Effect.provide(NodeFileSystem.layer) + ) +) +``` + +## Obtaining Information About the Running Process + +Here, we'll explore how to retrieve information about a running process. + +```ts +import { Command, CommandExecutor } from "@effect/platform" +import { + NodeCommandExecutor, + NodeFileSystem, + NodeRuntime +} from "@effect/platform-node" +import { Effect, Stream, String } from "effect" + +const runString = ( + stream: Stream.Stream +): Effect.Effect => + stream.pipe(Stream.decodeText(), Stream.runFold(String.empty, String.concat)) + +const program = Effect.gen(function* (_) { + const executor = yield* _(CommandExecutor.CommandExecutor) + + const command = Command.make("ls") + + const [exitCode, stdout, stderr] = yield* _( + // Start running the command and return a handle to the running process. + executor.start(command), + Effect.flatMap((process) => + Effect.all( + [ + // Waits for the process to exit and returns the ExitCode of the command that was run. + process.exitCode, + // The standard output stream of the process. + runString(process.stdout), + // The standard error stream of the process. + runString(process.stderr) + ], + { concurrency: 3 } + ) + ) + ) + console.log({ exitCode, stdout, stderr }) +}) + +NodeRuntime.runMain( + Effect.scoped(program).pipe( + Effect.provide(NodeCommandExecutor.layer), + Effect.provide(NodeFileSystem.layer) + ) +) +``` + +## Running a Platform Command with stdout Streamed to process.stdout + +To run a command (for example `cat`) and stream its `stdout` to `process.stdout` follow these steps: + +```ts +import { Command } from "@effect/platform" +import { NodeContext, NodeRuntime } from "@effect/platform-node" +import { Effect } from "effect" + +// Create a command to run `cat` on a file and inherit stdout +const program = Command.make("cat", "./some-file.txt").pipe( + Command.stdout("inherit"), + Command.exitCode +) + +// Run the command using NodeRuntime with the NodeContext layer +NodeRuntime.runMain(program.pipe(Effect.provide(NodeContext.layer))) +``` + +# FileSystem + +The `@effect/platform/FileSystem` module provides a single `FileSystem` tag, which acts as the gateway for interacting with the filesystem. + +Here's a list of operations that can be performed using the `FileSystem` tag: + +| **Name** | **Arguments** | **Return** | **Description** | +| --------------------------- | ---------------------------------------------------------------- | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **access** | `path: string`, `options?: AccessFileOptions` | `Effect` | Check if a file can be accessed. You can optionally specify the level of access to check for. | +| **copy** | `fromPath: string`, `toPath: string`, `options?: CopyOptions` | `Effect` | Copy a file or directory from `fromPath` to `toPath`. Equivalent to `cp -r`. | +| **copyFile** | `fromPath: string`, `toPath: string` | `Effect` | Copy a file from `fromPath` to `toPath`. | +| **chmod** | `path: string`, `mode: number` | `Effect` | Change the permissions of a file. | +| **chown** | `path: string`, `uid: number`, `gid: number` | `Effect` | Change the owner and group of a file. | +| **exists** | `path: string` | `Effect` | Check if a path exists. | +| **link** | `fromPath: string`, `toPath: string` | `Effect` | Create a hard link from `fromPath` to `toPath`. | +| **makeDirectory** | `path: string`, `options?: MakeDirectoryOptions` | `Effect` | Create a directory at `path`. You can optionally specify the mode and whether to recursively create nested directories. | +| **makeTempDirectory** | `options?: MakeTempDirectoryOptions` | `Effect` | Create a temporary directory. By default, the directory will be created inside the system's default temporary directory. | +| **makeTempDirectoryScoped** | `options?: MakeTempDirectoryOptions` | `Effect` | Create a temporary directory inside a scope. Functionally equivalent to `makeTempDirectory`, but the directory will be automatically deleted when the scope is closed. | +| **makeTempFile** | `options?: MakeTempFileOptions` | `Effect` | Create a temporary file. The directory creation is functionally equivalent to `makeTempDirectory`. The file name will be a randomly generated string. | +| **makeTempFileScoped** | `options?: MakeTempFileOptions` | `Effect` | Create a temporary file inside a scope. Functionally equivalent to `makeTempFile`, but the file will be automatically deleted when the scope is closed. | +| **open** | `path: string`, `options?: OpenFileOptions` | `Effect` | Open a file at `path` with the specified `options`. The file handle will be automatically closed when the scope is closed. | +| **readDirectory** | `path: string`, `options?: ReadDirectoryOptions` | `Effect, PlatformError>` | List the contents of a directory. You can recursively list the contents of nested directories by setting the `recursive` option. | +| **readFile** | `path: string` | `Effect` | Read the contents of a file. | +| **readFileString** | `path: string`, `encoding?: string` | `Effect` | Read the contents of a file as a string. | +| **readLink** | `path: string` | `Effect` | Read the destination of a symbolic link. | +| **realPath** | `path: string` | `Effect` | Resolve a path to its canonicalized absolute pathname. | +| **remove** | `path: string`, `options?: RemoveOptions` | `Effect` | Remove a file or directory. By setting the `recursive` option to `true`, you can recursively remove nested directories. | +| **rename** | `oldPath: string`, `newPath: string` | `Effect` | Rename a file or directory. | +| **sink** | `path: string`, `options?: SinkOptions` | `Sink` | Create a writable `Sink` for the specified `path`. | +| **stat** | `path: string` | `Effect` | Get information about a file at `path`. | +| **stream** | `path: string`, `options?: StreamOptions` | `Stream` | Create a readable `Stream` for the specified `path`. | +| **symlink** | `fromPath: string`, `toPath: string` | `Effect` | Create a symbolic link from `fromPath` to `toPath`. | +| **truncate** | `path: string`, `length?: SizeInput` | `Effect` | Truncate a file to a specified length. If the `length` is not specified, the file will be truncated to length `0`. | +| **utimes** | `path: string`, `atime: Date \| number`, `mtime: Date \| number` | `Effect` | Change the file system timestamps of the file at `path`. | +| **watch** | `path: string` | `Stream` | Watch a directory or file for changes. | + +Let's explore a simple example using `readFileString`: + +```ts +import { FileSystem } from "@effect/platform" +import { NodeFileSystem, NodeRuntime } from "@effect/platform-node" +import { Effect } from "effect" + +// const readFileString: Effect.Effect +const readFileString = Effect.gen(function* (_) { + const fs = yield* _(FileSystem.FileSystem) + + // Reading the content of the same file where this code is written + const content = yield* _(fs.readFileString("./index.ts", "utf8")) + console.log(content) +}) + +NodeRuntime.runMain(readFileString.pipe(Effect.provide(NodeFileSystem.layer))) +``` + +# KeyValueStore + +## Overview + +The `KeyValueStore` module provides a robust and effectful interface for managing key-value pairs. It supports asynchronous operations, ensuring data integrity and consistency, and includes built-in implementations for in-memory, file system-based, and schema-validated stores. + +## Basic Usage + +The `KeyValueStore` interface includes the following operations: + +- **get**: Retrieve a value by key. +- **set**: Store a key-value pair. +- **remove**: Delete a key-value pair. +- **clear**: Remove all key-value pairs. +- **size**: Get the number of stored pairs. +- **modify**: Atomically modify a value. +- **has**: Check if a key exists. +- **isEmpty**: Check if the store is empty. + +**Example** + +```ts +import { KeyValueStore, layerMemory } from "@effect/platform/KeyValueStore" +import { Effect } from "effect" + +const program = Effect.gen(function* () { + const store = yield* KeyValueStore + console.log(yield* store.size) // Outputs: 0 + + yield* store.set("key", "value") + console.log(yield* store.size) // Outputs: 1 + + const value = yield* store.get("key") + console.log(value) // Outputs: { _id: 'Option', _tag: 'Some', value: 'value' } + + yield* store.remove("key") + console.log(yield* store.size) // Outputs: 0 +}) + +Effect.runPromise(program.pipe(Effect.provide(layerMemory))) +``` + +## Built-in Implementations + +The module provides several built-in implementations to suit different needs: + +- **In-Memory Store**: `layerMemory` provides a simple, in-memory key-value store, ideal for lightweight or testing scenarios. +- **File System Store**: `layerFileSystem` offers a file-based store for persistent storage needs. +- **Schema Store**: `layerSchema` enables schema-based validation for stored values, ensuring data integrity and type safety. + +## Schema Store + +The `SchemaStore` implementation allows you to validate and parse values according to a defined schema. This ensures that all data stored in the key-value store adheres to the specified structure, enhancing data integrity and type safety. + +**Example** + +```ts +import { KeyValueStore, layerMemory } from "@effect/platform/KeyValueStore" +import { Schema } from "@effect/schema" +import { Effect } from "effect" + +// Define a schema for the values +const Person = Schema.Struct({ + name: Schema.String, + age: Schema.Number +}) + +const program = Effect.gen(function* () { + const store = (yield* KeyValueStore).forSchema(Person) + + // Create a value that adheres to the schema + const value = { name: "Alice", age: 30 } + yield* store.set("user1", value) + console.log(yield* store.size) // Outputs: 1 + + // Retrieve and validate the value + const retrievedValue = yield* store.get("user1") + console.log(retrievedValue) // Outputs: { _id: 'Option', _tag: 'Some', value: { name: 'Alice', age: 30 } } +}) + +Effect.runPromise(program.pipe(Effect.provide(layerMemory))) +``` + +In this example: + +- **Person**: Defines the structure for the values stored in the key-value store. +- **store.set**: Stores a value adhering to `Person`. +- **store.get**: Retrieves and validates the stored value against `Person`. diff --git a/packages/platform/src/HttpApi.ts b/packages/platform/src/HttpApi.ts index b5f14cb69e..456eb0ffd6 100644 --- a/packages/platform/src/HttpApi.ts +++ b/packages/platform/src/HttpApi.ts @@ -162,7 +162,8 @@ export const addGroup: { ): HttpApi.Any => { const group = args.length === 1 ? args[0] : HttpApiGroup.prefix(args[1] as any, args[0]) return makeProto({ - ...self as any, + errorSchema: self.errorSchema as any, + annotations: self.annotations, groups: Chunk.append(self.groups, group) }) } @@ -202,7 +203,8 @@ export const addError: { } ): HttpApi => makeProto({ - ...self, + groups: self.groups, + annotations: self.annotations, errorSchema: HttpApiSchema.UnionUnify( self.errorSchema, schema.annotations(HttpApiSchema.annotations({ @@ -223,7 +225,8 @@ export const annotateMerge: { 2, (self: A, context: Context.Context): A => makeProto({ - ...self as any, + groups: self.groups, + errorSchema: self.errorSchema as any, annotations: Context.merge(self.annotations, context) }) as A ) @@ -239,7 +242,8 @@ export const annotate: { 3, (self: A, tag: Context.Tag, value: S): A => makeProto({ - ...self as any, + groups: self.groups, + errorSchema: self.errorSchema as any, annotations: Context.add(self.annotations, tag, value) }) as A ) diff --git a/packages/platform/src/HttpApiBuilder.ts b/packages/platform/src/HttpApiBuilder.ts index 6d6915d990..4269465d73 100644 --- a/packages/platform/src/HttpApiBuilder.ts +++ b/packages/platform/src/HttpApiBuilder.ts @@ -811,6 +811,7 @@ const makeErrorSchema = ( schemas.add(schema) } } + processSchema(api.errorSchema) for (const group of api.groups) { for (const endpoint of group.endpoints) { processSchema(endpoint.errorSchema) diff --git a/packages/platform/src/HttpApiError.ts b/packages/platform/src/HttpApiError.ts index 40b552e3a5..10c414fbdc 100644 --- a/packages/platform/src/HttpApiError.ts +++ b/packages/platform/src/HttpApiError.ts @@ -6,6 +6,7 @@ import type * as ParseResult from "@effect/schema/ParseResult" import * as Schema from "@effect/schema/Schema" import * as TreeFormatter from "@effect/schema/TreeFormatter" import * as Effect from "effect/Effect" +import { identity } from "effect/Function" import * as HttpApiSchema from "./HttpApiSchema.js" /** @@ -30,12 +31,36 @@ export interface Issue extends _tag: Schema.Literal< ["Pointer", "Unexpected", "Missing", "Composite", "Refinement", "Transformation", "Type", "Forbidden"] > - path: Schema.Array$> + path: PropertyKeysNoSymbol message: typeof Schema.String } > {} +/** + * @since 1.0.0 + * @category schemas + */ +export interface PropertyKeysNoSymbol extends + Schema.transform< + Schema.Array$>, + Schema.Array$> + > +{} + +/** + * @since 1.0.0 + * @category schemas + */ +export const PropertyKeysNoSymbol: PropertyKeysNoSymbol = Schema.transform( + Schema.Array(Schema.Union(Schema.String, Schema.Number)), + Schema.Array(Schema.Union(Schema.SymbolFromSelf, Schema.String, Schema.Number)), + { + decode: identity, + encode: (items) => items.filter((item) => typeof item !== "symbol") + } +) + /** * @since 1.0.0 * @category schemas @@ -51,7 +76,7 @@ export const Issue: Issue = Schema.Struct({ "Type", "Forbidden" ), - path: Schema.Array(Schema.Union(Schema.Symbol, Schema.String, Schema.Number)), + path: PropertyKeysNoSymbol, message: Schema.String }) @@ -67,7 +92,7 @@ export class HttpApiDecodeError extends Schema.TaggedError() }, HttpApiSchema.annotations({ status: 400, - description: "ApiDecodeError: The request did not match the expected schema" + description: "HttpApiDecodeError: The request did not match the expected schema" }) ) { /** diff --git a/packages/platform/src/HttpApiGroup.ts b/packages/platform/src/HttpApiGroup.ts index e08b0751c5..d64550c609 100644 --- a/packages/platform/src/HttpApiGroup.ts +++ b/packages/platform/src/HttpApiGroup.ts @@ -201,7 +201,9 @@ export const add: { endpoint: A ): HttpApiGroup => makeProto({ - ...self, + identifier: self.identifier, + errorSchema: self.errorSchema, + annotations: self.annotations, endpoints: Chunk.append(self.endpoints, endpoint) })) @@ -238,7 +240,9 @@ export const addError: { } ): HttpApiGroup => makeProto({ - ...self, + identifier: self.identifier, + annotations: self.annotations, + endpoints: self.endpoints, errorSchema: HttpApiSchema.UnionUnify( self.errorSchema, schema.annotations(HttpApiSchema.annotations({ @@ -270,7 +274,9 @@ export const prefix: { prefix: PathInput ): HttpApiGroup => makeProto({ - ...self, + identifier: self.identifier, + errorSchema: self.errorSchema, + annotations: self.annotations, endpoints: Chunk.map(self.endpoints, HttpApiEndpoint.prefix(prefix)) })) @@ -305,7 +311,9 @@ export const annotate: { 3, (self: A, tag: Context.Tag, value: S): A => makeProto({ - ...self as any, + identifier: self.identifier, + errorSchema: self.errorSchema as any, + endpoints: self.endpoints, annotations: Context.add(self.annotations, tag, value) }) as A ) @@ -326,7 +334,9 @@ export const annotateEndpointsMerge: { 2, (self: A, context: Context.Context): A => makeProto({ - ...self as any, + identifier: self.identifier, + errorSchema: self.errorSchema as any, + annotations: self.annotations, endpoints: Chunk.map(self.endpoints, HttpApiEndpoint.annotateMerge(context)) }) as A ) @@ -347,7 +357,9 @@ export const annotateEndpoints: { 3, (self: A, tag: Context.Tag, value: S): A => makeProto({ - ...self as any, + identifier: self.identifier, + errorSchema: self.errorSchema as any, + annotations: self.annotations, endpoints: Chunk.map(self.endpoints, HttpApiEndpoint.annotate(tag, value)) }) as A ) diff --git a/packages/platform/src/OpenApi.ts b/packages/platform/src/OpenApi.ts index 4196eb32a9..0d62323f83 100644 --- a/packages/platform/src/OpenApi.ts +++ b/packages/platform/src/OpenApi.ts @@ -482,7 +482,7 @@ export type OpenAPISpecPathItem = * @category models * @since 1.0.0 */ -export type OpenAPIJSONSchema = Omit +export type OpenAPIJSONSchema = JSONSchema.JsonSchema7 /** * @category models From b20a408f5d3aa9b678a77891b1753d7189262712 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 29 Aug 2024 12:21:31 +1200 Subject: [PATCH 54/59] README tweaks --- packages/platform/README.md | 57 ++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/packages/platform/README.md b/packages/platform/README.md index cbf2df92a4..cd7753e826 100644 --- a/packages/platform/README.md +++ b/packages/platform/README.md @@ -209,7 +209,7 @@ just by calling `HttpApiEndpoint.addError` multiple times. ### Multipart requests If you need to handle file uploads, you can use the `HttpApiSchema.Multipart` -api to flag a `HttpApiSchema` payload schema as a multipart request. +api to flag a `HttpApiEnen` payload schema as a multipart request. You can then use the schemas from the `Multipart` module to define the expected shape of the multipart request. @@ -238,7 +238,7 @@ class UsersApi extends HttpApiGroup.make("users").pipe( The `HttpApiSecurity` module provides a way to add security annotations to your API. -The `HttpApiSecurity` offers the following authorization types: +It offers the following authorization types: - `HttpApiSecurity.apiKey` - API key authorization through headers, query parameters, or cookies. @@ -283,7 +283,12 @@ server. ### Implementing a `HttpApiGroup` -First up, let's implement an `UsersApi` group with a single `findById` endpoint: +First up, let's implement an `UsersApi` group with a single `findById` endpoint. + +The `HttpApiBuilder.group` api takes the `HttpApi` definition, the group name, +and a function that adds the handlers required for the group. + +Each endpoint is implemented using the `HttpApiBuilder.handle` api. ```ts import { @@ -321,7 +326,7 @@ class MyApi extends HttpApi.empty.pipe(HttpApi.addGroup(UsersApi)) {} // Implementation // -------------------------------------------- -// the `HttpApiBuilder.group` api return a `Layer` +// the `HttpApiBuilder.group` api returns a `Layer` const UsersApiLive: Layer.Layer> = HttpApiBuilder.group(MyApi, "users", (handlers) => handlers.pipe( @@ -501,28 +506,7 @@ const UsersApiLive = HttpApiBuilder.group(MyApi, "users", (handlers) => ) ``` -## Deriving a client - -Once you have defined your API, you can derive a client that can interact with -the server. - -The `HttpApiClient` module provides all the apis you need to derive a client. - -```ts -import { HttpApiClient } from "@effect/platform" - -Effect.gen(function* () { - const client = yield* HttpApiClient.make(MyApi, { - baseUrl: "http://localhost:3000" - // You can tranform the HttpClient to add things like authentication - // transformClient: .... - }) - const user = yield* client.users.findById({ path: { id: 1 } }) - yield* Effect.log(user) -}) -``` - -## Swagger documentation +### Serving Swagger documentation You can add Swagger documentation to your API using the `HttpApiSwagger` module. @@ -546,6 +530,27 @@ const HttpLive = HttpApiBuilder.serve(HttpMiddleware.logger).pipe( ) ``` +## Deriving a client + +Once you have defined your API, you can derive a client that can interact with +the server. + +The `HttpApiClient` module provides all the apis you need to derive a client. + +```ts +import { HttpApiClient } from "@effect/platform" + +Effect.gen(function* () { + const client = yield* HttpApiClient.make(MyApi, { + baseUrl: "http://localhost:3000" + // You can transform the HttpClient to add things like authentication + // transformClient: .... + }) + const user = yield* client.users.findById({ path: { id: 1 } }) + yield* Effect.log(user) +}) +``` + # HTTP Client ## Overview From 4fde20340c1636a9028e93fca1aa471ae534d47a Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 29 Aug 2024 16:45:04 +1200 Subject: [PATCH 55/59] add success encoding type support --- packages/platform-node/examples/api.ts | 48 ++++++++ packages/platform/src/HttpApi.ts | 2 + packages/platform/src/HttpApiBuilder.ts | 48 ++++++-- packages/platform/src/HttpApiClient.ts | 48 ++++++-- packages/platform/src/HttpApiSchema.ts | 128 ++++++++++++++++---- packages/platform/src/HttpServerResponse.ts | 6 +- packages/platform/src/OpenApi.ts | 4 +- 7 files changed, 238 insertions(+), 46 deletions(-) diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index fb9f77ea9b..f9d7b372fa 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -66,6 +66,37 @@ class UsersApi extends HttpApiGroup.make("users").pipe( HttpApiEndpoint.setSuccess(User) ) ), + HttpApiGroup.add( + HttpApiEndpoint.get("csv", "/csv").pipe( + HttpApiEndpoint.setSuccess(Schema.String.pipe( + HttpApiSchema.withEncoding({ + kind: "Text", + contentType: "text/csv" + }) + )) + ) + ), + HttpApiGroup.add( + HttpApiEndpoint.get("binary", "/binary").pipe( + HttpApiEndpoint.setSuccess(Schema.Uint8ArrayFromSelf.pipe( + HttpApiSchema.withEncoding({ kind: "Uint8Array" }) + )) + ) + ), + HttpApiGroup.add( + HttpApiEndpoint.get("urlParams", "/url-params").pipe( + HttpApiEndpoint.setSuccess( + Schema.Struct({ + id: Schema.NumberFromString, + name: Schema.String + }).pipe( + HttpApiSchema.withEncoding({ + kind: "UrlParams" + }) + ) + ) + ) + ), HttpApiGroup.addError(Unauthorized), HttpApiGroup.prefix("/users"), OpenApi.annotate({ security }) @@ -97,6 +128,13 @@ const UsersLive = HttpApiBuilder.group(MyApi, "users", (handlers) => }) )), HttpApiBuilder.handle("me", (_) => CurrentUser), + HttpApiBuilder.handle("csv", (_) => Effect.succeed("id,name\n1,John")), + HttpApiBuilder.handle("urlParams", (_) => + Effect.succeed({ + id: 123, + name: "John" + })), + HttpApiBuilder.handle("binary", (_) => Effect.succeed(new Uint8Array([1, 2, 3, 4, 5]))), securityMiddleware )) @@ -106,6 +144,7 @@ const ApiLive = HttpApiBuilder.api(MyApi).pipe( HttpApiBuilder.serve(HttpMiddleware.logger).pipe( Layer.provide(HttpApiSwagger.layer()), + Layer.provide(HttpApiBuilder.middlewareOpenApi()), Layer.provide(ApiLive), Layer.provide(HttpApiBuilder.middlewareCors()), HttpServer.withLogAddress, @@ -129,6 +168,15 @@ Effect.gen(function*() { headers: { page: 10 } }) console.log("json", user) + + const csv = yield* client.users.csv() + console.log("csv", csv) + + const urlParams = yield* client.users.urlParams() + console.log("urlParams", urlParams) + + const binary = yield* client.users.binary() + console.log("binary", binary) }).pipe( Effect.provide(HttpClient.layer), NodeRuntime.runMain diff --git a/packages/platform/src/HttpApi.ts b/packages/platform/src/HttpApi.ts index 456eb0ffd6..dc361cf102 100644 --- a/packages/platform/src/HttpApi.ts +++ b/packages/platform/src/HttpApi.ts @@ -270,6 +270,7 @@ export const reflect = readonly successAST: Option.Option readonly successStatus: number + readonly successEncoding: HttpApiSchema.Encoding readonly errors: ReadonlyMap> }) => void } @@ -294,6 +295,7 @@ export const reflect = schema.ast) ), successStatus: HttpApiSchema.getStatusSuccess(endpoint.successSchema), + successEncoding: HttpApiSchema.getEncoding(endpoint.successSchema.ast), errors: extractErrors(endpoint.errorSchema.ast, groupErrors) }) } diff --git a/packages/platform/src/HttpApiBuilder.ts b/packages/platform/src/HttpApiBuilder.ts index 4269465d73..acd6f394b3 100644 --- a/packages/platform/src/HttpApiBuilder.ts +++ b/packages/platform/src/HttpApiBuilder.ts @@ -733,8 +733,47 @@ const handlerToRoute = ( ) const decodePayload = Option.map(endpoint.payloadSchema, Schema.decodeUnknown) const decodeHeaders = Option.map(endpoint.headersSchema, Schema.decodeUnknown) - const encodeSuccess = Option.map(HttpApiEndpoint.schemaSuccess(endpoint), Schema.encodeUnknown) + const encoding = HttpApiSchema.getEncoding(endpoint.successSchema.ast) const successStatus = HttpApiSchema.getStatusSuccess(endpoint.successSchema) + const encodeSuccess = Option.map(HttpApiEndpoint.schemaSuccess(endpoint), (schema) => { + const encode = Schema.encodeUnknown(schema) + switch (encoding.kind) { + case "Json": { + return (body: unknown) => + Effect.orDie( + Effect.flatMap(encode(body), (json) => + HttpServerResponse.json(json, { + status: successStatus, + contentType: encoding.contentType + })) + ) + } + case "Text": { + return (body: unknown) => + Effect.map(Effect.orDie(encode(body)), (text) => + HttpServerResponse.text(text as any, { + status: successStatus, + contentType: encoding.contentType + })) + } + case "Uint8Array": { + return (body: unknown) => + Effect.map(Effect.orDie(encode(body)), (data) => + HttpServerResponse.uint8Array(data as any, { + status: successStatus, + contentType: encoding.contentType + })) + } + case "UrlParams": { + return (body: unknown) => + Effect.map(Effect.orDie(encode(body)), (params) => + HttpServerResponse.urlParams(params as any, { + status: successStatus, + contentType: encoding.contentType + })) + } + } + }) return HttpRouter.makeRoute( endpoint.method, endpoint.path, @@ -770,12 +809,7 @@ const handlerToRoute = ( isFullResponse ? identity as (_: any) => Effect.Effect : encodeSuccess._tag === "Some" - ? Effect.flatMap((body) => - encodeSuccess.value(body).pipe( - Effect.flatMap((json) => HttpServerResponse.json(json, { status: successStatus })), - Effect.orDie - ) - ) + ? Effect.flatMap(encodeSuccess.value) : Effect.as(HttpServerResponse.empty({ status: successStatus })) ) }) diff --git a/packages/platform/src/HttpApiClient.ts b/packages/platform/src/HttpApiClient.ts index ea0852a0bc..74034d5bb4 100644 --- a/packages/platform/src/HttpApiClient.ts +++ b/packages/platform/src/HttpApiClient.ts @@ -1,13 +1,13 @@ /** * @since 1.0.0 */ +import * as ParseResult from "@effect/schema/ParseResult" import * as Schema from "@effect/schema/Schema" import * as Context from "effect/Context" import * as Effect from "effect/Effect" import { identity } from "effect/Function" import * as Option from "effect/Option" import type { Simplify } from "effect/Types" -import { unify } from "effect/Unify" import * as HttpApi from "./HttpApi.js" import type { HttpApiEndpoint } from "./HttpApiEndpoint.js" import type { HttpApiGroup } from "./HttpApiGroup.js" @@ -71,12 +71,32 @@ export const make = ( onGroup({ group }) { client[group.identifier] = {} }, - onEndpoint({ endpoint, errors, group, successAST, successStatus }) { + onEndpoint({ endpoint, errors, group, successAST, successEncoding, successStatus }) { const makeUrl = compilePath(endpoint.path) - const handleSuccess = unify(Option.match(successAST, { - onNone: () => HttpClientResponse.void, - onSome: (ast) => HttpClientResponse.schemaBodyJsonScoped(Schema.make(ast)) - })) + const successDecode = successAST.pipe( + Option.map((ast) => { + const schema = Schema.make(ast) + switch (successEncoding.kind) { + case "Json": { + return HttpClientResponse.schemaBodyJson(schema) + } + case "UrlParams": { + return HttpClientResponse.schemaBodyUrlParams(schema as any) + } + case "Uint8Array": { + return (response: HttpClientResponse.HttpClientResponse) => + response.arrayBuffer.pipe( + Effect.map((buffer) => new Uint8Array(buffer)), + Effect.flatMap(Schema.decodeUnknown(schema)) + ) + } + case "Text": { + return (response: HttpClientResponse.HttpClientResponse) => + Effect.flatMap(response.text, Schema.decodeUnknown(schema)) + } + } + }) + ) const handleError = ( request: HttpClientRequest.HttpClientRequest, response: HttpClientResponse.HttpClientResponse @@ -166,14 +186,16 @@ export const make = ( ) : identity, Effect.flatMap((request) => - httpClient(request).pipe( - Effect.orDie, - Effect.flatMap((response) => - response.status !== successStatus ? handleError(request, response) : Effect.succeed(response) - ) - ) + Effect.flatMap(httpClient(request), (response) => + response.status !== successStatus + ? handleError(request, response) + : Effect.succeed(response)) ), - handleSuccess, + successDecode._tag === "Some" + ? Effect.flatMap(successDecode.value) + : Effect.asVoid, + Effect.scoped, + Effect.catchIf(ParseResult.isParseError, Effect.die), Effect.mapInputContext((input) => Context.merge(context, input)) ) } diff --git a/packages/platform/src/HttpApiSchema.ts b/packages/platform/src/HttpApiSchema.ts index 4e35f037a5..2f7d14d1a6 100644 --- a/packages/platform/src/HttpApiSchema.ts +++ b/packages/platform/src/HttpApiSchema.ts @@ -34,44 +34,49 @@ export const AnnotationEmptyDecodeable: unique symbol = Symbol.for( * @since 1.0.0 * @category annotations */ -export const getStatus = (ast: AST.AST, defaultStatus: number): number => { - const annotations = ast._tag === "Transformation" ? +export const AnnotationEncoding: unique symbol = Symbol.for("@effect/platform/HttpApiSchema/AnnotationEncoding") + +const mergedAnnotations = (ast: AST.AST): Record => + ast._tag === "Transformation" ? { ...ast.to.annotations, ...ast.annotations } : ast.annotations - return annotations[AnnotationStatus] as number ?? defaultStatus -} + +const getAnnotation = (ast: AST.AST, key: symbol): A | undefined => mergedAnnotations(ast)[key] as A /** * @since 1.0.0 * @category annotations */ -export const getEmptyDecodeable = (ast: AST.AST): boolean => { - const annotations = ast._tag === "Transformation" ? - { - ...ast.to.annotations, - ...ast.annotations - } : - ast.annotations - return annotations[AnnotationEmptyDecodeable] as boolean ?? false -} +export const getStatus = (ast: AST.AST, defaultStatus: number): number => + getAnnotation(ast, AnnotationStatus) ?? defaultStatus /** * @since 1.0.0 * @category annotations */ -export const getMultipart = (ast: AST.AST): boolean => { - const annotations = ast._tag === "Transformation" ? - { - ...ast.to.annotations, - ...ast.annotations - } : - ast.annotations - return annotations[AnnotationMultipart] as boolean ?? false +export const getEmptyDecodeable = (ast: AST.AST): boolean => + getAnnotation(ast, AnnotationEmptyDecodeable) ?? false + +/** + * @since 1.0.0 + * @category annotations + */ +export const getMultipart = (ast: AST.AST): boolean => getAnnotation(ast, AnnotationMultipart) ?? false + +const encodingJson: Encoding = { + kind: "Json", + contentType: "application/json" } +/** + * @since 1.0.0 + * @category annotations + */ +export const getEncoding = (ast: AST.AST): Encoding => getAnnotation(ast, AnnotationEncoding) ?? encodingJson + /** * @since 1.0.0 * @category annotations @@ -280,3 +285,84 @@ export const Multipart = (self: S): Multipart => self.annotations({ [AnnotationMultipart]: true }) as any + +const defaultContentType = (encoding: Encoding["kind"]) => { + switch (encoding) { + case "Json": { + return "application/json" + } + case "UrlParams": { + return "application/x-www-form-urlencoded" + } + case "Uint8Array": { + return "application/octet-stream" + } + case "Text": { + return "text/plain" + } + } +} + +/** + * @since 1.0.0 + * @category encoding + */ +export interface Encoding { + readonly kind: "Json" | "UrlParams" | "Uint8Array" | "Text" + readonly contentType: string +} + +/** + * @since 1.0.0 + * @category encoding + */ +export declare namespace Encoding { + /** + * @since 1.0.0 + * @category encoding + */ + export type Validate = Kind extends "Json" ? {} + : Kind extends "UrlParams" ? [A["Encoded"]] extends [Readonly>] ? {} + : `'UrlParams' kind can only be encoded to 'Record'` + : Kind extends "Uint8Array" ? + [A["Encoded"]] extends [Uint8Array] ? {} : `'Uint8Array' kind can only be encoded to 'Uint8Array'` + : Kind extends "Text" ? [A["Encoded"]] extends [string] ? {} : `'Text' kind can only be encoded to 'string'` + : never +} + +/** + * @since 1.0.0 + * @category encoding + */ +export const withEncoding: { + ( + options: { + readonly kind: Kind + readonly contentType?: string | undefined + } & Encoding.Validate + ): (self: A) => A + ( + self: A, + options: { + readonly kind: Kind + readonly contentType?: string | undefined + } & Encoding.Validate + ): A +} = dual(2, (self: A, options: { + readonly kind: Encoding["kind"] + readonly contentType?: string | undefined +}): A => + self.annotations({ + [AnnotationEncoding]: { + kind: options.kind, + contentType: options.contentType ?? defaultContentType(options.kind) + }, + ...(options.kind === "Uint8Array" ? + { + jsonSchema: { + type: "string", + format: "binary" + } + } : + undefined) + }) as any) diff --git a/packages/platform/src/HttpServerResponse.ts b/packages/platform/src/HttpServerResponse.ts index f0a624d150..3a2ed00f8f 100644 --- a/packages/platform/src/HttpServerResponse.ts +++ b/packages/platform/src/HttpServerResponse.ts @@ -124,7 +124,7 @@ export const htmlStream: Effect.Effect = internal.json /** @@ -141,14 +141,14 @@ export const schemaJson: ( * @since 1.0.0 * @category constructors */ -export const unsafeJson: (body: unknown, options?: Options.WithContent | undefined) => HttpServerResponse = +export const unsafeJson: (body: unknown, options?: Options.WithContentType | undefined) => HttpServerResponse = internal.unsafeJson /** * @since 1.0.0 * @category constructors */ -export const urlParams: (body: UrlParams.Input, options?: Options.WithContent | undefined) => HttpServerResponse = +export const urlParams: (body: UrlParams.Input, options?: Options.WithContentType | undefined) => HttpServerResponse = internal.urlParams /** diff --git a/packages/platform/src/OpenApi.ts b/packages/platform/src/OpenApi.ts index 0d62323f83..c95e254f03 100644 --- a/packages/platform/src/OpenApi.ts +++ b/packages/platform/src/OpenApi.ts @@ -203,7 +203,7 @@ export const fromApi = (api: A): OpenAPISpec => { }) spec.tags!.push(tag) }, - onEndpoint({ endpoint, errors, group, mergedAnnotations, successAST, successStatus }) { + onEndpoint({ endpoint, errors, group, mergedAnnotations, successAST, successEncoding, successStatus }) { const path = endpoint.path.replace(/:(\w+)[^/]*/g, "{$1}") const method = endpoint.method.toLowerCase() as OpenAPISpecMethodName const op: DeepMutable = { @@ -244,7 +244,7 @@ export const fromApi = (api: A): OpenAPISpec => { successAST.pipe( Option.map((ast) => { op.responses![successStatus].content = { - "application/json": { + [successEncoding.contentType]: { schema: makeJsonSchema(Schema.make(ast)) } } From b9d717558a0b10ead77d999d963ce1edc3ab13c2 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 29 Aug 2024 16:49:15 +1200 Subject: [PATCH 56/59] document withEncoding --- packages/platform/README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/packages/platform/README.md b/packages/platform/README.md index cd7753e826..c5269a49a0 100644 --- a/packages/platform/README.md +++ b/packages/platform/README.md @@ -273,6 +273,30 @@ class UsersApi extends HttpApiGroup.make("users").pipe( ) {} ``` +### Changing the response encoding + +By default, the response is encoded as JSON. You can change the encoding using +the `HttpApiSchema.withEncoding` api. + +Here is an example of changing the encoding to text/csv: + +```ts +class UsersApi extends HttpApiGroup.make("users").pipe( + HttpApiGroup.add( + HttpApiEndpoint.get("csv", "/users/csv").pipe( + HttpApiEndpoint.setSuccess( + Schema.String.pipe( + HttpApiSchema.withEncoding({ + kind: "Text", + contentType: "text/csv" + }) + ) + ) + ) + ) +) {} +``` + ## Implementing a server Now that you have defined your API, you can implement a server that serves the From 509d91e00f89f46740509aee1dda374f3172ccb6 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 29 Aug 2024 17:00:47 +1200 Subject: [PATCH 57/59] add changeset --- .changeset/curvy-clouds-battle.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .changeset/curvy-clouds-battle.md diff --git a/.changeset/curvy-clouds-battle.md b/.changeset/curvy-clouds-battle.md new file mode 100644 index 0000000000..4621517e74 --- /dev/null +++ b/.changeset/curvy-clouds-battle.md @@ -0,0 +1,10 @@ +--- +"@effect/platform": patch +--- + +add HttpApi modules + +The `HttpApi` family of modules provide a declarative way to define HTTP APIs. + +For more infomation see the README.md for the /platform package:
    +https://github.com/Effect-TS/effect/blob/main/packages/platform/README.md From 002f244e9d13914298f53a5aef98f488572d4f1f Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 29 Aug 2024 17:06:17 +1200 Subject: [PATCH 58/59] fix typo --- packages/platform/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/platform/README.md b/packages/platform/README.md index c5269a49a0..7614f7e2b0 100644 --- a/packages/platform/README.md +++ b/packages/platform/README.md @@ -209,7 +209,7 @@ just by calling `HttpApiEndpoint.addError` multiple times. ### Multipart requests If you need to handle file uploads, you can use the `HttpApiSchema.Multipart` -api to flag a `HttpApiEnen` payload schema as a multipart request. +api to flag a `HttpApiEndpoint` payload schema as a multipart request. You can then use the schemas from the `Multipart` module to define the expected shape of the multipart request. From 11118f9cbe11418943920b802d3bb6f982257fa4 Mon Sep 17 00:00:00 2001 From: Tim Smart Date: Fri, 30 Aug 2024 12:00:05 +1200 Subject: [PATCH 59/59] add encoding helpers --- packages/platform-node/examples/api.ts | 13 ++++--------- packages/platform/src/HttpApiSchema.ts | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index f9d7b372fa..e754b46ccb 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -68,19 +68,14 @@ class UsersApi extends HttpApiGroup.make("users").pipe( ), HttpApiGroup.add( HttpApiEndpoint.get("csv", "/csv").pipe( - HttpApiEndpoint.setSuccess(Schema.String.pipe( - HttpApiSchema.withEncoding({ - kind: "Text", - contentType: "text/csv" - }) - )) + HttpApiEndpoint.setSuccess(HttpApiSchema.Text({ + contentType: "text/csv" + })) ) ), HttpApiGroup.add( HttpApiEndpoint.get("binary", "/binary").pipe( - HttpApiEndpoint.setSuccess(Schema.Uint8ArrayFromSelf.pipe( - HttpApiSchema.withEncoding({ kind: "Uint8Array" }) - )) + HttpApiEndpoint.setSuccess(HttpApiSchema.Uint8Array()) ) ), HttpApiGroup.add( diff --git a/packages/platform/src/HttpApiSchema.ts b/packages/platform/src/HttpApiSchema.ts index 2f7d14d1a6..96774b3656 100644 --- a/packages/platform/src/HttpApiSchema.ts +++ b/packages/platform/src/HttpApiSchema.ts @@ -366,3 +366,19 @@ export const withEncoding: { } : undefined) }) as any) + +/** + * @since 1.0.0 + * @category encoding + */ +export const Text = (options?: { + readonly contentType?: string +}): typeof Schema.String => withEncoding(Schema.String, { kind: "Text", ...options }) + +/** + * @since 1.0.0 + * @category encoding + */ +export const Uint8Array = (options?: { + readonly contentType?: string +}): typeof Schema.Uint8ArrayFromSelf => withEncoding(Schema.Uint8ArrayFromSelf, { kind: "Uint8Array", ...options })

    > => makeProto({ ...self as any, payloadSchema: Option.some(schema) @@ -568,7 +570,7 @@ export const setPayload: { */ export const setPath: { ( - schema: Path & ApiEndpoint.ValidatePath + schema: Path & HttpApiEndpoint.ValidatePath ): < Name extends string, Method extends HttpMethod, @@ -578,8 +580,8 @@ export const setPath: { _E, _R >( - self: ApiEndpoint - ) => ApiEndpoint, _P, _S, _E, _R | Schema.Schema.Context> + self: HttpApiEndpoint + ) => HttpApiEndpoint, _P, _S, _E, _R | Schema.Schema.Context> < Name extends string, Method extends HttpMethod, @@ -590,9 +592,9 @@ export const setPath: { _R, Path extends Schema.Schema.Any >( - self: ApiEndpoint, - schema: Path & ApiEndpoint.ValidatePath - ): ApiEndpoint, _P, _S, _E, _R | Schema.Schema.Context> + self: HttpApiEndpoint, + schema: Path & HttpApiEndpoint.ValidatePath + ): HttpApiEndpoint, _P, _S, _E, _R | Schema.Schema.Context> } = dual( 2, < @@ -605,9 +607,9 @@ export const setPath: { _R, Path extends Schema.Schema.Any >( - self: ApiEndpoint, - schema: Path & ApiEndpoint.ValidatePath - ): ApiEndpoint, _P, _S, _E, _R | Schema.Schema.Context> => + self: HttpApiEndpoint, + schema: Path & HttpApiEndpoint.ValidatePath + ): HttpApiEndpoint, _P, _S, _E, _R | Schema.Schema.Context> => makeProto({ ...self as any, pathSchema: Option.some(schema) @@ -621,9 +623,9 @@ export const setPath: { * @category request */ export const prefix: { - (prefix: HttpRouter.PathInput): (self: A) => A - (self: A, prefix: HttpRouter.PathInput): A -} = dual(2, (self: A, prefix: HttpRouter.PathInput): A => + (prefix: HttpRouter.PathInput): (self: A) => A + (self: A, prefix: HttpRouter.PathInput): A +} = dual(2, (self: A, prefix: HttpRouter.PathInput): A => makeProto({ ...self as any, path: HttpRouter.prefixPath(self.path, prefix) @@ -633,10 +635,10 @@ export const prefix: { * @since 1.0.0 * @category reflection */ -export const schemaSuccess = ( +export const schemaSuccess = ( self: A -): Option.Option, unknown, ApiEndpoint.Context>> => - ApiSchema.isVoid(self.successSchema.ast) ? Option.none() : Option.some(self.successSchema as any) +): Option.Option, unknown, HttpApiEndpoint.Context>> => + HttpApiSchema.isVoid(self.successSchema.ast) ? Option.none() : Option.some(self.successSchema as any) /** * Merge the annotations of the endpoint with the provided context. @@ -645,11 +647,11 @@ export const schemaSuccess = ( * @category annotations */ export const annotateMerge: { - (context: Context.Context): (self: A) => A - (self: A, context: Context.Context): A + (context: Context.Context): (self: A) => A + (self: A, context: Context.Context): A } = dual( 2, - (self: A, context: Context.Context): A => + (self: A, context: Context.Context): A => makeProto({ ...self as any, annotations: Context.merge(self.annotations, context) @@ -663,11 +665,11 @@ export const annotateMerge: { * @category annotations */ export const annotate: { - (tag: Context.Tag, value: S): (self: A) => A - (self: A, tag: Context.Tag, value: S): A + (tag: Context.Tag, value: S): (self: A) => A + (self: A, tag: Context.Tag, value: S): A } = dual( 3, - (self: A, tag: Context.Tag, value: S): A => + (self: A, tag: Context.Tag, value: S): A => makeProto({ ...self as any, annotations: Context.add(self.annotations, tag, value) diff --git a/packages/platform/src/ApiError.ts b/packages/platform/src/HttpApiError.ts similarity index 80% rename from packages/platform/src/ApiError.ts rename to packages/platform/src/HttpApiError.ts index 6aa7562a09..40b552e3a5 100644 --- a/packages/platform/src/ApiError.ts +++ b/packages/platform/src/HttpApiError.ts @@ -6,13 +6,13 @@ import type * as ParseResult from "@effect/schema/ParseResult" import * as Schema from "@effect/schema/Schema" import * as TreeFormatter from "@effect/schema/TreeFormatter" import * as Effect from "effect/Effect" -import * as ApiSchema from "./ApiSchema.js" +import * as HttpApiSchema from "./HttpApiSchema.js" /** * @since 1.0.0 * @category type ids */ -export const TypeId: unique symbol = Symbol.for("@effect/platform/ApiError") +export const TypeId: unique symbol = Symbol.for("@effect/platform/HttpApiError") /** * @since 1.0.0 @@ -59,13 +59,13 @@ export const Issue: Issue = Schema.Struct({ * @since 1.0.0 * @category errors */ -export class ApiDecodeError extends Schema.TaggedError()( - "ApiDecodeError", +export class HttpApiDecodeError extends Schema.TaggedError()( + "HttpApiDecodeError", { issues: Schema.Array(Issue), message: Schema.String }, - ApiSchema.annotations({ + HttpApiSchema.annotations({ status: 400, description: "ApiDecodeError: The request did not match the expected schema" }) @@ -73,16 +73,16 @@ export class ApiDecodeError extends Schema.TaggedError()( /** * @since 1.0.0 */ - static fromParseError(error: ParseResult.ParseError): Effect.Effect { + static fromParseError(error: ParseResult.ParseError): Effect.Effect { return ArrayFormatter.formatError(error).pipe( Effect.zip(TreeFormatter.formatError(error)), - Effect.map(([issues, message]) => new ApiDecodeError({ issues, message })) + Effect.map(([issues, message]) => new HttpApiDecodeError({ issues, message })) ) } /** * @since 1.0.0 */ - static refailParseError(error: ParseResult.ParseError): Effect.Effect { - return Effect.flatMap(ApiDecodeError.fromParseError(error), Effect.fail) + static refailParseError(error: ParseResult.ParseError): Effect.Effect { + return Effect.flatMap(HttpApiDecodeError.fromParseError(error), Effect.fail) } } diff --git a/packages/platform/src/HttpApiGroup.ts b/packages/platform/src/HttpApiGroup.ts new file mode 100644 index 0000000000..91986af46a --- /dev/null +++ b/packages/platform/src/HttpApiGroup.ts @@ -0,0 +1,348 @@ +/** + * @since 1.0.0 + */ +import * as Schema from "@effect/schema/Schema" +import * as Chunk from "effect/Chunk" +import * as Context from "effect/Context" +import { dual } from "effect/Function" +import { type Pipeable, pipeArguments } from "effect/Pipeable" +import * as Predicate from "effect/Predicate" +import * as HttpApiEndpoint from "./HttpApiEndpoint.js" +import type { HttpApiDecodeError } from "./HttpApiError.js" +import * as HttpApiSchema from "./HttpApiSchema.js" +import type { PathInput } from "./HttpRouter.js" + +/** + * @since 1.0.0 + * @category type ids + */ +export const TypeId: unique symbol = Symbol.for("@effect/platform/HttpApiGroup") + +/** + * @since 1.0.0 + * @category type ids + */ +export type TypeId = typeof TypeId + +/** + * @since 1.0.0 + * @category guards + */ +export const isHttpApiGroup = (u: unknown): u is HttpApiGroup.Any => Predicate.hasProperty(u, TypeId) + +/** + * An `HttpApiGroup` is a collection of `HttpApiEndpoint`s. You can use an `HttpApiGroup` to + * represent a portion of your domain. + * + * The endpoints can be implemented later using the `HttpApiBuilder.group` api. + * + * @since 1.0.0 + * @category models + */ +export interface HttpApiGroup< + out Name extends string, + out Endpoints extends HttpApiEndpoint.HttpApiEndpoint.All = never, + in out Error = HttpApiDecodeError, + out ErrorR = never +> extends Pipeable { + readonly [TypeId]: TypeId + readonly name: Name + readonly endpoints: Chunk.Chunk + readonly errorSchema: Schema.Schema + readonly annotations: Context.Context +} + +/** + * @since 1.0.0 + * @category models + */ +export declare namespace HttpApiGroup { + /** + * @since 1.0.0 + * @category models + */ + export type Any = + | HttpApiGroup + | HttpApiGroup + | HttpApiGroup + + /** + * @since 1.0.0 + * @category models + */ + export interface Service { + readonly _: unique symbol + readonly name: Name + } + + /** + * @since 1.0.0 + * @category models + */ + export type ToService = Group extends HttpApiGroup + ? Service + : never + + /** + * @since 1.0.0 + * @category models + */ + export type WithName = Extract + + /** + * @since 1.0.0 + * @category models + */ + export type Endpoints = Group extends HttpApiGroup + ? _Endpoints + : never + + /** + * @since 1.0.0 + * @category models + */ + export type EndpointsWithName = Endpoints> + + /** + * @since 1.0.0 + * @category models + */ + export type Error = Group extends HttpApiGroup ? + _Error + : never + + /** + * @since 1.0.0 + * @category models + */ + export type ErrorWithName = Error> + + /** + * @since 1.0.0 + * @category models + */ + export type Context = Group extends HttpApiGroup + ? _ErrorR | HttpApiEndpoint.HttpApiEndpoint.Context<_Endpoints> + : never + + /** + * @since 1.0.0 + * @category models + */ + export type ContextWithName = Context> +} + +const Proto = { + [TypeId]: TypeId, + pipe() { + return pipeArguments(this, arguments) + } +} + +const makeProto = (options: { + readonly name: Name + readonly endpoints: Chunk.Chunk + readonly errorSchema: Schema.Schema + readonly annotations: Context.Context +}): HttpApiGroup => Object.assign(Object.create(Proto), options) + +/** + * An `HttpApiGroup` is a collection of `HttpApiEndpoint`s. You can use an `HttpApiGroup` to + * represent a portion of your domain. + * + * The endpoints can be implemented later using the `HttpApiBuilder.group` api. + * + * @since 1.0.0 + * @category constructors + */ +export const make = (name: Name): HttpApiGroup => + makeProto({ + name, + endpoints: Chunk.empty(), + errorSchema: Schema.Never as any, + annotations: Context.empty() + }) + +/** + * Add an `HttpApiEndpoint` to an `HttpApiGroup`. + * + * @since 1.0.0 + * @category endpoints + */ +export const add: { + ( + endpoint: A + ): ( + self: HttpApiGroup + ) => HttpApiGroup + < + Name extends string, + Endpoints extends HttpApiEndpoint.HttpApiEndpoint.All, + Error, + ErrorR, + A extends HttpApiEndpoint.HttpApiEndpoint.All + >( + self: HttpApiGroup, + endpoint: A + ): HttpApiGroup +} = dual(2, < + Name extends string, + Endpoints extends HttpApiEndpoint.HttpApiEndpoint.All, + Error, + ErrorR, + A extends HttpApiEndpoint.HttpApiEndpoint.All +>( + self: HttpApiGroup, + endpoint: A +): HttpApiGroup => + makeProto({ + ...self, + endpoints: Chunk.append(self.endpoints, endpoint) + })) + +/** + * Add an error schema to an `HttpApiGroup`, which is shared by all endpoints in the + * group. + * + * @since 1.0.0 + * @category errors + */ +export const addError: { + ( + schema: Schema.Schema, + annotations?: { + readonly status?: number | undefined + } + ): ( + self: HttpApiGroup + ) => HttpApiGroup + ( + self: HttpApiGroup, + schema: Schema.Schema, + annotations?: { + readonly status?: number | undefined + } + ): HttpApiGroup +} = dual( + (args) => isHttpApiGroup(args[0]), + ( + self: HttpApiGroup, + schema: Schema.Schema, + annotations?: { + readonly status?: number | undefined + } + ): HttpApiGroup => + makeProto({ + ...self, + errorSchema: HttpApiSchema.UnionUnify( + self.errorSchema, + schema.annotations(HttpApiSchema.annotations({ + status: annotations?.status ?? HttpApiSchema.getStatusError(schema) + })) + ) + }) +) + +/** + * Add a path prefix to all endpoints in an `HttpApiGroup`. Note that this will only + * add the prefix to the endpoints before this api is called. + * + * @since 1.0.0 + * @category endpoints + */ +export const prefix: { + ( + prefix: PathInput + ): ( + self: HttpApiGroup + ) => HttpApiGroup + ( + self: HttpApiGroup, + prefix: PathInput + ): HttpApiGroup +} = dual(2, ( + self: HttpApiGroup, + prefix: PathInput +): HttpApiGroup => + makeProto({ + ...self, + endpoints: Chunk.map(self.endpoints, HttpApiEndpoint.prefix(prefix)) + })) + +/** + * Merge the annotations of an `HttpApiGroup` with a new context. + * + * @since 1.0.0 + * @category annotations + */ +export const annotateMerge: { + (context: Context.Context): (self: A) => A + (self: A, context: Context.Context): A +} = dual( + 2, + (self: A, context: Context.Context): A => + makeProto({ + ...self as any, + annotations: Context.merge(self.annotations, context) + }) as A +) + +/** + * Add an annotation to an `HttpApiGroup`. + * + * @since 1.0.0 + * @category annotations + */ +export const annotate: { + (tag: Context.Tag, value: S): (self: A) => A + (self: A, tag: Context.Tag, value: S): A +} = dual( + 3, + (self: A, tag: Context.Tag, value: S): A => + makeProto({ + ...self as any, + annotations: Context.add(self.annotations, tag, value) + }) as A +) + +/** + * For each endpoint in an `HttpApiGroup`, update the annotations with a new + * context. + * + * Note that this will only update the annotations before this api is called. + * + * @since 1.0.0 + * @category annotations + */ +export const annotateEndpointsMerge: { + (context: Context.Context): (self: A) => A + (self: A, context: Context.Context): A +} = dual( + 2, + (self: A, context: Context.Context): A => + makeProto({ + ...self as any, + endpoints: Chunk.map(self.endpoints, HttpApiEndpoint.annotateMerge(context)) + }) as A +) + +/** + * For each endpoint in an `HttpApiGroup`, add an annotation. + * + * Note that this will only add the annotation to the endpoints before this api + * is called. + * + * @since 1.0.0 + * @category annotations + */ +export const annotateEndpoints: { + (tag: Context.Tag, value: S): (self: A) => A + (self: A, tag: Context.Tag, value: S): A +} = dual( + 3, + (self: A, tag: Context.Tag, value: S): A => + makeProto({ + ...self as any, + endpoints: Chunk.map(self.endpoints, HttpApiEndpoint.annotate(tag, value)) + }) as A +) diff --git a/packages/platform/src/ApiSchema.ts b/packages/platform/src/HttpApiSchema.ts similarity index 96% rename from packages/platform/src/ApiSchema.ts rename to packages/platform/src/HttpApiSchema.ts index 5214f51208..4e35f037a5 100644 --- a/packages/platform/src/ApiSchema.ts +++ b/packages/platform/src/HttpApiSchema.ts @@ -13,21 +13,21 @@ import * as Struct from "effect/Struct" * @category annotations */ export const AnnotationMultipart: unique symbol = Symbol.for( - "@effect/platform/ApiSchema/AnnotationMultipart" + "@effect/platform/HttpApiSchema/AnnotationMultipart" ) /** * @since 1.0.0 * @category annotations */ -export const AnnotationStatus: unique symbol = Symbol.for("@effect/platform/ApiSchema/AnnotationStatus") +export const AnnotationStatus: unique symbol = Symbol.for("@effect/platform/HttpApiSchema/AnnotationStatus") /** * @since 1.0.0 * @category annotations */ export const AnnotationEmptyDecodeable: unique symbol = Symbol.for( - "@effect/platform/ApiSchema/AnnotationEmptyDecodeable" + "@effect/platform/HttpApiSchema/AnnotationEmptyDecodeable" ) /** @@ -255,7 +255,7 @@ export const NoContent: NoContent = Empty(204) as any * @since 1.0.0 * @category multipart */ -export const MultipartTypeId: unique symbol = Symbol.for("@effect/platform/ApiSchema/Multipart") +export const MultipartTypeId: unique symbol = Symbol.for("@effect/platform/HttpApiSchema/Multipart") /** * @since 1.0.0 diff --git a/packages/platform/src/ApiSecurity.ts b/packages/platform/src/HttpApiSecurity.ts similarity index 73% rename from packages/platform/src/ApiSecurity.ts rename to packages/platform/src/HttpApiSecurity.ts index 19776be607..31578289b7 100644 --- a/packages/platform/src/ApiSecurity.ts +++ b/packages/platform/src/HttpApiSecurity.ts @@ -11,7 +11,7 @@ import type { Covariant } from "effect/Types" * @since 1.0.0 * @category type ids */ -export const TypeId: unique symbol = Symbol.for("@effect/platform/ApiSecurity") +export const TypeId: unique symbol = Symbol.for("@effect/platform/HttpApiSecurity") /** * @since 1.0.0 @@ -23,13 +23,13 @@ export type TypeId = typeof TypeId * @since 1.0.0 * @category models */ -export type ApiSecurity = Bearer | ApiKey | Basic +export type HttpApiSecurity = Bearer | ApiKey | Basic /** * @since 1.0.0 * @category models */ -export declare namespace ApiSecurity { +export declare namespace HttpApiSecurity { /** * @since 1.0.0 * @category models @@ -45,14 +45,14 @@ export declare namespace ApiSecurity { * @since 1.0.0 * @category models */ - export type Type = A extends Proto ? Out : never + export type Type = A extends Proto ? Out : never } /** * @since 1.0.0 * @category models */ -export interface Bearer extends ApiSecurity.Proto { +export interface Bearer extends HttpApiSecurity.Proto { readonly _tag: "Bearer" } @@ -60,7 +60,7 @@ export interface Bearer extends ApiSecurity.Proto { * @since 1.0.0 * @category models */ -export interface ApiKey extends ApiSecurity.Proto { +export interface ApiKey extends HttpApiSecurity.Proto { readonly _tag: "ApiKey" readonly in: "header" | "query" | "cookie" readonly key: string @@ -70,7 +70,7 @@ export interface ApiKey extends ApiSecurity.Proto { * @since 1.0.0 * @category models */ -export interface Basic extends ApiSecurity.Proto { +export interface Basic extends HttpApiSecurity.Proto { readonly _tag: "Basic" } @@ -94,7 +94,7 @@ const Proto = { * Create an Bearer token security scheme. * * You can implement some api middleware for this security scheme using - * `ApiBuilder.middlewareSecurity`. + * `HttpApiBuilder.middlewareSecurity`. * * @since 1.0.0 * @category constructors @@ -108,10 +108,10 @@ export const bearer: Bearer = Object.assign(Object.create(Proto), { * Create an API key security scheme. * * You can implement some api middleware for this security scheme using - * `ApiBuilder.middlewareSecurity`. + * `HttpApiBuilder.middlewareSecurity`. * * To set the correct cookie in a handler, you can use - * `ApiBuilder.securitySetCookie`. + * `HttpApiBuilder.securitySetCookie`. * * @since 1.0.0 * @category constructors @@ -141,11 +141,11 @@ export const basic: Basic = Object.assign(Object.create(Proto), { * @category annotations */ export const annotateMerge: { - (context: Context.Context): (self: A) => A - (self: A, context: Context.Context): A + (context: Context.Context): (self: A) => A + (self: A, context: Context.Context): A } = dual( 2, - (self: A, context: Context.Context): A => + (self: A, context: Context.Context): A => Object.assign(Object.create(Proto), { ...self, annotations: Context.merge(self.annotations, context) @@ -157,11 +157,11 @@ export const annotateMerge: { * @category annotations */ export const annotate: { - (tag: Context.Tag, value: S): (self: A) => A - (self: A, tag: Context.Tag, value: S): A + (tag: Context.Tag, value: S): (self: A) => A + (self: A, tag: Context.Tag, value: S): A } = dual( 3, - (self: A, tag: Context.Tag, value: S): A => + (self: A, tag: Context.Tag, value: S): A => Object.assign(Object.create(Proto), { ...self, annotations: Context.add(self.annotations, tag, value) diff --git a/packages/platform/src/ApiSwagger.ts b/packages/platform/src/HttpApiSwagger.ts similarity index 85% rename from packages/platform/src/ApiSwagger.ts rename to packages/platform/src/HttpApiSwagger.ts index aced42ee85..67f4eeb80a 100644 --- a/packages/platform/src/ApiSwagger.ts +++ b/packages/platform/src/HttpApiSwagger.ts @@ -3,8 +3,8 @@ */ import * as Effect from "effect/Effect" import type { Layer } from "effect/Layer" -import { Api } from "./Api.js" -import { ApiRouter } from "./ApiBuilder.js" +import { HttpApi } from "./HttpApi.js" +import { Router } from "./HttpApiBuilder.js" import * as HttpServerResponse from "./HttpServerResponse.js" import * as internal from "./internal/apiSwagger.js" import * as OpenApi from "./OpenApi.js" @@ -15,10 +15,10 @@ import * as OpenApi from "./OpenApi.js" */ export const layer = (options?: { readonly path?: `/${string}` | undefined -}): Layer => - ApiRouter.use((router) => +}): Layer => + Router.use((router) => Effect.gen(function*() { - const api = yield* Api + const api = yield* HttpApi const spec = OpenApi.fromApi(api) const response = HttpServerResponse.html(` diff --git a/packages/platform/src/OpenApi.ts b/packages/platform/src/OpenApi.ts index a8501ff631..b8e009cc7a 100644 --- a/packages/platform/src/OpenApi.ts +++ b/packages/platform/src/OpenApi.ts @@ -9,9 +9,9 @@ import { dual } from "effect/Function" import * as Option from "effect/Option" import type { ReadonlyRecord } from "effect/Record" import type { DeepMutable, Mutable } from "effect/Types" -import * as Api from "./Api.js" -import * as ApiSchema from "./ApiSchema.js" -import type { ApiSecurity } from "./ApiSecurity.js" +import * as HttpApi from "./HttpApi.js" +import * as HttpApiSchema from "./HttpApiSchema.js" +import type { HttpApiSecurity } from "./HttpApiSecurity.js" import * as HttpMethod from "./HttpMethod.js" /** @@ -48,7 +48,7 @@ export class License extends Context.Tag("@effect/platform/OpenApi/License")() {} +export class Security extends Context.Tag("@effect/platform/OpenApi/Security")() {} /** * @since 1.0.0 @@ -68,7 +68,7 @@ export const annotations = (annotations: { readonly description?: string | undefined readonly version?: string | undefined readonly license?: OpenAPISpecLicense | undefined - readonly security?: ApiSecurity | undefined + readonly security?: HttpApiSecurity | undefined readonly externalDocs?: OpenAPISpecExternalDocs | undefined }): Context.Context => { let context = Context.empty() @@ -115,7 +115,7 @@ export const annotate: { readonly description?: string | undefined readonly version?: string | undefined readonly license?: OpenAPISpecLicense | undefined - readonly security?: ApiSecurity | undefined + readonly security?: HttpApiSecurity | undefined readonly externalDocs?: OpenAPISpecExternalDocs | undefined }): (self: A) => A (self: A, annotations: { @@ -124,7 +124,7 @@ export const annotate: { readonly description?: string | undefined readonly version?: string | undefined readonly license?: OpenAPISpecLicense | undefined - readonly security?: ApiSecurity | undefined + readonly security?: HttpApiSecurity | undefined readonly externalDocs?: OpenAPISpecExternalDocs | undefined }): A } = dual(2, (self: A, annotations_: { @@ -133,7 +133,7 @@ export const annotate: { readonly description?: string | undefined readonly version?: string | undefined readonly license?: OpenAPISpecLicense | undefined - readonly security?: ApiSecurity | undefined + readonly security?: HttpApiSecurity | undefined readonly externalDocs?: OpenAPISpecExternalDocs | undefined }): A => { const context = Context.merge( @@ -149,7 +149,7 @@ export const annotate: { * @category constructors * @since 1.0.0 */ -export const fromApi = (api: A): OpenAPISpec => { +export const fromApi = (api: A): OpenAPISpec => { const spec: DeepMutable = { openapi: "3.0.3", info: { @@ -164,9 +164,9 @@ export const fromApi = (api: A): OpenAPISpec => { }, security: [] } - const securityMap = new Map() + const securityMap = new Map() let securityCount = 0 - function registerSecurity(security: ApiSecurity): string { + function registerSecurity(security: HttpApiSecurity): string { if (securityMap.has(security)) { return securityMap.get(security)! } @@ -188,7 +188,7 @@ export const fromApi = (api: A): OpenAPISpec => { [registerSecurity(apiSecurity)]: [] }) }) - Api.reflect(api as any, { + HttpApi.reflect(api as any, { onGroup({ group }) { const tag: Mutable = { name: Context.getOrElse(group.annotations, Title, () => group.name) @@ -231,7 +231,7 @@ export const fromApi = (api: A): OpenAPISpec => { Option.map((schema) => { op.requestBody = { content: { - [ApiSchema.getMultipart(schema.ast) ? "multipart/form-data" : "application/json"]: { + [HttpApiSchema.getMultipart(schema.ast) ? "multipart/form-data" : "application/json"]: { schema: makeJsonSchema(schema) } }, @@ -264,7 +264,7 @@ export const fromApi = (api: A): OpenAPISpec => { description: Option.getOrElse(getDescriptionOrIdentifier(ast), () => "Error") } ast.pipe( - Option.filter((ast) => !ApiSchema.getEmptyDecodeable(ast)), + Option.filter((ast) => !HttpApiSchema.getEmptyDecodeable(ast)), Option.map((ast) => { op.responses![status].content = { "application/json": { @@ -295,7 +295,7 @@ const getPropertySignatures = (ast: AST.AST): ReadonlyArray { +const makeSecurityScheme = (security: HttpApiSecurity): OpenAPISecurityScheme => { const meta: Mutable> = {} Option.map(Context.getOption(security.annotations, Description), (description) => { meta.description = description diff --git a/packages/platform/src/index.ts b/packages/platform/src/index.ts index f6b1b7e9e5..7764a015ed 100644 --- a/packages/platform/src/index.ts +++ b/packages/platform/src/index.ts @@ -1,87 +1,87 @@ /** * @since 1.0.0 */ -export * as Api from "./Api.js" +export * as Command from "./Command.js" /** * @since 1.0.0 */ -export * as ApiBuilder from "./ApiBuilder.js" +export * as CommandExecutor from "./CommandExecutor.js" /** * @since 1.0.0 */ -export * as ApiClient from "./ApiClient.js" +export * as Cookies from "./Cookies.js" /** * @since 1.0.0 */ -export * as ApiEndpoint from "./ApiEndpoint.js" +export * as Effectify from "./Effectify.js" /** * @since 1.0.0 */ -export * as ApiError from "./ApiError.js" +export * as Error from "./Error.js" /** * @since 1.0.0 */ -export * as ApiGroup from "./ApiGroup.js" +export * as Etag from "./Etag.js" /** * @since 1.0.0 */ -export * as ApiSchema from "./ApiSchema.js" +export * as FileSystem from "./FileSystem.js" /** * @since 1.0.0 */ -export * as ApiSecurity from "./ApiSecurity.js" +export * as Headers from "./Headers.js" /** * @since 1.0.0 */ -export * as ApiSwagger from "./ApiSwagger.js" +export * as HttpApi from "./HttpApi.js" /** * @since 1.0.0 */ -export * as Command from "./Command.js" +export * as HttpApiBuilder from "./HttpApiBuilder.js" /** * @since 1.0.0 */ -export * as CommandExecutor from "./CommandExecutor.js" +export * as HttpApiClient from "./HttpApiClient.js" /** * @since 1.0.0 */ -export * as Cookies from "./Cookies.js" +export * as HttpApiEndpoint from "./HttpApiEndpoint.js" /** * @since 1.0.0 */ -export * as Effectify from "./Effectify.js" +export * as HttpApiError from "./HttpApiError.js" /** * @since 1.0.0 */ -export * as Error from "./Error.js" +export * as HttpApiGroup from "./HttpApiGroup.js" /** * @since 1.0.0 */ -export * as Etag from "./Etag.js" +export * as HttpApiSchema from "./HttpApiSchema.js" /** * @since 1.0.0 */ -export * as FileSystem from "./FileSystem.js" +export * as HttpApiSecurity from "./HttpApiSecurity.js" /** * @since 1.0.0 */ -export * as Headers from "./Headers.js" +export * as HttpApiSwagger from "./HttpApiSwagger.js" /** * @since 1.0.0 From 0df127eea453ccc03a098a55cc1b0e4eba21871a Mon Sep 17 00:00:00 2001 From: Tim Date: Tue, 27 Aug 2024 20:46:02 +1200 Subject: [PATCH 50/59] fix docgen --- packages/platform/src/HttpApiBuilder.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/platform/src/HttpApiBuilder.ts b/packages/platform/src/HttpApiBuilder.ts index ee36da8213..0f85901058 100644 --- a/packages/platform/src/HttpApiBuilder.ts +++ b/packages/platform/src/HttpApiBuilder.ts @@ -645,7 +645,7 @@ export const securitySetCookie = ( * @since 1.0.0 * @category middleware * @example - * import { ApiBuilder, ApiSecurity } from "@effect/platform" + * import { HttpApiBuilder, HttpApiSecurity } from "@effect/platform" * import { Schema } from "@effect/schema" * import { Context, Effect, Redacted } from "effect" * @@ -661,8 +661,8 @@ export const securitySetCookie = ( * * const securityMiddleware = Effect.gen(function*() { * const accounts = yield* Accounts - * return ApiBuilder.middlewareSecurity( - * ApiSecurity.bearer, + * return HttpApiBuilder.middlewareSecurity( + * HttpApiSecurity.bearer, * CurrentUser, * (token) => accounts.findUserByAccessToken(Redacted.value(token)) * ) From 1092acc2c2305ce9b0431c1178570366f01cb619 Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 28 Aug 2024 12:01:10 +1200 Subject: [PATCH 51/59] make HttpApi & HttpApiGroup class extendable --- packages/platform-node/examples/api.ts | 16 +++++------ packages/platform/src/HttpApi.ts | 36 ++++++++++++++----------- packages/platform/src/HttpApiBuilder.ts | 6 ++--- packages/platform/src/HttpApiClient.ts | 12 ++++----- packages/platform/src/HttpApiGroup.ts | 17 +++++++----- packages/platform/src/OpenApi.ts | 20 +++++++------- 6 files changed, 60 insertions(+), 47 deletions(-) diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index cae0f46559..8d94b913f1 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -36,7 +36,7 @@ const securityMiddleware = HttpApiBuilder.middlewareSecurity( (token) => Effect.succeed(new User({ id: 1000, name: `Authenticated with ${Redacted.value(token)}` })) ) -const users = HttpApiGroup.make("users").pipe( +class UsersApi extends HttpApiGroup.make("users").pipe( HttpApiGroup.add( HttpApiEndpoint.get("findById", "/:id").pipe( HttpApiEndpoint.setPath(Schema.Struct({ @@ -64,17 +64,17 @@ const users = HttpApiGroup.make("users").pipe( HttpApiGroup.addError(Unauthorized), HttpApiGroup.prefix("/users"), OpenApi.annotate({ security }) -) +) {} -const api = HttpApi.empty.pipe( - HttpApi.addGroup(users), +class MyApi extends HttpApi.empty.pipe( + HttpApi.addGroup(UsersApi), OpenApi.annotate({ title: "Users API", description: "API for managing users" }) -) +) {} -const UsersLive = HttpApiBuilder.group(api, "users", (handlers) => +const UsersLive = HttpApiBuilder.group(MyApi, "users", (handlers) => handlers.pipe( HttpApiBuilder.handle("create", (_) => Effect.succeed(new User({ ..._.payload, id: 123 }))), HttpApiBuilder.handle("findById", (_) => @@ -95,7 +95,7 @@ const UsersLive = HttpApiBuilder.group(api, "users", (handlers) => securityMiddleware )) -const ApiLive = HttpApiBuilder.api(api).pipe( +const ApiLive = HttpApiBuilder.api(MyApi).pipe( Layer.provide(UsersLive) ) @@ -111,7 +111,7 @@ HttpApiBuilder.serve(HttpMiddleware.logger).pipe( Effect.gen(function*() { yield* Effect.sleep(2000) - const client = yield* HttpApiClient.make(api, { + const client = yield* HttpApiClient.make(MyApi, { baseUrl: "http://localhost:3000" }) diff --git a/packages/platform/src/HttpApi.ts b/packages/platform/src/HttpApi.ts index 1beef41f9c..b5f14cb69e 100644 --- a/packages/platform/src/HttpApi.ts +++ b/packages/platform/src/HttpApi.ts @@ -47,6 +47,7 @@ export interface HttpApi< in out Error = never, out ErrorR = never > extends Pipeable { + new(_: never): {} readonly [TypeId]: TypeId readonly groups: Chunk.Chunk readonly errorSchema: Schema.Schema @@ -78,7 +79,13 @@ export declare namespace HttpApi { * @since 1.0.0 * @category models */ - export type Any = HttpApi | HttpApi | HttpApi + export interface Any extends Pipeable { + new(_: never): {} + readonly [TypeId]: TypeId + readonly groups: Chunk.Chunk + readonly errorSchema: Schema.Schema.All + readonly annotations: Context.Context + } /** * @since 1.0.0 @@ -100,7 +107,11 @@ const makeProto = ( readonly groups: Chunk.Chunk readonly errorSchema: Schema.Schema readonly annotations: Context.Context -}): HttpApi => Object.assign(Object.create(Proto), options) +}): HttpApi => { + function HttpApi() {} + Object.setPrototypeOf(HttpApi, Proto) + return Object.assign(HttpApi, options) as any +} /** * An empty `HttpApi`. You can use this to start building your `HttpApi`. @@ -253,7 +264,8 @@ export const reflect = readonly endpoint: HttpApiEndpoint.HttpApiEndpoint readonly mergedAnnotations: Context.Context - readonly success: readonly [ast: Option.Option, status: number] + readonly successAST: Option.Option + readonly successStatus: number readonly errors: ReadonlyMap> }) => void } @@ -269,22 +281,16 @@ export const reflect = > - for (const endpoint of endpoints) { - const errors = extractErrors(endpoint.errorSchema.ast, groupErrors) - const annotations = Context.merge(groupAnnotations, endpoint.annotations) - const success = [ - HttpApiEndpoint.schemaSuccess(endpoint).pipe( - Option.map((schema) => schema.ast) - ), - HttpApiSchema.getStatusSuccess(endpoint.successSchema) - ] as const options.onEndpoint({ group, endpoint, - mergedAnnotations: annotations, - success, - errors + mergedAnnotations: Context.merge(groupAnnotations, endpoint.annotations), + successAST: HttpApiEndpoint.schemaSuccess(endpoint).pipe( + Option.map((schema) => schema.ast) + ), + successStatus: HttpApiSchema.getStatusSuccess(endpoint.successSchema), + errors: extractErrors(endpoint.errorSchema.ast, groupErrors) }) } } diff --git a/packages/platform/src/HttpApiBuilder.ts b/packages/platform/src/HttpApiBuilder.ts index 0f85901058..77929a5b9f 100644 --- a/packages/platform/src/HttpApiBuilder.ts +++ b/packages/platform/src/HttpApiBuilder.ts @@ -213,7 +213,7 @@ export const group = < Groups extends HttpApiGroup.HttpApiGroup.Any, ApiError, ApiErrorR, - const Name extends Groups["name"], + const Name extends Groups["identifier"], RH, EX = never, RX = never @@ -233,7 +233,7 @@ export const group = < Router.use((router) => Effect.gen(function*() { const context = yield* Effect.context() - const group = Chunk.findFirst(api.groups, (group) => group.name === groupName) + const group = Chunk.findFirst(api.groups, (group) => group.identifier === groupName) if (group._tag === "None") { throw new Error(`Group "${groupName}" not found in API`) } @@ -304,7 +304,7 @@ export const handle: { > => { const o = Chunk.findFirst(self.group.endpoints, (endpoint) => endpoint.name === name) if (o._tag === "None") { - throw new Error(`Endpoint "${name}" not found in group "${self.group.name}"`) + throw new Error(`Endpoint "${name}" not found in group "${self.group.identifier}"`) } const endpoint = o.value return makeHandlers({ diff --git a/packages/platform/src/HttpApiClient.ts b/packages/platform/src/HttpApiClient.ts index 2df911e3b3..01a037a1d1 100644 --- a/packages/platform/src/HttpApiClient.ts +++ b/packages/platform/src/HttpApiClient.ts @@ -24,7 +24,7 @@ import * as HttpMethod from "./HttpMethod.js" */ export type Client = [A] extends [HttpApi.HttpApi] ? { - readonly [GroupName in _Groups["name"]]: [HttpApiGroup.WithName<_Groups, GroupName>] extends + readonly [GroupName in _Groups["identifier"]]: [HttpApiGroup.WithName<_Groups, GroupName>] extends [HttpApiGroup] ? { readonly [Name in _Endpoints["name"]]: [HttpApiEndpoint.WithName<_Endpoints, Name>] extends [ HttpApiEndpoint< @@ -68,11 +68,11 @@ export const make = ( const client: Record> = {} HttpApi.reflect(api as any, { onGroup({ group }) { - client[group.name] = {} + client[group.identifier] = {} }, - onEndpoint({ endpoint, errors, group, success }) { + onEndpoint({ endpoint, errors, group, successAST, successStatus }) { const makeUrl = compilePath(endpoint.path) - const handleSuccess = unify(Option.match(success[0], { + const handleSuccess = unify(Option.match(successAST, { onNone: () => HttpClientResponse.void, onSome: (ast) => HttpClientResponse.schemaBodyJsonScoped(Schema.make(ast)) })) @@ -132,7 +132,7 @@ export const make = ( Option.filter(() => !isMultipart), Option.map(Schema.encodeUnknown) ) - client[group.name][endpoint.name] = (request: { + client[group.identifier][endpoint.name] = (request: { readonly path: any readonly payload: any }) => { @@ -156,7 +156,7 @@ export const make = ( httpClient(request).pipe( Effect.orDie, Effect.flatMap((response) => - response.status !== success[1] ? handleError(request, response) : Effect.succeed(response) + response.status !== successStatus ? handleError(request, response) : Effect.succeed(response) ) ) ), diff --git a/packages/platform/src/HttpApiGroup.ts b/packages/platform/src/HttpApiGroup.ts index 91986af46a..e08b0751c5 100644 --- a/packages/platform/src/HttpApiGroup.ts +++ b/packages/platform/src/HttpApiGroup.ts @@ -45,8 +45,9 @@ export interface HttpApiGroup< in out Error = HttpApiDecodeError, out ErrorR = never > extends Pipeable { + new(_: never): {} readonly [TypeId]: TypeId - readonly name: Name + readonly identifier: Name readonly endpoints: Chunk.Chunk readonly errorSchema: Schema.Schema readonly annotations: Context.Context @@ -87,7 +88,7 @@ export declare namespace HttpApiGroup { * @since 1.0.0 * @category models */ - export type WithName = Extract + export type WithName = Extract /** * @since 1.0.0 @@ -140,11 +141,15 @@ const Proto = { } const makeProto = (options: { - readonly name: Name + readonly identifier: Name readonly endpoints: Chunk.Chunk readonly errorSchema: Schema.Schema readonly annotations: Context.Context -}): HttpApiGroup => Object.assign(Object.create(Proto), options) +}): HttpApiGroup => { + function HttpApiGroup() {} + Object.setPrototypeOf(HttpApiGroup, Proto) + return Object.assign(HttpApiGroup, options) as any +} /** * An `HttpApiGroup` is a collection of `HttpApiEndpoint`s. You can use an `HttpApiGroup` to @@ -155,9 +160,9 @@ const makeProto = (name: Name): HttpApiGroup => +export const make = (identifier: Name): HttpApiGroup => makeProto({ - name, + identifier, endpoints: Chunk.empty(), errorSchema: Schema.Never as any, annotations: Context.empty() diff --git a/packages/platform/src/OpenApi.ts b/packages/platform/src/OpenApi.ts index b8e009cc7a..162218bb5d 100644 --- a/packages/platform/src/OpenApi.ts +++ b/packages/platform/src/OpenApi.ts @@ -136,11 +136,13 @@ export const annotate: { readonly security?: HttpApiSecurity | undefined readonly externalDocs?: OpenAPISpecExternalDocs | undefined }): A => { + const base = typeof self === "function" ? function() {} : self + Object.setPrototypeOf(base, Object.getPrototypeOf(self)) const context = Context.merge( self.annotations, annotations(annotations_) ) - return Object.assign(Object.create(Object.getPrototypeOf(self)), self, { + return Object.assign(base, self, { annotations: context }) }) @@ -191,7 +193,7 @@ export const fromApi = (api: A): OpenAPISpec => { HttpApi.reflect(api as any, { onGroup({ group }) { const tag: Mutable = { - name: Context.getOrElse(group.annotations, Title, () => group.name) + name: Context.getOrElse(group.annotations, Title, () => group.identifier) } Option.map(Context.getOption(group.annotations, Description), (description) => { tag.description = description @@ -201,17 +203,17 @@ export const fromApi = (api: A): OpenAPISpec => { }) spec.tags!.push(tag) }, - onEndpoint({ endpoint, errors, group, mergedAnnotations, success }) { + onEndpoint({ endpoint, errors, group, mergedAnnotations, successAST, successStatus }) { const path = endpoint.path.replace(/:(\w+)[^/]*/g, "{$1}") const method = endpoint.method.toLowerCase() as OpenAPISpecMethodName const op: DeepMutable = { - tags: [Context.getOrElse(group.annotations, Title, () => group.name)], - operationId: Context.getOrElse(endpoint.annotations, Identifier, () => `${group.name}.${endpoint.name}`), + tags: [Context.getOrElse(group.annotations, Title, () => group.identifier)], + operationId: Context.getOrElse(endpoint.annotations, Identifier, () => `${group.identifier}.${endpoint.name}`), parameters: [], security: [], responses: { - [success[1]]: { - description: Option.getOrElse(getDescriptionOrIdentifier(success[0]), () => "Success") + [successStatus]: { + description: Option.getOrElse(getDescriptionOrIdentifier(successAST), () => "Success") } } } @@ -239,9 +241,9 @@ export const fromApi = (api: A): OpenAPISpec => { } }) ) - success[0].pipe( + successAST.pipe( Option.map((ast) => { - op.responses![success[1]].content = { + op.responses![successStatus].content = { "application/json": { schema: makeJsonSchema(Schema.make(ast)) } From 6ca395c9bc0330b7ce8877a366a3a8bae6283b16 Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 28 Aug 2024 12:54:21 +1200 Subject: [PATCH 52/59] add headers support --- packages/platform-node/examples/api.ts | 12 +- packages/platform/src/HttpApiBuilder.ts | 7 + packages/platform/src/HttpApiClient.ts | 15 +- packages/platform/src/HttpApiEndpoint.ts | 227 ++++++++++++++++++----- packages/platform/src/OpenApi.ts | 68 +++---- 5 files changed, 250 insertions(+), 79 deletions(-) diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index 8d94b913f1..fb9f77ea9b 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -43,6 +43,11 @@ class UsersApi extends HttpApiGroup.make("users").pipe( id: Schema.NumberFromString })), HttpApiEndpoint.setSuccess(User), + HttpApiEndpoint.setHeaders(Schema.Struct({ + page: Schema.NumberFromString.pipe( + Schema.optionalWith({ default: () => 1 }) + ) + })), HttpApiEndpoint.addError(Schema.String.pipe( HttpApiSchema.asEmpty({ status: 413, decode: () => "boom" }) )) @@ -88,7 +93,7 @@ const UsersLive = HttpApiBuilder.group(MyApi, "users", (handlers) => ), new User({ id: _.path.id, - name: "John" + name: `John Doe (${_.headers.page})` }) )), HttpApiBuilder.handle("me", (_) => CurrentUser), @@ -119,7 +124,10 @@ Effect.gen(function*() { data.append("name", "John") console.log("Multipart", yield* client.users.create({ payload: data })) - const user = yield* client.users.findById({ path: { id: 123 } }) + const user = yield* client.users.findById({ + path: { id: 123 }, + headers: { page: 10 } + }) console.log("json", user) }).pipe( Effect.provide(HttpClient.layer), diff --git a/packages/platform/src/HttpApiBuilder.ts b/packages/platform/src/HttpApiBuilder.ts index 77929a5b9f..6d6915d990 100644 --- a/packages/platform/src/HttpApiBuilder.ts +++ b/packages/platform/src/HttpApiBuilder.ts @@ -732,6 +732,7 @@ const handlerToRoute = ( Option.getOrElse(() => false) ) const decodePayload = Option.map(endpoint.payloadSchema, Schema.decodeUnknown) + const decodeHeaders = Option.map(endpoint.headersSchema, Schema.decodeUnknown) const encodeSuccess = Option.map(HttpApiEndpoint.schemaSuccess(endpoint), Schema.encodeUnknown) const successStatus = HttpApiSchema.getStatusSuccess(endpoint.successSchema) return HttpRouter.makeRoute( @@ -753,11 +754,17 @@ const handlerToRoute = ( Effect.flatMap((raw) => Effect.catchAll(decodePayload.value(raw), HttpApiDecodeError.refailParseError)) )) : identity, + decodeHeaders._tag === "Some" + ? Effect.bind("headers", (_) => Effect.orDie(decodeHeaders.value(request.headers))) + : identity, Effect.flatMap((input) => { const request: any = { path: input.pathParams } if ("payload" in input) { request.payload = input.payload } + if ("headers" in input) { + request.headers = input.headers + } return handler(request) }), isFullResponse ? diff --git a/packages/platform/src/HttpApiClient.ts b/packages/platform/src/HttpApiClient.ts index 01a037a1d1..ea0852a0bc 100644 --- a/packages/platform/src/HttpApiClient.ts +++ b/packages/platform/src/HttpApiClient.ts @@ -32,12 +32,13 @@ export type Client = [A] extends infer _Method, infer _Path, infer _Payload, + infer _Headers, infer _Success, infer _Error, infer _R > ] ? ( - request: Simplify> + request: Simplify> ) => Effect.Effect< _Success, _Error | _GroupError | _ApiError | HttpClientError.HttpClientError @@ -132,9 +133,13 @@ export const make = ( Option.filter(() => !isMultipart), Option.map(Schema.encodeUnknown) ) + const encodeHeaders = endpoint.headersSchema.pipe( + Option.map(Schema.encodeUnknown) + ) client[group.identifier][endpoint.name] = (request: { readonly path: any readonly payload: any + readonly headers: any }) => { const url = request && request.path ? makeUrl(request && request.path) : endpoint.path const baseRequest = HttpClientRequest.make(endpoint.method)(url) @@ -152,6 +157,14 @@ export const make = ( Effect.orDie ) : Effect.succeed(baseRequest)).pipe( + encodeHeaders._tag === "Some" + ? Effect.flatMap((httpRequest) => + encodeHeaders.value(request.headers).pipe( + Effect.orDie, + Effect.map((headers) => HttpClientRequest.setHeaders(httpRequest, headers as any)) + ) + ) + : identity, Effect.flatMap((request) => httpClient(request).pipe( Effect.orDie, diff --git a/packages/platform/src/HttpApiEndpoint.ts b/packages/platform/src/HttpApiEndpoint.ts index 0fe3cbcfc6..941168537e 100644 --- a/packages/platform/src/HttpApiEndpoint.ts +++ b/packages/platform/src/HttpApiEndpoint.ts @@ -46,6 +46,7 @@ export interface HttpApiEndpoint< out Method extends HttpMethod, in out Path = never, in out Payload = never, + in out Headers = never, in out Success = void, in out Error = never, out R = never @@ -56,6 +57,7 @@ export interface HttpApiEndpoint< readonly method: Method readonly pathSchema: Option.Option> readonly payloadSchema: Option.Option> + readonly headersSchema: Option.Option> readonly successSchema: Schema.Schema readonly errorSchema: Schema.Schema readonly annotations: Context.Context @@ -77,6 +79,7 @@ export declare namespace HttpApiEndpoint { readonly method: HttpMethod readonly pathSchema: Option.Option readonly payloadSchema: Option.Option + readonly headersSchema: Option.Option readonly successSchema: Schema.Schema.Any readonly errorSchema: Schema.Schema.Any readonly annotations: Context.Context @@ -93,6 +96,7 @@ export declare namespace HttpApiEndpoint { readonly method: HttpMethod readonly pathSchema: Option.Option readonly payloadSchema: Option.Option + readonly headersSchema: Option.Option readonly successSchema: Schema.Schema.Any readonly errorSchema: Schema.Schema.All readonly annotations: Context.Context @@ -102,52 +106,100 @@ export declare namespace HttpApiEndpoint { * @since 1.0.0 * @category models */ - export type Success = Endpoint extends - HttpApiEndpoint ? - _Success + export type Success = Endpoint extends HttpApiEndpoint< + infer _Name, + infer _Method, + infer _Path, + infer _Payload, + infer _Headers, + infer _Success, + infer _Error, + infer _R + > ? _Success : never /** * @since 1.0.0 * @category models */ - export type Error = Endpoint extends - HttpApiEndpoint ? - _Error + export type Error = Endpoint extends HttpApiEndpoint< + infer _Name, + infer _Method, + infer _Path, + infer _Payload, + infer _Headers, + infer _Success, + infer _Error, + infer _R + > ? _Error : never /** * @since 1.0.0 * @category models */ - export type PathParsed = Endpoint extends - HttpApiEndpoint ? - _Path + export type PathParsed = Endpoint extends HttpApiEndpoint< + infer _Name, + infer _Method, + infer _Path, + infer _Payload, + infer _Headers, + infer _Success, + infer _Error, + infer _R + > ? _Path : never /** * @since 1.0.0 * @category models */ - export type Payload = Endpoint extends - HttpApiEndpoint ? - _Payload + export type Payload = Endpoint extends HttpApiEndpoint< + infer _Name, + infer _Method, + infer _Path, + infer _Payload, + infer _Headers, + infer _Success, + infer _Error, + infer _R + > ? _Payload : never /** * @since 1.0.0 * @category models */ - export type Request = { - readonly path: PathParsed - } & ([Payload] extends [infer P] ? [P] extends [never] ? {} : { readonly payload: P } : {}) + export type Headers = Endpoint extends HttpApiEndpoint< + infer _Name, + infer _Method, + infer _Path, + infer _Payload, + infer _Headers, + infer _Success, + infer _Error, + infer _R + > ? _Headers + : never + + /** + * @since 1.0.0 + * @category models + */ + export type Request = + & { + readonly path: PathParsed + } + & ([Payload] extends [infer P] ? [P] extends [never] ? {} : { readonly payload: P } : {}) + & ([Headers] extends [infer H] ? [H] extends [never] ? {} : { readonly headers: H } : {}) /** * @since 1.0.0 * @category models */ - export type ClientRequest = ( + export type ClientRequest = ( & ([Path] extends [void] ? {} : { readonly path: Path }) + & ([Headers] extends [never] ? {} : { readonly headers: Headers }) & ([Payload] extends [never] ? {} : [Payload] extends [Brand] ? { readonly payload: FormData } : { readonly payload: Payload }) @@ -157,9 +209,16 @@ export declare namespace HttpApiEndpoint { * @since 1.0.0 * @category models */ - export type Context = Endpoint extends - HttpApiEndpoint ? - _R + export type Context = Endpoint extends HttpApiEndpoint< + infer _Name, + infer _Method, + infer _Path, + infer _Payload, + infer _Headers, + infer _Success, + infer _Error, + infer _R + > ? _R : never /** @@ -260,6 +319,15 @@ export declare namespace HttpApiEndpoint { : `Path schema must be encodeable to strings` : {} + /** + * @since 1.0.0 + * @category models + */ + export type ValidateHeaders = S extends Schema.Schema + ? [_I] extends [Readonly>] ? {} + : `Headers schema must be encodeable to strings` + : {} + /** * @since 1.0.0 * @category models @@ -285,6 +353,7 @@ const makeProto = < Method extends HttpMethod, Path, Payload, + Headers, Success, Error, R @@ -294,10 +363,12 @@ const makeProto = < readonly method: Method readonly pathSchema: Option.Option> readonly payloadSchema: Option.Option> + readonly headersSchema: Option.Option> readonly successSchema: Schema.Schema readonly errorSchema: Schema.Schema readonly annotations: Context.Context -}): HttpApiEndpoint => Object.assign(Object.create(Proto), options) +}): HttpApiEndpoint => + Object.assign(Object.create(Proto), options) /** * @since 1.0.0 @@ -314,6 +385,7 @@ export const make = (method: Method) => method, pathSchema: Option.none(), payloadSchema: Option.none(), + headersSchema: Option.none(), successSchema: HttpApiSchema.NoContent as any, errorSchema: Schema.Never as any, annotations: Context.empty() @@ -382,28 +454,30 @@ export const setSuccess: { Method extends HttpMethod, _Path, _P, + _H, _S, _E, _R >( - self: HttpApiEndpoint - ) => HttpApiEndpoint, _E, _R | Schema.Schema.Context> + self: HttpApiEndpoint + ) => HttpApiEndpoint, _E, _R | Schema.Schema.Context> < Name extends string, Method extends HttpMethod, _Path, _P, + _H, _S, _E, _R, S extends Schema.Schema.Any >( - self: HttpApiEndpoint, + self: HttpApiEndpoint, schema: S, annotations?: { readonly status?: number | undefined } - ): HttpApiEndpoint, _E, _R | Schema.Schema.Context> + ): HttpApiEndpoint, _E, _R | Schema.Schema.Context> } = dual( (args) => isHttpApiEndpoint(args[0]), < @@ -411,12 +485,13 @@ export const setSuccess: { Method extends HttpMethod, _Path, _P, + _H, _S, _E, _R, S extends Schema.Schema.Any >( - self: HttpApiEndpoint, + self: HttpApiEndpoint, schema: S, annotations?: { readonly status?: number | undefined @@ -448,28 +523,30 @@ export const addError: { Method extends HttpMethod, _Path, _P, + _H, _S, _E, _R >( - self: HttpApiEndpoint - ) => HttpApiEndpoint, _R | Schema.Schema.Context> + self: HttpApiEndpoint + ) => HttpApiEndpoint, _R | Schema.Schema.Context> < Name extends string, Method extends HttpMethod, _Path, _P, + _H, _S, _E, _R, E extends Schema.Schema.All >( - self: HttpApiEndpoint, + self: HttpApiEndpoint, schema: E, annotations?: { readonly status?: number | undefined } - ): HttpApiEndpoint, _R | Schema.Schema.Context> + ): HttpApiEndpoint, _R | Schema.Schema.Context> } = dual( (args) => isHttpApiEndpoint(args[0]), < @@ -477,17 +554,18 @@ export const addError: { Method extends HttpMethod, _Path, _P, + _H, _S, _E, _R, E extends Schema.Schema.All >( - self: HttpApiEndpoint, + self: HttpApiEndpoint, schema: E, annotations?: { readonly status?: number | undefined } - ): HttpApiEndpoint, _R | Schema.Schema.Context> => + ): HttpApiEndpoint, _R | Schema.Schema.Context> => makeProto({ ...self as any, errorSchema: HttpApiSchema.UnionUnify( @@ -521,25 +599,27 @@ export const setPayload: { Name extends string, _Path, _P, + _H, _S, _E, _R >( - self: HttpApiEndpoint - ) => HttpApiEndpoint, _S, _E, _R | Schema.Schema.Context

    > => makeProto({ - ...self, + ...self as any, payloadSchema: Option.some(schema) }) ) @@ -551,41 +575,44 @@ export const path: { ): < Name extends string, Method extends HttpMethod, - _Path extends Schema.Schema.Any, - _P extends Schema.Schema.All, - _S extends Schema.Schema.Any, - _E extends Schema.Schema.All + _Path, + _P, + _S, + _E, + _R >( - self: ApiEndpoint - ) => ApiEndpoint + self: ApiEndpoint + ) => ApiEndpoint, _P, _S, _E, _R | Schema.Schema.Context> < Name extends string, Method extends HttpMethod, - _Path extends Schema.Schema.Any, - _P extends Schema.Schema.All, - _S extends Schema.Schema.Any, - _E extends Schema.Schema.All, + _Path, + _P, + _S, + _E, + _R, Path extends Schema.Schema.Any >( - self: ApiEndpoint, + self: ApiEndpoint, schema: Path & ApiEndpoint.ValidatePath - ): ApiEndpoint + ): ApiEndpoint, _P, _S, _E, _R | Schema.Schema.Context> } = dual( 2, < Name extends string, Method extends HttpMethod, - _Path extends Schema.Schema.Any, - _P extends Schema.Schema.All, - _S extends Schema.Schema.Any, - _E extends Schema.Schema.All, + _Path, + _P, + _S, + _E, + _R, Path extends Schema.Schema.Any >( - self: ApiEndpoint, + self: ApiEndpoint, schema: Path & ApiEndpoint.ValidatePath - ): ApiEndpoint => + ): ApiEndpoint, _P, _S, _E, _R | Schema.Schema.Context> => makeProto({ - ...self, + ...self as any, pathSchema: Option.some(schema) }) ) @@ -595,11 +622,11 @@ export const path: { * @category request */ export const prefix: { - (prefix: HttpRouter.PathInput): (self: A) => A - (self: A, prefix: HttpRouter.PathInput): A -} = dual(2, (self: A, prefix: HttpRouter.PathInput): A => + (prefix: HttpRouter.PathInput): (self: A) => A + (self: A, prefix: HttpRouter.PathInput): A +} = dual(2, (self: A, prefix: HttpRouter.PathInput): A => makeProto({ - ...self, + ...self as any, path: HttpRouter.prefixPath(self.path, prefix) }) as A) @@ -607,7 +634,7 @@ export const prefix: { * @since 1.0.0 * @category reflection */ -export const successIsVoid = (self: A): boolean => { +export const successIsVoid = (self: A): boolean => { const ast = Schema.encodedSchema(self.successSchema).ast return ast._tag === "VoidKeyword" } @@ -616,21 +643,23 @@ export const successIsVoid = (self: A): boolean => { * @since 1.0.0 * @category reflection */ -export const schemaSuccess = (self: A): Option.Option => - successIsVoid(self) ? Option.none() : Option.some(self.successSchema) +export const schemaSuccess = ( + self: A +): Option.Option, unknown, ApiEndpoint.Context>> => + successIsVoid(self) ? Option.none() : Option.some(self.successSchema as any) /** * @since 1.0.0 * @category annotations */ export const annotateMerge: { - (context: Context.Context): (self: A) => A - (self: A, context: Context.Context): A + (context: Context.Context): (self: A) => A + (self: A, context: Context.Context): A } = dual( 2, - (self: A, context: Context.Context): A => + (self: A, context: Context.Context): A => makeProto({ - ...self, + ...self as any, annotations: Context.merge(self.annotations, context) }) as A ) @@ -640,13 +669,13 @@ export const annotateMerge: { * @category annotations */ export const annotate: { - (tag: Context.Tag, value: S): (self: A) => A - (self: A, tag: Context.Tag, value: S): A + (tag: Context.Tag, value: S): (self: A) => A + (self: A, tag: Context.Tag, value: S): A } = dual( 3, - (self: A, tag: Context.Tag, value: S): A => + (self: A, tag: Context.Tag, value: S): A => makeProto({ - ...self, + ...self as any, annotations: Context.add(self.annotations, tag, value) }) as A ) diff --git a/packages/platform/src/ApiGroup.ts b/packages/platform/src/ApiGroup.ts index 2f997b4e3e..d8bdc33f4e 100644 --- a/packages/platform/src/ApiGroup.ts +++ b/packages/platform/src/ApiGroup.ts @@ -36,7 +36,7 @@ export const isApiGroup = (u: unknown): u is ApiGroup.Any => Predicate.hasProper */ export interface ApiGroup< out Name extends string, - out Endpoints extends ApiEndpoint.ApiEndpoint.Any = never, + out Endpoints extends ApiEndpoint.ApiEndpoint.All = never, in out Error = ApiDecodeError, out ErrorR = never > extends Pipeable { @@ -130,7 +130,7 @@ const Proto = { } } -const makeProto = (options: { +const makeProto = (options: { readonly name: Name readonly endpoints: Chunk.Chunk readonly errorSchema: Schema.Schema @@ -154,27 +154,27 @@ export const make = (name: Name): ApiGroup => * @category endpoints */ export const add: { - ( + ( endpoint: A - ): ( + ): ( self: ApiGroup ) => ApiGroup < Name extends string, - Endpoints extends ApiEndpoint.ApiEndpoint.Any, + Endpoints extends ApiEndpoint.ApiEndpoint.All, Error, ErrorR, - A extends ApiEndpoint.ApiEndpoint.Any + A extends ApiEndpoint.ApiEndpoint.All >( self: ApiGroup, endpoint: A ): ApiGroup } = dual(2, < Name extends string, - Endpoints extends ApiEndpoint.ApiEndpoint.Any, + Endpoints extends ApiEndpoint.ApiEndpoint.All, Error, ErrorR, - A extends ApiEndpoint.ApiEndpoint.Any + A extends ApiEndpoint.ApiEndpoint.All >( self: ApiGroup, endpoint: A @@ -194,10 +194,10 @@ export const addError: { annotations?: { readonly status?: number | undefined } - ): ( + ): ( self: ApiGroup ) => ApiGroup - ( + ( self: ApiGroup, schema: Schema.Schema, annotations?: { @@ -206,7 +206,7 @@ export const addError: { ): ApiGroup } = dual( (args) => isApiGroup(args[0]), - ( + ( self: ApiGroup, schema: Schema.Schema, annotations?: { @@ -231,14 +231,14 @@ export const addError: { export const prefix: { ( prefix: PathInput - ): ( + ): ( self: ApiGroup ) => ApiGroup - ( + ( self: ApiGroup, prefix: PathInput ): ApiGroup -} = dual(2, ( +} = dual(2, ( self: ApiGroup, prefix: PathInput ): ApiGroup => diff --git a/packages/platform/src/ApiReflection.ts b/packages/platform/src/ApiReflection.ts index 170f47e808..f94ead3ff3 100644 --- a/packages/platform/src/ApiReflection.ts +++ b/packages/platform/src/ApiReflection.ts @@ -12,11 +12,9 @@ import type { HttpMethod } from "./HttpMethod.js" const extractErrors = ( ast: AST.AST, - encoded: boolean, inherited: ReadonlyMap ): ReadonlyMap => { const topStatus = ApiSchema.getStatusErrorAST(ast) - ast = encoded ? AST.encodedAST(ast) : ast const errors = new Map(inherited) function process(ast: AST.AST) { if (ast._tag === "NeverKeyword") { @@ -52,51 +50,44 @@ const extractErrors = ( export const reflect = ( self: Api.Api, options: { - readonly mode: "encoded" | "full" readonly onGroup: (options: { - readonly apiAnnotations: Context.Context readonly group: ApiGroup.ApiGroup - readonly annotations: Context.Context + readonly mergedAnnotations: Context.Context }) => void readonly onEndpoint: (options: { - readonly apiAnnotations: Context.Context readonly group: ApiGroup.ApiGroup - readonly groupAnnotations: Context.Context readonly endpoint: ApiEndpoint.ApiEndpoint - readonly annotations: Context.Context + readonly mergedAnnotations: Context.Context readonly success: readonly [ast: Option.Option, status: number] readonly errors: ReadonlyMap }) => void } ) => { - const apiErrors = extractErrors(self.errorSchema.ast, options.mode === "encoded", new Map()) + const apiErrors = extractErrors(self.errorSchema.ast, new Map()) const groups = self.groups as Iterable> for (const group of groups) { - const groupErrors = extractErrors(group.errorSchema.ast, options.mode === "encoded", apiErrors) + const groupErrors = extractErrors(group.errorSchema.ast, apiErrors) const groupAnnotations = Context.merge(self.annotations, group.annotations) options.onGroup({ - apiAnnotations: self.annotations, group, - annotations: groupAnnotations + mergedAnnotations: groupAnnotations }) const endpoints = group.endpoints as Iterable> for (const endpoint of endpoints) { - const errors = extractErrors(endpoint.errorSchema.ast, options.mode === "encoded", groupErrors) + const errors = extractErrors(endpoint.errorSchema.ast, groupErrors) const annotations = Context.merge(groupAnnotations, endpoint.annotations) const success = [ ApiEndpoint.schemaSuccess(endpoint).pipe( - Option.map((schema) => options.mode === "full" ? schema.ast : AST.encodedAST(schema.ast)) + Option.map((schema) => schema.ast) ), ApiSchema.getStatusSuccess(endpoint.successSchema) ] as const options.onEndpoint({ - apiAnnotations: self.annotations, - groupAnnotations, group, endpoint, - annotations, + mergedAnnotations: annotations, success, errors }) From 18fc85dd9ac4ecd1afde7c6d1e61a57a347b9544 Mon Sep 17 00:00:00 2001 From: Tim Date: Sat, 24 Aug 2024 21:57:00 +1200 Subject: [PATCH 23/59] OpenApi generation --- .changeset/young-pugs-grow.md | 5 + packages/effect/src/Context.ts | 13 ++ packages/effect/src/internal/context.ts | 12 ++ packages/platform-node/examples/api.ts | 9 +- packages/platform/src/OpenApi.ts | 161 +++++++++++++++++++++++- 5 files changed, 193 insertions(+), 7 deletions(-) create mode 100644 .changeset/young-pugs-grow.md diff --git a/.changeset/young-pugs-grow.md b/.changeset/young-pugs-grow.md new file mode 100644 index 0000000000..d9aa6f49ff --- /dev/null +++ b/.changeset/young-pugs-grow.md @@ -0,0 +1,5 @@ +--- +"effect": minor +--- + +add Context.getOrElse api, for gettings a Tag's value with a fallback diff --git a/packages/effect/src/Context.ts b/packages/effect/src/Context.ts index b6bc4ac934..9cf2440bdd 100644 --- a/packages/effect/src/Context.ts +++ b/packages/effect/src/Context.ts @@ -8,6 +8,7 @@ * @since 2.0.0 */ import type { Equal } from "./Equal.js" +import type { LazyArg } from "./Function.js" import type { Inspectable } from "./Inspectable.js" import * as internal from "./internal/context.js" import type { Option } from "./Option.js" @@ -263,6 +264,18 @@ export const get: { >(self: Context, tag: T): Tag.Service } = internal.get +/** + * Get a service from the context that corresponds to the given tag, or + * use the fallback value. + * + * @since 3.7.0 + * @category getters + */ +export const getOrElse: { + (tag: Tag, orElse: LazyArg): (self: Context) => S | B + (self: Context, tag: Tag, orElse: LazyArg): S | B +} = internal.getOrElse + /** * Get a service from the context that corresponds to the given tag. * This function is unsafe because if the tag is not present in the context, a runtime error will be thrown. diff --git a/packages/effect/src/internal/context.ts b/packages/effect/src/internal/context.ts index 96cfe269a2..1fe348d8a5 100644 --- a/packages/effect/src/internal/context.ts +++ b/packages/effect/src/internal/context.ts @@ -1,5 +1,6 @@ import type * as C from "../Context.js" import * as Equal from "../Equal.js" +import type { LazyArg } from "../Function.js" import { dual } from "../Function.js" import * as Hash from "../Hash.js" import { format, NodeInspectSymbol, toJSON } from "../Inspectable.js" @@ -209,6 +210,17 @@ export const get: { >(self: C.Context, tag: T): C.Tag.Service } = unsafeGet +/** @internal */ +export const getOrElse = dual< + (tag: C.Tag, orElse: LazyArg) => (self: C.Context) => S | B, + (self: C.Context, tag: C.Tag, orElse: LazyArg) => S | B +>(3, (self, tag, orElse) => { + if (!self.unsafeMap.has(tag.key)) { + return orElse() + } + return self.unsafeMap.get(tag.key)! as any +}) + /** @internal */ export const getOption = dual< (tag: C.Tag) => (self: C.Context) => O.Option, diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index 75127c6053..4696d42200 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -8,7 +8,8 @@ import { ApiSecurity, HttpClient, HttpMiddleware, - HttpServer + HttpServer, + OpenApi } from "@effect/platform" import { NodeHttpServer, NodeRuntime } from "@effect/platform-node" import { Schema } from "@effect/schema" @@ -62,7 +63,11 @@ const users = ApiGroup.make("users").pipe( ) const api = Api.empty.pipe( - Api.addGroup(users) + Api.addGroup(users), + OpenApi.annotate({ + title: "Users API", + description: "API for managing users" + }) ) const UsersLive = ApiBuilder.group(api, "users", (handlers) => diff --git a/packages/platform/src/OpenApi.ts b/packages/platform/src/OpenApi.ts index a94c1e2f7b..0dea4fc060 100644 --- a/packages/platform/src/OpenApi.ts +++ b/packages/platform/src/OpenApi.ts @@ -1,11 +1,18 @@ /** * @since 1.0.0 */ -import type * as JSONSchema from "@effect/schema/JSONSchema" +import * as AST from "@effect/schema/AST" +import * as JSONSchema from "@effect/schema/JSONSchema" +import * as Schema from "@effect/schema/Schema" import * as Context from "effect/Context" import { dual } from "effect/Function" +import * as Option from "effect/Option" import type { ReadonlyRecord } from "effect/Record" +import type { DeepMutable, Mutable } from "effect/Types" +import type { Api } from "./Api.js" +import { reflect } from "./ApiReflection.js" import type { ApiSecurity } from "./ApiSecurity.js" +import * as HttpMethod from "./HttpMethod.js" /** * @since 1.0.0 @@ -99,6 +106,7 @@ export const annotate: { readonly license?: OpenAPISpecLicense | undefined readonly security?: ApiSecurity | undefined readonly externalDocs?: OpenAPISpecExternalDocs | undefined + readonly tags?: ReadonlyArray | undefined }): (self: A) => A (self: A, annotations: { readonly title?: string | undefined @@ -107,6 +115,7 @@ export const annotate: { readonly license?: OpenAPISpecLicense | undefined readonly security?: ApiSecurity | undefined readonly externalDocs?: OpenAPISpecExternalDocs | undefined + readonly tags?: ReadonlyArray | undefined }): A } = dual(2, (self: A, annotations_: { readonly title?: string | undefined @@ -115,6 +124,7 @@ export const annotate: { readonly license?: OpenAPISpecLicense | undefined readonly security?: ApiSecurity | undefined readonly externalDocs?: OpenAPISpecExternalDocs | undefined + readonly tags?: ReadonlyArray | undefined }): A => { const context = Context.merge( self.annotations, @@ -125,6 +135,141 @@ export const annotate: { }) }) +/** + * @category constructors + * @since 1.0.0 + */ +export const fromApi = (api: A): OpenAPISpec => { + const spec: DeepMutable = { + openapi: "3.0.3", + info: { + title: Context.getOrElse(api.annotations, Title, () => "Api"), + version: Context.getOrElse(api.annotations, Version, () => "0.0.1") + }, + paths: {}, + tags: [] + } + Option.map(Context.getOption(api.annotations, Description), (description) => { + spec.info.description = description + }) + Option.map(Context.getOption(api.annotations, License), (license) => { + spec.info.license = license + }) + reflect(api as any, { + onGroup({ group }) { + const tag: Mutable = { + name: group.name + } + Option.map(Context.getOption(group.annotations, Description), (description) => { + tag.description = description + }) + Option.map(Context.getOption(group.annotations, ExternalDocs), (externalDocs) => { + tag.externalDocs = externalDocs + }) + spec.tags!.push(tag) + }, + onEndpoint({ endpoint, errors, group, success }) { + const path = endpoint.path.replace(/:(\w+)[^/]*/g, "{$1}") + const method = endpoint.method.toLowerCase() as OpenAPISpecMethodName + const op: DeepMutable = { + tags: [group.name], + operationId: endpoint.name, + parameters: [], + responses: { + [success[1]]: { + description: "Success" + } + } + } + Option.map(Context.getOption(endpoint.annotations, Description), (description) => { + op.description = description + }) + Option.map(Context.getOption(endpoint.annotations, ExternalDocs), (externalDocs) => { + op.externalDocs = externalDocs + }) + endpoint.payloadSchema.pipe( + Option.filter(() => HttpMethod.hasBody(endpoint.method)), + Option.map((schema) => { + op.requestBody = { + content: { + "application/json": { + schema: makeJsonSchema(schema) + } + }, + required: true + } + }) + ) + success[0].pipe( + Option.map((ast) => { + op.responses![success[1]].content = { + "application/json": { + schema: makeJsonSchema(Schema.make(ast)) + } + } + }) + ) + if (Option.isSome(endpoint.pathSchema)) { + getPropertySignatures(AST.encodedAST(endpoint.pathSchema.value.ast)).forEach((ps) => { + op.parameters!.push({ + name: ps.name as string, + in: "path", + schema: makeJsonSchema(Schema.make(ps.type)), + required: !ps.isOptional + }) + }) + } + if (!HttpMethod.hasBody(endpoint.method) && Option.isSome(endpoint.payloadSchema)) { + getPropertySignatures(AST.encodedAST(endpoint.payloadSchema.value.ast)).forEach((ps) => { + op.parameters!.push({ + name: ps.name as string, + in: "query", + schema: makeJsonSchema(Schema.make(ps.type)), + required: !ps.isOptional + }) + }) + } + for (const [status, ast] of errors) { + if (op.responses![status]) continue + op.responses![status] = { + description: Option.getOrElse(AST.getDescriptionAnnotation(ast), () => "Error"), + content: { + "application/json": { + schema: makeJsonSchema(Schema.make(ast)) + } + } + } + } + if (!spec.paths[path]) { + spec.paths[path] = {} + } + spec.paths[path][method] = op + } + }) + + return spec +} + +const getPropertySignatures = (ast: AST.AST): ReadonlyArray => { + switch (ast._tag) { + case "Union": { + return ast.types.flatMap(getPropertySignatures) + } + case "TypeLiteral": { + return ast.propertySignatures + } + default: { + return [] + } + } +} + +const makeJsonSchema = (schema: Schema.Schema.All): OpenAPIJSONSchema => { + const jsonSchema = JSONSchema.make(schema as any) + delete jsonSchema.$schema + return jsonSchema +} + /** * @category models * @since 1.0.0 @@ -236,6 +381,12 @@ export type OpenAPISpecPathItem = readonly parameters?: Array } +/** + * @category models + * @since 1.0.0 + */ +export type OpenAPIJSONSchema = Omit + /** * @category models * @since 1.0.0 @@ -243,7 +394,7 @@ export type OpenAPISpecPathItem = export interface OpenAPISpecParameter { readonly name: string readonly in: "query" | "header" | "path" | "cookie" - readonly schema: JSONSchema.JsonSchema7 + readonly schema: OpenAPIJSONSchema readonly description?: string readonly required?: boolean readonly deprecated?: boolean @@ -276,7 +427,7 @@ export type OpenApiSpecContent = { */ export interface OpenApiSpecResponseHeader { readonly description?: string - readonly schema: JSONSchema.JsonSchema7 + readonly schema: OpenAPIJSONSchema } /** @@ -303,7 +454,7 @@ export interface OpenApiSpecResponse { * @since 1.0.0 */ export interface OpenApiSpecMediaType { - readonly schema?: JSONSchema.JsonSchema7 + readonly schema?: OpenAPIJSONSchema readonly example?: object readonly description?: string } @@ -323,7 +474,7 @@ export interface OpenAPISpecRequestBody { * @since 1.0.0 */ export interface OpenAPIComponents { - readonly schemas?: ReadonlyRecord + readonly schemas?: ReadonlyRecord readonly securitySchemes?: ReadonlyRecord } From f7d8fa5e011859b27e37ef0a42a7dcb40c46045a Mon Sep 17 00:00:00 2001 From: Tim Date: Sat, 24 Aug 2024 22:05:50 +1200 Subject: [PATCH 24/59] prefix operationId --- packages/platform/src/OpenApi.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/platform/src/OpenApi.ts b/packages/platform/src/OpenApi.ts index 0dea4fc060..5cfc309b12 100644 --- a/packages/platform/src/OpenApi.ts +++ b/packages/platform/src/OpenApi.ts @@ -173,7 +173,7 @@ export const fromApi = (api: A): OpenAPISpec => { const method = endpoint.method.toLowerCase() as OpenAPISpecMethodName const op: DeepMutable = { tags: [group.name], - operationId: endpoint.name, + operationId: `${group.name}.${endpoint.name}`, parameters: [], responses: { [success[1]]: { From 97299213635598a2daf294f2a0ad1f825fef3181 Mon Sep 17 00:00:00 2001 From: Tim Date: Sun, 25 Aug 2024 09:51:48 +1200 Subject: [PATCH 25/59] allow operationId to be overriden --- packages/platform/src/OpenApi.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/packages/platform/src/OpenApi.ts b/packages/platform/src/OpenApi.ts index 5cfc309b12..cdf942571e 100644 --- a/packages/platform/src/OpenApi.ts +++ b/packages/platform/src/OpenApi.ts @@ -14,6 +14,12 @@ import { reflect } from "./ApiReflection.js" import type { ApiSecurity } from "./ApiSecurity.js" import * as HttpMethod from "./HttpMethod.js" +/** + * @since 1.0.0 + * @category annotations + */ +export class Identifier extends Context.Tag("@effect/platform/OpenApi/Identifier")() {} + /** * @since 1.0.0 * @category annotations @@ -57,6 +63,7 @@ export class ExternalDocs * @category annotations */ export const annotations = (annotations: { + readonly identifier?: string | undefined readonly title?: string | undefined readonly description?: string | undefined readonly version?: string | undefined @@ -65,6 +72,9 @@ export const annotations = (annotations: { readonly externalDocs?: OpenAPISpecExternalDocs | undefined }): Context.Context => { let context = Context.empty() + if (annotations.identifier !== undefined) { + context = Context.add(context, Identifier, annotations.identifier) + } if (annotations.title !== undefined) { context = Context.add(context, Title, annotations.title) } @@ -100,31 +110,31 @@ export interface Annotatable { */ export const annotate: { (annotations: { + readonly identifier?: string | undefined readonly title?: string | undefined readonly description?: string | undefined readonly version?: string | undefined readonly license?: OpenAPISpecLicense | undefined readonly security?: ApiSecurity | undefined readonly externalDocs?: OpenAPISpecExternalDocs | undefined - readonly tags?: ReadonlyArray | undefined }): (self: A) => A (self: A, annotations: { + readonly identifier?: string | undefined readonly title?: string | undefined readonly description?: string | undefined readonly version?: string | undefined readonly license?: OpenAPISpecLicense | undefined readonly security?: ApiSecurity | undefined readonly externalDocs?: OpenAPISpecExternalDocs | undefined - readonly tags?: ReadonlyArray | undefined }): A } = dual(2, (self: A, annotations_: { + readonly identifier?: string | undefined readonly title?: string | undefined readonly description?: string | undefined readonly version?: string | undefined readonly license?: OpenAPISpecLicense | undefined readonly security?: ApiSecurity | undefined readonly externalDocs?: OpenAPISpecExternalDocs | undefined - readonly tags?: ReadonlyArray | undefined }): A => { const context = Context.merge( self.annotations, @@ -173,7 +183,7 @@ export const fromApi = (api: A): OpenAPISpec => { const method = endpoint.method.toLowerCase() as OpenAPISpecMethodName const op: DeepMutable = { tags: [group.name], - operationId: `${group.name}.${endpoint.name}`, + operationId: Context.getOrElse(endpoint.annotations, Identifier, () => `${group.name}.${endpoint.name}`), parameters: [], responses: { [success[1]]: { From 6ee91cb5a96170e56c8a583c6eaa67ff20bec8da Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 26 Aug 2024 09:30:08 +1200 Subject: [PATCH 26/59] move api to context --- packages/platform-node/examples/api.ts | 10 ++-- packages/platform/src/Api.ts | 14 ++++++ packages/platform/src/ApiBuilder.ts | 67 ++++++++++++++------------ 3 files changed, 56 insertions(+), 35 deletions(-) diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index 4696d42200..9ea34b2d82 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -90,10 +90,14 @@ const UsersLive = ApiBuilder.group(api, "users", (handlers) => securityMiddleware )) -ApiBuilder.serve(api, HttpMiddleware.logger).pipe( - HttpServer.withLogAddress, - Layer.provide(UsersLive), +const ApiLive = ApiBuilder.api(api).pipe( + Layer.provide(UsersLive) +) + +ApiBuilder.serve(HttpMiddleware.logger).pipe( + Layer.provide(ApiLive), Layer.provide(ApiBuilder.middlewareCors()), + HttpServer.withLogAddress, Layer.provide(NodeHttpServer.layer(createServer, { port: 3000 })), Layer.launch, NodeRuntime.runMain diff --git a/packages/platform/src/Api.ts b/packages/platform/src/Api.ts index 9745915728..38e8fec93c 100644 --- a/packages/platform/src/Api.ts +++ b/packages/platform/src/Api.ts @@ -46,11 +46,25 @@ export interface Api< readonly annotations: Context.Context } +/** + * @since 1.0.0 + * @category tags + */ +export const Api: Context.Tag = Context.GenericTag("@effect/platform/Api") + /** * @since 1.0.0 * @category models */ export declare namespace Api { + /** + * @since 1.0.0 + * @category models + */ + export interface Service { + readonly _: unique symbol + } + /** * @since 1.0.0 * @category models diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index 7b646df78b..7591200eb9 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -45,29 +45,21 @@ export class ApiRouter extends HttpRouter.Tag("@effect/platform/ApiBuilder/ApiRo * @category constructors */ export const serve: { - ( - self: Api.Api - ): Layer.Layer | ErrorR> - ( - self: Api.Api, + (): Layer.Layer + ( middleware: (httpApp: HttpApp.Default) => HttpApp.Default ): Layer.Layer< never, never, | HttpServer.HttpServer | Exclude - | ApiGroup.ApiGroup.ToService - | ErrorR > -} = ( - self: Api.Api.Any, - middleware?: HttpMiddleware.HttpMiddleware.Applied -): Layer.Layer< +} = (middleware?: HttpMiddleware.HttpMiddleware.Applied): Layer.Layer< never, never, any > => - httpApp(self as any).pipe( + httpApp.pipe( Effect.map(HttpServer.serve(middleware!)), Layer.unwrapEffect, Layer.provide(ApiRouter.Live) @@ -77,28 +69,35 @@ export const serve: { * @since 1.0.0 * @category constructors */ -export const httpApp = ( - self: Api.Api -): Effect.Effect< +export const httpApp: Effect.Effect< HttpApp.Default, never, - ApiRouter | ApiGroup.ApiGroup.ToService | ErrorR -> => - Effect.gen(function*() { - const router = yield* ApiRouter.router - const apiMiddleware = yield* Effect.serviceOption(ApiMiddleware) - const errorSchema = makeErrorSchema(self as any) - const encodeError = Schema.encodeUnknown(errorSchema) - return router.pipe( - apiMiddleware._tag === "Some" ? apiMiddleware.value : identity, - Effect.catchAll((error) => - Effect.matchEffect(encodeError(error), { - onFailure: () => Effect.die(error), - onSuccess: ([body, status]) => Effect.orDie(HttpServerResponse.json(body, { status })) - }) - ) + ApiRouter | Api.Api.Service +> = Effect.gen(function*() { + const api = yield* Api.Api + const router = yield* ApiRouter.router + const apiMiddleware = yield* Effect.serviceOption(ApiMiddleware) + const errorSchema = makeErrorSchema(api as any) + const encodeError = Schema.encodeUnknown(errorSchema) + return router.pipe( + apiMiddleware._tag === "Some" ? apiMiddleware.value : identity, + Effect.catchAll((error) => + Effect.matchEffect(encodeError(error), { + onFailure: () => Effect.die(error), + onSuccess: ([body, status]) => Effect.orDie(HttpServerResponse.json(body, { status })) + }) ) - }) + ) +}) + +/** + * @since 1.0.0 + * @category constructors + */ +export const api = ( + self: Api.Api +): Layer.Layer | ErrorR> => + Layer.succeed(Api.Api, self) as any /** * @since 1.0.0 @@ -196,7 +195,11 @@ export const group = < ) => | Handlers | ApiGroup.ApiGroup.ErrorWithName, RH> | Effect.Effect | ApiGroup.ApiGroup.ErrorWithName, RH>, EX, RX> -): Layer.Layer, EX, RX | RH | ApiGroup.ApiGroup.ContextWithName> => +): Layer.Layer< + ApiGroup.ApiGroup.Service, + EX, + RX | RH | ApiGroup.ApiGroup.ContextWithName | ApiErrorR +> => ApiRouter.use((router) => Effect.gen(function*() { const context = yield* Effect.context() From 958fca95b608f0404325fa65a68eb6999c5ff069 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 26 Aug 2024 09:50:28 +1200 Subject: [PATCH 27/59] move ApiReflection into Api module --- packages/platform-node/examples/api.ts | 1 + packages/platform/src/Api.ts | 91 ++++++++++++++++++++++++ packages/platform/src/ApiBuilder.ts | 23 ++++++ packages/platform/src/ApiClient.ts | 11 ++- packages/platform/src/ApiEndpoint.ts | 70 +------------------ packages/platform/src/ApiReflection.ts | 96 -------------------------- packages/platform/src/ApiSchema.ts | 84 +++++++++++++++++++++- packages/platform/src/OpenApi.ts | 7 +- packages/platform/src/index.ts | 5 -- 9 files changed, 207 insertions(+), 181 deletions(-) delete mode 100644 packages/platform/src/ApiReflection.ts diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index 9ea34b2d82..ee7258710e 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -95,6 +95,7 @@ const ApiLive = ApiBuilder.api(api).pipe( ) ApiBuilder.serve(HttpMiddleware.logger).pipe( + Layer.provide(ApiBuilder.middlewareOpenApi()), Layer.provide(ApiLive), Layer.provide(ApiBuilder.middlewareCors()), HttpServer.withLogAddress, diff --git a/packages/platform/src/Api.ts b/packages/platform/src/Api.ts index 38e8fec93c..e8390b2b61 100644 --- a/packages/platform/src/Api.ts +++ b/packages/platform/src/Api.ts @@ -1,16 +1,20 @@ /** * @since 1.0.0 */ +import * as AST from "@effect/schema/AST" import * as Schema from "@effect/schema/Schema" import * as Chunk from "effect/Chunk" import * as Context from "effect/Context" import { dual } from "effect/Function" +import * as Option from "effect/Option" import type { Pipeable } from "effect/Pipeable" import { pipeArguments } from "effect/Pipeable" import * as Predicate from "effect/Predicate" +import * as ApiEndpoint from "./ApiEndpoint.js" import { ApiDecodeError } from "./ApiError.js" import * as ApiGroup from "./ApiGroup.js" import * as ApiSchema from "./ApiSchema.js" +import type { HttpMethod } from "./HttpMethod.js" import type * as HttpRouter from "./HttpRouter.js" /** @@ -212,3 +216,90 @@ export const annotate: { annotations: Context.add(self.annotations, tag, value) }) as A ) + +/** + * @since 1.0.0 + * @category reflection + */ +export const reflect = ( + self: Api, + options: { + readonly onGroup: (options: { + readonly group: ApiGroup.ApiGroup + readonly mergedAnnotations: Context.Context + }) => void + readonly onEndpoint: (options: { + readonly group: ApiGroup.ApiGroup + readonly endpoint: ApiEndpoint.ApiEndpoint + readonly mergedAnnotations: Context.Context + readonly success: readonly [ast: Option.Option, status: number] + readonly errors: ReadonlyMap + }) => void + } +) => { + const apiErrors = extractErrors(self.errorSchema.ast, new Map()) + + const groups = self.groups as Iterable> + for (const group of groups) { + const groupErrors = extractErrors(group.errorSchema.ast, apiErrors) + const groupAnnotations = Context.merge(self.annotations, group.annotations) + options.onGroup({ + group, + mergedAnnotations: groupAnnotations + }) + const endpoints = group.endpoints as Iterable> + + for (const endpoint of endpoints) { + const errors = extractErrors(endpoint.errorSchema.ast, groupErrors) + const annotations = Context.merge(groupAnnotations, endpoint.annotations) + const success = [ + ApiEndpoint.schemaSuccess(endpoint).pipe( + Option.map((schema) => schema.ast) + ), + ApiSchema.getStatusSuccess(endpoint.successSchema) + ] as const + options.onEndpoint({ + group, + endpoint, + mergedAnnotations: annotations, + success, + errors + }) + } + } +} + +// ------------------------------------------------------------------------------------- + +const extractErrors = ( + ast: AST.AST, + inherited: ReadonlyMap +): ReadonlyMap => { + const topStatus = ApiSchema.getStatusErrorAST(ast) + const errors = new Map(inherited) + function process(ast: AST.AST) { + if (ast._tag === "NeverKeyword") { + return + } + const status = ApiSchema.getStatus(ast, topStatus) + if (errors.has(status)) { + const current = errors.get(status)! + errors.set( + status, + AST.Union.make( + current._tag === "Union" ? [...current.types, ast] : [current, ast] + ) + ) + } else { + errors.set(status, ast) + } + } + if (ast._tag === "Union") { + for (const type of ast.types) { + process(type) + } + } else { + process(ast) + } + return errors +} diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index 7591200eb9..196670a52b 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -31,6 +31,7 @@ import * as HttpRouter from "./HttpRouter.js" import * as HttpServer from "./HttpServer.js" import * as HttpServerRequest from "./HttpServerRequest.js" import * as HttpServerResponse from "./HttpServerResponse.js" +import * as OpenApi from "./OpenApi.js" /** * The router that the API endpoints are attached to. @@ -456,6 +457,28 @@ export const middlewareCors = ( } | undefined ): Layer.Layer => middlewareLayer(HttpMiddleware.cors(options)) +/** + * A middleware that adds an openapi.json endpoint to the API. + * + * @since 1.0.0 + * @category middleware + */ +export const middlewareOpenApi = ( + options?: { + readonly path?: HttpRouter.PathInput | undefined + } | undefined +): Layer.Layer => + ApiRouter.use((router) => + Effect.gen(function*() { + const api = yield* Api.Api + const spec = OpenApi.fromApi(api) + const response = yield* HttpServerResponse.json(spec).pipe( + Effect.orDie + ) + yield* router.get(options?.path ?? "/openapi.json", response) + }) + ) + /** * @since 1.0.0 * @category middleware diff --git a/packages/platform/src/ApiClient.ts b/packages/platform/src/ApiClient.ts index 8c9f306b2d..c9aeec6927 100644 --- a/packages/platform/src/ApiClient.ts +++ b/packages/platform/src/ApiClient.ts @@ -8,10 +8,9 @@ import { identity } from "effect/Function" import * as Option from "effect/Option" import type { Simplify } from "effect/Types" import { unify } from "effect/Unify" -import type { Api } from "./Api.js" +import * as Api from "./Api.js" import type { ApiEndpoint } from "./ApiEndpoint.js" import type { ApiGroup } from "./ApiGroup.js" -import { reflect } from "./ApiReflection.js" import * as HttpClient from "./HttpClient.js" import * as HttpClientError from "./HttpClientError.js" import * as HttpClientRequest from "./HttpClientRequest.js" @@ -22,7 +21,7 @@ import * as HttpMethod from "./HttpMethod.js" * @since 1.0.0 * @category models */ -export type Client = [A] extends [Api] ? { +export type Client = [A] extends [Api.Api] ? { readonly [GroupName in _Groups["name"]]: [ApiGroup.WithName<_Groups, GroupName>] extends [ApiGroup] ? { readonly [Name in _Endpoints["name"]]: [ApiEndpoint.WithName<_Endpoints, Name>] extends [ @@ -51,13 +50,13 @@ export type Client = [A] extends [Api( +export const make = ( api: A, options?: { readonly transformClient?: ((client: HttpClient.HttpClient.Default) => HttpClient.HttpClient.Default) | undefined readonly baseUrl?: string | undefined } -): Effect.Effect>, never, Api.Context | HttpClient.HttpClient.Default> => +): Effect.Effect>, never, Api.Api.Context | HttpClient.HttpClient.Default> => Effect.gen(function*() { const context = yield* Effect.context() const httpClient = (yield* HttpClient.HttpClient).pipe( @@ -65,7 +64,7 @@ export const make = ( options?.transformClient === undefined ? identity : options.transformClient ) const client: Record> = {} - reflect(api as any, { + Api.reflect(api as any, { onGroup({ group }) { client[group.name] = {} }, diff --git a/packages/platform/src/ApiEndpoint.ts b/packages/platform/src/ApiEndpoint.ts index 6cc5934166..12e5d47239 100644 --- a/packages/platform/src/ApiEndpoint.ts +++ b/packages/platform/src/ApiEndpoint.ts @@ -25,18 +25,6 @@ export const TypeId: unique symbol = Symbol.for("@effect/platform/ApiEndpoint") */ export type TypeId = typeof TypeId -/** - * @since 1.0.0 - * @category symbols - */ -export const Ignored: unique symbol = Symbol.for("@effect/platform/ApiEndpoint/Ignored") - -/** - * @since 1.0.0 - * @category symbols - */ -export type Ignored = typeof Ignored - /** * @since 1.0.0 * @category guards @@ -67,12 +55,6 @@ export interface ApiEndpoint< readonly annotations: Context.Context } -/** - * @since 1.0.0 - * @category models - */ -export interface PathParams extends Schema.Record$ {} - /** * @since 1.0.0 * @category models @@ -286,7 +268,7 @@ export const make = (method: Method) => method, pathSchema: Option.none(), payloadSchema: Option.none(), - successSchema: Empty as any, + successSchema: ApiSchema.NoContent as any, errorSchema: Schema.Never as any, annotations: Context.empty() }) @@ -336,56 +318,6 @@ export const del: ( path: HttpRouter.PathInput ) => ApiEndpoint = make("DELETE") -type Void$ = typeof Schema.Void - -/** - * @since 1.0.0 - * @category schemas - */ -export interface Created extends Void$ { - readonly _: unique symbol -} - -/** - * @since 1.0.0 - * @category schemas - */ -export const Created: Created = Schema.Void.annotations(ApiSchema.annotations({ - status: 201 -})) as any - -/** - * @since 1.0.0 - * @category schemas - */ -export interface Accepted extends Void$ { - readonly _: unique symbol -} - -/** - * @since 1.0.0 - * @category schemas - */ -export const Accepted: Accepted = Schema.Void.annotations(ApiSchema.annotations({ - status: 202 -})) as any - -/** - * @since 1.0.0 - * @category schemas - */ -export interface Empty extends Void$ { - readonly _: unique symbol -} - -/** - * @since 1.0.0 - * @category schemas - */ -export const Empty: Empty = Schema.Void.annotations(ApiSchema.annotations({ - status: 204 -})) as any - /** * @since 1.0.0 * @category result diff --git a/packages/platform/src/ApiReflection.ts b/packages/platform/src/ApiReflection.ts deleted file mode 100644 index f94ead3ff3..0000000000 --- a/packages/platform/src/ApiReflection.ts +++ /dev/null @@ -1,96 +0,0 @@ -/** - * @since 1.0.0 - */ -import * as AST from "@effect/schema/AST" -import * as Context from "effect/Context" -import * as Option from "effect/Option" -import type * as Api from "./Api.js" -import * as ApiEndpoint from "./ApiEndpoint.js" -import type * as ApiGroup from "./ApiGroup.js" -import * as ApiSchema from "./ApiSchema.js" -import type { HttpMethod } from "./HttpMethod.js" - -const extractErrors = ( - ast: AST.AST, - inherited: ReadonlyMap -): ReadonlyMap => { - const topStatus = ApiSchema.getStatusErrorAST(ast) - const errors = new Map(inherited) - function process(ast: AST.AST) { - if (ast._tag === "NeverKeyword") { - return - } - const status = ApiSchema.getStatus(ast, topStatus) - if (errors.has(status)) { - const current = errors.get(status)! - errors.set( - status, - AST.Union.make( - current._tag === "Union" ? [...current.types, ast] : [current, ast] - ) - ) - } else { - errors.set(status, ast) - } - } - if (ast._tag === "Union") { - for (const type of ast.types) { - process(type) - } - } else { - process(ast) - } - return errors -} - -/** - * @since 1.0.0 - * @category reflection - */ -export const reflect = ( - self: Api.Api, - options: { - readonly onGroup: (options: { - readonly group: ApiGroup.ApiGroup - readonly mergedAnnotations: Context.Context - }) => void - readonly onEndpoint: (options: { - readonly group: ApiGroup.ApiGroup - readonly endpoint: ApiEndpoint.ApiEndpoint - readonly mergedAnnotations: Context.Context - readonly success: readonly [ast: Option.Option, status: number] - readonly errors: ReadonlyMap - }) => void - } -) => { - const apiErrors = extractErrors(self.errorSchema.ast, new Map()) - - const groups = self.groups as Iterable> - for (const group of groups) { - const groupErrors = extractErrors(group.errorSchema.ast, apiErrors) - const groupAnnotations = Context.merge(self.annotations, group.annotations) - options.onGroup({ - group, - mergedAnnotations: groupAnnotations - }) - const endpoints = group.endpoints as Iterable> - - for (const endpoint of endpoints) { - const errors = extractErrors(endpoint.errorSchema.ast, groupErrors) - const annotations = Context.merge(groupAnnotations, endpoint.annotations) - const success = [ - ApiEndpoint.schemaSuccess(endpoint).pipe( - Option.map((schema) => schema.ast) - ), - ApiSchema.getStatusSuccess(endpoint.successSchema) - ] as const - options.onEndpoint({ - group, - endpoint, - mergedAnnotations: annotations, - success, - errors - }) - } - } -} diff --git a/packages/platform/src/ApiSchema.ts b/packages/platform/src/ApiSchema.ts index c3086f6724..72b77cb49b 100644 --- a/packages/platform/src/ApiSchema.ts +++ b/packages/platform/src/ApiSchema.ts @@ -2,7 +2,8 @@ * @since 1.0.0 */ import * as AST from "@effect/schema/AST" -import type * as Schema from "@effect/schema/Schema" +import * as Schema from "@effect/schema/Schema" +import { constVoid, identity } from "effect/Function" import * as Struct from "effect/Struct" /** @@ -68,3 +69,84 @@ export const getStatusErrorAST = (ast: AST.AST): number => getStatus(ast, 500) * @category reflection */ export const getStatusError = (self: A): number => getStatusErrorAST(self.ast) + +/** + * @since 1.0.0 + * @category schemas + */ +export interface PathParams extends Schema.Record$ {} + +type Void$ = typeof Schema.Void + +/** + * @since 1.0.0 + * @category schemas + */ +export const Empty = (status: number): typeof Schema.Void => Schema.Void.annotations(annotations({ status })) + +/** + * @since 1.0.0 + * @category schemas + */ +export interface asEmpty + extends Schema.transform> +{} + +/** + * @since 1.0.0 + * @category schemas + */ +export const asEmpty = ( + self: S, + status: number +): asEmpty => + Schema.transform( + Schema.Void, + Schema.Union(self, Schema.Void), + { + decode: identity, + encode: constVoid + } + ).annotations(annotations({ status })) + +/** + * @since 1.0.0 + * @category schemas + */ +export interface Created extends Void$ { + readonly _: unique symbol +} + +/** + * @since 1.0.0 + * @category schemas + */ +export const Created: Created = Empty(201) as any + +/** + * @since 1.0.0 + * @category schemas + */ +export interface Accepted extends Void$ { + readonly _: unique symbol +} + +/** + * @since 1.0.0 + * @category schemas + */ +export const Accepted: Accepted = Empty(202) as any + +/** + * @since 1.0.0 + * @category schemas + */ +export interface NoContent extends Void$ { + readonly _: unique symbol +} + +/** + * @since 1.0.0 + * @category schemas + */ +export const NoContent: NoContent = Empty(204) as any diff --git a/packages/platform/src/OpenApi.ts b/packages/platform/src/OpenApi.ts index cdf942571e..f5dba963c9 100644 --- a/packages/platform/src/OpenApi.ts +++ b/packages/platform/src/OpenApi.ts @@ -9,8 +9,7 @@ import { dual } from "effect/Function" import * as Option from "effect/Option" import type { ReadonlyRecord } from "effect/Record" import type { DeepMutable, Mutable } from "effect/Types" -import type { Api } from "./Api.js" -import { reflect } from "./ApiReflection.js" +import * as Api from "./Api.js" import type { ApiSecurity } from "./ApiSecurity.js" import * as HttpMethod from "./HttpMethod.js" @@ -149,7 +148,7 @@ export const annotate: { * @category constructors * @since 1.0.0 */ -export const fromApi = (api: A): OpenAPISpec => { +export const fromApi = (api: A): OpenAPISpec => { const spec: DeepMutable = { openapi: "3.0.3", info: { @@ -165,7 +164,7 @@ export const fromApi = (api: A): OpenAPISpec => { Option.map(Context.getOption(api.annotations, License), (license) => { spec.info.license = license }) - reflect(api as any, { + Api.reflect(api as any, { onGroup({ group }) { const tag: Mutable = { name: group.name diff --git a/packages/platform/src/index.ts b/packages/platform/src/index.ts index be6d6f3ed0..208836c491 100644 --- a/packages/platform/src/index.ts +++ b/packages/platform/src/index.ts @@ -28,11 +28,6 @@ export * as ApiError from "./ApiError.js" */ export * as ApiGroup from "./ApiGroup.js" -/** - * @since 1.0.0 - */ -export * as ApiReflection from "./ApiReflection.js" - /** * @since 1.0.0 */ From e984ed3683ae4ede8060c184964022510f928254 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 26 Aug 2024 10:42:00 +1200 Subject: [PATCH 28/59] add support for empty response errors --- packages/platform-node/examples/api.ts | 4 +- packages/platform/src/Api.ts | 28 +++++----- packages/platform/src/ApiBuilder.ts | 20 ++++--- packages/platform/src/ApiClient.ts | 40 ++++++++++---- packages/platform/src/ApiSchema.ts | 74 ++++++++++++++++++++------ packages/platform/src/OpenApi.ts | 21 +++++--- 6 files changed, 136 insertions(+), 51 deletions(-) diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index ee7258710e..29d8c4b094 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -42,7 +42,9 @@ const users = ApiGroup.make("users").pipe( id: Schema.NumberFromString })), ApiEndpoint.success(User), - ApiEndpoint.error(Schema.String) + ApiEndpoint.error(Schema.String.pipe( + ApiSchema.asEmpty({ status: 413, decode: () => "boom" }) + )) ) ), ApiGroup.add( diff --git a/packages/platform/src/Api.ts b/packages/platform/src/Api.ts index e8390b2b61..61e4944a15 100644 --- a/packages/platform/src/Api.ts +++ b/packages/platform/src/Api.ts @@ -233,7 +233,7 @@ export const reflect = ( readonly endpoint: ApiEndpoint.ApiEndpoint readonly mergedAnnotations: Context.Context readonly success: readonly [ast: Option.Option, status: number] - readonly errors: ReadonlyMap + readonly errors: ReadonlyMap> }) => void } ) => { @@ -273,8 +273,8 @@ export const reflect = ( const extractErrors = ( ast: AST.AST, - inherited: ReadonlyMap -): ReadonlyMap => { + inherited: ReadonlyMap> +): ReadonlyMap> => { const topStatus = ApiSchema.getStatusErrorAST(ast) const errors = new Map(inherited) function process(ast: AST.AST) { @@ -282,17 +282,21 @@ const extractErrors = ( return } const status = ApiSchema.getStatus(ast, topStatus) - if (errors.has(status)) { - const current = errors.get(status)! - errors.set( - status, - AST.Union.make( - current._tag === "Union" ? [...current.types, ast] : [current, ast] + const emptyDecodeable = ApiSchema.getEmptyDecodeable(ast) + const current = errors.get(status) ?? Option.none() + errors.set( + status, + current.pipe( + Option.map((current) => + AST.Union.make( + current._tag === "Union" ? [...current.types, ast] : [current, ast] + ) + ), + Option.orElse(() => + !emptyDecodeable && AST.encodedAST(ast)._tag === "VoidKeyword" ? Option.none() : Option.some(ast) ) ) - } else { - errors.set(status, ast) - } + ) } if (ast._tag === "Union") { for (const type of ast.types) { diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index 196670a52b..6692980016 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -1,7 +1,8 @@ /** * @since 1.0.0 */ -import type * as AST from "@effect/schema/AST" +import * as AST from "@effect/schema/AST" +import * as ParseResult from "@effect/schema/ParseResult" import * as Schema from "@effect/schema/Schema" import * as Chunk from "effect/Chunk" import * as Context from "effect/Context" @@ -85,7 +86,7 @@ export const httpApp: Effect.Effect< Effect.catchAll((error) => Effect.matchEffect(encodeError(error), { onFailure: () => Effect.die(error), - onSuccess: ([body, status]) => Effect.orDie(HttpServerResponse.json(body, { status })) + onSuccess: Effect.succeed }) ) ) @@ -671,7 +672,7 @@ const astCache = globalValue("@effect/platform/ApiBuilder", () => new WeakMap, any, any> -): Schema.Schema => { +): Schema.Schema => { const schemas = new Set() function processSchema(schema: Schema.Schema.Any): void { if (astCache.has(schema.ast)) { @@ -701,9 +702,16 @@ const makeErrorSchema = ( } return Schema.Union(...[...schemas].map((schema) => { const status = ApiSchema.getStatusError(schema) - return Schema.transform(Schema.Any, schema, { - decode: identity, - encode: (error) => [error, status] + const encoded = AST.encodedAST(schema.ast) + const isEmpty = encoded._tag === "VoidKeyword" + return Schema.transformOrFail(Schema.Any, schema, { + decode: (_, __, ast) => ParseResult.fail(new ParseResult.Forbidden(ast, _, "Encode only schema")), + encode: (error, _, ast) => + isEmpty ? + HttpServerResponse.empty({ status }) : + HttpServerResponse.json(error, { status }).pipe( + Effect.mapError((error) => new ParseResult.Type(ast, error, "Could not encode to JSON")) + ) }) })) as any } diff --git a/packages/platform/src/ApiClient.ts b/packages/platform/src/ApiClient.ts index c9aeec6927..b07198dddc 100644 --- a/packages/platform/src/ApiClient.ts +++ b/packages/platform/src/ApiClient.ts @@ -38,7 +38,7 @@ export type Client = [A] extends [Api.Api> ) => Effect.Effect< _Success, - _Error | _GroupError | _ApiError + _Error | _GroupError | _ApiError | HttpClientError.HttpClientError > : never } : @@ -87,21 +87,39 @@ export const make = ( response }) ) + } else if (Option.isNone(error)) { + return Effect.fail( + new HttpClientError.ResponseError({ + reason: "StatusCode", + request, + response + }) + ) } - const decode = Schema.decodeUnknown(Schema.make(error)) - return response.json.pipe( - Effect.flatMap(decode), - Effect.matchEffect({ - onFailure: () => - Effect.die( + const decode = Schema.decodeUnknown(Schema.make(error.value)) + return response.text.pipe( + Effect.flatMap((text) => + text === "" ? Effect.void : Effect.try({ + try: () => JSON.parse(text), + catch: (cause) => new HttpClientError.ResponseError({ reason: "Decode", request, - response + response, + cause }) - ), - onSuccess: Effect.fail - }) + }) + ), + Effect.flatMap((json) => + Effect.mapError(decode(json), (cause) => + new HttpClientError.ResponseError({ + reason: "Decode", + request, + response, + cause + })) + ), + Effect.flatMap(Effect.fail) ) } const encodePayload = Option.map(endpoint.payloadSchema, Schema.encodeUnknown) diff --git a/packages/platform/src/ApiSchema.ts b/packages/platform/src/ApiSchema.ts index 72b77cb49b..ada64f1a21 100644 --- a/packages/platform/src/ApiSchema.ts +++ b/packages/platform/src/ApiSchema.ts @@ -3,7 +3,8 @@ */ import * as AST from "@effect/schema/AST" import * as Schema from "@effect/schema/Schema" -import { constVoid, identity } from "effect/Function" +import type { LazyArg } from "effect/Function" +import { constVoid, dual } from "effect/Function" import * as Struct from "effect/Struct" /** @@ -12,6 +13,14 @@ import * as Struct from "effect/Struct" */ export const AnnotationStatus: unique symbol = Symbol.for("@effect/platform/ApiSchema/AnnotationStatus") +/** + * @since 1.0.0 + * @category annotations + */ +export const AnnotationEmptyDecodeable: unique symbol = Symbol.for( + "@effect/platform/ApiSchema/AnnotationEmptyDecodeable" +) + /** * @since 1.0.0 * @category annotations @@ -26,6 +35,20 @@ export const getStatus = (ast: AST.AST, defaultStatus: number): number => { return annotations[AnnotationStatus] as number ?? defaultStatus } +/** + * @since 1.0.0 + * @category annotations + */ +export const getEmptyDecodeable = (ast: AST.AST): boolean => { + const annotations = ast._tag === "Transformation" ? + { + ...ast.to.annotations, + ...ast.annotations + } : + ast.annotations + return annotations[AnnotationEmptyDecodeable] as boolean ?? false +} + /** * @since 1.0.0 * @category annotations @@ -88,26 +111,47 @@ export const Empty = (status: number): typeof Schema.Void => Schema.Void.annotat * @since 1.0.0 * @category schemas */ -export interface asEmpty - extends Schema.transform> -{} +export interface asEmpty< + S extends Schema.Schema.Any +> extends Schema.transform {} /** * @since 1.0.0 * @category schemas */ -export const asEmpty = ( - self: S, - status: number -): asEmpty => - Schema.transform( - Schema.Void, - Schema.Union(self, Schema.Void), - { - decode: identity, - encode: constVoid +export const asEmpty: { + (options: { + readonly status: number + readonly decode: LazyArg> + }): (self: S) => asEmpty + ( + self: S, + options: { + readonly status: number + readonly decode?: LazyArg> + } + ): asEmpty +} = dual( + 2, + ( + self: S, + options: { + readonly status: number + readonly decode?: LazyArg> } - ).annotations(annotations({ status })) + ): asEmpty => + Schema.transform( + Schema.Void, + Schema.typeSchema(self), + { + decode: options.decode as any, + encode: constVoid + } + ).annotations(annotations({ + status: options.status, + [AnnotationEmptyDecodeable]: true + })) as any +) /** * @since 1.0.0 diff --git a/packages/platform/src/OpenApi.ts b/packages/platform/src/OpenApi.ts index f5dba963c9..85e4fed336 100644 --- a/packages/platform/src/OpenApi.ts +++ b/packages/platform/src/OpenApi.ts @@ -12,6 +12,7 @@ import type { DeepMutable, Mutable } from "effect/Types" import * as Api from "./Api.js" import type { ApiSecurity } from "./ApiSecurity.js" import * as HttpMethod from "./HttpMethod.js" +import { ApiSchema } from "./index.js" /** * @since 1.0.0 @@ -241,13 +242,21 @@ export const fromApi = (api: A): OpenAPISpec => { for (const [status, ast] of errors) { if (op.responses![status]) continue op.responses![status] = { - description: Option.getOrElse(AST.getDescriptionAnnotation(ast), () => "Error"), - content: { - "application/json": { - schema: makeJsonSchema(Schema.make(ast)) - } - } + description: ast.pipe( + Option.flatMap((ast) => AST.getDescriptionAnnotation(ast)), + Option.getOrElse(() => "Error") + ) } + ast.pipe( + Option.filter((ast) => !ApiSchema.getEmptyDecodeable(ast)), + Option.map((ast) => { + op.responses![status].content = { + "application/json": { + schema: makeJsonSchema(Schema.make(ast)) + } + } + }) + ) } if (!spec.paths[path]) { spec.paths[path] = {} From 972624d5a62ca94a3235e376f640fee642d8ea59 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 26 Aug 2024 10:53:33 +1200 Subject: [PATCH 29/59] openapi wip --- packages/platform/src/ApiBuilder.ts | 2 +- packages/platform/src/OpenApi.ts | 25 +++++++++++++++++-------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index 6692980016..9cf2656a3a 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -476,7 +476,7 @@ export const middlewareOpenApi = ( const response = yield* HttpServerResponse.json(spec).pipe( Effect.orDie ) - yield* router.get(options?.path ?? "/openapi.json", response) + yield* router.get(options?.path ?? "/openapi.json", Effect.succeed(response)) }) ) diff --git a/packages/platform/src/OpenApi.ts b/packages/platform/src/OpenApi.ts index 85e4fed336..526eefb45d 100644 --- a/packages/platform/src/OpenApi.ts +++ b/packages/platform/src/OpenApi.ts @@ -168,7 +168,7 @@ export const fromApi = (api: A): OpenAPISpec => { Api.reflect(api as any, { onGroup({ group }) { const tag: Mutable = { - name: group.name + name: Context.getOrElse(group.annotations, Title, () => group.name) } Option.map(Context.getOption(group.annotations, Description), (description) => { tag.description = description @@ -182,12 +182,15 @@ export const fromApi = (api: A): OpenAPISpec => { const path = endpoint.path.replace(/:(\w+)[^/]*/g, "{$1}") const method = endpoint.method.toLowerCase() as OpenAPISpecMethodName const op: DeepMutable = { - tags: [group.name], + tags: [Context.getOrElse(group.annotations, Title, () => group.name)], operationId: Context.getOrElse(endpoint.annotations, Identifier, () => `${group.name}.${endpoint.name}`), parameters: [], responses: { [success[1]]: { - description: "Success" + description: success[0].pipe( + Option.flatMap(AST.getDescriptionAnnotation), + Option.getOrElse(() => "Success") + ) } } } @@ -220,7 +223,7 @@ export const fromApi = (api: A): OpenAPISpec => { }) ) if (Option.isSome(endpoint.pathSchema)) { - getPropertySignatures(AST.encodedAST(endpoint.pathSchema.value.ast)).forEach((ps) => { + getPropertySignatures(endpoint.pathSchema.value.ast).forEach((ps) => { op.parameters!.push({ name: ps.name as string, in: "path", @@ -230,7 +233,7 @@ export const fromApi = (api: A): OpenAPISpec => { }) } if (!HttpMethod.hasBody(endpoint.method) && Option.isSome(endpoint.payloadSchema)) { - getPropertySignatures(AST.encodedAST(endpoint.payloadSchema.value.ast)).forEach((ps) => { + getPropertySignatures(endpoint.payloadSchema.value.ast).forEach((ps) => { op.parameters!.push({ name: ps.name as string, in: "query", @@ -243,7 +246,7 @@ export const fromApi = (api: A): OpenAPISpec => { if (op.responses![status]) continue op.responses![status] = { description: ast.pipe( - Option.flatMap((ast) => AST.getDescriptionAnnotation(ast)), + Option.flatMap(AST.getDescriptionAnnotation), Option.getOrElse(() => "Error") ) } @@ -270,11 +273,17 @@ export const fromApi = (api: A): OpenAPISpec => { const getPropertySignatures = (ast: AST.AST): ReadonlyArray => { switch (ast._tag) { + case "TypeLiteral": { + return ast.propertySignatures + } case "Union": { return ast.types.flatMap(getPropertySignatures) } - case "TypeLiteral": { - return ast.propertySignatures + case "Transformation": { + return getPropertySignatures(ast.from) + } + case "Suspend": { + return getPropertySignatures(ast.f()) } default: { return [] From d5b7a4aaab6fea89584e4b7c7426947212e50b04 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 26 Aug 2024 10:57:42 +1200 Subject: [PATCH 30/59] add Api.Service to ApiBuilder.serve --- packages/platform/src/ApiBuilder.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/platform/src/ApiBuilder.ts b/packages/platform/src/ApiBuilder.ts index 9cf2656a3a..cb458d692c 100644 --- a/packages/platform/src/ApiBuilder.ts +++ b/packages/platform/src/ApiBuilder.ts @@ -47,7 +47,7 @@ export class ApiRouter extends HttpRouter.Tag("@effect/platform/ApiBuilder/ApiRo * @category constructors */ export const serve: { - (): Layer.Layer + (): Layer.Layer ( middleware: (httpApp: HttpApp.Default) => HttpApp.Default ): Layer.Layer< @@ -55,6 +55,7 @@ export const serve: { never, | HttpServer.HttpServer | Exclude + | Api.Api.Service > } = (middleware?: HttpMiddleware.HttpMiddleware.Applied): Layer.Layer< never, From 52c3dbdbc0465b6f837efdf1ca1fd2c8c75aea62 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 26 Aug 2024 11:07:01 +1200 Subject: [PATCH 31/59] OpenApi property descriptions --- packages/platform/src/OpenApi.ts | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/packages/platform/src/OpenApi.ts b/packages/platform/src/OpenApi.ts index 526eefb45d..31d93fbadc 100644 --- a/packages/platform/src/OpenApi.ts +++ b/packages/platform/src/OpenApi.ts @@ -224,22 +224,12 @@ export const fromApi = (api: A): OpenAPISpec => { ) if (Option.isSome(endpoint.pathSchema)) { getPropertySignatures(endpoint.pathSchema.value.ast).forEach((ps) => { - op.parameters!.push({ - name: ps.name as string, - in: "path", - schema: makeJsonSchema(Schema.make(ps.type)), - required: !ps.isOptional - }) + op.parameters!.push(makeProperty(ps, "path")) }) } if (!HttpMethod.hasBody(endpoint.method) && Option.isSome(endpoint.payloadSchema)) { getPropertySignatures(endpoint.payloadSchema.value.ast).forEach((ps) => { - op.parameters!.push({ - name: ps.name as string, - in: "query", - schema: makeJsonSchema(Schema.make(ps.type)), - required: !ps.isOptional - }) + op.parameters!.push(makeProperty(ps, "query")) }) } for (const [status, ast] of errors) { @@ -291,6 +281,19 @@ const getPropertySignatures = (ast: AST.AST): ReadonlyArray { + const spec: Mutable = { + in: type, + name: ps.name as string, + schema: makeJsonSchema(Schema.make(ps.type)), + required: !ps.isOptional + } + Option.map(AST.getDescriptionAnnotation(ps), (description) => { + spec.description = description + }) + return spec +} + const makeJsonSchema = (schema: Schema.Schema.All): OpenAPIJSONSchema => { const jsonSchema = JSONSchema.make(schema as any) delete jsonSchema.$schema From 3ad8e168c81bbe60519e257417235487f857978b Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 26 Aug 2024 11:09:55 +1200 Subject: [PATCH 32/59] makeProperty description fallback --- packages/platform/src/OpenApi.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/platform/src/OpenApi.ts b/packages/platform/src/OpenApi.ts index 31d93fbadc..faeb06e706 100644 --- a/packages/platform/src/OpenApi.ts +++ b/packages/platform/src/OpenApi.ts @@ -288,9 +288,12 @@ const makeProperty = (ps: AST.PropertySignature, type: OpenAPISpecParameter["in" schema: makeJsonSchema(Schema.make(ps.type)), required: !ps.isOptional } - Option.map(AST.getDescriptionAnnotation(ps), (description) => { - spec.description = description - }) + AST.getDescriptionAnnotation(ps).pipe( + Option.orElse(() => AST.getDescriptionAnnotation(ps.type)), + Option.map((description) => { + spec.description = description + }) + ) return spec } From 357daec5cf00d713eb78ad2f67c9a1c38d6a14c6 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 26 Aug 2024 12:49:14 +1200 Subject: [PATCH 33/59] add swagger layer --- packages/platform-node/examples/api.ts | 29 +++++---- packages/platform/src/ApiSecurity.ts | 13 ++-- packages/platform/src/ApiSwagger.ts | 46 ++++++++++++++ packages/platform/src/OpenApi.ts | 64 +++++++++++++++++++- packages/platform/src/index.ts | 5 ++ packages/platform/src/internal/apiSwagger.ts | 7 +++ scripts/package-swagger.mjs | 22 +++++++ 7 files changed, 162 insertions(+), 24 deletions(-) create mode 100644 packages/platform/src/ApiSwagger.ts create mode 100644 packages/platform/src/internal/apiSwagger.ts create mode 100644 scripts/package-swagger.mjs diff --git a/packages/platform-node/examples/api.ts b/packages/platform-node/examples/api.ts index 29d8c4b094..9fa1838ec6 100644 --- a/packages/platform-node/examples/api.ts +++ b/packages/platform-node/examples/api.ts @@ -6,6 +6,7 @@ import { ApiGroup, ApiSchema, ApiSecurity, + ApiSwagger, HttpClient, HttpMiddleware, HttpServer, @@ -27,7 +28,7 @@ class Unauthorized extends Schema.TaggedError()("Unauthorized", { message: Schema.String }, ApiSchema.annotations({ status: 401 })) {} -const security = ApiSecurity.bearer() +const security = ApiSecurity.bearer const securityMiddleware = ApiBuilder.middlewareSecurity( security, @@ -61,7 +62,8 @@ const users = ApiGroup.make("users").pipe( ) ), ApiGroup.addError(Unauthorized), - ApiGroup.prefix("/users") + ApiGroup.prefix("/users"), + OpenApi.annotate({ security }) ) const api = Api.empty.pipe( @@ -97,6 +99,7 @@ const ApiLive = ApiBuilder.api(api).pipe( ) ApiBuilder.serve(HttpMiddleware.logger).pipe( + Layer.provide(ApiSwagger.layer()), Layer.provide(ApiBuilder.middlewareOpenApi()), Layer.provide(ApiLive), Layer.provide(ApiBuilder.middlewareCors()), @@ -106,14 +109,14 @@ ApiBuilder.serve(HttpMiddleware.logger).pipe( NodeRuntime.runMain ) -Effect.gen(function*() { - yield* Effect.sleep(2000) - const client = yield* ApiClient.make(api, { - baseUrl: "http://localhost:3000" - }) - const user = yield* client.users.findById({ path: { id: 123 } }) - console.log(user) -}).pipe( - Effect.provide(HttpClient.layer), - NodeRuntime.runMain -) +// Effect.gen(function*() { +// yield* Effect.sleep(2000) +// const client = yield* ApiClient.make(api, { +// baseUrl: "http://localhost:3000" +// }) +// const user = yield* client.users.findById({ path: { id: 123 } }) +// console.log(user) +// }).pipe( +// Effect.provide(HttpClient.layer), +// NodeRuntime.runMain +// ) diff --git a/packages/platform/src/ApiSecurity.ts b/packages/platform/src/ApiSecurity.ts index 5409a73c89..218838559d 100644 --- a/packages/platform/src/ApiSecurity.ts +++ b/packages/platform/src/ApiSecurity.ts @@ -54,7 +54,6 @@ export declare namespace ApiSecurity { */ export interface Bearer extends ApiSecurity.Proto { readonly _tag: "Bearer" - readonly prefix: string } /** @@ -95,14 +94,10 @@ const Proto = { * @since 1.0.0 * @category constructors */ -export const bearer = (options?: { - readonly prefix?: string | undefined -}): Bearer => - Object.assign(Object.create(Proto), { - _tag: "Bearer", - prefix: options?.prefix ?? "Bearer", - annotations: Context.empty() - }) +export const bearer: Bearer = Object.assign(Object.create(Proto), { + _tag: "Bearer", + annotations: Context.empty() +}) /** * @since 1.0.0 diff --git a/packages/platform/src/ApiSwagger.ts b/packages/platform/src/ApiSwagger.ts new file mode 100644 index 0000000000..aced42ee85 --- /dev/null +++ b/packages/platform/src/ApiSwagger.ts @@ -0,0 +1,46 @@ +/** + * @since 1.0.0 + */ +import * as Effect from "effect/Effect" +import type { Layer } from "effect/Layer" +import { Api } from "./Api.js" +import { ApiRouter } from "./ApiBuilder.js" +import * as HttpServerResponse from "./HttpServerResponse.js" +import * as internal from "./internal/apiSwagger.js" +import * as OpenApi from "./OpenApi.js" + +/** + * @since 1.0.0 + * @category layers + */ +export const layer = (options?: { + readonly path?: `/${string}` | undefined +}): Layer => + ApiRouter.use((router) => + Effect.gen(function*() { + const api = yield* Api + const spec = OpenApi.fromApi(api) + const response = HttpServerResponse.html(` + + + + + ${spec.info.title} Documentation + + + +