@shipfox/client-logs 17.0.0 → 22.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-type.log +1 -0
  3. package/CHANGELOG.md +28 -0
  4. package/dist/components/agent-session-rows.d.ts +2 -1
  5. package/dist/components/agent-session-rows.d.ts.map +1 -1
  6. package/dist/components/agent-session-rows.js +34 -19
  7. package/dist/components/agent-session-rows.js.map +1 -1
  8. package/dist/components/log-group.d.ts +3 -2
  9. package/dist/components/log-group.d.ts.map +1 -1
  10. package/dist/components/log-group.js +12 -4
  11. package/dist/components/log-group.js.map +1 -1
  12. package/dist/components/log-view.d.ts +2 -1
  13. package/dist/components/log-view.d.ts.map +1 -1
  14. package/dist/components/log-view.js +76 -23
  15. package/dist/components/log-view.js.map +1 -1
  16. package/dist/components/output-log-row.d.ts.map +1 -1
  17. package/dist/components/output-log-row.js +1 -1
  18. package/dist/components/output-log-row.js.map +1 -1
  19. package/dist/components/system-markers.d.ts.map +1 -1
  20. package/dist/components/system-markers.js +9 -4
  21. package/dist/components/system-markers.js.map +1 -1
  22. package/dist/core/log-search.d.ts +7 -0
  23. package/dist/core/log-search.d.ts.map +1 -0
  24. package/dist/core/log-search.js +124 -0
  25. package/dist/core/log-search.js.map +1 -0
  26. package/dist/hooks/api/step-logs.d.ts +169 -1
  27. package/dist/hooks/api/step-logs.d.ts.map +1 -1
  28. package/dist/hooks/api/step-logs.js +23 -3
  29. package/dist/hooks/api/step-logs.js.map +1 -1
  30. package/dist/tsconfig.test.tsbuildinfo +1 -1
  31. package/package.json +3 -3
  32. package/src/components/agent-session-rows.tsx +36 -24
  33. package/src/components/log-group.tsx +18 -5
  34. package/src/components/log-view.test.tsx +146 -18
  35. package/src/components/log-view.tsx +81 -18
  36. package/src/components/output-log-row.tsx +5 -1
  37. package/src/components/system-markers.tsx +14 -4
  38. package/src/core/log-search.test.ts +96 -0
  39. package/src/core/log-search.ts +121 -0
  40. package/src/hooks/api/step-logs-query.test.tsx +42 -0
  41. package/src/hooks/api/step-logs.ts +19 -3
  42. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/hooks/api/step-logs.ts"],"sourcesContent":["import {readLogsResponseSchema} from '@shipfox/api-logs-dto';\nimport {ApiError, checkedApiRequest} from '@shipfox/client-api';\nimport {useQuery, useQueryClient} from '@tanstack/react-query';\nimport {useRef} from 'react';\nimport {\n mergeLogRead,\n STEP_LOG_LIVE_REFETCH_MS,\n type StepLogSnapshot,\n stepLogRefetchInterval,\n} from '#core/log-read.js';\nimport {parseLogNdjson, toLogRead} from './log-mapper.js';\n\nexport const stepLogsQueryKeys = {\n all: ['step-logs'] as const,\n detail: (stepId: string, attempt: number) =>\n [...stepLogsQueryKeys.all, 'detail', stepId, attempt] as const,\n};\n\ninterface ReadStepAttemptLogsPageParams {\n stepId: string;\n attempt: number;\n cursor: number;\n signal?: AbortSignal;\n}\n\nexport async function readStepAttemptLogsPage({\n stepId,\n attempt,\n cursor,\n signal,\n}: ReadStepAttemptLogsPageParams) {\n const params = new URLSearchParams({cursor: String(cursor)});\n const response = await checkedApiRequest(\n readLogsResponseSchema,\n `/steps/${encodeURIComponent(stepId)}/attempts/${attempt}/logs?${params.toString()}`,\n {signal},\n );\n return toLogRead(response);\n}\n\nclass StepLogObjectFetchError extends Error {\n readonly status: number;\n\n constructor(status: number) {\n super(`Could not load compacted logs (${status})`);\n this.name = 'StepLogObjectFetchError';\n this.status = status;\n }\n}\n\nasync function readPresignedLogObject(url: string, signal?: AbortSignal): Promise<string> {\n const response = await fetch(url, signal ? {signal} : undefined);\n if (!response.ok) throw new StepLogObjectFetchError(response.status);\n return await response.text();\n}\n\nexport function isMissingStepLogStreamError(error: unknown): boolean {\n return error instanceof ApiError && error.status === 404 && error.code === 'not-found';\n}\n\nexport interface UseStepAttemptLogsQueryOptions {\n retryMissingStream?: boolean;\n missingStreamRetryCount?: number | undefined;\n missingStreamRetryDelayMs?: number | undefined;\n initialErrorRetryCount?: number;\n initialErrorRetryDelayMs?: number;\n}\n\n/**\n * Narrow React Query wrapper for step logs. Its query function can read the prior\n * snapshot imperatively, but bounded missing-stream retries need a ref that resets\n * when the step, attempt, or retry budget changes. Keep that lifecycle state here\n * rather than exporting query options that could accidentally share it between views.\n */\nexport function useStepAttemptLogsQuery(\n stepId: string | undefined,\n attempt: number | undefined,\n options: UseStepAttemptLogsQueryOptions = {},\n) {\n const queryClient = useQueryClient();\n const missingStreamFailureCountRef = useRef(0);\n const missingStreamScopeRef = useRef<string | null>(null);\n const enabled = Boolean(stepId && attempt && Number.isInteger(attempt) && attempt > 0);\n const queryKey =\n enabled && stepId && attempt\n ? stepLogsQueryKeys.detail(stepId, attempt)\n : [...stepLogsQueryKeys.all, 'detail'];\n const missingStreamScope =\n enabled && stepId && attempt\n ? `${stepId}:${attempt}:${options.missingStreamRetryCount ?? 'unbounded'}`\n : null;\n if (missingStreamScopeRef.current !== missingStreamScope) {\n missingStreamScopeRef.current = missingStreamScope;\n missingStreamFailureCountRef.current = 0;\n }\n const initialErrorRetryCount = options.initialErrorRetryCount ?? 0;\n const initialErrorRetryDelayMs = options.initialErrorRetryDelayMs ?? STEP_LOG_LIVE_REFETCH_MS;\n const missingStreamRetryDelayMs = options.missingStreamRetryDelayMs ?? STEP_LOG_LIVE_REFETCH_MS;\n\n return useQuery({\n queryKey,\n enabled,\n queryFn: async ({signal}) => {\n const previous = queryClient.getQueryData<StepLogSnapshot>(queryKey);\n let response: Awaited<ReturnType<typeof readStepAttemptLogsPage>>;\n try {\n response = await readStepAttemptLogsPage({\n stepId: stepId ?? '',\n attempt: attempt ?? 0,\n cursor: previous?.nextCursor ?? 0,\n signal,\n });\n } catch (error) {\n if (\n options.retryMissingStream &&\n previous === undefined &&\n isMissingStepLogStreamError(error)\n ) {\n const retryCount = options.missingStreamRetryCount;\n if (retryCount === undefined) throw error;\n if (missingStreamFailureCountRef.current >= retryCount) {\n return emptyCompleteLogSnapshot();\n }\n missingStreamFailureCountRef.current += 1;\n }\n throw error;\n }\n\n missingStreamFailureCountRef.current = 0;\n\n if (response.mode === 'presigned') {\n const ndjson = await readPresignedLogObject(response.url, signal);\n return mergeLogRead(previous, {\n mode: 'presigned',\n response,\n records: parseLogNdjson(ndjson),\n });\n }\n\n return mergeLogRead(previous, {\n mode: 'inline',\n response,\n records: parseLogNdjson(response.ndjson),\n });\n },\n retry: (failureCount, error) => {\n if (initialErrorRetryCount <= 0) return false;\n if (queryClient.getQueryData<StepLogSnapshot>(queryKey) !== undefined) return false;\n if (options.retryMissingStream && isMissingStepLogStreamError(error)) return false;\n return failureCount < initialErrorRetryCount;\n },\n retryDelay: initialErrorRetryDelayMs,\n refetchInterval: (query) => {\n if (\n options.retryMissingStream &&\n query.state.data === undefined &&\n isMissingStepLogStreamError(query.state.error)\n ) {\n return missingStreamRetryDelayMs;\n }\n\n return stepLogRefetchInterval(query.state.data, query.state.status === 'error');\n },\n refetchIntervalInBackground: false,\n refetchOnMount: (query) => !query.state.data?.complete,\n refetchOnWindowFocus: (query) => !query.state.data?.complete,\n refetchOnReconnect: (query) => !query.state.data?.complete,\n });\n}\n\nfunction emptyCompleteLogSnapshot(): StepLogSnapshot {\n return {\n records: [],\n nextCursor: 0,\n source: 'inline',\n state: 'closed',\n complete: true,\n hasMore: false,\n truncated: false,\n totalBytes: null,\n expiresAt: null,\n };\n}\n"],"names":["readLogsResponseSchema","ApiError","checkedApiRequest","useQuery","useQueryClient","useRef","mergeLogRead","STEP_LOG_LIVE_REFETCH_MS","stepLogRefetchInterval","parseLogNdjson","toLogRead","stepLogsQueryKeys","all","detail","stepId","attempt","readStepAttemptLogsPage","cursor","signal","params","URLSearchParams","String","response","encodeURIComponent","toString","StepLogObjectFetchError","Error","status","name","readPresignedLogObject","url","fetch","undefined","ok","text","isMissingStepLogStreamError","error","code","useStepAttemptLogsQuery","options","queryClient","missingStreamFailureCountRef","missingStreamScopeRef","enabled","Boolean","Number","isInteger","queryKey","missingStreamScope","missingStreamRetryCount","current","initialErrorRetryCount","initialErrorRetryDelayMs","missingStreamRetryDelayMs","queryFn","previous","getQueryData","nextCursor","retryMissingStream","retryCount","emptyCompleteLogSnapshot","mode","ndjson","records","retry","failureCount","retryDelay","refetchInterval","query","state","data","refetchIntervalInBackground","refetchOnMount","complete","refetchOnWindowFocus","refetchOnReconnect","source","hasMore","truncated","totalBytes","expiresAt"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/hooks/api/step-logs.ts"],"sourcesContent":["import {readLogsResponseSchema} from '@shipfox/api-logs-dto';\nimport {ApiError, checkedApiRequest} from '@shipfox/client-api';\nimport {useQuery, useQueryClient} from '@tanstack/react-query';\nimport {useCallback, useRef} from 'react';\nimport {\n mergeLogRead,\n STEP_LOG_LIVE_REFETCH_MS,\n type StepLogSnapshot,\n stepLogRefetchInterval,\n} from '#core/log-read.js';\nimport {parseLogNdjson, toLogRead} from './log-mapper.js';\n\nexport const stepLogsQueryKeys = {\n all: ['step-logs'] as const,\n detail: (stepId: string, attempt: number) =>\n [...stepLogsQueryKeys.all, 'detail', stepId, attempt] as const,\n};\n\ninterface ReadStepAttemptLogsPageParams {\n stepId: string;\n attempt: number;\n cursor: number;\n signal?: AbortSignal;\n}\n\nexport async function readStepAttemptLogsPage({\n stepId,\n attempt,\n cursor,\n signal,\n}: ReadStepAttemptLogsPageParams) {\n const params = new URLSearchParams({cursor: String(cursor)});\n const response = await checkedApiRequest(\n readLogsResponseSchema,\n `/steps/${encodeURIComponent(stepId)}/attempts/${attempt}/logs?${params.toString()}`,\n {signal},\n );\n return toLogRead(response);\n}\n\nclass StepLogObjectFetchError extends Error {\n readonly status: number;\n\n constructor(status: number) {\n super(`Could not load compacted logs (${status})`);\n this.name = 'StepLogObjectFetchError';\n this.status = status;\n }\n}\n\nasync function readPresignedLogObject(url: string, signal?: AbortSignal): Promise<string> {\n const response = await fetch(url, signal ? {signal} : undefined);\n if (!response.ok) throw new StepLogObjectFetchError(response.status);\n return await response.text();\n}\n\nexport function isMissingStepLogStreamError(error: unknown): boolean {\n return error instanceof ApiError && error.status === 404 && error.code === 'not-found';\n}\n\nexport interface UseStepAttemptLogsQueryOptions {\n retryMissingStream?: boolean;\n missingStreamRetryCount?: number | undefined;\n missingStreamRetryDelayMs?: number | undefined;\n initialErrorRetryCount?: number;\n initialErrorRetryDelayMs?: number;\n}\n\n/**\n * Narrow React Query wrapper for step logs. Its query function can read the prior\n * snapshot imperatively, but bounded missing-stream retries need a ref that resets\n * when the step, attempt, or retry budget changes. Keep that lifecycle state here\n * rather than exporting query options that could accidentally share it between views.\n */\nexport function useStepAttemptLogsQuery(\n stepId: string | undefined,\n attempt: number | undefined,\n options: UseStepAttemptLogsQueryOptions = {},\n) {\n const queryClient = useQueryClient();\n const missingStreamFailureCountRef = useRef(0);\n const missingStreamScopeRef = useRef<string | null>(null);\n const manualRefetchRef = useRef(false);\n const enabled = Boolean(stepId && attempt && Number.isInteger(attempt) && attempt > 0);\n const queryKey =\n enabled && stepId && attempt\n ? stepLogsQueryKeys.detail(stepId, attempt)\n : [...stepLogsQueryKeys.all, 'detail'];\n const missingStreamScope =\n enabled && stepId && attempt\n ? `${stepId}:${attempt}:${options.missingStreamRetryCount ?? 'unbounded'}`\n : null;\n if (missingStreamScopeRef.current !== missingStreamScope) {\n missingStreamScopeRef.current = missingStreamScope;\n missingStreamFailureCountRef.current = 0;\n }\n const initialErrorRetryCount = options.initialErrorRetryCount ?? 0;\n const initialErrorRetryDelayMs = options.initialErrorRetryDelayMs ?? STEP_LOG_LIVE_REFETCH_MS;\n const missingStreamRetryDelayMs = options.missingStreamRetryDelayMs ?? STEP_LOG_LIVE_REFETCH_MS;\n\n const query = useQuery({\n queryKey,\n enabled,\n queryFn: async ({signal}) => {\n const previous = queryClient.getQueryData<StepLogSnapshot>(queryKey);\n const manualRefetch = manualRefetchRef.current;\n manualRefetchRef.current = false;\n let response: Awaited<ReturnType<typeof readStepAttemptLogsPage>>;\n try {\n response = await readStepAttemptLogsPage({\n stepId: stepId ?? '',\n attempt: attempt ?? 0,\n cursor: previous?.nextCursor ?? 0,\n signal,\n });\n } catch (error) {\n if (\n options.retryMissingStream &&\n previous === undefined &&\n isMissingStepLogStreamError(error) &&\n !manualRefetch\n ) {\n const retryCount = options.missingStreamRetryCount;\n if (retryCount === undefined) throw error;\n if (missingStreamFailureCountRef.current >= retryCount) {\n return emptyCompleteLogSnapshot();\n }\n missingStreamFailureCountRef.current += 1;\n }\n throw error;\n }\n\n missingStreamFailureCountRef.current = 0;\n\n if (response.mode === 'presigned') {\n const ndjson = await readPresignedLogObject(response.url, signal);\n return mergeLogRead(previous, {\n mode: 'presigned',\n response,\n records: parseLogNdjson(ndjson),\n });\n }\n\n return mergeLogRead(previous, {\n mode: 'inline',\n response,\n records: parseLogNdjson(response.ndjson),\n });\n },\n retry: (failureCount, error) => {\n if (initialErrorRetryCount <= 0) return false;\n if (queryClient.getQueryData<StepLogSnapshot>(queryKey) !== undefined) return false;\n if (options.retryMissingStream && isMissingStepLogStreamError(error)) return false;\n return failureCount < initialErrorRetryCount;\n },\n retryDelay: initialErrorRetryDelayMs,\n refetchInterval: (query) => {\n if (\n options.retryMissingStream &&\n query.state.data === undefined &&\n isMissingStepLogStreamError(query.state.error)\n ) {\n return missingStreamRetryDelayMs;\n }\n\n return stepLogRefetchInterval(query.state.data, query.state.status === 'error');\n },\n refetchIntervalInBackground: false,\n refetchOnMount: (query) => !query.state.data?.complete,\n refetchOnWindowFocus: (query) => !query.state.data?.complete,\n refetchOnReconnect: (query) => !query.state.data?.complete,\n });\n\n const refetchLogs = useCallback(() => {\n // React Query reuses an in-flight request when it has no cached data. Only\n // mark a refetch as manual when this call can start a new request; otherwise\n // the marker would be consumed by the next automatic poll.\n if (!query.isFetching || query.data !== undefined) {\n manualRefetchRef.current = true;\n }\n return query.refetch();\n }, [query.data, query.isFetching, query.refetch]);\n\n return {...query, refetchLogs};\n}\n\nfunction emptyCompleteLogSnapshot(): StepLogSnapshot {\n return {\n records: [],\n nextCursor: 0,\n source: 'inline',\n state: 'closed',\n complete: true,\n hasMore: false,\n truncated: false,\n totalBytes: null,\n expiresAt: null,\n };\n}\n"],"names":["readLogsResponseSchema","ApiError","checkedApiRequest","useQuery","useQueryClient","useCallback","useRef","mergeLogRead","STEP_LOG_LIVE_REFETCH_MS","stepLogRefetchInterval","parseLogNdjson","toLogRead","stepLogsQueryKeys","all","detail","stepId","attempt","readStepAttemptLogsPage","cursor","signal","params","URLSearchParams","String","response","encodeURIComponent","toString","StepLogObjectFetchError","Error","status","name","readPresignedLogObject","url","fetch","undefined","ok","text","isMissingStepLogStreamError","error","code","useStepAttemptLogsQuery","options","queryClient","missingStreamFailureCountRef","missingStreamScopeRef","manualRefetchRef","enabled","Boolean","Number","isInteger","queryKey","missingStreamScope","missingStreamRetryCount","current","initialErrorRetryCount","initialErrorRetryDelayMs","missingStreamRetryDelayMs","query","queryFn","previous","getQueryData","manualRefetch","nextCursor","retryMissingStream","retryCount","emptyCompleteLogSnapshot","mode","ndjson","records","retry","failureCount","retryDelay","refetchInterval","state","data","refetchIntervalInBackground","refetchOnMount","complete","refetchOnWindowFocus","refetchOnReconnect","refetchLogs","isFetching","refetch","source","hasMore","truncated","totalBytes","expiresAt"],"mappings":"AAAA,SAAQA,sBAAsB,QAAO,wBAAwB;AAC7D,SAAQC,QAAQ,EAAEC,iBAAiB,QAAO,sBAAsB;AAChE,SAAQC,QAAQ,EAAEC,cAAc,QAAO,wBAAwB;AAC/D,SAAQC,WAAW,EAAEC,MAAM,QAAO,QAAQ;AAC1C,SACEC,YAAY,EACZC,wBAAwB,EAExBC,sBAAsB,QACjB,oBAAoB;AAC3B,SAAQC,cAAc,EAAEC,SAAS,QAAO,kBAAkB;AAE1D,OAAO,MAAMC,oBAAoB;IAC/BC,KAAK;QAAC;KAAY;IAClBC,QAAQ,CAACC,QAAgBC,UACvB;eAAIJ,kBAAkBC,GAAG;YAAE;YAAUE;YAAQC;SAAQ;AACzD,EAAE;AASF,OAAO,eAAeC,wBAAwB,EAC5CF,MAAM,EACNC,OAAO,EACPE,MAAM,EACNC,MAAM,EACwB;IAC9B,MAAMC,SAAS,IAAIC,gBAAgB;QAACH,QAAQI,OAAOJ;IAAO;IAC1D,MAAMK,WAAW,MAAMrB,kBACrBF,wBACA,CAAC,OAAO,EAAEwB,mBAAmBT,QAAQ,UAAU,EAAEC,QAAQ,MAAM,EAAEI,OAAOK,QAAQ,IAAI,EACpF;QAACN;IAAM;IAET,OAAOR,UAAUY;AACnB;AAEA,IAAA,AAAMG,0BAAN,MAAMA,gCAAgCC;IAGpC,YAAYC,MAAc,CAAE;QAC1B,KAAK,CAAC,CAAC,+BAA+B,EAAEA,OAAO,CAAC,CAAC;QACjD,IAAI,CAACC,IAAI,GAAG;QACZ,IAAI,CAACD,MAAM,GAAGA;IAChB;AACF;AAEA,eAAeE,uBAAuBC,GAAW,EAAEZ,MAAoB;IACrE,MAAMI,WAAW,MAAMS,MAAMD,KAAKZ,SAAS;QAACA;IAAM,IAAIc;IACtD,IAAI,CAACV,SAASW,EAAE,EAAE,MAAM,IAAIR,wBAAwBH,SAASK,MAAM;IACnE,OAAO,MAAML,SAASY,IAAI;AAC5B;AAEA,OAAO,SAASC,4BAA4BC,KAAc;IACxD,OAAOA,iBAAiBpC,YAAYoC,MAAMT,MAAM,KAAK,OAAOS,MAAMC,IAAI,KAAK;AAC7E;AAUA;;;;;CAKC,GACD,OAAO,SAASC,wBACdxB,MAA0B,EAC1BC,OAA2B,EAC3BwB,UAA0C,CAAC,CAAC;IAE5C,MAAMC,cAAcrC;IACpB,MAAMsC,+BAA+BpC,OAAO;IAC5C,MAAMqC,wBAAwBrC,OAAsB;IACpD,MAAMsC,mBAAmBtC,OAAO;IAChC,MAAMuC,UAAUC,QAAQ/B,UAAUC,WAAW+B,OAAOC,SAAS,CAAChC,YAAYA,UAAU;IACpF,MAAMiC,WACJJ,WAAW9B,UAAUC,UACjBJ,kBAAkBE,MAAM,CAACC,QAAQC,WACjC;WAAIJ,kBAAkBC,GAAG;QAAE;KAAS;IAC1C,MAAMqC,qBACJL,WAAW9B,UAAUC,UACjB,GAAGD,OAAO,CAAC,EAAEC,QAAQ,CAAC,EAAEwB,QAAQW,uBAAuB,IAAI,aAAa,GACxE;IACN,IAAIR,sBAAsBS,OAAO,KAAKF,oBAAoB;QACxDP,sBAAsBS,OAAO,GAAGF;QAChCR,6BAA6BU,OAAO,GAAG;IACzC;IACA,MAAMC,yBAAyBb,QAAQa,sBAAsB,IAAI;IACjE,MAAMC,2BAA2Bd,QAAQc,wBAAwB,IAAI9C;IACrE,MAAM+C,4BAA4Bf,QAAQe,yBAAyB,IAAI/C;IAEvE,MAAMgD,QAAQrD,SAAS;QACrB8C;QACAJ;QACAY,SAAS,OAAO,EAACtC,MAAM,EAAC;YACtB,MAAMuC,WAAWjB,YAAYkB,YAAY,CAAkBV;YAC3D,MAAMW,gBAAgBhB,iBAAiBQ,OAAO;YAC9CR,iBAAiBQ,OAAO,GAAG;YAC3B,IAAI7B;YACJ,IAAI;gBACFA,WAAW,MAAMN,wBAAwB;oBACvCF,QAAQA,UAAU;oBAClBC,SAASA,WAAW;oBACpBE,QAAQwC,UAAUG,cAAc;oBAChC1C;gBACF;YACF,EAAE,OAAOkB,OAAO;gBACd,IACEG,QAAQsB,kBAAkB,IAC1BJ,aAAazB,aACbG,4BAA4BC,UAC5B,CAACuB,eACD;oBACA,MAAMG,aAAavB,QAAQW,uBAAuB;oBAClD,IAAIY,eAAe9B,WAAW,MAAMI;oBACpC,IAAIK,6BAA6BU,OAAO,IAAIW,YAAY;wBACtD,OAAOC;oBACT;oBACAtB,6BAA6BU,OAAO,IAAI;gBAC1C;gBACA,MAAMf;YACR;YAEAK,6BAA6BU,OAAO,GAAG;YAEvC,IAAI7B,SAAS0C,IAAI,KAAK,aAAa;gBACjC,MAAMC,SAAS,MAAMpC,uBAAuBP,SAASQ,GAAG,EAAEZ;gBAC1D,OAAOZ,aAAamD,UAAU;oBAC5BO,MAAM;oBACN1C;oBACA4C,SAASzD,eAAewD;gBAC1B;YACF;YAEA,OAAO3D,aAAamD,UAAU;gBAC5BO,MAAM;gBACN1C;gBACA4C,SAASzD,eAAea,SAAS2C,MAAM;YACzC;QACF;QACAE,OAAO,CAACC,cAAchC;YACpB,IAAIgB,0BAA0B,GAAG,OAAO;YACxC,IAAIZ,YAAYkB,YAAY,CAAkBV,cAAchB,WAAW,OAAO;YAC9E,IAAIO,QAAQsB,kBAAkB,IAAI1B,4BAA4BC,QAAQ,OAAO;YAC7E,OAAOgC,eAAehB;QACxB;QACAiB,YAAYhB;QACZiB,iBAAiB,CAACf;YAChB,IACEhB,QAAQsB,kBAAkB,IAC1BN,MAAMgB,KAAK,CAACC,IAAI,KAAKxC,aACrBG,4BAA4BoB,MAAMgB,KAAK,CAACnC,KAAK,GAC7C;gBACA,OAAOkB;YACT;YAEA,OAAO9C,uBAAuB+C,MAAMgB,KAAK,CAACC,IAAI,EAAEjB,MAAMgB,KAAK,CAAC5C,MAAM,KAAK;QACzE;QACA8C,6BAA6B;QAC7BC,gBAAgB,CAACnB,QAAU,CAACA,MAAMgB,KAAK,CAACC,IAAI,EAAEG;QAC9CC,sBAAsB,CAACrB,QAAU,CAACA,MAAMgB,KAAK,CAACC,IAAI,EAAEG;QACpDE,oBAAoB,CAACtB,QAAU,CAACA,MAAMgB,KAAK,CAACC,IAAI,EAAEG;IACpD;IAEA,MAAMG,cAAc1E,YAAY;QAC9B,2EAA2E;QAC3E,6EAA6E;QAC7E,2DAA2D;QAC3D,IAAI,CAACmD,MAAMwB,UAAU,IAAIxB,MAAMiB,IAAI,KAAKxC,WAAW;YACjDW,iBAAiBQ,OAAO,GAAG;QAC7B;QACA,OAAOI,MAAMyB,OAAO;IACtB,GAAG;QAACzB,MAAMiB,IAAI;QAAEjB,MAAMwB,UAAU;QAAExB,MAAMyB,OAAO;KAAC;IAEhD,OAAO;QAAC,GAAGzB,KAAK;QAAEuB;IAAW;AAC/B;AAEA,SAASf;IACP,OAAO;QACLG,SAAS,EAAE;QACXN,YAAY;QACZqB,QAAQ;QACRV,OAAO;QACPI,UAAU;QACVO,SAAS;QACTC,WAAW;QACXC,YAAY;QACZC,WAAW;IACb;AACF"}