MediaWiki:HeroPlanner.js: Difference between revisions
From Heroes of Might and Magic: Olden Era Official Wiki
No edit summary |
No edit summary |
||
| Line 357: | Line 357: | ||
var h2 = u3.bind({ k: 1 }); | var h2 = u3.bind({ k: 1 }); | ||
// | // node_modules/preact/hooks/dist/hooks.module.js | ||
function | var t3; | ||
var r2; | |||
var u4; | |||
var i3; | |||
var f3 = []; | |||
var c3 = l; | |||
var e3 = c3.__b; | |||
var a3 = c3.__r; | |||
var v2 = c3.diffed; | |||
var l3 = c3.__c; | |||
var m2 = c3.unmount; | |||
var p3 = c3.__; | |||
function j2() { | |||
for (var n3; n3 = f3.shift(); ) { | |||
var t4 = n3.__H; | |||
if (n3.__P && t4) try { | |||
t4.__h.some(z2), t4.__h.some(B2), t4.__h = []; | |||
} catch (r3) { | |||
t4.__h = [], c3.__e(r3, n3.__v); | |||
} | |||
} | |||
} | } | ||
c3.__b = function(n3) { | |||
r2 = null, e3 && e3(n3); | |||
}, c3.__ = function(n3, t4) { | |||
n3 && t4.__k && t4.__k.__m && (n3.__m = t4.__k.__m), p3 && p3(n3, t4); | |||
}, c3.__r = function(n3) { | |||
a3 && a3(n3), t3 = 0; | |||
var i4 = (r2 = n3.__c).__H; | |||
i4 && (u4 === r2 ? (i4.__h = [], r2.__h = [], i4.__.some(function(n4) { | |||
n4.__N && (n4.__ = n4.__N), n4.u = n4.__N = void 0; | |||
})) : (i4.__h.some(z2), i4.__h.some(B2), i4.__h = [], t3 = 0)), u4 = r2; | |||
}, c3.diffed = function(n3) { | |||
v2 && v2(n3); | |||
var t4 = n3.__c; | |||
t4 && t4.__H && (t4.__H.__h.length && (1 !== f3.push(t4) && i3 === c3.requestAnimationFrame || ((i3 = c3.requestAnimationFrame) || w2)(j2)), t4.__H.__.some(function(n4) { | |||
n4.u && (n4.__H = n4.u, n4.u = void 0); | |||
})), u4 = r2 = null; | |||
}, c3.__c = function(n3, t4) { | |||
t4.some(function(n4) { | |||
try { | |||
n4.__h.some(z2), n4.__h = n4.__h.filter(function(n5) { | |||
return !n5.__ || B2(n5); | |||
}); | |||
} catch (r3) { | |||
t4.some(function(n5) { | |||
n5.__h && (n5.__h = []); | |||
}), t4 = [], c3.__e(r3, n4.__v); | |||
} | |||
}), l3 && l3(n3, t4); | |||
}, c3.unmount = function(n3) { | |||
m2 && m2(n3); | |||
var t4, r3 = n3.__c; | |||
r3 && r3.__H && (r3.__H.__.some(function(n4) { | |||
try { | |||
z2(n4); | |||
} catch (n5) { | |||
t4 = n5; | |||
} | |||
}), r3.__H = void 0, t4 && c3.__e(t4, r3.__v)); | |||
}; | }; | ||
var | var k2 = "function" == typeof requestAnimationFrame; | ||
function w2(n3) { | |||
var t4, r3 = function() { | |||
clearTimeout(u5), k2 && cancelAnimationFrame(t4), setTimeout(n3); | |||
}, u5 = setTimeout(r3, 35); | |||
k2 && (t4 = requestAnimationFrame(r3)); | |||
} | |||
function z2(n3) { | |||
var t4 = r2, u5 = n3.__c; | |||
"function" == typeof u5 && (n3.__c = void 0, u5()), r2 = t4; | |||
} | |||
}; | function B2(n3) { | ||
var t4 = r2; | |||
n3.__c = n3.__(), r2 = t4; | |||
} | |||
// node_modules/preact/compat/dist/compat.module.js | |||
function g3(n3, t4) { | |||
for (var e4 in t4) n3[e4] = t4[e4]; | |||
return n3; | |||
} | |||
function E2(n3, t4) { | |||
for (var e4 in n3) if ("__source" !== e4 && !(e4 in t4)) return true; | |||
for (var r3 in t4) if ("__source" !== r3 && n3[r3] !== t4[r3]) return true; | |||
return false; | |||
} | |||
function M2(n3, t4) { | |||
this.props = n3, this.context = t4; | |||
} | |||
} | (M2.prototype = new C()).isPureReactComponent = true, M2.prototype.shouldComponentUpdate = function(n3, t4) { | ||
return E2(this.props, n3) || E2(this.state, t4); | |||
}; | |||
var T3 = l.__b; | |||
l.__b = function(n3) { | |||
n3.type && n3.type.__f && n3.ref && (n3.props.ref = n3.ref, n3.ref = null), T3 && T3(n3); | |||
}; | }; | ||
var | var A3 = "undefined" != typeof Symbol && Symbol.for && /* @__PURE__ */ Symbol.for("react.forward_ref") || 3911; | ||
var O2 = l.__e; | |||
l.__e = function(n3, t4, e4, r3) { | |||
if (n3.then) { | |||
for (var u5, o3 = t4; o3 = o3.__; ) if ((u5 = o3.__c) && u5.__c) return null == t4.__e && (t4.__e = e4.__e, t4.__k = e4.__k || []), u5.__c(n3, t4); | |||
var | |||
var t4 = | |||
} | } | ||
O2(n3, t4, e4, r3); | |||
}; | |||
var U2 = l.unmount; | |||
function V2(n3, t4, e4) { | |||
return n3 && (n3.__c && n3.__c.__H && (n3.__c.__H.__.forEach(function(n4) { | |||
"function" == typeof n4.__c && n4.__c(); | |||
}), n3.__c.__H = null), null != (n3 = g3({}, n3)).__c && (n3.__c.__P === e4 && (n3.__c.__P = t4), n3.__c.__e = true, n3.__c = null), n3.__k = n3.__k && n3.__k.map(function(n4) { | |||
return V2(n4, t4, e4); | |||
})), n3; | |||
} | } | ||
function W2(n3, t4, e4) { | |||
return n3 && e4 && (n3.__v = null, n3.__k = n3.__k && n3.__k.map(function(n4) { | |||
return W2(n4, t4, e4); | |||
}), n3.__c && n3.__c.__P === t4 && (n3.__e && e4.appendChild(n3.__e), n3.__c.__e = true, n3.__c.__P = e4)), n3; | |||
} | |||
function P3() { | |||
this.__u = 0, this.o = null, this.__b = null; | |||
} | |||
function j3(n3) { | |||
var t4 = n3.__ && n3.__.__c; | |||
} | return t4 && t4.__a && t4.__a(n3); | ||
} | |||
function B3() { | |||
this.i = null, this.l = null; | |||
} | |||
l.unmount = function(n3) { | |||
var t4 = n3.__c; | var t4 = n3.__c; | ||
t4 && t4. | t4 && (t4.__z = true), t4 && t4.__R && t4.__R(), t4 && 32 & n3.__u && (n3.type = null), U2 && U2(n3); | ||
}, (P3.prototype = new C()).__c = function(n3, t4) { | |||
} | var e4 = t4.__c, r3 = this; | ||
null == r3.o && (r3.o = []), r3.o.push(e4); | |||
var u5 = j3(r3.__v), o3 = false, i4 = function() { | |||
o3 || r3.__z || (o3 = true, e4.__R = null, u5 ? u5(f4) : f4()); | |||
}; | |||
e4.__R = i4; | |||
} | var l4 = e4.__P; | ||
e4.__P = null; | |||
var f4 = function() { | |||
if (!--r3.__u) { | |||
if (r3.state.__a) { | |||
var n4 = r3.state.__a; | |||
r3.__v.__k[0] = W2(n4, n4.__c.__P, n4.__c.__O); | |||
} | |||
var t5; | |||
for (r3.setState({ __a: r3.__b = null }); t5 = r3.o.pop(); ) t5.__P = l4, t5.forceUpdate(); | |||
} | } | ||
}), | }; | ||
}, | r3.__u++ || 32 & t4.__u || r3.setState({ __a: r3.__b = r3.__v.__k[0] }), n3.then(i4, i4); | ||
}, P3.prototype.componentWillUnmount = function() { | |||
this.o = []; | |||
}, P3.prototype.render = function(n3, e4) { | |||
if (this.__b) { | |||
if (this.__v.__k) { | |||
var r3 = document.createElement("div"), o3 = this.__v.__k[0].__c; | |||
this.__v.__k[0] = V2(this.__b, r3, o3.__O = o3.__P); | |||
} | } | ||
} | this.__b = null; | ||
} | |||
var i4 = e4.__a && k(S, null, n3.fallback); | |||
return i4 && (i4.__u &= -33), [k(S, null, e4.__a ? null : n3.children), i4]; | |||
}; | }; | ||
var | var H2 = function(n3, t4, e4) { | ||
if (++e4[1] === e4[0] && n3.l.delete(t4), n3.props.revealOrder && ("t" !== n3.props.revealOrder[0] || !n3.l.size)) for (e4 = n3.i; e4; ) { | |||
for (; e4.length > 3; ) e4.pop()(); | |||
if (e4[1] < e4[0]) break; | |||
} | n3.i = e4 = e4[2]; | ||
} | |||
}; | |||
function Z(n3) { | |||
return this.getChildContext = function() { | |||
return n3.context; | |||
}, n3.children; | |||
} | } | ||
function | function Y(n3) { | ||
var | var e4 = this, r3 = n3.h; | ||
if (e4.componentWillUnmount = function() { | |||
R(null, e4.v), e4.v = null, e4.h = null; | |||
}, e4.h && e4.h !== r3 && e4.componentWillUnmount(), !e4.v) { | |||
for (var u5 = e4.__v; null !== u5 && !u5.__m && null !== u5.__; ) u5 = u5.__; | |||
e4.h = r3, e4.v = { nodeType: 1, parentNode: r3, childNodes: [], __k: { __m: u5.__m }, contains: function() { | |||
return true; | |||
}, namespaceURI: r3.namespaceURI, insertBefore: function(n4, t4) { | |||
this.childNodes.push(n4), e4.h.insertBefore(n4, t4); | |||
}, removeChild: function(n4) { | |||
this.childNodes.splice(this.childNodes.indexOf(n4) >>> 1, 1), e4.h.removeChild(n4); | |||
} }; | |||
} | |||
R(k(Z, { context: e4.context }, n3.__v), e4.v); | |||
} | } | ||
function | function $2(n3, e4) { | ||
var | var r3 = k(Y, { __v: n3, h: e4 }); | ||
return r3.containerInfo = e4, r3; | |||
} | } | ||
(B3.prototype = new C()).__a = function(n3) { | |||
var t4 = this, e4 = j3(t4.__v), r3 = t4.l.get(n3); | |||
return r3[0]++, function(u5) { | |||
var o3 = function() { | |||
t4.props.revealOrder ? (r3.push(u5), H2(t4, n3, r3)) : u5(); | |||
} | }; | ||
e4 ? e4(o3) : o3(); | |||
}; | |||
for (var | }, B3.prototype.render = function(n3) { | ||
return | this.i = null, this.l = /* @__PURE__ */ new Map(); | ||
var t4 = F(n3.children); | |||
n3.revealOrder && "b" === n3.revealOrder[0] && t4.reverse(); | |||
for (var e4 = t4.length; e4--; ) this.l.set(t4[e4], this.i = [1, 0, this.i]); | |||
} | return n3.children; | ||
}, B3.prototype.componentDidUpdate = B3.prototype.componentDidMount = function() { | |||
var n3 = this; | |||
this.l.forEach(function(t4, e4) { | |||
H2(n3, e4, t4); | |||
}); | |||
}; | }; | ||
var | var q3 = "undefined" != typeof Symbol && Symbol.for && /* @__PURE__ */ Symbol.for("react.element") || 60103; | ||
var G2 = /^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|dominant|fill|flood|font|glyph(?!R)|horiz|image(!S)|letter|lighting|marker(?!H|W|U)|overline|paint|pointer|shape|stop|strikethrough|stroke|text(?!L)|transform|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/; | |||
var J2 = /^on(Ani|Tra|Tou|BeforeInp|Compo)/; | |||
var K2 = /[A-Z0-9]/g; | |||
var Q2 = "undefined" != typeof document; | |||
var X2 = function(n3) { | |||
return ("undefined" != typeof Symbol && "symbol" == typeof /* @__PURE__ */ Symbol() ? /fil|che|rad/ : /fil|che|ra/).test(n3); | |||
}; | }; | ||
C.prototype.isReactComponent = true, ["componentWillMount", "componentWillReceiveProps", "componentWillUpdate"].forEach(function(t4) { | |||
Object.defineProperty(C.prototype, t4, { configurable: true, get: function() { | |||
return this["UNSAFE_" + t4]; | |||
}, set: function(n3) { | |||
Object.defineProperty(this, t4, { configurable: true, writable: true, value: n3 }); | |||
} | } }); | ||
}); | |||
var en = l.event; | |||
l.event = function(n3) { | |||
return en && (n3 = en(n3)), n3.persist = function() { | |||
}, n3.isPropagationStopped = function() { | |||
return this.cancelBubble; | |||
}, n3.isDefaultPrevented = function() { | |||
return this.defaultPrevented; | |||
}, n3.nativeEvent = n3; | |||
}; | }; | ||
var | var rn; | ||
function | var un = { configurable: true, get: function() { | ||
return this.class; | |||
} }; | |||
var on = l.vnode; | |||
l.vnode = function(n3) { | |||
})), n3; | "string" == typeof n3.type && (function(n4) { | ||
} | var t4 = n4.props, e4 = n4.type, u5 = {}, o3 = -1 == e4.indexOf("-"); | ||
function | for (var i4 in t4) { | ||
var l4 = t4[i4]; | |||
if (!("value" === i4 && "defaultValue" in t4 && null == l4 || Q2 && "children" === i4 && "noscript" === e4 || "class" === i4 || "className" === i4)) { | |||
var f4 = i4.toLowerCase(); | |||
"defaultValue" === i4 && "value" in t4 && null == t4.value ? i4 = "value" : "download" === i4 && true === l4 ? l4 = "" : "translate" === f4 && "no" === l4 ? l4 = false : "o" === f4[0] && "n" === f4[1] ? "ondoubleclick" === f4 ? i4 = "ondblclick" : "onchange" !== f4 || "input" !== e4 && "textarea" !== e4 || X2(t4.type) ? "onfocus" === f4 ? i4 = "onfocusin" : "onblur" === f4 ? i4 = "onfocusout" : J2.test(i4) && (i4 = f4) : f4 = i4 = "oninput" : o3 && G2.test(i4) ? i4 = i4.replace(K2, "-$&").toLowerCase() : null === l4 && (l4 = void 0), "oninput" === f4 && u5[i4 = f4] && (i4 = "oninputCapture"), u5[i4] = l4; | |||
} | |||
} | |||
"select" == e4 && (u5.multiple && Array.isArray(u5.value) && (u5.value = F(t4.children).forEach(function(n5) { | |||
n5.props.selected = -1 != u5.value.indexOf(n5.props.value); | |||
})), null != u5.defaultValue && (u5.value = F(t4.children).forEach(function(n5) { | |||
n5.props.selected = u5.multiple ? -1 != u5.defaultValue.indexOf(n5.props.value) : u5.defaultValue == n5.props.value; | |||
}))), t4.class && !t4.className ? (u5.class = t4.class, Object.defineProperty(u5, "className", un)) : t4.className && (u5.class = u5.className = t4.className), n4.props = u5; | |||
})(n3), n3.$$typeof = q3, on && on(n3); | |||
}; | |||
var ln = l.__r; | |||
l.__r = function(n3) { | |||
ln && ln(n3), rn = n3.__c; | |||
}; | |||
var fn = l.diffed; | |||
l.diffed = function(n3) { | |||
fn && fn(n3); | |||
var t4 = n3.props, e4 = n3.__e; | |||
null != e4 && "textarea" === n3.type && "value" in t4 && t4.value !== e4.value && (e4.value = null == t4.value ? "" : t4.value), rn = null; | |||
}; | |||
// src/planner/utils/cn.js | |||
function cn(...classes) { | |||
return classes.filter(Boolean).join(" "); | |||
} | } | ||
var cn_default = cn; | |||
// src/planner/components/Panel.jsx | |||
var SIZE = 12; | |||
var HALF = SIZE / 2; | |||
var ROOT = u3` | |||
} | position: absolute; | ||
top: 324px; | |||
left: 452px; | |||
z-index: 100; | |||
filter: drop-shadow(0 0 0.3rem black); | |||
`; | |||
var ARROW = u3` | |||
position: absolute; | |||
var | top: -${HALF}px; | ||
left: -${HALF}px; | |||
width: ${SIZE}px; | |||
height: ${SIZE}px; | |||
background-color: #bcb096; | |||
`; | |||
var ARROW_PLACEMENT = { | |||
[NORTH]: u3` | |||
clip-path: polygon(50% 50%, 0 0, 100% 0); | |||
`, | |||
[EAST]: u3` | |||
clip-path: polygon(50% 50%, 100% 0, 100% 100%); | |||
`, | |||
[SOUTH]: u3` | |||
clip-path: polygon(50% 50%, 100% 100%, 0% 100%); | |||
`, | |||
[WEST]: u3` | |||
clip-path: polygon(50% 50%, 0 100%, 0 0); | |||
` | |||
}; | |||
var BOX = u3` | |||
position: absolute; | |||
width: max-content; | |||
border: solid 1px #bcb096; | |||
border-radius: 8px; | |||
`; | |||
var DEFAULT_WAY = NORTH; | |||
var DEFAULT_OFFSET = "50%"; | |||
var Panel = class extends M2 { | |||
vars = { | |||
rootRef: M(), | |||
boxRef: M() | |||
}; | }; | ||
state = { | |||
left: void 0, | |||
right: void 0, | |||
top: void 0, | |||
bottom: void 0 | |||
}; | }; | ||
render() { | |||
const { className, rootRef, boxRef, boxClassName, children, maxWidth, way = DEFAULT_WAY } = this.props; | |||
const kids = Array.isArray(children) ? children : [children]; | |||
const { left, right, top, bottom } = this.state; | |||
const usedRootRef = rootRef || this.vars.rootRef; | |||
const usedBoxRef = boxRef || this.vars.boxRef; | |||
return /* @__PURE__ */ u2("div", { class: cn_default(ROOT, className), ref: usedRootRef, children: [ | |||
/* @__PURE__ */ u2("div", { ref: usedBoxRef, class: cn_default(BOX, boxClassName), style: { maxWidth, left, right, top, bottom }, children: [ | |||
} | ...kids | ||
] }), | |||
/* @__PURE__ */ u2("div", { class: cn_default(ARROW, ARROW_PLACEMENT[way]) }) | |||
] }); | |||
} | } | ||
componentDidMount() { | |||
this.refreshBoxOffset(); | |||
window.addEventListener("resize", this.onWindowResize); | |||
} | } | ||
componentDidUpdate() { | |||
this.refreshBoxOffset(); | |||
} | |||
componentWillUnmount() { | |||
} | window.removeEventListener("resize", this.onWindowResize); | ||
} | |||
// ----------------------------------------------------------------------------------------------------------------- | |||
// P R I V A T E | |||
// ----------------------------------------------------------------------------------------------------------------- | |||
onWindowResize = () => { | |||
this.refreshBoxOffset(); | |||
}; | |||
refreshBoxOffset = () => { | |||
const { way = DEFAULT_WAY, offset = DEFAULT_OFFSET, rootRef, boxRef } = this.props; | |||
}, | const rootElement = (rootRef || this.vars.rootRef).current; | ||
const boxElement = (boxRef || this.vars.boxRef).current; | |||
const offsetValue = resolveOffset(offset, boxElement, way); | |||
let coordinates; | |||
switch (way) { | |||
case NORTH: | |||
coordinates = { left: -offsetValue, top: -HALF - boxElement.offsetHeight }; | |||
break; | |||
case SOUTH: | |||
coordinates = { left: -offsetValue, top: HALF }; | |||
break; | |||
case EAST: | |||
coordinates = { left: HALF, top: -offsetValue }; | |||
break; | |||
case WEST: | |||
coordinates = { left: -HALF - boxElement.offsetWidth, top: -offsetValue }; | |||
break; | |||
default: | |||
} | |||
const imprisoned = imprisonCoordinates(coordinates, boxElement, rootElement); | |||
this.setState(imprisoned); | |||
}; | |||
}; | |||
function resolveOffset(offset, element, way) { | |||
if (typeof offset === "number") { | |||
return offset; | |||
} | |||
const percent = Number(offset.match(/\d+/)[0]); | |||
switch (way) { | |||
case NORTH: | |||
// fall | |||
case SOUTH: | |||
return Math.round(element.offsetWidth * percent / 100); | |||
case EAST: | |||
// fall | |||
case WEST: | |||
return Math.round(element.offsetHeight * percent / 100); | |||
default: | |||
return 0; | |||
} | } | ||
} | } | ||
function | function imprisonCoordinates(coordinates, boxElement, rootElement) { | ||
const boxBounds = boxElement.getBoundingClientRect(); | |||
return | const rootBounds = rootElement.getBoundingClientRect(); | ||
const scaleRatio = boxBounds.width / boxElement.offsetWidth; | |||
const futureRightmostBound = rootBounds.left + boxBounds.width + coordinates.left * scaleRatio; | |||
const overflowRight = futureRightmostBound - (window.innerWidth - 20); | |||
if (overflowRight > 0) { | |||
return { | |||
left: coordinates.left - overflowRight / scaleRatio, | |||
top: coordinates.top | |||
}; | |||
} | |||
const futureLeftmostBound = rootBounds.left + coordinates.left * scaleRatio; | |||
const overflowLeft = 5 - futureLeftmostBound; | |||
if (overflowLeft > 0) { | |||
return { | |||
left: coordinates.left + overflowLeft / scaleRatio, | |||
top: coordinates.top | |||
}; | |||
} | |||
return coordinates; | |||
} | } | ||
var Panel_default = Panel; | |||
// src/planner/components/HintContent.jsx | |||
var ROOT2 = u3` | |||
padding: 6px 8px; | |||
`; | |||
var TITLE = u3` | |||
font-weight: bold; | |||
color: #d6bc7c; | |||
padding-bottom: 4px; | |||
`; | |||
var TEXT = u3` | |||
color: #fff; | |||
`; | |||
var HintContent = class extends C { | |||
render() { | |||
const { title, text } = this.props; | |||
return /* @__PURE__ */ u2("div", { class: ROOT2, children: [ | |||
} | title && /* @__PURE__ */ u2("div", { class: TITLE, children: title }), | ||
text && /* @__PURE__ */ u2("div", { class: TEXT, dangerouslySetInnerHTML: { __html: text } }) | |||
] }); | |||
} | |||
}; | }; | ||
var | var HintContent_default = HintContent; | ||
var | // src/planner/components/Hint.jsx | ||
var ROOT3 = u3` | |||
position: relative; | |||
var | line-height: 0; | ||
`; | |||
var PANEL = u3` | |||
position: fixed; | |||
pointer-events: none; | |||
z-index: 9999; | |||
`; | |||
var BOX2 = u3` | |||
background: #191b2c; | |||
border-radius: 4px; | |||
var | `; | ||
var Hint = class extends C { | |||
vars = { | |||
} | triggerRef: M(), | ||
panelRef: M() | |||
}; | |||
state = { | |||
isOpen: false | |||
}; | |||
render() { | |||
const { text, title, way = NORTH, children, hintClassName } = this.props; | |||
const { isOpen } = this.state; | |||
const kids = Array.isArray(children) ? children : [children]; | |||
return /* @__PURE__ */ u2( | |||
"div", | |||
{ | |||
class: ROOT3, | |||
ref: this.vars.triggerRef, | |||
onPointerEnter: this.onRootPointerEnter, | |||
onPointerLeave: this.onRootPointerLeave, | |||
children: [ | |||
kids[0], | |||
isOpen && Boolean(title || text) && $2( | |||
/* @__PURE__ */ u2( | |||
Panel_default, | |||
{ | |||
rootRef: this.vars.panelRef, | |||
className: cn_default(PANEL, hintClassName), | |||
boxClassName: BOX2, | |||
way, | |||
maxWidth: 320, | |||
children: /* @__PURE__ */ u2(HintContent_default, { title, text }) | |||
} | |||
), | |||
document.body | |||
) | |||
] | |||
} | |||
); | |||
} | |||
componentDidUpdate() { | |||
if (this.state.isOpen) { | |||
this.refreshPanelPosition(); | |||
} | |||
} | |||
// ----------------------------------------------------------------------------------------------------------------- | |||
// P R I V A T E | |||
// ----------------------------------------------------------------------------------------------------------------- | |||
onRootPointerEnter = () => { | |||
this.setState({ isOpen: true }); | |||
isOpen: | |||
}; | }; | ||
onRootPointerLeave = () => { | |||
this.setState({ isOpen: false }); | |||
}; | }; | ||
refreshPanelPosition = () => { | |||
const panelElement = this.vars.panelRef.current; | |||
if (!panelElement) { | |||
return; | |||
const | } | ||
const | const triggerElement = this.vars.triggerRef.current; | ||
const | const b3 = triggerElement.getBoundingClientRect(); | ||
const { way = NORTH } = this.props; | |||
switch (way) { | |||
case NORTH: | |||
panelElement.style.left = Math.round(b3.x + b3.width / 2) + "px"; | |||
panelElement.style.top = Math.round(b3.y) + "px"; | |||
break; | |||
case SOUTH: | |||
panelElement.style.left = Math.round(b3.x + b3.width / 2) + "px"; | |||
panelElement.style.top = Math.round(b3.y + b3.height) + "px"; | |||
break; | |||
case EAST: | |||
panelElement.style.left = Math.round(b3.x + b3.width) + "px"; | |||
panelElement.style.top = Math.round(b3.y + b3.height / 2) + "px"; | |||
break; | |||
case WEST: | |||
panelElement.style.left = Math.round(b3.x) + "px"; | |||
panelElement.style.top = Math.round(b3.y + b3.height / 2) + "px"; | |||
break; | |||
default: | |||
} | } | ||
}; | }; | ||
}; | |||
var Hint_default = Hint; | |||
// src/planner/components/Menu.jsx | |||
var BOX3 = u3` | |||
background: #1f3756; | |||
overflow: auto; | |||
& > * { | |||
display: inline-block; | |||
} | |||
& [data-id=${NONE}] { | |||
padding: 16px; | |||
} | |||
`; | |||
var ICON = u3` | |||
width: 56px; | |||
cursor: pointer; | |||
`; | |||
var Menu = class extends C { | |||
vars = { | |||
boxRef: M(), | |||
timeout: null | |||
}; | }; | ||
render() { | |||
const | const { list, className, boxClassName, way, offset, maxWidth } = this.props; | ||
return /* @__PURE__ */ u2( | |||
Panel_default, | |||
{ | |||
className, | |||
boxRef: this.vars.boxRef, | |||
boxClassName: cn_default(BOX3, boxClassName), | |||
way, | |||
offset, | |||
maxWidth, | |||
children: Object.values(list).map((item) => { | |||
const { Component } = item; | |||
if (Component) { | |||
return /* @__PURE__ */ u2(Component, { ...item, onClick: this.onIconClick }); | |||
} | |||
return /* @__PURE__ */ u2(Hint_default, { title: item.name, text: item.description, children: /* @__PURE__ */ u2( | |||
"img", | |||
{ | |||
class: ICON, | |||
src: item.icon, | |||
"data-id": item.id, | |||
onClick: this.onIconClick | |||
}, | |||
item.id | |||
) }); | |||
}) | |||
} | |||
); | |||
} | |||
componentDidMount() { | |||
this.vars.timeout = setTimeout(this.listenForClose, 100); | |||
} | |||
componentWillUnmount() { | |||
window.removeEventListener("click", this.onWindowClick); | |||
clearTimeout(this.vars.timeout); | |||
this.vars = null; | |||
} | |||
// ----------------------------------------------------------------------------------------------------------------- | |||
// P R I V A T E | |||
// ----------------------------------------------------------------------------------------------------------------- | |||
/** | |||
* | |||
*/ | |||
listenForClose = () => { | |||
window.addEventListener("click", this.onWindowClick); | |||
}; | |||
/** | |||
* | |||
*/ | |||
onWindowClick = (event) => { | |||
const boxElement = this.vars.boxRef.current; | |||
const { target } = event; | |||
if (target instanceof Node && boxElement.contains(target)) { | |||
return; | |||
} | } | ||
this.props.onChoice(); | |||
}; | |||
/** | |||
* | |||
*/ | |||
onIconClick = (event) => { | |||
this.props.onChoice(event.currentTarget.dataset.id); | |||
}; | }; | ||
}; | }; | ||
var | var Menu_default = Menu; | ||
// src/planner/components/ | // src/planner/components/Portrait.jsx | ||
var | var ROOT_CSS = u3` | ||
position: absolute; | |||
left: 0; | |||
top: 0; | |||
`; | |||
var PIC_CSS = u3` | |||
width: 100%; | |||
`; | `; | ||
var | var MEDALLION_CSS = u3` | ||
position: absolute; | |||
left: 0; | |||
top: -5px; | |||
}; | width: 140px; | ||
render() { | height: 140px; | ||
const { | border-bottom-left-radius: 50%; | ||
return /* @__PURE__ */ u2( | border-bottom-right-radius: 50%; | ||
-webkit-mask: url(#compoundMask); | |||
mask: url(#compoundMask); | |||
cursor: pointer; | |||
/*background: red;*/ | |||
/*filter: drop-shadow(0 0 2px rgba(255,255,255,0.5));*/ | |||
`; | |||
var MENU = u3` | |||
left: 152px; | |||
top: 84px; | |||
max-height: 681px; | |||
`; | |||
var Portrait = class extends C { | |||
state = { | |||
isOpen: false | |||
}; | |||
render() { | |||
const { hero, heroes } = this.props; | |||
const { isOpen } = this.state; | |||
return /* @__PURE__ */ u2("div", { className: ROOT_CSS, children: [ | |||
/* @__PURE__ */ u2("div", { className: MEDALLION_CSS, onClick: this.onMedallionClick, children: [ | |||
/* @__PURE__ */ u2("svg", { width: "0", height: "0", style: "position:absolute", children: /* @__PURE__ */ u2("defs", { children: /* @__PURE__ */ u2("mask", { id: "compoundMask", maskContentUnits: "objectBoundingBox", children: [ | |||
/* @__PURE__ */ u2("rect", { x: "0", y: "0", width: "1", height: "0.55", fill: "white" }), | |||
/* @__PURE__ */ u2("circle", { cx: "0.54", cy: "0.58", r: "0.41", fill: "white" }) | |||
] }) }) }), | |||
hero && /* @__PURE__ */ u2("img", { className: PIC_CSS, src: heroes[hero].portrait }) | |||
] }), | |||
isOpen && /* @__PURE__ */ u2( | |||
Menu_default, | |||
{ | |||
className: MENU, | |||
maxWidth: 508, | |||
way: EAST, | |||
offset: 70, | |||
list: heroes, | |||
onChoice: this.onMenuChoice | |||
} | |||
) | |||
] }); | |||
} | } | ||
// ----------------------------------------------------------------------------------------------------------------- | // ----------------------------------------------------------------------------------------------------------------- | ||
| Line 915: | Line 1,054: | ||
* | * | ||
*/ | */ | ||
onMedallionClick = () => { | |||
if (!this.state.isOpen) { | |||
this.setState({ isOpen: true }); | |||
} | |||
}; | }; | ||
/** | /** | ||
* | * | ||
*/ | */ | ||
onMenuChoice = (choice) => { | |||
console.log("choice:", choice); | |||
this.setState({ isOpen: false }); | |||
if ( | if (choice && choice !== this.props.hero) { | ||
this.props.onHeroChange(choice); | |||
} | } | ||
}; | }; | ||
}; | }; | ||
var | var Portrait_default = Portrait; | ||
// src/planner/components/ | // src/planner/components/Level.jsx | ||
var | var ROOT_CSS2 = u3` | ||
position: absolute; | position: absolute; | ||
left: | left: 29px; | ||
top: | top: 90px; | ||
transform: scale(0.5); | |||
border-radius: 50%; | |||
border | |||
cursor: pointer; | cursor: pointer; | ||
`; | `; | ||
var | var Level = class extends C { | ||
render() { | render() { | ||
const { | const { src } = this.props; | ||
return /* @__PURE__ */ u2("img", { className: ROOT_CSS2, src }); | |||
return | |||
} | } | ||
// ----------------------------------------------------------------------------------------------------------------- | // ----------------------------------------------------------------------------------------------------------------- | ||
// P R I V A T E | // P R I V A T E | ||
// ----------------------------------------------------------------------------------------------------------------- | // ----------------------------------------------------------------------------------------------------------------- | ||
}; | |||
var Level_default = Level; | |||
// src/planner/helpers/compression/SETTINGS.js | |||
var WIKI_URL = "https://wiki.hoodedhorse.com/Heroes_of_Might_and_Magic_Olden_Era/"; | |||
var SYMBOLS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; | |||
var FIELD_INDEX_BITS = 6; | |||
var | |||
// src/planner/helpers/compression/DICTIONARY.js | |||
var DICTIONARY = { | |||
heroes: [ | |||
"human_hero_1", | |||
"human_hero_2", | |||
"human_hero_3", | |||
// src/planner/helpers/compression/DICTIONARY.js | |||
var DICTIONARY = { | |||
heroes: [ | |||
"human_hero_1", | |||
"human_hero_2", | |||
"human_hero_3", | |||
"human_hero_4", | "human_hero_4", | ||
"human_hero_5", | "human_hero_5", | ||
| Line 1,746: | Line 1,800: | ||
const valueBits = stream.slice(cursor, cursor + field.bits); | const valueBits = stream.slice(cursor, cursor + field.bits); | ||
cursor += field.bits; | cursor += field.bits; | ||
const numericValue = parseInt(valueBits, 2); | |||
if (field.dictionary) { | if (field.dictionary) { | ||
if ( | if (numericValue >= field.dictionary.length) { | ||
console.warn(`Dictionary index ${ | console.warn(`Dictionary index ${numericValue} out of bounds for field "${field.key}"!`); | ||
return result; | return result; | ||
} | } | ||
result[field.key] = field.dictionary[numericValue]; | |||
} | } else { | ||
if (!isNaN(numericValue)) { | |||
result[field.key] = numericValue; | |||
} | |||
} | } | ||
expectedIndex = currentIndex + 1; | expectedIndex = currentIndex + 1; | ||
| Line 1,977: | Line 2,032: | ||
var Labels_default = Labels; | var Labels_default = Labels; | ||
// src/planner/components/ | // src/planner/components/SubskillInfo.jsx | ||
var | var ROOT4 = u3` | ||
padding: 6px 8px; | |||
display: flex; | |||
gap: 4px; | |||
&:hover { | |||
background: #192b44; | |||
} | |||
&:active { | |||
background: #191b2c; | |||
} | |||
&[data-id=${NONE}] img { | |||
width: 32px; | |||
height: 32px; | |||
} | |||
`; | |||
var ICON2 = u3` | |||
width: 48px; | |||
height: 48px; | |||
flex-shrink: 0; | |||
`; | |||
var TITLE2 = u3` | |||
font-weight: bold; | |||
color: #d6bc7c; | |||
`; | |||
var TEXT2 = u3` | |||
color: #fff; | |||
`; | |||
var SubskillInfo = class extends C { | |||
render() { | |||
const { id, icon, name, description, onClick } = this.props; | |||
return /* @__PURE__ */ u2("div", { class: ROOT4, "data-id": id, onClick, children: [ | |||
/* @__PURE__ */ u2("img", { class: ICON2, src: icon }), | |||
/* @__PURE__ */ u2("div", { children: [ | |||
/* @__PURE__ */ u2("div", { class: TITLE2, children: name }), | |||
/* @__PURE__ */ u2("div", { class: TEXT2, dangerouslySetInnerHTML: { __html: description } }) | |||
] }) | |||
] }); | |||
} | |||
}; | |||
var SubskillInfo_default = SubskillInfo; | |||
// src/planner/components/Subskill.jsx | |||
var ROOT5 = u3` | |||
position: absolute; | position: absolute; | ||
cursor: pointer; | cursor: pointer; | ||
/*background: red;*/ | /*background: red;*/ | ||
width: | width: 24px; | ||
height: | height: 24px; | ||
border-radius: 4px; | |||
`; | |||
var BORDERED = u3` | |||
border: solid 1px palegoldenrod; | |||
`; | |||
var LEVEL_1 = u3` | |||
left: 54px; | |||
top: -1px; | |||
`; | |||
var LEVEL_2 = u3` | |||
left: 54px; | |||
top: 25px; | |||
`; | `; | ||
var | var HIT = u3` | ||
position: absolute; | |||
u3` | inset: 0; | ||
& img { | |||
width: 100%; | |||
`, | } | ||
`; | |||
var MENU2 = u3` | |||
left: 12px; | |||
top: 24px; | |||
`; | |||
/ | var MENU_BOX = u3` | ||
display: flex; | |||
flex-direction: column; | |||
`; | |||
var Subskill = class extends C { | |||
state = { | |||
isOpen: false | |||
}; | |||
render() { | |||
const { family, index, level, skills } = this.props; | |||
const { isOpen } = this.state; | |||
const { subs = [] } = skills[family + "_" + (level + 1)] || {}; | |||
const subskillData = subs[index]; | |||
return /* @__PURE__ */ u2("div", { className: cn_default(ROOT5, level === 1 ? LEVEL_1 : LEVEL_2, !subskillData && BORDERED), children: [ | |||
/* @__PURE__ */ u2("div", { className: HIT, onClick: this.onHitClick, children: subskillData && /* @__PURE__ */ u2(Hint_default, { title: subskillData.name, text: subskillData.description, children: /* @__PURE__ */ u2("img", { src: subskillData.icon }) }) }), | |||
/* | isOpen && /* @__PURE__ */ u2( | ||
Menu_default, | |||
{ | |||
className: MENU2, | |||
boxClassName: MENU_BOX, | |||
/* | maxWidth: 340, | ||
u3` | list: this.prepareMenuChoices(subs), | ||
left: | onChoice: this.onMenuChoice, | ||
top: | way: SOUTH | ||
} | |||
) | |||
] }); | |||
} | |||
// ----------------------------------------------------------------------------------------------------------------- | |||
// P R I V A T E | |||
// ----------------------------------------------------------------------------------------------------------------- | |||
onHitClick = () => { | |||
if (!this.state.isOpen) { | |||
this.setState({ isOpen: true }); | |||
} | |||
}; | |||
onMenuChoice = (choice) => { | |||
console.log("choice:", choice); | |||
this.setState({ isOpen: false }); | |||
if (choice === void 0) { | |||
return; | |||
} | |||
const { family, skillSlot, level, skills, index, onChange } = this.props; | |||
const { subs } = skills[family + "_" + (level + 1)]; | |||
const chosenIndex = subs.findIndex((sub) => sub.id === choice); | |||
const currentIndex = index === void 0 ? -1 : index; | |||
if (chosenIndex !== currentIndex) { | |||
onChange(chosenIndex, skillSlot, level); | |||
} | |||
}; | |||
prepareMenuChoices = (subs) => { | |||
const options = subs.map((item) => { | |||
return { | |||
...item, | |||
Component: SubskillInfo_default | |||
}; | |||
}); | |||
options.push({ | |||
id: NONE, | |||
icon: this.props.emptyUrl, | |||
name: "", | |||
description: "", | |||
Component: SubskillInfo_default | |||
}); | |||
return options; | |||
}; | |||
}; | |||
var Subskill_default = Subskill; | |||
// src/planner/components/Skill.jsx | |||
var ROOT_CSS6 = u3` | |||
position: absolute; | |||
cursor: pointer; | |||
/*background: red;*/ | |||
width: 50px; | |||
height: 50px; | |||
`; | |||
var SLOTS = [ | |||
/* 0 */ | |||
u3` | |||
left: 326px; | |||
top: 83px; | |||
`, | `, | ||
/* 7 */ | /* 1 */ | ||
u3` | |||
left: 417px; | |||
top: 83px; | |||
`, | |||
/* 2 */ | |||
u3` | |||
left: 508px; | |||
top: 83px; | |||
`, | |||
/* 3 */ | |||
u3` | |||
left: 599px; | |||
top: 83px; | |||
`, | |||
/* 4 */ | |||
u3` | |||
left: 326px; | |||
top: 143px; | |||
`, | |||
/* 5 */ | |||
u3` | |||
left: 417px; | |||
top: 143px; | |||
`, | |||
/* 6 */ | |||
u3` | |||
left: 508px; | |||
top: 143px; | |||
`, | |||
/* 7 */ | |||
u3` | u3` | ||
left: 599px; | left: 599px; | ||
| Line 2,037: | Line 2,234: | ||
cursor: not-allowed; | cursor: not-allowed; | ||
`; | `; | ||
var | var MENU3 = u3` | ||
left: 25px; | left: 25px; | ||
top: 52px; | top: 52px; | ||
`; | `; | ||
var | var LEVEL = u3` | ||
position: absolute; | |||
right: 4px; | |||
bottom: 0; | |||
color: #fff; | |||
font-family: Arial, sans-serif; | |||
`; | |||
var Skill = class extends C { | var Skill = class extends C { | ||
state = { | state = { | ||
| Line 2,064: | Line 2,250: | ||
}; | }; | ||
render() { | render() { | ||
const { nr, id, skills, heroData } = this.props; | const { nr, id, skills, heroData, sub1, sub2, onSubskillChange, emptyUrl } = this.props; | ||
const { isOpen } = this.state; | const { isOpen } = this.state; | ||
const skillData = skills[id]; | const skillData = skills[id]; | ||
const isDisabled = Boolean(heroData?.skills[nr]); | const isDisabled = Boolean(heroData?.skills[nr]); | ||
return /* @__PURE__ */ u2("div", { className: cn_default(ROOT_CSS6, SLOTS[nr], isDisabled && FORBIDDEN) | return /* @__PURE__ */ u2("div", { className: cn_default(ROOT_CSS6, SLOTS[nr], isDisabled && FORBIDDEN), children: [ | ||
/* @__PURE__ */ u2("div", { className: HIT_CSS, onClick: !isDisabled && this.onHitClick, children: skillData && /* @__PURE__ */ u2(Hint_default, { title: skillData.name, text: skillData.description, children: /* @__PURE__ */ u2("img", { src: skillData.icon }) }) }), | /* @__PURE__ */ u2("div", { className: HIT_CSS, onClick: !isDisabled && this.onHitClick, children: skillData && /* @__PURE__ */ u2(Hint_default, { title: skillData.name, text: skillData.description, children: /* @__PURE__ */ u2("img", { src: skillData.icon }) }) }), | ||
isOpen && /* @__PURE__ */ u2( | isOpen && /* @__PURE__ */ u2( | ||
Menu_default, | Menu_default, | ||
{ | { | ||
className: | className: MENU3, | ||
maxWidth: 340, | maxWidth: 340, | ||
list: this.filterSkills(skills), | list: this.filterSkills(skills), | ||
onChoice: this.onMenuChoice, | onChoice: this.onMenuChoice, | ||
way: SOUTH, | way: SOUTH | ||
} | |||
), | |||
skillData && /* @__PURE__ */ u2( | |||
Subskill_default, | |||
{ | |||
family: id, | |||
skillSlot: nr, | |||
index: sub1, | |||
level: 1, | |||
skills, | |||
onChange: onSubskillChange, | |||
emptyUrl | |||
} | |||
), | |||
sub1 !== void 0 && /* @__PURE__ */ u2( | |||
Subskill_default, | |||
{ | |||
family: id, | |||
skillSlot: nr, | |||
index: sub2, | |||
level: 2, | |||
skills, | |||
onChange: onSubskillChange, | |||
emptyUrl | |||
} | } | ||
) | ), | ||
/* @__PURE__ */ u2("div", { class: LEVEL, children: computeLevel(skillData, sub1, sub2) }) | |||
] }); | ] }); | ||
} | } | ||
| Line 2,095: | Line 2,304: | ||
console.log("choice:", choice); | console.log("choice:", choice); | ||
this.setState({ isOpen: false }); | this.setState({ isOpen: false }); | ||
if (choice !== this.props.id) { | if (choice && choice !== this.props.id) { | ||
this.props.onChange(choice, this.props.nr); | this.props.onChange(choice, this.props.nr); | ||
} | } | ||
| Line 2,122: | Line 2,331: | ||
}; | }; | ||
}; | }; | ||
function computeLevel(skillData, sub1, sub2) { | |||
if (!skillData) { | |||
return ""; | |||
} | |||
if (sub1 === void 0) { | |||
return 1; | |||
} | |||
if (sub2 === void 0) { | |||
return 2; | |||
} | |||
return 3; | |||
} | |||
var Skill_default = Skill; | var Skill_default = Skill; | ||
| Line 2,132: | Line 2,353: | ||
removeUnknownArtifact(draft); | removeUnknownArtifact(draft); | ||
removeUnknownUnit(draft); | removeUnknownUnit(draft); | ||
ensureNativeSkills(draft, heroes); | ensureNativeSkills(draft, heroes); | ||
removeWrongCombatOrThaumaturgy(draft, heroes); | |||
removeDuplicateSkills(draft); | |||
removeUnexpectedSubskills(draft); | |||
return draft; | return draft; | ||
} | } | ||
function removeUnknownHero(draft) { | function removeUnknownHero(draft, heroes) { | ||
const { hero } = draft; | |||
if (hero && !heroes[hero]) { | |||
console.warn(`Unknown hero "${draft.hero}" was removed!`); | |||
delete draft.hero; | |||
} | |||
} | } | ||
function removeUnknownSkill(draft) { | function removeUnknownSkill(draft, skills) { | ||
for (let i4 = 0; i4 < 8; i4++) { | |||
const key = `skill${i4}Id`; | |||
const skillId = draft[key]; | |||
if (skillId) { | |||
if (!skills[skillId]) { | |||
delete draft[key]; | |||
console.warn(`Unknown skill "${skillId}" was removed!`); | |||
} else if (skills[skillId].subs.length) { | |||
delete draft[key]; | |||
console.warn(`Non-basic skill "${skillId}" was removed!`); | |||
} | |||
} | |||
} | |||
} | } | ||
function removeUnknownSubskill(draft) { | function removeUnknownSubskill(draft, skills) { | ||
for (let i4 = 0; i4 < 8; i4++) { | |||
const skillKey = `skill${i4}Id`; | |||
const skillId = draft[skillKey]; | |||
const sub1Key = `skill${i4}Sub1`; | |||
const sub1Index = draft[sub1Key]; | |||
const sub2Key = `skill${i4}Sub2`; | |||
const sub2Index = draft[sub2Key]; | |||
if (skillId) { | |||
if (sub1Index !== void 0) { | |||
const advancedSubs = skills[skillId + "_2"]?.subs || []; | |||
if (sub1Index >= advancedSubs.length) { | |||
delete draft[sub1Key]; | |||
console.warn(`Out-of-bounds Advanced subskill was removed!`); | |||
} | |||
} | |||
if (sub2Index !== void 0) { | |||
const expertSubs = skills[skillId + "_3"]?.subs || []; | |||
if (sub2Index >= expertSubs.length) { | |||
delete draft[sub2Key]; | |||
console.warn(`Out-of-bounds Expert subskill was removed!`); | |||
} | |||
} | |||
} | |||
} | |||
} | } | ||
function removeUnknownArtifact(draft) { | function removeUnknownArtifact(draft) { | ||
| Line 2,148: | Line 2,411: | ||
function removeUnknownUnit(draft) { | function removeUnknownUnit(draft) { | ||
} | } | ||
function removeWrongCombatOrThaumaturgy(draft) { | function removeWrongCombatOrThaumaturgy(draft, heroes) { | ||
const { hero } = draft; | |||
if (hero) { | |||
const { isMight } = heroes[hero]; | |||
for (let i4 = 0; i4 < 8; i4++) { | |||
const key = `skill${i4}Id`; | |||
const skillId = draft[key]; | |||
if (skillId) { | |||
if (skillId === "skill_battle_artistry") { | |||
if (!isMight) { | |||
delete draft[key]; | |||
console.warn(`Skill "${skillId}" was removed because it's only for Might!`); | |||
} | |||
} else if (skillId === "skill_wisdom") { | |||
if (isMight) { | |||
delete draft[key]; | |||
console.warn(`Skill "${skillId}" was removed because it's only for Magic!`); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | } | ||
function | function removeDuplicateSkills(draft) { | ||
const used = {}; | |||
for (let i4 = 0; i4 < 8; i4++) { | |||
const key = `skill${i4}Id`; | |||
const skillId = draft[key]; | |||
if (skillId) { | |||
if (used[skillId]) { | |||
delete draft[key]; | |||
console.warn(`Duplicate skill "${skillId}" was removed!`); | |||
} else { | |||
used[skillId] = true; | |||
} | |||
} | |||
} | |||
} | } | ||
function | function removeUnexpectedSubskills(draft) { | ||
for (let i4 = 0; i4 < 8; i4++) { | |||
const skillKey = `skill${i4}Id`; | |||
const skillId = draft[skillKey]; | |||
const sub1Key = `skill${i4}Sub1`; | |||
const sub1Index = draft[sub1Key]; | |||
const sub2Key = `skill${i4}Sub2`; | |||
const sub2Index = draft[sub2Key]; | |||
if (!skillId) { | |||
if (sub1Index !== void 0) { | |||
delete draft[sub1Key]; | |||
console.warn(`Unexpected Advanced subskill was removed!`); | |||
} | |||
if (sub2Index !== void 0) { | |||
delete draft[sub2Key]; | |||
console.warn(`Unexpected Expert subskill was removed!`); | |||
} | |||
} else { | |||
if (sub1Index === void 0 && sub2Index !== void 0) { | |||
delete draft[sub2Key]; | |||
console.warn(`Unsupported Expert subskill was removed!`); | |||
} | |||
} | |||
} | |||
} | } | ||
function ensureNativeSkills(draft, heroes) { | function ensureNativeSkills(draft, heroes) { | ||
| Line 2,173: | Line 2,493: | ||
// src/planner/helpers/acceptSkill.js | // src/planner/helpers/acceptSkill.js | ||
function acceptSkill(skillId, nr, state) { | function acceptSkill(skillId, nr, state, heroData) { | ||
const draft = { ...state }; | const draft = { ...state }; | ||
if (heroData) { | |||
if (heroData.skills.find((skill) => skill.name === skillId)) { | |||
console.warn("Refused to change into a native skill!"); | |||
return draft; | |||
} | |||
} | |||
if (skillId === NONE) { | if (skillId === NONE) { | ||
draft[`skill${nr}Id`] | delete draft[`skill${nr}Id`]; | ||
draft[`skill${nr}Sub1`] | delete draft[`skill${nr}Sub1`]; | ||
draft[`skill${nr}Sub2`] | delete draft[`skill${nr}Sub2`]; | ||
return draft; | return draft; | ||
} | } | ||
for (let i4 = 0; i4 < 8; i4++) { | for (let i4 = 0; i4 < 8; i4++) { | ||
if (draft[`skill${i4}Id`] === skillId) { | if (draft[`skill${i4}Id`] === skillId) { | ||
draft[`skill${i4}Id`] | delete draft[`skill${i4}Id`]; | ||
draft[`skill${i4}Sub1`] | delete draft[`skill${i4}Sub1`]; | ||
draft[`skill${i4}Sub2`] | delete draft[`skill${i4}Sub2`]; | ||
console.log("Existing duplicate skill has been removed!"); | |||
} | } | ||
} | } | ||
draft[`skill${nr}Id`] = skillId; | draft[`skill${nr}Id`] = skillId; | ||
draft[`skill${nr}Sub1`] | delete draft[`skill${nr}Sub1`]; | ||
draft[`skill${nr}Sub2`] | delete draft[`skill${nr}Sub2`]; | ||
return draft; | return draft; | ||
} | } | ||
| Line 2,201: | Line 2,528: | ||
height: ${HEIGHT}px; | height: ${HEIGHT}px; | ||
transform-origin: 0 0; | transform-origin: 0 0; | ||
-webkit-touch-callout: none; | |||
-webkit-user-select: none; | |||
user-select: none; | |||
& img { | & img { | ||
| Line 2,221: | Line 2,551: | ||
const heroData = heroes[hero]; | const heroData = heroes[hero]; | ||
const skillNumbers = [0, 1, 2, 3, 4, 5, 6, 7]; | const skillNumbers = [0, 1, 2, 3, 4, 5, 6, 7]; | ||
return /* @__PURE__ */ u2("div", { className: APP_CSS, ref: appRef, children: [ | return /* @__PURE__ */ u2("div", { className: APP_CSS, ref: appRef, onContextMenu: this.onRootContextMenu, children: [ | ||
/* @__PURE__ */ u2("style", { children: CSS }), | /* @__PURE__ */ u2("style", { children: CSS }), | ||
/* @__PURE__ */ u2("img", { className: BG_CSS, src: bgUrl, alt: "empty background" }), | /* @__PURE__ */ u2("img", { className: BG_CSS, src: bgUrl, alt: "empty background" }), | ||
| Line 2,237: | Line 2,567: | ||
skills, | skills, | ||
onChange: this.onSkillChange, | onChange: this.onSkillChange, | ||
onSubskillChange: this.onSubskillChange, | |||
emptyUrl, | emptyUrl, | ||
heroData | heroData | ||
| Line 2,267: | Line 2,598: | ||
/** | /** | ||
* | * | ||
*/ | */ | ||
refreshScale = () => { | onRootContextMenu = (event) => { | ||
const appElement = this.vars.appRef.current; | event.preventDefault(); | ||
const rootElement = appElement.parentNode; | }; | ||
const { width } = rootElement.getBoundingClientRect(); | /** | ||
const coreWidth = Math.min(width, WIDTH); | * | ||
const coreHeight = coreWidth * HEIGHT / WIDTH; | */ | ||
rootElement.style.height = Math.ceil(coreHeight) + "px"; | refreshScale = () => { | ||
const scaleRatio = coreWidth / WIDTH; | const appElement = this.vars.appRef.current; | ||
appElement.style.transform = `scale(${scaleRatio})`; | const rootElement = appElement.parentNode; | ||
appElement.style.left = Math.floor((width - coreWidth) / 2) + "px"; | const { width } = rootElement.getBoundingClientRect(); | ||
}; | const coreWidth = Math.min(width, WIDTH); | ||
/** | const coreHeight = coreWidth * HEIGHT / WIDTH; | ||
* | rootElement.style.height = Math.ceil(coreHeight) + "px"; | ||
*/ | const scaleRatio = coreWidth / WIDTH; | ||
onHeroChange = (hero) => { | appElement.style.transform = `scale(${scaleRatio})`; | ||
appElement.style.left = Math.floor((width - coreWidth) / 2) + "px"; | |||
}; | |||
/** | |||
* | |||
}; | */ | ||
/** | onHeroChange = (hero) => { | ||
* | this.save({ ...this.state, hero }); | ||
*/ | }; | ||
onSkillChange = (choice, nr) => { | /** | ||
const futureState = acceptSkill_default(choice, nr, this.state); | * | ||
*/ | |||
onSkillChange = (choice, nr) => { | |||
const { heroes } = this.props; | |||
const heroData = heroes[this.state.hero]; | |||
const futureState = acceptSkill_default(choice, nr, this.state, heroData); | |||
this.save(futureState); | |||
}; | |||
/** | |||
* | |||
*/ | |||
onSubskillChange = (choice, nr, level) => { | |||
const key = `skill${nr}Sub${level}`; | |||
const value = choice === -1 ? void 0 : choice; | |||
const futureState = { ...this.state, [key]: value }; | |||
if (level === 1 && value === void 0) { | |||
futureState[`skill${nr}Sub2`] = void 0; | |||
} | |||
this.save(futureState); | |||
}; | |||
/** | |||
* | |||
*/ | |||
onHashChange = (stateFragment) => { | |||
const { heroes, skills } = this.props; | |||
const sanitized = sanitize_default(stateFragment, heroes, skills); | |||
const subState = {}; | |||
for (const field of FIELDS_default) { | |||
const { key } = field; | |||
subState[key] = sanitized[key]; | |||
} | |||
this.setState(subState); | |||
}; | }; | ||
/** | /** | ||
* | * | ||
*/ | */ | ||
save = (futureState) => { | |||
const { heroes, skills } = this.props; | const { heroes, skills } = this.props; | ||
const | const safeState = sanitize_default(futureState, heroes, skills); | ||
Persistence_default.remember(safeState); | |||
}; | }; | ||
}; | }; | ||
Revision as of 10:44, 15 September 2026
(() => {
// node_modules/preact/dist/preact.module.js
var n;
var l;
var u;
var t;
var i;
var r;
var o;
var e;
var f;
var c;
var a;
var s;
var h;
var p;
var v;
var y;
var d = {};
var w = [];
var _ = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;
var g = Array.isArray;
function m(n3, l4) {
for (var u5 in l4) n3[u5] = l4[u5];
return n3;
}
function b(n3) {
n3 && n3.parentNode && n3.parentNode.removeChild(n3);
}
function k(l4, u5, t4) {
var i4, r3, o3, e4 = {};
for (o3 in u5) "key" == o3 ? i4 = u5[o3] : "ref" == o3 ? r3 = u5[o3] : e4[o3] = u5[o3];
if (arguments.length > 2 && (e4.children = arguments.length > 3 ? n.call(arguments, 2) : t4), "function" == typeof l4 && null != l4.defaultProps) for (o3 in l4.defaultProps) void 0 === e4[o3] && (e4[o3] = l4.defaultProps[o3]);
return x(l4, e4, i4, r3, null);
}
function x(n3, t4, i4, r3, o3) {
var e4 = { type: n3, props: t4, key: i4, ref: r3, __k: null, __: null, __b: 0, __e: null, __c: null, constructor: void 0, __v: null == o3 ? ++u : o3, __i: -1, __u: 0 };
return null == o3 && null != l.vnode && l.vnode(e4), e4;
}
function M() {
return { current: null };
}
function S(n3) {
return n3.children;
}
function C(n3, l4) {
this.props = n3, this.context = l4;
}
function $(n3, l4) {
if (null == l4) return n3.__ ? $(n3.__, n3.__i + 1) : null;
for (var u5; l4 < n3.__k.length; l4++) if (null != (u5 = n3.__k[l4]) && null != u5.__e) return u5.__e;
return "function" == typeof n3.type ? $(n3) : null;
}
function I(n3) {
if (n3.__P && n3.__d) {
var u5 = n3.__v, t4 = u5.__e, i4 = [], r3 = [], o3 = m({}, u5);
o3.__v = u5.__v + 1, l.vnode && l.vnode(o3), q(n3.__P, o3, u5, n3.__n, n3.__P.namespaceURI, 32 & u5.__u ? [t4] : null, i4, null == t4 ? $(u5) : t4, !!(32 & u5.__u), r3), o3.__v = u5.__v, o3.__.__k[o3.__i] = o3, D(i4, o3, r3), u5.__e = u5.__ = null, o3.__e != t4 && P(o3);
}
}
function P(n3) {
if (null != (n3 = n3.__) && null != n3.__c) return n3.__e = n3.__c.base = null, n3.__k.some(function(l4) {
if (null != l4 && null != l4.__e) return n3.__e = n3.__c.base = l4.__e;
}), P(n3);
}
function A(n3) {
(!n3.__d && (n3.__d = true) && i.push(n3) && !H.__r++ || r != l.debounceRendering) && ((r = l.debounceRendering) || o)(H);
}
function H() {
try {
for (var n3, l4 = 1; i.length; ) i.length > l4 && i.sort(e), n3 = i.shift(), l4 = i.length, I(n3);
} finally {
i.length = H.__r = 0;
}
}
function L(n3, l4, u5, t4, i4, r3, o3, e4, f4, c4, a4) {
var s3, h4, p4, v3, y3, _3, g4 = t4 && t4.__k || w, m3 = l4.length;
for (f4 = T(u5, l4, g4, f4, m3), s3 = 0; s3 < m3; s3++) null != (p4 = u5.__k[s3]) && (h4 = -1 != p4.__i && g4[p4.__i] || d, p4.__i = s3, _3 = q(n3, p4, h4, i4, r3, o3, e4, f4, c4, a4), v3 = p4.__e, p4.ref && h4.ref != p4.ref && (h4.ref && J(h4.ref, null, p4), a4.push(p4.ref, p4.__c || v3, p4)), null == y3 && null != v3 && (y3 = v3), 4 & p4.__u ? (f4 = j(p4, f4, n3), h4.__e && (h4.__e = null)) : "function" == typeof p4.type && void 0 !== _3 ? f4 = _3 : v3 && (f4 = v3.nextSibling), p4.__u &= -7);
return u5.__e = y3, f4;
}
function T(n3, l4, u5, t4, i4) {
var r3, o3, e4, f4, c4, a4 = u5.length, s3 = a4, h4 = 0;
for (n3.__k = new Array(i4), r3 = 0; r3 < i4; r3++) null != (o3 = l4[r3]) && "boolean" != typeof o3 && "function" != typeof o3 ? ("string" == typeof o3 || "number" == typeof o3 || "bigint" == typeof o3 || o3.constructor == String ? o3 = n3.__k[r3] = x(null, o3, null, null, null) : g(o3) ? o3 = n3.__k[r3] = x(S, { children: o3 }, null, null, null) : void 0 === o3.constructor && o3.__b > 0 ? o3 = n3.__k[r3] = x(o3.type, o3.props, o3.key, o3.ref ? o3.ref : null, o3.__v) : n3.__k[r3] = o3, f4 = r3 + h4, o3.__ = n3, o3.__b = n3.__b + 1, e4 = null, -1 != (c4 = o3.__i = O(o3, u5, f4, s3)) && (s3--, (e4 = u5[c4]) && (e4.__u |= 2)), null == e4 || null == e4.__v ? (-1 == c4 && (i4 > a4 ? h4-- : i4 < a4 && h4++), "function" != typeof o3.type && (o3.__u |= 4)) : c4 != f4 && (c4 == f4 - 1 ? h4-- : c4 == f4 + 1 ? h4++ : (c4 > f4 ? h4-- : h4++, o3.__u |= 4))) : n3.__k[r3] = null;
if (s3) for (r3 = 0; r3 < a4; r3++) null != (e4 = u5[r3]) && 0 == (2 & e4.__u) && (e4.__e == t4 && (t4 = $(e4)), K(e4, e4));
return t4;
}
function j(n3, l4, u5) {
var t4, i4;
if ("function" == typeof n3.type) {
for (t4 = n3.__k, i4 = 0; t4 && i4 < t4.length; i4++) t4[i4] && (t4[i4].__ = n3, l4 = j(t4[i4], l4, u5));
return l4;
}
n3.__e != l4 && (l4 && n3.type && !l4.parentNode && (l4 = $(n3)), l4 = u5.insertBefore(n3.__e, l4 || null));
do {
l4 = l4 && l4.nextSibling;
} while (null != l4 && 8 == l4.nodeType);
return l4;
}
function F(n3, l4) {
return l4 = l4 || [], null == n3 || "boolean" == typeof n3 || (g(n3) ? n3.some(function(n4) {
F(n4, l4);
}) : l4.push(n3)), l4;
}
function O(n3, l4, u5, t4) {
var i4, r3, o3, e4 = n3.key, f4 = n3.type, c4 = l4[u5], a4 = null != c4 && 0 == (2 & c4.__u);
if (null === c4 && null == e4 || a4 && e4 == c4.key && f4 == c4.type) return u5;
if (t4 > (a4 ? 1 : 0)) {
for (i4 = u5 - 1, r3 = u5 + 1; i4 >= 0 || r3 < l4.length; ) if (null != (c4 = l4[o3 = i4 >= 0 ? i4-- : r3++]) && 0 == (2 & c4.__u) && e4 == c4.key && f4 == c4.type) return o3;
}
return -1;
}
function z(n3, l4, u5) {
"-" == l4[0] ? n3.setProperty(l4, null == u5 ? "" : u5) : n3[l4] = null == u5 ? "" : "number" != typeof u5 || _.test(l4) ? u5 : u5 + "px";
}
function N(n3, l4, u5, t4, i4) {
var r3, o3;
n: if ("style" == l4) if ("string" == typeof u5) n3.style.cssText = u5;
else {
if ("string" == typeof t4 && (n3.style.cssText = t4 = ""), t4) for (l4 in t4) u5 && l4 in u5 || z(n3.style, l4, "");
if (u5) for (l4 in u5) t4 && u5[l4] == t4[l4] || z(n3.style, l4, u5[l4]);
}
else if ("o" == l4[0] && "n" == l4[1]) r3 = l4 != (l4 = l4.replace(s, "$1")), o3 = l4.toLowerCase(), l4 = o3 in n3 || "onFocusOut" == l4 || "onFocusIn" == l4 ? o3.slice(2) : l4.slice(2), n3.l || (n3.l = {}), n3.l[l4 + r3] = u5, u5 ? t4 ? u5[a] = t4[a] : (u5[a] = h, n3.addEventListener(l4, r3 ? v : p, r3)) : n3.removeEventListener(l4, r3 ? v : p, r3);
else {
if ("http://www.w3.org/2000/svg" == i4) l4 = l4.replace(/xlink(H|:h)/, "h").replace(/sName$/, "s");
else if ("width" != l4 && "height" != l4 && "href" != l4 && "list" != l4 && "form" != l4 && "tabIndex" != l4 && "download" != l4 && "rowSpan" != l4 && "colSpan" != l4 && "role" != l4 && "popover" != l4 && l4 in n3) try {
n3[l4] = null == u5 ? "" : u5;
break n;
} catch (n4) {
}
"function" == typeof u5 || (null == u5 || false === u5 && "-" != l4[4] ? n3.removeAttribute(l4) : n3.setAttribute(l4, "popover" == l4 && 1 == u5 ? "" : u5));
}
}
function V(n3) {
return function(u5) {
if (this.l) {
var t4 = this.l[u5.type + n3];
if (null == u5[c]) u5[c] = h++;
else if (u5[c] < t4[a]) return;
return t4(l.event ? l.event(u5) : u5);
}
};
}
function q(n3, u5, t4, i4, r3, o3, e4, f4, c4, a4) {
var s3, h4, p4, v3, y3, d3, _3, k3, x3, M3, I2, P4, A4, H3, T4, j4, F3 = u5.type;
if (void 0 !== u5.constructor) return null;
128 & t4.__u && (c4 = !!(32 & t4.__u), o3 = [f4 = u5.__e = t4.__e]), (s3 = l.__b) && s3(u5);
n: if ("function" == typeof F3) {
h4 = e4.length;
try {
if (x3 = u5.props, M3 = F3.prototype && F3.prototype.render, I2 = (s3 = F3.contextType) && i4[s3.__c], P4 = s3 ? I2 ? I2.props.value : s3.__ : i4, t4.__c ? k3 = (p4 = u5.__c = t4.__c).__ = p4.__E : (M3 ? u5.__c = p4 = new F3(x3, P4) : (u5.__c = p4 = new C(x3, P4), p4.constructor = F3, p4.render = Q), I2 && I2.sub(p4), p4.state || (p4.state = {}), p4.__n = i4, v3 = p4.__d = true, p4.__h = [], p4._sb = []), M3 && null == p4.__s && (p4.__s = p4.state), M3 && null != F3.getDerivedStateFromProps && (p4.__s == p4.state && (p4.__s = m({}, p4.__s)), m(p4.__s, F3.getDerivedStateFromProps(x3, p4.__s))), y3 = p4.props, d3 = p4.state, p4.__v = u5, v3) M3 && null == F3.getDerivedStateFromProps && null != p4.componentWillMount && p4.componentWillMount(), M3 && null != p4.componentDidMount && p4.__h.push(p4.componentDidMount);
else {
if (M3 && null == F3.getDerivedStateFromProps && x3 !== y3 && null != p4.componentWillReceiveProps && p4.componentWillReceiveProps(x3, P4), u5.__v == t4.__v || !p4.__e && null != p4.shouldComponentUpdate && false === p4.shouldComponentUpdate(x3, p4.__s, P4)) {
u5.__v != t4.__v && (p4.props = x3, p4.state = p4.__s, p4.__d = false), u5.__e = t4.__e, u5.__k = t4.__k, u5.__k.some(function(n4) {
n4 && (n4.__ = u5);
}), w.push.apply(p4.__h, p4._sb), p4._sb = [], p4.__h.length && e4.push(p4), f4 = $(t4);
break n;
}
null != p4.componentWillUpdate && p4.componentWillUpdate(x3, p4.__s, P4), M3 && null != p4.componentDidUpdate && p4.__h.push(function() {
p4.componentDidUpdate(y3, d3, _3);
});
}
if (p4.context = P4, p4.props = x3, p4.__P = n3, p4.__e = false, A4 = l.__r, H3 = 0, M3) p4.state = p4.__s, p4.__d = false, A4 && A4(u5), s3 = p4.render(p4.props, p4.state, p4.context), w.push.apply(p4.__h, p4._sb), p4._sb = [];
else do {
p4.__d = false, A4 && A4(u5), s3 = p4.render(p4.props, p4.state, p4.context), p4.state = p4.__s;
} while (p4.__d && ++H3 < 25);
p4.state = p4.__s, null != p4.getChildContext && (i4 = m(m({}, i4), p4.getChildContext())), M3 && !v3 && null != p4.getSnapshotBeforeUpdate && (_3 = p4.getSnapshotBeforeUpdate(y3, d3)), T4 = null != s3 && s3.type === S && null == s3.key ? E(s3.props.children) : s3, f4 = L(n3, g(T4) ? T4 : [T4], u5, t4, i4, r3, o3, e4, f4, c4, a4), p4.base = u5.__e, u5.__u &= -161, p4.__h.length && e4.push(p4), k3 && (p4.__E = p4.__ = null);
} catch (n4) {
if (e4.length = h4, u5.__v = null, c4 || null != o3) {
if (n4.then) {
for (u5.__u |= c4 ? 160 : 128; f4 && 8 == f4.nodeType && f4.nextSibling; ) f4 = f4.nextSibling;
null != o3 && (o3[o3.indexOf(f4)] = null), u5.__e = f4;
} else if (null != o3) for (j4 = o3.length; j4--; ) b(o3[j4]);
} else u5.__e = t4.__e;
null == u5.__k && (u5.__k = t4.__k || []), n4.then || B(u5), l.__e(n4, u5, t4);
}
} else null == o3 && u5.__v == t4.__v ? (u5.__k = t4.__k, u5.__e = t4.__e) : f4 = u5.__e = G(t4.__e, u5, t4, i4, r3, o3, e4, c4, a4);
return (s3 = l.diffed) && s3(u5), 128 & u5.__u ? void 0 : f4;
}
function B(n3) {
n3 && (n3.__c && (n3.__c.__e = true), n3.__k && n3.__k.some(B));
}
function D(n3, u5, t4) {
for (var i4 = 0; i4 < t4.length; i4++) J(t4[i4], t4[++i4], t4[++i4]);
l.__c && l.__c(u5, n3), n3.some(function(u6) {
try {
n3 = u6.__h, u6.__h = [], n3.some(function(n4) {
n4.call(u6);
});
} catch (n4) {
l.__e(n4, u6.__v);
}
});
}
function E(n3) {
return "object" != typeof n3 || null == n3 || n3.__b > 0 ? n3 : g(n3) ? n3.map(E) : void 0 !== n3.constructor ? null : m({}, n3);
}
function G(u5, t4, i4, r3, o3, e4, f4, c4, a4) {
var s3, h4, p4, v3, y3, w3, _3, m3 = i4.props || d, k3 = t4.props, x3 = t4.type;
if ("svg" == x3 ? o3 = "http://www.w3.org/2000/svg" : "math" == x3 ? o3 = "http://www.w3.org/1998/Math/MathML" : o3 || (o3 = "http://www.w3.org/1999/xhtml"), null != e4) {
for (s3 = 0; s3 < e4.length; s3++) if ((y3 = e4[s3]) && "setAttribute" in y3 == !!x3 && (x3 ? y3.localName == x3 : 3 == y3.nodeType)) {
u5 = y3, e4[s3] = null;
break;
}
}
if (null == u5) {
if (null == x3) return document.createTextNode(k3);
u5 = document.createElementNS(o3, x3, k3.is && k3), c4 && (l.__m && l.__m(t4, e4), c4 = false), e4 = null;
}
if (null == x3) m3 === k3 || c4 && u5.data == k3 || (u5.data = k3);
else {
if (e4 = "textarea" == x3 && null != k3.defaultValue ? null : e4 && n.call(u5.childNodes), !c4 && null != e4) for (m3 = {}, s3 = 0; s3 < u5.attributes.length; s3++) m3[(y3 = u5.attributes[s3]).name] = y3.value;
for (s3 in m3) y3 = m3[s3], "dangerouslySetInnerHTML" == s3 ? p4 = y3 : "children" == s3 || s3 in k3 || "value" == s3 && "defaultValue" in k3 || "checked" == s3 && "defaultChecked" in k3 || N(u5, s3, null, y3, o3);
for (s3 in k3) y3 = k3[s3], "children" == s3 ? v3 = y3 : "dangerouslySetInnerHTML" == s3 ? h4 = y3 : "value" == s3 ? w3 = y3 : "checked" == s3 ? _3 = y3 : c4 && "function" != typeof y3 || m3[s3] === y3 || N(u5, s3, y3, m3[s3], o3);
if (h4) c4 || p4 && (h4.__html == p4.__html || h4.__html == u5.innerHTML) || (u5.innerHTML = h4.__html), t4.__k = [];
else if (p4 && (u5.innerHTML = ""), L("template" == t4.type ? u5.content : u5, g(v3) ? v3 : [v3], t4, i4, r3, "foreignObject" == x3 ? "http://www.w3.org/1999/xhtml" : o3, e4, f4, e4 ? e4[0] : i4.__k && $(i4, 0), c4, a4), null != e4) for (s3 = e4.length; s3--; ) b(e4[s3]);
c4 && "textarea" != x3 || (s3 = "value", "progress" == x3 && null == w3 ? u5.removeAttribute("value") : null != w3 && (w3 !== u5[s3] || "progress" == x3 && !w3 || "option" == x3 && w3 != m3[s3]) && N(u5, s3, w3, m3[s3], o3), s3 = "checked", null != _3 && _3 != u5[s3] && N(u5, s3, _3, m3[s3], o3));
}
return u5;
}
function J(n3, u5, t4) {
try {
if ("function" == typeof n3) {
var i4 = "function" == typeof n3.__u;
i4 && n3.__u(), i4 && null == u5 || (n3.__u = n3(u5));
} else n3.current = u5;
} catch (n4) {
l.__e(n4, t4);
}
}
function K(n3, u5, t4) {
var i4, r3;
if (l.unmount && l.unmount(n3), (i4 = n3.ref) && (i4.current && i4.current != n3.__e || J(i4, null, u5)), null != (i4 = n3.__c)) {
if (i4.componentWillUnmount) try {
i4.componentWillUnmount();
} catch (n4) {
l.__e(n4, u5);
}
i4.base = i4.__P = i4.__n = null;
}
if (i4 = n3.__k) for (r3 = 0; r3 < i4.length; r3++) i4[r3] && K(i4[r3], u5, t4 || "function" != typeof n3.type);
t4 || b(n3.__e), n3.__c = n3.__ = n3.__e = void 0;
}
function Q(n3, l4, u5) {
return this.constructor(n3, u5);
}
function R(u5, t4, i4) {
var r3, o3, e4, f4;
t4 == document && (t4 = document.documentElement), l.__ && l.__(u5, t4), o3 = (r3 = "function" == typeof i4) ? null : i4 && i4.__k || t4.__k, e4 = [], f4 = [], q(t4, u5 = (!r3 && i4 || t4).__k = k(S, null, [u5]), o3 || d, d, t4.namespaceURI, !r3 && i4 ? [i4] : o3 ? null : t4.firstChild ? n.call(t4.childNodes) : null, e4, !r3 && i4 ? i4 : o3 ? o3.__e : t4.firstChild, r3, f4), D(e4, u5, f4), u5.props.children = null;
}
n = w.slice, l = { __e: function(n3, l4, u5, t4) {
for (var i4, r3, o3; l4 = l4.__; ) if ((i4 = l4.__c) && !i4.__) try {
if ((r3 = i4.constructor) && null != r3.getDerivedStateFromError && (i4.setState(r3.getDerivedStateFromError(n3)), o3 = i4.__d), null != i4.componentDidCatch && (i4.componentDidCatch(n3, t4 || {}), o3 = i4.__d), o3) return i4.__E = i4;
} catch (l5) {
n3 = l5;
}
throw n3;
} }, u = 0, t = function(n3) {
return null != n3 && void 0 === n3.constructor;
}, C.prototype.setState = function(n3, l4) {
var u5;
u5 = null != this.__s && this.__s != this.state ? this.__s : this.__s = m({}, this.state), "function" == typeof n3 && (n3 = n3(m({}, u5), this.props)), n3 && m(u5, n3), null != n3 && this.__v && (l4 && this._sb.push(l4), A(this));
}, C.prototype.forceUpdate = function(n3) {
this.__v && (this.__e = true, n3 && this.__h.push(n3), A(this));
}, C.prototype.render = S, i = [], o = "function" == typeof Promise ? Promise.prototype.then.bind(Promise.resolve()) : setTimeout, e = function(n3, l4) {
return n3.__v.__b - l4.__v.__b;
}, H.__r = 0, f = Math.random().toString(8), c = "__d" + f, a = "__a" + f, s = /(PointerCapture)$|Capture$/i, h = 0, p = V(false), v = V(true), y = 0;
// node_modules/preact/jsx-runtime/dist/jsxRuntime.module.js
var f2 = 0;
function u2(e4, t4, n3, o3, i4, u5) {
t4 || (t4 = {});
var a4, c4, p4 = t4;
if ("ref" in p4) for (c4 in p4 = {}, t4) "ref" == c4 ? a4 = t4[c4] : p4[c4] = t4[c4];
var l4 = { type: e4, props: p4, key: n3, ref: a4, __k: null, __: null, __b: 0, __e: null, __c: null, constructor: void 0, __v: --f2, __i: -1, __u: 0, __source: i4, __self: u5 };
if ("function" == typeof e4 && (a4 = e4.defaultProps)) for (c4 in a4) void 0 === p4[c4] && (p4[c4] = a4[c4]);
return l.vnode && l.vnode(l4), l4;
}
// src/planner/helpers/mount.jsx
function mount(App2, root, props) {
root.innerHTML = "";
R(/* @__PURE__ */ u2(App2, { ...props }), root);
root.style.position = "relative";
root.style.visibility = "visible";
}
var mount_default = mount;
// src/planner/SETTINGS.js
var WIDTH = 708;
var HEIGHT = 809;
var NONE = "NONE";
var NORTH = "NORTH";
var EAST = "EAST";
var SOUTH = "SOUTH";
var WEST = "WEST";
// node_modules/goober/dist/goober.modern.js
var e2 = { data: "" };
var t2 = (t4) => {
if ("object" == typeof window) {
let e4 = (t4 ? t4.querySelector("#_goober") : window._goober) || Object.assign(document.createElement("style"), { innerHTML: " ", id: "_goober" });
return e4.nonce = window.__nonce__, e4.parentNode || (t4 || document.head).appendChild(e4), e4.firstChild;
}
return t4 || e2;
};
var a2 = /(?:([\u0080-\uFFFF\w-%@]+) *:? *([^{;]+?);|([^;}{]*?) *{)|(}\s*)/g;
var l2 = /\/\*[^]*?\*\/| +/g;
var n2 = /\n+/g;
var o2 = (e4, t4) => {
let r3 = "", a4 = "", l4 = "";
for (let n3 in e4) {
let c4 = e4[n3];
"@" == n3[0] ? "i" == n3[1] ? r3 = n3 + " " + c4 + ";" : a4 += "f" == n3[1] ? o2(c4, n3) : n3 + "{" + o2(c4, "k" == n3[1] ? "" : t4) + "}" : "object" == typeof c4 ? a4 += o2(c4, t4 ? t4.replace(/([^,])+/g, (e5) => n3.replace(/([^,]*:\S+\([^)]*\))|([^,])+/g, (t5) => /&/.test(t5) ? t5.replace(/&/g, e5) : e5 ? e5 + " " + t5 : t5)) : n3) : null != c4 && (n3 = "-" == n3[1] ? n3 : n3.replace(/[A-Z]/g, "-$&").toLowerCase(), l4 += o2.p ? o2.p(n3, c4) : n3 + ":" + c4 + ";");
}
return r3 + (t4 && l4 ? t4 + "{" + l4 + "}" : l4) + a4;
};
var c2 = {};
var i2 = (e4) => {
if ("object" == typeof e4) {
let t4 = "";
for (let r3 in e4) t4 += r3 + i2(e4[r3]);
return t4;
}
return e4;
};
var s2 = (e4, t4, r3, s3, p4) => {
let u5 = i2(e4), d3 = c2[u5] || (c2[u5] = ((e5) => {
let t5 = 0, r4 = 11;
for (; t5 < e5.length; ) r4 = 101 * r4 + e5.charCodeAt(t5++) >>> 0;
return "go" + r4;
})(u5));
if (!c2[d3]) {
let t5 = u5 !== e4 ? e4 : ((e5) => {
let t6, r4, o3 = [{}];
for (; t6 = a2.exec(e5.replace(l2, "")); ) t6[4] ? o3.shift() : t6[3] ? (r4 = t6[3].replace(n2, " ").trim(), o3.unshift(o3[0][r4] = o3[0][r4] || {})) : o3[0][t6[1]] = t6[2].replace(n2, " ").trim();
return o3[0];
})(e4);
c2[d3] = o2(p4 ? { ["@keyframes " + d3]: t5 } : t5, r3 ? "" : "." + d3);
}
let f4 = r3 && c2.g;
return r3 && (c2.g = c2[d3]), ((e5, t5, r4, a4) => {
a4 ? t5.data = t5.data.replace(a4, e5) : -1 === t5.data.indexOf(e5) && (t5.data = r4 ? e5 + t5.data : t5.data + e5);
})(c2[d3], t4, s3, f4), d3;
};
var p2 = (e4, t4, r3) => e4.reduce((e5, a4, l4) => {
let n3 = t4[l4];
if (n3 && n3.call) {
let e6 = n3(r3), t5 = e6 && e6.props && e6.props.className || /^go/.test(e6) && e6;
n3 = t5 ? "." + t5 : e6 && "object" == typeof e6 ? e6.props ? "" : o2(e6, "") : false === e6 ? "" : e6;
}
return e5 + a4 + (null == n3 ? "" : n3);
}, "");
function u3(e4) {
let r3 = this || {}, a4 = e4.call ? e4(r3.p) : e4;
return s2(a4.unshift ? a4.raw ? p2(a4, [].slice.call(arguments, 1), r3.p) : a4.reduce((e5, t4) => Object.assign(e5, t4 && t4.call ? t4(r3.p) : t4), {}) : a4, t2(r3.target), r3.g, r3.o, r3.k);
}
var b2 = u3.bind({ g: 1 });
var h2 = u3.bind({ k: 1 });
// node_modules/preact/hooks/dist/hooks.module.js
var t3;
var r2;
var u4;
var i3;
var f3 = [];
var c3 = l;
var e3 = c3.__b;
var a3 = c3.__r;
var v2 = c3.diffed;
var l3 = c3.__c;
var m2 = c3.unmount;
var p3 = c3.__;
function j2() {
for (var n3; n3 = f3.shift(); ) {
var t4 = n3.__H;
if (n3.__P && t4) try {
t4.__h.some(z2), t4.__h.some(B2), t4.__h = [];
} catch (r3) {
t4.__h = [], c3.__e(r3, n3.__v);
}
}
}
c3.__b = function(n3) {
r2 = null, e3 && e3(n3);
}, c3.__ = function(n3, t4) {
n3 && t4.__k && t4.__k.__m && (n3.__m = t4.__k.__m), p3 && p3(n3, t4);
}, c3.__r = function(n3) {
a3 && a3(n3), t3 = 0;
var i4 = (r2 = n3.__c).__H;
i4 && (u4 === r2 ? (i4.__h = [], r2.__h = [], i4.__.some(function(n4) {
n4.__N && (n4.__ = n4.__N), n4.u = n4.__N = void 0;
})) : (i4.__h.some(z2), i4.__h.some(B2), i4.__h = [], t3 = 0)), u4 = r2;
}, c3.diffed = function(n3) {
v2 && v2(n3);
var t4 = n3.__c;
t4 && t4.__H && (t4.__H.__h.length && (1 !== f3.push(t4) && i3 === c3.requestAnimationFrame || ((i3 = c3.requestAnimationFrame) || w2)(j2)), t4.__H.__.some(function(n4) {
n4.u && (n4.__H = n4.u, n4.u = void 0);
})), u4 = r2 = null;
}, c3.__c = function(n3, t4) {
t4.some(function(n4) {
try {
n4.__h.some(z2), n4.__h = n4.__h.filter(function(n5) {
return !n5.__ || B2(n5);
});
} catch (r3) {
t4.some(function(n5) {
n5.__h && (n5.__h = []);
}), t4 = [], c3.__e(r3, n4.__v);
}
}), l3 && l3(n3, t4);
}, c3.unmount = function(n3) {
m2 && m2(n3);
var t4, r3 = n3.__c;
r3 && r3.__H && (r3.__H.__.some(function(n4) {
try {
z2(n4);
} catch (n5) {
t4 = n5;
}
}), r3.__H = void 0, t4 && c3.__e(t4, r3.__v));
};
var k2 = "function" == typeof requestAnimationFrame;
function w2(n3) {
var t4, r3 = function() {
clearTimeout(u5), k2 && cancelAnimationFrame(t4), setTimeout(n3);
}, u5 = setTimeout(r3, 35);
k2 && (t4 = requestAnimationFrame(r3));
}
function z2(n3) {
var t4 = r2, u5 = n3.__c;
"function" == typeof u5 && (n3.__c = void 0, u5()), r2 = t4;
}
function B2(n3) {
var t4 = r2;
n3.__c = n3.__(), r2 = t4;
}
// node_modules/preact/compat/dist/compat.module.js
function g3(n3, t4) {
for (var e4 in t4) n3[e4] = t4[e4];
return n3;
}
function E2(n3, t4) {
for (var e4 in n3) if ("__source" !== e4 && !(e4 in t4)) return true;
for (var r3 in t4) if ("__source" !== r3 && n3[r3] !== t4[r3]) return true;
return false;
}
function M2(n3, t4) {
this.props = n3, this.context = t4;
}
(M2.prototype = new C()).isPureReactComponent = true, M2.prototype.shouldComponentUpdate = function(n3, t4) {
return E2(this.props, n3) || E2(this.state, t4);
};
var T3 = l.__b;
l.__b = function(n3) {
n3.type && n3.type.__f && n3.ref && (n3.props.ref = n3.ref, n3.ref = null), T3 && T3(n3);
};
var A3 = "undefined" != typeof Symbol && Symbol.for && /* @__PURE__ */ Symbol.for("react.forward_ref") || 3911;
var O2 = l.__e;
l.__e = function(n3, t4, e4, r3) {
if (n3.then) {
for (var u5, o3 = t4; o3 = o3.__; ) if ((u5 = o3.__c) && u5.__c) return null == t4.__e && (t4.__e = e4.__e, t4.__k = e4.__k || []), u5.__c(n3, t4);
}
O2(n3, t4, e4, r3);
};
var U2 = l.unmount;
function V2(n3, t4, e4) {
return n3 && (n3.__c && n3.__c.__H && (n3.__c.__H.__.forEach(function(n4) {
"function" == typeof n4.__c && n4.__c();
}), n3.__c.__H = null), null != (n3 = g3({}, n3)).__c && (n3.__c.__P === e4 && (n3.__c.__P = t4), n3.__c.__e = true, n3.__c = null), n3.__k = n3.__k && n3.__k.map(function(n4) {
return V2(n4, t4, e4);
})), n3;
}
function W2(n3, t4, e4) {
return n3 && e4 && (n3.__v = null, n3.__k = n3.__k && n3.__k.map(function(n4) {
return W2(n4, t4, e4);
}), n3.__c && n3.__c.__P === t4 && (n3.__e && e4.appendChild(n3.__e), n3.__c.__e = true, n3.__c.__P = e4)), n3;
}
function P3() {
this.__u = 0, this.o = null, this.__b = null;
}
function j3(n3) {
var t4 = n3.__ && n3.__.__c;
return t4 && t4.__a && t4.__a(n3);
}
function B3() {
this.i = null, this.l = null;
}
l.unmount = function(n3) {
var t4 = n3.__c;
t4 && (t4.__z = true), t4 && t4.__R && t4.__R(), t4 && 32 & n3.__u && (n3.type = null), U2 && U2(n3);
}, (P3.prototype = new C()).__c = function(n3, t4) {
var e4 = t4.__c, r3 = this;
null == r3.o && (r3.o = []), r3.o.push(e4);
var u5 = j3(r3.__v), o3 = false, i4 = function() {
o3 || r3.__z || (o3 = true, e4.__R = null, u5 ? u5(f4) : f4());
};
e4.__R = i4;
var l4 = e4.__P;
e4.__P = null;
var f4 = function() {
if (!--r3.__u) {
if (r3.state.__a) {
var n4 = r3.state.__a;
r3.__v.__k[0] = W2(n4, n4.__c.__P, n4.__c.__O);
}
var t5;
for (r3.setState({ __a: r3.__b = null }); t5 = r3.o.pop(); ) t5.__P = l4, t5.forceUpdate();
}
};
r3.__u++ || 32 & t4.__u || r3.setState({ __a: r3.__b = r3.__v.__k[0] }), n3.then(i4, i4);
}, P3.prototype.componentWillUnmount = function() {
this.o = [];
}, P3.prototype.render = function(n3, e4) {
if (this.__b) {
if (this.__v.__k) {
var r3 = document.createElement("div"), o3 = this.__v.__k[0].__c;
this.__v.__k[0] = V2(this.__b, r3, o3.__O = o3.__P);
}
this.__b = null;
}
var i4 = e4.__a && k(S, null, n3.fallback);
return i4 && (i4.__u &= -33), [k(S, null, e4.__a ? null : n3.children), i4];
};
var H2 = function(n3, t4, e4) {
if (++e4[1] === e4[0] && n3.l.delete(t4), n3.props.revealOrder && ("t" !== n3.props.revealOrder[0] || !n3.l.size)) for (e4 = n3.i; e4; ) {
for (; e4.length > 3; ) e4.pop()();
if (e4[1] < e4[0]) break;
n3.i = e4 = e4[2];
}
};
function Z(n3) {
return this.getChildContext = function() {
return n3.context;
}, n3.children;
}
function Y(n3) {
var e4 = this, r3 = n3.h;
if (e4.componentWillUnmount = function() {
R(null, e4.v), e4.v = null, e4.h = null;
}, e4.h && e4.h !== r3 && e4.componentWillUnmount(), !e4.v) {
for (var u5 = e4.__v; null !== u5 && !u5.__m && null !== u5.__; ) u5 = u5.__;
e4.h = r3, e4.v = { nodeType: 1, parentNode: r3, childNodes: [], __k: { __m: u5.__m }, contains: function() {
return true;
}, namespaceURI: r3.namespaceURI, insertBefore: function(n4, t4) {
this.childNodes.push(n4), e4.h.insertBefore(n4, t4);
}, removeChild: function(n4) {
this.childNodes.splice(this.childNodes.indexOf(n4) >>> 1, 1), e4.h.removeChild(n4);
} };
}
R(k(Z, { context: e4.context }, n3.__v), e4.v);
}
function $2(n3, e4) {
var r3 = k(Y, { __v: n3, h: e4 });
return r3.containerInfo = e4, r3;
}
(B3.prototype = new C()).__a = function(n3) {
var t4 = this, e4 = j3(t4.__v), r3 = t4.l.get(n3);
return r3[0]++, function(u5) {
var o3 = function() {
t4.props.revealOrder ? (r3.push(u5), H2(t4, n3, r3)) : u5();
};
e4 ? e4(o3) : o3();
};
}, B3.prototype.render = function(n3) {
this.i = null, this.l = /* @__PURE__ */ new Map();
var t4 = F(n3.children);
n3.revealOrder && "b" === n3.revealOrder[0] && t4.reverse();
for (var e4 = t4.length; e4--; ) this.l.set(t4[e4], this.i = [1, 0, this.i]);
return n3.children;
}, B3.prototype.componentDidUpdate = B3.prototype.componentDidMount = function() {
var n3 = this;
this.l.forEach(function(t4, e4) {
H2(n3, e4, t4);
});
};
var q3 = "undefined" != typeof Symbol && Symbol.for && /* @__PURE__ */ Symbol.for("react.element") || 60103;
var G2 = /^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|dominant|fill|flood|font|glyph(?!R)|horiz|image(!S)|letter|lighting|marker(?!H|W|U)|overline|paint|pointer|shape|stop|strikethrough|stroke|text(?!L)|transform|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/;
var J2 = /^on(Ani|Tra|Tou|BeforeInp|Compo)/;
var K2 = /[A-Z0-9]/g;
var Q2 = "undefined" != typeof document;
var X2 = function(n3) {
return ("undefined" != typeof Symbol && "symbol" == typeof /* @__PURE__ */ Symbol() ? /fil|che|rad/ : /fil|che|ra/).test(n3);
};
C.prototype.isReactComponent = true, ["componentWillMount", "componentWillReceiveProps", "componentWillUpdate"].forEach(function(t4) {
Object.defineProperty(C.prototype, t4, { configurable: true, get: function() {
return this["UNSAFE_" + t4];
}, set: function(n3) {
Object.defineProperty(this, t4, { configurable: true, writable: true, value: n3 });
} });
});
var en = l.event;
l.event = function(n3) {
return en && (n3 = en(n3)), n3.persist = function() {
}, n3.isPropagationStopped = function() {
return this.cancelBubble;
}, n3.isDefaultPrevented = function() {
return this.defaultPrevented;
}, n3.nativeEvent = n3;
};
var rn;
var un = { configurable: true, get: function() {
return this.class;
} };
var on = l.vnode;
l.vnode = function(n3) {
"string" == typeof n3.type && (function(n4) {
var t4 = n4.props, e4 = n4.type, u5 = {}, o3 = -1 == e4.indexOf("-");
for (var i4 in t4) {
var l4 = t4[i4];
if (!("value" === i4 && "defaultValue" in t4 && null == l4 || Q2 && "children" === i4 && "noscript" === e4 || "class" === i4 || "className" === i4)) {
var f4 = i4.toLowerCase();
"defaultValue" === i4 && "value" in t4 && null == t4.value ? i4 = "value" : "download" === i4 && true === l4 ? l4 = "" : "translate" === f4 && "no" === l4 ? l4 = false : "o" === f4[0] && "n" === f4[1] ? "ondoubleclick" === f4 ? i4 = "ondblclick" : "onchange" !== f4 || "input" !== e4 && "textarea" !== e4 || X2(t4.type) ? "onfocus" === f4 ? i4 = "onfocusin" : "onblur" === f4 ? i4 = "onfocusout" : J2.test(i4) && (i4 = f4) : f4 = i4 = "oninput" : o3 && G2.test(i4) ? i4 = i4.replace(K2, "-$&").toLowerCase() : null === l4 && (l4 = void 0), "oninput" === f4 && u5[i4 = f4] && (i4 = "oninputCapture"), u5[i4] = l4;
}
}
"select" == e4 && (u5.multiple && Array.isArray(u5.value) && (u5.value = F(t4.children).forEach(function(n5) {
n5.props.selected = -1 != u5.value.indexOf(n5.props.value);
})), null != u5.defaultValue && (u5.value = F(t4.children).forEach(function(n5) {
n5.props.selected = u5.multiple ? -1 != u5.defaultValue.indexOf(n5.props.value) : u5.defaultValue == n5.props.value;
}))), t4.class && !t4.className ? (u5.class = t4.class, Object.defineProperty(u5, "className", un)) : t4.className && (u5.class = u5.className = t4.className), n4.props = u5;
})(n3), n3.$$typeof = q3, on && on(n3);
};
var ln = l.__r;
l.__r = function(n3) {
ln && ln(n3), rn = n3.__c;
};
var fn = l.diffed;
l.diffed = function(n3) {
fn && fn(n3);
var t4 = n3.props, e4 = n3.__e;
null != e4 && "textarea" === n3.type && "value" in t4 && t4.value !== e4.value && (e4.value = null == t4.value ? "" : t4.value), rn = null;
};
// src/planner/utils/cn.js
function cn(...classes) {
return classes.filter(Boolean).join(" ");
}
var cn_default = cn;
// src/planner/components/Panel.jsx
var SIZE = 12;
var HALF = SIZE / 2;
var ROOT = u3`
position: absolute;
top: 324px;
left: 452px;
z-index: 100;
filter: drop-shadow(0 0 0.3rem black);
`;
var ARROW = u3`
position: absolute;
top: -${HALF}px;
left: -${HALF}px;
width: ${SIZE}px;
height: ${SIZE}px;
background-color: #bcb096;
`;
var ARROW_PLACEMENT = {
[NORTH]: u3`
clip-path: polygon(50% 50%, 0 0, 100% 0);
`,
[EAST]: u3`
clip-path: polygon(50% 50%, 100% 0, 100% 100%);
`,
[SOUTH]: u3`
clip-path: polygon(50% 50%, 100% 100%, 0% 100%);
`,
[WEST]: u3`
clip-path: polygon(50% 50%, 0 100%, 0 0);
`
};
var BOX = u3`
position: absolute;
width: max-content;
border: solid 1px #bcb096;
border-radius: 8px;
`;
var DEFAULT_WAY = NORTH;
var DEFAULT_OFFSET = "50%";
var Panel = class extends M2 {
vars = {
rootRef: M(),
boxRef: M()
};
state = {
left: void 0,
right: void 0,
top: void 0,
bottom: void 0
};
render() {
const { className, rootRef, boxRef, boxClassName, children, maxWidth, way = DEFAULT_WAY } = this.props;
const kids = Array.isArray(children) ? children : [children];
const { left, right, top, bottom } = this.state;
const usedRootRef = rootRef || this.vars.rootRef;
const usedBoxRef = boxRef || this.vars.boxRef;
return /* @__PURE__ */ u2("div", { class: cn_default(ROOT, className), ref: usedRootRef, children: [
/* @__PURE__ */ u2("div", { ref: usedBoxRef, class: cn_default(BOX, boxClassName), style: { maxWidth, left, right, top, bottom }, children: [
...kids
] }),
/* @__PURE__ */ u2("div", { class: cn_default(ARROW, ARROW_PLACEMENT[way]) })
] });
}
componentDidMount() {
this.refreshBoxOffset();
window.addEventListener("resize", this.onWindowResize);
}
componentDidUpdate() {
this.refreshBoxOffset();
}
componentWillUnmount() {
window.removeEventListener("resize", this.onWindowResize);
}
// -----------------------------------------------------------------------------------------------------------------
// P R I V A T E
// -----------------------------------------------------------------------------------------------------------------
onWindowResize = () => {
this.refreshBoxOffset();
};
refreshBoxOffset = () => {
const { way = DEFAULT_WAY, offset = DEFAULT_OFFSET, rootRef, boxRef } = this.props;
const rootElement = (rootRef || this.vars.rootRef).current;
const boxElement = (boxRef || this.vars.boxRef).current;
const offsetValue = resolveOffset(offset, boxElement, way);
let coordinates;
switch (way) {
case NORTH:
coordinates = { left: -offsetValue, top: -HALF - boxElement.offsetHeight };
break;
case SOUTH:
coordinates = { left: -offsetValue, top: HALF };
break;
case EAST:
coordinates = { left: HALF, top: -offsetValue };
break;
case WEST:
coordinates = { left: -HALF - boxElement.offsetWidth, top: -offsetValue };
break;
default:
}
const imprisoned = imprisonCoordinates(coordinates, boxElement, rootElement);
this.setState(imprisoned);
};
};
function resolveOffset(offset, element, way) {
if (typeof offset === "number") {
return offset;
}
const percent = Number(offset.match(/\d+/)[0]);
switch (way) {
case NORTH:
// fall
case SOUTH:
return Math.round(element.offsetWidth * percent / 100);
case EAST:
// fall
case WEST:
return Math.round(element.offsetHeight * percent / 100);
default:
return 0;
}
}
function imprisonCoordinates(coordinates, boxElement, rootElement) {
const boxBounds = boxElement.getBoundingClientRect();
const rootBounds = rootElement.getBoundingClientRect();
const scaleRatio = boxBounds.width / boxElement.offsetWidth;
const futureRightmostBound = rootBounds.left + boxBounds.width + coordinates.left * scaleRatio;
const overflowRight = futureRightmostBound - (window.innerWidth - 20);
if (overflowRight > 0) {
return {
left: coordinates.left - overflowRight / scaleRatio,
top: coordinates.top
};
}
const futureLeftmostBound = rootBounds.left + coordinates.left * scaleRatio;
const overflowLeft = 5 - futureLeftmostBound;
if (overflowLeft > 0) {
return {
left: coordinates.left + overflowLeft / scaleRatio,
top: coordinates.top
};
}
return coordinates;
}
var Panel_default = Panel;
// src/planner/components/HintContent.jsx
var ROOT2 = u3`
padding: 6px 8px;
`;
var TITLE = u3`
font-weight: bold;
color: #d6bc7c;
padding-bottom: 4px;
`;
var TEXT = u3`
color: #fff;
`;
var HintContent = class extends C {
render() {
const { title, text } = this.props;
return /* @__PURE__ */ u2("div", { class: ROOT2, children: [
title && /* @__PURE__ */ u2("div", { class: TITLE, children: title }),
text && /* @__PURE__ */ u2("div", { class: TEXT, dangerouslySetInnerHTML: { __html: text } })
] });
}
};
var HintContent_default = HintContent;
// src/planner/components/Hint.jsx
var ROOT3 = u3`
position: relative;
line-height: 0;
`;
var PANEL = u3`
position: fixed;
pointer-events: none;
z-index: 9999;
`;
var BOX2 = u3`
background: #191b2c;
border-radius: 4px;
`;
var Hint = class extends C {
vars = {
triggerRef: M(),
panelRef: M()
};
state = {
isOpen: false
};
render() {
const { text, title, way = NORTH, children, hintClassName } = this.props;
const { isOpen } = this.state;
const kids = Array.isArray(children) ? children : [children];
return /* @__PURE__ */ u2(
"div",
{
class: ROOT3,
ref: this.vars.triggerRef,
onPointerEnter: this.onRootPointerEnter,
onPointerLeave: this.onRootPointerLeave,
children: [
kids[0],
isOpen && Boolean(title || text) && $2(
/* @__PURE__ */ u2(
Panel_default,
{
rootRef: this.vars.panelRef,
className: cn_default(PANEL, hintClassName),
boxClassName: BOX2,
way,
maxWidth: 320,
children: /* @__PURE__ */ u2(HintContent_default, { title, text })
}
),
document.body
)
]
}
);
}
componentDidUpdate() {
if (this.state.isOpen) {
this.refreshPanelPosition();
}
}
// -----------------------------------------------------------------------------------------------------------------
// P R I V A T E
// -----------------------------------------------------------------------------------------------------------------
onRootPointerEnter = () => {
this.setState({ isOpen: true });
};
onRootPointerLeave = () => {
this.setState({ isOpen: false });
};
refreshPanelPosition = () => {
const panelElement = this.vars.panelRef.current;
if (!panelElement) {
return;
}
const triggerElement = this.vars.triggerRef.current;
const b3 = triggerElement.getBoundingClientRect();
const { way = NORTH } = this.props;
switch (way) {
case NORTH:
panelElement.style.left = Math.round(b3.x + b3.width / 2) + "px";
panelElement.style.top = Math.round(b3.y) + "px";
break;
case SOUTH:
panelElement.style.left = Math.round(b3.x + b3.width / 2) + "px";
panelElement.style.top = Math.round(b3.y + b3.height) + "px";
break;
case EAST:
panelElement.style.left = Math.round(b3.x + b3.width) + "px";
panelElement.style.top = Math.round(b3.y + b3.height / 2) + "px";
break;
case WEST:
panelElement.style.left = Math.round(b3.x) + "px";
panelElement.style.top = Math.round(b3.y + b3.height / 2) + "px";
break;
default:
}
};
};
var Hint_default = Hint;
// src/planner/components/Menu.jsx
var BOX3 = u3`
background: #1f3756;
overflow: auto;
& > * {
display: inline-block;
}
& [data-id=${NONE}] {
padding: 16px;
}
`;
var ICON = u3`
width: 56px;
cursor: pointer;
`;
var Menu = class extends C {
vars = {
boxRef: M(),
timeout: null
};
render() {
const { list, className, boxClassName, way, offset, maxWidth } = this.props;
return /* @__PURE__ */ u2(
Panel_default,
{
className,
boxRef: this.vars.boxRef,
boxClassName: cn_default(BOX3, boxClassName),
way,
offset,
maxWidth,
children: Object.values(list).map((item) => {
const { Component } = item;
if (Component) {
return /* @__PURE__ */ u2(Component, { ...item, onClick: this.onIconClick });
}
return /* @__PURE__ */ u2(Hint_default, { title: item.name, text: item.description, children: /* @__PURE__ */ u2(
"img",
{
class: ICON,
src: item.icon,
"data-id": item.id,
onClick: this.onIconClick
},
item.id
) });
})
}
);
}
componentDidMount() {
this.vars.timeout = setTimeout(this.listenForClose, 100);
}
componentWillUnmount() {
window.removeEventListener("click", this.onWindowClick);
clearTimeout(this.vars.timeout);
this.vars = null;
}
// -----------------------------------------------------------------------------------------------------------------
// P R I V A T E
// -----------------------------------------------------------------------------------------------------------------
/**
*
*/
listenForClose = () => {
window.addEventListener("click", this.onWindowClick);
};
/**
*
*/
onWindowClick = (event) => {
const boxElement = this.vars.boxRef.current;
const { target } = event;
if (target instanceof Node && boxElement.contains(target)) {
return;
}
this.props.onChoice();
};
/**
*
*/
onIconClick = (event) => {
this.props.onChoice(event.currentTarget.dataset.id);
};
};
var Menu_default = Menu;
// src/planner/components/Portrait.jsx
var ROOT_CSS = u3`
position: absolute;
left: 0;
top: 0;
`;
var PIC_CSS = u3`
width: 100%;
`;
var MEDALLION_CSS = u3`
position: absolute;
left: 0;
top: -5px;
width: 140px;
height: 140px;
border-bottom-left-radius: 50%;
border-bottom-right-radius: 50%;
-webkit-mask: url(#compoundMask);
mask: url(#compoundMask);
cursor: pointer;
/*background: red;*/
/*filter: drop-shadow(0 0 2px rgba(255,255,255,0.5));*/
`;
var MENU = u3`
left: 152px;
top: 84px;
max-height: 681px;
`;
var Portrait = class extends C {
state = {
isOpen: false
};
render() {
const { hero, heroes } = this.props;
const { isOpen } = this.state;
return /* @__PURE__ */ u2("div", { className: ROOT_CSS, children: [
/* @__PURE__ */ u2("div", { className: MEDALLION_CSS, onClick: this.onMedallionClick, children: [
/* @__PURE__ */ u2("svg", { width: "0", height: "0", style: "position:absolute", children: /* @__PURE__ */ u2("defs", { children: /* @__PURE__ */ u2("mask", { id: "compoundMask", maskContentUnits: "objectBoundingBox", children: [
/* @__PURE__ */ u2("rect", { x: "0", y: "0", width: "1", height: "0.55", fill: "white" }),
/* @__PURE__ */ u2("circle", { cx: "0.54", cy: "0.58", r: "0.41", fill: "white" })
] }) }) }),
hero && /* @__PURE__ */ u2("img", { className: PIC_CSS, src: heroes[hero].portrait })
] }),
isOpen && /* @__PURE__ */ u2(
Menu_default,
{
className: MENU,
maxWidth: 508,
way: EAST,
offset: 70,
list: heroes,
onChoice: this.onMenuChoice
}
)
] });
}
// -----------------------------------------------------------------------------------------------------------------
// P R I V A T E
// -----------------------------------------------------------------------------------------------------------------
/**
*
*/
onMedallionClick = () => {
if (!this.state.isOpen) {
this.setState({ isOpen: true });
}
};
/**
*
*/
onMenuChoice = (choice) => {
console.log("choice:", choice);
this.setState({ isOpen: false });
if (choice && choice !== this.props.hero) {
this.props.onHeroChange(choice);
}
};
};
var Portrait_default = Portrait;
// src/planner/components/Level.jsx
var ROOT_CSS2 = u3`
position: absolute;
left: 29px;
top: 90px;
transform: scale(0.5);
border-radius: 50%;
cursor: pointer;
`;
var Level = class extends C {
render() {
const { src } = this.props;
return /* @__PURE__ */ u2("img", { className: ROOT_CSS2, src });
}
// -----------------------------------------------------------------------------------------------------------------
// P R I V A T E
// -----------------------------------------------------------------------------------------------------------------
};
var Level_default = Level;
// src/planner/helpers/compression/SETTINGS.js
var WIKI_URL = "https://wiki.hoodedhorse.com/Heroes_of_Might_and_Magic_Olden_Era/";
var SYMBOLS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var FIELD_INDEX_BITS = 6;
// src/planner/helpers/compression/DICTIONARY.js
var DICTIONARY = {
heroes: [
"human_hero_1",
"human_hero_2",
"human_hero_3",
"human_hero_4",
"human_hero_5",
"human_hero_6",
"human_hero_7",
"human_hero_8",
"human_hero_9",
"human_hero_10",
"human_hero_11",
"human_hero_12",
"human_hero_13",
"human_hero_14",
"human_hero_15",
"human_hero_16",
"human_hero_17",
"human_hero_18",
"necro_hero_1",
"necro_hero_2",
"necro_hero_3",
"necro_hero_4",
"necro_hero_5",
"necro_hero_6",
"necro_hero_7",
"necro_hero_8",
"necro_hero_9",
"necro_hero_10",
"necro_hero_11",
"necro_hero_12",
"necro_hero_13",
"necro_hero_14",
"necro_hero_15",
"necro_hero_16",
"necro_hero_17",
"necro_hero_18",
"nature_hero_1",
"nature_hero_2",
"nature_hero_3",
"nature_hero_4",
"nature_hero_5",
"nature_hero_6",
"nature_hero_7",
"nature_hero_8",
"nature_hero_9",
"nature_hero_10",
"nature_hero_11",
"nature_hero_12",
"nature_hero_13",
"nature_hero_14",
"nature_hero_15",
"nature_hero_16",
"nature_hero_17",
"nature_hero_18",
"demon_hero_1",
"demon_hero_18",
"demon_hero_2",
"demon_hero_3",
"demon_hero_4",
"demon_hero_5",
"demon_hero_7",
"demon_hero_8",
"demon_hero_9",
"demon_hero_10",
"demon_hero_11",
"demon_hero_12",
"demon_hero_13",
"demon_hero_14",
"demon_hero_15",
"demon_hero_16",
"demon_hero_17",
"demon_hero_6",
"unfrozen_hero_1",
"unfrozen_hero_2",
"unfrozen_hero_3",
"unfrozen_hero_4",
"unfrozen_hero_5",
"unfrozen_hero_6",
"unfrozen_hero_7",
"unfrozen_hero_8",
"unfrozen_hero_9",
"unfrozen_hero_10",
"unfrozen_hero_11",
"unfrozen_hero_12",
"unfrozen_hero_13",
"unfrozen_hero_14",
"unfrozen_hero_15",
"unfrozen_hero_16",
"unfrozen_hero_17",
"unfrozen_hero_18",
"dungeon_hero_1",
"dungeon_hero_2",
"dungeon_hero_3",
"dungeon_hero_4",
"dungeon_hero_5",
"dungeon_hero_6",
"dungeon_hero_7",
"dungeon_hero_8",
"dungeon_hero_9",
"dungeon_hero_10",
"dungeon_hero_11",
"dungeon_hero_12",
"dungeon_hero_13",
"dungeon_hero_14",
"dungeon_hero_15",
"dungeon_hero_16",
"dungeon_hero_17",
"dungeon_hero_18"
],
skills: [
"skill_assault",
"skill_protection",
"skill_leadership",
"skill_luck",
"skill_resistance",
"skill_tactics",
"skill_formation",
"skill_siege",
"skill_trainer",
"skill_battle_artistry",
"skill_battlemage",
"skill_sorcery",
"skill_summoner",
"skill_mastery",
"skill_magic_day",
"skill_magic_night",
"skill_magic_space",
"skill_magic_primal",
"skill_wisdom",
"skill_diplomacy",
"skill_logistic",
"skill_scouting",
"skill_enlightenment",
"skill_economy",
"skill_faction_humans",
"skill_faction_undead",
"skill_faction_nature",
"skill_faction_demons",
"skill_faction_unfrozen",
"skill_faction_dungeon"
],
artifactSword: [
"paupers_glory_dumb_club_artifact",
"duelists_pride_rapier_artifact",
"knights_honor_lance_artifact",
"ogres_club_of_havoc_artifact",
"power_of_the_dragon_father_red_dragon_flame_tongue_artifact",
"garotte_artifact",
"living_arrows_shroomwood_bow_artifact",
"rule_of_shadow_the_truthmaker_artifact",
"shadow_of_death_dark_hatchet_artifact",
"shamaniac_soul_shaman_staff_artifact",
"angelic_alliance_sword_of_judgement_artifact",
"beelzebubs_blessing_demon_claw_artifact",
"excalibur_artifact"
],
artifactShield: [
"duelists_pride_buckler_artifact",
"inner_song_singing_pan_pipe_artifact",
"knights_honor_misericorde_artifact",
"shoddy_shield_artifact",
"caduceus_artifact",
"ethereal_knowledge_glass_dagger_artifact",
"fine_wand_artifact",
"hourglass_of_protection_artifact",
"tarq_of_the_rampaging_ogre_artifact",
"power_of_the_dragon_father_dragon_scale_shield_artifact",
"rule_of_shadow_the_truthseeker_artifact",
"angelic_alliance_lions_shield_of_courage_artifact",
"beelzebubs_blessing_chitinous_shield_artifact"
],
artifactArmor: [
"chain_mail_artifact",
"paupers_glory_rags_artifact",
"eagle_armor_artifact",
"ethereal_knowledge_vortex_dress_artifact",
"knights_honor_plate_armor_artifact",
"tunic_of_the_cyclops_king_artifact",
"clothes_of_enlightenment_artifact",
"shadow_of_death_cursed_armor_artifact",
"shamaniac_soul_iridescent_cloak_artifact",
"angelic_alliance_armor_of_wonder_artifact",
"beelzebubs_blessing_heartbeat_artifact",
"power_of_the_dragon_father_dragon_scale_armor_artifact"
],
artifactHelmet: [
"head_torch_artifact",
"inner_song_fancy_mask_artifact",
"knights_honor_armet_artifact",
"paupers_glory_straw_hat_artifact",
"crown_of_the_supreme_magi_artifact",
"scholars_wisdom_scholars_tiara_artifact",
"tranquility_brightmind_tiara_artifact",
"angelic_alliance_helm_of_heavenly_enlightenment_artifact",
"beelzebubs_blessing_demon_crest_artifact",
"ethereal_knowledge_third_eye_artifact",
"power_of_the_dragon_father_dragon_crest_artifact",
"rule_of_shadow_nostrias_gaze_artifact",
"shamaniac_soul_gemwood_mask_artifact",
"spellbinders_hat_artifact",
"two_faced_mask_artifact"
],
artifactBoots: [
"ethereal_knowledge_mirror_shoes_artifact",
"power_of_the_dragon_father_dragonbone_greaves_artifact",
"wanderers_way_boots_of_travel_artifact",
"legions_step_artifact",
"shadow_of_death_bone_boots_artifact",
"swamp_boots_artifact",
"angelic_alliance_sandals_of_the_saint_artifact",
"seven_league_boots_artifact",
"warlord_boots_artifact"
],
artifactBelt: [
"paupers_glory_rope_belt_artifact",
"soulless_sash_artifact",
"elixir_of_life_flask_of_oblivion_artifact",
"endless_bag_artifact",
"warriors_strength_warriors_belt_artifact",
"gifts_of_dwarven_lords_protective_belt_artifact",
"milos_curse_skull_of_milos_artifact",
"power_of_the_dragon_father_slithering_sash_artifact",
"angelic_alliance_celestial_sash_of_bliss_artifact",
"magic_key_ring_artifact",
"spells_in_a_bottle_artifact"
],
artifactCape: [
"omencaller_artifact",
"gifts_of_dwarven_lords_automated_antimagic_shield_artifact",
"monster_head_artifact",
"power_of_the_dragon_father_dragon_wing_artifact",
"wanderers_way_backpack_artifact",
"wizards_might_wizards_cloak_artifact",
"banner_of_four_winds_artifact",
"living_arrows_light_and_shade_cloak_artifact",
"shadow_of_death_second_shade_artifact",
"ambassadors_word_ambassadors_sash_artifact",
"fallen_angel_wings_artifact"
],
artifactRing: [
"paupers_glory_wooden_ring_artifact",
"power_of_the_dragon_father_piercing_eye_of_a_dragon_artifact",
"shamaniac_soul_clutching_ring_artifact",
"chain_link_artifact",
"elixir_of_life_ring_of_life_artifact",
"gifts_of_dwarven_lords_emerald_resonance_controller_artifact",
"keepers_fortitude_keepers_ring_artifact",
"ring_of_neutrality_artifact",
"sixth_finger_artifact",
"tranquility_ring_of_serenity_artifact",
"ukhtabar_seal_tabar_seal_artifact",
"duelists_pride_brass_knuckles_artifact",
"gifts_of_dwarven_lords_crimson_resonance_controller_artifact",
"lords_ring_artifact",
"seal_of_silence_artifact",
"soulscaller_ring_artifact"
],
artifactPouch: [
"boreolos_foot_artifact",
"boreolos_hand_artifact",
"boreolos_head_artifact",
"boreolos_heart_artifact",
"inner_song_music_sheet_artifact",
"magic_scroll_artifact",
"milos_curse_golden_moth_artifact",
"paupers_glory_last_coin_artifact",
"rule_of_shadow_liquid_silence_artifact",
"tranquility_magic_mirror_artifact",
"ancient_idol_artifact",
"cards_deck_artifact",
"enchanted_magic_scroll_artifact",
"keepers_fortitude_keepers_oberegus_artifact",
"living_arrows_quivering_quiver_artifact",
"milos_curse_golden_pig_artifact",
"orb_of_destruction_artifact",
"scholars_wisdom_scholars_oberegus_artifact",
"spyglass_artifact",
"ukhtabar_seal_ukh_seal_artifact",
"voodoosh_doll_artifact",
"warriors_strength_warriors_oberegus_artifact",
"wizards_might_wizards_oberegus_artifact",
"flag_of_truce_artifact",
"golden_goose_egg_artifact",
"knights_honor_drums_of_war_artifact",
"mythic_scroll_box_artifact",
"orb_of_inhibition_artifact",
"resonant_sphere_orb_of_daylight_artifact",
"resonant_sphere_orb_of_eternity_artifact",
"resonant_sphere_orb_of_twilight_artifact",
"resonant_sphere_primal_orb_artifact",
"runestone_shards_artifact",
"shackles_of_war_artifact",
"tactical_guide_artifact",
"ambassadors_word_diplomatic_gifts_artifact",
"catechism_of_daylight_magic_artifact",
"catechism_of_night_magic_artifact",
"catechism_of_primal_magic_artifact",
"catechism_of_spacetime_magic_artifact",
"demonic_heart_artifact",
"elixir_of_life_lifeblood_fairy_artifact",
"pole_star_artifact"
],
artifactBanner: [
"holy_sigil_of_eridore_artifact",
"holy_sigil_of_insara_artifact",
"holy_sigil_of_mearea_artifact",
"holy_sigil_of_quix_artifact",
"holy_sigil_of_roph_artifact",
"holy_sigil_of_the_second_man_artifact",
"holy_sigil_of_the_seven_magi_artifact",
"holy_sigil_of_uurdt_artifact"
],
units: [
"esquire",
"esquire_upg",
"esquire_upg_alt",
"crossbowman",
"crossbowman_upg",
"crossbowman_upg_alt",
"griffin",
"griffin_upg",
"griffin_upg_alt",
"lightweaver",
"lightweaver_upg",
"lightweaver_upg_alt",
"sunlight_cavalry",
"sunlight_cavalry_upg",
"sunlight_cavalry_upg_alt",
"inquisitor",
"inquisitor_upg",
"inquisitor_upg_alt",
"angel",
"angel_upg",
"angel_upg_alt",
"skeleton",
"skeleton_upg",
"skeleton_upg_alt",
"flicker",
"flicker_upg",
"flicker_upg_alt",
"pet",
"pet_upg",
"pet_upg_alt",
"graverobber",
"graverobber_upg",
"graverobber_upg_alt",
"lich",
"lich_upg",
"lich_upg_alt",
"avatar_of_war",
"avatar_of_war_upg",
"avatar_of_war_upg_alt",
"vampire",
"vampire_upg",
"vampire_upg_alt",
"elf_tracker",
"elf_tracker_upg",
"elf_tracker_upg_alt",
"twinkle",
"twinkle_upg",
"twinkle_upg_alt",
"ent",
"ent_upg",
"ent_upg_alt",
"aqualotl",
"aqualotl_upg",
"aqualotl_upg_alt",
"druid",
"druid_upg",
"druid_upg_alt",
"qilin",
"qilin_upg",
"qilin_upg_alt",
"phoenix",
"phoenix_upg",
"phoenix_upg_alt",
"trick_demon",
"trick_demon_upg",
"trick_demon_upg_alt",
"locust",
"locust_upg",
"locust_upg_alt",
"wasp",
"wasp_upg",
"wasp_upg_alt",
"lava_larva",
"jaw",
"jaw_upg",
"jaw_upg_alt",
"godslayer",
"godslayer_upg",
"godslayer_upg_alt",
"olgoi",
"olgoi_upg",
"olgoi_upg_alt",
"hive_queen",
"hive_queen_upg",
"hive_queen_upg_alt",
"lesser_eldritch",
"lesser_eldritch_upg",
"lesser_eldritch_upg_alt",
"unfrozen_cultist",
"unfrozen_cultist_upg",
"unfrozen_cultist_upg_alt",
"frostworm_rider",
"frostworm_rider_upg",
"frostworm_rider_upg_alt",
"eldritch_flyer",
"eldritch_flyer_upg",
"eldritch_flyer_upg_alt",
"succubus",
"succubus_upg",
"succubus_upg_alt",
"arbitrator",
"arbitrator_upg",
"arbitrator_upg_alt",
"unspeakable",
"unspeakable_upg",
"unspeakable_upg_alt",
"trogl",
"trogl_upg",
"trogl_upg_alt",
"assassin",
"assassin_upg",
"assassin_upg_alt",
"blade_dancer",
"blade_dancer_upg",
"blade_dancer_upg_alt",
"minos",
"minos_upg",
"minos_upg_alt",
"medusa",
"medusa_upg",
"medusa_upg_alt",
"hydra",
"hydra_upg",
"hydra_upg_alt",
"black_dragon",
"black_dragon_upg",
"black_dragon_upg_alt",
"pixie",
"gnat",
"undead_peasant",
"peasant",
"halfling",
"animated_armor",
"gorilla",
"star_child",
"unicorn",
"kitten_horn",
"primal_remnant",
"fairy_dragon",
"giant_frog",
"mech_guard",
"dragon_hunter",
"coatl",
"sentinel",
"dragon",
"dragon_upg",
"avatar",
"lich_dragon"
]
};
var DICTIONARY_default = DICTIONARY;
// src/planner/helpers/compression/FIELDS.js
var FIELDS = [
/*00*/
{ key: "hero", bits: 8, dictionary: DICTIONARY_default.heroes },
/*01*/
{
key: "level",
bits: 5
/*32*/
},
/*02*/
{ key: "skill0Id", bits: 6, dictionary: DICTIONARY_default.skills },
/*03*/
{
key: "skill0Sub1",
bits: 3
/*8*/
},
/*04*/
{
key: "skill0Sub2",
bits: 3
/*8*/
},
/*05*/
{ key: "skill1Id", bits: 6, dictionary: DICTIONARY_default.skills },
/*06*/
{
key: "skill1Sub1",
bits: 3
/*8*/
},
/*07*/
{
key: "skill1Sub2",
bits: 3
/*8*/
},
/*08*/
{ key: "skill2Id", bits: 6, dictionary: DICTIONARY_default.skills },
/*09*/
{
key: "skill2Sub1",
bits: 3
/*8*/
},
/*10*/
{
key: "skill2Sub2",
bits: 3
/*8*/
},
/*11*/
{ key: "skill3Id", bits: 6, dictionary: DICTIONARY_default.skills },
/*12*/
{
key: "skill3Sub1",
bits: 3
/*8*/
},
/*13*/
{
key: "skill3Sub2",
bits: 3
/*8*/
},
/*14*/
{ key: "skill4Id", bits: 6, dictionary: DICTIONARY_default.skills },
/*15*/
{
key: "skill4Sub1",
bits: 3
/*8*/
},
/*16*/
{
key: "skill4Sub2",
bits: 3
/*8*/
},
/*17*/
{ key: "skill5Id", bits: 6, dictionary: DICTIONARY_default.skills },
/*18*/
{
key: "skill5Sub1",
bits: 3
/*8*/
},
/*19*/
{
key: "skill5Sub2",
bits: 3
/*8*/
},
/*20*/
{ key: "skill6Id", bits: 6, dictionary: DICTIONARY_default.skills },
/*21*/
{
key: "skill6Sub1",
bits: 3
/*8*/
},
/*22*/
{
key: "skill6Sub2",
bits: 3
/*8*/
},
/*23*/
{ key: "skill7Id", bits: 6, dictionary: DICTIONARY_default.skills },
/*24*/
{
key: "skill7Sub1",
bits: 3
/*8*/
},
/*25*/
{
key: "skill7Sub2",
bits: 3
/*8*/
},
/*26*/
{ key: "artifactSword", bits: 5, dictionary: DICTIONARY_default.artifactSword },
/*27*/
{ key: "artifactShield", bits: 5, dictionary: DICTIONARY_default.artifactShield },
/*28*/
{ key: "artifactArmor", bits: 5, dictionary: DICTIONARY_default.artifactArmor },
/*29*/
{ key: "artifactHelmet", bits: 5, dictionary: DICTIONARY_default.artifactHelmet },
/*30*/
{ key: "artifactBoots", bits: 5, dictionary: DICTIONARY_default.artifactBoots },
/*31*/
{ key: "artifactBelt", bits: 5, dictionary: DICTIONARY_default.artifactBelt },
/*32*/
{ key: "artifactCape", bits: 5, dictionary: DICTIONARY_default.artifactCape },
/*33*/
{ key: "artifactRingL", bits: 5, dictionary: DICTIONARY_default.artifactRing },
/*34*/
{ key: "artifactRingR", bits: 5, dictionary: DICTIONARY_default.artifactRing },
/*35*/
{ key: "artifactPouchTL", bits: 6, dictionary: DICTIONARY_default.artifactPouch },
/*36*/
{ key: "artifactPouchTR", bits: 6, dictionary: DICTIONARY_default.artifactPouch },
/*37*/
{ key: "artifactPouchBL", bits: 6, dictionary: DICTIONARY_default.artifactPouch },
/*38*/
{ key: "artifactPouchBR", bits: 6, dictionary: DICTIONARY_default.artifactPouch },
/*39*/
{ key: "artifactBanner", bits: 5, dictionary: DICTIONARY_default.artifactBanner },
/*40*/
{ key: "army0Id", bits: 8, dictionary: DICTIONARY_default.units },
/*41*/
{
key: "army0Count",
bits: 10
/*1024*/
},
/*42*/
{ key: "army1Id", bits: 8, dictionary: DICTIONARY_default.units },
/*43*/
{
key: "army1Count",
bits: 10
/*1024*/
},
/*44*/
{ key: "army2Id", bits: 8, dictionary: DICTIONARY_default.units },
/*45*/
{
key: "army2Count",
bits: 10
/*1024*/
},
/*46*/
{ key: "army3Id", bits: 8, dictionary: DICTIONARY_default.units },
/*47*/
{
key: "army3Count",
bits: 10
/*1024*/
},
/*48*/
{ key: "army4Id", bits: 8, dictionary: DICTIONARY_default.units },
/*49*/
{
key: "army4Count",
bits: 10
/*1024*/
},
/*50*/
{ key: "army5Id", bits: 8, dictionary: DICTIONARY_default.units },
/*51*/
{
key: "army5Count",
bits: 10
/*1024*/
},
/*52*/
{ key: "army6Id", bits: 8, dictionary: DICTIONARY_default.units },
/*53*/
{
key: "army6Count",
bits: 10
/*1024*/
}
];
var FIELDS_default = FIELDS;
// src/planner/helpers/compression/decode.js
function decode(symbols) {
if (!symbols) {
return {};
}
const stream = convertSymbolsToBits(symbols);
const result = {};
let cursor = 0;
let expectedIndex = 0;
while (cursor < stream.length) {
const isSequential = stream[cursor++] === "1";
let currentIndex;
if (isSequential) {
currentIndex = expectedIndex;
} else {
const indexBits = stream.slice(cursor, cursor + FIELD_INDEX_BITS);
cursor += FIELD_INDEX_BITS;
currentIndex = parseInt(indexBits, 2);
}
const field = FIELDS_default[currentIndex];
if (!field) {
console.warn(`Invalid field index encountered: ${currentIndex}`);
return result;
}
const valueBits = stream.slice(cursor, cursor + field.bits);
cursor += field.bits;
const numericValue = parseInt(valueBits, 2);
if (field.dictionary) {
if (numericValue >= field.dictionary.length) {
console.warn(`Dictionary index ${numericValue} out of bounds for field "${field.key}"!`);
return result;
}
result[field.key] = field.dictionary[numericValue];
} else {
if (!isNaN(numericValue)) {
result[field.key] = numericValue;
}
}
expectedIndex = currentIndex + 1;
}
return result;
}
function convertSymbolsToBits(symbols) {
if (!symbols) {
return "";
}
const base = BigInt(SYMBOLS.length);
let num = 0n;
for (const char of symbols) {
const index = SYMBOLS.indexOf(char);
if (index === -1) {
console.log(`Invalid symbol encountered: ${char}`);
return "";
}
num = num * base + BigInt(index);
}
return num.toString(2).slice(1);
}
var decode_default = decode;
// src/planner/utils/assume.js
function assume(condition, ...message) {
if (!condition) {
throw new Error(stringify(message));
}
}
function stringify(list) {
const lines = [];
for (const arg of list) {
lines.push(typeof arg === "object" ? JSON.stringify(arg, null, 4) : arg);
}
return lines.join("\n");
}
var assume_default = assume;
// src/planner/helpers/compression/encode.js
function encode(hub) {
let stream = "";
let jumpPending = false;
for (let i4 = 0; i4 < FIELDS_default.length; i4++) {
const { key, bits, dictionary } = FIELDS_default[i4];
let value = hub[key];
if (value === void 0) {
jumpPending = true;
continue;
}
if (jumpPending) {
stream += "0";
stream += i4.toString(2).padStart(FIELD_INDEX_BITS, "0");
jumpPending = false;
} else {
stream += "1";
}
if (dictionary) {
const index = dictionary.indexOf(value);
assume_default(index >= 0, `The value "${value}" is not present in the dictionary of "${key}"!`);
value = index;
}
stream += value.toString(2).padStart(bits, "0");
}
return convertBitsToSymbols(stream);
}
function convertBitsToSymbols(bits) {
if (!bits) {
return "";
}
let num = BigInt("0b1" + bits);
let res = "";
const base = BigInt(SYMBOLS.length);
while (num > 0n) {
res = SYMBOLS[Number(num % base)] + res;
num /= base;
}
return res;
}
var encode_default = encode;
// src/planner/helpers/Persistence.js
var STORAGE_KEY = "hero-planner";
var changeHandler;
var sourceOfTruth = null;
function setup(onChange) {
changeHandler = onChange;
window.addEventListener("hashchange", onHashChange);
const hash = window.location.hash.substring(1);
if (hash) {
parseSymbols(hash);
} else {
const stored = window.localStorage.getItem(STORAGE_KEY);
parseSymbols(stored || "");
}
}
function remember(state) {
const symbols = encode_default(state);
parseSymbols(symbols);
}
function onHashChange() {
const hash = window.location.hash.substring(1) || "";
parseSymbols(hash);
}
function parseSymbols(symbols) {
if (symbols !== sourceOfTruth) {
sourceOfTruth = symbols;
window.localStorage.setItem(STORAGE_KEY, symbols);
if (symbols) {
window.location.hash = symbols;
} else {
history.pushState(null, "", window.location.pathname + window.location.search);
}
const decoded = decode_default(symbols);
changeHandler(decoded);
}
}
var Persistence = {
setup,
remember
};
var Persistence_default = Persistence;
// src/planner/components/Reset.jsx
var ROOT_CSS3 = u3`
position: absolute;
left: 673px;
top: 38px;
width: 26px;
height: 26px;
border-radius: 50%;
cursor: pointer;
&:hover {
border: solid 2px yellow;
}
&:active {
border: solid 2px red;
}
`;
var Reset = class extends C {
render() {
return /* @__PURE__ */ u2("div", { className: ROOT_CSS3, onClick: this.onRootClick });
}
// -----------------------------------------------------------------------------------------------------------------
// P R I V A T E
// -----------------------------------------------------------------------------------------------------------------
/**
*
*/
onRootClick = () => {
Persistence_default.remember({});
};
};
var Reset_default = Reset;
// src/planner/components/Specialization.jsx
var ROOT_CSS4 = u3`
position: absolute;
left: 45px;
top: 150px;
width: 64px;
height: 64px;
border-radius: 50%;
& > * {
width: 100%;
height: 100%;
}
& img {
width: 100%;
}
`;
var Specialization = class extends C {
render() {
const { heroData } = this.props;
return /* @__PURE__ */ u2("div", { className: ROOT_CSS4, children: heroData && /* @__PURE__ */ u2(Hint_default, { title: heroData.specName, text: heroData.description, way: EAST, children: /* @__PURE__ */ u2("img", { src: heroData.specIcon }) }) });
}
// -----------------------------------------------------------------------------------------------------------------
// P R I V A T E
// -----------------------------------------------------------------------------------------------------------------
};
var Specialization_default = Specialization;
// src/planner/components/Labels.jsx
var ROOT_CSS5 = u3`
position: absolute;
left: 0;
top: 0;
color: #fff;
font-weight: bold;
font-size: 18px;
white-space: nowrap;
& > * {
position: absolute;
}
`;
var NAME_CSS = u3`
left: 208px;
top: 8px;
`;
var CLASS_CSS = u3`
left: 208px;
top: 42px;
font-size: 16px;
font-weight: normal;
`;
var Labels = class extends C {
render() {
const { heroData } = this.props;
return /* @__PURE__ */ u2("div", { className: ROOT_CSS5, children: [
heroData && /* @__PURE__ */ u2("div", { className: NAME_CSS, children: heroData.name }),
heroData && /* @__PURE__ */ u2("div", { className: CLASS_CSS, children: heroData.className })
] });
}
// -----------------------------------------------------------------------------------------------------------------
// P R I V A T E
// -----------------------------------------------------------------------------------------------------------------
};
var Labels_default = Labels;
// src/planner/components/SubskillInfo.jsx
var ROOT4 = u3`
padding: 6px 8px;
display: flex;
gap: 4px;
&:hover {
background: #192b44;
}
&:active {
background: #191b2c;
}
&[data-id=${NONE}] img {
width: 32px;
height: 32px;
}
`;
var ICON2 = u3`
width: 48px;
height: 48px;
flex-shrink: 0;
`;
var TITLE2 = u3`
font-weight: bold;
color: #d6bc7c;
`;
var TEXT2 = u3`
color: #fff;
`;
var SubskillInfo = class extends C {
render() {
const { id, icon, name, description, onClick } = this.props;
return /* @__PURE__ */ u2("div", { class: ROOT4, "data-id": id, onClick, children: [
/* @__PURE__ */ u2("img", { class: ICON2, src: icon }),
/* @__PURE__ */ u2("div", { children: [
/* @__PURE__ */ u2("div", { class: TITLE2, children: name }),
/* @__PURE__ */ u2("div", { class: TEXT2, dangerouslySetInnerHTML: { __html: description } })
] })
] });
}
};
var SubskillInfo_default = SubskillInfo;
// src/planner/components/Subskill.jsx
var ROOT5 = u3`
position: absolute;
cursor: pointer;
/*background: red;*/
width: 24px;
height: 24px;
border-radius: 4px;
`;
var BORDERED = u3`
border: solid 1px palegoldenrod;
`;
var LEVEL_1 = u3`
left: 54px;
top: -1px;
`;
var LEVEL_2 = u3`
left: 54px;
top: 25px;
`;
var HIT = u3`
position: absolute;
inset: 0;
& img {
width: 100%;
}
`;
var MENU2 = u3`
left: 12px;
top: 24px;
`;
var MENU_BOX = u3`
display: flex;
flex-direction: column;
`;
var Subskill = class extends C {
state = {
isOpen: false
};
render() {
const { family, index, level, skills } = this.props;
const { isOpen } = this.state;
const { subs = [] } = skills[family + "_" + (level + 1)] || {};
const subskillData = subs[index];
return /* @__PURE__ */ u2("div", { className: cn_default(ROOT5, level === 1 ? LEVEL_1 : LEVEL_2, !subskillData && BORDERED), children: [
/* @__PURE__ */ u2("div", { className: HIT, onClick: this.onHitClick, children: subskillData && /* @__PURE__ */ u2(Hint_default, { title: subskillData.name, text: subskillData.description, children: /* @__PURE__ */ u2("img", { src: subskillData.icon }) }) }),
isOpen && /* @__PURE__ */ u2(
Menu_default,
{
className: MENU2,
boxClassName: MENU_BOX,
maxWidth: 340,
list: this.prepareMenuChoices(subs),
onChoice: this.onMenuChoice,
way: SOUTH
}
)
] });
}
// -----------------------------------------------------------------------------------------------------------------
// P R I V A T E
// -----------------------------------------------------------------------------------------------------------------
onHitClick = () => {
if (!this.state.isOpen) {
this.setState({ isOpen: true });
}
};
onMenuChoice = (choice) => {
console.log("choice:", choice);
this.setState({ isOpen: false });
if (choice === void 0) {
return;
}
const { family, skillSlot, level, skills, index, onChange } = this.props;
const { subs } = skills[family + "_" + (level + 1)];
const chosenIndex = subs.findIndex((sub) => sub.id === choice);
const currentIndex = index === void 0 ? -1 : index;
if (chosenIndex !== currentIndex) {
onChange(chosenIndex, skillSlot, level);
}
};
prepareMenuChoices = (subs) => {
const options = subs.map((item) => {
return {
...item,
Component: SubskillInfo_default
};
});
options.push({
id: NONE,
icon: this.props.emptyUrl,
name: "",
description: "",
Component: SubskillInfo_default
});
return options;
};
};
var Subskill_default = Subskill;
// src/planner/components/Skill.jsx
var ROOT_CSS6 = u3`
position: absolute;
cursor: pointer;
/*background: red;*/
width: 50px;
height: 50px;
`;
var SLOTS = [
/* 0 */
u3`
left: 326px;
top: 83px;
`,
/* 1 */
u3`
left: 417px;
top: 83px;
`,
/* 2 */
u3`
left: 508px;
top: 83px;
`,
/* 3 */
u3`
left: 599px;
top: 83px;
`,
/* 4 */
u3`
left: 326px;
top: 143px;
`,
/* 5 */
u3`
left: 417px;
top: 143px;
`,
/* 6 */
u3`
left: 508px;
top: 143px;
`,
/* 7 */
u3`
left: 599px;
top: 143px;
`
];
var HIT_CSS = u3`
position: absolute;
inset: 0;
& img {
width: 100%;
}
`;
var FORBIDDEN = u3`
cursor: not-allowed;
`;
var MENU3 = u3`
left: 25px;
top: 52px;
`;
var LEVEL = u3`
position: absolute;
right: 4px;
bottom: 0;
color: #fff;
font-family: Arial, sans-serif;
`;
var Skill = class extends C {
state = {
isOpen: false
};
render() {
const { nr, id, skills, heroData, sub1, sub2, onSubskillChange, emptyUrl } = this.props;
const { isOpen } = this.state;
const skillData = skills[id];
const isDisabled = Boolean(heroData?.skills[nr]);
return /* @__PURE__ */ u2("div", { className: cn_default(ROOT_CSS6, SLOTS[nr], isDisabled && FORBIDDEN), children: [
/* @__PURE__ */ u2("div", { className: HIT_CSS, onClick: !isDisabled && this.onHitClick, children: skillData && /* @__PURE__ */ u2(Hint_default, { title: skillData.name, text: skillData.description, children: /* @__PURE__ */ u2("img", { src: skillData.icon }) }) }),
isOpen && /* @__PURE__ */ u2(
Menu_default,
{
className: MENU3,
maxWidth: 340,
list: this.filterSkills(skills),
onChoice: this.onMenuChoice,
way: SOUTH
}
),
skillData && /* @__PURE__ */ u2(
Subskill_default,
{
family: id,
skillSlot: nr,
index: sub1,
level: 1,
skills,
onChange: onSubskillChange,
emptyUrl
}
),
sub1 !== void 0 && /* @__PURE__ */ u2(
Subskill_default,
{
family: id,
skillSlot: nr,
index: sub2,
level: 2,
skills,
onChange: onSubskillChange,
emptyUrl
}
),
/* @__PURE__ */ u2("div", { class: LEVEL, children: computeLevel(skillData, sub1, sub2) })
] });
}
// -----------------------------------------------------------------------------------------------------------------
// P R I V A T E
// -----------------------------------------------------------------------------------------------------------------
onHitClick = () => {
if (!this.state.isOpen) {
this.setState({ isOpen: true });
}
};
onMenuChoice = (choice) => {
console.log("choice:", choice);
this.setState({ isOpen: false });
if (choice && choice !== this.props.id) {
this.props.onChange(choice, this.props.nr);
}
};
filterSkills = (skills) => {
const { emptyUrl, heroData = {} } = this.props;
const { isMight } = heroData;
let list = Object.values(skills);
list = list.filter((item) => {
if (item.subs.length) {
return false;
}
if (item.id.includes("faction")) {
return false;
}
if (!isMight && item.id === "skill_battle_artistry") {
return false;
}
if (isMight && item.id === "skill_wisdom") {
return false;
}
return true;
});
list.push({ id: NONE, icon: emptyUrl });
return list;
};
};
function computeLevel(skillData, sub1, sub2) {
if (!skillData) {
return "";
}
if (sub1 === void 0) {
return 1;
}
if (sub2 === void 0) {
return 2;
}
return 3;
}
var Skill_default = Skill;
// src/planner/helpers/sanitize.js
function sanitize(stateFragment, heroes, skills) {
const draft = { ...stateFragment };
removeUnknownHero(draft, heroes);
removeUnknownSkill(draft, skills);
removeUnknownSubskill(draft, skills);
removeUnknownArtifact(draft);
removeUnknownUnit(draft);
ensureNativeSkills(draft, heroes);
removeWrongCombatOrThaumaturgy(draft, heroes);
removeDuplicateSkills(draft);
removeUnexpectedSubskills(draft);
return draft;
}
function removeUnknownHero(draft, heroes) {
const { hero } = draft;
if (hero && !heroes[hero]) {
console.warn(`Unknown hero "${draft.hero}" was removed!`);
delete draft.hero;
}
}
function removeUnknownSkill(draft, skills) {
for (let i4 = 0; i4 < 8; i4++) {
const key = `skill${i4}Id`;
const skillId = draft[key];
if (skillId) {
if (!skills[skillId]) {
delete draft[key];
console.warn(`Unknown skill "${skillId}" was removed!`);
} else if (skills[skillId].subs.length) {
delete draft[key];
console.warn(`Non-basic skill "${skillId}" was removed!`);
}
}
}
}
function removeUnknownSubskill(draft, skills) {
for (let i4 = 0; i4 < 8; i4++) {
const skillKey = `skill${i4}Id`;
const skillId = draft[skillKey];
const sub1Key = `skill${i4}Sub1`;
const sub1Index = draft[sub1Key];
const sub2Key = `skill${i4}Sub2`;
const sub2Index = draft[sub2Key];
if (skillId) {
if (sub1Index !== void 0) {
const advancedSubs = skills[skillId + "_2"]?.subs || [];
if (sub1Index >= advancedSubs.length) {
delete draft[sub1Key];
console.warn(`Out-of-bounds Advanced subskill was removed!`);
}
}
if (sub2Index !== void 0) {
const expertSubs = skills[skillId + "_3"]?.subs || [];
if (sub2Index >= expertSubs.length) {
delete draft[sub2Key];
console.warn(`Out-of-bounds Expert subskill was removed!`);
}
}
}
}
}
function removeUnknownArtifact(draft) {
}
function removeUnknownUnit(draft) {
}
function removeWrongCombatOrThaumaturgy(draft, heroes) {
const { hero } = draft;
if (hero) {
const { isMight } = heroes[hero];
for (let i4 = 0; i4 < 8; i4++) {
const key = `skill${i4}Id`;
const skillId = draft[key];
if (skillId) {
if (skillId === "skill_battle_artistry") {
if (!isMight) {
delete draft[key];
console.warn(`Skill "${skillId}" was removed because it's only for Might!`);
}
} else if (skillId === "skill_wisdom") {
if (isMight) {
delete draft[key];
console.warn(`Skill "${skillId}" was removed because it's only for Magic!`);
}
}
}
}
}
}
function removeDuplicateSkills(draft) {
const used = {};
for (let i4 = 0; i4 < 8; i4++) {
const key = `skill${i4}Id`;
const skillId = draft[key];
if (skillId) {
if (used[skillId]) {
delete draft[key];
console.warn(`Duplicate skill "${skillId}" was removed!`);
} else {
used[skillId] = true;
}
}
}
}
function removeUnexpectedSubskills(draft) {
for (let i4 = 0; i4 < 8; i4++) {
const skillKey = `skill${i4}Id`;
const skillId = draft[skillKey];
const sub1Key = `skill${i4}Sub1`;
const sub1Index = draft[sub1Key];
const sub2Key = `skill${i4}Sub2`;
const sub2Index = draft[sub2Key];
if (!skillId) {
if (sub1Index !== void 0) {
delete draft[sub1Key];
console.warn(`Unexpected Advanced subskill was removed!`);
}
if (sub2Index !== void 0) {
delete draft[sub2Key];
console.warn(`Unexpected Expert subskill was removed!`);
}
} else {
if (sub1Index === void 0 && sub2Index !== void 0) {
delete draft[sub2Key];
console.warn(`Unsupported Expert subskill was removed!`);
}
}
}
}
function ensureNativeSkills(draft, heroes) {
const heroData = heroes[draft.hero];
if (heroData) {
const { skills } = heroData;
if (draft.skill0Id !== skills[0].name) {
draft.skill0Id = skills[0].name;
delete draft.skill0Sub1;
delete draft.skill0Sub2;
}
if (skills[1] && draft.skill1Id !== skills[1].name) {
draft.skill1Id = skills[1].name;
delete draft.skill1Sub1;
delete draft.skill1Sub2;
}
}
}
var sanitize_default = sanitize;
// src/planner/helpers/acceptSkill.js
function acceptSkill(skillId, nr, state, heroData) {
const draft = { ...state };
if (heroData) {
if (heroData.skills.find((skill) => skill.name === skillId)) {
console.warn("Refused to change into a native skill!");
return draft;
}
}
if (skillId === NONE) {
delete draft[`skill${nr}Id`];
delete draft[`skill${nr}Sub1`];
delete draft[`skill${nr}Sub2`];
return draft;
}
for (let i4 = 0; i4 < 8; i4++) {
if (draft[`skill${i4}Id`] === skillId) {
delete draft[`skill${i4}Id`];
delete draft[`skill${i4}Sub1`];
delete draft[`skill${i4}Sub2`];
console.log("Existing duplicate skill has been removed!");
}
}
draft[`skill${nr}Id`] = skillId;
delete draft[`skill${nr}Sub1`];
delete draft[`skill${nr}Sub2`];
return draft;
}
var acceptSkill_default = acceptSkill;
// src/planner/components/App.jsx
var APP_CSS = u3`
position: absolute;
width: ${WIDTH}px;
height: ${HEIGHT}px;
transform-origin: 0 0;
-webkit-touch-callout: none;
-webkit-user-select: none;
user-select: none;
& img {
-webkit-user-drag: none;
user-select: none;
}
`;
var BG_CSS = u3`
width: 100%;
filter: drop-shadow(0 0 0.3rem black);
`;
var App = class extends C {
vars = {
appRef: M()
};
render() {
const { hero } = this.state;
const { appRef } = this.vars;
const { bgUrl, levelUrl, emptyUrl, heroes, skills } = this.props;
const heroData = heroes[hero];
const skillNumbers = [0, 1, 2, 3, 4, 5, 6, 7];
return /* @__PURE__ */ u2("div", { className: APP_CSS, ref: appRef, onContextMenu: this.onRootContextMenu, children: [
/* @__PURE__ */ u2("style", { children: CSS }),
/* @__PURE__ */ u2("img", { className: BG_CSS, src: bgUrl, alt: "empty background" }),
/* @__PURE__ */ u2(Portrait_default, { hero, heroes, onHeroChange: this.onHeroChange }),
/* @__PURE__ */ u2(Specialization_default, { heroData }),
/* @__PURE__ */ u2(Labels_default, { heroData }),
/* @__PURE__ */ u2(Level_default, { src: levelUrl }),
skillNumbers.map((nr) => /* @__PURE__ */ u2(
Skill_default,
{
nr,
id: this.state[`skill${nr}Id`],
sub1: this.state[`skill${nr}Sub1`],
sub2: this.state[`skill${nr}Sub2`],
skills,
onChange: this.onSkillChange,
onSubskillChange: this.onSubskillChange,
emptyUrl,
heroData
},
"skill" + nr
)),
/* @__PURE__ */ u2(Reset_default, {})
] });
}
componentDidMount() {
window.addEventListener("resize", this.onWindowResize);
Persistence_default.setup(this.onHashChange);
this.refreshScale();
}
componentDidUpdate() {
Persistence_default.remember(this.state);
}
componentWillUnmount() {
window.removeEventListener("resize", this.onWindowResize);
}
// -----------------------------------------------------------------------------------------------------------------
// P R I V A T E
// -----------------------------------------------------------------------------------------------------------------
/**
*
*/
onWindowResize = () => {
this.refreshScale();
};
/**
*
*/
onRootContextMenu = (event) => {
event.preventDefault();
};
/**
*
*/
refreshScale = () => {
const appElement = this.vars.appRef.current;
const rootElement = appElement.parentNode;
const { width } = rootElement.getBoundingClientRect();
const coreWidth = Math.min(width, WIDTH);
const coreHeight = coreWidth * HEIGHT / WIDTH;
rootElement.style.height = Math.ceil(coreHeight) + "px";
const scaleRatio = coreWidth / WIDTH;
appElement.style.transform = `scale(${scaleRatio})`;
appElement.style.left = Math.floor((width - coreWidth) / 2) + "px";
};
/**
*
*/
onHeroChange = (hero) => {
this.save({ ...this.state, hero });
};
/**
*
*/
onSkillChange = (choice, nr) => {
const { heroes } = this.props;
const heroData = heroes[this.state.hero];
const futureState = acceptSkill_default(choice, nr, this.state, heroData);
this.save(futureState);
};
/**
*
*/
onSubskillChange = (choice, nr, level) => {
const key = `skill${nr}Sub${level}`;
const value = choice === -1 ? void 0 : choice;
const futureState = { ...this.state, [key]: value };
if (level === 1 && value === void 0) {
futureState[`skill${nr}Sub2`] = void 0;
}
this.save(futureState);
};
/**
*
*/
onHashChange = (stateFragment) => {
const { heroes, skills } = this.props;
const sanitized = sanitize_default(stateFragment, heroes, skills);
const subState = {};
for (const field of FIELDS_default) {
const { key } = field;
subState[key] = sanitized[key];
}
this.setState(subState);
};
/**
*
*/
save = (futureState) => {
const { heroes, skills } = this.props;
const safeState = sanitize_default(futureState, heroes, skills);
Persistence_default.remember(safeState);
};
};
var App_default = App;
// src/planner/utils/match.js
function match(text, pattern) {
if (pattern.global) {
return [...text.matchAll(pattern)];
} else {
return text.match(pattern) || [];
}
}
var match_default = match;
// src/planner/helpers/downloadPage.js
async function downloadPage(page, lang) {
lang = lang || "en";
const suffix = lang === "en" ? "" : "/" + lang;
const url = WIKI_URL + page + suffix;
let response;
try {
response = await fetch(url);
} catch (e4) {
console.warn(`Failed to fetch ${url}!`);
return "";
}
return await response.text();
}
var downloadPage_default = downloadPage;
// src/planner/data/getHeroes.js
async function getHeroes(lang) {
const overview = await downloadPage_default("Heroes_Overview", lang);
const [table = ""] = match_default(overview, /<table[\s\S]*?<\/table>/);
const rows = table.split("</tr>");
rows.shift();
const heroes = {};
for (let i4 = 0; i4 < rows.length; i4++) {
const hero = parseRow(rows[i4], rows[i4 + 1]);
if (hero) {
heroes[hero.id] = hero;
}
}
return heroes;
}
function parseRow(row, extraRow) {
const [iconColumn, nameColumn, typeColumn, classColumn, specIconColumn, specInfoColumn, skillsColumn] = row.split("</td>");
let [, id] = match_default(iconColumn, /data-id=['"]([^'"]*)/);
if (!id) {
return;
}
id = id.replaceAll("_", "_");
const [, icon] = match_default(iconColumn, /src=['"]([^'"]*)/);
if (!icon) {
return console.warn("No icon!");
}
const portrait = icon.replace(/\d*px/, "600px");
let [, name] = match_default(nameColumn, /<a.*?>([^<]*)/);
if (!name) {
return console.warn("No name!");
}
const isMight = typeColumn.includes("Might");
const [, classIcon] = match_default(classColumn, /src=['"]([^'"]*)/);
if (!classIcon) {
return console.warn("No classIcon!");
}
const [, className] = match_default(classColumn, /<a.*?>([^<]+)/);
if (!className) {
return console.warn("No className!");
}
let [, specIcon] = match_default(specIconColumn, /src=['"]([^'"]*)/);
if (!specIcon) {
return console.warn("No specIcon!");
}
specIcon = specIcon.replace(/\d*px/, "128px");
const [, specName] = match_default(specInfoColumn, /<b>([^<]+)/);
if (!specName) {
return console.warn("No specName!");
}
const [, description] = match_default(extraRow || "", /<td.*?>([^<]+)/);
if (!description) {
return console.warn("No description!");
}
const skills = parseSkills(skillsColumn);
if (!skills) {
return;
}
return { id, icon, portrait, name, isMight, classIcon, className, specIcon, specName, description, skills };
}
function parseSkills(column) {
const divs = column.split("</div>");
const skills = [];
for (const div of divs) {
if (!div) {
continue;
}
const [, src] = match_default(div, /src=['"]([^'"]*)/);
if (!src) {
return console.warn("No skill src!");
}
let [, name] = match_default(src, /\d+px-(.*?)\.\w+$/);
name = name.toLowerCase();
let [, level = 1] = match_default(name, /_(\d+)$/);
if (level !== 1) {
name = name.replace(/_\d+$/, "");
level = Number(level);
}
if (name.includes("faction")) {
skills.unshift({ name, level });
} else {
skills.push({ name, level });
}
}
return skills;
}
var getHeroes_default = getHeroes;
// src/planner/data/getSkills.js
async function getSkills(lang) {
const overview = await downloadPage_default("Skills_Overview", lang);
const boxes = overview.split('<div class="box ');
boxes.shift();
const skills = {};
for (let i4 = 0; i4 < boxes.length; i4++) {
const skill = parseBox(boxes[i4], boxes[i4 + 1], boxes[i4 + 2], boxes[i4 + 3]);
if (checkValid(skill)) {
skills[skill.id] = skill;
}
}
return skills;
}
function parseBox(box, subA, subB, subC) {
if (!box.startsWith("rank")) {
return;
}
let [, id] = match_default(box, /data-id=['"]([^'"]*)/);
id = id.replaceAll("_", "_");
const [, icon] = match_default(box, /([^ ]*) 2x/);
const [, name] = match_default(box, /box-name.*?>.*?>([^<]*)/);
const [, description] = match_default(box, /box-description.*?>([\s\S]*?)<\/div>/);
const subs = [];
if (subA.startsWith("sub")) {
for (const markup of [subA, subB, subC]) {
const parsed = parseSub(markup);
if (checkValid(parsed)) {
subs.push(parsed);
}
}
}
return { id, icon, name, description, subs };
}
function parseSub(subMarkup) {
if (!subMarkup.startsWith("sub")) {
return;
}
let [, id] = match_default(subMarkup, /data-id=['"]([^'"]*)/);
id = id.replaceAll("_", "_");
const [, icon] = match_default(subMarkup, /([^ ]*) 2x/);
const [, name] = match_default(subMarkup, /box-name.*?>.*?>([^<]*)/);
const [, description] = match_default(subMarkup, /box-description.*?>([\s\S]*?)<\/div>/);
return { id, icon, name, description };
}
function checkValid(target) {
if (!target) {
return false;
}
for (const key in target) {
if (!target[key]) {
console.warn(`Invalid value for key "${key}"!`);
return false;
}
}
return true;
}
var getSkills_default = getSkills;
// src/planner/planner.js
async function planner() {
const root = document.querySelector(".planner");
if (!root) {
window.addEventListener("load", onWindowLoad);
} else {
await run(root);
}
}
async function onWindowLoad() {
window.removeEventListener("load", onWindowLoad);
const root = document.querySelector(".planner");
if (root) {
await run(root);
}
}
async function run(root) {
console.log("Mounting HeroPlanner.");
const { lang } = root.dataset;
mount_default(App_default, root, {
bgUrl: root.querySelector(".background img").src,
levelUrl: root.querySelector(".level img").src,
emptyUrl: root.querySelector(".empty img").src,
heroes: await getHeroes_default(lang),
skills: await getSkills_default(lang)
});
}
planner();
})();
//# sourceMappingURL=planner.js.map


