bitsnap-react 1.22.0 → 1.23.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 (123) hide show
  1. package/AGENTS.md +20 -0
  2. package/dist/BitsnapCart-GK3MQGP7.js +2 -0
  3. package/dist/BitsnapCart-GK3MQGP7.js.map +1 -0
  4. package/dist/BitsnapCart-ZC6LMXLO.mjs +2 -0
  5. package/dist/CartProvider-FJDBDV4N.js +2 -0
  6. package/dist/CartProvider-FJDBDV4N.js.map +1 -0
  7. package/dist/{CartProvider-YUV2Q523.mjs → CartProvider-P7BZVK2M.mjs} +2 -2
  8. package/dist/PanelModelFiles-EKQRLF46.js.map +1 -1
  9. package/dist/analytics.js +1 -1
  10. package/dist/analytics.js.map +1 -1
  11. package/dist/analytics.mjs +1 -1
  12. package/dist/catalog.js +1 -1
  13. package/dist/catalog.js.map +1 -1
  14. package/dist/catalog.mjs +1 -1
  15. package/dist/chat.js +1 -1
  16. package/dist/chat.js.map +1 -1
  17. package/dist/chat.mjs +1 -1
  18. package/dist/{chunk-SAKZOHU7.js → chunk-2CL4B4KM.js} +2 -2
  19. package/dist/chunk-2CL4B4KM.js.map +1 -0
  20. package/dist/chunk-2D2TQK3R.js +2 -0
  21. package/dist/chunk-2D2TQK3R.js.map +1 -0
  22. package/dist/{chunk-C2AJ5B32.mjs → chunk-4AU5SEHU.mjs} +2 -2
  23. package/dist/chunk-6Q3VGPSF.js.map +1 -1
  24. package/dist/{chunk-ZFZR3CI5.js → chunk-7GSQV4NW.js} +2 -2
  25. package/dist/chunk-7GSQV4NW.js.map +1 -0
  26. package/dist/{chunk-WYRECFVW.js → chunk-CA5EJJW7.js} +2 -2
  27. package/dist/chunk-CA5EJJW7.js.map +1 -0
  28. package/dist/{chunk-U37ZH4YJ.js → chunk-DCICRN6G.js} +2 -2
  29. package/dist/chunk-DCICRN6G.js.map +1 -0
  30. package/dist/{chunk-QQSCVPOG.mjs → chunk-EVV25IKM.mjs} +2 -2
  31. package/dist/{chunk-QQSCVPOG.mjs.map → chunk-EVV25IKM.mjs.map} +1 -1
  32. package/dist/{chunk-MBSXTB6G.js → chunk-EVX5SQL2.js} +2 -2
  33. package/dist/chunk-EVX5SQL2.js.map +1 -0
  34. package/dist/chunk-FVZ4W7QG.js +5 -0
  35. package/dist/chunk-FVZ4W7QG.js.map +1 -0
  36. package/dist/chunk-GMQYQTUM.mjs +2 -0
  37. package/dist/chunk-GMQYQTUM.mjs.map +1 -0
  38. package/dist/{chunk-35ZQU353.js → chunk-I6QN3T6K.js} +2 -2
  39. package/dist/chunk-I6QN3T6K.js.map +1 -0
  40. package/dist/chunk-ILYJCT5S.js +2 -0
  41. package/dist/chunk-ILYJCT5S.js.map +1 -0
  42. package/dist/{chunk-QJOMFK4X.mjs → chunk-JRSQ2IGQ.mjs} +2 -2
  43. package/dist/chunk-JSDGZ4NY.js.map +1 -1
  44. package/dist/chunk-KOYBZORL.js.map +1 -1
  45. package/dist/{chunk-5MXBUGY3.mjs → chunk-M6QFQ3DR.mjs} +2 -2
  46. package/dist/chunk-MDAFPGPA.js.map +1 -1
  47. package/dist/{chunk-KFY6IOAA.js → chunk-MY6BPCRV.js} +2 -2
  48. package/dist/{chunk-ZFUE3AX5.mjs.map → chunk-MY6BPCRV.js.map} +1 -1
  49. package/dist/{chunk-QCIETNFZ.mjs → chunk-NMXTTD5M.mjs} +2 -2
  50. package/dist/chunk-PFKZ7KUU.js.map +1 -1
  51. package/dist/chunk-Q337IQNA.js.map +1 -1
  52. package/dist/{chunk-IVB3E4V3.mjs → chunk-RA6M3TJ3.mjs} +2 -2
  53. package/dist/{chunk-NCCP2UDM.mjs → chunk-SKQJESEB.mjs} +2 -2
  54. package/dist/chunk-STDV54FL.mjs +2 -0
  55. package/dist/chunk-STDV54FL.mjs.map +1 -0
  56. package/dist/{chunk-JS3KK56H.js → chunk-SZLSKIYU.js} +2 -2
  57. package/dist/chunk-SZLSKIYU.js.map +1 -0
  58. package/dist/chunk-W3RGQYPD.js.map +1 -1
  59. package/dist/{chunk-TVZLDLAV.mjs → chunk-W4EUYPJ3.mjs} +2 -2
  60. package/dist/chunk-Z3YOJ6NZ.js.map +1 -1
  61. package/dist/chunk-ZMEWUEZJ.mjs +5 -0
  62. package/dist/chunk-ZMEWUEZJ.mjs.map +1 -0
  63. package/dist/consent.js.map +1 -1
  64. package/dist/course.js +1 -1
  65. package/dist/course.js.map +1 -1
  66. package/dist/course.mjs +1 -1
  67. package/dist/embed/analytics.js +1 -1
  68. package/dist/errors.js.map +1 -1
  69. package/dist/index.css +1 -1
  70. package/dist/index.css.map +1 -1
  71. package/dist/index.js +1 -1
  72. package/dist/index.js.map +1 -1
  73. package/dist/index.mjs +1 -1
  74. package/dist/index.mjs.map +1 -1
  75. package/dist/internal.js.map +1 -1
  76. package/dist/methods-IEHZTZEY.mjs +2 -0
  77. package/dist/methods-S4KBRY2I.js +2 -0
  78. package/dist/methods-S4KBRY2I.js.map +1 -0
  79. package/dist/model-files-client-P4PORZJ6.js.map +1 -1
  80. package/dist/models.js.map +1 -1
  81. package/dist/returns.js +1 -1
  82. package/dist/returns.js.map +1 -1
  83. package/dist/returns.mjs +1 -1
  84. package/dist/viewer3d.js.map +1 -1
  85. package/dist/viewer3d.mjs +1 -1
  86. package/package.json +2 -2
  87. package/dist/BitsnapCart-AINUJQVF.mjs +0 -2
  88. package/dist/BitsnapCart-GP2UJSG4.js +0 -2
  89. package/dist/BitsnapCart-GP2UJSG4.js.map +0 -1
  90. package/dist/CartProvider-HTKGBPVA.js +0 -2
  91. package/dist/CartProvider-HTKGBPVA.js.map +0 -1
  92. package/dist/chunk-35ZQU353.js.map +0 -1
  93. package/dist/chunk-3TUL63IC.js +0 -2
  94. package/dist/chunk-3TUL63IC.js.map +0 -1
  95. package/dist/chunk-4JR74NXR.js +0 -2
  96. package/dist/chunk-4JR74NXR.js.map +0 -1
  97. package/dist/chunk-GLKBCVNH.mjs +0 -2
  98. package/dist/chunk-GLKBCVNH.mjs.map +0 -1
  99. package/dist/chunk-JS3KK56H.js.map +0 -1
  100. package/dist/chunk-KFY6IOAA.js.map +0 -1
  101. package/dist/chunk-MBSXTB6G.js.map +0 -1
  102. package/dist/chunk-QJBQ45R6.mjs +0 -5
  103. package/dist/chunk-QJBQ45R6.mjs.map +0 -1
  104. package/dist/chunk-SAKZOHU7.js.map +0 -1
  105. package/dist/chunk-SZNTXRFD.js +0 -5
  106. package/dist/chunk-SZNTXRFD.js.map +0 -1
  107. package/dist/chunk-U37ZH4YJ.js.map +0 -1
  108. package/dist/chunk-WYRECFVW.js.map +0 -1
  109. package/dist/chunk-ZFUE3AX5.mjs +0 -2
  110. package/dist/chunk-ZFZR3CI5.js.map +0 -1
  111. package/dist/methods-4Q37ITIM.js +0 -2
  112. package/dist/methods-4Q37ITIM.js.map +0 -1
  113. package/dist/methods-JLVRTNPE.mjs +0 -2
  114. /package/dist/{BitsnapCart-AINUJQVF.mjs.map → BitsnapCart-ZC6LMXLO.mjs.map} +0 -0
  115. /package/dist/{CartProvider-YUV2Q523.mjs.map → CartProvider-P7BZVK2M.mjs.map} +0 -0
  116. /package/dist/{chunk-C2AJ5B32.mjs.map → chunk-4AU5SEHU.mjs.map} +0 -0
  117. /package/dist/{chunk-QJOMFK4X.mjs.map → chunk-JRSQ2IGQ.mjs.map} +0 -0
  118. /package/dist/{chunk-5MXBUGY3.mjs.map → chunk-M6QFQ3DR.mjs.map} +0 -0
  119. /package/dist/{chunk-QCIETNFZ.mjs.map → chunk-NMXTTD5M.mjs.map} +0 -0
  120. /package/dist/{chunk-IVB3E4V3.mjs.map → chunk-RA6M3TJ3.mjs.map} +0 -0
  121. /package/dist/{chunk-NCCP2UDM.mjs.map → chunk-SKQJESEB.mjs.map} +0 -0
  122. /package/dist/{chunk-TVZLDLAV.mjs.map → chunk-W4EUYPJ3.mjs.map} +0 -0
  123. /package/dist/{methods-JLVRTNPE.mjs.map → methods-IEHZTZEY.mjs.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/emems/.t3/worktrees/bitsnap-react/emems-order-history-panel/dist/chunk-FVZ4W7QG.js","../src/panel/components/PanelLogin.tsx","../src/ui/card.tsx","../src/ui/email-code-login/EmailCodeLoginForm.tsx","../src/lib/render.text.tsx","../src/panel/audio-player/media.session.coordinator.ts","../src/panel/audio-player/AudioPlayer.tsx"],"names":["Card","className","props","jsx","cn","CardHeader","CardTitle","CardDescription","CardContent","MUTED","DARK_FIELD","EMAIL_FAILURES","LINK","EmailCodeLoginForm","login","texts","allowHaveCode","emailPlaceholder","emailInputId","codeInputId","buttonClassName","children","uid","useId","emailId","normalized"],"mappings":"AAAA,ylCAAgO,sDAAyC,sDAAuG,sDAAyC,sDAAyF,sDAAyF,sDAA+E,sDAAyE,sDAAgE,oDCApwB,+BAC0C,+CCKrE,SAFKA,EAAAA,CAAK,CAAE,SAAA,CAAAC,CAAAA,CAAW,GAAGC,CAAM,CAAA,CAAgC,CAClE,OACEC,6BAAAA,KAAC,CAAA,CACC,WAAA,CAAU,MAAA,CACV,SAAA,CAAWC,gCAAAA,mFACT,CACAH,CACF,CAAA,CACC,GAAGC,CAAAA,CACN,CAEJ,CAEA,SAASG,EAAAA,CAAW,CAAE,SAAA,CAAAJ,CAAAA,CAAW,GAAGC,CAAM,CAAA,CAAgC,CACxE,OACEC,6BAAAA,KAAC,CAAA,CACC,WAAA,CAAU,aAAA,CACV,SAAA,CAAWC,gCAAAA,0JACT,CACAH,CACF,CAAA,CACC,GAAGC,CAAAA,CACN,CAEJ,CAEA,SAASI,EAAAA,CAAU,CAAE,SAAA,CAAAL,CAAAA,CAAW,GAAGC,CAAM,CAAA,CAAgC,CACvE,OACEC,6BAAAA,KAAC,CAAA,CACC,WAAA,CAAU,YAAA,CACV,SAAA,CAAWC,gCAAAA,4BAAG,CAA8BH,CAAS,CAAA,CACpD,GAAGC,CAAAA,CACN,CAEJ,CAEA,SAASK,EAAAA,CAAgB,CAAE,SAAA,CAAAN,CAAAA,CAAW,GAAGC,CAAM,CAAA,CAAgC,CAC7E,OACEC,6BAAAA,KAAC,CAAA,CACC,WAAA,CAAU,kBAAA,CACV,SAAA,CAAWC,gCAAAA,+BAAG,CAAiCH,CAAS,CAAA,CACvD,GAAGC,CAAAA,CACN,CAEJ,CAeA,SAASM,EAAAA,CAAY,CAAE,SAAA,CAAAP,CAAAA,CAAW,GAAGC,CAAM,CAAA,CAAgC,CACzE,OACEC,6BAAAA,KAAC,CAAA,CACC,WAAA,CAAU,cAAA,CACV,SAAA,CAAWC,gCAAAA,MAAG,CAAQH,CAAS,CAAA,CAC9B,GAAGC,CAAAA,CACN,CAEJ,CCvEA,2CAA4B,IA6BtBO,EAAAA,CAAQ,yCAAA,CAERC,EAAAA,CACJ,0MAAA,CAEIC,EAAAA,CAAiB,IAAI,GAAA,CAAI,CAAC,cAAA,CAAgB,eAAA,CAAiB,qBAAqB,CAAC,CAAA,CACjFC,EAAAA,CACJ,sNAAA,CAOK,SAASC,EAAAA,CAAmB,CACjC,KAAA,CAAAC,CAAAA,CACA,KAAA,CAAAC,CAAAA,CACA,aAAA,CAAAC,CAAAA,CAAgB,CAAA,CAAA,CAChB,gBAAA,CAAAC,CAAAA,CACA,YAAA,CAAAC,CAAAA,CACA,WAAA,CAAAC,CAAAA,CACA,SAAA,CAAAlB,CAAAA,CACA,eAAA,CAAAmB,CAAAA,CACA,QAAA,CAAAC,CACF,CAAA,CAA4B,CAC1B,IAAMC,CAAAA,CAAMC,2BAAAA,CAAM,CACZC,CAAAA,kBAAUN,CAAAA,SAAgB,CAAA,EAAA;ACGlB,QAAA;ACSRO,YAAAA;ACqzB4D","file":"/home/emems/.t3/worktrees/bitsnap-react/emems-order-history-panel/dist/chunk-FVZ4W7QG.js","sourcesContent":[null,"import { useAutoAnimate } from \"@formkit/auto-animate/react\";\nimport { useEffect, useMemo, useRef, useState, type CSSProperties } from \"react\";\nimport { TurnstileChallenge } from \"../../captcha/TurnstileChallenge\";\nimport {\n InstrumentProvider,\n useInstrument,\n useInstrumentContext,\n type AnalyticsOption,\n} from \"../../analytics/instrument\";\nimport { getLocale } from \"../../components/checkout/locale\";\nimport { rpcProvider, useMutation } from \"../../rpc-provider\";\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"../../ui/card\";\nimport { kindFromRpcError } from \"../../ui/email-code-login/errors\";\nimport {\n LoginBrandLogo,\n type LoginLogoOptions,\n} from \"../../ui/email-code-login/LoginBrandLogo\";\nimport { EmailCodeLoginForm } from \"../../ui/email-code-login/EmailCodeLoginForm\";\nimport { pendingLoginKey } from \"../../ui/email-code-login/pending\";\nimport {\n useEmailCodeLogin,\n type EmailCodeAdapter,\n} from \"../../ui/email-code-login/useEmailCodeLogin\";\nimport {\n getAllowedReturnOrigins,\n setAllowedReturnOrigins,\n} from \"../config\";\nimport { panelFailureKind } from \"../login-adapter\";\nimport { resolvePanelLoginTexts, type PanelLoginTexts } from \"../login-texts\";\nimport { usePanelConfig } from \"../PanelProvider\";\nimport type { PanelLoginProps } from \"../types\";\nimport {\n buildAccessTokenRedirect,\n getReturnURLFromSearch,\n persistReturnURL,\n readPersistedReturnURL,\n} from \"../return-url\";\nimport { getPanelSession, savePanelSession } from \"../session-storage\";\n\nif (typeof window !== \"undefined\") {\n const currentOrigin = window.location.origin;\n const knownSiblings = [\n currentOrigin,\n \"https://bitsnap.pl\",\n \"https://kursy.bitsnap.pl\",\n ];\n if (getAllowedReturnOrigins().length === 0) {\n setAllowedReturnOrigins(Array.from(new Set(knownSiblings)));\n }\n}\n\n\n/** Props of {@link PanelLogin}; `PanelLoginProps` of the package is a superset. */\nexport type PanelLoginComponentProps = Pick<\n PanelLoginProps,\n \"analytics\" | \"texts\" | \"locale\" | \"showLogo\" | \"logoUrl\" | \"logoDarkUrl\"\n>;\n\ntype PanelLoginResult = { accessToken: string };\n\nconst PanelLoginForm = ({\n texts,\n projectID,\n host,\n locale,\n logo,\n}: {\n texts: PanelLoginTexts;\n projectID?: string;\n host?: string;\n locale?: string;\n logo: LoginLogoOptions;\n}) => {\n const [challengeVisible, setChallengeVisible] = useState(false);\n const challengeWaiter = useRef<((token: string | null) => void) | undefined>(undefined);\n const captchaToken = useRef(\"\");\n const beforeSend = useMemo(() => () => new Promise<boolean>((resolve) => {\n setChallengeVisible(true);\n const timer = window.setTimeout(() => { challengeWaiter.current = undefined; setChallengeVisible(false); resolve(false); }, 5 * 60 * 1000);\n challengeWaiter.current = (token) => { window.clearTimeout(timer); challengeWaiter.current = undefined; setChallengeVisible(false); captchaToken.current = token ?? \"\"; resolve(token !== null); };\n }), []);\n const instrument = useInstrumentContext();\n const { mutateAsync: loginUserAsync } = useMutation(\n rpcProvider.publicApi.userPanelLogin,\n );\n const { mutateAsync: verifyCodeAsync } = useMutation(\n rpcProvider.publicApi.userPanelLoginWithCode,\n );\n\n const adapter = useMemo<EmailCodeAdapter<PanelLoginResult>>(\n () => ({\n async send(email) {\n try {\n const response = await loginUserAsync({ email, turnstileToken: captchaToken.current });\n captchaToken.current = \"\";\n if (response.result.case === \"success\") {\n return {\n ok: true,\n retryIn: response.result.value.retryIn || undefined,\n challengeId: response.result.value.challengeId || undefined,\n };\n }\n return {\n ok: false,\n kind: panelFailureKind(\n response.result.case === \"failure\" ? response.result.value : 0,\n ),\n };\n } catch (cause) {\n return { ok: false, kind: kindFromRpcError(cause), cause };\n }\n },\n async verify({ email, code, challengeId }) {\n try {\n const response = await verifyCodeAsync({\n code: parseInt(code, 10),\n email,\n challengeId,\n });\n if (response.result.case === \"accessToken\" && response.result.value) {\n return { ok: true, value: { accessToken: response.result.value } };\n }\n return {\n ok: false,\n kind: panelFailureKind(\n response.result.case === \"failure\" ? response.result.value : 0,\n ),\n };\n } catch (cause) {\n return { ok: false, kind: kindFromRpcError(cause), cause };\n }\n },\n }),\n [loginUserAsync, verifyCodeAsync],\n );\n\n const login = useEmailCodeLogin<PanelLoginResult>({\n adapter,\n texts,\n beforeSend,\n storageKey: pendingLoginKey(\"panel\", projectID, host),\n onVerified: ({ accessToken }, email) => {\n instrument.track(\"panel_login\", {});\n savePanelSession(projectID, accessToken, email, host);\n const returnURL =\n typeof window !== \"undefined\" ? readPersistedReturnURL() : null;\n setTimeout(() => {\n if (returnURL) {\n window.location.href = buildAccessTokenRedirect(returnURL, accessToken);\n return;\n }\n window.location.reload();\n }, 100);\n },\n });\n\n const onCodeStep = login.step === \"code\";\n const title = onCodeStep && !login.needsEmail ? texts.codeTitle : texts.title;\n const description =\n onCodeStep && !login.needsEmail ? texts.codeDescription : texts.description;\n\n return (\n // Top-aligned: a vertically centred card moved when the step changed height.\n <main className=\"mx-auto flex w-full max-w-sm flex-1 flex-col justify-start pt-4 sm:pt-[12vh]\">\n <Card>\n <LoginBrandLogo\n projectId={projectID}\n locale={locale}\n className=\"px-4 sm:px-6\"\n {...logo}\n />\n <CardHeader className=\"px-4 sm:px-6\">\n <CardTitle role=\"heading\" aria-level={1} className=\"text-2xl\">\n {title}\n </CardTitle>\n <CardDescription>{description}</CardDescription>\n </CardHeader>\n <CardContent className=\"px-4 sm:px-6\">\n <EmailCodeLoginForm\n login={login}\n texts={texts}\n emailInputId=\"email\"\n codeInputId=\"verify-code\"\n />\n {challengeVisible && <TurnstileChallenge action=\"panel_login\" locale={locale} onToken={(token) => challengeWaiter.current?.(token)} onFailure={() => challengeWaiter.current?.(null)} />}\n </CardContent>\n </Card>\n </main>\n );\n};\n\nconst PanelLoginComponentWrapper = ({\n analytics,\n texts: textOverrides,\n locale,\n showLogo,\n logoUrl,\n logoDarkUrl,\n}: PanelLoginComponentProps) => {\n const { theme, allowedReturnOrigins, projectID, host } = usePanelConfig();\n const instrument = useInstrument(projectID, analytics, \"panel\");\n const texts = useMemo(\n () => resolvePanelLoginTexts(locale ?? getLocale(), textOverrides),\n [locale, textOverrides],\n );\n\n const styles = {\n \"--button-background-color\": theme?.colors?.brand ?? \"#FFFFFF\",\n \"--button-background-color-dark\": theme?.colors?.brandDark ?? \"#000000\",\n \"--button-text-color\": theme?.colors?.brandDark ?? \"#000000\",\n \"--button-text-color-dark\": theme?.colors?.brand ?? \"#FFFFFF\",\n } as CSSProperties;\n\n const [parent] = useAutoAnimate({\n duration: 300,\n easing: \"ease-in-out\",\n disrespectUserMotionPreference: false,\n });\n\n // Already signed in: leave the login page. Declared before the return URL\n // effect below, so that one (a token redirect) wins when both apply.\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n if (getPanelSession(projectID, host) != null) {\n window.location.href = window.location.href.replaceAll(\"login\", \"\");\n }\n }, [projectID, host]);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n if (window.parent !== window) return;\n\n const queryReturnURL = getReturnURLFromSearch(window.location.search);\n if (queryReturnURL) {\n persistReturnURL(queryReturnURL);\n }\n\n const returnURL = queryReturnURL ?? readPersistedReturnURL();\n if (!returnURL) return;\n\n const existingToken = getPanelSession(projectID, host);\n if (!existingToken) return;\n\n window.location.href = buildAccessTokenRedirect(returnURL, existingToken);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [allowedReturnOrigins, projectID, host]);\n\n return (\n <InstrumentProvider value={instrument}>\n <div className=\"bg-white text-black dark:bg-black dark:text-white\">\n <div\n className=\"font-inter flex min-h-screen w-full flex-col p-4\"\n style={styles}\n ref={parent}\n >\n <PanelLoginForm\n texts={texts}\n projectID={projectID}\n host={host}\n locale={locale}\n logo={{\n showLogo,\n logoUrl: logoUrl ?? theme?.logoURL,\n logoDarkUrl: logoDarkUrl ?? theme?.logoDarkURL,\n }}\n />\n </div>\n </div>\n </InstrumentProvider>\n );\n};\n\nexport const PanelLogin = (props: PanelLoginComponentProps = {}) => {\n return <PanelLoginComponentWrapper {...props} />;\n};\n","import * as React from \"react\"\n\nimport { cn } from \"@/src/lib/utils\"\n\nfunction Card({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card\"\n className={cn(\n \"bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\n \"@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn(\"leading-none font-semibold\", className)}\n {...props}\n />\n )\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n )\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-action\"\n className={cn(\n \"col-start-2 row-span-2 row-start-1 self-start justify-self-end\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-content\"\n className={cn(\"px-6\", className)}\n {...props}\n />\n )\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn(\"flex items-center px-6 [.border-t]:pt-6\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n}\n","import { CircleCheck } from \"lucide-react\";\nimport { useId, type FormEvent, type ReactNode } from \"react\";\nimport { cn } from \"@/src/lib/utils\";\nimport { Button } from \"../button\";\nimport { Input } from \"../input\";\nimport { Label } from \"../label\";\nimport { Spinner } from \"../spinner\";\nimport { OtpCodeField } from \"./OtpCodeField\";\nimport { fillText, type EmailCodeTexts } from \"./texts\";\nimport { type EmailCodeLogin } from \"./useEmailCodeLogin\";\n\nexport type EmailCodeLoginFormProps = {\n login: EmailCodeLogin;\n texts: EmailCodeTexts;\n /** Offers \"I already have a code\" under the e-mail step. */\n allowHaveCode?: boolean;\n /** Overrides the e-mail input placeholder. */\n emailPlaceholder?: string;\n /** `id` of the e-mail input; unique per instance by default. */\n emailInputId?: string;\n /** `id` of the code input; unique per instance by default. */\n codeInputId?: string;\n className?: string;\n /** Classes of the two primary buttons (brand colors). */\n buttonClassName?: string;\n /** Shown above the fields of the code step, after the \"sent to\" line. */\n children?: ReactNode;\n};\n\nconst MUTED = \"text-muted-foreground text-xs leading-5\";\n/** Borders of the dark theme: the `input` token is nearly the card colour. */\nconst DARK_FIELD =\n \"dark:border-foreground/30 dark:focus-visible:border-foreground/70 dark:focus-visible:ring-foreground/25 dark:aria-invalid:border-destructive-foreground dark:aria-invalid:ring-destructive-foreground/30\";\n/** Failures about the address itself; a throttled or failed send is not. */\nconst EMAIL_FAILURES = new Set([\"invalidEmail\", \"emailNotFound\", \"deliveryUnavailable\"]);\nconst LINK =\n \"inline-flex min-h-11 items-center px-1 text-sm underline underline-offset-4 hover:no-underline focus-visible:ring-[3px] focus-visible:ring-ring/50 rounded-sm outline-none disabled:opacity-50 disabled:no-underline\";\n\n/**\n * The two steps of the shared e-mail-code login. Markup only: all state comes\n * from {@link useEmailCodeLogin}. The surface wraps it in its own card or\n * dialog and renders the titles.\n */\nexport function EmailCodeLoginForm({\n login,\n texts,\n allowHaveCode = true,\n emailPlaceholder,\n emailInputId,\n codeInputId,\n className,\n buttonClassName,\n children,\n}: EmailCodeLoginFormProps) {\n const uid = useId();\n const emailId = emailInputId ?? `${uid}-email`;\n const codeId = codeInputId ?? `${uid}-code`;\n const noticeId = `${uid}-notice`;\n const hintId = `${uid}-hint`;\n\n const { notice } = login;\n const isError = notice?.kind === \"error\";\n const sending = login.busy === \"send\";\n const verifying = login.busy === \"verify\";\n const resending = login.busy === \"resend\";\n const buttonBase = cn(\"h-11 w-full\", buttonClassName);\n\n // Both live regions stay mounted (empty) so that a screen reader has\n // registered them before a message is put in; only their text changes.\n // The area reserves two lines, so a longer message does not push the buttons.\n const success = notice?.kind === \"success\";\n const noticeArea = (\n <div id={noticeId} className=\"min-h-10 text-sm leading-5\">\n <p\n role=\"alert\"\n className=\"font-medium text-red-700 dark:text-red-400\"\n >\n {isError ? notice.text : null}\n </p>\n <p\n role=\"status\"\n className={cn(\n \"flex items-start gap-1.5\",\n success\n ? \"font-medium text-emerald-700 dark:text-emerald-400\"\n : \"text-foreground\",\n )}\n >\n {success && <CircleCheck aria-hidden className=\"mt-0.5 size-4 shrink-0\" />}\n <span>{notice != null && !isError ? notice.text : null}</span>\n </p>\n </div>\n );\n const emailInvalid =\n isError &&\n login.step === \"email\" &&\n (notice.failure == null || EMAIL_FAILURES.has(notice.failure));\n\n const announcer = (\n <p className=\"sr-only\" role=\"status\" aria-live=\"polite\">\n {login.announcement}\n </p>\n );\n\n const emailField = (\n <div className=\"grid gap-2\">\n <Label htmlFor={emailId}>{texts.emailLabel}</Label>\n <Input\n id={emailId}\n ref={login.emailRef}\n name=\"email\"\n type=\"email\"\n autoComplete=\"email\"\n inputMode=\"email\"\n autoCapitalize=\"none\"\n autoCorrect=\"off\"\n spellCheck={false}\n autoFocus\n required\n className={cn(\n \"h-11 text-base disabled:opacity-100 disabled:text-foreground/70\",\n DARK_FIELD,\n )}\n placeholder={emailPlaceholder ?? texts.emailPlaceholder}\n value={login.email}\n disabled={login.isBusy}\n aria-invalid={emailInvalid ? true : undefined}\n aria-describedby={noticeId}\n onChange={(event) => login.setEmail(event.target.value)}\n />\n </div>\n );\n\n if (login.step === \"email\") {\n return (\n <form\n noValidate\n className={cn(\"flex flex-col gap-4\", className)}\n onSubmit={(event: FormEvent) => {\n event.preventDefault();\n void login.sendCode();\n }}\n >\n {announcer}\n {emailField}\n {noticeArea}\n <Button\n type=\"submit\"\n disabled={login.isBusy}\n aria-busy={sending}\n className={buttonBase}\n >\n {sending && <Spinner aria-hidden />}\n {sending ? texts.sending : texts.sendCode}\n </Button>\n {allowHaveCode && (\n <p className=\"flex flex-wrap items-center justify-center text-center text-sm\">\n {texts.haveCodePrompt !== \"\" && <span>{texts.haveCodePrompt}</span>}\n <button\n type=\"button\"\n className={LINK}\n disabled={login.isBusy}\n onClick={login.haveCode}\n >\n {texts.haveCode}\n </button>\n </p>\n )}\n </form>\n );\n }\n\n const [before, after] = texts.codeSentTo.split(\"{email}\");\n const dead = login.dead != null;\n const resendLabel = dead\n ? texts.resendNew\n : login.secondsLeft > 0\n ? fillText(texts.resendIn, { seconds: login.secondsLeft })\n : texts.resend;\n\n return (\n <form\n noValidate\n className={cn(\"flex flex-col gap-4\", className)}\n onSubmit={(event: FormEvent) => {\n event.preventDefault();\n void login.submitCode();\n }}\n >\n {announcer}\n {login.needsEmail ? (\n emailField\n ) : (\n <div className=\"flex flex-wrap items-center justify-between gap-x-2\">\n {/* The address moves to its own line before it is cut; the word\n joiner keeps the full stop with it. */}\n <p className=\"min-w-0 flex-[1_1_14rem] text-sm leading-5 break-words\">\n {before}\n <strong className=\"font-semibold\">{login.email}</strong>\n {\"\\u2060\"}\n {after}\n </p>\n <button\n type=\"button\"\n className={cn(LINK, \"-ml-1 shrink-0\")}\n disabled={login.isBusy}\n onClick={login.changeEmail}\n >\n {texts.changeEmail}\n </button>\n </div>\n )}\n {children}\n <div className=\"grid gap-2\">\n <Label htmlFor={codeId}>{texts.codeLabel}</Label>\n <OtpCodeField\n id={codeId}\n name=\"code\"\n inputRef={login.codeRef}\n value={login.code}\n onChange={login.setCode}\n onComplete={(value) => void login.submitCode(value)}\n disabled={login.isBusy || dead}\n invalid={isError && !login.needsEmail}\n aria-describedby={`${noticeId} ${hintId}`}\n />\n <p id={hintId} className={MUTED}>\n {texts.validity} {texts.spamHint}\n </p>\n </div>\n {noticeArea}\n <Button\n type=\"submit\"\n disabled={login.isBusy || dead}\n aria-busy={verifying}\n className={buttonBase}\n >\n {verifying && <Spinner aria-hidden />}\n {verifying ? texts.verifying : texts.verify}\n </Button>\n {login.needsEmail ? (\n <div className=\"flex justify-center\">\n <button\n type=\"button\"\n className={LINK}\n disabled={login.isBusy}\n onClick={login.changeEmail}\n >\n {texts.noCode}\n </button>\n </div>\n ) : (\n <Button\n type=\"button\"\n variant={dead ? \"default\" : \"outline\"}\n disabled={login.isBusy || (!dead && login.secondsLeft > 0)}\n aria-busy={resending}\n className={dead ? buttonBase : \"h-11 w-full\"}\n onClick={() => void login.resend()}\n >\n {resending && <Spinner aria-hidden />}\n {resendLabel}\n </Button>\n )}\n </form>\n );\n}\n","const URL_REGEX =\n /https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)/g;\n\ntype Replacements = {\n url: string;\n startIndex: number;\n endIndex: number;\n replacementText?: string;\n};\n\nconst findURLIndices = (text: string) => {\n const matches = [...text.matchAll(URL_REGEX)];\n return matches.map(\n (match) =>\n ({\n url: match[0],\n startIndex: match.index,\n endIndex: match.index + match[0].length - 1,\n }) as Replacements,\n );\n};\n\nconst replaceTextByIndices = (\n originalText: string,\n replacements: Replacements[],\n) => {\n let result = \"\";\n let lastIndex = 0;\n\n // Sort replacements by startIndex to handle them in order\n replacements.sort((a, b) => a.startIndex - b.startIndex);\n\n for (const { startIndex, endIndex, replacementText } of replacements) {\n // Append text before the current replacement\n result += originalText.slice(lastIndex, startIndex);\n // Append the replacement text\n result += replacementText;\n // Update lastIndex to after the replaced segment\n lastIndex = endIndex + 1;\n }\n\n // Append any remaining text after the last replacement\n result += originalText.slice(lastIndex);\n\n return result;\n};\n\nexport const renderText = (txt: string) => {\n const urlIndices = findURLIndices(txt);\n\n return (\n <p\n dangerouslySetInnerHTML={{\n __html: replaceTextByIndices(\n txt,\n urlIndices.map((el) => {\n el[\"replacementText\"] =\n `<a key=${el.url} href=${el.url} style=\"text-decoration: underline;\" target=\"_blank\">\n ${el.url}\n </a>`;\n return el;\n }),\n ),\n }}\n ></p>\n );\n};\n","/** Skip length of the player buttons and of the lock-screen skip handlers. */\nexport const SEEK_STEP_SECONDS = 10;\n\n/** Under this position \"previous track\" restarts the chapter instead of going back. */\nexport const PREVIOUS_TRACK_RESTART_SECONDS = 3;\n\nexport type MediaSessionArtwork = {\n src: string;\n sizes?: string;\n type?: string;\n};\n\nexport type MediaSessionMetadata = {\n title: string;\n album?: string;\n artist?: string;\n artwork?: string | MediaSessionArtwork | (string | MediaSessionArtwork)[];\n};\n\nconst MIME_BY_EXTENSION: Record<string, string> = {\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n webp: \"image/webp\",\n gif: \"image/gif\",\n avif: \"image/avif\",\n svg: \"image/svg+xml\",\n};\n\n/** Lock-screen artwork size we declare; the player does not decode the image. */\nconst ARTWORK_SIZES = \"512x512\";\n\nfunction mediaSessionAvailable(): boolean {\n return (\n typeof navigator != \"undefined\" &&\n typeof navigator.mediaSession != \"undefined\"\n );\n}\n\n/**\n * Turns an image URL into a media-session artwork entry. The `type` comes from\n * the file extension and is omitted when the extension is unknown, so the\n * browser does not get a wrong MIME type.\n */\nexport function mediaSessionArtworkFromUrl(url: string): MediaSessionArtwork {\n if (typeof url != \"string\" || url.length === 0) {\n return { src: url, sizes: ARTWORK_SIZES };\n }\n const withoutQuery = url.split(/[?#]/)[0];\n const extension = withoutQuery.includes(\".\")\n ? withoutQuery.slice(withoutQuery.lastIndexOf(\".\") + 1).toLowerCase()\n : \"\";\n const type = MIME_BY_EXTENSION[extension];\n const artwork: MediaSessionArtwork = { src: url, sizes: ARTWORK_SIZES };\n if (type != null) {\n artwork.type = type;\n }\n return artwork;\n}\n\nfunction normalizeArtwork(\n artwork: MediaSessionMetadata[\"artwork\"],\n): MediaSessionArtwork[] | undefined {\n if (artwork == null) {\n return undefined;\n }\n const entries = Array.isArray(artwork) ? artwork : [artwork];\n const normalized: MediaSessionArtwork[] = [];\n for (const entry of entries) {\n if (typeof entry === \"string\") {\n if (entry.length > 0) {\n normalized.push(mediaSessionArtworkFromUrl(entry));\n }\n continue;\n }\n if (entry != null && entry.src.length > 0) {\n normalized.push({\n src: entry.src,\n sizes: entry.sizes ?? ARTWORK_SIZES,\n ...(entry.type != null ? { type: entry.type } : {}),\n });\n }\n }\n return normalized.length > 0 ? normalized : undefined;\n}\n\nexport function mediaSessionSetMetadata(metadata: MediaSessionMetadata) {\n if (\n !mediaSessionAvailable() ||\n typeof MediaMetadata == \"undefined\"\n ) {\n return;\n }\n navigator.mediaSession.metadata = new MediaMetadata({\n title: metadata.title,\n album: metadata.album,\n artist: metadata.artist,\n artwork: normalizeArtwork(metadata.artwork),\n });\n}\n\nexport function mediaSessionPlay() {\n if (!mediaSessionAvailable()) return;\n navigator.mediaSession.playbackState = \"playing\";\n}\n\nexport function mediaSessionPause() {\n if (!mediaSessionAvailable()) return;\n navigator.mediaSession.playbackState = \"paused\";\n}\n\n/**\n * Reports duration, position and the real playback rate to the lock screen.\n * `setPositionState` throws on values it does not accept (no duration yet,\n * position past the end), so those calls are skipped or clamped.\n */\nexport function mediaSessionUpdateDurationAndPosition(\n duration: number | undefined,\n currentTime: number | undefined,\n playbackRate = 1,\n) {\n if (!mediaSessionAvailable()) return;\n if (duration == null || !Number.isFinite(duration) || duration <= 0) {\n return;\n }\n if (currentTime != null && isNaN(currentTime)) {\n return;\n }\n const position = Math.min(Math.max(currentTime ?? 0, 0), duration);\n const rate =\n Number.isFinite(playbackRate) && playbackRate > 0 ? playbackRate : 1;\n try {\n navigator.mediaSession.setPositionState({\n playbackRate: rate,\n duration,\n position,\n });\n } catch (e) {\n // Older browsers reject some combinations; the lock screen just keeps the\n // previous state.\n }\n}\n\nconst MEDIA_SESSION_ACTIONS: MediaSessionAction[] = [\n \"play\",\n \"pause\",\n \"stop\",\n \"seekbackward\",\n \"seekforward\",\n \"seekto\",\n \"previoustrack\",\n \"nexttrack\",\n];\n\nexport function startMediaSessionCoordinator(args: {\n title: string;\n album?: string;\n artist?: string;\n artwork?: MediaSessionMetadata[\"artwork\"];\n\n action: (details: MediaSessionActionDetails) => void;\n}) {\n if (!mediaSessionAvailable()) return;\n\n mediaSessionSetMetadata({\n title: args.title,\n album: args.album,\n artist: args.artist,\n artwork: args.artwork,\n });\n\n for (const action of MEDIA_SESSION_ACTIONS) {\n try {\n navigator.mediaSession.setActionHandler(action, (details) => {\n args.action(details);\n });\n } catch (e) {\n // The browser does not support this action (e.g. nexttrack).\n }\n }\n}\n\nexport function stopMediaSessionCoordinator() {\n if (!mediaSessionAvailable()) return;\n navigator.mediaSession.metadata = null;\n for (const action of MEDIA_SESSION_ACTIONS) {\n try {\n navigator.mediaSession.setActionHandler(action, null);\n } catch (e) {\n // Unsupported action; nothing to clear.\n }\n }\n}\n","import Hls from \"hls.js\";\nimport { Pause, Play, SkipBack, SkipForward } from \"lucide-react\";\nimport {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n type CSSProperties,\n} from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { Button } from \"../../ui/button\";\nimport LoadingIndicator from \"../LoadingIndicator\";\nimport {\n createHlsSource,\n playerErrorFromMediaError,\n prefersNativeHls,\n type HlsSource,\n type PlayerError,\n} from \"./hls-engine\";\nimport {\n PREVIOUS_TRACK_RESTART_SECONDS,\n SEEK_STEP_SECONDS,\n mediaSessionPause,\n mediaSessionPlay,\n mediaSessionSetMetadata,\n mediaSessionUpdateDurationAndPosition,\n startMediaSessionCoordinator,\n stopMediaSessionCoordinator,\n} from \"./media.session.coordinator\";\n\nimport \"./audio-player.css\";\nimport { useAudioTexts, formatTime } from \"./texts\";\nimport { playerStorage, SPEED_KEY, SPEEDS } from \"./storage\";\n\nexport type ChapterWithPublicUrl = {\n id: string;\n multimediaId?: string;\n name: string;\n description?: string;\n publicUrl: string;\n downloadableUrl?: string;\n duration?: number;\n};\n\n/** What the player could not play; `status` is the HTTP status when known. */\nexport type AudioPlayerError = PlayerError;\n\nexport type AudioPlayerMethods = {\n selectChapter: (chapter: ChapterWithPublicUrl) => void;\n /** Loads the current chapter again after an error, keeping the position. */\n retry: () => void;\n /** The error currently shown, if any. */\n getError: () => AudioPlayerError | null;\n};\n\ntype AudioPlayerProps = {\n locale?: string;\n chapters: ChapterWithPublicUrl[];\n styles: CSSProperties;\n updateCurrentTime?: (currentTime: number) => void;\n\n title?: string;\n imageURL?: string;\n /** Hide the repeated visual heading when the desktop details show the cover beside it. */\n coverShownBeside?: boolean;\n /** Book author, used as the lock-screen artist. */\n author?: string;\n\n setCurrentTimeHandler?: (seekTo: (second: number) => void) => void;\n uniqueProductID: string;\n\n onChapterChange?: (chapter: ChapterWithPublicUrl) => void;\n /** A fatal playback error the player could not recover from. */\n onError?: (error: AudioPlayerError) => void;\n /** The signed URL returned 401/403; the owner should refetch the chapters. */\n onExpiredUrl?: () => void;\n /** The last chapter ended. */\n onFinished?: () => void;\n};\n\nconst AudioPlayer = forwardRef<AudioPlayerMethods, AudioPlayerProps>(\n (\n {\n chapters,\n locale,\n styles,\n updateCurrentTime,\n setCurrentTimeHandler,\n title,\n imageURL,\n coverShownBeside,\n author,\n uniqueProductID,\n onChapterChange,\n onError,\n onExpiredUrl,\n onFinished,\n },\n ref,\n ) => {\n const t = useAudioTexts(locale);\n const [speed, setSpeed] = useState(1);\n const speedRef = useRef(1);\n const [chapterID, setChapterID] = useState<string>();\n const [sleepMode, setSleepMode] = useState(\"off\");\n const [sleepRemaining, setSleepRemaining] = useState(0);\n const sleepRef = useRef<{ mode: string; deadline: number }>({\n mode: \"off\",\n deadline: 0,\n });\n\n function cancelSleep() {\n sleepRef.current = { mode: \"off\", deadline: 0 };\n setSleepMode(\"off\");\n setSleepRemaining(0);\n }\n function changeSleep(mode: string) {\n const seconds = Number(mode) * 60;\n sleepRef.current = {\n mode,\n deadline: Number.isFinite(seconds) ? Date.now() + seconds * 1000 : 0,\n };\n setSleepMode(mode);\n setSleepRemaining(Number.isFinite(seconds) ? seconds : 0);\n }\n function changeSpeed(rate: number) {\n if (!SPEEDS.includes(rate)) return;\n setSpeed(rate);\n speedRef.current = rate;\n playerStorage.set(SPEED_KEY, String(rate));\n if (videoRef.current) videoRef.current.playbackRate = rate;\n updatePlayerDetails();\n }\n useEffect(() => {\n const saved = Number(playerStorage.get(SPEED_KEY));\n if (SPEEDS.includes(saved)) changeSpeed(saved);\n const timer = setInterval(() => {\n const { mode, deadline } = sleepRef.current;\n if (mode === \"off\" || mode === \"chapter\") return;\n const remaining = Math.max(\n 0,\n Math.ceil((deadline - Date.now()) / 1000),\n );\n setSleepRemaining(remaining);\n if (remaining === 0) {\n playWhenReadyRef.current = false;\n pause();\n cancelSleep();\n }\n }, 1000);\n return () => clearInterval(timer);\n }, []);\n\n enum PlayState {\n Playing,\n Paused,\n }\n\n const [playState, setPlayState] = useState<PlayState>(PlayState.Paused);\n const [currentTime, setCurrentTime] = useState<number | undefined>(\n undefined,\n );\n const [duration, setDuration] = useState<number | undefined>(undefined);\n const [isLoading, setIsLoading] = useState(false);\n const [playerError, setPlayerError] = useState<AudioPlayerError | null>(\n null,\n );\n\n const videoRef = useRef<HTMLVideoElement | null>(null);\n const hlsRef = useRef<HlsSource | null>(null);\n const timerRef = useRef<ReturnType<typeof setInterval> | undefined>(\n undefined,\n );\n\n const audioPlayerContainerRef = useRef<HTMLDivElement>(null!);\n\n const currentChapterRef = useRef<ChapterWithPublicUrl | null>(null);\n const playerErrorRef = useRef<AudioPlayerError | null>(null);\n\n /** Set by a user action; the next `loadeddata` starts playback once. */\n const playWhenReadyRef = useRef(false);\n /** Position restored for the chapter that is loading, once. */\n const resumedRef = useRef(false);\n /** Position to restore instead of the remembered one (URL refresh, retry). */\n const pendingSeekRef = useRef<number | null>(null);\n /** Chapter URL that already asked the owner for a fresh signed URL. */\n const expiredUrlRef = useRef<string | null>(null);\n const chaptersRef = useRef(chapters);\n const chaptersSignatureRef = useRef<string | null>(null);\n\n // The owner passes new callbacks on every render; the player must keep the\n // current ones without restarting playback.\n const callbacksRef = useRef({\n onChapterChange,\n onError,\n onExpiredUrl,\n onFinished,\n updateCurrentTime,\n title,\n imageURL,\n author,\n });\n callbacksRef.current = {\n onChapterChange,\n onError,\n onExpiredUrl,\n onFinished,\n updateCurrentTime,\n title,\n imageURL,\n author,\n };\n\n function saveLastPlayedTime(timeInSeconds: number) {\n if (\n !resumedRef.current ||\n !Number.isFinite(timeInSeconds) ||\n timeInSeconds < 0\n ) {\n return;\n }\n playerStorage.set(\n `__player__${uniqueProductID}_${currentChapterRef.current?.id}`,\n `${Math.floor(timeInSeconds)}`,\n );\n }\n\n function getLastPlayedTime(): number | undefined {\n const time = playerStorage.get(\n `__player__${uniqueProductID}_${currentChapterRef.current?.id}`,\n );\n\n if (time == null) {\n return undefined;\n }\n try {\n const result = parseInt(time);\n\n if (isNaN(result) || result < 0) {\n return undefined;\n }\n\n return result;\n } catch (e) {\n return undefined;\n }\n }\n\n function getLastSelectedChapterID(): string | undefined {\n const lastSelectedChapterID = playerStorage.get(\n `__player__${uniqueProductID}_last_chapter`,\n );\n if (lastSelectedChapterID == null) {\n return undefined;\n }\n return lastSelectedChapterID;\n }\n\n function setLastSelectedChapterID(chapterID: string) {\n playerStorage.set(`__player__${uniqueProductID}_last_chapter`, chapterID);\n }\n\n function deleteMemoryChapter(chapterID: string) {\n playerStorage.remove(`__player__${uniqueProductID}_${chapterID}`);\n }\n\n function syncMediaSessionMetadata(chapter: ChapterWithPublicUrl | null) {\n mediaSessionSetMetadata({\n title: chapter?.name ?? callbacksRef.current.title ?? \"\",\n album: callbacksRef.current.title,\n artist: callbacksRef.current.author,\n artwork: callbacksRef.current.imageURL,\n });\n }\n\n function reportError(error: AudioPlayerError) {\n playerErrorRef.current = error;\n setPlayerError(error);\n setIsLoading(false);\n callbacksRef.current.onError?.(error);\n }\n\n function clearError() {\n playerErrorRef.current = null;\n setPlayerError(null);\n }\n\n function attemptPlay() {\n const video = videoRef.current;\n if (video == null) {\n return;\n }\n const result = video.play() as Promise<void> | undefined;\n if (result != null && typeof result.catch == \"function\") {\n result.catch(() => {\n // The browser blocked playback; the user presses play.\n });\n }\n updatePlayerDetails();\n }\n\n function play() {\n attemptPlay();\n }\n\n function pause() {\n videoRef.current?.pause();\n updatePlayerDetails();\n }\n\n function togglePlayState() {\n if (playState === PlayState.Playing) {\n pause();\n return;\n }\n play();\n }\n\n function seekTo(toSecond: number) {\n const video = videoRef.current;\n if (video == null || !Number.isFinite(toSecond)) {\n return;\n }\n const knownDuration = Number.isFinite(video.duration)\n ? video.duration\n : 0;\n const target =\n knownDuration > 0\n ? Math.min(Math.max(toSecond, 0), knownDuration)\n : Math.max(toSecond, 0);\n setCurrentTime(target);\n video.currentTime = target;\n updatePlayerDetails();\n }\n\n function seekBy(seconds: number) {\n const video = videoRef.current;\n if (video == null) {\n return;\n }\n const knownDuration = Number.isFinite(video.duration)\n ? video.duration\n : undefined;\n let target = Math.max(video.currentTime + seconds, 0);\n if (knownDuration != null && target > knownDuration) {\n target = knownDuration;\n }\n seekTo(target);\n }\n\n function loadSource(src: string) {\n const video = videoRef.current;\n if (video == null) {\n return;\n }\n clearError();\n setIsLoading(true);\n\n if (prefersNativeHls(video)) {\n destroyHls();\n video.src = src;\n video.load();\n return;\n }\n\n if (Hls.isSupported()) {\n if (hlsRef.current == null) {\n hlsRef.current = createHlsSource({\n media: video,\n handlers: {\n onError: (error) => {\n reportError(error);\n },\n onExpiredUrl: () => {\n callbacksRef.current.onExpiredUrl?.();\n },\n },\n });\n }\n hlsRef.current.load(src);\n return;\n }\n\n // No Media Source and no native HLS: let the browser try the URL itself.\n destroyHls();\n video.src = src;\n video.load();\n }\n\n function destroyHls() {\n hlsRef.current?.destroy();\n hlsRef.current = null;\n }\n\n function playChapter(\n chapter: ChapterWithPublicUrl,\n options?: { play?: boolean },\n ) {\n const shouldPlay = options?.play === true;\n if (\n currentChapterRef.current &&\n videoRef.current &&\n !videoRef.current.ended\n ) {\n saveLastPlayedTime(videoRef.current.currentTime);\n }\n resumedRef.current = false;\n pendingSeekRef.current = null;\n playWhenReadyRef.current = shouldPlay;\n currentChapterRef.current = chapter;\n setChapterID(chapter.id);\n setCurrentTime(0);\n setDuration(chapter.duration);\n loadSource(chapter.publicUrl);\n syncMediaSessionMetadata(chapter);\n callbacksRef.current.onChapterChange?.(chapter);\n setLastSelectedChapterID(chapter.id);\n }\n\n function loadChapters(list: ChapterWithPublicUrl[]) {\n if (list.length === 0) {\n return;\n }\n\n const chapterID = getLastSelectedChapterID();\n const chapter =\n (chapterID != null\n ? list.find((candidate) => candidate.id === chapterID)\n : undefined) ?? list[0];\n\n // Mount and content changes never start playback on their own.\n playChapter(chapter, { play: false });\n }\n\n function playNextChapter() {\n const list = chaptersRef.current;\n const current = currentChapterRef.current;\n if (list == null || list.length === 0 || current == null) {\n return;\n }\n const currentChapterIndex = list.findIndex(\n (chapter) => chapter.id === current.id,\n );\n if (currentChapterIndex === -1) {\n return;\n }\n const nextChapterIndex = currentChapterIndex + 1;\n if (nextChapterIndex >= list.length) {\n finishPlayback(current);\n return;\n }\n playChapter(list[nextChapterIndex], { play: true });\n }\n\n function playPreviousChapter() {\n const list = chaptersRef.current;\n const current = currentChapterRef.current;\n if (current == null) {\n return;\n }\n const video = videoRef.current;\n if (video != null && video.currentTime > PREVIOUS_TRACK_RESTART_SECONDS) {\n seekTo(0);\n return;\n }\n const currentChapterIndex =\n list == null\n ? -1\n : list.findIndex((chapter) => chapter.id === current.id);\n if (currentChapterIndex > 0) {\n playChapter(list[currentChapterIndex - 1], { play: true });\n return;\n }\n seekTo(0);\n }\n\n function finishPlayback(chapter: ChapterWithPublicUrl) {\n // The chapter is done: no resume point, and the element stays at the end.\n deleteMemoryChapter(chapter.id);\n playWhenReadyRef.current = false;\n videoRef.current?.pause();\n setPlayState(PlayState.Paused);\n callbacksRef.current.onFinished?.();\n }\n\n function handleEnded() {\n const current = currentChapterRef.current;\n if (current == null) {\n return;\n }\n playerStorage.set(\n `__player__${uniqueProductID}_${current.id}_completed`,\n \"true\",\n );\n deleteMemoryChapter(current.id);\n if (sleepRef.current.mode === \"chapter\") {\n playWhenReadyRef.current = false;\n pause();\n cancelSleep();\n return;\n }\n playNextChapter();\n updatePlayerDetails();\n }\n\n function handleLoadedData() {\n const video = videoRef.current;\n if (video == null) {\n return;\n }\n setIsLoading(false);\n video.playbackRate = speedRef.current;\n expiredUrlRef.current = null;\n if (!resumedRef.current) {\n resumedRef.current = true;\n const pending = pendingSeekRef.current;\n pendingSeekRef.current = null;\n if (pending != null) {\n seekTo(pending);\n } else {\n const lastPlayedTime = getLastPlayedTime();\n if (lastPlayedTime != null) {\n seekTo(lastPlayedTime);\n }\n }\n }\n if (playWhenReadyRef.current) {\n playWhenReadyRef.current = false;\n attemptPlay();\n }\n }\n\n function handleMediaElementError() {\n const mediaError = videoRef.current?.error;\n const src = currentChapterRef.current?.publicUrl;\n // Safari plays HLS itself and reports an expired signed URL as a network\n // error (2) or an unsupported source (4). Ask for a fresh URL once per\n // URL; an error that repeats after that refresh is a real error.\n const refreshable = mediaError?.code === 2 || mediaError?.code === 4;\n if (\n refreshable &&\n hlsRef.current == null &&\n src != null &&\n expiredUrlRef.current !== src\n ) {\n expiredUrlRef.current = src;\n callbacksRef.current.onExpiredUrl?.();\n }\n reportError(playerErrorFromMediaError(mediaError));\n }\n\n function retry() {\n const chapter = currentChapterRef.current;\n const src = chapter?.publicUrl ?? hlsRef.current?.src;\n if (src == null) {\n return;\n }\n const video = videoRef.current;\n const position = video?.currentTime ?? 0;\n clearError();\n resumedRef.current = false;\n pendingSeekRef.current = position > 0 ? position : null;\n setCurrentTime(position);\n if (hlsRef.current != null) {\n hlsRef.current.retry();\n } else {\n loadSource(src);\n }\n }\n\n function handleMediaSessionAction(details: MediaSessionActionDetails) {\n switch (details.action) {\n case \"play\":\n play();\n break;\n case \"pause\":\n case \"stop\":\n pause();\n break;\n case \"seekbackward\":\n seekBy(-(details.seekOffset ?? SEEK_STEP_SECONDS));\n break;\n case \"seekforward\":\n seekBy(details.seekOffset ?? SEEK_STEP_SECONDS);\n break;\n case \"seekto\":\n // A seek to 0 is valid: only a missing time is ignored.\n if (details.seekTime != null) {\n seekTo(details.seekTime);\n }\n break;\n case \"previoustrack\":\n playPreviousChapter();\n break;\n case \"nexttrack\":\n playNextChapter();\n break;\n default:\n break;\n }\n }\n\n useImperativeHandle(ref, () => {\n return {\n selectChapter: (chapter: ChapterWithPublicUrl) => {\n playChapter(chapter, { play: true });\n },\n retry,\n getError: () => playerErrorRef.current,\n };\n });\n\n function updatePlayerDetails() {\n const video = videoRef.current;\n if (video == null) {\n return;\n }\n setPlayState(video.paused ? PlayState.Paused : PlayState.Playing);\n setDuration(video.duration);\n setCurrentTime(video.currentTime);\n if (!video.ended) {\n saveLastPlayedTime(video.currentTime);\n }\n mediaSessionUpdateDurationAndPosition(\n video.duration,\n video.currentTime,\n video.playbackRate,\n );\n if (\n video.networkState === video.NETWORK_LOADING &&\n video.readyState <= video.HAVE_FUTURE_DATA\n ) {\n setIsLoading(true);\n } else {\n setIsLoading(false);\n }\n callbacksRef.current.updateCurrentTime?.(video.currentTime);\n }\n\n // Lock-screen handlers are registered once; they read refs, so they always\n // see the current chapters and callbacks.\n useEffect(() => {\n startMediaSessionCoordinator({\n title: title ?? \"\",\n album: title,\n artist: author,\n artwork: imageURL,\n action: handleMediaSessionAction,\n });\n\n return () => {\n stopMediaSessionCoordinator();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // The book title, cover or author arrive after the details request.\n useEffect(() => {\n syncMediaSessionMetadata(currentChapterRef.current);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [title, author, imageURL]);\n\n useEffect(() => {\n const video = videoRef.current;\n if (video == null) {\n return;\n }\n video.addEventListener(\"loadeddata\", handleLoadedData);\n video.addEventListener(\"ended\", handleEnded);\n video.addEventListener(\"error\", handleMediaElementError);\n video.addEventListener(\"timeupdate\", updatePlayerDetails);\n video.addEventListener(\"play\", updatePlayerDetails);\n video.addEventListener(\"pause\", updatePlayerDetails);\n video.addEventListener(\"ratechange\", updatePlayerDetails);\n\n updatePlayerDetails();\n timerRef.current = setInterval(updatePlayerDetails, 500);\n\n return () => {\n video.removeEventListener(\"loadeddata\", handleLoadedData);\n video.removeEventListener(\"ended\", handleEnded);\n video.removeEventListener(\"error\", handleMediaElementError);\n video.removeEventListener(\"timeupdate\", updatePlayerDetails);\n video.removeEventListener(\"play\", updatePlayerDetails);\n video.removeEventListener(\"pause\", updatePlayerDetails);\n video.removeEventListener(\"ratechange\", updatePlayerDetails);\n if (timerRef.current != null) {\n clearInterval(timerRef.current);\n timerRef.current = undefined;\n }\n if (!video.ended) saveLastPlayedTime(video.currentTime);\n setCurrentTime(undefined);\n video.pause();\n destroyHls();\n video.removeAttribute(\"src\");\n video.load();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n if (setCurrentTimeHandler != null) {\n setCurrentTimeHandler(seekTo);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Compare by chapter ids and URLs: a new array with the same content must\n // not reload the stream or restart playback.\n const chaptersSignature = chapters\n .map((chapter) => `${chapter.id}|${chapter.publicUrl ?? \"\"}`)\n .join(\"\\n\");\n\n useEffect(() => {\n chaptersRef.current = chapters;\n const previousSignature = chaptersSignatureRef.current;\n if (previousSignature === chaptersSignature) {\n return;\n }\n chaptersSignatureRef.current = chaptersSignature;\n\n if (previousSignature == null) {\n loadChapters(chapters);\n return;\n }\n\n const current = currentChapterRef.current;\n if (current == null) {\n loadChapters(chapters);\n return;\n }\n const replacement = chapters.find((chapter) => chapter.id === current.id);\n if (replacement != null && replacement.publicUrl === current.publicUrl) {\n // Same stream, different array: keep playing.\n return;\n }\n if (replacement != null) {\n // A fresh signed URL for the chapter that is playing: keep the position\n // and whether it was playing.\n const video = videoRef.current;\n const position = video?.currentTime ?? 0;\n const wasPlaying = video != null && !video.paused;\n currentChapterRef.current = replacement;\n resumedRef.current = false;\n pendingSeekRef.current = position > 0 ? position : null;\n playWhenReadyRef.current = wasPlaying;\n loadSource(replacement.publicUrl);\n syncMediaSessionMetadata(replacement);\n callbacksRef.current.onChapterChange?.(replacement);\n setLastSelectedChapterID(replacement.id);\n return;\n }\n loadChapters(chapters);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [chaptersSignature]);\n\n useEffect(() => {\n switch (playState) {\n case PlayState.Playing:\n mediaSessionPlay();\n break;\n case PlayState.Paused:\n mediaSessionPause();\n break;\n }\n }, [playState]);\n\n const currentIndex = chapters.findIndex(\n (chapter) => chapter.id === chapterID,\n );\n const knownDuration =\n Number.isFinite(duration) && duration! > 0\n ? duration!\n : (chapters[currentIndex]?.duration ?? 0);\n const position = Math.min(\n Math.max(currentTime ?? 0, 0),\n knownDuration || Infinity,\n );\n const wholeBookKnown =\n chapters.length > 0 &&\n chapters.every(\n (chapter) => Number.isFinite(chapter.duration) && chapter.duration! > 0,\n );\n const remaining =\n Math.max(\n 0,\n knownDuration -\n position +\n (wholeBookKnown\n ? chapters\n .slice(currentIndex + 1)\n .reduce((sum, chapter) => sum + chapter.duration!, 0)\n : 0),\n ) / speed;\n const minutesLeft = Math.ceil(remaining / 60);\n const leftText = `${Math.floor(minutesLeft / 60) > 0 ? `${Math.floor(minutesLeft / 60)} h ` : \"\"}${minutesLeft % 60} min`;\n\n return (\n <div\n id=\"audio-player-container\"\n className=\"bitsnap-audio-player flex min-w-0 flex-col gap-3 text-neutral-900 dark:text-neutral-100\"\n style={\n {\n ...styles,\n \"--seek-before-width\": `${knownDuration > 0 ? (position / knownDuration) * 100 : 0}%`,\n } as CSSProperties\n }\n ref={audioPlayerContainerRef}\n data-player-error={playerError?.kind}\n >\n <video\n ref={videoRef}\n className=\"hidden\"\n poster={imageURL}\n title={title}\n />\n <div className={cn(\"flex min-w-0 items-center gap-3\", coverShownBeside && \"lg:hidden\")}>\n {imageURL && (\n <img\n src={imageURL}\n alt=\"\"\n className=\"h-16 w-16 shrink-0 rounded object-contain\"\n />\n )}\n <div className=\"min-w-0 break-words\">\n <p className=\"font-semibold\">\n {chapters[currentIndex]?.name ?? title}\n </p>\n {author && (\n <p className=\"text-sm text-neutral-600 dark:text-neutral-300\">\n {author}\n </p>\n )}\n </div>\n </div>\n {playerError && (\n <div\n role=\"alert\"\n className=\"rounded-lg bg-red-50 p-3 text-red-800 dark:bg-red-950 dark:text-red-200\"\n >\n <p>{t.error}</p>\n <Button variant=\"outline\" onClick={retry}>\n {t.retry}\n </Button>\n </div>\n )}\n <input\n type=\"range\"\n min=\"0\"\n max={knownDuration || 100}\n value={position}\n disabled={!knownDuration}\n aria-label={t.progress}\n aria-valuetext={`${formatTime(position)} ${t.of} ${formatTime(knownDuration)}`}\n onChange={(event) => seekTo(Number(event.target.value))}\n />\n <section className=\"flex w-full justify-between text-sm tabular-nums\">\n <span id=\"current-time\">{formatTime(position)}</span>\n <span id=\"duration\">{formatTime(knownDuration)}</span>\n </section>\n {knownDuration > 0 && (\n <p className=\"text-sm text-neutral-600 dark:text-neutral-300\">\n {t.left === \"left\"\n ? `${leftText} ${t.left}`\n : `${t.left} ${leftText}`}{\" \"}\n · {wholeBookKnown ? t.book : t.chapter} ({speed}×)\n </p>\n )}\n <div className=\"flex flex-wrap items-center justify-center gap-2\">\n <Button\n variant=\"outline\"\n onClick={playPreviousChapter}\n disabled={currentIndex < 0}\n aria-label={t.previous}\n >\n <SkipBack className=\"h-5 w-5\" />\n </Button>\n <Button\n variant=\"outline\"\n onClick={() => seekBy(-SEEK_STEP_SECONDS)}\n aria-label={t.rewind}\n >\n −{SEEK_STEP_SECONDS}\n </Button>\n <Button\n variant=\"outline\"\n onClick={togglePlayState}\n aria-label={playState === PlayState.Paused ? t.play : t.pause}\n >\n {playState === PlayState.Paused ? (\n <Play className=\"h-5 w-5\" />\n ) : (\n <Pause className=\"h-5 w-5\" />\n )}\n </Button>\n <Button\n variant=\"outline\"\n onClick={() => seekBy(SEEK_STEP_SECONDS)}\n aria-label={t.forward}\n >\n +{SEEK_STEP_SECONDS}\n </Button>\n <Button\n variant=\"outline\"\n onClick={playNextChapter}\n disabled={currentIndex < 0 || currentIndex >= chapters.length - 1}\n aria-label={t.next}\n >\n <SkipForward className=\"h-5 w-5\" />\n </Button>\n </div>\n <div className=\"flex flex-wrap gap-3 md:grid md:grid-cols-2\">\n <label className=\"flex flex-1 items-center gap-2 text-sm md:flex-col md:items-start md:whitespace-nowrap\">\n {t.speed}\n <select\n aria-label={t.speed}\n value={speed}\n onChange={(event) => changeSpeed(Number(event.target.value))}\n >\n {SPEEDS.map((rate) => (\n <option key={rate} value={rate}>\n {rate}×\n </option>\n ))}\n </select>\n </label>\n <label className=\"flex flex-1 items-center gap-2 text-sm md:flex-col md:items-start md:whitespace-nowrap\">\n {t.sleep}\n <select\n aria-label={t.sleep}\n value={sleepMode}\n onChange={(event) => changeSleep(event.target.value)}\n >\n <option value=\"off\">{t.off}</option>\n {[15, 30, 45, 60].map((minutes) => (\n <option key={minutes} value={minutes}>\n {minutes} min\n </option>\n ))}\n <option value=\"chapter\">{t.end}</option>\n </select>\n </label>\n </div>\n {sleepMode !== \"off\" && (\n <div className=\"flex items-center justify-between gap-2 text-sm\">\n <span role=\"timer\">\n {sleepMode === \"chapter\" ? t.end : formatTime(sleepRemaining)}\n </span>\n <Button variant=\"outline\" onClick={cancelSleep}>\n {t.cancel}\n </Button>\n </div>\n )}\n {isLoading && (\n <div role=\"status\" className=\"flex justify-center\">\n <LoadingIndicator />\n </div>\n )}\n </div>\n );\n },\n);\n\nexport default AudioPlayer;\n"]}
