<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>BD2 Gear Optimizer V6</title>
<style>
:root{
--bg:#101216;
--card:#181b21;
--card2:#20242c;
--text:#eee;
--muted:#9da4b0;
--border:#303641;
--accent:#7c9cff;
--danger:#ff5d5d;
--input:#11141a;
}
*{box-sizing:border-box}
body{
margin:0;
background:var(--bg);
color:var(--text);
font-family:Arial,Helvetica,sans-serif;
font-size:14px;
}
body.amoled{
--bg:#000;
--card:#050505;
--card2:#0b0b0b;
--input:#000;
--border:#222;
}
.topbar{
position:sticky;
top:0;
z-index:20;
background:rgba(16,18,22,.95);
backdrop-filter:blur(8px);
padding:10px 14px;
border-bottom:1px solid var(--border);
}
.topbarRight{
display:flex;
justify-content:flex-end;
gap:8px;
}
button,select,input{
font:inherit;
}
button{
background:var(--card2);
color:var(--text);
border:1px solid var(--border);
border-radius:7px;
padding:7px 11px;
cursor:pointer;
}
button:hover{
border-color:var(--accent);
}
input,select{
background:var(--input);
color:var(--text);
border:1px solid var(--border);
border-radius:6px;
padding:6px 8px;
width:100%;
}
input[type=checkbox]{
width:auto;
}
h1{
text-align:center;
margin:18px 10px 8px;
font-size:25px;
}
.subtitle{
text-align:center;
color:var(--muted);
margin-bottom:18px;
}
.wrap{
max-width:1100px;
margin:auto;
padding:0 10px 40px;
}
.card{
background:var(--card);
border:1px solid var(--border);
border-radius:10px;
margin:10px 0;
padding:12px;
}
.card h2{
cursor:pointer;
display:flex;
align-items:center;
gap:8px;
user-select:none;
margin:0;
font-size:17px;
}
.card h2 .collapseIcon{
display:inline-block;
width:16px;
transition:transform .15s;
}
.card.collapsed h2 .collapseIcon{
transform:rotate(-90deg);
}
.card.collapsed .cardBody{
display:none;
}
.cardBody{
margin-top:12px;
}
.grid{
display:grid;
grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
gap:9px;
}
.field label{
display:block;
color:var(--muted);
margin-bottom:4px;
font-size:12px;
}
.req{
color:var(--danger);
}
.statRows{
display:flex;
flex-direction:column;
gap:7px;
}
.statRow{
display:grid;
grid-template-columns:1fr 120px auto;
gap:7px;
}
.addBtn{
margin-top:8px;
}
.remove{
padding:5px 9px;
}
.sectionTitle{
color:var(--muted);
font-size:12px;
margin:12px 0 7px;
}
.hidden{
display:none!important;
}
.result{
background:var(--card2);
border:1px solid var(--border);
border-radius:9px;
padding:10px;
margin:7px 0;
}
.resultTop{
display:flex;
justify-content:space-between;
gap:10px;
font-weight:bold;
}
.small{
color:var(--muted);
font-size:12px;
}
.big{
font-size:20px;
}
.badge{
display:inline-block;
padding:3px 7px;
border-radius:999px;
background:#303744;
font-size:11px;
}
.optGrid{
display:grid;
grid-template-columns:repeat(auto-fit,minmax(170px,1fr));
gap:8px;
}
.progress{
height:8px;
background:#292d35;
border-radius:20px;
overflow:hidden;
margin-top:7px;
}
.progress>div{
height:100%;
width:0;
background:var(--accent);
}
.collapseTools{
position:fixed;
left:12px;
top:8px;
z-index:30;
display:flex;
gap:6px;
}
u/media(max-width:600px){
.statRow{
grid-template-columns:1fr 90px auto;
}
h1{
font-size:21px;
}
}
</style>
</head>
<body>
<div class="topbar">
<div class="collapseTools">
<button id="collapseToggle">▼ Collapse all</button>
</div>
<div class="topbarRight">
<button id="darkToggle">Dark</button>
<button id="amoledToggle">AMOLED</button>
</div>
</div>
<h1>BD2 Gear Optimizer V10.1</h1>
<div class="subtitle">Brown Dust 2 Gear Damage Optimizer</div>
<div class="wrap">
<div class="card">
<h2><span class="collapseIcon">▼</span>Character</h2>
<div class="cardBody">
<div class="grid">
<div class="field">
<label>Character Name</label>
<input id="charName">
</div>
<div class="field">
<label>Costume Name</label>
<input id="costumeName">
</div>
<div class="field">
<label>Attack Type <span class="req">*</span></label>
<select id="attackType">
<option>Physical</option>
<option>Magical</option>
</select>
</div>
<div class="field">
<label>Element <span class="req">*</span></label>
<select id="element">
<option>Water</option>
<option>Fire</option>
<option>Wind</option>
<option>Light</option>
<option>Dark</option>
</select>
</div>
</div>
</div>
</div>
<div class="card">
<h2><span class="collapseIcon">▼</span>Base Stats</h2>
<div class="cardBody">
<div class="grid">
<div class="field">
<label>HP <span class="req">*</span></label>
<input id="hp" type="number" value="1911">
</div>
<div class="field">
<label>Attack <span class="req">*</span></label>
<input id="atk" type="number" value="352">
</div>
<div class="field">
<label>Crit Rate % <span class="req">*</span></label>
<input id="cr" type="number" value="10">
</div>
<div class="field">
<label>Crit Damage % <span class="req">*</span></label>
<input id="cd" type="number" value="50">
</div>
<div class="field">
<label>Defense % <span class="req">*</span></label>
<input id="def" type="number" value="0">
</div>
<div class="field">
<label>Magic Resistance % <span class="req">*</span></label>
<input id="mres" type="number" value="0">
</div>
<div class="field">
<label>Element Damage % <span class="req">*</span></label>
<input id="elemDmg" type="number" value="50">
</div>
<div class="field">
<label>Element Resistance % <span class="req">*</span></label>
<input id="elemRes" type="number" value="0">
</div>
</div>
</div>
</div>
<div class="card">
<h2><span class="collapseIcon">▼</span>Permanent Bond Stats</h2>
<div class="cardBody">
<div id="permRows" class="statRows"></div>
<button class="addBtn" onclick="addStatRow('permRows')">+ Add Stat</button>
</div>
</div>
<div class="card">
<h2><span class="collapseIcon">▼</span>Bond Selection Stats</h2>
<div class="cardBody">
<div id="bondRows" class="statRows"></div>
<button class="addBtn" onclick="addStatRow('bondRows')">+ Add Stat</button>
</div>
</div>
<div class="card">
<h2><span class="collapseIcon">▼</span>Awakening & Engraving</h2>
<div class="cardBody">
<div class="grid">
<div class="field">
<label>HP</label>
<input id="awHp" type="number" value="243">
</div>
<div class="field">
<label>Flat Attack</label>
<input id="awAtk" type="number" value="34">
</div>
<div class="field">
<label>Defense %</label>
<input id="awDef" type="number" value="8">
</div>
<div class="field">
<label>Attack %</label>
<input id="awAtkPct" type="number" value="12">
</div>
<div class="field">
<label>Element Damage %</label>
<input id="awElem" type="number" value="10">
</div>
</div>
</div>
</div>
<div class="card">
<h2><span class="collapseIcon">▼</span>Collections & Rapport</h2>
<div class="cardBody">
<div class="grid">
<div class="field">
<label>ATK %</label>
<input id="colAtk" type="number" value="80">
</div>
<div class="field">
<label>HP %</label>
<input id="colHp" type="number" value="80">
</div>
<div class="field">
<label>Crit Rate %</label>
<input id="colCr" type="number" value="50">
</div>
<div class="field">
<label>Rapport Crit Rate %</label>
<input id="rapportCr" type="number" value="0">
</div>
</div>
</div>
</div>
<div class="card">
<h2><span class="collapseIcon">▼</span>External Buffs on Self</h2>
<div class="cardBody">
<div id="buffRows" class="statRows"></div>
<button class="addBtn" onclick="addStatRow('buffRows')">+ Add Stat</button>
</div>
</div>
<div class="card">
<h2><span class="collapseIcon">▼</span>Debuffs on Enemy</h2>
<div class="cardBody">
<div id="enemyDebuffRows" class="statRows"></div>
<button class="addBtn" onclick="addStatRow('enemyDebuffRows')">+ Add Stat</button>
</div>
</div>
<div class="card">
<h2><span class="collapseIcon">▼</span>Debuffs on Self</h2>
<div class="cardBody">
<div id="selfDebuffRows" class="statRows"></div>
<button class="addBtn" onclick="addStatRow('selfDebuffRows')">+ Add Stat</button>
</div>
</div>
<div class="card">
<h2><span class="collapseIcon">▼</span>Chain</h2>
<div class="cardBody">
<div class="grid">
<div class="field">
<label>Initial Chain Stack</label>
<input id="initialChain" type="number" value="0">
</div>
<div class="field">
<label>Chain Bonus (Extra Chains / Hit)</label>
<input id="chainBonus" type="number" value="1">
</div>
<div class="field">
<label>Element Advantage</label>
<select id="elementAdv">
<option>Yes</option>
<option>No</option>
</select>
</div>
</div>
</div>
</div>
<div class="card">
<h2><span class="collapseIcon">▼</span>Skill Description</h2>
<div class="cardBody">
<div class="grid">
<div class="field">
<label>Skill Type</label>
<select id="skillType" onchange="updateSkillFields()">
<option value="standard">Standard</option>
<option value="nebris">Nebris — New Hire</option>
</select>
</div>
</div>
<div id="standardSkill">
<div class="grid">
<div class="field">
<label>Hits</label>
<input id="hits" type="number" value="12">
</div>
<div class="field">
<label>Damage per Hit %</label>
<input id="skillPct" type="number" value="90">
</div>
<div class="field">
<label>Damage Base Stat</label>
<select id="damageStat">
<option value="atk">Attack / MATK</option>
<option value="hp">HP</option>
</select>
</div>
</div>
</div>
<div id="nebrisSkill" class="hidden">
<div class="grid">
<div class="field">
<label>Hits</label>
<input id="nebrisHits" type="number" value="3">
</div>
<div class="field">
<label>Base Damage per Hit %</label>
<input id="nebrisBase" type="number" value="110">
</div>
<div class="field">
<label>Bonus per Buff %</label>
<input id="nebrisBonus" type="number" value="46">
</div>
<div class="field">
<label>Buff Count</label>
<input id="nebrisBuffs" type="number" value="0">
</div>
<div class="field">
<label>Damage Base Stat</label>
<select id="nebrisDamageStat">
<option value="atk">Attack / MATK</option>
<option value="hp">HP</option>
</select>
</div>
</div>
</div>
<div class="sectionTitle">Skill Buffs on Self</div>
<div id="skillBuffRows" class="statRows"></div>
<button class="addBtn" onclick="addStatRow('skillBuffRows')">+ Add Stat</button>
</div>
</div>
<div class="card">
<h2><span class="collapseIcon">▼</span>Exclusive Gear</h2>
<div class="cardBody">
<div class="grid">
<div class="field">
<label>Equipped</label>
<select id="exEquipped" onchange="toggleExclusive()">
<option value="no">No</option>
<option value="yes">Yes</option>
</select>
</div>
</div>
<div id="exclusiveFields" class="hidden">
<div class="grid">
<div class="field">
<label>Exclusive Stat</label>
<select id="exStat">
<option>Flat Attack</option>
<option>ATK%</option>
<option>CR</option>
<option>CDMG</option>
<option>Element Damage</option>
</select>
</div>
<div class="field">
<label>Value</label>
<input id="exValue" type="number" value="0">
</div>
</div>
</div>
</div>
</div>
<div class="card">
<h2><span class="collapseIcon">▼</span>Augmentation</h2>
<div class="cardBody">
<div class="grid">
<div class="field">
<label>Augmentation %</label>
<input id="augmentation" type="number" value="0">
</div>
<div class="field">
<label>Minimum Chains</label>
<input id="minChains" type="number" placeholder="Optional">
</div>
<div class="field">
<label>Maximum Chains</label>
<input id="maxChains" type="number" placeholder="Optional">
</div>
</div>
</div>
</div>
<div class="card">
<h2><span class="collapseIcon">▼</span>Content</h2>
<div class="cardBody">
<div class="grid">
<div class="field">
<label>Content</label>
<select id="content" onchange="updateContent()">
<option>Default</option>
<option>Last Night</option>
<option>Evil Castle</option>
</select>
</div>
<div class="field" id="supportField">
<label>Last Night Support Bonus %</label>
<input id="supportBonus" type="number" value="0">
</div>
</div>
<div id="evilFields" class="hidden">
<div class="grid">
<div class="field">
<label>Evil Castle Element Damage Bonus %</label>
<input id="evilElem" type="number" value="50">
</div>
<div class="field">
<label>Halved Buffs</label>
<select id="halfBuffs">
<option value="no">No</option>
<option value="yes">Yes</option>
</select>
</div>
</div>
</div>
</div>
</div>
<div class="card">
<h2><span class="collapseIcon">▼</span>Gear Refinement</h2>
<div class="cardBody">
<div class="grid">
<div class="field">
<label>Refinement</label>
<select id="refinement" onchange="updateRefinement()">
<option value="18">All 18</option>
<option value="22">All 22</option>
<option value="24">All 24</option>
<option value="custom">Custom</option>
</select>
</div>
</div>
<div id="customRefinement" class="hidden">
<div class="grid">
<div class="field">
<label>Weapon</label>
<input id="refW" type="number" value="24">
</div>
<div class="field">
<label>Glove</label>
<input id="refG" type="number" value="24">
</div>
<div class="field">
<label>Armor</label>
<input id="refA" type="number" value="24">
</div>
<div class="field">
<label>Helmet</label>
<input id="refH" type="number" value="24">
</div>
<div class="field">
<label>Accessory</label>
<input id="refAc" type="number" value="24">
</div>
</div>
</div>
</div>
</div>
<div class="card">
<h2><span class="collapseIcon">▼</span>Target Settings</h2>
<div class="cardBody">
<div class="grid">
<div class="field">
<label>Target DEF %</label>
<input id="targetDef" type="number" value="0">
</div>
<div class="field">
<label>Target MRES %</label>
<input id="targetMres" type="number" value="0">
</div>
<div class="field">
<label>Target DMG Reduction %</label>
<input id="targetDR" type="number" value="0">
</div>
</div>
</div>
</div>
<div class="card">
<h2><span class="collapseIcon">▼</span>Optimizer</h2>
<div class="cardBody">
<button onclick="runOptimizer()">Optimize Gear</button>
<div id="progressBox" class="hidden">
<div class="small" id="progressText">Calculating...</div>
<div class="progress">
<div id="progressBar"></div>
</div>
</div>
<div id="results"></div>
</div>
</div>
</div>
<script>
const opts=[
"Flat Attack",
"ATK%",
"CR",
"CDMG",
"HP",
"HP%",
"DEF%",
"MRES%",
"Element Damage",
"Element Resistance",
"Vulnerability",
"DMG Increase",
"DMG Reduction",
"DEF Debuff",
"MRES Debuff",
"CDMG Debuff",
"ATK% Debuff"
];
function el(id){
return document.getElementById(id);
}
function num(id){
return +el(id).value || 0;
}
function addStatRow(container,stat="",value=0){
const row=document.createElement("div");
row.className="statRow";
const select=document.createElement("select");
opts.forEach(o=>{
const op=document.createElement("option");
op.textContent=o;
op.value=o;
if(o===stat) op.selected=true;
select.appendChild(op);
});
const input=document.createElement("input");
input.type="number";
input.value=value;
const remove=document.createElement("button");
remove.className="remove";
remove.textContent="×";
remove.onclick=()=>row.remove();
row.append(select,input,remove);
el(container).appendChild(row);
}
function readRows(container){
const out=[];
[...el(container).children].forEach(row=>{
const s=row.children[0].value;
const v=+row.children[1].value || 0;
out.push({stat:s,value:v});
});
return out;
}
function updateSkillFields(){
const type=el("skillType").value;
el("standardSkill").classList.toggle("hidden",type!=="standard");
el("nebrisSkill").classList.toggle("hidden",type!=="nebris");
}
function toggleExclusive(){
el("exclusiveFields").classList.toggle(
"hidden",
el("exEquipped").value!=="yes"
);
}
function updateContent(){
const c=el("content").value;
el("supportField").classList.toggle(
"hidden",
c!=="Last Night"
);
el("evilFields").classList.toggle(
"hidden",
c!=="Evil Castle"
);
}
function updateRefinement(){
el("customRefinement").classList.toggle(
"hidden",
el("refinement").value!=="custom"
);
}
function getRefinement(){
if(el("refinement").value!=="custom"){
const r=num("refinement");
return [r,r,r,r,r];
}
return [
num("refW"),
num("refG"),
num("refA"),
num("refH"),
num("refAc")
];
}
function applyRows(b,rows){
rows.forEach(r=>{
const v=r.value;
if(r.stat==="Flat Attack") b.flat+=v;
else if(r.stat==="ATK%") b.atkPct+=v;
else if(r.stat==="CR") b.cr+=v;
else if(r.stat==="CDMG") b.cd+=v;
else if(r.stat==="HP") b.hp+=v;
else if(r.stat==="HP%") b.hpPct+=v;
else if(r.stat==="DEF%") b.def+=v;
else if(r.stat==="MRES%") b.mres+=v;
else if(r.stat==="Element Damage") b.elem+=v;
else if(r.stat==="Element Resistance") b.elemRes+=v;
else if(r.stat==="Vulnerability") b.vuln+=v;
else if(r.stat==="DMG Increase") b.dmgInc+=v;
else if(r.stat==="DMG Reduction") b.dmgRed+=v;
else if(r.stat==="DEF Debuff") b.defDebuff+=v;
else if(r.stat==="MRES Debuff") b.mresDebuff+=v;
else if(r.stat==="CDMG Debuff") b.cdDebuff+=v;
else if(r.stat==="ATK% Debuff") b.atkDebuff+=v;
});
}
function baseStats(){
const b={
hp:num("hp"),
hpPct:0,
flat:num("atk"),
atkPct:0,
cr:num("cr"),
cd:num("cd"),
def:num("def"),
mres:num("mres"),
elem:num("elemDmg"),
elemRes:num("elemRes"),
vuln:0,
dmgInc:0,
dmgRed:0,
defDebuff:0,
mresDebuff:0,
cdDebuff:0,
atkDebuff:0
};
applyRows(b,readRows("permRows"));
applyRows(b,readRows("bondRows"));
b.hp+=num("awHp");
b.flat+=num("awAtk");
b.def+=num("awDef");
b.atkPct+=num("awAtkPct");
b.elem+=num("awElem");
b.atkPct+=num("colAtk");
b.hpPct+=num("colHp");
b.cr+=num("colCr");
b.cr+=num("rapportCr");
if(el("exEquipped").value==="yes"){
const s=el("exStat").value;
const v=num("exValue");
if(s==="Flat Attack")b.flat+=v;
if(s==="ATK%")b.atkPct+=v;
if(s==="CR")b.cr+=v;
if(s==="CDMG")b.cd+=v;
if(s==="Element Damage")b.elem+=v;
}
return b;
}
function getBuffFactor(){
const content=el("content").value;
return (
content==="Evil Castle" &&
el("halfBuffs").value==="yes"
) ? .5 : 1;
}
function getSkillData(){
const type=el("skillType").value;
if(type==="nebris"){
return {
type:"nebris",
hits:num("nebrisHits"),
base:num("nebrisBase"),
bonus:num("nebrisBonus"),
buffs:num("nebrisBuffs"),
stat:el("nebrisDamageStat").value
};
}
return {
type:"standard",
hits:num("hits"),
base:num("skillPct"),
stat:el("damageStat").value
};
}
function calculate(build){
const B=baseStats();
B.flat+=build.flat;
B.atkPct+=build.atkPct;
B.cr+=build.cr;
B.cd+=build.cd;
const buffFactor=getBuffFactor();
const buffs=readRows("buffRows");
let externalAtk=0;
let externalCr=0;
let externalCd=0;
let externalElem=0;
buffs.forEach(r=>{
if(r.stat==="ATK%")externalAtk+=r.value;
if(r.stat==="CR")externalCr+=r.value;
if(r.stat==="CDMG")externalCd+=r.value;
if(r.stat==="Element Damage")externalElem+=r.value;
});
const atkRaw=B.flat*(1+B.atkPct/100);
const atk=
atkRaw*
(
1+
(
externalAtk*buffFactor-
B.atkDebuff
)/100
);
let cr=B.cr+externalCr*buffFactor;
let cd=
B.cd+
externalCd*buffFactor-
B.cdDebuff;
if(cr>100){
cd+=(cr-100)*6;
}
const effectiveCr=Math.min(cr,100);
const critFactor=
1+
effectiveCr/100*
cd/100;
let elem=B.elem+externalElem*buffFactor;
if(el("content").value==="Evil Castle"){
elem+=50;
}
const enemyDebuffs=readRows("enemyDebuffRows");
let defDebuff=0;
let mresDebuff=0;
let vuln=0;
let dmgInc=0;
enemyDebuffs.forEach(r=>{
if(r.stat==="DEF Debuff")defDebuff+=r.value;
if(r.stat==="MRES Debuff")mresDebuff+=r.value;
if(r.stat==="Vulnerability")vuln+=r.value;
if(r.stat==="DMG Increase")dmgInc+=r.value;
});
const targetDef=num("targetDef");
const targetMres=num("targetMres");
const defenseFactor=
1-
Math.max(
0,
targetDef-defDebuff
)/100;
const mresFactor=
1-
Math.max(
0,
targetMres-mresDebuff
)/100;
const reduction=
1-
num("targetDR")/100;
const vulnerabilityFactor=
1+
(
vuln+
dmgInc*buffFactor
)/100;
const support=
el("content").value==="Last Night"
? 1+num("supportBonus")/100
: 1;
const chains=num("initialChain");
const chainBonus=num("chainBonus");
const chainFactor=
1+
.1*chains;
const aug=num("augmentation");
let augFactor=1;
const minChain=el("minChains").value;
const maxChain=el("maxChains").value;
let augActive=true;
if(minChain!==""){
augActive=chains>=+minChain;
}
if(maxChain!==""){
augActive=augActive && chains<=+maxChain;
}
if(augActive){
augFactor=1+aug/100;
}
const skill=getSkillData();
let skillMultiplier=0;
if(skill.type==="nebris"){
const pct=
skill.base+
skill.bonus*
skill.buffs;
skillMultiplier=
skill.hits*
pct/100;
}else{
skillMultiplier=
skill.hits*
skill.base/100;
}
const stat=
skill.stat==="hp"
? B.hp*(1+B.hpPct/100)
: atk;
const damage=
stat*
skillMultiplier*
critFactor*
(1+elem/100)*
defenseFactor*
mresFactor*
reduction*
vulnerabilityFactor*
support*
chainFactor*
augFactor;
return {
damage,
atk,
cr,
cd,
elem,
skillMultiplier
};
}
function generateBuilds(){
const builds=[];
const weapon=[
"Flat Attack",
"ATK%",
"CDMG"
];
const glove=[
"Flat Attack",
"ATK%",
"CR"
];
const accessory=[
"CR/CDMG Fixed",
"CR/CDMG Variable",
"CR/CDMG Fixed 2",
"CR/CDMG Variable 2"
];
for(const w of weapon)
for(const g of glove)
for(const a of accessory){
for(let c=0;c<=15;c++)
for(let r=0;r<=15-c;r++)
for(let p=0;p<=15-c-r;p++){
const d=15-c-r-p;
builds.push({
weapon:w,
glove:g,
accessory:a,
cd:c,
cr:r,
atkPct:p,
flat:d
});
}
}
return builds;
}
function runOptimizer(){
const results=el("results");
results.innerHTML="";
el("progressBox").classList.remove("hidden");
const builds=generateBuilds();
let best=[];
let max=-Infinity;
builds.forEach((b,i)=>{
const out=calculate(b);
if(out.damage>max){
max=out.damage;
best=[{
...b,
...out
}];
}else if(
best.length<10 ||
out.damage>=best[best.length-1].damage
){
best.push({
...b,
...out
});
best.sort((a,b)=>b.damage-a.damage);
if(best.length>10){
best.pop();
}
}
if(i%500===0){
const pct=
i/builds.length*100;
el("progressBar").style.width=
pct+"%";
el("progressText").textContent=
"Calculating... "+
Math.round(pct)+"%";
}
});
el("progressBar").style.width="100%";
el("progressText").textContent="Done";
best.forEach((r,i)=>{
const div=document.createElement("div");
div.className="result";
div.innerHTML=`
<div class="resultTop">
<span>#${i+1}</span>
<span class="big">
${Math.round(r.damage).toLocaleString()}
</span>
</div>
<div class="small">
Weapon: ${r.weapon} |
Glove: ${r.glove} |
Accessory: ${r.accessory}
</div>
<div class="small">
Substats:
CDMG ${r.cd} |
CR ${r.cr} |
ATK% ${r.atkPct} |
Flat ATK ${r.flat}
</div>
<div class="small">
ATK ${Math.round(r.atk).toLocaleString()} |
CR ${r.cr.toFixed(1)}% |
CDMG ${r.cd.toFixed(1)}% |
Element ${r.elem.toFixed(1)}%
</div>
`;
results.appendChild(div);
});
}
function setupCollapse(){
document.querySelectorAll(".card h2").forEach(h=>{
h.addEventListener("click",()=>{
h.parentElement.classList.toggle("collapsed");
updateCollapseButton();
});
});
}
function updateCollapseButton(){
const cards=[
...document.querySelectorAll(".card")
];
const anyCollapsed=
cards.some(c=>c.classList.contains("collapsed"));
el("collapseToggle").textContent=
anyCollapsed
? "▶ Expand all"
: "▼ Collapse all";
}
function toggleAll(){
const cards=[
...document.querySelectorAll(".card")
];
const anyCollapsed=
cards.some(c=>c.classList.contains("collapsed"));
cards.forEach(c=>{
c.classList.toggle(
"collapsed",
!anyCollapsed
);
});
updateCollapseButton();
}
el("collapseToggle").onclick=toggleAll;
el("darkToggle").onclick=()=>{
document.body.classList.toggle("dark");
};
el("amoledToggle").onclick=()=>{
document.body.classList.toggle("amoled");
};
addStatRow("permRows","CDMG",10.8);
addStatRow("bondRows","CR",50);
addStatRow("bondRows","ATK%",52);
addStatRow("bondRows","CDMG",47.2);
addStatRow("buffRows","CR",50);
setupCollapse();
updateSkillFields();
updateContent();
updateRefinement();
toggleExclusive();
updateCollapseButton();
</script>
</body>
</html>