@ranx729/ducktape-assets 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +12 -2
- package/README.md +12 -2
- package/catalog.json +794 -760
- package/index.json +5 -5
- package/package.json +3 -3
- package/sets/illuminated-acanthus.json +241 -85
- package/src/copy.mjs +24 -3
- package/src/generate.mjs +12 -2
- package/src/node.mjs +12 -0
- package/src/resolver.mjs +18 -5
package/index.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": 1,
|
|
3
|
-
"generatedAt": "2026-10-
|
|
3
|
+
"generatedAt": "2026-10-27T17:12:31.916Z",
|
|
4
4
|
"sets": {
|
|
5
5
|
"illuminated-acanthus": {
|
|
6
|
-
"version": "
|
|
6
|
+
"version": "2.0.0",
|
|
7
7
|
"package": "@ranx729/ducktape-assets-illuminated-acanthus",
|
|
8
8
|
"parts": [],
|
|
9
9
|
"mastersPackage": "@ranx729/ducktape-assets-illuminated-acanthus-masters",
|
|
10
10
|
"mastersParts": [],
|
|
11
|
-
"cdn": "https://cdn.jsdelivr.net/npm/@ranx729/ducktape-assets-illuminated-acanthus@
|
|
12
|
-
"mastersCdn": "https://cdn.jsdelivr.net/npm/@ranx729/ducktape-assets-illuminated-acanthus-masters@
|
|
11
|
+
"cdn": "https://cdn.jsdelivr.net/npm/@ranx729/ducktape-assets-illuminated-acanthus@2.0.0/",
|
|
12
|
+
"mastersCdn": "https://cdn.jsdelivr.net/npm/@ranx729/ducktape-assets-illuminated-acanthus-masters@2.0.0/",
|
|
13
13
|
"assets": 36,
|
|
14
14
|
"license": {
|
|
15
15
|
"artwork": "CC-BY-4.0"
|
|
16
16
|
},
|
|
17
|
-
"contentHash": "sha256:
|
|
17
|
+
"contentHash": "sha256:a7a943d0ee38ad8981251f4e6b723f69a5638417b682595a863563941510a81c",
|
|
18
18
|
"status": "active"
|
|
19
19
|
},
|
|
20
20
|
"medieval-cutouts": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ranx729/ducktape-assets",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Index, catalog and build-time resolver for the Ducktape Assets library. Metadata only, no images.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
},
|
|
45
45
|
"ducktape": {
|
|
46
46
|
"kind": "index",
|
|
47
|
-
"inputsHash": "sha256:
|
|
48
|
-
"contentHash": "sha256:
|
|
47
|
+
"inputsHash": "sha256:43ed276ca6ec7cc9615e54be5531d25f194c7f273616f26c09216e4df3ab617f",
|
|
48
|
+
"contentHash": "sha256:63c692b5bd87c81fadb195c40e0f4e0e3fa55dc1a826a8a8d50fda35ceb0f341",
|
|
49
49
|
"schema": 1
|
|
50
50
|
}
|
|
51
51
|
}
|
|
@@ -1611,25 +1611,25 @@
|
|
|
1611
1611
|
],
|
|
1612
1612
|
"encoding": {
|
|
1613
1613
|
"avif": true,
|
|
1614
|
-
"avifTopBytes":
|
|
1615
|
-
"webpTopBytes":
|
|
1614
|
+
"avifTopBytes": 130229,
|
|
1615
|
+
"webpTopBytes": 253534
|
|
1616
1616
|
},
|
|
1617
1617
|
"facing": "none",
|
|
1618
1618
|
"group": "floral-border",
|
|
1619
|
-
"height":
|
|
1619
|
+
"height": 1000,
|
|
1620
1620
|
"master": {
|
|
1621
|
-
"bytes":
|
|
1622
|
-
"h":
|
|
1621
|
+
"bytes": 1207266,
|
|
1622
|
+
"h": 1000,
|
|
1623
1623
|
"path": "masters/floral-frame.webp",
|
|
1624
|
-
"sha256": "
|
|
1625
|
-
"w":
|
|
1624
|
+
"sha256": "5a77b95402e616d528f845b93101afe239aee8cb21a79154f4733af8cc7c297f",
|
|
1625
|
+
"w": 1367
|
|
1626
1626
|
},
|
|
1627
1627
|
"palette": [
|
|
1628
|
-
"#
|
|
1629
|
-
"#
|
|
1630
|
-
"#
|
|
1631
|
-
"#
|
|
1632
|
-
"#
|
|
1628
|
+
"#bf7c3c",
|
|
1629
|
+
"#956731",
|
|
1630
|
+
"#b95e30",
|
|
1631
|
+
"#63655b",
|
|
1632
|
+
"#9a743e"
|
|
1633
1633
|
],
|
|
1634
1634
|
"related": [
|
|
1635
1635
|
{
|
|
@@ -1638,152 +1638,307 @@
|
|
|
1638
1638
|
}
|
|
1639
1639
|
],
|
|
1640
1640
|
"render": {
|
|
1641
|
+
"frame": {
|
|
1642
|
+
"atlas": {
|
|
1643
|
+
"avif": [
|
|
1644
|
+
{
|
|
1645
|
+
"bytes": 1266,
|
|
1646
|
+
"h": 47,
|
|
1647
|
+
"path": "avif/floral-frame-64.avif",
|
|
1648
|
+
"sha256": "c72f1029d3833b35d60254852e6257a043b24c9a75ac91eecfd396a5e5af43b7",
|
|
1649
|
+
"w": 64
|
|
1650
|
+
},
|
|
1651
|
+
{
|
|
1652
|
+
"bytes": 2051,
|
|
1653
|
+
"h": 70,
|
|
1654
|
+
"path": "avif/floral-frame-96.avif",
|
|
1655
|
+
"sha256": "2bcefa81cc582bb986977cc8941de86f9bc6197e2563a737a2ad868a3347ebc3",
|
|
1656
|
+
"w": 96
|
|
1657
|
+
},
|
|
1658
|
+
{
|
|
1659
|
+
"bytes": 3351,
|
|
1660
|
+
"h": 94,
|
|
1661
|
+
"path": "avif/floral-frame-128.avif",
|
|
1662
|
+
"sha256": "afd8bede3261bd6dcadae68c8633aa039a3e4181e1b76685fba3243f398a1b2f",
|
|
1663
|
+
"w": 128
|
|
1664
|
+
},
|
|
1665
|
+
{
|
|
1666
|
+
"bytes": 5052,
|
|
1667
|
+
"h": 140,
|
|
1668
|
+
"path": "avif/floral-frame-192.avif",
|
|
1669
|
+
"sha256": "3eea02e31baf0c0059abf160f4a39e8bb5bf2abfc3fa426393820dec13eaeb42",
|
|
1670
|
+
"w": 192
|
|
1671
|
+
},
|
|
1672
|
+
{
|
|
1673
|
+
"bytes": 6463,
|
|
1674
|
+
"h": 187,
|
|
1675
|
+
"path": "avif/floral-frame-256.avif",
|
|
1676
|
+
"sha256": "9ed5eff121b2ee01a8bd0618862ae7fbc87f2a2def0d4f6c51618831445198f0",
|
|
1677
|
+
"w": 256
|
|
1678
|
+
},
|
|
1679
|
+
{
|
|
1680
|
+
"bytes": 14881,
|
|
1681
|
+
"h": 281,
|
|
1682
|
+
"path": "avif/floral-frame-384.avif",
|
|
1683
|
+
"sha256": "b47dea3d0c356555b3f31ba4979163c708f0d99e97cb4130976a78b3c2b98ffd",
|
|
1684
|
+
"w": 384
|
|
1685
|
+
},
|
|
1686
|
+
{
|
|
1687
|
+
"bytes": 22279,
|
|
1688
|
+
"h": 375,
|
|
1689
|
+
"path": "avif/floral-frame-512.avif",
|
|
1690
|
+
"sha256": "46a428b802180a9ae46501d80ba536d4b1d39661ba30ca7903c422fa74867806",
|
|
1691
|
+
"w": 512
|
|
1692
|
+
},
|
|
1693
|
+
{
|
|
1694
|
+
"bytes": 47230,
|
|
1695
|
+
"h": 562,
|
|
1696
|
+
"path": "avif/floral-frame-768.avif",
|
|
1697
|
+
"sha256": "c05fba96991132f3c998f5720acc0286c58287b0d2708272fb32108474b71b0c",
|
|
1698
|
+
"w": 768
|
|
1699
|
+
},
|
|
1700
|
+
{
|
|
1701
|
+
"bytes": 77165,
|
|
1702
|
+
"h": 749,
|
|
1703
|
+
"path": "avif/floral-frame-1024.avif",
|
|
1704
|
+
"sha256": "fc62c1b0da3651d995583d4e953641b96ebb8489da9b4eb95ca5231bb5b3d7ca",
|
|
1705
|
+
"w": 1024
|
|
1706
|
+
},
|
|
1707
|
+
{
|
|
1708
|
+
"bytes": 130229,
|
|
1709
|
+
"h": 1000,
|
|
1710
|
+
"path": "avif/floral-frame-1367.avif",
|
|
1711
|
+
"sha256": "ecfc4fc9e19bdbf1547743c34c7004e34882b30f1f0f6b901d945e606fd7990a",
|
|
1712
|
+
"w": 1367
|
|
1713
|
+
}
|
|
1714
|
+
],
|
|
1715
|
+
"webp": [
|
|
1716
|
+
{
|
|
1717
|
+
"bytes": 1450,
|
|
1718
|
+
"h": 47,
|
|
1719
|
+
"path": "webp/floral-frame-64.webp",
|
|
1720
|
+
"sha256": "cf65baff36575006905dbd4d2d3c1c0bf5a0205c26744c4e19f5ac1e298cac6b",
|
|
1721
|
+
"w": 64
|
|
1722
|
+
},
|
|
1723
|
+
{
|
|
1724
|
+
"bytes": 2536,
|
|
1725
|
+
"h": 70,
|
|
1726
|
+
"path": "webp/floral-frame-96.webp",
|
|
1727
|
+
"sha256": "4aea33bd0ec4a2e46bfcc87eb0c980343edae525585df734703921d2c51773d7",
|
|
1728
|
+
"w": 96
|
|
1729
|
+
},
|
|
1730
|
+
{
|
|
1731
|
+
"bytes": 3774,
|
|
1732
|
+
"h": 94,
|
|
1733
|
+
"path": "webp/floral-frame-128.webp",
|
|
1734
|
+
"sha256": "138e726aa0837da22de393d01707a5d72f412ebe66fbd15633c36100e07b06a5",
|
|
1735
|
+
"w": 128
|
|
1736
|
+
},
|
|
1737
|
+
{
|
|
1738
|
+
"bytes": 7500,
|
|
1739
|
+
"h": 140,
|
|
1740
|
+
"path": "webp/floral-frame-192.webp",
|
|
1741
|
+
"sha256": "d35a388cf3a933858b2a384daee118f25b550415f47d382a3fff3b2c2b8e92ad",
|
|
1742
|
+
"w": 192
|
|
1743
|
+
},
|
|
1744
|
+
{
|
|
1745
|
+
"bytes": 11794,
|
|
1746
|
+
"h": 187,
|
|
1747
|
+
"path": "webp/floral-frame-256.webp",
|
|
1748
|
+
"sha256": "0bf57533e9aa36654c21c88bcb5bcc2e80bdd759deb8743a211ba5ba99a8a626",
|
|
1749
|
+
"w": 256
|
|
1750
|
+
},
|
|
1751
|
+
{
|
|
1752
|
+
"bytes": 24018,
|
|
1753
|
+
"h": 281,
|
|
1754
|
+
"path": "webp/floral-frame-384.webp",
|
|
1755
|
+
"sha256": "9b3c131e3b52a6afba33d73d2ac0cd01a7409bd2aa6dda4606d4b9de8dafe4ba",
|
|
1756
|
+
"w": 384
|
|
1757
|
+
},
|
|
1758
|
+
{
|
|
1759
|
+
"bytes": 40394,
|
|
1760
|
+
"h": 375,
|
|
1761
|
+
"path": "webp/floral-frame-512.webp",
|
|
1762
|
+
"sha256": "a1dfc972b693b9044f3ef8a5f474b4748d591eded2352728f42131b7ab875b9b",
|
|
1763
|
+
"w": 512
|
|
1764
|
+
},
|
|
1765
|
+
{
|
|
1766
|
+
"bytes": 86810,
|
|
1767
|
+
"h": 562,
|
|
1768
|
+
"path": "webp/floral-frame-768.webp",
|
|
1769
|
+
"sha256": "8b145b35855340bd7832ecd6678bb80e66881107615fdf3ab52056d0d5372007",
|
|
1770
|
+
"w": 768
|
|
1771
|
+
},
|
|
1772
|
+
{
|
|
1773
|
+
"bytes": 149138,
|
|
1774
|
+
"h": 749,
|
|
1775
|
+
"path": "webp/floral-frame-1024.webp",
|
|
1776
|
+
"sha256": "d7df608371aa5c2867fe9865476fc0b298df1e879eab26ea1d829d80dfe7c38f",
|
|
1777
|
+
"w": 1024
|
|
1778
|
+
},
|
|
1779
|
+
{
|
|
1780
|
+
"bytes": 253534,
|
|
1781
|
+
"h": 1000,
|
|
1782
|
+
"path": "webp/floral-frame-1367.webp",
|
|
1783
|
+
"sha256": "6b5ab7b0e09d23ca755215b129ce5db77eec3276a746e02bf16f3daef73a78aa",
|
|
1784
|
+
"w": 1367
|
|
1785
|
+
}
|
|
1786
|
+
]
|
|
1787
|
+
},
|
|
1788
|
+
"slice": {
|
|
1789
|
+
"bottom": 14.6,
|
|
1790
|
+
"left": 10.68,
|
|
1791
|
+
"right": 10.68,
|
|
1792
|
+
"top": 14.6
|
|
1793
|
+
},
|
|
1794
|
+
"slicePx": 146
|
|
1795
|
+
},
|
|
1641
1796
|
"image": {}
|
|
1642
1797
|
},
|
|
1643
1798
|
"resolutionLimited": false,
|
|
1644
1799
|
"sources": {
|
|
1645
1800
|
"avif": [
|
|
1646
1801
|
{
|
|
1647
|
-
"bytes":
|
|
1648
|
-
"h":
|
|
1802
|
+
"bytes": 1266,
|
|
1803
|
+
"h": 47,
|
|
1649
1804
|
"path": "avif/floral-frame-64.avif",
|
|
1650
|
-
"sha256": "
|
|
1805
|
+
"sha256": "c72f1029d3833b35d60254852e6257a043b24c9a75ac91eecfd396a5e5af43b7",
|
|
1651
1806
|
"w": 64
|
|
1652
1807
|
},
|
|
1653
1808
|
{
|
|
1654
|
-
"bytes":
|
|
1655
|
-
"h":
|
|
1809
|
+
"bytes": 2051,
|
|
1810
|
+
"h": 70,
|
|
1656
1811
|
"path": "avif/floral-frame-96.avif",
|
|
1657
|
-
"sha256": "
|
|
1812
|
+
"sha256": "2bcefa81cc582bb986977cc8941de86f9bc6197e2563a737a2ad868a3347ebc3",
|
|
1658
1813
|
"w": 96
|
|
1659
1814
|
},
|
|
1660
1815
|
{
|
|
1661
|
-
"bytes":
|
|
1662
|
-
"h":
|
|
1816
|
+
"bytes": 3351,
|
|
1817
|
+
"h": 94,
|
|
1663
1818
|
"path": "avif/floral-frame-128.avif",
|
|
1664
|
-
"sha256": "
|
|
1819
|
+
"sha256": "afd8bede3261bd6dcadae68c8633aa039a3e4181e1b76685fba3243f398a1b2f",
|
|
1665
1820
|
"w": 128
|
|
1666
1821
|
},
|
|
1667
1822
|
{
|
|
1668
|
-
"bytes":
|
|
1669
|
-
"h":
|
|
1823
|
+
"bytes": 5052,
|
|
1824
|
+
"h": 140,
|
|
1670
1825
|
"path": "avif/floral-frame-192.avif",
|
|
1671
|
-
"sha256": "
|
|
1826
|
+
"sha256": "3eea02e31baf0c0059abf160f4a39e8bb5bf2abfc3fa426393820dec13eaeb42",
|
|
1672
1827
|
"w": 192
|
|
1673
1828
|
},
|
|
1674
1829
|
{
|
|
1675
|
-
"bytes":
|
|
1676
|
-
"h":
|
|
1830
|
+
"bytes": 6463,
|
|
1831
|
+
"h": 187,
|
|
1677
1832
|
"path": "avif/floral-frame-256.avif",
|
|
1678
|
-
"sha256": "
|
|
1833
|
+
"sha256": "9ed5eff121b2ee01a8bd0618862ae7fbc87f2a2def0d4f6c51618831445198f0",
|
|
1679
1834
|
"w": 256
|
|
1680
1835
|
},
|
|
1681
1836
|
{
|
|
1682
|
-
"bytes":
|
|
1683
|
-
"h":
|
|
1837
|
+
"bytes": 14881,
|
|
1838
|
+
"h": 281,
|
|
1684
1839
|
"path": "avif/floral-frame-384.avif",
|
|
1685
|
-
"sha256": "
|
|
1840
|
+
"sha256": "b47dea3d0c356555b3f31ba4979163c708f0d99e97cb4130976a78b3c2b98ffd",
|
|
1686
1841
|
"w": 384
|
|
1687
1842
|
},
|
|
1688
1843
|
{
|
|
1689
|
-
"bytes":
|
|
1690
|
-
"h":
|
|
1844
|
+
"bytes": 22279,
|
|
1845
|
+
"h": 375,
|
|
1691
1846
|
"path": "avif/floral-frame-512.avif",
|
|
1692
|
-
"sha256": "
|
|
1847
|
+
"sha256": "46a428b802180a9ae46501d80ba536d4b1d39661ba30ca7903c422fa74867806",
|
|
1693
1848
|
"w": 512
|
|
1694
1849
|
},
|
|
1695
1850
|
{
|
|
1696
|
-
"bytes":
|
|
1697
|
-
"h":
|
|
1851
|
+
"bytes": 47230,
|
|
1852
|
+
"h": 562,
|
|
1698
1853
|
"path": "avif/floral-frame-768.avif",
|
|
1699
|
-
"sha256": "
|
|
1854
|
+
"sha256": "c05fba96991132f3c998f5720acc0286c58287b0d2708272fb32108474b71b0c",
|
|
1700
1855
|
"w": 768
|
|
1701
1856
|
},
|
|
1702
1857
|
{
|
|
1703
|
-
"bytes":
|
|
1704
|
-
"h":
|
|
1858
|
+
"bytes": 77165,
|
|
1859
|
+
"h": 749,
|
|
1705
1860
|
"path": "avif/floral-frame-1024.avif",
|
|
1706
|
-
"sha256": "
|
|
1861
|
+
"sha256": "fc62c1b0da3651d995583d4e953641b96ebb8489da9b4eb95ca5231bb5b3d7ca",
|
|
1707
1862
|
"w": 1024
|
|
1708
1863
|
},
|
|
1709
1864
|
{
|
|
1710
|
-
"bytes":
|
|
1711
|
-
"h":
|
|
1712
|
-
"path": "avif/floral-frame-
|
|
1713
|
-
"sha256": "
|
|
1714
|
-
"w":
|
|
1865
|
+
"bytes": 130229,
|
|
1866
|
+
"h": 1000,
|
|
1867
|
+
"path": "avif/floral-frame-1367.avif",
|
|
1868
|
+
"sha256": "ecfc4fc9e19bdbf1547743c34c7004e34882b30f1f0f6b901d945e606fd7990a",
|
|
1869
|
+
"w": 1367
|
|
1715
1870
|
}
|
|
1716
1871
|
],
|
|
1717
1872
|
"webp": [
|
|
1718
1873
|
{
|
|
1719
|
-
"bytes":
|
|
1720
|
-
"h":
|
|
1874
|
+
"bytes": 1450,
|
|
1875
|
+
"h": 47,
|
|
1721
1876
|
"path": "webp/floral-frame-64.webp",
|
|
1722
|
-
"sha256": "
|
|
1877
|
+
"sha256": "cf65baff36575006905dbd4d2d3c1c0bf5a0205c26744c4e19f5ac1e298cac6b",
|
|
1723
1878
|
"w": 64
|
|
1724
1879
|
},
|
|
1725
1880
|
{
|
|
1726
|
-
"bytes":
|
|
1727
|
-
"h":
|
|
1881
|
+
"bytes": 2536,
|
|
1882
|
+
"h": 70,
|
|
1728
1883
|
"path": "webp/floral-frame-96.webp",
|
|
1729
|
-
"sha256": "
|
|
1884
|
+
"sha256": "4aea33bd0ec4a2e46bfcc87eb0c980343edae525585df734703921d2c51773d7",
|
|
1730
1885
|
"w": 96
|
|
1731
1886
|
},
|
|
1732
1887
|
{
|
|
1733
|
-
"bytes":
|
|
1734
|
-
"h":
|
|
1888
|
+
"bytes": 3774,
|
|
1889
|
+
"h": 94,
|
|
1735
1890
|
"path": "webp/floral-frame-128.webp",
|
|
1736
|
-
"sha256": "
|
|
1891
|
+
"sha256": "138e726aa0837da22de393d01707a5d72f412ebe66fbd15633c36100e07b06a5",
|
|
1737
1892
|
"w": 128
|
|
1738
1893
|
},
|
|
1739
1894
|
{
|
|
1740
|
-
"bytes":
|
|
1741
|
-
"h":
|
|
1895
|
+
"bytes": 7500,
|
|
1896
|
+
"h": 140,
|
|
1742
1897
|
"path": "webp/floral-frame-192.webp",
|
|
1743
|
-
"sha256": "
|
|
1898
|
+
"sha256": "d35a388cf3a933858b2a384daee118f25b550415f47d382a3fff3b2c2b8e92ad",
|
|
1744
1899
|
"w": 192
|
|
1745
1900
|
},
|
|
1746
1901
|
{
|
|
1747
|
-
"bytes":
|
|
1748
|
-
"h":
|
|
1902
|
+
"bytes": 11794,
|
|
1903
|
+
"h": 187,
|
|
1749
1904
|
"path": "webp/floral-frame-256.webp",
|
|
1750
|
-
"sha256": "
|
|
1905
|
+
"sha256": "0bf57533e9aa36654c21c88bcb5bcc2e80bdd759deb8743a211ba5ba99a8a626",
|
|
1751
1906
|
"w": 256
|
|
1752
1907
|
},
|
|
1753
1908
|
{
|
|
1754
|
-
"bytes":
|
|
1755
|
-
"h":
|
|
1909
|
+
"bytes": 24018,
|
|
1910
|
+
"h": 281,
|
|
1756
1911
|
"path": "webp/floral-frame-384.webp",
|
|
1757
|
-
"sha256": "
|
|
1912
|
+
"sha256": "9b3c131e3b52a6afba33d73d2ac0cd01a7409bd2aa6dda4606d4b9de8dafe4ba",
|
|
1758
1913
|
"w": 384
|
|
1759
1914
|
},
|
|
1760
1915
|
{
|
|
1761
|
-
"bytes":
|
|
1762
|
-
"h":
|
|
1916
|
+
"bytes": 40394,
|
|
1917
|
+
"h": 375,
|
|
1763
1918
|
"path": "webp/floral-frame-512.webp",
|
|
1764
|
-
"sha256": "
|
|
1919
|
+
"sha256": "a1dfc972b693b9044f3ef8a5f474b4748d591eded2352728f42131b7ab875b9b",
|
|
1765
1920
|
"w": 512
|
|
1766
1921
|
},
|
|
1767
1922
|
{
|
|
1768
|
-
"bytes":
|
|
1769
|
-
"h":
|
|
1923
|
+
"bytes": 86810,
|
|
1924
|
+
"h": 562,
|
|
1770
1925
|
"path": "webp/floral-frame-768.webp",
|
|
1771
|
-
"sha256": "
|
|
1926
|
+
"sha256": "8b145b35855340bd7832ecd6678bb80e66881107615fdf3ab52056d0d5372007",
|
|
1772
1927
|
"w": 768
|
|
1773
1928
|
},
|
|
1774
1929
|
{
|
|
1775
|
-
"bytes":
|
|
1776
|
-
"h":
|
|
1930
|
+
"bytes": 149138,
|
|
1931
|
+
"h": 749,
|
|
1777
1932
|
"path": "webp/floral-frame-1024.webp",
|
|
1778
|
-
"sha256": "
|
|
1933
|
+
"sha256": "d7df608371aa5c2867fe9865476fc0b298df1e879eab26ea1d829d80dfe7c38f",
|
|
1779
1934
|
"w": 1024
|
|
1780
1935
|
},
|
|
1781
1936
|
{
|
|
1782
|
-
"bytes":
|
|
1783
|
-
"h":
|
|
1784
|
-
"path": "webp/floral-frame-
|
|
1785
|
-
"sha256": "
|
|
1786
|
-
"w":
|
|
1937
|
+
"bytes": 253534,
|
|
1938
|
+
"h": 1000,
|
|
1939
|
+
"path": "webp/floral-frame-1367.webp",
|
|
1940
|
+
"sha256": "6b5ab7b0e09d23ca755215b129ce5db77eec3276a746e02bf16f3daef73a78aa",
|
|
1941
|
+
"w": 1367
|
|
1787
1942
|
}
|
|
1788
1943
|
]
|
|
1789
1944
|
},
|
|
@@ -1796,16 +1951,16 @@
|
|
|
1796
1951
|
"scroll",
|
|
1797
1952
|
"rule"
|
|
1798
1953
|
],
|
|
1799
|
-
"thumbhash": "
|
|
1954
|
+
"thumbhash": "W2qCBIA2V7logGAxW/p1o0+HjYx4+Gh4DA==",
|
|
1800
1955
|
"title": "Floral frame",
|
|
1801
1956
|
"transparent": true,
|
|
1802
1957
|
"type": "frame",
|
|
1803
1958
|
"usage_notes": [
|
|
1804
|
-
"
|
|
1805
|
-
"
|
|
1959
|
+
"Complete frame for CSS border-image: the build records the slice (146 px on the master, 10.68 % of the width and 14.6 % of the height) and the resolver's frame() returns the rule; the opening is transparent.",
|
|
1960
|
+
"Also fine as one proportionally scaled image with content in the opening.",
|
|
1806
1961
|
"ornate-inner-frame and the frame-growth corners share its palette."
|
|
1807
1962
|
],
|
|
1808
|
-
"width":
|
|
1963
|
+
"width": 1367
|
|
1809
1964
|
},
|
|
1810
1965
|
"frame": {
|
|
1811
1966
|
"categories": [
|
|
@@ -8018,10 +8173,11 @@
|
|
|
8018
8173
|
"width": 1024
|
|
8019
8174
|
}
|
|
8020
8175
|
},
|
|
8021
|
-
"
|
|
8022
|
-
"
|
|
8023
|
-
"
|
|
8024
|
-
"
|
|
8176
|
+
"attribution": "adrian729 (CC-BY-4.0)",
|
|
8177
|
+
"builtAt": "2026-10-27T17:07:49.118Z",
|
|
8178
|
+
"cdn": "https://cdn.jsdelivr.net/npm/@ranx729/ducktape-assets-illuminated-acanthus@2.0.0/",
|
|
8179
|
+
"contentHash": "sha256:a7a943d0ee38ad8981251f4e6b723f69a5638417b682595a863563941510a81c",
|
|
8180
|
+
"inputsHash": "sha256:d948d8c1a8cba53b2941c84c6fcc368e950daa7dba43fdc2841237cf24f19023",
|
|
8025
8181
|
"kind": "authored",
|
|
8026
8182
|
"license": {
|
|
8027
8183
|
"artwork": "CC-BY-4.0",
|
|
@@ -8042,5 +8198,5 @@
|
|
|
8042
8198
|
"sharp": "0.35.5",
|
|
8043
8199
|
"tools": "0.0.0"
|
|
8044
8200
|
},
|
|
8045
|
-
"version": "
|
|
8201
|
+
"version": "2.0.0"
|
|
8046
8202
|
}
|
package/src/copy.mjs
CHANGED
|
@@ -51,13 +51,27 @@ function chooseLadder(ladder, spec) {
|
|
|
51
51
|
|
|
52
52
|
/** What to copy for one asset, grouped by role. Masters come from the masters package. */
|
|
53
53
|
export function chooseFiles(asset, assetId, spec) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
// `masters: true` alone means "I encode my own images": only the master is copied. Add formats, widths or max to
|
|
55
|
+
// get ladder files as well.
|
|
56
|
+
const wantsLadder = !spec.masters || spec.formats || spec.widths || spec.max;
|
|
57
|
+
const ladderSpec = wantsLadder ? spec : { ...spec, formats: [] };
|
|
58
|
+
const roles = { sources: chooseLadder(asset.sources, ladderSpec) };
|
|
59
|
+
if (asset.render?.tile?.rotated) roles.rotated = chooseLadder(asset.render.tile.rotated, ladderSpec);
|
|
60
|
+
if (asset.render?.frame?.atlas) roles.atlas = chooseLadder(asset.render.frame.atlas, ladderSpec);
|
|
57
61
|
if (spec.masters) roles.master = { package: 'masters', ...(asset.master ?? { path: `masters/${assetId}.webp` }) };
|
|
58
62
|
return roles;
|
|
59
63
|
}
|
|
60
64
|
|
|
65
|
+
/** The authored geometry of an asset without the generated ladders: what a build script needs to place it. */
|
|
66
|
+
function geometryOf(asset) {
|
|
67
|
+
const r = asset.render ?? {};
|
|
68
|
+
const out = {};
|
|
69
|
+
if (r.image) out.image = {};
|
|
70
|
+
if (r.tile) out.tile = { axis: r.tile.axis, period: r.tile.period ?? 1 };
|
|
71
|
+
if (r.frame) out.frame = { slice: r.frame.slice, ...(r.frame.slicePx ? { slicePx: r.frame.slicePx } : {}), ...(r.frame.corner ? { corner: r.frame.corner } : {}) };
|
|
72
|
+
return out;
|
|
73
|
+
}
|
|
74
|
+
|
|
61
75
|
/**
|
|
62
76
|
* @param {object} o
|
|
63
77
|
* @param {{pin?: string, out?: string, assets: Array<string|object>}} o.config
|
|
@@ -88,14 +102,21 @@ export async function copy({ config, out, index, base, log = () => {} }) {
|
|
|
88
102
|
if (v.path) files[role] = place(v);
|
|
89
103
|
else files[role] = Object.fromEntries(Object.entries(v).map(([fmt, f]) => [fmt, Array.isArray(f) ? f.map(place) : place(f)]));
|
|
90
104
|
}
|
|
105
|
+
const master = asset.master ?? null;
|
|
91
106
|
summary[spec.id] = {
|
|
92
107
|
set: setId,
|
|
93
108
|
version: entry.version,
|
|
94
109
|
title: asset.title,
|
|
95
110
|
description: asset.description,
|
|
111
|
+
type: asset.type,
|
|
96
112
|
width: asset.width,
|
|
97
113
|
height: asset.height,
|
|
114
|
+
// The master may be capped below the native size; coordinates measured on it must say so.
|
|
115
|
+
...(master ? { master: { width: master.w, height: master.h } } : {}),
|
|
116
|
+
transparent: asset.transparent ?? null,
|
|
98
117
|
thumbhash: asset.thumbhash,
|
|
118
|
+
render: geometryOf(asset),
|
|
119
|
+
...(asset.components ? { components: Object.fromEntries(Object.entries(asset.components).map(([k, c]) => [k, { width: c.width, height: c.height, ...(c.description ? { description: c.description } : {}) }])) } : {}),
|
|
99
120
|
license: asset.license ?? manifest.license.artwork,
|
|
100
121
|
attribution: asset.attribution ?? manifest.attribution ?? '',
|
|
101
122
|
files,
|
package/src/generate.mjs
CHANGED
|
@@ -90,8 +90,18 @@ function table(list) {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
const FLOWS = `1. **Paste a URL.** Any HTML, CSS or Markdown references one file on jsDelivr, for example \`https://cdn.jsdelivr.net/npm/@ranx729/ducktape-assets-walters-w102@1.2.0/webp/rabbit-church-bells-512.webp\`. Only that file is transferred. \`catalog.json\` lists the exact URL of every width and format, so nothing has to be guessed.
|
|
93
|
-
2. **Pick and copy.** Keep a small \`ducktape.json\` listing the asset ids you want, with optional widths, formats and \`masters: true\`. \`npx @ranx729/ducktape-assets copy\` fetches exactly those files into the project (default \`src/assets/ducktape/\`), verifies every SHA-256 against the manifest, and writes \`ducktape.manifest.json\` beside them with dimensions, thumbhash, licence and attribution per asset. Re-running is idempotent.
|
|
94
|
-
3. **Resolve in code.** \`npm i @ranx729/ducktape-assets\` installs metadata and a resolver, zero images. \`assets.image(id, { width })\` returns \`src\`, \`srcset\`, \`sizes\`, width, height, thumbhash and
|
|
93
|
+
2. **Pick and copy.** Keep a small \`ducktape.json\` listing the asset ids you want, with optional widths, formats and \`masters: true\`. \`npx @ranx729/ducktape-assets copy\` fetches exactly those files into the project (default \`src/assets/ducktape/\`), verifies every SHA-256 against the manifest, and writes \`ducktape.manifest.json\` beside them with type, dimensions (native and of the capped master), transparency, render geometry (tile axis, frame slice), thumbhash, licence and attribution per asset. \`masters: true\` alone copies only the lossless master (for apps that encode their own images); add \`formats\`, \`widths\` or \`max\` to copy ladder files as well. Re-running is idempotent.
|
|
94
|
+
3. **Resolve in code.** \`npm i @ranx729/ducktape-assets\` installs metadata and a resolver, zero images. \`assets.image(id, { width })\` returns \`src\`, \`srcset\`, \`sizes\`, width, height, thumbhash, licence, \`attribution\`, and \`file\` / \`files\` (path, bytes and sha256 of every referenced rung, for scripts that record or verify what they use). Bytes come from the CDN at request time, or from flow 2 when \`base\` points at the copied directory.
|
|
95
|
+
|
|
96
|
+
Build-time recipe in Node, offline, no network:
|
|
97
|
+
|
|
98
|
+
\`\`\`js
|
|
99
|
+
import { createNodeResolver } from '@ranx729/ducktape-assets/node';
|
|
100
|
+
const assets = await createNodeResolver({ formats: ['webp'] });
|
|
101
|
+
const img = await assets.image('walters-w102/rabbit-church-bells', { width: 256, dpr: 1 });
|
|
102
|
+
// img.src is the smallest rung at or above 256 px (never upscaled); img.file.sha256 and img.file.bytes are the publisher's.
|
|
103
|
+
// For an exact 2x pick ask for width 512 with dpr 1; the default dpr 3 returns the whole range for a srcset.
|
|
104
|
+
\`\`\``;
|
|
95
105
|
|
|
96
106
|
const CONFIG = `\`\`\`json
|
|
97
107
|
{
|
package/src/node.mjs
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
// Node-only helpers. Kept apart so the resolver stays browser-safe.
|
|
2
2
|
import { readFile } from 'node:fs/promises';
|
|
3
3
|
import { dirname, join } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { createResolver } from './resolver.mjs';
|
|
4
6
|
|
|
5
7
|
/** loadManifest for createResolver: reads `sets/<set>.json` beside a local index.json. */
|
|
6
8
|
export function fsManifestLoader(indexPath) {
|
|
7
9
|
const dir = dirname(indexPath);
|
|
8
10
|
return async (setId) => JSON.parse(await readFile(join(dir, 'sets', `${setId}.json`), 'utf8'));
|
|
9
11
|
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* A resolver over the data shipped in this package (or a local copy of it), with no network at all:
|
|
15
|
+
* the index and every set manifest are read from disk, so build scripts work offline and get the same
|
|
16
|
+
* hashes and bytes the publisher recorded. Options are those of createResolver plus `indexPath`.
|
|
17
|
+
*/
|
|
18
|
+
export async function createNodeResolver({ indexPath = fileURLToPath(new URL('../index.json', import.meta.url)), ...options } = {}) {
|
|
19
|
+
const index = JSON.parse(await readFile(indexPath, 'utf8'));
|
|
20
|
+
return createResolver({ index, loadManifest: fsManifestLoader(indexPath), ...options });
|
|
21
|
+
}
|