@rathnasgala/theme 0.0.20 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "@gala/site-template",
3
- "version": "0.0.1",
3
+ "version": "2.0.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@gala/site-template",
9
- "version": "0.0.1",
9
+ "version": "2.0.0",
10
10
  "devDependencies": {
11
11
  "@11ty/eleventy": "3.1.6",
12
+ "esbuild": "0.28.2",
12
13
  "github-slugger": "2.0.0",
13
14
  "markdown-it": "15.0.0",
14
15
  "markdown-it-footnote": "4.0.0",
@@ -273,6 +274,448 @@
273
274
  "node": ">=18"
274
275
  }
275
276
  },
277
+ "node_modules/@esbuild/aix-ppc64": {
278
+ "version": "0.28.2",
279
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz",
280
+ "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==",
281
+ "cpu": [
282
+ "ppc64"
283
+ ],
284
+ "dev": true,
285
+ "license": "MIT",
286
+ "optional": true,
287
+ "os": [
288
+ "aix"
289
+ ],
290
+ "engines": {
291
+ "node": ">=18"
292
+ }
293
+ },
294
+ "node_modules/@esbuild/android-arm": {
295
+ "version": "0.28.2",
296
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz",
297
+ "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==",
298
+ "cpu": [
299
+ "arm"
300
+ ],
301
+ "dev": true,
302
+ "license": "MIT",
303
+ "optional": true,
304
+ "os": [
305
+ "android"
306
+ ],
307
+ "engines": {
308
+ "node": ">=18"
309
+ }
310
+ },
311
+ "node_modules/@esbuild/android-arm64": {
312
+ "version": "0.28.2",
313
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz",
314
+ "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==",
315
+ "cpu": [
316
+ "arm64"
317
+ ],
318
+ "dev": true,
319
+ "license": "MIT",
320
+ "optional": true,
321
+ "os": [
322
+ "android"
323
+ ],
324
+ "engines": {
325
+ "node": ">=18"
326
+ }
327
+ },
328
+ "node_modules/@esbuild/android-x64": {
329
+ "version": "0.28.2",
330
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz",
331
+ "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==",
332
+ "cpu": [
333
+ "x64"
334
+ ],
335
+ "dev": true,
336
+ "license": "MIT",
337
+ "optional": true,
338
+ "os": [
339
+ "android"
340
+ ],
341
+ "engines": {
342
+ "node": ">=18"
343
+ }
344
+ },
345
+ "node_modules/@esbuild/darwin-arm64": {
346
+ "version": "0.28.2",
347
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz",
348
+ "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==",
349
+ "cpu": [
350
+ "arm64"
351
+ ],
352
+ "dev": true,
353
+ "license": "MIT",
354
+ "optional": true,
355
+ "os": [
356
+ "darwin"
357
+ ],
358
+ "engines": {
359
+ "node": ">=18"
360
+ }
361
+ },
362
+ "node_modules/@esbuild/darwin-x64": {
363
+ "version": "0.28.2",
364
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz",
365
+ "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==",
366
+ "cpu": [
367
+ "x64"
368
+ ],
369
+ "dev": true,
370
+ "license": "MIT",
371
+ "optional": true,
372
+ "os": [
373
+ "darwin"
374
+ ],
375
+ "engines": {
376
+ "node": ">=18"
377
+ }
378
+ },
379
+ "node_modules/@esbuild/freebsd-arm64": {
380
+ "version": "0.28.2",
381
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz",
382
+ "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==",
383
+ "cpu": [
384
+ "arm64"
385
+ ],
386
+ "dev": true,
387
+ "license": "MIT",
388
+ "optional": true,
389
+ "os": [
390
+ "freebsd"
391
+ ],
392
+ "engines": {
393
+ "node": ">=18"
394
+ }
395
+ },
396
+ "node_modules/@esbuild/freebsd-x64": {
397
+ "version": "0.28.2",
398
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz",
399
+ "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==",
400
+ "cpu": [
401
+ "x64"
402
+ ],
403
+ "dev": true,
404
+ "license": "MIT",
405
+ "optional": true,
406
+ "os": [
407
+ "freebsd"
408
+ ],
409
+ "engines": {
410
+ "node": ">=18"
411
+ }
412
+ },
413
+ "node_modules/@esbuild/linux-arm": {
414
+ "version": "0.28.2",
415
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz",
416
+ "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==",
417
+ "cpu": [
418
+ "arm"
419
+ ],
420
+ "dev": true,
421
+ "license": "MIT",
422
+ "optional": true,
423
+ "os": [
424
+ "linux"
425
+ ],
426
+ "engines": {
427
+ "node": ">=18"
428
+ }
429
+ },
430
+ "node_modules/@esbuild/linux-arm64": {
431
+ "version": "0.28.2",
432
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz",
433
+ "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==",
434
+ "cpu": [
435
+ "arm64"
436
+ ],
437
+ "dev": true,
438
+ "license": "MIT",
439
+ "optional": true,
440
+ "os": [
441
+ "linux"
442
+ ],
443
+ "engines": {
444
+ "node": ">=18"
445
+ }
446
+ },
447
+ "node_modules/@esbuild/linux-ia32": {
448
+ "version": "0.28.2",
449
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz",
450
+ "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==",
451
+ "cpu": [
452
+ "ia32"
453
+ ],
454
+ "dev": true,
455
+ "license": "MIT",
456
+ "optional": true,
457
+ "os": [
458
+ "linux"
459
+ ],
460
+ "engines": {
461
+ "node": ">=18"
462
+ }
463
+ },
464
+ "node_modules/@esbuild/linux-loong64": {
465
+ "version": "0.28.2",
466
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz",
467
+ "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==",
468
+ "cpu": [
469
+ "loong64"
470
+ ],
471
+ "dev": true,
472
+ "license": "MIT",
473
+ "optional": true,
474
+ "os": [
475
+ "linux"
476
+ ],
477
+ "engines": {
478
+ "node": ">=18"
479
+ }
480
+ },
481
+ "node_modules/@esbuild/linux-mips64el": {
482
+ "version": "0.28.2",
483
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz",
484
+ "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==",
485
+ "cpu": [
486
+ "mips64el"
487
+ ],
488
+ "dev": true,
489
+ "license": "MIT",
490
+ "optional": true,
491
+ "os": [
492
+ "linux"
493
+ ],
494
+ "engines": {
495
+ "node": ">=18"
496
+ }
497
+ },
498
+ "node_modules/@esbuild/linux-ppc64": {
499
+ "version": "0.28.2",
500
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz",
501
+ "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==",
502
+ "cpu": [
503
+ "ppc64"
504
+ ],
505
+ "dev": true,
506
+ "license": "MIT",
507
+ "optional": true,
508
+ "os": [
509
+ "linux"
510
+ ],
511
+ "engines": {
512
+ "node": ">=18"
513
+ }
514
+ },
515
+ "node_modules/@esbuild/linux-riscv64": {
516
+ "version": "0.28.2",
517
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz",
518
+ "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==",
519
+ "cpu": [
520
+ "riscv64"
521
+ ],
522
+ "dev": true,
523
+ "license": "MIT",
524
+ "optional": true,
525
+ "os": [
526
+ "linux"
527
+ ],
528
+ "engines": {
529
+ "node": ">=18"
530
+ }
531
+ },
532
+ "node_modules/@esbuild/linux-s390x": {
533
+ "version": "0.28.2",
534
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz",
535
+ "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==",
536
+ "cpu": [
537
+ "s390x"
538
+ ],
539
+ "dev": true,
540
+ "license": "MIT",
541
+ "optional": true,
542
+ "os": [
543
+ "linux"
544
+ ],
545
+ "engines": {
546
+ "node": ">=18"
547
+ }
548
+ },
549
+ "node_modules/@esbuild/linux-x64": {
550
+ "version": "0.28.2",
551
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz",
552
+ "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==",
553
+ "cpu": [
554
+ "x64"
555
+ ],
556
+ "dev": true,
557
+ "license": "MIT",
558
+ "optional": true,
559
+ "os": [
560
+ "linux"
561
+ ],
562
+ "engines": {
563
+ "node": ">=18"
564
+ }
565
+ },
566
+ "node_modules/@esbuild/netbsd-arm64": {
567
+ "version": "0.28.2",
568
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz",
569
+ "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==",
570
+ "cpu": [
571
+ "arm64"
572
+ ],
573
+ "dev": true,
574
+ "license": "MIT",
575
+ "optional": true,
576
+ "os": [
577
+ "netbsd"
578
+ ],
579
+ "engines": {
580
+ "node": ">=18"
581
+ }
582
+ },
583
+ "node_modules/@esbuild/netbsd-x64": {
584
+ "version": "0.28.2",
585
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz",
586
+ "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==",
587
+ "cpu": [
588
+ "x64"
589
+ ],
590
+ "dev": true,
591
+ "license": "MIT",
592
+ "optional": true,
593
+ "os": [
594
+ "netbsd"
595
+ ],
596
+ "engines": {
597
+ "node": ">=18"
598
+ }
599
+ },
600
+ "node_modules/@esbuild/openbsd-arm64": {
601
+ "version": "0.28.2",
602
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz",
603
+ "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==",
604
+ "cpu": [
605
+ "arm64"
606
+ ],
607
+ "dev": true,
608
+ "license": "MIT",
609
+ "optional": true,
610
+ "os": [
611
+ "openbsd"
612
+ ],
613
+ "engines": {
614
+ "node": ">=18"
615
+ }
616
+ },
617
+ "node_modules/@esbuild/openbsd-x64": {
618
+ "version": "0.28.2",
619
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz",
620
+ "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==",
621
+ "cpu": [
622
+ "x64"
623
+ ],
624
+ "dev": true,
625
+ "license": "MIT",
626
+ "optional": true,
627
+ "os": [
628
+ "openbsd"
629
+ ],
630
+ "engines": {
631
+ "node": ">=18"
632
+ }
633
+ },
634
+ "node_modules/@esbuild/openharmony-arm64": {
635
+ "version": "0.28.2",
636
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz",
637
+ "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==",
638
+ "cpu": [
639
+ "arm64"
640
+ ],
641
+ "dev": true,
642
+ "license": "MIT",
643
+ "optional": true,
644
+ "os": [
645
+ "openharmony"
646
+ ],
647
+ "engines": {
648
+ "node": ">=18"
649
+ }
650
+ },
651
+ "node_modules/@esbuild/sunos-x64": {
652
+ "version": "0.28.2",
653
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz",
654
+ "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==",
655
+ "cpu": [
656
+ "x64"
657
+ ],
658
+ "dev": true,
659
+ "license": "MIT",
660
+ "optional": true,
661
+ "os": [
662
+ "sunos"
663
+ ],
664
+ "engines": {
665
+ "node": ">=18"
666
+ }
667
+ },
668
+ "node_modules/@esbuild/win32-arm64": {
669
+ "version": "0.28.2",
670
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz",
671
+ "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==",
672
+ "cpu": [
673
+ "arm64"
674
+ ],
675
+ "dev": true,
676
+ "license": "MIT",
677
+ "optional": true,
678
+ "os": [
679
+ "win32"
680
+ ],
681
+ "engines": {
682
+ "node": ">=18"
683
+ }
684
+ },
685
+ "node_modules/@esbuild/win32-ia32": {
686
+ "version": "0.28.2",
687
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz",
688
+ "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==",
689
+ "cpu": [
690
+ "ia32"
691
+ ],
692
+ "dev": true,
693
+ "license": "MIT",
694
+ "optional": true,
695
+ "os": [
696
+ "win32"
697
+ ],
698
+ "engines": {
699
+ "node": ">=18"
700
+ }
701
+ },
702
+ "node_modules/@esbuild/win32-x64": {
703
+ "version": "0.28.2",
704
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz",
705
+ "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==",
706
+ "cpu": [
707
+ "x64"
708
+ ],
709
+ "dev": true,
710
+ "license": "MIT",
711
+ "optional": true,
712
+ "os": [
713
+ "win32"
714
+ ],
715
+ "engines": {
716
+ "node": ">=18"
717
+ }
718
+ },
276
719
  "node_modules/@shikijs/core": {
277
720
  "version": "4.4.3",
278
721
  "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-4.4.3.tgz",
@@ -885,6 +1328,48 @@
885
1328
  "errno": "cli.js"
886
1329
  }
