{"version":3,"file":"index.mjs","names":["Cookies","createAxios","renewRefreshToken","createRequest","Cookies","createFetch","Cookies","createAxiosRequest","createFetchRequest"],"sources":["../src/services/auth.ts","../src/services/token.ts","../src/services/blocklet.ts","../src/services/user-session.ts","../src/services/component.ts","../src/services/federated.ts","../package.json","../src/libs/utils.ts","../src/libs/csrf.ts","../src/libs/request/adapters/axios.ts","../src/libs/request/adapters/fetch.ts","../src/index.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/return-await */\nimport { WELLKNOWN_SERVICE_PATH_PREFIX } from '@abtnode/constant';\nimport { withQuery } from 'ufo';\n\nimport type { Axios } from 'axios';\nimport { TokenService } from './token';\n\nexport type UserPublicInfo = {\n  avatar: string;\n  did: string;\n  name: string;\n  fullName: string;\n  sourceAppPid: string | null;\n};\n\nexport type Webhook = {\n  type: 'slack' | 'api';\n  url: string;\n};\nexport type NotificationConfig = {\n  webhooks?: Webhook[];\n  notifications?: {\n    email?: boolean;\n    wallet?: boolean;\n    phone?: boolean;\n  };\n};\n\nexport type PrivacyConfig = {\n  [key: string]: boolean;\n};\n\nexport interface SpaceGateway {\n  did: string;\n  name: string;\n  url: string;\n  endpoint: string;\n}\n\nexport enum OrgQueryType {\n  OWNED = 'owned',\n  JOINED = 'joined',\n}\n\nexport class AuthService {\n  private api: Axios;\n\n  private token: TokenService;\n\n  constructor({ api, token }: { api: Axios; token: TokenService }) {\n    this.api = api;\n    this.token = token;\n  }\n\n  async getUserPublicInfo({ did, name }: { did: string; name?: string }): Promise<UserPublicInfo> {\n    const { data } = await this.api.get('/api/user', {\n      params: { did, name },\n    });\n    return data;\n  }\n\n  async getUserPrivacyConfig({ did, name }: { did: string; name?: string }): Promise<PrivacyConfig> {\n    const { data } = await this.api.get('/api/user/privacy/config', {\n      params: { did, name },\n    });\n    return data;\n  }\n\n  async saveUserPrivacyConfig(config: PrivacyConfig): Promise<PrivacyConfig> {\n    const { data } = await this.api.post('/api/user/privacy/config', config);\n    return data;\n  }\n\n  async getUserNotificationConfig(): Promise<NotificationConfig> {\n    const { data } = await this.api.get('/api/user/notification/config');\n    return data;\n  }\n\n  async saveUserNotificationConfig(config: NotificationConfig): Promise<NotificationConfig> {\n    const { data } = await this.api.post('/api/user/notification/config', config);\n    return data;\n  }\n\n  async testNotificationWebhook(webhook: Webhook): Promise<{\n    success: boolean;\n  }> {\n    const { data } = await this.api.put('/api/user/notification/webhook', webhook);\n    return data;\n  }\n\n  // eslint-disable-next-line require-await\n  async getProfileUrl({ did, locale }: { did: string; locale: string }) {\n    const url = `${WELLKNOWN_SERVICE_PATH_PREFIX}/user`;\n    return withQuery(url, {\n      did,\n      locale,\n    });\n  }\n\n  async getProfile() {\n    const { data } = await this.api.get('/api/user/profile');\n    return data;\n  }\n\n  async refreshProfile(): Promise<void> {\n    await this.api.put('/api/user/refreshProfile');\n  }\n\n  async followUser({ userDid }: { userDid: string }): Promise<void> {\n    await this.api.post(`/api/user/follow/${userDid}`);\n  }\n\n  async unfollowUser({ userDid }: { userDid: string }): Promise<void> {\n    await this.api.delete(`/api/user/follow/${userDid}`);\n  }\n\n  async isFollowingUser({ userDid }: { userDid: string }): Promise<boolean> {\n    const { data } = await this.api.get(`/api/user/follow/${userDid}`);\n    return data.isFollowing;\n  }\n\n  async saveProfile({\n    locale,\n    inviter,\n    metadata,\n    address,\n  }: {\n    locale?: string;\n    inviter?: string;\n    metadata?: any;\n    address?: any;\n  }) {\n    const { data } = await this.api.put('/api/user/profile', { locale, inviter, metadata, address });\n    return data;\n  }\n\n  async updateDidSpace({ spaceGateway }: { spaceGateway: SpaceGateway }) {\n    await this.api.put('/api/user/updateDidSpace', { spaceGateway });\n  }\n\n  /**\n   * 指定要退出登录的设备 id\n   * 指定要退出登录的会话状态\n   * @param {{ visitorId: string, status: string }} { visitorId, status }\n   * @return {Promise<void>}\n   */\n  async logout({\n    visitorId,\n    status,\n    includeFederated,\n  }: {\n    visitorId?: string;\n    status?: string;\n    includeFederated?: boolean;\n  }): Promise<void> {\n    const refreshToken = this.token.getRefreshToken();\n    const { data } = await this.api.post('/api/user/logout', {\n      visitorId,\n      status,\n      includeFederated,\n      refreshToken,\n    });\n    return data;\n  }\n\n  /**\n   * 删除当前登录用户\n   * @return {Promise<{did: string}>}\n   */\n  async destroyMyself(): Promise<{ did: string }> {\n    const { data } = await this.api.delete('/api/user');\n    return data;\n  }\n\n  /**\n   * org 相关\n   */\n  async getOrgs({\n    search = '',\n    type = '',\n    page = 1,\n    pageSize = 20,\n  }: {\n    search?: string;\n    page: number;\n    pageSize: number;\n    type?: OrgQueryType | '';\n  }): Promise<any> {\n    const { data } = await this.api.get('/api/user/orgs', { params: { search, page, pageSize, type } });\n    return data;\n  }\n\n  // 根据 orgId 查询一个 org 的信息\n  async getOrg(orgId: string): Promise<any> {\n    const { data } = await this.api.get(`/api/user/orgs/${orgId}`);\n    return data;\n  }\n\n  async createOrg(org: any): Promise<any> {\n    const { data } = await this.api.post('/api/user/orgs', { org });\n    return data;\n  }\n\n  // 查询一个role 的信息用于获取是否属于一个 org\n  async getRole(name: string): Promise<any> {\n    const { data } = await this.api.get('/api/user/role', { params: { name } });\n    return data;\n  }\n\n  async addResourceToOrg({\n    orgId,\n    resourceId,\n    type,\n    metadata,\n  }: {\n    orgId: string;\n    resourceId: string;\n    type?: string;\n    metadata?: any;\n  }): Promise<any> {\n    const { data } = await this.api.post(`/api/user/orgs/${orgId}/resources`, { resourceId, type, metadata });\n    return data;\n  }\n\n  async migrateResourceToOrg({ form, to, resourceId }: { form: string; to: string; resourceId: string }): Promise<any> {\n    const { data } = await this.api.put(`/api/user/orgs/${form}/resources`, { to, resourceId });\n    return data;\n  }\n}\n","import Cookie from 'js-cookie';\nimport { SESSION_TOKEN_STORAGE_KEY, REFRESH_TOKEN_STORAGE_KEY } from '@abtnode/constant';\n\nexport class TokenService {\n  getSessionToken(config: any) {\n    if (Cookie.get(SESSION_TOKEN_STORAGE_KEY)) {\n      return Cookie.get(SESSION_TOKEN_STORAGE_KEY);\n    }\n\n    if (config.sessionTokenKey) {\n      return window.localStorage.getItem(config.sessionTokenKey);\n    }\n\n    return '';\n  }\n\n  setSessionToken(value: string) {\n    Cookie.set(SESSION_TOKEN_STORAGE_KEY, value);\n  }\n\n  removeSessionToken() {\n    Cookie.remove(SESSION_TOKEN_STORAGE_KEY);\n  }\n\n  getRefreshToken() {\n    return localStorage.getItem(REFRESH_TOKEN_STORAGE_KEY);\n  }\n\n  setRefreshToken(value: string) {\n    localStorage.setItem(REFRESH_TOKEN_STORAGE_KEY, value);\n  }\n\n  removeRefreshToken() {\n    localStorage.removeItem(REFRESH_TOKEN_STORAGE_KEY);\n  }\n}\n","import { withQuery, joinURL } from 'ufo';\nimport QuickLRU from 'quick-lru';\nimport { Blocklet } from '../types';\n\nlet blockletCache: QuickLRU<string, Blocklet> | undefined;\n\nfunction getBlockletCache(): QuickLRU<string, Blocklet> {\n  if (!blockletCache) {\n    blockletCache = new QuickLRU<string, Blocklet>({ maxSize: 30, maxAge: 60 * 1000 });\n  }\n  return blockletCache;\n}\n\nexport class BlockletService {\n  getBlocklet(): Blocklet;\n  async getBlocklet(baseUrl?: string, force?: boolean): Promise<Blocklet>;\n\n  getBlocklet(baseUrl?: string, force: boolean = false): Blocklet | Promise<Blocklet> {\n    if (!baseUrl) {\n      if (typeof window === 'undefined' || typeof document === 'undefined') {\n        throw new Error('Cannot get blocklet in server side without baseUrl');\n      }\n\n      return window.blocklet;\n    }\n    const cache = getBlockletCache();\n    if (!force && cache.has(baseUrl)) {\n      return cache.get(baseUrl);\n    }\n\n    const url = withQuery(joinURL(baseUrl, '__blocklet__.js'), {\n      type: 'json',\n      t: Date.now(),\n    });\n    // eslint-disable-next-line no-async-promise-executor\n    return new Promise(async (resolve) => {\n      const res = await fetch(url);\n      const data: Blocklet = await res.json();\n      cache.set(baseUrl, data);\n      resolve(data);\n    });\n  }\n\n  loadBlocklet() {\n    return new Promise<void>((resolve, reject) => {\n      if (typeof window === 'undefined' || typeof document === 'undefined') {\n        reject();\n        return;\n      }\n\n      const blockletScript = document.createElement('script');\n      let basename = '/';\n      if (window.blocklet && window.blocklet.prefix) {\n        basename = window.blocklet.prefix;\n      }\n      blockletScript.src = withQuery(joinURL(basename, '__blocklet__.js'), {\n        t: Date.now(),\n      });\n      blockletScript.onload = () => {\n        resolve();\n      };\n      blockletScript.onerror = () => {\n        reject();\n      };\n      document.head.append(blockletScript);\n    });\n  }\n\n  getPrefix(blocklet?: Blocklet) {\n    if (blocklet) {\n      return blocklet?.prefix || '/';\n    }\n\n    if (typeof window === 'undefined' || typeof document === 'undefined') {\n      return null;\n    }\n\n    return window.blocklet?.prefix || '/';\n  }\n}\n","import type { Axios } from 'axios';\nimport { joinURL } from 'ufo';\nimport { WELLKNOWN_SERVICE_PATH_PREFIX, USER_SESSION_STATUS } from '@abtnode/constant';\nimport { BlockletService } from './blocklet';\n\nexport type UserSessionUser = {\n  avatar: string;\n  did: string;\n  email: string;\n  fullName: string;\n  pk: string;\n  remark?: string;\n  role: string;\n  roleTitle: string;\n  sourceAppPid: string | null;\n  sourceProvider: 'wallet' | 'auth0' | 'nft';\n};\n\nexport type UserSession = {\n  appName: string;\n  appPid: string;\n  extra: {\n    walletOS: 'android' | 'ios' | 'web';\n  };\n  id: string;\n  lastLoginIp: string;\n  passportId: string | null;\n  ua: string;\n  createdAt?: string;\n  updatedAt: string;\n  status?: string;\n  user?: UserSessionUser;\n  userDid: string;\n  visitorId: string;\n};\n\nexport type UserSessionList = {\n  list: UserSession[];\n  paging: {\n    page: number;\n    pageSize: number;\n    total: number;\n  };\n};\n\nexport type UserSessionQuery = {\n  page: number;\n  pageSize: number;\n  status?: USER_SESSION_STATUS.ONLINE | USER_SESSION_STATUS.EXPIRED | USER_SESSION_STATUS.OFFLINE;\n};\n\nexport class UserSessionService {\n  private api: Axios;\n\n  private blocklet: BlockletService;\n\n  constructor({ api, blocklet }: { api: Axios; blocklet?: BlockletService }) {\n    this.api = api;\n    this.blocklet = blocklet || new BlockletService();\n  }\n\n  getBaseUrl(appUrl?: string): string | undefined {\n    return appUrl ? joinURL(appUrl, WELLKNOWN_SERVICE_PATH_PREFIX) : undefined;\n  }\n\n  async getUserSessions({ did, appUrl }: { did: string; appUrl?: string }): Promise<UserSession[]> {\n    const baseURL = this.getBaseUrl(appUrl);\n\n    const blocklet = await this.blocklet.getBlocklet();\n    const { data } = await this.api.get('/api/user-session', {\n      baseURL,\n      params: {\n        userDid: did,\n        appPid: blocklet.appPid,\n      },\n    });\n    return data;\n  }\n\n  /**\n   * 获取个人的所有登录会话\n   */\n  async getMyLoginSessions(\n    { appUrl }: { appUrl?: string } = {},\n    params: UserSessionQuery = { page: 1, pageSize: 10 }\n  ): Promise<UserSessionList> {\n    const baseURL = this.getBaseUrl(appUrl);\n\n    const { data } = await this.api.get('/api/user-session/myself', { baseURL, params });\n    return data;\n  }\n\n  async loginByUserSession({\n    id,\n    appPid,\n    userDid,\n    passportId,\n    appUrl,\n  }: {\n    appPid: string;\n    userDid: string;\n    id: string;\n    passportId: string;\n    appUrl?: string;\n  }): Promise<UserSession[]> {\n    const baseURL = this.getBaseUrl(appUrl);\n    const { data } = await this.api.post(\n      '/api/user-session/login',\n      {\n        id,\n        appPid,\n        userDid,\n        passportId,\n      },\n      { baseURL }\n    );\n    return data;\n  }\n}\n","import { joinURL } from 'ufo';\nimport { Blocklet, BlockletComponent } from '../types';\n\n// FIXME: @zhanghan 由于 component 依赖于 blocklet 实例，而该实例可能需要异步获取，所以还是要求用户自己手动实例化 ComponentService\n// 等后续有比较好的方案，能够在 SDK 初始化时直接获取 blocklet 实例，再自动实例化 ComponentService\nexport class ComponentService {\n  private blocklet: Blocklet;\n\n  constructor({ blocklet = window?.blocklet }: { blocklet?: Blocklet } = {}) {\n    this.blocklet = blocklet;\n  }\n\n  getComponent(name: string) {\n    const componentMountPoints: BlockletComponent[] = this.blocklet?.componentMountPoints || [];\n    const item = componentMountPoints.find((x: any) => [x.title, x.name, x.did].includes(name));\n    return item;\n  }\n\n  getComponentMountPoint(name?: string): string {\n    const component: any = this.getComponent(name);\n    return component?.mountPoint || '';\n  }\n\n  getUrl(name: string, ...parts: string[]): string {\n    const mountPoint = this.getComponentMountPoint(name);\n    const appUrl = this.blocklet?.appUrl || '';\n    return joinURL(appUrl, mountPoint, ...parts);\n  }\n}\n","import isEmpty from 'lodash/isEmpty';\n\nimport type { Axios } from 'axios';\nimport { BlockletService } from './blocklet';\n\ntype AppInfo = {\n  appId: string;\n  appName: string;\n  appDescription: string;\n  appLogo: string;\n  appPid: string;\n  appUrl: string;\n  version: string;\n  sourceAppPid: string;\n  provider: string;\n};\ntype ServerInfo = {\n  appId: string;\n  appName: string;\n  appDescription: string;\n  appUrl: string;\n  sourceAppPid: string;\n  provider: string;\n  type: 'server';\n};\n\nexport class FederatedService {\n  private api: Axios;\n\n  private blocklet: BlockletService;\n\n  private blockletDataCache: Record<string, any> = {};\n\n  constructor({ api, blocklet }: { api: Axios; blocklet?: BlockletService }) {\n    this.api = api;\n    this.blocklet = blocklet || new BlockletService();\n  }\n\n  async getTrustedDomains(): Promise<Array<string>> {\n    const { data } = await this.api.get('/api/federated/getTrustedDomains');\n    return data;\n  }\n\n  getMaster(blocklet = this.blocklet.getBlocklet()) {\n    const federated = blocklet?.settings?.federated;\n    return federated?.master;\n  }\n\n  getConfig(blocklet = this.blocklet.getBlocklet()) {\n    const federated = blocklet?.settings?.federated;\n    return federated?.config;\n  }\n\n  getFederatedEnabled(blocklet = this.blocklet.getBlocklet()) {\n    const config = this.getConfig(blocklet);\n    return config?.status === 'approved';\n  }\n\n  getSourceAppPid(blocklet = this.blocklet.getBlocklet()) {\n    const master = this.getMaster(blocklet);\n    return master?.appPid;\n  }\n\n  getFederatedApp(blocklet = this.blocklet.getBlocklet()): AppInfo | null {\n    const master = this.getMaster(blocklet);\n    const isFederatedMode = !isEmpty(master);\n    if (!isFederatedMode) {\n      return null;\n    }\n    return {\n      appId: master.appId,\n      appName: master.appName,\n      appDescription: master.appDescription,\n      appLogo: master.appLogo,\n      appPid: master.appPid,\n      appUrl: master.appUrl,\n      version: master.version,\n      sourceAppPid: master.appPid,\n      provider: 'wallet',\n    };\n  }\n\n  getCurrentApp(blocklet = this.blocklet.getBlocklet()): AppInfo | ServerInfo {\n    // 适用于 blocklet 项目\n    if (blocklet) {\n      return {\n        appId: blocklet.appId,\n        appName: blocklet.appName,\n        appDescription: blocklet.appDescription,\n        appLogo: blocklet.appLogo,\n        appPid: blocklet.appPid,\n        appUrl: blocklet.appUrl,\n        version: blocklet.version,\n        // NOTICE: null 代表该值置空\n        sourceAppPid: null,\n        provider: 'wallet',\n      };\n    }\n    // HACK: 适用于 blocklet-server\n    if (window.env) {\n      const server = window.env!;\n      return {\n        appId: server.appId,\n        appName: server.appName,\n        appDescription: server.appDescription,\n        appUrl: server.baseUrl,\n        // NOTICE: null 代表该值置空\n        sourceAppPid: null,\n        provider: 'wallet',\n        type: 'server',\n      };\n    }\n    return null;\n  }\n\n  getApps(blocklet = this.blocklet.getBlocklet()) {\n    const appList = [];\n\n    const masterApp = this.getFederatedApp(blocklet);\n    const currentApp = this.getCurrentApp(blocklet);\n    const federatedEnabled = this.getFederatedEnabled(blocklet);\n\n    if (currentApp) {\n      appList.push(currentApp);\n    }\n    if (masterApp && masterApp?.appId !== currentApp?.appId && federatedEnabled) {\n      appList.push(masterApp);\n    }\n    // NOTICE: masterApp 应该排在前面\n    return appList.reverse();\n  }\n\n  async getBlockletData(appUrl: string, force = false) {\n    if (!force && this.blockletDataCache[appUrl]) {\n      return this.blockletDataCache[appUrl];\n    }\n\n    try {\n      const url = new URL('__blocklet__.js', appUrl);\n      url.searchParams.set('type', 'json');\n      const res = await fetch(url.href);\n      const jsonData = await res.json();\n      this.blockletDataCache[appUrl] = jsonData;\n      return jsonData;\n    } catch (err) {\n      console.error(`Failed to get blocklet data: ${appUrl}`, err);\n      return null;\n    }\n  }\n}\n","","import omit from 'lodash/omit';\nimport isObject from 'lodash/isObject';\nimport stableStringify from 'json-stable-stringify';\nimport Cookies from 'js-cookie';\nimport type { VerifyFn } from '../types';\n\nexport const sleep = (time = 0) => {\n  return new Promise<void>((resolve) => {\n    setTimeout(() => {\n      resolve();\n    }, time);\n  });\n};\n\nexport const getBearerToken = (token: string) => {\n  return `Bearer ${encodeURIComponent(token)}`;\n};\n\nconst visitorIdKey = 'vid';\nconst visitorIdKeyLegacy = '__visitor_id';\n\nexport const getVisitorId = () => {\n  return Cookies.get(visitorIdKey) || localStorage.getItem(visitorIdKeyLegacy);\n};\n\nexport const setVisitorId = (value: string | null) => {\n  if (value === null) {\n    localStorage.removeItem(visitorIdKey);\n  } else {\n    localStorage.setItem(visitorIdKey, value);\n  }\n};\n\nexport const verifyResponse = async (response: any, onInvalid: () => void, verifyFn?: VerifyFn) => {\n  if (\n    isObject(response.data) &&\n    response.status >= 200 &&\n    response.status < 300 &&\n    typeof window !== 'undefined' &&\n    window.blocklet?.appId &&\n    window.blocklet?.appPk\n  ) {\n    // 没有提供 verifyFn 时跳过验证\n    if (!verifyFn) {\n      return response;\n    }\n\n    if (!response.data.$signature) {\n      onInvalid();\n      throw new Error('Invalid response');\n    }\n\n    const { appId, appPk } = window.blocklet;\n    const data = stableStringify(omit(response.data, ['$signature']));\n    const result = await verifyFn(data, response.data.$signature, appPk, appId);\n\n    if (result === false) {\n      onInvalid();\n      throw new Error('Invalid response');\n    }\n  }\n\n  return response;\n};\n","import axios from 'axios';\nimport Cookie from 'js-cookie';\nimport { joinURL } from 'ufo';\nimport { WELLKNOWN_SERVICE_PATH_PREFIX } from '@abtnode/constant';\n\nexport function getCSRFToken() {\n  return Cookie.get('x-csrf-token');\n}\n\nexport function getLoginToken() {\n  return Cookie.get('login_token');\n}\n\nexport async function getCSRFTokenByLoginToken(): Promise<{ loginToken: string; csrfToken: string | null }> {\n  const csrfToken = getCSRFToken();\n  try {\n    const url: string = joinURL(window.location.origin, WELLKNOWN_SERVICE_PATH_PREFIX, '/api/did/csrfToken');\n    const { data } = await axios.get(url, {\n      headers: {\n        'x-csrf-token': csrfToken,\n      },\n    });\n\n    return data;\n  } catch (error) {\n    console.error(error);\n    return {\n      loginToken: getLoginToken(),\n      csrfToken: null,\n    };\n  }\n}\n","/* eslint-disable @typescript-eslint/return-await */\nimport axios from 'axios';\nimport Cookies from 'js-cookie';\nimport { SESSION_TOKEN_STORAGE_KEY, WELLKNOWN_SERVICE_PATH_PREFIX } from '@abtnode/constant';\nimport type { InternalAxiosRequestConfig, AxiosRequestHeaders, AxiosRequestConfig } from 'axios';\n\nimport Keyv from 'keyv';\nimport { KeyvLocalStorage } from 'keyv-browser';\nimport isNumber from 'lodash/isNumber';\nimport { version } from '../../../../package.json';\nimport { getBearerToken, getVisitorId, sleep, verifyResponse } from '../../utils';\nimport { RequestParams, TokenResult } from '../../../types';\nimport { getCSRFToken, getCSRFTokenByLoginToken, getLoginToken } from '../../csrf';\nimport { ComponentService } from '../../../services';\n\nlet csrfTokenCache: Keyv | undefined;\n\nfunction getCsrfTokenCache(): Keyv {\n  if (!csrfTokenCache) {\n    const cacheTtl = window?.blocklet?.settings?.session?.cacheTtl;\n    csrfTokenCache = new Keyv({\n      store: new KeyvLocalStorage(),\n      ttl: isNumber(cacheTtl) ? cacheTtl * 1000 : 1000 * 60 * 60,\n    });\n  }\n  return csrfTokenCache;\n}\n\ntype AxiosConfig = InternalAxiosRequestConfig & {\n  metaData?: {\n    startTime?: number;\n    endTime?: number;\n  };\n};\n\nasync function sleepForLoading(config: AxiosConfig, lazyTime: number = 300) {\n  config.metaData.endTime = +new Date();\n  const { startTime, endTime } = config.metaData;\n  const timeDiff = endTime - startTime;\n  if (timeDiff < lazyTime) await sleep(lazyTime - timeDiff);\n  delete config.metaData;\n}\n\nexport const createAxios = (options?: AxiosRequestConfig & { secure?: boolean }, requestParams?: RequestParams) => {\n  const headers = {\n    ...options?.headers,\n    'x-blocklet-js-sdk-version': version,\n  } as unknown as AxiosRequestHeaders;\n  // FIXME: @zhanghan 需要从外部传入 blocklet 实例\n  const componentService = new ComponentService();\n\n  const instance = axios.create({\n    ...options,\n    headers,\n  });\n\n  if (requestParams?.lazy) {\n    instance.interceptors.request.use(\n      (config: AxiosConfig) => {\n        config.metaData = { startTime: +new Date() };\n        return config;\n      },\n      (err) => Promise.reject(err)\n    );\n\n    instance.interceptors.response.use(\n      async (res) => {\n        if (res.config) {\n          await sleepForLoading(res.config, requestParams?.lazyTime);\n        }\n        return res;\n      },\n      async (err) => {\n        if (err.response) {\n          await sleepForLoading(err.response.config, requestParams?.lazyTime);\n        }\n        return Promise.reject(err);\n      }\n    );\n  }\n\n  instance.interceptors.request.use(\n    async (config: AxiosConfig) => {\n      const componentDid = requestParams?.componentDid ?? window.blocklet?.componentId?.split('/').pop();\n      config.baseURL = config.baseURL || componentService.getComponentMountPoint(componentDid);\n      config.timeout = config.timeout || 20 * 1000;\n\n      const loginToken = getLoginToken();\n      const csrfToken = getCSRFToken();\n      if (loginToken && csrfToken) {\n        const loginTokenKey = loginToken.slice(-32);\n        const cache = getCsrfTokenCache();\n        const csrfTokenFromCache = await cache.get(loginTokenKey);\n        if (csrfTokenFromCache) {\n          config.headers['x-csrf-token'] = csrfTokenFromCache;\n        } else {\n          const { loginToken: newLoginToken, csrfToken: newCsrfToken } = await getCSRFTokenByLoginToken();\n          if (newCsrfToken) {\n            await cache.set(newLoginToken.slice(-32), newCsrfToken);\n            config.headers['x-csrf-token'] = newCsrfToken;\n          } else {\n            config.headers['x-csrf-token'] = csrfToken;\n          }\n        }\n\n        // 如果 config.headers['x-csrf-token'] 跟 cookie 里面的对不上，需要设置一下 cookie 里面的 csrf token\n        if (config.headers['x-csrf-token'] && config.headers['x-csrf-token'] !== getCSRFToken()) {\n          Cookies.set('x-csrf-token', config.headers['x-csrf-token'], {\n            sameSite: 'strict',\n            secure: true,\n          });\n        }\n      }\n\n      // NOTICE: 需要将获取 visitorId 的逻辑放在这里，因为 visitorId 会在登录后才动态生成，需要确保后续的请求中，有正确携带 visitorId\n      const visitorId = getVisitorId();\n      if (![undefined, null].includes(visitorId)) {\n        config.headers['x-blocklet-visitor-id'] = visitorId;\n      }\n\n      return config;\n    },\n    (error) => Promise.reject(error)\n  );\n\n  return instance;\n};\n\nasync function renewRefreshToken(refreshToken: string) {\n  if (!refreshToken) {\n    throw new Error('Refresh token not found');\n  }\n  const refreshApi = createAxios({\n    baseURL: WELLKNOWN_SERVICE_PATH_PREFIX,\n    timeout: 10 * 1000,\n    secure: true,\n    headers: {\n      authorization: getBearerToken(refreshToken),\n    },\n  });\n  const { data } = await refreshApi.post('/api/did/refreshSession');\n  return data;\n}\n\nexport function createRequest(\n  {\n    getSessionToken,\n    setSessionToken,\n    removeSessionToken,\n    getRefreshToken,\n    setRefreshToken,\n    removeRefreshToken,\n    onRefreshTokenError,\n    onRefreshTokenSuccess,\n  }: {\n    getSessionToken: (config?: any) => string;\n    setSessionToken: (value: string) => void;\n    removeSessionToken: () => void;\n    getRefreshToken: () => string;\n    setRefreshToken: (value: string) => void;\n    removeRefreshToken: () => void;\n    onRefreshTokenError: (error: any) => void;\n    onRefreshTokenSuccess: (result: TokenResult) => void;\n  },\n  requestOptions?: AxiosRequestConfig,\n  requestParams?: RequestParams\n) {\n  let refreshingTokenRequest: Promise<TokenResult> = null;\n  const service = createAxios(\n    {\n      timeout: 30 * 1000,\n      ...requestOptions,\n    },\n    requestParams\n  );\n\n  service.interceptors.request.use(\n    async (config) => {\n      if (!Cookies.get(SESSION_TOKEN_STORAGE_KEY)) {\n        const token = getSessionToken(config);\n        if (token) {\n          config.headers.authorization = getBearerToken(token);\n        }\n      }\n      if (refreshingTokenRequest) {\n        await refreshingTokenRequest;\n      }\n\n      return config;\n    },\n    (error) => Promise.reject(error)\n  );\n\n  service.interceptors.response.use(\n    async (response: any) => {\n      if (response.config?.secure) {\n        const data = await verifyResponse(\n          response,\n          () => {\n            removeSessionToken();\n            removeRefreshToken();\n          },\n          requestParams?.verifyFn\n        );\n        return data;\n      }\n      return response;\n    },\n    async (error) => {\n      const originalRequest = error.config;\n      if (originalRequest) {\n        originalRequest.headers = originalRequest?.headers ? { ...originalRequest.headers } : {};\n        if (error?.response?.status === 401 && !originalRequest._retry) {\n          originalRequest._retry = true;\n          try {\n            if (!refreshingTokenRequest) {\n              refreshingTokenRequest = renewRefreshToken(getRefreshToken());\n            }\n            const tokenData = await refreshingTokenRequest;\n            setSessionToken(tokenData.nextToken);\n            setRefreshToken(tokenData.nextRefreshToken);\n            if (typeof onRefreshTokenSuccess === 'function') {\n              onRefreshTokenSuccess(tokenData);\n            }\n            return service(originalRequest);\n          } catch (refreshTokenError) {\n            removeSessionToken();\n            removeRefreshToken();\n            if (typeof onRefreshTokenError === 'function') {\n              onRefreshTokenError(refreshTokenError);\n            }\n            // NOTICE: 如果在更新 token 的过程中出现了错误，则应该返回原始请求的 result\n            return Promise.reject(error);\n          } finally {\n            refreshingTokenRequest = null;\n          }\n        }\n      }\n      return Promise.reject(error);\n    }\n  );\n  return service;\n}\n","/* eslint-disable @typescript-eslint/return-await */\nimport { WELLKNOWN_SERVICE_PATH_PREFIX, SESSION_TOKEN_STORAGE_KEY } from '@abtnode/constant';\nimport { joinURL } from 'ufo';\nimport Cookies from 'js-cookie';\nimport isUrl from 'is-url';\n\nimport { version } from '../../../../package.json';\nimport { getBearerToken, getVisitorId, sleep, verifyResponse } from '../../utils';\nimport { RequestParams, TokenResult } from '../../../types';\nimport { getCSRFToken } from '../../csrf';\nimport { ComponentService } from '../../../services';\n\nexport function createFetch(globalOptions: RequestInit = {}, requestParams?: RequestParams) {\n  return async (input: string | Request | URL, options?: RequestInit) => {\n    const startAt = Date.now();\n    const headers: HeadersInit = {\n      ...globalOptions?.headers,\n      ...options?.headers,\n      'x-csrf-token': getCSRFToken(),\n      'x-blocklet-js-sdk-version': version,\n    };\n    // FIXME: @zhanghan 如何实现 axios 中拦截器的类似效果，将 visitorId 的注入变成每次请求时的行为\n    const visitorId = getVisitorId();\n    if (![undefined, null].includes(visitorId)) {\n      // @ts-ignore 忽略这个 ts 错误\n      headers['x-blocklet-visitor-id'] = visitorId;\n    }\n\n    const request = fetch(input, {\n      ...globalOptions,\n      ...options,\n      headers,\n    });\n    try {\n      return request;\n      // eslint-disable-next-line no-useless-catch\n    } catch (error) {\n      throw error;\n    } finally {\n      const endAt = Date.now();\n      if (requestParams?.lazy) {\n        const lazyTime = requestParams?.lazyTime ?? 300;\n        const timeDiff = endAt - startAt;\n        if (timeDiff < lazyTime) await sleep(lazyTime - timeDiff);\n      }\n    }\n  };\n}\n\nasync function renewRefreshToken(refreshToken: string) {\n  if (!refreshToken) {\n    throw new Error('Refresh token not found');\n  }\n  const refreshApi = createFetch();\n  const res = await refreshApi(joinURL(WELLKNOWN_SERVICE_PATH_PREFIX, '/api/did/refreshSession'), {\n    method: 'POST',\n    headers: {\n      authorization: getBearerToken(refreshToken),\n    },\n  });\n  const data = await res.json();\n  return data;\n}\n\nexport function createRequest(\n  {\n    baseURL,\n    getSessionToken,\n    setSessionToken,\n    removeSessionToken,\n    getRefreshToken,\n    setRefreshToken,\n    removeRefreshToken,\n    onRefreshTokenError,\n    onRefreshTokenSuccess,\n  }: {\n    baseURL?: string;\n    getSessionToken: (config?: any) => string;\n    setSessionToken: (value: string) => void;\n    removeSessionToken: () => void;\n    getRefreshToken: () => string;\n    setRefreshToken: (value: string) => void;\n    removeRefreshToken: () => void;\n    onRefreshTokenError: (error: any) => void;\n    onRefreshTokenSuccess: (result: TokenResult) => void;\n  },\n  requestOptions?: RequestInit & { secure?: boolean },\n  requestParams?: RequestParams\n) {\n  let refreshingTokenRequest: Promise<TokenResult> = null;\n  const service = createFetch(requestOptions, requestParams);\n  // FIXME: @zhanghan 需要从外部传入 blocklet 实例\n  const componentService = new ComponentService();\n\n  return async (input: string | Request | URL, options?: RequestInit & { secure?: boolean }) => {\n    let authorization;\n\n    let finalUrl = input;\n    if (typeof input === 'string') {\n      if (!isUrl(input)) {\n        if (baseURL) {\n          finalUrl = joinURL(baseURL, input);\n        } else {\n          const componentDid = requestParams?.componentDid ?? window.blocklet?.componentId?.split('/').pop();\n          const mountPoint: string = componentService.getComponentMountPoint(componentDid);\n\n          finalUrl = joinURL(mountPoint, input);\n        }\n      }\n    }\n\n    if (!Cookies.get(SESSION_TOKEN_STORAGE_KEY)) {\n      const token = getSessionToken(requestOptions);\n      if (token) {\n        authorization = getBearerToken(token);\n      }\n    }\n    if (refreshingTokenRequest) {\n      await refreshingTokenRequest;\n    }\n    const res = await service(finalUrl, {\n      ...options,\n      headers: {\n        ...options?.headers,\n        authorization,\n      },\n    });\n    if (!res.ok && res.status === 401) {\n      refreshingTokenRequest = renewRefreshToken(getRefreshToken());\n      try {\n        const tokenData = await refreshingTokenRequest;\n        setSessionToken(tokenData.nextToken);\n        setRefreshToken(tokenData.nextRefreshToken);\n        if (typeof onRefreshTokenSuccess === 'function') {\n          onRefreshTokenSuccess(tokenData);\n        }\n        return service(finalUrl, {\n          ...options,\n          headers: {\n            ...options?.headers,\n            authorization,\n          },\n        });\n      } catch (error) {\n        removeSessionToken();\n        removeRefreshToken();\n        if (typeof onRefreshTokenError === 'function') {\n          onRefreshTokenError(error);\n        }\n        // NOTICE: 如果在更新 token 的过程中出现了错误，则应该返回原始请求的 result\n        return res;\n      } finally {\n        refreshingTokenRequest = null;\n      }\n    }\n\n    // FIXME: 重试的时候怎么注入检查逻辑？\n    if (res.ok && options?.secure) {\n      await verifyResponse(\n        { status: res.status, data: await res.json() },\n        () => {\n          removeSessionToken();\n          removeRefreshToken();\n        },\n        requestParams?.verifyFn\n      );\n    }\n\n    return res;\n  };\n}\n","import type { Axios, AxiosRequestConfig } from 'axios';\nimport { WELLKNOWN_SERVICE_PATH_PREFIX } from '@abtnode/constant';\n\nimport { AuthService, BlockletService, TokenService, UserSessionService, FederatedService } from './services';\nimport { createAxiosRequest, createFetchRequest } from './libs/request';\nimport type { RequestParams, VerifyFn } from './types';\n\nexport type * from './services';\nexport type { VerifyFn } from './types';\n\nexport * from './libs/csrf';\n\nexport interface BlockletSDKOptions {\n  verifyFn?: VerifyFn;\n}\n\nexport class BlockletSDK {\n  public api: Axios;\n\n  public user: AuthService;\n\n  public userSession: UserSessionService;\n\n  public token: TokenService;\n\n  public blocklet: BlockletService;\n\n  public federated: FederatedService;\n\n  constructor(options?: BlockletSDKOptions) {\n    const tokenService = new TokenService();\n    const internalApi = createAxiosRequest(\n      {\n        getSessionToken: tokenService.getSessionToken,\n        setSessionToken: tokenService.setSessionToken,\n        removeSessionToken: tokenService.removeSessionToken,\n        getRefreshToken: tokenService.getRefreshToken,\n        setRefreshToken: tokenService.setRefreshToken,\n        removeRefreshToken: tokenService.removeRefreshToken,\n        onRefreshTokenError: () => {\n          console.error('Failed to refresh token');\n        },\n        onRefreshTokenSuccess: () => {},\n      },\n      {\n        baseURL: WELLKNOWN_SERVICE_PATH_PREFIX,\n      },\n      {\n        verifyFn: options?.verifyFn,\n      }\n    );\n    const blocklet = new BlockletService();\n    this.user = new AuthService({ api: internalApi, token: tokenService });\n    this.federated = new FederatedService({ api: internalApi, blocklet });\n    this.userSession = new UserSessionService({ api: internalApi, blocklet });\n    this.token = tokenService;\n    this.blocklet = blocklet;\n\n    /**\n     * @deprecated this is deprecated, please use createAxios replace this\n     */\n    this.api = internalApi;\n  }\n}\n\nexport function createAxios(config: AxiosRequestConfig = {}, requestParams: RequestParams = {}) {\n  const tokenService = new TokenService();\n\n  return createAxiosRequest(\n    {\n      getSessionToken: tokenService.getSessionToken,\n      setSessionToken: tokenService.setSessionToken,\n      removeSessionToken: tokenService.removeSessionToken,\n      getRefreshToken: tokenService.getRefreshToken,\n      setRefreshToken: tokenService.setRefreshToken,\n      removeRefreshToken: tokenService.removeRefreshToken,\n      onRefreshTokenError: () => {\n        console.error('Failed to refresh token');\n      },\n      onRefreshTokenSuccess: () => {},\n    },\n    config,\n    requestParams\n  );\n}\n\nexport function createFetch(options?: RequestInit, requestParams?: RequestParams) {\n  const tokenService = new TokenService();\n  return createFetchRequest(\n    {\n      getSessionToken: tokenService.getSessionToken,\n      setSessionToken: tokenService.setSessionToken,\n      removeSessionToken: tokenService.removeSessionToken,\n      getRefreshToken: tokenService.getRefreshToken,\n      setRefreshToken: tokenService.setRefreshToken,\n      removeRefreshToken: tokenService.removeRefreshToken,\n      onRefreshTokenError: () => {\n        console.error('Failed to refresh token');\n      },\n      onRefreshTokenSuccess: () => {},\n    },\n    options,\n    requestParams\n  );\n}\n\n// NOTICE: 使用闭包来避免声明全局变量\nexport const getBlockletSDK = (() => {\n  let instance: BlockletSDK;\n\n  return (options?: BlockletSDKOptions) => {\n    if (!instance) {\n      instance = new BlockletSDK(options);\n    }\n\n    return instance;\n  };\n})();\n"],"mappings":";;;;;;;;;;;;;;;AA4CA,IAAa,cAAb,MAAyB;CAKvB,YAAY,EAAE,KAAK,SAA8C;AAC/D,OAAK,MAAM;AACX,OAAK,QAAQ;;CAGf,MAAM,kBAAkB,EAAE,KAAK,QAAiE;EAC9F,MAAM,EAAE,SAAS,MAAM,KAAK,IAAI,IAAI,aAAa,EAC/C,QAAQ;GAAE;GAAK;GAAM,EACtB,CAAC;AACF,SAAO;;CAGT,MAAM,qBAAqB,EAAE,KAAK,QAAgE;EAChG,MAAM,EAAE,SAAS,MAAM,KAAK,IAAI,IAAI,4BAA4B,EAC9D,QAAQ;GAAE;GAAK;GAAM,EACtB,CAAC;AACF,SAAO;;CAGT,MAAM,sBAAsB,QAA+C;EACzE,MAAM,EAAE,SAAS,MAAM,KAAK,IAAI,KAAK,4BAA4B,OAAO;AACxE,SAAO;;CAGT,MAAM,4BAAyD;EAC7D,MAAM,EAAE,SAAS,MAAM,KAAK,IAAI,IAAI,gCAAgC;AACpE,SAAO;;CAGT,MAAM,2BAA2B,QAAyD;EACxF,MAAM,EAAE,SAAS,MAAM,KAAK,IAAI,KAAK,iCAAiC,OAAO;AAC7E,SAAO;;CAGT,MAAM,wBAAwB,SAE3B;EACD,MAAM,EAAE,SAAS,MAAM,KAAK,IAAI,IAAI,kCAAkC,QAAQ;AAC9E,SAAO;;CAIT,MAAM,cAAc,EAAE,KAAK,UAA2C;AAEpE,SAAO,UADK,GAAG,8BAA8B,QACvB;GACpB;GACA;GACD,CAAC;;CAGJ,MAAM,aAAa;EACjB,MAAM,EAAE,SAAS,MAAM,KAAK,IAAI,IAAI,oBAAoB;AACxD,SAAO;;CAGT,MAAM,iBAAgC;AACpC,QAAM,KAAK,IAAI,IAAI,2BAA2B;;CAGhD,MAAM,WAAW,EAAE,WAA+C;AAChE,QAAM,KAAK,IAAI,KAAK,oBAAoB,UAAU;;CAGpD,MAAM,aAAa,EAAE,WAA+C;AAClE,QAAM,KAAK,IAAI,OAAO,oBAAoB,UAAU;;CAGtD,MAAM,gBAAgB,EAAE,WAAkD;EACxE,MAAM,EAAE,SAAS,MAAM,KAAK,IAAI,IAAI,oBAAoB,UAAU;AAClE,SAAO,KAAK;;CAGd,MAAM,YAAY,EAChB,QACA,SACA,UACA,WAMC;EACD,MAAM,EAAE,SAAS,MAAM,KAAK,IAAI,IAAI,qBAAqB;GAAE;GAAQ;GAAS;GAAU;GAAS,CAAC;AAChG,SAAO;;CAGT,MAAM,eAAe,EAAE,gBAAgD;AACrE,QAAM,KAAK,IAAI,IAAI,4BAA4B,EAAE,cAAc,CAAC;;;;;;;;CASlE,MAAM,OAAO,EACX,WACA,QACA,oBAKgB;EAChB,MAAM,eAAe,KAAK,MAAM,iBAAiB;EACjD,MAAM,EAAE,SAAS,MAAM,KAAK,IAAI,KAAK,oBAAoB;GACvD;GACA;GACA;GACA;GACD,CAAC;AACF,SAAO;;;;;;CAOT,MAAM,gBAA0C;EAC9C,MAAM,EAAE,SAAS,MAAM,KAAK,IAAI,OAAO,YAAY;AACnD,SAAO;;;;;CAMT,MAAM,QAAQ,EACZ,SAAS,IACT,OAAO,IACP,OAAO,GACP,WAAW,MAMI;EACf,MAAM,EAAE,SAAS,MAAM,KAAK,IAAI,IAAI,kBAAkB,EAAE,QAAQ;GAAE;GAAQ;GAAM;GAAU;GAAM,EAAE,CAAC;AACnG,SAAO;;CAIT,MAAM,OAAO,OAA6B;EACxC,MAAM,EAAE,SAAS,MAAM,KAAK,IAAI,IAAI,kBAAkB,QAAQ;AAC9D,SAAO;;CAGT,MAAM,UAAU,KAAwB;EACtC,MAAM,EAAE,SAAS,MAAM,KAAK,IAAI,KAAK,kBAAkB,EAAE,KAAK,CAAC;AAC/D,SAAO;;CAIT,MAAM,QAAQ,MAA4B;EACxC,MAAM,EAAE,SAAS,MAAM,KAAK,IAAI,IAAI,kBAAkB,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAC3E,SAAO;;CAGT,MAAM,iBAAiB,EACrB,OACA,YACA,MACA,YAMe;EACf,MAAM,EAAE,SAAS,MAAM,KAAK,IAAI,KAAK,kBAAkB,MAAM,aAAa;GAAE;GAAY;GAAM;GAAU,CAAC;AACzG,SAAO;;CAGT,MAAM,qBAAqB,EAAE,MAAM,IAAI,cAA8E;EACnH,MAAM,EAAE,SAAS,MAAM,KAAK,IAAI,IAAI,kBAAkB,KAAK,aAAa;GAAE;GAAI;GAAY,CAAC;AAC3F,SAAO;;;;;;AC/NX,IAAa,eAAb,MAA0B;CACxB,gBAAgB,QAAa;AAC3B,MAAI,OAAO,IAAI,0BAA0B,CACvC,QAAO,OAAO,IAAI,0BAA0B;AAG9C,MAAI,OAAO,gBACT,QAAO,OAAO,aAAa,QAAQ,OAAO,gBAAgB;AAG5D,SAAO;;CAGT,gBAAgB,OAAe;AAC7B,SAAO,IAAI,2BAA2B,MAAM;;CAG9C,qBAAqB;AACnB,SAAO,OAAO,0BAA0B;;CAG1C,kBAAkB;AAChB,SAAO,aAAa,QAAQ,0BAA0B;;CAGxD,gBAAgB,OAAe;AAC7B,eAAa,QAAQ,2BAA2B,MAAM;;CAGxD,qBAAqB;AACnB,eAAa,WAAW,0BAA0B;;;;;;AC7BtD,IAAI;AAEJ,SAAS,mBAA+C;AACtD,KAAI,CAAC,cACH,iBAAgB,IAAI,SAA2B;EAAE,SAAS;EAAI,QAAQ,KAAK;EAAM,CAAC;AAEpF,QAAO;;AAGT,IAAa,kBAAb,MAA6B;CAI3B,YAAY,SAAkB,QAAiB,OAAqC;AAClF,MAAI,CAAC,SAAS;AACZ,OAAI,OAAO,WAAW,eAAe,OAAO,aAAa,YACvD,OAAM,IAAI,MAAM,qDAAqD;AAGvE,UAAO,OAAO;;EAEhB,MAAM,QAAQ,kBAAkB;AAChC,MAAI,CAAC,SAAS,MAAM,IAAI,QAAQ,CAC9B,QAAO,MAAM,IAAI,QAAQ;EAG3B,MAAM,MAAM,UAAU,QAAQ,SAAS,kBAAkB,EAAE;GACzD,MAAM;GACN,GAAG,KAAK,KAAK;GACd,CAAC;AAEF,SAAO,IAAI,QAAQ,OAAO,YAAY;GAEpC,MAAM,OAAiB,OADX,MAAM,MAAM,IAAI,EACK,MAAM;AACvC,SAAM,IAAI,SAAS,KAAK;AACxB,WAAQ,KAAK;IACb;;CAGJ,eAAe;AACb,SAAO,IAAI,SAAe,SAAS,WAAW;AAC5C,OAAI,OAAO,WAAW,eAAe,OAAO,aAAa,aAAa;AACpE,YAAQ;AACR;;GAGF,MAAM,iBAAiB,SAAS,cAAc,SAAS;GACvD,IAAI,WAAW;AACf,OAAI,OAAO,YAAY,OAAO,SAAS,OACrC,YAAW,OAAO,SAAS;AAE7B,kBAAe,MAAM,UAAU,QAAQ,UAAU,kBAAkB,EAAE,EACnE,GAAG,KAAK,KAAK,EACd,CAAC;AACF,kBAAe,eAAe;AAC5B,aAAS;;AAEX,kBAAe,gBAAgB;AAC7B,YAAQ;;AAEV,YAAS,KAAK,OAAO,eAAe;IACpC;;CAGJ,UAAU,UAAqB;AAC7B,MAAI,SACF,QAAO,UAAU,UAAU;AAG7B,MAAI,OAAO,WAAW,eAAe,OAAO,aAAa,YACvD,QAAO;AAGT,SAAO,OAAO,UAAU,UAAU;;;;;;AC1BtC,IAAa,qBAAb,MAAgC;CAK9B,YAAY,EAAE,KAAK,YAAwD;AACzE,OAAK,MAAM;AACX,OAAK,WAAW,YAAY,IAAI,iBAAiB;;CAGnD,WAAW,QAAqC;AAC9C,SAAO,SAAS,QAAQ,QAAQ,8BAA8B,GAAG;;CAGnE,MAAM,gBAAgB,EAAE,KAAK,UAAoE;EAC/F,MAAM,UAAU,KAAK,WAAW,OAAO;EAEvC,MAAM,WAAW,MAAM,KAAK,SAAS,aAAa;EAClD,MAAM,EAAE,SAAS,MAAM,KAAK,IAAI,IAAI,qBAAqB;GACvD;GACA,QAAQ;IACN,SAAS;IACT,QAAQ,SAAS;IAClB;GACF,CAAC;AACF,SAAO;;;;;CAMT,MAAM,mBACJ,EAAE,WAAgC,EAAE,EACpC,SAA2B;EAAE,MAAM;EAAG,UAAU;EAAI,EAC1B;EAC1B,MAAM,UAAU,KAAK,WAAW,OAAO;EAEvC,MAAM,EAAE,SAAS,MAAM,KAAK,IAAI,IAAI,4BAA4B;GAAE;GAAS;GAAQ,CAAC;AACpF,SAAO;;CAGT,MAAM,mBAAmB,EACvB,IACA,QACA,SACA,YACA,UAOyB;EACzB,MAAM,UAAU,KAAK,WAAW,OAAO;EACvC,MAAM,EAAE,SAAS,MAAM,KAAK,IAAI,KAC9B,2BACA;GACE;GACA;GACA;GACA;GACD,EACD,EAAE,SAAS,CACZ;AACD,SAAO;;;;;;AC/GX,IAAa,mBAAb,MAA8B;CAG5B,YAAY,EAAE,WAAW,QAAQ,aAAsC,EAAE,EAAE;AACzE,OAAK,WAAW;;CAGlB,aAAa,MAAc;AAGzB,UAFkD,KAAK,UAAU,wBAAwB,EAAE,EACzD,MAAM,MAAW;GAAC,EAAE;GAAO,EAAE;GAAM,EAAE;GAAI,CAAC,SAAS,KAAK,CAAC;;CAI7F,uBAAuB,MAAuB;AAE5C,SADuB,KAAK,aAAa,KAAK,EAC5B,cAAc;;CAGlC,OAAO,MAAc,GAAG,OAAyB;EAC/C,MAAM,aAAa,KAAK,uBAAuB,KAAK;AAEpD,SAAO,QADQ,KAAK,UAAU,UAAU,IACjB,YAAY,GAAG,MAAM;;;;;;ACAhD,IAAa,mBAAb,MAA8B;CAO5B,YAAY,EAAE,KAAK,YAAwD;2BAF1B,EAAE;AAGjD,OAAK,MAAM;AACX,OAAK,WAAW,YAAY,IAAI,iBAAiB;;CAGnD,MAAM,oBAA4C;EAChD,MAAM,EAAE,SAAS,MAAM,KAAK,IAAI,IAAI,mCAAmC;AACvE,SAAO;;CAGT,UAAU,WAAW,KAAK,SAAS,aAAa,EAAE;AAEhD,UADkB,UAAU,UAAU,YACpB;;CAGpB,UAAU,WAAW,KAAK,SAAS,aAAa,EAAE;AAEhD,UADkB,UAAU,UAAU,YACpB;;CAGpB,oBAAoB,WAAW,KAAK,SAAS,aAAa,EAAE;AAE1D,SADe,KAAK,UAAU,SAAS,EACxB,WAAW;;CAG5B,gBAAgB,WAAW,KAAK,SAAS,aAAa,EAAE;AAEtD,SADe,KAAK,UAAU,SAAS,EACxB;;CAGjB,gBAAgB,WAAW,KAAK,SAAS,aAAa,EAAkB;EACtE,MAAM,SAAS,KAAK,UAAU,SAAS;AAEvC,MAAI,CADoB,CAAC,QAAQ,OAAO,CAEtC,QAAO;AAET,SAAO;GACL,OAAO,OAAO;GACd,SAAS,OAAO;GAChB,gBAAgB,OAAO;GACvB,SAAS,OAAO;GAChB,QAAQ,OAAO;GACf,QAAQ,OAAO;GACf,SAAS,OAAO;GAChB,cAAc,OAAO;GACrB,UAAU;GACX;;CAGH,cAAc,WAAW,KAAK,SAAS,aAAa,EAAwB;AAE1E,MAAI,SACF,QAAO;GACL,OAAO,SAAS;GAChB,SAAS,SAAS;GAClB,gBAAgB,SAAS;GACzB,SAAS,SAAS;GAClB,QAAQ,SAAS;GACjB,QAAQ,SAAS;GACjB,SAAS,SAAS;GAElB,cAAc;GACd,UAAU;GACX;AAGH,MAAI,OAAO,KAAK;GACd,MAAM,SAAS,OAAO;AACtB,UAAO;IACL,OAAO,OAAO;IACd,SAAS,OAAO;IAChB,gBAAgB,OAAO;IACvB,QAAQ,OAAO;IAEf,cAAc;IACd,UAAU;IACV,MAAM;IACP;;AAEH,SAAO;;CAGT,QAAQ,WAAW,KAAK,SAAS,aAAa,EAAE;EAC9C,MAAM,UAAU,EAAE;EAElB,MAAM,YAAY,KAAK,gBAAgB,SAAS;EAChD,MAAM,aAAa,KAAK,cAAc,SAAS;EAC/C,MAAM,mBAAmB,KAAK,oBAAoB,SAAS;AAE3D,MAAI,WACF,SAAQ,KAAK,WAAW;AAE1B,MAAI,aAAa,WAAW,UAAU,YAAY,SAAS,iBACzD,SAAQ,KAAK,UAAU;AAGzB,SAAO,QAAQ,SAAS;;CAG1B,MAAM,gBAAgB,QAAgB,QAAQ,OAAO;AACnD,MAAI,CAAC,SAAS,KAAK,kBAAkB,QACnC,QAAO,KAAK,kBAAkB;AAGhC,MAAI;GACF,MAAM,MAAM,IAAI,IAAI,mBAAmB,OAAO;AAC9C,OAAI,aAAa,IAAI,QAAQ,OAAO;GAEpC,MAAM,WAAW,OADL,MAAM,MAAM,IAAI,KAAK,EACN,MAAM;AACjC,QAAK,kBAAkB,UAAU;AACjC,UAAO;WACA,KAAK;AACZ,WAAQ,MAAM,gCAAgC,UAAU,IAAI;AAC5D,UAAO;;;;;;;;;;;AE5Ib,MAAa,SAAS,OAAO,MAAM;AACjC,QAAO,IAAI,SAAe,YAAY;AACpC,mBAAiB;AACf,YAAS;KACR,KAAK;GACR;;AAGJ,MAAa,kBAAkB,UAAkB;AAC/C,QAAO,UAAU,mBAAmB,MAAM;;AAG5C,MAAM,eAAe;AACrB,MAAM,qBAAqB;AAE3B,MAAa,qBAAqB;AAChC,QAAOA,OAAQ,IAAI,aAAa,IAAI,aAAa,QAAQ,mBAAmB;;AAW9E,MAAa,iBAAiB,OAAO,UAAe,WAAuB,aAAwB;AACjG,KACE,SAAS,SAAS,KAAK,IACvB,SAAS,UAAU,OACnB,SAAS,SAAS,OAClB,OAAO,WAAW,eAClB,OAAO,UAAU,SACjB,OAAO,UAAU,OACjB;AAEA,MAAI,CAAC,SACH,QAAO;AAGT,MAAI,CAAC,SAAS,KAAK,YAAY;AAC7B,cAAW;AACX,SAAM,IAAI,MAAM,mBAAmB;;EAGrC,MAAM,EAAE,OAAO,UAAU,OAAO;AAIhC,MAFe,MAAM,SADR,gBAAgB,KAAK,SAAS,MAAM,CAAC,aAAa,CAAC,CAAC,EAC7B,SAAS,KAAK,YAAY,OAAO,MAAM,KAE5D,OAAO;AACpB,cAAW;AACX,SAAM,IAAI,MAAM,mBAAmB;;;AAIvC,QAAO;;;;;ACzDT,SAAgB,eAAe;AAC7B,QAAO,OAAO,IAAI,eAAe;;AAGnC,SAAgB,gBAAgB;AAC9B,QAAO,OAAO,IAAI,cAAc;;AAGlC,eAAsB,2BAAsF;CAC1G,MAAM,YAAY,cAAc;AAChC,KAAI;EACF,MAAM,MAAc,QAAQ,OAAO,SAAS,QAAQ,+BAA+B,qBAAqB;EACxG,MAAM,EAAE,SAAS,MAAM,MAAM,IAAI,KAAK,EACpC,SAAS,EACP,gBAAgB,WACjB,EACF,CAAC;AAEF,SAAO;UACA,OAAO;AACd,UAAQ,MAAM,MAAM;AACpB,SAAO;GACL,YAAY,eAAe;GAC3B,WAAW;GACZ;;;;;;ACdL,IAAI;AAEJ,SAAS,oBAA0B;AACjC,KAAI,CAAC,gBAAgB;EACnB,MAAM,WAAW,QAAQ,UAAU,UAAU,SAAS;AACtD,mBAAiB,IAAI,KAAK;GACxB,OAAO,IAAI,kBAAkB;GAC7B,KAAK,SAAS,SAAS,GAAG,WAAW,MAAO,MAAO,KAAK;GACzD,CAAC;;AAEJ,QAAO;;AAUT,eAAe,gBAAgB,QAAqB,WAAmB,KAAK;AAC1E,QAAO,SAAS,UAAU,iBAAC,IAAI,MAAM;CACrC,MAAM,EAAE,WAAW,YAAY,OAAO;CACtC,MAAM,WAAW,UAAU;AAC3B,KAAI,WAAW,SAAU,OAAM,MAAM,WAAW,SAAS;AACzD,QAAO,OAAO;;AAGhB,MAAaC,iBAAe,SAAqD,kBAAkC;CACjH,MAAM,UAAU;EACd,GAAG,SAAS;EACZ,6BAA6B;EAC9B;CAED,MAAM,mBAAmB,IAAI,kBAAkB;CAE/C,MAAM,WAAW,MAAM,OAAO;EAC5B,GAAG;EACH;EACD,CAAC;AAEF,KAAI,eAAe,MAAM;AACvB,WAAS,aAAa,QAAQ,KAC3B,WAAwB;AACvB,UAAO,WAAW,EAAE,WAAW,iBAAC,IAAI,MAAM,EAAE;AAC5C,UAAO;MAER,QAAQ,QAAQ,OAAO,IAAI,CAC7B;AAED,WAAS,aAAa,SAAS,IAC7B,OAAO,QAAQ;AACb,OAAI,IAAI,OACN,OAAM,gBAAgB,IAAI,QAAQ,eAAe,SAAS;AAE5D,UAAO;KAET,OAAO,QAAQ;AACb,OAAI,IAAI,SACN,OAAM,gBAAgB,IAAI,SAAS,QAAQ,eAAe,SAAS;AAErE,UAAO,QAAQ,OAAO,IAAI;IAE7B;;AAGH,UAAS,aAAa,QAAQ,IAC5B,OAAO,WAAwB;EAC7B,MAAM,eAAe,eAAe,gBAAgB,OAAO,UAAU,aAAa,MAAM,IAAI,CAAC,KAAK;AAClG,SAAO,UAAU,OAAO,WAAW,iBAAiB,uBAAuB,aAAa;AACxF,SAAO,UAAU,OAAO,WAAW,KAAK;EAExC,MAAM,aAAa,eAAe;EAClC,MAAM,YAAY,cAAc;AAChC,MAAI,cAAc,WAAW;GAC3B,MAAM,gBAAgB,WAAW,MAAM,IAAI;GAC3C,MAAM,QAAQ,mBAAmB;GACjC,MAAM,qBAAqB,MAAM,MAAM,IAAI,cAAc;AACzD,OAAI,mBACF,QAAO,QAAQ,kBAAkB;QAC5B;IACL,MAAM,EAAE,YAAY,eAAe,WAAW,iBAAiB,MAAM,0BAA0B;AAC/F,QAAI,cAAc;AAChB,WAAM,MAAM,IAAI,cAAc,MAAM,IAAI,EAAE,aAAa;AACvD,YAAO,QAAQ,kBAAkB;UAEjC,QAAO,QAAQ,kBAAkB;;AAKrC,OAAI,OAAO,QAAQ,mBAAmB,OAAO,QAAQ,oBAAoB,cAAc,CACrF,QAAQ,IAAI,gBAAgB,OAAO,QAAQ,iBAAiB;IAC1D,UAAU;IACV,QAAQ;IACT,CAAC;;EAKN,MAAM,YAAY,cAAc;AAChC,MAAI,CAAC,CAAC,QAAW,KAAK,CAAC,SAAS,UAAU,CACxC,QAAO,QAAQ,2BAA2B;AAG5C,SAAO;KAER,UAAU,QAAQ,OAAO,MAAM,CACjC;AAED,QAAO;;AAGT,eAAeC,oBAAkB,cAAsB;AACrD,KAAI,CAAC,aACH,OAAM,IAAI,MAAM,0BAA0B;CAU5C,MAAM,EAAE,SAAS,MARED,cAAY;EAC7B,SAAS;EACT,SAAS,KAAK;EACd,QAAQ;EACR,SAAS,EACP,eAAe,eAAe,aAAa,EAC5C;EACF,CAAC,CACgC,KAAK,0BAA0B;AACjE,QAAO;;AAGT,SAAgBE,gBACd,EACE,iBACA,iBACA,oBACA,iBACA,iBACA,oBACA,qBACA,yBAWF,gBACA,eACA;CACA,IAAI,yBAA+C;CACnD,MAAM,UAAUF,cACd;EACE,SAAS,KAAK;EACd,GAAG;EACJ,EACD,cACD;AAED,SAAQ,aAAa,QAAQ,IAC3B,OAAO,WAAW;AAChB,MAAI,CAACG,OAAQ,IAAI,0BAA0B,EAAE;GAC3C,MAAM,QAAQ,gBAAgB,OAAO;AACrC,OAAI,MACF,QAAO,QAAQ,gBAAgB,eAAe,MAAM;;AAGxD,MAAI,uBACF,OAAM;AAGR,SAAO;KAER,UAAU,QAAQ,OAAO,MAAM,CACjC;AAED,SAAQ,aAAa,SAAS,IAC5B,OAAO,aAAkB;AACvB,MAAI,SAAS,QAAQ,OASnB,QARa,MAAM,eACjB,gBACM;AACJ,uBAAoB;AACpB,uBAAoB;KAEtB,eAAe,SAChB;AAGH,SAAO;IAET,OAAO,UAAU;EACf,MAAM,kBAAkB,MAAM;AAC9B,MAAI,iBAAiB;AACnB,mBAAgB,UAAU,iBAAiB,UAAU,EAAE,GAAG,gBAAgB,SAAS,GAAG,EAAE;AACxF,OAAI,OAAO,UAAU,WAAW,OAAO,CAAC,gBAAgB,QAAQ;AAC9D,oBAAgB,SAAS;AACzB,QAAI;AACF,SAAI,CAAC,uBACH,0BAAyBF,oBAAkB,iBAAiB,CAAC;KAE/D,MAAM,YAAY,MAAM;AACxB,qBAAgB,UAAU,UAAU;AACpC,qBAAgB,UAAU,iBAAiB;AAC3C,SAAI,OAAO,0BAA0B,WACnC,uBAAsB,UAAU;AAElC,YAAO,QAAQ,gBAAgB;aACxB,mBAAmB;AAC1B,yBAAoB;AACpB,yBAAoB;AACpB,SAAI,OAAO,wBAAwB,WACjC,qBAAoB,kBAAkB;AAGxC,YAAO,QAAQ,OAAO,MAAM;cACpB;AACR,8BAAyB;;;;AAI/B,SAAO,QAAQ,OAAO,MAAM;GAE/B;AACD,QAAO;;;;;ACrOT,SAAgBG,cAAY,gBAA6B,EAAE,EAAE,eAA+B;AAC1F,QAAO,OAAO,OAA+B,YAA0B;EACrE,MAAM,UAAU,KAAK,KAAK;EAC1B,MAAM,UAAuB;GAC3B,GAAG,eAAe;GAClB,GAAG,SAAS;GACZ,gBAAgB,cAAc;GAC9B,6BAA6B;GAC9B;EAED,MAAM,YAAY,cAAc;AAChC,MAAI,CAAC,CAAC,QAAW,KAAK,CAAC,SAAS,UAAU,CAExC,SAAQ,2BAA2B;EAGrC,MAAM,UAAU,MAAM,OAAO;GAC3B,GAAG;GACH,GAAG;GACH;GACD,CAAC;AACF,MAAI;AACF,UAAO;WAEA,OAAO;AACd,SAAM;YACE;GACR,MAAM,QAAQ,KAAK,KAAK;AACxB,OAAI,eAAe,MAAM;IACvB,MAAM,WAAW,eAAe,YAAY;IAC5C,MAAM,WAAW,QAAQ;AACzB,QAAI,WAAW,SAAU,OAAM,MAAM,WAAW,SAAS;;;;;AAMjE,eAAe,kBAAkB,cAAsB;AACrD,KAAI,CAAC,aACH,OAAM,IAAI,MAAM,0BAA0B;AAU5C,QADa,OAND,MADOA,eAAa,CACH,QAAQ,+BAA+B,0BAA0B,EAAE;EAC9F,QAAQ;EACR,SAAS,EACP,eAAe,eAAe,aAAa,EAC5C;EACF,CAAC,EACqB,MAAM;;AAI/B,SAAgB,cACd,EACE,SACA,iBACA,iBACA,oBACA,iBACA,iBACA,oBACA,qBACA,yBAYF,gBACA,eACA;CACA,IAAI,yBAA+C;CACnD,MAAM,UAAUA,cAAY,gBAAgB,cAAc;CAE1D,MAAM,mBAAmB,IAAI,kBAAkB;AAE/C,QAAO,OAAO,OAA+B,YAAiD;EAC5F,IAAI;EAEJ,IAAI,WAAW;AACf,MAAI,OAAO,UAAU,UACnB;OAAI,CAAC,MAAM,MAAM,CACf,KAAI,QACF,YAAW,QAAQ,SAAS,MAAM;QAC7B;IACL,MAAM,eAAe,eAAe,gBAAgB,OAAO,UAAU,aAAa,MAAM,IAAI,CAAC,KAAK;AAGlG,eAAW,QAFgB,iBAAiB,uBAAuB,aAAa,EAEjD,MAAM;;;AAK3C,MAAI,CAACC,OAAQ,IAAI,0BAA0B,EAAE;GAC3C,MAAM,QAAQ,gBAAgB,eAAe;AAC7C,OAAI,MACF,iBAAgB,eAAe,MAAM;;AAGzC,MAAI,uBACF,OAAM;EAER,MAAM,MAAM,MAAM,QAAQ,UAAU;GAClC,GAAG;GACH,SAAS;IACP,GAAG,SAAS;IACZ;IACD;GACF,CAAC;AACF,MAAI,CAAC,IAAI,MAAM,IAAI,WAAW,KAAK;AACjC,4BAAyB,kBAAkB,iBAAiB,CAAC;AAC7D,OAAI;IACF,MAAM,YAAY,MAAM;AACxB,oBAAgB,UAAU,UAAU;AACpC,oBAAgB,UAAU,iBAAiB;AAC3C,QAAI,OAAO,0BAA0B,WACnC,uBAAsB,UAAU;AAElC,WAAO,QAAQ,UAAU;KACvB,GAAG;KACH,SAAS;MACP,GAAG,SAAS;MACZ;MACD;KACF,CAAC;YACK,OAAO;AACd,wBAAoB;AACpB,wBAAoB;AACpB,QAAI,OAAO,wBAAwB,WACjC,qBAAoB,MAAM;AAG5B,WAAO;aACC;AACR,6BAAyB;;;AAK7B,MAAI,IAAI,MAAM,SAAS,OACrB,OAAM,eACJ;GAAE,QAAQ,IAAI;GAAQ,MAAM,MAAM,IAAI,MAAM;GAAE,QACxC;AACJ,uBAAoB;AACpB,uBAAoB;KAEtB,eAAe,SAChB;AAGH,SAAO;;;;;;ACxJX,IAAa,cAAb,MAAyB;CAavB,YAAY,SAA8B;EACxC,MAAM,eAAe,IAAI,cAAc;EACvC,MAAM,cAAcC,gBAClB;GACE,iBAAiB,aAAa;GAC9B,iBAAiB,aAAa;GAC9B,oBAAoB,aAAa;GACjC,iBAAiB,aAAa;GAC9B,iBAAiB,aAAa;GAC9B,oBAAoB,aAAa;GACjC,2BAA2B;AACzB,YAAQ,MAAM,0BAA0B;;GAE1C,6BAA6B;GAC9B,EACD,EACE,SAAS,+BACV,EACD,EACE,UAAU,SAAS,UACpB,CACF;EACD,MAAM,WAAW,IAAI,iBAAiB;AACtC,OAAK,OAAO,IAAI,YAAY;GAAE,KAAK;GAAa,OAAO;GAAc,CAAC;AACtE,OAAK,YAAY,IAAI,iBAAiB;GAAE,KAAK;GAAa;GAAU,CAAC;AACrE,OAAK,cAAc,IAAI,mBAAmB;GAAE,KAAK;GAAa;GAAU,CAAC;AACzE,OAAK,QAAQ;AACb,OAAK,WAAW;;;;AAKhB,OAAK,MAAM;;;AAIf,SAAgB,YAAY,SAA6B,EAAE,EAAE,gBAA+B,EAAE,EAAE;CAC9F,MAAM,eAAe,IAAI,cAAc;AAEvC,QAAOA,gBACL;EACE,iBAAiB,aAAa;EAC9B,iBAAiB,aAAa;EAC9B,oBAAoB,aAAa;EACjC,iBAAiB,aAAa;EAC9B,iBAAiB,aAAa;EAC9B,oBAAoB,aAAa;EACjC,2BAA2B;AACzB,WAAQ,MAAM,0BAA0B;;EAE1C,6BAA6B;EAC9B,EACD,QACA,cACD;;AAGH,SAAgB,YAAY,SAAuB,eAA+B;CAChF,MAAM,eAAe,IAAI,cAAc;AACvC,QAAOC,cACL;EACE,iBAAiB,aAAa;EAC9B,iBAAiB,aAAa;EAC9B,oBAAoB,aAAa;EACjC,iBAAiB,aAAa;EAC9B,iBAAiB,aAAa;EAC9B,oBAAoB,aAAa;EACjC,2BAA2B;AACzB,WAAQ,MAAM,0BAA0B;;EAE1C,6BAA6B;EAC9B,EACD,SACA,cACD;;AAIH,MAAa,wBAAwB;CACnC,IAAI;AAEJ,SAAQ,YAAiC;AACvC,MAAI,CAAC,SACH,YAAW,IAAI,YAAY,QAAQ;AAGrC,SAAO;;IAEP"}