1/** 2 * Shop listings â commerce overlay for garden works. 3 * Garden work remains canonical in garden-data.js (story, images, stage). 4 * 5 * Stripe setup: 6 * 1. Create a Product + Price in Stripe Dashboard (one-time payment). 7 * 2. Set STRIPE_SECRET_KEY in Netlify env. 8 * 3. Set stripePriceId below OR matching env var STRIPE_PRICE_<LISTING_ID>. 9 * 10 * @typedef {Object} ShopListing 11 * @property {string} id 12 * @property {string} gardenWorkId â matches garden-data.js work id 13 * @property {string} [stripePriceId] â Stripe Price ID (price_â¦) 14 * @property {string} [stripePriceEnv] â Netlify env var name fallback 15 * @property {number} [amountCents] â display + validation fallback 16 * @property {string} [currency] 17 * @property {string} [priceDisplay] â e.g. "$35.00" 18 * @property {string} [shopTitle] â override garden title on shop card 19 * @property {string} [shopSummary] â override garden summary on shop card 20 * @property {string} [shopImage] â override cover image on shop card 21 * @property {boolean} [comingSoon] â show placeholder, no checkout 22 * @property {string} [productType] â "physical" | "digital" 23 * @property {Object} [delivery] 24 * @property {string} delivery.type â "digital" | "physical" 25 * @property {string} [delivery.filePath] â path served after fulfillment (or direct free download URL path) 26 * @property {boolean} [freeDownload] â skip Stripe; link directly to delivery.filePath 27 * @property {string} [externalHref] â skip Stripe; link out (mailto:, tel:, or https) 28 * @property {string} [phoneHref] â optional tel: link shown under contact CTA 29 * @property {string} [phoneDisplay] â label for phoneHref 30 * @property {string} [organismId] â optional; Madeline shop ignores organism-scoped listings 31 * @property {boolean|Object} [homeNews] â legacy; homepage news is garden + events only (see home-news.js). 32 * Prefer putting news on the related garden work or calendar event with `newsCaption`. 33 */ 34 35/** Madeline Tasquin shop only â Artemisia / other organisms keep their own catalogs. */ 36const shopListings = [ 37 { 38 id: "future-sun-vinyl", 39 gardenWorkId: "future-sun-vinyl", 40 shopTitle: "Future / Sun Vinyl", 41 stripePriceId: null, 42 stripePriceEnv: "STRIPE_PRICE_FUTURE_SUN_VINYL", 43 amountCents: 3900, 44 currency: "usd", 45 priceDisplay: "$25â$54 (suggested $39)", 46 buyLabel: "Buy vinyl", 47 productType: "physical", 48 delivery: { type: "physical" }, 49 }, 50 { 51 id: "future-telephone-ep-digital", 52 gardenWorkId: "future-telephone-ep", 53 shopTitle: "Future Telephone (EP, 2017) â Digital Download", 54 stripePriceId: null, 55 stripePriceEnv: "STRIPE_PRICE_FUTURE_TELEPHONE_EP_DIGITAL", 56 amountCents: 888, 57 currency: "usd", 58 priceDisplay: "$8.88", 59 buyLabel: "Buy download", 60 productType: "digital", 61 delivery: { type: "digital" }, 62 }, 63 { 64 id: "atats-ep-digital", 65 gardenWorkId: "atats-ep", 66 shopTitle: "Another Trip Around the Sun (EP, 2012)", 67 stripePriceId: null, 68 stripePriceEnv: "STRIPE_PRICE_ATATS_EP_DIGITAL", 69 amountCents: 888, 70 currency: "usd", 71 priceDisplay: "$8.88", 72 buyLabel: "Buy download", 73 productType: "digital", 74 delivery: { type: "digital" }, 75 }, 76 { 77 id: "atats-title-track", 78 gardenWorkId: "atats-ep", 79 shopTitle: "Another Trip Around the Sun â title track", 80 stripePriceId: null, 81 // Checkout uses amountCents (Stripe Checkout USD minimum is $0.50) 82 amountCents: 50, 83 currency: "usd", 84 priceDisplay: "$0.50", 85 buyLabel: "Buy download", 86 productType: "digital", 87 delivery: { 88 type: "digital", 89 filePath: "audio/03_Another_Trip_Around_the_Sun.mp3", 90 }, 91 shopFeatured: true, 92 }, 93 { 94 id: "tell-the-ones-you-love", 95 gardenWorkId: "tell-the-ones-you-love", 96 shopTitle: "Tell the Ones You Love (single, 2025)", 97 stripePriceId: null, 98 stripePriceEnv: "STRIPE_PRICE_TELL_THE_ONES_YOU_LOVE", 99 amountCents: 333, 100 currency: "usd", 101 priceDisplay: "$3.33", 102 buyLabel: "Buy download", 103 productType: "digital", 104 delivery: { 105 type: "digital", 106 filePath: "audio/Tell_the_Ones_You_Love.mp3", 107 }, 108 }, 109 { 110 id: "dizzy", 111 gardenWorkId: "dizzy", 112 shopTitle: "Dizzy (single, 2019)", 113 stripePriceId: null, 114 stripePriceEnv: "STRIPE_PRICE_DIZZY", 115 amountCents: 333, 116 currency: "usd", 117 priceDisplay: "$3.33", 118 buyLabel: "Buy download", 119 productType: "digital", 120 delivery: { 121 type: "digital", 122 filePath: "audio/Dizzy_byMadelineTasquin.mp3", 123 }, 124 }, 125 { 126 id: "moon-the-sun-minizine-v1", 127 gardenWorkId: "moon-the-sun-minizine-v1", 128 stripePriceId: null, 129 // No Stripe Price product yet â checkout uses amountCents fallback if enabled 130 amountCents: 1200, 131 currency: "usd", 132 priceDisplay: "$12.00", 133 buyLabel: "Buy zine", 134 productType: "physical", 135 delivery: { type: "physical" }, 136 homeNews: { 137 enabled: true, 138 date: "2026-07-10", 139 title: "Moon the Sun minizine in the shop", 140 message: "A small printed guide to the network â available in the shop.", 141 url: "shop.html", 142 buttonText: "Visit the shop â", 143 }, 144 }, 145 { 146 id: "mighty-wave-tshirt", 147 gardenWorkId: "mighty-wave-tshirt", 148 comingSoon: true, 149 priceDisplay: "Custom â coming soon", 150 buyLabel: "Coming soon", 151 productType: "physical", 152 delivery: { type: "physical" }, 153 }, 154]; 155 156window.shopListings = shopListings;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.