{"version":3,"file":"authorizationChallengeEndpoint.mjs","names":[],"sources":["../../../src/openid4vc-issuer/router/authorizationChallengeEndpoint.ts"],"sourcesContent":["import type { AgentContext } from '@credo-ts/core'\nimport { joinUriParts, Kms, TypedArrayEncoder, utils } from '@credo-ts/core'\nimport type { HttpMethod, ParseAuthorizationChallengeRequestResult, RequestLike } from '@openid4vc/oauth2'\nimport { decodeJwt, Oauth2ErrorCodes, Oauth2ServerErrorResponseError } from '@openid4vc/oauth2'\nimport type { NextFunction, Response, Router } from 'express'\nimport {\n  OpenId4VcVerificationSessionRepository,\n  OpenId4VcVerificationSessionState,\n  OpenId4VcVerifierApi,\n} from '../../openid4vc-verifier'\nimport type { OpenId4VciCredentialConfigurationsSupportedWithFormats } from '../../shared'\nimport {\n  getAllowedAndRequestedScopeValues,\n  getCredentialConfigurationsSupportedForScopes,\n  getOfferedCredentials,\n  getScopesFromCredentialConfigurationsSupported,\n} from '../../shared'\nimport {\n  getRequestContext,\n  sendJsonResponse,\n  sendOauth2ErrorResponse,\n  sendUnknownServerErrorResponse,\n} from '../../shared/router'\nimport { OpenId4VcIssuanceSessionState } from '../OpenId4VcIssuanceSessionState'\nimport { OpenId4VcIssuerModuleConfig } from '../OpenId4VcIssuerModuleConfig'\nimport { OpenId4VcIssuerService } from '../OpenId4VcIssuerService'\nimport type { OpenId4VcIssuerRecord } from '../repository'\nimport { handlePushedAuthorizationRequest } from './pushedAuthorizationRequestEndpoint'\nimport type { OpenId4VcIssuanceRequest } from './requestContext'\n\nexport function configureAuthorizationChallengeEndpoint(router: Router, config: OpenId4VcIssuerModuleConfig) {\n  router.post(\n    config.authorizationChallengeEndpointPath,\n    async (request: OpenId4VcIssuanceRequest, response: Response, next: NextFunction) => {\n      const requestContext = getRequestContext(request)\n      const { agentContext, issuer } = requestContext\n\n      try {\n        const openId4VcIssuerService = agentContext.dependencyManager.resolve(OpenId4VcIssuerService)\n        const issuerMetadata = await openId4VcIssuerService.getIssuerMetadata(agentContext, issuer)\n        const authorizationServer = openId4VcIssuerService.getOauth2AuthorizationServer(agentContext)\n        const fullRequestUrl = joinUriParts(issuerMetadata.credentialIssuer.credential_issuer, [\n          config.authorizationChallengeEndpointPath,\n        ])\n        const requestLike = {\n          headers: new Headers(request.headers as Record<string, string>),\n          method: request.method as HttpMethod,\n          url: fullRequestUrl,\n        } as const\n\n        const parseResult = authorizationServer.parseAuthorizationChallengeRequest({\n          authorizationChallengeRequest: request.body,\n          request: requestLike,\n        })\n\n        const { authorizationChallengeRequest } = parseResult\n\n        if (authorizationChallengeRequest.auth_session) {\n          await handleAuthorizationChallengeWithAuthSession({\n            response,\n            next,\n            parseResult,\n            request: requestLike,\n            agentContext,\n            issuer,\n          })\n        } else {\n          // First call, no auth_session yet\n          await handleAuthorizationChallengeNoAuthSession({\n            agentContext,\n            issuer,\n            parseResult,\n            request: requestLike,\n          })\n        }\n      } catch (error) {\n        if (error instanceof Oauth2ServerErrorResponseError) {\n          return sendOauth2ErrorResponse(response, next, agentContext.config.logger, error)\n        }\n        return sendUnknownServerErrorResponse(response, next, agentContext.config.logger, error)\n      }\n    }\n  )\n}\n\n/**\n * Handle authorization challenge request without auth session. This endpoint\n * may fall back to a Pushed Authorization Request if no presentation during issuance\n * is required.\n */\nasync function handleAuthorizationChallengeNoAuthSession(options: {\n  agentContext: AgentContext\n  issuer: OpenId4VcIssuerRecord\n  parseResult: ParseAuthorizationChallengeRequestResult\n  request: RequestLike\n}) {\n  const { agentContext, issuer, parseResult, request } = options\n  const { authorizationChallengeRequest } = parseResult\n\n  const openId4VcIssuerService = agentContext.dependencyManager.resolve(OpenId4VcIssuerService)\n  const config = agentContext.dependencyManager.resolve(OpenId4VcIssuerModuleConfig)\n  const issuerMetadata = await openId4VcIssuerService.getIssuerMetadata(agentContext, issuer)\n\n  if (!authorizationChallengeRequest.issuer_state) {\n    throw new Oauth2ServerErrorResponseError({\n      error: Oauth2ErrorCodes.InvalidRequest,\n      error_description: `Missing required 'issuer_state' parameter. Only requests initiated by a credential offer are supported for authorization challenge.`,\n    })\n  }\n\n  if (!authorizationChallengeRequest.scope) {\n    throw new Oauth2ServerErrorResponseError({\n      error: Oauth2ErrorCodes.InvalidScope,\n      error_description: `Missing required 'scope' parameter`,\n    })\n  }\n\n  const issuanceSession = await openId4VcIssuerService.findSingleIssuanceSessionByQuery(agentContext, {\n    issuerId: issuer.issuerId,\n    issuerState: authorizationChallengeRequest.issuer_state,\n  })\n\n  const allowedStates = [OpenId4VcIssuanceSessionState.OfferCreated, OpenId4VcIssuanceSessionState.OfferUriRetrieved]\n  if (!issuanceSession || !allowedStates.includes(issuanceSession.state)) {\n    throw new Oauth2ServerErrorResponseError(\n      {\n        error: Oauth2ErrorCodes.InvalidRequest,\n        error_description: `Invalid 'issuer_state' parameter`,\n      },\n      {\n        internalMessage: !issuanceSession\n          ? `Issuance session not found for 'issuer_state' parameter '${authorizationChallengeRequest.issuer_state}'`\n          : `Issuance session '${issuanceSession.id}' has state '${\n              issuanceSession.state\n            }' but expected one of ${allowedStates.join(', ')}`,\n      }\n    )\n  }\n\n  if (issuanceSession?.chainedIdentity?.externalAuthorizationServerUrl) {\n    const clientId =\n      parseResult.authorizationChallengeRequest.client_id ??\n      (parseResult.clientAttestation?.clientAttestationJwt\n        ? // FIXME: export scheme for client attestation jwt\n          // FIXME: add sub to base jwt type\n          decodeJwt({\n            jwt: parseResult.clientAttestation.clientAttestationJwt,\n          }).payload.sub\n        : undefined)\n\n    if (!clientId || typeof clientId !== 'string') {\n      throw new Oauth2ServerErrorResponseError({\n        error: Oauth2ErrorCodes.InvalidClient,\n        error_description: `Missing required 'client_id' parameter in authorization request.`,\n      })\n    }\n\n    const { pushedAuthorizationResponse } = await handlePushedAuthorizationRequest(agentContext, {\n      issuer,\n      issuanceSession,\n      parsedAuthorizationRequest: {\n        clientAttestation: parseResult.clientAttestation,\n        dpop: parseResult.dpop,\n        authorizationRequest: {\n          ...parseResult.authorizationChallengeRequest,\n          response_type: 'code',\n          client_id: clientId,\n        },\n      },\n      request,\n    })\n\n    throw new Oauth2ServerErrorResponseError({\n      error: Oauth2ErrorCodes.RedirectToWeb,\n      error_description: 'Authorization required before issuance',\n      ...pushedAuthorizationResponse,\n    })\n  }\n\n  // From here on 'presentation' MUST be required\n  if (!issuanceSession.presentation?.required) {\n    throw new Oauth2ServerErrorResponseError(\n      {\n        error: Oauth2ErrorCodes.InvalidRequest,\n        error_description: `Invalid 'issuer_state' parameter`,\n      },\n      {\n        internalMessage: `Neither presentation during issuance or identity chaining was configured on issuance session '${issuanceSession.id}'`,\n      }\n    )\n  }\n\n  if (!config.getVerificationSession) {\n    throw new Oauth2ServerErrorResponseError(\n      {\n        error: Oauth2ErrorCodes.ServerError,\n      },\n      {\n        internalMessage: `Missing required 'getVerificationSession' callback in openid4vc issuer module config. This callback is required for presentation during issuance flows.`,\n      }\n    )\n  }\n\n  const authorizationServer = openId4VcIssuerService.getOauth2AuthorizationServer(agentContext, {\n    issuanceSessionId: issuanceSession.id,\n  })\n  const { clientAttestation, dpop } = await authorizationServer.verifyAuthorizationChallengeRequest({\n    authorizationChallengeRequest,\n    authorizationServerMetadata: issuerMetadata.authorizationServers[0],\n    request,\n    clientAttestation: {\n      ...parseResult.clientAttestation,\n      // First session config, fall back to global config\n      required: issuanceSession.walletAttestation?.required ?? config.walletAttestationsRequired,\n    },\n    dpop: {\n      ...parseResult.dpop,\n      // First session config, fall back to global config\n      required: issuanceSession.dpop?.required ?? config.dpopRequired,\n    },\n  })\n\n  // Bind dpop jwk thumbprint to session\n  if (dpop)\n    issuanceSession.dpop = {\n      // If dpop is provided at the start, it's required from now on.\n      required: true,\n      dpopJkt: dpop.jwkThumbprint,\n    }\n  if (clientAttestation)\n    issuanceSession.walletAttestation = {\n      // If client attestation is provided at the start, it's required from now on.\n      required: true,\n    }\n\n  const offeredCredentialConfigurations = getOfferedCredentials(\n    issuanceSession.credentialOfferPayload.credential_configuration_ids,\n    issuerMetadata.credentialIssuer.credential_configurations_supported\n  )\n\n  const allowedScopes = getScopesFromCredentialConfigurationsSupported(offeredCredentialConfigurations)\n  const requestedScopes = getAllowedAndRequestedScopeValues({\n    allowedScopes,\n    requestedScope: authorizationChallengeRequest.scope,\n  })\n  const requestedCredentialConfigurations = getCredentialConfigurationsSupportedForScopes(\n    offeredCredentialConfigurations,\n    requestedScopes\n  ) as OpenId4VciCredentialConfigurationsSupportedWithFormats\n\n  if (requestedScopes.length === 0 || Object.keys(requestedCredentialConfigurations).length === 0) {\n    throw new Oauth2ServerErrorResponseError({\n      error: Oauth2ErrorCodes.InvalidScope,\n      error_description: `No requested 'scope' values match with offered credential configurations.`,\n    })\n  }\n\n  const {\n    authorizationRequest,\n    verificationSession,\n    scopes: presentationScopes,\n  } = await config.getVerificationSession({\n    agentContext,\n    issuanceSession,\n    requestedCredentialConfigurations,\n    scopes: requestedScopes,\n  })\n\n  const kms = agentContext.resolve(Kms.KeyManagementApi)\n  // Store presentation during issuance session on the record\n  verificationSession.presentationDuringIssuanceSession = TypedArrayEncoder.toBase64Url(kms.randomBytes({ length: 32 }))\n  await agentContext.dependencyManager\n    .resolve(OpenId4VcVerificationSessionRepository)\n    .update(agentContext, verificationSession)\n\n  const authSession = TypedArrayEncoder.toBase64Url(kms.randomBytes({ length: 32 }))\n  issuanceSession.authorization = {\n    ...issuanceSession.authorization,\n    scopes: presentationScopes,\n  }\n  issuanceSession.presentation = {\n    required: true,\n    authSession,\n    openId4VcVerificationSessionId: verificationSession.id,\n  }\n\n  // If client attestation is used we have verified this client_id matches with the sub\n  // of the wallet attestation\n  issuanceSession.clientId = clientAttestation?.clientAttestation.payload.sub ?? authorizationChallengeRequest.client_id\n\n  await openId4VcIssuerService.updateState(\n    agentContext,\n    issuanceSession,\n    OpenId4VcIssuanceSessionState.AuthorizationInitiated\n  )\n\n  const authorizationChallengeErrorResponse = authorizationServer.createAuthorizationChallengePresentationErrorResponse(\n    {\n      authSession,\n      presentation: authorizationRequest,\n      errorDescription: 'Presentation required before issuance',\n    }\n  )\n  throw new Oauth2ServerErrorResponseError(authorizationChallengeErrorResponse)\n}\n\nasync function handleAuthorizationChallengeWithAuthSession(options: {\n  response: Response\n  agentContext: AgentContext\n  issuer: OpenId4VcIssuerRecord\n  next: NextFunction\n  parseResult: ParseAuthorizationChallengeRequestResult\n  request: RequestLike\n}) {\n  const { agentContext, issuer, parseResult, request, response, next } = options\n  const { authorizationChallengeRequest } = parseResult\n\n  const openId4VcIssuerService = agentContext.dependencyManager.resolve(OpenId4VcIssuerService)\n  const config = agentContext.dependencyManager.resolve(OpenId4VcIssuerModuleConfig)\n  const issuerMetadata = await openId4VcIssuerService.getIssuerMetadata(agentContext, issuer)\n\n  const verifierApi = agentContext.dependencyManager.resolve(OpenId4VcVerifierApi)\n\n  // NOTE: we ignore scope, issuer_state etc.. parameters if auth_session is present\n  // should we validate that these are not in the request? I'm not sure what best practice would be here\n\n  const issuanceSession = await openId4VcIssuerService.findSingleIssuanceSessionByQuery(agentContext, {\n    issuerId: issuer.issuerId,\n    presentationAuthSession: authorizationChallengeRequest.auth_session,\n  })\n  const allowedStates = [OpenId4VcIssuanceSessionState.AuthorizationInitiated]\n  if (\n    !issuanceSession?.presentation ||\n    !issuanceSession.presentation.openId4VcVerificationSessionId ||\n    !issuanceSession.presentation.authSession ||\n    !allowedStates.includes(issuanceSession.state)\n  ) {\n    throw new Oauth2ServerErrorResponseError(\n      {\n        error: Oauth2ErrorCodes.InvalidSession,\n        error_description: `Invalid 'auth_session'`,\n      },\n      {\n        internalMessage: !issuanceSession\n          ? `Issuance session not found for 'auth_session' parameter '${authorizationChallengeRequest.auth_session}'`\n          : !issuanceSession?.presentation\n            ? `Issuance session '${issuanceSession.id}' has no 'presentation'. This should not happen and means state is corrupted`\n            : `Issuance session '${issuanceSession.id}' has state '${\n                issuanceSession.state\n              }' but expected one of ${allowedStates.join(', ')}`,\n      }\n    )\n  }\n\n  const authorizationServer = openId4VcIssuerService.getOauth2AuthorizationServer(agentContext, {\n    issuanceSessionId: issuanceSession.id,\n  })\n  const { clientAttestation, dpop } = await authorizationServer.verifyAuthorizationChallengeRequest({\n    authorizationChallengeRequest,\n    authorizationServerMetadata: issuerMetadata.authorizationServers[0],\n    request,\n    clientAttestation: {\n      ...parseResult.clientAttestation,\n      // We only look at the issuance session here. If it is required\n      // it will be defined on the issuance session now.\n      required: issuanceSession.walletAttestation?.required,\n    },\n    dpop: {\n      ...parseResult.dpop,\n      // We only look at the issuance session here. If it is required\n      // it will be defined on the issuance session now.\n      required: issuanceSession.dpop?.required,\n    },\n  })\n\n  if (dpop && dpop.jwkThumbprint !== issuanceSession.dpop?.dpopJkt) {\n    throw new Oauth2ServerErrorResponseError(\n      {\n        error: Oauth2ErrorCodes.InvalidDpopProof,\n        error_description: 'Invalid jwk thumbprint',\n      },\n      {\n        internalMessage: `DPoP JWK thumbprint '${dpop.jwkThumbprint}' does not match expected value '${issuanceSession.dpop?.dpopJkt}'`,\n      }\n    )\n  }\n\n  if (clientAttestation && clientAttestation.clientAttestation.payload.sub !== issuanceSession.clientId) {\n    throw new Oauth2ServerErrorResponseError(\n      {\n        error: Oauth2ErrorCodes.InvalidClient,\n        error_description: 'Invalid client',\n      },\n      {\n        internalMessage: `Client id '${authorizationChallengeRequest.client_id}' from authorization challenge request does not match client id '${issuanceSession.clientId}' on issuance session`,\n      }\n    )\n  }\n\n  const { openId4VcVerificationSessionId } = issuanceSession.presentation\n\n  await verifierApi\n    .getVerificationSessionById(openId4VcVerificationSessionId)\n    .catch(async () => {\n      // Issuance session is corrupted\n      issuanceSession.errorMessage = `Associated openId4VcVerificationSessionRecord with id '${openId4VcVerificationSessionId}' does not exist`\n      await openId4VcIssuerService.updateState(agentContext, issuanceSession, OpenId4VcIssuanceSessionState.Error)\n\n      throw new Oauth2ServerErrorResponseError(\n        {\n          error: Oauth2ErrorCodes.InvalidSession,\n          error_description: `Invalid 'auth_session'`,\n        },\n        {\n          internalMessage: `Openid4vc verification session with id '${openId4VcVerificationSessionId}' not found during issuance session with id '${issuanceSession.id}'`,\n        }\n      )\n    })\n    .then(async (verificationSession) => {\n      // Issuance session cannot be used anymore\n      if (verificationSession.state === OpenId4VcVerificationSessionState.Error) {\n        issuanceSession.errorMessage = `Associated openId4VcVerificationSessionRecord with id '${openId4VcVerificationSessionId}' has error state`\n        await openId4VcIssuerService.updateState(agentContext, issuanceSession, OpenId4VcIssuanceSessionState.Error)\n      }\n\n      if (\n        verificationSession.state !== OpenId4VcVerificationSessionState.ResponseVerified ||\n        authorizationChallengeRequest.presentation_during_issuance_session !==\n          verificationSession.presentationDuringIssuanceSession\n      ) {\n        throw new Oauth2ServerErrorResponseError(\n          {\n            error: Oauth2ErrorCodes.InvalidSession,\n            error_description: `Invalid presentation for 'auth_session'`,\n          },\n          {\n            internalMessage:\n              verificationSession.state !== OpenId4VcVerificationSessionState.ResponseVerified\n                ? `Openid4vc verification session with id '${openId4VcVerificationSessionId}' has state '${verificationSession.state}', while '${OpenId4VcVerificationSessionState.ResponseVerified}' was expected.`\n                : `Openid4vc verification session with id '${openId4VcVerificationSessionId}' has 'presentation_during_issuance_session' '${verificationSession.presentationDuringIssuanceSession}', but authorization challenge request provided value '${authorizationChallengeRequest.presentation_during_issuance_session}'.`,\n          }\n        )\n      }\n    })\n\n  // Grant authorization\n  const kms = agentContext.resolve(Kms.KeyManagementApi)\n  const authorizationCode = TypedArrayEncoder.toBase64Url(kms.randomBytes({ length: 32 }))\n  const authorizationCodeExpiresAt = utils.addSecondsToDate(new Date(), config.authorizationCodeExpiresInSeconds)\n\n  issuanceSession.authorization = {\n    ...issuanceSession.authorization,\n    code: authorizationCode,\n    codeExpiresAt: authorizationCodeExpiresAt,\n  }\n\n  // TODO: we need to start using locks so we can't get corrupted state\n  await openId4VcIssuerService.updateState(\n    agentContext,\n    issuanceSession,\n    OpenId4VcIssuanceSessionState.AuthorizationGranted\n  )\n\n  const { authorizationChallengeResponse } = authorizationServer.createAuthorizationChallengeResponse({\n    authorizationCode,\n  })\n\n  return sendJsonResponse(response, next, authorizationChallengeResponse)\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA8BA,SAAgB,wCAAwC,QAAgB,QAAqC;AAC3G,QAAO,KACL,OAAO,oCACP,OAAO,SAAmC,UAAoB,SAAuB;EAEnF,MAAM,EAAE,cAAc,WADC,kBAAkB,QAAQ;AAGjD,MAAI;GACF,MAAM,yBAAyB,aAAa,kBAAkB,QAAQ,uBAAuB;GAC7F,MAAM,iBAAiB,MAAM,uBAAuB,kBAAkB,cAAc,OAAO;GAC3F,MAAM,sBAAsB,uBAAuB,6BAA6B,aAAa;GAC7F,MAAM,iBAAiB,aAAa,eAAe,iBAAiB,mBAAmB,CACrF,OAAO,mCACR,CAAC;GACF,MAAM,cAAc;IAClB,SAAS,IAAI,QAAQ,QAAQ,QAAkC;IAC/D,QAAQ,QAAQ;IAChB,KAAK;IACN;GAED,MAAM,cAAc,oBAAoB,mCAAmC;IACzE,+BAA+B,QAAQ;IACvC,SAAS;IACV,CAAC;GAEF,MAAM,EAAE,kCAAkC;AAE1C,OAAI,8BAA8B,aAChC,OAAM,4CAA4C;IAChD;IACA;IACA;IACA,SAAS;IACT;IACA;IACD,CAAC;OAGF,OAAM,0CAA0C;IAC9C;IACA;IACA;IACA,SAAS;IACV,CAAC;WAEG,OAAO;AACd,OAAI,iBAAiB,+BACnB,QAAO,wBAAwB,UAAU,MAAM,aAAa,OAAO,QAAQ,MAAM;AAEnF,UAAO,+BAA+B,UAAU,MAAM,aAAa,OAAO,QAAQ,MAAM;;GAG7F;;;;;;;AAQH,eAAe,0CAA0C,SAKtD;CACD,MAAM,EAAE,cAAc,QAAQ,aAAa,YAAY;CACvD,MAAM,EAAE,kCAAkC;CAE1C,MAAM,yBAAyB,aAAa,kBAAkB,QAAQ,uBAAuB;CAC7F,MAAM,SAAS,aAAa,kBAAkB,QAAQ,4BAA4B;CAClF,MAAM,iBAAiB,MAAM,uBAAuB,kBAAkB,cAAc,OAAO;AAE3F,KAAI,CAAC,8BAA8B,aACjC,OAAM,IAAI,+BAA+B;EACvC,OAAO,iBAAiB;EACxB,mBAAmB;EACpB,CAAC;AAGJ,KAAI,CAAC,8BAA8B,MACjC,OAAM,IAAI,+BAA+B;EACvC,OAAO,iBAAiB;EACxB,mBAAmB;EACpB,CAAC;CAGJ,MAAM,kBAAkB,MAAM,uBAAuB,iCAAiC,cAAc;EAClG,UAAU,OAAO;EACjB,aAAa,8BAA8B;EAC5C,CAAC;CAEF,MAAM,gBAAgB,CAAC,8BAA8B,cAAc,8BAA8B,kBAAkB;AACnH,KAAI,CAAC,mBAAmB,CAAC,cAAc,SAAS,gBAAgB,MAAM,CACpE,OAAM,IAAI,+BACR;EACE,OAAO,iBAAiB;EACxB,mBAAmB;EACpB,EACD,EACE,iBAAiB,CAAC,kBACd,4DAA4D,8BAA8B,aAAa,KACvG,qBAAqB,gBAAgB,GAAG,eACtC,gBAAgB,MACjB,wBAAwB,cAAc,KAAK,KAAK,IACtD,CACF;AAGH,KAAI,iBAAiB,iBAAiB,gCAAgC;EACpE,MAAM,WACJ,YAAY,8BAA8B,cACzC,YAAY,mBAAmB,uBAG5B,UAAU,EACR,KAAK,YAAY,kBAAkB,sBACpC,CAAC,CAAC,QAAQ,MACX;AAEN,MAAI,CAAC,YAAY,OAAO,aAAa,SACnC,OAAM,IAAI,+BAA+B;GACvC,OAAO,iBAAiB;GACxB,mBAAmB;GACpB,CAAC;EAGJ,MAAM,EAAE,gCAAgC,MAAM,iCAAiC,cAAc;GAC3F;GACA;GACA,4BAA4B;IAC1B,mBAAmB,YAAY;IAC/B,MAAM,YAAY;IAClB,sBAAsB;KACpB,GAAG,YAAY;KACf,eAAe;KACf,WAAW;KACZ;IACF;GACD;GACD,CAAC;AAEF,QAAM,IAAI,+BAA+B;GACvC,OAAO,iBAAiB;GACxB,mBAAmB;GACnB,GAAG;GACJ,CAAC;;AAIJ,KAAI,CAAC,gBAAgB,cAAc,SACjC,OAAM,IAAI,+BACR;EACE,OAAO,iBAAiB;EACxB,mBAAmB;EACpB,EACD,EACE,iBAAiB,iGAAiG,gBAAgB,GAAG,IACtI,CACF;AAGH,KAAI,CAAC,OAAO,uBACV,OAAM,IAAI,+BACR,EACE,OAAO,iBAAiB,aACzB,EACD,EACE,iBAAiB,2JAClB,CACF;CAGH,MAAM,sBAAsB,uBAAuB,6BAA6B,cAAc,EAC5F,mBAAmB,gBAAgB,IACpC,CAAC;CACF,MAAM,EAAE,mBAAmB,SAAS,MAAM,oBAAoB,oCAAoC;EAChG;EACA,6BAA6B,eAAe,qBAAqB;EACjE;EACA,mBAAmB;GACjB,GAAG,YAAY;GAEf,UAAU,gBAAgB,mBAAmB,YAAY,OAAO;GACjE;EACD,MAAM;GACJ,GAAG,YAAY;GAEf,UAAU,gBAAgB,MAAM,YAAY,OAAO;GACpD;EACF,CAAC;AAGF,KAAI,KACF,iBAAgB,OAAO;EAErB,UAAU;EACV,SAAS,KAAK;EACf;AACH,KAAI,kBACF,iBAAgB,oBAAoB,EAElC,UAAU,MACX;CAEH,MAAM,kCAAkC,sBACtC,gBAAgB,uBAAuB,8BACvC,eAAe,iBAAiB,oCACjC;CAGD,MAAM,kBAAkB,kCAAkC;EACxD,eAFoB,+CAA+C,gCAAgC;EAGnG,gBAAgB,8BAA8B;EAC/C,CAAC;CACF,MAAM,oCAAoC,8CACxC,iCACA,gBACD;AAED,KAAI,gBAAgB,WAAW,KAAK,OAAO,KAAK,kCAAkC,CAAC,WAAW,EAC5F,OAAM,IAAI,+BAA+B;EACvC,OAAO,iBAAiB;EACxB,mBAAmB;EACpB,CAAC;CAGJ,MAAM,EACJ,sBACA,qBACA,QAAQ,uBACN,MAAM,OAAO,uBAAuB;EACtC;EACA;EACA;EACA,QAAQ;EACT,CAAC;CAEF,MAAM,MAAM,aAAa,QAAQ,IAAI,iBAAiB;AAEtD,qBAAoB,oCAAoC,kBAAkB,YAAY,IAAI,YAAY,EAAE,QAAQ,IAAI,CAAC,CAAC;AACtH,OAAM,aAAa,kBAChB,QAAQ,uCAAuC,CAC/C,OAAO,cAAc,oBAAoB;CAE5C,MAAM,cAAc,kBAAkB,YAAY,IAAI,YAAY,EAAE,QAAQ,IAAI,CAAC,CAAC;AAClF,iBAAgB,gBAAgB;EAC9B,GAAG,gBAAgB;EACnB,QAAQ;EACT;AACD,iBAAgB,eAAe;EAC7B,UAAU;EACV;EACA,gCAAgC,oBAAoB;EACrD;AAID,iBAAgB,WAAW,mBAAmB,kBAAkB,QAAQ,OAAO,8BAA8B;AAE7G,OAAM,uBAAuB,YAC3B,cACA,iBACA,8BAA8B,uBAC/B;AASD,OAAM,IAAI,+BAPkC,oBAAoB,sDAC9D;EACE;EACA,cAAc;EACd,kBAAkB;EACnB,CACF,CAC4E;;AAG/E,eAAe,4CAA4C,SAOxD;CACD,MAAM,EAAE,cAAc,QAAQ,aAAa,SAAS,UAAU,SAAS;CACvE,MAAM,EAAE,kCAAkC;CAE1C,MAAM,yBAAyB,aAAa,kBAAkB,QAAQ,uBAAuB;CAC7F,MAAM,SAAS,aAAa,kBAAkB,QAAQ,4BAA4B;CAClF,MAAM,iBAAiB,MAAM,uBAAuB,kBAAkB,cAAc,OAAO;CAE3F,MAAM,cAAc,aAAa,kBAAkB,QAAQ,qBAAqB;CAKhF,MAAM,kBAAkB,MAAM,uBAAuB,iCAAiC,cAAc;EAClG,UAAU,OAAO;EACjB,yBAAyB,8BAA8B;EACxD,CAAC;CACF,MAAM,gBAAgB,CAAC,8BAA8B,uBAAuB;AAC5E,KACE,CAAC,iBAAiB,gBAClB,CAAC,gBAAgB,aAAa,kCAC9B,CAAC,gBAAgB,aAAa,eAC9B,CAAC,cAAc,SAAS,gBAAgB,MAAM,CAE9C,OAAM,IAAI,+BACR;EACE,OAAO,iBAAiB;EACxB,mBAAmB;EACpB,EACD,EACE,iBAAiB,CAAC,kBACd,4DAA4D,8BAA8B,aAAa,KACvG,CAAC,iBAAiB,eAChB,qBAAqB,gBAAgB,GAAG,gFACxC,qBAAqB,gBAAgB,GAAG,eACtC,gBAAgB,MACjB,wBAAwB,cAAc,KAAK,KAAK,IACxD,CACF;CAGH,MAAM,sBAAsB,uBAAuB,6BAA6B,cAAc,EAC5F,mBAAmB,gBAAgB,IACpC,CAAC;CACF,MAAM,EAAE,mBAAmB,SAAS,MAAM,oBAAoB,oCAAoC;EAChG;EACA,6BAA6B,eAAe,qBAAqB;EACjE;EACA,mBAAmB;GACjB,GAAG,YAAY;GAGf,UAAU,gBAAgB,mBAAmB;GAC9C;EACD,MAAM;GACJ,GAAG,YAAY;GAGf,UAAU,gBAAgB,MAAM;GACjC;EACF,CAAC;AAEF,KAAI,QAAQ,KAAK,kBAAkB,gBAAgB,MAAM,QACvD,OAAM,IAAI,+BACR;EACE,OAAO,iBAAiB;EACxB,mBAAmB;EACpB,EACD,EACE,iBAAiB,wBAAwB,KAAK,cAAc,mCAAmC,gBAAgB,MAAM,QAAQ,IAC9H,CACF;AAGH,KAAI,qBAAqB,kBAAkB,kBAAkB,QAAQ,QAAQ,gBAAgB,SAC3F,OAAM,IAAI,+BACR;EACE,OAAO,iBAAiB;EACxB,mBAAmB;EACpB,EACD,EACE,iBAAiB,cAAc,8BAA8B,UAAU,mEAAmE,gBAAgB,SAAS,wBACpK,CACF;CAGH,MAAM,EAAE,mCAAmC,gBAAgB;AAE3D,OAAM,YACH,2BAA2B,+BAA+B,CAC1D,MAAM,YAAY;AAEjB,kBAAgB,eAAe,0DAA0D,+BAA+B;AACxH,QAAM,uBAAuB,YAAY,cAAc,iBAAiB,8BAA8B,MAAM;AAE5G,QAAM,IAAI,+BACR;GACE,OAAO,iBAAiB;GACxB,mBAAmB;GACpB,EACD,EACE,iBAAiB,2CAA2C,+BAA+B,+CAA+C,gBAAgB,GAAG,IAC9J,CACF;GACD,CACD,KAAK,OAAO,wBAAwB;AAEnC,MAAI,oBAAoB,UAAU,kCAAkC,OAAO;AACzE,mBAAgB,eAAe,0DAA0D,+BAA+B;AACxH,SAAM,uBAAuB,YAAY,cAAc,iBAAiB,8BAA8B,MAAM;;AAG9G,MACE,oBAAoB,UAAU,kCAAkC,oBAChE,8BAA8B,yCAC5B,oBAAoB,kCAEtB,OAAM,IAAI,+BACR;GACE,OAAO,iBAAiB;GACxB,mBAAmB;GACpB,EACD,EACE,iBACE,oBAAoB,UAAU,kCAAkC,mBAC5D,2CAA2C,+BAA+B,eAAe,oBAAoB,MAAM,YAAY,kCAAkC,iBAAiB,mBAClL,2CAA2C,+BAA+B,gDAAgD,oBAAoB,kCAAkC,yDAAyD,8BAA8B,qCAAqC,KACnT,CACF;GAEH;CAGJ,MAAM,MAAM,aAAa,QAAQ,IAAI,iBAAiB;CACtD,MAAM,oBAAoB,kBAAkB,YAAY,IAAI,YAAY,EAAE,QAAQ,IAAI,CAAC,CAAC;CACxF,MAAM,6BAA6B,MAAM,iCAAiB,IAAI,MAAM,EAAE,OAAO,kCAAkC;AAE/G,iBAAgB,gBAAgB;EAC9B,GAAG,gBAAgB;EACnB,MAAM;EACN,eAAe;EAChB;AAGD,OAAM,uBAAuB,YAC3B,cACA,iBACA,8BAA8B,qBAC/B;CAED,MAAM,EAAE,mCAAmC,oBAAoB,qCAAqC,EAClG,mBACD,CAAC;AAEF,QAAO,iBAAiB,UAAU,MAAM,+BAA+B"}