@zoreal/oauth2-react 0.1.11 → 0.2.6

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.
package/dist/index.cjs CHANGED
@@ -21,6 +21,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  // src/index.ts
22
22
  var index_exports = {};
23
23
  __export(index_exports, {
24
+ DEFAULT_PAIRING_TIMEOUT_MS: () => DEFAULT_PAIRING_TIMEOUT_MS,
25
+ PairingModal: () => PairingModal,
24
26
  ZorealLogin: () => ZorealLogin,
25
27
  ZorealOAuthProvider: () => ZorealOAuthProvider,
26
28
  hasGrantedAllScopesZoreal: () => hasGrantedAllScopesZoreal,
@@ -33,32 +35,758 @@ __export(index_exports, {
33
35
  module.exports = __toCommonJS(index_exports);
34
36
 
35
37
  // src/context.tsx
36
- var import_react = require("react");
38
+ var import_react2 = require("react");
37
39
 
38
40
  // src/wire.ts
39
41
  var WIRE_VERSION = 1;
40
- var SDK_VERSION = "0.1.11";
42
+ var SDK_VERSION = "0.2.6";
41
43
  var DEFAULT_ISSUER = "https://id.zoreal.com";
42
44
  var POLL_INTERVAL_MS = 2e3;
43
45
  var POLL_INTERVAL_ENROLLING_MS = 5e3;
44
46
 
45
- // src/context.tsx
47
+ // src/PairingModal.tsx
48
+ var import_react = require("react");
49
+ var import_react_dom = require("react-dom");
50
+
51
+ // src/mark.tsx
46
52
  var import_jsx_runtime = require("react/jsx-runtime");
47
- var ZorealOAuthContext = (0, import_react.createContext)(null);
53
+ var ZOREAL_BLUE = "#00b4d9";
54
+ function ZorealMark({
55
+ size = 18,
56
+ brand = false,
57
+ className
58
+ }) {
59
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
60
+ "svg",
61
+ {
62
+ width: size,
63
+ height: size,
64
+ viewBox: "8.4 7.4 62.2 62.2",
65
+ fill: brand ? ZOREAL_BLUE : "currentColor",
66
+ fillRule: "evenodd",
67
+ "aria-hidden": true,
68
+ focusable: "false",
69
+ className,
70
+ children: [
71
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M56.1,32.9c.6-3.1-.8-6.4-3.7-8.1l-18-10.4,5.2-3,15.4,8.9c5.4,3.1,7.7,9.6,5.8,15.3-.3.8-.6,1.6-1.1,2.4-.4.7-.9,1.4-1.5,2.1-1.3,1.4-2.9,2.6-4.6,3.3-3.6,1.5-7.9,1.4-11.6-.7l-8.9-5.1c-2.9-1.7-6.5-1.3-8.9.8-.6.6-1.2,1.2-1.7,2-.5.8-.8,1.7-.9,2.5-.6,3.1.9,6.4,3.7,8.1l18,10.4-5.2,3-15.4-8.9c-5.4-3.1-7.7-9.6-5.8-15.3.2-.8.6-1.6,1-2.4.5-.7,1-1.4,1.5-2.1,1.3-1.4,2.9-2.6,4.7-3.3,3.6-1.6,7.8-1.4,11.5.6l8.9,5.2c3,1.7,6.6,1.3,8.9-.8.6-.6,1.2-1.2,1.7-2,.4-.8.7-1.7.9-2.5Z" }),
72
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M68.7,44.2c-.7,1.2-2.3,1.7-3.5.9-1.3-.7-1.7-2.3-1-3.5.7-1.3,2.3-1.7,3.5-1,1.3.7,1.7,2.3,1,3.6Z" }),
73
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M25.6,21.3c5.1-.8,10.4,0,15.3,2.9l1.2.7h0c1.2.7,1.6,2.3.9,3.5s-2.3,1.7-3.5.9l-1.2-.7c-4.2-2.4-9.1-3-13.5-1.9-1.6.4-3.1,1.1-4.5,1.9h0c-1.2.7-2.8.3-3.5-1-.7-1.2-.3-2.8.9-3.5,0,0,.1,0,.3-.1.3-.1.6-.4,1-.5,2.1-1.1,4.4-1.7,6.7-2.2Z" }),
74
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M9.6,31.8c.7-1.2,2.4-1.6,3.5-.8,1.2.7,1.6,2.4.8,3.5-.8,1.2-2.4,1.6-3.6.8-1.2-.8-1.5-2.4-.7-3.5Z" }),
75
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M46.2,30.3c.7-1.3,2.3-1.7,3.5-1,1.2.7,1.7,2.3.9,3.6-.7,1.2-2.3,1.7-3.5.9s-1.7-2.3-.9-3.5Z" }),
76
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M52.1,54.5c-5,.9-10.4,0-15.3-2.8l-1.2-.7h0c-1.2-.7-1.7-2.3-.9-3.5s2.3-1.7,3.5-.9l1.2.7c4.3,2.4,9.1,3,13.6,1.9,1.6-.4,3.1-1.1,4.5-1.9h0c1.2-.7,2.8-.3,3.5.9.7,1.3.3,2.9-.9,3.6-.1,0-.2,0-.3,0-.4.2-.7.4-1.1.6-2.1,1-4.3,1.7-6.7,2.1Z" }),
77
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M31.4,45.6c-.7,1.2-2.3,1.7-3.5.9s-1.7-2.3-.9-3.5,2.3-1.7,3.5-.9,1.7,2.3.9,3.5Z" })
78
+ ]
79
+ }
80
+ );
81
+ }
82
+
83
+ // src/lockup.tsx
84
+ var import_jsx_runtime2 = require("react/jsx-runtime");
85
+ function ZorealLockup({ height = 22, className }) {
86
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
87
+ "svg",
88
+ {
89
+ height,
90
+ width: height * (240 / 58.5),
91
+ viewBox: "0 0 240 58.5",
92
+ role: "img",
93
+ "aria-label": "ZOREAL",
94
+ focusable: "false",
95
+ className,
96
+ children: [
97
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
98
+ "path",
99
+ {
100
+ fill: "currentColor",
101
+ d: "M205,40.5h15.3v-3.5h-11.5v-18.4h-3.8v21.8ZM157,22.2v5.6h10.9v3.5h-10.9v5.8h12.5v3.5h-16.3v-21.8h16.2v3.5h-12.4ZM141.4,25.8c0,1.1-.4,2-1.2,2.7-.8.7-1.9,1-3.3,1h-5.6v-7.3h5.6c1.4,0,2.6.3,3.4.9.8.6,1.2,1.5,1.2,2.7ZM146,40.5l-5.9-8.3c.8-.2,1.4-.5,2.1-.9s1.2-.9,1.7-1.4c.4-.5.8-1.2,1.1-1.9s.4-1.5.4-2.4-.1-2-.5-2.9c-.4-.9-.9-1.6-1.7-2.2-.6-.6-1.5-1-2.5-1.4-1-.3-2.2-.4-3.4-.4h-9.8v21.8h3.8v-7.6h4.8l5.4,7.6h4.5ZM115.7,29.7c0,1.1-.1,2.1-.5,3s-.9,1.7-1.5,2.4-1.4,1.2-2.4,1.7c-.9.4-1.9.6-3,.6s-2.1-.1-3-.6-1.7-1-2.4-1.7-1.2-1.5-1.5-2.4-.5-1.9-.5-3,.1-2.1.5-3,.9-1.7,1.5-2.4,1.4-1.2,2.4-1.7c.9-.4,1.9-.6,3-.6s2.1.2,3,.6c.9.4,1.7,1,2.3,1.7.6.6,1.2,1.5,1.6,2.4s.5,1.9.5,3ZM119.7,29.6c0-1.5-.3-3-.8-4.4-.6-1.4-1.4-2.5-2.4-3.6-1-1-2.2-1.8-3.6-2.4-1.4-.6-3-.9-4.6-.9s-3.2.4-4.6.9c-1.4.6-2.7,1.4-3.7,2.4s-1.8,2.2-2.4,3.6c-.5,1.4-.8,2.8-.8,4.4s.3,3,.8,4.4c.6,1.4,1.4,2.5,2.4,3.6,1,1,2.2,1.8,3.6,2.4,1.4.6,3,.9,4.6.9s3.2-.4,4.6-.9c1.4-.6,2.6-1.4,3.7-2.4,1-1,1.8-2.2,2.4-3.6.5-1.4.8-2.9.8-4.4ZM86.1,22.1l-13,15.6v2.8h17.9v-3.4h-12.9l12.9-15.6v-2.8h-17.5v3.4h12.5ZM188.5,18.5h-3.5l-9.6,22h4c3.7-8.8,3.4-8,7.4-17.4,3.7,8.8,3.9,9.1,7.4,17.4h4l-9.6-22Z"
102
+ }
103
+ ),
104
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("g", { fill: ZOREAL_BLUE, fillRule: "evenodd", children: [
105
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M52,25.7c.4-2-.5-4.2-2.5-5.4l-11.8-6.8,3.4-2,10.1,5.9c3.6,2,5.1,6.3,3.8,10.1-.2.5-.4,1-.7,1.6-.3.5-.6.9-1,1.4-.9.9-1.9,1.7-3,2.2-2.4,1-5.2.9-7.6-.5l-5.9-3.4c-1.9-1.1-4.3-.9-5.9.5-.4.4-.8.8-1.1,1.3-.3.5-.5,1.1-.6,1.7-.4,2,.6,4.2,2.5,5.4l11.8,6.8-3.4,2-10.1-5.9c-3.6-2-5.1-6.3-3.8-10.1.1-.5.4-1,.7-1.6.3-.5.7-.9,1-1.4.9-.9,1.9-1.7,3.1-2.2,2.4-1,5.2-.9,7.6.4l5.9,3.4c1.9,1.1,4.3.9,5.9-.5.4-.4.8-.8,1.1-1.3.3-.5.5-1.1.6-1.7Z" }),
106
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M60.3,33.1c-.5.8-1.5,1.1-2.3.6-.9-.5-1.1-1.5-.7-2.3.5-.9,1.5-1.1,2.3-.7.9.5,1.1,1.5.7,2.4Z" }),
107
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M31.9,18c3.4-.5,6.9,0,10,1.9l.8.5h0c.8.5,1,1.5.6,2.3s-1.5,1.1-2.3.6l-.8-.5c-2.8-1.6-6-1.9-8.9-1.2-1,.3-2,.7-3,1.2h0c-.8.5-1.8.2-2.3-.7-.5-.8-.2-1.8.6-2.3,0,0,0,0,.2,0,.2,0,.4-.2.7-.3,1.4-.7,2.9-1.1,4.4-1.4Z" }),
108
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21.4,24.9c.5-.8,1.6-1,2.3-.5.8.5,1,1.6.5,2.3-.5.8-1.6,1-2.4.5-.8-.5-1-1.6-.5-2.3Z" }),
109
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M45.5,23.9c.5-.9,1.5-1.1,2.3-.7.8.5,1.1,1.5.6,2.4-.5.8-1.5,1.1-2.3.6s-1.1-1.5-.6-2.3Z" }),
110
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M49.4,39.9c-3.3.6-6.9,0-10-1.8l-.8-.5h0c-.8-.5-1.1-1.5-.6-2.3s1.5-1.1,2.3-.6l.8.5c2.8,1.6,6,1.9,9,1.2,1-.3,2-.7,3-1.2h0c.8-.5,1.8-.2,2.3.6.5.9.2,1.9-.6,2.4,0,0-.1,0-.2,0-.2.1-.5.3-.7.4-1.4.7-2.8,1.1-4.4,1.4Z" }),
111
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M35.8,34c-.5.8-1.5,1.1-2.3.6s-1.1-1.5-.6-2.3,1.5-1.1,2.3-.6,1.1,1.5.6,2.3Z" })
112
+ ] })
113
+ ]
114
+ }
115
+ );
116
+ }
117
+
118
+ // src/i18n.ts
119
+ var en = {
120
+ title: "Scan to sign in",
121
+ titleApprove: "Approve on your phone",
122
+ bodyScan: "Scan with your phone camera or the ZOREAL ID app.",
123
+ bodyApprove: "Approve the login in your ZOREAL ID app.",
124
+ bodyEnrolling: "Finish setting up ZOREAL ID on your phone, then approve the login.",
125
+ waiting: "Waiting for scan",
126
+ waitingApproval: "Waiting for approval",
127
+ expiresIn: "Expires in {time}",
128
+ secured: "Proof-of-Human verification by ZOREAL",
129
+ noIdTitle: "No ZOREAL ID yet?",
130
+ noIdBody: "Scan the same code to download the app and create one for free. It only takes a minute.",
131
+ cancel: "Cancel",
132
+ close: "Close",
133
+ qrAlt: "QR code to sign in with ZOREAL"
134
+ };
135
+ var TRANSLATIONS = {
136
+ en,
137
+ sv: {
138
+ title: "Skanna f\xF6r att logga in",
139
+ titleApprove: "Godk\xE4nn p\xE5 telefonen",
140
+ bodyScan: "Skanna med telefonens kamera eller ZOREAL ID-appen.",
141
+ bodyApprove: "Godk\xE4nn inloggningen i ZOREAL ID-appen.",
142
+ bodyEnrolling: "Slutf\xF6r konfigurationen av ZOREAL ID p\xE5 telefonen och godk\xE4nn sedan inloggningen.",
143
+ waiting: "V\xE4ntar p\xE5 skanning",
144
+ waitingApproval: "V\xE4ntar p\xE5 godk\xE4nnande",
145
+ expiresIn: "Upph\xF6r om {time}",
146
+ secured: "Proof-of-Human-verifiering av ZOREAL",
147
+ noIdTitle: "Har du inget ZOREAL ID?",
148
+ noIdBody: "Skanna samma kod f\xF6r att ladda ner appen och skapa ett gratis. Det tar bara en minut.",
149
+ cancel: "Avbryt",
150
+ close: "St\xE4ng",
151
+ qrAlt: "QR-kod f\xF6r att logga in med ZOREAL"
152
+ },
153
+ es: {
154
+ title: "Escanea para iniciar sesi\xF3n",
155
+ titleApprove: "Apru\xE9balo en tu tel\xE9fono",
156
+ bodyScan: "Escanea con la c\xE1mara de tu tel\xE9fono o con la app ZOREAL ID.",
157
+ bodyApprove: "Aprueba el inicio de sesi\xF3n en tu app ZOREAL ID.",
158
+ bodyEnrolling: "Termina de configurar ZOREAL ID en tu tel\xE9fono y luego aprueba el inicio de sesi\xF3n.",
159
+ waiting: "Esperando el escaneo",
160
+ waitingApproval: "Esperando aprobaci\xF3n",
161
+ expiresIn: "Caduca en {time}",
162
+ secured: "Verificaci\xF3n Proof-of-Human de ZOREAL",
163
+ noIdTitle: "\xBFA\xFAn no tienes ZOREAL ID?",
164
+ noIdBody: "Escanea el mismo c\xF3digo para descargar la app y crear una gratis. Solo toma un minuto.",
165
+ cancel: "Cancelar",
166
+ close: "Cerrar",
167
+ qrAlt: "C\xF3digo QR para iniciar sesi\xF3n con ZOREAL"
168
+ },
169
+ pt: {
170
+ title: "Digitalize para entrar",
171
+ titleApprove: "Aprove no seu telefone",
172
+ bodyScan: "Digitalize com a c\xE2mera do seu telefone ou com o app ZOREAL ID.",
173
+ bodyApprove: "Aprove o login no app ZOREAL ID.",
174
+ bodyEnrolling: "Termine de configurar o ZOREAL ID no seu telefone e depois aprove o login.",
175
+ waiting: "Aguardando digitaliza\xE7\xE3o",
176
+ waitingApproval: "Aguardando aprova\xE7\xE3o",
177
+ expiresIn: "Expira em {time}",
178
+ secured: "Verifica\xE7\xE3o Proof-of-Human da ZOREAL",
179
+ noIdTitle: "Ainda n\xE3o tem ZOREAL ID?",
180
+ noIdBody: "Digitalize o mesmo c\xF3digo para baixar o app e criar uma conta gr\xE1tis. Leva s\xF3 um minuto.",
181
+ cancel: "Cancelar",
182
+ close: "Fechar",
183
+ qrAlt: "C\xF3digo QR para entrar com ZOREAL"
184
+ },
185
+ fr: {
186
+ title: "Scannez pour vous connecter",
187
+ titleApprove: "Approuvez sur votre t\xE9l\xE9phone",
188
+ bodyScan: "Scannez avec l'appareil photo de votre t\xE9l\xE9phone ou l'app ZOREAL ID.",
189
+ bodyApprove: "Approuvez la connexion dans votre app ZOREAL ID.",
190
+ bodyEnrolling: "Terminez la configuration de ZOREAL ID sur votre t\xE9l\xE9phone, puis approuvez la connexion.",
191
+ waiting: "En attente du scan",
192
+ waitingApproval: "En attente d'approbation",
193
+ expiresIn: "Expire dans {time}",
194
+ secured: "V\xE9rification Proof-of-Human par ZOREAL",
195
+ noIdTitle: "Pas encore de ZOREAL ID ?",
196
+ noIdBody: "Scannez le m\xEAme code pour t\xE9l\xE9charger l'app et en cr\xE9er un gratuitement. Cela prend une minute.",
197
+ cancel: "Annuler",
198
+ close: "Fermer",
199
+ qrAlt: "Code QR pour se connecter avec ZOREAL"
200
+ },
201
+ de: {
202
+ title: "Zum Anmelden scannen",
203
+ titleApprove: "Auf dem Handy best\xE4tigen",
204
+ bodyScan: "Mit der Handykamera oder der ZOREAL ID App scannen.",
205
+ bodyApprove: "Anmeldung in der ZOREAL ID App best\xE4tigen.",
206
+ bodyEnrolling: "ZOREAL ID auf dem Handy fertig einrichten und dann die Anmeldung best\xE4tigen.",
207
+ waiting: "Warten auf Scan",
208
+ waitingApproval: "Warten auf Best\xE4tigung",
209
+ expiresIn: "L\xE4uft ab in {time}",
210
+ secured: "Proof-of-Human-Verifizierung von ZOREAL",
211
+ noIdTitle: "Noch keine ZOREAL ID?",
212
+ noIdBody: "Denselben Code scannen, um die App zu laden und kostenlos eine zu erstellen. Dauert nur eine Minute.",
213
+ cancel: "Abbrechen",
214
+ close: "Schlie\xDFen",
215
+ qrAlt: "QR-Code f\xFCr die Anmeldung mit ZOREAL"
216
+ },
217
+ ru: {
218
+ title: "\u041E\u0442\u0441\u043A\u0430\u043D\u0438\u0440\u0443\u0439\u0442\u0435, \u0447\u0442\u043E\u0431\u044B \u0432\u043E\u0439\u0442\u0438",
219
+ titleApprove: "\u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u043D\u0430 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0435",
220
+ bodyScan: "\u041E\u0442\u0441\u043A\u0430\u043D\u0438\u0440\u0443\u0439\u0442\u0435 \u043A\u0430\u043C\u0435\u0440\u043E\u0439 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0430 \u0438\u043B\u0438 \u0447\u0435\u0440\u0435\u0437 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 ZOREAL ID.",
221
+ bodyApprove: "\u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u0432\u0445\u043E\u0434 \u0432 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0438 ZOREAL ID.",
222
+ bodyEnrolling: "\u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0435 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0443 ZOREAL ID \u043D\u0430 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0435, \u0437\u0430\u0442\u0435\u043C \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u0432\u0445\u043E\u0434.",
223
+ waiting: "\u041E\u0436\u0438\u0434\u0430\u043D\u0438\u0435 \u0441\u043A\u0430\u043D\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F",
224
+ waitingApproval: "\u041E\u0436\u0438\u0434\u0430\u043D\u0438\u0435 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F",
225
+ expiresIn: "\u0418\u0441\u0442\u0435\u043A\u0430\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 {time}",
226
+ secured: "\u041F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 Proof-of-Human \u043E\u0442 ZOREAL",
227
+ noIdTitle: "\u0415\u0449\u0451 \u043D\u0435\u0442 ZOREAL ID?",
228
+ noIdBody: "\u041E\u0442\u0441\u043A\u0430\u043D\u0438\u0440\u0443\u0439\u0442\u0435 \u0442\u043E\u0442 \u0436\u0435 \u043A\u043E\u0434, \u0447\u0442\u043E\u0431\u044B \u0441\u043A\u0430\u0447\u0430\u0442\u044C \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u0438 \u0441\u043E\u0437\u0434\u0430\u0442\u044C \u0435\u0433\u043E \u0431\u0435\u0441\u043F\u043B\u0430\u0442\u043D\u043E. \u042D\u0442\u043E \u0437\u0430\u0439\u043C\u0451\u0442 \u043C\u0438\u043D\u0443\u0442\u0443.",
229
+ cancel: "\u041E\u0442\u043C\u0435\u043D\u0430",
230
+ close: "\u0417\u0430\u043A\u0440\u044B\u0442\u044C",
231
+ qrAlt: "QR-\u043A\u043E\u0434 \u0434\u043B\u044F \u0432\u0445\u043E\u0434\u0430 \u0447\u0435\u0440\u0435\u0437 ZOREAL"
232
+ },
233
+ ja: {
234
+ title: "\u30B9\u30AD\u30E3\u30F3\u3057\u3066\u30ED\u30B0\u30A4\u30F3",
235
+ titleApprove: "\u30B9\u30DE\u30FC\u30C8\u30D5\u30A9\u30F3\u3067\u627F\u8A8D",
236
+ bodyScan: "\u30B9\u30DE\u30FC\u30C8\u30D5\u30A9\u30F3\u306E\u30AB\u30E1\u30E9\u307E\u305F\u306FZOREAL ID\u30A2\u30D7\u30EA\u3067\u30B9\u30AD\u30E3\u30F3\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
237
+ bodyApprove: "ZOREAL ID\u30A2\u30D7\u30EA\u3067\u30ED\u30B0\u30A4\u30F3\u3092\u627F\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
238
+ bodyEnrolling: "\u30B9\u30DE\u30FC\u30C8\u30D5\u30A9\u30F3\u3067ZOREAL ID\u306E\u8A2D\u5B9A\u3092\u5B8C\u4E86\u3057\u3001\u30ED\u30B0\u30A4\u30F3\u3092\u627F\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
239
+ waiting: "\u30B9\u30AD\u30E3\u30F3\u5F85\u3061",
240
+ waitingApproval: "\u627F\u8A8D\u5F85\u3061",
241
+ expiresIn: "\u6709\u52B9\u671F\u9650\u307E\u3067 {time}",
242
+ secured: "ZOREAL\u306B\u3088\u308BProof-of-Human\u8A8D\u8A3C",
243
+ noIdTitle: "ZOREAL ID\u3092\u304A\u6301\u3061\u3067\u306A\u3044\u3067\u3059\u304B\uFF1F",
244
+ noIdBody: "\u540C\u3058\u30B3\u30FC\u30C9\u3092\u30B9\u30AD\u30E3\u30F3\u3057\u3066\u30A2\u30D7\u30EA\u3092\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\u3057\u3001\u7121\u6599\u3067\u4F5C\u6210\u3067\u304D\u307E\u3059\u30021\u5206\u307B\u3069\u3067\u5B8C\u4E86\u3057\u307E\u3059\u3002",
245
+ cancel: "\u30AD\u30E3\u30F3\u30BB\u30EB",
246
+ close: "\u9589\u3058\u308B",
247
+ qrAlt: "ZOREAL\u3067\u30ED\u30B0\u30A4\u30F3\u3059\u308B\u305F\u3081\u306EQR\u30B3\u30FC\u30C9"
248
+ },
249
+ hi: {
250
+ title: "\u0938\u093E\u0907\u0928 \u0907\u0928 \u0915\u0930\u0928\u0947 \u0915\u0947 \u0932\u093F\u090F \u0938\u094D\u0915\u0948\u0928 \u0915\u0930\u0947\u0902",
251
+ titleApprove: "\u0905\u092A\u0928\u0947 \u092B\u094B\u0928 \u092A\u0930 \u0938\u094D\u0935\u0940\u0915\u0943\u0924 \u0915\u0930\u0947\u0902",
252
+ bodyScan: "\u0905\u092A\u0928\u0947 \u092B\u094B\u0928 \u0915\u0947 \u0915\u0948\u092E\u0930\u0947 \u092F\u093E ZOREAL ID \u0910\u092A \u0938\u0947 \u0938\u094D\u0915\u0948\u0928 \u0915\u0930\u0947\u0902\u0964",
253
+ bodyApprove: "\u0905\u092A\u0928\u0947 ZOREAL ID \u0910\u092A \u092E\u0947\u0902 \u0932\u0949\u0917\u093F\u0928 \u0938\u094D\u0935\u0940\u0915\u0943\u0924 \u0915\u0930\u0947\u0902\u0964",
254
+ bodyEnrolling: "\u0905\u092A\u0928\u0947 \u092B\u094B\u0928 \u092A\u0930 ZOREAL ID \u0938\u0947\u091F\u0905\u092A \u092A\u0942\u0930\u093E \u0915\u0930\u0947\u0902, \u092B\u093F\u0930 \u0932\u0949\u0917\u093F\u0928 \u0938\u094D\u0935\u0940\u0915\u0943\u0924 \u0915\u0930\u0947\u0902\u0964",
255
+ waiting: "\u0938\u094D\u0915\u0948\u0928 \u0915\u0940 \u092A\u094D\u0930\u0924\u0940\u0915\u094D\u0937\u093E \u0939\u0948",
256
+ waitingApproval: "\u0938\u094D\u0935\u0940\u0915\u0943\u0924\u093F \u0915\u0940 \u092A\u094D\u0930\u0924\u0940\u0915\u094D\u0937\u093E \u0939\u0948",
257
+ expiresIn: "{time} \u092E\u0947\u0902 \u0938\u092E\u093E\u092A\u094D\u0924",
258
+ secured: "ZOREAL \u0926\u094D\u0935\u093E\u0930\u093E Proof-of-Human \u0938\u0924\u094D\u092F\u093E\u092A\u0928",
259
+ noIdTitle: "\u0905\u092D\u0940 \u0924\u0915 ZOREAL ID \u0928\u0939\u0940\u0902 \u0939\u0948?",
260
+ noIdBody: "\u0910\u092A \u0921\u093E\u0909\u0928\u0932\u094B\u0921 \u0915\u0930\u0928\u0947 \u0914\u0930 \u092E\u0941\u092B\u094D\u0924 \u092E\u0947\u0902 \u090F\u0915 \u092C\u0928\u093E\u0928\u0947 \u0915\u0947 \u0932\u093F\u090F \u0935\u0939\u0940 \u0915\u094B\u0921 \u0938\u094D\u0915\u0948\u0928 \u0915\u0930\u0947\u0902\u0964 \u0907\u0938\u092E\u0947\u0902 \u092C\u0938 \u090F\u0915 \u092E\u093F\u0928\u091F \u0932\u0917\u0924\u093E \u0939\u0948\u0964",
261
+ cancel: "\u0930\u0926\u094D\u0926 \u0915\u0930\u0947\u0902",
262
+ close: "\u092C\u0902\u0926 \u0915\u0930\u0947\u0902",
263
+ qrAlt: "ZOREAL \u0938\u0947 \u0938\u093E\u0907\u0928 \u0907\u0928 \u0915\u0930\u0928\u0947 \u0915\u0947 \u0932\u093F\u090F QR \u0915\u094B\u0921"
264
+ },
265
+ zhs: {
266
+ title: "\u626B\u7801\u767B\u5F55",
267
+ titleApprove: "\u5728\u624B\u673A\u4E0A\u6279\u51C6",
268
+ bodyScan: "\u4F7F\u7528\u624B\u673A\u76F8\u673A\u6216 ZOREAL ID \u5E94\u7528\u626B\u63CF\u3002",
269
+ bodyApprove: "\u8BF7\u5728 ZOREAL ID \u5E94\u7528\u4E2D\u6279\u51C6\u767B\u5F55\u3002",
270
+ bodyEnrolling: "\u8BF7\u5728\u624B\u673A\u4E0A\u5B8C\u6210 ZOREAL ID \u8BBE\u7F6E\uFF0C\u7136\u540E\u6279\u51C6\u767B\u5F55\u3002",
271
+ waiting: "\u7B49\u5F85\u626B\u63CF",
272
+ waitingApproval: "\u7B49\u5F85\u6279\u51C6",
273
+ expiresIn: "{time} \u540E\u5931\u6548",
274
+ secured: "\u7531 ZOREAL \u63D0\u4F9B\u7684 Proof-of-Human \u9A8C\u8BC1",
275
+ noIdTitle: "\u8FD8\u6CA1\u6709 ZOREAL ID\uFF1F",
276
+ noIdBody: "\u626B\u63CF\u540C\u4E00\u4E2A\u4E8C\u7EF4\u7801\u5373\u53EF\u4E0B\u8F7D\u5E94\u7528\u5E76\u514D\u8D39\u521B\u5EFA\uFF0C\u53EA\u9700\u4E00\u5206\u949F\u3002",
277
+ cancel: "\u53D6\u6D88",
278
+ close: "\u5173\u95ED",
279
+ qrAlt: "\u4F7F\u7528 ZOREAL \u767B\u5F55\u7684\u4E8C\u7EF4\u7801"
280
+ },
281
+ zht: {
282
+ title: "\u6383\u78BC\u767B\u5165",
283
+ titleApprove: "\u5728\u624B\u6A5F\u4E0A\u6838\u51C6",
284
+ bodyScan: "\u4F7F\u7528\u624B\u6A5F\u76F8\u6A5F\u6216 ZOREAL ID \u61C9\u7528\u7A0B\u5F0F\u6383\u63CF\u3002",
285
+ bodyApprove: "\u8ACB\u5728 ZOREAL ID \u61C9\u7528\u7A0B\u5F0F\u4E2D\u6838\u51C6\u767B\u5165\u3002",
286
+ bodyEnrolling: "\u8ACB\u5728\u624B\u6A5F\u4E0A\u5B8C\u6210 ZOREAL ID \u8A2D\u5B9A\uFF0C\u7136\u5F8C\u6838\u51C6\u767B\u5165\u3002",
287
+ waiting: "\u7B49\u5F85\u6383\u63CF",
288
+ waitingApproval: "\u7B49\u5F85\u6838\u51C6",
289
+ expiresIn: "{time} \u5F8C\u5931\u6548",
290
+ secured: "\u7531 ZOREAL \u63D0\u4F9B\u7684 Proof-of-Human \u9A57\u8B49",
291
+ noIdTitle: "\u9084\u6C92\u6709 ZOREAL ID\uFF1F",
292
+ noIdBody: "\u6383\u63CF\u540C\u4E00\u500B QR code \u5373\u53EF\u4E0B\u8F09\u61C9\u7528\u7A0B\u5F0F\u4E26\u514D\u8CBB\u5EFA\u7ACB\uFF0C\u53EA\u9700\u4E00\u5206\u9418\u3002",
293
+ cancel: "\u53D6\u6D88",
294
+ close: "\u95DC\u9589",
295
+ qrAlt: "\u4F7F\u7528 ZOREAL \u767B\u5165\u7684 QR code"
296
+ },
297
+ ar: {
298
+ title: "\u0627\u0645\u0633\u062D \u0644\u062A\u0633\u062C\u064A\u0644 \u0627\u0644\u062F\u062E\u0648\u0644",
299
+ titleApprove: "\u0648\u0627\u0641\u0642 \u0639\u0644\u0649 \u0647\u0627\u062A\u0641\u0643",
300
+ bodyScan: "\u0627\u0645\u0633\u062D \u0628\u0627\u0633\u062A\u062E\u062F\u0627\u0645 \u0643\u0627\u0645\u064A\u0631\u0627 \u0647\u0627\u062A\u0641\u0643 \u0623\u0648 \u062A\u0637\u0628\u064A\u0642 ZOREAL ID.",
301
+ bodyApprove: "\u0648\u0627\u0641\u0642 \u0639\u0644\u0649 \u062A\u0633\u062C\u064A\u0644 \u0627\u0644\u062F\u062E\u0648\u0644 \u0641\u064A \u062A\u0637\u0628\u064A\u0642 ZOREAL ID.",
302
+ bodyEnrolling: "\u0623\u0643\u0645\u0644 \u0625\u0639\u062F\u0627\u062F ZOREAL ID \u0639\u0644\u0649 \u0647\u0627\u062A\u0641\u0643\u060C \u062B\u0645 \u0648\u0627\u0641\u0642 \u0639\u0644\u0649 \u062A\u0633\u062C\u064A\u0644 \u0627\u0644\u062F\u062E\u0648\u0644.",
303
+ waiting: "\u0641\u064A \u0627\u0646\u062A\u0638\u0627\u0631 \u0627\u0644\u0645\u0633\u062D",
304
+ waitingApproval: "\u0641\u064A \u0627\u0646\u062A\u0638\u0627\u0631 \u0627\u0644\u0645\u0648\u0627\u0641\u0642\u0629",
305
+ expiresIn: "\u062A\u0646\u062A\u0647\u064A \u0627\u0644\u0635\u0644\u0627\u062D\u064A\u0629 \u062E\u0644\u0627\u0644 {time}",
306
+ secured: "\u0627\u0644\u062A\u062D\u0642\u0642 \u0645\u0646 Proof-of-Human \u0628\u0648\u0627\u0633\u0637\u0629 ZOREAL",
307
+ noIdTitle: "\u0644\u064A\u0633 \u0644\u062F\u064A\u0643 ZOREAL ID \u0628\u0639\u062F\u061F",
308
+ noIdBody: "\u0627\u0645\u0633\u062D \u0627\u0644\u0631\u0645\u0632 \u0646\u0641\u0633\u0647 \u0644\u062A\u0646\u0632\u064A\u0644 \u0627\u0644\u062A\u0637\u0628\u064A\u0642 \u0648\u0625\u0646\u0634\u0627\u0621 \u062D\u0633\u0627\u0628 \u0645\u062C\u0627\u0646\u064A. \u064A\u0633\u062A\u063A\u0631\u0642 \u0627\u0644\u0623\u0645\u0631 \u062F\u0642\u064A\u0642\u0629 \u0648\u0627\u062D\u062F\u0629 \u0641\u0642\u0637.",
309
+ cancel: "\u0625\u0644\u063A\u0627\u0621",
310
+ close: "\u0625\u063A\u0644\u0627\u0642",
311
+ qrAlt: "\u0631\u0645\u0632 QR \u0644\u062A\u0633\u062C\u064A\u0644 \u0627\u0644\u062F\u062E\u0648\u0644 \u0628\u0627\u0633\u062A\u062E\u062F\u0627\u0645 ZOREAL"
312
+ },
313
+ ko: {
314
+ title: "\uC2A4\uCE94\uD558\uC5EC \uB85C\uADF8\uC778",
315
+ titleApprove: "\uD734\uB300\uD3F0\uC5D0\uC11C \uC2B9\uC778",
316
+ bodyScan: "\uD734\uB300\uD3F0 \uCE74\uBA54\uB77C \uB610\uB294 ZOREAL ID \uC571\uC73C\uB85C \uC2A4\uCE94\uD558\uC138\uC694.",
317
+ bodyApprove: "ZOREAL ID \uC571\uC5D0\uC11C \uB85C\uADF8\uC778\uC744 \uC2B9\uC778\uD558\uC138\uC694.",
318
+ bodyEnrolling: "\uD734\uB300\uD3F0\uC5D0\uC11C ZOREAL ID \uC124\uC815\uC744 \uC644\uB8CC\uD55C \uD6C4 \uB85C\uADF8\uC778\uC744 \uC2B9\uC778\uD558\uC138\uC694.",
319
+ waiting: "\uC2A4\uCE94 \uB300\uAE30 \uC911",
320
+ waitingApproval: "\uC2B9\uC778 \uB300\uAE30 \uC911",
321
+ expiresIn: "{time} \uD6C4 \uB9CC\uB8CC",
322
+ secured: "ZOREAL\uC758 Proof-of-Human \uC778\uC99D",
323
+ noIdTitle: "\uC544\uC9C1 ZOREAL ID\uAC00 \uC5C6\uC73C\uC2E0\uAC00\uC694?",
324
+ noIdBody: "\uAC19\uC740 \uCF54\uB4DC\uB97C \uC2A4\uCE94\uD574 \uC571\uC744 \uB0B4\uB824\uBC1B\uACE0 \uBB34\uB8CC\uB85C \uB9CC\uB4DC\uC138\uC694. 1\uBD84\uC774\uBA74 \uB429\uB2C8\uB2E4.",
325
+ cancel: "\uCDE8\uC18C",
326
+ close: "\uB2EB\uAE30",
327
+ qrAlt: "ZOREAL\uB85C \uB85C\uADF8\uC778\uD558\uAE30 \uC704\uD55C QR \uCF54\uB4DC"
328
+ }
329
+ };
330
+ var RTL = /* @__PURE__ */ new Set(["ar", "he", "fa", "ur"]);
331
+ function lookup(locale) {
332
+ const tag = locale.toLowerCase().replace(/_/g, "-");
333
+ const primary = tag.split("-")[0];
334
+ if (primary === "zh") {
335
+ const simplified = /(^|-)(hans|cn|sg|my)(-|$)/.test(tag);
336
+ return TRANSLATIONS[simplified ? "zhs" : "zht"];
337
+ }
338
+ return TRANSLATIONS[tag] ?? TRANSLATIONS[primary];
339
+ }
340
+ function browserLocales() {
341
+ if (typeof navigator === "undefined") return [];
342
+ const nav = navigator;
343
+ if (nav.languages && nav.languages.length) return [...nav.languages];
344
+ return nav.language ? [nav.language] : [];
345
+ }
346
+ function strings(locale) {
347
+ if (locale) return lookup(locale) ?? en;
348
+ for (const candidate of browserLocales()) {
349
+ const hit = lookup(candidate);
350
+ if (hit) return hit;
351
+ }
352
+ return en;
353
+ }
354
+ function isRtl(locale) {
355
+ const tag = locale ?? browserLocales()[0];
356
+ if (!tag) return false;
357
+ return RTL.has(tag.toLowerCase().replace(/_/g, "-").split("-")[0]);
358
+ }
359
+ function interpolate(template, time) {
360
+ return template.replace("{time}", time);
361
+ }
362
+
363
+ // src/styles.ts
364
+ var PREFIX = "zrl";
365
+ var cx = (name) => `${PREFIX}-${name}`;
366
+ var STYLE_ELEMENT_ID = "zoreal-pairing-styles";
367
+ var LIGHT = `
368
+ --zrl-scrim: rgba(16, 18, 27, 0.45);
369
+ --zrl-surface: #ffffff;
370
+ --zrl-surface-sunken: #f6f7f9;
371
+ --zrl-ink: #16181c;
372
+ --zrl-ink-soft: #4a4f57;
373
+ --zrl-ink-mute: #6b7078;
374
+ --zrl-line: #e4e6ea;
375
+ --zrl-line-soft: #eef0f3;
376
+ --zrl-accent: #00b4d9;
377
+ --zrl-accent-soft: #dcf3fa;
378
+ --zrl-accent-ink: #04698a;
379
+ --zrl-urgent: #b4761a;
380
+ --zrl-qr-bg: #ffffff;
381
+ --zrl-shadow: 0 1px 2px rgba(16, 18, 27, 0.06), 0 20px 50px -12px rgba(16, 18, 27, 0.3);
382
+ --zrl-ring: rgba(16, 18, 27, 0.07);
383
+ `;
384
+ var DARK = `
385
+ --zrl-scrim: rgba(0, 0, 0, 0.62);
386
+ --zrl-surface: #17191d;
387
+ --zrl-surface-sunken: #1f2226;
388
+ --zrl-ink: #f4f5f7;
389
+ --zrl-ink-soft: #b3b8c0;
390
+ --zrl-ink-mute: #8b9199;
391
+ --zrl-line: #2c3036;
392
+ --zrl-line-soft: #24272c;
393
+ --zrl-accent: #34c9e8;
394
+ --zrl-accent-soft: #0d3b47;
395
+ --zrl-accent-ink: #7fdcf0;
396
+ --zrl-urgent: #e0a952;
397
+ /* The QR well stays white in dark mode on purpose: a scanner needs the
398
+ quiet-zone contrast, and an inverted QR fails on a good number of phone
399
+ cameras. It reads as a deliberate light panel, not a theming miss. */
400
+ --zrl-qr-bg: #ffffff;
401
+ --zrl-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 20px 50px -12px rgba(0, 0, 0, 0.65);
402
+ --zrl-ring: rgba(255, 255, 255, 0.1);
403
+ `;
404
+ var CSS = `
405
+ .${PREFIX}-root { ${LIGHT} }
406
+ .${PREFIX}-root[data-theme="dark"] { ${DARK} }
407
+ @media (prefers-color-scheme: dark) {
408
+ .${PREFIX}-root[data-theme="auto"] { ${DARK} }
409
+ }
410
+
411
+ .${PREFIX}-scrim {
412
+ position: fixed;
413
+ inset: 0;
414
+ z-index: 2147483000;
415
+ display: grid;
416
+ place-items: center;
417
+ overflow-y: auto;
418
+ padding: 16px;
419
+ background: var(--zrl-scrim);
420
+ backdrop-filter: blur(3px);
421
+ -webkit-backdrop-filter: blur(3px);
422
+ font-family: inherit;
423
+ animation: ${PREFIX}-fade 200ms ease-out both;
424
+ }
425
+
426
+ .${PREFIX}-card {
427
+ position: relative;
428
+ box-sizing: border-box;
429
+ width: 100%;
430
+ max-width: 380px;
431
+ border-radius: 16px;
432
+ background: var(--zrl-surface);
433
+ color: var(--zrl-ink);
434
+ box-shadow: var(--zrl-shadow);
435
+ outline: 1px solid var(--zrl-ring);
436
+ outline-offset: -1px;
437
+ text-align: center;
438
+ animation: ${PREFIX}-rise 300ms cubic-bezier(0.23, 1, 0.32, 1) both;
439
+ }
440
+
441
+ .${PREFIX}-body { padding: 28px 24px 20px; }
442
+
443
+ .${PREFIX}-lockup { display: block; margin: 0 auto; color: var(--zrl-ink); }
444
+
445
+ .${PREFIX}-title {
446
+ margin: 18px 0 0;
447
+ font-size: 18px;
448
+ font-weight: 600;
449
+ letter-spacing: -0.01em;
450
+ line-height: 1.3;
451
+ color: var(--zrl-ink);
452
+ }
453
+
454
+ .${PREFIX}-body-text {
455
+ margin: 6px auto 0;
456
+ max-width: 30ch;
457
+ font-size: 14px;
458
+ line-height: 1.55;
459
+ color: var(--zrl-ink-soft);
460
+ }
461
+
462
+ .${PREFIX}-qr-well {
463
+ position: relative;
464
+ display: grid;
465
+ place-items: center;
466
+ box-sizing: border-box;
467
+ width: 204px;
468
+ height: 204px;
469
+ margin: 20px auto 0;
470
+ padding: 12px;
471
+ border: 1px solid var(--zrl-line);
472
+ border-radius: 16px;
473
+ background: var(--zrl-qr-bg);
474
+ }
475
+
476
+ .${PREFIX}-qr {
477
+ display: block;
478
+ width: 100%;
479
+ height: 100%;
480
+ border-radius: 8px;
481
+ transition: filter 300ms cubic-bezier(0.23, 1, 0.32, 1),
482
+ opacity 300ms cubic-bezier(0.23, 1, 0.32, 1),
483
+ transform 300ms cubic-bezier(0.23, 1, 0.32, 1);
484
+ }
485
+
486
+ /* Once the code is claimed the QR is spent. Blurring it out rather than
487
+ swapping it keeps one object on screen through the state change, so the eye
488
+ reads a transformation instead of two things trading places. */
489
+ .${PREFIX}-qr[data-spent="true"] { opacity: 0.2; filter: blur(3px); transform: scale(0.96); }
490
+
491
+ .${PREFIX}-qr-overlay {
492
+ position: absolute;
493
+ inset: 0;
494
+ display: grid;
495
+ place-items: center;
496
+ animation: ${PREFIX}-fade 200ms ease-out both;
497
+ }
498
+
499
+ .${PREFIX}-qr-badge {
500
+ display: grid;
501
+ place-items: center;
502
+ width: 56px;
503
+ height: 56px;
504
+ border-radius: 999px;
505
+ background: var(--zrl-accent-soft);
506
+ color: var(--zrl-accent-ink);
507
+ }
508
+
509
+ .${PREFIX}-status {
510
+ display: flex;
511
+ align-items: center;
512
+ justify-content: center;
513
+ gap: 8px;
514
+ margin-top: 20px;
515
+ font-size: 14px;
516
+ font-weight: 500;
517
+ color: var(--zrl-ink);
518
+ }
519
+
520
+ .${PREFIX}-dot { position: relative; display: grid; place-items: center; width: 8px; height: 8px; }
521
+ .${PREFIX}-dot i {
522
+ position: absolute;
523
+ width: 8px;
524
+ height: 8px;
525
+ border-radius: 999px;
526
+ background: var(--zrl-accent);
527
+ font-style: normal;
528
+ }
529
+ .${PREFIX}-dot i:first-child { animation: ${PREFIX}-ping 1.8s cubic-bezier(0.23, 1, 0.32, 1) infinite; }
530
+
531
+ .${PREFIX}-timer {
532
+ margin: 4px 0 0;
533
+ font-size: 12px;
534
+ font-variant-numeric: tabular-nums;
535
+ color: var(--zrl-ink-mute);
536
+ transition: color 200ms ease-out;
537
+ }
538
+ .${PREFIX}-timer[data-urgent="true"] { color: var(--zrl-urgent); }
539
+
540
+ .${PREFIX}-help {
541
+ padding: 14px 24px;
542
+ border-top: 1px solid var(--zrl-line-soft);
543
+ background: var(--zrl-surface-sunken);
544
+ border-radius: 0;
545
+ }
546
+ .${PREFIX}-help-title { margin: 0; font-size: 12px; font-weight: 600; color: var(--zrl-ink); }
547
+ .${PREFIX}-help-body {
548
+ margin: 4px auto 0;
549
+ max-width: 34ch;
550
+ font-size: 12px;
551
+ line-height: 1.55;
552
+ color: var(--zrl-ink-soft);
553
+ }
554
+
555
+ .${PREFIX}-footer { padding: 12px; border-top: 1px solid var(--zrl-line-soft); }
556
+
557
+ .${PREFIX}-cancel {
558
+ display: block;
559
+ width: 100%;
560
+ padding: 10px;
561
+ border: 0;
562
+ border-radius: 12px;
563
+ background: transparent;
564
+ font: inherit;
565
+ font-size: 14px;
566
+ font-weight: 500;
567
+ color: var(--zrl-ink-soft);
568
+ cursor: pointer;
569
+ transition: background-color 150ms ease-out, color 150ms ease-out, transform 150ms ease-out;
570
+ }
571
+ .${PREFIX}-cancel:hover { background: var(--zrl-surface-sunken); color: var(--zrl-ink); }
572
+ .${PREFIX}-cancel:active { transform: scale(0.99); }
573
+
574
+ .${PREFIX}-secured {
575
+ display: flex;
576
+ align-items: center;
577
+ justify-content: center;
578
+ gap: 6px;
579
+ margin: 6px 0 0;
580
+ font-size: 12px;
581
+ color: var(--zrl-ink-mute);
582
+ }
583
+
584
+ .${PREFIX}-close {
585
+ position: absolute;
586
+ top: 12px;
587
+ inset-inline-end: 12px;
588
+ display: grid;
589
+ place-items: center;
590
+ width: 32px;
591
+ height: 32px;
592
+ padding: 0;
593
+ border: 0;
594
+ border-radius: 8px;
595
+ background: transparent;
596
+ color: var(--zrl-ink-mute);
597
+ cursor: pointer;
598
+ transition: background-color 150ms ease-out, color 150ms ease-out, transform 150ms ease-out;
599
+ }
600
+ .${PREFIX}-close:hover { background: var(--zrl-surface-sunken); color: var(--zrl-ink); }
601
+ .${PREFIX}-close:active { transform: scale(0.95); }
602
+
603
+ .${PREFIX}-card :focus-visible {
604
+ outline: 2px solid var(--zrl-accent);
605
+ outline-offset: 2px;
606
+ }
607
+
608
+ @keyframes ${PREFIX}-fade { from { opacity: 0 } to { opacity: 1 } }
609
+ @keyframes ${PREFIX}-rise {
610
+ from { opacity: 0; transform: translateY(10px) scale(0.98) }
611
+ to { opacity: 1; transform: none }
612
+ }
613
+ @keyframes ${PREFIX}-ping {
614
+ 0% { transform: scale(1); opacity: 0.5 }
615
+ 70%, 100% { transform: scale(2.6); opacity: 0 }
616
+ }
617
+
618
+ @media (prefers-reduced-motion: reduce) {
619
+ .${PREFIX}-scrim,
620
+ .${PREFIX}-card,
621
+ .${PREFIX}-qr-overlay { animation: none }
622
+ .${PREFIX}-dot i:first-child { animation: none; opacity: 0.35 }
623
+ .${PREFIX}-qr,
624
+ .${PREFIX}-cancel,
625
+ .${PREFIX}-close,
626
+ .${PREFIX}-timer { transition: none }
627
+ }
628
+ `;
629
+ function ensureStyles() {
630
+ if (typeof document === "undefined") return;
631
+ if (document.getElementById(STYLE_ELEMENT_ID)) return;
632
+ const el = document.createElement("style");
633
+ el.id = STYLE_ELEMENT_ID;
634
+ el.textContent = CSS;
635
+ document.head.appendChild(el);
636
+ }
637
+
638
+ // src/PairingModal.tsx
639
+ var import_jsx_runtime3 = require("react/jsx-runtime");
640
+ var DEFAULT_PAIRING_TIMEOUT_MS = 12e4;
641
+ var URGENT_SECONDS = 20;
642
+ function mmss(totalSeconds) {
643
+ const m = Math.floor(totalSeconds / 60);
644
+ const s = totalSeconds % 60;
645
+ return `${m}:${String(s).padStart(2, "0")}`;
646
+ }
647
+ var IconClose = () => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, focusable: "false", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M18 6 6 18M6 6l12 12" }) });
648
+ var IconPhone = () => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, focusable: "false", children: [
649
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("rect", { x: "6", y: "2", width: "12", height: "20", rx: "2.5" }),
650
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M11 18.5h2" })
651
+ ] });
652
+ var IconShield = () => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, focusable: "false", children: [
653
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" }),
654
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m9 12 2 2 4-4" })
655
+ ] });
656
+ function PairingModal({
657
+ state,
658
+ qrUrl,
659
+ onCancel,
660
+ locale,
661
+ theme = "auto",
662
+ timeoutMs = DEFAULT_PAIRING_TIMEOUT_MS
663
+ }) {
664
+ const t = strings(locale);
665
+ const titleId = (0, import_react.useId)();
666
+ const closeRef = (0, import_react.useRef)(null);
667
+ const deadlineRef = (0, import_react.useRef)(0);
668
+ const [remaining, setRemaining] = (0, import_react.useState)(Math.round(timeoutMs / 1e3));
669
+ const settled = state.status === "claimed" || state.status === "enrolling";
670
+ const onCancelRef = (0, import_react.useRef)(onCancel);
671
+ onCancelRef.current = onCancel;
672
+ (0, import_react.useEffect)(() => {
673
+ ensureStyles();
674
+ }, []);
675
+ (0, import_react.useEffect)(() => {
676
+ const serverMs = typeof state.expiresIn === "number" ? state.expiresIn * 1e3 : Infinity;
677
+ deadlineRef.current = Date.now() + Math.min(timeoutMs, serverMs);
678
+ setRemaining(Math.round(Math.min(timeoutMs, serverMs) / 1e3));
679
+ const id = setInterval(() => {
680
+ const left = Math.max(0, Math.ceil((deadlineRef.current - Date.now()) / 1e3));
681
+ setRemaining(left);
682
+ if (left === 0) {
683
+ clearInterval(id);
684
+ onCancelRef.current();
685
+ }
686
+ }, 1e3);
687
+ return () => clearInterval(id);
688
+ }, [timeoutMs]);
689
+ (0, import_react.useEffect)(() => {
690
+ const onKey = (e) => {
691
+ if (e.key === "Escape") onCancelRef.current();
692
+ };
693
+ document.addEventListener("keydown", onKey);
694
+ const previous = document.body.style.overflow;
695
+ document.body.style.overflow = "hidden";
696
+ closeRef.current?.focus();
697
+ return () => {
698
+ document.removeEventListener("keydown", onKey);
699
+ document.body.style.overflow = previous;
700
+ };
701
+ }, []);
702
+ if (typeof document === "undefined") return null;
703
+ const body = state.status === "enrolling" ? t.bodyEnrolling : settled ? t.bodyApprove : t.bodyScan;
704
+ return (0, import_react_dom.createPortal)(
705
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: `${cx("root")} ${cx("scrim")}`, "data-theme": theme, onClick: onCancel, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
706
+ "div",
707
+ {
708
+ className: cx("card"),
709
+ role: "dialog",
710
+ "aria-modal": "true",
711
+ "aria-labelledby": titleId,
712
+ dir: isRtl(locale) ? "rtl" : "ltr",
713
+ onClick: (e) => e.stopPropagation(),
714
+ children: [
715
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { ref: closeRef, type: "button", className: cx("close"), "aria-label": t.close, onClick: onCancel, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IconClose, {}) }),
716
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: cx("body"), children: [
717
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ZorealLockup, { height: 44, className: cx("lockup") }),
718
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { id: titleId, className: cx("title"), children: settled ? t.titleApprove : t.title }),
719
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: cx("body-text"), children: body }),
720
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: cx("qr-well"), children: [
721
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("img", { className: cx("qr"), "data-spent": settled, src: qrUrl, alt: t.qrAlt, width: 180, height: 180 }),
722
+ settled && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: cx("qr-overlay"), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: cx("qr-badge"), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IconPhone, {}) }) })
723
+ ] }),
724
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: cx("status"), children: [
725
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: cx("dot"), children: [
726
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("i", {}),
727
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("i", {})
728
+ ] }),
729
+ settled ? t.waitingApproval : t.waiting
730
+ ] }),
731
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: cx("timer"), "data-urgent": remaining <= URGENT_SECONDS, children: interpolate(t.expiresIn, mmss(remaining)) })
732
+ ] }),
733
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: cx("help"), children: [
734
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: cx("help-title"), children: t.noIdTitle }),
735
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: cx("help-body"), children: t.noIdBody })
736
+ ] }),
737
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: cx("footer"), children: [
738
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: cx("cancel"), onClick: onCancel, children: t.cancel }),
739
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: cx("secured"), children: [
740
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IconShield, {}),
741
+ t.secured
742
+ ] })
743
+ ] })
744
+ ]
745
+ }
746
+ ) }),
747
+ document.body
748
+ );
749
+ }
750
+
751
+ // src/context.tsx
752
+ var import_jsx_runtime4 = require("react/jsx-runtime");
753
+ var ZorealOAuthContext = (0, import_react2.createContext)(null);
754
+ var PairingHostContext = (0, import_react2.createContext)(null);
755
+ function useZorealPairingHost() {
756
+ return (0, import_react2.useContext)(PairingHostContext);
757
+ }
48
758
  function ZorealOAuthProvider({
49
759
  clientId,
50
760
  issuer = DEFAULT_ISSUER,
51
761
  locale,
762
+ theme = "auto",
763
+ pairingUI = "modal",
764
+ pairingTimeoutMs,
52
765
  children
53
766
  }) {
54
- const value = (0, import_react.useMemo)(
767
+ const [pairing, setPairing] = (0, import_react2.useState)(null);
768
+ const value = (0, import_react2.useMemo)(
55
769
  () => ({ clientId, issuer: issuer.replace(/\/$/, ""), locale }),
56
770
  [clientId, issuer, locale]
57
771
  );
58
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ZorealOAuthContext.Provider, { value, children });
772
+ const host = pairingUI === "modal" ? setPairing : null;
773
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ZorealOAuthContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(PairingHostContext.Provider, { value: host, children: [
774
+ children,
775
+ pairing && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
776
+ PairingModal,
777
+ {
778
+ state: pairing.state,
779
+ qrUrl: pairing.qrUrl,
780
+ onCancel: pairing.cancel,
781
+ locale,
782
+ theme,
783
+ timeoutMs: pairingTimeoutMs
784
+ }
785
+ )
786
+ ] }) });
59
787
  }
