@graffiti-garden/implementation-decentralized 0.0.2 → 0.0.3
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/1-services/4-inboxes-tests.d.ts.map +1 -1
- package/dist/1-services/4-inboxes.d.ts +3 -3
- package/dist/1-services/4-inboxes.d.ts.map +1 -1
- package/dist/3-protocol/4-graffiti.d.ts.map +1 -1
- package/dist/3-protocol/login-dialog.html.d.ts +1 -1
- package/dist/3-protocol/login-dialog.html.d.ts.map +1 -1
- package/dist/browser/index.js +7 -7
- package/dist/browser/index.js.map +3 -3
- package/dist/browser/login-dialog.html-VTDKJZBG.js +44 -0
- package/dist/browser/login-dialog.html-VTDKJZBG.js.map +7 -0
- package/dist/browser/{style-YUTCEBZV-RWYJV575.js → style-3ALLGCD7-QNFKN6AK.js} +18 -36
- package/dist/browser/style-3ALLGCD7-QNFKN6AK.js.map +7 -0
- package/dist/cjs/1-services/4-inboxes-tests.js +2 -0
- package/dist/cjs/1-services/4-inboxes-tests.js.map +2 -2
- package/dist/cjs/1-services/4-inboxes.js +17 -8
- package/dist/cjs/1-services/4-inboxes.js.map +2 -2
- package/dist/cjs/3-protocol/4-graffiti.js +40 -12
- package/dist/cjs/3-protocol/4-graffiti.js.map +2 -2
- package/dist/cjs/3-protocol/login-dialog.html.js +9 -9
- package/dist/cjs/3-protocol/login-dialog.html.js.map +1 -1
- package/dist/esm/1-services/4-inboxes-tests.js +2 -0
- package/dist/esm/1-services/4-inboxes-tests.js.map +2 -2
- package/dist/esm/1-services/4-inboxes.js +19 -9
- package/dist/esm/1-services/4-inboxes.js.map +2 -2
- package/dist/esm/3-protocol/4-graffiti.js +41 -12
- package/dist/esm/3-protocol/4-graffiti.js.map +2 -2
- package/dist/esm/3-protocol/login-dialog.html.js +9 -9
- package/dist/esm/3-protocol/login-dialog.html.js.map +1 -1
- package/package.json +3 -3
- package/src/1-services/4-inboxes-tests.ts +2 -0
- package/src/1-services/4-inboxes.ts +25 -15
- package/src/3-protocol/4-graffiti.ts +65 -17
- package/src/3-protocol/login-dialog.html.ts +9 -9
- package/dist/browser/login-dialog.html-XUWYDNNI.js +0 -44
- package/dist/browser/login-dialog.html-XUWYDNNI.js.map +0 -7
- package/dist/browser/style-YUTCEBZV-RWYJV575.js.map +0 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/3-protocol/login-dialog.html.ts"],
|
|
4
|
-
"sourcesContent": ["export const template = `<template id=\"graffiti-login-welcome\">\n <h1>\n <a target=\"_blank\" href=\"https://graffiti.garden\">Graffiti
|
|
4
|
+
"sourcesContent": ["export const template = `<template id=\"graffiti-login-welcome\">\n <h1>\n <a target=\"_blank\" href=\"https://graffiti.garden\">Graffiti Log In</a>\n </h1>\n\n <ul>\n <li><a type=\"button\" id=\"graffiti-login-new\">Create new Graffiti identity</a></li>\n <li><button class=\"secondary\" id=\"graffiti-login-existing\">Use existing Graffiti identity</button></li>\n </ul>\n\n <aside>\n This application is built with\n <a target=\"_blank\" href=\"https://graffiti.garden\">Graffiti</a>.\n </aside>\n</template>\n\n<template id=\"graffiti-login-handle\">\n<h1>\n <a target=\"_blank\" href=\"https://graffiti.garden\">Graffiti Log In</a>\n</h1>\n\n <form id=\"graffiti-login-handle-form\">\n <label for=\"username\">Graffiti handle:</label>\n <input\n type=\"text\"\n name=\"username\"\n id=\"username\"\n autocomplete=\"username\"\n autocapitalize=\"none\"\n spellcheck=\"false\"\n inputmode=\"url\"\n placeholder=\"you.graffiti.actor\"\n required\n >\n <button id=\"graffiti-login-handle-submit\" type=\"submit\">\n Log In\n </button>\n </form>\n\n <p>\n Don't have a Graffiti handle? <a id=\"graffiti-login-new\">Create one</a>.\n </p>\n</template>`;\n"],
|
|
5
5
|
"mappings": "AAAO,MAAM,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graffiti-garden/implementation-decentralized",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "A client for a decentralized implementation of the Graffiti API",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -50,8 +50,8 @@
|
|
|
50
50
|
"vitest": "^4.0.17"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@graffiti-garden/api": "^1.1.
|
|
54
|
-
"@graffiti-garden/modal": "^1.0.
|
|
53
|
+
"@graffiti-garden/api": "^1.1.1",
|
|
54
|
+
"@graffiti-garden/modal": "^1.0.2",
|
|
55
55
|
"@ipld/dag-cbor": "^9.2.5",
|
|
56
56
|
"@noble/ed25519": "^3.0.0",
|
|
57
57
|
"@noble/hashes": "^2.0.1",
|
|
@@ -32,6 +32,7 @@ export function inboxTests(inboxEndpoint: string, inboxToken: string) {
|
|
|
32
32
|
|
|
33
33
|
// Get the message back
|
|
34
34
|
const message = await inboxes.get(inboxEndpoint, messageId, inboxToken);
|
|
35
|
+
assert(message !== null);
|
|
35
36
|
expect(message.m).toEqual(sending);
|
|
36
37
|
expect(message.l).toEqual(0);
|
|
37
38
|
|
|
@@ -62,6 +63,7 @@ export function inboxTests(inboxEndpoint: string, inboxToken: string) {
|
|
|
62
63
|
expect(endResult2.done).toBe(true);
|
|
63
64
|
|
|
64
65
|
const message2 = await inboxes.get(inboxEndpoint, messageId, inboxToken);
|
|
66
|
+
assert(message2 !== null);
|
|
65
67
|
expect(message2.m).toEqual(sending);
|
|
66
68
|
expect(message2.l).toEqual(42);
|
|
67
69
|
});
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
compileGraffitiObjectSchema,
|
|
9
9
|
GraffitiErrorCursorExpired,
|
|
10
|
+
GraffitiErrorNotFound,
|
|
10
11
|
} from "@graffiti-garden/api";
|
|
11
12
|
import {
|
|
12
13
|
encode as dagCborEncode,
|
|
@@ -61,23 +62,32 @@ export class Inboxes {
|
|
|
61
62
|
inboxUrl: string,
|
|
62
63
|
messageId: string,
|
|
63
64
|
inboxToken?: string | null,
|
|
64
|
-
): Promise<LabeledMessageBase> {
|
|
65
|
+
): Promise<LabeledMessageBase | null> {
|
|
65
66
|
const messageCacheKey = getMessageCacheKey(inboxUrl, messageId);
|
|
66
67
|
const cache = await this.cache;
|
|
67
68
|
const cached = await cache.messages.get(messageCacheKey);
|
|
68
|
-
if (cached) return cached;
|
|
69
|
+
if (cached !== undefined) return cached;
|
|
69
70
|
|
|
70
71
|
const url = `${inboxUrl}/message/${messageId}`;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
72
|
+
let response: Response | null = null;
|
|
73
|
+
try {
|
|
74
|
+
response = await fetchWithErrorHandling(url, {
|
|
75
|
+
method: "GET",
|
|
76
|
+
headers: {
|
|
77
|
+
...(inboxToken
|
|
78
|
+
? {
|
|
79
|
+
Authorization: `Bearer ${inboxToken}`,
|
|
80
|
+
}
|
|
81
|
+
: {}),
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
} catch (e) {
|
|
85
|
+
if (e instanceof GraffitiErrorNotFound) {
|
|
86
|
+
await cache.messages.set(messageCacheKey, null);
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
throw e;
|
|
90
|
+
}
|
|
81
91
|
|
|
82
92
|
const blob = await response.blob();
|
|
83
93
|
const cbor = dagCborDecode(await blob.arrayBuffer());
|
|
@@ -607,8 +617,8 @@ async function canUseIDB(): Promise<boolean> {
|
|
|
607
617
|
|
|
608
618
|
type Cache = {
|
|
609
619
|
messages: {
|
|
610
|
-
get(k: string): Promise<LabeledMessageBase | undefined>;
|
|
611
|
-
set(k: string, value: LabeledMessageBase): Promise<void>;
|
|
620
|
+
get(k: string): Promise<LabeledMessageBase | null | undefined>;
|
|
621
|
+
set(k: string, value: LabeledMessageBase | null): Promise<void>;
|
|
612
622
|
del(k: string): Promise<void>;
|
|
613
623
|
};
|
|
614
624
|
messageIds: {
|
|
@@ -695,7 +705,7 @@ async function createCache(): Promise<Cache> {
|
|
|
695
705
|
};
|
|
696
706
|
}
|
|
697
707
|
|
|
698
|
-
const m = new Map<string, LabeledMessageBase>();
|
|
708
|
+
const m = new Map<string, LabeledMessageBase | null>();
|
|
699
709
|
const q = new Map<string, CacheQueryValue>();
|
|
700
710
|
|
|
701
711
|
return {
|
|
@@ -29,6 +29,7 @@ import { Authorization } from "../1-services/1-authorization";
|
|
|
29
29
|
import { StorageBuckets } from "../1-services/3-storage-buckets";
|
|
30
30
|
import {
|
|
31
31
|
Inboxes,
|
|
32
|
+
LABELED_MESSAGE_LABEL_KEY,
|
|
32
33
|
LABELED_MESSAGE_MESSAGE_KEY,
|
|
33
34
|
MESSAGE_METADATA_KEY,
|
|
34
35
|
MESSAGE_OBJECT_KEY,
|
|
@@ -239,11 +240,7 @@ export class GraffitiDecentralized implements Graffiti {
|
|
|
239
240
|
) as HTMLInputElement | null;
|
|
240
241
|
input?.setAttribute("value", proposedHandle);
|
|
241
242
|
input?.addEventListener("focus", () => input?.select());
|
|
242
|
-
|
|
243
|
-
setTimeout(() => r(), 0);
|
|
244
|
-
}).then(() => {
|
|
245
|
-
input?.focus();
|
|
246
|
-
});
|
|
243
|
+
setTimeout(() => input?.focus(), 0);
|
|
247
244
|
|
|
248
245
|
template
|
|
249
246
|
?.querySelector("#graffiti-login-handle-form")
|
|
@@ -293,13 +290,16 @@ export class GraffitiDecentralized implements Graffiti {
|
|
|
293
290
|
e.preventDefault();
|
|
294
291
|
this.login_("");
|
|
295
292
|
});
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
293
|
+
|
|
294
|
+
setTimeout(
|
|
295
|
+
() =>
|
|
296
|
+
(
|
|
297
|
+
template?.querySelector(
|
|
298
|
+
"#graffiti-login-new",
|
|
299
|
+
) as HTMLAnchorElement
|
|
300
|
+
)?.focus(),
|
|
301
|
+
0,
|
|
302
|
+
);
|
|
303
303
|
}
|
|
304
304
|
|
|
305
305
|
const createUrl = new URL(this.identityCreatorEndpoint);
|
|
@@ -1017,7 +1017,12 @@ export class GraffitiDecentralized implements Graffiti {
|
|
|
1017
1017
|
const result = itResult.value;
|
|
1018
1018
|
|
|
1019
1019
|
const label = result.l;
|
|
1020
|
-
|
|
1020
|
+
// Anything invalid or unexpected, we can skip
|
|
1021
|
+
if (
|
|
1022
|
+
label !== MESSAGE_LABEL_VALID &&
|
|
1023
|
+
label !== MESSAGE_LABEL_UNLABELED &&
|
|
1024
|
+
label !== MESSAGE_LABEL_TRASH
|
|
1025
|
+
)
|
|
1021
1026
|
continue;
|
|
1022
1027
|
|
|
1023
1028
|
const messageId = result.id;
|
|
@@ -1061,9 +1066,50 @@ export class GraffitiDecentralized implements Graffiti {
|
|
|
1061
1066
|
announcements,
|
|
1062
1067
|
};
|
|
1063
1068
|
continue;
|
|
1069
|
+
} else if (label === MESSAGE_LABEL_TRASH) {
|
|
1070
|
+
// If it is simply trash, just continue.
|
|
1071
|
+
if (!tombstonedMessageId) continue;
|
|
1072
|
+
|
|
1073
|
+
// Make sure the tombstone points to a real message
|
|
1074
|
+
const past = await this.inboxes.get(
|
|
1075
|
+
inboxEndpoint,
|
|
1076
|
+
tombstonedMessageId,
|
|
1077
|
+
inboxToken,
|
|
1078
|
+
);
|
|
1079
|
+
if (
|
|
1080
|
+
!past ||
|
|
1081
|
+
past[LABELED_MESSAGE_MESSAGE_KEY][MESSAGE_OBJECT_KEY].url !==
|
|
1082
|
+
object.url
|
|
1083
|
+
)
|
|
1084
|
+
continue;
|
|
1085
|
+
|
|
1086
|
+
// If the referred to message isn't labeled as trash, trash it
|
|
1087
|
+
// This may happen if a trash message is processed on another
|
|
1088
|
+
// device and the device cache is out of date.
|
|
1089
|
+
if (past[LABELED_MESSAGE_LABEL_KEY] !== MESSAGE_LABEL_TRASH) {
|
|
1090
|
+
// Label the message as trash
|
|
1091
|
+
this.inboxes.label(
|
|
1092
|
+
inboxEndpoint,
|
|
1093
|
+
tombstonedMessageId,
|
|
1094
|
+
MESSAGE_LABEL_TRASH,
|
|
1095
|
+
inboxToken,
|
|
1096
|
+
);
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
// Return the tombstone
|
|
1100
|
+
yield {
|
|
1101
|
+
messageId,
|
|
1102
|
+
tombstone: true,
|
|
1103
|
+
object,
|
|
1104
|
+
storageBucketKey,
|
|
1105
|
+
allowedTickets,
|
|
1106
|
+
tags: receivedTags,
|
|
1107
|
+
announcements,
|
|
1108
|
+
};
|
|
1109
|
+
continue;
|
|
1064
1110
|
}
|
|
1065
1111
|
|
|
1066
|
-
//
|
|
1112
|
+
// Otherwise, unlabeled: try to validate the object
|
|
1067
1113
|
let validationError: unknown | undefined = undefined;
|
|
1068
1114
|
try {
|
|
1069
1115
|
const actor = object.actor;
|
|
@@ -1123,13 +1169,15 @@ export class GraffitiDecentralized implements Graffiti {
|
|
|
1123
1169
|
// Get the referenced message
|
|
1124
1170
|
.get(inboxEndpoint, tombstonedMessageId, inboxToken)
|
|
1125
1171
|
.then((result) => {
|
|
1126
|
-
// Make sure that it actually references the object being deleted
|
|
1127
1172
|
if (
|
|
1173
|
+
// Make sure that it actually references the object being deleted
|
|
1128
1174
|
result &&
|
|
1129
1175
|
result[LABELED_MESSAGE_MESSAGE_KEY][MESSAGE_OBJECT_KEY].url ===
|
|
1130
|
-
object.url
|
|
1176
|
+
object.url &&
|
|
1177
|
+
// And that the object is not already marked as trash
|
|
1178
|
+
result[LABELED_MESSAGE_LABEL_KEY] !== MESSAGE_LABEL_TRASH
|
|
1131
1179
|
) {
|
|
1132
|
-
// If
|
|
1180
|
+
// If valid but not yet trash, label the message as trash
|
|
1133
1181
|
this.inboxes.label(
|
|
1134
1182
|
inboxEndpoint,
|
|
1135
1183
|
tombstonedMessageId,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
export const template = `<template id="graffiti-login-welcome">
|
|
2
2
|
<h1>
|
|
3
|
-
<a target="_blank" href="https://graffiti.garden">Graffiti
|
|
3
|
+
<a target="_blank" href="https://graffiti.garden">Graffiti Log In</a>
|
|
4
4
|
</h1>
|
|
5
5
|
|
|
6
6
|
<ul>
|
|
7
|
-
<li><a type="button" id="graffiti-login-new">Create
|
|
8
|
-
<li><button class="secondary" id="graffiti-login-existing">Use
|
|
7
|
+
<li><a type="button" id="graffiti-login-new">Create new Graffiti identity</a></li>
|
|
8
|
+
<li><button class="secondary" id="graffiti-login-existing">Use existing Graffiti identity</button></li>
|
|
9
9
|
</ul>
|
|
10
10
|
|
|
11
11
|
<aside>
|
|
@@ -15,12 +15,12 @@ export const template = `<template id="graffiti-login-welcome">
|
|
|
15
15
|
</template>
|
|
16
16
|
|
|
17
17
|
<template id="graffiti-login-handle">
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
<h1>
|
|
19
|
+
<a target="_blank" href="https://graffiti.garden">Graffiti Log In</a>
|
|
20
|
+
</h1>
|
|
21
21
|
|
|
22
22
|
<form id="graffiti-login-handle-form">
|
|
23
|
-
<label for="username">
|
|
23
|
+
<label for="username">Graffiti handle:</label>
|
|
24
24
|
<input
|
|
25
25
|
type="text"
|
|
26
26
|
name="username"
|
|
@@ -29,7 +29,7 @@ export const template = `<template id="graffiti-login-welcome">
|
|
|
29
29
|
autocapitalize="none"
|
|
30
30
|
spellcheck="false"
|
|
31
31
|
inputmode="url"
|
|
32
|
-
placeholder="
|
|
32
|
+
placeholder="you.graffiti.actor"
|
|
33
33
|
required
|
|
34
34
|
>
|
|
35
35
|
<button id="graffiti-login-handle-submit" type="submit">
|
|
@@ -38,6 +38,6 @@ export const template = `<template id="graffiti-login-welcome">
|
|
|
38
38
|
</form>
|
|
39
39
|
|
|
40
40
|
<p>
|
|
41
|
-
Don't
|
|
41
|
+
Don't have a Graffiti handle? <a id="graffiti-login-new">Create one</a>.
|
|
42
42
|
</p>
|
|
43
43
|
</template>`;
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import"./chunk-RFBBAUMM.js";var t=`<template id="graffiti-login-welcome">
|
|
2
|
-
<h1>
|
|
3
|
-
<a target="_blank" href="https://graffiti.garden">Graffiti<wbr> Log In</a>
|
|
4
|
-
</h1>
|
|
5
|
-
|
|
6
|
-
<ul>
|
|
7
|
-
<li><a type="button" id="graffiti-login-new">Create new Graffiti identity</a></li>
|
|
8
|
-
<li><button class="secondary" id="graffiti-login-existing">Use existing Graffiti identity</button></li>
|
|
9
|
-
</ul>
|
|
10
|
-
|
|
11
|
-
<aside>
|
|
12
|
-
This application is built with
|
|
13
|
-
<a target="_blank" href="https://graffiti.garden">Graffiti</a>.
|
|
14
|
-
</aside>
|
|
15
|
-
</template>
|
|
16
|
-
|
|
17
|
-
<template id="graffiti-login-handle">
|
|
18
|
-
<h1>
|
|
19
|
-
<a target="_blank" href="https://graffiti.garden">Graffiti<wbr> Log In</a>
|
|
20
|
-
</h1>
|
|
21
|
-
|
|
22
|
-
<form id="graffiti-login-handle-form">
|
|
23
|
-
<label for="username">Enter your Graffiti handle:</label>
|
|
24
|
-
<input
|
|
25
|
-
type="text"
|
|
26
|
-
name="username"
|
|
27
|
-
id="username"
|
|
28
|
-
autocomplete="username"
|
|
29
|
-
autocapitalize="none"
|
|
30
|
-
spellcheck="false"
|
|
31
|
-
inputmode="url"
|
|
32
|
-
placeholder="example.graffiti.actor"
|
|
33
|
-
required
|
|
34
|
-
>
|
|
35
|
-
<button id="graffiti-login-handle-submit" type="submit">
|
|
36
|
-
Log In
|
|
37
|
-
</button>
|
|
38
|
-
</form>
|
|
39
|
-
|
|
40
|
-
<p>
|
|
41
|
-
Don't have a Graffiti handle? <a id="graffiti-login-new">Create one</a>.
|
|
42
|
-
</p>
|
|
43
|
-
</template>`;export{t as template};
|
|
44
|
-
//# sourceMappingURL=login-dialog.html-XUWYDNNI.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/3-protocol/login-dialog.html.ts"],
|
|
4
|
-
"sourcesContent": ["export const template = `<template id=\"graffiti-login-welcome\">\n <h1>\n <a target=\"_blank\" href=\"https://graffiti.garden\">Graffiti<wbr> Log In</a>\n </h1>\n\n <ul>\n <li><a type=\"button\" id=\"graffiti-login-new\">Create new Graffiti identity</a></li>\n <li><button class=\"secondary\" id=\"graffiti-login-existing\">Use existing Graffiti identity</button></li>\n </ul>\n\n <aside>\n This application is built with\n <a target=\"_blank\" href=\"https://graffiti.garden\">Graffiti</a>.\n </aside>\n</template>\n\n<template id=\"graffiti-login-handle\">\n <h1>\n <a target=\"_blank\" href=\"https://graffiti.garden\">Graffiti<wbr> Log In</a>\n </h1>\n\n <form id=\"graffiti-login-handle-form\">\n <label for=\"username\">Enter your Graffiti handle:</label>\n <input\n type=\"text\"\n name=\"username\"\n id=\"username\"\n autocomplete=\"username\"\n autocapitalize=\"none\"\n spellcheck=\"false\"\n inputmode=\"url\"\n placeholder=\"example.graffiti.actor\"\n required\n >\n <button id=\"graffiti-login-handle-submit\" type=\"submit\">\n Log In\n </button>\n </form>\n\n <p>\n Don't have a Graffiti handle? <a id=\"graffiti-login-new\">Create one</a>.\n </p>\n</template>`;\n"],
|
|
5
|
-
"mappings": "4BAAO,IAAMA,EAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;",
|
|
6
|
-
"names": ["template"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../node_modules/@graffiti-garden/modal/src/style.css"],
|
|
4
|
-
"sourcesContent": [".graffiti-modal {\n --back: rgb(26, 26, 26, 0.85);\n --halfback: rgba(80, 80, 80, 0.85);\n --halfback2: rgba(26, 26, 26, 0.85);\n --hover: rgba(202, 122, 204, 0.3);\n --frontfaded: rgba(190, 190, 190);\n --front: rgba(240, 240, 240);\n --emph: rgb(202, 122, 204);\n --blurpix: 3px;\n border-color: var(--emph);\n box-sizing: border-box;\n border-width: 2px;\n padding: 0;\n margin: 0;\n border-radius: 1rem;\n box-shadow: 0 0 2rem black;\n overflow: hidden;\n opacity: 0;\n transition: opacity 0.3s;\n pointer-events: none;\n display: block;\n min-width: 95dvw;\n min-height: 95dvh;\n height: 95dvh;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n flex-direction: column;\n justify-content: flex-start;\n align-items: center;\n font-family:\n Inter,\n -apple-system,\n BlinkMacSystemFont,\n \"Segoe UI\",\n Roboto,\n Oxygen,\n Ubuntu,\n Cantarell,\n \"Fira Sans\",\n \"Droid Sans\",\n \"Helvetica Neue\",\n sans-serif;\n color: var(--front);\n font-size: 150%;\n\n * {\n box-sizing: border-box;\n padding: 0;\n margin: 0;\n }\n\n ::selection {\n background: rgba(202, 122, 204, 0.3);\n }\n\n :focus {\n outline: 2px solid var(--front);\n }\n\n header {\n width: 100%;\n display: flex;\n justify-content: flex-end;\n }\n\n main {\n flex: 1;\n max-width: 600px;\n width: 100%;\n gap: 2em;\n padding-top: 4dvh;\n padding-bottom: 4dvh;\n margin-top: 4dvh;\n margin-bottom: 4dvh;\n margin-left: 4dvw;\n margin-right: 4dvw;\n padding-left: 4dvw;\n padding-right: 4dvw;\n background: var(--back);\n border-radius: 1rem;\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n scrollbar-color: var(--emph) rgba(0, 0, 0, 0);\n }\n\n ul {\n list-style-type: none;\n display: flex;\n flex-direction: column;\n gap: 0.5em;\n align-items: stretch;\n justify-content: stretch;\n }\n\n aside {\n color: var(--frontfaded);\n }\n\n .secondary,\n a:not([type=\"button\"]) {\n color: var(--emph);\n }\n\n h1 {\n font-size: 120%;\n font-family:\n Rock Salt,\n cursive,\n sans-serif;\n letter-spacing: 0.1em;\n text-align: center;\n color: var(--front);\n }\n\n h1 a:not([type=\"button\"]) {\n color: inherit;\n }\n\n h1 a:hover {\n background: none;\n color: inherit;\n }\n\n button,\n input[type=\"submit\"],\n input[type=\"text\"],\n a[type=\"button\"] {\n font-size: inherit;\n width: 100%;\n text-align: center;\n display: block;\n border-radius: 1rem;\n border: 2px solid var(--emph);\n padding: 1em;\n padding-top: 0.5em;\n padding-bottom: 0.5em;\n transition: 0.1s;\n text-overflow: ellipsis;\n background: none;\n line-height: 1.2em;\n }\n\n input[type=\"text\"] {\n font-weight: 500;\n background: var(--front);\n text-align: left;\n color: black;\n }\n\n header button {\n border-radius: 0 0 0 1rem;\n border-right: none;\n border-top: none;\n background-color: var(--halfback2);\n width: fit-content;\n position: relative;\n overflow: hidden;\n }\n\n header button::before {\n z-index: -1;\n top: 0;\n left: 0;\n height: 100%;\n position: absolute;\n width: 100%;\n content: \"\";\n background-color: var(--back);\n }\n\n @media (max-width: 600px) {\n main {\n border-radius: 0;\n margin: auto;\n overflow: auto;\n }\n\n header button {\n border-radius: 0;\n border-left: none;\n width: 100%;\n }\n\n html {\n justify-content: safe center;\n }\n }\n\n a {\n text-decoration: none;\n }\n\n :is(button, ul a, input[type=\"submit\"]):hover {\n cursor: pointer;\n background: var(--hover);\n color: var(--front);\n }\n\n a:hover {\n text-decoration: underline;\n cursor: pointer;\n }\n\n form {\n display: flex;\n flex-direction: column;\n justify-content: flex-start;\n align-items: stretch;\n gap: 0.5em;\n }\n\n iframe {\n width: 100%;\n height: 100%;\n border: none;\n }\n\n :is(button, a[type=\"button\"], input[type=\"submit\"]).secondary {\n color: rgb(244, 213, 244);\n background: rgba(26, 26, 26, 0.6);\n }\n\n :is(button, a[type=\"button\"], input[type=\"submit\"]):not(.secondary) {\n background: var(--hover);\n color: white;\n }\n\n :is(button, a[type=\"button\"], input[type=\"submit\"]):hover {\n background: rgba(202, 122, 204, 0.6);\n color: white;\n text-decoration: none;\n }\n\n h3 {\n color: var(--frontfaded);\n }\n\n h2 {\n text-align: center;\n font-weight: 500;\n font-size: 150%;\n background: var(--halfback2);\n padding: 1rem;\n border-radius: 1rem;\n border: 1px solid var(--frontfaded);\n color: var(--front);\n }\n\n main > div {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: stretch;\n gap: 0.5rem;\n }\n}\n\n.graffiti-modal[open] {\n pointer-events: inherit;\n opacity: 1;\n}\n\n.graffiti-modal::backdrop {\n background-color: black;\n opacity: 0.5;\n}\n\n.graffiti-modal::before {\n content: \"\";\n position: fixed;\n left: 0;\n right: 0;\n z-index: -1;\n background-image: url(graffiti.jpg);\n background-size: cover;\n background-repeat: no-repeat;\n background-position: 50% 50%;\n height: calc(100% + 2 * var(--blurpix));\n width: calc(100% + 2 * var(--blurpix));\n filter: blur(var(--blurpix));\n margin: calc(-1 * var(--blurpix));\n}\n"],
|
|
5
|
-
"mappings": "4BAAA,IAAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;",
|
|
6
|
-
"names": ["style_default"]
|
|
7
|
-
}
|