@@ -0,0 +1,2 @@
1
+ import{c as A,h as t}from"./chunk-STDV54FL.mjs";import{a as d}from"./chunk-5R6AGO3Z.mjs";import{b as G,e as V}from"./chunk-4AU5SEHU.mjs";import{b as l}from"./chunk-U6FLIRIV.mjs";import{enumDesc as wt,fileDesc as F}from"@bufbuild/protobuf/codegenv2";var Z=F("Chtjb21tb24vdjEvZW52aXJvbm1lbnQucHJvdG8SCWNvbW1vbi52MSonCgtFbnZpcm9ubWVudBIOCgpQUk9EVUNUSU9OEAASCAoEVEVTVBABQk5aTGdpdGh1Yi5jb20vZW1tZW1zL3N1cGVyLWNhcnQvYXBwcy9zcnYtd29ya2VyL3V0aWxzL21vZGVscy9jb21tb24vdjE7Y29tbW9udjFiBnByb3RvMw"),U=(n=>(n[n.PRODUCTION=0]="PRODUCTION",n[n.TEST=1]="TEST",n))(U||{});import{fileDesc as y,messageDesc as _t,serviceDesc as B}from"@bufbuild/protobuf/codegenv2";import{file_google_protobuf_timestamp as J}from"@bufbuild/protobuf/wkt";var I=y("ChdwdWJsaWMvdjEvcmV0dXJucy5wcm90bxIJcHVibGljLnYxIosBChlTdGFydFJldHVyblNlc3Npb25SZXF1ZXN0EhIKCnByb2plY3RfaWQYASABKAkSDQoFZW1haWwYAiABKAkSKwoLZW52aXJvbm1lbnQYAyABKA4yFi5jb21tb24udjEuRW52aXJvbm1lbnQSEwoGbG9jYWxlGAQgASgJSACIAQFCCQoHX2xvY2FsZSJhChpTdGFydFJldHVyblNlc3Npb25SZXNwb25zZRIUCgxjaGFsbGVuZ2VfaWQYASABKAkSHAoUcmVzZW5kX2FmdGVyX3NlY29uZHMYAiABKAUSDwoHbWVzc2FnZRgDIAEoCSKBAQoaVmVyaWZ5UmV0dXJuU2Vzc2lvblJlcXVlc3QSEgoKcHJvamVjdF9pZBgBIAEoCRIUCgxjaGFsbGVuZ2VfaWQYAiABKAkSDAoEY29kZRgDIAEoCRIrCgtlbnZpcm9ubWVudBgEIAEoDjIWLmNvbW1vbi52MS5FbnZpcm9ubWVudCJkChtWZXJpZnlSZXR1cm5TZXNzaW9uUmVzcG9uc2USFQoNc2Vzc2lvbl90b2tlbhgBIAEoCRIuCgpleHBpcmVzX2F0GAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCJ0ChtFeGNoYW5nZVBhbmVsU2Vzc2lvblJlcXVlc3QSEgoKcHJvamVjdF9pZBgBIAEoCRIUCgxhY2Nlc3NfdG9rZW4YAiABKAkSKwoLZW52aXJvbm1lbnQYAyABKA4yFi5jb21tb24udjEuRW52aXJvbm1lbnQiZQocRXhjaGFuZ2VQYW5lbFNlc3Npb25SZXNwb25zZRIVCg1zZXNzaW9uX3Rva2VuGAEgASgJEi4KCmV4cGlyZXNfYXQYAiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIjMKClJldHVyblBhZ2USEQoJcGFnZV9zaXplGAEgASgFEhIKCnBhZ2VfdG9rZW4YAiABKAki1AEKElJldHVybk9yZGVyU3VtbWFyeRIaChJjYW5vbmljYWxfb3JkZXJfaWQYASABKAkSGQoRZGlzcGxheV9yZWZlcmVuY2UYAiABKAkSDwoHZ2F0ZXdheRgDIAEoCRIwCgxwdXJjaGFzZWRfYXQYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhMKC3RvdGFsX21pbm9yGAUgASgDEhAKCGN1cnJlbmN5GAYgASgJEh0KFXJldHVybmFibGVfbGluZV9jb3VudBgHIAEoBSJrChdMaXN0UmV0dXJuT3JkZXJzUmVxdWVzdBISCgpwcm9qZWN0X2lkGAEgASgJEhUKDXNlc3Npb25fdG9rZW4YAiABKAkSEQoJcGFnZV9zaXplGAMgASgFEhIKCnBhZ2VfdG9rZW4YBCABKAkicQoYTGlzdFJldHVybk9yZGVyc1Jlc3BvbnNlEi0KBm9yZGVycxgBIAMoCzIdLnB1YmxpYy52MS5SZXR1cm5PcmRlclN1bW1hcnkSFwoPbmV4dF9wYWdlX3Rva2VuGAIgASgJEg0KBXRvdGFsGAMgASgFIsQDCg9SZXR1cm5PcmRlckxpbmUSDwoHbGluZV9pZBgBIAEoCRISCgpwcm9kdWN0X2lkGAIgASgJEhIKCnZhcmlhbnRfaWQYAyABKAkSDAoEbmFtZRgEIAEoCRIYChBmdWxmaWxsbWVudF90eXBlGAUgASgJEhoKEnB1cmNoYXNlZF9xdWFudGl0eRgGIAEoBRIZChFyZXNlcnZlZF9xdWFudGl0eRgHIAEoBRIZChFyZXR1cm5lZF9xdWFudGl0eRgIIAEoBRIaChJhdmFpbGFibGVfcXVhbnRpdHkYCSABKAUSGgoScmVndWxhcl91bml0X21pbm9yGAogASgDEhcKD3BhaWRfdW5pdF9taW5vchgLIAEoAxIQCghjdXJyZW5jeRgMIAEoCRIQCghlbGlnaWJsZRgNIAEoCBIYChBleGNsdXNpb25fcmVhc29uGA4gASgJEh0KFXBhaWRfbGluZV90b3RhbF9taW5vchgPIAEoAxIfChdjb3Vwb25fYWxsb2NhdGlvbl9taW5vchgQIAEoAxIVCg1hY2Nlc3Nfc291cmNlGBEgASgJEhgKEGFjY2Vzc19yZWZlcmVuY2UYEiABKAki3wEKEVJldHVybk9yZGVyRGV0YWlsEhoKEmNhbm9uaWNhbF9vcmRlcl9pZBgBIAEoCRIZChFkaXNwbGF5X3JlZmVyZW5jZRgCIAEoCRIPCgdnYXRld2F5GAMgASgJEjAKDHB1cmNoYXNlZF9hdBgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASEwoLdG90YWxfbWlub3IYBSABKAMSEAoIY3VycmVuY3kYBiABKAkSKQoFbGluZXMYByADKAsyGi5wdWJsaWMudjEuUmV0dXJuT3JkZXJMaW5lIjsKFlJldHVyblJlcXVlc3RMaW5lSW5wdXQSDwoHbGluZV9pZBgBIAEoCRIQCghxdWFudGl0eRgCIAEoBSJzChJSZXR1cm5IaXN0b3J5RW50cnkSCgoCaWQYASABKAkSEQoJcmVmZXJlbmNlGAIgASgJEg4KBnN0YXR1cxgDIAEoCRIuCgpjcmVhdGVkX2F0GAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCK5AQoVUmV0dXJuUmVxdWVzdExpbmVWaWV3Eg8KB2xpbmVfaWQYASABKAkSDAoEbmFtZRgCIAEoCRIYChBmdWxmaWxsbWVudF90eXBlGAMgASgJEhoKEnJlcXVlc3RlZF9xdWFudGl0eRgEIAEoBRIZChFhcHByb3ZlZF9xdWFudGl0eRgFIAEoBRIZChFyZWNlaXZlZF9xdWFudGl0eRgGIAEoBRIVCg1hY2Nlc3Nfc3RhdHVzGAcgASgJIvoCChFSZXR1cm5SZXF1ZXN0VmlldxIKCgJpZBgBIAEoCRIRCglyZWZlcmVuY2UYAiABKAkSGgoSY2Fub25pY2FsX29yZGVyX2lkGAMgASgJEg4KBnN0YXR1cxgEIAEoCRIVCg1yZWZ1bmRfc3RhdHVzGAUgASgJEhsKE3JlZnVuZF9hbW91bnRfbWlub3IYBiABKAMSEAoIY3VycmVuY3kYByABKAkSFQoNY3VzdG9tZXJfbm90ZRgIIAEoCRIPCgd2ZXJzaW9uGAkgASgDEi4KCmNyZWF0ZWRfYXQYCiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEi8KBWxpbmVzGAsgAygLMiAucHVibGljLnYxLlJldHVyblJlcXVlc3RMaW5lVmlldxIuCgdoaXN0b3J5GAwgAygLMh0ucHVibGljLnYxLlJldHVybkhpc3RvcnlFbnRyeRIbChNyZXR1cm5faW5zdHJ1Y3Rpb25zGA0gASgJImIKGUdldFJldHVybmFibGVPcmRlclJlcXVlc3QSEgoKcHJvamVjdF9pZBgBIAEoCRIVCg1zZXNzaW9uX3Rva2VuGAIgASgJEhoKEmNhbm9uaWNhbF9vcmRlcl9pZBgDIAEoCSKAAQoaR2V0UmV0dXJuYWJsZU9yZGVyUmVzcG9uc2USKwoFb3JkZXIYASABKAsyHC5wdWJsaWMudjEuUmV0dXJuT3JkZXJEZXRhaWwSNQoOcmV0dXJuX2hpc3RvcnkYAiADKAsyHS5wdWJsaWMudjEuUmV0dXJuSGlzdG9yeUVudHJ5IrwBChpDcmVhdGVSZXR1cm5SZXF1ZXN0UmVxdWVzdBISCgpwcm9qZWN0X2lkGAEgASgJEhUKDXNlc3Npb25fdG9rZW4YAiABKAkSGgoSY2Fub25pY2FsX29yZGVyX2lkGAMgASgJEjAKBWl0ZW1zGAQgAygLMiEucHVibGljLnYxLlJldHVyblJlcXVlc3RMaW5lSW5wdXQSDAoEbm90ZRgFIAEoCRIXCg9pZGVtcG90ZW5jeV9rZXkYBiABKAkiTAobQ3JlYXRlUmV0dXJuUmVxdWVzdFJlc3BvbnNlEi0KB3JlcXVlc3QYASABKAsyHC5wdWJsaWMudjEuUmV0dXJuUmVxdWVzdFZpZXciaAoUTGlzdE15UmV0dXJuc1JlcXVlc3QSEgoKcHJvamVjdF9pZBgBIAEoCRIVCg1zZXNzaW9uX3Rva2VuGAIgASgJEhEKCXBhZ2Vfc2l6ZRgDIAEoBRISCgpwYWdlX3Rva2VuGAQgASgJIm4KFUxpc3RNeVJldHVybnNSZXNwb25zZRItCgdyZXR1cm5zGAEgAygLMhwucHVibGljLnYxLlJldHVyblJlcXVlc3RWaWV3EhcKD25leHRfcGFnZV90b2tlbhgCIAEoCRINCgV0b3RhbBgDIAEoBSJSChJHZXRNeVJldHVyblJlcXVlc3QSEgoKcHJvamVjdF9pZBgBIAEoCRIVCg1zZXNzaW9uX3Rva2VuGAIgASgJEhEKCXJldHVybl9pZBgDIAEoCSJEChNHZXRNeVJldHVyblJlc3BvbnNlEi0KB3JlcXVlc3QYASABKAsyHC5wdWJsaWMudjEuUmV0dXJuUmVxdWVzdFZpZXcyigYKDlJldHVybnNTZXJ2aWNlEmEKElN0YXJ0UmV0dXJuU2Vzc2lvbhIkLnB1YmxpYy52MS5TdGFydFJldHVyblNlc3Npb25SZXF1ZXN0GiUucHVibGljLnYxLlN0YXJ0UmV0dXJuU2Vzc2lvblJlc3BvbnNlEmQKE1ZlcmlmeVJldHVyblNlc3Npb24SJS5wdWJsaWMudjEuVmVyaWZ5UmV0dXJuU2Vzc2lvblJlcXVlc3QaJi5wdWJsaWMudjEuVmVyaWZ5UmV0dXJuU2Vzc2lvblJlc3BvbnNlEmcKFEV4Y2hhbmdlUGFuZWxTZXNzaW9uEiYucHVibGljLnYxLkV4Y2hhbmdlUGFuZWxTZXNzaW9uUmVxdWVzdBonLnB1YmxpYy52MS5FeGNoYW5nZVBhbmVsU2Vzc2lvblJlc3BvbnNlElsKEExpc3RSZXR1cm5PcmRlcnMSIi5wdWJsaWMudjEuTGlzdFJldHVybk9yZGVyc1JlcXVlc3QaIy5wdWJsaWMudjEuTGlzdFJldHVybk9yZGVyc1Jlc3BvbnNlEmEKEkdldFJldHVybmFibGVPcmRlchIkLnB1YmxpYy52MS5HZXRSZXR1cm5hYmxlT3JkZXJSZXF1ZXN0GiUucHVibGljLnYxLkdldFJldHVybmFibGVPcmRlclJlc3BvbnNlEmQKE0NyZWF0ZVJldHVyblJlcXVlc3QSJS5wdWJsaWMudjEuQ3JlYXRlUmV0dXJuUmVxdWVzdFJlcXVlc3QaJi5wdWJsaWMudjEuQ3JlYXRlUmV0dXJuUmVxdWVzdFJlc3BvbnNlElIKDUxpc3RNeVJldHVybnMSHy5wdWJsaWMudjEuTGlzdE15UmV0dXJuc1JlcXVlc3QaIC5wdWJsaWMudjEuTGlzdE15UmV0dXJuc1Jlc3BvbnNlEkwKC0dldE15UmV0dXJuEh0ucHVibGljLnYxLkdldE15UmV0dXJuUmVxdWVzdBoeLnB1YmxpYy52MS5HZXRNeVJldHVyblJlc3BvbnNlYgZwcm90bzM",[Z,J]);var i=B(I,0);import{TransportProvider as Yt,useInfiniteQuery as Xt,useMutation as Et,useQuery as Ft}from"@connectrpc/connect-query";import{createConnectTransport as Ut}from"@connectrpc/connect-web";import{QueryClient as yt,QueryClientProvider as Bt}from"@tanstack/react-query";import{useState as Jt}from"react";var R={};l(R,{cancelNotificationMessage:()=>le,createNotificationGroup:()=>q,createNotificationGroupUser:()=>se,createNotificationMessage:()=>ie,createNotificationMessageJob:()=>me,createNotificationSetting:()=>P,createNotificationUser:()=>_,deleteNotificationGroup:()=>D,deleteNotificationGroupUser:()=>ae,deleteNotificationMessage:()=>re,deleteNotificationMessageJob:()=>Ae,deleteNotificationSetting:()=>L,deleteNotificationUser:()=>te,duplicateNotificationMessage:()=>pe,getNotificationMessageReport:()=>ge,getNotificationStats:()=>fe,getNotificationUserSettings:()=>Ze,getProjectedRecipientCount:()=>We,getSentNotificationMessages:()=>de,getUserGroups:()=>Ne,previewNotificationMessageEmail:()=>Ye,readNotificationGroupUsers:()=>oe,readNotificationGroups:()=>w,readNotificationMessageJobs:()=>be,readNotificationMessages:()=>ce,readNotificationProducts:()=>Ve,readNotificationSetting:()=>H,readNotificationUsers:()=>$,retryFailedNotificationMessageJobs:()=>Re,updateNotificationGroup:()=>O,updateNotificationGroupUser:()=>ne,updateNotificationMessage:()=>ue,updateNotificationMessageJob:()=>Ge,updateNotificationSetting:()=>j,updateNotificationUser:()=>ee,updateUserGroups:()=>Se,verifyUserEmail:()=>he});import{enumDesc as us,fileDesc as x,messageDesc as rs,serviceDesc as k}from"@bufbuild/protobuf/codegenv2";import{file_google_protobuf_empty as Q,file_google_protobuf_timestamp as K}from"@bufbuild/protobuf/wkt";import{enumDesc as os,fileDesc as v,messageDesc as ns,serviceDesc as as}from"@bufbuild/protobuf/codegenv2";import{file_google_protobuf_empty as C,file_google_protobuf_timestamp as M}from"@bufbuild/protobuf/wkt";var h=v("ChpkYXNoYm9hcmQvdjEvcHJvZHVjdC5wcm90bxIUZGFzaGJvYXJkLnByb2R1Y3QudjEiNAoeR2V0R3Vlc3RDYXRhbG9nU2V0dGluZ3NSZXF1ZXN0EhIKCnByb2R1Y3RfaWQYASABKAkibAobU2V0R3Vlc3RDYXRhbG9nRW50cnlSZXF1ZXN0EhIKCnByb2R1Y3RfaWQYASABKAkSFAoMcHJvZHVjdF90eXBlGAIgASgJEg8KB2VuYWJsZWQYAyABKAgSEgoKc29ydF9vcmRlchgEIAEoBSL3AQofR2V0R3Vlc3RDYXRhbG9nU2V0dGluZ3NSZXNwb25zZRISCgpjYW5fbWFuYWdlGAEgASgIEh0KFWd1ZXN0X2NhdGFsb2dfZW5hYmxlZBgCIAEoCBI4CgdlbnRyaWVzGAMgAygLMicuZGFzaGJvYXJkLnByb2R1Y3QudjEuR3Vlc3RDYXRhbG9nRW50cnkSHQoVYXZhaWxhYmxlX3Byb2R1Y3RfaWRzGAQgAygJEkgKD3Byb2R1Y3Rfb3B0aW9ucxgFIAMoCzIvLmRhc2hib2FyZC5wcm9kdWN0LnYxLkd1ZXN0Q2F0YWxvZ1Byb2R1Y3RPcHRpb24iRQoZR3Vlc3RDYXRhbG9nUHJvZHVjdE9wdGlvbhISCgpwcm9kdWN0X2lkGAEgASgJEhQKDGRpc3BsYXlfbmFtZRgCIAEoCSJ+ChFHdWVzdENhdGFsb2dFbnRyeRISCgpwcm9kdWN0X2lkGAEgASgJEhQKDHByb2R1Y3RfdHlwZRgCIAEoCRIPCgdlbmFibGVkGAMgASgIEhIKCnNvcnRfb3JkZXIYBCABKAUSGgoSZWxpZ2liaWxpdHlfcmVhc29uGAUgASgJIisKFUFyY2hpdmVQcm9kdWN0UmVxdWVzdBISCgpwcm9kdWN0X2lkGAEgASgJIi0KF0R1cGxpY2F0ZVByb2R1Y3RSZXF1ZXN0EhIKCnByb2R1Y3RfaWQYASABKAkiOQoYRHVwbGljYXRlUHJvZHVjdFJlc3BvbnNlEh0KFWR1cGxpY2F0ZWRfcHJvZHVjdF9pZBgBIAEoCSI3CiBFeGNoYW5nZVByb2R1Y3RJRHNUb05hbWVzUmVxdWVzdBITCgtwcm9kdWN0X2lkcxgBIAMoCSK6AQohRXhjaGFuZ2VQcm9kdWN0SURzVG9OYW1lc1Jlc3BvbnNlEmAKDXByb2R1Y3RfbmFtZXMYASADKAsySS5kYXNoYm9hcmQucHJvZHVjdC52MS5FeGNoYW5nZVByb2R1Y3RJRHNUb05hbWVzUmVzcG9uc2UuUHJvZHVjdE5hbWVzRW50cnkaMwoRUHJvZHVjdE5hbWVzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASJ5ChtHZXRGaWxlQWNjZXNzTWVtYmVyc1JlcXVlc3QSEgoKcHJvZHVjdF9pZBgBIAEoCRITCgZzZWFyY2gYAiABKAlIAIgBARIXCgp2YXJpYW50X2lkGAMgASgJSAGIAQFCCQoHX3NlYXJjaEINCgtfdmFyaWFudF9pZCLRAQocR2V0RmlsZUFjY2Vzc01lbWJlcnNSZXNwb25zZRJJCgdtZW1iZXJzGAEgAygLMjguZGFzaGJvYXJkLnByb2R1Y3QudjEuR2V0RmlsZUFjY2Vzc01lbWJlcnNSZXNwb25zZS5WYWx1ZRpmCgVWYWx1ZRIKCgJpZBgBIAEoCRINCgVlbWFpbBgCIAEoCRIzCgpjcmVhdGVkX2F0GAMgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEgAiAEBQg0KC19jcmVhdGVkX2F0ImQKF0dpdmVBY2Nlc3NUb0ZpbGVSZXF1ZXN0EhIKCnByb2R1Y3RfaWQYASABKAkSFwoKdmFyaWFudF9pZBgCIAEoCUgAiAEBEg0KBWVtYWlsGAMgASgJQg0KC192YXJpYW50X2lkIisKGEdpdmVBY2Nlc3NUb0ZpbGVSZXNwb25zZRIPCgdzdWNjZXNzGAEgASgIIicKGVJlbW92ZUFjY2Vzc1RvRmlsZVJlcXVlc3QSCgoCaWQYASABKAkiLQoaUmVtb3ZlQWNjZXNzVG9GaWxlUmVzcG9uc2USDwoHc3VjY2VzcxgBIAEoCCJkCh9TZW5kVGVzdEVtYWlsV2l0aE1lc3NhZ2VSZXF1ZXN0Eg0KBWVtYWlsGAEgASgJEhQKDGh0bWxfbWVzc2FnZRgCIAEoCRISCgV0aXRsZRgDIAEoCUgAiAEBQggKBl90aXRsZSIvChlHZXRQcm9kdWN0VmFyaWFudHNSZXF1ZXN0EhIKCnByb2R1Y3RfaWQYASABKAkimQEKGkdldFByb2R1Y3RWYXJpYW50c1Jlc3BvbnNlElAKCHZhcmlhbnRzGAEgAygLMj4uZGFzaGJvYXJkLnByb2R1Y3QudjEuR2V0UHJvZHVjdFZhcmlhbnRzUmVzcG9uc2UuU2luZ2xlVmFyaWFudBopCg1TaW5nbGVWYXJpYW50EgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkigwEKKFVwZGF0ZVByb2R1Y3RBZnRlclB1cmNoYXNlTWVzc2FnZVJlcXVlc3QSEgoKcHJvZHVjdF9pZBgBIAEoCRIPCgdtZXNzYWdlGAIgASgJEhQKDGh0bWxfbWVzc2FnZRgDIAEoCRISCgV0aXRsZRgEIAEoCUgAiAEBQggKBl90aXRsZSI7CiVHZXRQcm9kdWN0QWZ0ZXJQdXJjaGFzZU1lc3NhZ2VSZXF1ZXN0EhIKCnByb2R1Y3RfaWQYASABKAkiuwIKJkdldFByb2R1Y3RBZnRlclB1cmNoYXNlTWVzc2FnZVJlc3BvbnNlElcKB3N1Y2Nlc3MYASABKAsyRC5kYXNoYm9hcmQucHJvZHVjdC52MS5HZXRQcm9kdWN0QWZ0ZXJQdXJjaGFzZU1lc3NhZ2VSZXNwb25zZS5TdWNjZXNzSAASNwoHZmFpbHVyZRgCIAEoDjIkLmRhc2hib2FyZC5wcm9kdWN0LnYxLkZhaWx1cmVNZXNzYWdlSAAadQoHU3VjY2VzcxIUCgdtZXNzYWdlGAEgASgJSACIAQESGQoMaHRtbF9tZXNzYWdlGAIgASgJSAGIAQESEgoFdGl0bGUYAyABKAlIAogBAUIKCghfbWVzc2FnZUIPCg1faHRtbF9tZXNzYWdlQggKBl90aXRsZUIICgZyZXN1bHQiMwodUHVibGlzaFByb2R1Y3RJZk5lZWRlZFJlcXVlc3QSEgoKcHJvZHVjdF9pZBgBIAEoCSJlCitVcGRhdGVQcm9kdWN0U2VuZFRpY2tldEFmdGVyUHVyY2hhc2VSZXF1ZXN0EhIKCnByb2R1Y3RfaWQYASABKAkSIgoac2VuZF90aWNrZXRfYWZ0ZXJfcHVyY2hhc2UYAiABKAgiVgoqVXBkYXRlUHJvZHVjdEF1ZGlvYm9va0FmdGVyUHVyY2hhc2VSZXF1ZXN0EhIKCnByb2R1Y3RfaWQYASABKAkSFAoMYXVkaW9ib29rX2lkGAIgASgJIj4KKEdldFByb2R1Y3RTZW5kVGlja2V0QWZ0ZXJQdXJjaGFzZVJlcXVlc3QSEgoKcHJvZHVjdF9pZBgBIAEoCSL5AQopR2V0UHJvZHVjdFNlbmRUaWNrZXRBZnRlclB1cmNoYXNlUmVzcG9uc2USWgoHc3VjY2VzcxgBIAEoCzJHLmRhc2hib2FyZC5wcm9kdWN0LnYxLkdldFByb2R1Y3RTZW5kVGlja2V0QWZ0ZXJQdXJjaGFzZVJlc3BvbnNlLlN1Y2Nlc3NIABI3CgdmYWlsdXJlGAIgASgOMiQuZGFzaGJvYXJkLnByb2R1Y3QudjEuRmFpbHVyZU1lc3NhZ2VIABotCgdTdWNjZXNzEiIKGnNlbmRfdGlja2V0X2FmdGVyX3B1cmNoYXNlGAEgASgIQggKBnJlc3VsdCI9CidHZXRQcm9kdWN0QXVkaW9ib29rQWZ0ZXJQdXJjaGFzZVJlcXVlc3QSEgoKcHJvZHVjdF9pZBgBIAEoCSKfAgooR2V0UHJvZHVjdEF1ZGlvYm9va0FmdGVyUHVyY2hhc2VSZXNwb25zZRJZCgdzdWNjZXNzGAEgASgLMkYuZGFzaGJvYXJkLnByb2R1Y3QudjEuR2V0UHJvZHVjdEF1ZGlvYm9va0FmdGVyUHVyY2hhc2VSZXNwb25zZS5TdWNjZXNzSAASNwoHZmFpbHVyZRgCIAEoDjIkLmRhc2hib2FyZC5wcm9kdWN0LnYxLkZhaWx1cmVNZXNzYWdlSAAaVQoHU3VjY2VzcxIUCgxhdWRpb2Jvb2tfaWQYASABKAkSFwoPYXVkaW9ib29rX3RpdGxlGAIgASgJEhsKE2F1ZGlvYm9va19pbWFnZV91cmwYAyABKAlCCAoGcmVzdWx0IjcKFVNlYXJjaFByb2R1Y3RzUmVxdWVzdBITCgZzZWFyY2gYASABKAlIAIgBAUIJCgdfc2VhcmNoIswCChZTZWFyY2hQcm9kdWN0c1Jlc3BvbnNlEkYKB3N1Y2Nlc3MYASABKAsyMy5kYXNoYm9hcmQucHJvZHVjdC52MS5TZWFyY2hQcm9kdWN0c1Jlc3BvbnNlLlJlc3VsdEgAEjcKB2ZhaWx1cmUYAiABKA4yJC5kYXNoYm9hcmQucHJvZHVjdC52MS5GYWlsdXJlTWVzc2FnZUgAGk8KDVNpbmdsZVByb2R1Y3QSCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRIWCglpbWFnZV91cmwYAyABKAlIAIgBAUIMCgpfaW1hZ2VfdXJsGlYKBlJlc3VsdBJMCghwcm9kdWN0cxgBIAMoCzI6LmRhc2hib2FyZC5wcm9kdWN0LnYxLlNlYXJjaFByb2R1Y3RzUmVzcG9uc2UuU2luZ2xlUHJvZHVjdEIICgZyZXN1bHQiNQofR2V0UHJvZHVjdEJvdWdodEFydGljbGVzUmVxdWVzdBISCgpwcm9kdWN0X2lkGAEgASgJImAKIEdldFByb2R1Y3RCb3VnaHRBcnRpY2xlc1Jlc3BvbnNlEjwKCGFydGljbGVzGAEgAygLMiouZGFzaGJvYXJkLnByb2R1Y3QudjEuUHJvZHVjdEJvdWdodEFydGljbGUiiAEKFFByb2R1Y3RCb3VnaHRBcnRpY2xlEgoKAmlkGAEgASgJEhIKCnByb2R1Y3RfaWQYAiABKAkSFAoHY29udGVudBgDIAEoCUgAiAEBEi4KCmNyZWF0ZWRfYXQYCCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgoKCF9jb250ZW50ImAKIVVwZGF0ZVByb2R1Y3RCb3VnaHRBcnRpY2xlUmVxdWVzdBI7CgdhcnRpY2xlGAEgASgLMiouZGFzaGJvYXJkLnByb2R1Y3QudjEuUHJvZHVjdEJvdWdodEFydGljbGUiJwoRR2V0UHJvZHVjdFJlcXVlc3QSEgoKcHJvZHVjdF9pZBgBIAEoCSKBAgoSR2V0UHJvZHVjdFJlc3BvbnNlEjIKB3Byb2R1Y3QYASABKAsyHy5kYXNoYm9hcmQucHJvZHVjdC52MS5Qcm9kdWN0VjJIABI3CgdmYWlsdXJlGAIgASgOMiQuZGFzaGJvYXJkLnByb2R1Y3QudjEuRmFpbHVyZU1lc3NhZ2VIABJGCgpzZWxsX3N0YXRzGAMgAygLMjIuZGFzaGJvYXJkLnByb2R1Y3QudjEuR2V0UHJvZHVjdFJlc3BvbnNlLlNlbGxTdGF0cxosCglTZWxsU3RhdHMSEQoJcHJvZHVjdElEGAEgASgJEgwKBHNvbGQYAiABKAVCCAoGcmVzdWx0InIKHENyZWF0ZU9yVXBkYXRlUHJvZHVjdFJlcXVlc3QSMAoHcHJvZHVjdBgBIAEoCzIfLmRhc2hib2FyZC5wcm9kdWN0LnYxLlByb2R1Y3RWMhIgChhpc19kZXNjcmlwdGlvbl9kaWZmZXJlbnQYAiABKAgiTQoeVXBkYXRlUHJvZHVjdFVuaXF1ZVNsdWdSZXF1ZXN0EhIKCnByb2R1Y3RfaWQYASABKAkSFwoPbmV3X3VuaXF1ZV9zbHVnGAIgASgJIqULCglQcm9kdWN0VjISDwoCaWQYASABKAlIAIgBARITCgt1bmlxdWVfc2x1ZxgCIAEoCRISCgpwcm9qZWN0X2lkGAMgASgJEjYKBnN0YXR1cxgEIAEoDjImLmRhc2hib2FyZC5wcm9kdWN0LnYxLlByb2R1Y3RWMi5TdGF0dXMSGQoMaXNfcmVjdXJyaW5nGAUgASgISAGIAQESNwoJcmVjdXJyaW5nGAYgASgLMh8uZGFzaGJvYXJkLnByb2R1Y3QudjEuUmVjdXJyaW5nSAKIAQESDAoEbmFtZRgHIAEoCRIYCgtkZXNjcmlwdGlvbhgIIAEoCUgDiAEBEh0KEGh0bWxfZGVzY3JpcHRpb24YCSABKAlIBIgBARIeChFzaG9ydF9kZXNjcmlwdGlvbhgKIAEoCUgFiAEBEhkKDHByaWNlX2Ftb3VudBgLIAEoBUgGiAEBEhsKDnByaWNlX2N1cnJlbmN5GAwgASgJSAeIAQESEAoDdGF4GA0gASgCSAiIAQESHwoSYXZhaWxhYmxlX3F1YW50aXR5GA4gASgFSAmIAQESPwoIZmVhdHVyZXMYDyADKAsyLS5kYXNoYm9hcmQucHJvZHVjdC52MS5Qcm9kdWN0VjIuRmVhdHVyZXNFbnRyeRIOCgZpbWFnZXMYECADKAkSHAoPdGh1bWJuYWlsX2ltYWdlGBEgASgJSAqIAQESFwoKbWFpbl9pbWFnZRgSIAEoCUgLiAEBEi8KCHZhcmlhbnRzGBMgAygLMh0uZGFzaGJvYXJkLnByb2R1Y3QudjEuVmFyaWFudBInChpzZW5kX3RpY2tldF9hZnRlcl9wdXJjaGFzZRgUIAEoCEgMiAEBEicKGmlzX3Byb2R1Y3RfdmlzaWJsZV9vbl9saXN0GBUgASgISA2IAQESGwoOaXNfZGVsaXZlcmFibGUYGCABKAhIDogBARIhChRmb3JjZV9tYW51YWxfcGF5bWVudBgdIAEoCEgPiAEBEhkKDHdlaWdodF9ncmFtcxgeIAEoBUgQiAEBEh4KEXdpZHRoX21pbGxpbWV0ZXJzGB8gASgFSBGIAQESHwoSaGVpZ2h0X21pbGxpbWV0ZXJzGCAgASgFSBKIAQESEgoKY3JlYXRlZF9hdBgZIAEoAxISCgp1cGRhdGVkX2F0GBogASgDEhcKCmRlbGV0ZWRfYXQYGyABKANIE4gBARIVCghhcmNoaXZlZBgcIAEoCEgUiAEBEhAKCHJldmlzaW9uGCEgASgFGi8KDUZlYXR1cmVzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4ASIzCgZTdGF0dXMSCQoFRFJBRlQQABIPCgtVTlBVQkxJU0hFRBABEg0KCVBVQkxJU0hFRBACQgUKA19pZEIPCg1faXNfcmVjdXJyaW5nQgwKCl9yZWN1cnJpbmdCDgoMX2Rlc2NyaXB0aW9uQhMKEV9odG1sX2Rlc2NyaXB0aW9uQhQKEl9zaG9ydF9kZXNjcmlwdGlvbkIPCg1fcHJpY2VfYW1vdW50QhEKD19wcmljZV9jdXJyZW5jeUIGCgRfdGF4QhUKE19hdmFpbGFibGVfcXVhbnRpdHlCEgoQX3RodW1ibmFpbF9pbWFnZUINCgtfbWFpbl9pbWFnZUIdChtfc2VuZF90aWNrZXRfYWZ0ZXJfcHVyY2hhc2VCHQobX2lzX3Byb2R1Y3RfdmlzaWJsZV9vbl9saXN0QhEKD19pc19kZWxpdmVyYWJsZUIXChVfZm9yY2VfbWFudWFsX3BheW1lbnRCDwoNX3dlaWdodF9ncmFtc0IUChJfd2lkdGhfbWlsbGltZXRlcnNCFQoTX2hlaWdodF9taWxsaW1ldGVyc0INCgtfZGVsZXRlZF9hdEILCglfYXJjaGl2ZWQiuwMKCVJlY3VycmluZxI6Cg1iaWxsaW5nUGVyaW9kGAEgASgOMiMuZGFzaGJvYXJkLnByb2R1Y3QudjEuQmlsbGluZ1BlcmlvZBIXCgp0cmlhbF9kYXlzGAIgASgFSACIAQESHwoSbnVtYmVyX29mX3BheW1lbnRzGAMgASgFSAGIAQESMQokY2hhbmdlX2Ftb3VudF9mb3JfY3VycmVudFN1YnNjcmliZXJzGAQgASgISAKIAQESNAoncmVtb3ZlX2FjY2Vzc19mb3JfY2FuY2VsbGVkX3N1YnNjcmliZXJzGAUgASgISAOIAQESLgohc2hvdWxkX3NlbmRfdHJpYWxfcGVyaW9kX3JlbWluZGVyGAYgASgISASIAQFCDQoLX3RyaWFsX2RheXNCFQoTX251bWJlcl9vZl9wYXltZW50c0InCiVfY2hhbmdlX2Ftb3VudF9mb3JfY3VycmVudFN1YnNjcmliZXJzQioKKF9yZW1vdmVfYWNjZXNzX2Zvcl9jYW5jZWxsZWRfc3Vic2NyaWJlcnNCJAoiX3Nob3VsZF9zZW5kX3RyaWFsX3BlcmlvZF9yZW1pbmRlciKrAgoPVmFyaWFudERpc2NvdW50EjgKBHR5cGUYASABKA4yKi5kYXNoYm9hcmQucHJvZHVjdC52MS5WYXJpYW50RGlzY291bnQuVHlwZRIOCgZhbW91bnQYAiABKAUSMQoIZW5kX2RhdGUYAyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wSACIAQESDwoCaWQYBCABKAlIAYgBARIPCgdlbmFibGVkGAUgASgIEjMKCnN0YXJ0X2RhdGUYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wSAKIAQEiIQoEVHlwZRIJCgVGSVhFRBAAEg4KClBFUkNFTlRBR0UQAUILCglfZW5kX2RhdGVCBQoDX2lkQg0KC19zdGFydF9kYXRlIt0GCgdWYXJpYW50EgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkSGAoLZGVzY3JpcHRpb24YAyABKAlIAIgBARIWCglpbWFnZV91cmwYBCABKAlIAYgBARIUCgxwcmljZV9hbW91bnQYBSABKAUSFgoOcHJpY2VfY3VycmVuY3kYBiABKAkSEAoDdGF4GAcgASgFSAKIAQESHwoSYXZhaWxhYmxlX3F1YW50aXR5GAggASgFSAOIAQESNwoJcmVjdXJyaW5nGAkgASgLMh8uZGFzaGJvYXJkLnByb2R1Y3QudjEuUmVjdXJyaW5nSASIAQESGwoOaXNfZGVsaXZlcmFibGUYCiABKAhIBYgBARIhChRsb3dlc3RfcHJpY2VfMzBfZGF5cxgLIAEoBUgGiAEBEjwKCGRpc2NvdW50GAwgASgLMiUuZGFzaGJvYXJkLnByb2R1Y3QudjEuVmFyaWFudERpc2NvdW50SAeIAQESPgoVZXN0aW1hdGVkX2RlbGl2ZXJ5X2F0GA0gASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEgIiAEBEhwKFHJlZ3VsYXJfcHJpY2VfYW1vdW50GA4gASgFEh4KFmVmZmVjdGl2ZV9wcmljZV9hbW91bnQYDyABKAUSIwoWcmVmZXJlbmNlX3ByaWNlX2Ftb3VudBgQIAEoBUgJiAEBEiMKG3JlZmVyZW5jZV9oaXN0b3J5X2F2YWlsYWJsZRgRIAEoCBIVCg1wcmljZV92ZXJzaW9uGBIgASgDEj0KFG5leHRfcHJpY2VfY2hhbmdlX2F0GBMgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEgKiAEBQg4KDF9kZXNjcmlwdGlvbkIMCgpfaW1hZ2VfdXJsQgYKBF90YXhCFQoTX2F2YWlsYWJsZV9xdWFudGl0eUIMCgpfcmVjdXJyaW5nQhEKD19pc19kZWxpdmVyYWJsZUIXChVfbG93ZXN0X3ByaWNlXzMwX2RheXNCCwoJX2Rpc2NvdW50QhgKFl9lc3RpbWF0ZWRfZGVsaXZlcnlfYXRCGQoXX3JlZmVyZW5jZV9wcmljZV9hbW91bnRCFwoVX25leHRfcHJpY2VfY2hhbmdlX2F0IngKHUNyZWF0ZU9yVXBkYXRlUHJvZHVjdFJlc3BvbnNlEhQKCnByb2R1Y3RfaWQYASABKAlIABI3CgdmYWlsdXJlGAIgASgOMiQuZGFzaGJvYXJkLnByb2R1Y3QudjEuRmFpbHVyZU1lc3NhZ2VIAEIICgZyZXN1bHQifAoMQm9vbFJlc3BvbnNlEikKB3N1Y2Nlc3MYASABKAsyFi5nb29nbGUucHJvdG9idWYuRW1wdHlIABI3CgdmYWlsdXJlGAIgASgOMiQuZGFzaGJvYXJkLnByb2R1Y3QudjEuRmFpbHVyZU1lc3NhZ2VIAEIICgZyZXN1bHQiIgoPT3BlcmF0aW9uUmVzdWx0Eg8KB3N1Y2Nlc3MYASABKAgiUAoSR2V0UHJvZHVjdHNSZXF1ZXN0EhMKBnNlYXJjaBgBIAEoCUgAiAEBEhEKBHR5cGUYAiABKAlIAYgBAUIJCgdfc2VhcmNoQgcKBV90eXBlIrwBChNHZXRQcm9kdWN0c1Jlc3BvbnNlEkMKB3N1Y2Nlc3MYASABKAsyMC5kYXNoYm9hcmQucHJvZHVjdC52MS5HZXRQcm9kdWN0c1Jlc3BvbnNlLlJlc3VsdEgAEjcKB2ZhaWx1cmUYAiABKA4yJC5kYXNoYm9hcmQucHJvZHVjdC52MS5GYWlsdXJlTWVzc2FnZUgAGh0KBlJlc3VsdBITCgtwcm9kdWN0X2lkcxgBIAMoCUIICgZyZXN1bHQilgEKF0dldFByb2R1Y3RzQnlJZHNSZXF1ZXN0EgsKA2lkcxgBIAMoCRIVCghjdXJyZW5jeRgCIAEoCUgAiAEBEhEKBGxhbmcYAyABKAlIAYgBARIbCg5ncm91cF92YXJpYW50cxgEIAEoCEgCiAEBQgsKCV9jdXJyZW5jeUIHCgVfbGFuZ0IRCg9fZ3JvdXBfdmFyaWFudHMiwQIKGEdldFByb2R1Y3RzQnlJZHNSZXNwb25zZRJICgdzdWNjZXNzGAEgASgLMjUuZGFzaGJvYXJkLnByb2R1Y3QudjEuR2V0UHJvZHVjdHNCeUlkc1Jlc3BvbnNlLlJlc3VsdEgAEjcKB2ZhaWx1cmUYAiABKA4yJC5kYXNoYm9hcmQucHJvZHVjdC52MS5GYWlsdXJlTWVzc2FnZUgAGkQKB1Byb2R1Y3QSCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRINCgVwcmljZRgDIAEoBRIQCghjdXJyZW5jeRgEIAEoCRpSCgZSZXN1bHQSSAoIcHJvZHVjdHMYASADKAsyNi5kYXNoYm9hcmQucHJvZHVjdC52MS5HZXRQcm9kdWN0c0J5SWRzUmVzcG9uc2UuUHJvZHVjdEIICgZyZXN1bHQi3QEKFUdldFByb2R1Y3RHcmlkUmVxdWVzdBISCgpwcm9qZWN0X2lkGAEgASgJEhMKBnNlYXJjaBgCIAEoCUgAiAEBEhUKCGN1cnJlbmN5GAMgASgJSAGIAQESGwoOZ3JvdXBfdmFyaWFudHMYBCABKAhIAogBARITCgZvZmZzZXQYBSABKAVIA4gBARISCgVsaW1pdBgGIAEoBUgEiAEBQgkKB19zZWFyY2hCCwoJX2N1cnJlbmN5QhEKD19ncm91cF92YXJpYW50c0IJCgdfb2Zmc2V0QggKBl9saW1pdCLCAQoWR2V0UHJvZHVjdEdyaWRSZXNwb25zZRJGCgdzdWNjZXNzGAEgASgLMjMuZGFzaGJvYXJkLnByb2R1Y3QudjEuR2V0UHJvZHVjdEdyaWRSZXNwb25zZS5SZXN1bHRIABI3CgdmYWlsdXJlGAIgASgOMiQuZGFzaGJvYXJkLnByb2R1Y3QudjEuRmFpbHVyZU1lc3NhZ2VIABodCgZSZXN1bHQSEwoLcHJvZHVjdF9pZHMYASADKAlCCAoGcmVzdWx0ItYBChpHZXRNYWluUGFnZVByb2R1Y3RzUmVxdWVzdBIXCgpwcm9qZWN0X2lkGAEgASgJSACIAQESEwoGc2VhcmNoGAIgASgJSAGIAQESEgoFbGltaXQYAyABKAVIAogBARITCgZvZmZzZXQYBCABKAVIA4gBARIdChBpbmNsdWRlX2FyY2hpdmVkGAUgASgISASIAQFCDQoLX3Byb2plY3RfaWRCCQoHX3NlYXJjaEIICgZfbGltaXRCCQoHX29mZnNldEITChFfaW5jbHVkZV9hcmNoaXZlZCL2AQobR2V0TWFpblBhZ2VQcm9kdWN0c1Jlc3BvbnNlEksKB3N1Y2Nlc3MYASABKAsyOC5kYXNoYm9hcmQucHJvZHVjdC52MS5HZXRNYWluUGFnZVByb2R1Y3RzUmVzcG9uc2UuUmVzdWx0SAASNwoHZmFpbHVyZRgCIAEoDjIkLmRhc2hib2FyZC5wcm9kdWN0LnYxLkZhaWx1cmVNZXNzYWdlSAAaRwoGUmVzdWx0EhMKC3Byb2R1Y3RfaWRzGAEgAygJEhgKC3RvdGFsX2NvdW50GAIgASgFSACIAQFCDgoMX3RvdGFsX2NvdW50QggKBnJlc3VsdCI6CiNHZXRQdWJsaWNQcm9kdWN0QnlVbmlxdWVTbHVnUmVxdWVzdBITCgt1bmlxdWVfc2x1ZxgBIAEoCSKXBAokR2V0UHVibGljUHJvZHVjdEJ5VW5pcXVlU2x1Z1Jlc3BvbnNlElQKB3N1Y2Nlc3MYASABKAsyQS5kYXNoYm9hcmQucHJvZHVjdC52MS5HZXRQdWJsaWNQcm9kdWN0QnlVbmlxdWVTbHVnUmVzcG9uc2UuUmVzdWx0SAASNwoHZmFpbHVyZRgCIAEoDjIkLmRhc2hib2FyZC5wcm9kdWN0LnYxLkZhaWx1cmVNZXNzYWdlSAAa1QIKBlJlc3VsdBIPCgdzdWNjZXNzGAEgASgIEhQKB21lc3NhZ2UYAiABKAlIAIgBARISCgpwcm9qZWN0X2lkGAMgASgJEgoKAmlkGAQgASgJEgwKBG5hbWUYBSABKAkSHgoRc2hvcnRfZGVzY3JpcHRpb24YBiABKAlIAYgBARIZCgxwcmljZV9hbW91bnQYByABKAVIAogBARIbCg5wcmljZV9jdXJyZW5jeRgIIAEoCUgDiAEBEhcKCm1haW5faW1hZ2UYCSABKAlIBIgBARIcCg90aHVtYm5haWxfaW1hZ2UYCiABKAlIBYgBAUIKCghfbWVzc2FnZUIUChJfc2hvcnRfZGVzY3JpcHRpb25CDwoNX3ByaWNlX2Ftb3VudEIRCg9fcHJpY2VfY3VycmVuY3lCDQoLX21haW5faW1hZ2VCEgoQX3RodW1ibmFpbF9pbWFnZUIICgZyZXN1bHQiYQoaR2V0UHVibGljQWdyZWVtZW50c1JlcXVlc3QSEgoKcHJvamVjdF9pZBgBIAEoCRITCgtwcm9kdWN0X2lkcxgCIAMoCRIaChJjb250YWluc19yZWN1cnJpbmcYAyABKAgi5QIKG0dldFB1YmxpY0FncmVlbWVudHNSZXNwb25zZRJLCgdzdWNjZXNzGAEgASgLMjguZGFzaGJvYXJkLnByb2R1Y3QudjEuR2V0UHVibGljQWdyZWVtZW50c1Jlc3BvbnNlLlJlc3VsdEgAEjcKB2ZhaWx1cmUYAiABKA4yJC5kYXNoYm9hcmQucHJvZHVjdC52MS5GYWlsdXJlTWVzc2FnZUgAGisKCUFncmVlbWVudBIMCgRuYW1lGAEgASgJEhAKCHJlcXVpcmVkGAIgASgIGogBCgZSZXN1bHQSDwoHc3VjY2VzcxgBIAEoCBIUCgdtZXNzYWdlGAIgASgJSACIAQESSwoGcmVzdWx0GAMgAygLMjsuZGFzaGJvYXJkLnByb2R1Y3QudjEuR2V0UHVibGljQWdyZWVtZW50c1Jlc3BvbnNlLkFncmVlbWVudEIKCghfbWVzc2FnZUIICgZyZXN1bHQiPAomR2V0RVByb2R1Y3RzQWRkZWRGb3JUaGlzUHJvZHVjdFJlcXVlc3QSEgoKcHJvZHVjdF9pZBgBIAEoCSLlAQonR2V0RVByb2R1Y3RzQWRkZWRGb3JUaGlzUHJvZHVjdFJlc3BvbnNlElcKB3N1Y2Nlc3MYASABKAsyRC5kYXNoYm9hcmQucHJvZHVjdC52MS5HZXRFUHJvZHVjdHNBZGRlZEZvclRoaXNQcm9kdWN0UmVzcG9uc2UuUmVzdWx0SAASNwoHZmFpbHVyZRgCIAEoDjIkLmRhc2hib2FyZC5wcm9kdWN0LnYxLkZhaWx1cmVNZXNzYWdlSAAaHgoGUmVzdWx0EhQKDGVwcm9kdWN0X2lkcxgBIAMoCUIICgZyZXN1bHQiVQopVXBkYXRlRVByb2R1Y3RzQWRkZWRGb3JUaGlzUHJvZHVjdFJlcXVlc3QSEgoKcHJvZHVjdF9pZBgBIAEoCRIUCgxlcHJvZHVjdF9pZHMYAiADKAkiOgokR2V0TGlzdE9mQWRkaXRpb25hbEFncmVlbWVudHNSZXF1ZXN0EhIKCnByb2R1Y3RfaWQYASABKAkiUAoPQWdyZWVtZW50T3B0aW9uEgwKBG5hbWUYASABKAkSEwoLaXNfcmVxdWlyZWQYAiABKAgSEQoEbGluaxgDIAEoCUgAiAEBQgcKBV9saW5rIrUCCiVHZXRMaXN0T2ZBZGRpdGlvbmFsQWdyZWVtZW50c1Jlc3BvbnNlElUKB3N1Y2Nlc3MYASABKAsyQi5kYXNoYm9hcmQucHJvZHVjdC52MS5HZXRMaXN0T2ZBZGRpdGlvbmFsQWdyZWVtZW50c1Jlc3BvbnNlLlJlc3VsdEgAEjcKB2ZhaWx1cmUYAiABKA4yJC5kYXNoYm9hcmQucHJvZHVjdC52MS5GYWlsdXJlTWVzc2FnZUgAGnIKBlJlc3VsdBIPCgdzdWNjZXNzGAEgASgIEhQKB21lc3NhZ2UYAiABKAlIAIgBARI1CgZyZXN1bHQYAyADKAsyJS5kYXNoYm9hcmQucHJvZHVjdC52MS5BZ3JlZW1lbnRPcHRpb25CCgoIX21lc3NhZ2VCCAoGcmVzdWx0IngKJ1VwZGF0ZUxpc3RPZkFkZGl0aW9uYWxBZ3JlZW1lbnRzUmVxdWVzdBISCgpwcm9kdWN0X2lkGAEgASgJEjkKCmFncmVlbWVudHMYAiADKAsyJS5kYXNoYm9hcmQucHJvZHVjdC52MS5BZ3JlZW1lbnRPcHRpb24iJAoUQ3JlYXRlUHJvZHVjdFJlcXVlc3QSDAoEbmFtZRgBIAEoCSIqChREZWxldGVQcm9kdWN0UmVxdWVzdBISCgpwcm9kdWN0X2lkGAEgASgJIjcKFUdldFByb2R1Y3RCeUlkUmVxdWVzdBISCgpwcm9qZWN0X2lkGAEgASgJEgoKAmlkGAIgASgJKr0BCg1CaWxsaW5nUGVyaW9kEhgKFEJJTExJTkdfUEVSSU9EX0RBSUxZEAASGQoVQklMTElOR19QRVJJT0RfV0VFS0xZEAESGgoWQklMTElOR19QRVJJT0RfTU9OVEhMWRACEhwKGEJJTExJTkdfUEVSSU9EX1FVQVJURVJMWRADEiAKHEJJTExJTkdfUEVSSU9EX1NFTUlfQU5OVUFMTFkQBBIbChdCSUxMSU5HX1BFUklPRF9BTk5VQUxMWRAFKpUCCg5GYWlsdXJlTWVzc2FnZRIbChdGQUlMVVJFX01FU1NBR0VfVU5LTk9XThAAEiUKIUZBSUxVUkVfTUVTU0FHRV9QUk9KRUNUX05PVF9GT1VORBABEiUKIUZBSUxVUkVfTUVTU0FHRV9QUk9EVUNUX05PVF9GT1VORBACEiYKIkZBSUxVUkVfTUVTU0FHRV9JTlZBTElEX1BST0RVQ1RfSUQQAxImCiJGQUlMVVJFX01FU1NBR0VfU0xVR19BTFJFQURZX1RBS0VOEAQSKQolRkFJTFVSRV9NRVNTQUdFX0NBTk5PVF9DUkVBVEVfUFJPRFVDVBAFEh0KGUZBSUxVUkVfTUVTU0FHRV9OT19BQ0NFU1MQBjLXJQoNUHJvZHVjdFJvdXRlchKAAQoVQ3JlYXRlT3JVcGRhdGVQcm9kdWN0EjIuZGFzaGJvYXJkLnByb2R1Y3QudjEuQ3JlYXRlT3JVcGRhdGVQcm9kdWN0UmVxdWVzdBozLmRhc2hib2FyZC5wcm9kdWN0LnYxLkNyZWF0ZU9yVXBkYXRlUHJvZHVjdFJlc3BvbnNlEnEKEER1cGxpY2F0ZVByb2R1Y3QSLS5kYXNoYm9hcmQucHJvZHVjdC52MS5EdXBsaWNhdGVQcm9kdWN0UmVxdWVzdBouLmRhc2hib2FyZC5wcm9kdWN0LnYxLkR1cGxpY2F0ZVByb2R1Y3RSZXNwb25zZRJzChdVcGRhdGVQcm9kdWN0VW5pcXVlU2x1ZxI0LmRhc2hib2FyZC5wcm9kdWN0LnYxLlVwZGF0ZVByb2R1Y3RVbmlxdWVTbHVnUmVxdWVzdBoiLmRhc2hib2FyZC5wcm9kdWN0LnYxLkJvb2xSZXNwb25zZRJfCgpHZXRQcm9kdWN0EicuZGFzaGJvYXJkLnByb2R1Y3QudjEuR2V0UHJvZHVjdFJlcXVlc3QaKC5kYXNoYm9hcmQucHJvZHVjdC52MS5HZXRQcm9kdWN0UmVzcG9uc2USpAEKIUdldFByb2R1Y3RTZW5kVGlja2V0QWZ0ZXJQdXJjaGFzZRI+LmRhc2hib2FyZC5wcm9kdWN0LnYxLkdldFByb2R1Y3RTZW5kVGlja2V0QWZ0ZXJQdXJjaGFzZVJlcXVlc3QaPy5kYXNoYm9hcmQucHJvZHVjdC52MS5HZXRQcm9kdWN0U2VuZFRpY2tldEFmdGVyUHVyY2hhc2VSZXNwb25zZRKhAQogR2V0UHJvZHVjdEF1ZGlvYm9va0FmdGVyUHVyY2hhc2USPS5kYXNoYm9hcmQucHJvZHVjdC52MS5HZXRQcm9kdWN0QXVkaW9ib29rQWZ0ZXJQdXJjaGFzZVJlcXVlc3QaPi5kYXNoYm9hcmQucHJvZHVjdC52MS5HZXRQcm9kdWN0QXVkaW9ib29rQWZ0ZXJQdXJjaGFzZVJlc3BvbnNlEo0BCiRVcGRhdGVQcm9kdWN0U2VuZFRpY2tldEFmdGVyUHVyY2hhc2USQS5kYXNoYm9hcmQucHJvZHVjdC52MS5VcGRhdGVQcm9kdWN0U2VuZFRpY2tldEFmdGVyUHVyY2hhc2VSZXF1ZXN0GiIuZGFzaGJvYXJkLnByb2R1Y3QudjEuQm9vbFJlc3BvbnNlEosBCiNVcGRhdGVQcm9kdWN0QXVkaW9ib29rQWZ0ZXJQdXJjaGFzZRJALmRhc2hib2FyZC5wcm9kdWN0LnYxLlVwZGF0ZVByb2R1Y3RBdWRpb2Jvb2tBZnRlclB1cmNoYXNlUmVxdWVzdBoiLmRhc2hib2FyZC5wcm9kdWN0LnYxLkJvb2xSZXNwb25zZRJxChZQdWJsaXNoUHJvZHVjdElmTmVlZGVkEjMuZGFzaGJvYXJkLnByb2R1Y3QudjEuUHVibGlzaFByb2R1Y3RJZk5lZWRlZFJlcXVlc3QaIi5kYXNoYm9hcmQucHJvZHVjdC52MS5Cb29sUmVzcG9uc2USmwEKHkdldFByb2R1Y3RBZnRlclB1cmNoYXNlTWVzc2FnZRI7LmRhc2hib2FyZC5wcm9kdWN0LnYxLkdldFByb2R1Y3RBZnRlclB1cmNoYXNlTWVzc2FnZVJlcXVlc3QaPC5kYXNoYm9hcmQucHJvZHVjdC52MS5HZXRQcm9kdWN0QWZ0ZXJQdXJjaGFzZU1lc3NhZ2VSZXNwb25zZRKHAQohVXBkYXRlUHJvZHVjdEFmdGVyUHVyY2hhc2VNZXNzYWdlEj4uZGFzaGJvYXJkLnByb2R1Y3QudjEuVXBkYXRlUHJvZHVjdEFmdGVyUHVyY2hhc2VNZXNzYWdlUmVxdWVzdBoiLmRhc2hib2FyZC5wcm9kdWN0LnYxLkJvb2xSZXNwb25zZRJ3ChJHZXRQcm9kdWN0VmFyaWFudHMSLy5kYXNoYm9hcmQucHJvZHVjdC52MS5HZXRQcm9kdWN0VmFyaWFudHNSZXF1ZXN0GjAuZGFzaGJvYXJkLnByb2R1Y3QudjEuR2V0UHJvZHVjdFZhcmlhbnRzUmVzcG9uc2USdQoYU2VuZFRlc3RFbWFpbFdpdGhNZXNzYWdlEjUuZGFzaGJvYXJkLnByb2R1Y3QudjEuU2VuZFRlc3RFbWFpbFdpdGhNZXNzYWdlUmVxdWVzdBoiLmRhc2hib2FyZC5wcm9kdWN0LnYxLkJvb2xSZXNwb25zZRJrCg5TZWFyY2hQcm9kdWN0cxIrLmRhc2hib2FyZC5wcm9kdWN0LnYxLlNlYXJjaFByb2R1Y3RzUmVxdWVzdBosLmRhc2hib2FyZC5wcm9kdWN0LnYxLlNlYXJjaFByb2R1Y3RzUmVzcG9uc2USjAEKGUV4Y2hhbmdlUHJvZHVjdElEc1RvTmFtZXMSNi5kYXNoYm9hcmQucHJvZHVjdC52MS5FeGNoYW5nZVByb2R1Y3RJRHNUb05hbWVzUmVxdWVzdBo3LmRhc2hib2FyZC5wcm9kdWN0LnYxLkV4Y2hhbmdlUHJvZHVjdElEc1RvTmFtZXNSZXNwb25zZRKJAQoYR2V0UHJvZHVjdEJvdWdodEFydGljbGVzEjUuZGFzaGJvYXJkLnByb2R1Y3QudjEuR2V0UHJvZHVjdEJvdWdodEFydGljbGVzUmVxdWVzdBo2LmRhc2hib2FyZC5wcm9kdWN0LnYxLkdldFByb2R1Y3RCb3VnaHRBcnRpY2xlc1Jlc3BvbnNlEnkKGlVwZGF0ZVByb2R1Y3RCb3VnaHRBcnRpY2xlEjcuZGFzaGJvYXJkLnByb2R1Y3QudjEuVXBkYXRlUHJvZHVjdEJvdWdodEFydGljbGVSZXF1ZXN0GiIuZGFzaGJvYXJkLnByb2R1Y3QudjEuQm9vbFJlc3BvbnNlEmkKF0FkZFByb2R1Y3RCb3VnaHRBcnRpY2xlEiouZGFzaGJvYXJkLnByb2R1Y3QudjEuUHJvZHVjdEJvdWdodEFydGljbGUaIi5kYXNoYm9hcmQucHJvZHVjdC52MS5Cb29sUmVzcG9uc2USfQoUR2V0RmlsZUFjY2Vzc01lbWJlcnMSMS5kYXNoYm9hcmQucHJvZHVjdC52MS5HZXRGaWxlQWNjZXNzTWVtYmVyc1JlcXVlc3QaMi5kYXNoYm9hcmQucHJvZHVjdC52MS5HZXRGaWxlQWNjZXNzTWVtYmVyc1Jlc3BvbnNlEnEKEEdpdmVBY2Nlc3NUb0ZpbGUSLS5kYXNoYm9hcmQucHJvZHVjdC52MS5HaXZlQWNjZXNzVG9GaWxlUmVxdWVzdBouLmRhc2hib2FyZC5wcm9kdWN0LnYxLkdpdmVBY2Nlc3NUb0ZpbGVSZXNwb25zZRJ3ChJSZW1vdmVBY2Nlc3NUb0ZpbGUSLy5kYXNoYm9hcmQucHJvZHVjdC52MS5SZW1vdmVBY2Nlc3NUb0ZpbGVSZXF1ZXN0GjAuZGFzaGJvYXJkLnByb2R1Y3QudjEuUmVtb3ZlQWNjZXNzVG9GaWxlUmVzcG9uc2USYQoOQXJjaGl2ZVByb2R1Y3QSKy5kYXNoYm9hcmQucHJvZHVjdC52MS5BcmNoaXZlUHJvZHVjdFJlcXVlc3QaIi5kYXNoYm9hcmQucHJvZHVjdC52MS5Cb29sUmVzcG9uc2USYwoQVW5hcmNoaXZlUHJvZHVjdBIrLmRhc2hib2FyZC5wcm9kdWN0LnYxLkFyY2hpdmVQcm9kdWN0UmVxdWVzdBoiLmRhc2hib2FyZC5wcm9kdWN0LnYxLkJvb2xSZXNwb25zZRJiCgtHZXRQcm9kdWN0cxIoLmRhc2hib2FyZC5wcm9kdWN0LnYxLkdldFByb2R1Y3RzUmVxdWVzdBopLmRhc2hib2FyZC5wcm9kdWN0LnYxLkdldFByb2R1Y3RzUmVzcG9uc2UScQoQR2V0UHJvZHVjdHNCeUlkcxItLmRhc2hib2FyZC5wcm9kdWN0LnYxLkdldFByb2R1Y3RzQnlJZHNSZXF1ZXN0Gi4uZGFzaGJvYXJkLnByb2R1Y3QudjEuR2V0UHJvZHVjdHNCeUlkc1Jlc3BvbnNlEmsKDkdldFByb2R1Y3RHcmlkEisuZGFzaGJvYXJkLnByb2R1Y3QudjEuR2V0UHJvZHVjdEdyaWRSZXF1ZXN0GiwuZGFzaGJvYXJkLnByb2R1Y3QudjEuR2V0UHJvZHVjdEdyaWRSZXNwb25zZRJ6ChNHZXRNYWluUGFnZVByb2R1Y3RzEjAuZGFzaGJvYXJkLnByb2R1Y3QudjEuR2V0TWFpblBhZ2VQcm9kdWN0c1JlcXVlc3QaMS5kYXNoYm9hcmQucHJvZHVjdC52MS5HZXRNYWluUGFnZVByb2R1Y3RzUmVzcG9uc2USlQEKHEdldFB1YmxpY1Byb2R1Y3RCeVVuaXF1ZVNsdWcSOS5kYXNoYm9hcmQucHJvZHVjdC52MS5HZXRQdWJsaWNQcm9kdWN0QnlVbmlxdWVTbHVnUmVxdWVzdBo6LmRhc2hib2FyZC5wcm9kdWN0LnYxLkdldFB1YmxpY1Byb2R1Y3RCeVVuaXF1ZVNsdWdSZXNwb25zZRJ6ChNHZXRQdWJsaWNBZ3JlZW1lbnRzEjAuZGFzaGJvYXJkLnByb2R1Y3QudjEuR2V0UHVibGljQWdyZWVtZW50c1JlcXVlc3QaMS5kYXNoYm9hcmQucHJvZHVjdC52MS5HZXRQdWJsaWNBZ3JlZW1lbnRzUmVzcG9uc2USngEKH0dldEVQcm9kdWN0c0FkZGVkRm9yVGhpc1Byb2R1Y3QSPC5kYXNoYm9hcmQucHJvZHVjdC52MS5HZXRFUHJvZHVjdHNBZGRlZEZvclRoaXNQcm9kdWN0UmVxdWVzdBo9LmRhc2hib2FyZC5wcm9kdWN0LnYxLkdldEVQcm9kdWN0c0FkZGVkRm9yVGhpc1Byb2R1Y3RSZXNwb25zZRKMAQoiVXBkYXRlRVByb2R1Y3RzQWRkZWRGb3JUaGlzUHJvZHVjdBI/LmRhc2hib2FyZC5wcm9kdWN0LnYxLlVwZGF0ZUVQcm9kdWN0c0FkZGVkRm9yVGhpc1Byb2R1Y3RSZXF1ZXN0GiUuZGFzaGJvYXJkLnByb2R1Y3QudjEuT3BlcmF0aW9uUmVzdWx0EpgBCh1HZXRMaXN0T2ZBZGRpdGlvbmFsQWdyZWVtZW50cxI6LmRhc2hib2FyZC5wcm9kdWN0LnYxLkdldExpc3RPZkFkZGl0aW9uYWxBZ3JlZW1lbnRzUmVxdWVzdBo7LmRhc2hib2FyZC5wcm9kdWN0LnYxLkdldExpc3RPZkFkZGl0aW9uYWxBZ3JlZW1lbnRzUmVzcG9uc2USiAEKIFVwZGF0ZUxpc3RPZkFkZGl0aW9uYWxBZ3JlZW1lbnRzEj0uZGFzaGJvYXJkLnByb2R1Y3QudjEuVXBkYXRlTGlzdE9mQWRkaXRpb25hbEFncmVlbWVudHNSZXF1ZXN0GiUuZGFzaGJvYXJkLnByb2R1Y3QudjEuT3BlcmF0aW9uUmVzdWx0EmIKDUNyZWF0ZVByb2R1Y3QSKi5kYXNoYm9hcmQucHJvZHVjdC52MS5DcmVhdGVQcm9kdWN0UmVxdWVzdBolLmRhc2hib2FyZC5wcm9kdWN0LnYxLk9wZXJhdGlvblJlc3VsdBJiCg1EZWxldGVQcm9kdWN0EiouZGFzaGJvYXJkLnByb2R1Y3QudjEuRGVsZXRlUHJvZHVjdFJlcXVlc3QaJS5kYXNoYm9hcmQucHJvZHVjdC52MS5PcGVyYXRpb25SZXN1bHQSZwoOR2V0UHJvZHVjdEJ5SWQSKy5kYXNoYm9hcmQucHJvZHVjdC52MS5HZXRQcm9kdWN0QnlJZFJlcXVlc3QaKC5kYXNoYm9hcmQucHJvZHVjdC52MS5HZXRQcm9kdWN0UmVzcG9uc2UShgEKF0dldEd1ZXN0Q2F0YWxvZ1NldHRpbmdzEjQuZGFzaGJvYXJkLnByb2R1Y3QudjEuR2V0R3Vlc3RDYXRhbG9nU2V0dGluZ3NSZXF1ZXN0GjUuZGFzaGJvYXJkLnByb2R1Y3QudjEuR2V0R3Vlc3RDYXRhbG9nU2V0dGluZ3NSZXNwb25zZRKAAQoUU2V0R3Vlc3RDYXRhbG9nRW50cnkSMS5kYXNoYm9hcmQucHJvZHVjdC52MS5TZXRHdWVzdENhdGFsb2dFbnRyeVJlcXVlc3QaNS5kYXNoYm9hcmQucHJvZHVjdC52MS5HZXRHdWVzdENhdGFsb2dTZXR0aW5nc1Jlc3BvbnNlYgZwcm90bzM",[C,M]);var z=x("CiBkYXNoYm9hcmQvdjEvbm90aWZpY2F0aW9ucy5wcm90bxIaZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEiYAoWVmVyaWZ5VXNlckVtYWlsUmVxdWVzdBISCgVlbWFpbBgBIAEoCUgAiAEBEhEKBGNvZGUYAiABKAlIAYgBARIMCgRzbHVnGAMgASgJQggKBl9lbWFpbEIHCgVfY29kZSK/AQoXVmVyaWZ5VXNlckVtYWlsUmVzcG9uc2USDwoCb2sYASABKAhIAIgBARIZCgxhY2Nlc3NfdG9rZW4YAiABKAlIAYgBARIUCgd1c2VyX2lkGAMgASgJSAKIAQESFQoIcmV0cnlfaW4YBCABKAVIA4gBARIRCgRzZW50GAUgASgISASIAQFCBQoDX29rQg8KDV9hY2Nlc3NfdG9rZW5CCgoIX3VzZXJfaWRCCwoJX3JldHJ5X2luQgcKBV9zZW50IlAKFEdldFVzZXJHcm91cHNSZXF1ZXN0EgwKBHNsdWcYASABKAkSGQoMYWNjZXNzX3Rva2VuGAIgASgJSACIAQFCDwoNX2FjY2Vzc190b2tlbiKJAgoVR2V0VXNlckdyb3Vwc1Jlc3BvbnNlEkcKBmdyb3VwcxgBIAMoCzI3LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLkdldFVzZXJHcm91cHNSZXNwb25zZS5Hcm91cBqmAQoFR3JvdXASCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRIYCgtkZXNjcmlwdGlvbhgDIAEoCUgAiAEBEg0KBWlzX29uGAQgASgIEjwKCWhvd19vZnRlbhgFIAEoDjIkLmNvbW1vbi52MS5Ob3RpZmljYXRpb25Hcm91cEhvd09mdGVuSAGIAQFCDgoMX2Rlc2NyaXB0aW9uQgwKCl9ob3dfb2Z0ZW4idwoXVXBkYXRlVXNlckdyb3Vwc1JlcXVlc3QSDAoEc2x1ZxgBIAEoCRIPCgd1c2VyX2lkGAIgASgJEhEKCWdyb3VwX2lkcxgDIAMoCRIZCgxhY2Nlc3NfdG9rZW4YBCABKAlIAIgBAUIPCg1fYWNjZXNzX3Rva2VuIm8KIkdldE5vdGlmaWNhdGlvblVzZXJTZXR0aW5nc1JlcXVlc3QSDAoEc2x1ZxgBIAEoCRIPCgd1c2VyX2lkGAIgASgJEhkKDGFjY2Vzc190b2tlbhgDIAEoCUgAiAEBQg8KDV9hY2Nlc3NfdG9rZW4ijAQKI0dldE5vdGlmaWNhdGlvblVzZXJTZXR0aW5nc1Jlc3BvbnNlElkKB3N1Y2Nlc3MYASABKAsyRi5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5HZXROb3RpZmljYXRpb25Vc2VyU2V0dGluZ3NSZXNwb25zZS5SZXN1bHRIABI9CgdmYWlsdXJlGAIgASgOMiouZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuRmFpbHVyZU1lc3NhZ2VIABrAAgoGUmVzdWx0Eh8KF25vdGlmaWNhdGlvbl9zZXR0aW5nX2lkGAEgASgJEhkKEXN1YnNjcmlwdGlvbl9zbHVnGAIgASgJEiMKG21vYmlsZV9ub3RpZmljYXRpb25fZW5hYmxlZBgDIAEoCBIiChplbWFpbF9ub3RpZmljYXRpb25fZW5hYmxlZBgEIAEoCBIgChhzbXNfbm90aWZpY2F0aW9uX2VuYWJsZWQYBSABKAgSJAocZW1haWxfbm90aWZpY2F0aW9uX2F2YWlsYWJsZRgGIAEoCBIiChpzbXNfbm90aWZpY2F0aW9uX2F2YWlsYWJsZRgHIAEoCBIlCh1tb2JpbGVfbm90aWZpY2F0aW9uX2F2YWlsYWJsZRgIIAEoCBIeChZoYXNfdXNlcl9pbnN0YWxsZWRfYXBwGAkgASgIQggKBnJlc3VsdCIiCiBDcmVhdGVOb3RpZmljYXRpb25TZXR0aW5nUmVxdWVzdCIgCh5SZWFkTm90aWZpY2F0aW9uU2V0dGluZ1JlcXVlc3QigwIKIFVwZGF0ZU5vdGlmaWNhdGlvblNldHRpbmdSZXF1ZXN0Eh8KF25vdGlmaWNhdGlvbl9zZXR0aW5nX2lkGAEgASgJEhkKEXN1YnNjcmlwdGlvbl9zbHVnGAIgASgJEiMKG21vYmlsZV9ub3RpZmljYXRpb25fZW5hYmxlZBgDIAEoCBIiChplbWFpbF9ub3RpZmljYXRpb25fZW5hYmxlZBgEIAEoCBIgChhzbXNfbm90aWZpY2F0aW9uX2VuYWJsZWQYBSABKAgSIAoTZW1haWxfb3Blbl90cmFja2luZxgGIAEoCEgAiAEBQhYKFF9lbWFpbF9vcGVuX3RyYWNraW5nIkMKIERlbGV0ZU5vdGlmaWNhdGlvblNldHRpbmdSZXF1ZXN0Eh8KF25vdGlmaWNhdGlvbl9zZXR0aW5nX2lkGAEgASgJIpADCh9SZWFkTm90aWZpY2F0aW9uU2V0dGluZ1Jlc3BvbnNlElUKB3N1Y2Nlc3MYASABKAsyQi5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5SZWFkTm90aWZpY2F0aW9uU2V0dGluZ1Jlc3BvbnNlLlJlc3VsdEgAEj0KB2ZhaWx1cmUYAiABKA4yKi5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5GYWlsdXJlTWVzc2FnZUgAGswBCgZSZXN1bHQSHwoXbm90aWZpY2F0aW9uX3NldHRpbmdfaWQYASABKAkSGQoRc3Vic2NyaXB0aW9uX3NsdWcYAiABKAkSIwobbW9iaWxlX25vdGlmaWNhdGlvbl9lbmFibGVkGAMgASgIEiIKGmVtYWlsX25vdGlmaWNhdGlvbl9lbmFibGVkGAQgASgIEiAKGHNtc19ub3RpZmljYXRpb25fZW5hYmxlZBgFIAEoCBIbChNlbWFpbF9vcGVuX3RyYWNraW5nGAYgASgIQggKBnJlc3VsdCLkAQobTm90aWZpY2F0aW9uU2V0dGluZ1Jlc3BvbnNlElEKB3N1Y2Nlc3MYASABKAsyPi5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5Ob3RpZmljYXRpb25TZXR0aW5nUmVzcG9uc2UuUmVzdWx0SAASPQoHZmFpbHVyZRgCIAEoDjIqLmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLkZhaWx1cmVNZXNzYWdlSAAaKQoGUmVzdWx0Eh8KF25vdGlmaWNhdGlvbl9zZXR0aW5nX2lkGAEgASgJQggKBnJlc3VsdCLKAQoeQ3JlYXRlTm90aWZpY2F0aW9uR3JvdXBSZXF1ZXN0EgwKBG5hbWUYASABKAkSGAoLZGVzY3JpcHRpb24YAiABKAlIAIgBARI8Cglob3dfb2Z0ZW4YAyABKA4yJC5jb21tb24udjEuTm90aWZpY2F0aW9uR3JvdXBIb3dPZnRlbkgBiAEBEhYKCWlzX3B1YmxpYxgEIAEoCEgCiAEBQg4KDF9kZXNjcmlwdGlvbkIMCgpfaG93X29mdGVuQgwKCl9pc19wdWJsaWMiWgodUmVhZE5vdGlmaWNhdGlvbkdyb3Vwc1JlcXVlc3QSEQoJZ3JvdXBfaWRzGAEgAygJEhcKCmdyb3VwX25hbWUYAiABKAlIAIgBAUINCgtfZ3JvdXBfbmFtZSLpAQoeVXBkYXRlTm90aWZpY2F0aW9uR3JvdXBSZXF1ZXN0Eh0KFW5vdGlmaWNhdGlvbl9ncm91cF9pZBgBIAEoCRIMCgRuYW1lGAIgASgJEhgKC2Rlc2NyaXB0aW9uGAMgASgJSACIAQESPAoJaG93X29mdGVuGAQgASgOMiQuY29tbW9uLnYxLk5vdGlmaWNhdGlvbkdyb3VwSG93T2Z0ZW5IAYgBARIWCglpc19wdWJsaWMYBSABKAhIAogBAUIOCgxfZGVzY3JpcHRpb25CDAoKX2hvd19vZnRlbkIMCgpfaXNfcHVibGljIj8KHkRlbGV0ZU5vdGlmaWNhdGlvbkdyb3VwUmVxdWVzdBIdChVub3RpZmljYXRpb25fZ3JvdXBfaWQYASABKAki6gMKHlJlYWROb3RpZmljYXRpb25Hcm91cHNSZXNwb25zZRJUCgdzdWNjZXNzGAEgASgLMkEuZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuUmVhZE5vdGlmaWNhdGlvbkdyb3Vwc1Jlc3BvbnNlLlJlc3VsdEgAEj0KB2ZhaWx1cmUYAiABKA4yKi5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5GYWlsdXJlTWVzc2FnZUgAGswBCgVHcm91cBIdChVub3RpZmljYXRpb25fZ3JvdXBfaWQYASABKAkSDAoEbmFtZRgCIAEoCRIYCgtkZXNjcmlwdGlvbhgDIAEoCUgAiAEBEjwKCWhvd19vZnRlbhgEIAEoDjIkLmNvbW1vbi52MS5Ob3RpZmljYXRpb25Hcm91cEhvd09mdGVuSAGIAQESDQoFdXNlcnMYBSABKAUSEQoJaXNfcHVibGljGAYgASgIQg4KDF9kZXNjcmlwdGlvbkIMCgpfaG93X29mdGVuGloKBlJlc3VsdBJQCgZncm91cHMYASADKAsyQC5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5SZWFkTm90aWZpY2F0aW9uR3JvdXBzUmVzcG9uc2UuR3JvdXBCCAoGcmVzdWx0It4BChlOb3RpZmljYXRpb25Hcm91cFJlc3BvbnNlEk8KB3N1Y2Nlc3MYASABKAsyPC5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5Ob3RpZmljYXRpb25Hcm91cFJlc3BvbnNlLlJlc3VsdEgAEj0KB2ZhaWx1cmUYAiABKA4yKi5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5GYWlsdXJlTWVzc2FnZUgAGicKBlJlc3VsdBIdChVub3RpZmljYXRpb25fZ3JvdXBfaWQYASABKAlCCAoGcmVzdWx0IqMCCh1DcmVhdGVOb3RpZmljYXRpb25Vc2VyUmVxdWVzdBIMCgRzbHVnGAEgASgJEg0KBWVtYWlsGAIgASgJEg4KBmdyb3VwcxgDIAMoCRISCgVwaG9uZRgEIAEoCUgAiAEBEhcKCmZpcnN0X25hbWUYBSABKAlIAYgBARIWCglsYXN0X25hbWUYBiABKAlIAogBARIjChttb2JpbGVfbm90aWZpY2F0aW9uX2VuYWJsZWQYByABKAgSIgoaZW1haWxfbm90aWZpY2F0aW9uX2VuYWJsZWQYCCABKAgSIAoYc21zX25vdGlmaWNhdGlvbl9lbmFibGVkGAkgASgIQggKBl9waG9uZUINCgtfZmlyc3RfbmFtZUIMCgpfbGFzdF9uYW1lIlgKHFJlYWROb3RpZmljYXRpb25Vc2Vyc1JlcXVlc3QSEAoIdXNlcl9pZHMYASADKAkSFwoKdXNlcl9lbWFpbBgCIAEoCUgAiAEBQg0KC191c2VyX2VtYWlsIrACCh1VcGRhdGVOb3RpZmljYXRpb25Vc2VyUmVxdWVzdBIMCgRzbHVnGAEgASgJEhwKFG5vdGlmaWNhdGlvbl91c2VyX2lkGAIgASgJEhcKCmZpcnN0X25hbWUYAyABKAlIAIgBARIWCglsYXN0X25hbWUYBCABKAlIAYgBARIjChttb2JpbGVfbm90aWZpY2F0aW9uX2VuYWJsZWQYBSABKAgSIgoaZW1haWxfbm90aWZpY2F0aW9uX2VuYWJsZWQYBiABKAgSIAoYc21zX25vdGlmaWNhdGlvbl9lbmFibGVkGAcgASgIEhkKDGFjY2Vzc190b2tlbhgIIAEoCUgCiAEBQg0KC19maXJzdF9uYW1lQgwKCl9sYXN0X25hbWVCDwoNX2FjY2Vzc190b2tlbiJqCh1EZWxldGVOb3RpZmljYXRpb25Vc2VyUmVxdWVzdBIPCgd1c2VyX2lkGAEgASgJEgwKBHNsdWcYAiABKAkSGQoMYWNjZXNzX3Rva2VuGAMgASgJSACIAQFCDwoNX2FjY2Vzc190b2tlbiL4AQodUmVhZE5vdGlmaWNhdGlvblVzZXJzUmVzcG9uc2USUwoHc3VjY2VzcxgBIAEoCzJALmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLlJlYWROb3RpZmljYXRpb25Vc2Vyc1Jlc3BvbnNlLlJlc3VsdEgAEj0KB2ZhaWx1cmUYAiABKA4yKi5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5GYWlsdXJlTWVzc2FnZUgAGjkKBlJlc3VsdBIvCgV1c2VycxgBIAMoCzIgLmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLlVzZXJCCAoGcmVzdWx0IqkCChhOb3RpZmljYXRpb25Vc2VyUmVzcG9uc2USTgoHc3VjY2VzcxgBIAEoCzI7LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLk5vdGlmaWNhdGlvblVzZXJSZXNwb25zZS5SZXN1bHRIABI9CgdmYWlsdXJlGAIgASgOMiouZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuRmFpbHVyZU1lc3NhZ2VIABIZCgxhY2Nlc3NfdG9rZW4YAyABKAlIAYgBARIUCgd1c2VyX2lkGAQgASgJSAKIAQEaJgoGUmVzdWx0EhwKFG5vdGlmaWNhdGlvbl91c2VyX2lkGAEgASgJQggKBnJlc3VsdEIPCg1fYWNjZXNzX3Rva2VuQgoKCF91c2VyX2lkImEKIkNyZWF0ZU5vdGlmaWNhdGlvbkdyb3VwVXNlclJlcXVlc3QSHQoVbm90aWZpY2F0aW9uX2dyb3VwX2lkGAEgASgJEhwKFG5vdGlmaWNhdGlvbl91c2VyX2lkGAIgASgJIjcKIlJlYWROb3RpZmljYXRpb25Hcm91cFVzZXJzUmVxdWVzdHMSEQoJZ3JvdXBfaWRzGAEgAygJIoUBCiJVcGRhdGVOb3RpZmljYXRpb25Hcm91cFVzZXJSZXF1ZXN0EiIKGm5vdGlmaWNhdGlvbl9ncm91cF91c2VyX2lkGAEgASgJEh0KFW5vdGlmaWNhdGlvbl9ncm91cF9pZBgCIAEoCRIcChRub3RpZmljYXRpb25fdXNlcl9pZBgDIAEoCSJICiJEZWxldGVOb3RpZmljYXRpb25Hcm91cFVzZXJSZXF1ZXN0EiIKGm5vdGlmaWNhdGlvbl9ncm91cF91c2VyX2lkGAEgASgJIoICCiJSZWFkTm90aWZpY2F0aW9uR3JvdXBVc2Vyc1Jlc3BvbnNlElgKB3N1Y2Nlc3MYASABKAsyRS5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5SZWFkTm90aWZpY2F0aW9uR3JvdXBVc2Vyc1Jlc3BvbnNlLlJlc3VsdEgAEj0KB2ZhaWx1cmUYAiABKA4yKi5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5GYWlsdXJlTWVzc2FnZUgAGjkKBlJlc3VsdBIvCgV1c2VycxgBIAMoCzIgLmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLlVzZXJCCAoGcmVzdWx0IusBCh1Ob3RpZmljYXRpb25Hcm91cFVzZXJSZXNwb25zZRJTCgdzdWNjZXNzGAEgASgLMkAuZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuTm90aWZpY2F0aW9uR3JvdXBVc2VyUmVzcG9uc2UuUmVzdWx0SAASPQoHZmFpbHVyZRgCIAEoDjIqLmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLkZhaWx1cmVNZXNzYWdlSAAaLAoGUmVzdWx0EiIKGm5vdGlmaWNhdGlvbl9ncm91cF91c2VyX2lkGAEgASgJQggKBnJlc3VsdCJjCgxDaGFubmVsU3RhdHMSEgoKcmVjaXBpZW50cxgBIAEoBRIMCgRzZW50GAIgASgFEhEKCWRlbGl2ZXJlZBgDIAEoBRIOCgZvcGVuZWQYBCABKAUSDgoGZmFpbGVkGAUgASgFIsABChRNZXNzYWdlRGVsaXZlcnlTdGF0cxI3CgVlbWFpbBgBIAEoCzIoLmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLkNoYW5uZWxTdGF0cxI4CgZtb2JpbGUYAiABKAsyKC5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5DaGFubmVsU3RhdHMSNQoDc21zGAMgASgLMiguZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuQ2hhbm5lbFN0YXRzIt0FChNOb3RpZmljYXRpb25NZXNzYWdlEh8KF25vdGlmaWNhdGlvbl9tZXNzYWdlX2lkGAEgASgJEkUKBnN0YXR1cxgCIAEoDjI1LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLk5vdGlmaWNhdGlvbk1lc3NhZ2VTdGF0dXMSKwoHc2VuZF9hdBgDIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASDQoFdGl0bGUYBCABKAkSFQoIc3VidGl0bGUYBSABKAlIAIgBARIUCgdtZXNzYWdlGAYgASgJSAGIAQESFgoJaW1hZ2VfdXJsGAcgASgJSAKIAQESFQoIb3Blbl91cmwYDyABKAlIA4gBARIOCgZncm91cHMYCCADKAkSEAoIcHJvZHVjdHMYCSADKAkSDQoFdXNlcnMYCiADKAkSIwobbW9iaWxlX25vdGlmaWNhdGlvbl9lbmFibGVkGAsgASgIEiIKGmVtYWlsX25vdGlmaWNhdGlvbl9lbmFibGVkGAwgASgIEiAKGHNtc19ub3RpZmljYXRpb25fZW5hYmxlZBgNIAEoCBIaCg1lcnJvcl9tZXNzYWdlGA4gASgJSASIAQESNQoMY2FuY2VsbGVkX2F0GBAgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEgFiAEBEkQKBXN0YXRzGBEgASgLMjAuZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuTWVzc2FnZURlbGl2ZXJ5U3RhdHNIBogBARIcCg9lbWFpbF9ib2R5X2h0bWwYEiABKAlIB4gBAUILCglfc3VidGl0bGVCCgoIX21lc3NhZ2VCDAoKX2ltYWdlX3VybEILCglfb3Blbl91cmxCEAoOX2Vycm9yX21lc3NhZ2VCDwoNX2NhbmNlbGxlZF9hdEIICgZfc3RhdHNCEgoQX2VtYWlsX2JvZHlfaHRtbCKDBAogQ3JlYXRlTm90aWZpY2F0aW9uTWVzc2FnZVJlcXVlc3QSRQoGc3RhdHVzGAEgASgOMjUuZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuTm90aWZpY2F0aW9uTWVzc2FnZVN0YXR1cxIrCgdzZW5kX2F0GAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBINCgV0aXRsZRgDIAEoCRIVCghzdWJ0aXRsZRgEIAEoCUgAiAEBEhQKB21lc3NhZ2UYBSABKAlIAYgBARIWCglpbWFnZV91cmwYBiABKAlIAogBARIVCghvcGVuX3VybBgNIAEoCUgDiAEBEg4KBmdyb3VwcxgHIAMoCRIQCghwcm9kdWN0cxgIIAMoCRINCgV1c2VycxgJIAMoCRIjChttb2JpbGVfbm90aWZpY2F0aW9uX2VuYWJsZWQYCiABKAgSIgoaZW1haWxfbm90aWZpY2F0aW9uX2VuYWJsZWQYCyABKAgSIAoYc21zX25vdGlmaWNhdGlvbl9lbmFibGVkGAwgASgIEhwKD2VtYWlsX2JvZHlfaHRtbBgOIAEoCUgEiAEBQgsKCV9zdWJ0aXRsZUIKCghfbWVzc2FnZUIMCgpfaW1hZ2VfdXJsQgsKCV9vcGVuX3VybEISChBfZW1haWxfYm9keV9odG1sIqQCCiJHZXRTZW50Tm90aWZpY2F0aW9uTWVzc2FnZXNSZXF1ZXN0EiQKF25vdGlmaWNhdGlvbl9tZXNzYWdlX2lkGAEgASgJSACIAQESMwoKc3RhcnRfdGltZRgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBIAYgBARIxCghlbmRfdGltZRgDIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBIAogBARIgChNpbmNsdWRlX2V4cG9ydF9kYXRhGAQgASgISAOIAQFCGgoYX25vdGlmaWNhdGlvbl9tZXNzYWdlX2lkQg0KC19zdGFydF90aW1lQgsKCV9lbmRfdGltZUIWChRfaW5jbHVkZV9leHBvcnRfZGF0YSLhAwojR2V0U2VudE5vdGlmaWNhdGlvbk1lc3NhZ2VzUmVzcG9uc2USWQoHc3VjY2VzcxgBIAEoCzJGLmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLkdldFNlbnROb3RpZmljYXRpb25NZXNzYWdlc1Jlc3BvbnNlLlJlc3VsdEgAEj0KB2ZhaWx1cmUYAiABKA4yKi5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5GYWlsdXJlTWVzc2FnZUgAGigKGE5vdGlmaWNhdGlvbk1lc3NhZ2VTdGF0cxIMCgRzZW50GAEgASgFGusBCgZSZXN1bHQSTgoVbm90aWZpY2F0aW9uX21lc3NhZ2VzGAEgAygLMi8uZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuTm90aWZpY2F0aW9uTWVzc2FnZRJnCgVzdGF0cxgCIAEoCzJYLmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLkdldFNlbnROb3RpZmljYXRpb25NZXNzYWdlc1Jlc3BvbnNlLk5vdGlmaWNhdGlvbk1lc3NhZ2VTdGF0cxIYCgtleHBvcnRfZGF0YRgDIAEoDEgAiAEBQg4KDF9leHBvcnRfZGF0YUIICgZyZXN1bHQi+gEKH1JlYWROb3RpZmljYXRpb25NZXNzYWdlc1JlcXVlc3QSJAoXbm90aWZpY2F0aW9uX21lc3NhZ2VfaWQYASABKAlIAIgBARIWCglwYWdlX3NpemUYAiABKAVIAYgBARIXCgpwYWdlX3Rva2VuGAMgASgJSAKIAQESRwoIc3RhdHVzZXMYBCADKA4yNS5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5Ob3RpZmljYXRpb25NZXNzYWdlU3RhdHVzQhoKGF9ub3RpZmljYXRpb25fbWVzc2FnZV9pZEIMCgpfcGFnZV9zaXplQg0KC19wYWdlX3Rva2VuItIECiBVcGRhdGVOb3RpZmljYXRpb25NZXNzYWdlUmVxdWVzdBIfChdub3RpZmljYXRpb25fbWVzc2FnZV9pZBgBIAEoCRJFCgZzdGF0dXMYAiABKA4yNS5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5Ob3RpZmljYXRpb25NZXNzYWdlU3RhdHVzEisKB3NlbmRfYXQYAyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEg0KBXRpdGxlGAQgASgJEhUKCHN1YnRpdGxlGAUgASgJSACIAQESFAoHbWVzc2FnZRgGIAEoCUgBiAEBEhYKCWltYWdlX3VybBgHIAEoCUgCiAEBEg4KBmdyb3VwcxgIIAMoCRIQCghwcm9kdWN0cxgJIAMoCRINCgV1c2VycxgKIAMoCRIjChttb2JpbGVfbm90aWZpY2F0aW9uX2VuYWJsZWQYCyABKAgSIgoaZW1haWxfbm90aWZpY2F0aW9uX2VuYWJsZWQYDCABKAgSIAoYc21zX25vdGlmaWNhdGlvbl9lbmFibGVkGA0gASgIEhoKDWVycm9yX21lc3NhZ2UYDiABKAlIA4gBARIVCghvcGVuX3VybBgPIAEoCUgEiAEBEhwKD2VtYWlsX2JvZHlfaHRtbBgQIAEoCUgFiAEBQgsKCV9zdWJ0aXRsZUIKCghfbWVzc2FnZUIMCgpfaW1hZ2VfdXJsQhAKDl9lcnJvcl9tZXNzYWdlQgsKCV9vcGVuX3VybEISChBfZW1haWxfYm9keV9odG1sIkMKIENhbmNlbE5vdGlmaWNhdGlvbk1lc3NhZ2VSZXF1ZXN0Eh8KF25vdGlmaWNhdGlvbl9tZXNzYWdlX2lkGAEgASgJIkYKI0R1cGxpY2F0ZU5vdGlmaWNhdGlvbk1lc3NhZ2VSZXF1ZXN0Eh8KF25vdGlmaWNhdGlvbl9tZXNzYWdlX2lkGAEgASgJIkwKKVJldHJ5RmFpbGVkTm90aWZpY2F0aW9uTWVzc2FnZUpvYnNSZXF1ZXN0Eh8KF25vdGlmaWNhdGlvbl9tZXNzYWdlX2lkGAEgASgJIoYCCipSZXRyeUZhaWxlZE5vdGlmaWNhdGlvbk1lc3NhZ2VKb2JzUmVzcG9uc2USYAoHc3VjY2VzcxgBIAEoCzJNLmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLlJldHJ5RmFpbGVkTm90aWZpY2F0aW9uTWVzc2FnZUpvYnNSZXNwb25zZS5SZXN1bHRIABI9CgdmYWlsdXJlGAIgASgOMiouZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuRmFpbHVyZU1lc3NhZ2VIABotCgZSZXN1bHQSEAoIcmVxdWV1ZWQYASABKAUSEQoJZXhoYXVzdGVkGAIgASgFQggKBnJlc3VsdCJGCiNHZXROb3RpZmljYXRpb25NZXNzYWdlUmVwb3J0UmVxdWVzdBIfChdub3RpZmljYXRpb25fbWVzc2FnZV9pZBgBIAEoCSL6AgokR2V0Tm90aWZpY2F0aW9uTWVzc2FnZVJlcG9ydFJlc3BvbnNlEloKB3N1Y2Nlc3MYASABKAsyRy5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5HZXROb3RpZmljYXRpb25NZXNzYWdlUmVwb3J0UmVzcG9uc2UuUmVzdWx0SAASPQoHZmFpbHVyZRgCIAEoDjIqLmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLkZhaWx1cmVNZXNzYWdlSAAarAEKBlJlc3VsdBJNChRub3RpZmljYXRpb25fbWVzc2FnZRgBIAEoCzIvLmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLk5vdGlmaWNhdGlvbk1lc3NhZ2USPwoFc3RhdHMYAiABKAsyMC5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5NZXNzYWdlRGVsaXZlcnlTdGF0cxISCgpyZWNpcGllbnRzGAMgASgFQggKBnJlc3VsdCJDCiBEZWxldGVOb3RpZmljYXRpb25NZXNzYWdlUmVxdWVzdBIfChdub3RpZmljYXRpb25fbWVzc2FnZV9pZBgBIAEoCSK2AgogUmVhZE5vdGlmaWNhdGlvbk1lc3NhZ2VzUmVzcG9uc2USVgoHc3VjY2VzcxgBIAEoCzJDLmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLlJlYWROb3RpZmljYXRpb25NZXNzYWdlc1Jlc3BvbnNlLlJlc3VsdEgAEj0KB2ZhaWx1cmUYAiABKA4yKi5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5GYWlsdXJlTWVzc2FnZUgAGnEKBlJlc3VsdBJOChVub3RpZmljYXRpb25fbWVzc2FnZXMYASADKAsyLy5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5Ob3RpZmljYXRpb25NZXNzYWdlEhcKD25leHRfcGFnZV90b2tlbhgCIAEoCUIICgZyZXN1bHQi5AEKG05vdGlmaWNhdGlvbk1lc3NhZ2VSZXNwb25zZRJRCgdzdWNjZXNzGAEgASgLMj4uZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuTm90aWZpY2F0aW9uTWVzc2FnZVJlc3BvbnNlLlJlc3VsdEgAEj0KB2ZhaWx1cmUYAiABKA4yKi5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5GYWlsdXJlTWVzc2FnZUgAGikKBlJlc3VsdBIfChdub3RpZmljYXRpb25fbWVzc2FnZV9pZBgBIAEoCUIICgZyZXN1bHQikgIKI0NyZWF0ZU5vdGlmaWNhdGlvbk1lc3NhZ2VKb2JSZXF1ZXN0EkgKBnN0YXR1cxgBIAEoDjI4LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLk5vdGlmaWNhdGlvbk1lc3NhZ2VKb2JTdGF0dXMSKwoHc2VudF9hdBgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASEwoLY3VzdG9tZXJfaWQYAyABKAkSHwoXbm90aWZpY2F0aW9uX21lc3NhZ2VfaWQYBCABKAkSEAoIcHJpb3JpdHkYBSADKAkSGgoNZXJyb3JfbWVzc2FnZRgGIAEoCUgAiAEBQhAKDl9lcnJvcl9tZXNzYWdlIuUEChROb3RpZmljYXRpb25EZWxpdmVyeRIgChhub3RpZmljYXRpb25fZGVsaXZlcnlfaWQYASABKAkSHwoXbm90aWZpY2F0aW9uX21lc3NhZ2VfaWQYAiABKAkSEwoLY3VzdG9tZXJfaWQYAyABKAkSGwoOcmVjaXBpZW50X25hbWUYBCABKAlIAIgBARIXCg9yZWNpcGllbnRfZW1haWwYBSABKAkSSAoHY2hhbm5lbBgGIAEoDjI3LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLk5vdGlmaWNhdGlvbkRlbGl2ZXJ5Q2hhbm5lbBJGCgZzdGF0dXMYByABKA4yNi5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5Ob3RpZmljYXRpb25EZWxpdmVyeVN0YXR1cxIwCgdzZW50X2F0GAggASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEgBiAEBEjUKDGRlbGl2ZXJlZF9hdBgJIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBIAogBARIyCglvcGVuZWRfYXQYCiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wSAOIAQESGgoNZXJyb3JfbWVzc2FnZRgLIAEoCUgEiAEBEhIKCm9wZW5fY291bnQYDCABKAUSEAoIYXR0ZW1wdHMYDSABKAVCEQoPX3JlY2lwaWVudF9uYW1lQgoKCF9zZW50X2F0Qg8KDV9kZWxpdmVyZWRfYXRCDAoKX29wZW5lZF9hdEIQCg5fZXJyb3JfbWVzc2FnZSLIAwoiUmVhZE5vdGlmaWNhdGlvbk1lc3NhZ2VKb2JzUmVxdWVzdBIoChtub3RpZmljYXRpb25fbWVzc2FnZV9qb2JfaWQYASABKAlIAIgBARIkChdub3RpZmljYXRpb25fbWVzc2FnZV9pZBgCIAEoCUgBiAEBEk0KB2NoYW5uZWwYAyABKA4yNy5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5Ob3RpZmljYXRpb25EZWxpdmVyeUNoYW5uZWxIAogBARJNCgdvdXRjb21lGAQgASgOMjcuZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuTm90aWZpY2F0aW9uRGVsaXZlcnlPdXRjb21lSAOIAQESEwoGc2VhcmNoGAUgASgJSASIAQESEQoEcGFnZRgGIAEoBUgFiAEBEhYKCXBhZ2Vfc2l6ZRgHIAEoBUgGiAEBQh4KHF9ub3RpZmljYXRpb25fbWVzc2FnZV9qb2JfaWRCGgoYX25vdGlmaWNhdGlvbl9tZXNzYWdlX2lkQgoKCF9jaGFubmVsQgoKCF9vdXRjb21lQgkKB19zZWFyY2hCBwoFX3BhZ2VCDAoKX3BhZ2Vfc2l6ZSLvAQojVXBkYXRlTm90aWZpY2F0aW9uTWVzc2FnZUpvYlJlcXVlc3QSIwobbm90aWZpY2F0aW9uX21lc3NhZ2Vfam9iX2lkGAEgASgJEkgKBnN0YXR1cxgCIAEoDjI4LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLk5vdGlmaWNhdGlvbk1lc3NhZ2VKb2JTdGF0dXMSKwoHc2VudF9hdBgDIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASGgoNZXJyb3JfbWVzc2FnZRgEIAEoCUgAiAEBQhAKDl9lcnJvcl9tZXNzYWdlIkoKI0RlbGV0ZU5vdGlmaWNhdGlvbk1lc3NhZ2VKb2JSZXF1ZXN0EiMKG25vdGlmaWNhdGlvbl9tZXNzYWdlX2pvYl9pZBgBIAEoCSLRBQojUmVhZE5vdGlmaWNhdGlvbk1lc3NhZ2VKb2JzUmVzcG9uc2USWQoHc3VjY2VzcxgBIAEoCzJGLmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLlJlYWROb3RpZmljYXRpb25NZXNzYWdlSm9ic1Jlc3BvbnNlLlJlc3VsdEgAEj0KB2ZhaWx1cmUYAiABKA4yKi5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5GYWlsdXJlTWVzc2FnZUgAGqoCChZOb3RpZmljYXRpb25NZXNzYWdlSm9iEiMKG25vdGlmaWNhdGlvbl9tZXNzYWdlX2pvYl9pZBgBIAEoCRJICgZzdGF0dXMYAiABKA4yOC5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5Ob3RpZmljYXRpb25NZXNzYWdlSm9iU3RhdHVzEisKB3NlbnRfYXQYAyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhMKC2N1c3RvbWVyX2lkGAQgASgJEh8KF25vdGlmaWNhdGlvbl9tZXNzYWdlX2lkGAUgASgJEhAKCHByaW9yaXR5GAYgAygJEhoKDWVycm9yX21lc3NhZ2UYByABKAlIAIgBAUIQCg5fZXJyb3JfbWVzc2FnZRrYAQoGUmVzdWx0EnkKGW5vdGlmaWNhdGlvbl9tZXNzYWdlX2pvYnMYASADKAsyVi5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5SZWFkTm90aWZpY2F0aW9uTWVzc2FnZUpvYnNSZXNwb25zZS5Ob3RpZmljYXRpb25NZXNzYWdlSm9iEkQKCmRlbGl2ZXJpZXMYAiADKAsyMC5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5Ob3RpZmljYXRpb25EZWxpdmVyeRINCgV0b3RhbBgDIAEoBUIICgZyZXN1bHQi7gEKHk5vdGlmaWNhdGlvbk1lc3NhZ2VKb2JSZXNwb25zZRJUCgdzdWNjZXNzGAEgASgLMkEuZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuTm90aWZpY2F0aW9uTWVzc2FnZUpvYlJlc3BvbnNlLlJlc3VsdEgAEj0KB2ZhaWx1cmUYAiABKA4yKi5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5GYWlsdXJlTWVzc2FnZUgAGi0KBlJlc3VsdBIjChtub3RpZmljYXRpb25fbWVzc2FnZV9qb2JfaWQYASABKAlCCAoGcmVzdWx0ItACCgRVc2VyEhwKFG5vdGlmaWNhdGlvbl91c2VyX2lkGAEgASgJEg0KBWVtYWlsGAIgASgJEhcKCmZpcnN0X25hbWUYAyABKAlIAIgBARIWCglsYXN0X25hbWUYBCABKAlIAYgBARIjChttb2JpbGVfbm90aWZpY2F0aW9uX2VuYWJsZWQYBSABKAgSIgoaZW1haWxfbm90aWZpY2F0aW9uX2VuYWJsZWQYBiABKAgSIAoYc21zX25vdGlmaWNhdGlvbl9lbmFibGVkGAcgASgIEi4KCmNyZWF0ZWRfYXQYCCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEh0KEGlzX2FwcF9pbnN0YWxsZWQYCSABKAhIAogBAUINCgtfZmlyc3RfbmFtZUIMCgpfbGFzdF9uYW1lQhMKEV9pc19hcHBfaW5zdGFsbGVkIjYKH1JlYWROb3RpZmljYXRpb25Qcm9kdWN0c1JlcXVlc3QSEwoLcHJvZHVjdF9pZHMYASADKAkisQEKJlByZXZpZXdOb3RpZmljYXRpb25NZXNzYWdlRW1haWxSZXF1ZXN0Eg0KBXRpdGxlGAEgASgJEhQKB21lc3NhZ2UYAiABKAlIAIgBARIcCg9lbWFpbF9ib2R5X2h0bWwYAyABKAlIAYgBARIWCglpbWFnZV91cmwYBCABKAlIAogBAUIKCghfbWVzc2FnZUISChBfZW1haWxfYm9keV9odG1sQgwKCl9pbWFnZV91cmwimwIKJ1ByZXZpZXdOb3RpZmljYXRpb25NZXNzYWdlRW1haWxSZXNwb25zZRJdCgdzdWNjZXNzGAEgASgLMkouZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuUHJldmlld05vdGlmaWNhdGlvbk1lc3NhZ2VFbWFpbFJlc3BvbnNlLlJlc3VsdEgAEj0KB2ZhaWx1cmUYAiABKA4yKi5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5GYWlsdXJlTWVzc2FnZUgAGkgKBlJlc3VsdBIPCgdzdWJqZWN0GAEgASgJEhEKCXByZWhlYWRlchgCIAEoCRIMCgRodG1sGAMgASgJEgwKBHRleHQYBCABKAlCCAoGcmVzdWx0IlQKIUdldFByb2plY3RlZFJlY2lwaWVudENvdW50UmVxdWVzdBIOCgZncm91cHMYASADKAkSEAoIcHJvZHVjdHMYAiADKAkSDQoFdXNlcnMYAyADKAkicQoiR2V0UHJvamVjdGVkUmVjaXBpZW50Q291bnRSZXNwb25zZRINCgV0b3RhbBgBIAEoBRITCgtlbWFpbF9jb3VudBgCIAEoBRIRCglzbXNfY291bnQYAyABKAUSFAoMbW9iaWxlX2NvdW50GAQgASgFIqEBChtHZXROb3RpZmljYXRpb25TdGF0c1JlcXVlc3QSMwoKc3RhcnRfdGltZRgBIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBIAIgBARIxCghlbmRfdGltZRgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBIAYgBAUINCgtfc3RhcnRfdGltZUILCglfZW5kX3RpbWUi7AUKHEdldE5vdGlmaWNhdGlvblN0YXRzUmVzcG9uc2USUgoHc3VjY2VzcxgBIAEoCzI/LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLkdldE5vdGlmaWNhdGlvblN0YXRzUmVzcG9uc2UuUmVzdWx0SAASPQoHZmFpbHVyZRgCIAEoDjIqLmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLkZhaWx1cmVNZXNzYWdlSAAadwoPU3RhdHVzQnJlYWtkb3duEg4KBmRyYWZ0cxgBIAEoBRIPCgdwbGFubmVkGAIgASgFEhMKC2luX3Byb2dyZXNzGAMgASgFEgwKBHNlbnQYBCABKAUSDQoFZXJyb3IYBSABKAUSEQoJY2FuY2VsbGVkGAYgASgFGj4KEENoYW5uZWxCcmVha2Rvd24SDgoGbW9iaWxlGAEgASgFEg0KBWVtYWlsGAIgASgFEgsKA3NtcxgDIAEoBRosCg1UaW1lbGluZVBvaW50EgwKBGRhdGUYASABKAkSDQoFY291bnQYAiABKAUaxwIKBlJlc3VsdBJiChBzdGF0dXNfYnJlYWtkb3duGAEgASgLMkguZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuR2V0Tm90aWZpY2F0aW9uU3RhdHNSZXNwb25zZS5TdGF0dXNCcmVha2Rvd24SZAoRY2hhbm5lbF9icmVha2Rvd24YAiABKAsySS5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5HZXROb3RpZmljYXRpb25TdGF0c1Jlc3BvbnNlLkNoYW5uZWxCcmVha2Rvd24SWAoIdGltZWxpbmUYAyADKAsyRi5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5HZXROb3RpZmljYXRpb25TdGF0c1Jlc3BvbnNlLlRpbWVsaW5lUG9pbnQSGQoRdG90YWxfc3Vic2NyaWJlcnMYBCABKAVCCAoGcmVzdWx0KmgKGU5vdGlmaWNhdGlvbk1lc3NhZ2VTdGF0dXMSCQoFRFJBRlQQABILCgdQTEFOTkVEEAESDwoLSU5fUFJPR1JFU1MQAhIICgRTRU5UEAMSCQoFRVJST1IQBBINCglDQU5DRUxMRUQQBSrOAQocTm90aWZpY2F0aW9uTWVzc2FnZUpvYlN0YXR1cxIoCiROT1RJRklDQVRJT05fTUVTU0FHRV9KT0JfU1RBVFVTX1RPRE8QABIvCitOT1RJRklDQVRJT05fTUVTU0FHRV9KT0JfU1RBVFVTX0lOX1BST0dSRVNTEAESKAokTk9USUZJQ0FUSU9OX01FU1NBR0VfSk9CX1NUQVRVU19TRU5UEAISKQolTk9USUZJQ0FUSU9OX01FU1NBR0VfSk9CX1NUQVRVU19FUlJPUhADKsYBChtOb3RpZmljYXRpb25EZWxpdmVyeUNoYW5uZWwSLQopTk9USUZJQ0FUSU9OX0RFTElWRVJZX0NIQU5ORUxfVU5TUEVDSUZJRUQQABInCiNOT1RJRklDQVRJT05fREVMSVZFUllfQ0hBTk5FTF9FTUFJTBABEigKJE5PVElGSUNBVElPTl9ERUxJVkVSWV9DSEFOTkVMX01PQklMRRACEiUKIU5PVElGSUNBVElPTl9ERUxJVkVSWV9DSEFOTkVMX1NNUxADKu4BChpOb3RpZmljYXRpb25EZWxpdmVyeVN0YXR1cxIsCihOT1RJRklDQVRJT05fREVMSVZFUllfU1RBVFVTX1VOU1BFQ0lGSUVEEAASKAokTk9USUZJQ0FUSU9OX0RFTElWRVJZX1NUQVRVU19QRU5ESU5HEAESJQohTk9USUZJQ0FUSU9OX0RFTElWRVJZX1NUQVRVU19TRU5UEAISJwojTk9USUZJQ0FUSU9OX0RFTElWRVJZX1NUQVRVU19GQUlMRUQQAxIoCiROT1RJRklDQVRJT05fREVMSVZFUllfU1RBVFVTX1NLSVBQRUQQBCrAAQobTm90aWZpY2F0aW9uRGVsaXZlcnlPdXRjb21lEiUKIU5PVElGSUNBVElPTl9ERUxJVkVSWV9PVVRDT01FX0FOWRAAEiYKIk5PVElGSUNBVElPTl9ERUxJVkVSWV9PVVRDT01FX1NFTlQQARIoCiROT1RJRklDQVRJT05fREVMSVZFUllfT1VUQ09NRV9GQUlMRUQQAhIoCiROT1RJRklDQVRJT05fREVMSVZFUllfT1VUQ09NRV9PUEVORUQQAyrPEQoORmFpbHVyZU1lc3NhZ2USGwoXRkFJTFVSRV9NRVNTQUdFX1VOS05PV04QABIlCiFGQUlMVVJFX01FU1NBR0VfUFJPSkVDVF9OT1RfRk9VTkQQARIyCi5GQUlMVVJFX01FU1NBR0VfTk9USUZJQ0FUSU9OX1NFVFRJTkdfTk9UX0ZPVU5EEAISNgoyRkFJTFVSRV9NRVNTQUdFX0NSRUFURV9OT1RJRklDQVRJT05fU0VUVElOR19GQUlMRUQQAxI2CjJGQUlMVVJFX01FU1NBR0VfVVBEQVRFX05PVElGSUNBVElPTl9TRVRUSU5HX0ZBSUxFRBAEEjYKMkZBSUxVUkVfTUVTU0FHRV9ERUxFVEVfTk9USUZJQ0FUSU9OX1NFVFRJTkdfRkFJTEVEEAUSMAosRkFJTFVSRV9NRVNTQUdFX05PVElGSUNBVElPTl9HUk9VUF9OT1RfRk9VTkQQBhIxCi1GQUlMVVJFX01FU1NBR0VfTk9USUZJQ0FUSU9OX0dST1VQU19OT1RfRk9VTkQQBxI0CjBGQUlMVVJFX01FU1NBR0VfQ1JFQVRFX05PVElGSUNBVElPTl9HUk9VUF9GQUlMRUQQCBI0CjBGQUlMVVJFX01FU1NBR0VfVVBEQVRFX05PVElGSUNBVElPTl9HUk9VUF9GQUlMRUQQCRI0CjBGQUlMVVJFX01FU1NBR0VfREVMRVRFX05PVElGSUNBVElPTl9HUk9VUF9GQUlMRUQQChIvCitGQUlMVVJFX01FU1NBR0VfTk9USUZJQ0FUSU9OX1VTRVJfTk9UX0ZPVU5EEAsSMAosRkFJTFVSRV9NRVNTQUdFX05PVElGSUNBVElPTl9VU0VSU19OT1RfRk9VTkQQDBIzCi9GQUlMVVJFX01FU1NBR0VfQ1JFQVRFX05PVElGSUNBVElPTl9VU0VSX0ZBSUxFRBANEjMKL0ZBSUxVUkVfTUVTU0FHRV9VUERBVEVfTk9USUZJQ0FUSU9OX1VTRVJfRkFJTEVEEA4SMwovRkFJTFVSRV9NRVNTQUdFX0RFTEVURV9OT1RJRklDQVRJT05fVVNFUl9GQUlMRUQQDxI1CjFGQUlMVVJFX01FU1NBR0VfTk9USUZJQ0FUSU9OX0dST1VQX1VTRVJfTk9UX0ZPVU5EEBASOQo1RkFJTFVSRV9NRVNTQUdFX0NSRUFURV9OT1RJRklDQVRJT05fR1JPVVBfVVNFUl9GQUlMRUQQERI5CjVGQUlMVVJFX01FU1NBR0VfVVBEQVRFX05PVElGSUNBVElPTl9HUk9VUF9VU0VSX0ZBSUxFRBASEjkKNUZBSUxVUkVfTUVTU0FHRV9ERUxFVEVfTk9USUZJQ0FUSU9OX0dST1VQX1VTRVJfRkFJTEVEEBMSMgouRkFJTFVSRV9NRVNTQUdFX05PVElGSUNBVElPTl9NRVNTQUdFX05PVF9GT1VORBAUEjMKL0ZBSUxVUkVfTUVTU0FHRV9OT1RJRklDQVRJT05fTUVTU0FHRVNfTk9UX0ZPVU5EEBUSNgoyRkFJTFVSRV9NRVNTQUdFX0NSRUFURV9OT1RJRklDQVRJT05fTUVTU0FHRV9GQUlMRUQQFhI2CjJGQUlMVVJFX01FU1NBR0VfVVBEQVRFX05PVElGSUNBVElPTl9NRVNTQUdFX0ZBSUxFRBAXEjYKMkZBSUxVUkVfTUVTU0FHRV9ERUxFVEVfTk9USUZJQ0FUSU9OX01FU1NBR0VfRkFJTEVEEBgSNgoyRkFJTFVSRV9NRVNTQUdFX05PVElGSUNBVElPTl9NRVNTQUdFX0pPQl9OT1RfRk9VTkQQGRI3CjNGQUlMVVJFX01FU1NBR0VfTk9USUZJQ0FUSU9OX01FU1NBR0VfSk9CU19OT1RfRk9VTkQQGhI6CjZGQUlMVVJFX01FU1NBR0VfQ1JFQVRFX05PVElGSUNBVElPTl9NRVNTQUdFX0pPQl9GQUlMRUQQGxI6CjZGQUlMVVJFX01FU1NBR0VfVVBEQVRFX05PVElGSUNBVElPTl9NRVNTQUdFX0pPQl9GQUlMRUQQHBI6CjZGQUlMVVJFX01FU1NBR0VfREVMRVRFX05PVElGSUNBVElPTl9NRVNTQUdFX0pPQl9GQUlMRUQQHRI2CjJGQUlMVVJFX01FU1NBR0VfTk9USUZJQ0FUSU9OX1NFVFRJTkdfQUxSRUFEWV9FWElTVBAeEjsKN0ZBSUxVUkVfTUVTU0FHRV9OT1RJRklDQVRJT05fU0VUVElOR19TTFVHX0FMUkVBRFlfVEFLRU4QHxIzCi9GQUlMVVJFX01FU1NBR0VfTk9USUZJQ0FUSU9OX1VTRVJfQUxSRUFEWV9FWElTVBAgEjQKMEZBSUxVUkVfTUVTU0FHRV9OT1RJRklDQVRJT05fR1JPVVBfQUxSRUFEWV9FWElTVBAhEjgKNEZBSUxVUkVfTUVTU0FHRV9OT1RJRklDQVRJT05fTUVTU0FHRV9OT1RfQ0FOQ0VMTEFCTEUQIhI2CjJGQUlMVVJFX01FU1NBR0VfQ0FOQ0VMX05PVElGSUNBVElPTl9NRVNTQUdFX0ZBSUxFRBAjEjUKMUZBSUxVUkVfTUVTU0FHRV9SRVRSWV9OT1RJRklDQVRJT05fTUVTU0FHRV9GQUlMRUQQJBI5CjVGQUlMVVJFX01FU1NBR0VfRFVQTElDQVRFX05PVElGSUNBVElPTl9NRVNTQUdFX0ZBSUxFRBAlEjUKMUZBSUxVUkVfTUVTU0FHRV9OT1RJRklDQVRJT05fTUVTU0FHRV9OT1RfRURJVEFCTEUQJhIoCiRGQUlMVVJFX01FU1NBR0VfRU1BSUxfUVVPVEFfRVhDRUVERUQQJxIoCiRGQUlMVVJFX01FU1NBR0VfRU1BSUxfUFJFVklFV19GQUlMRUQQKBInCiNGQUlMVVJFX01FU1NBR0VfRU1BSUxfQk9EWV9UT09fTE9ORxApMpwrChROb3RpZmljYXRpb25zU2VydmljZRKSAQoZQ3JlYXRlTm90aWZpY2F0aW9uU2V0dGluZxI8LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLkNyZWF0ZU5vdGlmaWNhdGlvblNldHRpbmdSZXF1ZXN0GjcuZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuTm90aWZpY2F0aW9uU2V0dGluZ1Jlc3BvbnNlEpIBChdSZWFkTm90aWZpY2F0aW9uU2V0dGluZxI6LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLlJlYWROb3RpZmljYXRpb25TZXR0aW5nUmVxdWVzdBo7LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLlJlYWROb3RpZmljYXRpb25TZXR0aW5nUmVzcG9uc2USkgEKGVVwZGF0ZU5vdGlmaWNhdGlvblNldHRpbmcSPC5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5VcGRhdGVOb3RpZmljYXRpb25TZXR0aW5nUmVxdWVzdBo3LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLk5vdGlmaWNhdGlvblNldHRpbmdSZXNwb25zZRKSAQoZRGVsZXRlTm90aWZpY2F0aW9uU2V0dGluZxI8LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLkRlbGV0ZU5vdGlmaWNhdGlvblNldHRpbmdSZXF1ZXN0GjcuZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuTm90aWZpY2F0aW9uU2V0dGluZ1Jlc3BvbnNlEowBChdDcmVhdGVOb3RpZmljYXRpb25Hcm91cBI6LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLkNyZWF0ZU5vdGlmaWNhdGlvbkdyb3VwUmVxdWVzdBo1LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLk5vdGlmaWNhdGlvbkdyb3VwUmVzcG9uc2USjwEKFlJlYWROb3RpZmljYXRpb25Hcm91cHMSOS5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5SZWFkTm90aWZpY2F0aW9uR3JvdXBzUmVxdWVzdBo6LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLlJlYWROb3RpZmljYXRpb25Hcm91cHNSZXNwb25zZRKMAQoXVXBkYXRlTm90aWZpY2F0aW9uR3JvdXASOi5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5VcGRhdGVOb3RpZmljYXRpb25Hcm91cFJlcXVlc3QaNS5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5Ob3RpZmljYXRpb25Hcm91cFJlc3BvbnNlEowBChdEZWxldGVOb3RpZmljYXRpb25Hcm91cBI6LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLkRlbGV0ZU5vdGlmaWNhdGlvbkdyb3VwUmVxdWVzdBo1LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLk5vdGlmaWNhdGlvbkdyb3VwUmVzcG9uc2USiQEKFkNyZWF0ZU5vdGlmaWNhdGlvblVzZXISOS5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5DcmVhdGVOb3RpZmljYXRpb25Vc2VyUmVxdWVzdBo0LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLk5vdGlmaWNhdGlvblVzZXJSZXNwb25zZRKMAQoVUmVhZE5vdGlmaWNhdGlvblVzZXJzEjguZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuUmVhZE5vdGlmaWNhdGlvblVzZXJzUmVxdWVzdBo5LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLlJlYWROb3RpZmljYXRpb25Vc2Vyc1Jlc3BvbnNlEokBChZVcGRhdGVOb3RpZmljYXRpb25Vc2VyEjkuZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuVXBkYXRlTm90aWZpY2F0aW9uVXNlclJlcXVlc3QaNC5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5Ob3RpZmljYXRpb25Vc2VyUmVzcG9uc2USiQEKFkRlbGV0ZU5vdGlmaWNhdGlvblVzZXISOS5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5EZWxldGVOb3RpZmljYXRpb25Vc2VyUmVxdWVzdBo0LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLk5vdGlmaWNhdGlvblVzZXJSZXNwb25zZRKYAQobQ3JlYXRlTm90aWZpY2F0aW9uR3JvdXBVc2VyEj4uZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuQ3JlYXRlTm90aWZpY2F0aW9uR3JvdXBVc2VyUmVxdWVzdBo5LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLk5vdGlmaWNhdGlvbkdyb3VwVXNlclJlc3BvbnNlEpwBChpSZWFkTm90aWZpY2F0aW9uR3JvdXBVc2VycxI+LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLlJlYWROb3RpZmljYXRpb25Hcm91cFVzZXJzUmVxdWVzdHMaPi5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5SZWFkTm90aWZpY2F0aW9uR3JvdXBVc2Vyc1Jlc3BvbnNlEpgBChtVcGRhdGVOb3RpZmljYXRpb25Hcm91cFVzZXISPi5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5VcGRhdGVOb3RpZmljYXRpb25Hcm91cFVzZXJSZXF1ZXN0GjkuZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuTm90aWZpY2F0aW9uR3JvdXBVc2VyUmVzcG9uc2USmAEKG0RlbGV0ZU5vdGlmaWNhdGlvbkdyb3VwVXNlchI+LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLkRlbGV0ZU5vdGlmaWNhdGlvbkdyb3VwVXNlclJlcXVlc3QaOS5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5Ob3RpZmljYXRpb25Hcm91cFVzZXJSZXNwb25zZRKSAQoZQ3JlYXRlTm90aWZpY2F0aW9uTWVzc2FnZRI8LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLkNyZWF0ZU5vdGlmaWNhdGlvbk1lc3NhZ2VSZXF1ZXN0GjcuZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuTm90aWZpY2F0aW9uTWVzc2FnZVJlc3BvbnNlEpUBChhSZWFkTm90aWZpY2F0aW9uTWVzc2FnZXMSOy5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5SZWFkTm90aWZpY2F0aW9uTWVzc2FnZXNSZXF1ZXN0GjwuZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuUmVhZE5vdGlmaWNhdGlvbk1lc3NhZ2VzUmVzcG9uc2USngEKG0dldFNlbnROb3RpZmljYXRpb25NZXNzYWdlcxI+LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLkdldFNlbnROb3RpZmljYXRpb25NZXNzYWdlc1JlcXVlc3QaPy5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5HZXRTZW50Tm90aWZpY2F0aW9uTWVzc2FnZXNSZXNwb25zZRKSAQoZVXBkYXRlTm90aWZpY2F0aW9uTWVzc2FnZRI8LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLlVwZGF0ZU5vdGlmaWNhdGlvbk1lc3NhZ2VSZXF1ZXN0GjcuZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuTm90aWZpY2F0aW9uTWVzc2FnZVJlc3BvbnNlEpIBChlEZWxldGVOb3RpZmljYXRpb25NZXNzYWdlEjwuZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuRGVsZXRlTm90aWZpY2F0aW9uTWVzc2FnZVJlcXVlc3QaNy5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5Ob3RpZmljYXRpb25NZXNzYWdlUmVzcG9uc2USkgEKGUNhbmNlbE5vdGlmaWNhdGlvbk1lc3NhZ2USPC5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5DYW5jZWxOb3RpZmljYXRpb25NZXNzYWdlUmVxdWVzdBo3LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLk5vdGlmaWNhdGlvbk1lc3NhZ2VSZXNwb25zZRKzAQoiUmV0cnlGYWlsZWROb3RpZmljYXRpb25NZXNzYWdlSm9icxJFLmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLlJldHJ5RmFpbGVkTm90aWZpY2F0aW9uTWVzc2FnZUpvYnNSZXF1ZXN0GkYuZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuUmV0cnlGYWlsZWROb3RpZmljYXRpb25NZXNzYWdlSm9ic1Jlc3BvbnNlEpgBChxEdXBsaWNhdGVOb3RpZmljYXRpb25NZXNzYWdlEj8uZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuRHVwbGljYXRlTm90aWZpY2F0aW9uTWVzc2FnZVJlcXVlc3QaNy5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5Ob3RpZmljYXRpb25NZXNzYWdlUmVzcG9uc2USoQEKHEdldE5vdGlmaWNhdGlvbk1lc3NhZ2VSZXBvcnQSPy5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5HZXROb3RpZmljYXRpb25NZXNzYWdlUmVwb3J0UmVxdWVzdBpALmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLkdldE5vdGlmaWNhdGlvbk1lc3NhZ2VSZXBvcnRSZXNwb25zZRKbAQocQ3JlYXRlTm90aWZpY2F0aW9uTWVzc2FnZUpvYhI/LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLkNyZWF0ZU5vdGlmaWNhdGlvbk1lc3NhZ2VKb2JSZXF1ZXN0GjouZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuTm90aWZpY2F0aW9uTWVzc2FnZUpvYlJlc3BvbnNlEp4BChtSZWFkTm90aWZpY2F0aW9uTWVzc2FnZUpvYnMSPi5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5SZWFkTm90aWZpY2F0aW9uTWVzc2FnZUpvYnNSZXF1ZXN0Gj8uZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuUmVhZE5vdGlmaWNhdGlvbk1lc3NhZ2VKb2JzUmVzcG9uc2USmwEKHFVwZGF0ZU5vdGlmaWNhdGlvbk1lc3NhZ2VKb2ISPy5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5VcGRhdGVOb3RpZmljYXRpb25NZXNzYWdlSm9iUmVxdWVzdBo6LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLk5vdGlmaWNhdGlvbk1lc3NhZ2VKb2JSZXNwb25zZRKbAQocRGVsZXRlTm90aWZpY2F0aW9uTWVzc2FnZUpvYhI/LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLkRlbGV0ZU5vdGlmaWNhdGlvbk1lc3NhZ2VKb2JSZXF1ZXN0GjouZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuTm90aWZpY2F0aW9uTWVzc2FnZUpvYlJlc3BvbnNlEoUBChhSZWFkTm90aWZpY2F0aW9uUHJvZHVjdHMSOy5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5SZWFkTm90aWZpY2F0aW9uUHJvZHVjdHNSZXF1ZXN0GiwuZGFzaGJvYXJkLnByb2R1Y3QudjEuU2VhcmNoUHJvZHVjdHNSZXNwb25zZRKeAQobR2V0Tm90aWZpY2F0aW9uVXNlclNldHRpbmdzEj4uZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuR2V0Tm90aWZpY2F0aW9uVXNlclNldHRpbmdzUmVxdWVzdBo/LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLkdldE5vdGlmaWNhdGlvblVzZXJTZXR0aW5nc1Jlc3BvbnNlEnoKD1ZlcmlmeVVzZXJFbWFpbBIyLmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLlZlcmlmeVVzZXJFbWFpbFJlcXVlc3QaMy5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5WZXJpZnlVc2VyRW1haWxSZXNwb25zZRJ0Cg1HZXRVc2VyR3JvdXBzEjAuZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuR2V0VXNlckdyb3Vwc1JlcXVlc3QaMS5kYXNoYm9hcmQubm90aWZpY2F0aW9ucy52MS5HZXRVc2VyR3JvdXBzUmVzcG9uc2USXwoQVXBkYXRlVXNlckdyb3VwcxIzLmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLlVwZGF0ZVVzZXJHcm91cHNSZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5EpsBChpHZXRQcm9qZWN0ZWRSZWNpcGllbnRDb3VudBI9LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLkdldFByb2plY3RlZFJlY2lwaWVudENvdW50UmVxdWVzdBo+LmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLkdldFByb2plY3RlZFJlY2lwaWVudENvdW50UmVzcG9uc2USiQEKFEdldE5vdGlmaWNhdGlvblN0YXRzEjcuZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuR2V0Tm90aWZpY2F0aW9uU3RhdHNSZXF1ZXN0GjguZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuR2V0Tm90aWZpY2F0aW9uU3RhdHNSZXNwb25zZRKqAQofUHJldmlld05vdGlmaWNhdGlvbk1lc3NhZ2VFbWFpbBJCLmRhc2hib2FyZC5ub3RpZmljYXRpb25zLnYxLlByZXZpZXdOb3RpZmljYXRpb25NZXNzYWdlRW1haWxSZXF1ZXN0GkMuZGFzaGJvYXJkLm5vdGlmaWNhdGlvbnMudjEuUHJldmlld05vdGlmaWNhdGlvbk1lc3NhZ2VFbWFpbFJlc3BvbnNlYgZwcm90bzM",[K,Q,h,A]);var T=(e=>(e[e.UNKNOWN=0]="UNKNOWN",e[e.PROJECT_NOT_FOUND=1]="PROJECT_NOT_FOUND",e[e.NOTIFICATION_SETTING_NOT_FOUND=2]="NOTIFICATION_SETTING_NOT_FOUND",e[e.CREATE_NOTIFICATION_SETTING_FAILED=3]="CREATE_NOTIFICATION_SETTING_FAILED",e[e.UPDATE_NOTIFICATION_SETTING_FAILED=4]="UPDATE_NOTIFICATION_SETTING_FAILED",e[e.DELETE_NOTIFICATION_SETTING_FAILED=5]="DELETE_NOTIFICATION_SETTING_FAILED",e[e.NOTIFICATION_GROUP_NOT_FOUND=6]="NOTIFICATION_GROUP_NOT_FOUND",e[e.NOTIFICATION_GROUPS_NOT_FOUND=7]="NOTIFICATION_GROUPS_NOT_FOUND",e[e.CREATE_NOTIFICATION_GROUP_FAILED=8]="CREATE_NOTIFICATION_GROUP_FAILED",e[e.UPDATE_NOTIFICATION_GROUP_FAILED=9]="UPDATE_NOTIFICATION_GROUP_FAILED",e[e.DELETE_NOTIFICATION_GROUP_FAILED=10]="DELETE_NOTIFICATION_GROUP_FAILED",e[e.NOTIFICATION_USER_NOT_FOUND=11]="NOTIFICATION_USER_NOT_FOUND",e[e.NOTIFICATION_USERS_NOT_FOUND=12]="NOTIFICATION_USERS_NOT_FOUND",e[e.CREATE_NOTIFICATION_USER_FAILED=13]="CREATE_NOTIFICATION_USER_FAILED",e[e.UPDATE_NOTIFICATION_USER_FAILED=14]="UPDATE_NOTIFICATION_USER_FAILED",e[e.DELETE_NOTIFICATION_USER_FAILED=15]="DELETE_NOTIFICATION_USER_FAILED",e[e.NOTIFICATION_GROUP_USER_NOT_FOUND=16]="NOTIFICATION_GROUP_USER_NOT_FOUND",e[e.CREATE_NOTIFICATION_GROUP_USER_FAILED=17]="CREATE_NOTIFICATION_GROUP_USER_FAILED",e[e.UPDATE_NOTIFICATION_GROUP_USER_FAILED=18]="UPDATE_NOTIFICATION_GROUP_USER_FAILED",e[e.DELETE_NOTIFICATION_GROUP_USER_FAILED=19]="DELETE_NOTIFICATION_GROUP_USER_FAILED",e[e.NOTIFICATION_MESSAGE_NOT_FOUND=20]="NOTIFICATION_MESSAGE_NOT_FOUND",e[e.NOTIFICATION_MESSAGES_NOT_FOUND=21]="NOTIFICATION_MESSAGES_NOT_FOUND",e[e.CREATE_NOTIFICATION_MESSAGE_FAILED=22]="CREATE_NOTIFICATION_MESSAGE_FAILED",e[e.UPDATE_NOTIFICATION_MESSAGE_FAILED=23]="UPDATE_NOTIFICATION_MESSAGE_FAILED",e[e.DELETE_NOTIFICATION_MESSAGE_FAILED=24]="DELETE_NOTIFICATION_MESSAGE_FAILED",e[e.NOTIFICATION_MESSAGE_JOB_NOT_FOUND=25]="NOTIFICATION_MESSAGE_JOB_NOT_FOUND",e[e.NOTIFICATION_MESSAGE_JOBS_NOT_FOUND=26]="NOTIFICATION_MESSAGE_JOBS_NOT_FOUND",e[e.CREATE_NOTIFICATION_MESSAGE_JOB_FAILED=27]="CREATE_NOTIFICATION_MESSAGE_JOB_FAILED",e[e.UPDATE_NOTIFICATION_MESSAGE_JOB_FAILED=28]="UPDATE_NOTIFICATION_MESSAGE_JOB_FAILED",e[e.DELETE_NOTIFICATION_MESSAGE_JOB_FAILED=29]="DELETE_NOTIFICATION_MESSAGE_JOB_FAILED",e[e.NOTIFICATION_SETTING_ALREADY_EXIST=30]="NOTIFICATION_SETTING_ALREADY_EXIST",e[e.NOTIFICATION_SETTING_SLUG_ALREADY_TAKEN=31]="NOTIFICATION_SETTING_SLUG_ALREADY_TAKEN",e[e.NOTIFICATION_USER_ALREADY_EXIST=32]="NOTIFICATION_USER_ALREADY_EXIST",e[e.NOTIFICATION_GROUP_ALREADY_EXIST=33]="NOTIFICATION_GROUP_ALREADY_EXIST",e[e.NOTIFICATION_MESSAGE_NOT_CANCELLABLE=34]="NOTIFICATION_MESSAGE_NOT_CANCELLABLE",e[e.CANCEL_NOTIFICATION_MESSAGE_FAILED=35]="CANCEL_NOTIFICATION_MESSAGE_FAILED",e[e.RETRY_NOTIFICATION_MESSAGE_FAILED=36]="RETRY_NOTIFICATION_MESSAGE_FAILED",e[e.DUPLICATE_NOTIFICATION_MESSAGE_FAILED=37]="DUPLICATE_NOTIFICATION_MESSAGE_FAILED",e[e.NOTIFICATION_MESSAGE_NOT_EDITABLE=38]="NOTIFICATION_MESSAGE_NOT_EDITABLE",e[e.EMAIL_QUOTA_EXCEEDED=39]="EMAIL_QUOTA_EXCEEDED",e[e.EMAIL_PREVIEW_FAILED=40]="EMAIL_PREVIEW_FAILED",e[e.EMAIL_BODY_TOO_LONG=41]="EMAIL_BODY_TOO_LONG",e))(T||{});var s=k(z,0);var P=s.method.createNotificationSetting,H=s.method.readNotificationSetting,j=s.method.updateNotificationSetting,L=s.method.deleteNotificationSetting,q=s.method.createNotificationGroup,w=s.method.readNotificationGroups,O=s.method.updateNotificationGroup,D=s.method.deleteNotificationGroup,_=s.method.createNotificationUser,$=s.method.readNotificationUsers,ee=s.method.updateNotificationUser,te=s.method.deleteNotificationUser,se=s.method.createNotificationGroupUser,oe=s.method.readNotificationGroupUsers,ne=s.method.updateNotificationGroupUser,ae=s.method.deleteNotificationGroupUser,ie=s.method.createNotificationMessage,ce=s.method.readNotificationMessages,de=s.method.getSentNotificationMessages,ue=s.method.updateNotificationMessage,re=s.method.deleteNotificationMessage,le=s.method.cancelNotificationMessage,Re=s.method.retryFailedNotificationMessageJobs,pe=s.method.duplicateNotificationMessage,ge=s.method.getNotificationMessageReport,me=s.method.createNotificationMessageJob,be=s.method.readNotificationMessageJobs,Ge=s.method.updateNotificationMessageJob,Ae=s.method.deleteNotificationMessageJob,Ve=s.method.readNotificationProducts,Ze=s.method.getNotificationUserSettings,he=s.method.verifyUserEmail,Ne=s.method.getUserGroups,Se=s.method.updateUserGroups,We=s.method.getProjectedRecipientCount,fe=s.method.getNotificationStats,Ye=s.method.previewNotificationMessageEmail;var p={};l(p,{addPublicOrderComment:()=>gt,applePayValidateMerchant:()=>rt,authorizeOneClickPayment:()=>lt,clearAppStoreAccountToken:()=>_e,didBuyProduct:()=>Le,getAppStoreAccountToken:()=>qe,getAppStoreEntitlements:()=>Oe,getAvailableCountForProduct:()=>at,getGuestCatalog:()=>Pe,getLoginBranding:()=>ct,getNotificationHistory:()=>nt,getNotificationSettings:()=>et,getNotificationSettingsDetails:()=>tt,getOrder:()=>Xe,getOrderForTestimonial:()=>mt,getOrderHistory:()=>Fe,getOrderRetryUrl:()=>Ue,getOrders:()=>Ee,getPreOrderDetails:()=>ut,getPublicOrderDetails:()=>pt,getShopProducts:()=>je,getStoreKitCatalog:()=>$e,getTestimonialUploadUrl:()=>Gt,getThankYouPage:()=>it,isOneClickPaymentAvailable:()=>dt,notifyUserAboutProductAvailability:()=>Rt,pushEvent:()=>Ke,pushSendDeviceToken:()=>Qe,restoreAppStorePurchases:()=>De,shouldShopProducts:()=>ze,shouldShowGuestCatalog:()=>Te,submitTestimonial:()=>bt,updateGlobalNotificationSettings:()=>st,updateNotificationSettings:()=>ot,userPanelDeleteAccount:()=>Ie,userPanelGetAudiobookDetails:()=>Ce,userPanelGetAudiobookDetailsDownloadURLs:()=>Me,userPanelGetFileDetails:()=>xe,userPanelGetProducts:()=>ve,userPanelGetTicketDetails:()=>ke,userPanelLogin:()=>ye,userPanelLoginWithCode:()=>Be,userPanelLogout:()=>Je,userPanelResolveProductAccess:()=>He,verifyAppStorePurchase:()=>we});var Xe=t.method.getOrder,Ee=t.method.getOrders,Fe=t.method.getOrderHistory,Ue=t.method.getOrderRetryUrl,ye=t.method.userPanelLogin,Be=t.method.userPanelLoginWithCode,Je=t.method.userPanelLogout,Ie=t.method.userPanelDeleteAccount,ve=t.method.userPanelGetProducts,Ce=t.method.userPanelGetAudiobookDetails,Me=t.method.userPanelGetAudiobookDetailsDownloadURLs,xe=t.method.userPanelGetFileDetails,ke=t.method.userPanelGetTicketDetails,Qe=t.method.pushSendDeviceToken,Ke=t.method.pushEvent,ze=t.method.shouldShopProducts,Te=t.method.shouldShowGuestCatalog,Pe=t.method.getGuestCatalog,He=t.method.userPanelResolveProductAccess,je=t.method.getShopProducts,Le=t.method.didBuyProduct,qe=t.method.getAppStoreAccountToken,we=t.method.verifyAppStorePurchase,Oe=t.method.getAppStoreEntitlements,De=t.method.restoreAppStorePurchases,_e=t.method.clearAppStoreAccountToken,$e=t.method.getStoreKitCatalog,et=t.method.getNotificationSettings,tt=t.method.getNotificationSettingsDetails,st=t.method.updateGlobalNotificationSettings,ot=t.method.updateNotificationSettings,nt=t.method.getNotificationHistory,at=t.method.getAvailableCountForProduct,it=t.method.getThankYouPage,ct=t.method.getLoginBranding,dt=t.method.isOneClickPaymentAvailable,ut=t.method.getPreOrderDetails,rt=t.method.applePayValidateMerchant,lt=t.method.authorizeOneClickPayment,Rt=t.method.notifyUserAboutProductAvailability,pt=t.method.getPublicOrderDetails,gt=t.method.addPublicOrderComment,mt=t.method.getOrderForTestimonial,bt=t.method.submitTestimonial,Gt=t.method.getTestimonialUploadUrl;var g={};l(g,{createReturnRequest:()=>St,exchangePanelSession:()=>Zt,getMyReturn:()=>ft,getReturnableOrder:()=>Nt,listMyReturns:()=>Wt,listReturnOrders:()=>ht,startReturnSession:()=>At,verifyReturnSession:()=>Vt});var At=i.method.startReturnSession,Vt=i.method.verifyReturnSession,Zt=i.method.exchangePanelSession,ht=i.method.listReturnOrders,Nt=i.method.getReturnableOrder,St=i.method.createReturnRequest,Wt=i.method.listMyReturns,ft=i.method.getMyReturn;import{jsx as W}from"react/jsx-runtime";var N,m;BigInt.prototype.toJSON=function(){return this.toString()};var Ys={publicApi:p,notifications:R,returns:g},Xs=Ft,Es=Et,Fs=Xt,It;function vt(){return It??V}function f(a){return Ut({baseUrl:a+"/api/rpc",useBinaryFormat:!0,interceptors:[G],fetch:async(o,n)=>fetch(o,{...n,keepalive:!1,credentials:"include"})})}var S=new Map;function Us(a){let o=S.get(a);return o==null&&(o=f(a),S.set(a,o)),o}var ys=({children:a})=>{let o=vt();(m==null||N!==o)&&(N=o,m=f(o));let[n]=Jt(()=>new yt({defaultOptions:{queries:{staleTime:5e3}}}));return W(Yt,{transport:m,children:W(Bt,{client:n,children:a})})};import{cva as Ct}from"class-variance-authority";import{Slot as Mt}from"radix-ui";import{jsx as kt}from"react/jsx-runtime";var xt=Ct("inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",{variants:{variant:{default:"bg-primary text-primary-foreground hover:bg-primary/90",destructive:"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",outline:"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",secondary:"bg-secondary text-secondary-foreground hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-9 px-4 py-2 has-[>svg]:px-3",xs:"h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",sm:"h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",lg:"h-10 rounded-md px-6 has-[>svg]:px-4",icon:"size-9","icon-xs":"size-6 rounded-md [&_svg:not([class*='size-'])]:size-3","icon-sm":"size-8","icon-lg":"size-10"}},defaultVariants:{variant:"default",size:"default"}});function Ms({className:a,variant:o="default",size:n="default",asChild:c=!1,...u}){let r=c?Mt.Root:"button";return kt(r,{"data-slot":"button","data-variant":o,"data-size":n,className:d(xt({variant:o,size:n,className:a})),...u})}import{jsx as Qt}from"react/jsx-runtime";function Ks({className:a,type:o,...n}){return Qt("input",{type:o,"data-slot":"input",className:d("file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm","focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]","aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",a),...n})}function Kt(a){let o=/^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.exec(a);if(o==null)return;let n=o[1];return n.length<=4&&(n=n.split("").map(c=>c+c).join("")),[parseInt(n.slice(0,2),16),parseInt(n.slice(2,4),16),parseInt(n.slice(4,6),16)]}function zt(a){let o=/^rgba?\(\s*(\d{1,3})[\s,]+(\d{1,3})[\s,]+(\d{1,3})(?:[\s,/]+[\d.%]+)?\s*\)$/i.exec(a);if(o==null)return;let n=[o[1],o[2],o[3]].map(Number);return n.every(c=>c<=255)?n:void 0}function Tt(a){let o=a/255;return o<=.03928?o/12.92:((o+.055)/1.055)**2.4}function Pt(a){let o=a.trim(),n=Kt(o)??zt(o);if(n==null)return;let[c,u,r]=n.map(Tt),b=.2126*c+.7152*u+.0722*r,X=1.05/(b+.05),E=(b+.05)/.05;return X>=E?"#ffffff":"#18181b"}function Ps(a){let o=Pt(a);return{buttonBackground:a,focusRing:a,...o!=null?{buttonForeground:o}:{}}}import*as Y from"react";import{jsx as jt}from"react/jsx-runtime";var Ht=Y.forwardRef(({className:a,...o},n)=>jt("textarea",{className:d("flex min-h-[60px] w-full rounded-md border border-neutral-200 bg-white px-3 py-2 text-sm ring-offset-white placeholder:text-neutral-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-950 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-neutral-800 dark:bg-neutral-950 dark:ring-offset-neutral-950 dark:placeholder:text-neutral-400 dark:focus-visible:ring-neutral-300",a),ref:n,...o}));Ht.displayName="Textarea";import{jsx as Lt}from"react/jsx-runtime";function Os({className:a,...o}){return Lt("div",{"data-slot":"skeleton",className:d("bg-accent animate-pulse rounded-md",a),...o})}export{T as a,ct as b,U as c,i as d,Ys as e,Xs as f,Es as g,Fs as h,vt as i,Us as j,ys as k,Ms as l,Ks as m,Pt as n,Ps as o,Os as p,Ht as q};
2
+ //# sourceMappingURL=chunk-GMQYQTUM.mjs.map