initial commit
90
.claude/skills/parse-dungeon/HTML-TEMPLATE.md
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
# Data Template Reference
|
||||||
|
|
||||||
|
## Dungeon Data File Structure
|
||||||
|
|
||||||
|
Each dungeon is a TypeScript file in `src/data/` that exports a `DungeonData` object.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import type { DungeonData } from "@/types/dungeon";
|
||||||
|
|
||||||
|
export const dungeonSlug: DungeonData = {
|
||||||
|
id: "dungeon-slug",
|
||||||
|
name: "Dungeon Name",
|
||||||
|
descriptionHtml: `Brief layout with <span class="wing-badge wing-arcane">Wing</span> badges if applicable`,
|
||||||
|
headerImage: "/assets/dungeon_name_header.jpg",
|
||||||
|
icon: "/assets/dungeon_dungeon_name.jpg",
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
type: "trash",
|
||||||
|
data: {
|
||||||
|
header: "Area Name — Trash Before BossName",
|
||||||
|
content: [
|
||||||
|
{ type: "quickRef", data: { html: `<strong>Environment:</strong> Brief description.` } },
|
||||||
|
{
|
||||||
|
type: "mob",
|
||||||
|
data: {
|
||||||
|
name: "Mob Name (Immune to CC)",
|
||||||
|
nameHtml: `Mob Name <span style="color: var(--accent-red); font-size: 12px;">(Immune to CC)</span>`,
|
||||||
|
tankRelevant: true,
|
||||||
|
abilitiesHtml: [
|
||||||
|
`<a href="https://www.wowhead.com/beta/spell=123456/ability-name">Ability Name</a> — TANK: What to do.`,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "boss",
|
||||||
|
data: {
|
||||||
|
bossNumber: "Boss 1 · Area/Wing",
|
||||||
|
name: "Boss Name",
|
||||||
|
subtitle: "One-line fight summary",
|
||||||
|
image: "/assets/boss_name_boss_fight.jpg",
|
||||||
|
abilities: [
|
||||||
|
{
|
||||||
|
name: "Ability Name",
|
||||||
|
wowheadUrl: "https://www.wowhead.com/beta/spell=123456/ability-name",
|
||||||
|
role: "tank",
|
||||||
|
importance: "tank-important",
|
||||||
|
descriptionHtml: `<ul><li><span class="warn">Warning.</span></li></ul>`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Ability Name",
|
||||||
|
wowheadUrl: "https://www.wowhead.com/beta/spell=123457/ability-name",
|
||||||
|
role: "everyone",
|
||||||
|
importance: "everyone-important",
|
||||||
|
descriptionHtml: `<ul><li>Description.</li></ul>`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ type: "divider" },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Registering in index.ts
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { dungeonSlug } from "./dungeon-slug";
|
||||||
|
|
||||||
|
// In dungeonList (alphabetical):
|
||||||
|
{ id: "dungeon-slug", name: "Dungeon Name", icon: "/assets/dungeon_dungeon_name.jpg" },
|
||||||
|
|
||||||
|
// In dungeonDataMap:
|
||||||
|
"dungeon-slug": dungeonSlug,
|
||||||
|
```
|
||||||
|
|
||||||
|
## Roles & Importance
|
||||||
|
|
||||||
|
| Role | Importance | Visual |
|
||||||
|
|------|-----------|--------|
|
||||||
|
| `"tank"` | `"tank-important"` | Blue left border + badge |
|
||||||
|
| `"everyone"` | `"everyone-important"` | Amber left border + badge |
|
||||||
|
| `"healer"` | `"healer-important"` | Green left border + badge |
|
||||||
|
| `"dps"` | `null` | Red badge, no border |
|
||||||
|
|
||||||
|
## HTML Classes: `warn` (red), `tip` (green), `wing-badge wing-arcane/void/light`
|
||||||
|
|
||||||
|
## Wowhead: `<a href="https://www.wowhead.com/beta/spell={ID}/{slug}">Name</a>`
|
||||||
145
.claude/skills/parse-dungeon/SKILL.md
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
---
|
||||||
|
name: parse-dungeon
|
||||||
|
description: Parses a method.gg dungeon HTML file and adds it to the M+ dungeon reference webapp. Use when the user wants to add a new dungeon, parse a dungeon HTML file, or generate guide content from a dungeon file in the dungeons/ directory.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Parse Dungeon Guide
|
||||||
|
|
||||||
|
Extracts boss info, trash mechanics, and assets from a method.gg dungeon HTML file, then adds the dungeon as a new TypeScript data file in the React webapp.
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
This is a **React + Vite + shadcn/ui** app. Dungeon content lives in typed data files, not raw HTML.
|
||||||
|
|
||||||
|
- `src/data/*.ts` — one file per dungeon (e.g., `nexus-point-xenas.ts`)
|
||||||
|
- `src/data/index.ts` — ordered dungeon list + data map exports
|
||||||
|
- `src/types/dungeon.ts` — TypeScript types for all data structures
|
||||||
|
- `src/components/dungeon/` — React components that render dungeon data
|
||||||
|
- `public/assets/` — all images (dungeon headers, boss screenshots, dungeon icons)
|
||||||
|
- `parse_dungeon.py` — Python script to extract raw data from method.gg HTML
|
||||||
|
|
||||||
|
## Step 1: Parse the HTML
|
||||||
|
|
||||||
|
Run the extraction script against the target dungeon file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source ~/.zshrc && poetry run python parse_dungeon.py dungeons/<filename>.html
|
||||||
|
```
|
||||||
|
|
||||||
|
If the script doesn't accept a CLI argument yet, update `parse_dungeon.py` to accept one via `sys.argv[1]`.
|
||||||
|
|
||||||
|
The script extracts:
|
||||||
|
- **Section content** — full text of each `guide-section-title` section
|
||||||
|
- **Boss images** — `img.section-boss` saved to `public/assets/`
|
||||||
|
- **Mob icons** — `div.mob-icon img` saved to `public/assets/`
|
||||||
|
- **Dungeon header image** — `img.boss--render` saved to `public/assets/`
|
||||||
|
- **Spell links** — all wowhead spell references with context
|
||||||
|
|
||||||
|
**Important:** Images must be saved to `public/assets/`, not `assets/`.
|
||||||
|
|
||||||
|
## Step 2: Identify content
|
||||||
|
|
||||||
|
From the parsed output, identify:
|
||||||
|
|
||||||
|
1. **Bosses** — sections ending in "Boss Fight" (e.g., "Vexamus Boss Fight")
|
||||||
|
2. **Trash sections** — sections ending in "Trash" (e.g., "Vexamus Trash")
|
||||||
|
3. **Mob names** — `h4.mob-name` elements within trash sections
|
||||||
|
4. **Role-specific mechanics** — identify abilities by role:
|
||||||
|
- **Tank:** tank, taunt, face away, defensive, positioning, aggro, kite, knockback, damage taken increase, swap, active mitigation
|
||||||
|
- **Healer:** heavy damage, healing absorb, dispel, disease, poison, curse, magic debuff, raid damage, heal check, ticking DoT
|
||||||
|
- **DPS:** interrupt, CC, burn target, add priority, enrage timer, soothe, purge, DPS check
|
||||||
|
- **Everyone:** dodge, soak, spread, stack, move, kill order, frontal, AoE avoidance
|
||||||
|
|
||||||
|
## Step 3: Create the data file
|
||||||
|
|
||||||
|
Create a new TypeScript file at `src/data/<dungeon-slug>.ts` following the types in `src/types/dungeon.ts`.
|
||||||
|
|
||||||
|
Reference an existing dungeon data file (e.g., `src/data/nexus-point-xenas.ts`) for the exact structure.
|
||||||
|
|
||||||
|
The file must:
|
||||||
|
- Import and conform to `DungeonData` from `@/types/dungeon`
|
||||||
|
- Export a named constant (camelCase of slug, e.g., `pitOfSaron`)
|
||||||
|
- Use HTML strings for rich content (Wowhead links, `<span class="warn">`, etc.) via template literals
|
||||||
|
- Image paths use `/assets/` prefix (served from `public/assets/`)
|
||||||
|
|
||||||
|
Key rules:
|
||||||
|
- **Brevity is critical.** 1-2 sentences max per ability. No paragraphs.
|
||||||
|
- **Include all role-relevant mechanics.** Every boss should have cards for each role that has a distinct responsibility.
|
||||||
|
- **Use role tags:** `tank`, `healer`, `dps`, `everyone` to classify each ability card.
|
||||||
|
- **Role-importance mapping:**
|
||||||
|
- `role: "tank"` → `importance: "tank-important"` (sky-blue left border)
|
||||||
|
- `role: "healer"` → `importance: "healer-important"` (green left border)
|
||||||
|
- `role: "everyone"` → `importance: "everyone-important"` or `null` (amber left border or none)
|
||||||
|
- `role: "dps"` → `importance: null` (red badge, no left border)
|
||||||
|
- **Ability card order per boss:** tank first, then healer, then everyone, then dps.
|
||||||
|
- **Ability descriptions use bullet points** — HTML `<ul><li>...</li></ul>` in the `descriptionHtml` field.
|
||||||
|
- **Mark CC-immune mobs** with `nameHtml` containing a red "(Immune to CC)" span.
|
||||||
|
- **Highlight warnings** with `<span class="warn">` and tips with `<span class="tip">`.
|
||||||
|
- **Environment/quick-ref** content uses `{ type: "quickRef", data: { html: "..." } }` in trash section content arrays.
|
||||||
|
|
||||||
|
## Step 4: Register the dungeon
|
||||||
|
|
||||||
|
Update `src/data/index.ts`:
|
||||||
|
|
||||||
|
1. Add the import for the new dungeon data file
|
||||||
|
2. If replacing a disabled entry in `dungeonList`, remove the `disabled: true` flag
|
||||||
|
3. Add the dungeon to `dungeonDataMap`
|
||||||
|
|
||||||
|
## Step 5: Verify
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make dev
|
||||||
|
```
|
||||||
|
|
||||||
|
- The new dungeon tab appears in the sidebar and is clickable
|
||||||
|
- All boss images render correctly from `public/assets/`
|
||||||
|
- Every boss has a section with abilities
|
||||||
|
- Tank-critical abilities are not missed
|
||||||
|
- Wowhead tooltip links work (hover to verify)
|
||||||
|
- Text is concise — cut any filler words
|
||||||
|
|
||||||
|
## Data Structure Reference
|
||||||
|
|
||||||
|
See `src/types/dungeon.ts` for full types. Key structures:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Dungeon data file exports:
|
||||||
|
export const dungeonSlug: DungeonData = {
|
||||||
|
id: "dungeon-slug", // URL hash
|
||||||
|
name: "Dungeon Name",
|
||||||
|
descriptionHtml: "...", // May contain wing badge spans
|
||||||
|
headerImage: "/assets/dungeon_header.jpg",
|
||||||
|
icon: "/assets/dungeon_icon.jpg",
|
||||||
|
sections: [
|
||||||
|
{ type: "trash", data: { header: "...", content: [...] } },
|
||||||
|
{ type: "boss", data: { bossNumber: "Boss 1 · Wing", name: "...", ... } },
|
||||||
|
{ type: "divider" },
|
||||||
|
// repeat...
|
||||||
|
],
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Wowhead Spell Links
|
||||||
|
|
||||||
|
All ability names must be wowhead links in the HTML strings.
|
||||||
|
|
||||||
|
Format: `<a href="https://www.wowhead.com/beta/spell={ID}/{slug}">Ability Name</a>`
|
||||||
|
|
||||||
|
- The spell ID comes from the parser output (SPELLS WITH CONTEXT section).
|
||||||
|
- The slug is the spell name lowercased with hyphens.
|
||||||
|
- The React app handles tooltip initialization automatically via `useWowheadTooltips` hook.
|
||||||
|
|
||||||
|
## Writing Style
|
||||||
|
|
||||||
|
- **Max 1-2 sentences per ability point.** No paragraphs.
|
||||||
|
- **Use bullet points** — `<ul><li>...</li></ul>` in descriptionHtml.
|
||||||
|
- **Lead with the ability name** as a wowhead link, followed by a dash and the description.
|
||||||
|
- **Ability order:** tank, healer, everyone, dps in each boss's abilities array.
|
||||||
|
- **Tank actions** should be explicit: "Face away", "Use defensive", "Pick up adds", "Position at edge".
|
||||||
|
- **Healer actions** should be explicit: "Dispel immediately", "Heavy healing required", "Heal absorb — heal through before next cast".
|
||||||
|
- **DPS actions** should be explicit: "Interrupt on cooldown", "Burn adds before X", "Soothe enrage".
|
||||||
|
- **Use `warn` for dangers** any role MUST react to.
|
||||||
|
- **Use `tip` for helpful tricks.**
|
||||||
|
- **Include all role-relevant mechanics.** Tag each ability with the most specific role responsible for handling it.
|
||||||
|
- Every boss should have at minimum one `tank-important` card if there is ANY tank-specific mechanic.
|
||||||
|
- Include healer and DPS cards where mechanics specifically require those roles to act.
|
||||||
7
.dockerignore
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
.git
|
||||||
|
.claude
|
||||||
|
dungeons
|
||||||
|
*.md
|
||||||
|
Makefile
|
||||||
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
.DS_Store
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
59
CLAUDE.md
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# Midnight S1 Tank Guide
|
||||||
|
|
||||||
|
WoW Midnight Season 1 M+ tanking quick-reference webapp. Built to be read at a glance on a second monitor during gameplay.
|
||||||
|
|
||||||
|
## Stack
|
||||||
|
|
||||||
|
React 19 + Vite + TypeScript + Tailwind v4 + shadcn/ui. No router — hash-based dungeon switching.
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
- `make dev` — start dev server on port 8000
|
||||||
|
- `make build` — production build
|
||||||
|
- `source ~/.zshrc` before any node/npm/npx command (lazy nvm)
|
||||||
|
|
||||||
|
## Design Rules
|
||||||
|
|
||||||
|
- **Dark only.** Deep abyss navy (`#050810`). No light mode, no toggle.
|
||||||
|
- **Frosted glass cards.** Use `.frost` class (backdrop-blur + semi-transparent bg). Never plain bg.
|
||||||
|
- **Square edges.** All radii are 0. No rounded corners anywhere.
|
||||||
|
- **Colours that pop.** Cyan (`#22d3ee`), sky blue (`#38bdf8`), purple (`#a78bfa`), amber (`#fbbf24`), red (`#f87171`), green (`#34d399`).
|
||||||
|
- **Readable at a glance.** Body text `text-base` minimum. Headers bump up. Bullet spacing `mb-2.5`.
|
||||||
|
- **Centre-aligned content.** Main container `max-w-7xl mx-auto`. 2-col grid on `lg:`.
|
||||||
|
- **Font:** Geist Variable.
|
||||||
|
|
||||||
|
## Role Colours
|
||||||
|
|
||||||
|
- Tank: `#38bdf8` (sky blue) — `text-tank`, `border-l-tank`
|
||||||
|
- Healer: `#34d399` (green) — `text-healer`
|
||||||
|
- DPS: `#f87171` (red) — `text-dps`
|
||||||
|
- Everyone: `#fbbf24` (amber) — `text-everyone`
|
||||||
|
|
||||||
|
## Project Layout
|
||||||
|
|
||||||
|
```
|
||||||
|
src/
|
||||||
|
data/*.ts — one file per dungeon, typed DungeonData exports
|
||||||
|
data/index.ts — dungeonList (sidebar order) + dungeonDataMap
|
||||||
|
types/dungeon.ts — all shared types
|
||||||
|
components/
|
||||||
|
dungeon/ — DungeonPage, BossHeader, AbilityCard, MobCard, TrashSection, etc.
|
||||||
|
layout/ — AppSidebar
|
||||||
|
ui/ — shadcn primitives (badge, button, card, etc.)
|
||||||
|
index.css — theme vars, .frost utility, wowhead overrides
|
||||||
|
public/assets/ — all images (dungeon headers, boss screenshots, icons)
|
||||||
|
dungeons/ — raw method.gg HTML source files
|
||||||
|
```
|
||||||
|
|
||||||
|
## Adding a Dungeon
|
||||||
|
|
||||||
|
Use `/parse-dungeon` skill. It runs `parse_dungeon.py` against a `dungeons/*.html` file, creates `src/data/<slug>.ts`, and registers it in `src/data/index.ts`.
|
||||||
|
|
||||||
|
## Content Rules
|
||||||
|
|
||||||
|
- HTML strings in data files (wowhead links, `<span class="warn">`, `<span class="tip">`).
|
||||||
|
- Ability card order per boss: tank first, then healer, then everyone, then dps.
|
||||||
|
- Include healer and DPS-specific mechanics — not just tank-focused content.
|
||||||
|
- DPS cards use `role: "dps"` with `importance: null` (red badge, no left border).
|
||||||
|
- Max 1-2 sentences per ability. No paragraphs.
|
||||||
|
- CC-immune mobs get red "(Immune to CC)" span in `nameHtml`.
|
||||||
11
Caddyfile
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
:8080 {
|
||||||
|
root * /srv
|
||||||
|
file_server
|
||||||
|
try_files {path} /index.html
|
||||||
|
header {
|
||||||
|
X-Content-Type-Options nosniff
|
||||||
|
X-Frame-Options DENY
|
||||||
|
Referrer-Policy strict-origin-when-cross-origin
|
||||||
|
}
|
||||||
|
encode gzip
|
||||||
|
}
|
||||||
14
Dockerfile
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# ── Build stage ──────────────────────────────────────────
|
||||||
|
FROM node:22-alpine AS build
|
||||||
|
WORKDIR /app
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
RUN npm ci --ignore-scripts
|
||||||
|
COPY . .
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# ── Runtime stage ────────────────────────────────────────
|
||||||
|
FROM caddy:2-alpine
|
||||||
|
COPY Caddyfile /etc/caddy/Caddyfile
|
||||||
|
COPY --from=build /app/dist /srv
|
||||||
|
USER nobody
|
||||||
|
EXPOSE 8080
|
||||||
19
Makefile
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
.PHONY: dev stop build install extract
|
||||||
|
|
||||||
|
PORT ?= 8000
|
||||||
|
|
||||||
|
dev:
|
||||||
|
npx vite --port $(PORT) --host &
|
||||||
|
@echo "Dev server running at http://localhost:$(PORT)"
|
||||||
|
|
||||||
|
stop:
|
||||||
|
@-pkill -f "vite --port $(PORT)" 2>/dev/null && echo "Stopped dev server" || echo "No dev server running"
|
||||||
|
|
||||||
|
build:
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
install:
|
||||||
|
npm install
|
||||||
|
|
||||||
|
extract:
|
||||||
|
node scripts/extract-data.mjs
|
||||||
BIN
assets/algethar_academy_header.jpg
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
assets/araknath_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
assets/arcanotron_custos_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
assets/chief_corewright_kasreth_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
assets/commander_kroluk_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
assets/corewarden_nysarra_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
assets/crawth_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
assets/degentrius_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
assets/derelict_duo_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
assets/dungeon_algeth_ar_academy.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
assets/dungeon_magister_s_terrace.jpg
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
assets/dungeon_maisara_caverns.jpg
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
assets/dungeon_nexus_point_xenas.jpg
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
assets/dungeon_pit_of_saron.jpg
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
assets/dungeon_seat_of_the_triumvirate.jpg
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
assets/dungeon_skyreach.jpg
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
assets/dungeon_windrunner_spire.jpg
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
assets/echo_of_doragosa_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
BIN
assets/emberdawn_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
assets/forgemaster_garfrost_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
assets/gemellus_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
BIN
assets/high_sage_viryx_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
assets/ick_and_krick_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
assets/l_ura_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
assets/lothraxion_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
assets/magisters_terrace_header.jpg
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
assets/maisara_caverns_header.jpg
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
assets/muro_jin_and_nekraxx_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
assets/nexus_point_xenas_header.jpg
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
assets/overgrown_ancient_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
assets/pit_of_saron_header.jpg
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
assets/rak_tul_vessel_of_souls_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
assets/ranjit_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
assets/rukhran_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
assets/saprish_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
assets/scourgelord_tyrannus_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
assets/seat_of_the_triumvirate_header.jpg
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
assets/seranel_sunlash_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
assets/skyreach_header.jpg
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
assets/the_restless_heart_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
assets/vexamus_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
assets/viceroy_nezhar_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
assets/vordaza_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
assets/windrunner_spire_header.jpg
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
assets/zuraal_the_ascended_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
25
components.json
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://ui.shadcn.com/schema.json",
|
||||||
|
"style": "base-nova",
|
||||||
|
"rsc": false,
|
||||||
|
"tsx": true,
|
||||||
|
"tailwind": {
|
||||||
|
"config": "",
|
||||||
|
"css": "src/index.css",
|
||||||
|
"baseColor": "neutral",
|
||||||
|
"cssVariables": true,
|
||||||
|
"prefix": ""
|
||||||
|
},
|
||||||
|
"iconLibrary": "lucide",
|
||||||
|
"rtl": false,
|
||||||
|
"aliases": {
|
||||||
|
"components": "@/components",
|
||||||
|
"utils": "@/lib/utils",
|
||||||
|
"ui": "@/components/ui",
|
||||||
|
"lib": "@/lib",
|
||||||
|
"hooks": "@/hooks"
|
||||||
|
},
|
||||||
|
"menuColor": "default",
|
||||||
|
"menuAccent": "subtle",
|
||||||
|
"registries": {}
|
||||||
|
}
|
||||||
6
docker-compose.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
services:
|
||||||
|
app:
|
||||||
|
build: .
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
restart: unless-stopped
|
||||||
3421
dungeons/algethar-academy.html
Normal file
3451
dungeons/magisters-terrace.html
Normal file
3510
dungeons/maisara-caverns.html
Normal file
3412
dungeons/nexus-point-xenas.html
Normal file
3413
dungeons/pit-of-saron.html
Normal file
3401
dungeons/seat-of-the-triumvirate.html
Normal file
3413
dungeons/skyreach.html
Normal file
3520
dungeons/windrunner-spire.html
Normal file
23
eslint.config.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import js from '@eslint/js'
|
||||||
|
import globals from 'globals'
|
||||||
|
import reactHooks from 'eslint-plugin-react-hooks'
|
||||||
|
import reactRefresh from 'eslint-plugin-react-refresh'
|
||||||
|
import tseslint from 'typescript-eslint'
|
||||||
|
import { defineConfig, globalIgnores } from 'eslint/config'
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
globalIgnores(['dist']),
|
||||||
|
{
|
||||||
|
files: ['**/*.{ts,tsx}'],
|
||||||
|
extends: [
|
||||||
|
js.configs.recommended,
|
||||||
|
tseslint.configs.recommended,
|
||||||
|
reactHooks.configs.flat.recommended,
|
||||||
|
reactRefresh.configs.vite,
|
||||||
|
],
|
||||||
|
languageOptions: {
|
||||||
|
ecmaVersion: 2020,
|
||||||
|
globals: globals.browser,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
15
index.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en" class="dark">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Midnight S1 — Tank Guide</title>
|
||||||
|
<script>var wowhead_tooltips = {"colorlinks": false, "iconizelinks": true, "iconSize": "small", "renamelinks": false}</script>
|
||||||
|
<script src="https://wow.zamimg.com/js/tooltips.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
2471
index.original.html
Normal file
58
midnight_season_1_tanking_summaries.md
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
---
|
||||||
|
created: 11-03-2026
|
||||||
|
---
|
||||||
|
|
||||||
|
# midnight_season_1_tanking_summaries.md
|
||||||
|
|
||||||
|
## download dungeon pages
|
||||||
|
|
||||||
|
```
|
||||||
|
monolith https://www.method.gg/guides/dungeons/nexus-point-xenas -o nexus-point.html
|
||||||
|
```
|
||||||
|
|
||||||
|
## prompt
|
||||||
|
|
||||||
|
```
|
||||||
|
I want to create a simple webapp that I can use while playing World of Warcraft
|
||||||
|
|
||||||
|
The goal should be a simple reference guide for each dungeon that i can use while tanking
|
||||||
|
|
||||||
|
There are 3 roles:
|
||||||
|
|
||||||
|
Tank - The role is to keep aggro and position enemies for the group to kill
|
||||||
|
DPS - Kill things
|
||||||
|
Healer - Keep everyone alive
|
||||||
|
|
||||||
|
The webapp should be dark, with dark navy blue themes. Colours/accents should pop and be bright but pleasant to look at.
|
||||||
|
|
||||||
|
The goal is for me (as a tank):
|
||||||
|
|
||||||
|
- I should know for each boss what I need to do
|
||||||
|
- This could be positioning
|
||||||
|
- Or enemy attacks I need to look out for
|
||||||
|
- Or defensives/abilities I need to use
|
||||||
|
|
||||||
|
Basically anything relating to tanking that I need to know in order to successfully complete the dungeon
|
||||||
|
|
||||||
|
There should be at the top of the page a selection for each dungeon. When clicked it should take me to the dungeon page
|
||||||
|
|
||||||
|
It should show me the bosses, and then key abilities/things I need ot pay attention to
|
||||||
|
|
||||||
|
The goal here is brevity. I need to know exactly what in the least amount of words WITHOUT SKIPPING ANYTHING IMPORTANT. We shouldn't write paragraphs when 1-2 sentences would do. It is imperative we do not miss important things as a tank I need to do. This is going ot be the main reference of what to do in the dungeons
|
||||||
|
|
||||||
|
The format should be big so it's easy to see at a glance (with cards) You should use your best judgement to make it easy to read while playing on a second screen and look nice. The app should look modern and sleek.
|
||||||
|
|
||||||
|
For each dungeon it should all be on page, with headers for bosses
|
||||||
|
|
||||||
|
You should use the assets contained within each dungeon file
|
||||||
|
|
||||||
|
Let's start with @dungeons/nexus-point-xenas.html
|
||||||
|
|
||||||
|
All the information you need is in there
|
||||||
|
|
||||||
|
You should
|
||||||
|
|
||||||
|
1. Identify the bosses in the dungeon
|
||||||
|
2. Identify any assets you need
|
||||||
|
3. Extract any and all relevant tanking information for bosses
|
||||||
|
```
|
||||||
8115
package-lock.json
generated
Normal file
42
package.json
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "midnight-s1-tank-guide",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "tsc -b && vite build",
|
||||||
|
"lint": "eslint .",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@base-ui/react": "^1.3.0",
|
||||||
|
"@fontsource-variable/geist": "^5.2.8",
|
||||||
|
"class-variance-authority": "^0.7.1",
|
||||||
|
"clsx": "^2.1.1",
|
||||||
|
"lucide-react": "^0.577.0",
|
||||||
|
"react": "^19.2.4",
|
||||||
|
"react-dom": "^19.2.4",
|
||||||
|
"shadcn": "^4.0.5",
|
||||||
|
"tailwind-merge": "^3.5.0",
|
||||||
|
"tw-animate-css": "^1.4.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@eslint/js": "^9.39.4",
|
||||||
|
"@tailwindcss/vite": "^4.2.1",
|
||||||
|
"@types/jsdom": "^28.0.0",
|
||||||
|
"@types/node": "^24.12.0",
|
||||||
|
"@types/react": "^19.2.14",
|
||||||
|
"@types/react-dom": "^19.2.3",
|
||||||
|
"@vitejs/plugin-react": "^4.5.0",
|
||||||
|
"eslint": "^9.39.4",
|
||||||
|
"eslint-plugin-react-hooks": "^7.0.1",
|
||||||
|
"eslint-plugin-react-refresh": "^0.5.2",
|
||||||
|
"globals": "^17.4.0",
|
||||||
|
"jsdom": "^28.1.0",
|
||||||
|
"tailwindcss": "^4.2.1",
|
||||||
|
"typescript": "~5.9.3",
|
||||||
|
"typescript-eslint": "^8.56.1",
|
||||||
|
"vite": "^6.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
175
parse_dungeon.py
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
"""Parse dungeon HTML files from method.gg to extract boss info, abilities, and assets.
|
||||||
|
|
||||||
|
Usage: poetry run python parse_dungeon.py dungeons/<filename>.html
|
||||||
|
"""
|
||||||
|
|
||||||
|
import base64
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from lxml import etree
|
||||||
|
|
||||||
|
|
||||||
|
def slugify(text: str) -> str:
|
||||||
|
return re.sub(r"[^a-zA-Z0-9]+", "_", text).strip("_").lower()
|
||||||
|
|
||||||
|
|
||||||
|
def save_base64_image(src: str, filename: str) -> str | None:
|
||||||
|
"""Extract base64 image data and save to file. Returns filename if saved."""
|
||||||
|
if not src.startswith("data:image/"):
|
||||||
|
return None
|
||||||
|
match = re.match(r"data:image/(\w+);base64,(.*)", src)
|
||||||
|
if not match:
|
||||||
|
return None
|
||||||
|
ext = match.group(1)
|
||||||
|
if ext == "jpeg":
|
||||||
|
ext = "jpg"
|
||||||
|
data = base64.b64decode(match.group(2))
|
||||||
|
full_path = f"assets/{filename}.{ext}"
|
||||||
|
with open(full_path, "wb") as f:
|
||||||
|
f.write(data)
|
||||||
|
print(f" Saved: {full_path} ({len(data)} bytes)")
|
||||||
|
return full_path
|
||||||
|
|
||||||
|
|
||||||
|
def main(html_file: str) -> None:
|
||||||
|
# Derive dungeon slug from filename
|
||||||
|
dungeon_slug = os.path.splitext(os.path.basename(html_file))[0]
|
||||||
|
dungeon_slug_clean = slugify(dungeon_slug)
|
||||||
|
|
||||||
|
parser = etree.HTMLParser()
|
||||||
|
tree = etree.parse(html_file, parser)
|
||||||
|
root = tree.getroot()
|
||||||
|
|
||||||
|
os.makedirs("assets", exist_ok=True)
|
||||||
|
|
||||||
|
# ── Dungeon title ──
|
||||||
|
titles = root.xpath('//h1[contains(@class, "main-title")]')
|
||||||
|
for t in titles:
|
||||||
|
print("=== DUNGEON TITLE ===")
|
||||||
|
print(etree.tostring(t, method="text", encoding="unicode").strip())
|
||||||
|
|
||||||
|
# ── Guide sections ──
|
||||||
|
sections = root.xpath('//div[contains(@class, "guide-section-title")]/h2')
|
||||||
|
print("\n=== GUIDE SECTIONS ===")
|
||||||
|
for s in sections:
|
||||||
|
print(f" {etree.tostring(s, method='text', encoding='unicode').strip()}")
|
||||||
|
|
||||||
|
# ── Full section content ──
|
||||||
|
print("\n" + "=" * 80)
|
||||||
|
print("=== FULL SECTION CONTENT ===")
|
||||||
|
print("=" * 80)
|
||||||
|
|
||||||
|
guide_sections = root.xpath('//div[contains(@class, "guide-section-title")]')
|
||||||
|
for section_title_div in guide_sections:
|
||||||
|
h2 = section_title_div.find(".//h2")
|
||||||
|
if h2 is None:
|
||||||
|
continue
|
||||||
|
title = etree.tostring(h2, method="text", encoding="unicode").strip()
|
||||||
|
|
||||||
|
parent = section_title_div.getparent()
|
||||||
|
if parent is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
full_text = etree.tostring(parent, method="text", encoding="unicode").strip()
|
||||||
|
full_text = re.sub(r"\n\s*\n", "\n\n", full_text)
|
||||||
|
full_text = re.sub(r" +", " ", full_text)
|
||||||
|
|
||||||
|
print(f"\n{'─' * 60}")
|
||||||
|
print(f"SECTION: {title}")
|
||||||
|
print(f"{'─' * 60}")
|
||||||
|
print(full_text[:3000])
|
||||||
|
if len(full_text) > 3000:
|
||||||
|
print(f"... [truncated, total {len(full_text)} chars]")
|
||||||
|
|
||||||
|
# ── Boss images ──
|
||||||
|
print("\n" + "=" * 80)
|
||||||
|
print("=== EXTRACTING BOSS IMAGES ===")
|
||||||
|
print("=" * 80)
|
||||||
|
|
||||||
|
boss_images = root.xpath('//img[contains(@class, "section-boss")]')
|
||||||
|
for i, img in enumerate(boss_images):
|
||||||
|
src = img.get("src", "")
|
||||||
|
ancestor = img
|
||||||
|
section_name = f"boss_{i}"
|
||||||
|
while ancestor is not None:
|
||||||
|
ancestor = ancestor.getparent()
|
||||||
|
if ancestor is not None:
|
||||||
|
title_el = ancestor.find('.//div[@class="guide-section-title"]//h2')
|
||||||
|
if title_el is not None:
|
||||||
|
section_name = slugify(
|
||||||
|
etree.tostring(title_el, method="text", encoding="unicode").strip()
|
||||||
|
)
|
||||||
|
break
|
||||||
|
save_base64_image(src, section_name)
|
||||||
|
|
||||||
|
# ── Dungeon header image ──
|
||||||
|
header_imgs = root.xpath('//img[contains(@class, "boss--render")]')
|
||||||
|
for img in header_imgs:
|
||||||
|
src = img.get("src", "")
|
||||||
|
save_base64_image(src, f"{dungeon_slug_clean}_header")
|
||||||
|
|
||||||
|
# ── Mob icons ──
|
||||||
|
mob_icons = root.xpath('//div[contains(@class, "mob-icon")]/img')
|
||||||
|
for i, icon_img in enumerate(mob_icons):
|
||||||
|
src = icon_img.get("src", "")
|
||||||
|
mob_header_div = icon_img.getparent().getparent()
|
||||||
|
name_el = (
|
||||||
|
mob_header_div.find('.//h4[@class="mob-name"]')
|
||||||
|
if mob_header_div is not None
|
||||||
|
else None
|
||||||
|
)
|
||||||
|
if name_el is not None:
|
||||||
|
mob_name = etree.tostring(name_el, method="text", encoding="unicode").strip()
|
||||||
|
mob_name_clean = slugify(mob_name)
|
||||||
|
else:
|
||||||
|
mob_name_clean = f"mob_{i}"
|
||||||
|
save_base64_image(src, f"icon_{mob_name_clean}")
|
||||||
|
|
||||||
|
# ── Wowhead spell links ──
|
||||||
|
print("\n" + "=" * 80)
|
||||||
|
print("=== SPELLS WITH CONTEXT ===")
|
||||||
|
print("=" * 80)
|
||||||
|
|
||||||
|
spell_links = root.xpath('//a[contains(@href, "wowhead.com") and contains(@href, "spell")]')
|
||||||
|
for link in spell_links:
|
||||||
|
href = link.get("href", "")
|
||||||
|
spell_name = etree.tostring(link, method="text", encoding="unicode").strip()
|
||||||
|
|
||||||
|
parent = link.getparent()
|
||||||
|
if parent is not None:
|
||||||
|
context = etree.tostring(parent, method="text", encoding="unicode").strip()
|
||||||
|
context = re.sub(r"\s+", " ", context)[:300]
|
||||||
|
else:
|
||||||
|
context = ""
|
||||||
|
|
||||||
|
spell_id_match = re.search(r"spell=(\d+)", href)
|
||||||
|
spell_id = spell_id_match.group(1) if spell_id_match else "unknown"
|
||||||
|
|
||||||
|
print(f"\n Spell: {spell_name} (ID: {spell_id})")
|
||||||
|
print(f" Context: {context}")
|
||||||
|
|
||||||
|
# ── Dungeon selector images ──
|
||||||
|
print("\n" + "=" * 80)
|
||||||
|
print("=== DUNGEON SELECTOR IMAGES ===")
|
||||||
|
print("=" * 80)
|
||||||
|
|
||||||
|
dungeon_links = root.xpath('//a[contains(@class, "boss-guide-link")]')
|
||||||
|
for link in dungeon_links:
|
||||||
|
img = link.find(".//img")
|
||||||
|
if img is not None:
|
||||||
|
alt = img.get("alt", "")
|
||||||
|
src = img.get("src", "")
|
||||||
|
dungeon_name = re.sub(r" Mythic\+ Guide", "", alt)
|
||||||
|
dungeon_name_clean = slugify(dungeon_name)
|
||||||
|
saved = save_base64_image(src, f"dungeon_{dungeon_name_clean}")
|
||||||
|
if saved:
|
||||||
|
print(f" {alt}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print("Usage: poetry run python parse_dungeon.py dungeons/<filename>.html")
|
||||||
|
sys.exit(1)
|
||||||
|
main(sys.argv[1])
|
||||||
162
poetry.lock
generated
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand.
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lxml"
|
||||||
|
version = "6.0.2"
|
||||||
|
description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API."
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
groups = ["main"]
|
||||||
|
files = [
|
||||||
|
{file = "lxml-6.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e77dd455b9a16bbd2a5036a63ddbd479c19572af81b624e79ef422f929eef388"},
|
||||||
|
{file = "lxml-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d444858b9f07cefff6455b983aea9a67f7462ba1f6cbe4a21e8bf6791bf2153"},
|
||||||
|
{file = "lxml-6.0.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f952dacaa552f3bb8834908dddd500ba7d508e6ea6eb8c52eb2d28f48ca06a31"},
|
||||||
|
{file = "lxml-6.0.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:71695772df6acea9f3c0e59e44ba8ac50c4f125217e84aab21074a1a55e7e5c9"},
|
||||||
|
{file = "lxml-6.0.2-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:17f68764f35fd78d7c4cc4ef209a184c38b65440378013d24b8aecd327c3e0c8"},
|
||||||
|
{file = "lxml-6.0.2-cp310-cp310-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:058027e261afed589eddcfe530fcc6f3402d7fd7e89bfd0532df82ebc1563dba"},
|
||||||
|
{file = "lxml-6.0.2-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8ffaeec5dfea5881d4c9d8913a32d10cfe3923495386106e4a24d45300ef79c"},
|
||||||
|
{file = "lxml-6.0.2-cp310-cp310-manylinux_2_31_armv7l.whl", hash = "sha256:f2e3b1a6bb38de0bc713edd4d612969dd250ca8b724be8d460001a387507021c"},
|
||||||
|
{file = "lxml-6.0.2-cp310-cp310-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d6690ec5ec1cce0385cb20896b16be35247ac8c2046e493d03232f1c2414d321"},
|
||||||
|
{file = "lxml-6.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f2a50c3c1d11cad0ebebbac357a97b26aa79d2bcaf46f256551152aa85d3a4d1"},
|
||||||
|
{file = "lxml-6.0.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:3efe1b21c7801ffa29a1112fab3b0f643628c30472d507f39544fd48e9549e34"},
|
||||||
|
{file = "lxml-6.0.2-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:59c45e125140b2c4b33920d21d83681940ca29f0b83f8629ea1a2196dc8cfe6a"},
|
||||||
|
{file = "lxml-6.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:452b899faa64f1805943ec1c0c9ebeaece01a1af83e130b69cdefeda180bb42c"},
|
||||||
|
{file = "lxml-6.0.2-cp310-cp310-win32.whl", hash = "sha256:1e786a464c191ca43b133906c6903a7e4d56bef376b75d97ccbb8ec5cf1f0a4b"},
|
||||||
|
{file = "lxml-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:dacf3c64ef3f7440e3167aa4b49aa9e0fb99e0aa4f9ff03795640bf94531bcb0"},
|
||||||
|
{file = "lxml-6.0.2-cp310-cp310-win_arm64.whl", hash = "sha256:45f93e6f75123f88d7f0cfd90f2d05f441b808562bf0bc01070a00f53f5028b5"},
|
||||||
|
{file = "lxml-6.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:13e35cbc684aadf05d8711a5d1b5857c92e5e580efa9a0d2be197199c8def607"},
|
||||||
|
{file = "lxml-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b1675e096e17c6fe9c0e8c81434f5736c0739ff9ac6123c87c2d452f48fc938"},
|
||||||
|
{file = "lxml-6.0.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8ac6e5811ae2870953390452e3476694196f98d447573234592d30488147404d"},
|
||||||
|
{file = "lxml-6.0.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5aa0fc67ae19d7a64c3fe725dc9a1bb11f80e01f78289d05c6f62545affec438"},
|
||||||
|
{file = "lxml-6.0.2-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de496365750cc472b4e7902a485d3f152ecf57bd3ba03ddd5578ed8ceb4c5964"},
|
||||||
|
{file = "lxml-6.0.2-cp311-cp311-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:200069a593c5e40b8f6fc0d84d86d970ba43138c3e68619ffa234bc9bb806a4d"},
|
||||||
|
{file = "lxml-6.0.2-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d2de809c2ee3b888b59f995625385f74629707c9355e0ff856445cdcae682b7"},
|
||||||
|
{file = "lxml-6.0.2-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:b2c3da8d93cf5db60e8858c17684c47d01fee6405e554fb55018dd85fc23b178"},
|
||||||
|
{file = "lxml-6.0.2-cp311-cp311-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:442de7530296ef5e188373a1ea5789a46ce90c4847e597856570439621d9c553"},
|
||||||
|
{file = "lxml-6.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2593c77efde7bfea7f6389f1ab249b15ed4aa5bc5cb5131faa3b843c429fbedb"},
|
||||||
|
{file = "lxml-6.0.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:3e3cb08855967a20f553ff32d147e14329b3ae70ced6edc2f282b94afbc74b2a"},
|
||||||
|
{file = "lxml-6.0.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:2ed6c667fcbb8c19c6791bbf40b7268ef8ddf5a96940ba9404b9f9a304832f6c"},
|
||||||
|
{file = "lxml-6.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b8f18914faec94132e5b91e69d76a5c1d7b0c73e2489ea8929c4aaa10b76bbf7"},
|
||||||
|
{file = "lxml-6.0.2-cp311-cp311-win32.whl", hash = "sha256:6605c604e6daa9e0d7f0a2137bdc47a2e93b59c60a65466353e37f8272f47c46"},
|
||||||
|
{file = "lxml-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e5867f2651016a3afd8dd2c8238baa66f1e2802f44bc17e236f547ace6647078"},
|
||||||
|
{file = "lxml-6.0.2-cp311-cp311-win_arm64.whl", hash = "sha256:4197fb2534ee05fd3e7afaab5d8bfd6c2e186f65ea7f9cd6a82809c887bd1285"},
|
||||||
|
{file = "lxml-6.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:a59f5448ba2ceccd06995c95ea59a7674a10de0810f2ce90c9006f3cbc044456"},
|
||||||
|
{file = "lxml-6.0.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e8113639f3296706fbac34a30813929e29247718e88173ad849f57ca59754924"},
|
||||||
|
{file = "lxml-6.0.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a8bef9b9825fa8bc816a6e641bb67219489229ebc648be422af695f6e7a4fa7f"},
|
||||||
|
{file = "lxml-6.0.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:65ea18d710fd14e0186c2f973dc60bb52039a275f82d3c44a0e42b43440ea534"},
|
||||||
|
{file = "lxml-6.0.2-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c371aa98126a0d4c739ca93ceffa0fd7a5d732e3ac66a46e74339acd4d334564"},
|
||||||
|
{file = "lxml-6.0.2-cp312-cp312-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:700efd30c0fa1a3581d80a748157397559396090a51d306ea59a70020223d16f"},
|
||||||
|
{file = "lxml-6.0.2-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c33e66d44fe60e72397b487ee92e01da0d09ba2d66df8eae42d77b6d06e5eba0"},
|
||||||
|
{file = "lxml-6.0.2-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:90a345bbeaf9d0587a3aaffb7006aa39ccb6ff0e96a57286c0cb2fd1520ea192"},
|
||||||
|
{file = "lxml-6.0.2-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:064fdadaf7a21af3ed1dcaa106b854077fbeada827c18f72aec9346847cd65d0"},
|
||||||
|
{file = "lxml-6.0.2-cp312-cp312-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fbc74f42c3525ac4ffa4b89cbdd00057b6196bcefe8bce794abd42d33a018092"},
|
||||||
|
{file = "lxml-6.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6ddff43f702905a4e32bc24f3f2e2edfe0f8fde3277d481bffb709a4cced7a1f"},
|
||||||
|
{file = "lxml-6.0.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6da5185951d72e6f5352166e3da7b0dc27aa70bd1090b0eb3f7f7212b53f1bb8"},
|
||||||
|
{file = "lxml-6.0.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:57a86e1ebb4020a38d295c04fc79603c7899e0df71588043eb218722dabc087f"},
|
||||||
|
{file = "lxml-6.0.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:2047d8234fe735ab77802ce5f2297e410ff40f5238aec569ad7c8e163d7b19a6"},
|
||||||
|
{file = "lxml-6.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6f91fd2b2ea15a6800c8e24418c0775a1694eefc011392da73bc6cef2623b322"},
|
||||||
|
{file = "lxml-6.0.2-cp312-cp312-win32.whl", hash = "sha256:3ae2ce7d6fedfb3414a2b6c5e20b249c4c607f72cb8d2bb7cc9c6ec7c6f4e849"},
|
||||||
|
{file = "lxml-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:72c87e5ee4e58a8354fb9c7c84cbf95a1c8236c127a5d1b7683f04bed8361e1f"},
|
||||||
|
{file = "lxml-6.0.2-cp312-cp312-win_arm64.whl", hash = "sha256:61cb10eeb95570153e0c0e554f58df92ecf5109f75eacad4a95baa709e26c3d6"},
|
||||||
|
{file = "lxml-6.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:9b33d21594afab46f37ae58dfadd06636f154923c4e8a4d754b0127554eb2e77"},
|
||||||
|
{file = "lxml-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6c8963287d7a4c5c9a432ff487c52e9c5618667179c18a204bdedb27310f022f"},
|
||||||
|
{file = "lxml-6.0.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1941354d92699fb5ffe6ed7b32f9649e43c2feb4b97205f75866f7d21aa91452"},
|
||||||
|
{file = "lxml-6.0.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bb2f6ca0ae2d983ded09357b84af659c954722bbf04dea98030064996d156048"},
|
||||||
|
{file = "lxml-6.0.2-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eb2a12d704f180a902d7fa778c6d71f36ceb7b0d317f34cdc76a5d05aa1dd1df"},
|
||||||
|
{file = "lxml-6.0.2-cp313-cp313-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:6ec0e3f745021bfed19c456647f0298d60a24c9ff86d9d051f52b509663feeb1"},
|
||||||
|
{file = "lxml-6.0.2-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:846ae9a12d54e368933b9759052d6206a9e8b250291109c48e350c1f1f49d916"},
|
||||||
|
{file = "lxml-6.0.2-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ef9266d2aa545d7374938fb5c484531ef5a2ec7f2d573e62f8ce722c735685fd"},
|
||||||
|
{file = "lxml-6.0.2-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:4077b7c79f31755df33b795dc12119cb557a0106bfdab0d2c2d97bd3cf3dffa6"},
|
||||||
|
{file = "lxml-6.0.2-cp313-cp313-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a7c5d5e5f1081955358533be077166ee97ed2571d6a66bdba6ec2f609a715d1a"},
|
||||||
|
{file = "lxml-6.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8f8d0cbd0674ee89863a523e6994ac25fd5be9c8486acfc3e5ccea679bad2679"},
|
||||||
|
{file = "lxml-6.0.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:2cbcbf6d6e924c28f04a43f3b6f6e272312a090f269eff68a2982e13e5d57659"},
|
||||||
|
{file = "lxml-6.0.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dfb874cfa53340009af6bdd7e54ebc0d21012a60a4e65d927c2e477112e63484"},
|
||||||
|
{file = "lxml-6.0.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:fb8dae0b6b8b7f9e96c26fdd8121522ce5de9bb5538010870bd538683d30e9a2"},
|
||||||
|
{file = "lxml-6.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:358d9adae670b63e95bc59747c72f4dc97c9ec58881d4627fe0120da0f90d314"},
|
||||||
|
{file = "lxml-6.0.2-cp313-cp313-win32.whl", hash = "sha256:e8cd2415f372e7e5a789d743d133ae474290a90b9023197fd78f32e2dc6873e2"},
|
||||||
|
{file = "lxml-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:b30d46379644fbfc3ab81f8f82ae4de55179414651f110a1514f0b1f8f6cb2d7"},
|
||||||
|
{file = "lxml-6.0.2-cp313-cp313-win_arm64.whl", hash = "sha256:13dcecc9946dca97b11b7c40d29fba63b55ab4170d3c0cf8c0c164343b9bfdcf"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:b0c732aa23de8f8aec23f4b580d1e52905ef468afb4abeafd3fec77042abb6fe"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4468e3b83e10e0317a89a33d28f7aeba1caa4d1a6fd457d115dd4ffe90c5931d"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:abd44571493973bad4598a3be7e1d807ed45aa2adaf7ab92ab7c62609569b17d"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:370cd78d5855cfbffd57c422851f7d3864e6ae72d0da615fca4dad8c45d375a5"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:901e3b4219fa04ef766885fb40fa516a71662a4c61b80c94d25336b4934b71c0"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:a4bf42d2e4cf52c28cc1812d62426b9503cdb0c87a6de81442626aa7d69707ba"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2c7fdaa4d7c3d886a42534adec7cfac73860b89b4e5298752f60aa5984641a0"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:98a5e1660dc7de2200b00d53fa00bcd3c35a3608c305d45a7bbcaf29fa16e83d"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:dc051506c30b609238d79eda75ee9cab3e520570ec8219844a72a46020901e37"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8799481bbdd212470d17513a54d568f44416db01250f49449647b5ab5b5dccb9"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9261bb77c2dab42f3ecd9103951aeca2c40277701eb7e912c545c1b16e0e4917"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:65ac4a01aba353cfa6d5725b95d7aed6356ddc0a3cd734de00124d285b04b64f"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:b22a07cbb82fea98f8a2fd814f3d1811ff9ed76d0fc6abc84eb21527596e7cc8"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:d759cdd7f3e055d6bc8d9bec3ad905227b2e4c785dc16c372eb5b5e83123f48a"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:945da35a48d193d27c188037a05fec5492937f66fb1958c24fc761fb9d40d43c"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314-win32.whl", hash = "sha256:be3aaa60da67e6153eb15715cc2e19091af5dc75faef8b8a585aea372507384b"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314-win_amd64.whl", hash = "sha256:fa25afbadead523f7001caf0c2382afd272c315a033a7b06336da2637d92d6ed"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314-win_arm64.whl", hash = "sha256:063eccf89df5b24e361b123e257e437f9e9878f425ee9aae3144c77faf6da6d8"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:6162a86d86893d63084faaf4ff937b3daea233e3682fb4474db07395794fa80d"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:414aaa94e974e23a3e92e7ca5b97d10c0cf37b6481f50911032c69eeb3991bba"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:48461bd21625458dd01e14e2c38dd0aea69addc3c4f960c30d9f59d7f93be601"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:25fcc59afc57d527cfc78a58f40ab4c9b8fd096a9a3f964d2781ffb6eb33f4ed"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5179c60288204e6ddde3f774a93350177e08876eaf3ab78aa3a3649d43eb7d37"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314t-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:967aab75434de148ec80597b75062d8123cadf2943fb4281f385141e18b21338"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d100fcc8930d697c6561156c6810ab4a508fb264c8b6779e6e61e2ed5e7558f9"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ca59e7e13e5981175b8b3e4ab84d7da57993eeff53c07764dcebda0d0e64ecd"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:957448ac63a42e2e49531b9d6c0fa449a1970dbc32467aaad46f11545be9af1d"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314t-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b7fc49c37f1786284b12af63152fe1d0990722497e2d5817acfe7a877522f9a9"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e19e0643cc936a22e837f79d01a550678da8377d7d801a14487c10c34ee49c7e"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:1db01e5cf14345628e0cbe71067204db658e2fb8e51e7f33631f5f4735fefd8d"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:875c6b5ab39ad5291588aed6925fac99d0097af0dd62f33c7b43736043d4a2ec"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:cdcbed9ad19da81c480dfd6dd161886db6096083c9938ead313d94b30aadf272"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:80dadc234ebc532e09be1975ff538d154a7fa61ea5031c03d25178855544728f"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314t-win32.whl", hash = "sha256:da08e7bb297b04e893d91087df19638dc7a6bb858a954b0cc2b9f5053c922312"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314t-win_amd64.whl", hash = "sha256:252a22982dca42f6155125ac76d3432e548a7625d56f5a273ee78a5057216eca"},
|
||||||
|
{file = "lxml-6.0.2-cp314-cp314t-win_arm64.whl", hash = "sha256:bb4c1847b303835d89d785a18801a883436cdfd5dc3d62947f9c49e24f0f5a2c"},
|
||||||
|
{file = "lxml-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a656ca105115f6b766bba324f23a67914d9c728dafec57638e2b92a9dcd76c62"},
|
||||||
|
{file = "lxml-6.0.2-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c54d83a2188a10ebdba573f16bd97135d06c9ef60c3dc495315c7a28c80a263f"},
|
||||||
|
{file = "lxml-6.0.2-cp38-cp38-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:1ea99340b3c729beea786f78c38f60f4795622f36e305d9c9be402201efdc3b7"},
|
||||||
|
{file = "lxml-6.0.2-cp38-cp38-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:af85529ae8d2a453feee4c780d9406a5e3b17cee0dd75c18bd31adcd584debc3"},
|
||||||
|
{file = "lxml-6.0.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:fe659f6b5d10fb5a17f00a50eb903eb277a71ee35df4615db573c069bcf967ac"},
|
||||||
|
{file = "lxml-6.0.2-cp38-cp38-win32.whl", hash = "sha256:5921d924aa5468c939d95c9814fa9f9b5935a6ff4e679e26aaf2951f74043512"},
|
||||||
|
{file = "lxml-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:0aa7070978f893954008ab73bb9e3c24a7c56c054e00566a21b553dc18105fca"},
|
||||||
|
{file = "lxml-6.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2c8458c2cdd29589a8367c09c8f030f1d202be673f0ca224ec18590b3b9fb694"},
|
||||||
|
{file = "lxml-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3fee0851639d06276e6b387f1c190eb9d7f06f7f53514e966b26bae46481ec90"},
|
||||||
|
{file = "lxml-6.0.2-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b2142a376b40b6736dfc214fd2902409e9e3857eff554fed2d3c60f097e62a62"},
|
||||||
|
{file = "lxml-6.0.2-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a6b5b39cc7e2998f968f05309e666103b53e2edd01df8dc51b90d734c0825444"},
|
||||||
|
{file = "lxml-6.0.2-cp39-cp39-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4aec24d6b72ee457ec665344a29acb2d35937d5192faebe429ea02633151aad"},
|
||||||
|
{file = "lxml-6.0.2-cp39-cp39-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:b42f4d86b451c2f9d06ffb4f8bbc776e04df3ba070b9fe2657804b1b40277c48"},
|
||||||
|
{file = "lxml-6.0.2-cp39-cp39-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6cdaefac66e8b8f30e37a9b4768a391e1f8a16a7526d5bc77a7928408ef68e93"},
|
||||||
|
{file = "lxml-6.0.2-cp39-cp39-manylinux_2_31_armv7l.whl", hash = "sha256:b738f7e648735714bbb82bdfd030203360cfeab7f6e8a34772b3c8c8b820568c"},
|
||||||
|
{file = "lxml-6.0.2-cp39-cp39-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:daf42de090d59db025af61ce6bdb2521f0f102ea0e6ea310f13c17610a97da4c"},
|
||||||
|
{file = "lxml-6.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:66328dabea70b5ba7e53d94aa774b733cf66686535f3bc9250a7aab53a91caaf"},
|
||||||
|
{file = "lxml-6.0.2-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:e237b807d68a61fc3b1e845407e27e5eb8ef69bc93fe8505337c1acb4ee300b6"},
|
||||||
|
{file = "lxml-6.0.2-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:ac02dc29fd397608f8eb15ac1610ae2f2f0154b03f631e6d724d9e2ad4ee2c84"},
|
||||||
|
{file = "lxml-6.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:817ef43a0c0b4a77bd166dc9a09a555394105ff3374777ad41f453526e37f9cb"},
|
||||||
|
{file = "lxml-6.0.2-cp39-cp39-win32.whl", hash = "sha256:bc532422ff26b304cfb62b328826bd995c96154ffd2bac4544f37dbb95ecaa8f"},
|
||||||
|
{file = "lxml-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:995e783eb0374c120f528f807443ad5a83a656a8624c467ea73781fc5f8a8304"},
|
||||||
|
{file = "lxml-6.0.2-cp39-cp39-win_arm64.whl", hash = "sha256:08b9d5e803c2e4725ae9e8559ee880e5328ed61aa0935244e0515d7d9dbec0aa"},
|
||||||
|
{file = "lxml-6.0.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e748d4cf8fef2526bb2a589a417eba0c8674e29ffcb570ce2ceca44f1e567bf6"},
|
||||||
|
{file = "lxml-6.0.2-pp310-pypy310_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4ddb1049fa0579d0cbd00503ad8c58b9ab34d1254c77bc6a5576d96ec7853dba"},
|
||||||
|
{file = "lxml-6.0.2-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cb233f9c95f83707dae461b12b720c1af9c28c2d19208e1be03387222151daf5"},
|
||||||
|
{file = "lxml-6.0.2-pp310-pypy310_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bc456d04db0515ce3320d714a1eac7a97774ff0849e7718b492d957da4631dd4"},
|
||||||
|
{file = "lxml-6.0.2-pp310-pypy310_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2613e67de13d619fd283d58bda40bff0ee07739f624ffee8b13b631abf33083d"},
|
||||||
|
{file = "lxml-6.0.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:24a8e756c982c001ca8d59e87c80c4d9dcd4d9b44a4cbeb8d9be4482c514d41d"},
|
||||||
|
{file = "lxml-6.0.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1c06035eafa8404b5cf475bb37a9f6088b0aca288d4ccc9d69389750d5543700"},
|
||||||
|
{file = "lxml-6.0.2-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c7d13103045de1bdd6fe5d61802565f1a3537d70cd3abf596aa0af62761921ee"},
|
||||||
|
{file = "lxml-6.0.2-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0a3c150a95fbe5ac91de323aa756219ef9cf7fde5a3f00e2281e30f33fa5fa4f"},
|
||||||
|
{file = "lxml-6.0.2-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:60fa43be34f78bebb27812ed90f1925ec99560b0fa1decdb7d12b84d857d31e9"},
|
||||||
|
{file = "lxml-6.0.2-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:21c73b476d3cfe836be731225ec3421fa2f048d84f6df6a8e70433dff1376d5a"},
|
||||||
|
{file = "lxml-6.0.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:27220da5be049e936c3aca06f174e8827ca6445a4353a1995584311487fc4e3e"},
|
||||||
|
{file = "lxml-6.0.2.tar.gz", hash = "sha256:cd79f3367bd74b317dda655dc8fcfa304d9eb6e4fb06b7168c5cf27f96e0cd62"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
cssselect = ["cssselect (>=0.7)"]
|
||||||
|
html-clean = ["lxml_html_clean"]
|
||||||
|
html5 = ["html5lib"]
|
||||||
|
htmlsoup = ["BeautifulSoup4"]
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
lock-version = "2.1"
|
||||||
|
python-versions = "^3.12"
|
||||||
|
content-hash = "51fcc3287807d80972696b287267c9510262d473f6a5328d44c478a16dbc851e"
|
||||||
BIN
public/assets/algethar_academy_header.jpg
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
public/assets/araknath_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
public/assets/arcanotron_custos_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
public/assets/chief_corewright_kasreth_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
public/assets/commander_kroluk_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
public/assets/corewarden_nysarra_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
public/assets/crawth_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
public/assets/degentrius_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
public/assets/derelict_duo_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
public/assets/dungeon_algeth_ar_academy.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
public/assets/dungeon_magister_s_terrace.jpg
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
public/assets/dungeon_maisara_caverns.jpg
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
public/assets/dungeon_nexus_point_xenas.jpg
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
public/assets/dungeon_pit_of_saron.jpg
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
public/assets/dungeon_seat_of_the_triumvirate.jpg
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
public/assets/dungeon_skyreach.jpg
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
public/assets/dungeon_windrunner_spire.jpg
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
public/assets/echo_of_doragosa_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
BIN
public/assets/emberdawn_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
public/assets/forgemaster_garfrost_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
public/assets/gemellus_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
BIN
public/assets/high_sage_viryx_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
public/assets/ick_and_krick_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
public/assets/l_ura_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
public/assets/lothraxion_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
public/assets/magisters_terrace_header.jpg
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
public/assets/maisara_caverns_header.jpg
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
public/assets/muro_jin_and_nekraxx_boss_fight.jpg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
public/assets/nexus_point_xenas_header.jpg
Normal file
|
After Width: | Height: | Size: 25 KiB |