grain.social is a photo sharing platform built on atproto. grain.social
atproto photography appview
48
fork

Configure Feed

Select the types of activity you want to include in your feed.

style: auto-format files via vp check --fix

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

+571 -883
+2 -1
app/app.css
··· 59 59 } 60 60 61 61 @media (max-width: 600px) { 62 - html, body { 62 + html, 63 + body { 63 64 overflow: hidden; 64 65 position: fixed; 65 66 inset: 0;
+69 -60
app/lib/utils/bsky-post.ts
··· 1 - import { callXrpc } from '$hatk/client' 2 - import { parseTextToFacets } from '$lib/utils/rich-text' 1 + import { callXrpc } from "$hatk/client"; 2 + import { parseTextToFacets } from "$lib/utils/rich-text"; 3 3 4 4 interface BskyPostOptions { 5 - url: string 5 + url: string; 6 6 location?: { 7 - name: string 7 + name: string; 8 8 address?: { 9 - locality?: string 10 - region?: string 11 - country?: string 12 - } 13 - } | null 14 - description?: string 9 + locality?: string; 10 + region?: string; 11 + country?: string; 12 + }; 13 + } | null; 14 + description?: string; 15 15 images: Array<{ 16 - dataUrl: string 17 - alt?: string 18 - width: number 19 - height: number 20 - }> 16 + dataUrl: string; 17 + alt?: string; 18 + width: number; 19 + height: number; 20 + }>; 21 21 } 22 22 23 23 export async function createBskyPost(options: BskyPostOptions): Promise<void> { 24 - const { url, location, description, images } = options 24 + const { url, location, description, images } = options; 25 25 26 - const graphemeLength = (s: string) => [...new Intl.Segmenter().segment(s)].length 26 + const graphemeLength = (s: string) => [...new Intl.Segmenter().segment(s)].length; 27 27 28 - const lines: string[] = [] 28 + const lines: string[] = []; 29 29 if (location) { 30 - lines.push(`📍 ${location.name}`) 30 + lines.push(`📍 ${location.name}`); 31 31 if (location.address) { 32 - const parts: string[] = [] 33 - if (location.address.locality) parts.push(location.address.locality) 34 - if (location.address.region) parts.push(location.address.region) 35 - if (location.address.country) parts.push(location.address.country) 36 - if (parts.length > 0) lines.push(parts.join(', ')) 32 + const parts: string[] = []; 33 + if (location.address.locality) parts.push(location.address.locality); 34 + if (location.address.region) parts.push(location.address.region); 35 + if (location.address.country) parts.push(location.address.country); 36 + if (parts.length > 0) lines.push(parts.join(", ")); 37 37 } 38 38 } 39 39 40 - const suffix = `\n\n${url}\n\n#grainsocial` 41 - const prefixText = lines.length > 0 ? lines.join('\n') + '\n' : '' 42 - const overhead = graphemeLength(prefixText + suffix) 43 - const maxDesc = 300 - overhead 40 + const suffix = `\n\n${url}\n\n#grainsocial`; 41 + const prefixText = lines.length > 0 ? lines.join("\n") + "\n" : ""; 42 + const overhead = graphemeLength(prefixText + suffix); 43 + const maxDesc = 300 - overhead; 44 44 45 45 if (description?.trim()) { 46 - let desc = description.trim() 46 + let desc = description.trim(); 47 47 if (graphemeLength(desc) > maxDesc) { 48 - const segments = [...new Intl.Segmenter().segment(desc)] 49 - desc = segments.slice(0, Math.max(0, maxDesc - 1)).map((s) => s.segment).join('') + '…' 48 + const segments = [...new Intl.Segmenter().segment(desc)]; 49 + desc = 50 + segments 51 + .slice(0, Math.max(0, maxDesc - 1)) 52 + .map((s) => s.segment) 53 + .join("") + "…"; 50 54 } 51 55 if (desc) { 52 - lines.push('') 53 - lines.push(desc) 56 + lines.push(""); 57 + lines.push(desc); 54 58 } 55 59 } 56 - lines.push('') 57 - lines.push(url) 58 - lines.push('') 59 - lines.push('#grainsocial') 60 + lines.push(""); 61 + lines.push(url); 62 + lines.push(""); 63 + lines.push("#grainsocial"); 60 64 61 - const postText = lines.join('\n') 65 + const postText = lines.join("\n"); 62 66 63 67 const resolveHandle = async (handle: string): Promise<string | null> => { 64 68 try { 65 69 const res = await fetch( 66 - `https://public.api.bsky.app/xrpc/com.atproto.identity.resolveHandle?handle=${encodeURIComponent(handle)}` 67 - ) 68 - if (!res.ok) return null 69 - const data = await res.json() 70 - return data.did ?? null 70 + `https://public.api.bsky.app/xrpc/com.atproto.identity.resolveHandle?handle=${encodeURIComponent(handle)}`, 71 + ); 72 + if (!res.ok) return null; 73 + const data = await res.json(); 74 + return data.did ?? null; 71 75 } catch { 72 - return null 76 + return null; 73 77 } 74 - } 75 - const postFacets = (await parseTextToFacets(postText, resolveHandle)).facets 78 + }; 79 + const postFacets = (await parseTextToFacets(postText, resolveHandle)).facets; 76 80 77 - const imageRefs: Array<{ image: any; alt: string; aspectRatio?: { width: number; height: number } }> = [] 81 + const imageRefs: Array<{ 82 + image: any; 83 + alt: string; 84 + aspectRatio?: { width: number; height: number }; 85 + }> = []; 78 86 for (const img of images.slice(0, 4)) { 79 - const base64 = img.dataUrl.split(',')[1] 80 - const binary = Uint8Array.from(atob(base64), (c) => c.charCodeAt(0)) 81 - const blob = new Blob([binary], { type: 'image/jpeg' }) 82 - const uploadResult = await callXrpc('dev.hatk.uploadBlob', blob as any) 87 + const base64 = img.dataUrl.split(",")[1]; 88 + const binary = Uint8Array.from(atob(base64), (c) => c.charCodeAt(0)); 89 + const blob = new Blob([binary], { type: "image/jpeg" }); 90 + const uploadResult = await callXrpc("dev.hatk.uploadBlob", blob as any); 83 91 imageRefs.push({ 84 92 image: (uploadResult as any).blob, 85 - alt: img.alt || '', 93 + alt: img.alt || "", 86 94 aspectRatio: { width: img.width, height: img.height }, 87 - }) 95 + }); 88 96 } 89 97 90 - await callXrpc('dev.hatk.createRecord', { 91 - collection: 'app.bsky.feed.post', 98 + await callXrpc("dev.hatk.createRecord", { 99 + collection: "app.bsky.feed.post", 92 100 record: { 93 101 text: postText, 94 102 facets: postFacets.length > 0 ? postFacets : undefined, 95 - embed: imageRefs.length > 0 96 - ? { $type: 'app.bsky.embed.images' as const, images: imageRefs } 97 - : undefined, 98 - tags: ['grainsocial'], 103 + embed: 104 + imageRefs.length > 0 105 + ? { $type: "app.bsky.embed.images" as const, images: imageRefs } 106 + : undefined, 107 + tags: ["grainsocial"], 99 108 createdAt: new Date().toISOString(), 100 109 }, 101 - }) 110 + }); 102 111 }
+2 -6
app/service-worker.js
··· 33 33 34 34 // For navigation requests, try network first (so new deploys are picked up) 35 35 if (event.request.mode === "navigate") { 36 - event.respondWith( 37 - fetch(event.request).catch(() => caches.match(event.request)), 38 - ); 36 + event.respondWith(fetch(event.request).catch(() => caches.match(event.request))); 39 37 return; 40 38 } 41 39 42 40 // For assets, use cache-first with network fallback 43 41 if (ASSETS.has(url.pathname)) { 44 - event.respondWith( 45 - caches.match(event.request).then((cached) => cached || fetch(event.request)), 46 - ); 42 + event.respondWith(caches.match(event.request).then((cached) => cached || fetch(event.request))); 47 43 return; 48 44 } 49 45
+240 -182
docs/plans/2026-03-24-story-crosspost-design.md
··· 13 13 ### Task 1: Extract shared Bluesky post utility 14 14 15 15 **Files:** 16 + 16 17 - Create: `app/lib/utils/bsky-post.ts` 17 18 - Modify: `app/routes/create/+page.svelte` (lines 187-275) 18 19 ··· 21 22 This extracts the Bluesky posting logic from gallery create into a reusable function. 22 23 23 24 ```ts 24 - import { callXrpc } from '$hatk/client' 25 - import { parseTextToFacets } from '$lib/utils/rich-text' 25 + import { callXrpc } from "$hatk/client"; 26 + import { parseTextToFacets } from "$lib/utils/rich-text"; 26 27 27 28 interface BskyPostOptions { 28 29 /** The grain permalink URL */ 29 - url: string 30 + url: string; 30 31 /** Optional location data */ 31 32 location?: { 32 - name: string 33 + name: string; 33 34 address?: { 34 - locality?: string 35 - region?: string 36 - country?: string 37 - } 38 - } | null 35 + locality?: string; 36 + region?: string; 37 + country?: string; 38 + }; 39 + } | null; 39 40 /** Optional description text (will be truncated to fit 300 grapheme limit) */ 40 - description?: string 41 + description?: string; 41 42 /** Images to embed (max 4 for Bluesky) */ 42 43 images: Array<{ 43 - dataUrl: string 44 - alt?: string 45 - width: number 46 - height: number 47 - }> 44 + dataUrl: string; 45 + alt?: string; 46 + width: number; 47 + height: number; 48 + }>; 48 49 } 49 50 50 51 export async function createBskyPost(options: BskyPostOptions): Promise<void> { 51 - const { url, location, description, images } = options 52 + const { url, location, description, images } = options; 52 53 53 - const graphemeLength = (s: string) => [...new Intl.Segmenter().segment(s)].length 54 + const graphemeLength = (s: string) => [...new Intl.Segmenter().segment(s)].length; 54 55 55 - const lines: string[] = [] 56 + const lines: string[] = []; 56 57 if (location) { 57 - lines.push(`📍 ${location.name}`) 58 + lines.push(`📍 ${location.name}`); 58 59 if (location.address) { 59 - const parts: string[] = [] 60 - if (location.address.locality) parts.push(location.address.locality) 61 - if (location.address.region) parts.push(location.address.region) 62 - if (location.address.country) parts.push(location.address.country) 63 - if (parts.length > 0) lines.push(parts.join(', ')) 60 + const parts: string[] = []; 61 + if (location.address.locality) parts.push(location.address.locality); 62 + if (location.address.region) parts.push(location.address.region); 63 + if (location.address.country) parts.push(location.address.country); 64 + if (parts.length > 0) lines.push(parts.join(", ")); 64 65 } 65 66 } 66 67 67 - const suffix = `\n\n${url}\n\n#grainsocial` 68 - const prefixText = lines.length > 0 ? lines.join('\n') + '\n' : '' 69 - const overhead = graphemeLength(prefixText + suffix) 70 - const maxDesc = 300 - overhead 68 + const suffix = `\n\n${url}\n\n#grainsocial`; 69 + const prefixText = lines.length > 0 ? lines.join("\n") + "\n" : ""; 70 + const overhead = graphemeLength(prefixText + suffix); 71 + const maxDesc = 300 - overhead; 71 72 72 73 if (description?.trim()) { 73 - let desc = description.trim() 74 + let desc = description.trim(); 74 75 if (graphemeLength(desc) > maxDesc) { 75 - const segments = [...new Intl.Segmenter().segment(desc)] 76 - desc = segments.slice(0, Math.max(0, maxDesc - 1)).map((s) => s.segment).join('') + '…' 76 + const segments = [...new Intl.Segmenter().segment(desc)]; 77 + desc = 78 + segments 79 + .slice(0, Math.max(0, maxDesc - 1)) 80 + .map((s) => s.segment) 81 + .join("") + "…"; 77 82 } 78 83 if (desc) { 79 - lines.push('') 80 - lines.push(desc) 84 + lines.push(""); 85 + lines.push(desc); 81 86 } 82 87 } 83 - lines.push('') 84 - lines.push(url) 85 - lines.push('') 86 - lines.push('#grainsocial') 88 + lines.push(""); 89 + lines.push(url); 90 + lines.push(""); 91 + lines.push("#grainsocial"); 87 92 88 - const postText = lines.join('\n') 93 + const postText = lines.join("\n"); 89 94 90 95 // Resolve Bluesky handles for mentions 91 96 const resolveHandle = async (handle: string): Promise<string | null> => { 92 97 try { 93 98 const res = await fetch( 94 - `https://public.api.bsky.app/xrpc/com.atproto.identity.resolveHandle?handle=${encodeURIComponent(handle)}` 95 - ) 96 - if (!res.ok) return null 97 - const data = await res.json() 98 - return data.did ?? null 99 + `https://public.api.bsky.app/xrpc/com.atproto.identity.resolveHandle?handle=${encodeURIComponent(handle)}`, 100 + ); 101 + if (!res.ok) return null; 102 + const data = await res.json(); 103 + return data.did ?? null; 99 104 } catch { 100 - return null 105 + return null; 101 106 } 102 - } 103 - const postFacets = (await parseTextToFacets(postText, resolveHandle)).facets 107 + }; 108 + const postFacets = (await parseTextToFacets(postText, resolveHandle)).facets; 104 109 105 110 // Upload images (max 4) 106 - const imageRefs: Array<{ image: any; alt: string; aspectRatio?: { width: number; height: number } }> = [] 111 + const imageRefs: Array<{ 112 + image: any; 113 + alt: string; 114 + aspectRatio?: { width: number; height: number }; 115 + }> = []; 107 116 for (const img of images.slice(0, 4)) { 108 - const base64 = img.dataUrl.split(',')[1] 109 - const binary = Uint8Array.from(atob(base64), (c) => c.charCodeAt(0)) 110 - const blob = new Blob([binary], { type: 'image/jpeg' }) 111 - const uploadResult = await callXrpc('dev.hatk.uploadBlob', blob as any) 117 + const base64 = img.dataUrl.split(",")[1]; 118 + const binary = Uint8Array.from(atob(base64), (c) => c.charCodeAt(0)); 119 + const blob = new Blob([binary], { type: "image/jpeg" }); 120 + const uploadResult = await callXrpc("dev.hatk.uploadBlob", blob as any); 112 121 imageRefs.push({ 113 122 image: (uploadResult as any).blob, 114 - alt: img.alt || '', 123 + alt: img.alt || "", 115 124 aspectRatio: { width: img.width, height: img.height }, 116 - }) 125 + }); 117 126 } 118 127 119 - await callXrpc('dev.hatk.createRecord', { 120 - collection: 'app.bsky.feed.post', 128 + await callXrpc("dev.hatk.createRecord", { 129 + collection: "app.bsky.feed.post", 121 130 record: { 122 - $type: 'app.bsky.feed.post', 131 + $type: "app.bsky.feed.post", 123 132 text: postText, 124 133 facets: postFacets.length > 0 ? postFacets : undefined, 125 - embed: imageRefs.length > 0 126 - ? { $type: 'app.bsky.embed.images', images: imageRefs } 127 - : undefined, 128 - tags: ['grainsocial'], 134 + embed: 135 + imageRefs.length > 0 ? { $type: "app.bsky.embed.images", images: imageRefs } : undefined, 136 + tags: ["grainsocial"], 129 137 createdAt: new Date().toISOString(), 130 138 }, 131 - }) 139 + }); 132 140 } 133 141 ``` 134 142 ··· 137 145 In `app/routes/create/+page.svelte`, replace lines 187-275 (the `if (postToBluesky && $viewer)` block) with: 138 146 139 147 ```ts 140 - import { createBskyPost } from '$lib/utils/bsky-post' 148 + import { createBskyPost } from "$lib/utils/bsky-post"; 141 149 142 150 // ... inside publish(), after step 4 (gallery items created): 143 151 144 152 // 5. Create Bluesky post if opted in 145 153 if (postToBluesky && $viewer) { 146 - const galleryRkey = galleryUri.split('/').pop() 147 - const galleryUrl = `https://grain.social/profile/${$viewer.did}/gallery/${galleryRkey}` 154 + const galleryRkey = galleryUri.split("/").pop(); 155 + const galleryUrl = `https://grain.social/profile/${$viewer.did}/gallery/${galleryRkey}`; 148 156 await createBskyPost({ 149 157 url: galleryUrl, 150 - location: location ? { 151 - name: location.name, 152 - address: location.address, 153 - } : null, 158 + location: location 159 + ? { 160 + name: location.name, 161 + address: location.address, 162 + } 163 + : null, 154 164 description: description.trim() || undefined, 155 165 images: photos, 156 - }) 166 + }); 157 167 } 158 168 ``` 159 169 ··· 174 184 ### Task 2: Add story permalink route 175 185 176 186 **Files:** 187 + 177 188 - Create: `app/routes/profile/[did]/story/[rkey]/+page.ts` 178 189 - Create: `app/routes/profile/[did]/story/[rkey]/+page.svelte` 179 190 ··· 182 193 `app/routes/profile/[did]/story/[rkey]/+page.ts` — follows same pattern as gallery `+page.ts`: 183 194 184 195 ```ts 185 - import { browser } from "$app/environment" 186 - import { storyQuery } from "$lib/queries" 187 - import type { PageLoad } from "./$types" 196 + import { browser } from "$app/environment"; 197 + import { storyQuery } from "$lib/queries"; 198 + import type { PageLoad } from "./$types"; 188 199 189 200 export const load: PageLoad = async ({ params, parent, fetch }) => { 190 - const did = decodeURIComponent(params.did) 191 - const rkey = params.rkey 192 - const storyUri = `at://${did}/social.grain.story/${rkey}` 193 - const { queryClient } = await parent() 194 - const prefetch = queryClient.prefetchQuery(storyQuery(storyUri, fetch)) 195 - if (!browser) await prefetch 196 - return { did, rkey, storyUri } 197 - } 201 + const did = decodeURIComponent(params.did); 202 + const rkey = params.rkey; 203 + const storyUri = `at://${did}/social.grain.story/${rkey}`; 204 + const { queryClient } = await parent(); 205 + const prefetch = queryClient.prefetchQuery(storyQuery(storyUri, fetch)); 206 + if (!browser) await prefetch; 207 + return { did, rkey, storyUri }; 208 + }; 198 209 ``` 199 210 200 211 **Step 2: Add `storyQuery` to `app/lib/queries.ts`** ··· 218 229 This is like `getStories.ts` but fetches a single story by URI with NO 24h filter: 219 230 220 231 ```ts 221 - import { defineQuery } from "$hatk" 222 - import { views } from "$hatk" 223 - import type { GrainActorProfile, Story } from "$hatk" 232 + import { defineQuery } from "$hatk"; 233 + import { views } from "$hatk"; 234 + import type { GrainActorProfile, Story } from "$hatk"; 224 235 225 236 export default defineQuery("social.grain.unspecced.getStory", async (ctx) => { 226 - const { db, ok } = ctx 227 - const storyUri = ctx.params.story 228 - if (!storyUri) return ok({ story: null }) 237 + const { db, ok } = ctx; 238 + const storyUri = ctx.params.story; 239 + if (!storyUri) return ok({ story: null }); 229 240 230 241 const rows = (await db.query( 231 242 `SELECT uri, cid, did, media, aspect_ratio, location, address, created_at ··· 233 244 WHERE uri = $1`, 234 245 [storyUri], 235 246 )) as { 236 - uri: string 237 - cid: string 238 - did: string 239 - media: string 240 - aspect_ratio: string 241 - location: string | null 242 - address: string | null 243 - created_at: string 244 - }[] 247 + uri: string; 248 + cid: string; 249 + did: string; 250 + media: string; 251 + aspect_ratio: string; 252 + location: string | null; 253 + address: string | null; 254 + created_at: string; 255 + }[]; 245 256 246 - const row = rows[0] 247 - if (!row) return ok({ story: null }) 257 + const row = rows[0]; 258 + if (!row) return ok({ story: null }); 248 259 249 260 // Resolve author profile 250 - const profiles = await ctx.lookup<GrainActorProfile>("social.grain.actor.profile", "did", [row.did]) 251 - const author = profiles.get(row.did) 261 + const profiles = await ctx.lookup<GrainActorProfile>("social.grain.actor.profile", "did", [ 262 + row.did, 263 + ]); 264 + const author = profiles.get(row.did); 252 265 const profileView = author 253 266 ? views.grainActorDefsProfileView({ 254 267 cid: author.cid, ··· 261 274 cid: "", 262 275 did: row.did, 263 276 handle: row.did, 264 - }) 277 + }); 265 278 266 - let blobRef: any 279 + let blobRef: any; 267 280 try { 268 - blobRef = typeof row.media === "string" ? JSON.parse(row.media) : row.media 281 + blobRef = typeof row.media === "string" ? JSON.parse(row.media) : row.media; 269 282 } catch { 270 - blobRef = row.media 283 + blobRef = row.media; 271 284 } 272 285 273 - let aspectRatio: { width: number; height: number } 286 + let aspectRatio: { width: number; height: number }; 274 287 try { 275 - aspectRatio = typeof row.aspect_ratio === "string" ? JSON.parse(row.aspect_ratio) : row.aspect_ratio 288 + aspectRatio = 289 + typeof row.aspect_ratio === "string" ? JSON.parse(row.aspect_ratio) : row.aspect_ratio; 276 290 } catch { 277 - aspectRatio = { width: 4, height: 3 } 291 + aspectRatio = { width: 4, height: 3 }; 278 292 } 279 293 280 - let location: Story["location"] | null = null 294 + let location: Story["location"] | null = null; 281 295 if (row.location) { 282 296 try { 283 - location = typeof row.location === "string" ? JSON.parse(row.location) : row.location 297 + location = typeof row.location === "string" ? JSON.parse(row.location) : row.location; 284 298 } catch { 285 - location = null 299 + location = null; 286 300 } 287 301 } 288 302 289 - let address: Story["address"] | null = null 303 + let address: Story["address"] | null = null; 290 304 if (row.address) { 291 305 try { 292 - address = typeof row.address === "string" ? JSON.parse(row.address) : row.address 306 + address = typeof row.address === "string" ? JSON.parse(row.address) : row.address; 293 307 } catch { 294 - address = null 308 + address = null; 295 309 } 296 310 } 297 311 298 312 // Cross-post lookup 299 - let crossPost: { url: string } | undefined 300 - const rkey = row.uri.split("/").pop() 301 - const searchUrl = `grain.social/profile/${row.did}/story/${rkey}` 313 + let crossPost: { url: string } | undefined; 314 + const rkey = row.uri.split("/").pop(); 315 + const searchUrl = `grain.social/profile/${row.did}/story/${rkey}`; 302 316 const postRows = (await db.query( 303 317 `SELECT uri FROM "app.bsky.feed.post" WHERE did = $1 AND "text" LIKE '%' || $2 || '%' LIMIT 1`, 304 318 [row.did, searchUrl], 305 - )) as Array<{ uri: string }> 319 + )) as Array<{ uri: string }>; 306 320 if (postRows.length) { 307 - const postRkey = postRows[0].uri.split("/").pop() 308 - crossPost = { url: `https://bsky.app/profile/${row.did}/post/${postRkey}` } 321 + const postRkey = postRows[0].uri.split("/").pop(); 322 + crossPost = { url: `https://bsky.app/profile/${row.did}/post/${postRkey}` }; 309 323 } 310 324 311 325 const story = views.storyView({ ··· 323 337 : {}), 324 338 ...(crossPost ? { crossPost } : {}), 325 339 createdAt: row.created_at, 326 - }) 340 + }); 327 341 328 - return ok({ story }) 329 - }) 342 + return ok({ story }); 343 + }); 330 344 ``` 331 345 332 346 **Step 4: Create the lexicon `lexicons/social/grain/unspecced/getStory.json`** ··· 508 522 ### Task 3: Add "Post to Bluesky" to StoryCreate 509 523 510 524 **Files:** 525 + 511 526 - Modify: `app/lib/components/molecules/StoryCreate.svelte` 512 527 513 528 **Step 1: Add checkbox and Bluesky posting to StoryCreate** 514 529 515 530 Add imports: 531 + 516 532 ```ts 517 - import Checkbox from '$lib/components/atoms/Checkbox.svelte' 518 - import { createBskyPost } from '$lib/utils/bsky-post' 519 - import { viewer } from '$lib/stores' 533 + import Checkbox from "$lib/components/atoms/Checkbox.svelte"; 534 + import { createBskyPost } from "$lib/utils/bsky-post"; 535 + import { viewer } from "$lib/stores"; 520 536 ``` 521 537 522 538 Add state: 539 + 523 540 ```ts 524 - let postToBluesky = $state(false) 541 + let postToBluesky = $state(false); 525 542 ``` 526 543 527 544 After the existing `await callXrpc('dev.hatk.createRecord', ...)` in `publish()`, add: 528 545 529 546 ```ts 530 - const storyUri = (result as any).uri as string 547 + const storyUri = (result as any).uri as string; 531 548 532 549 // Post to Bluesky if opted in 533 550 if (postToBluesky && $viewer) { 534 - const storyRkey = storyUri.split('/').pop() 535 - const storyUrl = `https://grain.social/profile/${$viewer.did}/story/${storyRkey}` 551 + const storyRkey = storyUri.split("/").pop(); 552 + const storyUrl = `https://grain.social/profile/${$viewer.did}/story/${storyRkey}`; 536 553 await createBskyPost({ 537 554 url: storyUrl, 538 - location: location ? { 539 - name: location.name, 540 - address: location.address, 541 - } : null, 542 - images: [{ 543 - dataUrl: photo.dataUrl, 544 - alt: '', 545 - width: photo.width, 546 - height: photo.height, 547 - }], 548 - }) 555 + location: location 556 + ? { 557 + name: location.name, 558 + address: location.address, 559 + } 560 + : null, 561 + images: [ 562 + { 563 + dataUrl: photo.dataUrl, 564 + alt: "", 565 + width: photo.width, 566 + height: photo.height, 567 + }, 568 + ], 569 + }); 549 570 } 550 571 ``` 551 572 552 573 Add checkbox in the template below the LocationInput: 574 + 553 575 ```svelte 554 576 <Checkbox bind:checked={postToBluesky} label="Post to Bluesky" /> 555 577 ``` ··· 566 588 ### Task 4: OG image endpoint for stories (optional but recommended) 567 589 568 590 **Files:** 591 + 569 592 - Create: `server/og/story.ts` 570 593 571 594 **Step 1: Create `server/og/story.ts`** ··· 573 596 Simpler than gallery OG — single image with author info: 574 597 575 598 ```ts 576 - import { defineOG } from "$hatk" 577 - import type { GrainActorProfile, Story } from "$hatk" 599 + import { defineOG } from "$hatk"; 600 + import type { GrainActorProfile, Story } from "$hatk"; 578 601 579 602 export default defineOG("/og/profile/:did/story/:rkey", async (ctx) => { 580 - const { db, params, fetchImage, lookup, blobUrl } = ctx 581 - const { did, rkey } = params 603 + const { db, params, fetchImage, lookup, blobUrl } = ctx; 604 + const { did, rkey } = params; 582 605 583 - const storyUri = `at://${did}/social.grain.story/${rkey}` 606 + const storyUri = `at://${did}/social.grain.story/${rkey}`; 584 607 585 608 const rows = (await db.query( 586 609 `SELECT uri, did, cid, media, aspect_ratio FROM "social.grain.story" WHERE uri = $1`, 587 610 [storyUri], 588 611 )) as Array<{ 589 - uri: string 590 - did: string 591 - cid: string 592 - media: string 593 - aspect_ratio: string 594 - }> 612 + uri: string; 613 + did: string; 614 + cid: string; 615 + media: string; 616 + aspect_ratio: string; 617 + }>; 595 618 596 - const row = rows[0] 619 + const row = rows[0]; 597 620 if (!row) { 598 621 return { 599 622 element: { 600 623 type: "div", 601 624 props: { 602 - style: { display: "flex", width: "100%", height: "100%", background: "#ffffff", color: "#171717", alignItems: "center", justifyContent: "center" }, 625 + style: { 626 + display: "flex", 627 + width: "100%", 628 + height: "100%", 629 + background: "#ffffff", 630 + color: "#171717", 631 + alignItems: "center", 632 + justifyContent: "center", 633 + }, 603 634 children: "Story not found", 604 635 }, 605 636 }, 606 - } 637 + }; 607 638 } 608 639 609 - let blobRef: any 640 + let blobRef: any; 610 641 try { 611 - blobRef = typeof row.media === "string" ? JSON.parse(row.media) : row.media 642 + blobRef = typeof row.media === "string" ? JSON.parse(row.media) : row.media; 612 643 } catch { 613 - blobRef = row.media 644 + blobRef = row.media; 614 645 } 615 646 616 - const imageUrl = blobUrl(row.did, blobRef, "feed_fullsize") 617 - const imageDataUrl = imageUrl ? await fetchImage(imageUrl) : null 647 + const imageUrl = blobUrl(row.did, blobRef, "feed_fullsize"); 648 + const imageDataUrl = imageUrl ? await fetchImage(imageUrl) : null; 618 649 619 - const profiles = await lookup<GrainActorProfile>("social.grain.actor.profile", "did", [did]) 620 - const author = profiles.get(did) 621 - const avatarRef = author ? blobUrl(did, author.value.avatar) : null 622 - const avatarDataUrl = avatarRef ? await fetchImage(avatarRef) : null 650 + const profiles = await lookup<GrainActorProfile>("social.grain.actor.profile", "did", [did]); 651 + const author = profiles.get(did); 652 + const avatarRef = author ? blobUrl(did, author.value.avatar) : null; 653 + const avatarDataUrl = avatarRef ? await fetchImage(avatarRef) : null; 623 654 624 655 return { 625 656 element: { 626 657 type: "div", 627 658 props: { 628 - style: { display: "flex", width: "100%", height: "100%", backgroundColor: "#000000", position: "relative" }, 659 + style: { 660 + display: "flex", 661 + width: "100%", 662 + height: "100%", 663 + backgroundColor: "#000000", 664 + position: "relative", 665 + }, 629 666 children: [ 630 - ...(imageDataUrl ? [{ 631 - type: "img", 632 - props: { 633 - src: imageDataUrl, 634 - style: { width: "100%", height: "100%", objectFit: "contain" }, 635 - }, 636 - }] : []), 667 + ...(imageDataUrl 668 + ? [ 669 + { 670 + type: "img", 671 + props: { 672 + src: imageDataUrl, 673 + style: { width: "100%", height: "100%", objectFit: "contain" }, 674 + }, 675 + }, 676 + ] 677 + : []), 637 678 { 638 679 type: "div", 639 680 props: { 640 681 style: { 641 - position: "absolute", bottom: "0", left: "0", right: "0", height: "80px", 682 + position: "absolute", 683 + bottom: "0", 684 + left: "0", 685 + right: "0", 686 + height: "80px", 642 687 background: "linear-gradient(transparent, rgba(0,0,0,0.7))", 643 - display: "flex", alignItems: "flex-end", padding: "0 24px 16px 24px", gap: "12px", 688 + display: "flex", 689 + alignItems: "flex-end", 690 + padding: "0 24px 16px 24px", 691 + gap: "12px", 644 692 }, 645 693 children: [ 646 - ...(avatarDataUrl ? [{ 647 - type: "img", 648 - props: { 649 - src: avatarDataUrl, 650 - style: { width: "44px", height: "44px", borderRadius: "22px", objectFit: "cover" as const }, 651 - }, 652 - }] : []), 694 + ...(avatarDataUrl 695 + ? [ 696 + { 697 + type: "img", 698 + props: { 699 + src: avatarDataUrl, 700 + style: { 701 + width: "44px", 702 + height: "44px", 703 + borderRadius: "22px", 704 + objectFit: "cover" as const, 705 + }, 706 + }, 707 + }, 708 + ] 709 + : []), 653 710 { 654 711 type: "div", 655 712 props: { ··· 658 715 { 659 716 type: "div", 660 717 props: { 661 - children: author?.value.displayName || `@${author?.handle || did.slice(0, 24)}`, 718 + children: 719 + author?.value.displayName || `@${author?.handle || did.slice(0, 24)}`, 662 720 style: { fontSize: 24, fontWeight: 600, color: "#ffffff" }, 663 721 }, 664 722 }, ··· 682 740 title: `Story by @${author?.handle || did.slice(0, 24)} — Grain`, 683 741 description: "Photo story on Grain", 684 742 }, 685 - } 686 - }) 743 + }; 744 + }); 687 745 ``` 688 746 689 747 **Step 2: Update story permalink OGMeta to use the OG endpoint**
+2
docs/plans/2026-03-29-story-archive-design.md
··· 38 38 ## Files 39 39 40 40 **New:** 41 + 41 42 - `server/xrpc/getStoryArchive.ts` 42 43 - `lexicons/social/grain/unspecced/getStoryArchive.json` 43 44 - `app/lib/components/molecules/StoryArchive.svelte` 44 45 45 46 **Modified:** 47 + 46 48 - `app/lib/queries.ts` — add `storyArchiveQuery` 47 49 - `app/routes/profile/[did]/+page.svelte` — archive button + grid section 48 50 - `app/lib/components/organisms/StoryViewer.svelte` — single-story mode, full date for old stories
+46 -35
docs/plans/2026-03-29-story-archive-plan.md
··· 13 13 ### Task 1: Lexicon + Server Endpoint 14 14 15 15 **Files:** 16 + 16 17 - Create: `lexicons/social/grain/unspecced/getStoryArchive.json` 17 18 - Create: `server/xrpc/getStoryArchive.ts` 18 19 ··· 59 60 **Step 2: Create the server endpoint** 60 61 61 62 Create `server/xrpc/getStoryArchive.ts`. This mirrors `server/xrpc/getStories.ts` with these differences: 63 + 62 64 - No 24-hour cutoff 63 65 - `ORDER BY created_at DESC` (newest first, not ASC) 64 66 - Cursor-based pagination using `created_at` timestamp ··· 226 228 ### Task 2: Client Query 227 229 228 230 **Files:** 231 + 229 232 - Modify: `app/lib/queries.ts` (add after `storiesQuery` around line 89) 230 233 231 234 **Step 1: Add `storyArchiveQuery` to queries.ts** ··· 237 240 queryOptions({ 238 241 queryKey: ["stories", "archive", did, cursor], 239 242 queryFn: () => 240 - callXrpc("social.grain.unspecced.getStoryArchive", { actor: did, ...(cursor ? { cursor } : {}) }, f).then( 241 - (r) => r ?? { stories: [], cursor: undefined }, 242 - ), 243 + callXrpc( 244 + "social.grain.unspecced.getStoryArchive", 245 + { actor: did, ...(cursor ? { cursor } : {}) }, 246 + f, 247 + ).then((r) => r ?? { stories: [], cursor: undefined }), 243 248 staleTime: 60_000, 244 249 }); 245 250 ``` ··· 261 266 ### Task 3: StoryViewer — Single-Story Mode + Date Formatting 262 267 263 268 **Files:** 269 + 264 270 - Modify: `app/lib/components/organisms/StoryViewer.svelte` 265 271 266 272 **Step 1: Add `singleStory` prop** ··· 273 279 onclose, 274 280 singleStory, 275 281 }: { 276 - initialDid: string 277 - onclose: () => void 278 - singleStory?: { uri: string } | null 279 - } = $props() 282 + initialDid: string; 283 + onclose: () => void; 284 + singleStory?: { uri: string } | null; 285 + } = $props(); 280 286 ``` 281 287 282 288 **Step 2: Override story loading in single-story mode** ··· 286 292 Add a new import at line 6: 287 293 288 294 ```typescript 289 - import { storiesQuery, storyAuthorsQuery, storyQuery } from '$lib/queries' 295 + import { storiesQuery, storyAuthorsQuery, storyQuery } from "$lib/queries"; 290 296 ``` 291 297 292 298 Add after the `storyAuthors` query (around line 23): ··· 294 300 ```typescript 295 301 // Single-story mode: load just one story by URI 296 302 const singleStoryData = createQuery(() => ({ 297 - ...storyQuery(singleStory?.uri ?? ''), 303 + ...storyQuery(singleStory?.uri ?? ""), 298 304 enabled: !!singleStory, 299 - })) 305 + })); 300 306 ``` 301 307 302 308 Override `stories` and `authorDids` derivations. Replace the existing `stories` line (line 55) and `totalStories` (line 58) with: 303 309 304 310 ```typescript 305 311 const stories = createQuery(() => 306 - singleStory ? { ...storyQuery(singleStory.uri), enabled: true } : storiesQuery(currentDid) 307 - ) 312 + singleStory ? { ...storyQuery(singleStory.uri), enabled: true } : storiesQuery(currentDid), 313 + ); 308 314 309 315 const currentStory = $derived( 310 - singleStory 311 - ? (singleStoryData.data ?? undefined) 312 - : stories.data?.[currentStoryIndex] 313 - ) 314 - const totalStories = $derived(singleStory ? 1 : (stories.data?.length ?? 0)) 316 + singleStory ? (singleStoryData.data ?? undefined) : stories.data?.[currentStoryIndex], 317 + ); 318 + const totalStories = $derived(singleStory ? 1 : (stories.data?.length ?? 0)); 315 319 ``` 316 320 317 321 **Step 3: Disable author swiping in single-story mode** ··· 321 325 ```typescript 322 326 function next() { 323 327 if (currentStoryIndex < totalStories - 1) { 324 - currentStoryIndex++ 325 - progress = 0 328 + currentStoryIndex++; 329 + progress = 0; 326 330 } else if (!singleStory && currentAuthorIndex < authorDids.length - 1) { 327 - currentAuthorIndex++ 331 + currentAuthorIndex++; 328 332 } else { 329 - onclose() 333 + onclose(); 330 334 } 331 335 } 332 336 ``` ··· 336 340 ```typescript 337 341 function prev() { 338 342 if (currentStoryIndex > 0) { 339 - currentStoryIndex-- 340 - progress = 0 343 + currentStoryIndex--; 344 + progress = 0; 341 345 } else if (!singleStory && currentAuthorIndex > 0) { 342 - currentAuthorIndex-- 346 + currentAuthorIndex--; 343 347 } 344 348 } 345 349 ``` ··· 350 354 351 355 ```typescript 352 356 function timeAgo(dateStr: string): string { 353 - const diff = Date.now() - new Date(dateStr).getTime() 354 - const hours = Math.floor(diff / (1000 * 60 * 60)) 357 + const diff = Date.now() - new Date(dateStr).getTime(); 358 + const hours = Math.floor(diff / (1000 * 60 * 60)); 355 359 if (hours < 1) { 356 - const mins = Math.floor(diff / (1000 * 60)) 357 - return `${mins}m` 360 + const mins = Math.floor(diff / (1000 * 60)); 361 + return `${mins}m`; 358 362 } 359 363 if (hours < 24) { 360 - return `${hours}h` 364 + return `${hours}h`; 361 365 } 362 - return new Date(dateStr).toLocaleDateString(undefined, { month: 'short', day: 'numeric' }) 366 + return new Date(dateStr).toLocaleDateString(undefined, { month: "short", day: "numeric" }); 363 367 } 364 368 ``` 365 369 ··· 380 384 ### Task 4: StoryArchive Grid Component 381 385 382 386 **Files:** 387 + 383 388 - Create: `app/lib/components/molecules/StoryArchive.svelte` 384 389 385 390 **Step 1: Create the component** ··· 559 564 ### Task 5: Wire Into Profile Page 560 565 561 566 **Files:** 567 + 562 568 - Modify: `app/routes/profile/[did]/+page.svelte` 563 569 564 570 **Step 1: Add imports and state** ··· 566 572 Add to the imports (after the StoryViewer import, line 15): 567 573 568 574 ```typescript 569 - import StoryArchive from '$lib/components/molecules/StoryArchive.svelte' 570 - import { Archive } from 'lucide-svelte' 575 + import StoryArchive from "$lib/components/molecules/StoryArchive.svelte"; 576 + import { Archive } from "lucide-svelte"; 571 577 ``` 572 578 573 579 Add state variable (after `showStoryViewer` at line 21): 574 580 575 581 ```typescript 576 - let showArchive = $state(false) 582 + let showArchive = $state(false); 577 583 ``` 578 584 579 585 Add derived (after `hasStory` at line 30): 580 586 581 587 ```typescript 582 - const isOwnProfile = $derived(viewerDid === did) 588 + const isOwnProfile = $derived(viewerDid === did); 583 589 ``` 584 590 585 591 **Step 2: Add archive button to the profile header** ··· 668 674 Update the existing `$effect` at line 24 to also reset archive state: 669 675 670 676 ```typescript 671 - $effect(() => { void did; void profile.data; followersOffset = 0; showArchive = false }) 677 + $effect(() => { 678 + void did; 679 + void profile.data; 680 + followersOffset = 0; 681 + showArchive = false; 682 + }); 672 683 ``` 673 684 674 685 **Step 6: Verify types**
+37 -149
lexicons/app/bsky/actor/defs.json
··· 3 3 "defs": { 4 4 "nux": { 5 5 "type": "object", 6 - "required": [ 7 - "id", 8 - "completed" 9 - ], 6 + "required": ["id", "completed"], 10 7 "properties": { 11 8 "id": { 12 9 "type": "string", ··· 32 29 }, 33 30 "mutedWord": { 34 31 "type": "object", 35 - "required": [ 36 - "value", 37 - "targets" 38 - ], 32 + "required": ["value", "targets"], 39 33 "properties": { 40 34 "id": { 41 35 "type": "string" ··· 63 57 "type": "string", 64 58 "default": "all", 65 59 "description": "Groups of users to apply the muted word to. If undefined, applies to all users.", 66 - "knownValues": [ 67 - "all", 68 - "exclude-following" 69 - ] 60 + "knownValues": ["all", "exclude-following"] 70 61 } 71 62 }, 72 63 "description": "A word that the account owner has muted." 73 64 }, 74 65 "savedFeed": { 75 66 "type": "object", 76 - "required": [ 77 - "id", 78 - "type", 79 - "value", 80 - "pinned" 81 - ], 67 + "required": ["id", "type", "value", "pinned"], 82 68 "properties": { 83 69 "id": { 84 70 "type": "string" 85 71 }, 86 72 "type": { 87 73 "type": "string", 88 - "knownValues": [ 89 - "feed", 90 - "list", 91 - "timeline" 92 - ] 74 + "knownValues": ["feed", "list", "timeline"] 93 75 }, 94 76 "value": { 95 77 "type": "string" ··· 101 83 }, 102 84 "statusView": { 103 85 "type": "object", 104 - "required": [ 105 - "status", 106 - "record" 107 - ], 86 + "required": ["status", "record"], 108 87 "properties": { 109 88 "cid": { 110 89 "type": "string", ··· 115 94 "format": "at-uri" 116 95 }, 117 96 "embed": { 118 - "refs": [ 119 - "app.bsky.embed.external#view" 120 - ], 97 + "refs": ["app.bsky.embed.external#view"], 121 98 "type": "union", 122 99 "description": "An optional embed associated with the status." 123 100 }, ··· 127 104 "status": { 128 105 "type": "string", 129 106 "description": "The status for the account.", 130 - "knownValues": [ 131 - "app.bsky.actor.status#live" 132 - ] 107 + "knownValues": ["app.bsky.actor.status#live"] 133 108 }, 134 109 "isActive": { 135 110 "type": "boolean", ··· 172 147 }, 173 148 "profileView": { 174 149 "type": "object", 175 - "required": [ 176 - "did", 177 - "handle" 178 - ], 150 + "required": ["did", "handle"], 179 151 "properties": { 180 152 "did": { 181 153 "type": "string", ··· 283 255 }, 284 256 "feedViewPref": { 285 257 "type": "object", 286 - "required": [ 287 - "feed" 288 - ], 258 + "required": ["feed"], 289 259 "properties": { 290 260 "feed": { 291 261 "type": "string", ··· 316 286 }, 317 287 "labelersPref": { 318 288 "type": "object", 319 - "required": [ 320 - "labelers" 321 - ], 289 + "required": ["labelers"], 322 290 "properties": { 323 291 "labelers": { 324 292 "type": "array", ··· 331 299 }, 332 300 "interestsPref": { 333 301 "type": "object", 334 - "required": [ 335 - "tags" 336 - ], 302 + "required": ["tags"], 337 303 "properties": { 338 304 "tags": { 339 305 "type": "array", ··· 349 315 }, 350 316 "knownFollowers": { 351 317 "type": "object", 352 - "required": [ 353 - "count", 354 - "followers" 355 - ], 318 + "required": ["count", "followers"], 356 319 "properties": { 357 320 "count": { 358 321 "type": "integer" ··· 371 334 }, 372 335 "mutedWordsPref": { 373 336 "type": "object", 374 - "required": [ 375 - "items" 376 - ], 337 + "required": ["items"], 377 338 "properties": { 378 339 "items": { 379 340 "type": "array", ··· 387 348 }, 388 349 "savedFeedsPref": { 389 350 "type": "object", 390 - "required": [ 391 - "pinned", 392 - "saved" 393 - ], 351 + "required": ["pinned", "saved"], 394 352 "properties": { 395 353 "saved": { 396 354 "type": "array", ··· 417 375 "sort": { 418 376 "type": "string", 419 377 "description": "Sorting mode for threads.", 420 - "knownValues": [ 421 - "oldest", 422 - "newest", 423 - "most-likes", 424 - "random", 425 - "hotness" 426 - ] 378 + "knownValues": ["oldest", "newest", "most-likes", "random", "hotness"] 427 379 } 428 380 } 429 381 }, ··· 447 399 }, 448 400 "hiddenPostsPref": { 449 401 "type": "object", 450 - "required": [ 451 - "items" 452 - ], 402 + "required": ["items"], 453 403 "properties": { 454 404 "items": { 455 405 "type": "array", ··· 463 413 }, 464 414 "labelerPrefItem": { 465 415 "type": "object", 466 - "required": [ 467 - "did" 468 - ], 416 + "required": ["did"], 469 417 "properties": { 470 418 "did": { 471 419 "type": "string", ··· 476 424 "mutedWordTarget": { 477 425 "type": "string", 478 426 "maxLength": 640, 479 - "knownValues": [ 480 - "content", 481 - "tag" 482 - ], 427 + "knownValues": ["content", "tag"], 483 428 "maxGraphemes": 64 484 429 }, 485 430 "adultContentPref": { 486 431 "type": "object", 487 - "required": [ 488 - "enabled" 489 - ], 432 + "required": ["enabled"], 490 433 "properties": { 491 434 "enabled": { 492 435 "type": "boolean", ··· 524 467 }, 525 468 "contentLabelPref": { 526 469 "type": "object", 527 - "required": [ 528 - "label", 529 - "visibility" 530 - ], 470 + "required": ["label", "visibility"], 531 471 "properties": { 532 472 "label": { 533 473 "type": "string" ··· 539 479 }, 540 480 "visibility": { 541 481 "type": "string", 542 - "knownValues": [ 543 - "ignore", 544 - "show", 545 - "warn", 546 - "hide" 547 - ] 482 + "knownValues": ["ignore", "show", "warn", "hide"] 548 483 } 549 484 } 550 485 }, 551 486 "profileViewBasic": { 552 487 "type": "object", 553 - "required": [ 554 - "did", 555 - "handle" 556 - ], 488 + "required": ["did", "handle"], 557 489 "properties": { 558 490 "did": { 559 491 "type": "string", ··· 610 542 }, 611 543 "savedFeedsPrefV2": { 612 544 "type": "object", 613 - "required": [ 614 - "items" 615 - ], 545 + "required": ["items"], 616 546 "properties": { 617 547 "items": { 618 548 "type": "array", ··· 625 555 }, 626 556 "verificationView": { 627 557 "type": "object", 628 - "required": [ 629 - "issuer", 630 - "uri", 631 - "isValid", 632 - "createdAt" 633 - ], 558 + "required": ["issuer", "uri", "isValid", "createdAt"], 634 559 "properties": { 635 560 "uri": { 636 561 "type": "string", ··· 697 622 }, 698 623 "verificationState": { 699 624 "type": "object", 700 - "required": [ 701 - "verifications", 702 - "verifiedStatus", 703 - "trustedVerifierStatus" 704 - ], 625 + "required": ["verifications", "verifiedStatus", "trustedVerifierStatus"], 705 626 "properties": { 706 627 "verifications": { 707 628 "type": "array", ··· 714 635 "verifiedStatus": { 715 636 "type": "string", 716 637 "description": "The user's status as a verified account.", 717 - "knownValues": [ 718 - "valid", 719 - "invalid", 720 - "none" 721 - ] 638 + "knownValues": ["valid", "invalid", "none"] 722 639 }, 723 640 "trustedVerifierStatus": { 724 641 "type": "string", 725 642 "description": "The user's status as a trusted verifier.", 726 - "knownValues": [ 727 - "valid", 728 - "invalid", 729 - "none" 730 - ] 643 + "knownValues": ["valid", "invalid", "none"] 731 644 } 732 645 }, 733 646 "description": "Represents the verification information about the user this object is attached to." ··· 744 657 }, 745 658 "profileViewDetailed": { 746 659 "type": "object", 747 - "required": [ 748 - "did", 749 - "handle" 750 - ], 660 + "required": ["did", "handle"], 751 661 "properties": { 752 662 "did": { 753 663 "type": "string", ··· 838 748 }, 839 749 "bskyAppProgressGuide": { 840 750 "type": "object", 841 - "required": [ 842 - "guide" 843 - ], 751 + "required": ["guide"], 844 752 "properties": { 845 753 "guide": { 846 754 "type": "string", ··· 869 777 }, 870 778 "profileAssociatedChat": { 871 779 "type": "object", 872 - "required": [ 873 - "allowIncoming" 874 - ], 780 + "required": ["allowIncoming"], 875 781 "properties": { 876 782 "allowIncoming": { 877 783 "type": "string", 878 - "knownValues": [ 879 - "all", 880 - "none", 881 - "following" 882 - ] 784 + "knownValues": ["all", "none", "following"] 883 785 } 884 786 } 885 787 }, 886 788 "profileAssociatedGerm": { 887 789 "type": "object", 888 - "required": [ 889 - "showButtonTo", 890 - "messageMeUrl" 891 - ], 790 + "required": ["showButtonTo", "messageMeUrl"], 892 791 "properties": { 893 792 "messageMeUrl": { 894 793 "type": "string", ··· 896 795 }, 897 796 "showButtonTo": { 898 797 "type": "string", 899 - "knownValues": [ 900 - "usersIFollow", 901 - "everyone" 902 - ] 798 + "knownValues": ["usersIFollow", "everyone"] 903 799 } 904 800 } 905 801 }, ··· 924 820 "postgateEmbeddingRules": { 925 821 "type": "array", 926 822 "items": { 927 - "refs": [ 928 - "app.bsky.feed.postgate#disableRule" 929 - ], 823 + "refs": ["app.bsky.feed.postgate#disableRule"], 930 824 "type": "union" 931 825 }, 932 826 "maxLength": 5, ··· 937 831 }, 938 832 "profileAssociatedActivitySubscription": { 939 833 "type": "object", 940 - "required": [ 941 - "allowSubscriptions" 942 - ], 834 + "required": ["allowSubscriptions"], 943 835 "properties": { 944 836 "allowSubscriptions": { 945 837 "type": "string", 946 - "knownValues": [ 947 - "followers", 948 - "mutuals", 949 - "none" 950 - ] 838 + "knownValues": ["followers", "mutuals", "none"] 951 839 } 952 840 } 953 841 }
+1 -4
lexicons/app/bsky/embed/defs.json
··· 3 3 "defs": { 4 4 "aspectRatio": { 5 5 "type": "object", 6 - "required": [ 7 - "width", 8 - "height" 9 - ], 6 + "required": ["width", "height"], 10 7 "properties": { 11 8 "width": { 12 9 "type": "integer",
+5 -19
lexicons/app/bsky/embed/external.json
··· 3 3 "defs": { 4 4 "main": { 5 5 "type": "object", 6 - "required": [ 7 - "external" 8 - ], 6 + "required": ["external"], 9 7 "properties": { 10 8 "external": { 11 9 "ref": "#external", ··· 16 14 }, 17 15 "view": { 18 16 "type": "object", 19 - "required": [ 20 - "external" 21 - ], 17 + "required": ["external"], 22 18 "properties": { 23 19 "external": { 24 20 "ref": "#viewExternal", ··· 28 24 }, 29 25 "external": { 30 26 "type": "object", 31 - "required": [ 32 - "uri", 33 - "title", 34 - "description" 35 - ], 27 + "required": ["uri", "title", "description"], 36 28 "properties": { 37 29 "uri": { 38 30 "type": "string", ··· 40 32 }, 41 33 "thumb": { 42 34 "type": "blob", 43 - "accept": [ 44 - "image/*" 45 - ], 35 + "accept": ["image/*"], 46 36 "maxSize": 1000000 47 37 }, 48 38 "title": { ··· 55 45 }, 56 46 "viewExternal": { 57 47 "type": "object", 58 - "required": [ 59 - "uri", 60 - "title", 61 - "description" 62 - ], 48 + "required": ["uri", "title", "description"], 63 49 "properties": { 64 50 "uri": { 65 51 "type": "string",
+5 -18
lexicons/app/bsky/embed/images.json
··· 3 3 "defs": { 4 4 "main": { 5 5 "type": "object", 6 - "required": [ 7 - "images" 8 - ], 6 + "required": ["images"], 9 7 "properties": { 10 8 "images": { 11 9 "type": "array", ··· 19 17 }, 20 18 "view": { 21 19 "type": "object", 22 - "required": [ 23 - "images" 24 - ], 20 + "required": ["images"], 25 21 "properties": { 26 22 "images": { 27 23 "type": "array", ··· 35 31 }, 36 32 "image": { 37 33 "type": "object", 38 - "required": [ 39 - "image", 40 - "alt" 41 - ], 34 + "required": ["image", "alt"], 42 35 "properties": { 43 36 "alt": { 44 37 "type": "string", ··· 46 39 }, 47 40 "image": { 48 41 "type": "blob", 49 - "accept": [ 50 - "image/*" 51 - ], 42 + "accept": ["image/*"], 52 43 "maxSize": 1000000 53 44 }, 54 45 "aspectRatio": { ··· 59 50 }, 60 51 "viewImage": { 61 52 "type": "object", 62 - "required": [ 63 - "thumb", 64 - "fullsize", 65 - "alt" 66 - ], 53 + "required": ["thumb", "fullsize", "alt"], 67 54 "properties": { 68 55 "alt": { 69 56 "type": "string",
+6 -26
lexicons/app/bsky/embed/record.json
··· 3 3 "defs": { 4 4 "main": { 5 5 "type": "object", 6 - "required": [ 7 - "record" 8 - ], 6 + "required": ["record"], 9 7 "properties": { 10 8 "record": { 11 9 "ref": "com.atproto.repo.strongRef", ··· 15 13 }, 16 14 "view": { 17 15 "type": "object", 18 - "required": [ 19 - "record" 20 - ], 16 + "required": ["record"], 21 17 "properties": { 22 18 "record": { 23 19 "refs": [ ··· 36 32 }, 37 33 "viewRecord": { 38 34 "type": "object", 39 - "required": [ 40 - "uri", 41 - "cid", 42 - "author", 43 - "value", 44 - "indexedAt" 45 - ], 35 + "required": ["uri", "cid", "author", "value", "indexedAt"], 46 36 "properties": { 47 37 "cid": { 48 38 "type": "string", ··· 100 90 }, 101 91 "viewBlocked": { 102 92 "type": "object", 103 - "required": [ 104 - "uri", 105 - "blocked", 106 - "author" 107 - ], 93 + "required": ["uri", "blocked", "author"], 108 94 "properties": { 109 95 "uri": { 110 96 "type": "string", ··· 122 108 }, 123 109 "viewDetached": { 124 110 "type": "object", 125 - "required": [ 126 - "uri", 127 - "detached" 128 - ], 111 + "required": ["uri", "detached"], 129 112 "properties": { 130 113 "uri": { 131 114 "type": "string", ··· 139 122 }, 140 123 "viewNotFound": { 141 124 "type": "object", 142 - "required": [ 143 - "uri", 144 - "notFound" 145 - ], 125 + "required": ["uri", "notFound"], 146 126 "properties": { 147 127 "uri": { 148 128 "type": "string",
+3 -13
lexicons/app/bsky/embed/recordWithMedia.json
··· 3 3 "defs": { 4 4 "main": { 5 5 "type": "object", 6 - "required": [ 7 - "record", 8 - "media" 9 - ], 6 + "required": ["record", "media"], 10 7 "properties": { 11 8 "media": { 12 - "refs": [ 13 - "app.bsky.embed.images", 14 - "app.bsky.embed.video", 15 - "app.bsky.embed.external" 16 - ], 9 + "refs": ["app.bsky.embed.images", "app.bsky.embed.video", "app.bsky.embed.external"], 17 10 "type": "union" 18 11 }, 19 12 "record": { ··· 24 17 }, 25 18 "view": { 26 19 "type": "object", 27 - "required": [ 28 - "record", 29 - "media" 30 - ], 20 + "required": ["record", "media"], 31 21 "properties": { 32 22 "media": { 33 23 "refs": [
+7 -25
lexicons/app/bsky/embed/video.json
··· 3 3 "defs": { 4 4 "main": { 5 5 "type": "object", 6 - "required": [ 7 - "video" 8 - ], 6 + "required": ["video"], 9 7 "properties": { 10 8 "alt": { 11 9 "type": "string", ··· 15 13 }, 16 14 "video": { 17 15 "type": "blob", 18 - "accept": [ 19 - "video/mp4" 20 - ], 16 + "accept": ["video/mp4"], 21 17 "maxSize": 100000000, 22 18 "description": "The mp4 video file. May be up to 100mb, formerly limited to 50mb." 23 19 }, ··· 36 32 "presentation": { 37 33 "type": "string", 38 34 "description": "A hint to the client about how to present the video.", 39 - "knownValues": [ 40 - "default", 41 - "gif" 42 - ] 35 + "knownValues": ["default", "gif"] 43 36 } 44 37 } 45 38 }, 46 39 "view": { 47 40 "type": "object", 48 - "required": [ 49 - "cid", 50 - "playlist" 51 - ], 41 + "required": ["cid", "playlist"], 52 42 "properties": { 53 43 "alt": { 54 44 "type": "string", ··· 74 64 "presentation": { 75 65 "type": "string", 76 66 "description": "A hint to the client about how to present the video.", 77 - "knownValues": [ 78 - "default", 79 - "gif" 80 - ] 67 + "knownValues": ["default", "gif"] 81 68 } 82 69 } 83 70 }, 84 71 "caption": { 85 72 "type": "object", 86 - "required": [ 87 - "lang", 88 - "file" 89 - ], 73 + "required": ["lang", "file"], 90 74 "properties": { 91 75 "file": { 92 76 "type": "blob", 93 - "accept": [ 94 - "text/vtt" 95 - ], 77 + "accept": ["text/vtt"], 96 78 "maxSize": 20000 97 79 }, 98 80 "lang": {
+17 -75
lexicons/app/bsky/feed/defs.json
··· 3 3 "defs": { 4 4 "postView": { 5 5 "type": "object", 6 - "required": [ 7 - "uri", 8 - "cid", 9 - "author", 10 - "record", 11 - "indexedAt" 12 - ], 6 + "required": ["uri", "cid", "author", "record", "indexedAt"], 13 7 "properties": { 14 8 "cid": { 15 9 "type": "string", ··· 78 72 }, 79 73 "replyRef": { 80 74 "type": "object", 81 - "required": [ 82 - "root", 83 - "parent" 84 - ], 75 + "required": ["root", "parent"], 85 76 "properties": { 86 77 "root": { 87 - "refs": [ 88 - "#postView", 89 - "#notFoundPost", 90 - "#blockedPost" 91 - ], 78 + "refs": ["#postView", "#notFoundPost", "#blockedPost"], 92 79 "type": "union" 93 80 }, 94 81 "parent": { 95 - "refs": [ 96 - "#postView", 97 - "#notFoundPost", 98 - "#blockedPost" 99 - ], 82 + "refs": ["#postView", "#notFoundPost", "#blockedPost"], 100 83 "type": "union" 101 84 }, 102 85 "grandparentAuthor": { ··· 112 95 }, 113 96 "blockedPost": { 114 97 "type": "object", 115 - "required": [ 116 - "uri", 117 - "blocked", 118 - "author" 119 - ], 98 + "required": ["uri", "blocked", "author"], 120 99 "properties": { 121 100 "uri": { 122 101 "type": "string", ··· 207 186 }, 208 187 "feedViewPost": { 209 188 "type": "object", 210 - "required": [ 211 - "post" 212 - ], 189 + "required": ["post"], 213 190 "properties": { 214 191 "post": { 215 192 "ref": "#postView", ··· 225 202 "description": "Unique identifier per request that may be passed back alongside interactions." 226 203 }, 227 204 "reason": { 228 - "refs": [ 229 - "#reasonRepost", 230 - "#reasonPin" 231 - ], 205 + "refs": ["#reasonRepost", "#reasonPin"], 232 206 "type": "union" 233 207 }, 234 208 "feedContext": { ··· 240 214 }, 241 215 "notFoundPost": { 242 216 "type": "object", 243 - "required": [ 244 - "uri", 245 - "notFound" 246 - ], 217 + "required": ["uri", "notFound"], 247 218 "properties": { 248 219 "uri": { 249 220 "type": "string", ··· 257 228 }, 258 229 "reasonRepost": { 259 230 "type": "object", 260 - "required": [ 261 - "by", 262 - "indexedAt" 263 - ], 231 + "required": ["by", "indexedAt"], 264 232 "properties": { 265 233 "by": { 266 234 "ref": "app.bsky.actor.defs#profileViewBasic", ··· 282 250 }, 283 251 "blockedAuthor": { 284 252 "type": "object", 285 - "required": [ 286 - "did" 287 - ], 253 + "required": ["did"], 288 254 "properties": { 289 255 "did": { 290 256 "type": "string", ··· 298 264 }, 299 265 "generatorView": { 300 266 "type": "object", 301 - "required": [ 302 - "uri", 303 - "cid", 304 - "did", 305 - "creator", 306 - "displayName", 307 - "indexedAt" 308 - ], 267 + "required": ["uri", "cid", "did", "creator", "displayName", "indexedAt"], 309 268 "properties": { 310 269 "cid": { 311 270 "type": "string", ··· 385 344 }, 386 345 "threadViewPost": { 387 346 "type": "object", 388 - "required": [ 389 - "post" 390 - ], 347 + "required": ["post"], 391 348 "properties": { 392 349 "post": { 393 350 "ref": "#postView", 394 351 "type": "ref" 395 352 }, 396 353 "parent": { 397 - "refs": [ 398 - "#threadViewPost", 399 - "#notFoundPost", 400 - "#blockedPost" 401 - ], 354 + "refs": ["#threadViewPost", "#notFoundPost", "#blockedPost"], 402 355 "type": "union" 403 356 }, 404 357 "replies": { 405 358 "type": "array", 406 359 "items": { 407 - "refs": [ 408 - "#threadViewPost", 409 - "#notFoundPost", 410 - "#blockedPost" 411 - ], 360 + "refs": ["#threadViewPost", "#notFoundPost", "#blockedPost"], 412 361 "type": "union" 413 362 } 414 363 }, ··· 471 420 }, 472 421 "skeletonFeedPost": { 473 422 "type": "object", 474 - "required": [ 475 - "post" 476 - ], 423 + "required": ["post"], 477 424 "properties": { 478 425 "post": { 479 426 "type": "string", 480 427 "format": "at-uri" 481 428 }, 482 429 "reason": { 483 - "refs": [ 484 - "#skeletonReasonRepost", 485 - "#skeletonReasonPin" 486 - ], 430 + "refs": ["#skeletonReasonRepost", "#skeletonReasonPin"], 487 431 "type": "union" 488 432 }, 489 433 "feedContext": { ··· 524 468 }, 525 469 "skeletonReasonRepost": { 526 470 "type": "object", 527 - "required": [ 528 - "repost" 529 - ], 471 + "required": ["repost"], 530 472 "properties": { 531 473 "repost": { 532 474 "type": "string",
+5 -20
lexicons/app/bsky/feed/post.json
··· 6 6 "type": "record", 7 7 "record": { 8 8 "type": "object", 9 - "required": [ 10 - "text", 11 - "createdAt" 12 - ], 9 + "required": ["text", "createdAt"], 13 10 "properties": { 14 11 "tags": { 15 12 "type": "array", ··· 59 56 "description": "Annotations of text (mentions, URLs, hashtags, etc)" 60 57 }, 61 58 "labels": { 62 - "refs": [ 63 - "com.atproto.label.defs#selfLabels" 64 - ], 59 + "refs": ["com.atproto.label.defs#selfLabels"], 65 60 "type": "union", 66 61 "description": "Self-label values for this post. Effectively content warnings." 67 62 }, ··· 84 79 }, 85 80 "entity": { 86 81 "type": "object", 87 - "required": [ 88 - "index", 89 - "type", 90 - "value" 91 - ], 82 + "required": ["index", "type", "value"], 92 83 "properties": { 93 84 "type": { 94 85 "type": "string", ··· 106 97 }, 107 98 "replyRef": { 108 99 "type": "object", 109 - "required": [ 110 - "root", 111 - "parent" 112 - ], 100 + "required": ["root", "parent"], 113 101 "properties": { 114 102 "root": { 115 103 "ref": "com.atproto.repo.strongRef", ··· 123 111 }, 124 112 "textSlice": { 125 113 "type": "object", 126 - "required": [ 127 - "start", 128 - "end" 129 - ], 114 + "required": ["start", "end"], 130 115 "properties": { 131 116 "end": { 132 117 "type": "integer",
+2 -7
lexicons/app/bsky/feed/postgate.json
··· 6 6 "type": "record", 7 7 "record": { 8 8 "type": "object", 9 - "required": [ 10 - "post", 11 - "createdAt" 12 - ], 9 + "required": ["post", "createdAt"], 13 10 "properties": { 14 11 "post": { 15 12 "type": "string", ··· 23 20 "embeddingRules": { 24 21 "type": "array", 25 22 "items": { 26 - "refs": [ 27 - "#disableRule" 28 - ], 23 + "refs": ["#disableRule"], 29 24 "type": "union" 30 25 }, 31 26 "maxLength": 5,
+3 -13
lexicons/app/bsky/feed/threadgate.json
··· 6 6 "type": "record", 7 7 "record": { 8 8 "type": "object", 9 - "required": [ 10 - "post", 11 - "createdAt" 12 - ], 9 + "required": ["post", "createdAt"], 13 10 "properties": { 14 11 "post": { 15 12 "type": "string", ··· 19 16 "allow": { 20 17 "type": "array", 21 18 "items": { 22 - "refs": [ 23 - "#mentionRule", 24 - "#followerRule", 25 - "#followingRule", 26 - "#listRule" 27 - ], 19 + "refs": ["#mentionRule", "#followerRule", "#followingRule", "#listRule"], 28 20 "type": "union" 29 21 }, 30 22 "maxLength": 5, ··· 49 41 }, 50 42 "listRule": { 51 43 "type": "object", 52 - "required": [ 53 - "list" 54 - ], 44 + "required": ["list"], 55 45 "properties": { 56 46 "list": { 57 47 "type": "string",
+7 -39
lexicons/app/bsky/graph/defs.json
··· 7 7 }, 8 8 "listView": { 9 9 "type": "object", 10 - "required": [ 11 - "uri", 12 - "cid", 13 - "creator", 14 - "name", 15 - "purpose", 16 - "indexedAt" 17 - ], 10 + "required": ["uri", "cid", "creator", "name", "purpose", "indexedAt"], 18 11 "properties": { 19 12 "cid": { 20 13 "type": "string", ··· 88 81 }, 89 82 "listItemView": { 90 83 "type": "object", 91 - "required": [ 92 - "uri", 93 - "subject" 94 - ], 84 + "required": ["uri", "subject"], 95 85 "properties": { 96 86 "uri": { 97 87 "type": "string", ··· 105 95 }, 106 96 "relationship": { 107 97 "type": "object", 108 - "required": [ 109 - "did" 110 - ], 98 + "required": ["did"], 111 99 "properties": { 112 100 "did": { 113 101 "type": "string", ··· 148 136 }, 149 137 "listViewBasic": { 150 138 "type": "object", 151 - "required": [ 152 - "uri", 153 - "cid", 154 - "name", 155 - "purpose" 156 - ], 139 + "required": ["uri", "cid", "name", "purpose"], 157 140 "properties": { 158 141 "cid": { 159 142 "type": "string", ··· 199 182 }, 200 183 "notFoundActor": { 201 184 "type": "object", 202 - "required": [ 203 - "actor", 204 - "notFound" 205 - ], 185 + "required": ["actor", "notFound"], 206 186 "properties": { 207 187 "actor": { 208 188 "type": "string", ··· 233 213 }, 234 214 "starterPackView": { 235 215 "type": "object", 236 - "required": [ 237 - "uri", 238 - "cid", 239 - "record", 240 - "creator", 241 - "indexedAt" 242 - ], 216 + "required": ["uri", "cid", "record", "creator", "indexedAt"], 243 217 "properties": { 244 218 "cid": { 245 219 "type": "string", ··· 299 273 }, 300 274 "starterPackViewBasic": { 301 275 "type": "object", 302 - "required": [ 303 - "uri", 304 - "cid", 305 - "record", 306 - "creator", 307 - "indexedAt" 308 - ], 276 + "required": ["uri", "cid", "record", "creator", "indexedAt"], 309 277 "properties": { 310 278 "cid": { 311 279 "type": "string",
+3 -16
lexicons/app/bsky/labeler/defs.json
··· 3 3 "defs": { 4 4 "labelerView": { 5 5 "type": "object", 6 - "required": [ 7 - "uri", 8 - "cid", 9 - "creator", 10 - "indexedAt" 11 - ], 6 + "required": ["uri", "cid", "creator", "indexedAt"], 12 7 "properties": { 13 8 "cid": { 14 9 "type": "string", ··· 45 40 }, 46 41 "labelerPolicies": { 47 42 "type": "object", 48 - "required": [ 49 - "labelValues" 50 - ], 43 + "required": ["labelValues"], 51 44 "properties": { 52 45 "labelValues": { 53 46 "type": "array", ··· 78 71 }, 79 72 "labelerViewDetailed": { 80 73 "type": "object", 81 - "required": [ 82 - "uri", 83 - "cid", 84 - "creator", 85 - "policies", 86 - "indexedAt" 87 - ], 74 + "required": ["uri", "cid", "creator", "policies", "indexedAt"], 88 75 "properties": { 89 76 "cid": { 90 77 "type": "string",
+7 -29
lexicons/app/bsky/notification/defs.json
··· 3 3 "defs": { 4 4 "preference": { 5 5 "type": "object", 6 - "required": [ 7 - "list", 8 - "push" 9 - ], 6 + "required": ["list", "push"], 10 7 "properties": { 11 8 "list": { 12 9 "type": "boolean" ··· 94 91 }, 95 92 "chatPreference": { 96 93 "type": "object", 97 - "required": [ 98 - "include", 99 - "push" 100 - ], 94 + "required": ["include", "push"], 101 95 "properties": { 102 96 "push": { 103 97 "type": "boolean" 104 98 }, 105 99 "include": { 106 100 "type": "string", 107 - "knownValues": [ 108 - "all", 109 - "accepted" 110 - ] 101 + "knownValues": ["all", "accepted"] 111 102 } 112 103 } 113 104 }, 114 105 "activitySubscription": { 115 106 "type": "object", 116 - "required": [ 117 - "post", 118 - "reply" 119 - ], 107 + "required": ["post", "reply"], 120 108 "properties": { 121 109 "post": { 122 110 "type": "boolean" ··· 128 116 }, 129 117 "filterablePreference": { 130 118 "type": "object", 131 - "required": [ 132 - "include", 133 - "list", 134 - "push" 135 - ], 119 + "required": ["include", "list", "push"], 136 120 "properties": { 137 121 "list": { 138 122 "type": "boolean" ··· 142 126 }, 143 127 "include": { 144 128 "type": "string", 145 - "knownValues": [ 146 - "all", 147 - "follows" 148 - ] 129 + "knownValues": ["all", "follows"] 149 130 } 150 131 } 151 132 }, 152 133 "subjectActivitySubscription": { 153 134 "type": "object", 154 - "required": [ 155 - "subject", 156 - "activitySubscription" 157 - ], 135 + "required": ["subject", "activitySubscription"], 158 136 "properties": { 159 137 "subject": { 160 138 "type": "string",
+6 -22
lexicons/app/bsky/richtext/facet.json
··· 3 3 "defs": { 4 4 "tag": { 5 5 "type": "object", 6 - "required": [ 7 - "tag" 8 - ], 6 + "required": ["tag"], 9 7 "properties": { 10 8 "tag": { 11 9 "type": "string", ··· 17 15 }, 18 16 "link": { 19 17 "type": "object", 20 - "required": [ 21 - "uri" 22 - ], 18 + "required": ["uri"], 23 19 "properties": { 24 20 "uri": { 25 21 "type": "string", ··· 30 26 }, 31 27 "main": { 32 28 "type": "object", 33 - "required": [ 34 - "index", 35 - "features" 36 - ], 29 + "required": ["index", "features"], 37 30 "properties": { 38 31 "index": { 39 32 "ref": "#byteSlice", ··· 42 35 "features": { 43 36 "type": "array", 44 37 "items": { 45 - "refs": [ 46 - "#mention", 47 - "#link", 48 - "#tag" 49 - ], 38 + "refs": ["#mention", "#link", "#tag"], 50 39 "type": "union" 51 40 } 52 41 } ··· 55 44 }, 56 45 "mention": { 57 46 "type": "object", 58 - "required": [ 59 - "did" 60 - ], 47 + "required": ["did"], 61 48 "properties": { 62 49 "did": { 63 50 "type": "string", ··· 68 55 }, 69 56 "byteSlice": { 70 57 "type": "object", 71 - "required": [ 72 - "byteStart", 73 - "byteEnd" 74 - ], 58 + "required": ["byteStart", "byteEnd"], 75 59 "properties": { 76 60 "byteEnd": { 77 61 "type": "integer",
+8 -38
lexicons/com/atproto/label/defs.json
··· 5 5 "label": { 6 6 "type": "object", 7 7 "description": "Metadata tag on an atproto resource (eg, repo or record).", 8 - "required": [ 9 - "src", 10 - "uri", 11 - "val", 12 - "cts" 13 - ], 8 + "required": ["src", "uri", "val", "cts"], 14 9 "properties": { 15 10 "ver": { 16 11 "type": "integer" ··· 50 45 "selfLabels": { 51 46 "type": "object", 52 47 "description": "Metadata tags on an atproto record, published by the author within the record.", 53 - "required": [ 54 - "values" 55 - ], 48 + "required": ["values"], 56 49 "properties": { 57 50 "values": { 58 51 "type": "array", ··· 66 59 }, 67 60 "selfLabel": { 68 61 "type": "object", 69 - "required": [ 70 - "val" 71 - ], 62 + "required": ["val"], 72 63 "properties": { 73 64 "val": { 74 65 "type": "string", ··· 79 70 "labelValueDefinition": { 80 71 "type": "object", 81 72 "description": "Declares a label value and its expected interpretations and behaviors.", 82 - "required": [ 83 - "identifier", 84 - "severity", 85 - "blurs", 86 - "locales" 87 - ], 73 + "required": ["identifier", "severity", "blurs", "locales"], 88 74 "properties": { 89 75 "identifier": { 90 76 "type": "string", ··· 92 78 }, 93 79 "severity": { 94 80 "type": "string", 95 - "knownValues": [ 96 - "inform", 97 - "alert", 98 - "none" 99 - ] 81 + "knownValues": ["inform", "alert", "none"] 100 82 }, 101 83 "blurs": { 102 84 "type": "string", 103 - "knownValues": [ 104 - "content", 105 - "media", 106 - "none" 107 - ] 85 + "knownValues": ["content", "media", "none"] 108 86 }, 109 87 "defaultSetting": { 110 88 "type": "string", 111 - "knownValues": [ 112 - "ignore", 113 - "warn", 114 - "hide" 115 - ] 89 + "knownValues": ["ignore", "warn", "hide"] 116 90 }, 117 91 "adultOnly": { 118 92 "type": "boolean" ··· 128 102 }, 129 103 "labelValueDefinitionStrings": { 130 104 "type": "object", 131 - "required": [ 132 - "lang", 133 - "name", 134 - "description" 135 - ], 105 + "required": ["lang", "name", "description"], 136 106 "properties": { 137 107 "lang": { 138 108 "type": "string",
+1 -5
lexicons/com/atproto/moderation/defs.json
··· 45 45 "subjectType": { 46 46 "type": "string", 47 47 "description": "Tag describing a type of subject that might be reported.", 48 - "knownValues": [ 49 - "account", 50 - "record", 51 - "chat" 52 - ] 48 + "knownValues": ["account", "record", "chat"] 53 49 } 54 50 } 55 51 }
+1 -4
lexicons/com/atproto/repo/strongRef.json
··· 5 5 "defs": { 6 6 "main": { 7 7 "type": "object", 8 - "required": [ 9 - "uri", 10 - "cid" 11 - ], 8 + "required": ["uri", "cid"], 12 9 "properties": { 13 10 "uri": { 14 11 "type": "string",
+5 -1
lexicons/social/grain/gallery/defs.json
··· 50 50 "type": "object", 51 51 "required": ["url"], 52 52 "properties": { 53 - "url": { "type": "string", "format": "uri", "description": "URL to the cross-posted Bluesky post." } 53 + "url": { 54 + "type": "string", 55 + "format": "uri", 56 + "description": "URL to the cross-posted Bluesky post." 57 + } 54 58 } 55 59 }, 56 60 "viewerState": {
+40 -33
patches/pds-csrf-no-secure.js
··· 3 3 // so ASWebAuthenticationSession on iOS can send it over HTTP://localhost. 4 4 // This file is mounted into the PDS container via docker-compose.yml. 5 5 // See: @atproto/oauth-provider/dist/router/assets/csrf.js 6 - var __importDefault = (this && this.__importDefault) || function (mod) { 7 - return (mod && mod.__esModule) ? mod : { "default": mod }; 8 - }; 6 + var __importDefault = 7 + (this && this.__importDefault) || 8 + function (mod) { 9 + return mod && mod.__esModule ? mod : { default: mod }; 10 + }; 9 11 Object.defineProperty(exports, "__esModule", { value: true }); 10 12 exports.setupCsrfToken = setupCsrfToken; 11 13 exports.validateCsrfToken = validateCsrfToken; ··· 18 20 const TOKEN_BYTE_LENGTH = 12; 19 21 const TOKEN_LENGTH = TOKEN_BYTE_LENGTH * 2; // 2 hex chars per byte 20 22 const CSRF_COOKIE_OPTIONS = { 21 - expires: undefined, 22 - secure: false, // patched: was true, breaks iOS ASWebAuthenticationSession over HTTP 23 - httpOnly: false, 24 - sameSite: 'lax', 25 - path: `/`, 23 + expires: undefined, 24 + secure: false, // patched: was true, breaks iOS ASWebAuthenticationSession over HTTP 25 + httpOnly: false, 26 + sameSite: "lax", 27 + path: `/`, 26 28 }; 27 29 async function generateCsrfToken() { 28 - return (0, crypto_js_1.randomHexId)(TOKEN_BYTE_LENGTH); 30 + return (0, crypto_js_1.randomHexId)(TOKEN_BYTE_LENGTH); 29 31 } 30 32 async function setupCsrfToken(req, res) { 31 - const token = getCookieCsrf(req) || (await generateCsrfToken()); 32 - (0, index_js_1.setCookie)(res, oauth_provider_api_1.CSRF_COOKIE_NAME, token, CSRF_COOKIE_OPTIONS); 33 + const token = getCookieCsrf(req) || (await generateCsrfToken()); 34 + (0, index_js_1.setCookie)(res, oauth_provider_api_1.CSRF_COOKIE_NAME, token, CSRF_COOKIE_OPTIONS); 33 35 } 34 36 async function validateCsrfToken(req, res) { 35 - const cookieValue = getCookieCsrf(req); 36 - const headerValue = getHeadersCsrf(req); 37 - (0, index_js_1.setCookie)(res, oauth_provider_api_1.CSRF_COOKIE_NAME, cookieValue || (await generateCsrfToken()), CSRF_COOKIE_OPTIONS); 38 - if (!headerValue) { 39 - throw (0, http_errors_1.default)(400, `Missing CSRF header`); 40 - } 41 - if (!cookieValue) { 42 - throw (0, http_errors_1.default)(400, `Missing CSRF cookie`); 43 - } 44 - if (cookieValue !== headerValue) { 45 - throw (0, http_errors_1.default)(400, `CSRF mismatch`); 46 - } 37 + const cookieValue = getCookieCsrf(req); 38 + const headerValue = getHeadersCsrf(req); 39 + (0, index_js_1.setCookie)( 40 + res, 41 + oauth_provider_api_1.CSRF_COOKIE_NAME, 42 + cookieValue || (await generateCsrfToken()), 43 + CSRF_COOKIE_OPTIONS, 44 + ); 45 + if (!headerValue) { 46 + throw (0, http_errors_1.default)(400, `Missing CSRF header`); 47 + } 48 + if (!cookieValue) { 49 + throw (0, http_errors_1.default)(400, `Missing CSRF cookie`); 50 + } 51 + if (cookieValue !== headerValue) { 52 + throw (0, http_errors_1.default)(400, `CSRF mismatch`); 53 + } 47 54 } 48 55 function getCookieCsrf(req) { 49 - const cookieValue = (0, index_js_1.getCookie)(req, oauth_provider_api_1.CSRF_COOKIE_NAME); 50 - if (cookieValue?.length === TOKEN_LENGTH) { 51 - return cookieValue; 52 - } 53 - return undefined; 56 + const cookieValue = (0, index_js_1.getCookie)(req, oauth_provider_api_1.CSRF_COOKIE_NAME); 57 + if (cookieValue?.length === TOKEN_LENGTH) { 58 + return cookieValue; 59 + } 60 + return undefined; 54 61 } 55 62 function getHeadersCsrf(req) { 56 - const headerValue = req.headers[oauth_provider_api_1.CSRF_HEADER_NAME]; 57 - if (typeof headerValue === 'string' && headerValue.length === TOKEN_LENGTH) { 58 - return headerValue; 59 - } 60 - return undefined; 63 + const headerValue = req.headers[oauth_provider_api_1.CSRF_HEADER_NAME]; 64 + if (typeof headerValue === "string" && headerValue.length === TOKEN_LENGTH) { 65 + return headerValue; 66 + } 67 + return undefined; 61 68 }
+3 -4
server/feeds/actor.ts
··· 18 18 19 19 // Resolve handle to DID if needed 20 20 if (!actor.startsWith("did:")) { 21 - const rows = (await ctx.db.query( 22 - `SELECT did FROM _repos WHERE handle = $1`, 23 - [actor], 24 - )) as { did: string }[]; 21 + const rows = (await ctx.db.query(`SELECT did FROM _repos WHERE handle = $1`, [actor])) as { 22 + did: string; 23 + }[]; 25 24 if (rows[0]?.did) { 26 25 actor = rows[0].did; 27 26 }
+35 -32
server/hydrate/galleries.ts
··· 99 99 for (const row of favRows) viewerFavs.set(row.subject, row.uri); 100 100 } 101 101 102 - const [profiles, favCounts, commentCounts, labelsByUri, galleryItemRows, crossPosts] = await Promise.all([ 103 - ctx.lookup<GrainActorProfile>("social.grain.actor.profile", "did", dids), 104 - galleryUris.length > 0 105 - ? (ctx.db.query( 106 - `SELECT subject, COUNT(DISTINCT did) as count FROM "social.grain.favorite" 102 + const [profiles, favCounts, commentCounts, labelsByUri, galleryItemRows, crossPosts] = 103 + await Promise.all([ 104 + ctx.lookup<GrainActorProfile>("social.grain.actor.profile", "did", dids), 105 + galleryUris.length > 0 106 + ? ( 107 + ctx.db.query( 108 + `SELECT subject, COUNT(DISTINCT did) as count FROM "social.grain.favorite" 107 109 WHERE subject IN (${galleryUris.map((_, i) => `$${i + 1}`).join(",")}) GROUP BY subject`, 108 - galleryUris, 109 - ) as Promise<{ subject: string; count: number }[]>).then((rows) => { 110 - const m = new Map<string, number>(); 111 - for (const r of rows) m.set(r.subject, Number(r.count)); 112 - return m; 113 - }) 114 - : Promise.resolve(new Map<string, number>()), 115 - ctx.count("social.grain.comment", "subject", galleryUris), 116 - ctx.labels(galleryUris) as Promise<Map<string, Label[]>>, 117 - galleryUris.length > 0 118 - ? (ctx.db.query( 119 - `SELECT uri, did, cid, gallery, item, position, created_at 110 + galleryUris, 111 + ) as Promise<{ subject: string; count: number }[]> 112 + ).then((rows) => { 113 + const m = new Map<string, number>(); 114 + for (const r of rows) m.set(r.subject, Number(r.count)); 115 + return m; 116 + }) 117 + : Promise.resolve(new Map<string, number>()), 118 + ctx.count("social.grain.comment", "subject", galleryUris), 119 + ctx.labels(galleryUris) as Promise<Map<string, Label[]>>, 120 + galleryUris.length > 0 121 + ? (ctx.db.query( 122 + `SELECT uri, did, cid, gallery, item, position, created_at 120 123 FROM "social.grain.gallery.item" 121 124 WHERE gallery IN (${galleryUris.map((_, i) => `$${i + 1}`).join(",")}) 122 125 ORDER BY position ASC`, 123 - galleryUris, 124 - ) as Promise< 125 - Array<{ 126 - uri: string; 127 - did: string; 128 - cid: string; 129 - gallery: string; 130 - item: string; 131 - position: number; 132 - created_at: string; 133 - }> 134 - >) 135 - : Promise.resolve([]), 136 - lookupCrossPosts(ctx.db, items, "gallery"), 137 - ]); 126 + galleryUris, 127 + ) as Promise< 128 + Array<{ 129 + uri: string; 130 + did: string; 131 + cid: string; 132 + gallery: string; 133 + item: string; 134 + position: number; 135 + created_at: string; 136 + }> 137 + >) 138 + : Promise.resolve([]), 139 + lookupCrossPosts(ctx.db, items, "gallery"), 140 + ]); 138 141 139 142 // Group gallery items by gallery URI 140 143 const itemsByGallery = new Map<string, Array<{ photoUri: string; position: number }>>();
+1 -5
server/hydrate/stories.ts
··· 18 18 * Hydrate raw story rows into StoryView objects. 19 19 * Resolves the author profile, filters by label moderation, and maps to views. 20 20 */ 21 - export async function hydrateStories( 22 - ctx: BaseContext, 23 - actor: string, 24 - rows: StoryRow[], 25 - ) { 21 + export async function hydrateStories(ctx: BaseContext, actor: string, rows: StoryRow[]) { 26 22 // Resolve author profile 27 23 const profiles = await ctx.lookup<GrainActorProfile>("social.grain.actor.profile", "did", [ 28 24 actor,
+1 -2
server/og/story.ts
··· 117 117 type: "div", 118 118 props: { 119 119 children: 120 - author?.value.displayName || 121 - `@${author?.handle || did.slice(0, 24)}`, 120 + author?.value.displayName || `@${author?.handle || did.slice(0, 24)}`, 122 121 style: { fontSize: 24, fontWeight: 600, color: "#ffffff" }, 123 122 }, 124 123 },
+1
tsconfig.server.tsbuildinfo
··· 1 + {"fileNames":["./node_modules/typescript/lib/lib.es5.d.ts","./node_modules/typescript/lib/lib.es2015.d.ts","./node_modules/typescript/lib/lib.es2016.d.ts","./node_modules/typescript/lib/lib.es2017.d.ts","./node_modules/typescript/lib/lib.es2018.d.ts","./node_modules/typescript/lib/lib.es2019.d.ts","./node_modules/typescript/lib/lib.es2020.d.ts","./node_modules/typescript/lib/lib.es2021.d.ts","./node_modules/typescript/lib/lib.es2022.d.ts","./node_modules/typescript/lib/lib.dom.d.ts","./node_modules/typescript/lib/lib.dom.iterable.d.ts","./node_modules/typescript/lib/lib.dom.asynciterable.d.ts","./node_modules/typescript/lib/lib.webworker.importscripts.d.ts","./node_modules/typescript/lib/lib.scripthost.d.ts","./node_modules/typescript/lib/lib.es2015.core.d.ts","./node_modules/typescript/lib/lib.es2015.collection.d.ts","./node_modules/typescript/lib/lib.es2015.generator.d.ts","./node_modules/typescript/lib/lib.es2015.iterable.d.ts","./node_modules/typescript/lib/lib.es2015.promise.d.ts","./node_modules/typescript/lib/lib.es2015.proxy.d.ts","./node_modules/typescript/lib/lib.es2015.reflect.d.ts","./node_modules/typescript/lib/lib.es2015.symbol.d.ts","./node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","./node_modules/typescript/lib/lib.es2016.array.include.d.ts","./node_modules/typescript/lib/lib.es2016.intl.d.ts","./node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","./node_modules/typescript/lib/lib.es2017.date.d.ts","./node_modules/typescript/lib/lib.es2017.object.d.ts","./node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2017.string.d.ts","./node_modules/typescript/lib/lib.es2017.intl.d.ts","./node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","./node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","./node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","./node_modules/typescript/lib/lib.es2018.intl.d.ts","./node_modules/typescript/lib/lib.es2018.promise.d.ts","./node_modules/typescript/lib/lib.es2018.regexp.d.ts","./node_modules/typescript/lib/lib.es2019.array.d.ts","./node_modules/typescript/lib/lib.es2019.object.d.ts","./node_modules/typescript/lib/lib.es2019.string.d.ts","./node_modules/typescript/lib/lib.es2019.symbol.d.ts","./node_modules/typescript/lib/lib.es2019.intl.d.ts","./node_modules/typescript/lib/lib.es2020.bigint.d.ts","./node_modules/typescript/lib/lib.es2020.date.d.ts","./node_modules/typescript/lib/lib.es2020.promise.d.ts","./node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2020.string.d.ts","./node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","./node_modules/typescript/lib/lib.es2020.intl.d.ts","./node_modules/typescript/lib/lib.es2020.number.d.ts","./node_modules/typescript/lib/lib.es2021.promise.d.ts","./node_modules/typescript/lib/lib.es2021.string.d.ts","./node_modules/typescript/lib/lib.es2021.weakref.d.ts","./node_modules/typescript/lib/lib.es2021.intl.d.ts","./node_modules/typescript/lib/lib.es2022.array.d.ts","./node_modules/typescript/lib/lib.es2022.error.d.ts","./node_modules/typescript/lib/lib.es2022.intl.d.ts","./node_modules/typescript/lib/lib.es2022.object.d.ts","./node_modules/typescript/lib/lib.es2022.string.d.ts","./node_modules/typescript/lib/lib.es2022.regexp.d.ts","./node_modules/typescript/lib/lib.esnext.disposable.d.ts","./node_modules/typescript/lib/lib.esnext.float16.d.ts","./node_modules/typescript/lib/lib.decorators.d.ts","./node_modules/typescript/lib/lib.decorators.legacy.d.ts","./node_modules/typescript/lib/lib.es2022.full.d.ts","./node_modules/@hatk/hatk/dist/lex-types.d.ts","./node_modules/@hatk/hatk/dist/hydrate.d.ts","./node_modules/@hatk/hatk/dist/config.d.ts","./node_modules/@hatk/hatk/dist/xrpc.d.ts","./node_modules/@hatk/hatk/dist/feeds.d.ts","./node_modules/@hatk/hatk/dist/seed.d.ts","./node_modules/@hatk/hatk/dist/database/ports.d.ts","./node_modules/@hatk/hatk/dist/setup.d.ts","./node_modules/@hatk/hatk/dist/hooks.d.ts","./node_modules/@hatk/hatk/dist/labels.d.ts","./node_modules/@hatk/hatk/dist/opengraph.d.ts","./node_modules/@hatk/hatk/dist/renderer.d.ts","./hatk.generated.ts","./server/on-login.ts","./server/hydrate/galleries.ts","./server/labels/_hidden.ts","./server/feeds/actor.ts","./server/feeds/camera.ts","./server/feeds/following.ts","./server/feeds/hashtag.ts","./node_modules/h3-js/dist/types.d.ts","./server/feeds/location.ts","./server/feeds/recent.ts","./server/hydrate/stories.ts","./server/labels/copyright.ts","./server/labels/gore.ts","./server/labels/harassment.ts","./server/labels/misleading.ts","./server/labels/nudity.ts","./server/labels/other.ts","./server/labels/sexual.ts","./server/labels/spam.ts","./server/og/gallery.ts","./server/og/profile.ts","./server/og/story.ts","./server/xrpc/deletegallery.ts","./server/xrpc/getactorprofile.ts","./server/xrpc/getcameras.ts","./server/xrpc/getfollowers.ts","./server/xrpc/getfollowing.ts","./server/xrpc/getgallery.ts","./server/xrpc/getgallerythread.ts","./server/xrpc/getknownfollowers.ts","./server/xrpc/getlocations.ts","./server/xrpc/getnotifications.ts","./server/xrpc/getstories.ts","./server/xrpc/getstory.ts","./server/xrpc/getstoryarchive.ts","./server/xrpc/getstoryauthors.ts","./server/xrpc/getsuggestedfollows.ts","./server/xrpc/searchgalleries.ts","./server/xrpc/searchprofiles.ts","./seeds/seed.ts","./hatk.config.ts","./node_modules/@types/deep-eql/index.d.ts","./node_modules/assertion-error/index.d.ts","./node_modules/@types/chai/index.d.ts","./node_modules/@types/cookie/index.d.ts","./node_modules/@types/estree/index.d.ts","./node_modules/@types/node/compatibility/iterators.d.ts","./node_modules/@types/node/globals.typedarray.d.ts","./node_modules/@types/node/buffer.buffer.d.ts","./node_modules/@types/node/globals.d.ts","./node_modules/@types/node/web-globals/abortcontroller.d.ts","./node_modules/@types/node/web-globals/blob.d.ts","./node_modules/@types/node/web-globals/console.d.ts","./node_modules/@types/node/web-globals/crypto.d.ts","./node_modules/@types/node/web-globals/domexception.d.ts","./node_modules/@types/node/web-globals/encoding.d.ts","./node_modules/@types/node/web-globals/events.d.ts","./node_modules/undici-types/utility.d.ts","./node_modules/undici-types/header.d.ts","./node_modules/undici-types/readable.d.ts","./node_modules/undici-types/fetch.d.ts","./node_modules/undici-types/formdata.d.ts","./node_modules/undici-types/connector.d.ts","./node_modules/undici-types/client-stats.d.ts","./node_modules/undici-types/client.d.ts","./node_modules/undici-types/errors.d.ts","./node_modules/undici-types/dispatcher.d.ts","./node_modules/undici-types/global-dispatcher.d.ts","./node_modules/undici-types/global-origin.d.ts","./node_modules/undici-types/pool-stats.d.ts","./node_modules/undici-types/pool.d.ts","./node_modules/undici-types/handlers.d.ts","./node_modules/undici-types/balanced-pool.d.ts","./node_modules/undici-types/round-robin-pool.d.ts","./node_modules/undici-types/h2c-client.d.ts","./node_modules/undici-types/agent.d.ts","./node_modules/undici-types/mock-interceptor.d.ts","./node_modules/undici-types/mock-call-history.d.ts","./node_modules/undici-types/mock-agent.d.ts","./node_modules/undici-types/mock-client.d.ts","./node_modules/undici-types/mock-pool.d.ts","./node_modules/undici-types/snapshot-agent.d.ts","./node_modules/undici-types/mock-errors.d.ts","./node_modules/undici-types/proxy-agent.d.ts","./node_modules/undici-types/env-http-proxy-agent.d.ts","./node_modules/undici-types/retry-handler.d.ts","./node_modules/undici-types/retry-agent.d.ts","./node_modules/undici-types/api.d.ts","./node_modules/undici-types/cache-interceptor.d.ts","./node_modules/undici-types/interceptors.d.ts","./node_modules/undici-types/util.d.ts","./node_modules/undici-types/cookies.d.ts","./node_modules/undici-types/patch.d.ts","./node_modules/undici-types/websocket.d.ts","./node_modules/undici-types/eventsource.d.ts","./node_modules/undici-types/diagnostics-channel.d.ts","./node_modules/undici-types/content-type.d.ts","./node_modules/undici-types/cache.d.ts","./node_modules/undici-types/index.d.ts","./node_modules/@types/node/web-globals/fetch.d.ts","./node_modules/@types/node/web-globals/importmeta.d.ts","./node_modules/@types/node/web-globals/messaging.d.ts","./node_modules/@types/node/web-globals/navigator.d.ts","./node_modules/@types/node/web-globals/performance.d.ts","./node_modules/@types/node/web-globals/storage.d.ts","./node_modules/@types/node/web-globals/streams.d.ts","./node_modules/@types/node/web-globals/timers.d.ts","./node_modules/@types/node/web-globals/url.d.ts","./node_modules/@types/node/assert.d.ts","./node_modules/@types/node/assert/strict.d.ts","./node_modules/@types/node/async_hooks.d.ts","./node_modules/@types/node/buffer.d.ts","./node_modules/@types/node/child_process.d.ts","./node_modules/@types/node/cluster.d.ts","./node_modules/@types/node/console.d.ts","./node_modules/@types/node/constants.d.ts","./node_modules/@types/node/crypto.d.ts","./node_modules/@types/node/dgram.d.ts","./node_modules/@types/node/diagnostics_channel.d.ts","./node_modules/@types/node/dns.d.ts","./node_modules/@types/node/dns/promises.d.ts","./node_modules/@types/node/domain.d.ts","./node_modules/@types/node/events.d.ts","./node_modules/@types/node/fs.d.ts","./node_modules/@types/node/fs/promises.d.ts","./node_modules/@types/node/http.d.ts","./node_modules/@types/node/http2.d.ts","./node_modules/@types/node/https.d.ts","./node_modules/@types/node/inspector.d.ts","./node_modules/@types/node/inspector.generated.d.ts","./node_modules/@types/node/inspector/promises.d.ts","./node_modules/@types/node/module.d.ts","./node_modules/@types/node/net.d.ts","./node_modules/buffer/index.d.ts","./node_modules/@types/node/os.d.ts","./node_modules/@types/node/path.d.ts","./node_modules/@types/node/path/posix.d.ts","./node_modules/@types/node/path/win32.d.ts","./node_modules/@types/node/perf_hooks.d.ts","./node_modules/@types/node/process.d.ts","./node_modules/@types/node/punycode.d.ts","./node_modules/@types/node/querystring.d.ts","./node_modules/@types/node/quic.d.ts","./node_modules/@types/node/readline.d.ts","./node_modules/@types/node/readline/promises.d.ts","./node_modules/@types/node/repl.d.ts","./node_modules/@types/node/sea.d.ts","./node_modules/@types/node/sqlite.d.ts","./node_modules/@types/node/stream.d.ts","./node_modules/@types/node/stream/consumers.d.ts","./node_modules/@types/node/stream/promises.d.ts","./node_modules/@types/node/stream/web.d.ts","./node_modules/@types/node/string_decoder.d.ts","./node_modules/@types/node/test.d.ts","./node_modules/@types/node/test/reporters.d.ts","./node_modules/@types/node/timers.d.ts","./node_modules/@types/node/timers/promises.d.ts","./node_modules/@types/node/tls.d.ts","./node_modules/@types/node/trace_events.d.ts","./node_modules/@types/node/tty.d.ts","./node_modules/@types/node/url.d.ts","./node_modules/@types/node/util.d.ts","./node_modules/@types/node/util/types.d.ts","./node_modules/@types/node/v8.d.ts","./node_modules/@types/node/vm.d.ts","./node_modules/@types/node/wasi.d.ts","./node_modules/@types/node/worker_threads.d.ts","./node_modules/@types/node/zlib.d.ts","./node_modules/@types/node/index.d.ts","./node_modules/@types/resolve/index.d.ts","./node_modules/@types/trusted-types/lib/index.d.ts","./node_modules/@types/trusted-types/index.d.ts","../node_modules/@types/unist/index.d.ts","../node_modules/@types/hast/index.d.ts","../node_modules/@types/linkify-it/build/index.cjs.d.ts","../node_modules/@types/linkify-it/index.d.ts","../node_modules/@types/mdurl/build/index.cjs.d.ts","../node_modules/@types/markdown-it/dist/index.cjs.d.ts","../node_modules/@types/markdown-it/index.d.ts","../node_modules/@types/mdast/index.d.ts","../node_modules/@types/mdurl/index.d.ts","../node_modules/@types/web-bluetooth/index.d.ts"],"fileIdsList":[[68,127,190,198,202,205,207,208,209,222],[66,69,70,71,73,74,75,76,77,127,190,198,202,205,207,208,209,222],[127,190,198,202,205,207,208,209,222],[66,67,127,190,198,202,205,207,208,209,222],[67,68,127,190,198,202,205,207,208,209,222],[66,127,190,198,202,205,207,208,209,222],[69,127,190,198,202,205,207,208,209,222],[72,127,190,198,202,205,207,208,209,222],[66,67,68,127,190,198,202,205,207,208,209,222],[120,121,127,190,198,202,205,207,208,209,222],[127,187,188,190,198,202,205,207,208,209,222],[127,189,190,198,202,205,207,208,209,222],[190,198,202,205,207,208,209,222],[127,190,198,202,205,207,208,209,222,230],[127,190,191,196,198,201,202,205,207,208,209,211,222,227,239],[127,190,191,192,198,201,202,205,207,208,209,222],[127,190,193,198,202,205,207,208,209,222,240],[127,190,194,195,198,202,205,207,208,209,213,222],[127,190,195,198,202,205,207,208,209,222,227,236],[127,190,196,198,201,202,205,207,208,209,211,222],[127,189,190,197,198,202,205,207,208,209,222],[127,190,198,199,202,205,207,208,209,222],[127,190,198,200,201,202,205,207,208,209,222],[127,189,190,198,201,202,205,207,208,209,222],[127,190,198,201,202,203,205,207,208,209,222,227,239],[127,190,198,201,202,203,205,207,208,209,222,227,230],[127,177,190,198,201,202,204,205,207,208,209,211,222,227,239],[127,190,198,201,202,204,205,207,208,209,211,222,227,236,239],[127,190,198,202,204,205,206,207,208,209,222,227,236,239],[125,126,127,128,129,130,131,132,133,134,135,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246],[127,190,198,201,202,205,207,208,209,222],[127,190,198,202,205,207,209,222],[127,190,198,202,205,207,208,209,210,222,239],[127,190,198,201,202,205,207,208,209,211,222,227],[127,190,198,202,205,207,208,209,213,222],[127,190,198,202,205,207,208,209,214,222],[127,190,198,201,202,205,207,208,209,217,222],[127,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246],[127,190,198,202,205,207,208,209,219,222],[127,190,198,202,205,207,208,209,220,222],[127,190,195,198,202,205,207,208,209,211,222,230],[127,190,198,201,202,205,207,208,209,222,223],[127,190,198,202,205,207,208,209,222,224,240,243],[127,190,198,201,202,205,207,208,209,222,227,229,230],[127,190,198,202,205,207,208,209,222,228,230],[127,190,198,202,205,207,208,209,222,230,240],[127,190,198,202,205,207,208,209,222,231],[127,187,190,198,202,205,207,208,209,222,227,233,239],[127,190,198,202,205,207,208,209,222,227,232],[127,190,198,201,202,205,207,208,209,222,234,235],[127,190,198,202,205,207,208,209,222,234,235],[127,190,195,198,202,205,207,208,209,211,222,227,236],[127,190,198,202,205,207,208,209,222,237],[127,190,198,202,205,207,208,209,211,222,238],[127,190,198,202,204,205,207,208,209,220,222,239],[127,190,198,202,205,207,208,209,222,240,241],[127,190,195,198,202,205,207,208,209,222,241],[127,190,198,202,205,207,208,209,222,227,242],[127,190,198,202,205,207,208,209,210,222,243],[127,190,198,202,205,207,208,209,222,244],[127,190,193,198,202,205,207,208,209,222],[127,190,195,198,202,205,207,208,209,222],[127,190,198,202,205,207,208,209,222,240],[127,177,190,198,202,205,207,208,209,222],[127,190,198,202,205,207,208,209,222,239],[127,190,198,202,205,207,208,209,222,245],[127,190,198,202,205,207,208,209,217,222],[127,190,198,202,205,207,208,209,222,235],[127,177,190,198,201,202,203,205,207,208,209,217,222,227,230,239,242,243,245],[127,190,198,202,205,207,208,209,222,227,246],[127,190,198,202,205,207,208,209,222,249],[127,142,145,148,149,190,198,202,205,207,208,209,222,239],[127,145,190,198,202,205,207,208,209,222,227,239],[127,145,149,190,198,202,205,207,208,209,222,239],[127,190,198,202,205,207,208,209,222,227],[127,139,190,198,202,205,207,208,209,222],[127,143,190,198,202,205,207,208,209,222],[127,141,142,145,190,198,202,205,207,208,209,222,239],[127,190,198,202,205,207,208,209,211,222,236],[127,190,198,202,205,207,208,209,222,247],[127,139,190,198,202,205,207,208,209,222,247],[127,141,145,190,198,202,205,207,208,209,211,222,239],[127,136,137,138,140,144,190,198,201,202,205,207,208,209,222,227,239],[127,145,154,162,190,198,202,205,207,208,209,222],[127,137,143,190,198,202,205,207,208,209,222],[127,145,171,172,190,198,202,205,207,208,209,222],[127,137,140,145,190,198,202,205,207,208,209,222,230,239,247],[127,145,190,198,202,205,207,208,209,222],[127,141,145,190,198,202,205,207,208,209,222,239],[127,136,190,198,202,205,207,208,209,222],[127,139,140,141,143,144,145,146,147,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,172,173,174,175,176,190,198,202,205,207,208,209,222],[127,145,164,167,190,198,202,205,207,208,209,222],[127,145,154,155,156,190,198,202,205,207,208,209,222],[127,143,145,155,157,190,198,202,205,207,208,209,222],[127,144,190,198,202,205,207,208,209,222],[127,137,139,145,190,198,202,205,207,208,209,222],[127,145,149,155,157,190,198,202,205,207,208,209,222],[127,149,190,198,202,205,207,208,209,222],[127,143,145,148,190,198,202,205,207,208,209,222,239],[127,137,141,145,154,190,198,202,205,207,208,209,222],[127,145,164,190,198,202,205,207,208,209,222],[127,157,190,198,202,205,207,208,209,222],[127,139,145,171,190,198,202,205,207,208,209,222,230,245,247],[78,127,190,198,202,205,207,208,209,222],[78,80,81,127,190,198,202,205,207,208,209,222],[78,80,81,86,127,190,198,202,205,207,208,209,222],[78,80,127,190,198,202,205,207,208,209,222],[78,86,127,190,198,202,205,207,208,209,222],[78,89,127,190,198,202,205,207,208,209,222],[78,81,127,190,198,202,205,207,208,209,222],[127,190,198,202,205,207,208,209,222,251],[127,190,198,202,205,207,208,209,222,253],[127,190,198,202,205,207,208,209,222,253,255],[127,190,198,202,205,207,208,209,222,256],[127,190,198,202,205,207,208,209,222,255]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2e80ee7a49e8ac312cc11b77f1475804bee36b3b2bc896bead8b6e1266befb43","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7a3c8b952931daebdfc7a2897c53c0a1c73624593fa070e46bd537e64dcd20a","affectsGlobalScope":true,"impliedFormat":1},{"version":"80e18897e5884b6723488d4f5652167e7bb5024f946743134ecc4aa4ee731f89","affectsGlobalScope":true,"impliedFormat":1},{"version":"cd034f499c6cdca722b60c04b5b1b78e058487a7085a8e0d6fb50809947ee573","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"51ad4c928303041605b4d7ae32e0c1ee387d43a24cd6f1ebf4a2699e1076d4fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"196cb558a13d4533a5163286f30b0509ce0210e4b316c56c38d4c0fd2fb38405","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"3cbad9a1ba4453443026ed38e4b8be018abb26565fa7c944376463ad9df07c41","impliedFormat":1},{"version":"78a4223c4ee8898a21548c05707eed2c6b80e7c457fae0bfc5ccce06c29dc4dd","impliedFormat":99},{"version":"ba98067248bdefff26facae2d09f1f6d0036e6a0df85852b4ae1621ee20a4f5d","impliedFormat":99},{"version":"8b46dbc442d3e43b8d1d915694557b2f3b1178aea90a2ce165897c6d6632589d","impliedFormat":99},{"version":"8bd9385895fcfa3ed54d11d4e3402686633ce5a1b3b5c8a7aa1c0b50d944eaae","impliedFormat":99},{"version":"9f7fd12bb06f68a758bf0a71f926346c6a8c289a0df22908fbf565b9e7c66873","impliedFormat":99},{"version":"a30dbe99671c0e83603d11599a505b700d8d868c3d3a63d98a12bc84cddfaa90","impliedFormat":99},{"version":"6f40480510b80633de4aaa1af08b5203a35596d3dedc7f327d4bd6983e6e5dac","impliedFormat":99},{"version":"7cf687b3372cd459ef68cd57a186da4b3666b12239e01eb82c00c9d17492a6af","impliedFormat":99},{"version":"9f80c7d36ac58a2cd00c8e843c5072887093bea0cdcbe8b6701685b0e644f427","impliedFormat":99},{"version":"0ea61fbc27f5b3eb6b033fc1273674c28fe141cf2b40740ca5eab51f6ad775d7","impliedFormat":99},{"version":"7e880d9e0a3b25ca407f853941a46c7dacaac75dc442b030d31bbe67562b9d5a","impliedFormat":99},{"version":"5a8a2895255d4cd113190739e63e03f570fc7e6ced64d6c596cd0c56d644abc6","impliedFormat":99},{"version":"55126209b71c681fc61cc990501168ac02d6cc0b5700fdae2f96b81e355e0708","impliedFormat":99},{"version":"2d0b8e4153e334420eab7e3a306212448aa8bbb78a6c3ffb37ab34579fd4b165","impliedFormat":99},{"version":"3783e1be2fb00d98625416297a74ed15e034ea1963d6cf809ea2215908eb5ed4","impliedFormat":99},{"version":"1cd6ec15d62c4821d666c7e030cd10079e4a1d25c64f4a564deb3510e68d4fab","impliedFormat":99},{"version":"6a0d7159f01290238666448ccc8f0b5858643c07a9bdb5e97b4234c6ddede556","impliedFormat":99},{"version":"ef6aa413dc11ae5f9f4577c855353d61d6ced3b538280d7532fa1588e0f1da07","impliedFormat":99},{"version":"6513e4b5f53eb5a1805acfe7b68e593615e7d61611153bea5459ff07e39b8bcf","impliedFormat":99},{"version":"ae3904c0fc2f4daafde0851320715ccf57efb07e7c1e29523ef53a7022000f9b","impliedFormat":99},{"version":"69359b0bbe2f541ae5003ea8ecfe6d2316786971cf91f4239d2b64120d4d3fb8","impliedFormat":1},{"version":"556e886fde836424bdc57327eea4bb43833b53449eec7aacd45f91e46d70fa68","impliedFormat":99},{"version":"8003561763d456fee57bbbfed8c2a916c0791b8c845f15350d37061d8c15ad99","impliedFormat":99},{"version":"f54bdeedfe2535f5e5108792ddfd6edb2b14a6d25516f789dc7bd1116fa816b0","impliedFormat":99},{"version":"b7f5f03979e92b588f3f4754946f430943e8313fd36ad668a0b733a05ce44519","impliedFormat":99},{"version":"39ffceedb0e8dd76e61984f5cba52e9151974584b00ecd9121044db26a570ecc","impliedFormat":99},{"version":"253b40edda98709104e699418c4062c9e1fe7e77af607928b47939a06cbcae1d","impliedFormat":99},{"version":"c1db03280062c184b7f3375184f0e5cc91e5606466732746515fcd0bcad44c19","impliedFormat":99},{"version":"7496ceb0df5db209c01299818f9f58e41a43ae9fb9a931c613f6efee6e11d032","impliedFormat":99},{"version":"eb8b2b371d8eeeca8fc845e80b31f7165fab319c985d132a214e4c6ee76307c3","impliedFormat":99},{"version":"0cf2b73053559d2fb5bf646d6a806948c25cd526ea223cb0a336758072859e5b","impliedFormat":99},{"version":"55df920668d908511c68170d922039a8cc88e36171a78b7f686f46b11bde8bf8","impliedFormat":99},{"version":"056a82d016614744072574f7242137c28c4e6f90c69b53a3b64db4271a119be1","impliedFormat":99},{"version":"32123f13c93a018c5094af85fdb2555db19b42e8d619be5ee1f527f5457b6822","impliedFormat":99},{"version":"a7878823b495ac73d7e30b4c8630097aa6a8d45cb4de5ad69b973cf2862829f3","impliedFormat":99},{"version":"3593150a748a87d7f20b8cd139c2dd757405f0ad3fd8d745d9ca3dcbf716ecbe","impliedFormat":99},{"version":"8562696e81369474660ade63ddd79b0b218b5e2a1692015427c2bb4e45c5cf35","impliedFormat":99},{"version":"bb67aa50cf3e1180fd014b1037dc64ffc58be62a4b5c4defcab0ba6a3c2a395a","impliedFormat":99},{"version":"7480b2e5a08f03f1238b7c854b838a299ca6100cddae43d473a71002230de7a2","signature":"ee4ddc8383b4f7ce78332a67d4aa0812d11dc7b92bff2a5994e59d70edac6b5a","impliedFormat":99},{"version":"b20528aacb1a6e5859962278db68558f0d658e202872ccb93c947d6367dc9bc7","signature":"f1898174d7fcaa72d1733d84e65cc9e1bb0c74573e6d74a613165d809398fe6d","impliedFormat":99},{"version":"6d71f5b7e59c94e17468c73137b16a1f0db6d41e228066a320fac831cb39587f","impliedFormat":99},{"version":"77adef4706804c3f60d91d3019c406f6373e0f44aac2c87ca4f1b774ac402643","impliedFormat":99},{"version":"25a9c94698073513e5adae628e8c54ef9254507e7b82df33875b9b86215c2f0e","impliedFormat":99},{"version":"10bf417a1dcc72fcbaf1b5a3d453ea5a1e3ff7c5fdeae377e3eef881f98d62fd","impliedFormat":99},{"version":"d61282b607bcc084ac5c498d1f3c3d19c458a9fe855e07b373896abcd3c29197","impliedFormat":99},{"version":"27f4d465813e2162c9d983b9e1686927e9714591862214fa966614de1820d94b","impliedFormat":99},{"version":"9572c1887ed9baefd1f6103cd47f31f7090700f361b47f367dd7f976dd87b7c4","impliedFormat":99},{"version":"5697d3e4276ce8c93b32d6b8ea7a052615e0773a04d0eb0de5f54a3ab08f3f03","impliedFormat":99},{"version":"592256adc9abc1a6f377281071e6b8230bd9b34180a6cb7050caa14a77a35567","impliedFormat":99},{"version":"9da54d81f6dd25e86112709ba2c9e5f0cf5a86319de1511abdeb9c1cb400c41b","impliedFormat":99},{"version":"a36375b4685ceaa8c04470cd7412f22cfde73c9dc623da5b8c086c51f85e126e","impliedFormat":99},{"version":"6af86d9c7caad874de927a51e5ef9471ffa1646f2013ff1e1ef6ec4bacbbfb48","impliedFormat":99},{"version":"e370709dd894c1d914eb7be628b281df5d77cb2ef69ffb2ef92560646a643ebe","impliedFormat":99},{"version":"515d134930e6cca7146b9b9aa7289be8b1fa2b5dd3df4502c5278f707c1a71a6","impliedFormat":99},{"version":"427fe2004642504828c1476d0af4270e6ad4db6de78c0b5da3e4c5ca95052a99","impliedFormat":1},{"version":"2eeffcee5c1661ddca53353929558037b8cf305ffb86a803512982f99bcab50d","impliedFormat":99},{"version":"9afb4cb864d297e4092a79ee2871b5d3143ea14153f62ef0bb04ede25f432030","affectsGlobalScope":true,"impliedFormat":99},{"version":"1748c03e7a7d118f7f6648c709507971eb0d416f489958492c5ae625de445184","impliedFormat":1},{"version":"151ff381ef9ff8da2da9b9663ebf657eac35c4c9a19183420c05728f31a6761d","impliedFormat":1},{"version":"d153a11543fd884b596587ccd97aebbeed950b26933ee000f94009f1ab142848","affectsGlobalScope":true,"impliedFormat":1},{"version":"0ccdaa19852d25ecd84eec365c3bfa16e7859cadecf6e9ca6d0dbbbee439743f","affectsGlobalScope":true,"impliedFormat":1},{"version":"438b41419b1df9f1fbe33b5e1b18f5853432be205991d1b19f5b7f351675541e","affectsGlobalScope":true,"impliedFormat":1},{"version":"096116f8fedc1765d5bd6ef360c257b4a9048e5415054b3bf3c41b07f8951b0b","affectsGlobalScope":true,"impliedFormat":1},{"version":"e5e01375c9e124a83b52ee4b3244ed1a4d214a6cfb54ac73e164a823a4a7860a","affectsGlobalScope":true,"impliedFormat":1},{"version":"f90ae2bbce1505e67f2f6502392e318f5714bae82d2d969185c4a6cecc8af2fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"4b58e207b93a8f1c88bbf2a95ddc686ac83962b13830fe8ad3f404ffc7051fb4","affectsGlobalScope":true,"impliedFormat":1},{"version":"1fefabcb2b06736a66d2904074d56268753654805e829989a46a0161cd8412c5","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"c18a99f01eb788d849ad032b31cafd49de0b19e083fe775370834c5675d7df8e","affectsGlobalScope":true,"impliedFormat":1},{"version":"5247874c2a23b9a62d178ae84f2db6a1d54e6c9a2e7e057e178cc5eea13757fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"cdcf9ea426ad970f96ac930cd176d5c69c6c24eebd9fc580e1572d6c6a88f62c","impliedFormat":1},{"version":"23cd712e2ce083d68afe69224587438e5914b457b8acf87073c22494d706a3d0","impliedFormat":1},{"version":"156a859e21ef3244d13afeeba4e49760a6afa035c149dda52f0c45ea8903b338","impliedFormat":1},{"version":"10ec5e82144dfac6f04fa5d1d6c11763b3e4dbbac6d99101427219ab3e2ae887","impliedFormat":1},{"version":"615754924717c0b1e293e083b83503c0a872717ad5aa60ed7f1a699eb1b4ea5c","impliedFormat":1},{"version":"074de5b2fdead0165a2757e3aaef20f27a6347b1c36adea27d51456795b37682","impliedFormat":1},{"version":"68834d631c8838c715f225509cfc3927913b9cc7a4870460b5b60c8dbdb99baf","impliedFormat":1},{"version":"24371e69a38fc33e268d4a8716dbcda430d6c2c414a99ff9669239c4b8f40dea","impliedFormat":1},{"version":"ccab02f3920fc75c01174c47fcf67882a11daf16baf9e81701d0a94636e94556","impliedFormat":1},{"version":"3e11fce78ad8c0e1d1db4ba5f0652285509be3acdd519529bc8fcef85f7dafd9","impliedFormat":1},{"version":"ea6bc8de8b59f90a7a3960005fd01988f98fd0784e14bc6922dde2e93305ec7d","impliedFormat":1},{"version":"36107995674b29284a115e21a0618c4c2751b32a8766dd4cb3ba740308b16d59","impliedFormat":1},{"version":"914a0ae30d96d71915fc519ccb4efbf2b62c0ddfb3a3fc6129151076bc01dc60","impliedFormat":1},{"version":"9c32412007b5662fd34a8eb04292fb5314ec370d7016d1c2fb8aa193c807fe22","impliedFormat":1},{"version":"7fd1b31fd35876b0aa650811c25ec2c97a3c6387e5473eb18004bed86cdd76b6","impliedFormat":1},{"version":"4d327f7d72ad0918275cea3eee49a6a8dc8114ae1d5b7f3f5d0774de75f7439a","impliedFormat":1},{"version":"6ebe8ebb8659aaa9d1acbf3710d7dae3e923e97610238b9511c25dc39023a166","impliedFormat":1},{"version":"e85d7f8068f6a26710bff0cc8c0fc5e47f71089c3780fbede05857331d2ddec9","impliedFormat":1},{"version":"7befaf0e76b5671be1d47b77fcc65f2b0aad91cc26529df1904f4a7c46d216e9","impliedFormat":1},{"version":"0a60a292b89ca7218b8616f78e5bbd1c96b87e048849469cccb4355e98af959a","impliedFormat":1},{"version":"0b6e25234b4eec6ed96ab138d96eb70b135690d7dd01f3dd8a8ab291c35a683a","impliedFormat":1},{"version":"9666f2f84b985b62400d2e5ab0adae9ff44de9b2a34803c2c5bd3c8325b17dc0","impliedFormat":1},{"version":"40cd35c95e9cf22cfa5bd84e96408b6fcbca55295f4ff822390abb11afbc3dca","impliedFormat":1},{"version":"b1616b8959bf557feb16369c6124a97a0e74ed6f49d1df73bb4b9ddf68acf3f3","impliedFormat":1},{"version":"5b03a034c72146b61573aab280f295b015b9168470f2df05f6080a2122f9b4df","impliedFormat":1},{"version":"40b463c6766ca1b689bfcc46d26b5e295954f32ad43e37ee6953c0a677e4ae2b","impliedFormat":1},{"version":"249b9cab7f5d628b71308c7d9bb0a808b50b091e640ba3ed6e2d0516f4a8d91d","impliedFormat":1},{"version":"80aae6afc67faa5ac0b32b5b8bc8cc9f7fa299cff15cf09cc2e11fd28c6ae29e","impliedFormat":1},{"version":"f473cd2288991ff3221165dcf73cd5d24da30391f87e85b3dd4d0450c787a391","impliedFormat":1},{"version":"499e5b055a5aba1e1998f7311a6c441a369831c70905cc565ceac93c28083d53","impliedFormat":1},{"version":"8aee8b6d4f9f62cf3776cda1305fb18763e2aade7e13cea5bbe699112df85214","impliedFormat":1},{"version":"c63b9ada8c72f95aac5db92aea07e5e87ec810353cdf63b2d78f49a58662cf6c","impliedFormat":1},{"version":"1cc2a09e1a61a5222d4174ab358a9f9de5e906afe79dbf7363d871a7edda3955","impliedFormat":1},{"version":"5d0375ca7310efb77e3ef18d068d53784faf62705e0ad04569597ae0e755c401","impliedFormat":1},{"version":"59af37caec41ecf7b2e76059c9672a49e682c1a2aa6f9d7dc78878f53aa284d6","impliedFormat":1},{"version":"addf417b9eb3f938fddf8d81e96393a165e4be0d4a8b6402292f9c634b1cb00d","impliedFormat":1},{"version":"b64d4d1c5f877f9c666e98e833f0205edb9384acc46e98a1fef344f64d6aba44","impliedFormat":1},{"version":"adf27937dba6af9f08a68c5b1d3fce0ca7d4b960c57e6d6c844e7d1a8e53adae","impliedFormat":1},{"version":"12950411eeab8563b349cb7959543d92d8d02c289ed893d78499a19becb5a8cc","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"c9381908473a1c92cb8c516b184e75f4d226dad95c3a85a5af35f670064d9a2f","impliedFormat":1},{"version":"c3f5289820990ab66b70c7fb5b63cb674001009ff84b13de40619619a9c8175f","affectsGlobalScope":true,"impliedFormat":1},{"version":"b3275d55fac10b799c9546804126239baf020d220136163f763b55a74e50e750","affectsGlobalScope":true,"impliedFormat":1},{"version":"fa68a0a3b7cb32c00e39ee3cd31f8f15b80cac97dce51b6ee7fc14a1e8deb30b","affectsGlobalScope":true,"impliedFormat":1},{"version":"1cf059eaf468efcc649f8cf6075d3cb98e9a35a0fe9c44419ec3d2f5428d7123","affectsGlobalScope":true,"impliedFormat":1},{"version":"6c36e755bced82df7fb6ce8169265d0a7bb046ab4e2cb6d0da0cb72b22033e89","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"7a93de4ff8a63bafe62ba86b89af1df0ccb5e40bb85b0c67d6bbcfdcf96bf3d4","affectsGlobalScope":true,"impliedFormat":1},{"version":"90e85f9bc549dfe2b5749b45fe734144e96cd5d04b38eae244028794e142a77e","affectsGlobalScope":true,"impliedFormat":1},{"version":"e0a5deeb610b2a50a6350bd23df6490036a1773a8a71d70f2f9549ab009e67ee","affectsGlobalScope":true,"impliedFormat":1},{"version":"3fad5618174d74a34ee006406d4eb37e8d07dd62eb1315dbf52f48d31a337547","impliedFormat":1},{"version":"7e49f52a159435fc8df4de9dc377ef5860732ca2dc9efec1640531d3cf5da7a3","impliedFormat":1},{"version":"dd4bde4bdc2e5394aed6855e98cf135dfdf5dd6468cad842e03116d31bbcc9bc","impliedFormat":1},{"version":"4d4e879009a84a47c05350b8dca823036ba3a29a3038efed1be76c9f81e45edf","affectsGlobalScope":true,"impliedFormat":1},{"version":"8b50a819485ffe0d237bf0d131e92178d14d11e2aa873d73615a9ec578b341f5","impliedFormat":1},{"version":"9ba13b47cb450a438e3076c4a3f6afb9dc85e17eae50f26d4b2d72c0688c9251","impliedFormat":1},{"version":"b64cd4401633ea4ecadfd700ddc8323a13b63b106ac7127c1d2726f32424622c","impliedFormat":1},{"version":"37c6e5fe5715814412b43cc9b50b24c67a63c4e04e753e0d1305970d65417a60","impliedFormat":1},{"version":"1d024184fb57c58c5c91823f9d10b4915a4867b7934e89115fd0d861a9df27c8","impliedFormat":1},{"version":"ee0e4946247f842c6dd483cbb60a5e6b484fee07996e3a7bc7343dfb68a04c5d","impliedFormat":1},{"version":"ef051f42b7e0ef5ca04552f54c4552eac84099d64b6c5ad0ef4033574b6035b8","impliedFormat":1},{"version":"853a43154f1d01b0173d9cbd74063507ece57170bad7a3b68f3fa1229ad0a92f","impliedFormat":1},{"version":"56231e3c39a031bfb0afb797690b20ed4537670c93c0318b72d5180833d98b72","impliedFormat":1},{"version":"5cc7c39031bfd8b00ad58f32143d59eb6ffc24f5d41a20931269011dccd36c5e","impliedFormat":1},{"version":"12d602a8fe4c2f2ba4f7804f5eda8ba07e0c83bf5cf0cda8baffa2e9967bfb77","affectsGlobalScope":true,"impliedFormat":1},{"version":"a856ab781967b62b288dfd85b860bef0e62f005ed4b1b8fa25c53ce17856acaf","impliedFormat":1},{"version":"cc25940cfb27aa538e60d465f98bb5068d4d7d33131861ace43f04fe6947d68f","impliedFormat":1},{"version":"8db46b61a690f15b245cf16270db044dc047dce9f93b103a59f50262f677ea1f","impliedFormat":1},{"version":"01ff95aa1443e3f7248974e5a771f513cb2ac158c8898f470a1792f817bee497","impliedFormat":1},{"version":"757227c8b345c57d76f7f0e3bbad7a91ffca23f1b2547cbed9e10025816c9cb7","impliedFormat":1},{"version":"959d0327c96dd9bb5521f3ed6af0c435996504cc8dd46baa8e12cb3b3518cef1","impliedFormat":1},{"version":"e1c1a0b4d1ead0de9eca52203aeb1f771f21e6238d6fcd15aa56ac2a02f1b7bf","impliedFormat":1},{"version":"101f482fd48cb4c7c0468dcc6d62c843d842977aea6235644b1edd05e81fbf22","impliedFormat":1},{"version":"266bee0a41e9c3ba335583e21e9277ae03822402cf5e8e1d99f5196853613b98","affectsGlobalScope":true,"impliedFormat":1},{"version":"386606f8a297988535cb1401959041cfa7f59d54b8a9ed09738e65c98684c976","impliedFormat":1},{"version":"8e9c23ba78aabc2e0a27033f18737a6df754067731e69dc5f52823957d60a4b6","impliedFormat":1},{"version":"3ef397f12387eff17f550bc484ea7c27d21d43816bbe609d495107f44b97e933","impliedFormat":1},{"version":"1023282e2ba810bc07905d3668349fbd37a26411f0c8f94a70ef3c05fe523fcf","impliedFormat":1},{"version":"b214ebcf76c51b115453f69729ee8aa7b7f8eccdae2a922b568a45c2d7ff52f7","impliedFormat":1},{"version":"429c9cdfa7d126255779efd7e6d9057ced2d69c81859bbab32073bad52e9ba76","impliedFormat":1},{"version":"e236b5eba291f51bdf32c231673e6cab81b5410850e61f51a7a524dddadc0f95","impliedFormat":1},{"version":"ce8653341224f8b45ff46d2a06f2cacb96f841f768a886c9d8dd8ec0878b11bd","affectsGlobalScope":true,"impliedFormat":1},{"version":"7f2c62938251b45715fd2a9887060ec4fbc8724727029d1cbce373747252bdd7","impliedFormat":1},{"version":"e3ace08b6bbd84655d41e244677b474fd995923ffef7149ddb68af8848b60b05","impliedFormat":1},{"version":"132580b0e86c48fab152bab850fc57a4b74fe915c8958d2ccb052b809a44b61c","impliedFormat":1},{"version":"90a278f5fab7557e69e97056c0841adf269c42697194f0bd5c5e69152637d4b3","impliedFormat":1},{"version":"69c9a5a9392e8564bd81116e1ed93b13205201fb44cb35a7fde8c9f9e21c4b23","impliedFormat":1},{"version":"5f8fc37f8434691ffac1bfd8fc2634647da2c0e84253ab5d2dd19a7718915b35","impliedFormat":1},{"version":"5981c2340fd8b076cae8efbae818d42c11ffc615994cb060b1cd390795f1be2b","impliedFormat":1},{"version":"f263485c9ca90df9fe7bb3a906db9701997dc6cae86ace1f8106ac8d2f7f677b","impliedFormat":1},{"version":"1edcf2f36fc332615846bde6dcc71a8fe526065505bc5e3dcfd65a14becdf698","affectsGlobalScope":true,"impliedFormat":1},{"version":"0250da3eb85c99624f974e77ef355cdf86f43980251bc371475c2b397ba55bcd","impliedFormat":1},{"version":"f1c93e046fb3d9b7f8249629f4b63dc068dd839b824dd0aa39a5e68476dc9420","impliedFormat":1},{"version":"3d3a5f27ffbc06c885dd4d5f9ee20de61faf877fe2c3a7051c4825903d9a7fdc","impliedFormat":1},{"version":"12806f9f085598ef930edaf2467a5fa1789a878fba077cd27e85dc5851e11834","impliedFormat":1},{"version":"1dbca38aa4b0db1f4f9e6edacc2780af7e028b733d2a98dd3598cd235ca0c97d","impliedFormat":1},{"version":"a43fe41c33d0a192a0ecaf9b92e87bef3709c9972e6d53c42c49251ccb962d69","impliedFormat":1},{"version":"a177959203c017fad3ecc4f3d96c8757a840957a4959a3ae00dab9d35961ca6c","affectsGlobalScope":true,"impliedFormat":1},{"version":"6fc727ccf9b36e257ff982ea0badeffbfc2c151802f741bddff00c6af3b784cf","impliedFormat":1},{"version":"19143c930aef7ccf248549f3e78992f2f1049118ec5d4622e95025057d8e392b","impliedFormat":1},{"version":"4844a4c9b4b1e812b257676ed8a80b3f3be0e29bf05e742cc2ea9c3c6865e6c6","impliedFormat":1},{"version":"064878a60367e0407c42fb7ba02a2ea4d83257357dc20088e549bd4d89433e9c","impliedFormat":1},{"version":"cca8917838a876e2d7016c9b6af57cbf11fdf903c5fdd8e613fa31840b2957bf","impliedFormat":1},{"version":"d91ae55e4282c22b9c21bc26bd3ef637d3fe132507b10529ae68bf76f5de785b","impliedFormat":1},{"version":"b484ec11ba00e3a2235562a41898d55372ccabe607986c6fa4f4aba72093749f","impliedFormat":1},{"version":"7e8a671604329e178bb479c8f387715ebd40a091fc4a7552a0a75c2f3a21c65c","impliedFormat":1},{"version":"41ef7992c555671a8fe54db302788adefa191ded810a50329b79d20a6772d14c","impliedFormat":1},{"version":"041a7781b9127ab568d2cdcce62c58fdea7c7407f40b8c50045d7866a2727130","impliedFormat":1},{"version":"4c5e90ddbcd177ad3f2ffc909ae217c87820f1e968f6959e4b6ba38a8cec935e","impliedFormat":1},{"version":"b70dd9a44e1ac42f030bb12e7d79117eac7cb74170d72d381a1e7913320af23a","impliedFormat":1},{"version":"55cdbeebe76a1fa18bbd7e7bf73350a2173926bd3085bb050cf5a5397025ee4e","impliedFormat":1},{"version":"8baa5d0febc68db886c40bf341e5c90dc215a90cd64552e47e8184be6b7e3358","impliedFormat":1},{"version":"15fe687c59d62741b4494d5e623d497d55eb38966ecf5bea7f36e48fc3fbe15e","impliedFormat":1},{"version":"2c3b8be03577c98530ef9cb1a76e2c812636a871f367e9edf4c5f3ce702b77f8","affectsGlobalScope":true,"impliedFormat":1},{"version":"89121c1bf2990f5219bfd802a3e7fc557de447c62058d6af68d6b6348d64499a","impliedFormat":1},{"version":"79b4369233a12c6fa4a07301ecb7085802c98f3a77cf9ab97eee27e1656f82e6","impliedFormat":1},{"version":"742f21debb3937c3839a63245648238555bdab1ea095d43fd10c88a64029bf76","impliedFormat":1},{"version":"7cfdf3b9a5ba934a058bfc9390c074104dc7223b7e3c16fd5335206d789bc3d3","impliedFormat":1},{"version":"0944f27ebff4b20646b71e7e3faaaae50a6debd40bc63e225de1320dd15c5795","impliedFormat":1},{"version":"8a7219b41d3c1c93f3f3b779146f313efade2404eeece88dcd366df7e2364977","impliedFormat":1},{"version":"a109c4289d59d9019cfe1eeab506fe57817ee549499b02a83a7e9d3bdf662d63","impliedFormat":1},{"version":"d4a22007b481fe2a2e6bfd3a42c00cd62d41edb36d30fc4697df2692e9891fc8","impliedFormat":1},{"version":"5d30565583300c9256072a013ac0318cc603ff769b4c5cafc222394ea93963e1","impliedFormat":1},{"version":"28ca156f93e9f2f073d825452a114d106291d123564ca49af5b108ba20311011","affectsGlobalScope":true,"impliedFormat":1}],"root":[[78,85],[87,119]],"options":{"allowImportingTsExtensions":true,"composite":true,"esModuleInterop":true,"module":100,"skipLibCheck":true,"strict":true,"target":9},"referencedMap":[[119,1],[78,2],[68,3],[72,3],[70,4],[74,5],[67,6],[75,1],[66,3],[76,7],[77,3],[71,3],[73,8],[69,9],[122,10],[123,3],[120,3],[124,3],[187,11],[188,11],[189,12],[127,13],[190,14],[191,15],[192,16],[125,3],[193,17],[194,18],[195,19],[196,20],[197,21],[198,22],[199,22],[200,23],[201,24],[202,25],[203,26],[128,3],[126,3],[204,27],[205,28],[206,29],[247,30],[207,31],[208,32],[209,31],[210,33],[211,34],[213,35],[214,36],[215,36],[216,36],[217,37],[218,38],[219,39],[220,40],[221,41],[222,42],[223,42],[224,43],[225,3],[226,3],[227,44],[228,45],[229,44],[230,46],[231,47],[232,48],[233,49],[234,50],[235,51],[236,52],[237,53],[238,54],[239,55],[240,56],[241,57],[242,58],[243,59],[244,60],[129,31],[130,3],[131,61],[132,62],[133,3],[134,63],[135,3],[178,64],[179,65],[180,66],[181,66],[182,67],[183,3],[184,14],[185,68],[186,65],[245,69],[246,70],[248,3],[250,71],[249,3],[121,3],[212,3],[86,3],[63,3],[64,3],[12,3],[10,3],[11,3],[16,3],[15,3],[2,3],[17,3],[18,3],[19,3],[20,3],[21,3],[22,3],[23,3],[24,3],[3,3],[25,3],[26,3],[4,3],[27,3],[31,3],[28,3],[29,3],[30,3],[32,3],[33,3],[34,3],[5,3],[35,3],[36,3],[37,3],[38,3],[6,3],[42,3],[39,3],[40,3],[41,3],[43,3],[7,3],[44,3],[49,3],[50,3],[45,3],[46,3],[47,3],[48,3],[8,3],[54,3],[51,3],[52,3],[53,3],[55,3],[9,3],[56,3],[65,3],[57,3],[58,3],[60,3],[59,3],[1,3],[61,3],[62,3],[14,3],[13,3],[154,72],[166,73],[151,74],[167,75],[176,76],[142,77],[143,78],[141,79],[175,80],[170,81],[174,82],[145,83],[163,84],[144,85],[173,86],[139,87],[140,81],[146,88],[147,3],[153,89],[150,88],[137,90],[177,91],[168,92],[157,93],[156,88],[158,94],[161,95],[155,96],[159,97],[171,80],[148,98],[149,99],[162,100],[138,75],[165,101],[164,88],[152,99],[160,102],[169,3],[136,3],[172,103],[118,104],[82,105],[83,105],[84,105],[85,105],[87,106],[88,105],[80,104],[89,105],[81,3],[90,104],[91,104],[92,104],[93,104],[94,104],[95,104],[96,104],[97,104],[98,104],[99,104],[100,104],[79,104],[101,104],[102,104],[103,104],[104,104],[105,104],[106,107],[107,104],[108,104],[109,108],[110,104],[111,109],[112,107],[113,109],[114,110],[115,104],[116,107],[117,104],[252,111],[253,3],[254,112],[256,113],[257,114],[258,111],[255,3],[259,115],[251,3],[260,3]],"affectedFilesPendingEmit":[[119,17],[78,17],[118,17],[82,17],[83,17],[84,17],[85,17],[87,17],[88,17],[80,17],[89,17],[81,17],[90,17],[91,17],[92,17],[93,17],[94,17],[95,17],[96,17],[97,17],[98,17],[99,17],[100,17],[79,17],[101,17],[102,17],[103,17],[104,17],[105,17],[106,17],[107,17],[108,17],[109,17],[110,17],[111,17],[112,17],[113,17],[114,17],[115,17],[116,17],[117,17]],"emitSignatures":[78,79,80,81,82,83,84,85,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119],"version":"5.9.3"}