{"version":3,"file":"index.cjs","sources":["../../src/types/addressbook.ts","../../src/types/calls.ts","../../src/types/chat.ts","../../src/types/config.ts","../../src/types/janus.ts","../../src/types/media.ts","../../src/types/proxy.ts","../../src/platform.node.ts","../../src/config.ts","../../src/Utils.ts","../../src/Proxy.ts","../../src/AddressBook.ts","../../src/Auth.ts","../../../../node_modules/ltx/lib/escape.js","../../../../node_modules/ltx/lib/Element.js","../../../../node_modules/ltx/lib/createElement.js","../../../../node_modules/ltx/lib/parsers/ltx.js","../../../../node_modules/@xmpp/events/lib/TimeoutError.js","../../../../node_modules/@xmpp/events/lib/timeout.js","../../../../node_modules/@xmpp/events/lib/delay.js","../../../../node_modules/@xmpp/events/lib/onoff.js","../../../../node_modules/@xmpp/events/lib/promise.js","../../../../node_modules/@xmpp/events/lib/Deferred.js","../../../../node_modules/@xmpp/events/lib/procedure.js","../../../../node_modules/@xmpp/events/lib/listeners.js","../../../../node_modules/@xmpp/xml/lib/XMLError.js","../../../../node_modules/@xmpp/xml/lib/Parser.js","../../../../node_modules/@xmpp/xml/index.js","../../../../node_modules/@xmpp/jid/lib/escaping.js","../../../../node_modules/@xmpp/jid/lib/JID.js","../../../../node_modules/@xmpp/jid/lib/parse.js","../../../../node_modules/@xmpp/jid/index.js","../../../../node_modules/@xmpp/error/index.js","../../../../node_modules/@xmpp/connection/lib/StreamError.js","../../../../node_modules/@xmpp/connection/lib/util.js","../../../../node_modules/@xmpp/connection/index.js","../../../../node_modules/@xmpp/client-core/lib/Client.js","../../../../node_modules/@xmpp/reconnect/index.js","../../../../node_modules/@xmpp/websocket/lib/Socket.js","../../../../node_modules/@xmpp/websocket/lib/Connection.js","../../../../node_modules/@xmpp/websocket/lib/FramedParser.js","../../../../node_modules/@xmpp/connection-tcp/Socket.js","../../../../node_modules/@xmpp/connection-tcp/index.js","../../../../node_modules/@xmpp/tcp/lib/Connection.js","../../../../node_modules/@xmpp/tcp/index.js","../../../../node_modules/@xmpp/tls/lib/Socket.js","../../../../node_modules/@xmpp/tls/lib/Connection.js","../../../../node_modules/@xmpp/tls/index.js","../../../../node_modules/koa-compose/index.js","../../../../node_modules/@xmpp/middleware/lib/Context.js","../../../../node_modules/@xmpp/middleware/lib/IncomingContext.js","../../../../node_modules/@xmpp/middleware/lib/OutgoingContext.js","../../../../node_modules/@xmpp/middleware/index.js","../../../../node_modules/@xmpp/middleware/lib/StanzaError.js","../../../../node_modules/@xmpp/iq/caller.js","../../../../node_modules/@xmpp/id/index.js","../../../../node_modules/@xmpp/iq/callee.js","../../../../node_modules/@xmpp/resolve/lib/dns.js","../../../../node_modules/@xmpp/resolve/lib/alt-connections.js","../../../../node_modules/@xmpp/resolve/lib/http.js","../../../../node_modules/@xmpp/xml/lib/parse.js","../../../../node_modules/@xmpp/resolve/index.js","../../../../node_modules/@xmpp/resolve/resolve.js","../../../../node_modules/@xmpp/starttls/index.js","../../../../node_modules/@xmpp/starttls/starttls.js","../../../../node_modules/@xmpp/base64/index.js","../../../../node_modules/@xmpp/sasl/lib/SASLError.js","../../../../node_modules/@xmpp/sasl/index.js","../../../../node_modules/@xmpp/sasl2/index.js","../../../../node_modules/@xmpp/resource-binding/index.js","../../../../node_modules/@xmpp/client-core/src/bind2/bind2.js","../../../../node_modules/saslmechanisms/main.js","../../../../node_modules/saslmechanisms/lib/factory.js","../../../../node_modules/@xmpp/client-core/src/fast/fast.js","../../../../node_modules/create-hash/index.js","../../../../node_modules/create-hmac/index.js","../../../../node_modules/sasl-scram-sha-1/lib/bitops.js","../../../../node_modules/sasl-scram-sha-1/lib/utils.js","../../../../node_modules/randombytes/index.js","../../../../node_modules/sasl-scram-sha-1/index.js","../../../../node_modules/@xmpp/sasl-scram-sha-1/index.js","../../../../node_modules/sasl-plain/main.js","../../../../node_modules/sasl-plain/lib/mechanism.js","../../../../node_modules/@xmpp/sasl-plain/index.js","../../../../node_modules/sasl-anonymous/main.js","../../../../node_modules/sasl-anonymous/lib/mechanism.js","../../../../node_modules/@xmpp/sasl-anonymous/index.js","../../../../node_modules/@xmpp/sasl-ht-sha-256-none/index.js","../../src/messaging/xmpp/xmpp.utils.ts","../../src/messaging/xmpp/ChatUtils.ts","../../src/messaging/xmpp/xmpp.node.ts","../../../../node_modules/@xmpp/websocket/index.js","../../../../node_modules/@xmpp/stream-features/index.js","../../src/messaging/xmpp/Helpers.ts","../../src/messaging/xmpp/StreamManagement.ts","../../src/messaging/xmpp/PrivacyList.ts","../../src/messaging/xmpp/MultiUserChat.ts","../../src/messaging/xmpp/Dialogs.ts","../../src/messaging/xmpp/Messages.ts","../../src/videocalling/WebRTCSignalingProcessor.ts","../../src/messaging/AbstractChatService.ts","../../src/messaging/xmpp/index.ts","../../../../node_modules/@sama-communications/sdk/dist/@sama-communications.sdk.mjs","../../src/messaging/sama/BlockList.ts","../../src/messaging/sama/index.ts","../../src/videocalling_conference/janus.js","../../src/videocalling_conference/JanusClient.ts","../../src/videocalling_conference/ConferenceSession.ts","../../src/videocalling_conference/ConferenceClient.ts","../../src/Data.ts","../../src/Meetings.ts","../../src/PushNotifications.ts","../../src/Storage.ts","../../src/Users.ts","../../src/videocalling/WebRTCHelpers.ts","../../src/videocalling/WebRTCPeerConnection.ts","../../src/videocalling/WebRTCSignalingProvider.ts","../../src/videocalling/WebRTCSession.ts","../../src/videocalling/WebRTCClient.ts","../../src/Whiteboard.ts","../../src/LinkPreview.ts","../../src/ConnectyCube.ts","../../src/index.ts","../../src/types/data.ts","../../src/types/pushnotifications.ts","../../src/types/dialogs.ts","../../src/types/auth.ts","../../src/types/meetings.ts"],"sourcesContent":["import type { ForceParams } from './common';\nimport type { ConnectyCubeUsers } from './users';\n\nexport const AddressBookUserDataType = {\n  COMPACT: 1,\n  FULL: 0,\n} as const;\nexport type AddressBookUserDataType = (typeof AddressBookUserDataType)[keyof typeof AddressBookUserDataType];\n\nexport namespace ConnectyCubeAddressBook {\n  export type Contact = { name: string; phone: string; destroy?: number | string };\n  // Request parameters type\n  export type UploadParams = { udid?: string } & ForceParams;\n  export type GetRegisteredUsersParams = boolean | { udid?: string; compact: AddressBookUserDataType | number }; // 1 - compact user data, 0 - full user data\n  // Response data types\n  export type UploadResponse = {\n    deleted: number;\n    rejected: Record<string | number, string[]>;\n    created: number;\n    updated: number;\n  };\n  export type GetRegisteredUsersResponse = {\n    items: Partial<ConnectyCubeUsers.User> & { address_book_name: string }[];\n  };\n}\n","import type { PlainObject } from './common';\nimport type WebRTCSession from '../videocalling/WebRTCSession';\nimport type WebRTCSignalingProvider from '../videocalling/WebRTCSignalingProvider';\n\nexport const CallSignalingModuleIdentifier = 'WebRTCVideoChat';\n\nexport const CallSignalingType = {\n  CALL: 'call',\n  ACCEPT: 'accept',\n  REJECT: 'reject',\n  STOP: 'hangUp',\n  RESTART: 'iceRestart',\n  RESTART_ACCEPT: 'iceRestartAccept',\n  CANDIDATE: 'iceCandidates',\n} as const;\nexport type CallSignalingType = (typeof CallSignalingType)[keyof typeof CallSignalingType];\n\nexport const CallSessionConnectionState = {\n  UNDEFINED: 0,\n  CONNECTING: 1,\n  CONNECTED: 2,\n  FAILED: 3,\n  DISCONNECTED: 4,\n  CLOSED: 5,\n  COMPLETED: 6,\n} as const;\nexport type CallSessionConnectionState = (typeof CallSessionConnectionState)[keyof typeof CallSessionConnectionState];\n\nexport const CallSessionState = {\n  NEW: 1,\n  ACTIVE: 2,\n  STOPPED: 3,\n  REJECTED: 4,\n  CLOSED: 5,\n} as const;\nexport type CallSessionState = (typeof CallSessionState)[keyof typeof CallSessionState];\n\nexport const CallType = {\n  VIDEO: 1,\n  AUDIO: 2,\n} as const;\nexport type CallType = (typeof CallType)[keyof typeof CallType];\n\nexport const CallEvent = {\n  CALL: 'call',\n  ACCEPT: 'accept',\n  REJECT: 'reject',\n  STOP: 'stop',\n  INVALID: 'invalid',\n  NOT_ANSWER: 'not-answer',\n  REMOTE_STREAM: 'remote-stream',\n  CONNECTION_STATE: 'connection-state',\n  CLOSE: 'close',\n  STATS_REPORT: 'stats-report',\n  DEVICES: 'devices',\n} as const;\nexport type CallEvent = (typeof CallEvent)[keyof typeof CallEvent];\n\nexport const PeerConnectionState = {\n  NEW: 1,\n  CONNECTING: 2,\n  CHECKING: 3,\n  CONNECTED: 4,\n  DISCONNECTED: 5,\n  FAILED: 6,\n  CLOSED: 7,\n  COMPLETED: 8,\n} as const;\nexport type PeerConnectionState = (typeof PeerConnectionState)[keyof typeof PeerConnectionState];\n\nexport namespace ConnectyCubeCalls {\n  export type StatsReportObj = {\n    audio: PlainObject;\n    video: PlainObject;\n    candidate: PlainObject;\n  };\n  export type UserInfo<UserInfoExtra = PlainObject> = {\n    maxBandwidth?: number;\n    bandwidth?: number;\n  } & UserInfoExtra;\n  export type ExtensionParams<Extra = PlainObject, UserInfoExtra = PlainObject> = {\n    callType?: number;\n    callerID?: number;\n    iceCandidates?: RTCIceCandidateInit[];\n    opponentsIDs?: number[];\n    userInfo?: UserInfo<UserInfoExtra>;\n    sessionID?: string;\n    moduleIdentifier?: string;\n    signalType?: string;\n    platform?: string;\n    sdp?: string;\n  } & Extra;\n  export type Session = WebRTCSession;\n  export type SignalingProvider = WebRTCSignalingProvider;\n  export type SessionParams = {\n    ID: string | null;\n    initiatorID: number;\n    opponentsIDs: number[];\n    callType: CallType;\n    signalingProvider: SignalingProvider;\n    currentUserID: number;\n    maxBandwidth: number;\n  };\n  // Listeners\n  export type OnCallListener = (session: Session, userInfo: UserInfo) => void;\n  export type OnAcceptCallListener = (session: Session, userID: number, userInfo: UserInfo) => void;\n  export type OnRejectCallListener = (session: Session, userID: number, userInfo: UserInfo) => void;\n  export type OnStopCallListener = (session: Session, userID: number, userInfo: UserInfo) => void;\n  export type OnInvalidEventsListener = (session: Session, userID: number, userInfo: UserInfo) => void;\n  export type OnUserNotAnswerListener = (session: Session, userID: number) => void;\n  export type OnRemoteStreamListener = (session: Session, userID: number, stream: MediaStream) => void;\n  export type OnSessionConnectionStateChangedListener = (\n    session: Session,\n    userID: number,\n    connectionState: CallSessionConnectionState\n  ) => void;\n  export type OnSessionCloseListener = (session: Session) => void;\n  export type OnCallStatsReportListener = (session: Session, userID: number, stats: RTCStatsReport, error: Error) => void;\n  export type OnDevicesChangeListener = ((this: MediaDevices, ev: Event) => void) | ((ev: Event) => void);\n  export type Listeners =\n    | OnCallListener\n    | OnAcceptCallListener\n    | OnRejectCallListener\n    | OnStopCallListener\n    | OnInvalidEventsListener\n    | OnUserNotAnswerListener\n    | OnRemoteStreamListener\n    | OnSessionConnectionStateChangedListener\n    | OnSessionCloseListener\n    | OnCallStatsReportListener\n    | OnDevicesChangeListener;\n  export type ListenerName =\n    | 'onCallListener'\n    | 'onAcceptCallListener'\n    | 'onRejectCallListener'\n    | 'onStopCallListener'\n    | 'onInvalidEventsListener'\n    | 'onUserNotAnswerListener'\n    | 'onRemoteStreamListener'\n    | 'onSessionConnectionStateChangedListener'\n    | 'onSessionCloseListener'\n    | 'onCallStatsReport'\n    | 'onDevicesChangeListener';\n}\n","import type { Element, Node } from '@xmpp/xml';\nimport type { StatusEvents } from '@xmpp/connection';\nimport type { VoidCallback, PlainObject } from './common';\nimport type { ConnectyCubeCalls } from './calls';\nimport type { ConnectyCubeDialogs } from './dialogs';\nimport type { ConnectyCubeUsers } from './users';\nimport type { ConnectyCubeMessages } from './messages';\nimport type ChatHelpers from '../messaging/xmpp/Helpers';\nimport type PrivacyList from '../messaging/xmpp/PrivacyList';\nimport type BlockList from '../messaging/sama/BlockList';\nimport type MultiUserChat from '../messaging/xmpp/MultiUserChat';\nimport type StreamManagement from '../messaging/xmpp/StreamManagement';\n\nexport const ChatType = {\n  CHAT: 'chat',\n  GROUPCHAT: 'groupchat',\n} as const;\nexport type ChatType = (typeof ChatType)[keyof typeof ChatType];\n\nexport const ChatEvent = {\n  STATUS: 'status',\n  ERROR: 'error',\n  DISCONNECTED: 'disconnected',\n  RECONNECTED: 'reconnected',\n  MESSAGE: 'message',\n  SYSTEM_MESSAGE: 'system-message',\n  ERROR_MESSAGE: 'error-message',\n  TYPING_MESSAGE: 'typing-message',\n  UPDATE_MESSAGE: 'update-message',\n  DELETE_MESSAGE: 'delete-message',\n  REACTIONS_MESSAGE: 'reactions-message',\n  DELIVERED_MESSAGE: 'delivered-message',\n  READ_MESSAGE: 'read-message',\n  SENT_MESSAGE: 'sent-message',\n  USER_LAST_ACTIVITY: 'user-last-activity',\n  JOIN: 'join',\n  LEAVE: 'leave',\n  KICK: 'kick',\n} as const;\nexport type ChatEvent = (typeof ChatEvent)[keyof typeof ChatEvent];\n\nexport const PrivacyListAction = {\n  ALLOW: 'allow',\n  DENY: 'deny',\n} as const;\nexport type PrivacyListAction = (typeof PrivacyListAction)[keyof typeof PrivacyListAction];\nexport namespace ConnectyCubeChat {\n  export type XmlElement = Element;\n  export type XmlNode = Node;\n  export type StanzaCallback = (stanza: Element) => void;\n  export type StanzasCallbacks = { [stanzaId: string]: StanzaCallback };\n  export type ConnectionParams = { userId: number; password: string; deviceId?: string };\n  export type ConnectionStatus = keyof StatusEvents;\n\n  export type MessageExtension<Extra = PlainObject, AttachmentExtra = PlainObject, UserInfoExtra = PlainObject> = {\n    date_sent?: string | number;\n    attachments?: ConnectyCubeMessages.Attachment<AttachmentExtra>[];\n    dialog_id?: string;\n    dialogId?: string;\n    addedParticipantsIds?: string;\n    removedParticipantsIds?: string;\n    save_to_history?: number;\n    iceCandidates?: RTCIceCandidateInit[];\n    opponentsIDs?: number[];\n    moduleIdentifier?: string;\n    sdp?: string;\n    sessionID?: string;\n    signalType?: string;\n    callType?: number;\n    callerID?: number;\n    platform?: string;\n    userInfo?: ConnectyCubeCalls.UserInfo<UserInfoExtra>;\n  } & Extra;\n\n  export type ParseExtraParamsResult<\n    Extra = PlainObject,\n    AttachmentExtra = PlainObject,\n    UserInfoExtra = PlainObject,\n  > = { extension: MessageExtension<Extra, AttachmentExtra, UserInfoExtra>; dialogId: string | null };\n  export type ParseReactionsResult = { add: string | null; remove: string | null };\n\n  export type MessageParams<Extra = PlainObject, AttachmentExtra = PlainObject, UserInfoExtra = PlainObject> = {\n    id?: string;\n    type?: ChatType | string;\n    body?: string | null;\n    extension?: MessageExtension<Extra, AttachmentExtra, UserInfoExtra>;\n  };\n  export type Message<Extra = PlainObject, AttachmentExtra = PlainObject, UserInfoExtra = PlainObject> = {\n    id: string;\n    dialog_id: string | null;\n    recipient_id?: string | number | null;\n    is_forwarded?: boolean;\n    type?: ChatType | string;\n    body: string | null;\n    extension: MessageExtension<Extra, AttachmentExtra, UserInfoExtra> | null;\n    delay?: unknown;\n  };\n  export type SystemMessageParams<Extra = PlainObject, AttachmentExtra = PlainObject, UserInfoExtra = PlainObject> = {\n    id?: string;\n    body?: string | null;\n    extension?: MessageExtension<Extra, AttachmentExtra, UserInfoExtra>;\n  };\n  export type SystemMessage<Extra = PlainObject, AttachmentExtra = PlainObject, UserInfoExtra = PlainObject> = {\n    id: string;\n    body: string;\n    userId: number;\n    extension: MessageExtension<Extra, AttachmentExtra, UserInfoExtra> | null;\n  };\n  export type MessageStatusParams = {\n    messageId: string;\n    dialogId: string;\n    userId?: number;\n  };\n  export type DialogReadParams = {\n    dialogId: string;\n  };\n  export type EditMessageParams<Extra = PlainObject, AttachmentExtra = PlainObject, UserInfoExtra = PlainObject> = {\n    to?: string | number;\n    dialogId: string;\n    body: string;\n    originMessageId: string;\n    extension?: MessageExtension<Extra, AttachmentExtra, UserInfoExtra>;\n    last?: boolean;\n  };\n  export type DeleteMessageParams = {\n    to?: string | number;\n    dialogId: string;\n    messageId: string;\n  };\n  export type LastActivity = {\n    userId: number | null;\n    seconds: number;\n  };\n  export type SearchParams = {\n    search_text?: string;\n    start_date?: number | string | Date;\n    end_date?: number | string | Date;\n    chat_dialog_ids?: string | string[];\n  };\n  export type SearchResult = {\n    results: {\n      dialogs: ConnectyCubeDialogs.Dialog[];\n      messages: unknown[];\n      users: ConnectyCubeUsers.User[];\n    };\n  } & PlainObject;\n  export type UserJIDParams = {\n    userId?: number;\n    resource?: string;\n    jid?: string;\n  } & PlainObject;\n  // XMPP client events and listeners\n  export type XMPPClientEvent = string | symbol;\n  export type XMPPClientListener = VoidCallback;\n  export type XMPPClientListeners = Map<XMPPClientEvent, XMPPClientListener>;\n  // Chat listeners\n  export type OnChatStatusListener = (status: ConnectionStatus) => void;\n  export type OnChatConnectionErrorListener = (error: Error) => void;\n  export type OnChatDisconnectedListener = () => void;\n  export type OnChatReconnectedListener = () => void;\n  export type OnMessageListener = (userId: number, message: Message) => void;\n  export type OnMessageSystemListener = (message: SystemMessage) => void;\n  export type OnMessageErrorListener = (messageId: string, error: { code: number; info: string }) => void;\n  export type OnMessageTypingListener = (typing: boolean, userId: number, dialogId: string) => void;\n  export type OnMessageUpdateListener = (\n    messageId: string,\n    isLast: boolean,\n    updatedBody: string,\n    dialogId: string,\n    userId: number,\n    extraParams: object | null\n  ) => void;\n  export type OnMessageDeleteListener = (messageId: string, dialogId: string, userId: number) => void;\n  export type OnMessageReactionsListener = (\n    messageId: string,\n    userId: number,\n    dialogId: string,\n    add: string,\n    remove: string\n  ) => void;\n  export type OnMessageDeliveredListener = (messageId: string, dialogId: string, userId: number) => void;\n  export type OnMessageReadListener = (messageId: string, dialogId: string, userId: number) => void;\n  export type OnMessageSentListener = (lost: MessageParams | null, sent: MessageParams | null) => void;\n  export type OnLastUserActivityListener = (userId: number, seconds: number) => void;\n  export type OnDialogJoinListener = (dialogId: string, userId: number) => void;\n  export type OnDialogLeaveListener = (dialogId: string, userId: number) => void;\n  export type OnDialogKickListener = (dialogId: string, initiatorId: number) => void;\n  export type Listeners =\n    | OnChatStatusListener\n    | OnChatConnectionErrorListener\n    | OnChatDisconnectedListener\n    | OnChatReconnectedListener\n    | OnMessageListener\n    | OnMessageSystemListener\n    | OnMessageErrorListener\n    | OnMessageTypingListener\n    | OnMessageUpdateListener\n    | OnMessageDeleteListener\n    | OnMessageReactionsListener\n    | OnMessageDeliveredListener\n    | OnMessageReadListener\n    | OnMessageSentListener\n    | OnLastUserActivityListener\n    | OnDialogJoinListener\n    | OnDialogLeaveListener\n    | OnDialogKickListener;\n  export type ListenerName =\n    | 'onChatStatusListener'\n    | 'onConnectionErrorListener'\n    | 'onDisconnectedListener'\n    | 'onReconnectListener'\n    | 'onMessageListener'\n    | 'onSystemMessageListener'\n    | 'onMessageErrorListener'\n    | 'onMessageTypingListener'\n    | 'onMessageUpdateListener'\n    | 'onMessageDeleteListener'\n    | 'onMessageReactionsListener'\n    | 'onDeliveredStatusListener'\n    | 'onReadStatusListener'\n    | 'onSentMessageCallback'\n    | 'onLastUserActivityListener'\n    | 'onJoinOccupant'\n    | 'onLeaveOccupant'\n    | 'onKickOccupant';\n  // PrivacyList\n  export type PrivacyListItem = {\n    user_id: string | number;\n    action: PrivacyListAction | string;\n    mutualBlock?: boolean;\n  };\n  export type PrivacyList = {\n    name: string;\n    items: PrivacyListItem[];\n  };\n  export type PrivacyListNames = {\n    default: string | null;\n    active: string | null;\n    names: string[];\n  };\n  export type PrivacyListItemParams = {\n    value: string;\n    action: string;\n    order: number;\n    isMutual: boolean;\n  };\n  export type DialogId = string;\n  export type UserId = number;\n}\n\nexport interface ChatRealTimeService {\n  onChatStatusListener: ConnectyCubeChat.OnChatStatusListener;\n  onConnectionErrorListener: ConnectyCubeChat.OnChatConnectionErrorListener;\n  onDisconnectedListener: ConnectyCubeChat.OnChatDisconnectedListener;\n  onReconnectListener: ConnectyCubeChat.OnChatReconnectedListener;\n  onMessageListener: ConnectyCubeChat.OnMessageListener;\n  onSystemMessageListener: ConnectyCubeChat.OnMessageSystemListener;\n  onMessageTypingListener: ConnectyCubeChat.OnMessageTypingListener;\n  onMessageUpdateListener: ConnectyCubeChat.OnMessageUpdateListener;\n  onMessageDeleteListener: ConnectyCubeChat.OnMessageDeleteListener;\n  onMessageReactionsListener: ConnectyCubeChat.OnMessageReactionsListener;\n  onReadStatusListener: ConnectyCubeChat.OnMessageReadListener;\n  onLastUserActivityListener: ConnectyCubeChat.OnLastUserActivityListener;\n\n  get connectionStatus(): string;\n  get currentUserId(): ConnectyCubeChat.UserId;\n\n  connect(params: ConnectyCubeChat.ConnectionParams): Promise<boolean>;\n  disconnect(): Promise<boolean>;\n  terminate(): void;\n\n  ping(): Promise<void>;\n  pingWithTimeout(timeout: number): Promise<unknown>;\n\n  send(\n    dialogId: ConnectyCubeChat.DialogId | ConnectyCubeChat.UserId,\n    message: ConnectyCubeChat.MessageParams\n  ): string | Promise<string>;\n  sendSystemMessage(\n    userId: ConnectyCubeChat.UserId | ConnectyCubeChat.UserId[],\n    message: ConnectyCubeChat.SystemMessageParams\n  ): string | Promise<string>;\n  sendWebRTCSignalingMessage(\n    userId: ConnectyCubeChat.UserId,\n    message: ConnectyCubeChat.SystemMessageParams\n  ): string | Promise<string>;\n\n  sendIsTypingStatus(dialogId: ConnectyCubeChat.DialogId | ConnectyCubeChat.UserId): void | Promise<void>;\n  sendIsStopTypingStatus(dialogId: ConnectyCubeChat.DialogId | ConnectyCubeChat.UserId): void | Promise<void>;\n\n  sendDeliveredStatus(params: ConnectyCubeChat.MessageStatusParams): void | Promise<void>;\n  sendReadStatus(params: ConnectyCubeChat.MessageStatusParams): void | Promise<void>;\n\n  editMessage(params: ConnectyCubeChat.EditMessageParams): void | Promise<void>;\n  deleteMessage(params: ConnectyCubeChat.DeleteMessageParams): void | Promise<void>;\n\n  getLastUserActivity(userId: ConnectyCubeChat.UserId): Promise<ConnectyCubeChat.LastActivity>;\n  subscribeToUserLastActivityStatus(userId: ConnectyCubeChat.UserId): void;\n  unsubscribeFromUserLastActivityStatus(userId?: ConnectyCubeChat.UserId): void;\n\n  markActive(): void;\n  markInactive(): void;\n\n  addListener(name: ChatEvent, listener: ConnectyCubeChat.Listeners): () => void;\n  removeListener(name: ChatEvent): void;\n  removeAllListeners(): void;\n}\n\nexport interface XMPPChatRealTimeService extends ChatRealTimeService {\n  readonly helpers: ChatHelpers;\n  readonly muc: MultiUserChat;\n  readonly privacylist: PrivacyList;\n  readonly streamManagement: StreamManagement;\n}\n\nexport interface SAMAChatRealTimeService extends ChatRealTimeService {\n  readonly blockList: BlockList;\n}\n","import type { ConnectyCubeAuth } from './auth';\nimport type { Config } from '../config';\n\nexport const ChatProtocol = {\n  BOSH: 1,\n  WS: 2,\n} as const;\nexport type ChatProtocol = (typeof ChatProtocol)[keyof typeof ChatProtocol];\n\nexport const JanusDebugMode = {\n  ALL: 'all',\n  TRACE: 'trace',\n  DEBUG: 'debug',\n  VDEBUG: 'vdebug',\n  LOG: 'log',\n  WARN: 'warn',\n  ERROR: 'error',\n} as const;\nexport type JanusDebugMode = (typeof JanusDebugMode)[keyof typeof JanusDebugMode];\n\nexport const ChatAPIs = {\n  SAMA: 'sama',\n  XMPP: 'xmpp',\n} as const;\nexport type ChatAPIs = (typeof ChatAPIs)[keyof typeof ChatAPIs];\n\nexport namespace ConnectyCubeConfig {\n  export type Object = Partial<Config>;\n  export type Credentials = {\n    appId: number | string;\n    authKey?: string;\n    token?: string;\n    systemApiKey?: string;\n    authSecret?: string;\n  };\n  export type Endpoints = { api: string; api_url?: string; chat: string; chat_url?: string; muc?: string };\n  export type ChatProtocolURLs = { bosh?: string; websocket?: string; active?: ChatProtocol | number };\n  export type ChatStreamManagement = { enable: boolean; acknowledgementTimeout?: number };\n  export type ChatReconnect = { enable: boolean; timeInterval: number };\n  export type Chat = {\n    streamManagement?: ChatStreamManagement;\n    reconnect?: ChatReconnect;\n    apiImp?: ChatAPIs;\n  };\n  export type VideochatIceServer = {\n    urls: string | string[];\n    url?: string;\n    credential?: string;\n    username?: string;\n  };\n  export type Videochat = {\n    alwaysRelayCalls?: boolean;\n    answerTimeInterval?: number;\n    dialingTimeInterval?: number;\n    disconnectTimeInterval?: number;\n    statsReportTimeInterval?: number | null;\n    iceServers?: VideochatIceServer[];\n  };\n  export type JanusDebug = JanusDebugMode | JanusDebugMode[] | boolean;\n  export type Conference = {\n    server: string;\n    debug?: JanusDebug;\n  };\n  export type Whiteboard = {\n    server: string;\n  };\n  export type LinkPreview = {\n    server: string;\n  };\n  export type ApiRoutes = {\n    session: string;\n    login: string;\n    users: string;\n    chat: string;\n    blobs: string;\n    subscriptions: string;\n    events: string;\n    data: string;\n    addressbook: string;\n    meetings: string;\n    whiteboards: string;\n    unfurl: string;\n    calls: string;\n    type: string;\n  };\n  export type SessionHandlerResponse = () => void;\n  export type SessionRetryCallback = (session: Partial<ConnectyCubeAuth.Session>) => void;\n  export type SessionExpiredListener = (\n    handler: SessionHandlerResponse,\n    retry: SessionRetryCallback\n  ) => void | Promise<void>;\n  export type XMPPData = { body?: string; headers?: string };\n  export type XMPPDataListener = (size: number, data?: XMPPData | null) => void;\n  export type Listeners = {\n    sessionExpired?: SessionExpiredListener;\n    xmppDataWrite?: XMPPDataListener;\n    xmppDataRead?: XMPPDataListener;\n  };\n  export type Debug = { mode: number | boolean };\n  export type Options = {\n    creds?: Credentials;\n    endpoints?: Endpoints;\n    chatProtocol?: ChatProtocolURLs;\n    chat?: Chat;\n    videochat?: Videochat;\n    conference?: Conference;\n    whiteboard?: Whiteboard;\n    on?: Listeners;\n    timeout?: number;\n    debug?: Debug;\n  };\n}\n","import type ConferenceSession from '../videocalling_conference/ConferenceSession';\nimport type { VoidCallback } from './common';\n\nexport const DeviceInputType = {\n  VIDEO: 'videoinput',\n  AUDIO: 'audioinput',\n} as const;\nexport type DeviceInputType = (typeof DeviceInputType)[keyof typeof DeviceInputType];\n\nexport const JanusEvent = {\n  PARTICIPANT_JOINED: 'participant_joined',\n  PARTICIPANT_LEFT: 'participant_left',\n  LOCAL_STREAM: 'local_stream',\n  REMOTE_STREAM: 'remote_stream',\n  REMOTE_TRACKS_UPDATED: 'remote_tracks_updated',\n  DATA_CHANNEL_OPEN: 'data_channel_open',\n  DATA_CHANNEL_MESSAGE: 'data_channel_message',\n  ERROR: 'error',\n} as const;\nexport type JanusEvent = (typeof JanusEvent)[keyof typeof JanusEvent];\n\nexport const JanusCallType = {\n  VIDEO: 'video',\n  AUDIO: 'audio',\n} as const;\nexport type JanusCallType = (typeof JanusCallType)[keyof typeof JanusCallType];\n\nexport const JanusMediaTrackReason = {\n  CREATED: 'created',\n  ENDED: 'ended',\n  MUTE: 'mute',\n  UNMUTE: 'unmute',\n} as const;\nexport type JanusMediaTrackReason = (typeof JanusMediaTrackReason)[keyof typeof JanusMediaTrackReason];\n\nexport const ConferenceEvent = {\n  JOIN: 'join',\n  LEFT: 'left',\n  SLOW_LINK: 'slow-link',\n  REMOTE_TRACKS_UPDATED: 'remote-tracks',\n  REMOTE_STREAM: 'remote-stream',\n  REMOTE_CONNECTION_STATE: 'remote-connection-state',\n  DATA_CHANNEL_OPENED: 'data-channel-opened',\n  DATA_CHANNEL_MESSAGE: 'data-channel-message',\n  SESSION_CONNECTION_STATE: 'session-connection-state',\n  ERROR: 'error',\n} as const;\nexport type ConferenceEvent = (typeof ConferenceEvent)[keyof typeof ConferenceEvent];\n\nexport namespace ConnectyCubeJanus {\n  export interface CreateOfferParams {\n    tracks: Array<{\n      type: string;\n      mid?: string;\n      recv?: boolean;\n      capture?: boolean | MediaStreamTrack;\n      replace?: boolean;\n    }>;\n    customizeSdp?(jsep: unknown): void;\n    success?(jsep: unknown): void;\n    error?(error: unknown): void;\n  }\n  export interface VideoRoomPluginHandle {\n    createOffer(opts: CreateOfferParams): void;\n    send(msg: unknown): void;\n    getLocalVolume?(id: unknown, callback: (value: unknown) => void): void;\n    handleRemoteJsep?(opts: { jsep: unknown }): void;\n    getId?(): string | number;\n    detach?(opts: { success?: () => void; error?: (err: unknown) => void }): void;\n    isAudioMuted?(): boolean;\n    unmuteAudio?(): void;\n    muteAudio?(): void;\n    isVideoMuted?(): boolean;\n    unmuteVideo?(): void;\n    muteVideo?(): void;\n    data?(opts: { data: unknown; label: unknown; success: (value?: unknown) => void; error: (err?: unknown) => void }): void;\n    webrtcStuff?: { pc: RTCPeerConnection };\n  }\n  export interface RemoteFeed {\n    userId?: number;\n    stream?: MediaStream;\n    tracks?: Record<string, MediaStreamTrack>;\n    createAnswer(opts: unknown): void;\n    send(msg: unknown): void;\n    detach(): void;\n    getBitrate?(): unknown;\n    getRemoteVolume?(id: unknown, callback: (value: unknown) => void): void;\n  }\n  export interface BitrateDisplayElement {\n    text: ((value?: unknown) => void) | null;\n  }\n  export interface SuccessErrorCallbacks {\n    success?: VoidCallback;\n    error?: (error: unknown) => void;\n  }\n  export interface InitCallbacks extends SuccessErrorCallbacks {\n    destroyed?: () => void;\n    timeoutSessionCallback?: () => void;\n  }\n  export interface PluginCallbacks extends SuccessErrorCallbacks {\n    localStream?: MediaStream;\n    displayName?: string;\n    iceState?: (iceState: unknown) => void;\n    slowLink?: (uplink: unknown, nacks: unknown) => void;\n    consentDialog?: (on: unknown) => void;\n    mediaState?: (medium: unknown, on: unknown) => void;\n    webrtcState?: (on: unknown) => void;\n    oncleanup?: () => void;\n  }\n  export type Session = ConferenceSession;\n  export interface RequestCallbacks extends SuccessErrorCallbacks {\n    displayName?: string;\n  }\n  // Listeners\n  export type OnParticipantJoinedListener = (\n    session: Session,\n    userId: number,\n    userName: string,\n    isExist: boolean\n  ) => void;\n  export type OnParticipantLeftListener = (session: Session, ...args: unknown[]) => void;\n  export type OnSlowLinkListener = (session: Session, userId: number | null, uplink: unknown, nacks: unknown) => void;\n  export type OnRemoteStreamListener = (session: Session, userId: number, stream: MediaStream) => void;\n  export type OnRemoteTracksUpdatedListener = (\n    session: Session,\n    userId: number,\n    track: MediaStreamTrack,\n    eventType: unknown\n  ) => void;\n  export type OnRemoteConnectionStateChangedListener = (session: Session, userId: number, iceState: unknown) => void;\n  export type OnDataChannelOpenedListener = (session: Session, label: unknown) => void;\n  export type OnDataChannelMessageListener = (session: Session, label: unknown, data: unknown) => void;\n  export type OnSessionConnectionStateChangedListener = (session: Session, iceState: unknown) => void;\n  export type OnErrorListener = (session: Session, error: unknown) => void;\n  export type Listeners =\n    | OnParticipantJoinedListener\n    | OnParticipantLeftListener\n    | OnSlowLinkListener\n    | OnRemoteStreamListener\n    | OnRemoteTracksUpdatedListener\n    | OnRemoteConnectionStateChangedListener\n    | OnDataChannelOpenedListener\n    | OnDataChannelMessageListener\n    | OnSessionConnectionStateChangedListener\n    | OnErrorListener;\n  export type ListenerName =\n    | 'onParticipantJoinedListener'\n    | 'onParticipantLeftListener'\n    | 'onSlowLinkListener'\n    | 'onRemoteStreamListener'\n    | 'onRemoteTracksUpdatedListener'\n    | 'onRemoteConnectionStateChangedListener'\n    | 'onDataChannelOpenedListener'\n    | 'onDataChannelMessageListener'\n    | 'onSessionConnectionStateChangedListener'\n    | 'onErrorListener';\n}\n","export const MediaType = {\n  AUDIO: 'audio',\n  VIDEO: 'video',\n  NONE: 'none',\n} as const;\nexport type MediaType = (typeof MediaType)[keyof typeof MediaType];\n\nexport namespace ConnectyCubeMedia {\n  export interface ElementOptions {\n    muted?: boolean;\n    mirror?: boolean;\n  }\n  export interface ElementParams {\n    elementId?: string;\n    options?: ElementOptions;\n  }\n  export interface DisplayParams extends DisplayMediaStreamOptions, ElementParams {}\n  export interface UserParams extends MediaStreamConstraints, ElementParams {}\n  export type DeviceIdOrTrackConstraints = MediaTrackConstraints | string;\n  export type TrackConstraintsOrDeviceIds = {\n    audio?: DeviceIdOrTrackConstraints;\n    video?: DeviceIdOrTrackConstraints;\n  };\n}\n","import type { StringObject } from './common';\nimport type { ConnectyCubeConfig } from './config';\nimport type { ConnectyCubeAuth } from './auth';\n\nexport const ProxyMethod = {\n  GET: 'GET',\n  POST: 'POST',\n  PUT: 'PUT',\n  PATCH: 'PATCH',\n  DELETE: 'DELETE',\n  HEAD: 'HEAD',\n} as const;\nexport type ProxyMethod = (typeof ProxyMethod)[keyof typeof ProxyMethod];\n\nexport const ProxyType = {\n  JSON: 'json',\n  TEXT: 'text',\n} as const;\nexport type ProxyType = (typeof ProxyType)[keyof typeof ProxyType];\n\nexport type ProxyRequestObject = {\n  method: string;\n  body?: BodyInit;\n  headers?: StringObject;\n  signal?: AbortSignal;\n  timeout?: number;\n};\n\nexport type ProxyResponseBody = unknown;\n\nexport type FetchResponse = {\n  ok: boolean;\n  status?: number;\n  url?: string;\n  text(): Promise<string>;\n  json(): Promise<unknown>;\n};\n\nexport namespace ConnectyCubeProxy {\n  export type Params = {\n    url: string;\n    type?: ProxyMethod;\n    data?: unknown;\n    contentType?: boolean;\n    dataType?: ProxyType;\n    useArrayQuery?: boolean;\n    fileToCustomObject?: boolean;\n    authKey?: string;\n    abort_id?: string | number;\n  };\n  export type AbortControllersMap = {\n    [key: string | number]: {\n      controllers: AbortController[];\n      doneRequestsCount?: number;\n    };\n  };\n  export type SDKInstance = {\n    config: ConnectyCubeConfig.Object;\n    session: Partial<ConnectyCubeAuth.Session> | null;\n  };\n  export type ErrorObject = {\n    code?: number;\n    info?: { errors?: { base?: string[] } };\n  };\n}\n","declare global {\n  interface Window {\n    adapter?: unknown;\n  }\n}\n\nexport const sdkVersion = '__package_version__';\n\nexport const isBrowser = typeof window !== 'undefined' && typeof document === 'object';\nexport const isNodeJS = true;\nexport const isReactNative = false;\nexport const isExpo = false;\n\nexport const adapter = isBrowser ? window.adapter : undefined;\nexport const navigator = isBrowser ? window.navigator : undefined;\nexport const mediaDevices = isBrowser && navigator ? navigator.mediaDevices : undefined;\nexport const MediaStream = isBrowser ? window.MediaStream : undefined;\nexport const MediaStreamTrack = isBrowser ? window.MediaStreamTrack : undefined;\nexport const RTCIceCandidate = isBrowser ? window.RTCIceCandidate : undefined;\nexport const RTCPeerConnection = isBrowser ? window.RTCPeerConnection : undefined;\nexport const RTCRtpReceiver = isBrowser ? window.RTCRtpReceiver : undefined;\nexport const RTCRtpSender = isBrowser ? window.RTCRtpSender : undefined;\nexport const RTCSessionDescription = isBrowser ? window.RTCSessionDescription : undefined;\nexport const isWebRTCAvailable: boolean = isBrowser ? Boolean(mediaDevices && RTCPeerConnection) : false;\n","import type { Config as ConnectyCubeConfig, PlainObject } from './types';\nimport { ChatAPIs } from './types/constants';\nimport { JanusDebugMode } from './types/constants';\nimport { sdkVersion } from '@platform';\n\nexport class Config {\n  private static instance: Config;\n\n  public version: string = sdkVersion;\n  public creds: ConnectyCubeConfig.Credentials = { appId: '', authKey: '' };\n  public endpoints: ConnectyCubeConfig.Endpoints = {\n    api: 'api.connectycube.com',\n    chat: 'chat.connectycube.com',\n    muc: 'muc.chat.connectycube.com',\n  };\n  public chatProtocol: ConnectyCubeConfig.ChatProtocolURLs = {\n    bosh: 'https://chat.connectycube.com:5281',\n    websocket: 'wss://chat.connectycube.com:5291',\n    active: 2,\n  };\n  public chat: ConnectyCubeConfig.Chat = {\n    streamManagement: { enable: false },\n    reconnect: { enable: true, timeInterval: 5 },\n    apiImp: ChatAPIs.XMPP,\n  };\n  public videochat: ConnectyCubeConfig.Videochat = {\n    alwaysRelayCalls: false,\n    answerTimeInterval: 60,\n    dialingTimeInterval: 5,\n    disconnectTimeInterval: 30,\n    statsReportTimeInterval: null,\n    iceServers: [\n      { urls: 'stun:stun.l.google.com:19302' },\n      { urls: 'stun:turn.connectycube.com' },\n      {\n        urls: 'turn:turn.connectycube.com:5349?transport=udp',\n        username: 'connectycube',\n        credential: '4c29501ca9207b7fb9c4b4b6b04faeb1',\n      },\n      {\n        urls: 'turn:turn.connectycube.com:5349?transport=tcp',\n        username: 'connectycube',\n        credential: '4c29501ca9207b7fb9c4b4b6b04faeb1',\n      },\n    ],\n  };\n  public conference: ConnectyCubeConfig.Conference = {\n    server: 'wss://janus.connectycube.com:8989',\n    debug: JanusDebugMode.ALL,\n  };\n  public whiteboard: ConnectyCubeConfig.Whiteboard = { server: 'https://whiteboard.connectycube.com' };\n  public linkpreview: ConnectyCubeConfig.LinkPreview = { server: 'https://linkpreview.connectycube.com' };\n  readonly urls: ConnectyCubeConfig.ApiRoutes = {\n    session: 'session',\n    login: 'login',\n    users: 'users',\n    chat: 'chat',\n    blobs: 'blobs',\n    subscriptions: 'subscriptions',\n    events: 'events',\n    data: 'data',\n    addressbook: 'address_book',\n    meetings: 'meetings',\n    whiteboards: 'whiteboards',\n    unfurl: 'unfurl',\n    calls: 'calls',\n    type: '.json',\n  };\n  public on: ConnectyCubeConfig.Listeners = {\n    sessionExpired: undefined,\n    xmppDataWrite: undefined,\n    xmppDataRead: undefined,\n  };\n  public timeout: number | null = null;\n  public debug: ConnectyCubeConfig.Debug = { mode: 1 };\n\n  private constructor() {}\n\n  public static getInstance(): Config {\n    if (!Config.instance) {\n      Config.instance = new Config();\n    }\n    return Config.instance;\n  }\n\n  public set(options: ConnectyCubeConfig.Options): void {\n    this.endpoints.api_url = options.endpoints?.api_url;\n\n    if (options.endpoints?.chat) {\n      this.endpoints.muc = `muc.${options.endpoints.chat}`;\n      this.chatProtocol.bosh = `https://${options.endpoints.chat}:5281`;\n      this.chatProtocol.websocket = options.endpoints.chat_url ?? `wss://${options.endpoints.chat}:5291`;\n    }\n\n    Object.keys(options).forEach((key: string) => {\n      if (key !== 'set' && Object.prototype.hasOwnProperty.call(this, key)) {\n        const optionValue = options[key as keyof ConnectyCubeConfig.Options];\n        const _key = key as keyof Config;\n        const _val = this[_key];\n\n        if (typeof optionValue === 'object' && optionValue !== null) {\n          Object.keys(optionValue).forEach((nextKey) => {\n            if (_val !== null && typeof _val === 'object' && Object.prototype.hasOwnProperty.call(_val, nextKey)) {\n              (_val as PlainObject)[nextKey] = (optionValue as PlainObject)[nextKey];\n            }\n          });\n        } else {\n          (this as PlainObject)[key] = optionValue;\n        }\n      }\n    });\n  }\n}\n\nexport default Config.getInstance();\n","import type { Config, VoidCallback } from './types';\nimport { isBrowser, isExpo, isNodeJS, isReactNative } from '@platform';\nimport config from './config';\n\nexport default class Utils {\n  static loggers: Array<VoidCallback> = [];\n\n  static env = {\n    isReactNative,\n    isBrowser,\n    isNodeJS,\n    isExpo,\n  };\n\n  static safeCallbackCall(cb: VoidCallback = () => {}): VoidCallback {\n    return (...args: unknown[]) => {\n      if (typeof cb === 'function') {\n        try {\n          cb(...args);\n        } catch (err) {\n          console.error('Error in listener:', err, `Check the code:\\n>>>\\n${cb.toString()}\\n<<<`);\n        }\n      }\n    };\n  }\n\n  static getUrl(base: Config.ApiRoutes[keyof Config.ApiRoutes], res?: string | number, ext?: string | number): string {\n    const resource = res ? `/${res}` : '';\n    const extension = ext ? `/${ext}` : '';\n    return `${config.endpoints.api_url ?? `https://${config.endpoints.api}`}/${base}${resource}${extension}${config.urls.type}`;\n  }\n\n  static isArray(arg: unknown): arg is unknown[] {\n    return Array.isArray(arg);\n  }\n\n  static isObject(obj: unknown): boolean {\n    return Object.prototype.toString.call(obj) === '[object Object]';\n  }\n\n  static getBsonObjectId(): string {\n    // The object for type MongoDB.Bson.ObjectId\n    // http://docs.mongodb.org/manual/reference/object-id/\n    const ObjectId = {\n      machine: Math.floor(Math.random() * 16777216).toString(16),\n      pid: Math.floor(Math.random() * 32767).toString(16),\n      increment: 0,\n    };\n    const timestamp = Math.floor(Date.now() / 1000).toString(16);\n    const increment = (ObjectId.increment++).toString(16);\n\n    if (parseInt(increment, 16) > 0xffffff) {\n      ObjectId.increment = 0;\n    }\n\n    return (\n      timestamp.padStart(8, '0') +\n      ObjectId.machine.padStart(6, '0') +\n      ObjectId.pid.padStart(4, '0') +\n      increment.padStart(6, '0')\n    );\n  }\n\n  static DLog(...args: unknown[]): void {\n    if (Utils.loggers.length > 0) {\n      Utils.loggers.forEach((logger) => logger(args));\n      return;\n    }\n\n    const consoleLoggerFunction = (): VoidCallback => {\n      return (...args: unknown[]) => console.log(...args);\n    };\n\n    if (typeof config.debug === 'object') {\n      const modes = Array.isArray(config.debug.mode) ? config.debug.mode : [config.debug.mode];\n      modes.forEach((mode) => {\n        if (mode === 1) {\n          Utils.loggers.push(consoleLoggerFunction());\n        }\n      });\n    }\n\n    Utils.loggers.forEach((logger) => logger(args));\n  }\n\n  static callTrafficUsageCallback(callbackName: 'xmppDataRead' | 'xmppDataWrite', data: Config.XMPPData): void {\n    if (typeof config.on[callbackName] !== 'function') return;\n\n    const getStringSize = (str: string): number => new Blob([str]).size;\n    const getDataSize = (data: Config.XMPPData = {}): number => {\n      const { body: b, headers: h } = data;\n      let size = 0;\n      if (b) size += getStringSize(typeof b === 'string' ? b : JSON.stringify(b));\n      if (h) size += getStringSize(JSON.stringify(h));\n      return size;\n    };\n\n    config.on[callbackName](getDataSize(data), data);\n  }\n\n  static cloneObject<T>(obj: T = {} as T, escapeNull: boolean = false): T {\n    try {\n      const json = JSON.stringify(obj);\n      const jsonObject = escapeNull ? json.replace(/null/g, '\"\"') : json;\n\n      return JSON.parse(jsonObject);\n    } catch {\n      return obj;\n    }\n  }\n}\n","import type { Auth, Proxy, PlainObject } from './types';\nimport type { FetchResponse, ProxyRequestObject, ProxyResponseBody } from './types/proxy';\nimport { ProxyMethod, ProxyType } from './types/constants';\n\nimport config from './config';\nimport Utils from './Utils';\n\nexport default class ProxyService {\n  public sdkInstance: Proxy.SDKInstance = {\n    config,\n    session: null,\n  };\n  public requestsNumber: number = 0;\n  private currentUserId: number | undefined;\n  private abortControllersMap: Proxy.AbortControllersMap = {};\n  public requestMethod: typeof ProxyMethod = ProxyMethod;\n  public responseType: typeof ProxyType = ProxyType;\n\n  public setSession(session: Partial<Auth.Session> | null): void {\n    this.sdkInstance.session = session;\n\n    if (session && session.user_id) {\n      this.setCurrentUserId(session.user_id);\n    }\n  }\n\n  public getSession(): Partial<Auth.Session> | null {\n    return this.sdkInstance.session;\n  }\n\n  public setCurrentUserId(userId?: number | null): void {\n    this.currentUserId = userId || undefined;\n  }\n\n  public getCurrentUserId(): number | undefined {\n    return this.currentUserId;\n  }\n\n  public logRequest(params: Proxy.Params, requestId: number): void {\n    Utils.DLog(`[Request][${requestId}]`, `${params.type || 'GET'} ${params.url}`, params);\n  }\n\n  public logResponse(response: ProxyResponseBody, requestId: number): void {\n    Utils.DLog(`[Response][${requestId}]`, response);\n  }\n\n  public buildRequestAndURL(params: Proxy.Params): [ProxyRequestObject, string] {\n    const isGetOrHeadType = !params.type || params.type === 'GET' || params.type === 'HEAD';\n    const isPostOrPutType = params.type ? params.type === 'POST' || params.type === 'PUT' : false;\n    const token = this.sdkInstance && this.sdkInstance.session && this.sdkInstance.session.token;\n    const isInternalRequest = params.url.indexOf('s3.amazonaws.com') === -1;\n    const isMultipartFormData = params.contentType === false;\n    const authKey = params.authKey;\n    const requestObject: ProxyRequestObject = {\n      method: params.type || 'GET',\n    };\n\n    let requestURL = params.url;\n\n    if (params.data) {\n      const requestBody = this.buildRequestBody(params, isMultipartFormData, isPostOrPutType);\n\n      if (isGetOrHeadType) {\n        requestURL += `?${requestBody}`;\n      } else {\n        requestObject.body = requestBody as BodyInit;\n      }\n    }\n\n    if (!isMultipartFormData) {\n      requestObject.headers = {\n        'Content-Type': isPostOrPutType\n          ? 'application/json;charset=utf-8'\n          : 'application/x-www-form-urlencoded; charset=UTF-8',\n      };\n    }\n\n    if (isInternalRequest) {\n      if (!requestObject.headers) {\n        requestObject.headers = {};\n      }\n\n      requestObject.headers['CB-SDK'] = `JS ${config.version} - Client`;\n\n      if (token) {\n        requestObject.headers['CB-Token'] = token;\n      } else if (authKey) {\n        requestObject.headers['CB-AuthKey'] = authKey;\n      }\n    }\n\n    if (config.timeout) {\n      requestObject.timeout = config.timeout;\n    }\n\n    return [requestObject, requestURL];\n  }\n\n  public buildRequestBody(\n    params: Proxy.Params,\n    isMultipartFormData: boolean,\n    isPostOrPutType: boolean\n  ): FormData | string {\n    const data = params.data as PlainObject;\n    const useArrayQuery = params.useArrayQuery;\n\n    let dataObject: FormData | string;\n\n    if (isMultipartFormData) {\n      const formData = new FormData();\n      Object.keys(data).forEach(function (item) {\n        const fileEntry = data[item] as { data: Blob; name: string } | undefined;\n\n        if (params.fileToCustomObject && item === 'file' && fileEntry) {\n          formData.append(item, fileEntry.data, fileEntry.name);\n        } else {\n          const value = data[item];\n          formData.append(item, value instanceof Uint8Array ? new Blob([new Uint8Array(value)]) : (value as string | Blob));\n        }\n      });\n      dataObject = formData;\n    } else if (isPostOrPutType) {\n      dataObject = JSON.stringify(data);\n    } else {\n      dataObject = this.serializeQueryParams(data, '', useArrayQuery, 0);\n    }\n\n    return dataObject;\n  }\n\n  public serializeQueryParams(\n    obj: PlainObject | unknown[],\n    prefix: string,\n    useArrayQuery: boolean | undefined,\n    level = 0\n  ): string {\n    const parts: string[] = [];\n    const objRecord = obj as PlainObject;\n\n    for (const propName in objRecord) {\n      let propQueryName = this.encodeURIComponent(propName);\n\n      if (Utils.isArray(obj)) {\n        propQueryName = '';\n      }\n\n      const key = prefix ? prefix + `[${propQueryName}]` : propQueryName;\n      let value = objRecord[propName] as PlainObject | unknown[];\n      const isArrayVal = Utils.isArray(value);\n\n      if ((isArrayVal && (useArrayQuery || level === 0)) || Utils.isObject(value)) {\n        parts.push(this.serializeQueryParams(value, key, useArrayQuery, ++level));\n      } else {\n        const strVal = isArrayVal ? value.sort().join(',') : String(value);\n        parts.push(`${key}=${this.encodeURIComponent(strVal)}`);\n      }\n    }\n\n    return parts.sort().join('&');\n  }\n\n  public encodeURIComponent(uriComponent: string | number | boolean): string {\n    return encodeURIComponent(uriComponent).replace(/[#$&+,/:;=?@\\[\\]]/g, (c) => `%${c.charCodeAt(0).toString(16)}`);\n  }\n\n  public abortRequest(abortId: string | number): void {\n    if (this.abortControllersMap[abortId]) {\n      const controllers = this.abortControllersMap[abortId].controllers || [];\n\n      controllers.forEach((controller) => {\n        controller.abort();\n      });\n    }\n  }\n\n  public processSuccessfulOrFailedRequest(abort_id?: string | number): void {\n    if (!abort_id || !this.abortControllersMap[abort_id]) {\n      return;\n    }\n\n    const controllers = this.abortControllersMap[abort_id].controllers || [];\n\n    if (!this.abortControllersMap[abort_id].doneRequestsCount) {\n      this.abortControllersMap[abort_id].doneRequestsCount = 1;\n    } else {\n      this.abortControllersMap[abort_id].doneRequestsCount += 1;\n    }\n\n    const doneRequestsCount = this.abortControllersMap[abort_id].doneRequestsCount;\n\n    if (doneRequestsCount === controllers.length) {\n      delete this.abortControllersMap[abort_id];\n    }\n  }\n\n  public async ajax<T>(params: Proxy.Params): Promise<T> {\n    const requestId = ++this.requestsNumber;\n\n    return new Promise((resolve, reject) => {\n      this.logRequest(params, requestId);\n\n      const [requestObject, requestURL] = this.buildRequestAndURL(params);\n      const abort_id = params.abort_id;\n\n      if (abort_id) {\n        let index = 0;\n\n        if (this.abortControllersMap[abort_id]) {\n          const controllers = this.abortControllersMap[abort_id].controllers || [];\n          this.abortControllersMap[abort_id].controllers.push(new AbortController());\n          index = controllers.length - 1;\n        } else {\n          this.abortControllersMap[abort_id] = {\n            controllers: [new AbortController()],\n          };\n        }\n        const signal = this.abortControllersMap[abort_id].controllers[index].signal;\n        Object.assign(requestObject, { signal });\n      }\n\n      let response: FetchResponse | undefined;\n\n      const body = requestObject.body === null ? undefined : requestObject.body;\n      const requestInit = { ...requestObject, body };\n\n      // The Promise returned from fetch() won’t reject on HTTP error\n      // status even if the response is an HTTP 404 or 500.\n      // Instead, it will resolve normally (with ok status set to false),\n      // and it will only reject on network failure or if anything prevented the request from completing.\n      fetch(requestURL, requestInit as unknown as Parameters<typeof fetch>[1])\n        .then((resp: FetchResponse) => {\n          response = resp;\n          const dataType = params.dataType || ProxyType.JSON;\n          return dataType === ProxyType.TEXT ? resp.text() : resp.json();\n        })\n        .then((body: ProxyResponseBody) => {\n          this.processSuccessfulOrFailedRequest(abort_id);\n          if (!response!.ok) {\n            this.processAjaxError(\n              response!,\n              body,\n              null,\n              reject as (reason?: unknown) => void,\n              resolve as (value: ProxyResponseBody) => void,\n              params,\n              requestId\n            );\n          } else {\n            this.processAjaxResponse(body, resolve as (value: ProxyResponseBody) => void, requestId);\n          }\n        })\n        .catch((error: unknown) => {\n          this.processSuccessfulOrFailedRequest(abort_id);\n          this.processAjaxError(\n            response ?? null,\n            ' ',\n            error,\n            reject as (reason?: unknown) => void,\n            resolve as (value: ProxyResponseBody) => void,\n            params,\n            requestId\n          );\n        });\n    });\n  }\n\n  public processAjaxResponse(\n    body: ProxyResponseBody,\n    resolve: (value: ProxyResponseBody) => void,\n    requestId: number\n  ): void {\n    const responseBody = body !== undefined && body !== null && body !== ' ' ? body : 'empty body';\n    this.logResponse(responseBody, requestId);\n\n    resolve(body);\n  }\n\n  public processAjaxError(\n    response: FetchResponse | null,\n    body: ProxyResponseBody,\n    error: unknown,\n    reject: (reason?: unknown) => void,\n    resolve: (value: ProxyResponseBody) => void,\n    params: Proxy.Params,\n    requestId: number\n  ): void {\n    const err = error as { code?: number; errno?: unknown };\n    if (!response && error && !err.code) {\n      reject(error);\n      return;\n    }\n\n    const bodyObj = body as { errors?: unknown } | null;\n    const responseBody = body || error || bodyObj?.errors;\n    const statusCode = response?.status;\n    const code: number | undefined = (response && statusCode) || (error ? err.code : undefined);\n    const rawInfo =\n      (body && typeof body === 'string' && body !== ' ' ? JSON.parse(body) : body) || (error ? err.errno : undefined);\n    const errorObject: Proxy.ErrorObject = {\n      code,\n      info: rawInfo as Proxy.ErrorObject['info'],\n    };\n\n    this.logResponse(responseBody, requestId);\n\n    if ((response?.url ?? '').indexOf(config.urls.session) === -1) {\n      if (this.isExpiredSessionError(errorObject) && typeof config.on.sessionExpired === 'function') {\n        this.handleExpiredSessionResponse(errorObject, null, reject, resolve, params);\n      } else {\n        reject(errorObject);\n      }\n    } else {\n      reject(errorObject);\n    }\n  }\n\n  public handleExpiredSessionResponse(\n    error: Proxy.ErrorObject | null,\n    response: ProxyResponseBody | null,\n    reject: (reason?: unknown) => void,\n    resolve: (value: ProxyResponseBody) => void,\n    params: Proxy.Params\n  ): void {\n    const handleResponse = () => {\n      if (error) {\n        reject(error);\n      } else {\n        resolve(response);\n      }\n    };\n\n    const retryCallback = (session: Partial<Auth.Session>) => {\n      if (session) {\n        this.setSession(session);\n        this.ajax(params).then(resolve).catch(reject);\n      }\n    };\n\n    if (typeof config.on.sessionExpired === 'function') {\n      config.on.sessionExpired(handleResponse, retryCallback);\n    }\n  }\n\n  private isExpiredSessionError(error: Proxy.ErrorObject): boolean {\n    try {\n      return error && error.code === 401 && error.info?.errors?.base?.[0] === 'Required session does not exist';\n    } catch {\n      return false;\n    }\n  }\n}\n","import type { AddressBook } from './types';\nimport { ProxyMethod } from './types/constants';\nimport ProxyService from './Proxy';\nimport Utils from './Utils';\nimport config from './config';\n\nexport default class AddressBookService {\n  public proxy: ProxyService;\n  readonly route = config.urls.addressbook;\n\n  constructor(proxy: ProxyService) {\n    this.proxy = proxy;\n  }\n\n  public async uploadAddressBook(\n    list: AddressBook.Contact[] = [],\n    params: AddressBook.UploadParams = {}\n  ): Promise<AddressBook.UploadResponse> {\n    if (!Utils.isArray(list)) {\n      throw new Error('First parameter must be an Array.');\n    }\n\n    const ajaxParams = {\n      type: ProxyMethod.POST,\n      url: Utils.getUrl(this.route),\n      data: { contacts: list, ...params },\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async get(udid?: string): Promise<AddressBook.Contact[]> {\n    const ajaxParams = {\n      type: ProxyMethod.GET,\n      url: Utils.getUrl(this.route),\n      data: udid ? { udid } : undefined,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async getRegisteredUsers(\n    params: AddressBook.GetRegisteredUsersParams = false\n  ): Promise<AddressBook.GetRegisteredUsersResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.GET,\n      url: Utils.getUrl(this.route, 'registered_users'),\n      data: typeof params === 'boolean' ? { compact: params ? 1 : 0 } : params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n}\n","import type { Auth, Users, EmptyResponse } from './types';\nimport { ProxyMethod, ProxyType } from './types/constants';\nimport ProxyService from './Proxy';\nimport Utils from './Utils';\nimport config from './config';\n\nexport default class AuthService {\n  public proxy: ProxyService;\n\n  readonly routes = {\n    session: config.urls.session,\n    login: config.urls.login,\n  };\n\n  constructor(proxy: ProxyService) {\n    this.proxy = proxy;\n  }\n\n  public setSession = (session: Partial<Auth.Session>): void => {\n    this.proxy.setSession(session);\n  };\n\n  public getSession = async (): Promise<Auth.Session> => {\n    try {\n      const ajaxParams = {\n        type: ProxyMethod.GET,\n        url: Utils.getUrl(this.routes.session),\n      };\n      const response = await this.proxy.ajax<Auth.GetSessionRawResponse>(ajaxParams);\n      return response.session;\n    } catch (error) {\n      throw error;\n    }\n  };\n\n  public createSession = async (params: Auth.LoginParams | {} = {}): Promise<Auth.Session> => {\n    if (config.creds.appId === '' || config.creds.authKey === '') {\n      throw new Error('Cannot create a new session without \"appId\" and \"authKey\"');\n    }\n\n    try {\n      const ajaxParams = {\n        type: ProxyMethod.POST,\n        url: Utils.getUrl(this.routes.session),\n        data: this.generateCreateSessionParams(params),\n      };\n      const response = await this.proxy.ajax<Auth.GetSessionRawResponse>(ajaxParams);\n      this.proxy.setSession(response.session);\n      this.proxy.setCurrentUserId(response.session.user_id);\n      return response.session;\n    } catch (error) {\n      throw error;\n    }\n  };\n\n  public destroySession = async (): Promise<EmptyResponse> => {\n    try {\n      const ajaxParams = {\n        type: ProxyMethod.DELETE,\n        url: Utils.getUrl(this.routes.session),\n        dataType: ProxyType.TEXT,\n      };\n      await this.proxy.ajax(ajaxParams);\n      this.proxy.setSession(null);\n      this.proxy.setCurrentUserId(null);\n    } catch (error) {\n      throw error;\n    }\n  };\n\n  public login = async (params: Auth.LoginParams): Promise<Users.User> => {\n    try {\n      const ajaxParams = {\n        type: ProxyMethod.POST,\n        url: Utils.getUrl(this.routes.login),\n        data: params,\n      };\n      const { user } = await this.proxy.ajax<Auth.LoginRawResponse>(ajaxParams);\n      this.proxy.setCurrentUserId(user.id);\n      return user;\n    } catch (error) {\n      throw error;\n    }\n  };\n\n  public logout = async (): Promise<EmptyResponse> => {\n    const ajaxParams = {\n      type: ProxyMethod.DELETE,\n      url: Utils.getUrl(this.routes.login),\n      dataType: ProxyType.TEXT,\n    };\n    this.proxy.setCurrentUserId(null);\n    return this.proxy.ajax(ajaxParams);\n  };\n\n  private generateCreateSessionParams(params: Auth.LoginParams | {} = {}): Auth.GeneratedSessionParams {\n    const message: Auth.GeneratedSessionParams = {\n      application_id: config.creds.appId ?? '',\n      auth_key: config.creds.authKey ?? '',\n    };\n\n    if ('guest' in params) {\n      message.user = params;\n    } else if ('login' in params && 'password' in params) {\n      message.user = { login: params.login, password: params.password };\n    } else if ('email' in params && 'password' in params) {\n      message.user = { email: params.email, password: params.password };\n    } else if ('provider' in params) {\n      message.provider = params.provider;\n      if ('keys' in params) {\n        message.keys = params.keys;\n      }\n      if ('firebase_phone' in params) {\n        message.firebase_phone = params.firebase_phone;\n      }\n      if ('firebase_email' in params) {\n        message.firebase_email = params.firebase_email;\n      }\n    }\n\n    return message;\n  }\n}\n","'use strict';\n\nconst escapeXMLTable = {\n  \"&\": \"&amp;\",\n  \"<\": \"&lt;\",\n  \">\": \"&gt;\",\n  '\"': \"&quot;\",\n  \"'\": \"&apos;\",\n};\n\nfunction escapeXMLReplace(match) {\n  return escapeXMLTable[match];\n}\n\nconst unescapeXMLTable = {\n  \"&amp;\": \"&\",\n  \"&lt;\": \"<\",\n  \"&gt;\": \">\",\n  \"&quot;\": '\"',\n  \"&apos;\": \"'\",\n};\n\nfunction unescapeXMLReplace(match) {\n  if (match[1] === \"#\") {\n    const num =\n      match[2] === \"x\"\n        ? parseInt(match.slice(3), 16)\n        : parseInt(match.slice(2), 10);\n    // https://www.w3.org/TR/xml/#NT-Char defines legal XML characters:\n    // #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]\n    if (\n      num === 0x9 ||\n      num === 0xa ||\n      num === 0xd ||\n      (num >= 0x20 && num <= 0xd7ff) ||\n      (num >= 0xe000 && num <= 0xfffd) ||\n      (num >= 0x10000 && num <= 0x10ffff)\n    ) {\n      return String.fromCodePoint(num);\n    }\n    throw new Error(\"Illegal XML character 0x\" + num.toString(16));\n  }\n  if (unescapeXMLTable[match]) {\n    return unescapeXMLTable[match] || match;\n  }\n  throw new Error(\"Illegal XML entity \" + match);\n}\n\nfunction escapeXML(s) {\n  return s.replace(/[\"&'<>]/g, escapeXMLReplace);\n}\n\nfunction unescapeXML(s) {\n  let result = \"\";\n  let start = -1;\n  let end = -1;\n  let previous = 0;\n  while (\n    (start = s.indexOf(\"&\", previous)) !== -1 &&\n    (end = s.indexOf(\";\", start + 1)) !== -1\n  ) {\n    result =\n      result +\n      s.slice(previous, start) +\n      unescapeXMLReplace(s.slice(start, end + 1));\n    previous = end + 1;\n  }\n\n  // shortcut if loop never entered:\n  // return the original string without creating new objects\n  if (previous === 0) return s;\n\n  // push the remaining characters\n  result = result + s.substring(previous);\n\n  return result;\n}\n\nfunction escapeXMLText(s) {\n  return s.replace(/[&<>]/g, escapeXMLReplace);\n}\n\nfunction unescapeXMLText(s) {\n  return s.replace(/&(amp|#38|lt|#60|gt|#62);/g, unescapeXMLReplace);\n}\n\nexports.escapeXML = escapeXML;\nexports.escapeXMLText = escapeXMLText;\nexports.unescapeXML = unescapeXML;\nexports.unescapeXMLText = unescapeXMLText;\n","'use strict';\n\nvar escape = require('./escape.js');\n\n/**\n * Element\n *\n * Attributes are in the element.attrs object. Children is a list of\n * either other Elements or Strings for text content.\n **/\nclass Element {\n  constructor(name, attrs) {\n    this.name = name;\n    this.parent = null;\n    this.children = [];\n    this.attrs = {};\n    this.setAttrs(attrs);\n  }\n\n  /* Accessors */\n\n  /**\n   * if (element.is('message', 'jabber:client')) ...\n   **/\n  is(name, xmlns) {\n    return this.getName() === name && (!xmlns || this.getNS() === xmlns);\n  }\n\n  /* without prefix */\n  getName() {\n    const idx = this.name.indexOf(\":\");\n    return idx >= 0 ? this.name.slice(idx + 1) : this.name;\n  }\n\n  /**\n   * retrieves the namespace of the current element, upwards recursively\n   **/\n  getNS() {\n    const idx = this.name.indexOf(\":\");\n    if (idx >= 0) {\n      const prefix = this.name.slice(0, idx);\n      return this.findNS(prefix);\n    }\n    return this.findNS();\n  }\n\n  /**\n   * find the namespace to the given prefix, upwards recursively\n   **/\n  findNS(prefix) {\n    if (!prefix) {\n      /* default namespace */\n      if (this.attrs.xmlns) {\n        return this.attrs.xmlns;\n      } else if (this.parent) {\n        return this.parent.findNS();\n      }\n    } else {\n      /* prefixed namespace */\n      const attr = \"xmlns:\" + prefix;\n      if (this.attrs[attr]) {\n        return this.attrs[attr];\n      } else if (this.parent) {\n        return this.parent.findNS(prefix);\n      }\n    }\n  }\n\n  /**\n   * Recursiverly gets all xmlns defined, in the form of {url:prefix}\n   **/\n  getXmlns() {\n    let namespaces = {};\n\n    if (this.parent) {\n      namespaces = this.parent.getXmlns();\n    }\n\n    for (const attr in this.attrs) {\n      const m = attr.match(\"xmlns:?(.*)\");\n      // eslint-disable-next-line  no-prototype-builtins\n      if (this.attrs.hasOwnProperty(attr) && m) {\n        namespaces[this.attrs[attr]] = m[1];\n      }\n    }\n    return namespaces;\n  }\n\n  setAttrs(attrs) {\n    if (typeof attrs === \"string\") {\n      this.attrs.xmlns = attrs;\n    } else if (attrs) {\n      Object.assign(this.attrs, attrs);\n    }\n  }\n\n  /**\n   * xmlns can be null, returns the matching attribute.\n   **/\n  getAttr(name, xmlns) {\n    if (!xmlns) {\n      return this.attrs[name];\n    }\n\n    const namespaces = this.getXmlns();\n\n    if (!namespaces[xmlns]) {\n      return null;\n    }\n\n    return this.attrs[[namespaces[xmlns], name].join(\":\")];\n  }\n\n  /**\n   * xmlns can be null\n   **/\n  getChild(name, xmlns) {\n    return this.getChildren(name, xmlns)[0];\n  }\n\n  /**\n   * xmlns can be null\n   **/\n  getChildren(name, xmlns) {\n    const result = [];\n    for (const child of this.children) {\n      if (\n        child.getName &&\n        child.getName() === name &&\n        (!xmlns || child.getNS() === xmlns)\n      ) {\n        result.push(child);\n      }\n    }\n    return result;\n  }\n\n  /**\n   * xmlns and recursive can be null\n   **/\n  getChildByAttr(attr, val, xmlns, recursive) {\n    return this.getChildrenByAttr(attr, val, xmlns, recursive)[0];\n  }\n\n  /**\n   * xmlns and recursive can be null\n   **/\n  getChildrenByAttr(attr, val, xmlns, recursive) {\n    let result = [];\n    for (const child of this.children) {\n      if (\n        child.attrs &&\n        child.attrs[attr] === val &&\n        (!xmlns || child.getNS() === xmlns)\n      ) {\n        result.push(child);\n      }\n      if (recursive && child.getChildrenByAttr) {\n        result.push(child.getChildrenByAttr(attr, val, xmlns, true));\n      }\n    }\n    if (recursive) {\n      result = result.flat();\n    }\n    return result;\n  }\n\n  getChildrenByFilter(filter, recursive) {\n    let result = [];\n    for (const child of this.children) {\n      if (filter(child)) {\n        result.push(child);\n      }\n      if (recursive && child.getChildrenByFilter) {\n        result.push(child.getChildrenByFilter(filter, true));\n      }\n    }\n    if (recursive) {\n      result = result.flat();\n    }\n    return result;\n  }\n\n  getText() {\n    let text = \"\";\n    for (const child of this.children) {\n      if (typeof child === \"string\" || typeof child === \"number\") {\n        text += child;\n      }\n    }\n    return text;\n  }\n\n  getChildText(name, xmlns) {\n    const child = this.getChild(name, xmlns);\n    return child ? child.getText() : null;\n  }\n\n  /**\n   * Return all direct descendents that are Elements.\n   * This differs from `getChildren` in that it will exclude text nodes,\n   * processing instructions, etc.\n   */\n  getChildElements() {\n    return this.getChildrenByFilter((child) => {\n      return child instanceof Element;\n    });\n  }\n\n  /* Builder */\n\n  /** returns uppermost parent */\n  root() {\n    if (this.parent) {\n      return this.parent.root();\n    }\n    return this;\n  }\n\n  /** just parent or itself */\n  up() {\n    if (this.parent) {\n      return this.parent;\n    }\n    return this;\n  }\n\n  /** create child node and return it */\n  c(name, attrs) {\n    return this.cnode(new Element(name, attrs));\n  }\n\n  cnode(child) {\n    this.children.push(child);\n    if (typeof child === \"object\") {\n      child.parent = this;\n    }\n    return child;\n  }\n\n  append(...nodes) {\n    for (const node of nodes) {\n      this.children.push(node);\n      if (typeof node === \"object\") {\n        node.parent = this;\n      }\n    }\n  }\n\n  prepend(...nodes) {\n    for (const node of nodes) {\n      this.children.unshift(node);\n      if (typeof node === \"object\") {\n        node.parent = this;\n      }\n    }\n  }\n\n  /** add text node and return element */\n  t(text) {\n    this.children.push(text);\n    return this;\n  }\n\n  /* Manipulation */\n\n  /**\n   * Either:\n   *   el.remove(childEl)\n   *   el.remove('author', 'urn:...')\n   */\n  remove(el, xmlns) {\n    const filter =\n      typeof el === \"string\"\n        ? (child) => {\n            /* 1st parameter is tag name */\n            return !(child.is && child.is(el, xmlns));\n          }\n        : (child) => {\n            /* 1st parameter is element */\n            return child !== el;\n          };\n\n    this.children = this.children.filter(filter);\n\n    return this;\n  }\n\n  text(val) {\n    if (val && this.children.length === 1) {\n      this.children[0] = val;\n      return this;\n    }\n    return this.getText();\n  }\n\n  attr(attr, val) {\n    if (typeof val !== \"undefined\" || val === null) {\n      if (!this.attrs) {\n        this.attrs = {};\n      }\n      this.attrs[attr] = val;\n      return this;\n    }\n    return this.attrs[attr];\n  }\n\n  /* Serialization */\n\n  toString() {\n    let s = \"\";\n    this.write((c) => {\n      s += c;\n    });\n    return s;\n  }\n\n  _addChildren(writer) {\n    writer(\">\");\n    for (const child of this.children) {\n      /* Skip null/undefined */\n      if (child != null) {\n        if (child.write) {\n          child.write(writer);\n        } else if (typeof child === \"string\") {\n          writer(escape.escapeXMLText(child));\n        } else if (child.toString) {\n          writer(escape.escapeXMLText(child.toString(10)));\n        }\n      }\n    }\n    writer(\"</\");\n    writer(this.name);\n    writer(\">\");\n  }\n\n  write(writer) {\n    writer(\"<\");\n    writer(this.name);\n    for (const k in this.attrs) {\n      const v = this.attrs[k];\n      // === null || undefined\n      if (v != null) {\n        writer(\" \");\n        writer(k);\n        writer('=\"');\n        writer(escape.escapeXML(typeof v === \"string\" ? v : v.toString(10)));\n        writer('\"');\n      }\n    }\n    if (this.children.length === 0) {\n      writer(\"/>\");\n    } else {\n      this._addChildren(writer);\n    }\n  }\n}\n\nElement.prototype.tree = Element.prototype.root;\n\nmodule.exports = Element;\n","'use strict';\n\nvar Element = require('./Element.js');\n\nfunction append(el, child) {\n  if (Array.isArray(child)) {\n    for (const c of child) append(el, c);\n    return;\n  }\n\n  if (child === \"\" || child == null || child === true || child === false) {\n    return;\n  }\n\n  el.cnode(child);\n}\n\n/**\n * JSX compatible API, use this function as pragma\n * https://facebook.github.io/jsx/\n *\n * @param  {string} name  name of the element\n * @param  {object} attrs object of attribute key/value pairs\n * @return {Element}      Element\n */\nfunction createElement(name, attrs, ...children) {\n  if (typeof attrs === \"object\" && attrs !== null) {\n    // __self and __source are added by babel in development\n    // https://github.com/facebook/react/pull/4596\n    // https://babeljs.io/docs/en/babel-preset-react#development\n    // https://babeljs.io/docs/en/babel-plugin-transform-react-jsx-source\n    delete attrs.__source;\n    delete attrs.__self;\n\n    for (const [key, value] of Object.entries(attrs)) {\n      if (value == null) delete attrs[key];\n      else attrs[key] = value.toString(10);\n    }\n  }\n\n  const el = new Element(name, attrs);\n\n  for (const child of children) {\n    append(el, child);\n  }\n\n  return el;\n}\n\nmodule.exports = createElement;\n","'use strict';\n\nvar events = require('events');\nvar escape = require('../escape.js');\n\nconst STATE_TEXT = 0;\nconst STATE_IGNORE_COMMENT = 1;\nconst STATE_IGNORE_INSTRUCTION = 2;\nconst STATE_TAG_NAME = 3;\nconst STATE_TAG = 4;\nconst STATE_ATTR_NAME = 5;\nconst STATE_ATTR_EQ = 6;\nconst STATE_ATTR_QUOT = 7;\nconst STATE_ATTR_VALUE = 8;\nconst STATE_CDATA = 9;\nconst STATE_IGNORE_CDATA = 10;\n\nclass SaxLtx extends events.EventEmitter {\n  constructor() {\n    super();\n    let state = STATE_TEXT;\n    let remainder;\n    let parseRemainder;\n    let tagName;\n    let attrs;\n    let endTag;\n    let selfClosing;\n    let attrQuote;\n    let attrQuoteChar;\n    let recordStart = 0;\n    let attrName;\n\n    this._handleTagOpening = function _handleTagOpening(\n      endTag,\n      tagName,\n      attrs\n    ) {\n      if (!endTag) {\n        this.emit(\"startElement\", tagName, attrs);\n        if (selfClosing) {\n          this.emit(\"endElement\", tagName, true);\n        }\n      } else {\n        this.emit(\"endElement\", tagName, false);\n      }\n    };\n\n    this.write = function write(data) {\n      if (typeof data !== \"string\") {\n        data = data.toString();\n      }\n      let pos = 0;\n\n      /* Anything from previous write()? */\n      if (remainder) {\n        data = remainder + data;\n        pos += !parseRemainder ? remainder.length : 0;\n        parseRemainder = false;\n        remainder = null;\n      }\n\n      function endRecording() {\n        if (typeof recordStart === \"number\") {\n          const recorded = data.slice(recordStart, pos);\n          recordStart = undefined;\n          return recorded;\n        }\n      }\n\n      for (; pos < data.length; pos++) {\n        switch (state) {\n          case STATE_TEXT: {\n            // if we're looping through text, fast-forward using indexOf to\n            // the next '<' character\n            const lt = data.indexOf(\"<\", pos);\n            if (lt !== -1 && pos !== lt) {\n              pos = lt;\n            }\n\n            break;\n          }\n          case STATE_ATTR_VALUE: {\n            // if we're looping through an attribute, fast-forward using\n            // indexOf to the next end quote character\n            const quot = data.indexOf(attrQuoteChar, pos);\n            if (quot !== -1) {\n              pos = quot;\n            }\n\n            break;\n          }\n          case STATE_IGNORE_COMMENT: {\n            // if we're looping through a comment, fast-forward using\n            // indexOf to the first end-comment character\n            const endcomment = data.indexOf(\"-->\", pos);\n            if (endcomment !== -1) {\n              pos = endcomment + 2; // target the '>' character\n            }\n\n            break;\n          }\n          case STATE_IGNORE_CDATA: {\n            // if we're looping through a CDATA, fast-forward using\n            // indexOf to the first end-CDATA character ]]>\n            const endCDATA = data.indexOf(\"]]>\", pos);\n            if (endCDATA !== -1) {\n              pos = endCDATA + 2; // target the '>' character\n            }\n\n            break;\n          }\n          // No default\n        }\n\n        const c = data.charCodeAt(pos);\n        switch (state) {\n          case STATE_TEXT:\n            if (c === 60 /* < */) {\n              const text = endRecording();\n              if (text) {\n                this.emit(\"text\", escape.unescapeXML(text));\n              }\n              state = STATE_TAG_NAME;\n              recordStart = pos + 1;\n              attrs = {};\n            }\n            break;\n          case STATE_CDATA:\n            if (c === 93 /* ] */) {\n              if (data.substr(pos + 1, 2) === \"]>\") {\n                const cData = endRecording();\n                if (cData) {\n                  this.emit(\"text\", cData);\n                }\n                state = STATE_TEXT;\n              } else if (data.length < pos + 2) {\n                parseRemainder = true;\n                pos = data.length;\n              }\n            }\n            break;\n          case STATE_TAG_NAME:\n            if (c === 47 /* / */ && recordStart === pos) {\n              recordStart = pos + 1;\n              endTag = true;\n            } else if (c === 33 /* ! */) {\n              if (data.substr(pos + 1, 7) === \"[CDATA[\") {\n                recordStart = pos + 8;\n                state = STATE_CDATA;\n              } else if (\n                data.length < pos + 8 &&\n                \"[CDATA[\".startsWith(data.slice(pos + 1))\n              ) {\n                // We potentially have CDATA, but the chunk is ending; stop here and let the next write() decide\n                parseRemainder = true;\n                pos = data.length;\n              } else {\n                recordStart = undefined;\n                state = STATE_IGNORE_COMMENT;\n              }\n            } else if (c === 63 /* ? */) {\n              recordStart = undefined;\n              state = STATE_IGNORE_INSTRUCTION;\n            } else if (c <= 32 || c === 47 /* / */ || c === 62 /* > */) {\n              tagName = endRecording();\n              pos--;\n              state = STATE_TAG;\n            }\n            break;\n          case STATE_IGNORE_COMMENT:\n            if (c === 62 /* > */) {\n              const prevFirst = data.charCodeAt(pos - 1);\n              const prevSecond = data.charCodeAt(pos - 2);\n              if (\n                (prevFirst === 45 /* - */ && prevSecond === 45) /* - */ ||\n                (prevFirst === 93 /* ] */ && prevSecond === 93) /* ] */\n              ) {\n                state = STATE_TEXT;\n              }\n            }\n            break;\n          case STATE_IGNORE_INSTRUCTION:\n            if (c === 62 /* > */) {\n              const prev = data.charCodeAt(pos - 1);\n              if (prev === 63 /* ? */) {\n                state = STATE_TEXT;\n              }\n            }\n            break;\n          case STATE_TAG:\n            if (c === 62 /* > */) {\n              this._handleTagOpening(endTag, tagName, attrs);\n              tagName = undefined;\n              attrs = undefined;\n              endTag = undefined;\n              selfClosing = undefined;\n              state = STATE_TEXT;\n              recordStart = pos + 1;\n            } else if (c === 47 /* / */) {\n              selfClosing = true;\n            } else if (c > 32) {\n              recordStart = pos;\n              state = STATE_ATTR_NAME;\n            }\n            break;\n          case STATE_ATTR_NAME:\n            if (c <= 32 || c === 61 /* = */) {\n              attrName = endRecording();\n              pos--;\n              state = STATE_ATTR_EQ;\n            }\n            break;\n          case STATE_ATTR_EQ:\n            if (c === 61 /* = */) {\n              state = STATE_ATTR_QUOT;\n            }\n            break;\n          case STATE_ATTR_QUOT:\n            if (c === 34 /* \" */ || c === 39 /* ' */) {\n              attrQuote = c;\n              attrQuoteChar = c === 34 ? '\"' : \"'\";\n              state = STATE_ATTR_VALUE;\n              recordStart = pos + 1;\n            }\n            break;\n          case STATE_ATTR_VALUE:\n            if (c === attrQuote) {\n              const value = escape.unescapeXML(endRecording());\n              attrs[attrName] = value;\n              attrName = undefined;\n              state = STATE_TAG;\n            }\n            break;\n        }\n      }\n\n      if (typeof recordStart === \"number\" && recordStart <= data.length) {\n        remainder = data.slice(recordStart);\n        recordStart = 0;\n      }\n    };\n  }\n\n  end(data) {\n    if (data) {\n      this.write(data);\n    }\n\n    /* Uh, yeah */\n    this.write = function write() {};\n  }\n}\n\nmodule.exports = SaxLtx;\n","export default class TimeoutError extends Error {\n  constructor(message) {\n    super(message);\n    this.name = \"TimeoutError\";\n  }\n}\n","import TimeoutError from \"./TimeoutError.js\";\nimport delay from \"./delay.js\";\n\nexport default function timeout(promise, ms) {\n  const promiseDelay = delay(ms);\n\n  function cancelDelay() {\n    clearTimeout(promiseDelay.timeout);\n  }\n\n  const error = new TimeoutError();\n  return Promise.race([\n    promise.finally(cancelDelay),\n    promiseDelay.then(() => {\n      throw error;\n    }),\n  ]);\n}\n","export default function delay(ms) {\n  let timeout;\n  const promise = new Promise((resolve) => {\n    timeout = setTimeout(resolve, ms);\n  });\n  promise.timeout = timeout;\n  return promise;\n}\n","const map = new WeakMap();\n\nexport default function onoff(target) {\n  let m = map.get(target);\n\n  if (!m) {\n    const on = (target.addEventListener ?? target.addListener).bind(target);\n    const off = (target.removeEventListener ?? target.removeListener).bind(\n      target,\n    );\n    const once = (\n      target.once ??\n      ((event, handler) =>\n        target.addEventListener(event, handler, { once: true }))\n    ).bind(target);\n    m = { on, off, once };\n    map.set(target, m);\n  }\n\n  return m;\n}\n","import onoff from \"./onoff.js\";\nimport TimeoutError from \"./TimeoutError.js\";\n\nexport default function promise(target, event, rejectEvent = \"error\", timeout) {\n  return new Promise((resolve, reject) => {\n    let timeoutId;\n\n    const { off, once } = onoff(target);\n\n    const cleanup = () => {\n      clearTimeout(timeoutId);\n      off(event, onEvent);\n      off(rejectEvent, onError);\n    };\n\n    function onError(reason) {\n      reject(reason);\n      cleanup();\n    }\n\n    function onEvent(value) {\n      resolve(value);\n      cleanup();\n    }\n\n    once(event, onEvent);\n    if (rejectEvent) {\n      once(rejectEvent, onError);\n    }\n\n    if (timeout) {\n      const error = new TimeoutError();\n      timeoutId = setTimeout(() => {\n        cleanup();\n        reject(error);\n      }, timeout);\n    }\n  });\n}\n","export default function Deferred() {\n  this.promise = new Promise((resolve, reject) => {\n    this.resolve = resolve;\n    this.reject = reject;\n  });\n}\n","export default function procedure(entity, stanza = null, handler) {\n  return new Promise((resolve, reject) => {\n    function onError(err) {\n      entity.removeListener(\"nonza\", listener);\n      reject(err);\n    }\n\n    function done(...args) {\n      entity.removeListener(\"nonza\", listener);\n      resolve(...args);\n    }\n\n    async function listener(element) {\n      try {\n        await handler(element, done);\n      } catch (err) {\n        onError(err);\n      }\n    }\n\n    stanza && entity.send(stanza).catch(onError);\n    entity.on(\"nonza\", listener);\n  });\n}\n","import onoff from \"./onoff.js\";\n\nexport default function listeners(events) {\n  return {\n    subscribe(target) {\n      const { on } = onoff(target);\n      for (const [event, handler] of Object.entries(events)) {\n        on(event, handler);\n      }\n    },\n    unsubscribe(target) {\n      const { off } = onoff(target);\n      for (const [event, handler] of Object.entries(events)) {\n        off(event, handler);\n      }\n    },\n  };\n}\n","export default class XMLError extends Error {\n  constructor(...args) {\n    super(...args);\n    this.name = \"XMLError\";\n  }\n}\n","import LtxParser from \"ltx/lib/parsers/ltx.js\";\nimport Element from \"ltx/lib/Element.js\";\nimport { EventEmitter } from \"@xmpp/events\";\n\nimport XMLError from \"./XMLError.js\";\n\nclass Parser extends EventEmitter {\n  constructor() {\n    super();\n    const parser = new LtxParser();\n    this.root = null;\n    this.cursor = null;\n\n    parser.on(\"startElement\", this.onStartElement.bind(this));\n    parser.on(\"endElement\", this.onEndElement.bind(this));\n    parser.on(\"text\", this.onText.bind(this));\n\n    this.parser = parser;\n  }\n\n  onStartElement(name, attrs) {\n    const element = new Element(name, attrs);\n\n    const { root, cursor } = this;\n\n    if (!root) {\n      this.root = element;\n      this.emit(\"start\", element);\n    } else if (cursor !== root) {\n      cursor.append(element);\n    }\n\n    this.cursor = element;\n  }\n\n  onEndElement(name) {\n    const { root, cursor } = this;\n    if (name !== cursor.name) {\n      // <foo></bar>\n      this.emit(\"error\", new XMLError(`${cursor.name} must be closed.`));\n      return;\n    }\n\n    if (cursor === root) {\n      this.emit(\"end\", root);\n      return;\n    }\n\n    if (!cursor.parent) {\n      cursor.parent = root;\n      this.emit(\"element\", cursor);\n      this.cursor = root;\n      return;\n    }\n\n    this.cursor = cursor.parent;\n  }\n\n  onText(str) {\n    const { cursor } = this;\n    if (!cursor) {\n      this.emit(\"error\", new XMLError(`${str} must be a child.`));\n      return;\n    }\n\n    cursor.t(str);\n  }\n\n  write(data) {\n    this.parser.write(data);\n  }\n\n  end(data) {\n    if (data) {\n      this.parser.write(data);\n    }\n  }\n}\n\nParser.XMLError = XMLError;\n\nexport default Parser;\n","import Element from \"ltx/lib/Element.js\";\nimport createElement from \"ltx/lib/createElement.js\";\nimport {\n  escapeXML,\n  unescapeXML,\n  escapeXMLText,\n  unescapeXMLText,\n} from \"ltx/lib/escape.js\";\n\nimport Parser from \"./lib/Parser.js\";\nimport XMLError from \"./lib/XMLError.js\";\n\nexport default function xml(...args) {\n  return createElement(...args);\n}\n\nObject.assign(xml, {\n  Element,\n  createElement,\n  Parser,\n  escapeXML,\n  unescapeXML,\n  escapeXMLText,\n  unescapeXMLText,\n  XMLError,\n  xml,\n});\n\nexport {\n  Element,\n  createElement,\n  Parser,\n  escapeXML,\n  unescapeXML,\n  escapeXMLText,\n  unescapeXMLText,\n  XMLError,\n  xml,\n};\n","export function detect(local) {\n  if (!local) {\n    return false;\n  }\n\n  // Remove all escaped sequences\n  const tmp = local\n    .replaceAll(String.raw`\\20`, \"\")\n    .replaceAll(String.raw`\\22`, \"\")\n    .replaceAll(String.raw`\\26`, \"\")\n    .replaceAll(String.raw`\\27`, \"\")\n    .replaceAll(String.raw`\\2f`, \"\")\n    .replaceAll(String.raw`\\3a`, \"\")\n    .replaceAll(String.raw`\\3c`, \"\")\n    .replaceAll(String.raw`\\3e`, \"\")\n    .replaceAll(String.raw`\\40`, \"\")\n    .replaceAll(String.raw`\\5c`, \"\");\n\n  // Detect if we have unescaped sequences\n  const search = tmp.search(/[ \"&'/:<>@\\\\]/g);\n  if (search === -1) {\n    return false;\n  }\n\n  return true;\n}\n\n/**\n * Escape the local part of a JID.\n *\n * @see http://xmpp.org/extensions/xep-0106.html\n * @param String local local part of a jid\n * @return An escaped local part\n */\nexport function escape(local) {\n  if (local === null) {\n    return null;\n  }\n\n  return local\n    .replaceAll(/^\\s+|\\s+$/g, \"\")\n    .replaceAll(\"\\\\\", String.raw`\\5c`)\n    .replaceAll(\" \", String.raw`\\20`)\n    .replaceAll('\"', String.raw`\\22`)\n    .replaceAll(\"&\", String.raw`\\26`)\n    .replaceAll(\"'\", String.raw`\\27`)\n    .replaceAll(\"/\", String.raw`\\2f`)\n    .replaceAll(\":\", String.raw`\\3a`)\n    .replaceAll(\"<\", String.raw`\\3c`)\n    .replaceAll(\">\", String.raw`\\3e`)\n    .replaceAll(\"@\", String.raw`\\40`);\n}\n\n/**\n * Unescape a local part of a JID.\n *\n * @see http://xmpp.org/extensions/xep-0106.html\n * @param String local local part of a jid\n * @return unescaped local part\n */\nexport function unescape(local) {\n  if (local === null) {\n    return null;\n  }\n\n  return local\n    .replaceAll(String.raw`\\20`, \" \")\n    .replaceAll(String.raw`\\22`, '\"')\n    .replaceAll(String.raw`\\26`, \"&\")\n    .replaceAll(String.raw`\\27`, \"'\")\n    .replaceAll(String.raw`\\2f`, \"/\")\n    .replaceAll(String.raw`\\3a`, \":\")\n    .replaceAll(String.raw`\\3c`, \"<\")\n    .replaceAll(String.raw`\\3e`, \">\")\n    .replaceAll(String.raw`\\40`, \"@\")\n    .replaceAll(String.raw`\\5c`, \"\\\\\");\n}\n","import * as escaping from \"./escaping.js\";\n\n/**\n * JID implements\n * - XMPP addresses according to RFC6122\n * - XEP-0106: JID Escaping\n *\n * @see http://tools.ietf.org/html/rfc6122#section-2\n * @see http://xmpp.org/extensions/xep-0106.html\n */\nclass JID {\n  constructor(local, domain, resource) {\n    if (typeof domain !== \"string\" || !domain) {\n      throw new TypeError(`Invalid domain.`);\n    }\n\n    this.setDomain(domain);\n    this.setLocal(typeof local === \"string\" ? local : \"\");\n    this.setResource(typeof resource === \"string\" ? resource : \"\");\n  }\n\n  [Symbol.toPrimitive](hint) {\n    if (hint === \"number\") {\n      return Number.NaN;\n    }\n\n    return this.toString();\n  }\n\n  toString(unescape) {\n    let s = this._domain;\n    if (this._local) {\n      s = this.getLocal(unescape) + \"@\" + s;\n    }\n\n    if (this._resource) {\n      s = s + \"/\" + this._resource;\n    }\n\n    return s;\n  }\n\n  /**\n   * Convenience method to distinguish users\n   * */\n  bare() {\n    if (this._resource) {\n      return new JID(this._local, this._domain, null);\n    }\n\n    return this;\n  }\n\n  /**\n   * Comparison function\n   * */\n  equals(other) {\n    return (\n      this._local === other._local &&\n      this._domain === other._domain &&\n      this._resource === other._resource\n    );\n  }\n\n  /**\n   * http://xmpp.org/rfcs/rfc6122.html#addressing-localpart\n   * */\n  setLocal(local, escape) {\n    escape = escape || escaping.detect(local);\n\n    if (escape) {\n      local = escaping.escape(local);\n    }\n\n    this._local = local && local.toLowerCase();\n    return this;\n  }\n\n  getLocal(unescape = false) {\n    let local = null;\n\n    local = unescape ? escaping.unescape(this._local) : this._local;\n\n    return local;\n  }\n\n  /**\n   * http://xmpp.org/rfcs/rfc6122.html#addressing-domain\n   */\n  setDomain(domain) {\n    this._domain = domain.toLowerCase();\n    return this;\n  }\n\n  getDomain() {\n    return this._domain;\n  }\n\n  /**\n   * http://xmpp.org/rfcs/rfc6122.html#addressing-resourcepart\n   */\n  setResource(resource) {\n    this._resource = resource;\n    return this;\n  }\n\n  getResource() {\n    return this._resource;\n  }\n}\n\nObject.defineProperty(JID.prototype, \"local\", {\n  get: JID.prototype.getLocal,\n  set: JID.prototype.setLocal,\n});\n\nObject.defineProperty(JID.prototype, \"domain\", {\n  get: JID.prototype.getDomain,\n  set: JID.prototype.setDomain,\n});\n\nObject.defineProperty(JID.prototype, \"resource\", {\n  get: JID.prototype.getResource,\n  set: JID.prototype.setResource,\n});\n\nexport default JID;\n","import JID from \"./JID.js\";\n\nexport default function parse(s) {\n  let local;\n  let resource;\n\n  const resourceStart = s.indexOf(\"/\");\n  if (resourceStart !== -1) {\n    resource = s.slice(resourceStart + 1);\n    s = s.slice(0, resourceStart);\n  }\n\n  const atStart = s.indexOf(\"@\");\n  if (atStart !== -1) {\n    local = s.slice(0, atStart);\n    s = s.slice(atStart + 1);\n  }\n\n  return new JID(local, s, resource);\n}\n","import JID from \"./lib/JID.js\";\nimport { detect, escape, unescape } from \"./lib/escaping.js\";\nimport parse from \"./lib/parse.js\";\n\nexport function equal(a, b) {\n  return a.equals(b);\n}\n\nfunction jid(...args) {\n  if (!args[1] && !args[2]) {\n    return parse(...args);\n  }\n\n  return new JID(...args);\n}\n\nconst j = jid.bind();\nj.jid = jid;\nj.JID = JID;\nj.parse = parse;\nj.equal = equal;\nj.detectEscape = detect;\nj.escapeLocal = escape;\nj.unescapeLocal = unescape;\n\nexport default j;\n\nexport { jid, JID, parse };\n\nexport {\n  detect as detectEscape,\n  escape as escapeLocal,\n  unescape as unescapeLocal,\n};\n","// https://xmpp.org/rfcs/rfc6120.html#rfc.section.4.9.2\n\nclass XMPPError extends Error {\n  constructor(condition, text, application) {\n    super(condition + (text ? ` - ${text}` : \"\"));\n    this.name = \"XMPPError\";\n    this.condition = condition;\n    this.text = text;\n    this.application = application;\n  }\n\n  static fromElement(element) {\n    const [condition, second, third] = element.getChildElements();\n    let text;\n    let application;\n\n    if (second) {\n      if (second.is(\"text\")) {\n        text = second;\n      } else if (second) {\n        application = second;\n      }\n\n      if (third) application = third;\n    }\n\n    const error = new this(\n      condition.name,\n      text ? text.text() : \"\",\n      application,\n    );\n    error.element = element;\n    return error;\n  }\n}\n\nexport default XMPPError;\n","import XMPPError from \"@xmpp/error\";\n\n// https://xmpp.org/rfcs/rfc6120.html#streams-error\n\nclass StreamError extends XMPPError {\n  constructor(...args) {\n    super(...args);\n    this.name = \"StreamError\";\n  }\n}\n\nexport default StreamError;\n","function parseURI(URI) {\n  let { port, hostname, protocol } = new URL(URI);\n  // https://github.com/nodejs/node/issues/12410#issuecomment-294138912\n  if (hostname === \"[::1]\") {\n    hostname = \"::1\";\n  }\n\n  return { port, hostname, protocol };\n}\n\nfunction parseHost(host) {\n  const { port, hostname } = parseURI(`http://${host}`);\n  return { port, hostname };\n}\n\nfunction parseService(service) {\n  return service.includes(\"://\") ? parseURI(service) : parseHost(service);\n}\n\nexport { parseURI, parseHost, parseService };\n","import { EventEmitter, promise, listeners } from \"@xmpp/events\";\nimport jid from \"@xmpp/jid\";\nimport xml from \"@xmpp/xml\";\n\nimport StreamError from \"./lib/StreamError.js\";\nimport { parseHost, parseService } from \"./lib/util.js\";\n\nconst NS_STREAM = \"urn:ietf:params:xml:ns:xmpp-streams\";\nconst NS_JABBER_STREAM = \"http://etherx.jabber.org/streams\";\n\nclass Connection extends EventEmitter {\n  #socketListeners = null;\n  #parserListeners = null;\n\n  constructor(options = {}) {\n    super();\n\n    if (typeof options === \"string\") {\n      options = { domain: options };\n    }\n\n    this.jid = null;\n    this.timeout = options.timeout || 2000;\n    this.options = options;\n    this.status = \"offline\";\n    this.socket = null;\n    this.parser = null;\n    this.root = null;\n  }\n\n  isSecure() {\n    return this.socket?.secure === true;\n  }\n\n  async _streamError(condition, children) {\n    try {\n      await this.send(\n        // prettier-ignore\n        xml('stream:error', {}, [\n          xml(condition, {xmlns: NS_STREAM}, children),\n        ]),\n      );\n    } catch {}\n\n    return this.disconnect();\n  }\n\n  _onData(data) {\n    const str = data.toString(\"utf8\");\n    this.parser.write(str);\n  }\n\n  #onParserError(error) {\n    // https://xmpp.org/rfcs/rfc6120.html#streams-error-conditions-bad-format\n    // \"This error can be used instead of the more specific XML-related errors,\n    // such as <bad-namespace-prefix/>, <invalid-xml/>, <not-well-formed/>, <restricted-xml/>,\n    // and <unsupported-encoding/>. However, the more specific errors are RECOMMENDED.\"\n    this._streamError(\"bad-format\");\n    this._detachParser();\n    this.emit(\"error\", error);\n  }\n\n  #onSocketClosed(dirty, reason) {\n    this._detachSocket();\n    this._status(\"disconnect\", { clean: !dirty, reason });\n  }\n\n  #onStreamClosed(dirty, reason) {\n    this._detachParser();\n    this._status(\"close\", { clean: !dirty, reason });\n  }\n\n  _attachSocket(socket) {\n    this.socket = socket;\n    this.#socketListeners ??= listeners({\n      data: this._onData.bind(this),\n      close: this.#onSocketClosed.bind(this),\n      connect: () => this._status(\"connect\"),\n      error: (error) => this.emit(\"error\", error),\n    });\n    this.#socketListeners.subscribe(this.socket);\n  }\n\n  _detachSocket() {\n    this.socket && this.#socketListeners?.unsubscribe(this.socket);\n    this.socket = null;\n  }\n\n  _onElement(element) {\n    const isStreamError = element.is(\"error\", NS_JABBER_STREAM);\n\n    if (isStreamError) {\n      this._onStreamError(element);\n    }\n\n    this.emit(\"element\", element);\n    this.emit(this.isStanza(element) ? \"stanza\" : \"nonza\", element);\n\n    if (isStreamError) {\n      // \"Stream Errors Are Unrecoverable\"\n      // \"The entity that receives the stream error then SHALL close the stream\"\n      this.disconnect();\n    }\n  }\n\n  // https://xmpp.org/rfcs/rfc6120.html#streams-error\n  _onStreamError(element) {\n    const error = StreamError.fromElement(element);\n\n    if (error.condition === \"see-other-host\") {\n      return this._onSeeOtherHost(error);\n    }\n\n    this.emit(\"error\", error);\n  }\n\n  // https://xmpp.org/rfcs/rfc6120.html#streams-error-conditions-see-other-host\n  async _onSeeOtherHost(error) {\n    const { protocol } = parseService(this.options.service);\n\n    const host = error.element.getChildText(\"see-other-host\");\n    const { port } = parseHost(host);\n\n    let service;\n    service = port\n      ? `${protocol || \"xmpp:\"}//${host}`\n      : (protocol ? `${protocol}//` : \"\") + host;\n\n    try {\n      await promise(this, \"disconnect\");\n      const { domain, lang } = this.options;\n      await this.connect(service);\n      await this.open({ domain, lang });\n    } catch (err) {\n      this.emit(\"error\", err);\n    }\n  }\n\n  _attachParser(parser) {\n    this.parser = parser;\n    this.#parserListeners ??= listeners({\n      element: this._onElement.bind(this),\n      error: this.#onParserError.bind(this),\n      end: this.#onStreamClosed.bind(this),\n      start: (element) => this._status(\"open\", element),\n    });\n    this.#parserListeners.subscribe(this.parser);\n  }\n\n  _detachParser() {\n    this.parser && this.#parserListeners?.unsubscribe(this.parser);\n    this.parser = null;\n    this.root = null;\n  }\n\n  _jid(id) {\n    this.jid = jid(id);\n    return this.jid;\n  }\n\n  /*\n  [\n    \"offline\",\n    // \"disconnect\",\n    \"connecting\",\n    \"connected\",\n    \"opening\",\n    \"open\",\n    \"online\",\n    \"closing\",\n    \"close\",\n    \"disconnecting\",\n    \"disconnect\",\n    \"offline\",\n  ];\n  */\n  _status(status, ...args) {\n    if (this.status === status) return;\n    this.status = status;\n    this.emit(\"status\", status, ...args);\n    this.emit(status, ...args);\n  }\n\n  _ready(resumed = false) {\n    if (resumed) {\n      this.status = \"online\";\n    } else {\n      this._status(\"online\", this.jid);\n    }\n  }\n\n  async disconnect() {\n    let el;\n\n    try {\n      el = await this._closeStream();\n    } catch (err) {\n      this.#onStreamClosed(err);\n    }\n\n    try {\n      await this._closeSocket();\n    } catch (err) {\n      this.#onSocketClosed(true, err);\n    }\n\n    return el;\n  }\n\n  /**\n   * Opens the socket then opens the stream\n   */\n  async start() {\n    if (this.status !== \"offline\") {\n      throw new Error(\"Connection is not offline\");\n    }\n\n    const { service, domain, lang } = this.options;\n\n    await this.connect(service);\n\n    const promiseOnline = promise(this, \"online\");\n\n    await this.open({ domain, lang });\n\n    return promiseOnline;\n  }\n\n  /**\n   * Connects the socket\n   */\n  async connect(service) {\n    this._status(\"connecting\", service);\n    const socket = new this.Socket();\n    this._attachSocket(socket);\n    // The 'connect' status is set by the socket 'connect' listener\n    socket.connect(this.socketParameters(service));\n    return promise(socket, \"connect\");\n  }\n\n  /**\n   * Disconnects the socket\n   * https://xmpp.org/rfcs/rfc6120.html#streams-close\n   * https://tools.ietf.org/html/rfc7395#section-3.6\n   */\n  async _closeSocket(timeout = this.timeout) {\n    this._status(\"disconnecting\");\n    this.socket.end();\n\n    // The 'disconnect' status is set by the socket 'close' listener\n    await promise(this.socket, \"close\", \"error\", timeout);\n  }\n\n  /**\n   * Opens the stream\n   */\n  async open(options) {\n    this._status(\"opening\");\n\n    const { domain, lang } = options;\n\n    const headerElement = this.headerElement();\n    headerElement.attrs.to = domain;\n    headerElement.attrs[\"xml:lang\"] = lang;\n    this.root = headerElement;\n\n    this._attachParser(new this.Parser());\n\n    await this.write(this.header(headerElement));\n    return promise(this, \"open\", \"error\", this.timeout);\n  }\n\n  /**\n   * Closes the stream then closes the socket\n   * https://xmpp.org/rfcs/rfc6120.html#streams-close\n   * https://tools.ietf.org/html/rfc7395#section-3.6\n   */\n  async stop() {\n    const el = await this.disconnect();\n    this._status(\"offline\", el);\n    return el;\n  }\n\n  /**\n   * Closes the stream and wait for the server to close it\n   * https://xmpp.org/rfcs/rfc6120.html#streams-close\n   * https://tools.ietf.org/html/rfc7395#section-3.6\n   */\n  async _closeStream(timeout = this.timeout) {\n    await this.#runHooks(\"close\");\n\n    const fragment = this.footer(this.footerElement());\n\n    await this.write(fragment);\n    this._status(\"closing\");\n    return promise(this.parser, \"end\", \"error\", timeout);\n    // The 'close' status is set by the parser 'end' listener\n  }\n\n  /**\n   * Restart the stream\n   * https://xmpp.org/rfcs/rfc6120.html#streams-negotiation-restart\n   */\n  async restart() {\n    this._detachParser();\n    const { domain, lang } = this.options;\n    return this.open({ domain, lang });\n  }\n\n  async send(element) {\n    element.parent = this.root;\n    await this.write(element.toString());\n    this.emit(\"send\", element);\n  }\n\n  sendReceive(element, timeout = this.timeout) {\n    return Promise.all([\n      this.send(element),\n      promise(this, \"element\", \"error\", timeout),\n    ]).then(([, el]) => el);\n  }\n\n  async write(string) {\n    // https://xmpp.org/rfcs/rfc6120.html#streams-close\n    // \"Refrain from sending any further data over its outbound stream to the other entity\"\n    if (this.status === \"closing\") {\n      throw new Error(\"Connection is closing\");\n    }\n\n    return new Promise((resolve, reject) => {\n      this.socket.write(string, (err) => (err ? reject(err) : resolve()));\n    });\n  }\n\n  isStanza(element) {\n    const { name } = element;\n    return name === \"iq\" || name === \"message\" || name === \"presence\";\n  }\n\n  isNonza(element) {\n    return !this.isStanza(element);\n  }\n\n  // Override\n  header(el) {\n    return el.toString();\n  }\n\n  // Override\n  headerElement() {\n    return new xml.Element(\"\", {\n      version: \"1.0\",\n      xmlns: this.NS,\n    });\n  }\n\n  // Override\n  footer(el) {\n    return el.toString();\n  }\n\n  // Override\n  footerElement() {}\n\n  // Override\n  socketParameters() {}\n\n  /* Experimental hooks */\n  #hooks = new Map();\n  #hook_events = new Set([\"close\"]);\n  hook(event, handler /*priority = 0 TODO */) {\n    this.#assertHookEventName(event);\n\n    if (!this.#hooks.has(event)) {\n      this.#hooks.set(event, new Set());\n    }\n\n    this.#hooks.get(event).add([handler]);\n  }\n  #assertHookEventName(event) {\n    if (!this.#hook_events.has(event)) {\n      throw new Error(`Hook event name \"${event}\" is unknown.`);\n    }\n  }\n  unhook(event, handler) {\n    this.#assertHookEventName(event);\n    const handlers = this.#hooks.get(\"event\");\n    const item = [...handlers].find((item) => item.handler === handler);\n    handlers.remove(item);\n  }\n  async #runHooks(event, ...args) {\n    this.#assertHookEventName(event);\n\n    const hooks = this.#hooks.get(event);\n    if (!hooks) return;\n\n    // TODO run hooks by priority\n    // run hooks with the same priority in parallel\n\n    await Promise.all(\n      [...hooks].map(async ([handler]) => {\n        try {\n          await handler(...args);\n        } catch (err) {\n          this.emit(\"error\", err);\n        }\n      }),\n    );\n  }\n}\n\n// Override\nConnection.prototype.NS = \"\";\nConnection.prototype.Socket = null;\nConnection.prototype.Parser = null;\n\nexport default Connection;\n","import Connection from \"@xmpp/connection\";\n\nclass Client extends Connection {\n  constructor(options) {\n    super(options);\n    this.transports = [];\n  }\n\n  send(element, ...args) {\n    return this.Transport.prototype.send.call(this, element, ...args);\n  }\n\n  sendMany(...args) {\n    return this.Transport.prototype.sendMany.call(this, ...args);\n  }\n\n  _findTransport(service) {\n    return this.transports.find((Transport) => {\n      try {\n        return Transport.prototype.socketParameters(service) !== undefined;\n      } catch {\n        return false;\n      }\n    });\n  }\n\n  connect(service) {\n    const Transport = this._findTransport(service);\n\n    if (!Transport) {\n      throw new Error(\"No compatible connection method found.\");\n    }\n\n    this.Transport = Transport;\n    this.Socket = Transport.prototype.Socket;\n    this.Parser = Transport.prototype.Parser;\n\n    return super.connect(service);\n  }\n\n  socketParameters(...args) {\n    return this.Transport.prototype.socketParameters(...args);\n  }\n\n  header(headerElement, ...args) {\n    // if the client knows the XMPP identity then it SHOULD include the 'from' attribute\n    // after the confidentiality and integrity of the stream are protected via TLS\n    // or an equivalent security layer.\n    // https://xmpp.org/rfcs/rfc6120.html#rfc.section.4.7.1\n    const from = this.isSecure() && this.jid?.bare().toString();\n    if (from) headerElement.attrs.from = from;\n    return this.Transport.prototype.header(headerElement, ...args);\n  }\n\n  headerElement(...args) {\n    return this.Transport.prototype.headerElement(...args);\n  }\n\n  footer(...args) {\n    return this.Transport.prototype.footer(...args);\n  }\n\n  footerElement(...args) {\n    return this.Transport.prototype.footerElement(...args);\n  }\n}\n\nClient.prototype.NS = \"jabber:client\";\n\nexport default Client;\n","import { EventEmitter } from \"@xmpp/events\";\n\nclass Reconnect extends EventEmitter {\n  constructor(entity) {\n    super();\n\n    this.delay = 1000;\n    this.entity = entity;\n    this._timeout = null;\n  }\n\n  #onDisconnect = () => {\n    this.scheduleReconnect();\n  };\n\n  scheduleReconnect() {\n    const { entity, delay, _timeout } = this;\n    clearTimeout(_timeout);\n    this._timeout = setTimeout(async () => {\n      if (entity.status !== \"disconnect\") {\n        return;\n      }\n\n      try {\n        await this.reconnect();\n      } catch {\n        // Ignoring the rejection is safe because the error is emitted on entity by #start\n      }\n    }, delay);\n  }\n\n  async reconnect() {\n    const { entity } = this;\n    this.emit(\"reconnecting\");\n\n    const { service, domain, lang } = entity.options;\n    await entity.connect(service);\n    await entity.open({ domain, lang });\n\n    this.emit(\"reconnected\");\n  }\n\n  start() {\n    const { entity } = this;\n    entity.on(\"disconnect\", this.#onDisconnect);\n  }\n\n  stop() {\n    const { entity, _timeout } = this;\n    entity.removeListener(\"disconnect\", this.#onDisconnect);\n    clearTimeout(_timeout);\n  }\n}\n\nexport default function reconnect({ entity }) {\n  const r = new Reconnect(entity);\n  r.start();\n  return r;\n}\n","import { EventEmitter, listeners } from \"@xmpp/events\";\nimport { parseURI } from \"@xmpp/connection/lib/util.js\";\n\nconst CODE = \"ECONNERROR\";\n\nexport function isSecure(url) {\n  const uri = parseURI(url);\n  if (uri.protocol === \"wss:\") return true;\n  if ([\"localhost\", \"127.0.0.1\", \"::1\"].includes(uri.hostname)) return true;\n  return false;\n}\n\nexport default class Socket extends EventEmitter {\n  #listeners = null;\n  socket = null;\n  url = null;\n  secure = false;\n\n  connect(url) {\n    this.url = url;\n    this.secure = isSecure(url);\n    // eslint-disable-next-line n/no-unsupported-features/node-builtins\n    this._attachSocket(new WebSocket(url, [\"xmpp\"]));\n  }\n\n  _attachSocket(socket) {\n    this.socket = socket;\n    this.#listeners ??= listeners({\n      open: () => this.emit(\"connect\"),\n      message: ({ data }) => this.emit(\"data\", data),\n      error: (event) => {\n        const { url } = this;\n        // WS\n        let { error } = event;\n        // DOM\n        if (!error) {\n          error = new Error(event.message || `WebSocket ${CODE} ${url}`);\n          error.errno = CODE;\n          error.code = CODE;\n        }\n\n        error.event = event;\n        error.url = url;\n        this.emit(\"error\", error);\n      },\n      close: (event) => {\n        this._detachSocket();\n        this.emit(\"close\", !event.wasClean, event);\n      },\n    });\n    this.#listeners.subscribe(this.socket);\n  }\n\n  _detachSocket() {\n    this.url = null;\n    this.secure = false;\n    this.socket && this.#listeners?.unsubscribe(this.socket);\n    this.socket = null;\n  }\n\n  end() {\n    this.socket.close();\n  }\n\n  write(data, fn) {\n    function done(err) {\n      if (!fn) return;\n      // eslint-disable-next-line promise/catch-or-return, promise/no-promise-in-callback\n      Promise.resolve().then(() => fn(err));\n    }\n\n    try {\n      this.socket.send(data);\n    } catch (err) {\n      done(err);\n      return;\n    }\n    done();\n  }\n}\n","import Connection from \"@xmpp/connection\";\nimport xml from \"@xmpp/xml\";\n\nimport Socket from \"./Socket.js\";\nimport FramedParser from \"./FramedParser.js\";\n\nconst NS_FRAMING = \"urn:ietf:params:xml:ns:xmpp-framing\";\n\n/* References\n * WebSocket protocol https://tools.ietf.org/html/rfc6455\n * WebSocket Web API https://html.spec.whatwg.org/multipage/comms.html#network\n * XMPP over WebSocket https://tools.ietf.org/html/rfc7395\n */\n\nclass ConnectionWebSocket extends Connection {\n  send(element, ...args) {\n    element.attrs.xmlns ??= this.NS;\n    return super.send(element, ...args);\n  }\n\n  async sendMany(elements) {\n    for (const element of elements) {\n      element.attrs.xmlns ??= this.NS;\n      element.parent = this.root;\n      this.socket.write(element.toString());\n      this.emit(\"send\", element);\n    }\n  }\n\n  // https://tools.ietf.org/html/rfc7395#section-3.6\n  footerElement() {\n    return new xml.Element(\"close\", {\n      xmlns: NS_FRAMING,\n    });\n  }\n\n  // https://tools.ietf.org/html/rfc7395#section-3.4\n  headerElement() {\n    const el = super.headerElement();\n    el.name = \"open\";\n    el.attrs.xmlns = NS_FRAMING;\n    return el;\n  }\n\n  socketParameters(service) {\n    return /^wss?:\\/\\//.test(service) ? service : undefined;\n  }\n}\n\nConnectionWebSocket.prototype.Socket = Socket;\nConnectionWebSocket.prototype.NS = \"jabber:client\";\nConnectionWebSocket.prototype.Parser = FramedParser;\n\nexport default ConnectionWebSocket;\n","import { Parser, Element, XMLError } from \"@xmpp/xml\";\n\nexport default class FramedParser extends Parser {\n  onStartElement(name, attrs) {\n    const element = new Element(name, attrs);\n\n    const { cursor } = this;\n\n    if (cursor) {\n      cursor.append(element);\n    }\n\n    this.cursor = element;\n  }\n\n  onEndElement(name) {\n    const { cursor } = this;\n    if (name !== cursor.name) {\n      // <foo></bar>\n      this.emit(\"error\", new XMLError(`${cursor.name} must be closed.`));\n      return;\n    }\n\n    if (cursor.parent) {\n      this.cursor = cursor.parent;\n      return;\n    }\n\n    if (cursor.is(\"open\", \"urn:ietf:params:xml:ns:xmpp-framing\")) {\n      this.emit(\"start\", cursor);\n    } else if (cursor.is(\"close\", \"urn:ietf:params:xml:ns:xmpp-framing\")) {\n      this.emit(\"end\", cursor);\n    } else {\n      this.emit(\"element\", cursor);\n    }\n\n    this.cursor = null;\n  }\n}\n","import { Socket as TCPSocket } from \"node:net\";\n\nexport default class Socket extends TCPSocket {\n  secure = false;\n}\n","import Connection from \"@xmpp/connection\";\nimport { Parser } from \"@xmpp/xml\";\nimport { parseURI } from \"@xmpp/connection/lib/util.js\";\n\nimport Socket from \"./Socket.js\";\n\nconst NS_STREAM = \"http://etherx.jabber.org/streams\";\n\n/* References\n * Extensible Messaging and Presence Protocol (XMPP): Core http://xmpp.org/rfcs/rfc6120.html\n */\nclass ConnectionTCP extends Connection {\n  async sendMany(elements) {\n    let fragment = \"\";\n\n    for (const element of elements) {\n      element.parent = this.root;\n      fragment += element.toString();\n    }\n\n    await this.write(fragment);\n\n    for (const element of elements) {\n      this.emit(\"send\", element);\n    }\n  }\n\n  socketParameters(service) {\n    const { port, hostname, protocol } = parseURI(service);\n\n    return protocol === \"xmpp:\"\n      ? { port: port ? Number(port) : null, host: hostname }\n      : undefined;\n  }\n\n  // https://xmpp.org/rfcs/rfc6120.html#streams-open\n  headerElement() {\n    const el = super.headerElement();\n    el.name = \"stream:stream\";\n    el.attrs[\"xmlns:stream\"] = NS_STREAM;\n    return el;\n  }\n\n  // https://xmpp.org/rfcs/rfc6120.html#streams-open\n  header(el) {\n    return `<?xml version='1.0'?>${el.toString().slice(0, -2)}>`;\n  }\n\n  // https://xmpp.org/rfcs/rfc6120.html#streams-close\n  footer() {\n    return \"</stream:stream>\";\n  }\n}\n\nConnectionTCP.prototype.NS = NS_STREAM;\nConnectionTCP.prototype.Socket = Socket;\nConnectionTCP.prototype.Parser = Parser;\n\nexport default ConnectionTCP;\n","import Connection from \"@xmpp/connection-tcp\";\n\nclass ConnectionTCP extends Connection {\n  socketParameters(service) {\n    const params = super.socketParameters(service);\n    if (!params) return params;\n    params.port = params.port || 5222;\n    return params;\n  }\n}\n\nConnectionTCP.prototype.NS = \"jabber:client\";\n\nexport default ConnectionTCP;\n","import ConnectionTCP from \"./lib/Connection.js\";\n\nexport default function tcp({ entity }) {\n  entity.transports.push(ConnectionTCP);\n}\n","import tls from \"node:tls\";\n\nimport { EventEmitter, listeners } from \"@xmpp/events\";\n\nclass Socket extends EventEmitter {\n  timeout = null;\n  #listeners = null;\n  socket = null;\n  secure = true;\n\n  connect(...args) {\n    this._attachSocket(tls.connect(...args));\n  }\n\n  _attachSocket(socket) {\n    this.socket = socket;\n    this.#listeners ??= listeners({\n      close: () => {\n        this._detachSocket();\n        this.emit(\"close\");\n      },\n      data: (data) => {\n        this.emit(\"data\", data);\n      },\n      error: (err) => {\n        this.emit(\"error\", err);\n      },\n      secureConnect: () => {\n        if (this.socket.getProtocol() !== \"TLSv1.3\") {\n          return this.emit(\"connect\");\n        }\n\n        // Waiting before sending the stream header improves compatibility\n        // with Openfire TLSv1.3 implementation. For more info, see:\n        // https://github.com/xmppjs/xmpp.js/issues/889#issuecomment-902686879\n        // https://github.com/xmppjs/xmpp.js/pull/912\n        this.timeout = setTimeout(() => {\n          this.emit(\"connect\");\n        }, 1);\n      },\n    });\n    this.#listeners.subscribe(this.socket);\n  }\n\n  _detachSocket() {\n    this.#listeners.unsubscribe(this.socket);\n    this.socket = null;\n  }\n\n  end() {\n    this.socket.end();\n  }\n\n  write(data, fn) {\n    this.socket.write(data, fn);\n  }\n}\n\nexport default Socket;\n","import { parseURI } from \"@xmpp/connection/lib/util.js\";\nimport ConnectionTCP from \"@xmpp/connection-tcp\";\n\nimport Socket from \"./Socket.js\";\n\nclass ConnectionTLS extends ConnectionTCP {\n  socketParameters(service) {\n    const { port, hostname, protocol } = parseURI(service);\n    return protocol === \"xmpps:\"\n      ? {\n          port: Number(port) || 5223,\n          host: hostname,\n        }\n      : undefined;\n  }\n}\n\nConnectionTLS.prototype.Socket = Socket;\nConnectionTLS.prototype.NS = \"jabber:client\";\n\nexport default ConnectionTLS;\n","import ConnectionTLS from \"./lib/Connection.js\";\n\nexport default function tls({ entity }) {\n  entity.transports.push(ConnectionTLS);\n}\n","'use strict'\n\n/**\n * Expose compositor.\n */\n\nmodule.exports = compose\n\n/**\n * Compose `middleware` returning\n * a fully valid middleware comprised\n * of all those which are passed.\n *\n * @param {Array} middleware\n * @return {Function}\n * @api public\n */\n\nfunction compose (middleware) {\n  if (!Array.isArray(middleware)) throw new TypeError('Middleware stack must be an array!')\n  for (const fn of middleware) {\n    if (typeof fn !== 'function') throw new TypeError('Middleware must be composed of functions!')\n  }\n\n  /**\n   * @param {Object} context\n   * @return {Promise}\n   * @api public\n   */\n\n  return function (context, next) {\n    // last called middleware #\n    let index = -1\n    return dispatch(0)\n    function dispatch (i) {\n      if (i <= index) return Promise.reject(new Error('next() called multiple times'))\n      index = i\n      let fn = middleware[i]\n      if (i === middleware.length) fn = next\n      if (!fn) return Promise.resolve()\n      try {\n        return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));\n      } catch (err) {\n        return Promise.reject(err)\n      }\n    }\n  }\n}\n","export default class Context {\n  constructor(entity, stanza) {\n    this.stanza = stanza;\n    this.entity = entity;\n\n    const { name, attrs } = stanza;\n    const { type, id } = attrs;\n\n    this.name = name;\n    this.id = id || \"\";\n\n    if (name === \"message\") {\n      this.type = type || \"normal\";\n    } else if (name === \"presence\") {\n      this.type = type || \"available\";\n    } else {\n      this.type = type || \"\";\n    }\n\n    this.from = null;\n    this.to = null;\n    this.local = \"\";\n    this.domain = \"\";\n    this.resource = \"\";\n  }\n}\n","import JID from \"@xmpp/jid\";\n\nimport Context from \"./Context.js\";\n\nexport default class IncomingContext extends Context {\n  constructor(entity, stanza) {\n    super(entity, stanza);\n\n    const { jid } = entity;\n    const { domain } = entity.options ?? {};\n\n    const to = stanza.attrs.to || jid?.toString();\n    const from = stanza.attrs.from || domain;\n\n    if (to) this.to = new JID(to);\n\n    if (from) {\n      this.from = new JID(from);\n      this.local = this.from.local;\n      this.domain = this.from.domain;\n      this.resource = this.from.resource;\n    }\n  }\n}\n","import JID from \"@xmpp/jid\";\n\nimport Context from \"./Context.js\";\n\nexport default class OutgoingContext extends Context {\n  constructor(entity, stanza) {\n    super(entity, stanza);\n\n    const { jid } = entity;\n    const { domain } = entity.options ?? {};\n\n    const from = stanza.attrs.from || jid?.toString();\n    const to = stanza.attrs.to || domain;\n\n    if (from) this.from = new JID(from);\n\n    if (to) {\n      this.to = new JID(to);\n      this.local = this.to.local;\n      this.domain = this.to.domain;\n      this.resource = this.to.resource;\n    }\n  }\n}\n","import compose from \"koa-compose\";\n\nimport IncomingContext from \"./lib/IncomingContext.js\";\nimport OutgoingContext from \"./lib/OutgoingContext.js\";\n\nfunction listener(entity, middleware, Context) {\n  return (stanza) => {\n    const ctx = new Context(entity, stanza);\n    return compose(middleware)(ctx);\n  };\n}\n\nfunction errorHandler(entity) {\n  return (ctx, next) => {\n    next()\n      .then((reply) => reply && entity.send(reply))\n      .catch((err) => entity.emit(\"error\", err));\n  };\n}\n\nexport default function middleware({ entity }) {\n  const incoming = [errorHandler(entity)];\n  const outgoing = [];\n\n  const incomingListener = listener(entity, incoming, IncomingContext);\n  const outgoingListener = listener(entity, outgoing, OutgoingContext);\n\n  entity.on(\"element\", incomingListener);\n  entity.on(\"send\", outgoingListener);\n\n  return {\n    use(fn) {\n      incoming.push(fn);\n      return fn;\n    },\n    filter(fn) {\n      outgoing.push(fn);\n      return fn;\n    },\n  };\n}\n","import XMPPError from \"@xmpp/error\";\n\n/* https://xmpp.org/rfcs/rfc6120.html#stanzas-error */\n\nclass StanzaError extends XMPPError {\n  constructor(condition, text, application, type) {\n    super(condition, text, application);\n    this.type = type;\n    this.name = \"StanzaError\";\n  }\n\n  static fromElement(element) {\n    const error = super.fromElement(element);\n    error.type = element.attrs.type;\n    return error;\n  }\n}\n\nexport default StanzaError;\n","import xid from \"@xmpp/id\";\nimport StanzaError from \"@xmpp/middleware/lib/StanzaError.js\";\nimport { Deferred, timeout as timeoutPromise } from \"@xmpp/events\";\nimport xml from \"@xmpp/xml\";\n\nfunction isReply({ name, type }) {\n  if (name !== \"iq\") return false;\n  if (type !== \"error\" && type !== \"result\") return false;\n  return true;\n}\n\nclass IQCaller {\n  constructor({ entity, middleware }) {\n    this.handlers = new Map();\n    this.entity = entity;\n    this.middleware = middleware;\n  }\n\n  start() {\n    this.middleware.use(this._route.bind(this));\n  }\n\n  _route({ type, name, id, stanza }, next) {\n    if (!isReply({ name, type })) return next();\n\n    const deferred = this.handlers.get(id);\n\n    if (!deferred) {\n      return next();\n    }\n\n    if (type === \"error\") {\n      deferred.reject(StanzaError.fromElement(stanza.getChild(\"error\")));\n    } else {\n      deferred.resolve(stanza);\n    }\n\n    this.handlers.delete(id);\n  }\n\n  async request(stanza, timeout = 30 * 1000) {\n    if (!stanza.attrs.id) {\n      stanza.attrs.id = xid();\n    }\n\n    const deferred = new Deferred();\n    this.handlers.set(stanza.attrs.id, deferred);\n\n    try {\n      await this.entity.send(stanza);\n      await timeoutPromise(deferred.promise, timeout);\n    } catch (err) {\n      this.handlers.delete(stanza.attrs.id);\n      throw err;\n    }\n\n    return deferred.promise;\n  }\n\n  _childRequest(type, element, to, ...args) {\n    const {\n      name,\n      attrs: { xmlns },\n    } = element;\n    return this.request(xml(\"iq\", { type, to }, element), ...args).then(\n      (stanza) => stanza.getChild(name, xmlns),\n    );\n  }\n\n  async get(...args) {\n    return this._childRequest(\"get\", ...args);\n  }\n\n  async set(...args) {\n    return this._childRequest(\"set\", ...args);\n  }\n}\n\nexport default function iqCaller(...args) {\n  const iqCaller = new IQCaller(...args);\n  iqCaller.start();\n  return iqCaller;\n}\n","export default function id() {\n  let i;\n  while (!i) {\n    i = Math.random().toString(36).slice(2, 12);\n  }\n\n  return i;\n}\n","import xml from \"@xmpp/xml\";\n\n/**\n * References\n * https://xmpp.org/rfcs/rfc6120.html#stanzas-semantics-iq\n * https://xmpp.org/rfcs/rfc6120.html#stanzas-error\n */\n\nconst NS_STANZA = \"urn:ietf:params:xml:ns:xmpp-stanzas\";\n\nfunction isQuery({ name, type }) {\n  if (name !== \"iq\") return false;\n  if (type === \"error\" || type === \"result\") return false;\n  return true;\n}\n\nfunction isValidQuery({ type }, children, child) {\n  if (type !== \"get\" && type !== \"set\") return false;\n  if (children.length !== 1) return false;\n  if (!child) return false;\n  return true;\n}\n\nfunction buildReply({ stanza }) {\n  return xml(\"iq\", {\n    to: stanza.attrs.from,\n    from: stanza.attrs.to,\n    id: stanza.attrs.id,\n  });\n}\n\nfunction buildReplyResult(ctx, child) {\n  const reply = buildReply(ctx);\n  reply.attrs.type = \"result\";\n  if (child) {\n    reply.append(child);\n  }\n\n  return reply;\n}\n\nfunction buildReplyError(ctx, error, child) {\n  const reply = buildReply(ctx);\n  reply.attrs.type = \"error\";\n  if (child) {\n    reply.append(child);\n  }\n\n  reply.append(error);\n  return reply;\n}\n\nfunction buildError(type, condition) {\n  return xml(\"error\", { type }, xml(condition, NS_STANZA));\n}\n\nfunction iqHandler(entity) {\n  return async function iqHandler(ctx, next) {\n    if (!isQuery(ctx)) return next();\n\n    const { stanza } = ctx;\n    const children = stanza.getChildElements();\n    const [child] = children;\n\n    if (!isValidQuery(ctx, children, child)) {\n      return buildReplyError(ctx, buildError(\"modify\", \"bad-request\"), child);\n    }\n\n    ctx.element = child;\n\n    let reply;\n    try {\n      reply = await next();\n    } catch (err) {\n      entity.emit(\"error\", err);\n      reply = buildError(\"cancel\", \"internal-server-error\");\n    }\n\n    if (!reply) {\n      reply = buildError(\"cancel\", \"service-unavailable\");\n    }\n\n    if (reply instanceof xml.Element && reply.is(\"error\")) {\n      return buildReplyError(ctx, reply, child);\n    }\n\n    return buildReplyResult(\n      ctx,\n      reply instanceof xml.Element ? reply : undefined,\n    );\n  };\n}\n\nfunction route(type, ns, name, handler) {\n  return (ctx, next) => {\n    if ((ctx.type !== type) | !ctx.element || !ctx.element.is(name, ns))\n      return next();\n    return handler(ctx, next);\n  };\n}\n\nexport default function iqCallee({ middleware, entity }) {\n  middleware.use(iqHandler(entity));\n\n  return {\n    get(ns, name, handler) {\n      middleware.use(route(\"get\", ns, name, handler));\n    },\n    set(ns, name, handler) {\n      middleware.use(route(\"set\", ns, name, handler));\n    },\n  };\n}\n","/* eslint-disable promise/no-nesting */\n\nimport dns from \"node:dns\";\n\n// eslint-disable-next-line unicorn/prefer-set-has\nconst IGNORE_CODES = [\"ENOTFOUND\", \"ENODATA\"];\n\nfunction lookup(domain, options = {}) {\n  options.all = true;\n  return new Promise((resolve, reject) => {\n    dns.lookup(domain, options, (err, addresses) => {\n      if (err) {\n        return reject(err);\n      }\n\n      const result = [];\n      for (const { family, address } of addresses) {\n        const uri = `://${family === 4 ? address : \"[\" + address + \"]\"}:`;\n        result.push(\n          {\n            family,\n            address,\n            uri: \"xmpps\" + uri + \"5223\",\n          },\n          {\n            family,\n            address,\n            uri: \"xmpp\" + uri + \"5222\",\n          },\n        );\n      }\n      resolve(result);\n    });\n  });\n}\n\nfunction resolveSrv(domain, { service, protocol }) {\n  return new Promise((resolve, reject) => {\n    dns.resolveSrv(`_${service}._${protocol}.${domain}`, (err, records) => {\n      if (err && IGNORE_CODES.includes(err.code)) {\n        resolve([]);\n      } else if (err) {\n        reject(err);\n      } else {\n        resolve(\n          records.map((record) => {\n            return Object.assign(record, { service, protocol });\n          }),\n        );\n      }\n    });\n  });\n}\n\nfunction sortSrv(records) {\n  return records.toSorted((a, b) => {\n    const priority = a.priority - b.priority;\n    if (priority !== 0) {\n      return priority;\n    }\n\n    const weight = b.weight - a.weight;\n    if (weight !== 0) {\n      return weight;\n    }\n\n    return 0;\n  });\n}\n\nfunction lookupSrvs(srvs, options) {\n  const addresses = [];\n  return Promise.all(\n    srvs.map(async (srv) => {\n      const srvAddresses = await lookup(srv.name, options);\n      for (const address of srvAddresses) {\n        const { port, service } = srv;\n        const addr = address.address;\n        addresses.push({\n          ...address,\n          ...srv,\n          uri: `${service.split(\"-\")[0]}://${\n            address.family === 6 ? \"[\" + addr + \"]\" : addr\n          }:${port}`,\n        });\n      }\n    }),\n  ).then(() => addresses);\n}\n\nfunction resolve(domain, options = {}) {\n  if (!options.srv) {\n    options.srv = [\n      {\n        service: \"xmpps-client\",\n        protocol: \"tcp\",\n      },\n      {\n        service: \"xmpp-client\",\n        protocol: \"tcp\",\n      },\n      {\n        service: \"xmpps-server\",\n        protocol: \"tcp\",\n      },\n      {\n        service: \"xmpp-server\",\n        protocol: \"tcp\",\n      },\n      {\n        service: \"stun\",\n        protocol: \"tcp\",\n      },\n      {\n        service: \"stun\",\n        protocol: \"udp\",\n      },\n      {\n        service: \"stuns \",\n        protcol: \"tcp\",\n      },\n      {\n        service: \"turn\",\n        protocol: \"tcp\",\n      },\n      {\n        service: \"turn\",\n        protocol: \"udp\",\n      },\n      {\n        service: \"turns\",\n        protcol: \"tcp\",\n      },\n    ];\n  }\n\n  const family = { options };\n  return lookup(domain, options).then((addresses) => {\n    return Promise.all(\n      options.srv.map((srv) => {\n        return resolveSrv(domain, { ...srv, family }).then((records) => {\n          return lookupSrvs(records, options);\n        });\n      }),\n    ).then((srvs) => [...sortSrv(srvs.flat()), ...addresses]);\n  });\n}\n\nexport { lookup, resolveSrv, resolve, lookupSrvs, sortSrv };\n","function isSecure(uri) {\n  return uri.startsWith(\"https\") || uri.startsWith(\"wss\");\n}\n\nexport function compare(a, b) {\n  let secure;\n  if (isSecure(a.uri) && !isSecure(b.uri)) {\n    secure = -1;\n  } else if (!isSecure(a.uri) && isSecure(b.uri)) {\n    secure = 1;\n  } else {\n    secure = 0;\n  }\n\n  if (secure !== 0) {\n    return secure;\n  }\n\n  let method;\n  if (a.method === b.method) {\n    method = 0;\n  } else if (a.method === \"websocket\") {\n    method = -1;\n  } else if (b.method === \"websocket\") {\n    method = 1;\n  } else if (a.method === \"xbosh\") {\n    method = -1;\n  } else if (b.method === \"xbosh\") {\n    method = 1;\n  } else if (a.method === \"httppoll\") {\n    method = -1;\n  } else if (b.method === \"httppoll\") {\n    method = 1;\n  } else {\n    method = 0;\n  }\n\n  if (method !== 0) {\n    return method;\n  }\n\n  return 0;\n}\n","import parse from \"@xmpp/xml/lib/parse.js\";\n\nimport { compare as compareAltConnections } from \"./alt-connections.js\";\n\nexport function resolve(domain) {\n  // eslint-disable-next-line n/no-unsupported-features/node-builtins\n  return fetch(`https://${domain}/.well-known/host-meta`)\n    .then((res) => res.text())\n    .then((res) => {\n      return parse(res)\n        .getChildren(\"Link\")\n        .filter((link) =>\n          [\n            \"urn:xmpp:alt-connections:websocket\",\n            \"urn:xmpp:alt-connections:httppoll\",\n            \"urn:xmpp:alt-connections:xbosh\",\n          ].includes(link.attrs.rel),\n        )\n        .map(({ attrs }) => ({\n          rel: attrs.rel,\n          href: attrs.href,\n          method: attrs.rel.split(\":\").pop(),\n          uri: attrs.href,\n        }))\n        .toSorted(compareAltConnections);\n    })\n    .catch(() => {\n      return [];\n    });\n}\n","import Parser from \"./Parser.js\";\n\nexport default function parse(data) {\n  const p = new Parser();\n\n  let result = null;\n  let error = null;\n\n  p.on(\"start\", (el) => {\n    result = el;\n  });\n  p.on(\"element\", (el) => {\n    result.append(el);\n  });\n  p.on(\"error\", (err) => {\n    error = err;\n  });\n\n  p.write(data);\n  p.end();\n\n  if (error) {\n    throw error;\n  } else {\n    return result;\n  }\n}\n","import { promise } from \"@xmpp/events\";\n\nimport _resolve from \"./resolve.js\";\n\nasync function fetchURIs(domain) {\n  const result = await _resolve(domain, {\n    srv: [\n      {\n        service: \"xmpps-client\",\n        protocol: \"tcp\",\n      },\n      {\n        service: \"xmpp-client\",\n        protocol: \"tcp\",\n      },\n    ],\n  });\n\n  return [\n    // Remove duplicates\n    ...new Set(result.map((record) => record.uri)),\n  ];\n}\n\nfunction filterSupportedURIs(entity, uris) {\n  return uris.filter((uri) => entity._findTransport(uri));\n}\n\nasync function fallbackConnect(entity, uris) {\n  if (uris.length === 0) {\n    throw new Error(\"Couldn't connect\");\n  }\n\n  const uri = uris.shift();\n  const Transport = entity._findTransport(uri);\n\n  if (!Transport) {\n    return fallbackConnect(entity, uris);\n  }\n\n  entity._status(\"connecting\", uri);\n  const params = Transport.prototype.socketParameters(uri);\n  const socket = new Transport.prototype.Socket();\n\n  try {\n    socket.connect(params);\n    await promise(socket, \"connect\");\n  } catch {\n    return fallbackConnect(entity, uris);\n  }\n\n  entity._attachSocket(socket);\n  socket.emit(\"connect\");\n  entity.Transport = Transport;\n  entity.Socket = Transport.prototype.Socket;\n  entity.Parser = Transport.prototype.Parser;\n}\n\nexport default function resolve({ entity }) {\n  const _connect = entity.connect;\n  entity.connect = async function connect(service) {\n    if (!service || /:\\/\\//.test(service)) {\n      return _connect.call(this, service);\n    }\n\n    const uris = filterSupportedURIs(entity, await fetchURIs(service));\n\n    if (uris.length === 0) {\n      throw new Error(\"No compatible transport found.\");\n    }\n\n    try {\n      await fallbackConnect(entity, uris);\n    } catch (err) {\n      await entity.disconnect();\n      entity._status(\"disconnect\");\n      throw err;\n    }\n  };\n}\n\nexport { _resolve as resolve };\n","import * as dns from \"./lib/dns.js\";\nimport * as http from \"./lib/http.js\";\n\nexport default function resolve(...args) {\n  return Promise.all([\n    dns.resolve ? dns.resolve(...args) : Promise.resolve([]),\n    http.resolve(...args),\n  ]).then(([records, endpoints]) => [...records, ...endpoints]);\n}\n\nexport { dns, http };\n","import xml from \"@xmpp/xml\";\n\nimport { canUpgrade, upgrade } from \"./starttls.js\";\n\n/*\n * References\n * https://xmpp.org/rfcs/rfc6120.html#tls\n */\n\nconst NS = \"urn:ietf:params:xml:ns:xmpp-tls\";\n\nasync function negotiate(entity) {\n  const element = await entity.sendReceive(xml(\"starttls\", { xmlns: NS }));\n  if (element.is(\"proceed\", NS)) {\n    return element;\n  }\n\n  throw new Error(\"STARTTLS_FAILURE\");\n}\n\nexport default function starttls({ streamFeatures }) {\n  return streamFeatures.use(\"starttls\", NS, async ({ entity }, next) => {\n    const { socket, options } = entity;\n    if (!canUpgrade(socket)) {\n      return next();\n    }\n\n    await negotiate(entity);\n    const tlsSocket = await upgrade(socket, { host: options.domain });\n    entity._attachSocket(tlsSocket);\n\n    await entity.restart();\n  });\n}\n","import tls from \"node:tls\";\nimport net from \"node:net\";\n\nimport { promise } from \"@xmpp/events\";\nimport Socket from \"@xmpp/tls/lib/Socket.js\";\n\nexport function canUpgrade(socket) {\n  return socket instanceof net.Socket && !(socket instanceof tls.TLSSocket);\n}\n\nexport async function upgrade(socket, options = {}) {\n  const tlsSocket = new Socket();\n  tlsSocket.connect({ socket, ...options });\n  await promise(tlsSocket, \"connect\");\n\n  return tlsSocket;\n}\n","export function encode(string) {\n  return globalThis.btoa(string);\n}\n\nexport function decode(string) {\n  return globalThis.atob(string);\n}\n","import XMPPError from \"@xmpp/error\";\n\n// https://xmpp.org/rfcs/rfc6120.html#sasl-errors\n\nclass SASLError extends XMPPError {\n  constructor(...args) {\n    super(...args);\n    this.name = \"SASLError\";\n  }\n}\n\nexport default SASLError;\n","import { encode, decode } from \"@xmpp/base64\";\nimport xml from \"@xmpp/xml\";\nimport { procedure } from \"@xmpp/events\";\n\nimport SASLError from \"./lib/SASLError.js\";\n\n// https://xmpp.org/rfcs/rfc6120.html#sasl\n\nconst NS = \"urn:ietf:params:xml:ns:xmpp-sasl\";\n\nexport function getAvailableMechanisms(element, NS, saslFactory) {\n  const offered = new Set(\n    element.getChildren(\"mechanism\", NS).map((m) => m.text()),\n  );\n  const supported = saslFactory._mechs.map(({ name }) => name);\n  return supported.filter((mech) => offered.has(mech));\n}\n\nasync function authenticate({ saslFactory, entity, mechanism, credentials }) {\n  const mech = saslFactory.create([mechanism]);\n  if (!mech) {\n    throw new Error(`SASL: Mechanism ${mechanism} not found.`);\n  }\n\n  const { domain } = entity.options;\n  const creds = {\n    username: null,\n    password: null,\n    server: domain,\n    host: domain,\n    realm: domain,\n    serviceType: \"xmpp\",\n    serviceName: domain,\n    ...credentials,\n  };\n\n  await procedure(\n    entity,\n    mech.clientFirst &&\n      xml(\n        \"auth\",\n        { xmlns: NS, mechanism: mech.name },\n        encode(await mech.response(creds)),\n      ),\n    async (element, done) => {\n      if (element.getNS() !== NS) return;\n\n      if (element.name === \"challenge\") {\n        await mech.challenge(decode(element.text()));\n        const resp = await mech.response(creds);\n        await entity.send(\n          xml(\n            \"response\",\n            { xmlns: NS, mechanism: mech.name },\n            typeof resp === \"string\" ? encode(resp) : \"\",\n          ),\n        );\n        return;\n      }\n\n      if (element.name === \"failure\") {\n        throw SASLError.fromElement(element);\n      }\n\n      if (element.name === \"success\") {\n        return done();\n      }\n    },\n  );\n}\n\nexport default function sasl({ streamFeatures, saslFactory }, onAuthenticate) {\n  streamFeatures.use(\"mechanisms\", NS, async ({ entity }, _next, element) => {\n    const mechanisms = getAvailableMechanisms(element, NS, saslFactory);\n    if (mechanisms.length === 0) {\n      throw new SASLError(\"SASL: No compatible mechanism available.\");\n    }\n\n    async function done(credentials, mechanism) {\n      await authenticate({\n        saslFactory,\n        entity,\n        mechanism,\n        credentials,\n      });\n    }\n\n    await onAuthenticate(done, mechanisms, null, entity);\n\n    await entity.restart();\n  });\n}\n","import { encode, decode } from \"@xmpp/base64\";\nimport SASLError from \"@xmpp/sasl/lib/SASLError.js\";\nimport xml from \"@xmpp/xml\";\nimport { procedure } from \"@xmpp/events\";\nimport { getAvailableMechanisms } from \"@xmpp/sasl\";\n\n// https://xmpp.org/extensions/xep-0388.html\n\nconst NS = \"urn:xmpp:sasl:2\";\n\nasync function authenticate({\n  saslFactory,\n  entity,\n  mechanism,\n  credentials,\n  userAgent,\n  streamFeatures,\n  features,\n}) {\n  const mech = saslFactory.create([mechanism]);\n  if (!mech) {\n    throw new Error(`SASL: Mechanism ${mechanism} not found.`);\n  }\n\n  const { domain } = entity.options;\n  const creds = {\n    username: null,\n    password: null,\n    server: domain,\n    host: domain,\n    realm: domain,\n    serviceType: \"xmpp\",\n    serviceName: domain,\n    ...credentials,\n  };\n\n  await procedure(\n    entity,\n    xml(\"authenticate\", { xmlns: NS, mechanism: mech.name }, [\n      mech.clientFirst &&\n        xml(\"initial-response\", {}, encode(await mech.response(creds))),\n      userAgent,\n      ...streamFeatures,\n    ]),\n    async (element, done) => {\n      if (element.getNS() !== NS) return;\n\n      if (element.name === \"challenge\") {\n        await mech.challenge(decode(element.text()));\n        const resp = await mech.response(creds);\n        await entity.send(\n          xml(\n            \"response\",\n            { xmlns: NS, mechanism: mech.name },\n            typeof resp === \"string\" ? encode(resp) : \"\",\n          ),\n        );\n        return;\n      }\n\n      if (element.name === \"failure\") {\n        throw SASLError.fromElement(element);\n      }\n\n      if (element.name === \"continue\") {\n        throw new Error(\"SASL continue is not supported yet\");\n      }\n\n      if (element.name === \"success\") {\n        const additionalData = element.getChild(\"additional-data\")?.text();\n        if (additionalData && mech.final) {\n          await mech.final(decode(additionalData));\n        }\n\n        // https://xmpp.org/extensions/xep-0388.html#success\n        // this is a bare JID, unless resource binding or stream resumption has occurred, in which case it is a full JID.\n        const aid = element.getChildText(\"authorization-identifier\");\n        if (aid) {\n          entity._jid(aid);\n        }\n\n        for (const child of element.getChildElements()) {\n          const feature = features.get(child.getNS());\n          feature?.[1]?.(child);\n        }\n\n        return done();\n      }\n    },\n  );\n}\n\nexport default function sasl2({ streamFeatures, saslFactory }, onAuthenticate) {\n  const features = new Map();\n  let fast;\n\n  streamFeatures.use(\n    \"authentication\",\n    NS,\n    async ({ entity }, _next, element) => {\n      const mechanisms = getAvailableMechanisms(element, NS, saslFactory);\n      const streamFeatures = await getStreamFeatures({ element, features });\n      const fast_available = !!fast?.mechanism;\n\n      if (mechanisms.length === 0 && !fast_available) {\n        throw new SASLError(\"SASL: No compatible mechanism available.\");\n      }\n\n      await onAuthenticate(\n        done,\n        mechanisms,\n        fast_available ? fast : null,\n        entity,\n      );\n\n      async function done(credentials, mechanism, userAgent) {\n        // Try fast\n        const success = await fast.auth({\n          authenticate,\n          entity,\n          userAgent,\n          streamFeatures,\n          features,\n          credentials,\n        });\n        if (success) return;\n\n        // fast.auth may mutate streamFeatures to request a token\n\n        // If fast authentication fails, continue and try without\n        await authenticate({\n          entity,\n          userAgent,\n          streamFeatures,\n          features,\n          saslFactory,\n          mechanism,\n          credentials,\n        });\n      }\n    },\n  );\n\n  return {\n    use(ns, req, res) {\n      features.set(ns, [req, res]);\n    },\n    setup({ fast: _fast }) {\n      fast = _fast;\n    },\n  };\n}\n\nasync function getStreamFeatures({ element, features }) {\n  const promises = [];\n\n  const inline = element.getChild(\"inline\");\n  if (!inline) return promises;\n\n  for (const element of inline.getChildElements()) {\n    const xmlns = element.getNS();\n    const feature = features.get(xmlns);\n    if (!feature) continue;\n    promises.push(feature[0](element));\n  }\n\n  return Promise.all(promises);\n}\n","import xml from \"@xmpp/xml\";\n\n/*\n * References\n * https://xmpp.org/rfcs/rfc6120.html#bind\n */\n\nconst NS = \"urn:ietf:params:xml:ns:xmpp-bind\";\n\nfunction makeBindElement(resource) {\n  return xml(\"bind\", { xmlns: NS }, resource && xml(\"resource\", {}, resource));\n}\n\nasync function bind(entity, iqCaller, resource) {\n  const result = await iqCaller.set(makeBindElement(resource));\n  const jid = result.getChildText(\"jid\");\n  entity._jid(jid);\n  entity._ready(false);\n  return jid;\n}\n\nfunction route({ iqCaller }, resource) {\n  return async ({ entity }, next) => {\n    resource = typeof resource === \"function\" ? await resource() : resource;\n    await bind(entity, iqCaller, resource);\n    next();\n  };\n}\n\nexport default function resourceBinding(\n  { streamFeatures, iqCaller },\n  resource,\n) {\n  streamFeatures.use(\"bind\", NS, route({ iqCaller }, resource));\n}\n","import xml from \"@xmpp/xml\";\n\nconst NS = \"urn:xmpp:bind:0\";\n\nexport default function bind2({ sasl2, entity }, tag) {\n  const features = new Map();\n\n  sasl2.use(\n    NS,\n    async (element) => {\n      if (!element.is(\"bind\", NS)) return;\n\n      tag = typeof tag === \"function\" ? await tag() : tag;\n\n      const sessionFeatures = await getSessionFeatures({ element, features });\n\n      return xml(\n        \"bind\",\n        { xmlns: \"urn:xmpp:bind:0\" },\n        tag && xml(\"tag\", null, tag),\n        ...sessionFeatures,\n      );\n    },\n    (element) => {\n      if (!element.is(\"bound\")) return;\n      entity._ready(false);\n      for (const child of element.getChildElements()) {\n        const feature = features.get(child.getNS());\n        feature?.[1]?.(child);\n      }\n    },\n  );\n\n  return {\n    use(ns, req, res) {\n      features.set(ns, [req, res]);\n    },\n  };\n}\n\nfunction getSessionFeatures({ element, features }) {\n  const promises = [];\n\n  const inline = element.getChild(\"inline\");\n  if (!inline) return promises;\n\n  for (const element of inline.getChildElements()) {\n    const xmlns = element.attrs.var;\n    const feature = features.get(xmlns);\n    if (!feature) continue;\n    promises.push(feature[0](element));\n  }\n\n  return Promise.all(promises);\n}\n","(function(root, factory) {\n  if (typeof exports === 'object') {\n    // CommonJS\n    factory(exports,\n            module,\n            require('./lib/factory'));\n  } else if (typeof define === 'function' && define.amd) {\n    // AMD\n    define(['exports',\n            'module',\n            './lib/factory'], factory);\n  }\n}(this, function(exports, module, Factory) {\n  \n  exports = module.exports = Factory;\n  exports.Factory = Factory;\n  \n}));\n","(function(root, factory) {\n  if (typeof exports === 'object') {\n    // CommonJS\n    factory(exports, module);\n  } else if (typeof define === 'function' && define.amd) {\n    // AMD\n    define(['exports', 'module'], factory);\n  }\n}(this, function(exports, module) {\n  \n  /**\n   * `Factory` constructor.\n   *\n   * @api public\n   */\n  function Factory() {\n    this._mechs = [];\n  }\n  \n  /**\n   * Utilize the given `mech` with optional `name`, overridding the mechanism's\n   * default name.\n   *\n   * Examples:\n   *\n   *     factory.use(FooMechanism);\n   *\n   *     factory.use('XFOO', FooMechanism);\n   *\n   * @param {String|Mechanism} name\n   * @param {Mechanism} mech\n   * @return {Factory} for chaining\n   * @api public\n   */\n  Factory.prototype.use = function(name, mech) {\n    if (!mech) {\n      mech = name;\n      name = mech.prototype.name;\n    }\n    this._mechs.push({ name: name, mech: mech });\n    return this;\n  };\n  \n  /**\n   * Create a new mechanism from supported list of `mechs`.\n   *\n   * If no mechanisms are supported, returns `null`.\n   *\n   * Examples:\n   *\n   *     var mech = factory.create(['FOO', 'BAR']);\n   *\n   * @param {Array} mechs\n   * @return {Mechanism}\n   * @api public\n   */\n  Factory.prototype.create = function(mechs) {\n    for (var i = 0, len = this._mechs.length; i < len; i++) {\n      for (var j = 0, jlen = mechs.length; j < jlen; j++) {\n        var entry = this._mechs[i];\n        if (entry.name == mechs[j]) {\n          return new entry.mech();\n        }\n      }\n    }\n    return null;\n  };\n\n  exports = module.exports = Factory;\n  \n}));\n","import { EventEmitter } from \"@xmpp/events\";\nimport { getAvailableMechanisms } from \"@xmpp/sasl\";\nimport SASLError from \"@xmpp/sasl/lib/SASLError.js\";\nimport xml from \"@xmpp/xml\";\nimport SASLFactory from \"saslmechanisms\";\n\nconst NS = \"urn:xmpp:fast:0\";\n\nexport default function fast({ sasl2, entity }) {\n  const saslFactory = new SASLFactory();\n\n  let token;\n\n  const fast = new EventEmitter();\n  Object.assign(fast, {\n    mechanism: null,\n    mechanisms: [],\n    async saveToken(t) {\n      token = t;\n    },\n    async fetchToken() {\n      return token;\n    },\n    async deleteToken() {\n      token = null;\n    },\n    async save(token) {\n      try {\n        await this.saveToken(token);\n      } catch (err) {\n        entity.emit(\"error\", err);\n      }\n    },\n    async fetch() {\n      try {\n        return this.fetchToken();\n      } catch (err) {\n        entity.emit(\"error\", err);\n      }\n    },\n    async delete() {\n      try {\n        await this.deleteToken();\n      } catch (err) {\n        entity.emit(\"error\", err);\n      }\n    },\n    saslFactory,\n    async auth({\n      authenticate,\n      entity,\n      userAgent,\n      credentials,\n      streamFeatures,\n      features,\n    }) {\n      // Unavailable\n      if (!fast.mechanism) {\n        return false;\n      }\n\n      const { token } = credentials;\n      if (!isTokenValid(token, fast.mechanisms)) {\n        return onInvalidToken();\n      }\n\n      try {\n        await authenticate({\n          saslFactory: fast.saslFactory,\n          mechanism: token.mechanism,\n          credentials: {\n            ...credentials,\n            password: token.token,\n          },\n          streamFeatures: [\n            ...streamFeatures,\n            xml(\"fast\", {\n              xmlns: NS,\n            }),\n          ],\n          entity,\n          userAgent,\n          features,\n        });\n        return true;\n      } catch (err) {\n        if (\n          err instanceof SASLError &&\n          [\"not-authorized\", \"credentials-expired\"].includes(err.condition)\n        ) {\n          return onInvalidToken();\n        }\n        entity.emit(\"error\", err);\n        return false;\n      }\n\n      async function onInvalidToken() {\n        await fast.delete();\n        requestToken(streamFeatures);\n        return false;\n      }\n    },\n  });\n\n  function requestToken(streamFeatures) {\n    streamFeatures.push(\n      xml(\"request-token\", {\n        xmlns: NS,\n        mechanism: fast.mechanism,\n      }),\n    );\n  }\n\n  function reset() {\n    fast.mechanism = null;\n    fast.mechanisms = [];\n  }\n  reset();\n\n  sasl2.use(\n    NS,\n    async (element) => {\n      if (!element.is(\"fast\", NS)) return reset();\n\n      fast.available = true;\n\n      const mechanisms = getAvailableMechanisms(element, NS, saslFactory);\n      const mechanism = mechanisms[0];\n\n      if (!mechanism) return reset();\n      fast.mechanisms = mechanisms;\n      fast.mechanism = mechanism;\n\n      // The rest is handled by @xmpp/sasl2\n    },\n    async (element) => {\n      if (element.is(\"token\", NS)) {\n        await fast.save({\n          // The token is bound by the mechanism\n          // > Servers MUST bind tokens to the mechanism selected by the client in its original request, and reject attempts to use them with other mechanisms.\n          mechanism: fast.mechanism,\n          token: element.attrs.token,\n          expiry: element.attrs.expiry,\n        });\n      }\n    },\n  );\n\n  return fast;\n}\n\nexport function isTokenValid(token, mechanisms) {\n  if (!token) return false;\n\n  // Avoid an error round trip if the server does not support the token mechanism anymore\n  if (!mechanisms.includes(token.mechanism)) {\n    return false;\n  }\n\n  // Avoid an error round trip if the token is already expired\n  if (new Date(token.expiry) <= new Date()) {\n    return false;\n  }\n\n  return true;\n}\n","module.exports = require('crypto').createHash\n","module.exports = require('crypto').createHmac\n","/* jslint bitwise: true */\nvar createHash = require('create-hash');\nvar createHmac = require('create-hmac');\n\nexports.XOR = function (a, b) {\n  var res = [];\n  if (a.length > b.length) {\n    for (var i = 0; i < b.length; i++) {\n      res.push(a[i] ^ b[i]);\n    }\n  } else {\n    for (var j = 0; j < a.length; j++) {\n      res.push(a[j] ^ b[j]);\n    }\n  }\n  return new Uint8Array(res);\n};\n\nexports.H = function (text) {\n    return createHash('sha1').update(text).digest();\n};\n\nexports.HMAC = function (key, msg) {\n    return createHmac('sha1', key).update(msg).digest();\n};\n\nexports.Hi = function (text, salt, iterations) {\n    var concat = new Uint8Array(salt.length + 4);\n    concat.set(salt);\n    concat.set(new Uint8Array([0, 0, 0, 1]), salt.length);\n    var ui1 = exports.HMAC(text, concat);\n    var ui = ui1;\n    for (var i = 0; i < iterations - 1; i++) {\n        ui1 = exports.HMAC(text, ui1);\n        ui = exports.XOR(ui, ui1);\n    }\n\n    return ui;\n};\n\n","var randomBytes = require('randombytes');\n\n\nexports.parse = function (chal) {\n    var dtives = {};\n    var tokens = chal.split(/,(?=(?:[^\"]|\"[^\"]*\")*$)/);\n    for (var i = 0, len = tokens.length; i < len; i++) {\n        var dtiv = /(\\w+)=[\"]?([^\"]+)[\"]?$/.exec(tokens[i]);\n        if (dtiv) {\n            dtives[dtiv[1]] = dtiv[2];\n        }\n    }\n    return dtives;\n};\n\nexports.saslname = function (name) {\n    var escaped = [];\n    var curr = '';\n    for (var i = 0; i < name.length; i++) {\n        curr = name[i];\n        if (curr === ',') {\n            escaped.push('=2C');\n        } else if (curr === '=') {\n            escaped.push('=3D');\n        } else {\n            escaped.push(curr);\n        }\n    }\n    return escaped.join('');\n};\n\nexports.genNonce = function (len) {\n    return randomBytes((len || 32) / 2).toString('hex');\n};\n","module.exports = require('crypto').randomBytes\n","var bitops = require('./lib/bitops');\nvar utils = require('./lib/utils');\n\nvar RESP = {};\nvar CLIENT_KEY = 'Client Key';\nvar SERVER_KEY = 'Server Key';\n\nfunction base64decode(s) {\n    if (atob) {\n        return Uint8Array.from(atob(s), function(c) { return c.charCodeAt(0); });\n    } else {\n        return Uint8Array.from(Buffer.from(s, 'base64'));\n    }\n}\n\nfunction base64encode(s) {\n   if (btoa) {\n       return btoa(s);\n   } else {\n       return Buffer.from(s).toString('base64');\n   }\n}\n\nfunction Mechanism(options) {\n    options = options || {};\n    this._genNonce = options.genNonce || utils.genNonce;\n    this._stage = 'initial';\n}\n\n// Conform to the SASL lib's expectations\nMechanism.Mechanism = Mechanism;\n\n\nMechanism.prototype.name = 'SCRAM-SHA-1';\nMechanism.prototype.clientFirst = true;\n\n\nMechanism.prototype.response = function (cred) {\n    return RESP[this._stage](this, cred);\n};\n\nMechanism.prototype.challenge = function (chal) {\n    var values = utils.parse(chal);\n\n    this._salt = base64decode(values.s || '');\n    this._iterationCount = parseInt(values.i, 10);\n    this._nonce = values.r;\n    this._verifier = values.v;\n    this._error = values.e;\n    this._challenge = chal;\n\n    return this;\n};\n\n\nRESP.initial = function (mech, cred) {\n    mech._cnonce = mech._genNonce();\n\n    var authzid = '';\n    if (cred.authzid) {\n        authzid = 'a=' + utils.saslname(cred.authzid);\n    }\n\n    mech._gs2Header = 'n,' + authzid + ',';\n\n    var nonce = 'r=' + mech._cnonce;\n    var username = 'n=' + utils.saslname(cred.username || '');\n\n    mech._clientFirstMessageBare = username + ',' + nonce;\n    var result = mech._gs2Header + mech._clientFirstMessageBare;\n\n    mech._stage = 'challenge';\n\n    return result;\n};\n\n\nRESP.challenge = function (mech, cred) {\n    var gs2Header = base64encode(mech._gs2Header);\n\n    mech._clientFinalMessageWithoutProof = 'c=' + gs2Header + ',r=' + mech._nonce;\n\n    var saltedPassword, clientKey, serverKey;\n\n    // If our cached salt is the same, we can reuse cached credentials to speed\n    // up the hashing process.\n    if (cred.salt && cred.salt.every(function(value, index) { return value === mech._salt[index]; })) {\n        if (cred.clientKey && cred.serverKey) {\n            clientKey = cred.clientKey;\n            serverKey = cred.serverKey;\n        } else if (cred.saltedPassword) {\n            saltedPassword = cred.saltedPassword;\n            clientKey = bitops.HMAC(saltedPassword, CLIENT_KEY);\n            serverKey = bitops.HMAC(saltedPassword, SERVER_KEY);\n        }\n    } else {\n        saltedPassword = bitops.Hi(cred.password || '', mech._salt, mech._iterationCount);\n        clientKey = bitops.HMAC(saltedPassword, CLIENT_KEY);\n        serverKey = bitops.HMAC(saltedPassword, SERVER_KEY);\n    }\n\n    var storedKey = bitops.H(clientKey);\n    var authMessage = mech._clientFirstMessageBare + ',' +\n                      mech._challenge + ',' +\n                      mech._clientFinalMessageWithoutProof;\n    var clientSignature = bitops.HMAC(storedKey, authMessage);\n\n    var clientProof = base64encode(String.fromCharCode.apply(null, bitops.XOR(clientKey, clientSignature)));\n\n    mech._serverSignature = bitops.HMAC(serverKey, authMessage);\n\n    var result = mech._clientFinalMessageWithoutProof + ',p=' + clientProof;\n\n    mech._stage = 'final';\n\n    mech.cache = {\n        salt: mech._salt,\n        saltedPassword: saltedPassword,\n        clientKey: clientKey,\n        serverKey: serverKey\n    };\n\n    return result;\n};\n\nRESP.final = function () {\n    // TODO: Signal errors\n    return '';\n};\n\n\n\nmodule.exports = Mechanism;\n","import mech from \"sasl-scram-sha-1\";\n\nexport default function saslScramSha1(sasl) {\n  sasl.use(mech);\n}\n","(function(root, factory) {\n  if (typeof exports === 'object') {\n    // CommonJS\n    factory(exports,\n            module,\n            require('./lib/mechanism'));\n  } else if (typeof define === 'function' && define.amd) {\n    // AMD\n    define(['exports',\n            'module',\n            './lib/mechanism'], factory);\n  }\n}(this, function(exports, module, Mechanism) {\n\n  exports = module.exports = Mechanism;\n  exports.Mechanism = Mechanism;\n  \n}));\n","(function(root, factory) {\n  if (typeof exports === 'object') {\n    // CommonJS\n    factory(exports, module);\n  } else if (typeof define === 'function' && define.amd) {\n    // AMD\n    define(['exports', 'module'], factory);\n  }\n}(this, function(exports, module) {\n\n  /**\n   * PLAIN `Mechanism` constructor.\n   *\n   * This class implements the PLAIN SASL mechanism.\n   *\n   * The PLAIN SASL mechanism provides support for exchanging a clear-text\n   * username and password.  This mechanism should not be used without adequate\n   * security provided by an underlying transport layer. \n   *\n   * References:\n   *  - [RFC 4616](http://tools.ietf.org/html/rfc4616)\n   *\n   * @api public\n   */\n  function Mechanism() {\n  }\n  \n  Mechanism.prototype.name = 'PLAIN';\n  Mechanism.prototype.clientFirst = true;\n  \n  /**\n   * Encode a response using given credential.\n   *\n   * Options:\n   *  - `username`\n   *  - `password`\n   *  - `authzid`   authorization identity (optional)\n   *\n   * @param {Object} cred\n   * @api public\n   */\n  Mechanism.prototype.response = function(cred) {\n    var str = '';\n    str += cred.authzid || '';\n    str += '\\0';\n    str += cred.username;\n    str += '\\0';\n    str += cred.password;\n    return str;\n  };\n  \n  /**\n   * Decode a challenge issued by the server.\n   *\n   * @param {String} chal\n   * @return {Mechanism} for chaining\n   * @api public\n   */\n  Mechanism.prototype.challenge = function(chal) {\n    return this;\n  };\n\n  exports = module.exports = Mechanism;\n  \n}));\n","import mech from \"sasl-plain\";\n\nexport default function saslPlain(sasl) {\n  sasl.use(mech);\n}\n","(function(root, factory) {\n  if (typeof exports === 'object') {\n    // CommonJS\n    factory(exports,\n            module,\n            require('./lib/mechanism'));\n  } else if (typeof define === 'function' && define.amd) {\n    // AMD\n    define(['exports',\n            'module',\n            './lib/mechanism'], factory);\n  }\n}(this, function(exports, module, Mechanism) {\n\n  exports = module.exports = Mechanism;\n  exports.Mechanism = Mechanism;\n  \n}));\n","(function(root, factory) {\n  if (typeof exports === 'object') {\n    // CommonJS\n    factory(exports, module);\n  } else if (typeof define === 'function' && define.amd) {\n    // AMD\n    define(['exports', 'module'], factory);\n  }\n}(this, function(exports, module) {\n\n  /**\n   * ANONYMOUS `Mechanism` constructor.\n   *\n   * This class implements the ANONYMOUS SASL mechanism.\n   *\n   * The ANONYMOUS SASL mechanism provides support for permitting anonymous\n   * access to various services\n   *\n   * References:\n   *  - [RFC 4505](http://tools.ietf.org/html/rfc4505)\n   *\n   * @api public\n   */\n  function Mechanism() {\n  }\n  \n  Mechanism.prototype.name = 'ANONYMOUS';\n  Mechanism.prototype.clientFirst = true;\n  \n  /**\n   * Encode a response using optional trace information.\n   *\n   * Options:\n   *  - `trace`  trace information (optional)\n   *\n   * @param {Object} cred\n   * @api public\n   */\n  Mechanism.prototype.response = function(cred) {\n    return cred.trace || '';\n  };\n  \n  /**\n   * Decode a challenge issued by the server.\n   *\n   * @param {String} chal\n   * @api public\n   */\n  Mechanism.prototype.challenge = function(chal) {\n  };\n\n  exports = module.exports = Mechanism;\n  \n}));\n","import mech from \"sasl-anonymous\";\n\n/**\n * [XEP-0175: Best Practices for Use of SASL ANONYMOUS](https://xmpp.org/extensions/xep-0175.html)\n * [RFC-4504: Anonymous Simple Authentication and Security Layer (SASL) Mechanism](https://tools.ietf.org/html/rfc4505)\n */\n\nexport default function saslAnonymous(sasl) {\n  sasl.use(mech);\n}\n","/* eslint-disable n/no-unsupported-features/node-builtins */\n\n// https://datatracker.ietf.org/doc/draft-schmaus-kitten-sasl-ht/\n// https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API\n\nexport function Mechanism() {}\n\nMechanism.prototype.Mechanism = Mechanism;\nMechanism.prototype.name = \"HT-SHA-256-NONE\";\nMechanism.prototype.clientFirst = true;\n\nMechanism.prototype.response = async function response({ username, password }) {\n  this.key = await crypto.subtle.importKey(\n    \"raw\",\n    new TextEncoder().encode(password),\n    // https://developer.mozilla.org/en-US/docs/Web/API/HmacImportParams\n    { name: \"HMAC\", hash: \"SHA-256\" },\n    false, // extractable\n    [\"sign\", \"verify\"],\n  );\n  const signature = await crypto.subtle.sign(\n    \"HMAC\",\n    this.key,\n    new TextEncoder().encode(\"Initiator\"),\n  );\n  return `${username}\\0${String.fromCodePoint(...new Uint8Array(signature))}`;\n};\n\nMechanism.prototype.final = async function final(data) {\n  const signature = Uint8Array.from(data, (c) => c.codePointAt(0));\n  // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/verify\n  const result = await crypto.subtle.verify(\n    \"HMAC\",\n    this.key,\n    signature,\n    new TextEncoder().encode(\"Responder\"),\n  );\n  if (result !== true) {\n    throw new Error(\"Responder message from server was wrong\");\n  }\n};\n\nexport default function saslHashedToken(sasl) {\n  sasl.use(Mechanism);\n}\n","import type { XMPPClient, XMPPCredentials, XMPPCredentialsAuth, XMPPOptions, XMPPUserAgent } from '@xmppClient';\nimport type { FAST } from '@xmpp/client-core/src/fast/fast.js';\n\nexport function createOnAuthenticate(credentials: XMPPCredentials = {}, userAgent: XMPPUserAgent) {\n  return async function onAuthenticate(...args: unknown[]) {\n    const [authenticate, mechanisms, fast, entity] = args as [XMPPCredentialsAuth, string[], FAST, XMPPClient];\n\n    if (typeof credentials === 'function') {\n      const mechanism = getMechanism(mechanisms, entity);\n\n      await credentials(authenticate, mechanism);\n    } else {\n      credentials.token ??= await fast?.fetch();\n\n      const mechanism = getMechanism(mechanisms, entity, credentials);\n\n      await authenticate(credentials, mechanism, userAgent);\n    }\n  };\n}\n\nexport function getMechanism(mechanisms: string[], entity: XMPPClient, options?: XMPPOptions): string {\n  const username = options?.username || entity.options?.username;\n  const password = options?.password || entity.options?.password;\n  const token = options?.token || entity.options?.token;\n\n  if (!username && !password && !token && mechanisms.includes('ANONYMOUS')) {\n    return 'ANONYMOUS';\n  }\n\n  if (entity.isSecure() || entity.tcpEnabled) return mechanisms[0];\n\n  return mechanisms.find((mechanism) => mechanism !== 'PLAIN') ?? '';\n}\n\nexport function getDomain(service: string): string {\n  const domain = service.split('://')[1] || service;\n\n  return domain.split(':')[0].split('/')[0];\n}\n\nexport function setupIfAvailable(module?: (...args: any[]) => any, ...args: unknown[]): unknown {\n  if (typeof module !== 'function') {\n    return undefined;\n  }\n\n  return module(...args);\n}\n","import config from '../../config';\nimport { xml } from '@xmpp/client-core';\nimport type { Chat, PlainObject, StringObject, StringOrStringObject } from '../../types/index';\n\nexport default class ChatUtils {\n  static buildUserJid(params: Chat.UserJIDParams = {}): string | void {\n    const { userId, resource, jid } = params;\n    const appId = config.creds.appId;\n    const url = config.endpoints.chat;\n\n    return userId ? `${userId}-${appId}@${url}${resource ? `/${resource}` : ''}` : jid;\n  }\n\n  static buildUserJidLocalPart(userId: string | number): string {\n    return `${userId}-${config.creds.appId}`;\n  }\n\n  static createMessageStanza(attrs?: StringOrStringObject): Chat.XmlElement {\n    return xml('message', attrs);\n  }\n\n  static createIqStanza(attrs?: StringOrStringObject): Chat.XmlElement {\n    return xml('iq', attrs);\n  }\n\n  static createPresenceStanza(attrs?: StringOrStringObject): Chat.XmlElement {\n    return xml('presence', attrs);\n  }\n\n  static createNonza(name: string, attrs?: StringOrStringObject): Chat.XmlElement {\n    return xml(name, attrs);\n  }\n\n  static getAttr(element: Chat.XmlElement | undefined, name: string): string {\n    return element?.getAttr(name) || element?.attrs[name] || '';\n  }\n\n  static getElement(element: Chat.XmlElement | undefined, name: string): Chat.XmlElement | undefined {\n    return element?.getChild(name);\n  }\n\n  static getName(element: Chat.XmlElement): string | null {\n    return element?.getName() || null;\n  }\n\n  static getText(element: Chat.XmlElement): string | null {\n    return element?.getText() || null;\n  }\n\n  static getChildElements(element: Chat.XmlElement | undefined): Chat.XmlElement[] {\n    return element?.getChildElements() || [];\n  }\n\n  static isErrorStanza(element: Chat.XmlElement): boolean {\n    return !!element?.getChild('error');\n  }\n\n  static getAllElements(element: Chat.XmlElement, name: string): Chat.XmlElement[] {\n    return element?.getChildren(name) || [];\n  }\n\n  static getElementText(element: Chat.XmlElement, name: string): string | null {\n    return element?.getChildText(name) || null;\n  }\n\n  static getElementTreePath(element: Chat.XmlElement, elementsPath: string[]): Chat.XmlElement | undefined {\n    return elementsPath.reduce<Chat.XmlElement | undefined>(\n      (prevElement: Chat.XmlElement | undefined, name: string) =>\n        prevElement ? ChatUtils.getElement(prevElement, name) : undefined,\n      element as Chat.XmlElement\n    );\n  }\n\n  static assignObjectToXml(element: Chat.XmlElement, obj: PlainObject, name: string): Chat.XmlElement {\n    element = element.c(name);\n\n    Object.keys(obj).forEach((key: string) => {\n      const val = obj[key] as PlainObject;\n\n      if (val !== null && typeof val === 'object') {\n        ChatUtils.assignObjectToXml(element, val, key);\n      } else {\n        element = element\n          .c(key)\n          .t(String(val ?? ''))\n          .up();\n      }\n    });\n\n    element = element.up();\n\n    return element;\n  }\n\n  static assignExtraParamsToXml(element: Chat.XmlElement, extension: PlainObject): Chat.XmlElement {\n    let extraParams = ChatUtils.getElement(element, 'extraParams');\n\n    Object.keys(extension).forEach((key) => {\n      const val = extension[key];\n\n      if (key === 'attachments' && Array.isArray(val)) {\n        val.forEach((attachment: unknown) => {\n          extraParams!.c('attachment', attachment as StringObject).up();\n        });\n      } else if (val !== null && typeof val === 'object') {\n        ChatUtils.assignObjectToXml(extraParams!, val as PlainObject, key);\n      } else {\n        extraParams!\n          .c(key)\n          .t(String(val ?? ''))\n          .up();\n      }\n    });\n\n    element.up();\n\n    return element;\n  }\n\n  static assignXmlToObject(element: Chat.XmlElement, obj: PlainObject): PlainObject {\n    const { children, name } = element;\n    const item: PlainObject = { [name]: {} };\n\n    children.forEach((node: Chat.XmlNode) => {\n      if (typeof node === 'string') {\n        (item as PlainObject)[name] = node;\n      } else if (node.children.length > 0) {\n        ChatUtils.assignXmlToObject(node, (item[name] as PlainObject) || {});\n      } else {\n        ((item[name] as PlainObject) || {})[node.name] = ChatUtils.getText(node);\n      }\n    });\n\n    return Object.assign(obj, item);\n  }\n\n  static parseExtraParams(element: Chat.XmlElement): Chat.ParseExtraParamsResult | null {\n    if (!element) {\n      return null;\n    }\n\n    const extension: Chat.MessageExtension = { attachments: [] };\n    let dialogId: string | null = null;\n\n    element.children.forEach((node: Chat.XmlNode) => {\n      if (typeof node === 'string') {\n        return;\n      }\n\n      if (node.name === 'attachment') {\n        const attachment: PlainObject = {};\n\n        Object.keys(node.attrs).forEach((key: string) => {\n          attachment[key] = key === 'size' ? parseInt(String(node.attrs.size), 10) : node.attrs[key];\n        });\n\n        extension.attachments!.push(attachment);\n      } else if (node.name === 'dialog_id') {\n        dialogId = ChatUtils.getElementText(element, 'dialog_id');\n        extension.dialog_id = dialogId ?? undefined;\n      }\n\n      if (node.children.length) {\n        ChatUtils.assignXmlToObject(node, extension);\n      }\n    });\n\n    if (Array.isArray(extension.attachments) && extension.attachments.length === 0) {\n      delete extension.attachments;\n    }\n    if (extension.moduleIdentifier) {\n      delete extension.moduleIdentifier;\n    }\n\n    return { extension, dialogId };\n  }\n\n  static buildErrorFromXMPPErrorStanza(errorStanza: Chat.XmlElement): { code: number; info: string | null } {\n    const errorElement = ChatUtils.getElement(errorStanza, 'error');\n    const code = errorElement ? parseInt(ChatUtils.getAttr(errorElement, 'code') || '0', 10) : 0;\n    const info = errorElement ? ChatUtils.getElementText(errorElement, 'text') : null;\n    return { code: code, info: info };\n  }\n\n  static getUniqueId(suffix?: unknown): string {\n    const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n      const r = (Math.random() * 16) | 0;\n      const v = c == 'x' ? r : (r & 0x3) | 0x8;\n      return v.toString(16);\n    });\n\n    if (typeof suffix === 'string' || typeof suffix === 'number') {\n      return `${uuid}:${suffix}`;\n    } else {\n      return uuid;\n    }\n  }\n\n  static parseReactions(element: Chat.XmlElement): Chat.ParseReactionsResult {\n    const reactions = ChatUtils.getChildElements(element).map((node: Chat.XmlElement) => ({\n      add: ChatUtils.getAttr(node, 'add') === 'true',\n      remove: ChatUtils.getAttr(node, 'remove') === 'true',\n      reaction: ChatUtils.getAttr(node, 'type'),\n    }));\n\n    return reactions.reduce((items, { add, remove, reaction }) => {\n      if (add) {\n        items['add'] = reaction;\n      } else if (remove) {\n        items['remove'] = reaction;\n      }\n      return items;\n    }, {} as Chat.ParseReactionsResult);\n  }\n}\n","import type { Element } from '@xmpp/xml';\nimport type { Options } from '@xmpp/connection';\nimport type { Reconnect } from '@xmpp/reconnect';\nimport type { Middleware } from '@xmpp/middleware';\nimport type { StreamFeatures } from '@xmpp/stream-features';\nimport type { IQCaller } from '@xmpp/iq/caller.js';\nimport type { IQCallee } from '@xmpp/iq/callee.js';\nimport type { SASL2 } from '@xmpp/sasl2';\nimport type { SASL } from '@xmpp/sasl';\nimport type { Resource } from '@xmpp/resource-binding';\nimport type { Bind2 } from '@xmpp/client-core/src/bind2/bind2.js';\nimport type { Token, FAST } from '@xmpp/client-core/src/fast/fast.js';\n\nimport WebSocketImpl from 'ws';\nimport { jid, xml, Client } from '@xmpp/client-core';\nimport _reconnect from '@xmpp/reconnect';\nimport _websocket from '@xmpp/websocket';\nimport _tcp from '@xmpp/tcp';\nimport _tls from '@xmpp/tls';\nimport _middleware from '@xmpp/middleware';\nimport _streamFeatures from '@xmpp/stream-features';\nimport _iqCaller from '@xmpp/iq/caller.js';\nimport _iqCallee from '@xmpp/iq/callee.js';\nimport _resolve from '@xmpp/resolve';\nimport _starttls from '@xmpp/starttls';\nimport _sasl2 from '@xmpp/sasl2';\nimport _sasl from '@xmpp/sasl';\nimport _resourceBinding from '@xmpp/resource-binding';\nimport _bind2 from '@xmpp/client-core/src/bind2/bind2.js';\nimport _fast from '@xmpp/client-core/src/fast/fast.js';\nimport scramsha1 from '@xmpp/sasl-scram-sha-1';\nimport plain from '@xmpp/sasl-plain';\nimport anonymous from '@xmpp/sasl-anonymous';\nimport htsha256none from '@xmpp/sasl-ht-sha-256-none';\nimport SASLFactory from 'saslmechanisms';\nimport { createOnAuthenticate, getDomain, setupIfAvailable } from './xmpp.utils';\nimport ChatUtils from './ChatUtils';\nimport Utils from '../../Utils';\nimport config from '../../config';\nimport { ChatAPIs } from '../../types/constants';\n\nif (\n  config.chat.apiImp === ChatAPIs.XMPP ||\n  (typeof globalThis.WebSocket === 'undefined' && typeof WebSocketImpl !== 'undefined')\n) {\n  globalThis.WebSocket = WebSocketImpl as unknown as typeof globalThis.WebSocket;\n}\n\nconst { CUBE_TCP_ENABLE, CUBE_TLS_ENABLE } = process?.env || {};\nconst tcpEnabled = !!CUBE_TCP_ENABLE;\nconst tlsEnabled = !!CUBE_TLS_ENABLE;\n\nexport type XMPPResource = Resource | string | (() => Promise<string>) | undefined;\nexport type XMPPCredentialsProp = string | undefined;\nexport type XMPPCredentialsAuth = (\n  credentials: Partial<XMPPCredentialsObj>,\n  mechanism: string,\n  userAgent?: XMPPUserAgent\n) => Promise<void>;\nexport type XMPPCredentials =\n  | Partial<XMPPCredentialsObj>\n  | ((callback: XMPPCredentialsAuth, mechanism: string) => Promise<void>)\n  | undefined;\nexport type XMPPUserAgent = Element | undefined;\n\nexport interface XMPPCredentialsObj {\n  username: XMPPCredentialsProp;\n  password: XMPPCredentialsProp;\n  token: Token;\n}\n\nexport interface XMPPOptions extends Options, Partial<XMPPCredentialsObj> {\n  resource?: XMPPResource;\n  credentials?: XMPPCredentials;\n  userAgent?: XMPPUserAgent;\n}\n\nexport interface XMPPClient extends Client {\n  entity: Client;\n  reconnect: Reconnect<Client>;\n  websocket: ReturnType<typeof _websocket>;\n  tcp: ReturnType<typeof _tcp>;\n  tls: ReturnType<typeof _tls>;\n  middleware: Middleware<Client>;\n  streamFeatures: StreamFeatures<Client>;\n  iqCaller: IQCaller<Client>;\n  iqCallee: IQCallee<Client>;\n  resolve: ReturnType<typeof _resolve>;\n  starttls: Middleware<Client>;\n  saslFactory: SASLFactory;\n  sasl2: SASL2;\n  sasl: SASL;\n  resourceBinding: ReturnType<typeof _resourceBinding>;\n  mechanisms: { [x: string]: void }[];\n  bind2: Bind2;\n  fast: FAST;\n  options: XMPPOptions;\n  sendOnline: (element: Element, ...args: unknown[]) => Promise<void>;\n  tcpEnabled?: boolean;\n  tlsEnabled?: boolean;\n}\n\nfunction xmppClient(options: XMPPOptions): XMPPClient {\n  let { resource, credentials, username, password, userAgent, ...params } = options;\n\n  const { domain, service } = params;\n\n  if (!domain && service) {\n    params.domain = getDomain(service);\n  }\n\n  const entity = new Client(params);\n\n  if (username && params.domain) {\n    entity.jid = jid(username, params.domain);\n  }\n\n  const reconnect = _reconnect({ entity });\n  const websocket = _websocket({ entity });\n  const tcp = setupIfAvailable(tcpEnabled ? _tcp : undefined, { entity });\n  const tls = setupIfAvailable(tlsEnabled ? _tls : undefined, { entity });\n  const middleware = _middleware({ entity });\n  const streamFeatures = _streamFeatures({ middleware });\n  const iqCaller = _iqCaller({ middleware, entity });\n  const iqCallee = _iqCallee({ middleware, entity });\n  const resolve = _resolve({ entity });\n\n  // SASL mechanisms - order matters and define priority\n  const saslFactory = new SASLFactory();\n  const mechanisms = Object.entries({ ...(typeof scramsha1 === 'function' && { scramsha1 }), plain, anonymous }).map(\n    ([k, v]) => ({ [k]: v(saslFactory) })\n  );\n\n  userAgent ??= xml('user-agent', { id: ChatUtils.getUniqueId() });\n\n  // Stream features - order matters and define priority\n  const starttls = setupIfAvailable(tlsEnabled ? _starttls : undefined, { streamFeatures });\n  const sasl2 = _sasl2(\n    { streamFeatures, saslFactory },\n    createOnAuthenticate(credentials ?? { username, password }, userAgent)\n  );\n\n  const fast = _fast({ sasl2, entity });\n\n  sasl2.setup({ fast });\n\n  // SASL2 inline features\n  const bind2 = _bind2({ sasl2, entity }, resource as string | (() => Promise<string>));\n\n  // FAST mechanisms - order matters and define priority\n  htsha256none(fast.saslFactory);\n\n  // Stream features - order matters and define priority\n  const sasl = _sasl(\n    { streamFeatures, saslFactory },\n    createOnAuthenticate(credentials ?? { username, password }, userAgent)\n  );\n  const resourceBinding = _resourceBinding({ iqCaller, streamFeatures }, resource as Resource | undefined);\n\n  iqCallee?.get('urn:xmpp:ping', 'ping', () => ({}));\n\n  const sendOnline = function (element: Element, ...args: unknown[]): Promise<void> {\n    if (entity.status === 'online') {\n      return entity.send.call(entity, element, ...args);\n    } else {\n      const message = \"You are not connected to chat. Please call 'connect' function first\";\n\n      Utils.DLog('[Chat][Error]', message);\n\n      return Promise.reject(new Error(message));\n    }\n  };\n\n  return Object.assign(entity, {\n    entity,\n    reconnect,\n    tcp,\n    websocket,\n    tls,\n    middleware,\n    streamFeatures,\n    iqCaller,\n    iqCallee,\n    resolve,\n    starttls,\n    saslFactory,\n    sasl2,\n    sasl,\n    resourceBinding,\n    mechanisms,\n    bind2,\n    fast,\n    sendOnline,\n    tcpEnabled,\n    tlsEnabled,\n  }) as XMPPClient;\n}\n\nexport { jid, xml, xmppClient };\n","import ConnectionWebSocket from \"./lib/Connection.js\";\n\nexport default function websocket({ entity }) {\n  entity.transports.push(ConnectionWebSocket);\n}\n","/**\n * References\n * https://xmpp.org/rfcs/rfc6120.html#streams-negotiation Stream Negotiation\n * https://xmpp.org/extensions/xep-0170.html XEP-0170: Recommended Order of Stream Feature Negotiation\n * https://xmpp.org/registrar/stream-features.html XML Stream Features\n */\n\nexport default function streamFeatures({ middleware }) {\n  function use(name, xmlns, handler) {\n    return middleware.use((ctx, next) => {\n      const { stanza } = ctx;\n      if (!stanza.is(\"features\", \"http://etherx.jabber.org/streams\"))\n        return next();\n      const feature = stanza.getChild(name, xmlns);\n      if (!feature) return next();\n      return handler(ctx, next, feature);\n    });\n  }\n\n  return {\n    use,\n  };\n}\n","import Utils from '../../Utils';\nimport config from '../../config';\nimport ChatUtils from './ChatUtils';\n\nexport default class ChatHelpers {\n  public xmppJID: string = '';\n\n  public get userCurrentJid(): string | '' {\n    return this.xmppJID;\n  }\n\n  public set userCurrentJid(jid: string | null) {\n    this.xmppJID = jid || '';\n  }\n\n  public getUniqueId = ChatUtils.getUniqueId;\n\n  public isNumeric(value: string): boolean {\n    return /^-?\\d+$/.test(value) || /^\\d+\\.\\d+$/.test(value);\n  }\n\n  public jidOrUserId(jidOrUserId: string | number): string {\n    if (typeof jidOrUserId === 'string') {\n      return this.isNumeric(jidOrUserId)\n        ? this.getUserJid(jidOrUserId)\n        : jidOrUserId.includes('@')\n          ? jidOrUserId\n          : this.getRoomJidFromDialogId(jidOrUserId);\n    }\n\n    return this.getUserJid(jidOrUserId);\n  }\n\n  public typeChat(jidOrUserId: string | number): 'chat' | 'groupchat' {\n    switch (typeof jidOrUserId) {\n      case 'string':\n        return this.isNumeric(jidOrUserId)\n          ? 'chat'\n          : jidOrUserId.includes('@')\n            ? jidOrUserId.includes('muc')\n              ? 'groupchat'\n              : 'chat'\n            : 'groupchat';\n      case 'number':\n        return 'chat';\n      default:\n        throw new Error('Unsupported chat type');\n    }\n  }\n\n  public getUserJid(userId: string | number): string {\n    return `${userId}-${config.creds.appId}@${config.endpoints.chat}`;\n  }\n\n  public getUserNickWithMucDomain(userId: string | number): string {\n    return `${config.endpoints.muc}/${userId}`;\n  }\n\n  public getUserIdFromJID(jid: string = this.userCurrentJid): number | null {\n    return jid?.includes('@') ? parseInt(jid.split('@')[0].split('-')[0]) : null;\n  }\n\n  public getDialogIdFromJID(jid: string): string | null {\n    return jid?.includes('@') ? jid.split('@')[0].split('_')[1] : null;\n  }\n\n  public getRoomJidFromDialogId(dialogId: string): string {\n    return `${config.creds.appId}_${dialogId}@${config.endpoints.muc}`;\n  }\n\n  public getRoomJid(jid: string): string {\n    return `${jid}/${this.getUserIdFromJID(this.userCurrentJid)}`;\n  }\n\n  public getIdFromResource(jid: string): number | null {\n    const parts = jid.split('/');\n    return parts.length > 1 ? parseInt(parts.slice(1).join('/')) : null;\n  }\n\n  public getRoomJidFromRoomFullJid(jid: string): string | null {\n    const parts = jid.split('/');\n    return parts.length > 1 ? parts[0] : null;\n  }\n\n  public getBsonObjectId = Utils.getBsonObjectId;\n\n  public getUserIdFromRoomJid(roomJid: string): number | null {\n    const parts = roomJid.split('/');\n    return parts.length > 1 ? parseInt(parts[parts.length - 1]) : null;\n  }\n\n  getDialogJid(identifier: string): string {\n    return identifier.indexOf('@') > 0 ? identifier : this.getRoomJidFromDialogId(identifier);\n  }\n}\n","import type { Chat, StringObject } from '../../types';\nimport type XMPPChatService from '.';\nimport { ChatProtocol, ChatType } from '../../types/constants';\nimport config from '../../config';\nimport ChatUtils from './ChatUtils';\nimport Utils from '../../Utils';\n\nconst NonzaName = {\n  ENABLE: 'enable',\n  ENABLED: 'enabled',\n  REQUEST: 'r',\n  ANSWER: 'a',\n} as const;\n\nexport default class StreamManagement {\n  readonly xmlns = 'urn:xmpp:sm:3';\n\n  private enabled: boolean = false;\n  private clientHandledCounter: number = 0;\n  private serverHandledCounter: number = 0;\n  private messagesQueue: Set<Chat.MessageParams> = new Set();\n  private messagesQueueClearTimer?: NodeJS.Timeout | number;\n\n  constructor(private chat: XMPPChatService) {}\n\n  public get supported(): boolean {\n    return config.chatProtocol.active === ChatProtocol.WS && (config.chat.streamManagement?.enable ?? false);\n  }\n\n  public start(): void {\n    this.enabled = false;\n\n    if (this.supported) {\n      this.removeElementHandler();\n      this.addElementHandler();\n      this.sendNonza(NonzaName.ENABLE);\n    }\n  }\n\n  public stop(): void {\n    this.enabled = false;\n\n    if (this.supported) {\n      this.removeElementHandler();\n      this.markMessagesQueueAsLost();\n    }\n  }\n\n  public async sendAndCount(stanza: Chat.XmlElement, message: Chat.MessageParams): Promise<void> {\n    const type = ChatUtils.getAttr(stanza, 'type');\n    const body = ChatUtils.getElementText(stanza, 'body');\n    const attachments = ChatUtils.getAllElements(stanza, 'attachment');\n    const isMessage = stanza.name === 'message';\n    const isChat = type === ChatType.CHAT || type === ChatType.GROUPCHAT;\n    const isContent = Boolean(body || attachments.length);\n\n    try {\n      await this.chat.xmppClient.sendOnline(stanza);\n\n      if (this.enabled && isMessage && isChat && isContent) {\n        this.messagesQueue.add(message);\n        this.sendNonza(NonzaName.REQUEST);\n      }\n    } catch {\n      this.markMessageAsLost(message);\n    }\n  }\n\n  private elementHandler = (stanza: Chat.XmlElement): void => {\n    const [name, xmlns] = [stanza.name, ChatUtils.getAttr(stanza, 'xmlns')];\n\n    if (xmlns === this.xmlns && name === NonzaName.ENABLED) {\n      this.clientHandledCounter = 0;\n      this.serverHandledCounter = 0;\n      this.enabled = true;\n      return;\n    }\n\n    if (xmlns !== this.xmlns) this.clientHandledCounter++;\n\n    if (name === NonzaName.REQUEST) {\n      this.sendNonza(NonzaName.ANSWER);\n      return;\n    }\n\n    if (name === NonzaName.ANSWER) {\n      const nextHandledCounter = parseInt(ChatUtils.getAttr(stanza, 'h'), 10);\n      const currHandledCounter = Number.isNaN(nextHandledCounter) ? this.serverHandledCounter : nextHandledCounter;\n      const diffHandledCounter = currHandledCounter - this.serverHandledCounter;\n\n      this.serverHandledCounter = currHandledCounter;\n      this.markMessagesQueueAsSent(diffHandledCounter);\n      this.markMessagesQueueAsLostByTimeout();\n    }\n  };\n\n  private markMessageAsSent(message: Chat.MessageParams): void {\n    Utils.safeCallbackCall(this.chat.onSentMessageCallback)(null, message);\n    this.messagesQueue.delete(message);\n  }\n\n  private markMessageAsLost(message: Chat.MessageParams, clear: boolean = true): void {\n    Utils.safeCallbackCall(this.chat.onSentMessageCallback)(message, null);\n    if (clear) this.messagesQueue.delete(message);\n  }\n\n  private markMessagesQueueAsSent(iterations: number = 0): void {\n    const iterator = this.messagesQueue.values();\n\n    for (let i = 0; i < iterations; i++) {\n      const { done, value } = iterator.next();\n      if (done) break;\n      this.markMessageAsSent(value);\n    }\n  }\n\n  private markMessagesQueueAsLost(): void {\n    clearTimeout(this.messagesQueueClearTimer);\n    this.messagesQueueClearTimer = undefined;\n\n    if (this.messagesQueue.size > 0) {\n      this.messagesQueue.forEach((message) => {\n        this.markMessageAsLost(message, false);\n      });\n      this.messagesQueue.clear();\n    }\n  }\n\n  private markMessagesQueueAsLostByTimeout(): void {\n    const ackTimeout = (config.chat.streamManagement?.acknowledgementTimeout ?? 30) * 1000;\n\n    clearTimeout(this.messagesQueueClearTimer);\n    this.messagesQueueClearTimer = setTimeout(() => {\n      this.markMessagesQueueAsLost();\n    }, ackTimeout);\n  }\n\n  private sendNonza(name: string): Promise<void> {\n    const attrs: StringObject =\n      name === NonzaName.ANSWER ? { xmlns: this.xmlns, h: String(this.clientHandledCounter) } : { xmlns: this.xmlns };\n    const nonza = ChatUtils.createNonza(name, attrs);\n\n    return this.chat.xmppClient.sendOnline(nonza);\n  }\n\n  private removeElementHandler(): void {\n    this.chat.xmppClient.removeListener('element', this.elementHandler);\n  }\n\n  private addElementHandler(): void {\n    this.chat.xmppClient.on('element', this.elementHandler);\n  }\n}\n","import type { XMPPClient } from '@xmppClient';\nimport type { Chat } from '../../types';\nimport { PrivacyListAction } from '../../types/constants';\nimport ChatUtils from './ChatUtils';\nimport ChatHelpers from './Helpers';\n\nexport default class PrivacyList {\n  readonly xmlns = 'jabber:iq:privacy';\n  public helpers: ChatHelpers;\n  public xmppClient: XMPPClient;\n  public stanzasCallbacks: Chat.StanzasCallbacks;\n\n  constructor(options: { helpers: ChatHelpers; xmppClient: XMPPClient; stanzasCallbacks: Chat.StanzasCallbacks }) {\n    this.helpers = options.helpers;\n    this.xmppClient = options.xmppClient;\n    this.stanzasCallbacks = options.stanzasCallbacks;\n  }\n\n  public async create(list: Chat.PrivacyList): Promise<void> {\n    return new Promise((resolve, reject) => {\n      const privacyList = list.items.reduce(\n        (acc, { user_id, action, mutualBlock }) => {\n          acc[user_id] = { action, mutualBlock };\n          return acc;\n        },\n        {} as Record<string, Partial<Chat.PrivacyListItem>>\n      );\n\n      const privacyListKeys = Object.keys(privacyList);\n      const iqParams = {\n        type: 'set',\n        from: this.helpers.userCurrentJid,\n        id: ChatUtils.getUniqueId('edit'),\n      };\n\n      let iq = ChatUtils.createIqStanza(iqParams);\n\n      iq.c('query', { xmlns: this.xmlns }).c('list', { name: list.name });\n\n      for (let index = 0, j = 0, len = privacyListKeys.length; index < len; index++, j = j + 2) {\n        const userId = privacyListKeys[index];\n        const { action = '', mutualBlock = false } = privacyList[userId];\n        const isMutual = mutualBlock && action === 'deny';\n        const userJid = this.helpers.jidOrUserId(parseInt(userId, 10));\n        const userMuc = this.helpers.getUserNickWithMucDomain(userId);\n\n        this.assignPrivacyItem(iq, { order: j + 1, value: userJid, action, isMutual });\n        this.assignPrivacyItem(iq, { order: j + 2, value: userMuc, action, isMutual });\n      }\n\n      this.stanzasCallbacks[iqParams.id] = (stanza: Chat.XmlElement) => {\n        ChatUtils.isErrorStanza(stanza) ? reject(ChatUtils.buildErrorFromXMPPErrorStanza(stanza)) : resolve();\n      };\n\n      this.xmppClient.sendOnline(iq);\n    });\n  }\n\n  public async getList(name: string): Promise<Chat.PrivacyList> {\n    return new Promise((resolve, _reject) => {\n      const id = ChatUtils.getUniqueId('getlist');\n      const iq = ChatUtils.createIqStanza({\n        type: 'get',\n        from: this.helpers.userCurrentJid,\n        id,\n      });\n\n      iq.c('query', { xmlns: this.xmlns }).c('list', { name });\n\n      this.stanzasCallbacks[id] = (stanza: Chat.XmlElement): void => {\n        const query = stanza ? ChatUtils.getElement(stanza, 'query') : undefined;\n        const list = query ? ChatUtils.getElement(query, 'list') : undefined;\n\n        const privacyList: Chat.PrivacyList = {\n          name: ChatUtils.getAttr(list, 'name'),\n          items: ChatUtils.getChildElements(list)\n            .map((item, index) => {\n              if (index % 2 === 0) {\n                const { action, value } = item.attrs;\n                return {\n                  user_id: this.helpers.getUserIdFromJID(value),\n                  action: action,\n                } as Chat.PrivacyListItem;\n              }\n              return null;\n            })\n            .filter((item) => item !== null),\n        };\n\n        resolve(privacyList);\n\n        delete this.stanzasCallbacks[id];\n      };\n\n      this.xmppClient.sendOnline(iq);\n    });\n  }\n\n  public async update(list: Chat.PrivacyList): Promise<void> {\n    try {\n      const currentList = await this.getList(list.name);\n      const map = new Map(currentList.items.map((currentListItem) => [currentListItem.user_id, currentListItem]));\n\n      for (const item of list.items) {\n        if (item.action === PrivacyListAction.ALLOW) {\n          map.delete(item.user_id);\n        } else {\n          const updatedItem = Object.assign({}, map.get(item.user_id), item);\n          map.set(item.user_id, updatedItem);\n        }\n      }\n\n      const updatedListItems = Array.from(map.values());\n      const updatedList = { name: list.name, items: updatedListItems };\n\n      await this.create(updatedList);\n    } catch (error) {\n      throw error;\n    }\n  }\n\n  public async getNames(): Promise<Chat.PrivacyListNames> {\n    return new Promise((resolve, reject) => {\n      const id = ChatUtils.getUniqueId('getNames');\n      const iq = ChatUtils.createIqStanza({\n        type: 'get',\n        from: this.helpers.userCurrentJid,\n        id,\n      });\n\n      iq.c('query', { xmlns: this.xmlns });\n\n      this.stanzasCallbacks[id] = (stanza: Chat.XmlElement) => {\n        if (!ChatUtils.isErrorStanza(stanza)) {\n          const query = stanza ? ChatUtils.getElement(stanza, 'query') : undefined;\n          const defaultElement = query ? ChatUtils.getElement(query, 'default') : undefined;\n          const activeElement = query ? ChatUtils.getElement(query, 'active') : undefined;\n          const defaultName = defaultElement ? ChatUtils.getAttr(defaultElement, 'name') : null;\n          const activeName = activeElement ? ChatUtils.getAttr(activeElement, 'name') : null;\n          const allNames = query\n            ? ChatUtils.getChildElements(query).map((listEl) => ChatUtils.getAttr(listEl, 'name'))\n            : [];\n\n          const namesList: Chat.PrivacyListNames = {\n            default: defaultName,\n            active: activeName,\n            names: allNames,\n          };\n\n          resolve(namesList);\n        } else {\n          reject(ChatUtils.buildErrorFromXMPPErrorStanza(stanza));\n        }\n      };\n\n      this.xmppClient.sendOnline(iq);\n    });\n  }\n\n  public async delete(name: string): Promise<void> {\n    return new Promise((resolve, reject) => {\n      const id = ChatUtils.getUniqueId('remove');\n      const iq = ChatUtils.createIqStanza({\n        type: 'set',\n        from: this.helpers.userCurrentJid,\n        id,\n      });\n\n      iq.c('query', { xmlns: this.xmlns }).c('list', { name: name ? name : '' });\n\n      this.stanzasCallbacks[id] = (stanza: Chat.XmlElement) => {\n        ChatUtils.isErrorStanza(stanza) ? reject(ChatUtils.buildErrorFromXMPPErrorStanza(stanza)) : resolve();\n      };\n\n      this.xmppClient.sendOnline(iq);\n    });\n  }\n\n  public async setAsDefault(name: string | null): Promise<void> {\n    return new Promise((resolve, reject) => {\n      const id = ChatUtils.getUniqueId('default');\n      const iq = ChatUtils.createIqStanza({\n        type: 'set',\n        from: this.helpers.userCurrentJid,\n        id,\n      });\n\n      iq.c('query', { xmlns: this.xmlns }).c('default', name ? { name: name } : {});\n\n      this.stanzasCallbacks[id] = (stanza: Chat.XmlElement) => {\n        ChatUtils.isErrorStanza(stanza) ? reject(ChatUtils.buildErrorFromXMPPErrorStanza(stanza)) : resolve();\n      };\n\n      this.xmppClient.sendOnline(iq);\n    });\n  }\n\n  private assignPrivacyItem(iq: Chat.XmlElement, params: Chat.PrivacyListItemParams): void {\n    const { value, action, order, isMutual } = params;\n    const query = iq ? ChatUtils.getElement(iq, 'query') : undefined;\n    const list = query ? ChatUtils.getElement(query, 'list') : undefined;\n\n    if (!list) return;\n\n    const item = list.c('item', { type: 'jid', value, action, order });\n\n    if (isMutual) {\n      item.up();\n\n      if (order % 2 === 0) {\n        iq.up().up();\n      }\n    } else {\n      item.c('message', {}).up().c('presence-in', {}).up().c('presence-out', {}).up().c('iq', {}).up().up();\n    }\n  }\n}\n","import type { XMPPClient } from '@xmppClient';\nimport type { Chat } from '../../types';\nimport ChatHelpers from './Helpers';\nimport ChatUtils from './ChatUtils';\n\nexport default class MultiUserChat {\n  readonly xmlns = 'http://jabber.org/protocol/muc';\n  public helpers: ChatHelpers;\n  public xmppClient: XMPPClient;\n  public stanzasCallbacks: Chat.StanzasCallbacks;\n  public joinedRooms: { [jid: string]: boolean } = {};\n\n  constructor(options: { helpers: ChatHelpers; xmppClient: XMPPClient; stanzasCallbacks: Chat.StanzasCallbacks }) {\n    this.helpers = options.helpers;\n    this.xmppClient = options.xmppClient;\n    this.stanzasCallbacks = options.stanzasCallbacks;\n  }\n\n  public async join(dialogIdOrJid: string): Promise<void> {\n    return new Promise((resolve, reject) => {\n      const id = ChatUtils.getUniqueId('join');\n      const dialogJid = this.helpers.getDialogJid(dialogIdOrJid);\n      const presenceStanza = ChatUtils.createPresenceStanza({\n        id: id,\n        from: this.helpers.userCurrentJid,\n        to: this.helpers.getRoomJid(dialogJid),\n      });\n\n      presenceStanza.c('x', { xmlns: this.xmlns }).c('history', { maxstanzas: 0 });\n\n      this.stanzasCallbacks[id] = (stanza: Chat.XmlElement) => {\n        const x = stanza ? ChatUtils.getElement(stanza, 'x') : undefined;\n        const status = x ? ChatUtils.getElement(x, 'status') : undefined;\n        const code = status ? ChatUtils.getAttr(status, 'code') : undefined;\n\n        if (code === '110') {\n          this.joinedRooms[dialogJid] = true;\n          resolve();\n        } else {\n          const isJoin = ChatUtils.getAttr(x, 'xmlns') === this.xmlns && id.endsWith(':join');\n          const isError = ChatUtils.getAttr(stanza, 'type') === 'error';\n\n          if (isJoin && isError) {\n            const errorElement = ChatUtils.getElement(stanza, 'error');\n\n            if (!errorElement) {\n              reject(new Error('Unknown error'));\n              return;\n            }\n\n            const errorResponse = {\n              code: ChatUtils.getAttr(errorElement, 'code'),\n              message: ChatUtils.getElementText(errorElement, 'text') || 'Unknown issue',\n            };\n\n            reject(errorResponse);\n          }\n        }\n      };\n\n      this.xmppClient.sendOnline(presenceStanza);\n    });\n  }\n\n  public async leave(dialogIdOrJid: string): Promise<void> {\n    return new Promise((resolve) => {\n      const dialogJid = this.helpers.getDialogJid(dialogIdOrJid);\n      const presenceStanza = ChatUtils.createPresenceStanza({\n        type: 'unavailable',\n        from: this.helpers.userCurrentJid,\n        to: this.helpers.getRoomJid(dialogJid),\n      });\n\n      delete this.joinedRooms[dialogJid];\n\n      this.stanzasCallbacks['muc:leave'] = (_stanza: Chat.XmlElement) => {\n        resolve();\n      };\n\n      this.xmppClient.sendOnline(presenceStanza);\n    });\n  }\n\n  public async listOnlineUsers(dialogIdOrJid: string): Promise<number[]> {\n    return new Promise((resolve, _reject) => {\n      const id = ChatUtils.getUniqueId('muc_disco_items');\n      const iqStanza = ChatUtils.createIqStanza({\n        type: 'get',\n        to: this.helpers.getDialogJid(dialogIdOrJid),\n        from: this.helpers.userCurrentJid,\n        id,\n      });\n\n      iqStanza.c('query', { xmlns: 'http://jabber.org/protocol/disco#items' });\n\n      this.stanzasCallbacks[id] = (stanza: Chat.XmlElement) => {\n        const stanzaId = ChatUtils.getAttr(stanza, 'id');\n\n        if (this.stanzasCallbacks[stanzaId]) {\n          const query = ChatUtils.getElement(stanza, 'query');\n          const users = ChatUtils.getChildElements(query)\n            .map((item: Chat.XmlElement): number | null => {\n              const roomJid = ChatUtils.getAttr(item, 'jid');\n              return this.helpers.getUserIdFromRoomJid(roomJid);\n            })\n            .filter((userId: number | null) => userId !== null);\n\n          resolve(users);\n        }\n      };\n\n      this.xmppClient.sendOnline(iqStanza);\n    });\n  }\n}\n","import type { Dialogs, EmptyResponse, ForceParams } from '../../types';\nimport { ProxyMethod, ProxyType } from '../../types/constants';\nimport ProxyService from '../../Proxy';\nimport Utils from '../../Utils';\nimport config from '../../config';\n\nexport default class DialogsService {\n  public proxy: ProxyService;\n  readonly route = `${config.urls.chat}/Dialog`;\n\n  constructor(proxy: ProxyService) {\n    this.proxy = proxy;\n  }\n\n  public async list(params: Dialogs.ListParams = {}): Promise<Dialogs.ListResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.GET,\n      url: Utils.getUrl(this.route),\n      data: params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async create(params: Dialogs.CreateParams): Promise<Dialogs.Dialog> {\n    const data = Utils.cloneObject(params);\n\n    const ajaxParams = {\n      type: ProxyMethod.POST,\n      url: Utils.getUrl(this.route),\n      data: {\n        ...data,\n        admins_ids: Utils.isArray(data.admins_ids) ? data.admins_ids.join(', ') : data.admins_ids,\n        occupants_ids: Utils.isArray(data.occupants_ids) ? data.occupants_ids.join(', ') : data.occupants_ids,\n      },\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async update(id: string, params: Dialogs.UpdateParams = {}): Promise<Dialogs.Dialog> {\n    const ajaxParams = {\n      type: ProxyMethod.PUT,\n      url: Utils.getUrl(this.route, id),\n      data: params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public delete(id: string, params?: ForceParams): Promise<EmptyResponse>;\n  public delete(ids: string[], params?: ForceParams): Promise<Dialogs.DeleteResponse>;\n  public async delete(\n    idOrIds: string | string[],\n    params: ForceParams = {}\n  ): Promise<Dialogs.DeleteResponse | EmptyResponse> {\n    const idsToDelete = typeof idOrIds === 'string' ? idOrIds.split(',').map((id) => id.trim()) : idOrIds;\n    const ajaxParams = {\n      type: ProxyMethod.DELETE,\n      url: Utils.getUrl(this.route, idsToDelete.toString()),\n      dataType: idsToDelete.length === 1 ? ProxyType.TEXT : ProxyType.JSON,\n      data: params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async addAdmins(id: string, admins_ids: number[]): Promise<Dialogs.Dialog> {\n    const ajaxParams = {\n      type: ProxyMethod.PUT,\n      url: Utils.getUrl(this.route, id, 'admins'),\n      data: { push_all: { admins_ids } },\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async removeAdmins(id: string, admins_ids: number[]): Promise<Dialogs.Dialog> {\n    const ajaxParams = {\n      type: ProxyMethod.PUT,\n      url: Utils.getUrl(this.route, id, 'admins'),\n      data: { pull_all: { admins_ids } },\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async subscribe(id: string): Promise<Dialogs.Dialog> {\n    const ajaxParams = {\n      type: ProxyMethod.POST,\n      url: Utils.getUrl(this.route, id, 'subscribe'),\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public subscribeToPublic = this.subscribe;\n\n  public async unsubscribe(id: string): Promise<EmptyResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.DELETE,\n      url: Utils.getUrl(this.route, id, 'subscribe'),\n      dataType: ProxyType.TEXT,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public unsubscribeFromPublic = this.unsubscribe;\n\n  public async updateNotificationsSettings(\n    id: string,\n    enabled: number | boolean\n  ): Promise<Dialogs.UpdateNotificationsSettingsResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.PUT,\n      url: Utils.getUrl(this.route, id, 'notifications'),\n      data: { enabled: enabled ? 1 : 0 },\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async getNotificationsSettings(id: string): Promise<Dialogs.GetNotificationsSettingsResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.GET,\n      url: Utils.getUrl(this.route, id, 'notifications'),\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async getPublicOccupants(\n    id: string,\n    params: Dialogs.GetPublicOccupantsParams = {}\n  ): Promise<Dialogs.GetPublicOccupantsResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.GET,\n      url: Utils.getUrl(this.route, id, 'occupants'),\n      data: params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async clearHistory(id: string): Promise<EmptyResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.DELETE,\n      url: Utils.getUrl(this.route, 'clearHistory', id),\n      dataType: ProxyType.TEXT,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n}\n","import type { EmptyResponse, ForceParams, Messages } from '../../types';\nimport { ProxyMethod, ProxyType } from '../../types/constants';\nimport ProxyService from '../../Proxy';\nimport Utils from '../../Utils';\nimport config from '../../config';\n\nexport default class MessagesService {\n  public proxy: ProxyService;\n  readonly route = `${config.urls.chat}/Message`;\n\n  constructor(proxy: ProxyService) {\n    this.proxy = proxy;\n  }\n\n  public async list(params: Messages.ListParams = {}): Promise<Messages.ListResponse> {\n    const ajaxParams = {\n      url: Utils.getUrl(this.route),\n      data: params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async create(params: Messages.CreateParams = {}): Promise<Messages.Message> {\n    const ajaxParams = {\n      url: Utils.getUrl(this.route),\n      type: ProxyMethod.POST,\n      data: params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async update(id: string | string[], params: Messages.UpdateParams = {}): Promise<EmptyResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.PUT,\n      dataType: ProxyType.TEXT,\n      url: Utils.getUrl(this.route, Array.isArray(id) ? id.join(',') : id),\n      data: params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async delete(ids: string | string[], params?: ForceParams): Promise<Messages.DeleteResponse> {\n    const res = Utils.isArray(ids) ? ids.join(',') : ids;\n    const ajaxParams = {\n      url: Utils.getUrl(this.route, res),\n      type: ProxyMethod.DELETE,\n      dataType: ProxyType.TEXT,\n      data: params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async createSystem(params: Messages.CreateSystemParams): Promise<Messages.CreateSystemResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.POST,\n      url: Utils.getUrl(this.route, 'system'),\n      data: params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async unreadCount(params: Messages.UnreadCountParams = {}): Promise<Messages.UnreadCountResponse> {\n    const data = Utils.cloneObject(params);\n\n    if (data && data.chat_dialog_ids && Utils.isArray(data.chat_dialog_ids)) {\n      data.chat_dialog_ids = data.chat_dialog_ids.join(', ');\n    }\n\n    const ajaxParams = {\n      url: Utils.getUrl(this.route, 'unread'),\n      data: data,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async listReactions(id: string = '_'): Promise<Messages.ListReactionsResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.GET,\n      dataType: ProxyType.JSON,\n      url: Utils.getUrl(this.route, id, 'reactions'),\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async addReaction(id: string, reaction: string): Promise<EmptyResponse> {\n    return this.updateReaction(id, reaction);\n  }\n\n  public async removeReaction(id: string, reaction: string): Promise<EmptyResponse> {\n    return this.updateReaction(id, undefined, reaction);\n  }\n\n  public async updateReaction(id: string, add?: string, remove?: string): Promise<EmptyResponse> {\n    return this.putReaction(id, { add, remove });\n  }\n\n  private async putReaction(id: string, params: Messages.PutReactionParams): Promise<EmptyResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.PUT,\n      dataType: ProxyType.TEXT,\n      url: Utils.getUrl(this.route, id, 'reactions'),\n      data: params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n}\n","import type WebRTCClient from './WebRTCClient';\nimport type { Calls } from '../types';\nimport { CallSignalingType } from '../types/constants';\n\nexport default class WebRTCSignalingProcessor {\n  public delegate: WebRTCClient;\n\n  constructor(delegate: WebRTCClient) {\n    this.delegate = delegate;\n  }\n\n  public onMessage = (userID: number, extension: Calls.ExtensionParams): void => {\n    const sessionId = extension?.sessionID ?? '';\n    const signalType = extension?.signalType;\n    /** cleanup */\n    delete extension?.moduleIdentifier;\n    delete extension?.sessionID;\n    delete extension?.signalType;\n\n    switch (signalType) {\n      case CallSignalingType.CALL:\n        this.delegate.onCallHandler(userID, sessionId, extension);\n        break;\n      case CallSignalingType.ACCEPT:\n        this.delegate.onAcceptHandler(userID, sessionId, extension);\n        break;\n      case CallSignalingType.REJECT:\n        this.delegate.onRejectHandler(userID, sessionId, extension);\n        break;\n      case CallSignalingType.STOP:\n        this.delegate.onStopHandler(userID, sessionId, extension);\n        break;\n      case CallSignalingType.CANDIDATE:\n        this.delegate.onIceCandidatesHandler(userID, sessionId, extension);\n        break;\n      case CallSignalingType.RESTART:\n        this.delegate.onIceRestartHandler(userID, sessionId, extension);\n        break;\n      case CallSignalingType.RESTART_ACCEPT:\n        this.delegate.onIceRestartAcceptHandler(userID, sessionId, extension);\n        break;\n    }\n  };\n}\n","import config from '../config';\nimport Utils from '../Utils';\nimport ProxyService from '../Proxy';\nimport DialogsService from './xmpp/Dialogs';\nimport MessagesService from './xmpp/Messages';\nimport WebRTCSignalingProcessor from '../videocalling/WebRTCSignalingProcessor';\nimport type { Chat } from '../types';\nimport { ChatEvent, ProxyMethod } from '../types/constants';\n\nexport default abstract class AbstractChatService {\n  public proxy: ProxyService;\n  public dialog: DialogsService;\n  public message: MessagesService;\n  declare webrtcSignalingProcessor: WebRTCSignalingProcessor;\n\n  public isConnected: boolean = false;\n  protected isConnecting: boolean = false;\n  protected isLogout: boolean = false;\n  protected isReconnect: boolean = false;\n\n  declare onChatStatusListener: Chat.OnChatStatusListener;\n  declare onConnectionErrorListener: Chat.OnChatConnectionErrorListener;\n  declare onDisconnectedListener: Chat.OnChatDisconnectedListener;\n  declare onReconnectListener: Chat.OnChatReconnectedListener;\n  declare onMessageListener: Chat.OnMessageListener;\n  declare onSystemMessageListener: Chat.OnMessageSystemListener;\n  declare onMessageTypingListener: Chat.OnMessageTypingListener;\n  declare onMessageUpdateListener: Chat.OnMessageUpdateListener;\n  declare onMessageDeleteListener: Chat.OnMessageDeleteListener;\n  declare onMessageReactionsListener: Chat.OnMessageReactionsListener;\n  declare onReadStatusListener: Chat.OnMessageReadListener;\n  declare onLastUserActivityListener: Chat.OnLastUserActivityListener;\n  declare onMessageErrorListener: Chat.OnMessageErrorListener;\n  declare onDeliveredStatusListener: Chat.OnMessageDeliveredListener;\n  declare onSentMessageCallback: Chat.OnMessageSentListener;\n  declare onJoinOccupant: Chat.OnDialogJoinListener;\n  declare onLeaveOccupant: Chat.OnDialogLeaveListener;\n  declare onKickOccupant: Chat.OnDialogKickListener;\n\n  constructor(proxy: ProxyService) {\n    this.proxy = proxy;\n    this.dialog = new DialogsService(proxy);\n    this.message = new MessagesService(proxy);\n  }\n\n  public async search(params: Chat.SearchParams): Promise<Chat.SearchResult> {\n    const query = Object.assign({}, params);\n\n    if (query.start_date) {\n      query.start_date = new Date(query.start_date).toISOString();\n    }\n    if (query.end_date) {\n      query.end_date = new Date(query.end_date).toISOString();\n    }\n    if (Utils.isArray(query.chat_dialog_ids)) {\n      query.chat_dialog_ids = (query.chat_dialog_ids as string[]).join(',');\n    }\n\n    const ajaxParams = {\n      type: ProxyMethod.GET,\n      url: Utils.getUrl(`${config.urls.chat}/search`),\n      data: query,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public abstract ping(): Promise<void>;\n\n  public async pingWithTimeout(timeout: number = 5000): Promise<unknown> {\n    return new Promise(async (resolve, reject) => {\n      const error = `Failed to ping chat server ${config.chatProtocol.websocket}. Timed out after ${timeout}ms`;\n      const timer = setTimeout(() => {\n        Utils.safeCallbackCall(this.onConnectionErrorListener)(error);\n        reject(error);\n      }, timeout);\n\n      try {\n        const result = await this.ping();\n        clearTimeout(timer);\n        resolve(result);\n      } catch {\n        clearTimeout(timer);\n        reject(error);\n      }\n    });\n  }\n\n  protected getListenerByName(name: ChatEvent): Chat.ListenerName | null {\n    switch (name) {\n      case ChatEvent.STATUS:\n        return 'onChatStatusListener';\n      case ChatEvent.ERROR:\n        return 'onConnectionErrorListener';\n      case ChatEvent.DISCONNECTED:\n        return 'onDisconnectedListener';\n      case ChatEvent.RECONNECTED:\n        return 'onReconnectListener';\n      case ChatEvent.MESSAGE:\n        return 'onMessageListener';\n      case ChatEvent.SYSTEM_MESSAGE:\n        return 'onSystemMessageListener';\n      case ChatEvent.ERROR_MESSAGE:\n        return 'onMessageErrorListener';\n      case ChatEvent.TYPING_MESSAGE:\n        return 'onMessageTypingListener';\n      case ChatEvent.UPDATE_MESSAGE:\n        return 'onMessageUpdateListener';\n      case ChatEvent.DELETE_MESSAGE:\n        return 'onMessageDeleteListener';\n      case ChatEvent.REACTIONS_MESSAGE:\n        return 'onMessageReactionsListener';\n      case ChatEvent.DELIVERED_MESSAGE:\n        return 'onDeliveredStatusListener';\n      case ChatEvent.READ_MESSAGE:\n        return 'onReadStatusListener';\n      case ChatEvent.SENT_MESSAGE:\n        return 'onSentMessageCallback';\n      case ChatEvent.USER_LAST_ACTIVITY:\n        return 'onLastUserActivityListener';\n      case ChatEvent.JOIN:\n        return 'onJoinOccupant';\n      case ChatEvent.LEAVE:\n        return 'onLeaveOccupant';\n      case ChatEvent.KICK:\n        return 'onKickOccupant';\n      default:\n        return null;\n    }\n  }\n\n  public addListener(name: ChatEvent, listener: Chat.Listeners): () => void {\n    const listenerName = this.getListenerByName(name);\n    if (listenerName) {\n      (this[listenerName] as Chat.Listeners) = listener;\n    }\n    return this.removeListener.bind(this, name);\n  }\n\n  public removeListener(name: ChatEvent): void {\n    const listenerName = this.getListenerByName(name);\n    if (listenerName) {\n      (this[listenerName] as Chat.Listeners | undefined) = undefined;\n    }\n  }\n\n  public removeAllListeners(): void {\n    Object.keys(this).forEach((key: string) => {\n      if (key.startsWith('on') && key.endsWith('Listener') && typeof this[key as Chat.ListenerName] === 'function') {\n        (this[key as Chat.ListenerName] as Chat.Listeners | undefined) = undefined;\n      }\n    });\n  }\n}\n","import type { XMPPClient } from '@xmppClient';\nimport type { Calls, Chat, PlainObject, StringObject } from '../../types';\nimport type { XMPPChatRealTimeService } from '../../types/chat';\nimport { ChatEvent, CallType, CallSignalingModuleIdentifier } from '../../types/constants';\nimport { xmppClient } from '@xmppClient';\nimport config from '../../config';\nimport Utils from '../../Utils';\nimport ProxyService from '../../Proxy';\nimport ChatHelpers from './Helpers';\nimport ChatUtils from './ChatUtils';\nimport StreamManagement from './StreamManagement';\nimport PrivacyList from './PrivacyList';\nimport MultiUserChat from './MultiUserChat';\nimport AbstractChatService from '../AbstractChatService';\n\nexport default class XMPPChatService extends AbstractChatService implements XMPPChatRealTimeService {\n  declare onMessageErrorListener: Chat.OnMessageErrorListener;\n  declare onSentMessageCallback: Chat.OnMessageSentListener;\n  declare onDeliveredStatusListener: Chat.OnMessageDeliveredListener;\n  declare onJoinOccupant: Chat.OnDialogJoinListener;\n  declare onLeaveOccupant: Chat.OnDialogLeaveListener;\n  declare onKickOccupant: Chat.OnDialogKickListener;\n\n  public xmppClient: XMPPClient;\n  public helpers: ChatHelpers;\n  public privacylist: PrivacyList;\n  public muc: MultiUserChat;\n  public streamManagement: StreamManagement;\n\n  public stanzasCallbacks: Chat.StanzasCallbacks = {};\n  private xmppClientListeners: Chat.XMPPClientListeners = new Map<Chat.XMPPClientEvent, Chat.XMPPClientListener>();\n  private connectPromise: Promise<boolean> | null = null;\n  private earlyIncomingMessagesQueue: Chat.XmlElement[] = [];\n\n  constructor(proxy: ProxyService) {\n    super(proxy);\n    this.helpers = new ChatHelpers();\n\n    this.xmppClient = xmppClient({\n      service: config.chatProtocol.websocket,\n      credentials: (auth, mechanism) =>\n        auth(\n          {\n            username: this.xmppClient?.options?.username,\n            password: this.xmppClient?.options?.password,\n          },\n          mechanism\n        ),\n    });\n\n    if (config.chat.reconnect?.enable) {\n      this.xmppClient.reconnect.delay = config.chat.reconnect.timeInterval * 1000;\n    }\n\n    const options = {\n      xmppClient: this.xmppClient,\n      helpers: this.helpers,\n      stanzasCallbacks: this.stanzasCallbacks,\n    };\n\n    this.muc = new MultiUserChat(options);\n    this.privacylist = new PrivacyList(options);\n    this.streamManagement = new StreamManagement(this);\n  }\n\n  public get connectionStatus() {\n    return this.xmppClient.status;\n  }\n\n  public get currentUserId(): Chat.UserId {\n    const userJID = this.xmppClient.jid?.toString() ?? '';\n    const userID = this.helpers.getUserIdFromJID(userJID) ?? 0;\n    return userID;\n  }\n\n  public async connect(params: Chat.ConnectionParams): Promise<boolean> {\n    this.connectPromise = new Promise((resolve, reject) => {\n      Utils.DLog('[Chat]', 'Connect with parameter:', params);\n\n      if (this.isConnecting) {\n        Utils.DLog('[Chat]', 'Warning! Already in CONNECTING state');\n        resolve(false);\n        return;\n      }\n\n      if (this.isConnected) {\n        Utils.DLog('[Chat]', 'Warning! Chat is already connected!');\n        resolve(false);\n        return;\n      }\n\n      this.isConnecting = true;\n      this.isLogout = false;\n\n      this.removeAllXMPPClientListeners();\n\n      this.addXMPPClientListener('connect', () => {\n        Utils.DLog('[Chat]', this.isReconnect ? 'RECONNECTING' : 'CONNECTING');\n      });\n\n      this.addXMPPClientListener('online', () => {\n        Utils.DLog('[Chat]', 'ONLINE');\n        this.postConnectActions();\n        resolve(true);\n        this.connectPromise = null;\n      });\n\n      this.addXMPPClientListener('offline', () => {\n        Utils.DLog('[Chat]', 'OFFLINE');\n      });\n\n      this.addXMPPClientListener('disconnect', () => {\n        Utils.DLog('[Chat]', 'DISCONNECTED');\n\n        Utils.safeCallbackCall(this.onDisconnectedListener)();\n\n        if (config.chat.reconnect?.enable) {\n          this.isConnected = false;\n          this.isConnecting = false;\n        } else {\n          this.disconnect();\n        }\n      });\n\n      this.addXMPPClientListener('status', (status: Chat.ConnectionStatus, value: unknown) => {\n        Utils.DLog('[Chat]', `status - ${String(status)}`, typeof value === 'object' ? JSON.stringify(value) : '');\n        Utils.safeCallbackCall(this.onChatStatusListener)(status);\n      });\n\n      this.addXMPPClientListener('stanza', (stanza: Chat.XmlElement) => {\n        // it can be a case,\n        // when message came after xmpp auth but before resource binding,\n        // and it can cause some crashes, e.g.\n        // https://github.com/ConnectyCube/connectycube-js-sdk-releases/issues/28\n        if (stanza.is('message') && !this.isConnected) {\n          this.earlyIncomingMessagesQueue.push(stanza);\n          Utils.DLog('[Chat]', \"on 'stanza': enqueue incoming stanza (isConnected=false)\");\n          return;\n        }\n\n        // after 'input' and 'element' (only if stanza, not nonza)\n        if (stanza.is('presence')) {\n          this.onPresence(stanza);\n        } else if (stanza.is('iq')) {\n          this.onIQ(stanza);\n        } else if (stanza.is('message')) {\n          if (stanza.attrs.type === 'headline') {\n            this.onSystemMessage(stanza);\n          } else if (stanza.attrs.type === 'error') {\n            this.onMessageError(stanza);\n          } else {\n            this.onMessage(stanza);\n          }\n        }\n      });\n\n      this.addXMPPClientListener('error', (error: unknown) => {\n        Utils.DLog('[Chat]', 'ERROR:', error, {\n          isReconnect: this.isReconnect,\n          connectPromise: !!this.connectPromise,\n        });\n\n        if (this.connectPromise) {\n          if (!this.isReconnect) {\n            const err = error as { name?: string; condition?: unknown };\n            reject(err.name === 'SASLError' ? err.condition : error);\n            this.connectPromise = null;\n          }\n        } else {\n          Utils.safeCallbackCall(this.onConnectionErrorListener)(error);\n        }\n      });\n\n      this.addXMPPClientListener('output', (str) => {\n        Utils.callTrafficUsageCallback('xmppDataWrite', { body: str });\n        Utils.DLog('[Chat]', 'SENT:', str);\n      });\n\n      this.addXMPPClientListener('input', (str) => {\n        Utils.callTrafficUsageCallback('xmppDataRead', { body: str });\n        Utils.DLog('[Chat]', 'RECV:', str);\n      });\n\n      // save user connection data so they will be used when authenticate (above)\n      this.xmppClient.options.username = ChatUtils.buildUserJidLocalPart(params.userId);\n      this.xmppClient.options.password = params.password;\n      // start connect\n      this.xmppClient.start().catch((error) => {\n        console.error('[Chat] xmppClient.start error', error);\n        if (this.connectPromise) {\n          reject(error);\n          this.connectPromise = null;\n        } else {\n          Utils.safeCallbackCall(this.onConnectionErrorListener)(error);\n        }\n      });\n    });\n\n    return this.connectPromise;\n  }\n\n  public async ping(): Promise<void> {\n    return new Promise((resolve, reject) => {\n      const id = ChatUtils.getUniqueId('ping');\n      const iqStanza = ChatUtils.createIqStanza({ id, type: 'get', to: config.endpoints.chat });\n\n      iqStanza.c('ping', { xmlns: 'urn:xmpp:ping' });\n\n      this.stanzasCallbacks[id] = (stanza: Chat.XmlElement) => {\n        const error = ChatUtils.getElement(stanza, 'error');\n        if (error) {\n          reject(ChatUtils.buildErrorFromXMPPErrorStanza(error));\n        } else {\n          resolve();\n        }\n      };\n\n      this.xmppClient.sendOnline(iqStanza);\n    });\n  }\n\n  public send(dialogId: Chat.DialogId | Chat.UserId, message: Chat.MessageParams = {}): string {\n    const messageId = message.id ?? Utils.getBsonObjectId();\n    const messageStanza = ChatUtils.createMessageStanza({\n      from: this.helpers.userCurrentJid,\n      to: this.helpers.jidOrUserId(dialogId),\n      type: message.type ?? this.helpers.typeChat(dialogId),\n      id: messageId,\n    });\n\n    if (!message.id) {\n      message.id = messageId;\n    }\n\n    if (message.body) {\n      messageStanza.c('body').t(message.body).up();\n    }\n\n    if (message.extension) {\n      messageStanza.c('extraParams', { xmlns: 'jabber:client' });\n      ChatUtils.assignExtraParamsToXml(messageStanza, message.extension);\n    }\n\n    if (this.streamManagement.supported) {\n      this.streamManagement.sendAndCount(messageStanza, message);\n    } else {\n      this.xmppClient.sendOnline(messageStanza);\n    }\n\n    return messageId;\n  }\n\n  public sendSystemMessage(\n    userId: Chat.UserId | Chat.UserId[] | Chat.DialogId,\n    message: Chat.SystemMessageParams\n  ): string {\n    const messageId = message.id ?? Utils.getBsonObjectId();\n    const recipients = Array.isArray(userId) ? userId : [userId];\n\n    for (const recipient of recipients) {\n      const messageStanza = ChatUtils.createMessageStanza({\n        type: 'headline',\n        id: messageId,\n        to: this.helpers.jidOrUserId(recipient as Chat.UserId),\n      });\n\n      if (message.body) {\n        messageStanza.c('body').t(message.body).up();\n      }\n\n      if (message.extension) {\n        messageStanza.c('extraParams', { xmlns: 'jabber:client' }).c('moduleIdentifier').t('SystemNotifications').up();\n        ChatUtils.assignExtraParamsToXml(messageStanza, message.extension);\n      }\n\n      this.xmppClient.sendOnline(messageStanza);\n    }\n\n    return messageId;\n  }\n\n  public sendWebRTCSignalingMessage(\n    userId: Chat.UserId,\n    message: Chat.SystemMessageParams<Calls.ExtensionParams>\n  ): string {\n    const messageId = message.id ?? Utils.getBsonObjectId();\n\n    let messageStanza = ChatUtils.createMessageStanza({\n      to: this.helpers.jidOrUserId(userId),\n      type: 'headline',\n      id: messageId,\n    }).c('extraParams', { xmlns: 'jabber:client' });\n\n    const extension = message.extension ?? {};\n    Object.keys(extension).forEach((name) => {\n      const item = extension[name];\n\n      if (name === 'iceCandidates' && Utils.isArray(item)) {\n        messageStanza = messageStanza.c('iceCandidates');\n        ((item as RTCIceCandidateInit[]) || []).forEach((candidate) => {\n          messageStanza = messageStanza.c('iceCandidate');\n          if (Utils.isObject(candidate)) {\n            Object.entries(candidate).forEach(([key, value]) => {\n              messageStanza = messageStanza\n                .c(key)\n                .t(String(value || ''))\n                .up();\n            });\n          }\n          messageStanza = messageStanza.up();\n        });\n        messageStanza = messageStanza.up();\n      } else if (name === 'opponentsIDs' && Utils.isArray(item)) {\n        messageStanza = messageStanza.c('opponentsIDs');\n        ((item as number[] | string[]) || []).forEach((opponentId) => {\n          messageStanza = messageStanza\n            .c('opponentID')\n            .t(String(opponentId ?? ''))\n            .up();\n        });\n        messageStanza = messageStanza.up();\n      } else if (typeof item === 'object' && item !== null) {\n        ChatUtils.assignObjectToXml(messageStanza, item as PlainObject, name);\n      } else {\n        messageStanza = messageStanza\n          .c(name)\n          .t(String(item ?? ''))\n          .up();\n      }\n    });\n\n    messageStanza = messageStanza.up();\n\n    this.xmppClient.sendOnline(messageStanza);\n\n    return messageId;\n  }\n\n  public sendIsTypingStatus(dialogId: Chat.DialogId | Chat.UserId): void {\n    const messageStanza = ChatUtils.createMessageStanza({\n      from: this.helpers.userCurrentJid,\n      to: this.helpers.jidOrUserId(dialogId),\n      type: this.helpers.typeChat(dialogId),\n    });\n\n    messageStanza.c('composing', { xmlns: 'http://jabber.org/protocol/chatstates' });\n\n    this.xmppClient.sendOnline(messageStanza);\n  }\n\n  public sendIsStopTypingStatus(dialogId: Chat.DialogId | Chat.UserId): void {\n    const messageStanza = ChatUtils.createMessageStanza({\n      from: this.helpers.userCurrentJid,\n      to: this.helpers.jidOrUserId(dialogId),\n      type: this.helpers.typeChat(dialogId),\n    });\n\n    messageStanza.c('paused', { xmlns: 'http://jabber.org/protocol/chatstates' });\n\n    this.xmppClient.sendOnline(messageStanza);\n  }\n\n  public sendDeliveredStatus(params: Chat.MessageStatusParams): void {\n    const messageStanza = ChatUtils.createMessageStanza({\n      type: 'chat',\n      from: this.helpers.userCurrentJid,\n      id: Utils.getBsonObjectId(),\n      to: this.helpers.jidOrUserId(params.userId!),\n    });\n\n    messageStanza.c('received', { xmlns: 'urn:xmpp:chat-markers:0', id: params.messageId }).up();\n    messageStanza.c('extraParams', { xmlns: 'jabber:client' }).c('dialog_id').t(params.dialogId);\n\n    this.xmppClient.sendOnline(messageStanza);\n  }\n\n  public sendReadStatus(params: Chat.MessageStatusParams): void {\n    const messageStanza = ChatUtils.createMessageStanza({\n      type: 'chat',\n      from: this.helpers.userCurrentJid,\n      to: this.helpers.jidOrUserId(params.userId!),\n      id: Utils.getBsonObjectId(),\n    });\n\n    messageStanza.c('displayed', { xmlns: 'urn:xmpp:chat-markers:0', id: params.messageId }).up();\n    messageStanza.c('extraParams', { xmlns: 'jabber:client' }).c('dialog_id').t(params.dialogId);\n\n    this.xmppClient.sendOnline(messageStanza);\n  }\n\n  public editMessage(params: Chat.EditMessageParams): void {\n    const messageStanza = ChatUtils.createMessageStanza({\n      from: this.helpers.userCurrentJid,\n      to: this.helpers.jidOrUserId(params.to ?? params.dialogId),\n      type: this.helpers.typeChat(params.to ?? params.dialogId),\n      id: Utils.getBsonObjectId(),\n    });\n\n    messageStanza.c('body').t(params.body).up();\n    messageStanza\n      .c('replace', {\n        xmlns: 'urn:xmpp:message-correct:0',\n        id: params.originMessageId,\n        last: params.last ? 'true' : 'false',\n      })\n      .up();\n    messageStanza.c('extraParams', { xmlns: 'jabber:client' }).c('dialog_id').t(params.dialogId);\n\n    if (params.extension) {\n      ChatUtils.assignExtraParamsToXml(messageStanza, params.extension!);\n    }\n\n    this.xmppClient.sendOnline(messageStanza);\n  }\n\n  public deleteMessage(params: Chat.DeleteMessageParams): void {\n    const messageStanza = ChatUtils.createMessageStanza({\n      from: this.helpers.userCurrentJid,\n      to: this.helpers.jidOrUserId(params.to ?? params.dialogId),\n      type: this.helpers.typeChat(params.to ?? params.dialogId),\n      id: Utils.getBsonObjectId(),\n    });\n\n    messageStanza.c('remove', { xmlns: 'urn:xmpp:message-delete:0', id: params.messageId }).up();\n    messageStanza.c('extraParams', { xmlns: 'jabber:client' }).c('dialog_id').t(params.dialogId);\n\n    this.xmppClient.sendOnline(messageStanza);\n  }\n\n  public getLastUserActivity(userId: Chat.UserId): Promise<Chat.LastActivity> {\n    return new Promise((resolve, reject) => {\n      const id = ChatUtils.getUniqueId('lastActivity');\n      const iqStanza = ChatUtils.createIqStanza({\n        type: 'get',\n        from: this.helpers.userCurrentJid,\n        to: this.helpers.jidOrUserId(userId),\n        id: id,\n      });\n\n      iqStanza.c('query', { xmlns: 'jabber:iq:last' });\n\n      this.stanzasCallbacks[id] = (stanza: Chat.XmlElement) => {\n        if (ChatUtils.getElement(stanza, 'error')) {\n          reject(ChatUtils.buildErrorFromXMPPErrorStanza(stanza));\n        } else {\n          resolve(this.onLastActivityStanza(stanza));\n        }\n      };\n\n      this.xmppClient.sendOnline(iqStanza);\n    });\n  }\n\n  private onLastActivityStanza(stanza: Chat.XmlElement): Chat.LastActivity {\n    const from = ChatUtils.getAttr(stanza, 'from');\n    const userId = this.helpers.getUserIdFromJID(from);\n    const query = ChatUtils.getElement(stanza, 'query');\n    const seconds = query ? parseInt(ChatUtils.getAttr(query, 'seconds')) : 0;\n\n    Utils.safeCallbackCall(this.onLastUserActivityListener)(userId, seconds);\n\n    return { userId, seconds };\n  }\n\n  public markActive(): void {\n    const iqStanza = ChatUtils.createIqStanza({\n      id: this.helpers.getUniqueId('markActive'),\n      type: 'set',\n    });\n\n    iqStanza.c('mobile', {\n      xmlns: 'http://tigase.org/protocol/mobile#v2',\n      enable: 'false',\n    });\n\n    this.xmppClient.sendOnline(iqStanza);\n  }\n\n  public markInactive(): void {\n    const iqStanza = ChatUtils.createIqStanza({\n      id: this.helpers.getUniqueId('markActive'),\n      type: 'set',\n    });\n\n    iqStanza.c('mobile', {\n      xmlns: 'http://tigase.org/protocol/mobile#v2',\n      enable: 'true',\n    });\n\n    this.xmppClient.sendOnline(iqStanza);\n  }\n\n  public async disconnect(): Promise<boolean> {\n    Utils.DLog('[Chat]', 'disconnect');\n\n    if (this.isLogout) {\n      Utils.DLog('[Chat]', 'Warning! Chat is already disconnected!');\n      return true;\n    }\n\n    this.isLogout = true;\n    this.isReconnect = false;\n    this.isConnected = false;\n    this.isConnecting = false;\n    this.muc.joinedRooms = {};\n    this.helpers.userCurrentJid = '';\n    this.streamManagement.stop();\n\n    try {\n      await this.xmppClient.stop();\n      return true;\n    } catch {\n      return false;\n    }\n  }\n\n  public terminate(): void {\n    Utils.DLog('[Chat]', 'terminated');\n\n    this.isConnected = false;\n    this.isConnecting = false;\n    this.streamManagement.stop();\n    this.xmppClient.socket?.end();\n  }\n\n  private onMessage(rawStanza: Chat.XmlElement): void {\n    const forwardedStanza = ChatUtils.getElementTreePath(rawStanza, ['sent', 'forwarded', 'message']);\n    const stanza = forwardedStanza || rawStanza;\n    const from = ChatUtils.getAttr(stanza, 'from');\n    const type = ChatUtils.getAttr(stanza, 'type');\n    const invite = ChatUtils.getElement(stanza, 'invite');\n    const resource = this.xmppClient.jid?.getResource() || '';\n    const isChat = type === 'chat';\n\n    // ignore private message from the same resource or invite messages from MUC\n    if ((isChat && from.includes(resource)) || invite) {\n      return;\n    }\n\n    const messageId = ChatUtils.getAttr(stanza, 'id');\n    const delivered = ChatUtils.getElement(stanza, 'received');\n    const read = ChatUtils.getElement(stanza, 'displayed');\n    const replaceSubElement = ChatUtils.getElement(stanza, 'replace');\n    const reactionsSubElement = ChatUtils.getElement(stanza, 'reactions');\n    const removeSubElement = ChatUtils.getElement(stanza, 'remove');\n    const composing = Boolean(ChatUtils.getElement(stanza, 'composing'));\n    const paused = ChatUtils.getElement(stanza, 'paused');\n    const delay = ChatUtils.getElement(stanza, 'delay');\n    const extraParams = ChatUtils.getElement(stanza, 'extraParams');\n    const body = ChatUtils.getElementText(stanza, 'body');\n    const isForwarded = Boolean(forwardedStanza);\n    const isGroup = type === 'groupchat';\n    const recipient = isChat ? ChatUtils.getAttr(stanza, 'to') : null;\n    const recipientId = recipient ? this.helpers.getUserIdFromJID(recipient) : null;\n    const ext = extraParams ? ChatUtils.parseExtraParams(extraParams) : null;\n    const extension = ext ? ext.extension : null;\n    const dialogId = isGroup ? this.helpers.getDialogIdFromJID(from) : (ext?.dialogId ?? null);\n    const userId = isGroup ? this.helpers.getIdFromResource(from) : this.helpers.getUserIdFromJID(from);\n    const currentUserJid = this.xmppClient.jid?.toString();\n    const currentUserId = currentUserJid ? this.helpers.getUserIdFromJID(currentUserJid) : 0;\n\n    // typing statuses\n    if (composing || paused) {\n      if (isChat || isGroup || !delay) {\n        Utils.safeCallbackCall(this.onMessageTypingListener)(composing, userId, dialogId);\n      }\n\n      return;\n    }\n\n    // edit message\n    if (replaceSubElement) {\n      Utils.safeCallbackCall(this.onMessageUpdateListener)(\n        ChatUtils.getAttr(replaceSubElement, 'id'),\n        ChatUtils.getAttr(replaceSubElement, 'last') === 'true',\n        body,\n        dialogId,\n        userId,\n        extension\n      );\n\n      return;\n    }\n\n    // reactions\n    if (reactionsSubElement) {\n      if (isForwarded && isGroup) {\n        return;\n      }\n\n      const messageId = ChatUtils.getAttr(reactionsSubElement, 'message_id');\n      const userId = parseInt(ChatUtils.getAttr(reactionsSubElement, 'user_id'));\n      const { add, remove } = ChatUtils.parseReactions(reactionsSubElement);\n\n      Utils.safeCallbackCall(this.onMessageReactionsListener)(messageId, userId, dialogId, add, remove);\n\n      return;\n    }\n\n    // delete message\n    if (removeSubElement) {\n      const messageId = ChatUtils.getAttr(removeSubElement, 'id');\n\n      Utils.safeCallbackCall(this.onMessageDeleteListener)(messageId, dialogId, userId);\n\n      return;\n    }\n\n    // delivered / read statuses\n    if (delivered || read) {\n      if (delivered && isChat) {\n        const id = ChatUtils.getAttr(delivered, 'id');\n        Utils.safeCallbackCall(this.onDeliveredStatusListener)(id, dialogId, userId);\n      }\n      if (read && isChat) {\n        const id = ChatUtils.getAttr(read, 'id');\n        Utils.safeCallbackCall(this.onReadStatusListener)(id, dialogId, userId);\n      }\n\n      return;\n    }\n\n    // auto-send 'received' status (ignore messages from yourself)\n    if (dialogId && userId && userId !== currentUserId) {\n      this.sendDeliveredStatus({ messageId, dialogId, userId });\n    }\n\n    const message: Chat.Message = {\n      id: messageId,\n      dialog_id: dialogId,\n      recipient_id: recipientId,\n      is_forwarded: isForwarded,\n      type,\n      body,\n      extension,\n      delay,\n    };\n\n    if (isChat || isGroup) {\n      Utils.safeCallbackCall(this.onMessageListener)(userId, message);\n    }\n  }\n\n  private onPresence(stanza: Chat.XmlElement): void {\n    const from = ChatUtils.getAttr(stanza, 'from');\n    const id = ChatUtils.getAttr(stanza, 'id');\n    const type = ChatUtils.getAttr(stanza, 'type');\n    const currentUserJid = this.xmppClient.jid?.toString();\n    const currentUserId = this.helpers.getUserIdFromJID(currentUserJid);\n    const x = ChatUtils.getElement(stanza, 'x');\n    const xmlns = x ? ChatUtils.getAttr(x, 'xmlns') : null;\n    const status = x ? ChatUtils.getElement(x, 'xmlns') : null;\n    // const statusCode = status ? ChatUtils.getElement(status, 'code') : null;\n    const statusCode = status ? ChatUtils.getElementText(status, 'code') : null;\n\n    // MUC presences\n    if (xmlns && xmlns.startsWith('http://jabber.org/protocol/muc')) {\n      // Error\n      if (type === 'error') {\n        // JOIN to dialog error\n        if (id.endsWith(':join')) {\n          Utils.safeCallbackCall(this.stanzasCallbacks[id])(stanza);\n        }\n        return;\n      }\n\n      const dialogId = this.helpers.getDialogIdFromJID(from);\n      const mucUserId = this.helpers.getUserIdFromRoomJid(from);\n\n      // self presence\n      if (status) {\n        // KICK from dialog event\n        if (statusCode === '301') {\n          const item = ChatUtils.getElement(stanza, 'item');\n          const actorElement = item ? ChatUtils.getElement(item, 'actor') : null;\n          const initiatorUserJid = actorElement ? ChatUtils.getAttr(actorElement, 'jid') : null;\n          const initiatorId = this.helpers.getUserIdFromJID(initiatorUserJid ?? undefined);\n          const roomJid = this.helpers.getRoomJidFromRoomFullJid(from);\n\n          Utils.safeCallbackCall(this.onKickOccupant)(dialogId, initiatorId);\n\n          if (roomJid) {\n            delete this.muc.joinedRooms[roomJid];\n          }\n\n          return;\n        } else {\n          if (type === 'unavailable') {\n            // LEAVE response\n            if (status && statusCode === '110') {\n              Utils.safeCallbackCall(this.stanzasCallbacks['muc:leave'])(null);\n            }\n            return;\n          }\n          // JOIN response\n          if (id.endsWith(':join') && status && statusCode === '110') {\n            this.stanzasCallbacks[id]?.(stanza);\n            return;\n          }\n        }\n        // Occupants JOIN/LEAVE events\n      } else if (mucUserId != currentUserId) {\n        const listenerName = type === 'unavailable' ? 'onLeaveOccupant' : 'onJoinOccupant';\n\n        Utils.safeCallbackCall(this[listenerName])(dialogId, mucUserId);\n\n        return;\n      }\n    }\n  }\n\n  private onIQ(stanza: Chat.XmlElement): void {\n    const stanzaId = ChatUtils.getAttr(stanza, 'id');\n\n    if (this.stanzasCallbacks[stanzaId]) {\n      Utils.safeCallbackCall(this.stanzasCallbacks[stanzaId])(stanza);\n      delete this.stanzasCallbacks[stanzaId];\n    } else {\n      const from = ChatUtils.getAttr(stanza, 'from');\n      const query = ChatUtils.getElement(stanza, 'query');\n      if (from && query) {\n        this.onLastActivityStanza(stanza);\n      }\n    }\n  }\n\n  private onSystemMessage(rawStanza: Chat.XmlElement): void {\n    const forwardedStanza = ChatUtils.getElementTreePath(rawStanza, ['sent', 'forwarded', 'message']);\n    const stanza = forwardedStanza || rawStanza;\n    const from = ChatUtils.getAttr(stanza, 'from');\n    const messageId = ChatUtils.getAttr(stanza, 'id');\n    const extraParams = ChatUtils.getElement(stanza, 'extraParams');\n    const userId = this.helpers.getUserIdFromJID(from);\n    const delay = ChatUtils.getElement(stanza, 'delay');\n    const moduleIdentifier = extraParams ? ChatUtils.getElementText(extraParams, 'moduleIdentifier') : null;\n    const body = ChatUtils.getElementText(stanza, 'body');\n    const ext = extraParams ? ChatUtils.parseExtraParams(extraParams) : null;\n    const extension = ext ? ext.extension : null;\n\n    switch (moduleIdentifier) {\n      case 'SystemNotifications':\n        Utils.safeCallbackCall(this.onSystemMessageListener)({ id: messageId, userId, body, extension });\n        break;\n      case CallSignalingModuleIdentifier:\n        if (!delay && userId && extraParams) {\n          this.onWebRTCSignalingMessage(userId, extraParams);\n        }\n\n        if (this.webrtcSignalingProcessor && !delay) {\n          Utils.safeCallbackCall(this.webrtcSignalingProcessor.onMessage)(userId, extraParams);\n        }\n        break;\n      default:\n        break;\n    }\n  }\n\n  private onWebRTCSignalingMessage(userId: Chat.UserId, extensionElem: Chat.XmlElement): void {\n    if (!this.webrtcSignalingProcessor) {\n      return;\n    }\n\n    const extraParams = this.getCallExtension(extensionElem);\n\n    Utils.safeCallbackCall(this.webrtcSignalingProcessor.onMessage)(userId, extraParams);\n  }\n\n  private getCallExtension(extraParams?: Chat.XmlElement): Calls.ExtensionParams {\n    if (!extraParams) {\n      return {};\n    }\n\n    const extension: Calls.ExtensionParams = { iceCandidates: [], opponentsIDs: [] };\n    const elements = ChatUtils.getChildElements(extraParams);\n\n    elements.forEach((element: Chat.XmlElement) => {\n      const items = ChatUtils.getChildElements(element);\n      const key = ChatUtils.getName(element) ?? '';\n\n      switch (key) {\n        case 'callerID':\n          extension[key] = parseInt(ChatUtils.getText(element) || '0');\n          break;\n\n        case 'callType':\n          const type = ChatUtils.getText(element);\n          extension[key] = type === '1' ? CallType.VIDEO : type === '2' ? CallType.AUDIO : undefined;\n          break;\n\n        case 'iceCandidates':\n          items.forEach((item) => {\n            const candidate: StringObject = {};\n            ChatUtils.getChildElements(item).forEach((child) => {\n              const childName = ChatUtils.getName(child) || '';\n              const childText = ChatUtils.getText(child);\n              candidate[childName] =\n                childName === 'sdpMLineIndex' ? String(parseInt(childText || '0', 10)) : (childText ?? '');\n            });\n            extension.iceCandidates?.push(candidate);\n          });\n          break;\n\n        case 'opponentsIDs':\n          items.forEach((item) => {\n            extension.opponentsIDs?.push(parseInt(ChatUtils.getText(item) || '0'));\n          });\n          break;\n\n        default:\n          if (items.length > 1) {\n            if ((ChatUtils.getText(element) || '').length > 4096) {\n              extension[key] = items.reduce((acc, item) => acc + ChatUtils.getText(item), '');\n            } else {\n              ChatUtils.assignXmlToObject(element, extension);\n            }\n          } else {\n            if (key === 'userInfo') {\n              ChatUtils.assignXmlToObject(element, extension);\n            } else {\n              extension[key] = ChatUtils.getText(element);\n            }\n          }\n          break;\n      }\n    });\n\n    if (extension.iceCandidates?.length === 0) {\n      delete extension.iceCandidates;\n    }\n\n    if (extension.opponentsIDs?.length === 0) {\n      delete extension.opponentsIDs;\n    }\n\n    return extension;\n  }\n\n  private onMessageError(stanza: Chat.XmlElement): void {\n    // <error code=\"503\" type=\"cancel\">\n    //   <service-unavailable xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/>\n    //   <text xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\" xml:lang=\"en\">Service not available.</text>\n    // </error>\n    const messageId = ChatUtils.getAttr(stanza, 'id');\n    const error = ChatUtils.buildErrorFromXMPPErrorStanza(stanza);\n\n    Utils.safeCallbackCall(this.onMessageErrorListener)(messageId, error);\n  }\n\n  private postConnectActions(): void {\n    Utils.DLog('[Chat]', this.isReconnect ? 'RECONNECTED' : 'CONNECTED');\n\n    const presence = ChatUtils.createPresenceStanza();\n\n    this.streamManagement.start();\n    this.helpers.userCurrentJid = this.xmppClient.jid?.toString() ?? null;\n    this.isConnected = true;\n    this.isConnecting = false;\n    this.enableCarbons();\n    this.xmppClient.sendOnline(presence); // initial presence\n\n    if (this.isReconnect) {\n      // reconnect\n      Utils.safeCallbackCall(this.onReconnectListener)();\n    } else {\n      this.isReconnect = true;\n    }\n\n    if (this.earlyIncomingMessagesQueue.length > 0) {\n      Utils.DLog('[Chat]', `Flush 'earlyIncomingMessagesQueue' (length=${this.earlyIncomingMessagesQueue.length})`);\n\n      const stanzasCallback = this.xmppClientListeners.get('stanza');\n\n      this.earlyIncomingMessagesQueue.forEach((stanza) => {\n        stanzasCallback?.(stanza);\n      });\n      this.earlyIncomingMessagesQueue = [];\n    }\n  }\n\n  private enableCarbons(): void {\n    const iqStanza = ChatUtils.createIqStanza({\n      type: 'set',\n      from: this.helpers.userCurrentJid,\n      id: ChatUtils.getUniqueId('enableCarbons'),\n    });\n\n    iqStanza.c('enable', { xmlns: 'urn:xmpp:carbons:2' });\n\n    this.xmppClient.sendOnline(iqStanza);\n  }\n\n  private setSubscriptionToUserLastActivity(userId: Chat.UserId, enable: boolean): void {\n    const iqStanza = ChatUtils.createIqStanza({\n      id: this.helpers.getUniqueId('statusStreaming'),\n      type: 'set',\n    });\n\n    iqStanza.c('subscribe', {\n      xmlns: 'https://connectycube.com/protocol/status_streaming',\n      user_jid: this.helpers.jidOrUserId(userId),\n      enable,\n    });\n\n    this.xmppClient.sendOnline(iqStanza);\n  }\n\n  subscribeToUserLastActivityStatus(userId: Chat.UserId) {\n    this.setSubscriptionToUserLastActivity(userId, true);\n  }\n\n  unsubscribeFromUserLastActivityStatus(userId?: Chat.UserId) {\n    if (userId !== undefined) this.setSubscriptionToUserLastActivity(userId, false);\n  }\n\n  protected override getListenerByName(name: ChatEvent): Chat.ListenerName | null {\n    switch (name) {\n      case ChatEvent.ERROR_MESSAGE:\n        return 'onMessageErrorListener';\n      case ChatEvent.DELIVERED_MESSAGE:\n        return 'onDeliveredStatusListener';\n      case ChatEvent.SENT_MESSAGE:\n        return 'onSentMessageCallback';\n      case ChatEvent.JOIN:\n        return 'onJoinOccupant';\n      case ChatEvent.LEAVE:\n        return 'onLeaveOccupant';\n      case ChatEvent.KICK:\n        return 'onKickOccupant';\n      default:\n        return super.getListenerByName(name);\n    }\n  }\n\n  private addXMPPClientListener(name: Chat.XMPPClientEvent, listener: Chat.XMPPClientListener): void {\n    switch (name) {\n      case 'output':\n        this.xmppClient.middleware.filter(async (context, next) => {\n          listener(context.stanza?.toString());\n          await next();\n        });\n        break;\n\n      case 'input':\n        const _listener = (stanza: Chat.XmlElement) => {\n          listener(stanza.toString());\n        };\n        this.xmppClient.on('element', _listener);\n        this.xmppClientListeners.set(name, _listener);\n        break;\n\n      default:\n        this.xmppClient.on(name, listener);\n        this.xmppClientListeners.set(name, listener);\n        break;\n    }\n  }\n\n  private removeXMPPClientListener(name: Chat.XMPPClientEvent): void {\n    const listener = this.xmppClientListeners.get(name);\n    if (listener) {\n      this.xmppClient.removeListener(name, listener);\n    }\n    this.xmppClientListeners.delete(name);\n  }\n\n  private removeAllXMPPClientListeners(): void {\n    this.xmppClientListeners.forEach((_, name) => this.removeXMPPClientListener(name));\n  }\n}\n","var C = Object.defineProperty;\nvar D = (d, e, s) => e in d ? C(d, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : d[e] = s;\nvar o = (d, e, s) => D(d, typeof e != \"symbol\" ? e + \"\" : e, s);\nimport U from \"ws\";\nfunction E(d) {\n  const e = \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (s) => {\n    const n = Math.random() * 16 | 0;\n    return (s === \"x\" ? n : n & 3 | 8).toString(16);\n  });\n  return d !== void 0 ? `${e}:${d}` : e;\n}\nconst A = globalThis.WebSocket ?? U;\nclass O {\n  constructor(e) {\n    o(this, \"socket\");\n    o(this, \"config\");\n    o(this, \"currentUserId\");\n    o(this, \"responsesPromises\", {});\n    o(this, \"deviceId\");\n    o(this, \"onMessageListener\");\n    o(this, \"onMessageStatusListener\");\n    o(this, \"onMessageEditListener\");\n    o(this, \"onMessageDeleteListener\");\n    o(this, \"onMessageReactionsListener\");\n    o(this, \"onUserActivityListener\");\n    o(this, \"onUserTypingListener\");\n    o(this, \"onConversationCreateListener\");\n    o(this, \"onConversationUpdateListener\");\n    o(this, \"onConversationDeleteListener\");\n    o(this, \"onConnectEvent\");\n    o(this, \"onMessageEvent\");\n    o(this, \"onSystemMessageEvent\");\n    o(this, \"onDisconnectEvent\");\n    this.config = e;\n  }\n  async connect(e, s) {\n    return e && (this.config.endpoint.ws = e), s && (this.config.endpoint.http = s), new Promise((n, i) => {\n      this.socket = new A(this.config.endpoint.ws), this.socket.onopen = () => {\n        var r;\n        console.log(\"[socket.open]\"), (r = this.onConnectEvent) == null || r.call(this), n();\n      }, this.socket.onmessage = (r) => {\n        var g, _, p, v, f, k, b, q, R, x, w, S, L, P;\n        const t = JSON.parse(r.data);\n        if (console.log(\"[socket.message]\", t), t.typing) {\n          (g = this.onUserTypingListener) == null || g.call(this, t.typing);\n          return;\n        }\n        if (t.system_message || (_ = t.message) != null && _.system_message) {\n          const a = t.system_message ?? ((p = t.message) == null ? void 0 : p.system_message), { conversation_created: l, conversation_updated: m, conversation_kicked: u } = (a == null ? void 0 : a.x) ?? {};\n          if (l) {\n            (v = this.onConversationCreateListener) == null || v.call(this, l);\n            return;\n          }\n          if (m) {\n            (f = this.onConversationUpdateListener) == null || f.call(this, m);\n            return;\n          }\n          if (u) {\n            (k = this.onConversationDeleteListener) == null || k.call(this, u);\n            return;\n          }\n          (b = this.onSystemMessageEvent) == null || b.call(this, a);\n          return;\n        }\n        if (t.last_activity) {\n          (q = this.onUserActivityListener) == null || q.call(this, t.last_activity);\n          return;\n        }\n        if (t.message_read) {\n          (R = this.onMessageStatusListener) == null || R.call(this, t.message_read);\n          return;\n        }\n        if (t.message_edit) {\n          (x = this.onMessageEditListener) == null || x.call(this, t.message_edit);\n          return;\n        }\n        if (t.message_delete) {\n          (w = this.onMessageDeleteListener) == null || w.call(this, t.message_delete);\n          return;\n        }\n        if (t.message_reactions_update) {\n          (S = this.onMessageReactionsListener) == null || S.call(this, t.message_reactions_update);\n          return;\n        }\n        if (t.message) {\n          if (t.message.error) {\n            const a = t.message.id ?? Object.keys(this.responsesPromises).filter((l) => l.length == 37).slice(-1)[0];\n            this.responsesPromises[a].reject(t.message.error), delete this.responsesPromises[a];\n            return;\n          }\n          (L = this.onMessageListener) == null || L.call(this, t.message), t.message.from.toString() !== this.currentUserId && ((P = this.onMessageEvent) == null || P.call(this, t.message));\n          return;\n        }\n        if (t.ask) {\n          const a = t.ask.mid;\n          this.responsesPromises[a].resolve(t.ask), delete this.responsesPromises[a];\n          return;\n        }\n        const c = t.response;\n        if (c) {\n          const a = c.id;\n          if (!a) {\n            console.error(c.error);\n            return;\n          }\n          const { resolve: l, reject: m, resObjKey: u } = this.responsesPromises[a];\n          if (c.error)\n            c.error.status === 403 ? this.responsesPromises[a].reject(c.error) : m(c.error);\n          else if (Array.isArray(u)) {\n            const I = u.reduce((h, y) => (c[y] !== void 0 && (h[y] = c[y]), h), {});\n            u.every((h) => h in I) ? l(I) : m({ message: \"Server error.\" });\n          } else u ? c[u] ? l(c[u]) : m({ message: \"Server error.\" }) : l(c);\n          delete this.responsesPromises[a];\n        }\n      }, this.socket.onerror = (r) => {\n        console.log(\"[socket.error]\", r), i(r);\n      }, this.socket.onclose = () => {\n        var r;\n        console.log(\"[socket.close]\"), (r = this.onDisconnectEvent) == null || r.call(this), this.config.disableAutoReconnect || this.reconnect();\n      };\n    });\n  }\n  reconnect() {\n    const e = () => {\n      navigator.onLine && document.visibilityState === \"visible\" && (this.connect(), window.removeEventListener(\"online\", e), document.removeEventListener(\"visibilitychange\", e));\n    };\n    navigator.onLine && document.visibilityState === \"visible\" ? this.connect() : (window.addEventListener(\"online\", e), document.addEventListener(\"visibilitychange\", e));\n  }\n  async disconnect() {\n    var e;\n    return (e = this.socket) == null ? void 0 : e.close();\n  }\n  async sendRequest(e, s = {}, n = \"success\") {\n    const i = {\n      request: {\n        [e]: s,\n        id: E(e)\n      }\n    };\n    return this.sendPromise(i, n);\n  }\n  async sendPromise(e, s) {\n    return new Promise((n, i) => {\n      if (!this.socket) {\n        i(\"Socket is not connected.\");\n        return;\n      }\n      this.socket.send(JSON.stringify(e)), console.log(\"[socket.send]\", e), this.responsesPromises[e.request.id] = { resolve: n, reject: i, resObjKey: s };\n    });\n  }\n  async sendHttpPromise(e, s, n) {\n    console.log(\"[http.request]\", { request: n });\n    const i = { \"Content-Type\": \"application/json\" }, r = localStorage.getItem(\"sessionId\");\n    r && (i.Authorization = `Bearer ${r}`);\n    const t = {\n      method: e,\n      credentials: \"include\",\n      headers: i\n    };\n    n && (t.body = JSON.stringify(n));\n    const c = await fetch(`${this.config.endpoint.http}/${s}`, t), g = await c.text();\n    if (!c.ok)\n      throw console.error(\"[http.error]\", g), g || c.statusText;\n    const _ = g ? JSON.parse(g) : {};\n    return console.log(\"[http.response]\", { response: _ }), _;\n  }\n  async connectSocket(e) {\n    return this.sendRequest(\"connect\", { token: e.token, device_id: e.deviceId ?? this.deviceId });\n  }\n  async socketLogin(e) {\n    return this.sendRequest(\"user_login\", { organization_id: this.config.organization_id, ...e.user, device_id: e.deviceId ?? this.deviceId, token: e.token }, [\"user\", \"token\"]);\n  }\n  async disconnectSocket() {\n    return this.sendRequest(\"user_logout\");\n  }\n  async userCreate(e) {\n    return this.sendRequest(\"user_create\", { organization_id: this.config.organization_id, login: e.login, email: e.email, password: e.password }, \"user\");\n  }\n  async userEdit(e) {\n    return this.sendRequest(\"user_edit\", e, \"user\");\n  }\n  async userLogin(e) {\n    const { login: s, password: n } = e || {}, i = Date.now();\n    parseInt(localStorage.getItem(\"sessionExpiredAt\") || `${i}`, 10) - i <= 0 && localStorage.removeItem(\"sessionId\");\n    const t = { organization_id: this.config.organization_id, device_id: this.deviceId };\n    return s && n && (t.login = s, t.password = n), await this.sendHttpPromise(\"POST\", \"login\", t);\n  }\n  async userLogout() {\n    return await this.sendHttpPromise(\"POST\", \"logout\", null);\n  }\n  async userSendOTPToken(e) {\n    const s = { organization_id: this.config.organization_id, device_id: this.deviceId, email: e.email };\n    return this.sendRequest(\"user_send_otp\", s);\n  }\n  async userResetPassword(e) {\n    const s = { organization_id: this.config.organization_id, device_id: this.deviceId, email: e.email, token: e.token, new_password: e.new_password };\n    return this.sendRequest(\"user_reset_password\", s);\n  }\n  async userDelete() {\n    return localStorage.removeItem(\"sessionId\"), this.sendRequest(\"user_delete\");\n  }\n  async userSearch(e) {\n    const s = {\n      keyword: e.keyword,\n      ignore_ids: e.ignore_ids || [],\n      ...e.limit && { limit: e.limit },\n      ...e.updated_at && { updated_at: e.updated_at }\n    };\n    return this.sendRequest(\"user_search\", s, \"users\");\n  }\n  async getUsersByIds(e) {\n    return this.sendRequest(\"get_users_by_ids\", { ids: e.ids }, \"users\");\n  }\n  async getParticipantsByCids(e) {\n    return this.sendRequest(\"get_participants_by_cids\", { cids: e.cids }, [\"users\", \"conversations\"]);\n  }\n  async createUploadUrlForFiles(e) {\n    return this.sendRequest(\"create_files\", e.files, \"files\");\n  }\n  async getDownloadUrlForFiles(e) {\n    return this.sendRequest(\"get_file_urls\", { file_ids: e.file_ids }, \"file_urls\");\n  }\n  async messageCreate(e) {\n    return new Promise((s, n) => {\n      var r;\n      const i = {\n        message: {\n          id: e.mid,\n          body: e.body,\n          cid: e.cid,\n          x: e.x,\n          attachments: e.attachments,\n          replied_message_id: e.replied_message_id,\n          forwarded_message_id: e.forwarded_message_id\n        }\n      };\n      this.responsesPromises[i.message.id] = { resolve: s, reject: n }, (r = this.socket) == null || r.send(JSON.stringify(i)), console.log(\"[socket.send]\", i);\n    });\n  }\n  async messageSystem(e) {\n    return new Promise((s, n) => {\n      var r;\n      const i = {\n        system_message: {\n          id: e.mid,\n          uids: e.uids,\n          cid: e.cid,\n          x: e.x\n        }\n      };\n      this.responsesPromises[i.system_message.id] = { resolve: s, reject: n }, (r = this.socket) == null || r.send(JSON.stringify(i)), console.log(\"[socket.send]\", i);\n    });\n  }\n  async messageList(e) {\n    const s = {\n      cid: e.cid,\n      ...e.ids && { ids: e.ids },\n      ...e.limit && { limit: e.limit },\n      ...e.updated_at && { updated_at: e.updated_at }\n    };\n    return this.sendRequest(\"message_list\", s, \"messages\");\n  }\n  async messageSummary(e) {\n    return this.sendRequest(\"message_summary\", { cid: e.cid, filter: e.filter }, \"message\");\n  }\n  async messageTone(e) {\n    return this.sendRequest(\"message_tone\", { body: e.body, tone: e.tone }, \"message\");\n  }\n  async markConversationAsRead(e) {\n    return this.sendRequest(\"message_read\", { cid: e.cid, ids: e.mids });\n  }\n  async messageEdit(e) {\n    return this.sendRequest(\"message_edit\", { id: e.mid, body: e.body });\n  }\n  async messageDelete(e) {\n    return this.sendRequest(\"message_delete\", { cid: e.cid, ids: e.mids, type: e.type ?? \"myself\" });\n  }\n  async getUserActivity(e) {\n    return this.sendRequest(\"user_last_activity\", { ids: e }, \"last_activity\");\n  }\n  async subscribeToUserActivity(e) {\n    return this.sendRequest(\"user_last_activity_subscribe\", { id: e }, \"last_activity\");\n  }\n  async unsubscribeFromUserActivity() {\n    return this.sendRequest(\"user_last_activity_unsubscribe\");\n  }\n  async sendTypingStatus(e) {\n    return new Promise((s, n) => {\n      var r;\n      const i = { typing: { cid: e.cid, status: e.status } };\n      (r = this.socket) == null || r.send(JSON.stringify(i)), console.log(\"[socket.send]\", i), s();\n    });\n  }\n  async conversationCreate(e) {\n    return this.sendRequest(\"conversation_create\", e, \"conversation\");\n  }\n  async conversationUpdate(e) {\n    var s, n;\n    return this.sendRequest(\"conversation_update\", {\n      id: e.cid,\n      name: e.name,\n      description: e.description,\n      participants: {\n        add: (s = e.participants) == null ? void 0 : s.add,\n        remove: (n = e.participants) == null ? void 0 : n.remove\n      },\n      image_object: e.image_object\n    }, \"conversation\");\n  }\n  async conversationList(e) {\n    var n;\n    const s = {\n      ...e.limit && { limit: e.limit },\n      ...e.updated_at && { updated_at: { gt: e.updated_at.gt, lt: e.updated_at.lt } },\n      ...((n = e.ids) == null ? void 0 : n.length) && { ids: e.ids }\n    };\n    return this.sendRequest(\"conversation_list\", s, \"conversations\");\n  }\n  async conversationDelete(e) {\n    return this.sendRequest(\"conversation_delete\", { id: e.cid });\n  }\n  async conversationSearch(e) {\n    return this.sendRequest(\n      \"conversation_search\",\n      { name: e.name, ...e.limit != null && { limit: e.limit } },\n      \"conversations\"\n    );\n  }\n  async conversationHandlerCreate(e) {\n    return this.sendRequest(\"conversation_handler_create\", { cid: e.cid, content: e.content });\n  }\n  async getConversationHandler(e) {\n    return this.sendRequest(\"get_conversation_handler\", { cid: e.cid }, \"conversation_handler\");\n  }\n  async conversationHandlerDelete(e) {\n    return this.sendRequest(\"conversation_handler_delete\", { cid: e.cid });\n  }\n  async pushSubscriptionCreate(e) {\n    return this.sendRequest(\"push_subscription_create\", {\n      platform: \"web\",\n      web_endpoint: e.web_endpoint,\n      web_key_auth: e.web_key_auth,\n      web_key_p256dh: e.web_key_p256dh,\n      device_udid: this.deviceId\n    }, \"subscription\");\n  }\n  async pushSubscriptionDelete() {\n    return this.sendRequest(\"push_subscription_delete\", { device_udid: this.deviceId });\n  }\n  async ping() {\n    return this.sendRequest(\"ping\", {}, \"pong\");\n  }\n  async setActivityStatus(e) {\n    return this.sendRequest(\"activity_status\", { isInactive: !!e }, \"success\");\n  }\n  async blockList() {\n    return this.sendRequest(\"list_blocked_users\", {}, \"users\");\n  }\n  async blockUsers(e) {\n    return this.sendRequest(\"block_user\", { ids: e }, \"success\");\n  }\n  async unblockUsers(e) {\n    return this.sendRequest(\"unblock_user\", { ids: e }, \"success\");\n  }\n  async reactionsUpdate(e, s, n) {\n    return this.sendRequest(\"message_reactions_update\", { mid: e, add: s, remove: n }, \"success\");\n  }\n  async reactionsList(e) {\n    return this.sendRequest(\"message_reactions_list\", { mid: e }, \"reactions\");\n  }\n}\nexport {\n  O as SAMAClient\n};\n","import { SAMAClient } from '@sama-communications/sdk';\nimport type { Chat } from '../../types';\n\nexport default class BlockList {\n  private samaClient: SAMAClient;\n\n  constructor(samaClient: SAMAClient) {\n    this.samaClient = samaClient;\n  }\n\n  public async block(userId: Chat.UserId): Promise<void>;\n  public async block(userIds: Chat.UserId[]): Promise<void>;\n  public async block(userIds: Chat.UserId | Chat.UserId[]): Promise<void> {\n    if (!Array.isArray(userIds)) {\n      userIds = [userIds];\n    }\n\n    await this.samaClient.blockUsers(userIds);\n  }\n\n  public async unblock(userId: Chat.UserId): Promise<void>;\n  public async unblock(userIds: Chat.UserId[]): Promise<void>;\n  public async unblock(userIds: Chat.UserId | Chat.UserId[]): Promise<void> {\n    if (!Array.isArray(userIds)) {\n      userIds = [userIds];\n    }\n\n    await this.samaClient.unblockUsers(userIds);\n  }\n\n  public async list(): Promise<Chat.UserId[]> {\n    const usersIds = await this.samaClient.blockList();\n    return usersIds;\n  }\n}\n","import config from '../../config';\nimport Utils from '../../Utils';\nimport { SAMAClient } from '@sama-communications/sdk';\nimport ProxyService from '../../Proxy';\nimport AbstractChatService from '../AbstractChatService';\nimport BlockList from './BlockList';\nimport type { SAMAChatRealTimeService } from '../../types/chat';\nimport type { Calls, Chat, PlainObject } from '../../types';\nimport { CallSignalingModuleIdentifier, CallType } from '../../types/constants';\n\nexport default class SAMAChatService extends AbstractChatService implements SAMAChatRealTimeService {\n  public samaClient: SAMAClient;\n  public blockList: BlockList;\n  public currentUserNativeId: Chat.UserId = 0;\n\n  constructor(proxy: ProxyService) {\n    super(proxy);\n\n    this.samaClient = new SAMAClient({\n      endpoint: {\n        ws: config.chatProtocol.websocket || '',\n        http: `https://${config.endpoints.api}`,\n      },\n      organization_id: `${config.creds.appId}`,\n      disableAutoReconnect: true,\n    });\n\n    this.blockList = new BlockList(this.samaClient);\n  }\n\n  public get connectionStatus(): string {\n    return '';\n  }\n\n  public get currentUserId(): Chat.UserId {\n    return this.currentUserNativeId || 0;\n  }\n\n  public async connect(params: Chat.ConnectionParams): Promise<boolean> {\n    Utils.DLog('[Chat]', 'Connect with parameter:', params);\n\n    this.samaClient.deviceId = params.deviceId ?? Utils.getBsonObjectId();\n\n    this.removeAllSamaListeners();\n    this.addAllSamaListeners();\n\n    if (!this.isConnected) {\n      await this.samaClient.connect();\n\n      this.isConnected = true;\n    }\n\n    const authorizedUser = await this.samaClient.socketLogin({\n      user: { userId: params.userId, password: params.password },\n    });\n\n    this.currentUserNativeId = authorizedUser.user.native_id;\n    this.isLogout = false;\n\n    return true;\n  }\n\n  public async disconnect(): Promise<boolean> {\n    Utils.DLog('[Chat]', 'disconnect');\n\n    this.isConnected = false;\n\n    try {\n      await this.samaClient.disconnectSocket();\n      await this.samaClient.disconnect();\n      this.currentUserNativeId = 0;\n      return true;\n    } catch {\n      return false;\n    }\n  }\n\n  public terminate(): void {\n    Utils.DLog('[Chat]', 'terminated');\n\n    this.isConnected = false;\n    this.currentUserNativeId = 0;\n\n    this.samaClient.disconnect();\n  }\n\n  private onSamaConnectedListener(): void {\n    Utils.DLog('[Chat]', this.samaClient.deviceId, '[connected]');\n\n    this.isConnected = true;\n\n    Utils.safeCallbackCall(this.onChatStatusListener)('connect');\n  }\n\n  private onSamaDisconnectListener(): void {\n    Utils.DLog('[Chat]', this.samaClient.deviceId, '[disconnect]');\n\n    this.isConnected = false;\n    this.isLogout = true;\n\n    Utils.safeCallbackCall(this.onChatStatusListener)('disconnect');\n    Utils.safeCallbackCall(this.onDisconnectedListener)();\n  }\n\n  private onSamaMessageEventListener(message: any): void {\n    Utils.DLog('[Chat]', '[packet]', this.samaClient.deviceId, message);\n  }\n\n  private onSamaMessageListener(message: any): void {\n    Utils.DLog('[Chat]', '[onMessage]', this.samaClient.deviceId, message);\n\n    const { _id, cid, from, body, t, x, attachments } = message;\n\n    const messageParams: Chat.Message = {\n      id: _id,\n      dialog_id: cid,\n      body: body,\n      extension: Object.assign({ date_sent: t, attachments }, x),\n    };\n\n    Utils.safeCallbackCall(this.onMessageListener)(from, messageParams);\n  }\n\n  private onSamaSystemMessageListener(message: any): void {\n    Utils.DLog('[Chat]', '[onSystem]', this.samaClient.deviceId, message);\n\n    const { _id, from, t, x } = message;\n\n    const systemMessage: Chat.SystemMessage = {\n      id: _id,\n      body: null as unknown as string,\n      userId: from,\n      extension: Object.assign({ date_sent: t }, x),\n    };\n\n    if (systemMessage.extension?.['moduleIdentifier'] === CallSignalingModuleIdentifier) {\n      return this.onWebRTCSignalingSystemMessage(systemMessage);\n    }\n\n    Utils.safeCallbackCall(this.onSystemMessageListener)(systemMessage);\n  }\n\n  private onWebRTCSignalingSystemMessage(systemMessage: Chat.SystemMessage<Calls.ExtensionParams>): void {\n    const extension = systemMessage.extension ?? {};\n\n    Object.keys(extension).forEach((key) => {\n      switch (key) {\n        case 'callerID':\n          extension[key] = parseInt(String(extension[key] || '0'));\n          break;\n\n        case 'callType':\n          const type = extension[key];\n          extension[key] = String(type) === '1' ? CallType.VIDEO : String(type) === '2' ? CallType.AUDIO : undefined;\n          break;\n\n        case 'opponentsIDs':\n          extension[key]?.map((opponentID) => Number(opponentID || '0'));\n          break;\n\n        case 'iceCandidates':\n          (extension[key] as unknown[] | undefined)?.forEach((iceCandidate: unknown) => {\n            const c = iceCandidate as PlainObject;\n            Object.keys(c).forEach((iceObjectKey) => {\n              if (iceObjectKey === 'sdpMLineIndex') {\n                c[iceObjectKey] = parseInt(String(c[iceObjectKey] || '0'));\n              }\n            });\n          });\n          break;\n\n        default:\n          break;\n      }\n    });\n\n    return Utils.safeCallbackCall(this.webrtcSignalingProcessor.onMessage)(\n      systemMessage.userId,\n      systemMessage.extension\n    );\n  }\n\n  private onSamaMessageStatusListener(message: any): void {\n    Utils.DLog('[Chat]', '[onStatus]', this.samaClient.deviceId, message);\n\n    const { ids, cid, from } = message;\n\n    for (const messageId of ids) {\n      Utils.safeCallbackCall(this.onReadStatusListener)(messageId, cid, from);\n    }\n  }\n\n  private onSamaUserLastActivityListener(message: any): void {\n    Utils.DLog('[Chat]', '[onLastActivity]', this.samaClient.deviceId, message);\n\n    Object.entries(message).forEach(([userId, lastActivityTs]) => {\n      Utils.safeCallbackCall(this.onLastUserActivityListener)(Number(userId), Number(lastActivityTs));\n    });\n  }\n\n  private onSamaTypingListener(message: any): void {\n    Utils.DLog('[Chat]', '[onTyping]', this.samaClient.deviceId, message);\n\n    const { cid, from, status } = message;\n    const isTyping = status === 'start';\n\n    Utils.safeCallbackCall(this.onMessageTypingListener)(isTyping, from, cid);\n  }\n\n  private onSamaMessageEditListener(message: any): void {\n    Utils.DLog('[Chat]', '[onEdit]', this.samaClient.deviceId, message);\n\n    const { id, cid, from, body } = message;\n\n    const messageEditParams = {\n      messageId: id,\n      isLast: false,\n      updatedBody: body,\n      dialogId: cid,\n      userId: from,\n      extraParams: {},\n    };\n\n    Utils.safeCallbackCall(this.onMessageUpdateListener)(\n      messageEditParams.messageId,\n      messageEditParams.isLast,\n      messageEditParams.updatedBody,\n      messageEditParams.dialogId,\n      messageEditParams.userId,\n      messageEditParams.extraParams\n    );\n  }\n\n  private onSamaDeleteListener(message: any): void {\n    Utils.DLog('[Chat]', '[onDelete]', this.samaClient.deviceId, message);\n\n    const { ids, cid, from } = message;\n\n    for (const messageId of ids) {\n      Utils.safeCallbackCall(this.onMessageDeleteListener)(messageId, cid, from);\n    }\n  }\n\n  private onSamaMessageReactionListener(messageReaction: any): void {\n    Utils.DLog('[Chat]', '[onReaction]', this.samaClient.deviceId, messageReaction);\n\n    const { mid, cid, from, add, remove } = messageReaction;\n\n    Utils.safeCallbackCall(this.onMessageReactionsListener)(mid, from, cid, add, remove);\n  }\n\n  public async ping(): Promise<void> {\n    await this.samaClient.ping();\n  }\n\n  public async sendIsTypingStatus(dialogId: Chat.DialogId | Chat.UserId): Promise<void> {\n    const requestParams = {\n      cid: String(dialogId),\n      status: 'start',\n    };\n\n    await this.samaClient.sendTypingStatus(requestParams);\n  }\n\n  public async sendIsStopTypingStatus(dialogId: Chat.DialogId | Chat.UserId): Promise<void> {\n    const requestParams = {\n      cid: String(dialogId),\n      status: 'stop',\n    };\n\n    await this.samaClient.sendTypingStatus(requestParams);\n  }\n\n  public async send(dialogId: Chat.DialogId | Chat.UserId, message: Chat.MessageParams): Promise<string> {\n    const mid = message.id ?? Utils.getBsonObjectId();\n    const x = message.extension ?? {};\n    const attachments = x?.['attachments'];\n    delete x?.['attachments'];\n\n    const requestParams = {\n      mid,\n      body: message.body ?? '',\n      x,\n      attachments,\n      cid: String(dialogId),\n    };\n\n    const ack = await this.samaClient.messageCreate(requestParams);\n\n    return ack?.server_mid ?? mid;\n  }\n\n  public sendSystemMessage(userId: Chat.UserId, message: Chat.SystemMessageParams): Promise<string>;\n  public sendSystemMessage(userIds: Array<Chat.UserId>, message: Chat.SystemMessageParams): Promise<string>;\n  public sendSystemMessage(dialogId: Chat.DialogId, message: Chat.SystemMessageParams): Promise<string>;\n  public async sendSystemMessage(\n    userIdsOrDialogId: Chat.UserId | Array<Chat.UserId> | Chat.DialogId,\n    message: Chat.SystemMessageParams\n  ): Promise<string> {\n    const mid = message.id ?? Utils.getBsonObjectId();\n\n    const destinationParams = Array.isArray(userIdsOrDialogId)\n      ? { uids: userIdsOrDialogId }\n      : typeof userIdsOrDialogId === 'number'\n        ? { uids: [userIdsOrDialogId] }\n        : { cid: userIdsOrDialogId };\n\n    const requestParams = {\n      mid,\n      x: message.extension ?? {},\n      ...destinationParams,\n    };\n\n    this.samaClient.messageSystem(requestParams);\n\n    return mid;\n  }\n\n  public async sendWebRTCSignalingMessage(userId: number, message: Chat.SystemMessageParams): Promise<string> {\n    return await this.sendSystemMessage(userId, message);\n  }\n\n  public async sendDeliveredStatus(_params: Chat.MessageStatusParams): Promise<void> {}\n\n  public async sendReadStatus(params: Chat.MessageStatusParams): Promise<void> {\n    const requestParams = {\n      cid: params.dialogId,\n      mids: [params.messageId],\n    };\n\n    await this.samaClient.markConversationAsRead(requestParams);\n  }\n\n  public async markDialogAsRead(params: Chat.DialogReadParams): Promise<void> {\n    const requestParams = {\n      cid: params.dialogId,\n    };\n\n    await this.samaClient.markConversationAsRead(requestParams);\n  }\n\n  public async updateReaction(messageId: string, addReaction: string, removeReaction: string): Promise<void> {\n    await this.samaClient.reactionsUpdate(messageId, addReaction, removeReaction);\n  }\n\n  public async editMessage(params: Chat.EditMessageParams): Promise<void> {\n    const requestParams = {\n      mid: params.originMessageId,\n      body: params.body,\n    };\n\n    await this.samaClient.messageEdit(requestParams);\n  }\n\n  public async deleteMessage(params: Chat.DeleteMessageParams): Promise<void> {\n    const requestParams = {\n      cid: params.dialogId,\n      mids: [params.messageId],\n      type: 'all',\n    };\n\n    await this.samaClient.messageDelete(requestParams);\n  }\n\n  public async getLastUserActivity(userId: Chat.UserId): Promise<Chat.LastActivity> {\n    const result = await this.samaClient.getUserActivity([userId]);\n\n    if (!(userId in result)) {\n      throw new Error('User not found');\n    }\n\n    const activityDate = result[userId];\n\n    if (activityDate === 0) {\n      return { userId, seconds: activityDate };\n    }\n\n    return { userId, seconds: !activityDate ? activityDate : Math.ceil(+new Date() / 1000) - activityDate };\n  }\n\n  public async subscribeToUserLastActivityStatus(userId: Chat.UserId): Promise<void> {\n    return await this.samaClient.subscribeToUserActivity(userId);\n  }\n\n  public async unsubscribeFromUserLastActivityStatus(_userId?: Chat.UserId): Promise<void> {\n    return await this.samaClient.unsubscribeFromUserActivity();\n  }\n\n  public async markActive(): Promise<void> {\n    await this.samaClient.setActivityStatus(false);\n  }\n\n  public async markInactive(): Promise<void> {\n    await this.samaClient.setActivityStatus(true);\n  }\n\n  private addAllSamaListeners() {\n    this.samaClient.onConnectEvent = this.onSamaConnectedListener.bind(this);\n    this.samaClient.onDisconnectEvent = this.onSamaDisconnectListener.bind(this);\n\n    this.samaClient.onMessageListener = this.onSamaMessageEventListener.bind(this);\n    this.samaClient.onMessageEvent = this.onSamaMessageListener.bind(this);\n    this.samaClient.onSystemMessageEvent = this.onSamaSystemMessageListener.bind(this);\n\n    this.samaClient.onMessageStatusListener = this.onSamaMessageStatusListener.bind(this);\n    this.samaClient.onMessageReactionsListener = this.onSamaMessageReactionListener.bind(this);\n\n    this.samaClient.onMessageEditListener = this.onSamaMessageEditListener.bind(this);\n    this.samaClient.onMessageDeleteListener = this.onSamaDeleteListener.bind(this);\n\n    this.samaClient.onUserActivityListener = this.onSamaUserLastActivityListener.bind(this);\n    this.samaClient.onUserTypingListener = this.onSamaTypingListener.bind(this);\n  }\n\n  private removeAllSamaListeners() {\n    this.samaClient.onConnectEvent = void 0;\n    this.samaClient.onDisconnectEvent = void 0;\n\n    this.samaClient.onMessageListener = void 0;\n    this.samaClient.onMessageEvent = void 0;\n    this.samaClient.onSystemMessageEvent = void 0;\n\n    this.samaClient.onMessageStatusListener = void 0;\n    this.samaClient.onMessageReactionsListener = void 0;\n\n    this.samaClient.onMessageEditListener = void 0;\n    this.samaClient.onMessageDeleteListener = void 0;\n\n    this.samaClient.onUserActivityListener = void 0;\n    this.samaClient.onUserTypingListener = void 0;\n  }\n}\n","const {\n  adapter,\n  navigator,\n  MediaStream,\n  MediaStreamTrack,\n  RTCPeerConnection,\n  RTCRtpReceiver,\n  RTCRtpSender,\n  isReactNative\n} = require('@platform');\n\n('use strict');\n/*\n  The MIT License (MIT)\n\n  Copyright (c) 2016 Meetecho\n\n  Permission is hereby granted, free of charge, to any person obtaining\n  a copy of this software and associated documentation files (the \"Software\"),\n  to deal in the Software without restriction, including without limitation\n  the rights to use, copy, modify, merge, publish, distribute, sublicense,\n  and/or sell copies of the Software, and to permit persons to whom the\n  Software is furnished to do so, subject to the following conditions:\n\n  The above copyright notice and this permission notice shall be included\n  in all copies or substantial portions of the Software.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n  OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n  OTHER DEALINGS IN THE SOFTWARE.\n */\n\n// List of sessions\nJanus.sessions = {};\n\nJanus.mobile = isReactNative;\n\nJanus.isExtensionEnabled = function () {\n  if (Janus.mobile) {\n    return false;\n  }\n  if (navigator.mediaDevices && navigator.mediaDevices.getDisplayMedia) {\n    // No need for the extension, getDisplayMedia is supported\n    return true;\n  }\n  if (window.navigator.userAgent.match('Chrome')) {\n    let chromever = parseInt(window.navigator.userAgent.match(/Chrome\\/(.*) /)[1], 10);\n    let maxver = 33;\n    if (window.navigator.userAgent.match('Linux')) maxver = 35; // \"known\" crash in chrome 34 and 35 on linux\n    if (chromever >= 26 && chromever <= maxver) {\n      // Older versions of Chrome don't support this extension-based approach, so lie\n      return true;\n    }\n    return Janus.extension.isInstalled();\n  } else {\n    // Firefox and others, no need for the extension (but this doesn't mean it will work)\n    return true;\n  }\n};\n\nconst defaultExtension = {\n  // Screensharing Chrome Extension ID\n  extensionId: 'hapfgfdkleiggjjpfpenajgdnfckjpaj',\n  isInstalled: function () {\n    if (Janus.mobile) {\n      return false;\n    } else {\n      return document.querySelector('#janus-extension-installed') !== null;\n    }\n  },\n  getScreen: function (callback) {\n    if (Janus.mobile) {\n      callback();\n    } else {\n      let pending = window.setTimeout(function () {\n        let error = new Error('NavigatorUserMediaError');\n        error.name =\n          'The required Chrome extension is not installed: click <a href=\"#\">here</a> to install it. (NOTE: this will need you to refresh the page)';\n        return callback(error);\n      }, 1000);\n      this.cache[pending] = callback;\n      window.postMessage({ type: 'janusGetScreen', id: pending }, '*');\n    }\n  },\n  init: function () {\n    let cache = {};\n    this.cache = cache;\n    // Wait for events from the Chrome Extension\n    if (!Janus.mobile) {\n      window.addEventListener('message', function (event) {\n        if (event.origin != window.location.origin) return;\n        if (event.data.type == 'janusGotScreen' && cache[event.data.id]) {\n          let callback = cache[event.data.id];\n          delete cache[event.data.id];\n          if (event.data.sourceId === '') {\n            // user canceled\n            let error = new Error('NavigatorUserMediaError');\n            error.name = 'You cancelled the request for permission, giving up...';\n            callback(error);\n          } else {\n            callback(null, event.data.sourceId);\n          }\n        } else if (event.data.type == 'janusGetScreenPending') {\n          window.clearTimeout(event.data.id);\n        }\n      });\n    }\n  },\n};\n\nJanus.useDefaultDependencies = function (deps) {\n  let f = (deps && deps.fetch) || fetch;\n  let p = (deps && deps.Promise) || Promise;\n  let socketCls = (deps && deps.WebSocket) || WebSocket;\n\n  return {\n    newWebSocket: function (server, proto) {\n      return new socketCls(server, proto);\n    },\n    extension: (deps && deps.extension) || defaultExtension,\n    isArray: function (arr) {\n      return Array.isArray(arr);\n    },\n    webRTCAdapter: (deps && deps.adapter) || adapter,\n    httpAPICall: function (url, options) {\n      let fetchOptions = {\n        method: options.verb,\n        headers: {\n          Accept: 'application/json, text/plain, */*',\n        },\n        cache: 'no-cache',\n      };\n      if (options.verb === 'POST') {\n        fetchOptions.headers['Content-Type'] = 'application/json';\n      }\n      if (typeof options.withCredentials !== 'undefined') {\n        fetchOptions.credentials =\n          options.withCredentials === true ? 'include' : options.withCredentials ? options.withCredentials : 'omit';\n      }\n      if (options.body) {\n        fetchOptions.body = JSON.stringify(options.body);\n      }\n\n      let fetching = f(url, fetchOptions).catch(function (error) {\n        return p.reject({\n          message: 'Probably a network error, is the server down?',\n          error: error,\n        });\n      });\n\n      /*\n       * fetch() does not natively support timeouts.\n       * Work around this by starting a timeout manually, and racing it agains the fetch() to see which thing resolves first.\n       */\n\n      if (options.timeout) {\n        let timeout = new p(function (resolve, reject) {\n          let timerId = setTimeout(function () {\n            clearTimeout(timerId);\n            return reject({\n              message: 'Request timed out',\n              timeout: options.timeout,\n            });\n          }, options.timeout);\n        });\n        fetching = p.race([fetching, timeout]);\n      }\n\n      fetching\n        .then(function (response) {\n          if (response.ok) {\n            if (typeof options.success === typeof Janus.noop) {\n              return response.json().then(\n                function (parsed) {\n                  try {\n                    options.success(parsed);\n                  } catch (error) {\n                    Janus.error('Unhandled httpAPICall success callback error', error);\n                  }\n                },\n                function (error) {\n                  return p.reject({\n                    message: 'Failed to parse response body',\n                    error: error,\n                    response: response,\n                  });\n                }\n              );\n            }\n          } else {\n            return p.reject({ message: 'API call failed', response: response });\n          }\n        })\n        .catch(function (error) {\n          if (typeof options.error === typeof Janus.noop) {\n            options.error(error.message || '<< internal error >>', error);\n          }\n        });\n\n      return fetching;\n    },\n  };\n};\n\nJanus.useOldDependencies = function (deps) {\n  let jq = (deps && deps.jQuery) || jQuery;\n  let socketCls = (deps && deps.WebSocket) || WebSocket;\n  return {\n    newWebSocket: function (server, proto) {\n      return new socketCls(server, proto);\n    },\n    isArray: function (arr) {\n      return jq.isArray(arr);\n    },\n    extension: (deps && deps.extension) || defaultExtension,\n    webRTCAdapter: (deps && deps.adapter) || adapter,\n    httpAPICall: function (url, options) {\n      let payload =\n        typeof options.body !== 'undefined'\n          ? {\n            contentType: 'application/json',\n            data: JSON.stringify(options.body),\n          }\n          : {};\n      let credentials =\n        typeof options.withCredentials !== 'undefined'\n          ? { xhrFields: { withCredentials: options.withCredentials } }\n          : {};\n\n      return jq.ajax(\n        jq.extend(payload, credentials, {\n          url: url,\n          type: options.verb,\n          cache: false,\n          dataType: 'json',\n          async: options.async,\n          timeout: options.timeout,\n          success: function (result) {\n            if (typeof options.success === typeof Janus.noop) {\n              options.success(result);\n            }\n          },\n          error: function (xhr, status, err) {\n            if (typeof options.error === typeof Janus.noop) {\n              options.error(status, err);\n            }\n          },\n        })\n      );\n    },\n  };\n};\n\n// Helper function to convert a deprecated media object to a tracks array\nJanus.mediaToTracks = function (media) {\n  let tracks = [];\n  if (!media) {\n    // Default is bidirectional audio and video, using default devices\n    tracks.push({ type: 'audio', capture: true, recv: true });\n    tracks.push({ type: 'video', capture: true, recv: true });\n  } else {\n    if (\n      !media.keepAudio &&\n      media.audio !== false &&\n      (typeof media.audio === 'undefined' ||\n        media.audio ||\n        media.audioSend ||\n        media.audioRecv ||\n        media.addAudio ||\n        media.replaceAudio ||\n        media.removeAudio)\n    ) {\n      // We may need an audio track\n      let track = { type: 'audio' };\n      if (media.removeAudio) {\n        track.remove = true;\n      } else {\n        if (media.addAudio) track.add = true;\n        else if (media.replaceAudio) track.replace = true;\n        // Check if we need to capture an audio device\n        if (media.audioSend !== false) track.capture = media.audio || true;\n        // Check if we need to receive audio\n        if (media.audioRecv !== false) track.recv = true;\n      }\n      // Add an audio track if needed\n      if (track.remove || track.capture || track.recv) tracks.push(track);\n    }\n    if (\n      !media.keepVideo &&\n      media.video !== false &&\n      (typeof media.video === 'undefined' ||\n        media.video ||\n        media.videoSend ||\n        media.videoRecv ||\n        media.addVideo ||\n        media.replaceVideo ||\n        media.removeVideo)\n    ) {\n      // We may need a video track\n      let track = { type: 'video' };\n      if (media.removeVideo) {\n        track.remove = true;\n      } else {\n        if (media.addVideo) track.add = true;\n        else if (media.replaceVideo) track.replace = true;\n        // Check if we need to capture a video device\n        if (media.videoSend !== false) {\n          track.capture = media.video || true;\n          if (['screen', 'window', 'desktop'].includes(track.capture)) {\n            // Change the type to 'screen'\n            track.type = 'screen';\n            track.capture = { video: {} };\n            // Check if there's constraints\n            if (media.screenshareFrameRate) track.capture.frameRate = media.screenshareFrameRate;\n            if (media.screenshareHeight) track.capture.height = media.screenshareHeight;\n            if (media.screenshareWidth) track.capture.width = media.screenshareWidth;\n          }\n        }\n        // Check if we need to receive video\n        if (media.videoRecv !== false) track.recv = true;\n      }\n      // Add a video track if needed\n      if (track.remove || track.capture || track.recv) tracks.push(track);\n    }\n    if (media.data) {\n      // We need a data channel\n      tracks.push({ type: 'data' });\n    }\n  }\n  // Done\n  return tracks;\n};\n\n// Helper function to convert a track object to a set of constraints\nJanus.trackConstraints = function (track) {\n  let constraints = {};\n  if (!track || !track.capture) return constraints;\n  if (track.type === 'audio') {\n    // Just put the capture part in the constraints\n    constraints.audio = track.capture;\n  } else if (track.type === 'video') {\n    // Check if one of the keywords was passed\n    if ((track.simulcast || track.svc) && track.capture === true) track.capture = 'hires';\n    if (track.capture === true || typeof track.capture === 'object') {\n      // Use the provided capture object as video constraint\n      constraints.video = track.capture;\n    } else {\n      let width = 0;\n      let height = 0;\n      if (track.capture === 'lowres') {\n        // Small resolution, 4:3\n        width = 320;\n        height = 240;\n      } else if (track.capture === 'lowres-16:9') {\n        // Small resolution, 16:9\n        width = 320;\n        height = 180;\n      } else if (track.capture === 'hires' || track.capture === 'hires-16:9' || track.capture === 'hdres') {\n        // High(HD) resolution is only 16:9\n        width = 1280;\n        height = 720;\n      } else if (track.capture === 'fhdres') {\n        // Full HD resolution is only 16:9\n        width = 1920;\n        height = 1080;\n      } else if (track.capture === '4kres') {\n        // 4K resolution is only 16:9\n        width = 3840;\n        height = 2160;\n      } else if (track.capture === 'stdres') {\n        // Normal resolution, 4:3\n        width = 640;\n        height = 480;\n      } else if (track.capture === 'stdres-16:9') {\n        // Normal resolution, 16:9\n        width = 640;\n        height = 360;\n      } else {\n        Janus.log('Default video setting is stdres 4:3');\n        width = 640;\n        height = 480;\n      }\n      constraints.video = {\n        width: { ideal: width },\n        height: { ideal: height },\n      };\n    }\n  } else if (track.type === 'screen') {\n    // Use the provided capture object as video constraint\n    constraints.video = track.capture;\n  }\n  return constraints;\n};\n\nJanus.noop = function () { };\n\nJanus.dataChanDefaultLabel = 'JanusDataChannel';\n\n// Note: in the future we may want to change this, e.g., as was\n// attempted in https://github.com/meetecho/janus-gateway/issues/1670\nJanus.endOfCandidates = null;\n\n// Stop all tracks from a given stream\nJanus.stopAllTracks = function (stream) {\n  try {\n    // Try a MediaStreamTrack.stop() for each track\n    let tracks = stream.getTracks();\n    for (let mst of tracks) {\n      Janus.log(mst);\n      if (mst && mst.dontStop !== true) {\n        mst.stop();\n      }\n    }\n  } catch (e) {\n    // Do nothing if this fails\n  }\n};\n\n// Initialization\nJanus.init = function (options) {\n  options = options || {};\n  options.callback = typeof options.callback == 'function' ? options.callback : Janus.noop;\n  if (Janus.initDone) {\n    // Already initialized\n    options.callback();\n  } else {\n    if (typeof console.log == 'undefined') {\n      console.log = function () { };\n    }\n    // Console logging (all debugging disabled by default)\n    Janus.trace = Janus.noop;\n    Janus.debug = Janus.noop;\n    Janus.vdebug = Janus.noop;\n    Janus.log = Janus.noop;\n    Janus.warn = Janus.noop;\n    Janus.error = Janus.noop;\n    if (options.debug === true || options.debug === 'all') {\n      // Enable all debugging levels\n      Janus.trace = console.trace.bind(console);\n      Janus.debug = console.debug.bind(console);\n      Janus.vdebug = console.debug.bind(console);\n      Janus.log = console.log.bind(console);\n      Janus.warn = console.warn.bind(console);\n      Janus.error = console.error.bind(console);\n    } else if (Array.isArray(options.debug)) {\n      for (let d of options.debug) {\n        switch (d) {\n          case 'trace':\n            Janus.trace = console.trace.bind(console);\n            break;\n          case 'debug':\n            Janus.debug = console.debug.bind(console);\n            break;\n          case 'vdebug':\n            Janus.vdebug = console.debug.bind(console);\n            break;\n          case 'log':\n            Janus.log = console.log.bind(console);\n            break;\n          case 'warn':\n            Janus.warn = console.warn.bind(console);\n            break;\n          case 'error':\n            Janus.error = console.error.bind(console);\n            break;\n          default:\n            console.error(\n              \"Unknown debugging option '\" + d + \"' (supported: 'trace', 'debug', 'vdebug', 'log', warn', 'error')\"\n            );\n            break;\n        }\n      }\n    }\n    Janus.log('Initializing library');\n\n    let usedDependencies = options.dependencies || Janus.useDefaultDependencies();\n    Janus.isArray = usedDependencies.isArray;\n    Janus.webRTCAdapter = usedDependencies.webRTCAdapter;\n    Janus.httpAPICall = usedDependencies.httpAPICall;\n    Janus.newWebSocket = usedDependencies.newWebSocket;\n    Janus.extension = usedDependencies.extension;\n    Janus.extension.init();\n\n    // Helper method to enumerate devices\n    Janus.listDevices = function (callback, config) {\n      callback = typeof callback == 'function' ? callback : Janus.noop;\n      if (!config) config = { audio: true, video: true };\n      if (Janus.isGetUserMediaAvailable()) {\n        navigator.mediaDevices\n          .getUserMedia(config)\n          .then(function (stream) {\n            navigator.mediaDevices.enumerateDevices().then(function (devices) {\n              Janus.debug(devices);\n              callback(devices);\n              // Get rid of the now useless stream\n              Janus.stopAllTracks(stream);\n            });\n          })\n          .catch(function (err) {\n            Janus.error(err);\n            callback([]);\n          });\n      } else {\n        Janus.warn('navigator.mediaDevices unavailable');\n        callback([]);\n      }\n    };\n    // Helper methods to attach/reattach a stream to a video element (previously part of adapter.js)\n    // Janus.attachMediaStream = function(element, stream) {\n    // \ttry {\n    // \t\telement.srcObject = stream;\n    // \t} catch (e) {\n    // \t\ttry {\n    // \t\t\telement.src = URL.createObjectURL(stream);\n    // \t\t} catch (e) {\n    // \t\t\tJanus.error(\"Error attaching stream to element\", e);\n    // \t\t}\n    // \t}\n    // };\n    // Janus.reattachMediaStream = function(to, from) {\n    // \ttry {\n    // \t\tto.srcObject = from.srcObject;\n    // \t} catch (e) {\n    // \t\ttry {\n    // \t\t\tto.src = from.src;\n    // \t\t} catch (e) {\n    // \t\t\tJanus.error(\"Error reattaching stream to element\", e);\n    // \t\t}\n    // \t}\n    // };\n    // Detect tab close: make sure we don't loose existing onbeforeunload handlers\n    // (note: for iOS we need to subscribe to a different event, 'pagehide', see\n    // https://gist.github.com/thehunmonkgroup/6bee8941a49b86be31a787fe8f4b8cfe)\n    // let iOS = ['iPad', 'iPhone', 'iPod'].indexOf(navigator.platform) >= 0;\n    // let eventName = iOS ? 'pagehide' : 'beforeunload';\n    // let oldOBF = window[\"on\" + eventName];\n    // window.addEventListener(eventName, function() {\n    // \tJanus.log(\"Closing window\");\n    // \tfor(let s in Janus.sessions) {\n    // \t\tif(Janus.sessions[s] && Janus.sessions[s].destroyOnUnload) {\n    // \t\t\tJanus.log(\"Destroying session \" + s);\n    // \t\t\tJanus.sessions[s].destroy({unload: true, notifyDestroyed: false});\n    // \t\t}\n    // \t}\n    // \tif(oldOBF && typeof oldOBF == \"function\") {\n    // \t\toldOBF();\n    // \t}\n    // });\n    // If this is a Safari Technology Preview, check if VP8 is supported\n    Janus.safariVp8 = false;\n    if (Janus.webRTCAdapter.browserDetails.browser === 'safari' && Janus.webRTCAdapter.browserDetails.version >= 605) {\n      // Let's see if RTCRtpSender.getCapabilities() is there\n      if (\n        RTCRtpSender &&\n        RTCRtpSender.getCapabilities &&\n        RTCRtpSender.getCapabilities('video') &&\n        RTCRtpSender.getCapabilities('video').codecs &&\n        RTCRtpSender.getCapabilities('video').codecs.length\n      ) {\n        for (let codec of RTCRtpSender.getCapabilities('video').codecs) {\n          if (codec && codec.mimeType && codec.mimeType.toLowerCase() === 'video/vp8') {\n            Janus.safariVp8 = true;\n            break;\n          }\n        }\n        if (Janus.safariVp8) {\n          Janus.log('This version of Safari supports VP8');\n        } else {\n          Janus.warn(\n            \"This version of Safari does NOT support VP8: if you're using a Technology Preview, \" +\n            \"try enabling the 'WebRTC VP8 codec' setting in the 'Experimental Features' Develop menu\"\n          );\n        }\n      } else {\n        // We do it in a very ugly way, as there's no alternative...\n        // We create a PeerConnection to see if VP8 is in an offer\n        let testpc = new RTCPeerConnection({});\n        testpc.createOffer({ offerToReceiveVideo: true }).then(function (offer) {\n          Janus.safariVp8 = offer.sdp.indexOf('VP8') !== -1;\n          if (Janus.safariVp8) {\n            Janus.log('This version of Safari supports VP8');\n          } else {\n            Janus.warn(\n              \"This version of Safari does NOT support VP8: if you're using a Technology Preview, \" +\n              \"try enabling the 'WebRTC VP8 codec' setting in the 'Experimental Features' Develop menu\"\n            );\n          }\n          testpc.close();\n          testpc = null;\n        });\n      }\n    }\n    Janus.initDone = true;\n    options.callback();\n  }\n};\n\n// Helper method to check whether WebRTC is supported by this browser\nJanus.isWebrtcSupported = function () {\n  return !!RTCPeerConnection;\n};\n// Helper method to check whether devices can be accessed by this browser (e.g., not possible via plain HTTP)\nJanus.isGetUserMediaAvailable = function () {\n  return navigator.mediaDevices && navigator.mediaDevices.getUserMedia;\n};\n\n// Helper method to create random identifiers (e.g., transaction)\nJanus.randomString = function (len) {\n  let charSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n  let randomString = '';\n  for (let i = 0; i < len; i++) {\n    let randomPoz = Math.floor(Math.random() * charSet.length);\n    randomString += charSet.charAt(randomPoz);\n  }\n  return randomString;\n};\n\nfunction Janus(gatewayCallbacks) {\n  gatewayCallbacks = gatewayCallbacks || {};\n  gatewayCallbacks.success = typeof gatewayCallbacks.success == 'function' ? gatewayCallbacks.success : Janus.noop;\n  gatewayCallbacks.error = typeof gatewayCallbacks.error == 'function' ? gatewayCallbacks.error : Janus.noop;\n  gatewayCallbacks.destroyed =\n    typeof gatewayCallbacks.destroyed == 'function' ? gatewayCallbacks.destroyed : Janus.noop;\n  if (!Janus.initDone) {\n    gatewayCallbacks.error('Library not initialized');\n    return {};\n  }\n  if (!Janus.isWebrtcSupported()) {\n    gatewayCallbacks.error('WebRTC not supported by this browser');\n    return {};\n  }\n  Janus.log('Library initialized: ' + Janus.initDone);\n  if (!gatewayCallbacks.server) {\n    gatewayCallbacks.error('Invalid server url');\n    return {};\n  }\n  let websockets = false;\n  let ws = null;\n  let wsHandlers = {};\n  let wsKeepaliveTimeoutId = null;\n  let servers = null;\n  let serversIndex = 0;\n  let server = gatewayCallbacks.server;\n  if (Janus.isArray(server)) {\n    Janus.log('Multiple servers provided (' + server.length + '), will use the first that works');\n    server = null;\n    servers = gatewayCallbacks.server;\n    Janus.debug(servers);\n  } else {\n    if (server.indexOf('ws') === 0) {\n      websockets = true;\n      Janus.log('Using WebSockets to contact Janus: ' + server);\n    } else {\n      websockets = false;\n      Janus.log('Using REST API to contact Janus: ' + server);\n    }\n  }\n  let iceServers = gatewayCallbacks.iceServers || [{ urls: 'stun:stun.l.google.com:19302' }];\n  let iceTransportPolicy = gatewayCallbacks.iceTransportPolicy;\n  let bundlePolicy = gatewayCallbacks.bundlePolicy;\n  // Whether we should enable the withCredentials flag for XHR requests\n  let withCredentials = false;\n  if (typeof gatewayCallbacks.withCredentials !== 'undefined' && gatewayCallbacks.withCredentials !== null)\n    withCredentials = gatewayCallbacks.withCredentials === true;\n  // Optional max events\n  let maxev = 10;\n  if (typeof gatewayCallbacks.max_poll_events !== 'undefined' && gatewayCallbacks.max_poll_events !== null)\n    maxev = gatewayCallbacks.max_poll_events;\n  if (maxev < 1) maxev = 1;\n  // Token to use (only if the token based authentication mechanism is enabled)\n  let token = null;\n  if (typeof gatewayCallbacks.token !== 'undefined' && gatewayCallbacks.token !== null) token = gatewayCallbacks.token;\n  // API secret to use (only if the shared API secret is enabled)\n  let apisecret = null;\n  if (typeof gatewayCallbacks.apisecret !== 'undefined' && gatewayCallbacks.apisecret !== null)\n    apisecret = gatewayCallbacks.apisecret;\n  // Whether we should destroy this session when onbeforeunload is called\n  this.destroyOnUnload = true;\n  if (typeof gatewayCallbacks.destroyOnUnload !== 'undefined' && gatewayCallbacks.destroyOnUnload !== null)\n    this.destroyOnUnload = gatewayCallbacks.destroyOnUnload === true;\n  // Some timeout-related values\n  let keepAlivePeriod = 25000;\n  if (typeof gatewayCallbacks.keepAlivePeriod !== 'undefined' && gatewayCallbacks.keepAlivePeriod !== null)\n    keepAlivePeriod = gatewayCallbacks.keepAlivePeriod;\n  if (isNaN(keepAlivePeriod)) keepAlivePeriod = 25000;\n  let longPollTimeout = 60000;\n  if (typeof gatewayCallbacks.longPollTimeout !== 'undefined' && gatewayCallbacks.longPollTimeout !== null)\n    longPollTimeout = gatewayCallbacks.longPollTimeout;\n  if (isNaN(longPollTimeout)) longPollTimeout = 60000;\n\n  // overrides for default maxBitrate values for simulcasting\n  function getMaxBitrates(simulcastMaxBitrates) {\n    let maxBitrates = {\n      high: 900000,\n      medium: 300000,\n      low: 100000,\n    };\n\n    if (typeof simulcastMaxBitrates !== 'undefined' && simulcastMaxBitrates !== null) {\n      if (simulcastMaxBitrates.high) maxBitrates.high = simulcastMaxBitrates.high;\n      if (simulcastMaxBitrates.medium) maxBitrates.medium = simulcastMaxBitrates.medium;\n      if (simulcastMaxBitrates.low) maxBitrates.low = simulcastMaxBitrates.low;\n    }\n\n    return maxBitrates;\n  }\n\n  let connected = false;\n  let sessionId = null;\n  let pluginHandles = {};\n  let that = this;\n  let retries = 0;\n  let transactions = {};\n  createSession(gatewayCallbacks);\n\n  // Public methods\n  this.getServer = function () {\n    return server;\n  };\n  this.isConnected = function () {\n    return connected;\n  };\n  this.reconnect = function (callbacks) {\n    callbacks = callbacks || {};\n    callbacks.success = typeof callbacks.success == 'function' ? callbacks.success : Janus.noop;\n    callbacks.error = typeof callbacks.error == 'function' ? callbacks.error : Janus.noop;\n    callbacks['reconnect'] = true;\n    createSession(callbacks);\n  };\n  this.getSessionId = function () {\n    return sessionId;\n  };\n  this.getInfo = function (callbacks) {\n    getInfo(callbacks);\n  };\n  this.destroy = function (callbacks) {\n    destroySession(callbacks);\n  };\n  this.attach = function (callbacks) {\n    createHandle(callbacks);\n  };\n\n  function eventHandler() {\n    if (sessionId == null) return;\n    Janus.debug('Long poll...');\n    if (!connected) {\n      Janus.warn('Is the server down? (connected=false)');\n      return;\n    }\n    let longpoll = server + '/' + sessionId + '?rid=' + new Date().getTime();\n    if (maxev) longpoll = longpoll + '&maxev=' + maxev;\n    if (token) longpoll = longpoll + '&token=' + encodeURIComponent(token);\n    if (apisecret) longpoll = longpoll + '&apisecret=' + encodeURIComponent(apisecret);\n    Janus.httpAPICall(longpoll, {\n      verb: 'GET',\n      withCredentials: withCredentials,\n      success: handleEvent,\n      timeout: longPollTimeout,\n      error: function (textStatus, errorThrown) {\n        Janus.error(textStatus + ':', errorThrown);\n        retries++;\n        if (retries > 3) {\n          // Did we just lose the server? :-(\n          connected = false;\n          gatewayCallbacks.error('Lost connection to the server (is it down?)');\n          return;\n        }\n        eventHandler();\n      },\n    });\n  }\n\n  // Private event handler: this will trigger plugin callbacks, if set\n  function handleEvent(json, skipTimeout) {\n    retries = 0;\n    if (!websockets && typeof sessionId !== 'undefined' && sessionId !== null && skipTimeout !== true) eventHandler();\n    if (!websockets && Janus.isArray(json)) {\n      // We got an array: it means we passed a maxev > 1, iterate on all objects\n      for (let i = 0; i < json.length; i++) {\n        handleEvent(json[i], true);\n      }\n      return;\n    }\n    if (json['janus'] === 'keepalive') {\n      // Nothing happened\n      Janus.vdebug('Got a keepalive on session ' + sessionId);\n      return;\n    } else if (json['janus'] === 'server_info') {\n      // Just info on the Janus instance\n      Janus.debug('Got info on the Janus instance');\n      Janus.debug(json);\n      const transaction = json['transaction'];\n      if (transaction) {\n        const reportSuccess = transactions[transaction];\n        if (reportSuccess) reportSuccess(json);\n        delete transactions[transaction];\n      }\n      return;\n    } else if (json['janus'] === 'ack') {\n      // Just an ack, we can probably ignore\n      Janus.debug('Got an ack on session ' + sessionId);\n      Janus.debug(json);\n      const transaction = json['transaction'];\n      if (transaction) {\n        const reportSuccess = transactions[transaction];\n        if (reportSuccess) reportSuccess(json);\n        delete transactions[transaction];\n      }\n      return;\n    } else if (json['janus'] === 'success') {\n      // Success!\n      Janus.debug('Got a success on session ' + sessionId);\n      Janus.debug(json);\n      const transaction = json['transaction'];\n      if (transaction) {\n        const reportSuccess = transactions[transaction];\n        if (reportSuccess) reportSuccess(json);\n        delete transactions[transaction];\n      }\n      return;\n    } else if (json['janus'] === 'trickle') {\n      // We got a trickle candidate from Janus\n      const sender = json['sender'];\n      if (!sender) {\n        Janus.warn('Missing sender...');\n        return;\n      }\n      const pluginHandle = pluginHandles[sender];\n      if (!pluginHandle) {\n        Janus.debug('This handle is not attached to this session');\n        return;\n      }\n      let candidate = json['candidate'];\n      Janus.debug('Got a trickled candidate on session ' + sessionId);\n      Janus.debug(candidate);\n      let config = pluginHandle.webrtcStuff;\n      if (config.pc && config.remoteSdp) {\n        // Add candidate right now\n        Janus.debug('Adding remote candidate:', candidate);\n        if (!candidate || candidate.completed === true) {\n          // end-of-candidates\n          config.pc.addIceCandidate(Janus.endOfCandidates);\n        } else {\n          // New candidate\n          config.pc.addIceCandidate(candidate);\n        }\n      } else {\n        // We didn't do setRemoteDescription (trickle got here before the offer?)\n        Janus.debug(\"We didn't do setRemoteDescription (trickle got here before the offer?), caching candidate\");\n        if (!config.candidates) config.candidates = [];\n        config.candidates.push(candidate);\n        Janus.debug(config.candidates);\n      }\n    } else if (json['janus'] === 'webrtcup') {\n      // The PeerConnection with the server is up! Notify this\n      Janus.debug('Got a webrtcup event on session ' + sessionId);\n      Janus.debug(json);\n      const sender = json['sender'];\n      if (!sender) {\n        Janus.warn('Missing sender...');\n        return;\n      }\n      const pluginHandle = pluginHandles[sender];\n      if (!pluginHandle) {\n        Janus.debug('This handle is not attached to this session');\n        return;\n      }\n      pluginHandle.webrtcState(true);\n      return;\n    } else if (json['janus'] === 'hangup') {\n      // A plugin asked the core to hangup a PeerConnection on one of our handles\n      Janus.debug('Got a hangup event on session ' + sessionId);\n      Janus.debug(json);\n      const sender = json['sender'];\n      if (!sender) {\n        Janus.warn('Missing sender...');\n        return;\n      }\n      const pluginHandle = pluginHandles[sender];\n      if (!pluginHandle) {\n        Janus.debug('This handle is not attached to this session');\n        return;\n      }\n      pluginHandle.webrtcState(false, json['reason']);\n      pluginHandle.hangup();\n    } else if (json['janus'] === 'detached') {\n      // A plugin asked the core to detach one of our handles\n      Janus.debug('Got a detached event on session ' + sessionId);\n      Janus.debug(json);\n      const sender = json['sender'];\n      if (!sender) {\n        Janus.warn('Missing sender...');\n        return;\n      }\n      const pluginHandle = pluginHandles[sender];\n      if (!pluginHandle) {\n        // Don't warn here because destroyHandle causes this situation.\n        return;\n      }\n      pluginHandle.ondetached();\n      pluginHandle.detach();\n    } else if (json['janus'] === 'media') {\n      // Media started/stopped flowing\n      Janus.debug('Got a media event on session ' + sessionId);\n      Janus.debug(json);\n      const sender = json['sender'];\n      if (!sender) {\n        Janus.warn('Missing sender...');\n        return;\n      }\n      const pluginHandle = pluginHandles[sender];\n      if (!pluginHandle) {\n        Janus.debug('This handle is not attached to this session');\n        return;\n      }\n      pluginHandle.mediaState(json['type'], json['receiving'], json['mid']);\n    } else if (json['janus'] === 'slowlink') {\n      Janus.debug('Got a slowlink event on session ' + sessionId);\n      Janus.debug(json);\n      // Trouble uplink or downlink\n      const sender = json['sender'];\n      if (!sender) {\n        Janus.warn('Missing sender...');\n        return;\n      }\n      const pluginHandle = pluginHandles[sender];\n      if (!pluginHandle) {\n        Janus.debug('This handle is not attached to this session');\n        return;\n      }\n      pluginHandle.slowLink(json['uplink'], json['lost'], json['mid']);\n    } else if (json['janus'] === 'error') {\n      // Oops, something wrong happened\n      Janus.error('Ooops: ' + json['error'].code + ' ' + json['error'].reason); // FIXME\n      Janus.debug(json);\n      let transaction = json['transaction'];\n      if (transaction) {\n        let reportSuccess = transactions[transaction];\n        if (reportSuccess) {\n          reportSuccess(json);\n        }\n        delete transactions[transaction];\n      }\n      return;\n    } else if (json['janus'] === 'event') {\n      Janus.debug('Got a plugin event on session ' + sessionId);\n      Janus.debug(json);\n      const sender = json['sender'];\n      if (!sender) {\n        Janus.warn('Missing sender...');\n        return;\n      }\n      let plugindata = json['plugindata'];\n      if (!plugindata) {\n        Janus.warn('Missing plugindata...');\n        return;\n      }\n      Janus.debug('  -- Event is coming from ' + sender + ' (' + plugindata['plugin'] + ')');\n      let data = plugindata['data'];\n      Janus.debug(data);\n      const pluginHandle = pluginHandles[sender];\n      if (!pluginHandle) {\n        Janus.warn('This handle is not attached to this session');\n        return;\n      }\n      let jsep = json['jsep'];\n      if (jsep) {\n        Janus.debug('Handling SDP as well...');\n        Janus.debug(jsep);\n      }\n      let callback = pluginHandle.onmessage;\n      if (callback) {\n        Janus.debug('Notifying application...');\n        // Send to callback specified when attaching plugin handle\n        callback(data, jsep);\n      } else {\n        // Send to generic callback (?)\n        Janus.debug('No provided notification callback');\n      }\n    } else if (json['janus'] === 'timeout') {\n      Janus.error('Timeout on session ' + sessionId);\n      Janus.debug(json);\n      if (websockets) {\n        ws.close(3504, 'Gateway timeout');\n      }\n      return;\n    } else {\n      Janus.warn(\"Unknown message/event  '\" + json['janus'] + \"' on session \" + sessionId);\n      Janus.debug(json);\n    }\n  }\n\n  // Private helper to send keep-alive messages on WebSockets\n  function keepAlive() {\n    if (!server || !websockets || !connected) return;\n    wsKeepaliveTimeoutId = setTimeout(keepAlive, keepAlivePeriod);\n    let request = {\n      janus: 'keepalive',\n      session_id: sessionId,\n      transaction: Janus.randomString(12),\n    };\n    if (token) request['token'] = token;\n    if (apisecret) request['apisecret'] = apisecret;\n    ws.send(JSON.stringify(request));\n  }\n\n  // Private method to create a session\n  function createSession(callbacks) {\n    let transaction = Janus.randomString(12);\n    let request = { janus: 'create', transaction: transaction };\n    if (callbacks['reconnect']) {\n      // We're reconnecting, claim the session\n      connected = false;\n      request['janus'] = 'claim';\n      request['session_id'] = sessionId;\n      // If we were using websockets, ignore the old connection\n      if (ws) {\n        ws.onopen = null;\n        ws.onerror = null;\n        ws.onclose = null;\n        if (wsKeepaliveTimeoutId) {\n          clearTimeout(wsKeepaliveTimeoutId);\n          wsKeepaliveTimeoutId = null;\n        }\n      }\n    }\n    if (token) request['token'] = token;\n    if (apisecret) request['apisecret'] = apisecret;\n    if (!server && Janus.isArray(servers)) {\n      // We still need to find a working server from the list we were given\n      server = servers[serversIndex];\n      if (server.indexOf('ws') === 0) {\n        websockets = true;\n        Janus.log('Server #' + (serversIndex + 1) + ': trying WebSockets to contact Janus (' + server + ')');\n      } else {\n        websockets = false;\n        Janus.log('Server #' + (serversIndex + 1) + ': trying REST API to contact Janus (' + server + ')');\n      }\n    }\n    if (websockets) {\n      ws = Janus.newWebSocket(server, 'janus-protocol');\n      wsHandlers = {\n        error: function () {\n          Janus.error('Error connecting to the Janus WebSockets server... ' + server);\n          if (Janus.isArray(servers) && !callbacks['reconnect']) {\n            serversIndex++;\n            if (serversIndex === servers.length) {\n              // We tried all the servers the user gave us and they all failed\n              callbacks.error('Error connecting to any of the provided Janus servers: Is the server down?');\n              return;\n            }\n            // Let's try the next server\n            server = null;\n            setTimeout(function () {\n              createSession(callbacks);\n            }, 200);\n            return;\n          }\n          callbacks.error('Error connecting to the Janus WebSockets server: Is the server down?');\n        },\n\n        open: function () {\n          // We need to be notified about the success\n          transactions[transaction] = function (json) {\n            Janus.debug(json);\n            if (json['janus'] !== 'success') {\n              Janus.error('Ooops: ' + json['error'].code + ' ' + json['error'].reason); // FIXME\n              callbacks.error(json['error'].reason);\n              return;\n            }\n            wsKeepaliveTimeoutId = setTimeout(keepAlive, keepAlivePeriod);\n            connected = true;\n            sessionId = json['session_id'] ? json['session_id'] : json.data['id'];\n            if (callbacks['reconnect']) {\n              Janus.log('Claimed session: ' + sessionId);\n            } else {\n              Janus.log('Created session: ' + sessionId);\n            }\n            Janus.sessions[sessionId] = that;\n            callbacks.success();\n          };\n          ws.send(JSON.stringify(request));\n        },\n\n        message: function (event) {\n          handleEvent(JSON.parse(event.data));\n        },\n\n        close: function () {\n          if (!server || !connected) {\n            return;\n          }\n          connected = false;\n          // FIXME What if this is called when the page is closed?\n          gatewayCallbacks.error('Lost connection to the server (is it down?)');\n        },\n      };\n\n      for (let eventName in wsHandlers) {\n        ws.addEventListener(eventName, wsHandlers[eventName]);\n      }\n\n      return;\n    }\n    Janus.httpAPICall(server, {\n      verb: 'POST',\n      withCredentials: withCredentials,\n      body: request,\n      success: function (json) {\n        Janus.debug(json);\n        if (json['janus'] !== 'success') {\n          Janus.error('Ooops: ' + json['error'].code + ' ' + json['error'].reason); // FIXME\n          callbacks.error(json['error'].reason);\n          return;\n        }\n        connected = true;\n        sessionId = json['session_id'] ? json['session_id'] : json.data['id'];\n        if (callbacks['reconnect']) {\n          Janus.log('Claimed session: ' + sessionId);\n        } else {\n          Janus.log('Created session: ' + sessionId);\n        }\n        Janus.sessions[sessionId] = that;\n        eventHandler();\n        callbacks.success();\n      },\n      error: function (textStatus, errorThrown) {\n        Janus.error(textStatus + ':', errorThrown); // FIXME\n        if (Janus.isArray(servers) && !callbacks['reconnect']) {\n          serversIndex++;\n          if (serversIndex === servers.length) {\n            // We tried all the servers the user gave us and they all failed\n            callbacks.error('Error connecting to any of the provided Janus servers: Is the server down?');\n            return;\n          }\n          // Let's try the next server\n          server = null;\n          setTimeout(function () {\n            createSession(callbacks);\n          }, 200);\n          return;\n        }\n        if (errorThrown === '') callbacks.error(textStatus + ': Is the server down?');\n        else if (errorThrown && errorThrown.error) callbacks.error(textStatus + ': ' + errorThrown.error.message);\n        else callbacks.error(textStatus + ': ' + errorThrown);\n      },\n    });\n  }\n\n  // Private method to get info on the server\n  function getInfo(callbacks) {\n    callbacks = callbacks || {};\n    // FIXME This method triggers a success even when we fail\n    callbacks.success = typeof callbacks.success == 'function' ? callbacks.success : Janus.noop;\n    callbacks.error = typeof callbacks.error == 'function' ? callbacks.error : Janus.noop;\n    Janus.log('Getting info on Janus instance');\n    if (!connected) {\n      Janus.warn('Is the server down? (connected=false)');\n      callbacks.error('Is the server down? (connected=false)');\n      return;\n    }\n    // We just need to send an \"info\" request\n    let transaction = Janus.randomString(12);\n    let request = { janus: 'info', transaction: transaction };\n    if (token) request['token'] = token;\n    if (apisecret) request['apisecret'] = apisecret;\n    if (websockets) {\n      transactions[transaction] = function (json) {\n        Janus.log('Server info:');\n        Janus.debug(json);\n        if (json['janus'] !== 'server_info') {\n          Janus.error('Ooops: ' + json['error'].code + ' ' + json['error'].reason); // FIXME\n        }\n        callbacks.success(json);\n      };\n      ws.send(JSON.stringify(request));\n      return;\n    }\n    Janus.httpAPICall(server, {\n      verb: 'POST',\n      withCredentials: withCredentials,\n      body: request,\n      success: function (json) {\n        Janus.log('Server info:');\n        Janus.debug(json);\n        if (json['janus'] !== 'server_info') {\n          Janus.error('Ooops: ' + json['error'].code + ' ' + json['error'].reason); // FIXME\n        }\n        callbacks.success(json);\n      },\n      error: function (textStatus, errorThrown) {\n        Janus.error(textStatus + ':', errorThrown); // FIXME\n        if (errorThrown === '') callbacks.error(textStatus + ': Is the server down?');\n        else callbacks.error(textStatus + ': ' + errorThrown);\n      },\n    });\n  }\n\n  // Private method to destroy a session\n  function destroySession(callbacks) {\n    callbacks = callbacks || {};\n    // FIXME This method triggers a success even when we fail\n    callbacks.success = typeof callbacks.success == 'function' ? callbacks.success : Janus.noop;\n    callbacks.error = typeof callbacks.error == 'function' ? callbacks.error : Janus.noop;\n    let unload = callbacks.unload === true;\n    let notifyDestroyed = true;\n    if (typeof callbacks.notifyDestroyed !== 'undefined' && callbacks.notifyDestroyed !== null)\n      notifyDestroyed = callbacks.notifyDestroyed === true;\n    let cleanupHandles = callbacks.cleanupHandles === true;\n    Janus.log('Destroying session ' + sessionId + ' (unload=' + unload + ')');\n    if (!sessionId) {\n      Janus.warn('No session to destroy');\n      callbacks.success();\n      if (notifyDestroyed) gatewayCallbacks.destroyed();\n      return;\n    }\n    if (cleanupHandles) {\n      for (let handleId in pluginHandles) destroyHandle(handleId, { noRequest: true });\n    }\n    if (!connected) {\n      Janus.warn('Is the server down? (connected=false)');\n      sessionId = null;\n      callbacks.success();\n      return;\n    }\n    // No need to destroy all handles first, Janus will do that itself\n    let request = { janus: 'destroy', transaction: Janus.randomString(12) };\n    if (token) request['token'] = token;\n    if (apisecret) request['apisecret'] = apisecret;\n    if (unload) {\n      // We're unloading the page: use sendBeacon for HTTP instead,\n      // or just close the WebSocket connection if we're using that\n      if (websockets) {\n        ws.onclose = null;\n        ws.close();\n        ws = null;\n      } else {\n        navigator.sendBeacon(server + '/' + sessionId, JSON.stringify(request));\n      }\n      Janus.log('Destroyed session:');\n      sessionId = null;\n      connected = false;\n      callbacks.success();\n      if (notifyDestroyed) gatewayCallbacks.destroyed();\n      return;\n    }\n    if (websockets) {\n      request['session_id'] = sessionId;\n\n      let unbindWebSocket = function () {\n        for (let eventName in wsHandlers) {\n          ws.removeEventListener(eventName, wsHandlers[eventName]);\n        }\n        ws.removeEventListener('message', onUnbindMessage);\n        ws.removeEventListener('error', onUnbindError);\n        if (wsKeepaliveTimeoutId) {\n          clearTimeout(wsKeepaliveTimeoutId);\n        }\n        ws.close();\n      };\n\n      let onUnbindMessage = function (event) {\n        let data = JSON.parse(event.data);\n        if (data.session_id == request.session_id && data.transaction == request.transaction) {\n          unbindWebSocket();\n          callbacks.success();\n          if (notifyDestroyed) gatewayCallbacks.destroyed();\n        }\n      };\n      let onUnbindError = function () {\n        unbindWebSocket();\n        callbacks.error('Failed to destroy the server: Is the server down?');\n        if (notifyDestroyed) gatewayCallbacks.destroyed();\n      };\n\n      ws.addEventListener('message', onUnbindMessage);\n      ws.addEventListener('error', onUnbindError);\n\n      if (ws.readyState === 1) {\n        ws.send(JSON.stringify(request));\n      } else {\n        onUnbindError();\n      }\n\n      return;\n    }\n    Janus.httpAPICall(server + '/' + sessionId, {\n      verb: 'POST',\n      withCredentials: withCredentials,\n      body: request,\n      success: function (json) {\n        Janus.log('Destroyed session:');\n        Janus.debug(json);\n        sessionId = null;\n        connected = false;\n        if (json['janus'] !== 'success') {\n          Janus.error('Ooops: ' + json['error'].code + ' ' + json['error'].reason); // FIXME\n        }\n        callbacks.success();\n        if (notifyDestroyed) gatewayCallbacks.destroyed();\n      },\n      error: function (textStatus, errorThrown) {\n        Janus.error(textStatus + ':', errorThrown); // FIXME\n        // Reset everything anyway\n        sessionId = null;\n        connected = false;\n        callbacks.success();\n        if (notifyDestroyed) gatewayCallbacks.destroyed();\n      },\n    });\n  }\n\n  // Private method to create a plugin handle\n  function createHandle(callbacks) {\n    callbacks = callbacks || {};\n    callbacks.success = typeof callbacks.success == 'function' ? callbacks.success : Janus.noop;\n    callbacks.error = typeof callbacks.error == 'function' ? callbacks.error : Janus.noop;\n    callbacks.dataChannelOptions = callbacks.dataChannelOptions || {\n      ordered: true,\n    };\n    callbacks.consentDialog = typeof callbacks.consentDialog == 'function' ? callbacks.consentDialog : Janus.noop;\n    callbacks.iceState = typeof callbacks.iceState == 'function' ? callbacks.iceState : Janus.noop;\n    callbacks.mediaState = typeof callbacks.mediaState == 'function' ? callbacks.mediaState : Janus.noop;\n    callbacks.webrtcState = typeof callbacks.webrtcState == 'function' ? callbacks.webrtcState : Janus.noop;\n    callbacks.slowLink = typeof callbacks.slowLink == 'function' ? callbacks.slowLink : Janus.noop;\n    callbacks.onmessage = typeof callbacks.onmessage == 'function' ? callbacks.onmessage : Janus.noop;\n    callbacks.onlocaltrack = typeof callbacks.onlocaltrack == 'function' ? callbacks.onlocaltrack : Janus.noop;\n    callbacks.onremotetrack = typeof callbacks.onremotetrack == 'function' ? callbacks.onremotetrack : Janus.noop;\n    callbacks.ondata = typeof callbacks.ondata == 'function' ? callbacks.ondata : Janus.noop;\n    callbacks.ondataopen = typeof callbacks.ondataopen == 'function' ? callbacks.ondataopen : Janus.noop;\n    callbacks.oncleanup = typeof callbacks.oncleanup == 'function' ? callbacks.oncleanup : Janus.noop;\n    callbacks.ondetached = typeof callbacks.ondetached == 'function' ? callbacks.ondetached : Janus.noop;\n    if (!connected) {\n      Janus.warn('Is the server down? (connected=false)');\n      callbacks.error('Is the server down? (connected=false)');\n      return;\n    }\n    let plugin = callbacks.plugin;\n    if (!plugin) {\n      Janus.error('Invalid plugin');\n      callbacks.error('Invalid plugin');\n      return;\n    }\n    let opaqueId = callbacks.opaqueId;\n    let loopIndex = callbacks.loopIndex;\n    let handleToken = callbacks.token ? callbacks.token : token;\n    let transaction = Janus.randomString(12);\n    let request = {\n      janus: 'attach',\n      plugin: plugin,\n      opaque_id: opaqueId,\n      loop_index: loopIndex,\n      transaction: transaction,\n    };\n    if (handleToken) request['token'] = handleToken;\n    if (apisecret) request['apisecret'] = apisecret;\n    if (websockets) {\n      transactions[transaction] = function (json) {\n        Janus.debug(json);\n        if (json['janus'] !== 'success') {\n          Janus.error('Ooops: ' + json['error'].code + ' ' + json['error'].reason); // FIXME\n          callbacks.error('Ooops: ' + json['error'].code + ' ' + json['error'].reason);\n          return;\n        }\n        let handleId = json.data['id'];\n        Janus.log('Created handle: ' + handleId);\n        let pluginHandle = {\n          session: that,\n          plugin: plugin,\n          id: handleId,\n          token: handleToken,\n          detached: false,\n          webrtcStuff: {\n            started: false,\n            myStream: null,\n            streamExternal: false,\n            mySdp: null,\n            mediaConstraints: null,\n            pc: null,\n            dataChannelOptions: callbacks.dataChannelOptions,\n            dataChannel: {},\n            dtmfSender: null,\n            trickle: true,\n            iceDone: false,\n            bitrate: {},\n          },\n          getId: function () {\n            return handleId;\n          },\n          getPlugin: function () {\n            return plugin;\n          },\n          getVolume: function (mid, result) {\n            return getVolume(handleId, mid, true, result);\n          },\n          getRemoteVolume: function (mid, result) {\n            return getVolume(handleId, mid, true, result);\n          },\n          getLocalVolume: function (mid, result) {\n            return getVolume(handleId, mid, false, result);\n          },\n          isAudioMuted: function (mid) {\n            return isMuted(handleId, mid, false);\n          },\n          muteAudio: function (mid) {\n            return mute(handleId, mid, false, true);\n          },\n          unmuteAudio: function (mid) {\n            return mute(handleId, mid, false, false);\n          },\n          isVideoMuted: function (mid) {\n            return isMuted(handleId, mid, true);\n          },\n          muteVideo: function (mid) {\n            return mute(handleId, mid, true, true);\n          },\n          unmuteVideo: function (mid) {\n            return mute(handleId, mid, true, false);\n          },\n          getBitrate: function (mid) {\n            return getBitrate(handleId, mid);\n          },\n          setMaxBitrate: function (mid, bitrate) {\n            return setBitrate(handleId, mid, bitrate);\n          },\n          send: function (callbacks) {\n            sendMessage(handleId, callbacks);\n          },\n          data: function (callbacks) {\n            sendData(handleId, callbacks);\n          },\n          dtmf: function (callbacks) {\n            sendDtmf(handleId, callbacks);\n          },\n          consentDialog: callbacks.consentDialog,\n          iceState: callbacks.iceState,\n          mediaState: callbacks.mediaState,\n          webrtcState: callbacks.webrtcState,\n          slowLink: callbacks.slowLink,\n          onmessage: callbacks.onmessage,\n          createOffer: function (callbacks) {\n            prepareWebrtc(handleId, true, callbacks);\n          },\n          createAnswer: function (callbacks) {\n            prepareWebrtc(handleId, false, callbacks);\n          },\n          handleRemoteJsep: function (callbacks) {\n            prepareWebrtcPeer(handleId, callbacks);\n          },\n          replaceTracks: function (callbacks) {\n            replaceTracks(handleId, callbacks);\n          },\n          getLocalTracks: function () {\n            return getLocalTracks(handleId);\n          },\n          getRemoteTracks: function () {\n            return getRemoteTracks(handleId);\n          },\n          onlocaltrack: callbacks.onlocaltrack,\n          onremotetrack: callbacks.onremotetrack,\n          ondata: callbacks.ondata,\n          ondataopen: callbacks.ondataopen,\n          oncleanup: callbacks.oncleanup,\n          ondetached: callbacks.ondetached,\n          hangup: function (sendRequest) {\n            cleanupWebrtc(handleId, sendRequest === true);\n          },\n          detach: function (callbacks) {\n            destroyHandle(handleId, callbacks);\n          },\n        };\n        pluginHandles[handleId] = pluginHandle;\n        callbacks.success(pluginHandle);\n      };\n      request['session_id'] = sessionId;\n      ws.send(JSON.stringify(request));\n      return;\n    }\n    Janus.httpAPICall(server + '/' + sessionId, {\n      verb: 'POST',\n      withCredentials: withCredentials,\n      body: request,\n      success: function (json) {\n        Janus.debug(json);\n        if (json['janus'] !== 'success') {\n          Janus.error('Ooops: ' + json['error'].code + ' ' + json['error'].reason); // FIXME\n          callbacks.error('Ooops: ' + json['error'].code + ' ' + json['error'].reason);\n          return;\n        }\n        let handleId = json.data['id'];\n        Janus.log('Created handle: ' + handleId);\n        let pluginHandle = {\n          session: that,\n          plugin: plugin,\n          id: handleId,\n          token: handleToken,\n          detached: false,\n          webrtcStuff: {\n            started: false,\n            myStream: null,\n            streamExternal: false,\n            mySdp: null,\n            mediaConstraints: null,\n            pc: null,\n            dataChannelOptions: callbacks.dataChannelOptions,\n            dataChannel: {},\n            dtmfSender: null,\n            trickle: true,\n            iceDone: false,\n            bitrate: {},\n          },\n          getId: function () {\n            return handleId;\n          },\n          getPlugin: function () {\n            return plugin;\n          },\n          getVolume: function (mid, result) {\n            return getVolume(handleId, mid, true, result);\n          },\n          getRemoteVolume: function (mid, result) {\n            return getVolume(handleId, mid, true, result);\n          },\n          getLocalVolume: function (mid, result) {\n            return getVolume(handleId, mid, false, result);\n          },\n          isAudioMuted: function (mid) {\n            return isMuted(handleId, mid, false);\n          },\n          muteAudio: function (mid) {\n            return mute(handleId, mid, false, true);\n          },\n          unmuteAudio: function (mid) {\n            return mute(handleId, mid, false, false);\n          },\n          isVideoMuted: function (mid) {\n            return isMuted(handleId, mid, true);\n          },\n          muteVideo: function (mid) {\n            return mute(handleId, mid, true, true);\n          },\n          unmuteVideo: function (mid) {\n            return mute(handleId, mid, true, false);\n          },\n          getBitrate: function (mid) {\n            return getBitrate(handleId, mid);\n          },\n          setMaxBitrate: function (mid, bitrate) {\n            return setBitrate(handleId, mid, bitrate);\n          },\n          send: function (callbacks) {\n            sendMessage(handleId, callbacks);\n          },\n          data: function (callbacks) {\n            sendData(handleId, callbacks);\n          },\n          dtmf: function (callbacks) {\n            sendDtmf(handleId, callbacks);\n          },\n          consentDialog: callbacks.consentDialog,\n          iceState: callbacks.iceState,\n          mediaState: callbacks.mediaState,\n          webrtcState: callbacks.webrtcState,\n          slowLink: callbacks.slowLink,\n          onmessage: callbacks.onmessage,\n          createOffer: function (callbacks) {\n            prepareWebrtc(handleId, true, callbacks);\n          },\n          createAnswer: function (callbacks) {\n            prepareWebrtc(handleId, false, callbacks);\n          },\n          handleRemoteJsep: function (callbacks) {\n            prepareWebrtcPeer(handleId, callbacks);\n          },\n          replaceTracks: function (callbacks) {\n            replaceTracks(handleId, callbacks);\n          },\n          getLocalTracks: function () {\n            return getLocalTracks(handleId);\n          },\n          getRemoteTracks: function () {\n            return getRemoteTracks(handleId);\n          },\n          onlocaltrack: callbacks.onlocaltrack,\n          onremotetrack: callbacks.onremotetrack,\n          ondata: callbacks.ondata,\n          ondataopen: callbacks.ondataopen,\n          oncleanup: callbacks.oncleanup,\n          ondetached: callbacks.ondetached,\n          hangup: function (sendRequest) {\n            cleanupWebrtc(handleId, sendRequest === true);\n          },\n          detach: function (callbacks) {\n            destroyHandle(handleId, callbacks);\n          },\n        };\n        pluginHandles[handleId] = pluginHandle;\n        callbacks.success(pluginHandle);\n      },\n      error: function (textStatus, errorThrown) {\n        Janus.error(textStatus + ':', errorThrown); // FIXME\n        if (errorThrown === '') callbacks.error(textStatus + ': Is the server down?');\n        else callbacks.error(textStatus + ': ' + errorThrown);\n      },\n    });\n  }\n\n  // Private method to send a message\n  function sendMessage(handleId, callbacks) {\n    callbacks = callbacks || {};\n    callbacks.success = typeof callbacks.success == 'function' ? callbacks.success : Janus.noop;\n    callbacks.error = typeof callbacks.error == 'function' ? callbacks.error : Janus.noop;\n    if (!connected) {\n      Janus.warn('Is the server down? (connected=false)');\n      callbacks.error('Is the server down? (connected=false)');\n      return;\n    }\n    let pluginHandle = pluginHandles[handleId];\n    if (!pluginHandle || !pluginHandle.webrtcStuff) {\n      Janus.warn('Invalid handle');\n      callbacks.error('Invalid handle');\n      return;\n    }\n    let message = callbacks.message;\n    let jsep = callbacks.jsep;\n    let transaction = Janus.randomString(12);\n    let request = { janus: 'message', body: message, transaction: transaction };\n    if (pluginHandle.token) request['token'] = pluginHandle.token;\n    if (apisecret) request['apisecret'] = apisecret;\n    if (jsep) {\n      request.jsep = {\n        type: jsep.type,\n        sdp: jsep.sdp,\n      };\n      if (jsep.e2ee) request.jsep.e2ee = true;\n      if (jsep.rid_order === 'hml' || jsep.rid_order === 'lmh') request.jsep.rid_order = jsep.rid_order;\n      if (jsep.force_relay) request.jsep.force_relay = true;\n    }\n    Janus.debug('Sending message to plugin (handle=' + handleId + '):');\n    Janus.debug(request);\n    if (websockets) {\n      request['session_id'] = sessionId;\n      request['handle_id'] = handleId;\n      transactions[transaction] = function (json) {\n        Janus.debug('Message sent!');\n        Janus.debug(json);\n        if (json['janus'] === 'success') {\n          // We got a success, must have been a synchronous transaction\n          let plugindata = json['plugindata'];\n          if (!plugindata) {\n            Janus.warn('Request succeeded, but missing plugindata...');\n            callbacks.success();\n            return;\n          }\n          Janus.log('Synchronous transaction successful (' + plugindata['plugin'] + ')');\n          let data = plugindata['data'];\n          Janus.debug(data);\n          callbacks.success(data);\n          return;\n        } else if (json['janus'] !== 'ack') {\n          // Not a success and not an ack, must be an error\n          if (json['error']) {\n            Janus.error('Ooops: ' + json['error'].code + ' ' + json['error'].reason); // FIXME\n            callbacks.error(json['error'].code + ' ' + json['error'].reason);\n          } else {\n            Janus.error('Unknown error'); // FIXME\n            callbacks.error('Unknown error');\n          }\n          return;\n        }\n        // If we got here, the plugin decided to handle the request asynchronously\n        callbacks.success();\n      };\n      ws.send(JSON.stringify(request));\n      return;\n    }\n    Janus.httpAPICall(server + '/' + sessionId + '/' + handleId, {\n      verb: 'POST',\n      withCredentials: withCredentials,\n      body: request,\n      success: function (json) {\n        Janus.debug('Message sent!');\n        Janus.debug(json);\n        if (json['janus'] === 'success') {\n          // We got a success, must have been a synchronous transaction\n          let plugindata = json['plugindata'];\n          if (!plugindata) {\n            Janus.warn('Request succeeded, but missing plugindata...');\n            callbacks.success();\n            return;\n          }\n          Janus.log('Synchronous transaction successful (' + plugindata['plugin'] + ')');\n          let data = plugindata['data'];\n          Janus.debug(data);\n          callbacks.success(data);\n          return;\n        } else if (json['janus'] !== 'ack') {\n          // Not a success and not an ack, must be an error\n          if (json['error']) {\n            Janus.error('Ooops: ' + json['error'].code + ' ' + json['error'].reason); // FIXME\n            callbacks.error(json['error'].code + ' ' + json['error'].reason);\n          } else {\n            Janus.error('Unknown error'); // FIXME\n            callbacks.error('Unknown error');\n          }\n          return;\n        }\n        // If we got here, the plugin decided to handle the request asynchronously\n        callbacks.success();\n      },\n      error: function (textStatus, errorThrown) {\n        Janus.error(textStatus + ':', errorThrown); // FIXME\n        callbacks.error(textStatus + ': ' + errorThrown);\n      },\n    });\n  }\n\n  // Private method to send a trickle candidate\n  function sendTrickleCandidate(handleId, candidate) {\n    if (!connected) {\n      Janus.warn('Is the server down? (connected=false)');\n      return;\n    }\n    let pluginHandle = pluginHandles[handleId];\n    if (!pluginHandle || !pluginHandle.webrtcStuff) {\n      Janus.warn('Invalid handle');\n      return;\n    }\n    let request = {\n      janus: 'trickle',\n      candidate: candidate,\n      transaction: Janus.randomString(12),\n    };\n    if (pluginHandle.token) request['token'] = pluginHandle.token;\n    if (apisecret) request['apisecret'] = apisecret;\n    Janus.vdebug('Sending trickle candidate (handle=' + handleId + '):');\n    Janus.vdebug(request);\n    if (websockets) {\n      request['session_id'] = sessionId;\n      request['handle_id'] = handleId;\n      ws.send(JSON.stringify(request));\n      return;\n    }\n    Janus.httpAPICall(server + '/' + sessionId + '/' + handleId, {\n      verb: 'POST',\n      withCredentials: withCredentials,\n      body: request,\n      success: function (json) {\n        Janus.vdebug('Candidate sent!');\n        Janus.vdebug(json);\n        if (json['janus'] !== 'ack') {\n          Janus.error('Ooops: ' + json['error'].code + ' ' + json['error'].reason); // FIXME\n          return;\n        }\n      },\n      error: function (textStatus, errorThrown) {\n        Janus.error(textStatus + ':', errorThrown); // FIXME\n      },\n    });\n  }\n\n  // Private method to create a data channel\n  function createDataChannel(handleId, dclabel, dcprotocol, incoming, pendingData) {\n    let pluginHandle = pluginHandles[handleId];\n    if (!pluginHandle || !pluginHandle.webrtcStuff) {\n      Janus.warn('Invalid handle');\n      return;\n    }\n    let config = pluginHandle.webrtcStuff;\n    if (!config.pc) {\n      Janus.warn('Invalid PeerConnection');\n      return;\n    }\n    let onDataChannelMessage = function (event) {\n      Janus.log('Received message on data channel:', event);\n      let label = event.target.label;\n      pluginHandle.ondata(event.data, label);\n    };\n    let onDataChannelStateChange = function (event) {\n      Janus.log('Received state change on data channel:', event);\n      let label = event.target.label;\n      let protocol = event.target.protocol;\n      let dcState = config.dataChannel[label] ? config.dataChannel[label].readyState : 'null';\n      Janus.log('State change on <' + label + '> data channel: ' + dcState);\n      if (dcState === 'open') {\n        // Any pending messages to send?\n        if (config.dataChannel[label].pending && config.dataChannel[label].pending.length > 0) {\n          Janus.log('Sending pending messages on <' + label + '>:', config.dataChannel[label].pending.length);\n          for (let data of config.dataChannel[label].pending) {\n            Janus.log('Sending data on data channel <' + label + '>');\n            Janus.debug(data);\n            config.dataChannel[label].send(data);\n          }\n          config.dataChannel[label].pending = [];\n        }\n        // Notify the open data channel\n        pluginHandle.ondataopen(label, protocol);\n      }\n    };\n    let onDataChannelError = function (error) {\n      Janus.error('Got error on data channel:', error);\n      // TODO\n    };\n    if (!incoming) {\n      // FIXME Add options (ordered, maxRetransmits, etc.)\n      let dcoptions = config.dataChannelOptions;\n      if (dcprotocol) dcoptions.protocol = dcprotocol;\n      config.dataChannel[dclabel] = config.pc.createDataChannel(dclabel, dcoptions);\n    } else {\n      // The channel was created by Janus\n      config.dataChannel[dclabel] = incoming;\n    }\n    config.dataChannel[dclabel].onmessage = onDataChannelMessage;\n    config.dataChannel[dclabel].onopen = onDataChannelStateChange;\n    config.dataChannel[dclabel].onclose = onDataChannelStateChange;\n    config.dataChannel[dclabel].onerror = onDataChannelError;\n    config.dataChannel[dclabel].pending = [];\n    if (pendingData) config.dataChannel[dclabel].pending.push(pendingData);\n  }\n\n  // Private method to send a data channel message\n  function sendData(handleId, callbacks) {\n    callbacks = callbacks || {};\n    callbacks.success = typeof callbacks.success == 'function' ? callbacks.success : Janus.noop;\n    callbacks.error = typeof callbacks.error == 'function' ? callbacks.error : Janus.noop;\n    let pluginHandle = pluginHandles[handleId];\n    if (!pluginHandle || !pluginHandle.webrtcStuff) {\n      Janus.warn('Invalid handle');\n      callbacks.error('Invalid handle');\n      return;\n    }\n    let config = pluginHandle.webrtcStuff;\n    let data = callbacks.text || callbacks.data;\n    if (!data) {\n      Janus.warn('Invalid data');\n      callbacks.error('Invalid data');\n      return;\n    }\n    let label = callbacks.label ? callbacks.label : Janus.dataChanDefaultLabel;\n    if (!config.dataChannel[label]) {\n      // Create new data channel and wait for it to open\n      createDataChannel(handleId, label, callbacks.protocol, false, data, callbacks.protocol);\n      callbacks.success();\n      return;\n    }\n    if (config.dataChannel[label].readyState !== 'open') {\n      config.dataChannel[label].pending.push(data);\n      callbacks.success();\n      return;\n    }\n    Janus.log('Sending data on data channel <' + label + '>');\n    Janus.debug(data);\n    config.dataChannel[label].send(data);\n    callbacks.success();\n  }\n\n  // Private method to send a DTMF tone\n  function sendDtmf(handleId, callbacks) {\n    callbacks = callbacks || {};\n    callbacks.success = typeof callbacks.success == 'function' ? callbacks.success : Janus.noop;\n    callbacks.error = typeof callbacks.error == 'function' ? callbacks.error : Janus.noop;\n    let pluginHandle = pluginHandles[handleId];\n    if (!pluginHandle || !pluginHandle.webrtcStuff) {\n      Janus.warn('Invalid handle');\n      callbacks.error('Invalid handle');\n      return;\n    }\n    let config = pluginHandle.webrtcStuff;\n    if (!config.dtmfSender) {\n      // Create the DTMF sender the proper way, if possible\n      if (config.pc) {\n        let senders = config.pc.getSenders();\n        let audioSender = senders.find(function (sender) {\n          return sender.track && sender.track.kind === 'audio';\n        });\n        if (!audioSender) {\n          Janus.warn('Invalid DTMF configuration (no audio track)');\n          callbacks.error('Invalid DTMF configuration (no audio track)');\n          return;\n        }\n        config.dtmfSender = audioSender.dtmf;\n        if (config.dtmfSender) {\n          Janus.log('Created DTMF Sender');\n          config.dtmfSender.ontonechange = function (tone) {\n            Janus.debug('Sent DTMF tone: ' + tone.tone);\n          };\n        }\n      }\n      if (!config.dtmfSender) {\n        Janus.warn('Invalid DTMF configuration');\n        callbacks.error('Invalid DTMF configuration');\n        return;\n      }\n    }\n    let dtmf = callbacks.dtmf;\n    if (!dtmf) {\n      Janus.warn('Invalid DTMF parameters');\n      callbacks.error('Invalid DTMF parameters');\n      return;\n    }\n    let tones = dtmf.tones;\n    if (!tones) {\n      Janus.warn('Invalid DTMF string');\n      callbacks.error('Invalid DTMF string');\n      return;\n    }\n    let duration = typeof dtmf.duration === 'number' ? dtmf.duration : 500; // We choose 500ms as the default duration for a tone\n    let gap = typeof dtmf.gap === 'number' ? dtmf.gap : 50; // We choose 50ms as the default gap between tones\n    Janus.debug('Sending DTMF string ' + tones + ' (duration ' + duration + 'ms, gap ' + gap + 'ms)');\n    config.dtmfSender.insertDTMF(tones, duration, gap);\n    callbacks.success();\n  }\n\n  // Private method to destroy a plugin handle\n  function destroyHandle(handleId, callbacks) {\n    callbacks = callbacks || {};\n    callbacks.success = typeof callbacks.success == 'function' ? callbacks.success : Janus.noop;\n    callbacks.error = typeof callbacks.error == 'function' ? callbacks.error : Janus.noop;\n    let noRequest = callbacks.noRequest === true;\n    Janus.log('Destroying handle ' + handleId + ' (only-locally=' + noRequest + ')');\n    cleanupWebrtc(handleId);\n    let pluginHandle = pluginHandles[handleId];\n    if (!pluginHandle || pluginHandle.detached) {\n      // Plugin was already detached by Janus, calling detach again will return a handle not found error, so just exit here\n      delete pluginHandles[handleId];\n      callbacks.success();\n      return;\n    }\n    pluginHandle.detached = true;\n    if (noRequest) {\n      // We're only removing the handle locally\n      delete pluginHandles[handleId];\n      callbacks.success();\n      return;\n    }\n    if (!connected) {\n      Janus.warn('Is the server down? (connected=false)');\n      callbacks.error('Is the server down? (connected=false)');\n      return;\n    }\n    let request = { janus: 'detach', transaction: Janus.randomString(12) };\n    if (pluginHandle.token) request['token'] = pluginHandle.token;\n    if (apisecret) request['apisecret'] = apisecret;\n    if (websockets) {\n      request['session_id'] = sessionId;\n      request['handle_id'] = handleId;\n      ws.send(JSON.stringify(request));\n      delete pluginHandles[handleId];\n      callbacks.success();\n      return;\n    }\n    Janus.httpAPICall(server + '/' + sessionId + '/' + handleId, {\n      verb: 'POST',\n      withCredentials: withCredentials,\n      body: request,\n      success: function (json) {\n        Janus.log('Destroyed handle:');\n        Janus.debug(json);\n        if (json['janus'] !== 'success') {\n          Janus.error('Ooops: ' + json['error'].code + ' ' + json['error'].reason); // FIXME\n        }\n        delete pluginHandles[handleId];\n        callbacks.success();\n      },\n      error: function (textStatus, errorThrown) {\n        Janus.error(textStatus + ':', errorThrown); // FIXME\n        // We cleanup anyway\n        delete pluginHandles[handleId];\n        callbacks.success();\n      },\n    });\n  }\n\n  // WebRTC stuff\n  // Helper function to create a new PeerConnection, if we need one\n  function createPeerconnectionIfNeeded(handleId, callbacks) {\n    let pluginHandle = pluginHandles[handleId];\n    if (!pluginHandle || !pluginHandle.webrtcStuff) {\n      Janus.warn('Invalid handle');\n      throw 'Invalid handle';\n    }\n    let config = pluginHandle.webrtcStuff;\n    if (config.pc) {\n      // Nothing to do, we have a PeerConnection already\n      return;\n    }\n    let pc_config = {\n      iceServers: iceServers,\n      iceTransportPolicy: iceTransportPolicy,\n      bundlePolicy: bundlePolicy,\n    };\n    pc_config.sdpSemantics = 'unified-plan';\n    // Check if a sender or receiver transform has been provided\n    let insertableStreams = false;\n    if (callbacks.tracks) {\n      for (let track of callbacks.tracks) {\n        if (track.transforms && (track.transforms.sender || track.transforms.receiver)) {\n          insertableStreams = true;\n          break;\n        }\n      }\n    }\n    if (\n      RTCRtpSender &&\n      (RTCRtpSender.prototype.createEncodedStreams ||\n        (RTCRtpSender.prototype.createEncodedAudioStreams && RTCRtpSender.prototype.createEncodedVideoStreams)) &&\n      insertableStreams\n    ) {\n      config.insertableStreams = true;\n      pc_config.forceEncodedAudioInsertableStreams = true;\n      pc_config.forceEncodedVideoInsertableStreams = true;\n      pc_config.encodedInsertableStreams = true;\n    }\n    Janus.log('Creating PeerConnection');\n    config.pc = new RTCPeerConnection(pc_config);\n    Janus.debug(config.pc);\n    if (config.pc.getStats) {\n      // FIXME\n      config.volume = {};\n      config.bitrate.value = '0 kbits/sec';\n    }\n    Janus.log('Preparing local SDP and gathering candidates (trickle=' + config.trickle + ')');\n    config.pc.oniceconnectionstatechange = function () {\n      if (config.pc) pluginHandle.iceState(config.pc.iceConnectionState);\n    };\n    config.pc.onicecandidate = function (event) {\n      if (!event.candidate || (event.candidate.candidate && event.candidate.candidate.indexOf('endOfCandidates') > 0)) {\n        Janus.log('End of candidates.');\n        config.iceDone = true;\n        if (config.trickle === true) {\n          // Notify end of candidates\n          sendTrickleCandidate(handleId, { completed: true });\n        } else {\n          // No trickle, time to send the complete SDP (including all candidates)\n          sendSDP(handleId, callbacks);\n        }\n      } else {\n        // JSON.stringify doesn't work on some WebRTC objects anymore\n        // See https://code.google.com/p/chromium/issues/detail?id=467366\n        let candidate = {\n          candidate: event.candidate.candidate,\n          sdpMid: event.candidate.sdpMid,\n          sdpMLineIndex: event.candidate.sdpMLineIndex,\n        };\n        if (config.trickle === true) {\n          // Send candidate\n          sendTrickleCandidate(handleId, candidate);\n        }\n      }\n    };\n    config.pc.ontrack = function (event) {\n      Janus.log('Handling Remote Track', event);\n      if (!event.streams) return;\n      if (!event.track) return;\n      // Notify about the new track event\n      let mid = event.transceiver ? event.transceiver.mid || event.transceiver._mid : event.track.id;\n      try {\n        pluginHandle.onremotetrack(event.track, mid, true, {\n          reason: 'created',\n        });\n      } catch (e) {\n        Janus.error('Error calling onremotetrack', e);\n      }\n      if (event.track.onended) return;\n      let trackMutedTimeoutId = null;\n      Janus.log('Adding onended callback to track:', event.track);\n      event.track.onended = function (ev) {\n        Janus.log('Remote track removed:', ev);\n        clearTimeout(trackMutedTimeoutId);\n        // Notify the application\n        let transceivers = config.pc ? config.pc.getTransceivers() : null;\n        let transceiver = transceivers\n          ? transceivers.find((transceiver) => {\n            const receiver = transceiver.receiver || transceiver._receiver;\n            const track = receiver.track || receiver._track;\n            return track === ev.target;\n          })\n          : null;\n        let mid = transceiver ? transceiver.mid || transceiver._mid : ev.target.id;\n        try {\n          pluginHandle.onremotetrack(ev.target, mid, false, {\n            reason: 'ended',\n          });\n        } catch (e) {\n          Janus.error('Error calling onremotetrack on removal', e);\n        }\n      };\n      event.track.onmute = function (ev) {\n        Janus.log('Remote track muted:', ev);\n        if (!trackMutedTimeoutId) {\n          const target = ev.target;\n          trackMutedTimeoutId = setTimeout(function () {\n            Janus.log('Removing remote track');\n            // Notify the application the track is gone\n            let transceivers = config.pc ? config.pc.getTransceivers() : null;\n            let transceiver = transceivers\n              ? transceivers.find((transceiver) => {\n                const receiver = transceiver.receiver || transceiver._receiver;\n                const track = receiver.track || receiver._track;\n                return track === target;\n              })\n              : null;\n            let mid = transceiver ? transceiver.mid || transceiver._mid : target.id;\n            try {\n              pluginHandle.onremotetrack(target, mid, false, {\n                reason: 'mute',\n              });\n            } catch (e) {\n              Janus.error('Error calling onremotetrack on mute', e);\n            }\n            trackMutedTimeoutId = null;\n            // Chrome seems to raise mute events only at multiples of 834ms;\n            // we set the timeout to three times this value (rounded to 840ms);\n          }, 3 * 840);\n        }\n      };\n      event.track.onunmute = function (ev) {\n        Janus.log('Remote track flowing again:', ev);\n        if (trackMutedTimeoutId != null) {\n          clearTimeout(trackMutedTimeoutId);\n          trackMutedTimeoutId = null;\n        } else {\n          try {\n            // Notify the application the track is back\n            let transceivers = config.pc ? config.pc.getTransceivers() : null;\n            let transceiver = transceivers\n              ? transceivers.find((transceiver) => {\n                const receiver = transceiver.receiver || transceiver._receiver;\n                const track = receiver.track || receiver._track;\n                return track === ev.target;\n              })\n              : null;\n            let mid = transceiver ? transceiver.mid || transceiver._mid : ev.target.id;\n            pluginHandle.onremotetrack(ev.target, mid, true, {\n              reason: 'unmute',\n            });\n          } catch (e) {\n            Janus.error('Error calling onremotetrack on unmute', e);\n          }\n        }\n      };\n    };\n  }\n\n  // Helper function used when creating either an offer or answer: it\n  // prepares what needs to be prepared, including creating a new\n  // PeerConnection (if needed) and updating the tracks configuration,\n  // before invoking the function to actually generate the offer/answer\n  async function prepareWebrtc(handleId, offer, callbacks) {\n    callbacks = callbacks || {};\n    callbacks.success = typeof callbacks.success == 'function' ? callbacks.success : Janus.noop;\n    callbacks.error = typeof callbacks.error == 'function' ? callbacks.error : webrtcError;\n    let jsep = callbacks.jsep;\n    if (offer && jsep) {\n      Janus.error('Provided a JSEP to a createOffer');\n      callbacks.error('Provided a JSEP to a createOffer');\n      return;\n    } else if (!offer && (!jsep || !jsep.type || !jsep.sdp)) {\n      Janus.error('A valid JSEP is required for createAnswer');\n      callbacks.error('A valid JSEP is required for createAnswer');\n      return;\n    }\n    // If the deprecated media was provided instead of tracks, translate it\n    if (callbacks.media && !callbacks.tracks) {\n      callbacks.tracks = Janus.mediaToTracks(callbacks.media);\n      if (callbacks.simulcast === true || callbacks.simulcast2 === true || callbacks.svc) {\n        // Find the video track and add simulcast/SVC info there\n        for (let track of callbacks.tracks) {\n          if (track.type === 'video') {\n            if (callbacks.simulcast === true || callbacks.simulcast2 === true) track.simulcast = true;\n            else if (callbacks.svc) track.svc = callbacks.svc;\n            break;\n          }\n        }\n      }\n      Janus.warn('Deprecated media object passed, use tracks instead. Automatically translated to:', callbacks.tracks);\n    }\n    // Check that callbacks.array is a valid array\n    if (callbacks.tracks && !Array.isArray(callbacks.tracks)) {\n      Janus.error('Tracks must be an array');\n      callbacks.error('Tracks must be an array');\n      return;\n    }\n    // Get the plugin handle\n    let pluginHandle = pluginHandles[handleId];\n    if (!pluginHandle || !pluginHandle.webrtcStuff) {\n      Janus.warn('Invalid handle');\n      callbacks.error('Invalid handle');\n      return;\n    }\n    let config = pluginHandle.webrtcStuff;\n    config.trickle = isTrickleEnabled(callbacks.trickle);\n    try {\n      // Create a PeerConnection, if needed\n      createPeerconnectionIfNeeded(handleId, callbacks);\n      if (offer) {\n        // Capture devices and setup tracks, if needed\n        await captureDevices(handleId, callbacks);\n      }\n      // Create offer or answer now (depending on the context)\n      if (!jsep) {\n        let offer = await createOffer(handleId, callbacks);\n        callbacks.success(offer);\n      } else {\n        await config.pc.setRemoteDescription(jsep);\n        Janus.log('Remote description accepted!');\n        config.remoteSdp = jsep.sdp;\n        // Any trickle candidate we cached?\n        if (config.candidates && config.candidates.length > 0) {\n          for (let i = 0; i < config.candidates.length; i++) {\n            let candidate = config.candidates[i];\n            Janus.debug('Adding remote candidate:', candidate);\n            if (!candidate || candidate.completed === true) {\n              // end-of-candidates\n              config.pc.addIceCandidate(Janus.endOfCandidates);\n            } else {\n              // New candidate\n              config.pc.addIceCandidate(candidate);\n            }\n          }\n          config.candidates = [];\n        }\n        // Capture devices and setup tracks, if needed\n        await captureDevices(handleId, callbacks);\n        // Create the answer now\n        let answer = await createAnswer(handleId, callbacks);\n        callbacks.success(answer);\n      }\n    } catch (err) {\n      Janus.error(err);\n      callbacks.error(err);\n    }\n  }\n\n  function prepareWebrtcPeer(handleId, callbacks) {\n    callbacks = callbacks || {};\n    callbacks.success = typeof callbacks.success == 'function' ? callbacks.success : Janus.noop;\n    callbacks.error = typeof callbacks.error == 'function' ? callbacks.error : webrtcError;\n    callbacks.customizeSdp = typeof callbacks.customizeSdp == 'function' ? callbacks.customizeSdp : Janus.noop;\n    let jsep = callbacks.jsep;\n    let pluginHandle = pluginHandles[handleId];\n    if (!pluginHandle || !pluginHandle.webrtcStuff) {\n      Janus.warn('Invalid handle');\n      callbacks.error('Invalid handle');\n      return;\n    }\n    let config = pluginHandle.webrtcStuff;\n    if (jsep) {\n      if (!config.pc) {\n        Janus.warn('Wait, no PeerConnection?? if this is an answer, use createAnswer and not handleRemoteJsep');\n        callbacks.error('No PeerConnection: if this is an answer, use createAnswer and not handleRemoteJsep');\n        return;\n      }\n      callbacks.customizeSdp(jsep);\n      config.pc.setRemoteDescription(jsep).then(function () {\n        Janus.log('Remote description accepted!');\n        config.remoteSdp = jsep.sdp;\n        // Any trickle candidate we cached?\n        if (config.candidates && config.candidates.length > 0) {\n          for (let i = 0; i < config.candidates.length; i++) {\n            let candidate = config.candidates[i];\n            Janus.debug('Adding remote candidate:', candidate);\n            if (!candidate || candidate.completed === true) {\n              // end-of-candidates\n              config.pc.addIceCandidate(Janus.endOfCandidates);\n            } else {\n              // New candidate\n              config.pc.addIceCandidate(candidate);\n            }\n          }\n          config.candidates = [];\n        }\n        // Done\n        callbacks.success();\n      }, callbacks.error);\n    } else {\n      callbacks.error('Invalid JSEP');\n    }\n  }\n\n  async function createOffer(handleId, callbacks) {\n    callbacks = callbacks || {};\n    callbacks.customizeSdp = typeof callbacks.customizeSdp == 'function' ? callbacks.customizeSdp : Janus.noop;\n    let pluginHandle = pluginHandles[handleId];\n    if (!pluginHandle || !pluginHandle.webrtcStuff) {\n      Janus.warn('Invalid handle');\n      throw 'Invalid handle';\n    }\n    let config = pluginHandle.webrtcStuff;\n    Janus.log('Creating offer (iceDone=' + config.iceDone + ')');\n    // https://code.google.com/p/webrtc/issues/detail?id=3508\n    let mediaConstraints = {};\n    let iceRestart = callbacks.iceRestart === true;\n    // If we need an ICE restart, set the related constraint\n    if (iceRestart) mediaConstraints.iceRestart = true;\n    Janus.debug(mediaConstraints);\n    let offer = await config.pc.createOffer(mediaConstraints);\n    Janus.debug(offer);\n    // JSON.stringify doesn't work on some WebRTC objects anymore\n    // See https://code.google.com/p/chromium/issues/detail?id=467366\n    let jsep = {\n      type: 'offer',\n      sdp: offer.sdp,\n    };\n    callbacks.customizeSdp(jsep);\n    offer.sdp = jsep.sdp;\n    Janus.log('Setting local description');\n    config.mySdp = {\n      type: 'offer',\n      sdp: offer.sdp,\n    };\n    await config.pc.setLocalDescription(offer);\n    config.mediaConstraints = mediaConstraints;\n    if (!config.iceDone && !config.trickle) {\n      // FIXME Don't do anything until we have all candidates\n      Janus.log('Waiting for all candidates...');\n      return null;\n    }\n    // If transforms are present, notify Janus that the media is end-to-end encrypted\n    if (config.insertableStreams) offer.e2ee = true;\n    return offer;\n  }\n\n  async function createAnswer(handleId, callbacks) {\n    callbacks = callbacks || {};\n    callbacks.customizeSdp = typeof callbacks.customizeSdp == 'function' ? callbacks.customizeSdp : Janus.noop;\n    let pluginHandle = pluginHandles[handleId];\n    if (!pluginHandle || !pluginHandle.webrtcStuff) {\n      Janus.warn('Invalid handle');\n      throw 'Invalid handle';\n    }\n    let config = pluginHandle.webrtcStuff;\n    Janus.log('Creating answer (iceDone=' + config.iceDone + ')');\n    let answer = await config.pc.createAnswer();\n    Janus.debug(answer);\n    // JSON.stringify doesn't work on some WebRTC objects anymore\n    // See https://code.google.com/p/chromium/issues/detail?id=467366\n    let jsep = {\n      type: 'answer',\n      sdp: answer.sdp,\n    };\n    callbacks.customizeSdp(jsep);\n    answer.sdp = jsep.sdp;\n    Janus.log('Setting local description');\n    config.mySdp = {\n      type: 'answer',\n      sdp: answer.sdp,\n    };\n    await config.pc.setLocalDescription(answer);\n    if (!config.iceDone && !config.trickle) {\n      // FIXME Don't do anything until we have all candidates\n      Janus.log('Waiting for all candidates...');\n      return null;\n    }\n    // If transforms are present, notify Janus that the media is end-to-end encrypted\n    if (config.insertableStreams) answer.e2ee = true;\n    return answer;\n  }\n\n  function sendSDP(handleId, callbacks) {\n    callbacks = callbacks || {};\n    callbacks.success = typeof callbacks.success == 'function' ? callbacks.success : Janus.noop;\n    callbacks.error = typeof callbacks.error == 'function' ? callbacks.error : Janus.noop;\n    let pluginHandle = pluginHandles[handleId];\n    if (!pluginHandle || !pluginHandle.webrtcStuff) {\n      Janus.warn('Invalid handle, not sending anything');\n      return;\n    }\n    let config = pluginHandle.webrtcStuff;\n    Janus.log('Sending offer/answer SDP...');\n    if (!config.mySdp) {\n      Janus.warn('Local SDP instance is invalid, not sending anything...');\n      return;\n    }\n    config.mySdp = {\n      type: config.pc.localDescription.type,\n      sdp: config.pc.localDescription.sdp,\n    };\n    if (config.trickle === false) config.mySdp['trickle'] = false;\n    Janus.debug(callbacks);\n    config.sdpSent = true;\n    callbacks.success(config.mySdp);\n  }\n\n  async function replaceTracks(handleId, callbacks) {\n    callbacks = callbacks || {};\n    callbacks.success = typeof callbacks.success == 'function' ? callbacks.success : Janus.noop;\n    callbacks.error = typeof callbacks.error == 'function' ? callbacks.error : Janus.noop;\n    // Check that callbacks.array is a valid array\n    if (callbacks.tracks && !Array.isArray(callbacks.tracks)) {\n      Janus.error('Tracks must be an array');\n      callbacks.error('Tracks must be an array');\n      return;\n    }\n    // Add the replace:true if it's missing\n    for (let track of callbacks.tracks) {\n      if (track.add || (!track.replace && !track.remove)) track.replace = true;\n    }\n    try {\n      await captureDevices(handleId, callbacks);\n      callbacks.success();\n    } catch (err) {\n      Janus.error(err);\n      callbacks.error(err);\n    }\n  }\n\n  async function captureDevices(handleId, callbacks) {\n    let pluginHandle = pluginHandles[handleId];\n    if (!pluginHandle || !pluginHandle.webrtcStuff) {\n      Janus.warn('Invalid handle, not sending anything');\n      throw 'Invalid handle';\n    }\n    let config = pluginHandle.webrtcStuff;\n    if (!config.pc) {\n      Janus.warn('Invalid PeerConnection');\n      throw 'Invalid PeerConnection';\n    }\n    let tracks = callbacks.tracks;\n    if (!tracks || !Array.isArray(tracks) || tracks.length === 0) {\n      // Nothing to do\n      return;\n    }\n    let openedConsentDialog = false;\n    // Check if we can/should group getUserMedia calls\n    let groups = {};\n    for (let track of tracks) {\n      delete track.gumGroup;\n      if (!track.type || !['audio', 'video'].includes(track.type)) continue;\n      if (!track.capture || track.capture instanceof MediaStreamTrack) continue;\n      let group = track.group ? track.group : 'default';\n      if (!groups[group]) groups[group] = {};\n      if (groups[group][track.type]) continue;\n      track.gumGroup = group;\n      groups[group][track.type] = track;\n    }\n    let keys = Object.keys(groups);\n    for (let key of keys) {\n      let group = groups[key];\n      if (!group.audio || !group.video) {\n        if (group.audio) delete group.audio.gumGroup;\n        if (group.video) delete group.video.gumGroup;\n        delete groups[key];\n      }\n    }\n    let answer = callbacks.jsep ? true : false;\n    for (let track of tracks) {\n      if (!track.type) {\n        Janus.warn('Missing track type:', track);\n        continue;\n      }\n      if (track.type === 'data') {\n        // Easy enough: create a datachannel if we don't have one already\n        if (config.pc.ondatachannel) {\n          Janus.warn('Data channel exists already, not creating another one');\n          continue;\n        }\n        Janus.log('Creating default data channel');\n        createDataChannel(handleId, Janus.dataChanDefaultLabel, null, false);\n        config.pc.ondatachannel = function (event) {\n          Janus.log('Data channel created by Janus:', event);\n          createDataChannel(handleId, event.channel.label, event.channel.protocol, event.channel);\n        };\n        continue;\n      }\n      if (\n        typeof track.add === 'undefined' &&\n        track.add === null &&\n        typeof track.remove === 'undefined' &&\n        track.remove === null &&\n        typeof track.replace === 'undefined' &&\n        track.replace === null\n      ) {\n        // Let's default to 'add'\n        track.add = true;\n      }\n      if ((track.add && track.remove) || (track.add && track.remove && track.replace)) {\n        Janus.warn('Conflicting actions for track, ignoring:', track);\n        continue;\n      }\n      if (track.add && track.replace) {\n        Janus.warn('Both add and replace provided, falling back to replace:', track);\n        delete track.add;\n      } else if (track.remove && track.replace) {\n        Janus.warn('Both remove and replace provided, falling back to remove:', track);\n        delete track.replace;\n      }\n      let kind = track.type;\n      if (track.type === 'screen') kind = 'video'; // FIXME\n      let transceiver = null,\n        sender = null;\n      if (track.mid) {\n        // Search by mid\n        transceiver = config.pc.getTransceivers().find((t) => t.mid === track.mid && t.receiver.track.kind === kind);\n      } else {\n        // Find the first track of this type\n        transceiver = config.pc.getTransceivers().find((t) => t.receiver.track.kind === kind);\n      }\n      if (track.replace || track.remove) {\n        if (!transceiver) {\n          Janus.warn(\"Couldn't find a transceiver for track:\", track);\n          continue;\n        }\n        if (!transceiver.sender) {\n          Janus.warn('No sender in the transceiver for track:', track);\n          continue;\n        }\n        sender = transceiver.sender;\n      }\n      if (answer && !transceiver) {\n        transceiver = config.pc.getTransceivers().find((t) => t.receiver.track.kind === kind);\n        if (!transceiver) {\n          Janus.warn(\"Couldn't find a transceiver for track:\", track);\n          continue;\n        }\n      }\n      // Capture the new track, if we need to\n      let nt = null,\n        trackId = null;\n      if (track.remove) {\n        Janus.log('Removing track from PeerConnection', track);\n        trackId = sender.track ? sender.track.id : null;\n        await sender.replaceTrack(null);\n      } else if (track.capture) {\n        if (track.gumGroup && groups[track.gumGroup] && groups[track.gumGroup].stream) {\n          // We did a getUserMedia before already\n          let stream = groups[track.gumGroup].stream;\n          nt = track.type === 'audio' ? stream.getAudioTracks()[0] : stream.getVideoTracks()[0];\n          delete groups[track.gumGroup].stream;\n          delete groups[track.gumGroup];\n          delete track.gumGroup;\n        } else if (track.capture instanceof MediaStreamTrack) {\n          // An external track was provided, use that\n          nt = track.capture;\n        } else {\n          if (!openedConsentDialog) {\n            openedConsentDialog = true;\n            pluginHandle.consentDialog(true);\n          }\n          let constraints = Janus.trackConstraints(track),\n            stream = null;\n          if (track.type === 'audio' || track.type === 'video') {\n            // Use getUserMedia: check if we need to group audio and video together\n            if (track.gumGroup) {\n              let otherType = track.type === 'audio' ? 'video' : 'audio';\n              if (groups[track.gumGroup] && groups[track.gumGroup][otherType]) {\n                let otherTrack = groups[track.gumGroup][otherType];\n                let otherConstraints = Janus.trackConstraints(otherTrack);\n                constraints[otherType] = otherConstraints[otherType];\n              }\n            }\n            stream = await navigator.mediaDevices.getUserMedia(constraints);\n            if (track.gumGroup && constraints.audio && constraints.video) {\n              // We just performed a grouped getUserMedia, keep track of the\n              // stream so that we can immediately assign the track later\n              groups[track.gumGroup].stream = stream;\n              delete track.gumGroup;\n            }\n          } else {\n            // Use getDisplayMedia\n            stream = await navigator.mediaDevices.getDisplayMedia(constraints);\n          }\n          nt = track.type === 'audio' ? stream.getAudioTracks()[0] : stream.getVideoTracks()[0];\n        }\n        if (track.replace) {\n          // Replace the track\n          await sender.replaceTrack(nt);\n          // Update the transceiver direction\n          let newDirection = 'sendrecv';\n          if (track.recv === false || transceiver.direction === 'inactive' || transceiver.direction === 'sendonly')\n            newDirection = 'sendonly';\n          if (transceiver.setDirection) transceiver.setDirection(newDirection);\n          else transceiver.direction = newDirection;\n        } else {\n          // FIXME Add as a new track\n          if (!config.myStream) config.myStream = new MediaStream();\n          if (kind === 'audio' || (!track.simulcast && !track.svc)) {\n            sender = config.pc.addTrack(nt, config.myStream);\n            transceiver = config.pc.getTransceivers().find((t) => t.sender === sender);\n          } else if (track.simulcast) {\n            if (Janus.webRTCAdapter.browserDetails.browser !== 'firefox') {\n              // Standard RID\n              Janus.log('Enabling rid-based simulcasting:', nt);\n              let maxBitrates = getMaxBitrates(track.simulcastMaxBitrates);\n              transceiver = config.pc.addTransceiver(nt, {\n                direction: 'sendrecv',\n                streams: [config.myStream],\n                sendEncodings: track.sendEncodings || [\n                  { rid: 'h', active: true, maxBitrate: maxBitrates.high },\n                  {\n                    rid: 'm',\n                    active: true,\n                    maxBitrate: maxBitrates.medium,\n                    scaleResolutionDownBy: 2,\n                  },\n                  {\n                    rid: 'l',\n                    active: true,\n                    maxBitrate: maxBitrates.low,\n                    scaleResolutionDownBy: 4,\n                  },\n                ],\n              });\n            } else {\n              // Firefox-based RID, based on https://gist.github.com/voluntas/088bc3cc62094730647b\n              Janus.log('Enabling Simulcasting for Firefox (RID)');\n              transceiver = config.pc.addTransceiver(nt, {\n                direction: 'sendrecv',\n                streams: [config.myStream],\n              });\n              sender = transceiver ? transceiver.sender : null;\n              if (sender) {\n                let parameters = sender.getParameters();\n                if (!parameters) parameters = {};\n                let maxBitrates = getMaxBitrates(track.simulcastMaxBitrates);\n                parameters.encodings = track.sendEncodings || [\n                  { rid: 'h', active: true, maxBitrate: maxBitrates.high },\n                  {\n                    rid: 'm',\n                    active: true,\n                    maxBitrate: maxBitrates.medium,\n                    scaleResolutionDownBy: 2,\n                  },\n                  {\n                    rid: 'l',\n                    active: true,\n                    maxBitrate: maxBitrates.low,\n                    scaleResolutionDownBy: 4,\n                  },\n                ];\n                sender.setParameters(parameters);\n              }\n            }\n          } else {\n            Janus.log('Enabling SVC (' + track.svc + '):', nt);\n            transceiver = config.pc.addTransceiver(nt, {\n              direction: 'sendrecv',\n              streams: [config.myStream],\n              sendEncodings: [{ scalabilityMode: track.svc }],\n            });\n          }\n          if (!sender) sender = transceiver ? transceiver.sender : null;\n          // Check if we need to override some settings\n          if (track.codec) {\n            if (Janus.webRTCAdapter.browserDetails.browser === 'firefox') {\n              Janus.warn('setCodecPreferences not supported in Firefox, ignoring codec for track:', track);\n            } else if (typeof track.codec !== 'string') {\n              Janus.warn('Invalid codec value, ignoring for track:', track);\n            } else {\n              let mimeType = kind + '/' + track.codec.toLowerCase();\n              let codecs = RTCRtpReceiver.getCapabilities(kind).codecs.filter(function (codec) {\n                return codec.mimeType.toLowerCase() === mimeType;\n              });\n              if (!codecs || codecs.length === 0) {\n                Janus.warn('Codec not supported in this browser for this track, ignoring:', track);\n              } else if (transceiver) {\n                try {\n                  transceiver.setCodecPreferences(codecs);\n                } catch (err) {\n                  Janus.warn('Failed enforcing codec for this ' + kind + ' track:', err);\n                }\n              }\n            }\n          }\n          if (track.bitrate) {\n            // Override maximum bitrate\n            if (track.simulcast || track.svc) {\n              Janus.warn('Ignoring bitrate for simulcast/SVC track, use sendEncodings for that');\n            } else if (isNaN(track.bitrate) || track.bitrate < 0) {\n              Janus.warn('Ignoring invalid bitrate for track:', track);\n            } else if (sender) {\n              let params = sender.getParameters();\n              if (!params || !params.encodings || params.encodings.length === 0) {\n                Janus.warn('No encodings in the sender parameters, ignoring bitrate for track:', track);\n              } else {\n                params.encodings[0].maxBitrate = track.bitrate;\n                await sender.setParameters(params);\n              }\n            }\n          }\n          if (kind === 'video' && track.framerate) {\n            // Override maximum framerate\n            if (track.simulcast || track.svc) {\n              Janus.warn('Ignoring framerate for simulcast/SVC track, use sendEncodings for that');\n            } else if (isNaN(track.framerate) || track.framerate < 0) {\n              Janus.warn('Ignoring invalid framerate for track:', track);\n            } else if (sender) {\n              let params = sender.getParameters();\n              if (!params || !params.encodings || params.encodings.length === 0) {\n                Janus.warn('No encodings in the sender parameters, ignoring framerate for track:', track);\n              } else {\n                params.encodings[0].maxFramerate = track.framerate;\n                await sender.setParameters(params);\n              }\n            }\n          }\n          // Check if insertable streams are involved\n          if (track.transforms) {\n            if (sender && track.transforms.sender) {\n              // There's a sender transform, set it on the transceiver sender\n              let senderStreams = null;\n              if (RTCRtpSender.prototype.createEncodedStreams) {\n                senderStreams = sender.createEncodedStreams();\n              } else if (\n                RTCRtpSender.prototype.createAudioEncodedStreams ||\n                RTCRtpSender.prototype.createEncodedVideoStreams\n              ) {\n                if (kind === 'audio') {\n                  senderStreams = sender.createEncodedAudioStreams();\n                } else if (kind === 'video') {\n                  senderStreams = sender.createEncodedVideoStreams();\n                }\n              }\n              if (senderStreams) {\n                Janus.log('Insertable Streams sender transform:', senderStreams);\n                if (senderStreams.readableStream && senderStreams.writableStream) {\n                  senderStreams.readableStream\n                    .pipeThrough(track.transforms.sender)\n                    .pipeTo(senderStreams.writableStream);\n                } else if (senderStreams.readable && senderStreams.writable) {\n                  senderStreams.readable.pipeThrough(track.transforms.sender).pipeTo(senderStreams.writable);\n                }\n              }\n            }\n            if (transceiver && transceiver.receiver && track.transforms.receiver) {\n              // There's a receiver transform, set it on the transceiver receiver\n              let receiverStreams = null;\n              if (RTCRtpReceiver.prototype.createEncodedStreams) {\n                receiverStreams = transceiver.receiver.createEncodedStreams();\n              } else if (\n                RTCRtpReceiver.prototype.createAudioEncodedStreams ||\n                RTCRtpReceiver.prototype.createEncodedVideoStreams\n              ) {\n                if (kind === 'audio') {\n                  receiverStreams = transceiver.receiver.createEncodedAudioStreams();\n                } else if (kind === 'video') {\n                  receiverStreams = transceiver.receiver.createEncodedVideoStreams();\n                }\n              }\n              if (receiverStreams) {\n                Janus.log('Insertable Streams receiver transform:', receiverStreams);\n                if (receiverStreams.readableStream && receiverStreams.writableStream) {\n                  receiverStreams.readableStream\n                    .pipeThrough(track.transforms.receiver)\n                    .pipeTo(receiverStreams.writableStream);\n                } else if (receiverStreams.readable && receiverStreams.writable) {\n                  receiverStreams.readable.pipeThrough(track.transforms.receiver).pipeTo(receiverStreams.writable);\n                }\n              }\n            }\n          }\n        }\n        if (nt && track.dontStop === true) nt.dontStop = true;\n      } else if (track.recv && !transceiver) {\n        // Maybe a new recvonly track\n        transceiver = config.pc.addTransceiver(kind);\n        if (transceiver) {\n          // Check if we need to override some settings\n          if (track.codec) {\n            if (Janus.webRTCAdapter.browserDetails.browser === 'firefox') {\n              Janus.warn('setCodecPreferences not supported in Firefox, ignoring codec for track:', track);\n            } else if (typeof track.codec !== 'string') {\n              Janus.warn('Invalid codec value, ignoring for track:', track);\n            } else {\n              let mimeType = kind + '/' + track.codec.toLowerCase();\n              let codecs = RTCRtpReceiver.getCapabilities(kind).codecs.filter(function (codec) {\n                return codec.mimeType.toLowerCase() === mimeType;\n              });\n              if (!codecs || codecs.length === 0) {\n                Janus.warn('Codec not supported in this browser for this track, ignoring:', track);\n              } else {\n                try {\n                  transceiver.setCodecPreferences(codecs);\n                } catch (err) {\n                  Janus.warn('Failed enforcing codec for this ' + kind + ' track:', err);\n                }\n              }\n            }\n          }\n          // Check if insertable streams are involved\n          if (transceiver.receiver && track.transforms && track.transforms.receiver) {\n            // There's a receiver transform, set it on the transceiver receiver\n            let receiverStreams = null;\n            if (RTCRtpReceiver.prototype.createEncodedStreams) {\n              receiverStreams = transceiver.receiver.createEncodedStreams();\n            } else if (\n              RTCRtpReceiver.prototype.createAudioEncodedStreams ||\n              RTCRtpReceiver.prototype.createEncodedVideoStreams\n            ) {\n              if (kind === 'audio') {\n                receiverStreams = transceiver.receiver.createEncodedAudioStreams();\n              } else if (kind === 'video') {\n                receiverStreams = transceiver.receiver.createEncodedVideoStreams();\n              }\n            }\n            if (receiverStreams) {\n              Janus.log('Insertable Streams receiver transform:', receiverStreams);\n              if (receiverStreams.readableStream && receiverStreams.writableStream) {\n                receiverStreams.readableStream\n                  .pipeThrough(track.transforms.receiver)\n                  .pipeTo(receiverStreams.writableStream);\n              } else if (receiverStreams.readable && receiverStreams.writable) {\n                receiverStreams.readable.pipeThrough(track.transforms.receiver).pipeTo(receiverStreams.writable);\n              }\n            }\n          }\n        }\n      }\n      // Get rid of the old track\n      // FIXME We should probably do this *before* capturing the new\n      // track, since this prevents, for instance, just changing the\n      // resolution of the same webcam we're capturing already (the\n      // existing resolution would be returned, or an overconstrained\n      // error). On the other end, closing the track before we capture\n      // the new device means we'd end up with a period of time where\n      // no video is sent (changing device takes some time), and\n      // media would be stopped entirely in case capturing the new\n      // device results in an error. To keep things simpler, we're\n      // doing it after: we can make this configurable in the future.\n      if (trackId && config.myStream) {\n        let rt = null;\n        if (kind === 'audio' && config.myStream.getAudioTracks() && config.myStream.getAudioTracks().length) {\n          for (let t of config.myStream.getAudioTracks()) {\n            if (t.id === trackId) {\n              rt = t;\n              Janus.log('Removing audio track:', rt);\n            }\n          }\n        } else if (kind === 'video' && config.myStream.getVideoTracks() && config.myStream.getVideoTracks().length) {\n          for (let t of config.myStream.getVideoTracks()) {\n            if (t.id === trackId) {\n              rt = t;\n              Janus.log('Removing video track:', rt);\n            }\n          }\n        }\n        if (rt) {\n          // Remove the track and notify the application\n          try {\n            config.myStream.removeTrack(rt);\n            pluginHandle.onlocaltrack(rt, false);\n          } catch (e) {\n            Janus.error('Error calling onlocaltrack on removal for renegotiation', e);\n          }\n          // Close the old track (unless we've been asked not to)\n          if (rt.dontStop !== true) {\n            try {\n              rt.stop();\n            } catch (e) { }\n          }\n        }\n      }\n      if (nt) {\n        // FIXME Add the new track locally\n        config.myStream.addTrack(nt);\n        // Notify the application about the new local track, if any\n        nt.onended = function (ev) {\n          Janus.log('Local track removed:', ev);\n          try {\n            pluginHandle.onlocaltrack(ev.target, false);\n          } catch (e) {\n            Janus.error('Error calling onlocaltrack following end', e);\n          }\n        };\n        try {\n          pluginHandle.onlocaltrack(nt, true);\n        } catch (e) {\n          Janus.error('Error calling onlocaltrack for track add', e);\n        }\n      }\n      // Update the direction of the transceiver\n      if (transceiver) {\n        let curdir = transceiver.direction,\n          newdir = null;\n        let send = nt && transceiver.sender.track,\n          recv = track.recv !== false && transceiver.receiver.track;\n        if (send && recv) newdir = 'sendrecv';\n        else if (send && !recv) newdir = 'sendonly';\n        else if (!send && recv) newdir = 'recvonly';\n        else if (!send && !recv) newdir = 'inactive';\n        if (newdir && newdir !== curdir) {\n          Janus.warn('Changing direction of transceiver to ' + newdir + ' (was ' + curdir + ')', track);\n          if (transceiver.setDirection) transceiver.setDirection(newdir);\n          else transceiver.direction = newdir;\n        }\n      }\n    }\n    if (openedConsentDialog) pluginHandle.consentDialog(false);\n  }\n\n  function getLocalTracks(handleId) {\n    let pluginHandle = pluginHandles[handleId];\n    if (!pluginHandle || !pluginHandle.webrtcStuff) {\n      Janus.warn('Invalid handle');\n      return null;\n    }\n    let config = pluginHandle.webrtcStuff;\n    if (!config.pc) {\n      Janus.warn('Invalid PeerConnection');\n      return null;\n    }\n    let tracks = [];\n    let transceivers = config.pc.getTransceivers();\n    for (let tr of transceivers) {\n      let track = null;\n      if (tr.sender && tr.sender.track) {\n        track = { mid: tr.mid };\n        track.type = tr.sender.track.kind;\n        track.id = tr.sender.track.id;\n        track.label = tr.sender.track.label;\n      }\n      if (track) tracks.push(track);\n    }\n    return tracks;\n  }\n\n  function getRemoteTracks(handleId) {\n    let pluginHandle = pluginHandles[handleId];\n    if (!pluginHandle || !pluginHandle.webrtcStuff) {\n      Janus.warn('Invalid handle');\n      return null;\n    }\n    let config = pluginHandle.webrtcStuff;\n    if (!config.pc) {\n      Janus.warn('Invalid PeerConnection');\n      return null;\n    }\n    let tracks = [];\n    let transceivers = config.pc.getTransceivers();\n    for (let tr of transceivers) {\n      let track = null;\n      if (tr.receiver && tr.receiver.track) {\n        track = { mid: tr.mid };\n        track.type = tr.receiver.track.kind;\n        track.id = tr.receiver.track.id;\n        track.label = tr.receiver.track.label;\n      }\n      if (track) tracks.push(track);\n    }\n    return tracks;\n  }\n\n  function getVolume(handleId, mid, remote, result) {\n    result = typeof result == 'function' ? result : Janus.noop;\n    let pluginHandle = pluginHandles[handleId];\n    if (!pluginHandle || !pluginHandle.webrtcStuff) {\n      Janus.warn('Invalid handle');\n      result(0);\n      return;\n    }\n    let stream = remote ? 'remote' : 'local';\n    let config = pluginHandle.webrtcStuff;\n    if (!config.volume[stream]) config.volume[stream] = { value: 0 };\n    // Start getting the volume, if audioLevel in getStats is supported (apparently\n    // they're only available in Chrome/Safari right now: https://webrtc-stats.callstats.io/)\n    if (\n      config.pc &&\n      config.pc.getStats &&\n      (Janus.webRTCAdapter.browserDetails.browser === 'chrome' ||\n        Janus.webRTCAdapter.browserDetails.browser === 'safari')\n    ) {\n      // Are we interested in a mid in particular?\n      let query = config.pc;\n      if (mid) {\n        let transceiver = config.pc.getTransceivers().find((t) => t.mid === mid && t.receiver.track.kind === 'audio');\n        if (!transceiver) {\n          Janus.warn('No audio transceiver with mid ' + mid);\n          result(0);\n          return;\n        }\n        if (remote && !transceiver.receiver) {\n          Janus.warn('Remote transceiver track unavailable');\n          result(0);\n          return;\n        } else if (!remote && !transceiver.sender) {\n          Janus.warn('Local transceiver track unavailable');\n          result(0);\n          return;\n        }\n        query = remote ? transceiver.receiver : transceiver.sender;\n      }\n      query.getStats().then(function (stats) {\n        stats.forEach(function (res) {\n          if (!res || res.kind !== 'audio') return;\n          if ((remote && !res.remoteSource) || (!remote && res.type !== 'media-source')) return;\n          result(res.audioLevel ? res.audioLevel : 0);\n        });\n      });\n      return config.volume[stream].value;\n    } else {\n      // audioInputLevel and audioOutputLevel seem only available in Chrome? audioLevel\n      // seems to be available on Chrome and Firefox, but they don't seem to work\n      Janus.warn('Getting the ' + stream + ' volume unsupported by browser');\n      result(0);\n      return;\n    }\n  }\n\n  function isMuted(handleId, mid, video) {\n    let pluginHandle = pluginHandles[handleId];\n    if (!pluginHandle || !pluginHandle.webrtcStuff) {\n      Janus.warn('Invalid handle');\n      return true;\n    }\n    let config = pluginHandle.webrtcStuff;\n    if (!config.pc) {\n      Janus.warn('Invalid PeerConnection');\n      return true;\n    }\n    if (!config.myStream) {\n      Janus.warn('Invalid local MediaStream');\n      return true;\n    }\n    if (video) {\n      // Check video track\n      if (!config.myStream.getVideoTracks() || config.myStream.getVideoTracks().length === 0) {\n        Janus.warn('No video track');\n        return true;\n      }\n      if (mid) {\n        let transceiver = config.pc.getTransceivers().find((t) => t.mid === mid && t.receiver.track.kind === 'video');\n        if (!transceiver) {\n          Janus.warn('No video transceiver with mid ' + mid);\n          return true;\n        }\n        if (!transceiver.sender || !transceiver.sender.track) {\n          Janus.warn('No video sender with mid ' + mid);\n          return true;\n        }\n        return !transceiver.sender.track.enabled;\n      } else {\n        return !config.myStream.getVideoTracks()[0].enabled;\n      }\n    } else {\n      // Check audio track\n      if (!config.myStream.getAudioTracks() || config.myStream.getAudioTracks().length === 0) {\n        Janus.warn('No audio track');\n        return true;\n      }\n      if (mid) {\n        let transceiver = config.pc.getTransceivers().find((t) => t.mid === mid && t.receiver.track.kind === 'audio');\n        if (!transceiver) {\n          Janus.warn('No audio transceiver with mid ' + mid);\n          return true;\n        }\n        if (!transceiver.sender || !transceiver.sender.track) {\n          Janus.warn('No audio sender with mid ' + mid);\n          return true;\n        }\n        return !transceiver.sender.track.enabled;\n      } else {\n        return !config.myStream.getAudioTracks()[0].enabled;\n      }\n    }\n  }\n\n  function mute(handleId, mid, video, mute) {\n    let pluginHandle = pluginHandles[handleId];\n    if (!pluginHandle || !pluginHandle.webrtcStuff) {\n      Janus.warn('Invalid handle');\n      return false;\n    }\n    let config = pluginHandle.webrtcStuff;\n    if (!config.pc) {\n      Janus.warn('Invalid PeerConnection');\n      return false;\n    }\n    if (!config.myStream) {\n      Janus.warn('Invalid local MediaStream');\n      return false;\n    }\n    if (video) {\n      // Mute/unmute video track\n      if (!config.myStream.getVideoTracks() || config.myStream.getVideoTracks().length === 0) {\n        Janus.warn('No video track');\n        return false;\n      }\n      if (mid) {\n        let transceiver = config.pc.getTransceivers().find((t) => t.mid === mid && t.receiver.track.kind === 'video');\n        if (!transceiver) {\n          Janus.warn('No video transceiver with mid ' + mid);\n          return false;\n        }\n        if (!transceiver.sender || !transceiver.sender.track) {\n          Janus.warn('No video sender with mid ' + mid);\n          return false;\n        }\n        transceiver.sender.track.enabled = mute ? false : true;\n      } else {\n        for (const videostream of config.myStream.getVideoTracks()) {\n          videostream.enabled = !mute;\n        }\n      }\n    } else {\n      // Mute/unmute audio track\n      if (!config.myStream.getAudioTracks() || config.myStream.getAudioTracks().length === 0) {\n        Janus.warn('No audio track');\n        return false;\n      }\n      if (mid) {\n        let transceiver = config.pc.getTransceivers().find((t) => t.mid === mid && t.receiver.track.kind === 'audio');\n        if (!transceiver) {\n          Janus.warn('No audio transceiver with mid ' + mid);\n          return false;\n        }\n        if (!transceiver.sender || !transceiver.sender.track) {\n          Janus.warn('No audio sender with mid ' + mid);\n          return false;\n        }\n        transceiver.sender.track.enabled = mute ? false : true;\n      } else {\n        for (const audiostream of config.myStream.getAudioTracks()) {\n          audiostream.enabled = !mute;\n        }\n      }\n    }\n    return true;\n  }\n\n  function getBitrate(handleId, mid) {\n    let pluginHandle = pluginHandles[handleId];\n    if (!pluginHandle || !pluginHandle.webrtcStuff) {\n      Janus.warn('Invalid handle');\n      return 'Invalid handle';\n    }\n    let config = pluginHandle.webrtcStuff;\n    if (!config.pc) return 'Invalid PeerConnection';\n    // Start getting the bitrate, if getStats is supported\n    if (config.pc.getStats) {\n      let query = config.pc;\n      let target = mid ? mid : 'default';\n      if (mid) {\n        let transceiver = config.pc.getTransceivers().find((t) => t.mid === mid && t.receiver.track.kind === 'video');\n        if (!transceiver) {\n          Janus.warn('No video transceiver with mid ' + mid);\n          return 'No video transceiver with mid ' + mid;\n        }\n        if (!transceiver.receiver) {\n          Janus.warn('No video receiver with mid ' + mid);\n          return 'No video receiver with mid ' + mid;\n        }\n        query = transceiver.receiver;\n      }\n      if (!config.bitrate[target]) {\n        config.bitrate[target] = {\n          timer: null,\n          bsnow: null,\n          bsbefore: null,\n          tsnow: null,\n          tsbefore: null,\n          value: '0 kbits/sec',\n        };\n      }\n      if (!config.bitrate[target].timer) {\n        Janus.log('Starting bitrate timer' + (mid ? ' for mid ' + mid : '') + ' (via getStats)');\n        config.bitrate[target].timer = setInterval(function () {\n          query.getStats().then(function (stats) {\n            stats.forEach(function (res) {\n              if (!res) return;\n              let inStats = false;\n              // Check if these are statistics on incoming media\n              if (\n                (res.mediaType === 'video' || res.id.toLowerCase().indexOf('video') > -1) &&\n                res.type === 'inbound-rtp' &&\n                res.id.indexOf('rtcp') < 0\n              ) {\n                // New stats\n                inStats = true;\n              } else if (\n                res.type == 'ssrc' &&\n                res.bytesReceived &&\n                (res.googCodecName === 'VP8' || res.googCodecName === '')\n              ) {\n                // Older Chromer versions\n                inStats = true;\n              }\n              // Parse stats now\n              if (inStats) {\n                config.bitrate[target].bsnow = res.bytesReceived;\n                config.bitrate[target].tsnow = res.timestamp;\n                if (config.bitrate[target].bsbefore === null || config.bitrate[target].tsbefore === null) {\n                  // Skip this round\n                  config.bitrate[target].bsbefore = config.bitrate[target].bsnow;\n                  config.bitrate[target].tsbefore = config.bitrate[target].tsnow;\n                } else {\n                  // Calculate bitrate\n                  let timePassed = config.bitrate[target].tsnow - config.bitrate[target].tsbefore;\n                  if (Janus.webRTCAdapter.browserDetails.browser === 'safari') timePassed = timePassed / 1000; // Apparently the timestamp is in microseconds, in Safari\n                  let bitRate = Math.round(\n                    ((config.bitrate[target].bsnow - config.bitrate[target].bsbefore) * 8) / timePassed\n                  );\n                  if (Janus.webRTCAdapter.browserDetails.browser === 'safari') bitRate = parseInt(bitRate / 1000);\n                  config.bitrate[target].value = bitRate + ' kbits/sec';\n                  //~ Janus.log(\"Estimated bitrate is \" + config.bitrate.value);\n                  config.bitrate[target].bsbefore = config.bitrate[target].bsnow;\n                  config.bitrate[target].tsbefore = config.bitrate[target].tsnow;\n                }\n              }\n            });\n          });\n        }, 1000);\n        return '0 kbits/sec'; // We don't have a bitrate value yet\n      }\n      return config.bitrate[target].value;\n    } else {\n      Janus.warn('Getting the video bitrate unsupported by browser');\n      return 'Feature unsupported by browser';\n    }\n  }\n\n  function setBitrate(handleId, mid, bitrate) {\n    let pluginHandle = pluginHandles[handleId];\n    if (!pluginHandle || !pluginHandle.webrtcStuff) {\n      Janus.warn('Invalid handle');\n      return;\n    }\n    let config = pluginHandle.webrtcStuff;\n    if (!config.pc) {\n      Janus.warn('Invalid PeerConnection');\n      return;\n    }\n    let transceiver = config.pc.getTransceivers().find((t) => t.mid === mid);\n    if (!transceiver) {\n      Janus.warn('No transceiver with mid', mid);\n      return;\n    }\n    if (!transceiver.sender) {\n      Janus.warn('No sender for transceiver with mid', mid);\n      return;\n    }\n    let params = transceiver.sender.getParameters();\n    if (!params || !params.encodings || params.encodings.length === 0) {\n      Janus.warn('No parameters encodings');\n    } else if (params.encodings.length > 1) {\n      Janus.warn('Ignoring bitrate for simulcast track, use sendEncodings for that');\n    } else if (isNaN(bitrate) || bitrate < 0) {\n      Janus.warn('Invalid bitrate (must be a positive integer)');\n    } else {\n      params.encodings[0].maxBitrate = bitrate;\n      transceiver.sender.setParameters(params);\n    }\n  }\n\n  function webrtcError(error) {\n    Janus.error('WebRTC error:', error);\n  }\n\n  function cleanupWebrtc(handleId, hangupRequest) {\n    Janus.log('Cleaning WebRTC stuff');\n    let pluginHandle = pluginHandles[handleId];\n    if (!pluginHandle) {\n      // Nothing to clean\n      return;\n    }\n    let config = pluginHandle.webrtcStuff;\n    if (config) {\n      if (hangupRequest === true) {\n        // Send a hangup request (we don't really care about the response)\n        let request = { janus: 'hangup', transaction: Janus.randomString(12) };\n        if (pluginHandle.token) request['token'] = pluginHandle.token;\n        if (apisecret) request['apisecret'] = apisecret;\n        Janus.debug('Sending hangup request (handle=' + handleId + '):');\n        Janus.debug(request);\n        if (websockets) {\n          request['session_id'] = sessionId;\n          request['handle_id'] = handleId;\n          ws.send(JSON.stringify(request));\n        } else {\n          Janus.httpAPICall(server + '/' + sessionId + '/' + handleId, {\n            verb: 'POST',\n            withCredentials: withCredentials,\n            body: request,\n          });\n        }\n      }\n      // Cleanup stack\n      if (config.volume) {\n        if (config.volume['local'] && config.volume['local'].timer) clearInterval(config.volume['local'].timer);\n        if (config.volume['remote'] && config.volume['remote'].timer) clearInterval(config.volume['remote'].timer);\n      }\n      for (let i in config.bitrate) {\n        if (config.bitrate[i].timer) clearInterval(config.bitrate[i].timer);\n      }\n      config.bitrate = {};\n      if (!config.streamExternal && config.myStream) {\n        Janus.log('Stopping local stream tracks');\n        Janus.stopAllTracks(config.myStream);\n      }\n      config.streamExternal = false;\n      config.myStream = null;\n      // Close PeerConnection\n      try {\n        config.pc.close();\n      } catch (e) {\n        // Do nothing\n      }\n      config.pc = null;\n      config.candidates = null;\n      config.mySdp = null;\n      config.remoteSdp = null;\n      config.iceDone = false;\n      config.dataChannel = {};\n      config.dtmfSender = null;\n      config.insertableStreams = false;\n    }\n    pluginHandle.oncleanup();\n  }\n\n  function isTrickleEnabled(trickle) {\n    Janus.debug('isTrickleEnabled:', trickle);\n    return trickle === false ? false : true;\n  }\n}\n\nmodule.exports = Janus;\n","import type { Config, Janus, VoidCallback, PlainObject } from '../types';\nimport { JanusDebugMode, JanusEvent, JanusMediaTrackReason } from '../types/constants';\nimport { adapter, MediaStream } from '@platform';\nimport EventEmitter from 'eventemitter3';\nimport config from '../config';\nimport JanusEngine from './janus.js';\nimport Utils from '../Utils';\n\nexport default class JanusClient {\n  public token: Config.Credentials['token'];\n  public server: Config.Conference['server'];\n  public debug: Config.JanusDebug;\n  declare engine: JanusEngine;\n  public videoRoomPlugin: Janus.VideoRoomPluginHandle | null = null;\n  public isOnlyAudio: boolean = false;\n  public currentRoomId: string | null = null;\n  public currentUserId: number | string | null = null;\n  public remoteFeeds: Record<number | string, Janus.RemoteFeed | null> = {};\n  public remoteJseps: PlainObject<string | number> = {};\n  public remoteFeedsAttachingInProgress: Record<number | string, Janus.RemoteFeed | null> = {};\n  public bitrateTimers: { [userId: number | string]: NodeJS.Timeout | number | null } = {};\n  public emitter: EventEmitter = new EventEmitter();\n\n  constructor(token: Config.Credentials['token']) {\n    if (!Utils.env.isReactNative && !adapter) {\n      throw new Error(\n        'Error: in order to use this library please connect adapter.js. More info https://github.com/webrtc/adapter'\n      );\n    }\n\n    this.token = token;\n    this.server = config.conference.server;\n    this.debug = config.conference.debug ?? JanusDebugMode.ALL;\n\n    if (!this.server) {\n      throw new Error(\"'server' parameter is mandatory\");\n    } else if (this.server.includes('http')) {\n      this.server += '/janus';\n    }\n  }\n\n  public createSession({\n    success = () => {},\n    error = () => {},\n    destroyed = () => {},\n    timeoutSessionCallback = () => {},\n  }: Janus.InitCallbacks): void {\n    JanusEngine.init({\n      debug: this.debug,\n      callback: () => {\n        if (!JanusEngine.isWebrtcSupported()) {\n          Utils.safeCallbackCall(error)(`Your browser does not support WebRTC, so you can't use this functionality.`);\n          return;\n        }\n\n        this.engine = new JanusEngine({\n          server: this.server,\n          iceServers: config.videochat.iceServers,\n          token: this.token,\n          success: () => Utils.safeCallbackCall(success)(),\n          error: (err: unknown) => Utils.safeCallbackCall(error)(err),\n          destroyed: () => Utils.safeCallbackCall(destroyed)(),\n          timeoutSessionCallback: () => Utils.safeCallbackCall(timeoutSessionCallback)(),\n        });\n      },\n    });\n  }\n\n  public getSessionId(): string | null {\n    return this.engine?.getSessionId?.() ?? null;\n  }\n\n  public destroySession({ success = () => {}, error = () => {} }: Janus.SuccessErrorCallbacks): void {\n    this.engine?.destroy?.({\n      success: () => Utils.safeCallbackCall(success)(),\n      error: (err: unknown) => Utils.safeCallbackCall(error)(err),\n    });\n  }\n\n  public attachVideoConferencingPlugin(\n    isRemote: boolean,\n    userId: number,\n    skipMedia: boolean,\n    callbacks: Janus.PluginCallbacks\n  ): void {\n    let remoteFeed: Janus.RemoteFeed | null = null;\n\n    const localStream = callbacks.localStream;\n    delete callbacks.localStream;\n\n    const displayName = callbacks.displayName;\n    delete callbacks.displayName;\n\n    this.engine?.attach?.({\n      plugin: 'janus.plugin.videoroom',\n      success: (pluginHandle: Janus.VideoRoomPluginHandle | Janus.RemoteFeed) => {\n        if (isRemote) {\n          remoteFeed = pluginHandle as Janus.RemoteFeed;\n          remoteFeed.userId = userId;\n          this.remoteFeedsAttachingInProgress[userId] = remoteFeed;\n\n          const listen = {\n            request: 'join',\n            room: this.currentRoomId,\n            ptype: 'listener',\n            feed: userId,\n            display: displayName,\n          };\n\n          remoteFeed?.send({ message: listen });\n        } else {\n          this.videoRoomPlugin = pluginHandle as Janus.VideoRoomPluginHandle;\n        }\n\n        Utils.safeCallbackCall(callbacks.success)();\n      },\n      error: (error: unknown) => {\n        Utils.safeCallbackCall(callbacks.error)(error);\n      },\n      consentDialog: (on: unknown) => {\n        Utils.safeCallbackCall(callbacks.consentDialog)(on);\n      },\n      mediaState: (medium: unknown, on: unknown) => {\n        Utils.safeCallbackCall(callbacks.mediaState)(medium, on);\n      },\n      webrtcState: (on: unknown) => {\n        Utils.safeCallbackCall(callbacks.webrtcState)(on);\n      },\n      slowLink: (uplink: unknown, nacks: unknown) => {\n        Utils.safeCallbackCall(callbacks.slowLink)(uplink, nacks);\n      },\n      iceState: (iceConnectionState: unknown) => {\n        Utils.safeCallbackCall(callbacks.iceState)(iceConnectionState);\n      },\n      onmessage: (msg: PlainObject, jsep: unknown) => {\n        const event = msg?.['videoroom'];\n\n        if (isRemote) {\n          if (event) {\n            // Remote feed attached\n            if (event === 'attached') {\n              const feedId = msg['id'] as number | string;\n              this.remoteFeeds[feedId] = this.remoteFeedsAttachingInProgress[feedId];\n              this.remoteFeedsAttachingInProgress[feedId] = null;\n            } else if (msg['error']) {\n              Utils.safeCallbackCall(callbacks.error)(msg['error']);\n            }\n          }\n\n          if (jsep) {\n            const feedId = msg['id'] as number | string;\n\n            // ICE restart case\n            if (!feedId) {\n            }\n\n            this.remoteJseps[feedId] = jsep;\n\n            const remoteFeed = this.remoteFeeds[feedId];\n\n            if (!remoteFeed) return;\n\n            this.createAnswer(\n              {\n                remoteFeed,\n                jsep,\n              },\n              localStream as MediaStream,\n              {\n                success: () => {},\n                error: (error) => {\n                  Utils.safeCallbackCall(callbacks.error)(error);\n                },\n              }\n            );\n          }\n\n          // local feed\n        } else {\n          if (event) {\n            // We JOINED\n            if (event === 'joined') {\n              const media = skipMedia ? { audio: false, video: false } : { audio: true, video: true };\n              const existedStream = skipMedia ? undefined : localStream;\n              const offerParams = { media, stream: existedStream };\n              this.createOffer(offerParams, {\n                success: () => {\n                  if (msg['publishers']) {\n                    const publishers = msg['publishers'] as Record<string | number, PlainObject>;\n                    for (const f in publishers) {\n                      const userId = publishers[f]['id'] as number;\n                      const userDisplayName = publishers[f]['display'] as string;\n                      this.emitter.emit(JanusEvent.PARTICIPANT_JOINED, userId, userDisplayName, true);\n                    }\n                  }\n                },\n                error: (error) => {\n                  Utils.safeCallbackCall(callbacks.error)(error);\n                },\n              });\n\n              // We JOINED and now receiving who is online\n            } else if (event === 'event') {\n              // Any new feed to attach to?\n              if (msg['publishers']) {\n                const publishers = msg['publishers'] as Record<string | number, PlainObject>;\n\n                for (const f in publishers) {\n                  const userId = publishers[f]['id'] as number;\n                  const userDisplayName = publishers[f]['display'] as string;\n\n                  this.emitter.emit(JanusEvent.PARTICIPANT_JOINED, userId, userDisplayName, false);\n                }\n\n                // Someone is LEAVING\n              } else if (msg['leaving']) {\n                // One of the publishers has gone away?\n                const feedId = msg['leaving'] as number;\n                const success = this.detachRemoteFeed(feedId);\n                if (success) {\n                  this.emitter.emit(JanusEvent.PARTICIPANT_LEFT, feedId, null);\n                }\n              } else if (msg['unpublished']) {\n                // One of the publishers has gone away?\n                const feedId = msg['unpublished'] as number | string;\n                if (feedId !== 'ok') {\n                  const success = this.detachRemoteFeed(Number(feedId));\n                  if (success) {\n                    this.emitter.emit(JanusEvent.PARTICIPANT_LEFT, feedId, null);\n                  }\n                }\n              } else if (msg['error']) {\n                Utils.DLog('[janus error message]', msg['error']);\n                // #define VIDEOROOM_ERROR_ID_EXISTS\t\t\t436\n                // #define VIDEOROOM_ERROR_UNAUTHORIZED\t\t433\n                //\n                this.emitter.emit(JanusEvent.ERROR, msg);\n                Utils.safeCallbackCall(callbacks.error)(msg['error']);\n              }\n            }\n          }\n\n          if (jsep) {\n            this.videoRoomPlugin?.handleRemoteJsep?.({ jsep: jsep });\n\n            // TODO:\n            // handle wrong or unsupported codecs here...\n            // const video = msg['video_codec']\n            // if(mystream && mystream.getVideoTracks() && mystream.getVideoTracks().length > 0 && !video) {\n            // \t\t'Our video stream has been rejected, viewers won't see us'\n            // }\n          }\n        }\n      },\n      onlocaltrack: (track: MediaStreamTrack, on: unknown) => {\n        Utils.DLog('[onlocaltrack]', track, on);\n        this.onLocalTrack(track, on);\n      },\n      onremotetrack: (track: MediaStreamTrack, mid: unknown, on: unknown, metadata: unknown) => {\n        Utils.DLog('[onremotetrack]', track, mid, on, metadata);\n        this.onRemoteTrack(\n          remoteFeed!,\n          track,\n          typeof mid === 'string' ? mid : String(mid),\n          on,\n          metadata as { reason?: string } | undefined\n        );\n      },\n      ondataopen: (channelLabel: string) => {\n        Utils.DLog('[ondataopen]', channelLabel);\n        this.emitter.emit(JanusEvent.DATA_CHANNEL_OPEN, channelLabel);\n      },\n      ondata: (data: unknown, channelLabel: string) => {\n        Utils.DLog('[ondata]', channelLabel, data);\n        this.emitter.emit(JanusEvent.DATA_CHANNEL_MESSAGE, channelLabel, data);\n      },\n      oncleanup: () => {\n        Utils.safeCallbackCall(callbacks.oncleanup)();\n      },\n      detached: () => {},\n    });\n  }\n\n  public onLocalTrack(_track: MediaStreamTrack, _on: unknown): void {\n    // this.emitter.emit(JanusEvent.LOCAL_STREAM, track);\n  }\n\n  public onRemoteTrack(\n    remoteFeed: Janus.RemoteFeed,\n    track: MediaStreamTrack,\n    mid: string,\n    _on: unknown,\n    metadata: { reason?: string } | undefined\n  ): void {\n    const eventType = metadata && metadata.reason;\n    if (eventType === JanusMediaTrackReason.CREATED) {\n      const isStreamNoExistedBefore = !remoteFeed.stream || !remoteFeed.tracks;\n      if (isStreamNoExistedBefore) {\n        remoteFeed.tracks = { [mid]: track };\n        remoteFeed.stream = new MediaStream!([track]);\n      } else {\n        if (remoteFeed.tracks) remoteFeed.tracks[mid] = track;\n        remoteFeed.stream?.addTrack(track);\n      }\n      if (isStreamNoExistedBefore) {\n        this.emitter.emit(JanusEvent.REMOTE_STREAM, remoteFeed.userId, remoteFeed.stream);\n      }\n    } else if (eventType === JanusMediaTrackReason.ENDED) {\n      if (remoteFeed.tracks) delete remoteFeed.tracks[mid];\n      const feedStream = remoteFeed.stream;\n      if (!feedStream) return;\n      const trackToRemove = feedStream\n        .getTracks()\n        .find((streamTrack: MediaStreamTrack) => streamTrack.kind === track.kind);\n      if (trackToRemove) feedStream.removeTrack(trackToRemove);\n    }\n    this.emitter.emit(JanusEvent.REMOTE_TRACKS_UPDATED, remoteFeed.userId, track, eventType);\n  }\n\n  public getPluginId(): string | null {\n    const id = this.videoRoomPlugin?.getId?.();\n    return id != null ? String(id) : null;\n  }\n\n  public detachVideoConferencingPlugin(callbacks: Janus.SuccessErrorCallbacks): void {\n    const clean = () => {\n      this.videoRoomPlugin = null;\n\n      // detach all remote feeds\n      Object.keys(this.remoteFeeds).forEach((userId) => {\n        this.detachRemoteFeed(Number(userId));\n      });\n\n      this.remoteFeeds = {};\n      this.remoteJseps = {};\n      /*\n       * Deprecated\n      this.currentMediaDeviceId = null\n       */\n    };\n\n    this.videoRoomPlugin?.detach?.({\n      success: () => {\n        clean();\n\n        Utils.safeCallbackCall(callbacks.success)();\n      },\n      error: (error: unknown) => {\n        clean();\n\n        Utils.safeCallbackCall(callbacks.error)(error);\n      },\n    });\n  }\n\n  public join(roomId: string, userId: number, isOnlyAudio: boolean, callbacks: Janus.RequestCallbacks): void {\n    const displayName = callbacks.displayName;\n    delete callbacks.displayName;\n\n    this.isOnlyAudio = isOnlyAudio;\n\n    Utils.DLog('isOnlyAudio: ' + this.isOnlyAudio);\n\n    const joinEvent = {\n      request: 'join',\n      room: roomId,\n      ptype: 'publisher',\n      id: userId,\n      display: displayName,\n    };\n\n    this.videoRoomPlugin?.send?.({\n      message: joinEvent,\n      success: (_resp: unknown) => {\n        this.currentRoomId = roomId;\n        this.currentUserId = userId;\n        Utils.safeCallbackCall(callbacks.success)();\n      },\n      error: (error: unknown) => {\n        Utils.safeCallbackCall(callbacks.error)(error);\n      },\n    });\n  }\n\n  public leave(callbacks: Janus.RequestCallbacks): void {\n    Utils.DLog('leave');\n\n    if (!this.engine?.isConnected?.()) {\n      Utils.safeCallbackCall(callbacks.success)();\n      return;\n    }\n\n    const leaveEvent = {\n      request: 'leave',\n      room: this.currentRoomId,\n      id: this.currentUserId,\n    };\n\n    if (this.videoRoomPlugin) {\n      this.videoRoomPlugin?.send?.({ message: leaveEvent });\n    }\n    this.currentRoomId = null;\n    this.currentUserId = null;\n\n    Utils.safeCallbackCall(callbacks.success)();\n  }\n\n  public listOnlineParticipants(roomId: string, callbacks: Janus.SuccessErrorCallbacks): void {\n    const listRequest = { request: 'listparticipants', room: roomId };\n\n    this.videoRoomPlugin?.send?.({\n      message: listRequest,\n      success: (data: { participants?: unknown[] } | null | undefined) => {\n        const participants = data?.participants ?? [];\n        Utils.safeCallbackCall(callbacks.success)(participants);\n      },\n      error: (error: unknown) => {\n        Utils.safeCallbackCall(callbacks.error)(error);\n      },\n    });\n  }\n\n  public toggleAudioMute(): boolean {\n    const muted = this.videoRoomPlugin?.isAudioMuted?.();\n    if (muted) {\n      this.videoRoomPlugin?.unmuteAudio?.();\n    } else {\n      this.videoRoomPlugin?.muteAudio?.();\n    }\n    return this.videoRoomPlugin?.isAudioMuted?.() ?? false;\n  }\n\n  public isAudioMuted(): boolean {\n    try {\n      return this.videoRoomPlugin?.isAudioMuted?.() ?? false;\n    } catch (e) {\n      throw new Error('Unknown audio mute/unmute state. Join the room to manage these settings');\n    }\n  }\n\n  public toggleRemoteAudioMute(userId: number): boolean {\n    const remoteFeed = this.remoteFeeds[userId];\n    if (!remoteFeed) {\n      return false;\n    }\n\n    const audioTracks = remoteFeed.stream?.getAudioTracks?.();\n    if (audioTracks && audioTracks.length > 0) {\n      for (let i = 0; i < audioTracks.length; ++i) {\n        audioTracks[i].enabled = !audioTracks[i].enabled;\n      }\n      return !audioTracks[0].enabled;\n    }\n\n    return false;\n  }\n\n  public isRemoteAudioMuted(userId: number): boolean {\n    const remoteFeed = this.remoteFeeds[userId];\n    if (!remoteFeed) {\n      return false;\n    }\n\n    const audioTracks = remoteFeed.stream?.getAudioTracks?.();\n    if (audioTracks && audioTracks.length > 0) {\n      return !audioTracks[0].enabled;\n    }\n\n    return false;\n  }\n\n  public toggleVideoMute(): boolean {\n    const muted = this.videoRoomPlugin?.isVideoMuted?.();\n    if (muted) {\n      this.videoRoomPlugin?.unmuteVideo?.();\n    } else {\n      this.videoRoomPlugin?.muteVideo?.();\n    }\n    return this.videoRoomPlugin?.isVideoMuted?.() || false;\n  }\n\n  public isVideoMuted(): boolean {\n    try {\n      return this.videoRoomPlugin?.isVideoMuted?.() || false;\n    } catch (e) {\n      throw new Error('Unknown video mute/unmute state. Join the room to manage these settings');\n    }\n  }\n\n  public toggleRemoteVideoMute(userId: number): boolean {\n    const remoteFeed = this.remoteFeeds[userId];\n    if (!remoteFeed) {\n      return false;\n    }\n\n    const videoTracks = remoteFeed.stream?.getVideoTracks?.();\n    if (videoTracks && videoTracks.length > 0) {\n      for (let i = 0; i < videoTracks.length; ++i) {\n        videoTracks[i].enabled = !videoTracks[i].enabled;\n      }\n      return !videoTracks[0].enabled;\n    }\n\n    return false;\n  }\n\n  public isRemoteVideoMuted(userId: number): boolean {\n    const remoteFeed = this.remoteFeeds[userId];\n    if (!remoteFeed) {\n      return false;\n    }\n\n    const videoTracks = remoteFeed.stream?.getVideoTracks?.();\n    if (videoTracks && videoTracks.length > 0) {\n      return !videoTracks[0].enabled;\n    }\n\n    return false;\n  }\n\n  public sendKeyframeRequest(roomId: string, callbacks: Janus.SuccessErrorCallbacks): void {\n    const configureRequest = {\n      request: 'configure',\n      room: roomId,\n      keyframe: true,\n    };\n\n    this.videoRoomPlugin?.send?.({\n      message: configureRequest,\n      success: (response: unknown) => {\n        Utils.safeCallbackCall(callbacks.success)(response);\n      },\n      error: (error: unknown) => {\n        Utils.safeCallbackCall(callbacks.error)(error);\n      },\n    });\n  }\n\n  public getTracksFromStream(stream: MediaStream): { type: string; capture: MediaStreamTrack; recv: boolean }[] {\n    const tracks: { type: string; capture: MediaStreamTrack; recv: boolean }[] = [];\n\n    const audioTracks = stream.getAudioTracks();\n    if (audioTracks.length) {\n      const audioTrack = audioTracks[0];\n      tracks.push({ type: 'audio', capture: audioTrack, recv: false });\n    }\n\n    const videoTracks = stream.getVideoTracks();\n    if (videoTracks.length) {\n      const videoTrack = videoTracks[0];\n      tracks.push({ type: 'video', capture: videoTrack, recv: false });\n    }\n\n    return tracks;\n  }\n\n  public createOffer(\n    mediaParams: { stream?: MediaStream; media: { audio: boolean; video: boolean }; replace?: boolean },\n    callbacks: Janus.SuccessErrorCallbacks\n  ): void {\n    Utils.DLog('[JanusWrapper][createOffer]', mediaParams);\n\n    const { stream: existedStream, media, replace } = mediaParams;\n\n    const createOfferParams: Janus.CreateOfferParams = { tracks: [{ type: 'data' }] };\n\n    if (existedStream) {\n      const tracksFromStream = this.getTracksFromStream(existedStream);\n      createOfferParams.tracks = createOfferParams.tracks.concat(tracksFromStream);\n    } else if (media) {\n      const tracksFromParams: { type: string; capture: boolean; recv: boolean; replace: boolean }[] = [];\n      if (media.audio) {\n        tracksFromParams.push({\n          type: 'audio',\n          capture: media.audio,\n          recv: false,\n          replace: !!replace,\n        });\n      }\n      if (media.video) {\n        tracksFromParams.push({\n          type: 'video',\n          capture: media.video,\n          recv: false,\n          replace: !!replace,\n        });\n      }\n      createOfferParams.tracks = createOfferParams.tracks.concat(tracksFromParams);\n    } else {\n      createOfferParams.tracks = createOfferParams.tracks.concat([\n        { type: 'audio', capture: true, recv: false, replace: !!replace },\n        { type: 'video', capture: true, recv: false, replace: !!replace },\n      ]);\n    }\n\n    Utils.DLog('[JanusWrapper][createOffer][params]', createOfferParams);\n\n    createOfferParams.customizeSdp = (_jsep: unknown) => {};\n\n    createOfferParams.success = (jsep: unknown) => {\n      const publish = {\n        request: 'configure',\n        audio: !!media.audio,\n        video: !!media.video,\n      };\n      Utils.DLog('[JanusWrapper][createOffer][success]', publish);\n\n      this.videoRoomPlugin?.send?.({ message: publish, jsep: jsep });\n\n      Utils.safeCallbackCall(callbacks.success)();\n    };\n\n    createOfferParams.error = (error: unknown) => {\n      Utils.DLog('[JanusWrapper][createOffer][error]', error);\n      if (media.audio) {\n        this.createOffer({ media: { video: false, audio: false } }, callbacks);\n      } else {\n        Utils.safeCallbackCall(callbacks.error)(error);\n      }\n    };\n\n    this.videoRoomPlugin?.createOffer?.(createOfferParams);\n  }\n\n  public getTracksMidsFromStream(stream: MediaStream): { type: string; mid: string; recv: boolean }[] {\n    const tracks: { type: string; mid: string; recv: boolean }[] = [];\n\n    const audioTracks = stream.getAudioTracks();\n    if (audioTracks.length) {\n      const audioTrack = audioTracks[0];\n      tracks.push({ type: 'audio', mid: audioTrack.id, recv: true });\n    }\n\n    const videoTracks = stream.getVideoTracks();\n    if (videoTracks.length) {\n      const videoTrack = videoTracks[0];\n      tracks.push({ type: 'video', mid: videoTrack.id, recv: true });\n    }\n\n    return tracks;\n  }\n\n  public createAnswer(\n    { remoteFeed, jsep }: { remoteFeed: Janus.RemoteFeed; jsep: unknown },\n    existedStream: MediaStream,\n    callbacks: Janus.SuccessErrorCallbacks\n  ): void {\n    Utils.DLog('[JanusWrapper][createAnswer]', jsep, existedStream);\n    let tracks: Array<{ type: string; mid?: string; recv?: boolean }> = [{ type: 'data' }];\n\n    if (existedStream) {\n      const tracksFromStream = this.getTracksMidsFromStream(existedStream);\n      tracks = tracks.concat(tracksFromStream);\n    }\n\n    Utils.DLog('[JanusWrapper][createAnswer][tracks]', tracks);\n\n    remoteFeed.createAnswer({\n      jsep: jsep,\n      tracks: tracks,\n      success: (jsep: unknown) => {\n        const body = { request: 'start', room: this.currentRoomId };\n        Utils.DLog('[JanusWrapper][createAnswer][success]', body);\n\n        remoteFeed.send({ message: body, jsep: jsep });\n\n        Utils.safeCallbackCall(callbacks.success)();\n      },\n      error: (error: unknown) => {\n        Utils.DLog('[JanusWrapper][createAnswer][error]', error);\n        Utils.safeCallbackCall(callbacks.error)(error);\n      },\n    });\n  }\n\n  public detachRemoteFeed(userId: number): boolean {\n    const remoteFeed = this.remoteFeeds[userId];\n    if (remoteFeed) {\n      remoteFeed.detach();\n      this.remoteFeeds[userId] = null;\n      this.remoteJseps[userId] = null;\n      return true;\n    }\n    return false;\n  }\n\n  public getUserBitrate(userId: number): unknown {\n    const remoteFeed = this.remoteFeeds[userId];\n    return remoteFeed?.getBitrate?.();\n  }\n\n  public getVolume(resultCallback: (value: unknown) => void): void {\n    this.videoRoomPlugin?.getLocalVolume?.(null, resultCallback);\n  }\n\n  public getUserVolume(userId: number, resultCallback: (value: unknown) => void): void {\n    const remoteFeed = this.remoteFeeds[userId];\n    return remoteFeed?.getRemoteVolume?.(null, resultCallback);\n  }\n\n  public showBitrate(userId: number, element: Janus.BitrateDisplayElement): void {\n    const remoteFeed = this.remoteFeeds[userId];\n    const adapterDetails = (adapter as { browserDetails?: { browser?: string } })?.browserDetails;\n\n    if (!Utils.env.isReactNative && (adapterDetails?.browser === 'chrome' || adapterDetails?.browser === 'firefox')) {\n      this.bitrateTimers[userId] = setInterval(() => {\n        const bitrate = remoteFeed?.getBitrate?.();\n        if (bitrate != null) element.text?.(bitrate);\n      }, 1000);\n    }\n  }\n\n  public hideBitrate(userId: number, element: Janus.BitrateDisplayElement): void {\n    if (this.bitrateTimers[userId]) {\n      clearInterval(this.bitrateTimers[userId]);\n    }\n    this.bitrateTimers[userId] = null;\n    element.text = null;\n  }\n\n  public on(eventType: JanusEvent, listener: VoidCallback): EventEmitter {\n    return this.emitter.addListener(eventType, listener);\n  }\n\n  public removeAllListeners(eventType?: JanusEvent): EventEmitter {\n    return this.emitter.removeAllListeners(eventType);\n  }\n}\n","import type { Auth, Janus, Media } from '../types';\nimport { JanusCallType, JanusEvent } from '../types/constants';\nimport { mediaDevices } from '@platform';\nimport Utils from '../Utils';\nimport JanusClient from './JanusClient';\n\nexport default class ConferenceSession {\n  private client: JanusClient;\n  public id: string = `${Math.random()}`;\n  public currentUserDisplayName?: string;\n  public localStream?: MediaStream;\n  public mediaParams: MediaStreamConstraints = {};\n  declare onParticipantJoinedListener: Janus.OnParticipantJoinedListener;\n  declare onParticipantLeftListener: Janus.OnParticipantLeftListener;\n  declare onSlowLinkListener: Janus.OnSlowLinkListener;\n  declare onRemoteStreamListener: Janus.OnRemoteStreamListener;\n  declare onRemoteTracksUpdatedListener: Janus.OnRemoteTracksUpdatedListener;\n  declare onRemoteConnectionStateChangedListener: Janus.OnRemoteConnectionStateChangedListener;\n  declare onDataChannelOpenedListener: Janus.OnDataChannelOpenedListener;\n  declare onDataChannelMessageListener: Janus.OnDataChannelMessageListener;\n  declare onSessionConnectionStateChangedListener: Janus.OnSessionConnectionStateChangedListener;\n  declare onErrorListener: Janus.OnErrorListener;\n\n  constructor(token: Auth.Session['token']) {\n    this.client = new JanusClient(token);\n    this.client.on(JanusEvent.PARTICIPANT_JOINED, this.onParticipantJoined);\n    this.client.on(JanusEvent.PARTICIPANT_LEFT, this.onParticipantLeft);\n    this.client.on(JanusEvent.REMOTE_STREAM, this.onRemoteStream);\n    this.client.on(JanusEvent.REMOTE_TRACKS_UPDATED, this.onRemoteTracksUpdated);\n    this.client.on(JanusEvent.DATA_CHANNEL_OPEN, this.onDataChannelOpen);\n    this.client.on(JanusEvent.DATA_CHANNEL_MESSAGE, this.onDataChannelMessage);\n    this.client.on(JanusEvent.ERROR, this.onError);\n  }\n\n  get currentRoomId(): string | null {\n    return this.client.currentRoomId;\n  }\n\n  set currentRoomId(roomId: string | null) {\n    this.client.currentRoomId = roomId;\n  }\n\n  get currentPublisherPC() {\n    return this.client?.videoRoomPlugin?.webrtcStuff?.pc ?? null;\n  }\n\n  private async createSession(): Promise<void> {\n    let isResolved = false;\n\n    return new Promise((resolve, reject) => {\n      this.client.createSession({\n        success: () => {\n          isResolved = true;\n          resolve(void 0);\n        },\n        error: (error) => {\n          if (isResolved) {\n            this.onError(error);\n          } else {\n            reject(error);\n          }\n        },\n      });\n    });\n  }\n\n  // joinAsPublisher+Listener\n  public async join(roomId: string, user_id: number, userDisplayName: string): Promise<void> {\n    this.currentUserDisplayName = userDisplayName;\n    this.currentRoomId = roomId;\n    await this.createSession();\n    await this.createHandler(user_id, false, false);\n    await this.joinInternal(this.currentRoomId, user_id);\n  }\n\n  public async joinAsListener(roomId: string, user_id: number, userDisplayName: string): Promise<void> {\n    this.currentUserDisplayName = userDisplayName;\n    this.currentRoomId = roomId;\n    await this.createSession();\n    await this.createHandler(user_id, false, true);\n    await this.joinInternal(this.currentRoomId, user_id);\n  }\n\n  public async sendKeyframeRequest(roomId: string): Promise<unknown> {\n    return new Promise((resolve, reject) => {\n      this.client.sendKeyframeRequest(roomId, {\n        success: resolve,\n        error: reject,\n      });\n    });\n  }\n\n  private async createHandler(user_id: number, isRemote: boolean, skipMedia: boolean = false): Promise<void> {\n    return new Promise((resolve, reject) => {\n      this.client.attachVideoConferencingPlugin(isRemote, user_id, skipMedia, {\n        success: resolve,\n        error: reject,\n        iceState: isRemote\n          ? (iceState) => this.onRemoteIceStateChanged(user_id, iceState)\n          : (iceState) => this.onLocalIceStateChanged(iceState),\n        slowLink: isRemote\n          ? (uplink, nacks) => this.onSlowLink(user_id, uplink, nacks)\n          : (uplink, nacks) => this.onSlowLink(null, uplink, nacks),\n        localStream: this.localStream,\n        displayName: this.currentUserDisplayName,\n      });\n    });\n  }\n\n  private async joinInternal(roomId: string, user_id: number): Promise<void> {\n    return new Promise((resolve, reject) => {\n      this.client.join(roomId, user_id, false, {\n        success: resolve,\n        error: reject,\n        displayName: this.currentUserDisplayName,\n      });\n    });\n  }\n\n  private onParticipantJoined = (user_id: number, userDisplayName: string, isExistingParticipant: boolean): void => {\n    Utils.DLog('[onParticipantJoined]', user_id, userDisplayName, isExistingParticipant);\n    this.createHandler(user_id, true, false);\n    Utils.safeCallbackCall(this.onParticipantJoinedListener)(this, user_id, userDisplayName, isExistingParticipant);\n  };\n\n  private onParticipantLeft = (user_id: number, userDisplayName: string): void => {\n    Utils.DLog('[onParticipantLeft]', user_id, userDisplayName);\n    Utils.safeCallbackCall(this.onParticipantLeftListener)(this, user_id, userDisplayName);\n  };\n\n  private onError = (error: unknown): void => {\n    Utils.DLog('[onError]', JSON.stringify(error));\n    Utils.safeCallbackCall(this.onErrorListener)(this, error);\n  };\n\n  private onDataChannelOpen = (label: unknown): void => {\n    Utils.DLog('[onDataChannelOpen]', label);\n    Utils.safeCallbackCall(this.onDataChannelOpenedListener)(this, label);\n  };\n\n  private onDataChannelMessage = (user_id: number, data: unknown): void => {\n    Utils.DLog('[onDataChannelMessage]', user_id, data);\n    Utils.safeCallbackCall(this.onDataChannelMessageListener)(this, user_id, data);\n  };\n\n  private onLocalIceStateChanged = (iceState: unknown): void => {\n    Utils.DLog('[onLocalIceStateChanged]', iceState);\n    Utils.safeCallbackCall(this.onSessionConnectionStateChangedListener)(this, iceState);\n  };\n\n  private onRemoteIceStateChanged = (user_id: number, iceState: unknown): void => {\n    Utils.DLog('[onRemoteIceStateChanged]', user_id, iceState);\n    Utils.safeCallbackCall(this.onRemoteConnectionStateChangedListener)(this, user_id, iceState);\n  };\n\n  private onRemoteStream = (user_id: number, stream: MediaStream): void => {\n    Utils.DLog('[onRemoteStream]', user_id, stream);\n    Utils.safeCallbackCall(this.onRemoteStreamListener)(this, user_id, stream);\n  };\n\n  private onRemoteTracksUpdated = (user_id: number, track: MediaStreamTrack, eventType: unknown): void => {\n    Utils.DLog('[onRemoteTracksUpdated]', user_id, track, eventType);\n    Utils.safeCallbackCall(this.onRemoteTracksUpdatedListener)(this, user_id, track, eventType);\n  };\n\n  private onSlowLink = (user_id: number | null, uplink: unknown, nacks: unknown): void => {\n    Utils.DLog('[onSlowLink]', user_id, uplink, nacks);\n    Utils.safeCallbackCall(this.onSlowLinkListener)(this, user_id, uplink, nacks);\n  };\n\n  public async listOfOnlineParticipants(): Promise<unknown> {\n    return new Promise((resolve, reject) => {\n      if (this.currentRoomId) {\n        this.client.listOnlineParticipants(this.currentRoomId, {\n          success: resolve,\n          error: reject,\n        });\n      } else {\n        reject('Room ID is not set');\n      }\n    });\n  }\n\n  public async leave(): Promise<void> {\n    this.currentRoomId = null;\n    this.currentUserDisplayName = undefined;\n    await this.leaveGroup();\n    await this.detachVideoConferencingPlugin();\n    await this.destroy();\n\n    if (this.localStream) {\n      this.localStream.getTracks().forEach((track) => track.stop());\n      this.localStream = undefined;\n      this.mediaParams = {};\n    }\n  }\n\n  public async leaveGroup(): Promise<void> {\n    return new Promise((resolve, reject) => {\n      this.client.leave({\n        success: resolve,\n        error: reject,\n      });\n    });\n  }\n\n  public async destroy(): Promise<void> {\n    return new Promise((resolve, reject) => {\n      this.client.destroySession({\n        success: resolve,\n        error: reject,\n      });\n    });\n  }\n\n  public async detachVideoConferencingPlugin(): Promise<void> {\n    return new Promise((resolve, reject) => {\n      this.client.detachVideoConferencingPlugin({\n        success: resolve,\n        error: reject,\n      });\n    });\n  }\n\n  public async getDisplayMedia(params: Media.DisplayParams): Promise<MediaStream> {\n    if (!mediaDevices?.getDisplayMedia) {\n      throw new Error(\"Your environment does not support 'getDisplayMedia' API\");\n    }\n\n    const elementId = params && params.elementId;\n    const options = params && params.options;\n    const mediaParams = { ...params };\n\n    this.mediaParams = mediaParams;\n    delete mediaParams.elementId;\n    delete mediaParams.options;\n\n    try {\n      const stream = await mediaDevices!.getDisplayMedia(mediaParams);\n      return this.upsertStream(stream, elementId, options);\n    } catch (error) {\n      throw error;\n    }\n  }\n\n  public async getUserMedia(params: Media.UserParams): Promise<MediaStream> {\n    if (!mediaDevices?.getUserMedia) {\n      throw new Error(\"Your environment does not support 'getUserMedia' API\");\n    }\n\n    const elementId = params && params.elementId;\n    const options = params && params.options;\n    const mediaParams = { ...params };\n\n    this.mediaParams = mediaParams;\n    delete mediaParams.elementId;\n    delete mediaParams.options;\n\n    try {\n      const stream = await mediaDevices!.getUserMedia(mediaParams);\n      return this.upsertStream(stream, elementId, options);\n    } catch (error) {\n      throw error;\n    }\n  }\n\n  private upsertStream(\n    stream: MediaStream,\n    elementId: string | null = null,\n    options: Media.ElementOptions = {}\n  ): MediaStream {\n    const shouldUpdateCurrentStream = !!this.localStream;\n\n    if (shouldUpdateCurrentStream) {\n      this.replaceTracks(stream);\n    } else {\n      this.localStream = stream;\n    }\n\n    if (!this.localStream) {\n      throw new Error('Local stream is not defined');\n    }\n\n    if (elementId) {\n      if (shouldUpdateCurrentStream) {\n        this.detachMediaStream(elementId, options);\n      }\n      this.attachMediaStream(elementId, this.localStream, options);\n    }\n\n    this.localStream.getTracks().forEach((track) => {\n      const type = track.kind as 'audio' | 'video';\n      const deviceId = track.getSettings().deviceId;\n\n      if (deviceId) {\n        if (typeof this.mediaParams[type] === 'object') {\n          this.mediaParams[type].deviceId = deviceId;\n        } else {\n          this.mediaParams[type] = { deviceId };\n        }\n      }\n    });\n\n    return this.localStream;\n  }\n\n  private replaceTracks(stream: MediaStream): MediaStream {\n    this.localStream?.getTracks().forEach((localTrack) => {\n      if (localTrack.kind === JanusCallType.AUDIO && stream.getAudioTracks().length === 0) {\n        return;\n      } else {\n        localTrack.stop();\n        this.localStream?.removeTrack(localTrack);\n      }\n    });\n\n    stream.getTracks().forEach((newTrack: MediaStreamTrack) => {\n      const pcSenders = this.currentPublisherPC?.getSenders?.();\n      const sender = pcSenders?.find(({ track }: RTCRtpSender) => newTrack.kind === track?.kind);\n\n      if (newTrack.kind === JanusCallType.AUDIO) {\n        newTrack.enabled = this.localStream?.getAudioTracks().every(({ enabled }) => enabled) ?? true;\n      } else {\n        newTrack.enabled = this.localStream?.getVideoTracks().every(({ enabled }) => enabled) ?? true;\n      }\n\n      if (sender) {\n        sender.replaceTrack(newTrack);\n        this.localStream?.addTrack(newTrack);\n      } else {\n        console.warn(`No sender found for track kind: ${newTrack.kind}`);\n      }\n    });\n\n    if (!this.localStream) {\n      throw new Error('Local stream is not defined');\n    }\n\n    return this.localStream;\n  }\n\n  public async switchMediaTracks(options: Media.TrackConstraintsOrDeviceIds): Promise<MediaStream> {\n    [JanusCallType.AUDIO, JanusCallType.VIDEO].forEach((type) => {\n      const device = type === JanusCallType.AUDIO ? options.audio : type === JanusCallType.VIDEO ? options.video : {};\n      const deviceId = typeof device === 'string' ? device : (device?.deviceId ?? null);\n\n      if (deviceId) {\n        if (typeof this.mediaParams[type] === 'object') {\n          this.mediaParams[type].deviceId = deviceId;\n        } else {\n          this.mediaParams[type] = { deviceId };\n        }\n      }\n    });\n\n    try {\n      const mediaParams = {\n        audio: this.mediaParams?.audio ?? false,\n        video: this.mediaParams?.video ?? false,\n      };\n      const stream = await mediaDevices!.getUserMedia(mediaParams);\n      return this.replaceTracks(stream);\n    } catch (error) {\n      throw error;\n    }\n  }\n\n  public muteVideo(): void {\n    if (!this.isVideoMuted()) {\n      this.client.toggleVideoMute();\n    }\n  }\n\n  public unmuteVideo(): void {\n    if (this.isVideoMuted()) {\n      this.client.toggleVideoMute();\n    }\n  }\n\n  public muteAudio(): void {\n    if (!this.isAudioMuted()) {\n      this.client.toggleAudioMute();\n    }\n  }\n\n  public unmuteAudio(): void {\n    if (this.isAudioMuted()) {\n      this.client.toggleAudioMute();\n    }\n  }\n\n  public isVideoMuted(): boolean {\n    return this.client.isVideoMuted();\n  }\n\n  public isAudioMuted(): boolean {\n    return this.client.isAudioMuted();\n  }\n\n  public async getUserVolume(): Promise<unknown> {\n    return new Promise((resolve, _reject) => {\n      return this.client.getVolume(resolve);\n    });\n  }\n\n  public getRemoteUserBitrate(userId: number): unknown {\n    return this.client.getUserBitrate(userId);\n  }\n\n  public async getRemoteUserVolume(userId: number): Promise<unknown> {\n    return new Promise((resolve) => {\n      return this.client.getUserVolume(userId, resolve);\n    });\n  }\n\n  public attachMediaStream(elementId: string, stream: MediaStream, opt?: Media.ElementOptions): void {\n    const mediaElement = document.getElementById(elementId) as HTMLMediaElement;\n\n    if ('srcObject' in mediaElement) {\n      mediaElement.srcObject = stream;\n      mediaElement.style.transform = opt?.mirror ? 'scaleX(-1)' : 'none';\n      if (typeof opt?.muted === 'boolean') {\n        mediaElement.muted = opt?.muted;\n      }\n      mediaElement.onloadedmetadata = async (_event: Event) => {\n        try {\n          await mediaElement.play();\n        } catch (error) {\n          console.error('[VideoChatConference]:', error);\n        }\n      };\n    } else {\n      throw new Error(`Unable to attach media stream, element #${elementId} is undefined`);\n    }\n  }\n\n  public detachMediaStream(elementId: string, opt?: Media.ElementOptions) {\n    const mediaElement = document.getElementById(elementId) as HTMLMediaElement;\n\n    if ('srcObject' in mediaElement) {\n      mediaElement.pause();\n      mediaElement.srcObject = null;\n      mediaElement.style.transform = opt?.mirror ? 'scaleX(-1)' : 'none';\n      if (typeof opt?.muted === 'boolean') {\n        mediaElement.muted = opt?.muted;\n      }\n    } else {\n      throw new Error(`Unable to attach media stream, element #${elementId} is undefined`);\n    }\n  }\n\n  public async sendData(data: unknown, label: unknown): Promise<unknown> {\n    return new Promise((resolve, reject) => {\n      if (!this.client.videoRoomPlugin?.data) {\n        reject(new Error('Video room plugin or data channel is not available'));\n        return;\n      }\n\n      this.client.videoRoomPlugin.data({\n        data,\n        label,\n        success: resolve,\n        error: reject,\n      });\n    });\n  }\n}\n","import type { Janus } from '../types';\nimport { JanusCallType, ConferenceEvent, DeviceInputType } from '../types/constants';\nimport { mediaDevices } from '@platform';\nimport ConferenceSession from './ConferenceSession';\nimport ProxyService from '../Proxy';\n\nexport default class ConferenceClient {\n  public proxy: ProxyService;\n  public DeviceInputType: typeof DeviceInputType = DeviceInputType;\n  public JanusCallType: typeof JanusCallType = JanusCallType;\n  public sessionsStore: { [id: ConferenceSession['id']]: ConferenceSession } = {};\n  declare onParticipantJoinedListener: Janus.OnParticipantJoinedListener;\n  declare onParticipantLeftListener: Janus.OnParticipantLeftListener;\n  declare onSlowLinkListener: Janus.OnSlowLinkListener;\n  declare onRemoteStreamListener: Janus.OnRemoteStreamListener;\n  declare onRemoteTracksUpdatedListener: Janus.OnRemoteTracksUpdatedListener;\n  declare onRemoteConnectionStateChangedListener: Janus.OnRemoteConnectionStateChangedListener;\n  declare onDataChannelOpenedListener: Janus.OnDataChannelOpenedListener;\n  declare onDataChannelMessageListener: Janus.OnDataChannelMessageListener;\n  declare onSessionConnectionStateChangedListener: Janus.OnSessionConnectionStateChangedListener;\n  declare onErrorListener: Janus.OnErrorListener;\n\n  constructor(proxy: ProxyService) {\n    this.proxy = proxy;\n  }\n\n  createNewSession() {\n    const session = new ConferenceSession(this.getCurrentSessionToken());\n\n    this.sessionsStore[session.id] = session;\n    session.onParticipantJoinedListener = this.onParticipantJoinedListener;\n    session.onParticipantLeftListener = this.onParticipantLeftListener;\n    session.onSlowLinkListener = this.onSlowLinkListener;\n    session.onRemoteStreamListener = this.onRemoteStreamListener;\n    session.onRemoteTracksUpdatedListener = this.onRemoteTracksUpdatedListener;\n    session.onRemoteConnectionStateChangedListener = this.onRemoteConnectionStateChangedListener;\n    session.onDataChannelOpenedListener = this.onDataChannelOpenedListener;\n    session.onDataChannelMessageListener = this.onDataChannelMessageListener;\n    session.onSessionConnectionStateChangedListener = this.onSessionConnectionStateChangedListener;\n    session.onErrorListener = this.onErrorListener;\n\n    return session;\n  }\n\n  public async getMediaDevices(kind?: DeviceInputType): Promise<MediaDeviceInfo[]> {\n    if (mediaDevices?.enumerateDevices) {\n      const devices = await mediaDevices.enumerateDevices();\n      return kind ? devices.filter((device) => device.kind === kind) : devices;\n    } else {\n      throw new Error(\"No 'enumerateDevices' API supported\");\n    }\n  }\n\n  public clearSession(session_id: ConferenceSession['id']): void {\n    delete this.sessionsStore[session_id];\n  }\n\n  public getCurrentSessionToken(): string {\n    const currentSession = this.proxy.getSession();\n\n    if (currentSession?.token) {\n      return currentSession.token;\n    } else {\n      throw new Error('Session does not exist');\n    }\n  }\n\n  private getListenerByName(name: ConferenceEvent): Janus.ListenerName | null {\n    switch (name) {\n      case ConferenceEvent.JOIN:\n        return 'onParticipantJoinedListener';\n      case ConferenceEvent.LEFT:\n        return 'onParticipantLeftListener';\n      case ConferenceEvent.SLOW_LINK:\n        return 'onSlowLinkListener';\n      case ConferenceEvent.REMOTE_STREAM:\n        return 'onRemoteStreamListener';\n      case ConferenceEvent.REMOTE_TRACKS_UPDATED:\n        return 'onRemoteTracksUpdatedListener';\n      case ConferenceEvent.REMOTE_CONNECTION_STATE:\n        return 'onRemoteConnectionStateChangedListener';\n      case ConferenceEvent.DATA_CHANNEL_OPENED:\n        return 'onDataChannelOpenedListener';\n      case ConferenceEvent.DATA_CHANNEL_MESSAGE:\n        return 'onDataChannelMessageListener';\n      case ConferenceEvent.SESSION_CONNECTION_STATE:\n        return 'onSessionConnectionStateChangedListener';\n      case ConferenceEvent.ERROR:\n        return 'onErrorListener';\n      default:\n        return null;\n    }\n  }\n\n  public addListener(name: ConferenceEvent, listener: Janus.Listeners): () => void {\n    const listenerName = this.getListenerByName(name);\n    if (listenerName) {\n      (this[listenerName] as Janus.Listeners) = listener;\n    }\n    return this.removeListener.bind(this, name);\n  }\n\n  public removeListener(name: ConferenceEvent): void {\n    const listenerName = this.getListenerByName(name);\n    if (listenerName) {\n      (this[listenerName] as Janus.Listeners | undefined) = undefined;\n    }\n  }\n\n  public removeAllListeners(): void {\n    Object.keys(this).forEach((key) => {\n      if (key.startsWith('on') && key.endsWith('Listener') && typeof this[key as Janus.ListenerName] === 'function') {\n        (this[key as Janus.ListenerName] as Janus.Listeners | undefined) = undefined;\n      }\n    });\n  }\n}\n","import type { Data, EmptyResponse, SearchCondition } from './types';\nimport { ProxyMethod, ProxyType } from './types/constants';\nimport ProxyService from './Proxy';\nimport Utils from './Utils';\nimport config from './config';\n\nexport default class DataService {\n  public proxy: ProxyService;\n  readonly route = config.urls.data;\n\n  constructor(proxy: ProxyService) {\n    this.proxy = proxy;\n  }\n\n  public async create(className: string, params: Data.CreateParams = {}): Promise<Data.DataRecord> {\n    const isMany = Utils.isArray(params);\n    const multi = isMany ? 'multi' : undefined;\n    const ajaxParams = {\n      type: ProxyMethod.POST,\n      url: Utils.getUrl(this.route, className, multi),\n      data: isMany ? { record: this.createRecord(params) } : params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async list(className: string, params: Data.ListParams = {}): Promise<Data.ListResponse> {\n    const ext = typeof params === 'string' ? params : Utils.isArray(params) ? params.toString() : undefined;\n    const ajaxParams = {\n      url: Utils.getUrl(this.route, className, ext),\n      data: ext ? undefined : params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async readPermissions(className: string, id: string): Promise<Data.ReadPermissionsResponse> {\n    const ajaxParams = {\n      url: Utils.getUrl(this.route, className, id),\n      data: { permissions: 1 },\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async update(\n    className: string,\n    params: Data.UpdateOptions | Data.UpdateOptions[] = {}\n  ): Promise<Data.UpdateResponse | Data.DataRecord> {\n    const isMany = Utils.isArray(params);\n    const isSearch = !isMany && params.search_criteria;\n    const ext = isMany ? 'multi' : isSearch ? 'by_criteria' : params.id || params._id || '';\n    const ajaxParams = {\n      type: ProxyMethod.PUT,\n      url: Utils.getUrl(this.route, className, ext),\n      data: isMany ? { record: this.createRecord(params) } : params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async delete(\n    className: string,\n    params: string | string[] | SearchCondition<string | number | undefined>\n  ): Promise<Data.DeleteResponse | EmptyResponse> {\n    const isCriteria = Utils.isObject(params);\n    const isOne = typeof params === 'string' || (Utils.isArray(params) && params.length === 1);\n    const ext = isCriteria ? 'by_criteria' : typeof params === 'string' ? params : (params?.toString() ?? '');\n    const ajaxParams = {\n      type: ProxyMethod.DELETE,\n      url: Utils.getUrl(this.route, className, ext),\n      data: isCriteria ? params : undefined,\n      dataType: isOne ? ProxyType.TEXT : undefined,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  private createRecord(params: Data.CreateRecord[] = []): object {\n    return params.reduce((items, item, index) => {\n      const key = index + 1;\n      const id = item.id || item._id;\n      const record = id ? { ...item, id } : item;\n\n      return { ...items, [key]: record };\n    }, {});\n  }\n}\n","import type { EmptyResponse, Meetings } from './types';\nimport { ProxyMethod, ProxyType } from './types/constants';\nimport ProxyService from './Proxy';\nimport Utils from './Utils';\nimport config from './config';\n\nexport default class MeetingsService {\n  public proxy: ProxyService;\n  readonly route = config.urls.meetings;\n\n  constructor(proxy: ProxyService) {\n    this.proxy = proxy;\n  }\n\n  public async get(params: Meetings.GetParams = {}): Promise<Meetings.Meeting | Meetings.Meeting[]> {\n    const ajaxParams = {\n      type: ProxyMethod.GET,\n      url: Utils.getUrl(this.route),\n      data: params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async create(params: Meetings.CreateParams = {}): Promise<Meetings.Meeting> {\n    const MINUTE = 60;\n    const startTimestamp = Math.ceil(Date.now() / 1000);\n    const endTimestamp = startTimestamp + 60 * MINUTE;\n    const defaultName = new Date(startTimestamp).toLocaleString('en', {\n      year: 'numeric',\n      month: 'long',\n      day: 'numeric',\n      hour: 'numeric',\n      minute: 'numeric',\n    });\n    const defaultParams = {\n      name: defaultName,\n      start_date: startTimestamp,\n      end_date: endTimestamp,\n      attendees: [],\n      record: false,\n      chat: false,\n    };\n    const ajaxParams = {\n      type: ProxyMethod.POST,\n      url: Utils.getUrl(this.route),\n      data: { ...defaultParams, ...params },\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async update(id: string | number, params: Meetings.MeetingParams): Promise<Meetings.Meeting> {\n    const ajaxParams = {\n      type: ProxyMethod.PUT,\n      url: Utils.getUrl(this.route, id),\n      data: params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async delete(id: string | number): Promise<EmptyResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.DELETE,\n      url: Utils.getUrl(this.route, id),\n      dataType: ProxyType.TEXT,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async getRecordings(id: string | number): Promise<Meetings.Recording[]> {\n    const ajaxParams = {\n      type: ProxyMethod.GET,\n      url: Utils.getUrl(this.route, 'recordings', id),\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n}\n","import type { EmptyResponse, PushNotifications } from './types';\nimport { encode } from 'js-base64';\nimport { ProxyMethod, ProxyType } from './types/constants';\nimport config from './config';\nimport ProxyService from './Proxy';\nimport Utils from './Utils';\n\nexport default class PushNotificationsService {\n  public proxy: ProxyService;\n  public subscriptions: SubscriptionsService;\n  public events: EventsService;\n\n  constructor(proxy: ProxyService) {\n    this.proxy = proxy;\n    this.subscriptions = new SubscriptionsService(proxy);\n    this.events = new EventsService(proxy);\n  }\n\n  public base64Encode = encode;\n}\n\nclass SubscriptionsService {\n  public proxy: ProxyService;\n  readonly route = config.urls.subscriptions;\n\n  constructor(proxy: ProxyService) {\n    this.proxy = proxy;\n  }\n\n  public async create(params: PushNotifications.SubscriptionsCreateParams): Promise<PushNotifications.Subscription> {\n    const ajaxParams = {\n      type: ProxyMethod.POST,\n      url: Utils.getUrl(this.route),\n      data: params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async list(): Promise<PushNotifications.Subscription[]> {\n    const ajaxParams = {\n      type: ProxyMethod.GET,\n      url: Utils.getUrl(this.route),\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async delete(id: string | number): Promise<EmptyResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.DELETE,\n      dataType: ProxyType.TEXT,\n      url: Utils.getUrl(this.route, id),\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n}\n\nclass EventsService {\n  public proxy: ProxyService;\n  readonly route = config.urls.events;\n\n  constructor(proxy: ProxyService) {\n    this.proxy = proxy;\n  }\n\n  public async create(event: PushNotifications.EventsCreateParams): Promise<PushNotifications.Event[]> {\n    const ajaxParams = {\n      type: ProxyMethod.POST,\n      url: Utils.getUrl(this.route),\n      data: { event },\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n}\n","import type { EmptyResponse, PlainObject, Proxy, Storage, StringObject, StringOrStringObject } from './types';\nimport { ProxyMethod, ProxyType } from './types/constants';\nimport ProxyService from './Proxy';\nimport Utils from './Utils';\nimport config from './config';\n\nexport default class StorageService {\n  public proxy: ProxyService;\n  readonly route = config.urls.blobs;\n\n  constructor(proxy: ProxyService) {\n    this.proxy = proxy;\n  }\n\n  public async list(params: Storage.ListParams = {}): Promise<Storage.ListResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.GET,\n      url: Utils.getUrl(this.route),\n      data: params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async create(params?: Storage.CreateParams): Promise<Storage.BlobResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.POST,\n      url: Utils.getUrl(this.route),\n      data: { blob: params },\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async delete(id: number | string): Promise<EmptyResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.DELETE,\n      url: Utils.getUrl(this.route, id),\n      dataType: ProxyType.TEXT,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async createAndUpload(params: Storage.CreateAndUploadParams): Promise<Storage.Blob> {\n    const { name, file, size, abort_id, type: content_type, public: isPublic = true } = params;\n    const createParams = { name, content_type, public: isPublic };\n\n    let blob: Storage.Blob;\n\n    return this.create(createParams)\n      .then(({ blob: blobObject }) => {\n        blob = blobObject;\n        const uri = this.parseUri(blob.blob_object_access?.params);\n        const uploadUrl = `${uri.protocol}://${uri.authority}${uri.path}`;\n        const uploadParams: Proxy.Params = { url: uploadUrl, data: {} };\n\n        if (abort_id) {\n          uploadParams.abort_id = abort_id;\n        }\n\n        const queryKey = typeof uri.queryKey === 'object' && uri.queryKey !== null ? uri.queryKey : {};\n        const data = (uploadParams.data ?? {}) as PlainObject;\n\n        Object.keys(queryKey).forEach((key) => {\n          data[key] = decodeURIComponent(queryKey[key]);\n        });\n        data.file = file;\n        uploadParams.data = data;\n\n        return this.upload(uploadParams).then(() => blob);\n      })\n      .then((blob) => this.markUploaded({ id: blob.id, size }).then(() => blob))\n      .then((blob) => ({ ...blob, size }));\n  }\n\n  public async upload(params: Proxy.Params): Promise<any> {\n    const ajaxParams = {\n      ...params,\n      type: ProxyMethod.POST,\n      dataType: ProxyType.TEXT,\n      contentType: false,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async markUploaded(params: Storage.MarkUploadedParams): Promise<EmptyResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.PUT,\n      url: Utils.getUrl(this.route, params.id, 'complete'),\n      data: {\n        size: params.size,\n      },\n      dataType: ProxyType.TEXT,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async getInfo(id: number | string): Promise<Storage.BlobResponse> {\n    const ajaxParams = {\n      url: Utils.getUrl(this.route, id),\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async getFile(uid: string): Promise<Storage.BlobResponse> {\n    const ajaxParams = {\n      url: Utils.getUrl(this.route, uid),\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async getFileObject(uid: string, params: Storage.GetFileObjectParams): Promise<Storage.BlobResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.GET,\n      url: Utils.getUrl(this.route, uid, 'object'),\n      data: params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async update(params: Storage.UpdateParams): Promise<Storage.BlobResponse> {\n    const data = { blob: {} as PlainObject };\n\n    if (typeof params.name !== 'undefined') {\n      data.blob.name = params.name;\n    }\n\n    const ajaxParams = {\n      url: Utils.getUrl(this.route, params.id),\n      data: data,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public privateUrl(fileUID: string = ''): string {\n    return `${config.endpoints.api_url ?? `https://${config.endpoints.api}`}/blobs/${fileUID}?token=${this.proxy.getSession()?.token}`;\n  }\n\n  public publicUrl(fileUID: string = ''): string {\n    return `${config.endpoints.api_url ?? `https://${config.endpoints.api}`}/blobs/${fileUID}`;\n  }\n\n  private parseUri(str: string = ''): Record<string, StringOrStringObject> {\n    const options = {\n      strictMode: false,\n      key: [\n        'source',\n        'protocol',\n        'authority',\n        'userInfo',\n        'user',\n        'password',\n        'host',\n        'port',\n        'relative',\n        'path',\n        'directory',\n        'file',\n        'query',\n        'anchor',\n      ] as const,\n      q: {\n        name: 'queryKey',\n        parser: /(?:^|&)([^&=]*)=?([^&]*)/g,\n      },\n      parser: {\n        strict:\n          /^(?:([^:\\/?#]+):)?(?:\\/\\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\\/?#]*)(?::(\\d*))?))?((((?:[^?#\\/]*\\/)*)([^?#]*))(?:\\?([^#]*))?(?:#(.*))?)/,\n        loose:\n          /^(?:(?![^:@]+:[^:@\\/]*@)([^:\\/?#.]+):)?(?:\\/\\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\\/?#]*)(?::(\\d*))?)(((\\/(?:[^?#](?![^?#\\/]*\\.[^?#\\/.]+(?:[?#]|$)))*\\/?)?([^?#\\/]*))(?:\\?([^#]*))?(?:#(.*))?)/,\n      },\n    };\n\n    const m = options.parser[options.strictMode ? 'strict' : 'loose'].exec(str) ?? [];\n\n    const uri = {\n      source: '',\n      protocol: '',\n      authority: '',\n      userInfo: '',\n      user: '',\n      password: '',\n      host: '',\n      port: '',\n      relative: '',\n      path: '',\n      directory: '',\n      file: '',\n      query: '',\n      anchor: '',\n      queryKey: {} as StringObject,\n    };\n\n    options.key.forEach((key, i) => {\n      uri[key] = m[i] ?? '';\n    });\n\n    uri.query.replace(options.q.parser, (_0: string, k: string, v: string) => {\n      if (k) uri.queryKey[k] = v;\n      return '';\n    });\n\n    return uri;\n  }\n}\n","import type { EmptyResponse, PlainObject, StringObject, Users } from './types';\nimport { ProxyMethod, ProxyType } from './types/constants';\nimport config from './config';\nimport ProxyService from './Proxy';\nimport Utils from './Utils';\n\nexport default class UsersService {\n  public proxy: ProxyService;\n  readonly route = config.urls.users;\n\n  constructor(proxy: ProxyService) {\n    this.proxy = proxy;\n  }\n\n  public async getV2(params: Users.GetV2Params): Promise<Users.GetV2Response> {\n    const ajaxParams = {\n      type: ProxyMethod.GET,\n      url: Utils.getUrl(this.route, 'v2'),\n      useArrayQuery: true,\n      data: params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async signup(user: Users.SignUpParams, auth_key?: string): Promise<Users.UserResponse> {\n    const ajaxParams = {\n      authKey: auth_key ?? config.creds.authKey,\n      type: ProxyMethod.POST,\n      url: Utils.getUrl(this.route),\n      data: { user },\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async update(user: Users.UpdateParams = {}): Promise<Users.UserResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.PUT,\n      url: Utils.getUrl(this.route, this.proxy.getCurrentUserId()),\n      data: { user },\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async delete(): Promise<EmptyResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.DELETE,\n      url: Utils.getUrl(this.route, this.proxy.getCurrentUserId()),\n      dataType: ProxyType.TEXT,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async resetPassword(email: string = ''): Promise<EmptyResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.POST,\n      url: Utils.getUrl(this.route, 'password', 'reset'),\n      data: { email },\n      dataType: ProxyType.TEXT,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async listOnline(params: Users.ListOnlineParams = {}): Promise<Users.UsersResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.GET,\n      url: Utils.getUrl(this.route, 'online'),\n      data: params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async getOnlineCount(): Promise<Users.OnlineCountResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.GET,\n      url: Utils.getUrl(this.route, 'online'),\n      data: { count: true },\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  /**\n   * @deprecated Use `getV2(params)` instead.\n   */\n  public async get(params: PlainObject): Promise<Users.OldGetResponse | Users.UserResponse> {\n    let data = Utils.cloneObject(params) as PlainObject;\n    let url: string | number = '';\n\n    const filters: string[] = [];\n    const dateFields = ['created_at', 'updated_at', 'last_request_at'];\n    const numberFields = ['id', 'external_user_id'];\n    const extensions: StringObject = {\n      login: 'by_login',\n      full_name: 'by_full_name',\n      facebook_id: 'by_facebook_id',\n      twitter_id: 'by_twitter_id',\n      phone: 'phone',\n      email: 'by_email',\n      tags: 'by_tags',\n      external: 'external',\n    };\n\n    function generateFilter(filter: PlainObject): string {\n      const obj = Utils.cloneObject(filter) as PlainObject;\n      const field = String(obj.field ?? '');\n      let type = dateFields.includes(field) ? 'date' : typeof obj.value;\n\n      if (Utils.isArray(obj.value)) {\n        if (type === 'object') {\n          type = typeof (obj.value as unknown[])[0];\n        }\n        obj.value = (obj.value as unknown[]).toString();\n      }\n\n      return [type, field, obj.param, obj.value].join(' ');\n    }\n\n    if (data.order) {\n      const order = data.order as PlainObject;\n      const field = String(order.field ?? '');\n      const type = field in dateFields ? 'date' : field in numberFields ? 'number' : 'string';\n      data.order = [order.sort, type, order.field].join(' ');\n    }\n\n    if (data && data.filter) {\n      if (Utils.isArray(data.filter)) {\n        (data.filter as unknown[]).forEach((filter: unknown) => {\n          filters.push(generateFilter((filter as PlainObject) ?? {}));\n        });\n      } else {\n        filters.push(generateFilter((data.filter as PlainObject) ?? {}));\n      }\n      data.filter = filters;\n    }\n\n    if (typeof data === 'number') {\n      url = data;\n      data = undefined as unknown as PlainObject;\n    } else {\n      for (const key in extensions) {\n        if (data[key]) {\n          url = extensions[key];\n\n          if (key === extensions.external) {\n            url += `/${data[extensions.external]}`;\n            data = undefined as unknown as PlainObject;\n          }\n\n          break;\n        }\n      }\n    }\n\n    const ajaxParams = {\n      type: ProxyMethod.GET,\n      url: Utils.getUrl(this.route, url),\n      data,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n}\n","import { navigator } from '@platform';\nimport config from '../config';\n\nexport default class WebRTCHelpers {\n  static getUserJid(id: string | number): string {\n    return `${id}-${config.creds.appId}@${config.endpoints.chat}`;\n  }\n\n  static getUserIdFromJID(jid: string): number | null {\n    return jid?.includes('@') ? parseInt(jid.split('@')[0].split('-')[0]) : null;\n  }\n\n  static trace(text: string): void {\n    if (config.debug) {\n      console.log('[VideoChat]:', text);\n    }\n  }\n\n  static traceWarning(text: string): void {\n    if (config.debug) {\n      console.warn('[VideoChat]:', text);\n    }\n  }\n\n  static traceError(text: string): void {\n    if (config.debug) {\n      console.error('[VideoChat]:', text);\n    }\n  }\n\n  static get getVersionFirefox(): number {\n    const ua = navigator?.userAgent ?? null;\n    let version = 0;\n    if (ua) {\n      const ffInfo = ua.match(/(?:firefox)[ \\/](\\d+)/i) || [];\n      version = ffInfo[1] ? +ffInfo[1] : 0;\n    }\n    return typeof version === 'string' ? parseInt(version) : version;\n  }\n\n  static get getVersionSafari(): number {\n    const ua = navigator?.userAgent ?? null;\n    let version = 0;\n    if (ua) {\n      const sInfo = ua.match(/(?:safari)[ \\/](\\d+)/i) || [];\n      if (sInfo.length) {\n        const sVer = ua.match(/(?:version)[ \\/](\\d+)/i) || [];\n        if (sVer) {\n          version = sVer[1] ? +sVer[1] : 0;\n        }\n      }\n    }\n\n    return typeof version === 'string' ? parseInt(version) : version;\n  }\n}\n","import type { Calls, Config } from '../types';\nimport type WebRTCSession from './WebRTCSession';\nimport { CallSessionConnectionState, CallType, MediaType, PeerConnectionState } from '../types/constants';\nimport { RTCPeerConnection, RTCSessionDescription, MediaStream } from '@platform';\nimport config from '../config';\nimport WebRTCHelpers from './WebRTCHelpers';\n\nexport default class WebRTCPeerConnection {\n  declare original: RTCPeerConnection;\n  declare session: WebRTCSession;\n  declare userID: number;\n  declare type: RTCSdpType;\n  public remoteSDP: string | null = null;\n  public state: PeerConnectionState = PeerConnectionState.NEW;\n  public iceCandidates: RTCIceCandidateInit[] = [];\n  public answerTimeInterval: number = 0;\n  public onStatusClosedChecker: NodeJS.Timeout | number | null = null;\n  public dialingTimer: NodeJS.Timeout | number | null = null;\n  public statsReportTimer: NodeJS.Timeout | number | null = null;\n  public waitingReconnectTimeoutCallback: NodeJS.Timeout | number | null = null;\n  public released: boolean = false;\n\n  public remoteStream: MediaStream = (() => {\n    if (!MediaStream) {\n      throw new Error('MediaStream is not available');\n    }\n\n    return new MediaStream();\n  })();\n\n  constructor(session: WebRTCSession, userID: number, type: RTCSdpType) {\n    this.create();\n    this.setup(session, userID, type);\n  }\n\n  private create() {\n    const rtcConfiguration: RTCConfiguration = {\n      iceTransportPolicy: (config.videochat.alwaysRelayCalls ? 'relay' : 'all') as RTCIceTransportPolicy,\n      iceServers: config.videochat.iceServers?.map(\n        (item: Config.VideochatIceServer): RTCIceServer => ({\n          urls: item.urls ?? item.url,\n          username: item.username,\n          credential: item.credential,\n        })\n      ) as RTCIceServer[],\n    };\n\n    this.original = RTCPeerConnection ? new RTCPeerConnection(rtcConfiguration) : ({} as RTCPeerConnection);\n\n    WebRTCHelpers.trace(`new RTCPeerConnection(${JSON.stringify(rtcConfiguration, null, 2)})`);\n  }\n\n  private setup(session: WebRTCSession, userID: number, type: RTCSdpType): void {\n    this.type = type;\n    this.userID = userID;\n    this.session = session;\n    this.session.startCallTime = Date.now();\n\n    this.original.addEventListener('track', this.onMediaTrackHandler);\n    this.original.addEventListener('icecandidate', this.onIceCandidateHandler);\n    this.original.addEventListener('signalingstatechange', this.onSignalingStateHandler);\n    this.original.addEventListener('iceconnectionstatechange', this.onIceConnectionStateHandler);\n\n    WebRTCHelpers.trace(`RTCPeerConnection init. ${this.toString()}`);\n  }\n\n  private onMediaTrackHandler = (event: RTCTrackEvent): void => {\n    this.remoteStream.addTrack(event.track);\n\n    if (\n      (this.session.callType == CallType.VIDEO && this.remoteStream.getVideoTracks().length) ||\n      (this.session.callType == CallType.AUDIO && this.remoteStream.getAudioTracks().length)\n    ) {\n      this.session.onRemoteStream(this.userID, this.remoteStream);\n    }\n\n    this.getWrappedStats();\n  };\n\n  private onIceCandidateHandler = (event: RTCPeerConnectionIceEvent): void => {\n    if (event.candidate) {\n      const { sdpMLineIndex, sdpMid, candidate } = event.candidate;\n      const iceCandidate: RTCIceCandidateInit = { sdpMLineIndex, sdpMid, candidate };\n\n      if (this.signalingState === 'stable' && this.original.canTrickleIceCandidates) {\n        this.session.processIceCandidates(this.userID, [iceCandidate]);\n      } else {\n        this.iceCandidates.push(iceCandidate);\n      }\n    }\n  };\n\n  private onSignalingStateHandler = async (): Promise<void> => {\n    WebRTCHelpers.trace(`onSignalingStateHandler: ${this.signalingState}`);\n\n    if (this.signalingState === 'stable' && this.iceCandidates.length > 0) {\n      this.session.processIceCandidates(this.userID, this.iceCandidates);\n      this.iceCandidates.length = 0;\n    }\n  };\n\n  /** handler of remote media stream */\n  private onIceConnectionStateHandler = (): void => {\n    WebRTCHelpers.trace(`onIceConnectionStateHandler: ${this.iceConnectionState}`);\n\n    if (this.onStatusClosedChecker && WebRTCHelpers.getVersionSafari >= 11) {\n      clearTimeout(this.onStatusClosedChecker);\n    }\n\n    switch (this.iceConnectionState) {\n      case 'checking':\n        this.state = PeerConnectionState.CHECKING;\n        this.session.onSessionConnectionStateChanged(this.userID, CallSessionConnectionState.CONNECTING);\n        break;\n      case 'connected':\n        this.state = PeerConnectionState.CONNECTED;\n        this.clearWaitingReconnectTimer();\n        this.session.onSessionConnectionStateChanged(this.userID, CallSessionConnectionState.CONNECTED);\n        break;\n      case 'completed':\n        this.state = PeerConnectionState.COMPLETED;\n        this.clearWaitingReconnectTimer();\n        this.session.onSessionConnectionStateChanged(this.userID, CallSessionConnectionState.COMPLETED);\n        break;\n      case 'failed':\n        this.state = PeerConnectionState.FAILED;\n        this.session.onSessionConnectionStateChanged(this.userID, CallSessionConnectionState.FAILED);\n        break;\n      case 'disconnected':\n        this.state = PeerConnectionState.DISCONNECTED;\n        this.startWaitingReconnectTimer();\n        this.session.onSessionConnectionStateChanged(this.userID, CallSessionConnectionState.DISCONNECTED);\n        if (WebRTCHelpers.getVersionSafari >= 11) {\n          this.onStatusClosedChecker = setTimeout(() => {\n            this.onIceConnectionStateHandler(); // repeat to get status \"closed\"\n          }, 500);\n        }\n        break;\n      case 'closed': // TODO: this state doesn't fires on Safari 11\n        this.state = PeerConnectionState.CLOSED;\n        this.clearWaitingReconnectTimer();\n        this.session.onSessionConnectionStateChanged(this.userID, CallSessionConnectionState.CLOSED);\n        break;\n      default:\n        break;\n    }\n  };\n\n  private clearWaitingReconnectTimer(): void {\n    if (this.waitingReconnectTimeoutCallback) {\n      WebRTCHelpers.trace('clearWaitingReconnectTimer');\n      clearTimeout(this.waitingReconnectTimeoutCallback);\n      this.waitingReconnectTimeoutCallback = null;\n    }\n  }\n\n  private startWaitingReconnectTimer(): void {\n    const timeout = (config.videochat.disconnectTimeInterval ?? 30) * 1000;\n\n    WebRTCHelpers.trace(`startWaitingReconnectTimer, timeout: ${timeout}`);\n\n    this.waitingReconnectTimeoutCallback = setTimeout(() => {\n      WebRTCHelpers.trace('waitingReconnectTimeoutCallback');\n      if (this.waitingReconnectTimeoutCallback) {\n        clearTimeout(this.waitingReconnectTimeoutCallback);\n      }\n      this.release();\n      this.session.closeSessionIfAllConnectionsClosed();\n    }, timeout);\n  }\n\n  private clearStatsReportTimer(): void {\n    if (this.statsReportTimer) {\n      clearInterval(this.statsReportTimer);\n      this.statsReportTimer = null;\n    }\n  }\n\n  public async addCandidates(iceCandidates: RTCIceCandidateInit[]): Promise<void> {\n    for (const iceCandidate of iceCandidates) {\n      if (iceCandidate?.candidate) {\n        try {\n          await this.addIceCandidate(iceCandidate);\n          WebRTCHelpers.trace(`'addIceCandidate' success: ${this.signalingState}`);\n        } catch (error) {\n          WebRTCHelpers.traceError(`'addIceCandidate' error: ${error}`);\n        }\n      }\n    }\n  }\n\n  public release(): void {\n    this.clearDialingTimer();\n    this.clearStatsReportTimer();\n    this.close();\n    if (WebRTCHelpers.getVersionSafari >= 11) {\n      this.onIceConnectionStateHandler(); // TODO: 'closed' state doesn't fires on Safari 11 (do it manually)\n    }\n    this.original.removeEventListener('track', this.onMediaTrackHandler);\n    this.original.removeEventListener('icecandidate', this.onIceCandidateHandler);\n    this.original.removeEventListener('signalingstatechange', this.onSignalingStateHandler);\n    this.original.removeEventListener('iceconnectionstatechange', this.onIceConnectionStateHandler);\n    this.released = true;\n    WebRTCHelpers.trace(`RTCPeerConnection closed. ${this.toString()}`);\n  }\n\n  public clearDialingTimer(): void {\n    if (this.dialingTimer) {\n      WebRTCHelpers.trace('clearDialingTimer');\n      clearInterval(this.dialingTimer);\n      this.dialingTimer = null;\n      this.answerTimeInterval = 0;\n    }\n  }\n\n  public async getAndSetLocalSessionDescription(\n    maxBandwidth: number,\n    iceRestart: boolean = false\n  ): Promise<RTCSessionDescriptionInit> {\n    this.state = PeerConnectionState.CONNECTING;\n\n    try {\n      const offerOptions = iceRestart ? { iceRestart } : undefined;\n      const sessionDescription =\n        this.type === 'offer' ? await this.createOffer(offerOptions) : await this.createAnswer();\n\n      await this.setLocalDescription(sessionDescription);\n      this.setRTCRtpSenderMaxBandwidth(maxBandwidth);\n\n      return sessionDescription;\n    } catch (error) {\n      throw error;\n    }\n  }\n\n  public setRTCRtpSenderMaxBandwidth(maxBandwidth: number): void {\n    const senders = this.getSenders() || [];\n    const maxBitrate = maxBandwidth ? Math.round(maxBandwidth * 1000) : 0;\n\n    senders.forEach((sender: RTCRtpSender) => {\n      if (sender.track?.kind === MediaType.VIDEO) {\n        const params = sender.getParameters();\n\n        params.encodings ??= [{}];\n        params.encodings.forEach((encoding) => {\n          if (maxBitrate > 0) {\n            encoding.maxBitrate = maxBitrate;\n          } else {\n            delete encoding.maxBitrate;\n          }\n        });\n\n        sender\n          .setParameters(params)\n          .then(() => {\n            WebRTCHelpers.trace(\n              `Set 'maxBandwidth' for ${this.userID}: ${maxBandwidth > 0 ? `${maxBandwidth} kbps` : 'unlimited'}`\n            );\n          })\n          .catch((error) => {\n            WebRTCHelpers.traceWarning(`Set 'maxBandwidth' for ${this.userID}: ${error}`);\n          });\n      }\n    });\n  }\n\n  public startDialingTimer(extension: Calls.ExtensionParams, withOnNotAnswerCallback: boolean): void {\n    const dialingTimeInterval = (config.videochat.dialingTimeInterval ?? 5) * 1000;\n    const answerTimeInterval = (config.videochat.answerTimeInterval ?? 60) * 1000;\n\n    WebRTCHelpers.trace(`startDialingTimer, dialingTimeInterval: ${JSON.stringify(dialingTimeInterval)}`);\n\n    const dialingCallback = (\n      extension: Calls.ExtensionParams,\n      withOnNotAnswerCallback: boolean,\n      skipIncrement: boolean\n    ) => {\n      if (!skipIncrement) {\n        this.answerTimeInterval += dialingTimeInterval;\n      }\n\n      WebRTCHelpers.trace(`dialingCallback, extension: ${JSON.stringify(extension)}`);\n\n      if (this.answerTimeInterval >= answerTimeInterval) {\n        this.clearDialingTimer();\n\n        if (withOnNotAnswerCallback) {\n          this.session.processOnNotAnswer(this);\n        }\n      } else {\n        this.session.processCall(this, extension);\n      }\n    };\n\n    this.dialingTimer = setInterval(dialingCallback, dialingTimeInterval, extension, withOnNotAnswerCallback, false);\n\n    dialingCallback(extension, withOnNotAnswerCallback, true); // call for the 1st time\n  }\n\n  public async setRemoteSessionDescription(type: RTCSdpType, sdp: string): Promise<void> {\n    const desc = new RTCSessionDescription!({ sdp, type });\n    return this.setRemoteDescription(desc);\n  }\n\n  private getWrappedStats(): void {\n    if (config.videochat.statsReportTimeInterval) {\n      let lastResult: RTCStatsReport;\n\n      WebRTCHelpers.trace('Stats tracker has been started');\n\n      this.statsReportTimer = setInterval(() => {\n        this.getStatsCustom(\n          lastResult,\n          (results, lastResults) => {\n            lastResult = lastResults;\n            this.session.onCallStatsReport(this.userID, results);\n          },\n          (err) => {\n            WebRTCHelpers.traceError(`Get stats error. ${err.name}: ${err.message}`);\n            this.session.onCallStatsReport(this.userID, null, err);\n          }\n        );\n      }, config.videochat.statsReportTimeInterval * 1000);\n    }\n  }\n\n  set sdpRemote(sdp: string) {\n    if (sdp) {\n      this.remoteSDP = sdp;\n    }\n  }\n\n  get sdpRemote(): string | null {\n    return this.remoteSDP;\n  }\n\n  toString(): string {\n    return `sessionID: ${this.session.ID}, userID: ${this.userID}, type: ${this.type}, state: ${this.state}`;\n  }\n\n  private getStatsCustom(\n    lastResults: RTCStatsReport,\n    onSuccess: (\n      stats: { local: Calls.StatsReportObj; remote: Calls.StatsReportObj },\n      lastResults: RTCStatsReport\n    ) => void,\n    onFail: (err: Error) => void\n  ) {\n    const obj: Calls.StatsReportObj = { audio: {}, video: {}, candidate: {} };\n    const statistic: { local: Calls.StatsReportObj; remote: Calls.StatsReportObj } = {\n      local: Object.assign({}, obj),\n      remote: Object.assign({}, obj),\n    };\n\n    if (WebRTCHelpers.getVersionFirefox) {\n      const localStream = this.session.localStream;\n      const localVideoSettings = localStream?.getVideoTracks()[0].getSettings();\n\n      if (localVideoSettings) {\n        statistic.local.video.frameHeight = localVideoSettings.height;\n        statistic.local.video.frameWidth = localVideoSettings.width;\n      }\n    }\n\n    this.getStats().then((results: RTCStatsReport) => {\n      results.forEach((result) => {\n        let item;\n\n        if (result.bytesReceived && result.type === 'inbound-rtp') {\n          item = statistic.remote[result.mediaType as keyof typeof obj];\n          item.bitrate = this.getBitratePerSecond(result, lastResults, false);\n          item.bytesReceived = result.bytesReceived;\n          item.packetsReceived = result.packetsReceived;\n          item.timestamp = result.timestamp;\n          if (result.mediaType === MediaType.VIDEO && result.framerateMean) {\n            item.framesPerSecond = Math.round(result.framerateMean * 10) / 10;\n          }\n        } else if (result.bytesSent && result.type === 'outbound-rtp') {\n          item = statistic.local[result.mediaType as keyof typeof obj];\n          item.bitrate = this.getBitratePerSecond(result, lastResults, true);\n          item.bytesSent = result.bytesSent;\n          item.packetsSent = result.packetsSent;\n          item.timestamp = result.timestamp;\n          if (result.mediaType === MediaType.VIDEO && result.framerateMean) {\n            item.framesPerSecond = Math.round(result.framerateMean * 10) / 10;\n          }\n        } else if (result.type === 'local-candidate') {\n          item = statistic.local.candidate;\n          if (result.candidateType === 'host' && result.mozLocalTransport === 'udp' && result.transport === 'udp') {\n            item.protocol = result.transport;\n            item.ip = result.ipAddress;\n            item.port = result.portNumber;\n          } else if (!WebRTCHelpers.getVersionFirefox) {\n            item.protocol = result.protocol;\n            item.ip = result.ip;\n            item.port = result.port;\n          }\n        } else if (result.type === 'remote-candidate') {\n          item = statistic.remote.candidate;\n          item.protocol = result.protocol || result.transport;\n          item.ip = result.ip || result.ipAddress;\n          item.port = result.port || result.portNumber;\n        } else if (result.type === 'track' && result.kind === MediaType.VIDEO && !WebRTCHelpers.getVersionFirefox) {\n          if (result.remoteSource) {\n            item = statistic.remote.video;\n            item.frameHeight = result.frameHeight;\n            item.frameWidth = result.frameWidth;\n            item.framesPerSecond = this.getFramesPerSecond(result, lastResults, false);\n          } else {\n            item = statistic.local.video;\n            item.frameHeight = result.frameHeight;\n            item.frameWidth = result.frameWidth;\n            item.framesPerSecond = this.getFramesPerSecond(result, lastResults, true);\n          }\n        }\n      });\n      onSuccess(statistic, results);\n    }, onFail);\n  }\n\n  private getBitratePerSecond(result: RTCStats, lastResults: RTCStatsReport, isLocal: boolean): number {\n    const lastResult = lastResults.get(result.id);\n    const seconds = lastResult ? (result.timestamp - lastResult.timestamp) / 1000 : 5;\n    const kilo = 1024;\n    const bit = 8;\n    const r = result as RTCStats & { bytesSent?: number; bytesReceived?: number };\n    const l = lastResult as (RTCStats & { bytesSent?: number; bytesReceived?: number }) | undefined;\n    const bitrate = !lastResult\n      ? 0\n      : isLocal\n        ? (bit * ((r.bytesSent ?? 0) - (l?.bytesSent ?? 0))) / (kilo * seconds)\n        : (bit * ((r.bytesReceived ?? 0) - (l?.bytesReceived ?? 0))) / (kilo * seconds);\n\n    return Math.round(bitrate);\n  }\n\n  private getFramesPerSecond(result: RTCStats, lastResults: RTCStatsReport, isLocal: boolean): number {\n    const lastResult = lastResults && lastResults.get(result.id);\n    const seconds = lastResult ? (result.timestamp - lastResult.timestamp) / 1000 : 5;\n    const r = result as RTCStats & { framesSent?: number; framesReceived?: number };\n    const l = lastResult as (RTCStats & { framesSent?: number; framesReceived?: number }) | undefined;\n    const framesPerSecond = !lastResult\n      ? 0\n      : isLocal\n        ? ((r.framesSent ?? 0) - (l?.framesSent ?? 0)) / seconds\n        : ((r.framesReceived ?? 0) - (l?.framesReceived ?? 0)) / seconds;\n\n    return Math.round(framesPerSecond * 10) / 10;\n  }\n\n  // original RTCPeerConnection methods\n  close(): void {\n    this.original.close?.();\n  }\n  addTrack(track: MediaStreamTrack, stream: MediaStream): RTCRtpSender {\n    return this.original.addTrack?.(track, stream) ?? null;\n  }\n  getSenders(): RTCRtpSender[] {\n    return this.original.getSenders?.() ?? null;\n  }\n  async createOffer(options?: RTCOfferOptions): Promise<RTCSessionDescriptionInit> {\n    return (await this.original.createOffer?.(options)) ?? null;\n  }\n  async createAnswer(options?: RTCOfferOptions): Promise<RTCSessionDescriptionInit> {\n    return (await this.original.createAnswer?.(options)) ?? null;\n  }\n  async getStats(selector?: MediaStreamTrack | null): Promise<RTCStatsReport> {\n    return (await this.original.getStats?.(selector)) ?? null;\n  }\n  async addIceCandidate(candidate?: RTCIceCandidateInit): Promise<void> {\n    await this.original.addIceCandidate?.(candidate);\n  }\n  async setRemoteDescription(description: RTCSessionDescriptionInit): Promise<void> {\n    await this.original.setRemoteDescription?.(description);\n  }\n  async setLocalDescription(description?: RTCSessionDescriptionInit): Promise<void> {\n    await this.original.setLocalDescription?.(description);\n  }\n  get localDescription(): RTCSessionDescription | null {\n    return this.original.localDescription ?? null;\n  }\n  get signalingState(): RTCSignalingState {\n    return this.original.signalingState ?? 'closed';\n  }\n  get iceConnectionState(): RTCIceConnectionState {\n    return this.original.iceConnectionState ?? 'closed';\n  }\n}\n","import type { Calls, Chat } from '../types';\nimport type { ChatRealTimeService } from '../types/chat';\nimport { CallSignalingModuleIdentifier, CallSignalingType } from '../types/constants';\nimport Utils from '../Utils';\n\nexport default class WebRTCSignalingProvider {\n  public chatService: ChatRealTimeService;\n\n  constructor(chatService: ChatRealTimeService) {\n    this.chatService = chatService;\n  }\n\n  public sendCandidate(\n    userID: Chat.UserId,\n    iceCandidates: RTCIceCandidateInit[],\n    ext: Calls.ExtensionParams = {}\n  ): void {\n    const extension = Object.assign({}, ext, { iceCandidates });\n\n    this.sendMessage(userID, extension, CallSignalingType.CANDIDATE);\n  }\n\n  public sendMessage(userID: Chat.UserId, ext: Calls.ExtensionParams, signalingType: CallSignalingType): void {\n    const extension = Object.assign({}, ext);\n    /** basic parameters */\n    extension.moduleIdentifier = CallSignalingModuleIdentifier;\n    extension.signalType = signalingType;\n    /** extension.sessionID */\n    /** extension.callType */\n    extension.platform = Utils.env.isBrowser ? 'web' : Utils.env.isReactNative || Utils.env.isExpo ? 'mobile' : 'node';\n    /** extension.callerID */\n    /** extension.opponentsIDs */\n    /** extension.sdp */\n\n    if (extension.userInfo) {\n      if (!Object.keys(extension.userInfo).length) {\n        delete extension.userInfo;\n      } else if (extension.userInfo.maxBandwidth === 0) {\n        delete extension.userInfo.maxBandwidth;\n      }\n    }\n\n    const systemCallMessage: Chat.SystemMessageParams = {\n      id: Utils.getBsonObjectId(),\n      extension: extension,\n    };\n\n    this.chatService.sendWebRTCSignalingMessage(userID, systemCallMessage);\n  }\n}\n","import type { Calls, Media } from '../types';\nimport {\n  CallSessionConnectionState,\n  CallSessionState,\n  CallSignalingType,\n  CallType,\n  MediaType,\n  PeerConnectionState,\n} from '../types/constants';\nimport { mediaDevices } from '@platform';\nimport config from '../config';\nimport WebRTCPeerConnection from './WebRTCPeerConnection';\nimport WebRTCSignalingProvider from './WebRTCSignalingProvider';\nimport WebRTCHelpers from './WebRTCHelpers';\nimport Utils from '../Utils';\n\nexport default class WebRTCSession {\n  public ID: string | null = null;\n  public state: CallSessionState = CallSessionState.NEW;\n  declare callType: CallType;\n  declare initiatorID: number;\n  declare currentUserID: number;\n  public opponentsIDs: number[] = [];\n  public maxBandwidth: number = 0;\n  public peerConnections: { [userID: number]: WebRTCPeerConnection } = {};\n  public localStream?: MediaStream;\n  public mediaParams: MediaStreamConstraints = {};\n  declare signalingProvider: WebRTCSignalingProvider;\n  public answerTimer: NodeJS.Timeout | number | null = null;\n  public waitingOfferOrAnswerTimer: NodeJS.Timeout | number | null = null;\n  public startCallTime: number = 0;\n  public acceptCallTime: number = 0;\n  declare onUserNotAnswerListener: Calls.OnUserNotAnswerListener;\n  declare onRemoteStreamListener: Calls.OnRemoteStreamListener;\n  declare onSessionCloseListener: Calls.OnSessionCloseListener;\n  declare onCallStatsReportListener: Calls.OnCallStatsReportListener;\n  declare onSessionConnectionStateChangedListener: Calls.OnSessionConnectionStateChangedListener;\n\n  constructor(params: Calls.SessionParams) {\n    Object.assign(this, params, { ID: params.ID ?? generateUUID() });\n  }\n\n  public async getDisplayMedia(params: Media.DisplayParams): Promise<MediaStream> {\n    if (!mediaDevices?.getDisplayMedia) {\n      throw new Error(\"Your environment does not support 'getDisplayMedia' API\");\n    }\n\n    const elementId = params && params.elementId;\n    const options = params && params.options;\n    const mediaParams = { ...params };\n\n    this.mediaParams = mediaParams;\n\n    delete mediaParams.elementId;\n    delete mediaParams.options;\n\n    try {\n      const stream = await mediaDevices!.getDisplayMedia(mediaParams);\n      const localStream = this.upsertStream(stream, elementId, options);\n      return localStream;\n    } catch (error) {\n      throw error;\n    }\n  }\n\n  public async getUserMedia(params: Media.UserParams): Promise<MediaStream> {\n    if (!mediaDevices?.getUserMedia) {\n      throw new Error(\"Your environment does not support 'getUserMedia' API\");\n    }\n\n    const elementId = params && params.elementId;\n    const options = params && params.options;\n    const mediaParams = { ...params };\n\n    this.mediaParams = mediaParams;\n\n    delete mediaParams.elementId;\n    delete mediaParams.options;\n\n    try {\n      const stream = await mediaDevices!.getUserMedia(mediaParams);\n      const localStream = this.upsertStream(stream, elementId, options);\n      return localStream;\n    } catch (error) {\n      throw error;\n    }\n  }\n\n  private upsertStream(stream: MediaStream, elementId?: string, options?: Media.ElementOptions): MediaStream {\n    const shouldUpdateCurrentStream = !!this.localStream;\n\n    if (shouldUpdateCurrentStream) {\n      this.replaceTracks(stream);\n    } else {\n      this.localStream = stream;\n    }\n\n    if (!this.localStream) {\n      throw new Error('Local stream is not defined');\n    }\n\n    if (elementId) {\n      if (shouldUpdateCurrentStream) {\n        this.detachMediaStream(elementId, options);\n      }\n      this.attachMediaStream(elementId, this.localStream, options);\n    }\n\n    this.localStream.getTracks().forEach((track) => {\n      const type = track.kind as 'audio' | 'video';\n      const deviceId = track.getSettings().deviceId;\n\n      if (deviceId) {\n        if (typeof this.mediaParams[type] === 'object') {\n          this.mediaParams[type].deviceId = deviceId;\n        } else {\n          this.mediaParams[type] = { deviceId };\n        }\n      }\n    });\n\n    return this.localStream;\n  }\n\n  private replaceTracks(stream: MediaStream): MediaStream {\n    this.localStream?.getTracks().forEach((localTrack) => {\n      if (localTrack.kind === MediaType.AUDIO && stream.getAudioTracks().length === 0) {\n        return;\n      } else {\n        localTrack.stop();\n        this.localStream?.removeTrack(localTrack);\n      }\n    });\n\n    stream.getTracks().forEach((newTrack) => {\n      if (newTrack.kind === MediaType.AUDIO) {\n        newTrack.enabled = this.localStream?.getAudioTracks().every(({ enabled }) => enabled) ?? true;\n      } else {\n        newTrack.enabled = this.localStream?.getVideoTracks().every(({ enabled }) => enabled) ?? true;\n      }\n\n      if (newTrack) {\n        Object.values(this.peerConnections).forEach((pc) => {\n          pc.getSenders()\n            .find(({ track }) => newTrack.kind === track?.kind)\n            ?.replaceTrack(newTrack);\n        });\n        this.localStream?.addTrack(newTrack);\n      }\n    });\n\n    if (!this.localStream) {\n      throw new Error('Local stream is not defined');\n    }\n\n    return this.localStream;\n  }\n\n  public async setMaxBandwidth(maxBandwidth: number): Promise<void | void[]> {\n    const peers = this.peerConnections;\n    const peersKeys = Object.keys(peers);\n\n    if (peersKeys.length < 1) {\n      WebRTCHelpers.trace(\"No 'RTCPeerConnection' to set 'maxBandwidth'\");\n      return;\n    }\n\n    return Promise.all(peersKeys.map((userID) => peers[Number(userID)].setRTCRtpSenderMaxBandwidth(maxBandwidth)));\n  }\n\n  public connectionStateForUser(userID: number): PeerConnectionState | null {\n    const peerConnection = this.peerConnections[userID];\n    return peerConnection ? peerConnection.state : null;\n  }\n\n  public attachMediaStream(elementId: string, stream: MediaStream, opt?: Media.ElementOptions): void {\n    const mediaElement = document.getElementById(elementId) as HTMLMediaElement;\n\n    if ('srcObject' in mediaElement) {\n      mediaElement.srcObject = stream;\n      mediaElement.style.transform = opt?.mirror ? 'scaleX(-1)' : 'none';\n      if (typeof opt?.muted === 'boolean') {\n        mediaElement.muted = opt?.muted;\n      }\n      mediaElement.onloadedmetadata = async (_event: Event) => {\n        try {\n          await mediaElement.play();\n        } catch (error) {\n          console.error('[VideoChat]:', error);\n        }\n      };\n    } else {\n      throw new Error(`Unable to attach media stream, element #${elementId} is undefined`);\n    }\n  }\n\n  public detachMediaStream(elementId: string, opt?: Media.ElementOptions): void {\n    const mediaElement = document.getElementById(elementId) as HTMLMediaElement;\n\n    if ('srcObject' in mediaElement) {\n      mediaElement.pause();\n      mediaElement.srcObject = null;\n      mediaElement.style.transform = opt?.mirror ? 'scaleX(-1)' : 'none';\n      if (typeof opt?.muted === 'boolean') {\n        mediaElement.muted = opt?.muted;\n      }\n    } else {\n      throw new Error(`Unable to attach media stream, element #${elementId} is undefined`);\n    }\n  }\n\n  public async switchMediaTracks(options: Media.TrackConstraintsOrDeviceIds = {}): Promise<MediaStream> {\n    Utils.DLog('switchMediaTracks:', options);\n\n    [MediaType.AUDIO, MediaType.VIDEO].forEach((type) => {\n      const device = type === MediaType.AUDIO ? options.audio : type === MediaType.VIDEO ? options.video : {};\n      const deviceId = typeof device === 'string' ? device : (device?.deviceId ?? null);\n\n      if (deviceId) {\n        if (typeof this.mediaParams[type as 'audio' | 'video'] !== 'object') {\n          (this.mediaParams[type as 'audio' | 'video'] as MediaTrackConstraints).deviceId = deviceId;\n        } else {\n          this.mediaParams[type as 'audio' | 'video'] = { deviceId };\n        }\n      }\n    });\n\n    try {\n      const constrains = { audio: this.mediaParams.audio || false, video: this.mediaParams.video || false };\n      const stream = await mediaDevices!.getUserMedia(constrains);\n      const localStream = this.replaceTracks(stream);\n      return localStream;\n    } catch (error) {\n      throw error;\n    }\n  }\n\n  public call(extension: Calls.UserInfo = {}): void {\n    const ext = prepareExtension(extension);\n\n    WebRTCHelpers.trace(`Call, extension: ${JSON.stringify(ext)}`);\n\n    this.state = CallSessionState.ACTIVE;\n    this.maxBandwidth = Number(ext.userInfo?.maxBandwidth ?? 0);\n    this.opponentsIDs.forEach((userID) => {\n      this.callInternal(userID, ext, true);\n    });\n  }\n\n  private async callInternal(\n    userID: number,\n    extension: Calls.ExtensionParams,\n    withOnNotAnswerCallback: boolean\n  ): Promise<void> {\n    const pc = new WebRTCPeerConnection(this, userID, 'offer');\n\n    this.localStream?.getTracks().forEach((track) => {\n      pc.addTrack(track, this.localStream as MediaStream);\n    });\n\n    this.peerConnections[userID] = pc;\n\n    try {\n      await pc.getAndSetLocalSessionDescription(this.maxBandwidth);\n      WebRTCHelpers.trace('getAndSetLocalSessionDescription success');\n      pc.startDialingTimer(extension, withOnNotAnswerCallback); // call requests to user\n    } catch (error) {\n      WebRTCHelpers.traceError(`getAndSetLocalSessionDescription error: ${error}`);\n    }\n  }\n\n  public accept(extension: Calls.UserInfo = {}): void {\n    const ext = prepareExtension(extension);\n\n    WebRTCHelpers.trace(`Accept, extension: ${JSON.stringify(ext)}`);\n\n    if (this.state === CallSessionState.ACTIVE) {\n      WebRTCHelpers.traceError(\"Can't accept, the session is already active, return\");\n      return;\n    }\n\n    if (this.state === CallSessionState.CLOSED) {\n      WebRTCHelpers.traceError(\"Can't accept, the session is already closed, return\");\n      this.stop({});\n      return;\n    }\n\n    this.state = CallSessionState.ACTIVE;\n    this.acceptCallTime = Date.now();\n    this.clearAnswerTimer();\n    this.acceptInternal(this.initiatorID, ext);\n\n    // group call\n    const opponentsIDs = this.opponentsIDs.filter((userID) => userID !== this.currentUserID);\n\n    if (opponentsIDs.length > 0) {\n      this.startWaitingOfferOrAnswerTimer();\n      opponentsIDs.forEach((opponentID) => {\n        if (this.currentUserID > opponentID) {\n          this.callInternal(opponentID, ext, true);\n        }\n      });\n    }\n  }\n\n  private async acceptInternal(userID: number, extension: Calls.ExtensionParams): Promise<void> {\n    const pc = this.peerConnections[userID];\n\n    if (!pc || !pc.sdpRemote) {\n      WebRTCHelpers.traceError(\"Can't accept the call, there is no information about peer connection by some reason\");\n      return;\n    }\n\n    this.localStream?.getTracks().forEach((track) => {\n      pc.addTrack(track, this.localStream as MediaStream);\n    });\n\n    try {\n      await pc.setRemoteSessionDescription('offer', pc.sdpRemote);\n      WebRTCHelpers.trace('setRemoteSessionDescription - success');\n      await pc.getAndSetLocalSessionDescription(this.maxBandwidth);\n      WebRTCHelpers.trace('getAndSetLocalSessionDescription - success');\n\n      const ext = Object.assign({}, extension, {\n        sessionID: this.ID,\n        callType: this.callType,\n        callerID: this.initiatorID,\n        opponentsIDs: this.opponentsIDs,\n        sdp: pc.localDescription?.sdp,\n      });\n\n      this.signalingProvider.sendMessage(userID, ext, CallSignalingType.ACCEPT);\n    } catch (error) {\n      WebRTCHelpers.traceError(`[acceptInternal] Error: ${error}`);\n    }\n  }\n\n  public reject(extension: Calls.UserInfo = {}): void {\n    const ext = prepareExtension(extension);\n\n    WebRTCHelpers.trace(`Reject, extension: ${JSON.stringify(ext.userInfo)}`);\n\n    this.state = CallSessionState.REJECTED;\n    this.clearAnswerTimer();\n    Object.assign(ext, {\n      sessionID: this.ID,\n      callType: this.callType,\n      callerID: this.initiatorID,\n      opponentsIDs: this.opponentsIDs,\n    });\n\n    Object.keys(this.peerConnections).forEach((userID) => {\n      this.signalingProvider.sendMessage(Number(userID), ext, CallSignalingType.REJECT);\n    });\n\n    this.close();\n  }\n\n  public stop(extension: Calls.UserInfo = {}): void {\n    const ext = prepareExtension(extension);\n\n    WebRTCHelpers.trace(`Stop, extension: ${JSON.stringify(ext.userInfo)}`);\n\n    this.state = CallSessionState.STOPPED;\n\n    if (this.answerTimer) {\n      this.clearAnswerTimer();\n    }\n\n    Object.assign(ext, {\n      sessionID: this.ID,\n      callType: this.callType,\n      callerID: this.initiatorID,\n      opponentsIDs: this.opponentsIDs,\n    });\n\n    Object.keys(this.peerConnections).forEach((userID) => {\n      this.signalingProvider.sendMessage(Number(userID), ext, CallSignalingType.STOP);\n    });\n\n    this.close();\n  }\n\n  public canInitiateIceRestart(userID: number): boolean {\n    return this.peerConnections[userID]?.type === 'offer';\n  }\n\n  public async iceRestart(userID: number): Promise<void> {\n    const pc = this.peerConnections[userID];\n\n    if (!pc) {\n      WebRTCHelpers.traceError(\"Can't restart ice, there is no information about peer connection by some reason\");\n      return;\n    }\n\n    try {\n      const { sdp } = await pc.getAndSetLocalSessionDescription(this.maxBandwidth, true);\n      const ext = { sessionID: this.ID ?? '', sdp };\n      this.signalingProvider.sendMessage(userID, ext, CallSignalingType.RESTART);\n      WebRTCHelpers.trace('[iceRestart] OK');\n    } catch (error) {\n      WebRTCHelpers.traceError(`[iceRestart] Error: ${error}`);\n    }\n  }\n\n  public processOnCall(callerID: number, extension: Calls.ExtensionParams): void {\n    const opponentsIDs = [this.initiatorID, ...this.opponentsIDs.filter((userID) => userID !== this.currentUserID)];\n\n    opponentsIDs.forEach((opponentID) => {\n      const pc = this.peerConnections[opponentID];\n\n      if (pc) {\n        if (opponentID === callerID) {\n          pc.sdpRemote = extension.sdp ?? '';\n          /** The group call logic starts here */\n          if (callerID !== this.initiatorID && this.state === CallSessionState.ACTIVE) {\n            this.acceptInternal(callerID, extension);\n          }\n        }\n      } else {\n        /** create peer connections for each opponent */\n        const rtcSdpType = opponentID !== callerID && this.currentUserID > opponentID ? 'offer' : 'answer';\n        const pc = new WebRTCPeerConnection(this, opponentID, rtcSdpType);\n\n        this.peerConnections[opponentID] = pc;\n\n        if (opponentID === callerID) {\n          pc.sdpRemote = extension.sdp ?? '';\n          this.startAnswerTimer();\n        }\n      }\n    });\n  }\n\n  public async processOnAccept(userID: number, extension: Calls.ExtensionParams): Promise<void> {\n    const pc = this.peerConnections[userID];\n\n    if (!pc) {\n      WebRTCHelpers.traceWarning(\"Ignore 'OnAccept', there is no information about peer connection by some reason\");\n    }\n\n    try {\n      pc.clearDialingTimer();\n      await pc.setRemoteSessionDescription('answer', extension.sdp ?? '');\n      WebRTCHelpers.trace(\"'setRemoteSessionDescription' success\");\n    } catch (error) {\n      WebRTCHelpers.traceError(`'setRemoteSessionDescription' error: ${error}`);\n    }\n  }\n\n  public processOnReject(userID: number): void {\n    const pc = this.peerConnections[userID];\n\n    this.clearWaitingOfferOrAnswerTimer();\n\n    if (pc) {\n      pc.release();\n    } else {\n      WebRTCHelpers.traceWarning(\"Ignore 'OnReject', there is no information about peer connection by some reason\");\n    }\n\n    this.closeSessionIfAllConnectionsClosed();\n  }\n\n  public processOnStop(userID: number): void {\n    this.clearAnswerTimer();\n\n    /** drop the call if the initiator did it */\n    if (userID === this.initiatorID) {\n      const pcKeys = Object.keys(this.peerConnections);\n      if (pcKeys.length > 0) {\n        pcKeys.forEach((key: string) => {\n          this.peerConnections[Number(key)].release();\n        });\n      } else {\n        WebRTCHelpers.traceWarning(\"Ignore 'OnStop', there is no information about peer connections by some reason\");\n      }\n    } else {\n      const pc = this.peerConnections[userID];\n      if (pc) {\n        pc.release();\n      } else {\n        WebRTCHelpers.traceWarning('Ignore \"OnStop\", there is no information about peer connection by some reason');\n      }\n    }\n\n    this.closeSessionIfAllConnectionsClosed();\n  }\n\n  public async processOnIceCandidates(userID: number, extension: Calls.ExtensionParams): Promise<void> {\n    const pc = this.peerConnections[userID];\n\n    if (!pc) {\n      WebRTCHelpers.traceWarning(\n        'Ignore \"OnIceCandidates\", there is no information about peer connection by some reason'\n      );\n    }\n\n    if (extension.iceCandidates) {\n      await pc.addCandidates(extension.iceCandidates);\n    }\n  }\n\n  public async processOnIceRestart(userID: number, extension: Calls.ExtensionParams): Promise<void> {\n    const pc = this.peerConnections[userID];\n\n    if (!pc) {\n      WebRTCHelpers.traceWarning('Ignore \"OnIceRestart\", there is no information about peer connection by some reason');\n    }\n\n    try {\n      await pc.setRemoteSessionDescription('offer', extension.sdp ?? '');\n      const { sdp } = await pc.getAndSetLocalSessionDescription(this.maxBandwidth);\n      const ext = { sessionID: this.ID ?? '', sdp };\n      this.signalingProvider.sendMessage(userID, ext, CallSignalingType.RESTART_ACCEPT);\n      WebRTCHelpers.trace('[processOnIceRestart] Success');\n    } catch (error) {\n      WebRTCHelpers.traceError(`[processOnIceRestart] Error: ${error}`);\n    }\n  }\n\n  public async processOnIceRestartAccept(userID: number, extension: Calls.ExtensionParams): Promise<void> {\n    const pc = this.peerConnections[userID];\n\n    if (!pc) {\n      WebRTCHelpers.traceWarning(\n        'Ignore \"OnIceRestartAccept\", there is no information about peer connection by some reason'\n      );\n    }\n\n    try {\n      await pc.setRemoteSessionDescription('answer', extension.sdp ?? '');\n      WebRTCHelpers.trace('[processOnIceRestartAccept] Success');\n    } catch (error) {\n      WebRTCHelpers.traceError(`[processOnIceRestartAccept] Error: ${error}`);\n    }\n  }\n\n  public processCall(peerConnection: WebRTCPeerConnection, extension: Calls.ExtensionParams = {}): void {\n    const ext = Object.assign({ userInfo: {} }, extension, {\n      sessionID: this.ID,\n      callType: this.callType,\n      callerID: this.initiatorID,\n      opponentsIDs: this.opponentsIDs,\n      sdp: peerConnection.localDescription?.sdp,\n    });\n\n    this.signalingProvider.sendMessage(peerConnection.userID, ext, CallSignalingType.CALL);\n  }\n\n  public processIceCandidates(userID: number, iceCandidates: RTCIceCandidateInit[]): void {\n    const extension = {\n      sessionID: this.ID ?? '',\n      callType: this.callType,\n      callerID: this.initiatorID,\n      opponentsIDs: this.opponentsIDs,\n    };\n\n    this.signalingProvider.sendCandidate(userID, iceCandidates, extension);\n  }\n\n  public processOnNotAnswer(peerConnection: WebRTCPeerConnection): void {\n    WebRTCHelpers.trace(`Answer timeout callback for session ${this.ID} for user ${peerConnection.userID}`);\n\n    this.clearWaitingOfferOrAnswerTimer();\n    peerConnection.release();\n    Utils.safeCallbackCall(this.onUserNotAnswerListener)(this, peerConnection.userID);\n    this.closeSessionIfAllConnectionsClosed();\n  }\n\n  public onRemoteStream(userID: number, stream: MediaStream): void {\n    Utils.safeCallbackCall(this.onRemoteStreamListener)(this, userID, stream);\n  }\n\n  public onCallStatsReport(userID: number, stats: unknown, error?: Error): void {\n    Utils.safeCallbackCall(this.onCallStatsReportListener)(this, userID, stats, error);\n  }\n\n  public onSessionConnectionStateChanged(userID: number, connectionState: CallSessionConnectionState): void {\n    Utils.safeCallbackCall(this.onSessionConnectionStateChangedListener)(this, userID, connectionState);\n  }\n\n  private close(): void {\n    Object.values(this.peerConnections).forEach((pc) => {\n      try {\n        pc.release();\n      } catch (e) {\n        Utils.DLog(`Peer close error: ${e}`);\n      }\n    });\n\n    this.closeLocalMediaStream();\n    this.state = CallSessionState.CLOSED;\n    Utils.safeCallbackCall(this.onSessionCloseListener)(this);\n  }\n\n  public closeSessionIfAllConnectionsClosed(): void {\n    const isAllClosed = Object.values(this.peerConnections).every((pc) => {\n      try {\n        /*\n         * TODO:\n         * Uses RTCPeerConnection.signalingState instead RTCPeerConnection.iceConnectionState,\n         * because state 'closed' comes after few time from Safari, but signaling state comes instantly\n         */\n        return pc.iceConnectionState === 'closed' || pc.signalingState === 'closed' || pc.released;\n      } catch (err: unknown) {\n        WebRTCHelpers.traceError(String(err));\n        // need to set peerState to 'closed' on error. FF will crashed without this part.\n        return true;\n      }\n    });\n\n    WebRTCHelpers.trace(`All peer connections closed: ${isAllClosed}`);\n\n    if (isAllClosed) {\n      this.closeLocalMediaStream();\n      Utils.safeCallbackCall(this.onSessionCloseListener)(this);\n      this.state = CallSessionState.CLOSED;\n    }\n  }\n\n  private closeLocalMediaStream(): void {\n    if (this.localStream) {\n      this.localStream.getTracks().forEach((track) => track.stop());\n      this.localStream = undefined;\n      this.mediaParams = {};\n    }\n  }\n\n  public mute(type: MediaType): void {\n    this.muteStream(false, type);\n  }\n\n  public unmute(type: MediaType): void {\n    this.muteStream(true, type);\n  }\n\n  private muteStream(enabled: boolean, type: MediaType = MediaType.NONE): void {\n    const tracks =\n      type === MediaType.AUDIO\n        ? this.localStream?.getAudioTracks()\n        : type === MediaType.VIDEO\n          ? this.localStream?.getVideoTracks()\n          : [];\n\n    tracks?.forEach((track) => {\n      track.enabled = enabled;\n    });\n  }\n\n  private clearAnswerTimer(): void {\n    if (this.answerTimer) {\n      WebRTCHelpers.trace('clearAnswerTimer');\n      clearTimeout(this.answerTimer);\n      this.answerTimer = null;\n    }\n  }\n\n  private startAnswerTimer(): void {\n    WebRTCHelpers.trace('startAnswerTimer');\n\n    this.answerTimer = setTimeout(\n      () => {\n        WebRTCHelpers.trace('answerTimeoutCallback');\n        this.close();\n        this.answerTimer = null;\n      },\n      (config.videochat.answerTimeInterval ?? 60) * 1000\n    );\n  }\n\n  private clearWaitingOfferOrAnswerTimer(): void {\n    if (this.waitingOfferOrAnswerTimer) {\n      WebRTCHelpers.trace('clearWaitingOfferOrAnswerTimer');\n      clearTimeout(this.waitingOfferOrAnswerTimer);\n      this.waitingOfferOrAnswerTimer = null;\n    }\n  }\n\n  private startWaitingOfferOrAnswerTimer(): void {\n    const answerTimeInterval = config.videochat.answerTimeInterval ?? 60;\n    const timeWait = (this.acceptCallTime - this.startCallTime) / 1000;\n    const timeDiff = Math.min(timeWait, answerTimeInterval / 2);\n    const timeout = Math.max(answerTimeInterval - timeDiff, 1);\n\n    WebRTCHelpers.trace(`startWaitingOfferOrAnswerTimer, timeout: ${timeout}`);\n\n    this.waitingOfferOrAnswerTimer = setTimeout(() => {\n      WebRTCHelpers.trace('waitingOfferOrAnswerTimeoutCallback');\n\n      Object.values(this.peerConnections).forEach((pc) => {\n        if (pc.state === PeerConnectionState.CONNECTING || pc.state === PeerConnectionState.NEW) {\n          this.processOnNotAnswer(pc);\n        }\n      });\n\n      this.waitingOfferOrAnswerTimer = null;\n    }, timeout * 1000);\n  }\n\n  public toString(): string {\n    return `ID: ${this.ID}, initiatorID: ${this.initiatorID}, opponentsIDs: ${this.opponentsIDs}, state: ${this.state}, callType: ${this.callType}`;\n  }\n}\n\nfunction generateUUID(): string {\n  let d = Date.now();\n  const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n    const r = ((d + Math.random() * 16) % 16) | 0;\n    d = Math.floor(d / 16);\n    return (c == 'x' ? r : (r & 0x3) | 0x8).toString(16);\n  });\n  return uuid;\n}\n\nfunction prepareExtension(extension: Calls.UserInfo = {}): Calls.ExtensionParams {\n  const ext = { userInfo: extension };\n\n  try {\n    if (Utils.isObject(extension)) {\n      ext.userInfo = Utils.cloneObject(extension, true);\n    } else {\n      WebRTCHelpers.traceWarning('Ignore \"prepareExtension\", must be an object');\n    }\n  } catch (err: unknown) {\n    WebRTCHelpers.traceWarning(err instanceof Error ? err.message : String(err));\n  }\n\n  return ext;\n}\n","import { mediaDevices } from '@platform';\nimport config from '../config';\nimport ProxyService from '../Proxy';\nimport Utils from '../Utils';\nimport WebRTCSession from './WebRTCSession';\nimport WebRTCSignalingProcessor from './WebRTCSignalingProcessor';\nimport WebRTCSignalingProvider from './WebRTCSignalingProvider';\nimport WebRTCHelpers from './WebRTCHelpers';\nimport type { Calls, EmptyResponse } from '../types';\nimport type { ChatRealTimeService } from '../types/chat';\nimport {\n  CallEvent,\n  CallSessionConnectionState,\n  CallSessionState,\n  CallType,\n  PeerConnectionState,\n  ProxyMethod,\n} from '../types/constants';\n\nexport default class WebRTCClient {\n  public chatService: ChatRealTimeService;\n  public proxy: ProxyService;\n  public signalingProcessor: WebRTCSignalingProcessor;\n  public signalingProvider: WebRTCSignalingProvider;\n  public SessionConnectionState: typeof CallSessionConnectionState = CallSessionConnectionState;\n  public PeerConnectionState: typeof PeerConnectionState = PeerConnectionState;\n  public CallType: typeof CallType = CallType;\n  public sessions: { [key: string]: WebRTCSession } = {};\n  declare onCallListener: Calls.OnCallListener;\n  declare onAcceptCallListener: Calls.OnAcceptCallListener;\n  declare onRejectCallListener: Calls.OnRejectCallListener;\n  declare onStopCallListener: Calls.OnStopCallListener;\n  declare onInvalidEventsListener: Calls.OnInvalidEventsListener;\n  declare onUserNotAnswerListener: Calls.OnUserNotAnswerListener;\n  declare onRemoteStreamListener: Calls.OnRemoteStreamListener;\n  declare onSessionConnectionStateChangedListener: Calls.OnSessionConnectionStateChangedListener;\n  declare onSessionCloseListener: Calls.OnSessionCloseListener;\n  declare onCallStatsReport: Calls.OnCallStatsReportListener;\n  public onDevicesChangeListener: Calls.OnDevicesChangeListener = () => {};\n\n  constructor(chatService: ChatRealTimeService, proxy: ProxyService) {\n    this.chatService = chatService;\n    this.proxy = proxy;\n\n    this.signalingProcessor = new WebRTCSignalingProcessor(this);\n    this.signalingProvider = new WebRTCSignalingProvider(this.chatService);\n\n    if (mediaDevices) {\n      mediaDevices.ondevicechange = Utils.safeCallbackCall(this.onDevicesChangeListener);\n    }\n  }\n\n  private get currentUserID(): number {\n    return this.chatService.currentUserId;\n  }\n\n  public async getMediaDevices(kind?: MediaDeviceKind): Promise<MediaDeviceInfo[]> {\n    if (mediaDevices?.enumerateDevices) {\n      const devices = await mediaDevices.enumerateDevices();\n      return kind ? devices.filter((device) => device.kind === kind) : devices;\n    } else {\n      throw new Error(\"No 'enumerateDevices' API supported\");\n    }\n  }\n\n  public createNewSession(\n    opponentsIDs: number[],\n    callType: CallType,\n    options?: { maxBandwidth?: number; bandwidth?: number }\n  ): WebRTCSession {\n    const maxBandwidth = (options?.maxBandwidth || options?.bandwidth) ?? 0;\n\n    if (!opponentsIDs) {\n      throw new Error(\"Can't create a session without opponentsIDs\");\n    }\n\n    return this.createAndStoreSession(null, this.currentUserID, opponentsIDs, callType, maxBandwidth);\n  }\n\n  private createAndStoreSession(\n    sessionID: string | null,\n    initiatorID: number,\n    opponentsIDs: number[],\n    callType: CallType,\n    maxBandwidth: number = 0\n  ): WebRTCSession {\n    const webRTCSession = new WebRTCSession({\n      ID: sessionID,\n      initiatorID,\n      opponentsIDs,\n      callType,\n      signalingProvider: this.signalingProvider,\n      currentUserID: this.currentUserID,\n      maxBandwidth,\n    });\n\n    webRTCSession.onUserNotAnswerListener = this.onUserNotAnswerListener;\n    webRTCSession.onRemoteStreamListener = this.onRemoteStreamListener;\n    webRTCSession.onSessionConnectionStateChangedListener = this.onSessionConnectionStateChangedListener;\n    webRTCSession.onSessionCloseListener = this.onSessionCloseListener;\n    webRTCSession.onCallStatsReportListener = this.onCallStatsReport;\n\n    if (webRTCSession?.ID) {\n      this.sessions[webRTCSession.ID] = webRTCSession;\n    }\n\n    return webRTCSession;\n  }\n\n  public clearSession(sessionId: string): void {\n    delete this.sessions[sessionId];\n  }\n\n  /// Reject call by http request\n  public callRejectRequest(params: {\n    sessionID: string;\n    recipientId: number;\n    platform: string;\n    userInfo?: Calls.UserInfo;\n  }): Promise<EmptyResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.POST,\n      url: Utils.getUrl(config.urls.calls, 'reject'),\n      data: params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  /// DELEGATE (signaling)\n\n  public onCallHandler(userID: number, sessionID: string, extension: Calls.ExtensionParams): void {\n    const userInfo = extension.userInfo || {};\n    const maxBandwidth = Number(userInfo.maxBandwidth ?? 0);\n\n    let session = this.sessions[sessionID];\n\n    WebRTCHelpers.trace(`onCall. userID: ${userID}, sessionID: ${sessionID}, extension: ${JSON.stringify(extension)}`);\n\n    if (!session) {\n      session = this.createAndStoreSession(\n        sessionID,\n        extension.callerID || 0,\n        extension.opponentsIDs || [],\n        (extension.callType as CallType) || CallType.VIDEO,\n        maxBandwidth\n      );\n\n      Utils.safeCallbackCall(this.onCallListener)(session, userInfo);\n    }\n\n    session.processOnCall(userID, extension);\n  }\n\n  public onAcceptHandler(userID: number, sessionID: string, extension: Calls.ExtensionParams): void {\n    const session = this.sessions[sessionID];\n    const userInfo = extension.userInfo || {};\n\n    WebRTCHelpers.trace(\n      `onAccept. UserID: ${userID}, sessionID: ${sessionID}, extension: ${JSON.stringify(extension)}`\n    );\n\n    if (session && (session.state === CallSessionState.ACTIVE || session.state === CallSessionState.NEW)) {\n      Utils.safeCallbackCall(this.onAcceptCallListener)(session, userID, userInfo);\n      session.processOnAccept(userID, extension);\n    } else {\n      WebRTCHelpers.traceWarning(`Ignore 'onAccept', there is no information about session ${sessionID}`);\n    }\n  }\n\n  public onRejectHandler(userID: number, sessionID: string, extension: Calls.ExtensionParams): void {\n    const session = this.sessions[sessionID];\n\n    WebRTCHelpers.trace(\n      `onReject. UserID: ${userID}, sessionID: ${sessionID}, extension: ${JSON.stringify(extension)}`\n    );\n\n    if (session) {\n      const userInfo = extension.userInfo || {};\n\n      Utils.safeCallbackCall(this.onRejectCallListener)(session, userID, userInfo);\n      session.processOnReject(userID);\n    } else {\n      WebRTCHelpers.traceWarning(`Ignore 'onReject', there is no information about session ${sessionID}`);\n    }\n  }\n\n  public onStopHandler(userID: number, sessionID: string, extension: Calls.ExtensionParams) {\n    WebRTCHelpers.trace(`onStop. UserID: ${userID}, sessionID: ${sessionID}, extension: ${JSON.stringify(extension)}`);\n\n    const session = this.sessions[sessionID];\n    const userInfo = extension.userInfo || {};\n\n    if (session && (session.state === CallSessionState.ACTIVE || session.state === CallSessionState.NEW)) {\n      session.processOnStop(userID);\n      Utils.safeCallbackCall(this.onStopCallListener)(session, userID, userInfo);\n    } else {\n      Utils.safeCallbackCall(this.onInvalidEventsListener)(session, userID, userInfo);\n      WebRTCHelpers.traceWarning(`Ignore 'onStop', there is no information about session ${sessionID} by some reason`);\n    }\n  }\n\n  public onIceCandidatesHandler(userID: number, sessionID: string, extension: Calls.ExtensionParams) {\n    const session = this.sessions[sessionID];\n\n    WebRTCHelpers.trace(\n      `onIceCandidates. UserID: ${userID}. SessionID: ${sessionID}. ICE candidates count: ${\n        extension.iceCandidates?.length ?? 0\n      }`\n    );\n\n    if (session) {\n      if (session.state === CallSessionState.ACTIVE) {\n        session.processOnIceCandidates(userID, extension);\n      } else {\n        WebRTCHelpers.traceWarning(`Ignore 'OnIceCandidates', the session ( ${sessionID} ) has invalid state`);\n      }\n    } else {\n      WebRTCHelpers.traceWarning(`Ignore 'OnIceCandidates', there is no information about session ${sessionID}`);\n    }\n  }\n\n  public onIceRestartHandler(userID: number, sessionID: string, extension: Calls.ExtensionParams) {\n    const session = this.sessions[sessionID];\n\n    WebRTCHelpers.trace(\n      `onIceRestart. UserID: ${userID}. SessionID: ${sessionID}. Extension: ${JSON.stringify(extension)}`\n    );\n\n    if (session) {\n      if (session.state === CallSessionState.ACTIVE) {\n        session.processOnIceRestart(userID, extension);\n      } else {\n        WebRTCHelpers.traceWarning(`Ignore 'OnIceRestart', the session (${sessionID}) has invalid state`);\n      }\n    } else {\n      WebRTCHelpers.traceWarning(`Ignore 'OnIceRestart', there is no information about session ${sessionID}`);\n    }\n  }\n\n  public onIceRestartAcceptHandler(userID: number, sessionID: string, extension: Calls.ExtensionParams) {\n    const session = this.sessions[sessionID];\n\n    WebRTCHelpers.trace(\n      `onIceRestartAccept. UserID: ${userID}. SessionID: ${sessionID}. Extension: ${JSON.stringify(extension)}`\n    );\n\n    if (session) {\n      if (session.state === CallSessionState.ACTIVE) {\n        session.processOnIceRestartAccept(userID, extension);\n      } else {\n        WebRTCHelpers.traceWarning(`Ignore 'onIceRestartAccept', the session (${sessionID}) has invalid state`);\n      }\n    } else {\n      WebRTCHelpers.traceWarning(`Ignore 'onIceRestartAccept', there is no information about session ${sessionID}`);\n    }\n  }\n\n  private getListenerByName(name: CallEvent): Calls.ListenerName | null {\n    switch (name) {\n      case CallEvent.CALL:\n        return 'onCallListener';\n      case CallEvent.ACCEPT:\n        return 'onAcceptCallListener';\n      case CallEvent.REJECT:\n        return 'onRejectCallListener';\n      case CallEvent.STOP:\n        return 'onStopCallListener';\n      case CallEvent.INVALID:\n        return 'onInvalidEventsListener';\n      case CallEvent.NOT_ANSWER:\n        return 'onUserNotAnswerListener';\n      case CallEvent.REMOTE_STREAM:\n        return 'onRemoteStreamListener';\n      case CallEvent.CONNECTION_STATE:\n        return 'onSessionConnectionStateChangedListener';\n      case CallEvent.CLOSE:\n        return 'onSessionCloseListener';\n      case CallEvent.STATS_REPORT:\n        return 'onCallStatsReport';\n      case CallEvent.DEVICES:\n        return 'onDevicesChangeListener';\n      default:\n        return null;\n    }\n  }\n\n  public addListener(name: CallEvent, listener: Calls.Listeners): () => void {\n    const listenerName = this.getListenerByName(name);\n    if (listenerName) {\n      (this[listenerName] as Calls.Listeners) = listener;\n    }\n    return this.removeListener.bind(this, name);\n  }\n\n  public removeListener(name: CallEvent): void {\n    const listenerName = this.getListenerByName(name);\n    if (listenerName) {\n      (this[listenerName] as Calls.Listeners | undefined) = name === CallEvent.DEVICES ? () => {} : undefined;\n    }\n  }\n\n  public removeAllListeners(): void {\n    Object.keys(this).forEach((key) => {\n      if (key.startsWith('on') && key.endsWith('Listener') && typeof this[key as Calls.ListenerName] === 'function') {\n        (this[key as Calls.ListenerName] as Calls.Listeners | undefined) =\n          key === 'onDevicesChangeListener' ? () => {} : undefined;\n      }\n    });\n  }\n}\n","import type { EmptyResponse, Whiteboard } from './types';\nimport { ProxyMethod, ProxyType } from './types/constants';\nimport ProxyService from './Proxy';\nimport config from './config';\nimport Utils from './Utils';\n\nexport default class WhiteboardService {\n  public proxy: ProxyService;\n  readonly route = config.urls.whiteboards;\n  readonly server = config.whiteboard.server;\n\n  constructor(proxy: ProxyService) {\n    this.proxy = proxy;\n  }\n\n  public getURL({ id, title, username }: Whiteboard.GetUrlParams): string {\n    return `${this.server}?whiteboardid=${id}&username=${username}&title=${title}`;\n  }\n\n  public async get(paramsOrId: Whiteboard.GetParams): Promise<Whiteboard.Item[]> {\n    const ajaxParams = {\n      type: ProxyMethod.GET,\n      url: Utils.getUrl(this.route),\n      data: typeof paramsOrId === 'string' ? { chat_dialog_id: paramsOrId } : paramsOrId,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async create(params: Whiteboard.CreateParams): Promise<Whiteboard.Item> {\n    const ajaxParams = {\n      type: ProxyMethod.POST,\n      url: Utils.getUrl(this.route),\n      data: params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async update(id: string, params: Whiteboard.UpdateParams): Promise<Whiteboard.Item> {\n    const ajaxParams = {\n      type: ProxyMethod.PUT,\n      url: Utils.getUrl(this.route, id),\n      data: params,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n\n  public async delete(id: string): Promise<EmptyResponse> {\n    const ajaxParams = {\n      type: ProxyMethod.DELETE,\n      url: Utils.getUrl(this.route, id),\n      dataType: ProxyType.TEXT,\n    };\n\n    return this.proxy.ajax(ajaxParams);\n  }\n}\n","import type { LinkPreview, LinkPreviewCache } from './types';\nimport { ProxyMethod } from './types/constants';\nimport ProxyService from './Proxy';\nimport config from './config';\n\nexport default class LinkPreviewService {\n  public proxy: ProxyService;\n  public cache: LinkPreviewCache = new Map<string, LinkPreview>();\n\n  readonly route = config.urls.unfurl;\n  readonly server = config.linkpreview.server;\n\n  constructor(proxy: ProxyService) {\n    this.proxy = proxy;\n  }\n\n  public async get(url: string): Promise<LinkPreview> {\n    if (!this.cache.has(url)) {\n      let linkPreview: LinkPreview = { url, title: '', description: '', images: [] }\n      \n      try {\n        const ajaxParams = {\n          type: ProxyMethod.POST,\n          url: `${this.server}/${this.route}`,\n          data: { url },\n        };\n\n        linkPreview = (await this.proxy.ajax(ajaxParams)) as LinkPreview;\n      } catch (error) {\n        linkPreview.title = this.getHostFromUrl(url);\n      }\n\n      this.cache.set(url, linkPreview);\n    }\n\n    return this.cache.get(url) as LinkPreview;\n  }\n\n  private getHostFromUrl(url: string): string {\n    if (typeof URL === 'function') {\n      return new URL(url).hostname;\n    }\n\n    const match = url.match(/^(?:https?:\\/\\/)?([^\\/]+)/);\n    return match ? match[1] : url;\n  }\n}\n","import type { Config } from './types';\nimport { ChatAPIs } from './types/constants';\nimport { isWebRTCAvailable, sdkVersion, isBrowser, isNodeJS, isReactNative } from '@platform';\nimport config from './config';\nimport AddressBookService from './AddressBook';\nimport AuthService from './Auth';\nimport XMPPChatService from './messaging/xmpp';\nimport SAMAChatService from './messaging/sama';\nimport ConferenceClient from './videocalling_conference/ConferenceClient';\nimport DataService from './Data';\nimport MeetingsService from './Meetings';\nimport ProxyService from './Proxy';\nimport PushNotificationsService from './PushNotifications';\nimport StorageService from './Storage';\nimport UsersService from './Users';\nimport Utils from './Utils';\nimport WebRTCClient from './videocalling/WebRTCClient';\nimport WhiteboardService from './Whiteboard';\nimport LinkPreviewService from './LinkPreview';\n\nexport default class ConnectyCube<ChatService extends SAMAChatService | XMPPChatService = XMPPChatService> {\n  declare ConnectyCube: typeof ConnectyCube;\n\n  readonly version: string = sdkVersion;\n  readonly platform: string = isBrowser ? 'browser' : isNodeJS ? 'node' : isReactNative ? 'react-native' : 'unknown';\n  readonly isWebRTCAvailable: boolean = isWebRTCAvailable;\n\n  declare utils: Utils;\n  declare service: ProxyService;\n  declare auth: AuthService;\n  declare users: UsersService;\n  declare storage: StorageService;\n  declare pushnotifications: PushNotificationsService;\n  declare data: DataService;\n  declare addressbook: AddressBookService;\n  declare chat: ChatService;\n  declare meeting: MeetingsService;\n  declare whiteboard: WhiteboardService;\n  declare linkpreview: LinkPreviewService;\n  declare videochat: WebRTCClient;\n  declare videochatconference: ConferenceClient;\n  declare setSession: AuthService['setSession'];\n  declare getSession: AuthService['getSession'];\n  declare createSession: AuthService['createSession'];\n  declare destroySession: AuthService['destroySession'];\n  /**\n   * @deprecated ConnectyCube.login(user) is deprecated. Use `ConnectyCube.createSession(user)` or `ConnectyCube.auth.login(user)` instead.\n   */\n  declare login: AuthService['login'];\n  /**\n   * @deprecated ConnectyCube.logout() is deprecated. Use `ConnectyCube.destroySession()` or `ConnectyCube.auth.logout()` instead.\n   */\n  declare logout: AuthService['logout'];\n\n  public init(credentials: Config.Credentials, configMap: Config.Options = {}): void {\n    if (configMap && typeof configMap === 'object') {\n      config.set(configMap);\n    }\n\n    this.utils = Utils;\n    this.service = new ProxyService();\n    this.auth = new AuthService(this.service);\n    this.users = new UsersService(this.service);\n    this.storage = new StorageService(this.service);\n    this.pushnotifications = new PushNotificationsService(this.service);\n    this.data = new DataService(this.service);\n    this.addressbook = new AddressBookService(this.service);\n    this.chat = (\n      config.chat.apiImp === ChatAPIs.SAMA ? new SAMAChatService(this.service) : new XMPPChatService(this.service)\n    ) as ChatService;\n    this.meeting = new MeetingsService(this.service);\n    this.whiteboard = new WhiteboardService(this.service);\n    this.linkpreview = new LinkPreviewService(this.service);\n\n    if (isWebRTCAvailable) {\n      this.videochat = new WebRTCClient(this.chat, this.service);\n      this.chat.webrtcSignalingProcessor = this.videochat.signalingProcessor;\n      this.videochatconference = new ConferenceClient(this.service);\n    }\n\n    if (credentials.token) {\n      config.creds.appId = credentials.appId;\n      this.service.setSession({ token: credentials.token });\n    } else {\n      config.creds.appId = credentials.appId;\n      config.creds.authKey = credentials.authKey;\n    }\n\n    this.setSession = this.auth.setSession;\n    this.getSession = this.auth.getSession;\n    this.createSession = this.auth.createSession;\n    this.destroySession = this.auth.destroySession;\n    this.login = this.auth.login;\n    this.logout = this.auth.logout;\n  }\n}\n\nexport { type XMPPChatService as XMPPChat, type SAMAChatService as SAMAChat };\n","import ConnectyCube from './ConnectyCube';\nimport type { SAMAChat, XMPPChat } from './ConnectyCube';\n\nconst connectycube: ConnectyCube = new ConnectyCube();\n\nconnectycube.ConnectyCube = ConnectyCube;\n\nexport default connectycube;\nexport { ConnectyCube };\nexport * from './types/constants';\nexport type * from './types';\nexport type { XMPPChat, SAMAChat };\n","import type { DeleteIdsResponse, PaginationParams, PlainObject, SearchCondition, Timestamps } from './common';\n\nexport const DataPermission = {\n  CREATE: 'create',\n  READ: 'read',\n  UPDATE: 'update',\n  DELETE: 'delete',\n} as const;\nexport type DataPermission = (typeof DataPermission)[keyof typeof DataPermission];\n\nexport const DataPermissionAccess = {\n  OPEN: 'open',\n  OWNER: 'owner',\n  NOT_ALLOWED: 'not_allowed',\n  OPEN_FOR_GROUPS: 'open_for_groups',\n  OPEN_FOR_USERS_IDS: 'open_for_users_ids',\n} as const;\nexport type DataPermissionAccess = (typeof DataPermissionAccess)[keyof typeof DataPermissionAccess];\n\nexport namespace ConnectyCubeData {\n  export type PermissionOptions = {\n    access: DataPermissionAccess | string;\n    user_ids?: string[];\n    user_groups?: string[];\n  };\n  export type Permissions = Record<DataPermission | string, PermissionOptions>;\n  export type CreateRecord = PlainObject & {\n    permissions?: Permissions;\n  };\n  export type DataRecord = Timestamps & PlainObject & {\n    _id: string;\n    _parent_id: string | null;\n    user_id: number;\n    permissions: Permissions;\n  };\n  // Request parameters type\n  export type CreateParams = CreateRecord | CreateRecord[];\n  export type ListFilter = Omit<PaginationParams, 'offset'> & {\n    count?: number;\n    output?: { include?: string[]; exclude?: string[] };\n    near?: string;\n    [field: string]: SearchCondition<unknown> | undefined;\n  };\n  export type ListParams = string | string[] | ListFilter | undefined;\n  export type ReadParams = { permissions: 1 };\n  export type UpdateOptions = PlainObject & {\n    id?: string | number;\n    _id?: string | number;\n    inc?: Record<string, number>;\n    pull?: PlainObject;\n    pull_with_filter?: Record<string, PlainObject>;\n    pull_all?: Record<string, unknown[]>;\n    pop?: Record<string, 1 | -1>;\n    push?: Record<string, unknown[]>;\n    add_to_set?: Record<string, unknown[]>;\n    update_by_index?: Record<string, PlainObject<number>>;\n    search_criteria?: SearchCondition<unknown>;\n  };\n  // Response data types\n  export type ListResponse = { class_name: string; items: DataRecord[] };\n  export type ReadPermissionsResponse = { record_id: string; permissions: Permissions };\n  export type UpdateResponse = ListResponse & {\n    skip?: number;\n    limit?: number;\n    total_found?: number;\n    not_found?: { ids: string[] };\n  };\n  export type DeleteResponse = DeleteIdsResponse | { total_deleted: number };\n}\n","import type { DateOrTimestamp } from './common';\n\nexport const NotificationChannel = {\n  APNS: 'apns',\n  VOIP: 'apns_voip',\n  GCM: 'gcm',\n  WEB: 'web',\n} as const;\nexport type NotificationChannel = (typeof NotificationChannel)[keyof typeof NotificationChannel];\n\nexport const DevicePlatform = {\n  IOS: 'ios',\n  ANDROID: 'android',\n  WEB: 'web',\n} as const;\nexport type DevicePlatform = (typeof DevicePlatform)[keyof typeof DevicePlatform];\n\nexport const PushEnvironment = {\n  DEV: 'development',\n  PROD: 'production',\n} as const;\nexport type PushEnvironment = (typeof PushEnvironment)[keyof typeof PushEnvironment];\n\nexport namespace ConnectyCubePushNotifications {\n  export type Subscription = {\n    subscription: {\n      id: number | string;\n      notification_channel: {\n        name: NotificationChannel | string;\n      };\n      device: {\n        udid: string;\n        platform: {\n          name: DevicePlatform | string;\n        };\n      };\n    };\n  };\n  export type Event = {\n    event: {\n      id: number;\n      event_type: string | null;\n      message: string | null;\n      date: DateOrTimestamp;\n      period: DateOrTimestamp;\n      name: string | null;\n      occured_count?: number;\n      created_at?: DateOrTimestamp;\n      updated_at?: DateOrTimestamp;\n      end_date?: DateOrTimestamp;\n      active?: boolean | null;\n      application_id: number | null;\n      user_id: number | null;\n      kind: string | null;\n      environment: PushEnvironment | null;\n      tag_query?: string;\n      notification_channel?: {\n        name?: NotificationChannel | null;\n      };\n    };\n  };\n  export type PushTokenBaseParams = {\n    environment: PushEnvironment | string;\n  };\n  export type PushTokenMobileParams = PushTokenBaseParams & {\n    client_identification_sequence: string;\n    bundle_identifier?: string;\n  };\n  export type PushTokenWebParams = PushTokenBaseParams & {\n    web_endpoint: string;\n    web_auth: string;\n    web_p256dh: string;\n  };\n  // Request parameters type\n  export type SubscriptionsCreateParams = {\n    notification_channels: NotificationChannel | string;\n    push_token: PushTokenMobileParams | PushTokenWebParams;\n    device: {\n      platform: DevicePlatform | string;\n      udid: string;\n    };\n  };\n  export type EventsCreateParams = {\n    notification_type: 'push' | string;\n    push_type: NotificationChannel | string;\n    environment: PushEnvironment | string;\n    event_type?: 'one_shot' | string;\n    message?: string | null;\n    user?: {\n      ids: string | number[];\n      tags?: {\n        any?: string;\n        all?: string;\n        exclude?: string;\n      };\n    };\n    external_user?: { ids: string | number[] };\n  };\n}\n","import type {\n  DeleteIdsResponse,\n  PagedResponse,\n  PaginationParams,\n  PlainObject,\n  SearchableProps,\n  Timestamp,\n  Timestamps,\n} from './common';\nimport type { ConnectyCubeUsers } from './users';\n\nexport const DialogType = {\n  PUBLIC: 1,\n  GROUP: 2,\n  PRIVATE: 3,\n  BROADCAST: 4,\n  MEETING: 5,\n} as const;\nexport type DialogType = (typeof DialogType)[keyof typeof DialogType];\n\nexport const LastMessageMessageStatus = {\n  SENT: 'sent',\n  DELIVERED: 'delivered',\n  READ: 'read',\n} as const;\nexport type LastMessageMessageStatus = (typeof LastMessageMessageStatus)[keyof typeof LastMessageMessageStatus];\n\nexport const DialogDateProp = {\n  CREATED: 'created_at',\n  UPDATED: 'updated_at',\n  LAST_MESSAGE: 'last_message_date_sent',\n} as const;\nexport type DialogDateProp = (typeof DialogDateProp)[keyof typeof DialogDateProp];\n\nexport namespace ConnectyCubeDialogs {\n  export type Dialog<ExtensionExtra = PlainObject> = Timestamps & {\n    _id: string;\n    name: string;\n    description: string | null;\n    photo: string | null;\n    type: DialogType;\n    user_id: number;\n    xmpp_room_jid?: string | null;\n    last_message: string | null;\n    last_message_date_sent?: Timestamp;\n    last_message_id: string | null;\n    last_message_user_id: number | null;\n    last_message_status: LastMessageMessageStatus | string | null;\n    occupants_ids: number[];\n    admins_ids: number[];\n    occupants_count?: number;\n    pinned_messages_ids?: string[];\n    unread_messages_count: number;\n    extensions?: ExtensionExtra;\n    permissions?: { allow_preview: boolean | string | number } | null;\n  };\n  // Request parameters type\n  export type ListParams = SearchableProps<Dialog> & Omit<PaginationParams<Dialog>, 'offset'> & { count?: number };\n  export type CreateParams<ExtensionExtra = PlainObject> = Pick<\n    Dialog<ExtensionExtra>,\n    'type' | 'extensions' | 'permissions' | 'pinned_messages_ids'\n  > & {\n    name?: string;\n    photo?: string | null;\n    description?: string | null;\n    occupants_ids?: (string | number)[] | string;\n    admins_ids?: (string | number)[] | string;\n  };\n  export type UpdateParams<ExtensionExtra = PlainObject> = Omit<\n    CreateParams<ExtensionExtra>,\n    'type' | 'occupants_ids' | 'admins_ids'\n  > & {\n    push_all?: Pick<CreateParams<ExtensionExtra>, 'occupants_ids' | 'admins_ids' | 'pinned_messages_ids'>;\n    pull_all?: Pick<CreateParams<ExtensionExtra>, 'occupants_ids' | 'admins_ids' | 'pinned_messages_ids'>;\n  };\n  export type GetPublicOccupantsParams = Pick<PaginationParams, 'skip' | 'limit'>;\n  // Response data types\n  export type ListResponse = PagedResponse<Dialog>;\n  export type DeleteResponse = DeleteIdsResponse;\n  export type NotificationsSettingsResponse = { notifications: { enabled: number | string } };\n  export type GetNotificationsSettingsResponse = NotificationsSettingsResponse;\n  export type UpdateNotificationsSettingsResponse = NotificationsSettingsResponse;\n  export type GetPublicOccupantsResponse = { items: ConnectyCubeUsers.User[] };\n}\n","import type { DateOrTimestamp, PlainObject } from './common';\nimport type { ConnectyCubeUsers } from './users';\n\nexport const LoginProviderNames = {\n  FACEBOOK: 'facebook',\n  TWITTER: 'twitter',\n  FIREBASE_PHONE: 'firebase_phone',\n  FIREBASE_EMAIL: 'firebase_email',\n} as const;\nexport type LoginProviderNames = (typeof LoginProviderNames)[keyof typeof LoginProviderNames];\n\nexport namespace ConnectyCubeAuth {\n  export type Session = {\n    id: number;\n    user_id: number;\n    application_id: string | number;\n    token: string;\n    ts: DateOrTimestamp;\n    created_at: DateOrTimestamp;\n    updated_at: DateOrTimestamp;\n    user?: ConnectyCubeUsers.User | null;\n  };\n  export type LoginProviderKeys = { token: string; secret?: string };\n  export type LoginFirebaseKeys = { project_id: string | number; access_token: string };\n  export type LoginByLogin = { login: string; password: string };\n  export type LoginByEmail = { email: string; password: string };\n  export type LoginByGuest = { guest: '1'; full_name: string };\n  // Login by social providers\n  export type LoginByFacebook = {\n    provider: typeof LoginProviderNames.FACEBOOK;\n    keys: LoginProviderKeys;\n  };\n  export type LoginByTwitter = {\n    provider: typeof LoginProviderNames.TWITTER;\n    keys: LoginProviderKeys;\n  };\n  export type LoginByFirebasePhone = {\n    provider: typeof LoginProviderNames.FIREBASE_PHONE;\n    firebase_phone: LoginFirebaseKeys;\n  };\n  export type LoginByFirebaseEmail = {\n    provider: typeof LoginProviderNames.FIREBASE_EMAIL;\n    firebase_email: LoginFirebaseKeys;\n  };\n  // Request parameters type\n  export type LoginParams =\n    | LoginByLogin\n    | LoginByEmail\n    | LoginByGuest\n    | LoginByFacebook\n    | LoginByTwitter\n    | LoginByFirebasePhone\n    | LoginByFirebaseEmail;\n  export type GeneratedSessionParams = {\n    application_id: string | number;\n    auth_key: string;\n    user?: LoginByLogin | LoginByEmail | LoginByGuest;\n    provider?: LoginProviderNames;\n    keys?: LoginProviderKeys;\n    firebase_phone?: LoginFirebaseKeys;\n    firebase_email?: LoginFirebaseKeys;\n  };\n  // Response data type\n  export type LoginRawResponse = { user: ConnectyCubeUsers.User } & PlainObject;\n  export type GetSessionRawResponse = { session: Session } & PlainObject;\n}\n","import type { DateOrTimestamp, PaginationParams, SearchCondition, SearchableProps, Timestamps } from './common';\n\nexport const MeetingDateMetric = {\n  MINUTES: 'minutes',\n  HOURS: 'hours',\n  DAYS: 'days',\n  WEEK: 'weeks',\n} as const;\nexport type MeetingDateMetric = (typeof MeetingDateMetric)[keyof typeof MeetingDateMetric];\n\nexport namespace ConnectyCubeMeetings {\n  export type Attendee = { id?: number; email?: string };\n  export type MeetingParams = {\n    name?: string;\n    start_date?: DateOrTimestamp;\n    end_date?: DateOrTimestamp;\n    attendees?: Attendee[];\n    record?: boolean | null;\n    public?: boolean;\n    scheduled?: boolean;\n    notify?: boolean;\n    notify_before?: {\n      metric: MeetingDateMetric | string;\n      value: number; // 'minutes' range [0 - 55], 'hours' range [1 - 24], 'days' range [1 - 30], 'weeks' range [1 - 4]\n    };\n    timezone?: {\n      offset: number; // Minutes UTC offset\n      name: string; // Timezone Name\n    };\n  };\n  export type Meeting = Timestamps & {\n    _id: string;\n    chat_dialog_id?: string | null;\n    host_id: number;\n  } & MeetingParams;\n  export type Recording = {\n    _id: string;\n    room_id: string;\n    participants_ids: number[];\n    updated_at: string;\n    created_at: string;\n    download_url: string;\n    participants_count: number;\n    duration: number;\n    size: number;\n  };\n  // Request parameters type\n  export type GetParams = SearchableProps<Pick<Meeting, '_id' | 'updated_at' | 'created_at' | 'scheduled'>>\n    & Pick<PaginationParams, 'offset' | 'limit'>\n    & { start_at?: SearchCondition<DateOrTimestamp>; end_at?: SearchCondition<DateOrTimestamp> };\n  export type CreateParams = { chat?: boolean } & MeetingParams;\n}\n"],"names":["CallSignalingModuleIdentifier","CallSignalingType","CALL","ACCEPT","REJECT","STOP","RESTART","RESTART_ACCEPT","CANDIDATE","CallSessionConnectionState","UNDEFINED","CONNECTING","CONNECTED","FAILED","DISCONNECTED","CLOSED","COMPLETED","CallSessionState","NEW","ACTIVE","STOPPED","REJECTED","CallType","VIDEO","AUDIO","CallEvent","INVALID","NOT_ANSWER","REMOTE_STREAM","CONNECTION_STATE","CLOSE","STATS_REPORT","DEVICES","PeerConnectionState","CHECKING","ChatType","CHAT","GROUPCHAT","ChatEvent","STATUS","ERROR","RECONNECTED","MESSAGE","SYSTEM_MESSAGE","ERROR_MESSAGE","TYPING_MESSAGE","UPDATE_MESSAGE","DELETE_MESSAGE","REACTIONS_MESSAGE","DELIVERED_MESSAGE","READ_MESSAGE","SENT_MESSAGE","USER_LAST_ACTIVITY","JOIN","LEAVE","KICK","PrivacyListAction","ALLOW","DENY","ChatProtocol","BOSH","WS","JanusDebugMode","ALL","TRACE","DEBUG","VDEBUG","LOG","WARN","ChatAPIs","SAMA","XMPP","DeviceInputType","JanusEvent","PARTICIPANT_JOINED","PARTICIPANT_LEFT","LOCAL_STREAM","REMOTE_TRACKS_UPDATED","DATA_CHANNEL_OPEN","DATA_CHANNEL_MESSAGE","JanusCallType","JanusMediaTrackReason","CREATED","ENDED","MUTE","UNMUTE","ConferenceEvent","LEFT","SLOW_LINK","REMOTE_CONNECTION_STATE","DATA_CHANNEL_OPENED","SESSION_CONNECTION_STATE","MediaType","NONE","ProxyMethod","GET","POST","PUT","PATCH","DELETE","HEAD","ProxyType","JSON","TEXT","sdkVersion","isBrowser","window","document","isNodeJS","isReactNative","isExpo","adapter","undefined","navigator","mediaDevices","MediaStream","MediaStreamTrack","RTCIceCandidate","RTCPeerConnection","RTCRtpReceiver","RTCRtpSender","RTCSessionDescription","isWebRTCAvailable","Boolean","Config","static","version","creds","appId","authKey","endpoints","api","chat","muc","chatProtocol","bosh","websocket","active","streamManagement","enable","reconnect","timeInterval","apiImp","videochat","alwaysRelayCalls","answerTimeInterval","dialingTimeInterval","disconnectTimeInterval","statsReportTimeInterval","iceServers","urls","username","credential","conference","server","debug","whiteboard","linkpreview","session","login","users","blobs","subscriptions","events","data","addressbook","meetings","whiteboards","unfurl","calls","type","on","sessionExpired","xmppDataWrite","xmppDataRead","timeout","mode","constructor","getInstance","instance","set","options","this","api_url","chat_url","Object","keys","forEach","key","prototype","hasOwnProperty","call","optionValue","_val","nextKey","config","Utils","safeCallbackCall","cb","args","err","console","error","toString","getUrl","base","res","ext","resource","extension","isArray","arg","Array","isObject","obj","getBsonObjectId","ObjectId","machine","Math","floor","random","pid","increment","timestamp","Date","now","parseInt","padStart","DLog","loggers","length","logger","push","log","callTrafficUsageCallback","callbackName","getStringSize","str","Blob","size","body","b","headers","h","stringify","getDataSize","cloneObject","escapeNull","json","jsonObject","replace","parse","ProxyService","sdkInstance","requestsNumber","currentUserId","abortControllersMap","requestMethod","responseType","setSession","user_id","setCurrentUserId","getSession","userId","getCurrentUserId","logRequest","params","requestId","url","logResponse","response","buildRequestAndURL","isGetOrHeadType","isPostOrPutType","token","isInternalRequest","indexOf","isMultipartFormData","contentType","requestObject","method","requestURL","requestBody","buildRequestBody","useArrayQuery","dataObject","formData","FormData","item","fileEntry","fileToCustomObject","append","name","value","Uint8Array","serializeQueryParams","prefix","level","parts","objRecord","propName","propQueryName","encodeURIComponent","isArrayVal","strVal","sort","join","String","uriComponent","c","charCodeAt","abortRequest","abortId","controllers","controller","abort","processSuccessfulOrFailedRequest","abort_id","doneRequestsCount","ajax","Promise","resolve","reject","index","AbortController","signal","assign","requestInit","fetch","then","resp","dataType","text","ok","processAjaxResponse","processAjaxError","catch","responseBody","code","bodyObj","errors","statusCode","status","errorObject","info","errno","isExpiredSessionError","handleExpiredSessionResponse","handleResponse","retryCallback","AddressBookService","proxy","route","uploadAddressBook","list","Error","ajaxParams","contacts","get","udid","getRegisteredUsers","compact","AuthService","routes","async","createSession","generateCreateSessionParams","destroySession","user","id","logout","message","application_id","auth_key","password","email","provider","firebase_phone","firebase_email","escapeXMLTable","escapeXMLReplace","match","unescapeXMLTable","unescapeXMLReplace","num","slice","fromCodePoint","_escape","escapeXML","s","escapeXMLText","unescapeXML","result","start","end","previous","substring","unescapeXMLText","escape","require$$0","Element","attrs","parent","children","setAttrs","is","xmlns","getName","getNS","idx","findNS","attr","getXmlns","namespaces","m","getAttr","getChild","getChildren","child","getChildByAttr","val","recursive","getChildrenByAttr","flat","getChildrenByFilter","filter","getText","getChildText","getChildElements","root","up","cnode","nodes","node","prepend","unshift","t","remove","el","write","_addChildren","writer","k","v","tree","Element_1","createElement_1","__source","__self","entries","require$$1","SaxLtx","EventEmitter","super","remainder","parseRemainder","tagName","endTag","selfClosing","attrQuote","attrQuoteChar","attrName","state","recordStart","_handleTagOpening","emit","pos","endRecording","recorded","lt","quot","endcomment","endCDATA","substr","cData","startsWith","prevFirst","prevSecond","ltx","TimeoutError","promise","ms","promiseDelay","setTimeout","delay","race","finally","clearTimeout","map","WeakMap","onoff","target","addEventListener","addListener","bind","off","removeEventListener","removeListener","once","event","handler","rejectEvent","timeoutId","cleanup","onEvent","onError","reason","Deferred","procedure","entity","stanza","listener","done","element","send","listeners","subscribe","unsubscribe","XMLError","Parser","parser","LtxParser","cursor","onStartElement","onEndElement","onText","xml","createElement","detect","local","replaceAll","raw","search","unescape","JID","domain","TypeError","setDomain","setLocal","setResource","Symbol","toPrimitive","hint","Number","NaN","_domain","_local","getLocal","_resource","bare","equals","other","escaping.detect","escaping.escape","toLowerCase","escaping.unescape","getDomain","getResource","resourceStart","atStart","jid","defineProperty","j","equal","a","detectEscape","escapeLocal","unescapeLocal","XMPPError","condition","application","fromElement","second","third","StreamError","parseURI","URI","port","hostname","protocol","URL","parseHost","host","Connection","socketListeners","parserListeners","socket","isSecure","secure","_streamError","disconnect","_onData","onParserError","_detachParser","onSocketClosed","dirty","_detachSocket","_status","clean","onStreamClosed","_attachSocket","close","connect","_onElement","isStreamError","_onStreamError","isStanza","_onSeeOtherHost","service","includes","parseService","lang","open","_attachParser","_jid","_ready","resumed","_closeStream","_closeSocket","promiseOnline","Socket","socketParameters","headerElement","to","header","stop","runHooks","fragment","footer","footerElement","restart","sendReceive","all","string","isNonza","NS","hooks","Map","hook_events","Set","hook","assertHookEventName","has","add","unhook","handlers","find","Client","transports","Transport","sendMany","_findTransport","from","Reconnect","_timeout","onDisconnect","scheduleReconnect","CODE","uri","WebSocket","wasClean","fn","NS_FRAMING","ConnectionWebSocket","elements","test","TCPSocket","NS_STREAM","ConnectionTCP","tcp","tls","secureConnect","getProtocol","ConnectionTLS","koaCompose","middleware","context","next","dispatch","i","Context","IncomingContext","OutgoingContext","ctx","compose","errorHandler","reply","StanzaError","IQCaller","use","_route","isReply","deferred","delete","request","xid","timeoutPromise","_childRequest","buildReply","buildReplyError","buildError","iqHandler","isQuery","isValidQuery","buildReplyResult","ns","IGNORE_CODES","lookup","dns","addresses","family","address","srv","protcol","resolveSrv","records","record","srvs","srvAddresses","addr","split","lookupSrvs","toSorted","priority","weight","compare","p","link","rel","href","pop","compareAltConnections","fetchURIs","dns.resolve","http.resolve","_resolve","fallbackConnect","uris","shift","_connect","filterSupportedURIs","starttls","streamFeatures","net","TLSSocket","canUpgrade","negotiate","tlsSocket","upgrade","encode","globalThis","btoa","decode","atob","SASLError","getAvailableMechanisms","saslFactory","offered","_mechs","mech","sasl","onAuthenticate","_next","mechanisms","credentials","mechanism","create","realm","serviceType","serviceName","clientFirst","challenge","authenticate","userAgent","features","additionalData","final","aid","feature","sasl2","fast","promises","inline","getStreamFeatures","fast_available","auth","req","setup","_fast","iqCaller","makeBindElement","resourceBinding","bind2","tag","sessionFeatures","var","getSessionFeatures","module","Factory","exports","mechs","len","jlen","entry","factory","SASLFactory","reset","saveToken","deleteToken","save","fetchToken","expiry","isTokenValid","onInvalidToken","requestToken","available","createHash","createHmac","XOR","H","update","digest","HMAC","msg","Hi","salt","iterations","concat","ui1","ui","randomBytes","randombytes","utils","chal","dtives","tokens","dtiv","exec","saslname","escaped","curr","genNonce","bitops","RESP","CLIENT_KEY","SERVER_KEY","base64encode","Buffer","Mechanism","_genNonce","_stage","cred","values","_salt","_iterationCount","_nonce","r","_verifier","_error","e","_challenge","initial","_cnonce","authzid","_gs2Header","nonce","_clientFirstMessageBare","saltedPassword","clientKey","serverKey","gs2Header","_clientFinalMessageWithoutProof","every","storedKey","authMessage","clientSignature","clientProof","fromCharCode","apply","_serverSignature","cache","saslScramSha1","saslPlain","trace","saslAnonymous","createOnAuthenticate","getMechanism","tcpEnabled","setupIfAvailable","crypto","subtle","importKey","TextEncoder","hash","signature","sign","codePointAt","verify","ChatUtils","buildUserJid","buildUserJidLocalPart","createMessageStanza","createIqStanza","createPresenceStanza","createNonza","getElement","isErrorStanza","getAllElements","getElementText","getElementTreePath","elementsPath","reduce","prevElement","assignObjectToXml","assignExtraParamsToXml","extraParams","attachment","assignXmlToObject","parseExtraParams","attachments","dialogId","dialog_id","moduleIdentifier","buildErrorFromXMPPErrorStanza","errorStanza","errorElement","getUniqueId","suffix","uuid","parseReactions","reaction","items","WebSocketImpl","CUBE_TCP_ENABLE","CUBE_TLS_ENABLE","process","env","tlsEnabled","xmppClient","_reconnect","_websocket","_tcp","_tls","incoming","outgoing","incomingListener","outgoingListener","_middleware","_streamFeatures","_iqCaller","iqCallee","_iqCallee","scramsha1","plain","anonymous","_starttls","_sasl2","_bind2","htsha256none","_sasl","_resourceBinding","sendOnline","ChatHelpers","xmppJID","userCurrentJid","isNumeric","jidOrUserId","getUserJid","getRoomJidFromDialogId","typeChat","getUserNickWithMucDomain","getUserIdFromJID","getDialogIdFromJID","getRoomJid","getIdFromResource","getRoomJidFromRoomFullJid","getUserIdFromRoomJid","roomJid","getDialogJid","identifier","NonzaName","StreamManagement","enabled","clientHandledCounter","serverHandledCounter","messagesQueue","messagesQueueClearTimer","supported","removeElementHandler","addElementHandler","sendNonza","markMessagesQueueAsLost","sendAndCount","isMessage","isChat","isContent","markMessageAsLost","elementHandler","nextHandledCounter","currHandledCounter","isNaN","diffHandledCounter","markMessagesQueueAsSent","markMessagesQueueAsLostByTimeout","markMessageAsSent","onSentMessageCallback","clear","iterator","ackTimeout","acknowledgementTimeout","nonza","PrivacyList","helpers","stanzasCallbacks","privacyList","acc","action","mutualBlock","privacyListKeys","iqParams","iq","isMutual","userJid","userMuc","assignPrivacyItem","order","getList","_reject","query","currentList","currentListItem","updatedItem","updatedListItems","updatedList","getNames","defaultElement","activeElement","defaultName","activeName","allNames","listEl","default","names","setAsDefault","MultiUserChat","joinedRooms","dialogIdOrJid","dialogJid","presenceStanza","maxstanzas","x","isJoin","endsWith","isError","errorResponse","leave","_stanza","listOnlineUsers","iqStanza","stanzaId","DialogsService","admins_ids","occupants_ids","idOrIds","idsToDelete","trim","addAdmins","push_all","removeAdmins","pull_all","subscribeToPublic","unsubscribeFromPublic","updateNotificationsSettings","getNotificationsSettings","getPublicOccupants","clearHistory","MessagesService","ids","createSystem","unreadCount","chat_dialog_ids","listReactions","addReaction","updateReaction","removeReaction","putReaction","WebRTCSignalingProcessor","delegate","onMessage","userID","sessionId","sessionID","signalType","onCallHandler","onAcceptHandler","onRejectHandler","onStopHandler","onIceCandidatesHandler","onIceRestartHandler","onIceRestartAcceptHandler","AbstractChatService","dialog","isConnected","isConnecting","isLogout","isReconnect","start_date","toISOString","end_date","pingWithTimeout","timer","onConnectionErrorListener","ping","getListenerByName","listenerName","removeAllListeners","XMPPChatService","privacylist","xmppClientListeners","connectPromise","earlyIncomingMessagesQueue","connectionStatus","userJID","removeAllXMPPClientListeners","addXMPPClientListener","postConnectActions","onDisconnectedListener","onChatStatusListener","onPresence","onIQ","onSystemMessage","onMessageError","messageId","messageStanza","sendSystemMessage","recipients","recipient","sendWebRTCSignalingMessage","candidate","opponentId","sendIsTypingStatus","sendIsStopTypingStatus","sendDeliveredStatus","sendReadStatus","editMessage","originMessageId","last","deleteMessage","getLastUserActivity","onLastActivityStanza","seconds","onLastUserActivityListener","markActive","markInactive","terminate","rawStanza","forwardedStanza","invite","delivered","read","replaceSubElement","reactionsSubElement","removeSubElement","composing","paused","isForwarded","isGroup","recipientId","currentUserJid","onMessageTypingListener","onMessageUpdateListener","onMessageReactionsListener","onMessageDeleteListener","onDeliveredStatusListener","onReadStatusListener","recipient_id","is_forwarded","onMessageListener","mucUserId","actorElement","initiatorUserJid","initiatorId","onKickOccupant","onSystemMessageListener","onWebRTCSignalingMessage","webrtcSignalingProcessor","extensionElem","getCallExtension","iceCandidates","opponentsIDs","childName","childText","onMessageErrorListener","presence","enableCarbons","onReconnectListener","stanzasCallback","setSubscriptionToUserLastActivity","user_jid","subscribeToUserLastActivityStatus","unsubscribeFromUserLastActivityStatus","_listener","removeXMPPClientListener","_","C","o","d","enumerable","configurable","writable","D","E","n","A","U","O","endpoint","ws","http","onopen","onConnectEvent","onmessage","g","f","q","R","w","S","L","P","typing","onUserTypingListener","system_message","conversation_created","l","conversation_updated","conversation_kicked","u","onConversationCreateListener","onConversationUpdateListener","onConversationDeleteListener","onSystemMessageEvent","last_activity","onUserActivityListener","message_read","onMessageStatusListener","message_edit","onMessageEditListener","message_delete","message_reactions_update","responsesPromises","onMessageEvent","ask","mid","resObjKey","I","y","onerror","onclose","onDisconnectEvent","disableAutoReconnect","onLine","visibilityState","sendRequest","sendPromise","sendHttpPromise","localStorage","getItem","Authorization","statusText","connectSocket","device_id","deviceId","socketLogin","organization_id","disconnectSocket","userCreate","userEdit","userLogin","removeItem","userLogout","userSendOTPToken","userResetPassword","new_password","userDelete","userSearch","keyword","ignore_ids","limit","updated_at","getUsersByIds","getParticipantsByCids","cids","createUploadUrlForFiles","files","getDownloadUrlForFiles","file_ids","messageCreate","cid","replied_message_id","forwarded_message_id","messageSystem","uids","messageList","messageSummary","messageTone","tone","markConversationAsRead","mids","messageEdit","messageDelete","getUserActivity","subscribeToUserActivity","unsubscribeFromUserActivity","sendTypingStatus","conversationCreate","conversationUpdate","description","participants","image_object","conversationList","gt","conversationDelete","conversationSearch","conversationHandlerCreate","content","getConversationHandler","conversationHandlerDelete","pushSubscriptionCreate","platform","web_endpoint","web_key_auth","web_key_p256dh","device_udid","pushSubscriptionDelete","setActivityStatus","isInactive","blockList","blockUsers","unblockUsers","reactionsUpdate","reactionsList","BlockList","samaClient","block","userIds","unblock","SAMAChatService","currentUserNativeId","SAMAClient","removeAllSamaListeners","addAllSamaListeners","authorizedUser","native_id","onSamaConnectedListener","onSamaDisconnectListener","onSamaMessageEventListener","onSamaMessageListener","_id","messageParams","date_sent","onSamaSystemMessageListener","systemMessage","onWebRTCSignalingSystemMessage","opponentID","iceCandidate","iceObjectKey","onSamaMessageStatusListener","onSamaUserLastActivityListener","lastActivityTs","onSamaTypingListener","isTyping","onSamaMessageEditListener","messageEditParams","isLast","updatedBody","onSamaDeleteListener","onSamaMessageReactionListener","messageReaction","requestParams","ack","server_mid","userIdsOrDialogId","destinationParams","_params","markDialogAsRead","activityDate","ceil","_userId","Janus","sessions","mobile","isExtensionEnabled","getDisplayMedia","chromever","maxver","isInstalled","defaultExtension","extensionId","querySelector","getScreen","callback","pending","postMessage","init","origin","location","sourceId","gatewayCallbacks","success","noop","destroyed","initDone","isWebrtcSupported","websockets","wsHandlers","wsKeepaliveTimeoutId","servers","serversIndex","iceTransportPolicy","bundlePolicy","withCredentials","maxev","max_poll_events","apisecret","destroyOnUnload","keepAlivePeriod","longPollTimeout","getMaxBitrates","simulcastMaxBitrates","maxBitrates","high","medium","low","connected","pluginHandles","that","retries","transactions","eventHandler","warn","longpoll","getTime","httpAPICall","verb","handleEvent","textStatus","errorThrown","skipTimeout","transaction","reportSuccess","sender","pluginHandle","webrtcStuff","pc","remoteSdp","completed","addIceCandidate","endOfCandidates","candidates","webrtcState","hangup","ondetached","detach","mediaState","slowLink","plugindata","jsep","vdebug","keepAlive","janus","session_id","randomString","callbacks","newWebSocket","eventName","sendMessage","handleId","sdp","e2ee","rid_order","force_relay","sendTrickleCandidate","createDataChannel","dclabel","dcprotocol","pendingData","onDataChannelStateChange","label","dcState","dataChannel","readyState","ondataopen","dcoptions","dataChannelOptions","ondata","sendData","dataChanDefaultLabel","sendDtmf","dtmfSender","audioSender","getSenders","track","kind","dtmf","ontonechange","tones","duration","gap","insertDTMF","destroyHandle","noRequest","cleanupWebrtc","detached","createPeerconnectionIfNeeded","pc_config","insertableStreams","tracks","transforms","receiver","createEncodedStreams","createEncodedAudioStreams","createEncodedVideoStreams","forceEncodedAudioInsertableStreams","forceEncodedVideoInsertableStreams","encodedInsertableStreams","getStats","volume","bitrate","trickle","oniceconnectionstatechange","iceState","iceConnectionState","onicecandidate","iceDone","mySdp","localDescription","sdpSent","sendSDP","sdpMid","sdpMLineIndex","ontrack","streams","transceiver","_mid","onremotetrack","onended","trackMutedTimeoutId","ev","transceivers","getTransceivers","_receiver","_track","onmute","onunmute","prepareWebrtc","offer","webrtcError","media","mediaToTracks","simulcast","simulcast2","svc","captureDevices","setRemoteDescription","answer","customizeSdp","createAnswer","setLocalDescription","mediaConstraints","iceRestart","createOffer","prepareWebrtcPeer","replaceTracks","openedConsentDialog","groups","gumGroup","capture","group","audio","video","ondatachannel","channel","nt","trackId","replaceTrack","stream","getAudioTracks","getVideoTracks","consentDialog","constraints","trackConstraints","otherType","otherTrack","otherConstraints","getUserMedia","newDirection","recv","direction","setDirection","myStream","addTrack","webRTCAdapter","browserDetails","browser","addTransceiver","sendEncodings","rid","maxBitrate","scaleResolutionDownBy","parameters","getParameters","encodings","setParameters","scalabilityMode","codec","mimeType","codecs","getCapabilities","setCodecPreferences","framerate","maxFramerate","senderStreams","createAudioEncodedStreams","readableStream","writableStream","pipeThrough","pipeTo","readable","receiverStreams","dontStop","rt","removeTrack","onlocaltrack","curdir","newdir","getLocalTracks","tr","getRemoteTracks","getVolume","remote","stats","remoteSource","audioLevel","isMuted","mute","videostream","audiostream","getBitrate","bsnow","bsbefore","tsnow","tsbefore","setInterval","inStats","mediaType","bytesReceived","googCodecName","timePassed","bitRate","round","setBitrate","hangupRequest","clearInterval","streamExternal","stopAllTracks","oncleanup","getServer","getSessionId","getInfo","destroy","unload","notifyDestroyed","cleanupHandles","sendBeacon","unbindWebSocket","onUnbindMessage","onUnbindError","attach","ordered","plugin","opaqueId","loopIndex","handleToken","opaque_id","loop_index","started","getId","getPlugin","getRemoteVolume","getLocalVolume","isAudioMuted","muteAudio","unmuteAudio","isVideoMuted","muteVideo","unmuteVideo","setMaxBitrate","handleRemoteJsep","createHandle","useDefaultDependencies","deps","socketCls","proto","arr","fetchOptions","Accept","fetching","timerId","parsed","useOldDependencies","jq","jQuery","payload","xhrFields","extend","xhr","keepAudio","audioSend","audioRecv","addAudio","replaceAudio","removeAudio","keepVideo","videoSend","videoRecv","addVideo","replaceVideo","removeVideo","screenshareFrameRate","frameRate","screenshareHeight","height","screenshareWidth","width","ideal","getTracks","mst","usedDependencies","dependencies","listDevices","isGetUserMediaAvailable","enumerateDevices","devices","safariVp8","testpc","offerToReceiveVideo","charSet","randomPoz","charAt","JanusClient","videoRoomPlugin","isOnlyAudio","currentRoomId","remoteFeeds","remoteJseps","remoteFeedsAttachingInProgress","bitrateTimers","emitter","timeoutSessionCallback","JanusEngine","engine","attachVideoConferencingPlugin","isRemote","skipMedia","remoteFeed","localStream","displayName","listen","room","ptype","feed","display","uplink","nacks","feedId","offerParams","publishers","userDisplayName","detachRemoteFeed","onLocalTrack","metadata","onRemoteTrack","channelLabel","_on","eventType","isStreamNoExistedBefore","feedStream","trackToRemove","streamTrack","getPluginId","detachVideoConferencingPlugin","roomId","joinEvent","_resp","leaveEvent","listOnlineParticipants","listRequest","toggleAudioMute","muted","toggleRemoteAudioMute","audioTracks","isRemoteAudioMuted","toggleVideoMute","toggleRemoteVideoMute","videoTracks","isRemoteVideoMuted","sendKeyframeRequest","configureRequest","keyframe","getTracksFromStream","audioTrack","videoTrack","mediaParams","existedStream","createOfferParams","tracksFromStream","tracksFromParams","_jsep","publish","getTracksMidsFromStream","getUserBitrate","resultCallback","getUserVolume","showBitrate","adapterDetails","hideBitrate","ConferenceSession","client","currentUserDisplayName","onParticipantJoined","onParticipantLeft","onRemoteStream","onRemoteTracksUpdated","onDataChannelOpen","onDataChannelMessage","currentPublisherPC","isResolved","createHandler","joinInternal","joinAsListener","onRemoteIceStateChanged","onLocalIceStateChanged","onSlowLink","isExistingParticipant","onParticipantJoinedListener","onParticipantLeftListener","onErrorListener","onDataChannelOpenedListener","onDataChannelMessageListener","onSessionConnectionStateChangedListener","onRemoteConnectionStateChangedListener","onRemoteStreamListener","onRemoteTracksUpdatedListener","onSlowLinkListener","listOfOnlineParticipants","leaveGroup","elementId","upsertStream","shouldUpdateCurrentStream","detachMediaStream","attachMediaStream","getSettings","localTrack","newTrack","pcSenders","switchMediaTracks","device","getRemoteUserBitrate","getRemoteUserVolume","opt","mediaElement","getElementById","srcObject","style","transform","mirror","onloadedmetadata","_event","play","pause","ConferenceClient","sessionsStore","createNewSession","getCurrentSessionToken","getMediaDevices","clearSession","currentSession","DataService","className","isMany","multi","createRecord","readPermissions","permissions","isSearch","search_criteria","isCriteria","isOne","MeetingsService","startTimestamp","endTimestamp","defaultParams","toLocaleString","year","month","day","hour","minute","attendees","getRecordings","PushNotificationsService","SubscriptionsService","EventsService","base64Encode","StorageService","blob","createAndUpload","file","content_type","public","isPublic","createParams","blobObject","parseUri","blob_object_access","uploadParams","authority","path","queryKey","decodeURIComponent","upload","markUploaded","getFile","uid","getFileObject","privateUrl","fileUID","publicUrl","strict","loose","source","userInfo","relative","directory","anchor","_0","UsersService","getV2","signup","resetPassword","listOnline","getOnlineCount","count","filters","dateFields","numberFields","extensions","full_name","facebook_id","twitter_id","phone","tags","external","generateFilter","field","param","WebRTCHelpers","traceWarning","traceError","getVersionFirefox","ua","ffInfo","getVersionSafari","sVer","WebRTCPeerConnection","remoteSDP","onStatusClosedChecker","dialingTimer","statsReportTimer","waitingReconnectTimeoutCallback","released","remoteStream","rtcConfiguration","original","startCallTime","onMediaTrackHandler","onIceCandidateHandler","onSignalingStateHandler","onIceConnectionStateHandler","callType","getWrappedStats","signalingState","canTrickleIceCandidates","processIceCandidates","onSessionConnectionStateChanged","clearWaitingReconnectTimer","startWaitingReconnectTimer","release","closeSessionIfAllConnectionsClosed","clearStatsReportTimer","addCandidates","clearDialingTimer","getAndSetLocalSessionDescription","maxBandwidth","offerOptions","sessionDescription","setRTCRtpSenderMaxBandwidth","senders","encoding","startDialingTimer","withOnNotAnswerCallback","dialingCallback","skipIncrement","processOnNotAnswer","processCall","setRemoteSessionDescription","desc","lastResult","getStatsCustom","results","lastResults","onCallStatsReport","sdpRemote","ID","onSuccess","onFail","statistic","localVideoSettings","frameHeight","frameWidth","getBitratePerSecond","packetsReceived","framerateMean","framesPerSecond","bytesSent","packetsSent","candidateType","mozLocalTransport","transport","ip","ipAddress","portNumber","getFramesPerSecond","isLocal","framesSent","framesReceived","selector","WebRTCSignalingProvider","chatService","sendCandidate","signalingType","systemCallMessage","WebRTCSession","peerConnections","answerTimer","waitingOfferOrAnswerTimer","acceptCallTime","generateUUID","setMaxBandwidth","peers","peersKeys","connectionStateForUser","peerConnection","constrains","prepareExtension","callInternal","accept","clearAnswerTimer","acceptInternal","initiatorID","currentUserID","startWaitingOfferOrAnswerTimer","callerID","signalingProvider","canInitiateIceRestart","processOnCall","rtcSdpType","startAnswerTimer","processOnAccept","processOnReject","clearWaitingOfferOrAnswerTimer","processOnStop","pcKeys","processOnIceCandidates","processOnIceRestart","processOnIceRestartAccept","onUserNotAnswerListener","onCallStatsReportListener","connectionState","closeLocalMediaStream","onSessionCloseListener","isAllClosed","muteStream","unmute","timeWait","timeDiff","min","max","WebRTCClient","signalingProcessor","SessionConnectionState","onDevicesChangeListener","ondevicechange","bandwidth","createAndStoreSession","webRTCSession","callRejectRequest","onCallListener","onAcceptCallListener","onRejectCallListener","onInvalidEventsListener","onStopCallListener","WhiteboardService","getURL","title","paramsOrId","chat_dialog_id","LinkPreviewService","linkPreview","images","getHostFromUrl","ConnectyCube","configMap","storage","pushnotifications","meeting","videochatconference","connectycube","COMPACT","FULL","CREATE","READ","UPDATE","OPEN","OWNER","NOT_ALLOWED","OPEN_FOR_GROUPS","OPEN_FOR_USERS_IDS","IOS","ANDROID","WEB","UPDATED","LAST_MESSAGE","PUBLIC","GROUP","PRIVATE","BROADCAST","MEETING","SENT","DELIVERED","FACEBOOK","TWITTER","FIREBASE_PHONE","FIREBASE_EMAIL","MINUTES","HOURS","DAYS","WEEK","APNS","VOIP","GCM","DEV","PROD"],"mappings":"iUAGO,MCCMA,EAAgC,kBAEhCC,EAAoB,CAC/BC,KAAM,OACNC,OAAQ,SACRC,OAAQ,SACRC,KAAM,SACNC,QAAS,aACTC,eAAgB,mBAChBC,UAAW,iBAIAC,EAA6B,CACxCC,UAAW,EACXC,WAAY,EACZC,UAAW,EACXC,OAAQ,EACRC,aAAc,EACdC,OAAQ,EACRC,UAAW,GAIAC,EAAmB,CAC9BC,IAAK,EACLC,OAAQ,EACRC,QAAS,EACTC,SAAU,EACVN,OAAQ,GAIGO,EAAW,CACtBC,MAAO,EACPC,MAAO,GAIIC,EAAY,CACvBvB,KAAM,OACNC,OAAQ,SACRC,OAAQ,SACRC,KAAM,OACNqB,QAAS,UACTC,WAAY,aACZC,cAAe,gBACfC,iBAAkB,mBAClBC,MAAO,QACPC,aAAc,eACdC,QAAS,WAIEC,EAAsB,CACjCf,IAAK,EACLP,WAAY,EACZuB,SAAU,EACVtB,UAAW,EACXE,aAAc,EACdD,OAAQ,EACRE,OAAQ,EACRC,UAAW,GCrDAmB,EAAW,CACtBC,KAAM,OACNC,UAAW,aAIAC,EAAY,CACvBC,OAAQ,SACRC,MAAO,QACP1B,aAAc,eACd2B,YAAa,cACbC,QAAS,UACTC,eAAgB,iBAChBC,cAAe,gBACfC,eAAgB,iBAChBC,eAAgB,iBAChBC,eAAgB,iBAChBC,kBAAmB,oBACnBC,kBAAmB,oBACnBC,aAAc,eACdC,aAAc,eACdC,mBAAoB,qBACpBC,KAAM,OACNC,MAAO,QACPC,KAAM,QAIKC,EAAoB,CAC/BC,MAAO,QACPC,KAAM,QCxCKC,EAAe,CAC1BC,KAAM,EACNC,GAAI,GAIOC,EAAiB,CAC5BC,IAAK,MACLC,MAAO,QACPC,MAAO,QACPC,OAAQ,SACRC,IAAK,MACLC,KAAM,OACN5B,MAAO,SAII6B,EAAW,CACtBC,KAAM,OACNC,KAAM,QCnBKC,EAAkB,CAC7BjD,MAAO,aACPC,MAAO,cAIIiD,EAAa,CACxBC,mBAAoB,qBACpBC,iBAAkB,mBAClBC,aAAc,eACdhD,cAAe,gBACfiD,sBAAuB,wBACvBC,kBAAmB,oBACnBC,qBAAsB,uBACtBvC,MAAO,SAIIwC,EAAgB,CAC3BzD,MAAO,QACPC,MAAO,SAIIyD,EAAwB,CACnCC,QAAS,UACTC,MAAO,QACPC,KAAM,OACNC,OAAQ,UAIGC,EAAkB,CAC7BjC,KAAM,OACNkC,KAAM,OACNC,UAAW,YACXX,sBAAuB,gBACvBjD,cAAe,gBACf6D,wBAAyB,0BACzBC,oBAAqB,sBACrBX,qBAAsB,uBACtBY,yBAA0B,2BAC1BnD,MAAO,SC7CIoD,EAAY,CACvBpE,MAAO,QACPD,MAAO,QACPsE,KAAM,QCCKC,EAAc,CACzBC,IAAK,MACLC,KAAM,OACNC,IAAK,MACLC,MAAO,QACPC,OAAQ,SACRC,KAAM,QAIKC,EAAY,CACvBC,KAAM,OACNC,KAAM,QCVKC,EAAa,QAEbC,EAA8B,oBAAXC,QAA8C,iBAAbC,SACpDC,GAAW,EACXC,GAAgB,EAChBC,GAAS,EAETC,EAAUN,EAAYC,OAAOK,aAAUC,EACvCC,EAAYR,EAAYC,OAAOO,eAAYD,EAC3CE,EAAeT,GAAaQ,EAAYA,EAAUC,kBAAeF,EACjEG,EAAcV,EAAYC,OAAOS,iBAAcH,EAC/CI,EAAmBX,EAAYC,OAAOU,sBAAmBJ,EACzDK,EAAkBZ,EAAYC,OAAOW,qBAAkBL,EACvDM,EAAoBb,EAAYC,OAAOY,uBAAoBN,EAC3DO,EAAiBd,EAAYC,OAAOa,oBAAiBP,EACrDQ,EAAef,EAAYC,OAAOc,kBAAeR,EACjDS,EAAwBhB,EAAYC,OAAOe,2BAAwBT,EACnEU,IAA6BjB,GAAYkB,QAAQT,GAAgBI,oSClBjEM,EACHC,gBAEDC,QAAkBtB,EAClBuB,MAAwC,CAAEC,MAAO,GAAIC,QAAS,IAC9DC,UAA0C,CAC/CC,IAAK,uBACLC,KAAM,wBACNC,IAAK,6BAEAC,aAAoD,CACzDC,KAAM,qCACNC,UAAW,mCACXC,OAAQ,GAEHL,KAAgC,CACrCM,iBAAkB,CAAEC,QAAQ,GAC5BC,UAAW,CAAED,QAAQ,EAAME,aAAc,GACzCC,OAAQzE,EAASE,MAEZwE,UAA0C,CAC/CC,kBAAkB,EAClBC,mBAAoB,GACpBC,oBAAqB,EACrBC,uBAAwB,GACxBC,wBAAyB,KACzBC,WAAY,CACV,CAAEC,KAAM,gCACR,CAAEA,KAAM,8BACR,CACEA,KAAM,gDACNC,SAAU,eACVC,WAAY,oCAEd,CACEF,KAAM,gDACNC,SAAU,eACVC,WAAY,sCAIXC,WAA4C,CACjDC,OAAQ,oCACRC,MAAO7F,EAAeC,KAEjB6F,WAA4C,CAAEF,OAAQ,uCACtDG,YAA8C,CAAEH,OAAQ,wCACtDJ,KAAqC,CAC5CQ,QAAS,UACTC,MAAO,QACPC,MAAO,QACP5B,KAAM,OACN6B,MAAO,QACPC,cAAe,gBACfC,OAAQ,SACRC,KAAM,OACNC,YAAa,eACbC,SAAU,WACVC,YAAa,cACbC,OAAQ,SACRC,MAAO,QACPC,KAAM,SAEDC,GAAmC,CACxCC,oBAAgB5D,EAChB6D,mBAAe7D,EACf8D,kBAAc9D,GAET+D,QAAyB,KACzBpB,MAAkC,CAAEqB,KAAM,GAEjD,WAAAC,GAAuB,CAEhB,kBAAOC,GAIZ,OAHKtD,EAAOuD,WACVvD,EAAOuD,SAAW,IAAIvD,GAEjBA,EAAOuD,QAChB,CAEO,GAAAC,CAAIC,GACTC,KAAKpD,UAAUqD,QAAUF,EAAQnD,WAAWqD,QAExCF,EAAQnD,WAAWE,OACrBkD,KAAKpD,UAAUG,IAAM,OAAOgD,EAAQnD,UAAUE,OAC9CkD,KAAKhD,aAAaC,KAAO,WAAW8C,EAAQnD,UAAUE,YACtDkD,KAAKhD,aAAaE,UAAY6C,EAAQnD,UAAUsD,UAAY,SAASH,EAAQnD,UAAUE,aAGzFqD,OAAOC,KAAKL,GAASM,QAASC,IAC5B,GAAY,QAARA,GAAiBH,OAAOI,UAAUC,eAAeC,KAAKT,KAAMM,GAAM,CACpE,MAAMI,EAAcX,EAAQO,GAEtBK,EAAOX,KADAM,GAGc,iBAAhBI,GAA4C,OAAhBA,EACrCP,OAAOC,KAAKM,GAAaL,QAASO,IACnB,OAATD,GAAiC,iBAATA,GAAqBR,OAAOI,UAAUC,eAAeC,KAAKE,EAAMC,KACzFD,EAAqBC,GAAYF,EAA4BE,MAIjEZ,KAAqBM,GAAOI,CAEjC,GAEJ,EAGF,IAAAG,EAAevE,EAAOsD,cC9GR,MAAOkB,GACnBvE,eAAsC,GAEtCA,WAAa,CACXhB,gBACAJ,YACAG,WACAE,UAGF,uBAAOuF,CAAiBC,EAAmB,QACzC,MAAO,IAAIC,KACT,GAAkB,mBAAPD,EACT,IACEA,KAAMC,EACR,CAAE,MAAOC,GACPC,QAAQC,MAAM,qBAAsBF,EAAK,yBAAyBF,EAAGK,kBACvE,EAGN,CAEA,aAAOC,CAAOC,EAAgDC,EAAuBC,GACnF,MAAMC,EAAWF,EAAM,IAAIA,IAAQ,GAC7BG,EAAYF,EAAM,IAAIA,IAAQ,GACpC,MAAO,GAAGZ,EAAOjE,UAAUqD,SAAW,WAAWY,EAAOjE,UAAUC,SAAS0E,IAAOG,IAAWC,IAAYd,EAAO7C,KAAKoB,MACvH,CAEA,cAAOwC,CAAQC,GACb,OAAOC,MAAMF,QAAQC,EACvB,CAEA,eAAOE,CAASC,GACd,MAA+C,oBAAxC7B,OAAOI,UAAUc,SAASZ,KAAKuB,EACxC,CAEA,sBAAOC,GAGL,MAAMC,EAAW,CACfC,QAASC,KAAKC,MAAsB,SAAhBD,KAAKE,UAAqBjB,SAAS,IACvDkB,IAAKH,KAAKC,MAAsB,MAAhBD,KAAKE,UAAkBjB,SAAS,IAChDmB,UAAW,GAEPC,EAAYL,KAAKC,MAAMK,KAAKC,MAAQ,KAAMtB,SAAS,IACnDmB,GAAaN,EAASM,aAAanB,SAAS,IAMlD,OAJIuB,SAASJ,EAAW,IAAM,WAC5BN,EAASM,UAAY,GAIrBC,EAAUI,SAAS,EAAG,KACtBX,EAASC,QAAQU,SAAS,EAAG,KAC7BX,EAASK,IAAIM,SAAS,EAAG,KACzBL,EAAUK,SAAS,EAAG,IAE1B,CAEA,WAAOC,IAAQ7B,GACb,GAAIH,GAAMiC,QAAQC,OAAS,EAEzB,YADAlC,GAAMiC,QAAQ1C,QAAS4C,GAAWA,EAAOhC,IAQ3C,GAA4B,iBAAjBJ,EAAOxC,MAAoB,EACtByD,MAAMF,QAAQf,EAAOxC,MAAMqB,MAAQmB,EAAOxC,MAAMqB,KAAO,CAACmB,EAAOxC,MAAMqB,OAC7EW,QAASX,IACA,IAATA,GACFoB,GAAMiC,QAAQG,KAPX,IAAIjC,IAAoBE,QAAQgC,OAAOlC,KAUhD,CAEAH,GAAMiC,QAAQ1C,QAAS4C,GAAWA,EAAOhC,GAC3C,CAEA,+BAAOmC,CAAyBC,EAAgDvE,GAC9E,GAAuC,mBAA5B+B,EAAOxB,GAAGgE,GAA8B,OAEnD,MAAMC,EAAiBC,GAAwB,IAAIC,KAAK,CAACD,IAAME,KAS/D5C,EAAOxB,GAAGgE,GARU,EAACvE,EAAwB,MAC3C,MAAQ4E,KAAMC,EAAGC,QAASC,GAAM/E,EAChC,IAAI2E,EAAO,EAGX,OAFIE,IAAGF,GAAQH,EAA2B,iBAANK,EAAiBA,EAAI3I,KAAK8I,UAAUH,KACpEE,IAAGJ,GAAQH,EAActI,KAAK8I,UAAUD,KACrCJ,GAGeM,CAAYjF,GAAOA,EAC7C,CAEA,kBAAOkF,CAAehC,EAAS,GAASiC,GAAsB,GAC5D,IACE,MAAMC,EAAOlJ,KAAK8I,UAAU9B,GACtBmC,EAAaF,EAAaC,EAAKE,QAAQ,QAAS,MAAQF,EAE9D,OAAOlJ,KAAKqJ,MAAMF,EACpB,CAAE,MACA,OAAOnC,CACT,CACF,ECtGY,MAAOsC,GACZC,YAAiC,CACtC1D,SACArC,QAAS,MAEJgG,eAAyB,EACxBC,cACAC,oBAAiD,CAAA,EAClDC,cAAoCnK,EACpCoK,aAAiC7J,EAEjC,UAAA8J,CAAWrG,GAChBwB,KAAKuE,YAAY/F,QAAUA,EAEvBA,GAAWA,EAAQsG,SACrB9E,KAAK+E,iBAAiBvG,EAAQsG,QAElC,CAEO,UAAAE,GACL,OAAOhF,KAAKuE,YAAY/F,OAC1B,CAEO,gBAAAuG,CAAiBE,GACtBjF,KAAKyE,cAAgBQ,QAAUvJ,CACjC,CAEO,gBAAAwJ,GACL,OAAOlF,KAAKyE,aACd,CAEO,UAAAU,CAAWC,EAAsBC,GACtCvE,GAAMgC,KAAK,aAAauC,KAAc,GAAGD,EAAOhG,MAAQ,SAASgG,EAAOE,MAAOF,EACjF,CAEO,WAAAG,CAAYC,EAA6BH,GAC9CvE,GAAMgC,KAAK,cAAcuC,KAAcG,EACzC,CAEO,kBAAAC,CAAmBL,GACxB,MAAMM,GAAmBN,EAAOhG,MAAwB,QAAhBgG,EAAOhG,MAAkC,SAAhBgG,EAAOhG,KAClEuG,IAAkBP,EAAOhG,OAAuB,SAAhBgG,EAAOhG,MAAmC,QAAhBgG,EAAOhG,MACjEwG,EAAQ5F,KAAKuE,aAAevE,KAAKuE,YAAY/F,SAAWwB,KAAKuE,YAAY/F,QAAQoH,MACjFC,GAA+D,IAA3CT,EAAOE,IAAIQ,QAAQ,oBACvCC,GAA6C,IAAvBX,EAAOY,YAC7BrJ,EAAUyI,EAAOzI,QACjBsJ,EAAoC,CACxCC,OAAQd,EAAOhG,MAAQ,OAGzB,IAAI+G,EAAaf,EAAOE,IAExB,GAAIF,EAAOtG,KAAM,CACf,MAAMsH,EAAcpG,KAAKqG,iBAAiBjB,EAAQW,EAAqBJ,GAEnED,EACFS,GAAc,IAAIC,IAElBH,EAAcvC,KAAO0C,CAEzB,CA4BA,OA1BKL,IACHE,EAAcrC,QAAU,CACtB,eAAgB+B,EACZ,iCACA,qDAIJE,IACGI,EAAcrC,UACjBqC,EAAcrC,QAAU,CAAA,GAG1BqC,EAAcrC,QAAQ,UAAY,MAAM/C,EAAOrE,mBAE3CoJ,EACFK,EAAcrC,QAAQ,YAAcgC,EAC3BjJ,IACTsJ,EAAcrC,QAAQ,cAAgBjH,IAItCkE,EAAOpB,UACTwG,EAAcxG,QAAUoB,EAAOpB,SAG1B,CAACwG,EAAeE,EACzB,CAEO,gBAAAE,CACLjB,EACAW,EACAJ,GAEA,MAAM7G,EAAOsG,EAAOtG,KACdwH,EAAgBlB,EAAOkB,cAE7B,IAAIC,EAEJ,GAAIR,EAAqB,CACvB,MAAMS,EAAW,IAAIC,SACrBtG,OAAOC,KAAKtB,GAAMuB,QAAQ,SAAUqG,GAClC,MAAMC,EAAY7H,EAAK4H,GAEvB,GAAItB,EAAOwB,oBAA+B,SAATF,GAAmBC,EAClDH,EAASK,OAAOH,EAAMC,EAAU7H,KAAM6H,EAAUG,UAC3C,CACL,MAAMC,EAAQjI,EAAK4H,GACnBF,EAASK,OAAOH,EAAMK,aAAiBC,WAAa,IAAIxD,KAAK,CAAC,IAAIwD,WAAWD,KAAYA,EAC3F,CACF,GACAR,EAAaC,CACf,MACED,EADSZ,EACI3K,KAAK8I,UAAUhF,GAEfkB,KAAKiH,qBAAqBnI,EAAM,GAAIwH,EAAe,GAGlE,OAAOC,CACT,CAEO,oBAAAU,CACLjF,EACAkF,EACAZ,EACAa,EAAQ,GAER,MAAMC,EAAkB,GAClBC,EAAYrF,EAElB,IAAK,MAAMsF,KAAYD,EAAW,CAChC,IAAIE,EAAgBvH,KAAKwH,mBAAmBF,GAExCxG,GAAMc,QAAQI,KAChBuF,EAAgB,IAGlB,MAAMjH,EAAM4G,EAASA,EAAS,IAAIK,KAAmBA,EACrD,IAAIR,EAAQM,EAAUC,GACtB,MAAMG,EAAa3G,GAAMc,QAAQmF,GAEjC,GAAKU,IAAenB,GAA2B,IAAVa,IAAiBrG,GAAMiB,SAASgF,GACnEK,EAAMlE,KAAKlD,KAAKiH,qBAAqBF,EAAOzG,EAAKgG,IAAiBa,QAC7D,CACL,MAAMO,EAASD,EAAaV,EAAMY,OAAOC,KAAK,KAAOC,OAAOd,GAC5DK,EAAMlE,KAAK,GAAG5C,KAAON,KAAKwH,mBAAmBE,KAC/C,CACF,CAEA,OAAON,EAAMO,OAAOC,KAAK,IAC3B,CAEO,kBAAAJ,CAAmBM,GACxB,OAAON,mBAAmBM,GAAc1D,QAAQ,qBAAuB2D,GAAM,IAAIA,EAAEC,WAAW,GAAG3G,SAAS,MAC5G,CAEO,YAAA4G,CAAaC,GAClB,GAAIlI,KAAK0E,oBAAoBwD,GAAU,EACjBlI,KAAK0E,oBAAoBwD,GAASC,aAAe,IAEzD9H,QAAS+H,IACnBA,EAAWC,SAEf,CACF,CAEO,gCAAAC,CAAiCC,GACtC,IAAKA,IAAavI,KAAK0E,oBAAoB6D,GACzC,OAGF,MAAMJ,EAAcnI,KAAK0E,oBAAoB6D,GAAUJ,aAAe,GAEjEnI,KAAK0E,oBAAoB6D,GAAUC,kBAGtCxI,KAAK0E,oBAAoB6D,GAAUC,mBAAqB,EAFxDxI,KAAK0E,oBAAoB6D,GAAUC,kBAAoB,EAK/BxI,KAAK0E,oBAAoB6D,GAAUC,oBAEnCL,EAAYnF,eAC7BhD,KAAK0E,oBAAoB6D,EAEpC,CAEO,UAAME,CAAQrD,GACnB,MAAMC,IAAcrF,KAAKwE,eAEzB,OAAO,IAAIkE,QAAQ,CAACC,EAASC,KAC3B5I,KAAKmF,WAAWC,EAAQC,GAExB,MAAOY,EAAeE,GAAcnG,KAAKyF,mBAAmBL,GACtDmD,EAAWnD,EAAOmD,SAExB,GAAIA,EAAU,CACZ,IAAIM,EAAQ,EAEZ,GAAI7I,KAAK0E,oBAAoB6D,GAAW,CACtC,MAAMJ,EAAcnI,KAAK0E,oBAAoB6D,GAAUJ,aAAe,GACtEnI,KAAK0E,oBAAoB6D,GAAUJ,YAAYjF,KAAK,IAAI4F,iBACxDD,EAAQV,EAAYnF,OAAS,CAC/B,MACEhD,KAAK0E,oBAAoB6D,GAAY,CACnCJ,YAAa,CAAC,IAAIW,kBAGtB,MAAMC,EAAS/I,KAAK0E,oBAAoB6D,GAAUJ,YAAYU,GAAOE,OACrE5I,OAAO6I,OAAO/C,EAAe,CAAE8C,UACjC,CAEA,IAAIvD,EAEJ,MAAM9B,EAA8B,OAAvBuC,EAAcvC,UAAgBhI,EAAYuK,EAAcvC,KAC/DuF,EAAc,IAAKhD,EAAevC,QAMxCwF,MAAM/C,EAAY8C,GACfE,KAAMC,IACL5D,EAAW4D,EAEX,OADiBhE,EAAOiE,UAAYtO,EAAUC,QAC1BD,EAAUE,KAAOmO,EAAKE,OAASF,EAAKlF,SAEzDiF,KAAMzF,IACL1D,KAAKsI,iCAAiCC,GACjC/C,EAAU+D,GAWbvJ,KAAKwJ,oBAAoB9F,EAAMiF,EAA+CtD,GAV9ErF,KAAKyJ,iBACHjE,EACA9B,EACA,KACAkF,EACAD,EACAvD,EACAC,KAMLqE,MAAOtI,IACNpB,KAAKsI,iCAAiCC,GACtCvI,KAAKyJ,iBACHjE,GAAY,KACZ,IACApE,EACAwH,EACAD,EACAvD,EACAC,MAIV,CAEO,mBAAAmE,CACL9F,EACAiF,EACAtD,GAEA,MAAMsE,EAAejG,SAAgD,MAATA,EAAeA,EAAO,aAClF1D,KAAKuF,YAAYoE,EAActE,GAE/BsD,EAAQjF,EACV,CAEO,gBAAA+F,CACLjE,EACA9B,EACAtC,EACAwH,EACAD,EACAvD,EACAC,GAEA,MAAMnE,EAAME,EACZ,IAAKoE,GAAYpE,IAAUF,EAAI0I,KAE7B,YADAhB,EAAOxH,GAIT,MAAMyI,EAAUnG,EACViG,EAAejG,GAAQtC,GAASyI,GAASC,OACzCC,EAAavE,GAAUwE,OAIvBC,EAAiC,CACrCL,KAJgCpE,GAAYuE,IAAgB3I,EAAQF,EAAI0I,UAAOlO,GAK/EwO,MAHCxG,GAAwB,iBAATA,GAA8B,MAATA,EAAe1I,KAAKqJ,MAAMX,GAAQA,KAAUtC,EAAQF,EAAIiJ,WAAQzO,IAMvGsE,KAAKuF,YAAYoE,EAActE,SAE1BG,GAAUF,KAAO,IAAIQ,QAAQjF,EAAO7C,KAAKQ,UACxCwB,KAAKoK,sBAAsBH,IAAoD,mBAA7BpJ,EAAOxB,GAAGC,eAC9DU,KAAKqK,6BAA6BJ,EAAa,KAAMrB,EAAQD,EAASvD,GAKxEwD,EAAOqB,EAEX,CAEO,4BAAAI,CACLjJ,EACAoE,EACAoD,EACAD,EACAvD,GAEA,MAAMkF,EAAiB,KACjBlJ,EACFwH,EAAOxH,GAEPuH,EAAQnD,IAIN+E,EAAiB/L,IACjBA,IACFwB,KAAK6E,WAAWrG,GAChBwB,KAAKyI,KAAKrD,GAAQ+D,KAAKR,GAASe,MAAMd,KAIF,mBAA7B/H,EAAOxB,GAAGC,gBACnBuB,EAAOxB,GAAGC,eAAegL,EAAgBC,EAE7C,CAEQ,qBAAAH,CAAsBhJ,GAC5B,IACE,OAAOA,GAAwB,MAAfA,EAAMwI,MAAkD,oCAAlCxI,EAAM8I,MAAMJ,QAAQvI,OAAO,EACnE,CAAE,MACA,OAAO,CACT,CACF,ECvVY,MAAOiJ,GACZC,MACEC,MAAQ7J,EAAO7C,KAAKe,YAE7B,WAAAY,CAAY8K,GACVzK,KAAKyK,MAAQA,CACf,CAEO,uBAAME,CACXC,EAA8B,GAC9BxF,EAAmC,CAAA,GAEnC,IAAKtE,GAAMc,QAAQgJ,GACjB,MAAM,IAAIC,MAAM,qCAGlB,MAAMC,EAAa,CACjB1L,KAAM5E,EAAYE,KAClB4K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,OACvB5L,KAAM,CAAEiM,SAAUH,KAASxF,IAG7B,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,SAAME,CAAIC,GACf,MAAMH,EAAa,CACjB1L,KAAM5E,EAAYC,IAClB6K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,OACvB5L,KAAMmM,EAAO,CAAEA,aAASvP,GAG1B,OAAOsE,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,wBAAMI,CACX9F,GAA+C,GAE/C,MAAM0F,EAAa,CACjB1L,KAAM5E,EAAYC,IAClB6K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAO,oBAC9B5L,KAAwB,kBAAXsG,EAAuB,CAAE+F,QAAS/F,EAAS,EAAI,GAAMA,GAGpE,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,EC7CY,MAAOM,GACZX,MAEEY,OAAS,CAChB7M,QAASqC,EAAO7C,KAAKQ,QACrBC,MAAOoC,EAAO7C,KAAKS,OAGrB,WAAAkB,CAAY8K,GACVzK,KAAKyK,MAAQA,CACf,CAEO5F,WAAcrG,IACnBwB,KAAKyK,MAAM5F,WAAWrG,IAGjBwG,WAAasG,UAClB,IACE,MAAMR,EAAa,CACjB1L,KAAM5E,EAAYC,IAClB6K,IAAKxE,GAAMQ,OAAOtB,KAAKqL,OAAO7M,UAGhC,aADuBwB,KAAKyK,MAAMhC,KAAiCqC,IACnDtM,OAClB,CAAE,MAAO4C,GACP,MAAMA,CACR,GAGKmK,cAAgBD,MAAOlG,EAAgC,MAC5D,GAA2B,KAAvBvE,EAAOpE,MAAMC,OAAyC,KAAzBmE,EAAOpE,MAAME,QAC5C,MAAM,IAAIkO,MAAM,6DAGlB,IACE,MAAMC,EAAa,CACjB1L,KAAM5E,EAAYE,KAClB4K,IAAKxE,GAAMQ,OAAOtB,KAAKqL,OAAO7M,SAC9BM,KAAMkB,KAAKwL,4BAA4BpG,IAEnCI,QAAiBxF,KAAKyK,MAAMhC,KAAiCqC,GAGnE,OAFA9K,KAAKyK,MAAM5F,WAAWW,EAAShH,SAC/BwB,KAAKyK,MAAM1F,iBAAiBS,EAAShH,QAAQsG,SACtCU,EAAShH,OAClB,CAAE,MAAO4C,GACP,MAAMA,CACR,GAGKqK,eAAiBH,UACtB,IACE,MAAMR,EAAa,CACjB1L,KAAM5E,EAAYK,OAClByK,IAAKxE,GAAMQ,OAAOtB,KAAKqL,OAAO7M,SAC9B6K,SAAUtO,EAAUE,YAEhB+E,KAAKyK,MAAMhC,KAAKqC,GACtB9K,KAAKyK,MAAM5F,WAAW,MACtB7E,KAAKyK,MAAM1F,iBAAiB,KAC9B,CAAE,MAAO3D,GACP,MAAMA,CACR,GAGK3C,MAAQ6M,MAAOlG,IACpB,IACE,MAAM0F,EAAa,CACjB1L,KAAM5E,EAAYE,KAClB4K,IAAKxE,GAAMQ,OAAOtB,KAAKqL,OAAO5M,OAC9BK,KAAMsG,IAEFsG,KAAEA,SAAe1L,KAAKyK,MAAMhC,KAA4BqC,GAE9D,OADA9K,KAAKyK,MAAM1F,iBAAiB2G,EAAKC,IAC1BD,CACT,CAAE,MAAOtK,GACP,MAAMA,CACR,GAGKwK,OAASN,UACd,MAAMR,EAAa,CACjB1L,KAAM5E,EAAYK,OAClByK,IAAKxE,GAAMQ,OAAOtB,KAAKqL,OAAO5M,OAC9B4K,SAAUtO,EAAUE,MAGtB,OADA+E,KAAKyK,MAAM1F,iBAAiB,MACrB/E,KAAKyK,MAAMhC,KAAKqC,IAGjB,2BAAAU,CAA4BpG,EAAgC,IAClE,MAAMyG,EAAuC,CAC3CC,eAAgBjL,EAAOpE,MAAMC,OAAS,GACtCqP,SAAUlL,EAAOpE,MAAME,SAAW,IAsBpC,MAnBI,UAAWyI,EACbyG,EAAQH,KAAOtG,EACN,UAAWA,GAAU,aAAcA,EAC5CyG,EAAQH,KAAO,CAAEjN,MAAO2G,EAAO3G,MAAOuN,SAAU5G,EAAO4G,UAC9C,UAAW5G,GAAU,aAAcA,EAC5CyG,EAAQH,KAAO,CAAEO,MAAO7G,EAAO6G,MAAOD,SAAU5G,EAAO4G,UAC9C,aAAc5G,IACvByG,EAAQK,SAAW9G,EAAO8G,SACtB,SAAU9G,IACZyG,EAAQzL,KAAOgF,EAAOhF,MAEpB,mBAAoBgF,IACtByG,EAAQM,eAAiB/G,EAAO+G,gBAE9B,mBAAoB/G,IACtByG,EAAQO,eAAiBhH,EAAOgH,iBAI7BP,CACT,iqBCvHF,MAAMQ,EAAiB,CACrB,IAAK,QACL,IAAK,OACL,IAAK,OACL,IAAK,SACL,IAAK,UAGP,SAASC,EAAiBC,GACxB,OAAOF,EAAeE,EACxB,CAEA,MAAMC,EAAmB,CACvB,QAAS,IACT,OAAQ,IACR,OAAQ,IACR,SAAU,IACV,SAAU,KAGZ,SAASC,EAAmBF,GAC1B,GAAiB,MAAbA,EAAM,GAAY,CACpB,MAAMG,EACS,MAAbH,EAAM,GACF3J,SAAS2J,EAAMI,MAAM,GAAI,IACzB/J,SAAS2J,EAAMI,MAAM,GAAI,IAG/B,GACU,IAARD,GACQ,KAARA,GACQ,KAARA,GACCA,GAAO,IAAQA,GAAO,OACtBA,GAAO,OAAUA,GAAO,OACxBA,GAAO,OAAWA,GAAO,QAE1B,OAAO7E,OAAO+E,cAAcF,GAE9B,MAAM,IAAI7B,MAAM,2BAA6B6B,EAAIrL,SAAS,IAC9D,CACE,GAAImL,EAAiBD,GACnB,OAAOC,EAAiBD,IAAUA,EAEpC,MAAM,IAAI1B,MAAM,sBAAwB0B,EAC1C,QAwCAM,GAAAC,UAtCA,SAAmBC,GACjB,OAAOA,EAAE3I,QAAQ,WAAYkI,EAC/B,EAqCAO,GAAAG,cATA,SAAuBD,GACrB,OAAOA,EAAE3I,QAAQ,SAAUkI,EAC7B,EAQAO,GAAAI,YApCA,SAAqBF,GACnB,IAAIG,EAAS,GACTC,GAAQ,EACRC,GAAM,EACNC,EAAW,EACf,MACyC,KAAtCF,EAAQJ,EAAEjH,QAAQ,IAAKuH,MACc,KAArCD,EAAML,EAAEjH,QAAQ,IAAKqH,EAAQ,KAE9BD,EACEA,EACAH,EAAEJ,MAAMU,EAAUF,GAClBV,EAAmBM,EAAEJ,MAAMQ,EAAOC,EAAM,IAC1CC,EAAWD,EAAM,EAKnB,OAAiB,IAAbC,EAAuBN,GAG3BG,GAAkBH,EAAEO,UAAUD,GAEvBH,EACT,EAaAL,GAAAU,gBAPA,SAAyBR,GACvB,OAAOA,EAAE3I,QAAQ,6BAA8BqI,EACjD,wCClFA,IAAIe,EAASC,KAQb,MAAMC,EACJ,WAAA/N,CAAYmH,EAAM6G,GAChB3N,KAAK8G,KAAOA,EACZ9G,KAAK4N,OAAS,KACd5N,KAAK6N,SAAW,GAChB7N,KAAK2N,MAAQ,CAAA,EACb3N,KAAK8N,SAASH,EAClB,CAOE,EAAAI,CAAGjH,EAAMkH,GACP,OAAOhO,KAAKiO,YAAcnH,KAAUkH,GAAShO,KAAKkO,UAAYF,EAClE,CAGE,OAAAC,GACE,MAAME,EAAMnO,KAAK8G,KAAKhB,QAAQ,KAC9B,OAAOqI,GAAO,EAAInO,KAAK8G,KAAK6F,MAAMwB,EAAM,GAAKnO,KAAK8G,IACtD,CAKE,KAAAoH,GACE,MAAMC,EAAMnO,KAAK8G,KAAKhB,QAAQ,KAC9B,GAAIqI,GAAO,EAAG,CACZ,MAAMjH,EAASlH,KAAK8G,KAAK6F,MAAM,EAAGwB,GAClC,OAAOnO,KAAKoO,OAAOlH,EACzB,CACI,OAAOlH,KAAKoO,QAChB,CAKE,MAAAA,CAAOlH,GACL,GAAKA,EAOE,CAEL,MAAMmH,EAAO,SAAWnH,EACxB,GAAIlH,KAAK2N,MAAMU,GACb,OAAOrO,KAAK2N,MAAMU,GACb,GAAIrO,KAAK4N,OACd,OAAO5N,KAAK4N,OAAOQ,OAAOlH,EAElC,KAfiB,CAEX,GAAIlH,KAAK2N,MAAMK,MACb,OAAOhO,KAAK2N,MAAMK,MACb,GAAIhO,KAAK4N,OACd,OAAO5N,KAAK4N,OAAOQ,QAE3B,CASA,CAKE,QAAAE,GACE,IAAIC,EAAa,CAAA,EAEbvO,KAAK4N,SACPW,EAAavO,KAAK4N,OAAOU,YAG3B,IAAK,MAAMD,KAAQrO,KAAK2N,MAAO,CAC7B,MAAMa,EAAIH,EAAK9B,MAAM,eAEjBvM,KAAK2N,MAAMnN,eAAe6N,IAASG,IACrCD,EAAWvO,KAAK2N,MAAMU,IAASG,EAAE,GAEzC,CACI,OAAOD,CACX,CAEE,QAAAT,CAASH,GACc,iBAAVA,EACT3N,KAAK2N,MAAMK,MAAQL,EACVA,GACTxN,OAAO6I,OAAOhJ,KAAK2N,MAAOA,EAEhC,CAKE,OAAAc,CAAQ3H,EAAMkH,GACZ,IAAKA,EACH,OAAOhO,KAAK2N,MAAM7G,GAGpB,MAAMyH,EAAavO,KAAKsO,WAExB,OAAKC,EAAWP,GAIThO,KAAK2N,MAAM,CAACY,EAAWP,GAAQlH,GAAMc,KAAK,MAHxC,IAIb,CAKE,QAAA8G,CAAS5H,EAAMkH,GACb,OAAOhO,KAAK2O,YAAY7H,EAAMkH,GAAO,EACzC,CAKE,WAAAW,CAAY7H,EAAMkH,GAChB,MAAMd,EAAS,GACf,IAAK,MAAM0B,KAAS5O,KAAK6N,UAErBe,EAAMX,SACNW,EAAMX,YAAcnH,GAClBkH,GAASY,EAAMV,UAAYF,GAE7Bd,EAAOhK,KAAK0L,GAGhB,OAAO1B,CACX,CAKE,cAAA2B,CAAeR,EAAMS,EAAKd,EAAOe,GAC/B,OAAO/O,KAAKgP,kBAAkBX,EAAMS,EAAKd,EAAOe,GAAW,EAC/D,CAKE,iBAAAC,CAAkBX,EAAMS,EAAKd,EAAOe,GAClC,IAAI7B,EAAS,GACb,IAAK,MAAM0B,KAAS5O,KAAK6N,UAErBe,EAAMjB,OACNiB,EAAMjB,MAAMU,KAAUS,GACpBd,GAASY,EAAMV,UAAYF,GAE7Bd,EAAOhK,KAAK0L,GAEVG,GAAaH,EAAMI,mBACrB9B,EAAOhK,KAAK0L,EAAMI,kBAAkBX,EAAMS,EAAKd,GAAO,IAM1D,OAHIe,IACF7B,EAASA,EAAO+B,QAEX/B,CACX,CAEE,mBAAAgC,CAAoBC,EAAQJ,GAC1B,IAAI7B,EAAS,GACb,IAAK,MAAM0B,KAAS5O,KAAK6N,SACnBsB,EAAOP,IACT1B,EAAOhK,KAAK0L,GAEVG,GAAaH,EAAMM,qBACrBhC,EAAOhK,KAAK0L,EAAMM,oBAAoBC,GAAQ,IAMlD,OAHIJ,IACF7B,EAASA,EAAO+B,QAEX/B,CACX,CAEE,OAAAkC,GACE,IAAI9F,EAAO,GACX,IAAK,MAAMsF,KAAS5O,KAAK6N,SACF,iBAAVe,GAAuC,iBAAVA,IACtCtF,GAAQsF,GAGZ,OAAOtF,CACX,CAEE,YAAA+F,CAAavI,EAAMkH,GACjB,MAAMY,EAAQ5O,KAAK0O,SAAS5H,EAAMkH,GAClC,OAAOY,EAAQA,EAAMQ,UAAY,IACrC,CAOE,gBAAAE,GACE,OAAOtP,KAAKkP,oBAAqBN,GACxBA,aAAiBlB,EAE9B,CAKE,IAAA6B,GACE,OAAIvP,KAAK4N,OACA5N,KAAK4N,OAAO2B,OAEdvP,IACX,CAGE,EAAAwP,GACE,OAAIxP,KAAK4N,OACA5N,KAAK4N,OAEP5N,IACX,CAGE,CAAA+H,CAAEjB,EAAM6G,GACN,OAAO3N,KAAKyP,MAAM,IAAI/B,EAAQ5G,EAAM6G,GACxC,CAEE,KAAA8B,CAAMb,GAKJ,OAJA5O,KAAK6N,SAAS3K,KAAK0L,GACE,iBAAVA,IACTA,EAAMhB,OAAS5N,MAEV4O,CACX,CAEE,MAAA/H,IAAU6I,GACR,IAAK,MAAMC,KAAQD,EACjB1P,KAAK6N,SAAS3K,KAAKyM,GACC,iBAATA,IACTA,EAAK/B,OAAS5N,KAGtB,CAEE,OAAA4P,IAAWF,GACT,IAAK,MAAMC,KAAQD,EACjB1P,KAAK6N,SAASgC,QAAQF,GACF,iBAATA,IACTA,EAAK/B,OAAS5N,KAGtB,CAGE,CAAA8P,CAAExG,GAEA,OADAtJ,KAAK6N,SAAS3K,KAAKoG,GACZtJ,IACX,CASE,MAAA+P,CAAOC,EAAIhC,GACT,MAAMmB,EACU,iBAAPa,EACFpB,KAEUA,EAAMb,IAAMa,EAAMb,GAAGiC,EAAIhC,IAEnCY,GAEQA,IAAUoB,EAKzB,OAFAhQ,KAAK6N,SAAW7N,KAAK6N,SAASsB,OAAOA,GAE9BnP,IACX,CAEE,IAAAsJ,CAAKwF,GACH,OAAIA,GAAgC,IAAzB9O,KAAK6N,SAAS7K,QACvBhD,KAAK6N,SAAS,GAAKiB,EACZ9O,MAEFA,KAAKoP,SAChB,CAEE,IAAAf,CAAKA,EAAMS,GACT,YAAmB,IAARA,GAA+B,OAARA,GAC3B9O,KAAK2N,QACR3N,KAAK2N,MAAQ,CAAA,GAEf3N,KAAK2N,MAAMU,GAAQS,EACZ9O,MAEFA,KAAK2N,MAAMU,EACtB,CAIE,QAAAhN,GACE,IAAI0L,EAAI,GAIR,OAHA/M,KAAKiQ,MAAOlI,IACVgF,GAAKhF,IAEAgF,CACX,CAEE,YAAAmD,CAAaC,GACXA,EAAO,KACP,IAAK,MAAMvB,KAAS5O,KAAK6N,SAEV,MAATe,IACEA,EAAMqB,MACRrB,EAAMqB,MAAME,GACc,iBAAVvB,EAChBuB,EAAO3C,EAAOR,cAAc4B,IACnBA,EAAMvN,UACf8O,EAAO3C,EAAOR,cAAc4B,EAAMvN,SAAS,OAIjD8O,EAAO,MACPA,EAAOnQ,KAAK8G,MACZqJ,EAAO,IACX,CAEE,KAAAF,CAAME,GACJA,EAAO,KACPA,EAAOnQ,KAAK8G,MACZ,IAAK,MAAMsJ,KAAKpQ,KAAK2N,MAAO,CAC1B,MAAM0C,EAAIrQ,KAAK2N,MAAMyC,GAEZ,MAALC,IACFF,EAAO,KACPA,EAAOC,GACPD,EAAO,MACPA,EAAO3C,EAAOV,UAAuB,iBAANuD,EAAiBA,EAAIA,EAAEhP,SAAS,MAC/D8O,EAAO,KAEf,CACiC,IAAzBnQ,KAAK6N,SAAS7K,OAChBmN,EAAO,MAEPnQ,KAAKkQ,aAAaC,EAExB,SAGAzC,EAAQnN,UAAU+P,KAAO5C,EAAQnN,UAAUgP,KAE3CgB,GAAiB7C,qECtWjB,IAAIA,EAAUD,KAEd,SAAS5G,EAAOmJ,EAAIpB,GAClB,GAAI9M,MAAMF,QAAQgN,GAChB,IAAK,MAAM7G,KAAK6G,EAAO/H,EAAOmJ,EAAIjI,OAItB,KAAV6G,GAAyB,MAATA,IAA2B,IAAVA,IAA4B,IAAVA,GAIvDoB,EAAGP,MAAMb,EACX,QAkCA4B,GAxBA,SAAuB1J,EAAM6G,KAAUE,GACrC,GAAqB,iBAAVF,GAAgC,OAAVA,EAAgB,QAKxCA,EAAM8C,gBACN9C,EAAM+C,OAEb,IAAK,MAAOpQ,EAAKyG,KAAU5G,OAAOwQ,QAAQhD,GAC3B,MAAT5G,SAAsB4G,EAAMrN,GAC3BqN,EAAMrN,GAAOyG,EAAM1F,SAAS,GAEvC,CAEE,MAAM2O,EAAK,IAAItC,EAAQ5G,EAAM6G,GAE7B,IAAK,MAAMiB,KAASf,EAClBhH,EAAOmJ,EAAIpB,GAGb,OAAOoB,CACT,8DC7CA,IAAInR,EAAS4O,EAAAA,QACTD,EAASoD,KAcb,MAAMC,UAAehS,EAAOiS,aAC1B,WAAAnR,GACEoR,QACA,IACIC,EACAC,EACAC,EACAvD,EACAwD,EACAC,EACAC,EACAC,EAEAC,EAVAC,EAfW,EAwBXC,EAAc,EAGlBzR,KAAK0R,kBAAoB,SACvBP,EACAD,EACAvD,GAEKwD,EAMHnR,KAAK2R,KAAK,aAAcT,GAAS,IALjClR,KAAK2R,KAAK,eAAgBT,EAASvD,GAC/ByD,GACFpR,KAAK2R,KAAK,aAAcT,GAAS,GAK3C,EAEIlR,KAAKiQ,MAAQ,SAAenR,GACN,iBAATA,IACTA,EAAOA,EAAKuC,YAEd,IAAIuQ,EAAM,EAUV,SAASC,IACP,GAA2B,iBAAhBJ,EAA0B,CACnC,MAAMK,EAAWhT,EAAK6N,MAAM8E,EAAaG,GAEzC,OADAH,OAAc/V,EACPoW,CACjB,CACA,CAEM,IAfId,IACFlS,EAAOkS,EAAYlS,EACnB8S,GAAQX,EAAoC,EAAnBD,EAAUhO,OACnCiO,GAAiB,EACjBD,EAAY,MAWPY,EAAM9S,EAAKkE,OAAQ4O,IAAO,CAC/B,OAAQJ,GACN,KAlES,EAkEQ,CAGf,MAAMO,EAAKjT,EAAKgH,QAAQ,IAAK8L,IAClB,IAAPG,GAAaH,IAAQG,IACvBH,EAAMG,GAGR,KACZ,CACU,KApEe,EAoEQ,CAGrB,MAAMC,EAAOlT,EAAKgH,QAAQwL,EAAeM,IAC5B,IAATI,IACFJ,EAAMI,GAGR,KACZ,CACU,KArFmB,EAqFQ,CAGzB,MAAMC,EAAanT,EAAKgH,QAAQ,SAAO8L,IACpB,IAAfK,IACFL,EAAMK,EAAa,GAGrB,KACZ,CACU,KAtFiB,GAsFQ,CAGvB,MAAMC,EAAWpT,EAAKgH,QAAQ,MAAO8L,IACpB,IAAbM,IACFN,EAAMM,EAAW,GAGnB,KACZ,EAIQ,MAAMnK,EAAIjJ,EAAKkJ,WAAW4J,GAC1B,OAAQJ,GACN,KA/GS,EAgHP,GAAU,KAANzJ,EAAkB,CACpB,MAAMuB,EAAOuI,IACTvI,GACFtJ,KAAK2R,KAAK,OAAQnE,EAAOP,YAAY3D,IAEvCkI,EAlHS,EAmHTC,EAAcG,EAAM,EACpBjE,EAAQ,CAAA,CACtB,CACY,MACF,KAjHU,EAkHR,GAAU,KAAN5F,EACF,GAAgC,OAA5BjJ,EAAKqT,OAAOP,EAAM,EAAG,GAAa,CACpC,MAAMQ,EAAQP,IACVO,GACFpS,KAAK2R,KAAK,OAAQS,GAEpBZ,EAjIG,CAkInB,MAAyB1S,EAAKkE,OAAS4O,EAAM,IAC7BX,GAAiB,EACjBW,EAAM9S,EAAKkE,QAGf,MACF,KArIa,EAsID,KAAN+E,GAAoB0J,IAAgBG,GACtCH,EAAcG,EAAM,EACpBT,GAAS,GACM,KAANpJ,EACuB,YAA5BjJ,EAAKqT,OAAOP,EAAM,EAAG,IACvBH,EAAcG,EAAM,EACpBJ,EAtII,GAwIJ1S,EAAKkE,OAAS4O,EAAM,GACpB,UAAUS,WAAWvT,EAAK6N,MAAMiF,EAAM,KAGtCX,GAAiB,EACjBW,EAAM9S,EAAKkE,SAEXyO,OAAc/V,EACd8V,EAxJa,GA0JA,KAANzJ,GACT0J,OAAc/V,EACd8V,EA3JmB,IA4JVzJ,GAAK,IAAY,KAANA,GAA0B,KAANA,KACxCmJ,EAAUW,IACVD,IACAJ,EA7JI,GA+JN,MACF,KAnKmB,EAoKjB,GAAU,KAANzJ,EAAkB,CACpB,MAAMuK,EAAYxT,EAAKkJ,WAAW4J,EAAM,GAClCW,EAAazT,EAAKkJ,WAAW4J,EAAM,IAExB,KAAdU,GAA2C,KAAfC,GACd,KAAdD,GAA2C,KAAfC,KAE7Bf,EA5KG,EA8KnB,CACY,MACF,KA9KuB,EA+KrB,GAAU,KAANzJ,EAAkB,CAEP,KADAjJ,EAAKkJ,WAAW4J,EAAM,KAEjCJ,EApLG,EAsLnB,CACY,MACF,KApLQ,EAqLI,KAANzJ,GACF/H,KAAK0R,kBAAkBP,EAAQD,EAASvD,GACxCuD,OAAUxV,EACViS,OAAQjS,EACRyV,OAASzV,EACT0V,OAAc1V,EACd8V,EA/LK,EAgMLC,EAAcG,EAAM,GACL,KAAN7J,EACTqJ,GAAc,EACLrJ,EAAI,KACb0J,EAAcG,EACdJ,EAhMU,GAkMZ,MACF,KAnMc,GAoMRzJ,GAAK,IAAY,KAANA,KACbwJ,EAAWM,IACXD,IACAJ,EAtMQ,GAwMV,MACF,KAzMY,EA0MA,KAANzJ,IACFyJ,EA1MU,GA4MZ,MACF,KA7Mc,EA8MF,KAANzJ,GAA0B,KAANA,IACtBsJ,EAAYtJ,EACZuJ,EAAsB,KAANvJ,EAAW,IAAM,IACjCyJ,EAhNW,EAiNXC,EAAcG,EAAM,GAEtB,MACF,KApNe,EAqNb,GAAI7J,IAAMsJ,EAAW,CACnB,MAAMtK,EAAQyG,EAAOP,YAAY4E,KACjClE,EAAM4D,GAAYxK,EAClBwK,OAAW7V,EACX8V,EA7NI,CA8NlB,EAGA,CAEiC,iBAAhBC,GAA4BA,GAAe3S,EAAKkE,SACzDgO,EAAYlS,EAAK6N,MAAM8E,GACvBA,EAAc,EAEtB,CACA,CAEE,GAAArE,CAAItO,GACEA,GACFkB,KAAKiQ,MAAMnR,GAIbkB,KAAKiQ,MAAQ,WAAiB,CAClC,SAGAuC,GAAiB3B,eC7PF,MAAM4B,WAAqB5H,MACxC,WAAAlL,CAAYkM,GACVkF,MAAMlF,GACN7L,KAAK8G,KAAO,cACd,ECDa,SAASrH,GAAQiT,EAASC,GACvC,MAAMC,ECJO,SAAeD,GAC5B,IAAIlT,EACJ,MAAMiT,EAAU,IAAIhK,QAASC,IAC3BlJ,EAAUoT,WAAWlK,EAASgK,KAGhC,OADAD,EAAQjT,QAAUA,EACXiT,CACT,CDHuBI,CAAMH,GAM3B,MAAMvR,EAAQ,IAAIqR,GAClB,OAAO/J,QAAQqK,KAAK,CAClBL,EAAQM,QANV,WACEC,aAAaL,EAAanT,QAC5B,GAKEmT,EAAazJ,KAAK,KAChB,MAAM/H,KAGZ,CEjBA,MAAM8R,GAAM,IAAIC,QAED,SAASC,GAAMC,GAC5B,IAAI7E,EAAI0E,GAAIlI,IAAIqI,GAEhB,IAAK7E,EAAG,CAUNA,EAAI,CAAEnP,IATMgU,EAAOC,kBAAoBD,EAAOE,aAAaC,KAAKH,GAStDI,KARGJ,EAAOK,qBAAuBL,EAAOM,gBAAgBH,KAChEH,GAOaO,MAJbP,EAAOO,MACb,EAAQC,EAAOC,IACPT,EAAOC,iBAAiBO,EAAOC,EAAS,CAAEF,MAAM,MAClDJ,KAAKH,IAEPH,GAAIpT,IAAIuT,EAAQ7E,EAClB,CAEA,OAAOA,CACT,CCjBe,SAASkE,GAAQW,EAAQQ,EAAOE,EAAc,QAAStU,GACpE,OAAO,IAAIiJ,QAAQ,CAACC,EAASC,KAC3B,IAAIoL,EAEJ,MAAMP,IAAEA,EAAGG,KAAEA,GAASR,GAAMC,GAEtBY,EAAU,KACdhB,aAAae,GACbP,EAAII,EAAOK,GACXT,EAAIM,EAAaI,IAGnB,SAASA,EAAQC,GACfxL,EAAOwL,GACPH,GACF,CAEA,SAASC,EAAQnN,GACf4B,EAAQ5B,GACRkN,GACF,CAOA,GALAL,EAAKC,EAAOK,GACRH,GACFH,EAAKG,EAAaI,GAGhB1U,EAAS,CACX,MAAM2B,EAAQ,IAAIqR,GAClBuB,EAAYnB,WAAW,KACrBoB,IACArL,EAAOxH,IACN3B,EACL,GAEJ,CCtCe,SAAS4U,KACtBrU,KAAK0S,QAAU,IAAIhK,QAAQ,CAACC,EAASC,KACnC5I,KAAK2I,QAAUA,EACf3I,KAAK4I,OAASA,GAElB,CCLe,SAAS0L,GAAUC,EAAQC,EAAS,KAAMV,GACvD,OAAO,IAAIpL,QAAQ,CAACC,EAASC,KAC3B,SAASuL,EAAQjT,GACfqT,EAAOZ,eAAe,QAASc,GAC/B7L,EAAO1H,EACT,CAEA,SAASwT,KAAQzT,GACfsT,EAAOZ,eAAe,QAASc,GAC/B9L,KAAW1H,EACb,CAEAqK,eAAemJ,EAASE,GACtB,UACQb,EAAQa,EAASD,EACzB,CAAE,MAAOxT,GACPiT,EAAQjT,EACV,CACF,CAEAsT,GAAUD,EAAOK,KAAKJ,GAAQ9K,MAAMyK,GACpCI,EAAOlV,GAAG,QAASoV,IAEvB,CCrBe,SAASI,GAAUhW,GAChC,MAAO,CACL,SAAAiW,CAAUzB,GACR,MAAMhU,GAAEA,GAAO+T,GAAMC,GACrB,IAAK,MAAOQ,EAAOC,KAAY3T,OAAOwQ,QAAQ9R,GAC5CQ,EAAGwU,EAAOC,EAEd,EACA,WAAAiB,CAAY1B,GACV,MAAMI,IAAEA,GAAQL,GAAMC,GACtB,IAAK,MAAOQ,EAAOC,KAAY3T,OAAOwQ,QAAQ9R,GAC5C4U,EAAII,EAAOC,EAEf,EAEJ,CCjBe,MAAMkB,WAAiBnK,MACpC,WAAAlL,IAAesB,GACb8P,SAAS9P,GACTjB,KAAK8G,KAAO,UACd,ECEF,MAAMmO,WAAenE,EAAAA,aACnB,WAAAnR,GACEoR,QACA,MAAMmE,EAAS,IAAIC,GACnBnV,KAAKuP,KAAO,KACZvP,KAAKoV,OAAS,KAEdF,EAAO7V,GAAG,eAAgBW,KAAKqV,eAAe7B,KAAKxT,OACnDkV,EAAO7V,GAAG,aAAcW,KAAKsV,aAAa9B,KAAKxT,OAC/CkV,EAAO7V,GAAG,OAAQW,KAAKuV,OAAO/B,KAAKxT,OAEnCA,KAAKkV,OAASA,CAChB,CAEA,cAAAG,CAAevO,EAAM6G,GACnB,MAAMgH,EAAU,IAAIjH,GAAQ5G,EAAM6G,IAE5B4B,KAAEA,EAAI6F,OAAEA,GAAWpV,KAEpBuP,EAGM6F,IAAW7F,GACpB6F,EAAOvO,OAAO8N,IAHd3U,KAAKuP,KAAOoF,EACZ3U,KAAK2R,KAAK,QAASgD,IAKrB3U,KAAKoV,OAAST,CAChB,CAEA,YAAAW,CAAaxO,GACX,MAAMyI,KAAEA,EAAI6F,OAAEA,GAAWpV,KACzB,GAAI8G,IAASsO,EAAOtO,KAApB,CAMA,GAAIsO,IAAW7F,EAKf,OAAK6F,EAAOxH,YAOZ5N,KAAKoV,OAASA,EAAOxH,SANnBwH,EAAOxH,OAAS2B,EAChBvP,KAAK2R,KAAK,UAAWyD,QACrBpV,KAAKoV,OAAS7F,IAPdvP,KAAK2R,KAAK,MAAOpC,EAHnB,MAFEvP,KAAK2R,KAAK,QAAS,IAAIqD,GAAS,GAAGI,EAAOtO,wBAiB9C,CAEA,MAAAyO,CAAOhS,GACL,MAAM6R,OAAEA,GAAWpV,KACdoV,EAKLA,EAAOtF,EAAEvM,GAJPvD,KAAK2R,KAAK,QAAS,IAAIqD,GAAS,GAAGzR,sBAKvC,CAEA,KAAA0M,CAAMnR,GACJkB,KAAKkV,OAAOjF,MAAMnR,EACpB,CAEA,GAAAsO,CAAItO,GACEA,GACFkB,KAAKkV,OAAOjF,MAAMnR,EAEtB,EChEa,SAAS0W,MAAOvU,GAC7B,OAAOwU,MAAiBxU,EAC1B,CCdO,SAASyU,GAAOC,GACrB,IAAKA,EACH,OAAO,EAkBT,OAAe,IAdHA,EACTC,WAAW/N,OAAOgO,GAAG,MAAO,IAC5BD,WAAW/N,OAAOgO,GAAG,MAAO,IAC5BD,WAAW/N,OAAOgO,GAAG,MAAO,IAC5BD,WAAW/N,OAAOgO,GAAG,MAAO,IAC5BD,WAAW/N,OAAOgO,GAAG,MAAO,IAC5BD,WAAW/N,OAAOgO,GAAG,MAAO,IAC5BD,WAAW/N,OAAOgO,GAAG,MAAO,IAC5BD,WAAW/N,OAAOgO,GAAG,MAAO,IAC5BD,WAAW/N,OAAOgO,GAAG,MAAO,IAC5BD,WAAW/N,OAAOgO,GAAG,MAAO,IAGZC,OAAO,iBAM5B,CASO,SAAStI,GAAOmI,GACrB,OAAc,OAAVA,EACK,KAGFA,EACJC,WAAW,aAAc,IACzBA,WAAW,KAAM/N,OAAOgO,GAAG,OAC3BD,WAAW,IAAK/N,OAAOgO,GAAG,OAC1BD,WAAW,IAAK/N,OAAOgO,GAAG,OAC1BD,WAAW,IAAK/N,OAAOgO,GAAG,OAC1BD,WAAW,IAAK/N,OAAOgO,GAAG,OAC1BD,WAAW,IAAK/N,OAAOgO,GAAG,OAC1BD,WAAW,IAAK/N,OAAOgO,GAAG,OAC1BD,WAAW,IAAK/N,OAAOgO,GAAG,OAC1BD,WAAW,IAAK/N,OAAOgO,GAAG,OAC1BD,WAAW,IAAK/N,OAAOgO,GAAG,MAC/B,CASO,SAASE,GAASJ,GACvB,OAAc,OAAVA,EACK,KAGFA,EACJC,WAAW/N,OAAOgO,GAAG,MAAO,KAC5BD,WAAW/N,OAAOgO,GAAG,MAAO,KAC5BD,WAAW/N,OAAOgO,GAAG,MAAO,KAC5BD,WAAW/N,OAAOgO,GAAG,MAAO,KAC5BD,WAAW/N,OAAOgO,GAAG,MAAO,KAC5BD,WAAW/N,OAAOgO,GAAG,MAAO,KAC5BD,WAAW/N,OAAOgO,GAAG,MAAO,KAC5BD,WAAW/N,OAAOgO,GAAG,MAAO,KAC5BD,WAAW/N,OAAOgO,GAAG,MAAO,KAC5BD,WAAW/N,OAAOgO,GAAG,MAAO,KACjC,CFGAZ,GAAOD,SAAWA,GC/DlB7U,OAAO6I,OAAOwM,GAAK,CACjB9H,WACA+H,iBACAR,UACFnI,UAAEA,GAAAA,UACFG,YAAEA,GAAAA,YACFD,cAAEA,GAAAA,cACFO,gBAAEA,GAAAA,gBACAyH,YACAQ,SEfF,MAAMQ,GACJ,WAAArW,CAAYgW,EAAOM,EAAQvU,GACzB,GAAsB,iBAAXuU,IAAwBA,EACjC,MAAM,IAAIC,UAAU,mBAGtBlW,KAAKmW,UAAUF,GACfjW,KAAKoW,SAA0B,iBAAVT,EAAqBA,EAAQ,IAClD3V,KAAKqW,YAAgC,iBAAb3U,EAAwBA,EAAW,GAC7D,CAEA,CAAC4U,OAAOC,aAAaC,GACnB,MAAa,WAATA,EACKC,OAAOC,IAGT1W,KAAKqB,UACd,CAEA,QAAAA,CAAS0U,GACP,IAAIhJ,EAAI/M,KAAK2W,QASb,OARI3W,KAAK4W,SACP7J,EAAI/M,KAAK6W,SAASd,GAAY,IAAMhJ,GAGlC/M,KAAK8W,YACP/J,EAAIA,EAAI,IAAM/M,KAAK8W,WAGd/J,CACT,CAKA,IAAAgK,GACE,OAAI/W,KAAK8W,UACA,IAAId,GAAIhW,KAAK4W,OAAQ5W,KAAK2W,QAAS,MAGrC3W,IACT,CAKA,MAAAgX,CAAOC,GACL,OACEjX,KAAK4W,SAAWK,EAAML,QACtB5W,KAAK2W,UAAYM,EAAMN,SACvB3W,KAAK8W,YAAcG,EAAMH,SAE7B,CAKA,QAAAV,CAAST,EAAOnI,GAQd,OAPAA,EAASA,GAAU0J,GAAgBvB,MAGjCA,EAAQwB,GAAgBxB,IAG1B3V,KAAK4W,OAASjB,GAASA,EAAMyB,cACtBpX,IACT,CAEA,QAAA6W,CAASd,GAAW,GAClB,IAAIJ,EAAQ,KAIZ,OAFAA,EAAQI,EAAWsB,GAAkBrX,KAAK4W,QAAU5W,KAAK4W,OAElDjB,CACT,CAKA,SAAAQ,CAAUF,GAER,OADAjW,KAAK2W,QAAUV,EAAOmB,cACfpX,IACT,CAEA,SAAAsX,GACE,OAAOtX,KAAK2W,OACd,CAKA,WAAAN,CAAY3U,GAEV,OADA1B,KAAK8W,UAAYpV,EACV1B,IACT,CAEA,WAAAuX,GACE,OAAOvX,KAAK8W,SACd,EC1Ga,SAASzS,GAAM0I,GAC5B,IAAI4I,EACAjU,EAEJ,MAAM8V,EAAgBzK,EAAEjH,QAAQ,MACV,IAAlB0R,IACF9V,EAAWqL,EAAEJ,MAAM6K,EAAgB,GACnCzK,EAAIA,EAAEJ,MAAM,EAAG6K,IAGjB,MAAMC,EAAU1K,EAAEjH,QAAQ,KAM1B,OALgB,IAAZ2R,IACF9B,EAAQ5I,EAAEJ,MAAM,EAAG8K,GACnB1K,EAAIA,EAAEJ,MAAM8K,EAAU,IAGjB,IAAIzB,GAAIL,EAAO5I,EAAGrL,EAC3B,CCXA,SAASgW,MAAOzW,GACd,OAAKA,EAAK,IAAOA,EAAK,GAIf,IAAI+U,MAAO/U,GAHToD,MAASpD,EAIpB,CFiGAd,OAAOwX,eAAe3B,GAAIzV,UAAW,QAAS,CAC5CyK,IAAKgL,GAAIzV,UAAUsW,SACnB/W,IAAKkW,GAAIzV,UAAU6V,WAGrBjW,OAAOwX,eAAe3B,GAAIzV,UAAW,SAAU,CAC7CyK,IAAKgL,GAAIzV,UAAU+W,UACnBxX,IAAKkW,GAAIzV,UAAU4V,YAGrBhW,OAAOwX,eAAe3B,GAAIzV,UAAW,WAAY,CAC/CyK,IAAKgL,GAAIzV,UAAUgX,YACnBzX,IAAKkW,GAAIzV,UAAU8V,cE3GrB,MAAMuB,GAAIF,GAAIlE,OACdoE,GAAEF,IAAMA,GACRE,GAAE5B,IAAMA,GACR4B,GAAEvT,MAAQA,GACVuT,GAAEC,MAhBK,SAAeC,EAAGnU,GACvB,OAAOmU,EAAEd,OAAOrT,EAClB,EAeAiU,GAAEG,aAAerC,GACjBkC,GAAEI,YAAcxK,GAChBoK,GAAEK,cAAgBlC,GCrBlB,MAAMmC,WAAkBrN,MACtB,WAAAlL,CAAYwY,EAAW7O,EAAM8O,GAC3BrH,MAAMoH,GAAa7O,EAAO,MAAMA,IAAS,KACzCtJ,KAAK8G,KAAO,YACZ9G,KAAKmY,UAAYA,EACjBnY,KAAKsJ,KAAOA,EACZtJ,KAAKoY,YAAcA,CACrB,CAEA,kBAAOC,CAAY1D,GACjB,MAAOwD,EAAWG,EAAQC,GAAS5D,EAAQrF,mBAC3C,IAAIhG,EACA8O,EAEAE,IACEA,EAAOvK,GAAG,QACZzE,EAAOgP,EACEA,IACTF,EAAcE,GAGZC,IAAOH,EAAcG,IAG3B,MAAMnX,EAAQ,IAAIpB,KAChBmY,EAAUrR,KACVwC,EAAOA,EAAKA,OAAS,GACrB8O,GAGF,OADAhX,EAAMuT,QAAUA,EACTvT,CACT,EC7BF,MAAMoX,WAAoBN,GACxB,WAAAvY,IAAesB,GACb8P,SAAS9P,GACTjB,KAAK8G,KAAO,aACd,ECRF,SAAS2R,GAASC,GAChB,IAAIC,KAAEA,EAAIC,SAAEA,EAAQC,SAAEA,GAAa,IAAIC,IAAIJ,GAM3C,MAJiB,UAAbE,IACFA,EAAW,OAGN,CAAED,OAAMC,WAAUC,WAC3B,CAEA,SAASE,GAAUC,GACjB,MAAML,KAAEA,EAAIC,SAAEA,GAAaH,GAAS,UAAUO,KAC9C,MAAO,CAAEL,OAAMC,WACjB,CCHA,MAAMK,WAAmBnI,EAAAA,aACvBoI,GAAmB,KACnBC,GAAmB,KAEnB,WAAAxZ,CAAYI,EAAU,IACpBgR,QAEuB,iBAAZhR,IACTA,EAAU,CAAEkW,OAAQlW,IAGtBC,KAAK0X,IAAM,KACX1X,KAAKP,QAAUM,EAAQN,SAAW,IAClCO,KAAKD,QAAUA,EACfC,KAAKgK,OAAS,UACdhK,KAAKoZ,OAAS,KACdpZ,KAAKkV,OAAS,KACdlV,KAAKuP,KAAO,IACd,CAEA,QAAA8J,GACE,OAA+B,IAAxBrZ,KAAKoZ,QAAQE,MACtB,CAEA,kBAAMC,CAAapB,EAAWtK,GAC5B,UACQ7N,KAAK4U,KAETY,GAAI,eAAgB,GAAI,CACtBA,GAAI2C,EAAW,CAACnK,MAhCR,uCAgC2BH,KAGzC,CAAE,MAAO,CAET,OAAO7N,KAAKwZ,YACd,CAEA,OAAAC,CAAQ3a,GACN,MAAMyE,EAAMzE,EAAKuC,SAAS,QAC1BrB,KAAKkV,OAAOjF,MAAM1M,EACpB,CAEA,EAAAmW,CAAetY,GAKbpB,KAAKuZ,aAAa,cAClBvZ,KAAK2Z,gBACL3Z,KAAK2R,KAAK,QAASvQ,EACrB,CAEA,EAAAwY,CAAgBC,EAAOzF,GACrBpU,KAAK8Z,gBACL9Z,KAAK+Z,QAAQ,aAAc,CAAEC,OAAQH,EAAOzF,UAC9C,CAEA,EAAA6F,CAAgBJ,EAAOzF,GACrBpU,KAAK2Z,gBACL3Z,KAAK+Z,QAAQ,QAAS,CAAEC,OAAQH,EAAOzF,UACzC,CAEA,aAAA8F,CAAcd,GACZpZ,KAAKoZ,OAASA,EACdpZ,MAAKkZ,IAAqBrE,GAAU,CAClC/V,KAAMkB,KAAKyZ,QAAQjG,KAAKxT,MACxBma,MAAOna,MAAK4Z,EAAgBpG,KAAKxT,MACjCoa,QAAS,IAAMpa,KAAK+Z,QAAQ,WAC5B3Y,MAAQA,GAAUpB,KAAK2R,KAAK,QAASvQ,KAEvCpB,MAAKkZ,EAAiBpE,UAAU9U,KAAKoZ,OACvC,CAEA,aAAAU,GACE9Z,KAAKoZ,QAAUpZ,MAAKkZ,GAAkBnE,YAAY/U,KAAKoZ,QACvDpZ,KAAKoZ,OAAS,IAChB,CAEA,UAAAiB,CAAW1F,GACT,MAAM2F,EAAgB3F,EAAQ5G,GAAG,QAjFZ,oCAmFjBuM,GACFta,KAAKua,eAAe5F,GAGtB3U,KAAK2R,KAAK,UAAWgD,GACrB3U,KAAK2R,KAAK3R,KAAKwa,SAAS7F,GAAW,SAAW,QAASA,GAEnD2F,GAGFta,KAAKwZ,YAET,CAGA,cAAAe,CAAe5F,GACb,MAAMvT,EAAQoX,GAAYH,YAAY1D,GAEtC,GAAwB,mBAApBvT,EAAM+W,UACR,OAAOnY,KAAKya,gBAAgBrZ,GAG9BpB,KAAK2R,KAAK,QAASvQ,EACrB,CAGA,qBAAMqZ,CAAgBrZ,GACpB,MAAMyX,SAAEA,GDvGZ,SAAsB6B,GACpB,OAAOA,EAAQC,SAAS,OAASlC,GAASiC,GAAW3B,GAAU2B,EACjE,CCqGyBE,CAAa5a,KAAKD,QAAQ2a,SAEzC1B,EAAO5X,EAAMuT,QAAQtF,aAAa,mBAClCsJ,KAAEA,GAASI,GAAUC,GAE3B,IAAI0B,EACJA,EAAU/B,EACN,GAAGE,GAAY,YAAYG,KAC1BH,EAAW,GAAGA,MAAe,IAAMG,EAExC,UACQtG,GAAQ1S,KAAM,cACpB,MAAMiW,OAAEA,EAAM4E,KAAEA,GAAS7a,KAAKD,cACxBC,KAAKoa,QAAQM,SACb1a,KAAK8a,KAAK,CAAE7E,SAAQ4E,QAC5B,CAAE,MAAO3Z,GACPlB,KAAK2R,KAAK,QAASzQ,EACrB,CACF,CAEA,aAAA6Z,CAAc7F,GACZlV,KAAKkV,OAASA,EACdlV,MAAKmZ,IAAqBtE,GAAU,CAClCF,QAAS3U,KAAKqa,WAAW7G,KAAKxT,MAC9BoB,MAAOpB,MAAK0Z,EAAelG,KAAKxT,MAChCoN,IAAKpN,MAAKia,EAAgBzG,KAAKxT,MAC/BmN,MAAQwH,GAAY3U,KAAK+Z,QAAQ,OAAQpF,KAE3C3U,MAAKmZ,EAAiBrE,UAAU9U,KAAKkV,OACvC,CAEA,aAAAyE,GACE3Z,KAAKkV,QAAUlV,MAAKmZ,GAAkBpE,YAAY/U,KAAKkV,QACvDlV,KAAKkV,OAAS,KACdlV,KAAKuP,KAAO,IACd,CAEA,IAAAyL,CAAKrP,GAEH,OADA3L,KAAK0X,IAAMA,GAAI/L,GACR3L,KAAK0X,GACd,CAkBA,OAAAqC,CAAQ/P,KAAW/I,GACbjB,KAAKgK,SAAWA,IACpBhK,KAAKgK,OAASA,EACdhK,KAAK2R,KAAK,SAAU3H,KAAW/I,GAC/BjB,KAAK2R,KAAK3H,KAAW/I,GACvB,CAEA,MAAAga,CAAOC,GAAU,GACXA,EACFlb,KAAKgK,OAAS,SAEdhK,KAAK+Z,QAAQ,SAAU/Z,KAAK0X,IAEhC,CAEA,gBAAM8B,GACJ,IAAIxJ,EAEJ,IACEA,QAAWhQ,KAAKmb,cAClB,CAAE,MAAOja,GACPlB,MAAKia,EAAgB/Y,EACvB,CAEA,UACQlB,KAAKob,cACb,CAAE,MAAOla,GACPlB,MAAK4Z,GAAgB,EAAM1Y,EAC7B,CAEA,OAAO8O,CACT,CAKA,WAAM7C,GACJ,GAAoB,YAAhBnN,KAAKgK,OACP,MAAM,IAAIa,MAAM,6BAGlB,MAAM6P,QAAEA,EAAOzE,OAAEA,EAAM4E,KAAEA,GAAS7a,KAAKD,cAEjCC,KAAKoa,QAAQM,GAEnB,MAAMW,EAAgB3I,GAAQ1S,KAAM,UAIpC,aAFMA,KAAK8a,KAAK,CAAE7E,SAAQ4E,SAEnBQ,CACT,CAKA,aAAMjB,CAAQM,GACZ1a,KAAK+Z,QAAQ,aAAcW,GAC3B,MAAMtB,EAAS,IAAIpZ,KAAKsb,OAIxB,OAHAtb,KAAKka,cAAcd,GAEnBA,EAAOgB,QAAQpa,KAAKub,iBAAiBb,IAC9BhI,GAAQ0G,EAAQ,UACzB,CAOA,kBAAMgC,CAAa3b,EAAUO,KAAKP,SAChCO,KAAK+Z,QAAQ,iBACb/Z,KAAKoZ,OAAOhM,YAGNsF,GAAQ1S,KAAKoZ,OAAQ,QAAS,QAAS3Z,EAC/C,CAKA,UAAMqb,CAAK/a,GACTC,KAAK+Z,QAAQ,WAEb,MAAM9D,OAAEA,EAAM4E,KAAEA,GAAS9a,EAEnByb,EAAgBxb,KAAKwb,gBAQ3B,OAPAA,EAAc7N,MAAM8N,GAAKxF,EACzBuF,EAAc7N,MAAM,YAAckN,EAClC7a,KAAKuP,KAAOiM,EAEZxb,KAAK+a,cAAc,IAAI/a,KAAKiV,cAEtBjV,KAAKiQ,MAAMjQ,KAAK0b,OAAOF,IACtB9I,GAAQ1S,KAAM,OAAQ,QAASA,KAAKP,QAC7C,CAOA,UAAMkc,GACJ,MAAM3L,QAAWhQ,KAAKwZ,aAEtB,OADAxZ,KAAK+Z,QAAQ,UAAW/J,GACjBA,CACT,CAOA,kBAAMmL,CAAa1b,EAAUO,KAAKP,eAC1BO,MAAK4b,EAAU,SAErB,MAAMC,EAAW7b,KAAK8b,OAAO9b,KAAK+b,iBAIlC,aAFM/b,KAAKiQ,MAAM4L,GACjB7b,KAAK+Z,QAAQ,WACNrH,GAAQ1S,KAAKkV,OAAQ,MAAO,QAASzV,EAE9C,CAMA,aAAMuc,GACJhc,KAAK2Z,gBACL,MAAM1D,OAAEA,EAAM4E,KAAEA,GAAS7a,KAAKD,QAC9B,OAAOC,KAAK8a,KAAK,CAAE7E,SAAQ4E,QAC7B,CAEA,UAAMjG,CAAKD,GACTA,EAAQ/G,OAAS5N,KAAKuP,WAChBvP,KAAKiQ,MAAM0E,EAAQtT,YACzBrB,KAAK2R,KAAK,OAAQgD,EACpB,CAEA,WAAAsH,CAAYtH,EAASlV,EAAUO,KAAKP,SAClC,OAAOiJ,QAAQwT,IAAI,CACjBlc,KAAK4U,KAAKD,GACVjC,GAAQ1S,KAAM,UAAW,QAASP,KACjC0J,KAAK,GAAI6G,KAAQA,EACtB,CAEA,WAAMC,CAAMkM,GAGV,GAAoB,YAAhBnc,KAAKgK,OACP,MAAM,IAAIa,MAAM,yBAGlB,OAAO,IAAInC,QAAQ,CAACC,EAASC,KAC3B5I,KAAKoZ,OAAOnJ,MAAMkM,EAASjb,GAASA,EAAM0H,EAAO1H,GAAOyH,MAE5D,CAEA,QAAA6R,CAAS7F,GACP,MAAM7N,KAAEA,GAAS6N,EACjB,MAAgB,OAAT7N,GAA0B,YAATA,GAA+B,aAATA,CAChD,CAEA,OAAAsV,CAAQzH,GACN,OAAQ3U,KAAKwa,SAAS7F,EACxB,CAGA,MAAA+G,CAAO1L,GACL,OAAOA,EAAG3O,UACZ,CAGA,aAAAma,GACE,OAAO,IAAIhG,GAAI9H,QAAQ,GAAI,CACzBlR,QAAS,MACTwR,MAAOhO,KAAKqc,IAEhB,CAGA,MAAAP,CAAO9L,GACL,OAAOA,EAAG3O,UACZ,CAGA,aAAA0a,GAAiB,CAGjB,gBAAAR,GAAoB,CAGpBe,GAAS,IAAIC,IACbC,GAAe,IAAIC,IAAI,CAAC,UACxB,IAAAC,CAAK7I,EAAOC,GACV9T,MAAK2c,EAAqB9I,GAErB7T,MAAKsc,EAAOM,IAAI/I,IACnB7T,MAAKsc,EAAOxc,IAAI+T,EAAO,IAAI4I,KAG7Bzc,MAAKsc,EAAOtR,IAAI6I,GAAOgJ,IAAI,CAAC/I,GAC9B,CACA,EAAA6I,CAAqB9I,GACnB,IAAK7T,MAAKwc,EAAaI,IAAI/I,GACzB,MAAM,IAAIhJ,MAAM,oBAAoBgJ,iBAExC,CACA,MAAAiJ,CAAOjJ,EAAOC,GACZ9T,MAAK2c,EAAqB9I,GAC1B,MAAMkJ,EAAW/c,MAAKsc,EAAOtR,IAAI,SAC3BtE,EAAO,IAAIqW,GAAUC,KAAMtW,GAASA,EAAKoN,UAAYA,GAC3DiJ,EAAShN,OAAOrJ,EAClB,CACA,OAAMkV,CAAU/H,KAAU5S,GACxBjB,MAAK2c,EAAqB9I,GAE1B,MAAMyI,EAAQtc,MAAKsc,EAAOtR,IAAI6I,GACzByI,SAKC5T,QAAQwT,IACZ,IAAII,GAAOpJ,IAAI5H,OAAQwI,MACrB,UACQA,KAAW7S,EACnB,CAAE,MAAOC,GACPlB,KAAK2R,KAAK,QAASzQ,EACrB,IAGN,EAIF+X,GAAW1Y,UAAU8b,GAAK,GAC1BpD,GAAW1Y,UAAU+a,OAAS,KAC9BrC,GAAW1Y,UAAU0U,OAAS,KC5Z9B,MAAMgI,WAAehE,GACnB,WAAAtZ,CAAYI,GACVgR,MAAMhR,GACNC,KAAKkd,WAAa,EACpB,CAEA,IAAAtI,CAAKD,KAAY1T,GACf,OAAOjB,KAAKmd,UAAU5c,UAAUqU,KAAKnU,KAAKT,KAAM2U,KAAY1T,EAC9D,CAEA,QAAAmc,IAAYnc,GACV,OAAOjB,KAAKmd,UAAU5c,UAAU6c,SAAS3c,KAAKT,QAASiB,EACzD,CAEA,cAAAoc,CAAe3C,GACb,OAAO1a,KAAKkd,WAAWF,KAAMG,IAC3B,IACE,YAAyDzhB,IAAlDyhB,EAAU5c,UAAUgb,iBAAiBb,EAC9C,CAAE,MACA,OAAO,CACT,GAEJ,CAEA,OAAAN,CAAQM,GACN,MAAMyC,EAAYnd,KAAKqd,eAAe3C,GAEtC,IAAKyC,EACH,MAAM,IAAItS,MAAM,0CAOlB,OAJA7K,KAAKmd,UAAYA,EACjBnd,KAAKsb,OAAS6B,EAAU5c,UAAU+a,OAClCtb,KAAKiV,OAASkI,EAAU5c,UAAU0U,OAE3BlE,MAAMqJ,QAAQM,EACvB,CAEA,gBAAAa,IAAoBta,GAClB,OAAOjB,KAAKmd,UAAU5c,UAAUgb,oBAAoBta,EACtD,CAEA,MAAAya,CAAOF,KAAkBva,GAKvB,MAAMqc,EAAOtd,KAAKqZ,YAAcrZ,KAAK0X,KAAKX,OAAO1V,WAEjD,OADIic,IAAM9B,EAAc7N,MAAM2P,KAAOA,GAC9Btd,KAAKmd,UAAU5c,UAAUmb,OAAOF,KAAkBva,EAC3D,CAEA,aAAAua,IAAiBva,GACf,OAAOjB,KAAKmd,UAAU5c,UAAUib,iBAAiBva,EACnD,CAEA,MAAA6a,IAAU7a,GACR,OAAOjB,KAAKmd,UAAU5c,UAAUub,UAAU7a,EAC5C,CAEA,aAAA8a,IAAiB9a,GACf,OAAOjB,KAAKmd,UAAU5c,UAAUwb,iBAAiB9a,EACnD,EAGFgc,GAAO1c,UAAU8b,GAAK,gBCjEtB,MAAMkB,WAAkBzM,EAAAA,aACtB,WAAAnR,CAAY4U,GACVxD,QAEA/Q,KAAK8S,MAAQ,IACb9S,KAAKuU,OAASA,EACdvU,KAAKwd,SAAW,IAClB,CAEAC,GAAgB,KACdzd,KAAK0d,qBAGP,iBAAAA,GACE,MAAMnJ,OAAEA,EAAMzB,MAAEA,EAAK0K,SAAEA,GAAaxd,KACpCiT,aAAauK,GACbxd,KAAKwd,SAAW3K,WAAWvH,UACzB,GAAsB,eAAlBiJ,EAAOvK,OAIX,UACQhK,KAAK1C,WACb,CAAE,MAEF,GACCwV,EACL,CAEA,eAAMxV,GACJ,MAAMiX,OAAEA,GAAWvU,KACnBA,KAAK2R,KAAK,gBAEV,MAAM+I,QAAEA,EAAOzE,OAAEA,EAAM4E,KAAEA,GAAStG,EAAOxU,cACnCwU,EAAO6F,QAAQM,SACfnG,EAAOuG,KAAK,CAAE7E,SAAQ4E,SAE5B7a,KAAK2R,KAAK,cACZ,CAEA,KAAAxE,GACE,MAAMoH,OAAEA,GAAWvU,KACnBuU,EAAOlV,GAAG,aAAcW,MAAKyd,EAC/B,CAEA,IAAA9B,GACE,MAAMpH,OAAEA,EAAMiJ,SAAEA,GAAaxd,KAC7BuU,EAAOZ,eAAe,aAAc3T,MAAKyd,GACzCxK,aAAauK,EACf,EChDF,MAAMG,GAAO,oBASE,cAAqB7M,EAAAA,aAClC+D,GAAa,KACbuE,OAAS,KACT9T,IAAM,KACNgU,QAAS,EAET,OAAAc,CAAQ9U,GACNtF,KAAKsF,IAAMA,EACXtF,KAAKsZ,OAfF,SAAkBhU,GACvB,MAAMsY,EAAMnF,GAASnT,GACrB,MAAqB,SAAjBsY,EAAI/E,YACJ,CAAC,YAAa,YAAa,OAAO8B,SAASiD,EAAIhF,SAErD,CAUkBS,CAAS/T,GAEvBtF,KAAKka,cAAc,IAAI2D,UAAUvY,EAAK,CAAC,SACzC,CAEA,aAAA4U,CAAcd,GACZpZ,KAAKoZ,OAASA,EACdpZ,MAAK6U,IAAeA,GAAU,CAC5BiG,KAAM,IAAM9a,KAAK2R,KAAK,WACtB9F,QAAS,EAAG/M,UAAWkB,KAAK2R,KAAK,OAAQ7S,GACzCsC,MAAQyS,IACN,MAAMvO,IAAEA,GAAQtF,KAEhB,IAAIoB,MAAEA,GAAUyS,EAEXzS,IACHA,EAAQ,IAAIyJ,MAAMgJ,EAAMhI,SAAW,aAAa8R,MAAQrY,KACxDlE,EAAM+I,MAAQwT,GACdvc,EAAMwI,KAAO+T,IAGfvc,EAAMyS,MAAQA,EACdzS,EAAMkE,IAAMA,EACZtF,KAAK2R,KAAK,QAASvQ,IAErB+Y,MAAQtG,IACN7T,KAAK8Z,gBACL9Z,KAAK2R,KAAK,SAAUkC,EAAMiK,SAAUjK,MAGxC7T,MAAK6U,EAAWC,UAAU9U,KAAKoZ,OACjC,CAEA,aAAAU,GACE9Z,KAAKsF,IAAM,KACXtF,KAAKsZ,QAAS,EACdtZ,KAAKoZ,QAAUpZ,MAAK6U,GAAYE,YAAY/U,KAAKoZ,QACjDpZ,KAAKoZ,OAAS,IAChB,CAEA,GAAAhM,GACEpN,KAAKoZ,OAAOe,OACd,CAEA,KAAAlK,CAAMnR,EAAMif,GACV,SAASrJ,EAAKxT,GACP6c,GAELrV,QAAQC,UAAUQ,KAAK,IAAM4U,EAAG7c,GAClC,CAEA,IACElB,KAAKoZ,OAAOxE,KAAK9V,EACnB,CAAE,MAAOoC,GAEP,YADAwT,EAAKxT,EAEP,CACAwT,GACF,GCxEF,MAAMsJ,GAAa,sCAQnB,MAAMC,WAA4BhF,GAChC,IAAArE,CAAKD,KAAY1T,GAEf,OADA0T,EAAQhH,MAAMK,QAAUhO,KAAKqc,GACtBtL,MAAM6D,KAAKD,KAAY1T,EAChC,CAEA,cAAMmc,CAASc,GACb,IAAK,MAAMvJ,KAAWuJ,EACpBvJ,EAAQhH,MAAMK,QAAUhO,KAAKqc,GAC7B1H,EAAQ/G,OAAS5N,KAAKuP,KACtBvP,KAAKoZ,OAAOnJ,MAAM0E,EAAQtT,YAC1BrB,KAAK2R,KAAK,OAAQgD,EAEtB,CAGA,aAAAoH,GACE,OAAO,IAAIvG,GAAI9H,QAAQ,QAAS,CAC9BM,MAAOgQ,IAEX,CAGA,aAAAxC,GACE,MAAMxL,EAAKe,MAAMyK,gBAGjB,OAFAxL,EAAGlJ,KAAO,OACVkJ,EAAGrC,MAAMK,MAAQgQ,GACVhO,CACT,CAEA,gBAAAuL,CAAiBb,GACf,MAAO,aAAayD,KAAKzD,GAAWA,OAAUhf,CAChD,EAGFuiB,GAAoB1d,UAAU+a,OAASA,GACvC2C,GAAoB1d,UAAU8b,GAAK,gBACnC4B,GAAoB1d,UAAU0U,OCjDf,cAA2BA,GACxC,cAAAI,CAAevO,EAAM6G,GACnB,MAAMgH,EAAU,IAAIjH,GAAQ5G,EAAM6G,IAE5ByH,OAAEA,GAAWpV,KAEfoV,GACFA,EAAOvO,OAAO8N,GAGhB3U,KAAKoV,OAAST,CAChB,CAEA,YAAAW,CAAaxO,GACX,MAAMsO,OAAEA,GAAWpV,KACf8G,IAASsO,EAAOtO,KAMhBsO,EAAOxH,OACT5N,KAAKoV,OAASA,EAAOxH,QAInBwH,EAAOrH,GAAG,OAAQ,uCACpB/N,KAAK2R,KAAK,QAASyD,GACVA,EAAOrH,GAAG,QAAS,uCAC5B/N,KAAK2R,KAAK,MAAOyD,GAEjBpV,KAAK2R,KAAK,UAAWyD,GAGvBpV,KAAKoV,OAAS,MAjBZpV,KAAK2R,KAAK,QAAS,IAAIqD,GAAS,GAAGI,EAAOtO,wBAkB9C,UCnCa,cAAqBsX,EAAAA,OAClC9E,QAAS,GCGX,MAAM+E,GAAY,0CAKlB,cAA4BpF,GAC1B,cAAMmE,CAASc,GACb,IAAIrC,EAAW,GAEf,IAAK,MAAMlH,KAAWuJ,EACpBvJ,EAAQ/G,OAAS5N,KAAKuP,KACtBsM,GAAYlH,EAAQtT,iBAGhBrB,KAAKiQ,MAAM4L,GAEjB,IAAK,MAAMlH,KAAWuJ,EACpBle,KAAK2R,KAAK,OAAQgD,EAEtB,CAEA,gBAAA4G,CAAiBb,GACf,MAAM/B,KAAEA,EAAIC,SAAEA,EAAQC,SAAEA,GAAaJ,GAASiC,GAE9C,MAAoB,UAAb7B,EACH,CAAEF,KAAMA,EAAOlC,OAAOkC,GAAQ,KAAMK,KAAMJ,QAC1Cld,CACN,CAGA,aAAA8f,GACE,MAAMxL,EAAKe,MAAMyK,gBAGjB,OAFAxL,EAAGlJ,KAAO,gBACVkJ,EAAGrC,MAAM,gBAAkB0Q,GACpBrO,CACT,CAGA,MAAA0L,CAAO1L,GACL,MAAO,wBAAwBA,EAAG3O,WAAWsL,MAAM,QACrD,CAGA,MAAAmP,GACE,MAAO,kBACT,GAGFwC,GAAc/d,UAAU8b,GAAKgC,GAC7BC,GAAc/d,UAAU+a,OAASA,GACjCgD,GAAc/d,UAAU0U,OAASA,GCtDjC,MAAMqJ,WAAsBrF,GAC1B,gBAAAsC,CAAiBb,GACf,MAAMtV,EAAS2L,MAAMwK,iBAAiBb,GACtC,OAAKtV,GACLA,EAAOuT,KAAOvT,EAAOuT,MAAQ,KACtBvT,GAFaA,CAGtB,ECNa,SAASmZ,IAAIhK,OAAEA,IAC5BA,EAAO2I,WAAWha,KAAKob,GACzB,CDOAA,GAAc/d,UAAU8b,GAAK,gBEP7B,MAAMf,WAAexK,EAAAA,aACnBrR,QAAU,KACVoV,GAAa,KACbuE,OAAS,KACTE,QAAS,EAET,OAAAc,IAAWnZ,GACTjB,KAAKka,cAAcsE,EAAAA,QAAIpE,WAAWnZ,GACpC,CAEA,aAAAiZ,CAAcd,GACZpZ,KAAKoZ,OAASA,EACdpZ,MAAK6U,IAAeA,GAAU,CAC5BsF,MAAO,KACLna,KAAK8Z,gBACL9Z,KAAK2R,KAAK,UAEZ7S,KAAOA,IACLkB,KAAK2R,KAAK,OAAQ7S,IAEpBsC,MAAQF,IACNlB,KAAK2R,KAAK,QAASzQ,IAErBud,cAAe,KACb,GAAkC,YAA9Bze,KAAKoZ,OAAOsF,cACd,OAAO1e,KAAK2R,KAAK,WAOnB3R,KAAKP,QAAUoT,WAAW,KACxB7S,KAAK2R,KAAK,YACT,MAGP3R,MAAK6U,EAAWC,UAAU9U,KAAKoZ,OACjC,CAEA,aAAAU,GACE9Z,MAAK6U,EAAWE,YAAY/U,KAAKoZ,QACjCpZ,KAAKoZ,OAAS,IAChB,CAEA,GAAAhM,GACEpN,KAAKoZ,OAAOhM,KACd,CAEA,KAAA6C,CAAMnR,EAAMif,GACV/d,KAAKoZ,OAAOnJ,MAAMnR,EAAMif,EAC1B,EClDF,MAAMY,WAAsBL,GAC1B,gBAAA/C,CAAiBb,GACf,MAAM/B,KAAEA,EAAIC,SAAEA,EAAQC,SAAEA,GAAaJ,GAASiC,GAC9C,MAAoB,WAAb7B,EACH,CACEF,KAAMlC,OAAOkC,IAAS,KACtBK,KAAMJ,QAERld,CACN,ECZa,SAAS8iB,IAAIjK,OAAEA,IAC5BA,EAAO2I,WAAWha,KAAKyb,GACzB,WDaAA,GAAcpe,UAAU+a,OAASA,GACjCqD,GAAcpe,UAAU8b,GAAK,kCEZ7BuC,GAYA,SAAkBC,GAChB,IAAK/c,MAAMF,QAAQid,GAAa,MAAM,IAAI3I,UAAU,sCACpD,IAAK,MAAM6H,KAAMc,EACf,GAAkB,mBAAPd,EAAmB,MAAM,IAAI7H,UAAU,6CASpD,OAAO,SAAU4I,EAASC,GAExB,IAAIlW,GAAQ,EACZ,OACA,SAASmW,EAAUC,GACjB,GAAIA,GAAKpW,EAAO,OAAOH,QAAQE,OAAO,IAAIiC,MAAM,iCAChDhC,EAAQoW,EACR,IAAIlB,EAAKc,EAAWI,GAEpB,GADIA,IAAMJ,EAAW7b,SAAQ+a,EAAKgB,IAC7BhB,EAAI,OAAOrV,QAAQC,UACxB,IACE,OAAOD,QAAQC,QAAQoV,EAAGe,EAASE,EAASxL,KAAK,KAAMyL,EAAI,IACnE,CAAQ,MAAO/d,GACP,OAAOwH,QAAQE,OAAO1H,EAC9B,CACA,CAZW8d,CAAS,EAapB,CACA,iBC/Ce,MAAME,GACnB,WAAAvf,CAAY4U,EAAQC,GAClBxU,KAAKwU,OAASA,EACdxU,KAAKuU,OAASA,EAEd,MAAMzN,KAAEA,EAAI6G,MAAEA,GAAU6G,GAClBpV,KAAEA,EAAIuM,GAAEA,GAAOgC,EAErB3N,KAAK8G,KAAOA,EACZ9G,KAAK2L,GAAKA,GAAM,GAGd3L,KAAKZ,KADM,YAAT0H,EACU1H,GAAQ,SACF,aAAT0H,EACG1H,GAAQ,YAERA,GAAQ,GAGtBY,KAAKsd,KAAO,KACZtd,KAAKyb,GAAK,KACVzb,KAAK2V,MAAQ,GACb3V,KAAKiW,OAAS,GACdjW,KAAK0B,SAAW,EAClB,ECpBa,MAAMyd,WAAwBD,GAC3C,WAAAvf,CAAY4U,EAAQC,GAClBzD,MAAMwD,EAAQC,GAEd,MAAMkD,IAAEA,GAAQnD,GACV0B,OAAEA,GAAW1B,EAAOxU,SAAW,CAAA,EAE/B0b,EAAKjH,EAAO7G,MAAM8N,IAAM/D,GAAKrW,WAC7Bic,EAAO9I,EAAO7G,MAAM2P,MAAQrH,EAE9BwF,IAAIzb,KAAKyb,GAAK,IAAIzF,GAAIyF,IAEtB6B,IACFtd,KAAKsd,KAAO,IAAItH,GAAIsH,GACpBtd,KAAK2V,MAAQ3V,KAAKsd,KAAK3H,MACvB3V,KAAKiW,OAASjW,KAAKsd,KAAKrH,OACxBjW,KAAK0B,SAAW1B,KAAKsd,KAAK5b,SAE9B,EClBa,MAAM0d,WAAwBF,GAC3C,WAAAvf,CAAY4U,EAAQC,GAClBzD,MAAMwD,EAAQC,GAEd,MAAMkD,IAAEA,GAAQnD,GACV0B,OAAEA,GAAW1B,EAAOxU,SAAW,CAAA,EAE/Bud,EAAO9I,EAAO7G,MAAM2P,MAAQ5F,GAAKrW,WACjCoa,EAAKjH,EAAO7G,MAAM8N,IAAMxF,EAE1BqH,IAAMtd,KAAKsd,KAAO,IAAItH,GAAIsH,IAE1B7B,IACFzb,KAAKyb,GAAK,IAAIzF,GAAIyF,GAClBzb,KAAK2V,MAAQ3V,KAAKyb,GAAG9F,MACrB3V,KAAKiW,OAASjW,KAAKyb,GAAGxF,OACtBjW,KAAK0B,SAAW1B,KAAKyb,GAAG/Z,SAE5B,ECjBF,SAAS+S,GAASF,EAAQsK,EAAYK,GACpC,OAAQ1K,IACN,MAAM6K,EAAM,IAAIH,EAAQ3K,EAAQC,GAChC,OAAO8K,GAAQT,EAARS,CAAoBD,GAE/B,CAEA,SAASE,GAAahL,GACpB,MAAO,CAAC8K,EAAKN,KACXA,IACG5V,KAAMqW,GAAUA,GAASjL,EAAOK,KAAK4K,IACrC9V,MAAOxI,GAAQqT,EAAO5C,KAAK,QAASzQ,IAE3C,CCdA,MAAMue,WAAoBvH,GACxB,WAAAvY,CAAYwY,EAAW7O,EAAM8O,EAAahZ,GACxC2R,MAAMoH,EAAW7O,EAAM8O,GACvBpY,KAAKZ,KAAOA,EACZY,KAAK8G,KAAO,aACd,CAEA,kBAAOuR,CAAY1D,GACjB,MAAMvT,EAAQ2P,MAAMsH,YAAY1D,GAEhC,OADAvT,EAAMhC,KAAOuV,EAAQhH,MAAMvO,KACpBgC,CACT,ECJF,MAAMse,GACJ,WAAA/f,EAAY4U,OAAEA,EAAMsK,WAAEA,IACpB7e,KAAK+c,SAAW,IAAIR,IACpBvc,KAAKuU,OAASA,EACdvU,KAAK6e,WAAaA,CACpB,CAEA,KAAA1R,GACEnN,KAAK6e,WAAWc,IAAI3f,KAAK4f,OAAOpM,KAAKxT,MACvC,CAEA,MAAA4f,EAAOxgB,KAAEA,EAAI0H,KAAEA,EAAI6E,GAAEA,EAAE6I,OAAEA,GAAUuK,GACjC,IAlBJ,UAAiBjY,KAAEA,EAAI1H,KAAEA,IACvB,MAAa,OAAT0H,IACS,UAAT1H,GAA6B,WAATA,EAE1B,CAcSygB,CAAQ,CAAE/Y,OAAM1H,SAAS,OAAO2f,IAErC,MAAMe,EAAW9f,KAAK+c,SAAS/R,IAAIW,GAEnC,IAAKmU,EACH,OAAOf,IAGI,UAAT3f,EACF0gB,EAASlX,OAAO6W,GAAYpH,YAAY7D,EAAO9F,SAAS,WAExDoR,EAASnX,QAAQ6L,GAGnBxU,KAAK+c,SAASgD,OAAOpU,EACvB,CAEA,aAAMqU,CAAQxL,EAAQ/U,EAAU,KACzB+U,EAAO7G,MAAMhC,KAChB6I,EAAO7G,MAAMhC,GC1CJ,WACb,IAAIsT,EACJ,MAAQA,GACNA,EAAI7c,KAAKE,SAASjB,SAAS,IAAIsL,MAAM,EAAG,IAG1C,OAAOsS,CACT,CDmCwBgB,IAGpB,MAAMH,EAAW,IAAIzL,GACrBrU,KAAK+c,SAASjd,IAAI0U,EAAO7G,MAAMhC,GAAImU,GAEnC,UACQ9f,KAAKuU,OAAOK,KAAKJ,SACjB0L,GAAeJ,EAASpN,QAASjT,EACzC,CAAE,MAAOyB,GAEP,MADAlB,KAAK+c,SAASgD,OAAOvL,EAAO7G,MAAMhC,IAC5BzK,CACR,CAEA,OAAO4e,EAASpN,OAClB,CAEA,aAAAyN,CAAc/gB,EAAMuV,EAAS8G,KAAOxa,GAClC,MAAM6F,KACJA,EACA6G,OAAOK,MAAEA,IACP2G,EACJ,OAAO3U,KAAKggB,QAAQxK,GAAI,KAAM,CAAEpW,OAAMqc,MAAM9G,MAAa1T,GAAMkI,KAC5DqL,GAAWA,EAAO9F,SAAS5H,EAAMkH,GAEtC,CAEA,SAAMhD,IAAO/J,GACX,OAAOjB,KAAKmgB,cAAc,SAAUlf,EACtC,CAEA,SAAMnB,IAAOmB,GACX,OAAOjB,KAAKmgB,cAAc,SAAUlf,EACtC,EEpDF,SAASmf,IAAW5L,OAAEA,IACpB,OAAOgB,GAAI,KAAM,CACfiG,GAAIjH,EAAO7G,MAAM2P,KACjBA,KAAM9I,EAAO7G,MAAM8N,GACnB9P,GAAI6I,EAAO7G,MAAMhC,IAErB,CAYA,SAAS0U,GAAgBhB,EAAKje,EAAOwN,GACnC,MAAM4Q,EAAQY,GAAWf,GAOzB,OANAG,EAAM7R,MAAMvO,KAAO,QACfwP,GACF4Q,EAAM3Y,OAAO+H,GAGf4Q,EAAM3Y,OAAOzF,GACNoe,CACT,CAEA,SAASc,GAAWlhB,EAAM+Y,GACxB,OAAO3C,GAAI,QAAS,CAAEpW,QAAQoW,GAAI2C,EA7ClB,uCA8ClB,CAEA,SAASoI,GAAUhM,GACjB,OAAOjJ,eAAyB+T,EAAKN,GACnC,IAhDJ,UAAiBjY,KAAEA,EAAI1H,KAAEA,IACvB,MAAa,OAAT0H,GACS,UAAT1H,GAA6B,WAATA,CAE1B,CA4CSohB,CAAQnB,GAAM,OAAON,IAE1B,MAAMvK,OAAEA,GAAW6K,EACbxR,EAAW2G,EAAOlF,oBACjBV,GAASf,EAEhB,IAhDJ,UAAsBzO,KAAEA,GAAQyO,EAAUe,GACxC,OAAa,QAATxP,GAA2B,QAATA,IACE,IAApByO,EAAS7K,UACR4L,CAEP,CA2CS6R,CAAapB,EAAKxR,EAAUe,GAC/B,OAAOyR,GAAgBhB,EAAKiB,GAAW,SAAU,eAAgB1R,GAKnE,IAAI4Q,EAFJH,EAAI1K,QAAU/F,EAGd,IACE4Q,QAAcT,GAChB,CAAE,MAAO7d,GACPqT,EAAO5C,KAAK,QAASzQ,GACrBse,EAAQc,GAAW,SAAU,wBAC/B,CAMA,OAJKd,IACHA,EAAQc,GAAW,SAAU,wBAG3Bd,aAAiBhK,GAAI9H,SAAW8R,EAAMzR,GAAG,SACpCsS,GAAgBhB,EAAKG,EAAO5Q,GApDzC,SAA0ByQ,EAAKzQ,GAC7B,MAAM4Q,EAAQY,GAAWf,GAMzB,OALAG,EAAM7R,MAAMvO,KAAO,SACfwP,GACF4Q,EAAM3Y,OAAO+H,GAGR4Q,CACT,CA+CWkB,CACLrB,EACAG,aAAiBhK,GAAI9H,QAAU8R,OAAQ9jB,EAE3C,CACF,CAEA,SAASgP,GAAMtL,EAAMuhB,EAAI7Z,EAAMgN,GAC7B,MAAO,CAACuL,EAAKN,IACNM,EAAIjgB,OAASA,GAASigB,EAAI1K,UAAY0K,EAAI1K,QAAQ5G,GAAGjH,EAAM6Z,GACvD5B,IACFjL,EAAQuL,EAAKN,EAExB,CC9FA,MAAM6B,GAAe,CAAC,YAAa,WAEnC,SAASC,GAAO5K,EAAQlW,EAAU,IAEhC,OADAA,EAAQmc,KAAM,EACP,IAAIxT,QAAQ,CAACC,EAASC,KAC3BkY,EAAAA,QAAID,OAAO5K,EAAQlW,EAAS,CAACmB,EAAK6f,KAChC,GAAI7f,EACF,OAAO0H,EAAO1H,GAGhB,MAAMgM,EAAS,GACf,IAAK,MAAM8T,OAAEA,EAAMC,QAAEA,KAAaF,EAAW,CAC3C,MAAMnD,EAAM,MAAiB,IAAXoD,EAAeC,EAAU,IAAMA,EAAU,OAC3D/T,EAAOhK,KACL,CACE8d,SACAC,UACArD,IAAK,QAAUA,EAAM,QAEvB,CACEoD,SACAC,UACArD,IAAK,OAASA,EAAM,QAG1B,CACAjV,EAAQuE,MAGd,CAwDA,SAASvE,GAAQsN,EAAQlW,EAAU,IA+CjC,OA9CKA,EAAQmhB,MACXnhB,EAAQmhB,IAAM,CACZ,CACExG,QAAS,eACT7B,SAAU,OAEZ,CACE6B,QAAS,cACT7B,SAAU,OAEZ,CACE6B,QAAS,eACT7B,SAAU,OAEZ,CACE6B,QAAS,cACT7B,SAAU,OAEZ,CACE6B,QAAS,OACT7B,SAAU,OAEZ,CACE6B,QAAS,OACT7B,SAAU,OAEZ,CACE6B,QAAS,SACTyG,QAAS,OAEX,CACEzG,QAAS,OACT7B,SAAU,OAEZ,CACE6B,QAAS,OACT7B,SAAU,OAEZ,CACE6B,QAAS,QACTyG,QAAS,SAMRN,GAAO5K,EAAQlW,GAASoJ,KAAM4X,GAC5BrY,QAAQwT,IACbnc,EAAQmhB,IAAIhO,IAAKgO,GAvGvB,SAAoBjL,GAAQyE,QAAEA,EAAO7B,SAAEA,IACrC,OAAO,IAAInQ,QAAQ,CAACC,EAASC,KAC3BkY,EAAAA,QAAIM,WAAW,IAAI1G,MAAY7B,KAAY5C,IAAU,CAAC/U,EAAKmgB,KACrDngB,GAAO0f,GAAajG,SAASzZ,EAAI0I,MACnCjB,EAAQ,IACCzH,EACT0H,EAAO1H,GAEPyH,EACE0Y,EAAQnO,IAAKoO,GACJnhB,OAAO6I,OAAOsY,EAAQ,CAAE5G,UAAS7B,kBAMpD,CAwFeuI,CAAWnL,EAAQ,IAAKiL,IAAe/X,KAAMkY,GAtE5D,SAAoBE,EAAMxhB,GACxB,MAAMghB,EAAY,GAClB,OAAOrY,QAAQwT,IACbqF,EAAKrO,IAAI5H,MAAO4V,IACd,MAAMM,QAAqBX,GAAOK,EAAIpa,KAAM/G,GAC5C,IAAK,MAAMkhB,KAAWO,EAAc,CAClC,MAAM7I,KAAEA,EAAI+B,QAAEA,GAAYwG,EACpBO,EAAOR,EAAQA,QACrBF,EAAU7d,KAAK,IACV+d,KACAC,EACHtD,IAAK,GAAGlD,EAAQgH,MAAM,KAAK,QACN,IAAnBT,EAAQD,OAAe,IAAMS,EAAO,IAAMA,KACxC9I,KAER,KAEFxP,KAAK,IAAM4X,EACf,CAqDiBY,CAAWN,EAASthB,MAG/BoJ,KAAMoY,IAAS,WA1FJF,EA0FgBE,EAAKtS,OAzF7BoS,EAAQO,SAAS,CAAC9J,EAAGnU,KAC1B,MAAMke,EAAW/J,EAAE+J,SAAWle,EAAEke,SAChC,GAAiB,IAAbA,EACF,OAAOA,EAGT,MAAMC,EAASne,EAAEme,OAAShK,EAAEgK,OAC5B,OAAe,IAAXA,EACKA,EAGF,QA8EuCf,GA1FlD,IAAiBM,IA4FjB,CClJA,SAAShI,GAASuE,GAChB,OAAOA,EAAIvL,WAAW,UAAYuL,EAAIvL,WAAW,MACnD,CAEO,SAAS0P,GAAQjK,EAAGnU,GACzB,IAAI2V,EAaApT,EAJJ,OAPEoT,EADED,GAASvB,EAAE8F,OAASvE,GAAS1V,EAAEia,MACxB,GACCvE,GAASvB,EAAE8F,MAAQvE,GAAS1V,EAAEia,KAC/B,EAEA,EAGI,IAAXtE,EACKA,GAKPpT,EADE4R,EAAE5R,SAAWvC,EAAEuC,OACR,EACa,cAAb4R,EAAE5R,QACF,EACa,cAAbvC,EAAEuC,OACF,EACa,UAAb4R,EAAE5R,QACF,EACa,UAAbvC,EAAEuC,OACF,EACa,aAAb4R,EAAE5R,QACF,EACa,aAAbvC,EAAEuC,OACF,EAEA,EAGI,IAAXA,EACKA,EAGF,EACT,CCtCO,SAASyC,GAAQsN,GAEtB,OAAO/M,MAAM,WAAW+M,2BACrB9M,KAAM3H,GAAQA,EAAI8H,QAClBH,KAAM3H,GCNI,SAAe1C,GAC5B,MAAMkjB,EAAI,IAAI/M,GAEd,IAAI/H,EAAS,KACT9L,EAAQ,KAeZ,GAbA4gB,EAAE3iB,GAAG,QAAU2Q,IACb9C,EAAS8C,IAEXgS,EAAE3iB,GAAG,UAAY2Q,IACf9C,EAAOrG,OAAOmJ,KAEhBgS,EAAE3iB,GAAG,QAAU6B,IACbE,EAAQF,IAGV8gB,EAAE/R,MAAMnR,GACRkjB,EAAE5U,MAEEhM,EACF,MAAMA,EAEN,OAAO8L,CAEX,CDjBa7I,CAAM7C,GACVmN,YAAY,QACZQ,OAAQ8S,GACP,CACE,qCACA,oCACA,kCACAtH,SAASsH,EAAKtU,MAAMuU,MAEvBhP,IAAI,EAAGvF,YAAO,CACbuU,IAAKvU,EAAMuU,IACXC,KAAMxU,EAAMwU,KACZjc,OAAQyH,EAAMuU,IAAIR,MAAM,KAAKU,MAC7BxE,IAAKjQ,EAAMwU,QAEZP,SAASS,KAEb3Y,MAAM,IACE,GAEb,CEzBA4B,eAAegX,GAAUrM,GACvB,MAAM/I,QCFO,YAAoBjM,GACjC,OAAOyH,QAAQwT,IAAI,CACjBqG,GAAcA,MAAethB,GAAQyH,QAAQC,QAAQ,IACrD6Z,MAAgBvhB,KACfkI,KAAK,EAAEkY,EAASzkB,KAAe,IAAIykB,KAAYzkB,GACpD,CDHuB6lB,CAASxM,EAAQ,CACpCiL,IAAK,CACH,CACExG,QAAS,eACT7B,SAAU,OAEZ,CACE6B,QAAS,cACT7B,SAAU,UAKhB,MAAO,IAEF,IAAI4D,IAAIvP,EAAOgG,IAAKoO,GAAWA,EAAO1D,MAE7C,CAMAtS,eAAeoX,GAAgBnO,EAAQoO,GACrC,GAAoB,IAAhBA,EAAK3f,OACP,MAAM,IAAI6H,MAAM,oBAGlB,MAAM+S,EAAM+E,EAAKC,QACXzF,EAAY5I,EAAO8I,eAAeO,GAExC,IAAKT,EACH,OAAOuF,GAAgBnO,EAAQoO,GAGjCpO,EAAOwF,QAAQ,aAAc6D,GAC7B,MAAMxY,EAAS+X,EAAU5c,UAAUgb,iBAAiBqC,GAC9CxE,EAAS,IAAI+D,EAAU5c,UAAU+a,OAEvC,IACElC,EAAOgB,QAAQhV,SACTsN,GAAQ0G,EAAQ,UACxB,CAAE,MACA,OAAOsJ,GAAgBnO,EAAQoO,EACjC,CAEApO,EAAO2F,cAAcd,GACrBA,EAAOzH,KAAK,WACZ4C,EAAO4I,UAAYA,EACnB5I,EAAO+G,OAAS6B,EAAU5c,UAAU+a,OACpC/G,EAAOU,OAASkI,EAAU5c,UAAU0U,MACtC,CAEe,SAAStM,IAAQ4L,OAAEA,IAChC,MAAMsO,EAAWtO,EAAO6F,QACxB7F,EAAO6F,QAAU9O,eAAuBoP,GACtC,IAAKA,GAAW,QAAQyD,KAAKzD,GAC3B,OAAOmI,EAASpiB,KAAKT,KAAM0a,GAG7B,MAAMiI,EAzCV,SAA6BpO,EAAQoO,GACnC,OAAOA,EAAKxT,OAAQyO,GAAQrJ,EAAO8I,eAAeO,GACpD,CAuCiBkF,CAAoBvO,QAAc+N,GAAU5H,IAEzD,GAAoB,IAAhBiI,EAAK3f,OACP,MAAM,IAAI6H,MAAM,kCAGlB,UACQ6X,GAAgBnO,EAAQoO,EAChC,CAAE,MAAOzhB,GAGP,YAFMqT,EAAOiF,aACbjF,EAAOwF,QAAQ,cACT7Y,CACR,CACF,CACF,CEtEA,MAAMmb,GAAK,kCAWI,SAAS0G,IAASC,eAAEA,IACjC,OAAOA,EAAerD,IAAI,WAAYtD,GAAI/Q,OAASiJ,UAAUwK,KAC3D,MAAM3F,OAAEA,EAAMrZ,QAAEA,GAAYwU,EAC5B,ICjBG,SAAoB6E,GACzB,OAAOA,aAAkB6J,EAAAA,QAAI3H,UAAYlC,aAAkBoF,EAAAA,QAAI0E,UACjE,CDeSC,CAAW/J,GACd,OAAO2F,UAbbzT,eAAyBiJ,GACvB,MAAMI,QAAgBJ,EAAO0H,YAAYzG,GAAI,WAAY,CAAExH,MAAOqO,MAClE,GAAI1H,EAAQ5G,GAAG,UAAWsO,IACxB,OAAO1H,EAGT,MAAM,IAAI9J,MAAM,mBAClB,CASUuY,CAAU7O,GAChB,MAAM8O,QClBH/X,eAAuB8N,EAAQrZ,EAAU,IAC9C,MAAMsjB,EAAY,IAAI/H,GAItB,OAHA+H,EAAUjJ,QAAQ,CAAEhB,YAAWrZ,UACzB2S,GAAQ2Q,EAAW,WAElBA,CACT,CDY4BC,CAAQlK,EAAQ,CAAEJ,KAAMjZ,EAAQkW,SACxD1B,EAAO2F,cAAcmJ,SAEf9O,EAAOyH,WAEjB,CEjCO,SAASuH,GAAOpH,GACrB,OAAOqH,WAAWC,KAAKtH,EACzB,CAEO,SAASuH,GAAOvH,GACrB,OAAOqH,WAAWG,KAAKxH,EACzB,CCFA,MAAMyH,WAAkB1L,GACtB,WAAAvY,IAAesB,GACb8P,SAAS9P,GACTjB,KAAK8G,KAAO,WACd,ECAF,MAAMuV,GAAK,mCAEJ,SAASwH,GAAuBlP,EAAS0H,EAAIyH,GAClD,MAAMC,EAAU,IAAItH,IAClB9H,EAAQhG,YAAY,YAAa0N,GAAInJ,IAAK1E,GAAMA,EAAElF,SAGpD,OADkBwa,EAAYE,OAAO9Q,IAAI,EAAGpM,UAAWA,GACtCqI,OAAQ8U,GAASF,EAAQnH,IAAIqH,GAChD,CAuDe,SAASC,IAAKlB,eAAEA,EAAcc,YAAEA,GAAeK,GAC5DnB,EAAerD,IAAI,aAActD,GAAI/Q,OAASiJ,UAAU6P,EAAOzP,KAC7D,MAAM0P,EAAaR,GAAuBlP,EAAS0H,GAAIyH,GACvD,GAA0B,IAAtBO,EAAWrhB,OACb,MAAM,IAAI4gB,GAAU,kDAYhBO,EATN7Y,eAAoBgZ,EAAaC,SA5DrCjZ,gBAA4BwY,YAAEA,EAAWvP,OAAEA,EAAMgQ,UAAEA,EAASD,YAAEA,IAC5D,MAAML,EAAOH,EAAYU,OAAO,CAACD,IACjC,IAAKN,EACH,MAAM,IAAIpZ,MAAM,mBAAmB0Z,gBAGrC,MAAMtO,OAAEA,GAAW1B,EAAOxU,QACpBtD,EAAQ,CACZwB,SAAU,KACV+N,SAAU,KACV5N,OAAQ6X,EACR+C,KAAM/C,EACNwO,MAAOxO,EACPyO,YAAa,OACbC,YAAa1O,KACVqO,SAGChQ,GACJC,EACA0P,EAAKW,aACHpP,GACE,OACA,CAAExH,MAAOqO,GAAIkI,UAAWN,EAAKnd,MAC7Byc,SAAaU,EAAKze,SAAS/I,KAE/B6O,MAAOqJ,EAASD,KACd,GAAIC,EAAQzG,UAAYmO,GAAxB,CAEA,GAAqB,cAAjB1H,EAAQ7N,KAAsB,OAC1Bmd,EAAKY,UAAUnB,GAAO/O,EAAQrL,SACpC,MAAMF,QAAa6a,EAAKze,SAAS/I,GAQjC,kBAPM8X,EAAOK,KACXY,GACE,WACA,CAAExH,MAAOqO,GAAIkI,UAAWN,EAAKnd,MACb,iBAATsC,EAAoBma,GAAOna,GAAQ,IAIhD,CAEA,GAAqB,YAAjBuL,EAAQ7N,KACV,MAAM8c,GAAUvL,YAAY1D,GAG9B,MAAqB,YAAjBA,EAAQ7N,KACH4N,SADT,CAnB4B,GAwBlC,CAUYoQ,CAAa,CACjBhB,cACAvP,SACAgQ,YACAD,eAEJ,EAE2BD,EAAY,KAAM9P,SAEvCA,EAAOyH,WAEjB,CCnFA,MAAMK,GAAK,kBAEX/Q,eAAewZ,IAAahB,YAC1BA,EAAWvP,OACXA,EAAMgQ,UACNA,EAASD,YACTA,EAAWS,UACXA,EAAS/B,eACTA,EAAcgC,SACdA,IAEA,MAAMf,EAAOH,EAAYU,OAAO,CAACD,IACjC,IAAKN,EACH,MAAM,IAAIpZ,MAAM,mBAAmB0Z,gBAGrC,MAAMtO,OAAEA,GAAW1B,EAAOxU,QACpBtD,EAAQ,CACZwB,SAAU,KACV+N,SAAU,KACV5N,OAAQ6X,EACR+C,KAAM/C,EACNwO,MAAOxO,EACPyO,YAAa,OACbC,YAAa1O,KACVqO,SAGChQ,GACJC,EACAiB,GAAI,eAAgB,CAAExH,MAAOqO,GAAIkI,UAAWN,EAAKnd,MAAQ,CACvDmd,EAAKW,aACHpP,GAAI,mBAAoB,CAAA,EAAI+N,SAAaU,EAAKze,SAAS/I,KACzDsoB,KACG/B,IAEL1X,MAAOqJ,EAASD,KACd,GAAIC,EAAQzG,UAAYmO,GAAxB,CAEA,GAAqB,cAAjB1H,EAAQ7N,KAAsB,OAC1Bmd,EAAKY,UAAUnB,GAAO/O,EAAQrL,SACpC,MAAMF,QAAa6a,EAAKze,SAAS/I,GAQjC,kBAPM8X,EAAOK,KACXY,GACE,WACA,CAAExH,MAAOqO,GAAIkI,UAAWN,EAAKnd,MACb,iBAATsC,EAAoBma,GAAOna,GAAQ,IAIhD,CAEA,GAAqB,YAAjBuL,EAAQ7N,KACV,MAAM8c,GAAUvL,YAAY1D,GAG9B,GAAqB,aAAjBA,EAAQ7N,KACV,MAAM,IAAI+D,MAAM,sCAGlB,GAAqB,YAAjB8J,EAAQ7N,KAAoB,CAC9B,MAAMme,EAAiBtQ,EAAQjG,SAAS,oBAAoBpF,OACxD2b,GAAkBhB,EAAKiB,aACnBjB,EAAKiB,MAAMxB,GAAOuB,IAK1B,MAAME,EAAMxQ,EAAQtF,aAAa,4BAC7B8V,GACF5Q,EAAOyG,KAAKmK,GAGd,IAAK,MAAMvW,KAAS+F,EAAQrF,mBAAoB,CAC9C,MAAM8V,EAAUJ,EAASha,IAAI4D,EAAMV,SACnCkX,IAAU,KAAKxW,EACjB,CAEA,OAAO8F,GACT,CA1C4B,GA6ClC,CAEe,SAAS2Q,IAAMrC,eAAEA,EAAcc,YAAEA,GAAeK,GAC7D,MAAMa,EAAW,IAAIzI,IACrB,IAAI+I,EAiDJ,OA/CAtC,EAAerD,IACb,iBACAtD,GACA/Q,OAASiJ,UAAU6P,EAAOzP,KACxB,MAAM0P,EAAaR,GAAuBlP,EAAS0H,GAAIyH,GACjDd,QAoDZ1X,gBAAiCqJ,QAAEA,EAAOqQ,SAAEA,IAC1C,MAAMO,EAAW,GAEXC,EAAS7Q,EAAQjG,SAAS,UAChC,IAAK8W,EAAQ,OAAOD,EAEpB,IAAK,MAAM5Q,KAAW6Q,EAAOlW,mBAAoB,CAC/C,MAAMtB,EAAQ2G,EAAQzG,QAChBkX,EAAUJ,EAASha,IAAIgD,GACxBoX,GACLG,EAASriB,KAAKkiB,EAAQ,GAAGzQ,GAC3B,CAEA,OAAOjM,QAAQwT,IAAIqJ,EACrB,CAlEmCE,CAAkB,CAAE9Q,UAASqQ,aACpDU,IAAmBJ,GAAMf,UAE/B,GAA0B,IAAtBF,EAAWrhB,SAAiB0iB,EAC9B,MAAM,IAAI9B,GAAU,kDAGhBO,EAON7Y,eAAoBgZ,EAAaC,EAAWQ,GAU1C,SARsBO,EAAKK,KAAK,CAC9Bb,gBACAvQ,SACAwQ,YACA/B,iBACAgC,WACAV,gBAEW,aAKPQ,GAAa,CACjBvQ,SACAwQ,YACA/B,iBACAgC,WACAlB,cACAS,YACAD,eAEJ,EA7BED,EACAqB,EAAiBJ,EAAO,KACxB/Q,KA+BC,CACL,GAAAoL,CAAIgB,EAAIiF,EAAKpkB,GACXwjB,EAASllB,IAAI6gB,EAAI,CAACiF,EAAKpkB,GACzB,EACA,KAAAqkB,EAAQP,KAAMQ,IACZR,EAAOQ,CACT,EAEJ,CChJA,MAAMzJ,GAAK,mCAMX/Q,eAAekI,GAAKe,EAAQwR,EAAUrkB,GACpC,MAAMwL,QAAe6Y,EAASjmB,IALhC,SAAyB4B,GACvB,OAAO8T,GAAI,OAAQ,CAAExH,MAAOqO,IAAM3a,GAAY8T,GAAI,WAAY,CAAA,EAAI9T,GACpE,CAGoCskB,CAAgBtkB,IAC5CgW,EAAMxK,EAAOmC,aAAa,OAGhC,OAFAkF,EAAOyG,KAAKtD,GACZnD,EAAO0G,QAAO,GACPvD,CACT,CAUe,SAASuO,IACtBjD,eAAEA,EAAc+C,SAAEA,GAClBrkB,GAEAshB,EAAerD,IAAI,OAAQtD,GAZ7B,UAAe0J,SAAEA,GAAYrkB,GAC3B,OAAO4J,OAASiJ,UAAUwK,KACxBrd,EAA+B,mBAAbA,QAAgCA,IAAaA,QACzD8R,GAAKe,EAAQwR,EAAUrkB,GAC7Bqd,IAEJ,CAMiCrU,CAAM,CAAEqb,YAAYrkB,GACrD,CChCA,MAAM2a,GAAK,kBAEI,SAAS6J,IAAMb,MAAEA,EAAK9Q,OAAEA,GAAU4R,GAC/C,MAAMnB,EAAW,IAAIzI,IA4BrB,OA1BA8I,EAAM1F,IACJtD,GACA/Q,MAAOqJ,IACL,IAAKA,EAAQ5G,GAAG,OAAQsO,IAAK,OAE7B8J,EAAqB,mBAARA,QAA2BA,IAAQA,EAEhD,MAAMC,QA0BZ,UAA4BzR,QAAEA,EAAOqQ,SAAEA,IACrC,MAAMO,EAAW,GAEXC,EAAS7Q,EAAQjG,SAAS,UAChC,IAAK8W,EAAQ,OAAOD,EAEpB,IAAK,MAAM5Q,KAAW6Q,EAAOlW,mBAAoB,CAC/C,MAAMtB,EAAQ2G,EAAQhH,MAAM0Y,IACtBjB,EAAUJ,EAASha,IAAIgD,GACxBoX,GACLG,EAASriB,KAAKkiB,EAAQ,GAAGzQ,GAC3B,CAEA,OAAOjM,QAAQwT,IAAIqJ,EACrB,CAxCoCe,CAAmB,CAAE3R,UAASqQ,aAE5D,OAAOxP,GACL,OACA,CAAExH,MAAO,mBACTmY,GAAO3Q,GAAI,MAAO,KAAM2Q,MACrBC,IAGNzR,IACC,GAAKA,EAAQ5G,GAAG,SAAhB,CACAwG,EAAO0G,QAAO,GACd,IAAK,MAAMrM,KAAS+F,EAAQrF,mBAAoB,CAC9C,MAAM8V,EAAUJ,EAASha,IAAI4D,EAAMV,SACnCkX,IAAU,KAAKxW,EACjB,CAL0B,IASvB,CACL,GAAA+Q,CAAIgB,EAAIiF,EAAKpkB,GACXwjB,EAASllB,IAAI6gB,EAAI,CAACiF,EAAKpkB,GACzB,EAEJ,mDC1B0B+kB,GAAQC,iBAARD,gBCJlB,SAASE,EAASF,GAOxB,SAASC,IACPxmB,KAAKgkB,OAAS,EAClB,CAiBEwC,EAAQjmB,UAAUof,IAAM,SAAS7Y,EAAMmd,GAMrC,OALKA,IAEHnd,GADAmd,EAAOnd,GACKvG,UAAUuG,MAExB9G,KAAKgkB,OAAO9gB,KAAK,CAAE4D,KAAMA,EAAMmd,KAAMA,IAC9BjkB,IACX,EAeEwmB,EAAQjmB,UAAUikB,OAAS,SAASkC,GAClC,IAAK,IAAIzH,EAAI,EAAG0H,EAAM3mB,KAAKgkB,OAAOhhB,OAAQic,EAAI0H,EAAK1H,IACjD,IAAK,IAAIrH,EAAI,EAAGgP,EAAOF,EAAM1jB,OAAQ4U,EAAIgP,EAAMhP,IAAK,CAClD,IAAIiP,EAAQ7mB,KAAKgkB,OAAO/E,GACxB,GAAI4H,EAAM/f,MAAQ4f,EAAM9O,GACtB,OAAO,IAAIiP,EAAM5C,IAE3B,CAEI,OAAO,IACX,EAEYsC,EAAOE,QAAUD,CAE7B,CAnEIM,CAAQL,ODSsBD,eAEtBD,GAAOE,QAAUD,IACnBA,QAAUA,0BETpB,MAAMnK,GAAK,kBAEI,SAASiJ,IAAKD,MAAEA,EAAK9Q,OAAEA,IACpC,MAAMuP,EAAc,IAAIiD,GAExB,IAAInhB,EAEJ,MAAM0f,EAAO,IAAIxU,eAoGjB,SAASkW,IACP1B,EAAKf,UAAY,KACjBe,EAAKjB,WAAa,EACpB,CAgCA,OAtIAlkB,OAAO6I,OAAOsc,EAAM,CAClBf,UAAW,KACXF,WAAY,GACZ,eAAM4C,CAAUnX,GACdlK,EAAQkK,CACV,EACAxE,WAAgB,SACP1F,EAET,iBAAMshB,GACJthB,EAAQ,IACV,EACA,UAAMuhB,CAAKvhB,GACT,UACQ5F,KAAKinB,UAAUrhB,EACvB,CAAE,MAAO1E,GACPqT,EAAO5C,KAAK,QAASzQ,EACvB,CACF,EACA,WAAMgI,GACJ,IACE,OAAOlJ,KAAKonB,YACd,CAAE,MAAOlmB,GACPqT,EAAO5C,KAAK,QAASzQ,EACvB,CACF,EACA,YAAM,GACJ,UACQlB,KAAKknB,aACb,CAAE,MAAOhmB,GACPqT,EAAO5C,KAAK,QAASzQ,EACvB,CACF,EACA4iB,cACA,UAAM6B,EAAKb,aACTA,EAAYvQ,OACZA,EAAMwQ,UACNA,EAAST,YACTA,EAAWtB,eACXA,EAAcgC,SACdA,IAGA,IAAKM,EAAKf,UACR,OAAO,EAGT,MAAM3e,MAAEA,GAAU0e,EAClB,IAyFC,SAAsB1e,EAAOye,GAClC,IAAKze,EAAO,OAAO,EAGnB,IAAKye,EAAW1J,SAAS/U,EAAM2e,WAC7B,OAAO,EAIT,GAAI,IAAI7hB,KAAKkD,EAAMyhB,SAAW,IAAI3kB,KAChC,OAAO,EAGT,OAAO,CACT,CAvGW4kB,CAAa1hB,EAAO0f,EAAKjB,YAC5B,OAAOkD,IAGT,IAkBE,aAjBMzC,EAAa,CACjBhB,YAAawB,EAAKxB,YAClBS,UAAW3e,EAAM2e,UACjBD,YAAa,IACRA,EACHtY,SAAUpG,EAAMA,OAElBod,eAAgB,IACXA,EACHxN,GAAI,OAAQ,CACVxH,MAAOqO,MAGX9H,SACAwQ,YACAC,cAEK,CACT,CAAE,MAAO9jB,GACP,OACEA,aAAe0iB,IACf,CAAC,iBAAkB,uBAAuBjJ,SAASzZ,EAAIiX,WAEhDoP,KAEThT,EAAO5C,KAAK,QAASzQ,IACd,EACT,CAEAoK,eAAeic,IAGb,aAFMjC,EAAKvF,SAOjB,SAAsBiD,GACpBA,EAAe9f,KACbsS,GAAI,gBAAiB,CACnBxH,MAAOqO,GACPkI,UAAWe,EAAKf,YAGtB,CAbMiD,CAAaxE,IACN,CACT,CACF,IAgBFgE,IAEA3B,EAAM1F,IACJtD,GACA/Q,MAAOqJ,IACL,IAAKA,EAAQ5G,GAAG,OAAQsO,IAAK,OAAO2K,IAEpC1B,EAAKmC,WAAY,EAEjB,MAAMpD,EAAaR,GAAuBlP,EAAS0H,GAAIyH,GACjDS,EAAYF,EAAW,GAE7B,IAAKE,EAAW,OAAOyC,IACvB1B,EAAKjB,WAAaA,EAClBiB,EAAKf,UAAYA,GAInBjZ,MAAOqJ,IACDA,EAAQ5G,GAAG,QAASsO,WAChBiJ,EAAK6B,KAAK,CAGd5C,UAAWe,EAAKf,UAChB3e,MAAO+O,EAAQhH,MAAM/H,MACrByhB,OAAQ1S,EAAQhH,MAAM0Z,WAMvB/B,CACT,2DCrJAoC,GAAiBja,EAAAA,QAAkBia,6CCAnCC,GAAiBla,EAAAA,QAAkBka,uDCCnC,IAAID,EAAaja,KACbka,EAAa/W,KAEjB6V,EAAAmB,IAAc,SAAU9P,EAAGnU,GACzB,IAAInC,EAAM,GACV,GAAIsW,EAAE9U,OAASW,EAAEX,OACf,IAAK,IAAIic,EAAI,EAAGA,EAAItb,EAAEX,OAAQic,IAC5Bzd,EAAI0B,KAAK4U,EAAEmH,GAAKtb,EAAEsb,SAGpB,IAAK,IAAIrH,EAAI,EAAGA,EAAIE,EAAE9U,OAAQ4U,IAC5BpW,EAAI0B,KAAK4U,EAAEF,GAAKjU,EAAEiU,IAGtB,OAAO,IAAI5Q,WAAWxF,EACxB,EAEAilB,EAAAoB,EAAY,SAAUve,GAClB,OAAOoe,EAAW,QAAQI,OAAOxe,GAAMye,QAC3C,EAEAtB,EAAAuB,KAAe,SAAU1nB,EAAK2nB,GAC1B,OAAON,EAAW,OAAQrnB,GAAKwnB,OAAOG,GAAKF,QAC/C,EAEAtB,EAAAyB,GAAa,SAAU5e,EAAM6e,EAAMC,GAC/B,IAAIC,EAAS,IAAIrhB,WAAWmhB,EAAKnlB,OAAS,GAC1CqlB,EAAOvoB,IAAIqoB,GACXE,EAAOvoB,IAAI,IAAIkH,WAAW,CAAC,EAAG,EAAG,EAAG,IAAKmhB,EAAKnlB,QAG9C,IAFA,IAAIslB,EAAM7B,EAAQuB,KAAK1e,EAAM+e,GACzBE,EAAKD,EACArJ,EAAI,EAAGA,EAAImJ,EAAa,EAAGnJ,IAChCqJ,EAAM7B,EAAQuB,KAAK1e,EAAMgf,GACzBC,EAAK9B,EAAQmB,IAAIW,EAAID,GAGzB,OAAOC,CACX,uECtCA,IAAIC,cCAJC,GAAiBhb,EAAAA,QAAkB+a,oBDGnCE,GAAArkB,MAAgB,SAAUskB,GAGtB,IAFA,IAAIC,EAAS,CAAA,EACTC,EAASF,EAAKjH,MAAM,2BACfzC,EAAI,EAAG0H,EAAMkC,EAAO7lB,OAAQic,EAAI0H,EAAK1H,IAAK,CAC/C,IAAI6J,EAAO,yBAAyBC,KAAKF,EAAO5J,IAC5C6J,IACAF,EAAOE,EAAK,IAAMA,EAAK,GAEnC,CACI,OAAOF,CACX,EAEAF,GAAAM,SAAmB,SAAUliB,GAGzB,IAFA,IAAImiB,EAAU,GACVC,EAAO,GACFjK,EAAI,EAAGA,EAAInY,EAAK9D,OAAQic,IAEhB,OADbiK,EAAOpiB,EAAKmY,IAERgK,EAAQ/lB,KAAK,OACG,MAATgmB,EACPD,EAAQ/lB,KAAK,OAEb+lB,EAAQ/lB,KAAKgmB,GAGrB,OAAOD,EAAQrhB,KAAK,GACxB,EAEA8gB,GAAAS,SAAmB,SAAUxC,GACzB,OAAO6B,GAAa7B,GAAO,IAAM,GAAGtlB,SAAS,MACjD,4CEjCA,IAAI+nB,EAAS3b,KACTib,EAAQ9X,KAERyY,EAAO,CAAA,EACPC,EAAa,aACbC,EAAa,aAUjB,SAASC,EAAazc,GACnB,OAAI0W,KACOA,KAAK1W,GAEL0c,OAAOnM,KAAKvQ,GAAG1L,SAAS,SAEtC,CAEA,SAASqoB,EAAU3pB,GACfA,EAAUA,GAAW,CAAA,EACrBC,KAAK2pB,UAAY5pB,EAAQopB,UAAYT,EAAMS,SAC3CnpB,KAAK4pB,OAAS,SAClB,QAGAF,EAAUA,UAAYA,EAGtBA,EAAUnpB,UAAUuG,KAAO,cAC3B4iB,EAAUnpB,UAAUqkB,aAAc,EAGlC8E,EAAUnpB,UAAUiF,SAAW,SAAUqkB,GACrC,OAAOR,EAAKrpB,KAAK4pB,QAAQ5pB,KAAM6pB,EACnC,EAEAH,EAAUnpB,UAAUskB,UAAY,SAAU8D,GACtC,IAnCkB5b,EAmCd+c,EAASpB,EAAMrkB,MAAMskB,GASzB,OAPA3oB,KAAK+pB,OArCahd,EAqCQ+c,EAAO/c,GAAK,GApClC4W,KACO3c,WAAWsW,KAAKqG,KAAK5W,GAAI,SAAShF,GAAK,OAAOA,EAAEC,WAAW,EAAG,GAE9DhB,WAAWsW,KAAKmM,OAAOnM,KAAKvQ,EAAG,YAkC1C/M,KAAKgqB,gBAAkBpnB,SAASknB,EAAO7K,EAAG,IAC1Cjf,KAAKiqB,OAASH,EAAOI,EACrBlqB,KAAKmqB,UAAYL,EAAOzZ,EACxBrQ,KAAKoqB,OAASN,EAAOO,EACrBrqB,KAAKsqB,WAAa3B,EAEX3oB,IACX,EAGAqpB,EAAKkB,QAAU,SAAUtG,EAAM4F,GAC3B5F,EAAKuG,QAAUvG,EAAK0F,YAEpB,IAAIc,EAAU,GACVZ,EAAKY,UACLA,EAAU,KAAO/B,EAAMM,SAASa,EAAKY,UAGzCxG,EAAKyG,WAAa,KAAOD,EAAU,IAEnC,IAAIE,EAAQ,KAAO1G,EAAKuG,QACpBvsB,EAAW,KAAOyqB,EAAMM,SAASa,EAAK5rB,UAAY,IAEtDgmB,EAAK2G,wBAA0B3sB,EAAW,IAAM0sB,EAChD,IAAIzd,EAAS+W,EAAKyG,WAAazG,EAAK2G,wBAIpC,OAFA3G,EAAK2F,OAAS,YAEP1c,CACX,EAGAmc,EAAKxE,UAAY,SAAUZ,EAAM4F,GAC7B,IAIIgB,EAAgBC,EAAWC,EAJ3BC,EAAYxB,EAAavF,EAAKyG,YAElCzG,EAAKgH,gCAAkC,KAAOD,EAAY,MAAQ/G,EAAKgG,OAMnEJ,EAAK1B,MAAQ0B,EAAK1B,KAAK+C,MAAM,SAASnkB,EAAO8B,GAAS,OAAO9B,IAAUkd,EAAK8F,MAAMlhB,EAAO,GACrFghB,EAAKiB,WAAajB,EAAKkB,WACvBD,EAAYjB,EAAKiB,UACjBC,EAAYlB,EAAKkB,WACVlB,EAAKgB,iBACZA,EAAiBhB,EAAKgB,eACtBC,EAAY1B,EAAOpB,KAAK6C,EAAgBvB,GACxCyB,EAAY3B,EAAOpB,KAAK6C,EAAgBtB,KAG5CsB,EAAiBzB,EAAOlB,GAAG2B,EAAK7d,UAAY,GAAIiY,EAAK8F,MAAO9F,EAAK+F,iBACjEc,EAAY1B,EAAOpB,KAAK6C,EAAgBvB,GACxCyB,EAAY3B,EAAOpB,KAAK6C,EAAgBtB,IAG5C,IAAI4B,EAAY/B,EAAOvB,EAAEiD,GACrBM,EAAcnH,EAAK2G,wBAA0B,IAC/B3G,EAAKqG,WAAa,IAClBrG,EAAKgH,gCACnBI,EAAkBjC,EAAOpB,KAAKmD,EAAWC,GAEzCE,EAAc9B,EAAa3hB,OAAO0jB,aAAaC,MAAM,KAAMpC,EAAOxB,IAAIkD,EAAWO,KAErFpH,EAAKwH,iBAAmBrC,EAAOpB,KAAK+C,EAAWK,GAE/C,IAAIle,EAAS+W,EAAKgH,gCAAkC,MAAQK,EAW5D,OATArH,EAAK2F,OAAS,QAEd3F,EAAKyH,MAAQ,CACTvD,KAAMlE,EAAK8F,MACXc,eAAgBA,EAChBC,UAAWA,EACXC,UAAWA,GAGR7d,CACX,EAEAmc,EAAKnE,MAAQ,WAET,MAAO,EACX,EAIAyG,GAAiBjC,eClIF,SAASiC,GAAczH,GACpCA,EAAKvE,IAAIsE,GACX,iECQQ,SAASwC,EAASF,EAAQmD,IAEtBnD,EAAOE,QAAUiD,GACnBA,UAAYA,CAEtB,CAdI5C,CAAQL,gBCKJ,SAASA,EAASF,GAgBxB,SAASmD,IACX,CAEEA,EAAUnpB,UAAUuG,KAAO,QAC3B4iB,EAAUnpB,UAAUqkB,aAAc,EAalC8E,EAAUnpB,UAAUiF,SAAW,SAASqkB,GACtC,IAAItmB,EAAM,GAMV,OALAA,GAAOsmB,EAAKY,SAAW,GACvBlnB,GAAO,KACPA,GAAOsmB,EAAK5rB,UACZsF,GAAO,MACAsmB,EAAK7d,QAEhB,EASE0d,EAAUnpB,UAAUskB,UAAY,SAAS8D,GACvC,OAAO3oB,IACX,EAEYumB,EAAOE,QAAUiD,CAE7B,CA7DI5C,CAAQL,2CCDG,SAASmF,GAAU1H,GAChCA,EAAKvE,IAAIsE,GACX,iECQQ,SAASwC,EAASF,EAAQmD,IAEtBnD,EAAOE,QAAUiD,GACnBA,UAAYA,CAEtB,CAdI5C,CAAQL,gBCKJ,SAASA,EAASF,GAexB,SAASmD,IACX,CAEEA,EAAUnpB,UAAUuG,KAAO,YAC3B4iB,EAAUnpB,UAAUqkB,aAAc,EAWlC8E,EAAUnpB,UAAUiF,SAAW,SAASqkB,GACtC,OAAOA,EAAKgC,OAAS,EACzB,EAQEnC,EAAUnpB,UAAUskB,UAAY,SAAS8D,GAC3C,EAEYpC,EAAOE,QAAUiD,CAE7B,CAlDI5C,CAAQL,2CCIG,SAASqF,GAAc5H,GACpCA,EAAKvE,IAAIsE,GACX,CCJO,SAASyF,KAAa,UCFbqC,GAAqBzH,EAA+B,CAAA,EAAIS,GACtE,OAAOzZ,kBAAiCrK,GACtC,MAAO6jB,EAAcT,EAAYiB,EAAM/Q,GAAUtT,EAEjD,GAA2B,mBAAhBqjB,EAA4B,CACrC,MAAMC,EAAYyH,GAAa3H,EAAY9P,SAErC+P,EAAYQ,EAAcP,EAClC,KAAO,CACLD,EAAY1e,cAAgB0f,GAAMpc,SAElC,MAAMqb,EAAYyH,GAAa3H,EAAY9P,EAAQ+P,SAE7CQ,EAAaR,EAAaC,EAAWQ,EAC7C,CACF,CACF,UAEgBiH,GAAa3H,EAAsB9P,EAAoBxU,GACrE,MAAM9B,EAAW8B,GAAS9B,UAAYsW,EAAOxU,SAAS9B,SAChD+N,EAAWjM,GAASiM,UAAYuI,EAAOxU,SAASiM,SAChDpG,EAAQ7F,GAAS6F,OAAS2O,EAAOxU,SAAS6F,MAEhD,OAAK3H,GAAa+N,GAAapG,IAASye,EAAW1J,SAAS,aAIxDpG,EAAO8E,YAAc9E,EAAO0X,WAAmB5H,EAAW,GAEvDA,EAAWrH,KAAMuH,GAA4B,UAAdA,IAA0B,GALvD,WAMX,UAQgB2H,GAAiB3F,KAAqCtlB,GACpE,GAAsB,mBAAXslB,EAIX,OAAOA,KAAUtlB,EACnB,CDxCAyoB,GAAUnpB,UAAUmpB,UAAYA,GAChCA,GAAUnpB,UAAUuG,KAAO,kBAC3B4iB,GAAUnpB,UAAUqkB,aAAc,EAElC8E,GAAUnpB,UAAUiF,SAAW8F,gBAAwBrN,SAAEA,EAAQ+N,SAAEA,IACjEhM,KAAKM,UAAY6rB,OAAOC,OAAOC,UAC7B,OACA,IAAIC,aAAc/I,OAAOvX,GAEzB,CAAElF,KAAM,OAAQylB,KAAM,YACtB,EACA,CAAC,OAAQ,WAEX,MAAMC,QAAkBL,OAAOC,OAAOK,KACpC,OACAzsB,KAAKM,KACL,IAAIgsB,aAAc/I,OAAO,cAE3B,MAAO,GAAGtlB,MAAa4J,OAAO+E,iBAAiB,IAAI5F,WAAWwlB,KAChE,EAEA9C,GAAUnpB,UAAU2kB,MAAQ5Z,eAAqBxM,GAC/C,MAAM0tB,EAAYxlB,WAAWsW,KAAKxe,EAAOiJ,GAAMA,EAAE2kB,YAAY,IAQ7D,IAAe,UANMP,OAAOC,OAAOO,OACjC,OACA3sB,KAAKM,IACLksB,GACA,IAAIF,aAAc/I,OAAO,cAGzB,MAAM,IAAI1Y,MAAM,0CAEpB,EEpCc,MAAO+hB,GACnB,mBAAOC,CAAaznB,EAA6B,IAC/C,MAAMH,OAAEA,EAAMvD,SAAEA,EAAQgW,IAAEA,GAAQtS,EAC5B1I,EAAQmE,EAAOpE,MAAMC,MACrB4I,EAAMzE,EAAOjE,UAAUE,KAE7B,OAAOmI,EAAS,GAAGA,KAAUvI,KAAS4I,IAAM5D,EAAW,IAAIA,IAAa,KAAOgW,CACjF,CAEA,4BAAOoV,CAAsB7nB,GAC3B,MAAO,GAAGA,KAAUpE,EAAOpE,MAAMC,OACnC,CAEA,0BAAOqwB,CAAoBpf,GACzB,OAAO6H,GAAI,UAAW7H,EACxB,CAEA,qBAAOqf,CAAerf,GACpB,OAAO6H,GAAI,KAAM7H,EACnB,CAEA,2BAAOsf,CAAqBtf,GAC1B,OAAO6H,GAAI,WAAY7H,EACzB,CAEA,kBAAOuf,CAAYpmB,EAAc6G,GAC/B,OAAO6H,GAAI1O,EAAM6G,EACnB,CAEA,cAAOc,CAAQkG,EAAsC7N,GACnD,OAAO6N,GAASlG,QAAQ3H,IAAS6N,GAAShH,MAAM7G,IAAS,EAC3D,CAEA,iBAAOqmB,CAAWxY,EAAsC7N,GACtD,OAAO6N,GAASjG,SAAS5H,EAC3B,CAEA,cAAOmH,CAAQ0G,GACb,OAAOA,GAAS1G,WAAa,IAC/B,CAEA,cAAOmB,CAAQuF,GACb,OAAOA,GAASvF,WAAa,IAC/B,CAEA,uBAAOE,CAAiBqF,GACtB,OAAOA,GAASrF,oBAAsB,EACxC,CAEA,oBAAO8d,CAAczY,GACnB,QAASA,GAASjG,SAAS,QAC7B,CAEA,qBAAO2e,CAAe1Y,EAA0B7N,GAC9C,OAAO6N,GAAShG,YAAY7H,IAAS,EACvC,CAEA,qBAAOwmB,CAAe3Y,EAA0B7N,GAC9C,OAAO6N,GAAStF,aAAavI,IAAS,IACxC,CAEA,yBAAOymB,CAAmB5Y,EAA0B6Y,GAClD,OAAOA,EAAaC,OAClB,CAACC,EAA0C5mB,IACzC4mB,EAAcd,GAAUO,WAAWO,EAAa5mB,QAAQpL,EAC1DiZ,EAEJ,CAEA,wBAAOgZ,CAAkBhZ,EAA0B3S,EAAkB8E,GAkBnE,OAjBA6N,EAAUA,EAAQ5M,EAAEjB,GAEpB3G,OAAOC,KAAK4B,GAAK3B,QAASC,IACxB,MAAMwO,EAAM9M,EAAI1B,GAEJ,OAARwO,GAA+B,iBAARA,EACzB8d,GAAUe,kBAAkBhZ,EAAS7F,EAAKxO,GAE1CqU,EAAUA,EACP5M,EAAEzH,GACFwP,EAAEjI,OAAOiH,GAAO,KAChBU,OAIPmF,EAAUA,EAAQnF,IAGpB,CAEA,6BAAOoe,CAAuBjZ,EAA0BhT,GACtD,IAAIksB,EAAcjB,GAAUO,WAAWxY,EAAS,eAqBhD,OAnBAxU,OAAOC,KAAKuB,GAAWtB,QAASC,IAC9B,MAAMwO,EAAMnN,EAAUrB,GAEV,gBAARA,GAAyBwB,MAAMF,QAAQkN,GACzCA,EAAIzO,QAASytB,IACXD,EAAa9lB,EAAE,aAAc+lB,GAA4Bte,OAE1C,OAARV,GAA+B,iBAARA,EAChC8d,GAAUe,kBAAkBE,EAAc/e,EAAoBxO,GAE9DutB,EACG9lB,EAAEzH,GACFwP,EAAEjI,OAAOiH,GAAO,KAChBU,OAIPmF,EAAQnF,KAEDmF,CACT,CAEA,wBAAOoZ,CAAkBpZ,EAA0B3S,GACjD,MAAM6L,SAAEA,EAAQ/G,KAAEA,GAAS6N,EACrBjO,EAAoB,CAAEI,CAACA,GAAO,IAYpC,OAVA+G,EAASxN,QAASsP,IACI,iBAATA,EACRjJ,EAAqBI,GAAQ6I,EACrBA,EAAK9B,SAAS7K,OAAS,EAChC4pB,GAAUmB,kBAAkBpe,EAAOjJ,EAAKI,IAAyB,CAAA,IAE/DJ,EAAKI,IAAyB,IAAI6I,EAAK7I,MAAQ8lB,GAAUxd,QAAQO,KAIhExP,OAAO6I,OAAOhH,EAAK0E,EAC5B,CAEA,uBAAOsnB,CAAiBrZ,GACtB,IAAKA,EACH,OAAO,KAGT,MAAMhT,EAAmC,CAAEssB,YAAa,IACxD,IAAIC,EAA0B,KAgC9B,OA9BAvZ,EAAQ9G,SAASxN,QAASsP,IACxB,GAAoB,iBAATA,EAAX,CAIA,GAAkB,eAAdA,EAAK7I,KAAuB,CAC9B,MAAMgnB,EAA0B,CAAA,EAEhC3tB,OAAOC,KAAKuP,EAAKhC,OAAOtN,QAASC,IAC/BwtB,EAAWxtB,GAAe,SAARA,EAAiBsC,SAASiF,OAAO8H,EAAKhC,MAAMlK,MAAO,IAAMkM,EAAKhC,MAAMrN,KAGxFqB,EAAUssB,YAAa/qB,KAAK4qB,EAC9B,KAAyB,cAAdne,EAAK7I,OACdonB,EAAWtB,GAAUU,eAAe3Y,EAAS,aAC7ChT,EAAUwsB,UAAYD,QAAYxyB,GAGhCiU,EAAK9B,SAAS7K,QAChB4pB,GAAUmB,kBAAkBpe,EAAMhO,EAhBpC,IAoBEG,MAAMF,QAAQD,EAAUssB,cAAiD,IAAjCtsB,EAAUssB,YAAYjrB,eACzDrB,EAAUssB,YAEftsB,EAAUysB,yBACLzsB,EAAUysB,iBAGZ,CAAEzsB,YAAWusB,WACtB,CAEA,oCAAOG,CAA8BC,GACnC,MAAMC,EAAe3B,GAAUO,WAAWmB,EAAa,SAGvD,MAAO,CAAE1kB,KAFI2kB,EAAe3rB,SAASgqB,GAAUne,QAAQ8f,EAAc,SAAW,IAAK,IAAM,EAEtErkB,KADRqkB,EAAe3B,GAAUU,eAAeiB,EAAc,QAAU,KAE/E,CAEA,kBAAOC,CAAYC,GACjB,MAAMC,EAAO,uCAAuCtqB,QAAQ,QAAU2D,IACpE,MAAMmiB,EAAqB,GAAhB9nB,KAAKE,SAAiB,EAEjC,OADe,KAALyF,EAAWmiB,EAAS,EAAJA,EAAW,GAC5B7oB,SAAS,MAGpB,MAAsB,iBAAXotB,GAAyC,iBAAXA,EAChC,GAAGC,KAAQD,IAEXC,CAEX,CAEA,qBAAOC,CAAeha,GAOpB,OANkBiY,GAAUtd,iBAAiBqF,GAASzB,IAAKvD,IAAqB,CAC9EkN,IAAwC,SAAnC+P,GAAUne,QAAQkB,EAAM,OAC7BI,OAA8C,SAAtC6c,GAAUne,QAAQkB,EAAM,UAChCif,SAAUhC,GAAUne,QAAQkB,EAAM,WAGnB8d,OAAO,CAACoB,GAAShS,MAAK9M,SAAQ6e,eACzC/R,EACFgS,EAAW,IAAID,EACN7e,IACT8e,EAAc,OAAID,GAEbC,GACN,CAAA,EACL,GC3KAhuB,EAAO/D,KAAKU,SAAWzE,EAASE,WACC,IAAzBuqB,WAAW3F,gBAAsD,IAAlBiR,EAAAA,WAEvDtL,WAAW3F,UAAYiR,EAAAA,SAGzB,MAAMC,gBAAEA,GAAeC,gBAAEA,IAAoBC,SAASC,KAAO,CAAA,EACvDjD,KAAe8C,GACfI,KAAeH,GAoDrB,SAASI,GAAWrvB,GAClB,IAAI2B,SAAEA,EAAQ4iB,YAAEA,EAAWrmB,SAAEA,EAAQ+N,SAAEA,EAAQ+Y,UAAEA,KAAc3f,GAAWrF,EAE1E,MAAMkW,OAAEA,EAAMyE,QAAEA,GAAYtV,GAEvB6Q,GAAUyE,IACbtV,EAAO6Q,OFzEL,SAAoByE,GAGxB,OAFeA,EAAQgH,MAAM,OAAO,IAAMhH,GAE5BgH,MAAM,KAAK,GAAGA,MAAM,KAAK,EACzC,CEqEoBpK,CAAUoD,IAG5B,MAAMnG,EAAS,IAAI0I,GAAO7X,GAEtBnH,GAAYmH,EAAO6Q,SACrB1B,EAAOmD,IAAMA,GAAIzZ,EAAUmH,EAAO6Q,SAGpC,MAAM3Y,ErD/DO,UAAmBiX,OAAEA,IAClC,MAAM2V,EAAI,IAAI3M,GAAUhJ,GAExB,OADA2V,EAAE/c,QACK+c,CACT,CqD2DoBmF,CAAW,CAAE9a,WACzBrX,ECpHO,UAAmBqX,OAAEA,IAClCA,EAAO2I,WAAWha,KAAK+a,GACzB,CDkHoBqR,CAAW,CAAE/a,WACzBgK,EAAM2N,GAAiBD,GAAasD,QAAO7zB,EAAW,CAAE6Y,WACxDiK,EAAM0N,GAAiBiD,GAAaK,QAAO9zB,EAAW,CAAE6Y,WACxDsK,EtCrGO,UAAoBtK,OAAEA,IACnC,MAAMkb,EAAW,CAAClQ,GAAahL,IACzBmb,EAAW,GAEXC,EAAmBlb,GAASF,EAAQkb,EAAUtQ,IAC9CyQ,EAAmBnb,GAASF,EAAQmb,EAAUtQ,IAKpD,OAHA7K,EAAOlV,GAAG,UAAWswB,GACrBpb,EAAOlV,GAAG,OAAQuwB,GAEX,CACLjQ,IAAI5B,IACF0R,EAASvsB,KAAK6a,GACPA,GAET5O,OAAO4O,IACL2R,EAASxsB,KAAK6a,GACPA,GAGb,CsCiFqB8R,CAAY,CAAEtb,WAC3ByO,EEnHO,UAAwBnE,WAAEA,IAYvC,MAAO,CACLc,IAZF,SAAa7Y,EAAMkH,EAAO8F,GACxB,OAAO+K,EAAWc,IAAI,CAACN,EAAKN,KAC1B,MAAMvK,OAAEA,GAAW6K,EACnB,IAAK7K,EAAOzG,GAAG,WAAY,oCACzB,OAAOgR,IACT,MAAMqG,EAAU5Q,EAAO9F,SAAS5H,EAAMkH,GACtC,OAAKoX,EACEtR,EAAQuL,EAAKN,EAAMqG,GADLrG,KAGzB,EAKF,CFoGyB+Q,CAAgB,CAAAjR,WAAEA,IACnCkH,EpC7CO,YAAqB9kB,GAClC,MAAM8kB,EAAW,IAAIrG,MAAYze,GAEjC,OADA8kB,EAAS5Y,QACF4Y,CACT,CoCyCmBgK,CAAU,YAAElR,EAAYtK,WACnCyb,ElCvBO,UAAkBnR,WAAEA,EAAUtK,OAAEA,IAG7C,OAFAsK,EAAWc,IAAIY,GAAUhM,IAElB,CACL,GAAAvJ,CAAI2V,EAAI7Z,EAAMgN,GACZ+K,EAAWc,IAAIjV,GAAM,MAAOiW,EAAI7Z,EAAMgN,GACxC,EACA,GAAAhU,CAAI6gB,EAAI7Z,EAAMgN,GACZ+K,EAAWc,IAAIjV,GAAM,MAAOiW,EAAI7Z,EAAMgN,GACxC,EAEJ,CkCYmBmc,CAAU,YAAEpR,EAAYtK,WACnC5L,EAAU8Z,GAAS,CAAElO,WAGrBuP,EAAc,IAAIiD,GAClB1C,EAAalkB,OAAOwQ,QAAQ,CAAyCuf,UAAEA,GAAYC,MAAEA,GAAKC,UAAEA,KAAald,IAC7G,EAAE9C,EAAGC,MAAE,CAAQD,CAACA,GAAIC,EAAEyT,MAGxBiB,IAAcvP,GAAI,aAAc,CAAE7J,GAAIihB,GAAU4B,gBAGhD,MAAMzL,EAAWmJ,GAAiBiD,GAAakB,QAAY30B,EAAW,CAAAsnB,eAAEA,IAClEqC,EAAQiL,GACZ,CAAAtN,eAAEA,EAAgBc,eAClBiI,GAAqBzH,GAAe,CAAErmB,WAAU+N,YAAY+Y,IAGxDO,EAAOQ,GAAM,OAAET,EAAO9Q,WAE5B8Q,EAAMQ,MAAM,CAAAP,KAAEA,IAGd,MAAMY,EAAQqK,GAAO,CAAAlL,MAAEA,EAAO9Q,UAAU7S,IHzG3B,SAAyBwiB,GACtCA,EAAKvE,IAAI+J,GACX,CG0GE8G,CAAalL,EAAKxB,aAGlB,MAAMI,EAAOuM,GACX,CAAAzN,eAAEA,EAAgBc,eAClBiI,GAAqBzH,GAAe,CAAErmB,WAAU+N,YAAY+Y,IAExDkB,EAAkByK,GAAiB,CAAA3K,SAAEA,EAAQ/C,eAAEA,GAAkBthB,GAEvEsuB,GAAUhlB,IAAI,gBAAiB,OAAQ,KAAA,CAAS,IAchD,OAAO7K,OAAO6I,OAAOuL,EAAQ,CAC3BA,mBACAjX,MACAihB,YACArhB,MACAshB,aACAK,iBACAmE,WACA+C,WACAiK,UACArnB,WACAoa,EACAe,oBACAuB,OACAnB,kBACA+B,EACA5B,mBACA6B,OACAZ,EACAqL,WA/BiB,SAAUhc,KAAqB1T,GAChD,GAAsB,WAAlBsT,EAAOvK,OACT,OAAOuK,EAAOK,KAAKnU,KAAK8T,EAAQI,KAAY1T,GACvC,CACL,MAAM4K,EAAU,sEAIhB,OAFA/K,GAAMgC,KAAK,gBAAiB+I,GAErBnD,QAAQE,OAAO,IAAIiC,MAAMgB,GAClC,CACF,EAsBEogB,cACAkD,eAEJ,CGhMc,MAAOyB,GACZC,QAAkB,GAEzB,kBAAWC,GACT,OAAO9wB,KAAK6wB,OACd,CAEA,kBAAWC,CAAepZ,GACxB1X,KAAK6wB,QAAUnZ,GAAO,EACxB,CAEO8W,YAAc5B,GAAU4B,YAExB,SAAAuC,CAAUhqB,GACf,MAAO,UAAUoX,KAAKpX,IAAU,aAAaoX,KAAKpX,EACpD,CAEO,WAAAiqB,CAAYA,GACjB,MAA2B,iBAAhBA,EACFhxB,KAAK+wB,UAAUC,GAClBhxB,KAAKixB,WAAWD,GAChBA,EAAYrW,SAAS,KACnBqW,EACAhxB,KAAKkxB,uBAAuBF,GAG7BhxB,KAAKixB,WAAWD,EACzB,CAEO,QAAAG,CAASH,GACd,cAAeA,GACb,IAAK,SACH,OAAOhxB,KAAK+wB,UAAUC,GAClB,OACAA,EAAYrW,SAAS,KACnBqW,EAAYrW,SAAS,OACnB,YACA,OACF,YACR,IAAK,SACH,MAAO,OACT,QACE,MAAM,IAAI9P,MAAM,yBAEtB,CAEO,UAAAomB,CAAWhsB,GAChB,MAAO,GAAGA,KAAUpE,EAAOpE,MAAMC,SAASmE,EAAOjE,UAAUE,MAC7D,CAEO,wBAAAs0B,CAAyBnsB,GAC9B,MAAO,GAAGpE,EAAOjE,UAAUG,OAAOkI,GACpC,CAEO,gBAAAosB,CAAiB3Z,EAAc1X,KAAK8wB,gBACzC,OAAOpZ,GAAKiD,SAAS,KAAO/X,SAAS8U,EAAIgK,MAAM,KAAK,GAAGA,MAAM,KAAK,IAAM,IAC1E,CAEO,kBAAA4P,CAAmB5Z,GACxB,OAAOA,GAAKiD,SAAS,KAAOjD,EAAIgK,MAAM,KAAK,GAAGA,MAAM,KAAK,GAAK,IAChE,CAEO,sBAAAwP,CAAuBhD,GAC5B,MAAO,GAAGrtB,EAAOpE,MAAMC,SAASwxB,KAAYrtB,EAAOjE,UAAUG,KAC/D,CAEO,UAAAw0B,CAAW7Z,GAChB,MAAO,GAAGA,KAAO1X,KAAKqxB,iBAAiBrxB,KAAK8wB,iBAC9C,CAEO,iBAAAU,CAAkB9Z,GACvB,MAAMtQ,EAAQsQ,EAAIgK,MAAM,KACxB,OAAOta,EAAMpE,OAAS,EAAIJ,SAASwE,EAAMuF,MAAM,GAAG/E,KAAK,MAAQ,IACjE,CAEO,yBAAA6pB,CAA0B/Z,GAC/B,MAAMtQ,EAAQsQ,EAAIgK,MAAM,KACxB,OAAOta,EAAMpE,OAAS,EAAIoE,EAAM,GAAK,IACvC,CAEOnF,gBAAkBnB,GAAMmB,gBAExB,oBAAAyvB,CAAqBC,GAC1B,MAAMvqB,EAAQuqB,EAAQjQ,MAAM,KAC5B,OAAOta,EAAMpE,OAAS,EAAIJ,SAASwE,EAAMA,EAAMpE,OAAS,IAAM,IAChE,CAEA,YAAA4uB,CAAaC,GACX,OAAOA,EAAW/rB,QAAQ,KAAO,EAAI+rB,EAAa7xB,KAAKkxB,uBAAuBW,EAChF,ECtFF,MAAMC,GACI,SADJA,GAEK,UAFLA,GAGK,IAHLA,GAII,IAGI,MAAOC,GASCj1B,KARXkR,MAAQ,gBAETgkB,SAAmB,EACnBC,qBAA+B,EAC/BC,qBAA+B,EAC/BC,cAAyC,IAAI1V,IAC7C2V,wBAER,WAAAzyB,CAAoB7C,GAAAkD,KAAAlD,KAAAA,CAAwB,CAE5C,aAAWu1B,GACT,OAAOxxB,EAAO7D,aAAaG,SAAW9E,EAAaE,KAAOsI,EAAO/D,KAAKM,kBAAkBC,SAAU,EACpG,CAEO,KAAA8P,GACLnN,KAAKgyB,SAAU,EAEXhyB,KAAKqyB,YACPryB,KAAKsyB,uBACLtyB,KAAKuyB,oBACLvyB,KAAKwyB,UAAUV,IAEnB,CAEO,IAAAnW,GACL3b,KAAKgyB,SAAU,EAEXhyB,KAAKqyB,YACPryB,KAAKsyB,uBACLtyB,KAAKyyB,0BAET,CAEO,kBAAMC,CAAale,EAAyB3I,GACjD,MAAMzM,EAAOwtB,GAAUne,QAAQ+F,EAAQ,QACjC9Q,EAAOkpB,GAAUU,eAAe9Y,EAAQ,QACxCyZ,EAAcrB,GAAUS,eAAe7Y,EAAQ,cAC/Cme,EAA4B,YAAhBne,EAAO1N,KACnB8rB,EAASxzB,IAASvI,EAASC,MAAQsI,IAASvI,EAASE,UACrD87B,EAAYx2B,QAAQqH,GAAQuqB,EAAYjrB,QAE9C,UACQhD,KAAKlD,KAAKsyB,WAAWuB,WAAWnc,GAElCxU,KAAKgyB,SAAWW,GAAaC,GAAUC,IACzC7yB,KAAKmyB,cAActV,IAAIhR,GACvB7L,KAAKwyB,UAAUV,IAEnB,CAAE,MACA9xB,KAAK8yB,kBAAkBjnB,EACzB,CACF,CAEQknB,eAAkBve,IACxB,MAAO1N,EAAMkH,GAAS,CAACwG,EAAO1N,KAAM8lB,GAAUne,QAAQ+F,EAAQ,UAE9D,GAAIxG,IAAUhO,KAAKgO,OAASlH,IAASgrB,GAInC,OAHA9xB,KAAKiyB,qBAAuB,EAC5BjyB,KAAKkyB,qBAAuB,OAC5BlyB,KAAKgyB,SAAU,GAMjB,GAFIhkB,IAAUhO,KAAKgO,OAAOhO,KAAKiyB,uBAE3BnrB,IAASgrB,IAKb,GAAIhrB,IAASgrB,GAAkB,CAC7B,MAAMkB,EAAqBpwB,SAASgqB,GAAUne,QAAQ+F,EAAQ,KAAM,IAC9Dye,EAAqBxc,OAAOyc,MAAMF,GAAsBhzB,KAAKkyB,qBAAuBc,EACpFG,EAAqBF,EAAqBjzB,KAAKkyB,qBAErDlyB,KAAKkyB,qBAAuBe,EAC5BjzB,KAAKozB,wBAAwBD,GAC7BnzB,KAAKqzB,kCACP,OAZErzB,KAAKwyB,UAAUV,KAeX,iBAAAwB,CAAkBznB,GACxB/K,GAAMC,iBAAiBf,KAAKlD,KAAKy2B,sBAAjCzyB,CAAwD,KAAM+K,GAC9D7L,KAAKmyB,cAAcpS,OAAOlU,EAC5B,CAEQ,iBAAAinB,CAAkBjnB,EAA6B2nB,GAAiB,GACtE1yB,GAAMC,iBAAiBf,KAAKlD,KAAKy2B,sBAAjCzyB,CAAwD+K,EAAS,MAC7D2nB,GAAOxzB,KAAKmyB,cAAcpS,OAAOlU,EACvC,CAEQ,uBAAAunB,CAAwBhL,EAAqB,GACnD,MAAMqL,EAAWzzB,KAAKmyB,cAAcrI,SAEpC,IAAK,IAAI7K,EAAI,EAAGA,EAAImJ,EAAYnJ,IAAK,CACnC,MAAMvK,KAAEA,EAAI3N,MAAEA,GAAU0sB,EAAS1U,OACjC,GAAIrK,EAAM,MACV1U,KAAKszB,kBAAkBvsB,EACzB,CACF,CAEQ,uBAAA0rB,GACNxf,aAAajT,KAAKoyB,yBAClBpyB,KAAKoyB,6BAA0B12B,EAE3BsE,KAAKmyB,cAAc1uB,KAAO,IAC5BzD,KAAKmyB,cAAc9xB,QAASwL,IAC1B7L,KAAK8yB,kBAAkBjnB,GAAS,KAElC7L,KAAKmyB,cAAcqB,QAEvB,CAEQ,gCAAAH,GACN,MAAMK,EAA4E,KAA9D7yB,EAAO/D,KAAKM,kBAAkBu2B,wBAA0B,IAE5E1gB,aAAajT,KAAKoyB,yBAClBpyB,KAAKoyB,wBAA0Bvf,WAAW,KACxC7S,KAAKyyB,2BACJiB,EACL,CAEQ,SAAAlB,CAAU1rB,GAChB,MAAM6G,EACJ7G,IAASgrB,GAAmB,CAAE9jB,MAAOhO,KAAKgO,MAAOnK,EAAGgE,OAAO7H,KAAKiyB,uBAA0B,CAAEjkB,MAAOhO,KAAKgO,OACpG4lB,EAAQhH,GAAUM,YAAYpmB,EAAM6G,GAE1C,OAAO3N,KAAKlD,KAAKsyB,WAAWuB,WAAWiD,EACzC,CAEQ,oBAAAtB,GACNtyB,KAAKlD,KAAKsyB,WAAWzb,eAAe,UAAW3T,KAAK+yB,eACtD,CAEQ,iBAAAR,GACNvyB,KAAKlD,KAAKsyB,WAAW/vB,GAAG,UAAWW,KAAK+yB,eAC1C,ECjJY,MAAOc,GACV7lB,MAAQ,oBACV8lB,QACA1E,WACA2E,iBAEP,WAAAp0B,CAAYI,GACVC,KAAK8zB,QAAU/zB,EAAQ+zB,QACvB9zB,KAAKovB,WAAarvB,EAAQqvB,WAC1BpvB,KAAK+zB,iBAAmBh0B,EAAQg0B,gBAClC,CAEO,YAAMvP,CAAO5Z,GAClB,OAAO,IAAIlC,QAAQ,CAACC,EAASC,KAC3B,MAAMorB,EAAcppB,EAAKikB,MAAMpB,OAC7B,CAACwG,GAAOnvB,UAASovB,SAAQC,kBACvBF,EAAInvB,GAAW,CAAEovB,SAAQC,eAClBF,GAET,CAAA,GAGIG,EAAkBj0B,OAAOC,KAAK4zB,GAC9BK,EAAW,CACfj1B,KAAM,MACNke,KAAMtd,KAAK8zB,QAAQhD,eACnBnlB,GAAIihB,GAAU4B,YAAY,SAG5B,IAAI8F,EAAK1H,GAAUI,eAAeqH,GAElCC,EAAGvsB,EAAE,QAAS,CAAEiG,MAAOhO,KAAKgO,QAASjG,EAAE,OAAQ,CAAEjB,KAAM8D,EAAK9D,OAE5D,IAAK,IAAI+B,EAAQ,EAAG+O,EAAI,EAAG+O,EAAMyN,EAAgBpxB,OAAQ6F,EAAQ8d,EAAK9d,IAAS+O,GAAQ,EAAG,CACxF,MAAM3S,EAASmvB,EAAgBvrB,IACzBqrB,OAAEA,EAAS,GAAEC,YAAEA,GAAc,GAAUH,EAAY/uB,GACnDsvB,EAAWJ,GAA0B,SAAXD,EAC1BM,EAAUx0B,KAAK8zB,QAAQ9C,YAAYpuB,SAASqC,EAAQ,KACpDwvB,EAAUz0B,KAAK8zB,QAAQ1C,yBAAyBnsB,GAEtDjF,KAAK00B,kBAAkBJ,EAAI,CAAEK,MAAO/c,EAAI,EAAG7Q,MAAOytB,EAASN,SAAQK,aACnEv0B,KAAK00B,kBAAkBJ,EAAI,CAAEK,MAAO/c,EAAI,EAAG7Q,MAAO0tB,EAASP,SAAQK,YACrE,CAEAv0B,KAAK+zB,iBAAiBM,EAAS1oB,IAAO6I,IACpCoY,GAAUQ,cAAc5Y,GAAU5L,EAAOgkB,GAAUyB,8BAA8B7Z,IAAW7L,KAG9F3I,KAAKovB,WAAWuB,WAAW2D,IAE/B,CAEO,aAAMM,CAAQ9tB,GACnB,OAAO,IAAI4B,QAAQ,CAACC,EAASksB,KAC3B,MAAMlpB,EAAKihB,GAAU4B,YAAY,WAC3B8F,EAAK1H,GAAUI,eAAe,CAClC5tB,KAAM,MACNke,KAAMtd,KAAK8zB,QAAQhD,eACnBnlB,OAGF2oB,EAAGvsB,EAAE,QAAS,CAAEiG,MAAOhO,KAAKgO,QAASjG,EAAE,OAAQ,CAAEjB,SAEjD9G,KAAK+zB,iBAAiBpoB,GAAO6I,IAC3B,MAAMsgB,EAAQtgB,EAASoY,GAAUO,WAAW3Y,EAAQ,cAAW9Y,EACzDkP,EAAOkqB,EAAQlI,GAAUO,WAAW2H,EAAO,aAAUp5B,EAErDs4B,EAAgC,CACpCltB,KAAM8lB,GAAUne,QAAQ7D,EAAM,QAC9BikB,MAAOjC,GAAUtd,iBAAiB1E,GAC/BsI,IAAI,CAACxM,EAAMmC,KACV,GAAIA,EAAQ,GAAM,EAAG,CACnB,MAAMqrB,OAAEA,EAAMntB,MAAEA,GAAUL,EAAKiH,MAC/B,MAAO,CACL7I,QAAS9E,KAAK8zB,QAAQzC,iBAAiBtqB,GACvCmtB,OAAQA,EAEZ,CACA,OAAO,OAER/kB,OAAQzI,GAAkB,OAATA,IAGtBiC,EAAQqrB,UAEDh0B,KAAK+zB,iBAAiBpoB,IAG/B3L,KAAKovB,WAAWuB,WAAW2D,IAE/B,CAEO,YAAMxM,CAAOld,GAClB,IACE,MAAMmqB,QAAoB/0B,KAAK40B,QAAQhqB,EAAK9D,MACtCoM,EAAM,IAAIqJ,IAAIwY,EAAYlG,MAAM3b,IAAK8hB,GAAoB,CAACA,EAAgBlwB,QAASkwB,KAEzF,IAAK,MAAMtuB,KAAQkE,EAAKikB,MACtB,GAAInoB,EAAKwtB,SAAWh8B,EAAkBC,MACpC+a,EAAI6M,OAAOrZ,EAAK5B,aACX,CACL,MAAMmwB,EAAc90B,OAAO6I,OAAO,CAAA,EAAIkK,EAAIlI,IAAItE,EAAK5B,SAAU4B,GAC7DwM,EAAIpT,IAAI4G,EAAK5B,QAASmwB,EACxB,CAGF,MAAMC,EAAmBpzB,MAAMwb,KAAKpK,EAAI4W,UAClCqL,EAAc,CAAEruB,KAAM8D,EAAK9D,KAAM+nB,MAAOqG,SAExCl1B,KAAKwkB,OAAO2Q,EACpB,CAAE,MAAO/zB,GACP,MAAMA,CACR,CACF,CAEO,cAAMg0B,GACX,OAAO,IAAI1sB,QAAQ,CAACC,EAASC,KAC3B,MAAM+C,EAAKihB,GAAU4B,YAAY,YAC3B8F,EAAK1H,GAAUI,eAAe,CAClC5tB,KAAM,MACNke,KAAMtd,KAAK8zB,QAAQhD,eACnBnlB,OAGF2oB,EAAGvsB,EAAE,QAAS,CAAEiG,MAAOhO,KAAKgO,QAE5BhO,KAAK+zB,iBAAiBpoB,GAAO6I,IAC3B,GAAKoY,GAAUQ,cAAc5Y,GAkB3B5L,EAAOgkB,GAAUyB,8BAA8B7Z,QAlBX,CACpC,MAAMsgB,EAAQtgB,EAASoY,GAAUO,WAAW3Y,EAAQ,cAAW9Y,EACzD25B,EAAiBP,EAAQlI,GAAUO,WAAW2H,EAAO,gBAAap5B,EAClE45B,EAAgBR,EAAQlI,GAAUO,WAAW2H,EAAO,eAAYp5B,EAChE65B,EAAcF,EAAiBzI,GAAUne,QAAQ4mB,EAAgB,QAAU,KAC3EG,EAAaF,EAAgB1I,GAAUne,QAAQ6mB,EAAe,QAAU,KACxEG,EAAWX,EACblI,GAAUtd,iBAAiBwlB,GAAO5hB,IAAKwiB,GAAW9I,GAAUne,QAAQinB,EAAQ,SAC5E,GAQJ/sB,EANyC,CACvCgtB,QAASJ,EACTp4B,OAAQq4B,EACRI,MAAOH,GAIX,GAKFz1B,KAAKovB,WAAWuB,WAAW2D,IAE/B,CAEO,YAAM,CAAOxtB,GAClB,OAAO,IAAI4B,QAAQ,CAACC,EAASC,KAC3B,MAAM+C,EAAKihB,GAAU4B,YAAY,UAC3B8F,EAAK1H,GAAUI,eAAe,CAClC5tB,KAAM,MACNke,KAAMtd,KAAK8zB,QAAQhD,eACnBnlB,OAGF2oB,EAAGvsB,EAAE,QAAS,CAAEiG,MAAOhO,KAAKgO,QAASjG,EAAE,OAAQ,CAAEjB,KAAMA,GAAc,KAErE9G,KAAK+zB,iBAAiBpoB,GAAO6I,IAC3BoY,GAAUQ,cAAc5Y,GAAU5L,EAAOgkB,GAAUyB,8BAA8B7Z,IAAW7L,KAG9F3I,KAAKovB,WAAWuB,WAAW2D,IAE/B,CAEO,kBAAMuB,CAAa/uB,GACxB,OAAO,IAAI4B,QAAQ,CAACC,EAASC,KAC3B,MAAM+C,EAAKihB,GAAU4B,YAAY,WAC3B8F,EAAK1H,GAAUI,eAAe,CAClC5tB,KAAM,MACNke,KAAMtd,KAAK8zB,QAAQhD,eACnBnlB,OAGF2oB,EAAGvsB,EAAE,QAAS,CAAEiG,MAAOhO,KAAKgO,QAASjG,EAAE,UAAWjB,EAAO,CAAEA,KAAMA,GAAS,CAAA,GAE1E9G,KAAK+zB,iBAAiBpoB,GAAO6I,IAC3BoY,GAAUQ,cAAc5Y,GAAU5L,EAAOgkB,GAAUyB,8BAA8B7Z,IAAW7L,KAG9F3I,KAAKovB,WAAWuB,WAAW2D,IAE/B,CAEQ,iBAAAI,CAAkBJ,EAAqBlvB,GAC7C,MAAM2B,MAAEA,EAAKmtB,OAAEA,EAAMS,MAAEA,EAAKJ,SAAEA,GAAanvB,EACrC0vB,EAAQR,EAAK1H,GAAUO,WAAWmH,EAAI,cAAW54B,EACjDkP,EAAOkqB,EAAQlI,GAAUO,WAAW2H,EAAO,aAAUp5B,EAE3D,IAAKkP,EAAM,OAEX,MAAMlE,EAAOkE,EAAK7C,EAAE,OAAQ,CAAE3I,KAAM,MAAO2H,QAAOmtB,SAAQS,UAEtDJ,GACF7tB,EAAK8I,KAEDmlB,EAAQ,GAAM,GAChBL,EAAG9kB,KAAKA,MAGV9I,EAAKqB,EAAE,UAAW,IAAIyH,KAAKzH,EAAE,cAAe,CAAA,GAAIyH,KAAKzH,EAAE,eAAgB,CAAA,GAAIyH,KAAKzH,EAAE,KAAM,IAAIyH,KAAKA,IAErG,EClNY,MAAOsmB,GACV9nB,MAAQ,iCACV8lB,QACA1E,WACA2E,iBACAgC,YAA0C,CAAA,EAEjD,WAAAp2B,CAAYI,GACVC,KAAK8zB,QAAU/zB,EAAQ+zB,QACvB9zB,KAAKovB,WAAarvB,EAAQqvB,WAC1BpvB,KAAK+zB,iBAAmBh0B,EAAQg0B,gBAClC,CAEO,UAAMnsB,CAAKouB,GAChB,OAAO,IAAIttB,QAAQ,CAACC,EAASC,KAC3B,MAAM+C,EAAKihB,GAAU4B,YAAY,QAC3ByH,EAAYj2B,KAAK8zB,QAAQlC,aAAaoE,GACtCE,EAAiBtJ,GAAUK,qBAAqB,CACpDthB,GAAIA,EACJ2R,KAAMtd,KAAK8zB,QAAQhD,eACnBrV,GAAIzb,KAAK8zB,QAAQvC,WAAW0E,KAG9BC,EAAenuB,EAAE,IAAK,CAAEiG,MAAOhO,KAAKgO,QAASjG,EAAE,UAAW,CAAEouB,WAAY,IAExEn2B,KAAK+zB,iBAAiBpoB,GAAO6I,IAC3B,MAAM4hB,EAAI5hB,EAASoY,GAAUO,WAAW3Y,EAAQ,UAAO9Y,EACjDsO,EAASosB,EAAIxJ,GAAUO,WAAWiJ,EAAG,eAAY16B,EAGvD,GAAa,SAFAsO,EAAS4iB,GAAUne,QAAQzE,EAAQ,aAAUtO,GAGxDsE,KAAK+1B,YAAYE,IAAa,EAC9BttB,QACK,CACL,MAAM0tB,EAASzJ,GAAUne,QAAQ2nB,EAAG,WAAap2B,KAAKgO,OAASrC,EAAG2qB,SAAS,SACrEC,EAAgD,UAAtC3J,GAAUne,QAAQ+F,EAAQ,QAE1C,GAAI6hB,GAAUE,EAAS,CACrB,MAAMhI,EAAe3B,GAAUO,WAAW3Y,EAAQ,SAElD,IAAK+Z,EAEH,YADA3lB,EAAO,IAAIiC,MAAM,kBAInB,MAAM2rB,EAAgB,CACpB5sB,KAAMgjB,GAAUne,QAAQ8f,EAAc,QACtC1iB,QAAS+gB,GAAUU,eAAeiB,EAAc,SAAW,iBAG7D3lB,EAAO4tB,EACT,CACF,GAGFx2B,KAAKovB,WAAWuB,WAAWuF,IAE/B,CAEO,WAAMO,CAAMT,GACjB,OAAO,IAAIttB,QAASC,IAClB,MAAMstB,EAAYj2B,KAAK8zB,QAAQlC,aAAaoE,GACtCE,EAAiBtJ,GAAUK,qBAAqB,CACpD7tB,KAAM,cACNke,KAAMtd,KAAK8zB,QAAQhD,eACnBrV,GAAIzb,KAAK8zB,QAAQvC,WAAW0E,YAGvBj2B,KAAK+1B,YAAYE,GAExBj2B,KAAK+zB,iBAAiB,aAAgB2C,IACpC/tB,KAGF3I,KAAKovB,WAAWuB,WAAWuF,IAE/B,CAEO,qBAAMS,CAAgBX,GAC3B,OAAO,IAAIttB,QAAQ,CAACC,EAASksB,KAC3B,MAAMlpB,EAAKihB,GAAU4B,YAAY,mBAC3BoI,EAAWhK,GAAUI,eAAe,CACxC5tB,KAAM,MACNqc,GAAIzb,KAAK8zB,QAAQlC,aAAaoE,GAC9B1Y,KAAMtd,KAAK8zB,QAAQhD,eACnBnlB,OAGFirB,EAAS7uB,EAAE,QAAS,CAAEiG,MAAO,2CAE7BhO,KAAK+zB,iBAAiBpoB,GAAO6I,IAC3B,MAAMqiB,EAAWjK,GAAUne,QAAQ+F,EAAQ,MAE3C,GAAIxU,KAAK+zB,iBAAiB8C,GAAW,CACnC,MAAM/B,EAAQlI,GAAUO,WAAW3Y,EAAQ,SACrC9V,EAAQkuB,GAAUtd,iBAAiBwlB,GACtC5hB,IAAKxM,IACJ,MAAMirB,EAAU/E,GAAUne,QAAQ/H,EAAM,OACxC,OAAO1G,KAAK8zB,QAAQpC,qBAAqBC,KAE1CxiB,OAAQlK,GAAqC,OAAXA,GAErC0D,EAAQjK,EACV,GAGFsB,KAAKovB,WAAWuB,WAAWiG,IAE/B,EC3GY,MAAOE,GACZrsB,MACEC,MAAQ,GAAG7J,EAAO7C,KAAKlB,cAEhC,WAAA6C,CAAY8K,GACVzK,KAAKyK,MAAQA,CACf,CAEO,UAAMG,CAAKxF,EAA6B,IAC7C,MAAM0F,EAAa,CACjB1L,KAAM5E,EAAYC,IAClB6K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,OACvB5L,KAAMsG,GAGR,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,YAAM0Z,CAAOpf,GAClB,MAAMtG,EAAOgC,GAAMkD,YAAYoB,GAEzB0F,EAAa,CACjB1L,KAAM5E,EAAYE,KAClB4K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,OACvB5L,KAAM,IACDA,EACHi4B,WAAYj2B,GAAMc,QAAQ9C,EAAKi4B,YAAcj4B,EAAKi4B,WAAWnvB,KAAK,MAAQ9I,EAAKi4B,WAC/EC,cAAel2B,GAAMc,QAAQ9C,EAAKk4B,eAAiBl4B,EAAKk4B,cAAcpvB,KAAK,MAAQ9I,EAAKk4B,gBAI5F,OAAOh3B,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,YAAMgd,CAAOnc,EAAYvG,EAA+B,IAC7D,MAAM0F,EAAa,CACjB1L,KAAM5E,EAAYG,IAClB2K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOiB,GAC9B7M,KAAMsG,GAGR,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAIO,YAAM,CACXmsB,EACA7xB,EAAsB,IAEtB,MAAM8xB,EAAiC,iBAAZD,EAAuBA,EAAQvV,MAAM,KAAKxO,IAAKvH,GAAOA,EAAGwrB,QAAUF,EACxFnsB,EAAa,CACjB1L,KAAM5E,EAAYK,OAClByK,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOwsB,EAAY71B,YAC1CgI,SAAiC,IAAvB6tB,EAAYl0B,OAAejI,EAAUE,KAAOF,EAAUC,KAChE8D,KAAMsG,GAGR,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,eAAMssB,CAAUzrB,EAAYorB,GACjC,MAAMjsB,EAAa,CACjB1L,KAAM5E,EAAYG,IAClB2K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOiB,EAAI,UAClC7M,KAAM,CAAEu4B,SAAU,CAAEN,gBAGtB,OAAO/2B,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,kBAAMwsB,CAAa3rB,EAAYorB,GACpC,MAAMjsB,EAAa,CACjB1L,KAAM5E,EAAYG,IAClB2K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOiB,EAAI,UAClC7M,KAAM,CAAEy4B,SAAU,CAAER,gBAGtB,OAAO/2B,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,eAAMgK,CAAUnJ,GACrB,MAAMb,EAAa,CACjB1L,KAAM5E,EAAYE,KAClB4K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOiB,EAAI,cAGpC,OAAO3L,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO0sB,kBAAoBx3B,KAAK8U,UAEzB,iBAAMC,CAAYpJ,GACvB,MAAMb,EAAa,CACjB1L,KAAM5E,EAAYK,OAClByK,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOiB,EAAI,aAClCtC,SAAUtO,EAAUE,MAGtB,OAAO+E,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO2sB,sBAAwBz3B,KAAK+U,YAE7B,iCAAM2iB,CACX/rB,EACAqmB,GAEA,MAAMlnB,EAAa,CACjB1L,KAAM5E,EAAYG,IAClB2K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOiB,EAAI,iBAClC7M,KAAM,CAAEkzB,QAASA,EAAU,EAAI,IAGjC,OAAOhyB,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,8BAAM6sB,CAAyBhsB,GACpC,MAAMb,EAAa,CACjB1L,KAAM5E,EAAYC,IAClB6K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOiB,EAAI,kBAGpC,OAAO3L,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,wBAAM8sB,CACXjsB,EACAvG,EAA2C,IAE3C,MAAM0F,EAAa,CACjB1L,KAAM5E,EAAYC,IAClB6K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOiB,EAAI,aAClC7M,KAAMsG,GAGR,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,kBAAM+sB,CAAalsB,GACxB,MAAMb,EAAa,CACjB1L,KAAM5E,EAAYK,OAClByK,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAO,eAAgBiB,GAC9CtC,SAAUtO,EAAUE,MAGtB,OAAO+E,KAAKyK,MAAMhC,KAAKqC,EACzB,ECnJY,MAAOgtB,GACZrtB,MACEC,MAAQ,GAAG7J,EAAO7C,KAAKlB,eAEhC,WAAA6C,CAAY8K,GACVzK,KAAKyK,MAAQA,CACf,CAEO,UAAMG,CAAKxF,EAA8B,IAC9C,MAAM0F,EAAa,CACjBxF,IAAKxE,GAAMQ,OAAOtB,KAAK0K,OACvB5L,KAAMsG,GAGR,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,YAAM0Z,CAAOpf,EAAgC,IAClD,MAAM0F,EAAa,CACjBxF,IAAKxE,GAAMQ,OAAOtB,KAAK0K,OACvBtL,KAAM5E,EAAYE,KAClBoE,KAAMsG,GAGR,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,YAAMgd,CAAOnc,EAAuBvG,EAAgC,IACzE,MAAM0F,EAAa,CACjB1L,KAAM5E,EAAYG,IAClB0O,SAAUtO,EAAUE,KACpBqK,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAO5I,MAAMF,QAAQ+J,GAAMA,EAAG/D,KAAK,KAAO+D,GACjE7M,KAAMsG,GAGR,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,YAAM,CAAOitB,EAAwB3yB,GAC1C,MAAM5D,EAAMV,GAAMc,QAAQm2B,GAAOA,EAAInwB,KAAK,KAAOmwB,EAC3CjtB,EAAa,CACjBxF,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOlJ,GAC9BpC,KAAM5E,EAAYK,OAClBwO,SAAUtO,EAAUE,KACpB6D,KAAMsG,GAGR,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,kBAAMktB,CAAa5yB,GACxB,MAAM0F,EAAa,CACjB1L,KAAM5E,EAAYE,KAClB4K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAO,UAC9B5L,KAAMsG,GAGR,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,iBAAMmtB,CAAY7yB,EAAqC,IAC5D,MAAMtG,EAAOgC,GAAMkD,YAAYoB,GAE3BtG,GAAQA,EAAKo5B,iBAAmBp3B,GAAMc,QAAQ9C,EAAKo5B,mBACrDp5B,EAAKo5B,gBAAkBp5B,EAAKo5B,gBAAgBtwB,KAAK,OAGnD,MAAMkD,EAAa,CACjBxF,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAO,UAC9B5L,KAAMA,GAGR,OAAOkB,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,mBAAMqtB,CAAcxsB,EAAa,KACtC,MAAMb,EAAa,CACjB1L,KAAM5E,EAAYC,IAClB4O,SAAUtO,EAAUC,KACpBsK,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOiB,EAAI,cAGpC,OAAO3L,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,iBAAMstB,CAAYzsB,EAAYijB,GACnC,OAAO5uB,KAAKq4B,eAAe1sB,EAAIijB,EACjC,CAEO,oBAAM0J,CAAe3sB,EAAYijB,GACtC,OAAO5uB,KAAKq4B,eAAe1sB,OAAIjQ,EAAWkzB,EAC5C,CAEO,oBAAMyJ,CAAe1sB,EAAYkR,EAAc9M,GACpD,OAAO/P,KAAKu4B,YAAY5sB,EAAI,CAAEkR,MAAK9M,UACrC,CAEQ,iBAAMwoB,CAAY5sB,EAAYvG,GACpC,MAAM0F,EAAa,CACjB1L,KAAM5E,EAAYG,IAClB0O,SAAUtO,EAAUE,KACpBqK,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOiB,EAAI,aAClC7M,KAAMsG,GAGR,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,EC5GY,MAAO0tB,GACZC,SAEP,WAAA94B,CAAY84B,GACVz4B,KAAKy4B,SAAWA,CAClB,CAEOC,UAAY,CAACC,EAAgBh3B,KAClC,MAAMi3B,EAAYj3B,GAAWk3B,WAAa,GACpCC,EAAan3B,GAAWm3B,WAM9B,cAJOn3B,GAAWysB,wBACXzsB,GAAWk3B,iBACXl3B,GAAWm3B,WAEVA,GACN,KAAKnkC,EAAkBC,KACrBoL,KAAKy4B,SAASM,cAAcJ,EAAQC,EAAWj3B,GAC/C,MACF,KAAKhN,EAAkBE,OACrBmL,KAAKy4B,SAASO,gBAAgBL,EAAQC,EAAWj3B,GACjD,MACF,KAAKhN,EAAkBG,OACrBkL,KAAKy4B,SAASQ,gBAAgBN,EAAQC,EAAWj3B,GACjD,MACF,KAAKhN,EAAkBI,KACrBiL,KAAKy4B,SAASS,cAAcP,EAAQC,EAAWj3B,GAC/C,MACF,KAAKhN,EAAkBO,UACrB8K,KAAKy4B,SAASU,uBAAuBR,EAAQC,EAAWj3B,GACxD,MACF,KAAKhN,EAAkBK,QACrBgL,KAAKy4B,SAASW,oBAAoBT,EAAQC,EAAWj3B,GACrD,MACF,KAAKhN,EAAkBM,eACrB+K,KAAKy4B,SAASY,0BAA0BV,EAAQC,EAAWj3B,KC9BrD,MAAgB23B,GACrB7uB,MACA8uB,OACA1tB,QAGA2tB,aAAuB,EACpBC,cAAwB,EACxBC,UAAoB,EACpBC,aAAuB,EAqBjC,WAAAh6B,CAAY8K,GACVzK,KAAKyK,MAAQA,EACbzK,KAAKu5B,OAAS,IAAIzC,GAAersB,GACjCzK,KAAK6L,QAAU,IAAIisB,GAAgBrtB,EACrC,CAEO,YAAMqL,CAAO1Q,GAClB,MAAM0vB,EAAQ30B,OAAO6I,OAAO,CAAA,EAAI5D,GAE5B0vB,EAAM8E,aACR9E,EAAM8E,WAAa,IAAIl3B,KAAKoyB,EAAM8E,YAAYC,eAE5C/E,EAAMgF,WACRhF,EAAMgF,SAAW,IAAIp3B,KAAKoyB,EAAMgF,UAAUD,eAExC/4B,GAAMc,QAAQkzB,EAAMoD,mBACtBpD,EAAMoD,gBAAmBpD,EAAMoD,gBAA6BtwB,KAAK,MAGnE,MAAMkD,EAAa,CACjB1L,KAAM5E,EAAYC,IAClB6K,IAAKxE,GAAMQ,OAAO,GAAGT,EAAO7C,KAAKlB,eACjCgC,KAAMg2B,GAGR,OAAO90B,KAAKyK,MAAMhC,KAAKqC,EACzB,CAIO,qBAAMivB,CAAgBt6B,EAAkB,KAC7C,OAAO,IAAIiJ,QAAQ4C,MAAO3C,EAASC,KACjC,MAAMxH,EAAQ,8BAA8BP,EAAO7D,aAAaE,8BAA8BuC,MACxFu6B,EAAQnnB,WAAW,KACvB/R,GAAMC,iBAAiBf,KAAKi6B,0BAA5Bn5B,CAAuDM,GACvDwH,EAAOxH,IACN3B,GAEH,IACE,MAAMyN,QAAelN,KAAKk6B,OAC1BjnB,aAAa+mB,GACbrxB,EAAQuE,EACV,CAAE,MACA+F,aAAa+mB,GACbpxB,EAAOxH,EACT,GAEJ,CAEU,iBAAA+4B,CAAkBrzB,GAC1B,OAAQA,GACN,KAAK9P,EAAUC,OACb,MAAO,uBACT,KAAKD,EAAUE,MACb,MAAO,4BACT,KAAKF,EAAUxB,aACb,MAAO,yBACT,KAAKwB,EAAUG,YACb,MAAO,sBACT,KAAKH,EAAUI,QACb,MAAO,oBACT,KAAKJ,EAAUK,eACb,MAAO,0BACT,KAAKL,EAAUM,cACb,MAAO,yBACT,KAAKN,EAAUO,eACb,MAAO,0BACT,KAAKP,EAAUQ,eACb,MAAO,0BACT,KAAKR,EAAUS,eACb,MAAO,0BACT,KAAKT,EAAUU,kBACb,MAAO,6BACT,KAAKV,EAAUW,kBACb,MAAO,4BACT,KAAKX,EAAUY,aACb,MAAO,uBACT,KAAKZ,EAAUa,aACb,MAAO,wBACT,KAAKb,EAAUc,mBACb,MAAO,6BACT,KAAKd,EAAUe,KACb,MAAO,iBACT,KAAKf,EAAUgB,MACb,MAAO,kBACT,KAAKhB,EAAUiB,KACb,MAAO,iBACT,QACE,OAAO,KAEb,CAEO,WAAAsb,CAAYzM,EAAiB2N,GAClC,MAAM2lB,EAAep6B,KAAKm6B,kBAAkBrzB,GAI5C,OAHIszB,IACDp6B,KAAKo6B,GAAmC3lB,GAEpCzU,KAAK2T,eAAeH,KAAKxT,KAAM8G,EACxC,CAEO,cAAA6M,CAAe7M,GACpB,MAAMszB,EAAep6B,KAAKm6B,kBAAkBrzB,GACxCszB,IACDp6B,KAAKo6B,QAA+C1+B,EAEzD,CAEO,kBAAA2+B,GACLl6B,OAAOC,KAAKJ,MAAMK,QAASC,IACrBA,EAAI+R,WAAW,OAAS/R,EAAIg2B,SAAS,aAAyD,mBAAnCt2B,KAAKM,KACjEN,KAAKM,QAA2D5E,IAGvE,ECzIY,MAAO4+B,WAAwBhB,GAQpClK,WACA0E,QACAyG,YACAx9B,IACAK,iBAEA22B,iBAA0C,CAAA,EACzCyG,oBAAgD,IAAIje,IACpDke,eAA0C,KAC1CC,2BAAgD,GAExD,WAAA/6B,CAAY8K,GACVsG,MAAMtG,GACNzK,KAAK8zB,QAAU,IAAIlD,GAEnB5wB,KAAKovB,WAAaA,GAAW,CAC3B1U,QAAS7Z,EAAO7D,aAAaE,UAC7BonB,YAAa,CAACqB,EAAMpB,IAClBoB,EACE,CACE1nB,SAAU+B,KAAKovB,YAAYrvB,SAAS9B,SACpC+N,SAAUhM,KAAKovB,YAAYrvB,SAASiM,UAEtCuY,KAIF1jB,EAAO/D,KAAKQ,WAAWD,SACzB2C,KAAKovB,WAAW9xB,UAAUwV,MAA6C,IAArCjS,EAAO/D,KAAKQ,UAAUC,cAG1D,MAAMwC,EAAU,CACdqvB,WAAYpvB,KAAKovB,WACjB0E,QAAS9zB,KAAK8zB,QACdC,iBAAkB/zB,KAAK+zB,kBAGzB/zB,KAAKjD,IAAM,IAAI+4B,GAAc/1B,GAC7BC,KAAKu6B,YAAc,IAAI1G,GAAY9zB,GACnCC,KAAK5C,iBAAmB,IAAI20B,GAAiB/xB,KAC/C,CAEA,oBAAW26B,GACT,OAAO36B,KAAKovB,WAAWplB,MACzB,CAEA,iBAAWvF,GACT,MAAMm2B,EAAU56B,KAAKovB,WAAW1X,KAAKrW,YAAc,GAEnD,OADerB,KAAK8zB,QAAQzC,iBAAiBuJ,IAAY,CAE3D,CAEO,aAAMxgB,CAAQhV,GA2HnB,OA1HApF,KAAKy6B,eAAiB,IAAI/xB,QAAQ,CAACC,EAASC,KAC1C9H,GAAMgC,KAAK,SAAU,0BAA2BsC,GAE5CpF,KAAKy5B,cACP34B,GAAMgC,KAAK,SAAU,6CACrB6F,GAAQ,IAIN3I,KAAKw5B,aACP14B,GAAMgC,KAAK,SAAU,4CACrB6F,GAAQ,KAIV3I,KAAKy5B,cAAe,EACpBz5B,KAAK05B,UAAW,EAEhB15B,KAAK66B,+BAEL76B,KAAK86B,sBAAsB,UAAW,KACpCh6B,GAAMgC,KAAK,SAAU9C,KAAK25B,YAAc,eAAiB,gBAG3D35B,KAAK86B,sBAAsB,SAAU,KACnCh6B,GAAMgC,KAAK,SAAU,UACrB9C,KAAK+6B,qBACLpyB,GAAQ,GACR3I,KAAKy6B,eAAiB,OAGxBz6B,KAAK86B,sBAAsB,UAAW,KACpCh6B,GAAMgC,KAAK,SAAU,aAGvB9C,KAAK86B,sBAAsB,aAAc,KACvCh6B,GAAMgC,KAAK,SAAU,gBAErBhC,GAAMC,iBAAiBf,KAAKg7B,uBAA5Bl6B,GAEID,EAAO/D,KAAKQ,WAAWD,QACzB2C,KAAKw5B,aAAc,EACnBx5B,KAAKy5B,cAAe,GAEpBz5B,KAAKwZ,eAITxZ,KAAK86B,sBAAsB,SAAU,CAAC9wB,EAA+BjD,KACnEjG,GAAMgC,KAAK,SAAU,YAAY+E,OAAOmC,KAA4B,iBAAVjD,EAAqB/L,KAAK8I,UAAUiD,GAAS,IACvGjG,GAAMC,iBAAiBf,KAAKi7B,qBAA5Bn6B,CAAkDkJ,KAGpDhK,KAAK86B,sBAAsB,SAAWtmB,IAKpC,GAAIA,EAAOzG,GAAG,aAAe/N,KAAKw5B,YAGhC,OAFAx5B,KAAK06B,2BAA2Bx3B,KAAKsR,QACrC1T,GAAMgC,KAAK,SAAU,4DAKnB0R,EAAOzG,GAAG,YACZ/N,KAAKk7B,WAAW1mB,GACPA,EAAOzG,GAAG,MACnB/N,KAAKm7B,KAAK3mB,GACDA,EAAOzG,GAAG,aACO,aAAtByG,EAAO7G,MAAMvO,KACfY,KAAKo7B,gBAAgB5mB,GACU,UAAtBA,EAAO7G,MAAMvO,KACtBY,KAAKq7B,eAAe7mB,GAEpBxU,KAAK04B,UAAUlkB,MAKrBxU,KAAK86B,sBAAsB,QAAU15B,IAMnC,GALAN,GAAMgC,KAAK,SAAU,SAAU1B,EAAO,CACpCu4B,YAAa35B,KAAK25B,YAClBc,iBAAkBz6B,KAAKy6B,iBAGrBz6B,KAAKy6B,gBACP,IAAKz6B,KAAK25B,YAAa,CACrB,MAAMz4B,EAAME,EACZwH,EAAoB,cAAb1H,EAAI4F,KAAuB5F,EAAIiX,UAAY/W,GAClDpB,KAAKy6B,eAAiB,IACxB,OAEA35B,GAAMC,iBAAiBf,KAAKi6B,0BAA5Bn5B,CAAuDM,KAI3DpB,KAAK86B,sBAAsB,SAAWv3B,IACpCzC,GAAMsC,yBAAyB,gBAAiB,CAAEM,KAAMH,IACxDzC,GAAMgC,KAAK,SAAU,QAASS,KAGhCvD,KAAK86B,sBAAsB,QAAUv3B,IACnCzC,GAAMsC,yBAAyB,eAAgB,CAAEM,KAAMH,IACvDzC,GAAMgC,KAAK,SAAU,QAASS,KAIhCvD,KAAKovB,WAAWrvB,QAAQ9B,SAAW2uB,GAAUE,sBAAsB1nB,EAAOH,QAC1EjF,KAAKovB,WAAWrvB,QAAQiM,SAAW5G,EAAO4G,cAE1ChM,KAAKovB,WAAWjiB,QAAQzD,MAAOtI,IAC7BD,QAAQC,MAAM,gCAAiCA,GAC3CpB,KAAKy6B,gBACP7xB,EAAOxH,GACPpB,KAAKy6B,eAAiB,MAEtB35B,GAAMC,iBAAiBf,KAAKi6B,0BAA5Bn5B,CAAuDM,QAKtDpB,KAAKy6B,cACd,CAEO,UAAMP,GACX,OAAO,IAAIxxB,QAAQ,CAACC,EAASC,KAC3B,MAAM+C,EAAKihB,GAAU4B,YAAY,QAC3BoI,EAAWhK,GAAUI,eAAe,CAAErhB,KAAIvM,KAAM,MAAOqc,GAAI5a,EAAOjE,UAAUE,OAElF85B,EAAS7uB,EAAE,OAAQ,CAAEiG,MAAO,kBAE5BhO,KAAK+zB,iBAAiBpoB,GAAO6I,IAC3B,MAAMpT,EAAQwrB,GAAUO,WAAW3Y,EAAQ,SACvCpT,EACFwH,EAAOgkB,GAAUyB,8BAA8BjtB,IAE/CuH,KAIJ3I,KAAKovB,WAAWuB,WAAWiG,IAE/B,CAEO,IAAAhiB,CAAKsZ,EAAuCriB,EAA8B,IAC/E,MAAMyvB,EAAYzvB,EAAQF,IAAM7K,GAAMmB,kBAChCs5B,EAAgB3O,GAAUG,oBAAoB,CAClDzP,KAAMtd,KAAK8zB,QAAQhD,eACnBrV,GAAIzb,KAAK8zB,QAAQ9C,YAAY9C,GAC7B9uB,KAAMyM,EAAQzM,MAAQY,KAAK8zB,QAAQ3C,SAASjD,GAC5CviB,GAAI2vB,IAsBN,OAnBKzvB,EAAQF,KACXE,EAAQF,GAAK2vB,GAGXzvB,EAAQnI,MACV63B,EAAcxzB,EAAE,QAAQ+H,EAAEjE,EAAQnI,MAAM8L,KAGtC3D,EAAQlK,YACV45B,EAAcxzB,EAAE,cAAe,CAAEiG,MAAO,kBACxC4e,GAAUgB,uBAAuB2N,EAAe1vB,EAAQlK,YAGtD3B,KAAK5C,iBAAiBi1B,UACxBryB,KAAK5C,iBAAiBs1B,aAAa6I,EAAe1vB,GAElD7L,KAAKovB,WAAWuB,WAAW4K,GAGtBD,CACT,CAEO,iBAAAE,CACLv2B,EACA4G,GAEA,MAAMyvB,EAAYzvB,EAAQF,IAAM7K,GAAMmB,kBAChCw5B,EAAa35B,MAAMF,QAAQqD,GAAUA,EAAS,CAACA,GAErD,IAAK,MAAMy2B,KAAaD,EAAY,CAClC,MAAMF,EAAgB3O,GAAUG,oBAAoB,CAClD3tB,KAAM,WACNuM,GAAI2vB,EACJ7f,GAAIzb,KAAK8zB,QAAQ9C,YAAY0K,KAG3B7vB,EAAQnI,MACV63B,EAAcxzB,EAAE,QAAQ+H,EAAEjE,EAAQnI,MAAM8L,KAGtC3D,EAAQlK,YACV45B,EAAcxzB,EAAE,cAAe,CAAEiG,MAAO,kBAAmBjG,EAAE,oBAAoB+H,EAAE,uBAAuBN,KAC1God,GAAUgB,uBAAuB2N,EAAe1vB,EAAQlK,YAG1D3B,KAAKovB,WAAWuB,WAAW4K,EAC7B,CAEA,OAAOD,CACT,CAEO,0BAAAK,CACL12B,EACA4G,GAEA,MAAMyvB,EAAYzvB,EAAQF,IAAM7K,GAAMmB,kBAEtC,IAAIs5B,EAAgB3O,GAAUG,oBAAoB,CAChDtR,GAAIzb,KAAK8zB,QAAQ9C,YAAY/rB,GAC7B7F,KAAM,WACNuM,GAAI2vB,IACHvzB,EAAE,cAAe,CAAEiG,MAAO,kBAE7B,MAAMrM,EAAYkK,EAAQlK,WAAa,CAAA,EA0CvC,OAzCAxB,OAAOC,KAAKuB,GAAWtB,QAASyG,IAC9B,MAAMJ,EAAO/E,EAAUmF,GAEV,kBAATA,GAA4BhG,GAAMc,QAAQ8E,IAC5C60B,EAAgBA,EAAcxzB,EAAE,kBAC9BrB,GAAkC,IAAIrG,QAASu7B,IAC/CL,EAAgBA,EAAcxzB,EAAE,gBAC5BjH,GAAMiB,SAAS65B,IACjBz7B,OAAOwQ,QAAQirB,GAAWv7B,QAAQ,EAAEC,EAAKyG,MACvCw0B,EAAgBA,EACbxzB,EAAEzH,GACFwP,EAAEjI,OAAOd,GAAS,KAClByI,OAGP+rB,EAAgBA,EAAc/rB,OAEhC+rB,EAAgBA,EAAc/rB,MACZ,iBAAT1I,GAA2BhG,GAAMc,QAAQ8E,IAClD60B,EAAgBA,EAAcxzB,EAAE,iBAC9BrB,GAAgC,IAAIrG,QAASw7B,IAC7CN,EAAgBA,EACbxzB,EAAE,cACF+H,EAAEjI,OAAOg0B,GAAc,KACvBrsB,OAEL+rB,EAAgBA,EAAc/rB,MACL,iBAAT9I,GAA8B,OAATA,EACrCkmB,GAAUe,kBAAkB4N,EAAe70B,EAAqBI,GAEhEy0B,EAAgBA,EACbxzB,EAAEjB,GACFgJ,EAAEjI,OAAOnB,GAAQ,KACjB8I,OAIP+rB,EAAgBA,EAAc/rB,KAE9BxP,KAAKovB,WAAWuB,WAAW4K,GAEpBD,CACT,CAEO,kBAAAQ,CAAmB5N,GACxB,MAAMqN,EAAgB3O,GAAUG,oBAAoB,CAClDzP,KAAMtd,KAAK8zB,QAAQhD,eACnBrV,GAAIzb,KAAK8zB,QAAQ9C,YAAY9C,GAC7B9uB,KAAMY,KAAK8zB,QAAQ3C,SAASjD,KAG9BqN,EAAcxzB,EAAE,YAAa,CAAEiG,MAAO,0CAEtChO,KAAKovB,WAAWuB,WAAW4K,EAC7B,CAEO,sBAAAQ,CAAuB7N,GAC5B,MAAMqN,EAAgB3O,GAAUG,oBAAoB,CAClDzP,KAAMtd,KAAK8zB,QAAQhD,eACnBrV,GAAIzb,KAAK8zB,QAAQ9C,YAAY9C,GAC7B9uB,KAAMY,KAAK8zB,QAAQ3C,SAASjD,KAG9BqN,EAAcxzB,EAAE,SAAU,CAAEiG,MAAO,0CAEnChO,KAAKovB,WAAWuB,WAAW4K,EAC7B,CAEO,mBAAAS,CAAoB52B,GACzB,MAAMm2B,EAAgB3O,GAAUG,oBAAoB,CAClD3tB,KAAM,OACNke,KAAMtd,KAAK8zB,QAAQhD,eACnBnlB,GAAI7K,GAAMmB,kBACVwZ,GAAIzb,KAAK8zB,QAAQ9C,YAAY5rB,EAAOH,UAGtCs2B,EAAcxzB,EAAE,WAAY,CAAEiG,MAAO,0BAA2BrC,GAAIvG,EAAOk2B,YAAa9rB,KACxF+rB,EAAcxzB,EAAE,cAAe,CAAEiG,MAAO,kBAAmBjG,EAAE,aAAa+H,EAAE1K,EAAO8oB,UAEnFluB,KAAKovB,WAAWuB,WAAW4K,EAC7B,CAEO,cAAAU,CAAe72B,GACpB,MAAMm2B,EAAgB3O,GAAUG,oBAAoB,CAClD3tB,KAAM,OACNke,KAAMtd,KAAK8zB,QAAQhD,eACnBrV,GAAIzb,KAAK8zB,QAAQ9C,YAAY5rB,EAAOH,QACpC0G,GAAI7K,GAAMmB,oBAGZs5B,EAAcxzB,EAAE,YAAa,CAAEiG,MAAO,0BAA2BrC,GAAIvG,EAAOk2B,YAAa9rB,KACzF+rB,EAAcxzB,EAAE,cAAe,CAAEiG,MAAO,kBAAmBjG,EAAE,aAAa+H,EAAE1K,EAAO8oB,UAEnFluB,KAAKovB,WAAWuB,WAAW4K,EAC7B,CAEO,WAAAW,CAAY92B,GACjB,MAAMm2B,EAAgB3O,GAAUG,oBAAoB,CAClDzP,KAAMtd,KAAK8zB,QAAQhD,eACnBrV,GAAIzb,KAAK8zB,QAAQ9C,YAAY5rB,EAAOqW,IAAMrW,EAAO8oB,UACjD9uB,KAAMY,KAAK8zB,QAAQ3C,SAAS/rB,EAAOqW,IAAMrW,EAAO8oB,UAChDviB,GAAI7K,GAAMmB,oBAGZs5B,EAAcxzB,EAAE,QAAQ+H,EAAE1K,EAAO1B,MAAM8L,KACvC+rB,EACGxzB,EAAE,UAAW,CACZiG,MAAO,6BACPrC,GAAIvG,EAAO+2B,gBACXC,KAAMh3B,EAAOg3B,KAAO,OAAS,UAE9B5sB,KACH+rB,EAAcxzB,EAAE,cAAe,CAAEiG,MAAO,kBAAmBjG,EAAE,aAAa+H,EAAE1K,EAAO8oB,UAE/E9oB,EAAOzD,WACTirB,GAAUgB,uBAAuB2N,EAAen2B,EAAOzD,WAGzD3B,KAAKovB,WAAWuB,WAAW4K,EAC7B,CAEO,aAAAc,CAAcj3B,GACnB,MAAMm2B,EAAgB3O,GAAUG,oBAAoB,CAClDzP,KAAMtd,KAAK8zB,QAAQhD,eACnBrV,GAAIzb,KAAK8zB,QAAQ9C,YAAY5rB,EAAOqW,IAAMrW,EAAO8oB,UACjD9uB,KAAMY,KAAK8zB,QAAQ3C,SAAS/rB,EAAOqW,IAAMrW,EAAO8oB,UAChDviB,GAAI7K,GAAMmB,oBAGZs5B,EAAcxzB,EAAE,SAAU,CAAEiG,MAAO,4BAA6BrC,GAAIvG,EAAOk2B,YAAa9rB,KACxF+rB,EAAcxzB,EAAE,cAAe,CAAEiG,MAAO,kBAAmBjG,EAAE,aAAa+H,EAAE1K,EAAO8oB,UAEnFluB,KAAKovB,WAAWuB,WAAW4K,EAC7B,CAEO,mBAAAe,CAAoBr3B,GACzB,OAAO,IAAIyD,QAAQ,CAACC,EAASC,KAC3B,MAAM+C,EAAKihB,GAAU4B,YAAY,gBAC3BoI,EAAWhK,GAAUI,eAAe,CACxC5tB,KAAM,MACNke,KAAMtd,KAAK8zB,QAAQhD,eACnBrV,GAAIzb,KAAK8zB,QAAQ9C,YAAY/rB,GAC7B0G,GAAIA,IAGNirB,EAAS7uB,EAAE,QAAS,CAAEiG,MAAO,mBAE7BhO,KAAK+zB,iBAAiBpoB,GAAO6I,IACvBoY,GAAUO,WAAW3Y,EAAQ,SAC/B5L,EAAOgkB,GAAUyB,8BAA8B7Z,IAE/C7L,EAAQ3I,KAAKu8B,qBAAqB/nB,KAItCxU,KAAKovB,WAAWuB,WAAWiG,IAE/B,CAEQ,oBAAA2F,CAAqB/nB,GAC3B,MAAM8I,EAAOsP,GAAUne,QAAQ+F,EAAQ,QACjCvP,EAASjF,KAAK8zB,QAAQzC,iBAAiB/T,GACvCwX,EAAQlI,GAAUO,WAAW3Y,EAAQ,SACrCgoB,EAAU1H,EAAQlyB,SAASgqB,GAAUne,QAAQqmB,EAAO,YAAc,EAIxE,OAFAh0B,GAAMC,iBAAiBf,KAAKy8B,2BAA5B37B,CAAwDmE,EAAQu3B,GAEzD,CAAEv3B,SAAQu3B,UACnB,CAEO,UAAAE,GACL,MAAM9F,EAAWhK,GAAUI,eAAe,CACxCrhB,GAAI3L,KAAK8zB,QAAQtF,YAAY,cAC7BpvB,KAAM,QAGRw3B,EAAS7uB,EAAE,SAAU,CACnBiG,MAAO,uCACP3Q,OAAQ,UAGV2C,KAAKovB,WAAWuB,WAAWiG,EAC7B,CAEO,YAAA+F,GACL,MAAM/F,EAAWhK,GAAUI,eAAe,CACxCrhB,GAAI3L,KAAK8zB,QAAQtF,YAAY,cAC7BpvB,KAAM,QAGRw3B,EAAS7uB,EAAE,SAAU,CACnBiG,MAAO,uCACP3Q,OAAQ,SAGV2C,KAAKovB,WAAWuB,WAAWiG,EAC7B,CAEO,gBAAMpd,GAGX,GAFA1Y,GAAMgC,KAAK,SAAU,cAEjB9C,KAAK05B,SAEP,OADA54B,GAAMgC,KAAK,SAAU,2CACd,EAGT9C,KAAK05B,UAAW,EAChB15B,KAAK25B,aAAc,EACnB35B,KAAKw5B,aAAc,EACnBx5B,KAAKy5B,cAAe,EACpBz5B,KAAKjD,IAAIg5B,YAAc,CAAA,EACvB/1B,KAAK8zB,QAAQhD,eAAiB,GAC9B9wB,KAAK5C,iBAAiBue,OAEtB,IAEE,aADM3b,KAAKovB,WAAWzT,QACf,CACT,CAAE,MACA,OAAO,CACT,CACF,CAEO,SAAAihB,GACL97B,GAAMgC,KAAK,SAAU,cAErB9C,KAAKw5B,aAAc,EACnBx5B,KAAKy5B,cAAe,EACpBz5B,KAAK5C,iBAAiBue,OACtB3b,KAAKovB,WAAWhW,QAAQhM,KAC1B,CAEQ,SAAAsrB,CAAUmE,GAChB,MAAMC,EAAkBlQ,GAAUW,mBAAmBsP,EAAW,CAAC,OAAQ,YAAa,YAChFroB,EAASsoB,GAAmBD,EAC5Bvf,EAAOsP,GAAUne,QAAQ+F,EAAQ,QACjCpV,EAAOwtB,GAAUne,QAAQ+F,EAAQ,QACjCuoB,EAASnQ,GAAUO,WAAW3Y,EAAQ,UACtC9S,EAAW1B,KAAKovB,WAAW1X,KAAKH,eAAiB,GACjDqb,EAAkB,SAATxzB,EAGf,GAAKwzB,GAAUtV,EAAK3C,SAASjZ,IAAcq7B,EACzC,OAGF,MAAMzB,EAAY1O,GAAUne,QAAQ+F,EAAQ,MACtCwoB,EAAYpQ,GAAUO,WAAW3Y,EAAQ,YACzCyoB,EAAOrQ,GAAUO,WAAW3Y,EAAQ,aACpC0oB,EAAoBtQ,GAAUO,WAAW3Y,EAAQ,WACjD2oB,EAAsBvQ,GAAUO,WAAW3Y,EAAQ,aACnD4oB,EAAmBxQ,GAAUO,WAAW3Y,EAAQ,UAChD6oB,EAAYhhC,QAAQuwB,GAAUO,WAAW3Y,EAAQ,cACjD8oB,EAAS1Q,GAAUO,WAAW3Y,EAAQ,UACtC1B,EAAQ8Z,GAAUO,WAAW3Y,EAAQ,SACrCqZ,EAAcjB,GAAUO,WAAW3Y,EAAQ,eAC3C9Q,EAAOkpB,GAAUU,eAAe9Y,EAAQ,QACxC+oB,EAAclhC,QAAQygC,GACtBU,EAAmB,cAATp+B,EACVs8B,EAAY9I,EAAShG,GAAUne,QAAQ+F,EAAQ,MAAQ,KACvDipB,EAAc/B,EAAY17B,KAAK8zB,QAAQzC,iBAAiBqK,GAAa,KACrEj6B,EAAMosB,EAAcjB,GAAUoB,iBAAiBH,GAAe,KAC9DlsB,EAAYF,EAAMA,EAAIE,UAAY,KAClCusB,EAAWsP,EAAUx9B,KAAK8zB,QAAQxC,mBAAmBhU,GAAS7b,GAAKysB,UAAY,KAC/EjpB,EAASu4B,EAAUx9B,KAAK8zB,QAAQtC,kBAAkBlU,GAAQtd,KAAK8zB,QAAQzC,iBAAiB/T,GACxFogB,EAAiB19B,KAAKovB,WAAW1X,KAAKrW,WACtCoD,EAAgBi5B,EAAiB19B,KAAK8zB,QAAQzC,iBAAiBqM,GAAkB,EAGvF,GAAIL,GAAaC,EAKf,aAJI1K,GAAU4K,IAAY1qB,IACxBhS,GAAMC,iBAAiBf,KAAK29B,wBAA5B78B,CAAqDu8B,EAAWp4B,EAAQipB,IAO5E,GAAIgP,EAUF,YATAp8B,GAAMC,iBAAiBf,KAAK49B,wBAA5B98B,CACE8rB,GAAUne,QAAQyuB,EAAmB,MACY,SAAjDtQ,GAAUne,QAAQyuB,EAAmB,QACrCx5B,EACAwqB,EACAjpB,EACAtD,GAOJ,GAAIw7B,EAAqB,CACvB,GAAII,GAAeC,EACjB,OAGF,MAAMlC,EAAY1O,GAAUne,QAAQ0uB,EAAqB,cACnDl4B,EAASrC,SAASgqB,GAAUne,QAAQ0uB,EAAqB,aACzDtgB,IAAEA,EAAG9M,OAAEA,GAAW6c,GAAU+B,eAAewO,GAIjD,YAFAr8B,GAAMC,iBAAiBf,KAAK69B,2BAA5B/8B,CAAwDw6B,EAAWr2B,EAAQipB,EAAUrR,EAAK9M,EAG5F,CAGA,GAAIqtB,EAAkB,CACpB,MAAM9B,EAAY1O,GAAUne,QAAQ2uB,EAAkB,MAItD,YAFAt8B,GAAMC,iBAAiBf,KAAK89B,wBAA5Bh9B,CAAqDw6B,EAAWpN,EAAUjpB,EAG5E,CAGA,GAAI+3B,GAAaC,EAAM,CACrB,GAAID,GAAapK,EAAQ,CACvB,MAAMjnB,EAAKihB,GAAUne,QAAQuuB,EAAW,MACxCl8B,GAAMC,iBAAiBf,KAAK+9B,0BAA5Bj9B,CAAuD6K,EAAIuiB,EAAUjpB,EACvE,CACA,GAAIg4B,GAAQrK,EAAQ,CAClB,MAAMjnB,EAAKihB,GAAUne,QAAQwuB,EAAM,MACnCn8B,GAAMC,iBAAiBf,KAAKg+B,qBAA5Bl9B,CAAkD6K,EAAIuiB,EAAUjpB,EAClE,CAEA,MACF,CAGIipB,GAAYjpB,GAAUA,IAAWR,GACnCzE,KAAKg8B,oBAAoB,CAAEV,YAAWpN,WAAUjpB,WAGlD,MAAM4G,EAAwB,CAC5BF,GAAI2vB,EACJnN,UAAWD,EACX+P,aAAcR,EACdS,aAAcX,EACdn+B,OACAsE,OACA/B,YACAmR,UAGE8f,GAAU4K,IACZ18B,GAAMC,iBAAiBf,KAAKm+B,kBAA5Br9B,CAA+CmE,EAAQ4G,EAE3D,CAEQ,UAAAqvB,CAAW1mB,GACjB,MAAM8I,EAAOsP,GAAUne,QAAQ+F,EAAQ,QACjC7I,EAAKihB,GAAUne,QAAQ+F,EAAQ,MAC/BpV,EAAOwtB,GAAUne,QAAQ+F,EAAQ,QACjCkpB,EAAiB19B,KAAKovB,WAAW1X,KAAKrW,WACtCoD,EAAgBzE,KAAK8zB,QAAQzC,iBAAiBqM,GAC9CtH,EAAIxJ,GAAUO,WAAW3Y,EAAQ,KACjCxG,EAAQooB,EAAIxJ,GAAUne,QAAQ2nB,EAAG,SAAW,KAC5CpsB,EAASosB,EAAIxJ,GAAUO,WAAWiJ,EAAG,SAAW,KAEhDrsB,EAAaC,EAAS4iB,GAAUU,eAAetjB,EAAQ,QAAU,KAGvE,GAAIgE,GAASA,EAAMqE,WAAW,kCAAmC,CAE/D,GAAa,UAATjT,EAKF,YAHIuM,EAAG2qB,SAAS,UACdx1B,GAAMC,iBAAiBf,KAAK+zB,iBAAiBpoB,GAA7C7K,CAAkD0T,IAKtD,MAAM0Z,EAAWluB,KAAK8zB,QAAQxC,mBAAmBhU,GAC3C8gB,EAAYp+B,KAAK8zB,QAAQpC,qBAAqBpU,GAGpD,GAAItT,EAAQ,CAEV,GAAmB,QAAfD,EAAsB,CACxB,MAAMrD,EAAOkmB,GAAUO,WAAW3Y,EAAQ,QACpC6pB,EAAe33B,EAAOkmB,GAAUO,WAAWzmB,EAAM,SAAW,KAC5D43B,EAAmBD,EAAezR,GAAUne,QAAQ4vB,EAAc,OAAS,KAC3EE,EAAcv+B,KAAK8zB,QAAQzC,iBAAiBiN,QAAoB5iC,GAChEi2B,EAAU3xB,KAAK8zB,QAAQrC,0BAA0BnU,GAQvD,OANAxc,GAAMC,iBAAiBf,KAAKw+B,eAA5B19B,CAA4CotB,EAAUqQ,QAElD5M,UACK3xB,KAAKjD,IAAIg5B,YAAYpE,GAIhC,CACE,GAAa,gBAATvyB,EAKF,YAHI4K,GAAyB,QAAfD,GACZjJ,GAAMC,iBAAiBf,KAAK+zB,iBAAiB,aAA7CjzB,CAA2D,OAK/D,GAAI6K,EAAG2qB,SAAS,UAAYtsB,GAAyB,QAAfD,EAEpC,YADA/J,KAAK+zB,iBAAiBpoB,KAAM6I,EAKlC,MAAO,GAAI4pB,GAAa35B,EAAe,CACrC,MAAM21B,EAAwB,gBAATh7B,EAAyB,kBAAoB,iBAIlE,YAFA0B,GAAMC,iBAAiBf,KAAKo6B,GAA5Bt5B,CAA2CotB,EAAUkQ,EAGvD,CACF,CACF,CAEQ,IAAAjD,CAAK3mB,GACX,MAAMqiB,EAAWjK,GAAUne,QAAQ+F,EAAQ,MAE3C,GAAIxU,KAAK+zB,iBAAiB8C,GACxB/1B,GAAMC,iBAAiBf,KAAK+zB,iBAAiB8C,GAA7C/1B,CAAwD0T,UACjDxU,KAAK+zB,iBAAiB8C,OACxB,CACL,MAAMvZ,EAAOsP,GAAUne,QAAQ+F,EAAQ,QACjCsgB,EAAQlI,GAAUO,WAAW3Y,EAAQ,SACvC8I,GAAQwX,GACV90B,KAAKu8B,qBAAqB/nB,EAE9B,CACF,CAEQ,eAAA4mB,CAAgByB,GACtB,MACMroB,EADkBoY,GAAUW,mBAAmBsP,EAAW,CAAC,OAAQ,YAAa,aACpDA,EAC5Bvf,EAAOsP,GAAUne,QAAQ+F,EAAQ,QACjC8mB,EAAY1O,GAAUne,QAAQ+F,EAAQ,MACtCqZ,EAAcjB,GAAUO,WAAW3Y,EAAQ,eAC3CvP,EAASjF,KAAK8zB,QAAQzC,iBAAiB/T,GACvCxK,EAAQ8Z,GAAUO,WAAW3Y,EAAQ,SACrC4Z,EAAmBP,EAAcjB,GAAUU,eAAeO,EAAa,oBAAsB,KAC7FnqB,EAAOkpB,GAAUU,eAAe9Y,EAAQ,QACxC/S,EAAMosB,EAAcjB,GAAUoB,iBAAiBH,GAAe,KAC9DlsB,EAAYF,EAAMA,EAAIE,UAAY,KAExC,OAAQysB,GACN,IAAK,sBACHttB,GAAMC,iBAAiBf,KAAKy+B,wBAA5B39B,CAAqD,CAAE6K,GAAI2vB,EAAWr2B,SAAQvB,OAAM/B,cACpF,MACF,KAAKjN,GACEoe,GAAS7N,GAAU4oB,GACtB7tB,KAAK0+B,yBAAyBz5B,EAAQ4oB,GAGpC7tB,KAAK2+B,2BAA6B7rB,GACpChS,GAAMC,iBAAiBf,KAAK2+B,yBAAyBjG,UAArD53B,CAAgEmE,EAAQ4oB,GAMhF,CAEQ,wBAAA6Q,CAAyBz5B,EAAqB25B,GACpD,IAAK5+B,KAAK2+B,yBACR,OAGF,MAAM9Q,EAAc7tB,KAAK6+B,iBAAiBD,GAE1C99B,GAAMC,iBAAiBf,KAAK2+B,yBAAyBjG,UAArD53B,CAAgEmE,EAAQ4oB,EAC1E,CAEQ,gBAAAgR,CAAiBhR,GACvB,IAAKA,EACH,MAAO,CAAA,EAGT,MAAMlsB,EAAmC,CAAEm9B,cAAe,GAAIC,aAAc,IA8D5E,OA7DiBnS,GAAUtd,iBAAiBue,GAEnCxtB,QAASsU,IAChB,MAAMka,EAAQjC,GAAUtd,iBAAiBqF,GACnCrU,EAAMssB,GAAU3e,QAAQ0G,IAAY,GAE1C,OAAQrU,GACN,IAAK,WACHqB,EAAUrB,GAAOsC,SAASgqB,GAAUxd,QAAQuF,IAAY,KACxD,MAEF,IAAK,WACH,MAAMvV,EAAOwtB,GAAUxd,QAAQuF,GAC/BhT,EAAUrB,GAAgB,MAATlB,EAAepJ,EAASC,MAAiB,MAATmJ,EAAepJ,EAASE,WAAQwF,EACjF,MAEF,IAAK,gBACHmzB,EAAMxuB,QAASqG,IACb,MAAMk1B,EAA0B,CAAA,EAChChP,GAAUtd,iBAAiB5I,GAAMrG,QAASuO,IACxC,MAAMowB,EAAYpS,GAAU3e,QAAQW,IAAU,GACxCqwB,EAAYrS,GAAUxd,QAAQR,GACpCgtB,EAAUoD,GACM,kBAAdA,EAAgCn3B,OAAOjF,SAASq8B,GAAa,IAAK,KAAQA,GAAa,KAE3Ft9B,EAAUm9B,eAAe57B,KAAK04B,KAEhC,MAEF,IAAK,eACH/M,EAAMxuB,QAASqG,IACb/E,EAAUo9B,cAAc77B,KAAKN,SAASgqB,GAAUxd,QAAQ1I,IAAS,QAEnE,MAEF,QACMmoB,EAAM7rB,OAAS,GACZ4pB,GAAUxd,QAAQuF,IAAY,IAAI3R,OAAS,KAC9CrB,EAAUrB,GAAOuuB,EAAMpB,OAAO,CAACwG,EAAKvtB,IAASutB,EAAMrH,GAAUxd,QAAQ1I,GAAO,IAE5EkmB,GAAUmB,kBAAkBpZ,EAAShT,GAG3B,aAARrB,EACFssB,GAAUmB,kBAAkBpZ,EAAShT,GAErCA,EAAUrB,GAAOssB,GAAUxd,QAAQuF,MAOL,IAApChT,EAAUm9B,eAAe97B,eACpBrB,EAAUm9B,cAGoB,IAAnCn9B,EAAUo9B,cAAc/7B,eACnBrB,EAAUo9B,aAGZp9B,CACT,CAEQ,cAAA05B,CAAe7mB,GAKrB,MAAM8mB,EAAY1O,GAAUne,QAAQ+F,EAAQ,MACtCpT,EAAQwrB,GAAUyB,8BAA8B7Z,GAEtD1T,GAAMC,iBAAiBf,KAAKk/B,uBAA5Bp+B,CAAoDw6B,EAAWl6B,EACjE,CAEQ,kBAAA25B,GACNj6B,GAAMgC,KAAK,SAAU9C,KAAK25B,YAAc,cAAgB,aAExD,MAAMwF,EAAWvS,GAAUK,uBAgB3B,GAdAjtB,KAAK5C,iBAAiB+P,QACtBnN,KAAK8zB,QAAQhD,eAAiB9wB,KAAKovB,WAAW1X,KAAKrW,YAAc,KACjErB,KAAKw5B,aAAc,EACnBx5B,KAAKy5B,cAAe,EACpBz5B,KAAKo/B,gBACLp/B,KAAKovB,WAAWuB,WAAWwO,GAEvBn/B,KAAK25B,YAEP74B,GAAMC,iBAAiBf,KAAKq/B,oBAA5Bv+B,GAEAd,KAAK25B,aAAc,EAGjB35B,KAAK06B,2BAA2B13B,OAAS,EAAG,CAC9ClC,GAAMgC,KAAK,SAAU,8CAA8C9C,KAAK06B,2BAA2B13B,WAEnG,MAAMs8B,EAAkBt/B,KAAKw6B,oBAAoBxvB,IAAI,UAErDhL,KAAK06B,2BAA2Br6B,QAASmU,IACvC8qB,IAAkB9qB,KAEpBxU,KAAK06B,2BAA6B,EACpC,CACF,CAEQ,aAAA0E,GACN,MAAMxI,EAAWhK,GAAUI,eAAe,CACxC5tB,KAAM,MACNke,KAAMtd,KAAK8zB,QAAQhD,eACnBnlB,GAAIihB,GAAU4B,YAAY,mBAG5BoI,EAAS7uB,EAAE,SAAU,CAAEiG,MAAO,uBAE9BhO,KAAKovB,WAAWuB,WAAWiG,EAC7B,CAEQ,iCAAA2I,CAAkCt6B,EAAqB5H,GAC7D,MAAMu5B,EAAWhK,GAAUI,eAAe,CACxCrhB,GAAI3L,KAAK8zB,QAAQtF,YAAY,mBAC7BpvB,KAAM,QAGRw3B,EAAS7uB,EAAE,YAAa,CACtBiG,MAAO,qDACPwxB,SAAUx/B,KAAK8zB,QAAQ9C,YAAY/rB,GACnC5H,WAGF2C,KAAKovB,WAAWuB,WAAWiG,EAC7B,CAEA,iCAAA6I,CAAkCx6B,GAChCjF,KAAKu/B,kCAAkCt6B,GAAQ,EACjD,CAEA,qCAAAy6B,CAAsCz6B,QACrBvJ,IAAXuJ,GAAsBjF,KAAKu/B,kCAAkCt6B,GAAQ,EAC3E,CAEmB,iBAAAk1B,CAAkBrzB,GACnC,OAAQA,GACN,KAAK9P,EAAUM,cACb,MAAO,yBACT,KAAKN,EAAUW,kBACb,MAAO,4BACT,KAAKX,EAAUa,aACb,MAAO,wBACT,KAAKb,EAAUe,KACb,MAAO,iBACT,KAAKf,EAAUgB,MACb,MAAO,kBACT,KAAKhB,EAAUiB,KACb,MAAO,iBACT,QACE,OAAO8Y,MAAMopB,kBAAkBrzB,GAErC,CAEQ,qBAAAg0B,CAAsBh0B,EAA4B2N,GACxD,OAAQ3N,GACN,IAAK,SACH9G,KAAKovB,WAAWvQ,WAAW1P,OAAO7D,MAAOwT,EAASC,KAChDtK,EAASqK,EAAQtK,QAAQnT,kBACnB0d,MAER,MAEF,IAAK,QACH,MAAM4gB,EAAanrB,IACjBC,EAASD,EAAOnT,aAElBrB,KAAKovB,WAAW/vB,GAAG,UAAWsgC,GAC9B3/B,KAAKw6B,oBAAoB16B,IAAIgH,EAAM64B,GACnC,MAEF,QACE3/B,KAAKovB,WAAW/vB,GAAGyH,EAAM2N,GACzBzU,KAAKw6B,oBAAoB16B,IAAIgH,EAAM2N,GAGzC,CAEQ,wBAAAmrB,CAAyB94B,GAC/B,MAAM2N,EAAWzU,KAAKw6B,oBAAoBxvB,IAAIlE,GAC1C2N,GACFzU,KAAKovB,WAAWzb,eAAe7M,EAAM2N,GAEvCzU,KAAKw6B,oBAAoBza,OAAOjZ,EAClC,CAEQ,4BAAA+zB,GACN76B,KAAKw6B,oBAAoBn6B,QAAQ,CAACw/B,EAAG/4B,IAAS9G,KAAK4/B,yBAAyB94B,GAC9E,ECv8BF,IAAIg5B,GAAI3/B,OAAOwX,eAEXooB,GAAI,CAACC,EAAG3V,EAAGtd,IADP,EAACizB,EAAG3V,EAAGtd,IAAMsd,KAAK2V,EAAIF,GAAEE,EAAG3V,EAAG,CAAE4V,YAAY,EAAIC,cAAc,EAAIC,UAAU,EAAIp5B,MAAOgG,IAAOizB,EAAE3V,GAAKtd,EACxFqzB,CAAEJ,EAAe,iBAAL3V,EAAgBA,EAAI,GAAKA,EAAGtd,GAE7D,SAASszB,GAAEL,GACT,MAAM3V,EAAI,uCAAuCjmB,QAAQ,QAAU2I,IACjE,MAAMuzB,EAAoB,GAAhBl+B,KAAKE,SAAgB,EAC/B,OAAc,MAANyK,EAAYuzB,EAAQ,EAAJA,EAAQ,GAAGj/B,SAAS,MAE9C,YAAa,IAAN2+B,EAAe,GAAG3V,KAAK2V,IAAM3V,CACtC,CACA,MAAMkW,GAAI/c,WAAW3F,WAAa2iB,EAAAA,QAClC,MAAMC,GACJ,WAAA9gC,CAAY0qB,GACV0V,GAAE//B,KAAM,UACR+/B,GAAE//B,KAAM,UACR+/B,GAAE//B,KAAM,iBACR+/B,GAAE//B,KAAM,oBAAqB,IAC7B+/B,GAAE//B,KAAM,YACR+/B,GAAE//B,KAAM,qBACR+/B,GAAE//B,KAAM,2BACR+/B,GAAE//B,KAAM,yBACR+/B,GAAE//B,KAAM,2BACR+/B,GAAE//B,KAAM,8BACR+/B,GAAE//B,KAAM,0BACR+/B,GAAE//B,KAAM,wBACR+/B,GAAE//B,KAAM,gCACR+/B,GAAE//B,KAAM,gCACR+/B,GAAE//B,KAAM,gCACR+/B,GAAE//B,KAAM,kBACR+/B,GAAE//B,KAAM,kBACR+/B,GAAE//B,KAAM,wBACR+/B,GAAE//B,KAAM,qBACRA,KAAKa,OAASwpB,CAChB,CACA,aAAMjQ,CAAQiQ,EAAGtd,GACf,OAAOsd,IAAMrqB,KAAKa,OAAO6/B,SAASC,GAAKtW,GAAItd,IAAM/M,KAAKa,OAAO6/B,SAASE,KAAO7zB,GAAI,IAAIrE,QAAQ,CAAC43B,EAAGrhB,KAC/Fjf,KAAKoZ,OAAS,IAAImnB,GAAEvgC,KAAKa,OAAO6/B,SAASC,IAAK3gC,KAAKoZ,OAAOynB,OAAS,KACjE,IAAI3W,EACJ/oB,QAAQgC,IAAI,iBAA+C,OAA5B+mB,EAAIlqB,KAAK8gC,iBAA2B5W,EAAEzpB,KAAKT,MAAOsgC,KAChFtgC,KAAKoZ,OAAO2nB,UAAa7W,IAC1B,IAAI8W,EAAGnB,EAAG7d,EAAG3R,EAAG4wB,EAAG7wB,EAAGzM,EAAGu9B,EAAGC,EAAG/K,EAAGgL,EAAGC,EAAGC,EAAGC,EAC3C,MAAMzxB,EAAI9U,KAAKqJ,MAAM6lB,EAAEprB,MACvB,GAAIqC,QAAQgC,IAAI,mBAAoB2M,GAAIA,EAAE0xB,OAExC,YADmC,OAAlCR,EAAIhhC,KAAKyhC,uBAAiCT,EAAEvgC,KAAKT,KAAM8P,EAAE0xB,SAG5D,GAAI1xB,EAAE4xB,gBAAqC,OAAlB7B,EAAI/vB,EAAEjE,UAAoBg0B,EAAE6B,eAAgB,CACnE,MAAM5pB,EAAIhI,EAAE4xB,iBAAsC,OAAlB1f,EAAIlS,EAAEjE,cAAmB,EAASmW,EAAE0f,iBAAmBC,qBAAsBC,EAAGC,qBAAsBrzB,EAAGszB,oBAAqBC,IAAY,MAALjqB,OAAY,EAASA,EAAEse,IAAM,CAAA,EAClM,OAAIwL,OACyC,OAA1CvxB,EAAIrQ,KAAKgiC,+BAAyC3xB,EAAE5P,KAAKT,KAAM4hC,IAG9DpzB,OACyC,OAA1CyyB,EAAIjhC,KAAKiiC,+BAAyChB,EAAExgC,KAAKT,KAAMwO,IAG9DuzB,OACyC,OAA1C3xB,EAAIpQ,KAAKkiC,+BAAyC9xB,EAAE3P,KAAKT,KAAM+hC,SAG/B,OAAlCp+B,EAAI3D,KAAKmiC,uBAAiCx+B,EAAElD,KAAKT,KAAM8X,GAE1D,CACA,GAAIhI,EAAEsyB,cAEJ,YADqC,OAApClB,EAAIlhC,KAAKqiC,yBAAmCnB,EAAEzgC,KAAKT,KAAM8P,EAAEsyB,gBAG9D,GAAItyB,EAAEwyB,aAEJ,YADsC,OAArCnB,EAAInhC,KAAKuiC,0BAAoCpB,EAAE1gC,KAAKT,KAAM8P,EAAEwyB,eAG/D,GAAIxyB,EAAE0yB,aAEJ,YADoC,OAAnCpM,EAAIp2B,KAAKyiC,wBAAkCrM,EAAE31B,KAAKT,KAAM8P,EAAE0yB,eAG7D,GAAI1yB,EAAE4yB,eAEJ,YADsC,OAArCtB,EAAIphC,KAAK89B,0BAAoCsD,EAAE3gC,KAAKT,KAAM8P,EAAE4yB,iBAG/D,GAAI5yB,EAAE6yB,yBAEJ,YADyC,OAAxCtB,EAAIrhC,KAAK69B,6BAAuCwD,EAAE5gC,KAAKT,KAAM8P,EAAE6yB,2BAGlE,GAAI7yB,EAAEjE,QAAS,CACb,GAAIiE,EAAEjE,QAAQzK,MAAO,CACnB,MAAM0W,EAAIhI,EAAEjE,QAAQF,IAAMxL,OAAOC,KAAKJ,KAAK4iC,mBAAmBzzB,OAAQyyB,GAAkB,IAAZA,EAAE5+B,QAAc2J,OAAM,GAAI,GAEtG,OADA3M,KAAK4iC,kBAAkB9qB,GAAGlP,OAAOkH,EAAEjE,QAAQzK,mBAAepB,KAAK4iC,kBAAkB9qB,EAEnF,CAEA,OADgC,OAA/BwpB,EAAIthC,KAAKm+B,oBAA8BmD,EAAE7gC,KAAKT,KAAM8P,EAAEjE,cAAUiE,EAAEjE,QAAQyR,KAAKjc,aAAerB,KAAKyE,gBAA+C,OAA5B88B,EAAIvhC,KAAK6iC,iBAA2BtB,EAAE9gC,KAAKT,KAAM8P,EAAEjE,UAE5K,CACA,GAAIiE,EAAEgzB,IAAK,CACT,MAAMhrB,EAAIhI,EAAEgzB,IAAIC,IAEhB,OADA/iC,KAAK4iC,kBAAkB9qB,GAAGnP,QAAQmH,EAAEgzB,iBAAa9iC,KAAK4iC,kBAAkB9qB,EAE1E,CACA,MAAM/P,EAAI+H,EAAEtK,SACZ,GAAIuC,EAAG,CACL,MAAM+P,EAAI/P,EAAE4D,GACZ,IAAKmM,EAEH,YADA3W,QAAQC,MAAM2G,EAAE3G,OAGlB,MAAQuH,QAASi5B,EAAGh5B,OAAQ4F,EAAGw0B,UAAWjB,GAAM/hC,KAAK4iC,kBAAkB9qB,GACvE,GAAI/P,EAAE3G,MACe,MAAnB2G,EAAE3G,MAAM4I,OAAiBhK,KAAK4iC,kBAAkB9qB,GAAGlP,OAAOb,EAAE3G,OAASoN,EAAEzG,EAAE3G,YACtE,GAAIU,MAAMF,QAAQmgC,GAAI,CACzB,MAAMkB,EAAIlB,EAAEtU,OAAO,CAAC5pB,EAAGq/B,UAAgB,IAATn7B,EAAEm7B,KAAkBr/B,EAAEq/B,GAAKn7B,EAAEm7B,IAAKr/B,GAAI,IACpEk+B,EAAE7W,MAAOrnB,GAAMA,KAAKo/B,GAAKrB,EAAEqB,GAAKz0B,EAAE,CAAE3C,QAAS,iBAC/C,MAAOk2B,EAAIh6B,EAAEg6B,GAAKH,EAAE75B,EAAEg6B,IAAMvzB,EAAE,CAAE3C,QAAS,kBAAqB+1B,EAAE75B,UACzD/H,KAAK4iC,kBAAkB9qB,EAChC,GACC9X,KAAKoZ,OAAO+pB,QAAWjZ,IACxB/oB,QAAQgC,IAAI,iBAAkB+mB,GAAIjL,EAAEiL,IACnClqB,KAAKoZ,OAAOgqB,QAAU,KACvB,IAAIlZ,EACJ/oB,QAAQgC,IAAI,kBAAmD,OAA/B+mB,EAAIlqB,KAAKqjC,oBAA8BnZ,EAAEzpB,KAAKT,MAAOA,KAAKa,OAAOyiC,sBAAwBtjC,KAAK1C,cAGpI,CACA,SAAAA,GACE,MAAM+sB,EAAI,KACR1uB,UAAU4nC,QAAuC,YAA7BloC,SAASmoC,kBAAkCxjC,KAAKoa,UAAWhf,OAAOsY,oBAAoB,SAAU2W,GAAIhvB,SAASqY,oBAAoB,mBAAoB2W,KAE3K1uB,UAAU4nC,QAAuC,YAA7BloC,SAASmoC,gBAAgCxjC,KAAKoa,WAAahf,OAAOkY,iBAAiB,SAAU+W,GAAIhvB,SAASiY,iBAAiB,mBAAoB+W,GACrK,CACA,gBAAM7Q,GACJ,IAAI6Q,EACJ,OAA4B,OAApBA,EAAIrqB,KAAKoZ,aAAkB,EAASiR,EAAElQ,OAChD,CACA,iBAAMspB,CAAYpZ,EAAGtd,EAAI,CAAA,EAAIuzB,EAAI,WAC/B,MAAMrhB,EAAI,CACRe,QAAS,CACPqK,CAACA,GAAItd,EACLpB,GAAI00B,GAAEhW,KAGV,OAAOrqB,KAAK0jC,YAAYzkB,EAAGqhB,EAC7B,CACA,iBAAMoD,CAAYrZ,EAAGtd,GACnB,OAAO,IAAIrE,QAAQ,CAAC43B,EAAGrhB,KAChBjf,KAAKoZ,QAIVpZ,KAAKoZ,OAAOxE,KAAK5Z,KAAK8I,UAAUumB,IAAKlpB,QAAQgC,IAAI,gBAAiBknB,GAAIrqB,KAAK4iC,kBAAkBvY,EAAErK,QAAQrU,IAAM,CAAEhD,QAAS23B,EAAG13B,OAAQqW,EAAG+jB,UAAWj2B,IAH/IkS,EAAE,6BAKR,CACA,qBAAM0kB,CAAgBtZ,EAAGtd,EAAGuzB,GAC1Bn/B,QAAQgC,IAAI,iBAAkB,CAAE6c,QAASsgB,IACzC,MAAMrhB,EAAI,CAAE,eAAgB,oBAAsBiL,EAAI0Z,aAAaC,QAAQ,aAC3E3Z,IAAMjL,EAAE6kB,cAAgB,UAAU5Z,KAClC,MAAMpa,EAAI,CACR5J,OAAQmkB,EACR/F,YAAa,UACb1gB,QAASqb,GAEXqhB,IAAMxwB,EAAEpM,KAAO1I,KAAK8I,UAAUw8B,IAC9B,MAAMv4B,QAAUmB,MAAM,GAAGlJ,KAAKa,OAAO6/B,SAASE,QAAQ7zB,IAAK+C,GAAIkxB,QAAUj5B,EAAEuB,OAC3E,IAAKvB,EAAEwB,GACL,MAAMpI,QAAQC,MAAM,eAAgB4/B,GAAIA,GAAKj5B,EAAEg8B,WACjD,MAAMlE,EAAImB,EAAIhmC,KAAKqJ,MAAM28B,GAAK,CAAA,EAC9B,OAAO7/B,QAAQgC,IAAI,kBAAmB,CAAEqC,SAAUq6B,IAAMA,CAC1D,CACA,mBAAMmE,CAAc3Z,GAClB,OAAOrqB,KAAKyjC,YAAY,UAAW,CAAE79B,MAAOykB,EAAEzkB,MAAOq+B,UAAW5Z,EAAE6Z,UAAYlkC,KAAKkkC,UACrF,CACA,iBAAMC,CAAY9Z,GAChB,OAAOrqB,KAAKyjC,YAAY,aAAc,CAAEW,gBAAiBpkC,KAAKa,OAAOujC,mBAAoB/Z,EAAE3e,KAAMu4B,UAAW5Z,EAAE6Z,UAAYlkC,KAAKkkC,SAAUt+B,MAAOykB,EAAEzkB,OAAS,CAAC,OAAQ,SACtK,CACA,sBAAMy+B,GACJ,OAAOrkC,KAAKyjC,YAAY,cAC1B,CACA,gBAAMa,CAAWja,GACf,OAAOrqB,KAAKyjC,YAAY,cAAe,CAAEW,gBAAiBpkC,KAAKa,OAAOujC,gBAAiB3lC,MAAO4rB,EAAE5rB,MAAOwN,MAAOoe,EAAEpe,MAAOD,SAAUqe,EAAEre,UAAY,OACjJ,CACA,cAAMu4B,CAASla,GACb,OAAOrqB,KAAKyjC,YAAY,YAAapZ,EAAG,OAC1C,CACA,eAAMma,CAAUna,GACd,MAAQ5rB,MAAOsO,EAAGf,SAAUs0B,GAAMjW,GAAK,GAAIpL,EAAIvc,KAAKC,MACpDC,SAASghC,aAAaC,QAAQ,qBAAuB,GAAG5kB,IAAK,IAAMA,GAAK,GAAK2kB,aAAaa,WAAW,aACrG,MAAM30B,EAAI,CAAEs0B,gBAAiBpkC,KAAKa,OAAOujC,gBAAiBH,UAAWjkC,KAAKkkC,UAC1E,OAAOn3B,GAAKuzB,IAAMxwB,EAAErR,MAAQsO,EAAG+C,EAAE9D,SAAWs0B,SAAUtgC,KAAK2jC,gBAAgB,OAAQ,QAAS7zB,EAC9F,CACA,gBAAM40B,GACJ,aAAa1kC,KAAK2jC,gBAAgB,OAAQ,SAAU,KACtD,CACA,sBAAMgB,CAAiBta,GACrB,MAAMtd,EAAI,CAAEq3B,gBAAiBpkC,KAAKa,OAAOujC,gBAAiBH,UAAWjkC,KAAKkkC,SAAUj4B,MAAOoe,EAAEpe,OAC7F,OAAOjM,KAAKyjC,YAAY,gBAAiB12B,EAC3C,CACA,uBAAM63B,CAAkBva,GACtB,MAAMtd,EAAI,CAAEq3B,gBAAiBpkC,KAAKa,OAAOujC,gBAAiBH,UAAWjkC,KAAKkkC,SAAUj4B,MAAOoe,EAAEpe,MAAOrG,MAAOykB,EAAEzkB,MAAOi/B,aAAcxa,EAAEwa,cACpI,OAAO7kC,KAAKyjC,YAAY,sBAAuB12B,EACjD,CACA,gBAAM+3B,GACJ,OAAOlB,aAAaa,WAAW,aAAczkC,KAAKyjC,YAAY,cAChE,CACA,gBAAMsB,CAAW1a,GACf,MAAMtd,EAAI,CACRi4B,QAAS3a,EAAE2a,QACXC,WAAY5a,EAAE4a,YAAc,MACzB5a,EAAE6a,OAAS,CAAEA,MAAO7a,EAAE6a,UACtB7a,EAAE8a,YAAc,CAAEA,WAAY9a,EAAE8a,aAErC,OAAOnlC,KAAKyjC,YAAY,cAAe12B,EAAG,QAC5C,CACA,mBAAMq4B,CAAc/a,GAClB,OAAOrqB,KAAKyjC,YAAY,mBAAoB,CAAE1L,IAAK1N,EAAE0N,KAAO,QAC9D,CACA,2BAAMsN,CAAsBhb,GAC1B,OAAOrqB,KAAKyjC,YAAY,2BAA4B,CAAE6B,KAAMjb,EAAEib,MAAQ,CAAC,QAAS,iBAClF,CACA,6BAAMC,CAAwBlb,GAC5B,OAAOrqB,KAAKyjC,YAAY,eAAgBpZ,EAAEmb,MAAO,QACnD,CACA,4BAAMC,CAAuBpb,GAC3B,OAAOrqB,KAAKyjC,YAAY,gBAAiB,CAAEiC,SAAUrb,EAAEqb,UAAY,YACrE,CACA,mBAAMC,CAActb,GAClB,OAAO,IAAI3hB,QAAQ,CAACqE,EAAGuzB,KACrB,IAAIpW,EACJ,MAAMjL,EAAI,CACRpT,QAAS,CACPF,GAAI0e,EAAE0Y,IACNr/B,KAAM2mB,EAAE3mB,KACRkiC,IAAKvb,EAAEub,IACPxP,EAAG/L,EAAE+L,EACLnI,YAAa5D,EAAE4D,YACf4X,mBAAoBxb,EAAEwb,mBACtBC,qBAAsBzb,EAAEyb,uBAG5B9lC,KAAK4iC,kBAAkB3jB,EAAEpT,QAAQF,IAAM,CAAEhD,QAASoE,EAAGnE,OAAQ03B,GAA0B,OAApBpW,EAAIlqB,KAAKoZ,SAAmB8Q,EAAEtV,KAAK5Z,KAAK8I,UAAUmb,IAAK9d,QAAQgC,IAAI,gBAAiB8b,IAE3J,CACA,mBAAM8mB,CAAc1b,GAClB,OAAO,IAAI3hB,QAAQ,CAACqE,EAAGuzB,KACrB,IAAIpW,EACJ,MAAMjL,EAAI,CACRyiB,eAAgB,CACd/1B,GAAI0e,EAAE0Y,IACNiD,KAAM3b,EAAE2b,KACRJ,IAAKvb,EAAEub,IACPxP,EAAG/L,EAAE+L,IAGTp2B,KAAK4iC,kBAAkB3jB,EAAEyiB,eAAe/1B,IAAM,CAAEhD,QAASoE,EAAGnE,OAAQ03B,GAA0B,OAApBpW,EAAIlqB,KAAKoZ,SAAmB8Q,EAAEtV,KAAK5Z,KAAK8I,UAAUmb,IAAK9d,QAAQgC,IAAI,gBAAiB8b,IAElK,CACA,iBAAMgnB,CAAY5b,GAChB,MAAMtd,EAAI,CACR64B,IAAKvb,EAAEub,OACJvb,EAAE0N,KAAO,CAAEA,IAAK1N,EAAE0N,QAClB1N,EAAE6a,OAAS,CAAEA,MAAO7a,EAAE6a,UACtB7a,EAAE8a,YAAc,CAAEA,WAAY9a,EAAE8a,aAErC,OAAOnlC,KAAKyjC,YAAY,eAAgB12B,EAAG,WAC7C,CACA,oBAAMm5B,CAAe7b,GACnB,OAAOrqB,KAAKyjC,YAAY,kBAAmB,CAAEmC,IAAKvb,EAAEub,IAAKz2B,OAAQkb,EAAElb,QAAU,UAC/E,CACA,iBAAMg3B,CAAY9b,GAChB,OAAOrqB,KAAKyjC,YAAY,eAAgB,CAAE//B,KAAM2mB,EAAE3mB,KAAM0iC,KAAM/b,EAAE+b,MAAQ,UAC1E,CACA,4BAAMC,CAAuBhc,GAC3B,OAAOrqB,KAAKyjC,YAAY,eAAgB,CAAEmC,IAAKvb,EAAEub,IAAK7N,IAAK1N,EAAEic,MAC/D,CACA,iBAAMC,CAAYlc,GAChB,OAAOrqB,KAAKyjC,YAAY,eAAgB,CAAE93B,GAAI0e,EAAE0Y,IAAKr/B,KAAM2mB,EAAE3mB,MAC/D,CACA,mBAAM8iC,CAAcnc,GAClB,OAAOrqB,KAAKyjC,YAAY,iBAAkB,CAAEmC,IAAKvb,EAAEub,IAAK7N,IAAK1N,EAAEic,KAAMlnC,KAAMirB,EAAEjrB,MAAQ,UACvF,CACA,qBAAMqnC,CAAgBpc,GACpB,OAAOrqB,KAAKyjC,YAAY,qBAAsB,CAAE1L,IAAK1N,GAAK,gBAC5D,CACA,6BAAMqc,CAAwBrc,GAC5B,OAAOrqB,KAAKyjC,YAAY,+BAAgC,CAAE93B,GAAI0e,GAAK,gBACrE,CACA,iCAAMsc,GACJ,OAAO3mC,KAAKyjC,YAAY,iCAC1B,CACA,sBAAMmD,CAAiBvc,GACrB,OAAO,IAAI3hB,QAAQ,CAACqE,EAAGuzB,KACrB,IAAIpW,EACJ,MAAMjL,EAAI,CAAEuiB,OAAQ,CAAEoE,IAAKvb,EAAEub,IAAK57B,OAAQqgB,EAAErgB,SACvB,OAApBkgB,EAAIlqB,KAAKoZ,SAAmB8Q,EAAEtV,KAAK5Z,KAAK8I,UAAUmb,IAAK9d,QAAQgC,IAAI,gBAAiB8b,GAAIlS,KAE7F,CACA,wBAAM85B,CAAmBxc,GACvB,OAAOrqB,KAAKyjC,YAAY,sBAAuBpZ,EAAG,eACpD,CACA,wBAAMyc,CAAmBzc,GACvB,IAAItd,EAAGuzB,EACP,OAAOtgC,KAAKyjC,YAAY,sBAAuB,CAC7C93B,GAAI0e,EAAEub,IACN9+B,KAAMujB,EAAEvjB,KACRigC,YAAa1c,EAAE0c,YACfC,aAAc,CACZnqB,IAA6B,OAAvB9P,EAAIsd,EAAE2c,mBAAwB,EAASj6B,EAAE8P,IAC/C9M,OAAgC,OAAvBuwB,EAAIjW,EAAE2c,mBAAwB,EAAS1G,EAAEvwB,QAEpDk3B,aAAc5c,EAAE4c,cACf,eACL,CACA,sBAAMC,CAAiB7c,GACrB,IAAIiW,EACJ,MAAMvzB,EAAI,IACLsd,EAAE6a,OAAS,CAAEA,MAAO7a,EAAE6a,UACtB7a,EAAE8a,YAAc,CAAEA,WAAY,CAAEgC,GAAI9c,EAAE8a,WAAWgC,GAAIp1B,GAAIsY,EAAE8a,WAAWpzB,SACtD,OAAduuB,EAAIjW,EAAE0N,YAAwBuI,EAAEt9B,SAAW,CAAE+0B,IAAK1N,EAAE0N,MAE3D,OAAO/3B,KAAKyjC,YAAY,oBAAqB12B,EAAG,gBAClD,CACA,wBAAMq6B,CAAmB/c,GACvB,OAAOrqB,KAAKyjC,YAAY,sBAAuB,CAAE93B,GAAI0e,EAAEub,KACzD,CACA,wBAAMyB,CAAmBhd,GACvB,OAAOrqB,KAAKyjC,YACV,sBACA,CAAE38B,KAAMujB,EAAEvjB,QAAoB,MAAXujB,EAAE6a,OAAiB,CAAEA,MAAO7a,EAAE6a,QACjD,gBAEJ,CACA,+BAAMoC,CAA0Bjd,GAC9B,OAAOrqB,KAAKyjC,YAAY,8BAA+B,CAAEmC,IAAKvb,EAAEub,IAAK2B,QAASld,EAAEkd,SAClF,CACA,4BAAMC,CAAuBnd,GAC3B,OAAOrqB,KAAKyjC,YAAY,2BAA4B,CAAEmC,IAAKvb,EAAEub,KAAO,uBACtE,CACA,+BAAM6B,CAA0Bpd,GAC9B,OAAOrqB,KAAKyjC,YAAY,8BAA+B,CAAEmC,IAAKvb,EAAEub,KAClE,CACA,4BAAM8B,CAAuBrd,GAC3B,OAAOrqB,KAAKyjC,YAAY,2BAA4B,CAClDkE,SAAU,MACVC,aAAcvd,EAAEud,aAChBC,aAAcxd,EAAEwd,aAChBC,eAAgBzd,EAAEyd,eAClBC,YAAa/nC,KAAKkkC,UACjB,eACL,CACA,4BAAM8D,GACJ,OAAOhoC,KAAKyjC,YAAY,2BAA4B,CAAEsE,YAAa/nC,KAAKkkC,UAC1E,CACA,UAAMhK,GACJ,OAAOl6B,KAAKyjC,YAAY,OAAQ,CAAA,EAAI,OACtC,CACA,uBAAMwE,CAAkB5d,GACtB,OAAOrqB,KAAKyjC,YAAY,kBAAmB,CAAEyE,aAAc7d,GAAK,UAClE,CACA,eAAM8d,GACJ,OAAOnoC,KAAKyjC,YAAY,qBAAsB,CAAA,EAAI,QACpD,CACA,gBAAM2E,CAAW/d,GACf,OAAOrqB,KAAKyjC,YAAY,aAAc,CAAE1L,IAAK1N,GAAK,UACpD,CACA,kBAAMge,CAAahe,GACjB,OAAOrqB,KAAKyjC,YAAY,eAAgB,CAAE1L,IAAK1N,GAAK,UACtD,CACA,qBAAMie,CAAgBje,EAAGtd,EAAGuzB,GAC1B,OAAOtgC,KAAKyjC,YAAY,2BAA4B,CAAEV,IAAK1Y,EAAGxN,IAAK9P,EAAGgD,OAAQuwB,GAAK,UACrF,CACA,mBAAMiI,CAAcle,GAClB,OAAOrqB,KAAKyjC,YAAY,yBAA0B,CAAEV,IAAK1Y,GAAK,YAChE,EC9WY,MAAOme,GACXC,WAER,WAAA9oC,CAAY8oC,GACVzoC,KAAKyoC,WAAaA,CACpB,CAIO,WAAMC,CAAMC,GACZ7mC,MAAMF,QAAQ+mC,KACjBA,EAAU,CAACA,UAGP3oC,KAAKyoC,WAAWL,WAAWO,EACnC,CAIO,aAAMC,CAAQD,GACd7mC,MAAMF,QAAQ+mC,KACjBA,EAAU,CAACA,UAGP3oC,KAAKyoC,WAAWJ,aAAaM,EACrC,CAEO,UAAM/9B,GAEX,aADuB5K,KAAKyoC,WAAWN,WAEzC,ECvBY,MAAOU,WAAwBvP,GACpCmP,WACAN,UACAW,oBAAmC,EAE1C,WAAAnpC,CAAY8K,GACVsG,MAAMtG,GAENzK,KAAKyoC,WAAa,IAAIM,GAAW,CAC/BrI,SAAU,CACRC,GAAI9/B,EAAO7D,aAAaE,WAAa,GACrC0jC,KAAM,WAAW//B,EAAOjE,UAAUC,OAEpCunC,gBAAiB,GAAGvjC,EAAOpE,MAAMC,QACjC4mC,sBAAsB,IAGxBtjC,KAAKmoC,UAAY,IAAIK,GAAUxoC,KAAKyoC,WACtC,CAEA,oBAAW9N,GACT,MAAO,EACT,CAEA,iBAAWl2B,GACT,OAAOzE,KAAK8oC,qBAAuB,CACrC,CAEO,aAAM1uB,CAAQhV,GACnBtE,GAAMgC,KAAK,SAAU,0BAA2BsC,GAEhDpF,KAAKyoC,WAAWvE,SAAW9+B,EAAO8+B,UAAYpjC,GAAMmB,kBAEpDjC,KAAKgpC,yBACLhpC,KAAKipC,sBAEAjpC,KAAKw5B,oBACFx5B,KAAKyoC,WAAWruB,UAEtBpa,KAAKw5B,aAAc,GAGrB,MAAM0P,QAAuBlpC,KAAKyoC,WAAWtE,YAAY,CACvDz4B,KAAM,CAAEzG,OAAQG,EAAOH,OAAQ+G,SAAU5G,EAAO4G,YAMlD,OAHAhM,KAAK8oC,oBAAsBI,EAAex9B,KAAKy9B,UAC/CnpC,KAAK05B,UAAW,GAET,CACT,CAEO,gBAAMlgB,GACX1Y,GAAMgC,KAAK,SAAU,cAErB9C,KAAKw5B,aAAc,EAEnB,IAIE,aAHMx5B,KAAKyoC,WAAWpE,yBAChBrkC,KAAKyoC,WAAWjvB,aACtBxZ,KAAK8oC,oBAAsB,GACpB,CACT,CAAE,MACA,OAAO,CACT,CACF,CAEO,SAAAlM,GACL97B,GAAMgC,KAAK,SAAU,cAErB9C,KAAKw5B,aAAc,EACnBx5B,KAAK8oC,oBAAsB,EAE3B9oC,KAAKyoC,WAAWjvB,YAClB,CAEQ,uBAAA4vB,GACNtoC,GAAMgC,KAAK,SAAU9C,KAAKyoC,WAAWvE,SAAU,eAE/ClkC,KAAKw5B,aAAc,EAEnB14B,GAAMC,iBAAiBf,KAAKi7B,qBAA5Bn6B,CAAkD,UACpD,CAEQ,wBAAAuoC,GACNvoC,GAAMgC,KAAK,SAAU9C,KAAKyoC,WAAWvE,SAAU,gBAE/ClkC,KAAKw5B,aAAc,EACnBx5B,KAAK05B,UAAW,EAEhB54B,GAAMC,iBAAiBf,KAAKi7B,qBAA5Bn6B,CAAkD,cAClDA,GAAMC,iBAAiBf,KAAKg7B,uBAA5Bl6B,EACF,CAEQ,0BAAAwoC,CAA2Bz9B,GACjC/K,GAAMgC,KAAK,SAAU,WAAY9C,KAAKyoC,WAAWvE,SAAUr4B,EAC7D,CAEQ,qBAAA09B,CAAsB19B,GAC5B/K,GAAMgC,KAAK,SAAU,cAAe9C,KAAKyoC,WAAWvE,SAAUr4B,GAE9D,MAAM29B,IAAEA,EAAG5D,IAAEA,EAAGtoB,KAAEA,EAAI5Z,KAAEA,EAAIoM,EAAEA,EAACsmB,EAAEA,EAACnI,YAAEA,GAAgBpiB,EAE9C49B,EAA8B,CAClC99B,GAAI69B,EACJrb,UAAWyX,EACXliC,KAAMA,EACN/B,UAAWxB,OAAO6I,OAAO,CAAE0gC,UAAW55B,EAAGme,eAAemI,IAG1Dt1B,GAAMC,iBAAiBf,KAAKm+B,kBAA5Br9B,CAA+Cwc,EAAMmsB,EACvD,CAEQ,2BAAAE,CAA4B99B,GAClC/K,GAAMgC,KAAK,SAAU,aAAc9C,KAAKyoC,WAAWvE,SAAUr4B,GAE7D,MAAM29B,IAAEA,EAAGlsB,KAAEA,EAAIxN,EAAEA,EAACsmB,EAAEA,GAAMvqB,EAEtB+9B,EAAoC,CACxCj+B,GAAI69B,EACJ9lC,KAAM,KACNuB,OAAQqY,EACR3b,UAAWxB,OAAO6I,OAAO,CAAE0gC,UAAW55B,GAAKsmB,IAG7C,GAAIwT,EAAcjoC,WAA8B,mBAAMjN,EACpD,OAAOsL,KAAK6pC,+BAA+BD,GAG7C9oC,GAAMC,iBAAiBf,KAAKy+B,wBAA5B39B,CAAqD8oC,EACvD,CAEQ,8BAAAC,CAA+BD,GACrC,MAAMjoC,EAAYioC,EAAcjoC,WAAa,CAAA,EAiC7C,OA/BAxB,OAAOC,KAAKuB,GAAWtB,QAASC,IAC9B,OAAQA,GACN,IAAK,WACHqB,EAAUrB,GAAOsC,SAASiF,OAAOlG,EAAUrB,IAAQ,MACnD,MAEF,IAAK,WACH,MAAMlB,EAAOuC,EAAUrB,GACvBqB,EAAUrB,GAAwB,MAAjBuH,OAAOzI,GAAgBpJ,EAASC,MAAyB,MAAjB4R,OAAOzI,GAAgBpJ,EAASE,WAAQwF,EACjG,MAEF,IAAK,eACHiG,EAAUrB,IAAM4S,IAAK42B,GAAerzB,OAAOqzB,GAAc,MACzD,MAEF,IAAK,gBACFnoC,EAAUrB,IAAgCD,QAAS0pC,IAClD,MAAMhiC,EAAIgiC,EACV5pC,OAAOC,KAAK2H,GAAG1H,QAAS2pC,IACD,kBAAjBA,IACFjiC,EAAEiiC,GAAgBpnC,SAASiF,OAAOE,EAAEiiC,IAAiB,cAW1DlpC,GAAMC,iBAAiBf,KAAK2+B,yBAAyBjG,UAArD53B,CACL8oC,EAAc3kC,OACd2kC,EAAcjoC,UAElB,CAEQ,2BAAAsoC,CAA4Bp+B,GAClC/K,GAAMgC,KAAK,SAAU,aAAc9C,KAAKyoC,WAAWvE,SAAUr4B,GAE7D,MAAMksB,IAAEA,EAAG6N,IAAEA,EAAGtoB,KAAEA,GAASzR,EAE3B,IAAK,MAAMyvB,KAAavD,EACtBj3B,GAAMC,iBAAiBf,KAAKg+B,qBAA5Bl9B,CAAkDw6B,EAAWsK,EAAKtoB,EAEtE,CAEQ,8BAAA4sB,CAA+Br+B,GACrC/K,GAAMgC,KAAK,SAAU,mBAAoB9C,KAAKyoC,WAAWvE,SAAUr4B,GAEnE1L,OAAOwQ,QAAQ9E,GAASxL,QAAQ,EAAE4E,EAAQklC,MACxCrpC,GAAMC,iBAAiBf,KAAKy8B,2BAA5B37B,CAAwD2V,OAAOxR,GAASwR,OAAO0zB,KAEnF,CAEQ,oBAAAC,CAAqBv+B,GAC3B/K,GAAMgC,KAAK,SAAU,aAAc9C,KAAKyoC,WAAWvE,SAAUr4B,GAE7D,MAAM+5B,IAAEA,EAAGtoB,KAAEA,EAAItT,OAAEA,GAAW6B,EACxBw+B,EAAsB,UAAXrgC,EAEjBlJ,GAAMC,iBAAiBf,KAAK29B,wBAA5B78B,CAAqDupC,EAAU/sB,EAAMsoB,EACvE,CAEQ,yBAAA0E,CAA0Bz+B,GAChC/K,GAAMgC,KAAK,SAAU,WAAY9C,KAAKyoC,WAAWvE,SAAUr4B,GAE3D,MAAMF,GAAEA,EAAEi6B,IAAEA,EAAGtoB,KAAEA,EAAI5Z,KAAEA,GAASmI,EAE1B0+B,EAAoB,CACxBjP,UAAW3vB,EACX6+B,QAAQ,EACRC,YAAa/mC,EACbwqB,SAAU0X,EACV3gC,OAAQqY,EACRuQ,YAAa,CAAA,GAGf/sB,GAAMC,iBAAiBf,KAAK49B,wBAA5B98B,CACEypC,EAAkBjP,UAClBiP,EAAkBC,OAClBD,EAAkBE,YAClBF,EAAkBrc,SAClBqc,EAAkBtlC,OAClBslC,EAAkB1c,YAEtB,CAEQ,oBAAA6c,CAAqB7+B,GAC3B/K,GAAMgC,KAAK,SAAU,aAAc9C,KAAKyoC,WAAWvE,SAAUr4B,GAE7D,MAAMksB,IAAEA,EAAG6N,IAAEA,EAAGtoB,KAAEA,GAASzR,EAE3B,IAAK,MAAMyvB,KAAavD,EACtBj3B,GAAMC,iBAAiBf,KAAK89B,wBAA5Bh9B,CAAqDw6B,EAAWsK,EAAKtoB,EAEzE,CAEQ,6BAAAqtB,CAA8BC,GACpC9pC,GAAMgC,KAAK,SAAU,eAAgB9C,KAAKyoC,WAAWvE,SAAU0G,GAE/D,MAAM7H,IAAEA,EAAG6C,IAAEA,EAAGtoB,KAAEA,EAAIT,IAAEA,EAAG9M,OAAEA,GAAW66B,EAExC9pC,GAAMC,iBAAiBf,KAAK69B,2BAA5B/8B,CAAwDiiC,EAAKzlB,EAAMsoB,EAAK/oB,EAAK9M,EAC/E,CAEO,UAAMmqB,SACLl6B,KAAKyoC,WAAWvO,MACxB,CAEO,wBAAM4B,CAAmB5N,GAC9B,MAAM2c,EAAgB,CACpBjF,IAAK/9B,OAAOqmB,GACZlkB,OAAQ,eAGJhK,KAAKyoC,WAAW7B,iBAAiBiE,EACzC,CAEO,4BAAM9O,CAAuB7N,GAClC,MAAM2c,EAAgB,CACpBjF,IAAK/9B,OAAOqmB,GACZlkB,OAAQ,cAGJhK,KAAKyoC,WAAW7B,iBAAiBiE,EACzC,CAEO,UAAMj2B,CAAKsZ,EAAuCriB,GACvD,MAAMk3B,EAAMl3B,EAAQF,IAAM7K,GAAMmB,kBAC1Bm0B,EAAIvqB,EAAQlK,WAAa,CAAA,EACzBssB,EAAcmI,GAAiB,mBAC9BA,GAAiB,YAExB,MAAMyU,EAAgB,CACpB9H,MACAr/B,KAAMmI,EAAQnI,MAAQ,GACtB0yB,IACAnI,cACA2X,IAAK/9B,OAAOqmB,IAGR4c,QAAY9qC,KAAKyoC,WAAW9C,cAAckF,GAEhD,OAAOC,GAAKC,YAAchI,CAC5B,CAKO,uBAAMvH,CACXwP,EACAn/B,GAEA,MAAMk3B,EAAMl3B,EAAQF,IAAM7K,GAAMmB,kBAE1BgpC,EAAoBnpC,MAAMF,QAAQopC,GACpC,CAAEhF,KAAMgF,GACqB,iBAAtBA,EACL,CAAEhF,KAAM,CAACgF,IACT,CAAEpF,IAAKoF,GAEPH,EAAgB,CACpB9H,MACA3M,EAAGvqB,EAAQlK,WAAa,CAAA,KACrBspC,GAKL,OAFAjrC,KAAKyoC,WAAW1C,cAAc8E,GAEvB9H,CACT,CAEO,gCAAMpH,CAA2B12B,EAAgB4G,GACtD,aAAa7L,KAAKw7B,kBAAkBv2B,EAAQ4G,EAC9C,CAEO,yBAAMmwB,CAAoBkP,GAAmD,CAE7E,oBAAMjP,CAAe72B,GAC1B,MAAMylC,EAAgB,CACpBjF,IAAKxgC,EAAO8oB,SACZoY,KAAM,CAAClhC,EAAOk2B,kBAGVt7B,KAAKyoC,WAAWpC,uBAAuBwE,EAC/C,CAEO,sBAAMM,CAAiB/lC,GAC5B,MAAMylC,EAAgB,CACpBjF,IAAKxgC,EAAO8oB,gBAGRluB,KAAKyoC,WAAWpC,uBAAuBwE,EAC/C,CAEO,oBAAMxS,CAAeiD,EAAmBlD,EAAqBE,SAC5Dt4B,KAAKyoC,WAAWH,gBAAgBhN,EAAWlD,EAAaE,EAChE,CAEO,iBAAM4D,CAAY92B,GACvB,MAAMylC,EAAgB,CACpB9H,IAAK39B,EAAO+2B,gBACZz4B,KAAM0B,EAAO1B,YAGT1D,KAAKyoC,WAAWlC,YAAYsE,EACpC,CAEO,mBAAMxO,CAAcj3B,GACzB,MAAMylC,EAAgB,CACpBjF,IAAKxgC,EAAO8oB,SACZoY,KAAM,CAAClhC,EAAOk2B,WACdl8B,KAAM,aAGFY,KAAKyoC,WAAWjC,cAAcqE,EACtC,CAEO,yBAAMvO,CAAoBr3B,GAC/B,MAAMiI,QAAelN,KAAKyoC,WAAWhC,gBAAgB,CAACxhC,IAEtD,KAAMA,KAAUiI,GACd,MAAM,IAAIrC,MAAM,kBAGlB,MAAMugC,EAAel+B,EAAOjI,GAE5B,OAAqB,IAAjBmmC,EACK,CAAEnmC,SAAQu3B,QAAS4O,GAGrB,CAAEnmC,SAAQu3B,QAAU4O,EAA8BhpC,KAAKipC,MAAM,IAAI3oC,KAAS,KAAQ0oC,EAA/CA,EAC5C,CAEO,uCAAM3L,CAAkCx6B,GAC7C,aAAajF,KAAKyoC,WAAW/B,wBAAwBzhC,EACvD,CAEO,2CAAMy6B,CAAsC4L,GACjD,aAAatrC,KAAKyoC,WAAW9B,6BAC/B,CAEO,gBAAMjK,SACL18B,KAAKyoC,WAAWR,mBAAkB,EAC1C,CAEO,kBAAMtL,SACL38B,KAAKyoC,WAAWR,mBAAkB,EAC1C,CAEQ,mBAAAgB,GACNjpC,KAAKyoC,WAAW3H,eAAiB9gC,KAAKopC,wBAAwB51B,KAAKxT,MACnEA,KAAKyoC,WAAWpF,kBAAoBrjC,KAAKqpC,yBAAyB71B,KAAKxT,MAEvEA,KAAKyoC,WAAWtK,kBAAoBn+B,KAAKspC,2BAA2B91B,KAAKxT,MACzEA,KAAKyoC,WAAW5F,eAAiB7iC,KAAKupC,sBAAsB/1B,KAAKxT,MACjEA,KAAKyoC,WAAWtG,qBAAuBniC,KAAK2pC,4BAA4Bn2B,KAAKxT,MAE7EA,KAAKyoC,WAAWlG,wBAA0BviC,KAAKiqC,4BAA4Bz2B,KAAKxT,MAChFA,KAAKyoC,WAAW5K,2BAA6B79B,KAAK2qC,8BAA8Bn3B,KAAKxT,MAErFA,KAAKyoC,WAAWhG,sBAAwBziC,KAAKsqC,0BAA0B92B,KAAKxT,MAC5EA,KAAKyoC,WAAW3K,wBAA0B99B,KAAK0qC,qBAAqBl3B,KAAKxT,MAEzEA,KAAKyoC,WAAWpG,uBAAyBriC,KAAKkqC,+BAA+B12B,KAAKxT,MAClFA,KAAKyoC,WAAWhH,qBAAuBzhC,KAAKoqC,qBAAqB52B,KAAKxT,KACxE,CAEQ,sBAAAgpC,GACNhpC,KAAKyoC,WAAW3H,oBAAiB,EACjC9gC,KAAKyoC,WAAWpF,uBAAoB,EAEpCrjC,KAAKyoC,WAAWtK,uBAAoB,EACpCn+B,KAAKyoC,WAAW5F,oBAAiB,EACjC7iC,KAAKyoC,WAAWtG,0BAAuB,EAEvCniC,KAAKyoC,WAAWlG,6BAA0B,EAC1CviC,KAAKyoC,WAAW5K,gCAA6B,EAE7C79B,KAAKyoC,WAAWhG,2BAAwB,EACxCziC,KAAKyoC,WAAW3K,6BAA0B,EAE1C99B,KAAKyoC,WAAWpG,4BAAyB,EACzCriC,KAAKyoC,WAAWhH,0BAAuB,CACzC,4DC9aF,MAAMhmC,QACJA,EAAOE,UACPA,EAASE,YACTA,EAAWC,iBACXA,EAAgBE,kBAChBA,EAAiBC,eACjBA,EAAcC,aACdA,EAAYX,cACZA,GACEkS,GA4BJ89B,EAAMC,SAAW,CAAA,EAEjBD,EAAME,OAASlwC,EAEfgwC,EAAMG,mBAAqB,WACzB,GAAIH,EAAME,OACR,OAAO,EAET,GAAI9vC,EAAUC,cAAgBD,EAAUC,aAAa+vC,gBAEnD,OAAO,EAET,GAAIvwC,OAAOO,UAAUopB,UAAUxY,MAAM,UAAW,CAC9C,IAAIq/B,EAAYhpC,SAASxH,OAAOO,UAAUopB,UAAUxY,MAAM,iBAAiB,GAAI,IAC3Es/B,EAAS,GAEb,OADIzwC,OAAOO,UAAUopB,UAAUxY,MAAM,WAAUs/B,EAAS,IACpDD,GAAa,IAAMA,GAAaC,GAI7BN,EAAM5pC,UAAUmqC,cAGvB,OAAO,CAEX,EAEA,MAAMC,EAAmB,CAEvBC,YAAa,mCACbF,YAAa,WACX,OAAIP,EAAME,QAGwD,OAAzDpwC,SAAS4wC,cAAc,+BAGlCC,UAAW,SAAUC,GACnB,GAAIZ,EAAME,OACRU,QACK,CACL,IAAIC,EAAUhxC,OAAOyX,WAAW,WAC9B,IAAIzR,EAAQ,IAAIyJ,MAAM,2BAGtB,OAFAzJ,EAAM0F,KACJ,2IACKqlC,EAAS/qC,IACf,KACHpB,KAAK0rB,MAAM0gB,GAAWD,EACtB/wC,OAAOixC,YAAY,CAAEjtC,KAAM,iBAAkBuM,GAAIygC,GAAW,OAGhEE,KAAM,WACJ,IAAI5gB,EAAQ,CAAA,EACZ1rB,KAAK0rB,MAAQA,EAER6f,EAAME,QACTrwC,OAAOkY,iBAAiB,UAAW,SAAUO,GAC3C,GAAIA,EAAM04B,QAAUnxC,OAAOoxC,SAASD,OACpC,GAAuB,kBAAnB14B,EAAM/U,KAAKM,MAA4BssB,EAAM7X,EAAM/U,KAAK6M,IAAK,CAC/D,IAAIwgC,EAAWzgB,EAAM7X,EAAM/U,KAAK6M,IAEhC,UADO+f,EAAM7X,EAAM/U,KAAK6M,IACI,KAAxBkI,EAAM/U,KAAK2tC,SAAiB,CAE9B,IAAIrrC,EAAQ,IAAIyJ,MAAM,2BACtBzJ,EAAM0F,KAAO,yDACbqlC,EAAS/qC,QAET+qC,EAAS,KAAMt4B,EAAM/U,KAAK2tC,cAEA,yBAAnB54B,EAAM/U,KAAKM,MACpBhE,OAAO6X,aAAaY,EAAM/U,KAAK6M,GAEnC,KAggBN,SAAS4/B,EAAMmB,GAMb,IALAA,EAAmBA,GAAoB,CAAA,GACtBC,QAA6C,mBAA5BD,EAAiBC,QAAwBD,EAAiBC,QAAUpB,EAAMqB,KAC5GF,EAAiBtrC,MAAyC,mBAA1BsrC,EAAiBtrC,MAAsBsrC,EAAiBtrC,MAAQmqC,EAAMqB,KACtGF,EAAiBG,UACsB,mBAA9BH,EAAiBG,UAA0BH,EAAiBG,UAAYtB,EAAMqB,MAClFrB,EAAMuB,SAET,OADAJ,EAAiBtrC,MAAM,2BAChB,CAAA,EAET,IAAKmqC,EAAMwB,oBAET,OADAL,EAAiBtrC,MAAM,wCAChB,CAAA,EAGT,GADAmqC,EAAMpoC,IAAI,wBAA0BooC,EAAMuB,WACrCJ,EAAiBtuC,OAEpB,OADAsuC,EAAiBtrC,MAAM,sBAChB,CAAA,EAET,IAAI4rC,GAAa,EACbrM,EAAK,KACLsM,EAAa,CAAA,EACbC,EAAuB,KACvBC,EAAU,KACVC,EAAe,EACfhvC,EAASsuC,EAAiBtuC,OAC1BmtC,EAAM3pC,QAAQxD,IAChBmtC,EAAMpoC,IAAI,8BAAgC/E,EAAO4E,OAAS,oCAC1D5E,EAAS,KACT+uC,EAAUT,EAAiBtuC,OAC3BmtC,EAAMltC,MAAM8uC,IAEiB,IAAzB/uC,EAAO0H,QAAQ,OACjBknC,GAAa,EACbzB,EAAMpoC,IAAI,sCAAwC/E,KAElD4uC,GAAa,EACbzB,EAAMpoC,IAAI,oCAAsC/E,IAGpD,IAAIL,EAAa2uC,EAAiB3uC,YAAc,CAAC,CAAEC,KAAM,iCACrDqvC,EAAqBX,EAAiBW,mBACtCC,EAAeZ,EAAiBY,aAEhCC,GAAkB,OAC0B,IAArCb,EAAiBa,iBAAwE,OAArCb,EAAiBa,kBAC9EA,GAAuD,IAArCb,EAAiBa,iBAErC,IAAIC,EAAQ,QACoC,IAArCd,EAAiBe,iBAAwE,OAArCf,EAAiBe,kBAC9ED,EAAQd,EAAiBe,iBACvBD,EAAQ,IAAGA,EAAQ,GAEvB,IAAI5nC,EAAQ,UAC0B,IAA3B8mC,EAAiB9mC,OAAoD,OAA3B8mC,EAAiB9mC,QAAgBA,EAAQ8mC,EAAiB9mC,OAE/G,IAAI8nC,EAAY,UAC0B,IAA/BhB,EAAiBgB,WAA4D,OAA/BhB,EAAiBgB,YACxEA,EAAYhB,EAAiBgB,WAE/B1tC,KAAK2tC,iBAAkB,OACyB,IAArCjB,EAAiBiB,iBAAwE,OAArCjB,EAAiBiB,kBAC9E3tC,KAAK2tC,iBAAuD,IAArCjB,EAAiBiB,iBAE1C,IAAIC,EAAkB,UAC0B,IAArClB,EAAiBkB,iBAAwE,OAArClB,EAAiBkB,kBAC9EA,EAAkBlB,EAAiBkB,iBACjC1a,MAAM0a,KAAkBA,EAAkB,MAC9C,IAAIC,EAAkB,IAMtB,SAASC,EAAeC,GACtB,IAAIC,EAAc,CAChBC,KAAM,IACNC,OAAQ,IACRC,IAAK,KASP,OANI,MAAOJ,IACLA,EAAqBE,OAAMD,EAAYC,KAAOF,EAAqBE,MACnEF,EAAqBG,SAAQF,EAAYE,OAASH,EAAqBG,QACvEH,EAAqBI,MAAKH,EAAYG,IAAMJ,EAAqBI,MAGhEH,OAlBuC,IAArCtB,EAAiBmB,iBAAwE,OAArCnB,EAAiBmB,kBAC9EA,EAAkBnB,EAAiBmB,iBACjC3a,MAAM2a,KAAkBA,EAAkB,KAmB9C,IAAIO,GAAY,EACZxV,EAAY,KACZyV,EAAgB,CAAA,EAChBC,EAAOtuC,KACPuuC,EAAU,EACVC,EAAe,CAAA,EA8BnB,SAASC,IACP,GAAiB,MAAb7V,EAAmB,OAEvB,GADA2S,EAAMltC,MAAM,iBACP+vC,EAEH,YADA7C,EAAMmD,KAAK,yCAGb,IAAIC,EAAWvwC,EAAS,IAAMw6B,EAAY,SAAU,IAAIl2B,MAAOksC,UAC3DpB,IAAOmB,EAAWA,EAAW,UAAYnB,GACzC5nC,IAAO+oC,EAAWA,EAAW,UAAYnnC,mBAAmB5B,IAC5D8nC,IAAWiB,EAAWA,EAAW,cAAgBnnC,mBAAmBkmC,IACxEnC,EAAMsD,YAAYF,EAAU,CAC1BG,KAAM,MACNvB,gBAAiBA,EACjBZ,QAASoC,EACTtvC,QAASouC,EACTzsC,MAAO,SAAU4tC,EAAYC,GAG3B,GAFA1D,EAAMnqC,MAAM4tC,EAAa,IAAKC,GAC9BV,IACIA,EAAU,EAIZ,OAFAH,GAAY,OACZ1B,EAAiBtrC,MAAM,+CAGzBqtC,OAMN,SAASM,EAAY7qC,EAAMgrC,GAGzB,GAFAX,EAAU,EACLvB,GAAD,MAAsBpU,IAAmE,IAAhBsW,GAAsBT,IAC9FzB,IAAczB,EAAM3pC,QAAQsC,GAOjC,GAAsB,cAAlBA,EAAY,MAAhB,CAIO,GAAsB,gBAAlBA,EAAY,MAAqB,CAE1CqnC,EAAMltC,MAAM,kCACZktC,EAAMltC,MAAM6F,GACZ,MAAMirC,EAAcjrC,EAAkB,YACtC,GAAIirC,EAAa,CACf,MAAMC,EAAgBZ,EAAaW,GAC/BC,GAAeA,EAAclrC,UAC1BsqC,EAAaW,GAEtB,OACK,GAAsB,QAAlBjrC,EAAY,MAAa,CAElCqnC,EAAMltC,MAAM,yBAA2Bu6B,GACvC2S,EAAMltC,MAAM6F,GACZ,MAAMirC,EAAcjrC,EAAkB,YACtC,GAAIirC,EAAa,CACf,MAAMC,EAAgBZ,EAAaW,GAC/BC,GAAeA,EAAclrC,UAC1BsqC,EAAaW,GAEtB,OACK,GAAsB,YAAlBjrC,EAAY,MAAiB,CAEtCqnC,EAAMltC,MAAM,4BAA8Bu6B,GAC1C2S,EAAMltC,MAAM6F,GACZ,MAAMirC,EAAcjrC,EAAkB,YACtC,GAAIirC,EAAa,CACf,MAAMC,EAAgBZ,EAAaW,GAC/BC,GAAeA,EAAclrC,UAC1BsqC,EAAaW,GAEtB,OACK,GAAsB,YAAlBjrC,EAAY,MAAiB,CAEtC,MAAMmrC,EAASnrC,EAAa,OAC5B,IAAKmrC,EAEH,YADA9D,EAAMmD,KAAK,qBAGb,MAAMY,EAAejB,EAAcgB,GACnC,IAAKC,EAEH,YADA/D,EAAMltC,MAAM,+CAGd,IAAIu9B,EAAY13B,EAAgB,UAChCqnC,EAAMltC,MAAM,uCAAyCu6B,GACrD2S,EAAMltC,MAAMu9B,GACZ,IAAI/6B,EAASyuC,EAAaC,YACtB1uC,EAAO2uC,IAAM3uC,EAAO4uC,WAEtBlE,EAAMltC,MAAM,2BAA4Bu9B,GACnCA,IAAqC,IAAxBA,EAAU8T,UAK1B7uC,EAAO2uC,GAAGG,gBAAgB/T,GAH1B/6B,EAAO2uC,GAAGG,gBAAgBpE,EAAMqE,mBAOlCrE,EAAMltC,MAAM,6FACPwC,EAAOgvC,aAAYhvC,EAAOgvC,WAAa,IAC5ChvC,EAAOgvC,WAAW3sC,KAAK04B,GACvB2P,EAAMltC,MAAMwC,EAAOgvC,iBAEhB,IAAsB,aAAlB3rC,EAAY,MAAkB,CAEvCqnC,EAAMltC,MAAM,mCAAqCu6B,GACjD2S,EAAMltC,MAAM6F,GACZ,MAAMmrC,EAASnrC,EAAa,OAC5B,IAAKmrC,EAEH,YADA9D,EAAMmD,KAAK,qBAGb,MAAMY,EAAejB,EAAcgB,GACnC,OAAKC,OAILA,EAAaQ,aAAY,QAHvBvE,EAAMltC,MAAM,+CAKT,GAAsB,WAAlB6F,EAAY,MAAgB,CAErCqnC,EAAMltC,MAAM,iCAAmCu6B,GAC/C2S,EAAMltC,MAAM6F,GACZ,MAAMmrC,EAASnrC,EAAa,OAC5B,IAAKmrC,EAEH,YADA9D,EAAMmD,KAAK,qBAGb,MAAMY,EAAejB,EAAcgB,GACnC,IAAKC,EAEH,YADA/D,EAAMltC,MAAM,+CAGdixC,EAAaQ,aAAY,EAAO5rC,EAAa,QAC7CorC,EAAaS,cACR,GAAsB,aAAlB7rC,EAAY,MAAkB,CAEvCqnC,EAAMltC,MAAM,mCAAqCu6B,GACjD2S,EAAMltC,MAAM6F,GACZ,MAAMmrC,EAASnrC,EAAa,OAC5B,IAAKmrC,EAEH,YADA9D,EAAMmD,KAAK,qBAGb,MAAMY,EAAejB,EAAcgB,GACnC,IAAKC,EAEH,OAEFA,EAAaU,aACbV,EAAaW,cACR,GAAsB,UAAlB/rC,EAAY,MAAe,CAEpCqnC,EAAMltC,MAAM,gCAAkCu6B,GAC9C2S,EAAMltC,MAAM6F,GACZ,MAAMmrC,EAASnrC,EAAa,OAC5B,IAAKmrC,EAEH,YADA9D,EAAMmD,KAAK,qBAGb,MAAMY,EAAejB,EAAcgB,GACnC,IAAKC,EAEH,YADA/D,EAAMltC,MAAM,+CAGdixC,EAAaY,WAAWhsC,EAAW,KAAGA,EAAgB,UAAGA,EAAU,UAC9D,GAAsB,aAAlBA,EAAY,MAAkB,CACvCqnC,EAAMltC,MAAM,mCAAqCu6B,GACjD2S,EAAMltC,MAAM6F,GAEZ,MAAMmrC,EAASnrC,EAAa,OAC5B,IAAKmrC,EAEH,YADA9D,EAAMmD,KAAK,qBAGb,MAAMY,EAAejB,EAAcgB,GACnC,IAAKC,EAEH,YADA/D,EAAMltC,MAAM,+CAGdixC,EAAaa,SAASjsC,EAAa,OAAGA,EAAW,KAAGA,EAAU,SACzD,IAAsB,UAAlBA,EAAY,MAAe,CAEpCqnC,EAAMnqC,MAAM,UAAY8C,EAAY,MAAE0F,KAAO,IAAM1F,EAAY,MAAEkQ,QACjEm3B,EAAMltC,MAAM6F,GACZ,IAAIirC,EAAcjrC,EAAkB,YACpC,GAAIirC,EAAa,CACf,IAAIC,EAAgBZ,EAAaW,GAC7BC,GACFA,EAAclrC,UAETsqC,EAAaW,GAEtB,OACK,GAAsB,UAAlBjrC,EAAY,MAAe,CACpCqnC,EAAMltC,MAAM,iCAAmCu6B,GAC/C2S,EAAMltC,MAAM6F,GACZ,MAAMmrC,EAASnrC,EAAa,OAC5B,IAAKmrC,EAEH,YADA9D,EAAMmD,KAAK,qBAGb,IAAI0B,EAAalsC,EAAiB,WAClC,IAAKksC,EAEH,YADA7E,EAAMmD,KAAK,yBAGbnD,EAAMltC,MAAM,6BAA+BgxC,EAAS,KAAOe,EAAmB,OAAI,KAClF,IAAItxC,EAAOsxC,EAAiB,KAC5B7E,EAAMltC,MAAMS,GACZ,MAAMwwC,EAAejB,EAAcgB,GACnC,IAAKC,EAEH,YADA/D,EAAMmD,KAAK,+CAGb,IAAI2B,EAAOnsC,EAAW,KAClBmsC,IACF9E,EAAMltC,MAAM,2BACZktC,EAAMltC,MAAMgyC,IAEd,IAAIlE,EAAWmD,EAAavO,UACxBoL,GACFZ,EAAMltC,MAAM,4BAEZ8tC,EAASrtC,EAAMuxC,IAGf9E,EAAMltC,MAAM,yCAET,IAAsB,YAAlB6F,EAAY,MAMrB,OALAqnC,EAAMnqC,MAAM,sBAAwBw3B,GACpC2S,EAAMltC,MAAM6F,QACR8oC,GACFrM,EAAGxmB,MAAM,KAAM,oBAIjBoxB,EAAMmD,KAAK,2BAA6BxqC,EAAY,MAAI,gBAAkB00B,GAC1E2S,EAAMltC,MAAM6F,WA3MZqnC,EAAM+E,OAAO,8BAAgC1X,QAP7C,IAAK,IAAI3Z,EAAI,EAAGA,EAAI/a,EAAKlB,OAAQic,IAC/B8vB,EAAY7qC,EAAK+a,IAAI,GAsN3B,SAASsxB,IACP,IAAKnyC,IAAW4uC,IAAeoB,EAAW,OAC1ClB,EAAuBr6B,WAAW09B,EAAW3C,GAC7C,IAAI5tB,EAAU,CACZwwB,MAAO,YACPC,WAAY7X,EACZuW,YAAa5D,EAAMmF,aAAa,KAE9B9qC,IAAOoa,EAAe,MAAIpa,GAC1B8nC,IAAW1tB,EAAmB,UAAI0tB,GACtC/M,EAAG/rB,KAAK5Z,KAAK8I,UAAUkc,IAIzB,SAASzU,EAAcolC,GACrB,IAAIxB,EAAc5D,EAAMmF,aAAa,IACjC1wB,EAAU,CAAEwwB,MAAO,SAAUrB,YAAaA,GA8B9C,GA7BIwB,EAAqB,YAEvBvC,GAAY,EACZpuB,EAAe,MAAI,QACnBA,EAAoB,WAAI4Y,EAEpB+H,IACFA,EAAGE,OAAS,KACZF,EAAGwC,QAAU,KACbxC,EAAGyC,QAAU,KACT8J,IACFj6B,aAAai6B,GACbA,EAAuB,QAIzBtnC,IAAOoa,EAAe,MAAIpa,GAC1B8nC,IAAW1tB,EAAmB,UAAI0tB,IACjCtvC,GAAUmtC,EAAM3pC,QAAQurC,KAE3B/uC,EAAS+uC,EAAQC,GACY,IAAzBhvC,EAAO0H,QAAQ,OACjBknC,GAAa,EACbzB,EAAMpoC,IAAI,YAAciqC,EAAe,GAAK,yCAA2ChvC,EAAS,OAEhG4uC,GAAa,EACbzB,EAAMpoC,IAAI,YAAciqC,EAAe,GAAK,uCAAyChvC,EAAS,OAG9F4uC,EAAJ,CACErM,EAAK4K,EAAMqF,aAAaxyC,EAAQ,kBAChC6uC,EAAa,CACX7rC,MAAO,WAEL,GADAmqC,EAAMnqC,MAAM,sDAAwDhD,GAChEmtC,EAAM3pC,QAAQurC,KAAawD,EAAqB,UAElD,OADAvD,IACIA,IAAiBD,EAAQnqC,YAE3B2tC,EAAUvvC,MAAM,+EAIlBhD,EAAS,UACTyU,WAAW,WACTtH,EAAcolC,IACb,MAGLA,EAAUvvC,MAAM,yEAGlB0Z,KAAM,WAEJ0zB,EAAaW,GAAe,SAAUjrC,GAEpC,GADAqnC,EAAMltC,MAAM6F,GACU,YAAlBA,EAAY,MAGd,OAFAqnC,EAAMnqC,MAAM,UAAY8C,EAAY,MAAE0F,KAAO,IAAM1F,EAAY,MAAEkQ,aACjEu8B,EAAUvvC,MAAM8C,EAAY,MAAEkQ,QAGhC84B,EAAuBr6B,WAAW09B,EAAW3C,GAC7CQ,GAAY,EACZxV,EAAY10B,EAAiB,WAAIA,EAAiB,WAAIA,EAAKpF,KAAS,GAChE6xC,EAAqB,UACvBpF,EAAMpoC,IAAI,oBAAsBy1B,GAEhC2S,EAAMpoC,IAAI,oBAAsBy1B,GAElC2S,EAAMC,SAAS5S,GAAa0V,EAC5BqC,EAAUhE,SACZ,EACAhM,EAAG/rB,KAAK5Z,KAAK8I,UAAUkc,KAGzBnU,QAAS,SAAUgI,GACjBk7B,EAAY/zC,KAAKqJ,MAAMwP,EAAM/U,QAG/Bqb,MAAO,WACA/b,GAAWgwC,IAGhBA,GAAY,EAEZ1B,EAAiBtrC,MAAM,kDAI3B,IAAK,IAAIyvC,KAAa5D,EACpBtM,EAAGrtB,iBAAiBu9B,EAAW5D,EAAW4D,SAK9CtF,EAAMsD,YAAYzwC,EAAQ,CACxB0wC,KAAM,OACNvB,gBAAiBA,EACjB7pC,KAAMsc,EACN2sB,QAAS,SAAUzoC,GAEjB,GADAqnC,EAAMltC,MAAM6F,GACU,YAAlBA,EAAY,MAGd,OAFAqnC,EAAMnqC,MAAM,UAAY8C,EAAY,MAAE0F,KAAO,IAAM1F,EAAY,MAAEkQ,aACjEu8B,EAAUvvC,MAAM8C,EAAY,MAAEkQ,QAGhCg6B,GAAY,EACZxV,EAAY10B,EAAiB,WAAIA,EAAiB,WAAIA,EAAKpF,KAAS,GAChE6xC,EAAqB,UACvBpF,EAAMpoC,IAAI,oBAAsBy1B,GAEhC2S,EAAMpoC,IAAI,oBAAsBy1B,GAElC2S,EAAMC,SAAS5S,GAAa0V,EAC5BG,IACAkC,EAAUhE,WAEZvrC,MAAO,SAAU4tC,EAAYC,GAE3B,GADA1D,EAAMnqC,MAAM4tC,EAAa,IAAKC,GAC1B1D,EAAM3pC,QAAQurC,KAAawD,EAAqB,UAElD,OADAvD,IACIA,IAAiBD,EAAQnqC,YAE3B2tC,EAAUvvC,MAAM,+EAIlBhD,EAAS,UACTyU,WAAW,WACTtH,EAAcolC,IACb,MAGe,KAAhB1B,EAAoB0B,EAAUvvC,MAAM4tC,EAAa,yBAC5CC,GAAeA,EAAY7tC,MAAOuvC,EAAUvvC,MAAM4tC,EAAa,KAAOC,EAAY7tC,MAAMyK,SAC5F8kC,EAAUvvC,MAAM4tC,EAAa,KAAOC,MAgd/C,SAAS6B,EAAYC,EAAUJ,GAI7B,IAHAA,EAAYA,GAAa,CAAA,GACfhE,QAAsC,mBAArBgE,EAAUhE,QAAwBgE,EAAUhE,QAAUpB,EAAMqB,KACvF+D,EAAUvvC,MAAkC,mBAAnBuvC,EAAUvvC,MAAsBuvC,EAAUvvC,MAAQmqC,EAAMqB,MAC5EwB,EAGH,OAFA7C,EAAMmD,KAAK,8CACXiC,EAAUvvC,MAAM,yCAGlB,IAAIkuC,EAAejB,EAAc0C,GACjC,IAAKzB,IAAiBA,EAAaC,YAGjC,OAFAhE,EAAMmD,KAAK,uBACXiC,EAAUvvC,MAAM,kBAGlB,IAAIyK,EAAU8kC,EAAU9kC,QACpBwkC,EAAOM,EAAUN,KACjBlB,EAAc5D,EAAMmF,aAAa,IACjC1wB,EAAU,CAAEwwB,MAAO,UAAW9sC,KAAMmI,EAASsjC,YAAaA,GAc9D,GAbIG,EAAa1pC,QAAOoa,EAAe,MAAIsvB,EAAa1pC,OACpD8nC,IAAW1tB,EAAmB,UAAI0tB,GAClC2C,IACFrwB,EAAQqwB,KAAO,CACbjxC,KAAMixC,EAAKjxC,KACX4xC,IAAKX,EAAKW,KAERX,EAAKY,OAAMjxB,EAAQqwB,KAAKY,MAAO,GACZ,QAAnBZ,EAAKa,WAA0C,QAAnBb,EAAKa,YAAqBlxB,EAAQqwB,KAAKa,UAAYb,EAAKa,WACpFb,EAAKc,cAAanxB,EAAQqwB,KAAKc,aAAc,IAEnD5F,EAAMltC,MAAM,qCAAuC0yC,EAAW,MAC9DxF,EAAMltC,MAAM2hB,GACRgtB,EAkCF,OAjCAhtB,EAAoB,WAAI4Y,EACxB5Y,EAAmB,UAAI+wB,EACvBvC,EAAaW,GAAe,SAAUjrC,GAGpC,GAFAqnC,EAAMltC,MAAM,iBACZktC,EAAMltC,MAAM6F,GACU,YAAlBA,EAAY,MAAiB,CAE/B,IAAIksC,EAAalsC,EAAiB,WAClC,IAAKksC,EAGH,OAFA7E,EAAMmD,KAAK,qDACXiC,EAAUhE,UAGZpB,EAAMpoC,IAAI,uCAAyCitC,EAAmB,OAAI,KAC1E,IAAItxC,EAAOsxC,EAAiB,KAG5B,OAFA7E,EAAMltC,MAAMS,QACZ6xC,EAAUhE,QAAQ7tC,GAES,QAAlBoF,EAAY,MAYvBysC,EAAUhE,UAVJzoC,EAAY,OACdqnC,EAAMnqC,MAAM,UAAY8C,EAAY,MAAE0F,KAAO,IAAM1F,EAAY,MAAEkQ,QACjEu8B,EAAUvvC,MAAM8C,EAAY,MAAE0F,KAAO,IAAM1F,EAAY,MAAEkQ,UAEzDm3B,EAAMnqC,MAAM,iBACZuvC,EAAUvvC,MAAM,iBAMtB,OACAu/B,EAAG/rB,KAAK5Z,KAAK8I,UAAUkc,IAGzBurB,EAAMsD,YAAYzwC,EAAS,IAAMw6B,EAAY,IAAMmY,EAAU,CAC3DjC,KAAM,OACNvB,gBAAiBA,EACjB7pC,KAAMsc,EACN2sB,QAAS,SAAUzoC,GAGjB,GAFAqnC,EAAMltC,MAAM,iBACZktC,EAAMltC,MAAM6F,GACU,YAAlBA,EAAY,MAAiB,CAE/B,IAAIksC,EAAalsC,EAAiB,WAClC,IAAKksC,EAGH,OAFA7E,EAAMmD,KAAK,qDACXiC,EAAUhE,UAGZpB,EAAMpoC,IAAI,uCAAyCitC,EAAmB,OAAI,KAC1E,IAAItxC,EAAOsxC,EAAiB,KAG5B,OAFA7E,EAAMltC,MAAMS,QACZ6xC,EAAUhE,QAAQ7tC,GAES,QAAlBoF,EAAY,MAYvBysC,EAAUhE,UAVJzoC,EAAY,OACdqnC,EAAMnqC,MAAM,UAAY8C,EAAY,MAAE0F,KAAO,IAAM1F,EAAY,MAAEkQ,QACjEu8B,EAAUvvC,MAAM8C,EAAY,MAAE0F,KAAO,IAAM1F,EAAY,MAAEkQ,UAEzDm3B,EAAMnqC,MAAM,iBACZuvC,EAAUvvC,MAAM,mBAOtBA,MAAO,SAAU4tC,EAAYC,GAC3B1D,EAAMnqC,MAAM4tC,EAAa,IAAKC,GAC9B0B,EAAUvvC,MAAM4tC,EAAa,KAAOC,MAM1C,SAASmC,EAAqBL,EAAUnV,GACtC,IAAKwS,EAEH,YADA7C,EAAMmD,KAAK,yCAGb,IAAIY,EAAejB,EAAc0C,GACjC,IAAKzB,IAAiBA,EAAaC,YAEjC,YADAhE,EAAMmD,KAAK,kBAGb,IAAI1uB,EAAU,CACZwwB,MAAO,UACP5U,UAAWA,EACXuT,YAAa5D,EAAMmF,aAAa,KAMlC,GAJIpB,EAAa1pC,QAAOoa,EAAe,MAAIsvB,EAAa1pC,OACpD8nC,IAAW1tB,EAAmB,UAAI0tB,GACtCnC,EAAM+E,OAAO,qCAAuCS,EAAW,MAC/DxF,EAAM+E,OAAOtwB,GACTgtB,EAIF,OAHAhtB,EAAoB,WAAI4Y,EACxB5Y,EAAmB,UAAI+wB,OACvBpQ,EAAG/rB,KAAK5Z,KAAK8I,UAAUkc,IAGzBurB,EAAMsD,YAAYzwC,EAAS,IAAMw6B,EAAY,IAAMmY,EAAU,CAC3DjC,KAAM,OACNvB,gBAAiBA,EACjB7pC,KAAMsc,EACN2sB,QAAS,SAAUzoC,GACjBqnC,EAAM+E,OAAO,mBACb/E,EAAM+E,OAAOpsC,GACS,QAAlBA,EAAY,OACdqnC,EAAMnqC,MAAM,UAAY8C,EAAY,MAAE0F,KAAO,IAAM1F,EAAY,MAAEkQ,SAIrEhT,MAAO,SAAU4tC,EAAYC,GAC3B1D,EAAMnqC,MAAM4tC,EAAa,IAAKC,MAMpC,SAASoC,EAAkBN,EAAUO,EAASC,EAAY9hB,EAAU+hB,GAClE,IAAIlC,EAAejB,EAAc0C,GACjC,IAAKzB,IAAiBA,EAAaC,YAEjC,YADAhE,EAAMmD,KAAK,kBAGb,IAAI7tC,EAASyuC,EAAaC,YAC1B,IAAK1uC,EAAO2uC,GAEV,YADAjE,EAAMmD,KAAK,0BAGb,IAKI+C,EAA2B,SAAU59B,GACvC03B,EAAMpoC,IAAI,yCAA0C0Q,GACpD,IAAI69B,EAAQ79B,EAAMR,OAAOq+B,MACrB74B,EAAWhF,EAAMR,OAAOwF,SACxB84B,EAAU9wC,EAAO+wC,YAAYF,GAAS7wC,EAAO+wC,YAAYF,GAAOG,WAAa,OAEjF,GADAtG,EAAMpoC,IAAI,oBAAsBuuC,EAAQ,mBAAqBC,GAC7C,SAAZA,EAAoB,CAEtB,GAAI9wC,EAAO+wC,YAAYF,GAAOtF,SAAWvrC,EAAO+wC,YAAYF,GAAOtF,QAAQppC,OAAS,EAAG,CACrFuoC,EAAMpoC,IAAI,gCAAkCuuC,EAAQ,KAAM7wC,EAAO+wC,YAAYF,GAAOtF,QAAQppC,QAC5F,IAAK,IAAIlE,KAAQ+B,EAAO+wC,YAAYF,GAAOtF,QACzCb,EAAMpoC,IAAI,iCAAmCuuC,EAAQ,KACrDnG,EAAMltC,MAAMS,GACZ+B,EAAO+wC,YAAYF,GAAO98B,KAAK9V,GAEjC+B,EAAO+wC,YAAYF,GAAOtF,QAAU,GAGtCkD,EAAawC,WAAWJ,EAAO74B,GAEnC,EAKA,GAAK4W,EAOH5uB,EAAO+wC,YAAYN,GAAW7hB,MAPjB,CAEb,IAAIsiB,EAAYlxC,EAAOmxC,mBACnBT,IAAYQ,EAAUl5B,SAAW04B,GACrC1wC,EAAO+wC,YAAYN,GAAWzwC,EAAO2uC,GAAG6B,kBAAkBC,EAASS,GAKrElxC,EAAO+wC,YAAYN,GAASvQ,UAvCD,SAAUltB,GACnC03B,EAAMpoC,IAAI,oCAAqC0Q,GAC/C,IAAI69B,EAAQ79B,EAAMR,OAAOq+B,MACzBpC,EAAa2C,OAAOp+B,EAAM/U,KAAM4yC,EAClC,EAoCA7wC,EAAO+wC,YAAYN,GAASzQ,OAAS4Q,EACrC5wC,EAAO+wC,YAAYN,GAASlO,QAAUqO,EACtC5wC,EAAO+wC,YAAYN,GAASnO,QAhBH,SAAU/hC,GACjCmqC,EAAMnqC,MAAM,6BAA8BA,EAE5C,EAcAP,EAAO+wC,YAAYN,GAASlF,QAAU,GAClCoF,GAAa3wC,EAAO+wC,YAAYN,GAASlF,QAAQlpC,KAAKsuC,GAI5D,SAASU,EAASnB,EAAUJ,IAC1BA,EAAYA,GAAa,CAAA,GACfhE,QAAsC,mBAArBgE,EAAUhE,QAAwBgE,EAAUhE,QAAUpB,EAAMqB,KACvF+D,EAAUvvC,MAAkC,mBAAnBuvC,EAAUvvC,MAAsBuvC,EAAUvvC,MAAQmqC,EAAMqB,KACjF,IAAI0C,EAAejB,EAAc0C,GACjC,IAAKzB,IAAiBA,EAAaC,YAGjC,OAFAhE,EAAMmD,KAAK,uBACXiC,EAAUvvC,MAAM,kBAGlB,IAAIP,EAASyuC,EAAaC,YACtBzwC,EAAO6xC,EAAUrnC,MAAQqnC,EAAU7xC,KACvC,IAAKA,EAGH,OAFAysC,EAAMmD,KAAK,qBACXiC,EAAUvvC,MAAM,gBAGlB,IAAIswC,EAAQf,EAAUe,MAAQf,EAAUe,MAAQnG,EAAM4G,qBACtD,OAAKtxC,EAAO+wC,YAAYF,GAMqB,SAAzC7wC,EAAO+wC,YAAYF,GAAOG,YAC5BhxC,EAAO+wC,YAAYF,GAAOtF,QAAQlpC,KAAKpE,QACvC6xC,EAAUhE,YAGZpB,EAAMpoC,IAAI,iCAAmCuuC,EAAQ,KACrDnG,EAAMltC,MAAMS,GACZ+B,EAAO+wC,YAAYF,GAAO98B,KAAK9V,QAC/B6xC,EAAUhE,YAZR0E,EAAkBN,EAAUW,EAAOf,EAAU93B,UAAU,EAAO/Z,EAAM6xC,EAAU93B,eAC9E83B,EAAUhE,WAed,SAASyF,EAASrB,EAAUJ,IAC1BA,EAAYA,GAAa,CAAA,GACfhE,QAAsC,mBAArBgE,EAAUhE,QAAwBgE,EAAUhE,QAAUpB,EAAMqB,KACvF+D,EAAUvvC,MAAkC,mBAAnBuvC,EAAUvvC,MAAsBuvC,EAAUvvC,MAAQmqC,EAAMqB,KACjF,IAAI0C,EAAejB,EAAc0C,GACjC,IAAKzB,IAAiBA,EAAaC,YAGjC,OAFAhE,EAAMmD,KAAK,uBACXiC,EAAUvvC,MAAM,kBAGlB,IAAIP,EAASyuC,EAAaC,YAC1B,IAAK1uC,EAAOwxC,WAAY,CAEtB,GAAIxxC,EAAO2uC,GAAI,CACb,IACI8C,EADUzxC,EAAO2uC,GAAG+C,aACEv1B,KAAK,SAAUqyB,GACvC,OAAOA,EAAOmD,OAA+B,UAAtBnD,EAAOmD,MAAMC,IACtC,GACA,IAAKH,EAGH,OAFA/G,EAAMmD,KAAK,oDACXiC,EAAUvvC,MAAM,+CAGlBP,EAAOwxC,WAAaC,EAAYI,KAC5B7xC,EAAOwxC,aACT9G,EAAMpoC,IAAI,uBACVtC,EAAOwxC,WAAWM,aAAe,SAAUvM,GACzCmF,EAAMltC,MAAM,mBAAqB+nC,EAAKA,KACxC,GAGJ,IAAKvlC,EAAOwxC,WAGV,OAFA9G,EAAMmD,KAAK,mCACXiC,EAAUvvC,MAAM,8BAIpB,IAAIsxC,EAAO/B,EAAU+B,KACrB,IAAKA,EAGH,OAFAnH,EAAMmD,KAAK,gCACXiC,EAAUvvC,MAAM,2BAGlB,IAAIwxC,EAAQF,EAAKE,MACjB,IAAKA,EAGH,OAFArH,EAAMmD,KAAK,4BACXiC,EAAUvvC,MAAM,uBAGlB,IAAIyxC,EAAoC,iBAAlBH,EAAKG,SAAwBH,EAAKG,SAAW,IAC/DC,EAA0B,iBAAbJ,EAAKI,IAAmBJ,EAAKI,IAAM,GACpDvH,EAAMltC,MAAM,uBAAyBu0C,EAAQ,cAAgBC,EAAW,WAAaC,EAAM,OAC3FjyC,EAAOwxC,WAAWU,WAAWH,EAAOC,EAAUC,GAC9CnC,EAAUhE,UAIZ,SAASqG,EAAcjC,EAAUJ,IAC/BA,EAAYA,GAAa,CAAA,GACfhE,QAAsC,mBAArBgE,EAAUhE,QAAwBgE,EAAUhE,QAAUpB,EAAMqB,KACvF+D,EAAUvvC,MAAkC,mBAAnBuvC,EAAUvvC,MAAsBuvC,EAAUvvC,MAAQmqC,EAAMqB,KACjF,IAAIqG,GAAoC,IAAxBtC,EAAUsC,UAC1B1H,EAAMpoC,IAAI,qBAAuB4tC,EAAW,kBAAoBkC,EAAY,KAC5EC,GAAcnC,GACd,IAAIzB,EAAejB,EAAc0C,GACjC,IAAKzB,GAAgBA,EAAa6D,SAIhC,cAFO9E,EAAc0C,QACrBJ,EAAUhE,UAIZ,GADA2C,EAAa6D,UAAW,EACpBF,EAIF,cAFO5E,EAAc0C,QACrBJ,EAAUhE,UAGZ,IAAKyB,EAGH,OAFA7C,EAAMmD,KAAK,8CACXiC,EAAUvvC,MAAM,yCAGlB,IAAI4e,EAAU,CAAEwwB,MAAO,SAAUrB,YAAa5D,EAAMmF,aAAa,KAGjE,GAFIpB,EAAa1pC,QAAOoa,EAAe,MAAIsvB,EAAa1pC,OACpD8nC,IAAW1tB,EAAmB,UAAI0tB,GAClCV,EAMF,OALAhtB,EAAoB,WAAI4Y,EACxB5Y,EAAmB,UAAI+wB,EACvBpQ,EAAG/rB,KAAK5Z,KAAK8I,UAAUkc,WAChBquB,EAAc0C,QACrBJ,EAAUhE,UAGZpB,EAAMsD,YAAYzwC,EAAS,IAAMw6B,EAAY,IAAMmY,EAAU,CAC3DjC,KAAM,OACNvB,gBAAiBA,EACjB7pC,KAAMsc,EACN2sB,QAAS,SAAUzoC,GACjBqnC,EAAMpoC,IAAI,qBACVooC,EAAMltC,MAAM6F,GACU,YAAlBA,EAAY,OACdqnC,EAAMnqC,MAAM,UAAY8C,EAAY,MAAE0F,KAAO,IAAM1F,EAAY,MAAEkQ,eAE5Di6B,EAAc0C,GACrBJ,EAAUhE,WAEZvrC,MAAO,SAAU4tC,EAAYC,GAC3B1D,EAAMnqC,MAAM4tC,EAAa,IAAKC,UAEvBZ,EAAc0C,GACrBJ,EAAUhE,aAOhB,SAASyG,EAA6BrC,EAAUJ,GAC9C,IAAIrB,EAAejB,EAAc0C,GACjC,IAAKzB,IAAiBA,EAAaC,YAEjC,MADAhE,EAAMmD,KAAK,kBACL,iBAER,IAAI7tC,EAASyuC,EAAaC,YAC1B,GAAI1uC,EAAO2uC,GAET,OAEF,IAAI6D,EAAY,CACdt1C,WAAYA,EACZsvC,mBAAoBA,EACpBC,aAAcA,EAEhB+F,aAAyB,gBAErBC,GAAoB,EACxB,GAAI3C,EAAU4C,OACZ,IAAK,IAAIf,KAAS7B,EAAU4C,OAC1B,GAAIf,EAAMgB,aAAehB,EAAMgB,WAAWnE,QAAUmD,EAAMgB,WAAWC,UAAW,CAC9EH,GAAoB,EACpB,MAKJp3C,IACCA,EAAaqE,UAAUmzC,sBACrBx3C,EAAaqE,UAAUozC,2BAA6Bz3C,EAAaqE,UAAUqzC,4BAC9EN,IAEAzyC,EAAOyyC,mBAAoB,EAC3BD,EAAUQ,oCAAqC,EAC/CR,EAAUS,oCAAqC,EAC/CT,EAAUU,0BAA2B,GAEvCxI,EAAMpoC,IAAI,2BACVtC,EAAO2uC,GAAK,IAAIxzC,EAAkBq3C,GAClC9H,EAAMltC,MAAMwC,EAAO2uC,IACf3uC,EAAO2uC,GAAGwE,WAEZnzC,EAAOozC,OAAS,CAAA,EAChBpzC,EAAOqzC,QAAQntC,MAAQ,eAEzBwkC,EAAMpoC,IAAI,yDAA2DtC,EAAOszC,QAAU,KACtFtzC,EAAO2uC,GAAG4E,2BAA6B,WACjCvzC,EAAO2uC,IAAIF,EAAa+E,SAASxzC,EAAO2uC,GAAG8E,mBACjD,EACAzzC,EAAO2uC,GAAG+E,eAAiB,SAAU1gC,GACnC,IAAKA,EAAM+nB,WAAc/nB,EAAM+nB,UAAUA,WAAa/nB,EAAM+nB,UAAUA,UAAU91B,QAAQ,mBAAqB,EAC3GylC,EAAMpoC,IAAI,sBACVtC,EAAO2zC,SAAU,GACM,IAAnB3zC,EAAOszC,QAET/C,EAAqBL,EAAU,CAAErB,WAAW,IAwUpD,SAAiBqB,EAAUJ,GACzBA,EAAYA,GAAa,CAAA,EACzBA,EAAUhE,QAAsC,mBAArBgE,EAAUhE,QAAwBgE,EAAUhE,QAAUpB,EAAMqB,KACvF+D,EAAUvvC,MAAkC,mBAAnBuvC,EAAUvvC,MAAsBuvC,EAAUvvC,MAAQmqC,EAAMqB,KACjF,IAAI0C,EAAejB,EAAc0C,GACjC,IAAKzB,IAAiBA,EAAaC,YAEjC,YADAhE,EAAMmD,KAAK,wCAGb,IAAI7tC,EAASyuC,EAAaC,YAE1B,GADAhE,EAAMpoC,IAAI,gCACLtC,EAAO4zC,MAEV,YADAlJ,EAAMmD,KAAK,0DAGb7tC,EAAO4zC,MAAQ,CACbr1C,KAAMyB,EAAO2uC,GAAGkF,iBAAiBt1C,KACjC4xC,IAAKnwC,EAAO2uC,GAAGkF,iBAAiB1D,MAEX,IAAnBnwC,EAAOszC,UAAmBtzC,EAAO4zC,MAAe,SAAI,GACxDlJ,EAAMltC,MAAMsyC,GACZ9vC,EAAO8zC,SAAU,EACjBhE,EAAUhE,QAAQ9rC,EAAO4zC,OA3VnBG,CAAQ7D,EAAUJ,OAEf,CAGL,IAAI/U,EAAY,CACdA,UAAW/nB,EAAM+nB,UAAUA,UAC3BiZ,OAAQhhC,EAAM+nB,UAAUiZ,OACxBC,cAAejhC,EAAM+nB,UAAUkZ,gBAEV,IAAnBj0C,EAAOszC,SAET/C,EAAqBL,EAAUnV,GAGrC,EACA/6B,EAAO2uC,GAAGuF,QAAU,SAAUlhC,GAE5B,GADA03B,EAAMpoC,IAAI,wBAAyB0Q,IAC9BA,EAAMmhC,QAAS,OACpB,IAAKnhC,EAAM2+B,MAAO,OAElB,IAAIzP,EAAMlvB,EAAMohC,YAAcphC,EAAMohC,YAAYlS,KAAOlvB,EAAMohC,YAAYC,KAAOrhC,EAAM2+B,MAAM7mC,GAC5F,IACE2jC,EAAa6F,cAActhC,EAAM2+B,MAAOzP,GAAK,EAAM,CACjD3uB,OAAQ,YAEV,MAAOiW,GACPkhB,EAAMnqC,MAAM,8BAA+BipB,GAE7C,GAAIxW,EAAM2+B,MAAM4C,QAAS,OACzB,IAAIC,EAAsB,KAC1B9J,EAAMpoC,IAAI,oCAAqC0Q,EAAM2+B,OACrD3+B,EAAM2+B,MAAM4C,QAAU,SAAUE,GAC9B/J,EAAMpoC,IAAI,wBAAyBmyC,GACnCriC,aAAaoiC,GAEb,IAAIE,EAAe10C,EAAO2uC,GAAK3uC,EAAO2uC,GAAGgG,kBAAoB,KACzDP,EAAcM,EACdA,EAAav4B,KAAMi4B,IACnB,MAAMxB,EAAWwB,EAAYxB,UAAYwB,EAAYQ,UAErD,OADchC,EAASjB,OAASiB,EAASiC,UACxBJ,EAAGjiC,SAEpB,KACA0vB,EAAMkS,EAAcA,EAAYlS,KAAOkS,EAAYC,KAAOI,EAAGjiC,OAAO1H,GACxE,IACE2jC,EAAa6F,cAAcG,EAAGjiC,OAAQ0vB,GAAK,EAAO,CAChD3uB,OAAQ,UAEV,MAAOiW,GACPkhB,EAAMnqC,MAAM,yCAA0CipB,GAE1D,EACAxW,EAAM2+B,MAAMmD,OAAS,SAAUL,GAE7B,GADA/J,EAAMpoC,IAAI,sBAAuBmyC,IAC5BD,EAAqB,CACxB,MAAMhiC,EAASiiC,EAAGjiC,OAClBgiC,EAAsBxiC,WAAW,WAC/B04B,EAAMpoC,IAAI,yBAEV,IAAIoyC,EAAe10C,EAAO2uC,GAAK3uC,EAAO2uC,GAAGgG,kBAAoB,KACzDP,EAAcM,EACdA,EAAav4B,KAAMi4B,IACnB,MAAMxB,EAAWwB,EAAYxB,UAAYwB,EAAYQ,UAErD,OADchC,EAASjB,OAASiB,EAASiC,UACxBriC,IAEjB,KACA0vB,EAAMkS,EAAcA,EAAYlS,KAAOkS,EAAYC,KAAO7hC,EAAO1H,GACrE,IACE2jC,EAAa6F,cAAc9hC,EAAQ0vB,GAAK,EAAO,CAC7C3uB,OAAQ,SAEV,MAAOiW,GACPkhB,EAAMnqC,MAAM,sCAAuCipB,GAErDgrB,EAAsB,IAGxB,EAAG,MAEP,EACAxhC,EAAM2+B,MAAMoD,SAAW,SAAUN,GAE/B,GADA/J,EAAMpoC,IAAI,8BAA+BmyC,GACd,MAAvBD,EACFpiC,aAAaoiC,GACbA,EAAsB,UAEtB,IAEE,IAAIE,EAAe10C,EAAO2uC,GAAK3uC,EAAO2uC,GAAGgG,kBAAoB,KACzDP,EAAcM,EACdA,EAAav4B,KAAMi4B,IACnB,MAAMxB,EAAWwB,EAAYxB,UAAYwB,EAAYQ,UAErD,OADchC,EAASjB,OAASiB,EAASiC,UACxBJ,EAAGjiC,SAEpB,KACA0vB,EAAMkS,EAAcA,EAAYlS,KAAOkS,EAAYC,KAAOI,EAAGjiC,OAAO1H,GACxE2jC,EAAa6F,cAAcG,EAAGjiC,OAAQ0vB,GAAK,EAAM,CAC/C3uB,OAAQ,WAEV,MAAOiW,GACPkhB,EAAMnqC,MAAM,wCAAyCipB,GAG3D,CACF,EAOF/e,eAAeuqC,EAAc9E,EAAU+E,EAAOnF,IAC5CA,EAAYA,GAAa,CAAA,GACfhE,QAAsC,mBAArBgE,EAAUhE,QAAwBgE,EAAUhE,QAAUpB,EAAMqB,KACvF+D,EAAUvvC,MAAkC,mBAAnBuvC,EAAUvvC,MAAsBuvC,EAAUvvC,MAAQ20C,EAC3E,IAAI1F,EAAOM,EAAUN,KACrB,GAAIyF,GAASzF,EAGX,OAFA9E,EAAMnqC,MAAM,yCACZuvC,EAAUvvC,MAAM,oCAEX,KAAK00C,GAAWzF,GAASA,EAAKjxC,MAASixC,EAAKW,KAGjD,OAFAzF,EAAMnqC,MAAM,kDACZuvC,EAAUvvC,MAAM,6CAIlB,GAAIuvC,EAAUqF,QAAUrF,EAAU4C,OAAQ,CAExC,GADA5C,EAAU4C,OAAShI,EAAM0K,cAActF,EAAUqF,QACrB,IAAxBrF,EAAUuF,YAA+C,IAAzBvF,EAAUwF,YAAuBxF,EAAUyF,IAE7E,IAAK,IAAI5D,KAAS7B,EAAU4C,OAC1B,GAAmB,UAAff,EAAMpzC,KAAkB,EACE,IAAxBuxC,EAAUuF,YAA+C,IAAzBvF,EAAUwF,WAAqB3D,EAAM0D,WAAY,EAC5EvF,EAAUyF,MAAK5D,EAAM4D,IAAMzF,EAAUyF,KAC9C,MAIN7K,EAAMmD,KAAK,mFAAoFiC,EAAU4C,QAG3G,GAAI5C,EAAU4C,SAAWzxC,MAAMF,QAAQ+uC,EAAU4C,QAG/C,OAFAhI,EAAMnqC,MAAM,gCACZuvC,EAAUvvC,MAAM,2BAIlB,IAAIkuC,EAAejB,EAAc0C,GACjC,IAAKzB,IAAiBA,EAAaC,YAGjC,OAFAhE,EAAMmD,KAAK,uBACXiC,EAAUvvC,MAAM,kBAGlB,IAAIP,EAASyuC,EAAaC,YA8lC5B,IAA0B4E,EA7lCxBtzC,EAAOszC,SA6lCiBA,EA7lCUxD,EAAUwD,QA8lC5C5I,EAAMltC,MAAM,oBAAqB81C,IACd,IAAZA,GA9lCP,IAQE,GANAf,EAA6BrC,EAAUJ,GACnCmF,SAEIO,EAAetF,EAAUJ,GAG5BN,EAGE,CAKL,SAJMxvC,EAAO2uC,GAAG8G,qBAAqBjG,GACrC9E,EAAMpoC,IAAI,gCACVtC,EAAO4uC,UAAYY,EAAKW,IAEpBnwC,EAAOgvC,YAAchvC,EAAOgvC,WAAW7sC,OAAS,EAAG,CACrD,IAAK,IAAIic,EAAI,EAAGA,EAAIpe,EAAOgvC,WAAW7sC,OAAQic,IAAK,CACjD,IAAI2c,EAAY/6B,EAAOgvC,WAAW5wB,GAClCssB,EAAMltC,MAAM,2BAA4Bu9B,GACnCA,IAAqC,IAAxBA,EAAU8T,UAK1B7uC,EAAO2uC,GAAGG,gBAAgB/T,GAH1B/6B,EAAO2uC,GAAGG,gBAAgBpE,EAAMqE,iBAMpC/uC,EAAOgvC,WAAa,SAGhBwG,EAAetF,EAAUJ,GAE/B,IAAI4F,QAkGVjrC,eAA4BylC,EAAUJ,GACpCA,EAAYA,GAAa,CAAA,EACzBA,EAAU6F,aAAgD,mBAA1B7F,EAAU6F,aAA6B7F,EAAU6F,aAAejL,EAAMqB,KACtG,IAAI0C,EAAejB,EAAc0C,GACjC,IAAKzB,IAAiBA,EAAaC,YAEjC,MADAhE,EAAMmD,KAAK,kBACL,iBAER,IAAI7tC,EAASyuC,EAAaC,YAC1BhE,EAAMpoC,IAAI,4BAA8BtC,EAAO2zC,QAAU,KACzD,IAAI+B,QAAe11C,EAAO2uC,GAAGiH,eAC7BlL,EAAMltC,MAAMk4C,GAGZ,IAAIlG,EAAO,CACTjxC,KAAM,SACN4xC,IAAKuF,EAAOvF,KAUd,GARAL,EAAU6F,aAAanG,GACvBkG,EAAOvF,IAAMX,EAAKW,IAClBzF,EAAMpoC,IAAI,6BACVtC,EAAO4zC,MAAQ,CACbr1C,KAAM,SACN4xC,IAAKuF,EAAOvF,WAERnwC,EAAO2uC,GAAGkH,oBAAoBH,IAC/B11C,EAAO2zC,UAAY3zC,EAAOszC,QAG7B,OADA5I,EAAMpoC,IAAI,iCACH,KAGLtC,EAAOyyC,oBAAmBiD,EAAOtF,MAAO,GAC5C,OAAOsF,EAnIgBE,CAAa1F,EAAUJ,GAC1CA,EAAUhE,QAAQ4J,OA1BT,CACT,IAAIT,QA+EVxqC,eAA2BylC,EAAUJ,GACnCA,EAAYA,GAAa,CAAA,EACzBA,EAAU6F,aAAgD,mBAA1B7F,EAAU6F,aAA6B7F,EAAU6F,aAAejL,EAAMqB,KACtG,IAAI0C,EAAejB,EAAc0C,GACjC,IAAKzB,IAAiBA,EAAaC,YAEjC,MADAhE,EAAMmD,KAAK,kBACL,iBAER,IAAI7tC,EAASyuC,EAAaC,YAC1BhE,EAAMpoC,IAAI,2BAA6BtC,EAAO2zC,QAAU,KAExD,IAAImC,EAAmB,CAAA,EACnBC,GAAsC,IAAzBjG,EAAUiG,WAEvBA,IAAYD,EAAiBC,YAAa,GAC9CrL,EAAMltC,MAAMs4C,GACZ,IAAIb,QAAcj1C,EAAO2uC,GAAGqH,YAAYF,GACxCpL,EAAMltC,MAAMy3C,GAGZ,IAAIzF,EAAO,CACTjxC,KAAM,QACN4xC,IAAK8E,EAAM9E,KAWb,GATAL,EAAU6F,aAAanG,GACvByF,EAAM9E,IAAMX,EAAKW,IACjBzF,EAAMpoC,IAAI,6BACVtC,EAAO4zC,MAAQ,CACbr1C,KAAM,QACN4xC,IAAK8E,EAAM9E,WAEPnwC,EAAO2uC,GAAGkH,oBAAoBZ,GACpCj1C,EAAO81C,iBAAmBA,GACrB91C,EAAO2zC,UAAY3zC,EAAOszC,QAG7B,OADA5I,EAAMpoC,IAAI,iCACH,KAGLtC,EAAOyyC,oBAAmBwC,EAAM7E,MAAO,GAC3C,OAAO6E,EAvHee,CAAY9F,EAAUJ,GACxCA,EAAUhE,QAAQmJ,IA0BpB,MAAO50C,GACPqqC,EAAMnqC,MAAMF,GACZyvC,EAAUvvC,MAAMF,IAIpB,SAAS41C,EAAkB/F,EAAUJ,IACnCA,EAAYA,GAAa,CAAA,GACfhE,QAAsC,mBAArBgE,EAAUhE,QAAwBgE,EAAUhE,QAAUpB,EAAMqB,KACvF+D,EAAUvvC,MAAkC,mBAAnBuvC,EAAUvvC,MAAsBuvC,EAAUvvC,MAAQ20C,EAC3EpF,EAAU6F,aAAgD,mBAA1B7F,EAAU6F,aAA6B7F,EAAU6F,aAAejL,EAAMqB,KACtG,IAAIyD,EAAOM,EAAUN,KACjBf,EAAejB,EAAc0C,GACjC,IAAKzB,IAAiBA,EAAaC,YAGjC,OAFAhE,EAAMmD,KAAK,uBACXiC,EAAUvvC,MAAM,kBAGlB,IAAIP,EAASyuC,EAAaC,YAC1B,GAAIc,EAAM,CACR,IAAKxvC,EAAO2uC,GAGV,OAFAjE,EAAMmD,KAAK,kGACXiC,EAAUvvC,MAAM,sFAGlBuvC,EAAU6F,aAAanG,GACvBxvC,EAAO2uC,GAAG8G,qBAAqBjG,GAAMlnC,KAAK,WAIxC,GAHAoiC,EAAMpoC,IAAI,gCACVtC,EAAO4uC,UAAYY,EAAKW,IAEpBnwC,EAAOgvC,YAAchvC,EAAOgvC,WAAW7sC,OAAS,EAAG,CACrD,IAAK,IAAIic,EAAI,EAAGA,EAAIpe,EAAOgvC,WAAW7sC,OAAQic,IAAK,CACjD,IAAI2c,EAAY/6B,EAAOgvC,WAAW5wB,GAClCssB,EAAMltC,MAAM,2BAA4Bu9B,GACnCA,IAAqC,IAAxBA,EAAU8T,UAK1B7uC,EAAO2uC,GAAGG,gBAAgB/T,GAH1B/6B,EAAO2uC,GAAGG,gBAAgBpE,EAAMqE,iBAMpC/uC,EAAOgvC,WAAa,GAGtBc,EAAUhE,SACZ,EAAGgE,EAAUvvC,YAEbuvC,EAAUvvC,MAAM,gBA4GpBkK,eAAeyrC,EAAchG,EAAUJ,GAKrC,IAJAA,EAAYA,GAAa,CAAA,GACfhE,QAAsC,mBAArBgE,EAAUhE,QAAwBgE,EAAUhE,QAAUpB,EAAMqB,KACvF+D,EAAUvvC,MAAkC,mBAAnBuvC,EAAUvvC,MAAsBuvC,EAAUvvC,MAAQmqC,EAAMqB,KAE7E+D,EAAU4C,SAAWzxC,MAAMF,QAAQ+uC,EAAU4C,QAG/C,OAFAhI,EAAMnqC,MAAM,gCACZuvC,EAAUvvC,MAAM,2BAIlB,IAAK,IAAIoxC,KAAS7B,EAAU4C,QACtBf,EAAM31B,MAAS21B,EAAMpuC,UAAYouC,EAAMziC,UAASyiC,EAAMpuC,SAAU,GAEtE,UACQiyC,EAAetF,EAAUJ,GAC/BA,EAAUhE,UACV,MAAOzrC,GACPqqC,EAAMnqC,MAAMF,GACZyvC,EAAUvvC,MAAMF,IAIpBoK,eAAe+qC,EAAetF,EAAUJ,GACtC,IAAIrB,EAAejB,EAAc0C,GACjC,IAAKzB,IAAiBA,EAAaC,YAEjC,MADAhE,EAAMmD,KAAK,wCACL,iBAER,IAAI7tC,EAASyuC,EAAaC,YAC1B,IAAK1uC,EAAO2uC,GAEV,MADAjE,EAAMmD,KAAK,0BACL,yBAER,IAAI6E,EAAS5C,EAAU4C,OACvB,IAAKA,IAAWzxC,MAAMF,QAAQ2xC,IAA6B,IAAlBA,EAAOvwC,OAE9C,OAEF,IAAIg0C,GAAsB,EAEtBC,EAAS,CAAA,EACb,IAAK,IAAIzE,KAASe,EAAQ,CAExB,UADOf,EAAM0E,UACR1E,EAAMpzC,OAAS,CAAC,QAAS,SAASub,SAAS63B,EAAMpzC,MAAO,SAC7D,IAAKozC,EAAM2E,SAAW3E,EAAM2E,mBAAmBr7C,EAAkB,SACjE,IAAIs7C,EAAQ5E,EAAM4E,MAAQ5E,EAAM4E,MAAQ,UACnCH,EAAOG,KAAQH,EAAOG,GAAS,CAAA,GAChCH,EAAOG,GAAO5E,EAAMpzC,QACxBozC,EAAM0E,SAAWE,EACjBH,EAAOG,GAAO5E,EAAMpzC,MAAQozC,GAE9B,IAAIpyC,EAAOD,OAAOC,KAAK62C,GACvB,IAAK,IAAI32C,KAAOF,EAAM,CACpB,IAAIg3C,EAAQH,EAAO32C,GACd82C,EAAMC,OAAUD,EAAME,QACrBF,EAAMC,cAAcD,EAAMC,MAAMH,SAChCE,EAAME,cAAcF,EAAME,MAAMJ,gBAC7BD,EAAO32C,IAGlB,IAAIi2C,IAAS5F,EAAUN,KACvB,IAAK,IAAImC,KAASe,EAAQ,CACxB,IAAKf,EAAMpzC,KAAM,CACfmsC,EAAMmD,KAAK,sBAAuB8D,GAClC,SAEF,GAAmB,SAAfA,EAAMpzC,KAAiB,CAEzB,GAAIyB,EAAO2uC,GAAG+H,cAAe,CAC3BhM,EAAMmD,KAAK,yDACX,SAEFnD,EAAMpoC,IAAI,iCACVkuC,EAAkBN,EAAUxF,EAAM4G,qBAAsB,MAAM,GAC9DtxC,EAAO2uC,GAAG+H,cAAgB,SAAU1jC,GAClC03B,EAAMpoC,IAAI,iCAAkC0Q,GAC5Cw9B,EAAkBN,EAAUl9B,EAAM2jC,QAAQ9F,MAAO79B,EAAM2jC,QAAQ3+B,SAAUhF,EAAM2jC,QACjF,EACA,SAaF,QAVuB,IAAdhF,EAAM31B,KACC,OAAd21B,EAAM31B,UACkB,IAAjB21B,EAAMziC,QACI,OAAjByiC,EAAMziC,aACmB,IAAlByiC,EAAMpuC,SACK,OAAlBouC,EAAMpuC,UAGNouC,EAAM31B,KAAM,GAET21B,EAAM31B,KAAO21B,EAAMziC,QAAYyiC,EAAM31B,KAAO21B,EAAMziC,QAAUyiC,EAAMpuC,QAAU,CAC/EmnC,EAAMmD,KAAK,2CAA4C8D,GACvD,SAEEA,EAAM31B,KAAO21B,EAAMpuC,SACrBmnC,EAAMmD,KAAK,0DAA2D8D,UAC/DA,EAAM31B,KACJ21B,EAAMziC,QAAUyiC,EAAMpuC,UAC/BmnC,EAAMmD,KAAK,4DAA6D8D,UACjEA,EAAMpuC,SAEf,IAAIquC,EAAOD,EAAMpzC,KACE,WAAfozC,EAAMpzC,OAAmBqzC,EAAO,SACpC,IAAIwC,EAAc,KAChB5F,EAAS,KAQX,GALE4F,EAFEzC,EAAMzP,IAEMliC,EAAO2uC,GAAGgG,kBAAkBx4B,KAAMlN,GAAMA,EAAEizB,MAAQyP,EAAMzP,KAAOjzB,EAAE2jC,SAASjB,MAAMC,OAASA,GAGzF5xC,EAAO2uC,GAAGgG,kBAAkBx4B,KAAMlN,GAAMA,EAAE2jC,SAASjB,MAAMC,OAASA,GAE9ED,EAAMpuC,SAAWouC,EAAMziC,OAAQ,CACjC,IAAKklC,EAAa,CAChB1J,EAAMmD,KAAK,yCAA0C8D,GACrD,SAEF,IAAKyC,EAAY5F,OAAQ,CACvB9D,EAAMmD,KAAK,0CAA2C8D,GACtD,SAEFnD,EAAS4F,EAAY5F,OAEvB,GAAIkH,IAAWtB,IACbA,EAAcp0C,EAAO2uC,GAAGgG,kBAAkBx4B,KAAMlN,GAAMA,EAAE2jC,SAASjB,MAAMC,OAASA,IAC3EwC,GAAa,CAChB1J,EAAMmD,KAAK,yCAA0C8D,GACrD,SAIJ,IAAIiF,EAAK,KACPC,EAAU,KACZ,GAAIlF,EAAMziC,OACRw7B,EAAMpoC,IAAI,qCAAsCqvC,GAChDkF,EAAUrI,EAAOmD,MAAQnD,EAAOmD,MAAM7mC,GAAK,WACrC0jC,EAAOsI,aAAa,WACrB,GAAInF,EAAM2E,QAAS,CACxB,GAAI3E,EAAM0E,UAAYD,EAAOzE,EAAM0E,WAAaD,EAAOzE,EAAM0E,UAAUU,OAAQ,CAE7E,IAAIA,EAASX,EAAOzE,EAAM0E,UAAUU,OACpCH,EAAoB,UAAfjF,EAAMpzC,KAAmBw4C,EAAOC,iBAAiB,GAAKD,EAAOE,iBAAiB,UAC5Eb,EAAOzE,EAAM0E,UAAUU,cACvBX,EAAOzE,EAAM0E,iBACb1E,EAAM0E,cACR,GAAI1E,EAAM2E,mBAAmBr7C,EAElC27C,EAAKjF,EAAM2E,YACN,CACAH,IACHA,GAAsB,EACtB1H,EAAayI,eAAc,IAE7B,IAAIC,EAAczM,EAAM0M,iBAAiBzF,GACvCoF,EAAS,KACX,GAAmB,UAAfpF,EAAMpzC,MAAmC,UAAfozC,EAAMpzC,KAAkB,CAEpD,GAAIozC,EAAM0E,SAAU,CAClB,IAAIgB,EAA2B,UAAf1F,EAAMpzC,KAAmB,QAAU,QACnD,GAAI63C,EAAOzE,EAAM0E,WAAaD,EAAOzE,EAAM0E,UAAUgB,GAAY,CAC/D,IAAIC,EAAalB,EAAOzE,EAAM0E,UAAUgB,GACpCE,EAAmB7M,EAAM0M,iBAAiBE,GAC9CH,EAAYE,GAAaE,EAAiBF,IAG9CN,QAAej8C,EAAUC,aAAay8C,aAAaL,GAC/CxF,EAAM0E,UAAYc,EAAYX,OAASW,EAAYV,QAGrDL,EAAOzE,EAAM0E,UAAUU,OAASA,SACzBpF,EAAM0E,eAIfU,QAAej8C,EAAUC,aAAa+vC,gBAAgBqM,GAExDP,EAAoB,UAAfjF,EAAMpzC,KAAmBw4C,EAAOC,iBAAiB,GAAKD,EAAOE,iBAAiB,GAErF,GAAItF,EAAMpuC,QAAS,OAEXirC,EAAOsI,aAAaF,GAE1B,IAAIa,EAAe,YACA,IAAf9F,EAAM+F,MAA4C,aAA1BtD,EAAYuD,WAAsD,aAA1BvD,EAAYuD,YAC9EF,EAAe,YACbrD,EAAYwD,aAAcxD,EAAYwD,aAAaH,GAClDrD,EAAYuD,UAAYF,MACxB,CAGL,GADKz3C,EAAO63C,WAAU73C,EAAO63C,SAAW,IAAI78C,GAC/B,UAAT42C,IAAsBD,EAAM0D,YAAc1D,EAAM4D,IAClD/G,EAASxuC,EAAO2uC,GAAGmJ,SAASlB,EAAI52C,EAAO63C,UACvCzD,EAAcp0C,EAAO2uC,GAAGgG,kBAAkBx4B,KAAMlN,GAAMA,EAAEu/B,SAAWA,QAC9D,GAAImD,EAAM0D,WACf,GAAmD,YAA/C3K,EAAMqN,cAAcC,eAAeC,QAAuB,CAE5DvN,EAAMpoC,IAAI,mCAAoCs0C,GAC9C,IAAIzJ,EAAcF,EAAe0E,EAAMzE,sBACvCkH,EAAcp0C,EAAO2uC,GAAGuJ,eAAetB,EAAI,CACzCe,UAAW,WACXxD,QAAS,CAACn0C,EAAO63C,UACjBM,cAAexG,EAAMwG,eAAiB,CACpC,CAAEC,IAAK,IAAK97C,QAAQ,EAAM+7C,WAAYlL,EAAYC,MAClD,CACEgL,IAAK,IACL97C,QAAQ,EACR+7C,WAAYlL,EAAYE,OACxBiL,sBAAuB,GAEzB,CACEF,IAAK,IACL97C,QAAQ,EACR+7C,WAAYlL,EAAYG,IACxBgL,sBAAuB,WAY7B,GANA5N,EAAMpoC,IAAI,2CACV8xC,EAAcp0C,EAAO2uC,GAAGuJ,eAAetB,EAAI,CACzCe,UAAW,WACXxD,QAAS,CAACn0C,EAAO63C,YAEnBrJ,EAAS4F,EAAcA,EAAY5F,OAAS,KACxCA,EAAQ,CACV,IAAI+J,EAAa/J,EAAOgK,gBACnBD,IAAYA,EAAa,CAAA,GAC9B,IAAIpL,EAAcF,EAAe0E,EAAMzE,sBACvCqL,EAAWE,UAAY9G,EAAMwG,eAAiB,CAC5C,CAAEC,IAAK,IAAK97C,QAAQ,EAAM+7C,WAAYlL,EAAYC,MAClD,CACEgL,IAAK,IACL97C,QAAQ,EACR+7C,WAAYlL,EAAYE,OACxBiL,sBAAuB,GAEzB,CACEF,IAAK,IACL97C,QAAQ,EACR+7C,WAAYlL,EAAYG,IACxBgL,sBAAuB,IAG3B9J,EAAOkK,cAAcH,SAIzB7N,EAAMpoC,IAAI,iBAAmBqvC,EAAM4D,IAAM,KAAMqB,GAC/CxC,EAAcp0C,EAAO2uC,GAAGuJ,eAAetB,EAAI,CACzCe,UAAW,WACXxD,QAAS,CAACn0C,EAAO63C,UACjBM,cAAe,CAAC,CAAEQ,gBAAiBhH,EAAM4D,QAK7C,GAFK/G,IAAQA,EAAS4F,EAAcA,EAAY5F,OAAS,MAErDmD,EAAMiH,MACR,GAAmD,YAA/ClO,EAAMqN,cAAcC,eAAeC,QACrCvN,EAAMmD,KAAK,0EAA2E8D,QACjF,GAA2B,iBAAhBA,EAAMiH,MACtBlO,EAAMmD,KAAK,2CAA4C8D,OAClD,CACL,IAAIkH,EAAWjH,EAAO,IAAMD,EAAMiH,MAAMriC,cACpCuiC,EAAS19C,EAAe29C,gBAAgBnH,GAAMkH,OAAOxqC,OAAO,SAAUsqC,GACxE,OAAOA,EAAMC,SAAStiC,gBAAkBsiC,CAC1C,GACA,GAAKC,GAA4B,IAAlBA,EAAO32C,QAEf,GAAIiyC,EACT,IACEA,EAAY4E,oBAAoBF,GAChC,MAAOz4C,GACPqqC,EAAMmD,KAAK,mCAAqC+D,EAAO,UAAWvxC,SALpEqqC,EAAMmD,KAAK,gEAAiE8D,GAUlF,GAAIA,EAAM0B,QAER,GAAI1B,EAAM0D,WAAa1D,EAAM4D,IAC3B7K,EAAMmD,KAAK,6EACN,GAAIxb,MAAMsf,EAAM0B,UAAY1B,EAAM0B,QAAU,EACjD3I,EAAMmD,KAAK,sCAAuC8D,QAC7C,GAAInD,EAAQ,CACjB,IAAIjqC,EAASiqC,EAAOgK,gBACfj0C,GAAWA,EAAOk0C,WAAyC,IAA5Bl0C,EAAOk0C,UAAUt2C,QAGnDoC,EAAOk0C,UAAU,GAAGJ,WAAa1G,EAAM0B,cACjC7E,EAAOkK,cAAcn0C,IAH3BmmC,EAAMmD,KAAK,qEAAsE8D,GAOvF,GAAa,UAATC,GAAoBD,EAAMsH,UAE5B,GAAItH,EAAM0D,WAAa1D,EAAM4D,IAC3B7K,EAAMmD,KAAK,+EACN,GAAIxb,MAAMsf,EAAMsH,YAActH,EAAMsH,UAAY,EACrDvO,EAAMmD,KAAK,wCAAyC8D,QAC/C,GAAInD,EAAQ,CACjB,IAAIjqC,EAASiqC,EAAOgK,gBACfj0C,GAAWA,EAAOk0C,WAAyC,IAA5Bl0C,EAAOk0C,UAAUt2C,QAGnDoC,EAAOk0C,UAAU,GAAGS,aAAevH,EAAMsH,gBACnCzK,EAAOkK,cAAcn0C,IAH3BmmC,EAAMmD,KAAK,uEAAwE8D,GAQzF,GAAIA,EAAMgB,WAAY,CACpB,GAAInE,GAAUmD,EAAMgB,WAAWnE,OAAQ,CAErC,IAAI2K,EAAgB,KAChB99C,EAAaqE,UAAUmzC,qBACzBsG,EAAgB3K,EAAOqE,wBAEvBx3C,EAAaqE,UAAU05C,2BACvB/9C,EAAaqE,UAAUqzC,6BAEV,UAATnB,EACFuH,EAAgB3K,EAAOsE,4BACL,UAATlB,IACTuH,EAAgB3K,EAAOuE,8BAGvBoG,IACFzO,EAAMpoC,IAAI,uCAAwC62C,GAC9CA,EAAcE,gBAAkBF,EAAcG,eAChDH,EAAcE,eACXE,YAAY5H,EAAMgB,WAAWnE,QAC7BgL,OAAOL,EAAcG,gBACfH,EAAcM,UAAYN,EAAc7Z,UACjD6Z,EAAcM,SAASF,YAAY5H,EAAMgB,WAAWnE,QAAQgL,OAAOL,EAAc7Z,WAIvF,GAAI8U,GAAeA,EAAYxB,UAAYjB,EAAMgB,WAAWC,SAAU,CAEpE,IAAI8G,EAAkB,KAClBt+C,EAAesE,UAAUmzC,qBAC3B6G,EAAkBtF,EAAYxB,SAASC,wBAEvCz3C,EAAesE,UAAU05C,2BACzBh+C,EAAesE,UAAUqzC,6BAEZ,UAATnB,EACF8H,EAAkBtF,EAAYxB,SAASE,4BACrB,UAATlB,IACT8H,EAAkBtF,EAAYxB,SAASG,8BAGvC2G,IACFhP,EAAMpoC,IAAI,yCAA0Co3C,GAChDA,EAAgBL,gBAAkBK,EAAgBJ,eACpDI,EAAgBL,eACbE,YAAY5H,EAAMgB,WAAWC,UAC7B4G,OAAOE,EAAgBJ,gBACjBI,EAAgBD,UAAYC,EAAgBpa,UACrDoa,EAAgBD,SAASF,YAAY5H,EAAMgB,WAAWC,UAAU4G,OAAOE,EAAgBpa,aAM7FsX,IAAyB,IAAnBjF,EAAMgI,WAAmB/C,EAAG+C,UAAW,QAC5C,GAAIhI,EAAM+F,OAAStD,IAExBA,EAAcp0C,EAAO2uC,GAAGuJ,eAAetG,GACnCwC,GAAa,CAEf,GAAIzC,EAAMiH,MACR,GAAmD,YAA/ClO,EAAMqN,cAAcC,eAAeC,QACrCvN,EAAMmD,KAAK,0EAA2E8D,QACjF,GAA2B,iBAAhBA,EAAMiH,MACtBlO,EAAMmD,KAAK,2CAA4C8D,OAClD,CACL,IAAIkH,EAAWjH,EAAO,IAAMD,EAAMiH,MAAMriC,cACpCuiC,EAAS19C,EAAe29C,gBAAgBnH,GAAMkH,OAAOxqC,OAAO,SAAUsqC,GACxE,OAAOA,EAAMC,SAAStiC,gBAAkBsiC,CAC1C,GACA,GAAKC,GAA4B,IAAlBA,EAAO32C,OAGpB,IACEiyC,EAAY4E,oBAAoBF,GAChC,MAAOz4C,GACPqqC,EAAMmD,KAAK,mCAAqC+D,EAAO,UAAWvxC,QALpEqqC,EAAMmD,KAAK,gEAAiE8D,GAWlF,GAAIyC,EAAYxB,UAAYjB,EAAMgB,YAAchB,EAAMgB,WAAWC,SAAU,CAEzE,IAAI8G,EAAkB,KAClBt+C,EAAesE,UAAUmzC,qBAC3B6G,EAAkBtF,EAAYxB,SAASC,wBAEvCz3C,EAAesE,UAAU05C,2BACzBh+C,EAAesE,UAAUqzC,6BAEZ,UAATnB,EACF8H,EAAkBtF,EAAYxB,SAASE,4BACrB,UAATlB,IACT8H,EAAkBtF,EAAYxB,SAASG,8BAGvC2G,IACFhP,EAAMpoC,IAAI,yCAA0Co3C,GAChDA,EAAgBL,gBAAkBK,EAAgBJ,eACpDI,EAAgBL,eACbE,YAAY5H,EAAMgB,WAAWC,UAC7B4G,OAAOE,EAAgBJ,gBACjBI,EAAgBD,UAAYC,EAAgBpa,UACrDoa,EAAgBD,SAASF,YAAY5H,EAAMgB,WAAWC,UAAU4G,OAAOE,EAAgBpa,YAiBjG,GAAIuX,GAAW72C,EAAO63C,SAAU,CAC9B,IAAI+B,EAAK,KACT,GAAa,UAAThI,GAAoB5xC,EAAO63C,SAASb,kBAAoBh3C,EAAO63C,SAASb,iBAAiB70C,OAC3F,IAAK,IAAI8M,KAAKjP,EAAO63C,SAASb,iBACxB/nC,EAAEnE,KAAO+rC,IACX+C,EAAK3qC,EACLy7B,EAAMpoC,IAAI,wBAAyBs3C,SAGlC,GAAa,UAAThI,GAAoB5xC,EAAO63C,SAASZ,kBAAoBj3C,EAAO63C,SAASZ,iBAAiB90C,OAClG,IAAK,IAAI8M,KAAKjP,EAAO63C,SAASZ,iBACxBhoC,EAAEnE,KAAO+rC,IACX+C,EAAK3qC,EACLy7B,EAAMpoC,IAAI,wBAAyBs3C,IAIzC,GAAIA,EAAI,CAEN,IACE55C,EAAO63C,SAASgC,YAAYD,GAC5BnL,EAAaqL,aAAaF,GAAI,GAC9B,MAAOpwB,GACPkhB,EAAMnqC,MAAM,0DAA2DipB,GAGzE,IAAoB,IAAhBowB,EAAGD,SACL,IACEC,EAAG9+B,OACH,MAAO0O,GAAG,GAIlB,GAAIotB,EAAI,CAEN52C,EAAO63C,SAASC,SAASlB,GAEzBA,EAAGrC,QAAU,SAAUE,GACrB/J,EAAMpoC,IAAI,uBAAwBmyC,GAClC,IACEhG,EAAaqL,aAAarF,EAAGjiC,QAAQ,GACrC,MAAOgX,GACPkhB,EAAMnqC,MAAM,2CAA4CipB,GAE5D,EACA,IACEilB,EAAaqL,aAAalD,GAAI,GAC9B,MAAOptB,GACPkhB,EAAMnqC,MAAM,2CAA4CipB,IAI5D,GAAI4qB,EAAa,CACf,IAAI2F,EAAS3F,EAAYuD,UACvBqC,EAAS,KACPjmC,EAAO6iC,GAAMxC,EAAY5F,OAAOmD,MAClC+F,GAAsB,IAAf/F,EAAM+F,MAAkBtD,EAAYxB,SAASjB,MAClD59B,GAAQ2jC,EAAMsC,EAAS,WAClBjmC,IAAS2jC,EAAMsC,EAAS,YACvBjmC,GAAQ2jC,EAAMsC,EAAS,WACvBjmC,GAAS2jC,IAAMsC,EAAS,YAC9BA,GAAUA,IAAWD,IACvBrP,EAAMmD,KAAK,wCAA0CmM,EAAS,SAAWD,EAAS,IAAKpI,GACnFyC,EAAYwD,aAAcxD,EAAYwD,aAAaoC,GAClD5F,EAAYuD,UAAYqC,IAI/B7D,GAAqB1H,EAAayI,eAAc,GAGtD,SAAS+C,EAAe/J,GACtB,IAAIzB,EAAejB,EAAc0C,GACjC,IAAKzB,IAAiBA,EAAaC,YAEjC,OADAhE,EAAMmD,KAAK,kBACJ,KAET,IAAI7tC,EAASyuC,EAAaC,YAC1B,IAAK1uC,EAAO2uC,GAEV,OADAjE,EAAMmD,KAAK,0BACJ,KAET,IAAI6E,EAAS,GACTgC,EAAe10C,EAAO2uC,GAAGgG,kBAC7B,IAAK,IAAIuF,KAAMxF,EAAc,CAC3B,IAAI/C,EAAQ,KACRuI,EAAG1L,QAAU0L,EAAG1L,OAAOmD,QACzBA,EAAQ,CAAEzP,IAAKgY,EAAGhY,KAClByP,EAAMpzC,KAAO27C,EAAG1L,OAAOmD,MAAMC,KAC7BD,EAAM7mC,GAAKovC,EAAG1L,OAAOmD,MAAM7mC,GAC3B6mC,EAAMd,MAAQqJ,EAAG1L,OAAOmD,MAAMd,OAE5Bc,GAAOe,EAAOrwC,KAAKsvC,GAEzB,OAAOe,EAGT,SAASyH,EAAgBjK,GACvB,IAAIzB,EAAejB,EAAc0C,GACjC,IAAKzB,IAAiBA,EAAaC,YAEjC,OADAhE,EAAMmD,KAAK,kBACJ,KAET,IAAI7tC,EAASyuC,EAAaC,YAC1B,IAAK1uC,EAAO2uC,GAEV,OADAjE,EAAMmD,KAAK,0BACJ,KAET,IAAI6E,EAAS,GACTgC,EAAe10C,EAAO2uC,GAAGgG,kBAC7B,IAAK,IAAIuF,KAAMxF,EAAc,CAC3B,IAAI/C,EAAQ,KACRuI,EAAGtH,UAAYsH,EAAGtH,SAASjB,QAC7BA,EAAQ,CAAEzP,IAAKgY,EAAGhY,KAClByP,EAAMpzC,KAAO27C,EAAGtH,SAASjB,MAAMC,KAC/BD,EAAM7mC,GAAKovC,EAAGtH,SAASjB,MAAM7mC,GAC7B6mC,EAAMd,MAAQqJ,EAAGtH,SAASjB,MAAMd,OAE9Bc,GAAOe,EAAOrwC,KAAKsvC,GAEzB,OAAOe,EAGT,SAAS0H,EAAUlK,EAAUhO,EAAKmY,EAAQhuC,GACxCA,EAA0B,mBAAVA,EAAuBA,EAASq+B,EAAMqB,KACtD,IAAI0C,EAAejB,EAAc0C,GACjC,IAAKzB,IAAiBA,EAAaC,YAGjC,OAFAhE,EAAMmD,KAAK,uBACXxhC,EAAO,GAGT,IAAI0qC,EAASsD,EAAS,SAAW,QAC7Br6C,EAASyuC,EAAaC,YAI1B,GAHK1uC,EAAOozC,OAAO2D,KAAS/2C,EAAOozC,OAAO2D,GAAU,CAAE7wC,MAAO,IAI3DlG,EAAO2uC,IACP3uC,EAAO2uC,GAAGwE,WACsC,WAA/CzI,EAAMqN,cAAcC,eAAeC,SACa,WAA/CvN,EAAMqN,cAAcC,eAAeC,SACrC,CAEA,IAAIhkB,EAAQj0B,EAAO2uC,GACnB,GAAIzM,EAAK,CACP,IAAIkS,EAAcp0C,EAAO2uC,GAAGgG,kBAAkBx4B,KAAMlN,GAAMA,EAAEizB,MAAQA,GAAiC,UAA1BjzB,EAAE2jC,SAASjB,MAAMC,MAC5F,IAAKwC,EAGH,OAFA1J,EAAMmD,KAAK,iCAAmC3L,QAC9C71B,EAAO,GAGT,GAAIguC,IAAWjG,EAAYxB,SAGzB,OAFAlI,EAAMmD,KAAK,6CACXxhC,EAAO,GAEF,IAAKguC,IAAWjG,EAAY5F,OAGjC,OAFA9D,EAAMmD,KAAK,4CACXxhC,EAAO,GAGT4nB,EAAQomB,EAASjG,EAAYxB,SAAWwB,EAAY5F,OAStD,OAPAva,EAAMkf,WAAW7qC,KAAK,SAAUgyC,GAC9BA,EAAM96C,QAAQ,SAAUmB,GACjBA,GAAoB,UAAbA,EAAIixC,OACXyI,IAAW15C,EAAI45C,eAAmBF,GAAuB,iBAAb15C,EAAIpC,MACrD8N,EAAO1L,EAAI65C,WAAa75C,EAAI65C,WAAa,GAC3C,EACF,GACOx6C,EAAOozC,OAAO2D,GAAQ7wC,MAM7B,OAFAwkC,EAAMmD,KAAK,eAAiBkJ,EAAS,uCACrC1qC,EAAO,GAKX,SAASouC,EAAQvK,EAAUhO,EAAKuU,GAC9B,IAAIhI,EAAejB,EAAc0C,GACjC,IAAKzB,IAAiBA,EAAaC,YAEjC,OADAhE,EAAMmD,KAAK,mBACJ,EAET,IAAI7tC,EAASyuC,EAAaC,YAC1B,IAAK1uC,EAAO2uC,GAEV,OADAjE,EAAMmD,KAAK,2BACJ,EAET,IAAK7tC,EAAO63C,SAEV,OADAnN,EAAMmD,KAAK,8BACJ,EAET,GAAI4I,EAAO,CAET,IAAKz2C,EAAO63C,SAASZ,kBAAgE,IAA5Cj3C,EAAO63C,SAASZ,iBAAiB90C,OAExE,OADAuoC,EAAMmD,KAAK,mBACJ,EAET,GAAI3L,EAAK,CACP,IAAIkS,EAAcp0C,EAAO2uC,GAAGgG,kBAAkBx4B,KAAMlN,GAAMA,EAAEizB,MAAQA,GAAiC,UAA1BjzB,EAAE2jC,SAASjB,MAAMC,MAC5F,OAAKwC,EAIAA,EAAY5F,QAAW4F,EAAY5F,OAAOmD,OAIvCyC,EAAY5F,OAAOmD,MAAMxgB,SAH/BuZ,EAAMmD,KAAK,4BAA8B3L,IAClC,IALPwI,EAAMmD,KAAK,iCAAmC3L,IACvC,GAQT,OAAQliC,EAAO63C,SAASZ,iBAAiB,GAAG9lB,QAI9C,IAAKnxB,EAAO63C,SAASb,kBAAgE,IAA5Ch3C,EAAO63C,SAASb,iBAAiB70C,OAExE,OADAuoC,EAAMmD,KAAK,mBACJ,EAET,GAAI3L,EAAK,CACP,IAAIkS,EAAcp0C,EAAO2uC,GAAGgG,kBAAkBx4B,KAAMlN,GAAMA,EAAEizB,MAAQA,GAAiC,UAA1BjzB,EAAE2jC,SAASjB,MAAMC,MAC5F,OAAKwC,EAIAA,EAAY5F,QAAW4F,EAAY5F,OAAOmD,OAIvCyC,EAAY5F,OAAOmD,MAAMxgB,SAH/BuZ,EAAMmD,KAAK,4BAA8B3L,IAClC,IALPwI,EAAMmD,KAAK,iCAAmC3L,IACvC,GAQT,OAAQliC,EAAO63C,SAASb,iBAAiB,GAAG7lB,QAKlD,SAASupB,EAAKxK,EAAUhO,EAAKuU,EAAOiE,GAClC,IAAIjM,EAAejB,EAAc0C,GACjC,IAAKzB,IAAiBA,EAAaC,YAEjC,OADAhE,EAAMmD,KAAK,mBACJ,EAET,IAAI7tC,EAASyuC,EAAaC,YAC1B,IAAK1uC,EAAO2uC,GAEV,OADAjE,EAAMmD,KAAK,2BACJ,EAET,IAAK7tC,EAAO63C,SAEV,OADAnN,EAAMmD,KAAK,8BACJ,EAET,GAAI4I,EAAO,CAET,IAAKz2C,EAAO63C,SAASZ,kBAAgE,IAA5Cj3C,EAAO63C,SAASZ,iBAAiB90C,OAExE,OADAuoC,EAAMmD,KAAK,mBACJ,EAET,GAAI3L,EAAK,CACP,IAAIkS,EAAcp0C,EAAO2uC,GAAGgG,kBAAkBx4B,KAAMlN,GAAMA,EAAEizB,MAAQA,GAAiC,UAA1BjzB,EAAE2jC,SAASjB,MAAMC,MAC5F,IAAKwC,EAEH,OADA1J,EAAMmD,KAAK,iCAAmC3L,IACvC,EAET,IAAKkS,EAAY5F,SAAW4F,EAAY5F,OAAOmD,MAE7C,OADAjH,EAAMmD,KAAK,4BAA8B3L,IAClC,EAETkS,EAAY5F,OAAOmD,MAAMxgB,SAAUupB,OAEnC,IAAK,MAAMC,KAAe36C,EAAO63C,SAASZ,iBACxC0D,EAAYxpB,SAAWupB,MAGtB,CAEL,IAAK16C,EAAO63C,SAASb,kBAAgE,IAA5Ch3C,EAAO63C,SAASb,iBAAiB70C,OAExE,OADAuoC,EAAMmD,KAAK,mBACJ,EAET,GAAI3L,EAAK,CACP,IAAIkS,EAAcp0C,EAAO2uC,GAAGgG,kBAAkBx4B,KAAMlN,GAAMA,EAAEizB,MAAQA,GAAiC,UAA1BjzB,EAAE2jC,SAASjB,MAAMC,MAC5F,IAAKwC,EAEH,OADA1J,EAAMmD,KAAK,iCAAmC3L,IACvC,EAET,IAAKkS,EAAY5F,SAAW4F,EAAY5F,OAAOmD,MAE7C,OADAjH,EAAMmD,KAAK,4BAA8B3L,IAClC,EAETkS,EAAY5F,OAAOmD,MAAMxgB,SAAUupB,OAEnC,IAAK,MAAME,KAAe56C,EAAO63C,SAASb,iBACxC4D,EAAYzpB,SAAWupB,EAI7B,OAAO,EAGT,SAASG,EAAW3K,EAAUhO,GAC5B,IAAIuM,EAAejB,EAAc0C,GACjC,IAAKzB,IAAiBA,EAAaC,YAEjC,OADAhE,EAAMmD,KAAK,kBACJ,iBAET,IAAI7tC,EAASyuC,EAAaC,YAC1B,IAAK1uC,EAAO2uC,GAAI,MAAO,yBAEvB,GAAI3uC,EAAO2uC,GAAGwE,SAAU,CACtB,IAAIlf,EAAQj0B,EAAO2uC,GACfn8B,EAAS0vB,GAAY,UACzB,GAAIA,EAAK,CACP,IAAIkS,EAAcp0C,EAAO2uC,GAAGgG,kBAAkBx4B,KAAMlN,GAAMA,EAAEizB,MAAQA,GAAiC,UAA1BjzB,EAAE2jC,SAASjB,MAAMC,MAC5F,IAAKwC,EAEH,OADA1J,EAAMmD,KAAK,iCAAmC3L,GACvC,iCAAmCA,EAE5C,IAAKkS,EAAYxB,SAEf,OADAlI,EAAMmD,KAAK,8BAAgC3L,GACpC,8BAAgCA,EAEzCjO,EAAQmgB,EAAYxB,SAYtB,OAVK5yC,EAAOqzC,QAAQ7gC,KAClBxS,EAAOqzC,QAAQ7gC,GAAU,CACvB2mB,MAAO,KACP2hB,MAAO,KACPC,SAAU,KACVC,MAAO,KACPC,SAAU,KACV/0C,MAAO,gBAGNlG,EAAOqzC,QAAQ7gC,GAAQ2mB,MAkDrBn5B,EAAOqzC,QAAQ7gC,GAAQtM,OAjD5BwkC,EAAMpoC,IAAI,0BAA4B4/B,EAAM,YAAcA,EAAM,IAAM,mBACtEliC,EAAOqzC,QAAQ7gC,GAAQ2mB,MAAQ+hB,YAAY,WACzCjnB,EAAMkf,WAAW7qC,KAAK,SAAUgyC,GAC9BA,EAAM96C,QAAQ,SAAUmB,GACtB,IAAKA,EAAK,OACV,IAAIw6C,GAAU,EAkBd,IAfqB,UAAlBx6C,EAAIy6C,WAAyBz6C,EAAImK,GAAGyL,cAActR,QAAQ,UAAW,IACzD,gBAAbtE,EAAIpC,MACJoC,EAAImK,GAAG7F,QAAQ,QAAU,EAGzBk2C,GAAU,EAEE,QAAZx6C,EAAIpC,OACJoC,EAAI06C,eACmB,QAAtB16C,EAAI26C,eAAiD,KAAtB36C,EAAI26C,gBAGpCH,GAAU,GAGRA,EAGF,GAFAn7C,EAAOqzC,QAAQ7gC,GAAQsoC,MAAQn6C,EAAI06C,cACnCr7C,EAAOqzC,QAAQ7gC,GAAQwoC,MAAQr6C,EAAIiB,UACK,OAApC5B,EAAOqzC,QAAQ7gC,GAAQuoC,UAAyD,OAApC/6C,EAAOqzC,QAAQ7gC,GAAQyoC,SAErEj7C,EAAOqzC,QAAQ7gC,GAAQuoC,SAAW/6C,EAAOqzC,QAAQ7gC,GAAQsoC,MACzD96C,EAAOqzC,QAAQ7gC,GAAQyoC,SAAWj7C,EAAOqzC,QAAQ7gC,GAAQwoC,UACpD,CAEL,IAAIO,EAAav7C,EAAOqzC,QAAQ7gC,GAAQwoC,MAAQh7C,EAAOqzC,QAAQ7gC,GAAQyoC,SACpB,WAA/CvQ,EAAMqN,cAAcC,eAAeC,UAAsBsD,GAA0B,KACvF,IAAIC,EAAUj6C,KAAKk6C,MACmD,GAAlEz7C,EAAOqzC,QAAQ7gC,GAAQsoC,MAAQ96C,EAAOqzC,QAAQ7gC,GAAQuoC,UAAiBQ,GAExB,WAA/C7Q,EAAMqN,cAAcC,eAAeC,UAAsBuD,EAAUz5C,SAASy5C,EAAU,MAC1Fx7C,EAAOqzC,QAAQ7gC,GAAQtM,MAAQs1C,EAAU,aAEzCx7C,EAAOqzC,QAAQ7gC,GAAQuoC,SAAW/6C,EAAOqzC,QAAQ7gC,GAAQsoC,MACzD96C,EAAOqzC,QAAQ7gC,GAAQyoC,SAAWj7C,EAAOqzC,QAAQ7gC,GAAQwoC,MAG/D,EACF,IACC,KACI,eAKT,OADAtQ,EAAMmD,KAAK,oDACJ,iCAIX,SAAS6N,EAAWxL,EAAUhO,EAAKmR,GACjC,IAAI5E,EAAejB,EAAc0C,GACjC,IAAKzB,IAAiBA,EAAaC,YAEjC,YADAhE,EAAMmD,KAAK,kBAGb,IAAI7tC,EAASyuC,EAAaC,YAC1B,IAAK1uC,EAAO2uC,GAEV,YADAjE,EAAMmD,KAAK,0BAGb,IAAIuG,EAAcp0C,EAAO2uC,GAAGgG,kBAAkBx4B,KAAMlN,GAAMA,EAAEizB,MAAQA,GACpE,IAAKkS,EAEH,YADA1J,EAAMmD,KAAK,0BAA2B3L,GAGxC,IAAKkS,EAAY5F,OAEf,YADA9D,EAAMmD,KAAK,qCAAsC3L,GAGnD,IAAI39B,EAAS6vC,EAAY5F,OAAOgK,gBAC3Bj0C,GAAWA,EAAOk0C,WAAyC,IAA5Bl0C,EAAOk0C,UAAUt2C,OAE1CoC,EAAOk0C,UAAUt2C,OAAS,EACnCuoC,EAAMmD,KAAK,oEACFxb,MAAMghB,IAAYA,EAAU,EACrC3I,EAAMmD,KAAK,iDAEXtpC,EAAOk0C,UAAU,GAAGJ,WAAahF,EACjCe,EAAY5F,OAAOkK,cAAcn0C,IAPjCmmC,EAAMmD,KAAK,2BAWf,SAASqH,EAAY30C,GACnBmqC,EAAMnqC,MAAM,gBAAiBA,GAG/B,SAAS8xC,GAAcnC,EAAUyL,GAC/BjR,EAAMpoC,IAAI,yBACV,IAAImsC,EAAejB,EAAc0C,GACjC,IAAKzB,EAEH,OAEF,IAAIzuC,EAASyuC,EAAaC,YAC1B,GAAI1uC,EAAQ,CACV,IAAsB,IAAlB27C,EAAwB,CAE1B,IAAIx8B,EAAU,CAAEwwB,MAAO,SAAUrB,YAAa5D,EAAMmF,aAAa,KAC7DpB,EAAa1pC,QAAOoa,EAAe,MAAIsvB,EAAa1pC,OACpD8nC,IAAW1tB,EAAmB,UAAI0tB,GACtCnC,EAAMltC,MAAM,kCAAoC0yC,EAAW,MAC3DxF,EAAMltC,MAAM2hB,GACRgtB,GACFhtB,EAAoB,WAAI4Y,EACxB5Y,EAAmB,UAAI+wB,EACvBpQ,EAAG/rB,KAAK5Z,KAAK8I,UAAUkc,KAEvBurB,EAAMsD,YAAYzwC,EAAS,IAAMw6B,EAAY,IAAMmY,EAAU,CAC3DjC,KAAM,OACNvB,gBAAiBA,EACjB7pC,KAAMsc,IAKRnf,EAAOozC,SACLpzC,EAAOozC,OAAc,OAAKpzC,EAAOozC,OAAc,MAAEja,OAAOyiB,cAAc57C,EAAOozC,OAAc,MAAEja,OAC7Fn5B,EAAOozC,OAAe,QAAKpzC,EAAOozC,OAAe,OAAEja,OAAOyiB,cAAc57C,EAAOozC,OAAe,OAAEja,QAEtG,IAAK,IAAI/a,KAAKpe,EAAOqzC,QACfrzC,EAAOqzC,QAAQj1B,GAAG+a,OAAOyiB,cAAc57C,EAAOqzC,QAAQj1B,GAAG+a,OAE/Dn5B,EAAOqzC,QAAU,CAAA,GACZrzC,EAAO67C,gBAAkB77C,EAAO63C,WACnCnN,EAAMpoC,IAAI,gCACVooC,EAAMoR,cAAc97C,EAAO63C,WAE7B73C,EAAO67C,gBAAiB,EACxB77C,EAAO63C,SAAW,KAElB,IACE73C,EAAO2uC,GAAGr1B,QACV,MAAOkQ,IAGTxpB,EAAO2uC,GAAK,KACZ3uC,EAAOgvC,WAAa,KACpBhvC,EAAO4zC,MAAQ,KACf5zC,EAAO4uC,UAAY,KACnB5uC,EAAO2zC,SAAU,EACjB3zC,EAAO+wC,YAAc,CAAA,EACrB/wC,EAAOwxC,WAAa,KACpBxxC,EAAOyyC,mBAAoB,EAE7BhE,EAAasN,YAhiFfrxC,EAAcmhC,GAGd1sC,KAAK68C,UAAY,WACf,OAAOz+C,CACT,EACA4B,KAAKw5B,YAAc,WACjB,OAAO4U,CACT,EACApuC,KAAK1C,UAAY,SAAUqzC,IACzBA,EAAYA,GAAa,CAAA,GACfhE,QAAsC,mBAArBgE,EAAUhE,QAAwBgE,EAAUhE,QAAUpB,EAAMqB,KACvF+D,EAAUvvC,MAAkC,mBAAnBuvC,EAAUvvC,MAAsBuvC,EAAUvvC,MAAQmqC,EAAMqB,KACjF+D,EAAqB,WAAI,EACzBplC,EAAcolC,EAChB,EACA3wC,KAAK88C,aAAe,WAClB,OAAOlkB,CACT,EACA54B,KAAK+8C,QAAU,SAAUpM,IAkazB,SAAiBA,GAMf,GALAA,EAAYA,GAAa,CAAA,EAEzBA,EAAUhE,QAAsC,mBAArBgE,EAAUhE,QAAwBgE,EAAUhE,QAAUpB,EAAMqB,KACvF+D,EAAUvvC,MAAkC,mBAAnBuvC,EAAUvvC,MAAsBuvC,EAAUvvC,MAAQmqC,EAAMqB,KACjFrB,EAAMpoC,IAAI,mCACLirC,EAGH,OAFA7C,EAAMmD,KAAK,8CACXiC,EAAUvvC,MAAM,yCAIlB,IAAI+tC,EAAc5D,EAAMmF,aAAa,IACjC1wB,EAAU,CAAEwwB,MAAO,OAAQrB,YAAaA,GACxCvpC,IAAOoa,EAAe,MAAIpa,GAC1B8nC,IAAW1tB,EAAmB,UAAI0tB,GACtC,GAAIV,EAUF,OATAwB,EAAaW,GAAe,SAAUjrC,GACpCqnC,EAAMpoC,IAAI,gBACVooC,EAAMltC,MAAM6F,GACU,gBAAlBA,EAAY,OACdqnC,EAAMnqC,MAAM,UAAY8C,EAAY,MAAE0F,KAAO,IAAM1F,EAAY,MAAEkQ,QAEnEu8B,EAAUhE,QAAQzoC,EACpB,OACAy8B,EAAG/rB,KAAK5Z,KAAK8I,UAAUkc,IAGzBurB,EAAMsD,YAAYzwC,EAAQ,CACxB0wC,KAAM,OACNvB,gBAAiBA,EACjB7pC,KAAMsc,EACN2sB,QAAS,SAAUzoC,GACjBqnC,EAAMpoC,IAAI,gBACVooC,EAAMltC,MAAM6F,GACU,gBAAlBA,EAAY,OACdqnC,EAAMnqC,MAAM,UAAY8C,EAAY,MAAE0F,KAAO,IAAM1F,EAAY,MAAEkQ,QAEnEu8B,EAAUhE,QAAQzoC,IAEpB9C,MAAO,SAAU4tC,EAAYC,GAC3B1D,EAAMnqC,MAAM4tC,EAAa,IAAKC,GACV,KAAhBA,EAAoB0B,EAAUvvC,MAAM4tC,EAAa,yBAChD2B,EAAUvvC,MAAM4tC,EAAa,KAAOC,MA5c7C8N,CAAQpM,EACV,EACA3wC,KAAKg9C,QAAU,SAAUrM,IAgdzB,SAAwBA,GACtBA,EAAYA,GAAa,CAAA,EAEzBA,EAAUhE,QAAsC,mBAArBgE,EAAUhE,QAAwBgE,EAAUhE,QAAUpB,EAAMqB,KACvF+D,EAAUvvC,MAAkC,mBAAnBuvC,EAAUvvC,MAAsBuvC,EAAUvvC,MAAQmqC,EAAMqB,KACjF,IAAIqQ,GAA8B,IAArBtM,EAAUsM,OACnBC,GAAkB,OACmB,IAA9BvM,EAAUuM,iBAAiE,OAA9BvM,EAAUuM,kBAChEA,GAAgD,IAA9BvM,EAAUuM,iBAC9B,IAAIC,GAA8C,IAA7BxM,EAAUwM,eAE/B,GADA5R,EAAMpoC,IAAI,sBAAwBy1B,EAAY,YAAcqkB,EAAS,MAChErkB,EAIH,OAHA2S,EAAMmD,KAAK,yBACXiC,EAAUhE,eACNuQ,GAAiBxQ,EAAiBG,aAGxC,GAAIsQ,EACF,IAAK,IAAIpM,KAAY1C,EAAe2E,EAAcjC,EAAU,CAAEkC,WAAW,IAE3E,IAAK7E,EAIH,OAHA7C,EAAMmD,KAAK,yCACX9V,EAAY,UACZ+X,EAAUhE,UAIZ,IAAI3sB,EAAU,CAAEwwB,MAAO,UAAWrB,YAAa5D,EAAMmF,aAAa,KAC9D9qC,IAAOoa,EAAe,MAAIpa,GAC1B8nC,IAAW1tB,EAAmB,UAAI0tB,GACtC,GAAIuP,EAeF,OAZIjQ,GACFrM,EAAGyC,QAAU,KACbzC,EAAGxmB,QACHwmB,EAAK,MAELhlC,EAAUyhD,WAAWh/C,EAAS,IAAMw6B,EAAW59B,KAAK8I,UAAUkc,IAEhEurB,EAAMpoC,IAAI,sBACVy1B,EAAY,KACZwV,GAAY,EACZuC,EAAUhE,eACNuQ,GAAiBxQ,EAAiBG,aAGxC,GAAIG,EAAY,CACdhtB,EAAoB,WAAI4Y,EAExB,IAAIykB,EAAkB,WACpB,IAAK,IAAIxM,KAAa5D,EACpBtM,EAAGjtB,oBAAoBm9B,EAAW5D,EAAW4D,IAE/ClQ,EAAGjtB,oBAAoB,UAAW4pC,GAClC3c,EAAGjtB,oBAAoB,QAAS6pC,GAC5BrQ,GACFj6B,aAAai6B,GAEfvM,EAAGxmB,OACL,EAEImjC,EAAkB,SAAUzpC,GAC9B,IAAI/U,EAAO9D,KAAKqJ,MAAMwP,EAAM/U,MACxBA,EAAK2xC,YAAczwB,EAAQywB,YAAc3xC,EAAKqwC,aAAenvB,EAAQmvB,cACvEkO,IACA1M,EAAUhE,UACNuQ,GAAiBxQ,EAAiBG,YAE1C,EACI0Q,EAAgB,WAClBF,IACA1M,EAAUvvC,MAAM,qDACZ87C,GAAiBxQ,EAAiBG,WACxC,EAWA,OATAlM,EAAGrtB,iBAAiB,UAAWgqC,GAC/B3c,EAAGrtB,iBAAiB,QAASiqC,QAEP,IAAlB5c,EAAGkR,WACLlR,EAAG/rB,KAAK5Z,KAAK8I,UAAUkc,IAEvBu9B,KAKJhS,EAAMsD,YAAYzwC,EAAS,IAAMw6B,EAAW,CAC1CkW,KAAM,OACNvB,gBAAiBA,EACjB7pC,KAAMsc,EACN2sB,QAAS,SAAUzoC,GACjBqnC,EAAMpoC,IAAI,sBACVooC,EAAMltC,MAAM6F,GACZ00B,EAAY,KACZwV,GAAY,EACU,YAAlBlqC,EAAY,OACdqnC,EAAMnqC,MAAM,UAAY8C,EAAY,MAAE0F,KAAO,IAAM1F,EAAY,MAAEkQ,QAEnEu8B,EAAUhE,UACNuQ,GAAiBxQ,EAAiBG,aAExCzrC,MAAO,SAAU4tC,EAAYC,GAC3B1D,EAAMnqC,MAAM4tC,EAAa,IAAKC,GAE9BrW,EAAY,KACZwV,GAAY,EACZuC,EAAUhE,UACNuQ,GAAiBxQ,EAAiBG,eA3jB1CphC,CAAeklC,EACjB,EACA3wC,KAAKw9C,OAAS,SAAU7M,IA+jBxB,SAAsBA,GAmBpB,GAlBAA,EAAYA,GAAa,CAAA,EACzBA,EAAUhE,QAAsC,mBAArBgE,EAAUhE,QAAwBgE,EAAUhE,QAAUpB,EAAMqB,KACvF+D,EAAUvvC,MAAkC,mBAAnBuvC,EAAUvvC,MAAsBuvC,EAAUvvC,MAAQmqC,EAAMqB,KACjF+D,EAAUqB,mBAAqBrB,EAAUqB,oBAAsB,CAC7DyL,SAAS,GAEX9M,EAAUoH,cAAkD,mBAA3BpH,EAAUoH,cAA8BpH,EAAUoH,cAAgBxM,EAAMqB,KACzG+D,EAAU0D,SAAwC,mBAAtB1D,EAAU0D,SAAyB1D,EAAU0D,SAAW9I,EAAMqB,KAC1F+D,EAAUT,WAA4C,mBAAxBS,EAAUT,WAA2BS,EAAUT,WAAa3E,EAAMqB,KAChG+D,EAAUb,YAA8C,mBAAzBa,EAAUb,YAA4Ba,EAAUb,YAAcvE,EAAMqB,KACnG+D,EAAUR,SAAwC,mBAAtBQ,EAAUR,SAAyBQ,EAAUR,SAAW5E,EAAMqB,KAC1F+D,EAAU5P,UAA0C,mBAAvB4P,EAAU5P,UAA0B4P,EAAU5P,UAAYwK,EAAMqB,KAC7F+D,EAAUgK,aAAgD,mBAA1BhK,EAAUgK,aAA6BhK,EAAUgK,aAAepP,EAAMqB,KACtG+D,EAAUwE,cAAkD,mBAA3BxE,EAAUwE,cAA8BxE,EAAUwE,cAAgB5J,EAAMqB,KACzG+D,EAAUsB,OAAoC,mBAApBtB,EAAUsB,OAAuBtB,EAAUsB,OAAS1G,EAAMqB,KACpF+D,EAAUmB,WAA4C,mBAAxBnB,EAAUmB,WAA2BnB,EAAUmB,WAAavG,EAAMqB,KAChG+D,EAAUiM,UAA0C,mBAAvBjM,EAAUiM,UAA0BjM,EAAUiM,UAAYrR,EAAMqB,KAC7F+D,EAAUX,WAA4C,mBAAxBW,EAAUX,WAA2BW,EAAUX,WAAazE,EAAMqB,MAC3FwB,EAGH,OAFA7C,EAAMmD,KAAK,8CACXiC,EAAUvvC,MAAM,yCAGlB,IAAIs8C,EAAS/M,EAAU+M,OACvB,IAAKA,EAGH,OAFAnS,EAAMnqC,MAAM,uBACZuvC,EAAUvvC,MAAM,kBAGlB,IAAIu8C,EAAWhN,EAAUgN,SACrBC,EAAYjN,EAAUiN,UACtBC,EAAclN,EAAU/qC,MAAQ+qC,EAAU/qC,MAAQA,EAClDupC,EAAc5D,EAAMmF,aAAa,IACjC1wB,EAAU,CACZwwB,MAAO,SACPkN,OAAQA,EACRI,UAAWH,EACXI,WAAYH,EACZzO,YAAaA,GAEX0O,IAAa79B,EAAe,MAAI69B,GAChCnQ,IAAW1tB,EAAmB,UAAI0tB,GACtC,GAAIV,EAwHF,OAvHAwB,EAAaW,GAAe,SAAUjrC,GAEpC,GADAqnC,EAAMltC,MAAM6F,GACU,YAAlBA,EAAY,MAGd,OAFAqnC,EAAMnqC,MAAM,UAAY8C,EAAY,MAAE0F,KAAO,IAAM1F,EAAY,MAAEkQ,aACjEu8B,EAAUvvC,MAAM,UAAY8C,EAAY,MAAE0F,KAAO,IAAM1F,EAAY,MAAEkQ,QAGvE,IAAI28B,EAAW7sC,EAAKpF,KAAS,GAC7BysC,EAAMpoC,IAAI,mBAAqB4tC,GAC/B,IAAIzB,EAAe,CACjB9wC,QAAS8vC,EACToP,OAAQA,EACR/xC,GAAIolC,EACJnrC,MAAOi4C,EACP1K,UAAU,EACV5D,YAAa,CACXyO,SAAS,EACTtF,SAAU,KACVgE,gBAAgB,EAChBjI,MAAO,KACPkC,iBAAkB,KAClBnH,GAAI,KACJwC,mBAAoBrB,EAAUqB,mBAC9BJ,YAAa,CAAA,EACbS,WAAY,KACZ8B,SAAS,EACTK,SAAS,EACTN,QAAS,CAAA,GAEX+J,MAAO,WACL,OAAOlN,GAETmN,UAAW,WACT,OAAOR,GAETzC,UAAW,SAAUlY,EAAK71B,GACxB,OAAO+tC,EAAUlK,EAAUhO,GAAK,EAAM71B,IAExCixC,gBAAiB,SAAUpb,EAAK71B,GAC9B,OAAO+tC,EAAUlK,EAAUhO,GAAK,EAAM71B,IAExCkxC,eAAgB,SAAUrb,EAAK71B,GAC7B,OAAO+tC,EAAUlK,EAAUhO,GAAK,EAAO71B,IAEzCmxC,aAAc,SAAUtb,GACtB,OAAOuY,EAAQvK,EAAUhO,GAAK,IAEhCub,UAAW,SAAUvb,GACnB,OAAOwY,EAAKxK,EAAUhO,GAAK,GAAO,IAEpCwb,YAAa,SAAUxb,GACrB,OAAOwY,EAAKxK,EAAUhO,GAAK,GAAO,IAEpCyb,aAAc,SAAUzb,GACtB,OAAOuY,EAAQvK,EAAUhO,GAAK,IAEhC0b,UAAW,SAAU1b,GACnB,OAAOwY,EAAKxK,EAAUhO,GAAK,GAAM,IAEnC2b,YAAa,SAAU3b,GACrB,OAAOwY,EAAKxK,EAAUhO,GAAK,GAAM,IAEnC2Y,WAAY,SAAU3Y,GACpB,OAAO2Y,EAAW3K,EAAUhO,IAE9B4b,cAAe,SAAU5b,EAAKmR,GAC5B,OAAOqI,EAAWxL,EAAUhO,EAAKmR,IAEnCt/B,KAAM,SAAU+7B,GACdG,EAAYC,EAAUJ,IAExB7xC,KAAM,SAAU6xC,GACduB,EAASnB,EAAUJ,IAErB+B,KAAM,SAAU/B,GACdyB,EAASrB,EAAUJ,IAErBoH,cAAepH,EAAUoH,cACzB1D,SAAU1D,EAAU0D,SACpBnE,WAAYS,EAAUT,WACtBJ,YAAaa,EAAUb,YACvBK,SAAUQ,EAAUR,SACpBpP,UAAW4P,EAAU5P,UACrB8V,YAAa,SAAUlG,GACrBkF,EAAc9E,GAAU,EAAMJ,IAEhC8F,aAAc,SAAU9F,GACtBkF,EAAc9E,GAAU,EAAOJ,IAEjCiO,iBAAkB,SAAUjO,GAC1BmG,EAAkB/F,EAAUJ,IAE9BoG,cAAe,SAAUpG,GACvBoG,EAAchG,EAAUJ,IAE1BmK,eAAgB,WACd,OAAOA,EAAe/J,IAExBiK,gBAAiB,WACf,OAAOA,EAAgBjK,IAEzB4J,aAAchK,EAAUgK,aACxBxF,cAAexE,EAAUwE,cACzBlD,OAAQtB,EAAUsB,OAClBH,WAAYnB,EAAUmB,WACtB8K,UAAWjM,EAAUiM,UACrB5M,WAAYW,EAAUX,WACtBD,OAAQ,SAAUtM,GAChByP,GAAcnC,GAA0B,IAAhBtN,IAE1BwM,OAAQ,SAAUU,GAChBqC,EAAcjC,EAAUJ,KAG5BtC,EAAc0C,GAAYzB,EAC1BqB,EAAUhE,QAAQ2C,EACpB,EACAtvB,EAAoB,WAAI4Y,OACxB+H,EAAG/rB,KAAK5Z,KAAK8I,UAAUkc,IAGzBurB,EAAMsD,YAAYzwC,EAAS,IAAMw6B,EAAW,CAC1CkW,KAAM,OACNvB,gBAAiBA,EACjB7pC,KAAMsc,EACN2sB,QAAS,SAAUzoC,GAEjB,GADAqnC,EAAMltC,MAAM6F,GACU,YAAlBA,EAAY,MAGd,OAFAqnC,EAAMnqC,MAAM,UAAY8C,EAAY,MAAE0F,KAAO,IAAM1F,EAAY,MAAEkQ,aACjEu8B,EAAUvvC,MAAM,UAAY8C,EAAY,MAAE0F,KAAO,IAAM1F,EAAY,MAAEkQ,QAGvE,IAAI28B,EAAW7sC,EAAKpF,KAAS,GAC7BysC,EAAMpoC,IAAI,mBAAqB4tC,GAC/B,IAAIzB,EAAe,CACjB9wC,QAAS8vC,EACToP,OAAQA,EACR/xC,GAAIolC,EACJnrC,MAAOi4C,EACP1K,UAAU,EACV5D,YAAa,CACXyO,SAAS,EACTtF,SAAU,KACVgE,gBAAgB,EAChBjI,MAAO,KACPkC,iBAAkB,KAClBnH,GAAI,KACJwC,mBAAoBrB,EAAUqB,mBAC9BJ,YAAa,CAAA,EACbS,WAAY,KACZ8B,SAAS,EACTK,SAAS,EACTN,QAAS,CAAA,GAEX+J,MAAO,WACL,OAAOlN,GAETmN,UAAW,WACT,OAAOR,GAETzC,UAAW,SAAUlY,EAAK71B,GACxB,OAAO+tC,EAAUlK,EAAUhO,GAAK,EAAM71B,IAExCixC,gBAAiB,SAAUpb,EAAK71B,GAC9B,OAAO+tC,EAAUlK,EAAUhO,GAAK,EAAM71B,IAExCkxC,eAAgB,SAAUrb,EAAK71B,GAC7B,OAAO+tC,EAAUlK,EAAUhO,GAAK,EAAO71B,IAEzCmxC,aAAc,SAAUtb,GACtB,OAAOuY,EAAQvK,EAAUhO,GAAK,IAEhCub,UAAW,SAAUvb,GACnB,OAAOwY,EAAKxK,EAAUhO,GAAK,GAAO,IAEpCwb,YAAa,SAAUxb,GACrB,OAAOwY,EAAKxK,EAAUhO,GAAK,GAAO,IAEpCyb,aAAc,SAAUzb,GACtB,OAAOuY,EAAQvK,EAAUhO,GAAK,IAEhC0b,UAAW,SAAU1b,GACnB,OAAOwY,EAAKxK,EAAUhO,GAAK,GAAM,IAEnC2b,YAAa,SAAU3b,GACrB,OAAOwY,EAAKxK,EAAUhO,GAAK,GAAM,IAEnC2Y,WAAY,SAAU3Y,GACpB,OAAO2Y,EAAW3K,EAAUhO,IAE9B4b,cAAe,SAAU5b,EAAKmR,GAC5B,OAAOqI,EAAWxL,EAAUhO,EAAKmR,IAEnCt/B,KAAM,SAAU+7B,GACdG,EAAYC,EAAUJ,IAExB7xC,KAAM,SAAU6xC,GACduB,EAASnB,EAAUJ,IAErB+B,KAAM,SAAU/B,GACdyB,EAASrB,EAAUJ,IAErBoH,cAAepH,EAAUoH,cACzB1D,SAAU1D,EAAU0D,SACpBnE,WAAYS,EAAUT,WACtBJ,YAAaa,EAAUb,YACvBK,SAAUQ,EAAUR,SACpBpP,UAAW4P,EAAU5P,UACrB8V,YAAa,SAAUlG,GACrBkF,EAAc9E,GAAU,EAAMJ,IAEhC8F,aAAc,SAAU9F,GACtBkF,EAAc9E,GAAU,EAAOJ,IAEjCiO,iBAAkB,SAAUjO,GAC1BmG,EAAkB/F,EAAUJ,IAE9BoG,cAAe,SAAUpG,GACvBoG,EAAchG,EAAUJ,IAE1BmK,eAAgB,WACd,OAAOA,EAAe/J,IAExBiK,gBAAiB,WACf,OAAOA,EAAgBjK,IAEzB4J,aAAchK,EAAUgK,aACxBxF,cAAexE,EAAUwE,cACzBlD,OAAQtB,EAAUsB,OAClBH,WAAYnB,EAAUmB,WACtB8K,UAAWjM,EAAUiM,UACrB5M,WAAYW,EAAUX,WACtBD,OAAQ,SAAUtM,GAChByP,GAAcnC,GAA0B,IAAhBtN,IAE1BwM,OAAQ,SAAUU,GAChBqC,EAAcjC,EAAUJ,KAG5BtC,EAAc0C,GAAYzB,EAC1BqB,EAAUhE,QAAQ2C,IAEpBluC,MAAO,SAAU4tC,EAAYC,GAC3B1D,EAAMnqC,MAAM4tC,EAAa,IAAKC,GACV,KAAhBA,EAAoB0B,EAAUvvC,MAAM4tC,EAAa,yBAChD2B,EAAUvvC,MAAM4tC,EAAa,KAAOC,MA/1B7C4P,CAAalO,EACf,CA4gFF,QAloGApF,EAAMuT,uBAAyB,SAAUC,GACvC,IAAI9d,EAAK8d,GAAQA,EAAK71C,OAAUA,MAC5B8Y,EAAK+8B,GAAQA,EAAKr2C,SAAYA,QAC9Bs2C,EAAaD,GAAQA,EAAKlhC,WAAcA,UAE5C,MAAO,CACL+yB,aAAc,SAAUxyC,EAAQ6gD,GAC9B,OAAO,IAAID,EAAU5gD,EAAQ6gD,IAE/Bt9C,UAAYo9C,GAAQA,EAAKp9C,WAAcoqC,EACvCnqC,QAAS,SAAUs9C,GACjB,OAAOp9C,MAAMF,QAAQs9C,IAEvBtG,cAAgBmG,GAAQA,EAAKtjD,SAAYA,EACzCozC,YAAa,SAAUvpC,EAAKvF,GAC1B,IAAIo/C,EAAe,CACjBj5C,OAAQnG,EAAQ+uC,KAChBlrC,QAAS,CACPw7C,OAAQ,qCAEV1zB,MAAO,YAEY,SAAjB3rB,EAAQ+uC,OACVqQ,EAAav7C,QAAQ,gBAAkB,yBAEF,IAA5B7D,EAAQwtC,kBACjB4R,EAAa76B,aACiB,IAA5BvkB,EAAQwtC,gBAA2B,UAAYxtC,EAAQwtC,gBAAkBxtC,EAAQwtC,gBAAkB,QAEnGxtC,EAAQ2D,OACVy7C,EAAaz7C,KAAO1I,KAAK8I,UAAU/D,EAAQ2D,OAG7C,IAAI27C,EAAWpe,EAAE37B,EAAK65C,GAAcz1C,MAAM,SAAUtI,GAClD,OAAO4gB,EAAEpZ,OAAO,CACdiD,QAAS,gDACTzK,MAAOA,GAEX,GAOA,GAAIrB,EAAQN,QAAS,CACnB,IAAIA,EAAU,IAAIuiB,EAAE,SAAUrZ,EAASC,GACrC,IAAI02C,EAAUzsC,WAAW,WAEvB,OADAI,aAAaqsC,GACN12C,EAAO,CACZiD,QAAS,oBACTpM,QAASM,EAAQN,SAErB,EAAGM,EAAQN,QACb,GACA4/C,EAAWr9B,EAAEjP,KAAK,CAACssC,EAAU5/C,IAkC/B,OA/BA4/C,EACGl2C,KAAK,SAAU3D,GACd,OAAIA,EAAS+D,UACAxJ,EAAQ4sC,gBAAmBpB,EAAMqB,KACnCpnC,EAAStB,OAAOiF,KACrB,SAAUo2C,GACR,IACEx/C,EAAQ4sC,QAAQ4S,GAChB,MAAOn+C,GACPmqC,EAAMnqC,MAAM,+CAAgDA,KAGhE,SAAUA,GACR,OAAO4gB,EAAEpZ,OAAO,CACdiD,QAAS,gCACTzK,MAAOA,EACPoE,SAAUA,GAEd,QAfJ,EAmBOwc,EAAEpZ,OAAO,CAAEiD,QAAS,kBAAmBrG,SAAUA,GAE5D,GACCkE,MAAM,SAAUtI,UACJrB,EAAQqB,cAAiBmqC,EAAMqB,MACxC7sC,EAAQqB,MAAMA,EAAMyK,SAAW,uBAAwBzK,EAE3D,GAEKi+C,GAGb,EAEA9T,EAAMiU,mBAAqB,SAAUT,GACnC,IAAIU,EAAMV,GAAQA,EAAKW,QAAWA,OAC9BV,EAAaD,GAAQA,EAAKlhC,WAAcA,UAC5C,MAAO,CACL+yB,aAAc,SAAUxyC,EAAQ6gD,GAC9B,OAAO,IAAID,EAAU5gD,EAAQ6gD,IAE/Br9C,QAAS,SAAUs9C,GACjB,OAAOO,EAAG79C,QAAQs9C,IAEpBv9C,UAAYo9C,GAAQA,EAAKp9C,WAAcoqC,EACvC6M,cAAgBmG,GAAQA,EAAKtjD,SAAYA,EACzCozC,YAAa,SAAUvpC,EAAKvF,GAC1B,IAAI4/C,OACsB,IAAjB5/C,EAAQ2D,KACX,CACAsC,YAAa,mBACblH,KAAM9D,KAAK8I,UAAU/D,EAAQ2D,OAE7B,CAAA,EACF4gB,OACiC,IAA5BvkB,EAAQwtC,gBACX,CAAEqS,UAAW,CAAErS,gBAAiBxtC,EAAQwtC,kBACxC,CAAA,EAEN,OAAOkS,EAAGh3C,KACRg3C,EAAGI,OAAOF,EAASr7B,EAAa,CAC9Bhf,IAAKA,EACLlG,KAAMW,EAAQ+uC,KACdpjB,OAAO,EACPriB,SAAU,OACViC,MAAOvL,EAAQuL,MACf7L,QAASM,EAAQN,QACjBktC,QAAS,SAAUz/B,UACNnN,EAAQ4sC,gBAAmBpB,EAAMqB,MAC1C7sC,EAAQ4sC,QAAQz/B,IAGpB9L,MAAO,SAAU0+C,EAAK91C,EAAQ9I,UACjBnB,EAAQqB,cAAiBmqC,EAAMqB,MACxC7sC,EAAQqB,MAAM4I,EAAQ9I,QAOpC,EAGAqqC,EAAM0K,cAAgB,SAAUD,GAC9B,IAAIzC,EAAS,GACb,GAAKyC,EAIE,CACL,IACGA,EAAM+J,YACS,IAAhB/J,EAAMqB,aACkB,IAAhBrB,EAAMqB,OACZrB,EAAMqB,OACNrB,EAAMgK,WACNhK,EAAMiK,WACNjK,EAAMkK,UACNlK,EAAMmK,cACNnK,EAAMoK,aACR,CAEA,IAAI5N,EAAQ,CAAEpzC,KAAM,SAChB42C,EAAMoK,YACR5N,EAAMziC,QAAS,GAEXimC,EAAMkK,SAAU1N,EAAM31B,KAAM,EACvBm5B,EAAMmK,eAAc3N,EAAMpuC,SAAU,IAErB,IAApB4xC,EAAMgK,YAAqBxN,EAAM2E,QAAUnB,EAAMqB,QAAS,IAEtC,IAApBrB,EAAMiK,YAAqBzN,EAAM+F,MAAO,KAG1C/F,EAAMziC,QAAUyiC,EAAM2E,SAAW3E,EAAM+F,OAAMhF,EAAOrwC,KAAKsvC,GAE/D,IACGwD,EAAMqK,YACS,IAAhBrK,EAAMsB,aACkB,IAAhBtB,EAAMsB,OACZtB,EAAMsB,OACNtB,EAAMsK,WACNtK,EAAMuK,WACNvK,EAAMwK,UACNxK,EAAMyK,cACNzK,EAAM0K,aACR,CAEA,IAAIlO,EAAQ,CAAEpzC,KAAM,SAChB42C,EAAM0K,YACRlO,EAAMziC,QAAS,GAEXimC,EAAMwK,SAAUhO,EAAM31B,KAAM,EACvBm5B,EAAMyK,eAAcjO,EAAMpuC,SAAU,IAErB,IAApB4xC,EAAMsK,YACR9N,EAAM2E,QAAUnB,EAAMsB,QAAS,EAC3B,CAAC,SAAU,SAAU,WAAW38B,SAAS63B,EAAM2E,WAEjD3E,EAAMpzC,KAAO,SACbozC,EAAM2E,QAAU,CAAEG,MAAO,IAErBtB,EAAM2K,uBAAsBnO,EAAM2E,QAAQyJ,UAAY5K,EAAM2K,sBAC5D3K,EAAM6K,oBAAmBrO,EAAM2E,QAAQ2J,OAAS9K,EAAM6K,mBACtD7K,EAAM+K,mBAAkBvO,EAAM2E,QAAQ6J,MAAQhL,EAAM+K,qBAIpC,IAApB/K,EAAMuK,YAAqB/N,EAAM+F,MAAO,KAG1C/F,EAAMziC,QAAUyiC,EAAM2E,SAAW3E,EAAM+F,OAAMhF,EAAOrwC,KAAKsvC,GAE3DwD,EAAMl3C,MAERy0C,EAAOrwC,KAAK,CAAE9D,KAAM,cApEtBm0C,EAAOrwC,KAAK,CAAE9D,KAAM,QAAS+3C,SAAS,EAAMoB,MAAM,IAClDhF,EAAOrwC,KAAK,CAAE9D,KAAM,QAAS+3C,SAAS,EAAMoB,MAAM,IAuEpD,OAAOhF,CACT,EAGAhI,EAAM0M,iBAAmB,SAAUzF,GACjC,IAAIwF,EAAc,CAAA,EAClB,IAAKxF,IAAUA,EAAM2E,QAAS,OAAOa,EACrC,GAAmB,UAAfxF,EAAMpzC,KAER44C,EAAYX,MAAQ7E,EAAM2E,aACrB,GAAmB,UAAf3E,EAAMpzC,KAGf,IADKozC,EAAM0D,WAAa1D,EAAM4D,OAA0B,IAAlB5D,EAAM2E,UAAkB3E,EAAM2E,QAAU,UACxD,IAAlB3E,EAAM2E,SAA6C,iBAAlB3E,EAAM2E,QAEzCa,EAAYV,MAAQ9E,EAAM2E,YACrB,CACL,IAAI6J,EAAQ,EACRF,EAAS,EACS,WAAlBtO,EAAM2E,SAER6J,EAAQ,IACRF,EAAS,KACkB,gBAAlBtO,EAAM2E,SAEf6J,EAAQ,IACRF,EAAS,KACkB,UAAlBtO,EAAM2E,SAAyC,eAAlB3E,EAAM2E,SAA8C,UAAlB3E,EAAM2E,SAE9E6J,EAAQ,KACRF,EAAS,KACkB,WAAlBtO,EAAM2E,SAEf6J,EAAQ,KACRF,EAAS,MACkB,UAAlBtO,EAAM2E,SAEf6J,EAAQ,KACRF,EAAS,MACkB,WAAlBtO,EAAM2E,SAEf6J,EAAQ,IACRF,EAAS,KACkB,gBAAlBtO,EAAM2E,SAEf6J,EAAQ,IACRF,EAAS,MAETvV,EAAMpoC,IAAI,uCACV69C,EAAQ,IACRF,EAAS,KAEX9I,EAAYV,MAAQ,CAClB0J,MAAO,CAAEC,MAAOD,GAChBF,OAAQ,CAAEG,MAAOH,QAGG,WAAftO,EAAMpzC,OAEf44C,EAAYV,MAAQ9E,EAAM2E,SAE5B,OAAOa,CACT,EAEAzM,EAAMqB,KAAO,WAAA,EAEbrB,EAAM4G,qBAAuB,mBAI7B5G,EAAMqE,gBAAkB,KAGxBrE,EAAMoR,cAAgB,SAAU/E,GAC9B,IAEE,IAAIrE,EAASqE,EAAOsJ,YACpB,IAAK,IAAIC,KAAO5N,EACdhI,EAAMpoC,IAAIg+C,GACNA,IAAwB,IAAjBA,EAAI3G,UACb2G,EAAIxlC,OAGR,MAAO0O,IAGX,EAGAkhB,EAAMe,KAAO,SAAUvsC,GAGrB,IAFAA,EAAUA,GAAW,CAAA,GACbosC,SAAsC,mBAApBpsC,EAAQosC,SAAyBpsC,EAAQosC,SAAWZ,EAAMqB,KAChFrB,EAAMuB,SAER/sC,EAAQosC,eACH,CAWL,QAV0B,IAAfhrC,QAAQgC,MACjBhC,QAAQgC,IAAM,WAAA,GAGhBooC,EAAM1f,MAAQ0f,EAAMqB,KACpBrB,EAAMltC,MAAQktC,EAAMqB,KACpBrB,EAAM+E,OAAS/E,EAAMqB,KACrBrB,EAAMpoC,IAAMooC,EAAMqB,KAClBrB,EAAMmD,KAAOnD,EAAMqB,KACnBrB,EAAMnqC,MAAQmqC,EAAMqB,MACE,IAAlB7sC,EAAQ1B,OAAoC,QAAlB0B,EAAQ1B,MAEpCktC,EAAM1f,MAAQ1qB,QAAQ0qB,MAAMrY,KAAKrS,SACjCoqC,EAAMltC,MAAQ8C,QAAQ9C,MAAMmV,KAAKrS,SACjCoqC,EAAM+E,OAASnvC,QAAQ9C,MAAMmV,KAAKrS,SAClCoqC,EAAMpoC,IAAMhC,QAAQgC,IAAIqQ,KAAKrS,SAC7BoqC,EAAMmD,KAAOvtC,QAAQutC,KAAKl7B,KAAKrS,SAC/BoqC,EAAMnqC,MAAQD,QAAQC,MAAMoS,KAAKrS,cAC5B,GAAIW,MAAMF,QAAQ7B,EAAQ1B,OAC/B,IAAK,IAAI2hC,KAAKjgC,EAAQ1B,MACpB,OAAQ2hC,GACN,IAAK,QACHuL,EAAM1f,MAAQ1qB,QAAQ0qB,MAAMrY,KAAKrS,SACjC,MACF,IAAK,QACHoqC,EAAMltC,MAAQ8C,QAAQ9C,MAAMmV,KAAKrS,SACjC,MACF,IAAK,SACHoqC,EAAM+E,OAASnvC,QAAQ9C,MAAMmV,KAAKrS,SAClC,MACF,IAAK,MACHoqC,EAAMpoC,IAAMhC,QAAQgC,IAAIqQ,KAAKrS,SAC7B,MACF,IAAK,OACHoqC,EAAMmD,KAAOvtC,QAAQutC,KAAKl7B,KAAKrS,SAC/B,MACF,IAAK,QACHoqC,EAAMnqC,MAAQD,QAAQC,MAAMoS,KAAKrS,SACjC,MACF,QACEA,QAAQC,MACN,6BAA+B4+B,EAAI,oEAM7CuL,EAAMpoC,IAAI,wBAEV,IAAIi+C,EAAmBrhD,EAAQshD,cAAgB9V,EAAMuT,yBA2ErD,GA1EAvT,EAAM3pC,QAAUw/C,EAAiBx/C,QACjC2pC,EAAMqN,cAAgBwI,EAAiBxI,cACvCrN,EAAMsD,YAAcuS,EAAiBvS,YACrCtD,EAAMqF,aAAewQ,EAAiBxQ,aACtCrF,EAAM5pC,UAAYy/C,EAAiBz/C,UACnC4pC,EAAM5pC,UAAU2qC,OAGhBf,EAAM+V,YAAc,SAAUnV,EAAUtrC,GACtCsrC,EAA8B,mBAAZA,EAAyBA,EAAWZ,EAAMqB,KACvD/rC,IAAQA,EAAS,CAAEw2C,OAAO,EAAMC,OAAO,IACxC/L,EAAMgW,0BACR5lD,EAAUC,aACPy8C,aAAax3C,GACbsI,KAAK,SAAUyuC,GACdj8C,EAAUC,aAAa4lD,mBAAmBr4C,KAAK,SAAUs4C,GACvDlW,EAAMltC,MAAMojD,GACZtV,EAASsV,GAETlW,EAAMoR,cAAc/E,EACtB,EACF,GACCluC,MAAM,SAAUxI,GACfqqC,EAAMnqC,MAAMF,GACZirC,EAAS,GACX,IAEFZ,EAAMmD,KAAK,sCACXvC,EAAS,IAEb,EA2CAZ,EAAMmW,WAAY,EACiC,WAA/CnW,EAAMqN,cAAcC,eAAeC,SAAwBvN,EAAMqN,cAAcC,eAAer8C,SAAW,IAE3G,GACEN,GACAA,EAAa09C,iBACb19C,EAAa09C,gBAAgB,UAC7B19C,EAAa09C,gBAAgB,SAASD,QACtCz9C,EAAa09C,gBAAgB,SAASD,OAAO32C,OAC7C,CACA,IAAK,IAAIy2C,KAASv9C,EAAa09C,gBAAgB,SAASD,OACtD,GAAIF,GAASA,EAAMC,UAA6C,cAAjCD,EAAMC,SAAStiC,cAA+B,CAC3Em0B,EAAMmW,WAAY,EAClB,MAGAnW,EAAMmW,UACRnW,EAAMpoC,IAAI,uCAEVooC,EAAMmD,KACJ,kLAIC,CAGL,IAAIiT,EAAS,IAAI3lD,EAAkB,IACnC2lD,EAAO9K,YAAY,CAAE+K,qBAAqB,IAAQz4C,KAAK,SAAU2sC,GAC/DvK,EAAMmW,WAAyC,IAA7B5L,EAAM9E,IAAIlrC,QAAQ,OAChCylC,EAAMmW,UACRnW,EAAMpoC,IAAI,uCAEVooC,EAAMmD,KACJ,8KAIJiT,EAAOxnC,QACPwnC,EAAS,IACX,GAGJpW,EAAMuB,UAAW,EACjB/sC,EAAQosC,WAEZ,EAGAZ,EAAMwB,kBAAoB,WACxB,QAAS/wC,CACX,EAEAuvC,EAAMgW,wBAA0B,WAC9B,OAAO5lD,EAAUC,cAAgBD,EAAUC,aAAay8C,YAC1D,EAGA9M,EAAMmF,aAAe,SAAU/pB,GAC7B,IAAIk7B,EAAU,iEACVnR,EAAe,GACnB,IAAK,IAAIzxB,EAAI,EAAGA,EAAI0H,EAAK1H,IAAK,CAC5B,IAAI6iC,EAAY1/C,KAAKC,MAAsBw/C,GAAhBz/C,KAAKE,UAChCouC,GAAgBmR,EAAQE,OAAOD,GAEjC,OAAOpR,CACT,EA2oFAF,GAAiBjF,eC9uGH,MAAOyW,GACZp8C,MACAxH,OACAC,MAEA4jD,gBAAsD,KACtDC,aAAuB,EACvBC,cAA+B,KAC/B19C,cAAwC,KACxC29C,YAAgE,CAAA,EAChEC,YAA4C,CAAA,EAC5CC,+BAAmF,CAAA,EACnFC,cAA+E,CAAA,EAC/EC,QAAwB,IAAI1xC,EAAAA,QAEnC,WAAAnR,CAAYiG,GACV,IAAK9E,GAAMouB,IAAI3zB,gBAAkBE,EAC/B,MAAM,IAAIoP,MACR,8GAQJ,GAJA7K,KAAK4F,MAAQA,EACb5F,KAAK5B,OAASyC,EAAO1C,WAAWC,OAChC4B,KAAK3B,MAAQwC,EAAO1C,WAAWE,OAAS7F,EAAeC,KAElDuH,KAAK5B,OACR,MAAM,IAAIyM,MAAM,mCACP7K,KAAK5B,OAAOuc,SAAS,UAC9B3a,KAAK5B,QAAU,SAEnB,CAEO,aAAAmN,EAAcohC,QACnBA,EAAU,OAAQvrC,MAClBA,EAAQ,OAAQyrC,UAChBA,EAAY,OAAQ4V,uBACpBA,EAAyB,SAEzBC,GAAYpW,KAAK,CACfjuC,MAAO2B,KAAK3B,MACZ8tC,SAAU,KACHuW,GAAY3V,oBAKjB/sC,KAAK2iD,OAAS,IAAID,GAAY,CAC5BtkD,OAAQ4B,KAAK5B,OACbL,WAAY8C,EAAOpD,UAAUM,WAC7B6H,MAAO5F,KAAK4F,MACZ+mC,QAAS,IAAM7rC,GAAMC,iBAAiB4rC,EAAvB7rC,GACfM,MAAQF,GAAiBJ,GAAMC,iBAAiBK,EAAvBN,CAA8BI,GACvD2rC,UAAW,IAAM/rC,GAAMC,iBAAiB8rC,EAAvB/rC,GACjB2hD,uBAAwB,IAAM3hD,GAAMC,iBAAiB0hD,EAAvB3hD,KAX9BA,GAAMC,iBAAiBK,EAAvBN,CAA8B,gFAetC,CAEO,YAAAg8C,GACL,OAAO98C,KAAK2iD,QAAQ7F,kBAAoB,IAC1C,CAEO,cAAArxC,EAAekhC,QAAEA,EAAU,OAAQvrC,MAAEA,EAAQ,SAClDpB,KAAK2iD,QAAQ3F,UAAU,CACrBrQ,QAAS,IAAM7rC,GAAMC,iBAAiB4rC,EAAvB7rC,GACfM,MAAQF,GAAiBJ,GAAMC,iBAAiBK,EAAvBN,CAA8BI,IAE3D,CAEO,6BAAA0hD,CACLC,EACA59C,EACA69C,EACAnS,GAEA,IAAIoS,EAAsC,KAE1C,MAAMC,EAAcrS,EAAUqS,mBACvBrS,EAAUqS,YAEjB,MAAMC,EAActS,EAAUsS,mBACvBtS,EAAUsS,YAEjBjjD,KAAK2iD,QAAQnF,SAAS,CACpBE,OAAQ,yBACR/Q,QAAU2C,IACR,GAAIuT,EAAU,CACZE,EAAazT,EACbyT,EAAW99C,OAASA,EACpBjF,KAAKsiD,+BAA+Br9C,GAAU89C,EAE9C,MAAMG,EAAS,CACbljC,QAAS,OACTmjC,KAAMnjD,KAAKmiD,cACXiB,MAAO,WACPC,KAAMp+C,EACNq+C,QAASL,GAGXF,GAAYnuC,KAAK,CAAE/I,QAASq3C,GAC9B,MACEljD,KAAKiiD,gBAAkB3S,EAGzBxuC,GAAMC,iBAAiB4vC,EAAUhE,QAAjC7rC,IAEFM,MAAQA,IACNN,GAAMC,iBAAiB4vC,EAAUvvC,MAAjCN,CAAwCM,IAE1C22C,cAAgB14C,IACdyB,GAAMC,iBAAiB4vC,EAAUoH,cAAjCj3C,CAAgDzB,IAElD6wC,WAAY,CAAChC,EAAiB7uC,KAC5ByB,GAAMC,iBAAiB4vC,EAAUT,WAAjCpvC,CAA6CotC,EAAQ7uC,IAEvDywC,YAAczwC,IACZyB,GAAMC,iBAAiB4vC,EAAUb,YAAjChvC,CAA8CzB,IAEhD8wC,SAAU,CAACoT,EAAiBC,KAC1B1iD,GAAMC,iBAAiB4vC,EAAUR,SAAjCrvC,CAA2CyiD,EAAQC,IAErDnP,SAAWC,IACTxzC,GAAMC,iBAAiB4vC,EAAU0D,SAAjCvzC,CAA2CwzC,IAE7CvT,UAAW,CAAC9Y,EAAkBooB,KAC5B,MAAMx8B,EAAQoU,GAAiB,UAE/B,GAAI46B,EAAU,CACZ,GAAIhvC,EAEF,GAAc,aAAVA,EAAsB,CACxB,MAAM4vC,EAASx7B,EAAQ,GACvBjoB,KAAKoiD,YAAYqB,GAAUzjD,KAAKsiD,+BAA+BmB,GAC/DzjD,KAAKsiD,+BAA+BmB,GAAU,IAChD,MAAWx7B,EAAW,OACpBnnB,GAAMC,iBAAiB4vC,EAAUvvC,MAAjCN,CAAwCmnB,EAAW,OAIvD,GAAIooB,EAAM,CACR,MAAMoT,EAASx7B,EAAQ,GAMvBjoB,KAAKqiD,YAAYoB,GAAUpT,EAE3B,MAAM0S,EAAa/iD,KAAKoiD,YAAYqB,GAEpC,IAAKV,EAAY,OAEjB/iD,KAAKy2C,aACH,CACEsM,aACA1S,QAEF2S,EACA,CACErW,QAAS,OACTvrC,MAAQA,IACNN,GAAMC,iBAAiB4vC,EAAUvvC,MAAjCN,CAAwCM,KAIhD,CAGF,KAAO,CACL,GAAIyS,EAEF,GAAc,WAAVA,EAAoB,CACtB,MAEM6vC,EAAc,CAAE1N,MAFR8M,EAAY,CAAEzL,OAAO,EAAOC,OAAO,GAAU,CAAED,OAAO,EAAMC,OAAO,GAEpDM,OADPkL,OAAYpnD,EAAYsnD,GAE9ChjD,KAAK62C,YAAY6M,EAAa,CAC5B/W,QAAS,KACP,GAAI1kB,EAAgB,WAAG,CACrB,MAAM07B,EAAa17B,EAAgB,WACnC,IAAK,MAAMgZ,KAAK0iB,EAAY,CAC1B,MAAM1+C,EAAS0+C,EAAW1iB,GAAO,GAC3B2iB,EAAkBD,EAAW1iB,GAAY,QAC/CjhC,KAAKwiD,QAAQ7wC,KAAKxY,EAAWC,mBAAoB6L,EAAQ2+C,GAAiB,EAC5E,CACF,GAEFxiD,MAAQA,IACNN,GAAMC,iBAAiB4vC,EAAUvvC,MAAjCN,CAAwCM,KAK9C,MAAO,GAAc,UAAVyS,EAET,GAAIoU,EAAgB,WAAG,CACrB,MAAM07B,EAAa17B,EAAgB,WAEnC,IAAK,MAAMgZ,KAAK0iB,EAAY,CAC1B,MAAM1+C,EAAS0+C,EAAW1iB,GAAO,GAC3B2iB,EAAkBD,EAAW1iB,GAAY,QAE/CjhC,KAAKwiD,QAAQ7wC,KAAKxY,EAAWC,mBAAoB6L,EAAQ2+C,GAAiB,EAC5E,CAGF,MAAO,GAAI37B,EAAa,QAAG,CAEzB,MAAMw7B,EAASx7B,EAAa,QACZjoB,KAAK6jD,iBAAiBJ,IAEpCzjD,KAAKwiD,QAAQ7wC,KAAKxY,EAAWE,iBAAkBoqD,EAAQ,KAE3D,MAAO,GAAIx7B,EAAiB,YAAG,CAE7B,MAAMw7B,EAASx7B,EAAiB,YAChC,GAAe,OAAXw7B,EAAiB,CACHzjD,KAAK6jD,iBAAiBptC,OAAOgtC,KAE3CzjD,KAAKwiD,QAAQ7wC,KAAKxY,EAAWE,iBAAkBoqD,EAAQ,KAE3D,CACF,MAAWx7B,EAAW,QACpBnnB,GAAMgC,KAAK,wBAAyBmlB,EAAW,OAI/CjoB,KAAKwiD,QAAQ7wC,KAAKxY,EAAWjC,MAAO+wB,GACpCnnB,GAAMC,iBAAiB4vC,EAAUvvC,MAAjCN,CAAwCmnB,EAAW,QAKrDooB,GACFrwC,KAAKiiD,iBAAiBrD,mBAAmB,CAAEvO,KAAMA,GASrD,GAEFsK,aAAc,CAACnI,EAAyBnzC,KACtCyB,GAAMgC,KAAK,iBAAkB0vC,EAAOnzC,GACpCW,KAAK8jD,aAAatR,EAAOnzC,IAE3B81C,cAAe,CAAC3C,EAAyBzP,EAAc1jC,EAAa0kD,KAClEjjD,GAAMgC,KAAK,kBAAmB0vC,EAAOzP,EAAK1jC,EAAI0kD,GAC9C/jD,KAAKgkD,cACHjB,EACAvQ,EACe,iBAARzP,EAAmBA,EAAMl7B,OAAOk7B,GACvC1jC,EACA0kD,IAGJjS,WAAamS,IACXnjD,GAAMgC,KAAK,eAAgBmhD,GAC3BjkD,KAAKwiD,QAAQ7wC,KAAKxY,EAAWK,kBAAmByqD,IAElDhS,OAAQ,CAACnzC,EAAemlD,KACtBnjD,GAAMgC,KAAK,WAAYmhD,EAAcnlD,GACrCkB,KAAKwiD,QAAQ7wC,KAAKxY,EAAWM,qBAAsBwqD,EAAcnlD,IAEnE89C,UAAW,KACT97C,GAAMC,iBAAiB4vC,EAAUiM,UAAjC97C,IAEFqyC,SAAU,QAEd,CAEO,YAAA2Q,CAAapO,EAA0BwO,GAE9C,CAEO,aAAAF,CACLjB,EACAvQ,EACAzP,EACAmhB,EACAH,GAEA,MAAMI,EAAYJ,GAAYA,EAAS3vC,OACvC,GAAI+vC,IAAcxqD,EAAsBC,QAAS,CAC/C,MAAMwqD,GAA2BrB,EAAWnL,SAAWmL,EAAWxP,OAC9D6Q,GACFrB,EAAWxP,OAAS,CAAExQ,CAACA,GAAMyP,GAC7BuQ,EAAWnL,OAAS,IAAI/7C,EAAa,CAAC22C,MAElCuQ,EAAWxP,SAAQwP,EAAWxP,OAAOxQ,GAAOyP,GAChDuQ,EAAWnL,QAAQe,SAASnG,IAE1B4R,GACFpkD,KAAKwiD,QAAQ7wC,KAAKxY,EAAW7C,cAAeysD,EAAW99C,OAAQ89C,EAAWnL,OAE9E,MAAO,GAAIuM,IAAcxqD,EAAsBE,MAAO,CAChDkpD,EAAWxP,eAAewP,EAAWxP,OAAOxQ,GAChD,MAAMshB,EAAatB,EAAWnL,OAC9B,IAAKyM,EAAY,OACjB,MAAMC,EAAgBD,EACnBnD,YACAlkC,KAAMunC,GAAkCA,EAAY9R,OAASD,EAAMC,MAClE6R,GAAeD,EAAW3J,YAAY4J,EAC5C,CACAtkD,KAAKwiD,QAAQ7wC,KAAKxY,EAAWI,sBAAuBwpD,EAAW99C,OAAQutC,EAAO2R,EAChF,CAEO,WAAAK,GACL,MAAM74C,EAAK3L,KAAKiiD,iBAAiBhE,UACjC,OAAa,MAANtyC,EAAa9D,OAAO8D,GAAM,IACnC,CAEO,6BAAA84C,CAA8B9T,GACnC,MAAM32B,EAAQ,KACZha,KAAKiiD,gBAAkB,KAGvB9hD,OAAOC,KAAKJ,KAAKoiD,aAAa/hD,QAAS4E,IACrCjF,KAAK6jD,iBAAiBptC,OAAOxR,MAG/BjF,KAAKoiD,YAAc,CAAA,EACnBpiD,KAAKqiD,YAAc,CAAA,GAOrBriD,KAAKiiD,iBAAiBhS,SAAS,CAC7BtD,QAAS,KACP3yB,IAEAlZ,GAAMC,iBAAiB4vC,EAAUhE,QAAjC7rC,IAEFM,MAAQA,IACN4Y,IAEAlZ,GAAMC,iBAAiB4vC,EAAUvvC,MAAjCN,CAAwCM,KAG9C,CAEO,IAAAwG,CAAK88C,EAAgBz/C,EAAgBi9C,EAAsBvR,GAChE,MAAMsS,EAActS,EAAUsS,mBACvBtS,EAAUsS,YAEjBjjD,KAAKkiD,YAAcA,EAEnBphD,GAAMgC,KAAK,gBAAkB9C,KAAKkiD,aAElC,MAAMyC,EAAY,CAChB3kC,QAAS,OACTmjC,KAAMuB,EACNtB,MAAO,YACPz3C,GAAI1G,EACJq+C,QAASL,GAGXjjD,KAAKiiD,iBAAiBrtC,OAAO,CAC3B/I,QAAS84C,EACThY,QAAUiY,IACR5kD,KAAKmiD,cAAgBuC,EACrB1kD,KAAKyE,cAAgBQ,EACrBnE,GAAMC,iBAAiB4vC,EAAUhE,QAAjC7rC,IAEFM,MAAQA,IACNN,GAAMC,iBAAiB4vC,EAAUvvC,MAAjCN,CAAwCM,KAG9C,CAEO,KAAAq1B,CAAMka,GAGX,GAFA7vC,GAAMgC,KAAK,UAEN9C,KAAK2iD,QAAQnpB,gBAEhB,YADA14B,GAAMC,iBAAiB4vC,EAAUhE,QAAjC7rC,GAIF,MAAM+jD,EAAa,CACjB7kC,QAAS,QACTmjC,KAAMnjD,KAAKmiD,cACXx2C,GAAI3L,KAAKyE,eAGPzE,KAAKiiD,iBACPjiD,KAAKiiD,iBAAiBrtC,OAAO,CAAE/I,QAASg5C,IAE1C7kD,KAAKmiD,cAAgB,KACrBniD,KAAKyE,cAAgB,KAErB3D,GAAMC,iBAAiB4vC,EAAUhE,QAAjC7rC,EACF,CAEO,sBAAAgkD,CAAuBJ,EAAgB/T,GAC5C,MAAMoU,EAAc,CAAE/kC,QAAS,mBAAoBmjC,KAAMuB,GAEzD1kD,KAAKiiD,iBAAiBrtC,OAAO,CAC3B/I,QAASk5C,EACTpY,QAAU7tC,IACR,MAAMkoC,EAAeloC,GAAMkoC,cAAgB,GAC3ClmC,GAAMC,iBAAiB4vC,EAAUhE,QAAjC7rC,CAA0CkmC,IAE5C5lC,MAAQA,IACNN,GAAMC,iBAAiB4vC,EAAUvvC,MAAjCN,CAAwCM,KAG9C,CAEO,eAAA4jD,GACL,MAAMC,EAAQjlD,KAAKiiD,iBAAiB5D,iBAMpC,OALI4G,EACFjlD,KAAKiiD,iBAAiB1D,gBAEtBv+C,KAAKiiD,iBAAiB3D,cAEjBt+C,KAAKiiD,iBAAiB5D,mBAAoB,CACnD,CAEO,YAAAA,GACL,IACE,OAAOr+C,KAAKiiD,iBAAiB5D,mBAAoB,CACnD,CAAE,MAAOh0B,GACP,MAAM,IAAIxf,MAAM,0EAClB,CACF,CAEO,qBAAAq6C,CAAsBjgD,GAC3B,MAAM89C,EAAa/iD,KAAKoiD,YAAYn9C,GACpC,IAAK89C,EACH,OAAO,EAGT,MAAMoC,EAAcpC,EAAWnL,QAAQC,mBACvC,GAAIsN,GAAeA,EAAYniD,OAAS,EAAG,CACzC,IAAK,IAAIic,EAAI,EAAGA,EAAIkmC,EAAYniD,SAAUic,EACxCkmC,EAAYlmC,GAAG+S,SAAWmzB,EAAYlmC,GAAG+S,QAE3C,OAAQmzB,EAAY,GAAGnzB,OACzB,CAEA,OAAO,CACT,CAEO,kBAAAozB,CAAmBngD,GACxB,MAAM89C,EAAa/iD,KAAKoiD,YAAYn9C,GACpC,IAAK89C,EACH,OAAO,EAGT,MAAMoC,EAAcpC,EAAWnL,QAAQC,mBACvC,SAAIsN,GAAeA,EAAYniD,OAAS,KAC9BmiD,EAAY,GAAGnzB,OAI3B,CAEO,eAAAqzB,GACL,MAAMJ,EAAQjlD,KAAKiiD,iBAAiBzD,iBAMpC,OALIyG,EACFjlD,KAAKiiD,iBAAiBvD,gBAEtB1+C,KAAKiiD,iBAAiBxD,cAEjBz+C,KAAKiiD,iBAAiBzD,mBAAoB,CACnD,CAEO,YAAAA,GACL,IACE,OAAOx+C,KAAKiiD,iBAAiBzD,mBAAoB,CACnD,CAAE,MAAOn0B,GACP,MAAM,IAAIxf,MAAM,0EAClB,CACF,CAEO,qBAAAy6C,CAAsBrgD,GAC3B,MAAM89C,EAAa/iD,KAAKoiD,YAAYn9C,GACpC,IAAK89C,EACH,OAAO,EAGT,MAAMwC,EAAcxC,EAAWnL,QAAQE,mBACvC,GAAIyN,GAAeA,EAAYviD,OAAS,EAAG,CACzC,IAAK,IAAIic,EAAI,EAAGA,EAAIsmC,EAAYviD,SAAUic,EACxCsmC,EAAYtmC,GAAG+S,SAAWuzB,EAAYtmC,GAAG+S,QAE3C,OAAQuzB,EAAY,GAAGvzB,OACzB,CAEA,OAAO,CACT,CAEO,kBAAAwzB,CAAmBvgD,GACxB,MAAM89C,EAAa/iD,KAAKoiD,YAAYn9C,GACpC,IAAK89C,EACH,OAAO,EAGT,MAAMwC,EAAcxC,EAAWnL,QAAQE,mBACvC,SAAIyN,GAAeA,EAAYviD,OAAS,KAC9BuiD,EAAY,GAAGvzB,OAI3B,CAEO,mBAAAyzB,CAAoBf,EAAgB/T,GACzC,MAAM+U,EAAmB,CACvB1lC,QAAS,YACTmjC,KAAMuB,EACNiB,UAAU,GAGZ3lD,KAAKiiD,iBAAiBrtC,OAAO,CAC3B/I,QAAS65C,EACT/Y,QAAUnnC,IACR1E,GAAMC,iBAAiB4vC,EAAUhE,QAAjC7rC,CAA0C0E,IAE5CpE,MAAQA,IACNN,GAAMC,iBAAiB4vC,EAAUvvC,MAAjCN,CAAwCM,KAG9C,CAEO,mBAAAwkD,CAAoBhO,GACzB,MAAMrE,EAAuE,GAEvE4R,EAAcvN,EAAOC,iBAC3B,GAAIsN,EAAYniD,OAAQ,CACtB,MAAM6iD,EAAaV,EAAY,GAC/B5R,EAAOrwC,KAAK,CAAE9D,KAAM,QAAS+3C,QAAS0O,EAAYtN,MAAM,GAC1D,CAEA,MAAMgN,EAAc3N,EAAOE,iBAC3B,GAAIyN,EAAYviD,OAAQ,CACtB,MAAM8iD,EAAaP,EAAY,GAC/BhS,EAAOrwC,KAAK,CAAE9D,KAAM,QAAS+3C,QAAS2O,EAAYvN,MAAM,GAC1D,CAEA,OAAOhF,CACT,CAEO,WAAAsD,CACLkP,EACApV,GAEA7vC,GAAMgC,KAAK,8BAA+BijD,GAE1C,MAAQnO,OAAQoO,EAAahQ,MAAEA,EAAK5xC,QAAEA,GAAY2hD,EAE5CE,EAA6C,CAAE1S,OAAQ,CAAC,CAAEn0C,KAAM,UAEtE,GAAI4mD,EAAe,CACjB,MAAME,EAAmBlmD,KAAK4lD,oBAAoBI,GAClDC,EAAkB1S,OAAS0S,EAAkB1S,OAAOlrB,OAAO69B,EAC7D,MAAO,GAAIlQ,EAAO,CAChB,MAAMmQ,EAA0F,GAC5FnQ,EAAMqB,OACR8O,EAAiBjjD,KAAK,CACpB9D,KAAM,QACN+3C,QAASnB,EAAMqB,MACfkB,MAAM,EACNn0C,UAAWA,IAGX4xC,EAAMsB,OACR6O,EAAiBjjD,KAAK,CACpB9D,KAAM,QACN+3C,QAASnB,EAAMsB,MACfiB,MAAM,EACNn0C,UAAWA,IAGf6hD,EAAkB1S,OAAS0S,EAAkB1S,OAAOlrB,OAAO89B,EAC7D,MACEF,EAAkB1S,OAAS0S,EAAkB1S,OAAOlrB,OAAO,CACzD,CAAEjpB,KAAM,QAAS+3C,SAAS,EAAMoB,MAAM,EAAOn0C,UAAWA,GACxD,CAAEhF,KAAM,QAAS+3C,SAAS,EAAMoB,MAAM,EAAOn0C,UAAWA,KAI5DtD,GAAMgC,KAAK,sCAAuCmjD,GAElDA,EAAkBzP,aAAgB4P,MAElCH,EAAkBtZ,QAAW0D,IAC3B,MAAMgW,EAAU,CACdrmC,QAAS,YACTq3B,QAASrB,EAAMqB,MACfC,QAAStB,EAAMsB,OAEjBx2C,GAAMgC,KAAK,uCAAwCujD,GAEnDrmD,KAAKiiD,iBAAiBrtC,OAAO,CAAE/I,QAASw6C,EAAShW,KAAMA,IAEvDvvC,GAAMC,iBAAiB4vC,EAAUhE,QAAjC7rC,IAGFmlD,EAAkB7kD,MAASA,IACzBN,GAAMgC,KAAK,qCAAsC1B,GAC7C40C,EAAMqB,MACRr3C,KAAK62C,YAAY,CAAEb,MAAO,CAAEsB,OAAO,EAAOD,OAAO,IAAW1G,GAE5D7vC,GAAMC,iBAAiB4vC,EAAUvvC,MAAjCN,CAAwCM,IAI5CpB,KAAKiiD,iBAAiBpL,cAAcoP,EACtC,CAEO,uBAAAK,CAAwB1O,GAC7B,MAAMrE,EAAyD,GAEzD4R,EAAcvN,EAAOC,iBAC3B,GAAIsN,EAAYniD,OAAQ,CACtB,MAAM6iD,EAAaV,EAAY,GAC/B5R,EAAOrwC,KAAK,CAAE9D,KAAM,QAAS2jC,IAAK8iB,EAAWl6C,GAAI4sC,MAAM,GACzD,CAEA,MAAMgN,EAAc3N,EAAOE,iBAC3B,GAAIyN,EAAYviD,OAAQ,CACtB,MAAM8iD,EAAaP,EAAY,GAC/BhS,EAAOrwC,KAAK,CAAE9D,KAAM,QAAS2jC,IAAK+iB,EAAWn6C,GAAI4sC,MAAM,GACzD,CAEA,OAAOhF,CACT,CAEO,YAAAkD,EACLsM,WAAEA,EAAU1S,KAAEA,GACd2V,EACArV,GAEA7vC,GAAMgC,KAAK,+BAAgCutC,EAAM2V,GACjD,IAAIzS,EAAgE,CAAC,CAAEn0C,KAAM,SAE7E,GAAI4mD,EAAe,CACjB,MAAME,EAAmBlmD,KAAKsmD,wBAAwBN,GACtDzS,EAASA,EAAOlrB,OAAO69B,EACzB,CAEAplD,GAAMgC,KAAK,uCAAwCywC,GAEnDwP,EAAWtM,aAAa,CACtBpG,KAAMA,EACNkD,OAAQA,EACR5G,QAAU0D,IACR,MAAM3sC,EAAO,CAAEsc,QAAS,QAASmjC,KAAMnjD,KAAKmiD,eAC5CrhD,GAAMgC,KAAK,wCAAyCY,GAEpDq/C,EAAWnuC,KAAK,CAAE/I,QAASnI,EAAM2sC,KAAMA,IAEvCvvC,GAAMC,iBAAiB4vC,EAAUhE,QAAjC7rC,IAEFM,MAAQA,IACNN,GAAMgC,KAAK,sCAAuC1B,GAClDN,GAAMC,iBAAiB4vC,EAAUvvC,MAAjCN,CAAwCM,KAG9C,CAEO,gBAAAyiD,CAAiB5+C,GACtB,MAAM89C,EAAa/iD,KAAKoiD,YAAYn9C,GACpC,QAAI89C,IACFA,EAAW9S,SACXjwC,KAAKoiD,YAAYn9C,GAAU,KAC3BjF,KAAKqiD,YAAYp9C,GAAU,MACpB,EAGX,CAEO,cAAAshD,CAAethD,GACpB,MAAM89C,EAAa/iD,KAAKoiD,YAAYn9C,GACpC,OAAO89C,GAAYrH,cACrB,CAEO,SAAAT,CAAUuL,GACfxmD,KAAKiiD,iBAAiB7D,iBAAiB,KAAMoI,EAC/C,CAEO,aAAAC,CAAcxhD,EAAgBuhD,GACnC,MAAMzD,EAAa/iD,KAAKoiD,YAAYn9C,GACpC,OAAO89C,GAAY5E,kBAAkB,KAAMqI,EAC7C,CAEO,WAAAE,CAAYzhD,EAAgB0P,GACjC,MAAMouC,EAAa/iD,KAAKoiD,YAAYn9C,GAC9B0hD,EAAkBlrD,GAAuDo9C,eAE1E/3C,GAAMouB,IAAI3zB,eAA8C,WAA5BorD,GAAgB7N,SAAoD,YAA5B6N,GAAgB7N,UACvF94C,KAAKuiD,cAAct9C,GAAU82C,YAAY,KACvC,MAAM7H,EAAU6O,GAAYrH,eACb,MAAXxH,GAAiBv/B,EAAQrL,OAAO4qC,IACnC,KAEP,CAEO,WAAA0S,CAAY3hD,EAAgB0P,GAC7B3U,KAAKuiD,cAAct9C,IACrBw3C,cAAcz8C,KAAKuiD,cAAct9C,IAEnCjF,KAAKuiD,cAAct9C,GAAU,KAC7B0P,EAAQrL,KAAO,IACjB,CAEO,EAAAjK,CAAG8kD,EAAuB1vC,GAC/B,OAAOzU,KAAKwiD,QAAQjvC,YAAY4wC,EAAW1vC,EAC7C,CAEO,kBAAA4lB,CAAmB8pB,GACxB,OAAOnkD,KAAKwiD,QAAQnoB,mBAAmB8pB,EACzC,EChtBY,MAAO0C,GACXC,OACDn7C,GAAa,GAAGvJ,KAAKE,WACrBykD,uBACA/D,YACA+C,YAAsC,CAAA,EAY7C,WAAApmD,CAAYiG,GACV5F,KAAK8mD,OAAS,IAAI9E,GAAYp8C,GAC9B5F,KAAK8mD,OAAOznD,GAAGlG,EAAWC,mBAAoB4G,KAAKgnD,qBACnDhnD,KAAK8mD,OAAOznD,GAAGlG,EAAWE,iBAAkB2G,KAAKinD,mBACjDjnD,KAAK8mD,OAAOznD,GAAGlG,EAAW7C,cAAe0J,KAAKknD,gBAC9ClnD,KAAK8mD,OAAOznD,GAAGlG,EAAWI,sBAAuByG,KAAKmnD,uBACtDnnD,KAAK8mD,OAAOznD,GAAGlG,EAAWK,kBAAmBwG,KAAKonD,mBAClDpnD,KAAK8mD,OAAOznD,GAAGlG,EAAWM,qBAAsBuG,KAAKqnD,sBACrDrnD,KAAK8mD,OAAOznD,GAAGlG,EAAWjC,MAAO8I,KAAKmU,QACxC,CAEA,iBAAIguC,GACF,OAAOniD,KAAK8mD,OAAO3E,aACrB,CAEA,iBAAIA,CAAcuC,GAChB1kD,KAAK8mD,OAAO3E,cAAgBuC,CAC9B,CAEA,sBAAI4C,GACF,OAAOtnD,KAAK8mD,QAAQ7E,iBAAiB1S,aAAaC,IAAM,IAC1D,CAEQ,mBAAMjkC,GACZ,IAAIg8C,GAAa,EAEjB,OAAO,IAAI7+C,QAAQ,CAACC,EAASC,KAC3B5I,KAAK8mD,OAAOv7C,cAAc,CACxBohC,QAAS,KACP4a,GAAa,EACb5+C,OAAQ,IAEVvH,MAAQA,IACFmmD,EACFvnD,KAAKmU,QAAQ/S,GAEbwH,EAAOxH,OAKjB,CAGO,UAAMwG,CAAK88C,EAAgB5/C,EAAiB8+C,GACjD5jD,KAAK+mD,uBAAyBnD,EAC9B5jD,KAAKmiD,cAAgBuC,QACf1kD,KAAKuL,sBACLvL,KAAKwnD,cAAc1iD,GAAS,GAAO,SACnC9E,KAAKynD,aAAaznD,KAAKmiD,cAAer9C,EAC9C,CAEO,oBAAM4iD,CAAehD,EAAgB5/C,EAAiB8+C,GAC3D5jD,KAAK+mD,uBAAyBnD,EAC9B5jD,KAAKmiD,cAAgBuC,QACf1kD,KAAKuL,sBACLvL,KAAKwnD,cAAc1iD,GAAS,GAAO,SACnC9E,KAAKynD,aAAaznD,KAAKmiD,cAAer9C,EAC9C,CAEO,yBAAM2gD,CAAoBf,GAC/B,OAAO,IAAIh8C,QAAQ,CAACC,EAASC,KAC3B5I,KAAK8mD,OAAOrB,oBAAoBf,EAAQ,CACtC/X,QAAShkC,EACTvH,MAAOwH,KAGb,CAEQ,mBAAM4+C,CAAc1iD,EAAiB+9C,EAAmBC,GAAqB,GACnF,OAAO,IAAIp6C,QAAQ,CAACC,EAASC,KAC3B5I,KAAK8mD,OAAOlE,8BAA8BC,EAAU/9C,EAASg+C,EAAW,CACtEnW,QAAShkC,EACTvH,MAAOwH,EACPyrC,SAAUwO,EACLxO,GAAar0C,KAAK2nD,wBAAwB7iD,EAASuvC,GACnDA,GAAar0C,KAAK4nD,uBAAuBvT,GAC9ClE,SAAU0S,EACN,CAACU,EAAQC,IAAUxjD,KAAK6nD,WAAW/iD,EAASy+C,EAAQC,GACpD,CAACD,EAAQC,IAAUxjD,KAAK6nD,WAAW,KAAMtE,EAAQC,GACrDR,YAAahjD,KAAKgjD,YAClBC,YAAajjD,KAAK+mD,0BAGxB,CAEQ,kBAAMU,CAAa/C,EAAgB5/C,GACzC,OAAO,IAAI4D,QAAQ,CAACC,EAASC,KAC3B5I,KAAK8mD,OAAOl/C,KAAK88C,EAAQ5/C,GAAS,EAAO,CACvC6nC,QAAShkC,EACTvH,MAAOwH,EACPq6C,YAAajjD,KAAK+mD,0BAGxB,CAEQC,oBAAsB,CAACliD,EAAiB8+C,EAAyBkE,KACvEhnD,GAAMgC,KAAK,wBAAyBgC,EAAS8+C,EAAiBkE,GAC9D9nD,KAAKwnD,cAAc1iD,GAAS,GAAM,GAClChE,GAAMC,iBAAiBf,KAAK+nD,4BAA5BjnD,CAAyDd,KAAM8E,EAAS8+C,EAAiBkE,IAGnFb,kBAAoB,CAACniD,EAAiB8+C,KAC5C9iD,GAAMgC,KAAK,sBAAuBgC,EAAS8+C,GAC3C9iD,GAAMC,iBAAiBf,KAAKgoD,0BAA5BlnD,CAAuDd,KAAM8E,EAAS8+C,IAGhEzvC,QAAW/S,IACjBN,GAAMgC,KAAK,YAAa9H,KAAK8I,UAAU1C,IACvCN,GAAMC,iBAAiBf,KAAKioD,gBAA5BnnD,CAA6Cd,KAAMoB,IAG7CgmD,kBAAqB1V,IAC3B5wC,GAAMgC,KAAK,sBAAuB4uC,GAClC5wC,GAAMC,iBAAiBf,KAAKkoD,4BAA5BpnD,CAAyDd,KAAM0xC,IAGzD2V,qBAAuB,CAACviD,EAAiBhG,KAC/CgC,GAAMgC,KAAK,yBAA0BgC,EAAShG,GAC9CgC,GAAMC,iBAAiBf,KAAKmoD,6BAA5BrnD,CAA0Dd,KAAM8E,EAAShG,IAGnE8oD,uBAA0BvT,IAChCvzC,GAAMgC,KAAK,2BAA4BuxC,GACvCvzC,GAAMC,iBAAiBf,KAAKooD,wCAA5BtnD,CAAqEd,KAAMq0C,IAGrEsT,wBAA0B,CAAC7iD,EAAiBuvC,KAClDvzC,GAAMgC,KAAK,4BAA6BgC,EAASuvC,GACjDvzC,GAAMC,iBAAiBf,KAAKqoD,uCAA5BvnD,CAAoEd,KAAM8E,EAASuvC,IAG7E6S,eAAiB,CAACpiD,EAAiB8yC,KACzC92C,GAAMgC,KAAK,mBAAoBgC,EAAS8yC,GACxC92C,GAAMC,iBAAiBf,KAAKsoD,uBAA5BxnD,CAAoDd,KAAM8E,EAAS8yC,IAG7DuP,sBAAwB,CAACriD,EAAiB0tC,EAAyB2R,KACzErjD,GAAMgC,KAAK,0BAA2BgC,EAAS0tC,EAAO2R,GACtDrjD,GAAMC,iBAAiBf,KAAKuoD,8BAA5BznD,CAA2Dd,KAAM8E,EAAS0tC,EAAO2R,IAG3E0D,WAAa,CAAC/iD,EAAwBy+C,EAAiBC,KAC7D1iD,GAAMgC,KAAK,eAAgBgC,EAASy+C,EAAQC,GAC5C1iD,GAAMC,iBAAiBf,KAAKwoD,mBAA5B1nD,CAAgDd,KAAM8E,EAASy+C,EAAQC,IAGlE,8BAAMiF,GACX,OAAO,IAAI//C,QAAQ,CAACC,EAASC,KACvB5I,KAAKmiD,cACPniD,KAAK8mD,OAAOhC,uBAAuB9kD,KAAKmiD,cAAe,CACrDxV,QAAShkC,EACTvH,MAAOwH,IAGTA,EAAO,uBAGb,CAEO,WAAM6tB,GACXz2B,KAAKmiD,cAAgB,KACrBniD,KAAK+mD,4BAAyBrrD,QACxBsE,KAAK0oD,mBACL1oD,KAAKykD,sCACLzkD,KAAKg9C,UAEPh9C,KAAKgjD,cACPhjD,KAAKgjD,YAAY9B,YAAY7gD,QAASmyC,GAAUA,EAAM72B,QACtD3b,KAAKgjD,iBAActnD,EACnBsE,KAAK+lD,YAAc,CAAA,EAEvB,CAEO,gBAAM2C,GACX,OAAO,IAAIhgD,QAAQ,CAACC,EAASC,KAC3B5I,KAAK8mD,OAAOrwB,MAAM,CAChBkW,QAAShkC,EACTvH,MAAOwH,KAGb,CAEO,aAAMo0C,GACX,OAAO,IAAIt0C,QAAQ,CAACC,EAASC,KAC3B5I,KAAK8mD,OAAOr7C,eAAe,CACzBkhC,QAAShkC,EACTvH,MAAOwH,KAGb,CAEO,mCAAM67C,GACX,OAAO,IAAI/7C,QAAQ,CAACC,EAASC,KAC3B5I,KAAK8mD,OAAOrC,8BAA8B,CACxC9X,QAAShkC,EACTvH,MAAOwH,KAGb,CAEO,qBAAM+iC,CAAgBvmC,GAC3B,IAAKxJ,GAAc+vC,gBACjB,MAAM,IAAI9gC,MAAM,2DAGlB,MAAM89C,EAAYvjD,GAAUA,EAAOujD,UAC7B5oD,EAAUqF,GAAUA,EAAOrF,QAC3BgmD,EAAc,IAAK3gD,GAEzBpF,KAAK+lD,YAAcA,SACZA,EAAY4C,iBACZ5C,EAAYhmD,QAEnB,IACE,MAAM63C,QAAeh8C,EAAc+vC,gBAAgBoa,GACnD,OAAO/lD,KAAK4oD,aAAahR,EAAQ+Q,EAAW5oD,EAC9C,CAAE,MAAOqB,GACP,MAAMA,CACR,CACF,CAEO,kBAAMi3C,CAAajzC,GACxB,IAAKxJ,GAAcy8C,aACjB,MAAM,IAAIxtC,MAAM,wDAGlB,MAAM89C,EAAYvjD,GAAUA,EAAOujD,UAC7B5oD,EAAUqF,GAAUA,EAAOrF,QAC3BgmD,EAAc,IAAK3gD,GAEzBpF,KAAK+lD,YAAcA,SACZA,EAAY4C,iBACZ5C,EAAYhmD,QAEnB,IACE,MAAM63C,QAAeh8C,EAAcy8C,aAAa0N,GAChD,OAAO/lD,KAAK4oD,aAAahR,EAAQ+Q,EAAW5oD,EAC9C,CAAE,MAAOqB,GACP,MAAMA,CACR,CACF,CAEQ,YAAAwnD,CACNhR,EACA+Q,EAA2B,KAC3B5oD,EAAgC,CAAA,GAEhC,MAAM8oD,IAA8B7oD,KAAKgjD,YAQzC,GANI6F,EACF7oD,KAAK+2C,cAAca,GAEnB53C,KAAKgjD,YAAcpL,GAGhB53C,KAAKgjD,YACR,MAAM,IAAIn4C,MAAM,+BAuBlB,OApBI89C,IACEE,GACF7oD,KAAK8oD,kBAAkBH,EAAW5oD,GAEpCC,KAAK+oD,kBAAkBJ,EAAW3oD,KAAKgjD,YAAajjD,IAGtDC,KAAKgjD,YAAY9B,YAAY7gD,QAASmyC,IACpC,MAAMpzC,EAAOozC,EAAMC,KACbvO,EAAWsO,EAAMwW,cAAc9kB,SAEjCA,IACoC,iBAA3BlkC,KAAK+lD,YAAY3mD,GAC1BY,KAAK+lD,YAAY3mD,GAAM8kC,SAAWA,EAElClkC,KAAK+lD,YAAY3mD,GAAQ,CAAE8kC,eAK1BlkC,KAAKgjD,WACd,CAEQ,aAAAjM,CAAca,GA4BpB,GA3BA53C,KAAKgjD,aAAa9B,YAAY7gD,QAAS4oD,IACjCA,EAAWxW,OAAS/4C,EAAcxD,OAA4C,IAAnC0hD,EAAOC,iBAAiB70C,SAGrEimD,EAAWttC,OACX3b,KAAKgjD,aAAatI,YAAYuO,MAIlCrR,EAAOsJ,YAAY7gD,QAAS6oD,IAC1B,MAAMC,EAAYnpD,KAAKsnD,oBAAoB/U,eACrClD,EAAS8Z,GAAWnsC,KAAK,EAAGw1B,WAA0B0W,EAASzW,OAASD,GAAOC,MAEjFyW,EAASzW,OAAS/4C,EAAcxD,MAClCgzD,EAASl3B,QAAUhyB,KAAKgjD,aAAanL,iBAAiB3sB,MAAM,EAAG8G,aAAcA,KAAY,EAEzFk3B,EAASl3B,QAAUhyB,KAAKgjD,aAAalL,iBAAiB5sB,MAAM,EAAG8G,aAAcA,KAAY,EAGvFqd,GACFA,EAAOsI,aAAauR,GACpBlpD,KAAKgjD,aAAarK,SAASuQ,IAE3B/nD,QAAQutC,KAAK,mCAAmCwa,EAASzW,WAIxDzyC,KAAKgjD,YACR,MAAM,IAAIn4C,MAAM,+BAGlB,OAAO7K,KAAKgjD,WACd,CAEO,uBAAMoG,CAAkBrpD,GAC7B,CAACrG,EAAcxD,MAAOwD,EAAczD,OAAOoK,QAASjB,IAClD,MAAMiqD,EAASjqD,IAAS1F,EAAcxD,MAAQ6J,EAAQs3C,MAAQj4C,IAAS1F,EAAczD,MAAQ8J,EAAQu3C,MAAQ,CAAA,EACvGpT,EAA6B,iBAAXmlB,EAAsBA,EAAUA,GAAQnlB,UAAY,KAExEA,IACoC,iBAA3BlkC,KAAK+lD,YAAY3mD,GAC1BY,KAAK+lD,YAAY3mD,GAAM8kC,SAAWA,EAElClkC,KAAK+lD,YAAY3mD,GAAQ,CAAE8kC,eAKjC,IACE,MAAM6hB,EAAc,CAClB1O,MAAOr3C,KAAK+lD,aAAa1O,QAAS,EAClCC,MAAOt3C,KAAK+lD,aAAazO,QAAS,GAE9BM,QAAeh8C,EAAcy8C,aAAa0N,GAChD,OAAO/lD,KAAK+2C,cAAca,EAC5B,CAAE,MAAOx2C,GACP,MAAMA,CACR,CACF,CAEO,SAAAq9C,GACAz+C,KAAKw+C,gBACRx+C,KAAK8mD,OAAOzB,iBAEhB,CAEO,WAAA3G,GACD1+C,KAAKw+C,gBACPx+C,KAAK8mD,OAAOzB,iBAEhB,CAEO,SAAA/G,GACAt+C,KAAKq+C,gBACRr+C,KAAK8mD,OAAO9B,iBAEhB,CAEO,WAAAzG,GACDv+C,KAAKq+C,gBACPr+C,KAAK8mD,OAAO9B,iBAEhB,CAEO,YAAAxG,GACL,OAAOx+C,KAAK8mD,OAAOtI,cACrB,CAEO,YAAAH,GACL,OAAOr+C,KAAK8mD,OAAOzI,cACrB,CAEO,mBAAMoI,GACX,OAAO,IAAI/9C,QAAQ,CAACC,EAASksB,IACpB70B,KAAK8mD,OAAO7L,UAAUtyC,GAEjC,CAEO,oBAAA2gD,CAAqBrkD,GAC1B,OAAOjF,KAAK8mD,OAAOP,eAAethD,EACpC,CAEO,yBAAMskD,CAAoBtkD,GAC/B,OAAO,IAAIyD,QAASC,GACX3I,KAAK8mD,OAAOL,cAAcxhD,EAAQ0D,GAE7C,CAEO,iBAAAogD,CAAkBJ,EAAmB/Q,EAAqB4R,GAC/D,MAAMC,EAAepuD,SAASquD,eAAef,GAE7C,KAAI,cAAec,GAcjB,MAAM,IAAI5+C,MAAM,2CAA2C89C,kBAb3Dc,EAAaE,UAAY/R,EACzB6R,EAAaG,MAAMC,UAAYL,GAAKM,OAAS,aAAe,OAClC,kBAAfN,GAAKvE,QACdwE,EAAaxE,MAAQuE,GAAKvE,OAE5BwE,EAAaM,iBAAmBz+C,MAAO0+C,IACrC,UACQP,EAAaQ,MACrB,CAAE,MAAO7oD,GACPD,QAAQC,MAAM,yBAA0BA,EAC1C,EAKN,CAEO,iBAAA0nD,CAAkBH,EAAmBa,GAC1C,MAAMC,EAAepuD,SAASquD,eAAef,GAE7C,KAAI,cAAec,GAQjB,MAAM,IAAI5+C,MAAM,2CAA2C89C,kBAP3Dc,EAAaS,QACbT,EAAaE,UAAY,KACzBF,EAAaG,MAAMC,UAAYL,GAAKM,OAAS,aAAe,OAClC,kBAAfN,GAAKvE,QACdwE,EAAaxE,MAAQuE,GAAKvE,MAKhC,CAEO,cAAM/S,CAASpzC,EAAe4yC,GACnC,OAAO,IAAIhpC,QAAQ,CAACC,EAASC,KACtB5I,KAAK8mD,OAAO7E,iBAAiBnjD,KAKlCkB,KAAK8mD,OAAO7E,gBAAgBnjD,KAAK,CAC/BA,OACA4yC,QACA/E,QAAShkC,EACTvH,MAAOwH,IARPA,EAAO,IAAIiC,MAAM,wDAWvB,EC3cY,MAAOs/C,GACZ1/C,MACAvR,gBAA0CA,EAC1CQ,cAAsCA,EACtC0wD,cAAsE,CAAA,EAY7E,WAAAzqD,CAAY8K,GACVzK,KAAKyK,MAAQA,CACf,CAEA,gBAAA4/C,GACE,MAAM7rD,EAAU,IAAIqoD,GAAkB7mD,KAAKsqD,0BAc3C,OAZAtqD,KAAKoqD,cAAc5rD,EAAQmN,IAAMnN,EACjCA,EAAQupD,4BAA8B/nD,KAAK+nD,4BAC3CvpD,EAAQwpD,0BAA4BhoD,KAAKgoD,0BACzCxpD,EAAQgqD,mBAAqBxoD,KAAKwoD,mBAClChqD,EAAQ8pD,uBAAyBtoD,KAAKsoD,uBACtC9pD,EAAQ+pD,8BAAgCvoD,KAAKuoD,8BAC7C/pD,EAAQ6pD,uCAAyCroD,KAAKqoD,uCACtD7pD,EAAQ0pD,4BAA8BloD,KAAKkoD,4BAC3C1pD,EAAQ2pD,6BAA+BnoD,KAAKmoD,6BAC5C3pD,EAAQ4pD,wCAA0CpoD,KAAKooD,wCACvD5pD,EAAQypD,gBAAkBjoD,KAAKioD,gBAExBzpD,CACT,CAEO,qBAAM+rD,CAAgB9X,GAC3B,GAAI72C,GAAc4lD,iBAAkB,CAClC,MAAMC,QAAgB7lD,EAAa4lD,mBACnC,OAAO/O,EAAOgP,EAAQtyC,OAAQk6C,GAAWA,EAAO5W,OAASA,GAAQgP,CACnE,CACE,MAAM,IAAI52C,MAAM,sCAEpB,CAEO,YAAA2/C,CAAa/Z,UACXzwC,KAAKoqD,cAAc3Z,EAC5B,CAEO,sBAAA6Z,GACL,MAAMG,EAAiBzqD,KAAKyK,MAAMzF,aAElC,GAAIylD,GAAgB7kD,MAClB,OAAO6kD,EAAe7kD,MAEtB,MAAM,IAAIiF,MAAM,yBAEpB,CAEQ,iBAAAsvB,CAAkBrzB,GACxB,OAAQA,GACN,KAAK9M,EAAgBjC,KACnB,MAAO,8BACT,KAAKiC,EAAgBC,KACnB,MAAO,4BACT,KAAKD,EAAgBE,UACnB,MAAO,qBACT,KAAKF,EAAgB1D,cACnB,MAAO,yBACT,KAAK0D,EAAgBT,sBACnB,MAAO,gCACT,KAAKS,EAAgBG,wBACnB,MAAO,yCACT,KAAKH,EAAgBI,oBACnB,MAAO,8BACT,KAAKJ,EAAgBP,qBACnB,MAAO,+BACT,KAAKO,EAAgBK,yBACnB,MAAO,0CACT,KAAKL,EAAgB9C,MACnB,MAAO,kBACT,QACE,OAAO,KAEb,CAEO,WAAAqc,CAAYzM,EAAuB2N,GACxC,MAAM2lB,EAAep6B,KAAKm6B,kBAAkBrzB,GAI5C,OAHIszB,IACDp6B,KAAKo6B,GAAoC3lB,GAErCzU,KAAK2T,eAAeH,KAAKxT,KAAM8G,EACxC,CAEO,cAAA6M,CAAe7M,GACpB,MAAMszB,EAAep6B,KAAKm6B,kBAAkBrzB,GACxCszB,IACDp6B,KAAKo6B,QAAgD1+B,EAE1D,CAEO,kBAAA2+B,GACLl6B,OAAOC,KAAKJ,MAAMK,QAASC,IACrBA,EAAI+R,WAAW,OAAS/R,EAAIg2B,SAAS,aAA0D,mBAApCt2B,KAAKM,KACjEN,KAAKM,QAA6D5E,IAGzE,EC7GY,MAAOgvD,GACZjgD,MACEC,MAAQ7J,EAAO7C,KAAKc,KAE7B,WAAAa,CAAY8K,GACVzK,KAAKyK,MAAQA,CACf,CAEO,YAAM+Z,CAAOmmC,EAAmBvlD,EAA4B,IACjE,MAAMwlD,EAAS9pD,GAAMc,QAAQwD,GACvBylD,EAAQD,EAAS,aAAUlvD,EAC3BoP,EAAa,CACjB1L,KAAM5E,EAAYE,KAClB4K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOigD,EAAWE,GACzC/rD,KAAM8rD,EAAS,CAAEtpC,OAAQthB,KAAK8qD,aAAa1lD,IAAYA,GAGzD,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,UAAMF,CAAK+/C,EAAmBvlD,EAA0B,IAC7D,MAAM3D,EAAwB,iBAAX2D,EAAsBA,EAAStE,GAAMc,QAAQwD,GAAUA,EAAO/D,gBAAa3F,EACxFoP,EAAa,CACjBxF,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOigD,EAAWlpD,GACzC3C,KAAM2C,OAAM/F,EAAY0J,GAG1B,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,qBAAMigD,CAAgBJ,EAAmBh/C,GAC9C,MAAMb,EAAa,CACjBxF,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOigD,EAAWh/C,GACzC7M,KAAM,CAAEksD,YAAa,IAGvB,OAAOhrD,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,YAAMgd,CACX6iC,EACAvlD,EAAoD,IAEpD,MAAMwlD,EAAS9pD,GAAMc,QAAQwD,GACvB6lD,GAAYL,GAAUxlD,EAAO8lD,gBAC7BzpD,EAAMmpD,EAAS,QAAUK,EAAW,cAAgB7lD,EAAOuG,IAAMvG,EAAOokC,KAAO,GAC/E1+B,EAAa,CACjB1L,KAAM5E,EAAYG,IAClB2K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOigD,EAAWlpD,GACzC3C,KAAM8rD,EAAS,CAAEtpC,OAAQthB,KAAK8qD,aAAa1lD,IAAYA,GAGzD,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,YAAM,CACX6/C,EACAvlD,GAEA,MAAM+lD,EAAarqD,GAAMiB,SAASqD,GAC5BgmD,EAA0B,iBAAXhmD,GAAwBtE,GAAMc,QAAQwD,IAA6B,IAAlBA,EAAOpC,OACvEvB,EAAM0pD,EAAa,cAAkC,iBAAX/lD,EAAsBA,EAAUA,GAAQ/D,YAAc,GAChGyJ,EAAa,CACjB1L,KAAM5E,EAAYK,OAClByK,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOigD,EAAWlpD,GACzC3C,KAAMqsD,EAAa/lD,OAAS1J,EAC5B2N,SAAU+hD,EAAQrwD,EAAUE,UAAOS,GAGrC,OAAOsE,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEQ,YAAAggD,CAAa1lD,EAA8B,IACjD,OAAOA,EAAOqoB,OAAO,CAACoB,EAAOnoB,EAAMmC,KACjC,MAAMvI,EAAMuI,EAAQ,EACd8C,EAAKjF,EAAKiF,IAAMjF,EAAK8iC,IACrBloB,EAAS3V,EAAK,IAAKjF,EAAMiF,MAAOjF,EAEtC,MAAO,IAAKmoB,EAAOvuB,CAACA,GAAMghB,IACzB,CAAA,EACL,EChFY,MAAO+pC,GACZ5gD,MACEC,MAAQ7J,EAAO7C,KAAKgB,SAE7B,WAAAW,CAAY8K,GACVzK,KAAKyK,MAAQA,CACf,CAEO,SAAMO,CAAI5F,EAA6B,IAC5C,MAAM0F,EAAa,CACjB1L,KAAM5E,EAAYC,IAClB6K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,OACvB5L,KAAMsG,GAGR,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,YAAM0Z,CAAOpf,EAAgC,IAClD,MACMkmD,EAAiBlpD,KAAKipC,KAAK3oC,KAAKC,MAAQ,KACxC4oD,EAAeD,EAAiB,KAQhCE,EAAgB,CACpB1kD,KARkB,IAAIpE,KAAK4oD,GAAgBG,eAAe,KAAM,CAChEC,KAAM,UACNC,MAAO,OACPC,IAAK,UACLC,KAAM,UACNC,OAAQ,YAIRlyB,WAAY0xB,EACZxxB,SAAUyxB,EACVQ,UAAW,GACXzqC,QAAQ,EACRxkB,MAAM,GAEFgO,EAAa,CACjB1L,KAAM5E,EAAYE,KAClB4K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,OACvB5L,KAAM,IAAK0sD,KAAkBpmD,IAG/B,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,YAAMgd,CAAOnc,EAAqBvG,GACvC,MAAM0F,EAAa,CACjB1L,KAAM5E,EAAYG,IAClB2K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOiB,GAC9B7M,KAAMsG,GAGR,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,YAAM,CAAOa,GAClB,MAAMb,EAAa,CACjB1L,KAAM5E,EAAYK,OAClByK,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOiB,GAC9BtC,SAAUtO,EAAUE,MAGtB,OAAO+E,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,mBAAMkhD,CAAcrgD,GACzB,MAAMb,EAAa,CACjB1L,KAAM5E,EAAYC,IAClB6K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAO,aAAciB,IAG9C,OAAO3L,KAAKyK,MAAMhC,KAAKqC,EACzB,ECxEY,MAAOmhD,GACZxhD,MACA7L,cACAC,OAEP,WAAAc,CAAY8K,GACVzK,KAAKyK,MAAQA,EACbzK,KAAKpB,cAAgB,IAAIstD,GAAqBzhD,GAC9CzK,KAAKnB,OAAS,IAAIstD,GAAc1hD,EAClC,CAEO2hD,aAAe7oC,EAAAA,OAGxB,MAAM2oC,GACGzhD,MACEC,MAAQ7J,EAAO7C,KAAKY,cAE7B,WAAAe,CAAY8K,GACVzK,KAAKyK,MAAQA,CACf,CAEO,YAAM+Z,CAAOpf,GAClB,MAAM0F,EAAa,CACjB1L,KAAM5E,EAAYE,KAClB4K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,OACvB5L,KAAMsG,GAGR,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,UAAMF,GACX,MAAME,EAAa,CACjB1L,KAAM5E,EAAYC,IAClB6K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,QAGzB,OAAO1K,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,YAAM,CAAOa,GAClB,MAAMb,EAAa,CACjB1L,KAAM5E,EAAYK,OAClBwO,SAAUtO,EAAUE,KACpBqK,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOiB,IAGhC,OAAO3L,KAAKyK,MAAMhC,KAAKqC,EACzB,EAGF,MAAMqhD,GACG1hD,MACEC,MAAQ7J,EAAO7C,KAAKa,OAE7B,WAAAc,CAAY8K,GACVzK,KAAKyK,MAAQA,CACf,CAEO,YAAM+Z,CAAO3Q,GAClB,MAAM/I,EAAa,CACjB1L,KAAM5E,EAAYE,KAClB4K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,OACvB5L,KAAM,CAAE+U,UAGV,OAAO7T,KAAKyK,MAAMhC,KAAKqC,EACzB,ECrEY,MAAOuhD,GACZ5hD,MACEC,MAAQ7J,EAAO7C,KAAKW,MAE7B,WAAAgB,CAAY8K,GACVzK,KAAKyK,MAAQA,CACf,CAEO,UAAMG,CAAKxF,EAA6B,IAC7C,MAAM0F,EAAa,CACjB1L,KAAM5E,EAAYC,IAClB6K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,OACvB5L,KAAMsG,GAGR,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,YAAM0Z,CAAOpf,GAClB,MAAM0F,EAAa,CACjB1L,KAAM5E,EAAYE,KAClB4K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,OACvB5L,KAAM,CAAEwtD,KAAMlnD,IAGhB,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,YAAM,CAAOa,GAClB,MAAMb,EAAa,CACjB1L,KAAM5E,EAAYK,OAClByK,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOiB,GAC9BtC,SAAUtO,EAAUE,MAGtB,OAAO+E,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,qBAAMyhD,CAAgBnnD,GAC3B,MAAM0B,KAAEA,EAAI0lD,KAAEA,EAAI/oD,KAAEA,EAAI8E,SAAEA,EAAUnJ,KAAMqtD,EAAcC,OAAQC,GAAW,GAASvnD,EAC9EwnD,EAAe,CAAE9lD,OAAM2lD,eAAcC,OAAQC,GAEnD,IAAIL,EAEJ,OAAOtsD,KAAKwkB,OAAOooC,GAChBzjD,KAAK,EAAGmjD,KAAMO,MACbP,EAAOO,EACP,MAAMjvC,EAAM5d,KAAK8sD,SAASR,EAAKS,oBAAoB3nD,QAE7C4nD,EAA6B,CAAE1nD,IADnB,GAAGsY,EAAI/E,cAAc+E,EAAIqvC,YAAYrvC,EAAIsvC,OACNpuD,KAAM,CAAA,GAEvDyJ,IACFykD,EAAazkD,SAAWA,GAG1B,MAAM4kD,EAAmC,iBAAjBvvC,EAAIuvC,UAA0C,OAAjBvvC,EAAIuvC,SAAoBvvC,EAAIuvC,SAAW,CAAA,EACtFruD,EAAQkuD,EAAaluD,MAAQ,GAQnC,OANAqB,OAAOC,KAAK+sD,GAAU9sD,QAASC,IAC7BxB,EAAKwB,GAAO8sD,mBAAmBD,EAAS7sD,MAE1CxB,EAAK0tD,KAAOA,EACZQ,EAAaluD,KAAOA,EAEbkB,KAAKqtD,OAAOL,GAAc7jD,KAAK,IAAMmjD,KAE7CnjD,KAAMmjD,GAAStsD,KAAKstD,aAAa,CAAE3hD,GAAI2gD,EAAK3gD,GAAIlI,SAAQ0F,KAAK,IAAMmjD,IACnEnjD,KAAMmjD,IAAI,IAAWA,EAAM7oD,SAChC,CAEO,YAAM4pD,CAAOjoD,GAClB,MAAM0F,EAAa,IACd1F,EACHhG,KAAM5E,EAAYE,KAClB2O,SAAUtO,EAAUE,KACpB+K,aAAa,GAGf,OAAOhG,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,kBAAMwiD,CAAaloD,GACxB,MAAM0F,EAAa,CACjB1L,KAAM5E,EAAYG,IAClB2K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOtF,EAAOuG,GAAI,YACzC7M,KAAM,CACJ2E,KAAM2B,EAAO3B,MAEf4F,SAAUtO,EAAUE,MAGtB,OAAO+E,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,aAAMiyC,CAAQpxC,GACnB,MAAMb,EAAa,CACjBxF,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOiB,IAGhC,OAAO3L,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,aAAMyiD,CAAQC,GACnB,MAAM1iD,EAAa,CACjBxF,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAO8iD,IAGhC,OAAOxtD,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,mBAAM2iD,CAAcD,EAAapoD,GACtC,MAAM0F,EAAa,CACjB1L,KAAM5E,EAAYC,IAClB6K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAO8iD,EAAK,UACnC1uD,KAAMsG,GAGR,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,YAAMgd,CAAO1iB,GAClB,MAAMtG,EAAO,CAAEwtD,KAAM,SAEM,IAAhBlnD,EAAO0B,OAChBhI,EAAKwtD,KAAKxlD,KAAO1B,EAAO0B,MAG1B,MAAMgE,EAAa,CACjBxF,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOtF,EAAOuG,IACrC7M,KAAMA,GAGR,OAAOkB,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,UAAA4iD,CAAWC,EAAkB,IAClC,MAAO,GAAG9sD,EAAOjE,UAAUqD,SAAW,WAAWY,EAAOjE,UAAUC,eAAe8wD,WAAiB3tD,KAAKyK,MAAMzF,cAAcY,OAC7H,CAEO,SAAAgoD,CAAUD,EAAkB,IACjC,MAAO,GAAG9sD,EAAOjE,UAAUqD,SAAW,WAAWY,EAAOjE,UAAUC,eAAe8wD,GACnF,CAEQ,QAAAb,CAASvpD,EAAc,IAC7B,MAAMxD,EAAU,CAEdO,IAAK,CACH,SACA,WACA,YACA,WACA,OACA,WACA,OACA,OACA,WACA,OACA,YACA,OACA,QACA,UAEF4gC,EAAG,CAEDhsB,OAAQ,6BAEVA,OAAQ,CACN24C,OACE,0IACFC,MACE,qMAIAt/C,EAAIzO,EAAQmV,OAA8C,MAAE6T,KAAKxlB,IAAQ,GAEzEqa,EAAM,CACVmwC,OAAQ,GACRl1C,SAAU,GACVo0C,UAAW,GACXe,SAAU,GACVtiD,KAAM,GACNM,SAAU,GACVgN,KAAM,GACNL,KAAM,GACNs1C,SAAU,GACVf,KAAM,GACNgB,UAAW,GACX1B,KAAM,GACN13B,MAAO,GACPq5B,OAAQ,GACRhB,SAAU,CAAA,GAYZ,OATAptD,EAAQO,IAAID,QAAQ,CAACC,EAAK2e,KACxBrB,EAAItd,GAAOkO,EAAEyQ,IAAM,KAGrBrB,EAAIkX,MAAM1wB,QAAQrE,EAAQmhC,EAAEhsB,OAAQ,CAACk5C,EAAYh+C,EAAWC,KACtDD,IAAGwN,EAAIuvC,SAAS/8C,GAAKC,GAClB,KAGFuN,CACT,EC5MY,MAAOywC,GACZ5jD,MACEC,MAAQ7J,EAAO7C,KAAKU,MAE7B,WAAAiB,CAAY8K,GACVzK,KAAKyK,MAAQA,CACf,CAEO,WAAM6jD,CAAMlpD,GACjB,MAAM0F,EAAa,CACjB1L,KAAM5E,EAAYC,IAClB6K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAO,MAC9BpE,eAAe,EACfxH,KAAMsG,GAGR,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,YAAMyjD,CAAO7iD,EAA0BK,GAC5C,MAAMjB,EAAa,CACjBnO,QAASoP,GAAYlL,EAAOpE,MAAME,QAClCyC,KAAM5E,EAAYE,KAClB4K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,OACvB5L,KAAM,CAAE4M,SAGV,OAAO1L,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,YAAMgd,CAAOpc,EAA2B,IAC7C,MAAMZ,EAAa,CACjB1L,KAAM5E,EAAYG,IAClB2K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAO1K,KAAKyK,MAAMvF,oBACzCpG,KAAM,CAAE4M,SAGV,OAAO1L,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,YAAM,GACX,MAAMA,EAAa,CACjB1L,KAAM5E,EAAYK,OAClByK,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAO1K,KAAKyK,MAAMvF,oBACzCmE,SAAUtO,EAAUE,MAGtB,OAAO+E,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,mBAAM0jD,CAAcviD,EAAgB,IACzC,MAAMnB,EAAa,CACjB1L,KAAM5E,EAAYE,KAClB4K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAO,WAAY,SAC1C5L,KAAM,CAAEmN,SACR5C,SAAUtO,EAAUE,MAGtB,OAAO+E,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,gBAAM2jD,CAAWrpD,EAAiC,IACvD,MAAM0F,EAAa,CACjB1L,KAAM5E,EAAYC,IAClB6K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAO,UAC9B5L,KAAMsG,GAGR,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,oBAAM4jD,GACX,MAAM5jD,EAAa,CACjB1L,KAAM5E,EAAYC,IAClB6K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAO,UAC9B5L,KAAM,CAAE6vD,OAAO,IAGjB,OAAO3uD,KAAKyK,MAAMhC,KAAKqC,EACzB,CAKO,SAAME,CAAI5F,GACf,IAAItG,EAAOgC,GAAMkD,YAAYoB,GACzBE,EAAuB,GAE3B,MAAMspD,EAAoB,GACpBC,EAAa,CAAC,aAAc,aAAc,mBAC1CC,EAAe,CAAC,KAAM,oBACtBC,EAA2B,CAC/BtwD,MAAO,WACPuwD,UAAW,eACXC,YAAa,iBACbC,WAAY,gBACZC,MAAO,QACPljD,MAAO,WACPmjD,KAAM,UACNC,SAAU,YAGZ,SAASC,EAAengD,GACtB,MAAMnN,EAAMlB,GAAMkD,YAAYmL,GACxBogD,EAAQ1nD,OAAO7F,EAAIutD,OAAS,IAClC,IAAInwD,EAAOyvD,EAAWl0C,SAAS40C,GAAS,cAAgBvtD,EAAI+E,MAS5D,OAPIjG,GAAMc,QAAQI,EAAI+E,SACP,WAAT3H,IACFA,SAAe4C,EAAI+E,MAAoB,IAEzC/E,EAAI+E,MAAS/E,EAAI+E,MAAoB1F,YAGhC,CAACjC,EAAMmwD,EAAOvtD,EAAIwtD,MAAOxtD,EAAI+E,OAAOa,KAAK,IAClD,CAEA,GAAI9I,EAAK61B,MAAO,CACd,MAAMA,EAAQ71B,EAAK61B,MACb46B,EAAQ1nD,OAAO8sB,EAAM46B,OAAS,IAC9BnwD,EAAOmwD,KAASV,EAAa,OAASU,KAAST,EAAe,SAAW,SAC/EhwD,EAAK61B,MAAQ,CAACA,EAAMhtB,KAAMvI,EAAMu1B,EAAM46B,OAAO3nD,KAAK,IACpD,CAaA,GAXI9I,GAAQA,EAAKqQ,SACXrO,GAAMc,QAAQ9C,EAAKqQ,QACpBrQ,EAAKqQ,OAAqB9O,QAAS8O,IAClCy/C,EAAQ1rD,KAAKosD,EAAgBngD,GAA0B,CAAA,MAGzDy/C,EAAQ1rD,KAAKosD,EAAgBxwD,EAAKqQ,QAA0B,CAAA,IAE9DrQ,EAAKqQ,OAASy/C,GAGI,iBAAT9vD,EACTwG,EAAMxG,EACNA,OAAOpD,OAEP,IAAK,MAAM4E,KAAOyuD,EAChB,GAAIjwD,EAAKwB,GAAM,CACbgF,EAAMypD,EAAWzuD,GAEbA,IAAQyuD,EAAWM,WACrB/pD,GAAO,IAAIxG,EAAKiwD,EAAWM,YAC3BvwD,OAAOpD,GAGT,KACF,CAIJ,MAAMoP,EAAa,CACjB1L,KAAM5E,EAAYC,IAClB6K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOpF,GAC9BxG,QAGF,OAAOkB,KAAKyK,MAAMhC,KAAKqC,EACzB,ECnKY,MAAO2kD,GACnB,iBAAOx+B,CAAWtlB,GAChB,MAAO,GAAGA,KAAM9K,EAAOpE,MAAMC,SAASmE,EAAOjE,UAAUE,MACzD,CAEA,uBAAOu0B,CAAiB3Z,GACtB,OAAOA,GAAKiD,SAAS,KAAO/X,SAAS8U,EAAIgK,MAAM,KAAK,GAAGA,MAAM,KAAK,IAAM,IAC1E,CAEA,YAAOmK,CAAMviB,GACPzI,EAAOxC,OACT8C,QAAQgC,IAAI,eAAgBmG,EAEhC,CAEA,mBAAOomD,CAAapmD,GACdzI,EAAOxC,OACT8C,QAAQutC,KAAK,eAAgBplC,EAEjC,CAEA,iBAAOqmD,CAAWrmD,GACZzI,EAAOxC,OACT8C,QAAQC,MAAM,eAAgBkI,EAElC,CAEA,4BAAWsmD,GACT,MAAMC,EAAKl0D,GAAWopB,WAAa,KACnC,IAAIvoB,EAAU,EACd,GAAIqzD,EAAI,CACN,MAAMC,EAASD,EAAGtjD,MAAM,2BAA6B,GACrD/P,EAAUszD,EAAO,IAAMA,EAAO,GAAK,CACrC,CACA,MAA0B,iBAAZtzD,EAAuBoG,SAASpG,GAAWA,CAC3D,CAEA,2BAAWuzD,GACT,MAAMF,EAAKl0D,GAAWopB,WAAa,KACnC,IAAIvoB,EAAU,EACd,GAAIqzD,EAAI,CAEN,IADcA,EAAGtjD,MAAM,0BAA4B,IACzCvJ,OAAQ,CAChB,MAAMgtD,EAAOH,EAAGtjD,MAAM,2BAA6B,GAC/CyjD,IACFxzD,EAAUwzD,EAAK,IAAMA,EAAK,GAAK,EAEnC,CACF,CAEA,MAA0B,iBAAZxzD,EAAuBoG,SAASpG,GAAWA,CAC3D,EC/CY,MAAOyzD,GAKZC,UAA2B,KAC3B1+C,MAA6B7a,EAAoBf,IACjDkpC,cAAuC,GACvCnhC,mBAA6B,EAC7BwyD,sBAAwD,KACxDC,aAA+C,KAC/CC,iBAAmD,KACnDC,gCAAkE,KAClEC,UAAoB,EAEpBC,aAA4B,MACjC,IAAK30D,EACH,MAAM,IAAIgP,MAAM,gCAGlB,OAAO,IAAIhP,CACZ,EANkC,GAQnC,WAAA8D,CAAYnB,EAAwBm6B,EAAgBv5B,GAClDY,KAAKwkB,SACLxkB,KAAK6lB,MAAMrnB,EAASm6B,EAAQv5B,EAC9B,CAEQ,MAAAolB,GACN,MAAMisC,EAAqC,CACzCpjB,mBAAqBxsC,EAAOpD,UAAUC,iBAAmB,QAAU,MACnEK,WAAY8C,EAAOpD,UAAUM,YAAYmV,IACtCxM,IAA+B,CAC9B1I,KAAM0I,EAAK1I,MAAQ0I,EAAKpB,IACxBrH,SAAUyI,EAAKzI,SACfC,WAAYwI,EAAKxI,eAKvB8B,KAAK0wD,SAAW10D,EAAoB,IAAIA,EAAkBy0D,GAAqB,CAAA,EAE/EhB,GAAc5jC,MAAM,yBAAyB7wB,KAAK8I,UAAU2sD,EAAkB,KAAM,MACtF,CAEQ,KAAA5qC,CAAMrnB,EAAwBm6B,EAAgBv5B,GACpDY,KAAKZ,KAAOA,EACZY,KAAK24B,OAASA,EACd34B,KAAKxB,QAAUA,EACfwB,KAAKxB,QAAQmyD,cAAgBjuD,KAAKC,MAElC3C,KAAK0wD,SAASp9C,iBAAiB,QAAStT,KAAK4wD,qBAC7C5wD,KAAK0wD,SAASp9C,iBAAiB,eAAgBtT,KAAK6wD,uBACpD7wD,KAAK0wD,SAASp9C,iBAAiB,uBAAwBtT,KAAK8wD,yBAC5D9wD,KAAK0wD,SAASp9C,iBAAiB,2BAA4BtT,KAAK+wD,6BAEhEtB,GAAc5jC,MAAM,2BAA2B7rB,KAAKqB,aACtD,CAEQuvD,oBAAuB/8C,IAC7B7T,KAAKwwD,aAAa7X,SAAS9kC,EAAM2+B,QAG9BxyC,KAAKxB,QAAQwyD,UAAYh7D,EAASC,OAAS+J,KAAKwwD,aAAa1Y,iBAAiB90C,QAC9EhD,KAAKxB,QAAQwyD,UAAYh7D,EAASE,OAAS8J,KAAKwwD,aAAa3Y,iBAAiB70C,SAE/EhD,KAAKxB,QAAQ0oD,eAAelnD,KAAK24B,OAAQ34B,KAAKwwD,cAGhDxwD,KAAKixD,mBAGCJ,sBAAyBh9C,IAC/B,GAAIA,EAAM+nB,UAAW,CACnB,MAAMkZ,cAAEA,EAAaD,OAAEA,EAAMjZ,UAAEA,GAAc/nB,EAAM+nB,UAC7CmO,EAAoC,CAAE+K,gBAAeD,SAAQjZ,aAEvC,WAAxB57B,KAAKkxD,gBAA+BlxD,KAAK0wD,SAASS,wBACpDnxD,KAAKxB,QAAQ4yD,qBAAqBpxD,KAAK24B,OAAQ,CAACoR,IAEhD/pC,KAAK8+B,cAAc57B,KAAK6mC,EAE5B,GAGM+mB,wBAA0BxlD,UAChCmkD,GAAc5jC,MAAM,4BAA4B7rB,KAAKkxD,kBAEzB,WAAxBlxD,KAAKkxD,gBAA+BlxD,KAAK8+B,cAAc97B,OAAS,IAClEhD,KAAKxB,QAAQ4yD,qBAAqBpxD,KAAK24B,OAAQ34B,KAAK8+B,eACpD9+B,KAAK8+B,cAAc97B,OAAS,IAKxB+tD,4BAA8B,KAOpC,OANAtB,GAAc5jC,MAAM,gCAAgC7rB,KAAKs0C,sBAErDt0C,KAAKmwD,uBAAyBV,GAAcM,kBAAoB,IAClE98C,aAAajT,KAAKmwD,uBAGZnwD,KAAKs0C,oBACX,IAAK,WACHt0C,KAAKwR,MAAQ7a,EAAoBC,SACjCoJ,KAAKxB,QAAQ6yD,gCAAgCrxD,KAAK24B,OAAQxjC,EAA2BE,YACrF,MACF,IAAK,YACH2K,KAAKwR,MAAQ7a,EAAoBrB,UACjC0K,KAAKsxD,6BACLtxD,KAAKxB,QAAQ6yD,gCAAgCrxD,KAAK24B,OAAQxjC,EAA2BG,WACrF,MACF,IAAK,YACH0K,KAAKwR,MAAQ7a,EAAoBjB,UACjCsK,KAAKsxD,6BACLtxD,KAAKxB,QAAQ6yD,gCAAgCrxD,KAAK24B,OAAQxjC,EAA2BO,WACrF,MACF,IAAK,SACHsK,KAAKwR,MAAQ7a,EAAoBpB,OACjCyK,KAAKxB,QAAQ6yD,gCAAgCrxD,KAAK24B,OAAQxjC,EAA2BI,QACrF,MACF,IAAK,eACHyK,KAAKwR,MAAQ7a,EAAoBnB,aACjCwK,KAAKuxD,6BACLvxD,KAAKxB,QAAQ6yD,gCAAgCrxD,KAAK24B,OAAQxjC,EAA2BK,cACjFi6D,GAAcM,kBAAoB,KACpC/vD,KAAKmwD,sBAAwBt9C,WAAW,KACtC7S,KAAK+wD,+BACJ,MAEL,MACF,IAAK,SACH/wD,KAAKwR,MAAQ7a,EAAoBlB,OACjCuK,KAAKsxD,6BACLtxD,KAAKxB,QAAQ6yD,gCAAgCrxD,KAAK24B,OAAQxjC,EAA2BM,UAOnF,0BAAA67D,GACFtxD,KAAKswD,kCACPb,GAAc5jC,MAAM,8BACpB5Y,aAAajT,KAAKswD,iCAClBtwD,KAAKswD,gCAAkC,KAE3C,CAEQ,0BAAAiB,GACN,MAAM9xD,EAA4D,KAAjDoB,EAAOpD,UAAUI,wBAA0B,IAE5D4xD,GAAc5jC,MAAM,wCAAwCpsB,KAE5DO,KAAKswD,gCAAkCz9C,WAAW,KAChD48C,GAAc5jC,MAAM,mCAChB7rB,KAAKswD,iCACPr9C,aAAajT,KAAKswD,iCAEpBtwD,KAAKwxD,UACLxxD,KAAKxB,QAAQizD,sCACZhyD,EACL,CAEQ,qBAAAiyD,GACF1xD,KAAKqwD,mBACP5T,cAAcz8C,KAAKqwD,kBACnBrwD,KAAKqwD,iBAAmB,KAE5B,CAEO,mBAAMsB,CAAc7yB,GACzB,IAAK,MAAMiL,KAAgBjL,EACzB,GAAIiL,GAAcnO,UAChB,UACQ57B,KAAK2vC,gBAAgB5F,GAC3B0lB,GAAc5jC,MAAM,8BAA8B7rB,KAAKkxD,iBACzD,CAAE,MAAO9vD,GACPquD,GAAcE,WAAW,4BAA4BvuD,IACvD,CAGN,CAEO,OAAAowD,GACLxxD,KAAK4xD,oBACL5xD,KAAK0xD,wBACL1xD,KAAKma,QACDs1C,GAAcM,kBAAoB,IACpC/vD,KAAK+wD,8BAEP/wD,KAAK0wD,SAASh9C,oBAAoB,QAAS1T,KAAK4wD,qBAChD5wD,KAAK0wD,SAASh9C,oBAAoB,eAAgB1T,KAAK6wD,uBACvD7wD,KAAK0wD,SAASh9C,oBAAoB,uBAAwB1T,KAAK8wD,yBAC/D9wD,KAAK0wD,SAASh9C,oBAAoB,2BAA4B1T,KAAK+wD,6BACnE/wD,KAAKuwD,UAAW,EAChBd,GAAc5jC,MAAM,6BAA6B7rB,KAAKqB,aACxD,CAEO,iBAAAuwD,GACD5xD,KAAKowD,eACPX,GAAc5jC,MAAM,qBACpB4wB,cAAcz8C,KAAKowD,cACnBpwD,KAAKowD,aAAe,KACpBpwD,KAAKrC,mBAAqB,EAE9B,CAEO,sCAAMk0D,CACXC,EACAlb,GAAsB,GAEtB52C,KAAKwR,MAAQ7a,EAAoBtB,WAEjC,IACE,MAAM08D,EAAenb,EAAa,CAAEA,mBAAel7C,EAC7Cs2D,EACU,UAAdhyD,KAAKZ,WAAyBY,KAAK62C,YAAYkb,SAAsB/xD,KAAKy2C,eAK5E,aAHMz2C,KAAK02C,oBAAoBsb,GAC/BhyD,KAAKiyD,4BAA4BH,GAE1BE,CACT,CAAE,MAAO5wD,GACP,MAAMA,CACR,CACF,CAEO,2BAAA6wD,CAA4BH,GACjC,MAAMI,EAAUlyD,KAAKuyC,cAAgB,GAC/B2G,EAAa4Y,EAAe1vD,KAAKk6C,MAAqB,IAAfwV,GAAuB,EAEpEI,EAAQ7xD,QAASgvC,IACf,GAAIA,EAAOmD,OAAOC,OAASn4C,EAAUrE,MAAO,CAC1C,MAAMmP,EAASiqC,EAAOgK,gBAEtBj0C,EAAOk0C,YAAc,CAAC,IACtBl0C,EAAOk0C,UAAUj5C,QAAS8xD,IACpBjZ,EAAa,EACfiZ,EAASjZ,WAAaA,SAEfiZ,EAASjZ,aAIpB7J,EACGkK,cAAcn0C,GACd+D,KAAK,KACJsmD,GAAc5jC,MACZ,0BAA0B7rB,KAAK24B,WAAWm5B,EAAe,EAAI,GAAGA,SAAsB,iBAGzFpoD,MAAOtI,IACNquD,GAAcC,aAAa,0BAA0B1vD,KAAK24B,WAAWv3B,MAE3E,GAEJ,CAEO,iBAAAgxD,CAAkBzwD,EAAkC0wD,GACzD,MAAMz0D,EAAoE,KAA7CiD,EAAOpD,UAAUG,qBAAuB,GAC/DD,EAAmE,KAA7CkD,EAAOpD,UAAUE,oBAAsB,IAEnE8xD,GAAc5jC,MAAM,2CAA2C7wB,KAAK8I,UAAUlG,MAE9E,MAAM00D,EAAkB,CACtB3wD,EACA0wD,EACAE,KAEKA,IACHvyD,KAAKrC,oBAAsBC,GAG7B6xD,GAAc5jC,MAAM,+BAA+B7wB,KAAK8I,UAAUnC,MAE9D3B,KAAKrC,oBAAsBA,GAC7BqC,KAAK4xD,oBAEDS,GACFryD,KAAKxB,QAAQg0D,mBAAmBxyD,OAGlCA,KAAKxB,QAAQi0D,YAAYzyD,KAAM2B,IAInC3B,KAAKowD,aAAerU,YAAYuW,EAAiB10D,EAAqB+D,EAAW0wD,GAAyB,GAE1GC,EAAgB3wD,EAAW0wD,GAAyB,EACtD,CAEO,iCAAMK,CAA4BtzD,EAAkB4xC,GACzD,MAAM2hB,EAAO,IAAIx2D,EAAuB,CAAE60C,MAAK5xC,SAC/C,OAAOY,KAAKs2C,qBAAqBqc,EACnC,CAEQ,eAAA1B,GACN,GAAIpwD,EAAOpD,UAAUK,wBAAyB,CAC5C,IAAI80D,EAEJnD,GAAc5jC,MAAM,kCAEpB7rB,KAAKqwD,iBAAmBtU,YAAY,KAClC/7C,KAAK6yD,eACHD,EACA,CAACE,EAASC,KACRH,EAAaG,EACb/yD,KAAKxB,QAAQw0D,kBAAkBhzD,KAAK24B,OAAQm6B,IAE7C5xD,IACCuuD,GAAcE,WAAW,oBAAoBzuD,EAAI4F,SAAS5F,EAAI2K,WAC9D7L,KAAKxB,QAAQw0D,kBAAkBhzD,KAAK24B,OAAQ,KAAMz3B,MAGV,IAA3CL,EAAOpD,UAAUK,wBACtB,CACF,CAEA,aAAIm1D,CAAUjiB,GACRA,IACFhxC,KAAKkwD,UAAYlf,EAErB,CAEA,aAAIiiB,GACF,OAAOjzD,KAAKkwD,SACd,CAEA,QAAA7uD,GACE,MAAO,cAAcrB,KAAKxB,QAAQ00D,eAAelzD,KAAK24B,iBAAiB34B,KAAKZ,gBAAgBY,KAAKwR,OACnG,CAEQ,cAAAqhD,CACNE,EACAI,EAIAC,GAEA,MAAMpxD,EAA4B,CAAEq1C,MAAO,CAAA,EAAIC,MAAO,CAAA,EAAI1b,UAAW,IAC/Dy3B,EAA2E,CAC/E19C,MAAOxV,OAAO6I,OAAO,CAAA,EAAIhH,GACzBk5C,OAAQ/6C,OAAO6I,OAAO,CAAA,EAAIhH,IAG5B,GAAIytD,GAAcG,kBAAmB,CACnC,MAAM5M,EAAchjD,KAAKxB,QAAQwkD,YAC3BsQ,EAAqBtQ,GAAalL,iBAAiB,GAAGkR,cAExDsK,IACFD,EAAU19C,MAAM2hC,MAAMic,YAAcD,EAAmBxS,OACvDuS,EAAU19C,MAAM2hC,MAAMkc,WAAaF,EAAmBtS,MAE1D,CAEAhhD,KAAKg0C,WAAW7qC,KAAM2pD,IACpBA,EAAQzyD,QAAS6M,IACf,IAAIxG,EAEAwG,EAAOgvC,eAAiC,gBAAhBhvC,EAAO9N,MACjCsH,EAAO2sD,EAAUnY,OAAOhuC,EAAO+uC,WAC/Bv1C,EAAKwtC,QAAUl0C,KAAKyzD,oBAAoBvmD,EAAQ6lD,GAAa,GAC7DrsD,EAAKw1C,cAAgBhvC,EAAOgvC,cAC5Bx1C,EAAKgtD,gBAAkBxmD,EAAOwmD,gBAC9BhtD,EAAKjE,UAAYyK,EAAOzK,UACpByK,EAAO+uC,YAAc3hD,EAAUrE,OAASiX,EAAOymD,gBACjDjtD,EAAKktD,gBAAkBxxD,KAAKk6C,MAA6B,GAAvBpvC,EAAOymD,eAAsB,KAExDzmD,EAAO2mD,WAA6B,iBAAhB3mD,EAAO9N,MACpCsH,EAAO2sD,EAAU19C,MAAMzI,EAAO+uC,WAC9Bv1C,EAAKwtC,QAAUl0C,KAAKyzD,oBAAoBvmD,EAAQ6lD,GAAa,GAC7DrsD,EAAKmtD,UAAY3mD,EAAO2mD,UACxBntD,EAAKotD,YAAc5mD,EAAO4mD,YAC1BptD,EAAKjE,UAAYyK,EAAOzK,UACpByK,EAAO+uC,YAAc3hD,EAAUrE,OAASiX,EAAOymD,gBACjDjtD,EAAKktD,gBAAkBxxD,KAAKk6C,MAA6B,GAAvBpvC,EAAOymD,eAAsB,KAExC,oBAAhBzmD,EAAO9N,MAChBsH,EAAO2sD,EAAU19C,MAAMimB,UACM,SAAzB1uB,EAAO6mD,eAAyD,QAA7B7mD,EAAO8mD,mBAAoD,QAArB9mD,EAAO+mD,WAClFvtD,EAAKmS,SAAW3L,EAAO+mD,UACvBvtD,EAAKwtD,GAAKhnD,EAAOinD,UACjBztD,EAAKiS,KAAOzL,EAAOknD,YACT3E,GAAcG,oBACxBlpD,EAAKmS,SAAW3L,EAAO2L,SACvBnS,EAAKwtD,GAAKhnD,EAAOgnD,GACjBxtD,EAAKiS,KAAOzL,EAAOyL,OAEI,qBAAhBzL,EAAO9N,MAChBsH,EAAO2sD,EAAUnY,OAAOtf,UACxBl1B,EAAKmS,SAAW3L,EAAO2L,UAAY3L,EAAO+mD,UAC1CvtD,EAAKwtD,GAAKhnD,EAAOgnD,IAAMhnD,EAAOinD,UAC9BztD,EAAKiS,KAAOzL,EAAOyL,MAAQzL,EAAOknD,YACT,UAAhBlnD,EAAO9N,MAAoB8N,EAAOulC,OAASn4C,EAAUrE,OAAUw5D,GAAcG,oBAClF1iD,EAAOkuC,cACT10C,EAAO2sD,EAAUnY,OAAO5D,MACxB5wC,EAAK6sD,YAAcrmD,EAAOqmD,YAC1B7sD,EAAK8sD,WAAatmD,EAAOsmD,WACzB9sD,EAAKktD,gBAAkB5zD,KAAKq0D,mBAAmBnnD,EAAQ6lD,GAAa,KAEpErsD,EAAO2sD,EAAU19C,MAAM2hC,MACvB5wC,EAAK6sD,YAAcrmD,EAAOqmD,YAC1B7sD,EAAK8sD,WAAatmD,EAAOsmD,WACzB9sD,EAAKktD,gBAAkB5zD,KAAKq0D,mBAAmBnnD,EAAQ6lD,GAAa,OAI1EI,EAAUE,EAAWP,IACpBM,EACL,CAEQ,mBAAAK,CAAoBvmD,EAAkB6lD,EAA6BuB,GACzE,MAAM1B,EAAaG,EAAY/nD,IAAIkC,EAAOvB,IACpC6wB,EAAUo2B,GAAc1lD,EAAOzK,UAAYmwD,EAAWnwD,WAAa,IAAO,EAG1EynB,EAAIhd,EACJ00B,EAAIgxB,EACJ1e,EAAW0e,EAEb0B,EALQ,IAMGpqC,EAAE2pC,WAAa,IAAMjyB,GAAGiyB,WAAa,KAPvC,KAOsDr3B,GANvD,IAOGtS,EAAEgyB,eAAiB,IAAMta,GAAGsa,eAAiB,KAR/C,KAQ8D1f,GAHvE,EAKJ,OAAOp6B,KAAKk6C,MAAMpI,EACpB,CAEQ,kBAAAmgB,CAAmBnnD,EAAkB6lD,EAA6BuB,GACxE,MAAM1B,EAAaG,GAAeA,EAAY/nD,IAAIkC,EAAOvB,IACnD6wB,EAAUo2B,GAAc1lD,EAAOzK,UAAYmwD,EAAWnwD,WAAa,IAAO,EAC1EynB,EAAIhd,EACJ00B,EAAIgxB,EACJgB,EAAmBhB,EAErB0B,IACIpqC,EAAEqqC,YAAc,IAAM3yB,GAAG2yB,YAAc,IAAM/3B,IAC7CtS,EAAEsqC,gBAAkB,IAAM5yB,GAAG4yB,gBAAkB,IAAMh4B,EAHzD,EAKJ,OAAOp6B,KAAKk6C,MAAwB,GAAlBsX,GAAwB,EAC5C,CAGA,KAAAz5C,GACEna,KAAK0wD,SAASv2C,SAChB,CACA,QAAAw+B,CAASnG,EAAyBoF,GAChC,OAAO53C,KAAK0wD,SAAS/X,WAAWnG,EAAOoF,IAAW,IACpD,CACA,UAAArF,GACE,OAAOvyC,KAAK0wD,SAASne,gBAAkB,IACzC,CACA,iBAAMsE,CAAY92C,GAChB,aAAcC,KAAK0wD,SAAS7Z,cAAc92C,KAAa,IACzD,CACA,kBAAM02C,CAAa12C,GACjB,aAAcC,KAAK0wD,SAASja,eAAe12C,KAAa,IAC1D,CACA,cAAMi0C,CAASygB,GACb,aAAcz0D,KAAK0wD,SAAS1c,WAAWygB,KAAc,IACvD,CACA,qBAAM9kB,CAAgB/T,SACd57B,KAAK0wD,SAAS/gB,kBAAkB/T,GACxC,CACA,0BAAM0a,CAAqBvP,SACnB/mC,KAAK0wD,SAASpa,uBAAuBvP,GAC7C,CACA,yBAAM2P,CAAoB3P,SAClB/mC,KAAK0wD,SAASha,sBAAsB3P,GAC5C,CACA,oBAAI2N,GACF,OAAO10C,KAAK0wD,SAAShc,kBAAoB,IAC3C,CACA,kBAAIwc,GACF,OAAOlxD,KAAK0wD,SAASQ,gBAAkB,QACzC,CACA,sBAAI5c,GACF,OAAOt0C,KAAK0wD,SAASpc,oBAAsB,QAC7C,ECjeY,MAAOogB,GACZC,YAEP,WAAAh1D,CAAYg1D,GACV30D,KAAK20D,YAAcA,CACrB,CAEO,aAAAC,CACLj8B,EACAmG,EACAr9B,EAA6B,CAAA,GAE7B,MAAME,EAAYxB,OAAO6I,OAAO,CAAA,EAAIvH,EAAK,CAAEq9B,kBAE3C9+B,KAAK8wC,YAAYnY,EAAQh3B,EAAWhN,EAAkBO,UACxD,CAEO,WAAA47C,CAAYnY,EAAqBl3B,EAA4BozD,GAClE,MAAMlzD,EAAYxB,OAAO6I,OAAO,CAAA,EAAIvH,GAEpCE,EAAUysB,iBAAmB15B,EAC7BiN,EAAUm3B,WAAa+7B,EAGvBlzD,EAAUgmC,SAAW7mC,GAAMouB,IAAI/zB,UAAY,MAAQ2F,GAAMouB,IAAI3zB,eAAiBuF,GAAMouB,IAAI1zB,OAAS,SAAW,OAKxGmG,EAAUqsD,WACP7tD,OAAOC,KAAKuB,EAAUqsD,UAAUhrD,OAEU,IAApCrB,EAAUqsD,SAAS8D,qBACrBnwD,EAAUqsD,SAAS8D,oBAFnBnwD,EAAUqsD,UAMrB,MAAM8G,EAA8C,CAClDnpD,GAAI7K,GAAMmB,kBACVN,UAAWA,GAGb3B,KAAK20D,YAAYh5B,2BAA2BhD,EAAQm8B,EACtD,EChCY,MAAOC,GACZ7B,GAAoB,KACpB1hD,MAA0B7b,EAAiBC,IAI3CmpC,aAAyB,GACzB+yB,aAAuB,EACvBkD,gBAA8D,CAAA,EAC9DhS,YACA+C,YAAsC,CAAA,EAEtCkP,YAA8C,KAC9CC,0BAA4D,KAC5DvE,cAAwB,EACxBwE,eAAyB,EAOhC,WAAAx1D,CAAYyF,GACVjF,OAAO6I,OAAOhJ,KAAMoF,EAAQ,CAAE8tD,GAAI9tD,EAAO8tD,IAAMkC,MACjD,CAEO,qBAAMzpB,CAAgBvmC,GAC3B,IAAKxJ,GAAc+vC,gBACjB,MAAM,IAAI9gC,MAAM,2DAGlB,MAAM89C,EAAYvjD,GAAUA,EAAOujD,UAC7B5oD,EAAUqF,GAAUA,EAAOrF,QAC3BgmD,EAAc,IAAK3gD,GAEzBpF,KAAK+lD,YAAcA,SAEZA,EAAY4C,iBACZ5C,EAAYhmD,QAEnB,IACE,MAAM63C,QAAeh8C,EAAc+vC,gBAAgBoa,GAEnD,OADoB/lD,KAAK4oD,aAAahR,EAAQ+Q,EAAW5oD,EAE3D,CAAE,MAAOqB,GACP,MAAMA,CACR,CACF,CAEO,kBAAMi3C,CAAajzC,GACxB,IAAKxJ,GAAcy8C,aACjB,MAAM,IAAIxtC,MAAM,wDAGlB,MAAM89C,EAAYvjD,GAAUA,EAAOujD,UAC7B5oD,EAAUqF,GAAUA,EAAOrF,QAC3BgmD,EAAc,IAAK3gD,GAEzBpF,KAAK+lD,YAAcA,SAEZA,EAAY4C,iBACZ5C,EAAYhmD,QAEnB,IACE,MAAM63C,QAAeh8C,EAAcy8C,aAAa0N,GAEhD,OADoB/lD,KAAK4oD,aAAahR,EAAQ+Q,EAAW5oD,EAE3D,CAAE,MAAOqB,GACP,MAAMA,CACR,CACF,CAEQ,YAAAwnD,CAAahR,EAAqB+Q,EAAoB5oD,GAC5D,MAAM8oD,IAA8B7oD,KAAKgjD,YAQzC,GANI6F,EACF7oD,KAAK+2C,cAAca,GAEnB53C,KAAKgjD,YAAcpL,GAGhB53C,KAAKgjD,YACR,MAAM,IAAIn4C,MAAM,+BAuBlB,OApBI89C,IACEE,GACF7oD,KAAK8oD,kBAAkBH,EAAW5oD,GAEpCC,KAAK+oD,kBAAkBJ,EAAW3oD,KAAKgjD,YAAajjD,IAGtDC,KAAKgjD,YAAY9B,YAAY7gD,QAASmyC,IACpC,MAAMpzC,EAAOozC,EAAMC,KACbvO,EAAWsO,EAAMwW,cAAc9kB,SAEjCA,IACoC,iBAA3BlkC,KAAK+lD,YAAY3mD,GAC1BY,KAAK+lD,YAAY3mD,GAAM8kC,SAAWA,EAElClkC,KAAK+lD,YAAY3mD,GAAQ,CAAE8kC,eAK1BlkC,KAAKgjD,WACd,CAEQ,aAAAjM,CAAca,GA2BpB,GA1BA53C,KAAKgjD,aAAa9B,YAAY7gD,QAAS4oD,IACjCA,EAAWxW,OAASn4C,EAAUpE,OAA4C,IAAnC0hD,EAAOC,iBAAiB70C,SAGjEimD,EAAWttC,OACX3b,KAAKgjD,aAAatI,YAAYuO,MAIlCrR,EAAOsJ,YAAY7gD,QAAS6oD,IACtBA,EAASzW,OAASn4C,EAAUpE,MAC9BgzD,EAASl3B,QAAUhyB,KAAKgjD,aAAanL,iBAAiB3sB,MAAM,EAAG8G,aAAcA,KAAY,EAEzFk3B,EAASl3B,QAAUhyB,KAAKgjD,aAAalL,iBAAiB5sB,MAAM,EAAG8G,aAAcA,KAAY,EAGvFk3B,IACF/oD,OAAO2pB,OAAO9pB,KAAKg1D,iBAAiB30D,QAASmvC,IAC3CA,EAAG+C,aACAv1B,KAAK,EAAGw1B,WAAY0W,EAASzW,OAASD,GAAOC,OAC5CkF,aAAauR,KAEnBlpD,KAAKgjD,aAAarK,SAASuQ,OAI1BlpD,KAAKgjD,YACR,MAAM,IAAIn4C,MAAM,+BAGlB,OAAO7K,KAAKgjD,WACd,CAEO,qBAAMqS,CAAgBvD,GAC3B,MAAMwD,EAAQt1D,KAAKg1D,gBACbO,EAAYp1D,OAAOC,KAAKk1D,GAE9B,KAAIC,EAAUvyD,OAAS,GAKvB,OAAO0F,QAAQwT,IAAIq5C,EAAUriD,IAAKylB,GAAW28B,EAAM7+C,OAAOkiB,IAASs5B,4BAA4BH,KAJ7FrC,GAAc5jC,MAAM,+CAKxB,CAEO,sBAAA2pC,CAAuB78B,GAC5B,MAAM88B,EAAiBz1D,KAAKg1D,gBAAgBr8B,GAC5C,OAAO88B,EAAiBA,EAAejkD,MAAQ,IACjD,CAEO,iBAAAu3C,CAAkBJ,EAAmB/Q,EAAqB4R,GAC/D,MAAMC,EAAepuD,SAASquD,eAAef,GAE7C,KAAI,cAAec,GAcjB,MAAM,IAAI5+C,MAAM,2CAA2C89C,kBAb3Dc,EAAaE,UAAY/R,EACzB6R,EAAaG,MAAMC,UAAYL,GAAKM,OAAS,aAAe,OAClC,kBAAfN,GAAKvE,QACdwE,EAAaxE,MAAQuE,GAAKvE,OAE5BwE,EAAaM,iBAAmBz+C,MAAO0+C,IACrC,UACQP,EAAaQ,MACrB,CAAE,MAAO7oD,GACPD,QAAQC,MAAM,eAAgBA,EAChC,EAKN,CAEO,iBAAA0nD,CAAkBH,EAAmBa,GAC1C,MAAMC,EAAepuD,SAASquD,eAAef,GAE7C,KAAI,cAAec,GAQjB,MAAM,IAAI5+C,MAAM,2CAA2C89C,kBAP3Dc,EAAaS,QACbT,EAAaE,UAAY,KACzBF,EAAaG,MAAMC,UAAYL,GAAKM,OAAS,aAAe,OAClC,kBAAfN,GAAKvE,QACdwE,EAAaxE,MAAQuE,GAAKvE,MAKhC,CAEO,uBAAMmE,CAAkBrpD,EAA6C,IAC1Ee,GAAMgC,KAAK,qBAAsB/C,GAEjC,CAACzF,EAAUpE,MAAOoE,EAAUrE,OAAOoK,QAASjB,IAC1C,MAAMiqD,EAASjqD,IAAS9E,EAAUpE,MAAQ6J,EAAQs3C,MAAQj4C,IAAS9E,EAAUrE,MAAQ8J,EAAQu3C,MAAQ,CAAA,EAC/FpT,EAA6B,iBAAXmlB,EAAsBA,EAAUA,GAAQnlB,UAAY,KAExEA,IACyD,iBAAhDlkC,KAAK+lD,YAAY3mD,GACzBY,KAAK+lD,YAAY3mD,GAAqD8kC,SAAWA,EAElFlkC,KAAK+lD,YAAY3mD,GAA6B,CAAE8kC,eAKtD,IACE,MAAMwxB,EAAa,CAAEre,MAAOr3C,KAAK+lD,YAAY1O,QAAS,EAAOC,MAAOt3C,KAAK+lD,YAAYzO,QAAS,GACxFM,QAAeh8C,EAAcy8C,aAAaqd,GAEhD,OADoB11D,KAAK+2C,cAAca,EAEzC,CAAE,MAAOx2C,GACP,MAAMA,CACR,CACF,CAEO,IAAAX,CAAKkB,EAA4B,IACtC,MAAMF,EAAMk0D,GAAiBh0D,GAE7B8tD,GAAc5jC,MAAM,oBAAoB7wB,KAAK8I,UAAUrC,MAEvDzB,KAAKwR,MAAQ7b,EAAiBE,OAC9BmK,KAAK8xD,aAAer7C,OAAOhV,EAAIusD,UAAU8D,cAAgB,GACzD9xD,KAAK++B,aAAa1+B,QAASs4B,IACzB34B,KAAK41D,aAAaj9B,EAAQl3B,GAAK,IAEnC,CAEQ,kBAAMm0D,CACZj9B,EACAh3B,EACA0wD,GAEA,MAAM7iB,EAAK,IAAIygB,GAAqBjwD,KAAM24B,EAAQ,SAElD34B,KAAKgjD,aAAa9B,YAAY7gD,QAASmyC,IACrChD,EAAGmJ,SAASnG,EAAOxyC,KAAKgjD,eAG1BhjD,KAAKg1D,gBAAgBr8B,GAAU6W,EAE/B,UACQA,EAAGqiB,iCAAiC7xD,KAAK8xD,cAC/CrC,GAAc5jC,MAAM,4CACpB2jB,EAAG4iB,kBAAkBzwD,EAAW0wD,EAClC,CAAE,MAAOjxD,GACPquD,GAAcE,WAAW,2CAA2CvuD,IACtE,CACF,CAEO,MAAAy0D,CAAOl0D,EAA4B,IACxC,MAAMF,EAAMk0D,GAAiBh0D,GAI7B,GAFA8tD,GAAc5jC,MAAM,sBAAsB7wB,KAAK8I,UAAUrC,MAErDzB,KAAKwR,QAAU7b,EAAiBE,OAElC,YADA45D,GAAcE,WAAW,uDAI3B,GAAI3vD,KAAKwR,QAAU7b,EAAiBF,OAGlC,OAFAg6D,GAAcE,WAAW,4DACzB3vD,KAAK2b,KAAK,IAIZ3b,KAAKwR,MAAQ7b,EAAiBE,OAC9BmK,KAAKm1D,eAAiBzyD,KAAKC,MAC3B3C,KAAK81D,mBACL91D,KAAK+1D,eAAe/1D,KAAKg2D,YAAav0D,GAGtC,MAAMs9B,EAAe/+B,KAAK++B,aAAa5vB,OAAQwpB,GAAWA,IAAW34B,KAAKi2D,eAEtEl3B,EAAa/7B,OAAS,IACxBhD,KAAKk2D,iCACLn3B,EAAa1+B,QAASypC,IAChB9pC,KAAKi2D,cAAgBnsB,GACvB9pC,KAAK41D,aAAa9rB,EAAYroC,GAAK,KAI3C,CAEQ,oBAAMs0D,CAAep9B,EAAgBh3B,GAC3C,MAAM6tC,EAAKxvC,KAAKg1D,gBAAgBr8B,GAEhC,GAAK6W,GAAOA,EAAGyjB,UAAf,CAKAjzD,KAAKgjD,aAAa9B,YAAY7gD,QAASmyC,IACrChD,EAAGmJ,SAASnG,EAAOxyC,KAAKgjD,eAG1B,UACQxT,EAAGkjB,4BAA4B,QAASljB,EAAGyjB,WACjDxD,GAAc5jC,MAAM,+CACd2jB,EAAGqiB,iCAAiC7xD,KAAK8xD,cAC/CrC,GAAc5jC,MAAM,8CAEpB,MAAMpqB,EAAMtB,OAAO6I,OAAO,CAAA,EAAIrH,EAAW,CACvCk3B,UAAW74B,KAAKkzD,GAChBlC,SAAUhxD,KAAKgxD,SACfmF,SAAUn2D,KAAKg2D,YACfj3B,aAAc/+B,KAAK++B,aACnBiS,IAAKxB,EAAGkF,kBAAkB1D,MAG5BhxC,KAAKo2D,kBAAkBtlB,YAAYnY,EAAQl3B,EAAK9M,EAAkBE,OACpE,CAAE,MAAOuM,GACPquD,GAAcE,WAAW,2BAA2BvuD,IACtD,CAvBA,MAFEquD,GAAcE,WAAW,sFA0B7B,CAEO,MAAA/mD,CAAOjH,EAA4B,IACxC,MAAMF,EAAMk0D,GAAiBh0D,GAE7B8tD,GAAc5jC,MAAM,sBAAsB7wB,KAAK8I,UAAUrC,EAAIusD,aAE7DhuD,KAAKwR,MAAQ7b,EAAiBI,SAC9BiK,KAAK81D,mBACL31D,OAAO6I,OAAOvH,EAAK,CACjBo3B,UAAW74B,KAAKkzD,GAChBlC,SAAUhxD,KAAKgxD,SACfmF,SAAUn2D,KAAKg2D,YACfj3B,aAAc/+B,KAAK++B,eAGrB5+B,OAAOC,KAAKJ,KAAKg1D,iBAAiB30D,QAASs4B,IACzC34B,KAAKo2D,kBAAkBtlB,YAAYr6B,OAAOkiB,GAASl3B,EAAK9M,EAAkBG,UAG5EkL,KAAKma,OACP,CAEO,IAAAwB,CAAKha,EAA4B,IACtC,MAAMF,EAAMk0D,GAAiBh0D,GAE7B8tD,GAAc5jC,MAAM,oBAAoB7wB,KAAK8I,UAAUrC,EAAIusD,aAE3DhuD,KAAKwR,MAAQ7b,EAAiBG,QAE1BkK,KAAKi1D,aACPj1D,KAAK81D,mBAGP31D,OAAO6I,OAAOvH,EAAK,CACjBo3B,UAAW74B,KAAKkzD,GAChBlC,SAAUhxD,KAAKgxD,SACfmF,SAAUn2D,KAAKg2D,YACfj3B,aAAc/+B,KAAK++B,eAGrB5+B,OAAOC,KAAKJ,KAAKg1D,iBAAiB30D,QAASs4B,IACzC34B,KAAKo2D,kBAAkBtlB,YAAYr6B,OAAOkiB,GAASl3B,EAAK9M,EAAkBI,QAG5EiL,KAAKma,OACP,CAEO,qBAAAk8C,CAAsB19B,GAC3B,MAA8C,UAAvC34B,KAAKg1D,gBAAgBr8B,IAASv5B,IACvC,CAEO,gBAAMw3C,CAAWje,GACtB,MAAM6W,EAAKxvC,KAAKg1D,gBAAgBr8B,GAEhC,GAAK6W,EAKL,IACE,MAAMwB,IAAEA,SAAcxB,EAAGqiB,iCAAiC7xD,KAAK8xD,cAAc,GACvErwD,EAAM,CAAEo3B,UAAW74B,KAAKkzD,IAAM,GAAIliB,OACxChxC,KAAKo2D,kBAAkBtlB,YAAYnY,EAAQl3B,EAAK9M,EAAkBK,SAClEy6D,GAAc5jC,MAAM,kBACtB,CAAE,MAAOzqB,GACPquD,GAAcE,WAAW,uBAAuBvuD,IAClD,MAXEquD,GAAcE,WAAW,kFAY7B,CAEO,aAAA2G,CAAcH,EAAkBx0D,GAChB,CAAC3B,KAAKg2D,eAAgBh2D,KAAK++B,aAAa5vB,OAAQwpB,GAAWA,IAAW34B,KAAKi2D,gBAEnF51D,QAASypC,IACpB,MAAM0F,EAAKxvC,KAAKg1D,gBAAgBlrB,GAEhC,GAAI0F,EACE1F,IAAeqsB,IACjB3mB,EAAGyjB,UAAYtxD,EAAUqvC,KAAO,GAE5BmlB,IAAan2D,KAAKg2D,aAAeh2D,KAAKwR,QAAU7b,EAAiBE,QACnEmK,KAAK+1D,eAAeI,EAAUx0D,QAG7B,CAEL,MAAM40D,EAAazsB,IAAeqsB,GAAYn2D,KAAKi2D,cAAgBnsB,EAAa,QAAU,SACpF0F,EAAK,IAAIygB,GAAqBjwD,KAAM8pC,EAAYysB,GAEtDv2D,KAAKg1D,gBAAgBlrB,GAAc0F,EAE/B1F,IAAeqsB,IACjB3mB,EAAGyjB,UAAYtxD,EAAUqvC,KAAO,GAChChxC,KAAKw2D,mBAET,GAEJ,CAEO,qBAAMC,CAAgB99B,EAAgBh3B,GAC3C,MAAM6tC,EAAKxvC,KAAKg1D,gBAAgBr8B,GAE3B6W,GACHigB,GAAcC,aAAa,mFAG7B,IACElgB,EAAGoiB,0BACGpiB,EAAGkjB,4BAA4B,SAAU/wD,EAAUqvC,KAAO,IAChEye,GAAc5jC,MAAM,wCACtB,CAAE,MAAOzqB,GACPquD,GAAcE,WAAW,wCAAwCvuD,IACnE,CACF,CAEO,eAAAs1D,CAAgB/9B,GACrB,MAAM6W,EAAKxvC,KAAKg1D,gBAAgBr8B,GAEhC34B,KAAK22D,iCAEDnnB,EACFA,EAAGgiB,UAEH/B,GAAcC,aAAa,mFAG7B1vD,KAAKyxD,oCACP,CAEO,aAAAmF,CAAcj+B,GAInB,GAHA34B,KAAK81D,mBAGDn9B,IAAW34B,KAAKg2D,YAAa,CAC/B,MAAMa,EAAS12D,OAAOC,KAAKJ,KAAKg1D,iBAC5B6B,EAAO7zD,OAAS,EAClB6zD,EAAOx2D,QAASC,IACdN,KAAKg1D,gBAAgBv+C,OAAOnW,IAAMkxD,YAGpC/B,GAAcC,aAAa,iFAE/B,KAAO,CACL,MAAMlgB,EAAKxvC,KAAKg1D,gBAAgBr8B,GAC5B6W,EACFA,EAAGgiB,UAEH/B,GAAcC,aAAa,gFAE/B,CAEA1vD,KAAKyxD,oCACP,CAEO,4BAAMqF,CAAuBn+B,EAAgBh3B,GAClD,MAAM6tC,EAAKxvC,KAAKg1D,gBAAgBr8B,GAE3B6W,GACHigB,GAAcC,aACZ,0FAIA/tD,EAAUm9B,qBACN0Q,EAAGmiB,cAAchwD,EAAUm9B,cAErC,CAEO,yBAAMi4B,CAAoBp+B,EAAgBh3B,GAC/C,MAAM6tC,EAAKxvC,KAAKg1D,gBAAgBr8B,GAE3B6W,GACHigB,GAAcC,aAAa,uFAG7B,UACQlgB,EAAGkjB,4BAA4B,QAAS/wD,EAAUqvC,KAAO,IAC/D,MAAMA,IAAEA,SAAcxB,EAAGqiB,iCAAiC7xD,KAAK8xD,cACzDrwD,EAAM,CAAEo3B,UAAW74B,KAAKkzD,IAAM,GAAIliB,OACxChxC,KAAKo2D,kBAAkBtlB,YAAYnY,EAAQl3B,EAAK9M,EAAkBM,gBAClEw6D,GAAc5jC,MAAM,gCACtB,CAAE,MAAOzqB,GACPquD,GAAcE,WAAW,gCAAgCvuD,IAC3D,CACF,CAEO,+BAAM41D,CAA0Br+B,EAAgBh3B,GACrD,MAAM6tC,EAAKxvC,KAAKg1D,gBAAgBr8B,GAE3B6W,GACHigB,GAAcC,aACZ,6FAIJ,UACQlgB,EAAGkjB,4BAA4B,SAAU/wD,EAAUqvC,KAAO,IAChEye,GAAc5jC,MAAM,sCACtB,CAAE,MAAOzqB,GACPquD,GAAcE,WAAW,sCAAsCvuD,IACjE,CACF,CAEO,WAAAqxD,CAAYgD,EAAsC9zD,EAAmC,IAC1F,MAAMF,EAAMtB,OAAO6I,OAAO,CAAEglD,SAAU,CAAA,GAAMrsD,EAAW,CACrDk3B,UAAW74B,KAAKkzD,GAChBlC,SAAUhxD,KAAKgxD,SACfmF,SAAUn2D,KAAKg2D,YACfj3B,aAAc/+B,KAAK++B,aACnBiS,IAAKykB,EAAe/gB,kBAAkB1D,MAGxChxC,KAAKo2D,kBAAkBtlB,YAAY2kB,EAAe98B,OAAQl3B,EAAK9M,EAAkBC,KACnF,CAEO,oBAAAw8D,CAAqBz4B,EAAgBmG,GAC1C,MAAMn9B,EAAY,CAChBk3B,UAAW74B,KAAKkzD,IAAM,GACtBlC,SAAUhxD,KAAKgxD,SACfmF,SAAUn2D,KAAKg2D,YACfj3B,aAAc/+B,KAAK++B,cAGrB/+B,KAAKo2D,kBAAkBxB,cAAcj8B,EAAQmG,EAAen9B,EAC9D,CAEO,kBAAA6wD,CAAmBiD,GACxBhG,GAAc5jC,MAAM,uCAAuC7rB,KAAKkzD,eAAeuC,EAAe98B,UAE9F34B,KAAK22D,iCACLlB,EAAejE,UACf1wD,GAAMC,iBAAiBf,KAAKi3D,wBAA5Bn2D,CAAqDd,KAAMy1D,EAAe98B,QAC1E34B,KAAKyxD,oCACP,CAEO,cAAAvK,CAAevuB,EAAgBif,GACpC92C,GAAMC,iBAAiBf,KAAKsoD,uBAA5BxnD,CAAoDd,KAAM24B,EAAQif,EACpE,CAEO,iBAAAob,CAAkBr6B,EAAgBwiB,EAAgB/5C,GACvDN,GAAMC,iBAAiBf,KAAKk3D,0BAA5Bp2D,CAAuDd,KAAM24B,EAAQwiB,EAAO/5C,EAC9E,CAEO,+BAAAiwD,CAAgC14B,EAAgBw+B,GACrDr2D,GAAMC,iBAAiBf,KAAKooD,wCAA5BtnD,CAAqEd,KAAM24B,EAAQw+B,EACrF,CAEQ,KAAAh9C,GACNha,OAAO2pB,OAAO9pB,KAAKg1D,iBAAiB30D,QAASmvC,IAC3C,IACEA,EAAGgiB,SACL,CAAE,MAAOnnC,GACPvpB,GAAMgC,KAAK,qBAAqBunB,IAClC,IAGFrqB,KAAKo3D,wBACLp3D,KAAKwR,MAAQ7b,EAAiBF,OAC9BqL,GAAMC,iBAAiBf,KAAKq3D,uBAA5Bv2D,CAAoDd,KACtD,CAEO,kCAAAyxD,GACL,MAAM6F,EAAcn3D,OAAO2pB,OAAO9pB,KAAKg1D,iBAAiB9pC,MAAOskB,IAC7D,IAME,MAAiC,WAA1BA,EAAG8E,oBAAyD,WAAtB9E,EAAG0hB,gBAA+B1hB,EAAG+gB,QACpF,CAAE,MAAOrvD,GAGP,OAFAuuD,GAAcE,WAAW9nD,OAAO3G,KAEzB,CACT,IAGFuuD,GAAc5jC,MAAM,gCAAgCyrC,KAEhDA,IACFt3D,KAAKo3D,wBACLt2D,GAAMC,iBAAiBf,KAAKq3D,uBAA5Bv2D,CAAoDd,MACpDA,KAAKwR,MAAQ7b,EAAiBF,OAElC,CAEQ,qBAAA2hE,GACFp3D,KAAKgjD,cACPhjD,KAAKgjD,YAAY9B,YAAY7gD,QAASmyC,GAAUA,EAAM72B,QACtD3b,KAAKgjD,iBAActnD,EACnBsE,KAAK+lD,YAAc,CAAA,EAEvB,CAEO,IAAAxK,CAAKn8C,GACVY,KAAKu3D,YAAW,EAAOn4D,EACzB,CAEO,MAAAo4D,CAAOp4D,GACZY,KAAKu3D,YAAW,EAAMn4D,EACxB,CAEQ,UAAAm4D,CAAWvlC,EAAkB5yB,EAAkB9E,EAAUC,MAC/D,MAAMg5C,EACJn0C,IAAS9E,EAAUpE,MACf8J,KAAKgjD,aAAanL,iBAClBz4C,IAAS9E,EAAUrE,MACjB+J,KAAKgjD,aAAalL,iBAClB,GAERvE,GAAQlzC,QAASmyC,IACfA,EAAMxgB,QAAUA,GAEpB,CAEQ,gBAAA8jC,GACF91D,KAAKi1D,cACPxF,GAAc5jC,MAAM,oBACpB5Y,aAAajT,KAAKi1D,aAClBj1D,KAAKi1D,YAAc,KAEvB,CAEQ,gBAAAuB,GACN/G,GAAc5jC,MAAM,oBAEpB7rB,KAAKi1D,YAAcpiD,WACjB,KACE48C,GAAc5jC,MAAM,yBACpB7rB,KAAKma,QACLna,KAAKi1D,YAAc,MAEyB,KAA7Cp0D,EAAOpD,UAAUE,oBAAsB,IAE5C,CAEQ,8BAAAg5D,GACF32D,KAAKk1D,4BACPzF,GAAc5jC,MAAM,kCACpB5Y,aAAajT,KAAKk1D,2BAClBl1D,KAAKk1D,0BAA4B,KAErC,CAEQ,8BAAAgB,GACN,MAAMv4D,EAAqBkD,EAAOpD,UAAUE,oBAAsB,GAC5D85D,GAAYz3D,KAAKm1D,eAAiBn1D,KAAK2wD,eAAiB,IACxD+G,EAAWt1D,KAAKu1D,IAAIF,EAAU95D,EAAqB,GACnD8B,EAAU2C,KAAKw1D,IAAIj6D,EAAqB+5D,EAAU,GAExDjI,GAAc5jC,MAAM,4CAA4CpsB,KAEhEO,KAAKk1D,0BAA4BriD,WAAW,KAC1C48C,GAAc5jC,MAAM,uCAEpB1rB,OAAO2pB,OAAO9pB,KAAKg1D,iBAAiB30D,QAASmvC,IACvCA,EAAGh+B,QAAU7a,EAAoBtB,YAAcm6C,EAAGh+B,QAAU7a,EAAoBf,KAClFoK,KAAKwyD,mBAAmBhjB,KAI5BxvC,KAAKk1D,0BAA4B,MACtB,IAAVz1D,EACL,CAEO,QAAA4B,GACL,MAAO,OAAOrB,KAAKkzD,oBAAoBlzD,KAAKg2D,8BAA8Bh2D,KAAK++B,wBAAwB/+B,KAAKwR,oBAAoBxR,KAAKgxD,UACvI,EAGF,SAASoE,KACP,IAAIp1B,EAAIt9B,KAAKC,MAMb,MALa,uCAAuCyB,QAAQ,QAAU2D,IACpE,MAAMmiB,GAAM8V,EAAoB,GAAhB59B,KAAKE,UAAiB,GAAM,EAE5C,OADA09B,EAAI59B,KAAKC,MAAM29B,EAAI,KACN,KAALj4B,EAAWmiB,EAAS,EAAJA,EAAW,GAAK7oB,SAAS,KAGrD,CAEA,SAASs0D,GAAiBh0D,EAA4B,IACpD,MAAMF,EAAM,CAAEusD,SAAUrsD,GAExB,IACMb,GAAMiB,SAASJ,GACjBF,EAAIusD,SAAWltD,GAAMkD,YAAYrC,GAAW,GAE5C8tD,GAAcC,aAAa,+CAE/B,CAAE,MAAOxuD,GACPuuD,GAAcC,aAAaxuD,aAAe2J,MAAQ3J,EAAI2K,QAAUhE,OAAO3G,GACzE,CAEA,OAAOO,CACT,CCtsBc,MAAOo2D,GACZlD,YACAlqD,MACAqtD,mBACA1B,kBACA2B,uBAA4D5iE,EAC5DwB,oBAAkDA,EAClDX,SAA4BA,EAC5Bw1C,SAA6C,CAAA,EAW7CwsB,wBAAyD,OAEhE,WAAAr4D,CAAYg1D,EAAkClqD,GAC5CzK,KAAK20D,YAAcA,EACnB30D,KAAKyK,MAAQA,EAEbzK,KAAK83D,mBAAqB,IAAIt/B,GAAyBx4B,MACvDA,KAAKo2D,kBAAoB,IAAI1B,GAAwB10D,KAAK20D,aAEtD/4D,IACFA,EAAaq8D,eAAiBn3D,GAAMC,iBAAiBf,KAAKg4D,yBAE9D,CAEA,iBAAY/B,GACV,OAAOj2D,KAAK20D,YAAYlwD,aAC1B,CAEO,qBAAM8lD,CAAgB9X,GAC3B,GAAI72C,GAAc4lD,iBAAkB,CAClC,MAAMC,QAAgB7lD,EAAa4lD,mBACnC,OAAO/O,EAAOgP,EAAQtyC,OAAQk6C,GAAWA,EAAO5W,OAASA,GAAQgP,CACnE,CACE,MAAM,IAAI52C,MAAM,sCAEpB,CAEO,gBAAAw/C,CACLtrB,EACAiyB,EACAjxD,GAEA,MAAM+xD,GAAgB/xD,GAAS+xD,cAAgB/xD,GAASm4D,YAAc,EAEtE,IAAKn5B,EACH,MAAM,IAAIl0B,MAAM,+CAGlB,OAAO7K,KAAKm4D,sBAAsB,KAAMn4D,KAAKi2D,cAAel3B,EAAciyB,EAAUc,EACtF,CAEQ,qBAAAqG,CACNt/B,EACAm9B,EACAj3B,EACAiyB,EACAc,EAAuB,GAEvB,MAAMsG,EAAgB,IAAIrD,GAAc,CACtC7B,GAAIr6B,EACJm9B,cACAj3B,eACAiyB,WACAoF,kBAAmBp2D,KAAKo2D,kBACxBH,cAAej2D,KAAKi2D,cACpBnE,iBAaF,OAVAsG,EAAcnB,wBAA0Bj3D,KAAKi3D,wBAC7CmB,EAAc9P,uBAAyBtoD,KAAKsoD,uBAC5C8P,EAAchQ,wCAA0CpoD,KAAKooD,wCAC7DgQ,EAAcf,uBAAyBr3D,KAAKq3D,uBAC5Ce,EAAclB,0BAA4Bl3D,KAAKgzD,kBAE3CoF,GAAelF,KACjBlzD,KAAKwrC,SAAS4sB,EAAclF,IAAMkF,GAG7BA,CACT,CAEO,YAAA5N,CAAa5xB,UACX54B,KAAKwrC,SAAS5S,EACvB,CAGO,iBAAAy/B,CAAkBjzD,GAMvB,MAAM0F,EAAa,CACjB1L,KAAM5E,EAAYE,KAClB4K,IAAKxE,GAAMQ,OAAOT,EAAO7C,KAAKmB,MAAO,UACrCL,KAAMsG,GAGR,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAIO,aAAAiuB,CAAcJ,EAAgBE,EAAmBl3B,GACtD,MAAMqsD,EAAWrsD,EAAUqsD,UAAY,CAAA,EACjC8D,EAAer7C,OAAOu3C,EAAS8D,cAAgB,GAErD,IAAItzD,EAAUwB,KAAKwrC,SAAS3S,GAE5B42B,GAAc5jC,MAAM,mBAAmB8M,iBAAsBE,iBAAyB79B,KAAK8I,UAAUnC,MAEhGnD,IACHA,EAAUwB,KAAKm4D,sBACbt/B,EACAl3B,EAAUw0D,UAAY,EACtBx0D,EAAUo9B,cAAgB,GACzBp9B,EAAUqvD,UAAyBh7D,EAASC,MAC7C67D,GAGFhxD,GAAMC,iBAAiBf,KAAKs4D,eAA5Bx3D,CAA4CtC,EAASwvD,IAGvDxvD,EAAQ83D,cAAc39B,EAAQh3B,EAChC,CAEO,eAAAq3B,CAAgBL,EAAgBE,EAAmBl3B,GACxD,MAAMnD,EAAUwB,KAAKwrC,SAAS3S,GACxBm1B,EAAWrsD,EAAUqsD,UAAY,CAAA,EAEvCyB,GAAc5jC,MACZ,qBAAqB8M,iBAAsBE,iBAAyB79B,KAAK8I,UAAUnC,OAGjFnD,GAAYA,EAAQgT,QAAU7b,EAAiBE,QAAU2I,EAAQgT,QAAU7b,EAAiBC,IAI9F65D,GAAcC,aAAa,4DAA4D72B,MAHvF/3B,GAAMC,iBAAiBf,KAAKu4D,qBAA5Bz3D,CAAkDtC,EAASm6B,EAAQq1B,GACnExvD,EAAQi4D,gBAAgB99B,EAAQh3B,GAIpC,CAEO,eAAAs3B,CAAgBN,EAAgBE,EAAmBl3B,GACxD,MAAMnD,EAAUwB,KAAKwrC,SAAS3S,GAM9B,GAJA42B,GAAc5jC,MACZ,qBAAqB8M,iBAAsBE,iBAAyB79B,KAAK8I,UAAUnC,MAGjFnD,EAAS,CACX,MAAMwvD,EAAWrsD,EAAUqsD,UAAY,CAAA,EAEvCltD,GAAMC,iBAAiBf,KAAKw4D,qBAA5B13D,CAAkDtC,EAASm6B,EAAQq1B,GACnExvD,EAAQk4D,gBAAgB/9B,EAC1B,MACE82B,GAAcC,aAAa,4DAA4D72B,IAE3F,CAEO,aAAAK,CAAcP,EAAgBE,EAAmBl3B,GACtD8tD,GAAc5jC,MAAM,mBAAmB8M,iBAAsBE,iBAAyB79B,KAAK8I,UAAUnC,MAErG,MAAMnD,EAAUwB,KAAKwrC,SAAS3S,GACxBm1B,EAAWrsD,EAAUqsD,UAAY,CAAA,GAEnCxvD,GAAYA,EAAQgT,QAAU7b,EAAiBE,QAAU2I,EAAQgT,QAAU7b,EAAiBC,KAI9FkL,GAAMC,iBAAiBf,KAAKy4D,wBAA5B33D,CAAqDtC,EAASm6B,EAAQq1B,GACtEyB,GAAcC,aAAa,0DAA0D72B,sBAJrFr6B,EAAQo4D,cAAcj+B,GACtB73B,GAAMC,iBAAiBf,KAAK04D,mBAA5B53D,CAAgDtC,EAASm6B,EAAQq1B,GAKrE,CAEO,sBAAA70B,CAAuBR,EAAgBE,EAAmBl3B,GAC/D,MAAMnD,EAAUwB,KAAKwrC,SAAS3S,GAE9B42B,GAAc5jC,MACZ,4BAA4B8M,iBAAsBE,4BAChDl3B,EAAUm9B,eAAe97B,QAAU,KAInCxE,EACEA,EAAQgT,QAAU7b,EAAiBE,OACrC2I,EAAQs4D,uBAAuBn+B,EAAQh3B,GAEvC8tD,GAAcC,aAAa,2CAA2C72B,yBAGxE42B,GAAcC,aAAa,mEAAmE72B,IAElG,CAEO,mBAAAO,CAAoBT,EAAgBE,EAAmBl3B,GAC5D,MAAMnD,EAAUwB,KAAKwrC,SAAS3S,GAE9B42B,GAAc5jC,MACZ,yBAAyB8M,iBAAsBE,iBAAyB79B,KAAK8I,UAAUnC,MAGrFnD,EACEA,EAAQgT,QAAU7b,EAAiBE,OACrC2I,EAAQu4D,oBAAoBp+B,EAAQh3B,GAEpC8tD,GAAcC,aAAa,uCAAuC72B,wBAGpE42B,GAAcC,aAAa,gEAAgE72B,IAE/F,CAEO,yBAAAQ,CAA0BV,EAAgBE,EAAmBl3B,GAClE,MAAMnD,EAAUwB,KAAKwrC,SAAS3S,GAE9B42B,GAAc5jC,MACZ,+BAA+B8M,iBAAsBE,iBAAyB79B,KAAK8I,UAAUnC,MAG3FnD,EACEA,EAAQgT,QAAU7b,EAAiBE,OACrC2I,EAAQw4D,0BAA0Br+B,EAAQh3B,GAE1C8tD,GAAcC,aAAa,6CAA6C72B,wBAG1E42B,GAAcC,aAAa,sEAAsE72B,IAErG,CAEQ,iBAAAsB,CAAkBrzB,GACxB,OAAQA,GACN,KAAK3Q,EAAUvB,KACb,MAAO,iBACT,KAAKuB,EAAUtB,OACb,MAAO,uBACT,KAAKsB,EAAUrB,OACb,MAAO,uBACT,KAAKqB,EAAUpB,KACb,MAAO,qBACT,KAAKoB,EAAUC,QACb,MAAO,0BACT,KAAKD,EAAUE,WACb,MAAO,0BACT,KAAKF,EAAUG,cACb,MAAO,yBACT,KAAKH,EAAUI,iBACb,MAAO,0CACT,KAAKJ,EAAUK,MACb,MAAO,yBACT,KAAKL,EAAUM,aACb,MAAO,oBACT,KAAKN,EAAUO,QACb,MAAO,0BACT,QACE,OAAO,KAEb,CAEO,WAAA6c,CAAYzM,EAAiB2N,GAClC,MAAM2lB,EAAep6B,KAAKm6B,kBAAkBrzB,GAI5C,OAHIszB,IACDp6B,KAAKo6B,GAAoC3lB,GAErCzU,KAAK2T,eAAeH,KAAKxT,KAAM8G,EACxC,CAEO,cAAA6M,CAAe7M,GACpB,MAAMszB,EAAep6B,KAAKm6B,kBAAkBrzB,GACxCszB,IACDp6B,KAAKo6B,GAAgDtzB,IAAS3Q,EAAUO,QAAU,YAAWgF,EAElG,CAEO,kBAAA2+B,GACLl6B,OAAOC,KAAKJ,MAAMK,QAASC,IACrBA,EAAI+R,WAAW,OAAS/R,EAAIg2B,SAAS,aAA0D,mBAApCt2B,KAAKM,KACjEN,KAAKM,GACI,4BAARA,EAAoC,YAAW5E,IAGvD,EC/SY,MAAOi9D,GACZluD,MACEC,MAAQ7J,EAAO7C,KAAKiB,YACpBb,OAASyC,EAAOvC,WAAWF,OAEpC,WAAAuB,CAAY8K,GACVzK,KAAKyK,MAAQA,CACf,CAEO,MAAAmuD,EAAOjtD,GAAEA,EAAEktD,MAAEA,EAAK56D,SAAEA,IACzB,MAAO,GAAG+B,KAAK5B,uBAAuBuN,cAAe1N,WAAkB46D,GACzE,CAEO,SAAM7tD,CAAI8tD,GACf,MAAMhuD,EAAa,CACjB1L,KAAM5E,EAAYC,IAClB6K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,OACvB5L,KAA4B,iBAAfg6D,EAA0B,CAAEC,eAAgBD,GAAeA,GAG1E,OAAO94D,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,YAAM0Z,CAAOpf,GAClB,MAAM0F,EAAa,CACjB1L,KAAM5E,EAAYE,KAClB4K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,OACvB5L,KAAMsG,GAGR,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,YAAMgd,CAAOnc,EAAYvG,GAC9B,MAAM0F,EAAa,CACjB1L,KAAM5E,EAAYG,IAClB2K,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOiB,GAC9B7M,KAAMsG,GAGR,OAAOpF,KAAKyK,MAAMhC,KAAKqC,EACzB,CAEO,YAAM,CAAOa,GAClB,MAAMb,EAAa,CACjB1L,KAAM5E,EAAYK,OAClByK,IAAKxE,GAAMQ,OAAOtB,KAAK0K,MAAOiB,GAC9BtC,SAAUtO,EAAUE,MAGtB,OAAO+E,KAAKyK,MAAMhC,KAAKqC,EACzB,ECpDY,MAAOkuD,GACZvuD,MACAihB,MAA0B,IAAInP,IAE5B7R,MAAQ7J,EAAO7C,KAAKkB,OACpBd,OAASyC,EAAOtC,YAAYH,OAErC,WAAAuB,CAAY8K,GACVzK,KAAKyK,MAAQA,CACf,CAEO,SAAMO,CAAI1F,GACf,IAAKtF,KAAK0rB,MAAM9O,IAAItX,GAAM,CACxB,IAAI2zD,EAA2B,CAAE3zD,MAAKuzD,MAAO,GAAI9xB,YAAa,GAAImyB,OAAQ,IAE1E,IACE,MAAMpuD,EAAa,CACjB1L,KAAM5E,EAAYE,KAClB4K,IAAK,GAAGtF,KAAK5B,UAAU4B,KAAK0K,QAC5B5L,KAAM,CAAEwG,QAGV2zD,QAAqBj5D,KAAKyK,MAAMhC,KAAKqC,EACvC,CAAE,MAAO1J,GACP63D,EAAYJ,MAAQ74D,KAAKm5D,eAAe7zD,EAC1C,CAEAtF,KAAK0rB,MAAM5rB,IAAIwF,EAAK2zD,EACtB,CAEA,OAAOj5D,KAAK0rB,MAAM1gB,IAAI1F,EACxB,CAEQ,cAAA6zD,CAAe7zD,GACrB,GAAmB,mBAARwT,IACT,OAAO,IAAIA,IAAIxT,GAAKsT,SAGtB,MAAMrM,EAAQjH,EAAIiH,MAAM,6BACxB,OAAOA,EAAQA,EAAM,GAAKjH,CAC5B,ECzBY,MAAO8zD,GAGV58D,QAAkBtB,EAClBysC,SAAmBxsC,EAAY,UAAuB,OACtDiB,kBAA6BA,EA6B/B,IAAAkwC,CAAKhoB,EAAiC+0C,EAA4B,IACnEA,GAAkC,iBAAdA,GACtBx4D,EAAOf,IAAIu5D,GAGbr5D,KAAK0oB,MAAQ5nB,GACbd,KAAK0a,QAAU,IAAIpW,GACnBtE,KAAK2lB,KAAO,IAAIva,GAAYpL,KAAK0a,SACjC1a,KAAKtB,MAAQ,IAAI2vD,GAAaruD,KAAK0a,SACnC1a,KAAKs5D,QAAU,IAAIjN,GAAersD,KAAK0a,SACvC1a,KAAKu5D,kBAAoB,IAAItN,GAAyBjsD,KAAK0a,SAC3D1a,KAAKlB,KAAO,IAAI4rD,GAAY1qD,KAAK0a,SACjC1a,KAAKjB,YAAc,IAAIyL,GAAmBxK,KAAK0a,SAC/C1a,KAAKlD,KACH+D,EAAO/D,KAAKU,SAAWzE,EAASC,KAAO,IAAI6vC,GAAgB7oC,KAAK0a,SAAW,IAAI4f,GAAgBt6B,KAAK0a,SAEtG1a,KAAKw5D,QAAU,IAAInO,GAAgBrrD,KAAK0a,SACxC1a,KAAK1B,WAAa,IAAIq6D,GAAkB34D,KAAK0a,SAC7C1a,KAAKzB,YAAc,IAAIy6D,GAAmBh5D,KAAK0a,SAE3Cte,IACF4D,KAAKvC,UAAY,IAAIo6D,GAAa73D,KAAKlD,KAAMkD,KAAK0a,SAClD1a,KAAKlD,KAAK6hC,yBAA2B3+B,KAAKvC,UAAUq6D,mBACpD93D,KAAKy5D,oBAAsB,IAAItP,GAAiBnqD,KAAK0a,UAGnD4J,EAAY1e,OACd/E,EAAOpE,MAAMC,MAAQ4nB,EAAY5nB,MACjCsD,KAAK0a,QAAQ7V,WAAW,CAAEe,MAAO0e,EAAY1e,UAE7C/E,EAAOpE,MAAMC,MAAQ4nB,EAAY5nB,MACjCmE,EAAOpE,MAAME,QAAU2nB,EAAY3nB,SAGrCqD,KAAK6E,WAAa7E,KAAK2lB,KAAK9gB,WAC5B7E,KAAKgF,WAAahF,KAAK2lB,KAAK3gB,WAC5BhF,KAAKuL,cAAgBvL,KAAK2lB,KAAKpa,cAC/BvL,KAAKyL,eAAiBzL,KAAK2lB,KAAKla,eAChCzL,KAAKvB,MAAQuB,KAAK2lB,KAAKlnB,MACvBuB,KAAK4L,OAAS5L,KAAK2lB,KAAK/Z,MAC1B,EC3FF,MAAM8tD,GAA6B,IAAIN,GAEvCM,GAAaN,aAAeA,mC1HFW,CACrCO,QAAS,EACTC,KAAM,wU2HHsB,CAC5BC,OAAQ,SACRC,KAAM,OACNC,OAAQ,SACRl/D,OAAQ,uCAI0B,CAClCm/D,KAAM,OACNC,MAAO,QACPC,YAAa,cACbC,gBAAiB,kBACjBC,mBAAoB,uECLQ,CAC5BC,IAAK,MACLC,QAAS,UACTC,IAAK,8BCcuB,CAC5B3gE,QAAS,aACT4gE,QAAS,aACTC,aAAc,6CAnBU,CACxBC,OAAQ,EACRC,MAAO,EACPC,QAAS,EACTC,UAAW,EACXC,QAAS,0IAI6B,CACtCC,KAAM,OACNC,UAAW,YACXlB,KAAM,mCCpB0B,CAChCmB,SAAU,WACVC,QAAS,UACTC,eAAgB,iBAChBC,eAAgB,gECLe,CAC/BC,QAAS,UACTC,MAAO,QACPC,KAAM,OACNC,KAAM,qCHJ2B,CACjCC,KAAM,OACNC,KAAM,YACNC,IAAK,MACLpB,IAAK,mIAWwB,CAC7BqB,IAAK,cACLC,KAAM","x_google_ignoreList":[13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,91,92,102]}