domma-cms 1.8.29 → 1.8.31

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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.8.31] - 2026-10-20
4
+
5
+ - Add `pdfjs-dist` and `pdf-lib` as optional dependencies, for the Docs Tool's PDF documents (Docs 2.13: a PDF kept as it is, searchable inside, shown in the browser's viewer) and Docs Pro's PDF signing and PDF tools (0.10 and 0.11: boxes placed on the pages, forms filled in, marks drawn, pages turned, removed, reordered, taken out and merged). A server without them still runs Docs; those features say so and stand aside.
6
+
7
+ ## [1.8.30] - 2026-10-20
8
+
9
+ - Redraw the St George's Day castle and 26 seasonal details across the patron saints, Halloween and Valentine's Day celebrations. The CMS renderer uses the same shaded flowers, grouped plants, heritage props and characters as [domma-celebrate 1.5.0](https://github.com/pinpointzero73/domma-celebrate/releases/tag/v1.5.0).
10
+ - Start background particles throughout all four Patron Saints' Day scenes, retaining their gentle horizontal drift.
11
+ - Update [Domma JS to 0.53.3](https://github.com/pinpointzero73/domma/releases/tag/v0.53.3) for the celebration artwork release.
12
+
3
13
  ## [1.8.29] - 2026-10-19
4
14
 
5
15
  - Let site CSS and inline styles customise primary, outline and ghost buttons without fighting forced background, text and border colours, including hover states.
@@ -1,9 +1,9 @@
1
1
  /*!
2
- * Domma Tools CSS v0.53.2
2
+ * Domma Tools CSS v0.53.3
3
3
  * Dynamic Object Manipulation & Modeling API
4
4
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5
- * Built: 2026-10-17T11:26:13.841Z
6
- * Commit: ddc1a73
5
+ * Built: 2026-10-20T12:40:09.300Z
6
+ * Commit: f2ce209
7
7
  */
8
8
 
9
9
  /*!
@@ -1,9 +1,9 @@
1
1
  /*!
2
- * Domma Tools v0.53.2
2
+ * Domma Tools v0.53.3
3
3
  * Developer tools: Theme Roller & Page Roller
4
4
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5
- * Built: 2026-10-17T11:25:58.681Z
6
- * Commit: ddc1a73
5
+ * Built: 2026-10-20T12:39:56.638Z
6
+ * Commit: f2ce209
7
7
  *
8
8
  * Requires: domma.min.js
9
9
  */
@@ -39,8 +39,8 @@ Code was treated as the truth. Where docs disagree with it, the disagreement is
39
39
  | `campaigns-pro` | paid | 1.0.2 | Marketing campaigns, one paid Tool: compose a message, send it to an audience imported from Contacts (shared with Surveys), schedule sends, attach an offer that closes by a date or a claim limit. Opens and clicks (cookieless), links tagged for Analytics, a linked Shop discount code, send a survey as a campaign, follow-up sequences, resend to non-openers, A/B subject tests, and a version-1 stats feed other Tools read. |
40
40
  | `contacts-pro` | paid | 0.12.0 | Contacts, with more to them: your own custom fields, birthdays and ages with the ones coming up and a reminder in the sidebar, and groups with their own emblem and colours. Share a contact, several, or a whole group with people or roles - to view, or to edit. Call a contact now on a video call on your site. Works over the same contacts as the built-in Tool, so nothing moves and nothing is lost. |
41
41
  | `data-transfer` | paid | 1.3.3 | Move collections between file and MongoDB storage, back them up and restore them (all or some, merged or replaced) - keeping every entry's id - and clone them (cloned entries get new ids, so references stay unambiguous). Every restore and transfer takes a safety snapshot first. |
42
- | `docs` | paid | 2.8.1 | Document editor: Home and editor screens, sharing with Viewers/Editors, public links, import/export, send to page/blog/email, edit lock, Trash, version history, templates. |
43
- | `docs-pro` | paid | 0.8.1 | Domma Spaces (publish a Docs folder at `/spaces` with a Kindle-style reader), Cloud copies (Google Drive, OneDrive, Dropbox, S3), Signatures (emailed signing links, typed or drawn, signed copy with a certificate page) and protected public links (expiry date, password). Adds to Docs. |
42
+ | `docs` | paid | 2.13.1 | Document editor: Home and editor screens, sharing with Viewers/Editors, public links, import/export, send to page/blog/email, edit lock, Trash, version history, templates. PDF documents (2.13): a PDF kept as it is, shown in the browser's viewer, searchable inside, versioned on replace. |
43
+ | `docs-pro` | paid | 0.11.0 | Domma Spaces (publish a Docs folder at `/spaces` with a Kindle-style reader), Cloud copies (Google Drive, OneDrive, Dropbox, S3), Signatures (emailed signing links, typed or drawn, signed copy with a certificate page; 0.10: boxes placed on a PDF document's pages, the signed PDF stamped with pdf-lib), PDF tools (0.11: fill the PDF's own form, annotate, pages) and protected public links (expiry date, password). Adds to Docs. |
44
44
  | `email-pro` | paid | 0.9.0 | Full mail: read, write, send and search, over a synchronised store. Search, threads, rules, scheduled sends, snooze and vacation replies need MongoDB; without it, reading, filing and sending still work. |
45
45
  | `feedback` | free | 1.1.4 | Tell Domma what is broken, missing or good - straight from your admin - and see what became of it: seen, planned, in progress, done, with Domma's reply. |
46
46
  | `garage` | paid | 1.4.3 | UK vehicle management with DVLA API lookup, save vehicles, and search history. |
@@ -1842,7 +1842,7 @@ A safe way to move collections between file storage and MongoDB, take backups, r
1842
1842
 
1843
1843
  ### Docs (`docs`)
1844
1844
 
1845
- Tier: paid (closed source) · Version: 2.6.0 · Requires: no MongoDB (documents are JSON files under the plugin's `data/`); no `minCmsVersion` declared · Uses: `blog` (Send to a new blog post)
1845
+ Tier: paid (closed source) · Version: 2.13.1 · Requires: no MongoDB (documents are JSON files under the plugin's `data/`, PDF files beside them); optional `pdfjs-dist` (CMS optionalDependency) to read the text inside PDFs; no `minCmsVersion` declared · Uses: `blog` (Send to a new blog post)
1846
1846
 
1847
1847
  A document editor inside the admin. Documents are private until shared: share with people as Viewers or Editors, or publish a read-only public link. Import and export Markdown, HTML and text, print to PDF, and send a document on as a draft page, a draft blog post or an email. One person edits at a time; everyone else reads and sees who is editing.
1848
1848
 
@@ -1867,6 +1867,7 @@ A document editor inside the admin. Documents are private until shared: share wi
1867
1867
  - Saving a document accepts up to 5 MB (2.4.0) - documents with built-in pictures were refused at Fastify's 1 MB default.
1868
1868
  - **Suggester** share role (2.5.0, with Docs Pro): reads and suggests changes; without Docs Pro a Suggester is a Viewer. Pending suggestions are kept out of the public link, downloads, print, email and Send to by Docs itself; editors may take over editing from a Suggester.
1869
1869
  - Ready-made templates from an add-on (2.6.0) are listed in Templates after your own, marked with their category, read only.
1870
+ - **PDF documents** (2.13.0): New > Upload a PDF, Import or drop - up to 20 MB, kept whole (never rewritten) and shown in the browser's own PDF viewer; the text inside is read (pdfjs-dist, in a worker with a time budget) for search and the card excerpt; a PDF with JavaScript, Launch actions, attached files, rich media or XFA is refused with the reason, looking inside its compressed streams too. Shared, starred, filed, linked (the public page frames the PDF, Download PDF), emailed (attached), copied and trashed like any document; **Replace the PDF…** keeps the old file in Version history (download or restore). Add-ons declare the document kinds they understand (`kinds`, default HTML only).
1870
1871
  - `contentPaths: ["data"]` - documents are carried across plugin updates.
1871
1872
 
1872
1873
  **Where:** Admin sidebar "Docs" (book-open icon) -> `#/plugins/docs`; documents at `#/plugins/docs/d/<id>`; public links at `/docs/s/<token>`; settings under the banner cog; guide under **Documentation > Plugins > Docs**.
@@ -1891,7 +1892,7 @@ Tier: paid (closed source) · Version: 0.8.0 · Requires: `docs` 2.6+ (2.8+ for
1891
1892
 
1892
1893
  - **Cloud copies** (0.2.0): copies of your own documents (one folder and its folders, or all; never Trash) in **Google Drive** (scope `drive.file` - only its own files), **OneDrive** (its own app folder, `Files.ReadWrite.AppFolder`), **Dropbox** (App folder) or **S3 / S3-compatible** (Amazon S3, Cloudflare R2, Backblaze B2, Wasabi, MinIO; own SigV4 signing, no SDK) as Markdown, HTML, text and/or PDF, in folders matching your Docs folders under a folder you name. **Every save** (90 s after you stop editing), **Nightly** (after 2am, what changed) or **By hand**; unchanged documents are not sent again; copies stay when a document is trashed or deleted. Each customer makes their own app with the provider - a step-by-step guide per provider in the form, with the site's exact redirect address and a Copy button; Connect opens a sign-in window. Secrets encrypted at rest (AES-256-GCM keyed from JWT_SECRET), never sent back (Saved / last 4 of a key). Cards with state, what/as/when/where, Copy now, Test, See why; menu: Copy everything again, Connect again, Settings, Switch off, Remove. Editor chip ("Copied to Drive 10:42" / failed) and **Copy to the cloud now**. Failures notify the owner (source `docs-pro:cloud`), resolved when copying works again. Permission `cloud.use`, granted to `admin`.
1893
1894
 
1894
- - **Signatures** (0.3.0): **Request signatures…** on a document's menu - people (name + email, up to 20), optional signing order, message, deadline (7-90 days). The document is frozen with a SHA-256 fingerprint. Each signer is emailed their own link (in turn when ordered) to `/docs/sign/<token>`: the document, consent to sign electronically, typed or drawn signature, or decline with a reason. When everyone has signed, the signed copy - document, signatures and a certificate page (who, when, IP, browser, fingerprints, the full record) - is emailed to everyone as a PDF (web page when the server has no Chrome). **Signatures** place: each request's state, signers, Remind (once an hour each), Cancel, downloads, record. Editor chip ("Signed by 1 of 2"). Notifications to the sender (source `docs-pro:signing`). Needs the site's SMTP; a simple electronic signature (not for deeds/wills). Permission `signing.send`, granted to `admin`.
1895
+ - **Signatures** (0.3.0): **Request signatures…** on a document's menu - people (name + email, up to 20), optional signing order, message, deadline (7-90 days). The document is frozen with a SHA-256 fingerprint. Each signer is emailed their own link (in turn when ordered) to `/docs/sign/<token>`: the document, consent to sign electronically, typed or drawn signature, or decline with a reason. When everyone has signed, the signed copy - document, signatures and a certificate page (who, when, IP, browser, fingerprints, the full record) - is emailed to everyone as a PDF (web page when the server has no Chrome). **Signatures** place: each request's state, signers, Remind (once an hour each), Cancel, downloads, record. Editor chip ("Signed by 1 of 2"). Notifications to the sender (source `docs-pro:signing`). Needs the site's SMTP; a simple electronic signature (not for deeds/wills). Permission `signing.send`, granted to `admin`. **Signing a PDF** (0.10.0, Docs 2.13): the sender places Signature / Initials / Date / Name / Text boxes on the pages (a modal drawing them with pdf.js, served from the CMS's own copy at `/docs-pro/pdfjs/`), the file is frozen beside the request, the signer's page draws the pages with their boxes and their mark goes into every box; the signed PDF is the file with every box drawn in by pdf-lib (optional CMS dependency) plus a certificate page - no web-page copy. Spaces, Word, comments, suggestions and merge fields do not apply to PDF documents; cloud copies send the file. **PDF tools** (0.11.0): in a PDF document's menu - Fill in the form (the PDF's own AcroForm: text, ticks, choices; from a contact; Save and lock flattens), Annotate (text, date, tick, cross, highlight, stamp, picture, drawing placed on the pages), Pages (turn, remove, reorder), Take pages out (a new document), Add another PDF (merge) - every change a new version in Docs' History.
1895
1896
  - **Protected links** (0.3.0): an expiry date (the whole day counts) and/or a password (scrypt) on a document's public link, set in its Share panel. Expired -> a clear 410 page; password -> a form, then a 12-hour cookie for that link only; a new password asks everyone again; downloads are gated too. Kept with the document across new link addresses.
1896
1897
  - **Word files** (0.4.0): `.docx` in New > Import and drag-and-drop (15 MB) - headings, alignment, bold/italic/underline/strike, super/subscript, highlight, links, nested lists with numbering that carries on, quotes, code, tables with merged cells, pictures (PNG/JPEG/GIF to the Media library as `doc-…`, or up to 2 MB built in without Media rights); tracked changes accepted. **Download as Word (.docx)** on Home's and the editor's document menu. Own zip and XML code (no dependencies); hostile files capped per part, by node count and one import at a time; output validated against the Office 2019 schema.
1897
1898
  - **Merge fields** (0.4.0): **Insert a field** (contact name, first name, company, job title, email, phone, address, website, reference, today's date, your own `{{field}}`) and **Fill in the fields…** - search your Contacts or type values; makes a filled-in copy of your own (the original keeps its fields); values escaped, fields in the title too. A template with fields asks for them as soon as it is used and fills the new document in place.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domma-cms",
3
- "version": "1.8.29",
3
+ "version": "1.8.31",
4
4
  "description": "File-based CMS powered by Domma and Fastify. Run npx domma-cms my-site to create a new project.",
5
5
  "type": "module",
6
6
  "main": "server/server.js",
@@ -84,7 +84,7 @@
84
84
  "@fastify/rate-limit": "^10.3.0",
85
85
  "@fastify/static": "9.1.1",
86
86
  "bcryptjs": "^3.0.3",
87
- "domma-js": "0.53.2",
87
+ "domma-js": "0.53.3",
88
88
  "dotenv": "^17.2.3",
89
89
  "fastify": "5.8.5",
90
90
  "gray-matter": "^4.0.3",
@@ -98,6 +98,8 @@
98
98
  },
99
99
  "optionalDependencies": {
100
100
  "mongodb": "^6.21.0",
101
+ "pdf-lib": "^1.17.1",
102
+ "pdfjs-dist": "^6.4.299",
101
103
  "puppeteer-core": "^25.11.0"
102
104
  },
103
105
  "devDependencies": {
@@ -0,0 +1 @@
1
+ import{path as l,ellipse as T,gradient as d}from"./christmas-drawing.js";import{beginIllustration as u,line as f,leaf as t}from"./illustration-utils.js";function h(e,o,r=!1,a=1){const i=o?"#b7a28d":"#7f3046",s=o?["#fff9e8","#e2d6c0"]:["#d55b6a","#982c48"];for(let n=0;n<3;n++){const m=a*(1-n*.27);e.save(),e.scale(m,m),e.rotate(n*.6);for(let v=0;v<5;v++){e.save(),e.rotate(v*Math.PI*2/5);const b=r&&n===1;l(e,[["moveTo",0,.19],["bezierCurveTo",-.71,-.15,-.78,-.78,-.25,-.92],["quadraticCurveTo",0,-1.1,.25,-.92],["bezierCurveTo",.78,-.78,.71,-.15,0,.19],["closePath"]],d(e,-1,.2,b?["#fff5dc","#d8c9ac"]:s),b?"#b4a88d":i,.025),f(e,[["moveTo",-.46,-.62],["quadraticCurveTo",-.26,-.83,.02,-.76]],b||o?"#fffdf0":"#ee9290",.027),e.restore()}e.restore()}T(e,0,0,.14,.14,"#b98a42");for(let n=0;n<9;n++)T(e,Math.cos(n*2.4)*.09,Math.sin(n*2.4)*.09,.025,.025,"#f6d887")}export function drawEnglishRose(e,o,r=0){u(e,o)&&(f(e,[["moveTo",0,.1],["bezierCurveTo",-.25,.5,.1,1.1,0,1.55]],"#436448",.075),t(e,-.04,.95,-.85,.65),t(e,-.05,1.15,.9,.55),h(e,o.color?.toLowerCase()==="#ffffff",!1,.83+Math.sin(r*.002+(o.bloomPhase||0))*.035),e.restore())}export function drawTudorRose(e,o){if(u(e,o)){for(let r=0;r<5;r++)t(e,0,0,r*Math.PI*2/5+.63,1.1,"#45674d");h(e,!1,!0),e.restore()}}function C(e,o=["#8f639a","#b286b5","#e4b9d9"]){T(e,0,.14,.32,.36,d(e,-.2,.5,["#789073","#3d6257"]));for(let r=0;r<3;r++)for(let a=-2;a<=2;a++){const i=a*.11+r%2*.04,s=r*.13;f(e,[["moveTo",i,s+.12],["lineTo",i-.09,s-.09],["lineTo",i-.16,s-.12]],"#a5b28a",.018)}for(let r=0;r<27;r++){const a=(r/26-.5)*.62,i=-.5-Math.sin(r*1.9)*.065;f(e,[["moveTo",a*.8,-.04],["quadraticCurveTo",a*1.15,-.28,a,i]],o[r%o.length],.024)}}export function drawThistle(e,o){if(u(e,o)){f(e,[["moveTo",0,1.9],["quadraticCurveTo",.14,1,0,.35]],"#536e55",.055),t(e,.025,1.25,.9,.7),t(e,.035,1.6,-.9,.65);for(const r of[-1,1])f(e,[["moveTo",r*.1,1.18],["lineTo",r*.45,.82],["lineTo",r*.35,1.08],["lineTo",r*.57,1.03]],"#6e8765",.025);C(e,o.petalColors),e.restore()}}export function drawThistlePlant(e,o,r=0){if(u(e,o)){e.rotate(Math.sin(r*.001+(o.swayPhase||0))*.04);for(let a=-1;a<=1;a++){const i=a*.55,s=-1.55-(a===0?.35:0);f(e,[["moveTo",0,0],["quadraticCurveTo",i*.8,-.8,i,s]],"#57765b",.045),t(e,i*.6,-.7,a<=0?-1:1,.7),e.save(),e.translate(i,s),e.scale(.8,.8),C(e),e.restore()}e.restore()}}export function drawHeather(e,o){if(!u(e,o))return;e.rotate(Math.sin(o.sway||0)*.1),f(e,[["moveTo",.08,.8],["quadraticCurveTo",-.1,0,.05,-.9]],"#617258",.035);const r=o.bellCount||7;for(let a=0;a<r;a++){const i=a%2?-1:1,s=-.8+a*1.25/r;f(e,[["moveTo",0,s+.08],["lineTo",i*.18,s]],"#6b7b5d",.022),e.save(),e.translate(i*.18,s),e.rotate(-i*.25),l(e,[["moveTo",-.07,-.09],["quadraticCurveTo",-.18,-.04,-.14,.17],["quadraticCurveTo",0,.24,.14,.17],["quadraticCurveTo",.18,-.04,.07,-.09],["closePath"]],d(e,-.1,.2,["#d2a4c1",o.color||"#95649a"]),"#855582",.016),T(e,0,.17,.1,.025,"#714a75"),f(e,[["moveTo",-.045,.18],["lineTo",-.025,.24]],"#e6caac",.018),e.restore(),t(e,0,s+.2,i*.85,.24,"#6e8765")}e.restore()}function y(e){for(let o=0;o<6;o++)e.save(),e.rotate(o*Math.PI/3),l(e,[["moveTo",0,.1],["quadraticCurveTo",-.62,-.36,-.22,-.97],["lineTo",0,-1.13],["quadraticCurveTo",.64,-.72,0,.1],["closePath"]],d(e,-1.1,0,["#fff1a0","#e6b745"]),"#c8973b",.018),f(e,[["moveTo",0,-.19],["lineTo",-.03,-.89]],"#fff5b0",.027),e.restore();l(e,[["moveTo",-.21,-.17],["lineTo",-.3,.16],["quadraticCurveTo",0,.39,.3,.16],["lineTo",.21,-.17],["closePath"]],"#dfa339","#c58a31",.025),T(e,0,-.14,.26,.18,"#f7cc61"),T(e,0,-.13,.17,.11,"#aa6a27");for(let o=-1;o<=1;o++)f(e,[["moveTo",o*.05,-.1],["lineTo",o*.07,-.2]],"#f7d282",.018)}export function drawDaffodil(e,o){u(e,o)&&(f(e,[["moveTo",0,1.6],["quadraticCurveTo",.12,.6,0,0]],"#58754e",.065),t(e,0,1.5,-.35,1.05,"#67865a"),y(e),e.restore())}export function drawDaffodilField(e,o,r=0){if([o.x,o.y].every(Number.isFinite)){e.save(),e.globalAlpha*=o.opacity??1;for(const a of o.flowers||[]){if(!Number.isFinite(a.size)||a.size<=0)continue;const i=o.x+a.x,s=o.y-a.y,n=Math.sin(r*.001+(a.swayPhase||0))*.08;e.save(),e.translate(i,s),e.rotate(n),drawDaffodil(e,{x:0,y:-a.size*1.55,size:a.size,opacity:1}),e.restore()}e.restore()}}function q(e){for(let o=-2;o<=2;o++){const r=o*.27;l(e,[["moveTo",-.12,.95],["quadraticCurveTo",r*.6,-.1,r,-.97+Math.abs(o)*.13],["quadraticCurveTo",r+.3,-.55,.14,1],["closePath"]],d(e,-1,1.2,[o%2?"#6e9271":"#3b6e5c","#94ad86","#efe9cd"]),"#64866c",.015),f(e,[["moveTo",0,.9],["quadraticCurveTo",r*.75,-.1,r+.025,-.7]],"#b5c5a0",.013)}l(e,[["moveTo",-.14,.6],["lineTo",-.19,1.28],["quadraticCurveTo",0,1.43,.19,1.28],["lineTo",.14,.6],["closePath"]],d(e,.6,1.4,["#c6d0af","#fff6de"]),"#b8ba9c",.018);for(let o=-2;o<=2;o++)f(e,[["moveTo",o*.055,1.32],["quadraticCurveTo",o*.08,1.48,o*.11+.035,1.57]],"#b7a78b",.015)}export function drawLeek(e,o){u(e,o)&&(q(e),e.restore())}export function drawLeekBundle(e,o){if(u(e,o)){for(const r of[-2,2,-1,1,0])e.save(),e.translate(r*.17,-.05),e.rotate(r*.14),e.scale(.7,.7),q(e),e.restore();l(e,[["moveTo",-.49,.4],["quadraticCurveTo",0,.55,.49,.4],["lineTo",.46,.56],["quadraticCurveTo",0,.68,-.46,.56],["closePath"]],"#ae4650","#793541",.025);for(const r of[-1,1])l(e,[["moveTo",0,.5],["bezierCurveTo",r*.7,.1,r*.7,.8,0,.5],["closePath"]],"#cf6770","#873c4c",.025);T(e,0,.5,.09,.1,"#e49b8b"),e.restore()}}
@@ -1 +1 @@
1
- import{drawBat as b,drawGhost as R,drawPumpkin as I,drawJackOLantern as C,drawHauntedHouse as A,drawScarecrow as L}from"./halloween-drawing.js";export default{name:"halloween",displayName:"Halloween",emoji:"\u{1F383}",intensityConfig:{light:{count:30,speedRange:[.3,1],sizeRange:[2,5],gravestones:3,jackOLanterns:2,spiders:2,scarecrows:1,twinklingStars:8},medium:{count:60,speedRange:[.5,1.5],sizeRange:[2,6],gravestones:5,jackOLanterns:4,spiders:4,scarecrows:2,twinklingStars:15},heavy:{count:100,speedRange:[.7,2],sizeRange:[3,8],gravestones:8,jackOLanterns:6,spiders:6,scarecrows:3,twinklingStars:25}},particles:["bat","ghost","pumpkin"],decorations:["gravestone","jack-o-lantern","haunted-house","cauldron","spider","scarecrow","twinkling-star"],colors:{primary:"#ff6600",secondary:"#1a1a2e",accent:"#8b0000",ghost:"#f0f0f0",purple:"#6a0dad"},lightningChance:5e-4,lightningDuration:200,lightningTimer:0,lightningActive:!1,lightningColor:"#fefefe",createBat(e,t,o){const r=Math.random();let n,a,i;r<.33?(n=o.sizeRange[0]+Math.random()*(o.sizeRange[1]-o.sizeRange[0])*1.5,a=o.speedRange[0]+Math.random()*(o.speedRange[1]-o.speedRange[0])*1.3,i=.9+Math.random()*.1):r<.66?(n=o.sizeRange[0]+Math.random()*(o.sizeRange[1]-o.sizeRange[0]),a=o.speedRange[0]+Math.random()*(o.speedRange[1]-o.sizeRange[0]),i=.6+Math.random()*.2):(n=o.sizeRange[0]+Math.random()*(o.sizeRange[1]-o.sizeRange[0])*.7,a=o.speedRange[0]+Math.random()*(o.sizeRange[1]-o.sizeRange[0])*.7,i=.4+Math.random()*.2);const s=Math.random()<.5;return{type:"bat",x:s?-20:e+20,y:Math.random()*t*.7,baseY:Math.random()*t*.7,vx:s?a*2:-a*2,vy:0,size:n,speed:a,opacity:i,waveAmplitude:10+Math.random()*20,waveFrequency:.002+Math.random()*.003,waveOffset:Math.random()*Math.PI*2,time:0,rotation:0,active:!0,depth:r}},createGhost(e,t,o){const r=Math.random();let n,a,i;return r<.33?(n=o.sizeRange[0]+Math.random()*(o.sizeRange[1]-o.sizeRange[0])*1.8,a=o.speedRange[0]+Math.random()*(o.speedRange[1]-o.sizeRange[0])*.5,i=.7+Math.random()*.2):r<.66?(n=o.sizeRange[0]+Math.random()*(o.sizeRange[1]-o.sizeRange[0])*1.2,a=o.speedRange[0]+Math.random()*(o.sizeRange[1]-o.sizeRange[0])*.5,i=.5+Math.random()*.15):(n=o.sizeRange[0]+Math.random()*(o.sizeRange[1]-o.sizeRange[0]),a=o.speedRange[0]+Math.random()*(o.sizeRange[1]-o.sizeRange[0])*.5,i=.3+Math.random()*.15),{type:"ghost",x:Math.random()*e,y:-50,size:n,speed:a,opacity:i,windOffset:Math.random()*Math.PI*2,windSpeed:.01+Math.random()*.02,rotation:0,rotationSpeed:(Math.random()-.5)*.005,time:Math.random()*1e3,active:!0,depth:r}},createPumpkin(e,t,o){return{type:"pumpkin",x:Math.random()*e,y:Math.random()*t,size:o.sizeRange[0]+Math.random()*(o.sizeRange[1]-o.sizeRange[0]),vx:(Math.random()-.5)*.2,speed:(o.speedRange[0]+Math.random()*(o.speedRange[1]-o.sizeRange[0]))*.2,opacity:.8+Math.random()*.2,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.008,windOffset:Math.random()*Math.PI*2,windSpeed:.008+Math.random()*.015,glowPhase:Math.random()*Math.PI*2,floatPhase:Math.random()*Math.PI*2,floatSpeed:.001+Math.random()*.002,active:!0}},createGravestone(e,t,o={}){const r=["rounded","cross","obelisk"];return{type:"gravestone",x:o.x!==void 0?o.x:Math.random()*e,y:o.y!==void 0?o.y:t-30-Math.random()*20,size:15+Math.random()*10,opacity:.7+Math.random()*.2,shape:r[Math.floor(Math.random()*r.length)],rotation:(Math.random()-.5)*.1,active:!0,static:!0}},createJackOLantern(e,t,o={}){const r=["happy","scary","wicked"];return{type:"jack-o-lantern",x:o.x!==void 0?o.x:Math.random()*e,y:o.y!==void 0?o.y:t-25-Math.random()*15,size:12+Math.random()*8,opacity:.9+Math.random()*.1,face:r[Math.floor(Math.random()*r.length)],glowPhase:Math.random()*Math.PI*2,active:!0,static:!0}},createSpider(e,t,o={}){return{type:"spider",x:o.x!==void 0?o.x:Math.random()*e,y:o.y!==void 0?o.y:Math.random()*t*.3,baseY:o.y!==void 0?o.y:Math.random()*t*.3,size:5+Math.random()*5,opacity:.8+Math.random()*.2,threadLength:30+Math.random()*50,swingPhase:Math.random()*Math.PI*2,swingAmplitude:20+Math.random()*30,swingSpeed:.001+Math.random()*.002,time:0,active:!0,static:!1}},createFallingParticle(e,t,o){return Math.random()<.7?this.createPumpkin(e,t,o):{type:"spider-small",x:Math.random()*e,y:-20,size:1+Math.random()*2,speed:o.speedRange[0]+Math.random()*(o.speedRange[1]-o.sizeRange[0])*.5,opacity:.6+Math.random()*.3,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.02,windOffset:Math.random()*Math.PI*2,windSpeed:.01+Math.random()*.02,active:!0}},createInitialDecorations(e,t,o){const r=[];r.push({type:"haunted-house",x:80,y:t-120,size:80,opacity:.85,active:!0,static:!0}),r.push({type:"moon",x:e-120,y:100,size:60,opacity:.9,glowPhase:0,active:!0,static:!0});const n=o.gravestones??5;for(let l=0;l<n;l++)r.push({type:"gravestone",x:e/(n+1)*(l+1)+(Math.random()-.5)*40,y:t-30-Math.random()*10,size:12+Math.random()*8,opacity:.7+Math.random()*.2,variant:Math.floor(Math.random()*3),active:!0,static:!0});const a=o.jackOLanterns??4;for(let l=0;l<a;l++)r.push({type:"jack-o-lantern",x:e/(a+1)*(l+1)+(Math.random()-.5)*30,y:t-15,size:10+Math.random()*6,opacity:.9,glowPhase:Math.random()*Math.PI*2,active:!0,static:!0});const i=o.spiders??4;for(let l=0;l<i;l++)r.push({type:"spider",x:e/(i+1)*(l+1),y:0,targetY:50+Math.random()*100,currentY:0,size:3+Math.random()*3,opacity:.8,swingPhase:Math.random()*Math.PI*2,swingAmplitude:20+Math.random()*30,swingSpeed:.02+Math.random()*.02,active:!0,static:!0});const s=o.scarecrows??2;for(let l=0;l<s;l++)r.push({type:"scarecrow",x:120+l/(s-1||1)*(e-240),y:t-60,size:30+Math.random()*10,opacity:.9,swayPhase:Math.random()*Math.PI*2,swaySpeed:.015+Math.random()*.015,glowPhase:Math.random()*Math.PI*2,glowSpeed:.02,active:!0,static:!0});const h=o.twinklingStars??15;for(let l=0;l<h;l++)r.push(this.createTwinklingStar(e,t));return r},createTwinklingStar(e,t){return{type:"twinkling-star",x:Math.random()*e,y:Math.random()*(t*.5),size:1+Math.random()*2.5,opacity:.5+Math.random()*.3,twinklePhase:Math.random()*Math.PI*2,twinkleSpeed:.004+Math.random()*.003,colorVariant:Math.floor(Math.random()*3),active:!0,static:!0}},drawLightning(e,t,o,r,n,a,i,s,h,l,d){if(a<1)return;const y=(t+r)/2,u=(o+n)/2,M=Math.atan2(n-o,r-t),P=M+Math.PI/2,w=(Math.random()-.5)*i,m=y+Math.cos(P)*w,g=u+Math.sin(P)*w,f=a-1,p=i*s,z=l*.8;if(e.strokeStyle=d,e.lineWidth=l,e.lineCap="round",e.lineJoin="round",e.beginPath(),e.moveTo(t,o),e.lineTo(m,g),e.lineTo(r,n),e.stroke(),f>0&&(this.drawLightning(e,t,o,m,g,f,p,s,h,z,d),this.drawLightning(e,m,g,r,n,f,p,s,h,z,d),Math.random()<h&&f>1)){const v=Math.random()*i*.5,T=(Math.random()-.5)*Math.PI/3,S=m+Math.cos(M+T)*v,k=g+Math.sin(M+T)*v;this.drawLightning(e,m,g,S,k,f-1,p*.5,s,h*.5,z*.6,d)}},spawnSpecialParticle(e,t,o){const r=Math.random(),n=this.intensityConfig.medium;if(r<.15)return this.createBat(t,o,n);if(r<.16){if(e.some(i=>i.type==="witch"))return null;const a=Math.random()<.5;return{type:"witch",x:a?-100:t+100,y:Math.random()*(o*.4)+50,baseY:Math.random()*(o*.4)+50,vx:a?3+Math.random()*2:-(3+Math.random()*2),size:15+Math.random()*8,opacity:.85,waveAmplitude:15+Math.random()*20,waveFrequency:.002+Math.random()*.002,waveOffset:Math.random()*Math.PI*2,time:0,active:!0,static:!1}}return r<.18?{type:"floating-pumpkin",x:Math.random()*t,y:-50,size:8+Math.random()*6,vx:(Math.random()-.5)*.5,vy:.3+Math.random()*.5,opacity:.9,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.01,glowPhase:Math.random()*Math.PI*2,windOffset:Math.random()*Math.PI*2,windSpeed:.015,active:!0}:r<.2102?e.some(a=>a.type==="haunted-house")?null:{type:"haunted-house",x:Math.random()*t*.6+t*.2,y:o-100,size:40+Math.random()*20,opacity:.8,windowFlicker:0,active:!0,static:!0}:r<.2105?e.some(a=>a.type==="cauldron")?null:{type:"cauldron",x:Math.random()*t*.6+t*.2,y:o-40,size:25+Math.random()*10,opacity:1,bubbles:[],smoke:[],time:0,active:!0,static:!0}:null},updateSpecialParticles(e,t,o,r){this.lightningActive?(this.lightningTimer+=t,this.lightningTimer>=this.lightningDuration&&(this.lightningActive=!1,this.lightningTimer=0)):Math.random()<this.lightningChance&&(this.lightningActive=!0,this.lightningTimer=0),e.forEach(n=>{switch(n.time!==void 0&&(n.time+=t),n.type){case"moon":break;case"witch":(n.vx>0&&n.x>o+100||n.vx<0&&n.x<-100)&&(n.active=!1);break;case"floating-pumpkin":n.y>r+50&&(n.active=!1);break;case"cauldron":n.time%100<20&&n.bubbles.push({x:(Math.random()-.5)*n.size*.5,y:n.size*.3+Math.random()*n.size*.2,size:n.size*(.05+Math.random()*.1),vy:-.5-Math.random()*.5,opacity:1,life:1,fadeRate:.01+Math.random()*.005}),n.bubbles=n.bubbles.filter(a=>(a.y+=a.vy,a.vy*=.98,a.opacity-=a.fadeRate,a.opacity>0&&a.y>-n.size)),n.time%200<30&&n.smoke.push({x:(Math.random()-.5)*n.size*.3,y:-n.size*.5+Math.random()*n.size*.1,size:n.size*(.2+Math.random()*.3),vx:(Math.random()-.5)*.1,vy:-.2-Math.random()*.2,opacity:.5,life:1,fadeRate:.005+Math.random()*.003}),n.smoke=n.smoke.filter(a=>(a.x+=a.vx,a.y+=a.vy,a.size*=1.02,a.opacity-=a.fadeRate,a.opacity>0));break}})},drawBat:b,drawGhost:R,drawPumpkin:I,drawGravestone(e,t){const o=t.x,r=t.y,n=t.size;e.save(),e.globalAlpha=t.opacity,e.translate(o,r),e.rotate(t.rotation),e.fillStyle="#555555",e.strokeStyle="#333333",e.lineWidth=1,t.shape==="rounded"?(e.beginPath(),e.moveTo(-n*.5,n*.8),e.lineTo(-n*.5,-n*.3),e.arc(0,-n*.3,n*.5,Math.PI,0),e.lineTo(n*.5,n*.8),e.closePath(),e.fill(),e.stroke()):t.shape==="cross"?(e.fillRect(-n*.15,-n,n*.3,n*1.8),e.fillRect(-n*.5,-n*.3,n,n*.3)):(e.beginPath(),e.moveTo(-n*.4,n*.8),e.lineTo(-n*.5,-n*.5),e.lineTo(0,-n),e.lineTo(n*.5,-n*.5),e.lineTo(n*.4,n*.8),e.closePath(),e.fill(),e.stroke()),e.fillStyle="rgba(0, 100, 0, 0.3)",e.fillRect(-n*.4,n*.5,n*.8,n*.3),e.fillStyle="#222222",e.font=`${n*.4}px serif`,e.textAlign="center",e.textBaseline="middle",e.fillText("RIP",0,0),e.restore()},drawJackOLantern:C,drawHauntedHouse:A,drawCauldron(e,t,o){const r=t.x,n=t.y,a=t.size;e.save(),e.translate(r,n),e.fillStyle="#222222",e.strokeStyle="#111111",e.lineWidth=2,e.beginPath(),e.arc(0,0,a*.8,0,Math.PI),e.lineTo(-a*.8,a*.5),e.quadraticCurveTo(0,a*.8,a*.8,a*.5),e.closePath(),e.fill(),e.stroke(),e.strokeStyle="#1a1a1a",e.lineWidth=3,[-a*.5,0,a*.5].forEach(i=>{e.beginPath(),e.moveTo(i,a*.5),e.lineTo(i,a*.9),e.stroke()}),e.fillStyle="#00ff00",e.shadowColor="#00ff00",e.shadowBlur=15,e.beginPath(),e.ellipse(0,0,a*.7,a*.3,0,0,Math.PI*2),e.fill(),e.shadowBlur=0,t.bubbles.forEach(i=>{e.globalAlpha=i.opacity,e.fillStyle="#88ff88",e.beginPath(),e.arc(i.x,i.y,i.size,0,Math.PI*2),e.fill()}),e.globalAlpha=1,t.smoke.forEach(i=>{e.globalAlpha=i.opacity,e.fillStyle="#aaaaaa",e.beginPath(),e.arc(i.x,i.y,i.size,0,Math.PI*2),e.fill()}),e.restore()},drawSpider(e,t,o){const r=t.x,n=t.y,a=t.size,i=Math.sin(o*t.swingSpeed+t.swingPhase)*t.swingAmplitude;e.save(),e.globalAlpha=t.opacity,e.strokeStyle="#cccccc",e.lineWidth=1,e.setLineDash([2,2]),e.beginPath(),e.moveTo(r,n),e.lineTo(r+i,n+t.threadLength),e.stroke(),e.setLineDash([]),e.translate(r+i,n+t.threadLength),e.fillStyle="#000000",e.beginPath(),e.ellipse(0,0,a*.5,a*.7,0,0,Math.PI*2),e.fill(),e.beginPath(),e.arc(0,-a*.5,a*.3,0,Math.PI*2),e.fill(),e.strokeStyle="#1a1a1a",e.lineWidth=a*.1;const s=Math.sin(o*.005)*.2;for(let h=0;h<4;h++){const l=h/4*Math.PI-Math.PI/2,d=a*1.5;e.beginPath(),e.moveTo(-a*.3,-a*.2+h*a*.2),e.quadraticCurveTo(-a-Math.sin(l+s)*a*.3,-a*.2+h*a*.2-a*.5,-a*1.2,-a*.2+h*a*.2),e.stroke(),e.beginPath(),e.moveTo(a*.3,-a*.2+h*a*.2),e.quadraticCurveTo(a+Math.sin(l+s)*a*.3,-a*.2+h*a*.2-a*.5,a*1.2,-a*.2+h*a*.2),e.stroke()}e.fillStyle="#ff0000";for(let h=0;h<4;h++)e.beginPath(),e.arc(-a*.15+h%2*a*.3,-a*.55+Math.floor(h/2)*a*.1,a*.05,0,Math.PI*2),e.fill();e.restore()},drawSpiderSmall(e,t){e.save(),e.globalAlpha=t.opacity,e.translate(t.x,t.y),e.rotate(t.rotation),e.fillStyle="#1a1a1a",e.beginPath(),e.arc(0,0,t.size,0,Math.PI*2),e.fill(),e.strokeStyle="#1a1a1a",e.lineWidth=t.size*.3;for(let o=0;o<4;o++){const r=o/4*Math.PI-Math.PI/2;e.beginPath(),e.moveTo(0,0),e.lineTo(Math.cos(r)*t.size*2,Math.sin(r)*t.size*2),e.stroke(),e.beginPath(),e.moveTo(0,0),e.lineTo(-Math.cos(r)*t.size*2,Math.sin(r)*t.size*2),e.stroke()}e.restore()},drawWitch(e,t,o){const r=t.x,n=t.y+Math.sin(o*t.waveFrequency+t.waveOffset)*t.waveAmplitude,a=t.size,i=t.vx>0?1:-1;e.save(),e.globalAlpha=t.opacity,e.translate(r,n),i===-1&&e.scale(-1,1),e.strokeStyle="#8B4513",e.lineWidth=a*.12,e.lineCap="round",e.beginPath(),e.moveTo(a*.2,a*.6),e.lineTo(-a*1.5,a*.6),e.stroke(),e.strokeStyle="#D2691E",e.lineWidth=a*.06;for(let s=0;s<8;s++){const h=Math.PI/3*(s/7-.5);e.beginPath(),e.moveTo(-a*1.5,a*.6),e.lineTo(-a*1.5+Math.cos(h)*a*.4,a*.6+Math.sin(h)*a*.4),e.stroke()}e.fillStyle="#1a1a1a",e.strokeStyle="#0a0a0a",e.lineWidth=1,e.beginPath(),e.moveTo(a*.2,a*.6),e.quadraticCurveTo(-a*.5,a*.4,-a*.8,a*.1),e.lineTo(-a*.7,-a*.3),e.quadraticCurveTo(-a*.3,-a*.5,0,-a*.6),e.lineTo(a*.3,-a*.4),e.lineTo(a*.3,a*.5),e.closePath(),e.fill(),e.stroke(),e.fillStyle="#8B9355",e.beginPath(),e.ellipse(a*.25,-a*.6,a*.3,a*.35,0,0,Math.PI*2),e.fill(),e.fillStyle="#7a8245",e.beginPath(),e.moveTo(a*.45,-a*.6),e.quadraticCurveTo(a*.7,-a*.65,a*.72,-a*.5),e.lineTo(a*.6,-a*.52),e.quadraticCurveTo(a*.58,-a*.58,a*.4,-a*.55),e.closePath(),e.fill(),e.fillStyle="#2C1810",e.beginPath(),e.moveTo(a*.05,-a*.85),e.lineTo(a*.4,-a*1.6),e.lineTo(a*.5,-a*.8),e.closePath(),e.fill(),e.beginPath(),e.ellipse(a*.25,-a*.85,a*.5,a*.12,0,0,Math.PI*2),e.fill(),e.fillStyle="#ff6600",e.shadowColor="#ff6600",e.shadowBlur=a*.3,e.beginPath(),e.arc(a*.35,-a*.65,a*.08,0,Math.PI*2),e.fill(),e.shadowBlur=0,e.fillStyle="#8B9355",e.beginPath(),e.arc(a*.1,a*.5,a*.12,0,Math.PI*2),e.fill(),e.beginPath(),e.arc(-a*.3,a*.55,a*.1,0,Math.PI*2),e.fill(),e.strokeStyle="#1a1a1a",e.lineWidth=a*.1,e.beginPath(),e.moveTo(a*.15,a*.6),e.lineTo(a*.1,a*1),e.stroke(),e.beginPath(),e.moveTo(a*.05,a*.6),e.lineTo(a*.2,a*.95),e.stroke(),e.restore()},drawFloatingPumpkin(e,t){const o=t.x,r=t.y,n=t.size;e.save(),e.globalAlpha=t.opacity,e.translate(o,r),e.rotate(t.rotation),e.fillStyle="#ff6600",e.strokeStyle="#cc5200",e.lineWidth=n*.1,e.beginPath(),e.ellipse(0,0,n,n*.9,0,0,Math.PI*2),e.fill(),e.stroke();for(let i=-2;i<=2;i++)e.beginPath(),e.moveTo(i*n*.25,-n*.8),e.quadraticCurveTo(i*n*.3,0,i*n*.25,n*.8),e.stroke();e.fillStyle="#228B22",e.beginPath(),e.moveTo(-n*.15,-n*.8),e.lineTo(-n*.1,-n*1.1),e.lineTo(n*.1,-n*1.1),e.lineTo(n*.15,-n*.8),e.closePath(),e.fill();const a=.5+Math.sin(t.glowPhase+Date.now()*.005)*.5;e.fillStyle=`rgba(255, 200, 0, ${a})`,e.beginPath(),e.moveTo(-n*.4,-n*.3),e.lineTo(-n*.2,-n*.1),e.lineTo(-n*.6,-n*.1),e.closePath(),e.fill(),e.beginPath(),e.moveTo(n*.4,-n*.3),e.lineTo(n*.6,-n*.1),e.lineTo(n*.2,-n*.1),e.closePath(),e.fill(),e.beginPath(),e.moveTo(-n*.5,n*.2);for(let i=-4;i<=4;i++)e.lineTo(i*n*.12,n*.2+(i%2===0?n*.15:0));e.lineTo(n*.5,n*.2),e.closePath(),e.fill(),e.restore()},drawMoon(e,t,o){const r=t.x,n=t.y,a=t.size;e.save(),e.globalAlpha=t.opacity,e.translate(r,n);const i=.8+Math.sin(o*.001+t.glowPhase)*.2,s=e.createRadialGradient(0,0,0,0,0,a*1.5);s.addColorStop(0,`rgba(255, 255, 220, ${i})`),s.addColorStop(.4,`rgba(255, 255, 200, ${i*.5})`),s.addColorStop(.7,`rgba(255, 220, 150, ${i*.2})`),s.addColorStop(1,"rgba(255, 200, 100, 0)"),e.fillStyle=s,e.fillRect(-a*1.5,-a*1.5,a*3,a*3),e.fillStyle="#ffffdc",e.shadowColor="#ffffaa",e.shadowBlur=a*.3,e.beginPath(),e.arc(0,0,a,0,Math.PI*2),e.fill(),e.shadowBlur=0,e.fillStyle="rgba(200, 200, 170, 0.4)",e.beginPath(),e.arc(-a*.3,-a*.2,a*.2,0,Math.PI*2),e.fill(),e.beginPath(),e.arc(a*.4,a*.1,a*.15,0,Math.PI*2),e.fill(),e.beginPath(),e.arc(a*.1,a*.4,a*.18,0,Math.PI*2),e.fill(),e.beginPath(),e.arc(-a*.2,a*.5,a*.12,0,Math.PI*2),e.fill(),e.restore()},drawScarecrow:L,drawTwinklingStar(e,t,o){const r=t.x,n=t.y,a=t.size,i=.4+Math.sin(o*t.twinkleSpeed+t.twinklePhase)*.6;let s,h;switch(t.colorVariant){case 0:s=`rgba(255, 255, 255, ${i})`,h=`rgba(255, 255, 255, ${i*.3})`;break;case 1:s=`rgba(200, 150, 255, ${i})`,h=`rgba(150, 100, 255, ${i*.3})`;break;case 2:s=`rgba(255, 180, 100, ${i})`,h=`rgba(255, 150, 50, ${i*.3})`;break}e.save(),e.translate(r,n),e.shadowColor=h,e.shadowBlur=a*4*i,e.fillStyle=s,e.beginPath();for(let l=0;l<4;l++){const d=l/4*Math.PI-Math.PI/2,y=Math.cos(d)*a,u=Math.sin(d)*a,M=d+Math.PI/4,P=Math.cos(M)*(a*.3),w=Math.sin(M)*(a*.3);l===0?e.moveTo(y,u):e.lineTo(y,u),e.lineTo(P,w)}e.closePath(),e.fill(),e.shadowBlur=a*2*i,e.beginPath(),e.arc(0,0,a*.3,0,Math.PI*2),e.fill(),e.restore()},drawGlobalEffects(e,t,o,r){if(this.lightningActive){e.save(),e.globalAlpha=.8+Math.sin(this.lightningTimer*.01)*.2,e.shadowColor=this.lightningColor,e.shadowBlur=20;const n=o*(.4+Math.random()*.2),a=0,i=o*Math.random(),s=r;this.drawLightning(e,n,a,i,s,5+Math.floor(Math.random()*3),50+Math.random()*50,.7,.3,3+Math.random()*2,this.lightningColor),e.restore()}}};
1
+ import{drawWitch as b,drawCauldron as I,drawSpider as T,drawSpiderSmall as C,drawGravestone as L}from"./spooky-props-drawing.js";import{drawBat as A,drawGhost as c,drawPumpkin as O,drawJackOLantern as Y,drawHauntedHouse as $,drawScarecrow as B}from"./halloween-drawing.js";export default{name:"halloween",displayName:"Halloween",emoji:"\u{1F383}",intensityConfig:{light:{count:30,speedRange:[.3,1],sizeRange:[2,5],gravestones:3,jackOLanterns:2,spiders:2,scarecrows:1,twinklingStars:8},medium:{count:60,speedRange:[.5,1.5],sizeRange:[2,6],gravestones:5,jackOLanterns:4,spiders:4,scarecrows:2,twinklingStars:15},heavy:{count:100,speedRange:[.7,2],sizeRange:[3,8],gravestones:8,jackOLanterns:6,spiders:6,scarecrows:3,twinklingStars:25}},particles:["bat","ghost","pumpkin"],decorations:["gravestone","jack-o-lantern","haunted-house","cauldron","spider","scarecrow","twinkling-star"],colors:{primary:"#ff6600",secondary:"#1a1a2e",accent:"#8b0000",ghost:"#f0f0f0",purple:"#6a0dad"},lightningChance:5e-4,lightningDuration:200,lightningTimer:0,lightningActive:!1,lightningColor:"#fefefe",createBat(a,r,e){const o=Math.random();let t,n,i;o<.33?(t=e.sizeRange[0]+Math.random()*(e.sizeRange[1]-e.sizeRange[0])*1.5,n=e.speedRange[0]+Math.random()*(e.speedRange[1]-e.speedRange[0])*1.3,i=.9+Math.random()*.1):o<.66?(t=e.sizeRange[0]+Math.random()*(e.sizeRange[1]-e.sizeRange[0]),n=e.speedRange[0]+Math.random()*(e.speedRange[1]-e.sizeRange[0]),i=.6+Math.random()*.2):(t=e.sizeRange[0]+Math.random()*(e.sizeRange[1]-e.sizeRange[0])*.7,n=e.speedRange[0]+Math.random()*(e.sizeRange[1]-e.sizeRange[0])*.7,i=.4+Math.random()*.2);const h=Math.random()<.5;return{type:"bat",x:h?-20:a+20,y:Math.random()*r*.7,baseY:Math.random()*r*.7,vx:h?n*2:-n*2,vy:0,size:t,speed:n,opacity:i,waveAmplitude:10+Math.random()*20,waveFrequency:.002+Math.random()*.003,waveOffset:Math.random()*Math.PI*2,time:0,rotation:0,active:!0,depth:o}},createGhost(a,r,e){const o=Math.random();let t,n,i;return o<.33?(t=e.sizeRange[0]+Math.random()*(e.sizeRange[1]-e.sizeRange[0])*1.8,n=e.speedRange[0]+Math.random()*(e.speedRange[1]-e.sizeRange[0])*.5,i=.7+Math.random()*.2):o<.66?(t=e.sizeRange[0]+Math.random()*(e.sizeRange[1]-e.sizeRange[0])*1.2,n=e.speedRange[0]+Math.random()*(e.sizeRange[1]-e.sizeRange[0])*.5,i=.5+Math.random()*.15):(t=e.sizeRange[0]+Math.random()*(e.sizeRange[1]-e.sizeRange[0]),n=e.speedRange[0]+Math.random()*(e.sizeRange[1]-e.sizeRange[0])*.5,i=.3+Math.random()*.15),{type:"ghost",x:Math.random()*a,y:-50,size:t,speed:n,opacity:i,windOffset:Math.random()*Math.PI*2,windSpeed:.01+Math.random()*.02,rotation:0,rotationSpeed:(Math.random()-.5)*.005,time:Math.random()*1e3,active:!0,depth:o}},createPumpkin(a,r,e){return{type:"pumpkin",x:Math.random()*a,y:Math.random()*r,size:e.sizeRange[0]+Math.random()*(e.sizeRange[1]-e.sizeRange[0]),vx:(Math.random()-.5)*.2,speed:(e.speedRange[0]+Math.random()*(e.speedRange[1]-e.sizeRange[0]))*.2,opacity:.8+Math.random()*.2,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.008,windOffset:Math.random()*Math.PI*2,windSpeed:.008+Math.random()*.015,glowPhase:Math.random()*Math.PI*2,floatPhase:Math.random()*Math.PI*2,floatSpeed:.001+Math.random()*.002,active:!0}},createGravestone(a,r,e={}){const o=["rounded","cross","obelisk"];return{type:"gravestone",x:e.x!==void 0?e.x:Math.random()*a,y:e.y!==void 0?e.y:r-30-Math.random()*20,size:15+Math.random()*10,opacity:.7+Math.random()*.2,shape:o[Math.floor(Math.random()*o.length)],rotation:(Math.random()-.5)*.1,active:!0,static:!0}},createJackOLantern(a,r,e={}){const o=["happy","scary","wicked"];return{type:"jack-o-lantern",x:e.x!==void 0?e.x:Math.random()*a,y:e.y!==void 0?e.y:r-25-Math.random()*15,size:12+Math.random()*8,opacity:.9+Math.random()*.1,face:o[Math.floor(Math.random()*o.length)],glowPhase:Math.random()*Math.PI*2,active:!0,static:!0}},createSpider(a,r,e={}){return{type:"spider",x:e.x!==void 0?e.x:Math.random()*a,y:e.y!==void 0?e.y:Math.random()*r*.3,baseY:e.y!==void 0?e.y:Math.random()*r*.3,size:5+Math.random()*5,opacity:.8+Math.random()*.2,threadLength:30+Math.random()*50,swingPhase:Math.random()*Math.PI*2,swingAmplitude:20+Math.random()*30,swingSpeed:.001+Math.random()*.002,time:0,active:!0,static:!1}},createFallingParticle(a,r,e){return Math.random()<.7?this.createPumpkin(a,r,e):{type:"spider-small",x:Math.random()*a,y:-20,size:1+Math.random()*2,speed:e.speedRange[0]+Math.random()*(e.speedRange[1]-e.sizeRange[0])*.5,opacity:.6+Math.random()*.3,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.02,windOffset:Math.random()*Math.PI*2,windSpeed:.01+Math.random()*.02,active:!0}},createInitialDecorations(a,r,e){const o=[];o.push({type:"haunted-house",x:80,y:r-120,size:80,opacity:.85,active:!0,static:!0}),o.push({type:"moon",x:a-120,y:100,size:60,opacity:.9,glowPhase:0,active:!0,static:!0});const t=e.gravestones??5;for(let s=0;s<t;s++)o.push({type:"gravestone",x:a/(t+1)*(s+1)+(Math.random()-.5)*40,y:r-30-Math.random()*10,size:12+Math.random()*8,opacity:.7+Math.random()*.2,variant:Math.floor(Math.random()*3),active:!0,static:!0});const n=e.jackOLanterns??4;for(let s=0;s<n;s++)o.push({type:"jack-o-lantern",x:a/(n+1)*(s+1)+(Math.random()-.5)*30,y:r-15,size:10+Math.random()*6,opacity:.9,glowPhase:Math.random()*Math.PI*2,active:!0,static:!0});const i=e.spiders??4;for(let s=0;s<i;s++)o.push({type:"spider",x:a/(i+1)*(s+1),y:0,targetY:50+Math.random()*100,currentY:0,size:3+Math.random()*3,opacity:.8,swingPhase:Math.random()*Math.PI*2,swingAmplitude:20+Math.random()*30,swingSpeed:.02+Math.random()*.02,active:!0,static:!0});const h=e.scarecrows??2;for(let s=0;s<h;s++)o.push({type:"scarecrow",x:120+s/(h-1||1)*(a-240),y:r-60,size:30+Math.random()*10,opacity:.9,swayPhase:Math.random()*Math.PI*2,swaySpeed:.015+Math.random()*.015,glowPhase:Math.random()*Math.PI*2,glowSpeed:.02,active:!0,static:!0});const d=e.twinklingStars??15;for(let s=0;s<d;s++)o.push(this.createTwinklingStar(a,r));return o},createTwinklingStar(a,r){return{type:"twinkling-star",x:Math.random()*a,y:Math.random()*(r*.5),size:1+Math.random()*2.5,opacity:.5+Math.random()*.3,twinklePhase:Math.random()*Math.PI*2,twinkleSpeed:.004+Math.random()*.003,colorVariant:Math.floor(Math.random()*3),active:!0,static:!0}},drawLightning(a,r,e,o,t,n,i,h,d,s,m){if(n<1)return;const y=(r+o)/2,p=(e+t)/2,M=Math.atan2(t-e,o-r),w=M+Math.PI/2,f=(Math.random()-.5)*i,l=y+Math.cos(w)*f,u=p+Math.sin(w)*f,g=n-1,z=i*h,P=s*.8;if(a.strokeStyle=m,a.lineWidth=s,a.lineCap="round",a.lineJoin="round",a.beginPath(),a.moveTo(r,e),a.lineTo(l,u),a.lineTo(o,t),a.stroke(),g>0&&(this.drawLightning(a,r,e,l,u,g,z,h,d,P,m),this.drawLightning(a,l,u,o,t,g,z,h,d,P,m),Math.random()<d&&g>1)){const R=Math.random()*i*.5,v=(Math.random()-.5)*Math.PI/3,k=l+Math.cos(M+v)*R,S=u+Math.sin(M+v)*R;this.drawLightning(a,l,u,k,S,g-1,z*.5,h,d*.5,P*.6,m)}},spawnSpecialParticle(a,r,e){const o=Math.random(),t=this.intensityConfig.medium;if(o<.15)return this.createBat(r,e,t);if(o<.16){if(a.some(i=>i.type==="witch"))return null;const n=Math.random()<.5;return{type:"witch",x:n?-100:r+100,y:Math.random()*(e*.4)+50,baseY:Math.random()*(e*.4)+50,vx:n?3+Math.random()*2:-(3+Math.random()*2),size:15+Math.random()*8,opacity:.85,waveAmplitude:15+Math.random()*20,waveFrequency:.002+Math.random()*.002,waveOffset:Math.random()*Math.PI*2,time:0,active:!0,static:!1}}return o<.18?{type:"floating-pumpkin",x:Math.random()*r,y:-50,size:8+Math.random()*6,vx:(Math.random()-.5)*.5,vy:.3+Math.random()*.5,opacity:.9,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.01,glowPhase:Math.random()*Math.PI*2,windOffset:Math.random()*Math.PI*2,windSpeed:.015,active:!0}:o<.2102?a.some(n=>n.type==="haunted-house")?null:{type:"haunted-house",x:Math.random()*r*.6+r*.2,y:e-100,size:40+Math.random()*20,opacity:.8,windowFlicker:0,active:!0,static:!0}:o<.2105?a.some(n=>n.type==="cauldron")?null:{type:"cauldron",x:Math.random()*r*.6+r*.2,y:e-40,size:25+Math.random()*10,opacity:1,bubbles:[],smoke:[],time:0,active:!0,static:!0}:null},updateSpecialParticles(a,r,e,o){this.lightningActive?(this.lightningTimer+=r,this.lightningTimer>=this.lightningDuration&&(this.lightningActive=!1,this.lightningTimer=0)):Math.random()<this.lightningChance&&(this.lightningActive=!0,this.lightningTimer=0),a.forEach(t=>{switch(t.time!==void 0&&(t.time+=r),t.type){case"moon":break;case"witch":(t.vx>0&&t.x>e+100||t.vx<0&&t.x<-100)&&(t.active=!1);break;case"floating-pumpkin":t.y>o+50&&(t.active=!1);break;case"cauldron":t.time%100<20&&t.bubbles.push({x:(Math.random()-.5)*t.size*.5,y:t.size*.3+Math.random()*t.size*.2,size:t.size*(.05+Math.random()*.1),vy:-.5-Math.random()*.5,opacity:1,life:1,fadeRate:.01+Math.random()*.005}),t.bubbles=t.bubbles.filter(n=>(n.y+=n.vy,n.vy*=.98,n.opacity-=n.fadeRate,n.opacity>0&&n.y>-t.size)),t.time%200<30&&t.smoke.push({x:(Math.random()-.5)*t.size*.3,y:-t.size*.5+Math.random()*t.size*.1,size:t.size*(.2+Math.random()*.3),vx:(Math.random()-.5)*.1,vy:-.2-Math.random()*.2,opacity:.5,life:1,fadeRate:.005+Math.random()*.003}),t.smoke=t.smoke.filter(n=>(n.x+=n.vx,n.y+=n.vy,n.size*=1.02,n.opacity-=n.fadeRate,n.opacity>0));break}})},drawBat:A,drawGhost:c,drawPumpkin:O,drawGravestone:L,drawJackOLantern:Y,drawHauntedHouse:$,drawCauldron:I,drawSpider:T,drawSpiderSmall:C,drawWitch:b,drawFloatingPumpkin(a,r){const e=r.x,o=r.y,t=r.size;a.save(),a.globalAlpha=r.opacity,a.translate(e,o),a.rotate(r.rotation),a.fillStyle="#ff6600",a.strokeStyle="#cc5200",a.lineWidth=t*.1,a.beginPath(),a.ellipse(0,0,t,t*.9,0,0,Math.PI*2),a.fill(),a.stroke();for(let i=-2;i<=2;i++)a.beginPath(),a.moveTo(i*t*.25,-t*.8),a.quadraticCurveTo(i*t*.3,0,i*t*.25,t*.8),a.stroke();a.fillStyle="#228B22",a.beginPath(),a.moveTo(-t*.15,-t*.8),a.lineTo(-t*.1,-t*1.1),a.lineTo(t*.1,-t*1.1),a.lineTo(t*.15,-t*.8),a.closePath(),a.fill();const n=.5+Math.sin(r.glowPhase+Date.now()*.005)*.5;a.fillStyle=`rgba(255, 200, 0, ${n})`,a.beginPath(),a.moveTo(-t*.4,-t*.3),a.lineTo(-t*.2,-t*.1),a.lineTo(-t*.6,-t*.1),a.closePath(),a.fill(),a.beginPath(),a.moveTo(t*.4,-t*.3),a.lineTo(t*.6,-t*.1),a.lineTo(t*.2,-t*.1),a.closePath(),a.fill(),a.beginPath(),a.moveTo(-t*.5,t*.2);for(let i=-4;i<=4;i++)a.lineTo(i*t*.12,t*.2+(i%2===0?t*.15:0));a.lineTo(t*.5,t*.2),a.closePath(),a.fill(),a.restore()},drawMoon(a,r,e){const o=r.x,t=r.y,n=r.size;a.save(),a.globalAlpha=r.opacity,a.translate(o,t);const i=.8+Math.sin(e*.001+r.glowPhase)*.2,h=a.createRadialGradient(0,0,0,0,0,n*1.5);h.addColorStop(0,`rgba(255, 255, 220, ${i})`),h.addColorStop(.4,`rgba(255, 255, 200, ${i*.5})`),h.addColorStop(.7,`rgba(255, 220, 150, ${i*.2})`),h.addColorStop(1,"rgba(255, 200, 100, 0)"),a.fillStyle=h,a.fillRect(-n*1.5,-n*1.5,n*3,n*3),a.fillStyle="#ffffdc",a.shadowColor="#ffffaa",a.shadowBlur=n*.3,a.beginPath(),a.arc(0,0,n,0,Math.PI*2),a.fill(),a.shadowBlur=0,a.fillStyle="rgba(200, 200, 170, 0.4)",a.beginPath(),a.arc(-n*.3,-n*.2,n*.2,0,Math.PI*2),a.fill(),a.beginPath(),a.arc(n*.4,n*.1,n*.15,0,Math.PI*2),a.fill(),a.beginPath(),a.arc(n*.1,n*.4,n*.18,0,Math.PI*2),a.fill(),a.beginPath(),a.arc(-n*.2,n*.5,n*.12,0,Math.PI*2),a.fill(),a.restore()},drawScarecrow:B,drawTwinklingStar(a,r,e){const o=r.x,t=r.y,n=r.size,i=.4+Math.sin(e*r.twinkleSpeed+r.twinklePhase)*.6;let h,d;switch(r.colorVariant){case 0:h=`rgba(255, 255, 255, ${i})`,d=`rgba(255, 255, 255, ${i*.3})`;break;case 1:h=`rgba(200, 150, 255, ${i})`,d=`rgba(150, 100, 255, ${i*.3})`;break;case 2:h=`rgba(255, 180, 100, ${i})`,d=`rgba(255, 150, 50, ${i*.3})`;break}a.save(),a.translate(o,t),a.shadowColor=d,a.shadowBlur=n*4*i,a.fillStyle=h,a.beginPath();for(let s=0;s<4;s++){const m=s/4*Math.PI-Math.PI/2,y=Math.cos(m)*n,p=Math.sin(m)*n,M=m+Math.PI/4,w=Math.cos(M)*(n*.3),f=Math.sin(M)*(n*.3);s===0?a.moveTo(y,p):a.lineTo(y,p),a.lineTo(w,f)}a.closePath(),a.fill(),a.shadowBlur=n*2*i,a.beginPath(),a.arc(0,0,n*.3,0,Math.PI*2),a.fill(),a.restore()},drawGlobalEffects(a,r,e,o){if(this.lightningActive){a.save(),a.globalAlpha=.8+Math.sin(this.lightningTimer*.01)*.2,a.shadowColor=this.lightningColor,a.shadowBlur=20;const t=e*(.4+Math.random()*.2),n=0,i=e*Math.random(),h=o;this.drawLightning(a,t,n,i,h,5+Math.floor(Math.random()*3),50+Math.random()*50,.7,.3,3+Math.random()*2,this.lightningColor),a.restore()}}};
@@ -0,0 +1 @@
1
+ import{path as l,ellipse as b,gradient as d,rect as f}from"./christmas-drawing.js";import{beginIllustration as u,line as s,stud as m}from"./illustration-utils.js";export function drawShield(e,i,r=0){if(!u(e,i))return;const o=[["moveTo",0,-.78],["quadraticCurveTo",.3,-.54,.56,-.56],["lineTo",.5,.12],["quadraticCurveTo",.4,.51,0,.83],["quadraticCurveTo",-.4,.51,-.5,.12],["lineTo",-.56,-.56],["quadraticCurveTo",-.3,-.54,0,-.78],["closePath"]];l(e,o,d(e,-.8,.9,["#e0c796","#8b7049"]),"#615541",.035),e.save(),e.scale(.86,.86),l(e,o,d(e,-.8,.9,["#fff9e9","#ded7c4"])),e.clip(),f(e,-.095,-.9,.19,1.8,0,"#b63548"),f(e,-.65,-.25,1.3,.2,0,"#b63548"),s(e,[["moveTo",-.4,-.48],["quadraticCurveTo",-.43,.14,-.21,.4]],"rgba(255,255,240,0.6)",.035),e.restore();for(const[n,T]of[[0,-.69],[-.46,-.47],[.46,-.47],[-.41,.15],[.41,.15],[0,.68]])m(e,n,T,.023);const a=.55+Math.sin(r*.003+(i.glintPhase||0))*.15;b(e,-.03,-.15,.1,.1,"#b0915d"),b(e,-.05,-.18,.035,.03,`rgba(255,240,190,${a})`),e.restore()}export function drawStGeorgesCross(e,i,r=0){if(!u(e,i))return;const o=Math.sin(r*(i.waveSpeed||.002)+(i.waveOffset||0))*.12;f(e,-.63,-.55,.055,2.15,.018,d(e,-.5,1.6,["#b59a6b","#665844"])),m(e,-.6,-.58,.06);const a=[["moveTo",-.56,-.48],["bezierCurveTo",-.02,-.65+o,.25,-.22-o,.92,-.48+o],["lineTo",.92,.49+o],["bezierCurveTo",.25,.74-o,-.02,.32+o,-.56,.49],["closePath"]];l(e,a,d(e,-.6,.7,["#fffbeb","#d2d0be"]),"#a9a68e",.02),e.save(),e.clip(),l(e,[["moveTo",.02,-.65],["lineTo",.24,-.65],["lineTo",.24,.8],["lineTo",.02,.8],["closePath"]],"#b92e43"),l(e,[["moveTo",-.6,-.1],["bezierCurveTo",-.02,-.27+o,.25,.16-o,1,-.1+o],["lineTo",1,.1+o],["bezierCurveTo",.25,.36-o,-.02,-.07+o,-.6,.1],["closePath"]],"#b92e43");const n=e.createLinearGradient(-.6,0,1,0);["rgba(255,255,230,0.2)","rgba(255,255,230,0)","rgba(38,49,53,0.16)","rgba(255,255,230,0.25)","rgba(38,49,53,0.05)"].forEach((T,v)=>n.addColorStop(v/4,T)),e.fillStyle=n,e.fillRect(-.6,-.8,1.7,1.7),e.restore(),e.restore()}export function drawHarp(e,i,r=0){if(u(e,i)){for(let o=0;o<12;o++){const a=o/11,n=-.37+a*.82,T=-.78+a*.18,v=.75-a*1.25,t=Math.sin(r*.003+o+(i.glintPhase||0))*.003;s(e,[["moveTo",n,T],["quadraticCurveTo",n+t,(T+v)/2,n,v]],o%7===0?"#af6061":o%7===3?"#668392":"#d6c6a2",.012)}l(e,[["moveTo",-.54,.82],["bezierCurveTo",-.76,.35,-.79,-.47,-.5,-.91],["quadraticCurveTo",-.34,-1.05,-.21,-.82],["lineTo",-.37,-.72],["quadraticCurveTo",-.64,-.12,-.35,.73],["closePath"]],d(e,-1,.9,["#c69b60","#8e5d3d","#b98a52"]),"#674e3c",.028),l(e,[["moveTo",-.48,-.87],["bezierCurveTo",-.19,-1.01,.09,-.58,.5,-.74],["lineTo",.57,-.56],["quadraticCurveTo",.05,-.48,-.38,-.72],["closePath"]],"#c39a5e","#76563b",.025),l(e,[["moveTo",.49,-.63],["lineTo",.67,-.5],["lineTo",-.33,.88],["lineTo",-.52,.74],["closePath"]],d(e,-.6,.9,["#dab77c","#976844"]),"#6c503b",.025);for(let o=0;o<12;o++)m(e,-.37+o*.075,-.78+o*.016,.018);for(let o=0;o<5;o++){const a=-.53+o*.23;s(e,[["moveTo",-.56,a],["bezierCurveTo",-.73,a-.13,-.34,a-.08,-.56,a+.08]],"#e0bb7e",.02)}f(e,-.6,.78,.45,.12,.035,"#795438","#d4ad72",.018),e.restore()}}function p(e,i){for(const o of[-1,1])b(e,o*.68,-.05,.14,.21,"#a28b62"),b(e,o*.68,-.05,.08,.14,"#273b3a"),f(e,o*.44-.07,.5,.14,.23,.04,"#344846");l(e,[["moveTo",-.57,-.27],["bezierCurveTo",-1.07,.49,-.58,.8,0,.7],["bezierCurveTo",.58,.8,1.07,.49,.57,-.27],["closePath"]],d(e,-.3,.8,["#506762","#253a39","#172b2e"]),"#172b2b",.035),b(e,-.24,.17,.16,.3,"rgba(161,187,162,0.14)"),b(e,0,-.24,.61,.14,"#b7a275"),b(e,0,-.24,.52,.085,"#283935");for(let o=0;o<3;o++)for(let a=0;a<5-o;a++){const n=(a-(4-o)/2)*.22+o%2*.03,T=-.27-o*.11;b(e,n,T,.13,.065,"#ad7939"),b(e,n,T-.025,.12,.06,"#dfba62"),s(e,[["moveTo",n-.07,T-.04],["lineTo",n+.04,T-.05]],"#fff0af",.014)}const r=.035+Math.sin(i*.002)*.009;s(e,[["moveTo",.28,-.66],["lineTo",.28,-.54],["moveTo",.22,-.6],["lineTo",.34,-.6]],"#ffe8a2",r)}export function drawPotOfGold(e,i,r=0){u(e,i)&&(p(e,r),e.restore())}export function drawSmallGoldPot(e,i,r,o){drawPotOfGold(e,{x:i,y:r,size:o,opacity:1})}export function drawRainbow(e,i){const{startX:r,endX:o,endY:a,height:n}=i;if(![r,o,a,n].every(Number.isFinite)||n<=0||r===o)return;const T=Math.abs(o-r),v=Math.min(n*.25,T*.45),t=Math.max(1,Math.min(4,T/100));e.save(),e.globalAlpha*=i.opacity??.65,e.lineCap="round",["#ca6570","#dfa06c","#e7cc81","#89ac85","#72a6af","#7f8fb4","#a28dad"].forEach((C,P)=>{const h=P*t;s(e,[["moveTo",Math.min(r,o)+h,a],["bezierCurveTo",Math.min(r,o)+T*.12,a-v*1.33+h,Math.max(r,o)-T*.12,a-v*1.33+h,Math.max(r,o)-h,a]],C,t+.4)}),e.restore(),drawSmallGoldPot(e,o,a,20)}export function drawTartanPattern(e,i){if(!u(e,i))return;e.rotate(-.08),l(e,[["moveTo",-.94,-.65],["quadraticCurveTo",0,-.78,.92,-.65],["lineTo",.84,.65],["quadraticCurveTo",.1,.8,-.85,.63],["closePath"]],"#8b3b43","#66343e",.02),e.save(),e.clip();for(let o=-2;o<=2;o++){const a=o*.48;f(e,a-.13,-.85,.22,1.7,0,"rgba(30,61,63,0.8)"),f(e,-1,a-.13,2,.22,0,"rgba(30,61,63,0.7)");for(const n of[-.18,.18])s(e,[["moveTo",a+n,-.9],["lineTo",a+n,.9]],"#d6b775",.014),s(e,[["moveTo",-1,a+n],["lineTo",1,a+n]],"#d6b775",.014);s(e,[["moveTo",a,-.9],["lineTo",a,.9]],"#9fb8a7",.016),s(e,[["moveTo",-1,a],["lineTo",1,a]],"#9fb8a7",.016)}for(let o=-55;o<=55;o++)s(e,[["moveTo",-1,o*.018],["lineTo",1,o*.018+.13]],"rgba(242,221,184,0.09)",.004);e.fillStyle=d(e,-.8,.8,["rgba(255,229,195,0.17)","rgba(0,0,0,0)","rgba(22,28,30,0.22)"]),e.fillRect(-1,-1,2,2),e.restore();for(let o=0;o<23;o++){const a=-.84+o*.074;s(e,[["moveTo",a,.66+Math.cos(a*2)*.07],["lineTo",a-.025,.82+Math.cos(a*2)*.07]],o%2?"#b78275":"#8d9b87",.012)}b(e,-.58,-.4,.12,.12,"#adad98"),b(e,-.58,-.4,.085,.085,"#46605c"),m(e,-.58,-.4,.043),e.restore()}function g(e){l(e,[["moveTo",-.34,.13],["lineTo",-.34,-.36],["lineTo",-.22,-.36],["lineTo",-.22,-.25],["lineTo",-.1,-.25],["lineTo",-.1,-.52],["lineTo",.13,-.52],["lineTo",.13,-.22],["lineTo",.25,-.22],["lineTo",.25,-.4],["lineTo",.4,-.4],["lineTo",.4,.13],["closePath"]],d(e,-.5,.15,["#c9bb95","#8b917c"]),"#556860",.015);for(const[i,r,o]of[[-.34,-.4,.12],[-.1,-.57,.23],[.25,-.45,.15]])for(let a=0;a<3;a++)f(e,i+a*o/3,r,o/6,.07,0,"#bdb38e");l(e,[["moveTo",-.34,-.34],["lineTo",-.34,.1],["lineTo",-.27,.1],["lineTo",-.27,-.34]],"#e0d0a8"),f(e,-.035,-.03,.13,.17,.06,"#394f4e");for(const[i,r]of[[-.29,-.25],[0,-.42],[.31,-.3],[.02,-.23]])f(e,i,r,.035,.07,.01,"#425a55");for(let i=0;i<5;i++)s(e,[["moveTo",-.21,-.2+i*.065],["lineTo",.23,-.2+i*.065]],"rgba(69,83,69,0.2)",.006)}export function drawHighlandScene(e,i){if(u(e,i)){e.beginPath(),e.ellipse(0,-.12,1.14,.92,0,0,Math.PI*2),e.clip(),f(e,-1.2,-1.1,2.4,2,0,d(e,-1.1,.9,["#a5c1c5","#e7dbba","#718d87"])),b(e,.63,-.69,.11,.11,"#f6e6ba"),l(e,[["moveTo",-1.3,.24],["lineTo",-1.02,-.49],["lineTo",-.79,-.35],["lineTo",-.44,-.88],["lineTo",-.05,-.38],["lineTo",.33,-.69],["lineTo",.86,-.14],["lineTo",1.3,-.5],["lineTo",1.3,.6],["closePath"]],"#829c9b"),l(e,[["moveTo",-.64,-.61],["lineTo",-.44,-.88],["lineTo",-.19,-.56],["lineTo",-.41,-.68],["lineTo",-.46,-.58],["lineTo",-.51,-.68],["closePath"]],"#d3d6c6"),l(e,[["moveTo",-1.2,.23],["lineTo",-.8,-.21],["lineTo",-.49,-.09],["lineTo",-.13,-.38],["lineTo",.3,.04],["lineTo",.75,-.35],["lineTo",1.2,.12],["lineTo",1.2,.6],["closePath"]],"#5e7c79"),f(e,-1.2,.16,2.4,.85,0,d(e,.16,.9,["#a2b4a5","#4d7476"])),e.save(),e.globalAlpha*=.22,e.translate(0,.41),e.scale(1,-.6),g(e),e.restore(),l(e,[["moveTo",-.76,.31],["quadraticCurveTo",-.4,-.05,.17,.02],["quadraticCurveTo",.56,.08,.83,.29],["quadraticCurveTo",0,.42,-.76,.31],["closePath"]],"#526d57"),e.save(),e.translate(0,.07),g(e),e.restore();for(let r=0;r<13;r++){const o=.37+r*.033,a=.12+r%4*.08;s(e,[["moveTo",Math.sin(r*2.4)*.7-a,o],["lineTo",Math.sin(r*2.4)*.7+a,o]],r%2?"#c2c8ae":"#668c88",.009)}l(e,[["moveTo",-1.2,.58],["quadraticCurveTo",-.59,.4,-.24,.94],["lineTo",-1.2,1],["closePath"]],"#3a5950"),l(e,[["moveTo",.73,.71],["lineTo",.88,.39],["lineTo",.97,.72],["lineTo",1.06,.31],["lineTo",1.14,.83],["closePath"]],"#496553"),e.restore()}}
@@ -0,0 +1 @@
1
+ import{path as i,ellipse as t}from"./christmas-drawing.js";export function beginIllustration(e,o,a=!1){return![o.x,o.y,o.size].every(Number.isFinite)||o.size<=0?!1:(e.save(),e.translate(o.x,o.y),e.scale(o.size*(a&&o.vx<0?-1:1),o.size),e.rotate(o.rotation||0),e.globalAlpha*=o.opacity??1,e.lineCap="round",e.lineJoin="round",!0)}export function line(e,o,a,r=.02){i(e,o,null,a,r)}export function leaf(e,o,a,r,n=1,l="#4e795d"){e.save(),e.translate(o,a),e.rotate(r),e.scale(n,n),i(e,[["moveTo",0,0],["quadraticCurveTo",-.45,-.24,0,-.9],["quadraticCurveTo",.4,-.32,0,0],["closePath"]],l),line(e,[["moveTo",0,0],["lineTo",0,-.7]],"#9cab7a",.018),e.restore()}export function heart(e,o,a,r,n,l="#9c4655"){e.save(),e.translate(o,a),e.scale(r,r),i(e,[["moveTo",0,.7],["bezierCurveTo",-1.25,-.08,-.6,-.95,0,-.42],["bezierCurveTo",.6,-.95,1.25,-.08,0,.7],["closePath"]],n,l,.035),line(e,[["moveTo",-.5,-.16],["quadraticCurveTo",-.49,-.42,-.27,-.38]],"#f6cfca",.055),e.restore()}export function stud(e,o,a,r=.035){t(e,o,a,r,r,"#dab878"),t(e,o-r*.25,a-r*.3,r*.3,r*.3,"#fff0be")}
@@ -0,0 +1 @@
1
+ import{path as u,ellipse as b,gradient as n,rect as h}from"./christmas-drawing.js";import{beginIllustration as d,line as s,heart as f}from"./illustration-utils.js";export function drawLips(e,o,i=0){if(!d(e,o))return;const r=1+Math.sin(i*.003+(o.kissPhase||0))*.035;e.scale(r,r),u(e,[["moveTo",-1,0],["bezierCurveTo",-.52,-.1,-.37,-.65,0,-.32],["bezierCurveTo",.37,-.65,.52,-.1,1,0],["quadraticCurveTo",.35,.2,0,.09],["quadraticCurveTo",-.35,.2,-1,0],["closePath"]],n(e,-.5,.15,["#e68a8f",o.color||"#b53d5b"]),"#963c53",.025),u(e,[["moveTo",-1,0],["quadraticCurveTo",0,.9,1,0],["quadraticCurveTo",.25,.18,0,.08],["quadraticCurveTo",-.25,.18,-1,0],["closePath"]],n(e,0,.5,[o.color||"#bd4963","#d5767e"]),"#963c53",.025),s(e,[["moveTo",-.81,.05],["quadraticCurveTo",-.3,.17,0,.08],["quadraticCurveTo",.3,.17,.81,.05]],"#80384e",.03),s(e,[["moveTo",-.3,.34],["quadraticCurveTo",0,.43,.27,.32]],"#f8bcaf",.035),e.restore()}function m(e,o){const i="#b39887";if(o){u(e,[["moveTo",-.94,-.34],["lineTo",-.14,-1.04],["quadraticCurveTo",0,-1.16,.14,-1.04],["lineTo",.94,-.34],["closePath"]],"#d9bdaa",i,.02),h(e,-.71,-.86,1.42,1.1,.035,n(e,-.9,.3,["#fff9e6","#e9dcc5"]),i,.02),f(e,0,-.61,.18,"#bf6170");for(let r=0;r<3;r++)s(e,[["moveTo",-.48,-.3+r*.13],["quadraticCurveTo",-.08,-.34+r*.13,.44-r*.12,-.3+r*.13]],"#baa994",.018)}h(e,-1,-.43,2,1.12,.045,n(e,-.4,.7,["#f9ead6","#dec6b5"]),i,.025),u(e,[["moveTo",-.98,-.4],["lineTo",0,.31],["lineTo",.98,-.4],["lineTo",.98,.66],["lineTo",-.98,.66],["closePath"]],"#f1dfc7",i,.018),s(e,[["moveTo",-.97,.65],["lineTo",-.16,.11],["moveTo",.97,.65],["lineTo",.16,.11]],"#c8b19b",.018),o||u(e,[["moveTo",-.98,-.41],["lineTo",-.08,.24],["quadraticCurveTo",0,.31,.08,.24],["lineTo",.98,-.41],["closePath"]],n(e,-.45,.3,["#fff2dc","#e2ccb5"]),i,.02),b(e,0,.27,.16,.145,"#994352"),b(e,-.012,.252,.13,.115,"#bc6370"),e.save(),e.translate(0,.25),e.scale(.12,.12),f(e,0,0,.8,"#d99194","#8b3d50"),e.restore()}export function drawLoveLetter(e,o){d(e,o)&&(m(e,!0),e.restore())}export function drawEnvelope(e,o){d(e,o)&&(e.scale(.72,.72),m(e,!1),e.restore())}export function drawHeartGarland(e,o,i=0){if(![o.y,o.width].every(Number.isFinite)||o.width<=0)return;e.save(),e.globalAlpha*=o.opacity??1;const r=o.x||0,v=(o.sag??50)+Math.sin(i*.001+(o.swayPhase||0))*(o.swayAmplitude??10);s(e,[["moveTo",r,o.y],["quadraticCurveTo",r+o.width/2,o.y+v,r+o.width,o.y]],"#b19a74",1.3);for(const a of o.hearts||[]){if(![a.offset,a.size].every(Number.isFinite)||a.size<=0)continue;const l=a.offset,T=r+l*o.width,t=o.y+2*(1-l)*l*v;s(e,[["moveTo",T,t],["lineTo",T,t+7]],"#bca780",.8),e.save(),e.translate(T,t+7+a.size*.6),e.rotate(Math.sin(i*.0015+l*6)*.09);const C=1+Math.sin(i*.003+(a.pulsePhase||0))*.035,c=n(e,-a.size,a.size,["#ecb0a8",a.color||"#bc6174"]);f(e,0,0,a.size*C,c),s(e,[["moveTo",0,-a.size*.25],["lineTo",0,a.size*.5]],"rgba(255,231,212,0.45)",.5),e.restore()}e.restore()}
@@ -0,0 +1 @@
1
+ import{path as d,ellipse as n,gradient as u,rect as b}from"./christmas-drawing.js";import{beginIllustration as f,line as T,leaf as m}from"./illustration-utils.js";export function drawGravestone(e,r){if(!f(e,r))return;n(e,0,.78,.72,.12,"rgba(28,40,37,0.23)");let s=[["moveTo",-.48,.7],["lineTo",-.48,-.35],["bezierCurveTo",-.48,-.91,.48,-.91,.48,-.35],["lineTo",.48,.7],["closePath"]];const a=r.shape||["rounded","cross","obelisk"][r.variant||0];a==="cross"&&(s=[["moveTo",-.15,.7],["lineTo",-.15,-.25],["lineTo",-.48,-.25],["lineTo",-.48,-.51],["lineTo",-.15,-.51],["lineTo",-.15,-.98],["lineTo",.15,-.98],["lineTo",.15,-.51],["lineTo",.48,-.51],["lineTo",.48,-.25],["lineTo",.15,-.25],["lineTo",.15,.7],["closePath"]]),a==="obelisk"&&(s=[["moveTo",-.35,.7],["lineTo",-.4,-.53],["lineTo",0,-.97],["lineTo",.4,-.53],["lineTo",.35,.7],["closePath"]]),e.save(),e.translate(.055,.02),d(e,s,"#65706b","#485950",.025),e.restore(),d(e,s,u(e,-.8,.8,["#b7beb0","#7e8e85"]),"#53665d",.028),e.save(),e.clip(),T(e,[["moveTo",-.39,.52],["lineTo",-.39,-.32],["bezierCurveTo",-.39,-.78,.38,-.78,.38,-.32],["lineTo",.38,.51]],"#d6d6bd",.018),T(e,[["moveTo",0,-.55],["lineTo",0,-.18],["moveTo",-.12,-.42],["lineTo",.12,-.42]],"#63746a",.044);const i=[[["moveTo",-.25,.2],["lineTo",-.25,-.02],["quadraticCurveTo",-.08,-.04,-.12,.08],["lineTo",-.25,.08],["moveTo",-.2,.08],["lineTo",-.11,.2]],[["moveTo",-.03,-.02],["lineTo",.05,-.02],["moveTo",.01,-.02],["lineTo",.01,.2],["moveTo",-.03,.2],["lineTo",.05,.2]],[["moveTo",.14,.2],["lineTo",.14,-.02],["quadraticCurveTo",.34,-.04,.28,.09],["lineTo",.14,.09]]];for(const o of i)T(e,o,"#53665f",.023);T(e,[["moveTo",.3,-.58],["lineTo",.2,-.42],["lineTo",.29,-.3],["lineTo",.22,-.18]],"#6f7f73",.016),e.restore(),b(e,-.57,.63,1.14,.14,.035,"#89988a","#5d7163",.023);for(const[o,v,l]of[[-.41,.53,.12],[-.32,.6,.1],[.37,.63,.15]])n(e,o,v,l,l*.45,"#688366");m(e,-.47,.64,-.3,.27,"#5d795c"),e.restore()}export function drawCauldron(e,r,s=0){if(f(e,r)){for(const a of[-1,1])b(e,a*.43-.06,.49,.12,.25,.04,"#303f45"),n(e,a*.68,-.09,.14,.2,"#8a8f82"),n(e,a*.68,-.09,.08,.13,"#263a40");d(e,[["moveTo",-.58,-.29],["bezierCurveTo",-.95,.21,-.75,.67,0,.66],["bezierCurveTo",.75,.67,.95,.21,.58,-.29],["closePath"]],u(e,-.3,.7,["#586b6d","#2f444a","#1e303b"]),"#1f3139",.035),n(e,-.27,.15,.13,.29,"rgba(173,191,177,0.12)"),n(e,0,-.29,.63,.16,"#8e9b8c"),n(e,0,-.31,.55,.105,"#7fbb79"),n(e,-.17,-.34,.19,.035,"#c4d69a");for(let a=0;a<7;a++){const i=((s*3e-4+a*.145)%1+1)%1,o=Math.sin(a*2.7)*.38+Math.sin(s*.001+a)*.03,v=-.35-i*.9;e.save(),e.globalAlpha*=1-i,n(e,o,v,.035+a%3*.014,.04+a%3*.014,"#a5d493"),n(e,o-.012,v-.012,.012,.012,"#e4efbe"),e.restore()}for(let a=0;a<3;a++){const i=Math.sin(s*.001+a)*.08;T(e,[["moveTo",-.3+a*.28,-.5],["bezierCurveTo",-.45+a*.28+i,-.8,-.07+a*.28,-.85,-.2+a*.28+i,-1.15]],"rgba(160,194,172,0.22)",.035)}T(e,[["moveTo",-.51,.47],["quadraticCurveTo",0,.67,.51,.47]],"#536a6c",.02),e.restore()}}function t(e,r,s=0){for(const a of[-1,1])for(let i=0;i<4;i++){const o=-.23+i*.12,v=Math.sin(r*.006+s+i)*.04;T(e,[["moveTo",a*.14,o],["quadraticCurveTo",a*.49,o-.34,a*(.57+i*.05),o-.25],["lineTo",a*(.77+i*.045),o+.16+v]],"#5d5264",.045),T(e,[["moveTo",a*.31,o-.17],["lineTo",a*.53,o-.26]],"#9b8792",.012)}n(e,0,-.18,.28,.35,u(e,-.55,.2,["#826b86","#403c52"])),n(e,-.065,-.31,.09,.14,"rgba(206,170,190,0.2)"),n(e,0,.18,.21,.18,"#58465b");for(const a of[-1,1])n(e,a*.075,.18,.04,.045,"#dfc69f"),n(e,a*.075,.19,.018,.025,"#302e3b");T(e,[["moveTo",-.04,.31],["quadraticCurveTo",0,.35,.04,.31]],"#b9979b",.014)}export function drawSpider(e,r,s=0){if(![r.x,r.y,r.size].every(Number.isFinite)||r.size<=0)return;const a=Math.sin(s*(r.swingSpeed||.002)+(r.swingPhase||0))*(r.swingAmplitude||0),i=r.threadLength??50;f(e,r)&&(T(e,[["moveTo",0,0],["lineTo",a/r.size,i/r.size-.48]],"rgba(203,207,198,0.5)",.04),e.translate(a/r.size,i/r.size),t(e,s,r.legPhase||0),e.restore())}export function drawSpiderSmall(e,r,s=0){f(e,r)&&(t(e,s,r.legPhase||0),e.restore())}export function drawWitch(e,r,s=0){const a=r.y+Math.sin(s*(r.waveFrequency||0)+(r.waveOffset||0))*(r.waveAmplitude||0);if(!f(e,{...r,y:a},!0))return;const i=Math.sin(s*.004+(r.waveOffset||0))*.09;T(e,[["moveTo",-1.6,.7],["quadraticCurveTo",-.2,.49,1.12,.53]],"#967352",.08),T(e,[["moveTo",-1.4,.67],["lineTo",1.08,.51]],"#d1b084",.017),d(e,[["moveTo",-1.38,.6],["quadraticCurveTo",-1.76,.34,-2.05,.55],["lineTo",-1.96,.69],["lineTo",-2.04,.86],["quadraticCurveTo",-1.68,.99,-1.37,.73],["closePath"]],"#b9955e","#846c4e",.02);for(let o=0;o<7;o++)T(e,[["moveTo",-1.4,.66],["quadraticCurveTo",-1.7,.55+o*.045,-1.98,.55+o*.045]],o%2?"#d6b978":"#8a704d",.014);T(e,[["moveTo",-1.42,.58],["lineTo",-1.4,.76]],"#776044",.05);for(const[o,v]of[[.08,.51],[.38,.45]]){T(e,[["moveTo",o,v],["lineTo",o+.25,.75],["lineTo",o+.05,1.05]],"#9b8a9d",.11);for(let l=0;l<3;l++)T(e,[["moveTo",o+.11+l*.04,.94-l*.07],["lineTo",o+.21+l*.04,.95-l*.07]],"#d2bbc0",.025);d(e,[["moveTo",o,1],["lineTo",o+.14,1.03],["quadraticCurveTo",o+.36,1.17,o+.45,1.01],["quadraticCurveTo",o+.47,1.28,o-.03,1.17],["closePath"]],"#3a3d48")}d(e,[["moveTo",.12,-.32],["quadraticCurveTo",-.53,-.26,-.78,.45+i],["lineTo",-.93,.58+i],["quadraticCurveTo",-.18,.73,.41,.5],["quadraticCurveTo",.51,.1,.35,-.23],["closePath"]],u(e,-.4,.7,["#82718d","#4a425e","#343b4d"]),"#3a364c",.025),T(e,[["moveTo",-.13,-.14],["quadraticCurveTo",-.1,.15,-.49,.48]],"#ac91a7",.023),n(e,.22,-.57,.24,.28,"#d6c7a0"),d(e,[["moveTo",.35,-.59],["lineTo",.57,-.47],["quadraticCurveTo",.5,-.39,.36,-.44]],"#d6c7a0","#ad9e83",.014),d(e,[["moveTo",.04,-.78],["quadraticCurveTo",-.37,-.46,-.42,-.17+i],["quadraticCurveTo",-.13,-.28,.1,-.5],["closePath"]],"#b6a390");for(let o=0;o<4;o++)T(e,[["moveTo",.04-o*.035,-.67],["quadraticCurveTo",-.2-o*.035,-.4,-.29-o*.035,-.21+i]],"#d7c2a6",.018);n(e,.32,-.57,.023,.03,"#4e5146"),T(e,[["moveTo",.31,-.36],["quadraticCurveTo",.4,-.34,.44,-.39]],"#987b70",.015),d(e,[["moveTo",-.14,-.76],["quadraticCurveTo",-.18,-1.16,-.43,-1.36],["quadraticCurveTo",.09,-1.43,.42,-.73],["closePath"]],u(e,-1.4,-.7,["#80728a","#45425d"]),"#3f3d51",.025),n(e,.11,-.74,.59,.11,"#47445d"),T(e,[["moveTo",-.16,-.87],["quadraticCurveTo",.08,-.82,.33,-.86]],"#b18e6d",.07),b(e,.03,-.91,.13,.12,.015,"#d1b477","#745f50",.016),T(e,[["moveTo",.24,-.1],["quadraticCurveTo",.6,.11,.72,.48]],"#625675",.14),n(e,.73,.46,.09,.075,"#d6c7a0"),e.restore()}export function drawBanshee(e,r,s=0){const a=r.y+Math.sin(s*(r.waveFrequency||0)+(r.waveOffset||0))*(r.waveAmplitude||0);if(!f(e,{...r,y:a},!0))return;const i=Math.sin(s*.003+(r.wailPhase||0))*.12;d(e,[["moveTo",.07,-.83],["bezierCurveTo",-.69,-.87,-.5,.45,-1.35,.93+i],["quadraticCurveTo",-.72,.97,-.18,.55],["lineTo",.3,-.24],["closePath"]],"rgba(136,170,167,0.36)"),d(e,[["moveTo",-.15,-.43],["bezierCurveTo",-.6,-.14,-.15,.68,-.93,1.22+i],["quadraticCurveTo",-.38,1.02,-.2,1.23],["quadraticCurveTo",.04,.86,.24,1.06-i],["quadraticCurveTo",.59,.3,.31,-.43],["closePath"]],u(e,-.5,1.3,["#dce2ce","#abbfb3","#7b9d9e"]),"#89a69f",.018);for(let o=0;o<4;o++)T(e,[["moveTo",-.1+o*.1,-.16],["bezierCurveTo",-.2+o*.1,.39,.12-o*.15,.7,-.43+o*.16,1.02+i]],"#d2ddc9",.018);n(e,.14,-.72,.2,.26,"#e5e4cc"),d(e,[["moveTo",.03,-.98],["bezierCurveTo",-.44,-1.08,-.4,-.38,-.7,-.12+i],["quadraticCurveTo",-.24,-.18,.02,-.53],["lineTo",.2,-.94],["closePath"]],u(e,-1,-.1,["#c4d0c3","#829e9c"]));for(let o=0;o<5;o++)T(e,[["moveTo",.01-o*.035,-.91],["bezierCurveTo",-.23-o*.035,-.63,-.12-o*.08,-.35,-.45-o*.04,-.2+i]],"#d9dfcc",.014);for(const o of[.1,.25])n(e,o,-.75,.027,.039,"#617f7b"),T(e,[["moveTo",o,-.7],["lineTo",o-.02,-.62]],"#9db5aa",.014);n(e,.21,-.54,.042,.06,"#7d8f83");for(const o of[-1,1]){const v=.13+o*.37;T(e,[["moveTo",.13+o*.13,-.3],["quadraticCurveTo",v+o*.13,-.24,v,-.6]],"#b8cbbd",.12),n(e,v,-.62,.06,.1,"#d9dfc8");for(let l=0;l<3;l++)T(e,[["moveTo",v-.04+l*.035,-.66],["lineTo",v-.04+l*.035,-.79-l*.012]],"#d9dfc8",.02)}e.restore()}
@@ -1 +1 @@
1
- import{drawBagpiper as T}from"./character-drawing.js";export default{name:"st-andrews",displayName:"St Andrew's Day",emoji:"\u{1F3F4}\u{E0067}\u{E0062}\u{E0073}\u{E0063}\u{E0074}\u{E007F}",intensityConfig:{light:{count:50,speedRange:[.5,1.5],sizeRange:[2,4],thistles:4,bagpiperChance:2e-4,twinklingStars:12},medium:{count:100,speedRange:[.6,2],sizeRange:[2,5],thistles:6,bagpiperChance:4e-4,twinklingStars:20},heavy:{count:200,speedRange:[.8,2.5],sizeRange:[3,6],thistles:8,bagpiperChance:6e-4,twinklingStars:30}},particles:["heather-petal","heather","saltire-sparkle"],decorations:["thistle-plant","bagpiper","saltire-flag","tartan-pattern","highland-scene","twinkling-star"],colors:{primary:"#0065BD",secondary:"#FFFFFF",accent:"#8B008B",tartan:["#0065BD","#006400","#8B0000","#FFDD00"]},createHeatherPetal(e,o,n){const l=["#9370DB","#BA55D3","#DA70D6","#DDA0DD","#8B008B"];return{type:"heather-petal",x:-30,y:Math.random()*o,vx:n.speedRange[0]+Math.random()*(n.speedRange[1]-n.speedRange[0]),size:(n.sizeRange[0]+Math.random()*(n.sizeRange[1]-n.sizeRange[0]))*1.5,speed:(Math.random()-.5)*.2,opacity:.75+Math.random()*.25,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.02,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.03,color:l[Math.floor(Math.random()*l.length)],flutter:Math.random()*Math.PI*2,flutterSpeed:.02+Math.random()*.02,active:!0}},createThistle(e,o,n){const l=Math.random()<.5,a=l?"#FFFFFF":"#0065BD",t=l?["#FFFFFF","#f0f0f0","#e0e0e0"]:["#0065BD","#1a7dd4","#3399ee"];return{type:"thistle",x:-30,y:Math.random()*o,vx:n.speedRange[0]+Math.random()*(n.speedRange[1]-n.speedRange[0])*.7,size:n.sizeRange[0]+Math.random()*(n.sizeRange[1]-n.sizeRange[0]),speed:(Math.random()-.5)*.15,opacity:.7+Math.random()*.3,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.02,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.02,flowerColor:a,petalColors:t,active:!0}},createHeather(e,o,n){const l=Math.random();let a;return l<.5?a="#9370DB":l<.8?a="#BA55D3":a="#DA70D6",{type:"heather",x:-30,y:Math.random()*o,vx:(n.speedRange[0]+Math.random()*(n.speedRange[1]-n.speedRange[0]))*.6,size:n.sizeRange[0]+Math.random()*(n.sizeRange[1]-n.sizeRange[0]),speed:(Math.random()-.5)*.15,opacity:.75+Math.random()*.25,windOffset:Math.random()*Math.PI*2,windSpeed:.02+Math.random()*.02,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.03,color:a,sway:Math.random()*Math.PI*2,swaySpeed:.02+Math.random()*.02,bellCount:3+Math.floor(Math.random()*3),active:!0}},createSaltireSparkle(e,o,n){const l=["#0065BD","#FFFFFF"];return{type:"saltire-sparkle",x:-20,y:Math.random()*o,vx:(n.speedRange[0]+Math.random()*(n.speedRange[1]-n.speedRange[0]))*.8,size:n.sizeRange[0]+Math.random()*(n.sizeRange[1]-n.sizeRange[0])*.6,vy:(Math.random()-.5)*.2,opacity:.6+Math.random()*.4,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.04,color:l[Math.floor(Math.random()*l.length)],twinklePhase:Math.random()*Math.PI*2,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.02,active:!0,static:!1}},createFallingParticle(e,o,n){const l=Math.random();return l<.6?this.createHeatherPetal(e,o,n):l<.8?this.createHeather(e,o,n):l<.95?this.createSaltireSparkle(e,o,n):this.createThistle(e,o,n)},createThistlePlant(e,o,n={}){return{type:"thistle-plant",x:n.x!==void 0?n.x:Math.random()*e,y:n.y!==void 0?n.y:o-40,size:15+Math.random()*10,opacity:.8+Math.random()*.2,swayPhase:Math.random()*Math.PI*2,active:!0,static:!0}},createInitialDecorations(e,o,n){const l=[],a=n.thistles??5;for(let h=0;h<a;h++)l.push(this.createThistlePlant(e,o,{x:80+h/(a-1)*(e-160),y:o-60-Math.random()*30}));l.push({type:"bagpiper",x:150,y:o-60,baseY:o-60,vx:0,size:30+Math.random()*8,opacity:1,time:0,legPhase:0,bagInflate:.5,active:!0,static:!0}),l.push({type:"saltire-flag",x:e-100,y:80,size:60,opacity:1,wavePhase:Math.random()*Math.PI*2,active:!0,static:!0}),l.push({type:"tartan-pattern",x:e*.5,y:o-80,size:80+Math.random()*20,opacity:.9,active:!0,static:!0}),l.push({type:"highland-scene",x:e-200,y:o-150,size:100,opacity:.7,active:!0,static:!0});const t=n.twinklingStars??20;for(let h=0;h<t;h++)l.push(this.createTwinklingStar(e,o));return l},createTwinklingStar(e,o){return{type:"twinkling-star",x:Math.random()*e,y:Math.random()*(o*.6),size:1+Math.random()*2,opacity:.6+Math.random()*.3,twinklePhase:Math.random()*Math.PI*2,twinkleSpeed:.003+Math.random()*.003,active:!0,static:!0}},spawnSpecialParticle(e,o,n,l){const a=Math.random();if(a<l.bagpiperChance){if(e.some(h=>h.type==="bagpiper"))return null;const t=Math.random()<.5;return{type:"bagpiper",x:t?-60:o+60,y:n-50,vx:t?.8+Math.random()*.5:-(.8+Math.random()*.5),size:18+Math.random()*8,opacity:.9,time:0,marchPhase:Math.random()*Math.PI*2,active:!0,static:!1}}return a<4e-4&&e.filter(h=>h.type==="saltire-flag").length<2?{type:"saltire-flag",x:Math.random()*o*.6+o*.2,y:50+Math.random()*100,size:40+Math.random()*20,opacity:.8,waveOffset:Math.random()*Math.PI*2,time:0,active:!0,static:!1}:a<.01?this.createSaltireSparkle(o,n,l):null},drawHeatherPetal(e,o,n){const l=o.x,a=o.y,t=o.size,h=Math.sin(n*o.flutterSpeed+o.flutter)*.3;e.save(),e.globalAlpha=o.opacity,e.translate(l,a),e.rotate(o.rotation+h),e.fillStyle=o.color,e.strokeStyle="#6A0DAD",e.lineWidth=t*.08,e.beginPath(),e.moveTo(0,-t*.6),e.bezierCurveTo(t*.4,-t*.5,t*.5,t*.2,t*.3,t*.8),e.lineTo(-t*.3,t*.8),e.bezierCurveTo(-t*.5,t*.2,-t*.4,-t*.5,0,-t*.6),e.closePath(),e.fill(),e.stroke(),e.strokeStyle="rgba(106, 13, 173, 0.3)",e.lineWidth=t*.04;for(let s=0;s<4;s++){const r=-t*.5+s*t*.35;e.beginPath(),e.moveTo(-t*.25,r),e.lineTo(t*.25,r),e.stroke()}e.restore()},drawHeather(e,o){const n=o.x,l=o.y,a=o.size,t=Math.sin(o.sway)*a*.4;e.save(),e.globalAlpha=o.opacity,e.translate(n+t,l),e.rotate(o.rotation),e.strokeStyle="#6b5c4d",e.lineWidth=a*.12,e.lineCap="round",e.beginPath(),e.moveTo(0,a*.6),e.lineTo(0,-a*.8),e.stroke();const h=o.bellCount||4;for(let s=0;s<h;s++){const r=-a*.7+s/h*a*1.2,i=a*(.18+Math.random()*.08),d=s%2===0?1:-1;e.save(),e.translate(d*a*.15,r),e.rotate(d*.3);const y=e.createLinearGradient(0,-i,0,i*.3);y.addColorStop(0,o.color),y.addColorStop(.6,o.color),y.addColorStop(1,`${o.color}CC`),e.fillStyle=y,e.beginPath(),e.ellipse(0,0,i*.4,i,0,0,Math.PI*2),e.fill(),e.strokeStyle=`${o.color}AA`,e.lineWidth=i*.1,e.beginPath(),e.ellipse(0,i*.7,i*.35,i*.15,0,0,Math.PI*2),e.stroke(),e.strokeStyle="#8B7355",e.lineWidth=i*.08,e.beginPath(),e.moveTo(0,i*.8),e.lineTo(0,i*1.1),e.stroke(),e.restore()}e.fillStyle="#6b8b6b";for(let s=0;s<3;s++){const r=s/3*Math.PI*2-Math.PI/2;e.save(),e.rotate(r),e.beginPath(),e.ellipse(0,a*.5,a*.1,a*.25,0,0,Math.PI*2),e.fill(),e.restore()}e.restore()},drawThistle(e,o){const n=o.x,l=o.y,a=o.size;e.save(),e.globalAlpha=o.opacity,e.translate(n,l),e.rotate(o.rotation),e.strokeStyle="#5a704a",e.lineWidth=a*.1,e.lineCap="round",e.beginPath(),e.moveTo(0,a*2),e.quadraticCurveTo(a*.1,a*1.2,0,a*.5),e.stroke();const t=16;e.strokeStyle="#4a7a3a",e.fillStyle="#5a8a4a",e.lineWidth=a*.06,e.lineCap="round";for(let r=0;r<t;r++){const i=r/t*Math.PI*2,d=a*(.35+Math.random()*.15),y=i+(Math.random()-.5)*.3;e.save(),e.rotate(i),e.beginPath(),e.moveTo(0,-a*.2);const f=a*.15,M=-a*.3,m=Math.sin(.4)*d,g=-Math.cos(.4)*d-a*.2;e.quadraticCurveTo(f,M,m,g),e.stroke();for(let P=0;P<3;P++){const b=(P+1)/4,p=b*m,u=-a*.2+b*(g+a*.2);e.beginPath(),e.moveTo(p,u),e.lineTo(p+a*.08,u-a*.06),e.stroke()}e.restore()}e.fillStyle="#6a8a5a",e.beginPath(),e.ellipse(0,-a*.15,a*.28,a*.35,0,0,Math.PI*2),e.fill();const h=3,s=o.petalColors||["#9b59b6","#b980d1","#d4a5e3"];for(let r=0;r<h;r++){const i=a*(.25+r*.08),d=8+r*4,y=s[r];e.fillStyle=y;for(let f=0;f<d;f++){const M=f/d*Math.PI*2+r*.15,m=Math.cos(M)*i,g=Math.sin(M)*i-a*.15;e.save(),e.translate(m,g),e.rotate(M),e.beginPath(),e.moveTo(0,0),e.lineTo(0,-a*(.2+r*.05)),e.lineWidth=a*.02,e.strokeStyle=y,e.stroke(),e.restore()}}e.fillStyle="#4a6a3a",e.strokeStyle="#3a5a2a",e.lineWidth=1;for(let r=0;r<2;r++){const i=a*(.8+r*.6),d=r%2===0?1:-1;e.save(),e.translate(0,i),e.beginPath(),e.moveTo(0,0);const y=5,f=a*.15;for(let M=0;M<=y;M++){const m=M/y,g=a*.25*Math.sin(m*Math.PI);M<y?(e.lineTo(d*g*.3,-f*m),e.lineTo(d*(g+a*.08),-f*(m+.05)),e.lineTo(d*g*.7,-f*(m+.1))):e.lineTo(0,-f)}e.quadraticCurveTo(d*a*.05,-f*.5,0,0),e.closePath(),e.fill(),e.stroke(),e.strokeStyle="#2a4a1a",e.lineWidth=.5,e.beginPath(),e.moveTo(0,0),e.lineTo(0,-f),e.stroke(),e.restore()}e.restore()},drawThistlePlant(e,o,n){const l=o.x,a=o.y,t=o.size,h=Math.sin(n*.001+o.swayPhase)*.1;e.save(),e.globalAlpha=o.opacity,e.translate(l,a),e.rotate(h);for(let s=0;s<3;s++){const r=(s-1)*t*.4,i=t*(1.5+s*.3);e.strokeStyle="#8B4513",e.lineWidth=t*.1,e.beginPath(),e.moveTo(r,0),e.quadraticCurveTo(r+h*t,-i*.5,r,-i),e.stroke(),e.fillStyle="#8B008B",e.beginPath(),e.arc(r,-i,t*.4,0,Math.PI*2),e.fill();const d=8;e.strokeStyle="#8B008B",e.lineWidth=t*.05;for(let y=0;y<d;y++){const f=y/d*Math.PI*2;e.beginPath(),e.moveTo(r,-i),e.lineTo(r+Math.cos(f)*t*.6,-i+Math.sin(f)*t*.6),e.stroke()}}e.restore()},drawBagpiper:T,drawSaltireFlag(e,o,n){const l=o.x,a=o.y,t=o.size,h=n*.002+o.waveOffset;e.save(),e.globalAlpha=o.opacity,e.translate(l,a),e.fillStyle="#654321",e.fillRect(-t*.05,0,t*.1,t*1.5);const s=10,r=t*1.2,i=t*.8;e.fillStyle="#0065BD";for(let d=0;d<s;d++){const y=r/s,f=d*y,M=(d+1)*y,m=Math.sin(h+d*.3)*t*.1,g=Math.sin(h+(d+1)*.3)*t*.1;e.beginPath(),e.moveTo(f,m),e.lineTo(M,g),e.lineTo(M,i+g),e.lineTo(f,i+m),e.closePath(),e.fill()}e.strokeStyle="#FFFFFF",e.lineWidth=t*.12,e.shadowColor="rgba(255, 255, 255, 0.5)",e.shadowBlur=5;for(let d=0;d<s;d++){const y=r/s,f=d*y,M=(d+1)*y,m=Math.sin(h+d*.3)*t*.1,g=Math.sin(h+(d+1)*.3)*t*.1;e.beginPath(),e.moveTo(f,m),e.lineTo(M,i+g),e.stroke(),e.beginPath(),e.moveTo(f,i+m),e.lineTo(M,g),e.stroke()}e.shadowBlur=0,e.restore()},drawSaltireSparkle(e,o,n){const l=o.x,a=o.y,t=o.size,h=.6+Math.sin(n*.004+o.twinklePhase)*.4;e.save(),e.globalAlpha=o.opacity*h,e.translate(l,a),e.rotate(o.rotation),e.fillStyle=o.color,e.shadowColor=o.color,e.shadowBlur=t*2,e.beginPath(),e.moveTo(0,-t),e.lineTo(t*.3,-t*.3),e.lineTo(t,0),e.lineTo(t*.3,t*.3),e.lineTo(0,t),e.lineTo(-t*.3,t*.3),e.lineTo(-t,0),e.lineTo(-t*.3,-t*.3),e.closePath(),e.fill(),e.restore()},drawTartanPattern(e,o){const n=o.x,l=o.y,a=o.size;e.save(),e.globalAlpha=o.opacity,e.translate(n,l);const t=120,h=document.createElement("canvas");h.width=t,h.height=t;const s=h.getContext("2d"),r="#1a237e",i="#c62828",d="#1b5e20",y="#f9a825",f="#ffffff",M="#000000",m=[[4,i],[2,M],[2,i],[2,M],[4,i],[8,r],[2,M],[2,r],[2,M],[8,r],[2,d],[2,y],[2,d],[8,r],[2,M],[2,r],[2,M],[8,r],[4,i],[2,M],[2,i],[2,M],[4,i]];let g=0;for(let p=0;p<2;p++)for(const[u,S]of m)s.fillStyle=S,s.fillRect(0,g,t,u),g+=u;s.globalCompositeOperation="multiply",s.globalAlpha=.8;let P=0;for(let p=0;p<2;p++)for(const[u,S]of m)s.fillStyle=S,s.fillRect(P,0,u,t),P+=u;s.globalCompositeOperation="lighten",s.globalAlpha=.15,P=0;for(let p=0;p<2;p++)for(const[u,S]of m)(S===y||S===f)&&(s.fillStyle=f,s.fillRect(P,0,u,t)),P+=u;s.globalCompositeOperation="source-over",s.globalAlpha=1;const b=e.createPattern(h,"repeat");e.fillStyle=b,e.fillRect(-a/2,-a/2,a,a),e.strokeStyle="#2a2a2a",e.lineWidth=a*.03,e.strokeRect(-a/2,-a/2,a,a),e.strokeStyle="#e0e0e0",e.lineWidth=a*.015,e.strokeRect(-a/2+a*.04,-a/2+a*.04,a-a*.08,a-a*.08),e.strokeStyle="rgba(255, 255, 255, 0.1)",e.lineWidth=.5;for(let p=-a;p<a;p+=4)e.beginPath(),e.moveTo(-a/2+p,-a/2),e.lineTo(-a/2+p+a,a/2),e.stroke();e.save(),e.translate(-a*.35,-a*.35),e.fillStyle="#c0c0c0",e.strokeStyle="#808080",e.lineWidth=2,e.beginPath(),e.arc(0,0,a*.08,0,Math.PI*2),e.fill(),e.stroke(),e.scale(.06,.06),e.fillStyle="#8B008B",e.strokeStyle="#6A006A",e.lineWidth=2;for(let p=0;p<6;p++){const u=p/6*Math.PI*2;e.beginPath(),e.moveTo(0,0),e.lineTo(Math.cos(u)*a*.4,Math.sin(u)*a*.4),e.stroke()}e.beginPath(),e.arc(0,0,a*.15,0,Math.PI*2),e.fill(),e.restore(),e.restore()},drawHighlandScene(e,o){const n=o.x,l=o.y,a=o.size;e.save(),e.globalAlpha=o.opacity,e.translate(n,l);const t=e.createLinearGradient(0,-a,0,a*.5);t.addColorStop(0,"#4a7ba7"),t.addColorStop(1,"#b0c4de"),e.fillStyle=t,e.fillRect(-a,-a,a*2,a*1.5),e.fillStyle="rgba(80, 100, 130, 0.6)",e.beginPath(),e.moveTo(-a,a*.3),e.lineTo(-a*.6,-a*.3),e.lineTo(-a*.2,a*.1),e.lineTo(a*.2,-a*.5),e.lineTo(a*.6,a*.2),e.lineTo(a,a*.3),e.closePath(),e.fill(),e.fillStyle="rgba(60, 80, 100, 0.8)",e.beginPath(),e.moveTo(-a,a*.4),e.lineTo(-a*.7,a*.1),e.lineTo(-a*.3,-a*.1),e.lineTo(a*.1,-a*.2),e.lineTo(a*.5,a*.15),e.lineTo(a,a*.4),e.closePath(),e.fill(),e.fillStyle="#2a3a4a",e.fillRect(-a*.15,a*.25,a*.3,a*.2),e.fillRect(-a*.2,a*.15,a*.1,a*.15),e.fillRect(a*.1,a*.15,a*.1,a*.15),e.fillRect(-a*.06,a*.05,a*.12,a*.25);for(let s=0;s<5;s++)s%2===0&&e.fillRect(-a*.06+s*a*.06,a*.02,a*.03,a*.03);const h=e.createLinearGradient(0,a*.45,0,a*.6);h.addColorStop(0,"#1e3a5f"),h.addColorStop(1,"#0a1f3d"),e.fillStyle=h,e.fillRect(-a,a*.45,a*2,a*.15),e.globalAlpha=o.opacity*.3,e.fillStyle="#4a6a8a",e.fillRect(-a*.15,a*.48,a*.3,a*.08),e.globalAlpha=o.opacity*.2,e.fillStyle="#d0e0f0",e.fillRect(-a,a*.5,a*2,a*.05),e.restore()},drawTwinklingStar(e,o,n){const l=o.x,a=o.y,t=o.size,h=.5+Math.sin(n*o.twinkleSpeed+o.twinklePhase)*.5,s=`rgba(200, 220, 255, ${h})`,r=`rgba(150, 180, 255, ${h*.4})`;e.save(),e.translate(l,a),e.shadowColor=r,e.shadowBlur=t*3*h,e.fillStyle=s,e.beginPath();for(let i=0;i<4;i++){const d=i*Math.PI/2,y=Math.cos(d)*t,f=Math.sin(d)*t,M=d+Math.PI/4,m=Math.cos(M)*(t*.3),g=Math.sin(M)*(t*.3);i===0?e.moveTo(y,f):e.lineTo(y,f),e.lineTo(m,g)}e.closePath(),e.fill(),e.shadowBlur=t*2*h,e.beginPath(),e.arc(0,0,t*.25,0,Math.PI*2),e.fill(),e.restore()}};
1
+ import{drawTartanPattern as w,drawHighlandScene as g}from"./heritage-drawing.js";import{drawHeather as f,drawThistle as P,drawThistlePlant as S}from"./botanical-drawing.js";import{drawBagpiper as z}from"./character-drawing.js";export default{name:"st-andrews",displayName:"St Andrew's Day",emoji:"\u{1F3F4}\u{E0067}\u{E0062}\u{E0073}\u{E0063}\u{E0074}\u{E007F}",intensityConfig:{light:{count:50,speedRange:[.5,1.5],sizeRange:[2,4],thistles:4,bagpiperChance:2e-4,twinklingStars:12},medium:{count:100,speedRange:[.6,2],sizeRange:[2,5],thistles:6,bagpiperChance:4e-4,twinklingStars:20},heavy:{count:200,speedRange:[.8,2.5],sizeRange:[3,6],thistles:8,bagpiperChance:6e-4,twinklingStars:30}},particles:["heather-petal","heather","saltire-sparkle"],decorations:["thistle-plant","bagpiper","saltire-flag","tartan-pattern","highland-scene","twinkling-star"],colors:{primary:"#0065BD",secondary:"#FFFFFF",accent:"#8B008B",tartan:["#0065BD","#006400","#8B0000","#FFDD00"]},createHeatherPetal(e,t,r){const o=["#9370DB","#BA55D3","#DA70D6","#DDA0DD","#8B008B"];return{type:"heather-petal",x:Math.random()*e,y:Math.random()*t,vx:r.speedRange[0]+Math.random()*(r.speedRange[1]-r.speedRange[0]),size:(r.sizeRange[0]+Math.random()*(r.sizeRange[1]-r.sizeRange[0]))*1.5,speed:(Math.random()-.5)*.2,opacity:.75+Math.random()*.25,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.02,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.03,color:o[Math.floor(Math.random()*o.length)],flutter:Math.random()*Math.PI*2,flutterSpeed:.02+Math.random()*.02,active:!0}},createThistle(e,t,r){const o=Math.random()<.5,s=o?"#FFFFFF":"#0065BD",a=o?["#FFFFFF","#f0f0f0","#e0e0e0"]:["#0065BD","#1a7dd4","#3399ee"];return{type:"thistle",x:Math.random()*e,y:Math.random()*t,vx:r.speedRange[0]+Math.random()*(r.speedRange[1]-r.speedRange[0])*.7,size:r.sizeRange[0]+Math.random()*(r.sizeRange[1]-r.sizeRange[0]),speed:(Math.random()-.5)*.15,opacity:.7+Math.random()*.3,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.02,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.02,flowerColor:s,petalColors:a,active:!0}},createHeather(e,t,r){const o=Math.random();let s;return o<.5?s="#9370DB":o<.8?s="#BA55D3":s="#DA70D6",{type:"heather",x:Math.random()*e,y:Math.random()*t,vx:(r.speedRange[0]+Math.random()*(r.speedRange[1]-r.speedRange[0]))*.6,size:r.sizeRange[0]+Math.random()*(r.sizeRange[1]-r.sizeRange[0]),speed:(Math.random()-.5)*.15,opacity:.75+Math.random()*.25,windOffset:Math.random()*Math.PI*2,windSpeed:.02+Math.random()*.02,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.03,color:s,sway:Math.random()*Math.PI*2,swaySpeed:.02+Math.random()*.02,bellCount:3+Math.floor(Math.random()*3),active:!0}},createSaltireSparkle(e,t,r){const o=["#0065BD","#FFFFFF"];return{type:"saltire-sparkle",x:Math.random()*e,y:Math.random()*t,vx:(r.speedRange[0]+Math.random()*(r.speedRange[1]-r.speedRange[0]))*.8,size:r.sizeRange[0]+Math.random()*(r.sizeRange[1]-r.sizeRange[0])*.6,vy:(Math.random()-.5)*.2,opacity:.6+Math.random()*.4,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.04,color:o[Math.floor(Math.random()*o.length)],twinklePhase:Math.random()*Math.PI*2,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.02,active:!0,static:!1}},createFallingParticle(e,t,r){const o=Math.random();return o<.6?this.createHeatherPetal(e,t,r):o<.8?this.createHeather(e,t,r):o<.95?this.createSaltireSparkle(e,t,r):this.createThistle(e,t,r)},createThistlePlant(e,t,r={}){return{type:"thistle-plant",x:r.x!==void 0?r.x:Math.random()*e,y:r.y!==void 0?r.y:t-40,size:15+Math.random()*10,opacity:.8+Math.random()*.2,swayPhase:Math.random()*Math.PI*2,active:!0,static:!0}},createInitialDecorations(e,t,r){const o=[],s=r.thistles??5;for(let n=0;n<s;n++)o.push(this.createThistlePlant(e,t,{x:80+n/(s-1)*(e-160),y:t-60-Math.random()*30}));o.push({type:"bagpiper",x:150,y:t-60,baseY:t-60,vx:0,size:30+Math.random()*8,opacity:1,time:0,legPhase:0,bagInflate:.5,active:!0,static:!0}),o.push({type:"saltire-flag",x:e-100,y:80,size:60,opacity:1,wavePhase:Math.random()*Math.PI*2,active:!0,static:!0}),o.push({type:"tartan-pattern",x:e*.5,y:t-80,size:80+Math.random()*20,opacity:.9,active:!0,static:!0}),o.push({type:"highland-scene",x:e-200,y:t-150,size:100,opacity:.7,active:!0,static:!0});const a=r.twinklingStars??20;for(let n=0;n<a;n++)o.push(this.createTwinklingStar(e,t));return o},createTwinklingStar(e,t){return{type:"twinkling-star",x:Math.random()*e,y:Math.random()*(t*.6),size:1+Math.random()*2,opacity:.6+Math.random()*.3,twinklePhase:Math.random()*Math.PI*2,twinkleSpeed:.003+Math.random()*.003,active:!0,static:!0}},spawnSpecialParticle(e,t,r,o){const s=Math.random();if(s<o.bagpiperChance){if(e.some(n=>n.type==="bagpiper"))return null;const a=Math.random()<.5;return{type:"bagpiper",x:a?-60:t+60,y:r-50,vx:a?.8+Math.random()*.5:-(.8+Math.random()*.5),size:18+Math.random()*8,opacity:.9,time:0,marchPhase:Math.random()*Math.PI*2,active:!0,static:!1}}return s<4e-4&&e.filter(n=>n.type==="saltire-flag").length<2?{type:"saltire-flag",x:Math.random()*t*.6+t*.2,y:50+Math.random()*100,size:40+Math.random()*20,opacity:.8,waveOffset:Math.random()*Math.PI*2,time:0,active:!0,static:!1}:s<.01?this.createSaltireSparkle(t,r,o):null},drawHeatherPetal(e,t,r){const o=t.x,s=t.y,a=t.size,n=Math.sin(r*t.flutterSpeed+t.flutter)*.3;e.save(),e.globalAlpha=t.opacity,e.translate(o,s),e.rotate(t.rotation+n),e.fillStyle=t.color,e.strokeStyle="#6A0DAD",e.lineWidth=a*.08,e.beginPath(),e.moveTo(0,-a*.6),e.bezierCurveTo(a*.4,-a*.5,a*.5,a*.2,a*.3,a*.8),e.lineTo(-a*.3,a*.8),e.bezierCurveTo(-a*.5,a*.2,-a*.4,-a*.5,0,-a*.6),e.closePath(),e.fill(),e.stroke(),e.strokeStyle="rgba(106, 13, 173, 0.3)",e.lineWidth=a*.04;for(let l=0;l<4;l++){const p=-a*.5+l*a*.35;e.beginPath(),e.moveTo(-a*.25,p),e.lineTo(a*.25,p),e.stroke()}e.restore()},drawHeather:f,drawThistle:P,drawThistlePlant:S,drawBagpiper:z,drawSaltireFlag(e,t,r){const o=t.x,s=t.y,a=t.size,n=r*.002+t.waveOffset;e.save(),e.globalAlpha=t.opacity,e.translate(o,s),e.fillStyle="#654321",e.fillRect(-a*.05,0,a*.1,a*1.5);const l=10,p=a*1.2,h=a*.8;e.fillStyle="#0065BD";for(let i=0;i<l;i++){const d=p/l,M=i*d,m=(i+1)*d,y=Math.sin(n+i*.3)*a*.1,u=Math.sin(n+(i+1)*.3)*a*.1;e.beginPath(),e.moveTo(M,y),e.lineTo(m,u),e.lineTo(m,h+u),e.lineTo(M,h+y),e.closePath(),e.fill()}e.strokeStyle="#FFFFFF",e.lineWidth=a*.12,e.shadowColor="rgba(255, 255, 255, 0.5)",e.shadowBlur=5;for(let i=0;i<l;i++){const d=p/l,M=i*d,m=(i+1)*d,y=Math.sin(n+i*.3)*a*.1,u=Math.sin(n+(i+1)*.3)*a*.1;e.beginPath(),e.moveTo(M,y),e.lineTo(m,h+u),e.stroke(),e.beginPath(),e.moveTo(M,h+y),e.lineTo(m,u),e.stroke()}e.shadowBlur=0,e.restore()},drawSaltireSparkle(e,t,r){const o=t.x,s=t.y,a=t.size,n=.6+Math.sin(r*.004+t.twinklePhase)*.4;e.save(),e.globalAlpha=t.opacity*n,e.translate(o,s),e.rotate(t.rotation),e.fillStyle=t.color,e.shadowColor=t.color,e.shadowBlur=a*2,e.beginPath(),e.moveTo(0,-a),e.lineTo(a*.3,-a*.3),e.lineTo(a,0),e.lineTo(a*.3,a*.3),e.lineTo(0,a),e.lineTo(-a*.3,a*.3),e.lineTo(-a,0),e.lineTo(-a*.3,-a*.3),e.closePath(),e.fill(),e.restore()},drawTartanPattern:w,drawHighlandScene:g,drawTwinklingStar(e,t,r){const o=t.x,s=t.y,a=t.size,n=.5+Math.sin(r*t.twinkleSpeed+t.twinklePhase)*.5,l=`rgba(200, 220, 255, ${n})`,p=`rgba(150, 180, 255, ${n*.4})`;e.save(),e.translate(o,s),e.shadowColor=p,e.shadowBlur=a*3*n,e.fillStyle=l,e.beginPath();for(let h=0;h<4;h++){const i=h*Math.PI/2,d=Math.cos(i)*a,M=Math.sin(i)*a,m=i+Math.PI/4,y=Math.cos(m)*(a*.3),u=Math.sin(m)*(a*.3);h===0?e.moveTo(d,M):e.lineTo(d,M),e.lineTo(y,u)}e.closePath(),e.fill(),e.shadowBlur=a*2*n,e.beginPath(),e.arc(0,0,a*.25,0,Math.PI*2),e.fill(),e.restore()}};
@@ -1 +1 @@
1
- import{drawWelshDragon as y}from"./character-drawing.js";export default{name:"st-davids",displayName:"St David's Day",emoji:"\u{1F33B}",intensityConfig:{light:{count:50,speedRange:[.4,1.2],sizeRange:[2,4],daffodilFields:2,dragonChance:2e-4,twinklingStars:10},medium:{count:100,speedRange:[.5,1.5],sizeRange:[2,5],daffodilFields:3,dragonChance:4e-4,twinklingStars:18},heavy:{count:150,speedRange:[.6,1.8],sizeRange:[3,6],daffodilFields:4,dragonChance:6e-4,twinklingStars:25}},particles:["daffodil-petal","daffodil","spring-sparkle"],decorations:["daffodil-field","welsh-dragon","flag","harp","leek-bundle","twinkling-star"],colors:{primary:"#FFDD00",secondary:"#228B22",accent:"#DC143C",white:"#FFFFFF"},createDaffodilPetal(e,l,i){const r=["#FFDD00","#FFE135","#FFED4E","#FFF68F"];return{type:"daffodil-petal",x:-30,y:Math.random()*l,vx:i.speedRange[0]+Math.random()*(i.speedRange[1]-i.speedRange[0]),size:(i.sizeRange[0]+Math.random()*(i.sizeRange[1]-i.sizeRange[0]))*1.5,speed:(Math.random()-.5)*.2,opacity:.75+Math.random()*.25,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.02,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.03,color:r[Math.floor(Math.random()*r.length)],flutter:Math.random()*Math.PI*2,flutterSpeed:.02+Math.random()*.02,active:!0}},createDaffodil(e,l,i){return{type:"daffodil",x:-30,y:Math.random()*l,vx:i.speedRange[0]+Math.random()*(i.speedRange[1]-i.speedRange[0]),size:i.sizeRange[0]+Math.random()*(i.sizeRange[1]-i.sizeRange[0]),speed:.1,opacity:.8+Math.random()*.2,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.02,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.02,active:!0}},createLeek(e,l,i){return{type:"leek",x:-30,y:Math.random()*l,vx:(i.speedRange[0]+Math.random()*(i.speedRange[1]-i.speedRange[0]))*.8,size:i.sizeRange[0]+Math.random()*(i.sizeRange[1]-i.sizeRange[0])*1.2,speed:.15,opacity:.7+Math.random()*.3,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.03,windOffset:Math.random()*Math.PI*2,windSpeed:.02+Math.random()*.03,active:!0}},createSpringSparkle(e,l,i){const r=["#FFD700","#FFFFFF","#90EE90","#98FB98"];return{type:"spring-sparkle",x:-20,y:Math.random()*l,vx:(i.speedRange[0]+Math.random()*(i.speedRange[1]-i.speedRange[0]))*.8,size:i.sizeRange[0]+Math.random()*(i.sizeRange[1]-i.sizeRange[0])*.6,vy:(Math.random()-.5)*.2,opacity:.6+Math.random()*.4,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.04,color:r[Math.floor(Math.random()*r.length)],twinklePhase:Math.random()*Math.PI*2,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.02,active:!0,static:!1}},createFallingParticle(e,l,i){const r=Math.random();return r<.6?this.createDaffodilPetal(e,l,i):r<.8?this.createDaffodil(e,l,i):r<.95?this.createSpringSparkle(e,l,i):this.createLeek(e,l,i)},createDaffodilField(e,l,i={}){const r=[],o=15+Math.floor(Math.random()*10);for(let a=0;a<o;a++)r.push({x:Math.random()*e*.3,y:Math.random()*40,size:5+Math.random()*8,swayPhase:Math.random()*Math.PI*2});return{type:"daffodil-field",x:i.x!==void 0?i.x:Math.random()*e*.7,y:i.y!==void 0?i.y:l-50,flowers:r,opacity:.9,time:0,active:!0,static:!0}},createInitialDecorations(e,l,i){const r=[],o=i.daffodilFields??3;for(let n=0;n<o;n++)r.push(this.createDaffodilField(e,l,{x:e/(o+1)*(n+1),y:l-50}));r.push({type:"welsh-dragon",x:150,y:l-80,baseY:l-80,vx:0,size:35+Math.random()*10,opacity:1,time:0,wingPhase:Math.random()*Math.PI*2,breatheFirePhase:Math.random()*Math.PI*2,active:!0,static:!0}),r.push({type:"harp",x:e-200,y:l-90,size:40+Math.random()*10,opacity:1,glintPhase:Math.random()*Math.PI*2,active:!0,static:!0}),r.push({type:"leek-bundle",x:e*.3,y:l-40,size:25+Math.random()*5,opacity:1,active:!0,static:!0}),r.push({type:"flag",x:e-100,y:80,size:50,opacity:1,wavePhase:Math.random()*Math.PI*2,active:!0,static:!0});const a=i.twinklingStars??18;for(let n=0;n<a;n++)r.push(this.createTwinklingStar(e,l));return r},createTwinklingStar(e,l){return{type:"twinkling-star",x:Math.random()*e,y:Math.random()*(l*.5),size:1+Math.random()*2,opacity:.6+Math.random()*.3,twinklePhase:Math.random()*Math.PI*2,twinkleSpeed:.003+Math.random()*.003,active:!0,static:!0}},spawnSpecialParticle(e,l,i,r){const o=Math.random();if(o<r.dragonChance){if(e.some(n=>n.type==="welsh-dragon"))return null;const a=Math.random()<.5;return{type:"welsh-dragon",x:a?-100:l+100,y:Math.random()*i*.4+50,baseY:Math.random()*i*.4+50,vx:a?2+Math.random()*1:-(2+Math.random()*1),size:25+Math.random()*15,opacity:1,waveAmplitude:25+Math.random()*20,waveFrequency:.002+Math.random()*.002,waveOffset:Math.random()*Math.PI*2,time:0,wingPhase:Math.random()*Math.PI*2,breatheFirePhase:Math.random()*Math.PI*2,fireParticles:[],active:!0,static:!1}}return o<4e-4&&e.filter(n=>n.type==="daffodil-field").length<r.daffodilFields?this.createDaffodilField(l,i):null},drawDaffodilPetal(e,l,i){const r=l.x,o=l.y,a=l.size,n=Math.sin(i*l.flutterSpeed+l.flutter)*.3;e.save(),e.globalAlpha=l.opacity,e.translate(r,o),e.rotate(l.rotation+n),e.fillStyle=l.color,e.strokeStyle="#FFB700",e.lineWidth=a*.08,e.beginPath(),e.ellipse(0,0,a*.6,a*1.2,0,0,Math.PI*2),e.fill(),e.stroke(),e.strokeStyle="rgba(255, 200, 0, 0.4)",e.lineWidth=a*.06,e.beginPath(),e.moveTo(0,-a*1.1),e.lineTo(0,a*1.1),e.stroke(),e.restore()},drawDaffodil(e,l){const i=l.x,r=l.y,o=l.size;e.save(),e.globalAlpha=l.opacity,e.translate(i,r),e.rotate(l.rotation),e.fillStyle="#FFA500",e.strokeStyle="#FF8C00",e.lineWidth=o*.08,e.beginPath(),e.moveTo(-o*.25,0),e.lineTo(-o*.3,o*.3),e.lineTo(o*.3,o*.3),e.lineTo(o*.25,0),e.closePath(),e.fill(),e.stroke(),e.fillStyle="#FFDD00",e.strokeStyle="#FFC700",e.lineWidth=o*.06;for(let a=0;a<6;a++){const n=a/6*Math.PI*2-Math.PI/2;e.save(),e.rotate(n),e.translate(0,-o*.7),e.beginPath(),e.ellipse(0,0,o*.4,o*.6,0,0,Math.PI*2),e.fill(),e.stroke(),e.restore()}e.strokeStyle="#228B22",e.lineWidth=o*.12,e.beginPath(),e.moveTo(0,o*.3),e.lineTo(0,o*1.5),e.stroke(),e.restore()},drawLeek(e,l){const i=l.x,r=l.y,o=l.size;e.save(),e.globalAlpha=l.opacity,e.translate(i,r),e.rotate(l.rotation),e.fillStyle="#F5F5F5",e.strokeStyle="#DCDCDC",e.lineWidth=o*.08,e.beginPath(),e.ellipse(0,o*1.2,o*.4,o*.5,0,0,Math.PI*2),e.fill(),e.stroke(),e.fillStyle="#228B22",e.strokeStyle="#006400",e.lineWidth=o*.05,e.beginPath(),e.moveTo(-o*.3,o*1.2),e.quadraticCurveTo(-o*.25,o*.5,-o*.15,0),e.quadraticCurveTo(0,-o*.2,o*.15,0),e.quadraticCurveTo(o*.25,o*.5,o*.3,o*1.2),e.closePath(),e.fill(),e.stroke(),e.beginPath(),e.moveTo(-o*.15,0),e.quadraticCurveTo(-o*.6,-o*.3,-o*.8,0),e.stroke(),e.beginPath(),e.moveTo(o*.15,0),e.quadraticCurveTo(o*.6,-o*.3,o*.8,0),e.stroke(),e.strokeStyle="#D2B48C",e.lineWidth=o*.05;for(let a=0;a<5;a++){const n=(a-2)*o*.15;e.beginPath(),e.moveTo(n,o*1.5),e.lineTo(n+Math.sin(a*1.7)*o*.15,o*1.8),e.stroke()}e.restore()},drawSpringSparkle(e,l,i){const r=l.x,o=l.y,a=l.size,n=.6+Math.sin(i*.004+l.twinklePhase)*.4;e.save(),e.globalAlpha=l.opacity*n,e.translate(r,o),e.rotate(l.rotation),e.fillStyle=l.color,e.shadowColor=l.color,e.shadowBlur=a*2,e.beginPath(),e.moveTo(0,-a),e.lineTo(a*.3,-a*.3),e.lineTo(a,0),e.lineTo(a*.3,a*.3),e.lineTo(0,a),e.lineTo(-a*.3,a*.3),e.lineTo(-a,0),e.lineTo(-a*.3,-a*.3),e.closePath(),e.fill(),e.restore()},drawDaffodilField(e,l,i){const r=l.x,o=l.y;e.save(),e.globalAlpha=l.opacity,l.flowers.forEach(a=>{const n=Math.sin(i*.001+a.swayPhase)*a.size*.2;e.save(),e.translate(r+a.x,o-a.y),e.rotate(n*.1),e.strokeStyle="#228B22",e.lineWidth=a.size*.08,e.beginPath(),e.moveTo(0,0),e.lineTo(n,-a.size*2),e.stroke(),e.fillStyle="#FFDD00",e.shadowColor="#FFDD00",e.shadowBlur=a.size*.5,e.beginPath(),e.arc(n,-a.size*2,a.size*.5,0,Math.PI*2),e.fill(),e.shadowBlur=0,e.fillStyle="#FFA500",e.beginPath(),e.arc(n,-a.size*2,a.size*.25,0,Math.PI*2),e.fill(),e.restore()}),e.restore()},drawWelshDragon:y,drawHarp(e,l,i){const r=l.x,o=l.y,a=l.size;e.save(),e.globalAlpha=l.opacity,e.translate(r,o),e.strokeStyle="#8b4513",e.lineWidth=a*.08,e.lineCap="round",e.beginPath(),e.moveTo(-a*.3,a*.5),e.bezierCurveTo(-a*.5,a*.1,-a*.4,-a*.4,-a*.2,-a*.7),e.stroke(),e.beginPath(),e.moveTo(-a*.2,-a*.7),e.lineTo(a*.4,-a*.5),e.stroke(),e.beginPath(),e.moveTo(a*.4,-a*.5),e.lineTo(-a*.3,a*.5),e.stroke(),e.strokeStyle="#FFD700",e.lineWidth=a*.02;const n=12;for(let t=0;t<n;t++){const s=t/(n-1),h=-a*.3+s*a*.65,d=a*.5-s*a*1,P=-a*.25+s*a*.55,f=-a*.65+s*a*.15,M=Math.sin(i*.003+t*.3+l.glintPhase)*a*.02;e.beginPath(),e.moveTo(h+M,d),e.lineTo(P+M,f),e.stroke()}e.strokeStyle="#654321",e.lineWidth=a*.03,e.globalAlpha=.6;for(let t=0;t<4;t++){const s=a*.3-t*a*.25;e.beginPath(),e.arc(-a*.35,s,a*.08,0,Math.PI*2),e.stroke()}e.restore()},drawLeekBundle(e,l){const i=l.x,r=l.y,o=l.size;e.save(),e.globalAlpha=l.opacity,e.translate(i,r);for(let a=0;a<5;a++){e.save();const n=(a-2)*o*.15,t=(a-2)*.1;e.translate(n,0),e.rotate(t),e.fillStyle="#f5f5dc",e.strokeStyle="#d3d3c0",e.lineWidth=1,e.fillRect(-o*.08,o*.2,o*.16,o*.6),e.strokeRect(-o*.08,o*.2,o*.16,o*.6),e.fillStyle="#228B22",e.strokeStyle="#1a6b1a",e.beginPath(),e.moveTo(-o*.08,o*.2),e.lineTo(-o*.12,-o*.5),e.lineTo(0,-o*.7),e.lineTo(o*.12,-o*.5),e.lineTo(o*.08,o*.2),e.closePath(),e.fill(),e.stroke(),e.strokeStyle="#1a5a1a",e.lineWidth=.5,e.beginPath(),e.moveTo(0,o*.2),e.lineTo(0,-o*.65),e.stroke(),e.restore()}e.fillStyle="#DC143C",e.fillRect(-o*.5,o*.4,o,o*.12),e.beginPath(),e.ellipse(-o*.6,o*.46,o*.12,o*.08,0,0,Math.PI*2),e.fill(),e.beginPath(),e.ellipse(o*.6,o*.46,o*.12,o*.08,0,0,Math.PI*2),e.fill(),e.restore()},drawFlag(e,l,i){const r=l.x,o=l.y,a=l.size;e.save(),e.globalAlpha=l.opacity,e.translate(r,o),e.strokeStyle="#654321",e.lineWidth=a*.04,e.beginPath(),e.moveTo(0,0),e.lineTo(0,a*1.5),e.stroke();const n=Math.sin(i*.003+l.wavePhase)*a*.08;e.fillStyle="#FFFFFF",e.beginPath(),e.moveTo(0,0),e.bezierCurveTo(a*.3,0+n*.5,a*.6,0-n*.5,a*.9,0+n),e.lineTo(a*.9,a*.3+n),e.bezierCurveTo(a*.6,a*.3-n*.5,a*.3,a*.3+n*.5,0,a*.3),e.closePath(),e.fill(),e.fillStyle="#00B140",e.beginPath(),e.moveTo(0,a*.3),e.bezierCurveTo(a*.3,a*.3+n*.5,a*.6,a*.3-n*.5,a*.9,a*.3+n),e.lineTo(a*.9,a*.6+n),e.bezierCurveTo(a*.6,a*.6-n*.5,a*.3,a*.6+n*.5,0,a*.6),e.closePath(),e.fill(),e.fillStyle="#DC143C",e.save(),e.translate(a*.45,a*.3),e.scale(.28,.28),e.beginPath(),e.ellipse(a*.1,0,a*.45,a*.3,-.2,0,Math.PI*2),e.fill(),e.beginPath(),e.ellipse(a*.4,-a*.25,a*.22,a*.15,.3,0,Math.PI*2),e.fill(),e.beginPath(),e.ellipse(-a*.25,a*.1,a*.35,a*.28,.1,0,Math.PI*2),e.fill(),e.beginPath(),e.ellipse(a*.65,-a*.28,a*.2,a*.12,0,0,Math.PI*2),e.fill(),e.beginPath(),e.moveTo(a*.55,-a*.32),e.bezierCurveTo(a*.7,-a*.38,a*.85,-a*.35,a*.88,-a*.28),e.lineTo(a*.82,-a*.25),e.bezierCurveTo(a*.78,-a*.28,a*.65,-a*.3,a*.55,-a*.28),e.closePath(),e.fill(),e.beginPath(),e.moveTo(a*.58,-a*.24),e.bezierCurveTo(a*.72,-a*.22,a*.84,-a*.24,a*.87,-a*.28),e.lineTo(a*.82,-a*.3),e.bezierCurveTo(a*.75,-a*.27,a*.65,-a*.26,a*.58,-a*.27),e.closePath(),e.fill(),e.fillStyle="#FFFF00",e.beginPath(),e.ellipse(a*.58,-a*.32,a*.04,a*.05,.2,0,Math.PI*2),e.fill(),e.fillStyle="#DC143C",e.beginPath(),e.moveTo(a*.5,-a*.38),e.bezierCurveTo(a*.48,-a*.55,a*.52,-a*.65,a*.58,-a*.68),e.lineTo(a*.62,-a*.64),e.bezierCurveTo(a*.58,-a*.62,a*.54,-a*.52,a*.54,-a*.38),e.closePath(),e.fill(),e.beginPath(),e.moveTo(a*.48,-a*.4),e.bezierCurveTo(a*.42,-a*.58,a*.38,-a*.68,a*.35,-a*.72),e.lineTo(a*.38,-a*.74),e.bezierCurveTo(a*.42,-a*.7,a*.46,-a*.58,a*.5,-a*.42),e.closePath(),e.fill(),e.globalAlpha=.9,e.beginPath(),e.moveTo(-a*.1,-a*.15),e.bezierCurveTo(-a*.3,-a*.5,-a*.35,-a*.75,-a*.25,-a*.85),e.lineTo(-a*.22,-a*.82),e.bezierCurveTo(-a*.1,-a*.85,0,-a*.9,a*.1,-a*.88),e.lineTo(a*.12,-a*.84),e.bezierCurveTo(a*.2,-a*.8,a*.28,-a*.72,a*.3,-a*.62),e.lineTo(a*.25,-a*.58),e.bezierCurveTo(a*.22,-a*.5,a*.18,-a*.35,a*.1,-a*.25),e.lineTo(0,-a*.2),e.closePath(),e.fill(),e.beginPath(),e.moveTo(a*.15,-a*.2),e.bezierCurveTo(a*.3,-a*.55,a*.45,-a*.78,a*.6,-a*.82),e.lineTo(a*.62,-a*.78),e.bezierCurveTo(a*.7,-a*.75,a*.8,-a*.68,a*.85,-a*.58),e.lineTo(a*.82,-a*.54),e.bezierCurveTo(a*.75,-a*.52,a*.68,-a*.45,a*.6,-a*.38),e.lineTo(a*.55,-a*.35),e.bezierCurveTo(a*.45,-a*.3,a*.32,-a*.25,a*.2,-a*.22),e.closePath(),e.fill(),e.globalAlpha=1,e.beginPath(),e.ellipse(a*.25,a*.15,a*.12,a*.25,.5,0,Math.PI*2),e.fill(),e.beginPath(),e.moveTo(a*.32,a*.35),e.lineTo(a*.38,a*.55),e.lineTo(a*.42,a*.57),e.lineTo(a*.36,a*.37),e.closePath(),e.fill();for(let s=0;s<3;s++){e.beginPath();const h=a*.36+s*a*.04;e.moveTo(h,a*.55),e.lineTo(h+a*.02,a*.63),e.lineTo(h+a*.04,a*.55),e.closePath(),e.fill()}e.globalAlpha=.85,e.beginPath(),e.ellipse(a*.15,a*.12,a*.1,a*.22,.3,0,Math.PI*2),e.fill(),e.beginPath(),e.moveTo(a*.18,a*.3),e.lineTo(a*.2,a*.48),e.lineTo(a*.24,a*.5),e.lineTo(a*.22,a*.32),e.closePath(),e.fill(),e.globalAlpha=1,e.beginPath(),e.ellipse(-a*.15,a*.25,a*.15,a*.28,.8,0,Math.PI*2),e.fill(),e.beginPath(),e.moveTo(-a*.08,a*.48),e.lineTo(-a*.02,a*.65),e.lineTo(a*.02,a*.67),e.lineTo(-a*.04,a*.5),e.closePath(),e.fill();for(let s=0;s<3;s++){e.beginPath();const h=-a*.04+s*a*.04;e.moveTo(h,a*.65),e.lineTo(h+a*.02,a*.72),e.lineTo(h+a*.04,a*.65),e.closePath(),e.fill()}e.globalAlpha=.85,e.beginPath(),e.ellipse(-a*.28,a*.22,a*.13,a*.25,.6,0,Math.PI*2),e.fill(),e.globalAlpha=1,e.beginPath(),e.moveTo(-a*.5,a*.05),e.bezierCurveTo(-a*.75,a*.15,-a*.95,0,-a*1.05,-a*.3),e.bezierCurveTo(-a*1.1,-a*.45,-a*1.05,-a*.6,-a*.95,-a*.68),e.lineTo(-a*.88,-a*.72),e.lineTo(-a*.92,-a*.65),e.bezierCurveTo(-a*1,-a*.56,-a*1.02,-a*.42,-a*.98,-a*.28),e.bezierCurveTo(-a*.88,0,-a*.68,a*.1,-a*.48,a*.08),e.closePath(),e.fill();const t=5;for(let s=0;s<t;s++){const h=s/(t-1),d=-a*.6-h*a*.4,P=a*.1-h*a*.7+Math.sin(h*Math.PI)*a*.15,f=a*.12*(1-h*.5);e.beginPath(),e.moveTo(d,P),e.lineTo(d-f*.3,P-f),e.lineTo(d+f*.3,P-f*.8),e.closePath(),e.fill()}e.restore(),e.restore()},drawTwinklingStar(e,l,i){const r=l.x,o=l.y,a=l.size,n=.5+Math.sin(i*l.twinkleSpeed+l.twinklePhase)*.5,t=`rgba(255, 240, 200, ${n})`,s=`rgba(255, 220, 150, ${n*.4})`;e.save(),e.translate(r,o),e.shadowColor=s,e.shadowBlur=a*3*n,e.fillStyle=t,e.beginPath();for(let h=0;h<4;h++){const d=h*Math.PI/2,P=Math.cos(d)*a,f=Math.sin(d)*a,M=d+Math.PI/4,T=Math.cos(M)*(a*.3),m=Math.sin(M)*(a*.3);h===0?e.moveTo(P,f):e.lineTo(P,f),e.lineTo(T,m)}e.closePath(),e.fill(),e.shadowBlur=a*2*n,e.beginPath(),e.arc(0,0,a*.25,0,Math.PI*2),e.fill(),e.restore()}};
1
+ import{drawHarp as T}from"./heritage-drawing.js";import{drawDaffodil as p,drawDaffodilField as g,drawLeek as b,drawLeekBundle as y}from"./botanical-drawing.js";import{drawWelshDragon as w}from"./character-drawing.js";export default{name:"st-davids",displayName:"St David's Day",emoji:"\u{1F33B}",intensityConfig:{light:{count:50,speedRange:[.4,1.2],sizeRange:[2,4],daffodilFields:2,dragonChance:2e-4,twinklingStars:10},medium:{count:100,speedRange:[.5,1.5],sizeRange:[2,5],daffodilFields:3,dragonChance:4e-4,twinklingStars:18},heavy:{count:150,speedRange:[.6,1.8],sizeRange:[3,6],daffodilFields:4,dragonChance:6e-4,twinklingStars:25}},particles:["daffodil-petal","daffodil","spring-sparkle"],decorations:["daffodil-field","welsh-dragon","flag","harp","leek-bundle","twinkling-star"],colors:{primary:"#FFDD00",secondary:"#228B22",accent:"#DC143C",white:"#FFFFFF"},createDaffodilPetal(a,o,l){const i=["#FFDD00","#FFE135","#FFED4E","#FFF68F"];return{type:"daffodil-petal",x:Math.random()*a,y:Math.random()*o,vx:l.speedRange[0]+Math.random()*(l.speedRange[1]-l.speedRange[0]),size:(l.sizeRange[0]+Math.random()*(l.sizeRange[1]-l.sizeRange[0]))*1.5,speed:(Math.random()-.5)*.2,opacity:.75+Math.random()*.25,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.02,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.03,color:i[Math.floor(Math.random()*i.length)],flutter:Math.random()*Math.PI*2,flutterSpeed:.02+Math.random()*.02,active:!0}},createDaffodil(a,o,l){return{type:"daffodil",x:Math.random()*a,y:Math.random()*o,vx:l.speedRange[0]+Math.random()*(l.speedRange[1]-l.speedRange[0]),size:l.sizeRange[0]+Math.random()*(l.sizeRange[1]-l.sizeRange[0]),speed:.1,opacity:.8+Math.random()*.2,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.02,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.02,active:!0}},createLeek(a,o,l){return{type:"leek",x:Math.random()*a,y:Math.random()*o,vx:(l.speedRange[0]+Math.random()*(l.speedRange[1]-l.speedRange[0]))*.8,size:l.sizeRange[0]+Math.random()*(l.sizeRange[1]-l.sizeRange[0])*1.2,speed:.15,opacity:.7+Math.random()*.3,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.03,windOffset:Math.random()*Math.PI*2,windSpeed:.02+Math.random()*.03,active:!0}},createSpringSparkle(a,o,l){const i=["#FFD700","#FFFFFF","#90EE90","#98FB98"];return{type:"spring-sparkle",x:Math.random()*a,y:Math.random()*o,vx:(l.speedRange[0]+Math.random()*(l.speedRange[1]-l.speedRange[0]))*.8,size:l.sizeRange[0]+Math.random()*(l.sizeRange[1]-l.sizeRange[0])*.6,vy:(Math.random()-.5)*.2,opacity:.6+Math.random()*.4,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.04,color:i[Math.floor(Math.random()*i.length)],twinklePhase:Math.random()*Math.PI*2,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.02,active:!0,static:!1}},createFallingParticle(a,o,l){const i=Math.random();return i<.6?this.createDaffodilPetal(a,o,l):i<.8?this.createDaffodil(a,o,l):i<.95?this.createSpringSparkle(a,o,l):this.createLeek(a,o,l)},createDaffodilField(a,o,l={}){const i=[],s=15+Math.floor(Math.random()*10);for(let e=0;e<s;e++)i.push({x:Math.random()*a*.3,y:Math.random()*40,size:5+Math.random()*8,swayPhase:Math.random()*Math.PI*2});return{type:"daffodil-field",x:l.x!==void 0?l.x:Math.random()*a*.7,y:l.y!==void 0?l.y:o-50,flowers:i,opacity:.9,time:0,active:!0,static:!0}},createInitialDecorations(a,o,l){const i=[],s=l.daffodilFields??3;for(let n=0;n<s;n++)i.push(this.createDaffodilField(a,o,{x:a/(s+1)*(n+1),y:o-50}));i.push({type:"welsh-dragon",x:150,y:o-80,baseY:o-80,vx:0,size:35+Math.random()*10,opacity:1,time:0,wingPhase:Math.random()*Math.PI*2,breatheFirePhase:Math.random()*Math.PI*2,active:!0,static:!0}),i.push({type:"harp",x:a-200,y:o-90,size:40+Math.random()*10,opacity:1,glintPhase:Math.random()*Math.PI*2,active:!0,static:!0}),i.push({type:"leek-bundle",x:a*.3,y:o-40,size:25+Math.random()*5,opacity:1,active:!0,static:!0}),i.push({type:"flag",x:a-100,y:80,size:50,opacity:1,wavePhase:Math.random()*Math.PI*2,active:!0,static:!0});const e=l.twinklingStars??18;for(let n=0;n<e;n++)i.push(this.createTwinklingStar(a,o));return i},createTwinklingStar(a,o){return{type:"twinkling-star",x:Math.random()*a,y:Math.random()*(o*.5),size:1+Math.random()*2,opacity:.6+Math.random()*.3,twinklePhase:Math.random()*Math.PI*2,twinkleSpeed:.003+Math.random()*.003,active:!0,static:!0}},spawnSpecialParticle(a,o,l,i){const s=Math.random();if(s<i.dragonChance){if(a.some(n=>n.type==="welsh-dragon"))return null;const e=Math.random()<.5;return{type:"welsh-dragon",x:e?-100:o+100,y:Math.random()*l*.4+50,baseY:Math.random()*l*.4+50,vx:e?2+Math.random()*1:-(2+Math.random()*1),size:25+Math.random()*15,opacity:1,waveAmplitude:25+Math.random()*20,waveFrequency:.002+Math.random()*.002,waveOffset:Math.random()*Math.PI*2,time:0,wingPhase:Math.random()*Math.PI*2,breatheFirePhase:Math.random()*Math.PI*2,fireParticles:[],active:!0,static:!1}}return s<4e-4&&a.filter(n=>n.type==="daffodil-field").length<i.daffodilFields?this.createDaffodilField(o,l):null},drawDaffodilPetal(a,o,l){const i=o.x,s=o.y,e=o.size,n=Math.sin(l*o.flutterSpeed+o.flutter)*.3;a.save(),a.globalAlpha=o.opacity,a.translate(i,s),a.rotate(o.rotation+n),a.fillStyle=o.color,a.strokeStyle="#FFB700",a.lineWidth=e*.08,a.beginPath(),a.ellipse(0,0,e*.6,e*1.2,0,0,Math.PI*2),a.fill(),a.stroke(),a.strokeStyle="rgba(255, 200, 0, 0.4)",a.lineWidth=e*.06,a.beginPath(),a.moveTo(0,-e*1.1),a.lineTo(0,e*1.1),a.stroke(),a.restore()},drawDaffodil:p,drawLeek:b,drawSpringSparkle(a,o,l){const i=o.x,s=o.y,e=o.size,n=.6+Math.sin(l*.004+o.twinklePhase)*.4;a.save(),a.globalAlpha=o.opacity*n,a.translate(i,s),a.rotate(o.rotation),a.fillStyle=o.color,a.shadowColor=o.color,a.shadowBlur=e*2,a.beginPath(),a.moveTo(0,-e),a.lineTo(e*.3,-e*.3),a.lineTo(e,0),a.lineTo(e*.3,e*.3),a.lineTo(0,e),a.lineTo(-e*.3,e*.3),a.lineTo(-e,0),a.lineTo(-e*.3,-e*.3),a.closePath(),a.fill(),a.restore()},drawDaffodilField:g,drawWelshDragon:w,drawHarp:T,drawLeekBundle:y,drawFlag(a,o,l){const i=o.x,s=o.y,e=o.size;a.save(),a.globalAlpha=o.opacity,a.translate(i,s),a.strokeStyle="#654321",a.lineWidth=e*.04,a.beginPath(),a.moveTo(0,0),a.lineTo(0,e*1.5),a.stroke();const n=Math.sin(l*.003+o.wavePhase)*e*.08;a.fillStyle="#FFFFFF",a.beginPath(),a.moveTo(0,0),a.bezierCurveTo(e*.3,0+n*.5,e*.6,0-n*.5,e*.9,0+n),a.lineTo(e*.9,e*.3+n),a.bezierCurveTo(e*.6,e*.3-n*.5,e*.3,e*.3+n*.5,0,e*.3),a.closePath(),a.fill(),a.fillStyle="#00B140",a.beginPath(),a.moveTo(0,e*.3),a.bezierCurveTo(e*.3,e*.3+n*.5,e*.6,e*.3-n*.5,e*.9,e*.3+n),a.lineTo(e*.9,e*.6+n),a.bezierCurveTo(e*.6,e*.6-n*.5,e*.3,e*.6+n*.5,0,e*.6),a.closePath(),a.fill(),a.fillStyle="#DC143C",a.save(),a.translate(e*.45,e*.3),a.scale(.28,.28),a.beginPath(),a.ellipse(e*.1,0,e*.45,e*.3,-.2,0,Math.PI*2),a.fill(),a.beginPath(),a.ellipse(e*.4,-e*.25,e*.22,e*.15,.3,0,Math.PI*2),a.fill(),a.beginPath(),a.ellipse(-e*.25,e*.1,e*.35,e*.28,.1,0,Math.PI*2),a.fill(),a.beginPath(),a.ellipse(e*.65,-e*.28,e*.2,e*.12,0,0,Math.PI*2),a.fill(),a.beginPath(),a.moveTo(e*.55,-e*.32),a.bezierCurveTo(e*.7,-e*.38,e*.85,-e*.35,e*.88,-e*.28),a.lineTo(e*.82,-e*.25),a.bezierCurveTo(e*.78,-e*.28,e*.65,-e*.3,e*.55,-e*.28),a.closePath(),a.fill(),a.beginPath(),a.moveTo(e*.58,-e*.24),a.bezierCurveTo(e*.72,-e*.22,e*.84,-e*.24,e*.87,-e*.28),a.lineTo(e*.82,-e*.3),a.bezierCurveTo(e*.75,-e*.27,e*.65,-e*.26,e*.58,-e*.27),a.closePath(),a.fill(),a.fillStyle="#FFFF00",a.beginPath(),a.ellipse(e*.58,-e*.32,e*.04,e*.05,.2,0,Math.PI*2),a.fill(),a.fillStyle="#DC143C",a.beginPath(),a.moveTo(e*.5,-e*.38),a.bezierCurveTo(e*.48,-e*.55,e*.52,-e*.65,e*.58,-e*.68),a.lineTo(e*.62,-e*.64),a.bezierCurveTo(e*.58,-e*.62,e*.54,-e*.52,e*.54,-e*.38),a.closePath(),a.fill(),a.beginPath(),a.moveTo(e*.48,-e*.4),a.bezierCurveTo(e*.42,-e*.58,e*.38,-e*.68,e*.35,-e*.72),a.lineTo(e*.38,-e*.74),a.bezierCurveTo(e*.42,-e*.7,e*.46,-e*.58,e*.5,-e*.42),a.closePath(),a.fill(),a.globalAlpha=.9,a.beginPath(),a.moveTo(-e*.1,-e*.15),a.bezierCurveTo(-e*.3,-e*.5,-e*.35,-e*.75,-e*.25,-e*.85),a.lineTo(-e*.22,-e*.82),a.bezierCurveTo(-e*.1,-e*.85,0,-e*.9,e*.1,-e*.88),a.lineTo(e*.12,-e*.84),a.bezierCurveTo(e*.2,-e*.8,e*.28,-e*.72,e*.3,-e*.62),a.lineTo(e*.25,-e*.58),a.bezierCurveTo(e*.22,-e*.5,e*.18,-e*.35,e*.1,-e*.25),a.lineTo(0,-e*.2),a.closePath(),a.fill(),a.beginPath(),a.moveTo(e*.15,-e*.2),a.bezierCurveTo(e*.3,-e*.55,e*.45,-e*.78,e*.6,-e*.82),a.lineTo(e*.62,-e*.78),a.bezierCurveTo(e*.7,-e*.75,e*.8,-e*.68,e*.85,-e*.58),a.lineTo(e*.82,-e*.54),a.bezierCurveTo(e*.75,-e*.52,e*.68,-e*.45,e*.6,-e*.38),a.lineTo(e*.55,-e*.35),a.bezierCurveTo(e*.45,-e*.3,e*.32,-e*.25,e*.2,-e*.22),a.closePath(),a.fill(),a.globalAlpha=1,a.beginPath(),a.ellipse(e*.25,e*.15,e*.12,e*.25,.5,0,Math.PI*2),a.fill(),a.beginPath(),a.moveTo(e*.32,e*.35),a.lineTo(e*.38,e*.55),a.lineTo(e*.42,e*.57),a.lineTo(e*.36,e*.37),a.closePath(),a.fill();for(let t=0;t<3;t++){a.beginPath();const r=e*.36+t*e*.04;a.moveTo(r,e*.55),a.lineTo(r+e*.02,e*.63),a.lineTo(r+e*.04,e*.55),a.closePath(),a.fill()}a.globalAlpha=.85,a.beginPath(),a.ellipse(e*.15,e*.12,e*.1,e*.22,.3,0,Math.PI*2),a.fill(),a.beginPath(),a.moveTo(e*.18,e*.3),a.lineTo(e*.2,e*.48),a.lineTo(e*.24,e*.5),a.lineTo(e*.22,e*.32),a.closePath(),a.fill(),a.globalAlpha=1,a.beginPath(),a.ellipse(-e*.15,e*.25,e*.15,e*.28,.8,0,Math.PI*2),a.fill(),a.beginPath(),a.moveTo(-e*.08,e*.48),a.lineTo(-e*.02,e*.65),a.lineTo(e*.02,e*.67),a.lineTo(-e*.04,e*.5),a.closePath(),a.fill();for(let t=0;t<3;t++){a.beginPath();const r=-e*.04+t*e*.04;a.moveTo(r,e*.65),a.lineTo(r+e*.02,e*.72),a.lineTo(r+e*.04,e*.65),a.closePath(),a.fill()}a.globalAlpha=.85,a.beginPath(),a.ellipse(-e*.28,e*.22,e*.13,e*.25,.6,0,Math.PI*2),a.fill(),a.globalAlpha=1,a.beginPath(),a.moveTo(-e*.5,e*.05),a.bezierCurveTo(-e*.75,e*.15,-e*.95,0,-e*1.05,-e*.3),a.bezierCurveTo(-e*1.1,-e*.45,-e*1.05,-e*.6,-e*.95,-e*.68),a.lineTo(-e*.88,-e*.72),a.lineTo(-e*.92,-e*.65),a.bezierCurveTo(-e*1,-e*.56,-e*1.02,-e*.42,-e*.98,-e*.28),a.bezierCurveTo(-e*.88,0,-e*.68,e*.1,-e*.48,e*.08),a.closePath(),a.fill();const f=5;for(let t=0;t<f;t++){const r=t/(f-1),h=-e*.6-r*e*.4,M=e*.1-r*e*.7+Math.sin(r*Math.PI)*e*.15,d=e*.12*(1-r*.5);a.beginPath(),a.moveTo(h,M),a.lineTo(h-d*.3,M-d),a.lineTo(h+d*.3,M-d*.8),a.closePath(),a.fill()}a.restore(),a.restore()},drawTwinklingStar(a,o,l){const i=o.x,s=o.y,e=o.size,n=.5+Math.sin(l*o.twinkleSpeed+o.twinklePhase)*.5,f=`rgba(255, 240, 200, ${n})`,t=`rgba(255, 220, 150, ${n*.4})`;a.save(),a.translate(i,s),a.shadowColor=t,a.shadowBlur=e*3*n,a.fillStyle=f,a.beginPath();for(let r=0;r<4;r++){const h=r*Math.PI/2,M=Math.cos(h)*e,d=Math.sin(h)*e,m=h+Math.PI/4,P=Math.cos(m)*(e*.3),u=Math.sin(m)*(e*.3);r===0?a.moveTo(M,d):a.lineTo(M,d),a.lineTo(P,u)}a.closePath(),a.fill(),a.shadowBlur=e*2*n,a.beginPath(),a.arc(0,0,e*.25,0,Math.PI*2),a.fill(),a.restore()}};
@@ -1 +1 @@
1
- import{drawKnight as E,drawDragon as G}from"./character-drawing.js";export default{name:"st-georges",displayName:"St George's Day",emoji:"\u{1F3F4}\u{E0067}\u{E0062}\u{E0065}\u{E006E}\u{E0067}\u{E007F}",intensityConfig:{light:{count:40,speedRange:[.3,1],sizeRange:[2,4],roses:3,knightChance:2e-4,twinklingStars:10},medium:{count:80,speedRange:[.4,1.3],sizeRange:[2,5],roses:5,knightChance:4e-4,twinklingStars:18},heavy:{count:120,speedRange:[.5,1.6],sizeRange:[3,6],roses:8,knightChance:6e-4,twinklingStars:25}},particles:["rose-petal","tudor-rose","oak-leaf","sparkle"],decorations:["english-rose","st-georges-cross","knight","dragon","shield","castle","twinkling-star"],colors:{primary:"#C8102E",secondary:"#FFFFFF",tertiary:"#012169",accent:"#FFD700",greenStem:"#228B22"},createRosePetal(e,l,n){const o=Math.random()<.7?["#C8102E","#DC143C","#B91C1C","#991B1B"]:["#FFFFFF","#FFF5F5","#FECACA","#FEE2E2"];return{type:"rose-petal",x:-30,y:Math.random()*l,vx:n.speedRange[0]+Math.random()*(n.speedRange[1]-n.speedRange[0]),size:(n.sizeRange[0]+Math.random()*(n.sizeRange[1]-n.sizeRange[0]))*1.5,speed:(Math.random()-.5)*.2,opacity:.75+Math.random()*.25,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.02,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.03,color:o[Math.floor(Math.random()*o.length)],flutter:Math.random()*Math.PI*2,flutterSpeed:.02+Math.random()*.02,active:!0}},createTudorRose(e,l,n){return{type:"tudor-rose",x:-30,y:Math.random()*l,vx:n.speedRange[0]+Math.random()*(n.speedRange[1]-n.speedRange[0]),size:n.sizeRange[0]+Math.random()*(n.sizeRange[1]-n.sizeRange[0]),speed:(Math.random()-.5)*.15,opacity:.8+Math.random()*.2,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.02,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.02,petalCount:5,active:!0}},createOakLeaf(e,l,n){const s=Math.random();let o;return s<.6?o="#2d5016":s<.85?o="#6b8e23":o="#8b4513",{type:"oak-leaf",x:-30,y:Math.random()*l,vx:(n.speedRange[0]+Math.random()*(n.speedRange[1]-n.speedRange[0]))*.8,size:n.sizeRange[0]+Math.random()*(n.sizeRange[1]-n.sizeRange[0]),speed:(Math.random()-.5)*.2,opacity:.75+Math.random()*.25,windOffset:Math.random()*Math.PI*2,windSpeed:.02+Math.random()*.03,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.04,color:o,flutter:Math.random()*Math.PI*2,flutterSpeed:.03+Math.random()*.02,active:!0}},createSparkle(e,l,n){const s=["#FFD700","#FFFFFF","#C8102E"];return{type:"sparkle",x:-20,y:Math.random()*l,vx:(n.speedRange[0]+Math.random()*(n.speedRange[1]-n.speedRange[0]))*.8,size:n.sizeRange[0]+Math.random()*(n.sizeRange[1]-n.sizeRange[0])*.6,vy:(Math.random()-.5)*.2,opacity:.6+Math.random()*.4,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.04,color:s[Math.floor(Math.random()*s.length)],twinklePhase:Math.random()*Math.PI*2,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.02,active:!0,static:!1}},createFallingParticle(e,l,n){const s=Math.random();return s<.6?this.createRosePetal(e,l,n):s<.8?this.createTudorRose(e,l,n):s<.95?this.createSparkle(e,l,n):this.createOakLeaf(e,l,n)},createEnglishRose(e,l,n={}){return{type:"english-rose",x:n.x!==void 0?n.x:Math.random()*e*.8+e*.1,y:n.y!==void 0?n.y:l-60-Math.random()*100,size:15+Math.random()*10,opacity:1,color:Math.random()<.7?"#C8102E":"#FFFFFF",bloomPhase:Math.random()*Math.PI*2,petalCount:8+Math.floor(Math.random()*5),active:!0,static:!0}},createStGeorgesCross(e,l,n={}){return{type:"st-georges-cross",x:n.x!==void 0?n.x:e*.1+Math.random()*e*.8,y:n.y!==void 0?n.y:50+Math.random()*100,size:40+Math.random()*20,opacity:1,waveOffset:Math.random()*Math.PI*2,waveSpeed:.001+Math.random()*.001,active:!0,static:!0}},createKnight(e,l){const n=Math.random()<.5;return{type:"knight",x:n?-80:e+80,y:l-50,baseY:l-50,vx:n?.8+Math.random()*.4:-(.8+Math.random()*.4),size:20+Math.random()*10,opacity:1,marchPhase:Math.random()*Math.PI*2,marchSpeed:.015,active:!0,static:!1}},createDragon(e,l,n={}){const s=Math.random()<.5;return{type:"dragon",x:s?-100:e+100,y:l*.3+Math.random()*l*.2,baseY:l*.3+Math.random()*l*.2,vx:s?1.5+Math.random()*.5:-(1.5+Math.random()*.5),size:30+Math.random()*15,opacity:1,wingPhase:Math.random()*Math.PI*2,wingSpeed:.012,breatheFirePhase:Math.random()*Math.PI*2,active:!0,static:!1}},createShield(e,l,n={}){return{type:"shield",x:n.x!==void 0?n.x:e*.2+Math.random()*e*.6,y:n.y!==void 0?n.y:l-80-Math.random()*150,size:20+Math.random()*10,opacity:1,rotation:-Math.PI/12+Math.random()*(Math.PI/6),glintPhase:Math.random()*Math.PI*2,active:!0,static:!0}},createInitialDecorations(e,l,n){const s=[];s.push({type:"castle",x:150,y:l-100,size:80+Math.random()*20,opacity:1,active:!0,static:!0}),s.push({type:"dragon",x:e-200,y:l-60,baseY:l-60,vx:0,size:25+Math.random()*10,opacity:1,time:0,wingPhase:Math.random()*Math.PI*2,breathePhase:Math.random()*Math.PI*2,active:!0,static:!0}),s.push({type:"knight",x:e*.4,y:l-45,baseY:l-45,vx:0,size:20+Math.random()*5,opacity:1,time:0,legPhase:0,weaponRaised:!0,active:!0,static:!0}),s.push(this.createStGeorgesCross(e,l,{x:150,y:l-180,size:30})),s.push(this.createShield(e,l,{x:e*.15,y:l-60}));const o=n.twinklingStars??18;for(let a=0;a<o;a++)s.push(this.createTwinklingStar(e,l));return s},createTwinklingStar(e,l){return{type:"twinkling-star",x:Math.random()*e,y:Math.random()*(l*.5),size:1+Math.random()*2,opacity:.6+Math.random()*.3,twinklePhase:Math.random()*Math.PI*2,twinkleSpeed:.003+Math.random()*.003,active:!0,static:!0}},spawnSpecialParticle(e,l,n,s){const o=Math.random();return o<s.knightChance?e.some(a=>a.type==="knight")?null:this.createKnight(l,n):o<s.knightChance*1.2?e.some(a=>a.type==="dragon")?null:this.createDragon(l,n):o<5e-4&&e.filter(r=>r.type==="english-rose").length<s.roses?this.createEnglishRose(l,n):o<3e-4&&e.filter(r=>r.type==="st-georges-cross").length<2?this.createStGeorgesCross(l,n):o<4e-4&&e.filter(r=>r.type==="shield").length<3?this.createShield(l,n):null},drawRosePetal(e,l,n){const s=l.x,o=l.y,a=l.size,r=Math.sin(n*l.flutterSpeed+l.flutter)*.3;e.save(),e.globalAlpha=l.opacity,e.translate(s,o),e.rotate(l.rotation+r);const t=l.color.includes("FFF")||l.color.includes("fff");e.fillStyle=l.color,e.strokeStyle=t?"#FFE6E6":"#8B0000",e.lineWidth=a*.08,e.beginPath(),e.moveTo(0,-a*.4),e.bezierCurveTo(a*.6,-a*.8,a*.8,-a*.2,a*.4,a*.2),e.lineTo(0,a*1),e.lineTo(-a*.4,a*.2),e.bezierCurveTo(-a*.8,-a*.2,-a*.6,-a*.8,0,-a*.4),e.closePath(),e.fill(),e.stroke(),e.strokeStyle=t?"rgba(255, 182, 193, 0.5)":"rgba(139, 0, 0, 0.4)",e.lineWidth=a*.06,e.beginPath(),e.moveTo(0,-a*.3),e.lineTo(0,a*.9),e.stroke(),e.restore()},drawEnglishRose(e,l,n){const s=l.x,o=l.y,a=l.size,r=.8+(Math.sin(n*.002+l.bloomPhase)+1)*.1;e.save(),e.translate(s,o),e.strokeStyle=this.colors.greenStem,e.lineWidth=a*.12,e.beginPath(),e.moveTo(0,0),e.quadraticCurveTo(-a*.2,a*.8,0,a*1.5),e.stroke(),e.fillStyle="#2D5016",[-1,1].forEach(t=>{e.save(),e.translate(t*a*.15,a*.8),e.rotate(t*Math.PI/6),e.beginPath(),e.ellipse(0,0,a*.3,a*.15,0,0,Math.PI*2),e.fill(),e.restore()}),e.fillStyle=l.color,e.strokeStyle=l.color==="#FFFFFF"?"#FFE6E6":"#8B0000",e.lineWidth=1;for(let t=0;t<l.petalCount;t++){const d=t/l.petalCount*Math.PI*2;e.save(),e.rotate(d),e.translate(0,-a*.4*r),e.beginPath(),e.moveTo(0,a*.25),e.bezierCurveTo(-a*.25,-a*.1,-a*.15,-a*.35,0,-a*.25),e.bezierCurveTo(a*.15,-a*.35,a*.25,-a*.1,0,a*.25),e.closePath(),e.fill(),e.stroke(),e.restore()}e.globalAlpha=.9;for(let t=0;t<l.petalCount-2;t++){const d=t/(l.petalCount-2)*Math.PI*2+Math.PI/l.petalCount;e.save(),e.rotate(d),e.translate(0,-a*.25*r),e.beginPath(),e.moveTo(0,a*.15),e.bezierCurveTo(-a*.15,-a*.05,-a*.1,-a*.2,0,-a*.15),e.bezierCurveTo(a*.1,-a*.2,a*.15,-a*.05,0,a*.15),e.closePath(),e.fill(),e.restore()}e.globalAlpha=1,e.fillStyle="#FFD700",e.beginPath(),e.arc(0,0,a*.15*r,0,Math.PI*2),e.fill(),e.fillStyle="#FFA500";for(let t=0;t<8;t++){const d=t/8*Math.PI*2,i=a*.08*r;e.beginPath(),e.arc(Math.cos(d)*i,Math.sin(d)*i,a*.03,0,Math.PI*2),e.fill()}e.restore()},drawStGeorgesCross(e,l,n){const s=l.x,o=l.y,a=l.size,r=n*l.waveSpeed+l.waveOffset;e.save(),e.translate(s,o);const t=e.createLinearGradient(-a*.64,0,-a*.56,0);t.addColorStop(0,"#5a4a3a"),t.addColorStop(.5,"#8B4513"),t.addColorStop(1,"#6a5343"),e.fillStyle=t,e.fillRect(-a*.64,-a*.35,a*.08,a*1.9),e.strokeStyle="#9a6333",e.lineWidth=1,e.beginPath(),e.moveTo(-a*.64,-a*.35),e.lineTo(-a*.64,a*1.55),e.stroke(),e.strokeStyle="#3a2a1a",e.beginPath(),e.moveTo(-a*.56,-a*.35),e.lineTo(-a*.56,a*1.55),e.stroke(),e.fillStyle="#FFD700",e.beginPath(),e.arc(-a*.6,-a*.4,a*.06,0,Math.PI*2),e.fill(),e.strokeStyle="#DAA520",e.lineWidth=1.5,e.stroke();const d=a*1.5,i=a*1,f=12;for(let M=0;M<f;M++){const P=-a*.5+M/f*d,g=-a*.5+(M+1)/f*d,z=g-P,S=Math.sin(r+M*.4)*a*.12,m=Math.sin(r+(M+1)*.4)*a*.12,u=(P+z/2+a*.5)/d,k=u>.4&&u<.6;e.save(),e.fillStyle="#FFFFFF",e.beginPath(),e.moveTo(P,-i/2+S),e.lineTo(g,-i/2+m),e.lineTo(g,i/2+m),e.lineTo(P,i/2+S),e.closePath(),e.fill(),e.fillStyle="#C8102E",k&&(e.beginPath(),e.moveTo(P,-i/2+S),e.lineTo(g,-i/2+m),e.lineTo(g,i/2+m),e.lineTo(P,i/2+S),e.closePath(),e.fill()),e.beginPath(),e.moveTo(P,-i*.15+S),e.lineTo(g,-i*.15+m),e.lineTo(g,i*.15+m),e.lineTo(P,i*.15+S),e.closePath(),e.fill();const F=Math.sin(r+M*.4)*.15;F>0?e.fillStyle=`rgba(255, 255, 255, ${F*.3})`:e.fillStyle=`rgba(0, 0, 0, ${-F*.2})`,e.beginPath(),e.moveTo(P,-i/2+S),e.lineTo(g,-i/2+m),e.lineTo(g,i/2+m),e.lineTo(P,i/2+S),e.closePath(),e.fill(),e.strokeStyle="rgba(0, 0, 0, 0.1)",e.lineWidth=.5,e.beginPath(),e.moveTo(g,-i/2+m),e.lineTo(g,i/2+m),e.stroke(),e.restore()}e.strokeStyle="rgba(0, 0, 0, 0.25)",e.lineWidth=1.5,e.beginPath(),e.moveTo(-a*.5,-i/2+Math.sin(r)*a*.12);for(let M=1;M<=f;M++){const P=-a*.5+M/f*d,g=Math.sin(r+M*.4)*a*.12;e.lineTo(P,-i/2+g)}e.lineTo(-a*.5+d,i/2+Math.sin(r+f*.4)*a*.12);for(let M=f;M>=0;M--){const P=-a*.5+M/f*d,g=Math.sin(r+M*.4)*a*.12;e.lineTo(P,i/2+g)}e.closePath(),e.stroke(),e.fillStyle="#A9A9A9";for(let M=0;M<3;M++){const P=-i/2+M/2*i,g=Math.sin(r)*a*.12;e.beginPath(),e.arc(-a*.48,P+g,a*.03,0,Math.PI*2),e.fill(),e.strokeStyle="#696969",e.lineWidth=1,e.stroke()}e.restore()},drawKnight:E,drawDragon:G,drawShield(e,l,n){const s=l.x,o=l.y,a=l.size,r=(Math.sin(n*.003+l.glintPhase)+1)*.5;e.save(),e.translate(s,o),e.rotate(l.rotation),e.fillStyle="#FFFFFF",e.strokeStyle="#FFD700",e.lineWidth=2,e.beginPath(),e.moveTo(0,-a*.7),e.lineTo(a*.5,-a*.5),e.lineTo(a*.5,a*.3),e.lineTo(0,a*.7),e.lineTo(-a*.5,a*.3),e.lineTo(-a*.5,-a*.5),e.closePath(),e.fill(),e.stroke(),e.fillStyle="#C8102E",e.fillRect(-a*.1,-a*.6,a*.2,a*1.2),e.fillRect(-a*.45,-a*.1,a*.9,a*.2),e.strokeStyle=`rgba(255, 215, 0, ${r*.8})`,e.lineWidth=3,e.beginPath(),e.moveTo(0,-a*.7),e.lineTo(a*.5,-a*.5),e.lineTo(a*.5,a*.3),e.stroke(),e.fillStyle="#FFD700",e.strokeStyle="#DAA520",e.lineWidth=1,e.beginPath(),e.arc(0,0,a*.15,0,Math.PI*2),e.fill(),e.stroke(),e.fillStyle=`rgba(255, 255, 255, ${r*.6})`,e.beginPath(),e.arc(-a*.05,-a*.05,a*.06,0,Math.PI*2),e.fill(),e.restore()},drawCastle(e,l){const n=l.x,s=l.y,o=l.size;e.save(),e.globalAlpha=l.opacity,e.translate(n,s);const a="#9a958f",r="#6a655f",t="#4a4540",d="#b5b0aa",i=o*1.4,f=o*1;e.fillStyle=t,e.fillRect(-i/2+o*.05,-f+o*.05,i,f);const M=e.createLinearGradient(-i/2,-f,i/2,-f);M.addColorStop(0,r),M.addColorStop(.5,a),M.addColorStop(1,r),e.fillStyle=M,e.fillRect(-i/2,-f,i,f),e.strokeStyle=t,e.lineWidth=2,e.strokeRect(-i/2,-f,i,f),e.strokeStyle="rgba(74, 69, 64, 0.4)",e.lineWidth=1;const P=o*.12,g=o*.18;for(let h=0;h<8;h++){const y=-f+h*P,p=h%2*(g/2);for(let D=0;D<8;D++){const B=-i/2+D*g+p;e.strokeRect(B,y,g,P)}}e.fillStyle=a;const z=o*.15,S=o*.12;for(let h=0;h<9;h++)if(h%2===0){const y=-i/2+h*(i/8);e.fillRect(y,-f-S,z,S),e.strokeRect(y,-f-S,z,S),e.fillStyle=t,e.fillRect(y+z/2-o*.015,-f-S+o*.02,o*.03,S-o*.04),e.fillStyle=a}const m=o*.22,T=o*1.2,u=-o*.85,k=-T/2;e.fillStyle=t,e.beginPath(),e.ellipse(u+o*.03,k+o*.03,m,T/2,0,0,Math.PI*2),e.fill();const F=e.createRadialGradient(u-m*.3,k,0,u,k,m);F.addColorStop(0,d),F.addColorStop(.5,a),F.addColorStop(1,r),e.fillStyle=F,e.beginPath(),e.ellipse(u,k,m,T/2,0,0,Math.PI*2),e.fill(),e.strokeStyle=t,e.lineWidth=2,e.stroke(),e.fillStyle=a;for(let h=0;h<6;h++)if(h%2===0){const y=h/6*Math.PI,p=Math.cos(y)*m;e.fillRect(u+p-o*.06,-T-o*.1,o*.12,o*.1),e.strokeRect(u+p-o*.06,-T-o*.1,o*.12,o*.1)}e.fillStyle="#1a1510";for(let h=0;h<3;h++){const y=k-T*.2+h*T*.25;e.fillRect(u-o*.02,y,o*.04,o*.15),e.beginPath(),e.moveTo(u-o*.02,y+o*.15),e.lineTo(u-o*.06,y+o*.18),e.lineTo(u+o*.06,y+o*.18),e.lineTo(u+o*.02,y+o*.15),e.fill()}const C=o*.85;e.fillStyle=t,e.beginPath(),e.ellipse(C+o*.03,k+o*.03,m,T/2,0,0,Math.PI*2),e.fill();const I=e.createRadialGradient(C+m*.3,k,0,C,k,m);I.addColorStop(0,d),I.addColorStop(.5,a),I.addColorStop(1,r),e.fillStyle=I,e.beginPath(),e.ellipse(C,k,m,T/2,0,0,Math.PI*2),e.fill(),e.strokeStyle=t,e.lineWidth=2,e.stroke(),e.fillStyle=a;for(let h=0;h<6;h++)if(h%2===0){const y=h/6*Math.PI,p=Math.cos(y)*m;e.fillRect(C+p-o*.06,-T-o*.1,o*.12,o*.1),e.strokeRect(C+p-o*.06,-T-o*.1,o*.12,o*.1)}e.fillStyle="#1a1510";for(let h=0;h<3;h++){const y=k-T*.2+h*T*.25;e.fillRect(C-o*.02,y,o*.04,o*.15),e.beginPath(),e.moveTo(C-o*.02,y+o*.15),e.lineTo(C-o*.06,y+o*.18),e.lineTo(C+o*.06,y+o*.18),e.lineTo(C+o*.02,y+o*.15),e.fill()}const b=o*.35,v=o*.5;e.fillStyle=t,e.beginPath(),e.moveTo(-b,-o*.05),e.lineTo(-b,-v),e.arc(0,-v,b,Math.PI,0,!1),e.lineTo(b,-o*.05),e.closePath(),e.fill(),e.strokeStyle=r,e.lineWidth=o*.06,e.beginPath(),e.arc(0,-v,b-o*.03,Math.PI,0,!1),e.stroke(),e.strokeStyle="rgba(74, 69, 64, 0.6)",e.lineWidth=2;for(let h=0;h<9;h++){const y=Math.PI+h/8*Math.PI;e.beginPath(),e.moveTo(0,-v),e.lineTo(Math.cos(y)*b,-v+Math.sin(y)*b),e.stroke()}e.fillStyle="#0a0a08",e.beginPath(),e.moveTo(-b+o*.1,-o*.05),e.lineTo(-b+o*.1,-v+o*.05),e.arc(0,-v+o*.05,b-o*.1,Math.PI,0,!1),e.lineTo(b-o*.1,-o*.05),e.closePath(),e.fill(),e.strokeStyle="#2a2520",e.lineWidth=4;const A=7;for(let h=0;h<A;h++){const y=-b+o*.15+h/(A-1)*(b*2-o*.3);e.beginPath(),e.moveTo(y,-o*.05),e.lineTo(y,-v+o*.15),e.stroke()}e.lineWidth=3;for(let h=0;h<4;h++){const y=-o*.1-h*o*.12;e.beginPath(),e.moveTo(-b+o*.15,y),e.lineTo(b-o*.15,y),e.stroke()}e.fillStyle=r,e.beginPath(),e.moveTo(-i/2,0),e.lineTo(-i/2-o*.08,0),e.lineTo(-i/2-o*.05,-f*.6),e.lineTo(-i/2,-f*.6),e.closePath(),e.fill(),e.strokeStyle=t,e.stroke(),e.beginPath(),e.moveTo(i/2,0),e.lineTo(i/2+o*.08,0),e.lineTo(i/2+o*.05,-f*.6),e.lineTo(i/2,-f*.6),e.closePath(),e.fill(),e.stroke(),e.save(),e.translate(0,-T-o*.15);const W=e.createLinearGradient(-o*.02,0,o*.02,0);W.addColorStop(0,"#5a4a3a"),W.addColorStop(.5,"#8b7355"),W.addColorStop(1,"#5a4a3a"),e.fillStyle=W,e.fillRect(-o*.02,0,o*.04,-o*.45),e.strokeStyle="#3a2a1a",e.lineWidth=1,e.strokeRect(-o*.02,0,o*.04,-o*.45),e.fillStyle="#FFD700",e.beginPath(),e.arc(0,-o*.45,o*.04,0,Math.PI*2),e.fill(),e.strokeStyle="#DAA520",e.stroke();const R=o*.4,w=o*.25;e.fillStyle="#FFFFFF",e.fillRect(0,-o*.42,R,w),e.strokeStyle="rgba(0, 0, 0, 0.1)",e.strokeRect(0,-o*.42,R,w),e.fillStyle="#C8102E",e.fillRect(R*.4,-o*.42,R*.2,w),e.fillRect(0,-o*.42+w*.4,R,w*.2),e.restore(),e.restore()},drawTudorRose(e,l){const n=l.x,s=l.y,o=l.size;e.save(),e.globalAlpha=l.opacity,e.translate(n,s),e.rotate(l.rotation),e.fillStyle="#C8102E",e.strokeStyle="#8B0000",e.lineWidth=o*.05;for(let a=0;a<5;a++){const r=a/5*Math.PI*2-Math.PI/2;e.save(),e.rotate(r),e.beginPath(),e.moveTo(0,0),e.bezierCurveTo(-o*.5,-o*.4,-o*.6,-o*.8,0,-o*1.2),e.bezierCurveTo(o*.6,-o*.8,o*.5,-o*.4,0,0),e.closePath(),e.fill(),e.stroke(),e.restore()}e.fillStyle="#FFFFFF",e.strokeStyle="#E0E0E0";for(let a=0;a<5;a++){const r=a/5*Math.PI*2-Math.PI/2+Math.PI/5;e.save(),e.rotate(r),e.beginPath(),e.moveTo(0,0),e.bezierCurveTo(-o*.3,-o*.25,-o*.35,-o*.5,0,-o*.7),e.bezierCurveTo(o*.35,-o*.5,o*.3,-o*.25,0,0),e.closePath(),e.fill(),e.stroke(),e.restore()}e.fillStyle="#FFD700",e.strokeStyle="#DAA520",e.lineWidth=o*.05,e.beginPath(),e.arc(0,0,o*.2,0,Math.PI*2),e.fill(),e.stroke(),e.fillStyle="#FFA500";for(let a=0;a<5;a++){const r=a/5*Math.PI*2,t=o*.12;e.beginPath(),e.arc(Math.cos(r)*t,Math.sin(r)*t,o*.04,0,Math.PI*2),e.fill()}e.restore()},drawOakLeaf(e,l){const n=l.x,s=l.y,o=l.size;e.save(),e.globalAlpha=l.opacity,e.translate(n,s),e.rotate(l.rotation),e.fillStyle=l.color,e.strokeStyle=l.color==="#8b4513"?"#654321":"#1a3a0a",e.lineWidth=o*.08,e.beginPath(),e.moveTo(0,o*1.5),e.bezierCurveTo(o*.3,o*1.2,o*.4,o*1,o*.5,o*.8),e.bezierCurveTo(o*.7,o*.7,o*.8,o*.5,o*.6,o*.3),e.bezierCurveTo(o*.8,o*.2,o*.9,0,o*.7,-o*.3),e.bezierCurveTo(o*.85,-o*.5,o*.8,-o*.8,o*.5,-o*1),e.bezierCurveTo(o*.3,-o*1.2,0,-o*1.3,-o*.3,-o*1.2),e.bezierCurveTo(-o*.8,-o*.8,-o*.85,-o*.5,-o*.7,-o*.3),e.bezierCurveTo(-o*.9,0,-o*.8,o*.2,-o*.6,o*.3),e.bezierCurveTo(-o*.8,o*.5,-o*.7,o*.7,-o*.5,o*.8),e.bezierCurveTo(-o*.4,o*1,-o*.3,o*1.2,0,o*1.5),e.closePath(),e.fill(),e.stroke(),e.strokeStyle=l.color==="#8b4513"?"#654321":"#0a2505",e.lineWidth=o*.06,e.beginPath(),e.moveTo(0,o*1.4),e.lineTo(0,-o*1.15),e.stroke(),e.lineWidth=o*.03;for(let a=0;a<4;a++){const r=o*.8-a*o*.5;e.beginPath(),e.moveTo(0,r),e.lineTo(o*.4,r-o*.15),e.stroke(),e.beginPath(),e.moveTo(0,r),e.lineTo(-o*.4,r-o*.15),e.stroke()}e.restore()},drawSparkle(e,l,n){const s=l.x,o=l.y,a=l.size,r=.6+Math.sin(n*.004+l.twinklePhase)*.4;e.save(),e.globalAlpha=l.opacity*r,e.translate(s,o),e.rotate(l.rotation),e.fillStyle=l.color,e.shadowColor=l.color,e.shadowBlur=a*2,e.beginPath(),e.moveTo(0,-a),e.lineTo(a*.3,-a*.3),e.lineTo(a,0),e.lineTo(a*.3,a*.3),e.lineTo(0,a),e.lineTo(-a*.3,a*.3),e.lineTo(-a,0),e.lineTo(-a*.3,-a*.3),e.closePath(),e.fill(),e.restore()},drawCrown(e,l){const n=l.x,s=l.y,o=l.size,a=(Math.sin(l.glint)+1)*.5;e.save(),e.globalAlpha=l.opacity,e.translate(n,s),e.rotate(l.rotation);const r=e.createLinearGradient(-o,0,o,0);r.addColorStop(0,"#B8860B"),r.addColorStop(.5,"#FFD700"),r.addColorStop(1,"#B8860B"),e.fillStyle=r,e.strokeStyle="#8B6914",e.lineWidth=o*.05,e.beginPath(),e.ellipse(0,o*.3,o*.8,o*.25,0,0,Math.PI*2),e.fill(),e.stroke(),e.strokeStyle="#8B0000",e.lineWidth=o*.08,e.beginPath(),e.ellipse(0,o*.3,o*.7,o*.2,0,0,Math.PI*2),e.stroke(),e.fillStyle=r,e.strokeStyle="#8B6914",e.lineWidth=o*.05;for(let d=0;d<5;d++){const i=d/5*Math.PI*2-Math.PI/2,f=Math.cos(i)*o*.7,M=o*.3+Math.sin(i)*o*.2;e.save(),e.translate(f,M),e.rotate(i+Math.PI/2),e.beginPath(),e.moveTo(0,-o*.8),e.lineTo(-o*.12,-o*.3),e.lineTo(o*.12,-o*.3),e.closePath(),e.fill(),e.stroke(),e.beginPath(),e.moveTo(-o*.12,-o*.3),e.bezierCurveTo(-o*.25,-o*.5,-o*.28,-o*.65,-o*.2,-o*.75),e.lineTo(-o*.15,-o*.65),e.bezierCurveTo(-o*.18,-o*.55,-o*.15,-o*.4,-o*.08,-o*.32),e.fill(),e.stroke(),e.beginPath(),e.moveTo(o*.12,-o*.3),e.bezierCurveTo(o*.25,-o*.5,o*.28,-o*.65,o*.2,-o*.75),e.lineTo(o*.15,-o*.65),e.bezierCurveTo(o*.18,-o*.55,o*.15,-o*.4,o*.08,-o*.32),e.fill(),e.stroke(),e.restore()}e.fillStyle="#FFD700",e.strokeStyle="#8B6914",e.lineWidth=o*.04,e.beginPath(),e.fillRect(-o*.05,-o*.9,o*.1,o*.25),e.strokeRect(-o*.05,-o*.9,o*.1,o*.25),e.fillRect(-o*.15,-o*.82,o*.3,o*.08),e.strokeRect(-o*.15,-o*.82,o*.3,o*.08);const t=[{x:0,y:o*.3,color:"#DC143C",size:.12},{x:o*.4,y:o*.3,color:"#0000CD",size:.08},{x:-o*.4,y:o*.3,color:"#0000CD",size:.08}];for(const d of t)e.fillStyle=d.color,e.beginPath(),e.arc(d.x,d.y,o*d.size,0,Math.PI*2),e.fill(),e.fillStyle=`rgba(255, 255, 255, ${a*.7})`,e.beginPath(),e.arc(d.x-o*d.size*.3,d.y-o*d.size*.3,o*d.size*.4,0,Math.PI*2),e.fill();e.restore()},drawTwinklingStar(e,l,n){const s=l.x,o=l.y,a=l.size,r=.5+Math.sin(n*l.twinkleSpeed+l.twinklePhase)*.5,t=`rgba(255, 220, 220, ${r})`,d=`rgba(255, 180, 180, ${r*.4})`;e.save(),e.translate(s,o),e.shadowColor=d,e.shadowBlur=a*3*r,e.fillStyle=t,e.beginPath();for(let i=0;i<4;i++){const f=i*Math.PI/2,M=Math.cos(f)*a,P=Math.sin(f)*a,g=f+Math.PI/4,z=Math.cos(g)*(a*.3),S=Math.sin(g)*(a*.3);i===0?e.moveTo(M,P):e.lineTo(M,P),e.lineTo(z,S)}e.closePath(),e.fill(),e.shadowBlur=a*2*r,e.beginPath(),e.arc(0,0,a*.25,0,Math.PI*2),e.fill(),e.restore()}};
1
+ import{drawShield as k,drawStGeorgesCross as p}from"./heritage-drawing.js";import{drawEnglishRose as C,drawTudorRose as z}from"./botanical-drawing.js";import{drawKnight as R,drawDragon as w}from"./character-drawing.js";export default{name:"st-georges",displayName:"St George's Day",emoji:"\u{1F3F4}\u{E0067}\u{E0062}\u{E0065}\u{E006E}\u{E0067}\u{E007F}",intensityConfig:{light:{count:40,speedRange:[.3,1],sizeRange:[2,4],roses:3,knightChance:2e-4,twinklingStars:10},medium:{count:80,speedRange:[.4,1.3],sizeRange:[2,5],roses:5,knightChance:4e-4,twinklingStars:18},heavy:{count:120,speedRange:[.5,1.6],sizeRange:[3,6],roses:8,knightChance:6e-4,twinklingStars:25}},particles:["rose-petal","tudor-rose","oak-leaf","sparkle"],decorations:["english-rose","st-georges-cross","knight","dragon","shield","castle","twinkling-star"],colors:{primary:"#C8102E",secondary:"#FFFFFF",tertiary:"#012169",accent:"#FFD700",greenStem:"#228B22"},createRosePetal(e,a,r){const o=Math.random()<.7?["#C8102E","#DC143C","#B91C1C","#991B1B"]:["#FFFFFF","#FFF5F5","#FECACA","#FEE2E2"];return{type:"rose-petal",x:Math.random()*e,y:Math.random()*a,vx:r.speedRange[0]+Math.random()*(r.speedRange[1]-r.speedRange[0]),size:(r.sizeRange[0]+Math.random()*(r.sizeRange[1]-r.sizeRange[0]))*1.5,speed:(Math.random()-.5)*.2,opacity:.75+Math.random()*.25,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.02,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.03,color:o[Math.floor(Math.random()*o.length)],flutter:Math.random()*Math.PI*2,flutterSpeed:.02+Math.random()*.02,active:!0}},createTudorRose(e,a,r){return{type:"tudor-rose",x:Math.random()*e,y:Math.random()*a,vx:r.speedRange[0]+Math.random()*(r.speedRange[1]-r.speedRange[0]),size:r.sizeRange[0]+Math.random()*(r.sizeRange[1]-r.sizeRange[0]),speed:(Math.random()-.5)*.15,opacity:.8+Math.random()*.2,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.02,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.02,petalCount:5,active:!0}},createOakLeaf(e,a,r){const s=Math.random();let o;return s<.6?o="#2d5016":s<.85?o="#6b8e23":o="#8b4513",{type:"oak-leaf",x:Math.random()*e,y:Math.random()*a,vx:(r.speedRange[0]+Math.random()*(r.speedRange[1]-r.speedRange[0]))*.8,size:r.sizeRange[0]+Math.random()*(r.sizeRange[1]-r.sizeRange[0]),speed:(Math.random()-.5)*.2,opacity:.75+Math.random()*.25,windOffset:Math.random()*Math.PI*2,windSpeed:.02+Math.random()*.03,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.04,color:o,flutter:Math.random()*Math.PI*2,flutterSpeed:.03+Math.random()*.02,active:!0}},createSparkle(e,a,r){const s=["#FFD700","#FFFFFF","#C8102E"];return{type:"sparkle",x:Math.random()*e,y:Math.random()*a,vx:(r.speedRange[0]+Math.random()*(r.speedRange[1]-r.speedRange[0]))*.8,size:r.sizeRange[0]+Math.random()*(r.sizeRange[1]-r.sizeRange[0])*.6,vy:(Math.random()-.5)*.2,opacity:.6+Math.random()*.4,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.04,color:s[Math.floor(Math.random()*s.length)],twinklePhase:Math.random()*Math.PI*2,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.02,active:!0,static:!1}},createFallingParticle(e,a,r){const s=Math.random();return s<.6?this.createRosePetal(e,a,r):s<.8?this.createTudorRose(e,a,r):s<.95?this.createSparkle(e,a,r):this.createOakLeaf(e,a,r)},createEnglishRose(e,a,r={}){return{type:"english-rose",x:r.x!==void 0?r.x:Math.random()*e*.8+e*.1,y:r.y!==void 0?r.y:a-60-Math.random()*100,size:15+Math.random()*10,opacity:1,color:Math.random()<.7?"#C8102E":"#FFFFFF",bloomPhase:Math.random()*Math.PI*2,petalCount:8+Math.floor(Math.random()*5),active:!0,static:!0}},createStGeorgesCross(e,a,r={}){return{type:"st-georges-cross",x:r.x!==void 0?r.x:e*.1+Math.random()*e*.8,y:r.y!==void 0?r.y:50+Math.random()*100,size:40+Math.random()*20,opacity:1,waveOffset:Math.random()*Math.PI*2,waveSpeed:.001+Math.random()*.001,active:!0,static:!0}},createKnight(e,a){const r=Math.random()<.5;return{type:"knight",x:r?-80:e+80,y:a-50,baseY:a-50,vx:r?.8+Math.random()*.4:-(.8+Math.random()*.4),size:20+Math.random()*10,opacity:1,marchPhase:Math.random()*Math.PI*2,marchSpeed:.015,active:!0,static:!1}},createDragon(e,a,r={}){const s=Math.random()<.5;return{type:"dragon",x:s?-100:e+100,y:a*.3+Math.random()*a*.2,baseY:a*.3+Math.random()*a*.2,vx:s?1.5+Math.random()*.5:-(1.5+Math.random()*.5),size:30+Math.random()*15,opacity:1,wingPhase:Math.random()*Math.PI*2,wingSpeed:.012,breatheFirePhase:Math.random()*Math.PI*2,active:!0,static:!1}},createShield(e,a,r={}){return{type:"shield",x:r.x!==void 0?r.x:e*.2+Math.random()*e*.6,y:r.y!==void 0?r.y:a-80-Math.random()*150,size:20+Math.random()*10,opacity:1,rotation:-Math.PI/12+Math.random()*(Math.PI/6),glintPhase:Math.random()*Math.PI*2,active:!0,static:!0}},createInitialDecorations(e,a,r){const s=[];s.push({type:"castle",x:150,y:a-100,size:80+Math.random()*20,opacity:1,active:!0,static:!0}),s.push({type:"dragon",x:e-200,y:a-60,baseY:a-60,vx:0,size:25+Math.random()*10,opacity:1,time:0,wingPhase:Math.random()*Math.PI*2,breathePhase:Math.random()*Math.PI*2,active:!0,static:!0}),s.push({type:"knight",x:e*.4,y:a-45,baseY:a-45,vx:0,size:20+Math.random()*5,opacity:1,time:0,legPhase:0,weaponRaised:!0,active:!0,static:!0}),s.push(this.createStGeorgesCross(e,a,{x:55,y:a-190,size:30})),s.push(this.createShield(e,a,{x:e*.15,y:a-60}));const o=r.twinklingStars??18;for(let t=0;t<o;t++)s.push(this.createTwinklingStar(e,a));return s},createTwinklingStar(e,a){return{type:"twinkling-star",x:Math.random()*e,y:Math.random()*(a*.5),size:1+Math.random()*2,opacity:.6+Math.random()*.3,twinklePhase:Math.random()*Math.PI*2,twinkleSpeed:.003+Math.random()*.003,active:!0,static:!0}},spawnSpecialParticle(e,a,r,s){const o=Math.random();return o<s.knightChance?e.some(t=>t.type==="knight")?null:this.createKnight(a,r):o<s.knightChance*1.2?e.some(t=>t.type==="dragon")?null:this.createDragon(a,r):o<5e-4&&e.filter(i=>i.type==="english-rose").length<s.roses?this.createEnglishRose(a,r):o<3e-4&&e.filter(i=>i.type==="st-georges-cross").length<2?this.createStGeorgesCross(a,r):o<4e-4&&e.filter(i=>i.type==="shield").length<3?this.createShield(a,r):null},drawRosePetal(e,a,r){const s=a.x,o=a.y,t=a.size,i=Math.sin(r*a.flutterSpeed+a.flutter)*.3;e.save(),e.globalAlpha=a.opacity,e.translate(s,o),e.rotate(a.rotation+i);const y=a.color.includes("FFF")||a.color.includes("fff");e.fillStyle=a.color,e.strokeStyle=y?"#FFE6E6":"#8B0000",e.lineWidth=t*.08,e.beginPath(),e.moveTo(0,-t*.4),e.bezierCurveTo(t*.6,-t*.8,t*.8,-t*.2,t*.4,t*.2),e.lineTo(0,t*1),e.lineTo(-t*.4,t*.2),e.bezierCurveTo(-t*.8,-t*.2,-t*.6,-t*.8,0,-t*.4),e.closePath(),e.fill(),e.stroke(),e.strokeStyle=y?"rgba(255, 182, 193, 0.5)":"rgba(139, 0, 0, 0.4)",e.lineWidth=t*.06,e.beginPath(),e.moveTo(0,-t*.3),e.lineTo(0,t*.9),e.stroke(),e.restore()},drawEnglishRose:C,drawStGeorgesCross:p,drawKnight:R,drawDragon:w,drawShield:k,drawCastle(e,a){if(!Number.isFinite(a.size)||a.size<=0)return;e.save(),e.globalAlpha=a.opacity,e.translate(a.x,a.y),e.scale(a.size/100,a.size/100),e.lineJoin="round",e.lineCap="round";const r="#4c514e",s=(n,l)=>{const h=e.createLinearGradient(n,0,l,0);return h.addColorStop(0,"#a69e88"),h.addColorStop(.28,"#e0d6bb"),h.addColorStop(.62,"#c5bba1"),h.addColorStop(1,"#8c8b7c"),h},o=(n,l)=>{e.beginPath(),n.forEach(([h,M],m)=>m?e.lineTo(h,M):e.moveTo(h,M)),e.closePath(),e.fillStyle=l,e.fill(),e.strokeStyle=r,e.lineWidth=1.5,e.stroke()},t=(n,l,h,M,m,u)=>{const g=h/(m*2-1),b=[[n,M],[n,l]];for(let P=0;P<m*2-1;P++){const S=n+(P+1)*g,T=l+(P%2?9:0);b.push([S,T]),P<m*2-2&&b.push([S,l+(P%2?0:9)])}b.push([n+h,M]),o(b,u)},i=(n,l,h,M)=>{e.save(),e.beginPath(),e.rect(n,l,h,M-l),e.clip(),e.strokeStyle="rgba(88, 82, 66, 0.23)",e.lineWidth=.7;for(let m=0,u=l;u<M;m++,u+=12){e.beginPath(),e.moveTo(n,u),e.lineTo(n+h,u);for(let g=n+(m%2?-9:3);g<n+h;g+=21)e.moveTo(g,u),e.lineTo(g,u+12);e.stroke()}e.restore()},y=(n,l,h,M,m)=>{e.beginPath(),e.moveTo(n-h,l),e.lineTo(n-h,M),e.arc(n,M,h,Math.PI,Math.PI*2),e.lineTo(n+h,l),e.closePath(),e.fillStyle=m,e.fill()},d=(n,l)=>{y(n,l+15,4,l+4,"#666857"),y(n,l+14,2.3,l+4,"#303b3b"),e.fillStyle="#e8dfc6",e.fillRect(n-5,l+15,10,1.5)};e.fillStyle="rgba(24, 34, 31, 0.18)",e.beginPath(),e.ellipse(0,5,116,9,0,0,Math.PI*2),e.fill(),o([[-109,1],[-104,-7],[104,-7],[109,1]],"#8c917c"),t(-42,-137,84,-37,5,s(-42,42)),i(-41,-122,82,-37),e.fillStyle="#ede3c9",e.fillRect(-42,-123,84,3),e.fillStyle="rgba(72, 77, 66, 0.22)",e.fillRect(-42,-120,84,4),d(-22,-110),d(22,-110),d(0,-76),t(-81,-78,162,0,9,s(-81,81)),i(-80,-63,160,-2),e.fillStyle="#e7ddc4",e.fillRect(-81,-64,162,3),e.fillStyle="rgba(72, 77, 66, 0.2)",e.fillRect(-81,-61,162,4),y(0,-1,25,-35,"#a29980"),e.strokeStyle="#716f60",e.lineWidth=.9;for(let n=0;n<=9;n++){const l=Math.PI+n*Math.PI/9;e.beginPath(),e.moveTo(Math.cos(l)*20,-35+Math.sin(l)*20),e.lineTo(Math.cos(l)*25,-35+Math.sin(l)*25),e.stroke()}y(0,0,19,-35,"#263334"),e.save(),e.clip(),e.fillStyle="#46504a",e.fillRect(-19,-7,38,7),e.strokeStyle="#92907b",e.lineWidth=1.7,e.beginPath();for(let n=-15;n<=15;n+=6)e.moveTo(n,-56),e.lineTo(n,-9);for(let n=-47;n<=-12;n+=9)e.moveTo(-19,n),e.lineTo(19,n);e.stroke(),e.restore(),o([[-22,0],[-28,5],[28,5],[22,0]],"#d3c6a6");for(const n of[-80,80])e.beginPath(),e.moveTo(n-24,-101),e.lineTo(n+24,-101),e.lineTo(n+24,-5),e.quadraticCurveTo(n,4,n-24,-5),e.closePath(),e.fillStyle=s(n-24,n+24),e.fill(),e.strokeStyle=r,e.lineWidth=1.5,e.stroke(),i(n-23,-98,46,-7),t(n-27,-118,54,-98,4,s(n-27,n+27)),e.fillStyle="#eee3c8",e.fillRect(n-27,-100,54,3),e.fillStyle="rgba(72, 77, 66, 0.24)",e.fillRect(n-24,-97,48,4),d(n,-85),d(n,-49),e.strokeStyle="#8c8976",e.lineWidth=3,e.beginPath(),e.moveTo(n-23,-11),e.quadraticCurveTo(n,-4,n+23,-11),e.stroke();e.strokeStyle="#68624f",e.lineWidth=2,e.beginPath(),e.moveTo(0,-138),e.lineTo(0,-185),e.stroke(),o([[2,-182],[18,-180],[38,-183],[38,-159],[18,-156],[2,-158]],"#fff9e9"),e.save(),e.clip(),e.fillStyle="#b92435",e.fillRect(14,-185,6,32),o([[2,-173],[18,-171],[38,-174],[38,-168],[18,-165],[2,-167]],"#b92435"),e.restore(),e.fillStyle="#d9b56b",e.beginPath(),e.arc(0,-186,2.5,0,Math.PI*2),e.fill(),e.restore()},drawTudorRose:z,drawOakLeaf(e,a){const r=a.x,s=a.y,o=a.size;e.save(),e.globalAlpha=a.opacity,e.translate(r,s),e.rotate(a.rotation),e.fillStyle=a.color,e.strokeStyle=a.color==="#8b4513"?"#654321":"#1a3a0a",e.lineWidth=o*.08,e.beginPath(),e.moveTo(0,o*1.5),e.bezierCurveTo(o*.3,o*1.2,o*.4,o*1,o*.5,o*.8),e.bezierCurveTo(o*.7,o*.7,o*.8,o*.5,o*.6,o*.3),e.bezierCurveTo(o*.8,o*.2,o*.9,0,o*.7,-o*.3),e.bezierCurveTo(o*.85,-o*.5,o*.8,-o*.8,o*.5,-o*1),e.bezierCurveTo(o*.3,-o*1.2,0,-o*1.3,-o*.3,-o*1.2),e.bezierCurveTo(-o*.8,-o*.8,-o*.85,-o*.5,-o*.7,-o*.3),e.bezierCurveTo(-o*.9,0,-o*.8,o*.2,-o*.6,o*.3),e.bezierCurveTo(-o*.8,o*.5,-o*.7,o*.7,-o*.5,o*.8),e.bezierCurveTo(-o*.4,o*1,-o*.3,o*1.2,0,o*1.5),e.closePath(),e.fill(),e.stroke(),e.strokeStyle=a.color==="#8b4513"?"#654321":"#0a2505",e.lineWidth=o*.06,e.beginPath(),e.moveTo(0,o*1.4),e.lineTo(0,-o*1.15),e.stroke(),e.lineWidth=o*.03;for(let t=0;t<4;t++){const i=o*.8-t*o*.5;e.beginPath(),e.moveTo(0,i),e.lineTo(o*.4,i-o*.15),e.stroke(),e.beginPath(),e.moveTo(0,i),e.lineTo(-o*.4,i-o*.15),e.stroke()}e.restore()},drawSparkle(e,a,r){const s=a.x,o=a.y,t=a.size,i=.6+Math.sin(r*.004+a.twinklePhase)*.4;e.save(),e.globalAlpha=a.opacity*i,e.translate(s,o),e.rotate(a.rotation),e.fillStyle=a.color,e.shadowColor=a.color,e.shadowBlur=t*2,e.beginPath(),e.moveTo(0,-t),e.lineTo(t*.3,-t*.3),e.lineTo(t,0),e.lineTo(t*.3,t*.3),e.lineTo(0,t),e.lineTo(-t*.3,t*.3),e.lineTo(-t,0),e.lineTo(-t*.3,-t*.3),e.closePath(),e.fill(),e.restore()},drawCrown(e,a){const r=a.x,s=a.y,o=a.size,t=(Math.sin(a.glint)+1)*.5;e.save(),e.globalAlpha=a.opacity,e.translate(r,s),e.rotate(a.rotation);const i=e.createLinearGradient(-o,0,o,0);i.addColorStop(0,"#B8860B"),i.addColorStop(.5,"#FFD700"),i.addColorStop(1,"#B8860B"),e.fillStyle=i,e.strokeStyle="#8B6914",e.lineWidth=o*.05,e.beginPath(),e.ellipse(0,o*.3,o*.8,o*.25,0,0,Math.PI*2),e.fill(),e.stroke(),e.strokeStyle="#8B0000",e.lineWidth=o*.08,e.beginPath(),e.ellipse(0,o*.3,o*.7,o*.2,0,0,Math.PI*2),e.stroke(),e.fillStyle=i,e.strokeStyle="#8B6914",e.lineWidth=o*.05;for(let d=0;d<5;d++){const f=d/5*Math.PI*2-Math.PI/2,n=Math.cos(f)*o*.7,l=o*.3+Math.sin(f)*o*.2;e.save(),e.translate(n,l),e.rotate(f+Math.PI/2),e.beginPath(),e.moveTo(0,-o*.8),e.lineTo(-o*.12,-o*.3),e.lineTo(o*.12,-o*.3),e.closePath(),e.fill(),e.stroke(),e.beginPath(),e.moveTo(-o*.12,-o*.3),e.bezierCurveTo(-o*.25,-o*.5,-o*.28,-o*.65,-o*.2,-o*.75),e.lineTo(-o*.15,-o*.65),e.bezierCurveTo(-o*.18,-o*.55,-o*.15,-o*.4,-o*.08,-o*.32),e.fill(),e.stroke(),e.beginPath(),e.moveTo(o*.12,-o*.3),e.bezierCurveTo(o*.25,-o*.5,o*.28,-o*.65,o*.2,-o*.75),e.lineTo(o*.15,-o*.65),e.bezierCurveTo(o*.18,-o*.55,o*.15,-o*.4,o*.08,-o*.32),e.fill(),e.stroke(),e.restore()}e.fillStyle="#FFD700",e.strokeStyle="#8B6914",e.lineWidth=o*.04,e.beginPath(),e.fillRect(-o*.05,-o*.9,o*.1,o*.25),e.strokeRect(-o*.05,-o*.9,o*.1,o*.25),e.fillRect(-o*.15,-o*.82,o*.3,o*.08),e.strokeRect(-o*.15,-o*.82,o*.3,o*.08);const y=[{x:0,y:o*.3,color:"#DC143C",size:.12},{x:o*.4,y:o*.3,color:"#0000CD",size:.08},{x:-o*.4,y:o*.3,color:"#0000CD",size:.08}];for(const d of y)e.fillStyle=d.color,e.beginPath(),e.arc(d.x,d.y,o*d.size,0,Math.PI*2),e.fill(),e.fillStyle=`rgba(255, 255, 255, ${t*.7})`,e.beginPath(),e.arc(d.x-o*d.size*.3,d.y-o*d.size*.3,o*d.size*.4,0,Math.PI*2),e.fill();e.restore()},drawTwinklingStar(e,a,r){const s=a.x,o=a.y,t=a.size,i=.5+Math.sin(r*a.twinkleSpeed+a.twinklePhase)*.5,y=`rgba(255, 220, 220, ${i})`,d=`rgba(255, 180, 180, ${i*.4})`;e.save(),e.translate(s,o),e.shadowColor=d,e.shadowBlur=t*3*i,e.fillStyle=y,e.beginPath();for(let f=0;f<4;f++){const n=f*Math.PI/2,l=Math.cos(n)*t,h=Math.sin(n)*t,M=n+Math.PI/4,m=Math.cos(M)*(t*.3),u=Math.sin(M)*(t*.3);f===0?e.moveTo(l,h):e.lineTo(l,h),e.lineTo(m,u)}e.closePath(),e.fill(),e.shadowBlur=t*2*i,e.beginPath(),e.arc(0,0,t*.25,0,Math.PI*2),e.fill(),e.restore()}};
@@ -1 +1 @@
1
- import{drawMooningLeprechaun as b}from"./mooning-drawing.js";import{spawnMooningCharacter as w,updateMooningCharacter as S}from"./mooning-antics.js";import{drawLeprechaun as p,drawStaticLeprechaun as v}from"./character-drawing.js";export default{name:"st-patricks",displayName:"St Patrick's Day",emoji:"\u2618\uFE0F",intensityConfig:{light:{count:40,speedRange:[.4,1.2],sizeRange:[2,4],pots:1,leprechaunChance:3e-4,twinklingStars:10},medium:{count:80,speedRange:[.5,1.5],sizeRange:[2,5],pots:2,leprechaunChance:5e-4,twinklingStars:18},heavy:{count:120,speedRange:[.6,1.8],sizeRange:[3,6],pots:3,leprechaunChance:8e-4,twinklingStars:25}},particles:["clover-petal","shamrock","gold-coin","sparkle"],decorations:["pot-of-gold","rainbow","leprechaun","harp","static-leprechaun","moon","twinkling-star","mooning-leprechaun"],optInDecorations:{mooningLeprechaun:{chance:"mooningLeprechaunChance",value:5e-4}},colors:{primary:"#228B22",secondary:"#90EE90",white:"#FFFFFF",accent:"#FFD700",rainbow:["#ff0000","#ffa500","#ffff00","#00ff00","#0000ff","#4b0082","#8b00ff"]},createCloverPetal(e,o,n){const t=["#228B22","#32CD32","#90EE90","#3CB371","#2E8B57"];return{type:"clover-petal",x:-30,y:Math.random()*o,vx:n.speedRange[0]+Math.random()*(n.speedRange[1]-n.speedRange[0]),size:(n.sizeRange[0]+Math.random()*(n.sizeRange[1]-n.sizeRange[0]))*1.5,speed:(Math.random()-.5)*.2,opacity:.75+Math.random()*.25,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.025,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.03,color:t[Math.floor(Math.random()*t.length)],flutter:Math.random()*Math.PI*2,flutterSpeed:.02+Math.random()*.02,active:!0}},createShamrock(e,o,n){const t=Math.random();let r,a;return t<.5?(r="#228B22",a="#006400"):t<.75?(r="#FFFFFF",a="#d0d0d0"):(r="#FFD700",a="#DAA520"),{type:"shamrock",x:-30,y:Math.random()*o,vx:n.speedRange[0]+Math.random()*(n.speedRange[1]-n.speedRange[0]),size:n.sizeRange[0]+Math.random()*(n.sizeRange[1]-n.sizeRange[0]),speed:(Math.random()-.5)*.15,opacity:.7+Math.random()*.3,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.025,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.02,color:r,strokeColor:a,active:!0}},createGoldCoin(e,o,n){return{type:"gold-coin",x:-30,y:Math.random()*o,vx:(n.speedRange[0]+Math.random()*(n.speedRange[1]-n.speedRange[0]))*.8,size:2+Math.random()*3,speed:(Math.random()-.5)*.1,opacity:.9+Math.random()*.1,rotation:0,rotationSpeed:.05+Math.random()*.1,spinPhase:Math.random()*Math.PI*2,glintPhase:Math.random()*Math.PI*2,windOffset:Math.random()*Math.PI*2,windSpeed:.01+Math.random()*.02,active:!0}},createPotOfGold(e,o,n={}){return{type:"pot-of-gold",x:n.x!==void 0?n.x:Math.random()*e*.6+e*.2,y:n.y!==void 0?n.y:o-40,size:20+Math.random()*10,opacity:1,glintPhase:Math.random()*Math.PI*2,coins:[],active:!0,static:!0}},createRainbow(e,o,n,t){const a=n,s=(20+n)/2,i=o*.2,h=t-i/2;return{type:"rainbow",x:s,y:h,startX:20,endX:a,endY:t,width:e,height:o,opacity:.7,vx:0,vy:0,active:!0,static:!0}},createSparkle(e,o,n){const t=["#FFD700","#FFFFFF","#228B22"];return{type:"sparkle",x:-20,y:Math.random()*o,vx:(n.speedRange[0]+Math.random()*(n.speedRange[1]-n.speedRange[0]))*.8,size:n.sizeRange[0]+Math.random()*(n.sizeRange[1]-n.sizeRange[0])*.6,vy:(Math.random()-.5)*.2,opacity:.6+Math.random()*.4,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.04,color:t[Math.floor(Math.random()*t.length)],twinklePhase:Math.random()*Math.PI*2,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.02,active:!0,static:!1}},createFallingParticle(e,o,n){const t=Math.random();return t<.6?this.createCloverPetal(e,o,n):t<.8?this.createShamrock(e,o,n):t<.95?this.createGoldCoin(e,o,n):this.createSparkle(e,o,n)},createInitialDecorations(e,o,n){const t=[];t.push({type:"moon",x:e-120,y:100,size:60+Math.random()*20,opacity:.85,glowPhase:Math.random()*Math.PI*2,active:!0,static:!0});const r=20,a=220,s=o-40;t.push(this.createPotOfGold(e,o,{x:a,y:s})),t.push(this.createRainbow(e,o,a,s));const i=1+Math.floor(Math.random()*2);for(let M=0;M<i;M++){const y=60+Math.random()*(e-120);t.push({type:"static-leprechaun",x:y,y:o-35,size:12+Math.random()*4,opacity:1,time:Math.random()*1e3,wavePhase:Math.random()*Math.PI*2,active:!0,static:!0})}const h=n.twinklingStars??18;for(let M=0;M<h;M++)t.push(this.createTwinklingStar(e,o));return t},createTwinklingStar(e,o){return{type:"twinkling-star",x:Math.random()*e,y:Math.random()*(o*.5),size:1+Math.random()*2,opacity:.6+Math.random()*.3,twinklePhase:Math.random()*Math.PI*2,twinkleSpeed:.003+Math.random()*.003,active:!0,static:!0}},spawnSpecialParticle(e,o,n,t){const r=w(e,o,n,t,"mooning-leprechaun","mooningLeprechaunChance");if(r)return r;const a=Math.random();if(a<t.leprechaunChance){if(e.some(M=>M.type==="leprechaun"))return null;const s=Math.random()<.5,i=(o+100)/180;return{type:"leprechaun",x:s?-50:o+50,y:n-35,baseY:n-35,vx:s?i:-i,vy:0,size:12+Math.random()*6,opacity:1,time:0,legPhase:Math.random()*Math.PI*2,active:!0,static:!1}}if(a<t.leprechaunChance+3e-4){if(e.some(i=>i.type==="banshee"))return null;const s=Math.random()<.5;return{type:"banshee",x:s?-100:o+100,y:Math.random()*(n*.4)+50,baseY:Math.random()*(n*.4)+50,vx:s?2+Math.random()*1:-(2+Math.random()*1),size:18+Math.random()*10,opacity:.6+Math.random()*.2,waveAmplitude:25+Math.random()*20,waveFrequency:.0015+Math.random()*.002,waveOffset:Math.random()*Math.PI*2,time:0,wailPhase:Math.random()*Math.PI*2,active:!0,static:!1}}if(a<.001&&e.filter(i=>i.type==="pot-of-gold").length<t.pots){const i=this.createPotOfGold(o,n),h=this.createRainbow(o,n,i.x,i.y);return e.push(h),i}return null},updateSpecialParticles(e,o,n,t){return e.forEach(r=>{if(r.active){if(r.type==="mooning-leprechaun"){S(r,o,n);return}(r.type==="leprechaun"||r.type==="banshee")&&(r.time+=o,r.type==="leprechaun"?(r.vx>0&&r.x>n+r.size*2||r.vx<0&&r.x<-r.size*2)&&(r.active=!1):r.type==="banshee"&&(r.vx>0&&r.x>n+r.size*4||r.vx<0&&r.x<-r.size*4)&&(r.active=!1)),r.type==="static-leprechaun"&&(r.time+=o)}}),e.filter(r=>r.active)},drawCloverPetal(e,o,n){const t=o.x,r=o.y,a=o.size,s=Math.sin(n*o.flutterSpeed+o.flutter)*.3;e.save(),e.globalAlpha=o.opacity,e.translate(t,r),e.rotate(o.rotation+s),e.fillStyle=o.color,e.strokeStyle="#006400",e.lineWidth=a*.08,e.beginPath(),e.moveTo(0,-a*.3),e.bezierCurveTo(-a*.6,-a*.7,-a*.8,-a*.3,-a*.5,a*.2),e.lineTo(0,a*.8),e.lineTo(a*.5,a*.2),e.bezierCurveTo(a*.8,-a*.3,a*.6,-a*.7,0,-a*.3),e.closePath(),e.fill(),e.stroke(),e.strokeStyle="rgba(0, 100, 0, 0.4)",e.lineWidth=a*.06,e.beginPath(),e.moveTo(0,-a*.2),e.lineTo(0,a*.7),e.stroke(),e.restore()},drawSparkle(e,o,n){const t=o.x,r=o.y,a=o.size,s=.6+Math.sin(n*.004+o.twinklePhase)*.4;e.save(),e.globalAlpha=o.opacity*s,e.translate(t,r),e.rotate(o.rotation),e.fillStyle=o.color,e.shadowColor=o.color,e.shadowBlur=a*2,e.beginPath(),e.moveTo(0,-a),e.lineTo(a*.3,-a*.3),e.lineTo(a,0),e.lineTo(a*.3,a*.3),e.lineTo(0,a),e.lineTo(-a*.3,a*.3),e.lineTo(-a,0),e.lineTo(-a*.3,-a*.3),e.closePath(),e.fill(),e.restore()},drawShamrock(e,o){const n=o.x,t=o.y,r=o.size;e.save(),e.globalAlpha=o.opacity,e.translate(n,t),e.rotate(o.rotation),e.fillStyle=o.color||"#228B22",e.strokeStyle=o.strokeColor||"#006400",e.lineWidth=r*.1;for(let a=0;a<3;a++){const s=a/3*Math.PI*2-Math.PI/2;e.save(),e.rotate(s),e.translate(0,-r*.7),e.beginPath(),e.moveTo(0,r*.3),e.bezierCurveTo(-r*.5,-r*.2,-r*.3,-r*.6,0,-r*.35),e.bezierCurveTo(r*.3,-r*.6,r*.5,-r*.2,0,r*.3),e.closePath(),e.fill(),e.stroke(),e.restore()}e.strokeStyle="#8B4513",e.lineWidth=r*.15,e.beginPath(),e.moveTo(0,0),e.lineTo(0,r*1.2),e.stroke(),e.restore()},drawGoldCoin(e,o,n){const t=o.x,r=o.y,a=o.size,s=Math.abs(Math.cos(o.rotation))*a;if(e.save(),e.globalAlpha=o.opacity,e.translate(t,r),e.fillStyle="#FFD700",e.strokeStyle="#DAA520",e.lineWidth=a*.15,e.beginPath(),e.ellipse(0,0,s,a,0,0,Math.PI*2),e.fill(),e.stroke(),s>a*.3){const i=(Math.sin(n*.005+o.glintPhase)+1)*.5;e.fillStyle=`rgba(255, 255, 255, ${i*.6})`,e.beginPath(),e.ellipse(-s*.3,-a*.3,s*.3,a*.3,0,0,Math.PI*2),e.fill()}e.restore()},drawPotOfGold(e,o,n){const t=o.x,r=o.y,a=o.size;e.save(),e.translate(t,r),e.fillStyle="#1a1a1a",e.strokeStyle="#0a0a0a",e.lineWidth=2,e.beginPath(),e.arc(0,0,a*.7,0,Math.PI),e.lineTo(-a*.7,a*.4),e.quadraticCurveTo(0,a*.6,a*.7,a*.4),e.closePath(),e.fill(),e.stroke(),e.strokeStyle="#2a2a2a",e.lineWidth=3,e.beginPath(),e.arc(0,-a*.2,a*.5,Math.PI,0),e.stroke();const s=[{x:-a*.4,y:-a*.2,s:.8},{x:a*.3,y:-a*.3,s:.9},{x:-a*.1,y:-a*.5,s:1},{x:a*.5,y:-a*.1,s:.7},{x:-a*.5,y:0,s:.75},{x:a*.1,y:-a*.6,s:.85},{x:0,y:-a*.3,s:.95}];e.fillStyle="#FFD700",e.strokeStyle="#DAA520",e.lineWidth=1,s.forEach((h,M)=>{const y=n*.002+M*.5,P=(Math.sin(y)+1)*.5;e.save(),e.translate(h.x,h.y),e.beginPath(),e.arc(0,0,a*.2*h.s,0,Math.PI*2),e.fill(),e.stroke(),e.fillStyle=`rgba(255, 255, 255, ${P*.6})`,e.beginPath(),e.arc(-a*.08*h.s,-a*.08*h.s,a*.08*h.s,0,Math.PI*2),e.fill(),e.restore()}),e.globalAlpha=.3;const i=e.createRadialGradient(0,-a*.2,0,0,-a*.2,a*1.5);i.addColorStop(0,"#FFD700"),i.addColorStop(1,"rgba(255, 215, 0, 0)"),e.fillStyle=i,e.fillRect(-a*1.5,-a*1.5,a*3,a*1.5),e.restore()},drawSmallGoldPot(e,o,n,t){e.save(),e.translate(o,n),e.fillStyle="#1a1a1a",e.strokeStyle="#0a0a0a",e.lineWidth=1,e.beginPath(),e.arc(0,-t*.4,t*.7,0,Math.PI,!0),e.lineTo(t*.7,t*.4),e.quadraticCurveTo(0,t*.6,-t*.7,t*.4),e.closePath(),e.fill(),e.stroke(),e.fillStyle="#FFD700",e.beginPath(),e.arc(0,-t*.7,t*.5,0,Math.PI*2),e.fill(),e.restore()},drawRainbow(e,o){const n=o.startX,t=o.endX,r=o.endY,a=o.height;e.save(),e.globalAlpha=.5;const s=Math.abs(t-n),i=(n+t)/2,h=a*.2,M=(s*s+4*h*h)/(8*h),y=r+h-M,P=this.colors.rainbow,u=5;for(let d=P.length-1;d>=0;d--)e.strokeStyle=P[d],e.lineWidth=u,e.beginPath(),e.arc(i,y,M+(P.length-1-d)*u,Math.PI,0),e.stroke();e.restore(),this.drawSmallGoldPot(e,t,r,20)},drawLeprechaun:p,drawMooningLeprechaun:b,drawBanshee(e,o,n){const t=o.x,r=o.y+Math.sin(n*o.waveFrequency+o.waveOffset)*o.waveAmplitude,a=o.size,s=o.vx>0?1:-1;e.save(),e.globalAlpha=o.opacity,e.translate(t,r),s===-1&&e.scale(-1,1);const i=e.createRadialGradient(0,-a*.5,0,0,-a*.5,a*3);i.addColorStop(0,"rgba(180, 255, 180, 0.4)"),i.addColorStop(.3,"rgba(150, 255, 150, 0.2)"),i.addColorStop(.6,"rgba(120, 255, 120, 0.1)"),i.addColorStop(1,"rgba(100, 255, 100, 0)"),e.fillStyle=i,e.fillRect(-a*3,-a*3,a*6,a*6);const h=Math.sin(n*.008+o.wailPhase)*a*.25;e.fillStyle="rgba(200, 240, 200, 0.3)",e.beginPath(),e.moveTo(-a*.8,-a*1.2),e.bezierCurveTo(-a*1.2+h*2,-a*.4,-a*1+h*1.5,a*.6,-a*.6+h,a*1.8),e.bezierCurveTo(-a*.3,a*1.5,a*.3,a*1.5,a*.6-h,a*1.8),e.bezierCurveTo(a*1-h*1.5,a*.6,a*1.2-h*2,-a*.4,a*.8,-a*1.2),e.closePath(),e.fill(),e.fillStyle="rgba(230, 255, 230, 0.85)",e.strokeStyle="rgba(180, 255, 180, 0.6)",e.lineWidth=a*.04,e.beginPath(),e.moveTo(-a*.5,-a*1);for(let l=0;l<=12;l++){const d=l/12,f=Math.sin(n*.012+d*Math.PI*3+o.wailPhase)*a*.3,g=(d-.5)*a*1.8+f,m=-a*1+d*a*2.2;l===0?e.moveTo(g,m):e.lineTo(g,m)}e.lineTo(-a*.5,-a*1),e.closePath(),e.fill(),e.stroke(),e.strokeStyle="rgba(180, 255, 180, 0.4)",e.lineWidth=a*.02;for(let l=0;l<8;l++){const d=-a*.7+l*(a*1.4/7),f=Math.sin(n*.015+l*.8)*a*.2;e.beginPath(),e.moveTo(d,a*.4),e.lineTo(d+f,a*1.2+l%2*a*.4),e.stroke()}const M=Math.sin(n*.006)*.15;e.save(),e.rotate(M),e.fillStyle="rgba(240, 255, 240, 0.9)",e.strokeStyle="rgba(180, 230, 180, 0.5)",e.lineWidth=a*.03,e.beginPath(),e.ellipse(0,-a*.8,a*.35,a*.55,0,0,Math.PI*2),e.fill(),e.stroke(),e.fillStyle="rgba(50, 100, 50, 0.6)",e.beginPath(),e.ellipse(-a*.15,-a*.85,a*.12,a*.08,0,0,Math.PI*2),e.ellipse(a*.15,-a*.85,a*.12,a*.08,0,0,Math.PI*2),e.fill();const y=.6+Math.sin(n*.008+o.wailPhase)*.4;e.fillStyle=`rgba(100, 255, 150, ${y})`,e.shadowColor="#64ff96",e.shadowBlur=a*.6,e.beginPath(),e.arc(-a*.15,-a*.85,a*.08,0,Math.PI*2),e.arc(a*.15,-a*.85,a*.08,0,Math.PI*2),e.fill(),e.shadowBlur=0;const P=.2+Math.sin(n*.01+o.wailPhase)*.1;e.fillStyle="rgba(80, 150, 80, 0.7)",e.strokeStyle="rgba(50, 100, 50, 0.8)",e.lineWidth=a*.02,e.beginPath(),e.ellipse(0,-a*.6,a*.15,a*(.2+P),0,0,Math.PI*2),e.fill(),e.stroke(),e.restore(),e.strokeStyle="rgba(220, 255, 220, 0.7)";for(let l=0;l<12;l++){const d=-a*.35+l/11*a*.7,f=Math.sin(n*.01+l*.6+o.wailPhase)*a*.5,g=Math.cos(n*.008+l*.4)*a*.3;e.lineWidth=a*(.04+l%3*.02),e.beginPath(),e.moveTo(d,-a*1.1),e.bezierCurveTo(d+f*.3,-a*.5,d+f*.6+g*.5,a*.2,d+f+g,a*1+l%2*a*.5),e.stroke()}const u=Math.sin(n*.01+o.wailPhase)*a*.3;e.fillStyle="rgba(230, 255, 230, 0.8)",e.strokeStyle="rgba(180, 230, 180, 0.6)",e.lineWidth=a*.02,e.save(),e.translate(-a*.6,-a*.2),e.rotate(-.3+u*.002),e.beginPath(),e.ellipse(0,0,a*.15,a*.25,0,0,Math.PI*2),e.fill(),e.stroke();for(let l=0;l<4;l++){const d=-a*.08+l*a*.055;e.beginPath(),e.moveTo(d,a*.15),e.lineTo(d,a*.35),e.stroke()}e.restore(),e.save(),e.translate(a*.6,-a*.2),e.rotate(.3-u*.002),e.beginPath(),e.ellipse(0,0,a*.15,a*.25,0,0,Math.PI*2),e.fill(),e.stroke();for(let l=0;l<4;l++){const d=-a*.08+l*a*.055;e.beginPath(),e.moveTo(d,a*.15),e.lineTo(d,a*.35),e.stroke()}e.restore(),e.strokeStyle="rgba(180, 255, 180, 0.3)",e.lineWidth=a*.02;for(let l=0;l<6;l++){const d=l/6*Math.PI*2,f=Math.sin(n*.01+l*.8)*a*.6,g=a*(1.5+l%2*.5);e.beginPath(),e.moveTo(0,a*.4),e.bezierCurveTo(Math.cos(d)*a*.8+f*.5,a*1,Math.cos(d)*a*1.5+f,a*1.8,Math.cos(d)*g+f*1.5,a*2.5),e.stroke()}e.restore()},drawMoon(e,o,n){const t=o.x,r=o.y,a=o.size;e.save(),e.globalAlpha=o.opacity,e.translate(t,r);const s=e.createRadialGradient(-a*.2,-a*.2,0,0,0,a);s.addColorStop(0,"#90EE90"),s.addColorStop(.5,"#7FD87F"),s.addColorStop(1,"#5CB85C"),e.fillStyle=s,e.beginPath(),e.arc(0,0,a,0,Math.PI*2),e.fill(),e.fillStyle="rgba(60, 130, 60, 0.3)",e.beginPath(),e.arc(-a*.3,-a*.2,a*.15,0,Math.PI*2),e.fill(),e.beginPath(),e.arc(a*.25,a*.1,a*.2,0,Math.PI*2),e.fill(),e.beginPath(),e.arc(a*.1,-a*.4,a*.12,0,Math.PI*2),e.fill(),e.save(),e.translate(a*.2,a*.35),e.scale(.15,.15),e.fillStyle="rgba(34, 139, 34, 0.4)";for(let M=0;M<3;M++){const y=M/3*Math.PI*2-Math.PI/2;e.save(),e.rotate(y),e.translate(0,-a*.7),e.beginPath(),e.moveTo(0,a*.3),e.bezierCurveTo(-a*.5,-a*.2,-a*.3,-a*.6,0,-a*.35),e.bezierCurveTo(a*.3,-a*.6,a*.5,-a*.2,0,a*.3),e.closePath(),e.fill(),e.restore()}e.restore();const i=.3+Math.sin(n*.002+o.glowPhase)*.15;e.globalAlpha=i;const h=e.createRadialGradient(0,0,a*.8,0,0,a*1.8);h.addColorStop(0,"rgba(144, 238, 144, 0.8)"),h.addColorStop(.5,"rgba(144, 238, 144, 0.4)"),h.addColorStop(1,"rgba(144, 238, 144, 0)"),e.fillStyle=h,e.beginPath(),e.arc(0,0,a*1.8,0,Math.PI*2),e.fill(),e.restore()},drawStaticLeprechaun:v,drawTwinklingStar(e,o,n){const t=o.x,r=o.y,a=o.size,s=.5+Math.sin(n*o.twinkleSpeed+o.twinklePhase)*.5,i=`rgba(220, 255, 220, ${s})`,h=`rgba(180, 255, 180, ${s*.4})`;e.save(),e.translate(t,r),e.shadowColor=h,e.shadowBlur=a*3*s,e.fillStyle=i,e.beginPath();for(let M=0;M<4;M++){const y=M*Math.PI/2,P=Math.cos(y)*a,u=Math.sin(y)*a,l=y+Math.PI/4,d=Math.cos(l)*(a*.3),f=Math.sin(l)*(a*.3);M===0?e.moveTo(P,u):e.lineTo(P,f),e.lineTo(d,f)}e.closePath(),e.fill(),e.shadowBlur=a*2*s,e.beginPath(),e.arc(0,0,a*.25,0,Math.PI*2),e.fill(),e.restore()}};
1
+ import{drawBanshee as p}from"./spooky-props-drawing.js";import{drawPotOfGold as w,drawSmallGoldPot as P,drawRainbow as g}from"./heritage-drawing.js";import{drawMooningLeprechaun as b}from"./mooning-drawing.js";import{spawnMooningCharacter as S,updateMooningCharacter as z}from"./mooning-antics.js";import{drawLeprechaun as C,drawStaticLeprechaun as k}from"./character-drawing.js";export default{name:"st-patricks",displayName:"St Patrick's Day",emoji:"\u2618\uFE0F",intensityConfig:{light:{count:40,speedRange:[.4,1.2],sizeRange:[2,4],pots:1,leprechaunChance:3e-4,twinklingStars:10},medium:{count:80,speedRange:[.5,1.5],sizeRange:[2,5],pots:2,leprechaunChance:5e-4,twinklingStars:18},heavy:{count:120,speedRange:[.6,1.8],sizeRange:[3,6],pots:3,leprechaunChance:8e-4,twinklingStars:25}},particles:["clover-petal","shamrock","gold-coin","sparkle"],decorations:["pot-of-gold","rainbow","leprechaun","harp","static-leprechaun","moon","twinkling-star","mooning-leprechaun"],optInDecorations:{mooningLeprechaun:{chance:"mooningLeprechaunChance",value:5e-4}},colors:{primary:"#228B22",secondary:"#90EE90",white:"#FFFFFF",accent:"#FFD700",rainbow:["#ff0000","#ffa500","#ffff00","#00ff00","#0000ff","#4b0082","#8b00ff"]},createCloverPetal(e,o,n){const r=["#228B22","#32CD32","#90EE90","#3CB371","#2E8B57"];return{type:"clover-petal",x:Math.random()*e,y:Math.random()*o,vx:n.speedRange[0]+Math.random()*(n.speedRange[1]-n.speedRange[0]),size:(n.sizeRange[0]+Math.random()*(n.sizeRange[1]-n.sizeRange[0]))*1.5,speed:(Math.random()-.5)*.2,opacity:.75+Math.random()*.25,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.025,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.03,color:r[Math.floor(Math.random()*r.length)],flutter:Math.random()*Math.PI*2,flutterSpeed:.02+Math.random()*.02,active:!0}},createShamrock(e,o,n){const r=Math.random();let t,a;return r<.5?(t="#228B22",a="#006400"):r<.75?(t="#FFFFFF",a="#d0d0d0"):(t="#FFD700",a="#DAA520"),{type:"shamrock",x:Math.random()*e,y:Math.random()*o,vx:n.speedRange[0]+Math.random()*(n.speedRange[1]-n.speedRange[0]),size:n.sizeRange[0]+Math.random()*(n.sizeRange[1]-n.sizeRange[0]),speed:(Math.random()-.5)*.15,opacity:.7+Math.random()*.3,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.025,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.02,color:t,strokeColor:a,active:!0}},createGoldCoin(e,o,n){return{type:"gold-coin",x:Math.random()*e,y:Math.random()*o,vx:(n.speedRange[0]+Math.random()*(n.speedRange[1]-n.speedRange[0]))*.8,size:2+Math.random()*3,speed:(Math.random()-.5)*.1,opacity:.9+Math.random()*.1,rotation:0,rotationSpeed:.05+Math.random()*.1,spinPhase:Math.random()*Math.PI*2,glintPhase:Math.random()*Math.PI*2,windOffset:Math.random()*Math.PI*2,windSpeed:.01+Math.random()*.02,active:!0}},createPotOfGold(e,o,n={}){return{type:"pot-of-gold",x:n.x!==void 0?n.x:Math.random()*e*.6+e*.2,y:n.y!==void 0?n.y:o-40,size:20+Math.random()*10,opacity:1,glintPhase:Math.random()*Math.PI*2,coins:[],active:!0,static:!0}},createRainbow(e,o,n,r){const a=n,s=(20+n)/2,h=o*.2,l=r-h/2;return{type:"rainbow",x:s,y:l,startX:20,endX:a,endY:r,width:e,height:o,opacity:.7,vx:0,vy:0,active:!0,static:!0}},createSparkle(e,o,n){const r=["#FFD700","#FFFFFF","#228B22"];return{type:"sparkle",x:Math.random()*e,y:Math.random()*o,vx:(n.speedRange[0]+Math.random()*(n.speedRange[1]-n.speedRange[0]))*.8,size:n.sizeRange[0]+Math.random()*(n.sizeRange[1]-n.sizeRange[0])*.6,vy:(Math.random()-.5)*.2,opacity:.6+Math.random()*.4,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.04,color:r[Math.floor(Math.random()*r.length)],twinklePhase:Math.random()*Math.PI*2,windOffset:Math.random()*Math.PI*2,windSpeed:.015+Math.random()*.02,active:!0,static:!1}},createFallingParticle(e,o,n){const r=Math.random();return r<.6?this.createCloverPetal(e,o,n):r<.8?this.createShamrock(e,o,n):r<.95?this.createGoldCoin(e,o,n):this.createSparkle(e,o,n)},createInitialDecorations(e,o,n){const r=[];r.push({type:"moon",x:e-120,y:100,size:60+Math.random()*20,opacity:.85,glowPhase:Math.random()*Math.PI*2,active:!0,static:!0});const t=20,a=220,s=o-40;r.push(this.createPotOfGold(e,o,{x:a,y:s})),r.push(this.createRainbow(e,o,a,s));const h=1+Math.floor(Math.random()*2);for(let i=0;i<h;i++){const d=60+Math.random()*(e-120);r.push({type:"static-leprechaun",x:d,y:o-35,size:12+Math.random()*4,opacity:1,time:Math.random()*1e3,wavePhase:Math.random()*Math.PI*2,active:!0,static:!0})}const l=n.twinklingStars??18;for(let i=0;i<l;i++)r.push(this.createTwinklingStar(e,o));return r},createTwinklingStar(e,o){return{type:"twinkling-star",x:Math.random()*e,y:Math.random()*(o*.5),size:1+Math.random()*2,opacity:.6+Math.random()*.3,twinklePhase:Math.random()*Math.PI*2,twinkleSpeed:.003+Math.random()*.003,active:!0,static:!0}},spawnSpecialParticle(e,o,n,r){const t=S(e,o,n,r,"mooning-leprechaun","mooningLeprechaunChance");if(t)return t;const a=Math.random();if(a<r.leprechaunChance){if(e.some(i=>i.type==="leprechaun"))return null;const s=Math.random()<.5,h=(o+100)/180;return{type:"leprechaun",x:s?-50:o+50,y:n-35,baseY:n-35,vx:s?h:-h,vy:0,size:12+Math.random()*6,opacity:1,time:0,legPhase:Math.random()*Math.PI*2,active:!0,static:!1}}if(a<r.leprechaunChance+3e-4){if(e.some(h=>h.type==="banshee"))return null;const s=Math.random()<.5;return{type:"banshee",x:s?-100:o+100,y:Math.random()*(n*.4)+50,baseY:Math.random()*(n*.4)+50,vx:s?2+Math.random()*1:-(2+Math.random()*1),size:18+Math.random()*10,opacity:.6+Math.random()*.2,waveAmplitude:25+Math.random()*20,waveFrequency:.0015+Math.random()*.002,waveOffset:Math.random()*Math.PI*2,time:0,wailPhase:Math.random()*Math.PI*2,active:!0,static:!1}}if(a<.001&&e.filter(h=>h.type==="pot-of-gold").length<r.pots){const h=this.createPotOfGold(o,n),l=this.createRainbow(o,n,h.x,h.y);return e.push(l),h}return null},updateSpecialParticles(e,o,n,r){return e.forEach(t=>{if(t.active){if(t.type==="mooning-leprechaun"){z(t,o,n);return}(t.type==="leprechaun"||t.type==="banshee")&&(t.time+=o,t.type==="leprechaun"?(t.vx>0&&t.x>n+t.size*2||t.vx<0&&t.x<-t.size*2)&&(t.active=!1):t.type==="banshee"&&(t.vx>0&&t.x>n+t.size*4||t.vx<0&&t.x<-t.size*4)&&(t.active=!1)),t.type==="static-leprechaun"&&(t.time+=o)}}),e.filter(t=>t.active)},drawCloverPetal(e,o,n){const r=o.x,t=o.y,a=o.size,s=Math.sin(n*o.flutterSpeed+o.flutter)*.3;e.save(),e.globalAlpha=o.opacity,e.translate(r,t),e.rotate(o.rotation+s),e.fillStyle=o.color,e.strokeStyle="#006400",e.lineWidth=a*.08,e.beginPath(),e.moveTo(0,-a*.3),e.bezierCurveTo(-a*.6,-a*.7,-a*.8,-a*.3,-a*.5,a*.2),e.lineTo(0,a*.8),e.lineTo(a*.5,a*.2),e.bezierCurveTo(a*.8,-a*.3,a*.6,-a*.7,0,-a*.3),e.closePath(),e.fill(),e.stroke(),e.strokeStyle="rgba(0, 100, 0, 0.4)",e.lineWidth=a*.06,e.beginPath(),e.moveTo(0,-a*.2),e.lineTo(0,a*.7),e.stroke(),e.restore()},drawSparkle(e,o,n){const r=o.x,t=o.y,a=o.size,s=.6+Math.sin(n*.004+o.twinklePhase)*.4;e.save(),e.globalAlpha=o.opacity*s,e.translate(r,t),e.rotate(o.rotation),e.fillStyle=o.color,e.shadowColor=o.color,e.shadowBlur=a*2,e.beginPath(),e.moveTo(0,-a),e.lineTo(a*.3,-a*.3),e.lineTo(a,0),e.lineTo(a*.3,a*.3),e.lineTo(0,a),e.lineTo(-a*.3,a*.3),e.lineTo(-a,0),e.lineTo(-a*.3,-a*.3),e.closePath(),e.fill(),e.restore()},drawShamrock(e,o){const n=o.x,r=o.y,t=o.size;e.save(),e.globalAlpha=o.opacity,e.translate(n,r),e.rotate(o.rotation),e.fillStyle=o.color||"#228B22",e.strokeStyle=o.strokeColor||"#006400",e.lineWidth=t*.1;for(let a=0;a<3;a++){const s=a/3*Math.PI*2-Math.PI/2;e.save(),e.rotate(s),e.translate(0,-t*.7),e.beginPath(),e.moveTo(0,t*.3),e.bezierCurveTo(-t*.5,-t*.2,-t*.3,-t*.6,0,-t*.35),e.bezierCurveTo(t*.3,-t*.6,t*.5,-t*.2,0,t*.3),e.closePath(),e.fill(),e.stroke(),e.restore()}e.strokeStyle="#8B4513",e.lineWidth=t*.15,e.beginPath(),e.moveTo(0,0),e.lineTo(0,t*1.2),e.stroke(),e.restore()},drawGoldCoin(e,o,n){const r=o.x,t=o.y,a=o.size,s=Math.abs(Math.cos(o.rotation))*a;if(e.save(),e.globalAlpha=o.opacity,e.translate(r,t),e.fillStyle="#FFD700",e.strokeStyle="#DAA520",e.lineWidth=a*.15,e.beginPath(),e.ellipse(0,0,s,a,0,0,Math.PI*2),e.fill(),e.stroke(),s>a*.3){const h=(Math.sin(n*.005+o.glintPhase)+1)*.5;e.fillStyle=`rgba(255, 255, 255, ${h*.6})`,e.beginPath(),e.ellipse(-s*.3,-a*.3,s*.3,a*.3,0,0,Math.PI*2),e.fill()}e.restore()},drawPotOfGold:w,drawSmallGoldPot:P,drawRainbow:g,drawLeprechaun:C,drawMooningLeprechaun:b,drawBanshee:p,drawMoon(e,o,n){const r=o.x,t=o.y,a=o.size;e.save(),e.globalAlpha=o.opacity,e.translate(r,t);const s=e.createRadialGradient(-a*.2,-a*.2,0,0,0,a);s.addColorStop(0,"#90EE90"),s.addColorStop(.5,"#7FD87F"),s.addColorStop(1,"#5CB85C"),e.fillStyle=s,e.beginPath(),e.arc(0,0,a,0,Math.PI*2),e.fill(),e.fillStyle="rgba(60, 130, 60, 0.3)",e.beginPath(),e.arc(-a*.3,-a*.2,a*.15,0,Math.PI*2),e.fill(),e.beginPath(),e.arc(a*.25,a*.1,a*.2,0,Math.PI*2),e.fill(),e.beginPath(),e.arc(a*.1,-a*.4,a*.12,0,Math.PI*2),e.fill(),e.save(),e.translate(a*.2,a*.35),e.scale(.15,.15),e.fillStyle="rgba(34, 139, 34, 0.4)";for(let i=0;i<3;i++){const d=i/3*Math.PI*2-Math.PI/2;e.save(),e.rotate(d),e.translate(0,-a*.7),e.beginPath(),e.moveTo(0,a*.3),e.bezierCurveTo(-a*.5,-a*.2,-a*.3,-a*.6,0,-a*.35),e.bezierCurveTo(a*.3,-a*.6,a*.5,-a*.2,0,a*.3),e.closePath(),e.fill(),e.restore()}e.restore();const h=.3+Math.sin(n*.002+o.glowPhase)*.15;e.globalAlpha=h;const l=e.createRadialGradient(0,0,a*.8,0,0,a*1.8);l.addColorStop(0,"rgba(144, 238, 144, 0.8)"),l.addColorStop(.5,"rgba(144, 238, 144, 0.4)"),l.addColorStop(1,"rgba(144, 238, 144, 0)"),e.fillStyle=l,e.beginPath(),e.arc(0,0,a*1.8,0,Math.PI*2),e.fill(),e.restore()},drawStaticLeprechaun:k,drawTwinklingStar(e,o,n){const r=o.x,t=o.y,a=o.size,s=.5+Math.sin(n*o.twinkleSpeed+o.twinklePhase)*.5,h=`rgba(220, 255, 220, ${s})`,l=`rgba(180, 255, 180, ${s*.4})`;e.save(),e.translate(r,t),e.shadowColor=l,e.shadowBlur=a*3*s,e.fillStyle=h,e.beginPath();for(let i=0;i<4;i++){const d=i*Math.PI/2,M=Math.cos(d)*a,y=Math.sin(d)*a,m=d+Math.PI/4,f=Math.cos(m)*(a*.3),u=Math.sin(m)*(a*.3);i===0?e.moveTo(M,y):e.lineTo(M,u),e.lineTo(f,u)}e.closePath(),e.fill(),e.shadowBlur=a*2*s,e.beginPath(),e.arc(0,0,a*.25,0,Math.PI*2),e.fill(),e.restore()}};
@@ -1 +1 @@
1
- import{drawCupid as v}from"./character-drawing.js";import{drawIllustratedButterfly as z}from"./butterfly-drawing.js";export default{name:"valentines",displayName:"Valentine's Day",emoji:"\u{1F495}",intensityConfig:{light:{count:40,speedRange:[.3,.8],sizeRange:[2,4],garlands:1,cupidChance:3e-4},medium:{count:80,speedRange:[.4,1.2],sizeRange:[2,5],garlands:2,cupidChance:5e-4},heavy:{count:150,speedRange:[.5,1.5],sizeRange:[3,6],garlands:3,cupidChance:8e-4}},particles:["heart","rose-petal","sparkle","lips"],decorations:["cupid","love-letter","heart-garland","envelope","butterfly","heart-moon","neon-sign"],colors:{primary:"#ff1493",secondary:"#ff69b4",accent:"#dc143c",light:"#ffb6c1",gold:"#ffd700"},createHeart(e,o,s){const n=Math.random();let t,a,l;const h=["#ff1493","#ff69b4","#dc143c","#ffb6c1","#ff0080"];return n<.33?(t=s.sizeRange[0]+Math.random()*(s.sizeRange[1]-s.sizeRange[0])*1.5,a=s.speedRange[0]+Math.random()*(s.speedRange[1]-s.speedRange[0]),l=.8+Math.random()*.2):n<.66?(t=s.sizeRange[0]+Math.random()*(s.sizeRange[1]-s.sizeRange[0]),a=s.speedRange[0]+Math.random()*(s.speedRange[1]-s.speedRange[0]),l=.6+Math.random()*.2):(t=s.sizeRange[0]+Math.random()*(s.sizeRange[1]-s.sizeRange[0])*.8,a=s.speedRange[0]+Math.random()*(s.speedRange[1]-s.speedRange[0])*.8,l=.4+Math.random()*.2),{type:"heart",x:Math.random()*e,y:Math.random()*o,size:t,vx:(Math.random()-.5)*.3,vy:(Math.random()-.7)*.2,speed:a*.3,opacity:l,color:h[Math.floor(Math.random()*h.length)],windOffset:Math.random()*Math.PI*2,windSpeed:.005+Math.random()*.01,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.01,pulsePhase:Math.random()*Math.PI*2,pulseSpeed:.002+Math.random()*.003,floatPhase:Math.random()*Math.PI*2,floatSpeed:.001+Math.random()*.002,active:!0,depth:n}},createRosePetal(e,o,s){const n=["#ff1493","#ff69b4","#dc143c","#ff758f","#ffb6c1"];return{type:"rose-petal",x:Math.random()*e,y:-20,size:1.5+Math.random()*2,speed:s.speedRange[0]+Math.random()*(s.speedRange[1]-s.speedRange[0])*.6,opacity:.7+Math.random()*.3,color:n[Math.floor(Math.random()*n.length)],windOffset:Math.random()*Math.PI*2,windSpeed:.02+Math.random()*.03,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.05,flutterPhase:Math.random()*Math.PI*2,active:!0}},createSparkle(e,o,s){return{type:"sparkle",x:Math.random()*e,y:Math.random()*o,size:.5+Math.random()*1.5,opacity:1,life:20+Math.random()*30,maxLife:20+Math.random()*30,color:Math.random()<.5?"#ffd700":"#ffffff",twinklePhase:Math.random()*Math.PI*2,active:!0,static:!0}},createLips(e,o,s){const n=["#dc143c","#ff1493","#c71585","#ff0066"];return{type:"lips",x:Math.random()*e,y:Math.random()*o,size:3+Math.random()*3,vx:(Math.random()-.5)*.4,vy:(Math.random()-.7)*.2,speed:.3+Math.random()*.2,opacity:.8+Math.random()*.2,color:n[Math.floor(Math.random()*n.length)],rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.01,pulsePhase:Math.random()*Math.PI*2,pulseSpeed:.003+Math.random()*.002,floatPhase:Math.random()*Math.PI*2,floatSpeed:.001+Math.random()*.002,kissPhase:Math.random()*Math.PI*2,active:!0}},createHeartGarland(e,o,s={}){const n=8+Math.floor(Math.random()*5),t=[];for(let a=0;a<n;a++)t.push({offset:a/n,size:8+Math.random()*4,color:Math.random()<.5?"#ff1493":"#ff69b4",pulsePhase:Math.random()*Math.PI*2});return{type:"heart-garland",x:0,y:s.y!==void 0?s.y:50+Math.random()*100,width:e,hearts:t,sag:40+Math.random()*30,swayPhase:Math.random()*Math.PI*2,swayAmplitude:10+Math.random()*10,opacity:.8+Math.random()*.2,active:!0,static:!0}},createLoveLetter(e,o,s={}){const n=Math.random()<.5;return{type:"love-letter",x:n?-50:e+50,y:Math.random()*o*.6,baseY:Math.random()*o*.6,vx:n?1+Math.random()*1:-(1+Math.random()*1),size:12+Math.random()*6,opacity:.9+Math.random()*.1,rotation:(Math.random()-.5)*.3,rotationSpeed:(Math.random()-.5)*.005,waveAmplitude:15+Math.random()*15,waveFrequency:.002+Math.random()*.002,waveOffset:Math.random()*Math.PI*2,time:0,active:!0,static:!1}},createFallingParticle(e,o,s){const n=Math.random();return n<.6?this.createHeart(e,o,s):n<.85?this.createRosePetal(e,o,s):this.createLips(e,o,s)},createInitialDecorations(e,o,s){const n=[],t=s.garlands??2;for(let h=0;h<t;h++)n.push(this.createHeartGarland(e,o,{y:50+h*(o/(t+1))}));const a=4;for(let h=0;h<a;h++)n.push({type:"envelope",x:e/(a+1)*(h+1)+(Math.random()-.5)*30,y:o-25-Math.random()*10,size:15+Math.random()*5,opacity:.85,rotation:(Math.random()-.5)*.3,active:!0,static:!0});const l=s.butterflies??3;for(let h=0;h<l;h++)n.push({type:"butterfly",x:Math.random()*e,y:Math.random()*o*.6+50,baseY:Math.random()*o*.6+50,size:12+Math.random()*6,vx:(Math.random()-.5)*2,vy:0,waveOffset:Math.random()*Math.PI*2,waveFrequency:.003+Math.random()*.002,waveAmplitude:20+Math.random()*15,wingPhase:Math.random()*Math.PI*2,opacity:.9,color:Math.random()<.5?"pink":"purple",active:!0,static:!1});return n.push({type:"heart-moon",x:e*.85,y:o*.15,size:60+Math.random()*20,opacity:.9,glowPhase:Math.random()*Math.PI*2,active:!0,static:!0}),n},spawnSpecialParticle(e,o,s,n){const t=Math.random();if(t<n.cupidChance){if(e.some(l=>l.type==="cupid"))return null;const a=Math.random()<.5;return{type:"cupid",x:a?-100:o+100,y:Math.random()*s*.4+50,baseY:Math.random()*s*.4+50,vx:a?2+Math.random()*1.5:-(2+Math.random()*1.5),size:15+Math.random()*8,opacity:1,waveAmplitude:20+Math.random()*20,waveFrequency:.002+Math.random()*.002,waveOffset:Math.random()*Math.PI*2,time:0,wingPhase:Math.random()*Math.PI*2,active:!0,static:!1}}return t<.001?this.createLoveLetter(o,s):t<.0015?e.some(a=>a.type==="neon-sign"&&a.active)?null:{type:"neon-sign",x:o/2,y:s*.3,size:40+Math.random()*20,opacity:0,targetOpacity:1,phase:"fade-in",phaseTime:0,fadeInDuration:1500,stableDuration:5e3,fadeOutDuration:1e3,crackleIntensity:1,flickerPhase:Math.random()*Math.PI*2,glowPhase:Math.random()*Math.PI*2,tubeFlickers:[],active:!0,static:!1}:t<.02?this.createSparkle(o,s,n):null},drawHeart(e,o,s){const n=o.x,t=o.y,a=o.size,l=1+Math.sin(s*o.pulseSpeed+o.pulsePhase)*.15;e.save(),e.globalAlpha=o.opacity,e.translate(n,t),e.rotate(o.rotation),e.scale(l,l),e.fillStyle=o.color,e.shadowColor=o.color,e.shadowBlur=a*.8,e.beginPath(),e.moveTo(0,a*.3),e.bezierCurveTo(-a,-a*.3,-a*.6,-a,0,-a*.4),e.bezierCurveTo(a*.6,-a,a,-a*.3,0,a*.3),e.closePath(),e.fill(),e.shadowBlur=0,e.fillStyle="rgba(255, 255, 255, 0.3)",e.beginPath(),e.arc(-a*.25,-a*.5,a*.15,0,Math.PI*2),e.fill(),e.restore()},drawRosePetal(e,o,s){const n=o.x,t=o.y,a=o.size,l=Math.sin(s*.01+o.flutterPhase)*.3;e.save(),e.globalAlpha=o.opacity,e.translate(n,t),e.rotate(o.rotation+l),e.fillStyle=o.color,e.strokeStyle="rgba(139, 0, 0, 0.3)",e.lineWidth=.5,e.beginPath(),e.moveTo(0,0),e.bezierCurveTo(a*2,-a,a*2,a,0,0),e.closePath(),e.fill(),e.beginPath(),e.moveTo(0,0),e.quadraticCurveTo(a,0,a*1.5,0),e.stroke(),e.restore()},drawSparkle(e,o,s){const n=o.x,t=o.y,a=o.size,l=o.life/o.maxLife,h=(Math.sin(s*.01+o.twinklePhase)+1)*.5;e.save(),e.globalAlpha=o.opacity*l*h,e.translate(n,t),e.fillStyle=o.color,e.shadowColor=o.color,e.shadowBlur=a*2,e.beginPath();for(let r=0;r<4;r++){const d=r/4*Math.PI*2-Math.PI/2,f=Math.cos(d)*a*3,i=Math.sin(d)*a*3,M=d+Math.PI/4,y=Math.cos(M)*a*.5,p=Math.sin(M)*a*.5;r===0?e.moveTo(f,i):(e.lineTo(y,p),e.lineTo(f,i))}e.closePath(),e.fill(),e.restore()},drawLips(e,o,s){const n=o.x,t=o.y,a=o.size,l=1+Math.sin(s*o.pulseSpeed+o.pulsePhase)*.1,h=Math.sin(s*.008+o.kissPhase);e.save(),e.globalAlpha=o.opacity,e.translate(n,t),e.rotate(o.rotation),e.scale(l,l);const r=e.createRadialGradient(0,0,0,0,0,a*2);r.addColorStop(0,o.color),r.addColorStop(.6,o.color),r.addColorStop(1,"#8b0000"),e.fillStyle=r,e.strokeStyle="#8b0000",e.lineWidth=a*.1,e.beginPath(),e.moveTo(-a,0),e.bezierCurveTo(-a*.8,-a*.8,-a*.3,-a*1,0,-a*.6),e.bezierCurveTo(a*.3,-a*1,a*.8,-a*.8,a,0),e.fill(),e.stroke();const d=h*a*.15;if(e.beginPath(),e.moveTo(-a,0),e.bezierCurveTo(-a*.7,a*(.7+d),-a*.3,a*(1+d),0,a*(.8+d)),e.bezierCurveTo(a*.3,a*(1+d),a*.7,a*(.7+d),a,0),e.fill(),e.stroke(),e.globalAlpha=o.opacity*.5,e.fillStyle="rgba(255, 255, 255, 0.6)",e.beginPath(),e.ellipse(-a*.4,-a*.4,a*.2,a*.15,-.3,0,Math.PI*2),e.fill(),e.beginPath(),e.ellipse(a*.4,-a*.4,a*.2,a*.15,.3,0,Math.PI*2),e.fill(),e.beginPath(),e.ellipse(0,a*.5,a*.3,a*.2,0,0,Math.PI*2),e.fill(),h>.8){const f=a*1.5,i=Math.sin(o.kissPhase)*f,M=-Math.abs(Math.cos(o.kissPhase))*f;e.globalAlpha=o.opacity*(h-.8)*5,e.fillStyle="#ffd700",e.shadowColor="#ffd700",e.shadowBlur=a*.5,e.beginPath(),e.arc(i,M,a*.15,0,Math.PI*2),e.fill();for(let y=0;y<4;y++){const p=y/4*Math.PI*2+s*.01,m=i+Math.cos(p)*a*.4,u=M+Math.sin(p)*a*.4;e.beginPath(),e.moveTo(i,M),e.lineTo(m,u),e.lineWidth=a*.05,e.strokeStyle="#ffffff",e.stroke()}}e.restore()},drawCupid:v,drawLoveLetter(e,o,s){const n=o.x,t=o.y,a=o.size;e.save(),e.globalAlpha=o.opacity,e.translate(n,t),e.rotate(o.rotation),e.fillStyle="#fff5e6",e.strokeStyle="#daa520",e.lineWidth=1,e.fillRect(-a,-a*.7,a*2,a*1.4),e.strokeRect(-a,-a*.7,a*2,a*1.4),e.fillStyle="#ffe4b3",e.beginPath(),e.moveTo(-a,-a*.7),e.lineTo(0,0),e.lineTo(a,-a*.7),e.closePath(),e.fill(),e.stroke(),e.fillStyle="#dc143c",e.shadowColor="#dc143c",e.shadowBlur=5,e.beginPath(),e.moveTo(0,a*.1),e.bezierCurveTo(-a*.3,-a*.1,-a*.2,-a*.3,0,-a*.15),e.bezierCurveTo(a*.2,-a*.3,a*.3,-a*.1,0,a*.1),e.closePath(),e.fill(),e.shadowBlur=0,e.restore()},drawHeartGarland(e,o,s){const n=o.y,t=o.width,a=o.sag,l=o.hearts;e.save(),e.globalAlpha=o.opacity;const h=Math.sin(s*.001+o.swayPhase)*o.swayAmplitude;e.strokeStyle="#daa520",e.lineWidth=2,e.beginPath(),e.moveTo(0,n),e.quadraticCurveTo(t/2,n+a+h,t,n),e.stroke(),l.forEach(r=>{const d=r.offset*t,f=n+Math.sin(Math.PI*r.offset)*(a+h),i=1+Math.sin(s*.003+r.pulsePhase)*.1;e.save(),e.translate(d,f),e.scale(i,i),e.fillStyle=r.color,e.shadowColor=r.color,e.shadowBlur=r.size*.5,e.beginPath(),e.moveTo(0,r.size*.3),e.bezierCurveTo(-r.size,-r.size*.3,-r.size*.6,-r.size,0,-r.size*.4),e.bezierCurveTo(r.size*.6,-r.size,r.size,-r.size*.3,0,r.size*.3),e.closePath(),e.fill(),e.shadowBlur=0,e.restore()}),e.restore()},drawEnvelope(e,o,s){const n=o.x,t=o.y,a=o.size;e.save(),e.globalAlpha=o.opacity,e.translate(n,t),e.rotate(o.rotation),e.fillStyle="#fff5f5",e.strokeStyle="#ff69b4",e.lineWidth=a*.05,e.fillRect(-a*.7,-a*.5,a*1.4,a),e.strokeRect(-a*.7,-a*.5,a*1.4,a),e.fillStyle="#ffe4e1",e.beginPath(),e.moveTo(-a*.7,-a*.5),e.lineTo(0,a*.1),e.lineTo(a*.7,-a*.5),e.closePath(),e.fill(),e.stroke(),e.fillStyle="#ff1493",e.shadowColor="#ff1493",e.shadowBlur=a*.3,e.beginPath(),e.moveTo(0,a*.25),e.bezierCurveTo(-a*.3,-a*.1,-a*.2,-a*.3,0,-a*.15),e.bezierCurveTo(a*.2,-a*.3,a*.3,-a*.1,0,a*.25),e.closePath(),e.fill(),e.shadowBlur=0,e.restore()},drawButterfly(e,o,s=0){const n=s*(o.waveFrequency||0)+(o.waveOffset||0),t=o.waveAmplitude||0,a=o.color==="purple";z(e,{x:o.x+Math.sin(n)*t,y:(o.baseY??o.y)+Math.cos(s*(o.waveFrequency||0)*.7+(o.waveOffset||0))*t*.6,size:o.size*1.6,heading:-Math.PI/2,flapPhase:s*.01+(o.wingPhase||0),colourUpper:a?"#b48aba":"#d897b3",colourLower:a?"#896eaa":"#bb7798",alpha:o.opacity??1})},drawHeartMoon(e,o,s){const n=o.x,t=o.y,a=o.size,l=.3+Math.sin(s*.002+o.glowPhase)*.2;e.save(),e.globalAlpha=o.opacity,e.translate(n,t);const h=e.createRadialGradient(0,0,a*.5,0,0,a*2.5);h.addColorStop(0,`rgba(255, 182, 193, ${l*.8})`),h.addColorStop(.4,`rgba(255, 105, 180, ${l*.5})`),h.addColorStop(.7,`rgba(255, 20, 147, ${l*.3})`),h.addColorStop(1,"rgba(255, 20, 147, 0)"),e.fillStyle=h,e.beginPath(),e.arc(0,0,a*2.5,0,Math.PI*2),e.fill();const r=e.createRadialGradient(-a*.3,-a*.3,0,0,0,a);r.addColorStop(0,"#ffcce0"),r.addColorStop(.5,"#ffb3d9"),r.addColorStop(1,"#ff69b4"),e.fillStyle=r,e.beginPath(),e.moveTo(0,a*.3),e.bezierCurveTo(-a*.5,a*.5,-a,a*.2,-a,-a*.2),e.bezierCurveTo(-a,-a*.6,-a*.5,-a*.7,0,-a*.3),e.bezierCurveTo(a*.5,-a*.7,a,-a*.6,a,-a*.2),e.bezierCurveTo(a,a*.2,a*.5,a*.5,0,a*.3),e.closePath(),e.fill(),e.strokeStyle="#ff1493",e.lineWidth=a*.02,e.stroke(),e.fillStyle="rgba(255, 240, 245, 0.4)",e.beginPath(),e.arc(-a*.4,-a*.1,a*.15,0,Math.PI*2),e.fill(),e.beginPath(),e.arc(a*.3,0,a*.12,0,Math.PI*2),e.fill(),e.beginPath(),e.arc(-a*.2,a*.15,a*.1,0,Math.PI*2),e.fill(),e.fillStyle=`rgba(255, 255, 255, ${l})`;const d=[{x:-a*.3,y:-a*.4},{x:a*.2,y:-a*.3},{x:0,y:0},{x:-a*.5,y:a*.1},{x:a*.4,y:a*.15}];for(const f of d){e.save(),e.translate(f.x,f.y),e.beginPath();const i=a*.08;e.moveTo(0,-i),e.lineTo(i*.2,-i*.2),e.lineTo(i,0),e.lineTo(i*.2,i*.2),e.lineTo(0,i),e.lineTo(-i*.2,i*.2),e.lineTo(-i,0),e.lineTo(-i*.2,-i*.2),e.closePath(),e.fill(),e.restore()}e.restore()},drawNeonSign(e,o,s){const n=o.x,t=o.y,a=o.size;if(o.phaseTime+=16,o.phase==="fade-in"&&o.phaseTime>=o.fadeInDuration)o.phase="stable",o.phaseTime=0,o.opacity=o.targetOpacity,o.crackleIntensity=0;else if(o.phase==="stable"&&o.phaseTime>=o.stableDuration)o.phase="fade-out",o.phaseTime=0;else if(o.phase==="fade-out"&&o.phaseTime>=o.fadeOutDuration){o.active=!1;return}o.phase==="fade-in"?(o.opacity=o.phaseTime/o.fadeInDuration*o.targetOpacity,o.crackleIntensity=1-o.phaseTime/o.fadeInDuration):o.phase==="fade-out"&&(o.opacity=o.targetOpacity*(1-o.phaseTime/o.fadeOutDuration)),e.save(),e.translate(n,t);const l="#ff1493",h="#ff0066",r="#ffffff",d="Happy Valentine's Day",f=a;e.font=`bold ${f}px 'Arial Black', sans-serif`,e.textAlign="center",e.textBaseline="middle";const i=e.measureText(d).width;let M=0;o.crackleIntensity>0&&(M=(Math.random()-.5)*o.crackleIntensity*5);const y=d.split("");let p=-i/2;for(let m=0;m<y.length;m++){const u=y[m],P=e.measureText(u).width,w=(o.crackleIntensity>0?Math.random()<o.crackleIntensity*.3:!1)?o.opacity*(.3+Math.random()*.7):o.opacity;e.save(),e.translate(p+P/2,M),e.globalAlpha=w;const g=.8+Math.sin(s*.002+o.glowPhase+m*.5)*.2;e.shadowColor=l,e.shadowBlur=a*.8*g,e.fillStyle=l,e.fillText(u,0,0),e.shadowBlur=a*.5*g,e.fillStyle=h,e.fillText(u,0,0),e.shadowBlur=a*.3*g,e.fillStyle=r,e.fillText(u,0,0),e.shadowBlur=0,e.fillStyle=r,e.globalAlpha=w*.9,e.fillText(u,0,0),e.restore(),p+=P}if(o.crackleIntensity>.3){for(let m=0;m<3;m++)if(Math.random()<o.crackleIntensity*.5){const u=(Math.random()-.5)*i,P=(Math.random()-.5)*a*.3,b=2+Math.random()*3;e.save(),e.globalAlpha=o.opacity*Math.random(),e.fillStyle=Math.random()<.5?l:r,e.shadowColor=l,e.shadowBlur=b*4,e.beginPath(),e.arc(u,P,b,0,Math.PI*2),e.fill(),e.restore()}}(o.phase==="stable"||o.phase==="fade-out")&&(e.globalAlpha=o.opacity*.1,e.fillStyle="#ff1493",e.fillRect(-i*.55,-a*.6,i*1.1,a*1.2)),e.restore()}};
1
+ import{drawLips as v,drawLoveLetter as I,drawEnvelope as z,drawHeartGarland as S}from"./romantic-drawing.js";import{drawCupid as T}from"./character-drawing.js";import{drawIllustratedButterfly as k}from"./butterfly-drawing.js";export default{name:"valentines",displayName:"Valentine's Day",emoji:"\u{1F495}",intensityConfig:{light:{count:40,speedRange:[.3,.8],sizeRange:[2,4],garlands:1,cupidChance:3e-4},medium:{count:80,speedRange:[.4,1.2],sizeRange:[2,5],garlands:2,cupidChance:5e-4},heavy:{count:150,speedRange:[.5,1.5],sizeRange:[3,6],garlands:3,cupidChance:8e-4}},particles:["heart","rose-petal","sparkle","lips"],decorations:["cupid","love-letter","heart-garland","envelope","butterfly","heart-moon","neon-sign"],colors:{primary:"#ff1493",secondary:"#ff69b4",accent:"#dc143c",light:"#ffb6c1",gold:"#ffd700"},createHeart(e,a,t){const n=Math.random();let r,o,s;const h=["#ff1493","#ff69b4","#dc143c","#ffb6c1","#ff0080"];return n<.33?(r=t.sizeRange[0]+Math.random()*(t.sizeRange[1]-t.sizeRange[0])*1.5,o=t.speedRange[0]+Math.random()*(t.speedRange[1]-t.speedRange[0]),s=.8+Math.random()*.2):n<.66?(r=t.sizeRange[0]+Math.random()*(t.sizeRange[1]-t.sizeRange[0]),o=t.speedRange[0]+Math.random()*(t.speedRange[1]-t.speedRange[0]),s=.6+Math.random()*.2):(r=t.sizeRange[0]+Math.random()*(t.sizeRange[1]-t.sizeRange[0])*.8,o=t.speedRange[0]+Math.random()*(t.speedRange[1]-t.speedRange[0])*.8,s=.4+Math.random()*.2),{type:"heart",x:Math.random()*e,y:Math.random()*a,size:r,vx:(Math.random()-.5)*.3,vy:(Math.random()-.7)*.2,speed:o*.3,opacity:s,color:h[Math.floor(Math.random()*h.length)],windOffset:Math.random()*Math.PI*2,windSpeed:.005+Math.random()*.01,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.01,pulsePhase:Math.random()*Math.PI*2,pulseSpeed:.002+Math.random()*.003,floatPhase:Math.random()*Math.PI*2,floatSpeed:.001+Math.random()*.002,active:!0,depth:n}},createRosePetal(e,a,t){const n=["#ff1493","#ff69b4","#dc143c","#ff758f","#ffb6c1"];return{type:"rose-petal",x:Math.random()*e,y:-20,size:1.5+Math.random()*2,speed:t.speedRange[0]+Math.random()*(t.speedRange[1]-t.speedRange[0])*.6,opacity:.7+Math.random()*.3,color:n[Math.floor(Math.random()*n.length)],windOffset:Math.random()*Math.PI*2,windSpeed:.02+Math.random()*.03,rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.05,flutterPhase:Math.random()*Math.PI*2,active:!0}},createSparkle(e,a,t){return{type:"sparkle",x:Math.random()*e,y:Math.random()*a,size:.5+Math.random()*1.5,opacity:1,life:20+Math.random()*30,maxLife:20+Math.random()*30,color:Math.random()<.5?"#ffd700":"#ffffff",twinklePhase:Math.random()*Math.PI*2,active:!0,static:!0}},createLips(e,a,t){const n=["#dc143c","#ff1493","#c71585","#ff0066"];return{type:"lips",x:Math.random()*e,y:Math.random()*a,size:3+Math.random()*3,vx:(Math.random()-.5)*.4,vy:(Math.random()-.7)*.2,speed:.3+Math.random()*.2,opacity:.8+Math.random()*.2,color:n[Math.floor(Math.random()*n.length)],rotation:Math.random()*Math.PI*2,rotationSpeed:(Math.random()-.5)*.01,pulsePhase:Math.random()*Math.PI*2,pulseSpeed:.003+Math.random()*.002,floatPhase:Math.random()*Math.PI*2,floatSpeed:.001+Math.random()*.002,kissPhase:Math.random()*Math.PI*2,active:!0}},createHeartGarland(e,a,t={}){const n=8+Math.floor(Math.random()*5),r=[];for(let o=0;o<n;o++)r.push({offset:o/n,size:8+Math.random()*4,color:Math.random()<.5?"#ff1493":"#ff69b4",pulsePhase:Math.random()*Math.PI*2});return{type:"heart-garland",x:0,y:t.y!==void 0?t.y:50+Math.random()*100,width:e,hearts:r,sag:40+Math.random()*30,swayPhase:Math.random()*Math.PI*2,swayAmplitude:10+Math.random()*10,opacity:.8+Math.random()*.2,active:!0,static:!0}},createLoveLetter(e,a,t={}){const n=Math.random()<.5;return{type:"love-letter",x:n?-50:e+50,y:Math.random()*a*.6,baseY:Math.random()*a*.6,vx:n?1+Math.random()*1:-(1+Math.random()*1),size:12+Math.random()*6,opacity:.9+Math.random()*.1,rotation:(Math.random()-.5)*.3,rotationSpeed:(Math.random()-.5)*.005,waveAmplitude:15+Math.random()*15,waveFrequency:.002+Math.random()*.002,waveOffset:Math.random()*Math.PI*2,time:0,active:!0,static:!1}},createFallingParticle(e,a,t){const n=Math.random();return n<.6?this.createHeart(e,a,t):n<.85?this.createRosePetal(e,a,t):this.createLips(e,a,t)},createInitialDecorations(e,a,t){const n=[],r=t.garlands??2;for(let h=0;h<r;h++)n.push(this.createHeartGarland(e,a,{y:50+h*(a/(r+1))}));const o=4;for(let h=0;h<o;h++)n.push({type:"envelope",x:e/(o+1)*(h+1)+(Math.random()-.5)*30,y:a-25-Math.random()*10,size:15+Math.random()*5,opacity:.85,rotation:(Math.random()-.5)*.3,active:!0,static:!0});const s=t.butterflies??3;for(let h=0;h<s;h++)n.push({type:"butterfly",x:Math.random()*e,y:Math.random()*a*.6+50,baseY:Math.random()*a*.6+50,size:12+Math.random()*6,vx:(Math.random()-.5)*2,vy:0,waveOffset:Math.random()*Math.PI*2,waveFrequency:.003+Math.random()*.002,waveAmplitude:20+Math.random()*15,wingPhase:Math.random()*Math.PI*2,opacity:.9,color:Math.random()<.5?"pink":"purple",active:!0,static:!1});return n.push({type:"heart-moon",x:e*.85,y:a*.15,size:60+Math.random()*20,opacity:.9,glowPhase:Math.random()*Math.PI*2,active:!0,static:!0}),n},spawnSpecialParticle(e,a,t,n){const r=Math.random();if(r<n.cupidChance){if(e.some(s=>s.type==="cupid"))return null;const o=Math.random()<.5;return{type:"cupid",x:o?-100:a+100,y:Math.random()*t*.4+50,baseY:Math.random()*t*.4+50,vx:o?2+Math.random()*1.5:-(2+Math.random()*1.5),size:15+Math.random()*8,opacity:1,waveAmplitude:20+Math.random()*20,waveFrequency:.002+Math.random()*.002,waveOffset:Math.random()*Math.PI*2,time:0,wingPhase:Math.random()*Math.PI*2,active:!0,static:!1}}return r<.001?this.createLoveLetter(a,t):r<.0015?e.some(o=>o.type==="neon-sign"&&o.active)?null:{type:"neon-sign",x:a/2,y:t*.3,size:40+Math.random()*20,opacity:0,targetOpacity:1,phase:"fade-in",phaseTime:0,fadeInDuration:1500,stableDuration:5e3,fadeOutDuration:1e3,crackleIntensity:1,flickerPhase:Math.random()*Math.PI*2,glowPhase:Math.random()*Math.PI*2,tubeFlickers:[],active:!0,static:!1}:r<.02?this.createSparkle(a,t,n):null},drawHeart(e,a,t){const n=a.x,r=a.y,o=a.size,s=1+Math.sin(t*a.pulseSpeed+a.pulsePhase)*.15;e.save(),e.globalAlpha=a.opacity,e.translate(n,r),e.rotate(a.rotation),e.scale(s,s),e.fillStyle=a.color,e.shadowColor=a.color,e.shadowBlur=o*.8,e.beginPath(),e.moveTo(0,o*.3),e.bezierCurveTo(-o,-o*.3,-o*.6,-o,0,-o*.4),e.bezierCurveTo(o*.6,-o,o,-o*.3,0,o*.3),e.closePath(),e.fill(),e.shadowBlur=0,e.fillStyle="rgba(255, 255, 255, 0.3)",e.beginPath(),e.arc(-o*.25,-o*.5,o*.15,0,Math.PI*2),e.fill(),e.restore()},drawRosePetal(e,a,t){const n=a.x,r=a.y,o=a.size,s=Math.sin(t*.01+a.flutterPhase)*.3;e.save(),e.globalAlpha=a.opacity,e.translate(n,r),e.rotate(a.rotation+s),e.fillStyle=a.color,e.strokeStyle="rgba(139, 0, 0, 0.3)",e.lineWidth=.5,e.beginPath(),e.moveTo(0,0),e.bezierCurveTo(o*2,-o,o*2,o,0,0),e.closePath(),e.fill(),e.beginPath(),e.moveTo(0,0),e.quadraticCurveTo(o,0,o*1.5,0),e.stroke(),e.restore()},drawSparkle(e,a,t){const n=a.x,r=a.y,o=a.size,s=a.life/a.maxLife,h=(Math.sin(t*.01+a.twinklePhase)+1)*.5;e.save(),e.globalAlpha=a.opacity*s*h,e.translate(n,r),e.fillStyle=a.color,e.shadowColor=a.color,e.shadowBlur=o*2,e.beginPath();for(let l=0;l<4;l++){const i=l/4*Math.PI*2-Math.PI/2,f=Math.cos(i)*o*3,d=Math.sin(i)*o*3,u=i+Math.PI/4,y=Math.cos(u)*o*.5,p=Math.sin(u)*o*.5;l===0?e.moveTo(f,d):(e.lineTo(y,p),e.lineTo(f,d))}e.closePath(),e.fill(),e.restore()},drawLips:v,drawCupid:T,drawLoveLetter:I,drawHeartGarland:S,drawEnvelope:z,drawButterfly(e,a,t=0){const n=t*(a.waveFrequency||0)+(a.waveOffset||0),r=a.waveAmplitude||0,o=a.color==="purple";k(e,{x:a.x+Math.sin(n)*r,y:(a.baseY??a.y)+Math.cos(t*(a.waveFrequency||0)*.7+(a.waveOffset||0))*r*.6,size:a.size*1.6,heading:-Math.PI/2,flapPhase:t*.01+(a.wingPhase||0),colourUpper:o?"#b48aba":"#d897b3",colourLower:o?"#896eaa":"#bb7798",alpha:a.opacity??1})},drawHeartMoon(e,a,t){const n=a.x,r=a.y,o=a.size,s=.3+Math.sin(t*.002+a.glowPhase)*.2;e.save(),e.globalAlpha=a.opacity,e.translate(n,r);const h=e.createRadialGradient(0,0,o*.5,0,0,o*2.5);h.addColorStop(0,`rgba(255, 182, 193, ${s*.8})`),h.addColorStop(.4,`rgba(255, 105, 180, ${s*.5})`),h.addColorStop(.7,`rgba(255, 20, 147, ${s*.3})`),h.addColorStop(1,"rgba(255, 20, 147, 0)"),e.fillStyle=h,e.beginPath(),e.arc(0,0,o*2.5,0,Math.PI*2),e.fill();const l=e.createRadialGradient(-o*.3,-o*.3,0,0,0,o);l.addColorStop(0,"#ffcce0"),l.addColorStop(.5,"#ffb3d9"),l.addColorStop(1,"#ff69b4"),e.fillStyle=l,e.beginPath(),e.moveTo(0,o*.3),e.bezierCurveTo(-o*.5,o*.5,-o,o*.2,-o,-o*.2),e.bezierCurveTo(-o,-o*.6,-o*.5,-o*.7,0,-o*.3),e.bezierCurveTo(o*.5,-o*.7,o,-o*.6,o,-o*.2),e.bezierCurveTo(o,o*.2,o*.5,o*.5,0,o*.3),e.closePath(),e.fill(),e.strokeStyle="#ff1493",e.lineWidth=o*.02,e.stroke(),e.fillStyle="rgba(255, 240, 245, 0.4)",e.beginPath(),e.arc(-o*.4,-o*.1,o*.15,0,Math.PI*2),e.fill(),e.beginPath(),e.arc(o*.3,0,o*.12,0,Math.PI*2),e.fill(),e.beginPath(),e.arc(-o*.2,o*.15,o*.1,0,Math.PI*2),e.fill(),e.fillStyle=`rgba(255, 255, 255, ${s})`;const i=[{x:-o*.3,y:-o*.4},{x:o*.2,y:-o*.3},{x:0,y:0},{x:-o*.5,y:o*.1},{x:o*.4,y:o*.15}];for(const f of i){e.save(),e.translate(f.x,f.y),e.beginPath();const d=o*.08;e.moveTo(0,-d),e.lineTo(d*.2,-d*.2),e.lineTo(d,0),e.lineTo(d*.2,d*.2),e.lineTo(0,d),e.lineTo(-d*.2,d*.2),e.lineTo(-d,0),e.lineTo(-d*.2,-d*.2),e.closePath(),e.fill(),e.restore()}e.restore()},drawNeonSign(e,a,t){const n=a.x,r=a.y,o=a.size;if(a.phaseTime+=16,a.phase==="fade-in"&&a.phaseTime>=a.fadeInDuration)a.phase="stable",a.phaseTime=0,a.opacity=a.targetOpacity,a.crackleIntensity=0;else if(a.phase==="stable"&&a.phaseTime>=a.stableDuration)a.phase="fade-out",a.phaseTime=0;else if(a.phase==="fade-out"&&a.phaseTime>=a.fadeOutDuration){a.active=!1;return}a.phase==="fade-in"?(a.opacity=a.phaseTime/a.fadeInDuration*a.targetOpacity,a.crackleIntensity=1-a.phaseTime/a.fadeInDuration):a.phase==="fade-out"&&(a.opacity=a.targetOpacity*(1-a.phaseTime/a.fadeOutDuration)),e.save(),e.translate(n,r);const s="#ff1493",h="#ff0066",l="#ffffff",i="Happy Valentine's Day",f=o;e.font=`bold ${f}px 'Arial Black', sans-serif`,e.textAlign="center",e.textBaseline="middle";const d=e.measureText(i).width;let u=0;a.crackleIntensity>0&&(u=(Math.random()-.5)*a.crackleIntensity*5);const y=i.split("");let p=-d/2;for(let m=0;m<y.length;m++){const M=y[m],P=e.measureText(M).width,w=(a.crackleIntensity>0?Math.random()<a.crackleIntensity*.3:!1)?a.opacity*(.3+Math.random()*.7):a.opacity;e.save(),e.translate(p+P/2,u),e.globalAlpha=w;const g=.8+Math.sin(t*.002+a.glowPhase+m*.5)*.2;e.shadowColor=s,e.shadowBlur=o*.8*g,e.fillStyle=s,e.fillText(M,0,0),e.shadowBlur=o*.5*g,e.fillStyle=h,e.fillText(M,0,0),e.shadowBlur=o*.3*g,e.fillStyle=l,e.fillText(M,0,0),e.shadowBlur=0,e.fillStyle=l,e.globalAlpha=w*.9,e.fillText(M,0,0),e.restore(),p+=P}if(a.crackleIntensity>.3){for(let m=0;m<3;m++)if(Math.random()<a.crackleIntensity*.5){const M=(Math.random()-.5)*d,P=(Math.random()-.5)*o*.3,b=2+Math.random()*3;e.save(),e.globalAlpha=a.opacity*Math.random(),e.fillStyle=Math.random()<.5?s:l,e.shadowColor=s,e.shadowBlur=b*4,e.beginPath(),e.arc(M,P,b,0,Math.PI*2),e.fill(),e.restore()}}(a.phase==="stable"||a.phase==="fade-out")&&(e.globalAlpha=a.opacity*.1,e.fillStyle="#ff1493",e.fillRect(-d*.55,-o*.6,d*1.1,o*1.2)),e.restore()}};