# HV Utils 4.2.3 — Deep Structural Analysis
**Source:** `/home/gabogg/Downloads/HVUT_4.2.3.txt`
**Lines:** 9,710 (416 KB)
**Author:** sssss2
**Date:** 2026-06-21
**Sections:** 19 page-specific modules + 10 core shared modules
---
## 1. PAGE DETECTION
HV Utils uses a multi-layered detection system:
### Primary: URL Query Parsing (Line 212)
```js
const _query = Object.fromEntries(location.search.slice(1).split('&')
.map((q) => { const [k, v = ''] = q.split('=', 2);
return [decodeURIComponent(k), decodeURIComponent(v)];
}));
```
This parses Hentaiverse's `?s=X&ss=Y&screen=Z&filter=W` format into `_query.s`, `_query.ss`, `_query.screen`, `_query.filter`.
### Server Detection (Line 213-217)
```js
const _server = {
name: location.pathname.includes('/isekai/') ? 'isekai' : 'persistent',
season: $id('world_text')?.textContent.match(/\d+ Season \d+/)?.[0] || '1',
};
```
Also sets `_server.persistent` / `_server.isekai` for boolean checks.
### Page Dispatch Architecture (Lines 3819–9710)
The script uses a chain of `if/else if` blocks testing `_query.s`, `_query.ss`, and DOM elements:
| Section | Condition | Module | Line |
|---------|-----------|--------|------|
| Character | `s=Character, ss=ch` | `_ch` | 3819 |
| Equipment | `s=Character, ss=eq` | `_eq` | 3922 |
| Abilities | `s=Character, ss=ab` | `_ab` | 4096 |
| Training | `s=Character, ss=tr` | `_tr` | 4467 |
| Item Inventory | `s=Character, ss=it` | `_it` | 4675 |
| Settings | `s=Character, ss=se` | `_se` | 4703 |
| Item Shop | `s=Bazaar, ss=is` | `_is` | 4806 |
| The Shrine | `s=Bazaar, ss=ss` | `_ss` | 4832 |
| The Market | `s=Bazaar, ss=mk` | `_mk` | 5373 |
| Monster Lab | `s=Bazaar, ss=ml` | `_ml` | 5485 |
| MoogleMail | `s=Bazaar, ss=mm` | `_mm` | 6869 |
| Lottery | `s=Bazaar, ss=lt/la` | `_lt` | 8499 |
| Battle → Arena | `s=Battle, ss=ar` | `_ar` | 8560 |
| Battle → RoB | `s=Battle, ss=rb` | `_ar` | 8570 |
| Battle → Tower | `s=Battle, ss=tw` | — | 8580 |
| Battle → GrindFest | `s=Battle, ss=gr` | — | 8587 |
| Battle → Item World | `s=Battle, ss=iw` | — | 8594 |
| Armory (Equip Shop) | `s=Bazaar, ss=am` | `$armory` | 8609 |
| Modify (single equip) | `s=Bazaar, ss=am, screen=modify` | `_mo` | 9669 |
### No-Navbar Early Exit (Lines 1144–1164)
Before any page dispatch, the script checks `$id('navbar')`. If absent, it handles:
- **Battle pages:** Activates RE timer in battle mode
- **e-hentai.org gallery:** Activates RE timer in gallery mode
- **Riddle Master:** Commented out
Then `return` — none of the page modules execute.
---
## 2. INVENTORY/SHOP AUTOMATION
### Equipment Shop (`$armory`, Lines 8609–9667)
**Architecture:** A self-contained module on `?s=Bazaar&ss=am` pages with sub-modules:
#### Sidebar Buttons (Line 8752-8801)
- **Select All** — toggles all non-protected, non-filtered checkboxes
- **Tradeables / Pinned** — bulk selection by status
- **Equip Code** — generate forum BBcode for selected equipment
- **Sell / Salvage / Purchase & Salvage** — with smart selection:
- `sell`: selects items where sell_price ≥ salvage_value, excluding protected/locked/stored
- `salvage`: selects items where salvage_value > sell_price
- `purchase_salvage`: selects items profitable to buy+salvage
- **Bazaar Filters / Protect Filters** — toggle between show-all and hide-based-on-filters
#### Protection System (Line 9073-9089)
- The `protect()` method checks: `eq.info.protected || eq.info.pinned || $equip.filter.equip($config.settings.equipmentShopProtectFilters, eq)`
- Protected equipment is moved to a special `
` at the top labeled "Protected Equipment"
- Their checkboxes are disabled from "Select All"
- If `equipmentShopAutoProtect` is enabled, auto-submits a protect action
#### Bazaar Filter System (Line 9090-9104)
- Applies `equipmentShopBazaarFilters` to hide non-valuable equipment
- Also shows items where `salvage_value > purchase_price` (profitable to buy and salvage)
- Hidden items get `hvut-eqp-hidden` class; category headers auto-hide when all children hidden
#### Salvage Value Calculation (`$armory.calc`, Line 8852-8938)
- **`calc.materials(eq)`**: Estimates salvage materials based on quality, material type, core type, and rare status:
- Quality 1-3 (Crude–Average): `Scrap [type]` = `min(10, ceil(sell_price / 100))`
- Quality 4 (Superior): `Low-Grade [type]` × (1 on persistent, 3 on isekai)
- Quality 5 (Exquisite): `Mid-Grade [type]`
- Quality 6 (Magnificent): `High-Grade [type]`
- Quality 7+ (Legendary/Peerless): adds `[Quality] [Weapon/Staff/Armor] Core` (×5 if rare)
- Rare items: adds `Energy Cell`
- **`calc.value(materials)`**: Multiplies by item prices (with optional 1% market fee deduction)
- Shows "C" (sell price) and "V" (salvage value) columns, highlighting profitable salvage in green
#### Submit Confirm (Line 9184-9194)
Three modes based on `equipmentShopConfirm`:
- `0`: default browser confirm dialog
- `1`: auto-check confirm checkbox
- `2`: skip confirmation entirely
#### Screen-Specific Modifications (`$armory.modify`, Line 8978-9042)
- **organize**: Adds note input fields (for `@price, $note` forum code annotations)
- **modify**: Shows upgrade/IW levels
- **purchase**: Shows purchase price and salvage value side-by-side; applies bazaar filter
- **sell**: Loads salvage page to get salvage values; protects valuable items
- **salvage**: Loads sell page to get sell prices; protects valuable items
#### All-In-One Integration (Line 8940-8975)
- `$armory.integrate` loads ALL equipment categories (1H, 2H, Staff, Shield, Cloth, Light, Heavy) into a single unified table
- Adds an "All" tab to the filter bar
- Each category loads asynchronously via AJAX
### Item Shop (`_is`, Lines 4806–4828)
- Minimal: just adds `hvut-item-{type}` CSS class to each row for color coding
- Types: Consumable, Artifact, Trophy, Token, Crystal, MonsterFood, Material, Collectable
---
## 3. SHRINE (`_ss`, Lines 4832–5371)
### Bulk Offering Queue
**Per-Item Controls (Line 5029-5081):**
- Each item row gets:
- A number input for offer count
- An "Offer" button
- For trophies: "All" button (offers max = `floor(stock / bulk)`)
- Displays bulk grouping info (e.g., " / 1000")
**Trophy Value System (Line 5050-5068):**
- Trophies have tier-based values (1000c for T2, 2000c for T3, 4000c for T4, 5000c for T5)
- Auto-calculates upgrade paths: combining lower-tier trophies into higher tiers increases value
- Shows upgraded trophy tier and value
**Item Hiding (Line 5070-5072):**
- Items matching `shrineHideItems` (default: `['Figurine', 'Peerless Voucher']`) get `hvut-none-item` class
- Toggle button to show/hide these filtered items
**Reward Selection (Line 4911-4948):**
- Intercepts reward selection buttons, adds visual highlight on selected reward
- Tracks `reward_type` and `reward_slot` for each offering request
### Result Tracking
**Offering Requests (Line 5083-5371):**
- Each offering creates an AJAX request with: `iid`, `count`, optional `reward_type`/`reward_slot`
- Results parsed from server response messages
- Equipment rewards filtered through `shrineFilters` (default: Peerless, Legendary, Magnificent, Exquisite)
- Results displayed in a toggleable table showing per-item breakdowns:
- Percentage and count for each reward type
- Equipment names shown for quality-filtered items
- Grouped categories (Pouches, Charms, High-Grade Materials, Bindings, Crystals, PABs)
**Shrine Log (Line 4889-4889):**
- Persistent log of all offering results
- Reset button to clear log
---
## 4. MONSTER LAB (`_ml`, Lines 5485–6867)
### Monster List Display
**Sort System (Line 5660-5685):**
- Sorts by: index, name, class, PL, wins, kills, gains, gifts, morale, hunger
- Configurable default via `monsterLabDefaultSort`
- Click column headers to sort; clicking again reverses order
**Per-Monster Tracking (Line 5741-5836):**
- `_ml.mobs[]` array stores: name, class, PL, wins, kills, PA values, ER values, CT values, morale, hunger, gifts log
- `_ml.log[]` persisted to storage with: date, PL, wins, kills, PA/ER/CT arrays, 49-element gift array
**Morale/Hunger Display (Line 5791-5803):**
- Parses the pixel-width of bar images: `hunger = width * 200`, `morale = width * 200`
- Shows numeric value overlay on each bar
### Feed System
**Feed Actions (Line 5877-5909):**
- **Click morale bar:** Feeds drugs (increases morale)
- **Click hunger bar:** Feeds food (increases hunger)
- **Click wins/kills:** Updates monster stats (fetches the monster page)
- After feeding, auto-updates: PL, wins, kills, PAs, ERs, CTs, morale, hunger bars
**Bulk Feed (Line 5889-5891):**
- "Update Wins/Kills" button feeds ALL monsters
- `feedall(stat, value, food)` — conditional bulk feeding
### Gift Tracking
**Gift Summary (Line 5921-5976):**
- Parses message box for gift notifications: "X brought you a gift!" + "Received N× Item"
- Computes total gifts and estimated credit value using `$price.value()`
- Shows per-material breakdown in a summary panel
**Monster Log (Line 5996-6023):**
- Per-monster log showing all 49 tracked material types
- Shows: days since first log, total gifts, total value, daily average
- Formatted in two-column layout
- Materials tracked: 12 grade materials + Phazon + Shade Fragment + Repurposed Actuator + Defense Matrix + 33 Bindings + World Seed
### Crystal/Pill Feeder (Monster Upgrader, Lines 6037-6867)
**Upgrade Table (Line 6096-6135):**
- Spreadsheet-style grid: rows = monsters, columns = stats
- **Primary Attributes (PA):** STR, DEX, AGI, END, INT, WIS → use Vigor/Finesse/Swiftness/Fortitude/Cunning/Knowledge crystals
- **Elemental Resistances (ER):** FIRE, COLD, ELEC, WIND, HOLY, DARK → use Flames/Frost/Lightning/Tempest/Devotion/Corruption crystals
- **Chaos Tokens (CT):** 12 stats → use Chaos Tokens
**Bulk Operations:**
- Increase/Decrease all monsters' stats at once
- Equalize (set all to highest value)
- Per-stat buttons for each crystal type
- Right-click to decrease, left-click to increase
**Crystal Stock Tracking:**
- Loads item inventory to show available crystals
- Shows per-crystal usage and remaining stock
### Power Level Calculator (Lines ~6700-6867)
- Complex PL simulation with PA/ER/CT values
- Input fields for custom values with slider-like controls
- Shows PL changes per stat
---
## 5. MOOGLEMAIL (`$mail` + `_mm`, Lines 2174–2413, 6869–8498)
### Send Engine (`$mail`)
**Queue System (Line 2179-2305):**
- `$mail.queue[]`: Array of mail chunks
- `$mail.current`: Index of current mail being processed
- `$mail.ready`: Semaphore preventing concurrent sends
- Auto-chains: when one mail completes, the next automatically starts
**Chunking (Line 2306-2386):**
- Splits large attachments into chunks of 10 items each
- Auto-generates subject from first item name
- Calculates CoD totals with optional deduction
- Adds attachment text to body
**Send Process (Line 2186-2305):**
1. Fetches MoogleMail token if not cached
2. Removes any existing attachments
3. Attaches items via `attach_add` API (Promise.all for concurrency)
4. Sets CoD if applicable
5. For persistent CoD (Isekai → Persistent): opens persistent MoogleMail, attaches credits, sets CoD there
6. Sends message
7. On completion: advances to next queue item, or redirects to Sent folder
**Error Handling (Line 2387-2398):**
- Checks server response for error messages
- On error: logs and discards the draft
### Write UI (`_mm.write`, Lines 6889-7089)
**Compose Interface:**
- To: with datalist autocomplete from user list
- Subject: auto-filled from first attachment
- Body: textarea
- CoD Deduction field
- Persistent CoD checkbox (Isekai only)
**Attachment Panels (three tabs):**
1. **Credits** (`_mm.credits`): Amount input with pre-set buttons (10k, 100k, 500k, 1m, etc.)
2. **Equipment** (`_mm.equip`): List of all equipment with checkboxes, search by name/EID, protected-item warning
3. **Items** (`_mm.item`): Filter by group (Consumables, Materials, Trophies, Crystals, Figures), search by name, bulk count/check
**Item Attachment (Lines 7092-7169):**
- Search: type partial item names, separated by commas
- Each item row: checkbox, count input, price input, auto-calculated CoD
- "CALC" button: previews attachment text
- "ATTACH from TEXT": parses free-form text like `100 x Health Potion @ 10`
- "SEND" button on each row for single-item quick send
- "SEND ALL" to send everything checked
**User List (Line 7020-7049):**
- Persisted list of recipients
- Auto-adds on send
- Deduplication on save
- Editable via popup
---
## 6. TRAINING (`_tr`, Lines 4467–4671)
### Queue Management
**Data Model (Line 4470-4488):**
- `_tr.json` (stored as `hvut_tr_notif`): `{ current_name, current_level, current_end, next_name, next_level, next_id, error }`
- Training data: id, base cost, linear cost increment, exponential factor for all 15 trainable skills
**Progress Tracking (Line 4548-4559):**
- Reads `end_time` from server-rendered JavaScript
- Shows current training name + level in bottom bar
- Countdown timer with `HH:MM:SS` format
**Queue System (Lines 4491-4659):**
- **Plan Training:** Select skill + target level, shows calculated credit cost
- **Set:** Saves `next_name`/`next_level`/`next_id` to storage
- When current training completes (or on page load if idle):
1. Fetches training page
2. Checks if `next_name`'s current level < `next_level`
3. If yes: auto-submits `start_train=` form
4. If no: shows "Training completed!"
- **Cancel:** Clears the notification JSON
- **Reset Planning:** Clears both current and next
**Cost Calculation (Line 4611-4628):**
- Formula: `Σ pow(base + linear × level, 1 + exp × level)` for each level from current to target
- Uses the real game formulas for each training type
- Shows spent credits per training and total spent
**Bottom Bar Integration (Line 3647-3721):**
- `_bottom.tr` shows current training status in compact format
- Links to training page
- Auto-loads when timer expires
---
## 7. EQUIPMENT MANAGEMENT
### Upgrade Queue (`_mo.upgrade`, Lines 9669–9704)
On the single-equipment Modify page:
- Parses the upgrade materials table
- Calculates total cost using `$price.value(mats) + credits`
- Shows clickable total cost button → opens price editor
### Salvage/Repair/Rebuild (via `$armory`, Lines 8609-9667)
**Salvage vs Sell Comparison:**
- Calculates `salvage_value` from estimated materials × market prices
- Compares with `sell_price` or `purchase_price`
- Highlights profitable salvage in green (`hvut-eqp-profit`)
- "Purchase & Salvage" action filters for profitable arbitrage
**Batch Operations:**
- `$armory.submit.confirm('sell', ...)` / `$armory.submit.confirm('salvage', ...)`
- Gets the real submit button from the page, submits multi-equip form
### Reforge/Soulfuse
- Not directly implemented as separate features
- The Armory page covers all screens (organize, modify, repair, soulbind, purchase, sell, salvage)
### Equipment Data (`$armory.equipdata`, Line 8621)
- Stored as `hvut_equipdata` (persistent) / `hvuti_equipdata` (isekai)
- Contains per-EID: price (for forum code), note (for forum code `$featured` flag)
---
## 8. ITEM WORLD (Line 8594–8600)
The IW implementation is relatively minimal:
- Renders equipment list table with `$equip.list.table()`
- Moves the equipment blurb to the action area
- Initializes the battle panel (`$battle.init()`) for the equip select outer div
- **No PXP simulator is present** in this version (4.2.3). The script relies on the game's built-in IW interface.
Note: There *is* an EXP Simulator on the Character page (`_ch.exp`, Line 3823-3901) which uses the same exponential formula as the game.
---
## 9. ARENA/BATTLE MODES (Lines 8517–8604)
### Compact View
All battle modes (Arena, Ring of Blood, Tower, GrindFest, Item World) use `$battle.init()`:
**Layout System:**
- Wraps main pane in `hvut-bt-outer` class
- Adds a 600px side panel (`#hvut-bt-div`) on the left or right (configurable)
- Compact mode (`hvut-bt-on`): reduces main pane to 620px, side panel slides in
- Toggle button: "Details" / "Collapse"
**Equipment Panel (`.hvut-bt-equip`):**
- Shows equipped gear from current equip set
- Per-equip row: name (link), condition% / energy%, repair button
- Condition ≤ threshold (default 20%) shown in warning color
- Hover on repair shows per-material breakdown for that equip
**Item Inventory Panel (`.hvut-bt-items`):**
- Shows configured items from `equipPanelItemInventory`
- Format: `name (stock / threshold)`
- Warning if stock < threshold
- Click item name to buy from Item Shop
**Repair All Panel:**
- Calculates total materials needed
- Checks item inventory; if insufficient, offers to buy from Item Shop (Scraps, Energy Cell)
- Non-purchasable items (Infusions, Shards) trigger alert to buy from Market
### Arena-Specific
- Splits colspan=2 rows for proper compact layout
- Re-parents arena_list into arena_outer div
### Ring of Blood
- Same split_colspan treatment
- Includes arena_tokens in the outer
---
## 10. RE TIMER (`$re`, Lines 947–1142)
### Detection Mechanisms
**Mode Detection (Line 953):**
```js
$re.type = (!location.hostname.includes('hentaiverse.org') || _server.isekai) ? 'eh'
: $id('navbar') ? 'hv'
: $id('battle_top') ? 'ba'
: false;
```
- **`eh`**: e-hentai.org gallery or Isekai server
- **`hv`**: Normal Hentaiverse pages (has navbar)
- **`ba`**: Battle pages (has battle_top)
- **`false`**: Unknown/unsupported
### Key Management
- Stored as `hvut_re` (cross-profile, not namespaced): `{ date, key, count, clear }`
- **30-minute timer:** Random Encounter refreshes every 30 minutes
- **Auto-detection:**
- On HV pages: checks `location.search` for `encounter=`
- On e-hentai: scrapes the event pane for the encounter link
- **Daily reset:** If the stored date is from a different UTC day, auto-resets
### Notification
- **Countdown display:** Shows `MM:SS [count]` while timer active
- **"Ready"**: When timer expires, button shows "Ready [count]"
- **"Expired"**: If an encounter was generated but not cleared
- **Beep:** Audio notification at `[0.2, 500, 0.5]` (volume, Hz, seconds) when timer expires — configurable, with test button
- **Warning highlight:** `hvut-warn` class when an uncleared encounter exists
### Engagement
- **Click RE button:** Engages if ready/uncleared (or Ctrl+Click to force engage)
- **Battle mode:** Shows RE status, click loads new key
- **Gallery mode:** Opens in new tab (configurable alt.hentaiverse.org)
- **Gallery detection:** Scrapes e-hentai.org news.php for the encounter key
---
## 11. DIFFICULTY/PERSONA/SET SELECTOR
### Difficulty Changer (`$dfct`, Lines 3280–3337)
**Location:** Top bar, shows current difficulty (Normal/Hard/Nightmare/Hell/Nintendo/IWBTH/PFUDOR)
**Mechanism:**
- Hover reveals dropdown with all 7 difficulties
- Selecting triggers:
1. Fetch settings page
2. Extract form data
3. Modify `difflevel`
4. POST updated form
5. Update local `_player.difficulty`
6. Persist to `hvut_ch_style`
**State:** Persists chosen difficulty in `ch_style.difficulty` storage
### Persona & Equipment Set Selector (`$persona`, Lines 3340–3594)
**Location:** Top bar, shows "Persona" by default, then current set name
**Data Model:**
```js
$persona.json = {
pset: current_persona_number,
plen: total_personas,
pname: current_persona_name,
eset: current_equip_set_number,
elen: total_equip_sets,
ename: current_set_name,
[pset]: { name: "...", [eset]: { name: "..." }, ... }
}
```
**Persona Switching:**
1. Fetch `?s=Character&ss=ch` with `persona_set=`
2. Parse persona form for all persona names/IDs
3. Check if current matches stored
**Equip Set Switching:**
1. Fetch `?s=Character&ss=eq` with `equip_set=`
2. Detect active set by finding `_on.png` image
3. Save equip config to `$config.set('equipset', ...)` — array of `{ slot, category, name, customname, eid, key }`
**Auto-reload:** After persona/set change, reloads current page if on Equipment, Abilities, Items, or Settings tabs
**Stats Parsing:**
- Parses the stats pane to determine:
- Fighting Style (Staff/Dualwield/Niten/Two-Handed/One-Handed/Unarmed)
- Best spell type (highest affinity)
- Proficiency factor
- Magic score
- Saves to `ch_style` for external use (e.g., monsterbation)
**Warnings:**
- Shows red warning bar for: repair needed, attribute check, exhausted stamina
- Stamina warning for: Exhausted, accuracy penalty, or below `warnLowStamina`
---
## 12. UI SYSTEM
### Top Navigation Bar (Lines 3030–3277)
**Complete replacement** of the game's `#navbar`:
- Hidden via `#navbar { display: none; }`
- Custom `#hvut-top` flexbox bar with:
- **MENU dropdown** (or individual section dropdowns if integration disabled): Character, Bazaar, Battle, Armory categories in organized columns
- **Quick links:** Configurable 2-letter link buttons (CH, EQ, AB, TR, IT, SE, IS, SS, MK, ML, MM, etc.)
- **Stamina display** with dropdown for restorative items
- **Level display** with EXP progress bar
- **Difficulty** dropdown
- **Persona/Equip Set** dropdown
- **RE Timer** display
- **Server** indicator with switch link
- **Settings** gear icon
### Bottom Bar (Lines 3597–3816)
`#hvut-bottom` below the main pane:
- **Credits** display (C:)
- **Equipment Inventory** capacity (E: usage/capacity) with warnings near limit
- **Training** status with countdown
- **Lottery** displays for Weapon and Armor lotteries:
- Shows current equipment + time until next drawing
- Red highlight when drawing is imminent
- Pops up alert when qualifying equipment appears (checked against `lotteryFilters`)
### Color Coding System (Lines 2772–2820)
**CSS Custom Properties** on `:root`:
**Font Colors:**
- `--color-font-default`: #5C0D11 (dark red-brown)
- `--color-font-light`: #9B4E03 (orange-brown)
- `--color-font-highlight`: #c00 (red)
- `--color-font-warn`: #e00 (bright red)
- `--color-font-bonus`: #03c (blue)
- `--color-font-invalid`: #666 (gray)
- `--color-font-invert`: #fff (white)
**Background Colors:**
- `--color-bg-default`: #EDEBDF (parchment) — main background
- `--color-bg-back`: #E3E0D1 — secondary background
- `--color-bg-light`: #fff — light highlight
- `--color-bg-alpha`: #fff9 — translucent overlay
- `--color-bg-invert`: #5C0D11 — inverted (dark)
- `--color-bg-h1`: #edb — header background
**Equipment Quality Colors:**
- Peerless: #fbb (pink), Legendary: #fd8 (gold), Magnificent: #bdf (light blue), Exquisite: #ce9 (green), Superior: #ccc (gray)
- Applied as `hvut-equip-{Quality}` class + `background-color` on rows
**Item Type Colors:**
- Consumable: #00B000 (green), Artifact: #0000FF (blue), Trophy: #461B7E (purple), Token: #254117 (dark green), Crystal: #BA05B4 (magenta), MonsterFood: #489EFF (light blue), Material: #FF0000 (red), Collectable: #0000FF (blue)
- Applied as `hvut-item-{Type}` class on rows
**Warning System:**
- `.hvut-warn`: Red text (#e00)
- `.hvut-warn2`: Inverted (dark bg, white text)
- `.hvut-bonus`: Blue text (#03c)
### Side Panel System
- `.hvut-side`: Absolute-positioned 100px wide flex column
- Used on: Shrine (`.hvut-ss-side`), Monster Lab (`.hvut-ml-side`), Market (`.hvut-mk-side`), Armory (`.hvut-am-side`)
- Contains action buttons grouped with optional margins
---
## 13. STORAGE STRUCTURES
### Primary Storage: `GM_getValue` / `GM_setValue` (TGM/Greasemonkey)
All keys prefixed with `hvut_` (persistent) or `hvuti_` (isekai):
| Key | Type | Description |
|-----|------|-------------|
| `hvut_settings` | Object | All user settings |
| `hvut_prices` | Object | Item price mappings (name → credits) |
| `hvut_persona` | Object | Persona/equip set state |
| `hvut_ch_style` | Object | Character style (difficulty, FS, spell type, prof factor) |
| `hvut_equipset` | Array | Current equip set slots |
| `hvut_equipdata` | Object | Equipment notes/prices (per EID) |
| `hvut_ml_log` | Array | Monster Lab log |
| `hvut_ss_log` | Object | Shrine log |
| `hvut_mm_userlist` | Array | MoogleMail recipient list |
| `hvut_ab_level` | Object | Ability levels |
| `hvut_se_settings` | Object | Saved settings presets |
| `hvut_tr_level` | Object | Training levels |
### Secondary Storage: `localStorage` (backup for critical data)
The `$config.ls_savelist` (line 222) defines which keys also get localStorage backup:
- `ch_style`, `persona`, `prices`, `equipset`
### Cross-Profile Storage (no prefix)
| Key | Type | Description |
|-----|------|-------------|
| `hvut_re` | Object | Random Encounter state (`{ date, key, count, clear }`) |
| `hvut_tr_notif` | Object | Training notification state |
| `hvut_lt_notif` | Object | Lottery notification state |
### Migration System (`$config.migration`, Lines 402-511)
- Detects old localStorage-based data (pre-4.x)
- Upgrades: equipdata, prices, protection filters, bazaar filters, monster lab log, equip sets, shrine log
- Cleans up old localStorage keys after migration
- Version-specific migrations for 4.2 and 4.22
---
## 14. KEY FUNCTION NAMES AND PURPOSES
### Core Shared Modules
| Module | Line | Purpose |
|--------|------|---------|
| `$config` | 220 | Configuration system: get/set/del/validate/migrate |
| `$ajax` | 837 | Rate-limited AJAX queue (300ms interval, max 4 concurrent) |
| `$re` | 947 | Random Encounter timer and notification |
| `$equip` | 1227 | Equipment parsing, sorting, filtering, namecode generation |
| `$item` | 1810 | Item inventory loading, counting, shop buying |
| `$price` | 1950 | Item price management, market integration |
| `$mail` | 2174 | MoogleMail send queue engine |
| `$battle` | 2416 | Battle side panel (equipment, items, repair) |
| `$dfct` | 3280 | Difficulty changer |
| `$persona` | 3340 | Persona/equip set changer |
### Page-Specific Modules
| Module | Line | Page |
|--------|------|------|
| `_ch` | 3820 | Character: EXP simulator, stats parsing |
| `_eq` | 3923 | Equipment: popups, charms, mage stats, equip code |
| `_ab` | 4097 | Abilities: slotbar parsing, tree parsing, ability simulator |
| `_tr` | 4468 | Training: queue planning, cost calculation, auto-start |
| `_it` | 4676 | Item Inventory: type coloring |
| `_se` | 4704 | Settings: preset save/load |
| `_is` | 4807 | Item Shop: type coloring |
| `_ss` | 4833 | Shrine: bulk offering, reward tracking, trophy system |
| `_mk` | 5374 | Market: price display, order checking, crystal pack |
| `_ml` | 5486 | Monster Lab: list, feeding, upgrades, PLC |
| `_mm` | 6870 | MoogleMail: compose UI, item/equip/credits attach |
| `_lt` | 8500 | Lottery: notification toggle, golden ticket confirm |
| `_ar` | 8560 | Arena/RoB: layout adjustment |
| `$armory` | 8611 | Equipment Shop: unified list, protect/bazaar filters, salvage calc |
| `_mo` | 9670 | Modify (single equip): upgrade cost display |
### Key Utility Functions
| Function | Line | Purpose |
|----------|------|---------|
| `$id` / `$qs` / `$qsa` / `$xpath` | 191-194 | DOM selectors |
| `$doc` | 195 | HTML string → Document |
| `$element` | 196 | Element builder with attributes, events, children |
| `$input` | 197 | Form input builder (text/checkbox/select/number) |
| `time_format` | 198 | ms → HH:MM:SS / HH:MM / MM:SS |
| `date_format` | 199 | Unix timestamp → YY-MM-DD HH:MM |
| `parse_count` | 200 | "1,234" → 1234 |
| `parse_price` | 201 | "10m"/"500k" → number |
| `split2` | 202 | "key:value" → ["key", "value"] |
| `scrollIntoView` | 203 | Scroll parent to show child |
| `confirm_event` | 204 | Add confirmation to onclick handlers |
| `toggle_button` | 205 | Toggle button text based on CSS class |
| `play_beep` | 206 | Web Audio API beep |
| `popup` | 207 | Modal overlay |
| `popup_text` | 208 | Modal with textarea |
| `get_message` | 209 | Parse server message box |
| `$equip.filter.test` | 1609 | Filter expression evaluator (&&, \|\|, !, $Quality+, $pab=, $prefix, $level) |
| `$equip.namecode` | 1696 | Forum BBcode name decorator |
| `$equip.parse.name` | 1300 | Name regex parser (quality, prefix, type, slot, suffix) |
| `$equip.parse.elem` | 1397 | DOM element → equipment object |
| `$equip.parse.dynjs` | 1361 | dynjs_equip data → equipment object |
---
## 15. MARKET INTEGRATION
### Price System (`$price`, Lines 1950–2171)
**Storage:** `hvut_prices` — object mapping item names to credit values
**Item Groups (Lines 1953-1971):**
- **Consumables:** Health/Mana/Spirit Draughts/Potions/Elixirs, Energy Drinks, Caffeinated Candy, Infusions, Scrolls, Flower Vases, Bubble-Gum
- **Materials:** Grade materials, Scraps, Energy Cells, Phazon, Shade Fragment, Repurposed Actuator, Defense Matrix Modulator, Bindings (33 types), Weapon/Staff/Armor Cores, Shards
- **Trophies:** All 12 trophies
- **Crystals:** All 12 crystal types
- **Figures:** All 27 figurine types
**Isekai Filtering (Line 1982-1989):**
- Removes: Last Elixir, Energy Drink, Caffeinated Candy, Bindings, Crystals, Figures
- These items don't exist on Isekai server
**Market Data Fetching (Line 2101-2149):**
```js
$price.parse_market(filter, doc)
```
- Parses the market item list table (`#market_itemlist table`)
- Extracts: item name, item ID, your stock, market bid, market ask, market stock
- Caches in `$price.market[name]` = `{ itemid, stock, bid, ask, market_stock }`
- Filter names: `co` (consumables), `ma` (materials), `tr` (trophies), `ar` (artifacts), `fi` (figures), `mo` (monster food)
**Market Price Update (Line 2125-2149):**
- `$price.update_market(filter, key, save)`: Fetches current market data, extracts prices for specified key (bid/ask)
- Fetches all filters at once if `filter` is empty
**Market Integration Points:**
1. **Market Page (`_mk`):** Shows HVUT prices in extra column, highlighting mismatched orders
2. **Item Price Editor:** `$price.edit()` opens popup with "Bid"/"Ask" buttons to fetch market prices
3. **Equipment Salvage Calc:** Uses material prices from `$price.get('Materials')` to value salvage
4. **Monster Lab Gift Summary:** Uses `$price.value()` to estimate gift credit value
5. **Monster Lab Upgrade Cost:** Uses crystal prices to show upgrade costs
6. **Modify Page:** Shows total upgrade cost using material prices
7. **Crystal Pack:** On Monster Food market page, calculates aggregate crystal pack bid/ask
**Price Editor Popup (Line 2045-2088):**
- Textarea with `name @ price` format
- **Save:** Validates and saves
- **Bid/Ask:** Fetches market prices for specified key, replaces values
- **Edit All Items:** Switches to full price list
**Default Prices (Line 1972-1976):**
- Peerless Weapon/Staff/Armor Cores: 500,000 credits
---
## ARCHITECTURE SUMMARY
### Module Dependencies
```
$config (storage, settings)
↓
$ajax (network, 300ms/4conn rate limit)
↓
$equip (equipment parsing/filtering) ← $item (inventory) → $price (market)
↓ ↓
$re (RE timer) $battle (side panel) $mail (MM send)
↓
Page modules (_ch, _eq, _ab, _tr, _it, _se, _is, _ss, _mk, _ml, _mm, _lt, _ar, $armory, _mo)
↓
_top (top bar) + _bottom (bottom bar) — always active, uses _player and specific modules
```
### Design Patterns
- **Singleton modules:** All `$xxx` and `_xxx` objects are const-declared singletons
- **Lazy initialization:** Most modules have `init()` called only when their page matches
- **AJAX queue:** Central `$ajax` manages concurrency (max 4) and rate limiting (300ms interval)
- **Filter DSL:** The `$equip.filter` system implements a custom boolean expression evaluator for equipment matching
- **CSS variables:** All theming uses CSS custom properties, making re-skinning trivial
- **Storage namespacing:** Persistent (`hvut_`) and Isekai (`hvuti_`) have separate storage namespaces
- **Migration system:** Automatic data migration when version numbers don't match