887
1330
  },
1331
+ "node_modules/esbuild": {
1332
+ "version": "0.28.2",
1333
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz",
1334
+ "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==",
1335
+ "dev": true,
1336
+ "hasInstallScript": true,
1337
+ "license": "MIT",
1338
+ "bin": {
1339
+ "esbuild": "bin/esbuild"
1340
+ },
1341
+ "engines": {
1342
+ "node": ">=18"
1343
+ },
1344
+ "optionalDependencies": {
1345
+ "@esbuild/aix-ppc64": "0.28.2",
1346
+ "@esbuild/android-arm": "0.28.2",
1347
+ "@esbuild/android-arm64": "0.28.2",
1348
+ "@esbuild/android-x64": "0.28.2",
1349
+ "@esbuild/darwin-arm64": "0.28.2",
1350
+ "@esbuild/darwin-x64": "0.28.2",
1351
+ "@esbuild/freebsd-arm64": "0.28.2",
1352
+ "@esbuild/freebsd-x64": "0.28.2",
1353
+ "@esbuild/linux-arm": "0.28.2",
1354
+ "@esbuild/linux-arm64": "0.28.2",
1355
+ "@esbuild/linux-ia32": "0.28.2",
1356
+ "@esbuild/linux-loong64": "0.28.2",
1357
+ "@esbuild/linux-mips64el": "0.28.2",
1358
+ "@esbuild/linux-ppc64": "0.28.2",
1359
+ "@esbuild/linux-riscv64": "0.28.2",
1360
+ "@esbuild/linux-s390x": "0.28.2",
1361
+ "@esbuild/linux-x64": "0.28.2",
1362
+ "@esbuild/netbsd-arm64": "0.28.2",
1363
+ "@esbuild/netbsd-x64": "0.28.2",
1364
+ "@esbuild/openbsd-arm64": "0.28.2",
1365
+ "@esbuild/openbsd-x64": "0.28.2",
1366
+ "@esbuild/openharmony-arm64": "0.28.2",
1367
+ "@esbuild/sunos-x64": "0.28.2",
1368
+ "@esbuild/win32-arm64": "0.28.2",
1369
+ "@esbuild/win32-ia32": "0.28.2",
1370
+ "@esbuild/win32-x64": "0.28.2"
1371
+ }
1372
+ },
888
1373
  "node_modules/escape-html": {
889
1374
  "version": "1.0.3",
890
1375
  "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -1,19 +1,20 @@
1
1
  {
2
2
  "name": "@gala/site-template",
3
- "version": "0.0.1",
3
+ "version": "2.0.0",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "scripts": {
7
- "build": "eleventy",
7
+ "build:reader": "node scripts/build-reader.js",
8
+ "build": "npm run build:reader && eleventy",
9
+ "pretest": "npm run build:reader",
8
10
  "test": "node --test",
9
- "lint": "node --check eleventy.config.js && node --check lib/build-manifest.js && node --check lib/engagement-snapshot.js && node --check lib/performance-budget.js && node --check lib/publication-state.js && node --check lib/render-markdown.js && node --check lib/seo.js && node --check lib/share-targets.js && node --check lib/site-config.js && node --check scripts/push.js && node --check src/_data/buildManifest.js && node --check src/_data/engagementSnapshot.js && node --check src/_data/feedLinks.js && node --check src/_data/languages.js && node --check src/_data/site.js && node --check src/assets/interactions.js && node --check src/assets/preferences.js && node --check src/assets/search.js && node --check src/assets/theme-mode.js && node --check src/cname.11ty.js && node --check src/feed.11ty.js && node --check src/languages.11ty.js && node --check src/posts.11ty.js && node --check src/redirects.11ty.js && node --check src/search-index.11ty.js && node --check src/sitemap.11ty.js && node --check test/build-manifest.test.js && node --check test/cname.test.js && node --check test/component-contract.test.js && node --check test/config.test.js && node --check test/eleventy-manifest-build.test.js && node --check test/engagement-client.test.js && node --check test/engagement-snapshot.test.js && node --check test/feed.test.js && node --check test/fixtures/xss-payloads.js && node --check test/managed-files.test.js && node --check test/performance-budget.test.js && node --check test/preferences.test.js && node --check test/publication-state.test.js && node --check test/render-markdown.test.js && node --check test/search.test.js && node --check test/seo.test.js && node --check test/share-targets.test.js && node --check test/supporting-surfaces.test.js && node --check test/theme-contract.test.js && node --check test/theme-contrast.test.js && node --check test/theme-mode.test.js && node --check test/theme-release-workflow.test.js",
11
+ "lint": "node scripts/lint.js",
10
12
  "push": "node scripts/push.js"
11
13
  },
12
- "engines": {
13
- "node": ">=20"
14
- },
14
+ "engines": { "node": ">=20" },
15
15
  "devDependencies": {
16
16
  "@11ty/eleventy": "3.1.6",
17
+ "esbuild": "0.28.2",
17
18
  "github-slugger": "2.0.0",
18
19
  "markdown-it": "15.0.0",
19
20
  "markdown-it-footnote": "4.0.0",
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { build } from 'esbuild';
4
+
5
+ await build({
6
+ entryPoints: ['src/client/reader.js'],
7
+ outfile: 'src/assets/reader.js',
8
+ bundle: true,
9
+ minify: true,
10
+ format: 'iife',
11
+ platform: 'browser',
12
+ target: ['es2022'],
13
+ legalComments: 'none',
14
+ sourcemap: false,
15
+ });
16
+
17
+ await build({
18
+ entryPoints: ['src/styles/theme.css'],
19
+ outfile: 'src/assets/theme.css',
20
+ bundle: true,
21
+ minify: true,
22
+ legalComments: 'none',
23
+ external: ['../assets/*.svg'],
24
+ });
@@ -0,0 +1,21 @@
1
+ import { readdir } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { spawnSync } from 'node:child_process';
4
+
5
+ async function javascriptFiles(root) {
6
+ const entries = await readdir(root, { withFileTypes: true });
7
+ const nested = await Promise.all(entries.map(async (entry) => {
8
+ const target = path.join(root, entry.name);
9
+ if (entry.isDirectory()) return javascriptFiles(target);
10
+ return entry.isFile() && entry.name.endsWith('.js') ? [target] : [];
11
+ }));
12
+ return nested.flat();
13
+ }
14
+
15
+ const roots = ['lib', 'scripts', 'src', 'test'];
16
+ const files = ['eleventy.config.js', ...(await Promise.all(roots.map(javascriptFiles))).flat()].sort();
17
+ for (const file of files) {
18
+ const result = spawnSync(process.execPath, ['--check', file], { stdio: 'inherit', shell: false });
19
+ if (result.error) throw result.error;
20
+ if (result.status !== 0) process.exit(result.status ?? 1);
21
+ }
@@ -13,33 +13,42 @@
13
13
  {% macro tableOfContents(items) %}<nav class="gala-toc" aria-label="Table of contents"><ol>{% for item in items %}<li><a href="#{{ item.id }}">{{ item.text }}</a></li>{% endfor %}</ol></nav>{% endmacro %}
14
14
  {% macro shareControl(canonicalUrl, targets=[]) %}<section class="gala-share" aria-label="Share this article"><button type="button" data-copy-url="{{ canonicalUrl | escape }}" aria-label="Copy canonical URL">Copy link</button><output class="gala-share__status" aria-live="polite"></output><input class="gala-share__fallback" value="{{ canonicalUrl | escape }}" readonly aria-label="Canonical URL">{% if targets.length %}<ul>{% for target in targets %}<li><a href="{{ target.url | escape }}" rel="noopener noreferrer" aria-label="Share on {{ target.label | escape }}">{{ target.label }}</a></li>{% endfor %}</ul>{% endif %}</section>{% endmacro %}
15
15
  {% macro languageSwitcher(links, currentLanguage) %}{% if links.length > 2 %}<label>Preferred language <select data-language-preference data-navigate-on-selection>{% for link in links %}{% if link.hreflang != "x-default" %}<option value="{{ link.hreflang | escape }}" data-url="{{ link.href | escape }}"{% if link.hreflang == currentLanguage %} selected{% endif %}>{{ link.hreflang }}</option>{% endif %}{% endfor %}</select></label>{% endif %}{% endmacro %}
16
- {% macro engagementSummary(articleId, engagement, apiBaseUrl) %}
17
- <section class="gala-engagement" aria-label="Engagement" data-article-id="{{ articleId | escape }}" data-engagement-url="{{ apiBaseUrl | escape }}/v1/articles/{{ articleId | escape }}/engagement">
16
+ {% macro engagementSummary(articleId, canonicalUrl, engagement, apiBaseUrl) %}
17
+ <section id="conversation" class="gala-engagement" aria-label="Article conversation" data-article-id="{{ articleId | escape }}" data-engagement-url="{{ apiBaseUrl | escape }}/v1/articles/{{ articleId | escape }}/engagement">
18
+ <aside class="gala-action-rail" aria-label="Reader actions">
19
+ <div class="gala-reaction-actions" role="group" aria-label="React to this article">
20
+ {% for reaction in [
21
+ { value: 'like', label: 'Like', icon: '♥' },
22
+ { value: 'insightful', label: 'Insightful', icon: '✦' },
23
+ { value: 'celebrate', label: 'Celebrate', icon: '★' },
24
+ { value: 'funny', label: 'Funny', icon: '☺' },
25
+ { value: 'mind-blown', label: 'Mind blown', icon: '◉' },
26
+ { value: 'thank-you', label: 'Thank you', icon: '✓' }
27
+ ] %}<button type="button" data-reaction="{{ reaction.value }}" aria-label="{{ reaction.label }}" title="{{ reaction.label }}" aria-pressed="false"><span aria-hidden="true">{{ reaction.icon }}</span></button>{% endfor %}
28
+ </div>
29
+ <button type="button" data-follow-article aria-label="Follow article" title="Follow article" aria-pressed="false"><span aria-hidden="true">+</span><span class="gala-visually-hidden" data-follow-label>Follow article</span></button>
30
+ <div class="gala-share" aria-label="Share this article">
31
+ <button type="button" data-copy-url="{{ canonicalUrl | escape }}" aria-label="Copy link" title="Copy link">Copy</button>
32
+ <button type="button" data-native-share="{{ canonicalUrl | escape }}" aria-label="Share" title="Share">Share</button>
33
+ <a href="https://x.com/intent/post?url={{ canonicalUrl | urlencode }}" rel="noopener noreferrer" aria-label="Share on X" title="Share on X">X</a>
34
+ <a href="https://wa.me/?text={{ canonicalUrl | urlencode }}" rel="noopener noreferrer" aria-label="Share on WhatsApp" title="Share on WhatsApp">WA</a>
35
+ <output class="gala-share__status gala-visually-hidden" aria-live="polite"></output>
36
+ <input class="gala-share__fallback" value="{{ canonicalUrl | escape }}" readonly aria-label="Canonical URL">
37
+ </div>
38
+ </aside>
39
+ <div class="gala-conversation">
40
+ <header class="gala-conversation__header"><p class="gala-eyebrow">Discussion</p><h2>Continue the conversation</h2></header>
18
41
  {% if engagement.available %}<dl data-engagement-snapshot><div><dt>Reactions</dt><dd>{{ engagement.reactions }}</dd></div><div><dt>Comments</dt><dd>{{ engagement.comments }}</dd></div><div><dt>Views</dt><dd>{{ engagement.views }}</dd></div></dl>{% else %}<p class="gala-engagement__placeholder" role="status">Loading engagement data.</p>{% endif %}
19
42
  <div data-engagement-live></div>
20
43
  {# Readers see what they can do before they are asked who they are. Signing in is requested
21
44
  at the moment of intent, and the intent is replayed once they are back. #}
22
- <section class="gala-engagement-actions" aria-label="Reader actions" data-engagement-actions>
23
- <div class="gala-reaction-actions" role="group" aria-label="React to this article">
24
- {# The six the platform actually stores (io.gala.api.engagement.ReactionType). Offering
25
- any other name renders a button that can only ever fail on the way to the API. #}
26
- {% for reaction in [
27
- { value: 'like', label: 'Like' },
28
- { value: 'insightful', label: 'Insightful' },
29
- { value: 'celebrate', label: 'Celebrate' },
30
- { value: 'funny', label: 'Funny' },
31
- { value: 'mind-blown', label: 'Mind blown' },
32
- { value: 'thank-you', label: 'Thank you' }
33
- ] %}<button type="button" data-reaction="{{ reaction.value }}" aria-pressed="false">{{ reaction.label }}</button>{% endfor %}
34
- </div>
35
- <button type="button" data-follow-article aria-pressed="false">Follow article</button>
36
- </section>
37
45
  {# The conversation is an island: it owns its own state, because a thread five deep with a page
38
46
  cursor, an open reply form and an edit in progress is state, and hand-written DOM kept losing
39
47
  track of it. Nothing here is needed by a search engine — comments have always arrived from the
40
48
  API after load — so rendering them on the client costs nothing the article cares about. #}
41
49
  <div data-gala-comments></div>
42
50
  <output data-engagement-status aria-live="polite"></output>
51
+ </div>
43
52
  </section>
44
53
  {% endmacro %}
45
54
  {% macro pageFooter(siteName, links=[]) %}<footer class="gala-page-footer"><p>&copy; {{ siteName }}</p>{% if links.length %}<nav aria-label="Footer"><ul>{% for link in links %}<li><a href="{{ link.url }}">{{ link.label }}</a></li>{% endfor %}</ul></nav>{% endif %}</footer>{% endmacro %}