@bkazemi/verily 0.9.3 → 0.9.5
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/README.md +4 -2
- package/dist/browser/badge.css.d.ts +2 -0
- package/dist/browser/badge.css.js +2 -0
- package/dist/browser/badge.js +2 -66
- package/dist/browser/connect-dialog.css.d.ts +2 -0
- package/dist/browser/connect-dialog.css.js +2 -0
- package/dist/browser/connect-dialog.js +4 -24
- package/dist/browser/evidence-dialog.css.d.ts +2 -0
- package/dist/browser/evidence-dialog.css.js +2 -0
- package/dist/browser/evidence-dialog.d.ts +6 -1
- package/dist/browser/evidence-dialog.js +78 -110
- package/dist/browser/mark.css.d.ts +2 -0
- package/dist/browser/mark.css.js +2 -0
- package/dist/browser/mark.d.ts +1 -1
- package/dist/browser/mark.js +2 -6
- package/dist/server/index.js +12 -3
- package/dist/server/render.js +11 -9
- package/dist/server/style.css.d.ts +2 -0
- package/dist/server/style.css.js +2 -0
- package/dist/server/style.d.ts +1 -1
- package/dist/server/style.js +2 -441
- package/dist/verily.js +601 -205
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +8 -1
package/dist/verily.js
CHANGED
|
@@ -9825,6 +9825,9 @@ var Verily = (() => {
|
|
|
9825
9825
|
return attestation.hosted ? where : `${where} | Last checked ${when(attestation.confirmedAt)}`;
|
|
9826
9826
|
}
|
|
9827
9827
|
|
|
9828
|
+
// src/browser/badge.css.ts
|
|
9829
|
+
var badge_css_default = ":host {\n display: inline-block;\n max-width: 100%;\n vertical-align: middle;\n}\n* {\n box-sizing: border-box;\n}\n.badge,\n.peek {\n border: 1px solid var(--verily-border, #dce2e0);\n border-radius: 6px;\n background: var(--verily-surface, #fff);\n color: var(--verily-text, #202c29);\n font: var(--verily-font-size, 13px)/1.35\n var(--verily-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif);\n}\n.badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n max-width: 100%;\n padding: 3px 5px;\n text-decoration: none;\n}\nbutton.badge {\n margin: 0;\n cursor: pointer;\n}\na[href]:hover,\nbutton.badge:hover {\n background: var(--verily-hover, #f3f6f4);\n border-color: var(--verily-border, #dce2e0);\n}\n.badge:focus-visible {\n outline: 2px solid #357ce5;\n outline-offset: 2px;\n}\n.name {\n font-weight: 600;\n overflow-wrap: anywhere;\n min-width: 0;\n}\n.more {\n flex-shrink: 0;\n font-size: 11px;\n font-weight: 600;\n color: var(--verily-muted, #65726c);\n}\n.label {\n display: none;\n font-size: 11px;\n color: var(--verily-muted, #65726c);\n}\n.badge:hover .label,\n.badge:focus-within .label {\n display: inline;\n}\n.icon {\n display: grid;\n place-items: center;\n flex-shrink: 0;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n font-size: 12px;\n font-weight: 750;\n}\n.icon .glyph {\n display: block;\n width: 12px;\n height: 12px;\n}\n.mark {\n display: block;\n flex-shrink: 0;\n width: 20px;\n height: 20px;\n}\n.mark.pending {\n opacity: 0.45;\n}\n/* A dim ring where the account will go; it only spins where motion is welcome. */\n.spinner {\n flex-shrink: 0;\n width: 14px;\n height: 14px;\n border-radius: 50%;\n border: 2px solid currentColor;\n opacity: 0.3;\n}\n.divider {\n flex-shrink: 0;\n width: 1px;\n height: 12px;\n background: var(--verily-border, #dce2e0);\n}\n/* Several accounts, one to a row. The mark stays beside them and the rule runs their height. */\n.badge.stacked {\n align-items: stretch;\n padding: 5px 8px 5px 6px;\n text-align: left;\n}\n.stacked .mark {\n align-self: center;\n}\n.stacked .divider {\n height: auto;\n}\n.rows {\n display: grid;\n gap: 4px;\n min-width: 0;\n}\n.row {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n}\n/*\n * The accounts behind a short pill's count, opened beside it. Shut unless the browser\n * has it open as a popover, so one without popovers never shows it at all.\n */\n.peek {\n display: none;\n position: fixed;\n inset: auto;\n margin: 0;\n padding: 8px 10px;\n width: max-content;\n max-width: min(320px, calc(100vw - 16px));\n border-radius: 8px;\n box-shadow: 0 6px 20px rgba(0, 0, 0, 0.14);\n pointer-events: none;\n overflow: hidden;\n}\n/* A row taken out to fit the window: its own display would otherwise keep it showing. */\n.row[hidden] {\n display: none;\n}\n.peek:popover-open {\n display: block;\n}\n.peek .via {\n display: block;\n margin-top: 6px;\n font-size: 11px;\n color: var(--verily-muted, #65726c);\n}\n.provider {\n display: block;\n flex-shrink: 0;\n width: 14px;\n height: 14px;\n}\n.expired .icon {\n color: #815a12;\n background: #fbefce;\n}\n.revoked .icon,\n.retired .icon,\n.message .icon {\n color: #626d69;\n background: #edf0ee;\n}\n/* Nothing ran out and nothing wants attention: the holder chose this, so it is only quiet. */\n.retired .name {\n color: var(--verily-muted, #65726c);\n}\n.message {\n color: var(--verily-muted, #65726c);\n}\n.add {\n font-weight: 600;\n}\n@media (prefers-reduced-motion: no-preference) {\n a,\n button {\n transition:\n background 0.12s,\n border-color 0.12s;\n }\n /* The mark is drawn before the answer arrives, so it resolves rather than swaps. */\n .mark,\n .mark path {\n transition:\n opacity 0.18s ease,\n stroke 0.18s ease;\n }\n .spinner {\n border-top-color: transparent;\n opacity: 0.4;\n animation: verily-spin 0.7s linear infinite;\n }\n}\n@keyframes verily-spin {\n to {\n transform: rotate(360deg);\n }\n}\n";
|
|
9830
|
+
|
|
9828
9831
|
// src/marks.ts
|
|
9829
9832
|
var github = {
|
|
9830
9833
|
viewBox: "0 0 16 16",
|
|
@@ -9893,13 +9896,11 @@ var Verily = (() => {
|
|
|
9893
9896
|
check: { pathLength: "176", "stroke-dasharray": "108 176", "stroke-dashoffset": "-54" }
|
|
9894
9897
|
};
|
|
9895
9898
|
|
|
9899
|
+
// src/browser/mark.css.ts
|
|
9900
|
+
var mark_css_default = "@media (prefers-reduced-motion: no-preference) {\n .mark.current path:last-child {\n animation: verily-draw 0.8s cubic-bezier(0.65, 0, 0.35, 1) 0.1s backwards;\n }\n}\n@keyframes verily-draw {\n from {\n stroke-dasharray: 0 176;\n }\n to {\n stroke-dasharray: 108 176;\n }\n}\n";
|
|
9901
|
+
|
|
9896
9902
|
// src/browser/mark.ts
|
|
9897
|
-
var markStyles =
|
|
9898
|
-
@media (prefers-reduced-motion: no-preference) {
|
|
9899
|
-
.mark.current path:last-child { animation: verily-draw .8s cubic-bezier(.65, 0, .35, 1) .1s backwards; }
|
|
9900
|
-
}
|
|
9901
|
-
@keyframes verily-draw { from { stroke-dasharray: 0 176; } to { stroke-dasharray: 108 176; } }
|
|
9902
|
-
`;
|
|
9903
|
+
var markStyles = mark_css_default;
|
|
9903
9904
|
function paintMark(svg, tone) {
|
|
9904
9905
|
const colors = tones[tone];
|
|
9905
9906
|
svg.setAttribute("class", `mark ${tone}`);
|
|
@@ -9976,72 +9977,7 @@ var Verily = (() => {
|
|
|
9976
9977
|
}
|
|
9977
9978
|
|
|
9978
9979
|
// src/browser/badge.ts
|
|
9979
|
-
var styles =
|
|
9980
|
-
:host { display: inline-block; max-width: 100%; vertical-align: middle; }
|
|
9981
|
-
* { box-sizing: border-box; }
|
|
9982
|
-
.badge, .peek {
|
|
9983
|
-
border: 1px solid var(--verily-border, #dce2e0); border-radius: 6px;
|
|
9984
|
-
background: var(--verily-surface, #fff); color: var(--verily-text, #202c29);
|
|
9985
|
-
font: var(--verily-font-size, 13px)/1.35
|
|
9986
|
-
var(--verily-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif);
|
|
9987
|
-
}
|
|
9988
|
-
.badge {
|
|
9989
|
-
display: inline-flex; align-items: center; gap: 6px; max-width: 100%; padding: 3px 5px;
|
|
9990
|
-
text-decoration: none;
|
|
9991
|
-
}
|
|
9992
|
-
button.badge { margin: 0; cursor: pointer; }
|
|
9993
|
-
a[href]:hover, button.badge:hover { background: var(--verily-hover, #f3f6f4); border-color: var(--verily-border, #dce2e0); }
|
|
9994
|
-
.badge:focus-visible { outline: 2px solid #357ce5; outline-offset: 2px; }
|
|
9995
|
-
.name { font-weight: 600; overflow-wrap: anywhere; min-width: 0; }
|
|
9996
|
-
.more { flex-shrink: 0; font-size: 11px; font-weight: 600; color: var(--verily-muted, #65726c); }
|
|
9997
|
-
.label { display: none; font-size: 11px; color: var(--verily-muted, #65726c); }
|
|
9998
|
-
.badge:hover .label, .badge:focus-within .label { display: inline; }
|
|
9999
|
-
.icon { display: grid; place-items: center; flex-shrink: 0; width: 20px; height: 20px; border-radius: 50%; font-size: 12px; font-weight: 750; }
|
|
10000
|
-
.icon .glyph { display: block; width: 12px; height: 12px; }
|
|
10001
|
-
.mark { display: block; flex-shrink: 0; width: 20px; height: 20px; }
|
|
10002
|
-
.mark.pending { opacity: .45; }
|
|
10003
|
-
/* A dim ring where the account will go; it only spins where motion is welcome. */
|
|
10004
|
-
.spinner {
|
|
10005
|
-
flex-shrink: 0; width: 14px; height: 14px; border-radius: 50%;
|
|
10006
|
-
border: 2px solid currentColor; opacity: .3;
|
|
10007
|
-
}
|
|
10008
|
-
.divider { flex-shrink: 0; width: 1px; height: 12px; background: var(--verily-border, #dce2e0); }
|
|
10009
|
-
/* Several accounts, one to a row. The mark stays beside them and the rule runs their height. */
|
|
10010
|
-
.badge.stacked { align-items: stretch; padding: 5px 8px 5px 6px; text-align: left; }
|
|
10011
|
-
.stacked .mark { align-self: center; }
|
|
10012
|
-
.stacked .divider { height: auto; }
|
|
10013
|
-
.rows { display: grid; gap: 4px; min-width: 0; }
|
|
10014
|
-
.row { display: flex; align-items: center; gap: 6px; min-width: 0; }
|
|
10015
|
-
/*
|
|
10016
|
-
* The accounts behind a short pill's count, opened beside it. Shut unless the browser
|
|
10017
|
-
* has it open as a popover, so one without popovers never shows it at all.
|
|
10018
|
-
*/
|
|
10019
|
-
.peek {
|
|
10020
|
-
display: none; position: fixed; inset: auto; margin: 0; padding: 8px 10px;
|
|
10021
|
-
width: max-content; max-width: min(320px, calc(100vw - 16px));
|
|
10022
|
-
border-radius: 8px; box-shadow: 0 6px 20px rgba(0, 0, 0, .14); pointer-events: none;
|
|
10023
|
-
overflow: hidden;
|
|
10024
|
-
}
|
|
10025
|
-
/* A row taken out to fit the window: its own display would otherwise keep it showing. */
|
|
10026
|
-
.row[hidden] { display: none; }
|
|
10027
|
-
.peek:popover-open { display: block; }
|
|
10028
|
-
.peek .via { display: block; margin-top: 6px; font-size: 11px; color: var(--verily-muted, #65726c); }
|
|
10029
|
-
.provider { display: block; flex-shrink: 0; width: 14px; height: 14px; }
|
|
10030
|
-
.expired .icon { color: #815a12; background: #fbefce; }
|
|
10031
|
-
.revoked .icon, .retired .icon, .message .icon { color: #626d69; background: #edf0ee; }
|
|
10032
|
-
/* Nothing ran out and nothing wants attention: the holder chose this, so it is only quiet. */
|
|
10033
|
-
.retired .name { color: var(--verily-muted, #65726c); }
|
|
10034
|
-
.message { color: var(--verily-muted, #65726c); }
|
|
10035
|
-
.add { font-weight: 600; }
|
|
10036
|
-
@media (prefers-reduced-motion: no-preference) {
|
|
10037
|
-
a, button { transition: background .12s, border-color .12s; }
|
|
10038
|
-
/* The mark is drawn before the answer arrives, so it resolves rather than swaps. */
|
|
10039
|
-
.mark, .mark path { transition: opacity .18s ease, stroke .18s ease; }
|
|
10040
|
-
.spinner { border-top-color: transparent; opacity: .4; animation: verily-spin .7s linear infinite; }
|
|
10041
|
-
}
|
|
10042
|
-
@keyframes verily-spin { to { transform: rotate(360deg); } }
|
|
10043
|
-
${markStyles}
|
|
10044
|
-
`;
|
|
9980
|
+
var styles = badge_css_default + markStyles;
|
|
10045
9981
|
var sheet;
|
|
10046
9982
|
var frames = /* @__PURE__ */ new WeakMap();
|
|
10047
9983
|
var pendingKey = "\0pending";
|
|
@@ -10319,6 +10255,537 @@ var Verily = (() => {
|
|
|
10319
10255
|
return button2;
|
|
10320
10256
|
}
|
|
10321
10257
|
|
|
10258
|
+
// src/browser/evidence-dialog.css.ts
|
|
10259
|
+
var evidence_dialog_css_default = `* {
|
|
10260
|
+
box-sizing: border-box;
|
|
10261
|
+
}
|
|
10262
|
+
dialog {
|
|
10263
|
+
width: min(460px, calc(100vw - 32px));
|
|
10264
|
+
max-height: calc(100dvh - 40px);
|
|
10265
|
+
margin: auto;
|
|
10266
|
+
padding: 0;
|
|
10267
|
+
overflow: hidden;
|
|
10268
|
+
border: 1px solid #dce2de;
|
|
10269
|
+
border-radius: 16px;
|
|
10270
|
+
background: #fff;
|
|
10271
|
+
color: #23312b;
|
|
10272
|
+
box-shadow: 0 24px 90px #10201935;
|
|
10273
|
+
font:
|
|
10274
|
+
13px/1.6 system-ui,
|
|
10275
|
+
sans-serif;
|
|
10276
|
+
}
|
|
10277
|
+
/* The pane scrolls inside the dialog, which clips its scrollbar to the rounded corners.
|
|
10278
|
+
Contain keeps a scroll past its end from scrolling the page behind. */
|
|
10279
|
+
dialog[open] {
|
|
10280
|
+
display: flex;
|
|
10281
|
+
flex-direction: column;
|
|
10282
|
+
}
|
|
10283
|
+
.pane {
|
|
10284
|
+
min-height: 0;
|
|
10285
|
+
padding: 24px;
|
|
10286
|
+
overflow-y: auto;
|
|
10287
|
+
overscroll-behavior: contain;
|
|
10288
|
+
}
|
|
10289
|
+
dialog::backdrop {
|
|
10290
|
+
background: #15271f66;
|
|
10291
|
+
}
|
|
10292
|
+
header {
|
|
10293
|
+
display: flex;
|
|
10294
|
+
align-items: center;
|
|
10295
|
+
justify-content: space-between;
|
|
10296
|
+
gap: 16px;
|
|
10297
|
+
margin-bottom: 20px;
|
|
10298
|
+
}
|
|
10299
|
+
h2 {
|
|
10300
|
+
margin: 0;
|
|
10301
|
+
font-size: 18px;
|
|
10302
|
+
font-weight: 650;
|
|
10303
|
+
letter-spacing: -0.3px;
|
|
10304
|
+
}
|
|
10305
|
+
button {
|
|
10306
|
+
width: 32px;
|
|
10307
|
+
height: 32px;
|
|
10308
|
+
border: 1px solid #dce2de;
|
|
10309
|
+
border-radius: 8px;
|
|
10310
|
+
background: #fff;
|
|
10311
|
+
color: #52645a;
|
|
10312
|
+
font:
|
|
10313
|
+
20px system-ui,
|
|
10314
|
+
sans-serif;
|
|
10315
|
+
cursor: pointer;
|
|
10316
|
+
}
|
|
10317
|
+
button:hover {
|
|
10318
|
+
background: #f2f5f1;
|
|
10319
|
+
}
|
|
10320
|
+
.icon {
|
|
10321
|
+
display: grid;
|
|
10322
|
+
place-items: center;
|
|
10323
|
+
padding: 0;
|
|
10324
|
+
}
|
|
10325
|
+
.icon svg {
|
|
10326
|
+
width: 16px;
|
|
10327
|
+
height: 16px;
|
|
10328
|
+
}
|
|
10329
|
+
.title {
|
|
10330
|
+
display: flex;
|
|
10331
|
+
align-items: center;
|
|
10332
|
+
gap: 6px;
|
|
10333
|
+
min-width: 0;
|
|
10334
|
+
}
|
|
10335
|
+
.all {
|
|
10336
|
+
display: grid;
|
|
10337
|
+
place-items: center;
|
|
10338
|
+
width: 28px;
|
|
10339
|
+
height: 28px;
|
|
10340
|
+
border-radius: 8px;
|
|
10341
|
+
color: #52645a;
|
|
10342
|
+
}
|
|
10343
|
+
.all:hover {
|
|
10344
|
+
background: #f2f5f1;
|
|
10345
|
+
}
|
|
10346
|
+
.all svg {
|
|
10347
|
+
width: 16px;
|
|
10348
|
+
height: 16px;
|
|
10349
|
+
}
|
|
10350
|
+
a {
|
|
10351
|
+
color: #245f43;
|
|
10352
|
+
text-underline-offset: 3px;
|
|
10353
|
+
overflow-wrap: anywhere;
|
|
10354
|
+
}
|
|
10355
|
+
a:focus-visible,
|
|
10356
|
+
button:focus-visible,
|
|
10357
|
+
summary:focus-visible {
|
|
10358
|
+
outline: 2px solid #357ce5;
|
|
10359
|
+
outline-offset: 3px;
|
|
10360
|
+
}
|
|
10361
|
+
/* An element given its own display would otherwise go on showing while hidden. */
|
|
10362
|
+
[hidden] {
|
|
10363
|
+
display: none !important;
|
|
10364
|
+
}
|
|
10365
|
+
.summary {
|
|
10366
|
+
display: flex;
|
|
10367
|
+
align-items: center;
|
|
10368
|
+
gap: 8px;
|
|
10369
|
+
margin-top: 16px;
|
|
10370
|
+
}
|
|
10371
|
+
.mark {
|
|
10372
|
+
width: 36px;
|
|
10373
|
+
height: 36px;
|
|
10374
|
+
flex-shrink: 0;
|
|
10375
|
+
}
|
|
10376
|
+
.provider {
|
|
10377
|
+
width: 14px;
|
|
10378
|
+
height: 14px;
|
|
10379
|
+
}
|
|
10380
|
+
.state {
|
|
10381
|
+
font-size: 14px;
|
|
10382
|
+
font-weight: 650;
|
|
10383
|
+
line-height: 1.4;
|
|
10384
|
+
}
|
|
10385
|
+
.muted {
|
|
10386
|
+
color: #6b786f;
|
|
10387
|
+
font-size: 12px;
|
|
10388
|
+
}
|
|
10389
|
+
.account {
|
|
10390
|
+
position: relative;
|
|
10391
|
+
}
|
|
10392
|
+
.veiled > :not(.checking) {
|
|
10393
|
+
filter: blur(4px);
|
|
10394
|
+
opacity: 0.55;
|
|
10395
|
+
user-select: none;
|
|
10396
|
+
}
|
|
10397
|
+
.checking {
|
|
10398
|
+
position: absolute;
|
|
10399
|
+
inset: 0;
|
|
10400
|
+
display: flex;
|
|
10401
|
+
align-items: center;
|
|
10402
|
+
justify-content: center;
|
|
10403
|
+
gap: 8px;
|
|
10404
|
+
color: #23312b;
|
|
10405
|
+
font-size: 13px;
|
|
10406
|
+
font-weight: 600;
|
|
10407
|
+
}
|
|
10408
|
+
.spinner {
|
|
10409
|
+
width: 14px;
|
|
10410
|
+
height: 14px;
|
|
10411
|
+
border: 2px solid currentColor;
|
|
10412
|
+
border-right-color: transparent;
|
|
10413
|
+
border-radius: 50%;
|
|
10414
|
+
animation: spin 0.7s linear infinite;
|
|
10415
|
+
}
|
|
10416
|
+
@keyframes spin {
|
|
10417
|
+
to {
|
|
10418
|
+
transform: rotate(360deg);
|
|
10419
|
+
}
|
|
10420
|
+
}
|
|
10421
|
+
@media (prefers-reduced-motion: reduce) {
|
|
10422
|
+
.spinner {
|
|
10423
|
+
animation: none;
|
|
10424
|
+
}
|
|
10425
|
+
}
|
|
10426
|
+
/* The "signed" pill after the verifier's name, one size smaller than the line it sits on. */
|
|
10427
|
+
.summary .signed {
|
|
10428
|
+
display: inline-block;
|
|
10429
|
+
margin-left: 5px;
|
|
10430
|
+
padding: 0 6px;
|
|
10431
|
+
border: 1px solid #cfdcd3;
|
|
10432
|
+
border-radius: 999px;
|
|
10433
|
+
font-size: 10px;
|
|
10434
|
+
font-weight: 550;
|
|
10435
|
+
line-height: 1.3;
|
|
10436
|
+
text-decoration: none;
|
|
10437
|
+
vertical-align: 1px;
|
|
10438
|
+
}
|
|
10439
|
+
.summary a.signed:hover {
|
|
10440
|
+
background: #f2f5f1;
|
|
10441
|
+
}
|
|
10442
|
+
.summary .signed.bad {
|
|
10443
|
+
border-color: #b3261e;
|
|
10444
|
+
color: #b3261e;
|
|
10445
|
+
font-weight: 650;
|
|
10446
|
+
cursor: help;
|
|
10447
|
+
}
|
|
10448
|
+
.caution {
|
|
10449
|
+
display: inline-block;
|
|
10450
|
+
margin-left: 3px;
|
|
10451
|
+
color: #a15c00;
|
|
10452
|
+
vertical-align: -1.5px;
|
|
10453
|
+
}
|
|
10454
|
+
.caution svg {
|
|
10455
|
+
display: block;
|
|
10456
|
+
width: 10px;
|
|
10457
|
+
height: 10px;
|
|
10458
|
+
}
|
|
10459
|
+
.account {
|
|
10460
|
+
padding: 14px 16px;
|
|
10461
|
+
border: 1px solid #e0e6df;
|
|
10462
|
+
border-radius: 10px;
|
|
10463
|
+
margin-top: 12px;
|
|
10464
|
+
}
|
|
10465
|
+
.account h3 {
|
|
10466
|
+
display: flex;
|
|
10467
|
+
align-items: center;
|
|
10468
|
+
gap: 6px;
|
|
10469
|
+
margin: 0 0 3px;
|
|
10470
|
+
color: #6b786f;
|
|
10471
|
+
font-size: 11px;
|
|
10472
|
+
font-weight: 550;
|
|
10473
|
+
}
|
|
10474
|
+
.account a,
|
|
10475
|
+
.account strong {
|
|
10476
|
+
font-weight: 650;
|
|
10477
|
+
font-size: 14px;
|
|
10478
|
+
}
|
|
10479
|
+
/* The account's own name carries that weight; a link inside a line of prose does not. */
|
|
10480
|
+
.summary a,
|
|
10481
|
+
.method a,
|
|
10482
|
+
.additional a {
|
|
10483
|
+
font: inherit;
|
|
10484
|
+
}
|
|
10485
|
+
.reference {
|
|
10486
|
+
margin-top: 2px;
|
|
10487
|
+
}
|
|
10488
|
+
/* A fingerprint in fours: it breaks between groups, and copies as one unbroken word. */
|
|
10489
|
+
.fingerprint {
|
|
10490
|
+
font-family: ui-monospace, monospace;
|
|
10491
|
+
text-wrap: balance;
|
|
10492
|
+
}
|
|
10493
|
+
.fingerprint span {
|
|
10494
|
+
display: inline-block;
|
|
10495
|
+
margin-right: 0.5ch;
|
|
10496
|
+
}
|
|
10497
|
+
.method {
|
|
10498
|
+
margin-top: 8px;
|
|
10499
|
+
}
|
|
10500
|
+
/* In the corner the heading leaves empty, apart from everything that was checked. */
|
|
10501
|
+
.listing {
|
|
10502
|
+
position: absolute;
|
|
10503
|
+
top: 12px;
|
|
10504
|
+
right: 14px;
|
|
10505
|
+
padding: 1px 8px;
|
|
10506
|
+
border: 1px solid #e0e6df;
|
|
10507
|
+
border-radius: 999px;
|
|
10508
|
+
color: #6b786f;
|
|
10509
|
+
font-size: 11px;
|
|
10510
|
+
font-weight: 550;
|
|
10511
|
+
}
|
|
10512
|
+
.listing.preferred {
|
|
10513
|
+
border-color: #245f43;
|
|
10514
|
+
color: #245f43;
|
|
10515
|
+
}
|
|
10516
|
+
/* Quiet, as its pill is: the surface and the name step back, and the controls do not. */
|
|
10517
|
+
.account.retired {
|
|
10518
|
+
background: #f6f8f5;
|
|
10519
|
+
}
|
|
10520
|
+
.account.retired .identity > a,
|
|
10521
|
+
.account.retired .identity > strong,
|
|
10522
|
+
.account.retired .named > a,
|
|
10523
|
+
.account.retired .named > strong {
|
|
10524
|
+
color: #6b786f;
|
|
10525
|
+
}
|
|
10526
|
+
/* The name, then a dot and the account's creation date. The date wraps under a long name. */
|
|
10527
|
+
/* Clipped 4px left of the text, which hides the dot when the date wraps to a new line. */
|
|
10528
|
+
.named {
|
|
10529
|
+
display: flex;
|
|
10530
|
+
flex-wrap: wrap;
|
|
10531
|
+
align-items: baseline;
|
|
10532
|
+
gap: 0 14px;
|
|
10533
|
+
margin-left: -4px;
|
|
10534
|
+
padding-left: 4px;
|
|
10535
|
+
overflow-x: clip;
|
|
10536
|
+
}
|
|
10537
|
+
.since {
|
|
10538
|
+
position: relative;
|
|
10539
|
+
white-space: nowrap;
|
|
10540
|
+
}
|
|
10541
|
+
/* The dot sits in the gap before the date. */
|
|
10542
|
+
.since::before {
|
|
10543
|
+
content: '\xB7';
|
|
10544
|
+
position: absolute;
|
|
10545
|
+
left: -7px;
|
|
10546
|
+
transform: translateX(-50%);
|
|
10547
|
+
}
|
|
10548
|
+
.account.retired .mark {
|
|
10549
|
+
opacity: 0.45;
|
|
10550
|
+
}
|
|
10551
|
+
.group {
|
|
10552
|
+
margin: 20px 0 0;
|
|
10553
|
+
color: #6b786f;
|
|
10554
|
+
font-size: 11px;
|
|
10555
|
+
font-weight: 550;
|
|
10556
|
+
}
|
|
10557
|
+
summary.group {
|
|
10558
|
+
display: flex;
|
|
10559
|
+
align-items: center;
|
|
10560
|
+
gap: 4px;
|
|
10561
|
+
width: fit-content;
|
|
10562
|
+
border-radius: 4px;
|
|
10563
|
+
list-style: none;
|
|
10564
|
+
cursor: pointer;
|
|
10565
|
+
}
|
|
10566
|
+
summary::-webkit-details-marker {
|
|
10567
|
+
display: none;
|
|
10568
|
+
}
|
|
10569
|
+
.fold {
|
|
10570
|
+
display: flex;
|
|
10571
|
+
align-items: center;
|
|
10572
|
+
gap: 4px;
|
|
10573
|
+
width: auto;
|
|
10574
|
+
height: auto;
|
|
10575
|
+
padding: 2px 8px 2px 4px;
|
|
10576
|
+
margin-left: -4px;
|
|
10577
|
+
border: 0;
|
|
10578
|
+
background: none;
|
|
10579
|
+
font:
|
|
10580
|
+
550 12px/1.6 system-ui,
|
|
10581
|
+
sans-serif;
|
|
10582
|
+
}
|
|
10583
|
+
.fold svg,
|
|
10584
|
+
summary svg {
|
|
10585
|
+
width: 12px;
|
|
10586
|
+
height: 12px;
|
|
10587
|
+
}
|
|
10588
|
+
.fold[aria-expanded='true'] svg,
|
|
10589
|
+
details[open] > summary svg {
|
|
10590
|
+
transform: rotate(90deg);
|
|
10591
|
+
}
|
|
10592
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
10593
|
+
.fold svg,
|
|
10594
|
+
summary svg {
|
|
10595
|
+
transition: transform 0.15s;
|
|
10596
|
+
}
|
|
10597
|
+
}
|
|
10598
|
+
/* The fold and what the holder may do share a line, until a question needs the whole of it. */
|
|
10599
|
+
.bar {
|
|
10600
|
+
display: flex;
|
|
10601
|
+
align-items: center;
|
|
10602
|
+
flex-wrap: wrap;
|
|
10603
|
+
gap: 8px;
|
|
10604
|
+
margin-top: 10px;
|
|
10605
|
+
}
|
|
10606
|
+
.account .bar .row {
|
|
10607
|
+
margin: 0 0 0 auto;
|
|
10608
|
+
}
|
|
10609
|
+
.additional {
|
|
10610
|
+
margin-top: 2px;
|
|
10611
|
+
padding-left: 12px;
|
|
10612
|
+
}
|
|
10613
|
+
.joiner {
|
|
10614
|
+
display: block;
|
|
10615
|
+
width: 20px;
|
|
10616
|
+
height: 20px;
|
|
10617
|
+
margin: 8px auto -4px;
|
|
10618
|
+
color: #90a096;
|
|
10619
|
+
}
|
|
10620
|
+
dl {
|
|
10621
|
+
margin: 16px 0 0;
|
|
10622
|
+
padding-top: 12px;
|
|
10623
|
+
border-top: 1px solid #e5e9e3;
|
|
10624
|
+
display: grid;
|
|
10625
|
+
grid-template-columns: auto 1fr;
|
|
10626
|
+
gap: 5px 16px;
|
|
10627
|
+
font-size: 11px;
|
|
10628
|
+
}
|
|
10629
|
+
dt {
|
|
10630
|
+
color: #6b786f;
|
|
10631
|
+
}
|
|
10632
|
+
dd {
|
|
10633
|
+
margin: 0;
|
|
10634
|
+
text-align: right;
|
|
10635
|
+
overflow-wrap: anywhere;
|
|
10636
|
+
}
|
|
10637
|
+
.explanation {
|
|
10638
|
+
margin-top: 16px;
|
|
10639
|
+
}
|
|
10640
|
+
.action {
|
|
10641
|
+
width: auto;
|
|
10642
|
+
height: auto;
|
|
10643
|
+
padding: 9px 14px;
|
|
10644
|
+
font:
|
|
10645
|
+
600 13px/1.3 system-ui,
|
|
10646
|
+
sans-serif;
|
|
10647
|
+
color: #23312b;
|
|
10648
|
+
text-align: left;
|
|
10649
|
+
}
|
|
10650
|
+
.action.primary {
|
|
10651
|
+
border-color: #245f43;
|
|
10652
|
+
background: #245f43;
|
|
10653
|
+
color: #fff;
|
|
10654
|
+
}
|
|
10655
|
+
.action.primary:hover {
|
|
10656
|
+
background: #1d4f37;
|
|
10657
|
+
}
|
|
10658
|
+
.action:disabled {
|
|
10659
|
+
opacity: 0.6;
|
|
10660
|
+
cursor: progress;
|
|
10661
|
+
}
|
|
10662
|
+
.action.danger:hover {
|
|
10663
|
+
border-color: #b3261e;
|
|
10664
|
+
background: #fdecea;
|
|
10665
|
+
color: #b3261e;
|
|
10666
|
+
}
|
|
10667
|
+
.row {
|
|
10668
|
+
display: flex;
|
|
10669
|
+
justify-content: end;
|
|
10670
|
+
gap: 8px;
|
|
10671
|
+
margin-top: 16px;
|
|
10672
|
+
}
|
|
10673
|
+
.account .row {
|
|
10674
|
+
align-items: center;
|
|
10675
|
+
justify-content: start;
|
|
10676
|
+
flex-wrap: wrap;
|
|
10677
|
+
margin-top: 12px;
|
|
10678
|
+
}
|
|
10679
|
+
.account .action {
|
|
10680
|
+
padding: 5px 10px;
|
|
10681
|
+
font-size: 12px;
|
|
10682
|
+
}
|
|
10683
|
+
.account .action.dots {
|
|
10684
|
+
display: grid;
|
|
10685
|
+
place-items: center;
|
|
10686
|
+
align-self: stretch;
|
|
10687
|
+
width: 30px;
|
|
10688
|
+
padding: 0;
|
|
10689
|
+
}
|
|
10690
|
+
.dots svg {
|
|
10691
|
+
width: 16px;
|
|
10692
|
+
height: 16px;
|
|
10693
|
+
}
|
|
10694
|
+
/* Placed under its button each time it opens, above the dialog and clipped by none of it. */
|
|
10695
|
+
.menu {
|
|
10696
|
+
position: fixed;
|
|
10697
|
+
inset: auto;
|
|
10698
|
+
margin: 0;
|
|
10699
|
+
min-width: 170px;
|
|
10700
|
+
padding: 6px;
|
|
10701
|
+
border: 1px solid #dce2de;
|
|
10702
|
+
border-radius: 10px;
|
|
10703
|
+
background: #fff;
|
|
10704
|
+
color: #23312b;
|
|
10705
|
+
box-shadow: 0 12px 40px #10201930;
|
|
10706
|
+
}
|
|
10707
|
+
.menu:popover-open {
|
|
10708
|
+
display: grid;
|
|
10709
|
+
}
|
|
10710
|
+
.account .menu .action {
|
|
10711
|
+
border: 0;
|
|
10712
|
+
border-radius: 6px;
|
|
10713
|
+
padding: 6px 10px;
|
|
10714
|
+
font-weight: 550;
|
|
10715
|
+
}
|
|
10716
|
+
.menu .danger {
|
|
10717
|
+
color: #b3261e;
|
|
10718
|
+
}
|
|
10719
|
+
.menu hr {
|
|
10720
|
+
width: 100%;
|
|
10721
|
+
margin: 4px 0;
|
|
10722
|
+
border: 0;
|
|
10723
|
+
border-top: 1px solid #e5e9e3;
|
|
10724
|
+
}
|
|
10725
|
+
footer {
|
|
10726
|
+
display: flex;
|
|
10727
|
+
align-items: center;
|
|
10728
|
+
justify-content: start;
|
|
10729
|
+
gap: 6px;
|
|
10730
|
+
margin: 20px 0 -8px;
|
|
10731
|
+
color: #9aa9a0;
|
|
10732
|
+
font-size: 11px;
|
|
10733
|
+
}
|
|
10734
|
+
footer a {
|
|
10735
|
+
display: flex;
|
|
10736
|
+
color: inherit;
|
|
10737
|
+
}
|
|
10738
|
+
.logo {
|
|
10739
|
+
display: block;
|
|
10740
|
+
height: 13px;
|
|
10741
|
+
}
|
|
10742
|
+
/* Four or more accounts on a wide screen: two equal cards to a row. */
|
|
10743
|
+
@media (min-width: 960px) {
|
|
10744
|
+
dialog.many {
|
|
10745
|
+
width: min(900px, calc(100vw - 32px));
|
|
10746
|
+
}
|
|
10747
|
+
dialog.many .tiles {
|
|
10748
|
+
display: grid;
|
|
10749
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
10750
|
+
gap: 12px;
|
|
10751
|
+
margin-top: 12px;
|
|
10752
|
+
}
|
|
10753
|
+
/* Each card is three rows of the grid: who, its verdict, and the rest. A row is as tall as
|
|
10754
|
+
the taller card's part, so the verdicts and details of neighbouring cards line up. */
|
|
10755
|
+
dialog.many .tiles > .account {
|
|
10756
|
+
display: grid;
|
|
10757
|
+
grid-row: span 3;
|
|
10758
|
+
grid-template-rows: subgrid;
|
|
10759
|
+
row-gap: 0;
|
|
10760
|
+
margin-top: 0;
|
|
10761
|
+
}
|
|
10762
|
+
/* The dates sit at the foot of the third part, so they line up too. */
|
|
10763
|
+
dialog.many .tiles .rest {
|
|
10764
|
+
display: flex;
|
|
10765
|
+
flex-direction: column;
|
|
10766
|
+
}
|
|
10767
|
+
dialog.many .tiles .rest > dl {
|
|
10768
|
+
margin-top: auto;
|
|
10769
|
+
}
|
|
10770
|
+
dialog.many .tiles .rest > :has(+ dl) {
|
|
10771
|
+
margin-bottom: 16px;
|
|
10772
|
+
}
|
|
10773
|
+
/* The site's card is one tile wide, centred over the two columns. */
|
|
10774
|
+
dialog.many .local {
|
|
10775
|
+
width: calc(50% - 6px);
|
|
10776
|
+
margin-inline: auto;
|
|
10777
|
+
text-align: center;
|
|
10778
|
+
}
|
|
10779
|
+
dialog.many .local h3,
|
|
10780
|
+
dialog.many .local .named {
|
|
10781
|
+
justify-content: center;
|
|
10782
|
+
}
|
|
10783
|
+
dialog.many .local .additional {
|
|
10784
|
+
padding-left: 0;
|
|
10785
|
+
}
|
|
10786
|
+
}
|
|
10787
|
+
`;
|
|
10788
|
+
|
|
10322
10789
|
// src/browser/signed.ts
|
|
10323
10790
|
var checks = /* @__PURE__ */ new Map();
|
|
10324
10791
|
var published = /* @__PURE__ */ new Map();
|
|
@@ -10520,7 +10987,7 @@ ${claims(evidence)}`;
|
|
|
10520
10987
|
}
|
|
10521
10988
|
|
|
10522
10989
|
// src/version.ts
|
|
10523
|
-
var version = "v0.9.
|
|
10990
|
+
var version = "v0.9.5";
|
|
10524
10991
|
|
|
10525
10992
|
// src/browser/evidence-dialog.ts
|
|
10526
10993
|
function stampLink() {
|
|
@@ -10529,104 +10996,29 @@ ${claims(evidence)}`;
|
|
|
10529
10996
|
return link;
|
|
10530
10997
|
}
|
|
10531
10998
|
var openDialogs = /* @__PURE__ */ new WeakMap();
|
|
10532
|
-
var
|
|
10533
|
-
|
|
10534
|
-
|
|
10535
|
-
|
|
10536
|
-
|
|
10537
|
-
|
|
10538
|
-
|
|
10539
|
-
|
|
10540
|
-
|
|
10541
|
-
|
|
10542
|
-
|
|
10543
|
-
|
|
10544
|
-
|
|
10545
|
-
|
|
10546
|
-
|
|
10547
|
-
|
|
10548
|
-
|
|
10549
|
-
|
|
10550
|
-
|
|
10551
|
-
|
|
10552
|
-
|
|
10553
|
-
|
|
10554
|
-
|
|
10555
|
-
.provider { width: 14px; height: 14px; }
|
|
10556
|
-
.state { font-size: 14px; font-weight: 650; line-height: 1.4; }
|
|
10557
|
-
.muted { color: #6b786f; font-size: 12px; }
|
|
10558
|
-
.account { position: relative; }
|
|
10559
|
-
.veiled > :not(.checking) { filter: blur(4px); opacity: .55; user-select: none; }
|
|
10560
|
-
.checking { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: 8px; color: #23312b; font-size: 13px; font-weight: 600; }
|
|
10561
|
-
.spinner { width: 14px; height: 14px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: spin .7s linear infinite; }
|
|
10562
|
-
@keyframes spin { to { transform: rotate(360deg); } }
|
|
10563
|
-
@media (prefers-reduced-motion: reduce) { .spinner { animation: none; } }
|
|
10564
|
-
/* The "signed" pill after the verifier's name, one size smaller than the line it sits on. */
|
|
10565
|
-
.summary .signed { display: inline-block; margin-left: 5px; padding: 0 6px; border: 1px solid #cfdcd3; border-radius: 999px; font-size: 10px; font-weight: 550; line-height: 1.3; text-decoration: none; vertical-align: 1px; }
|
|
10566
|
-
.summary a.signed:hover { background: #f2f5f1; }
|
|
10567
|
-
.summary .signed.bad { border-color: #b3261e; color: #b3261e; font-weight: 650; cursor: help; }
|
|
10568
|
-
.caution { display: inline-block; margin-left: 3px; color: #a15c00; vertical-align: -1.5px; }
|
|
10569
|
-
.caution svg { display: block; width: 10px; height: 10px; }
|
|
10570
|
-
.account { padding: 14px 16px; border: 1px solid #e0e6df; border-radius: 10px; margin-top: 12px; }
|
|
10571
|
-
.account h3 { display: flex; align-items: center; gap: 6px; margin: 0 0 3px; color: #6b786f; font-size: 11px; font-weight: 550; }
|
|
10572
|
-
.account a, .account strong { font-weight: 650; font-size: 14px; }
|
|
10573
|
-
/* The account's own name carries that weight; a link inside a line of prose does not. */
|
|
10574
|
-
.summary a, .method a, .additional a { font: inherit; }
|
|
10575
|
-
.reference { margin-top: 2px; }
|
|
10576
|
-
/* A fingerprint in fours: it breaks between groups, and copies as one unbroken word. */
|
|
10577
|
-
.fingerprint { font-family: ui-monospace, monospace; text-wrap: balance; }
|
|
10578
|
-
.fingerprint span { display: inline-block; margin-right: .5ch; }
|
|
10579
|
-
.method { margin-top: 8px; }
|
|
10580
|
-
/* In the corner the heading leaves empty, apart from everything that was checked. */
|
|
10581
|
-
.listing { position: absolute; top: 12px; right: 14px; padding: 1px 8px; border: 1px solid #e0e6df; border-radius: 999px; color: #6b786f; font-size: 11px; font-weight: 550; }
|
|
10582
|
-
.listing.preferred { border-color: #245f43; color: #245f43; }
|
|
10583
|
-
/* Quiet, as its pill is: the surface and the name step back, and the controls do not. */
|
|
10584
|
-
.account.retired { background: #f6f8f5; }
|
|
10585
|
-
.account.retired > a, .account.retired > strong, .account.retired > .named > a, .account.retired > .named > strong { color: #6b786f; }
|
|
10586
|
-
/* The name, then a dot and the account's creation date. The date wraps under a long name. */
|
|
10587
|
-
/* Clipped 4px left of the text, which hides the dot when the date wraps to a new line. */
|
|
10588
|
-
.named { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 14px; margin-left: -4px; padding-left: 4px; overflow-x: clip; }
|
|
10589
|
-
.since { position: relative; white-space: nowrap; }
|
|
10590
|
-
/* The dot sits in the gap before the date. */
|
|
10591
|
-
.since::before { content: "\xB7"; position: absolute; left: -7px; transform: translateX(-50%); }
|
|
10592
|
-
.account.retired .mark { opacity: .45; }
|
|
10593
|
-
.group { margin: 20px 0 0; color: #6b786f; font-size: 11px; font-weight: 550; }
|
|
10594
|
-
summary.group { display: flex; align-items: center; gap: 4px; width: fit-content; border-radius: 4px; list-style: none; cursor: pointer; }
|
|
10595
|
-
summary::-webkit-details-marker { display: none; }
|
|
10596
|
-
.fold { display: flex; align-items: center; gap: 4px; width: auto; height: auto; padding: 2px 8px 2px 4px; margin-left: -4px; border: 0; background: none; font: 550 12px/1.6 system-ui, sans-serif; }
|
|
10597
|
-
.fold svg, summary svg { width: 12px; height: 12px; }
|
|
10598
|
-
.fold[aria-expanded="true"] svg, details[open] > summary svg { transform: rotate(90deg); }
|
|
10599
|
-
@media (prefers-reduced-motion: no-preference) { .fold svg, summary svg { transition: transform .15s; } }
|
|
10600
|
-
/* The fold and what the holder may do share a line, until a question needs the whole of it. */
|
|
10601
|
-
.bar { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
|
|
10602
|
-
.account .bar .row { margin: 0 0 0 auto; }
|
|
10603
|
-
.additional { margin-top: 2px; padding-left: 12px; }
|
|
10604
|
-
.joiner { display: block; width: 20px; height: 20px; margin: 8px auto -4px; color: #90a096; }
|
|
10605
|
-
dl { margin: 16px 0 0; padding-top: 12px; border-top: 1px solid #e5e9e3; display: grid; grid-template-columns: auto 1fr; gap: 5px 16px; font-size: 11px; }
|
|
10606
|
-
dt { color: #6b786f; }
|
|
10607
|
-
dd { margin: 0; text-align: right; overflow-wrap: anywhere; }
|
|
10608
|
-
.explanation { margin-top: 16px; }
|
|
10609
|
-
.action { width: auto; height: auto; padding: 9px 14px; font: 600 13px/1.3 system-ui, sans-serif; color: #23312b; text-align: left; }
|
|
10610
|
-
.action.primary { border-color: #245f43; background: #245f43; color: #fff; }
|
|
10611
|
-
.action.primary:hover { background: #1d4f37; }
|
|
10612
|
-
.action:disabled { opacity: .6; cursor: progress; }
|
|
10613
|
-
.action.danger:hover { border-color: #b3261e; background: #fdecea; color: #b3261e; }
|
|
10614
|
-
.row { display: flex; justify-content: end; gap: 8px; margin-top: 16px; }
|
|
10615
|
-
.account .row { align-items: center; justify-content: start; flex-wrap: wrap; margin-top: 12px; }
|
|
10616
|
-
.account .action { padding: 5px 10px; font-size: 12px; }
|
|
10617
|
-
.account .action.dots { display: grid; place-items: center; align-self: stretch; width: 30px; padding: 0; }
|
|
10618
|
-
.dots svg { width: 16px; height: 16px; }
|
|
10619
|
-
/* Placed under its button each time it opens, above the dialog and clipped by none of it. */
|
|
10620
|
-
.menu { position: fixed; inset: auto; margin: 0; min-width: 170px; padding: 6px; border: 1px solid #dce2de; border-radius: 10px; background: #fff; color: #23312b; box-shadow: 0 12px 40px #10201930; }
|
|
10621
|
-
.menu:popover-open { display: grid; }
|
|
10622
|
-
.account .menu .action { border: 0; border-radius: 6px; padding: 6px 10px; font-weight: 550; }
|
|
10623
|
-
.menu .danger { color: #b3261e; }
|
|
10624
|
-
.menu hr { width: 100%; margin: 4px 0; border: 0; border-top: 1px solid #e5e9e3; }
|
|
10625
|
-
footer { display: flex; align-items: center; justify-content: start; gap: 6px; margin: 20px 0 -8px; color: #9aa9a0; font-size: 11px; }
|
|
10626
|
-
footer a { display: flex; color: inherit; }
|
|
10627
|
-
.logo { display: block; height: 13px; }
|
|
10628
|
-
${markStyles}
|
|
10629
|
-
`;
|
|
10999
|
+
var holds = 0;
|
|
11000
|
+
var release = () => {
|
|
11001
|
+
};
|
|
11002
|
+
function holdPage(dialog) {
|
|
11003
|
+
if (holds++ === 0) {
|
|
11004
|
+
const { style, clientWidth } = document.documentElement;
|
|
11005
|
+
const held = ["overflow-x", "overflow-y", "scrollbar-gutter"];
|
|
11006
|
+
const saved = held.map((name) => [
|
|
11007
|
+
style.getPropertyValue(name),
|
|
11008
|
+
style.getPropertyPriority(name)
|
|
11009
|
+
]);
|
|
11010
|
+
if (innerWidth > clientWidth) style.setProperty("scrollbar-gutter", "stable", "important");
|
|
11011
|
+
style.setProperty("overflow-x", "hidden", "important");
|
|
11012
|
+
style.setProperty("overflow-y", "hidden", "important");
|
|
11013
|
+
release = () => held.forEach((name, i2) => {
|
|
11014
|
+
const [value, priority] = saved[i2];
|
|
11015
|
+
if (value) style.setProperty(name, value, priority);
|
|
11016
|
+
else style.removeProperty(name);
|
|
11017
|
+
});
|
|
11018
|
+
}
|
|
11019
|
+
dialog.addEventListener("close", () => --holds === 0 && release(), { once: true });
|
|
11020
|
+
}
|
|
11021
|
+
var styles2 = evidence_dialog_css_default + markStyles;
|
|
10630
11022
|
function node(tag, text = "", className = "") {
|
|
10631
11023
|
const element = document.createElement(tag);
|
|
10632
11024
|
element.textContent = text;
|
|
@@ -10749,6 +11141,7 @@ ${claims(evidence)}`;
|
|
|
10749
11141
|
}
|
|
10750
11142
|
function side(heading, name, reference, url, since, extra) {
|
|
10751
11143
|
const card = node("section", "", "account");
|
|
11144
|
+
const identity = node("div", "", "identity");
|
|
10752
11145
|
const title = node("h3");
|
|
10753
11146
|
const value = node(url ? "a" : "strong", name);
|
|
10754
11147
|
title.append(...heading);
|
|
@@ -10756,15 +11149,15 @@ ${claims(evidence)}`;
|
|
|
10756
11149
|
if (since) {
|
|
10757
11150
|
const named = node("div", "", "named");
|
|
10758
11151
|
named.append(value, node("span", since, "muted since"));
|
|
10759
|
-
|
|
10760
|
-
} else
|
|
10761
|
-
if (typeof reference === "string")
|
|
11152
|
+
identity.append(title, named);
|
|
11153
|
+
} else identity.append(title, value);
|
|
11154
|
+
if (typeof reference === "string") identity.append(node("div", reference, "muted reference"));
|
|
10762
11155
|
else if (reference) {
|
|
10763
11156
|
const groups = node("div", "", "muted reference fingerprint");
|
|
10764
11157
|
groups.append(...reference.map((group) => node("span", group)));
|
|
10765
|
-
|
|
11158
|
+
identity.append(groups);
|
|
10766
11159
|
}
|
|
10767
|
-
card.append(...extra);
|
|
11160
|
+
card.append(identity, ...extra);
|
|
10768
11161
|
return card;
|
|
10769
11162
|
}
|
|
10770
11163
|
var retiringNote = "Retiring keeps this record as history. It will no longer read as verified, and who can read it cannot be changed afterwards.";
|
|
@@ -10958,6 +11351,17 @@ ${claims(evidence)}`;
|
|
|
10958
11351
|
}
|
|
10959
11352
|
return svg;
|
|
10960
11353
|
}
|
|
11354
|
+
function reveal(element) {
|
|
11355
|
+
requestAnimationFrame(() => {
|
|
11356
|
+
const pane = element.closest(".pane");
|
|
11357
|
+
const tall = pane !== null && element.offsetHeight > pane.clientHeight;
|
|
11358
|
+
const still = matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
11359
|
+
element.scrollIntoView({
|
|
11360
|
+
block: tall ? "start" : "nearest",
|
|
11361
|
+
behavior: still ? "auto" : "smooth"
|
|
11362
|
+
});
|
|
11363
|
+
});
|
|
11364
|
+
}
|
|
10961
11365
|
function foldToggle(folded, fold) {
|
|
10962
11366
|
const toggle = node("button", "", "fold");
|
|
10963
11367
|
let shown3 = fold.open;
|
|
@@ -10972,6 +11376,7 @@ ${claims(evidence)}`;
|
|
|
10972
11376
|
toggle.onclick = () => {
|
|
10973
11377
|
set(!shown3);
|
|
10974
11378
|
fold.toggle(shown3);
|
|
11379
|
+
if (shown3) reveal(folded.at(-1));
|
|
10975
11380
|
};
|
|
10976
11381
|
return toggle;
|
|
10977
11382
|
}
|
|
@@ -11020,6 +11425,8 @@ ${claims(evidence)}`;
|
|
|
11020
11425
|
];
|
|
11021
11426
|
if (fold) bar.append(foldToggle([...methods, dates], fold), ...row);
|
|
11022
11427
|
const logo2 = providerMark(evidence.provider, evidence.attestations.external[0].method);
|
|
11428
|
+
const rest = node("div", "", "rest");
|
|
11429
|
+
rest.append(...fold ? [bar, ...methods, dates] : [...methods, dates, ...row]);
|
|
11023
11430
|
const card = namedCard(
|
|
11024
11431
|
// The mark and the name, or just the name. A mark that falls back to writing the name
|
|
11025
11432
|
// would print it twice here, since this heading writes it either way.
|
|
@@ -11028,9 +11435,8 @@ ${claims(evidence)}`;
|
|
|
11028
11435
|
// Status first, then how it was shown, then when. The proof explains the state
|
|
11029
11436
|
// above it, so it cannot sit before that state has been given.
|
|
11030
11437
|
summary,
|
|
11031
|
-
...fold ? [] : methods,
|
|
11032
11438
|
...evidence.status === "revoked" || retired ? [] : evidence.mark === "preferred" ? [node("div", "Preferred", "listing preferred")] : evidence.mark === "unused" ? [node("div", "No longer used", "listing")] : [],
|
|
11033
|
-
|
|
11439
|
+
rest
|
|
11034
11440
|
);
|
|
11035
11441
|
const surface = retired ? "account retired" : "account";
|
|
11036
11442
|
card.className = surface;
|
|
@@ -11074,6 +11480,7 @@ ${claims(evidence)}`;
|
|
|
11074
11480
|
provider: first.providerName
|
|
11075
11481
|
})
|
|
11076
11482
|
);
|
|
11483
|
+
localCard.className += " local";
|
|
11077
11484
|
const retired = records.filter((record2) => record2.status === "retired");
|
|
11078
11485
|
const listed = records.filter((record2) => record2.status !== "retired");
|
|
11079
11486
|
const cards = (among, warned) => among.map((record2) => {
|
|
@@ -11093,20 +11500,24 @@ ${record2.external.id}`;
|
|
|
11093
11500
|
const history = node("details", "", "history");
|
|
11094
11501
|
const count = node("summary", "", "group");
|
|
11095
11502
|
count.append(foldMark(), document.createTextNode(`Retired accounts (${retired.length})`));
|
|
11096
|
-
|
|
11097
|
-
|
|
11503
|
+
const gone = node("div", "", "tiles");
|
|
11504
|
+
gone.append(
|
|
11098
11505
|
...cards(retired, () => {
|
|
11099
11506
|
history.open = true;
|
|
11100
11507
|
})
|
|
11101
11508
|
);
|
|
11509
|
+
history.append(count, gone);
|
|
11102
11510
|
history.open = folds.retired ?? !listed.length;
|
|
11103
11511
|
count.addEventListener("click", () => {
|
|
11104
11512
|
folds.retired = !history.open;
|
|
11513
|
+
if (folds.retired) reveal(history);
|
|
11105
11514
|
});
|
|
11515
|
+
const accounts2 = node("div", "", "tiles");
|
|
11516
|
+
accounts2.append(...cards(listed));
|
|
11106
11517
|
content.replaceChildren(
|
|
11107
11518
|
localCard,
|
|
11108
11519
|
linkMark(),
|
|
11109
|
-
|
|
11520
|
+
accounts2,
|
|
11110
11521
|
...manage ? [addRow(manage)] : [],
|
|
11111
11522
|
...retired.length ? [history] : [],
|
|
11112
11523
|
// Nothing below the cards may name a provider. Approval, method and dates belong to
|
|
@@ -11117,6 +11528,7 @@ ${record2.external.id}`;
|
|
|
11117
11528
|
"muted explanation"
|
|
11118
11529
|
)
|
|
11119
11530
|
);
|
|
11531
|
+
return (listed.length || retired.length) >= 4;
|
|
11120
11532
|
}
|
|
11121
11533
|
function openEvidenceDialog(opener, load2, opened, arrange2 = (records) => records, manage, detailsOpen = false) {
|
|
11122
11534
|
const existing = openDialogs.get(opener);
|
|
@@ -11237,7 +11649,8 @@ ${record2.external.id}`;
|
|
|
11237
11649
|
if (key2 === drawn) return;
|
|
11238
11650
|
drawn = key2;
|
|
11239
11651
|
retries.clear();
|
|
11240
|
-
render(content, records, actions, (retry) => retries.add(retry), folds);
|
|
11652
|
+
const many = render(content, records, actions, (retry) => retries.add(retry), folds);
|
|
11653
|
+
dialog.className = many ? "many" : "";
|
|
11241
11654
|
};
|
|
11242
11655
|
const watch = (given) => {
|
|
11243
11656
|
clearTimeout(expiryTimer);
|
|
@@ -11299,34 +11712,16 @@ ${record2.external.id}`;
|
|
|
11299
11712
|
{ once: true }
|
|
11300
11713
|
);
|
|
11301
11714
|
if (opened && [opened].flat().length) draw(opened);
|
|
11715
|
+
holdPage(dialog);
|
|
11302
11716
|
dialog.showModal();
|
|
11303
11717
|
void refresh();
|
|
11304
11718
|
}
|
|
11305
11719
|
|
|
11720
|
+
// src/browser/connect-dialog.css.ts
|
|
11721
|
+
var connect_dialog_css_default = ".steps > p:first-child {\n margin-top: 0;\n}\n.choices {\n display: grid;\n gap: 8px;\n margin-top: 16px;\n}\n/* With a way back beside it, the heading sits by that and not in the middle. */\nheader.backed h2 {\n margin-right: auto;\n}\n.choices .action {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.choices .more {\n margin-left: auto;\n color: #6b786f;\n font-weight: 500;\n font-size: 12px;\n}\n.row.start {\n justify-content: start;\n}\n/* The block scrolls and its frame does not, so the copy button stays in its corner. */\n.code {\n position: relative;\n margin: 10px 0;\n}\npre {\n margin: 0;\n padding: 10px 64px 10px 12px;\n border: 1px solid #e0e6df;\n border-radius: 8px;\n background: #f6f8f5;\n font:\n 12px/1.5 ui-monospace,\n monospace;\n white-space: pre;\n overflow-x: auto;\n}\n.code .action {\n position: absolute;\n top: 9px;\n right: 9px;\n padding: 3px 8px;\n font-size: 11px;\n}\nlabel {\n display: grid;\n gap: 4px;\n margin-top: 12px;\n font-weight: 600;\n}\ninput[type='url'],\ninput[type='email'],\ninput[type='tel'],\ninput[type='text'],\ntextarea {\n width: 100%;\n padding: 8px 10px;\n border: 1px solid #cfd8d2;\n border-radius: 8px;\n font:\n 13px/1.4 system-ui,\n sans-serif;\n color: inherit;\n background: #fff;\n}\ntextarea {\n font-family: ui-monospace, monospace;\n font-size: 12px;\n resize: vertical;\n}\nfieldset {\n margin: 16px 0 0;\n padding: 10px 14px;\n border: 1px solid #e0e6df;\n border-radius: 10px;\n}\nlegend {\n padding: 0 4px;\n color: #6b786f;\n font-size: 11px;\n font-weight: 550;\n}\nfieldset label {\n display: flex;\n align-items: baseline;\n gap: 8px;\n margin-top: 4px;\n font-weight: 500;\n}\n/* A radio has no baseline to speak of, so it is set in the middle of the label's first line. */\nfieldset input {\n flex-shrink: 0;\n align-self: flex-start;\n width: 13px;\n height: 13px;\n font: inherit;\n margin-top: 4px;\n margin-top: calc((1lh - 13px) / 2);\n margin-bottom: 0;\n}\n.error {\n color: #9b2c33;\n}\n";
|
|
11722
|
+
|
|
11306
11723
|
// src/browser/connect-dialog.ts
|
|
11307
|
-
var connectStyles =
|
|
11308
|
-
${styles2}
|
|
11309
|
-
.steps > p:first-child { margin-top: 0; }
|
|
11310
|
-
.choices { display: grid; gap: 8px; margin-top: 16px; }
|
|
11311
|
-
/* With a way back beside it, the heading sits by that and not in the middle. */
|
|
11312
|
-
header.backed h2 { margin-right: auto; }
|
|
11313
|
-
.choices .action { display: flex; align-items: center; gap: 8px; }
|
|
11314
|
-
.choices .more { margin-left: auto; color: #6b786f; font-weight: 500; font-size: 12px; }
|
|
11315
|
-
.row.start { justify-content: start; }
|
|
11316
|
-
/* The block scrolls and its frame does not, so the copy button stays in its corner. */
|
|
11317
|
-
.code { position: relative; margin: 10px 0; }
|
|
11318
|
-
pre { margin: 0; padding: 10px 64px 10px 12px; border: 1px solid #e0e6df; border-radius: 8px; background: #f6f8f5; font: 12px/1.5 ui-monospace, monospace; white-space: pre; overflow-x: auto; }
|
|
11319
|
-
.code .action { position: absolute; top: 9px; right: 9px; padding: 3px 8px; font-size: 11px; }
|
|
11320
|
-
label { display: grid; gap: 4px; margin-top: 12px; font-weight: 600; }
|
|
11321
|
-
input[type=url], input[type=email], input[type=tel], input[type=text], textarea { width: 100%; padding: 8px 10px; border: 1px solid #cfd8d2; border-radius: 8px; font: 13px/1.4 system-ui, sans-serif; color: inherit; background: #fff; }
|
|
11322
|
-
textarea { font-family: ui-monospace, monospace; font-size: 12px; resize: vertical; }
|
|
11323
|
-
fieldset { margin: 16px 0 0; padding: 10px 14px; border: 1px solid #e0e6df; border-radius: 10px; }
|
|
11324
|
-
legend { padding: 0 4px; color: #6b786f; font-size: 11px; font-weight: 550; }
|
|
11325
|
-
fieldset label { display: flex; align-items: baseline; gap: 8px; margin-top: 4px; font-weight: 500; }
|
|
11326
|
-
/* A radio has no baseline to speak of, so it is set in the middle of the label's first line. */
|
|
11327
|
-
fieldset input { flex-shrink: 0; align-self: flex-start; width: 13px; height: 13px; font: inherit; margin-top: 4px; margin-top: calc((1lh - 13px) / 2); margin-bottom: 0; }
|
|
11328
|
-
.error { color: #9b2c33; }
|
|
11329
|
-
`;
|
|
11724
|
+
var connectStyles = styles2 + connect_dialog_css_default;
|
|
11330
11725
|
function codeBlock(code) {
|
|
11331
11726
|
const block = node("div", "", "code");
|
|
11332
11727
|
const scroller = node("pre");
|
|
@@ -11777,6 +12172,7 @@ ${record2.external.id}`;
|
|
|
11777
12172
|
{ once: true }
|
|
11778
12173
|
)
|
|
11779
12174
|
);
|
|
12175
|
+
holdPage(dialog);
|
|
11780
12176
|
dialog.showModal();
|
|
11781
12177
|
void choose();
|
|
11782
12178
|
return closed;
|