60
788
  function useZorealOAuth() {
61
- const ctx = (0, import_react.useContext)(ZorealOAuthContext);
789
+ const ctx = (0, import_react2.useContext)(ZorealOAuthContext);
62
790
  if (!ctx) {
63
791
  throw new Error(
64
792
  "useZorealOAuth must be used inside <ZorealOAuthProvider clientId=...>. Wrap your app (or the part that logs in) in the provider."
@@ -68,10 +796,10 @@ function useZorealOAuth() {
68
796
  }
69
797
 
70
798
  // src/ZorealLogin.tsx
71
- var import_react3 = require("react");
799
+ var import_react4 = require("react");
72
800
 
73
801
  // src/useZorealLogin.ts
74
- var import_react2 = require("react");
802
+ var import_react3 = require("react");
75
803
 
76
804
  // src/jwt.ts
77
805
  function unsafeClaims(idToken) {
@@ -225,12 +953,21 @@ function generateState() {
225
953
  // src/useZorealLogin.ts
226
954
  function useZorealFlow(options) {
227
955
  const { clientId, issuer, locale } = useZorealOAuth();
228
- const [pairing, setPairing] = (0, import_react2.useState)(null);
229
- const abortRef = (0, import_react2.useRef)(null);
230
- const optionsRef = (0, import_react2.useRef)(options);
956
+ const [pairing, setPairing] = (0, import_react3.useState)(null);
957
+ const publish = useZorealPairingHost();
958
+ const publishRef = (0, import_react3.useRef)(publish);
959
+ publishRef.current = publish;
960
+ const abortRef = (0, import_react3.useRef)(null);
961
+ const optionsRef = (0, import_react3.useRef)(options);
231
962
  optionsRef.current = options;
232
- (0, import_react2.useEffect)(() => () => abortRef.current?.abort(), []);
233
- const login = (0, import_react2.useCallback)(() => {
963
+ (0, import_react3.useEffect)(
964
+ () => () => {
965
+ abortRef.current?.abort();
966
+ publishRef.current?.(null);
967
+ },
968
+ []
969
+ );
970
+ const login = (0, import_react3.useCallback)(() => {
234
971
  const opts = optionsRef.current;
235
972
  const run = async () => {
236
973
  abortRef.current?.abort();
@@ -264,6 +1001,7 @@ function useZorealFlow(options) {
264
1001
  const cancel = () => {
265
1002
  controller.abort();
266
1003
  setPairing(null);
1004
+ publishRef.current?.(null);
267
1005
  };
268
1006
  const surface = {
269
1007
  pairUrl: started.pair_url,
@@ -280,6 +1018,9 @@ function useZorealFlow(options) {
280
1018
  cancel
281
1019
  };
282
1020
  setPairing(active);
1021
+ if (!useAppLink) {
1022
+ publishRef.current?.({ state: active.state, qrUrl: surface.qrUrl, cancel });
1023
+ }
283
1024
  opts.onPairingStateChange?.(active.state);
284
1025
  if (useAppLink) {
285
1026
  window.location.assign(started.pair_url);
@@ -292,12 +1033,16 @@ function useZorealFlow(options) {
292
1033
  setPairing(
293
1034
  (p) => p && p.requestId === started.request_id ? { ...p, state: enriched } : p
294
1035
  );
1036
+ if (!useAppLink) {
1037
+ publishRef.current?.({ state: enriched, qrUrl: surface.qrUrl, cancel });
1038
+ }
295
1039
  opts.onPairingStateChange?.(enriched);
296
1040
  },
297
1041
  controller.signal
298
1042
  );
299
1043
  }
300
1044
  setPairing(null);
1045
+ publishRef.current?.(null);
301
1046
  if (flow === "auth-code") {
302
1047
  opts.onCode?.({
303
1048
  code,
@@ -323,6 +1068,7 @@ function useZorealFlow(options) {
323
1068
  opts.onCredential?.(response);
324
1069
  } catch (e) {
325
1070
  setPairing(null);
1071
+ publishRef.current?.(null);
326
1072
  if (e instanceof DOMException && e.name === "AbortError") return;
327
1073
  if (e instanceof FlowAbandonedError) {
328
1074
  opts.onNonOAuthError?.(e.reason);
@@ -358,7 +1104,7 @@ function useZorealLogin(options) {
358
1104
  }
359
1105
 
360
1106
  // src/ZorealLogin.tsx
361
- var import_jsx_runtime2 = require("react/jsx-runtime");
1107
+ var import_jsx_runtime5 = require("react/jsx-runtime");
362
1108
  var TEXTS = {
363
1109
  continue_with: "Continue with ZOREAL",
364
1110
  signin_with: "Sign in with ZOREAL",
@@ -370,80 +1116,6 @@ var SIZES = {
370
1116
  medium: { height: 38, font: 14, pad: 16 },
371
1117
  small: { height: 32, font: 12, pad: 12 }
372
1118
  };
373
- var Mark = ({ size }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
374
- "svg",
375
- {
376
- width: size,
377
- height: size,
378
- viewBox: "8.4 7.4 62.2 62.2",
379
- fill: "currentColor",
380
- fillRule: "evenodd",
381
- "aria-hidden": true,
382
- focusable: "false",
383
- children: [
384
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M56.1,32.9c.6-3.1-.8-6.4-3.7-8.1l-18-10.4,5.2-3,15.4,8.9c5.4,3.1,7.7,9.6,5.8,15.3-.3.8-.6,1.6-1.1,2.4-.4.7-.9,1.4-1.5,2.1-1.3,1.4-2.9,2.6-4.6,3.3-3.6,1.5-7.9,1.4-11.6-.7l-8.9-5.1c-2.9-1.7-6.5-1.3-8.9.8-.6.6-1.2,1.2-1.7,2-.5.8-.8,1.7-.9,2.5-.6,3.1.9,6.4,3.7,8.1l18,10.4-5.2,3-15.4-8.9c-5.4-3.1-7.7-9.6-5.8-15.3.2-.8.6-1.6,1-2.4.5-.7,1-1.4,1.5-2.1,1.3-1.4,2.9-2.6,4.7-3.3,3.6-1.6,7.8-1.4,11.5.6l8.9,5.2c3,1.7,6.6,1.3,8.9-.8.6-.6,1.2-1.2,1.7-2,.4-.8.7-1.7.9-2.5Z" }),
385
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M68.7,44.2c-.7,1.2-2.3,1.7-3.5.9-1.3-.7-1.7-2.3-1-3.5.7-1.3,2.3-1.7,3.5-1,1.3.7,1.7,2.3,1,3.6Z" }),
386
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M25.6,21.3c5.1-.8,10.4,0,15.3,2.9l1.2.7h0c1.2.7,1.6,2.3.9,3.5s-2.3,1.7-3.5.9l-1.2-.7c-4.2-2.4-9.1-3-13.5-1.9-1.6.4-3.1,1.1-4.5,1.9h0c-1.2.7-2.8.3-3.5-1-.7-1.2-.3-2.8.9-3.5,0,0,.1,0,.3-.1.3-.1.6-.4,1-.5,2.1-1.1,4.4-1.7,6.7-2.2Z" }),
387
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M9.6,31.8c.7-1.2,2.4-1.6,3.5-.8,1.2.7,1.6,2.4.8,3.5-.8,1.2-2.4,1.6-3.6.8-1.2-.8-1.5-2.4-.7-3.5Z" }),
388
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M46.2,30.3c.7-1.3,2.3-1.7,3.5-1,1.2.7,1.7,2.3.9,3.6-.7,1.2-2.3,1.7-3.5.9s-1.7-2.3-.9-3.5Z" }),
389
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M52.1,54.5c-5,.9-10.4,0-15.3-2.8l-1.2-.7h0c-1.2-.7-1.7-2.3-.9-3.5s2.3-1.7,3.5-.9l1.2.7c4.3,2.4,9.1,3,13.6,1.9,1.6-.4,3.1-1.1,4.5-1.9h0c1.2-.7,2.8-.3,3.5.9.7,1.3.3,2.9-.9,3.6-.1,0-.2,0-.3,0-.4.2-.7.4-1.1.6-2.1,1-4.3,1.7-6.7,2.1Z" }),
390
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M31.4,45.6c-.7,1.2-2.3,1.7-3.5.9s-1.7-2.3-.9-3.5,2.3-1.7,3.5-.9,1.7,2.3.9,3.5Z" })
391
- ]
392
- }
393
- );
394
- var PairingPanel = ({ pairing }) => {
395
- const { status } = pairing.state;
396
- const line = status === "claimed" ? "Approve the login in your ZOREAL ID app." : status === "enrolling" ? "Finishing enrolment. This screen will continue by itself." : pairing.appLink ? "Continue in the ZOREAL ID app, then return to this tab." : "Scan with your phone camera or the ZOREAL ID app.";
397
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
398
- "div",
399
- {
400
- role: "dialog",
401
- "aria-label": "Log in with ZOREAL",
402
- style: {
403
- marginTop: 8,
404
- padding: 16,
405
- width: 232,
406
- borderRadius: 12,
407
- border: "1px solid rgba(128,128,128,0.35)",
408
- background: "Canvas",
409
- color: "CanvasText",
410
- textAlign: "center",
411
- fontFamily: "inherit"
412
- },
413
- children: [
414
- !pairing.appLink && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
415
- "img",
416
- {
417
- src: pairing.qrUrl,
418
- alt: `QR code for ${pairing.pairUrl}`,
419
- width: 200,
420
- height: 200,
421
- style: { display: "block", margin: "0 auto", borderRadius: 8 }
422
- }
423
- ),
424
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: { margin: "10px 0 0", fontSize: 12, lineHeight: 1.5 }, children: line }),
425
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
426
- "button",
427
- {
428
- type: "button",
429
- onClick: pairing.cancel,
430
- style: {
431
- marginTop: 10,
432
- border: "none",
433
- background: "none",
434
- color: "inherit",
435
- opacity: 0.6,
436
- fontSize: 12,
437
- cursor: "pointer",
438
- textDecoration: "underline"
439
- },
440
- children: "Cancel"
441
- }
442
- )
443
- ]
444
- }
445
- );
446
- };
447
1119
  function ZorealLogin(props) {
448
1120
  const {
449
1121
  onSuccess,
@@ -459,7 +1131,7 @@ function ZorealLogin(props) {
459
1131
  click_listener,
460
1132
  ...request
461
1133
  } = props;
462
- const { login, internals } = useZorealFlow({
1134
+ const { login } = useZorealFlow({
463
1135
  ...request,
464
1136
  flow: "browser-direct",
465
1137
  onCredential: onSuccess,
@@ -467,7 +1139,7 @@ function ZorealLogin(props) {
467
1139
  onNonOAuthError: (e) => onError?.(e)
468
1140
  });
469
1141
  const s = SIZES[size];
470
- const style = (0, import_react3.useMemo)(
1142
+ const style = (0, import_react4.useMemo)(
471
1143
  () => ({
472
1144
  display: "inline-flex",
473
1145
  alignItems: "center",
@@ -485,28 +1157,25 @@ function ZorealLogin(props) {
485
1157
  }),
486
1158
  [logo_alignment, s, shape, theme, width]
487
1159
  );
488
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { ...containerProps, children: [
489
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
490
- "button",
491
- {
492
- type: "button",
493
- style,
494
- onClick: () => {
495
- click_listener?.();
496
- login();
497
- },
498
- children: [
499
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Mark, { size: Math.round(s.font * 1.25) }),
500
- type === "standard" && TEXTS[text]
501
- ]
502
- }
503
- ),
504
- internals.pairing && !internals.pairing.appLink && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PairingPanel, { pairing: internals.pairing })
505
- ] });
1160
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ...containerProps, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1161
+ "button",
1162
+ {
1163
+ type: "button",
1164
+ style,
1165
+ onClick: () => {
1166
+ click_listener?.();
1167
+ login();
1168
+ },
1169
+ children: [
1170
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ZorealMark, { size: Math.round(s.font * 1.25) }),
1171
+ type === "standard" && TEXTS[text]
1172
+ ]
1173
+ }
1174
+ ) });
506
1175
  }
507
1176
 
508
1177
  // src/useZorealAutoLogin.ts
509
- var import_react4 = require("react");
1178
+ var import_react5 = require("react");
510
1179
  function useZorealAutoLogin(options) {
511
1180
  const { login } = useZorealFlow({
512
1181
  flow: "browser-direct",
@@ -523,8 +1192,8 @@ function useZorealAutoLogin(options) {
523
1192
  },
524
1193
  onNonOAuthError: (e) => options.onError?.(e)
525
1194
  });
526
- const fired = (0, import_react4.useRef)(false);
527
- (0, import_react4.useEffect)(() => {
1195
+ const fired = (0, import_react5.useRef)(false);
1196
+ (0, import_react5.useEffect)(() => {
528
1197
  if (options.disabled || fired.current) return;
529
1198
  fired.current = true;
530
1199
  login();
@@ -546,6 +1215,8 @@ function hasGrantedAnyScopeZoreal(response, firstScope, ...restScopes) {
546
1215
  }
547
1216
  // Annotate the CommonJS export names for ESM import in node:
548
1217
  0 && (module.exports = {
1218
+ DEFAULT_PAIRING_TIMEOUT_MS,
1219
+ PairingModal,
549
1220
  ZorealLogin,
550
1221
  ZorealOAuthProvider,
551
1222
  hasGrantedAllScopesZoreal,