From 1f5d1d335c76862d16f66fb261e4d351b90cdb04 Mon Sep 17 00:00:00 2001 From: Luigi1010101 Date: Thu, 23 Jul 2026 18:48:31 +0200 Subject: [PATCH] feat(seo): add evidence-backed search foundations --- .github/workflows/deploy.yml | 12 +- .github/workflows/quality.yml | 25 + .github/workflows/refresh.yml | 23 +- .gitignore | 3 +- README.md | 16 +- astro.config.mjs | 8 +- docs/seo-audit-2026-07-23.md | 316 ++ docs/seo-evidence-2026-07-23.json | 217 ++ package-lock.json | 4 + package.json | 12 +- public/data/bases.json | 3380 +++++++++---------- public/data/currency.json | 400 +-- public/data/omens.json | 100 +- public/og-exile-crafter.jpg | Bin 0 -> 146465 bytes public/robots.txt | 4 + scripts/_e2e_paste.mjs | 279 +- scripts/audit-seo-output.mjs | 221 ++ scripts/download-images.mjs | 441 ++- scripts/fetch-poe2db.mjs | 342 +- scripts/process-data.mjs | 98 +- scripts/refresh.mjs | 9 +- scripts/verify-seo.mjs | 1288 +++++++ seo-skill-policy.json | 177 + src/components/AffixSlots.astro | 11 +- src/components/BaseCard.astro | 9 +- src/components/Footer.astro | 23 +- src/components/Header.astro | 21 +- src/components/ModBadge.astro | 14 +- src/components/simulator/ActivityLog.astro | 6 +- src/components/simulator/EmptyState.astro | 14 +- src/components/simulator/LoadingState.astro | 2 +- src/components/simulator/OmenModal.astro | 4 +- src/components/simulator/PasteModal.astro | 12 +- src/components/simulator/RightPanel.astro | 4 +- src/i18n/en.json | 3 +- src/i18n/pt.json | 3 +- src/layouts/Base.astro | 49 +- src/lib/safe-html.js | 20 + src/lib/safe-json.js | 23 + src/lib/seo.ts | 31 + src/pages/404.astro | 7 +- src/pages/bases/[id].astro | 56 +- src/pages/bases/index.astro | 12 +- src/pages/calculator.astro | 31 +- src/pages/currency/index.astro | 17 +- src/pages/guides/index.astro | 13 +- src/pages/index.astro | 47 +- src/pages/mods/[id].astro | 44 +- src/pages/mods/index.astro | 10 +- src/pages/omens.astro | 17 +- src/pages/optimizer.astro | 15 +- src/pages/simulator.astro | 84 +- 52 files changed, 5703 insertions(+), 2274 deletions(-) create mode 100644 .github/workflows/quality.yml create mode 100644 docs/seo-audit-2026-07-23.md create mode 100644 docs/seo-evidence-2026-07-23.json create mode 100644 public/og-exile-crafter.jpg create mode 100644 public/robots.txt create mode 100644 scripts/audit-seo-output.mjs create mode 100644 scripts/verify-seo.mjs create mode 100644 seo-skill-policy.json create mode 100644 src/lib/safe-html.js create mode 100644 src/lib/safe-json.js create mode 100644 src/lib/seo.ts diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index f3db4db..af44119 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -3,12 +3,15 @@ name: Deploy to Cloudflare Pages on: push: branches: [main] - workflow_dispatch: jobs: deploy: + if: vars.PRODUCTION_RELEASE_GUARD_CONFIGURED == 'true' runs-on: ubuntu-latest timeout-minutes: 20 + environment: + name: production + url: https://exilecrafter.com concurrency: group: pages-${{ github.ref }} cancel-in-progress: false @@ -25,11 +28,8 @@ jobs: - name: Install run: npm ci --no-audit --no-fund - - name: Refresh poe2db data - run: npm run refresh - - - name: Build static site - run: npm run build + - name: Verify approved source and build static site + run: npm run check - name: Publish to Cloudflare Pages uses: cloudflare/pages-action@v1 diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml new file mode 100644 index 0000000..459812f --- /dev/null +++ b/.github/workflows/quality.yml @@ -0,0 +1,25 @@ +name: Quality + +on: + pull_request: + workflow_dispatch: + +jobs: + check: + runs-on: ubuntu-latest + timeout-minutes: 20 + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: npm + + - name: Install + run: npm ci --no-audit --no-fund + + - name: Build and verify + run: npm run check diff --git a/.github/workflows/refresh.yml b/.github/workflows/refresh.yml index 624342d..15e384f 100644 --- a/.github/workflows/refresh.yml +++ b/.github/workflows/refresh.yml @@ -4,12 +4,14 @@ on: schedule: # Every Sunday at 06:00 UTC (after typical GGG patch windows) - cron: '0 6 * * 0' - workflow_dispatch: # allow manual trigger jobs: refresh: runs-on: ubuntu-latest timeout-minutes: 20 + permissions: + contents: write + pull-requests: write steps: - uses: actions/checkout@v4 @@ -23,17 +25,26 @@ jobs: - name: Refresh poe2db data run: npm run refresh - - name: Build site - run: npm run build + - name: Verify refreshed data and build site + run: npm run check - - name: Commit updated data + - name: Propose updated data for review + env: + GH_TOKEN: ${{ github.token }} run: | git config user.name "craftclass-bot" git config user.email "craftclass-bot@users.noreply.github.com" - git add data/processed/ + git add data/processed/ public/data/ public/images/ if git diff --staged --quiet; then echo "No data changes to commit." else + branch="automation/poe2db-refresh-${GITHUB_RUN_ID}" + git switch -c "$branch" git commit -m "chore(data): weekly poe2db refresh" - git push + git push origin "$branch" + gh pr create \ + --base main \ + --head "$branch" \ + --title "chore(data): weekly poe2db refresh" \ + --body "Automated poe2db refresh. The complete build, SEO verifier, and simulator e2e test passed before this review request was opened." fi diff --git a/.gitignore b/.gitignore index bfa87a3..685078b 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ node_modules/ # Build output dist/ dist.zip +.seo-cache/ # Astro/Vite cache (auto-generated, safe to delete) .astro/ @@ -52,4 +53,4 @@ _*.txt # Build-time prices (replaced by live CF Pages Function at /api/prices) data/processed/prices.json -public/data/prices.json \ No newline at end of file +public/data/prices.json diff --git a/README.md b/README.md index 7e6fb36..c05df48 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,20 @@ # Exile Crafter -A visual crafting companion for **Path of Exile 2**. Browse every base, modifier, currency, and omen, then run live crafting simulations with keyboard shortcuts, in-game style item tooltips, and probability calculations. +A visual crafting companion for **Path of Exile 2**. Browse base, modifier, currency, and omen reference data, then run live crafting simulations with keyboard shortcuts, in-game style item tooltips, and probability calculations. Hosted at [exilecrafter.com](https://exilecrafter.com). Built as a fully static site for [Cloudflare Pages](https://pages.cloudflare.com/). Zero server runtime. ## Features -- **368 base items** across 17 equipment slots (helmets, body armours, gloves, boots, belts, amulets, rings, shields, weapons, foci, quivers, waystones, jewels, tablets, relics, charms, flasks) — each with stat attributes and affix slot counts -- **97 modifiers** with tier, level gate, tag classification, and stat ranges scraped from poe2db -- **135 currency items** — all standard orbs (lesser/normal/greater/perfect tiers), essences (all 4 tiers × 14 families), liquid emotions, catalysts, desecration bones, alloys, breachstones — all with real poe2db icons +- **1,690 base items** across 17 equipment slots (helmets, body armours, gloves, boots, belts, amulets, rings, shields, weapons, foci, quivers, waystones, jewels, tablets, relics, charms, flasks) — each with stat attributes and affix slot counts +- **2,064 modifiers** with tier, level gate, tag classification, and stat ranges scraped from poe2db +- **200 currency items** — all standard orbs (lesser/normal/greater/perfect tiers), essences (all 4 tiers × 14 families), liquid emotions, catalysts, desecration bones, alloys, breachstones — all with real poe2db icons - **50 omens** with effect descriptions, grouped by category (Alchemy, Exaltation, Annulment, Coronation, Erasure, etc.) - **Interactive Simulator** with keyboard shortcuts (`T` Transmute, `A` Alchemy, `R` Regal, `E` Exalt, `X` Annul, `C` Chaos, `D` Divine, `Z` Undo), only-valid-currency display, omen toggles via popover, full activity log, mod pool summary, cost tracking - **Probability Calculator** using a Web Worker for mod pool math (UI never freezes) - **Paste Import** — copy an item from PoE2 (Ctrl+C) and paste it into the simulator to load its exact state, including implicit, prefix, suffix, desecrated, and crafted mods - **In-game style item tooltip** — rarity-colored name, tier indicators (111/11/1), mod tags colored by damage type, gold separators, implicit/prefix/suffix sections -- **Crafting guides** — 7 curated step-by-step paths for common goals +- **Crafting guides** — 8 curated step-by-step paths for common goals - **i18n-ready** — easy to add languages by dropping a JSON file ## Quick start @@ -25,6 +25,8 @@ npm run refresh # scrape poe2db.tw, produce data/processed/*.json npm run weights # optional: bake in community weight data npm run dev # local dev server at http://localhost:4321 npm run build # static build → dist/ +npm run seo:audit # machine-readable rendered SEO snapshot +npm run check # build + deterministic SEO validation npm run preview # preview the built site npm run e2e # end-to-end paste import test ``` @@ -122,7 +124,7 @@ CRAFTCLASS_WEIGHTS_URL=https://example.com/poe2-weights.json npm run weights ## Tech -- **Astro 5** — static site generator with island architecture +- **Astro 7** — static site generator with island architecture - **Tailwind 4** (via Vite plugin) - **TypeScript** strict - **Cheerio** for HTML parsing in build scripts @@ -142,4 +144,4 @@ Exile Crafter is an unofficial fan tool and is not affiliated with or endorsed b ## License -MIT — see [LICENSE](./LICENSE). \ No newline at end of file +MIT — see [LICENSE](./LICENSE). diff --git a/astro.config.mjs b/astro.config.mjs index 8e50bcb..05ae174 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -8,14 +8,18 @@ import tailwindcss from '@tailwindcss/vite'; export default defineConfig({ site: 'https://exilecrafter.com', output: 'static', - trailingSlash: 'ignore', + trailingSlash: 'always', vite: { plugins: [tailwindcss()], worker: { format: 'es', }, }, - integrations: [sitemap()], + integrations: [ + sitemap({ + filter: (page) => page !== 'https://exilecrafter.com/optimizer/', + }), + ], server: { port: 4321, }, diff --git a/docs/seo-audit-2026-07-23.md b/docs/seo-audit-2026-07-23.md new file mode 100644 index 0000000..72e904f --- /dev/null +++ b/docs/seo-audit-2026-07-23.md @@ -0,0 +1,316 @@ +# Exile Crafter SEO audit and changeset + +Audit date: 2026-07-23 + +Site: + +Repository: + +Base commit: `30ce69dee0ed941441dd2251f81433fccfeae273` + +Machine-readable receipt: [`seo-evidence-2026-07-23.json`](./seo-evidence-2026-07-23.json) + +## Decision summary + +This is a **draft, advisory changeset**, not a production release approval. + +- `observed` The base build produced 3,764 HTML pages, but every page lacked a canonical, Open Graph metadata, Twitter metadata, and JSON-LD. [E-HTML-001](#e-html-001) +- `observed` The base internal-link graph left 3,429 pages with no discoverable inlink, while 76,704 rendered page-link occurrences relied on a redirect to add the trailing slash. [E-GRAPH-001](#e-graph-001) +- `observed` Catalogue query variants rendered the same unfiltered static HTML, so the visible filtering controls did not fulfill their user promise. [E-SXO-001](#e-sxo-001) +- `observed` All 2,064 modifier detail pages had fewer than 300 words in rendered main content, and 2,066 pages had fewer than 200 words. [E-CONTENT-001](#e-content-001) +- `observed` The local post-change gate now verifies 3,762 indexable canonicals, zero duplicate indexable titles, sitemap parity, valid JSON-LD, normalized internal links, and explicit dimensions on all 45,534 rendered image occurrences. [E-POST-001](#e-post-001) +- `inferred` The safest first move is to establish crawl, metadata, entity, and regression-control foundations while keeping unresolved catalogue UX and generated-page quality work visible as follow-up. [E-HTML-001](#e-html-001) [E-CONTENT-001](#e-content-001) [E-POST-001](#e-post-001) + +## Release decision + +- `observed` `npm run check` builds the complete static site, runs deterministic policy, metadata, canonical, schema, link, robots, sitemap, heading, and image checks, and executes the simulator paste-import e2e test. [E-POST-001](#e-post-001) +- `observed` The local gate passes against rendered output, but 2,823 indexable pages still have no internal inlink; this remains an advisory programmatic-page risk rather than a hidden pass condition. [E-POST-001](#e-post-001) +- `observed` A repository-wide TypeScript gate is not currently green: TypeScript 7 rejects the base `baseUrl` configuration, and a temporary standards-compatible path configuration exposed existing source errors outside this SEO diff. [E-BASETEST-001](#e-basetest-001) +- `observed` `npm audit` reports one high-severity advisory in `sharp <0.35.0` with a fix available; dependency upgrades are intentionally not hidden inside this SEO changeset. [E-NPM-001](#e-npm-001) +- `observed` A production-versus-preview release guard could not run because no preview deployment URL or Search Ops site UUID exists for this pull request yet. [E-LIMIT-001](#e-limit-001) +- `observed` The upstream repository currently reports no branch-protection rule, no repository ruleset, and no discoverable protected `production` environment; the authenticated contributor has read/pull access but cannot configure those owner controls. [E-GITHUB-001](#e-github-001) +- `documented` The release result is therefore **blocked for merge pending owner-configured branch/environment protection**, and otherwise inconclusive pending preview, baseline type-check resolution, and dependency-advisory review—not “pass.” [E-GITHUB-001](#e-github-001) [E-LIMIT-001](#e-limit-001) [E-BASETEST-001](#e-basetest-001) [E-NPM-001](#e-npm-001) + +## Changes included + +- `observed` The shared layout now emits one normalized HTTPS canonical, robots directives, Open Graph metadata, Twitter metadata, and safely serialized JSON-LD when supplied. [E-PATCH-001](#e-patch-001) +- `observed` The shared social card now references a verified 1200×630 JPEG with image type, dimensions, alt text, and `summary_large_image` Twitter metadata. [E-IMAGEGEN-001](#e-imagegen-001) [E-POST-001](#e-post-001) +- `observed` Base and modifier detail pages now have data-derived titles, descriptions, exact canonicals, and visible-fact `BreadcrumbList` markup; the home page has `WebSite` markup. [E-PATCH-001](#e-patch-001) +- `observed` Modifier badges and base cards now create crawlable detail links, and rendered internal page links use the configured trailing-slash URL form. [E-PATCH-001](#e-patch-001) +- `observed` The legacy optimizer and the custom 404 page are `noindex`; the optimizer is excluded from the sitemap. [E-PATCH-001](#e-patch-001) +- `observed` The source-controlled origin robots file adds the missing absolute sitemap declaration without copying Cloudflare's managed crawler block into the repository. [E-LIVE-001](#e-live-001) [E-PATCH-001](#e-patch-001) +- `observed` The historical audit base emitted 7,528 request-header warnings; upstream removed that static middleware before the final changeset parent, and the proposal preserves deterministic English output with a zero-warning full build. [E-BUILD-001](#e-build-001) [E-UPSTREAM-001](#e-upstream-001) [E-POST-001](#e-post-001) +- `observed` Rendered images now carry explicit dimensions, and offscreen catalogue imagery uses lazy loading and asynchronous decoding. [E-PATCH-001](#e-patch-001) [E-POST-001](#e-post-001) +- `observed` The footer repository link, generated-data date handling, home-page heading, heading hierarchy, and README inventory/framework facts were corrected from repository evidence. [E-REPO-001](#e-repo-001) [E-PATCH-001](#e-patch-001) +- `observed` The stale simulator e2e runner now executes Astro's emitted ES module against the actual rendered simulator page instead of evaluating it as a classic script against a hand-maintained DOM stub. [E-PATCH-001](#e-patch-001) [E-POST-001](#e-post-001) +- `observed` When `main` moved during the audit, the rebase retained its 150 new pure simulator assertions and module/component split; the built-app gate then caught missing component IDs, a broken parsed-base bridge, and a missing currency-operation argument that pure tests did not exercise. The proposed branch restores those runtime contracts and asserts their visible behavior. [E-UPSTREAM-001](#e-upstream-001) [E-POST-001](#e-post-001) +- `observed` External game data embedded in inline JSON now uses one script-safe serializer, and the optimizer no longer inserts a matched external base name through `innerHTML`. [E-PATCH-001](#e-patch-001) [E-POST-001](#e-post-001) +- `observed` External page and image refreshes now enforce HTTPS host allowlists, bounded slugs and item counts, contained output paths, finite redirects, request deadlines, and streamed response-byte ceilings. [E-PATCH-001](#e-patch-001) [E-POST-001](#e-post-001) +- `observed` Production deployment now builds and verifies only reviewed repository data; the weekly external refresh runs the full gate and opens a bot PR containing synchronized processed, browser, and image artifacts instead of pushing unreviewed output to `main`. [E-PATCH-001](#e-patch-001) [E-POST-001](#e-post-001) +- `observed` Manual dispatch was removed from secret-bearing deploy and write-enabled refresh workflows; deployment is disabled by default until the owner sets `PRODUCTION_RELEASE_GUARD_CONFIGURED=true`, and the job targets a named `production` environment for required reviewers, branch restrictions, and environment-scoped secrets. [E-PATCH-001](#e-patch-001) [E-GITHUB-001](#e-github-001) +- `observed` Catalogue counts in metadata and footer output now derive from the current processed manifest with explicit locales, preventing routine data refreshes or CI locale changes from silently staling claims or rendered-output hashes. [E-PATCH-001](#e-patch-001) [E-POST-001](#e-post-001) + +## Technical SEO + +| Rendered-output measure | Base commit | Proposed output | Claim and evidence | +|---|---:|---:|---| +| HTML pages | 3,764 | 3,764 | `observed` [E-HTML-001](#e-html-001) [E-POST-001](#e-post-001) | +| Indexable pages with a canonical | 0 | 3,762 | `observed` [E-HTML-001](#e-html-001) [E-POST-001](#e-post-001) | +| Indexable pages missing shared social title/description/image/card fields | 3,763 | 0 | `observed`; the base 404 is counted separately as an error page. [E-HTML-001](#e-html-001) [E-POST-001](#e-post-001) | +| Duplicate indexable title groups | 34 | 0 | `observed` [E-HTML-001](#e-html-001) [E-POST-001](#e-post-001) | +| Page-link occurrences without trailing slash | 76,704 | 0 | `observed` [E-GRAPH-001](#e-graph-001) [E-POST-001](#e-post-001) | +| Indexable pages with zero internal inlinks | 3,429 | 2,823 | `observed`; still unresolved at scale. [E-GRAPH-001](#e-graph-001) [E-POST-001](#e-post-001) | +| Sitemap URLs | 3,763 | 3,762 | `observed`; proposed sitemap exactly matches indexable canonicals. [E-LIVE-001](#e-live-001) [E-POST-001](#e-post-001) | +| Pages with valid JSON-LD | 0 | 3,755 | `observed` [E-HTML-001](#e-html-001) [E-POST-001](#e-post-001) | +| Image occurrences missing dimensions | 45,522 | 0 | `observed`; the rebased proposal also restores 12 quick-pick images dropped by the upstream component extraction, all with intrinsic dimensions. [E-IMAGE-001](#e-image-001) [E-UPSTREAM-001](#e-upstream-001) [E-POST-001](#e-post-001) | +| Titles longer than 60 characters | 926 | 1,030 | `observed`; advisory, disclosed rather than hidden by lossy truncation. [E-HTML-001](#e-html-001) [E-POST-001](#e-post-001) | + +`documented` `errorPages` and `noindexPages` are independent flags in the machine receipt; the proposed 404 is intentionally counted in both and the values are not additive. [E-HTML-001](#e-html-001) [E-POST-001](#e-post-001) + +- `observed` Live `/bases`, `/mods`, and other slashless page URLs redirected to their trailing-slash equivalents, matching the build’s `trailingSlash: "always"` target. [E-LIVE-001](#e-live-001) +- `observed` The sitemap used unique HTTPS URLs and sampled sitemap pages returned successfully during the audit. [E-LIVE-001](#e-live-001) +- `inferred` Exact canonical and sitemap parity remove ambiguity, but do not by themselves solve page discovery or content quality. [E-GRAPH-001](#e-graph-001) [E-CONTENT-001](#e-content-001) + +## On-page and content + +- `observed` The base commit reused one generic meta description across every rendered page and had 34 duplicate title groups. [E-HTML-001](#e-html-001) +- `observed` The proposed templates derive descriptions from visible item type, level, tier, requirements, modifier count, and domain data, while duplicate modifier descriptions receive semantic tier/domain/type qualifiers. [E-PATCH-001](#e-patch-001) +- `observed` The base README substantially understated the generated inventory and named an older Astro major version; the proposed README matches the processed-data manifest and package manifest. [E-REPO-001](#e-repo-001) [E-PATCH-001](#e-patch-001) +- `observed` The footer linked to a non-existent repository name at the base commit; it now links to the audited source repository. [E-SOURCE-001](#e-source-001) [E-PATCH-001](#e-patch-001) +- `inferred` Editorial trust remains limited because generated detail pages do not explain data methodology, verification cadence, editorial ownership, or how players should interpret unusual modifier records. [E-CONTENT-001](#e-content-001) +- `hypothesis` A concise, visible “data methodology and last verified” module could improve player trust and citation readiness, but its effect should be tested against engagement and search data rather than asserted. [E-CONTENT-001](#e-content-001) + +## Programmatic page risk + +- `observed` The site generates 1,690 base pages and 2,064 modifier pages from the processed game-data files. [E-REPO-001](#e-repo-001) +- `observed` All modifier detail pages were under 300 rendered words at the base commit, and many generated detail URLs had no internal inlink. [E-CONTENT-001](#e-content-001) [E-GRAPH-001](#e-graph-001) +- `observed` The proposed link additions reduce zero-inlink indexable pages from 3,429 to 2,823 but do not eliminate the problem. [E-GRAPH-001](#e-graph-001) [E-POST-001](#e-post-001) +- `inferred` Blanket indexation remains higher risk than a quality-gated rollout because uniqueness in IDs and metadata is not equivalent to unique search value. [E-CONTENT-001](#e-content-001) +- `hypothesis` A browsable, paginated modifier architecture plus template-specific quality thresholds could improve discovery without placing thousands of links in a single document. [E-GRAPH-001](#e-graph-001) + +## Search experience + +- `observed` The base catalogue templates read query parameters during a static build, and sampled query variants were byte-identical to the unfiltered collection pages. [E-SXO-001](#e-sxo-001) +- `observed` The proposed canonicals correctly collapse query variants to the collection URL, but the visible filter behavior itself is not repaired in this changeset. [E-PATCH-001](#e-patch-001) +- `observed` The home page used a 161-character primary heading at the base commit; the proposed page uses a concise task-oriented heading and retains the explanatory copy beneath it. [E-VISUAL-001](#e-visual-001) [E-PATCH-001](#e-patch-001) +- `inferred` Repairing the catalogue filters is a higher user-value follow-up than adding more acquisition pages, because existing search and navigation promises should work before scope expands. [E-SXO-001](#e-sxo-001) + +## Structured data + +- `observed` No rendered page contained JSON-LD at the base commit. [E-HTML-001](#e-html-001) +- `observed` The proposed output contains a `WebSite` entity on the home page and one `BreadcrumbList` on each base and modifier detail page, totaling 3,755 valid JSON-LD blocks. [E-POST-001](#e-post-001) +- `observed` JSON-LD and simulator bootstrap data are serialized with script-terminating characters escaped because the underlying game data is external, untrusted input. [E-SOURCE-001](#e-source-001) [E-PATCH-001](#e-patch-001) +- `documented` `Product`, `Review`, `FAQ`, and `HowTo` markup were intentionally not added because the current visible pages do not support the required factual or commercial claims. [E-PATCH-001](#e-patch-001) +- `observed` The local gate proves parseability and repository invariants; it does not claim Google rich-result eligibility. [E-POST-001](#e-post-001) + +## Images and performance + +- `observed` The repository contained 2,764 local WebP assets, and the audited local image set did not contain an asset over 50 KB. [E-IMAGE-001](#e-image-001) +- `observed` Currency and omen catalogue images were eagerly loaded at the base commit; the proposed templates lazy-load those offscreen assets and provide intrinsic dimensions. [E-IMAGE-001](#e-image-001) [E-PATCH-001](#e-patch-001) +- `observed` `public/og-exile-crafter.jpg` is a 1200×630, 146,465-byte JPEG generated for this changeset and visually inspected for exact title/subtitle text and safe-margin legibility. [E-IMAGEGEN-001](#e-imagegen-001) +- `observed` Repeated local Lighthouse 13.4.1 mobile runs measured home-page CLS at 0.370 and 0.378; representative `/bases/` and `/simulator/` runs measured 0.259 and 0.579 respectively. [E-PERF-001](#e-perf-001) +- `observed` Pre-rebase proposal diagnostics measured mobile CLS at 0.031 on the home page and 0.0047 on `/bases/`, with performance scores of 90 and 84. The final rebased simulator tree measured CLS at 0.0060, performance 88, SEO 100, and LCP 3,796 ms after reserving the loading-to-empty-state layout. [E-PERF-001](#e-perf-001) [E-UPSTREAM-001](#e-upstream-001) +- `observed` Those are lab measurements, and target-scoped CrUX field data was unavailable; no field CWV pass or fail is claimed. [E-LIMIT-001](#e-limit-001) +- `inferred` The post-change lab direction is favorable, but run-to-run variability, web-font behavior, and absent field data prevent a causal performance claim. [E-IMAGE-001](#e-image-001) [E-PERF-001](#e-perf-001) + +## GEO and AI search + +- `observed` The live crawler policy on the audit date allowed conventional search indexing, reserved AI-training rights, and blocked named extended/training crawlers. [E-LIVE-001](#e-live-001) +- `documented` [Cloudflare prepends its managed crawler block](https://developers.cloudflare.com/bots/additional-configurations/managed-robots-txt/#existing-robotstxt-file) to an existing origin `robots.txt`; the proposed origin file therefore contains only the conventional wildcard rule and sitemap declaration. [E-CLOUDFLARE-001](#e-cloudflare-001) [E-PATCH-001](#e-patch-001) +- `observed` `llms.txt` was not present on the live site, while page-level answer passages, sourcing context, and methodology remained sparse. [E-LIVE-001](#e-live-001) [E-CONTENT-001](#e-content-001) +- `inferred` Entity-consistent metadata and visible-fact schema improve machine interpretation, but AI visibility should not be claimed without platform observations or referral data. [E-POST-001](#e-post-001) [E-LIMIT-001](#e-limit-001) +- `documented` No crawler-rights restriction should be relaxed as an SEO side effect; that choice belongs to the site owner, and the combined Cloudflare preview response must be checked before merge. [E-LIVE-001](#e-live-001) [E-CLOUDFLARE-001](#e-cloudflare-001) + +## Internationalization + +- `observed` Translation dictionaries for English and Portuguese exist, but the static build exposes one shared URL set and rendered English output. [E-SOURCE-001](#e-source-001) +- `observed` Historical request-header locale detection produced static-build warnings and could not create stable language-specific canonicals; the final base removed that middleware. [E-BUILD-001](#e-build-001) [E-UPSTREAM-001](#e-upstream-001) +- `observed` The proposed shared layout and page sources explicitly render the current public URLs in English. [E-PATCH-001](#e-patch-001) +- `documented` Hreflang is deferred until separate locale URLs exist; when introduced, every localized page needs self-canonical and reciprocal annotations. [E-PATCH-001](#e-patch-001) + +## Search intelligence + +- `observed` A free web-search sample for Path of Exile 2 crafting surfaced dedicated tools and guides including [Forge of Exiles](https://forgeofexiles.com/), [PoE2 Wiki](https://www.poe2wiki.net/wiki/Crafting), [Sekhema Sandbox](https://sekhemasandbox.com/), and [Mobalytics](https://mobalytics.gg/poe-2/profile/perra/guides/poe2-crafting-guide). [E-SERP-001](#e-serp-001) +- `observed` The sample was directional only: no paid search volume, ranking history, or target-region SERP export was available. [E-LIMIT-001](#e-limit-001) +- `inferred` Existing competitors combine reference content with task-completion tools, supporting the decision to prioritize working filters, discoverable item relationships, and evidence-rich guides before publishing more templates. [E-SERP-001](#e-serp-001) [E-SXO-001](#e-sxo-001) + +## FLOW decision + +- **Find:** `observed` Crawl, rendered-output, live-response, content, performance, visual, and repository evidence identified metadata absence, weak discovery, broken catalogue filtering, thin generated pages, and unstable lab CLS. [E-HTML-001](#e-html-001) [E-GRAPH-001](#e-graph-001) [E-SXO-001](#e-sxo-001) [E-PERF-001](#e-perf-001) +- **Leverage:** `observed` Existing Astro layouts, processed game data, detail templates, and sitemap integration support deterministic fixes without a new content system. [E-SOURCE-001](#e-source-001) +- **Optimize:** `observed` This changeset adds shared metadata, schemas, URL normalization, discovery links, crawler-policy parity, image safeguards, and a rendered-output gate. [E-PATCH-001](#e-patch-001) +- **Win:** `hypothesis` The next defensible outcome is improved discovery and organic tool usage, measured with target-scoped first-party data after a clean preview comparison. [E-MEASURE-001](#e-measure-001) + +Framework and prompts © Daniel Agrici, CC BY 4.0 — github.com/AgriciDaniel/flow + +## Verification and drift control + +- `observed` `seo-skill-policy.json` records an explicit decision for all 27 umbrella SEO specialist skills plus the repository release guard. [E-POLICY-001](#e-policy-001) +- `observed` `npm run seo:skills` fails when a specialist decision or evidence artifact is missing. [E-POLICY-001](#e-policy-001) +- `observed` `npm run seo:check` parses every rendered HTML page and fails on canonical mismatches, duplicate indexable titles, malformed schema, sitemap drift, missing social metadata, unnormalized internal page links, heading/landmark violations, and robots omissions. [E-POST-001](#e-post-001) +- `observed` The same gate injects malicious script/attribute fixtures through the built simulator, calculator, and optimizer, verifies lossless safe-JSON and safe-HTML round trips, and proves that a sitewide `Disallow: /` fixture cannot satisfy the exact origin robots policy. [E-POST-001](#e-post-001) +- `observed` Adversarial refresh fixtures reject external or local hosts, encoded traversal, unsafe output paths, excessive discoveries, redirect chains, timeouts, oversized responses, parser failures, unknown seasons, and implausible dataset drift before external data can enter generated routes or browser payloads. [E-POST-001](#e-post-001) +- `observed` The gate also verifies exact per-route schema cardinality, non-empty social-value parity, current data counts, byte-identical processed/browser datasets, processed-data route coverage, internal link-target existence, workflow approval ordering, policy anchors, absolute social-image references, JPEG dimensions, and the social asset size ceiling. [E-POST-001](#e-post-001) +- `documented` Title length, remaining zero-inlink pages, and image counts are reported as advisories so a heuristic cannot silently replace human search-intent judgment. [E-POST-001](#e-post-001) + +## Skill coverage + +The machine-checked coverage decision is in [`seo-skill-policy.json`](../seo-skill-policy.json). + +| Coverage | Skills | Claim and evidence | +|---|---|---| +| Required | audit, page, technical, content, schema, images, sitemap, GEO, performance, visual, plan, programmatic, SXO, image generation, FLOW, search intelligence | `observed` Applied in this audit. [E-POLICY-001](#e-policy-001) | +| Conditional | hreflang, Google first-party data, backlinks, clustering, drift, Firecrawl, DataForSEO, release guard | `observed` Preconditions or target-scoped access were unavailable. [E-LIMIT-001](#e-limit-001) [E-POLICY-001](#e-policy-001) | +| Not applicable | competitor-page generation, local, maps, ecommerce | `observed` These page/business types are outside this changeset. [E-POLICY-001](#e-policy-001) | + +## Prioritized follow-up + +1. `documented` **Protect release authority before merge:** require PRs and the `Quality` check on `main`, block direct/force pushes, dismiss stale approvals, create a protected `production` environment, restrict it to `main`, require an owner reviewer, and move Cloudflare credentials to environment-scoped secrets. [E-GITHUB-001](#e-github-001) +2. `inferred` **Repair catalogue filters and URL state**, then test keyboard, mobile, empty-result, and shareable-filter behavior. [E-SXO-001](#e-sxo-001) +3. `inferred` **Design paginated discovery for base/modifier detail pages** and define an indexation quality threshold before expanding generated templates. [E-GRAPH-001](#e-graph-001) [E-CONTENT-001](#e-content-001) +4. `inferred` **Connect target-scoped Search Console and GA4**, pre-register the baseline, and inspect index coverage, query/page cohorts, organic tool starts, and engaged sessions. [E-LIMIT-001](#e-limit-001) [E-MEASURE-001](#e-measure-001) +5. `inferred` **Run a preview performance trace** for fonts, `/bases/`, and `/simulator/`; use field CWV when available and treat local Lighthouse as diagnostic. [E-PERF-001](#e-perf-001) +6. `hypothesis` **Add visible methodology and curated interpretation** to high-demand modifier/base cohorts after SERP-overlap and first-party demand validation. [E-CONTENT-001](#e-content-001) [E-SERP-001](#e-serp-001) +7. `documented` **Run the release guard** with exact production and preview URLs before merge; do not convert an unavailable comparison into a pass. [E-LIMIT-001](#e-limit-001) + +## Measurement + +- `documented` **Primary outcome:** organic search users who start the simulator or calculator, segmented by landing-page template. [E-MEASURE-001](#e-measure-001) +- `documented` **Leading indicators:** valid indexed pages, non-brand clicks, query-to-detail impressions, crawl discovery, and organic engaged sessions. [E-MEASURE-001](#e-measure-001) +- `documented` **Guardrails:** no increase in canonical/sitemap errors, soft-404 signals, render failures, or field CWV regressions. [E-MEASURE-001](#e-measure-001) +- `documented` Capture a pre-deploy baseline, annotate deployment time, compare stable cohorts after sufficient search recrawl, and avoid causal claims from a simple before/after movement. [E-MEASURE-001](#e-measure-001) + +## Risk and rollback + +- `inferred` Risk is **medium** because shared layout and generated detail templates affect thousands of URLs, even though the code diff is narrow and static. [E-PATCH-001](#e-patch-001) +- `observed` No secret, credential, user-data path, or cross-tenant behavior is introduced; production deployment no longer mutates approved build input from the network. [E-PATCH-001](#e-patch-001) +- `documented` Roll back by reverting the changeset commit; the deployment is static and the prior route files remain recoverable in Git. [E-REPO-001](#e-repo-001) +- `documented` Do not merge or move the PR out of draft until the owner-side branch and production-environment controls are verified; repository code cannot create or prove those settings. [E-GITHUB-001](#e-github-001) +- `documented` If preview checks find canonical, rendering, crawler-policy, or tool-flow regressions, do not merge; fix or revert before a production deployment. [E-POST-001](#e-post-001) + +## Evidence limitations + +- `observed` Target-authorized Search Console, GA4, URL Inspection, and CrUX data were unavailable, so traffic, ranking, indexation, and field-CWV claims are intentionally absent. [E-LIMIT-001](#e-limit-001) +- `observed` Semrush access had insufficient API units, while DataForSEO and Firecrawl were unavailable in this environment. [E-LIMIT-001](#e-limit-001) +- `observed` Common Crawl did not provide a useful target-specific backlink signal in the bounded check; no backlink-health conclusion is made. [E-LIMIT-001](#e-limit-001) +- `observed` Live crawling was bounded to protocol/redirect checks, key routes, robots, sitemap validation, and a stratified sample; the complete crawl was performed against deterministic local rendered output. [E-LIVE-001](#e-live-001) [E-POST-001](#e-post-001) +- `observed` Repository-wide `npx tsc --noEmit` is a pre-existing failing gate and is not represented as passing in this report. [E-BASETEST-001](#e-basetest-001) +- `observed` The existing high-severity `sharp` advisory remains open and should be resolved in a separately tested dependency changeset. [E-NPM-001](#e-npm-001) +- `documented` Search-result samples are volatile and advisory; they are not ranking proof or keyword-volume evidence. [E-SERP-001](#e-serp-001) + +## Evidence ledger + + +### E-REPO-001 — Repository and data snapshot + +`observed` Git base `30ce69dee0ed941441dd2251f81433fccfeae273`; `package.json`; `data/processed/manifest.json` generated at `2026-07-22T05:17:48.629Z`; processed arrays of 1,690 bases, 2,064 modifiers, 200 currency entries, and 50 omens; eight method records in `src/lib/methods.ts`. + + +### E-SOURCE-001 — Source inspection + +`observed` Astro configuration, layouts, middleware, components, page templates, i18n dictionaries, build scripts, data provenance declarations, route generation, and repository history at the base commit. + + +### E-BUILD-001 — Base build + +`observed` Clean dependency install and `npm run build` at the final base commit; 150 pure assertions passed, 3,764 pages were generated, and no request-header warning remained. The historical audit base `b6964ec34635633ac3905f15fad5f6440fc4401e` emitted 7,528 such warnings before upstream removed the static middleware. + + +### E-UPSTREAM-001 — Upstream drift and semantic rebase + +`observed` During PR creation, upstream `main` advanced from `b6964ec34635633ac3905f15fad5f6440fc4401e` through simulator parser, library, test, and component-refactor commits, then to the recorded base `30ce69dee0ed941441dd2251f81433fccfeae273` with middleware removal and partial DOM-contract repairs. A clean final-base build passed 150 pure assertions and generated 3,764 pages. The full rendered baseline changed only from 45,534 to 45,522 image occurrences because the extracted quick-pick component omitted 12 prior images; the other normalized SEO metrics were unchanged. The actual emitted-module e2e test additionally verified component IDs, visible paste result and main UI, parsed base match, currency mapping, exact seven-row import, malicious external-data rendering, and the reserved initial layout. + + +### E-HTML-001 — Base rendered-output crawl + +`observed` Full Cheerio parse of every base-commit HTML file for titles, descriptions, canonicals, robots, social metadata, headings, landmarks, JSON-LD, word counts, and image attributes. Reproduce from a clean base worktree with the commands and output hash in [`seo-evidence-2026-07-23.json`](./seo-evidence-2026-07-23.json). + + +### E-GRAPH-001 — Internal graph and URL normalization + +`observed` Full base-commit anchor graph normalized against `https://exilecrafter.com/`; redirect-form link occurrences, zero-inlink routes, and generated-route membership were counted by `scripts/audit-seo-output.mjs` and recorded in [`seo-evidence-2026-07-23.json`](./seo-evidence-2026-07-23.json). + + +### E-CONTENT-001 — Content and generated-page review + +`observed` Full word-count distribution from `scripts/audit-seo-output.mjs` plus representative home, catalogue, base, modifier, guide, calculator, simulator, optimizer, data-source, and trust-signal review; normalized counts are retained in [`seo-evidence-2026-07-23.json`](./seo-evidence-2026-07-23.json). + + +### E-SXO-001 — Catalogue behavior + +`observed` Source tracing and byte comparison of generated catalogue HTML for unparameterized and query-parameter routes; static code reads `Astro.request.url` without producing distinct filtered output. + + +### E-LIVE-001 — Bounded live observation + +`observed` HTTPS/HTTP status and redirect checks; production `robots.txt`; sitemap index and URL-set parsing; 52 stratified sitemap URL requests; observations captured 2026-07-23. + + +### E-CLOUDFLARE-001 — Managed robots behavior + +`documented` Cloudflare's official [managed robots documentation](https://developers.cloudflare.com/bots/additional-configurations/managed-robots-txt/#existing-robotstxt-file), last checked 2026-07-23, states that managed content is prepended to an origin file that returns HTTP 200. This is the basis for avoiding a stale duplicate of the managed block in source. + + +### E-IMAGE-001 — Image inventory + +`observed` Repository image walk for type and byte size, source-template loading/attribute inspection, and complete rendered-image occurrence analysis. + + +### E-IMAGEGEN-001 — Social preview asset + +`observed` Built-in OpenAI image generation produced the project-bound social artwork from a dark-fantasy crafting-banner prompt with exact “EXILE CRAFTER” and “PATH OF EXILE 2 CRAFTING COMPANION” text, no official game logo, and no watermark. The selected output was resized to 1200×630 JPEG, saved as `public/og-exile-crafter.jpg`, visually inspected, and validated by the deterministic gate. + + +### E-PERF-001 — Lab performance + +`observed` Lighthouse 13.4.1 mobile lab runs against local production builds for the home, base catalogue, and simulator templates. Home and base catalogue values are explicitly scoped to the pre-rebase proposal; the simulator was rerun against the final rebased source after its component and layout repair. Normalized measurements and the missing-raw-trace limitation are retained in [`seo-evidence-2026-07-23.json`](./seo-evidence-2026-07-23.json). + + +### E-VISUAL-001 — Visual review + +`observed` Mobile and desktop screenshot review of above-the-fold hierarchy, calls to action, navigation, catalogue density, and tool states. + + +### E-SERP-001 — Free-first search sample + +`observed` Bounded web search captured 2026-07-23 for Path of Exile 2 crafting-tool and guide intents; source pages are linked in [Search intelligence](#search-intelligence). + + +### E-LIMIT-001 — Access and freshness boundary + +`observed` Target authorization and connector checks for Google first-party data, CrUX/PageSpeed, Semrush, DataForSEO, Firecrawl, backlink sources, preview deployment, and Search Ops site registration. + + +### E-BASETEST-001 — Baseline type-check boundary + +`observed` `npx tsc --noEmit` against the unchanged base `tsconfig.json` fails because TypeScript 7 removed `baseUrl`; a temporary local migration to relative `paths` then exposed existing errors in the API and emulator modules. The temporary configuration was reverted, no type error was suppressed, and the proposed diff does not claim a passing repository-wide type gate. + + +### E-NPM-001 — Dependency audit boundary + +`observed` `npm audit --json` on 2026-07-23 reported one high-severity `sharp <0.35.0` advisory, [GHSA-f88m-g3jw-g9cj](https://github.com/advisories/GHSA-f88m-g3jw-g9cj), and no critical advisories. The machine receipt records the result; this draft does not apply an unreviewed dependency upgrade. + + +### E-PATCH-001 — Proposed source diff + +`observed` Proposed branch diff from the recorded base commit, including shared metadata, schemas, normalized links, index controls, crawler policy, deterministic locale behavior, image attributes, simulator runtime-contract repairs exposed by the semantic rebase, bounded external-data refreshes, approval-safe workflows, synchronized browser data, documentation, and verification code. The immutable final commit and canonical patch hash are published in the draft PR body after commit creation, avoiding a self-referential hash inside the diff. + + +### E-GITHUB-001 — Repository release-control boundary + +`observed` Read-only GitHub repository-control checks on 2026-07-23 returned contributor permission without push/admin authority, zero repository rulesets, no accessible `main` protection configuration, and no accessible `production` environment. The proposed workflow removes branch-selectable manual dispatch, targets a named production environment, and gates reviewed source, but owner-side rules and environment-scoped secrets remain required before merge. + + +### E-POST-001 — Proposed rendered-output gate + +`observed` `npm run check`; 3,764 HTML pages, 3,762 indexable pages, two noindex pages, 3,762 sitemap URLs, 3,755 valid JSON-LD blocks, zero duplicate indexable titles, zero non-normalized internal page links, zero missing image dimensions across 45,534 rendered occurrences, and 2,823 advisory zero-inlink pages. The same command runs exact seven-row paste assertions, malicious-data render fixtures through the built simulator/calculator/optimizer, refresh-boundary adversarial tests, workflow/source-data parity checks, and the policy gate. The SEO-output hash and normalized metrics are retained in [`seo-evidence-2026-07-23.json`](./seo-evidence-2026-07-23.json). + + +### E-POLICY-001 — Specialist coverage + +`observed` `seo-skill-policy.json` plus `npm run seo:skills`; 28 unique, evidence-linked coverage decisions. + + +### E-MEASURE-001 — Measurement protocol + +`documented` Proposed pre/post cohort protocol using target-scoped Search Console and analytics data when authorized; no outcome is claimed before deployment and sufficient recrawl. diff --git a/docs/seo-evidence-2026-07-23.json b/docs/seo-evidence-2026-07-23.json new file mode 100644 index 0000000..2715599 --- /dev/null +++ b/docs/seo-evidence-2026-07-23.json @@ -0,0 +1,217 @@ +{ + "schemaVersion": 1, + "auditId": "exilecrafter-seo-2026-07-23", + "capturedAt": "2026-07-23", + "site": "https://exilecrafter.com", + "repository": "https://github.com/buzzkillb/exilecrafter", + "initialAuditBase": "b6964ec34635633ac3905f15fad5f6440fc4401e", + "baseCommit": "30ce69dee0ed941441dd2251f81433fccfeae273", + "sourceBinding": "The final head commit and SHA-256 of the canonical base-to-head patch are recorded in the draft pull-request body after commit creation; embedding that hash here would make the diff self-referential.", + "environment": { + "node": "v26.5.0", + "astro": "7.1.3", + "cheerio": "1.2.0", + "lighthouse": "13.4.1" + }, + "renderedAudit": { + "tool": "scripts/audit-seo-output.mjs", + "hashDefinition": "SHA-256 over sorted relative path, NUL, file bytes, NUL for HTML, sitemap XML, robots.txt, the social preview asset, and the seven browser data payloads", + "reproduction": [ + "git worktree add --detach ../exilecrafter-seo-baseline 30ce69dee0ed941441dd2251f81433fccfeae273", + "(cd ../exilecrafter-seo-baseline && npm ci && npm run build)", + "node scripts/audit-seo-output.mjs --dist=../exilecrafter-seo-baseline/dist", + "npm run build && node scripts/audit-seo-output.mjs" + ], + "metricSemantics": "errorPages and noindexPages are independent flags; the proposed 404 page is counted in both and the categories must not be summed.", + "localeDeterminism": { + "locales": [ + "C", + "sv_SE.UTF-8" + ], + "matchingOutput": true, + "seoOutputSha256": "de78b672ef10a014620e7c944ad8f51523009e14fe99af12b98834162df58106" + }, + "baseline": { + "seoOutputSha256": "540a4bc293566d3e80b3b4ea8d94ccfea865f14d4570afdc7016331980cd7da1", + "metrics": { + "htmlPages": 3764, + "indexablePages": 3763, + "noindexPages": 0, + "errorPages": 1, + "missingCanonicals": 3763, + "missingSharedSocialMetadata": 3763, + "jsonLdPages": 0, + "invalidJsonLdBlocks": 0, + "duplicateTitleGroups": 34, + "titlesOver60": 926, + "pagesUnder200Words": 2066, + "modPagesUnder300Words": 2064, + "imageOccurrences": 45522, + "imagesMissingDimensions": 45522, + "nonTrailingPageLinkOccurrences": 76704, + "zeroInlinkPages": 3429, + "sitemapUrls": 3763, + "duplicateSitemapUrls": 0 + } + }, + "proposed": { + "seoOutputSha256": "de78b672ef10a014620e7c944ad8f51523009e14fe99af12b98834162df58106", + "metrics": { + "htmlPages": 3764, + "indexablePages": 3762, + "noindexPages": 2, + "errorPages": 1, + "missingCanonicals": 0, + "missingSharedSocialMetadata": 0, + "jsonLdPages": 3755, + "invalidJsonLdBlocks": 0, + "duplicateTitleGroups": 0, + "titlesOver60": 1030, + "pagesUnder200Words": 2066, + "modPagesUnder300Words": 2064, + "imageOccurrences": 45534, + "imagesMissingDimensions": 0, + "nonTrailingPageLinkOccurrences": 0, + "zeroInlinkPages": 2823, + "sitemapUrls": 3762, + "duplicateSitemapUrls": 0 + } + } + }, + "rebaseReceipt": { + "initialAuditBase": "b6964ec34635633ac3905f15fad5f6440fc4401e", + "changesetParent": "30ce69dee0ed941441dd2251f81433fccfeae273", + "upstreamPureAssertions": 150, + "baselineMetricDelta": "Only imageOccurrences and imagesMissingDimensions changed, from 45534 to 45522, because the simulator component extraction omitted 12 quick-pick images.", + "builtAppRepairs": [ + "restored main UI and omen-control DOM contracts", + "used the parser-resolved base record", + "passed the operation registry to currency mapping", + "restored visible paste results and quick-pick images", + "reserved initial simulator layout to prevent the loading-to-empty-state shift" + ] + }, + "liveReceipt": { + "capturedAt": "2026-07-23", + "method": "Bounded curl checks for protocol, redirects, robots, sitemap, key routes, query variants, and 52 stratified sitemap URLs.", + "queryVariantBodies": [ + { + "url": "https://exilecrafter.com/bases/", + "sha256": "d347cac94e5033c5c30e23b61e2db1ea40ed9b6539ceacd839bfc6c891c2cad8" + }, + { + "url": "https://exilecrafter.com/bases/?slot=ring", + "sha256": "d347cac94e5033c5c30e23b61e2db1ea40ed9b6539ceacd839bfc6c891c2cad8" + }, + { + "url": "https://exilecrafter.com/mods/", + "sha256": "ec33d5e269954d86218874b8cd0a9cb3d38f92762cf0a2d657a2dda2e83d99a3" + }, + { + "url": "https://exilecrafter.com/mods/?type=prefix", + "sha256": "ec33d5e269954d86218874b8cd0a9cb3d38f92762cf0a2d657a2dda2e83d99a3" + } + ], + "sitemapSample": { + "requested": 52, + "successful": 52 + }, + "robots": { + "managedBy": "Cloudflare", + "searchSignal": "yes", + "aiTrainSignal": "no", + "useSignal": "reference", + "sitemapDeclarationPresent": false + } + }, + "performanceReceipt": { + "capturedAt": "2026-07-23", + "tool": "Lighthouse 13.4.1", + "mode": "local production build, mobile emulation", + "baselineMetrics": { + "homeClsRuns": [ + 0.37, + 0.378 + ], + "basesCls": 0.259, + "simulatorCls": 0.579 + }, + "proposedRuns": [ + { + "route": "/", + "treeScope": "pre-rebase proposal diagnostic; not the final changeset tree", + "performanceScore": 90, + "seoScore": 100, + "lcpMilliseconds": 2883.8197500000006, + "cls": 0.030754560828536857, + "totalBytes": 167470, + "rawReportSha256": "06a27c7042faf46329246f265dc04933f640e4043fe4481701099123754a86ee" + }, + { + "route": "/bases/", + "treeScope": "pre-rebase proposal diagnostic; not the final changeset tree", + "performanceScore": 84, + "seoScore": 100, + "lcpMilliseconds": 3694.22195, + "cls": 0.004686827630065536, + "totalBytes": 1165614, + "rawReportSha256": "c42d94156e969363dec707bf0b2d916ed5ab8a6980a1582196ed925ef35e2641" + }, + { + "route": "/simulator/", + "treeScope": "final rebased proposed tree", + "performanceScore": 88, + "seoScore": 100, + "lcpMilliseconds": 3796.1335499999996, + "cls": 0.0059927590257546045, + "totalBytes": 428347, + "rawReportSha256": "3e21ae9ade8382914d51cf966df03f555263fa107d0ee664ee531960c5489221" + } + ], + "rawArtifactRetained": false, + "limitation": "Normalized lab receipt only; no target-scoped CrUX field data and no retained Lighthouse trace." + }, + "accessReceipt": { + "googleSearchConsole": "target authorization unavailable", + "ga4": "target authorization unavailable", + "crux": "target field data unavailable", + "semrush": "insufficient API units", + "dataforseo": "connector unavailable", + "firecrawl": "connector unavailable", + "backlinks": "bounded free-source check inconclusive", + "releasePreviewUrl": "unavailable", + "searchOpsSiteUuid": "unavailable" + }, + "repositoryControls": { + "capturedAt": "2026-07-23", + "viewerPermission": "READ", + "pushAllowed": false, + "repositoryRulesets": 0, + "mainProtection": "not found", + "productionEnvironment": "not found", + "requiredOwnerAction": "Before merge, require PRs and the Quality check on main, block direct and force pushes, dismiss stale approvals, create a protected production environment restricted to main with a required reviewer, and move Cloudflare credentials to environment-scoped secrets." + }, + "verificationControls": { + "workflowParsing": "structural YAML validation with an echo-decoy negative fixture", + "productionDeploy": "disabled unless PRODUCTION_RELEASE_GUARD_CONFIGURED=true; push to main only; exact npm run check before publish; no live refresh; named production environment", + "weeklyRefresh": "schedule only; bounded external refresh; exact npm run check; bot PR instead of direct main push", + "externalData": "HTTPS origin allowlists, contained paths, finite redirects, deadlines, byte/item bounds, fail-closed parser and season validation, and 25% drop/50% growth drift ceilings", + "clientData": "seven processed and public JSON payloads must be byte-identical", + "maliciousRenderFixtures": [ + "simulator", + "calculator", + "optimizer" + ] + }, + "dependencyAudit": { + "capturedAt": "2026-07-23", + "command": "npm audit --json", + "critical": 0, + "high": 1, + "package": "sharp", + "affectedRange": "<0.35.0", + "advisory": "https://github.com/advisories/GHSA-f88m-g3jw-g9cj", + "fixAvailable": true, + "changesetAction": "reported, not automatically upgraded in the SEO changeset" + } +} diff --git a/package-lock.json b/package-lock.json index 86e608c..5f1c272 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,8 +17,12 @@ }, "devDependencies": { "@types/node": "^26.1.1", + "js-yaml": "^4.3.0", "jsdom": "^29.1.1", "typescript": "^7.0.2" + }, + "engines": { + "node": ">=22.13.0" } }, "node_modules/@asamuzakjp/css-color": { diff --git a/package.json b/package.json index e0c09d0..2f5018a 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,9 @@ "version": "0.1.0", "private": true, "type": "module", + "engines": { + "node": ">=22.13.0" + }, "scripts": { "dev": "astro dev", "start": "astro dev", @@ -15,7 +18,11 @@ "process": "node scripts/process-data.mjs && node scripts/download-images.mjs", "weights": "node scripts/fetch-weights.mjs", "e2e": "node scripts/_e2e_paste.mjs", - "test": "node --experimental-strip-types --no-warnings tests/run.mjs" + "test": "node --experimental-strip-types --no-warnings tests/run.mjs", + "seo:audit": "node scripts/audit-seo-output.mjs", + "seo:skills": "node scripts/verify-seo.mjs --policy-only", + "seo:check": "node scripts/verify-seo.mjs", + "check": "npm run build && npm run seo:check && npm run e2e" }, "dependencies": { "@astrojs/sitemap": "^3.7.3", @@ -27,7 +34,8 @@ }, "devDependencies": { "@types/node": "^26.1.1", + "js-yaml": "^4.3.0", "jsdom": "^29.1.1", "typescript": "^7.0.2" } -} \ No newline at end of file +} diff --git a/public/data/bases.json b/public/data/bases.json index 6924267..41cb4ce 100644 --- a/public/data/bases.json +++ b/public/data/bases.json @@ -11,7 +11,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace10.webp", + "imageUrl": "/images/base/aberrant_sledge.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32,7 +32,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/Basetypes/AbsentAmulet.webp", + "imageUrl": "/images/base/absent_amulet.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -53,7 +53,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/abyss_tablet.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -76,7 +76,7 @@ "baseStats": { "armour": 496 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr01.webp", + "imageUrl": "/images/base/abyssal_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -97,7 +97,7 @@ "int": 36 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Flails/Flail13.webp", + "imageUrl": "/images/base/abyssal_flail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -118,7 +118,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/Basetypes/IronRing.webp", + "imageUrl": "/images/base/abyssal_signet.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -139,7 +139,7 @@ "int": 60 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Wands/Basetypes/Wand07.webp", + "imageUrl": "/images/base/acrid_wand.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -160,7 +160,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow07.webp", + "imageUrl": "/images/base/adherent_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -184,7 +184,7 @@ "armour": 98, "energy_shield": 27 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr04.webp", + "imageUrl": "/images/base/adherent_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -208,7 +208,7 @@ "armour": 96, "energy_shield": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr01.webp", + "imageUrl": "/images/base/adherent_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -231,7 +231,7 @@ "baseStats": { "energy_shield": 127 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt07.webp", + "imageUrl": "/images/base/adherents_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -254,7 +254,7 @@ "baseStats": { "energy_shield": 45 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt01.webp", + "imageUrl": "/images/base/adorned_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -278,7 +278,7 @@ "evasion": 74, "energy_shield": 23 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt03.webp", + "imageUrl": "/images/base/adorned_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -301,7 +301,7 @@ "baseStats": { "evasion": 148 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler13.webp", + "imageUrl": "/images/base/aegis_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -322,7 +322,7 @@ "int": 50 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff08.webp", + "imageUrl": "/images/base/aegis_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -346,7 +346,7 @@ "armour": 27, "energy_shield": 10 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr02.webp", + "imageUrl": "/images/base/aged_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -369,7 +369,7 @@ "baseStats": { "armour": 145 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower02.webp", + "imageUrl": "/images/base/aged_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -390,7 +390,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace10.webp", + "imageUrl": "/images/base/akoyan_club.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -411,7 +411,7 @@ "int": 90 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear10.webp", + "imageUrl": "/images/base/akoyan_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -432,7 +432,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow06.webp", + "imageUrl": "/images/base/alloy_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -453,7 +453,7 @@ "int": 72 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/PrimalTalisman.webp", + "imageUrl": "/images/base/alpha_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -476,7 +476,7 @@ "baseStats": { "energy_shield": 95 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt08.webp", + "imageUrl": "/images/base/altar_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -497,7 +497,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/Basetypes/AmberAmulet.webp", + "imageUrl": "/images/base/amber_amulet.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -518,7 +518,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Charms/Basetypes/AmethystCharm.webp", + "imageUrl": "/images/base/amethyst_charm.webp", "affixSlots": { "prefix": 0, "suffix": 0 @@ -539,7 +539,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/Basetypes/AmethystRing.webp", + "imageUrl": "/images/base/amethyst_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -560,7 +560,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/amphora_relic.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -583,7 +583,7 @@ "baseStats": { "armour": 160 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower10.webp", + "imageUrl": "/images/base/ancestor_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -607,7 +607,7 @@ "armour": 214, "evasion": 194 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex08.webp", + "imageUrl": "/images/base/ancestral_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -630,7 +630,7 @@ "baseStats": { "energy_shield": 109 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt08.webp", + "imageUrl": "/images/base/ancestral_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -654,7 +654,7 @@ "evasion": 132, "energy_shield": 46 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt05.webp", + "imageUrl": "/images/base/anchorite_garb.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -677,7 +677,7 @@ "baseStats": { "evasion": 178 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler08.webp", + "imageUrl": "/images/base/ancient_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -701,7 +701,7 @@ "armour": 89, "energy_shield": 25 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr02.webp", + "imageUrl": "/images/base/ancient_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -725,7 +725,7 @@ "armour": 89, "evasion": 81 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex01.webp", + "imageUrl": "/images/base/ancient_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -746,7 +746,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandSwords/Basetypes/2HSword10.webp", + "imageUrl": "/images/base/ancient_greatblade.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -770,7 +770,7 @@ "armour": 134, "energy_shield": 37 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr01.webp", + "imageUrl": "/images/base/ancient_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -794,7 +794,7 @@ "armour": 273, "energy_shield": 76 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Uniques/Loreweave.webp", + "imageUrl": "/images/base/ancient_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -817,7 +817,7 @@ "baseStats": { "armour": 137 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr04.webp", + "imageUrl": "/images/base/ancient_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -841,7 +841,7 @@ "armour": 179, "evasion": 163 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex08.webp", + "imageUrl": "/images/base/ancient_visor.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -862,7 +862,7 @@ "int": 29 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff01.webp", + "imageUrl": "/images/base/anima_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -883,7 +883,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Charms/Basetypes/AntidoteCharm.webp", + "imageUrl": "/images/base/antidote_charm.webp", "affixSlots": { "prefix": 0, "suffix": 0 @@ -906,7 +906,7 @@ "baseStats": { "energy_shield": 18 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus03.webp", + "imageUrl": "/images/base/antler_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -927,7 +927,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace03.webp", + "imageUrl": "/images/base/anvil_maul.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -951,7 +951,7 @@ "armour": 134, "energy_shield": 37 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr02.webp", + "imageUrl": "/images/base/apostle_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -974,7 +974,7 @@ "baseStats": { "weapon_range": "1" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Daggers/Basetypes/Dagger12.webp", + "imageUrl": "/images/base/arcane_dirk.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -997,7 +997,7 @@ "baseStats": { "energy_shield": 138 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt01.webp", + "imageUrl": "/images/base/arcane_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1018,7 +1018,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Claws/Basetypes/Claw07.webp", + "imageUrl": "/images/base/arced_claw.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1039,7 +1039,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandSwords/Basetypes/2HSword06.webp", + "imageUrl": "/images/base/arced_longsword.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1060,7 +1060,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandAxes/Basetypes/2HAxe04.webp", + "imageUrl": "/images/base/arched_greataxe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1084,7 +1084,7 @@ "armour": 179, "energy_shield": 50 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr08.webp", + "imageUrl": "/images/base/archon_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1105,7 +1105,7 @@ "int": 29 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff04.webp", + "imageUrl": "/images/base/arcing_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1128,7 +1128,7 @@ "baseStats": { "evasion": 296 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex01.webp", + "imageUrl": "/images/base/armoured_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1149,7 +1149,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Claws/Basetypes/Claw11.webp", + "imageUrl": "/images/base/armoured_claw.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1172,7 +1172,7 @@ "baseStats": { "evasion": 451 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex01.webp", + "imageUrl": "/images/base/armoured_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1195,7 +1195,7 @@ "baseStats": { "spirit": "100" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Scepters/Basetypes/Sceptre01.webp", + "imageUrl": "/images/base/aromatic_sceptre.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1218,7 +1218,7 @@ "baseStats": { "evasion": 126 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler12.webp", + "imageUrl": "/images/base/array_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -1241,7 +1241,7 @@ "baseStats": { "energy_shield": 49 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus06.webp", + "imageUrl": "/images/base/arrayed_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -1262,7 +1262,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow09.webp", + "imageUrl": "/images/base/artillery_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1286,7 +1286,7 @@ "evasion": 197, "energy_shield": 63 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt08.webp", + "imageUrl": "/images/base/ascetic_garb.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1307,7 +1307,7 @@ "int": 67 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/CinderbarkTalisman.webp", + "imageUrl": "/images/base/ashbark_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1328,7 +1328,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Staves/Basetypes/Staff01.webp", + "imageUrl": "/images/base/ashen_staff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1352,7 +1352,7 @@ "evasion": 248, "energy_shield": 76 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt01.webp", + "imageUrl": "/images/base/assassin_garb.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1375,7 +1375,7 @@ "baseStats": { "energy_shield": 51 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus01.webp", + "imageUrl": "/images/base/attuned_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -1396,7 +1396,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Wands/Basetypes/Wand03.webp", + "imageUrl": "/images/base/attuned_wand.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1420,7 +1420,7 @@ "armour": 99, "evasion": 90 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield10.webp", + "imageUrl": "/images/base/aureate_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -1444,7 +1444,7 @@ "evasion": 248, "energy_shield": 76 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt08.webp", + "imageUrl": "/images/base/austere_garb.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1468,7 +1468,7 @@ "evasion": 149, "energy_shield": 46 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt05.webp", + "imageUrl": "/images/base/avian_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1491,7 +1491,7 @@ "baseStats": { "energy_shield": 103 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt02.webp", + "imageUrl": "/images/base/avian_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1515,7 +1515,7 @@ "armour": 107, "evasion": 97 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield06.webp", + "imageUrl": "/images/base/avian_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -1538,7 +1538,7 @@ "baseStats": { "energy_shield": 71 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt02.webp", + "imageUrl": "/images/base/avian_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1559,7 +1559,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/Basetypes/AzureAmulet.webp", + "imageUrl": "/images/base/azure_amulet.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -1583,7 +1583,7 @@ "evasion": 58, "energy_shield": 19 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt01.webp", + "imageUrl": "/images/base/bandage_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -1604,7 +1604,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandAxes/Basetypes/1HAxe05.webp", + "imageUrl": "/images/base/bandit_hatchet.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1625,7 +1625,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace07.webp", + "imageUrl": "/images/base/bandit_mace.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1649,7 +1649,7 @@ "evasion": 122, "energy_shield": 39 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt02.webp", + "imageUrl": "/images/base/bandit_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1672,7 +1672,7 @@ "baseStats": { "energy_shield": 56 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt03.webp", + "imageUrl": "/images/base/bangled_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -1695,7 +1695,7 @@ "baseStats": { "armour": 355 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr02.webp", + "imageUrl": "/images/base/barbarian_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1716,7 +1716,7 @@ "int": 27 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff03.webp", + "imageUrl": "/images/base/barbarous_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1739,7 +1739,7 @@ "baseStats": { "evasion": 163 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex05.webp", + "imageUrl": "/images/base/barbed_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -1760,7 +1760,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear07.webp", + "imageUrl": "/images/base/barbed_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1783,7 +1783,7 @@ "baseStats": { "energy_shield": 39 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt04.webp", + "imageUrl": "/images/base/baroque_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -1807,7 +1807,7 @@ "armour": 123, "evasion": 112 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield04.webp", + "imageUrl": "/images/base/baroque_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -1830,7 +1830,7 @@ "baseStats": { "armour": 62 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower04.webp", + "imageUrl": "/images/base/barricade_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -1851,7 +1851,7 @@ "int": 22 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff08.webp", + "imageUrl": "/images/base/barrier_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1875,7 +1875,7 @@ "armour": 123, "evasion": 111 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex03.webp", + "imageUrl": "/images/base/bastion_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -1896,7 +1896,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandAxes/Basetypes/1HAxe11.webp", + "imageUrl": "/images/base/battle_axe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1917,7 +1917,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace05.webp", + "imageUrl": "/images/base/battle_pick.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1940,7 +1940,7 @@ "baseStats": { "energy_shield": 35 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt03.webp", + "imageUrl": "/images/base/beaded_circlet.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1961,7 +1961,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandAxes/Basetypes/1HAxe03.webp", + "imageUrl": "/images/base/bearded_axe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -1985,7 +1985,7 @@ "armour": 207, "energy_shield": 60 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr02.webp", + "imageUrl": "/images/base/bearskin_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -2006,7 +2006,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/BreachlordRing_Tul.webp", + "imageUrl": "/images/base/biostatic_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2027,7 +2027,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow09.webp", + "imageUrl": "/images/base/blackfire_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -2048,7 +2048,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace03.webp", + "imageUrl": "/images/base/blacksmith_maul.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -2072,7 +2072,7 @@ "armour": 145, "energy_shield": 40 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest07.webp", + "imageUrl": "/images/base/blacksteel_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2096,7 +2096,7 @@ "armour": 103, "evasion": 94 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex04.webp", + "imageUrl": "/images/base/blacksteel_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2120,7 +2120,7 @@ "armour": 154, "evasion": 140 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex04.webp", + "imageUrl": "/images/base/blacksteel_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2143,7 +2143,7 @@ "baseStats": { "armour": 203 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower01.webp", + "imageUrl": "/images/base/blacksteel_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2164,7 +2164,7 @@ "int": 33 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff07.webp", + "imageUrl": "/images/base/bladed_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -2188,7 +2188,7 @@ "evasion": 122, "energy_shield": 37 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt01.webp", + "imageUrl": "/images/base/bladed_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2209,7 +2209,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Traps/Trap04.webp", + "imageUrl": "/images/base/bladed_trap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -2232,7 +2232,7 @@ "baseStats": { "evasion": 139 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler08.webp", + "imageUrl": "/images/base/bladeguard_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2256,7 +2256,7 @@ "armour": 10, "energy_shield": 6 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest01.webp", + "imageUrl": "/images/base/blazon_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2277,7 +2277,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow08.webp", + "imageUrl": "/images/base/bleak_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -2298,7 +2298,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandSwords/Basetypes/2HSword03.webp", + "imageUrl": "/images/base/blessed_claymore.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -2321,7 +2321,7 @@ "baseStats": { "weapon_range": "1" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Daggers/Basetypes/Dagger08.webp", + "imageUrl": "/images/base/bloodletting_dagger.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -2342,7 +2342,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/Basetypes/BloodstoneAmulet.webp", + "imageUrl": "/images/base/bloodstone_amulet.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2363,7 +2363,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Quivers/Basetypes/QuiverBlunt.webp", + "imageUrl": "/images/base/blunt_quiver.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2384,7 +2384,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandAxes/Basetypes/1HAxe09.webp", + "imageUrl": "/images/base/boarding_hatchet.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -2408,7 +2408,7 @@ "armour": 134, "evasion": 122 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex06.webp", + "imageUrl": "/images/base/bold_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2431,7 +2431,7 @@ "baseStats": { "armour": 75 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr04.webp", + "imageUrl": "/images/base/bolstered_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2452,7 +2452,7 @@ "int": 50 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff04.webp", + "imageUrl": "/images/base/bolting_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -2473,7 +2473,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow07.webp", + "imageUrl": "/images/base/bombard_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -2496,7 +2496,7 @@ "baseStats": { "energy_shield": 54 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt04.webp", + "imageUrl": "/images/base/bone_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -2517,7 +2517,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Wands/Basetypes/Wand02.webp", + "imageUrl": "/images/base/bone_wand.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -2540,7 +2540,7 @@ "baseStats": { "evasion": 157 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex02.webp", + "imageUrl": "/images/base/bound_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2563,7 +2563,7 @@ "baseStats": { "evasion": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex03.webp", + "imageUrl": "/images/base/bound_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2587,7 +2587,7 @@ "armour": 89, "energy_shield": 25 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr01.webp", + "imageUrl": "/images/base/bound_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2611,7 +2611,7 @@ "armour": 107, "energy_shield": 31 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr02.webp", + "imageUrl": "/images/base/bound_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2634,7 +2634,7 @@ "baseStats": { "energy_shield": 68 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt02.webp", + "imageUrl": "/images/base/bound_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2658,7 +2658,7 @@ "armour": 41, "evasion": 35 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex02.webp", + "imageUrl": "/images/base/braced_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2681,7 +2681,7 @@ "baseStats": { "armour": 50 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower03.webp", + "imageUrl": "/images/base/braced_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2705,7 +2705,7 @@ "armour": 64, "energy_shield": 19 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr01.webp", + "imageUrl": "/images/base/braided_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2726,7 +2726,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear06.webp", + "imageUrl": "/images/base/branched_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -2747,7 +2747,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/Basetypes/BreachRing.webp", + "imageUrl": "/images/base/breach_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2768,7 +2768,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/breach_tablet.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -2789,7 +2789,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace07.webp", + "imageUrl": "/images/base/brigand_mace.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -2813,7 +2813,7 @@ "evasion": 163, "energy_shield": 50 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt02.webp", + "imageUrl": "/images/base/brigand_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -2837,7 +2837,7 @@ "armour": 26, "evasion": 20 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex01.webp", + "imageUrl": "/images/base/brimmed_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -2858,7 +2858,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandSwords/Basetypes/2HSword04.webp", + "imageUrl": "/images/base/broad_greatsword.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -2879,7 +2879,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear08.webp", + "imageUrl": "/images/base/broad_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -2900,7 +2900,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Quivers/Basetypes/QuiverBroadhead.webp", + "imageUrl": "/images/base/broadhead_quiver.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2921,7 +2921,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSwords/Basetypes/1HSword02.webp", + "imageUrl": "/images/base/broadsword.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -2944,7 +2944,7 @@ "baseStats": { "armour": 74 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr03.webp", + "imageUrl": "/images/base/bronze_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2968,7 +2968,7 @@ "evasion": 58, "energy_shield": 19 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt04.webp", + "imageUrl": "/images/base/buckled_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -2991,7 +2991,7 @@ "baseStats": { "armour": 244 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr02.webp", + "imageUrl": "/images/base/bulwark_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -3014,7 +3014,7 @@ "baseStats": { "armour": 171 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower06.webp", + "imageUrl": "/images/base/bulwark_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -3038,7 +3038,7 @@ "armour": 73, "evasion": 66 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex01.webp", + "imageUrl": "/images/base/burnished_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -3062,7 +3062,7 @@ "armour": 151, "evasion": 137 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex04.webp", + "imageUrl": "/images/base/cabalist_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3083,7 +3083,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace02.webp", + "imageUrl": "/images/base/calescent_hammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3107,7 +3107,7 @@ "evasion": 65, "energy_shield": 21 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt02.webp", + "imageUrl": "/images/base/cambric_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -3128,7 +3128,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow07.webp", + "imageUrl": "/images/base/cannonade_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3152,7 +3152,7 @@ "armour": 72, "evasion": 65 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex02.webp", + "imageUrl": "/images/base/captain_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -3175,7 +3175,7 @@ "baseStats": { "armour": 223 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr05.webp", + "imageUrl": "/images/base/carved_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -3199,7 +3199,7 @@ "armour": 89, "evasion": 81 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield08.webp", + "imageUrl": "/images/base/carved_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -3220,7 +3220,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandAxes/Basetypes/1HAxe07.webp", + "imageUrl": "/images/base/carving_hatchet.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3244,7 +3244,7 @@ "armour": 163, "evasion": 149 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex05.webp", + "imageUrl": "/images/base/cassis_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3267,7 +3267,7 @@ "baseStats": { "evasion": 233 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex04.webp", + "imageUrl": "/images/base/cavalry_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -3288,7 +3288,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow05.webp", + "imageUrl": "/images/base/cavalry_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3309,7 +3309,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandAxes/Basetypes/2HAxe11.webp", + "imageUrl": "/images/base/ceremonial_halberd.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3332,7 +3332,7 @@ "baseStats": { "energy_shield": 132 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt08.webp", + "imageUrl": "/images/base/ceremonial_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3353,7 +3353,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Flails/Flail02.webp", + "imageUrl": "/images/base/chain_flail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3377,7 +3377,7 @@ "armour": 25, "evasion": 16 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex01.webp", + "imageUrl": "/images/base/chain_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3400,7 +3400,7 @@ "baseStats": { "energy_shield": 47 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt04.webp", + "imageUrl": "/images/base/chain_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3424,7 +3424,7 @@ "armour": 218, "energy_shield": 63 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr03.webp", + "imageUrl": "/images/base/chain_vestments.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3447,7 +3447,7 @@ "baseStats": { "armour": 446 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr01.webp", + "imageUrl": "/images/base/champion_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3471,7 +3471,7 @@ "armour": 197, "evasion": 179 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex05.webp", + "imageUrl": "/images/base/champion_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3492,7 +3492,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/ChangelingTalisman.webp", + "imageUrl": "/images/base/changeling_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3516,7 +3516,7 @@ "evasion": 128, "energy_shield": 39 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt02.webp", + "imageUrl": "/images/base/charmed_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -3537,7 +3537,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSwords/Basetypes/1HSword05.webp", + "imageUrl": "/images/base/charred_shortsword.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3560,7 +3560,7 @@ "baseStats": { "armour": 390 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr10.webp", + "imageUrl": "/images/base/chieftain_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3581,7 +3581,7 @@ "int": 46 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Staves/Basetypes/Staff06.webp", + "imageUrl": "/images/base/chiming_staff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3605,7 +3605,7 @@ "armour": 61, "evasion": 54 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield05.webp", + "imageUrl": "/images/base/chiseled_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -3628,7 +3628,7 @@ "baseStats": { "evasion": 222 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex02.webp", + "imageUrl": "/images/base/cinched_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -3649,7 +3649,7 @@ "int": 11 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/CinderbarkTalisman.webp", + "imageUrl": "/images/base/cinderbark_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3672,7 +3672,7 @@ "baseStats": { "weapon_range": "1" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Daggers/Basetypes/Dagger13.webp", + "imageUrl": "/images/base/cinquedea.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3693,7 +3693,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Traps/Trap02.webp", + "imageUrl": "/images/base/clamping_trap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3717,7 +3717,7 @@ "evasion": 201, "energy_shield": 63 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt09.webp", + "imageUrl": "/images/base/clandestine_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3740,7 +3740,7 @@ "baseStats": { "spirit": "100" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Scepters/Basetypes/Sceptre08.webp", + "imageUrl": "/images/base/clasped_sceptre.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3761,7 +3761,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Traps/Trap01.webp", + "imageUrl": "/images/base/clay_trap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3782,7 +3782,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Charms/Basetypes/AmethystCharm.webp", + "imageUrl": "/images/base/cleansing_charm.webp", "affixSlots": { "prefix": 0, "suffix": 0 @@ -3806,7 +3806,7 @@ "armour": 195, "energy_shield": 57 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr07.webp", + "imageUrl": "/images/base/cleric_vestments.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3830,7 +3830,7 @@ "armour": 121, "evasion": 107 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex04.webp", + "imageUrl": "/images/base/cloaked_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3854,7 +3854,7 @@ "armour": 128, "evasion": 115 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex06.webp", + "imageUrl": "/images/base/closed_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3875,7 +3875,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/coffer_relic.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -3898,7 +3898,7 @@ "baseStats": { "evasion": 118 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler05.webp", + "imageUrl": "/images/base/coiled_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -3919,7 +3919,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Traps/TrapRemote04.webp", + "imageUrl": "/images/base/coiled_trap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -3940,7 +3940,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Flasks/Basetypes/FlaskLife06.webp", + "imageUrl": "/images/base/colossal_life_flask.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -3961,7 +3961,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Flasks/Basetypes/FlaskMana06.webp", + "imageUrl": "/images/base/colossal_mana_flask.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -3984,7 +3984,7 @@ "baseStats": { "armour": 404 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr01.webp", + "imageUrl": "/images/base/colosseum_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4008,7 +4008,7 @@ "armour": 94, "evasion": 85 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex02.webp", + "imageUrl": "/images/base/commander_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -4031,7 +4031,7 @@ "baseStats": { "armour": 233 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr07.webp", + "imageUrl": "/images/base/commander_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4052,7 +4052,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSwords/Basetypes/1HSword12.webp", + "imageUrl": "/images/base/commander_sword.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4073,7 +4073,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow05.webp", + "imageUrl": "/images/base/composite_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4094,7 +4094,7 @@ "int": 52 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/CondemnedTalisman.webp", + "imageUrl": "/images/base/condemned_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4118,7 +4118,7 @@ "armour": 273, "energy_shield": 76 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr04.webp", + "imageUrl": "/images/base/conjurer_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4141,7 +4141,7 @@ "baseStats": { "armour": 496 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr01.webp", + "imageUrl": "/images/base/conqueror_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4162,7 +4162,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow08.webp", + "imageUrl": "/images/base/construct_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4183,7 +4183,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace08.webp", + "imageUrl": "/images/base/construct_hammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4204,7 +4204,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/Basetypes/CoronaAmulet.webp", + "imageUrl": "/images/base/corona_amulet.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -4227,7 +4227,7 @@ "baseStats": { "armour": 233 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr01.webp", + "imageUrl": "/images/base/corroded_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4248,7 +4248,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandSwords/Basetypes/2HSword01.webp", + "imageUrl": "/images/base/corroded_longsword.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4271,7 +4271,7 @@ "baseStats": { "evasion": 210 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex07.webp", + "imageUrl": "/images/base/corsair_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4294,7 +4294,7 @@ "baseStats": { "evasion": 451 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex10.webp", + "imageUrl": "/images/base/corsair_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4317,7 +4317,7 @@ "baseStats": { "evasion": 320 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex09.webp", + "imageUrl": "/images/base/corsair_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4341,7 +4341,7 @@ "armour": 273, "energy_shield": 76 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr12.webp", + "imageUrl": "/images/base/corvus_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4362,7 +4362,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear03.webp", + "imageUrl": "/images/base/coursing_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4386,7 +4386,7 @@ "armour": 96, "evasion": 86 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex04.webp", + "imageUrl": "/images/base/covered_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -4409,7 +4409,7 @@ "baseStats": { "evasion": 257 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex10.webp", + "imageUrl": "/images/base/covert_hood.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4433,7 +4433,7 @@ "armour": 80, "evasion": 70 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex04.webp", + "imageUrl": "/images/base/cowled_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4454,7 +4454,7 @@ "int": 12 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff04.webp", + "imageUrl": "/images/base/crackling_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4475,7 +4475,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandAxes/Basetypes/1HAxe06.webp", + "imageUrl": "/images/base/crescent_axe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4496,7 +4496,7 @@ "int": 14 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff05.webp", + "imageUrl": "/images/base/crescent_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4520,7 +4520,7 @@ "armour": 50, "evasion": 44 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield04.webp", + "imageUrl": "/images/base/crescent_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -4541,7 +4541,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/Basetypes/CrimsonAmulet.webp", + "imageUrl": "/images/base/crimson_amulet.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -4562,7 +4562,7 @@ "int": 92 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Wands/Basetypes/Wand11.webp", + "imageUrl": "/images/base/critical_wand.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4585,7 +4585,7 @@ "baseStats": { "weapon_range": "1" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Daggers/Basetypes/Dagger02.webp", + "imageUrl": "/images/base/crone_knife.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4606,7 +4606,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear09.webp", + "imageUrl": "/images/base/crossblade_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4627,7 +4627,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace06.webp", + "imageUrl": "/images/base/crown_mace.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4650,7 +4650,7 @@ "baseStats": { "armour": 145 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower09.webp", + "imageUrl": "/images/base/crucible_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -4671,7 +4671,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow01.webp", + "imageUrl": "/images/base/crude_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4692,7 +4692,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Claws/Basetypes/Claw01.webp", + "imageUrl": "/images/base/crude_claw.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4713,7 +4713,7 @@ "int": 51 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/ViciousTalisman.webp", + "imageUrl": "/images/base/cruel_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4734,7 +4734,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace08.webp", + "imageUrl": "/images/base/crumbling_maul.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4758,7 +4758,7 @@ "armour": 206, "energy_shield": 57 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr06.webp", + "imageUrl": "/images/base/cryptic_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4782,7 +4782,7 @@ "armour": 188, "evasion": 171 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex04.webp", + "imageUrl": "/images/base/cryptic_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4806,7 +4806,7 @@ "armour": 134, "energy_shield": 37 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr04.webp", + "imageUrl": "/images/base/cryptic_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -4829,7 +4829,7 @@ "baseStats": { "energy_shield": 29 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus06.webp", + "imageUrl": "/images/base/crystal_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -4850,7 +4850,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow07.webp", + "imageUrl": "/images/base/cultist_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4874,7 +4874,7 @@ "armour": 54, "energy_shield": 19 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr03.webp", + "imageUrl": "/images/base/cultist_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4897,7 +4897,7 @@ "baseStats": { "energy_shield": 52 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus07.webp", + "imageUrl": "/images/base/cultist_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -4921,7 +4921,7 @@ "armour": 98, "evasion": 90 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex03.webp", + "imageUrl": "/images/base/cultist_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -4942,7 +4942,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace05.webp", + "imageUrl": "/images/base/cultist_greathammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -4965,7 +4965,7 @@ "baseStats": { "armour": 163 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower05.webp", + "imageUrl": "/images/base/cultist_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -4986,7 +4986,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow04.webp", + "imageUrl": "/images/base/cumbrous_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5009,7 +5009,7 @@ "baseStats": { "energy_shield": 109 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt03.webp", + "imageUrl": "/images/base/cursespeakers_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5030,7 +5030,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSwords/Basetypes/1HSword09.webp", + "imageUrl": "/images/base/cutlass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5054,7 +5054,7 @@ "evasion": 140, "energy_shield": 43 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt04.webp", + "imageUrl": "/images/base/daggerfoot_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -5075,7 +5075,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSwords/Basetypes/1HSword13.webp", + "imageUrl": "/images/base/dark_blade.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5096,7 +5096,7 @@ "int": 114 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Staves/Basetypes/Staff13.webp", + "imageUrl": "/images/base/dark_staff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5117,7 +5117,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Traps/TrapRemote03.webp", + "imageUrl": "/images/base/dart_trap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5141,7 +5141,7 @@ "armour": 303, "evasion": 276 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex02.webp", + "imageUrl": "/images/base/dastard_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5165,7 +5165,7 @@ "armour": 313, "evasion": 285 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex06.webp", + "imageUrl": "/images/base/death_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5189,7 +5189,7 @@ "armour": 273, "energy_shield": 76 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr06.webp", + "imageUrl": "/images/base/death_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5213,7 +5213,7 @@ "evasion": 163, "energy_shield": 50 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt08.webp", + "imageUrl": "/images/base/death_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5237,7 +5237,7 @@ "armour": 146, "evasion": 132 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex07.webp", + "imageUrl": "/images/base/decorated_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5258,7 +5258,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow04.webp", + "imageUrl": "/images/base/dedalian_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5281,7 +5281,7 @@ "baseStats": { "evasion": 270 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex05.webp", + "imageUrl": "/images/base/deerstalker_hood.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5304,7 +5304,7 @@ "baseStats": { "armour": 183 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower01.webp", + "imageUrl": "/images/base/defiant_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -5328,7 +5328,7 @@ "armour": 112, "energy_shield": 31 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest01.webp", + "imageUrl": "/images/base/deified_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -5352,7 +5352,7 @@ "armour": 94, "energy_shield": 27 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest04.webp", + "imageUrl": "/images/base/dekharan_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -5373,7 +5373,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/delirium_tablet.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -5397,7 +5397,7 @@ "armour": 89, "energy_shield": 26 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest03.webp", + "imageUrl": "/images/base/descry_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -5420,7 +5420,7 @@ "baseStats": { "evasion": 192 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler09.webp", + "imageUrl": "/images/base/desert_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -5443,7 +5443,7 @@ "baseStats": { "evasion": 311 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex04.webp", + "imageUrl": "/images/base/desert_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5466,7 +5466,7 @@ "baseStats": { "energy_shield": 75 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt03.webp", + "imageUrl": "/images/base/desert_circlet.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5487,7 +5487,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow08.webp", + "imageUrl": "/images/base/desolate_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5510,7 +5510,7 @@ "baseStats": { "armour": 116 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr06.webp", + "imageUrl": "/images/base/detailed_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -5533,7 +5533,7 @@ "baseStats": { "spirit": "100" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Scepters/Basetypes/Sceptre09.webp", + "imageUrl": "/images/base/devotional_sceptre.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5556,7 +5556,7 @@ "baseStats": { "spirit": "100" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Scepters/Basetypes/Sceptre07.webp", + "imageUrl": "/images/base/devouring_sceptre.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5580,7 +5580,7 @@ "evasion": 248, "energy_shield": 76 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt01.webp", + "imageUrl": "/images/base/devout_garb.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5601,7 +5601,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/diamond.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5622,7 +5622,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace08.webp", + "imageUrl": "/images/base/disintegrating_maul.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5643,7 +5643,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/Basetypes/DistortedAmulet.webp", + "imageUrl": "/images/base/distorted_amulet.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -5667,7 +5667,7 @@ "armour": 197, "energy_shield": 55 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr05.webp", + "imageUrl": "/images/base/divine_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5691,7 +5691,7 @@ "armour": 128, "evasion": 115 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex01.webp", + "imageUrl": "/images/base/domed_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5712,7 +5712,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Belts/Basetypes/Belt08.webp", + "imageUrl": "/images/base/double_belt.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -5733,7 +5733,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow12.webp", + "imageUrl": "/images/base/double_limb_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5757,7 +5757,7 @@ "armour": 49, "evasion": 43 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex03.webp", + "imageUrl": "/images/base/doubled_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -5778,7 +5778,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Charms/Basetypes/DousingCharm.webp", + "imageUrl": "/images/base/dousing_charm.webp", "affixSlots": { "prefix": 0, "suffix": 0 @@ -5801,7 +5801,7 @@ "baseStats": { "evasion": 244 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex05.webp", + "imageUrl": "/images/base/dragonscale_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -5824,7 +5824,7 @@ "baseStats": { "evasion": 255 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex06.webp", + "imageUrl": "/images/base/drakeskin_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -5845,7 +5845,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandAxes/Basetypes/1HAxe13.webp", + "imageUrl": "/images/base/dread_hatchet.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5866,7 +5866,7 @@ "int": 50 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff10.webp", + "imageUrl": "/images/base/dreaming_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5889,7 +5889,7 @@ "baseStats": { "energy_shield": 68 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt01.webp", + "imageUrl": "/images/base/druidic_circlet.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5913,7 +5913,7 @@ "armour": 179, "energy_shield": 50 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr02.webp", + "imageUrl": "/images/base/druidic_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5936,7 +5936,7 @@ "baseStats": { "energy_shield": 62 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus03.webp", + "imageUrl": "/images/base/druidic_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -5957,7 +5957,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow06.webp", + "imageUrl": "/images/base/dualstring_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5978,7 +5978,7 @@ "int": 114 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Wands/Basetypes/Wand13.webp", + "imageUrl": "/images/base/dueling_wand.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -5999,7 +5999,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandAxes/Basetypes/1HAxe01.webp", + "imageUrl": "/images/base/dull_hatchet.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -6022,7 +6022,7 @@ "baseStats": { "energy_shield": 63 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt05.webp", + "imageUrl": "/images/base/dunerunner_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -6043,7 +6043,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/HeistAmulet1.webp", + "imageUrl": "/images/base/dusk_amulet.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -6064,7 +6064,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/LakeRing1.webp", + "imageUrl": "/images/base/dusk_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -6085,7 +6085,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow05.webp", + "imageUrl": "/images/base/dyad_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -6108,7 +6108,7 @@ "baseStats": { "evasion": 92 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler08.webp", + "imageUrl": "/images/base/edged_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -6129,7 +6129,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Claws/Basetypes/Claw06.webp", + "imageUrl": "/images/base/edged_claw.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -6152,7 +6152,7 @@ "baseStats": { "armour": 76 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower05.webp", + "imageUrl": "/images/base/effigial_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -6175,7 +6175,7 @@ "baseStats": { "energy_shield": 68 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt01.webp", + "imageUrl": "/images/base/elaborate_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -6196,7 +6196,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow10.webp", + "imageUrl": "/images/base/elegant_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -6219,7 +6219,7 @@ "baseStats": { "energy_shield": 47 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus01.webp", + "imageUrl": "/images/base/elegant_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -6240,7 +6240,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandAxes/Basetypes/2HAxe05.webp", + "imageUrl": "/images/base/elegant_glaive.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -6263,7 +6263,7 @@ "baseStats": { "armour": 274 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr04.webp", + "imageUrl": "/images/base/elegant_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -6286,7 +6286,7 @@ "baseStats": { "armour": 206 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr04.webp", + "imageUrl": "/images/base/elegant_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -6309,7 +6309,7 @@ "baseStats": { "armour": 130 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr03.webp", + "imageUrl": "/images/base/elegant_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -6332,7 +6332,7 @@ "baseStats": { "armour": 418 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr06.webp", + "imageUrl": "/images/base/elegant_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -6355,7 +6355,7 @@ "baseStats": { "energy_shield": 58 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt04.webp", + "imageUrl": "/images/base/elegant_slippers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -6379,7 +6379,7 @@ "evasion": 85, "energy_shield": 26 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt02.webp", + "imageUrl": "/images/base/elegant_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -6402,7 +6402,7 @@ "baseStats": { "energy_shield": 103 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt09.webp", + "imageUrl": "/images/base/elementalist_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -6425,7 +6425,7 @@ "baseStats": { "armour": 177 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr05.webp", + "imageUrl": "/images/base/elite_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -6448,7 +6448,7 @@ "baseStats": { "energy_shield": 37 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt03.webp", + "imageUrl": "/images/base/embellished_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -6469,7 +6469,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandAxes/Basetypes/2HAxe10.webp", + "imageUrl": "/images/base/ember_greataxe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -6493,7 +6493,7 @@ "armour": 34, "energy_shield": 12 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest03.webp", + "imageUrl": "/images/base/emblem_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -6516,7 +6516,7 @@ "baseStats": { "evasion": 63 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex03.webp", + "imageUrl": "/images/base/embossed_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -6539,7 +6539,7 @@ "baseStats": { "evasion": 222 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex01.webp", + "imageUrl": "/images/base/embroidered_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -6562,7 +6562,7 @@ "baseStats": { "energy_shield": 38 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt07.webp", + "imageUrl": "/images/base/embroidered_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -6583,7 +6583,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/emerald.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -6604,7 +6604,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/Basetypes/EmeraldRing.webp", + "imageUrl": "/images/base/emerald_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -6628,7 +6628,7 @@ "armour": 99, "energy_shield": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest01.webp", + "imageUrl": "/images/base/empyreal_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -6649,7 +6649,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSwords/OneHandSwordStormBlade.webp", + "imageUrl": "/images/base/energy_blade.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -6672,7 +6672,7 @@ "baseStats": { "evasion": 148 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex01.webp", + "imageUrl": "/images/base/engraved_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -6696,7 +6696,7 @@ "armour": 85, "energy_shield": 24 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest02.webp", + "imageUrl": "/images/base/engraved_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -6717,7 +6717,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow04.webp", + "imageUrl": "/images/base/engraved_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -6740,7 +6740,7 @@ "baseStats": { "energy_shield": 22 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus04.webp", + "imageUrl": "/images/base/engraved_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -6764,7 +6764,7 @@ "armour": 136, "evasion": 122 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex02.webp", + "imageUrl": "/images/base/engraved_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -6787,7 +6787,7 @@ "baseStats": { "weapon_range": "1" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Daggers/Basetypes/Dagger06.webp", + "imageUrl": "/images/base/engraved_knife.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -6810,7 +6810,7 @@ "baseStats": { "energy_shield": 138 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt01.webp", + "imageUrl": "/images/base/enlightened_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -6831,7 +6831,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow04.webp", + "imageUrl": "/images/base/esoteric_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -6854,7 +6854,7 @@ "baseStats": { "weapon_range": "1" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Daggers/Dagger1.webp", + "imageUrl": "/images/base/ethereal_blade.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -6878,7 +6878,7 @@ "evasion": 197, "energy_shield": 63 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt03.webp", + "imageUrl": "/images/base/evangelist_garb.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -6899,7 +6899,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace01.webp", + "imageUrl": "/images/base/execratus_hammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -6920,7 +6920,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandAxes/Basetypes/2HAxe03.webp", + "imageUrl": "/images/base/executioner_greataxe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -6941,7 +6941,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/expedition_tablet.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -6965,7 +6965,7 @@ "armour": 149, "evasion": 132 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex05.webp", + "imageUrl": "/images/base/explorer_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -6988,7 +6988,7 @@ "baseStats": { "evasion": 451 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex13.webp", + "imageUrl": "/images/base/exquisite_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7009,7 +7009,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandAxes/Basetypes/1HAxe04.webp", + "imageUrl": "/images/base/extended_cleaver.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7033,7 +7033,7 @@ "evasion": 32, "energy_shield": 16 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt02.webp", + "imageUrl": "/images/base/face_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7057,7 +7057,7 @@ "armour": 134, "energy_shield": 37 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr01.webp", + "imageUrl": "/images/base/faithful_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -7078,7 +7078,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSwords/Basetypes/1HSword07.webp", + "imageUrl": "/images/base/falchion.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7102,7 +7102,7 @@ "evasion": 248, "energy_shield": 76 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt06.webp", + "imageUrl": "/images/base/falconers_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7123,7 +7123,7 @@ "int": 16 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/FamilialTalisman.webp", + "imageUrl": "/images/base/familial_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7144,7 +7144,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow07.webp", + "imageUrl": "/images/base/fanatic_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7165,7 +7165,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace05.webp", + "imageUrl": "/images/base/fanatic_greathammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7186,7 +7186,7 @@ "int": 68 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/FamilialTalisman.webp", + "imageUrl": "/images/base/fang_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7210,7 +7210,7 @@ "evasion": 171, "energy_shield": 52 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt04.webp", + "imageUrl": "/images/base/faridun_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7233,7 +7233,7 @@ "baseStats": { "armour": 149 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr05.webp", + "imageUrl": "/images/base/feathered_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -7256,7 +7256,7 @@ "baseStats": { "energy_shield": 153 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt10.webp", + "imageUrl": "/images/base/feathered_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7279,7 +7279,7 @@ "baseStats": { "energy_shield": 35 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt02.webp", + "imageUrl": "/images/base/feathered_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7302,7 +7302,7 @@ "baseStats": { "energy_shield": 41 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt05.webp", + "imageUrl": "/images/base/feathered_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -7326,7 +7326,7 @@ "armour": 67, "evasion": 60 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield06.webp", + "imageUrl": "/images/base/feathered_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -7349,7 +7349,7 @@ "baseStats": { "energy_shield": 54 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt05.webp", + "imageUrl": "/images/base/feathered_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7370,7 +7370,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace01.webp", + "imageUrl": "/images/base/felled_greatclub.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7393,7 +7393,7 @@ "baseStats": { "evasion": 58 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex02.webp", + "imageUrl": "/images/base/felt_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7416,7 +7416,7 @@ "baseStats": { "armour": 260 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr08.webp", + "imageUrl": "/images/base/fierce_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7437,7 +7437,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Belts/Basetypes/Belt11.webp", + "imageUrl": "/images/base/fine_belt.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -7460,7 +7460,7 @@ "baseStats": { "evasion": 105 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex06.webp", + "imageUrl": "/images/base/fine_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -7481,7 +7481,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Quivers/Basetypes/QuiverFire.webp", + "imageUrl": "/images/base/fire_quiver.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -7504,7 +7504,7 @@ "baseStats": { "evasion": 31 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex02.webp", + "imageUrl": "/images/base/firm_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -7525,7 +7525,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandSwords/Basetypes/2HSword11.webp", + "imageUrl": "/images/base/flanged_greatblade.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7546,7 +7546,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace03.webp", + "imageUrl": "/images/base/flanged_mace.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7569,7 +7569,7 @@ "baseStats": { "evasion": 157 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex06.webp", + "imageUrl": "/images/base/flared_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -7590,7 +7590,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace03.webp", + "imageUrl": "/images/base/flared_mace.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7613,7 +7613,7 @@ "baseStats": { "energy_shield": 51 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt06.webp", + "imageUrl": "/images/base/flax_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -7634,7 +7634,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow02.webp", + "imageUrl": "/images/base/flexed_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7658,7 +7658,7 @@ "armour": 109, "evasion": 99 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex01.webp", + "imageUrl": "/images/base/flexile_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -7681,7 +7681,7 @@ "baseStats": { "energy_shield": 153 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt06.webp", + "imageUrl": "/images/base/flowing_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7702,7 +7702,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear05.webp", + "imageUrl": "/images/base/flying_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7726,7 +7726,7 @@ "armour": 136, "energy_shield": 39 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr02.webp", + "imageUrl": "/images/base/forest_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7747,7 +7747,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace03.webp", + "imageUrl": "/images/base/forge_maul.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7768,7 +7768,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Claws/Basetypes/Claw04.webp", + "imageUrl": "/images/base/forked_claw.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7789,7 +7789,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear06.webp", + "imageUrl": "/images/base/forked_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7810,7 +7810,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Belts/Basetypes/ForkingBelt.webp", + "imageUrl": "/images/base/forking_belt.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -7831,7 +7831,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace08.webp", + "imageUrl": "/images/base/fortified_hammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7855,7 +7855,7 @@ "armour": 147, "evasion": 134 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex03.webp", + "imageUrl": "/images/base/fortress_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -7878,7 +7878,7 @@ "baseStats": { "armour": 223 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower06.webp", + "imageUrl": "/images/base/fortress_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -7902,7 +7902,7 @@ "evasion": 15, "energy_shield": 10 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt01.webp", + "imageUrl": "/images/base/frayed_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -7925,7 +7925,7 @@ "baseStats": { "evasion": 340 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex07.webp", + "imageUrl": "/images/base/freebooter_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7946,7 +7946,7 @@ "int": 20 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/FrenziedTalisman.webp", + "imageUrl": "/images/base/frenzied_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7967,7 +7967,7 @@ "int": 80 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Wands/Basetypes/Wand10.webp", + "imageUrl": "/images/base/frigid_wand.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -7990,7 +7990,7 @@ "baseStats": { "armour": 270 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr07.webp", + "imageUrl": "/images/base/full_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -8011,7 +8011,7 @@ "int": 70 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/FrenziedTalisman.webp", + "imageUrl": "/images/base/fungal_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -8034,7 +8034,7 @@ "baseStats": { "armour": 66 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr02.webp", + "imageUrl": "/images/base/fur_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -8058,7 +8058,7 @@ "armour": 85, "evasion": 76 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield02.webp", + "imageUrl": "/images/base/fur_lined_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -8082,7 +8082,7 @@ "evasion": 66, "energy_shield": 21 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt01.webp", + "imageUrl": "/images/base/furtive_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -8103,7 +8103,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandAxes/Basetypes/1HAxe10.webp", + "imageUrl": "/images/base/fury_cleaver.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -8124,7 +8124,7 @@ "int": 48 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/RabidTalisman.webp", + "imageUrl": "/images/base/fury_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -8148,7 +8148,7 @@ "armour": 179, "evasion": 163 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex08.webp", + "imageUrl": "/images/base/gallant_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -8169,7 +8169,7 @@ "int": 46 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Wands/Basetypes/Wand06.webp", + "imageUrl": "/images/base/galvanic_wand.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -8190,7 +8190,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Flasks/Basetypes/FlaskLife07.webp", + "imageUrl": "/images/base/gargantuan_life_flask.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -8211,7 +8211,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Flasks/Basetypes/FlaskMana07.webp", + "imageUrl": "/images/base/gargantuan_mana_flask.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -8235,7 +8235,7 @@ "evasion": 9, "energy_shield": 6 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt01.webp", + "imageUrl": "/images/base/gauze_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -8256,7 +8256,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Staves/Basetypes/Staff02.webp", + "imageUrl": "/images/base/gelid_staff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -8277,7 +8277,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow06.webp", + "imageUrl": "/images/base/gemini_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -8298,7 +8298,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow05.webp", + "imageUrl": "/images/base/gemini_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -8319,7 +8319,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Flasks/Basetypes/FlaskLife05.webp", + "imageUrl": "/images/base/giant_life_flask.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -8340,7 +8340,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Flasks/Basetypes/FlaskMana05.webp", + "imageUrl": "/images/base/giant_mana_flask.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -8361,7 +8361,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace13.webp", + "imageUrl": "/images/base/giant_maul.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -8385,7 +8385,7 @@ "armour": 222, "energy_shield": 63 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr09.webp", + "imageUrl": "/images/base/gilded_vestments.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -8409,7 +8409,7 @@ "armour": 109, "energy_shield": 31 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr01.webp", + "imageUrl": "/images/base/gilt_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -8432,7 +8432,7 @@ "baseStats": { "armour": 223 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower06.webp", + "imageUrl": "/images/base/glacial_fortress.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -8456,7 +8456,7 @@ "armour": 245, "evasion": 223 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex01.webp", + "imageUrl": "/images/base/gladiator_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -8480,7 +8480,7 @@ "armour": 206, "evasion": 187 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex06.webp", + "imageUrl": "/images/base/gladiatorial_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -8503,7 +8503,7 @@ "baseStats": { "weapon_range": "1" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Daggers/Basetypes/Dagger01.webp", + "imageUrl": "/images/base/glass_shank.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -8527,7 +8527,7 @@ "armour": 94, "energy_shield": 26 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr03.webp", + "imageUrl": "/images/base/gleaming_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -8548,7 +8548,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/HeistAmulet1.webp", + "imageUrl": "/images/base/gloam_amulet.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -8569,7 +8569,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/LakeRing2.webp", + "imageUrl": "/images/base/gloam_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -8592,7 +8592,7 @@ "baseStats": { "armour": 496 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr01.webp", + "imageUrl": "/images/base/glorious_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -8616,7 +8616,7 @@ "armour": 107, "energy_shield": 30 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest06.webp", + "imageUrl": "/images/base/glowering_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -8637,7 +8637,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/Basetypes/GoldAmulet.webp", + "imageUrl": "/images/base/gold_amulet.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -8660,7 +8660,7 @@ "baseStats": { "energy_shield": 62 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt06.webp", + "imageUrl": "/images/base/gold_circlet.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -8683,7 +8683,7 @@ "baseStats": { "energy_shield": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt05.webp", + "imageUrl": "/images/base/gold_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -8704,7 +8704,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/Basetypes/GoldRing.webp", + "imageUrl": "/images/base/gold_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -8728,7 +8728,7 @@ "armour": 49, "energy_shield": 15 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr03.webp", + "imageUrl": "/images/base/goldcast_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -8749,7 +8749,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSwords/DemigodsAuthority.webp", + "imageUrl": "/images/base/golden_blade.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -8770,7 +8770,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Charms/Basetypes/GoldenCharm.webp", + "imageUrl": "/images/base/golden_charm.webp", "affixSlots": { "prefix": 0, "suffix": 0 @@ -8791,7 +8791,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/DemigodsBand.webp", + "imageUrl": "/images/base/golden_hoop.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -8815,7 +8815,7 @@ "armour": 261, "evasion": 237 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex06.webp", + "imageUrl": "/images/base/golden_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -8840,7 +8840,7 @@ "evasion": 187, "energy_shield": 74 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/DemigodsArmour.webp", + "imageUrl": "/images/base/golden_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -8861,7 +8861,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Belts/Demibelt1.webp", + "imageUrl": "/images/base/golden_obi.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -8885,7 +8885,7 @@ "armour": 145, "evasion": 132 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield10.webp", + "imageUrl": "/images/base/golden_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -8909,7 +8909,7 @@ "armour": 107, "evasion": 97 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex02.webp", + "imageUrl": "/images/base/goldwork_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -8932,7 +8932,7 @@ "baseStats": { "armour": 192 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower08.webp", + "imageUrl": "/images/base/goldworked_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -8955,7 +8955,7 @@ "baseStats": { "armour": 288 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr10.webp", + "imageUrl": "/images/base/goliath_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -8976,7 +8976,7 @@ "int": 9 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff03.webp", + "imageUrl": "/images/base/gothic_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -8997,7 +8997,7 @@ "int": 31 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff01.webp", + "imageUrl": "/images/base/graceful_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9020,7 +9020,7 @@ "baseStats": { "evasion": 155 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex04.webp", + "imageUrl": "/images/base/grand_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -9041,7 +9041,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Flasks/Basetypes/FlaskLife04.webp", + "imageUrl": "/images/base/grand_life_flask.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -9062,7 +9062,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Flasks/Basetypes/FlaskMana04.webp", + "imageUrl": "/images/base/grand_mana_flask.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -9085,7 +9085,7 @@ "baseStats": { "armour": 162 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr01.webp", + "imageUrl": "/images/base/grand_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -9110,7 +9110,7 @@ "evasion": 165, "energy_shield": 50 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr01.webp", + "imageUrl": "/images/base/grand_regalia.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9131,7 +9131,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear08.webp", + "imageUrl": "/images/base/grand_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9155,7 +9155,7 @@ "armour": 112, "evasion": 102 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield11.webp", + "imageUrl": "/images/base/grand_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -9180,7 +9180,7 @@ "evasion": 165, "energy_shield": 50 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDexInt03.webp", + "imageUrl": "/images/base/grasping_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9201,7 +9201,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/BreachlordRing_Formless.webp", + "imageUrl": "/images/base/grasping_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -9222,7 +9222,7 @@ "int": 32 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Flails/Flail12.webp", + "imageUrl": "/images/base/great_flail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9243,7 +9243,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow01.webp", + "imageUrl": "/images/base/greatbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9264,7 +9264,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Flasks/Basetypes/FlaskLife03.webp", + "imageUrl": "/images/base/greater_life_flask.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -9285,7 +9285,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Flasks/Basetypes/FlaskMana03.webp", + "imageUrl": "/images/base/greater_mana_flask.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -9306,7 +9306,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace11.webp", + "imageUrl": "/images/base/greatmace.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9329,7 +9329,7 @@ "baseStats": { "energy_shield": 45 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt02.webp", + "imageUrl": "/images/base/grim_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -9353,7 +9353,7 @@ "evasion": 187, "energy_shield": 57 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt06.webp", + "imageUrl": "/images/base/grinning_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9374,7 +9374,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Charms/Basetypes/GroundingCharm.webp", + "imageUrl": "/images/base/grounding_charm.webp", "affixSlots": { "prefix": 0, "suffix": 0 @@ -9395,7 +9395,7 @@ "int": 26 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Flails/Flail09.webp", + "imageUrl": "/images/base/guarded_flail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9419,7 +9419,7 @@ "armour": 42, "evasion": 34 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex02.webp", + "imageUrl": "/images/base/guarded_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9440,7 +9440,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow03.webp", + "imageUrl": "/images/base/guardian_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9463,7 +9463,7 @@ "baseStats": { "armour": 325 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr11.webp", + "imageUrl": "/images/base/guardian_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9484,7 +9484,7 @@ "int": 34 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff08.webp", + "imageUrl": "/images/base/guardian_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9505,7 +9505,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear09.webp", + "imageUrl": "/images/base/guardian_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9528,7 +9528,7 @@ "baseStats": { "evasion": 163 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler06.webp", + "imageUrl": "/images/base/gutspike_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -9552,7 +9552,7 @@ "armour": 151, "energy_shield": 43 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr04.webp", + "imageUrl": "/images/base/hallowed_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9575,7 +9575,7 @@ "baseStats": { "energy_shield": 57 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus08.webp", + "imageUrl": "/images/base/hallowed_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -9598,7 +9598,7 @@ "baseStats": { "spirit": "100" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Scepters/Basetypes/Sceptre01.webp", + "imageUrl": "/images/base/hallowed_sceptre.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9621,7 +9621,7 @@ "baseStats": { "evasion": 120 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex07.webp", + "imageUrl": "/images/base/hardened_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -9644,7 +9644,7 @@ "baseStats": { "evasion": 392 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex01.webp", + "imageUrl": "/images/base/hardleather_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9665,7 +9665,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear01.webp", + "imageUrl": "/images/base/hardwood_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9689,7 +9689,7 @@ "armour": 10, "evasion": 7 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield01.webp", + "imageUrl": "/images/base/hardwood_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -9713,7 +9713,7 @@ "evasion": 226, "energy_shield": 70 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt05.webp", + "imageUrl": "/images/base/hatungo_garb.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9736,7 +9736,7 @@ "baseStats": { "energy_shield": 138 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt13.webp", + "imageUrl": "/images/base/havoc_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9760,7 +9760,7 @@ "evasion": 237, "energy_shield": 73 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt06.webp", + "imageUrl": "/images/base/hawkers_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9784,7 +9784,7 @@ "armour": 261, "energy_shield": 73 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr06.webp", + "imageUrl": "/images/base/heartcarver_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9805,7 +9805,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow02.webp", + "imageUrl": "/images/base/heartwood_shortbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9826,7 +9826,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Belts/Basetypes/Belt09.webp", + "imageUrl": "/images/base/heavy_belt.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -9847,7 +9847,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow13.webp", + "imageUrl": "/images/base/heavy_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9871,7 +9871,7 @@ "armour": 97, "energy_shield": 30 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr05.webp", + "imageUrl": "/images/base/heavy_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9892,7 +9892,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace07.webp", + "imageUrl": "/images/base/heavy_greathammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9915,7 +9915,7 @@ "baseStats": { "armour": 453 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr07.webp", + "imageUrl": "/images/base/heavy_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9936,7 +9936,7 @@ "int": 26 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff09.webp", + "imageUrl": "/images/base/hefty_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -9960,7 +9960,7 @@ "armour": 72, "energy_shield": 21 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr02.webp", + "imageUrl": "/images/base/heirloom_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -9981,7 +9981,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear13.webp", + "imageUrl": "/images/base/helix_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10004,7 +10004,7 @@ "baseStats": { "armour": 111 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower07.webp", + "imageUrl": "/images/base/heraldric_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -10028,7 +10028,7 @@ "evasion": 16, "energy_shield": 16 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt01.webp", + "imageUrl": "/images/base/hermit_garb.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10052,7 +10052,7 @@ "armour": 273, "evasion": 248 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex11.webp", + "imageUrl": "/images/base/heroic_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10076,7 +10076,7 @@ "evasion": 20, "energy_shield": 13 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt01.webp", + "imageUrl": "/images/base/hewn_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10099,7 +10099,7 @@ "baseStats": { "energy_shield": 45 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt03.webp", + "imageUrl": "/images/base/hexers_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10120,7 +10120,7 @@ "int": 9 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Flails/Flail03.webp", + "imageUrl": "/images/base/holy_flail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10143,7 +10143,7 @@ "baseStats": { "armour": 260 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr03.webp", + "imageUrl": "/images/base/homeguard_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10167,7 +10167,7 @@ "evasion": 46, "energy_shield": 19 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt03.webp", + "imageUrl": "/images/base/hooded_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10188,7 +10188,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandAxes/Basetypes/1HAxe02.webp", + "imageUrl": "/images/base/hook_axe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10209,7 +10209,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Claws/Basetypes/Claw08.webp", + "imageUrl": "/images/base/hooked_claw.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10233,7 +10233,7 @@ "armour": 39, "energy_shield": 16 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr02.webp", + "imageUrl": "/images/base/horned_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10254,7 +10254,7 @@ "int": 45 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/PrimalTalisman.webp", + "imageUrl": "/images/base/howling_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10277,7 +10277,7 @@ "baseStats": { "evasion": 158 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex05.webp", + "imageUrl": "/images/base/hunter_hood.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10300,7 +10300,7 @@ "baseStats": { "evasion": 105 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex02.webp", + "imageUrl": "/images/base/hunting_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -10323,7 +10323,7 @@ "baseStats": { "evasion": 339 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex03.webp", + "imageUrl": "/images/base/hunting_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10347,7 +10347,7 @@ "evasion": 65, "energy_shield": 22 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt03.webp", + "imageUrl": "/images/base/hunting_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -10368,7 +10368,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear03.webp", + "imageUrl": "/images/base/hunting_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10389,7 +10389,7 @@ "int": 27 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Flails/Flail10.webp", + "imageUrl": "/images/base/icicle_flail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10410,7 +10410,7 @@ "int": 80 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Staves/Basetypes/Staff09.webp", + "imageUrl": "/images/base/icicle_staff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10433,7 +10433,7 @@ "baseStats": { "armour": 374 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr07.webp", + "imageUrl": "/images/base/imperial_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10456,7 +10456,7 @@ "baseStats": { "energy_shield": 115 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt11.webp", + "imageUrl": "/images/base/imperial_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10477,7 +10477,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/incense_relic.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -10498,7 +10498,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Traps/TrapRemote02.webp", + "imageUrl": "/images/base/incense_trap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10522,7 +10522,7 @@ "armour": 163, "energy_shield": 46 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr05.webp", + "imageUrl": "/images/base/inquisitor_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10546,7 +10546,7 @@ "armour": 112, "energy_shield": 31 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest02.webp", + "imageUrl": "/images/base/intricate_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -10569,7 +10569,7 @@ "baseStats": { "energy_shield": 27 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt05.webp", + "imageUrl": "/images/base/intricate_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -10590,7 +10590,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Traps/TrapRemote05.webp", + "imageUrl": "/images/base/intricate_trap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10611,7 +10611,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Belts/Basetypes/InvokingBelt.webp", + "imageUrl": "/images/base/invoking_belt.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -10634,7 +10634,7 @@ "baseStats": { "evasion": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler04.webp", + "imageUrl": "/images/base/iron_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -10658,7 +10658,7 @@ "armour": 26, "energy_shield": 13 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr01.webp", + "imageUrl": "/images/base/iron_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10681,7 +10681,7 @@ "baseStats": { "armour": 115 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr03.webp", + "imageUrl": "/images/base/iron_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10702,7 +10702,7 @@ "int": 12 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Flails/Flail04.webp", + "imageUrl": "/images/base/iron_flail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10723,7 +10723,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandSwords/Basetypes/2HSword02.webp", + "imageUrl": "/images/base/iron_greatsword.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10746,7 +10746,7 @@ "baseStats": { "armour": 57 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr02.webp", + "imageUrl": "/images/base/iron_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -10767,7 +10767,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/Basetypes/IronRing.webp", + "imageUrl": "/images/base/iron_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -10791,7 +10791,7 @@ "armour": 149, "energy_shield": 46 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr05.webp", + "imageUrl": "/images/base/ironclad_vestments.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10812,7 +10812,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear02.webp", + "imageUrl": "/images/base/ironhead_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10836,7 +10836,7 @@ "armour": 64, "evasion": 58 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex01.webp", + "imageUrl": "/images/base/ironmail_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -10859,7 +10859,7 @@ "baseStats": { "aps": 1 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace02.webp", + "imageUrl": "/images/base/ironwood_greathammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10880,7 +10880,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow02.webp", + "imageUrl": "/images/base/ironwood_shortbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10904,7 +10904,7 @@ "armour": 80, "evasion": 72 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield01.webp", + "imageUrl": "/images/base/ironwood_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -10925,7 +10925,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/irradiated_tablet.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -10949,7 +10949,7 @@ "evasion": 208, "energy_shield": 65 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt04.webp", + "imageUrl": "/images/base/itinerant_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -10970,7 +10970,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/Basetypes/JadeAmulet.webp", + "imageUrl": "/images/base/jade_amulet.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -10991,7 +10991,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace10.webp", + "imageUrl": "/images/base/jade_club.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -11012,7 +11012,7 @@ "int": 65 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/LumberingTalisman.webp", + "imageUrl": "/images/base/jade_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -11035,7 +11035,7 @@ "baseStats": { "energy_shield": 73 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt08.webp", + "imageUrl": "/images/base/jade_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -11056,7 +11056,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandAxes/Basetypes/2HAxe08.webp", + "imageUrl": "/images/base/jagged_greataxe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -11077,7 +11077,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear07.webp", + "imageUrl": "/images/base/jagged_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -11100,7 +11100,7 @@ "baseStats": { "energy_shield": 23 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt04.webp", + "imageUrl": "/images/base/jewelled_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -11123,7 +11123,7 @@ "baseStats": { "evasion": 135 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler07.webp", + "imageUrl": "/images/base/jingling_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -11147,7 +11147,7 @@ "armour": 53, "energy_shield": 17 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest04.webp", + "imageUrl": "/images/base/jingling_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -11170,7 +11170,7 @@ "baseStats": { "energy_shield": 47 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus05.webp", + "imageUrl": "/images/base/jingling_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -11193,7 +11193,7 @@ "baseStats": { "armour": 355 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr09.webp", + "imageUrl": "/images/base/juggernaut_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -11216,7 +11216,7 @@ "baseStats": { "energy_shield": 84 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt05.webp", + "imageUrl": "/images/base/jungle_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -11240,7 +11240,7 @@ "armour": 64, "energy_shield": 19 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr04.webp", + "imageUrl": "/images/base/kalguuran_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -11261,7 +11261,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace01.webp", + "imageUrl": "/images/base/kalguuran_forgehammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -11284,7 +11284,7 @@ "baseStats": { "energy_shield": 103 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt05.webp", + "imageUrl": "/images/base/kamasan_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -11305,7 +11305,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandSwords/Basetypes/2HSword09.webp", + "imageUrl": "/images/base/keen_greatsword.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -11328,7 +11328,7 @@ "baseStats": { "energy_shield": 74 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt06.webp", + "imageUrl": "/images/base/keth_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -11349,7 +11349,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/BreachlordRing_UulNetol.webp", + "imageUrl": "/images/base/kinetic_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -11373,7 +11373,7 @@ "armour": 195, "evasion": 176 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex07.webp", + "imageUrl": "/images/base/knight_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -11396,7 +11396,7 @@ "baseStats": { "armour": 162 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr02.webp", + "imageUrl": "/images/base/knightly_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -11419,7 +11419,7 @@ "baseStats": { "weapon_range": "1" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Daggers/Basetypes/Dagger10.webp", + "imageUrl": "/images/base/kris_knife.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -11442,7 +11442,7 @@ "baseStats": { "evasion": 84 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex03.webp", + "imageUrl": "/images/base/lace_hood.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -11465,7 +11465,7 @@ "baseStats": { "evasion": 47 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex02.webp", + "imageUrl": "/images/base/laced_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -11488,7 +11488,7 @@ "baseStats": { "energy_shield": 51 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt02.webp", + "imageUrl": "/images/base/laced_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -11512,7 +11512,7 @@ "armour": 222, "evasion": 201 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex01.webp", + "imageUrl": "/images/base/lamellar_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -11533,7 +11533,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/Basetypes/LamentAmulet.webp", + "imageUrl": "/images/base/lament_amulet.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -11556,7 +11556,7 @@ "baseStats": { "evasion": 105 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler09.webp", + "imageUrl": "/images/base/laminate_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -11577,7 +11577,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/Basetypes/LapisAmulet.webp", + "imageUrl": "/images/base/lapis_amulet.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -11600,7 +11600,7 @@ "baseStats": { "energy_shield": 27 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt03.webp", + "imageUrl": "/images/base/lattice_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -11624,7 +11624,7 @@ "armour": 146, "energy_shield": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr07.webp", + "imageUrl": "/images/base/lavish_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -11648,7 +11648,7 @@ "armour": 27, "evasion": 23 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex02.webp", + "imageUrl": "/images/base/layered_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -11671,7 +11671,7 @@ "baseStats": { "evasion": 379 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex06.webp", + "imageUrl": "/images/base/layered_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -11692,7 +11692,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/Basetypes/LazuliRing.webp", + "imageUrl": "/images/base/lazuli_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -11713,7 +11713,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Traps/Trap06.webp", + "imageUrl": "/images/base/lead_trap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -11734,7 +11734,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace07.webp", + "imageUrl": "/images/base/leaden_greathammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -11757,7 +11757,7 @@ "baseStats": { "evasion": 10 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler01.webp", + "imageUrl": "/images/base/leather_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -11780,7 +11780,7 @@ "baseStats": { "evasion": 30 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex01.webp", + "imageUrl": "/images/base/leather_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -11803,7 +11803,7 @@ "baseStats": { "evasion": 231 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex08.webp", + "imageUrl": "/images/base/leatherbound_hood.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -11826,7 +11826,7 @@ "baseStats": { "evasion": 180 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex01.webp", + "imageUrl": "/images/base/leatherplate_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -11847,7 +11847,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Flasks/Basetypes/FlaskLife01.webp", + "imageUrl": "/images/base/lesser_life_flask.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -11868,7 +11868,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Flasks/Basetypes/FlaskMana01.webp", + "imageUrl": "/images/base/lesser_mana_flask.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -11891,7 +11891,7 @@ "baseStats": { "energy_shield": 71 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus06.webp", + "imageUrl": "/images/base/leyline_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -11912,7 +11912,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandAxes/Basetypes/2HAxe02.webp", + "imageUrl": "/images/base/light_halberd.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -11933,7 +11933,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Belts/Basetypes/Belt02.webp", + "imageUrl": "/images/base/linen_belt.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -11957,7 +11957,7 @@ "evasion": 23, "energy_shield": 10 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt02.webp", + "imageUrl": "/images/base/linen_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -11980,7 +11980,7 @@ "baseStats": { "armour": 195 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr03.webp", + "imageUrl": "/images/base/lionheart_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -12003,7 +12003,7 @@ "baseStats": { "evasion": 118 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex05.webp", + "imageUrl": "/images/base/lizardscale_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -12026,7 +12026,7 @@ "baseStats": { "evasion": 432 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex08.webp", + "imageUrl": "/images/base/lizardscale_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12047,7 +12047,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Belts/Basetypes/Belt04.webp", + "imageUrl": "/images/base/long_belt.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -12068,7 +12068,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff02.webp", + "imageUrl": "/images/base/long_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12089,7 +12089,7 @@ "int": 43 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/LumberingTalisman.webp", + "imageUrl": "/images/base/lumbering_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12110,7 +12110,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace01.webp", + "imageUrl": "/images/base/lumen_mace.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12131,7 +12131,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/Basetypes/LunarAmulet.webp", + "imageUrl": "/images/base/lunar_amulet.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -12152,7 +12152,7 @@ "int": 46 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff05.webp", + "imageUrl": "/images/base/lunar_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12175,7 +12175,7 @@ "baseStats": { "spirit": "100" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Scepters/Basetypes/Sceptre03.webp", + "imageUrl": "/images/base/lupine_sceptre.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12198,7 +12198,7 @@ "baseStats": { "energy_shield": 114 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt05.webp", + "imageUrl": "/images/base/luxurious_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12221,7 +12221,7 @@ "baseStats": { "energy_shield": 73 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt04.webp", + "imageUrl": "/images/base/luxurious_slippers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -12244,7 +12244,7 @@ "baseStats": { "energy_shield": 56 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus01.webp", + "imageUrl": "/images/base/magus_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -12267,7 +12267,7 @@ "baseStats": { "energy_shield": 90 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt11.webp", + "imageUrl": "/images/base/magus_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12288,7 +12288,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Belts/Basetypes/Belt07.webp", + "imageUrl": "/images/base/mail_belt.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -12311,7 +12311,7 @@ "baseStats": { "weapon_range": "1" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Daggers/Basetypes/Dagger09.webp", + "imageUrl": "/images/base/mail_breaker.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12334,7 +12334,7 @@ "baseStats": { "evasion": 451 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex01.webp", + "imageUrl": "/images/base/mail_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12358,7 +12358,7 @@ "armour": 22, "evasion": 17 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex01.webp", + "imageUrl": "/images/base/mail_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -12382,7 +12382,7 @@ "armour": 83, "energy_shield": 30 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr03.webp", + "imageUrl": "/images/base/mail_vestments.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12406,7 +12406,7 @@ "armour": 128, "energy_shield": 37 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr01.webp", + "imageUrl": "/images/base/mailed_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12427,7 +12427,7 @@ "int": 67 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/RabidTalisman.webp", + "imageUrl": "/images/base/maji_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12448,7 +12448,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow01.webp", + "imageUrl": "/images/base/makeshift_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12472,7 +12472,7 @@ "armour": 112, "evasion": 102 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield02.webp", + "imageUrl": "/images/base/mammoth_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -12496,7 +12496,7 @@ "armour": 230, "evasion": 208 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex04.webp", + "imageUrl": "/images/base/mantled_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12520,7 +12520,7 @@ "evasion": 71, "energy_shield": 30 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt03.webp", + "imageUrl": "/images/base/marabout_garb.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12543,7 +12543,7 @@ "baseStats": { "armour": 178 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr05.webp", + "imageUrl": "/images/base/maraketh_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12564,7 +12564,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace07.webp", + "imageUrl": "/images/base/marauding_mace.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12585,7 +12585,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace06.webp", + "imageUrl": "/images/base/marching_mace.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12609,7 +12609,7 @@ "armour": 85, "energy_shield": 27 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr04.webp", + "imageUrl": "/images/base/martyr_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12632,7 +12632,7 @@ "baseStats": { "armour": 341 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr04.webp", + "imageUrl": "/images/base/masked_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12653,7 +12653,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace07.webp", + "imageUrl": "/images/base/massive_greathammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12676,7 +12676,7 @@ "baseStats": { "armour": 187 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr06.webp", + "imageUrl": "/images/base/massive_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -12697,7 +12697,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear08.webp", + "imageUrl": "/images/base/massive_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12718,7 +12718,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Traps/Trap07.webp", + "imageUrl": "/images/base/medallion_trap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12739,7 +12739,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Flasks/Basetypes/FlaskLife02.webp", + "imageUrl": "/images/base/medium_life_flask.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -12760,7 +12760,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Flasks/Basetypes/FlaskMana02.webp", + "imageUrl": "/images/base/medium_mana_flask.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -12783,7 +12783,7 @@ "baseStats": { "armour": 246 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr02.webp", + "imageUrl": "/images/base/mercenary_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12807,7 +12807,7 @@ "armour": 89, "evasion": 81 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield03.webp", + "imageUrl": "/images/base/mercenary_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -12828,7 +12828,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSwords/Basetypes/1HSword11.webp", + "imageUrl": "/images/base/messer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12851,7 +12851,7 @@ "baseStats": { "armour": 154 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower03.webp", + "imageUrl": "/images/base/metalworked_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -12872,7 +12872,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow08.webp", + "imageUrl": "/images/base/militant_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12893,7 +12893,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/BreachlordRing_Esh.webp", + "imageUrl": "/images/base/mnemonic_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -12914,7 +12914,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace02.webp", + "imageUrl": "/images/base/molten_hammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12938,7 +12938,7 @@ "evasion": 216, "energy_shield": 67 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt10.webp", + "imageUrl": "/images/base/monastic_garb.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12959,7 +12959,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandAxes/Basetypes/2HAxe12.webp", + "imageUrl": "/images/base/monument_greataxe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -12982,7 +12982,7 @@ "baseStats": { "armour": 199 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr01.webp", + "imageUrl": "/images/base/monument_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -13005,7 +13005,7 @@ "baseStats": { "weapon_range": "1" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Daggers/Basetypes/Dagger05.webp", + "imageUrl": "/images/base/moon_dagger.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13026,7 +13026,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace09.webp", + "imageUrl": "/images/base/morning_star.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13050,7 +13050,7 @@ "armour": 91, "evasion": 82 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield09.webp", + "imageUrl": "/images/base/mosaic_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -13073,7 +13073,7 @@ "baseStats": { "armour": 89 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr05.webp", + "imageUrl": "/images/base/moulded_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -13096,7 +13096,7 @@ "baseStats": { "energy_shield": 110 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt10.webp", + "imageUrl": "/images/base/mystic_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13119,7 +13119,7 @@ "baseStats": { "evasion": 235 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex03.webp", + "imageUrl": "/images/base/narrow_hood.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13140,7 +13140,7 @@ "int": 8 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/NettleTalisman.webp", + "imageUrl": "/images/base/nettle_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13163,7 +13163,7 @@ "baseStats": { "energy_shield": 76 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt01.webp", + "imageUrl": "/images/base/noble_circlet.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13186,7 +13186,7 @@ "baseStats": { "armour": 297 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr05.webp", + "imageUrl": "/images/base/noble_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13210,7 +13210,7 @@ "armour": 141, "evasion": 128 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex02.webp", + "imageUrl": "/images/base/noble_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -13233,7 +13233,7 @@ "baseStats": { "armour": 186 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower07.webp", + "imageUrl": "/images/base/noble_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -13256,7 +13256,7 @@ "baseStats": { "evasion": 105 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler02.webp", + "imageUrl": "/images/base/oak_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -13279,7 +13279,7 @@ "baseStats": { "aps": 1 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace02.webp", + "imageUrl": "/images/base/oak_greathammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13303,7 +13303,7 @@ "evasion": 115, "energy_shield": 37 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt01.webp", + "imageUrl": "/images/base/oak_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13324,7 +13324,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow09.webp", + "imageUrl": "/images/base/obliterator_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13347,7 +13347,7 @@ "baseStats": { "weapon_range": "1" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Daggers/Basetypes/Dagger07.webp", + "imageUrl": "/images/base/obsidian_dagger.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13368,7 +13368,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandSwords/Basetypes/2HSword08.webp", + "imageUrl": "/images/base/obsidian_greatsword.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13392,7 +13392,7 @@ "armour": 230, "energy_shield": 65 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr04.webp", + "imageUrl": "/images/base/occultist_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13415,7 +13415,7 @@ "baseStats": { "spirit": "100" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Scepters/Basetypes/Sceptre05.webp", + "imageUrl": "/images/base/ochre_sceptre.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13436,7 +13436,7 @@ "int": 68 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Wands/Basetypes/Wand08.webp", + "imageUrl": "/images/base/offering_wand.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13460,7 +13460,7 @@ "evasion": 187, "energy_shield": 60 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt02.webp", + "imageUrl": "/images/base/oiled_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13484,7 +13484,7 @@ "armour": 66, "energy_shield": 20 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest06.webp", + "imageUrl": "/images/base/omen_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -13507,7 +13507,7 @@ "baseStats": { "spirit": "100" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Scepters/Basetypes/Sceptre04.webp", + "imageUrl": "/images/base/omen_sceptre.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13530,7 +13530,7 @@ "baseStats": { "energy_shield": 34 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt02.webp", + "imageUrl": "/images/base/ominous_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -13551,7 +13551,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/BreachlordRing_Chayula.webp", + "imageUrl": "/images/base/oneiric_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -13574,7 +13574,7 @@ "baseStats": { "energy_shield": 48 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt04.webp", + "imageUrl": "/images/base/opulent_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -13595,7 +13595,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear02.webp", + "imageUrl": "/images/base/orichalcum_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13616,7 +13616,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Belts/Basetypes/Belt06.webp", + "imageUrl": "/images/base/ornate_belt.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -13639,7 +13639,7 @@ "baseStats": { "evasion": 120 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler11.webp", + "imageUrl": "/images/base/ornate_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -13663,7 +13663,7 @@ "armour": 82, "energy_shield": 23 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr03.webp", + "imageUrl": "/images/base/ornate_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -13687,7 +13687,7 @@ "armour": 89, "evasion": 81 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex01.webp", + "imageUrl": "/images/base/ornate_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -13710,7 +13710,7 @@ "baseStats": { "armour": 256 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr04.webp", + "imageUrl": "/images/base/ornate_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -13733,7 +13733,7 @@ "baseStats": { "armour": 171 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr04.webp", + "imageUrl": "/images/base/ornate_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -13756,7 +13756,7 @@ "baseStats": { "armour": 496 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr06.webp", + "imageUrl": "/images/base/ornate_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13780,7 +13780,7 @@ "armour": 749, "energy_shield": 220 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Uniques/Loreweave.webp", + "imageUrl": "/images/base/ornate_ringmail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13801,7 +13801,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/overseer_tablet.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -13825,7 +13825,7 @@ "armour": 20, "energy_shield": 10 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr01.webp", + "imageUrl": "/images/base/padded_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -13848,7 +13848,7 @@ "baseStats": { "evasion": 111 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler03.webp", + "imageUrl": "/images/base/painted_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -13872,7 +13872,7 @@ "armour": 80, "energy_shield": 23 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest01.webp", + "imageUrl": "/images/base/painted_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -13893,7 +13893,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow04.webp", + "imageUrl": "/images/base/painted_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13916,7 +13916,7 @@ "baseStats": { "armour": 33 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower02.webp", + "imageUrl": "/images/base/painted_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -13939,7 +13939,7 @@ "baseStats": { "armour": 357 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr05.webp", + "imageUrl": "/images/base/paragon_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13960,7 +13960,7 @@ "int": 92 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Staves/Basetypes/Staff11.webp", + "imageUrl": "/images/base/paralysing_staff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -13984,7 +13984,7 @@ "evasion": 137, "energy_shield": 43 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt04.webp", + "imageUrl": "/images/base/pariah_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14007,7 +14007,7 @@ "baseStats": { "weapon_range": "1" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Daggers/Basetypes/Dagger11.webp", + "imageUrl": "/images/base/parrying_dagger.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14030,7 +14030,7 @@ "baseStats": { "evasion": 320 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex02.webp", + "imageUrl": "/images/base/patchwork_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14053,7 +14053,7 @@ "baseStats": { "evasion": 96 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex03.webp", + "imageUrl": "/images/base/pathfinder_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14076,7 +14076,7 @@ "baseStats": { "energy_shield": 34 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt06.webp", + "imageUrl": "/images/base/pauascale_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -14099,7 +14099,7 @@ "baseStats": { "evasion": 116 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler10.webp", + "imageUrl": "/images/base/pearl_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -14120,7 +14120,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/Basetypes/PearlRing.webp", + "imageUrl": "/images/base/pearl_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -14141,7 +14141,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/Basetypes/PearlescentAmulet.webp", + "imageUrl": "/images/base/pearlescent_amulet.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -14165,7 +14165,7 @@ "armour": 21, "evasion": 17 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield02.webp", + "imageUrl": "/images/base/pelage_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -14189,7 +14189,7 @@ "armour": 73, "energy_shield": 22 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr03.webp", + "imageUrl": "/images/base/pelt_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -14213,7 +14213,7 @@ "armour": 59, "energy_shield": 24 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr02.webp", + "imageUrl": "/images/base/pelt_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14234,7 +14234,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Quivers/Basetypes/QuiverPenetrating.webp", + "imageUrl": "/images/base/penetrating_quiver.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -14255,7 +14255,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/HeistAmulet2.webp", + "imageUrl": "/images/base/penumbra_amulet.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -14276,7 +14276,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/LakeRing3.webp", + "imageUrl": "/images/base/penumbra_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -14297,7 +14297,7 @@ "int": 114 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Staves/Basetypes/Staff07.webp", + "imageUrl": "/images/base/perching_staff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14318,7 +14318,7 @@ "int": 114 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Staves/Basetypes/Staff02.webp", + "imageUrl": "/images/base/permafrost_staff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14341,7 +14341,7 @@ "baseStats": { "armour": 166 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower01.webp", + "imageUrl": "/images/base/phalanx_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -14362,7 +14362,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Claws/Basetypes/Claw02.webp", + "imageUrl": "/images/base/pict_claw.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14383,7 +14383,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Claws/Basetypes/Claw12.webp", + "imageUrl": "/images/base/piercing_claw.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14404,7 +14404,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow10.webp", + "imageUrl": "/images/base/piercing_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14428,7 +14428,7 @@ "armour": 25, "energy_shield": 16 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr01.webp", + "imageUrl": "/images/base/pilgrim_vestments.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14452,7 +14452,7 @@ "armour": 134, "energy_shield": 37 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr01.webp", + "imageUrl": "/images/base/pious_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -14475,7 +14475,7 @@ "baseStats": { "spirit": "100" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Scepters/Basetypes/Sceptre01.webp", + "imageUrl": "/images/base/pious_sceptre.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14496,7 +14496,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Belts/Basetypes/Belt05.webp", + "imageUrl": "/images/base/plate_belt.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -14520,7 +14520,7 @@ "armour": 64, "evasion": 58 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex04.webp", + "imageUrl": "/images/base/plate_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -14543,7 +14543,7 @@ "baseStats": { "evasion": 31 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler03.webp", + "imageUrl": "/images/base/plated_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -14564,7 +14564,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Claws/Basetypes/Claw05.webp", + "imageUrl": "/images/base/plated_claw.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14587,7 +14587,7 @@ "baseStats": { "armour": 174 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr02.webp", + "imageUrl": "/images/base/plated_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -14608,7 +14608,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace06.webp", + "imageUrl": "/images/base/plated_mace.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14631,7 +14631,7 @@ "baseStats": { "armour": 116 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr02.webp", + "imageUrl": "/images/base/plated_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -14654,7 +14654,7 @@ "baseStats": { "energy_shield": 126 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt12.webp", + "imageUrl": "/images/base/plated_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14678,7 +14678,7 @@ "armour": 249, "energy_shield": 70 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr05.webp", + "imageUrl": "/images/base/plated_vestments.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14701,7 +14701,7 @@ "baseStats": { "energy_shield": 36 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus08.webp", + "imageUrl": "/images/base/plumed_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -14722,7 +14722,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace09.webp", + "imageUrl": "/images/base/pointed_maul.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14745,7 +14745,7 @@ "baseStats": { "evasion": 170 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex06.webp", + "imageUrl": "/images/base/polished_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -14769,7 +14769,7 @@ "armour": 94, "evasion": 85 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield04.webp", + "imageUrl": "/images/base/polished_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -14790,7 +14790,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/Basetypes/PortentAmulet.webp", + "imageUrl": "/images/base/portent_amulet.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -14811,7 +14811,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace12.webp", + "imageUrl": "/images/base/precise_greathammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14835,7 +14835,7 @@ "evasion": 268, "energy_shield": 82 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt08.webp", + "imageUrl": "/images/base/primal_markings.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14856,7 +14856,7 @@ "int": 25 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/PrimalTalisman.webp", + "imageUrl": "/images/base/primal_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14877,7 +14877,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Quivers/Basetypes/QuiverPrimed.webp", + "imageUrl": "/images/base/primed_quiver.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -14898,7 +14898,7 @@ "int": 99 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Wands/Basetypes/Wand12.webp", + "imageUrl": "/images/base/primordial_wand.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14919,7 +14919,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/Basetypes/PrismaticRing.webp", + "imageUrl": "/images/base/prismatic_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -14940,7 +14940,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandAxes/Basetypes/1HAxe12.webp", + "imageUrl": "/images/base/profane_cleaver.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14961,7 +14961,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear06.webp", + "imageUrl": "/images/base/pronged_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -14982,7 +14982,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow03.webp", + "imageUrl": "/images/base/protector_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15003,7 +15003,7 @@ "int": 31 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Staves/Basetypes/Staff05.webp", + "imageUrl": "/images/base/pyrophyte_staff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15027,7 +15027,7 @@ "armour": 102, "energy_shield": 29 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest05.webp", + "imageUrl": "/images/base/quartered_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -15051,7 +15051,7 @@ "evasion": 134, "energy_shield": 41 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt03.webp", + "imageUrl": "/images/base/quickslip_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -15074,7 +15074,7 @@ "baseStats": { "evasion": 49 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex02.webp", + "imageUrl": "/images/base/quilted_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15095,7 +15095,7 @@ "int": 29 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/RabidTalisman.webp", + "imageUrl": "/images/base/rabid_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15118,7 +15118,7 @@ "baseStats": { "armour": 150 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr04.webp", + "imageUrl": "/images/base/raider_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15142,7 +15142,7 @@ "evasion": 248, "energy_shield": 76 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt04.webp", + "imageUrl": "/images/base/rambler_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15165,7 +15165,7 @@ "baseStats": { "armour": 96 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower06.webp", + "imageUrl": "/images/base/rampart_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -15188,7 +15188,7 @@ "baseStats": { "spirit": "100" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Scepters/Basetypes/Sceptre01.webp", + "imageUrl": "/images/base/rattling_sceptre.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15209,7 +15209,7 @@ "int": 114 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Staves/Basetypes/Staff01.webp", + "imageUrl": "/images/base/ravenous_staff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15230,7 +15230,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Belts/Basetypes/Belt01.webp", + "imageUrl": "/images/base/rawhide_belt.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -15253,7 +15253,7 @@ "baseStats": { "evasion": 15 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex01.webp", + "imageUrl": "/images/base/rawhide_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -15274,7 +15274,7 @@ "int": 50 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff07.webp", + "imageUrl": "/images/base/razor_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15295,7 +15295,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Claws/Basetypes/Claw09.webp", + "imageUrl": "/images/base/razorglass_claw.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15316,7 +15316,7 @@ "int": 26 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff02.webp", + "imageUrl": "/images/base/reaching_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15337,7 +15337,7 @@ "int": 68 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Staves/Basetypes/Staff08.webp", + "imageUrl": "/images/base/reaping_staff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15358,7 +15358,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandAxes/Basetypes/2HAxe09.webp", + "imageUrl": "/images/base/reaver_glaive.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15379,7 +15379,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow04.webp", + "imageUrl": "/images/base/recurve_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15402,7 +15402,7 @@ "baseStats": { "armour": 174 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr06.webp", + "imageUrl": "/images/base/reefsteel_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -15425,7 +15425,7 @@ "baseStats": { "evasion": 124 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex04.webp", + "imageUrl": "/images/base/refined_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -15446,7 +15446,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/Basetypes/BreachRing.webp", + "imageUrl": "/images/base/refined_breach_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -15467,7 +15467,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Traps/Trap08.webp", + "imageUrl": "/images/base/refined_trap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15488,7 +15488,7 @@ "int": 114 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Staves/Basetypes/Staff02.webp", + "imageUrl": "/images/base/reflecting_staff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15509,7 +15509,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandSwords/Basetypes/2HSword12.webp", + "imageUrl": "/images/base/regalia_longsword.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15530,7 +15530,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandAxes/Basetypes/2HAxe07.webp", + "imageUrl": "/images/base/rending_halberd.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15551,7 +15551,7 @@ "int": 60 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Staves/Basetypes/Staff07.webp", + "imageUrl": "/images/base/rending_staff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15575,7 +15575,7 @@ "armour": 273, "energy_shield": 76 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr11.webp", + "imageUrl": "/images/base/revered_vestments.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15598,7 +15598,7 @@ "baseStats": { "evasion": 168 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex05.webp", + "imageUrl": "/images/base/rhoahide_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15619,7 +15619,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow05.webp", + "imageUrl": "/images/base/rider_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15642,7 +15642,7 @@ "baseStats": { "evasion": 55 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler05.webp", + "imageUrl": "/images/base/ridged_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -15665,7 +15665,7 @@ "baseStats": { "evasion": 359 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex05.webp", + "imageUrl": "/images/base/riding_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15689,7 +15689,7 @@ "armour": 73, "energy_shield": 21 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr05png.webp", + "imageUrl": "/images/base/righteous_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -15710,7 +15710,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/MirrorRing.webp", + "imageUrl": "/images/base/ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -15731,7 +15731,7 @@ "int": 23 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Flails/Flail08.webp", + "imageUrl": "/images/base/ring_flail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15755,7 +15755,7 @@ "armour": 195, "evasion": 176 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex01.webp", + "imageUrl": "/images/base/ring_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15778,7 +15778,7 @@ "baseStats": { "evasion": 79 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler07.webp", + "imageUrl": "/images/base/ringed_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -15802,7 +15802,7 @@ "armour": 14, "evasion": 11 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex01.webp", + "imageUrl": "/images/base/ringmail_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -15823,7 +15823,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandSwords/Basetypes/2HSword05.webp", + "imageUrl": "/images/base/rippled_greatsword.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15844,7 +15844,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/ritual_tablet.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -15867,7 +15867,7 @@ "baseStats": { "energy_shield": 119 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt06.webp", + "imageUrl": "/images/base/river_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15890,7 +15890,7 @@ "baseStats": { "armour": 38 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr02.webp", + "imageUrl": "/images/base/riveted_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -15911,7 +15911,7 @@ "int": 87 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Staves/Basetypes/Staff10.webp", + "imageUrl": "/images/base/roaring_staff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15932,7 +15932,7 @@ "int": 47 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/RoaringTalisman.webp", + "imageUrl": "/images/base/roaring_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15953,7 +15953,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow03.webp", + "imageUrl": "/images/base/robust_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -15977,7 +15977,7 @@ "armour": 63, "evasion": 53 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex02.webp", + "imageUrl": "/images/base/rogue_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -16001,7 +16001,7 @@ "armour": 13, "energy_shield": 6 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr01.webp", + "imageUrl": "/images/base/rope_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16024,7 +16024,7 @@ "baseStats": { "evasion": 210 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex01.webp", + "imageUrl": "/images/base/rotted_hood.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -16047,7 +16047,7 @@ "baseStats": { "armour": 22 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr01.webp", + "imageUrl": "/images/base/rough_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16070,7 +16070,7 @@ "baseStats": { "armour": 203 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower03.webp", + "imageUrl": "/images/base/royal_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16091,7 +16091,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/ruby.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -16112,7 +16112,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Charms/Basetypes/RubyCharm.webp", + "imageUrl": "/images/base/ruby_charm.webp", "affixSlots": { "prefix": 0, "suffix": 0 @@ -16133,7 +16133,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/Basetypes/RubyRing.webp", + "imageUrl": "/images/base/ruby_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16156,7 +16156,7 @@ "baseStats": { "armour": 376 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr03.webp", + "imageUrl": "/images/base/rugged_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -16177,7 +16177,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace08.webp", + "imageUrl": "/images/base/ruination_maul.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -16200,7 +16200,7 @@ "baseStats": { "energy_shield": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus09.webp", + "imageUrl": "/images/base/runed_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16225,7 +16225,7 @@ "energy_shield": 11, "runic_ward": 134 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr04.webp", + "imageUrl": "/images/base/runeforged_adherent_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16249,7 +16249,7 @@ "energy_shield": 107, "runic_ward": 138 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt07.webp", + "imageUrl": "/images/base/runeforged_adherents_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -16274,7 +16274,7 @@ "energy_shield": 20, "runic_ward": 39 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt03.webp", + "imageUrl": "/images/base/runeforged_adorned_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16297,7 +16297,7 @@ "baseStats": { "runic_ward": 141 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler13.webp", + "imageUrl": "/images/base/runeforged_aegis_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16322,7 +16322,7 @@ "energy_shield": 10, "runic_ward": 17 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr02.webp", + "imageUrl": "/images/base/runeforged_aged_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16346,7 +16346,7 @@ "energy_shield": 95, "runic_ward": 75 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt08.webp", + "imageUrl": "/images/base/runeforged_altar_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -16371,7 +16371,7 @@ "evasion": 194, "runic_ward": 86 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex08.webp", + "imageUrl": "/images/base/runeforged_ancestral_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -16395,7 +16395,7 @@ "energy_shield": 47, "runic_ward": 240 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt08.webp", + "imageUrl": "/images/base/runeforged_ancestral_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -16420,7 +16420,7 @@ "energy_shield": 46, "runic_ward": 74 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt05.webp", + "imageUrl": "/images/base/runeforged_anchorite_garb.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -16444,7 +16444,7 @@ "evasion": 155, "runic_ward": 35 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler08.webp", + "imageUrl": "/images/base/runeforged_ancient_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16469,7 +16469,7 @@ "energy_shield": 18, "runic_ward": 63 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr02.webp", + "imageUrl": "/images/base/runeforged_ancient_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16493,7 +16493,7 @@ "armour": 110, "runic_ward": 48 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr04.webp", + "imageUrl": "/images/base/runeforged_ancient_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16517,7 +16517,7 @@ "energy_shield": 18, "runic_ward": 17 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus03.webp", + "imageUrl": "/images/base/runeforged_antler_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16542,7 +16542,7 @@ "energy_shield": 25, "runic_ward": 116 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr02.webp", + "imageUrl": "/images/base/runeforged_apostle_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16565,7 +16565,7 @@ "baseStats": { "runic_ward": 122 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler12.webp", + "imageUrl": "/images/base/runeforged_array_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16589,7 +16589,7 @@ "energy_shield": 43, "runic_ward": 45 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus06.webp", + "imageUrl": "/images/base/runeforged_arrayed_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16614,7 +16614,7 @@ "energy_shield": 63, "runic_ward": 87 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt08.webp", + "imageUrl": "/images/base/runeforged_ascetic_garb.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -16637,7 +16637,7 @@ "baseStats": { "runic_ward": 157 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus01.webp", + "imageUrl": "/images/base/runeforged_attuned_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16662,7 +16662,7 @@ "energy_shield": 75, "runic_ward": 86 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt08.webp", + "imageUrl": "/images/base/runeforged_austere_garb.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -16687,7 +16687,7 @@ "energy_shield": 39, "runic_ward": 91 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt05.webp", + "imageUrl": "/images/base/runeforged_avian_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -16712,7 +16712,7 @@ "evasion": 78, "runic_ward": 59 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield06.webp", + "imageUrl": "/images/base/runeforged_avian_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16736,7 +16736,7 @@ "evasion": 148, "runic_ward": 35 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex05.webp", + "imageUrl": "/images/base/runeforged_barbed_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16757,7 +16757,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear07.webp", + "imageUrl": "/images/base/runeforged_barbed_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -16781,7 +16781,7 @@ "energy_shield": 34, "runic_ward": 36 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt04.webp", + "imageUrl": "/images/base/runeforged_baroque_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16806,7 +16806,7 @@ "evasion": 78, "runic_ward": 106 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield04.webp", + "imageUrl": "/images/base/runeforged_baroque_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16830,7 +16830,7 @@ "armour": 62, "runic_ward": 22 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower04.webp", + "imageUrl": "/images/base/runeforged_barricade_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16855,7 +16855,7 @@ "evasion": 107, "runic_ward": 39 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex03.webp", + "imageUrl": "/images/base/runeforged_bastion_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16879,7 +16879,7 @@ "energy_shield": 35, "runic_ward": 35 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt03.webp", + "imageUrl": "/images/base/runeforged_beaded_circlet.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -16904,7 +16904,7 @@ "energy_shield": 15, "runic_ward": 194 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest07.webp", + "imageUrl": "/images/base/runeforged_blacksteel_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16929,7 +16929,7 @@ "evasion": 33, "runic_ward": 141 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex04.webp", + "imageUrl": "/images/base/runeforged_blacksteel_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16954,7 +16954,7 @@ "evasion": 59, "runic_ward": 190 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex04.webp", + "imageUrl": "/images/base/runeforged_blacksteel_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -16978,7 +16978,7 @@ "evasion": 111, "runic_ward": 47 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler08.webp", + "imageUrl": "/images/base/runeforged_bladeguard_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -17003,7 +17003,7 @@ "energy_shield": 6, "runic_ward": 12 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest01.webp", + "imageUrl": "/images/base/runeforged_blazon_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -17027,7 +17027,7 @@ "armour": 75, "runic_ward": 21 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr04.webp", + "imageUrl": "/images/base/runeforged_bolstered_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -17048,7 +17048,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow07.webp", + "imageUrl": "/images/base/runeforged_bombard_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -17072,7 +17072,7 @@ "energy_shield": 54, "runic_ward": 53 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt04.webp", + "imageUrl": "/images/base/runeforged_bone_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -17096,7 +17096,7 @@ "evasion": 42, "runic_ward": 17 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex03.webp", + "imageUrl": "/images/base/runeforged_bound_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -17121,7 +17121,7 @@ "energy_shield": 23, "runic_ward": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr01.webp", + "imageUrl": "/images/base/runeforged_bound_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -17145,7 +17145,7 @@ "energy_shield": 64, "runic_ward": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt02.webp", + "imageUrl": "/images/base/runeforged_bound_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -17170,7 +17170,7 @@ "evasion": 35, "runic_ward": 26 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex02.webp", + "imageUrl": "/images/base/runeforged_braced_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -17194,7 +17194,7 @@ "armour": 50, "runic_ward": 18 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower03.webp", + "imageUrl": "/images/base/runeforged_braced_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -17219,7 +17219,7 @@ "energy_shield": 49, "runic_ward": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt02.webp", + "imageUrl": "/images/base/runeforged_brigand_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -17244,7 +17244,7 @@ "evasion": 20, "runic_ward": 26 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex01.webp", + "imageUrl": "/images/base/runeforged_brimmed_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -17268,7 +17268,7 @@ "armour": 74, "runic_ward": 26 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr03.webp", + "imageUrl": "/images/base/runeforged_bronze_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -17293,7 +17293,7 @@ "energy_shield": 19, "runic_ward": 27 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt04.webp", + "imageUrl": "/images/base/runeforged_buckled_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -17317,7 +17317,7 @@ "armour": 229, "runic_ward": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr02.webp", + "imageUrl": "/images/base/runeforged_bulwark_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -17341,7 +17341,7 @@ "armour": 144, "runic_ward": 53 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower06.webp", + "imageUrl": "/images/base/runeforged_bulwark_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -17366,7 +17366,7 @@ "evasion": 109, "runic_ward": 96 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex04.webp", + "imageUrl": "/images/base/runeforged_cabalist_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -17390,7 +17390,7 @@ "armour": 178, "runic_ward": 78 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr05.webp", + "imageUrl": "/images/base/runeforged_carved_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -17415,7 +17415,7 @@ "evasion": 81, "runic_ward": 40 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield08.webp", + "imageUrl": "/images/base/runeforged_carved_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -17439,7 +17439,7 @@ "evasion": 146, "runic_ward": 116 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex04.webp", + "imageUrl": "/images/base/runeforged_cavalry_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -17463,7 +17463,7 @@ "energy_shield": 117, "runic_ward": 103 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt08.webp", + "imageUrl": "/images/base/runeforged_ceremonial_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -17488,7 +17488,7 @@ "evasion": 16, "runic_ward": 29 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex01.webp", + "imageUrl": "/images/base/runeforged_chain_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -17512,7 +17512,7 @@ "energy_shield": 47, "runic_ward": 48 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt04.webp", + "imageUrl": "/images/base/runeforged_chain_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -17537,7 +17537,7 @@ "evasion": 169, "runic_ward": 56 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex05.webp", + "imageUrl": "/images/base/runeforged_champion_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -17558,7 +17558,7 @@ "int": 32 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/ChangelingTalisman.webp", + "imageUrl": "/images/base/runeforged_changeling_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -17583,7 +17583,7 @@ "energy_shield": 25, "runic_ward": 116 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt02.webp", + "imageUrl": "/images/base/runeforged_charmed_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -17607,7 +17607,7 @@ "armour": 390, "runic_ward": 69 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr10.webp", + "imageUrl": "/images/base/runeforged_chieftain_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -17632,7 +17632,7 @@ "evasion": 54, "runic_ward": 33 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield05.webp", + "imageUrl": "/images/base/runeforged_chiseled_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -17656,7 +17656,7 @@ "evasion": 209, "runic_ward": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex02.webp", + "imageUrl": "/images/base/runeforged_cinched_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -17681,7 +17681,7 @@ "energy_shield": 57, "runic_ward": 85 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr07.webp", + "imageUrl": "/images/base/runeforged_cleric_vestments.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -17706,7 +17706,7 @@ "evasion": 107, "runic_ward": 73 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex04.webp", + "imageUrl": "/images/base/runeforged_cloaked_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -17731,7 +17731,7 @@ "evasion": 115, "runic_ward": 52 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex06.webp", + "imageUrl": "/images/base/runeforged_closed_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -17756,7 +17756,7 @@ "evasion": 60, "runic_ward": 63 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex02.webp", + "imageUrl": "/images/base/runeforged_commander_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -17780,7 +17780,7 @@ "armour": 233, "runic_ward": 56 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr07.webp", + "imageUrl": "/images/base/runeforged_commander_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -17801,7 +17801,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow05.webp", + "imageUrl": "/images/base/runeforged_composite_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -17826,7 +17826,7 @@ "energy_shield": 68, "runic_ward": 107 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr04.webp", + "imageUrl": "/images/base/runeforged_conjurer_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -17849,7 +17849,7 @@ "baseStats": { "armour": 595 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr01.webp", + "imageUrl": "/images/base/runeforged_conqueror_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -17873,7 +17873,7 @@ "evasion": 210, "runic_ward": 56 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex07.webp", + "imageUrl": "/images/base/runeforged_corsair_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -17897,7 +17897,7 @@ "evasion": 406, "runic_ward": 107 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex10.webp", + "imageUrl": "/images/base/runeforged_corsair_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -17921,7 +17921,7 @@ "evasion": 320, "runic_ward": 76 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex09.webp", + "imageUrl": "/images/base/runeforged_corsair_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -17946,7 +17946,7 @@ "evasion": 86, "runic_ward": 39 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex04.webp", + "imageUrl": "/images/base/runeforged_covered_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -17971,7 +17971,7 @@ "evasion": 70, "runic_ward": 41 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex04.webp", + "imageUrl": "/images/base/runeforged_cowled_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -17992,7 +17992,7 @@ "int": 23 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff05.webp", + "imageUrl": "/images/base/runeforged_crescent_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -18017,7 +18017,7 @@ "evasion": 44, "runic_ward": 30 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield04.webp", + "imageUrl": "/images/base/runeforged_crescent_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -18041,7 +18041,7 @@ "armour": 145, "runic_ward": 36 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower09.webp", + "imageUrl": "/images/base/runeforged_crucible_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -18062,7 +18062,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow01.webp", + "imageUrl": "/images/base/runeforged_crude_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -18083,7 +18083,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace08.webp", + "imageUrl": "/images/base/runeforged_crumbling_maul.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -18108,7 +18108,7 @@ "energy_shield": 24, "runic_ward": 254 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr06.webp", + "imageUrl": "/images/base/runeforged_cryptic_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -18133,7 +18133,7 @@ "evasion": 140, "runic_ward": 85 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex04.webp", + "imageUrl": "/images/base/runeforged_cryptic_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -18158,7 +18158,7 @@ "energy_shield": 16, "runic_ward": 201 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr04.webp", + "imageUrl": "/images/base/runeforged_cryptic_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -18182,7 +18182,7 @@ "energy_shield": 29, "runic_ward": 25 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus06.webp", + "imageUrl": "/images/base/runeforged_crystal_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -18207,7 +18207,7 @@ "energy_shield": 19, "runic_ward": 35 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr03.webp", + "imageUrl": "/images/base/runeforged_cultist_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -18231,7 +18231,7 @@ "energy_shield": 50, "runic_ward": 32 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus07.webp", + "imageUrl": "/images/base/runeforged_cultist_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -18256,7 +18256,7 @@ "evasion": 81, "runic_ward": 35 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex03.webp", + "imageUrl": "/images/base/runeforged_cultist_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -18277,7 +18277,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace05.webp", + "imageUrl": "/images/base/runeforged_cultist_greathammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -18302,7 +18302,7 @@ "energy_shield": 17, "runic_ward": 194 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt04.webp", + "imageUrl": "/images/base/runeforged_daggerfoot_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -18327,7 +18327,7 @@ "evasion": 164, "runic_ward": 236 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex02.webp", + "imageUrl": "/images/base/runeforged_dastard_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -18352,7 +18352,7 @@ "evasion": 109, "runic_ward": 408 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex06.webp", + "imageUrl": "/images/base/runeforged_death_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -18377,7 +18377,7 @@ "energy_shield": 53, "runic_ward": 215 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr06.webp", + "imageUrl": "/images/base/runeforged_death_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -18401,7 +18401,7 @@ "evasion": 227, "runic_ward": 91 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex05.webp", + "imageUrl": "/images/base/runeforged_deerstalker_hood.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -18426,7 +18426,7 @@ "energy_shield": 22, "runic_ward": 53 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest04.webp", + "imageUrl": "/images/base/runeforged_dekharan_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -18450,7 +18450,7 @@ "evasion": 87, "runic_ward": 134 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler09.webp", + "imageUrl": "/images/base/runeforged_desert_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -18474,7 +18474,7 @@ "evasion": 243, "runic_ward": 99 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex04.webp", + "imageUrl": "/images/base/runeforged_desert_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -18498,7 +18498,7 @@ "armour": 116, "runic_ward": 26 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr06.webp", + "imageUrl": "/images/base/runeforged_detailed_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -18523,7 +18523,7 @@ "energy_shield": 52, "runic_ward": 56 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr05.webp", + "imageUrl": "/images/base/runeforged_divine_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -18548,7 +18548,7 @@ "evasion": 43, "runic_ward": 24 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex03.webp", + "imageUrl": "/images/base/runeforged_doubled_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -18572,7 +18572,7 @@ "evasion": 222, "runic_ward": 53 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex05.webp", + "imageUrl": "/images/base/runeforged_dragonscale_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -18596,7 +18596,7 @@ "evasion": 124, "runic_ward": 169 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex06.webp", + "imageUrl": "/images/base/runeforged_drakeskin_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -18621,7 +18621,7 @@ "energy_shield": 47, "runic_ward": 56 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr02.webp", + "imageUrl": "/images/base/runeforged_druidic_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -18645,7 +18645,7 @@ "energy_shield": 55, "runic_ward": 62 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus03.webp", + "imageUrl": "/images/base/runeforged_druidic_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -18666,7 +18666,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow06.webp", + "imageUrl": "/images/base/runeforged_dualstring_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -18690,7 +18690,7 @@ "energy_shield": 58, "runic_ward": 49 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt05.webp", + "imageUrl": "/images/base/runeforged_dunerunner_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -18711,7 +18711,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow05.webp", + "imageUrl": "/images/base/runeforged_dyad_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -18735,7 +18735,7 @@ "evasion": 92, "runic_ward": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler08.webp", + "imageUrl": "/images/base/runeforged_edged_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -18759,7 +18759,7 @@ "armour": 76, "runic_ward": 25 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower05.webp", + "imageUrl": "/images/base/runeforged_effigial_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -18782,7 +18782,7 @@ "baseStats": { "runic_ward": 146 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus01.webp", + "imageUrl": "/images/base/runeforged_elegant_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -18806,7 +18806,7 @@ "armour": 252, "runic_ward": 60 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr04.webp", + "imageUrl": "/images/base/runeforged_elegant_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -18830,7 +18830,7 @@ "armour": 189, "runic_ward": 45 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr04.webp", + "imageUrl": "/images/base/runeforged_elegant_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -18854,7 +18854,7 @@ "armour": 401, "runic_ward": 73 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr06.webp", + "imageUrl": "/images/base/runeforged_elegant_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -18878,7 +18878,7 @@ "energy_shield": 51, "runic_ward": 54 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt04.webp", + "imageUrl": "/images/base/runeforged_elegant_slippers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -18903,7 +18903,7 @@ "energy_shield": 18, "runic_ward": 63 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt02.webp", + "imageUrl": "/images/base/runeforged_elegant_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -18927,7 +18927,7 @@ "energy_shield": 103, "runic_ward": 76 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt09.webp", + "imageUrl": "/images/base/runeforged_elementalist_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -18951,7 +18951,7 @@ "armour": 177, "runic_ward": 49 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr05.webp", + "imageUrl": "/images/base/runeforged_elite_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -18976,7 +18976,7 @@ "energy_shield": 12, "runic_ward": 22 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest03.webp", + "imageUrl": "/images/base/runeforged_emblem_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -19000,7 +19000,7 @@ "evasion": 63, "runic_ward": 26 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex03.webp", + "imageUrl": "/images/base/runeforged_embossed_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -19024,7 +19024,7 @@ "evasion": 133, "runic_ward": 35 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex01.webp", + "imageUrl": "/images/base/runeforged_engraved_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -19048,7 +19048,7 @@ "energy_shield": 22, "runic_ward": 22 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus04.webp", + "imageUrl": "/images/base/runeforged_engraved_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -19073,7 +19073,7 @@ "evasion": 132, "runic_ward": 74 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex05.webp", + "imageUrl": "/images/base/runeforged_explorer_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -19098,7 +19098,7 @@ "energy_shield": 16, "runic_ward": 30 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt02.webp", + "imageUrl": "/images/base/runeforged_face_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -19123,7 +19123,7 @@ "energy_shield": 35, "runic_ward": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr01.webp", + "imageUrl": "/images/base/runeforged_faithful_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -19148,7 +19148,7 @@ "energy_shield": 57, "runic_ward": 189 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt06.webp", + "imageUrl": "/images/base/runeforged_falconers_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -19169,7 +19169,7 @@ "int": 32 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/FamilialTalisman.webp", + "imageUrl": "/images/base/runeforged_familial_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -19194,7 +19194,7 @@ "energy_shield": 41, "runic_ward": 99 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt04.webp", + "imageUrl": "/images/base/runeforged_faridun_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -19218,7 +19218,7 @@ "armour": 137, "runic_ward": 32 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr05.webp", + "imageUrl": "/images/base/runeforged_feathered_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -19242,7 +19242,7 @@ "energy_shield": 132, "runic_ward": 133 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt10.webp", + "imageUrl": "/images/base/runeforged_feathered_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -19266,7 +19266,7 @@ "energy_shield": 35, "runic_ward": 35 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt02.webp", + "imageUrl": "/images/base/runeforged_feathered_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -19290,7 +19290,7 @@ "energy_shield": 41, "runic_ward": 36 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt05.webp", + "imageUrl": "/images/base/runeforged_feathered_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -19315,7 +19315,7 @@ "evasion": 60, "runic_ward": 34 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield06.webp", + "imageUrl": "/images/base/runeforged_feathered_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -19339,7 +19339,7 @@ "energy_shield": 54, "runic_ward": 49 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt05.webp", + "imageUrl": "/images/base/runeforged_feathered_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -19360,7 +19360,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace01.webp", + "imageUrl": "/images/base/runeforged_felled_greatclub.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -19384,7 +19384,7 @@ "evasion": 58, "runic_ward": 27 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex02.webp", + "imageUrl": "/images/base/runeforged_felt_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -19408,7 +19408,7 @@ "armour": 260, "runic_ward": 57 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr08.webp", + "imageUrl": "/images/base/runeforged_fierce_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -19432,7 +19432,7 @@ "evasion": 105, "runic_ward": 26 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex06.webp", + "imageUrl": "/images/base/runeforged_fine_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -19456,7 +19456,7 @@ "evasion": 31, "runic_ward": 16 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex02.webp", + "imageUrl": "/images/base/runeforged_firm_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -19480,7 +19480,7 @@ "evasion": 157, "runic_ward": 39 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex06.webp", + "imageUrl": "/images/base/runeforged_flared_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -19504,7 +19504,7 @@ "energy_shield": 51, "runic_ward": 39 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt06.webp", + "imageUrl": "/images/base/runeforged_flax_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -19528,7 +19528,7 @@ "energy_shield": 91, "runic_ward": 236 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt06.webp", + "imageUrl": "/images/base/runeforged_flowing_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -19549,7 +19549,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace03.webp", + "imageUrl": "/images/base/runeforged_forge_maul.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -19570,7 +19570,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear06.webp", + "imageUrl": "/images/base/runeforged_forked_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -19595,7 +19595,7 @@ "evasion": 117, "runic_ward": 63 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex03.webp", + "imageUrl": "/images/base/runeforged_fortress_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -19619,7 +19619,7 @@ "armour": 156, "runic_ward": 106 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower06.webp", + "imageUrl": "/images/base/runeforged_fortress_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -19644,7 +19644,7 @@ "energy_shield": 10, "runic_ward": 17 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt01.webp", + "imageUrl": "/images/base/runeforged_frayed_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -19668,7 +19668,7 @@ "evasion": 154, "runic_ward": 240 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex07.webp", + "imageUrl": "/images/base/runeforged_freebooter_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -19692,7 +19692,7 @@ "armour": 270, "runic_ward": 69 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr07.webp", + "imageUrl": "/images/base/runeforged_full_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -19716,7 +19716,7 @@ "armour": 66, "runic_ward": 33 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr02.webp", + "imageUrl": "/images/base/runeforged_fur_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -19741,7 +19741,7 @@ "energy_shield": 6, "runic_ward": 11 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt01.webp", + "imageUrl": "/images/base/runeforged_gauze_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -19766,7 +19766,7 @@ "evasion": 137, "runic_ward": 65 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex05.webp", + "imageUrl": "/images/base/runeforged_gladiatorial_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -19791,7 +19791,7 @@ "energy_shield": 26, "runic_ward": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr03.webp", + "imageUrl": "/images/base/runeforged_gleaming_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -19816,7 +19816,7 @@ "energy_shield": 24, "runic_ward": 59 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest06.webp", + "imageUrl": "/images/base/runeforged_glowering_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -19840,7 +19840,7 @@ "energy_shield": 62, "runic_ward": 55 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt06.webp", + "imageUrl": "/images/base/runeforged_gold_circlet.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -19864,7 +19864,7 @@ "energy_shield": 33, "runic_ward": 52 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt05.webp", + "imageUrl": "/images/base/runeforged_gold_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -19889,7 +19889,7 @@ "energy_shield": 15, "runic_ward": 24 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr03.webp", + "imageUrl": "/images/base/runeforged_goldcast_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -19914,7 +19914,7 @@ "evasion": 214, "runic_ward": 124 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex06.webp", + "imageUrl": "/images/base/runeforged_golden_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -19939,7 +19939,7 @@ "evasion": 52, "runic_ward": 185 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield10.webp", + "imageUrl": "/images/base/runeforged_golden_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -19963,7 +19963,7 @@ "armour": 153, "runic_ward": 58 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower08.webp", + "imageUrl": "/images/base/runeforged_goldworked_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -19984,7 +19984,7 @@ "int": 23 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff03.webp", + "imageUrl": "/images/base/runeforged_gothic_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20008,7 +20008,7 @@ "evasion": 109, "runic_ward": 63 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex04.webp", + "imageUrl": "/images/base/runeforged_grand_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -20034,7 +20034,7 @@ "energy_shield": 50, "runic_ward": 215 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr01.webp", + "imageUrl": "/images/base/runeforged_grand_regalia.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20059,7 +20059,7 @@ "energy_shield": 64, "runic_ward": 107 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDexInt03.webp", + "imageUrl": "/images/base/runeforged_grasping_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20083,7 +20083,7 @@ "energy_shield": 42, "runic_ward": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt02.webp", + "imageUrl": "/images/base/runeforged_grim_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -20108,7 +20108,7 @@ "energy_shield": 24, "runic_ward": 254 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt06.webp", + "imageUrl": "/images/base/runeforged_grinning_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20133,7 +20133,7 @@ "evasion": 34, "runic_ward": 32 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex02.webp", + "imageUrl": "/images/base/runeforged_guarded_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20157,7 +20157,7 @@ "evasion": 114, "runic_ward": 85 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler06.webp", + "imageUrl": "/images/base/runeforged_gutspike_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -20182,7 +20182,7 @@ "energy_shield": 36, "runic_ward": 84 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr04.webp", + "imageUrl": "/images/base/runeforged_hallowed_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20206,7 +20206,7 @@ "energy_shield": 43, "runic_ward": 58 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus08.webp", + "imageUrl": "/images/base/runeforged_hallowed_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -20227,7 +20227,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear01.webp", + "imageUrl": "/images/base/runeforged_hardwood_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20252,7 +20252,7 @@ "evasion": 7, "runic_ward": 12 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield01.webp", + "imageUrl": "/images/base/runeforged_hardwood_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -20277,7 +20277,7 @@ "energy_shield": 56, "runic_ward": 158 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt05.webp", + "imageUrl": "/images/base/runeforged_hatungo_garb.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20302,7 +20302,7 @@ "energy_shield": 64, "runic_ward": 103 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt06.webp", + "imageUrl": "/images/base/runeforged_hawkers_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20327,7 +20327,7 @@ "energy_shield": 64, "runic_ward": 103 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr06.webp", + "imageUrl": "/images/base/runeforged_heartcarver_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20352,7 +20352,7 @@ "energy_shield": 30, "runic_ward": 44 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr05.webp", + "imageUrl": "/images/base/runeforged_heavy_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20376,7 +20376,7 @@ "armour": 363, "runic_ward": 158 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr07.webp", + "imageUrl": "/images/base/runeforged_heavy_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20400,7 +20400,7 @@ "armour": 111, "runic_ward": 30 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower07.webp", + "imageUrl": "/images/base/runeforged_heraldric_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -20425,7 +20425,7 @@ "energy_shield": 16, "runic_ward": 29 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt01.webp", + "imageUrl": "/images/base/runeforged_hermit_garb.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20450,7 +20450,7 @@ "energy_shield": 13, "runic_ward": 26 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt01.webp", + "imageUrl": "/images/base/runeforged_hewn_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20474,7 +20474,7 @@ "energy_shield": 45, "runic_ward": 43 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt03.webp", + "imageUrl": "/images/base/runeforged_hexers_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20499,7 +20499,7 @@ "energy_shield": 19, "runic_ward": 35 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt03.webp", + "imageUrl": "/images/base/runeforged_hooded_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20524,7 +20524,7 @@ "energy_shield": 16, "runic_ward": 30 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr02.webp", + "imageUrl": "/images/base/runeforged_horned_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20548,7 +20548,7 @@ "evasion": 158, "runic_ward": 49 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex05.webp", + "imageUrl": "/images/base/runeforged_hunter_hood.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20573,7 +20573,7 @@ "energy_shield": 22, "runic_ward": 34 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt03.webp", + "imageUrl": "/images/base/runeforged_hunting_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -20594,7 +20594,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear03.webp", + "imageUrl": "/images/base/runeforged_hunting_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20618,7 +20618,7 @@ "armour": 169, "runic_ward": 240 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr07.webp", + "imageUrl": "/images/base/runeforged_imperial_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20643,7 +20643,7 @@ "energy_shield": 44, "runic_ward": 52 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr05.webp", + "imageUrl": "/images/base/runeforged_inquisitor_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20668,7 +20668,7 @@ "energy_shield": 29, "runic_ward": 44 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest02.webp", + "imageUrl": "/images/base/runeforged_intricate_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -20692,7 +20692,7 @@ "energy_shield": 27, "runic_ward": 22 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt05.webp", + "imageUrl": "/images/base/runeforged_intricate_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -20716,7 +20716,7 @@ "evasion": 42, "runic_ward": 17 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler04.webp", + "imageUrl": "/images/base/runeforged_iron_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -20741,7 +20741,7 @@ "energy_shield": 13, "runic_ward": 26 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr01.webp", + "imageUrl": "/images/base/runeforged_iron_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20765,7 +20765,7 @@ "armour": 115, "runic_ward": 43 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr03.webp", + "imageUrl": "/images/base/runeforged_iron_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20789,7 +20789,7 @@ "armour": 57, "runic_ward": 21 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr02.webp", + "imageUrl": "/images/base/runeforged_iron_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -20814,7 +20814,7 @@ "energy_shield": 46, "runic_ward": 74 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr05.webp", + "imageUrl": "/images/base/runeforged_ironclad_vestments.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20835,7 +20835,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear02.webp", + "imageUrl": "/images/base/runeforged_ironhead_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20860,7 +20860,7 @@ "energy_shield": 60, "runic_ward": 92 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt04.webp", + "imageUrl": "/images/base/runeforged_itinerant_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20884,7 +20884,7 @@ "energy_shield": 73, "runic_ward": 56 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt08.webp", + "imageUrl": "/images/base/runeforged_jade_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -20908,7 +20908,7 @@ "energy_shield": 23, "runic_ward": 20 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt04.webp", + "imageUrl": "/images/base/runeforged_jewelled_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -20932,7 +20932,7 @@ "evasion": 124, "runic_ward": 32 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler07.webp", + "imageUrl": "/images/base/runeforged_jingling_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -20957,7 +20957,7 @@ "energy_shield": 17, "runic_ward": 31 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest04.webp", + "imageUrl": "/images/base/runeforged_jingling_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -20981,7 +20981,7 @@ "armour": 355, "runic_ward": 76 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr09.webp", + "imageUrl": "/images/base/runeforged_juggernaut_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21005,7 +21005,7 @@ "energy_shield": 67, "runic_ward": 104 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt05.webp", + "imageUrl": "/images/base/runeforged_jungle_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21030,7 +21030,7 @@ "energy_shield": 19, "runic_ward": 27 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr04.webp", + "imageUrl": "/images/base/runeforged_kalguuran_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -21051,7 +21051,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace01.webp", + "imageUrl": "/images/base/runeforged_kalguuran_forgehammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21075,7 +21075,7 @@ "energy_shield": 97, "runic_ward": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt05.webp", + "imageUrl": "/images/base/runeforged_kamasan_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21099,7 +21099,7 @@ "energy_shield": 74, "runic_ward": 66 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt06.webp", + "imageUrl": "/images/base/runeforged_keth_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21124,7 +21124,7 @@ "evasion": 176, "runic_ward": 85 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex07.webp", + "imageUrl": "/images/base/runeforged_knight_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21148,7 +21148,7 @@ "armour": 153, "runic_ward": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr02.webp", + "imageUrl": "/images/base/runeforged_knightly_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -21172,7 +21172,7 @@ "evasion": 84, "runic_ward": 35 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex03.webp", + "imageUrl": "/images/base/runeforged_lace_hood.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21196,7 +21196,7 @@ "evasion": 47, "runic_ward": 21 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex02.webp", + "imageUrl": "/images/base/runeforged_laced_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -21220,7 +21220,7 @@ "evasion": 105, "runic_ward": 29 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler09.webp", + "imageUrl": "/images/base/runeforged_laminate_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -21244,7 +21244,7 @@ "energy_shield": 27, "runic_ward": 26 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt03.webp", + "imageUrl": "/images/base/runeforged_lattice_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -21269,7 +21269,7 @@ "evasion": 23, "runic_ward": 17 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex02.webp", + "imageUrl": "/images/base/runeforged_layered_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -21293,7 +21293,7 @@ "evasion": 364, "runic_ward": 73 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex06.webp", + "imageUrl": "/images/base/runeforged_layered_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21314,7 +21314,7 @@ "int": 50 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace07.webp", + "imageUrl": "/images/base/runeforged_leaden_greathammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21338,7 +21338,7 @@ "evasion": 10, "runic_ward": 10 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler01.webp", + "imageUrl": "/images/base/runeforged_leather_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -21362,7 +21362,7 @@ "evasion": 30, "runic_ward": 29 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex01.webp", + "imageUrl": "/images/base/runeforged_leather_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21386,7 +21386,7 @@ "evasion": 231, "runic_ward": 56 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex08.webp", + "imageUrl": "/images/base/runeforged_leatherbound_hood.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21410,7 +21410,7 @@ "energy_shield": 47, "runic_ward": 114 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus06.webp", + "imageUrl": "/images/base/runeforged_leyline_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -21435,7 +21435,7 @@ "energy_shield": 10, "runic_ward": 17 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt02.webp", + "imageUrl": "/images/base/runeforged_linen_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -21459,7 +21459,7 @@ "evasion": 118, "runic_ward": 36 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex05.webp", + "imageUrl": "/images/base/runeforged_lizardscale_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -21483,7 +21483,7 @@ "evasion": 345, "runic_ward": 144 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex08.webp", + "imageUrl": "/images/base/runeforged_lizardscale_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21504,7 +21504,7 @@ "int": 23 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff02.webp", + "imageUrl": "/images/base/runeforged_long_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21528,7 +21528,7 @@ "energy_shield": 45, "runic_ward": 116 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt04.webp", + "imageUrl": "/images/base/runeforged_luxurious_slippers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -21551,7 +21551,7 @@ "baseStats": { "runic_ward": 176 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus01.webp", + "imageUrl": "/images/base/runeforged_magus_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -21576,7 +21576,7 @@ "evasion": 17, "runic_ward": 18 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex01.webp", + "imageUrl": "/images/base/runeforged_mail_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -21601,7 +21601,7 @@ "energy_shield": 30, "runic_ward": 53 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr03.webp", + "imageUrl": "/images/base/runeforged_mail_vestments.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21622,7 +21622,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow01.webp", + "imageUrl": "/images/base/runeforged_makeshift_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21647,7 +21647,7 @@ "evasion": 97, "runic_ward": 44 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield02.webp", + "imageUrl": "/images/base/runeforged_mammoth_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -21672,7 +21672,7 @@ "evasion": 200, "runic_ward": 73 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex04.webp", + "imageUrl": "/images/base/runeforged_mantled_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21697,7 +21697,7 @@ "energy_shield": 30, "runic_ward": 53 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt03.webp", + "imageUrl": "/images/base/runeforged_marabout_garb.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21721,7 +21721,7 @@ "armour": 178, "runic_ward": 61 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr05.webp", + "imageUrl": "/images/base/runeforged_maraketh_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21742,7 +21742,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace06.webp", + "imageUrl": "/images/base/runeforged_marching_mace.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21767,7 +21767,7 @@ "energy_shield": 27, "runic_ward": 43 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr04.webp", + "imageUrl": "/images/base/runeforged_martyr_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21791,7 +21791,7 @@ "armour": 279, "runic_ward": 85 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr04.webp", + "imageUrl": "/images/base/runeforged_masked_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21815,7 +21815,7 @@ "armour": 78, "runic_ward": 127 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr06.webp", + "imageUrl": "/images/base/runeforged_massive_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -21836,7 +21836,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace09.webp", + "imageUrl": "/images/base/runeforged_morning_star.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21860,7 +21860,7 @@ "armour": 89, "runic_ward": 22 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr05.webp", + "imageUrl": "/images/base/runeforged_moulded_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -21884,7 +21884,7 @@ "energy_shield": 110, "runic_ward": 68 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt10.webp", + "imageUrl": "/images/base/runeforged_mystic_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21905,7 +21905,7 @@ "int": 32 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/NettleTalisman.webp", + "imageUrl": "/images/base/runeforged_nettle_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21929,7 +21929,7 @@ "armour": 238, "runic_ward": 104 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr05.webp", + "imageUrl": "/images/base/runeforged_noble_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -21954,7 +21954,7 @@ "evasion": 87, "runic_ward": 116 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex02.webp", + "imageUrl": "/images/base/runeforged_noble_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -21978,7 +21978,7 @@ "armour": 171, "runic_ward": 41 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower07.webp", + "imageUrl": "/images/base/runeforged_noble_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22001,7 +22001,7 @@ "baseStats": { "aps": 1 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace02.webp", + "imageUrl": "/images/base/runeforged_oak_greathammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -22026,7 +22026,7 @@ "energy_shield": 55, "runic_ward": 128 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr04.webp", + "imageUrl": "/images/base/runeforged_occultist_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -22051,7 +22051,7 @@ "energy_shield": 20, "runic_ward": 34 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest06.webp", + "imageUrl": "/images/base/runeforged_omen_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22075,7 +22075,7 @@ "energy_shield": 33, "runic_ward": 63 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt04.webp", + "imageUrl": "/images/base/runeforged_opulent_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22098,7 +22098,7 @@ "baseStats": { "runic_ward": 117 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler11.webp", + "imageUrl": "/images/base/runeforged_ornate_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22123,7 +22123,7 @@ "energy_shield": 19, "runic_ward": 45 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr03.webp", + "imageUrl": "/images/base/runeforged_ornate_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22147,7 +22147,7 @@ "armour": 161, "runic_ward": 116 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr04.webp", + "imageUrl": "/images/base/runeforged_ornate_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22171,7 +22171,7 @@ "armour": 120, "runic_ward": 63 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr04.webp", + "imageUrl": "/images/base/runeforged_ornate_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22195,7 +22195,7 @@ "armour": 327, "runic_ward": 236 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr06.webp", + "imageUrl": "/images/base/runeforged_ornate_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -22220,7 +22220,7 @@ "energy_shield": 10, "runic_ward": 17 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr01.webp", + "imageUrl": "/images/base/runeforged_padded_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22244,7 +22244,7 @@ "armour": 33, "runic_ward": 15 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower02.webp", + "imageUrl": "/images/base/runeforged_painted_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22268,7 +22268,7 @@ "armour": 351, "runic_ward": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr05.webp", + "imageUrl": "/images/base/runeforged_paragon_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -22293,7 +22293,7 @@ "energy_shield": 39, "runic_ward": 60 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt04.webp", + "imageUrl": "/images/base/runeforged_pariah_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -22317,7 +22317,7 @@ "evasion": 96, "runic_ward": 43 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex03.webp", + "imageUrl": "/images/base/runeforged_pathfinder_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -22341,7 +22341,7 @@ "energy_shield": 34, "runic_ward": 26 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt06.webp", + "imageUrl": "/images/base/runeforged_pauascale_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22365,7 +22365,7 @@ "evasion": 116, "runic_ward": 29 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler10.webp", + "imageUrl": "/images/base/runeforged_pearl_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22390,7 +22390,7 @@ "evasion": 17, "runic_ward": 17 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield02.webp", + "imageUrl": "/images/base/runeforged_pelage_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22415,7 +22415,7 @@ "energy_shield": 22, "runic_ward": 34 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr03.webp", + "imageUrl": "/images/base/runeforged_pelt_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22440,7 +22440,7 @@ "energy_shield": 24, "runic_ward": 41 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr02.webp", + "imageUrl": "/images/base/runeforged_pelt_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -22465,7 +22465,7 @@ "energy_shield": 16, "runic_ward": 29 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr01.webp", + "imageUrl": "/images/base/runeforged_pilgrim_vestments.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -22490,7 +22490,7 @@ "evasion": 58, "runic_ward": 27 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex04.webp", + "imageUrl": "/images/base/runeforged_plate_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22514,7 +22514,7 @@ "evasion": 31, "runic_ward": 14 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler03.webp", + "imageUrl": "/images/base/runeforged_plated_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22539,7 +22539,7 @@ "energy_shield": 56, "runic_ward": 158 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr05.webp", + "imageUrl": "/images/base/runeforged_plated_vestments.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -22563,7 +22563,7 @@ "energy_shield": 36, "runic_ward": 30 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus08.webp", + "imageUrl": "/images/base/runeforged_plumed_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22584,7 +22584,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace09.webp", + "imageUrl": "/images/base/runeforged_pointed_maul.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -22608,7 +22608,7 @@ "evasion": 77, "runic_ward": 120 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex06.webp", + "imageUrl": "/images/base/runeforged_polished_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22633,7 +22633,7 @@ "evasion": 72, "runic_ward": 53 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield04.webp", + "imageUrl": "/images/base/runeforged_polished_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22658,7 +22658,7 @@ "energy_shield": 72, "runic_ward": 86 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt08.webp", + "imageUrl": "/images/base/runeforged_primal_markings.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -22683,7 +22683,7 @@ "energy_shield": 26, "runic_ward": 41 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest05.webp", + "imageUrl": "/images/base/runeforged_quartered_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22708,7 +22708,7 @@ "energy_shield": 40, "runic_ward": 32 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt03.webp", + "imageUrl": "/images/base/runeforged_quickslip_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22732,7 +22732,7 @@ "evasion": 49, "runic_ward": 33 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex02.webp", + "imageUrl": "/images/base/runeforged_quilted_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -22756,7 +22756,7 @@ "armour": 150, "runic_ward": 53 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr04.webp", + "imageUrl": "/images/base/runeforged_raider_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -22781,7 +22781,7 @@ "energy_shield": 68, "runic_ward": 107 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt04.webp", + "imageUrl": "/images/base/runeforged_rambler_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -22805,7 +22805,7 @@ "armour": 96, "runic_ward": 27 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower06.webp", + "imageUrl": "/images/base/runeforged_rampart_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22829,7 +22829,7 @@ "evasion": 15, "runic_ward": 14 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex01.webp", + "imageUrl": "/images/base/runeforged_rawhide_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22850,7 +22850,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow04.webp", + "imageUrl": "/images/base/runeforged_recurve_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -22874,7 +22874,7 @@ "armour": 174, "runic_ward": 39 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr06.webp", + "imageUrl": "/images/base/runeforged_reefsteel_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22898,7 +22898,7 @@ "evasion": 119, "runic_ward": 24 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex04.webp", + "imageUrl": "/images/base/runeforged_refined_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22922,7 +22922,7 @@ "evasion": 168, "runic_ward": 65 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex05.webp", + "imageUrl": "/images/base/runeforged_rhoahide_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -22946,7 +22946,7 @@ "evasion": 55, "runic_ward": 21 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler05.webp", + "imageUrl": "/images/base/runeforged_ridged_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22970,7 +22970,7 @@ "evasion": 79, "runic_ward": 24 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler07.webp", + "imageUrl": "/images/base/runeforged_ringed_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -22995,7 +22995,7 @@ "evasion": 11, "runic_ward": 12 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex01.webp", + "imageUrl": "/images/base/runeforged_ringmail_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -23019,7 +23019,7 @@ "energy_shield": 114, "runic_ward": 73 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt06.webp", + "imageUrl": "/images/base/runeforged_river_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23043,7 +23043,7 @@ "armour": 38, "runic_ward": 16 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr02.webp", + "imageUrl": "/images/base/runeforged_riveted_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -23068,7 +23068,7 @@ "evasion": 53, "runic_ward": 43 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex02.webp", + "imageUrl": "/images/base/runeforged_rogue_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23093,7 +23093,7 @@ "energy_shield": 6, "runic_ward": 11 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr01.webp", + "imageUrl": "/images/base/runeforged_rope_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -23117,7 +23117,7 @@ "armour": 22, "runic_ward": 14 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr01.webp", + "imageUrl": "/images/base/runeforged_rough_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -23141,7 +23141,7 @@ "armour": 193, "runic_ward": 44 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower03.webp", + "imageUrl": "/images/base/runeforged_royal_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -23165,7 +23165,7 @@ "energy_shield": 42, "runic_ward": 32 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus09.webp", + "imageUrl": "/images/base/runeforged_runed_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -23189,7 +23189,7 @@ "evasion": 362, "runic_ward": 119 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex07.webp", + "imageUrl": "/images/base/runeforged_runner_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23213,7 +23213,7 @@ "armour": 45, "runic_ward": 29 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr01.webp", + "imageUrl": "/images/base/runeforged_rusted_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23237,7 +23237,7 @@ "armour": 29, "runic_ward": 19 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr01.webp", + "imageUrl": "/images/base/runeforged_rusted_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23261,7 +23261,7 @@ "energy_shield": 142, "runic_ward": 64 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt08.webp", + "imageUrl": "/images/base/runeforged_sacramental_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23285,7 +23285,7 @@ "energy_shield": 68, "runic_ward": 53 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus08.webp", + "imageUrl": "/images/base/runeforged_sacred_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -23310,7 +23310,7 @@ "energy_shield": 48, "runic_ward": 77 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr06.webp", + "imageUrl": "/images/base/runeforged_sacrificial_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23335,7 +23335,7 @@ "energy_shield": 76, "runic_ward": 129 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDexInt02.webp", + "imageUrl": "/images/base/runeforged_sacrificial_regalia.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23360,7 +23360,7 @@ "energy_shield": 39, "runic_ward": 113 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr04.webp", + "imageUrl": "/images/base/runeforged_saintly_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23384,7 +23384,7 @@ "energy_shield": 69, "runic_ward": 49 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt05.webp", + "imageUrl": "/images/base/runeforged_sandsworn_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -23408,7 +23408,7 @@ "energy_shield": 75, "runic_ward": 48 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt04.webp", + "imageUrl": "/images/base/runeforged_sandsworn_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23433,7 +23433,7 @@ "evasion": 147, "runic_ward": 78 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex06.webp", + "imageUrl": "/images/base/runeforged_scale_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23458,7 +23458,7 @@ "energy_shield": 51, "runic_ward": 82 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt06.webp", + "imageUrl": "/images/base/runeforged_scalpers_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23483,7 +23483,7 @@ "energy_shield": 57, "runic_ward": 85 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt07.webp", + "imageUrl": "/images/base/runeforged_scoundrel_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23507,7 +23507,7 @@ "evasion": 240, "runic_ward": 69 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex07.webp", + "imageUrl": "/images/base/runeforged_scouts_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23532,7 +23532,7 @@ "energy_shield": 31, "runic_ward": 344 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr08.webp", + "imageUrl": "/images/base/runeforged_seastorm_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23557,7 +23557,7 @@ "energy_shield": 19, "runic_ward": 33 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest05.webp", + "imageUrl": "/images/base/runeforged_sectarian_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -23581,7 +23581,7 @@ "evasion": 68, "runic_ward": 22 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex04.webp", + "imageUrl": "/images/base/runeforged_sectioned_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -23606,7 +23606,7 @@ "energy_shield": 15, "runic_ward": 26 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr02.webp", + "imageUrl": "/images/base/runeforged_secured_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -23631,7 +23631,7 @@ "energy_shield": 10, "runic_ward": 138 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt04.webp", + "imageUrl": "/images/base/runeforged_secured_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -23656,7 +23656,7 @@ "energy_shield": 25, "runic_ward": 40 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest08.webp", + "imageUrl": "/images/base/runeforged_seer_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -23680,7 +23680,7 @@ "energy_shield": 34, "runic_ward": 184 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt06.webp", + "imageUrl": "/images/base/runeforged_sekhema_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -23705,7 +23705,7 @@ "energy_shield": 24, "runic_ward": 106 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest04.webp", + "imageUrl": "/images/base/runeforged_sekheman_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -23729,7 +23729,7 @@ "evasion": 170, "runic_ward": 68 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex05.webp", + "imageUrl": "/images/base/runeforged_serpentscale_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -23753,7 +23753,7 @@ "evasion": 260, "runic_ward": 69 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex08.webp", + "imageUrl": "/images/base/runeforged_serpentscale_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23777,7 +23777,7 @@ "evasion": 19, "runic_ward": 19 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex01.webp", + "imageUrl": "/images/base/runeforged_shabby_hood.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23802,7 +23802,7 @@ "energy_shield": 41, "runic_ward": 77 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr04.webp", + "imageUrl": "/images/base/runeforged_shaman_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23827,7 +23827,7 @@ "energy_shield": 32, "runic_ward": 49 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr03.webp", + "imageUrl": "/images/base/runeforged_shamanistic_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -23852,7 +23852,7 @@ "evasion": 87, "runic_ward": 44 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex05.webp", + "imageUrl": "/images/base/runeforged_shielded_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23873,7 +23873,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow02.webp", + "imageUrl": "/images/base/runeforged_shortbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23898,7 +23898,7 @@ "evasion": 223, "runic_ward": 107 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex04.webp", + "imageUrl": "/images/base/runeforged_shrouded_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23922,7 +23922,7 @@ "evasion": 128, "runic_ward": 53 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex04.webp", + "imageUrl": "/images/base/runeforged_shrouded_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23947,7 +23947,7 @@ "energy_shield": 9, "runic_ward": 16 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest02.webp", + "imageUrl": "/images/base/runeforged_sigil_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -23971,7 +23971,7 @@ "energy_shield": 64, "runic_ward": 65 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt05.webp", + "imageUrl": "/images/base/runeforged_silk_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -23995,7 +23995,7 @@ "energy_shield": 36, "runic_ward": 31 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt04.webp", + "imageUrl": "/images/base/runeforged_silk_slippers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24019,7 +24019,7 @@ "energy_shield": 21, "runic_ward": 128 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt06.webp", + "imageUrl": "/images/base/runeforged_sirenscale_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24043,7 +24043,7 @@ "energy_shield": 85, "runic_ward": 56 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt02.webp", + "imageUrl": "/images/base/runeforged_skycrown_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -24068,7 +24068,7 @@ "evasion": 199, "runic_ward": 107 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex01.webp", + "imageUrl": "/images/base/runeforged_slayer_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -24093,7 +24093,7 @@ "energy_shield": 35, "runic_ward": 395 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt02.webp", + "imageUrl": "/images/base/runeforged_sleek_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -24114,7 +24114,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace03.webp", + "imageUrl": "/images/base/runeforged_slim_mace.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -24138,7 +24138,7 @@ "evasion": 226, "runic_ward": 378 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex06.webp", + "imageUrl": "/images/base/runeforged_slipstrike_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -24162,7 +24162,7 @@ "evasion": 359, "runic_ward": 70 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex10.webp", + "imageUrl": "/images/base/runeforged_smuggler_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -24187,7 +24187,7 @@ "energy_shield": 52, "runic_ward": 56 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt05.webp", + "imageUrl": "/images/base/runeforged_soaring_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -24212,7 +24212,7 @@ "evasion": 103, "runic_ward": 53 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield06.webp", + "imageUrl": "/images/base/runeforged_soaring_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24236,7 +24236,7 @@ "armour": 258, "runic_ward": 365 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr03.webp", + "imageUrl": "/images/base/runeforged_soldier_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -24260,7 +24260,7 @@ "armour": 80, "runic_ward": 29 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr02.webp", + "imageUrl": "/images/base/runeforged_soldier_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -24285,7 +24285,7 @@ "energy_shield": 37, "runic_ward": 52 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt06.webp", + "imageUrl": "/images/base/runeforged_solid_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -24309,7 +24309,7 @@ "energy_shield": 15, "runic_ward": 17 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt02.webp", + "imageUrl": "/images/base/runeforged_sombre_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24333,7 +24333,7 @@ "energy_shield": 70, "runic_ward": 113 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt04.webp", + "imageUrl": "/images/base/runeforged_sorcerous_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -24357,7 +24357,7 @@ "evasion": 113, "runic_ward": 45 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex05.webp", + "imageUrl": "/images/base/runeforged_spiked_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24381,7 +24381,7 @@ "evasion": 64, "runic_ward": 20 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler06.webp", + "imageUrl": "/images/base/runeforged_spiked_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24402,7 +24402,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace04.webp", + "imageUrl": "/images/base/runeforged_spiked_club.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -24426,7 +24426,7 @@ "evasion": 104, "runic_ward": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler06.webp", + "imageUrl": "/images/base/runeforged_spikeward_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24450,7 +24450,7 @@ "evasion": 79, "runic_ward": 22 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex05.webp", + "imageUrl": "/images/base/runeforged_spined_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24475,7 +24475,7 @@ "energy_shield": 15, "runic_ward": 24 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt03.webp", + "imageUrl": "/images/base/runeforged_spiral_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24499,7 +24499,7 @@ "armour": 149, "runic_ward": 49 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr04.webp", + "imageUrl": "/images/base/runeforged_spired_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -24524,7 +24524,7 @@ "energy_shield": 37, "runic_ward": 52 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr06.webp", + "imageUrl": "/images/base/runeforged_spiritbone_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -24548,7 +24548,7 @@ "armour": 18, "runic_ward": 12 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower01.webp", + "imageUrl": "/images/base/runeforged_splintered_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24573,7 +24573,7 @@ "evasion": 65, "runic_ward": 34 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex03.webp", + "imageUrl": "/images/base/runeforged_stacked_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24597,7 +24597,7 @@ "evasion": 139, "runic_ward": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex02.webp", + "imageUrl": "/images/base/runeforged_stalking_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24621,7 +24621,7 @@ "armour": 228, "runic_ward": 64 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr06.webp", + "imageUrl": "/images/base/runeforged_steel_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -24646,7 +24646,7 @@ "evasion": 76, "runic_ward": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex01.webp", + "imageUrl": "/images/base/runeforged_steelmail_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24667,7 +24667,7 @@ "int": 23 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff06.webp", + "imageUrl": "/images/base/runeforged_steelpoint_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -24692,7 +24692,7 @@ "energy_shield": 28, "runic_ward": 39 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt04.webp", + "imageUrl": "/images/base/runeforged_steelpoint_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24716,7 +24716,7 @@ "evasion": 102, "runic_ward": 32 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex04.webp", + "imageUrl": "/images/base/runeforged_steeltoe_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24740,7 +24740,7 @@ "energy_shield": 18, "runic_ward": 17 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt03.webp", + "imageUrl": "/images/base/runeforged_stitched_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24764,7 +24764,7 @@ "armour": 15, "runic_ward": 10 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr01.webp", + "imageUrl": "/images/base/runeforged_stocky_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24788,7 +24788,7 @@ "armour": 417, "runic_ward": 103 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr08.webp", + "imageUrl": "/images/base/runeforged_stone_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -24812,7 +24812,7 @@ "armour": 133, "runic_ward": 36 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr05.webp", + "imageUrl": "/images/base/runeforged_stone_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24837,7 +24837,7 @@ "evasion": 85, "runic_ward": 41 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield05.webp", + "imageUrl": "/images/base/runeforged_stone_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24861,7 +24861,7 @@ "armour": 119, "runic_ward": 33 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower08.webp", + "imageUrl": "/images/base/runeforged_stone_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24886,7 +24886,7 @@ "evasion": 74, "runic_ward": 38 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield07.webp", + "imageUrl": "/images/base/runeforged_stratified_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24910,7 +24910,7 @@ "energy_shield": 14, "runic_ward": 14 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt01.webp", + "imageUrl": "/images/base/runeforged_straw_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24934,7 +24934,7 @@ "evasion": 179, "runic_ward": 36 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex04.webp", + "imageUrl": "/images/base/runeforged_studded_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -24955,7 +24955,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace04.webp", + "imageUrl": "/images/base/runeforged_studded_greatclub.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -24980,7 +24980,7 @@ "evasion": 29, "runic_ward": 22 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield03.webp", + "imageUrl": "/images/base/runeforged_studded_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -25004,7 +25004,7 @@ "evasion": 194, "runic_ward": 62 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex06.webp", + "imageUrl": "/images/base/runeforged_studded_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -25025,7 +25025,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow03.webp", + "imageUrl": "/images/base/runeforged_sturdy_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -25049,7 +25049,7 @@ "evasion": 10, "runic_ward": 10 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex01.webp", + "imageUrl": "/images/base/runeforged_suede_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -25073,7 +25073,7 @@ "evasion": 127, "runic_ward": 48 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex04.webp", + "imageUrl": "/images/base/runeforged_swathed_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -25097,7 +25097,7 @@ "evasion": 442, "runic_ward": 64 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex03.webp", + "imageUrl": "/images/base/runeforged_swiftstalker_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -25121,7 +25121,7 @@ "energy_shield": 36, "runic_ward": 181 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus10.webp", + "imageUrl": "/images/base/runeforged_tasalian_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -25145,7 +25145,7 @@ "armour": 127, "runic_ward": 180 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr06.webp", + "imageUrl": "/images/base/runeforged_tasalian_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -25169,7 +25169,7 @@ "energy_shield": 28, "runic_ward": 29 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt01.webp", + "imageUrl": "/images/base/runeforged_tattered_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -25193,7 +25193,7 @@ "armour": 112, "runic_ward": 176 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower10.webp", + "imageUrl": "/images/base/runeforged_tawhoan_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -25217,7 +25217,7 @@ "armour": 49, "runic_ward": 17 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr03.webp", + "imageUrl": "/images/base/runeforged_tempered_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -25238,7 +25238,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace06.webp", + "imageUrl": "/images/base/runeforged_temple_maul.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -25259,7 +25259,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow02.webp", + "imageUrl": "/images/base/runeforged_tense_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -25284,7 +25284,7 @@ "evasion": 243, "runic_ward": 64 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex08.webp", + "imageUrl": "/images/base/runeforged_thane_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -25309,7 +25309,7 @@ "energy_shield": 15, "runic_ward": 26 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt02.webp", + "imageUrl": "/images/base/runeforged_threaded_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -25334,7 +25334,7 @@ "energy_shield": 63, "runic_ward": 87 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr08.webp", + "imageUrl": "/images/base/runeforged_tideseer_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -25358,7 +25358,7 @@ "energy_shield": 26, "runic_ward": 24 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus05.webp", + "imageUrl": "/images/base/runeforged_tonal_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -25382,7 +25382,7 @@ "energy_shield": 9, "runic_ward": 10 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt01.webp", + "imageUrl": "/images/base/runeforged_torn_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -25407,7 +25407,7 @@ "evasion": 181, "runic_ward": 158 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex05.webp", + "imageUrl": "/images/base/runeforged_trailblazer_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -25431,7 +25431,7 @@ "evasion": 320, "runic_ward": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex05.webp", + "imageUrl": "/images/base/runeforged_trapper_hood.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -25456,7 +25456,7 @@ "energy_shield": 30, "runic_ward": 58 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt03.webp", + "imageUrl": "/images/base/runeforged_treerunner_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -25481,7 +25481,7 @@ "energy_shield": 30, "runic_ward": 44 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt05.webp", + "imageUrl": "/images/base/runeforged_tribal_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -25505,7 +25505,7 @@ "armour": 112, "runic_ward": 31 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr04.webp", + "imageUrl": "/images/base/runeforged_trimmed_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -25529,7 +25529,7 @@ "energy_shield": 19, "runic_ward": 19 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt01.webp", + "imageUrl": "/images/base/runeforged_twig_circlet.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -25553,7 +25553,7 @@ "energy_shield": 12, "runic_ward": 12 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus01.webp", + "imageUrl": "/images/base/runeforged_twig_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -25577,7 +25577,7 @@ "armour": 446, "runic_ward": 107 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr08.webp", + "imageUrl": "/images/base/runeforged_utzaal_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -25602,7 +25602,7 @@ "energy_shield": 35, "runic_ward": 26 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest06.webp", + "imageUrl": "/images/base/runeforged_vaal_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -25626,7 +25626,7 @@ "armour": 298, "runic_ward": 70 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr08.webp", + "imageUrl": "/images/base/runeforged_vaal_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -25650,7 +25650,7 @@ "energy_shield": 49, "runic_ward": 21 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt05.webp", + "imageUrl": "/images/base/runeforged_vaal_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -25674,7 +25674,7 @@ "armour": 253, "runic_ward": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr05.webp", + "imageUrl": "/images/base/runeforged_vaal_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -25698,7 +25698,7 @@ "armour": 169, "runic_ward": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr05.webp", + "imageUrl": "/images/base/runeforged_vaal_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -25722,7 +25722,7 @@ "armour": 221, "runic_ward": 35 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower08.webp", + "imageUrl": "/images/base/runeforged_vaal_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -25747,7 +25747,7 @@ "energy_shield": 26, "runic_ward": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt03.webp", + "imageUrl": "/images/base/runeforged_vaal_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -25772,7 +25772,7 @@ "evasion": 71, "runic_ward": 53 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex03.webp", + "imageUrl": "/images/base/runeforged_vagabond_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -25797,7 +25797,7 @@ "energy_shield": 27, "runic_ward": 43 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt04.webp", + "imageUrl": "/images/base/runeforged_veiled_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -25821,7 +25821,7 @@ "energy_shield": 68, "runic_ward": 56 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt07.webp", + "imageUrl": "/images/base/runeforged_vermeil_circlet.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -25846,7 +25846,7 @@ "evasion": 121, "runic_ward": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex01.webp", + "imageUrl": "/images/base/runeforged_veteran_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -25867,7 +25867,7 @@ "int": 52 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/ViciousTalisman.webp", + "imageUrl": "/images/base/runeforged_vicious_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -25891,7 +25891,7 @@ "energy_shield": 66, "runic_ward": 387 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt03.webp", + "imageUrl": "/images/base/runeforged_vile_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -25915,7 +25915,7 @@ "evasion": 179, "runic_ward": 52 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex06.webp", + "imageUrl": "/images/base/runeforged_viper_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -25940,7 +25940,7 @@ "evasion": 46, "runic_ward": 35 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex03.webp", + "imageUrl": "/images/base/runeforged_visored_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -25964,7 +25964,7 @@ "energy_shield": 34, "runic_ward": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus07.webp", + "imageUrl": "/images/base/runeforged_voodoo_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -25988,7 +25988,7 @@ "energy_shield": 83, "runic_ward": 69 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt07.webp", + "imageUrl": "/images/base/runeforged_votive_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26013,7 +26013,7 @@ "energy_shield": 35, "runic_ward": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt01.webp", + "imageUrl": "/images/base/runeforged_wanderer_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -26034,7 +26034,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear05.webp", + "imageUrl": "/images/base/runeforged_war_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26059,7 +26059,7 @@ "energy_shield": 23, "runic_ward": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt01.webp", + "imageUrl": "/images/base/runeforged_war_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -26084,7 +26084,7 @@ "evasion": 156, "runic_ward": 48 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex02.webp", + "imageUrl": "/images/base/runeforged_warded_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26105,7 +26105,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow03.webp", + "imageUrl": "/images/base/runeforged_warden_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26130,7 +26130,7 @@ "energy_shield": 39, "runic_ward": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr03.webp", + "imageUrl": "/images/base/runeforged_warlock_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -26154,7 +26154,7 @@ "armour": 466, "runic_ward": 86 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr10.webp", + "imageUrl": "/images/base/runeforged_warlord_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26178,7 +26178,7 @@ "armour": 305, "runic_ward": 56 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr02.webp", + "imageUrl": "/images/base/runeforged_warmonger_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26199,7 +26199,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace05.webp", + "imageUrl": "/images/base/runeforged_warpick.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26223,7 +26223,7 @@ "armour": 191, "runic_ward": 50 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr06.webp", + "imageUrl": "/images/base/runeforged_warrior_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26248,7 +26248,7 @@ "energy_shield": 25, "runic_ward": 43 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt02.webp", + "imageUrl": "/images/base/runeforged_waxed_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26273,7 +26273,7 @@ "energy_shield": 41, "runic_ward": 77 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt04.webp", + "imageUrl": "/images/base/runeforged_wayfarer_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26298,7 +26298,7 @@ "energy_shield": 23, "runic_ward": 38 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest07.webp", + "imageUrl": "/images/base/runeforged_wayward_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -26323,7 +26323,7 @@ "energy_shield": 28, "runic_ward": 39 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr04.webp", + "imageUrl": "/images/base/runeforged_weaver_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -26347,7 +26347,7 @@ "energy_shield": 47, "runic_ward": 34 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus10.webp", + "imageUrl": "/images/base/runeforged_whorl_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -26371,7 +26371,7 @@ "energy_shield": 29, "runic_ward": 27 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt02.webp", + "imageUrl": "/images/base/runeforged_wicker_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26392,7 +26392,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear04.webp", + "imageUrl": "/images/base/runeforged_winged_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26417,7 +26417,7 @@ "energy_shield": 32, "runic_ward": 417 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr02.webp", + "imageUrl": "/images/base/runeforged_wolfskin_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26441,7 +26441,7 @@ "evasion": 18, "runic_ward": 11 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler02.webp", + "imageUrl": "/images/base/runeforged_wooden_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -26462,7 +26462,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace01.webp", + "imageUrl": "/images/base/runeforged_wooden_club.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26486,7 +26486,7 @@ "evasion": 290, "runic_ward": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex02.webp", + "imageUrl": "/images/base/runeforged_woven_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26510,7 +26510,7 @@ "energy_shield": 15, "runic_ward": 15 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus02.webp", + "imageUrl": "/images/base/runeforged_woven_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -26534,7 +26534,7 @@ "evasion": 219, "runic_ward": 72 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex04.webp", + "imageUrl": "/images/base/runeforged_wrapped_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26558,7 +26558,7 @@ "armour": 99, "runic_ward": 35 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr03.webp", + "imageUrl": "/images/base/runeforged_wrapped_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26579,7 +26579,7 @@ "int": 23 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff01.webp", + "imageUrl": "/images/base/runeforged_wrapped_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26603,7 +26603,7 @@ "energy_shield": 22, "runic_ward": 21 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt02.webp", + "imageUrl": "/images/base/runeforged_wrapped_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -26627,7 +26627,7 @@ "evasion": 298, "runic_ward": 236 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex08.webp", + "imageUrl": "/images/base/runeforged_wyrmscale_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26648,7 +26648,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow08.webp", + "imageUrl": "/images/base/runeforged_zealot_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26673,7 +26673,7 @@ "evasion": 71, "runic_ward": 26 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex03.webp", + "imageUrl": "/images/base/runeforged_zealot_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -26696,7 +26696,7 @@ "baseStats": { "aps": 1 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace10.webp", + "imageUrl": "/images/base/runemastered_aberrant_sledge.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26721,7 +26721,7 @@ "energy_shield": 13, "runic_ward": 18 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr02.webp", + "imageUrl": "/images/base/runemastered_aged_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -26745,7 +26745,7 @@ "energy_shield": 72, "runic_ward": 149 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt08.webp", + "imageUrl": "/images/base/runemastered_altar_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26770,7 +26770,7 @@ "evasion": 174, "runic_ward": 107 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex08.webp", + "imageUrl": "/images/base/runemastered_ancestral_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26795,7 +26795,7 @@ "energy_shield": 43, "runic_ward": 130 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt05.webp", + "imageUrl": "/images/base/runemastered_anchorite_garb.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26820,7 +26820,7 @@ "energy_shield": 30, "runic_ward": 53 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr01.webp", + "imageUrl": "/images/base/runemastered_ancient_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -26845,7 +26845,7 @@ "energy_shield": 61, "runic_ward": 86 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Uniques/Loreweave.webp", + "imageUrl": "/images/base/runemastered_ancient_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26870,7 +26870,7 @@ "evasion": 153, "runic_ward": 59 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex08.webp", + "imageUrl": "/images/base/runemastered_ancient_visor.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26894,7 +26894,7 @@ "energy_shield": 23, "runic_ward": 34 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus03.webp", + "imageUrl": "/images/base/runemastered_antler_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -26918,7 +26918,7 @@ "evasion": 178, "runic_ward": 113 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex01.webp", + "imageUrl": "/images/base/runemastered_armoured_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26942,7 +26942,7 @@ "evasion": 361, "runic_ward": 129 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex01.webp", + "imageUrl": "/images/base/runemastered_armoured_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -26966,7 +26966,7 @@ "evasion": 103, "runic_ward": 33 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler12.webp", + "imageUrl": "/images/base/runemastered_array_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -26991,7 +26991,7 @@ "energy_shield": 68, "runic_ward": 43 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt01.webp", + "imageUrl": "/images/base/runemastered_assassin_garb.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27015,7 +27015,7 @@ "armour": 94, "runic_ward": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower04.webp", + "imageUrl": "/images/base/runemastered_barricade_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -27039,7 +27039,7 @@ "energy_shield": 24, "runic_ward": 72 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt03.webp", + "imageUrl": "/images/base/runemastered_beaded_circlet.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27063,7 +27063,7 @@ "armour": 102, "runic_ward": 88 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower01.webp", + "imageUrl": "/images/base/runemastered_blacksteel_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -27088,7 +27088,7 @@ "energy_shield": 13, "runic_ward": 47 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest01.webp", + "imageUrl": "/images/base/runemastered_blazon_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -27112,7 +27112,7 @@ "armour": 80, "runic_ward": 27 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr04.webp", + "imageUrl": "/images/base/runemastered_bolstered_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -27136,7 +27136,7 @@ "energy_shield": 46, "runic_ward": 138 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt04.webp", + "imageUrl": "/images/base/runemastered_bone_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27161,7 +27161,7 @@ "evasion": 59, "runic_ward": 34 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex02.webp", + "imageUrl": "/images/base/runemastered_braced_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -27185,7 +27185,7 @@ "armour": 88, "runic_ward": 34 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower03.webp", + "imageUrl": "/images/base/runemastered_braced_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -27210,7 +27210,7 @@ "evasion": 39, "runic_ward": 109 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex01.webp", + "imageUrl": "/images/base/runemastered_brimmed_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27234,7 +27234,7 @@ "armour": 135, "runic_ward": 20 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr03.webp", + "imageUrl": "/images/base/runemastered_bronze_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -27259,7 +27259,7 @@ "evasion": 33, "runic_ward": 58 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex01.webp", + "imageUrl": "/images/base/runemastered_burnished_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -27284,7 +27284,7 @@ "evasion": 135, "runic_ward": 55 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex01.webp", + "imageUrl": "/images/base/runemastered_chain_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27307,7 +27307,7 @@ "baseStats": { "energy_shield": 62 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt04.webp", + "imageUrl": "/images/base/runemastered_chain_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27331,7 +27331,7 @@ "evasion": 178, "runic_ward": 74 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex02.webp", + "imageUrl": "/images/base/runemastered_cinched_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -27356,7 +27356,7 @@ "energy_shield": 53, "runic_ward": 75 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr07.webp", + "imageUrl": "/images/base/runemastered_cleric_vestments.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27381,7 +27381,7 @@ "evasion": 102, "runic_ward": 115 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex04.webp", + "imageUrl": "/images/base/runemastered_cloaked_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27405,7 +27405,7 @@ "evasion": 202, "runic_ward": 37 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex07.webp", + "imageUrl": "/images/base/runemastered_corsair_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27430,7 +27430,7 @@ "energy_shield": 61, "runic_ward": 86 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr12.webp", + "imageUrl": "/images/base/runemastered_corvus_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27455,7 +27455,7 @@ "evasion": 63, "runic_ward": 73 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex04.webp", + "imageUrl": "/images/base/runemastered_covered_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -27479,7 +27479,7 @@ "evasion": 129, "runic_ward": 124 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex10.webp", + "imageUrl": "/images/base/runemastered_covert_hood.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27504,7 +27504,7 @@ "evasion": 93, "runic_ward": 19 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex04.webp", + "imageUrl": "/images/base/runemastered_cowled_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27529,7 +27529,7 @@ "evasion": 46, "runic_ward": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield04.webp", + "imageUrl": "/images/base/runemastered_crescent_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -27553,7 +27553,7 @@ "armour": 100, "runic_ward": 100 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower09.webp", + "imageUrl": "/images/base/runemastered_crucible_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -27577,7 +27577,7 @@ "energy_shield": 23, "runic_ward": 47 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus06.webp", + "imageUrl": "/images/base/runemastered_crystal_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -27602,7 +27602,7 @@ "energy_shield": 50, "runic_ward": 49 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr03.webp", + "imageUrl": "/images/base/runemastered_cultist_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27627,7 +27627,7 @@ "energy_shield": 40, "runic_ward": 70 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt08.webp", + "imageUrl": "/images/base/runemastered_death_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27652,7 +27652,7 @@ "evasion": 146, "runic_ward": 70 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex07.webp", + "imageUrl": "/images/base/runemastered_decorated_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27677,7 +27677,7 @@ "evasion": 56, "runic_ward": 24 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex03.webp", + "imageUrl": "/images/base/runemastered_doubled_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -27698,7 +27698,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow05.webp", + "imageUrl": "/images/base/runemastered_dyad_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27722,7 +27722,7 @@ "energy_shield": 96, "runic_ward": 75 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt09.webp", + "imageUrl": "/images/base/runemastered_elementalist_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27746,7 +27746,7 @@ "armour": 209, "runic_ward": 61 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr05.webp", + "imageUrl": "/images/base/runemastered_elite_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27771,7 +27771,7 @@ "energy_shield": 14, "runic_ward": 34 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest03.webp", + "imageUrl": "/images/base/runemastered_emblem_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -27795,7 +27795,7 @@ "evasion": 94, "runic_ward": 41 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex03.webp", + "imageUrl": "/images/base/runemastered_embossed_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -27819,7 +27819,7 @@ "energy_shield": 26, "runic_ward": 35 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt07.webp", + "imageUrl": "/images/base/runemastered_embroidered_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -27843,7 +27843,7 @@ "energy_shield": 38, "runic_ward": 45 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus04.webp", + "imageUrl": "/images/base/runemastered_engraved_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -27867,7 +27867,7 @@ "energy_shield": 124, "runic_ward": 86 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt01.webp", + "imageUrl": "/images/base/runemastered_enlightened_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27892,7 +27892,7 @@ "evasion": 180, "runic_ward": 56 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex05.webp", + "imageUrl": "/images/base/runemastered_explorer_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27916,7 +27916,7 @@ "evasion": 338, "runic_ward": 86 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex13.webp", + "imageUrl": "/images/base/runemastered_exquisite_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27941,7 +27941,7 @@ "energy_shield": 40, "runic_ward": 18 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt02.webp", + "imageUrl": "/images/base/runemastered_face_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27962,7 +27962,7 @@ "int": 45 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/FamilialTalisman.webp", + "imageUrl": "/images/base/runemastered_familial_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -27986,7 +27986,7 @@ "energy_shield": 55, "runic_ward": 99 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt02.webp", + "imageUrl": "/images/base/runemastered_feathered_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28010,7 +28010,7 @@ "energy_shield": 33, "runic_ward": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt05.webp", + "imageUrl": "/images/base/runemastered_feathered_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -28034,7 +28034,7 @@ "energy_shield": 32, "runic_ward": 98 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt05.webp", + "imageUrl": "/images/base/runemastered_feathered_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28055,7 +28055,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace01.webp", + "imageUrl": "/images/base/runemastered_felled_greatclub.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28079,7 +28079,7 @@ "evasion": 134, "runic_ward": 54 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex02.webp", + "imageUrl": "/images/base/runemastered_felt_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28103,7 +28103,7 @@ "armour": 334, "runic_ward": 24 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr08.webp", + "imageUrl": "/images/base/runemastered_fierce_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28127,7 +28127,7 @@ "evasion": 52, "runic_ward": 52 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex06.webp", + "imageUrl": "/images/base/runemastered_fine_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -28151,7 +28151,7 @@ "evasion": 63, "runic_ward": 27 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex02.webp", + "imageUrl": "/images/base/runemastered_firm_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -28175,7 +28175,7 @@ "armour": 231, "runic_ward": 126 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr07.webp", + "imageUrl": "/images/base/runemastered_full_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28200,7 +28200,7 @@ "energy_shield": 17, "runic_ward": 24 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt01.webp", + "imageUrl": "/images/base/runemastered_furtive_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -28225,7 +28225,7 @@ "energy_shield": 61, "runic_ward": 86 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr09.webp", + "imageUrl": "/images/base/runemastered_gilded_vestments.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28249,7 +28249,7 @@ "armour": 203, "runic_ward": 53 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower06.webp", + "imageUrl": "/images/base/runemastered_glacial_fortress.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -28273,7 +28273,7 @@ "energy_shield": 16, "runic_ward": 196 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt06.webp", + "imageUrl": "/images/base/runemastered_gold_circlet.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28298,7 +28298,7 @@ "energy_shield": 22, "runic_ward": 37 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr03.webp", + "imageUrl": "/images/base/runemastered_goldcast_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -28319,7 +28319,7 @@ "int": 31 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff03.webp", + "imageUrl": "/images/base/runemastered_gothic_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28345,7 +28345,7 @@ "energy_shield": 40, "runic_ward": 86 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr01.webp", + "imageUrl": "/images/base/runemastered_grand_regalia.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28369,7 +28369,7 @@ "evasion": 384, "runic_ward": 150 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDexInt03.webp", + "imageUrl": "/images/base/runemastered_grasping_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28394,7 +28394,7 @@ "evasion": 247, "runic_ward": 36 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex02.webp", + "imageUrl": "/images/base/runemastered_guarded_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28419,7 +28419,7 @@ "evasion": 49, "runic_ward": 23 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield01.webp", + "imageUrl": "/images/base/runemastered_hardwood_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -28443,7 +28443,7 @@ "energy_shield": 96, "runic_ward": 129 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt13.webp", + "imageUrl": "/images/base/runemastered_havoc_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28464,7 +28464,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Belts/Basetypes/Belt09.webp", + "imageUrl": "/images/base/runemastered_heavy_belt.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -28489,7 +28489,7 @@ "energy_shield": 22, "runic_ward": 122 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr05.webp", + "imageUrl": "/images/base/runemastered_heavy_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28513,7 +28513,7 @@ "armour": 96, "runic_ward": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower07.webp", + "imageUrl": "/images/base/runemastered_heraldric_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -28538,7 +28538,7 @@ "energy_shield": 45, "runic_ward": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt01.webp", + "imageUrl": "/images/base/runemastered_hermit_garb.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28563,7 +28563,7 @@ "evasion": 124, "runic_ward": 215 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex11.webp", + "imageUrl": "/images/base/runemastered_heroic_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28588,7 +28588,7 @@ "energy_shield": 10, "runic_ward": 54 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt01.webp", + "imageUrl": "/images/base/runemastered_hewn_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28612,7 +28612,7 @@ "energy_shield": 64, "runic_ward": 83 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt03.webp", + "imageUrl": "/images/base/runemastered_hexers_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28637,7 +28637,7 @@ "energy_shield": 23, "runic_ward": 54 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt03.webp", + "imageUrl": "/images/base/runemastered_hooded_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28662,7 +28662,7 @@ "energy_shield": 25, "runic_ward": 54 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr02.webp", + "imageUrl": "/images/base/runemastered_horned_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28686,7 +28686,7 @@ "evasion": 73, "runic_ward": 75 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex05.webp", + "imageUrl": "/images/base/runemastered_hunter_hood.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28711,7 +28711,7 @@ "energy_shield": 23, "runic_ward": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt03.webp", + "imageUrl": "/images/base/runemastered_hunting_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -28736,7 +28736,7 @@ "energy_shield": 22, "runic_ward": 62 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest02.webp", + "imageUrl": "/images/base/runemastered_intricate_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -28760,7 +28760,7 @@ "energy_shield": 47, "runic_ward": 24 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt05.webp", + "imageUrl": "/images/base/runemastered_intricate_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -28784,7 +28784,7 @@ "evasion": 45, "runic_ward": 45 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler04.webp", + "imageUrl": "/images/base/runemastered_iron_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -28809,7 +28809,7 @@ "energy_shield": 21, "runic_ward": 72 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr01.webp", + "imageUrl": "/images/base/runemastered_iron_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28833,7 +28833,7 @@ "armour": 260, "runic_ward": 55 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr03.webp", + "imageUrl": "/images/base/runemastered_iron_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28857,7 +28857,7 @@ "armour": 120, "runic_ward": 27 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr02.webp", + "imageUrl": "/images/base/runemastered_iron_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -28882,7 +28882,7 @@ "energy_shield": 60, "runic_ward": 37 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr05.webp", + "imageUrl": "/images/base/runemastered_ironclad_vestments.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28903,7 +28903,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear02.webp", + "imageUrl": "/images/base/runemastered_ironhead_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28927,7 +28927,7 @@ "energy_shield": 45, "runic_ward": 141 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt08.webp", + "imageUrl": "/images/base/runemastered_jade_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -28951,7 +28951,7 @@ "energy_shield": 21, "runic_ward": 27 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt04.webp", + "imageUrl": "/images/base/runemastered_jewelled_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -28976,7 +28976,7 @@ "energy_shield": 12, "runic_ward": 45 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest04.webp", + "imageUrl": "/images/base/runemastered_jingling_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -29000,7 +29000,7 @@ "energy_shield": 73, "runic_ward": 55 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt06.webp", + "imageUrl": "/images/base/runemastered_keth_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -29025,7 +29025,7 @@ "evasion": 159, "runic_ward": 93 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex07.webp", + "imageUrl": "/images/base/runemastered_knight_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -29049,7 +29049,7 @@ "evasion": 54, "runic_ward": 81 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex02.webp", + "imageUrl": "/images/base/runemastered_laced_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -29073,7 +29073,7 @@ "energy_shield": 34, "runic_ward": 34 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt03.webp", + "imageUrl": "/images/base/runemastered_lattice_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -29098,7 +29098,7 @@ "evasion": 47, "runic_ward": 14 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex02.webp", + "imageUrl": "/images/base/runemastered_layered_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -29122,7 +29122,7 @@ "evasion": 108, "runic_ward": 36 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler01.webp", + "imageUrl": "/images/base/runemastered_leather_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -29146,7 +29146,7 @@ "evasion": 82, "runic_ward": 165 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex01.webp", + "imageUrl": "/images/base/runemastered_leather_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -29170,7 +29170,7 @@ "evasion": 266, "runic_ward": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex08.webp", + "imageUrl": "/images/base/runemastered_leatherbound_hood.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -29195,7 +29195,7 @@ "energy_shield": 12, "runic_ward": 23 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt02.webp", + "imageUrl": "/images/base/runemastered_linen_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -29219,7 +29219,7 @@ "evasion": 99, "runic_ward": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex05.webp", + "imageUrl": "/images/base/runemastered_lizardscale_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -29240,7 +29240,7 @@ "int": 31 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff02.webp", + "imageUrl": "/images/base/runemastered_long_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -29264,7 +29264,7 @@ "energy_shield": 68, "runic_ward": 70 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt11.webp", + "imageUrl": "/images/base/runemastered_magus_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -29289,7 +29289,7 @@ "evasion": 44, "runic_ward": 54 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex01.webp", + "imageUrl": "/images/base/runemastered_mail_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -29314,7 +29314,7 @@ "energy_shield": 35, "runic_ward": 83 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr03.webp", + "imageUrl": "/images/base/runemastered_mail_vestments.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -29339,7 +29339,7 @@ "energy_shield": 30, "runic_ward": 110 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt03.webp", + "imageUrl": "/images/base/runemastered_marabout_garb.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -29363,7 +29363,7 @@ "armour": 275, "runic_ward": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr05.webp", + "imageUrl": "/images/base/runemastered_maraketh_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -29388,7 +29388,7 @@ "energy_shield": 20, "runic_ward": 81 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr04.webp", + "imageUrl": "/images/base/runemastered_martyr_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -29412,7 +29412,7 @@ "armour": 70, "runic_ward": 61 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr05.webp", + "imageUrl": "/images/base/runemastered_moulded_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -29433,7 +29433,7 @@ "int": 45 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/NettleTalisman.webp", + "imageUrl": "/images/base/runemastered_nettle_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -29456,7 +29456,7 @@ "baseStats": { "aps": 1 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace02.webp", + "imageUrl": "/images/base/runemastered_oak_greathammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -29481,7 +29481,7 @@ "energy_shield": 12, "runic_ward": 82 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest06.webp", + "imageUrl": "/images/base/runemastered_omen_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -29505,7 +29505,7 @@ "evasion": 114, "runic_ward": 12 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler11.webp", + "imageUrl": "/images/base/runemastered_ornate_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -29530,7 +29530,7 @@ "energy_shield": 206, "runic_ward": 130 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Uniques/Loreweave.webp", + "imageUrl": "/images/base/runemastered_ornate_ringmail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -29554,7 +29554,7 @@ "armour": 63, "runic_ward": 57 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower02.webp", + "imageUrl": "/images/base/runemastered_painted_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -29578,7 +29578,7 @@ "evasion": 219, "runic_ward": 55 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex03.webp", + "imageUrl": "/images/base/runemastered_pathfinder_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -29602,7 +29602,7 @@ "energy_shield": 30, "runic_ward": 31 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt06.webp", + "imageUrl": "/images/base/runemastered_pauascale_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -29627,7 +29627,7 @@ "energy_shield": 60, "runic_ward": 55 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr01.webp", + "imageUrl": "/images/base/runemastered_pilgrim_vestments.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -29652,7 +29652,7 @@ "evasion": 63, "runic_ward": 12 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex04.webp", + "imageUrl": "/images/base/runemastered_plate_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -29676,7 +29676,7 @@ "evasion": 67, "runic_ward": 23 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler03.webp", + "imageUrl": "/images/base/runemastered_plated_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -29700,7 +29700,7 @@ "energy_shield": 124, "runic_ward": 43 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt12.webp", + "imageUrl": "/images/base/runemastered_plated_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -29724,7 +29724,7 @@ "energy_shield": 23, "runic_ward": 106 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus08.webp", + "imageUrl": "/images/base/runemastered_plumed_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -29749,7 +29749,7 @@ "energy_shield": 68, "runic_ward": 107 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt08.webp", + "imageUrl": "/images/base/runemastered_primal_markings.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -29773,7 +29773,7 @@ "evasion": 178, "runic_ward": 152 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex02.webp", + "imageUrl": "/images/base/runemastered_quilted_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -29797,7 +29797,7 @@ "armour": 61, "runic_ward": 221 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr04.webp", + "imageUrl": "/images/base/runemastered_raider_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -29821,7 +29821,7 @@ "armour": 98, "runic_ward": 29 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower06.webp", + "imageUrl": "/images/base/runemastered_rampart_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -29846,7 +29846,7 @@ "energy_shield": 64, "runic_ward": 86 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr11.webp", + "imageUrl": "/images/base/runemastered_revered_vestments.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -29870,7 +29870,7 @@ "evasion": 219, "runic_ward": 69 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex05.webp", + "imageUrl": "/images/base/runemastered_rhoahide_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -29894,7 +29894,7 @@ "evasion": 66, "runic_ward": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler05.webp", + "imageUrl": "/images/base/runemastered_ridged_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -29919,7 +29919,7 @@ "evasion": 39, "runic_ward": 18 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex01.webp", + "imageUrl": "/images/base/runemastered_ringmail_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -29943,7 +29943,7 @@ "armour": 80, "runic_ward": 23 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr02.webp", + "imageUrl": "/images/base/runemastered_riveted_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -29968,7 +29968,7 @@ "evasion": 105, "runic_ward": 83 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex02.webp", + "imageUrl": "/images/base/runemastered_rogue_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -29993,7 +29993,7 @@ "energy_shield": 10, "runic_ward": 36 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr01.webp", + "imageUrl": "/images/base/runemastered_rope_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -30017,7 +30017,7 @@ "armour": 150, "runic_ward": 27 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr01.webp", + "imageUrl": "/images/base/runemastered_rough_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -30038,7 +30038,7 @@ "int": 114 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Wands/Basetypes/Wand01.webp", + "imageUrl": "/images/base/runemastered_runic_fork.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30062,7 +30062,7 @@ "armour": 244, "runic_ward": 110 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr01.webp", + "imageUrl": "/images/base/runemastered_rusted_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30086,7 +30086,7 @@ "armour": 360, "runic_ward": 36 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr01.webp", + "imageUrl": "/images/base/runemastered_rusted_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30111,7 +30111,7 @@ "energy_shield": 60, "runic_ward": 37 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr06.webp", + "imageUrl": "/images/base/runemastered_sacrificial_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30137,7 +30137,7 @@ "energy_shield": 38, "runic_ward": 215 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDexInt02.webp", + "imageUrl": "/images/base/runemastered_sacrificial_regalia.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30162,7 +30162,7 @@ "evasion": 170, "runic_ward": 75 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex06.webp", + "imageUrl": "/images/base/runemastered_scale_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30187,7 +30187,7 @@ "energy_shield": 53, "runic_ward": 75 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt06.webp", + "imageUrl": "/images/base/runemastered_scalpers_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30211,7 +30211,7 @@ "evasion": 270, "runic_ward": 130 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex07.webp", + "imageUrl": "/images/base/runemastered_scouts_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30235,7 +30235,7 @@ "evasion": 76, "runic_ward": 18 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex04.webp", + "imageUrl": "/images/base/runemastered_sectioned_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -30260,7 +30260,7 @@ "energy_shield": 17, "runic_ward": 41 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr02.webp", + "imageUrl": "/images/base/runemastered_secured_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -30284,7 +30284,7 @@ "evasion": 385, "runic_ward": 19 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex08.webp", + "imageUrl": "/images/base/runemastered_serpentscale_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30309,7 +30309,7 @@ "energy_shield": 42, "runic_ward": 44 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr04.webp", + "imageUrl": "/images/base/runemastered_shaman_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30334,7 +30334,7 @@ "evasion": 97, "runic_ward": 122 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex05.webp", + "imageUrl": "/images/base/runemastered_shielded_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30358,7 +30358,7 @@ "evasion": 164, "runic_ward": 138 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex04.webp", + "imageUrl": "/images/base/runemastered_shrouded_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30383,7 +30383,7 @@ "energy_shield": 19, "runic_ward": 12 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest02.webp", + "imageUrl": "/images/base/runemastered_sigil_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -30407,7 +30407,7 @@ "energy_shield": 27, "runic_ward": 110 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt05.webp", + "imageUrl": "/images/base/runemastered_silk_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30431,7 +30431,7 @@ "energy_shield": 36, "runic_ward": 54 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt04.webp", + "imageUrl": "/images/base/runemastered_silk_slippers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -30455,7 +30455,7 @@ "evasion": 406, "runic_ward": 86 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex10.webp", + "imageUrl": "/images/base/runemastered_smuggler_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30479,7 +30479,7 @@ "armour": 140, "runic_ward": 54 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr02.webp", + "imageUrl": "/images/base/runemastered_soldier_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30504,7 +30504,7 @@ "energy_shield": 39, "runic_ward": 37 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt06.webp", + "imageUrl": "/images/base/runemastered_solid_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30528,7 +30528,7 @@ "energy_shield": 24, "runic_ward": 18 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt02.webp", + "imageUrl": "/images/base/runemastered_sombre_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -30552,7 +30552,7 @@ "evasion": 61, "runic_ward": 33 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler06.webp", + "imageUrl": "/images/base/runemastered_spiked_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -30576,7 +30576,7 @@ "evasion": 72, "runic_ward": 18 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex05.webp", + "imageUrl": "/images/base/runemastered_spined_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -30601,7 +30601,7 @@ "energy_shield": 12, "runic_ward": 67 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt03.webp", + "imageUrl": "/images/base/runemastered_spiral_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -30625,7 +30625,7 @@ "armour": 115, "runic_ward": 85 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr04.webp", + "imageUrl": "/images/base/runemastered_spired_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30650,7 +30650,7 @@ "energy_shield": 32, "runic_ward": 113 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr06.webp", + "imageUrl": "/images/base/runemastered_spiritbone_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30674,7 +30674,7 @@ "armour": 100, "runic_ward": 23 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower01.webp", + "imageUrl": "/images/base/runemastered_splintered_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -30699,7 +30699,7 @@ "evasion": 155, "runic_ward": 21 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex03.webp", + "imageUrl": "/images/base/runemastered_stacked_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -30723,7 +30723,7 @@ "armour": 271, "runic_ward": 43 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr06.webp", + "imageUrl": "/images/base/runemastered_steel_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30747,7 +30747,7 @@ "evasion": 113, "runic_ward": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex04.webp", + "imageUrl": "/images/base/runemastered_steeltoe_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -30771,7 +30771,7 @@ "energy_shield": 30, "runic_ward": 23 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt03.webp", + "imageUrl": "/images/base/runemastered_stitched_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -30795,7 +30795,7 @@ "armour": 50, "runic_ward": 45 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr01.webp", + "imageUrl": "/images/base/runemastered_stocky_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -30819,7 +30819,7 @@ "armour": 157, "runic_ward": 46 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr05.webp", + "imageUrl": "/images/base/runemastered_stone_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -30843,7 +30843,7 @@ "energy_shield": 45, "runic_ward": 34 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt01.webp", + "imageUrl": "/images/base/runemastered_straw_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -30867,7 +30867,7 @@ "evasion": 384, "runic_ward": 107 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex01.webp", + "imageUrl": "/images/base/runemastered_strider_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30888,7 +30888,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace04.webp", + "imageUrl": "/images/base/runemastered_studded_greatclub.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30912,7 +30912,7 @@ "evasion": 301, "runic_ward": 29 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex06.webp", + "imageUrl": "/images/base/runemastered_studded_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30936,7 +30936,7 @@ "evasion": 63, "runic_ward": 20 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex01.webp", + "imageUrl": "/images/base/runemastered_suede_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -30960,7 +30960,7 @@ "energy_shield": 9, "runic_ward": 138 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt01.webp", + "imageUrl": "/images/base/runemastered_tattered_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -30984,7 +30984,7 @@ "armour": 95, "runic_ward": 23 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr03.webp", + "imageUrl": "/images/base/runemastered_tempered_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -31009,7 +31009,7 @@ "energy_shield": 40, "runic_ward": 56 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr08.webp", + "imageUrl": "/images/base/runemastered_tenebrous_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31030,7 +31030,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow02.webp", + "imageUrl": "/images/base/runemastered_tense_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31055,7 +31055,7 @@ "energy_shield": 19, "runic_ward": 34 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt02.webp", + "imageUrl": "/images/base/runemastered_threaded_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -31080,7 +31080,7 @@ "energy_shield": 15, "runic_ward": 129 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr08.webp", + "imageUrl": "/images/base/runemastered_tideseer_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31104,7 +31104,7 @@ "armour": 114, "runic_ward": 49 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr07.webp", + "imageUrl": "/images/base/runemastered_titan_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -31128,7 +31128,7 @@ "energy_shield": 19, "runic_ward": 57 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus05.webp", + "imageUrl": "/images/base/runemastered_tonal_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -31149,7 +31149,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace01.webp", + "imageUrl": "/images/base/runemastered_torment_club.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31173,7 +31173,7 @@ "energy_shield": 18, "runic_ward": 36 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt01.webp", + "imageUrl": "/images/base/runemastered_torn_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -31198,7 +31198,7 @@ "energy_shield": 33, "runic_ward": 47 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt05.webp", + "imageUrl": "/images/base/runemastered_tribal_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31222,7 +31222,7 @@ "armour": 79, "runic_ward": 71 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr04.webp", + "imageUrl": "/images/base/runemastered_trimmed_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -31246,7 +31246,7 @@ "energy_shield": 48, "runic_ward": 36 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt01.webp", + "imageUrl": "/images/base/runemastered_twig_circlet.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31270,7 +31270,7 @@ "energy_shield": 38, "runic_ward": 23 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus01.webp", + "imageUrl": "/images/base/runemastered_twig_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -31294,7 +31294,7 @@ "energy_shield": 72, "runic_ward": 56 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt10.webp", + "imageUrl": "/images/base/runemastered_twilight_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31319,7 +31319,7 @@ "energy_shield": 15, "runic_ward": 56 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt01.webp", + "imageUrl": "/images/base/runemastered_utility_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -31343,7 +31343,7 @@ "armour": 340, "runic_ward": 93 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr08.webp", + "imageUrl": "/images/base/runemastered_vaal_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31367,7 +31367,7 @@ "armour": 203, "runic_ward": 70 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower08.webp", + "imageUrl": "/images/base/runemastered_vaal_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -31392,7 +31392,7 @@ "evasion": 128, "runic_ward": 41 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex03.webp", + "imageUrl": "/images/base/runemastered_vagabond_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31417,7 +31417,7 @@ "energy_shield": 26, "runic_ward": 57 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt04.webp", + "imageUrl": "/images/base/runemastered_veiled_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31442,7 +31442,7 @@ "energy_shield": 26, "runic_ward": 63 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt01.webp", + "imageUrl": "/images/base/runemastered_velour_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -31466,7 +31466,7 @@ "evasion": 222, "runic_ward": 70 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex09.webp", + "imageUrl": "/images/base/runemastered_velvet_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31490,7 +31490,7 @@ "evasion": 148, "runic_ward": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield10.webp", + "imageUrl": "/images/base/runemastered_venerable_defender.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -31511,7 +31511,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/Basetypes/BloodstoneAmulet.webp", + "imageUrl": "/images/base/runemastered_veridical_chain.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -31536,7 +31536,7 @@ "energy_shield": 21, "runic_ward": 12 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr04.webp", + "imageUrl": "/images/base/runemastered_verisium_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -31560,7 +31560,7 @@ "energy_shield": 67, "runic_ward": 37 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt07.webp", + "imageUrl": "/images/base/runemastered_vermeil_circlet.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31584,7 +31584,7 @@ "evasion": 139, "runic_ward": 110 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex06.webp", + "imageUrl": "/images/base/runemastered_viper_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31609,7 +31609,7 @@ "evasion": 69, "runic_ward": 54 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex03.webp", + "imageUrl": "/images/base/runemastered_visored_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31633,7 +31633,7 @@ "energy_shield": 40, "runic_ward": 31 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus07.webp", + "imageUrl": "/images/base/runemastered_voodoo_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -31657,7 +31657,7 @@ "energy_shield": 48, "runic_ward": 186 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt07.webp", + "imageUrl": "/images/base/runemastered_votive_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31678,7 +31678,7 @@ "int": 50 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff10.webp", + "imageUrl": "/images/base/runemastered_warding_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31702,7 +31702,7 @@ "armour": 111, "runic_ward": 147 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr06.webp", + "imageUrl": "/images/base/runemastered_warrior_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31727,7 +31727,7 @@ "energy_shield": 38, "runic_ward": 69 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt02.webp", + "imageUrl": "/images/base/runemastered_waxed_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31752,7 +31752,7 @@ "energy_shield": 44, "runic_ward": 43 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt04.webp", + "imageUrl": "/images/base/runemastered_wayfarer_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31776,7 +31776,7 @@ "energy_shield": 45, "runic_ward": 45 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt02.webp", + "imageUrl": "/images/base/runemastered_wicker_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31800,7 +31800,7 @@ "evasion": 90, "runic_ward": 18 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler02.webp", + "imageUrl": "/images/base/runemastered_wooden_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -31821,7 +31821,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace01.webp", + "imageUrl": "/images/base/runemastered_wooden_club.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31845,7 +31845,7 @@ "energy_shield": 23, "runic_ward": 45 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus02.webp", + "imageUrl": "/images/base/runemastered_woven_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -31869,7 +31869,7 @@ "armour": 170, "runic_ward": 27 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr03.webp", + "imageUrl": "/images/base/runemastered_wrapped_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31893,7 +31893,7 @@ "energy_shield": 41, "runic_ward": 41 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt02.webp", + "imageUrl": "/images/base/runemastered_wrapped_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -31914,7 +31914,7 @@ "int": 114 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Wands/Basetypes/Wand01.webp", + "imageUrl": "/images/base/runic_fork.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31935,7 +31935,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSwords/Basetypes/1HSword10.webp", + "imageUrl": "/images/base/runic_shortsword.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31958,7 +31958,7 @@ "baseStats": { "evasion": 412 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex07.webp", + "imageUrl": "/images/base/runner_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -31981,7 +31981,7 @@ "baseStats": { "armour": 45 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr01.webp", + "imageUrl": "/images/base/rusted_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32004,7 +32004,7 @@ "baseStats": { "armour": 29 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr01.webp", + "imageUrl": "/images/base/rusted_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32025,7 +32025,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Quivers/Basetypes/QuiverSacral.webp", + "imageUrl": "/images/base/sacral_quiver.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -32048,7 +32048,7 @@ "baseStats": { "energy_shield": 153 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt08.webp", + "imageUrl": "/images/base/sacramental_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32071,7 +32071,7 @@ "baseStats": { "energy_shield": 81 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus08.webp", + "imageUrl": "/images/base/sacred_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -32092,7 +32092,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace06.webp", + "imageUrl": "/images/base/sacred_maul.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32113,7 +32113,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandAxes/Basetypes/1HAxe08.webp", + "imageUrl": "/images/base/sacrificial_axe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32137,7 +32137,7 @@ "armour": 160, "energy_shield": 48 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr06.webp", + "imageUrl": "/images/base/sacrificial_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32162,7 +32162,7 @@ "evasion": 248, "energy_shield": 76 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDexInt02.webp", + "imageUrl": "/images/base/sacrificial_regalia.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32186,7 +32186,7 @@ "armour": 188, "energy_shield": 52 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr04.webp", + "imageUrl": "/images/base/saintly_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32207,7 +32207,7 @@ "int": 99 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Staves/Basetypes/Staff12.webp", + "imageUrl": "/images/base/sanctified_staff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32230,7 +32230,7 @@ "baseStats": { "armour": 397 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr05.webp", + "imageUrl": "/images/base/sandsworn_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32253,7 +32253,7 @@ "baseStats": { "energy_shield": 78 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt05.webp", + "imageUrl": "/images/base/sandsworn_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -32276,7 +32276,7 @@ "baseStats": { "energy_shield": 78 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt04.webp", + "imageUrl": "/images/base/sandsworn_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32297,7 +32297,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/sapphire.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32318,7 +32318,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Charms/Basetypes/SapphireCharm.webp", + "imageUrl": "/images/base/sapphire_charm.webp", "affixSlots": { "prefix": 0, "suffix": 0 @@ -32339,7 +32339,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/Basetypes/SapphireRing.webp", + "imageUrl": "/images/base/sapphire_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -32360,7 +32360,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandAxes/Basetypes/2HAxe06.webp", + "imageUrl": "/images/base/savage_greataxe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32384,7 +32384,7 @@ "armour": 164, "evasion": 147 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex06.webp", + "imageUrl": "/images/base/scale_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32408,7 +32408,7 @@ "evasion": 154, "energy_shield": 51 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt06.webp", + "imageUrl": "/images/base/scalpers_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32429,7 +32429,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSwords/Basetypes/1HSword04.webp", + "imageUrl": "/images/base/scimitar.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32453,7 +32453,7 @@ "armour": 207, "evasion": 187 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex02.webp", + "imageUrl": "/images/base/scoundrel_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32477,7 +32477,7 @@ "evasion": 176, "energy_shield": 57 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt07.webp", + "imageUrl": "/images/base/scoundrel_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32500,7 +32500,7 @@ "baseStats": { "evasion": 240 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex07.webp", + "imageUrl": "/images/base/scouts_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32521,7 +32521,7 @@ "int": 50 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear10.webp", + "imageUrl": "/images/base/seaglass_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32542,7 +32542,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/seal_relic.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -32566,7 +32566,7 @@ "armour": 273, "energy_shield": 76 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr08.webp", + "imageUrl": "/images/base/seastorm_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32590,7 +32590,7 @@ "armour": 61, "energy_shield": 19 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest05.webp", + "imageUrl": "/images/base/sectarian_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -32613,7 +32613,7 @@ "baseStats": { "evasion": 68 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex04.webp", + "imageUrl": "/images/base/sectioned_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -32637,7 +32637,7 @@ "armour": 41, "energy_shield": 15 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr02.webp", + "imageUrl": "/images/base/secured_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -32661,7 +32661,7 @@ "evasion": 94, "energy_shield": 29 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt04.webp", + "imageUrl": "/images/base/secured_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -32685,7 +32685,7 @@ "armour": 88, "energy_shield": 25 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest08.webp", + "imageUrl": "/images/base/seer_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -32708,7 +32708,7 @@ "baseStats": { "energy_shield": 83 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt06.webp", + "imageUrl": "/images/base/sekhema_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -32732,7 +32732,7 @@ "armour": 123, "energy_shield": 34 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest04.webp", + "imageUrl": "/images/base/sekheman_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -32755,7 +32755,7 @@ "baseStats": { "armour": 265 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr09.webp", + "imageUrl": "/images/base/sentinel_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32778,7 +32778,7 @@ "baseStats": { "evasion": 203 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex05.webp", + "imageUrl": "/images/base/serpentscale_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -32801,7 +32801,7 @@ "baseStats": { "evasion": 260 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex08.webp", + "imageUrl": "/images/base/serpentscale_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32822,7 +32822,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Quivers/Basetypes/QuiverSerrated.webp", + "imageUrl": "/images/base/serrated_quiver.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -32845,7 +32845,7 @@ "baseStats": { "evasion": 19 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex01.webp", + "imageUrl": "/images/base/shabby_hood.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32869,7 +32869,7 @@ "evasion": 132, "energy_shield": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt07.webp", + "imageUrl": "/images/base/shaded_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32893,7 +32893,7 @@ "armour": 129, "energy_shield": 41 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr04.webp", + "imageUrl": "/images/base/shaman_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32917,7 +32917,7 @@ "armour": 123, "energy_shield": 34 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr03.webp", + "imageUrl": "/images/base/shamanistic_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -32938,7 +32938,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Claws/Basetypes/Claw10.webp", + "imageUrl": "/images/base/sharktooth_claw.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32962,7 +32962,7 @@ "armour": 97, "evasion": 87 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex05.webp", + "imageUrl": "/images/base/shielded_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -32983,7 +32983,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow02.webp", + "imageUrl": "/images/base/shortbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33004,7 +33004,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSwords/Basetypes/1HSword01.webp", + "imageUrl": "/images/base/shortsword.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33025,7 +33025,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Traps/TrapRemote01.webp", + "imageUrl": "/images/base/shrapnel_trap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33048,7 +33048,7 @@ "baseStats": { "spirit": "100" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Scepters/Basetypes/Sceptre06a.webp", + "imageUrl": "/images/base/shrine_sceptre.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33072,7 +33072,7 @@ "armour": 273, "evasion": 248 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex04.webp", + "imageUrl": "/images/base/shrouded_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33095,7 +33095,7 @@ "baseStats": { "evasion": 128 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex04.webp", + "imageUrl": "/images/base/shrouded_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33116,7 +33116,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSwords/Basetypes/1HSword06.webp", + "imageUrl": "/images/base/sickle_sword.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33137,7 +33137,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow07.webp", + "imageUrl": "/images/base/siege_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33161,7 +33161,7 @@ "armour": 20, "energy_shield": 9 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest02.webp", + "imageUrl": "/images/base/sigil_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -33185,7 +33185,7 @@ "armour": 89, "energy_shield": 25 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr01.webp", + "imageUrl": "/images/base/signet_cuffs.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -33208,7 +33208,7 @@ "baseStats": { "energy_shield": 64 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt05.webp", + "imageUrl": "/images/base/silk_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33231,7 +33231,7 @@ "baseStats": { "energy_shield": 36 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt04.webp", + "imageUrl": "/images/base/silk_slippers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -33252,7 +33252,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Charms/Basetypes/SilverCharm.webp", + "imageUrl": "/images/base/silver_charm.webp", "affixSlots": { "prefix": 0, "suffix": 0 @@ -33276,7 +33276,7 @@ "evasion": 97, "energy_shield": 31 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt02.webp", + "imageUrl": "/images/base/silverbuckled_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -33299,7 +33299,7 @@ "baseStats": { "weapon_range": "1" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Daggers/Basetypes/Dagger03.webp", + "imageUrl": "/images/base/simple_dagger.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33320,7 +33320,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Belts/Basetypes/SinewBelt.webp", + "imageUrl": "/images/base/sinew_belt.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -33341,7 +33341,7 @@ "int": 41 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff03.webp", + "imageUrl": "/images/base/sinister_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33362,7 +33362,7 @@ "int": 23 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Wands/Basetypes/Wand04.webp", + "imageUrl": "/images/base/siphoning_wand.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33385,7 +33385,7 @@ "baseStats": { "energy_shield": 54 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt06.webp", + "imageUrl": "/images/base/sirenscale_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -33408,7 +33408,7 @@ "baseStats": { "weapon_range": "1" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Daggers/Basetypes/Dagger04.webp", + "imageUrl": "/images/base/skinning_knife.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33432,7 +33432,7 @@ "evasion": 129, "energy_shield": 41 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt03.webp", + "imageUrl": "/images/base/skulking_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33453,7 +33453,7 @@ "int": 50 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff09.webp", + "imageUrl": "/images/base/skullcrusher_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33476,7 +33476,7 @@ "baseStats": { "energy_shield": 90 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt02.webp", + "imageUrl": "/images/base/skycrown_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33500,7 +33500,7 @@ "armour": 273, "evasion": 248 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex01.webp", + "imageUrl": "/images/base/slayer_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33523,7 +33523,7 @@ "baseStats": { "evasion": 177 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex03.webp", + "imageUrl": "/images/base/sleek_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -33547,7 +33547,7 @@ "evasion": 285, "energy_shield": 87 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt02.webp", + "imageUrl": "/images/base/sleek_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33568,7 +33568,7 @@ "int": 17 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Flails/Flail06.webp", + "imageUrl": "/images/base/slender_flail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33589,7 +33589,7 @@ "int": 20 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff07.webp", + "imageUrl": "/images/base/slicing_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33610,7 +33610,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace03.webp", + "imageUrl": "/images/base/slim_mace.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33633,7 +33633,7 @@ "baseStats": { "evasion": 519 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex06.webp", + "imageUrl": "/images/base/slipstrike_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33654,7 +33654,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace02.webp", + "imageUrl": "/images/base/smithing_hammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33675,7 +33675,7 @@ "int": 28 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff10.webp", + "imageUrl": "/images/base/smooth_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33698,7 +33698,7 @@ "baseStats": { "evasion": 359 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex10.webp", + "imageUrl": "/images/base/smuggler_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33719,7 +33719,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace02.webp", + "imageUrl": "/images/base/snakewood_greathammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33740,7 +33740,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow02.webp", + "imageUrl": "/images/base/snakewood_shortbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33764,7 +33764,7 @@ "evasion": 179, "energy_shield": 55 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt05.webp", + "imageUrl": "/images/base/soaring_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33785,7 +33785,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear04.webp", + "imageUrl": "/images/base/soaring_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33809,7 +33809,7 @@ "armour": 134, "evasion": 122 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield06.webp", + "imageUrl": "/images/base/soaring_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -33830,7 +33830,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/Basetypes/SolarAmulet.webp", + "imageUrl": "/images/base/solar_amulet.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -33853,7 +33853,7 @@ "baseStats": { "armour": 570 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr03.webp", + "imageUrl": "/images/base/soldier_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33876,7 +33876,7 @@ "baseStats": { "armour": 80 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr02.webp", + "imageUrl": "/images/base/soldier_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33900,7 +33900,7 @@ "armour": 143, "evasion": 129 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex03.webp", + "imageUrl": "/images/base/soldier_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33924,7 +33924,7 @@ "armour": 96, "evasion": 86 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex01.webp", + "imageUrl": "/images/base/soldiering_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -33945,7 +33945,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace06.webp", + "imageUrl": "/images/base/solemn_maul.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33969,7 +33969,7 @@ "evasion": 115, "energy_shield": 37 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt06.webp", + "imageUrl": "/images/base/solid_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -33992,7 +33992,7 @@ "baseStats": { "energy_shield": 15 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt02.webp", + "imageUrl": "/images/base/sombre_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34015,7 +34015,7 @@ "baseStats": { "energy_shield": 97 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt04.webp", + "imageUrl": "/images/base/sorcerous_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -34036,7 +34036,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Traps/Trap05.webp", + "imageUrl": "/images/base/spike_trap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -34059,7 +34059,7 @@ "baseStats": { "evasion": 135 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex05.webp", + "imageUrl": "/images/base/spiked_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34082,7 +34082,7 @@ "baseStats": { "evasion": 64 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler06.webp", + "imageUrl": "/images/base/spiked_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34103,7 +34103,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace04.webp", + "imageUrl": "/images/base/spiked_club.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -34124,7 +34124,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear07.webp", + "imageUrl": "/images/base/spiked_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -34147,7 +34147,7 @@ "baseStats": { "evasion": 124 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler06.webp", + "imageUrl": "/images/base/spikeward_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34170,7 +34170,7 @@ "baseStats": { "evasion": 79 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex05.webp", + "imageUrl": "/images/base/spined_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34191,7 +34191,7 @@ "int": 65 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/NettleTalisman.webp", + "imageUrl": "/images/base/spiny_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -34215,7 +34215,7 @@ "evasion": 43, "energy_shield": 15 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt03.webp", + "imageUrl": "/images/base/spiral_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34238,7 +34238,7 @@ "baseStats": { "armour": 149 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr04.webp", + "imageUrl": "/images/base/spired_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -34262,7 +34262,7 @@ "armour": 128, "energy_shield": 37 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr06.webp", + "imageUrl": "/images/base/spiritbone_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -34283,7 +34283,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Flails/Flail01.webp", + "imageUrl": "/images/base/splintered_flail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -34306,7 +34306,7 @@ "baseStats": { "armour": 18 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower01.webp", + "imageUrl": "/images/base/splintered_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34327,7 +34327,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandAxes/Basetypes/2HAxe01.webp", + "imageUrl": "/images/base/splitting_greataxe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -34348,7 +34348,7 @@ "int": 23 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Staves/Basetypes/Staff04.webp", + "imageUrl": "/images/base/spriggan_staff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -34372,7 +34372,7 @@ "armour": 73, "evasion": 65 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex03.webp", + "imageUrl": "/images/base/stacked_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34395,7 +34395,7 @@ "baseStats": { "energy_shield": 45 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus03.webp", + "imageUrl": "/images/base/staghorn_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34416,7 +34416,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Belts/Basetypes/StalkingBelt.webp", + "imageUrl": "/images/base/stalking_belt.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34439,7 +34439,7 @@ "baseStats": { "evasion": 148 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex02.webp", + "imageUrl": "/images/base/stalking_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34460,7 +34460,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear03.webp", + "imageUrl": "/images/base/stalking_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -34481,7 +34481,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Charms/Basetypes/StaunchingCharm.webp", + "imageUrl": "/images/base/staunching_charm.webp", "affixSlots": { "prefix": 0, "suffix": 0 @@ -34504,7 +34504,7 @@ "baseStats": { "armour": 228 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr06.webp", + "imageUrl": "/images/base/steel_plate.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -34525,7 +34525,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear02.webp", + "imageUrl": "/images/base/steelhead_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -34549,7 +34549,7 @@ "armour": 89, "evasion": 81 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex01.webp", + "imageUrl": "/images/base/steelmail_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34570,7 +34570,7 @@ "int": 18 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff06.webp", + "imageUrl": "/images/base/steelpoint_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -34594,7 +34594,7 @@ "evasion": 86, "energy_shield": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt04.webp", + "imageUrl": "/images/base/steelpoint_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34617,7 +34617,7 @@ "baseStats": { "evasion": 102 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex04.webp", + "imageUrl": "/images/base/steeltoe_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34638,7 +34638,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/Basetypes/StellarAmulet.webp", + "imageUrl": "/images/base/stellar_amulet.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34661,7 +34661,7 @@ "baseStats": { "energy_shield": 18 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt03.webp", + "imageUrl": "/images/base/stitched_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34684,7 +34684,7 @@ "baseStats": { "armour": 15 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr01.webp", + "imageUrl": "/images/base/stocky_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34708,7 +34708,7 @@ "armour": 91, "energy_shield": 26 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest01.webp", + "imageUrl": "/images/base/stoic_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34731,7 +34731,7 @@ "baseStats": { "spirit": "100" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Scepters/Basetypes/Sceptre02.webp", + "imageUrl": "/images/base/stoic_sceptre.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -34752,7 +34752,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Charms/Basetypes/StoneCharm.webp", + "imageUrl": "/images/base/stone_charm.webp", "affixSlots": { "prefix": 0, "suffix": 0 @@ -34775,7 +34775,7 @@ "baseStats": { "armour": 474 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr08.webp", + "imageUrl": "/images/base/stone_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -34796,7 +34796,7 @@ "int": 20 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Flails/Flail07.webp", + "imageUrl": "/images/base/stone_flail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -34817,7 +34817,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandSwords/Basetypes/2HSword07.webp", + "imageUrl": "/images/base/stone_greatsword.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -34840,7 +34840,7 @@ "baseStats": { "armour": 133 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr05.webp", + "imageUrl": "/images/base/stone_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34864,7 +34864,7 @@ "armour": 102, "evasion": 93 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield05.webp", + "imageUrl": "/images/base/stone_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34887,7 +34887,7 @@ "baseStats": { "armour": 119 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower08.webp", + "imageUrl": "/images/base/stone_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34908,7 +34908,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow03.webp", + "imageUrl": "/images/base/stout_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -34932,7 +34932,7 @@ "armour": 82, "evasion": 74 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield07.webp", + "imageUrl": "/images/base/stratified_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34955,7 +34955,7 @@ "baseStats": { "energy_shield": 14 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt01.webp", + "imageUrl": "/images/base/straw_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -34978,7 +34978,7 @@ "baseStats": { "evasion": 366 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex01.webp", + "imageUrl": "/images/base/strider_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -34999,7 +34999,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace05.webp", + "imageUrl": "/images/base/strife_pick.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35020,7 +35020,7 @@ "int": 50 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff02.webp", + "imageUrl": "/images/base/striking_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35041,7 +35041,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear12.webp", + "imageUrl": "/images/base/striking_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35062,7 +35062,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace08.webp", + "imageUrl": "/images/base/structured_hammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35085,7 +35085,7 @@ "baseStats": { "evasion": 186 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDex04.webp", + "imageUrl": "/images/base/studded_boots.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -35106,7 +35106,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace04.webp", + "imageUrl": "/images/base/studded_greatclub.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35129,7 +35129,7 @@ "baseStats": { "energy_shield": 57 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt01.webp", + "imageUrl": "/images/base/studded_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -35153,7 +35153,7 @@ "armour": 34, "evasion": 29 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield03.webp", + "imageUrl": "/images/base/studded_targe.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -35176,7 +35176,7 @@ "baseStats": { "evasion": 194 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex06.webp", + "imageUrl": "/images/base/studded_vest.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35197,7 +35197,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow03.webp", + "imageUrl": "/images/base/sturdy_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35220,7 +35220,7 @@ "baseStats": { "evasion": 10 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex01.webp", + "imageUrl": "/images/base/suede_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -35243,7 +35243,7 @@ "baseStats": { "evasion": 127 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex04.webp", + "imageUrl": "/images/base/swathed_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35266,7 +35266,7 @@ "baseStats": { "evasion": 118 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDex03.webp", + "imageUrl": "/images/base/swift_bracers.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -35287,7 +35287,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear05.webp", + "imageUrl": "/images/base/swift_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35310,7 +35310,7 @@ "baseStats": { "evasion": 451 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex03.webp", + "imageUrl": "/images/base/swiftstalker_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35331,7 +35331,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear11.webp", + "imageUrl": "/images/base/sword_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35352,7 +35352,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Claws/Basetypes/Claw13.webp", + "imageUrl": "/images/base/talon_claw.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35373,7 +35373,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/tapestry_relic.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -35396,7 +35396,7 @@ "baseStats": { "energy_shield": 91 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus10.webp", + "imageUrl": "/images/base/tasalian_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -35419,7 +35419,7 @@ "baseStats": { "armour": 280 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr06.webp", + "imageUrl": "/images/base/tasalian_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -35442,7 +35442,7 @@ "baseStats": { "energy_shield": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt01.webp", + "imageUrl": "/images/base/tattered_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35463,7 +35463,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow02.webp", + "imageUrl": "/images/base/taut_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35484,7 +35484,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace10.webp", + "imageUrl": "/images/base/tawhoan_greatclub.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35507,7 +35507,7 @@ "baseStats": { "armour": 264 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower10.webp", + "imageUrl": "/images/base/tawhoan_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -35528,7 +35528,7 @@ "int": 29 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Flails/Flail11.webp", + "imageUrl": "/images/base/tearing_flail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35551,7 +35551,7 @@ "baseStats": { "armour": 49 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr03.webp", + "imageUrl": "/images/base/tempered_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -35575,7 +35575,7 @@ "armour": 195, "energy_shield": 57 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr01.webp", + "imageUrl": "/images/base/templar_vestments.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35596,7 +35596,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace06.webp", + "imageUrl": "/images/base/temple_maul.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35617,7 +35617,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/temple_tablet.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -35638,7 +35638,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/HeistAmulet2.webp", + "imageUrl": "/images/base/tenebrous_amulet.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -35662,7 +35662,7 @@ "armour": 179, "energy_shield": 50 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr08.webp", + "imageUrl": "/images/base/tenebrous_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35683,7 +35683,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/LakeRing4.webp", + "imageUrl": "/images/base/tenebrous_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -35704,7 +35704,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow02.webp", + "imageUrl": "/images/base/tense_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35728,7 +35728,7 @@ "armour": 98, "energy_shield": 27 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesIntStr04.webp", + "imageUrl": "/images/base/tethering_bands.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -35752,7 +35752,7 @@ "armour": 273, "evasion": 248 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex08.webp", + "imageUrl": "/images/base/thane_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35773,7 +35773,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Charms/Basetypes/ThawingCharm.webp", + "imageUrl": "/images/base/thawing_charm.webp", "affixSlots": { "prefix": 0, "suffix": 0 @@ -35797,7 +35797,7 @@ "evasion": 35, "energy_shield": 15 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt02.webp", + "imageUrl": "/images/base/threaded_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -35818,7 +35818,7 @@ "int": 72 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/VoltfangTalisman.webp", + "imageUrl": "/images/base/thunder_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35842,7 +35842,7 @@ "armour": 218, "energy_shield": 63 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr08.webp", + "imageUrl": "/images/base/tideseer_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35863,7 +35863,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/time_lost_diamond.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35884,7 +35884,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/time_lost_emerald.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35905,7 +35905,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/time_lost_ruby.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35926,7 +35926,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/time_lost_sapphire.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -35949,7 +35949,7 @@ "baseStats": { "armour": 132 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr07.webp", + "imageUrl": "/images/base/titan_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -35972,7 +35972,7 @@ "baseStats": { "energy_shield": 26 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus05.webp", + "imageUrl": "/images/base/tonal_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -35993,7 +35993,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Charms/Basetypes/TopazCharm.webp", + "imageUrl": "/images/base/topaz_charm.webp", "affixSlots": { "prefix": 0, "suffix": 0 @@ -36014,7 +36014,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/Basetypes/TopazRing.webp", + "imageUrl": "/images/base/topaz_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -36035,7 +36035,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace01.webp", + "imageUrl": "/images/base/torment_club.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -36059,7 +36059,7 @@ "evasion": 248, "energy_shield": 76 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt01.webp", + "imageUrl": "/images/base/torment_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -36082,7 +36082,7 @@ "baseStats": { "energy_shield": 9 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt01.webp", + "imageUrl": "/images/base/torn_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -36103,7 +36103,7 @@ "int": 87 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Wands/Basetypes/Wand09.webp", + "imageUrl": "/images/base/torture_wand.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -36124,7 +36124,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace10.webp", + "imageUrl": "/images/base/totemic_greatclub.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -36147,7 +36147,7 @@ "baseStats": { "armour": 244 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr08.webp", + "imageUrl": "/images/base/totemic_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -36171,7 +36171,7 @@ "armour": 273, "evasion": 248 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex12a.webp", + "imageUrl": "/images/base/tournament_mail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -36192,7 +36192,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Quivers/Basetypes/QuiverToxic.webp", + "imageUrl": "/images/base/toxic_quiver.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -36216,7 +36216,7 @@ "armour": 249, "evasion": 226 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex05.webp", + "imageUrl": "/images/base/trailblazer_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -36237,7 +36237,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Flasks/Basetypes/FlaskLife08.webp", + "imageUrl": "/images/base/transcendent_life_flask.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -36258,7 +36258,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Flasks/Basetypes/FlaskMana08.webp", + "imageUrl": "/images/base/transcendent_mana_flask.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -36281,7 +36281,7 @@ "baseStats": { "evasion": 326 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex05.webp", + "imageUrl": "/images/base/trapper_hood.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -36302,7 +36302,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/HandCannon.webp", + "imageUrl": "/images/base/trarthan_cannon.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -36323,7 +36323,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSwords/Basetypes/1HSword08.webp", + "imageUrl": "/images/base/treasured_blade.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -36347,7 +36347,7 @@ "evasion": 111, "energy_shield": 34 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt03.webp", + "imageUrl": "/images/base/treerunner_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -36368,7 +36368,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow10.webp", + "imageUrl": "/images/base/tribal_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -36392,7 +36392,7 @@ "evasion": 87, "energy_shield": 30 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt05.webp", + "imageUrl": "/images/base/tribal_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -36415,7 +36415,7 @@ "baseStats": { "armour": 112 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr04.webp", + "imageUrl": "/images/base/trimmed_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -36438,7 +36438,7 @@ "baseStats": { "energy_shield": 19 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt01.webp", + "imageUrl": "/images/base/twig_circlet.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -36461,7 +36461,7 @@ "baseStats": { "energy_shield": 12 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus01.webp", + "imageUrl": "/images/base/twig_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -36484,7 +36484,7 @@ "baseStats": { "energy_shield": 82 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt10.webp", + "imageUrl": "/images/base/twilight_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -36505,7 +36505,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow06.webp", + "imageUrl": "/images/base/twin_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -36526,7 +36526,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow05.webp", + "imageUrl": "/images/base/twin_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -36547,7 +36547,7 @@ "int": 14 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Flails/Flail05.webp", + "imageUrl": "/images/base/twin_flail.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -36568,7 +36568,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/Basetypes/TwistedAmulet.webp", + "imageUrl": "/images/base/twisted_amulet.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -36589,7 +36589,7 @@ "int": 114 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Wands/Basetypes/Wand01.webp", + "imageUrl": "/images/base/twisted_wand.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -36610,7 +36610,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Quivers/Basetypes/QuiverTwoPoint.webp", + "imageUrl": "/images/base/two_point_quiver.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -36631,7 +36631,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/Basetypes/IronRing.webp", + "imageUrl": "/images/base/two_stone_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -36652,7 +36652,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Flasks/Basetypes/FlaskLife09.webp", + "imageUrl": "/images/base/ultimate_life_flask.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -36673,7 +36673,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Flasks/Basetypes/FlaskMana09.webp", + "imageUrl": "/images/base/ultimate_mana_flask.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -36694,7 +36694,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandSwords/Basetypes/2HSword13.webp", + "imageUrl": "/images/base/ultra_greatsword.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -36715,7 +36715,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/Basetypes/UnsetRing.webp", + "imageUrl": "/images/base/unset_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -36736,7 +36736,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/urn_relic.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -36757,7 +36757,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Traps/Trap03.webp", + "imageUrl": "/images/base/urn_trap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -36778,7 +36778,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Belts/Basetypes/Belt10.webp", + "imageUrl": "/images/base/utility_belt.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -36802,7 +36802,7 @@ "evasion": 81, "energy_shield": 25 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt01.webp", + "imageUrl": "/images/base/utility_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -36825,7 +36825,7 @@ "baseStats": { "armour": 496 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr08.webp", + "imageUrl": "/images/base/utzaal_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -36849,7 +36849,7 @@ "armour": 134, "energy_shield": 37 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest06.webp", + "imageUrl": "/images/base/vaal_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -36872,7 +36872,7 @@ "baseStats": { "armour": 298 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr08.webp", + "imageUrl": "/images/base/vaal_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -36895,7 +36895,7 @@ "baseStats": { "energy_shield": 51 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesInt05.webp", + "imageUrl": "/images/base/vaal_gloves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -36918,7 +36918,7 @@ "baseStats": { "armour": 268 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStr05.webp", + "imageUrl": "/images/base/vaal_greaves.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -36941,7 +36941,7 @@ "baseStats": { "armour": 179 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStr05.webp", + "imageUrl": "/images/base/vaal_mitts.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -36964,7 +36964,7 @@ "baseStats": { "armour": 244 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Tower08.webp", + "imageUrl": "/images/base/vaal_tower_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -36988,7 +36988,7 @@ "evasion": 90, "energy_shield": 27 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt03.webp", + "imageUrl": "/images/base/vaal_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -37012,7 +37012,7 @@ "armour": 83, "evasion": 71 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex03.webp", + "imageUrl": "/images/base/vagabond_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37033,7 +37033,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSwords/Basetypes/1HSword03.webp", + "imageUrl": "/images/base/vampiric_blade.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37054,7 +37054,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Crossbows/2HCrossbow04.webp", + "imageUrl": "/images/base/varnished_crossbow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37075,7 +37075,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/art/2ditems/maps/endgamemaps/endgamemap1.webp", + "imageUrl": "/images/base/vase_relic.webp", "affixSlots": { "prefix": 1, "suffix": 1 @@ -37099,7 +37099,7 @@ "evasion": 75, "energy_shield": 27 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDexInt04.webp", + "imageUrl": "/images/base/veiled_mask.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37123,7 +37123,7 @@ "evasion": 99, "energy_shield": 31 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt01.webp", + "imageUrl": "/images/base/velour_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -37146,7 +37146,7 @@ "baseStats": { "evasion": 240 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex09.webp", + "imageUrl": "/images/base/velvet_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37170,7 +37170,7 @@ "armour": 107, "evasion": 97 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Shield10.webp", + "imageUrl": "/images/base/venerable_defender.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -37194,7 +37194,7 @@ "armour": 230, "energy_shield": 65 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr10.webp", + "imageUrl": "/images/base/venerated_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37215,7 +37215,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Amulets/Basetypes/BloodstoneAmulet.webp", + "imageUrl": "/images/base/veridical_chain.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -37238,7 +37238,7 @@ "baseStats": { "energy_shield": 68 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt07.webp", + "imageUrl": "/images/base/vermeil_circlet.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37262,7 +37262,7 @@ "armour": 134, "evasion": 122 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsStrDex01.webp", + "imageUrl": "/images/base/veteran_sabatons.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -37283,7 +37283,7 @@ "int": 34 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/ViciousTalisman.webp", + "imageUrl": "/images/base/vicious_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37304,7 +37304,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandAxes/Basetypes/2HAxe13.webp", + "imageUrl": "/images/base/vile_greataxe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37327,7 +37327,7 @@ "baseStats": { "energy_shield": 171 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt03.webp", + "imageUrl": "/images/base/vile_robe.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37350,7 +37350,7 @@ "baseStats": { "evasion": 179 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex06.webp", + "imageUrl": "/images/base/viper_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37371,7 +37371,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Quivers/Basetypes/QuiverVisceral.webp", + "imageUrl": "/images/base/visceral_quiver.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -37395,7 +37395,7 @@ "armour": 54, "evasion": 46 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex03.webp", + "imageUrl": "/images/base/visored_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37416,7 +37416,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Rings/BreachlordRing_Xoph.webp", + "imageUrl": "/images/base/vitalic_ring.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -37437,7 +37437,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Quivers/Basetypes/QuiverVolant.webp", + "imageUrl": "/images/base/volant_quiver.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -37458,7 +37458,7 @@ "int": 31 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Wands/Basetypes/Wand05.webp", + "imageUrl": "/images/base/volatile_wand.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37479,7 +37479,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Staves/Basetypes/Staff03.webp", + "imageUrl": "/images/base/voltaic_staff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37500,7 +37500,7 @@ "int": 38 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/VoltfangTalisman.webp", + "imageUrl": "/images/base/voltfang_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37523,7 +37523,7 @@ "baseStats": { "energy_shield": 34 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus07.webp", + "imageUrl": "/images/base/voodoo_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -37546,7 +37546,7 @@ "baseStats": { "energy_shield": 83 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyInt07.webp", + "imageUrl": "/images/base/votive_raiment.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37570,7 +37570,7 @@ "armour": 218, "evasion": 197 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStrDex03.webp", + "imageUrl": "/images/base/wanderer_armour.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37594,7 +37594,7 @@ "evasion": 122, "energy_shield": 37 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt01.webp", + "imageUrl": "/images/base/wanderer_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -37615,7 +37615,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear05.webp", + "imageUrl": "/images/base/war_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37639,7 +37639,7 @@ "evasion": 94, "energy_shield": 29 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesDexInt01.webp", + "imageUrl": "/images/base/war_wraps.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -37663,7 +37663,7 @@ "armour": 179, "evasion": 163 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStrDex02.webp", + "imageUrl": "/images/base/warded_helm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37684,7 +37684,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow03.webp", + "imageUrl": "/images/base/warden_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37705,7 +37705,7 @@ "int": 50 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff10.webp", + "imageUrl": "/images/base/warding_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37729,7 +37729,7 @@ "armour": 134, "energy_shield": 37 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr03.webp", + "imageUrl": "/images/base/warlock_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -37752,7 +37752,7 @@ "baseStats": { "armour": 496 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyStr10.webp", + "imageUrl": "/images/base/warlord_cuirass.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37773,7 +37773,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow08.webp", + "imageUrl": "/images/base/warmonger_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37796,7 +37796,7 @@ "baseStats": { "armour": 325 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr02.webp", + "imageUrl": "/images/base/warmonger_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37817,7 +37817,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace05.webp", + "imageUrl": "/images/base/warpick.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37840,7 +37840,7 @@ "baseStats": { "armour": 191 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr06.webp", + "imageUrl": "/images/base/warrior_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37864,7 +37864,7 @@ "evasion": 53, "energy_shield": 25 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt02.webp", + "imageUrl": "/images/base/waxed_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37885,7 +37885,7 @@ "int": 30 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff05.webp", + "imageUrl": "/images/base/waxing_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37909,7 +37909,7 @@ "evasion": 114, "energy_shield": 41 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDexInt04.webp", + "imageUrl": "/images/base/wayfarer_jacket.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37933,7 +37933,7 @@ "evasion": 86, "energy_shield": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsDexInt01.webp", + "imageUrl": "/images/base/wayfarer_shoes.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -37956,7 +37956,7 @@ "baseStats": { "area_level": 65 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Maps/EndgameMaps/EndgameMap1.webp", + "imageUrl": "/images/base/waystone_tier_1.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -37979,7 +37979,7 @@ "baseStats": { "area_level": 74 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Maps/EndgameMaps/EndgameMap10.webp", + "imageUrl": "/images/base/waystone_tier_10.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38002,7 +38002,7 @@ "baseStats": { "area_level": 75 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Maps/EndgameMaps/EndgameMap11.webp", + "imageUrl": "/images/base/waystone_tier_11.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38025,7 +38025,7 @@ "baseStats": { "area_level": 76 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Maps/EndgameMaps/EndgameMap12.webp", + "imageUrl": "/images/base/waystone_tier_12.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38048,7 +38048,7 @@ "baseStats": { "area_level": 77 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Maps/EndgameMaps/EndgameMap13.webp", + "imageUrl": "/images/base/waystone_tier_13.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38071,7 +38071,7 @@ "baseStats": { "area_level": 78 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Maps/EndgameMaps/EndgameMap14.webp", + "imageUrl": "/images/base/waystone_tier_14.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38094,7 +38094,7 @@ "baseStats": { "area_level": 79 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Maps/EndgameMaps/EndgameMap15.webp", + "imageUrl": "/images/base/waystone_tier_15.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38117,7 +38117,7 @@ "baseStats": { "area_level": 80 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Maps/EndgameMaps/EndgameMap16.webp", + "imageUrl": "/images/base/waystone_tier_16.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38140,7 +38140,7 @@ "baseStats": { "area_level": 66 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Maps/EndgameMaps/EndgameMap2.webp", + "imageUrl": "/images/base/waystone_tier_2.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38163,7 +38163,7 @@ "baseStats": { "area_level": 67 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Maps/EndgameMaps/EndgameMap3.webp", + "imageUrl": "/images/base/waystone_tier_3.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38186,7 +38186,7 @@ "baseStats": { "area_level": 68 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Maps/EndgameMaps/EndgameMap4.webp", + "imageUrl": "/images/base/waystone_tier_4.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38209,7 +38209,7 @@ "baseStats": { "area_level": 69 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Maps/EndgameMaps/EndgameMap5.webp", + "imageUrl": "/images/base/waystone_tier_5.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38232,7 +38232,7 @@ "baseStats": { "area_level": 70 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Maps/EndgameMaps/EndgameMap6.webp", + "imageUrl": "/images/base/waystone_tier_6.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38255,7 +38255,7 @@ "baseStats": { "area_level": 71 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Maps/EndgameMaps/EndgameMap7.webp", + "imageUrl": "/images/base/waystone_tier_7.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38278,7 +38278,7 @@ "baseStats": { "area_level": 72 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Maps/EndgameMaps/EndgameMap8.webp", + "imageUrl": "/images/base/waystone_tier_8.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38301,7 +38301,7 @@ "baseStats": { "area_level": 73 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Maps/EndgameMaps/EndgameMap9.webp", + "imageUrl": "/images/base/waystone_tier_9.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38325,7 +38325,7 @@ "armour": 80, "energy_shield": 23 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Crest07.webp", + "imageUrl": "/images/base/wayward_crest_shield.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -38349,7 +38349,7 @@ "armour": 96, "energy_shield": 28 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsIntStr04.webp", + "imageUrl": "/images/base/weaver_leggings.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -38372,7 +38372,7 @@ "baseStats": { "energy_shield": 47 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus10.webp", + "imageUrl": "/images/base/whorl_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -38395,7 +38395,7 @@ "baseStats": { "energy_shield": 29 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetInt02.webp", + "imageUrl": "/images/base/wicker_tiara.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38416,7 +38416,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Belts/Basetypes/Belt03.webp", + "imageUrl": "/images/base/wide_belt.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -38437,7 +38437,7 @@ "int": 72 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/ViciousTalisman.webp", + "imageUrl": "/images/base/wildwood_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38458,7 +38458,7 @@ "int": 52 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Talismans/WingbeatTalisman.webp", + "imageUrl": "/images/base/wingbeat_talisman.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38479,7 +38479,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandSpears/1HSpear04.webp", + "imageUrl": "/images/base/winged_spear.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38500,7 +38500,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Wands/Basetypes/Wand01.webp", + "imageUrl": "/images/base/withered_wand.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38521,7 +38521,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Claws/Basetypes/Claw03.webp", + "imageUrl": "/images/base/wolfbone_claw.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38545,7 +38545,7 @@ "armour": 313, "energy_shield": 87 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr02.webp", + "imageUrl": "/images/base/wolfskin_mantle.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38568,7 +38568,7 @@ "baseStats": { "evasion": 18 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Shields/Buckler02.webp", + "imageUrl": "/images/base/wooden_buckler.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -38589,7 +38589,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/OneHandMaces/Basetypes/1HMace01.webp", + "imageUrl": "/images/base/wooden_club.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38612,7 +38612,7 @@ "baseStats": { "evasion": 222 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex02.webp", + "imageUrl": "/images/base/wool_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38635,7 +38635,7 @@ "baseStats": { "evasion": 296 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex02.webp", + "imageUrl": "/images/base/woven_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38658,7 +38658,7 @@ "baseStats": { "energy_shield": 15 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus02.webp", + "imageUrl": "/images/base/woven_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -38681,7 +38681,7 @@ "baseStats": { "evasion": 248 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetDex04.webp", + "imageUrl": "/images/base/wrapped_cap.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38704,7 +38704,7 @@ "baseStats": { "armour": 99 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetStr03.webp", + "imageUrl": "/images/base/wrapped_greathelm.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38725,7 +38725,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff01.webp", + "imageUrl": "/images/base/wrapped_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38748,7 +38748,7 @@ "baseStats": { "energy_shield": 22 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Boots/Basetypes/BootsInt02.webp", + "imageUrl": "/images/base/wrapped_sandals.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -38771,7 +38771,7 @@ "baseStats": { "spirit": "100" }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/OneHandWeapons/Scepters/Basetypes/Sceptre10.webp", + "imageUrl": "/images/base/wrath_sceptre.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38794,7 +38794,7 @@ "baseStats": { "energy_shield": 42 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Offhand/Foci/Basetypes/Focus02.webp", + "imageUrl": "/images/base/wreath_focus.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -38815,7 +38815,7 @@ "int": 36 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/WarStaves/Warstaff01.webp", + "imageUrl": "/images/base/wyrm_quarterstaff.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38838,7 +38838,7 @@ "baseStats": { "evasion": 451 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyDex08.webp", + "imageUrl": "/images/base/wyrmscale_coat.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38859,7 +38859,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/Bows/Basetypes/Bow08.webp", + "imageUrl": "/images/base/zealot_bow.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38883,7 +38883,7 @@ "armour": 143, "energy_shield": 41 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Helmets/Basetypes/HelmetIntStr03.webp", + "imageUrl": "/images/base/zealot_crown.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38907,7 +38907,7 @@ "armour": 82, "evasion": 74 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/Gloves/Basetypes/GlovesStrDex03.webp", + "imageUrl": "/images/base/zealot_gauntlets.webp", "affixSlots": { "prefix": 2, "suffix": 2 @@ -38928,7 +38928,7 @@ "int": 0 }, "baseStats": {}, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandMaces/Basetypes/2HMace05.webp", + "imageUrl": "/images/base/zealot_greathammer.webp", "affixSlots": { "prefix": 3, "suffix": 3 @@ -38952,7 +38952,7 @@ "armour": 273, "energy_shield": 76 }, - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Armours/BodyArmours/Basetypes/BodyIntStr13.webp", + "imageUrl": "/images/base/zenith_vestments.webp", "affixSlots": { "prefix": 3, "suffix": 3 diff --git a/public/data/currency.json b/public/data/currency.json index eaa7135..ffc01d9 100644 --- a/public/data/currency.json +++ b/public/data/currency.json @@ -10,7 +10,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Expedition2/ChippedVerisium.webp", + "imageUrl": "/images/currency/adaptive_alloy.webp", "stackSize": 10 }, { @@ -24,7 +24,7 @@ "description": "Adds quality that enhances Attribute modifiers on a ring or amulet Replaces other quality types", "effect": "Adds quality that enhances Attribute modifiers on a ring or amulet Replaces other quality types", "mechanics": "Adds quality that enhances Attribute modifiers on a ring or amulet Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/BreachCatalystAttribute.webp", + "imageUrl": "/images/currency/adaptive_catalyst.webp", "stackSize": 10 }, { @@ -38,7 +38,7 @@ "description": "Desecrates a Rare Amulet, Ring or Belt", "effect": "Desecrates a Rare Amulet, Ring or Belt", "mechanics": "Desecrates a Rare Amulet, Ring or Belt", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Abyss/AncientClavicle.webp", + "imageUrl": "/images/currency/ancient_collarbone.webp", "stackSize": 20, "minModifierLevel": 40 }, @@ -53,7 +53,7 @@ "description": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/TimelostConcentratedDistilledFear.webp", + "imageUrl": "/images/currency/ancient_concentrated_liquid_fear.webp", "stackSize": 10 }, { @@ -67,7 +67,7 @@ "description": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/TimelostConcentratedDistilledIsolation.webp", + "imageUrl": "/images/currency/ancient_concentrated_liquid_isolation.webp", "stackSize": 10 }, { @@ -81,7 +81,7 @@ "description": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/TimelostConcentratedDistilledSuffering.webp", + "imageUrl": "/images/currency/ancient_concentrated_liquid_suffering.webp", "stackSize": 10 }, { @@ -95,7 +95,7 @@ "description": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/TimelostDilutedDistilledGreed.webp", + "imageUrl": "/images/currency/ancient_diluted_liquid_greed.webp", "stackSize": 10 }, { @@ -109,7 +109,7 @@ "description": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/TimelostDilutedDistilledGuilt.webp", + "imageUrl": "/images/currency/ancient_diluted_liquid_guilt.webp", "stackSize": 10 }, { @@ -123,7 +123,7 @@ "description": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/TimelostDilutedDistilledIre.webp", + "imageUrl": "/images/currency/ancient_diluted_liquid_ire.webp", "stackSize": 10 }, { @@ -137,7 +137,7 @@ "description": "Desecrates a Rare Weapon or Quiver", "effect": "Desecrates a Rare Weapon or Quiver", "mechanics": "Desecrates a Rare Weapon or Quiver", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Abyss/AncientJawbone.webp", + "imageUrl": "/images/currency/ancient_jawbone.webp", "stackSize": 20, "minModifierLevel": 40 }, @@ -152,7 +152,7 @@ "description": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/TimelostDistilledDespair.webp", + "imageUrl": "/images/currency/ancient_liquid_despair.webp", "stackSize": 10 }, { @@ -166,7 +166,7 @@ "description": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/TimelostDistilledDisgust.webp", + "imageUrl": "/images/currency/ancient_liquid_disgust.webp", "stackSize": 10 }, { @@ -180,7 +180,7 @@ "description": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/TimelostDistilledEnvy.webp", + "imageUrl": "/images/currency/ancient_liquid_envy.webp", "stackSize": 10 }, { @@ -194,7 +194,7 @@ "description": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/TimelostDistilledParanoia.webp", + "imageUrl": "/images/currency/ancient_liquid_paranoia.webp", "stackSize": 10 }, { @@ -208,7 +208,7 @@ "description": "Reforges a unique equipment as another of the same item class", "effect": "Reforges a unique equipment as another of the same item class", "mechanics": "Reforges a unique equipment as another of the same item class", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/AncientOrb.webp", + "imageUrl": "/images/currency/ancient_orb.webp", "stackSize": 20 }, { @@ -222,7 +222,7 @@ "description": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/TimelessUniqueBeastEmotion.webp", + "imageUrl": "/images/currency/ancient_potent_liquid_contempt.webp", "stackSize": 10 }, { @@ -236,7 +236,7 @@ "description": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/TimlessUniqueConstructsEmotion.webp", + "imageUrl": "/images/currency/ancient_potent_liquid_ferocity.webp", "stackSize": 10 }, { @@ -250,7 +250,7 @@ "description": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Time-Lost Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/TimelessUniqueHumansEmotion.webp", + "imageUrl": "/images/currency/ancient_potent_liquid_melancholy.webp", "stackSize": 10 }, { @@ -264,7 +264,7 @@ "description": "Desecrates a Rare Armour", "effect": "Desecrates a Rare Armour", "mechanics": "Desecrates a Rare Armour", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Abyss/AncientRibs.webp", + "imageUrl": "/images/currency/ancient_rib.webp", "stackSize": 20, "minModifierLevel": 40 }, @@ -279,7 +279,7 @@ "description": "Improves the quality of a wand, staff or sceptre", "effect": "Improves the quality of a wand, staff or sceptre", "mechanics": "Improves the quality of a wand, staff or sceptre", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyWeaponMagicQuality.webp", + "imageUrl": "/images/currency/arcanists_etcher.webp", "stackSize": 20 }, { @@ -293,7 +293,7 @@ "description": "Improves the quality of an armour", "effect": "Improves the quality of an armour", "mechanics": "Improves the quality of an armour", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyArmourQuality.webp", + "imageUrl": "/images/currency/armourers_scrap.webp", "stackSize": 20 }, { @@ -307,7 +307,7 @@ "description": "Adds an Augment Socket to a Martial Weapon, wand, staff or Armour", "effect": "Adds an Augment Socket to a Martial Weapon, wand, staff or Armour", "mechanics": "Adds an Augment Socket to a Martial Weapon, wand, staff or Armour", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyAddEquipmentSocket.webp", + "imageUrl": "/images/currency/artificers_orb.webp", "stackSize": 20 }, { @@ -321,7 +321,7 @@ "description": "NameShow Full Descriptions Currency Exchange100 Gold NoteCodeartificers-shard DropLevel 5 BaseType Artificer's Shard Class Stackable Currency FlagsAlwaysAllocate TypeMetadata/Items/Currency/CurrencyAddEquipmentSocketShard SoundAudio/Sound Effects/ItemSounds/4.0/Currency/Orbs/OrbUse.ogg Tagscurrency_shard, currency IconArt/2DItems/Currency/CurrencyAddEquipmentSocketShard", "effect": "NameShow Full Descriptions Currency Exchange100 Gold NoteCodeartificers-shard DropLevel 5 BaseType Artificer's Shard Class Stackable Currency FlagsAlwaysAllocate TypeMetadata/Items/Currency/CurrencyAddEquipmentSocketShard SoundAudio/Sound Effects/ItemSounds/4.0/Currency/Orbs/OrbUse.ogg Tagscurrency_shard, currency IconArt/2DItems/Currency/CurrencyAddEquipmentSocketShard", "mechanics": "NameShow Full Descriptions Currency Exchange100 Gold NoteCodeartificers-shard DropLevel 5 BaseType Artificer's Shard Class Stackable Currency FlagsAlwaysAllocate TypeMetadata/Items/Currency/CurrencyAddEquipmentSocketShard SoundAudio/Sound Effects/ItemSounds/4.0/Currency/Orbs/OrbUse.ogg Tagscurrency_shard, currency IconArt/2DItems/Currency/CurrencyAddEquipmentSocketShard", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyAddEquipmentSocketShard.webp", + "imageUrl": "/images/currency/artificers_shard.webp", "stackSize": 10 }, { @@ -335,7 +335,7 @@ "description": "Improves the quality of a martial weapon", "effect": "Improves the quality of a martial weapon", "mechanics": "Improves the quality of a martial weapon", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyWeaponQuality.webp", + "imageUrl": "/images/currency/blacksmiths_whetstone.webp", "stackSize": 20 }, { @@ -349,7 +349,7 @@ "description": "Adds quality that enhances Armour, Evasion and Energy Shield modifiers on a ring or amulet Replaces other quality types", "effect": "Adds quality that enhances Armour, Evasion and Energy Shield modifiers on a ring or amulet Replaces other quality types", "mechanics": "Adds quality that enhances Armour, Evasion and Energy Shield modifiers on a ring or amulet Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/BreachCatalystDefences.webp", + "imageUrl": "/images/currency/carapace_catalyst.webp", "stackSize": 10 }, { @@ -363,7 +363,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Expedition2/Alloy4.webp", + "imageUrl": "/images/currency/celestial_alloy.webp", "stackSize": 10 }, { @@ -377,7 +377,7 @@ "description": "NameShow Full Descriptions Currency Exchange100 Gold NoteCodechance-shard DropLevel 1 BaseType Chance Shard Class Stackable Currency FlagsAlwaysAllocate TypeMetadata/Items/Currency/CurrencyUpgradeRandomlyShard Tagscurrency_shard, currency IconArt/2DItems/Currency/CurrencyUpgradeToUniqueShard", "effect": "NameShow Full Descriptions Currency Exchange100 Gold NoteCodechance-shard DropLevel 1 BaseType Chance Shard Class Stackable Currency FlagsAlwaysAllocate TypeMetadata/Items/Currency/CurrencyUpgradeRandomlyShard Tagscurrency_shard, currency IconArt/2DItems/Currency/CurrencyUpgradeToUniqueShard", "mechanics": "NameShow Full Descriptions Currency Exchange100 Gold NoteCodechance-shard DropLevel 1 BaseType Chance Shard Class Stackable Currency FlagsAlwaysAllocate TypeMetadata/Items/Currency/CurrencyUpgradeRandomlyShard Tagscurrency_shard, currency IconArt/2DItems/Currency/CurrencyUpgradeToUniqueShard", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyUpgradeToUniqueShard.webp", + "imageUrl": "/images/currency/chance_shard.webp", "stackSize": 10 }, { @@ -391,7 +391,7 @@ "description": "Removes a random modifier and augments a Rare item with a new random modifier", "effect": "Removes a random modifier and augments a Rare item with a new random modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new random modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyRerollRare.webp", + "imageUrl": "/images/currency/chaos_orb.webp", "stackSize": 20 }, { @@ -405,7 +405,7 @@ "description": "Adds quality that enhances Chaos modifiers on a ring or amulet Replaces other quality types", "effect": "Adds quality that enhances Chaos modifiers on a ring or amulet Replaces other quality types", "mechanics": "Adds quality that enhances Chaos modifiers on a ring or amulet Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/BreachCatalystChaos.webp", + "imageUrl": "/images/currency/chayulas_catalyst.webp", "stackSize": 10 }, { @@ -419,7 +419,7 @@ "description": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/ConcentratedDistilledFear.webp", + "imageUrl": "/images/currency/concentrated_liquid_fear.webp", "stackSize": 10 }, { @@ -433,7 +433,7 @@ "description": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/ConcentratedDistilledIsolation.webp", + "imageUrl": "/images/currency/concentrated_liquid_isolation.webp", "stackSize": 10 }, { @@ -447,7 +447,7 @@ "description": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/ConcentratedDistilledSuffering.webp", + "imageUrl": "/images/currency/concentrated_liquid_suffering.webp", "stackSize": 10 }, { @@ -461,7 +461,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Expedition2/ImbuedVerisium.webp", + "imageUrl": "/images/currency/cyclonic_alloy.webp", "stackSize": 10 }, { @@ -475,7 +475,7 @@ "description": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/DilutedDistilledGreed.webp", + "imageUrl": "/images/currency/diluted_liquid_greed.webp", "stackSize": 10 }, { @@ -489,7 +489,7 @@ "description": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/DilutedDistilledGuilt.webp", + "imageUrl": "/images/currency/diluted_liquid_guilt.webp", "stackSize": 10 }, { @@ -503,7 +503,7 @@ "description": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/DilutedDistilledIre.webp", + "imageUrl": "/images/currency/diluted_liquid_ire.webp", "stackSize": 10 }, { @@ -517,7 +517,7 @@ "description": "Randomises the numeric values of modifiers on an item", "effect": "Randomises the numeric values of modifiers on an item", "mechanics": "Randomises the numeric values of modifiers on an item", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyModValues.webp", + "imageUrl": "/images/currency/divine_orb.webp", "stackSize": 10 }, { @@ -531,7 +531,7 @@ "description": "Adds quality that enhances Lightning modifiers on a ring or amulet Replaces other quality types", "effect": "Adds quality that enhances Lightning modifiers on a ring or amulet Replaces other quality types", "mechanics": "Adds quality that enhances Lightning modifiers on a ring or amulet Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/BreachCatalystLightning.webp", + "imageUrl": "/images/currency/eshs_catalyst.webp", "stackSize": 10 }, { @@ -545,7 +545,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/PhysicalEssence.webp", + "imageUrl": "/images/currency/essence_of_abrasion.webp", "stackSize": 10, "guaranteedMod": "One Handed Melee Weapon or Bow: Adds (10—15) to (18—26) Physical Damage" }, @@ -560,7 +560,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/SpeedCasterEssence.webp", + "imageUrl": "/images/currency/essence_of_alacrity.webp", "stackSize": 10, "guaranteedMod": "Focus or Wand: (17—20)% increased Cast Speed" }, @@ -575,7 +575,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/AttackEssence.webp", + "imageUrl": "/images/currency/essence_of_battle.webp", "stackSize": 10, "guaranteedMod": "Martial Weapon: +(124—167) to Accuracy Rating" }, @@ -590,7 +590,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/AllyEssence.webp", + "imageUrl": "/images/currency/essence_of_command.webp", "stackSize": 10, "guaranteedMod": "Sceptre: Allies in your Presence deal (55—64)% increased Damage" }, @@ -605,7 +605,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/CorruptedEssenceDelirium.webp", + "imageUrl": "/images/currency/essence_of_delirium.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -620,7 +620,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/LightningEssence.webp", + "imageUrl": "/images/currency/essence_of_electricity.webp", "stackSize": 10, "guaranteedMod": "One Handed Melee Weapon or Bow: Adds (1—3) to (55—60) Lightning Damage" }, @@ -635,7 +635,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/DefencesEssence.webp", + "imageUrl": "/images/currency/essence_of_enhancement.webp", "stackSize": 10, "guaranteedMod": "Armour: (56—67)% increased Armour, Evasion and Energy Shield" }, @@ -650,7 +650,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/FireEssence.webp", + "imageUrl": "/images/currency/essence_of_flames.webp", "stackSize": 10, "guaranteedMod": "One Handed Melee Weapon or Bow: Adds (20—24) to (32—37) Fire Damage" }, @@ -665,7 +665,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/LightningResistanceEssence.webp", + "imageUrl": "/images/currency/essence_of_grounding.webp", "stackSize": 10, "guaranteedMod": "Armour, Belt or Jewellery: +(21—25)% to Lightning Resistance" }, @@ -680,7 +680,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/SpeedEssence.webp", + "imageUrl": "/images/currency/essence_of_haste.webp", "stackSize": 10, "guaranteedMod": "Melee Weapon: (17—19)% increased Attack Speed" }, @@ -695,7 +695,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/CorruptedEssenceHorror.webp", + "imageUrl": "/images/currency/essence_of_horror.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -710,7 +710,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/CorruptedEssenceHysteria.webp", + "imageUrl": "/images/currency/essence_of_hysteria.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -725,7 +725,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/ColdEssence.webp", + "imageUrl": "/images/currency/essence_of_ice.webp", "stackSize": 10, "guaranteedMod": "One Handed Melee Weapon or Bow: Adds (17—20) to (26—32) Cold Damage" }, @@ -740,7 +740,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/CorruptedEssenceInsanity.webp", + "imageUrl": "/images/currency/essence_of_insanity.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -755,7 +755,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/FireResistanceEssence.webp", + "imageUrl": "/images/currency/essence_of_insulation.webp", "stackSize": 10, "guaranteedMod": "Armour, Belt or Jewellery: +(21—25)% to Fire Resistance" }, @@ -770,7 +770,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/RarityResistanceEssence.webp", + "imageUrl": "/images/currency/essence_of_opulence.webp", "stackSize": 10, "guaranteedMod": "Boots, Gloves, Helmet or Jewellery: (11—14)% increased Rarity of Items found" }, @@ -785,7 +785,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/ChaosEssence.webp", + "imageUrl": "/images/currency/essence_of_ruin.webp", "stackSize": 10, "guaranteedMod": "Armour, Belt or Jewellery: +(8—11)% to Chaos Resistance" }, @@ -800,7 +800,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/CriticalEssence.webp", + "imageUrl": "/images/currency/essence_of_seeking.webp", "stackSize": 10, "guaranteedMod": "Martial Weapon: +(2.11—2.7)% to Critical Hit Chance" }, @@ -815,7 +815,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/CasterEssence.webp", + "imageUrl": "/images/currency/essence_of_sorcery.webp", "stackSize": 10, "guaranteedMod": "Focus or Wand: (55—64)% increased Spell Damage" }, @@ -830,7 +830,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/ColdResistanceEssence.webp", + "imageUrl": "/images/currency/essence_of_thawing.webp", "stackSize": 10, "guaranteedMod": "Armour, Belt or Jewellery: +(21—25)% to Cold Resistance" }, @@ -845,7 +845,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/AbyssalEssence.webp", + "imageUrl": "/images/currency/essence_of_the_abyss.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -860,7 +860,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/LifeEssence.webp", + "imageUrl": "/images/currency/essence_of_the_body.webp", "stackSize": 10, "guaranteedMod": "Belt, Body Armour, Helmet or Shield: +(85—99) to maximum Life" }, @@ -875,7 +875,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/BreachEssence.webp", + "imageUrl": "/images/currency/essence_of_the_breach.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -890,7 +890,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/AttributeEssence.webp", + "imageUrl": "/images/currency/essence_of_the_infinite.webp", "stackSize": 10, "guaranteedMod": "Equipment: +(17—20) to Strength, Dexterity or Intelligence" }, @@ -905,7 +905,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/ManaEssence.webp", + "imageUrl": "/images/currency/essence_of_the_mind.webp", "stackSize": 10, "guaranteedMod": "Belt, Boots, Gloves or Helmet: +(65—79) to maximum Mana" }, @@ -920,7 +920,7 @@ "description": "Augments a Rare item with a new random modifier", "effect": "Augments a Rare item with a new random modifier", "mechanics": "Augments a Rare item with a new random modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyAddModToRare.webp", + "imageUrl": "/images/currency/exalted_orb.webp", "stackSize": 20 }, { @@ -934,7 +934,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Expedition2/StandardVerisium.webp", + "imageUrl": "/images/currency/expansive_alloy.webp", "stackSize": 10 }, { @@ -948,7 +948,7 @@ "description": "Adds quality that enhances Life modifiers on a ring or amulet Replaces other quality types", "effect": "Adds quality that enhances Life modifiers on a ring or amulet Replaces other quality types", "mechanics": "Adds quality that enhances Life modifiers on a ring or amulet Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/BreachCatalystLife.webp", + "imageUrl": "/images/currency/flesh_catalyst.webp", "stackSize": 10 }, { @@ -962,7 +962,7 @@ "description": "Fracture a random modifier on a rare item with at least 4 modifiers, locking it in place.", "effect": "Fracture a random modifier on a rare item with at least 4 modifiers, locking it in place.", "mechanics": "Fracture a random modifier on a rare item with at least 4 modifiers, locking it in place.", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/FracturingOrb.webp", + "imageUrl": "/images/currency/fracturing_orb.webp", "stackSize": 20 }, { @@ -976,7 +976,7 @@ "description": "Improves the quality of a Skill Gem", "effect": "Improves the quality of a Skill Gem", "mechanics": "Improves the quality of a Skill Gem", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyGemQuality.webp", + "imageUrl": "/images/currency/gemcutters_prism.webp", "stackSize": 20 }, { @@ -990,7 +990,7 @@ "description": "Improves the quality of a flask", "effect": "Improves the quality of a flask", "mechanics": "Improves the quality of a flask", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyFlaskQuality.webp", + "imageUrl": "/images/currency/glassblowers_bauble.webp", "stackSize": 20 }, { @@ -1004,7 +1004,7 @@ "description": "Desecrates a Rare Amulet, Ring or Belt", "effect": "Desecrates a Rare Amulet, Ring or Belt", "mechanics": "Desecrates a Rare Amulet, Ring or Belt", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Abyss/GnawedClavicle.webp", + "imageUrl": "/images/currency/gnawed_collarbone.webp", "stackSize": 20 }, { @@ -1018,7 +1018,7 @@ "description": "Desecrates a Rare Weapon or Quiver", "effect": "Desecrates a Rare Weapon or Quiver", "mechanics": "Desecrates a Rare Weapon or Quiver", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Abyss/GnawedJawbone.webp", + "imageUrl": "/images/currency/gnawed_jawbone.webp", "stackSize": 20 }, { @@ -1032,7 +1032,7 @@ "description": "Desecrates a Rare Armour", "effect": "Desecrates a Rare Armour", "mechanics": "Desecrates a Rare Armour", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Abyss/GnawedRibs.webp", + "imageUrl": "/images/currency/gnawed_rib.webp", "stackSize": 20 }, { @@ -1046,7 +1046,7 @@ "description": "Removes a random modifier and augments a Rare item with a new random modifier", "effect": "Removes a random modifier and augments a Rare item with a new random modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new random modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyRerollRare.webp", + "imageUrl": "/images/currency/greater_chaos_orb.webp", "stackSize": 20, "minModifierLevel": 35 }, @@ -1061,7 +1061,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/GreaterPhysicalEssence.webp", + "imageUrl": "/images/currency/greater_essence_of_abrasion.webp", "stackSize": 10, "guaranteedMod": "One Handed Melee Weapon or Bow: Adds (16—24) to (28—42) Physical Damage" }, @@ -1076,7 +1076,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/GreaterSpeedCasterEssence.webp", + "imageUrl": "/images/currency/greater_essence_of_alacrity.webp", "stackSize": 10, "guaranteedMod": "Focus or Wand: (25—28)% increased Cast Speed" }, @@ -1091,7 +1091,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/GreaterAttackEssence.webp", + "imageUrl": "/images/currency/greater_essence_of_battle.webp", "stackSize": 10, "guaranteedMod": "Martial Weapon, Gloves or Quiver: +(237—346) to Accuracy Rating" }, @@ -1106,7 +1106,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/GreaterAllyEssence.webp", + "imageUrl": "/images/currency/greater_essence_of_command.webp", "stackSize": 10, "guaranteedMod": "Sceptre: Allies in your Presence deal (75—89)% increased Damage" }, @@ -1121,7 +1121,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/GreaterLightningEssence.webp", + "imageUrl": "/images/currency/greater_essence_of_electricity.webp", "stackSize": 10, "guaranteedMod": "One Handed Melee Weapon or Bow: Adds (1—6) to (85—107) Lightning Damage" }, @@ -1136,7 +1136,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/GreaterDefencesEssence.webp", + "imageUrl": "/images/currency/greater_essence_of_enhancement.webp", "stackSize": 10, "guaranteedMod": "Armour: (68—79)% increased Armour, Evasion and Energy Shield" }, @@ -1151,7 +1151,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/GreaterFireEssence.webp", + "imageUrl": "/images/currency/greater_essence_of_flames.webp", "stackSize": 10, "guaranteedMod": "One Handed Melee Weapon or Bow: Adds (35—44) to (56—71) Fire Damage" }, @@ -1166,7 +1166,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/GreaterLightningResistanceEssence.webp", + "imageUrl": "/images/currency/greater_essence_of_grounding.webp", "stackSize": 10, "guaranteedMod": "Armour, Belt or Jewellery: +(31—35)% to Lightning Resistance" }, @@ -1181,7 +1181,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/GreaterSpeedEssence.webp", + "imageUrl": "/images/currency/greater_essence_of_haste.webp", "stackSize": 10, "guaranteedMod": "Melee Weapon: (23—25)% increased Attack Speed" }, @@ -1196,7 +1196,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/GreaterColdEssence.webp", + "imageUrl": "/images/currency/greater_essence_of_ice.webp", "stackSize": 10, "guaranteedMod": "One Handed Melee Weapon or Bow: Adds (31—38) to (47—59) Cold Damage" }, @@ -1211,7 +1211,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/GreaterFireResistanceEssence.webp", + "imageUrl": "/images/currency/greater_essence_of_insulation.webp", "stackSize": 10, "guaranteedMod": "Armour, Belt or Jewellery: +(31—35)% to Fire Resistance" }, @@ -1226,7 +1226,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/GreaterRarityResistanceEssence.webp", + "imageUrl": "/images/currency/greater_essence_of_opulence.webp", "stackSize": 10, "guaranteedMod": "Boots, Gloves, Helmet or Jewellery: (15—18)% increased Rarity of Items found" }, @@ -1241,7 +1241,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/GreaterChaosEssence.webp", + "imageUrl": "/images/currency/greater_essence_of_ruin.webp", "stackSize": 10, "guaranteedMod": "Armour, Belt or Jewellery: +(16—19)% to Chaos Resistance" }, @@ -1256,7 +1256,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/GreaterCriticalEssence.webp", + "imageUrl": "/images/currency/greater_essence_of_seeking.webp", "stackSize": 10, "guaranteedMod": "Martial Weapon: +(3.11—3.8)% to Critical Hit Chance" }, @@ -1271,7 +1271,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/GreaterCasterEssence.webp", + "imageUrl": "/images/currency/greater_essence_of_sorcery.webp", "stackSize": 10, "guaranteedMod": "Focus or Wand: (75—89)% increased Spell Damage" }, @@ -1286,7 +1286,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/GreaterColdResistanceEssence.webp", + "imageUrl": "/images/currency/greater_essence_of_thawing.webp", "stackSize": 10, "guaranteedMod": "Armour, Belt or Jewellery: +(31—35)% to Cold Resistance" }, @@ -1301,7 +1301,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/GreaterLifeEssence.webp", + "imageUrl": "/images/currency/greater_essence_of_the_body.webp", "stackSize": 10, "guaranteedMod": "Belt, Body Armour, Helmet or Shield: +(100—119) to maximum Life" }, @@ -1316,7 +1316,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/GreaterAttributeEssence.webp", + "imageUrl": "/images/currency/greater_essence_of_the_infinite.webp", "stackSize": 10, "guaranteedMod": "Equipment: +(25—27) to Strength, Dexterity or Intelligence" }, @@ -1331,7 +1331,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/GreaterManaEssence.webp", + "imageUrl": "/images/currency/greater_essence_of_the_mind.webp", "stackSize": 10, "guaranteedMod": "Belt, Boots, Gloves or Helmet: +(80—89) to maximum Mana" }, @@ -1346,7 +1346,7 @@ "description": "Augments a Rare item with a new random modifier", "effect": "Augments a Rare item with a new random modifier", "mechanics": "Augments a Rare item with a new random modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyAddModToRare.webp", + "imageUrl": "/images/currency/greater_exalted_orb.webp", "stackSize": 20, "minModifierLevel": 35 }, @@ -1361,7 +1361,7 @@ "description": "Sets a Skill Gem to have 4 Support Gem Sockets", "effect": "Sets a Skill Gem to have 4 Support Gem Sockets", "mechanics": "Sets a Skill Gem to have 4 Support Gem Sockets", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyRerollSocketNumbers02.webp", + "imageUrl": "/images/currency/greater_jewellers_orb.webp", "stackSize": 20 }, { @@ -1375,7 +1375,7 @@ "description": "Augments a Magic item with a new random modifier", "effect": "Augments a Magic item with a new random modifier", "mechanics": "Augments a Magic item with a new random modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyAddModToMagic.webp", + "imageUrl": "/images/currency/greater_orb_of_augmentation.webp", "stackSize": 30, "minModifierLevel": 44 }, @@ -1390,7 +1390,7 @@ "description": "Upgrades a Normal item to a Magic item with 1 modifier", "effect": "Upgrades a Normal item to a Magic item with 1 modifier", "mechanics": "Upgrades a Normal item to a Magic item with 1 modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyUpgradeToMagic.webp", + "imageUrl": "/images/currency/greater_orb_of_transmutation.webp", "stackSize": 40, "minModifierLevel": 44 }, @@ -1405,7 +1405,7 @@ "description": "Upgrades a Magic item to a Rare item, adding 1 modifier", "effect": "Upgrades a Magic item to a Rare item, adding 1 modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding 1 modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyUpgradeMagicToRare.webp", + "imageUrl": "/images/currency/greater_regal_orb.webp", "stackSize": 20, "minModifierLevel": 35 }, @@ -1420,7 +1420,7 @@ "description": "Allows an item to foresee the result of the next Currency item used on it Modifying the item in any way removes the ability to foresee", "effect": "Allows an item to foresee the result of the next Currency item used on it Modifying the item in any way removes the ability to foresee", "mechanics": "Allows an item to foresee the result of the next Currency item used on it Modifying the item in any way removes the ability to foresee", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/HinekorasLock.webp", + "imageUrl": "/images/currency/hinekoras_lock.webp", "stackSize": 10 }, { @@ -1434,7 +1434,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/PhysicalEssenceLesser.webp", + "imageUrl": "/images/currency/lesser_essence_of_abrasion.webp", "stackSize": 10, "guaranteedMod": "One Handed Melee Weapon or Bow: Adds (4—6) to (7—11) Physical Damage" }, @@ -1449,7 +1449,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/SpeedCasterEssenceLesser.webp", + "imageUrl": "/images/currency/lesser_essence_of_alacrity.webp", "stackSize": 10, "guaranteedMod": "Focus or Wand: (13—16)% increased Cast Speed" }, @@ -1464,7 +1464,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/AttackEssenceLesser.webp", + "imageUrl": "/images/currency/lesser_essence_of_battle.webp", "stackSize": 10, "guaranteedMod": "Martial Weapon: +(61—84) to Accuracy Rating" }, @@ -1479,7 +1479,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/AllyEssenceLesser.webp", + "imageUrl": "/images/currency/lesser_essence_of_command.webp", "stackSize": 10, "guaranteedMod": "Sceptre: Allies in your Presence deal (35—44)% increased Damage" }, @@ -1494,7 +1494,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/LightningEssenceLesser.webp", + "imageUrl": "/images/currency/lesser_essence_of_electricity.webp", "stackSize": 10, "guaranteedMod": "One Handed Melee Weapon or Bow: Adds 1 to (13—19) Lightning Damage" }, @@ -1509,7 +1509,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/DefencesEssenceLesser.webp", + "imageUrl": "/images/currency/lesser_essence_of_enhancement.webp", "stackSize": 10, "guaranteedMod": "Armour: (27—42)% increased Armour, Evasion and Energy Shield" }, @@ -1524,7 +1524,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/FireEssenceLesser.webp", + "imageUrl": "/images/currency/lesser_essence_of_flames.webp", "stackSize": 10, "guaranteedMod": "One Handed Melee Weapon or Bow: Adds (4—6) to (7—10) Fire Damage" }, @@ -1539,7 +1539,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/LightningResistanceEssenceLesser.webp", + "imageUrl": "/images/currency/lesser_essence_of_grounding.webp", "stackSize": 10, "guaranteedMod": "Armour, Belt or Jewellery: +(11—15)% to Lightning Resistance" }, @@ -1554,7 +1554,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/SpeedEssenceLesser.webp", + "imageUrl": "/images/currency/lesser_essence_of_haste.webp", "stackSize": 10, "guaranteedMod": "Melee Weapon: (11—13)% increased Attack Speed" }, @@ -1569,7 +1569,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/ColdEssenceLesser.webp", + "imageUrl": "/images/currency/lesser_essence_of_ice.webp", "stackSize": 10, "guaranteedMod": "One Handed Melee Weapon or Bow: Adds (3—5) to (6—9) Cold Damage" }, @@ -1584,7 +1584,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/FireResistanceEssenceLesser.webp", + "imageUrl": "/images/currency/lesser_essence_of_insulation.webp", "stackSize": 10, "guaranteedMod": "Armour, Belt or Jewellery: +(11—15)% to Fire Resistance" }, @@ -1599,7 +1599,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/RarityResistanceEssenceLesser.webp", + "imageUrl": "/images/currency/lesser_essence_of_opulence.webp", "stackSize": 10, "guaranteedMod": "Boots, Gloves, Helmet or Jewellery: (6—10)% increased Rarity of Items found" }, @@ -1614,7 +1614,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/ChaosEssenceLesser.webp", + "imageUrl": "/images/currency/lesser_essence_of_ruin.webp", "stackSize": 10, "guaranteedMod": "Armour, Belt or Jewellery: +(4—7)% to Chaos Resistance" }, @@ -1629,7 +1629,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/CriticalEssenceLesser.webp", + "imageUrl": "/images/currency/lesser_essence_of_seeking.webp", "stackSize": 10, "guaranteedMod": "Martial Weapon: +(1.51—2.1)% to Critical Hit Chance" }, @@ -1644,7 +1644,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/CasterEssenceLesser.webp", + "imageUrl": "/images/currency/lesser_essence_of_sorcery.webp", "stackSize": 10, "guaranteedMod": "Focus or Wand: (35—44)% increased Spell Damage" }, @@ -1659,7 +1659,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/ColdResistanceEssenceLesser.webp", + "imageUrl": "/images/currency/lesser_essence_of_thawing.webp", "stackSize": 10, "guaranteedMod": "Armour, Belt or Jewellery: +(11—15)% to Cold Resistance" }, @@ -1674,7 +1674,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/LifeEssenceLesser.webp", + "imageUrl": "/images/currency/lesser_essence_of_the_body.webp", "stackSize": 10, "guaranteedMod": "Armour or Belt: +(30—39) to maximum Life" }, @@ -1689,7 +1689,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/AttributeEssenceLesser.webp", + "imageUrl": "/images/currency/lesser_essence_of_the_infinite.webp", "stackSize": 10, "guaranteedMod": "Equipment: +(9—12) to Strength, Dexterity or Intelligence" }, @@ -1704,7 +1704,7 @@ "description": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "effect": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding a guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/ManaEssenceLesser.webp", + "imageUrl": "/images/currency/lesser_essence_of_the_mind.webp", "stackSize": 10, "guaranteedMod": "Belt, Boots, Gloves, Helmet or Jewellery: +(25—34) to maximum Mana" }, @@ -1719,7 +1719,7 @@ "description": "Sets a Skill Gem to have 3 Support Gem Sockets", "effect": "Sets a Skill Gem to have 3 Support Gem Sockets", "mechanics": "Sets a Skill Gem to have 3 Support Gem Sockets", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyRerollSocketNumbers01.webp", + "imageUrl": "/images/currency/lesser_jewellers_orb.webp", "stackSize": 20 }, { @@ -1733,7 +1733,7 @@ "description": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/DistilledDespair.webp", + "imageUrl": "/images/currency/liquid_despair.webp", "stackSize": 1030 }, { @@ -1747,7 +1747,7 @@ "description": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/DistilledDisgust.webp", + "imageUrl": "/images/currency/liquid_disgust.webp", "stackSize": 10 }, { @@ -1761,7 +1761,7 @@ "description": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/DistilledEnvy.webp", + "imageUrl": "/images/currency/liquid_envy.webp", "stackSize": 10 }, { @@ -1775,7 +1775,7 @@ "description": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/DistilledParanoia.webp", + "imageUrl": "/images/currency/liquid_paranoia.webp", "stackSize": 10 }, { @@ -1789,7 +1789,7 @@ "description": "Immediately start a Runic Remnant Encounter with a random Runic Inscription", "effect": "Immediately start a Runic Remnant Encounter with a random Runic Inscription", "mechanics": "Immediately start a Runic Remnant Encounter with a random Runic Inscription", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Expedition2/LiquidMetalVerisium.webp", + "imageUrl": "/images/currency/liquid_verisium.webp", "stackSize": 20 }, { @@ -1803,7 +1803,7 @@ "description": "Creates a Mirrored copy of an item", "effect": "Creates a Mirrored copy of an item", "mechanics": "Creates a Mirrored copy of an item", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyDuplicate.webp", + "imageUrl": "/images/currency/mirror_of_kalandra.webp", "stackSize": 10 }, { @@ -1817,7 +1817,7 @@ "description": "Contains an unknown Leaguestone.", "effect": "Contains an unknown Leaguestone.", "mechanics": "Contains an unknown Leaguestone.", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Classic/Mystery.webp" + "imageUrl": "/images/currency/mystery_leaguestone.webp" }, { "id": "mystic_alloy", @@ -1830,7 +1830,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Expedition2/CelestialVerisium.webp", + "imageUrl": "/images/currency/mystic_alloy.webp", "stackSize": 10 }, { @@ -1844,7 +1844,7 @@ "description": "Adds quality that enhances Minion modifiers on a ring or amulet Replaces other quality types", "effect": "Adds quality that enhances Minion modifiers on a ring or amulet Replaces other quality types", "mechanics": "Adds quality that enhances Minion modifiers on a ring or amulet Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/BreachCatalystNecrotic.webp", + "imageUrl": "/images/currency/necrotic_catalyst.webp", "stackSize": 10 }, { @@ -1858,7 +1858,7 @@ "description": "Adds quality that enhances Mana modifiers on a ring or amulet Replaces other quality types", "effect": "Adds quality that enhances Mana modifiers on a ring or amulet Replaces other quality types", "mechanics": "Adds quality that enhances Mana modifiers on a ring or amulet Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/BreachCatalystMana.webp", + "imageUrl": "/images/currency/neural_catalyst.webp", "stackSize": 10 }, { @@ -1872,7 +1872,7 @@ "description": "While this item is active in your inventory your next Exalted Orb will consume all Catalyst Quality to increase the chance of the corresponding type of Modifier", "effect": "While this item is active in your inventory your next Exalted Orb will consume all Catalyst Quality to increase the chance of the corresponding type of Modifier", "mechanics": "While this item is active in your inventory your next Exalted Orb will consume all Catalyst Quality to increase the chance of the corresponding type of Modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnExaltConsumeQuality.webp", + "imageUrl": "/images/currency/omen_of_catalysing_exaltation.webp", "stackSize": 10 }, { @@ -1886,7 +1886,7 @@ "description": "While this item is active in your inventory your next Perfect or Corrupted Essence will remove only Suffix modifiers", "effect": "While this item is active in your inventory your next Perfect or Corrupted Essence will remove only Suffix modifiers", "mechanics": "While this item is active in your inventory your next Perfect or Corrupted Essence will remove only Suffix modifiers", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnPerfectEssenceSuffix.webp", + "imageUrl": "/images/currency/omen_of_dextral_crystallisation.webp", "stackSize": 10 }, { @@ -1900,7 +1900,7 @@ "description": "While this item is active in your inventory your next Perfect or Corrupted Essence will remove only Prefix modifiers", "effect": "While this item is active in your inventory your next Perfect or Corrupted Essence will remove only Prefix modifiers", "mechanics": "While this item is active in your inventory your next Perfect or Corrupted Essence will remove only Prefix modifiers", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnPerfectEssencePrefix.webp", + "imageUrl": "/images/currency/omen_of_sinistral_crystallisation.webp", "stackSize": 10 }, { @@ -1914,7 +1914,7 @@ "description": "Upgrades a Normal or Magic item to a Rare item with 4 random modifiers", "effect": "Upgrades a Normal or Magic item to a Rare item with 4 random modifiers", "mechanics": "Upgrades a Normal or Magic item to a Rare item with 4 random modifiers", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyUpgradeToRare.webp", + "imageUrl": "/images/currency/orb_of_alchemy.webp", "stackSize": 20 }, { @@ -1928,7 +1928,7 @@ "description": "Removes a random modifier from an item", "effect": "Removes a random modifier from an item", "mechanics": "Removes a random modifier from an item", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/AnnullOrb.webp", + "imageUrl": "/images/currency/orb_of_annulment.webp", "stackSize": 20 }, { @@ -1942,7 +1942,7 @@ "description": "Augments a Magic item with a new random modifier", "effect": "Augments a Magic item with a new random modifier", "mechanics": "Augments a Magic item with a new random modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyAddModToMagic.webp", + "imageUrl": "/images/currency/orb_of_augmentation.webp", "stackSize": 30 }, { @@ -1956,7 +1956,7 @@ "description": "Unpredictably either upgrades a Normal item to Unique rarity or destroys it", "effect": "Unpredictably either upgrades a Normal item to Unique rarity or destroys it", "mechanics": "Unpredictably either upgrades a Normal item to Unique rarity or destroys it", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyUpgradeToUnique.webp", + "imageUrl": "/images/currency/orb_of_chance.webp", "stackSize": 10 }, { @@ -1970,7 +1970,7 @@ "description": "Upgrades a Normal item to a Magic item with 1 modifier", "effect": "Upgrades a Normal item to a Magic item with 1 modifier", "mechanics": "Upgrades a Normal item to a Magic item with 1 modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyUpgradeToMagic.webp", + "imageUrl": "/images/currency/orb_of_transmutation.webp", "stackSize": 40 }, { @@ -1984,7 +1984,7 @@ "description": "Removes a random modifier and augments a Rare item with a new random modifier", "effect": "Removes a random modifier and augments a Rare item with a new random modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new random modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyRerollRare.webp", + "imageUrl": "/images/currency/perfect_chaos_orb.webp", "stackSize": 20, "minModifierLevel": 50 }, @@ -1999,7 +1999,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/PhysicalEssencePerfect.webp", + "imageUrl": "/images/currency/perfect_essence_of_abrasion.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -2014,7 +2014,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/SpeedCasterEssencePerfect.webp", + "imageUrl": "/images/currency/perfect_essence_of_alacrity.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -2029,7 +2029,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/AttackEssencePerfect.webp", + "imageUrl": "/images/currency/perfect_essence_of_battle.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -2044,7 +2044,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/AllyEssencePerfect.webp", + "imageUrl": "/images/currency/perfect_essence_of_command.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -2059,7 +2059,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/LightningEssencePerfect.webp", + "imageUrl": "/images/currency/perfect_essence_of_electricity.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -2074,7 +2074,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/DefencesEssencePerfect.webp", + "imageUrl": "/images/currency/perfect_essence_of_enhancement.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -2089,7 +2089,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/FireEssencePerfect.webp", + "imageUrl": "/images/currency/perfect_essence_of_flames.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -2104,7 +2104,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/LightningResistanceEssencePerfect.webp", + "imageUrl": "/images/currency/perfect_essence_of_grounding.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -2119,7 +2119,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/SpeedEssencePerfect.webp", + "imageUrl": "/images/currency/perfect_essence_of_haste.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -2134,7 +2134,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/ColdEssencePerfect.webp", + "imageUrl": "/images/currency/perfect_essence_of_ice.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -2149,7 +2149,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/FireResistanceEssencePerfect.webp", + "imageUrl": "/images/currency/perfect_essence_of_insulation.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -2164,7 +2164,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/RarityResistanceEssencePerfect.webp", + "imageUrl": "/images/currency/perfect_essence_of_opulence.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -2179,7 +2179,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/ChaosEssencePerfect.webp", + "imageUrl": "/images/currency/perfect_essence_of_ruin.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -2194,7 +2194,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/CriticalEssencePerfect.webp", + "imageUrl": "/images/currency/perfect_essence_of_seeking.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -2209,7 +2209,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/CasterEssencePerfect.webp", + "imageUrl": "/images/currency/perfect_essence_of_sorcery.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -2224,7 +2224,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/ColdResistanceEssencePerfect.webp", + "imageUrl": "/images/currency/perfect_essence_of_thawing.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -2239,7 +2239,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/LifeEssencePerfect.webp", + "imageUrl": "/images/currency/perfect_essence_of_the_body.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -2254,7 +2254,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/AttributeEssencePerfect.webp", + "imageUrl": "/images/currency/perfect_essence_of_the_infinite.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -2269,7 +2269,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Essence/ManaEssencePerfect.webp", + "imageUrl": "/images/currency/perfect_essence_of_the_mind.webp", "stackSize": 10, "guaranteedMod": "Removes a random modifier and augments a Rare item with a new guaranteed modifier" }, @@ -2284,7 +2284,7 @@ "description": "Augments a Rare item with a new random modifier", "effect": "Augments a Rare item with a new random modifier", "mechanics": "Augments a Rare item with a new random modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyAddModToRare.webp", + "imageUrl": "/images/currency/perfect_exalted_orb.webp", "stackSize": 20, "minModifierLevel": 50 }, @@ -2299,7 +2299,7 @@ "description": "Sets a Skill Gem to have 5 Support Gem Sockets", "effect": "Sets a Skill Gem to have 5 Support Gem Sockets", "mechanics": "Sets a Skill Gem to have 5 Support Gem Sockets", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyRerollSocketNumbers03.webp", + "imageUrl": "/images/currency/perfect_jewellers_orb.webp", "stackSize": 20 }, { @@ -2313,7 +2313,7 @@ "description": "Augments a Magic item with a new random modifier", "effect": "Augments a Magic item with a new random modifier", "mechanics": "Augments a Magic item with a new random modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyAddModToMagic.webp", + "imageUrl": "/images/currency/perfect_orb_of_augmentation.webp", "stackSize": 30, "minModifierLevel": 70 }, @@ -2328,7 +2328,7 @@ "description": "Upgrades a Normal item to a Magic item with 1 modifier", "effect": "Upgrades a Normal item to a Magic item with 1 modifier", "mechanics": "Upgrades a Normal item to a Magic item with 1 modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyUpgradeToMagic.webp", + "imageUrl": "/images/currency/perfect_orb_of_transmutation.webp", "stackSize": 40, "minModifierLevel": 70 }, @@ -2343,7 +2343,7 @@ "description": "Upgrades a Magic item to a Rare item, adding 1 modifier", "effect": "Upgrades a Magic item to a Rare item, adding 1 modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding 1 modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyUpgradeMagicToRare.webp", + "imageUrl": "/images/currency/perfect_regal_orb.webp", "stackSize": 20, "minModifierLevel": 50 }, @@ -2358,7 +2358,7 @@ "description": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/UniqueBeastEmotion.webp", + "imageUrl": "/images/currency/potent_liquid_contempt.webp", "stackSize": 10 }, { @@ -2372,7 +2372,7 @@ "description": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/UniqueConstructsEmotion.webp", + "imageUrl": "/images/currency/potent_liquid_ferocity.webp", "stackSize": 10 }, { @@ -2386,7 +2386,7 @@ "description": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "effect": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", "mechanics": "Removes a random modifer and Augments a Rare Basic Jewel with a new guaranteed Crafted modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/DistilledEmotions/UniqueHumansEmotion.webp", + "imageUrl": "/images/currency/potent_liquid_melancholy.webp", "stackSize": 10 }, { @@ -2400,7 +2400,7 @@ "description": "Desecrates a Rare Amulet, Ring or Belt", "effect": "Desecrates a Rare Amulet, Ring or Belt", "mechanics": "Desecrates a Rare Amulet, Ring or Belt", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Abyss/PreservedCalvicle.webp", + "imageUrl": "/images/currency/preserved_collarbone.webp", "stackSize": 20 }, { @@ -2414,7 +2414,7 @@ "description": "Desecrates a Rare Jewel", "effect": "Desecrates a Rare Jewel", "mechanics": "Desecrates a Rare Jewel", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Abyss/PreservedCranium.webp", + "imageUrl": "/images/currency/preserved_cranium.webp", "stackSize": 20 }, { @@ -2428,7 +2428,7 @@ "description": "Desecrates a Rare Weapon or Quiver", "effect": "Desecrates a Rare Weapon or Quiver", "mechanics": "Desecrates a Rare Weapon or Quiver", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Abyss/PreservedJawbone.webp", + "imageUrl": "/images/currency/preserved_jawbone.webp", "stackSize": 20 }, { @@ -2442,7 +2442,7 @@ "description": "Desecrates a Rare Armour", "effect": "Desecrates a Rare Armour", "mechanics": "Desecrates a Rare Armour", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Abyss/PreservedRibs.webp", + "imageUrl": "/images/currency/preserved_rib.webp", "stackSize": 20 }, { @@ -2456,7 +2456,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Expedition2/SovereignVerisium.webp", + "imageUrl": "/images/currency/prismatic_alloy.webp", "stackSize": 10 }, { @@ -2470,7 +2470,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Expedition2/ImpureVerisium.webp", + "imageUrl": "/images/currency/protective_alloy.webp", "stackSize": 10 }, { @@ -2484,7 +2484,7 @@ "description": "Adds quality that enhances Attack modifiers on a ring or amulet Replaces other quality types", "effect": "Adds quality that enhances Attack modifiers on a ring or amulet Replaces other quality types", "mechanics": "Adds quality that enhances Attack modifiers on a ring or amulet Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/BreachCatalystAttack.webp", + "imageUrl": "/images/currency/reaver_catalyst.webp", "stackSize": 10 }, { @@ -2498,7 +2498,7 @@ "description": "Adds quality that enhances Attribute modifiers on a jewel Replaces other quality types", "effect": "Adds quality that enhances Attribute modifiers on a jewel Replaces other quality types", "mechanics": "Adds quality that enhances Attribute modifiers on a jewel Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/JewelCatalystAttribute.webp", + "imageUrl": "/images/currency/refined_adaptive_catalyst.webp", "stackSize": 10 }, { @@ -2512,7 +2512,7 @@ "description": "Adds quality that enhances Armour, Evasion and Energy Shield modifiers on a jewel Replaces other quality types", "effect": "Adds quality that enhances Armour, Evasion and Energy Shield modifiers on a jewel Replaces other quality types", "mechanics": "Adds quality that enhances Armour, Evasion and Energy Shield modifiers on a jewel Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/JewelCatalystDefences.webp", + "imageUrl": "/images/currency/refined_carapace_catalyst.webp", "stackSize": 10 }, { @@ -2526,7 +2526,7 @@ "description": "Adds quality that enhances Chaos modifiers on a jewel Replaces other quality types", "effect": "Adds quality that enhances Chaos modifiers on a jewel Replaces other quality types", "mechanics": "Adds quality that enhances Chaos modifiers on a jewel Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/JewelCatalystChaos.webp", + "imageUrl": "/images/currency/refined_chayulas_catalyst.webp", "stackSize": 10 }, { @@ -2540,7 +2540,7 @@ "description": "Adds quality that enhances Lightning modifiers on a jewel Replaces other quality types", "effect": "Adds quality that enhances Lightning modifiers on a jewel Replaces other quality types", "mechanics": "Adds quality that enhances Lightning modifiers on a jewel Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/JewelCatalystLightning.webp", + "imageUrl": "/images/currency/refined_eshs_catalyst.webp", "stackSize": 10 }, { @@ -2554,7 +2554,7 @@ "description": "Adds quality that enhances Life modifiers on a jewel Replaces other quality types", "effect": "Adds quality that enhances Life modifiers on a jewel Replaces other quality types", "mechanics": "Adds quality that enhances Life modifiers on a jewel Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/JewelCatalystLife.webp", + "imageUrl": "/images/currency/refined_flesh_catalyst.webp", "stackSize": 10 }, { @@ -2568,7 +2568,7 @@ "description": "Adds quality that enhances Minion modifiers on a jewel Replaces other quality types", "effect": "Adds quality that enhances Minion modifiers on a jewel Replaces other quality types", "mechanics": "Adds quality that enhances Minion modifiers on a jewel Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/JewelCatalystNecrotic.webp", + "imageUrl": "/images/currency/refined_necrotic_catalyst.webp", "stackSize": 10 }, { @@ -2582,7 +2582,7 @@ "description": "Adds quality that enhances Mana modifiers on a jewel Replaces other quality types", "effect": "Adds quality that enhances Mana modifiers on a jewel Replaces other quality types", "mechanics": "Adds quality that enhances Mana modifiers on a jewel Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/JewelCatalystMana.webp", + "imageUrl": "/images/currency/refined_neural_catalyst.webp", "stackSize": 10 }, { @@ -2596,7 +2596,7 @@ "description": "Adds quality that enhances Attack modifiers on a jewel Replaces other quality types", "effect": "Adds quality that enhances Attack modifiers on a jewel Replaces other quality types", "mechanics": "Adds quality that enhances Attack modifiers on a jewel Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/JewelCatalystAttack.webp", + "imageUrl": "/images/currency/refined_reaver_catalyst.webp", "stackSize": 10 }, { @@ -2610,7 +2610,7 @@ "description": "Adds quality that enhances Caster modifiers on a jewel Replaces other quality types", "effect": "Adds quality that enhances Caster modifiers on a jewel Replaces other quality types", "mechanics": "Adds quality that enhances Caster modifiers on a jewel Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/JewelCatalystCaster.webp", + "imageUrl": "/images/currency/refined_sibilant_catalyst.webp", "stackSize": 10 }, { @@ -2624,7 +2624,7 @@ "description": "Adds quality that enhances Speed modifiers on a jewel Replaces other quality types", "effect": "Adds quality that enhances Speed modifiers on a jewel Replaces other quality types", "mechanics": "Adds quality that enhances Speed modifiers on a jewel Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/JewelCatalystSpeed.webp", + "imageUrl": "/images/currency/refined_skittering_catalyst.webp", "stackSize": 10 }, { @@ -2638,7 +2638,7 @@ "description": "Adds quality that enhances Cold modifiers on a jewel Replaces other quality types", "effect": "Adds quality that enhances Cold modifiers on a jewel Replaces other quality types", "mechanics": "Adds quality that enhances Cold modifiers on a jewel Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/JewelCatalystCold.webp", + "imageUrl": "/images/currency/refined_tuls_catalyst.webp", "stackSize": 10 }, { @@ -2652,7 +2652,7 @@ "description": "Adds quality that enhances Physical modifiers on a jewel Replaces other quality types", "effect": "Adds quality that enhances Physical modifiers on a jewel Replaces other quality types", "mechanics": "Adds quality that enhances Physical modifiers on a jewel Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/JewelCatalystPhysical.webp", + "imageUrl": "/images/currency/refined_uul_netols_catalyst.webp", "stackSize": 10 }, { @@ -2666,7 +2666,7 @@ "description": "Adds quality that enhances Fire modifiers on a jewel Replaces other quality types", "effect": "Adds quality that enhances Fire modifiers on a jewel Replaces other quality types", "mechanics": "Adds quality that enhances Fire modifiers on a jewel Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/JewelCatalystFire.webp", + "imageUrl": "/images/currency/refined_xophs_catalyst.webp", "stackSize": 10 }, { @@ -2680,7 +2680,7 @@ "description": "Upgrades a Magic item to a Rare item, adding 1 modifier", "effect": "Upgrades a Magic item to a Rare item, adding 1 modifier", "mechanics": "Upgrades a Magic item to a Rare item, adding 1 modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyUpgradeMagicToRare.webp", + "imageUrl": "/images/currency/regal_orb.webp", "stackSize": 20 }, { @@ -2694,7 +2694,7 @@ "description": "NameShow Full Descriptions Currency Exchange12 Gold NoteCoderegal-shard DropLevel 5 BaseType Regal Shard Class Stackable Currency FlagsAlwaysAllocate TypeMetadata/Items/Currency/CurrencyUpgradeMagicToRareShard SoundAudio/Sound Effects/ItemSounds/4.0/Currency/Orbs/OrbUse.ogg Tagscurrency_shard, currency IconArt/2DItems/Currency/CurrencyUpgradeMagicToRareShard", "effect": "NameShow Full Descriptions Currency Exchange12 Gold NoteCoderegal-shard DropLevel 5 BaseType Regal Shard Class Stackable Currency FlagsAlwaysAllocate TypeMetadata/Items/Currency/CurrencyUpgradeMagicToRareShard SoundAudio/Sound Effects/ItemSounds/4.0/Currency/Orbs/OrbUse.ogg Tagscurrency_shard, currency IconArt/2DItems/Currency/CurrencyUpgradeMagicToRareShard", "mechanics": "NameShow Full Descriptions Currency Exchange12 Gold NoteCoderegal-shard DropLevel 5 BaseType Regal Shard Class Stackable Currency FlagsAlwaysAllocate TypeMetadata/Items/Currency/CurrencyUpgradeMagicToRareShard SoundAudio/Sound Effects/ItemSounds/4.0/Currency/Orbs/OrbUse.ogg Tagscurrency_shard, currency IconArt/2DItems/Currency/CurrencyUpgradeMagicToRareShard", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyUpgradeMagicToRareShard.webp", + "imageUrl": "/images/currency/regal_shard.webp", "stackSize": 10 }, { @@ -2708,7 +2708,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Expedition2/ScrapVerisium.webp", + "imageUrl": "/images/currency/runic_alloy.webp", "stackSize": 10 }, { @@ -2722,7 +2722,7 @@ "description": "Identifies an item", "effect": "Identifies an item", "mechanics": "Identifies an item", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyIdentification.webp", + "imageUrl": "/images/currency/scroll_of_wisdom.webp", "stackSize": 40 }, { @@ -2736,7 +2736,7 @@ "description": "Adds quality that enhances Caster modifiers on a ring or amulet Replaces other quality types", "effect": "Adds quality that enhances Caster modifiers on a ring or amulet Replaces other quality types", "mechanics": "Adds quality that enhances Caster modifiers on a ring or amulet Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/BreachCatalystCaster.webp", + "imageUrl": "/images/currency/sibilant_catalyst.webp", "stackSize": 10 }, { @@ -2750,7 +2750,7 @@ "description": "Adds quality that enhances Speed modifiers on a ring or amulet Replaces other quality types", "effect": "Adds quality that enhances Speed modifiers on a ring or amulet Replaces other quality types", "mechanics": "Adds quality that enhances Speed modifiers on a ring or amulet Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/BreachCatalystSpeed.webp", + "imageUrl": "/images/currency/skittering_catalyst.webp", "stackSize": 10 }, { @@ -2764,7 +2764,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Expedition2/Alloy1.webp", + "imageUrl": "/images/currency/sovereign_alloy.webp", "stackSize": 10 }, { @@ -2778,7 +2778,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Expedition2/PureVerisium.webp", + "imageUrl": "/images/currency/swift_alloy.webp", "stackSize": 10 }, { @@ -2792,7 +2792,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Expedition2/Alloy2.webp", + "imageUrl": "/images/currency/the_runebinders_alloy.webp", "stackSize": 10 }, { @@ -2806,7 +2806,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Expedition2/Alloy3.webp", + "imageUrl": "/images/currency/the_runefathers_alloy.webp", "stackSize": 10 }, { @@ -2820,7 +2820,7 @@ "description": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "effect": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", "mechanics": "Removes a random modifier and augments a Rare item with a new guaranteed modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Expedition2/Alloy5.webp", + "imageUrl": "/images/currency/transcendent_alloy.webp", "stackSize": 10 }, { @@ -2834,7 +2834,7 @@ "description": "NameShow Full Descriptions Currency Exchange4 Gold NoteCodetransmutation-shard DropLevel 1 BaseType Transmutation Shard Class Stackable Currency FlagsAlwaysAllocate TypeMetadata/Items/Currency/CurrencyUpgradeToMagicShard Tagscurrency_shard, currency IconArt/2DItems/Currency/CurrencyUpgradeToMagicShard", "effect": "NameShow Full Descriptions Currency Exchange4 Gold NoteCodetransmutation-shard DropLevel 1 BaseType Transmutation Shard Class Stackable Currency FlagsAlwaysAllocate TypeMetadata/Items/Currency/CurrencyUpgradeToMagicShard Tagscurrency_shard, currency IconArt/2DItems/Currency/CurrencyUpgradeToMagicShard", "mechanics": "NameShow Full Descriptions Currency Exchange4 Gold NoteCodetransmutation-shard DropLevel 1 BaseType Transmutation Shard Class Stackable Currency FlagsAlwaysAllocate TypeMetadata/Items/Currency/CurrencyUpgradeToMagicShard Tagscurrency_shard, currency IconArt/2DItems/Currency/CurrencyUpgradeToMagicShard", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyUpgradeToMagicShard.webp", + "imageUrl": "/images/currency/transmutation_shard.webp", "stackSize": 10 }, { @@ -2848,7 +2848,7 @@ "description": "Adds quality that enhances Cold modifiers on a ring or amulet Replaces other quality types", "effect": "Adds quality that enhances Cold modifiers on a ring or amulet Replaces other quality types", "mechanics": "Adds quality that enhances Cold modifiers on a ring or amulet Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/BreachCatalystCold.webp", + "imageUrl": "/images/currency/tuls_catalyst.webp", "stackSize": 10 }, { @@ -2862,7 +2862,7 @@ "description": "Adds quality that enhances Physical modifiers on a ring or amulet Replaces other quality types", "effect": "Adds quality that enhances Physical modifiers on a ring or amulet Replaces other quality types", "mechanics": "Adds quality that enhances Physical modifiers on a ring or amulet Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/BreachCatalystPhysical.webp", + "imageUrl": "/images/currency/uul_netols_catalyst.webp", "stackSize": 10 }, { @@ -2876,7 +2876,7 @@ "description": "Modifies an item unpredictably and Corrupts it", "effect": "Modifies an item unpredictably and Corrupts it", "mechanics": "Modifies an item unpredictably and Corrupts it", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/CurrencyVaal.webp", + "imageUrl": "/images/currency/vaal_orb.webp", "stackSize": 20 }, { @@ -2890,7 +2890,7 @@ "description": "Adds quality that enhances Fire modifiers on a ring or amulet Replaces other quality types", "effect": "Adds quality that enhances Fire modifiers on a ring or amulet Replaces other quality types", "mechanics": "Adds quality that enhances Fire modifiers on a ring or amulet Replaces other quality types", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Breach/BreachCatalystFire.webp", + "imageUrl": "/images/currency/xophs_catalyst.webp", "stackSize": 10 } ] \ No newline at end of file diff --git a/public/data/omens.json b/public/data/omens.json index af68ad7..0395d2f 100644 --- a/public/data/omens.json +++ b/public/data/omens.json @@ -7,7 +7,7 @@ ], "description": "While this item is active in your inventory your next Logbook adds special modifiers to revealed Grand Expedition areas", "effect": "While this item is active in your inventory your next Logbook adds special modifiers to revealed Grand Expedition areas", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Expedition2/SpecialExpeditionPage5.webp" + "imageUrl": "/images/omen/aldurs_saga.webp" }, { "id": "medveds_saga", @@ -15,7 +15,7 @@ "appliesTo": [], "description": "While this item is active in your inventory your next Logbook guarantees a Medved encounter in the revealed Biome", "effect": "While this item is active in your inventory your next Logbook guarantees a Medved encounter in the revealed Biome", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Expedition2/SpecialExpeditionPage3.webp" + "imageUrl": "/images/omen/medveds_saga.webp" }, { "id": "olroths_saga", @@ -23,7 +23,7 @@ "appliesTo": [], "description": "While this item is active in your inventory your next Logbook guarantees an Olroth encounter in the revealed Biome", "effect": "While this item is active in your inventory your next Logbook guarantees an Olroth encounter in the revealed Biome", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Expedition2/SpecialExpeditionPage1.webp" + "imageUrl": "/images/omen/olroths_saga.webp" }, { "id": "omen_of_abyssal_echoes", @@ -31,7 +31,7 @@ "appliesTo": [], "description": "While this item is active in your inventory the next time you reveal Desecrated modifiers you can reroll the options once", "effect": "While this item is active in your inventory the next time you reveal Desecrated modifiers you can reroll the options once", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnAbyssRerollOptions.webp" + "imageUrl": "/images/omen/omen_of_abyssal_echoes.webp" }, { "id": "omen_of_amelioration", @@ -39,7 +39,7 @@ "appliesTo": [], "description": "While this item is active in your inventory will prevent 75% of Experience loss when you die", "effect": "While this item is active in your inventory will prevent 75% of Experience loss when you die", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/VoodooOmens3Blue.webp" + "imageUrl": "/images/omen/omen_of_amelioration.webp" }, { "id": "omen_of_answered_prayers", @@ -49,7 +49,7 @@ ], "description": "While this item is active in your inventory the next Shrine you click on will grant an additional Effect", "effect": "While this item is active in your inventory the next Shrine you click on will grant an additional Effect", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/VoodooOmens4Blue.webp" + "imageUrl": "/images/omen/omen_of_answered_prayers.webp" }, { "id": "omen_of_bartering", @@ -59,7 +59,7 @@ ], "description": "While this item is active in your inventory your next sold item's Gold value will be incorrectly assessed by the Vendor", "effect": "While this item is active in your inventory your next sold item's Gold value will be incorrectly assessed by the Vendor", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenSellVendorRandomise.webp" + "imageUrl": "/images/omen/omen_of_bartering.webp" }, { "id": "omen_of_catalysing_exaltation", @@ -69,7 +69,7 @@ ], "description": "While this item is active in your inventory your next Exalted Orb will consume all Catalyst Quality to increase the chance of the corresponding type of Modifier", "effect": "While this item is active in your inventory your next Exalted Orb will consume all Catalyst Quality to increase the chance of the corresponding type of Modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnExaltConsumeQuality.webp" + "imageUrl": "/images/omen/omen_of_catalysing_exaltation.webp" }, { "id": "omen_of_chance", @@ -79,7 +79,7 @@ ], "description": "While this item is active in your inventory your next Orb of Chance will not destroy the Item", "effect": "While this item is active in your inventory your next Orb of Chance will not destroy the Item", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnChanceNotDestroy.webp" + "imageUrl": "/images/omen/omen_of_chance.webp" }, { "id": "omen_of_chaotic_effectiveness", @@ -89,7 +89,7 @@ ], "description": "While this item is active in your inventory your next Chaos Orb will replace all Modifiers on a Waystone with Modifiers that do not grant Monster Effectiveness", "effect": "While this item is active in your inventory your next Chaos Orb will replace all Modifiers on a Waystone with Modifiers that do not grant Monster Effectiveness", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnChaosMapMonsterEffectiveness.webp" + "imageUrl": "/images/omen/omen_of_chaotic_effectiveness.webp" }, { "id": "omen_of_chaotic_monsters", @@ -99,7 +99,7 @@ ], "description": "While this item is active in your inventory your next Chaos Orb will replace all Modifiers on a Waystone with Modifiers that do not grant Monster Rarity", "effect": "While this item is active in your inventory your next Chaos Orb will replace all Modifiers on a Waystone with Modifiers that do not grant Monster Rarity", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnChaosMapItemQuantity.webp" + "imageUrl": "/images/omen/omen_of_chaotic_monsters.webp" }, { "id": "omen_of_chaotic_quantity", @@ -109,7 +109,7 @@ ], "description": "While this item is active in your inventory your next Chaos Orb will replace all Modifiers on a Waystone with Modifiers that do not grant Pack Size", "effect": "While this item is active in your inventory your next Chaos Orb will replace all Modifiers on a Waystone with Modifiers that do not grant Pack Size", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnChaosMapPackSize.webp" + "imageUrl": "/images/omen/omen_of_chaotic_quantity.webp" }, { "id": "omen_of_chaotic_rarity", @@ -119,7 +119,7 @@ ], "description": "While this item is active in your inventory your next Chaos Orb will replace all Modifiers on a Waystone with Modifiers that do not grant Item Rarity", "effect": "While this item is active in your inventory your next Chaos Orb will replace all Modifiers on a Waystone with Modifiers that do not grant Item Rarity", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnChaosMapItemRarity.webp" + "imageUrl": "/images/omen/omen_of_chaotic_rarity.webp" }, { "id": "omen_of_corruption", @@ -129,7 +129,7 @@ ], "description": "While this item is active in your inventory your next Vaal Orb will always result in change", "effect": "While this item is active in your inventory your next Vaal Orb will always result in change", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/VoodooOmens3Red.webp" + "imageUrl": "/images/omen/omen_of_corruption.webp" }, { "id": "omen_of_dextral_alchemy", @@ -139,7 +139,7 @@ ], "description": "While this item is active in your inventory your next Orb of Alchemy will result in the maximum number of suffix modifiers", "effect": "While this item is active in your inventory your next Orb of Alchemy will result in the maximum number of suffix modifiers", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/VoodooOmens2Green.webp" + "imageUrl": "/images/omen/omen_of_dextral_alchemy.webp" }, { "id": "omen_of_dextral_annulment", @@ -149,7 +149,7 @@ ], "description": "While this item is active in your inventory your next Orb of Annulment will remove only suffix modifiers", "effect": "While this item is active in your inventory your next Orb of Annulment will remove only suffix modifiers", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/VoodooOmens3Purple.webp" + "imageUrl": "/images/omen/omen_of_dextral_annulment.webp" }, { "id": "omen_of_dextral_coronation", @@ -159,7 +159,7 @@ ], "description": "While this item is active in your inventory your next Regal Orb will add only suffix modifiers", "effect": "While this item is active in your inventory your next Regal Orb will add only suffix modifiers", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/VoodooOmens2Red.webp" + "imageUrl": "/images/omen/omen_of_dextral_coronation.webp" }, { "id": "omen_of_dextral_crystallisation", @@ -169,7 +169,7 @@ ], "description": "While this item is active in your inventory your next Perfect or Corrupted Essence will remove only Suffix modifiers", "effect": "While this item is active in your inventory your next Perfect or Corrupted Essence will remove only Suffix modifiers", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnPerfectEssenceSuffix.webp" + "imageUrl": "/images/omen/omen_of_dextral_crystallisation.webp" }, { "id": "omen_of_dextral_erasure", @@ -179,7 +179,7 @@ ], "description": "While this item is active in your inventory your next Chaos Orb will remove only suffix modifiers", "effect": "While this item is active in your inventory your next Chaos Orb will remove only suffix modifiers", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/VoodooOmens3Dark.webp" + "imageUrl": "/images/omen/omen_of_dextral_erasure.webp" }, { "id": "omen_of_dextral_exaltation", @@ -189,7 +189,7 @@ ], "description": "While this item is active in your inventory your next Exalted Orb will add only suffix modifiers", "effect": "While this item is active in your inventory your next Exalted Orb will add only suffix modifiers", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/VoodooOmens3Yellow.webp" + "imageUrl": "/images/omen/omen_of_dextral_exaltation.webp" }, { "id": "omen_of_dextral_necromancy", @@ -199,7 +199,7 @@ ], "description": "While this item is active in your inventory your next Desecration attempt will add only suffix modifiers", "effect": "While this item is active in your inventory your next Desecration attempt will add only suffix modifiers", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnAbyssAddSuffixes.webp" + "imageUrl": "/images/omen/omen_of_dextral_necromancy.webp" }, { "id": "omen_of_gambling", @@ -209,7 +209,7 @@ ], "description": "While this item is active in your inventory your next Gamble purchase will have a 50% chance of costing no Gold and not consuming this Omen", "effect": "While this item is active in your inventory your next Gamble purchase will have a 50% chance of costing no Gold and not consuming this Omen", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenGambleNoGoldCost.webp" + "imageUrl": "/images/omen/omen_of_gambling.webp" }, { "id": "omen_of_greater_annulment", @@ -219,7 +219,7 @@ ], "description": "While this item is active in your inventory your next Orb of Annulment will remove two modifiers", "effect": "While this item is active in your inventory your next Orb of Annulment will remove two modifiers", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/VoodooOmens1Purple.webp" + "imageUrl": "/images/omen/omen_of_greater_annulment.webp" }, { "id": "omen_of_greater_exaltation", @@ -229,7 +229,7 @@ ], "description": "While this item is active in your inventory your next Exalted Orb will add two random modifiers", "effect": "While this item is active in your inventory your next Exalted Orb will add two random modifiers", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/VoodooOmens1Yellow.webp" + "imageUrl": "/images/omen/omen_of_greater_exaltation.webp" }, { "id": "omen_of_homogenising_coronation", @@ -239,7 +239,7 @@ ], "description": "While this item is active in your inventory your next Regal Orb will add a Modifier of the same type as an existing Modifier on the Item", "effect": "While this item is active in your inventory your next Regal Orb will add a Modifier of the same type as an existing Modifier on the Item", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnRegalAddExistingModType.webp" + "imageUrl": "/images/omen/omen_of_homogenising_coronation.webp" }, { "id": "omen_of_homogenising_exaltation", @@ -249,7 +249,7 @@ ], "description": "While this item is active in your inventory your next Exalted Orb will add a Modifier of the same type as an existing Modifier on the Item", "effect": "While this item is active in your inventory your next Exalted Orb will add a Modifier of the same type as an existing Modifier on the Item", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnExaltAddExistingModType.webp" + "imageUrl": "/images/omen/omen_of_homogenising_exaltation.webp" }, { "id": "omen_of_light", @@ -259,7 +259,7 @@ ], "description": "While this item is active in your inventory your next Orb of Annulment will remove only Desecrated modifiers", "effect": "While this item is active in your inventory your next Orb of Annulment will remove only Desecrated modifiers", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnAnnulRemoveAbyssMod.webp" + "imageUrl": "/images/omen/omen_of_light.webp" }, { "id": "omen_of_putrefaction", @@ -269,7 +269,7 @@ ], "description": "While this item is active in your inventory your next Desecration attempt will replace all modifiers on the item creating an item with up to 6 Unrevealed modifiers and Corrupting the item", "effect": "While this item is active in your inventory your next Desecration attempt will replace all modifiers on the item creating an item with up to 6 Unrevealed modifiers and Corrupting the item", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnAbyssVeilAllAndCorrupt.webp" + "imageUrl": "/images/omen/omen_of_putrefaction.webp" }, { "id": "omen_of_recombination", @@ -277,7 +277,7 @@ "appliesTo": [], "description": "", "effect": "", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenSellVendorRandomise.webp" + "imageUrl": "/images/omen/omen_of_recombination.webp" }, { "id": "omen_of_refreshment", @@ -285,7 +285,7 @@ "appliesTo": [], "description": "While this item is active in your inventory will fully recover your flask and charm charges when you reach Low Life", "effect": "While this item is active in your inventory will fully recover your flask and charm charges when you reach Low Life", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/VoodooOmens1Blue.webp" + "imageUrl": "/images/omen/omen_of_refreshment.webp" }, { "id": "omen_of_reinforcements", @@ -295,7 +295,7 @@ ], "description": "While this item is active in your inventory the next Rogue Exile you encounter will summon an ally", "effect": "While this item is active in your inventory the next Rogue Exile you encounter will summon an ally", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/VoodooOmens4Purple.webp" + "imageUrl": "/images/omen/omen_of_reinforcements.webp" }, { "id": "omen_of_resurgence", @@ -303,7 +303,7 @@ "appliesTo": [], "description": "While this item is active in your inventory fully recover your Life, Mana and Energy Shield when you reach Low Life", "effect": "While this item is active in your inventory fully recover your Life, Mana and Energy Shield when you reach Low Life", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/VoodooOmens2Blue.webp" + "imageUrl": "/images/omen/omen_of_resurgence.webp" }, { "id": "omen_of_sanctification", @@ -313,7 +313,7 @@ ], "description": "While this item is active in your inventory your next Divine Orb used on a Rare item will Sanctify it", "effect": "While this item is active in your inventory your next Divine Orb used on a Rare item will Sanctify it", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnDivineSanctify.webp" + "imageUrl": "/images/omen/omen_of_sanctification.webp" }, { "id": "omen_of_secret_compartments", @@ -323,7 +323,7 @@ ], "description": "While this item is active in your inventory the next Strongbox you click on will be reopenable", "effect": "While this item is active in your inventory the next Strongbox you click on will be reopenable", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/VoodooOmens4Dark.webp" + "imageUrl": "/images/omen/omen_of_secret_compartments.webp" }, { "id": "omen_of_sinistral_alchemy", @@ -333,7 +333,7 @@ ], "description": "While this item is active in your inventory your next Orb of Alchemy will result in the maximum number of prefix modifiers", "effect": "While this item is active in your inventory your next Orb of Alchemy will result in the maximum number of prefix modifiers", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/VoodooOmens1Green.webp" + "imageUrl": "/images/omen/omen_of_sinistral_alchemy.webp" }, { "id": "omen_of_sinistral_annulment", @@ -343,7 +343,7 @@ ], "description": "While this item is active in your inventory your next Orb of Annulment will remove only prefix modifiers", "effect": "While this item is active in your inventory your next Orb of Annulment will remove only prefix modifiers", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/VoodooOmens2Purple.webp" + "imageUrl": "/images/omen/omen_of_sinistral_annulment.webp" }, { "id": "omen_of_sinistral_coronation", @@ -353,7 +353,7 @@ ], "description": "While this item is active in your inventory your next Regal Orb will add only prefix modifiers", "effect": "While this item is active in your inventory your next Regal Orb will add only prefix modifiers", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/VoodooOmens1Red.webp" + "imageUrl": "/images/omen/omen_of_sinistral_coronation.webp" }, { "id": "omen_of_sinistral_crystallisation", @@ -363,7 +363,7 @@ ], "description": "While this item is active in your inventory your next Perfect or Corrupted Essence will remove only Prefix modifiers", "effect": "While this item is active in your inventory your next Perfect or Corrupted Essence will remove only Prefix modifiers", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnPerfectEssencePrefix.webp" + "imageUrl": "/images/omen/omen_of_sinistral_crystallisation.webp" }, { "id": "omen_of_sinistral_erasure", @@ -373,7 +373,7 @@ ], "description": "While this item is active in your inventory your next Chaos Orb will remove only prefix modifiers", "effect": "While this item is active in your inventory your next Chaos Orb will remove only prefix modifiers", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/VoodooOmens2Dark.webp" + "imageUrl": "/images/omen/omen_of_sinistral_erasure.webp" }, { "id": "omen_of_sinistral_exaltation", @@ -383,7 +383,7 @@ ], "description": "While this item is active in your inventory your next Exalted Orb will add only prefix modifiers", "effect": "While this item is active in your inventory your next Exalted Orb will add only prefix modifiers", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/VoodooOmens2Yellow.webp" + "imageUrl": "/images/omen/omen_of_sinistral_exaltation.webp" }, { "id": "omen_of_sinistral_necromancy", @@ -393,7 +393,7 @@ ], "description": "While this item is active in your inventory your next Desecration attempt will add only prefix modifiers", "effect": "While this item is active in your inventory your next Desecration attempt will add only prefix modifiers", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnAbyssAddPrefixes.webp" + "imageUrl": "/images/omen/omen_of_sinistral_necromancy.webp" }, { "id": "omen_of_the_ancients", @@ -403,7 +403,7 @@ ], "description": "While this item is active in your inventory your next Orb of Chance will upgrade the Item to a random Unique of the same Item Class", "effect": "While this item is active in your inventory your next Orb of Chance will upgrade the Item to a random Unique of the same Item Class", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnChanceAncientOrb.webp" + "imageUrl": "/images/omen/omen_of_the_ancients.webp" }, { "id": "omen_of_the_blackblooded", @@ -413,7 +413,7 @@ ], "description": "While this item is active in your inventory your next Weapon or Jewellery Desecration attempt will guarantee a random Kurgal modifier", "effect": "While this item is active in your inventory your next Weapon or Jewellery Desecration attempt will guarantee a random Kurgal modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnAbyssGuarenteedLichTypeMod3.webp" + "imageUrl": "/images/omen/omen_of_the_blackblooded.webp" }, { "id": "omen_of_the_blessed", @@ -423,7 +423,7 @@ ], "description": "While this item is active in your inventory your next Divine Orb will only reroll Implicit Modifiers", "effect": "While this item is active in your inventory your next Divine Orb will only reroll Implicit Modifiers", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnDivineRerollImplicits.webp" + "imageUrl": "/images/omen/omen_of_the_blessed.webp" }, { "id": "omen_of_the_hunt", @@ -433,7 +433,7 @@ ], "description": "While this item is active in your inventory the next Possessed monster you kill will release its Azmeri Spirit", "effect": "While this item is active in your inventory the next Possessed monster you kill will release its Azmeri Spirit", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/VoodooOmens4Green.webp" + "imageUrl": "/images/omen/omen_of_the_hunt.webp" }, { "id": "omen_of_the_liege", @@ -443,7 +443,7 @@ ], "description": "While this item is active in your inventory your next Weapon or Jewellery Desecration attempt will guarantee a random Amanamu modifier", "effect": "While this item is active in your inventory your next Weapon or Jewellery Desecration attempt will guarantee a random Amanamu modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnAbyssGuarenteedLichTypeMod2.webp" + "imageUrl": "/images/omen/omen_of_the_liege.webp" }, { "id": "omen_of_the_sovereign", @@ -453,7 +453,7 @@ ], "description": "While this item is active in your inventory your next Weapon or Jewellery Desecration attempt will guarantee a random Ulaman modifier", "effect": "While this item is active in your inventory your next Weapon or Jewellery Desecration attempt will guarantee a random Ulaman modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/OmenOnAbyssGuarenteedLichTypeMod1.webp" + "imageUrl": "/images/omen/omen_of_the_sovereign.webp" }, { "id": "omen_of_whittling", @@ -463,7 +463,7 @@ ], "description": "While this item is active in your inventory your next Chaos Orb will remove the lowest level modifier", "effect": "While this item is active in your inventory your next Chaos Orb will remove the lowest level modifier", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Omens/VoodooOmens1Dark.webp" + "imageUrl": "/images/omen/omen_of_whittling.webp" }, { "id": "uhtreds_saga", @@ -471,7 +471,7 @@ "appliesTo": [], "description": "While this item is active in your inventory your next Logbook guarantees an Uhtred encounter in the revealed Biome", "effect": "While this item is active in your inventory your next Logbook guarantees an Uhtred encounter in the revealed Biome", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Expedition2/SpecialExpeditionPage4.webp" + "imageUrl": "/images/omen/uhtreds_saga.webp" }, { "id": "voranas_saga", @@ -479,6 +479,6 @@ "appliesTo": [], "description": "While this item is active in your inventory your next Logbook guarantees a Vorana encounter in the revealed Biome", "effect": "While this item is active in your inventory your next Logbook guarantees a Vorana encounter in the revealed Biome", - "imageUrl": "https://cdn.poe2db.tw/image/Art/2DItems/Currency/Expedition2/SpecialExpeditionPage2.webp" + "imageUrl": "/images/omen/voranas_saga.webp" } ] \ No newline at end of file diff --git a/public/og-exile-crafter.jpg b/public/og-exile-crafter.jpg new file mode 100644 index 0000000000000000000000000000000000000000..aa45236fe3082e23c7f2112821870603fe6a3f38 GIT binary patch literal 146465 zcmbsQby!@#^8k!u#fnRD-$H@n6nBbju_DFY-QA^y;#Qo+VR0!=(c-$m;#!=A;)`v8 zzV!3GzvsU9@0-b)b26DEljr12l9QRgOMh39WRcMR7hb$TL;n}BFflMNv2d~f1zZwb zeB9?qLiCD=@cE*rAS0uoe@#bA_nL#1l|xuSSV_t9UnR)@e^>Goi4YUT8?7D{nGp$v z5E+#a`R@P{4H6Ra3*_g3^nU>b2^kgb1^Tmu&)HPSNT~mE|G(Kt$SD71|6M`CK}AMF zAwVT~E_sJ6P~F*Frm3d{j1aaXx9qN#&a30o%3HCL^TJMDHJj6(u52D4{VFYNO3n$pYS|Oke5snbDV^7Z#+M%Yg|vV{&IGAkAoOEyB4>b{E{c zxAJavS)WUdA+YiNUc3nUFM9nvdXi3|e zvT1agzduk+ZJVd&Y!*Wo-sO-g!r=}i~kfEUKZGr?IlON zto>~HmQ__j%QZEJQZDOnU=*OM;ceRw_uY4s?H=f0bt}quMU&EH!apaG3r>vLFuB;? zQcC9m*ZhH1M-fa?jqm+qInYbmrl^<_BFrw593lPJLJ$bJHN`3J1EH6UJwxA78&Gqg*SsEH8uVsmy$${0UX{`cvHG93(ksq8M+HNfk z&aXB&i!pRW#G1-EgUA`t%`lSyr6kHSXfdt{EuWRYf~Jv0u^R~RJi@Kf>P2w#)cfAF zp%!5(W>U<}_SI;q;D%u@mCJf1J%5c!lYghj@I)E- z%=`umfHQ=u{2L2^H}yG1YIN;|D6S}hh~f*OXuvN{87vTrqBI~fm4PZ6O~(Pdrodj; z!GTGKT`?#wxWzt!2I0jUJ6wXri=NFYT^8x~n%9z75z`%m+D-Q>6AzLQvuTWir|3Sv@k!3sE;2C-;n8z*?!LQC&^9v0plr_I*p^W&ZJb3nkYnhGc80wFSm;> zkJY3`CBMr$a$8lFM8(A79qJ?>Nul?Sfdsl-XCY1>qgaV9N;vEH>)YGKW_gYwVK$kU z4b8?tU37LY%1A}y?eS6Sb$2_q7ccSV-ux8gCuk=?(?E*pOy+eUSXC_sVrFJ$z8xXY ze$NdgX9gzZ&QJ=iB!5mtc|YW>=*oaL6^fa}o$KiR9_chJcTHvp)!LI8hyv`@P~rQI zVl5SCNW+I34S1P~L?zT0AC_7eR!%B*q&9Q7-N5v z#lVBiSHE2&hQ-4wB{T9Fa{!k=dI4*MBzaNQIt`WGRA_Fx>3j@V@uq4L_+rFrr3>$X zOO2IYP#zzJEo(|J8#$Yx+) z11J|a1uX@0X#mI(Pen>lNM!GrH5IUJtO*TqZ zUKP==;htELZX4$WU=;~-s2q^TD>hyC#(!pXm>NH%$(_K z-=E;PE8>$csQ_t`zpzh#@sM_F04k-|e^1#}^~mxNLp;)lD7T>9+Be>bkLpy6O$zPC@dGMpc?0g~5^170<)Y ziF*j^y*k)io_C1Rnmc-FsgDUMQxPQ|1;tXR5XIURNX|!XdI}h#V3P4se&vG<_%)$O zZiHgS0~o>L!}%hVMIKr#P04KfqlAaAVPJqrIl}FmTU=7OStgSm8sq%<%+w~A2|e@d zvMs&bVt-!qEFl)GFKWJJ-PJiBpH=CRP zK;TnaC>4&n3o9@IT$NZ6xlG28;dsT^BC@A{;^6VA^gGdURXQU~VnM=RPJ2+Lz5;KT zjNFHlbP&4>Pn0dKtrk#Y-{Gljy~sjQ5?gTSB8&;3;Gu4<5tGK8;J_r|piWjs258_y zDUrsc;+z&~r1JzBqeH1v$@}`SrBpMq`7DV@P=HInw(+u1Md^tYi4-YBh&;oVxkY%$ zMcfzwC|{*VaO3b8h0U@A!%e9*MA0k&^i5YyjQQ+J!or?>r%if`hrA9S6@zsky#TeL{Meui_=c^h*TBhqyRk11$>xecBG%a4|8@-8@&AFD4>7nCFc0> zNN|KRIuCA?tDHX8YzM!N4a;!;V4ES+)b0?cpXN1SulvcV9v&NR>b|q zF3+L-2&ILZaFcmC8|61rs&T5MMw~t(OH=}JW*g?v*Pim0On!2VvT>2y&uWE%C~n(! zND7^S-V7K`9_|BpKcK9<9ce)yKN+e{kCe_$WNr=&gVOtuk%T8fBT(DgaxtYrd^Ch5 zv#9Zd+(Mle+^jM$;dO&@IW?It{NsPI=~RApCZ3xr^3t%C1+=E5CI5W2i@jK`j7btF z(jtYfJ6e?9DVs)OE|3N_7bZsiUi<-?EVq#LJ7NN{_DEtp*y&YKTw{R5> zzq?h<8=TwTw}fcC9V&dvd4a=BABUX@zFN7)v4o=4Ix}VCeU;5K!X^_E=fU6<7b_gi zX!V`wNEin)t75UBSj!TlVG!4Y279N!Q;2>v9iah*Ei(X;7++Dxy&(p$D2FX40ls4O zh7A;>`0iqm(nASCHy}ME!Yg_s0dsY{AIR9tfN8A8_J{TJzmYprD?cxV9p^-lPY_bP zW0Zk~H}z3_(+E{l9~C&&ARpr zzifA_RvyC-)!0g>c^uxxHuwfVv1VH5YzwTZz<8Cz?jRaiDc+F*B6?T*p*jg$kyFe5 zW!mrWoyjXi2?K6!u{DfT3}S61HdF&M{09_Rd%mfWtPFNOV($r_c5mqt#anlSHa76t z?+z3naWbwtMce-($vQuI+A2LVJ+%H|+2Mb^hPZ7$c$of+q^r@dmhp0<)28_CbVk*J z&>|wXb!T(i>RJKvLxFdlt8wjNchlC{{p7srk?!hNn;)b8w&dwkNVCtq*WH`0odHqq zT9^|G2CV*}t9t?_?0qL5gebVfdfJZR+GdrQybxy@#>DT*O06evhex05dz*1r7;j+^z?qfg`7@;ud z+3s^SbR7?oEFL`x5I7LXW0RC#R^QVR4>9Js;B+|R^f7$W>_z+mExIIse`+aRq+{~< zi==fao)vhYu-OoVr$!e$tD`F6Cp&xp$h%{UkQdaEq{{idpZKa6_Rtza#^>+7$)>?S zDIbl-`++H8!Vc$ml!ugz22F`-v0Y=BHb7U8feiY<w%;c$Jak519yV#rNVu`*9z%nQ`TOn{SNN`xqkLH=>>yD$IlW&6-y+oa#QC zM^-^r2yc(Q*OO~nS^3kzks#KO1meQ&qj61=PkuY`Rac7@AlT`Z_jhRh%$1VfX8rLU zTfa+%*OPQJq;7>a>wdAgZyterbwIHjZ~!L>5&!MEcS0r+m?S=|aA34&yy&pMTK^O~ zcfao}kzaNkIEn6aJykb?@a?HS3yi|2{fp!Pdr)!7H~H~Ac+(oA5q*JCvQ{_f_zwVuNg*WELtPiJiMdhc42wC`qKoN1fzPl4C?7WQV)+M*=HaC0V5DG?$Rd~-Qjyyts! zAx?{tgd3(ksUDy+y@3H|84IX?U_iXMxK$I(Z!LhpX-!zeZiWXs5n~{4b0+%GfYu04 zLnF!JCwxed=4IaEKHZ9bo=ekxer!{Z+BTR0*6V+&&@t@N;-pk_e>V4Imed22q~B=W z4Ib~Czmd$o4vZT9(?dj%aY)B4ll0A9o=z!<^s;q6AM2Wq=ivmdHr1oHmF*%A_X|84 zz)t2V`Co;Tpsr7x)yG%T3eQBTF<9PYN%3;r+VtEn027?qDWv4_X3C1hu_TRNK**itg zsPJtqa=kw99=)p5TpzvN&p0^E$1qtX4pg$R`;(~li_ZbhcyN##c#ALr-Is}z2gkbS zqg#M)=xym6Y8AV>?})nGuFc)9Gu66* zK)FfqA#NSS{o1$t@b2ZIOWqIeJl(yUz`HL4DkQzM&2Y)lzew_dkmk)mw;P2_kK@a@ z@V`h#zsPe~=-dXpGhsI_vU@?BeL<23DMXLNyTi*577IfD-St{9ZLq7zv9gi(_8UZHXEFPp4IGS z`Gl#%p{mKa2tLc~VOh$l{-s_QC)h+#Q2q%ox$sqsu0a%8HTFWal~tj3k1`jnPvKVC z!MDd3zaETuet#;R&l?|%JHW4w?7r7%&+nKQ@o~_C3(Xq|T)T)J--&c8IAACpiUpbW zHm2t^UHrnUZ+B>Sn9gTbH@MeBkaAB}%v_%J9^O!|GmT8v9iF!jt#?ipn-OHAO_||n zGm_OkqF(()Y7cDv!8MR?8)yZM<%hr}aF_^$R(8eGkU+Wm!aIq)L#E5u$$?;xSIMX0s1{S@JNnwBf@u@e>PxKD>D6<@hB0@Stks=PDq6uU((KW%2wqpb*_F(T)Eu+m{HLWAPPq& zh+r`VBniKlI#qTlga&)8cavg>x=j1zIET zHtLvwkmbvq)d$gnt>ZsBlh2w{|Dua7(((qM2BAjLk!Mh?cC<>;6s)v)r>!E^^ZmX7 zPA37c4SMVl?my@XNgm%Y*t`^@=?*<>tYf{9biB|GFsZ!vY4Ys`LuifQixfwGPy9~< zG~{=Gkt+OU-L3;4(?~X2^Y+JPFbjZdw7S+|L>TDa5S^UFxqJ zo^UVq+tq%$^6kn~EV&76v(mI9JL=W5ds}bMQd0*}-`i}@fH1Z%j=VT@1Co<6nA!jw zEy(wy1-#uvhk8{=hYDmEI07V66F@!&`$A9n4RBmK&{~3mJw~1ZsP>h3dEO2>>wsIO9aR4Y&3Pd8?HVg zZ?|h)UtLQyUM(rz&`4tGp1?_Hu_HF!0-acvj{FYcSC7aOevEsE2;`?AX*hp~L`U#& z*501tuGOI%5s4s~3=0MpO&oz3^1CA)^HmllA+8OuM@g54MK&q%oh;z7gUsN9i3@_1>Jwc48eLE0wLE*2yX;VN(UXE$BzgB>(SRJjy$dK8TPsC9??lIQ-}H=Cke zOe2{Pu^tnJr$@JKRFJ-j>^#97#in?l{SBB*lB_tY2juKXVa}=vih$Hb{yEUudg3aE z(<%&$J#tM4(nX6BoIc#bB>WF{wDT9bdiaJ{Hz?K z-RIJ|6vt=Z=xczv1!Yu#xcY-66W}JCbn|y1g|mSf*Jsg(52W$eYGWqAor#H#`q+Zr zGvOA5EL1FNLqhPd=bhON7xf>>T<_Q2Ufl`z(6!F)v+sdD)4_K4E+%Campnl%88<^@ zBO8N}8Bfvosbj>5TF3}(h1>NoU*TS`LLs>E;_II$lf@qTKU|40+O2D{(M@UJjSSI= za|zM)@oRye5w&g;wZOq+W2NqZ9{GoLI9OnHlP;*?e68y*lHs{{LZ`&VRpa$0>fFON zhhbvPxjITkhAjIBjw}8~La>L#Dsvqm;^@08%fV`UP1fS2_f=ZgO8}3X6+(3f}@~o!{zTKHSzpfaZ(It6|1)PWRf1 z=JA@brM-KR3OKHTqtA8>j=}6RUeIs+_@}V@ z+v(k`l$*|8gvmijt(c@{=X zX{?9u_>NV9W$j@}?U2@sRNM}GP6D(aoH*XI5G;PYA$Qq*Hi4FSB4KaO#~ZwOO*d`= zd23v0_*2|VJK;o--bnk&i{2K+h8tbhdjUH?Ur^u889I1&@51Hgh+wvT6vc!MNA zZ|^wFi@!Qc4Qy@S%Uj(QSF7v0*__xol4L&#%2Vf*30#g88c#4lYV?iv5#m7Bt$9HO}w@-RW_@@$P#XJhrwD(sb(;>w0 zRelMN%Z+Z6&Tfrg{@vA`T|7bfsnbCb7p)5+lE=@x(^F%~_)Uarq=LlSX87Q^{~DfM z0IfR^1v&P_@LUi3ek`ri|viSNV^~* zGY^n6OWpqVO1Kily+Ci)9(JJHTFdMC)GA1vZzDN;tX;MA{(2)9y4Zp?NpdwfUFS|@ z_b31B^@F&H(M9G)#O20fe~M@4;%Xq2MdwXu-^(TJ_?|DMH=FtXiAfJEa}VQZ!K8DK zJ`uMrqj~F%SH{Erubsgw4^ZbV{{t3lrg=0U>^IsBSFC;qf7uMT=U8bZzVO)-iSt`TKG&lN^Rg;{N-|I zD&4L`#EL{nO))f$I^*omz4u*?@v}aOm&gEJcfz!#k8|P~7qBPTj5lZp-wGsv##d~> zbduA1VCgyE{Q9di*nLh{B8$REdsh@6yqgR2d9SR%@9*c{-oau$cFU?eU5!w;DwXar zR-AhYoB`W^{-GgH%AI>|qj#}hsaEo*b>u1j7oxlFifc~$sxCQa{!Y?oY|vrdLP*W= z$W<&+q0doz9r5JTenoit0PeYLKihf?nfl{0+k+PL@?sOH)GGnK&se?^$}jbmIK%Cf zO@X!dm`qA@!*@bpE}4&ik@~L#@{_vjf4MI9b;*uD9zcIxyX1*S zXm|{C7Q+G0Yk`n`@h&yux%)C%{Ic_GR*mZo=_+x^9?0)yYd~EEuM1Y4MSq8ra{ppn$-Y-!$(oINr{`}F} zZa=cQ{Oxyt?PEc9S?~P@_@@&q2sOp0HYD@X$VoFz$XYm<#ugeAggx&LEnME_1pLCU*g{m;N9{tnaBmPUo4j28%Lf^{6#9D<8`8Cn)1@y*vuLKbmZRB z&usTe<)-F!&h(hLTZHw%!=jXn!K`1~pAISop_}qcJO9@>9nJ8fHpolT!Fhk5FnrMB zwT;>(%^BSc;x_Rf%Eq<&Z~)o8ZUY>(o5I@!(itJD{V579>e=WWe~~`kp9_hKM?qZi z4gcgxP>ArjGMB^NY$s58YFy#JTbS;1i2q~QIO(Zt8enNE3*@VJ*w`DU5ir4>_omKF z&k|Ic40Y-My6n&yc+4_07#yMQw;yhIfkqumsunAeBH8@!J zAu~xCJ=w7M?U#G=g?-g>89`Cp;~{dT6PD*Jy1d|%Xg9wdg!(&>j(u0unY|Yd6OZmp zIC^yykzW6&-57g*-@QW}WOSLg;8{Kc?M>wf!mqx30*}KVx9jpBDR%rf#itQ3NBDEj z?;k*7X>7;-oJ)64ufXEVqxMWu#gtIENTc3k9{-)o4_$i>hF{(J(@~e!83B9Z)IU6V zo07;pP{2h9x_wXrXI;5S0t<29jgT?ju?zckn;011eY2{6SZ>-aC^x$>qH2AdTQr|R@Am<_u!z!t7vgwnmZ*tLwsCR-y3&JPdTDSgBXi1^Y~7rwnD zV@^JJhQBl8$JwugQ=JA67fz#2{^7=|^pTC)snm?1Yxh~zoyz5X*p7%A-c}GEo#Xjw zS%!@uZklVGcXnkhC6%u@C*_}w+Yyigm%=Lb%a-@rgLN*Yzi>|%tR7B}*Es{N^LyN8AO0c<9-4r%XQE*F_@Bn{7fnQq z-fdqzYF;_$jUT)4W?$F_ z<;a7FSOa?KY3(Fu1O02&drd zFw<7ixH9@;Nauql5NqN!E1-;#<>AS-ha4P8Mfg>Lu^39Dj=0S2}&JAIg>FIgkyS5*$%g1d;-NSUVxkEm={@pHh z_d%xTUET-QQ@=JFwwnvj#Xo%UW)X%nM>v`^Z(As+EZ;LKd@AgxKSPZ&rIWt8A!~LO z%K_KKWrG)loP9NK)r59ugIs*Jf7AB#dQ7oCeYu|u55h@PS{0h2DSC`Wg%AXou=Lgg zH~o&K4FYoGL6bhv+>dR1>N zjT^w>-upFH3qK;)=~DeMkPqE;KPs({N*stvYU?D-*Pi-0Z^QGzTs&1>gC0(E?wYo) za8*I~hi*g?v@s=o&4^53&3~b)%(u?cp5ENM*iMRq#2oM|CkaW{|B!)~yclLK+-*zLK;4>3 z2jzQ->04-_b+o)xQh~QJ9;{bx33H&YcY>jTk~*EwlQG>o!PHBmUyw^V%{cX=L3(6z zaI=DkhYnJj7llxxmHS5+ujdrJng4txP_z-=yu50bqfL~rIx+{*XKL$JM<~2EGqR1Xa+gG8llxYr#7BD%;~{BF8r^Ke;-i`vK+>6y*1KZ z$rtmx7Kl{i`krb?-8YqI|EWgFLv$cVNf7r9O|H0m&xh(-V5!45`kyHjK%t+CE0(ZA z`Ce8`O2rq;eW0}$R5m5qMe%8jw zeB8{IjLba6C@61|wpyvrf2JXrV6SNN{Oz@c`DQn~#!$O*oXxE2RCXJ??Tj)En+_M7 z^Rlkw3=BaCCATImL-sg2f@MPpSkprpf1$$<0!Wf>PGLw|?*izmqif*9|1B~?E%*tqA zka;jiLc>CP-@CO@pkR20YGQr}4ch>)B9mkBA#-OAihfp2Vo=6f#+IePz!E|BAaIwRypwyl(nAThC61rKAYtAdt&YM|v(DkgqE0Vqdmk=_cngT^J;y zX}`U;`{RRBpL?cYfh%Rzz;@kFM5+d&N4I_9(i%? z89|g*v}$&`ve!24Nc^|BxKzOdW+!S+x|eiYD8lmsviBuzzSC zIlDMrCYBzr!4!4YXpHQUjryp0ux9_Z=8?g@(LuUeRy-HkRyNVBMr>SHg;;?vS(aOd zxbb7tA!Aw=kDE70EX)WThpgC(2Q0La0wpmkl7B(_NUV%8Qjhi?O zCs!HG5-C~{MR5sRcjkRK50GL2-#!gi!FQ^z8jwYqa!UGk&}a|OpxFAe&?ET;oJU|5 z;vjOR=Uuls?3fwL=zARkZ6J9#mq#XKFCeUfKiR}Bko5>lN6>3gv?Tzg;Ns7+I zZ0y!7EV3tAiw{mECZZwYa&K&%KZ)cd4~4yKlq2Lu0geHeQcISfZH}aNG2O)g5ro|6 z$!LmSimY8VL_<4m<<*5oDEa_lONNRd)KLoLdhT6QSKBG>q%hPWM;s!g7e^V^k!dUR zl{u~cB=;_W8*s(!I*DE!y*GB zdpRWE;A3mwShQSlDsFi5T*z#MaXTau(dJ0fxK%t;!Pa_1x5wX%Yb=`6YZB)^s#YD% zmFi#XWVeHuKa0KW@)ld+=}IV+&@!tt#*6dQSg8O_j=?)Obp#6CzMmu-q-7-0bPK%H zI<;Wi?ON;l2*#W`qocjY1UR6x@Zv$Ve#+1pu7a zg>xafN~dW(A*3gb}7Aavg;|8=nsoigHKgWtSM0-xIzTBVV2 z=gA-5RNt&&@Rh@2QWLD8!)Z@72euc!g73}tAcKw9&5>e8v=WAt+YkK~?Cn5@jQ&zm zPMG85;$PqLyNO^#Dh^Cd4OwObMQ||Fka0qJhem`H$!$Yl@HLHm1`hV7)=zHJ)4L^HVk_-$PDm&G%B{LY^hv+$s_9`if)Zc=34F6 zJXoo@h@~YB+^=II0KNgGM(|*M-d6VZ#!${yPQh9l%9InPNn&urkUC+C?_Dw^ZbU|{ zCyquTGX-#Bfu5~`+)2yzET)yjXf2tdNnu z+L1dIxlD@Zu7j0nn4`mt8`FVV$iz+6LH!n1c>^0+1m^OZ{m^WcRgSWudhd#jUcJ9s zJzsHT5>rht$ktUEZ;Kf>y;}3;Qyz-#9v>w|A1sDd(#06j)N&|XNzY>Q)x|zd?ff$zs!#bK7Bb`E@g(ONQY*|zlZ?xnP3k8EDEVZ7+^4YYlq!*S% z%!^_DJZXqn;!TAK6?i@y_eB&+oxZ{1#dx-K;$~Jx4~_d9h;WdjNRMSrX0`~btvA$7Z5+`7pZL=^aBNPy+;XV9fwOxmPhzagkRiW ztnudvgtRWAQ=r%`AYxs=%iTOq@oc%xY%if1`QY~jw1IO| z(QzN8B-QwZGFiiI{cU?TG#q>MNWiqY`kpgBW03#);J`4*_Hv7Kh6Y=@EwIDEt$rhY z#4=WYoONYZFSXgRoViXMEiZMi-ah? z+PNA))%W#FO9Qch0>jEY&H$y-yLV-Ntm09_ic4>`#0!U{>+swi*^t@mbtS4m-q#F(38-VgF!OYLwm`Nc1zsnU#Mai3c!b85R%V zDarhA@kxprB%)qM=3-0(A-=KzWG#msPCCWt{q#`7}_bN<9=Z54j}h3whl`6Od?)mH6AYslRz!LfUC z(N@6N)H>KMnYWSs{}owzQ@uRgRYnDM{v)pb!>O#ijnDM|;r}tOimEw|O;nFfK^d*A zwXFgsO4d@{l}pAZo@4bheoo1G>Y9Wkp0E)MQK1VGbv;=fl}YEMxK#cJW&hz?=UQiA zJM+>0(f)4EaZbwrC64wHWzX;rTR+3UXAi;o{}1T=ch?d8f5W`s;&Xcb|7aWkt9SQb zjUDa(pu6_U%fr>FGG}#AkFITWm4VcoFZFat;El}ijc_aM6KRVj&#B(evcC37&>u1n z)cQQtklr56js}R?6H2w#uGd?T5}JX0z_LlJKUb5pxzbI3!^F)8<)A#Nn+hL5!{|e2 zu(Ko=ZLUB5pNl7y^mjJRG5B3t3*68fzgE~hJKg$Q@r(P2bVPaKoA&2kb37_M^xyX&_7eQAt6h2B#>Fo3X~RV6#0Lh>#px9B3)~UP(Mu58 z!Y6!_^!(<@9@Tc6BgsEFHVfi36GCYH0{cN`!r`>KC!_D%rTU0rkO`W^x9-DlCvGyM z+K36;gP5895~hFMQujTD^s`<5YxJMIj@K5KSNB2}x&5N%}WaA*3!z z6!;S#mv2eghCBo%2xB+o_%G6N2K0fmjziMa!zHD{Hm`NUO!DBr^kLi~v)~Qy)XaU1~d4NigdqX}k%m7ckQl9Y6S44k*l^3EHcW{Zn zw{7uc|DW`duQfL3zvGY4rTE>Qjd%=s{HvDW_6!Y`k2<6C&3l>)P6dsZ%CZyEOR~{T zG)3OHm`FpbzqZ`C8CauF*vY`xqS6yVB{%^dc%lcbew&>v4SR{zztx=kTT4PdFYZE? zsaN4g>CXql_=@o7cg~V$0+9qW?LxMFKY zwS}_St}0Q)^@ZUH3|(O&hK;XKEln5&JVbpC;KaRI5OB+K1pJgQ6>`6qDAt`97ZRqk z2mXEa+##2vo^pS;LxOzpTV;0$1B96PcqGWi(Vb2&SGo2l9+Cyp#A;aPp=^B&50|I6 zwI+!Sx+wue!JGoaYNz#RzN!?~SF~!KhRYv~CoY-MEsosNpITD2 zahyc3KMieclU{{qMr+H%%pJAkH+-_VbNkod^NsZ-@7{8&xi~(WMI||UAGC_^3x|kB z@!g9!zpjGPIp@S3qYCQRILYZ1?jZCt*@ONffj!!t|0u|>S3Sxq1$+{E`bL`O)=lFw zb?bbO^=yjyxo;>$% zYr@j}rl5O7UqwDObsr{Al8_9@f=+y|#)2Y#=H%(O3FWLhE>Uq868}-|Lxk{I4sEg= zb6exRKO6Dg7o%0$l^35t*kr=#MhCWjX zZOixs(Z#ZS!e(t^o%};x7M3Ay&-Uw8WjZz8XHpz|)L-SRCSNssJ%i`!7bd?IO=9+T zgXor5Wl}oHzC5a-{EEFg)(L|dmO6jR{B}?lOf>9teSX%MP5?%PL|&r|{t^7S6#e+@ zB$*k16A~5aM)&(ERDkR>h~~qjP}jK4&zg|zJmtsa=NX~GCV=iz%C6x+Bz{^0|5gUSV2%tIvmm zo9SOcH#$OAPDbVCMLvA$cHMuRoDJ#I9W?CNJG#G*=WKc23JJ6HfTfC#99XRCN}=;M z1f;h9uMNIBM;YX*#RF9<4D<4djpAj3y%b)6Pdr?pl}3mK#8t@*%yZho{x|-h9o5JW zc{67^xOAZ_nh{a^P0*^VsKUB_*j}5_b|7)s=9UTU{6vEKHnt2M_YESDXX5Ua&~QIn z;C|NzI_N-lO1qTyL*W4FEVruXGM_W3lQSRqqpeC+^aD(DC6JPw|680|WN8k)9ee&u z=|=cYr`#$OpK zo0-l1cCojo7~U4wcbGUUpabv-G&q~}%)W(tM} zb@FHelBHV~?z^Zd2EC7zXJY-WR%6q|M2!-4u+EJ1V4ij*_)Tq_r6w{B@;E}V*L13z z>B95>rz4LIj_2|pj1>k9Co%)1Z5-9I^@3LG=Z~*HQP*wc%Ceceb=f#wU&MpmjQL8K zHae9e`Mzd%6Gt28M;V28%6_$ln}p-P!lBSAC+kHGrjJ~Z2k=y3Eo_oO@w55m= zw4*w!Fbqpr@A0+c$+}I56Ljg~ACvgx$wlxUV)S53te0E@*_zEm&0gtF^6+ z@FFLi8pG*}##4se11foLRU`aBqGG)*;OD=2m@~4I3llugyAUsO*796gIc6G>M+vgK zJDn&sALv$HWUC1uF>MVp9Zr$$$I2Dv?q2@D56uUqh0Xdg6|_l;^f9$gasg#2TZ5j5 zH3N5EPHHk8_72q_plXf4vRb#G5WPv(!)fQcj+R6A!VcoCYH)cFHI<9;!`unDY)~ZC z!PYlcvMN0BC($a_VcO1CR9__g6-TRNj?M)1MnT}7E&Zt`ue(S@yQWowTOqgZ?XE?- z>+6>54!^zu3}VRJZ7=bnz^*<2DhKui1{+O-a(AUj(=LVIMQKOOS91*Yf=fEB#$%AK zX6Er2HY(kum+QvJ#zhtG*%5Z4{x_c;166N;YMQRA0hBcigTo=sbriAXZ#3QJi_$eZ zKh%EJIi4Qv&?}$0VZ9JB9}=ii$oDwr?@<^eH-A}N1CU3tP-$oS664YVd5y)y{%?Fr;QqppE*G*PMWqS z1{ktR*5lgouk{0*=cZU|Va(!&JhI2-ngzzGuqvhe=I#WH*6o`0Pe-GsP9AjO3p?}u zv@1=kX_#^SQNUgQ3UF!K4DY}KP0qkJKW-`F# z_5U#S6<}>OOT)B9N{beEdvPat2((b3#a)X_ump$VR$N+&yC=B2I}|Mh*Wzx)wSW5F zd%x#rPxhS5&d$zmvSDU-W;XL#eJN>JYUkU1QU7q*)Ehg*N`-~h@z;{6{mKd}NT6nM z_3t-RY~`q;M~=|KAJg*`>Ux!X4;GhMHXtG0HoZq_rIw@0g~x&3rBQ>Na>PkK_s6qH z(Pl3;eIt#lN^L}e%f8Y9uKCBFOM4i{WI5MCo9^c!kz&=}pVsVV*TJMtJ^J}7c;yZ9 zmYW#5`5N67#FK90E27XjC_C)g2PmgrqT1)(#c$$2b@Y0WoAuM!lViNTJzVQr9U}|( zfcZ zwl_$fX?XdF2}w{X3Ht!+_!HWE8ZR88TwPHnqyt+HA;vXp70dfSnbj3gbJX*6(iLZw z5qs2h9zpu{vlY{8vm598|Ehg|wOxG)p5IT*h(s)jYkzO!uzDVP`^=?x8PZ+|3c&;m z?@i`9|A;7!9G1c3@(f}%DgxClUA?59Mo^+4k(UVgdg$s?nrWLRw@+PEUGVaDS8Z}* z-A^hh7%ZW>J%^r6wDEa8Y{t!cJA?S5U^d{F$B1)UoK@Q_rHJlPXo)y}g67g67VKUwd^R_QW61 z^CF*|i=)W%lM&5c z)3m*!!0V^(|0z*OjdsvIIZc_vQ#@{Dfa7!4$1o3LWrwp^UfvhY-X#@N&w`BbDh`gk zA+K^0zAuVK)-No=f-Lz;w_7+_5njL&7HCGXAj>idY7GdA-vwUEoX@VK zc?1ZA!woB|5nd<6FLXKwRNqGIYZo~GBoR3vfBC+>ug1*Z>AWanE@8TGsMkIWsC#HL z^$$wJc~*BX~@Tt+E=0eQC~pReRAni z0)+8opdP9gvM^=HvtKqI@>DPh2cZMPt|uj6#R~^&b;78lujk?e^XT)f`_M(HONw_d z2DWFnkkXw5qtohi&9|drv8q9w&*Ku=fuAWy2&{N=Fd9<6ZhWty8?4YMy{#Y3(bVOY zc~_~{l%aUPu47yKYj^S4{@%iJkiTK`?4{CfJ$cMPhmy6XMNfwbysVw!10r&(mPqWi zF%f?BG0#*q&!Q!!A<`UHD{*GERNT*n_9y*DZojsVQeaEHwb#Wg#u=pVW|hbWi!{`{ ze1;hW_tiNWe90@A7#JjqMM!2CUrR0^y=-e!ONiUkpzV`~ab8QkFE~n-!!i{*bxdxc zBVKHKC6FERvO|l*X zw9BSxA&q0P8wZLCX2s|RMK_%2!3#~oH~p5*K+G(HaW3RalM2}Nx8utJ(F)JsOs9*k zgll{gB?8-S4;BgHh|0#PDhJ8UpfkNUyW&ScpQgCSWBG)9Q z>i&!Ek-f+m6YUWuKC2*c!ft~9U~c@U*vZ$6*;}Xv+E|l?%kETDka@Tl^~~_jV@MJW z4zYTbRg+~=agDt1s?yg`P_W(#tDlNSuC>dudQ(c8vVpdu#TT?f=gD@C*Zd2StZihF zf)Zx?HxnD8U$$~3?JQG?==VSA2RpXkjSA`OZe^?2&!*atMhdpkO$0p-#vN-01!~8# zt}XcRrICaiv{!`}P>He)E>9}h@GF*SWH}i{jW^k6IqUG~#o)_PW*E$AzrL;W@VFO4 zF2ck};NN;|uLS*2cmjU~ZaZ08dSJ!@h7Tn6@f#AEfKIY3PQ=TdeA#9C%MhJU{qu<4 zF|BGZ9RI{`Vx~j-W)V~e`(>VSh7&ZU%|n1vuaIOY&XfzZMiW+*@)}TRkP{J0 zdtRk&@04GKew5%6bj-Y1IN#uOaXs%=bVwmf3qT=F+qR^K8j;!;*4IW?_#Jv3`K19Q z4vQ)*K7M+jOV#C{Z5r-)G4YK|e0{R-mnZ$(EGO$AQ>KtIk*odjk8-f0Ydut0Ib||L z%69KDe-@RS8%kBInMhk!$;9^_!4w#>ujg9Jy{BEen?94S6|-z0{fP_FqG<5pu748hLaRGPL`lAe-x27)#-{aP05?o4m*S8hI+ouBCE z*-E9?S8vtMHYjR^F5JOpCt3s^7FTwi{KBXWrpIwMt7XB z6^BT5!CgV|;-^@IEzPLp?#gNKS=Cl+B0U=xVxYoY;YatnqZ}?D&hoAD8wz^_*J{(D zR49afB?7zIN7@xYAumYFKX26Lsli>>L3k83{Bf0|s#FB9#|z-Iob*NudT!4!P_lO$ zKsipCgc>!u1XMoe?8R^py|a7g`pPL!FK&aR_NEW8!7lE3_c^s$^NZ!m$m&@)wd)n9 zgl)?08;P-VP!r|?X3YGT-@OBLf}1_VH`^isyo1Uhcu;uwrqi7w`!#=}srF(`_6gjJ zuq;`E2hR94)FAY?_J&Lnn+JcFoL{ce%Rb6p6lK2ew-nJtXbr~_o7LKjJ*BrO{p2#k z40_p11vA5n>f&9Y5xeIr%AAqL$u~?hUa)Zl#-CLAOA+;X;Dd7BtcKQc%lIf^b5{~e z_tk?EbQCjq&AjyBl2Tx2?X2m_xKv0BG1ImabfA;=2OzT!(-xluAlsw!a7a$gQ7Q50(DdvwMVCv_&D7VvMYYpR1|#$jwrH1#z}CF z@>6tl-nes)bjw0`8zSF?KMM7QX2`zqA&wZ8$&D83b$fl~Ww_ylTjTwHg9ag{g5z=0Lgu>jmnOo=l(TSV4TeycDe% z1hs?yIP0Iqqk&Y3`9qcF+)b}G*qa0h;OAQM)R{ljk{&+HxQd75V7ly&^5AHj?j z$GrO`S+8F$*CJEa5qjBKjNqdIX|sdHcrU&?MH9-fPj=0oGUW^qU(@^DVR3(pX7A;K z>&ohs&`{%3eryb@*M6a7^|REz{zYv&tc%qqd-R zCW1e@M)hMV^Mj28@472TcySX`mKFshVWQVaQ@wB_T|}?F`OXG8OOPr%d!ldNh!f^l zVV%oLvK^f#$?KF8zL!yR8C8SlcwLK$t5!U}U+|2`9GXx^NT^!&;bh26>EPD4N9T_E z3)Cfi*|8E7JfEYz+D?DatF3XI5D~w_r}z5MqnCeToZq3ubX6np2PMDYtKPY0q!O1P zSMnWhGWrMVuVO!rc4^|et%lnR<|-Q0X|ADDbKA3E@sjfW(;;Vq9bLGJ>nnsRVs}YB z3Ae?4O#;ieKBLfAyiHGSRT;a&EzhG((b#%Ix!39$R6tf~znnS-_s+8@?`m&qyzZY2 ztwgh=aMwp)!lsGU(^M+y*yTghaba1Ayd0rkl9EuPwXOOOt^>U_;gB9Un z3X4CSN@4nI8?Kxum<#jR*4l8DdNwaRD$d~>usBnKpy8LoqC#_!5YCV1JklJiIK?e? zcFYPu0XcT1tcFHqr<4-Q*KjHER>Z-+YO){C7?Em)q9nGS77@D=yEVCm^5BZ6kGT9f z2ZF)d;QhX8v*(!Sn^hu1{*n{-hVV5Pp@7{re$;G$K@n>&n^bPCo?+dFMw$zhW}+*^ z^IUmSy2NimpuadvW_wPJgpo+(G~HW%lzz5)T7&K+c#i#r_K^X<9az($Qgl*tI zr2GmGza-EjQjFl-hoS;04$%If7|U_0HkV*a%jfUwK-?g}xI#6%KPbJ{Q*)W?hCj=& zqbDV8mh4x&7Cri1UUhM>vDO~VV1bO+Ka*`|iqOb5P{r_Bf@qZW%C9wJcKr|QN1Mw+ zW5itvxwp7SYCgslstbgbY2^%Xkw~@F#R@Wd9j?z36elzZn<_7MsxZ^F)p2QP z;q>$$Y+wM|u-$kal}vOm+SrgYlvt~EU4=SM{Z!`EirRDWB=(biHQp=E-=fJePD$gR znMrnMi7IH#4v6;KV&+hyE4bmG&{(Qnz7+MyMcw~yC#3`R#1=BVjMulYyBZIZJMc>W z-W#_IA0D6E_LbXs%KMEP-bne@G0N4ARDkr%AaYI=_7LoI-$CMq<^L)m+3O~BgfeQR z_f8od+D~hVvR;w_#8%sz3Q*AvY>N1@uB-Ii|6m8B3eXTPjlNSRljGG~SUt)fg0@7k;$b}o%BmM0kkGujfs3D$z*?v^`i_Bhb!)p> zTqb9uy!CEd3s{o0FIqdZbOUyu(g<(~R?9DVg?Ro_7E;N`TdRcYU(m+z>UM!Ypnxf(x30 z;=Vtxa!WmhRr(Va&`NUTi6y{x^WU?;?v(1+uQm$$Q!?-7o2>d>J#}GuZbk3(j;o%@ z-59n{Y3ns|uNf)>mg!)%}apfERZi$z*Og?mYpvveDKkB$2uzZW;xqY?h(Ai=v_73$w;GWpeH2*CQ`R1U-`fL#X*_ zo!xfn`9)dk`{tIP8ANbD>B~#?5`>LyNfs8F{B}m4D{Hz|54^ekYyW=k0d#P+_n2fN zy9Uu+>57A`iC%mryl^5l};+Cg{W<*jHUfSk;CNEl6P?MR493y4^ zo<}+3NlYC6=8cb}dHS9@qSw}%oThiZRa|s!njY3jC1$f+Vqc7a$KSF`Q0hC_BeUN= z>~Tk%i9tK0XU7F;MX*Vh^)}Oc{0|BbD^hy zL~b%CUV`Y@6>9#)D2Sd7$5JSCy1AV3L!P#k;U{*Q2wLMk6<@xn#7SKG&6)7MwX6zr z*lPDwP`^+H=leThqutiBvjVaWk(>B&rpoFWcw*Kc6#8)ZTtiN1JrOMC@e(2`qbQTE zZCRthoeeKX8UcV)9!0l8iRS^RufHjCoh7*}^o&Cv0(wV^9?Nq+@s5ahoT3idKK9ms@Ytv>J1BNL^idsh2?Dx8@`>(=j9d9s;H}X?a>JcH>OU2 z4UOHan=InSjCB}V`KH%A3+N{id-KbU>? z51b|A@1VrJsT8Vvtirno&-}zG()DO1_9ie$I_m>&DM9s1+iFspF6%SU+)5CoNR_&@ z9mvfPkyk?D}dWP^=ZnzBj8qRWSVJ*V6HRr0%ZPxQzh#9YBiQ7ogSI>9wzyI~N zMUau7fJeQrpL>L4n@BQ0{>H9H?+o+uYA(>NXLUx#-%yGJzv(PF?`FefYeXwTaU}F^WQ2^J=?)Zobb4#8!W8217jXc*QhTw3>=)J~mKYUn@qeSDt8ZT_Nr=9Z-uILWF*Wd?OaM7$CSUl!(n4&^(9RX%?k_ z2>NhwdLHqMv83El=`Q%fnjhPiUB8!ee;i zzPcHM=YNcT24kPxH@)9Vq=!!f9fht_B;K849gVHO3J(;)>4%;Z_Ett6LA2MaURzw@ zzXUVR)K-`3eA?&!r$-6HJjc7ajs=H6rSqO;s(?Z8!4^&UpsBDpdO_orN{uV#ZE$WT9G-jiujMO$9WK*qg$QNPM{P7`Bjo=p-{1$ri1-xuYziQA*lWmf5Z8406w zE&XR0>Rz02JB*pXyB|}eV_gobBW%jk&E0ED5U>a`srq(#?>^#8wbqY8m%JB*f@1y$ z#cjuIk$|cO{p4uTM2lx9JDx=?@Cq>9T77BUenZJ9(YpZ1u0WcLmi4qOp|Li;jDJG%Vy(Nwk!%AGB(Y}hflj6aN^a& z+IF<_1hw}nhLsn#!dB@edx7W29zL|a17SWZ0NkkGY*@5i3z#i?LK}EMyfcn5VtwNl zt5D^m5#%?8c#40t8r;zG8ZBF_ezA0Kn!iQ5@JjH2V_z^!p?;wb2G`*?fPi#KT!kRH zU#cd{ZXuCoOlm7}L5Dl(<$*({|DuTHHHK-{z#OTxrpWz>*0lM9Y2-^QpJ-QmVv*|r>AmDM`1Wn z)rdIhU?4UsEZbwtTX+|0RKkY$pov(o2o1AYc9URqFWu7CUE(c?fJau`xS8IW6}J3C z)9RWgYNzy33}H}IBsY7eJs#C6J!|uAOZ;^DQuNz_0P1G6!8%uqMsyR`v_avck)mE2 z%cJ1z{&Isvp8<)sXL_W-U0M?H?-KnYM3nkjYS7O5NfwE>=;*uiv()f2_wmSft+d5A z@U=UeLG5XV=vY^q)v`iz>V&}vr+AFLS3Xf1YwhNS&Fu{8ofujjaZUv%Z94L95>&{1Rli zw*nS-)S{*Mx^_`Yt=t$TPWEN)cGQQxev@6)ow0Tn%0R^Y8D6Ngt-V}%x=5xNpEzq< zI=L_UScfvRBpX^Ey`0p<8^Zf45{to}1IyA9ZF$XIt0|^uN0ZHW%_x)NsiC?hA(T-C#hpiNqDg+Mz#5Fe`1nUZkJ5S5ljDf~fk zVQ={H1h(?)!n?M<|1|#Z;?UYa!*@yo{*_B-&KcH{TvrTxWiDSG-W4x5{v!a9{AX3Q z9fvkV*U8ImCNF%9Np$mTPCDK?>nT0}bYlNP=4)@0s(ZD8l#cBC*_yVXLX3t2>FDqL zsX*4}X(gUnI8FmKnqJRhHCw9Q6o-zdzc(1mHV-;(+GokJ2G6~R72q~|vreyJ5UeGh zE>-~p_p|sn23?*%!oadH-#BZX2VA`Mp9Kb!44en!wA^ zqEdBBI@Ixe#1UGjXsTIY5<{n_Q|2RlrCifoTv)$S zfj>7|sKGEI@i86G=XrxkERSPy@t6awM8l%KUPyterKwG8Hu~3_x7eD6d=s`+{m3|D zYY~+YxGi*%$2m+R@SR?%@BYxB0|IV2`Y=&}AKf-a++O2j~>2^Q9pRZh!uJQfr@ zs=*N6d`CJ|BGO&WM=8WqJoPM9K&v>!>K*AA&a+7UcDEa0T7pbzT_qeu)F_;6^HN_2 zt&`&|UI`cAK$*#R74Z8X-?4KZE=!D`Z*Waag6CT=x+vC$rFOmnZR=kg@zj>hyF(BM z*q#u{BthNfrj2AC{5Rdqs&PvZ7eJ_q^$JAPKq~tC~||@rY1g2*aKU3SM%!Mch6gEhW7*?Vzp~Vt3tSHrHAYZK6YPf zPqu*szg(a|B(WhO^A*hx-pW9#_KD6!~oQkieKD14iQ{RpOQ1T?Md^#0jB z%ivSuw%D@A7IsZ!Mu%oLWn6L?DR?#$t|wY8XN6fC)D8SWNt_xJ$!fbi52-8Z$^zqo zA@cSF(!BzDZPGJy-suiyAkQ}6)TE9W+tE!#PbqkPK~_xqM3K13bwQEc=8{M)U9b64 zRMm$Dd~Z9l?xxqB2@49hZ9iUj4$-w}HIg+$t~dWsV$IJpD4MBHilpgT<2yK9O9c^m zLi8NdKD!+$tXc5iL42Dfh}MY z(JMYRbFr7ys2k`d6k6X@YY1n?WIz@c`P1!pe)>v2f{)H6=w*&icrl_B@K?aMR}cU_ z_VOU`Lw9T#UW13}nwNqZWoR9# zV&lYiD8mzW3TukM+C`%Jrz%L38E|PDO`(RVfms`Orc~0mIHY$1*-4~$oWk_s+>+v% zE7n(!sTpe9lseJa>R|#j0u@mF4)EoY;J1-i)tfZA{Ysq!w~JYQ%*$|jer0LVRJ+!* zG3M!2ff-d_*a6Gzev&psAx~XrZM-1sO_tjOHz#qOm3(1y8yIJTx;*YJtj>PV%HGu?JQ3!AYD`LgFK8iJsZ zKwORZ_`USu)U$Fs7KY6t77gm^^MVW?ZC#pE3uh69(Y>tA(V8T?b$QZ;1>a)?3YYfE z*6wO2R*n&h#pTh=c=@}RuVK@B$I!}~_Sy~|qcDRKc(`qUTkSaOthF6t7Cy5tFon%- z&F?H#dLw0JOA}P4b>X77k#7qygnzM4H&E>;D>^Vtw}tm!dR7Yf@4C9^!lyY!K|W}L z_6B#EB4xH&Yd0a~ZMM@cGy4d&1+~<6wuNPE{)Of`O3`JG3EOs31I@bq8^h@4W*g{Y zarsVz&L0#SXn72CIr%+H&2N$e3EMR9aGIKSap>ETaVXQ;1+(y=aF`9z6CG&7M+CYY zzK%Y$h;_D0Z9-WuL$!vgy#6Zr%UJ)NMf{M!?#lAVqV6OayKW4TFrAxw;jE$85TivlzXqSyL6&xu+h>CXj&73 zjB+t@>VZoDodg6rN0~Ei#G9~BJr7md5onzP^5V0C$)W z%R*XbqbYMr*dzBAc^FqINIfi;qfnDGVBp8j(UhsQUd~u7sw(o)$FY^CCF+N-*_7)h zAA0-gqprepy?yCb6%|nI2q>Oa=LaNI4>>NgOzEqK$d%<8)fp~x=5|*YCeHetNxz(n zNnF$mt93ajI-YVAo%(|U6G|HmIlRgm5ktyNt+jVOKX7Kyy>vr7aS=FqwSJCE%8$BU z;z?#s0Mdx*awg~RURQnM{d8H5S8*5JhQO2RB{1ycxC@uMv0ir&4uSxB*r{aPkNFP~ z==`=ZP0!96;W1I|VwZ($cVi3hHWDY^J8e+@((KKMSc7I^df&)z)y_*DR;ub4rX8Bz zGg#HVbXa}uawEUfy(&(8i^L6X_7*^_*=HevUSOFYlO71`+7Ys^SCXVz%M#$kO>~+B zhtm6kPJZSkZlS2Q37KE_qg>0BYzEEUM)uHXMP1%IFypLW?e5jSY4+vwoLVjLdA976Zj_6H z&~;6s@v|G>NIJu$FbNpzjnd&wgB^cxi%U4!fTHj=*rd0vEGiu4dU;}Gg?I3<0xYHY zRi;gH%rY-Tp@szqCzhqO61=alP@m0Vd1V~!E9QTD)_J9va(d^C(0Ud+q+>S5Br$)L zq8p!9f=ma2Loy6TdUIp(`)*h~N19V49j47??yOY6(&h$$kGhXK(g#iaPia$y%i;5k4@x!I8b51(jV&%WKIU_`|ygr*SdTLfydV zR6QFxo0smUESOF3U;4VEsb*?W<^hX>!~FGPd$l>D-0K>HoZ{#-=#+kZYU&l$uwn!S z_MIZv)Vxo~Fj%o!X3R*(xAJDw^d>;*r!RN>Fks+QLo4$&!o0~4vTD|Z%jszw&%*8sH;-6+gyhZY7m9;zO@ zu8bK0|34@#XMo416ZK=~^=Q=EcRmbES$XmsB zdG##HYjV^Vl$SNf!9@6$r3B>s<PwgNsT5kCmYV(u3&eL z4>*=H_OF9dDo1mLiFtX{f&qfu6ROUFMWNdq&%@xhSZHW%rNKBjYyQu&6Gj-UL!VmK zEKvx$PHINxv^%wUu6`c_1LUc5U$%6v3L>TS_lvwwC`h5bT-Ul4@~OsR4%KtqO&(j9 zJ!|8ZmnfAfWF~(R+u*UK3bSE5bKr!!;0&}XIRZ>2kFLMu>{7WzlXwSrYKfU5`@$e( z_uPwmcz6#tM$bn&)%HzqM?^txeW9%Ywj;AvG<<0ybCF;PXi1!MKJ+zRREqS*#-hB;9m6*58MBTT#e75?1$EI{Q9#_ zaICO@ezjEr#ljO>=f)>sgNa|Fx&a$}%hhC-QNnXs)g=`kB$%=xLPgr8E!@>FGmJy- z1=CdaEtaqv%E(c8my$V`7WG8CNOt;>PF^w4-hqdx5}2)?5^^f$f!-RmAmimsbB?(= zzOa=r;2j-KMwU53G+;(pF>h;}=HNzt`AB+=ldn5JGmX4Js2It(+f`plb*q&UX8cnfI z-(`Ie%t{&C7VDIFryFUAWnVs`L%)xw8FHXHA5f=A#b`6;v&g5>%^@6qghh=)2b7sx zUhk|Yz{bi*j%aH^1D0q-;R!h`=Mt<^%vv&V?WhP5KQr6mneTwgOE?0v=(GV#jo3BL zzSKBg7vp9`Hhn3z%#h-fmu8z_{5D|#0n+PrcVsZ5W5f10_{a%e=!ZsC6(r8tohd71 zsSUEX;&RvtXryY%N~S&4)#epUE}lD9af?_~DP?K$$NeXwXC!+WU`xuMbg}Xyqb+x# zrxol@iZnkTdngvJ0=SKy)P?N^6Wl~E)}D-ZuDtDiA(Ga4s{EN4rSn~byX&)-7y5xr z!!f8R=1>sYtrR3n(0vW{nQ>WI_mM@~67_w;SD&=X!fBmXn;9)%1a-GbMo81r`|a9w z)mlh{Yn1jDOsb9D`VqBy9}LrC5LSyJCYNbCZlPPcM@zqErUQjQbMw{r8FO>_9aB^L z4wAfpt>4YTMgseaO66n=J;!I`5{F19Qk=hvIONV%zC|C*5f?T*XG}6~Tk1q)#BeZi zs$=}QGrBP!B@gy#9ld`d5<`d=xF{C;{{I zfwf85S6;Y$zrI zf;6KpMW=KM>Dx5Ziwp*6VW?UQSk!xeP#pHYkNwj6gEDWh-&O2<eTZ zSwEm`-{n9>qiETt>rtHB^d9N?_Q8JxaQ~iy&l!L+UP2w^>B#%k)9~=z18{YVbaUo< zv<1B&Xl33TW->P=>AZ@TE=-QN6tdjQMYA$+#BGW)c{}#PWAVswk>go}dyl?kzB9(R zWTtq4d!t2vKl^K^=cwZ`u^32)w#pQj7a+&XUwMipuLP%;q}WaE|DnuWhtMcAQUwJp zu;<(+2*n{7Q1H(!UD!KKU0TBC_^-A2>TCt??P?nLpH1|Vs3T0MFCh7#V+#8I<>R!- z{IU0zBUEd=fMcEIDEt;;0*5o+VTK0o{3nlR+kUfjyo={GfIlddnF>#1f4_dn!207# zUUvYbE4ucAjMO(E0c$HfRaEP>?y5@J+?$UC&V)U7lM!>#30G-Xq;dpHMJIu{**aYf zI7MH!(E=nAUX}`hQG4e`X$p+2!9C;y^049BB+OTSM6<@%QqF-Eo)K?{T^roeevX9; zF9znC^XMWz^=rRrnG)WguSFeDw~udbpNAM@bwSuo67-Meg{}$QNc*1Xj%)VVA#JxJ z!vuqU!j2SU#-YPXh1Bx<}9~kLV&+EQFpEV+xCRb^ue`Omo zr%-mMU&&eYW4}G;>SDHVO|E|l2r6st0X2?{pCQo2(+hR0U;}|QmoIsFS}cbJzmxLx z;x_Xg2@5Bul^x+1Q61T`gN5}uUaH{XCKg#z`D(P9N8$_d51&H(I)cdhrq_+8 z@RsV^^yHtj$6&SQ^Guai6-v9)$tK1=Ed2;v_WS`vnG!$5W=~H}HS(Rj zWCNhd^Xn6ET7EB}K$>xd@{+FGTks8IE>)7HTY}N)x}x0QEVcHZ44)2BW>J1ceB1PJ z>lFu|J-Zvb>FuZOy&HSX$r^d`qxBp0F%9TgG=5$+mbAbU`HlNwY2>$&3|Rm3lIPY7 zi}{Rd6-#fHg)&ul3_Kp;p!~TZ131M8(=THQ8B4F0S6{4^Rq;Qd(d@#>0ffpeD5CUBl3CV&Pm6E2F{BMzzDPS zRps&Z-{`s<&ld|Vp*e3qZd^2jYB9w5CaCYwbqEolkOgNMdTd>!g@=^oEm1Pjf|Pz5 zxq1bb=bYcf*Kx?I=N0IcIgPKL?#IdG3hGE<>m#Y2KcCcx3o*Djmz-Y)W)~gBmkAknJG-Ehmc^Am>hhQ2e%WH@<<| z&~g0mJPm|_x5qV&zYC0|EZv|c_=x)~)pqw};h+(*)@>Rd@5=L|gI*qGxCERr(<4)A zlJb8xp@* zUhrVpDAt9w*q%_U?l15bS8eK5|rRk!0G#hg{amF^ed*<#7WtVGZmmUTFg>!5ku*Zsf#!j;d zjNA*}?EWwEUx3Fk^0k5ldBMn$(BovQmi7Xwdu+J1%-CD)7ln&s!kCVSLvQ=4orGX0zV_cq(xGg`rOZaX6OxBdUrIJX_G z5d4?#@xP4yy%Z}1bp>0I;dagU=5Cg(Q5EaC2d!H(_YAtp?ZzPu8~6!{<;Z=OtZTFL z_jkC15}B_WuK`erU&zguRGQ5!WY`*cy#Jiqi;0GYj*50&`E%2$B9tW)9AA)j{3=O>gfcAA$~Io=fe!!XpOtMKl#p*1GN-QKb?n`-8qr4-fkb3MvVpAgFLmSw?*E9qHw~LcwneDLQmU$x$1D9` zbS-3UBs!9_sjI(Kk+*;O{EPdyZ6sg+W&VE@i`kJhDsSMmj{ip|d{iKTe_OQ;^BdPE zqUT_rT_~er&JFA{40+uk(`VS{LSNR*|0On>h|u+%&xM9;BoV>uDgUOlfAgH1Lf`+C z-XKf=MfsYs^Nw`_&II)_v2KektsOgNvDeh$+W=@_LguCL-OUTqlkFe zGL6R`oG(0uW%e2JB)((yi=M8mk7iqBS z%f~s;7)>ZvLCjX=8=S3-=O!3b_$% zdD*ss0-dFz=pW$B*5q92GpkO1m{(Mr?dJ&PZG(y$-1=$Zl~5_1M58Y)IKK@#6oJ}S zPdhiopx%q;(Q@fiQ`5VYKeXa66qPRBBG0acpD+(wejtZM_i4+@Zp$rVFq_TcT4-3w z%4 z!64O2@D)`~lq!N{?Y%Y?P8)UbBiAFz*REych^)epLvpqDlf_m|_8)M=+x8=l8ZrK8 zLQS2u+<0lrqKS6HUvyW*B$R=hj!%+J|JZ*km!;Wc|1NX;>R$k*-+utH14w}ClVr*W zfaHCF5bL1ukYDTn`fGdGvpR-6ksy`)Il2eiNAdiW22P@%+u@Mn@s_+$xyrh_GTm8ST9}6B!g5MsPRw)YD-DIb(KYXlsPZd_`L%5U2&%ab5{>unX zQ$@hDQ`KY{EYeSXOURC$8p`%7w@Jp2h-^s%%xRn<$Y)X4)$?$2@~ zH0)-wy}Qvbe>V^~;1I2oFnO_iW!e7ZQrb<+0`I2`lj#yz3FAD&QM-x-DuzvpCEX_e zK@n#5e?`OY^_%-eG$9as$oW$$Lk&kb_xod=VeL2XsF6(yG^>(>nJNMEFhWs;t)umDI5xLmP3>w|?AO-ka?<%|wBTN-}E}cy-cferI|l zNU{&UVV4O?y$?ZJhx*JTr_i1C=&*znft-!aE4`P}puc}2 zii#r2**I~zWo@Dtjxt9PWA2*xU1U+Jtwoyh#rQ;IL~KQ@R^K-Sw$s*w0V*TGLj>^{ zrz%Fj;|Cl-^k3)tP~8%(ekl4QeFc`(m;vEskX-+R2KmYhsLs=?wdw>hxwDA}Y5 z=($vIpy@56)fNKn8~pfs`mU$hDiiZZcTp#t8Fd>j-vkU(mGs{E&aF)B9$q3nXTbRK zRE6eO3Nm)H(w3XwA?&Cm{(ZB*$x>eZtj&+t@tvQaSUq6MHwq8&LJo=&7S^0Q%i__wd864{k zwj<>#8zsXDdR@4W{bRaDB)v3up_|Ez@#i0uQ1{d_*x0x^ceB9B-txGpH$E|Y#^tXoEOc8<$ zm?zM)3)STJ@#wv-oTE-$^1lg zZZ24N6DpY*vxpO^5ip4sIxz<9aw7L5`;_>_H7H`!@2R_qy}X;=|0F{)jLM&@jgR)p zIE|p`N5wi(zNvf@2$9%pBxc2uC*4uq^hve0%4wj{&U8x|@DS|OAmlAD6o$Un{i)vX z0m`0OqoI6d&ZRSS=t}5FKG;-J%(H7Ly`-Y9OedU!^#_GTg)SC&Sgs)aEl13cZwKRf z=J8cwUVt)~@TWUoc1xgHsCyH^)mRovaF)$*17YX0Agga+-54s|up5`CF#U84+e@Qb z3;MK}rweAH#Pn`n(qOL$LUffqzin28mFNIqBK?3Bsv<8>A&cdzN^F;T=fbtEoLVa@ zWQF2ZqQ=9O2-ur)uE;{2S;dpb5>xG(T%NdjAKHEh{NeVJH)8O!NAuvU?u+Auod zWBe|6GU|Fyf0U-#ksxw~y^zn6q+S$a!+cTLyD_aw=x7kZ^G)bOVRzdQ&#_J@w0YAG z)QspnR3frEX4Z9mMoHk6)TuZB2Sq(zRQ?~V;5FW|m9QjKL8h_xSLAOLsf&>DzY^8e zDB>1SOFn6{e*c4lzrV^LJ(SyF{3-AsgX5aboO3&7&6@OP?c@r$gWkentgs5KX)NOB z+vnHZr^ti)=#17L@;2GO$)4E7+HSlzF|$h*^ljr6Bp37ZU0?UEMur}T(RnoO_SR4(+# zx?7kLj?eUKAuuFoCT|6fO?&&w5ztF zT>}&2_tG}WS+Sp@7Aiu zXC^TCIO408)Rzx7VYZyDUn+&UQ){csC2q;5IdUW?=r^AiOaB58R3_JNW?~72#sk|gJ=aeQNKy?H$DU@ucW#GB) zHT!BCWUB{10fytKJSIki2C~zRzThjv4x3SQ!sqCzm!%L zZ|Hy#0 zlRWrRI_iB1I5#l*m0rdVuTU)VSXX4nz^9)Wo4l3Dv^Hzi@xkOV7tut%{r%&ihyc_C5S zN>NSx*0=i~zy5DvC!bJ(8?pZ6-w#-%_2w3-kAfg4zl6FaiQUTXyoy~scn=5jVb;14 z8jJ`iFaZ<9Lk0b!>Gm|kCm)rq5Ry&?fWX3*ed!TDCjKB7m7UIyfA?btIYSf1YC$>C zk|l$x*v43EuX~ zubh%$Sa>HHnkc*T5Ywo3(#|b)=Nq*s^r$J#Usb^gcA<#4^71S(Mz7K0Ee1`PCWtIc zawS#d$Gk7qt4FOeude4nHY3Q%yVXkPlC&Rip^N(%ptdk|99?SlYW{h#sXK|?iT~C7 zP5d2)Jd4e-cDW|X^oF0g8{~`Z%v?)ccvCS4_p|u7vYC;x+iK*ut=s}+q2JG?ob3V| zXDi%Gj^DUHYj)09zY=|EBxiI=jdoQh!<|$~(LCih87f(z5WRbKeL(bSakbtoPDs7@AAJa#(O9Ung5dfhSQN z56N4^6uZkN%aLAL0_D!j)5kJoGam*jU7P&eSH^5MbqDy&SNGaOqk6E;x^^H4s!`+p ze9K+!*I46{y6dd~A-3G1Oh&zy-PMU6%JOy?km-bIHOrGm-Dvp(F}$B|=(yqUIZM!5 zaNE>D^Fm!`U-WR6&$;=3K36uUJ`EFV_`%S{ta7Tmp(JeHP10vP?!6Si{r9 zE>7K|riqo;a+P)!hxBTeY`c~7rrvi7@;%N75w~7XjNArt0*dO$I?4PtGwc2;jV53Z z`DP*UmEiRc9)`Z?B!!Z}K~T-#bzdrZI`s4igc7pm`;BEjRxm12@G&feiPjFd*hRPf zdSzkFvMm>d>Jc;M#J;j{y>%T^C<6Gh_^%mgMq6d@?)(yW=mu?VH=oe_35BBdg?giz ze=FD)+7kqp_6$e;3~)o%bea^kZ$4eX?_F8u$Yd*-JSb&-gs)P$`SAA3-j<)%>@m+^ zgII%uoXCLu(f2=-q*U-$SqyYU-Sv@pADl^?ljI4{3o#$E_XBrN9>`j~ z#S(_okg9P0gM8IhtQZ%J+~i{yTZA9VlqSD_(puA zlDiXzEGK#Cz|5=WWnG~WStV@nCim;^=k)hE5I@fGQ$E*-yaXHP@0$|Mj6OQOJE2WB z5ARFbg>w9=HU`Bs@YgND1nnEq+ht0J<*?FRe~Y(@x6>|S${T7 z)pirQ`z(Uctltg30WL`nJ~kuO24|OIJj2aLzENqEX*UKPD`GOkWIb3oGfW8SMn#B$<`;X+(GRjvnrapEy3%b)&0J?a|zj!k<}qrfeNr9k=1(l;mr zd5kt0@#saf2$!m$>81azVB(IYjUXX#!E`d-OB2 zdDSB{#DDGG;@7n-U(h|)?hwtN7aiuP?OTHazPMT0sI7>Nh*WOf+%?1h>4L;ourRUv z_S$)sr-PQ$N9Apzs@FnT2-}658NxC={LEb}l$^VzLiJ_KsAi?Y7!7z!TH3NLN5-ii zKuofW#d|gwMEX^hw+0Z(tCBDx-X#1~>*;JbUAPdEbpnnHnSkJ=wnkqrmcR|pCs4jr z@~PkzFCyaQ3j0S4h)|#hLkMeYy6HfVZR(Z(gcWsfT6ydQ3QXNd^i-`dxcac6`4>)$ zlA==4Pb0uI2Eb0I_ww*x#$l=cUb%tJTEL3Z{7-0In8kqJ=xq+G-YJ*qxS5EQl>-wg zXD(t~fxRD(^gRpzXYaZaoBUM`mMLC*Mm`+TFAqN-O`CmfNGax zAgd+CV%>VK^(bu!dXrs~=z1~^Wz~M5F*~U*mG*6=+#9RKE;))YtMW)1Bw}#j8u}y0 z_*X8x_KT|tf7C7xo8mDo;W0K=lK+wp%TD#;*zZ535)ae)IBUaup28*YsNH9Exr1w5 zxDp2AuhLYoe4*$Wxi4L<0e@lqdraGLa+tJhB~M`Dl48_oreM*kElqweXP-10yzO7O zkLB=US3KhOenKE5SVfzi(}$(J?|xT2vi3Cr(N*p#LsZ{)uIbKHHq#^NTH~Jc!D0`R zIF>L2INN8K*eeTHvxYbXzojuu>~@twPwWA|*UCsAzVR`5LKP7UpKr)}d6WBsib1N; zy_6A)Ooz_7XZ|Cmgh@8yPZjzX)}-G0W&g+f5Yk-Cjx@2`!@K|KGG7*+cuDSeJzc95 zx-uhB^zx+C9~1n$wtwBu5jp5IOgu94>W~IHS(jehFEqy7{1{;l8smq(6!s4pC*@z; zlK!Xwt{}w_oC^OlLrYRB)^R;>3O1Rxi-_ zOImUqx6ZkFUCDgU@vN2g%j8}Z=v*0)%|EM?z1cdzEIc(8M5R*r@Sd~nQ_3l)$SP5) zwCxE|9BSSqe#a=dc=4A~3MitXF~FrI=@qW^^KSHJP`6wd&el9{v7q<$g6-Fz*~3@Z zpaW(5%(YcZ`*VZ*B+9Fv$Q~QjdLoP&-qw@&Q1LpQ~uSOHQv3XF1xA^unk+I&_h#ccSKCuceFn= z+hc^FT&zbb;-jdCs$hbJ}>4C{V3dmVb3?yW}n%<6F(K5C|wbP@{~$~l+r3j;(7S*rrT`U&^v zOk{hO$Lmn=m=3uPTE)I6UbvfKgJp-%Lme>Nu9u>mPY{-s88cUUFDf|G*)bn&Uubv@ z+jHs@l19<(=nA_!dN7scL#fj_(^AJ+;*Xr{=Lh7_=$@x-Ws8XVQGP!a$RfaDmv&UE zsa>q#Sd!N=({PgHd#2SREp*i?)8M>#sAM#ZOoCF&)k5b_rqtxA)GaUpm*VI4eEysx zbHam;-X%O~H*r#IfY_Iv#oyo0%Ad}GA{K-chr{9-`#w1RQzF+oVA}jSJNKY9Zl7)U zt+>ZTQczoorkJ6~Q!0|2TR%tZEz&mwi=W5|lQ0#G&pu40E&{&zqf=ya( z45>TpGMF^b5zDhnRa}Za;8j|CiO3)FmGMFLep#RJeleUh8jgXl>q*e7Awp|K`*DZws!zDe^7d4Vw5*yWa&#o`S z6J=?EuyGQ5moRys6RzPRvL!vG!BVex@{ z_XGiw7K%poBwsw-%*9KyPt7jfzn}Ql>tEtCGv|h+@aIppp_l_tt|^ zWrXxT*DYNd^_R$|Kv%fRc}cuov-W4swn;bJdJ5JpZc=2aEl&ORCk)x*X^q*s<7Yq> z_pLQGou&Cyu0(xO#!;9Rd}Jr&c4|>nq#2foo__MFl=+$Vz0SI)tMC2KofqrQ5Tcc4 zC3BpfW`I}BlH6m=wcPfVL_20rn`iW#$9<#Btob$n20=!hx06mz+-m3l-X?0%U3JJD zXVC>P=Zo>{!CNQkMPz*q9s6>|z=V4X)A^8()~SXKj7#Z=%UJTKI+Z2SEBdGs<^}h{ zSoA9HJIJ1PF{ga7I}^*g=m870a)z)-nMUN>ysuH8zvhvAIf@y21&62+24r0tkGAp# z#;9i1>N5WrS+ZYa3aIFYXR}hWTC6WppHP><-|?C85ZHzrD}u2R5qh9rQ5Mz!cJ6wC zLf&iT6#BCedxZC6)J1)F1lqi$CC>N;iOfjb7UAKbtQrrvny{HrOyx^=gLMnONMP1$Lc0O)Qg*g}7E}5R49J;K_+ejf=Xn>UrRuGP%Udnp%>a(%I^Nt#6O?CWK7GHeC@G{?#@bJnKwjL5%FXByN%d>qa1;qgn?oB{1V{aOFJc7_qsJ+Q|I{pRJ6T z(P+|2@o2wr+deONbd=QnObzn8&aE9Olda!iRlV(oqkPDB?^Y&P+O<08`-oY1pAMpt zbHIw^Q-v7wyZBapFBwLL6Orq-Bkw9R#SZYS8KrKq9ix6wBl6LP0%5AqH zKxJ)1d_m|L8flkcNf^G=x4FekFwm|$$uI(JBS>Dts6BmW?!s%&JDCbrcS`A2*mmJc z|0>ikNc+Obuw>iX8ugQI5$mhN(dOjSxHQH-&UlCD$O3ry}xDZuF@R8i1tYNz4)Q{FC575?fhQD*s~-3))j3k1m@^y)7QZFw;Ds zo3~l_8(<~<6G75_#4V+O1VTo|p+K<)!qX z^`p?1ZzOzinvldsD<$uRrJZz&oQqrh2Kj*5QM+M#Y|gZ8EYsqgZ$nvNby@Y`VQW#s z`s7nuo~p*_!C$xv4-dI>OST=y=BA3X&|H5U?w4)viG+Q`EGwva-Z589G7u`F^Qw$< zS4lrorSiG-f1Gf;T!|omh(P8avCNzu<5|1JtQ+<$x2|uQ08ESdK0#qaEeWQ3g1oDaf5qvX;eN%P=>0TN<3HZI zUQS?|)JzE!DH-M4_J~)(n&BaR8CY%ADPv=q2{!O>b=Vgn=<4uUIJhm~Uwp;+dHK`Y zzd5_CRcNzBO780jwV*SpM|H(Ahs@Pu$zUxzu~6~<2^Z7rg(7@6^){zQ1;Tp_TBB(r zn^p&S{AVh{g0!vh3|S7Uyt!1{2XxS1^PiqN1p4$oG&nA0C{-vFdKQLOQh6B{^cWnk zs%}D@eRA5Xk-pK=gEdJmxWq$u6TubfT9l~h&S$z2m$E^V#w;HWA*03C!kRSj;r)~r zk2Jqz8tnBc2KU>`LBxJgVhw~V{&Q_h04vGMezaVVmGbPPDtwjzm96T7)kum3 z;`KQ=Kd>~XalJ2GuGB`l{@xn4yqAJJ*2s%Cy#;|pxRk}u!>wFXh-U+{&d8%gV!+`}exuFTXHY zWaBT}TG%^saVK+6MF<3k&jzHlDI+M?nB?CuM29Lh&9K7ek_0?KLl#mo8D=r4AMd9~ z$9itY4;@37|JVVTvFcRs=4~R0)8S6=slqZNOTjP9WXWrRFZhyO7Vt^K{%y0G-DfIi zsEv&q<@Zb>W0o4Eh>RU@YBB8C-Y7Sk%}XA1?q9K+>jh%QzIdJRx^A&90xe&*q(C*c;aX87Zqb~-oxX`@O015+^d zpRBiYU#sGsm$Ho3BRX+N<5wFj3lYB}>-b^;>v0Q>h|4I|!s;2$28RzivK~_p*K+K6 z_aH<`;g3|(qxr%T2fPk$-Td{iadawBC5`*4Hb`ZwSP#EN(S{f_=T@#mC*LP6qL-b{ zpue{#VQ;bSvrLOS%73j!dG3SBmrx(=T2ZaAgCELn>}%$?r>v6dyMH zGg{2DC{Cm(-EXG&SWZw2TT#*Vt4Os9&3m<)OWm@7jx0q1o=zEs;XS$@&=`!Pk#!M& zqimdvMN`4{13=LULXDKxeN+N=F8=#dH$W*n_hCCt4(iV^o=65zE`qt+0UvYT#`_>z zANDD$^kX1zHH#Sk@0_WT7G$z7tyGxNQ+vIG+iyf?H^srqx6Ad&?`726i}kF2OgQR9 zI!ucHP-o@V^dV4B4k1`Ggr^C~o@WF{pJZEHbh{{Vab;pW&p4>j*ZInb3XRd|dZY}N z+7jg!L{A|1CamC}>JyAGdqCR?_I@h`()vq#=gTy$pYQnc@1vpnBd+YQd8D;XS|BW#K&_uFWIlSx!De>ky z8x>q>8%qvzXQ3i&p=SI{H`o5Pm76$7P+K8*oDAP%$u^U#5o)V#E}bM^jd#8j)GMAO zoy-c42UMJAyk@E-MxXBYiqG{7_TWw#T(NHCRl?QUBVuUB$^RkHh?NGpQ#pyPd;yf! z3J%MtGtyK1!fb%guw^E|EUrv0;21XYEc|LveCm24IGD2K%Nzy~F%VzyZ@bGdBk?nJGHIXe73kPFoWg$^m-A3~wyC_(mb-#hzg)pw9=P3vunEK56=#@ozph%J zx4MKoBMk<19sJ+4b;t=zbDH0az;~vf-J9=!Pi^G5Qu8N?2l-T< zC#us#)ym2VK}BPg+nb)-U_d3c1MLL>bKv?`0=7%;A; z@gQc=LF7Ccbehs=KKK#cgBHRdl;}K`*&o*mdXG53K%Ut#7u5(t(h>|#xAzkg8~iikoWW2YGnw|ywkrdEH1mbV3>O1H21 zHrq-tQ8WG+qrsyB78~Zy@IM@J{v~xFib=uIIgV>icg)Gqc3@rGBO(zL>Zxq(ia+%q=pHD_%kj92%pVN^?aUppNB`fiMG8+l`buct#Fjqw%3A zNngfcAviw2pCZ;Kd~m9hhhs0rif=2G6cj-TU{Yr*fhJeMM>T!;+GP28GgORseJEQk zOCPrZ^-u8R*(43(DIX1Wb|Y$WeY*|ZCbwPmE{|1`hJ2~ZAD1$9$e&R!b97%egJg*Y zraR9(bBnY!Eotf3*=L5KtUu-p?=4Ot>|3 zS!=NOd(zGHr`?LH`Q+!=%{-06l0Wnz%S z=v;AE{OA995RhlU$bOFCKCTp=6?*#>ru&xE8ASRykz~*7qQam-+VLBUm=RbOtW+N{ zDCqdJ;;l+^KhL+yA=kaKMlVLCDkn&YRk+dUH4nofQ>vncQijklkyx&!UTbeQ}`$K2dqeV z@Dp=!7~MUetqZV-Zz4As7wpOAsKYJuyE(GXmx3FV)$@IcIE|QTqP07zy8++GKE}$S z5tXw|1}syO3g0iQ=q``t;KKTp_$NR^FTodf``^R^&#&E_-4a-ZG$ES|OJE1^t_DD) zebX;J_j!c4TiTWHcSO{T$F;-Ggwftu@X+m$X*cEmo6LQ->i!|qUzGcnyoR$A$fBQ7 zI97bol(UamTczKfeZLcJ-onj}1(9~uT&4~J*&guQa<|yyW5GB*FIp;(SL;tVTDnyy+iTEtkGXM z7S-ElhoSqn4g~6}h%tik8M6MotgAzBM0VxuRNUzvSQ)K*n$L7PR(PT2g^6P6LZ;6! zAr6)>tG^m#yj7TL?0WmPS_`ny6E-?uVE`D;I#ZicFupW?nKmDy>R36USU7F;>uMgQ zu)o{{*P6xF<^TqH5~%Cc5j6CT-tUh-s~X&tFM16iW0ac1JlD%}S4B`AOOMJ(i1R(_omO8<)BTb(3^v7k47! zvZ5eo=~u}!|7-^kZ)q)#J$L-a;%#XuE8mga7t6%ZC1Y+&_1N^Gd*)YqFh-V*`c>2rr%>v5zb`09U`pT1`HdhEI zn4AOV^80x(GryOnn}rzTi>b4Xc5mLOD|Eo5RU^YKrY5VlZdCHoNuJ+P^sQxCXX!Yi14Q99HO zf<>Cl*hIQQj(aXRo>mfW_WoT}Jt1+Q4~R{}jNfLN2Ds@NN+TJ$jBA=Dxih&XP4Jl} z!Gz*?X4Qti^t9Zx_8qzE%U4#J%g?+_?tp&oBr;ApRt6h)%PQ8L!oDD+J*jux3<>zX zZ+T^Uae~5l-ozhgs@;9xQdzfB)LMer3ksR3qQd2aztg@M<2~J_x11j6r zwaR|%TB+)U&8j%04on-U%+&B2`N7&Q&nKW?<00&4ctjD$&WM<~TM(dfkZhe5x(#{_^kFGCi@ZpU&0!T4t4i0#D&XAm#%k z$k#n@Jp;vhXo)Ap_-wZ6o(D0dTJyb_>Ji|YnzZHIYw+?@D}M3;?1YicFpE8&!m7#Wu$L@}( zoC*3hHrZ$^9WG%?Np`7@SxY^J9c2ax+gcrhi^sEfLWA1^y}2epaAv{T%8zBvwf`@h zZq!s5n?aM6r5W9{R`F5YHNF)$zy4kD@`r517x;-XJ~p*pypb))G2kL79+;cx9o~}n zZCSDz{s+TSm}m=Bb3O2DNi7js!V8Fb0^q%r>zGBD`Q4ti9FaJLK>sMPt=OBVz^#-V zZV|iw%mpX`XYCA{M$BJq%0aPeou}~kaJ42hC23_h*9#4stfu0) zPYOuK#9uVwl|uoH9e4)I6+C4)S%_G-6{bz$3|kPk>=v?X!Tka@gYuoyDJ zlR)gKE{j(OU1{1cc+|1T5De;9nJzJ}$4b&xD9FT@Q{Ak48#=F{KZ|1QFM;M2QE}ru zsaN>nzzOK_RFW|&)>@W_@e@jIkWe|TnB2F5UGRc~C+7bTJp+TXs13-xS^5sFTO+Y3 zsa0FVb9HMEAJjugs$fkD^b}bl*IT9MWC)nfm6&$?5&>05_>3}`7i6`CG&A?HFM(S6 z@G2b0#(84?gONCy9kI}g8ddQHT6yE{$~i&%gVtu^T%D&KvorGZyGbXjG?|88X$7jG z9lGdQ&1w}AI0`iIg#nI++5*Ee-J6ej@!8+hmXV?D#>i&Uw zCM=pNC;4vGCp0Y^)dPr6ByBXZ7Z@N2gXGsL%AncVqLCTSIRjfR?ium5FVXh~MMyJi z=rB3L8o`5!Y|*JKhrfg_b1iyZ>S%>H)nLqU)c70_$3v(JH9EyTU2gA4~NPg!T3RB6b1^%`J<| z>PAU0(2g>H?a+4!J8OZM`w+~3?kE=c9ARdb=-XwmBwFF)F|tl(@NJ&afWd!i)O}eE z?-_{%>%}$kC6)x=ni4p5T0}F&5bC2b5pP-M4PrRzmLL<@F7i(AGb`XqvE6v}500KI zZ^XDy^2)TK$^f}b@i#rQha;D+{$k_Ph7odj!{$p+Qr8X1P9p4t5?_^UOC2H9Q3Bx8B+sC^Yg$mMp5RvzFL$ zZ>C(Sw7I0%M0N-V#Hb_bmMCwe2mH(<5XpnaFQNXl@JfQ1hpUHYZz=W`zpSX0{rc*l zZQGGwI#10??^QYgnWxSm*lz6H%98CVxWbw(d9zkb5vO!zhSGh&&+0?20p)QV-DXoTP+~c6OI%e|mY}^IPWBZ+XH&{zdS1q2M zI0ky5!A0cB=mz`^IV4Px6!UMVcW*c~toBc8=wv@DN1=IuzKeU8LqBER{26l>a_glNmtO($BV6*~Rfd=-OmI z+nL^rIUuQ;Y2_^&3>Nh)GHfY82OF+SGh{k9Zbx!bP3hA5*e<>Jbm<0;*7VH#effT8%EP`owyP;wddA z@hiefF8vY=PS`P_-%BSy0lz2|natbRJXcDE&-O4b0T{en3pc zJ&AhY!N=j8d(ZtiR<_fYhKfy&IWepOg5Z9z^TB7hM=NXgMEs>$Fe;UC0h++fN@%pM zFQ~j6G<9SA!SKW-pi&}dQ;f^mrAq$xvnkW^M*jsm17$$P0^5x_xtMr-Qilomd zvt~I*$en50#2$jGF3{(}44*QX=a8qf6N9U}I_X3Th)%BVR%pi|G4NnO$xUhdp@?VQ zMO^lK$jnt76Oj|FN_DR0Q^;VP^)sT+W`yj{QKMeyT4&IRjcHgycfIIP@Y9EEl1bw{ z<3DuXum``f7100-ftM%Rwe9xSZucu+ep`}EK(&3jys{mzVNu0;>eo$=u}yW4LKOuy zcEOieu=JvlCl>LcdF70d0I;t>oJIu$j{-ILRJk)Ul16EBgvl`@yL>f4O=H)Y{GQo>UtsQ*jaSrs#$2QwFc|J9qmooBF{pl;jGlR#pY z2%gHL0%-C_s?=b5IN}E+#rsCxz!S+et!-faQtCqF#<0y{Iy3Fp`*y#dHLdBa9Y#4a zYpD6xDNneV*+Z-n7R0A0LuM_|;=sdz0ClC(t!%4&5v-gnkukq;N4K}9*3Z9fTD3i1 zGOBv90+h2Ev=*&qi@7F5XT;F9cfK1|aRZnOblFNiY1f0Fly=(V+gGTH2K z0PzevgtT_G6E)Kk?f$}X`9?D0tu(dh0G-a8(9u%Oo5 zPcBU@-X>wxB?c;nYAObLC8=D?AkT`E;bSAhIjMo@QJmD|5Mi4zL`*5Q8SZ|}k5bCY z%4$7kq4-q!P#cm^d>%|mwHY1^CQ~Ui9JQX%e5k3^e|FXpk?;PMOV1DaR~1$a4QC@S z1dc!=xhS~E%IREoH10eS*@P%DBxVTzEq>G9u|61ENuDDAsTXE0PGB`0<5Iyf9mC9p^?BSvcdaLHPL?^ z#KJBF!-)Pz5~{?7nl};Sg+aQLveN|`Y3YM44_r)h@&Hhhj!6aRjH2}E!u04*$cor8 zHVmE5iUULAzkLG_j{rmFzj*@(2SexMQp2G6rp`D43Hh~?7gXIGo0sBhCjUdZ9tG-+~|DHB;=cGa~6};X`iJv&8aV z?wy|MlVVTjd2+VjA*){^?dw(UZ3;}DFMZk-J7xU~r(pc3_!q7=rSsgJ<+c4!?g{&r z--I77qo`+Rc+xdz?uohM^^o73=Id1MO){+BU$~}MdcTEN>ev2fIU>1=KcS9ouk^N0 ziv~XPmv}B-oe`N&#(mXa+w1Rg`>Orw7`Q{|Z@GOB)iqn1FL7IbQ+{~4XMO;=6+eI_jIdl70q$XYfrDn_GKd0~ibz`l1&l&dg7Y;Du)ft}fGQQ=v=m)r4?}Od)f5;O%?F{Gf zxxW-U>Wrv3|L^)2&i+|~zvEw_JXj&dORJ?7eZ{3(+OF&z$DVN%sSc=u-xjk4Q8}64Q+t)$k zCzuuUEbe9SX-4c^DR&sdcwI~?T{YFYXm{?Kv7RWm11Kh35_ggYlgeKdtzQQ-uf`Yl z=iOjAd(O`@o&`5Lv0NfwA1azSJHkhOL5sPKn6cLVPdLsv}sRT(VFd7K{# zEB4RzT&we>o}Na&%@izN`zK(>`vL6x-qhEJ8y_(1%k{C~rn7h3{u!82F8PJc{`HT` zr&Tet^mHQq>RPLoS&_++sc0!bU(VcOWzjXwBf+0X{|h&f6fAs)jaSgnrwx8o=I^#w5j84~CGotcF*tAx zcaUw|Ic7)vF5);>Qv5UJIpRohpm;^WAt!}$TaVrW)Yx}JCN-;hS1dyEisi#TEjH9) z;~>_v_RjOe5X_&s<`wl-DQIo%ooR!*jjZ%}srTs=NmdN;&7VVlP<5VJCG^Vp&LJ zO<&tgt5M2l)(PlL{nag~PHb$$0J=X_Zcrnh^#~i-beO|!PNSHH4tn!%=Q9<`D$fhV z@-~73Dk;WAgpXvMzr_M>@8YT#HOjF*V{hO9x4u?3M}LiZ44+}I`-aOCA`_Rbc#h4i zzI%~c z_C^dm7+-ZhTY%qYI4ju75K>U88`_dC8*95=c3j*F_K1xHp!j^d*`5qcq=<)eyQP=b zrKh>xVpmoQd7RIG=d3Am<`#8I(g^fe$=@rmK44DgL#pB6qVbdZLEmn`ODSf>^OVL3+r65_|3aV>`UztErU)qJ^d7tHB;vwt~XlylcyiHM{G{L zl|J4porskBL?rT#tSunk$yf*~w}!8DN@{n!BYk=_7_KA45Zc*o{4Ao# zJ0H<|Utusd}T$TV`xcPz_IMW_<(temKV$xwJ3u-5Dp%$C{kG;6@Erfr(SdsF=Z#N3dE2T33rUl5 zkXRz3QOD~RH{?KvnhvL_)E2X{Qf8trcub(xH)wQGVi=#=DHurHqGe;Ag_rP7cvX7P z!i~hjR9EN6hfYbgA-MtqknH@C;Rmk)(`s@WB!jS#&m>G8FEoyPEH*^A!${kqEh2AR zrHPzbGrag?sR_W>WaMTxI+x#WVGbLe{eGLBnh#18EYoH@Lf%21V1zY|WNh7nBVKEtMwoXr zj7EOhau=GXQdc5bt)^43P>>%tsVTSJS5_K%mI;FLQ$vB5@YQ4VQ!lD`gJ+LtgwnSn zY#tIoovet6c%yXF%%4kX8q2X7wItgQI#r%{FYM2b#eSFTiZ?@&wb!>kI_rY3#$61$ z;+_~3A_9^e{L(20*Zfg75UNXg8tW{0~ z{E@dUO{GL#$m#BoU3-l}=pn5F&2r@JZZ&At2Ha5kl@7UbYqvGt9^bIzha?-^t+|@g zm@1C+FNK&GSDEC`@7a!8ve1!4w(ses$PDK5>*$%+)W3zc{j6QK{~(v@7V6FD2h0(n z-1!TaaO3wdaQSrRBemxH;Br;hzfvPSR+7)Eg4 zL4uV(E{8v|1djYlG~IvkM2Y>S<|647ld&ZX?d_rdW8vY+>v!F~``s^0B7T*C@T{B5dk;ieTEJX_IAH2?9b+L=w2UVSk zSG1a-GtqJ5nx}l0_F;~eTPmsPT*Z{_@SUM^uA>xAFX@p&K0Y2`Ybq=A&MC)wA9St* zk%rZqH_GtX^Wy1@jS3m2ld_<>Uw$jfAA$G@zXnhd`V@~5$%OzR30{ip;{Ijf++(D$3AA-aL%=60S+`%nc}*0MhtV&!xVjB#rv zQXb~8q9v^l>iJS|?42LmbWjB3J}o1?8*zjG>E$GTie!H1keL=JP4ztN<&0gAs3U+B zi-dICgDIFs6zwQR5nz3YDf+q9kj$VoLb5e{Q(ao{5w9~quy;0v>=73Anws+E{+W;b zard60+zU2^`}n*tD-U67_2UT!fx4;t8XpN_eQFVwbJ$qIw z{vQCIKw-a`V^3+)9a}7{3*d(R1W;96RJIb|F;!+r*NK1zbB#*2H%(q^K4L*$NCLIB zt|L^N<}3$uk@Lj&uA6_5>Z}nQU2SGh$`ES;vjUyl8Eo zsQ_56DPwEMg@&4TU{@-?tU2)Rv0Y~61>9hKf7!@VAy!z%*rKt zYtUuO^kv8SKgW;aO8zhYxA-VpT--eUORtCTmTcXnPJIU0?{F=a)LyVLA4<-V!o0(A zvemp2rN(9Fq_W|&q&bQ`p^5G2nQm#^M0pVrY&pzLZe`rHdEE@vJ!R|(k~1b+{6emYr)YbwH+AgJfZ~#R8m(hJ8 zzV<$6B+)KVLOC8|D34dHz?)Vl)~8Z4hqs|E1&0uhoA-`d1YBnfcjMBadsQLtPF6JEQniB;{9*`0FM6v0$hDKw>RASzOV0!{I5o)<)P}Tl*-O=DaWDP znC@>;BjYn@ERe-?jOz#rH98nd-F2Df0TZDrQn~i&I!3T>b9J8Z!fIw!5+Kx zm#!ZQ9NZ-#IlB7C$>wn=#2Dmj#7H1%<#EtOV2@Z6YpKxF?-P*rCFsH8J4C0Wxb(@v zA4DLzTSNk8EqLdGWIbg%Y+xqW4kkHb zQC4Q`*P@IK*^Jz%VI~6s-e6zT(-j8h-iDY1F=fY6m`8q^fp`)TuF!P27R%Bwwq;s%UI9@kDZu2)A+E2}*3N8blDhnIe zQ7s;-{{RdA7wLcbE?mFi$SUgizw%$FK5Tp6SJZv;rVOPKh8d9`LWyup>Sr02#d8jn z1#5ns%_S7(V=FKxEX<$}7dJCDU~8_Ty$OIux?)mfS6G8I!FZJrtHrNfWmy8zJ7tTG zVIXyA&}f!j+W7wfvhEUTWF&Za%CE2RLU{neQ#W%@m|$A_=_pAPaGZA!ZLV zHRgjrV6|CynOk#TN6Z@_U)3=HDDf?ZzXLuNJ(w6n|Zfyp)TOqmpA_a3YL`q%k(ro;q2;IAbQ!p&@%|s&kU8`puR%t@kAV6IB$o< zSk(Cmh&w)Vc96NPbw&o zRLNCS=CF=GXs&c@%)ZC1Pj}an%k2d(c;78Ey%)dOw8}(ORvcZu47l+#wtEB!HO|8N zR6o=qg!vF?C=&kwVWhBnBel&KKx=*0&TG~Wy=`kp~kXg!MpxMx*DldOMmS7KNOA?Ar%QKKh3L*7N*{i1kpS(rq@>(&l|TD#^a zhR1om-Qp%+=!KkpY59~!m|cc6)nmdh2Tt5ekMG4|WY+dg9kZg|AG}ugGu4z(-YqjM za+O(1mS9L5MQZ!OS%cyPTptr=jiu&yUl(U`G_1`k@$}f6+Id_V6M|-CaI3&zD#r0-$El7YI14oF zWw_8Xz^^7hOX~+{Mj#sdC-#A>JflJlcM`=-V#@39A4~ZQ>qu1u@t^F73UI|8e`+h> zk8LJ6`H2d(%ES19ROWrg`!j#@`Ndam5T3n3D6}h7Tpbd$0Rza zse})CaQ3EoH9$S){;Dp|A$f`;#LQPa)JH?$FI(4075f+Wm$m}tvAc0C==@TL3&_9J z64T{{>O!$rjcY!^GaklRGY60T5V$;bm0zuM7Ta72UlE+IYAmWd0$IrV75zw1FQO9g zQ@q{iwH|` zX9+JICAx=fmHj0q;-|UmQKh7^0D5+-t;76gF+B5e&!kVO`{p`3UZk<((1%sy`(sl8 za~3H~?mDjy;A)N%Qjw;!$x*T0pJ`V@cU%Z-%&GG$n`9;Fs?!1hcs4wpOUvGY0fsFp z7;AuEy~h^F?$gC+i9=wjw0+j2sNq`^!33o+btVdnn)aEo^9oDlunWhWN)FB+G;c() z3-+1B#aZBjUfY17Wi1EQzVOI+8eVc`i^V}%3;B!m4KtX-++h0(Gu?mE8rMZ$eq|@w*5ky*T~oBbvPE@b$amun55=$H;}3;RH2Zy^mitRRt;%TaRm zX?S*CusLYI_YvUCH2I4{YV;o4gMy{dIq#jyM~AB~ruPqG)Zbq02W%K&U0Z^%_DcLf z7t4Bzj^`C;<|&A37jLVs@~wg(a8o(fb>PIJ)<78gQMaO9S z%}v$Jt}~_FDBamF`k42TU!f_x(l0*}r*~)fqDA80?oAfz{i-iNwCKjz_a*s>X?{O) zbZOOpa+3ZVeW%x<5wAl}QZav_7@pvwCM8D6YJh!Hj< zsnFI1H@^cuW9W;YX;>e;%*cE?zpC%dK01yAmF!JrcbtaM=DzVWLYsAQ;QPS-AKe*t znVRX5L1g~`aT4FHsmd`d925( zALt$8#eWmZ`!(P9{Lfwb)EqNETk8E!SSah%xIz+yQp22<4~VLr2Q>X-h6Lwu%j4@h z({VtnjPpA}nS0_lK_in(gbDPu1V~_y6&ia(1nSL4k?0pP1ivRd!eJed<8zXxD!N_N zu@WV$%eq_Qj6c`y9=I_N%5}wB9s=TCfl4`^@{YvQ9BovfIPzjrscBSI=ZSKc7loZ? zNmYPR+^de=6hO0$XSfv(l8X+Mf*jYp%IX;X}r!Y3_jACSyh=nLmsq6 z1KC#to(@WT-R2Cnt)r!LcTp7Wb*=D@CVJJ?==(4X5DNQ82`IO2>;-+%0g-!BHLOhB z8%2Wp$DaCWzV}<0wVmGPi_Lt*jo3IkbY|89Qy?;UeB_P_IE(jKD51LSIfM&E}hv$U(*i|%H9~imNt&)@C>zK^$*;Q z*p5iUgS1swOLqtvjy((|&Ols%FSHSsDHc*2a+1VmF}M(}#Lwu75CwgQ%QJ0PE94$& zxM==ImK_eAPWusPXacMKJoiH|h|;3pTlSTJtkq|$qS>jAQj|7q_kVML#GzU(bidkM z%-p?8G?*fw%R$&DPf>8~ZINdzEDGalb&k@~M!V4yQ=jFKLT-hFQIJ}=P)84R$loPh z+RLa9qh$P3VAq4xC4VZK{v)s3ipk&V{qI@aZN0O#35w7(LT^`X(Q^DdIJM@G4{{S$mbj6b30C}?GIGFA!CZG#3P*q>l zm3Tt5Wirz-hc&F8K&=yl6)*vS8mZU9_k9gz^TZWkRhvp)9iT5-6>ZY5`;MsSz&ije zjuB?9Kd*VVW5HZ|#WQ-FuDzuY{xLoJKQmuIZkM05=KO)YnOr?3)Q;M>^6>(3Y&Cp) z%za8H36ge~L#%*hu z9A|J6BMGzOJgwVFO@~HMVfG1*(-Z@TJ|aZ~O*e^Hhihi<`iAnv7aNDwTT-{_#IW6Y z@H&dB!?6AP!^$_2cwVsisa*d6xtk|O52Sl-sLI39%NgOb#(dKgd;~P|SD4&(r)nHN zW^$&>UhX0XH!AVL?wd`k!uMi!uUNVEfTc7r%XuEUuR;7-buuk=d%tk)6QEnLT>E|U z&d6Bcap2>t3seTczJ){h+Vedv3upHzWOZU`mkbR966&iw#VUBmso|_-RsDz{EJ$EJ z%|p!KP1a<6Pv?DMu;(RHcZ-V((y`Gq9~=pPu5V9|z*_6~W> zKgCkNf%a$3=id4P8vWeCK~QSDUg|}%Q z87R~&e4=empbp`zh2U9}6%{%uVP#h5E&%#dBc@`&0?Mg*MP!S?yyRsusdGpzt$eQk z07*;ZLOH9>h74+UYJ%w19SufPZ_xX>^BPPRU42u&lGuNs=`@$_Tq46PI%`A(b8TwQEnxFsfn>v^fhiG#yNS~s@+ zpnI1pXycW8Lu6k&&>Cu?gPnE{ADC=E}u&oJcHrt!K&gCQQiCo!0Q& zJ8Q}Uk9Hs(ZGz8nuRUrZ=s2d;9$qsvYq4~{tE3^>yzc)1?nn?^6*#L+4Ft8=TH~FaRF1EejiJZR@X*AzA8>pM# z6mJV1q}4a0q(V>>kI4#)j)XJE2-;oe7oVgMLb?!K@2pjJ-QP$nsE&F0MsO5*K7t>> z!eP{@bO8cj>FyU6je|nw6=d+4)ffrGEcq|qSc*wp4Sbs!!};Eo0_l8h_w6eh>NTZZ zK9XH;vA0db@`eu06l&N%lf1tyscUkTtwO#TL$Qe9^|Sy}Z(z)4N)HL*2z5EZ9G$b;DXYFmk#KG|q#ygt(nXJ24r#s2^cxl+G@=*QNX=B#}EU$N^r z{(?$@D!o1Z2BT~xFp}0&QOC@yod@rjQ|7pHy_mrIly9lomE_GwC0%=QFmM2j<8RrC zmfK|q4ucby04p&w(o0pbABne z{rW@MRrHVd5v&v0-VC|iD!OHv{VhPgkTZ@FBeC+&WaG3dl=5q9%wUGHw1EOe4~Odw zhC5saV<9VQYZ_jaehjh~sQ23je9@x}pn;pbw<63Ufinn zp0IKRW7u+e>LDT>hVJ@D(#bjxXkMf#*~#OHNiFqWz~i3qQCYu^mJDXOl|Zl;YEe)0 z#l*BXRkPk8KvEiwEj=I`+FJ4~`$arG#|Md48`ah3qBx38gR{KQV=YmSiGg%6Sh!Y? zlbNCPq^x{0ms*E#n$7Ox^-SB8T4eW?E9xRlBji~6soQ@uyxIN+YSu__(g{bN>9>d* zu*1N|D?XJkrn2x9{{S}7_FV&O*oL!^S8?%g*h*Oywr!Wr&@ip3mw0@xvk0u*9D=p} z#sJ^5a=I_iB% zg3DzC`L+5YB^iuo0vC~r(xtP@ZNCt65mdoGC@nHZn*FJ@O&Io%jzA_X+(a<6X!F>@ z{(<_wCFrp*=d@}ef^}hpIpSi4`9G*}i}+2!Z=i0_->S$>N0KkVv41quPYwD@|tv~0Z!37w8nLTGB1?4Z-U)|Ac`dy7j$Jn^s{A!` ze4gZ3e7&Paa6+~+Dxh7m9dm4Q3u%a`Rq+zVYaY_+-HsY9dN1n45%ME1F#3jZmF1V1 z!gch&;a-etT8FB2VzklK$oXQ@+TKj(rSS+n^Je-|qk4y_r!#4Nj z?=L0XQ>~p<^*x&+(6+@aZ!f=Rd_matakC|J(r%+J2gp4C00&MEgXaUry@6f|;tiy? z3rf3SuJGg4ZP>83l+R7SM-wsvPLD)v zgU;S^e;`X>&aA`Z(^G%QB}DYYM{+ppc<0l!-`_CNw!Jb8DzzBf5i8KaFGMhLIPlDL zmsmQ@UnF`G%7XOc)T2o=ED5psk2q!+4Z=8q@@t99%hmu47db2#q3}bo)42k@-4zE2 zH&VidG-`%r1Qj!?)UB$gXS8hYLcae1VF%8ou>@Qe%?qx8>HS4%r^4e)!Qq$Gm`b;y z`ack~4K#EE@SQw7Gqrq^Ay)BJZ=W&3)@9{uv`{bNWRK=5$cjSxe#eMWW@h;rT}A`% zeK_q5XTXko7p48+w^$ZiLOQe>rg7#w?4NFd4{3(T1z+ABFH(!7v2ZBk0S8ZA>&G3@ z8!DBG806hP#N1s~9)BY$00)bvudq3UL5G;$Ac1{lD_tj2Q>5dWc=3r&>iN?I0v3zg zJ*PA>@Ir~iZL?jaQ!>k4vGaUACC(Ug{59&!oJY_WZOdyk+~(T9jp}{}ibdN}v;3PJ zuJ=C94_zmA28N;G1e!RBDr7KgCt8{{X*t zeF<=$ixJl7;$d`I%xw>HE2bg#to|?HQ;VD(uX6HYSb87Gmmf;xqDsfs`k%fJnE-AR z5X^IxA51X$ogl)~3i89MC|M2~=8{=u9TBFv=5(goloeTu#lXWena@~RlnU<`@hxsG zo|NUvlOjyh-M5hfH_%{ZceMp#vwRIFl3mcb#~lbJeSDWwk|aEkv05jXg4fK=ZMbv0 ztp#JeL>2<#`lIsojxKE9P?mj){PePzC4Dk*da%QE%qW2);t_|jbS5NAi8 zqyZ}&&tUt^^x3D}*R)mPH}0h}of>wQL$7g4F4i{zTZ(W>uBwHQAp-vZg?{xm%-Ayt z3bMc~cX3Q8hIR+(_#=7ez4Q7?6O(zq^7-Snak9(w;GBOVbNm^^iu`CQVgylei4a6A zM{w6^a{VvSS&u97{;MxPMWa>M7V**%7{>!_{g;W7VofN0qwBfURo^$LN{mdXVC}(* zLV}G8to%F1*L1ROvt{eQH#69N4BSKg47kjW8=Z0e;td5-tY+@GfFVm7GB~x=!$T2?=c|s;^^X!$F56#j1BljMzq|B~DqP&w=Tx?)I-8@0u?z)AX4qBliD`EG%g4MHT<$_G zS=AbHBl5qpaoXcdqz9BGkL;aJk==q9Q~~br<0ib@cU_&k)5?&he>J` z7Gj!cNOhKSa{+}Ymaq|FYQuI8X_?xay##&FY{Hwu1e zDP1iH z#aCTX*jkozLIUnsv#iwU&K3o)4lC!vHuI;k7pNAFZy@r=cfR%8_l|dmpF{K^09koJ zcOODIrlRh3c@v{Egb0y4*#K8sWgxY=PpEnnmRYNGd6@AIH0l}jCrn)l_l0{@G)i3$ z$W=b^EovmK9<*87rOZv{KON>Y53SdLZYNoirRxP~;JKq65qk!Fu|bu+X{vwH46X&C zG&BOb)H*j;b6-$^7rsZghCW!{+g#b&hF7}_5;O>Sfsbf!LIp3OmKxfrF*4cE{-*n{ z9T)IIv&P6@p!5kieoABmkj)G!fcMQgwscg16fp;|umThDFE?;;(h;`n4RpYh#3CwcmXBw&$9?P&V;tI)BgZ5%GHARhiqpqUrUU~6IIUku)rAmjR8B(P{jIT07{sYvZ=*wLg_Id>RpT0d>yi-U7 z#bUy?G=?pDFhx|#Br8Nkr(}pnC&E`VRLmC=rMT@mtc^41Rh5+`X6v63%|5U(b1Sc+ z(IJi@lRRFgW#2+hJ{eW_Lv0kiUnHR6gG5)|6xju}(T3bOy}nQCWO6My2M#wH!&b&C zY}`*S77aMw^K%l>!N4?-_N+bw>^S0VMIRyJlTJE}70{>(?JqEkP1fV>c0iOljRT`yJi!fUHyv)wa2mC@ z9sZzi8T)#{7JulS9r$sj( zKT-a^u?`+^aZ!}YZXvSc9iap|hch6nDX}o$W-f697!=JJnrr4$HaLJi(a9-Qv2Y1d zWg3D}En`ut;xmlL>H;$z&-)xcg$xs9Af zPeFap_cAy!&IyC)Sn)Lr;Oik{G_aeitUTPoRIiC|ZF zH>qcoaT0RB616N=WyZQp!irJ}w^-qS@2afC#{CIS2=wXePx3XZ1+M^(2A<|2EgkZ| zrFh&M4DpNXG49G>imiwB9xC_*Wpp3ts937h-y={(mw{%TD8-Ci*tg%1OP~*c_<(e< zs`v!@;{O1w2#VAH05BBMS55et+nN|(F&_3-UUQoCuTpR;*gVvtyLCsv2vbIjY>0SB z{{V`Uk*1D?=lI}xN-woe%GDo9l{X9018pr=a#mPSp_vGEu`BZ zxzk0%&(x>8_rmp8zGfbogs3q|Q>bM#X+bJ0S_3-0>zTOge$mSm8Sby#YdzjMh<#KR>Abl$)VFp7S(o}$BTMxFpbuE_Lc;G?XR2c`%6z30CQpAymE6rpWGl8+4DI` zl@&}&8ss~ehUm>Zcu>{rx$-l@I!;H2_%gx~y6rxZ~` z@nL^@`I)%O_qC>(FRnVlRi}_%juCKB)C)ZQu@(bI4sW7U+*bS$ovvQQR6d5!K&A#X z^yo1cvxXUgCNbw6GIzO%^?GYm8InD`lokdp7 zyMzZ>jv^R-W*0jmN0{KMtK6YWE#rgCy|=iH?&a!_gGL}FZS5&A+)|J);usbti>uxE zL5V3%wmWfgRWP{(9voL_fY7YLP21|((^Cfkc@v|n49YD}NkLT37n^mFZrrxGrJM74$iOYmFkx6r7ufhfiC}a;{My60L2u z$o}Bh2iq<))vqvXymHn9u+WMHLu-~z3z{B2WL2w0c*$nOtzh|%TW$3o9 z_tG#hvFoEgB9b8BK31qG|y z&A76q=->HOlMt@-KYis@6|l#-0cC0KtC!bNLi5K_U+dGYuE)^k0>GvLK)>nq@(^r4|;b&(SEz#G^d3IG00v?6Os7&&)RI37YqYjZ|N(sF*pM>_vl|9y}Gq zSFm)NziCyBL+mGdmh$V5axac!5L}V>cKDWLg~wI?XNj0!Y}ZML)03Lx!TLhFE_0N& zU?HS}9XiBGYi&DscP-gTW~){GOMt}>gp@22@fx?71>v@-*%2nt? zl@Lzxv(Up4%(0eW$1s(^yAT$ zKYLwQr|-JOGj$cqW-r7I3X2qO7J8Dh*lV@m3n{T~fa^MiWPP^BUhm+*d9j~p`HE7@ zt#LjYmG~R=8F}hiE+|ITqwx<`FccZnONx0wCUEv}sP3iCfq4D_TFp-O{KVBAL>+9g6h9BVKGpq15W2BaW#v7fNJLxzLKE4 z=W-1o9LFW#sdFJ<*2{V6{3+}ZbT{eEEEd&8{A z-U#0uw(}`I0yUUePD+YY_?w>wp)a%KJQ=YdzF_F_<8iZ!jD{MAW2>*L1yH&$Z!sw` zd5RXbJ*N1SBHn!skfgnks;rcJLxZY4HS^V!5(EGNGjw}I#d3!N!3(pca{_N)H^fr9 z+@s_Bnb)1fa4wkd0R3tX$Cynwg1@2-6y70U>MbUKwm4kdQ_VqLF5~=2y0>R_n4hs< zaHG+K1(F(2I{Qp~i$L00GJ89U({PQC&btxsk!i|gd}x)g0CM&IIznMLw?X0^-`eX( z(l|DtgW8rQJL>7TT%X)QKo}_;tJ((Mg~ry~#YfQnal?;DM9eZ}q7)SCd4c46PEal; zB^6&X!Y|Q%1~G%!p6yQH0UUp*>W;iXeX}Z*LCdVb^{?gn?z0?)_%PqhpvA#>`uHEN zFUCe{?z(Rm%d<$lP4sF105J90`Tqd4%!UAiTs`fdNp8foYGKYt!bVy=sbts2BA_h+ zq~Z5Jf#)~-Z8`L*%C;{ zo3CGS`c8L%l#c;%%Cxoa{{SR7`FaVx-|wC7`-U=ZFa1roEX22Z&ZHgGCJ|=%Vp%q2 z8+G=TjvfZvbIR`rIYG-k1DGzw^r<+bi;jhE0dL@L1ftm1R}KcZ%fSM@pi z5o4V?8e6-CwBJ1ZFslIT2MK+*1t^LxSgcTbAm&s=RRdc!)?#L>{@=6-fTLmAA;eT@ zuoXpiipIsh0cp3w3!J-;O6T5GCsE57Q~;}B!P*v`cZpMn1CMw&`oIIB%UvU6P#a~P zS&GHQc!Rb*H|XMELYCCgdoR0Eoevj1sPV(NmML&A?&34LO13&M^&jMV(bkF9#Db7GD|2IN?8nvwF?D9!6aY5y7@VS&XDORdoSX zeQtNxsK>VE^C{(UD@*`;_5KVnN;BYGHYs~dtylel2-tFOc`NvZ7l6;Zq5$!HgcCgu z^8v#apt>-b`74aL-k8Ny=)XMcca)2D?9#oxXcc$%vY)q3aaAv+#0e>YHJji-FLyvA z%F8nVGzIx%)3s%a-F>tm=-O7>>h*fZ?3m?sY(I`NUwh~$)&287CJ`6vlw@uR?GBT6 zO8^zXUc7~~|n`^Y_ zV(6PLrFdAC+Kdqt_mz}LTxT<1#B_LzRTaW2&OIK8aRRDF_^ z9B)n&+90%`zbvut%Y|-Zr(}P4hVrmW!O;M3dN!_q(hiI`zwQ*%TRt89FiLTfmz%MZ zqBz_Kp%qviK?BGNJuO4)F-@u7^_45;k7-_<#w5mLIz43&ZTq=K)Y`jhRXVN??6GGA zV{8Cs-YRV`ZjM;stTYeaUt%Rp80OiDdX`DlboYp`aqYsh&v{|yqe7p-JCc{5_Cxr! z{1S_*A9!igS`JfR69y@^s$e~R<^x#rDaEWu3LGHKr|o!~O%FC7@I7LJmF0IU_$xVm z2VU3om6QU?mnu~M0I!}THrUHiSbj@c^RIY=r^&3M>brjiE7J467Hx*#aV{WLF`Bm;sZT&CHUM0L&WB( zxk9qnqWATc;DG||UxTC~m9<{BkK5NUp}cQ6LB|#Z#TQc0lIM?{{VdFh;FfAYX1Op>i+;AxcU0NtM7+N&rnot=+$Xrs%Bi7c@sjd>pQdf6%1El zXVN04KwGl~ZX~vH-5qOmjcisde@8ISZ-~bL_JKKXfj8(K#3}LUH5}?;mRY0RfbmdY zu{9q!8ClG+L3yAk_?MDcx##tQakw9%<>DDrSw3nJdNlN`-)9n<0049!iF|i{(|>xZ zGzy~n;GbbG1Jh43i?`X?fn=^)HICQP@I*s>#f0~yL24VbJwMo(odT_6(H=$@24x58 zMrbcxC2MQ{07;u!sQ&C$jUt>4Vk}(2Hso zPR=zgqiTzp_|!@}*%peYHNR*x?>fpA5m+T%)FWLU+)iF@yZI(8I^1TsU`m9`1(Op@ z$5&qx>?o}SrSzc1N<+~u1`qwRW%jv~1uHGB&w+6)?@wK~{+NG<=+i_ccXVO$L9g}| z@)InznFk=|o!FBGkX%riSItIs^C$Fu?|{-a*cs#hGR0t*tV9D@k-9pX2Id>d-Jdai$` zKab$froRNM8jYakrH>o&?0JWO;shL^9uvsh`O1~;KS=HM(f5EY`q98V4>0KBxpr27 z?GlDtw(7CAwG&aepe=R=`)V&vFy-RjHSr7BQI(%}XMg8R_1}&<-_NP?^N+uv4JGbU z7e@O>8kJ9Zjhx4j9cG3D;SnYnR>PUBh5o zNpbAvTs9Dz6_eFUAwZqsz-T+VLsg(IO_t@hW7DghZ{3I!NY`}bc0A1N;r3Yh`yrDm zkhl*)6fArl-~0Sx{F>xJ6Sm6`O9YnNFyQ^hrx_5%NCd(;PC= z+auyOm0x&I6koM|W2k`{3Eo|07W$&LWjVQM>k*=7M`9Aa2p?4G8D2GY_2`a8z8rHi zv@95>MNDSnzcYmY0QN)s{%&-$aUz+gBULcqyq&qUw_uU?@4x#B^#ITs=uhtMfRO2?q^_0jmfnC`C zD~PnTZyi(KNG;f>*AWumP2(;tBK@{Ey72_50IE*bb0uTt+c)E)KHxfi)8vA+yFl+GX(DR_($4ADESq zhl?Fy`aJ+k5O-!n(z?96WA7>;F}u$&B}#!>p?PJRSJ}*cJn}S%V--6ygV~0oOa#82ZS%UlQ`?H4w zuGx~ERN6OK)7DPp}!%MogKpEmv`T&Q*S*^{z zePXD#E7HWQc{|THshzr!zC29@aK?A$JHR3e`FkUbbXk?!-D8-_>8*VIr!-F!Z?bX3 zLjd}mO82IAopCdWye2h^zOORbxTw{(k8ZI0RcA)$3^j#D19kB(V2g^ZRarLdi|qSA zg=)BfpjU2$!WfUW%u@bG4PqD@f<47lMiG({@N&kr!u~@7tSw=Z=JzT)Cf3$qh|Cb# z$M*)j_xnPR5DLm^38deMn4*zMUFX6lnqsDTN)AFk*Rg9S5yP>i=~SyO6}k3D*^KoHlzP0Fm%?_f z`xgP_8jx3G?sFW?tY=2{-yOXX4B?@AFMsL+8UWPOEf|0t7#XD}v!)|Y6D=zJ4$q}Q z+tZ}vdobDGfN1rH>P=p?R5|^8&M=oNzRszE4-SRjSBi`dcesbyOv&1O5-LZnU;(T(Nw3svbTWfbT}K;1Qnk%PN! z-p6R}sJ1Hol_?iH)~Q!%@sVYX$ye;g&e~~%iZfkPy~`EI)!jxJQmzW*!y3y{tn(XY zb?o{xV9xuSx%q(@_b6DKD}$$jy_(DrW$wm&g-a<#Kb>uL(%Oqy{b3YQmZb_Eh{f;feZmf z&;p5CV0AFP-i)EqVH;@g1#K0=Jdi814P&gapwy!^GSrV3T41lNw^y_J30rLSZ9HIo zNp>*i{{Vw?7CH{wmx{oj5APR6F*4PxWTd~Ji z!2}hbQ#OkoW07W_V%U&rrS4^M%QlBfX6UT$?FWGLrq^%8XvC-`zV!%tgob(@xP=du zr1@WEOS%NBm$9$R9!tIHQL`D)e4{`><~!+Lkb>DzpzKLEO5{`>2&;i-#Obh*KFmeu zX1xCZrxUkUQ1M2l)+8eSu^4hzJvZ00;xy!@bL{^BXLz#VS`Bs>7x3@(fuzFDetfc$eMO&9r0U)X0{4Sera)HsJ5#=EZNEXY61cJ zU80t+*Q5(ywc2I6{@tJ#gJNmS&jr+@>2Q{1SFc5ep4pj_D=Mj_Hn3n6r9tSauFcBz z6muD?NlJ#r*_b z=7QC8oUUMMWr4YxH5YgOAew=tUM4hyLezR8-U$??y3*ZFq@-NW zz%&p1CD*~F4hON!x9OxWaJ}QxLa1Raxya{9yhj&^oxdDR$l=Frm9R z@b3lgLS*0H)7~{o5v<(eSD?3P9;Cw?TA}w!u)S36i?D&!4$Xa~O7y8xrFx{PQl(0j z{3=wbQl(1&00l~wE7qk-l`2%JU*WY_(m{bIEKejil`G8V;e{~ND3T2<6{*vLDygscU2=r~? zx^prk*W45PlvTK|pbnTSRrIs)z{t_t$>GT ztZU`JFnK~6)W1rVDparW*Z%-ArAn0#O1u)jf!GnwZkISZxhJqNTx z0R$j-IT2`KVQh;m_MOXrd4}B1VfhAbVZ-Q44<-m@E!Z!wd5Nm)k5aNlP97(AGUA5P zEjV2JMO2;#hL&i+HNPiExd=3_saIap1 z9p(Fg3e(ZOhk0a1iiyba81R|NKouJN!3HV7`?F&&&%0_Lo^Bc#I{9*aBB>};4^?Kv ziNEH<-46aBL4nC!OYKg&L$YMfSQ{RXQc}}SgaGci>2EY19mTv0nkN8-0)8b!ytUQG zHZ9w4n~}CIYOoXiMtsl`H=MzMj9Q=`REKk4v2=F!;I4J`dhk9Z6cofE0Dl zzj#1|6$n4yye;99^3FfeA2nJBX@EHA<}DMw%f_b}w~n$2syl+BU}>GQpsquu`&)(@$D_~_bj^K51c?>LyZ3bxNBLK zR^gG|4x;1lFI%}>df&3+t3Yyk!4)6lFFrajww>=31wc2t;4usZ$vOJEDl zV&IK*;{O0%A`NRHW$Zg9*0Xq_+2&yOliA?@AcJUllcP#}7$-^KQElm-%hm49e2yAr3tn zGwW0?p??Rf9WG=lgMrJW*O^Z2ELey$j^2+E15f>k?{uhBx4KhCTW!kd$*}}Vf<6id zQIYniWnxL0m0i$92HE)YM{}0XK6+X{nU%8;IiSe?>3xg~BZPC{`B5|a^rT1SWzV_p z?J6x{u%q_%cdIlwXG9Rfn1-O3-T8CGQd9D)k8XAFQWG8OYmoTf=h_u6>h(vwFtmB% zDYkp9^P8c}!JpTn$mWfUS~mO^AzWOsASLmoZu_z6aw#-rhngo<{XNFK1h!gQ5)=4= zPe1!vo}Nw)q;PsTSQJXKdXB#$OFxQ?e*KOxqNO{t^*J^ko^c#?G<;#G?#Y-;=9AH+ zXkQ(75C<@)o^R}CKq~a8GuUcP4uNGxbxN687nc0X=&W^nEA)1IdOHxPZ_&&9=bWyz ze8;)PD);s-YYgciop`AM)mpiEEq{U&tJpMkUPt=Jc<8tu$iYOyB)?a-rmvxAJYMA+ zkq;f~quh_x8Z0e(=jb@yUDQX%^vRVQCaAM-@xQAuq(!$dA~_g^dW-eYBP zn&E|#V^5!&1blY6Skrs^$;TW|fqAWlGVR#FcW_%E8-dfu$qlue?zUxVd{ zhgW}?j7Q6$%X|vHYW(9lRY^wnSv5_VQ;z3r8+yqV$@4mqu*xRK9!h{;K)#}YaeDnJ z4h}(FdfP{Z0Y7=8UHQCUbB=1MpPNy2i7n}Icvb2c9E#iXhXz`>m?B$TI( zM#~Ip-8mxcRsr?Lb-Ub?{F3l>B}{83DsMs#NqTzj`-J1(aOWPF=5BSW=NZA>25v@N zoUSg3NA&ZjbD!LMua1KgA-RQR#ya!zC4r?Vc0Lr6Gx@-w!{n+zas2J{4gs^Ka}bAi zt2tdWg=7a_TosFw)3APZE(xu*rqsEi6l0#dFga)Ea!KO@SpbqR*?`sGx;?|w&P=Nn5aCPvruW0O_^Ml<&|_z^@cfB6$0)}i{?9qb7A-$l!!1SBqtFtk9;dUPvIOOOZ*nO2C zPD(aS?$itYSxI{#)9Q*?RGiD{ez}8JZ76p}oK}qU8)Q)YgsI*c@8p1?_S{316{$%< zUn!2@e)ab@g!1dXHz037tB#E z+$GgNPX}6-%PXf#wURyB4wKKu!fA$oL$VL~AY8arPYf z@3f_mQqrBxMZHW1pHzMP5(H7Cs8)zXXy}u#MOf?Z!aR%`=)%7}K&@96AAwyzX?Q(( ztv`L+T_wL>8{i_dEjchcT{Kco68{|gy>w9odHe_C$9dCO7I)@?CZ{U?A+}A^@nxeTihRPdrj23j0`xmuyIUY=l%#LmQbE0di+0w|T z!H%~aXF`qgVZ)h%D3NsZ$Th>-BWJ7X(-wtILF~})s@hg#m35v(McT9K0+NSs`EgQp zNK_eb^TmLTkI!I()&cGMQCxYv3?Njm-|V1(ti6wyhvFqT3Tk0%)b`aTAwjZ>qi3Yd zFs*hT9de5kJZZAr39+QxbhW%DrinR(YOv4fsZ{RDE%&6)A$U_9>g+nf1^~&3?v@2L z-!FH?{&Oc-R-f530GPL3|X@T(Kq{j%NpQf6)>svUJ z8ywRxSObS1jMv;H2A$?t{%S>#N=|(2);*ObqH_(^X~odZHMMf&so+H-vkb`3w0qYTC_p=EI(c}+L%l*0Bi6>B}F_4Ol>D{y)?2IWAU(4X3H1bsL6CZs% zSS=N+=%;FT>BTUl`xIWD<@maSN$r;$-#bEu=hUdMtNNWF_+4k_PN$Lq=e}T6qr@il z(tvz0%}9z;c8o*^e$%VHUb*N$zy>jXOXgDbU4jND9!X&`?Z!CRpzHHp1E*~xUPj_N ztJzV*;;qkffK2RaNvJ72M(U{8DVjs*VI!Et>6#rUP=V)p!cCxl%GBi0Qok1e7HP3@ z$@uHm82&X%7qPyf=cun0PN(fF5J?M1$w5@}Qtj&O?W&@_ zOvyFmNNP%!J==er<-6X^Rka!1#8GAy)wa%P8|J~kaIsEL-wfC4V51&AwtmQoi-ERm z)r|JFFQ?bl=OO7hgmeWFBfw^zCchV#iLJFz=8~WZP2m0m0`}!^HXZ-W7w`-o%u{BN zJkK9(V%{cTpkG|G_ZOj0=4xi(lwXGbbOz1_QVkM~epHUY=(P&lAxm2acqsT=oF~|t z**a9;DjBG4p{yS`R!8g|=bPX4M#2Faw;WuOHbQ!lGjDYTTAsnGf4|myjG-+)Jw!fg z=yRuJjYRbXCR`F@DD*|nT z5va=n^{i=yV#!iQWbt`slh+$Lix2bjTU_%_D}Hg2_X10&APve5^_&SJl*YF3$ysP; zB6a(vOOH;61+mWYa*BGf|8}nt8NGq~W&EtXAxnxBL;5_PEbFy3XyQe#e*AV=E97KQ z$!MZ&>G);+&6ytA#DPWkm$`L(G>rddmlUK6m z%6q}TZ@KwZleFuZp5m5cDL79#>yw5e*#7_(WE&OGeE}5XSMW*j?duFp^@W7}+wM-= zZSFrn$hN~F=RI(z_O`GLwv%~Fb8gkI^!lsuuJ4diLhX{82DOkz)4Pv|IfHd^Ap2B3 zoR#5%Nyz2w#un2Do_#iwIdo4 z(ieQSHIKK;jhk@rb|^(uvEmgv7%}JPsjl!?w7~`B1^09vP^^vC2Vo7@lgPImr<@T* z;oNd%^vsj4`sOdF2&F4!`H|Wm^?&k)-wt!{VKIw6Ni0gFK>28HRPCyhXmXvgCDf2= z;?<;cc$e6#pq8pFh|A^y!U&xYG6UKB5k$UC`nC8#F_$s+KF+?=(63I)7fo(KFZdMB z>(*L@o>)qjNix*``#C#o`I;%JB0gObcfGKjQc{oZlA}pvWdNjwZA|$r z_L6fPsC2W2Qy*wy>@5M;aC5xc(H+sJbCSCi9)cBYK3>`qg|^iZa!)n60Y!Q@HsX* z%AdL~EvJo@Pe%pbGKs7FAj`+%*ZF;iA}ZCQHNR20Zdee~Zh_^8f*6VLZx9z|cfZX&STyra;KP=;{)WW;SZ zx^Z|Tv5D2(oyW^ZnM+;9uqL?j>w;qv?wgLFjX_UsqlxlI2O4N2gb!P$Y~(fMws6mj z#VBTg((U;pUVRP(z4l;vh>MnXLtn`6f-u+g-6i8m0stN#_Y_nhDdMjhG0g`2|H_85I8H$zRC4TzjtsvHi%SH2ghwT@`)(Fi(1 z-kXCXQN~m6UtTsmo^m(CHtcfPL=O-HaenKaF)-d>o=i_OziDoKFM5J8__Cx1-6tD3 zcXN{iVrtfBZ%x@FZ{Yp?b|e1TEMv2n=^)9yY8ifS0Tdv4PNu$aO$eOc`f?3`Xstm3 zvI%2JF&}>#tpogLWRN^JkxtT3q^@Rxvu@5=_?dnAFWz|(A4EWg0%O3t=-sfbYnEZ+ z#UN_SMvyBFZ`H@S+BhwY72zu=daYJBx&PHfJ<@HL6^$MUpx=$@vBgr8mpjV5n%p^u z%Z91c{sr`lpJYB!{`Hd?Y#j!ANd{WO{kvIUN*z!6TKpmKb)j<_TCTLxqbhXi(a0Es z*;eI#C;$V*;fyVhS8tMeTO>}kHjGlZ+?7wte#ACm z5HiPA#Hvl;*^;TYg$iu_c63&En~=W0z;%7E@}=n&B3rWK9e5Lgd=3peirxk2ZZh>I z%J0w8hKfY_lKvrc)7LH=DoRHn{Ck%;OJH^vw6AlHxyu0a!&2{a%D2>5FK$oIWLg>( zh9;=87J21t53O1OW$Jz~A7xtM7^U;~4wpBK7jCYJTF;1T8-30MVg!0;3EpX|>6#xY z4Q_ped=38oOX`o5fhUO{1eakcTUtS;kiHCFS0{Ey+`Q;#p1tk`Yts57wO*plQ}Si| zpUDeE_(^^90x7RR751*q(5>3~P48BWH3BwMZ`rTKufEX>hcb=33LIT7n9ZNu@8S9s z9IGHk$8M~v{{Y{#2QCMO{{e_9Qf;Rv*D8KP0+77BzTC*)=K)CKk;Dy9rtol{T-_3_qMpO`<`D7(X&OxG?xVKjiOz9B!|9CgSA~;#WL%2+t4fjPkj^gtIuxZ3LN&%-u9f z;FX-D5u=Q_5sE-31i@Qo0YLQmuHRe7q<`KtJakH2GXcfEDLKR*Z6t_ zW|T@;cDUrO=@wq@_qK-TabI|4^GqmZsJZn2#KLFzcNG*=UNIJfCSH7KjAF|F0Y3Z# zz#VJ$aUaz(NcsAszB8xB;YRK0J=FtacxI1?9}dR~%9w63w1Nd}&rlf`P^gwr)q6Cj zS=B-o;s>#$!PBT%QF=?Rr29?=HxLFr5`pr?ED4^KQFYySYO*^P(`Ow6)d1+ zWj_GY2C?b0!$y=2wDHyUZ38J$&40YkH-lV#{SJ_X=!}&-_|$+mdT-zjDo$ zRqQt&R9yFTMj$akggkJ!^Y~fk#!Th=Kft)#4P0jj6`K2s%mjYi*OnL}PG4h;Mq{=j zlJafKG-ZsSYu5y_*ktrvyu&K^*u35Xpvta32PG5)VXMK1bj#@e9i|?=)CWDyv?8Cq zb@0wO-q4H0m%oiBC=+>%s-T|BMJT@<<4&HG(rA#DQM$^ zZYv6mjqWS@$bhE`#21L1CTy<{RB>nHGdtt5`>wHI*&NeMYNnCghQ7{wMoF+6;M(4K zJc_;8XLiT z-F9`N3`p=sveE3;X8jGo6EzdJw+0N4Q+; z!E%+FRcX#Dk3{Ow^>MQ26W3s(Rq>p}0P+#_cNHmFaS_&bQWtJDze7i>uVmP9tTH=1>BmDZDQ$m&j+ zW+V!E%18w7CV#~Yx(WpagYlBby_`+Iwx%ypnYg^E%9SdzC!^Y^tk@mhd!R@b|8jA* zieHcl%uk4S(zkr19h_rrfrwOnNQrTFIgNCyAo-zG^pFx#!nM4L;U5th|+SRSQJJ2{uv&w6{nh9*=eTCpbG8p zRU~H|@KEjU2gq)KeKy#XxJ&94!clzJYgv?W(n8!824S~HQLuN^kq0(hf^TAiCY0R zeo}42?tHM-a3e7;HaX7fTD4&YduNgN%CJE|KlV0ssty`Qj76cE*I@@`f*>S7M|#DI2C_nby7tsFIM?w z+BW(Qyf}Hd0MSd}^wgO2K?5k9(5Abw7VgW_m(IlblNC46xMuo(IP!)-&8sDEZDp_* z;^$5hic^QN4VAV@eKDELgxR)hwg_Fr+I`LFh)T=G56)+|*|=C(R3XdA1u06I_bd#8w)Q0_5NGmldIA9d_K`|e3pn69f0-k`gOBxF8%%iinQ%-m;Zz6o@c z6apYY;t2=&%##+0Myl@BlVddWa602HAd73N9~goF13okw-3-92&iPq_*UI*P-`ze9 z^m}ghIkRY&e_Q?5`@S+eIhet^zxeRueC-%G|F)C>TLY6`%nja8v|Bo#G#P@p}b*9ci z?xUp%M{)Osh6CDe?Og%p7`X2ig<wc%>t1H& zg|0l~-oebXYV%Lq7oMb9IOx^tX<64J#=D;qoeEO9tP_3-@KbyUtJF(0oM<Du}aA#|G3uONnUBcvSXic2o}OU^Mqto|(+U_us!*|BBuZIkUTH6{u0k+Z*-5^CSCU z3Cx^0wF+mUOS2N&%LAf3WK`Bc(AF-Q>U~6?Wr)zbbc6OfkZ7H*l!wGo@yjNpQb5QP zUk7ZLS!*g8?xJ+i7U>Q3vVP;`OkK`ji#)Wlx?Pf27U=1-a}0HeUs__b5^j>09%Wqj z?77@?=*jiTK#EYP+yxdAz}{!a?WVj2&tO7soo*@-m__iXo`J-C;m|@S73$AiCv7v} zsDiidhv-as(Q(Cd{Pv|4Ynf3+6mshpA9Wb%b!v`P*OeVj9f4UwBEwAMuB_UD3~~fwZ-0R2?2# zSW~|XmCuNrjT$(NB4B|xfBd4{?Wr@3N?Bo){L0&?R*=J3y7nRqYyk(cz8Ge~I>x|| z@3}<1f4TwlS{Hk@gHJ#nc=mha5)}hjnitP$GYCzNR>HR@?k*0H;DkdxuOm8@$wZai z6^pF9a3TV?$ZQ^-yM1%W0LfuWuVOA{VCx-}m-%|&k6+i78G;t9?p^IPvMz#jey;MVdWBqH8tWY1&mnVb zxore}Fz}`A6Y>0T7xDKM?(HYxJ* za^~Fp@bvHdXlCex-?5augm;JeA_tju**X>Zk-1M*s!M~Am5`^65a&Pllw>D7i82d( zV7HWssJ<(pXd-IR$D;eG9=z~!vbIZ+5p~)yf2^gUHY9D~N_^#wHi%(rPi5VCp5!Xd z3t;{roi}vv*O}%xM`b>UHY9gV{lt;S>Sr;$Q1V=Hwro1a@P1+ zp?tK~r%URaCqoRoz2kIa)Yq9tey@vT{mpi=xT^jLJeWrt6!;IYH}FF8hN*e$mpO>y z6oIN{@3+>7X!@3*{W3-1Zx%Id_+-y@%(-}d#2p0``D`oaQe#RZgRrtnSXoipY>7R! zkx4N^w;()`?Mv67*I7@Ayft%({H(nm^^lO6@4<^*{%v@gqxRC{1IJEmom^Fv3;A8T zA)4IA%U3RPrFZjxreg7nMxuoyy-7NEZh5gkV3HL4Ib`d#Dl;@7?)=qIMg@?+qmnJI zwvMYQojf@HXOg$^f|UV+At{+IY4`$sGnhd0gPP8s%3io)42KPNg4( zV${_^J*gLGaKy99x`&;gyg}y_3C7E(7pE<}k4nMs!s+zH+C;A>ac~sNl=L>FdXdN(!Mk=KXol%|I(hdu_fCoO zO%N#q12DZeva=<*Iihz1(O!Mp^_YCPQQE<{pimJNTdaYGk#vQ#x2vnM`p^oTZuhU$LBr_pFJ$8--`^_fV}}KnxXC&xXJf!-^Mj7mW7?4 zFo8#I!V_!XZEFg<;Zpp^ZuA}iT-1H^p8xeLH`VO5g{cjV9NMTB%b|ry>bhH8@lm&e zm%uECDDVj4nGxb_!^<#wkOK4-|F%hj7pg|uLNzeBcGWR|v-7v=$?eVOAAkzxEnTu! zh`bl$^e1m%dGC3xaWzB{)JDdC?wcK&7ooSd^B^95`f&2aC<_mWx;%DnkNv5I%9=qa z`kvWafEsO59V=4B8e^qzm(=;zmdtj8`UiJ+stGcSbrD@GrU)nhs;=UuXyo!ZXOYg9 zhAYr8VfW=G$Y3|Y=r6ddov;1Snre2OwpmW|5!U_eW|f(%{?b3N7aOy4R3a3 zbtFWza2+e3B9Ej2yM?PTa!b{krNjO2=&wbVn(H_EdCRBeAsSwqm%RxU&dP%s62iL= zINN=8_}_oGr81-1M-6a~wO$3h%lc^|(aE!aJXc`~DrT_IpC0pf^xwo1q{6=@?rj!E z!E?&Y<94qVG;ZQ)7B~u+UM&$u-XFX>>F$9xD=Ggfid7VdlxspMq__g$!8 z5cTINR5*$$@qsF{Jt8obVy}-!EocU~Jvg~tma>X0_Y!&Z1j!NbFL*ns{QUiHx|4%A zD<5zmPvRZK{{W9iIZz{G$3=sCs(q&S(=+ayA)l!S^f)Cw)SXjW$+MnsCwgZE+@icQ z<5N(;>>=nh4zZ#*$L=Lflplf95l2e)m#o1sj$sV1TfQEbVJ<^WaSFFD*Qr{kQW3C2 zWySO@>oh0%r^)o)?SPIxm~KL>;|1a53AZ~TWH9T6ljSjXzMVt|eu7p7N2NEMI|@WSU8%2!#NHTz3nE-UtP{2Xu0 zg=syw*8UpX{D_>Io<+x3?LeSZU)TyFJmO*;{Ph}m(&$Xb#;}1^sa3<^jd`mUd9SJ; zs8Id@OE<- zJmeRSHr^I#;9cVX=3b;=UegelAZU8XfYCrM9}1gNUcNO=Kz#e(6%63V?4}C^Dji*v z)ipn4^FL(3Uc}8#!lG@L?nsd|9aJz|>Pio?_t%+UovDAZnFP1sgXR=_UVjBU&b$1~ zciKTXQkuJ{e0}e}duJI^Hal&?m?zEvOc_;mxMV(hQQC%iM41sZKje3eHpWbOn=x68 z97-tVcc_+cMV%qmJQBQxzpn|_lBec`06D?RGfuul%qqof6>ZESS{+ z6WRBYJODN*^GAS&2oKIYP{th3iBWJ$BA1H{JgEUvlos<(#JF2ah2EhsPg37+WIyD zB}}hiW)hpxZy)a0R?B((+RW_!Ez-Fm?Tnn6(gWjDGCnFrxA$#F-Tx|$4ANQaaI|AH)3OTQqTkMvtbgSH~d{?ix7?y&La4FksI zMCtucRb4IyE(QhPw_)X1wu=GmaNi!7+YXrX3p%`q5e-FwegCg~--7+p#lR7ERpT4H z#NmJ`gIpwo7NvNW59f>jdq~f$)r(?d@e!<@} z=r4>$`~O+Axc>k|O0Psulj_Qk)t@x`Vac#GM1N5;Uu8LagtS+s-E%p}xD z1Sxr$fR~#6@b9anP_{745FEME1NDxo&G@g)4jb3Zh~5leyQgDaMWGEXE56P8TBaasT&7Khse^plQL-zRo0XT1xg9kSrmt|fZods#gptj38loM;~R{RNIBqg@*YN#e3Eig=y;O)&o^1&f&Hp{#M!?g z1P`D2wAlk4Z)tL>SUaj?;d_EYWVcUYCQYi2K|42vuRF&ubW_ih^v>qMF|$L9;46K^ zH$;zzB1!&Vexb4L55dTU?*qB4dJ^hl&d68CyTyiv{pX3X%(syr!X`dve%6oRH_J_R ziqErwW#V4zDZeUozWf8Ie|Y`l{14#pDmDG2^H!R|{}@u8A=Gg3cljUSG(?f#U+|Uo zHfH1Xozm>`9EwOZTkS}AQ7{(oqZln8v_bDc7LHdJHR^8d1%Lg`(Ug!5e0O~)$k(5B=bChZFE+@4^$Rf=%E_s*ft{=(5IsUe zg)bwUAnOT|3cwF=fxZ77$zvotw9#MUtoL{sHzyGJWDJ=Aery zRd>o$VRAR2zLMAtjvN=9wNupZDO^e8#PMxo}?_@Adw(YFNS8{9_ z&nMyqEZ8Opi*y{^T?pVNX$>Q9r3c5`@C4gTu7<}iGOhLG+MgF#50TF{4T@`T0$wKM zTvaTzNH$`ZE@sfn&|tCF2G8lQJmz6LA{6oP#m{qkWVu6!Tl5H{M@X%>mlgf@xt4|l zhv5!XczexYSM_Fx4F+cIV$^Ws$M~u<4h;KtdOTEu6A_tcY7l;b25+z$5QK{s)hGWlZ_mefe}oicZ^ zySQMf%aCuE+OAUUfEg>z`6oPEkE(zA`#eD!RfTgeV1>BdrSVk;oNH}qVG5UJXz`2@ zYh_aLub$@txK>+>l|)LRMV2Vd=`Xg(wptaXPDrLjq3Xq|ZN!f6l01AcN!<6Rhbc|b zo-<^B7E2jl3mZz4Pc2V{4pZV-QDT~B5_r#TVp72-vxqH9zs3IU8XlGiVfHc(ejSgeFU5~uzZWqjnxLjFL?8sqvCdjAXXs97kTVMz)ojmN zOnp$jC6crCN$P+SZV5V*t(JbvUaMdW!%i`MfD#^Z=#8uvEtgS#bJoPv;NsXAnC3oc z->x*JtlW!S)UsfXB9fQW20NkQFQ7 z#CGVb9AWrpO@GcZ)o;_X&h8o}cK9P-jA#H{!%i*mzpB^hjzG;)zkk7^96{E%d`p+= z3pB0xyfF0OY-*&}93~WBQyN6TO@S_lfZ)c!&6mvqFNj#G%)*3@H{v$H&7eFgoJgqz zid1wbWi5%cxl*NbQ=GHKim-tO&XOws z8!mk_kMKJ{A-J^Xi!DuIU&Sk*%{$Qgz?xPRW`ff%ik<@D8bV#)sfC|YAWPm`va`G3AqC;L#i?Q0 z!Rf`uNnAxE8@v&Mn|D1`(Ujm1+z;aD@FRA4ypbh_mhftpKf}=EexfG1i%Ft?)87O4KHLW?IKtym*NOWn2SgiqCbYkP15Q6ZtD7%w2iZ_4A(o^P*s~aXL zIny^rs$a)SPxjN!c(4_d77Y+~MbXE(6KcA2#zl&9G|kk!Fi@J`Rxy8iUuzA2S#_VZules1ET2cKJZtXc3c%-F!Vy8nlAos->U5 z>CE_nDN{N&Nq3hbKPr@RtZw+5=xprjDdO;?CGi+AQ7HUu&Pfszt1*6MyFlY&Qk^i8Rvf_z<;2g(^CIAWk zU6HJxo_#}^yw)t`zpr80d#Y}$O6UGP%_gfWxoirHRTO|T%)#o7{zeh0qeGyVJL35`h0E!q_3oZ%WgpYDH8ycJi>08ti z5_hUW9B6MrIO0RhELe97HD?*!(|h@i!!Q0+1JTXa#ZlRov%Y>64F~ll zP)GKSp$AKbVd|(6e1{*zhy?+Wj^sK2?aH8Yu- zlO~lHVfZ5_CYG@5{bCEERJYB}UU+ac#6K6p^ z<&h@-mFPNz=*d6dW*>F%S4D1xZ8n2P6N*d*mwd9M=}z+ly+V-w-%R5oQE~_F(%8&c zaz?-8%d7f4Nuiu-na0iwP#1XeL?4P3$Hq;ejs%<$ZJ79u#;2fkm=H+X`IG$xw+*q= z)C+KQv{LUqF&ve?$K#$1jL9rw6%3Tx#T9F-&XAHi*Bk&LBTcYo*|vmAmz>VW(_iy~ zRsy0J7S_Luu~Ybm3qG_lC6Pms!jkrR0i!eKr|P7La4u|J8Qu%olRZ_4y1m^ml^VJA z1wY!e-&Mk5|F+!*;D(yGNvbQK`b#fxtSXNYFTB_VCt%E&x19J@855Bn@ya3DTCFSYuNEIJB| zhgDVmF*dR5Zt|Tp!%FsgtgrM&v%i81iW!)lB5-kklK^Z`6#@tC%$JDNr2heKIp0lZ ze(7{R*Sw64C>b`I^87pqy#e$0>4vb`leLbNnDm6hJ5*M=Pbs{Yb97xTpXDa5yTv4E z*Bjwi=QIPQ(qot7jwolu=_mNcF~y+{MfanUut+eoAbyUTmT|S6x z5ypO2osK^%Z-n##vqs;=b$C$A)Jiw%FCivu)z~|U%yxG-YRkA;ItR8Vz{cf}A`$YW=HBYD?jhQI#f1HUoVjZ3~h`;2tC-0-Gpv_a2(U^Ks)GhQWnJ0KWB&sF*7WnM?)FOyTo_ zO{~aFw3bk$b0=|JIZUYoW$k}s_=S>Cl=4^;4yh?-lHT%C$wAqGGYH|FGIo2a(T1%I;0!7yHsZg4Vxybw2Z=Pf{ zbCWqf#HEv6qd!7Ht9l zGaZ}Y3yHu`vLOshxNjcso-5r(h1ZsWUxvO_j->PU)1qGT^`K}?DyG+5aMEODGLm=xR3{y3Q;PwyTOp?a-{`*)jEE9IFcw$F~ z3SYzco;UUkte!@KgXTzNlx@2kuak&|2a<-z>}n_hkny{=j=gV^HOC$nGH~EUg=!N6 z>Z)b-H`VnW(?Uo>F!dE6@#qn_AVA71}bsHy^Cr zVj1GexT1?)3wy*OFSs5acEVwi#5E;!p1`A=XAQEnqHrr(M*7pSZgC~Mm)v!SH<7zq zCYP{O@mU}pz#GBYL{xw3IPv9pk3vAW!LCl&9<# zkJE|Nr}!3RM!lCwgPTPf;mZkO^yasLvHk@}>_N!;pQ233|E?YoDK?#GT0mzM|gA%XH z?}2~_YODkV%OeWWsp_jHMCb@S(8smYaE??362y8SaF14%{oZ}W8G|`0+!PA_4SWw3 z4sD-K(bA83-=*KtxGnMb=CQtZ<477Qbc4Czr%|?k_#r)qWwbbgiW&klSHc(jQjtm! zyD?S=1;>U>$$LN4`FnK2EH}X@W4L3-kKcdPG(c{*5ncx+H!pcI>Nx%Zu6UxfSVzO& z`Hc$UzR(r{Y_AV+kt`m7n}}M`NM%ooB}G4?Hj5B2GV?|?R1{I>V^J}DvFUz~tsBqv z+Z;4JI5a?ODpb;nY`sqi5Y+h^)-N69Snie$zQgQ;UoY7$r!I7uMgW%2IJl_rLfb)H zd|H;+=Aj05GT+h1-tE?~pOf21g#VH$sYU;;)Fo+bOxGZr_(1!x?AZ=rNzR)3Ua|%F z2>r>A$l3XDMx|Dmx%`7^af46`r!Y)`e-xa{DwiAKs85ZM+Z7t)Wa#Uo^@od@1aRDj zqD7FT6eGRqv8q0AjDPqAzTleA%A*`OZ&6N4+G5NFjgm}j4BRz9pz+( zsSe1+?t@{cWasgTC8F2gDR5&Z_apw>=lLm^-~Q0wZ~ao8g&2B!b9j=V=y(UtHreSw z|1@ldPMGWOh(;P_EtotHsF&@@U5eib`8y+}WT_#ytRFdz$;wj1t!trN8%3tCxn+Fk zCftc_TApK7C1^>a#dK(CTC&`INnZRJao02RP98E+;$(>nh^$PqsbD2y7!mL+p(&u7 zF%S78JD#rW%T44ZKaK80M0pMRJEZz8Y79Rg*Ax#jiexsj883GhT3tGY_0jD15^0y_Clvu2Z~3Z4s@Ao?USmMqg~hSs*QNP%*{61m(7( z+i(!g#vB1*BuLgVZ_;I(dh%*<8XGx(j}7B9=ZvNAUa+NeK{(bOan7b*=1t)$*B$g~ znl{NzLZ&2-*qC4g*6Wo)!h0#gEPwAV@MQqZy5e!?h8Kyz>p)HUm8n93=ew~| zc`(M6W*d|cFf+v;D{&{6sE)!gz0ANY`Jk+{_Ch?#%AA(H61gCUnVK5c9A}tS8i59^;2( z5ZLg9LK14CjbEcr)PN7?I82|Y`c>A!OkJOy%p0s^q%8?7ibs^ao8SeavJklrvJU)8 zJRRCZlul7Kr33kJMyZ}Kt}xf$kN#4!Gctm(sN;TUiA|{fljL@m@p{D-pNhJ;U_0o{ zmp-WGQEMCi$27j@OI*EFYdA4LvwKWdx;k$XhiR5tovRrj=5dQ@j(-VeO&+q#^|~NU z9~?mX2?I&1=nG9GN|%#ZZ+ozLX#S?C#9!IG#V%V1lpUsbj^puB6H600?BfoXTANz28{E6+LskVxU~VZs#nZHo}&krCtbN*e@|UGQjgs znAm8A!%Df3GXtO)_Y&ZUVz4Zh#3{nE!@P;_F@z1Pj%5j?vo@eFgNb(Mrd{M1g(BQ= zA%&+*A$_9b2o`yjO2(U)2)9VX1s0_!z#@QXw`q$s*D}!oe~C^MUB#Ix5*yTU(kk|) z!>l=(mVi4Ih82-!_E%g160HRQTuPi9&FWoV-Ngd;6AFQ#@eKn10QyPXn!cN25tdB; zH@fO9i*09^SRiW*4-%TmO0w#nBjD_XdnIC7HC!XZ1oRcQ>bw@PGo?)XCIeuY0I(kQj3?|vI*2B~(V}%a6ViKmAlwzuh#duV> zp%ejc%UFXK6lH>&;-!;FG+zv{u~if*`j<+m1qPkU0{cS5S`+REP-c zEeHdMZ4Q`*>vKr_a7R(%XW;oR<_F7Da;xRX_(^fk!k?k|wp#)R!|=sL#2_NX31c?@ z0Gkv3z7nA=0LgRoiMuWByXBQAPH|D9w9F52_o!GVTx8P$rlNS%Sa&szN{uFXskH_b zmOGT7cgYb|wk%EsC5D3dkAU1&AG6%ZpsSdRr-Qgw*m{Uwz-DNRa(zHGnOkIsO-A)z8!a=k`37-M(Tr-E}Y{tRMT0~R=oGF=~9Ov83p8^02oogk}-Ix01!KIkk>4JeAnnPGKtTCOIFviAxQJelB`B+->q z0u92W`=qqM0@_1p;Bw{EXeOYfI16r%a2a^~%#LMjrg?%;ThYu%B|!vY{{S(j0+adX zDk(rKwgl7`L4a@&A>J1mPS`9vnH>x_T}(y**;sn+R}K~$$Bz-Int-F5DL%-xB5fAi z?U+nNymmkdlZlwB+NR-bZQA(baVdCtd~P(r39m0cok}394W<1r44;_d3v#W-@Ai%$ zKovTJNtu)rP#o_tS20*3fK1VIgy`$s3R+6DflTF)Lw9L*W40Bh1Qwi1CZLyM!AIq; zvr|36$Q}w=AjM!X9*8MQ-k1o1ibc#wjBmy1(ynoJ#HoYUvYm|7DMB#_Pr;T8umDhW zKvr2`ph|Ro!p)+D@C-K31ZFHYA#s^w{Y2v6`0TGRGMw=hFwSud?rI|A7O#cJB}$l$ zd=Vg2?o`21el87EVTpeWj0Rmrxku|Dk;@;}d=ZN-5tV5Is^R=hLfXbN!iImG@ZuuE zW0(H`hFRJgQN9U6?=q~$3#i*LTWl63Et_S6gA{N;5UtD+LElq3aL#K8Tg*b$xo8B^ zp81P%gD`4iQ+2;=#4_RvkQCVXsg9SKWwhotAOPfK&m6|tIb}H`Q&G`R%y-&mZ5}rAPQGVkgX1>ta#yW(s?Q-#EVN1hbjwx?oJC--f#<;^Nh=5tQ zmyE`cm!PIw{h($;CR(|3pwM$f2F9c1UOGEvirj(4GOFSY2Iwt|Ql&+umR0sndc=oB zWzC%;90yEAj?nr5@)#2!y^F2^C7~!Tor8-X$80fFr3F8I;#?FcUqwNRcQ!tt({{R+ zX=6vFUA(+R7U=s+FjNZYIL>9(eWJuzg>13gnAYu`L_jSwh>Q>`YQuZ6=3v(%+d-L9 z%Y!=N1AGbPNI+7WLTxhKE>LgaW89#Z23w*48MWL?altwSl-f2nFthr%tmcXP-po1h z@NufM>SWN_)Yx>pnyOjkl+12yFQ}V~-?8Ofv<2hfHV7EB+#vj!a}24^=|4sP0E~Wa zT)cdez6a!63?Bjr`i|YPAYNlfw9ow-MiB9t&)yM}dzh;S37iRB2wX?)#Idl0P+k|P zWH@llirn)!mmUK`SfB#nhU-^WK)rcq*Kg(_B)yXB5F9E*x*cL&i=l|~C|W!)qeFZk zWlAG8HSCy=1#iT-33;MIG}Up4nqblLOFNz*w;ZsoSn^=JLZ|~wd26Ff$^ZRRTrL{usO&2 zoPj@M5PhXG!m7!glwsg^;v{aWsUCzbgAPR%3UCn!Q187FP;OoFU;$bWBIX$J1y-JR zMuMCI@6GLiD-pC8B*u7;L`(T>d1;x1DFJ+|o?atSa;<KR^ro;Xu%ED)Ff~wr71>tM^hw*(YVqS89R1(VA{qIavbU{@wilZKtC`nP$gW& z4azn>Kq*W#vCLCawePrYAOhIcQHiWxVyg-#BQE#>$?sBR)TT9e#H0c?!d%oKt|5j6 ztOhOwWJ;gb(T-Np2owzs{r5zsy;_^N91KOMd{rBCP-3za%yjY6z)!FqOq$;z4FucSSK)W!*@=XKbNE_*3Q*c93VXVNW*wTDY zf8f25^A`kwKx&IeK)_-o4si9UpC&2ll-M3tuvB0Q~S*(qdNpcN{Wg$-P?&#uJS z=ym2NCTTA`VuRfQ({)il55K{*ue^~|WK>`6Z6T!W#^IIlR2oZ^bdzWt7Q%v53kC4^ zUkr0>&w{^1h#FR;<%mIb@RAK?E9gt8fQf#HfRT1D*9A-(u67Dqb?1smV(XgoW*c>Y z^k?zL1!d|!Ix1vtL)xU$Z(O7WPLrxlWPYH^cSyckmnK}F5s z&@ABi5K00qs>y`P2U~zOB4(&5zTRO~(I&K0i~$d`93xrS1i|EPC7v>6uj!#E3P3R(Rt%59k7*2w2=T<7~mI4?|=28pqXoN9T4 zs$4sqC)OYlbdKwRhbCO$);%*y!I!8)o1vfw*vFK2NXLa}BGxxIjvsKU7(Ak*7^}jA z1H(5&@mcDwc@1V`{~L$kNqHYZg#a4b`ytyqu66=E-|$$9xRpqUG+@ zf(w>$WX(x*BI5$XlDx!K4U}Xr^9ZbVL`q7ODjm3BJqS1Gb1yhWt3hfw=@MrrO{e}5 zeV>gVh*&0=OUVNk?{kyOh~O!xS{t3z0*42gb8%SD5m(T5++kNoBg9*Ev<%}A0kE$G zQNq>1SS6X$j3X0WIvqe)@rZ2_8qwH7Iuk~vRgKoA*fnr4HCMO=iBwMP6mPT`2SRLw zD;c{HEY#?*M{m#-gI1ABhsmS@D|otMudx6%T|`L5hgGy|r}vCP8U@rHme#yk;_JNz zoU2G91S}13Y{Jz8kr$#a#C%75dNdO|&LE{8ctD20El0BZT>-#wI3TZuY&cb}RP%9V z(JQ za)#A%tQ1G#Be_rSfkOeVSfYxKG2Rf~m31-}tL{UEuAnM5x*>hlLe|}#J&D352Bd!0 zCb>Ftsx7E6G9*O?OF$BVC@>5C1_WqSVF*eTxQo=d<4g`kgY6}|O1>*PMxg^{DX+a@ zaKKji8EhKQnMG0z+_bh41g()Q(FGxJimc&hj-;^n6%&nAjwVdO8e{+n+_qAo4|>y0 z%N|5f7-eZ%%^~H3^rG-8I~Jg-fk#E|Sbre0g6^zRV7X)je&XGq2!M$o<75;fsCvCk zNjU}p^4g{*4vYuVlOx@MeqjZ*sV2^_xs?PLBg#jp(0NxJgYy(FttD2!!4`hB{u~o^ zq7^T)6>|(LgwfmEP;!k-ZYkblLNcQZ4;KSw#3XDnt)*sAOug6@jB{A%Y1Z6Dg=RNTuqc(SFsct1 zmGvzfg$kF8r(?O8cn2b-mcZF+z5%vogaeE#_Zn;erEj8|DelS%DyZknBJJc-IsT3Bj?6#d_D; z!-T*w8~7{XAo*yktNp5jf)9e7$zzgcuHVaK0*6;lnK{6?!eZThYr83SR%XD0;a|=; z95S3rf**4=F6=1H=>ba%^sA$qL;PszUcNw?%Z7a3r)dbrA5&x;TjCs8BQhL zdS>Ng))A;jbx|lND|ghOK)!<2c{@9cCaQ~JrY z;+!mMSHTgM=VU6w4H;R}XqA5k5~Cf%=Os+7oGvwCFs_EV#S9C*9O?0-r=R^va8Rrk zt?_c$i;IGSG?Ut8<|RpMxQ_3Tf)u+|yVbfAuNZngPbg{}>1%{NRu=2RGvfyiNioGL#orZzwcwi4uSVvCoxcj38emfAGyHbuN} z>l(PJydo-Eg1du70W%aBKH0Dh zaO3u+Y=+BZ@{`T*2wL>T5o2NfxH!0sm2vubBH#dDvhe^QgGw!XV?jV_olmH}eR}>B z!l3~exU0R<{MsOja(_HSrJj~ujcJFOW~Py1d%^=@01$-_n4w&27)AZ$2%P?s-cC0B zn4?tGxlabQvN`>R0=1~xReT7J!scqvg{*zsi zHR~=hQM}Y%3Oj+j)6Cq3lv_x0UQr5*EC+0M`MAaus{q>L_LM`pDcWmh-s?^7I;T1^ z^(le!!aRrIEBQed5sXiTnPA0KFh@Mcoy)SCN<28RTi1Bf3?RH%+w_>=QBibf%vIU( zX`z^yqhvBk4uLe@gxNOGHa|L~%bdDUuc$4Xd19qU0Qbxu&Q>%JFC+^U#qn~m8CF^D zDv~9=*tNNgx!eKd3mu%o6rojdQ2;4VF=)HBqx&#w7iHuhJj$U8%>xFQh`?}MR?1es z)FDvNVA4RvRmrV@aolqB{oq@2UTYTxeqq(EWw<<>B+$}<88XudN4*N_!qv`YznRbw z*s`Xyz9TSCRk2vlwh$K8TT$1-DkaE;MezYNkp zFeoWdSm3CMQl<=9!4f8u6R=K_Iv66_u8$@XDl5~1sU3*nWZYY)KN;QjrXWOps!7S!Tlx$5sP-4b+d#ecTt4a z@Bky4+BV$2qcM?SE&)}-iW0kp+fZRmoE+RDSwUEWXMHx z7d{p7K~bIGORRMk#w9jUSq=sc!3~$7y$FzBX!@83oS$W$DQ7Lh#=SbBcQbSDw=WbdP?Ggb&AZRhz2GBWOODlx8_Vt7 z%2id$up)dhYn|01%02A_8q`s?J{GP6h6o+ah$Ma7AVJ5k!#dkfXwZWfrb>q1;07go znw(`5Q)~3H@$iysMz$0TvBJ!oCFlJJ+vqvWw&pD6RH;rVVTfJJC=4%^cwm^fI8E|+YJM1uY(FFK z5nxp}#_R%pyLE0-?mUEJtTZwij6L5Ga-}3hoGKM6)6=iWM7l^Dh@GfN^<% zQppxg$}SsN^ul>fKt4+hT0tk=eSyBq+!_WZNmJ4+r-CQyuM)xGD4^U340?w#Wp_^( zD>$&ItAJYIIVUQHyLd8z!o)M>=rMK8qPAvO`)<072RXSPBxFX3Mk-Twj5~{6W%~`D z^y=ke0YD9VUr-C2vjgn)SU5qkx}YK|qV>2x__ zAEH5W(Q3;80QqeJZcfGXk4BZ2fT%t90JjqYzGVPvG06Y`?IMmlJNSzhuBA_LXmg@4 zJ%EK218o$_3rL6@9s{(#_PZ*GPH+vvj^|#KPY4KF#2_{rC>%96JN;78Kqw0Alv0%i zZJ9TiRdY&MF`reTQ2=sY9T?vu8@A5Gl-lYlS+Q$501WtU8t7-fQWl$+4E zzKOtqh{J?2VLQ_-)<}>o9h=uQly!i%JSvtZ8!}hTJfVmzs-Fspa;zZAM>o6<%9i>L z`+<;_1JUpdMlpgv&*!@}igMp!Bm3f+wXEy*Wec~Y$EDk$hb-5W0DZoY1n1!+1GnT6 zSl_sMb{fVilFQ?W6CO~i)u|Wkh^n@#M6(!AhF%B-X=`ZKREl=8fpgtoT*W00OVnH! zW6=%n5u@Sws@wDB+G8NC5lc3|QPU-^NW=2^Z%cwbtf8~JVmcBBCg`!ipe&?yp`zWI zgJ3@+ty8E~3&1e7-^U`u&$BZi{B{XQ%ruD8q3oE?iqtn|!QOQHg$uQ1Or zCNFZ1G?rUd!Lm^dZhL}KTQv5pLu}+cYt&9Ei&rW*9~V;ilCm^rAj1ufM8eIxoht}Oe8>NAJyg|vEM2g~>g2grh<3y?m@@_v>xjI&? zFj7+&MNtkU7U=N@b!LO0!O6nh;<0FghT%J)qvrM{W{Q!r8lvM#L=$F}HrBhq%7YoUiD0<_ z(=CKd250T=ApHYagM zEt03Tof^oHJIa<7*g4M-7^-*%!A*Hy<8`rS3Ty+2cyfI<%W-9oHbv;XgtS~nU@#c( z%2%RbaE8L2Sb3o+K$sppctn`S3ToDykGNM22UIT<(V19gO{iN8Y2=Lfea#GH@Lfy4 zDWaiUJ)%HTlx@bFE5u$^z0(!+VhgwuN(z*%Kn<>_sBo;Fe{P^4I*7E)qX3yj%wI6P zL>z*mu!oh6#&OjY=-v-8i3LC-$RTXpPJx@p_d;>GecR?b%2kLO>`V%da$RINqZXco zAb}Zw4KdB4g&RN4=^Nb(gbo>k2Aa2?y65Fzl!F@C=lXBdh1 z0W3Rxota@2Tq!CsHgdc{zemFs9kwd@=uv?%Ha4As8OqnV!r4^~zYbyYxLYzXM@7K% z9U}5BipDcq<`0x;w8fDQb5Noq6fdPWVFqo&m4)4963&5WDTwT5S8P3e4sIflgi59) z2qhIVA!vbHh9eaRUH5p4=(?`Fd5keBpuD~7007rD^V~H{ekNzB!W&}LUR8)CVg=pB z5txo%*VvWL6idltRiGgF%cMf5CEj( zxL5^ximeAYpfduPddFB2nqfnm7z6`wd=7jr2hy$Y21M3MkHmpBMj0C`Qr?{c#T-`& zj4&^H`pnJzQj_i6u)6r(SfJ-_%NjAH)`}`wUffNOvz{LXrUJ;8&+^J`=D*kkGm^iDiv7h4I`YO zUSc2$Wl#3vEZaq7IL(&fo>DQRCD zVFjX@dcDDd`uI?r_+YqS?N>}P#JLqIWdqhP)NfCDk+L|m^2A4x+Uk}yyfYvrBaC6T zP%6u|=rY7Yjj*WjVFnCi0Ng`G3=`WkQB){dNcY^K$O?lOV!XD)Uj_<5p@a%|25f9u zyc~_#lH}3Jkx2LBsBhz#d@NI5QP^L0*ATKfUjo74bigGEr znYpgol|TcUP|8NQkT|tvQk*@c)!@-)T*B!UnKmxpkV*E6qHs~uzL@x}cFM3l#Q|Rpd%n&-lkx*sZ!Z~AHjew z2f};{0>RpJlRN=fHW9er1`*^ME*14Ey&>h04 zn8p$|1}Ig!SdNWT4~qD*c#46)x-#LIIS^?AYB~5Nti~gC)TZTWxgXg}L%L|^NF)~2 zK4;yg<}Gj=6mN(F8%d@s9wr! zKr$@b1=W_wc4YGl7H$Nsk@$*=<}pG!!%q5+nnzoK(5ND6Fz|WIpi(;L{X+pzbD*?QczLE~y=b zwjG`LVZP@gI}_uBVF+a)!86EKDe?$gy6Lq zA0;bn?R&V9={FR(Cws2R#Jn~OwmGe*ZUREewWwxno65_<*bJLCwqS?Y)9KB1;Q|CiN>zX~W?DQ!sBQKujb|y7 zx?K=ils4(86fBD=j~6dFB>XdL##&G;TgbeD3<2U6@hh#tNkLl|$1>LPb6&vUnG3ff z5j-E8gnxljxQ6i}S}t|5bRjn+LZLd9cI%qG;wm6)Zt{v+8r?wd$n zpq3l0!S9xF9m(g~EM;MhfK0j`bETE)U>(`xFf>3hecFht_)+^KRRd5M(ObJPmO)|!0hXZzuwEdy00vv+V~T1ySQ+K? znzcr?p_o@N9q+i8e@GZdkUK%Hr2^WrFer6W>0MgnMW=Py>6RHTTpD>@#$-FBUZy zfLKV}*grDZBEKwJWes|N)2Uy%e&A~!Lg4bn^rpfFo(j5;fyZ@C>Eo9S3{rwN=z|+_qR=^9n&Imj zk6A z3{bkWrnW*Ma+qK)meY>NzSAOeQsCCOkA#Ji0egIm5VFak?7+SN95{1?_cMwioU9b& z&_W};%RIdZSg~nQ96i^8i~W!hCFWh-a)hyw+Xc(&TN^x#8|RjyXAtJar=<>fZ{yPqsYwP|E`iH35;n21>s2fvz;VJe z87cu?Tr}AF;R+LiJJ2u7ct>Wl7py#q0m{W_C0g2}P}Qy1f;ly`ae?%o7(;7Q+Fh{v z0yM{aant0nL7G8`7=<-=id5ZWo1D3|@@g-vwhmcN*`@92IV)=xqZCS((U*uLwRpE+ z`EJ<@Y?nM&sIB!ea^oHl1q6_SI4BVMs0h}(Pl zmrqv%V-l$omY^uareypF4iLA148YDVWkEuvmzGS#E;phg5>;(sfhe{fND@-r?jZ?# zHyYG6{G)g~h!}%`i1(+e+ek!)D{MD=&VK8V-PV^DKxN7;9zu%zCYTt9KcwbEf0Q zAh%iK;k3CZ-7DI4cy)($G}_N$a;U1#qF0q_8DvnReyw zM7{q2W=+wxOzLtu!g7n3+A4c)p~o;o&0ArA5kyPSd4+jAF&#ND4UjjyoXZH!2sERQMtvvaGOnR*JhKAnWxN?dX)0(9 zQn;;?9AgwFDi(sbn6Cn!S#(+~1DLgKKM=)V?4qgbGa#a1U);vqctK{SH5kPuWmNP^ zOF*zQgp@rPeTcPPh_`v`w zFrcnQd5&ULPtX8&big6g^8q`2LT+vzz7B~25y7kbC{mKrz|#UaSo=oc{9L9xb!RK0 zQybu1GE8tJ2d^hb3HHjvYob726)$v+80M}?W``&YSXCCq?65oxu%<>P_S!M13Sf(S zv?JZi;s(stb}RpmH7c;bEs;K8V5zChR+qeU1iY3HDjd2kR zA>em85lnhc0fj+p0dC+VP;wIaNqM3zhCO455hSG8TmV?ksuu&!1GutmbVr5cJasLT zBSSSUz+X%Jvmgw03ai_gwyyq3wJ3m57ei9%;SHiSVVJ$5jc0zh? z_I(94#m$_bGtl)0-)rgIXh)FQ!kgboA25`!{;){HFCc*JEU;L3qUcy>3qdW! z$X8qbVpVY97Npt^YRcCf*+TBQ{{Rb&YUaUcJt#op0kFS2z?J4`t7kx^RcH#PZw#%H z^sH`Q0??3*%lNIXDq3C=ACOsjd3c1fOT=ZMpt8(jnQ3WEr{ED8Pr{`?3rj)`d|bJI zp>S=KSp+q##Wh#CSy?cQ?8O%y&Jz-^H_{HXh7FtHmE(b%l@Nr(4&pVC@a$X;?rgB; zs#v^Dgr>|U74;25V7^|i9;gWpjv>pA)mA>$1n?-9u%@16E?Ouo)Ka%*BmfyIf!CG* zcC{?j-z`RaN_Du_mMbt7s&YH*LTxlycyPhC;e>*2&G#y@IhZ)nO3!R5*pX3X1WPTa zk2e=EkthiR7>dyM;h3WivZ#Gae9lJURd!vxmjbSYy0@kO0A+>*B&sZDEKtoZ2<;1Q zMGB}A!^ZjzUUfm_BvgO{QNC8yG`ujlQnpvkaP~97n(6-lai~zMAiyb@8%4F`DJ?95 zZ+cMGi?zPWWdRLVrVqSbi2+j-pvx3gN~%?^ah8@2fY7pv?o2_=2s*zqyq?RV zaOM_^N;e691_tBcj?aP@`>xp9?OjAvs#kKx*fKm4`^Hj(>KRpsEEB#w>S)%yOVIZ$ zUpQWa;!2^#EDJ*J^@*OX@7x5k)vALaL=`RuCE@%Msl2Tp9%7m>-W(Tnmmi!!e9QCL z;d@JbFYX9#?os#QaXYgH8h<)Y;AaSrq5bV%M8;xQEw6%bVv#`fqFE483~c_Y@1!%M4*&ek3j@FO)26u4Tmx429P|g;IUa=<{;aPXqzR{ z%iN~0%&A1yB?M(Bu1P|a4P*EbL=?_Q*7Ro&mI*4?P{OzYN!bq#?H#F>3fisd%4ij8 zv_g_$i3ZiG!kS2aPD!kl0Hvn(1_vnGa#ZmY&!a1WKpW4BLrTf(^5&Na>DvgUgO4VInjUfMDpjGa0LgR~uW7;J7rm?huJ!nxHK$5yyg$|fGs4HsZBGGYa}l@I%l#UMBR z3V^RMNow+t91Yvz8_@tl(=Bo;mnF4iwwkpta^5uWD@_hcmqR-V{v}n++L7xgtHYk@ zK+m}y9kZS0CmEGhEfYWoNP3I1y=L-@!gA!|j6x#rCURZv$6gp|50-f|hKr!hGi#ll z3@VZX;4}zm23XNuT?<((35>!aJ4de|kru?0s?=S|Abihvxv`3BFRh^L5)`He+{*>S z2jja&;yq)I?RR@w)N8;ZCJ`MZ4~wG`=3ODyo45nMa}d85R@>9-;57~a-e-piWVbxp z@4jUs*F0P`HIod@!zqIj#!jHKkum#m29llA6_b!2W+2fKY}C@#yhQT?Cl?CLZe2fO zEfi4;s`TzG3p#&fK1XaQ=x*jGn6>@`h~TYRwr45;*qr7Ou5n`JmNt^$rQLee%96wp z_K?fS>TX(Exl1+FGoer$kkcTj9g(o{4to@V3(hx_7rA0gxY5QwEQO+o_|-UJJ&7!# zyJSbPR7e85#0xY>ladOgMxoB5ACk}@s*tzLrwf|xh;;x>Q>z9vQY~h#*m!utD(%{L zn+y$!YoJ2msJ(&eSUQ(IWtCtd(cBW?KqR!{_#HToXW_Q_J-UN8N&T_>9xaNzjj6Y7 zhL=*02O}acD4NVq{#9w)DtTyi<%BlIyuCwXfFEqOZxm&g0@k1ISh^Tq%|Z!jMDK&^ zsJ3HzWnS2q13~$U>R%NsiA@c~RZVZ)8p)hQpp=j;Wt&PiXNhQzaT|(|3s#}!6GlcS zub$~c>o(fY$qF;T2%#gk;)|_UM|)yE^7fA_@K!R%c+ait({^zVjeQFv+UZOZiX+rA zHbbJlw#GR%$A~RFVrtbYVV)aocR;HxvhvTsg?fW7A6BIzpR)6J0auY@7$G9;i&)^w z020_xx@p!%2at!t5io>J1<}z5l-V63V7dN1tY~5Wap-eFDBwM@)4#?`kBW>eU~*lr zbl!>`)HT)jtzGKT#&c~O#NE5K7j$B}?Mn=wr4V?|)|_zCm-Hq>U+NZPot-3nDWL$BjO3rZHXWMa?@^^DI1z07Nr&1kuK>0dH161!@b0mJIOU=$u2_ zg_#wYWC5ng&bYCXr?B)FwD02^FLh1)tSEU#Uu%*mgW%z)3HGOd$+OiwI zVh5DlcEu=BYTQCliYoC3$Rt#`RKyHtEDpja#==!;bZ^1-cp*sbcNi~0m(){EIO3p) z))YG-nh|@2*UdHffNg_^)}mdF^Il^B*jf~9mXeRlA)w@$`YU)bE0b1hWFAe+Q%n@= zOc1#(_1rdNa^BXN&XQ@8@+p1#KtQf}s4W9-AU%u+OnWD8*;rAeDQ@MIzUnAwUK_dx za1FMM2O!1d+!ILahr@4*f+g%%*(g1rzX%BgV*8|8^|=J& zC>Ix~5S6hC2n0+$LxzlbqUjNn=Z&P?W9t!v9J~XFH-z{?V6pf$@rrS;ypZRMG~HaX zeWDmUOJEUE-WF$Zm@Tg0(&7ia~FJvK?5irqa)#F3PKGcaxw0v zS~iccxIFafD2dQzFKg!7`~>$7px{|y-nJdy!`;n#i0sdc<%~8}EJg@KTr)o4Sfc*` z)oih;K#?5+#VHy_0ZP_wOB86a$jZ(2Wt{CYr9n`V+g!0SSKJjaK_fYFhQER;3#bZa zM;h%j@M0}lCWY`2+EhZH_@=C7t6qy@Wz#r#V6TxN7l6%qY7kLLNd}&N1l}WY{{R{< zoJ)NE7QB2cM$yOm@KuK!z;_zgRBqwUS5+oBfTMfBjG!t|1@==>XB1jT=YUpBm$;02 z39Z$x90G2BT6MmSkhQcadPquuhF`W_1)y`pKmvOnTVQH6ve0&BqdKr9bvEv*U1V)c zJ0Q#EJ=4r$)xo$#vZ@snEh;REtt#J%Q*TeU2Xotbi$)j+0;r))^%}I^JP+Imy>1)D z^AX|Xmu%U2njC|{S*fhmiHBSxD+RIZPco`Bu+nTYxdSXf;94z)P|}d5bTk?;OptjB zqe!hp=C(|tdq!Vqz~AgCG2VE#r;KqMMPh<^-sO(ORInSag9%PyPZiYbunasd3hL?= zQX`ovJB&p2>+%&!{e=BtIMpG_KJsCX$rIP9z$e^!uJ-p4=!u7Iz75M@bA#~en zZIochpy7|nMWsEqaRDGid2IqHIY8HvwHnQ5GVqqKGEy^@8Qx zfENU21_d~RhocZ^;c*fde8C9WmF@${2f_^lS6XwP?@Vp!0en$lSkg>V-9U%)dH?4?5*GQ2aYQ4slA-=}EQ z>>R@ifo95!SxW9U3e{b$7_uvsuAN0h2BAiumZifKW#Ob42nKFYEerLtIHV@!DEArFRopr*3lyfB11EbU`W z!v1vATMH{^cDB!d5P3ycYk7n5V!oomemQxJ13G}cuHsFokUk4v zu?iv{NIh1b$dhYlkN{fw(kOmhR2!vbW)YYlNDS9Fp;1+_jmzRR?gccl&zY?JE-iz= z%q(IMrDio~(O2$XF#~mkZDs1mq)<7Qlvq^Y7#o0Kw@K0|PIPw^iI&=nUeW~G zS}%tEOE9KQ)B#wde8Ng)!>AaAuhnEgsL;EOXNd1h)=Cx@{{S!%x(g_|r3Lbtj}EP) zQ5x4wL9I*5?7SwpClft3PX=x(EasY)QB7gwADUt!rm=05FHzZNGNLGeNK*Z_2=X%U zk*T*}!V!0mP&MK-IY7%(kJ+f3TcKK=h{tqkzhYySs^Ac7K7PaV?yftO^)#ukk9->ztO#^#CQGSz*K#fh;z}uNPd4y4A(RFfVNUAj9F7=}`KE_C`*( zj2a}!9l?)V<=Y2%G{O*SG#aXD#?lg{d=x~hUQr3{Q7c2)T;LdB)!DQ>&`OCJLQzre z)(dV-(*&_7;#~5SQ<~cc1PV1k0hM?Ne%3;rzHyNFrR_7llA={Tp+d#*z)LgLwjp|W zFe8Qy#Lnn`jb7COElsxvy(Q)=L6@Oanq77Z@_CjEzVceb;=U7(ztwr45Bk3f8~*@- zNs3zg+vX;eP{o!?257>ipvB!DsyA+3EiZ=&AFz~)o1ro$L27vm%f|6>;p(OWz8BuO zMO^5D?(0ym7t5kqYvIsZ5CNqF2}PA~UtiHj-E_=CZ7^4S5 zfH7oAkYQMA?p~Ptl!Lmxn1CwT6vt!*jVsTD07C0J@TBH#xf9^+egfx`!$b0vkmCT9wmlb)VnUSEl# zxz-{-*Ae7tyCsugHl%$N6IC-wT8+{gc|(5{hl*A*j|@^_3mqxLOsJs~JHYD(OcGzl z2W+i=15=2ETY!zqh>?c@R#X50+ZQ+qpiKhPkEpu29_q}F-g&ui?yH4~tN?|)6CCC8 zA}y77B)AuL$Y6{eZGg6FKKmE*C@rJKt{^@X=&(rR9$h}=pfz-N*E9Je9%WJs()piS z{$^(Nd&9>yFVICI=C}f%1kvgr3@xIgA{s|Hm(w*FuUHsxIkx`*MX9=Qw#B~F9e)`B zaHyw99uSQkbwvPygy-O-k>P-8Wsbd7y;!9h+ZPR0I!xx&VEAJW$ck+RRzkBG6h?Gr z&B_)oU)hI@a>3h(YJ(L($0)8mmL_W|I3mA?z}mgH(662T3cI)!43tzQy|~`tQfqZ( z3rX1K4@uk;kOY1NhFur;Bv*Cle@mLPi$hF4-9?1}dDN=L2oQCb=9QnfgMtr(i1RFn zUt_E18vg*VNWn1je+qLq=e~P~n);PJ>HvfTnwUx|f~%oP*GR`!53uDINotkDDMwLO z3$<&OArQk2M~E63Qsr1ndjk^g^jEez?Eusk-brHnmBh%bkQTV{7y6YPLn9)T=H(T^ zT9E)~K$pKyLcn2R8@ZDI07#S|SlJtTd5GFt#wt;ld>(ainiel=9}6ty&C|ud+`|%7 z2w>bHMQMsfx&Z-JO7J^_$u3?RXg-KZ;3tr5eMXU9Y9K#mqkdT(ezG(?)CIJPk+dOa zp|1r5d1dXjcpI|!zy@K=c+>~-nh;q;?#OmI4oQeq%Worwyd&Pkl`UyUcv1O^_K8CS z$#{aPBXSM@0FJy9d3D8^HD@I`ITVVxZr4X4cH-X+kXml*hL6L^2PY@96cI*LjK^`i3E@O6h_ zxGEOK3v!9FBPdn_6tv%7BUN(zuQ9<4QAx43s@`QFUpHh(861+XfRu(ONDwZUz?Qq) zh6O?>w5+|6UtCm~U|R~4;tD7Dn4nkqu;E)}e<8^;kglH@9U+#vW+%NMogUHt(jS@nxGju9IR zC3yb;x74%5rFgQ}4KS$Aj)Z$KanwG*VRF$HAedP$Fy;}hXcjM=Ga-sI0n`emj7Kr? zjA{hL1!8V8YfM!`F4LF+BD-+n-tQy}GW`p_OTJJDp|7IQ1-=fA#q#!$2rG@N4~8)f zVNfpPL|YnJ1++?<8GkW^i$GG&F%*D-;Shd`toV0rsM~R7TYRGgTVc%iLcwiGgKpbt)TdrMF9lBkO5q;1DU%!fKGD@#H3zAK5Jujzycznyn=*{ zU?QRP7B~qwC)O#ibsw~~p#Uu-KaS?Fy{HowtASMBUAfIIx_m~BvY_gAG8iGHTxbdh zfSVrfIt&>4hsrg_M{?H&DxAw=R)|%r58#Hvb~PV2rgZTHqk63sEDIFLHWreL?2>baJ~e6^yb(b_(B1#NftW-BZj7DaTZ2kL1EI#?c|NCw#H!cdFc z9Me%N0Shrus&om84XmYN5~u=|Sybx68H}yFL1;(b2upkQMsr;=Ef_(qtA*4CB3#Hi z2PG_iV8`fUh6mkU3`eM?WS5@fmH0!z-|H#_@p~qtHBu%@Jd@Oa;1dDIlNTu-lEGB%X8_9 z7+hB8K5;!MK?%4R_}m!}JF($*6p%h@l0#JENfve3YJSPju@ z);U279t;K0QZtB|%4w{KNVM=-gHpJq;p#D`1xARa#S$foFF>IeTPl+?i=ZDd$_kq2 z8KSK>L>?oWbRkNyZL%~S830|l8FtqMDq(7-vb+(TAaZZ>K?UCl#4WBO(K;YN5178M zVQE_TDb$2))&oaz)Ln#1~@W5tWS!vdv%6rX!EktLK)x zIwEuPNwjjACq>rN-M$W37vZQ1FN4EgMT|>^kRxRP4r93-S$N=X%Y_k?V$lUHNWl>S zSB*luE0K(sHWcA1VT`Z~xs4UCP$+kY2&X0*W3pO}%&6riL;$Azf1w$io#cS2L`h`b z9!WsPQITP)!BEJe=}W>!R*Y#iWJe@EEpZD%a^^;cDD4S<#f_+Gzfq8U;P z9drj0&LM*f^9g&6w{#127T*B_a3x1u1<55 zqc}a7dJMRq0SL{5%|y{TFi5nIP*i|Lqy3~YErPD?-kspYH*}E3KwM#Kh7@6z@T}s@ z@9fMj1iELfGfV^NV(&<0OFk@(RYc?Y4xffR!7G6ohlR`*qNfx;KmuE}`DVL*W_w_~ zWBOPC!{L_%3&!$;r-27`U4RNO(LfM|xSRB$MHc`gcnYv?ZkVAntaU7u_*6a>7{p+j zce5IQWD0a@-nnN?KumCon`_a}z(6fZ#&TgCG-1|^_D)!8Art}t6%cXI&L|c_ zAZbU@808G;2CfqYnn-fVSQ*sIg}@nl!CN#2fY+8EvzJ?xnB0?#e$NCpJ0@k>ZTu3o zcEVWv)v+zqS0Etsy5Yd+0xs=PO3idC$k1dd_=EBU(DDB096hQ45~>2qQA;{w67WL^ zFywQ}e+@*a;1eQT z_|zG~sdOqV(C`plYBIcrUTDj8hB-I5!ELHccCa!*LB6m}D>UXcB?jwtvDiT-nHLHJ z*b=HvK562vm57!e2x-cNXx%HR}z)l3dixP0gJh6E~Qd&?*GM5b7X0FY$75tL=!Fcg8a05Fq2(8(%j zj9L_R8nH{17c2nfHaDeaw}3o2DkeQpO@!(H0E>y9%aY3e^at<~rt+4sFY_-_+M=1x zv0uEf6I)O>;31e=tqhd@7+etr02eKhgo?OlQt)i^e%1`z?6A3TnVP=6>07Y-iSfYyb%1z6Ei2bfNNIxQ1io94r zT{%>~%z;I(BFCJfX{b|xC8FthdTJsJ;gm=6(f8D5t#pREGRF_Bq=>NKPF97w- zbr29(hfflKwbto14zB>$*)2_i={jP9za-4HU~z04a_$SOS1bbB)oSI_oSF&|G1svs0_B=}k z;$P4e;Px9=Yb}`Im0m7(W(Pc0b}vKd+>TEM$C zkOoX_1%Np1Usw#r)^sIN%s5KrW6pHpem^|?VewE}DNafOWx@s6T3O|`QU$SV4KcY` z!WZO+wve!Me&KE!u;r+hUJYS|#R9K{$VZ+e6gHM#%VEK(IBD{9hL|yQ4XLv#h)6h} zK@D5sKwvEWiB%ZwffWuaxR+{8qPXlV{x=BurJ)T3&AFH2qQ=kC${Z^)o!#a(rzYD- zC~5dH%2_$fPIpLw07wIGZ>GapmPZF3!22@UZGdFi0k$AC%B?uQC0KSc>7+fwZZSGb z=BzAhGLcFfZuWs*BIlT%XoZJRgL25bVby6#@2^KN+>5>T9ucO;#;<&@xndPWUiu-B zVYF-UE)La1C>d+TkId6x!BnH}6-U@B#g%yLbNxIi-O4dUkS;W=6GlIWRtTZr<_)>*z}3GlV2nh05`41LtKChD2} ziAUbc@1nu_iowJw!i5iP^@2NA1w)56V7UZqLPY^hcqP!`8hW!)BF7h%o0^&<~3n@lKhGr0$#pW0Q%CUIO zAP_647BCW{SwpvYx3IX}RI*mh-W8qJrG3B10SAyRuGh|I3j2P$n29GC7r+QtIVynB zC@j}LFA*%CmZ5PZmiKn-M?kq{e13`uYYljYVj4JZs01#@#VD~Mu7vI6mxJr^5b>7? zKG9V<2|pe9Ew7$-`-LP#Mv?d~=9!iw{pS2c&u*&YNRS4`Sb0~wO~-Ytd2g7{%lv2hx<6P@AJ*G@yCn58OC$^MN`W#A9b|PA`=D{cFZQ_s;dU^<;BOklU$iEvf**C#6hOE=WaL>)_Ho`vNHu*fs6<5A0Vz1 zZJ=~8P-8`z05ifU(6KDikmlwC!WC4bG_{Yb8Dx4;l=N+V0~z8gtwz+y92qsak-!$3 z8KGcKRTZg#-~hN_6eG=X)OMk6Y+BvQ3X-k`4TOZVZyv0vLBth6;8iq(oeR?_M99`c zK%s4TBY=t(m>=262Dm+4ha}ywHbbKAthE@YAUgypOHfzIti!#&ZXtz^d@`nFEqoxA z7rWK5NH}mjB=HnXh(S*oH^in9YP&TwHY0f@T!mgzj5W^oPDZdi_#y~Aain2RiB9E2 zF;k2X(E&O~IpQVQIg6@B(RU>sEW9oDFUdUFUM1zqoWLLyTPNQk=TfqCSm!#&0~!nL z0)_Em6#)q%^m2IaI$4<9PJyEv!&rXFpIQr}Mr_Uw$cHtJG2hwQFc-B2f5;uh%6?3b zk}d)en3g*SW7zd8@WI{Hi?`BeH`6NQ$h@di(Km9_Ms)_4)u{TKnWa2R&}hP$(}tAW zBy4+2-GyTs5`O7^WBHM)Lf^5X+@y6C*cbM&%YI|^ZX{P;0=!*nADCH6>Cz7&XUk>h z(V0aBt3gJ3C6L>~tl83XcwmA8q7H?RkwwE|*S67F=(b>%D$Y*^FSKFriE0L{Oo&|v zWc#n;qqeoAwZJrdYR^_~6wOX__&B29W!J$WB5-LUTEy0_oGYr5t3m~%{ zYSWoqS#&thm|9yJJ6T0%FWzMj95gR1ezhJpOY#mv5SOlluPyN@Q5F1w#6Z^_cFIaG z8|84Utr~#5aRef8wP#*lMm%zrer7=5PNiPvNjKw(Z7WjTBN9H(Wk!^oq2y-5M|}eX zs6n+fl8NNFqE%R3;=H6p)I+_ho>$E#f_zGKL5YVx6hVKnE*hW5<+kN2AeUEN&av zRg9s830T}Q6r?L6yYRv~D6+-O`9T&I6D_%B9 zl8ZQ_Oa&!ojp?kv8-`XnAPA_q*cn?x!tzF|(p&p&ekF!t%X9WH`j$o(jwxJ~0rP34 z#_+-5Vd7Bog8qnLfR@fPbqLG}b$<|MN3fJ+I7nzE5P7je z>xy5BODd|bFq*PIJb?JJGiX5skj5qcw+IMJm+;E@2qLO6{{R32L}fCV3?rzJ5lFEb zMroAFpRVp`#23O={{WPx`K$+;CQ3 zZz;L8C>d{3xMOgZFBtaA9+u!0uXJKskQILcS7Q#Om!OCtI=@AhSRVe zKADh1B|f(r+n?Ddi z6-~+z&bQecyCPM9W-S1mAQq!m0WiLfW|{+#X0$nm*6qO7@tjkImg_$Fu z?Uhav6Z}Ju7vOa(M}>+_E~C~XjFpjP;RRFlRd#pi=A}8=T8AYSHla&w)V(geGHw%3 zdnQ4lLj+3S&3J5eGZnq(J=*nwO*&u;IF*5<4hrO%%C-f4R2$196-^IQh)c$8mLDxu zerQT7+IcFp+XjIYfM>D311J(BoGNv{TJ}c_*A3f z{twYorAmjz{+fv@SL=UWO8qUP@!R2cZzN|@-sNo(zZ%c%j5J(e{ObEA(glXGdWUi; zp|H}KiK?JkOQsVIik#xhf*=OTdQ>go(ZtsU^RzZy6Z03PR%A|7mq(ZhkW;Isp*xUj z&j>IeGF;q&Z9GR6erbZ?rYdP0T79fpROpfHX+iY@5bmiK!^vlC9L}b4%ts(fwxFqQ zNlEH8N)PXuUG5WI)KIT>WC-*Y!rX$wA0m3}7ddL>CT&?R|HD+Ogx`^|d zR}gu{)TdjgG(AiC-y88tPYifvx+BOnMEer?lvvMKpLvx?){A-R#92VpXaS8q8iJc@ z+?CW(E5*D<+rffqR8oMoW<9O}YHEZ(m(l|vik~L%=KSt8!DJW5D-alMs}L=Sz|^xB z5rS1MFB&RFvtmX~ub^-?LPvFCR>E)mrG;$PcAkDtI*v-f=pCu*@o)!ODor;THQTDJ zY(5@g+9A>11;cM>Bs0?Ta*jaS?Tw9ci=}{pe;fRj#Pkg12fhtfdI*UMf=fA zoK#C|kVegg-KG~nl*`5$2sKLa;>(rYK`{8^mvq=MW}KK@>Bx3YE;mBz_na5WOwXuZ zW8RzQ*@!~~KFPw@f8?)m;8pVgTmwRC5lEFP1gTVfzoGvC1Mq&AQvU!|{<_ckEA<~B zbMRNiTi3(g<+Cwnui`>)uzhYxZV|)QWjmL1z-b0jM@4rWviMHN2@UT302$XH#lBJv z62nlk*%#5Lvv`|grC7){p5j+3g?w=Rqm{KM_910?I+r~qZE+qfmf|9cL=4i>wZU?j z0>Yw>mP$EH@=h8>zz^bD> zD2JK|%FMn^{^XXD29!9kJwkh7oB(r>=T4;-wIIWTk7~-v&q{%N6arKHV^0DSp9M#3 z)}7VXi4TS|K<=vk?DGy4Wx(uZucitG-5MOBrR@z%lsb@EO)bR%!6_6Py6zF%yf5RL z!QrMaO2sv=M;tJ)S8_`MX}YDN0EIp^O)fdCJ0Qd^*|QIF;`u3@WfxUvDm?ZOQw|cK zkZoip9N*+cyRueA()iR=YFtaxh7TC9UMlC>vEb2D5k@w1$*V4HvaOY&49~t0w;mCL znsI>JRu5Tc?8dg{V?_fh3s965s@az^37;ygpZOT*WVQo867SSA~2osha8jFVY|m?OaW{V zjjUMk(M&cd4OI}bmQ&^<&MFQ{_*Nn5cc22QPAMXt05Eo}G&O8!teIEh1PxLa=ff;6 zSWtlG0!JgZJ@ERLRnSn&=5ytUwv797vd#ne)Zo) z_?9|=LO=jouK_g(Q+*O#Ht<}BfHJcgO_vWA1L1HjhMg=ql|O;mTEHB@%qSO*nHQL# z5L;#3a=B+{kQ!1sxQ#ZRM@Zy>PuOj>SaTMO1CE_E25MEytLgaH#WK;)LaVSy*6x%= z;0&y2Euh2dgt2hTsUcu+h3sn#2(&IbHr1v7043w?)d)-+p+m@!>(A++yOh<84VzeQ z;wTCc93o4dLw#eC_D%gj-=HjP0$LJ!11cn>t$lj{GO~yVnNENuI!JylR!ej{7!_!k ziLgA?=4q83(cK!4rKkvxNXjeB6lAwT+Kwh<*ixb;JR@YJvP|7_S~R(9P)Mq@w73d@ zHnmgs)E2@EgsbJ)U;x_0QY9mijs}d^fEQLh{1}8cIV{9n#sajxKJOnU-nE1X17>z> zO+dmZV8-~BbE2ubi|E33pgZ)KFIiNSj>JJhc5w_#9~e!P#iDo!{;Jhgs-d7I-q;Wc zOGvQh-}McuydDBz`-N39-l1AGnF7)92r`exOQNk|+ROoQAAN>M~UaS^c-YIwY62QZ{8 zuO?H6f+>M{@hD4?0^k~+&i4I+GQo+gv3eYfddqHfG8L%9-~c9Q^HlZm^cWv;u*9C5 z9j{)|T4OVO`Y8P=@8-roWe?7;-5aT?w z@MPvFU=c^TmV$P_<)_uxL zO$X6B_Dd55S!Pw0>u6e5QH)M9$$4bK%nF1W(B)FPCW}{r@GU(N>qM8epxCn`WNHqi zSV4pk{zRhZJ*?JB`bij?r5uISFQk(%{J9+JQD>DX+YE6-_>)^U#4fpo9!VRkbuWX6 zY73T2@OJo_ZJ1>v-gS%OTTJmLMVR2lmK$!4XDpL0_Q7yno8pn(2)yt# zPgU@hB9Eim?K*&=ry#EMGlYlheYhTcT}oCZ$(0X!h*gF+&8i}zfsy!o&W-PL_#X(Y zlwM2P;e&qEz#3`{Y!qF|A(F1K&keb@ra$JiR;zGo)WQb38bptAQx4;!Q$7cbDgOX` zHO)7zLdE1U7%(dBD6)=chgCln{wi=nah~Q?1}c}{AKQ)5SiICAI4|zfQV!yEpvwZx zs&)?**C{cJ;2N@MAa9C~OJ@fITy=8bF~uj~(G*Lv(M~hv>R4cRvvRed;WEQ{Jd(*% z0;u(DY>N&9W>*bOuzq8;TL+TA*yd((84TD)g-PTzEg8e6G|CO#)$iTQD{i+Eo4*jT zP}7zwpk@MkxmhD}jF}~-%C(imKwnj68hA$u3?XQ!V6*DfmyZFhktn$aRBgFPgF+EQ z7R07Hf+E*4gLcE74l=e5%H!4`y-*$su%SFP6JA!j#@YkL4|2h@w_$-ap~dDffSiTe zhc{ezQx*RJDhMPC!imiFHeWscEU+5{MYP79y3UIH6Sdm08Ss0$Z7ErFFxkJO(~Eo_Zw(j?-G&^1dIS=th4hWOI~ zPpkqx zoEc#Zgc%~K3RF$Lw9;-lJEEjzXe}1~urB}uCNLx;NC;z)Vk>f~h~tJ}!uB967nvit zTWEB ztLt8TJwsAGA?H<*x@nfF@o;XXA3n2G7|UiwoW^4&6gyNzHqiHT1kw9W`45)Z~yvOU9u%)hI?n+3l$?2~^w-<5?PMMUjseG}>Ewl=P zmOTkmKm{W&mh6}CHh7mxIv}`+w@khGvnQNInY$h}_)tM~8(G!_2PGIPt1)W4yR;Jj z01*~hwk5fYR1{WwcUhJ!De@@iQv#RDe!_`hR<;-hfF4|)+&?D-F3gP~c z9wyw&u0qrWe4D`CADF|xI~tDaiUNTK7bbLzbe1#AFbn}+qZT1br7c&SFlkF^VJ-te zm(igJ3E?Hp%aL#_3a3>!x_LD>S7G%6>oLLFgDGzH2xuIG3U(2-(_1&L#- zDh6Pt2n{++^D@NqefcGIKx&QBK~Mm!(PC<4%1#t)2D26R3PlUFCQ5lC$yqJ1Xbd5M zZ*Xs0R1&GWSE*fEqBQOoTMeNERz9%?kCDP*AnfWacmUg$+Q)G+1Z+u09MzB|w_mUJ zN{mn`UE^v}I2CNaxAh1xUpH~TE!#JA{zCe zQEYSph;7?XwZw&`=Hn=g;t<5Saru5z;=W(ee>eIs=Klb}a4u`~KRT8E0#vQRLR;`{ z^28BfUYJ}Qm+px1)xU&Y$~7xb25(wwKlcn!&vL5d&E)T$piOoTv^)9Ybagw+$I>A?}y7d%kTZ~nxH`Lb{e`ItM@)k`M%|Pfh zEF8IFU#Q7i;+6~?K&w^Pl zRCESb3M}g)d&Tz==e=4raY{ncsglsVruc%UO;W4e7ckMinqhrPcUWzk-Bk3;NvMW{ zorL5PCij$8z^r&()g@0lhk~WMPGK*K3>yu}u(99Ol~Tu1R%V6^@o0O=M|XmXaa}K~00=BS2M9MTEJiUj`O{ z1>&VUdL7=sn2lJcS7n3cN)bkM(o`+Z7Fb`6)MP(wfYxF8`O9j-s01Ijm z7alo3fLM)e+eiFnF%+_wQC+3wW3nmJy#Wo{WcXlVC_UMiN35&qs9wN<{Knhl2I8B20+3 za2V1UE5ms^fycOAd$m^OH~I?TPVCbkV4XO4|#o|;h-r$8axx0X2rDv3ay}PQb z#HCF|*bN*&Ax5_IK?9$-Cb|fYTFm8Mt_SsJza(K}e2@Z>Hire;Rymi7qBc4g3cI>( zsd0mKQt@2-Syx=Rg+Xmzp=qR98Dw2s%Xx?(aB+_1wwfCo{usg}6bO|n!g(Xr)~egu z@xupgC9=d%&QKaw8TVJ==) z#x3^NF~DGp?^NupYXzN(D#z%B2voxezUG--Xf%=KE__r4YUDu=Kkdo|LbFRcPNn>+ zi(SuIVML_vdLUw$Z&M=;OkRE#ti;De?MTzXDR7<#;&>Asq@l`vqy@{!Cq5KIUxZ*r z*?W~7t6P;ldFnTmWFZ_7wWaJJ*+9r>X->$E!RfmSEV2U{ut*0RDpmVn z;lf69R6K#Cc#ZSWpjXr~;G^6?*;x?s1iuUeP#Uyg2n?CRDn97a4FJDxi4?P!Y7gW= z-UR3E7x%5ez=h(X;P;d!u7qORvNJU+EL~={!vb4(YL7Ka6 z`K#WbBV^bofuaCeH<6MlEBA#VEnbMp^I5v(?fW!hHZ{B*GL3cCcJuFth?F+Up~XX1 z)B{+-+dOyN1cj42Q%A0TWnzggb0FJgETui1#K~~|qb(RN(#WDp$qAU&|Nbq483_SHt>RIhS}ca{xb4+F4h!tXgjqeBO1% zd>lj>DNFH!A2zW@Q6Ua23822oQ~;zXzSfQ*xnyDB8_XJC#K%KJVCENLN-fqC%x#1o zpl%7kqKims-J}i(0@H!+5+GXhUY?>zrp?`@PgWe zVM{Zrd4fK3u#99O3CtC8juB-_#yrKO`rFMVL25+m64vydj1wjh}*UdIrJdLp<6SD%5WAyGozb#p`rl-5lAXuFz-2w1N6a~olz?U-oO zn2LiNbjnkuO_mIz2ot*k z)>K{_C$y9ufiNX_I3*&?ni`@i=n|0}1$8zmGb|R0z0327^>7>ZUcPIU`*?^a94JES zmJVjvw}-A_Y1dZoCRVW)l$rv?K1@Hzn`5bYY?rjW(<95emIi8;j!%yl7^ob(eAf_= zvkx&5py}Bx({UH!oa#_K%7`(6xb~Qj$(IR7#}Sy1$@(f~l)_i&sC;B1tgn;i<<4f7 zT}y;MEFj(lryRqA?p`Nsva|mH>NE8XdN1sk9OHPS0fMUsJ(o#EUn;N_mIVT@4=_WZ zGSfphrr^a(&=0?e4^B(ScH3(LSwgxJ&@zyvS!n@=1>gbr%N&8rwu*R`W)|9j7Nyl0 zVj#TeFp&*GCII`3dbR^u%vnv8;lu2Lp{VxPkDC7#a@2n(iaAx-D@O@uW_32|>wlt)>Vo8_Awg09$=3FSO=t zCMv}9Es+jMe*vf~TcivSeDmy*_&^Z<05Rvm@+Tf*wqo8uQ$*qhM#rIfa>Z>{By@-q z3*-RP(c2X76VJI?lTg{hTIsQcct>ra!WZ5W8I$PFS6duVT7Zli!xfi4#KQ*pYw7}Q z%!1HInmL6&N&+n`@Iay^4>9HXZUs4TnCAs*Qsm_Ml4{wTf`!u zM7UXXR_b2~Ew@?i3`AO62DF`!$}a(cD%w)jZDQt10#bMkim#xLFDM%ifz3bx44bik zdz92PU~Ug|g@8%&39#y6>eN;Mgln@6m_7Fg(bVN-fps&}GAuXK5zv=ayC__jNl6Ye zgGbaE$JoU?HwduNZX35_a^=Sm*wD+Uzbr*)$;MX^1lbDy@dF@{kQdumDm!IItaN{J z+j9!nCgM3NEE&8I3$&#mKlu=8E6J&iudlhQ3tyG*6D6Pw+)a!fa|D2od5R|QxNMzs z1qVzc0YvhA2Tr3ei}+b6bi{>|WU=rcg_rt5Rv@o|_&7?$702kge+$2d;P^fh<@kOH ze;1jZy7TsxF53# zO@gKbH}@M*XxtG-*cI=dTr408t0L?Y?vP}Q?kOXT(BOxg&xTe~(+n}^RY13kkjeu< ztWiV(oc$mnV1<7ZECF(`#@Cpow%s5otV>0fRrL+ZsK~q|n!v^@V#TAN{g+U)poM!4O zKs*_F)xeZtke^)i!QNJwI=V3P7A8ho;Y$ys;uXi)fQ24^wg$AILhN>UaCV47Wmx3&*B?3;oN3syaNCn2Lx{}z&ek(@{X-@P`Ysi zYufrHp{FLU0|$uLmX@sZ#j#}Uj+@L>09_l2OI2R@iSRQTN3t^hE@c~26jb6Xl?izL zA`@@H3jPM7pM!=FvG}+-n|uwxHyFYZ+~f7RR~oosDR_-23yG`BxnF=Y?kbH27mx^~gpgNOmZqq) zyd~ah0<`}Cb7&c`+tj|(Je{1T~WaaCz9R|g;%Dbo8TF4it=dWFamxlNHl9r95w8mM3$uR_sJ z3gCo8J$wSA4-g6jCIv5K?l%Js8s*)08Td&AR zs@&0#9H3d|UI{t@qua~(gaoRyiv}BrbFLH^oC0M*9hgL@H(Bp7C8%T`CY8jg5c|zA zz9mjDz>5&i6zSf{#Lq0KnjBXF6QrUl7xL+jkyb1Y zTW2065rd_ccG+9TqG44+j&Bw#BNw|=#=*9SHGNbuS5lW!u)qaivet10sv8Um1Fh~qKl-*-pRyN%3#`u zZVV-SGX5_RNKzS%Mh-q$$KaLlFf6kad>FfDM7?Gj7C+SB;_bt@!4zaUI!n435E7aU)Fr9@${Zo1|Kw6U;#Om6lOQw^H8k}Mg@37Hyn%Rn=b z8)apt2G`Rikgjb2s@p`*rF`G9UbvWJCIOAD#$#ck@@cFH&ob7RWMh5>uc8)cg=6_?GG8UM z9_)Z{`%m2owk`$keGpq~$1ED2X#pGP=TsE2M_M5`BFED4B>*go41}T#KaIk9miD^yosg4qf)*Xh%`71#Dkr%YFg0SK6MfYLt9T33nB!v4s4}UQ7d}a zXEC?f2w;fSfGrk2qwN~K#X`<3mWnhUP37vMP@t_hMYI?@iw2-sv;v}{&ws%Sc^d*luD` zXF$GtZZPS|WHp1*M|Zo!u^`nZU95BL_y(1iab{)}Vp8UDMH)U9O-h@K8PhFTRHn}) zq*_-=%t+ve=(v0kW*J0DQ&Rpe3}1oA$tonX9HmAaM=oAv3T=rEJ8-!0rVshCmmY#+ z!^sugWpLaqD-xHR!ow=sgSr)F?XDwKv!gf_i(Fe0o3tW-EJfl0utG8bRugr%RdJ|N zqmhSBc$evLR`+TF8Emhk3j$zj0@<;|DO=~KhKF#sSSt{xR0<^m2x2$bG6M$E>p!!# zHx5qGRx5ow4-q)wQjx;sza+l2E>a=ER9Bf)T&mjZO1zT-YwawzznB!x8#q^NN{T}A zhY-@MR5?823fkW?)ozBpk<}>yEyCt4fSUn>ZlZ#foJ1LVrOrU%j2-n_s5Em4E4xiYMP);nFDX8WJ5a`NHYX|xU<=BC_W~6JQ9ygV7!g`vP7j5+U*6+Y zdMM%r5?igMx`R@Hh$`BFK`#)%6P=SvLvdwIc@4IW?7|cQCeSMnW>~s)NP@c+4sA&6 zc{;8+k9*-tsK#$dQ~+pV#yg9#;vx6(dsf;yHSL9b~E4vQ-#z?lsM#GdhPHGO! z)#V}9;Sy3()q!3w1&0GKj+<$+96F~pFe4GUdT^oE7_x3vH&s16eTbxxA*52j?ZnS8 zfVXP&7SO8M0&P`9S_NKQ!=C6cI?p8oh8%M-Veoc9;0S=BLwtS1JM^pyV<&Rl3P1x) z&cWJdqZw2LVvg-{s*W+ZpaA9;{wiD$kSfHXnwSBNY`|d_ZHj-w{17Hl*)wq$!znoZ zCqDrXf-n!ztVN8dHS)9K>S8KBSrEkKnoDt?j)nOA<>Kbt`1}n|_`Sdij0jb3BNvUt zesTw#%k%(01;bmqfCQ`tm3Sf7E^O#bHGY!$frhTYv~ckQ=@UrYTtULwX&l&|hfzj$ z%xcc5`9@9!xFS0eaKu2)j&#FI7uK<1-VsY7#KRy6_tA^Vw&wdv>??H;5jKk2kApcy zKLrFbqNYg3!I^J0LX{HNBx+=5C@qk5x~&pvHgQ==DRkgNlSK5@z@cEXz-YTMEOM&w zdCXfD;=gH4;XN{<<7y8PKz>*GfZ}US9QuWHS`Y+)FIQ89LQAkI;#Ic4)VWpxZc64C zo^IeERbS>cvY|*_?Uu@g?nDU4LijFYL9rc$l(tr&3`rIM;5Z>8mMvfwmC@yv;syz5 z_&q}HK+B`J<|FSipJJFR3~52O(7go~~1gur*IAa5O*K zKdP)-`%3|1Vy}6PVE~XC0hlhhV}at^k2HS4^&K$Wkyhk%w02oZr%;J#v!Xa<_# z7t}^B4J^~f&$zOLePvKwLDTNy4vRZ1?(Xgq+}+)RYY6TZ+zIZ!=;H1YTsH&{kU)S0 zmt69`-*@Z&yVbR)=1liIr*?L>`^-#Fx7H#Yi0abPkC-WYsvN<>Es{^qK)>ziospgb zdP7TvRSQ@`FoO&zGgxPs?|MEG9*)oXoyk}SFlptTq^q|3Z`jh)6H>uFZ9Qbp~QJ0~4Wfi343Z4Htz&XI*!6 z8vVg&*{TsVoU@{V7~?9Hswf3kvfdajvHUbHrK{D6xm>Sn-U;7^8(0o;L@myR7nkOSty#GjO$S|c+{1 zz8b9->nI+rqn)WFOQsC8=3^qZo$otL`BrX7wi5%@OCoIEE$Bz!V8sf%iHdEjq{}eT`ha<2;KxA97W9v{_;Ax~|WZZDT zTZcy;Y%jfdN=nRCPHT3heU&8A5^K25B~1X~E%~=FB^3|gFYj9eoW3^EU@T`P7V4vS z6EI5hq~W8&z2#7%AsxG&z?ec`Oy@@0wUkC~1jnV0RL6+^W{dN-$rT$*)u87Ov@ez- z%VyyWN37tS_!GfgcAXM&l+Qs)hAVhRoEWTF59Pk^nk7mrR<$yPR)iszew$K9!)3G6 zf5oW$NchTikKZIQo@-gR*Ju%)LUnVg-kgo$L7FSC3yFsF<{Tr5LZC!PyaekrK^wG- zc!G4o;VYOoZI8)O;MFaPdaKF#)DW1gdfcP5g<|=TyN5FK0#FMIJo!XXlx(wXBrgeO zF?@N*J)x|!8qLv5&5_b_SIE7{{Ywpt#a~44SVuBjnxzZb@SGRPxeSt~5#5021J!`$$(O1N3 zr5oA!LLOjW-=cu8@f6DP(JC38^c=ZXGd)xXODmQ%b0$qZA6IDDYC@CNAC#>=pS$Q~^ElyLQdB~CS@*`K5%OXQTor@#!nzEnN> z9bHdRIQgZ{QUU>FMOf&nA~M*86gl7JL%&#)udqrsLChsI9BMielW{JjuPy(0XqH7! zS+=2e9IR07-??dqo_XAnbi!y3chMihrZpO(1OwxU!a$!aFL4R>+fuaIW~y~%X)d{6 z4P@8`dlfVq%dRvh#)eG>^6!(UYQ|rAgrbQ?xR3QflPnKfqfY0)4poWWoL2)UjvOtD&vZR!+zkW#v(wF{rsbG(dKAlKl%kf9`q1t+*!p-%@y9-TNy3isU2RpgJ`bdyM0}5BpW|^AR(J`;ePl$;?amX*6fhR zgav)D`J$f5qClK+16N>Qh$VR%$B@xe7dv}*iC=mJ3n#EZe zH^sIML;PSL=%#9b)zD zJgF9*Q*QZEaTFe(%=>Cx)wPZg=mpqegj^18nbxTLlZ>`H-py18^xP%`>NAdGscan` z;AY9{us1b0!`oyvCTC`+hlO-G`E*2^Corn=N6dDt*jP))$@!RS+qgH0lrT>;R}cD{ zaaCJF3sDn4BPh|x1xeaqYKMzw;7y-r@pLc_ds2HbcCd}Fw?EnLm+ms|0OzfmK~BG6 ze|~4T)6<+0Q4TNJm`gkRg@qH9LO-{eO@=V4&FqX}&ecMK(Qv03OCh3LA09?FY<0nm zrmGHp$`a&Ea4`flCw--NYr>XdWX2$kVl%S!$+{vF26ZJ!UlHe*im1tjVzf0c@BqXv zU@Bv+xv#l^D#={9`+ouNP--om^!GJ}2wveuxKEz7S-zZb%gsWRtF<{n!zMlV_7a2y zCgL22cWgvTG}ZDr0x~5oouhvNWfQxWfau#WtU*~F!9kE{ow9p^`5?0| zVP=Y~l8UpwV!4H+iF*dX!-~uL9*Jz+INpTor%WrJa;FiJ5Kiilf#)&%&;0E7trw`p zkX@NXmmd@fzz*FBH7gD{_>?|)eW5TXd^I^us~&~e;nE02vJ@6NLUuNoZaove zW9S(B6zmDq(5T1sLlMYy!nEiPf@OY@09r9=Y`jqeneL~fRo&`5%W3U69TZzM*IN_4 zI{xJ!B^ljXaVdKOaMT55m8?k9D?9Px?|S{;(`4unD(-ErMilKhFxvoztBnp?G4Lx}BhtO# zVpAxxo(8=180Vpwq1wqTLYWx$9{cR`W}}01COXrzQwF<|kv3XcDF&i5?~W};5Dl`K zLhVeOWY}-qRdFR0B8xYATYj9xXBhZmSVMcNY^$hV>tef>l2n4^x;lG$hpHbo@tgy~7d&g2xi&!6*$aPdX*2SFq!M0g^NK zwzABd-m0_kM6c~595Ywugjfl{`;d2*4pHGJQ7W9Fwqyu?tlm1ilq(-gMvRKS%iLhLQM$t-=Uz|Q!*a(11~Co z3keuIt!WqOE~OHbo*o@+^~b^7cSz7s;aw`hTY`I7h^MZyAt_%TYFKe0UTqWC&!k-{ z{!=ni%;Q$-XCZ4R8=}x?X%Rd_enjLbg_Pa5iQOUC?%?yU7&h%}R-JTeFI!$$k%WeN zgMJ&MDz49x8yM1GQ|ZTBb{CPG$>GAy4tybbHel z434KdxODZnjnJo=ob&Kat;QWyC&Co;F*$5X(AmgX5{JUxw@9k?4vl$@s@DOn%cM83 z!vItWAD(nSTjxp*DGHAWF?tUvY{XLd+!qgi5W=P=pmY#GNvu75V+Ue_p1xZ`zQw&sh>0c9~2 zWmr>M%t6_%p7Faepy3r%5Z{oOnPu?fhT#Mi)GZ}0X5<`Mc8*4B4@BXsY}ACa?Y`1b zT}phhNyCZ*I0)onX6iC4T;;sKwN{4r<0CCncgqvISOM&Q2%_bO4v*XT3))dOW5^a2l6;y{*y+SO? zO;&P^&N5j^-NX-c=rEZ_w)$B$aeBYt^)d}#kgzlzm`w+m(~**s%4YkBGOr!L9}zYa zyC!Ckt>BxYae=yWkxlWn!5n`m39l7GSb~XlFIALnTRRE#byMw!5Qbb`H4m;Lzl8q< zh!?FM;||6*fcAQftSVu>z6J~2*+BTUVQ`~eCH3M|J`pP?#A%|_x=?xJYSKw=o@>oO zIsz#3rch0EcPf~TQ*enurM)J78v#hS*02SKH>?8IIjz{uaI=ot`H)YozxapXCU=*n zKk(F9hGvc3{_jbOZzfkEuve7RV7&?auNuXi+tyb)!XdT2NuI4 zUI>*Y3`$kl@sO!)7gN=mAg#`Ly5==x&VkW%!ga0DKjehVzy#!8TX=P)D#=?&uNB4U z`y0OF){)~O(HiUgMTH0WO8t~$TmYTV)+$EBw>Gnzgl!_tATuW2y01PT%xMcWFc#AVSXKxGj(a#Oiuf8vFhWefXMgTUVblB*A8s2I344P<>u(;Jw)G+}lCtBRF^bnhJMZMB7 zWldzzvnJ+LC?KzjU+#hE+&Z3GFT41-qO*gYWT*I%%2RrwiQ0E2$`pa&UTNP_iEgdq zgO#Ri09jd$(HUFvZ%oqCmAVf2RmWy&ZRb$r*iPcEckla;F~w;(qic_jBXw>xwH;V% z$98T;Yn02fbCuiYD?>}G?^~*9*(D*eA(yE}LtoK>MY6bArUeX4 z!jlK-bDUbjn*7m)fx=^`!U+zheo^)x<`+V3rVsHr;4Jp)4CLp;f%M&Ab`yhVlddmw zGYMFWA#m5PG3EryFQ_W5R`vT^fc-rYIlVz*Q5Yf(R>q*HK_{z~s@cxF=fl?6dQ%rs zLN{4gNsA5UU|=J^^p5sR3_2*#;rl}~r>&WL%K&_{5sYoeqm(o6qSOeAi{!no3=~F7 zQ&lcjkF+L1F@ANzRlFZv4hA7C%U-UInizgi*s*KMiigEBepBt^V5KpHm9wo^3|d7S{!R6HCsoF z$-uTs@<~1y%s*YRQQsZjnZTN~h{F{hb-m9==7ZL`2h}uCl&_uqy24Cg{tzql7cd%- z(Sl1*@E0K46{I@HLU}(+3;I!;FD?pFJjY0=^PvJgnp8?0)=xob_e}=+Q zx^U=!e;c<~4_c(eMkDSP;?;^oQ8{D3iVL_4a5-;nkK)tDsCuFj*qQqt46K%xfaUu& z)-!O7&YM-yHqp!E1+I9!Gb;tIHeUfo3qj+1N+-GPp^4@_eg)JYw%;)@EDuO)P zZw%a#i<1vPn*Da!UZ$x>-VUXrPe)he7~jsy`IB_sk=Y?s+KUqDwV5I@FzmT*q-+fxL)Gb_i0VJxfERM8y){>kR)Qz$X%kz2zM9%;A8t1S(T z2<07i?Prl6znQ`uKLiYPMgIErGJMhh?T)eidEkP|WX|nnf_S;^FTnF4ALfJ1*f77g zki-R_YG%NP=i%_S+t=>_zkLrbU;%YSlsjluMDF)bVV~xMUXM&g-Likuyn*~JPe;DE~Vli(zv3Cr8{^)nPPqx z{&7fR_Ch@2_&k=$sqvZ8bF48)$0J89=EaX}$L#T!=l53QBk==YOvf*jz1r3vMJAv_ z&x9{Sql^!4Tjzr3Z@mPp8#en3=(k!Qv@5#fDDydeol5P!82A%g++pxjf=jY&B;-+6 zLvFzGDLz&w(*o0v2u$D9n0i=* z?NgsWSg~ZwVGdB?F@0C(4#1r(l)a{_V!h@xsUMlaKM(H(w>lGLMaZySm>u=C@^J6Z zBYQ$sOgdomW7&Y-&CrfF4|EaT`Bqd9ALQTG3Vy08VJ5T(E&$Q)Y>xd+H_x3-Hy3;r z@IhUyoDle9s!N`$G4$!a!xdFoWhg8gRy=m&H^-Zh^Q?*N3@pnw?l%4f(>8pqv={kf z=@VQKEN+*wXGLGL&QaER*6om2*WD%BXpL6!YpCsTMVFAT zV8!5=q0~^IK{@-k{|o)p837A;*sjDjl3PhGj!6@DR6mx|k6`%GWuj7roHIF9Z{2x*l`A7dPJO6|G$NWcc5BLYm zdS34oMj;}Lg^)iizVR7#punTmgk>^*5P*SoRg|Inm@e>^cTtCP5pJiW>0u^688I_d z;8kK`YQPj*h<)@Mm@IK4bS_!iM}QxcANunzU}f`HmnJ$2L6bPFo_I>gOy5(;OMan! z(G-PbC=ohm0I9fz+mFD66A1?iH>>dS=?q3o(w#2zjiSS~7dT4XA>o^Ey@9aM1c@e@ zK62HOn?Sgi#$pkQh~*t8l=Hs;W&4dqi3~UIw^>a`5&f%`1&Mgx>&qYjmJgj?p!e|e zpqM&1a@-0KcMgN(p`J!s)EwLW=k-g8HCSwv@=r%l67GZiT_eLrVg7^E>+ua=wJ-G} z<33@q02;FKS<;uYb$$ZmdTH6C!?eMl(o#T9wweL_SW=6Wx|VGTcTVT!l;1E{sBe0h zf56LrV`<*pl>w42=7D(7zi7Z8vtr~=>uV@)tnng<;_e2NF7fTW^X^)aGVIr)0D$w5h- zD45qu@W&Q$S6A0S2e}v2%7=Ud zrpzw-yAP`mS5Z|x_~s=E}^45tnN`Et8u-S3v1`(w2wq+ zj=q-Sm(NW`1{KEiTW5jTV6JaMqpbrgGwMl+hdV?Cu+MZ_dZ?Uyum3_!`S6kQ^0&c#(_oDUAluI9$sZy9xxAek-4F5oKp zpoY`;yOtU8%hi9o|Nca5)~>-kKsAci36?EQrhBZ$%qHk!oR(B8D4kFBp$ZPfbcQJjl{{iL|@WPHrn`EmoV zH0?X;K&62C;}F(z-A+Z02&?v=jyt>4)#zQ)N*ZuMrPt^zZg?KWZeVWhHlgx9kLSM@Gp0TesDF7zWuE&Uy z)yx|_uVTzW@jivWfNh??01Dgtz*|!Q?ZFYf>Uu+PF68Cxfu%jC<5@0Xb8h9LiXxF! zso7&G?^r+4BrdRvM!S~W`?)4Dk*&&ly%wp7hpI~cFW?HY_|s_JUNR-v?}>upI_V-+ zeDnbs-XSmDOoZNJ;aXFDdqn%I4?>9I8rG92G1AI%2kx1xTu$coQ9uhbHkJTw0^@Pa zdtIp+rW#c`(oQ3zZM-N6Qx-#vF$c+y8x>M?VXScW)EQ=9?|aH=1-lYGLIIdVmZt&C<~jp0>0W~ zM9x{J=bhx>uV-Q$9DRxn$Lh~6aZb^#%hecrJ9Nwhk1xLbdUln++6oK!Vl+M_Se=$O zTOdD}|8yvt7U-7!3wTf8`F(wd5=d0v(1#^+%qP{?G3mX9{+45RUuIGJJb|)IK?Z_y z_=xtW6(UFd9A(6Mu>3igFs|{yjk+T4I?AlL#6^n*q2S7nszHDg|099!MdgGml`k9Z ziH(n_6F=pRj%bqVsu#OO+w$^<4u_-ExW&sWb;00|qnPWz%Gm2Bcly`|y58&PU9{KO zxd!-E$JQCuHU=|)GicExr5N1L*LoajRO=y#@XTyY(IVDK{C0mqAKHaZe4jR7kyv&* z%x1OieC+VmF()^teWCg#Y$RFRuS)7q0)=g?2Fs@v4nEIkYlSBK4bn zR|@vBK%4iHA5*zK#)?}?+H(YtO=!PLWn{IhB`z^@DMi_esLQR?BDAx~f4EOZ)AaR) z_o$7Y0kQF}ehOo;eu398=z;qg0Xsv~+N3yqNHN;jy}}$4z8$Ef($bUQ%51X~pg+Sq za`lP#9?zg7E09a1VJaO(bENtb@w|E~is7`TZ@PJmt-XhA2Ov?o&Q#S>TlzEjiu4}7 zsA^q8t(Faj86R}I8vEhBd~mLcS&>$^#Qgtg)+NSA?PZM*p4-@DKQ!g5+Mq`ztpl?g zEc+|R(M&s|NFQ>MfHkn0xrxgz=%Bq)Jrx z@I3xmkyxpY=%aJl($HZ1ZNKP@TxBsE`4;&MGyd|avynC&VYO7>L4^~abrU^mfw|Tt z!k$)2ILIVvofC-VSW`_n3&!{Vu~IZq(b2%y+99vN?czcvm1MTP%mG9%us2RI)QxxP zpJ*wrs#qM2>g#Lprs7thB?6hq3HC@-{Pkj5IKU;IkX-O-5rr9V_%clb*btc~N85HC~ z#4KILH2^Z+(>I4}fy@Zqc(d;7t$e*vJo!k=34@)^2m?z-p}V zNlsB*a=kif_rm*GZh*bzt5RNbn{Eq!zBc=p8xrK;)JiM)N=^(@m3QXF;~V0x3W5(L zqlYzaq`I4F2)Y(n0iTU5Lm@X~5#JV&rz#K~(o23cJo?y)GSyqe4Afh%y@umsG(a9n z-2AlAf2j4{uFL4(D_9G!9x*Fr3sfZvUmAAfKPgx9)VuAnugfvqD0Sket!}{R_<#8e zi1|1q@iJa=f(NU3R`nv+b6VvuxcFJOP76S~uCq=h%!Rbi_dY?__2=0nkd0}(w(U>r z&j9m(Mne9F!88gf@56OGzH|akA2VV-3v-qG8t>%U)(YJC0r{DxNA>-g`ul7@lO5dr zp6_g3n09Pq>vlheYp=?k+A&KE{5P5Xx5uh`r{$u1;6=U3JOG^8U;DlAnk$R-W##Vj zLKP0>qmv_$p$kPtW@YmU37zj;$+a>hXkL<->+c*LQ$J^$^9uUED=^H(c9xSZh<4Mf z{#2p#EyihXjUVZLLE-A>t0(uo<|@bwlNEOJBgHfxK>A)Io8WWz1~{ zqZkgjT@xxQy09}SwtAMMHn-1wzAQ;e&a=DkXw9Ose4sm&rw+O-mPpvcdIg17wv**N z)no|D?eNhs5Xd7NPRV@xGJ*CGNzZ3^bbn#Yg00HYSl?!K|D>VSs*$~~3hq2usBj*) z2W2f%g}y;NXBS!|zT1>^?8rZ?Sei8fq9Iu|#*7DLj?9lC6uGgRWoUVo4 z*F~NxPgL#4>KfFr?kT~opjuR7fuzawV>C9S+>{olDmN>~%y%;|DAls4kK zg1iGV-g$0LUskml=6sJy9gAnx4Z3%I@7x)&ei@y>!8e~gBd%cbE}nE%H-m{fRns-S zv)Kj_g%k!OU9C~i3<4zp>)+@AqFdShdsqI>dH;rF&ri*Xs zuH(=fborQS8^i%BMGqAIJp6mOS59`kM9;@)@w33vInjlaYw-wp*b+uwH}Ga2tW7>t zA{T&W?Y6C5Lu2gG((77b#)q%}AKgf6Aj{b^>L84Do9Y6*LrL!rSYJ8=dxz%jKsH5(tw z1G$VIOh|3 z6|E7#{y&ELA~kqx|GWbck)59(-}sCs7>pQH}k8W>QkGP+t^o!D z8vBA?+d&tlBHJ4_#bUN~5 z^ghjuEZ&AeD7G|SZ3p$tqULwkm#@m%<*S+T>8#4D>y(hBYY=>P%*<#kZFWZnPXjDF zl_Ik&&dR!lJQAU@$0I3D(C!F=;rU^@sII{$W@-b&4Q28S7ajzyiS#HtzRfu_Y}YgU zsBfW`lRslSqW46qtav;~3vzX`&;vYdyNn|VDE1T^iF4#2{8bVdaH*5rTSV0lq~}~A zTzx;{)$#LQlbd7gL<)RJ=r(E?Jnl+xWwu~SgkTv!D(7WDdy;z3?-5Py)od(n!^rc~ zb>))&(KL>7KB;Ju#~tW|GNUWOh{K8)n%hSCpjmvmvcan|JWp>fX3O{S8~lyr!)tTX zE%9|9z%AU|`l>4pwcD&LS{nshe!lT%h?%mso1~28KcnChcflE)i^#=9Aj$F+7Tw!j z{z`b%cbH-Kza*2e4FGZ5s@Nh9LI6p(U>ciww05439w>+t6iKGY9Oj3hC>9Mtkr!mDGr+Occ~M=?i_ceKL~yX3ZBBoFE^H6@NEf>y zV=e=1XBlO3z!w@~8 z`kNL(q=VQ75-X)Y6hPQA@2lKK@f?7V>61udE_o7Te8i&wwwV;?GnDy`vnHcUV{VbM z%&4jL_xffCHDz`D6~@*s)S=yQ!TBqcd)~$Xj3_UOs@=I_6mb5$_tn#?NNx>`@s!u9W0^=A%#!@iH$aU}-x zi}~6e{{=Yx1vtO0kxZF54W@m;=!aP%o4_!q*6)75$o^bMQ}9$xjiI zUu~^jyhqZS1TJU3Y(%a&g<32%Rrr75N)f!q_k$pguHXBd4r~l;y{!j^bk~?a`8)y; z_sIJ0!%)G%BqBImh!nN^29Oym2o4pc0p*7;Iu{Hm>7_do%fC#nL?Y}y zVquO_lA%a-?z#IV;w6c2v+OgU*1+wLKbJv@8-)w?5|UR|TS}3-wwGsHsP-JcqUe@%PwGAt98ye#2JJsjmY5cIi&1)RtPHD)6)IjAL=;Hg> z%~nqr0+6J=m2nZyIB<`rD-2fdzX^>KduT~Mg0O>T-y=fB7sX=Z1zS-b zaIXk=C`aErNb?;BMj-8eai_kgcXIaHUJl_OcyIT|mK53dFTh7LIOc$_TI^NzEMUFq zyJiPp1M)Nj?8K1VC1xm`d6CRdF$s#u0Bi*U&cF$Z1R}>`3O@oYf6LpLzW^!4%}@X@ zuPofu4JAV_^xK8_9hXE#>kdS^nJ@IBoW;vL;4ff62C3xk1{B0I8Hs}oAP*eMV_}Y+Plmndho;*pzqt`3K9>#-B5e*gcYEl&m+3?M8_4VeMcEah_cXr z;|)iX!~wN-;PF4Fh_HeCH^b0(E#8g0|C8Q*gW3GtDq`oGc+PuHyzTgphN|EM+ZdNS zmOJcS2BZI>l8|hXn2%@0z{!?nE;1ehG?gL-a)wTVHLpXouYL!sm;9lKIHLUX7x1>N zA%zWi+tYx9M}dWhLxOwT)d0W%V6myV;BYj7Qd+4XYDw34AkcrY#}x2Lp*6^*2J zcxlT%g2f&lPx|oX|7>xfNC0H784KlbCrbnH)Y&6{{wvlT>RdAixD+Y{;ETo=%BfRV zrD{+9VMr@f{9o?ozj`4J*ZW z`LXAJ!Fpyj{c=iwas9W=|32d%^Zz6A2K+xQq0|3?Vzx2BQOsDIZ?Vs#YmxJjCt22l zOz%rr#f5qG^UA!A zD(b#kxjZY0l+N{Cd3|a9qzta-;f$U=y0(zew#l;o;@t`AJdvj5|wACpGXP zA4+k^RSdN|+5X@T#GT4;K+rzKb%??(t!8roq7cF~Lt0TU5 zaXr}a00E_rex6>>6-Yw8nzCdt;5dUQaDXGK$%wryY(=Y+sdaSN$6=s{bz}@SZZi>V zGo9$#D6EuPNb1y=YrF}c<8t}a=THCXZc+oY??le>H-FS9j}d}cp37gdNOMWRLt?#I zB7r5=e*x{*L~n7{CcbA{9dkLTe@Ejfc1`x4m?g*BsAqtI5(G;L-KaOYP%knB=HXtR zS@ejA>&YO-h=^N9V!A)E`ugD_ zrOE=mnK}t2i6p6(ZH>O`Imm8?B>e>}_PmeFxR2aK!2O&GuO;ncK2vH4u5}Qw% zVUfpixI}Umd&H#qQMYJF=sxc=qfv)P+$l#nb1(Y~0O({8nfm_Zegpf3rbowXtB*}( zajykZ7yX~8M-!!+$&eSU6lx4yr{&Ngg1&2~73E}LG=$f;Q|$Z=1ez=utsA%=G3Q?4 zL^thUcC@*^Jiy!S?{&_Fqc9T&P9o*yoWCio15yu6;uyf3lSt&|#MukG)I)q$AOvqYwvxTTTq}Q8AfAQA7KH3-@ya z!*@T>74ZZLX3(xo8QAGHkiVmKP=Hdu!q;;pfe_O+8y{dnnNhJuFaUu+;fzkWXsR$i z&cfk&YgrwR$d-pGR2`o!rJT!c1=7#cJvhexoL~>d^T6sdt!9N^R60M}kIH``!x}lg>_2wSqq7M6c`Cm6Kp*13_az)xHAU(1uwQ-I3PjPr<*qsF3P0S zhCsx11+E`~b!=NJAAXXJe|h`jdKewtNHlG0bi~;?$Di&(ASLgRQa@*jiBq@V zn$T4G{o!b75J14$ctxp-jujN&NX)6elN2id2!HHKHJ|d?8j!zMUKvjO*!RHDLLR-# zm%}R;PH{3PWqA=x#9B;$A%Pqt#U8fl-XaJ~LY{|Z5i4uQjw7|hg0fNX>I&w{V5R;c zWA&k`Wrq%tuar?G=K@b7UsZcIHU);h)Q?plZ`|58+~adzg9Sr@p_Ra?fgdczUw{&Q z4=L`migwPuD`hIDx!Z3l`28o0Mx;ib!XX2BfIM2wlMyf!9^tY1#}0Oc$7Qd4l$#~l z%ErVn7zewH(%WGj?hG75U0`-#u`r@uF^l@q<#U3 zJ?lRfs*RjeLkdAOg;As71ZxyF-FicJ)XtLHTQyKNoxM*ki;=#HHICcXiYqxx0CcVD zTogOJ4yQQJggB^6z||F(%I$>)ptJ5UP{eRBlnDd1rSgfS+rcZ=;Du_sTZbgZ@^(cG z$SQM&0qxWs8m4x%;biMd^ORUE1wikZVt}7mJW-OI<#$2B$`rpLeC73I*7Pd8(7UMn z^Zc-AJ&u)-tELy3UStE?l7{lw8iV^7DMg9|QXGZzdwD&YJmd)M3-Fc1@+J7&mhb=? z@j0&D#PImr!3_1`QLoTuPH-Wh8Jp5JA@1}NO!-#Q^bS-a6sb$hEWEUxhYHxM~?N?CwqUv#qJhJ7I;R(%U(Q6{*cxAt-&Mek^z{ol+F|s&jAIHykR;B|#U9GG6cKVBp|z8QotQB?-y=V)KB}zNu_0_=o_H zbigT76Y*?;A_$i>gHY%aS)ueab*Wi4I~}I|T77zTnzFs-+w$SZN7q_fhvdM&J z6_Dtal5BIM6PCY7PjKI+TkOL%N>EvnVl*kOdCTJ&#-j}d)*t$L$RkGxM@mwL@B7V0 zDkp#oxHAqOC)u1!E0=4hkHG`6Zwbj^XX(llhhdQ9@YB_n#i*8c-iaeC6LVZA7lwjU z+SFjzE;qHHoXdpybrQg=J4sSz(>0pzk7dKDQ6WaW3}GXu{@x8`?Q3OQ6rRJkub z@Sz8D70C6Cu#mnEWcrg(9)v;cx+%CpB|?RJvGqSsW%6-ME$;yGzb&u}8sJhk{|)Dj zMqnhqxw=OE;ntNKZmH0_nzjtI0S5)wy;kg@dOQnW_2}qhZdTYaIHqj4IevJPGVNMd z3l(W!4NPnCxE3QD^-UZe%YM!&CZvdR)Jh}}MX8Xvwv6}@Y-ME$e_hC?Xg$f_l~ zM0*C=bQ~N{;I__(qKYkmWAm8t>uv>Po}P=x_Ny_%4dz>zSI8HfN|{0-!8dm$^eVxE zZAs2Oxf=$IWI%h@4#-jV`f~Tg*XlHEyT$r)u4kENF^ziNAZ;d^SCZDLkc*3^4whuW zd;7m#f!$FIYKzj~Ygm}UpDkEE(D}&!P19S^f%^_ku~id`gXgKlilQ2BNeK@zlpXw$ z)4}?K7u3}vD_M>fmLotzYQ%$r8lC2`@Mj}Zo`rX8gnS!=Wj8am6b|+A33|)Vksv>i zZF2k{_#uNxp>SmzU1S(Hg<|Gqv;E>8jJ-i4NyuAtE6_P7Y->KFyh$WH-OnGq&egK$ z0>R}r*q|~@8kWFm42Rj{79*9;yugn|52{&vsqhZcVs?p*YtpL&7pPy|z#G)%zc)Wd z@z39G_wBh_NH=ifLoL|h?u>Z8B9Dw!3k#7@E*p~{xc+wvB0oOoSL=dW3uOu`DNg?; zC%MSWmtpji|LcV}@zM-|2x!{6c`GC~hhdKw5e_i-tQ6BbVzlHW`3+j!b;(EX1SUaW zl3gX#5NluH${X4%0sVQo~u-ZxfC(5nzPctkmI@e@73wsYDWv!5imQ(Z|ss6QEZk3{8;r0r)tNn z1E-N_VjX=Fsy2x*-ebdSFA~EmGL>6e3xn;tNP{DOerB_obxI5!Lb9yOkwP9ZCxmL^ z+#z3bSECI0pO`Kz2;@ow+_wgIO&fo(l1UqERGNGC=i>xg1ZL3Cs9?-x?9yOXe{G;y zg%NNRDdc0xG=;C{hFjL_h?ji-n@TsNeU$|DAXCoXwV*xp!~&&hE^enf)i&#rwsU z5|NN~(>`I>8MV>DnynOb=^BW2vBAH!>~de#AXqFB-VLkstmD&x--kG^I;H{GI0juz z>RDT?%m-rP$6?cHJJYWB4N$}?FR_pq6$m9!dlGTJhAxJ1&YZ3y1+J+s+xLiEE( z62B5^#ofaGqMO4JJ@GB%za(~!DU=M#PI`cxW7KC}E-XiTPKg|3`|B6vo_+`g4}?ds z6B~tAnE22n+L@w3Tx2Z6%~`R)_qVNR$fNW0p{O;Y+u?(t(Fv+ zL`U2)Wu@Ky`^r{}Pj1tYVF77x?2OiIR`Mw82!>@1*FEQ@#DWRF5ej#>;T@=ocydb% zxJm9i(jLX_&)V>75qGU>*G(jb34fp_?KDJETyRoJ7X7HW<1o4K)dEOlNyg0P&|i9l zV89aCzLzg%rAlJWZjH4@Q$-_TL(dy8oozFQgoG8}^b8D5d{cDolIhn4=eOj%gBryd z`>D{(_DFHehhV1jM|O(R(fa9j}Er^oB{7mPsHN z?lb|_8NrH+7tpx3kQ4ym01*zlQzbG#s1rNcO%Mp31yPh@3JAor|3*j1+77jW!&;z@ z|JI_(FbXIMv>>68-=R!Da~!ZFF93O@#t}C7#TOEx5>Qu!%_Xx(FtowNgO z6q;1CpK~);6KS0*er9!83{Bi^qZh52K8;65&&=VDzVS6<7Yyo!L0}IzX1>K<$!>~1 zZREGt*DdvSS@nA=QQy*rB_U_3{=7~%^Lm_moX?UgL>IIU0qoE(G63XamR-?0GuOu_ zX}en>7tJ%?L;~?ZCZ*v)8=GG+`J@EJMA=*pbwml!Hx2rzayPR?n&-(xq|wqx1-|{$ zsB!iCzqDjuoa)f6t^RUUg4~zPdAA~k6BoBuM1D&_0DrzXHTa01Z=5fG1CZZB6;4|j zw-opePRn!EZ@irGg_G+fW0T@$_$pE9AF<9I)x13#MI7vKp+~lB2B-|7`#L1KEUc9^ zJfK3&8T#9zQnZ#yOTz@YXDn|?B(;Sy?$TuJ(Yi`5zM+1vg7ik?2Q~yP{|)HguZ|P(c`j(46EtF(l zVri^C7vu`H7ik-QieBFFR@2Y(*IX26_sJ6t=;m(pHQhB-NskF;a?vBZr5;vzvwmdJYkld80#GG#mDfwaH$01_St*$yFUmleOSQ`yT}E zC3jF%@Ez$)YR-e+Xw(;bcMlaA&&Z;NW9s-Jw>9RP=uzdHL`szTE2siO$7NTtB@AqacU_KMols3WZLIZ7;3B?;Ns5%C#z|uK-GdA@7Ok7~B)iMtUA64dbhwQ+5 zY7BmTt(tqtiC0SoB#ewJ-F&mxcS%d+!9{QvPOZb_!JhzIRh|Or*}3FIEF-KgwfPp} zQF1xq)N3{Di}p5m$a=hrrP8ty6{(CgCc8Z6^wgH+t!i%a?+cDpxNLhz;thicT0FQI z4TwFz<%I5ft3_oq>}5aV@?~o^^-1^<@Jek*E0ig&FMM?C=xWedA*-woK|5qdeF^6U zXWw8aVJ?9N=l-&YQ&h<1#zhIvTX!6(pA&7deiUeUM<2lpnzB}fl4;NB?xd-ZXoxUuxmIIWRnly^>W?Nk-+rY2e2P`!poYXLu|t#DsqtOdMJ0B)5~nMqO3vU~ zUB=x%fFT%%Ko64}H%Vrnp$suffAIGHqW$S^_*eaUt`c@tB^POM?FH{YtpAYz+fk>& zfhYIh9(E}9AFxpoWs6?-5G4~d(!e?Qs%ns_~<$vRkCj(yi0TBTSfk1rx z{lA_J)LFcAFlVIZ{{^~8;oJ}GAMbnTeJ{mBwM zU0ZAMjrb-pdz~~%@x|G{Kg&+!%TBX@tM>Q~oTr#;F;mbQd^6T6L+(lGa_U>;D72;1*~z0kuPnoA3{-Uvt55vxXyu8$D#O| zvv2MHmvG;Tm%YWhoW4kPtl_i5-l^?iaw~;N<|R{-Fx{sEHV*YUAX>r^h*4DQ`E?f z#EhdT-7xBlg2^vLl%ioGD^@HUgu*vw>78dYlMSkQZ?Jg-_^*)zux4Z;KL<(IF%~WL z(d$^nG9T{QAx@|itNNAJ&(CZpDIYfN!!KIjX0Xa{_!g{bmIoIQ`b&#MW|IRpeM}=~ z*D1+IMTo_`h|qeB0SDV6JOBxM6luZ5gU&qvv@YReI+EyDcc0*C?f#{8xlDD(7XQUJ z=PUS>Tke=>(e4}u*d((Ln)20;M+JCf2mKIcmlh*5&+cMwGmaUdz5}oVDt2tyNizCU zVJP9AaYAow?*P-`*W}9(qhk9`QES)Y{yX5vLX15Qv19Y9Kt#a^2D`Q+_JrEliGz=a zU2N!}n-fAG=#bgvp+wbUYh1EOf*@MQQnB5SEV!1Hp#kOAwvmz~Qp%L1A)@6H=!m62%t7Gx&|Q6C ziufiYodK1nNoJ>B$xA7lTZ*U=(hn8HK5;)%L#V~d09#7*JRsgJ#a%N8Y0E~Tx`A)i z+7s8Ap7EwM&gL`x$YOoQOQO6~TCMJz|7NZP#VEFQv~8jM#@Ehx!P#YIk5a@@&xkgl z>ZN~+OQ1SK+vED=4ih0Xn?RJD5o(0@ECb`g3_eQ^BbCkh+MqPXSa7jjPiMBsP}G4vzsUXE%8r#2{B(zr3w*~Y&hY$Ze->pYfbh91%Q{UypTxUb zyYrZ|H9Cxm-JJYtG4m^1;v7}k*wc$U+BfeZ&$Y@gy(sgV>%v;BWy+Eplr_G`G&paI13Q(9!==|)B{#(9p)jQATl1|vZ z2qr(6Cgzmy`0q@PLL;xqG?%HSe4o|>WF1nJv43bM`)OqIv#&pcOv>v*?KORgCpoP} ziH{@(Y^BvfXKqZi79RaJ93RJ^Cc154i8-w~9h!h5RePhBg>`zbv)Mf*wev3fvFjYI zz|xR}D~s(&@rMDCnHx`@X$>|xeS6o?;@wwFF zk+#{xtfGm`$E{x7Y1O#$%d?4RX@!-j`8mhuqw;C&_O}(i?(v%s%(o@pQoZwM6a#-4 zP-s#*Mq3$wT+Juem7HAL@|uLpQb#(^!=ODMrmAF-`_d$&Y3Vk0A2zmob&0@Djmw== zx*r3^8Dx|tMQ!AsZS$I%rP=riPf~s?GNes+_h7irl}~?-ba|+R41aJ>;VW9#K&peV zvx}(1r3NQ_SmA1!aH0sC?L9r6p@v#Zw?hRfH{AmMs^upfixM3{@581PzV9Rto8dCj zOw`OZn=jTk#k3b2dfjych3s0Dvml7|3!{~Pb4%*kr}UeQ8}lL>JlORejcMyl zNm|@G<{H7O<0uJ?sO#&y-U2_R69~)MaSv{pUmOsXCwH<@&#g)Jf1Z6j-w>hkad%X! ze#vTir)eK>yC^Ivb#mXLBP^kQLj9c^t)%I^w2@l)ye-6W2oand+~i2T_KmBw;KJxXZ;aH_i%=LVaapPrhaV+^?YR>< zBgF^-R%Le0UB=?l1}>xIRoG4rXo^kxdS8FRn_|T(d*EDM&7?gz$HqjJ-|ySQLPg1U zjtAX+3XbCdj`E&TJB|-}L!IXDtYj9Kyw@K--vmvzh%=&XDgGjv+8vtM31o~}CkwF~~*tFj18A2J^Aef$+c7n07e>~20Xa(z~erz{r67Fzf%w%K^e-`4%j zYfSb<$j%4)%97549;U(XoqHL+ixw;{yY zG-cv|{i*2n$cxBSwx@1cX~PK{PMSQVQixRPToEfn>e6>Vp9cdJC1g7D^5?QGd?22W z7*p1v7-`PiPJ||W^6au@g@u@$ve*h%YKrs*zFHTEgk@~_hcJUW?v$(syZnWIcM~(7 zPy4Uts+v_boT_qaJ1QqD$g?HCV6Yo_3T++B=P@%$-e5U-M>Y^phS6RW-SO z4dMic^O~8OA{wENkzX@@sGc}*N>Y>D0o40r7Iy21MY5v%WNm0DL-%@9b#!ZHAGA== zF1RIfyKvc!`I#WA?=AmlwF*9Zh`6XrzGprWOrck3v=g zqn9WxvAjp;CPgfCv`BAxhSl@*C-+{mYu%6l%2}X-#eyE*0V^@1wsc zyVe?66g4XZrReJrpYz>tunabrU}AYFF~oW+OT2t*Rzjsza6Mp#d_d7=0(`(-`&CYSYaCOU|30}h!ksu(vk{*&g4^T zPhJ3j=(N)jWBu{$hcgiZ0~?f*7mY9ph~sAJ=O1Rny8zBS~T&d)|y& zCJ>4_G1+4_!yOr$LKP9aZig!sdx0r6Ev5<$_qOxro>Ff=ez;K8FV5m-=pHrFUWq&} zx+4LfQvP(y`)*>^>Dg51^usR%PzX>HoRJXyF7!ke@8}~=87L7garUD%jOUsCFOdif zwzXr2YxLgpxg<%L!PGC)n(-J?+8{26$9waX3$u-N2$v%#GV$)4e2(sh6Z4{XUT>0C zSniyDCZRJ;Z-OVS3}lME6u;}yLDaeUle_}3*Vj?i?_xr?;8p9|3Gvd}uonh#GyEXf z*XSEU{zA17PMc&P?O~&75+CNK)N=0-RL^=kljm934j9zzQ#z=aMdw204;lk>$yB3`UX$*1)v&P{?!K1f1@}D}^-n$-)ON%k4 zKAN!zd}PB$(SB6d%v-^~L)zf~h%3KZygOmm`k@f5W%BMl?)y7sU(v@;fr4PfTC`qLG!FH&1eO8$yvtA#;n zYS|^4M4rFE?xGpnH;Qa1-~HlPXyk8xY_@;itl}Ij?dW94Xm-~}+IimcUen=Kht;7$ z{CTN1z4dc>X9JS!eqn-d5d&8vRbpZ#ZSCw6SJPD#rnN)o&D!oB5#F~gO!V2zo{<(- zzg?=~(#hWqgs8N|TA=j8@H^eIYiyFbK)l1njXAd_vKm3V_RJ~}FzHsW+nxzDr+`Ud z9mprMs;Fp0#If8$CYY{u&pm}DHgxbY2{M|{{v~1&bzSO!s@9q=8ao{xUkvjhjBYs2 zCnBX{?qm{WOqK|b3wog0-*PBTk@{4r0rzR%y>!G;(sYa2AE zX@R<<{^H2%qbu%N*-O_MbJM=95nauv zk7F8}TpEj42g8?1&Te%55lKVP*S|=wXY_(04L4-dl9>ruhK4-K#l{P^0qD{Z0w^;z z8Z_j^)TS>&QFooz3fT^&Kx4wwMLYjbi9llnXs0BKAGj3<#kP|aJ%`r;M zLa}<5Q{mWK)2%i&&%Bw(^>lq;1ODh7=1Dw!JLLu}FUu;SzV#V<~cf|Z6a zq^;KL4CdM7YfD7l9`%^b5nVuWhFB+New}t-0EFcWKzfoY`xbyShe|82SlAHA{KUxMcKUFtf*Cnsp3a{A za;$VXV=piXTR>Q8Tc9C398uLo`zwVAnRX`}tL+B_xAQv^Bq%@4v9Cb>G!<*$tMP92 zFWqj~=ig@fF>xRUyOz!~BW68i^c%pK%*|UI@ME%>ADPvb8I&!4jv9u+wP(eQC-iW> zSDJ_Bc-_Q=r!NccQ(p6Fpq%uFrY!XOM0Vv;eA4v8+A$u@= z!me6yu|YeS^3hY~C@6LuQ`?YQFlMytHSY{=6^JiBPuR~YRpvzT8w*Px9HG)`H^GL( zF>NmIg6yi<2RvDhWQTYrJZ)aa#-$EFMeU~k2GGc`Py7bd{N*Hw!xDN9kw>ZaK>$yQ zWFWg4cEMb~Zv3+77v{wHMXXr?rd~`MDq|W#-`tqk)~D$hRoJSbwP z3CO|ZmHE{c7=IE&aS$4%Wp4-v9t}nM7qoI*B2xYD)>!D6AdBBiHymp3oJq3 zg@Gn*k3;%wo*-oNQMu-Cz-_tD%y?}?^`p6w8-@8>BiEHa*XT=oOBT2`!3cQss)@M6<1r!kHX|{_j0LU3LJi?C~>H`_d0$HZLFr^ zOQQUiyt`>XG%)7#a9-y|AB$K>8<*?`v(w*g2Am&I+IqkOe{e9w$@>17e)X>ETu%NcaV*230Tnh8cEogpv$EWU<2;6L8qCAP zBQ0Dehd4Wtos4STH()zS`moNW5n^KQ7$ko38R}d(f&zm`kj_|2VuRf)TUm4%L(8E2 zD)DcC&(wPD835*{#=rcg1VO>|(p^E3lB_AxiEO zDUvRo0WVm<>Yu`~aBxf{sr_%H%OIop5f&B?E6E^i(Dya*-;cc;E(W|ua4+_y~+ew8GB`9E2MA=b_{08uz z2}eo)io$E4rT-Y60|^O<@xgTPs^$M0ofAMs6b)z$ZL=y79C)kq)_&m`u&9#09}N9r z!^SS=nDei(IROxFY;G{gyA9o|F1VncQkNg%-G=-BX~E~OI$7rY_eaI)q$}qT(s9JX z)ddExT3HU$-K67L2GVVTlZbx>b$ri7)+GBJ`y8GW%kaAw?4;XpP?VPMN7ZY#>WJ!0 zgE53OAxliUqB9y`&662%sjC5GT{JD9izv4-!!Y{C6V{|klr(@$|0{|^VVMfa+P z-AENPm<*A61NE*!yw^~Co{0zY{=fA8r+5~}y!*ew{#@}CLa7KG`-g_F;)0uc_Np1YCQM8j_^aUs>+cacbi?L3G1meBE z;`54>@K&_*lZI8Y;4ML&LkgGS?h~b{agr-TJGDBeq9NbFM0upFP8XNW!%dqmU0a% zG(PSX5smccB;U}nl_X=iT5?b97G{N?$m{%Qfu=&^DLGYm_h?g+U2X_cw0~sQ$kxm@ z^#c50;$(eoikuJ;rQ%XL={Ge_{N-Ps@Dx)GTp7r6C9gmOf0Zv; z#;9=siQ|QJ!77uDL1B57>5%N^(A-PT4JM=gFz_Xtf$7v~@DIL)#QulD?Me|*?CpnX z7ZByMh+I;rwT>*u7m6SO4S1iHPsROfjKB^2fiU7d_nz-4lCw#93l8cD4UMspCAL^{ zzQfOr+A*uq7F*?B6(UqT;c&umJoSu*zfcue~#L>FM z@vtPqrRL@)_f&qm{*qppqBw_UzhvA%i$jr3@$I6_C{qECq)bUH$s=x^TeH{fX>NbJ zo8TGP(AG};Be|kk?}X6y!2u-`T!Rusl=L{mKVj}5&)J>$*VvfM?P$}PT1FshPJ03*W~FidG&zKhZiS zEukgUkCa+JsOYsCGI0V0?A@izC~RdMVBpk>TEx~*EKk4cPeKJ35mh62h$4ZvNp`cEyO4rjT z87>nH=_5@1oM0P_*hTfKM}B0Y%ItnB3eJWbiz&tyu!4~Ek;bD22W7UzOpZo0`Z8Wk ziSaG1eIK5oI&goBQu*+DpQa;OjD_$vh$a&nr6L0+fP3Ma-s3Q zx^Z$+27>+gTN*n}$zFX7+3`$k54_SVEuQub+sCv7BLScu0WrB|(;YmM^}e*U!< zg7~8hcuT>Bv6@YpMUtf#z+HC0XC>j6(Z?ijyh!>GpD4Hix^(uxy1wuYj~Y7sq?f2R zM4LXg15+ONaXQ$8?m*kV#(fsDsZI1`>Yp)hZ)kIj@WMOqs5H_AUN&-nHTC34ZR8HT z#1ZAxG)iXsa+~Db#Mezd_6n%T^YCQ>dG*7lrgK`SenhgKw@EkM(U@h~IG!UxyX=E^ z2Rh@mmr*Y1f~mF3BI^*Z${KVh0r2rohyDoz_NsB5T}5@9Dr@E4AtgZ>4gw^N ztTAR`JeSzPd3g%hCc>ZU$t3SR+$0>rq$I3J+D)F9m&N2U&ilLg~Mwiu4yqV6VKDO6f?X8bBMhZeB8g8TbG{-&ljsD6z8@)8X&n>K|rE)#UQ6~CGa?`TwO?;BHr z<#NB3pXTe)6ZZxa@&?3Lk+uffB!m6lK{Vt@vp3xUMXLHs6zxPx1gBVEk9xvU+wO!q z;dOFGM4G9-K;J!W4Di~QgjbC%zGTLtJyO|pf;Po1tTUgI2i-kmF@sA^h}G(6S-7`T zbI94IDlUn#f0t9M8>yMY~bbWc{A3A*An2XWHA zdtmXcGPe!>LPL9&S&}S3^=)W{8iWBij;%G`A#Bn3j%MiaDF4YH?F3Xq(95LS@V~fK zqF0bvMyM!wVmx^VN>bh6(#07S&@mTL9b05y>ufAQDBJ5tFl_OCBk?RwQ%F>2uy>tF z_HKr1^kKQU0QO|$gLrToaw*juyj`F;*ZM$3`Ck0HegOC`hhjs!{|Y&bLNtz=1_BZo z*bmD2#&4fa(z3te7Ljv{Q6dNVP3q4sB;-jC732q5_;VT`xdVkE4<|3wh<*wfae&GX1Ks{^8fFcRLxb>kPI; z3D;tcC|#8xczGmIX_C>{eka5ieIVJaOo*vhoR&fKJcF7PKXd8#spCa+s~5e#6uS1E z`AOE$-5k?X6jp$p%bPGOctGy*CUu?iD0boJKTg723LiJ!47ypHgCs=e(8A;1N_-;f zFj^I>i#z^q52{2>^F)(%FA4b)h@I9*bgmbKVEoX=okJWzh7+BiD3>DJfijLtTN(8} zeV#6+E*k24oL@*~kZAwA6q|gp7pdZDq_&%jyqpBuSFAdZM!5I@ zZE*%h#ghc#3Nd~PidR&LGMqH@heQd-(NmA>-)D{|h+{W>#TBdgSryBgN~oz;!@Obz z&`b77WTjfNl$0f{_iqS{BjGx;pa#Mg-{5@TIcfsiR``LPCo>hxBVL z2@01W%UvJQv?)vwP9x*f_k`ZAdw5owjHHf+NQ@c^%t%kJv)H1_nVYSNFpa?%$(=r5 zOpm_8oi5eIefXEICXl6CzQp>?@AvrEX6MW{1m#pw&n5WBGi6P3Y<{e~z7$I#?EvY0 z420;qCsh1f5U9^Hx?>1UD!tF%35jrIqIC~55srwB5(Pe!N;JTq@8k4wbkuJEEtEs8 zK8M@33KGw?0{doPj@)K|Zxk^3#PAm!Nvn{I88?U*sJjI0Rd&b3VUNG*argzQ8!wg& z!-G3N6glA|Bp65*3;-M)2E?um4u{IQk~j-3&qM3nkw41C5wYe&9N#-Y4y2vb!~~Z@ ze-B3 zl#8NNv!a_5kr8Ip4vkAaOs0wJu)p^5DVlE}#Y-3|H#=9G{hEhyhKUNE}R{$}XOdf(A0eXPI>YK7~5caEK*m4E~UjO(nbinXAR?rDVcMWa3)& zyc&8QI-WR1R&NmL05Dyk-ekJ)^e@~ZBajd3IO(9D)7nt}A~ z?`aKnWy>0iM~e#QG>ia4~WVb^-z&D zD^ls_ri#r@ucnGg%;tuK3L`)=jC-6kF^) zV{>@x{~G|g7Nuv>O$}qnfa09EPy<}zv`(BDbR2V2rEkB!oj(3hw&dpQRaHlEOu6|y zQSGEL2NfMoQ3R-p+aYU4 zJQJMLFFx|31;75xZgFoLgKds=`Ld~_QH*>8-TFMyBaveV;ndZ_araiA3W2TIK$wfg8a2l%x&fi&faTIt@`%MSy1_gSJ% z7&ry__4QHJ$c^Z(g4xTTe`M%2xvUr;vffGvQ=BGi0%Hh~Q(iB^AOlV;4oRnN2*~NT zsR*fZwIHPH0^Y7@l6mn}?68CnJIV8;2v@_-)kz!!aD}X9-EmowIEecnIrsqX1gmhv zibre8e=sC;!PaK;^1zKuRB*{>Dpc@I9SIegArA36bmy`iDWcXF7Huq?>Xt4r^3!W! zojfHDD@?}}Ib2~$xMd4Lok>cHL9V_IM2TDV#~mW-WnT6DnDBmE zAfByb>n|K_N+Mvu*NsXj!n>9C=iut!WHs{e8ihDF7b1OwG$p}pdA!r-Jx)0F*)V*% zyYiCACEYeSJz3YwsuJX&M9Gt+INOBNoEspnT_Tv>kKVy2bcMcDOf-6hl(+!BMoI`K zC2k`nB$%Oc7(^;IJS>{M3!b%h`v=Dhr&1v$uKHi;ADP{6=(9^i7{a(hpZ6N}PlA&Y cf}(d~pJuc f.startsWith('simulator.astro') && f.endsWith('.js')); -const simJsContent = await readFile(join(distDir, simJs), 'utf8'); +if (!simJs) throw new Error('Built simulator entrypoint was not found. Run npm run build first.'); + +const MALICIOUS_MARKUP = 'seo-xss">'; // The user's test input const ITEM_TEXT = `Item Class: Rings Rarity: Rare -Torment Whorl +${MALICIOUS_MARKUP} Gold Ring -------- Requires: Level 60 @@ -36,27 +39,8 @@ Leech 7.55(7-7.9)% of Physical Attack Damage as Life { Crafted Suffix Modifier "of Archaeology" (Tier: 1) } 17(15-18)% increased Rarity of Items found`; -const dom = new JSDOM(` -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -`, { +const simulatorHtml = await readFile('dist/simulator/index.html', 'utf8'); +const dom = new JSDOM(simulatorHtml, { url: 'http://localhost:4321/simulator/', pretendToBeVisual: true, runScripts: 'outside-only', @@ -66,12 +50,12 @@ const { window } = dom; window.Worker = class { addEventListener() {} postMessage() {} terminate() {} }; window.structuredClone = (obj) => JSON.parse(JSON.stringify(obj)); -// Inject sim-data -const basesJson = await readFile('data/processed/bases.json', 'utf8'); -const modsJson = await readFile('data/processed/mods.json', 'utf8'); -const currencyJson = await readFile('data/processed/currency.json', 'utf8'); -const omensJson = await readFile('data/processed/omens.json', 'utf8'); -const weightsJson = await readFile('data/processed/weights.json', 'utf8'); +// Inject the same processed data the browser would fetch. +const basesJson = await readFile('public/data/bases.json', 'utf8'); +const modsJson = await readFile('public/data/mods.json', 'utf8'); +const currencyJson = await readFile('public/data/currency.json', 'utf8'); +const omensJson = await readFile('public/data/omens.json', 'utf8'); +const weightsJson = await readFile('public/data/weights.json', 'utf8'); const simData = { bases: JSON.parse(basesJson).map((b) => ({ id: b.id, name: b.name, slot: b.slot, level: b.level, affixSlots: b.affixSlots, imageUrl: b.imageUrl, variant: b.variant })), @@ -80,17 +64,97 @@ const simData = { mods: JSON.parse(modsJson), weights: JSON.parse(weightsJson), }; +const exaltedIndex = simData.currency.findIndex((item) => item.id === 'exalted_orb'); +if (exaltedIndex < 0) throw new Error('Expected Exalted Orb fixture data was not found.'); +simData.currency[exaltedIndex] = { + ...simData.currency[exaltedIndex], + name: MALICIOUS_MARKUP, + description: MALICIOUS_MARKUP, + imageUrl: MALICIOUS_MARKUP, +}; +if (simData.omens.length === 0) throw new Error('Expected omen fixture data was not found.'); +const hostileOmenId = simData.omens[0].id; +simData.omens[0] = { + ...simData.omens[0], + name: MALICIOUS_MARKUP, + effect: MALICIOUS_MARKUP, + imageUrl: MALICIOUS_MARKUP, +}; + +const fetchedData = new Map([ + ['/data/currency.json', simData.currency], + ['/data/omens.json', simData.omens], + ['/data/mods.json', simData.mods], + ['/data/weights.json', simData.weights], +]); +const fetchStub = async (input) => { + const url = typeof input === 'string' ? input : input.url; + if (!fetchedData.has(url)) { + return { ok: false, status: 404, json: async () => ({}) }; + } + return { ok: true, status: 200, json: async () => fetchedData.get(url) }; +}; +window.fetch = fetchStub; + +// Astro emits an ES module with relative imports. Run it as a module while +// exposing the JSDOM browser globals it expects. +function installBrowserGlobals(targetWindow, targetFetch) { + targetWindow.Worker = class { addEventListener() {} postMessage() {} terminate() {} }; + targetWindow.structuredClone = (obj) => JSON.parse(JSON.stringify(obj)); + const browserGlobals = { + window: targetWindow, + document: targetWindow.document, + navigator: targetWindow.navigator, + location: targetWindow.location, + localStorage: targetWindow.localStorage, + HTMLElement: targetWindow.HTMLElement, + HTMLInputElement: targetWindow.HTMLInputElement, + HTMLSelectElement: targetWindow.HTMLSelectElement, + HTMLButtonElement: targetWindow.HTMLButtonElement, + Element: targetWindow.Element, + Node: targetWindow.Node, + Event: targetWindow.Event, + CustomEvent: targetWindow.CustomEvent, + Worker: targetWindow.Worker, + fetch: targetFetch, + requestAnimationFrame: targetWindow.requestAnimationFrame.bind(targetWindow), + cancelAnimationFrame: targetWindow.cancelAnimationFrame.bind(targetWindow), + getComputedStyle: targetWindow.getComputedStyle.bind(targetWindow), + }; + for (const [name, value] of Object.entries(browserGlobals)) { + Object.defineProperty(globalThis, name, { + configurable: true, + writable: true, + value, + }); + } +} +installBrowserGlobals(window, fetchStub); + +function assert(condition, message) { + if (!condition) throw new Error(`E2E assertion failed: ${message}`); +} -window.document.getElementById('sim-data').textContent = JSON.stringify(simData); -window.eval(simJsContent); +function builtEntrypoint(prefix) { + const filename = files.find((file) => file.startsWith(`${prefix}.astro`) && file.endsWith('.js')); + if (!filename) throw new Error(`Built ${prefix} entrypoint was not found.`); + return pathToFileURL(resolve(join(distDir, filename))).href; +} + +await import(pathToFileURL(resolve(join(distDir, simJs))).href); +await new Promise((resolveLoad) => setTimeout(resolveLoad, 0)); console.log('=== Testing PoE2 Item Import ===\n'); +assert(window.document.getElementById('main-ui'), 'simulator main UI contract is missing'); +assert(window.document.getElementById('omen-search'), 'omen search control is missing'); +assert(window.document.getElementById('omen-clear-all'), 'omen clear control is missing'); // 1. Open paste modal const pasteBtn = window.document.getElementById('paste-btn') || window.document.getElementById('paste-empty-btn'); if (pasteBtn) pasteBtn.click(); const pasteModal = window.document.getElementById('paste-modal'); console.log('Paste modal opened:', !pasteModal.classList.contains('hidden')); +assert(pasteModal && !pasteModal.classList.contains('hidden'), 'paste modal did not open'); // 2. Paste the text const textarea = window.document.getElementById('paste-textarea'); @@ -104,15 +168,25 @@ const detected = window.document.getElementById('paste-detected'); console.log('Detected:', detected?.textContent?.slice(0, 200)); const error = window.document.getElementById('paste-error'); console.log('Error visible:', !error?.classList.contains('hidden')); +assert(detected?.textContent?.includes(MALICIOUS_MARKUP), 'malicious item name was not rendered as text'); +assert(detected?.textContent?.includes('Matched'), 'pasted base was not matched'); +assert(!detected?.classList.contains('hidden'), 'paste detection remained visually hidden'); +assert(error?.classList.contains('hidden'), 'paste error was visible for the valid fixture'); +assert(!window.document.getElementById('seo-xss-fixture'), 'pasted markup escaped into the DOM'); // 4. Click Import const importBtn = window.document.getElementById('import-paste-btn') || window.document.getElementById('paste-import'); console.log('Import button disabled:', importBtn?.disabled); +assert(importBtn && !importBtn.disabled, 'valid paste import remained disabled'); if (importBtn && !importBtn.disabled) { importBtn.click(); await new Promise((r) => setTimeout(r, 100)); } +assert( + !window.document.getElementById('main-ui')?.classList.contains('hidden'), + 'simulator main UI did not become visible after import', +); // 5. Check the rendered item const itemName = window.document.querySelector('.item-name')?.textContent; @@ -126,9 +200,138 @@ modRows.forEach((r) => { console.log(` ${tier}: ${text}`); }); -if (modRows.length >= 5) { - console.log('\n✓ PASS: Item parsed and rendered with 5+ mods'); -} else { - console.error('\n✗ FAIL: Expected 5+ mod rows, got', modRows.length); - process.exit(1); -} \ No newline at end of file +assert(itemName === 'Gold Ring', `expected Gold Ring, got ${itemName}`); +assert(modRows.length === 7, `expected exactly 7 mod rows, got ${modRows.length}`); +for (const expectedText of [ + 'increased Rarity of Items found', + 'Physical Damage to Attacks', + 'all Elemental Resistances', +]) { + assert( + [...modRows].some((row) => row.textContent?.includes(expectedText)), + `representative modifier was not rendered: ${expectedText}`, + ); +} + +const hostileCurrency = window.document.querySelector('[data-original-id="exalted_orb"]'); +assert(hostileCurrency, 'hostile currency fixture was not rendered'); +assert( + hostileCurrency.getAttribute('aria-label')?.includes(MALICIOUS_MARKUP), + 'currency name did not round-trip through the escaped attribute', +); +assert(!hostileCurrency.querySelector('[onerror]'), 'currency fixture created an event-handler attribute'); +assert(!window.document.getElementById('seo-xss-fixture'), 'currency markup escaped into the DOM'); + +window.document.getElementById('open-omens-btn')?.click(); +const hostileOmen = [...window.document.querySelectorAll('.omen-btn')] + .find((button) => button.dataset.omen === hostileOmenId); +assert(hostileOmen, 'hostile omen fixture was not rendered'); +assert( + hostileOmen.getAttribute('aria-label') === MALICIOUS_MARKUP, + 'omen name did not round-trip through the escaped attribute', +); +assert(!hostileOmen.querySelector('[onerror]'), 'omen fixture created an event-handler attribute'); +assert(!window.document.getElementById('seo-xss-fixture'), 'omen markup escaped into the DOM'); + +console.log('\n✓ PASS: simulator import rendered exactly 7 mods and contained malicious data'); + +async function runCalculatorInjectionFixture() { + const html = await readFile('dist/calculator/index.html', 'utf8'); + const calculatorDom = new JSDOM(html, { + url: 'http://localhost:4321/calculator/', + pretendToBeVisual: true, + runScripts: 'outside-only', + }); + const base = { + ...simData.bases.find((item) => item.slot === 'ring'), + name: MALICIOUS_MARKUP, + }; + assert(base.id, 'calculator base fixture was not found'); + const maliciousModId = `mod-${MALICIOUS_MARKUP}`; + const maliciousMod = { + id: maliciousModId, + name: MALICIOUS_MARKUP, + description: MALICIOUS_MARKUP, + type: 'prefix', + domain: [base.slot], + tier: 1, + level: 1, + tags: [], + }; + const responses = new Map([ + ['/data/bases.json', [base]], + ['/data/mods.json', [maliciousMod]], + ['/data/weights.json', []], + ]); + const calculatorFetch = async (input) => { + const url = typeof input === 'string' ? input : input.url; + return responses.has(url) + ? { ok: true, status: 200, json: async () => responses.get(url) } + : { ok: false, status: 404, json: async () => ({}) }; + }; + calculatorDom.window.fetch = calculatorFetch; + installBrowserGlobals(calculatorDom.window, calculatorFetch); + await import(builtEntrypoint('calculator')); + await new Promise((resolveLoad) => setTimeout(resolveLoad, 0)); + + const baseSelect = calculatorDom.window.document.getElementById('base'); + assert(baseSelect.options[1]?.textContent === MALICIOUS_MARKUP, 'base option was not rendered as text'); + baseSelect.value = base.id; + baseSelect.dispatchEvent(new calculatorDom.window.Event('change', { bubbles: true })); + const search = calculatorDom.window.document.getElementById('mod-search'); + search.value = 'seo-xss'; + search.dispatchEvent(new calculatorDom.window.Event('input', { bubbles: true })); + + const result = calculatorDom.window.document.querySelector('.mod-item'); + assert(result, 'malicious modifier fixture was not rendered'); + assert(result.dataset.modId === maliciousModId, 'modifier ID did not round-trip safely'); + assert(result.textContent.includes(MALICIOUS_MARKUP), 'modifier description was not rendered as text'); + assert(!calculatorDom.window.document.getElementById('seo-xss-fixture'), 'calculator markup escaped into the DOM'); + assert(!result.querySelector('[onerror]'), 'calculator fixture created an event-handler attribute'); + calculatorDom.window.close(); +} + +async function runOptimizerInjectionFixture() { + const html = await readFile('dist/optimizer/index.html', 'utf8'); + const optimizerDom = new JSDOM(html, { + url: 'http://localhost:4321/optimizer/', + pretendToBeVisual: true, + runScripts: 'outside-only', + }); + const base = { + ...simData.bases.find((item) => item.slot === 'ring'), + name: MALICIOUS_MARKUP, + }; + const responses = new Map([ + ['/data/bases.json', [base]], + ['/data/mods.json', []], + ['/data/currency.json', []], + ['/api/prices', {}], + ]); + const optimizerFetch = async (input) => { + const url = typeof input === 'string' ? input : input.url; + return responses.has(url) + ? { ok: true, status: 200, json: async () => responses.get(url) } + : { ok: false, status: 404, json: async () => ({}) }; + }; + optimizerDom.window.fetch = optimizerFetch; + installBrowserGlobals(optimizerDom.window, optimizerFetch); + await import(builtEntrypoint('optimizer')); + await new Promise((resolveLoad) => setTimeout(resolveLoad, 0)); + + const paste = optimizerDom.window.document.getElementById('paste-area'); + paste.value = `Item Class: Rings\nRarity: Rare\nFixture Name\n${MALICIOUS_MARKUP}\n--------\nItem Level: 80`; + paste.dispatchEvent(new optimizerDom.window.Event('input', { bubbles: true })); + const detectedBase = optimizerDom.window.document.getElementById('detected-base'); + assert( + detectedBase.textContent === `${MALICIOUS_MARKUP} — 0 affixes`, + 'optimizer base name was not rendered as text', + ); + assert(!optimizerDom.window.document.getElementById('seo-xss-fixture'), 'optimizer markup escaped into the DOM'); + optimizerDom.window.close(); +} + +await runCalculatorInjectionFixture(); +await runOptimizerInjectionFixture(); +window.close(); +console.log('✓ PASS: simulator, calculator, and optimizer rejected executable fixture markup'); diff --git a/scripts/audit-seo-output.mjs b/scripts/audit-seo-output.mjs new file mode 100644 index 0000000..d23c433 --- /dev/null +++ b/scripts/audit-seo-output.mjs @@ -0,0 +1,221 @@ +import { createHash } from 'node:crypto'; +import { readFile, readdir } from 'node:fs/promises'; +import path from 'node:path'; +import { load } from 'cheerio'; + +const SITE = new URL('https://exilecrafter.com/'); +const distArgument = process.argv.find((argument) => argument.startsWith('--dist=')); +const DIST = path.resolve(distArgument?.slice('--dist='.length) || 'dist'); + +async function walk(directory) { + const entries = await readdir(directory, { withFileTypes: true }); + const files = []; + for (const entry of entries) { + const target = path.join(directory, entry.name); + if (entry.isDirectory()) files.push(...await walk(target)); + else files.push(target); + } + return files; +} + +function routeFromFile(file) { + const relative = path.relative(DIST, file).split(path.sep).join('/'); + if (relative === 'index.html') return '/'; + if (relative.endsWith('/index.html')) { + return `/${relative.slice(0, -'index.html'.length)}`; + } + return `/${relative}`; +} + +function normalizedText(value) { + return value.replace(/\s+/g, ' ').trim(); +} + +function isPagePath(pathname) { + const lastSegment = pathname.split('/').filter(Boolean).at(-1) ?? ''; + return !/\.[a-z0-9]{1,8}$/i.test(lastSegment) + && pathname !== '/api' + && !pathname.startsWith('/api/'); +} + +const files = (await walk(DIST)).sort(); +const htmlFiles = files.filter((file) => file.endsWith('.html')); +const artifactHash = createHash('sha256'); +const seoOutputFiles = files.filter((file) => { + const relative = path.relative(DIST, file).split(path.sep).join('/'); + return file.endsWith('.html') + || /^sitemap.*\.xml$/.test(relative) + || relative === 'robots.txt' + || relative === 'og-exile-crafter.jpg' + || /^data\/(?:bases|mods|currency|omens|weights|season|manifest)\.json$/.test(relative); +}); +for (const file of seoOutputFiles) { + const relative = path.relative(DIST, file).split(path.sep).join('/'); + artifactHash.update(relative); + artifactHash.update('\0'); + artifactHash.update(await readFile(file)); + artifactHash.update('\0'); +} +const pages = []; +let missingCanonicals = 0; +let missingSharedSocialMetadata = 0; +let jsonLdPages = 0; +let invalidJsonLdBlocks = 0; +let titlesOver60 = 0; +let pagesUnder200Words = 0; +let modPagesUnder300Words = 0; +let imageOccurrences = 0; +let imagesMissingDimensions = 0; +let nonTrailingPageLinkOccurrences = 0; + +for (const file of htmlFiles) { + const route = routeFromFile(file); + const html = await readFile(file, 'utf8'); + + const $ = load(html); + const title = normalizedText($('title').first().text()); + const description = $('meta[name="description"]').first().attr('content')?.trim() ?? ''; + const robots = $('meta[name="robots"]').first().attr('content')?.trim() ?? ''; + const isNoindex = /(?:^|,)\s*noindex(?:,|$)/i.test(robots); + const isIndexable = !isNoindex && route !== '/404.html'; + const canonical = $('link[rel="canonical"]').first().attr('href')?.trim() ?? null; + if (isIndexable && !canonical) missingCanonicals += 1; + if (title.length > 60) titlesOver60 += 1; + + const requiredSocialSelectors = [ + 'meta[property="og:title"]', + 'meta[property="og:description"]', + 'meta[property="og:image"]', + 'meta[name="twitter:card"]', + 'meta[name="twitter:title"]', + 'meta[name="twitter:description"]', + 'meta[name="twitter:image"]', + ]; + if ( + isIndexable + && requiredSocialSelectors.some((selector) => $(selector).length !== 1) + ) { + missingSharedSocialMetadata += 1; + } + + const jsonLdScripts = $('script[type="application/ld+json"]').toArray(); + if (jsonLdScripts.length > 0) jsonLdPages += 1; + for (const script of jsonLdScripts) { + try { + JSON.parse($(script).html() ?? ''); + } catch { + invalidJsonLdBlocks += 1; + } + } + + const mainText = normalizedText($('main').text()); + const wordCount = mainText === '' ? 0 : mainText.split(/\s+/).length; + if (wordCount < 200) pagesUnder200Words += 1; + if (route.startsWith('/mods/') && route !== '/mods/' && wordCount < 300) { + modPagesUnder300Words += 1; + } + + const images = $('img').toArray(); + imageOccurrences += images.length; + imagesMissingDimensions += images.filter((image) => { + return !$(image).attr('width') || !$(image).attr('height'); + }).length; + + const internalLinks = new Set(); + for (const anchor of $('a[href]').toArray()) { + const href = $(anchor).attr('href')?.trim() ?? ''; + if (href === '' || href.startsWith('#') || /^(?:mailto|tel|javascript|data):/i.test(href)) { + continue; + } + let target; + try { + target = new URL(href, new URL(route, SITE)); + } catch { + continue; + } + if (target.origin !== SITE.origin || !isPagePath(target.pathname)) continue; + const graphPath = target.pathname === '/' || target.pathname.endsWith('/') + ? target.pathname + : `${target.pathname}/`; + internalLinks.add(`${target.origin}${graphPath}`); + if (target.pathname !== '/' && !target.pathname.endsWith('/')) { + nonTrailingPageLinkOccurrences += 1; + } + } + + pages.push({ + route, + title, + description, + canonical, + isNoindex, + isIndexable, + internalLinks, + }); +} + +const titleGroups = new Map(); +for (const page of pages.filter((candidate) => candidate.isIndexable)) { + const key = page.title.toLocaleLowerCase('en'); + titleGroups.set(key, [...(titleGroups.get(key) ?? []), page.route]); +} +const duplicateTitleGroups = [...titleGroups.values()] + .filter((routes) => routes.length > 1).length; + +const pageUrls = new Set( + pages + .filter((page) => page.isIndexable) + .map((page) => `${SITE.origin}${page.route === '/' ? '/' : page.route}`), +); +const inlinks = new Map([...pageUrls].map((url) => [url, 0])); +for (const page of pages) { + const source = `${SITE.origin}${page.route === '/' ? '/' : page.route}`; + for (const target of page.internalLinks) { + if (target !== source && inlinks.has(target)) { + inlinks.set(target, inlinks.get(target) + 1); + } + } +} +const zeroInlinkPages = [...inlinks.entries()].filter(([url, count]) => { + return url !== `${SITE.origin}/` + && url !== `${SITE.origin}/404.html` + && count === 0; +}).length; + +let sitemapUrls = []; +try { + const sitemap = await readFile(path.join(DIST, 'sitemap-0.xml'), 'utf8'); + sitemapUrls = [...sitemap.matchAll(/([^<]+)<\/loc>/g)].map((match) => match[1]); +} catch { + // A missing sitemap is represented by an empty URL set. +} + +const result = { + schemaVersion: 1, + tool: 'scripts/audit-seo-output.mjs', + site: SITE.origin, + dist: path.relative(process.cwd(), DIST) || 'dist', + seoOutputSha256: artifactHash.digest('hex'), + metrics: { + htmlPages: pages.length, + indexablePages: pages.filter((page) => page.isIndexable).length, + noindexPages: pages.filter((page) => page.isNoindex).length, + errorPages: pages.filter((page) => page.route === '/404.html').length, + missingCanonicals, + missingSharedSocialMetadata, + jsonLdPages, + invalidJsonLdBlocks, + duplicateTitleGroups, + titlesOver60, + pagesUnder200Words, + modPagesUnder300Words, + imageOccurrences, + imagesMissingDimensions, + nonTrailingPageLinkOccurrences, + zeroInlinkPages, + sitemapUrls: sitemapUrls.length, + duplicateSitemapUrls: sitemapUrls.length - new Set(sitemapUrls).size, + }, +}; + +console.log(JSON.stringify(result, null, 2)); diff --git a/scripts/download-images.mjs b/scripts/download-images.mjs index 84f84e5..a3955f5 100644 --- a/scripts/download-images.mjs +++ b/scripts/download-images.mjs @@ -14,15 +14,24 @@ * the JSON in-place so the URL becomes a relative local path. */ -import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs'; -import { dirname, join } from 'path'; -import https from 'https'; -import { fileURLToPath } from 'url'; +import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs'; +import { dirname, join, resolve, sep } from 'node:path'; +import https from 'node:https'; +import { fileURLToPath, pathToFileURL } from 'node:url'; const __dirname = dirname(fileURLToPath(import.meta.url)); const ROOT = join(__dirname, '..'); const PUBLIC = join(ROOT, 'public', 'images'); const DATA = join(ROOT, 'data', 'processed'); +const PUBLIC_DATA = join(ROOT, 'public', 'data'); + +export const POE2DB_IMAGE_ORIGINS = Object.freeze(['https://cdn.poe2db.tw']); +export const IMAGE_REQUEST_TIMEOUT_MS = 15_000; +export const MAX_IMAGE_BYTES = 8 * 1024 * 1024; +export const MAX_IMAGE_REDIRECTS = 3; +export const MAX_ITEMS_PER_CATEGORY = 10_000; +export const MAX_IMAGE_PATH_SEGMENTS = 16; +export const MAX_IMAGE_PATH_LENGTH = 512; const CATEGORIES = [ { file: 'bases.json', key: 'bases', referer: 'https://poe2db.tw/us/' }, @@ -32,61 +41,345 @@ const CATEGORIES = [ ]; const MAX_CONCURRENT = 8; +const IMAGE_ORIGIN_SET = new Set(POE2DB_IMAGE_ORIGINS); +const REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]); +const CATEGORY_KEYS = new Set(CATEGORIES.map(({ key }) => key)); +const CATEGORY_FILES = new Set(CATEGORIES.map(({ file }) => file)); +const LOCAL_CATEGORY_PREFIXES = Object.freeze({ + bases: ['/images/base/', '/images/bases/'], + currency: ['/images/currency/'], + omens: ['/images/omen/', '/images/omens/'], +}); + +export function validateImageUrl(value, base) { + if (typeof value !== 'string' || !value.trim()) { + throw new TypeError('Image URL must be a non-empty string'); + } + const raw = value.trim(); + if ( + raw.includes('\\') + || /%(?:2e|2f|5c)/i.test(raw) + || /(?:^|\/)\.{1,2}(?:\/|$)/.test(raw) + ) { + throw new Error(`Refusing image URL with unsafe path syntax: ${raw}`); + } -function download(url, dest, referer) { - return new Promise((resolve, reject) => { - const u = new URL(url); - const opts = { - hostname: u.hostname, - path: u.pathname, - headers: { Referer: referer }, - timeout: 15_000, + let url; + try { + url = base ? new URL(raw, base) : new URL(raw); + } catch { + throw new Error(`Invalid poe2db image URL: ${raw}`); + } + if ( + url.protocol !== 'https:' + || !IMAGE_ORIGIN_SET.has(url.origin) + || url.username + || url.password + ) { + throw new Error(`Refusing non-allowlisted poe2db image URL: ${url.href}`); + } + url.hash = ''; + return url; +} + +export function validatePoe2dbReferer(value) { + let url; + try { + url = new URL(value); + } catch { + throw new Error(`Invalid poe2db referer: ${String(value)}`); + } + if ( + url.protocol !== 'https:' + || url.origin !== 'https://poe2db.tw' + || url.username + || url.password + || (url.pathname !== '/us' && !url.pathname.startsWith('/us/')) + ) { + throw new Error(`Refusing non-allowlisted poe2db referer: ${url.href}`); + } + url.search = ''; + url.hash = ''; + return url.href; +} + +function safePathSegments(encodedPath) { + if (encodedPath.length > MAX_IMAGE_PATH_LENGTH) { + throw new RangeError(`Image path exceeds ${MAX_IMAGE_PATH_LENGTH} characters`); + } + const encodedSegments = encodedPath.split('/').filter(Boolean); + if (encodedSegments.length < 1 || encodedSegments.length > MAX_IMAGE_PATH_SEGMENTS) { + throw new RangeError(`Image path must contain 1-${MAX_IMAGE_PATH_SEGMENTS} segments`); + } + + return encodedSegments.map((encodedSegment) => { + let segment; + try { + segment = decodeURIComponent(encodedSegment); + } catch { + throw new Error(`Invalid encoded image path segment: ${encodedSegment}`); + } + if ( + !segment + || segment === '.' + || segment === '..' + || segment.length > 180 + || /[\\/\u0000-\u001f\u007f<>:"|?*]/.test(segment) + || /[. ]$/.test(segment) + ) { + throw new Error(`Unsafe image path segment: ${segment}`); + } + return segment; + }); +} + +function assertImageOutputPath(candidate) { + const root = resolve(PUBLIC); + const output = resolve(candidate); + if (output === root || !output.startsWith(`${root}${sep}`)) { + throw new Error(`Image output path escapes public/images: ${candidate}`); + } + return output; +} + +function resolveContainedFile(rootDirectory, filename) { + const root = resolve(rootDirectory); + const output = resolve(root, filename); + if (output === root || !output.startsWith(`${root}${sep}`)) { + throw new Error(`Data output path escapes ${rootDirectory}: ${filename}`); + } + return output; +} + +export function resolveCategoryDataPaths(filename) { + if (!CATEGORY_FILES.has(filename)) { + throw new Error(`Unsafe processed-data filename: ${String(filename)}`); + } + return { + processed: resolveContainedFile(DATA, filename), + public: resolveContainedFile(PUBLIC_DATA, filename), + }; +} + +export function serializeCategoryItems(items) { + if (!Array.isArray(items)) throw new TypeError('Category data must be an array'); + if (items.length > MAX_ITEMS_PER_CATEGORY) { + throw new RangeError(`Category data exceeds ${MAX_ITEMS_PER_CATEGORY} items`); + } + return JSON.stringify(items, null, 2); +} + +export function syncCategoryData(filename, items) { + const paths = resolveCategoryDataPaths(filename); + const serialized = serializeCategoryItems(items); + mkdirSync(dirname(paths.processed), { recursive: true }); + mkdirSync(dirname(paths.public), { recursive: true }); + writeFileSync(paths.processed, serialized, 'utf8'); + writeFileSync(paths.public, serialized, 'utf8'); + return { ...paths, serialized }; +} + +export function assertCategoryDownloadSucceeded(filename, failureCount) { + if (!CATEGORY_FILES.has(filename)) { + throw new Error(`Unsafe processed-data filename: ${String(filename)}`); + } + if (!Number.isSafeInteger(failureCount) || failureCount < 0) { + throw new TypeError('Image failure count must be a non-negative integer'); + } + if (failureCount > 0) { + throw new Error( + `Refusing to synchronize ${filename}: ${failureCount} required image(s) failed validation or download`, + ); + } +} + +export function resolveLocalImageDestination(imageUrl, categoryKey) { + if (!CATEGORY_KEYS.has(categoryKey)) { + throw new Error(`Unsafe image category: ${String(categoryKey)}`); + } + const url = validateImageUrl(imageUrl); + const match = url.pathname.match(/\/Art\/2DItems\/(.+)$/i); + const encodedSubpath = match + ? match[1] + : url.pathname.split('/').filter(Boolean).at(-1); + if (!encodedSubpath) throw new Error(`Image URL has no filename: ${url.href}`); + + const segments = safePathSegments(encodedSubpath); + const sub = segments.join('/'); + const dest = assertImageOutputPath(resolve(PUBLIC, categoryKey, ...segments)); + return { dest, sub, url: url.href }; +} + +export function validateLocalImagePath(value, categoryKey) { + if (!CATEGORY_KEYS.has(categoryKey) || typeof value !== 'string') { + throw new Error('Local image path requires a known category and string value'); + } + if ( + value.includes('\\') + || value.includes('?') + || value.includes('#') + || /%(?:2e|2f|5c)/i.test(value) + ) { + throw new Error(`Unsafe local image path: ${value}`); + } + const prefix = LOCAL_CATEGORY_PREFIXES[categoryKey] + .find((candidate) => value.startsWith(candidate)); + if (!prefix) { + throw new Error(`Local image path does not match ${categoryKey}: ${value}`); + } + safePathSegments(value.slice(prefix.length)); + return value; +} + +export function localDest(imageUrl, categoryKey) { + if (!imageUrl) return null; + try { + return resolveLocalImageDestination(imageUrl, categoryKey); + } catch { + return null; + } +} + +export async function collectImageBody(stream, maxBytes = MAX_IMAGE_BYTES) { + if (!stream || typeof stream[Symbol.asyncIterator] !== 'function') { + throw new TypeError('Image response body must be an async iterable'); + } + if (!Number.isSafeInteger(maxBytes) || maxBytes < 1 || maxBytes > MAX_IMAGE_BYTES) { + throw new RangeError(`Image limit must be between 1 and ${MAX_IMAGE_BYTES} bytes`); + } + + const chunks = []; + let total = 0; + for await (const value of stream) { + const chunk = Buffer.isBuffer(value) ? value : Buffer.from(value); + total += chunk.length; + if (total > maxBytes) { + throw new RangeError(`Image response exceeds ${maxBytes} bytes`); + } + chunks.push(chunk); + } + return Buffer.concat(chunks, total); +} + +function requestImage(url, referer, timeoutMs, maxBytes) { + return new Promise((resolveRequest, rejectRequest) => { + let settled = false; + let hardTimer; + const settle = (callback, value) => { + if (settled) return; + settled = true; + clearTimeout(hardTimer); + callback(value); }; - https.get(opts, (res) => { - if (res.statusCode === 301 || res.statusCode === 302) { - res.resume(); - const redirect = res.headers.location; - if (!redirect) return reject(new Error(`Redirect with no Location: ${url}`)); - return download(redirect, dest, referer).then(resolve).catch(reject); + + const request = https.get(url, { + headers: { + Referer: referer, + Accept: 'image/*', + 'User-Agent': 'CraftClassBot/0.1 (+local)', + }, + timeout: timeoutMs, + }, (response) => { + const status = response.statusCode ?? 0; + if (REDIRECT_STATUSES.has(status)) { + const location = response.headers.location; + response.destroy(); + if (!location) { + settle(rejectRequest, new Error(`Redirect with no Location: ${url.href}`)); + return; + } + settle(resolveRequest, { redirect: location }); + return; + } + if (status !== 200) { + response.destroy(); + settle(rejectRequest, new Error(`HTTP ${status} for ${url.href}`)); + return; + } + + const contentType = String(response.headers['content-type'] || '').split(';', 1)[0].trim().toLowerCase(); + if (contentType && !contentType.startsWith('image/')) { + response.destroy(); + settle(rejectRequest, new Error(`Unexpected content type ${contentType} for ${url.href}`)); + return; } - if (res.statusCode !== 200) { - res.resume(); - return reject(new Error(`HTTP ${res.statusCode} for ${url}`)); + const declaredLength = Number(response.headers['content-length']); + if (Number.isFinite(declaredLength) && declaredLength > maxBytes) { + response.destroy(); + settle(rejectRequest, new RangeError(`Image exceeds ${maxBytes} bytes: ${url.href}`)); + return; } - const chunks = []; - res.on('data', c => chunks.push(c)); - res.on('end', () => { - mkdirSync(dirname(dest), { recursive: true }); - writeFileSync(dest, Buffer.concat(chunks)); - resolve(); - }); - res.on('error', reject); - }).on('error', reject).on('timeout', function () { - this.destroy(); - reject(new Error(`Timeout fetching ${url}`)); + + collectImageBody(response, maxBytes) + .then((body) => settle(resolveRequest, { body })) + .catch((error) => { + response.destroy(); + settle(rejectRequest, error); + }); + }); + request.on('timeout', () => { + request.destroy(new Error(`Timeout fetching ${url.href} after ${timeoutMs}ms`)); }); + request.on('error', (error) => settle(rejectRequest, error)); + hardTimer = setTimeout(() => { + const error = new Error(`Timeout fetching ${url.href} after ${timeoutMs}ms`); + settle(rejectRequest, error); + request.destroy(error); + }, timeoutMs); }); } -function localDest(imageUrl, categoryKey) { - if (!imageUrl) return null; - try { - const u = new URL(imageUrl); - // Extract the path after "Art/2DItems/" — that's the logical filename path - const match = u.pathname.match(/\/Art\/2DItems\/(.+)$/i); - if (!match) { - const parts = u.pathname.split('/'); - return { dest: join(PUBLIC, categoryKey, parts[parts.length - 1]), sub: parts[parts.length - 1] }; +export async function downloadImage( + value, + dest, + referer, + { + timeoutMs = IMAGE_REQUEST_TIMEOUT_MS, + maxBytes = MAX_IMAGE_BYTES, + maxRedirects = MAX_IMAGE_REDIRECTS, + requestImpl = requestImage, + } = {}, +) { + if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > IMAGE_REQUEST_TIMEOUT_MS) { + throw new RangeError(`Timeout must be between 1 and ${IMAGE_REQUEST_TIMEOUT_MS}ms`); + } + if (!Number.isSafeInteger(maxBytes) || maxBytes < 1 || maxBytes > MAX_IMAGE_BYTES) { + throw new RangeError(`Image limit must be between 1 and ${MAX_IMAGE_BYTES} bytes`); + } + if (!Number.isSafeInteger(maxRedirects) || maxRedirects < 0 || maxRedirects > MAX_IMAGE_REDIRECTS) { + throw new RangeError(`Redirect limit must be between 0 and ${MAX_IMAGE_REDIRECTS}`); + } + if (typeof requestImpl !== 'function') throw new TypeError('Image request implementation must be a function'); + + const output = assertImageOutputPath(dest); + const safeReferer = validatePoe2dbReferer(referer); + let url = validateImageUrl(value); + for (let redirectCount = 0; ; redirectCount++) { + const result = await requestImpl(url, safeReferer, timeoutMs, maxBytes); + if (!result || typeof result !== 'object') { + throw new TypeError('Image request returned an invalid result'); } - // Keep original case (matches poe2db's file naming) but join under categoryKey - const sub = match[1].replace(/\\/g, '/'); - return { dest: join(PUBLIC, categoryKey, sub), sub }; - } catch { - return null; + if (result.redirect) { + if (redirectCount >= maxRedirects) { + throw new Error(`Too many redirects fetching ${url.href}`); + } + url = validateImageUrl(result.redirect, url); + continue; + } + if (!Buffer.isBuffer(result.body) && !(result.body instanceof Uint8Array)) { + throw new TypeError('Image request returned no response body'); + } + if (result.body.byteLength > maxBytes) { + throw new RangeError(`Image response exceeds ${maxBytes} bytes`); + } + + mkdirSync(dirname(output), { recursive: true }); + writeFileSync(output, result.body); + return; } } -function toRelative(localResult) { +export function toRelative(localResult) { // The dest is like ...\public\images\currency\Currency\AncientOrb.webp // We want /images/currency/Currency/AncientOrb.webp const norm = localResult.dest.replace(/\\/g, '/'); @@ -100,20 +393,23 @@ function toRelative(localResult) { return '/images/' + localResult.sub; } -async function main() { +export async function main() { let total = 0, skipped = 0, failed = 0; for (const cat of CATEGORIES) { - const filePath = join(DATA, cat.file); + const { processed: filePath } = resolveCategoryDataPaths(cat.file); if (!existsSync(filePath)) { - console.warn(` [SKIP] ${cat.file} not found`); - continue; + throw new Error(`Required processed-data file not found: ${cat.file}`); } const items = JSON.parse(readFileSync(filePath, 'utf-8')); if (!Array.isArray(items)) { - console.warn(` [SKIP] ${cat.file} is not an array`); - continue; + throw new TypeError(`Required processed-data file is not an array: ${cat.file}`); + } + if (items.length > MAX_ITEMS_PER_CATEGORY) { + throw new RangeError( + `Refusing ${items.length} items from ${cat.file}; limit is ${MAX_ITEMS_PER_CATEGORY}`, + ); } console.log(`\n ${cat.file} (${items.length} items) …`); @@ -121,13 +417,30 @@ async function main() { // Build a list of items that need downloading const needDownload = []; let changed = false; + let categoryFailures = 0; for (const item of items) { + if (!item || typeof item !== 'object' || Array.isArray(item)) continue; const orig = item.imageUrl; - if (!orig || orig.startsWith('/images/') || orig.startsWith('./')) continue; + if (typeof orig !== 'string' || !orig) continue; + if (orig.startsWith('/images/')) { + try { + validateLocalImagePath(orig, cat.key); + } catch (error) { + failed++; + categoryFailures++; + console.warn(` [SKIP] ${error.message}`); + } + continue; + } const loc = localDest(orig, cat.key); - if (!loc) continue; + if (!loc) { + failed++; + categoryFailures++; + console.warn(` [SKIP] Refusing non-allowlisted or unsafe image URL: ${String(orig)}`); + continue; + } const destPath = loc.dest; item.imageUrl = toRelative(loc); @@ -148,11 +461,12 @@ async function main() { while (queue.length > 0) { const job = queue.shift(); try { - await download(job.orig, job.destPath, job.referer); + await downloadImage(job.orig, job.destPath, job.referer); total++; if (total % 25 === 0) console.log(` … ${total} downloaded`); } catch (err) { failed++; + categoryFailures++; console.error(` [FAIL] ${err.message}`); // Restore original CDN URL job.item.imageUrl = job.orig; @@ -163,8 +477,9 @@ async function main() { await Promise.all(workers); } + assertCategoryDownloadSucceeded(cat.file, categoryFailures); if (changed) { - writeFileSync(filePath, JSON.stringify(items, null, 2), 'utf-8'); + syncCategoryData(cat.file, items); console.log(` ✓ URLs localised` + (needDownload.length > 0 ? ` (${needDownload.length} new)` : '')); } else { console.log(` (no changes)`); @@ -177,4 +492,14 @@ async function main() { } } -main(); +export function isDirectExecution(metaUrl, argvEntry = process.argv[1]) { + if (!argvEntry) return false; + return pathToFileURL(resolve(argvEntry)).href === metaUrl; +} + +if (isDirectExecution(import.meta.url)) { + main().catch((error) => { + console.error(error); + process.exitCode = 1; + }); +} diff --git a/scripts/fetch-poe2db.mjs b/scripts/fetch-poe2db.mjs index 54a656d..082e8e9 100644 --- a/scripts/fetch-poe2db.mjs +++ b/scripts/fetch-poe2db.mjs @@ -3,18 +3,30 @@ // poe2db's own listing pages (Currency / Essence / Omen) plus a known-good base // item subcategory list. Output: data/raw/*.html + data/raw/index.json. -import { mkdir, writeFile, readFile } from 'node:fs/promises'; +import { mkdir, writeFile, readFile, stat } from 'node:fs/promises'; import { existsSync } from 'node:fs'; import path from 'node:path'; -import { fileURLToPath } from 'node:url'; +import { fileURLToPath, pathToFileURL } from 'node:url'; import * as cheerio from 'cheerio'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const ROOT = path.resolve(__dirname, '..'); const RAW = path.join(ROOT, 'data', 'raw'); -const BASE_URL = 'https://poe2db.tw/us'; +export const POE2DB_PAGE_ORIGIN = 'https://poe2db.tw'; +export const BASE_URL = `${POE2DB_PAGE_ORIGIN}/us`; +export const REQUEST_TIMEOUT_MS = 15_000; +export const MAX_RESPONSE_BYTES = 8 * 1024 * 1024; +export const MAX_REDIRECTS = 3; +export const MAX_FETCH_ATTEMPTS = 3; +export const MAX_DISCOVERED_ITEMS = 500; +export const MAX_GROUP_ITEMS = 1_000; +export const MAX_SLUG_LENGTH = 128; + const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) CraftClassBot/0.1 (+local)'; +const SAFE_SLUG_RE = new RegExp(`^[A-Za-z0-9][A-Za-z0-9_-]{0,${MAX_SLUG_LENGTH - 1}}$`); +const SAFE_RAW_LABELS = new Set(['base', 'currency', 'guide', 'omen']); +const REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]); // Base item subcategory pages. These are the index pages for each slot on poe2db // (e.g. /us/Helmets_str). poe2db doesn't have a single "all bases" listing, so @@ -94,13 +106,217 @@ const EXTRA_OMEN_PAGES = [ 'Omen_of_Abyssal_Echoes', // Cranium re-roll ]; -async function fetchPage(url) { - const res = await fetch(url, { headers: { 'User-Agent': UA, 'Accept': 'text/html,application/xhtml+xml' } }); - if (!res.ok) throw new Error(`HTTP ${res.status}`); - return await res.text(); +export function validatePageUrl(value, base = `${BASE_URL}/`) { + let url; + try { + url = new URL(value, base); + } catch { + throw new Error(`Invalid poe2db page URL: ${String(value)}`); + } + + if ( + url.protocol !== 'https:' + || url.origin !== POE2DB_PAGE_ORIGIN + || url.username + || url.password + || (url.pathname !== '/us' && !url.pathname.startsWith('/us/')) + ) { + throw new Error(`Refusing non-allowlisted poe2db page URL: ${url.href}`); + } + if (url.search) { + throw new Error(`Refusing poe2db page URL with query parameters: ${url.href}`); + } + + url.hash = ''; + return url; +} + +export function normalizeListingSlug(value) { + if (typeof value !== 'string') return null; + const raw = value.trim(); + if (!raw || raw === '#' || raw.includes('\\') || raw.includes('?')) return null; + + // Listing links are expected to be a single slug, /us/, or the + // equivalent absolute allowlisted URL. Reject path-relative traversal even + // when URL normalization would happen to bring it back under /us/. + const hashless = raw.split('#', 1)[0]; + if ( + !SAFE_SLUG_RE.test(hashless) + && !hashless.startsWith('/us/') + && !hashless.startsWith(`${POE2DB_PAGE_ORIGIN}/us/`) + ) { + return null; + } + + let url; + try { + url = validatePageUrl(hashless); + } catch { + return null; + } + + const encodedSlug = url.pathname.slice('/us/'.length); + if (!encodedSlug || encodedSlug.includes('/')) return null; + + let slug; + try { + slug = decodeURIComponent(encodedSlug); + } catch { + return null; + } + return SAFE_SLUG_RE.test(slug) ? slug : null; } -async function fetchWithRetry(url, attempts = 3) { +export function boundedUniqueSlugs(values, maxItems = MAX_GROUP_ITEMS) { + if (!Array.isArray(values)) throw new TypeError('Expected an array of poe2db slugs'); + if (!Number.isSafeInteger(maxItems) || maxItems < 1 || maxItems > MAX_GROUP_ITEMS) { + throw new RangeError(`Slug limit must be between 1 and ${MAX_GROUP_ITEMS}`); + } + if (values.length > maxItems) { + throw new RangeError(`Refusing ${values.length} poe2db slugs; limit is ${maxItems}`); + } + + const unique = []; + const seen = new Set(); + for (const value of values) { + const slug = normalizeListingSlug(value); + if (!slug) throw new Error(`Unsafe poe2db slug: ${String(value)}`); + if (!seen.has(slug)) { + seen.add(slug); + unique.push(slug); + } + } + return unique; +} + +export function resolveRawFile(filename) { + if ( + typeof filename !== 'string' + || !/^[A-Za-z0-9_][A-Za-z0-9_.-]{0,191}$/.test(filename) + || filename === '.' + || filename === '..' + ) { + throw new Error(`Unsafe raw filename: ${String(filename)}`); + } + const resolved = path.resolve(RAW, filename); + if (path.dirname(resolved) !== RAW) { + throw new Error(`Raw output path escapes data/raw: ${filename}`); + } + return resolved; +} + +export function resolveRawGroupFile(label, slug) { + if (!SAFE_RAW_LABELS.has(label)) throw new Error(`Unsafe raw group label: ${String(label)}`); + const normalized = normalizeListingSlug(slug); + if (!normalized) throw new Error(`Unsafe poe2db slug: ${String(slug)}`); + return resolveRawFile(`${label}_${normalized}.html`); +} + +async function readBoundedTextFile(filename, maxBytes = MAX_RESPONSE_BYTES) { + const file = resolveRawFile(filename); + const info = await stat(file); + if (info.size > maxBytes) { + throw new RangeError(`Refusing oversized cached HTML ${filename}: ${info.size} bytes`); + } + return await readFile(file, 'utf8'); +} + +async function responseTextWithinLimit(response, maxBytes) { + const declaredLength = Number(response.headers.get('content-length')); + if (Number.isFinite(declaredLength) && declaredLength > maxBytes) { + await response.body?.cancel(); + throw new RangeError(`Response exceeds ${maxBytes} bytes`); + } + if (!response.body) return ''; + + const reader = response.body.getReader(); + const chunks = []; + let total = 0; + try { + while (true) { + const { done, value } = await reader.read(); + if (done) break; + total += value.byteLength; + if (total > maxBytes) { + await reader.cancel(); + throw new RangeError(`Response exceeds ${maxBytes} bytes`); + } + chunks.push(Buffer.from(value)); + } + } finally { + reader.releaseLock(); + } + return Buffer.concat(chunks, total).toString('utf8'); +} + +export async function fetchPage( + value, + { + fetchImpl = fetch, + timeoutMs = REQUEST_TIMEOUT_MS, + maxBytes = MAX_RESPONSE_BYTES, + maxRedirects = MAX_REDIRECTS, + } = {}, +) { + if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > REQUEST_TIMEOUT_MS) { + throw new RangeError(`Timeout must be between 1 and ${REQUEST_TIMEOUT_MS}ms`); + } + if (!Number.isSafeInteger(maxBytes) || maxBytes < 1 || maxBytes > MAX_RESPONSE_BYTES) { + throw new RangeError(`Response limit must be between 1 and ${MAX_RESPONSE_BYTES} bytes`); + } + if (!Number.isSafeInteger(maxRedirects) || maxRedirects < 0 || maxRedirects > MAX_REDIRECTS) { + throw new RangeError(`Redirect limit must be between 0 and ${MAX_REDIRECTS}`); + } + + let url = validatePageUrl(value); + for (let redirectCount = 0; ; redirectCount++) { + const controller = new AbortController(); + let timer; + const deadline = new Promise((_, reject) => { + timer = setTimeout(() => { + controller.abort(); + reject(new Error(`Timeout fetching ${url.href} after ${timeoutMs}ms`)); + }, timeoutMs); + }); + try { + const operation = (async () => { + const response = await fetchImpl(url, { + headers: { 'User-Agent': UA, 'Accept': 'text/html,application/xhtml+xml' }, + redirect: 'manual', + signal: controller.signal, + }); + + if (REDIRECT_STATUSES.has(response.status)) { + await response.body?.cancel(); + return { redirect: response.headers.get('location') }; + } + if (!response.ok) { + await response.body?.cancel(); + throw new Error(`HTTP ${response.status}`); + } + return { html: await responseTextWithinLimit(response, maxBytes) }; + })(); + + const result = await Promise.race([operation, deadline]); + if ('redirect' in result) { + if (redirectCount >= maxRedirects) { + throw new Error(`Too many redirects fetching ${url.href}`); + } + if (!result.redirect) throw new Error(`Redirect with no Location: ${url.href}`); + url = validatePageUrl(result.redirect, url); + continue; + } + return result.html; + } finally { + clearTimeout(timer); + } + } +} + +async function fetchWithRetry(url, attempts = MAX_FETCH_ATTEMPTS) { + if (!Number.isSafeInteger(attempts) || attempts < 1 || attempts > MAX_FETCH_ATTEMPTS) { + throw new RangeError(`Fetch attempts must be between 1 and ${MAX_FETCH_ATTEMPTS}`); + } for (let i = 0; i < attempts; i++) { try { return await fetchPage(url); } catch (err) { @@ -114,7 +330,25 @@ async function fetchWithRetry(url, attempts = 3) { // Discover item slugs from a listing page (e.g. /Currency, /Essence, /Omen). // poe2db uses both (some tabs) and SVG (Currency Tab /37) formats. -async function discoverFromListing(html) { +function assertListingHtml(html) { + if (typeof html !== 'string') throw new TypeError('Listing HTML must be a string'); + const bytes = Buffer.byteLength(html, 'utf8'); + if (bytes > MAX_RESPONSE_BYTES) { + throw new RangeError(`Listing HTML exceeds ${MAX_RESPONSE_BYTES} bytes`); + } +} + +function addDiscoveredSlug(slugs, value) { + const slug = normalizeListingSlug(value); + if (!slug) return; + slugs.add(slug); + if (slugs.size > MAX_DISCOVERED_ITEMS) { + throw new RangeError(`Listing exceeds ${MAX_DISCOVERED_ITEMS} discovered items`); + } +} + +export function discoverFromListing(html) { + assertListingHtml(html); const $ = cheerio.load(html); const slugs = new Set(); @@ -127,8 +361,7 @@ async function discoverFromListing(html) { if (!/\/2DItems\/Currency\//.test(src)) return; const href = $a.attr('href') || ''; if (!href || href === '#') return; - const slug = href.replace(/^\/us\//, '').split('#')[0]; - if (slug) slugs.add(slug); + addDiscoveredSlug(slugs, href); }); // Check for SVG elements with xlink:href (used in Currency Tab /37 SVG grid) @@ -140,8 +373,7 @@ async function discoverFromListing(html) { if (!/\/2DItems\/Currency\//.test(src)) return; const href = $a.attr('xlink:href') || ''; if (!href || href === '#') return; - const slug = href.replace(/^\/us\//, '').split('#')[0]; - if (slug) slugs.add(slug); + addDiscoveredSlug(slugs, href); }); return [...slugs]; @@ -149,24 +381,46 @@ async function discoverFromListing(html) { // Discover item slugs from the Liquid Emotions listing page. // This page uses a card-based layout with plain links to individual pages. -async function discoverFromLiquidListing(html) { +export function discoverPlainListing(html, requiredName) { + assertListingHtml(html); + if (!(requiredName instanceof RegExp)) { + throw new TypeError('Plain-listing name matcher must be a RegExp'); + } + const nameMatcher = new RegExp(requiredName.source, requiredName.flags.replace(/[gy]/g, '')); const $ = cheerio.load(html); const slugs = new Set(); $('a[href]').each((_, a) => { const href = $(a).attr('href') || ''; - // Liquid emotion pages have slugs like "Diluted_Liquid_Ire", "Liquid_Paranoia", etc. - // They don't start with / or # and don't contain / - if (/^[A-Z][a-zA-Z_]+$/.test(href) && /Liquid/i.test(href)) { - slugs.add(href); - } + const slug = normalizeListingSlug(href); + if (slug && nameMatcher.test(slug)) addDiscoveredSlug(slugs, slug); }); return [...slugs]; } +export function discoverFromLiquidListing(html) { + // Liquid emotion pages have slugs like "Diluted_Liquid_Ire" and + // "Liquid_Paranoia". + return discoverPlainListing(html, /Liquid/i); +} + +export function assertNoFetchFailures(label, results) { + if (typeof label !== 'string' || !label) throw new TypeError('Fetch group label is required'); + if (!Array.isArray(results)) throw new TypeError('Fetch results must be an array'); + const failures = results.filter(({ error }) => error); + if (failures.length > 0) { + throw new AggregateError( + failures.map(({ slug, error }) => new Error(`${label}/${slug}: ${error}`)), + `Required poe2db group ${label} failed for ${failures.length} page(s)`, + ); + } + return results; +} + async function fetchGroup(label, pages) { + const safePages = boundedUniqueSlugs(pages, MAX_GROUP_ITEMS); const out = []; - for (const slug of pages) { - const file = path.join(RAW, `${label}_${slug}.html`); + for (const slug of safePages) { + const file = resolveRawGroupFile(label, slug); if (existsSync(file)) { console.log(` [cached] ${label}/${slug}`); out.push({ slug, file, cached: true }); @@ -184,16 +438,16 @@ async function fetchGroup(label, pages) { } await new Promise((r) => setTimeout(r, 250)); } - return out; + return assertNoFetchFailures(label, out); } -async function main() { +export async function main() { await mkdir(RAW, { recursive: true }); // Step 1: fetch listing pages so we can discover current item slugs console.log('Fetching listing pages (for slug discovery)...'); for (const lp of LISTING_PAGES) { - const file = path.join(RAW, lp.saveAs); + const file = resolveRawFile(lp.saveAs); if (existsSync(file)) { console.log(` [cached] ${lp.saveAs}`); continue; @@ -205,16 +459,17 @@ async function main() { console.log('ok'); } catch (err) { console.log(`FAIL (${err.message})`); + throw new Error(`Required poe2db listing failed: ${lp.url}`, { cause: err }); } } // Step 2: discover item slugs from each listing const discovered = {}; for (const lp of LISTING_PAGES) { - const file = path.join(RAW, lp.saveAs); + const file = resolveRawFile(lp.saveAs); if (!existsSync(file)) continue; - const html = await readFile(file, 'utf8'); - const slugs = await discoverFromListing(html); + const html = await readBoundedTextFile(lp.saveAs); + const slugs = discoverFromListing(html); discovered[lp.saveAs] = slugs; console.log(` discovered ${slugs.length} slugs from ${lp.saveAs}`); } @@ -230,10 +485,10 @@ async function main() { liquidSlugs = discovered['_listing_liquid.html']; } else { // Fallback: try discovering from the raw liquid listing page - const liquidFile = path.join(RAW, '_listing_liquid.html'); + const liquidFile = resolveRawFile('_listing_liquid.html'); if (existsSync(liquidFile)) { - const html = await readFile(liquidFile, 'utf8'); - liquidSlugs = await discoverFromLiquidListing(html); + const html = await readBoundedTextFile('_listing_liquid.html'); + liquidSlugs = discoverFromLiquidListing(html); discovered['_listing_liquid.html'] = liquidSlugs; console.log(` discovered ${liquidSlugs.length} slugs from _listing_liquid.html (fallback)`); } @@ -263,17 +518,10 @@ async function main() { if (discovered['_listing_catalyst.html']) { catalystSlugs = discovered['_listing_catalyst.html']; } else { - const catalystFile = path.join(RAW, '_listing_catalyst.html'); + const catalystFile = resolveRawFile('_listing_catalyst.html'); if (existsSync(catalystFile)) { - const html = await readFile(catalystFile, 'utf8'); - const $ = cheerio.load(html); - catalystSlugs = []; - $('a[href]').each((_, a) => { - const href = $(a).attr('href') || ''; - if (/^[A-Z][a-zA-Z_]+$/.test(href) && /Catalyst/i.test(href)) { - catalystSlugs.push(href); - } - }); + const html = await readBoundedTextFile('_listing_catalyst.html'); + catalystSlugs = discoverPlainListing(html, /Catalyst/i); console.log(` discovered ${catalystSlugs.length} catalyst slugs`); } } @@ -288,7 +536,7 @@ async function main() { await fetchGroup('guide', GUIDE_PAGES); console.log('\nFetching home (season detection)...'); - const homeFile = path.join(RAW, 'home.html'); + const homeFile = resolveRawFile('home.html'); if (!existsSync(homeFile)) { try { const html = await fetchWithRetry(BASE_URL); @@ -296,6 +544,7 @@ async function main() { console.log(' ok'); } catch (err) { console.log(` FAIL (${err.message})`); + throw new Error('Required poe2db home page failed', { cause: err }); } } else { console.log(' [cached] home'); @@ -304,5 +553,14 @@ async function main() { console.log('\nDone. Run `npm run process` next.'); } -main().catch((err) => { console.error(err); process.exit(1); }); +export function isDirectExecution(metaUrl, argvEntry = process.argv[1]) { + if (!argvEntry) return false; + return pathToFileURL(path.resolve(argvEntry)).href === metaUrl; +} +if (isDirectExecution(import.meta.url)) { + main().catch((err) => { + console.error(err); + process.exitCode = 1; + }); +} diff --git a/scripts/process-data.mjs b/scripts/process-data.mjs index 256427a..1ca8dff 100644 --- a/scripts/process-data.mjs +++ b/scripts/process-data.mjs @@ -14,6 +14,14 @@ const RAW = path.join(ROOT, 'data', 'raw'); const OUT = path.join(ROOT, 'data', 'processed'); const CDN = 'https://cdn.poe2db.tw'; +export const DATASET_COUNT_FLOORS = Object.freeze({ + bases: 500, + mods: 500, + currency: 50, + omens: 20, +}); +export const MAX_DATASET_DROP_RATIO = 0.25; +export const MAX_DATASET_GROWTH_RATIO = 0.50; const SLOT_MAP = { Helmets_str: 'helmet', Helmets_dex: 'helmet', Helmets_int: 'helmet', @@ -803,12 +811,6 @@ function parseSeason($) { }); } - // As a last resort, use the current known patch (accurate as of 2025). - // This gets updated when npm run fetch fetches the latest data. - if (!version || version === '0.0.0') { - version = '0.5.4b'; - } - return { id: slugify(name), name, version }; } @@ -1050,9 +1052,55 @@ async function processFile(filename) { return null; } -async function main() { +export function assertProcessedDataQuality({ + season, + counts, + previousCounts = null, + parseFailures = [], +}) { + if (!Array.isArray(parseFailures)) { + throw new TypeError('parseFailures must be an array'); + } + if (parseFailures.length > 0) { + throw new AggregateError( + parseFailures.map(({ file, error }) => new Error(`${file}: ${error?.message ?? error}`)), + `Refusing partial processed data after ${parseFailures.length} parser failure(s)`, + ); + } + if ( + !season + || season.id === 'unknown' + || season.name === 'Unknown' + || !/^\d+\.\d+\.\d+[a-z]?$/i.test(season.version ?? '') + ) { + throw new Error('Refusing processed data with an unknown or invalid season'); + } + + for (const [key, floor] of Object.entries(DATASET_COUNT_FLOORS)) { + const count = counts?.[key]; + if (!Number.isSafeInteger(count) || count < floor) { + throw new RangeError(`Processed ${key} count ${count} is below safety floor ${floor}`); + } + const previous = previousCounts?.[key]; + if (!Number.isSafeInteger(previous) || previous < 1) continue; + const lowerBound = Math.floor(previous * (1 - MAX_DATASET_DROP_RATIO)); + const upperBound = Math.ceil(previous * (1 + MAX_DATASET_GROWTH_RATIO)); + if (count < lowerBound || count > upperBound) { + throw new RangeError( + `Processed ${key} count ${count} is outside reviewed drift range ${lowerBound}-${upperBound}`, + ); + } + } +} + +export async function main() { await mkdir(OUT, { recursive: true }); const files = (await readdir(RAW)).filter((f) => f.endsWith('.html')); + let previousManifest = null; + const previousManifestPath = path.join(OUT, 'manifest.json'); + if (existsSync(previousManifestPath)) { + previousManifest = JSON.parse(await readFile(previousManifestPath, 'utf8')); + } let season = { id: 'unknown', name: 'Unknown', version: '0.0.0', detectedAt: new Date().toISOString(), source: 'poe2db' }; const bases = []; @@ -1060,6 +1108,7 @@ async function main() { const currency = []; const omens = []; let essenceListingHtml = null; + const parseFailures = []; for (const file of files) { try { @@ -1084,6 +1133,7 @@ async function main() { } } catch (err) { console.warn(`Failed ${file}: ${err.message}`); + parseFailures.push({ file, error: err }); } } @@ -1149,6 +1199,18 @@ async function main() { } } const modsFinal = [...modByDesc.values()].sort((a, b) => a.name.localeCompare(b.name)); + const counts = { + bases: basesFinal.length, + mods: modsFinal.length, + currency: currency.length, + omens: omens.length, + }; + assertProcessedDataQuality({ + season, + counts, + previousCounts: previousManifest?.counts, + parseFailures, + }); await writeFile(path.join(OUT, 'season.json'), JSON.stringify(season, null, 2), 'utf8'); await writeFile(path.join(OUT, 'bases.json'), JSON.stringify(basesFinal, null, 2), 'utf8'); @@ -1159,12 +1221,7 @@ async function main() { const manifest = { generatedAt: new Date().toISOString(), season, - counts: { - bases: basesFinal.length, - mods: modsFinal.length, - currency: currency.length, - omens: omens.length, - }, + counts, }; await writeFile(path.join(OUT, 'manifest.json'), JSON.stringify(manifest, null, 2), 'utf8'); @@ -1203,7 +1260,14 @@ async function main() { } } -main().catch((err) => { - console.error(err); - process.exit(1); -}); +export function isDirectExecution(metaUrl, argvEntry = process.argv[1]) { + if (!argvEntry) return false; + return pathToFileURL(path.resolve(argvEntry)).href === metaUrl; +} + +if (isDirectExecution(import.meta.url)) { + main().catch((err) => { + console.error(err); + process.exitCode = 1; + }); +} diff --git a/scripts/refresh.mjs b/scripts/refresh.mjs index a822718..83f3b2d 100644 --- a/scripts/refresh.mjs +++ b/scripts/refresh.mjs @@ -15,10 +15,13 @@ function run(cmd, args) { }); } -console.log('==> Step 1/2: fetch-poe2db'); +console.log('==> Step 1/3: fetch-poe2db'); await run('node', ['scripts/fetch-poe2db.mjs']); -console.log('\n==> Step 2/2: process-data'); +console.log('\n==> Step 2/3: process-data'); await run('node', ['scripts/process-data.mjs']); -console.log('\nRefresh complete. Run `npm run build` to bake JSON into the static site.'); +console.log('\n==> Step 3/3: download-images'); +await run('node', ['scripts/download-images.mjs']); + +console.log('\nRefresh complete. Run `npm run check` to verify the static site.'); diff --git a/scripts/verify-seo.mjs b/scripts/verify-seo.mjs new file mode 100644 index 0000000..1d2f593 --- /dev/null +++ b/scripts/verify-seo.mjs @@ -0,0 +1,1288 @@ +import { access, readFile, readdir } from 'node:fs/promises'; +import path from 'node:path'; +import { load } from 'cheerio'; +import yaml from 'js-yaml'; +import { escapeHtml } from '../src/lib/safe-html.js'; +import { serializeJsonForScript } from '../src/lib/safe-json.js'; + +const ROOT = process.cwd(); +const DIST = path.join(ROOT, 'dist'); +const SITE = new URL('https://exilecrafter.com/'); +const POLICY_PATH = path.join(ROOT, 'seo-skill-policy.json'); +const POLICY_ONLY = process.argv.includes('--policy-only'); +const failures = []; +const EXPECTED_ORIGIN_ROBOTS = [ + 'User-agent: *', + 'Allow: /', + '', + 'Sitemap: https://exilecrafter.com/sitemap-index.xml', +].join('\n'); + +const expectedSkills = [ + 'seo-audit', + 'seo-page', + 'seo-technical', + 'seo-content', + 'seo-schema', + 'seo-images', + 'seo-sitemap', + 'seo-geo', + 'seo-performance', + 'seo-visual', + 'seo-plan', + 'seo-programmatic', + 'seo-competitor-pages', + 'seo-hreflang', + 'seo-local', + 'seo-maps', + 'seo-google', + 'seo-backlinks', + 'seo-cluster', + 'seo-sxo', + 'seo-drift', + 'seo-ecommerce', + 'seo-firecrawl', + 'seo-dataforseo', + 'seo-image-gen', + 'seo-flow', + 'seo-intel', + 'seo-release-guard', +]; + +function fail(scope, message) { + failures.push(`${scope}: ${message}`); +} + +function expectThrow(scope, operation) { + try { + operation(); + fail(scope, 'malicious fixture was accepted'); + } catch { + // Expected rejection. + } +} + +async function expectRejection(scope, operation) { + try { + await operation(); + fail(scope, 'malicious fixture was accepted'); + } catch { + // Expected rejection. + } +} + +function normalizedText(value) { + return value.replace(/\s+/g, ' ').trim(); +} + +function markdownAnchors(source) { + const anchors = new Set( + [...source.matchAll(/\bid=["']([^"']+)["']/g)].map((match) => match[1]), + ); + for (const match of source.matchAll(/^#{1,6}\s+(.+?)\s*#*\s*$/gm)) { + const slug = match[1] + .replace(/[`*_~]/g, '') + .toLocaleLowerCase('en') + .replace(/[^\p{Letter}\p{Number}\s-]/gu, '') + .trim() + .replace(/\s+/g, '-'); + if (slug) anchors.add(slug); + } + return anchors; +} + +function isExpectedOriginRobots(source) { + return source.replace(/\r\n/g, '\n').trim() === EXPECTED_ORIGIN_ROBOTS; +} + +function expectedPageRobots(route) { + return route === '/404.html' || route === '/optimizer/' + ? 'noindex,follow' + : 'index,follow,max-image-preview:large,max-snippet:-1,max-video-preview:-1'; +} + +function hasExpectedPageRobots(route, value) { + return value === expectedPageRobots(route); +} + +function outputFailures() { + if (failures.length === 0) return; + + console.error(`\nSEO verification failed with ${failures.length} issue(s):`); + for (const issue of failures.slice(0, 50)) { + console.error(`- ${issue}`); + } + if (failures.length > 50) { + console.error(`- …and ${failures.length - 50} more`); + } + process.exitCode = 1; +} + +async function checkUntrustedDataGuards() { + const maliciousValue = { + name: '', + separators: '<>&\u2028\u2029', + }; + const serialized = serializeJsonForScript(maliciousValue); + if (/<\/script/i.test(serialized) || /${serialized}`, + ); + if (fixture('#seo-xss-fixture').length !== 0) { + fail('safe-json', 'malicious fixture escaped into the DOM'); + } + try { + JSON.parse(fixture('#fixture').html() ?? ''); + } catch (error) { + fail('safe-json', `inline JSON fixture is not parseable: ${error.message}`); + } + + const maliciousHtml = 'x" onerror="alert(1)">'; + const escapedHtml = escapeHtml(maliciousHtml); + const attributeFixture = load(``); + if ( + attributeFixture('#target').attr('src') !== maliciousHtml + || attributeFixture('#target').attr('onerror') !== undefined + || attributeFixture('#html-xss-fixture').length !== 0 + ) { + fail('safe-html', 'malicious attribute fixture escaped its quoted attribute'); + } + const textFixture = load(`
${escapedHtml}
`); + if ( + textFixture('#target').text() !== maliciousHtml + || textFixture('#html-xss-fixture').length !== 0 + ) { + fail('safe-html', 'malicious text fixture escaped into the DOM'); + } + const blockingRobotsFixture = [ + 'User-agent: *', + 'Disallow: /', + '', + 'Sitemap: https://exilecrafter.com/sitemap-index.xml', + ].join('\n'); + if (isExpectedOriginRobots(blockingRobotsFixture)) { + fail('robots.txt', 'a sitewide Disallow fixture bypassed the origin policy guard'); + } + if (hasExpectedPageRobots('/', 'index,nofollow')) { + fail('robots meta', 'an index,nofollow fixture bypassed the page policy guard'); + } + + const [simulatorSource, optimizerSource, calculatorSource] = await Promise.all([ + readFile(path.join(ROOT, 'src/pages/simulator.astro'), 'utf8'), + readFile(path.join(ROOT, 'src/pages/optimizer.astro'), 'utf8'), + readFile(path.join(ROOT, 'src/pages/calculator.astro'), 'utf8'), + ]); + if (!simulatorSource.includes('serializeJsonForScript(baseOptions)')) { + fail('simulator', 'external base data must use the safe inline JSON serializer'); + } + if (optimizerSource.includes('detectedBase.innerHTML')) { + fail('optimizer', 'external base names must not be assigned through innerHTML'); + } + const unsafeSourcePatterns = [ + [simulatorSource, 'src="${o.imageUrl}"', 'simulator omen image URL'], + [simulatorSource, 'src="${c.imageUrl}"', 'simulator currency image URL'], + [simulatorSource, '${s.currencyName}', 'simulator currency history name'], + [calculatorSource, 'data-mod-id="${m.id}"', 'calculator modifier ID attribute'], + [calculatorSource, 'CSS.escape(m.id)', 'calculator HTML attribute ID'], + ]; + for (const [source, pattern, scope] of unsafeSourcePatterns) { + if (source.includes(pattern)) { + fail(scope, `untrusted-data sink is not escaped: ${pattern}`); + } + } +} + +async function checkExternalRefreshGuards() { + const pageGuards = await import('./fetch-poe2db.mjs'); + const imageGuards = await import('./download-images.mjs'); + const processGuards = await import('./process-data.mjs'); + + if (pageGuards.normalizeListingSlug('/us/Exalted_Orb#details') !== 'Exalted_Orb') { + fail('poe2db page guard', 'valid same-origin listing slug was not normalized'); + } + for (const value of [ + 'https://example.com/us/Exalted_Orb', + 'http://poe2db.tw/us/Exalted_Orb', + '../../../../tmp/poison', + '/us/%2e%2e%2fpoison', + '/us/Exalted_Orb?next=https://example.com', + '//127.0.0.1/us/Exalted_Orb', + ]) { + if (pageGuards.normalizeListingSlug(value) !== null) { + fail('poe2db page guard', `unsafe listing value was accepted: ${value}`); + } + } + if ( + imageGuards.validateLocalImagePath('/images/base/example.webp', 'bases') + !== '/images/base/example.webp' + ) { + fail('poe2db local image guard', 'valid category-local image path did not round-trip'); + } + for (const value of [ + '/images/base/../../secret', + '/images/base/%2e%2e%2fsecret', + './../../../secret', + '/images/omens/wrong-category.webp', + ]) { + expectThrow( + 'poe2db local image guard', + () => imageGuards.validateLocalImagePath(value, 'bases'), + ); + } + expectThrow( + 'poe2db raw path guard', + () => pageGuards.resolveRawGroupFile('currency', '../../../../tmp/poison'), + ); + expectThrow( + 'poe2db group bound', + () => pageGuards.boundedUniqueSlugs( + Array.from({ length: pageGuards.MAX_GROUP_ITEMS + 1 }, () => 'Exalted_Orb'), + ), + ); + expectThrow( + 'poe2db partial failure', + () => pageGuards.assertNoFetchFailures('currency', [ + { slug: 'Exalted_Orb', error: 'fixture failure' }, + ]), + ); + + const listingFixture = ` +
+ + + `; + const discovered = pageGuards.discoverFromListing(listingFixture); + if (discovered.length !== 1 || discovered[0] !== 'Exalted_Orb') { + fail('poe2db listing guard', `unexpected discovered slugs: ${discovered.join(', ')}`); + } + expectThrow( + 'poe2db listing byte bound', + () => pageGuards.discoverFromListing( + 'x'.repeat(pageGuards.MAX_RESPONSE_BYTES + 1), + ), + ); + + const okHtml = await pageGuards.fetchPage('https://poe2db.tw/us/Exalted_Orb', { + fetchImpl: async () => new Response('ok', { + status: 200, + headers: { 'content-type': 'text/html' }, + }), + timeoutMs: 50, + maxBytes: 1_024, + }); + if (okHtml !== 'ok') { + fail('poe2db response guard', 'valid bounded HTML did not round-trip'); + } + await expectRejection( + 'poe2db redirect host guard', + () => pageGuards.fetchPage('https://poe2db.tw/us/Exalted_Orb', { + fetchImpl: async () => new Response(null, { + status: 302, + headers: { location: 'http://127.0.0.1/private' }, + }), + timeoutMs: 50, + maxBytes: 1_024, + }), + ); + await expectRejection( + 'poe2db redirect bound', + () => pageGuards.fetchPage('https://poe2db.tw/us/Exalted_Orb', { + fetchImpl: async () => new Response(null, { + status: 302, + headers: { location: '/us/Exalted_Orb' }, + }), + timeoutMs: 50, + maxBytes: 1_024, + maxRedirects: 1, + }), + ); + await expectRejection( + 'poe2db response byte bound', + () => pageGuards.fetchPage('https://poe2db.tw/us/Exalted_Orb', { + fetchImpl: async () => new Response('x', { + status: 200, + headers: { 'content-length': '2048' }, + }), + timeoutMs: 50, + maxBytes: 1_024, + }), + ); + await expectRejection( + 'poe2db request deadline', + () => pageGuards.fetchPage('https://poe2db.tw/us/Exalted_Orb', { + fetchImpl: async () => await new Promise(() => {}), + timeoutMs: 5, + maxBytes: 1_024, + }), + ); + + const validImage = 'https://cdn.poe2db.tw/image/Art/2DItems/Currency/Exalted.webp'; + if (imageGuards.validateImageUrl(validImage).href !== validImage) { + fail('poe2db image guard', 'valid allowlisted image URL did not round-trip'); + } + for (const value of [ + 'http://cdn.poe2db.tw/image/x.webp', + 'https://example.com/image/x.webp', + 'https://127.0.0.1/image/x.webp', + 'https://cdn.poe2db.tw/image/%2e%2e%2fsecret', + 'https://user:pass@cdn.poe2db.tw/image/x.webp', + ]) { + expectThrow('poe2db image host guard', () => imageGuards.validateImageUrl(value)); + } + expectThrow( + 'poe2db image output path guard', + () => imageGuards.resolveLocalImageDestination(validImage, '../../../../tmp'), + ); + expectThrow( + 'poe2db data output path guard', + () => imageGuards.resolveCategoryDataPaths('../../../../tmp/poison.json'), + ); + expectThrow( + 'poe2db image item bound', + () => imageGuards.serializeCategoryItems( + Array.from({ length: imageGuards.MAX_ITEMS_PER_CATEGORY + 1 }, () => ({})), + ), + ); + expectThrow( + 'poe2db image partial failure', + () => imageGuards.assertCategoryDownloadSucceeded('bases.json', 1), + ); + + async function* boundedImageFixture() { + yield Buffer.alloc(3); + yield Buffer.alloc(3); + } + await expectRejection( + 'poe2db image response byte bound', + () => imageGuards.collectImageBody(boundedImageFixture(), 5), + ); + const imageOutputFixture = path.join(ROOT, 'public/images/security-fixture.webp'); + await expectRejection( + 'poe2db image redirect host guard', + () => imageGuards.downloadImage( + validImage, + imageOutputFixture, + 'https://poe2db.tw/us/', + { + maxBytes: 16, + maxRedirects: 1, + requestImpl: async () => ({ redirect: 'http://127.0.0.1/private' }), + }, + ), + ); + await expectRejection( + 'poe2db image redirect bound', + () => imageGuards.downloadImage( + validImage, + imageOutputFixture, + 'https://poe2db.tw/us/', + { + maxBytes: 16, + maxRedirects: 1, + requestImpl: async () => ({ redirect: validImage }), + }, + ), + ); + await expectRejection( + 'poe2db image returned-body bound', + () => imageGuards.downloadImage( + validImage, + imageOutputFixture, + 'https://poe2db.tw/us/', + { + maxBytes: 2, + requestImpl: async () => ({ body: Buffer.alloc(3) }), + }, + ), + ); + + const currentManifest = JSON.parse( + await readFile(path.join(ROOT, 'data/processed/manifest.json'), 'utf8'), + ); + const currentCounts = currentManifest.counts; + processGuards.assertProcessedDataQuality({ + season: currentManifest.season, + counts: currentCounts, + previousCounts: currentCounts, + parseFailures: [], + }); + expectThrow( + 'poe2db parser partial-failure guard', + () => processGuards.assertProcessedDataQuality({ + season: currentManifest.season, + counts: currentCounts, + previousCounts: currentCounts, + parseFailures: [{ file: 'base_fixture.html', error: new Error('fixture') }], + }), + ); + expectThrow( + 'poe2db season guard', + () => processGuards.assertProcessedDataQuality({ + season: { id: 'unknown', name: 'Unknown', version: '0.0.0' }, + counts: currentCounts, + previousCounts: currentCounts, + parseFailures: [], + }), + ); + for (const counts of [ + { ...currentCounts, bases: 10 }, + { ...currentCounts, mods: currentCounts.mods * 2 }, + ]) { + expectThrow( + 'poe2db dataset drift guard', + () => processGuards.assertProcessedDataQuality({ + season: currentManifest.season, + counts, + previousCounts: currentCounts, + parseFailures: [], + }), + ); + } +} + +async function checkPolicy() { + let policy; + try { + policy = JSON.parse(await readFile(POLICY_PATH, 'utf8')); + } catch (error) { + fail('seo-skill-policy.json', `cannot be parsed: ${error.message}`); + return; + } + + if (policy.version !== 1) { + fail('seo-skill-policy.json', 'version must be 1'); + } + if (policy.site !== SITE.origin) { + fail('seo-skill-policy.json', `site must be ${SITE.origin}`); + } + if (!Array.isArray(policy.coverage)) { + fail('seo-skill-policy.json', 'coverage must be an array'); + return; + } + + const allowedClassifications = new Set(['required', 'conditional', 'not_applicable']); + const seen = new Set(); + for (const entry of policy.coverage) { + const scope = `seo-skill-policy.json#${entry?.skill ?? 'unknown'}`; + if (!entry || typeof entry.skill !== 'string') { + fail(scope, 'skill must be a string'); + continue; + } + if (seen.has(entry.skill)) { + fail(scope, 'skill is listed more than once'); + } + seen.add(entry.skill); + if (!allowedClassifications.has(entry.classification)) { + fail(scope, 'classification must be required, conditional, or not_applicable'); + } + if (typeof entry.reason !== 'string' || entry.reason.trim().length < 20) { + fail(scope, 'reason must explain the classification'); + } + if (typeof entry.evidence !== 'string' || entry.evidence.trim() === '') { + fail(scope, 'evidence must reference a repository artifact'); + continue; + } + + const [evidenceFile, evidenceAnchor] = entry.evidence.split('#'); + try { + const evidenceSource = await readFile(path.join(ROOT, evidenceFile), 'utf8'); + if (evidenceAnchor && !markdownAnchors(evidenceSource).has(evidenceAnchor)) { + fail(scope, `evidence anchor does not exist: #${evidenceAnchor}`); + } + } catch { + fail(scope, `evidence file does not exist: ${evidenceFile}`); + } + } + + for (const skill of expectedSkills) { + if (!seen.has(skill)) { + fail('seo-skill-policy.json', `missing coverage decision for ${skill}`); + } + } + for (const skill of seen) { + if (!expectedSkills.includes(skill)) { + fail('seo-skill-policy.json', `unexpected skill entry: ${skill}`); + } + } + + if (seen.size !== expectedSkills.length) { + fail( + 'seo-skill-policy.json', + `expected ${expectedSkills.length} unique skill decisions, found ${seen.size}`, + ); + } +} + +function workflowSteps(workflow, jobName) { + const steps = workflow?.jobs?.[jobName]?.steps; + return Array.isArray(steps) ? steps : []; +} + +function exactCommandIndex(steps, command) { + return steps.findIndex((step) => typeof step?.run === 'string' && step.run.trim() === command); +} + +function executableLines(script) { + return script + .split(/\r?\n/) + .map((line) => line.trim()) + .filter((line) => line !== '' && !line.startsWith('#')); +} + +function deployWorkflowErrors(workflow) { + const errors = []; + const triggers = Object.keys(workflow?.on ?? {}).sort(); + if (triggers.length !== 1 || triggers[0] !== 'push') { + errors.push('production deploy must be triggered only by a push'); + } + const branches = workflow?.on?.push?.branches; + if (!Array.isArray(branches) || branches.length !== 1 || branches[0] !== 'main') { + errors.push('production deploy push trigger must be restricted to main'); + } + const steps = workflowSteps(workflow, 'deploy'); + if (workflow?.jobs?.deploy?.if !== "vars.PRODUCTION_RELEASE_GUARD_CONFIGURED == 'true'") { + errors.push('production deploy must remain disabled until owner guard configuration is acknowledged'); + } + if ( + workflow?.jobs?.deploy?.environment?.name !== 'production' + || workflow?.jobs?.deploy?.environment?.url !== 'https://exilecrafter.com' + ) { + errors.push('production deploy must target the named production environment'); + } + const checkIndex = exactCommandIndex(steps, 'npm run check'); + const publishIndex = steps.findIndex((step) => step?.uses === 'cloudflare/pages-action@v1'); + if (steps.some((step) => typeof step?.run === 'string' && /\bnpm run refresh\b/.test(step.run))) { + errors.push('production deploy must not refresh data from the network'); + } + if (checkIndex < 0 || publishIndex < 0 || checkIndex > publishIndex) { + errors.push('an exact npm run check step must precede the Cloudflare publish action'); + } + return errors; +} + +function refreshWorkflowErrors(workflow) { + const errors = []; + const triggers = Object.keys(workflow?.on ?? {}).sort(); + if (triggers.length !== 1 || triggers[0] !== 'schedule') { + errors.push('external refresh must be schedule-only'); + } + if ( + workflow?.jobs?.refresh?.permissions?.contents !== 'write' + || workflow?.jobs?.refresh?.permissions?.['pull-requests'] !== 'write' + ) { + errors.push('refresh permissions must be explicit for branch and PR creation'); + } + const steps = workflowSteps(workflow, 'refresh'); + const refreshIndex = exactCommandIndex(steps, 'npm run refresh'); + const checkIndex = exactCommandIndex(steps, 'npm run check'); + const proposalIndex = steps.findIndex((step) => step?.name === 'Propose updated data for review'); + if ( + refreshIndex < 0 + || checkIndex < 0 + || proposalIndex < 0 + || refreshIndex > checkIndex + || checkIndex > proposalIndex + ) { + errors.push('refresh, exact gate, and review proposal steps are missing or out of order'); + } + const proposal = steps[proposalIndex]; + if (proposal?.env?.GH_TOKEN !== '${{ github.token }}') { + errors.push('review proposal must use the scoped workflow token'); + } + const lines = executableLines(typeof proposal?.run === 'string' ? proposal.run : ''); + for (const requiredLine of [ + 'git add data/processed/ public/data/ public/images/', + 'branch="automation/poe2db-refresh-${GITHUB_RUN_ID}"', + 'git switch -c "$branch"', + 'git commit -m "chore(data): weekly poe2db refresh"', + 'git push origin "$branch"', + 'gh pr create \\', + ]) { + if (!lines.includes(requiredLine)) { + errors.push(`review proposal is missing exact command: ${requiredLine}`); + } + } + return errors; +} + +function qualityWorkflowErrors(workflow) { + const errors = []; + if (!Object.hasOwn(workflow?.on ?? {}, 'pull_request')) { + errors.push('quality workflow must run on pull requests'); + } + if (exactCommandIndex(workflowSteps(workflow, 'check'), 'npm run check') < 0) { + errors.push('quality workflow must contain an exact npm run check step'); + } + return errors; +} + +async function checkWorkflowGuards() { + const [deploySource, refreshSource, qualitySource] = await Promise.all([ + readFile(path.join(ROOT, '.github/workflows/deploy.yml'), 'utf8'), + readFile(path.join(ROOT, '.github/workflows/refresh.yml'), 'utf8'), + readFile(path.join(ROOT, '.github/workflows/quality.yml'), 'utf8'), + ]); + let deploy; + let refresh; + let quality; + try { + deploy = yaml.load(deploySource); + refresh = yaml.load(refreshSource); + quality = yaml.load(qualitySource); + } catch (error) { + fail('workflow YAML', `cannot be parsed: ${error.message}`); + return; + } + for (const error of deployWorkflowErrors(deploy)) { + fail('deploy workflow', error); + } + for (const error of refreshWorkflowErrors(refresh)) { + fail('refresh workflow', error); + } + for (const error of qualityWorkflowErrors(quality)) { + fail('quality workflow', error); + } + + const decoyDeploy = { + on: { push: { branches: ['main'] } }, + jobs: { + deploy: { + steps: [ + { run: 'echo "npm run check"' }, + { uses: 'cloudflare/pages-action@v1' }, + ], + }, + }, + }; + if (deployWorkflowErrors(decoyDeploy).length === 0) { + fail('deploy workflow', 'an echo/comment decoy bypassed structural workflow validation'); + } +} + +async function checkClientDataParity() { + const filenames = [ + 'bases.json', + 'mods.json', + 'currency.json', + 'omens.json', + 'weights.json', + 'season.json', + 'manifest.json', + ]; + for (const filename of filenames) { + const [processed, client] = await Promise.all([ + readFile(path.join(ROOT, 'data/processed', filename)), + readFile(path.join(ROOT, 'public/data', filename)), + ]); + if (!processed.equals(client)) { + fail( + `public/data/${filename}`, + `must be byte-identical to data/processed/${filename}`, + ); + } + } +} + +async function walk(directory) { + const entries = await readdir(directory, { withFileTypes: true }); + const files = []; + for (const entry of entries) { + const target = path.join(directory, entry.name); + if (entry.isDirectory()) { + files.push(...await walk(target)); + } else { + files.push(target); + } + } + return files; +} + +function routeFromFile(file) { + const relative = path.relative(DIST, file).split(path.sep).join('/'); + if (relative === 'index.html') return '/'; + if (relative.endsWith('/index.html')) { + return `/${relative.slice(0, -'index.html'.length)}`; + } + return `/${relative}`; +} + +function metaContent($, attribute, value) { + return $(`meta[${attribute}="${value}"]`).map((_, element) => { + return $(element).attr('content')?.trim() ?? ''; + }).get(); +} + +function expectMetaValues({ $, route, attribute, name, expected }) { + const values = metaContent($, attribute, name); + if (values.length !== 1 || values[0] === '') { + fail(route, `expected one non-empty ${name} meta tag`); + return ''; + } + if (expected !== undefined && values[0] !== expected) { + fail(route, `${name} mismatch: ${values[0]} !== ${expected}`); + } + return values[0]; +} + +function collectSchemaUrls(value, urls = []) { + if (Array.isArray(value)) { + for (const item of value) collectSchemaUrls(item, urls); + return urls; + } + if (!value || typeof value !== 'object') return urls; + + for (const [key, child] of Object.entries(value)) { + if (['url', 'item', '@id'].includes(key) && typeof child === 'string') { + urls.push(child); + } else { + collectSchemaUrls(child, urls); + } + } + return urls; +} + +function jpegDimensions(buffer) { + if (buffer.length < 4 || buffer[0] !== 0xff || buffer[1] !== 0xd8) { + throw new Error('not a JPEG file'); + } + + const startOfFrameMarkers = new Set([ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc5, 0xc6, 0xc7, + 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf, + ]); + let offset = 2; + while (offset + 8 < buffer.length) { + if (buffer[offset] !== 0xff) { + offset += 1; + continue; + } + const marker = buffer[offset + 1]; + if (marker === 0xd9 || marker === 0xda) break; + const length = buffer.readUInt16BE(offset + 2); + if (startOfFrameMarkers.has(marker)) { + return { + height: buffer.readUInt16BE(offset + 5), + width: buffer.readUInt16BE(offset + 7), + }; + } + if (length < 2) throw new Error('invalid JPEG marker length'); + offset += length + 2; + } + throw new Error('JPEG dimensions were not found'); +} + +function inspectInternalLinks($, route) { + const targets = new Set(); + for (const element of $('a[href]').toArray()) { + const href = $(element).attr('href')?.trim() ?? ''; + if ( + href === '' + || href.startsWith('#') + || /^(?:mailto|tel|javascript|data):/i.test(href) + ) { + continue; + } + + let target; + try { + target = new URL(href, new URL(route, SITE)); + } catch { + fail(route, `invalid link URL: ${href}`); + continue; + } + if (target.origin !== SITE.origin) continue; + + const lastSegment = target.pathname.split('/').filter(Boolean).at(-1) ?? ''; + const isFile = /\.[a-z0-9]{1,8}$/i.test(lastSegment); + const isApi = target.pathname === '/api' || target.pathname.startsWith('/api/'); + if (!isFile && !isApi) { + targets.add(`${target.origin}${target.pathname}`); + } + if ( + target.pathname !== '/' + && !target.pathname.endsWith('/') + && !isFile + && !isApi + ) { + fail(route, `internal page link is not trailing-slash normalized: ${href}`); + } + } + return targets; +} + +async function inspectRenderedOutput() { + try { + await access(DIST); + } catch { + fail('dist', 'missing rendered output; run npm run build first'); + return null; + } + + const htmlFiles = (await walk(DIST)) + .filter((file) => file.endsWith('.html')) + .sort(); + if (htmlFiles.length === 0) { + fail('dist', 'contains no HTML files'); + return null; + } + + const pages = []; + let schemaPages = 0; + let schemaBlocks = 0; + let websiteSchemas = 0; + let breadcrumbSchemas = 0; + let longTitles = 0; + let images = 0; + let imagesWithoutDimensions = 0; + + for (const file of htmlFiles) { + const route = routeFromFile(file); + const $ = load(await readFile(file, 'utf8')); + const titles = $('title').map((_, element) => normalizedText($(element).text())).get(); + const descriptions = metaContent($, 'name', 'description'); + const robots = metaContent($, 'name', 'robots'); + const canonicals = $('link[rel="canonical"]').map((_, element) => { + return $(element).attr('href')?.trim() ?? ''; + }).get(); + + if (titles.length !== 1 || titles[0] === '') { + fail(route, `expected one non-empty title, found ${titles.length}`); + } + if (titles[0]?.length > 60) longTitles += 1; + if (descriptions.length !== 1 || descriptions[0] === '') { + fail(route, `expected one non-empty meta description, found ${descriptions.length}`); + } else if (descriptions[0].length > 160) { + fail(route, `meta description is ${descriptions[0].length} characters`); + } + if (robots.length !== 1 || robots[0] === '') { + fail(route, `expected one non-empty robots meta tag, found ${robots.length}`); + } else if (!hasExpectedPageRobots(route, robots[0])) { + fail(route, `robots meta must be exactly ${expectedPageRobots(route)}`); + } + if ($('h1').length !== 1) { + fail(route, `expected one h1, found ${$('h1').length}`); + } + if ($('main').length !== 1) { + fail(route, `expected one main landmark, found ${$('main').length}`); + } + + const isNoindex = robots.some((value) => /(?:^|,)\s*noindex(?:,|$)/i.test(value)); + const expectedCanonical = new URL(route, SITE).toString(); + if (!isNoindex && canonicals.length !== 1) { + fail(route, `indexable page must have one canonical, found ${canonicals.length}`); + } + if (canonicals.length > 1) { + fail(route, `expected at most one canonical, found ${canonicals.length}`); + } + if (canonicals[0] && canonicals[0] !== expectedCanonical) { + fail(route, `canonical mismatch: ${canonicals[0]} !== ${expectedCanonical}`); + } + if (canonicals[0] && !canonicals[0].startsWith('https://')) { + fail(route, `canonical must use HTTPS: ${canonicals[0]}`); + } + + const expectedSocialImage = `${SITE.origin}/og-exile-crafter.jpg`; + const ogTitle = expectMetaValues({ + $, route, attribute: 'property', name: 'og:title', expected: titles[0], + }); + const ogDescription = expectMetaValues({ + $, route, attribute: 'property', name: 'og:description', expected: descriptions[0], + }); + expectMetaValues({ + $, route, attribute: 'property', name: 'og:site_name', expected: 'Exile Crafter', + }); + expectMetaValues({ + $, route, attribute: 'property', name: 'og:type', expected: 'website', + }); + expectMetaValues({ + $, route, attribute: 'property', name: 'og:image', expected: expectedSocialImage, + }); + expectMetaValues({ + $, route, attribute: 'property', name: 'og:image:secure_url', expected: expectedSocialImage, + }); + expectMetaValues({ + $, route, attribute: 'property', name: 'og:image:type', expected: 'image/jpeg', + }); + expectMetaValues({ + $, route, attribute: 'property', name: 'og:image:width', expected: '1200', + }); + expectMetaValues({ + $, route, attribute: 'property', name: 'og:image:height', expected: '630', + }); + const ogImageAlt = expectMetaValues({ + $, route, attribute: 'property', name: 'og:image:alt', + }); + expectMetaValues({ + $, route, attribute: 'name', name: 'twitter:card', expected: 'summary_large_image', + }); + expectMetaValues({ + $, route, attribute: 'name', name: 'twitter:title', expected: ogTitle, + }); + expectMetaValues({ + $, route, attribute: 'name', name: 'twitter:description', expected: ogDescription, + }); + expectMetaValues({ + $, route, attribute: 'name', name: 'twitter:image', expected: expectedSocialImage, + }); + expectMetaValues({ + $, route, attribute: 'name', name: 'twitter:image:alt', expected: ogImageAlt, + }); + const ogUrls = metaContent($, 'property', 'og:url'); + if (canonicals.length === 1 && (ogUrls.length !== 1 || ogUrls[0] !== canonicals[0])) { + fail(route, 'og:url must exist once and match the canonical'); + } + if (canonicals.length === 0 && ogUrls.length !== 0) { + fail(route, 'og:url must be omitted when the page has no canonical'); + } + const scripts = $('script[type="application/ld+json"]').toArray(); + let pageWebsiteSchemas = 0; + let pageBreadcrumbSchemas = 0; + if (scripts.length > 0) schemaPages += 1; + schemaBlocks += scripts.length; + for (const script of scripts) { + let schema; + try { + schema = JSON.parse($(script).html() ?? ''); + } catch (error) { + fail(route, `invalid JSON-LD: ${error.message}`); + continue; + } + if (schema['@context'] !== 'https://schema.org') { + fail(route, 'JSON-LD @context must be https://schema.org'); + } + if (typeof schema['@type'] !== 'string' || schema['@type'] === '') { + fail(route, 'JSON-LD must have a non-empty @type'); + } + for (const value of collectSchemaUrls(schema)) { + let url; + try { + url = new URL(value); + } catch { + fail(route, `schema URL is not absolute: ${value}`); + continue; + } + if (url.protocol !== 'https:') { + fail(route, `schema URL must use HTTPS: ${value}`); + } + } + + if (schema['@type'] === 'WebSite') { + websiteSchemas += 1; + pageWebsiteSchemas += 1; + if ( + route !== '/' + || schema.url !== `${SITE.origin}/` + || schema.name !== 'Exile Crafter' + || schema['@id'] !== `${SITE.origin}/#website` + || schema.inLanguage !== 'en' + ) { + fail(route, 'WebSite schema does not match the canonical site entity'); + } + } else if (schema['@type'] === 'BreadcrumbList') { + breadcrumbSchemas += 1; + pageBreadcrumbSchemas += 1; + const list = schema.itemListElement; + const collectionUrl = route.startsWith('/bases/') + ? `${SITE.origin}/bases/` + : route.startsWith('/mods/') + ? `${SITE.origin}/mods/` + : null; + if (!collectionUrl || !Array.isArray(list) || list.length !== 2) { + fail(route, 'BreadcrumbList must have exactly two items on a detail route'); + } else { + const [collection, current] = list; + if ( + collection?.['@type'] !== 'ListItem' + || collection?.position !== 1 + || typeof collection?.name !== 'string' + || collection.name.trim() === '' + || collection?.item !== collectionUrl + ) { + fail(route, 'BreadcrumbList collection item is invalid'); + } + if ( + current?.['@type'] !== 'ListItem' + || current?.position !== 2 + || typeof current?.name !== 'string' + || current.name.trim() === '' + || current?.item !== expectedCanonical + || schema['@id'] !== `${expectedCanonical}#breadcrumb` + ) { + fail(route, 'BreadcrumbList current-page item is invalid'); + } + } + } else { + fail(route, `unsupported JSON-LD type: ${schema['@type']}`); + } + } + + const isDetailRoute = /^\/(?:bases|mods)\/[^/]+\/$/.test(route); + const expectedPageBreadcrumbs = isDetailRoute ? 1 : 0; + if (pageBreadcrumbSchemas !== expectedPageBreadcrumbs) { + fail( + route, + `expected ${expectedPageBreadcrumbs} BreadcrumbList schema, found ${pageBreadcrumbSchemas}`, + ); + } + const expectedPageWebsites = route === '/' ? 1 : 0; + if (pageWebsiteSchemas !== expectedPageWebsites) { + fail(route, `expected ${expectedPageWebsites} WebSite schema, found ${pageWebsiteSchemas}`); + } + + const internalLinks = inspectInternalLinks($, route); + const pageImages = $('img').toArray(); + images += pageImages.length; + imagesWithoutDimensions += pageImages.filter((element) => { + return !$(element).attr('width') || !$(element).attr('height'); + }).length; + + pages.push({ + route, + title: titles[0] ?? '', + description: descriptions[0] ?? '', + canonical: canonicals[0] ?? null, + isNoindex, + internalLinks, + }); + } + + let basesData = []; + let modsData = []; + let manifest = {}; + try { + [basesData, modsData, manifest] = await Promise.all([ + readFile(path.join(ROOT, 'data/processed/bases.json'), 'utf8').then(JSON.parse), + readFile(path.join(ROOT, 'data/processed/mods.json'), 'utf8').then(JSON.parse), + readFile(path.join(ROOT, 'data/processed/manifest.json'), 'utf8').then(JSON.parse), + ]); + } catch (error) { + fail('route coverage', `processed data cannot be parsed: ${error.message}`); + } + if (manifest.counts?.bases !== basesData.length) { + fail( + 'route coverage', + `manifest base count ${manifest.counts?.bases} !== data length ${basesData.length}`, + ); + } + if (manifest.counts?.mods !== modsData.length) { + fail( + 'route coverage', + `manifest mod count ${manifest.counts?.mods} !== data length ${modsData.length}`, + ); + } + const countDescriptions = [ + ['/bases/', basesData.length], + ['/mods/', modsData.length], + ['/currency/', manifest.counts?.currency], + ['/omens/', manifest.counts?.omens], + ]; + for (const [route, count] of countDescriptions) { + const page = pages.find((candidate) => candidate.route === route); + const formattedCount = Number(count).toLocaleString('en-US'); + if (!Number.isInteger(count) || !page?.description.includes(formattedCount)) { + fail( + route, + `meta description must include the current processed-data count ${formattedCount}`, + ); + } + } + if (websiteSchemas !== 1) { + fail('structured data', `expected one WebSite schema, found ${websiteSchemas}`); + } + if (breadcrumbSchemas !== basesData.length + modsData.length) { + fail( + 'structured data', + `expected ${basesData.length + modsData.length} BreadcrumbList schemas, found ${breadcrumbSchemas}`, + ); + } + + const expectedRoutes = new Set([ + '/', + '/404.html', + '/bases/', + '/calculator/', + '/currency/', + '/guides/', + '/mods/', + '/omens/', + '/optimizer/', + '/simulator/', + ...basesData.map((base) => `/bases/${base.id}/`), + ...modsData.map((mod) => `/mods/${mod.id}/`), + ]); + const renderedRoutes = new Set(pages.map((page) => page.route)); + if (expectedRoutes.size !== basesData.length + modsData.length + 10) { + fail('route coverage', 'processed IDs are duplicated or collide with fixed routes'); + } + for (const route of expectedRoutes) { + if (!renderedRoutes.has(route)) { + fail('route coverage', `missing generated route: ${route}`); + } + } + for (const route of renderedRoutes) { + if (!expectedRoutes.has(route)) { + fail('route coverage', `unexpected generated route: ${route}`); + } + } + + const indexable = pages.filter((page) => !page.isNoindex); + const titleGroups = new Map(); + const canonicalGroups = new Map(); + for (const page of indexable) { + const titleKey = page.title.toLocaleLowerCase('en'); + titleGroups.set(titleKey, [...(titleGroups.get(titleKey) ?? []), page.route]); + if (page.canonical) { + canonicalGroups.set( + page.canonical, + [...(canonicalGroups.get(page.canonical) ?? []), page.route], + ); + } + } + for (const [title, routes] of titleGroups) { + if (routes.length > 1) { + fail('titles', `duplicate "${title}" on ${routes.slice(0, 4).join(', ')}`); + } + } + for (const [canonical, routes] of canonicalGroups) { + if (routes.length > 1) { + fail('canonicals', `duplicate ${canonical} on ${routes.join(', ')}`); + } + } + + const inlinks = new Map(indexable.map((page) => [page.canonical, 0])); + for (const page of pages) { + for (const target of page.internalLinks) { + const canonicalTarget = target === SITE.origin ? `${SITE.origin}/` : target; + if (canonicalTarget !== page.canonical && inlinks.has(canonicalTarget)) { + inlinks.set(canonicalTarget, inlinks.get(canonicalTarget) + 1); + } + } + } + const zeroInlinkPages = [...inlinks.entries()] + .filter(([canonical, count]) => canonical !== `${SITE.origin}/` && count === 0) + .map(([canonical]) => canonical); + const renderedPageUrls = new Set( + pages.map((page) => `${SITE.origin}${page.route === '/' ? '/' : page.route}`), + ); + for (const page of pages) { + for (const target of page.internalLinks) { + const pageTarget = target === SITE.origin ? `${SITE.origin}/` : target; + if (!renderedPageUrls.has(pageTarget)) { + fail(page.route, `internal page link target does not exist: ${pageTarget}`); + } + } + } + + let sitemapXml = ''; + let sitemapIndexXml = ''; + try { + [sitemapXml, sitemapIndexXml] = await Promise.all([ + readFile(path.join(DIST, 'sitemap-0.xml'), 'utf8'), + readFile(path.join(DIST, 'sitemap-index.xml'), 'utf8'), + ]); + } catch (error) { + fail('sitemap', `missing sitemap output: ${error.message}`); + } + + if (!sitemapIndexXml.includes(`${SITE.origin}/sitemap-0.xml`)) { + fail('sitemap-index.xml', 'does not reference the generated sitemap'); + } + const sitemapUrls = [...sitemapXml.matchAll(/([^<]+)<\/loc>/g)] + .map((match) => match[1]); + const sitemapSet = new Set(sitemapUrls); + if (sitemapSet.size !== sitemapUrls.length) { + fail('sitemap-0.xml', 'contains duplicate URLs'); + } + for (const url of sitemapUrls) { + if (!url.startsWith(`${SITE.origin}/`)) { + fail('sitemap-0.xml', `contains non-canonical origin: ${url}`); + } + if (url !== `${SITE.origin}/` && !new URL(url).pathname.endsWith('/')) { + fail('sitemap-0.xml', `contains non-normalized page URL: ${url}`); + } + } + + const expectedSitemap = new Set(indexable.map((page) => page.canonical)); + for (const url of expectedSitemap) { + if (!sitemapSet.has(url)) { + fail('sitemap-0.xml', `missing indexable canonical: ${url}`); + } + } + for (const url of sitemapSet) { + if (!expectedSitemap.has(url)) { + fail('sitemap-0.xml', `contains a noindex or unknown URL: ${url}`); + } + } + + let robotsText = ''; + try { + robotsText = await readFile(path.join(DIST, 'robots.txt'), 'utf8'); + } catch (error) { + fail('robots.txt', `missing: ${error.message}`); + } + if (!/^User-agent:\s*\*/mi.test(robotsText)) { + fail('robots.txt', 'missing wildcard user-agent policy'); + } + if (!new RegExp(`^Sitemap:\\s*${SITE.origin.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}/sitemap-index\\.xml$`, 'mi').test(robotsText)) { + fail('robots.txt', 'missing absolute sitemap declaration'); + } + if (!isExpectedOriginRobots(robotsText)) { + fail( + 'robots.txt', + 'origin policy must exactly allow wildcard crawling and declare the canonical sitemap', + ); + } + + try { + const socialImage = await readFile(path.join(DIST, 'og-exile-crafter.jpg')); + const dimensions = jpegDimensions(socialImage); + if (dimensions.width !== 1200 || dimensions.height !== 630) { + fail( + 'og-exile-crafter.jpg', + `expected 1200x630, found ${dimensions.width}x${dimensions.height}`, + ); + } + if (socialImage.length > 1_000_000) { + fail('og-exile-crafter.jpg', `file is too large: ${socialImage.length} bytes`); + } + } catch (error) { + fail('og-exile-crafter.jpg', `cannot validate social image: ${error.message}`); + } + + console.log('Rendered SEO verification summary'); + console.log(`- HTML pages: ${pages.length}`); + console.log(`- Indexable pages: ${indexable.length}`); + console.log(`- Noindex pages: ${pages.length - indexable.length}`); + console.log(`- Sitemap URLs: ${sitemapUrls.length}`); + console.log(`- JSON-LD: ${schemaBlocks} block(s) on ${schemaPages} page(s)`); + console.log(`- Duplicate indexable titles: ${[...titleGroups.values()].filter((routes) => routes.length > 1).length}`); + console.log(`- Zero-inlink indexable pages (advisory): ${zeroInlinkPages.length}`); + console.log(`- Titles over 60 characters (advisory): ${longTitles}`); + console.log(`- Images without explicit dimensions (advisory): ${imagesWithoutDimensions}/${images}`); + + return { pages, indexable, sitemapUrls }; +} + +await checkUntrustedDataGuards(); +await checkExternalRefreshGuards(); +await checkPolicy(); +await checkWorkflowGuards(); +await checkClientDataParity(); +if (POLICY_ONLY) { + if (failures.length === 0) { + console.log(`SEO skill policy verified: ${expectedSkills.length} coverage decisions.`); + } + outputFailures(); +} else { + await inspectRenderedOutput(); + if (failures.length === 0) { + console.log('SEO verification passed.'); + } + outputFailures(); +} diff --git a/seo-skill-policy.json b/seo-skill-policy.json new file mode 100644 index 0000000..f488645 --- /dev/null +++ b/seo-skill-policy.json @@ -0,0 +1,177 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "version": 1, + "site": "https://exilecrafter.com", + "auditDate": "2026-07-23", + "baseCommit": "30ce69dee0ed941441dd2251f81433fccfeae273", + "coverage": [ + { + "skill": "seo-audit", + "classification": "required", + "reason": "Coordinates the repository, rendered-output, live-site, and specialist evidence.", + "evidence": "docs/seo-audit-2026-07-23.md#skill-coverage" + }, + { + "skill": "seo-page", + "classification": "required", + "reason": "Representative home, catalogue, detail, guide, and tool pages were reviewed.", + "evidence": "docs/seo-audit-2026-07-23.md#on-page-and-content" + }, + { + "skill": "seo-technical", + "classification": "required", + "reason": "Crawlability, indexability, canonicals, redirects, rendering, and internal links were tested.", + "evidence": "docs/seo-audit-2026-07-23.md#technical-seo" + }, + { + "skill": "seo-content", + "classification": "required", + "reason": "Quality, trust, thin-page risk, readability, and citation readiness were reviewed.", + "evidence": "docs/seo-audit-2026-07-23.md#on-page-and-content" + }, + { + "skill": "seo-schema", + "classification": "required", + "reason": "Existing and proposed structured data were checked against page-visible facts.", + "evidence": "docs/seo-audit-2026-07-23.md#structured-data" + }, + { + "skill": "seo-images", + "classification": "required", + "reason": "Formats, dimensions, loading behavior, and layout-shift exposure were reviewed.", + "evidence": "docs/seo-audit-2026-07-23.md#images-and-performance" + }, + { + "skill": "seo-sitemap", + "classification": "required", + "reason": "Sitemap syntax, uniqueness, protocol, canonical alignment, and noindex exclusions were tested.", + "evidence": "docs/seo-audit-2026-07-23.md#technical-seo" + }, + { + "skill": "seo-geo", + "classification": "required", + "reason": "AI crawler access, answerability, entity consistency, and passage-level citability were reviewed.", + "evidence": "docs/seo-audit-2026-07-23.md#geo-and-ai-search" + }, + { + "skill": "seo-performance", + "classification": "required", + "reason": "Repeatable Lighthouse lab runs were collected for representative templates.", + "evidence": "docs/seo-audit-2026-07-23.md#images-and-performance" + }, + { + "skill": "seo-visual", + "classification": "required", + "reason": "Desktop and mobile above-the-fold layouts were inspected.", + "evidence": "docs/seo-audit-2026-07-23.md#images-and-performance" + }, + { + "skill": "seo-plan", + "classification": "required", + "reason": "Findings are sequenced into immediate, validation, and measurement phases.", + "evidence": "docs/seo-audit-2026-07-23.md#prioritized-follow-up" + }, + { + "skill": "seo-programmatic", + "classification": "required", + "reason": "Thousands of generated base and modifier pages require explicit quality and indexation controls.", + "evidence": "docs/seo-audit-2026-07-23.md#programmatic-page-risk" + }, + { + "skill": "seo-competitor-pages", + "classification": "not_applicable", + "reason": "No comparison or alternatives page is present or proposed in this changeset.", + "evidence": "docs/seo-audit-2026-07-23.md#skill-coverage" + }, + { + "skill": "seo-hreflang", + "classification": "conditional", + "reason": "The current static site exposes only English URLs; run before publishing locale-specific routes.", + "evidence": "docs/seo-audit-2026-07-23.md#internationalization" + }, + { + "skill": "seo-local", + "classification": "not_applicable", + "reason": "Exile Crafter is not a local business and has no location-intent acquisition model.", + "evidence": "docs/seo-audit-2026-07-23.md#skill-coverage" + }, + { + "skill": "seo-maps", + "classification": "not_applicable", + "reason": "The site has no physical locations or map-pack ranking objective.", + "evidence": "docs/seo-audit-2026-07-23.md#skill-coverage" + }, + { + "skill": "seo-google", + "classification": "conditional", + "reason": "Target-scoped Search Console, GA4, URL Inspection, and CrUX access was not available.", + "evidence": "docs/seo-audit-2026-07-23.md#evidence-limitations" + }, + { + "skill": "seo-backlinks", + "classification": "conditional", + "reason": "No target-authorized first-party backlink source was available; free-source discovery was inconclusive.", + "evidence": "docs/seo-audit-2026-07-23.md#evidence-limitations" + }, + { + "skill": "seo-cluster", + "classification": "conditional", + "reason": "Run SERP-overlap clustering after a target keyword set and regional market are approved.", + "evidence": "docs/seo-audit-2026-07-23.md#prioritized-follow-up" + }, + { + "skill": "seo-sxo", + "classification": "required", + "reason": "Search-intent fit, navigation, catalogue controls, and conversion paths were reviewed.", + "evidence": "docs/seo-audit-2026-07-23.md#search-experience" + }, + { + "skill": "seo-drift", + "classification": "conditional", + "reason": "No prior immutable SEO baseline existed; this changeset adds deterministic checks for future drift.", + "evidence": "docs/seo-audit-2026-07-23.md#verification-and-drift-control" + }, + { + "skill": "seo-ecommerce", + "classification": "not_applicable", + "reason": "The game-item catalogue has no checkout, merchant feed, purchasable product, or marketplace scope.", + "evidence": "docs/seo-audit-2026-07-23.md#skill-coverage" + }, + { + "skill": "seo-firecrawl", + "classification": "conditional", + "reason": "The Firecrawl connector was unavailable; complete local rendered-output crawling and sampled live requests were used.", + "evidence": "docs/seo-audit-2026-07-23.md#evidence-limitations" + }, + { + "skill": "seo-dataforseo", + "classification": "conditional", + "reason": "The DataForSEO connector was unavailable; no paid metrics were inferred.", + "evidence": "docs/seo-audit-2026-07-23.md#evidence-limitations" + }, + { + "skill": "seo-image-gen", + "classification": "required", + "reason": "A verified 1200 by 630 social preview image closes the required Open Graph image gap.", + "evidence": "docs/seo-audit-2026-07-23.md#e-imagegen-001" + }, + { + "skill": "seo-flow", + "classification": "required", + "reason": "The audit uses the Find, Leverage, Optimize, Win sequence for evidence and prioritization.", + "evidence": "docs/seo-audit-2026-07-23.md#flow-decision" + }, + { + "skill": "seo-intel", + "classification": "required", + "reason": "A free-first SERP sample and repository-native market signals informed advisory opportunities.", + "evidence": "docs/seo-audit-2026-07-23.md#search-intelligence" + }, + { + "skill": "seo-release-guard", + "classification": "conditional", + "reason": "Run the production-versus-preview guard when the PR has a preview URL and a Search Ops site UUID.", + "evidence": "docs/seo-audit-2026-07-23.md#release-decision" + } + ] +} diff --git a/src/components/AffixSlots.astro b/src/components/AffixSlots.astro index 8110b42..a0ca01c 100644 --- a/src/components/AffixSlots.astro +++ b/src/components/AffixSlots.astro @@ -19,7 +19,16 @@ const suffixSlots = Array.from({ length: base.affixSlots.suffix }, (_, i) => {
- {base.imageUrl && {base.name}} + {base.imageUrl && ( + {base.name} + )}
{title}
diff --git a/src/components/BaseCard.astro b/src/components/BaseCard.astro index fc2911e..36163d3 100644 --- a/src/components/BaseCard.astro +++ b/src/components/BaseCard.astro @@ -15,7 +15,14 @@ const Tag = href ? 'a' : 'div'; >
{base.imageUrl ? ( - {base.name} + {base.name} ) : ( ? )} diff --git a/src/components/Footer.astro b/src/components/Footer.astro index c52a58a..11741c5 100644 --- a/src/components/Footer.astro +++ b/src/components/Footer.astro @@ -14,12 +14,15 @@ const dateFmt: Intl.DateTimeFormatOptions = { day: 'numeric', hour: '2-digit', minute: '2-digit', + timeZone: 'UTC', }; const updated = new Date(manifest.generatedAt).toLocaleDateString( locale === 'pt' ? 'pt-BR' : 'en-US', dateFmt, ); const { season, counts } = manifest; +const numberLocale = locale === 'pt' ? 'pt-BR' : 'en-US'; +const copyrightYear = new Date(manifest.generatedAt).getUTCFullYear().toString(); ---