diff --git a/SEO_FIX_GUIDE.md b/SEO_FIX_GUIDE.md new file mode 100644 index 00000000..c00927c1 --- /dev/null +++ b/SEO_FIX_GUIDE.md @@ -0,0 +1,412 @@ +# SEO Fix Guide - Google Search Console Indexing + +**Date:** October 15, 2025 +**Issue:** Google Search Console only indexing homepage, not tool pages +**Status:** FIXED โœ… + +--- + +## ๐Ÿ” Problems Identified + +### 1. **Outdated Sitemap** +- Missing Invoice Editor (`/invoice-editor`) +- Missing What's New page (`/whats-new`) +- Old lastmod dates (2025-01-23) +- Wrong priorities + +### 2. **React SPA Issue** (CRITICAL) +- Google can't index JavaScript-rendered pages +- Tool pages have no HTML content for crawlers +- All content loads client-side via React Router +- Search engines see empty `
` + +### 3. **Missing Meta Tags** +- No dynamic meta tags per page +- No Open Graph tags +- No Twitter Card tags +- No structured data (JSON-LD) + +--- + +## โœ… Solutions Implemented + +### 1. **Updated Sitemap.xml** +**File:** `/public/sitemap.xml` + +**Changes:** +- โœ… Added Invoice Editor +- โœ… Added What's New page +- โœ… Updated all lastmod dates to 2025-10-15 +- โœ… Increased editor tools priority to 0.9 +- โœ… Added comments for better organization +- โœ… Proper priority hierarchy + +### 2. **Pre-rendering with react-snap** +**File:** `package.json` + +**Added:** +```json +{ + "dependencies": { + "react-snap": "^1.23.0" + }, + "scripts": { + "build": "react-scripts build && react-snap" + }, + "reactSnap": { + "include": [ + "/", + "/object-editor", + "/table-editor", + "/invoice-editor", + "/url", + "/base64", + "/beautifier", + "/diff", + "/text-length", + "/whats-new", + "/privacy", + "/terms" + ] + } +} +``` + +**What it does:** +- Generates static HTML for each route +- Crawlers see full HTML content +- Improves SEO dramatically +- Faster first paint + +### 3. **Dynamic Meta Tags with react-helmet-async** +**Files Created:** +- `/src/components/SEO.js` - Reusable SEO component +- Updated `/src/App.js` - Wrapped with HelmetProvider +- Updated `/src/pages/Home.js` - Added SEO component + +**Features:** +- Dynamic title per page +- Dynamic description per page +- Open Graph tags (Facebook) +- Twitter Card tags +- JSON-LD structured data +- Canonical URLs + +--- + +## ๐Ÿ“‹ Steps to Fix in Google Search Console + +### Step 1: Verify Sitemap Update + +1. **Go to Google Search Console** + - URL: https://search.google.com/search-console + - Select property: `dewe.dev` + +2. **Navigate to Sitemaps** + - Left sidebar โ†’ "Sitemaps" + +3. **Remove Old Sitemap** (if exists) + - Find `https://dewe.dev/sitemap.xml` + - Click the 3 dots โ†’ "Remove sitemap" + +4. **Submit New Sitemap** + - Click "Add a new sitemap" + - Enter: `sitemap.xml` + - Click "Submit" + +5. **Wait for Processing** + - Status will show "Couldn't fetch" initially + - After deployment, it will show "Success" + - Check back in 24-48 hours + +--- + +### Step 2: Request Indexing for Key Pages + +1. **Go to URL Inspection Tool** + - Top search bar in Google Search Console + +2. **Inspect Each Tool Page:** + ``` + https://dewe.dev/object-editor + https://dewe.dev/table-editor + https://dewe.dev/invoice-editor + https://dewe.dev/url + https://dewe.dev/base64 + https://dewe.dev/beautifier + https://dewe.dev/diff + https://dewe.dev/text-length + https://dewe.dev/whats-new + ``` + +3. **For Each URL:** + - Paste URL in search bar + - Click "Test Live URL" + - Wait for test to complete + - If "URL is on Google": Great! + - If "URL is not on Google": Click "Request Indexing" + - Repeat for all pages + +--- + +### Step 3: Check robots.txt + +1. **Go to Settings** + - Left sidebar โ†’ "Settings" + - Click "Open report" under "robots.txt" + +2. **Verify robots.txt is accessible** + - Should show your robots.txt content + - Should reference sitemap: `Sitemap: https://dewe.dev/sitemap.xml` + +3. **If not accessible:** + - Check if `https://dewe.dev/robots.txt` works in browser + - Ensure Coolify/server serves static files correctly + +--- + +### Step 4: Monitor Coverage + +1. **Go to Coverage Report** + - Left sidebar โ†’ "Coverage" (or "Pages") + +2. **Check Indexed Pages** + - Should see increase in "Valid" pages + - Monitor "Excluded" and "Error" sections + +3. **Common Issues:** + - **"Discovered - currently not indexed"**: Normal, Google will index soon + - **"Crawled - currently not indexed"**: Low priority, may take time + - **"Excluded by 'noindex' tag"**: Check meta tags (shouldn't happen) + - **"Soft 404"**: Page has no content (pre-rendering should fix this) + +--- + +### Step 5: Check Enhancements + +1. **Go to Enhancements** + - Left sidebar โ†’ "Enhancements" + +2. **Check Mobile Usability** + - Should show "Valid" for all pages + - Fix any mobile issues + +3. **Check Core Web Vitals** + - Monitor performance metrics + - Aim for "Good" status + +--- + +## ๐Ÿš€ Deployment Steps + +### 1. Install Dependencies +```bash +cd /Users/dwindown/CascadeProjects/developer-tools +npm install +``` + +### 2. Test Build Locally +```bash +npm run build +``` + +**Expected:** +- Build completes successfully +- react-snap generates HTML files for each route +- Check `build/` folder for HTML files + +### 3. Deploy to Production +```bash +git add -A +git commit -m "fix: improve SEO with pre-rendering and dynamic meta tags + +- Updated sitemap.xml with all current pages +- Added react-snap for static HTML generation +- Implemented react-helmet-async for dynamic meta tags +- Created SEO component with Open Graph and Twitter Cards +- Added JSON-LD structured data +- Fixed Google Search Console indexing issues" + +git push +``` + +### 4. Verify Deployment +- Wait for Coolify to deploy +- Check https://dewe.dev/sitemap.xml +- Check https://dewe.dev/robots.txt +- Check https://dewe.dev/object-editor (view source, should see HTML content) + +--- + +## ๐Ÿงช Testing & Verification + +### Test 1: View Page Source +1. Open https://dewe.dev/object-editor +2. Right-click โ†’ "View Page Source" +3. **Before fix:** Only see `
` +4. **After fix:** See full HTML content with meta tags + +### Test 2: Google Rich Results Test +1. Go to https://search.google.com/test/rich-results +2. Enter: `https://dewe.dev/object-editor` +3. Should show structured data (JSON-LD) +4. Should pass validation + +### Test 3: Facebook Sharing Debugger +1. Go to https://developers.facebook.com/tools/debug/ +2. Enter: `https://dewe.dev/object-editor` +3. Should show Open Graph tags +4. Should display preview image + +### Test 4: Twitter Card Validator +1. Go to https://cards-dev.twitter.com/validator +2. Enter: `https://dewe.dev/object-editor` +3. Should show Twitter Card preview +4. Should display correctly + +--- + +## ๐Ÿ“Š Expected Timeline + +| Action | Timeline | +|--------|----------| +| Deploy changes | Immediate | +| Sitemap processed | 1-2 hours | +| Pages crawled | 1-7 days | +| Pages indexed | 3-14 days | +| Full coverage | 2-4 weeks | + +**Note:** Google indexing is not instant. Be patient! + +--- + +## ๐Ÿ”ง Troubleshooting + +### Issue: "Couldn't fetch sitemap" +**Solution:** +- Check if `https://dewe.dev/sitemap.xml` is accessible +- Ensure Coolify serves static files from `/public` +- Check server logs for 404 errors + +### Issue: "Discovered - currently not indexed" +**Solution:** +- Normal! Google discovered but hasn't indexed yet +- Request indexing manually (Step 2 above) +- Wait 7-14 days + +### Issue: "Crawled - currently not indexed" +**Solution:** +- Google crawled but deemed low priority +- Improve content quality +- Add more internal links +- Wait for Google to re-evaluate + +### Issue: "Soft 404" +**Solution:** +- Page has no content or very little content +- Pre-rendering should fix this +- Check if react-snap generated HTML correctly +- Verify build output + +### Issue: react-snap fails during build +**Solution:** +- Check console for errors +- May need to add `window.snapSaveState = () => ({})` to index.js +- Try `npm run build:no-snap` to build without pre-rendering +- Check react-snap documentation + +--- + +## ๐Ÿ“ Additional Recommendations + +### 1. Add More Content +- Write blog posts about each tool +- Create tutorial pages +- Add FAQ section +- More content = better SEO + +### 2. Internal Linking +- Link between related tools +- Add "Related Tools" section +- Create tool categories pages +- Improve navigation + +### 3. Performance Optimization +- Optimize images +- Minimize JavaScript +- Use CDN for assets +- Improve Core Web Vitals + +### 4. Schema Markup +- Add more structured data +- Use SoftwareApplication schema +- Add BreadcrumbList schema +- Add Organization schema + +### 5. Social Signals +- Share on social media +- Get backlinks +- Engage with developer communities +- Build brand awareness + +--- + +## ๐ŸŽฏ Success Metrics + +### Week 1 +- โœ… Sitemap processed +- โœ… 3-5 pages indexed +- โœ… No crawl errors + +### Week 2 +- โœ… 8-10 pages indexed +- โœ… Appearing in search results +- โœ… Mobile usability: Good + +### Week 4 +- โœ… All pages indexed +- โœ… Ranking for brand keywords +- โœ… Organic traffic increasing + +--- + +## ๐Ÿ“ž Support + +If issues persist after 2 weeks: +1. Check Google Search Console for specific errors +2. Review server logs for crawl errors +3. Test with different browsers +4. Consider hiring SEO consultant + +--- + +## โœ… Checklist + +### Immediate Actions +- [ ] Deploy code changes +- [ ] Verify sitemap.xml is accessible +- [ ] Verify robots.txt is accessible +- [ ] Submit sitemap in Google Search Console +- [ ] Request indexing for key pages + +### Within 24 Hours +- [ ] Check sitemap processing status +- [ ] Verify HTML pre-rendering works +- [ ] Test Open Graph tags +- [ ] Test Twitter Cards + +### Within 1 Week +- [ ] Monitor coverage report +- [ ] Check for crawl errors +- [ ] Verify pages being indexed +- [ ] Check search appearance + +### Within 1 Month +- [ ] Review all pages indexed +- [ ] Check ranking positions +- [ ] Monitor organic traffic +- [ ] Optimize based on data + +--- + +**Good luck! Your SEO should improve significantly with these changes.** ๐Ÿš€ diff --git a/package-lock.json b/package-lock.json index 45ffafb6..e1ef2db4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,8 +36,10 @@ "react": "18.3.1", "react-diff-view": "^3.3.2", "react-dom": "18.3.1", + "react-helmet-async": "^2.0.5", "react-router-dom": "6.26.2", "react-scripts": "5.0.1", + "react-snap": "^1.23.0", "reactflow": "^11.11.4", "serialize-javascript": "^6.0.0", "web-vitals": "^2.1.4" @@ -4264,7 +4266,6 @@ }, "node_modules/@types/node": { "version": "24.3.0", - "dev": true, "license": "MIT", "dependencies": { "undici-types": "~7.10.0" @@ -4827,7 +4828,6 @@ }, "node_modules/accepts": { "version": "1.3.8", - "dev": true, "license": "MIT", "dependencies": { "mime-types": "~2.1.34", @@ -4839,7 +4839,6 @@ }, "node_modules/accepts/node_modules/negotiator": { "version": "0.6.3", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -5111,7 +5110,6 @@ }, "node_modules/array-flatten": { "version": "1.1.1", - "dev": true, "license": "MIT" }, "node_modules/array-includes": { @@ -5295,6 +5293,12 @@ "node": ">= 0.4" } }, + "node_modules/async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "license": "MIT" + }, "node_modules/asynckit": { "version": "0.4.0", "dev": true, @@ -5726,7 +5730,6 @@ }, "node_modules/boolbase": { "version": "1.0.0", - "dev": true, "license": "ISC" }, "node_modules/brace-expansion": { @@ -5791,9 +5794,17 @@ "node-int64": "^0.4.0" } }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/buffer-from": { "version": "1.1.2", - "dev": true, "license": "MIT" }, "node_modules/builtin-modules": { @@ -5995,6 +6006,116 @@ "dev": true, "license": "MIT" }, + "node_modules/cheerio": { + "version": "1.0.0-rc.2", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.2.tgz", + "integrity": "sha512-9LDHQy1jHc/eXMzPN6/oah9Qba4CjdKECC7YYEE/2zge/tsGwt19NQp5NFdfd5Lx6TZlyC5SXNQkG41P9r6XDg==", + "license": "MIT", + "dependencies": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash": "^4.15.0", + "parse5": "^3.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cheerio/node_modules/css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha512-dUQOBoqdR7QwV90WysXPLXG5LO7nhYBgiWVfxF80DKPF8zx1t/pUd2FYy73emg3zrjtM6dzmYgbHKfV2rxiHQA==", + "license": "BSD-like", + "dependencies": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "node_modules/cheerio/node_modules/css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "license": "BSD-2-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/cheerio/node_modules/dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "license": "MIT", + "dependencies": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "node_modules/cheerio/node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "license": "BSD-2-Clause" + }, + "node_modules/cheerio/node_modules/domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/cheerio/node_modules/domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==", + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/cheerio/node_modules/entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "license": "BSD-2-Clause" + }, + "node_modules/cheerio/node_modules/htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "license": "MIT", + "dependencies": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "node_modules/cheerio/node_modules/nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/cheerio/node_modules/parse5": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", + "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/chokidar": { "version": "3.6.0", "dev": true, @@ -6358,9 +6479,59 @@ }, "node_modules/concat-map": { "version": "0.0.1", - "dev": true, "license": "MIT" }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/config-chain": { "version": "1.1.13", "license": "MIT", @@ -6395,7 +6566,6 @@ }, "node_modules/content-type": { "version": "1.0.5", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -6416,7 +6586,6 @@ }, "node_modules/cookie-signature": { "version": "1.0.6", - "dev": true, "license": "MIT" }, "node_modules/core-js": { @@ -6453,7 +6622,6 @@ }, "node_modules/core-util-is": { "version": "1.0.3", - "dev": true, "license": "MIT" }, "node_modules/cosmiconfig": { @@ -7026,7 +7194,6 @@ }, "node_modules/debug": { "version": "4.4.1", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -7398,7 +7565,6 @@ }, "node_modules/ee-first": { "version": "1.1.1", - "dev": true, "license": "MIT" }, "node_modules/ejs": { @@ -7451,6 +7617,15 @@ "node": ">= 0.8" } }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, "node_modules/enhanced-resolve": { "version": "5.18.3", "dev": true, @@ -7658,6 +7833,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "license": "MIT" + }, + "node_modules/es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", + "license": "MIT", + "dependencies": { + "es6-promise": "^4.0.3" + } + }, "node_modules/escalade": { "version": "3.2.0", "dev": true, @@ -7668,7 +7858,6 @@ }, "node_modules/escape-html": { "version": "1.0.3", - "dev": true, "license": "MIT" }, "node_modules/escape-string-regexp": { @@ -8374,7 +8563,6 @@ }, "node_modules/etag": { "version": "1.8.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -8486,6 +8674,12 @@ "url": "https://opencollective.com/express" } }, + "node_modules/express-history-api-fallback": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/express-history-api-fallback/-/express-history-api-fallback-2.2.1.tgz", + "integrity": "sha512-swxwm3aP8vrOOvlzOdZvHlSZtJGwHKaY94J6AkrAgCTmcbko3IRwbkhLv2wKV1WeZhjxX58aLMpP3atDBnKuZg==", + "license": "ISC" + }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "dev": true, @@ -8499,6 +8693,36 @@ "dev": true, "license": "MIT" }, + "node_modules/extract-zip": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", + "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", + "license": "BSD-2-Clause", + "dependencies": { + "concat-stream": "^1.6.2", + "debug": "^2.6.9", + "mkdirp": "^0.5.4", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + } + }, + "node_modules/extract-zip/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/extract-zip/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "dev": true, @@ -8593,6 +8817,15 @@ "bser": "2.1.1" } }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, "node_modules/fflate": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", @@ -8955,7 +9188,6 @@ }, "node_modules/forwarded": { "version": "0.2.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -8975,7 +9207,6 @@ }, "node_modules/fresh": { "version": "0.5.2", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -9001,7 +9232,6 @@ }, "node_modules/fs.realpath": { "version": "1.0.0", - "dev": true, "license": "ISC" }, "node_modules/fsevents": { @@ -9406,12 +9636,20 @@ }, "node_modules/he": { "version": "1.2.0", - "dev": true, "license": "MIT", "bin": { "he": "bin/he" } }, + "node_modules/highland": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/highland/-/highland-2.13.0.tgz", + "integrity": "sha512-zGZBcgAHPY2Zf9VG9S5IrlcC7CH9ELioXVtp9T5bU2a4fP2zIsA+Y8pV/n/h2lMwbWMHTX0I0xN0ODJ3Pd3aBQ==", + "license": "Apache-2.0", + "dependencies": { + "util-deprecate": "^1.0.2" + } + }, "node_modules/hoopy": { "version": "0.1.4", "dev": true, @@ -9494,6 +9732,27 @@ "dev": true, "license": "MIT" }, + "node_modules/html-minifier": { + "version": "3.5.21", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", + "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", + "license": "MIT", + "dependencies": { + "camel-case": "3.0.x", + "clean-css": "4.2.x", + "commander": "2.17.x", + "he": "1.2.x", + "param-case": "2.1.x", + "relateurl": "0.2.x", + "uglify-js": "3.4.x" + }, + "bin": { + "html-minifier": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/html-minifier-terser": { "version": "6.1.0", "dev": true, @@ -9522,6 +9781,67 @@ "node": ">= 12" } }, + "node_modules/html-minifier/node_modules/camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", + "license": "MIT", + "dependencies": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, + "node_modules/html-minifier/node_modules/clean-css": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", + "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", + "license": "MIT", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/html-minifier/node_modules/commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "license": "MIT" + }, + "node_modules/html-minifier/node_modules/lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==", + "license": "MIT" + }, + "node_modules/html-minifier/node_modules/no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "license": "MIT", + "dependencies": { + "lower-case": "^1.1.1" + } + }, + "node_modules/html-minifier/node_modules/param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==", + "license": "MIT", + "dependencies": { + "no-case": "^2.2.0" + } + }, + "node_modules/html-minifier/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/html-webpack-plugin": { "version": "5.6.4", "dev": true, @@ -9690,7 +10010,6 @@ }, "node_modules/iconv-lite": { "version": "0.6.3", - "dev": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -9801,7 +10120,6 @@ }, "node_modules/inflight": { "version": "1.0.6", - "dev": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -9810,7 +10128,6 @@ }, "node_modules/inherits": { "version": "2.0.4", - "dev": true, "license": "ISC" }, "node_modules/ini": { @@ -9830,6 +10147,15 @@ "node": ">= 0.4" } }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/iobuffer": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/iobuffer/-/iobuffer-5.4.0.tgz", @@ -10319,6 +10645,16 @@ "version": "2.0.0", "license": "ISC" }, + "node_modules/isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha512-9c4TNAKYXM5PRyVcwUZrF3W09nQ+sO7+jydgs4ZGW9dhsLG2VOlISJABombdQqQRXCwuYG3sYV/puGf5rp0qmA==", + "license": "MIT", + "dependencies": { + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" + } + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "dev": true, @@ -11805,7 +12141,6 @@ }, "node_modules/media-typer": { "version": "0.3.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -11845,7 +12180,6 @@ }, "node_modules/methods": { "version": "1.1.2", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -11876,7 +12210,6 @@ }, "node_modules/mime-db": { "version": "1.52.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -11884,7 +12217,6 @@ }, "node_modules/mime-types": { "version": "2.1.35", - "dev": true, "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -11927,6 +12259,85 @@ "webpack": "^5.0.0" } }, + "node_modules/minimalcss": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/minimalcss/-/minimalcss-0.8.1.tgz", + "integrity": "sha512-a+kbRVvxz+oQf43pweflM38KvcvVuTvv3v6a8UgVbfS7E2rktSJSf8kfbGToSXgbiBDP83WTh8MWL6PdT9ljag==", + "license": "MIT", + "dependencies": { + "cheerio": "1.0.0-rc.2", + "css-tree": "1.0.0-alpha.28", + "csso": "~3.5.0", + "filesize": "^3.5.11", + "minimist": "^1.2.0", + "puppeteer": "^1.8.0" + }, + "bin": { + "minimalcss": "bin/minimalcss.js" + } + }, + "node_modules/minimalcss/node_modules/css-tree": { + "version": "1.0.0-alpha.28", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.28.tgz", + "integrity": "sha512-joNNW1gCp3qFFzj4St6zk+Wh/NBv0vM5YbEreZk0SD4S23S+1xBKb6cLDg2uj4P4k/GUMlIm6cKIDqIG+vdt0w==", + "license": "MIT", + "dependencies": { + "mdn-data": "~1.1.0", + "source-map": "^0.5.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/minimalcss/node_modules/csso": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/csso/-/csso-3.5.1.tgz", + "integrity": "sha512-vrqULLffYU1Q2tLdJvaCYbONStnfkfimRxXNaGjxMldI0C7JPBC4rB1RyjhfdZ4m1frm8pM9uRPKH3d2knZ8gg==", + "license": "MIT", + "dependencies": { + "css-tree": "1.0.0-alpha.29" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/minimalcss/node_modules/csso/node_modules/css-tree": { + "version": "1.0.0-alpha.29", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.29.tgz", + "integrity": "sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg==", + "license": "MIT", + "dependencies": { + "mdn-data": "~1.1.0", + "source-map": "^0.5.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/minimalcss/node_modules/filesize": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz", + "integrity": "sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/minimalcss/node_modules/mdn-data": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-1.1.4.tgz", + "integrity": "sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA==", + "license": "MPL-2.0" + }, + "node_modules/minimalcss/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/minimalistic-assert": { "version": "1.0.1", "dev": true, @@ -11947,7 +12358,6 @@ }, "node_modules/minimist": { "version": "1.2.8", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -11962,7 +12372,6 @@ }, "node_modules/mkdirp": { "version": "0.5.6", - "dev": true, "license": "MIT", "dependencies": { "minimist": "^1.2.6" @@ -11973,7 +12382,6 @@ }, "node_modules/ms": { "version": "2.1.3", - "dev": true, "license": "MIT" }, "node_modules/multicast-dns": { @@ -12047,6 +12455,25 @@ "tslib": "^2.0.3" } }, + "node_modules/node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "license": "MIT", + "dependencies": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + }, + "node_modules/node-fetch/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/node-forge": { "version": "1.3.1", "dev": true, @@ -12293,7 +12720,6 @@ }, "node_modules/once": { "version": "1.4.0", - "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" @@ -12464,7 +12890,6 @@ }, "node_modules/parseurl": { "version": "1.3.3", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -12489,7 +12914,6 @@ }, "node_modules/path-is-absolute": { "version": "1.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -12534,6 +12958,12 @@ "node": ">=8" } }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "license": "MIT" + }, "node_modules/performance-now": { "version": "2.1.0", "devOptional": true, @@ -13913,9 +14343,17 @@ }, "node_modules/process-nextick-args": { "version": "2.0.1", - "dev": true, "license": "MIT" }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/promise": { "version": "8.3.0", "dev": true, @@ -13957,7 +14395,6 @@ }, "node_modules/proxy-addr": { "version": "2.0.7", - "dev": true, "license": "MIT", "dependencies": { "forwarded": "0.2.0", @@ -13969,12 +14406,17 @@ }, "node_modules/proxy-addr/node_modules/ipaddr.js": { "version": "1.9.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, "node_modules/psl": { "version": "1.15.0", "dev": true, @@ -13994,6 +14436,138 @@ "node": ">=6" } }, + "node_modules/puppeteer": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.20.0.tgz", + "integrity": "sha512-bt48RDBy2eIwZPrkgbcwHtb51mj2nKvHOPMaSH2IsWiv7lOG9k9zhaRzpDZafrk05ajMc3cu+lSQYYOfH2DkVQ==", + "deprecated": "< 24.15.0 is no longer supported", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.1.0", + "extract-zip": "^1.6.6", + "https-proxy-agent": "^2.2.1", + "mime": "^2.0.3", + "progress": "^2.0.1", + "proxy-from-env": "^1.0.0", + "rimraf": "^2.6.1", + "ws": "^6.1.0" + }, + "engines": { + "node": ">=6.4.0" + } + }, + "node_modules/puppeteer/node_modules/agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "license": "MIT", + "dependencies": { + "es6-promisify": "^5.0.0" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/puppeteer/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/puppeteer/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/puppeteer/node_modules/https-proxy-agent": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "license": "MIT", + "dependencies": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/puppeteer/node_modules/https-proxy-agent/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/puppeteer/node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/puppeteer/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/puppeteer/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/puppeteer/node_modules/ws": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz", + "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==", + "license": "MIT", + "dependencies": { + "async-limiter": "~1.0.0" + } + }, "node_modules/q": { "version": "1.5.1", "dev": true, @@ -14058,7 +14632,6 @@ }, "node_modules/range-parser": { "version": "1.2.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -14256,6 +14829,26 @@ "dev": true, "license": "MIT" }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", + "license": "MIT" + }, + "node_modules/react-helmet-async": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-2.0.5.tgz", + "integrity": "sha512-rYUYHeus+i27MvFE+Jaa4WsyBKGkL6qVgbJvSBoX8mbsWoABJXdEO0bZyi0F6i+4f0NuIb8AvqPMj3iXFHkMwg==", + "license": "Apache-2.0", + "dependencies": { + "invariant": "^2.2.4", + "react-fast-compare": "^3.2.2", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": "^16.6.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-is": { "version": "17.0.2", "license": "MIT" @@ -14368,6 +14961,366 @@ } } }, + "node_modules/react-snap": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/react-snap/-/react-snap-1.23.0.tgz", + "integrity": "sha512-spmg2maHSedLrn6QBAfLJkyMqeeffLTIs7h40pS1copW2xBrajx4HEAcanm+7IVGO6SYCPoGwvbU3U30UFN25g==", + "license": "MIT", + "dependencies": { + "clean-css": "4.2.1", + "express": "4.16.4", + "express-history-api-fallback": "2.2.1", + "highland": "2.13.0", + "html-minifier": "3.5.21", + "minimalcss": "0.8.1", + "mkdirp": "0.5.1", + "puppeteer": "^1.8.0", + "serve-static": "1.13.2", + "sourcemapped-stacktrace-node": "2.1.8" + }, + "bin": { + "react-snap": "run.js" + }, + "engines": { + "node": ">= 8.6.0" + } + }, + "node_modules/react-snap/node_modules/body-parser": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha512-YQyoqQG3sO8iCmf8+hyVpgHHOv0/hCEFiS4zTGUwTA1HjAFX66wRcNQrVCeJq9pgESMRvUAOvSil5MJlmccuKQ==", + "license": "MIT", + "dependencies": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "~1.6.3", + "iconv-lite": "0.4.23", + "on-finished": "~2.3.0", + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "~1.6.16" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/react-snap/node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/react-snap/node_modules/clean-css": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", + "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", + "license": "MIT", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/react-snap/node_modules/content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/react-snap/node_modules/cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha512-+IJOX0OqlHCszo2mBUq+SrEbCj6w7Kpffqx60zYbPTFaO4+yYgRjHwcZNpWvaTylDHaV7PPmBHzSecZiMhtPgw==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/react-snap/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/react-snap/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/react-snap/node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==", + "license": "MIT" + }, + "node_modules/react-snap/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/react-snap/node_modules/express": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", + "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.5", + "array-flatten": "1.1.1", + "body-parser": "1.18.3", + "content-disposition": "0.5.2", + "content-type": "~1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.1.1", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.4", + "qs": "6.5.2", + "range-parser": "~1.2.0", + "safe-buffer": "5.1.2", + "send": "0.16.2", + "serve-static": "1.13.2", + "setprototypeof": "1.1.0", + "statuses": "~1.4.0", + "type-is": "~1.6.16", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/react-snap/node_modules/finalhandler": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/react-snap/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/react-snap/node_modules/iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-snap/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "license": "ISC" + }, + "node_modules/react-snap/node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "license": "MIT" + }, + "node_modules/react-snap/node_modules/mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", + "license": "MIT", + "bin": { + "mime": "cli.js" + } + }, + "node_modules/react-snap/node_modules/minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha512-miQKw5Hv4NS1Psg2517mV4e4dYNaO3++hjAvLOAzKqZ61rH8NS1SK+vbfBWZ5PY/Me/bEWhUwqMghEW5Fb9T7Q==", + "license": "MIT" + }, + "node_modules/react-snap/node_modules/mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA==", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "license": "MIT", + "dependencies": { + "minimist": "0.0.8" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/react-snap/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/react-snap/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/react-snap/node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "license": "MIT" + }, + "node_modules/react-snap/node_modules/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/react-snap/node_modules/raw-body": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "license": "MIT", + "dependencies": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/react-snap/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/react-snap/node_modules/send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/react-snap/node_modules/serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "license": "MIT", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", + "send": "0.16.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/react-snap/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "license": "ISC" + }, + "node_modules/react-snap/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-snap/node_modules/statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/reactflow": { "version": "11.11.4", "resolved": "https://registry.npmjs.org/reactflow/-/reactflow-11.11.4.tgz", @@ -14396,7 +15349,6 @@ }, "node_modules/readable-stream": { "version": "3.6.2", - "dev": true, "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -14571,7 +15523,6 @@ }, "node_modules/relateurl": { "version": "0.2.7", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.10" @@ -14948,7 +15899,6 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", - "dev": true, "license": "MIT" }, "node_modules/sanitize.css": { @@ -15279,6 +16229,12 @@ "version": "3.1.0", "license": "MIT" }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "license": "MIT" + }, "node_modules/shebang-command": { "version": "2.0.0", "license": "MIT", @@ -15471,6 +16427,29 @@ "dev": true, "license": "MIT" }, + "node_modules/sourcemapped-stacktrace-node": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/sourcemapped-stacktrace-node/-/sourcemapped-stacktrace-node-2.1.8.tgz", + "integrity": "sha512-xQOqfT5mquKLBp+H06WTeGYEQh7OF5wa44IPHbh+qNdTP15xSzxwISPml1xCweJ6DExDpDDxXe/P34wP+GdDrg==", + "license": "BSD-3-Clause", + "dependencies": { + "es6-promise": "^4.1.1", + "isomorphic-fetch": "^2.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">= 8.6.0" + } + }, + "node_modules/sourcemapped-stacktrace-node/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/spdy": { "version": "4.0.2", "dev": true, @@ -15657,7 +16636,6 @@ }, "node_modules/string_decoder": { "version": "1.3.0", - "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" @@ -16594,7 +17572,6 @@ }, "node_modules/type-is": { "version": "1.6.18", - "dev": true, "license": "MIT", "dependencies": { "media-typer": "0.3.0", @@ -16674,6 +17651,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "license": "MIT" + }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", "dev": true, @@ -16697,6 +17680,37 @@ "node": ">=4.2.0" } }, + "node_modules/uglify-js": { + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", + "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==", + "license": "BSD-2-Clause", + "dependencies": { + "commander": "~2.19.0", + "source-map": "~0.6.1" + }, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/uglify-js/node_modules/commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "license": "MIT" + }, + "node_modules/uglify-js/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/unbox-primitive": { "version": "1.1.0", "dev": true, @@ -16721,7 +17735,6 @@ }, "node_modules/undici-types": { "version": "7.10.0", - "dev": true, "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { @@ -16781,7 +17794,6 @@ }, "node_modules/unpipe": { "version": "1.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -16830,6 +17842,12 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==", + "license": "MIT" + }, "node_modules/uri-js": { "version": "4.4.1", "dev": true, @@ -16858,7 +17876,6 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", - "dev": true, "license": "MIT" }, "node_modules/util.promisify": { @@ -16882,7 +17899,6 @@ }, "node_modules/utils-merge": { "version": "1.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4.0" @@ -16925,7 +17941,6 @@ }, "node_modules/vary": { "version": "1.1.2", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -17253,7 +18268,6 @@ }, "node_modules/whatwg-fetch": { "version": "3.6.20", - "dev": true, "license": "MIT" }, "node_modules/whatwg-mimetype": { @@ -17791,7 +18805,6 @@ }, "node_modules/wrappy": { "version": "1.0.2", - "dev": true, "license": "ISC" }, "node_modules/write-file-atomic": { @@ -17915,6 +18928,16 @@ "node": ">=8" } }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "dev": true, diff --git a/package.json b/package.json index 922df5ea..e348d800 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,10 @@ "react": "18.3.1", "react-diff-view": "^3.3.2", "react-dom": "18.3.1", + "react-helmet-async": "^2.0.5", "react-router-dom": "6.26.2", "react-scripts": "5.0.1", + "react-snap": "^1.23.0", "reactflow": "^11.11.4", "serialize-javascript": "^6.0.0", "web-vitals": "^2.1.4" @@ -46,10 +48,36 @@ }, "scripts": { "start": "react-scripts start", - "build": "react-scripts build", + "build": "react-scripts build && react-snap", + "build:no-snap": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, + "reactSnap": { + "inlineCss": true, + "minifyHtml": { + "collapseWhitespace": false, + "removeComments": false + }, + "puppeteerArgs": [ + "--no-sandbox", + "--disable-setuid-sandbox" + ], + "include": [ + "/", + "/object-editor", + "/table-editor", + "/invoice-editor", + "/url", + "/base64", + "/beautifier", + "/diff", + "/text-length", + "/whats-new", + "/privacy", + "/terms" + ] + }, "eslintConfig": { "extends": [ "react-app", diff --git a/public/sitemap.xml b/public/sitemap.xml index 2a69644b..919d8041 100644 --- a/public/sitemap.xml +++ b/public/sitemap.xml @@ -3,63 +3,86 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"> + https://dewe.dev/ - 2025-01-23 + 2025-10-15 weekly 1.0 + + https://dewe.dev/object-editor - 2025-01-23 + 2025-10-15 monthly - 0.8 + 0.9 https://dewe.dev/table-editor - 2025-01-23 + 2025-10-15 monthly - 0.8 + 0.9 + + https://dewe.dev/invoice-editor + 2025-10-15 + monthly + 0.9 + + + https://dewe.dev/url - 2025-01-23 + 2025-10-15 monthly 0.8 https://dewe.dev/base64 - 2025-01-23 + 2025-10-15 monthly 0.8 https://dewe.dev/beautifier - 2025-01-23 + 2025-10-15 monthly 0.8 + + https://dewe.dev/diff - 2025-01-23 + 2025-10-15 monthly 0.8 https://dewe.dev/text-length - 2025-01-23 + 2025-10-15 monthly 0.8 + + + + https://dewe.dev/whats-new + 2025-10-15 + weekly + 0.7 + + + https://dewe.dev/privacy - 2025-01-23 + 2025-10-15 yearly 0.3 https://dewe.dev/terms - 2025-01-23 + 2025-10-15 yearly 0.3 diff --git a/src/App.js b/src/App.js index d605eb62..63c92885 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,6 @@ import React, { useEffect } from 'react'; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; +import { HelmetProvider } from 'react-helmet-async'; import Layout from './components/Layout'; import ErrorBoundary from './components/ErrorBoundary'; import Home from './pages/Home'; @@ -30,31 +31,34 @@ function App() { }, []); return ( - - - - - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - - - - + + + + + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + + + + ); } diff --git a/src/components/SEO.js b/src/components/SEO.js new file mode 100644 index 00000000..894f077b --- /dev/null +++ b/src/components/SEO.js @@ -0,0 +1,75 @@ +import React from 'react'; +import { Helmet } from 'react-helmet-async'; + +const SEO = ({ + title, + description, + keywords, + path = '/', + type = 'website', + image = 'https://dewe.dev/og-image.png' +}) => { + const siteUrl = 'https://dewe.dev'; + const fullUrl = `${siteUrl}${path}`; + const fullTitle = title ? `${title} | Developer Tools` : 'Developer Tools - Essential Web Developer Utilities'; + const defaultDescription = 'Free online developer tools for JSON, CSV, Base64, URL encoding, code beautification, and more. Privacy-first, no data storage, all processing in your browser.'; + const metaDescription = description || defaultDescription; + const defaultKeywords = 'developer tools, json editor, csv converter, base64 encoder, url encoder, code beautifier, diff tool, web developer utilities, online tools'; + const metaKeywords = keywords || defaultKeywords; + + return ( + + {/* Basic Meta Tags */} + {fullTitle} + + + + + {/* Open Graph / Facebook */} + + + + + + + + {/* Twitter Card */} + + + + + + + {/* Additional SEO Tags */} + + + + + + {/* JSON-LD Structured Data */} + + + ); +}; + +export default SEO; diff --git a/src/pages/Home.js b/src/pages/Home.js index 31453d8b..7e99d155 100644 --- a/src/pages/Home.js +++ b/src/pages/Home.js @@ -4,6 +4,7 @@ import { Link } from 'react-router-dom'; import ToolCard from '../components/ToolCard'; import { TOOLS, SITE_CONFIG } from '../config/tools'; import { useAnalytics } from '../hooks/useAnalytics'; +import SEO from '../components/SEO'; const Home = () => { const [searchTerm, setSearchTerm] = useState(''); @@ -32,18 +33,24 @@ const Home = () => { ); return ( -
-
- {/* Hero Section */} -
- {/* Terminal-style header */} -
- - ~/dewe.dev $ - _ -
- -

+ <> + +
+
+
+ {/* Terminal-style header */} +
+ + ~/dewe.dev $ + _ +
+ +

{SITE_CONFIG.title}

@@ -215,7 +222,7 @@ const Home = () => {
-

+ ); };