@optionfactory/ful 0.79.0 → 0.90.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.
package/dist/ful.mjs CHANGED
@@ -70,171 +70,451 @@ class Hex {
70
70
  }
71
71
  }
72
72
 
73
- class ContextInterceptor {
74
- constructor() {
75
- const context = document.querySelector("meta[name='context']").getAttribute("content");
76
- this.context = context.endsWith("/") ? context.substring(0, context.length - 1) : context;
73
+ class Failure extends Error {
74
+ constructor(name, problems, cause) {
75
+ super(JSON.stringify(problems), { cause });
76
+ this.name = name;
77
+ this.problems = problems;
77
78
  }
78
- async intercept(request, chain){
79
- const separator = request.resource.startsWith("/") ? "" : "/";
80
- request.resource = this.context + separator + request.resource;
81
- return await chain.proceed(request);
79
+ }
80
+
81
+ class HttpClientError extends Failure {
82
+ constructor(status, problems, cause) {
83
+ super(`HttpClientError:${status}`, problems, cause);
84
+ this.status = status;
85
+ }
86
+ static of(type, cause) {
87
+ return new HttpClientError(0, [{
88
+ type,
89
+ context: null,
90
+ reason: cause.message,
91
+ details: null
92
+ }], cause);
93
+ }
94
+ /**
95
+ * Creates an HttpClientError from a Response.
96
+ * @param {Response} response
97
+ * @returns an HttpClientError
98
+ */
99
+ static async fromResponse(response) {
100
+ const text = await response.text();
101
+ const def = [{
102
+ type: "GENERIC_PROBLEM",
103
+ context: null,
104
+ reason: `${response.status} ${response.statusText}: ${text}`,
105
+ details: null
106
+ }];
107
+ try {
108
+ return new HttpClientError(response.status, text ? JSON.parse(text) : def);
109
+ } catch (e) {
110
+ return new HttpClientError(response.status, def);
111
+ }
82
112
  }
83
113
  }
84
114
 
85
115
  class CsrfTokenInterceptor {
116
+ #k; #v;
86
117
  constructor() {
87
- this.k = document.querySelector("meta[name='_csrf_header']").getAttribute("content");
88
- this.v = document.querySelector("meta[name='_csrf']").getAttribute("content");
118
+ this.#k = document.querySelector("meta[name='_csrf_header']").getAttribute("content");
119
+ this.#v = document.querySelector("meta[name='_csrf']").getAttribute("content");
89
120
  }
90
- async intercept(request, chain){
91
- const headers = new Headers(request.options.headers);
92
- headers.set(this.k, this.v);
93
- request.options.headers = headers;
121
+ async intercept(request, chain) {
122
+ request.headers.set(this.#k, this.#v);
94
123
  return await chain.proceed(request);
95
124
  }
96
125
  }
97
126
 
98
127
  class RedirectOnUnauthorizedInterceptor {
128
+ #redirectUri;
99
129
  constructor(redirectUri) {
100
- this.redirectUri = redirectUri;
130
+ this.#redirectUri = redirectUri;
101
131
  }
102
- async intercept(request, chain){
103
- const response = await chain.proceed(request);
132
+ async intercept(request, chain) {
133
+ const response = await chain.proceed(request);
104
134
  if (response.status !== 401) {
105
135
  return response;
106
136
  }
107
- window.location.href = this.redirectUri;
108
- }
109
- }
110
-
111
- class Failure extends Error {
112
- static parseProblems(status, text) {
113
- const def = [{
114
- type: "GENERIC_PROBLEM",
115
- context: null,
116
- reason: `${status}: ${text}`,
117
- details: null
118
- }];
119
- try {
120
- return text ? JSON.parse(text) : def;
121
- } catch (e) {
122
- return def;
123
- }
124
- }
125
- static fromResponse(status, text) {
126
- return new Failure(status, Failure.parseProblems(status, text));
127
- }
128
- constructor(status, problems) {
129
- super(JSON.stringify(problems));
130
- this.name = `Failure:${status}`;
131
- this.status = status;
132
- this.problems = problems;
137
+ window.location.href = this.#redirectUri;
133
138
  }
134
139
  }
135
140
 
136
141
  class HttpClientBuilder {
142
+ #interceptors;
137
143
  constructor() {
138
- this.interceptors = [];
139
- }
140
- withContext() {
141
- this.interceptors.push(new ContextInterceptor());
142
- return this;
144
+ this.#interceptors = [];
143
145
  }
144
146
  withCsrfToken() {
145
- this.interceptors.push(new CsrfTokenInterceptor());
147
+ this.#interceptors.push(new CsrfTokenInterceptor());
146
148
  return this;
147
149
  }
148
150
  withRedirectOnUnauthorized(redirectUri) {
149
- this.interceptors.push(new RedirectOnUnauthorizedInterceptor(redirectUri));
151
+ this.#interceptors.push(new RedirectOnUnauthorizedInterceptor(redirectUri));
150
152
  return this;
151
153
  }
152
154
  withInterceptors(...interceptors) {
153
- this.interceptors.push(...interceptors);
155
+ this.#interceptors.push(...interceptors);
154
156
  return this;
155
157
  }
156
158
  build() {
157
- const interceptors = this.interceptors;
158
- return new HttpClient({interceptors});
159
+ return new HttpClient(this.#interceptors);
159
160
  }
160
161
  }
161
162
 
162
163
  class HttpCall {
163
- async intercept(request, chain){
164
- return await fetch(request.resource, request.options);
165
- }
164
+ /**
165
+ *
166
+ * @async
167
+ * @param {Request} request
168
+ * @param {HttpInterceptorChain} chain
169
+ * @returns {Promise<Response>} the response
170
+ */
171
+ async intercept(request, chain) {
172
+ return await fetch(request);
173
+ }
166
174
  }
167
175
 
168
176
  class HttpInterceptorChain {
169
- constructor(interceptors, current){
177
+ constructor(interceptors, current) {
170
178
  this.interceptors = interceptors;
171
179
  this.current = current;
172
180
  }
173
- async proceed(request){
181
+ async proceed(request) {
174
182
  const interceptor = this.interceptors[this.current];
175
183
  return await interceptor.intercept(request, new HttpInterceptorChain(this.interceptors, this.current + 1));
176
184
  }
177
185
  }
178
186
 
179
-
180
187
  class HttpClient {
188
+ #interceptors;
189
+ /**
190
+ * Creates a builder for an HttpClient.
191
+ * @returns {HttpRequestBuilder} the client builder
192
+ */
181
193
  static builder() {
182
194
  return new HttpClientBuilder();
183
195
  }
184
- constructor({interceptors}){
185
- this.interceptors = interceptors || [];
196
+ /**
197
+ * Creates an HttpClient.
198
+ * @returns {[HttpInterceptor]} interceptors - a list of interceptors to be registered for every request performed by the created client.
199
+ */
200
+ constructor(interceptors) {
201
+ this.#interceptors = interceptors || [];
202
+ }
203
+ /**
204
+ * Performs an HTTP exchange.
205
+ * @async
206
+ * @param {string} uri - the (possibly relative) request url
207
+ * @param {RequestInit|undefined} options - fetch options
208
+ * @param {[any]|undefined} interceptors - the HttpInterceptors to be registered for this request.
209
+ * @returns {Promise<Response>} the response
210
+ */
211
+ async exchange(uri, options, interceptors) {
212
+ const is = [...this.#interceptors, ...interceptors || [], new HttpCall()];
213
+ const chain = new HttpInterceptorChain(is, 0);
214
+ return await chain.proceed(new Request(uri, options));
186
215
  }
187
- async exchange(resource, options) {
188
- const opts = options || {};
189
- const interceptors = [...this.interceptors, ...opts.interceptors || [], new HttpCall()];
190
- const chain = new HttpInterceptorChain(interceptors, 0);
191
- return await chain.proceed({resource, options: opts});
216
+ /**
217
+ * Creates a request builder.
218
+ * @param {string} method - the HTTP method to be used
219
+ * @param {string} uri - the (possibly relative) request url
220
+ * @returns {HttpRequestBuilder} the request builder
221
+ */
222
+ request(method, uri) {
223
+ return HttpRequestBuilder.create(this, method, uri);
192
224
  }
193
- async fetch(resource, options) {
194
- const response = await this.exchange(resource, options);
195
- if (!response.ok) {
196
- const message = await response.text();
197
- throw Failure.fromResponse(response.status, message);
198
- }
199
- return response;
225
+ /**
226
+ * Creates a request builder.
227
+ * @param {string} uri - the (possibly relative) request url
228
+ * @returns {HttpRequestBuilder} the request builder
229
+ */
230
+ get(uri) {
231
+ return HttpRequestBuilder.create(this, 'GET', uri);
232
+ }
233
+ /**
234
+ * Creates a request builder.
235
+ * @param {string} uri - the (possibly relative) request url
236
+ * @returns {HttpRequestBuilder} the request builder
237
+ */
238
+ head(uri) {
239
+ return HttpRequestBuilder.create(this, 'HEAD', uri);
240
+ }
241
+ /**
242
+ * Creates a request builder.
243
+ * @param {string} uri - the (possibly relative) request url
244
+ * @returns {HttpRequestBuilder} the request builder
245
+ */
246
+ post(uri) {
247
+ return HttpRequestBuilder.create(this, 'POST', uri);
248
+ }
249
+ /**
250
+ * Creates a request builder.
251
+ * @param {string} uri - the (possibly relative) request url
252
+ * @returns {HttpRequestBuilder} the request builder
253
+ */
254
+ put(uri) {
255
+ return HttpRequestBuilder.create(this, 'PUT', uri);
256
+ }
257
+ /**
258
+ * Creates a request builder.
259
+ * @param {string} uri - the (possibly relative) request url
260
+ * @returns {HttpRequestBuilder} the request builder
261
+ */
262
+ patch(uri) {
263
+ return HttpRequestBuilder.create(this, 'PATCH', uri);
264
+ }
265
+ /**
266
+ * Creates a request builder.
267
+ * @param {string} uri - the (possibly relative) request url
268
+ * @returns {HttpRequestBuilder} the request builder
269
+ */
270
+ delete(uri) {
271
+ return HttpRequestBuilder.create(this, 'DELETE', uri);
272
+ }
273
+ }
274
+
275
+
276
+ const unmarshal = async (response, type) => {
277
+ try {
278
+ return await response[type]();
279
+ } catch (e) {
280
+ throw HttpClientError.of("UNMARSHALING_PROBLEM", e);
281
+ }
282
+ };
283
+
284
+
285
+ class HttpRequestBuilder {
286
+ #client;
287
+ #method;
288
+ #uri;
289
+ #params;
290
+ #headers;
291
+ #body;
292
+ #options;
293
+ #interceptors;
294
+ /**
295
+ * Creates an HttpRequestBuilder.
296
+ * @param {HttpClient} client
297
+ * @param {string} method - the HTTP method to be used
298
+ * @param {string} uri - the (possibly relative) request url
299
+ * @returns {HttpRequestBuilder} the builder
300
+ */
301
+ static create(client, method, uri) {
302
+ return new HttpRequestBuilder(
303
+ client,
304
+ method,
305
+ uri,
306
+ new URLSearchParams(),
307
+ new Headers(),
308
+ undefined,
309
+ {},
310
+ []
311
+ );
312
+ }
313
+ /**
314
+ * Creates an HttpRequestBuilder.
315
+ * @param {HttpClient} client
316
+ * @param {string} method - the HTTP method to be used
317
+ * @param {string} uri - the (possibly relative) request url
318
+ * @param {URLSearchParams} params
319
+ * @param {Headers} headers
320
+ * @param {any} body
321
+ * @param {Omit<RequestInit,"headers"|"method"|"body">} options
322
+ * @param {[HttpInterceptor]} interceptors
323
+ */
324
+ constructor(client, method, uri, params, headers, body, options, interceptors) {
325
+ this.#client = client;
326
+ this.#method = method;
327
+ this.#uri = uri;
328
+ this.#params = params;
329
+ this.#body = body;
330
+ this.#headers = headers;
331
+ this.#options = options;
332
+ this.#interceptors = interceptors;
200
333
  }
201
- async json(resource, options) {
334
+ /**
335
+ * Add all passed headers to the request, overriding existing ones if that key already exists.
336
+ * @param {headersInit} hs
337
+ * @returns {HttpRequestBuilder} this builder
338
+ */
339
+ headers(hs) {
340
+ for (const [k, v] of new Headers(hs).entries()) {
341
+ this.#headers.set(k, v);
342
+ }
343
+ return this;
344
+ }
345
+ /**
346
+ * Adds an header to the request, overriding it if it already exists.
347
+ * @param {string} k
348
+ * @param {string} v
349
+ * @returns {HttpRequestBuilder} this builder
350
+ */
351
+ header(k, v) {
352
+ this.#headers.set(k, v);
353
+ return this;
354
+ }
355
+ /**
356
+ * Add all query parameters to the request, overriding existing ones if that key already exists.
357
+ * @param {URLSearchParams|Record<string,string>|string[][]|string} ps
358
+ * @returns {HttpRequestBuilder} this builder
359
+ */
360
+ params(ps) {
361
+ for (const [k, v] of new URLSearchParams(ps).entries()) {
362
+ this.#params.set(k, v);
363
+ }
364
+ return this;
365
+ }
366
+ /**
367
+ * Adds a query parameter to the request, overriding it if it already exists.
368
+ * @param {string} k
369
+ * @param {string} v
370
+ * @returns {HttpRequestBuilder} this builder
371
+ */
372
+ param(k, v) {
373
+ this.#params.set(k, v);
374
+ return this;
375
+ }
376
+ /**
377
+ * Sets the request body.
378
+ * `Content-Type: multipart/form-data` header is automatically added by fetch when data is a FormData instance if not explicitly set.
379
+ * `Content-Type: application/x-www-form-urlencoded` header is automatically added by fetch when data is an URLSearchParams instance if not explicitly set.
380
+ * `Content-Type: text/plain` header is automatically added by fetch when data is a string instance if not explicitly set.
381
+ * @param {string|ArrayBuffer|Blob|DataView|File|FormData|TypedArray|URLSearchParams|ReadableStream} data
382
+ * @returns {HttpRequestBuilder} this builder
383
+ */
384
+ body(data) {
385
+ this.#body = data;
386
+ return this;
387
+ }
388
+ /**
389
+ * Sets the request body that will be serialized as json. Calling this method adds the `Content-Type application/json` header for the request.
390
+ * @param {any} body - the body to be serialized as json
391
+ * @returns {HttpRequestBuilder} this builder
392
+ */
393
+ json(body) {
394
+ this.#headers.set("Content-Type", "application/json");
395
+ this.#body = JSON.stringify(body);
396
+ return this;
397
+ }
398
+ /**
399
+ * Sets a fetch options for the request.
400
+ * @param {Omit<RequestInit,"headers"|"method"|"body">} kvs
401
+ * @returns {HttpRequestBuilder} this builder
402
+ */
403
+ options(kvs) {
404
+ for (const [k, v] of Object.entries(kvs)) {
405
+ this.#options[k] = v;
406
+ }
407
+ return this;
408
+ }
409
+ /**
410
+ * Sets a fetch option for the request.
411
+ * @param {keyof Omit<RequestInit,"headers"|"method"|"body">} k
412
+ * @param {*} v
413
+ * @returns {HttpRequestBuilder} this builder
414
+ */
415
+ option(k, v) {
416
+ this.#options[k] = v;
417
+ return this;
418
+ }
419
+ /**
420
+ * Adds interceptors to the request.
421
+ * @param {[HttpInterceptor]} is - the interceptor to be regisered
422
+ * @returns {HttpRequestBuilder} this builder
423
+ */
424
+ interceptors(is) {
425
+ for (const i of is) {
426
+ this.#interceptors.push(i);
427
+ }
428
+ return this;
429
+ }
430
+ /**
431
+ * Adds an interceptor to the request.
432
+ * @param {HttpInterceptor} i - the interceptor to be regisered
433
+ * @returns {HttpRequestBuilder} this builder
434
+ */
435
+ interceptor(i) {
436
+ this.#interceptors.push(i);
437
+ return this;
438
+ }
439
+ /**
440
+ * Performs an HTTP exchange using the configured client, request and interceptors.
441
+ * @returns {Promise<Response>} the response
442
+ */
443
+ async exchange() {
444
+ const uri = this.#params.size ? `${this.#uri}?${this.#params}` : this.#uri;
445
+ const opts = {
446
+ ...this.#options,
447
+ headers: this.#headers,
448
+ method: this.#method,
449
+ body: this.#body,
450
+ };
451
+ return await this.#client.exchange(uri, opts, this.#interceptors);
452
+ }
453
+ /**
454
+ * Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.
455
+ * @returns {Promise<Response>} the response
456
+ */
457
+ async fetch() {
458
+ const uri = this.#params.size ? `${this.#uri}?${this.#params}` : this.#uri;
459
+ const opts = {
460
+ ...this.#options,
461
+ headers: this.#headers,
462
+ method: this.#method,
463
+ body: this.#body,
464
+ };
202
465
  try {
203
- const response = await this.fetch(resource, options);
204
- const text = await response.text();
205
- return text ? JSON.parse(text) : undefined;
466
+ const response = await this.#client.exchange(uri, opts, this.#interceptors);
467
+ if (!response.ok) {
468
+ throw await HttpClientError.fromResponse(response);
469
+ }
470
+ return response;
206
471
  } catch (e) {
207
472
  if (e instanceof Failure) {
208
473
  throw e;
209
474
  }
210
- throw new Failure(0, [{
211
- type: "CONNECTION_PROBLEM",
212
- context: null,
213
- reason: e.message,
214
- details: null
215
- }]);
475
+ throw HttpClientError.of("CONNECTION_PROBLEM", e);
216
476
  }
217
477
  }
218
- }
219
-
220
- function jsonRequest(method, body, headers){
221
- return {
222
- headers: {
223
- "Content-Type": "application/json",
224
- ...headers
225
- },
226
- method: method,
227
- body: JSON.stringify(body)
478
+ /**
479
+ * Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.
480
+ * @returns {Promise<string>} the response body, as text
481
+ */
482
+ async fetchText() {
483
+ const response = await this.fetch();
484
+ return await unmarshal(response, 'text');
485
+ }
486
+ /**
487
+ * Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.
488
+ * @returns {Promise<any>} the response body, deserialized as JSON
489
+ */
490
+ async fetchJson() {
491
+ const response = await this.fetch();
492
+ return await unmarshal(response, 'json');
493
+ }
494
+ /**
495
+ * Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.
496
+ * @returns {Promise<Uint8Array>} the response body, as an Uint8Array
497
+ */
498
+ async fetchBytes() {
499
+ const response = await this.fetch();
500
+ return await unmarshal(response, 'bytes');
501
+ }
502
+ /**
503
+ * Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.
504
+ * @returns {Promise<Blob>} the response body, as a Blob
505
+ */
506
+ async fetchBlob() {
507
+ const response = await this.fetch();
508
+ return await unmarshal(response, 'blob');
509
+ }
510
+ /**
511
+ * Performs an HTTP exchange using the configured client request, and interceptos throwing a failure when response status is not in the 200-299 range.
512
+ * @returns {Promise<ArrayBuffer>} the response body, as an ArrayBuffer
513
+ */
514
+ async fetchArrayBuffer() {
515
+ const response = await this.fetch();
516
+ return await unmarshal(response, 'arrayBuffer');
228
517
  }
229
- }
230
- function jsonPost(body, headers){
231
- return jsonRequest('POST', body, headers);
232
- }
233
- function jsonPut(body, headers){
234
- return jsonRequest('PUT', body, headers);
235
- }
236
- function jsonPatch(body, headers){
237
- return jsonRequest('PATCH', body, headers);
238
518
  }
239
519
 
240
520
  class Storage {
@@ -388,10 +668,10 @@ AuthorizationCodeFlow.PKCE_AND_STATE_KEY = "state-and-verifier";
388
668
  class AuthorizationCodeFlowSession {
389
669
  static parseToken(token) {
390
670
  const [rawHeader, rawPayload, signature] = token.split(".");
391
- const ut8decoder = new TextDecoder("utf-8");
671
+ const utf8decoder = new TextDecoder("utf-8");
392
672
  return {
393
- header: JSON.parse(ut8decoder.decode(Base64.decode(rawHeader, Base64.STANDARD))),
394
- payload: JSON.parse(ut8decoder.decode(Base64.decode(rawPayload, Base64.STANDARD))),
673
+ header: JSON.parse(utf8decoder.decode(Base64.decode(rawHeader, Base64.STANDARD))),
674
+ payload: JSON.parse(utf8decoder.decode(Base64.decode(rawPayload, Base64.STANDARD))),
395
675
  signature: signature
396
676
  };
397
677
  }
@@ -419,7 +699,8 @@ class AuthorizationCodeFlowSession {
419
699
  ])
420
700
  });
421
701
  if (!response.ok) {
422
- throw new Error("Error:" + response.status + ": " + response.text());
702
+ const text = await response.text();
703
+ throw new Error("Error:" + response.status + ": " + text);
423
704
  }
424
705
  const token = await response.json();
425
706
  this.token = token;
@@ -459,18 +740,19 @@ class AuthorizationCodeFlowSession {
459
740
  }
460
741
 
461
742
  class AuthorizationCodeFlowInterceptor {
743
+ #session;
744
+ #gracePeriodBefore;
745
+ #gracePeriodAfter;
462
746
  constructor(session, gracePeriodBefore, gracePeriodAfter) {
463
- this.session = session;
464
- this.gracePeriodBefore = gracePeriodBefore || 2000;
465
- this.gracePeriodAfter = gracePeriodAfter || 30000;
747
+ this.#session = session;
748
+ this.#gracePeriodBefore = gracePeriodBefore || 2000;
749
+ this.#gracePeriodAfter = gracePeriodAfter || 30000;
466
750
  }
467
751
  async intercept(request, chain) {
468
- await this.session.refreshIf(this.gracePeriodBefore);
469
- const headers = new Headers(request.options.headers);
470
- headers.set("Authorization", this.session.bearerToken());
471
- request.options.headers = headers;
752
+ await this.#session.refreshIf(this.#gracePeriodBefore);
753
+ request.headers.set("Authorization", this.#session.bearerToken());
472
754
  const response = await chain.proceed(request);
473
- await this.session.refreshIf(this.gracePeriodAfter);
755
+ await this.#session.refreshIf(this.#gracePeriodAfter);
474
756
  return response;
475
757
  }
476
758
  }
@@ -922,8 +1204,6 @@ const ParsedElement = (conf) => {
922
1204
  return k;
923
1205
  };
924
1206
 
925
- /* global Infinity, CSS */
926
-
927
1207
  function flatten(obj, prefix) {
928
1208
  return Object.keys(obj).reduce((acc, k) => {
929
1209
  const pre = prefix.length ? prefix + '.' : '';
@@ -1081,7 +1361,7 @@ class Form extends ParsedElement() {
1081
1361
  if (!this.hasAttribute('scroll-on-error')) {
1082
1362
  return;
1083
1363
  }
1084
- const ys = Array.from(this.querySelectorAll(`[ful-validated-field]:has(.${Form.INVALID_CLASS}) ful-field-error`))
1364
+ const ys = Array.from(this.querySelectorAll(`ful-errors:not([hidden]), [ful-validated-field]:has(.${Form.INVALID_CLASS}) ful-field-error`))
1085
1365
  .map(el => el.parentElement ? el.parentElement : el)
1086
1366
  .map(el => el.getBoundingClientRect().y + window.scrollY);
1087
1367
  const miny = Math.min(...ys);
@@ -1344,5 +1624,5 @@ class Spinner extends ParsedElement({
1344
1624
  }
1345
1625
  }
1346
1626
 
1347
- export { Attributes, AuthorizationCodeFlow, AuthorizationCodeFlowInterceptor, AuthorizationCodeFlowSession, Base64, Deferred, ElementsRegistry, Failure, Form, Fragments, Hex, HttpClient, INPUT_TEMPLATE, Input, LightSlots, LocalStorage, Nodes, ParsedElement, RadioGroup, Select, SessionStorage, Spinner, TemplatesRegistry, VersionedStorage, elements, jsonPatch, jsonPost, jsonPut, jsonRequest, makeInputFragment, timing };
1627
+ export { Attributes, AuthorizationCodeFlow, AuthorizationCodeFlowInterceptor, AuthorizationCodeFlowSession, Base64, Deferred, ElementsRegistry, Failure, Form, Fragments, Hex, HttpClient, HttpClientError, INPUT_TEMPLATE, Input, LightSlots, LocalStorage, Nodes, ParsedElement, RadioGroup, Select, SessionStorage, Spinner, TemplatesRegistry, VersionedStorage, elements, makeInputFragment, timing };
1348
1628
  //# sourceMappingURL=ful.mjs.map