oh-my-live2d
Version:
live2d component for web. 看板娘组件, 支持 model2、model3、model4
1,319 lines • 158 kB
JavaScript
import { E as Bt, u as kt, M as yt, T as De, P as Ae, C as Re, O as Oe, a as It } from "./oml2d.app.js";
var Y = Math.pow, I = (s, t, e) => new Promise((i, r) => {
var a = (l) => {
try {
o(e.next(l));
} catch (h) {
r(h);
}
}, n = (l) => {
try {
o(e.throw(l));
} catch (h) {
r(h);
}
}, o = (l) => l.done ? i(l.value) : Promise.resolve(l.value).then(a, n);
o((e = e.apply(s, t)).next());
});
const Kt = 2, Qt = 2;
var gt;
((s) => {
s.supportMoreMaskDivisions = !0, s.setOpacityFromMotion = !1;
})(gt || (gt = {}));
var L;
((s) => {
s.LOG_LEVEL_VERBOSE = 0, s.LOG_LEVEL_WARNING = 1, s.LOG_LEVEL_ERROR = 2, s.LOG_LEVEL_NONE = 999, s.logLevel = s.LOG_LEVEL_WARNING, s.sound = !0, s.motionSync = !0, s.motionFadingDuration = 500, s.idleMotionFadingDuration = 2e3, s.expressionFadingDuration = 500, s.preserveExpressionOnMotion = !0, s.cubism4 = gt;
})(L || (L = {}));
const xs = "0.4.0", C = {
log(s, ...t) {
L.logLevel <= L.LOG_LEVEL_VERBOSE && console.log(`[${s}]`, ...t);
},
warn(s, ...t) {
L.logLevel <= L.LOG_LEVEL_WARNING && console.warn(`[${s}]`, ...t);
},
error(s, ...t) {
L.logLevel <= L.LOG_LEVEL_ERROR && console.error(`[${s}]`, ...t);
}
};
function xt(s, t, e) {
return s < t ? t : s > e ? e : s;
}
function Be(s, t) {
return Math.random() * (t - s) + s;
}
function rt(s, t, e, i, r) {
const a = t[i];
a !== null && typeof a === s && (e[r] = a);
}
function at(s, t, e, i, r) {
const a = t[i];
Array.isArray(a) && (e[r] = a.filter((n) => n !== null && typeof n === s));
}
function pe(s, t) {
t.forEach((e) => {
Object.getOwnPropertyNames(e.prototype).forEach((i) => {
i !== "constructor" && Object.defineProperty(s.prototype, i, Object.getOwnPropertyDescriptor(e.prototype, i));
});
});
}
function ke(s) {
let t = s.lastIndexOf("/");
return t != -1 && (s = s.slice(0, t)), t = s.lastIndexOf("/"), t !== -1 && (s = s.slice(t + 1)), s;
}
function Ue(s, t) {
const e = s.indexOf(t);
e !== -1 && s.splice(e, 1);
}
class Ut extends Bt {
constructor(t, e) {
super(), this.expressions = [], this.reserveExpressionIndex = -1, this.destroyed = !1, this.settings = t, this.tag = `ExpressionManager(${t.name})`;
}
init() {
this.defaultExpression = this.createExpression({}, void 0), this.currentExpression = this.defaultExpression, this.stopAllExpressions();
}
loadExpression(t) {
return I(this, null, function* () {
if (!this.definitions[t]) {
C.warn(this.tag, `Undefined expression at [${t}]`);
return;
}
if (this.expressions[t] === null) {
C.warn(this.tag, `Cannot set expression at [${t}] because it's already failed in loading.`);
return;
}
if (this.expressions[t])
return this.expressions[t];
const e = yield this._loadExpression(t);
return this.expressions[t] = e, e;
});
}
_loadExpression(t) {
throw new Error("Not implemented.");
}
setRandomExpression() {
return I(this, null, function* () {
if (this.definitions.length) {
const t = [];
for (let e = 0; e < this.definitions.length; e++)
this.expressions[e] !== null && this.expressions[e] !== this.currentExpression && e !== this.reserveExpressionIndex && t.push(e);
if (t.length) {
const e = Math.floor(Math.random() * t.length);
return this.setExpression(e);
}
}
return !1;
});
}
resetExpression() {
this._setExpression(this.defaultExpression);
}
restoreExpression() {
this._setExpression(this.currentExpression);
}
setExpression(t) {
return I(this, null, function* () {
if (typeof t != "number" && (t = this.getExpressionIndex(t)), !(t > -1 && t < this.definitions.length) || t === this.expressions.indexOf(this.currentExpression))
return !1;
this.reserveExpressionIndex = t;
const e = yield this.loadExpression(t);
return !e || this.reserveExpressionIndex !== t ? !1 : (this.reserveExpressionIndex = -1, this.currentExpression = e, this._setExpression(e), !0);
});
}
update(t, e) {
return this.isFinished() ? !1 : this.updateParameters(t, e);
}
destroy() {
this.destroyed = !0, this.emit("destroy");
const t = this;
t.definitions = void 0, t.expressions = void 0;
}
}
const te = 0.01, Ve = 40 / 7.5, Ne = 1 / (0.15 * 1e3);
class Ge {
constructor() {
this.targetX = 0, this.targetY = 0, this.x = 0, this.y = 0, this.vx = 0, this.vy = 0;
}
focus(t, e, i = !1) {
this.targetX = xt(t, -1, 1), this.targetY = xt(e, -1, 1), i && (this.x = this.targetX, this.y = this.targetY);
}
update(t) {
const e = this.targetX - this.x, i = this.targetY - this.y;
if (Math.abs(e) < te && Math.abs(i) < te)
return;
const r = Math.sqrt(Y(e, 2) + Y(i, 2)), a = Ve / (1e3 / t);
let n = a * (e / r) - this.vx, o = a * (i / r) - this.vy;
const l = Math.sqrt(Y(n, 2) + Y(o, 2)), h = a * Ne * t;
l > h && (n *= h / l, o *= h / l), this.vx += n, this.vy += o;
const u = Math.sqrt(Y(this.vx, 2) + Y(this.vy, 2)), c = 0.5 * (Math.sqrt(Y(h, 2) + 8 * h * r) - h);
u > c && (this.vx *= c / u, this.vy *= c / u), this.x += this.vx, this.y += this.vy;
}
}
class Mt {
constructor(t) {
this.json = t;
let e = t.url;
if (typeof e != "string")
throw new TypeError("The `url` field in settings JSON must be defined as a string.");
this.url = e, this.name = ke(this.url);
}
resolveURL(t) {
return kt.resolve(this.url, t);
}
replaceFiles(t) {
this.moc = t(this.moc, "moc"), this.pose !== void 0 && (this.pose = t(this.pose, "pose")), this.physics !== void 0 && (this.physics = t(this.physics, "physics"));
for (let e = 0; e < this.textures.length; e++)
this.textures[e] = t(this.textures[e], `textures[${e}]`);
}
getDefinedFiles() {
const t = [];
return this.replaceFiles((e) => (t.push(e), e)), t;
}
validateFiles(t) {
const e = (a, n) => {
const o = this.resolveURL(a);
if (!t.includes(o)) {
if (n)
throw new Error(`File "${a}" is defined in settings, but doesn't exist in given files`);
return !1;
}
return !0;
};
return [this.moc, ...this.textures].forEach((a) => e(a, !0)), this.getDefinedFiles().filter((a) => e(a, !1));
}
}
var Ft = /* @__PURE__ */ ((s) => (s[s.NONE = 0] = "NONE", s[s.IDLE = 1] = "IDLE", s[s.NORMAL = 2] = "NORMAL", s[s.FORCE = 3] = "FORCE", s))(Ft || {});
class Xe {
constructor() {
this.debug = !1, this.currentPriority = 0, this.reservePriority = 0;
}
reserve(t, e, i) {
if (i <= 0)
return C.log(this.tag, "Cannot start a motion with MotionPriority.NONE."), !1;
if (t === this.currentGroup && e === this.currentIndex)
return C.log(this.tag, "Motion is already playing.", this.dump(t, e)), !1;
if (t === this.reservedGroup && e === this.reservedIndex || t === this.reservedIdleGroup && e === this.reservedIdleIndex)
return C.log(this.tag, "Motion is already reserved.", this.dump(t, e)), !1;
if (i === 1) {
if (this.currentPriority !== 0)
return C.log(this.tag, "Cannot start idle motion because another motion is playing.", this.dump(t, e)), !1;
if (this.reservedIdleGroup !== void 0)
return C.log(this.tag, "Cannot start idle motion because another idle motion has reserved.", this.dump(t, e)), !1;
this.setReservedIdle(t, e);
} else {
if (i < 3) {
if (i <= this.currentPriority)
return C.log(this.tag, "Cannot start motion because another motion is playing as an equivalent or higher priority.", this.dump(t, e)), !1;
if (i <= this.reservePriority)
return C.log(this.tag, "Cannot start motion because another motion has reserved as an equivalent or higher priority.", this.dump(t, e)), !1;
}
this.setReserved(t, e, i);
}
return !0;
}
start(t, e, i, r) {
if (r === 1) {
if (this.setReservedIdle(void 0, void 0), this.currentPriority !== 0)
return C.log(this.tag, "Cannot start idle motion because another motion is playing.", this.dump(e, i)), !1;
} else {
if (e !== this.reservedGroup || i !== this.reservedIndex)
return C.log(this.tag, "Cannot start motion because another motion has taken the place.", this.dump(e, i)), !1;
this.setReserved(void 0, void 0, 0);
}
return t ? (this.setCurrent(e, i, r), !0) : !1;
}
complete() {
this.setCurrent(void 0, void 0, 0);
}
setCurrent(t, e, i) {
this.currentPriority = i, this.currentGroup = t, this.currentIndex = e;
}
setReserved(t, e, i) {
this.reservePriority = i, this.reservedGroup = t, this.reservedIndex = e;
}
setReservedIdle(t, e) {
this.reservedIdleGroup = t, this.reservedIdleIndex = e;
}
isActive(t, e) {
return t === this.currentGroup && e === this.currentIndex || t === this.reservedGroup && e === this.reservedIndex || t === this.reservedIdleGroup && e === this.reservedIdleIndex;
}
reset() {
this.setCurrent(void 0, void 0, 0), this.setReserved(void 0, void 0, 0), this.setReservedIdle(void 0, void 0);
}
shouldRequestIdleMotion() {
return this.currentGroup === void 0 && this.reservedIdleGroup === void 0;
}
shouldOverrideExpression() {
return !L.preserveExpressionOnMotion && this.currentPriority > 1;
}
dump(t, e) {
if (this.debug) {
const i = [
"currentPriority",
"reservePriority",
"currentGroup",
"currentIndex",
"reservedGroup",
"reservedIndex",
"reservedIdleGroup",
"reservedIdleIndex"
];
return `
<Requested> group = "${t}", index = ${e}
` + i.map((r) => "[" + r + "] " + this[r]).join(`
`);
}
return "";
}
}
const ze = "SoundManager", je = 0.5;
class Z {
static get volume() {
return this._volume;
}
static set volume(t) {
this._volume = (t > 1 ? 1 : t < 0 ? 0 : t) || 0, this.audios.forEach((e) => e.volume = this._volume);
}
static add(t, e, i) {
const r = new Audio(t);
return r.volume = this._volume, r.preload = "auto", r.addEventListener("ended", () => {
this.dispose(r), e == null || e();
}), r.addEventListener("error", (a) => {
this.dispose(r), C.warn(ze, `Error occurred on "${t}"`, a.error), i == null || i(a.error);
}), this.audios.push(r), r;
}
static play(t) {
return new Promise((e, i) => {
var r;
(r = t.play()) == null || r.catch((a) => {
t.dispatchEvent(new ErrorEvent("error", { error: a })), i(a);
}), t.readyState === t.HAVE_ENOUGH_DATA ? e() : t.addEventListener("canplaythrough", e);
});
}
static dispose(t) {
t.pause(), t.removeAttribute("src"), Ue(this.audios, t);
}
static destroy() {
for (let t = this.audios.length - 1; t >= 0; t--)
this.dispose(this.audios[t]);
}
}
Z.audios = [];
Z._volume = je;
var Ye = /* @__PURE__ */ ((s) => (s.ALL = "ALL", s.IDLE = "IDLE", s.NONE = "NONE", s))(Ye || {});
class Pt extends Bt {
constructor(t, e) {
super(), this.motionGroups = {}, this.state = new Xe(), this.playing = !1, this.destroyed = !1, this.settings = t, this.tag = `MotionManager(${t.name})`, this.state.tag = this.tag;
}
init(t) {
t != null && t.idleMotionGroup && (this.groups.idle = t.idleMotionGroup), this.setupMotions(t), this.stopAllMotions();
}
setupMotions(t) {
for (const i of Object.keys(this.definitions))
this.motionGroups[i] = [];
let e;
switch (t == null ? void 0 : t.motionPreload) {
case "NONE":
return;
case "ALL":
e = Object.keys(this.definitions);
break;
case "IDLE":
default:
e = [this.groups.idle];
break;
}
for (const i of e)
if (this.definitions[i])
for (let r = 0; r < this.definitions[i].length; r++)
this.loadMotion(i, r).then();
}
loadMotion(t, e) {
return I(this, null, function* () {
var i;
if (!((i = this.definitions[t]) != null && i[e])) {
C.warn(this.tag, `Undefined motion at "${t}"[${e}]`);
return;
}
if (this.motionGroups[t][e] === null) {
C.warn(this.tag, `Cannot start motion at "${t}"[${e}] because it's already failed in loading.`);
return;
}
if (this.motionGroups[t][e])
return this.motionGroups[t][e];
const r = yield this._loadMotion(t, e);
if (!this.destroyed)
return this.motionGroups[t][e] = r != null ? r : null, r;
});
}
_loadMotion(t, e) {
throw new Error("Not implemented.");
}
startMotion(t, e) {
return I(this, arguments, function* (i, r, a = Ft.NORMAL) {
var n;
if (!this.state.reserve(i, r, a))
return !1;
const o = (n = this.definitions[i]) == null ? void 0 : n[r];
if (!o)
return !1;
this.currentAudio && Z.dispose(this.currentAudio);
let l;
if (L.sound) {
const u = this.getSoundFile(o);
if (u)
try {
l = Z.add(this.settings.resolveURL(u), () => this.currentAudio = void 0, () => this.currentAudio = void 0), this.currentAudio = l;
} catch (c) {
C.warn(this.tag, "Failed to create audio", u, c);
}
}
const h = yield this.loadMotion(i, r);
if (l) {
const u = Z.play(l).catch((c) => C.warn(this.tag, "Failed to play audio", l.src, c));
L.motionSync && (yield u);
}
return this.state.start(h, i, r, a) ? (C.log(this.tag, "Start motion:", this.getMotionName(o)), this.emit("motionStart", i, r, l), this.state.shouldOverrideExpression() && this.expressionManager && this.expressionManager.resetExpression(), this.playing = !0, this._startMotion(h), !0) : (l && (Z.dispose(l), this.currentAudio = void 0), !1);
});
}
startRandomMotion(t, e) {
return I(this, null, function* () {
const i = this.definitions[t];
if (i != null && i.length) {
const r = [];
for (let a = 0; a < i.length; a++)
this.motionGroups[t][a] !== null && !this.state.isActive(t, a) && r.push(a);
if (r.length) {
const a = Math.floor(Math.random() * r.length);
return this.startMotion(t, r[a], e);
}
}
return !1;
});
}
stopAllMotions() {
this._stopAllMotions(), this.state.reset(), this.currentAudio && (Z.dispose(this.currentAudio), this.currentAudio = void 0);
}
update(t, e) {
var i;
return this.isFinished() && (this.playing && (this.playing = !1, this.emit("motionFinish")), this.state.shouldOverrideExpression() && ((i = this.expressionManager) == null || i.restoreExpression()), this.state.complete(), this.state.shouldRequestIdleMotion() && this.startRandomMotion(this.groups.idle, Ft.IDLE)), this.updateParameters(t, e);
}
destroy() {
var t;
this.destroyed = !0, this.emit("destroy"), this.stopAllMotions(), (t = this.expressionManager) == null || t.destroy();
const e = this;
e.definitions = void 0, e.motionGroups = void 0;
}
}
const We = { x: 0, y: 0, width: 0, height: 0 };
class _e extends Bt {
constructor() {
super(...arguments), this.focusController = new Ge(), this.originalWidth = 0, this.originalHeight = 0, this.width = 0, this.height = 0, this.localTransform = new yt(), this.drawingMatrix = new yt(), this.hitAreas = {}, this.textureFlipY = !1, this.viewport = [0, 0, 0, 0], this.destroyed = !1;
}
init() {
this.setupLayout(), this.setupHitAreas();
}
setupLayout() {
const t = this, e = this.getSize();
t.originalWidth = e[0], t.originalHeight = e[1];
const i = Object.assign({
width: Kt,
height: Qt
}, this.getLayout());
this.localTransform.scale(i.width / Kt, i.height / Qt), t.width = this.originalWidth * this.localTransform.a, t.height = this.originalHeight * this.localTransform.d;
const r = i.x !== void 0 && i.x - i.width / 2 || i.centerX !== void 0 && i.centerX || i.left !== void 0 && i.left - i.width / 2 || i.right !== void 0 && i.right + i.width / 2 || 0, a = i.y !== void 0 && i.y - i.height / 2 || i.centerY !== void 0 && i.centerY || i.top !== void 0 && i.top - i.height / 2 || i.bottom !== void 0 && i.bottom + i.height / 2 || 0;
this.localTransform.translate(this.width * r, -this.height * a);
}
setupHitAreas() {
const t = this.getHitAreaDefs().filter((e) => e.index >= 0);
for (const e of t)
this.hitAreas[e.name] = e;
}
hitTest(t, e) {
return Object.keys(this.hitAreas).filter((i) => this.isHit(i, t, e));
}
isHit(t, e, i) {
if (!this.hitAreas[t])
return !1;
const r = this.hitAreas[t].index, a = this.getDrawableBounds(r, We);
return a.x <= e && e <= a.x + a.width && a.y <= i && i <= a.y + a.height;
}
getDrawableBounds(t, e) {
const i = this.getDrawableVertices(t);
let r = i[0], a = i[0], n = i[1], o = i[1];
for (let l = 0; l < i.length; l += 2) {
const h = i[l], u = i[l + 1];
r = Math.min(h, r), a = Math.max(h, a), n = Math.min(u, n), o = Math.max(u, o);
}
return e != null || (e = {}), e.x = r, e.y = n, e.width = a - r, e.height = o - n, e;
}
updateTransform(t) {
this.drawingMatrix.copyFrom(t).append(this.localTransform);
}
update(t, e) {
this.focusController.update(t);
}
destroy() {
this.destroyed = !0, this.emit("destroy"), this.motionManager.destroy(), this.motionManager = void 0;
}
}
const He = "XHRLoader";
class ee extends Error {
constructor(t, e, i, r = !1) {
super(t), this.url = e, this.status = i, this.aborted = r;
}
}
const E = class {
static createXHR(s, t, e, i, r) {
const a = new XMLHttpRequest();
if (E.allXhrSet.add(a), s) {
let n = E.xhrMap.get(s);
n ? n.add(a) : (n = /* @__PURE__ */ new Set([a]), E.xhrMap.set(s, n)), s.listeners("destroy").includes(E.cancelXHRs) || s.once("destroy", E.cancelXHRs);
}
return a.open("GET", t), a.responseType = e, a.onload = () => {
(a.status === 200 || a.status === 0) && a.response ? i(a.response) : a.onerror();
}, a.onerror = () => {
C.warn(He, `Failed to load resource as ${a.responseType} (Status ${a.status}): ${t}`), r(new ee("Network error.", t, a.status));
}, a.onabort = () => r(new ee("Aborted.", t, a.status, !0)), a.onloadend = () => {
var n;
E.allXhrSet.delete(a), s && ((n = E.xhrMap.get(s)) == null || n.delete(a));
}, a;
}
static cancelXHRs() {
var s;
(s = E.xhrMap.get(this)) == null || s.forEach((t) => {
t.abort(), E.allXhrSet.delete(t);
}), E.xhrMap.delete(this);
}
static release() {
E.allXhrSet.forEach((s) => s.abort()), E.allXhrSet.clear(), E.xhrMap = /* @__PURE__ */ new WeakMap();
}
};
let Ct = E;
Ct.xhrMap = /* @__PURE__ */ new WeakMap();
Ct.allXhrSet = /* @__PURE__ */ new Set();
Ct.loader = (s, t) => new Promise((e, i) => {
E.createXHR(s.target, s.settings ? s.settings.resolveURL(s.url) : s.url, s.type, (a) => {
s.result = a, e();
}, i).send();
});
function fe(s, t) {
let e = -1;
return i(0);
function i(r, a) {
if (a)
return Promise.reject(a);
if (r <= e)
return Promise.reject(new Error("next() called multiple times"));
e = r;
const n = s[r];
if (!n)
return Promise.resolve();
try {
return Promise.resolve(n(t, i.bind(null, r + 1)));
} catch (o) {
return Promise.reject(o);
}
}
}
class j {
static load(t) {
return fe(this.middlewares, t).then(() => t.result);
}
}
j.middlewares = [Ct.loader];
function qe(s, t = {}) {
var e;
const i = { resourceOptions: { crossorigin: t.crossOrigin } };
if (It.fromURL)
return It.fromURL(s, i).catch((n) => {
if (n instanceof Error)
throw n;
const o = new Error("Texture loading error");
throw o.event = n, o;
});
i.resourceOptions.autoLoad = !1;
const r = It.from(s, i);
if (r.baseTexture.valid)
return Promise.resolve(r);
const a = r.baseTexture.resource;
return (e = a._live2d_load) != null || (a._live2d_load = new Promise((n, o) => {
const l = (h) => {
a.source.removeEventListener("error", l);
const u = new Error("Texture loading error");
u.event = h, o(u);
};
a.source.addEventListener("error", l), a.load().then(() => n(r)).catch(l);
})), a._live2d_load;
}
const ie = "Live2DFactory", ye = (s, t) => I(void 0, null, function* () {
if (typeof s.source == "string") {
const e = yield j.load({
url: s.source,
type: "json",
target: s.live2dModel
});
e.url = s.source, s.source = e, s.live2dModel.emit("settingsJSONLoaded", e);
}
return t();
}), xe = (s, t) => I(void 0, null, function* () {
if (s.source instanceof Mt)
return s.settings = s.source, t();
if (typeof s.source == "object") {
const e = b.findRuntime(s.source);
if (e) {
const i = e.createModelSettings(s.source);
return s.settings = i, s.live2dModel.emit("settingsLoaded", i), t();
}
}
throw new TypeError("Unknown settings format.");
}), ve = (s, t) => {
if (s.settings) {
const e = b.findRuntime(s.settings);
if (e)
return e.ready().then(t);
}
return t();
}, Me = (s, t) => I(void 0, null, function* () {
yield t();
const e = s.internalModel;
if (e) {
const i = s.settings, r = b.findRuntime(i);
if (r) {
const a = [];
i.pose && a.push(j.load({
settings: i,
url: i.pose,
type: "json",
target: e
}).then((n) => {
e.pose = r.createPose(e.coreModel, n), s.live2dModel.emit("poseLoaded", e.pose);
}).catch((n) => {
s.live2dModel.emit("poseLoadError", n), C.warn(ie, "Failed to load pose.", n);
})), i.physics && a.push(j.load({
settings: i,
url: i.physics,
type: "json",
target: e
}).then((n) => {
e.physics = r.createPhysics(e.coreModel, n), s.live2dModel.emit("physicsLoaded", e.physics);
}).catch((n) => {
s.live2dModel.emit("physicsLoadError", n), C.warn(ie, "Failed to load physics.", n);
})), a.length && (yield Promise.all(a));
}
}
}), Pe = (s, t) => I(void 0, null, function* () {
if (s.settings) {
const e = s.live2dModel, i = s.settings.textures.map((r) => {
const a = s.settings.resolveURL(r);
return qe(a, { crossOrigin: s.options.crossOrigin });
});
if (yield t(), s.internalModel)
e.internalModel = s.internalModel, e.emit("modelLoaded", s.internalModel);
else
throw new TypeError("Missing internal model.");
e.textures = yield Promise.all(i), e.emit("textureLoaded", e.textures);
} else
throw new TypeError("Missing settings.");
}), Ce = (s, t) => I(void 0, null, function* () {
const e = s.settings;
if (e instanceof Mt) {
const i = b.findRuntime(e);
if (!i)
throw new TypeError("Unknown model settings.");
const r = yield j.load({
settings: e,
url: e.moc,
type: "arraybuffer",
target: s.live2dModel
});
if (!i.isValidMoc(r))
throw new Error("Invalid moc data");
const a = i.createCoreModel(r);
return s.internalModel = i.createInternalModel(a, e, s.options), t();
}
throw new TypeError("Missing settings.");
}), T = class {
static registerRuntime(s) {
T.runtimes.push(s), T.runtimes.sort((t, e) => e.version - t.version);
}
static findRuntime(s) {
for (const t of T.runtimes)
if (t.test(s))
return t;
}
static setupLive2DModel(s, t, e) {
return I(this, null, function* () {
const i = new Promise((n) => s.once("textureLoaded", n)), r = new Promise((n) => s.once("modelLoaded", n)), a = Promise.all([i, r]).then(() => s.emit("ready"));
yield fe(T.live2DModelMiddlewares, {
live2dModel: s,
source: t,
options: e || {}
}), yield a, s.emit("load");
});
}
static loadMotion(s, t, e) {
var i, r;
const a = (n) => s.emit("motionLoadError", t, e, n);
try {
const n = (i = s.definitions[t]) == null ? void 0 : i[e];
if (!n)
return Promise.resolve(void 0);
s.listeners("destroy").includes(T.releaseTasks) || s.once("destroy", T.releaseTasks);
let o = T.motionTasksMap.get(s);
o || (o = {}, T.motionTasksMap.set(s, o));
let l = o[t];
l || (l = [], o[t] = l);
const h = s.getMotionFile(n);
return (r = l[e]) != null || (l[e] = j.load({
url: h,
settings: s.settings,
type: s.motionDataType,
target: s
}).then((u) => {
var c;
const d = (c = T.motionTasksMap.get(s)) == null ? void 0 : c[t];
d && delete d[e];
const _ = s.createMotion(u, t, n);
return s.emit("motionLoaded", t, e, _), _;
}).catch((u) => {
C.warn(s.tag, `Failed to load motion: ${h}
`, u), a(u);
})), l[e];
} catch (n) {
C.warn(s.tag, `Failed to load motion at "${t}"[${e}]
`, n), a(n);
}
return Promise.resolve(void 0);
}
static loadExpression(s, t) {
var e;
const i = (r) => s.emit("expressionLoadError", t, r);
try {
const r = s.definitions[t];
if (!r)
return Promise.resolve(void 0);
s.listeners("destroy").includes(T.releaseTasks) || s.once("destroy", T.releaseTasks);
let a = T.expressionTasksMap.get(s);
a || (a = [], T.expressionTasksMap.set(s, a));
const n = s.getExpressionFile(r);
return (e = a[t]) != null || (a[t] = j.load({
url: n,
settings: s.settings,
type: "json",
target: s
}).then((o) => {
const l = T.expressionTasksMap.get(s);
l && delete l[t];
const h = s.createExpression(o, r);
return s.emit("expressionLoaded", t, h), h;
}).catch((o) => {
C.warn(s.tag, `Failed to load expression: ${n}
`, o), i(o);
})), a[t];
} catch (r) {
C.warn(s.tag, `Failed to load expression at [${t}]
`, r), i(r);
}
return Promise.resolve(void 0);
}
static releaseTasks() {
this instanceof Pt ? T.motionTasksMap.delete(this) : T.expressionTasksMap.delete(this);
}
};
let b = T;
b.runtimes = [];
b.urlToJSON = ye;
b.jsonToSettings = xe;
b.waitUntilReady = ve;
b.setupOptionals = Me;
b.setupEssentials = Pe;
b.createInternalModel = Ce;
b.live2DModelMiddlewares = [
ye,
xe,
ve,
Me,
Pe,
Ce
];
b.motionTasksMap = /* @__PURE__ */ new WeakMap();
b.expressionTasksMap = /* @__PURE__ */ new WeakMap();
Pt.prototype._loadMotion = function(s, t) {
return b.loadMotion(this, s, t);
};
Ut.prototype._loadExpression = function(s) {
return b.loadExpression(this, s);
};
class $e {
constructor() {
this._autoInteract = !1;
}
get autoInteract() {
return this._autoInteract;
}
set autoInteract(t) {
t !== this._autoInteract && (t ? this.on("pointertap", se, this) : this.off("pointertap", se, this), this._autoInteract = t);
}
registerInteraction(t) {
t !== this.interactionManager && (this.unregisterInteraction(), this._autoInteract && t && (this.interactionManager = t, t.on("pointermove", re, this)));
}
unregisterInteraction() {
var t;
this.interactionManager && ((t = this.interactionManager) == null || t.off("pointermove", re, this), this.interactionManager = void 0);
}
}
function se(s) {
this.tap(s.data.global.x, s.data.global.y);
}
function re(s) {
this.focus(s.data.global.x, s.data.global.y);
}
class Je extends De {
}
const D = new Ae(), Ze = new yt();
let G;
class Ke extends Re {
constructor(t) {
super(), this.tag = "Live2DModel(uninitialized)", this.textures = [], this.transform = new Je(), this.anchor = new Oe(this.onAnchorChange, this, 0, 0), this.glContextID = -1, this.elapsedTime = performance.now(), this.deltaTime = 0, this._autoUpdate = !1, this.once("modelLoaded", () => this.init(t));
}
static from(t, e) {
const i = new this(e);
return b.setupLive2DModel(i, t, e).then(() => i);
}
static fromSync(t, e) {
const i = new this(e);
return b.setupLive2DModel(i, t, e).then(e == null ? void 0 : e.onLoad).catch(e == null ? void 0 : e.onError), i;
}
static registerTicker(t) {
G = t;
}
get autoUpdate() {
return this._autoUpdate;
}
set autoUpdate(t) {
var e;
G || (G = (e = window.PIXI) == null ? void 0 : e.Ticker), t ? this._destroyed || (G ? (G.shared.add(this.onTickerUpdate, this), this._autoUpdate = !0) : C.warn(this.tag, "No Ticker registered, please call Live2DModel.registerTicker(Ticker).")) : (G == null || G.shared.remove(this.onTickerUpdate, this), this._autoUpdate = !1);
}
init(t) {
this.tag = `Live2DModel(${this.internalModel.settings.name})`;
const e = Object.assign({
autoUpdate: !0,
autoInteract: !0
}, t);
e.autoInteract && (this.interactive = !0), this.autoInteract = e.autoInteract, this.autoUpdate = e.autoUpdate;
}
onAnchorChange() {
this.pivot.set(this.anchor.x * this.internalModel.width, this.anchor.y * this.internalModel.height);
}
motion(t, e, i) {
return e === void 0 ? this.internalModel.motionManager.startRandomMotion(t, i) : this.internalModel.motionManager.startMotion(t, e, i);
}
expression(t) {
return this.internalModel.motionManager.expressionManager ? t === void 0 ? this.internalModel.motionManager.expressionManager.setRandomExpression() : this.internalModel.motionManager.expressionManager.setExpression(t) : Promise.resolve(!1);
}
focus(t, e, i = !1) {
D.x = t, D.y = e, this.toModelPosition(D, D, !0);
let r = D.x / this.internalModel.originalWidth * 2 - 1, a = D.y / this.internalModel.originalHeight * 2 - 1, n = Math.atan2(a, r);
this.internalModel.focusController.focus(Math.cos(n), -Math.sin(n), i);
}
tap(t, e) {
const i = this.hitTest(t, e);
i.length && (C.log(this.tag, "Hit", i), this.emit("hit", i));
}
hitTest(t, e) {
return D.x = t, D.y = e, this.toModelPosition(D, D), this.internalModel.hitTest(D.x, D.y);
}
toModelPosition(t, e = t.clone(), i) {
return i || (this._recursivePostUpdateTransform(), this.parent ? this.displayObjectUpdateTransform() : (this.parent = this._tempDisplayObjectParent, this.displayObjectUpdateTransform(), this.parent = null)), this.transform.worldTransform.applyInverse(t, e), this.internalModel.localTransform.applyInverse(e, e), e;
}
containsPoint(t) {
return this.getBounds(!0).contains(t.x, t.y);
}
_calculateBounds() {
this._bounds.addFrame(this.transform, 0, 0, this.internalModel.width, this.internalModel.height);
}
onTickerUpdate() {
this.update(G.shared.deltaMS);
}
update(t) {
this.deltaTime += t, this.elapsedTime += t;
}
_render(t) {
this.registerInteraction(t.plugins.interaction), t.batch.reset(), t.geometry.reset(), t.shader.reset(), t.state.reset();
let e = !1;
this.glContextID !== t.CONTEXT_UID && (this.glContextID = t.CONTEXT_UID, this.internalModel.updateWebGLContext(t.gl, this.glContextID), e = !0);
for (let a = 0; a < this.textures.length; a++) {
const n = this.textures[a];
n.valid && ((e || !n.baseTexture._glTextures[this.glContextID]) && (t.gl.pixelStorei(WebGLRenderingContext.UNPACK_FLIP_Y_WEBGL, this.internalModel.textureFlipY), t.texture.bind(n.baseTexture, 0)), this.internalModel.bindTexture(a, n.baseTexture._glTextures[this.glContextID].texture), n.baseTexture.touched = t.textureGC.count);
}
const i = t.framebuffer.viewport;
this.internalModel.viewport = [i.x, i.y, i.width, i.height], this.deltaTime && (this.internalModel.update(this.deltaTime, this.elapsedTime), this.deltaTime = 0);
const r = Ze.copyFrom(t.globalUniforms.uniforms.projectionMatrix).append(this.worldTransform);
this.internalModel.updateTransform(r), this.internalModel.draw(t.gl), t.state.reset(), t.texture.reset();
}
destroy(t) {
this.emit("destroy"), this.autoUpdate = !1, this.unregisterInteraction(), t != null && t.texture && this.textures.forEach((e) => e.destroy(t.baseTexture)), this.internalModel.destroy(), super.destroy(t);
}
}
pe(Ke, [$e]);
const U = class {
static resolveURL(s, t) {
var e;
const i = (e = U.filesMap[s]) == null ? void 0 : e[t];
if (i === void 0)
throw new Error("Cannot find this file from uploaded files: " + t);
return i;
}
static upload(s, t) {
return I(this, null, function* () {
const e = {};
for (const i of t.getDefinedFiles()) {
const r = decodeURI(kt.resolve(t.url, i)), a = s.find((n) => n.webkitRelativePath === r);
a && (e[i] = URL.createObjectURL(a));
}
U.filesMap[t._objectURL] = e;
});
}
static createSettings(s) {
return I(this, null, function* () {
const t = s.find((n) => n.name.endsWith("model.json") || n.name.endsWith("model3.json"));
if (!t)
throw new TypeError("Settings file not found");
const e = yield U.readText(t), i = JSON.parse(e);
i.url = t.webkitRelativePath;
const r = b.findRuntime(i);
if (!r)
throw new Error("Unknown settings JSON");
const a = r.createModelSettings(i);
return a._objectURL = URL.createObjectURL(t), a;
});
}
static readText(s) {
return I(this, null, function* () {
return new Promise((t, e) => {
const i = new FileReader();
i.onload = () => t(i.result), i.onerror = e, i.readAsText(s, "utf8");
});
});
}
};
let Vt = U;
Vt.filesMap = {};
Vt.factory = (s, t) => I(void 0, null, function* () {
if (Array.isArray(s.source) && s.source[0] instanceof File) {
const e = s.source;
let i = e.settings;
if (!i)
i = yield U.createSettings(e);
else if (!i._objectURL)
throw new Error('"_objectURL" must be specified in ModelSettings');
i.validateFiles(e.map((r) => encodeURI(r.webkitRelativePath))), yield U.upload(e, i), i.resolveURL = function(r) {
return U.resolveURL(this._objectURL, r);
}, s.source = i, s.live2dModel.once("modelLoaded", (r) => {
r.once("destroy", function() {
const a = this.settings._objectURL;
if (URL.revokeObjectURL(a), U.filesMap[a])
for (const n of Object.values(U.filesMap[a]))
URL.revokeObjectURL(n);
delete U.filesMap[a];
});
});
}
return t();
});
b.live2DModelMiddlewares.unshift(Vt.factory);
const F = class {
static unzip(s, t) {
return I(this, null, function* () {
const e = yield F.getFilePaths(s), i = [];
for (const a of t.getDefinedFiles()) {
const n = decodeURI(kt.resolve(t.url, a));
e.includes(n) && i.push(n);
}
const r = yield F.getFiles(s, i);
for (let a = 0; a < r.length; a++) {
const n = i[a], o = r[a];
Object.defineProperty(o, "webkitRelativePath", {
value: n
});
}
return r;
});
}
static createSettings(s) {
return I(this, null, function* () {
const e = (yield F.getFilePaths(s)).find((n) => n.endsWith("model.json") || n.endsWith("model3.json"));
if (!e)
throw new Error("Settings file not found");
const i = yield F.readText(s, e);
if (!i)
throw new Error("Empty settings file: " + e);
const r = JSON.parse(i);
r.url = e;
const a = b.findRuntime(r);
if (!a)
throw new Error("Unknown settings JSON");
return a.createModelSettings(r);
});
}
static zipReader(s, t) {
return I(this, null, function* () {
throw new Error("Not implemented");
});
}
static getFilePaths(s) {
return I(this, null, function* () {
throw new Error("Not implemented");
});
}
static getFiles(s, t) {
return I(this, null, function* () {
throw new Error("Not implemented");
});
}
static readText(s, t) {
return I(this, null, function* () {
throw new Error("Not implemented");
});
}
static releaseReader(s) {
}
};
let St = F;
St.ZIP_PROTOCOL = "zip://";
St.uid = 0;
St.factory = (s, t) => I(void 0, null, function* () {
const e = s.source;
let i, r, a;
if (typeof e == "string" && (e.endsWith(".zip") || e.startsWith(F.ZIP_PROTOCOL)) ? (e.startsWith(F.ZIP_PROTOCOL) ? i = e.slice(F.ZIP_PROTOCOL.length) : i = e, r = yield j.load({
url: i,
type: "blob",
target: s.live2dModel
})) : Array.isArray(e) && e.length === 1 && e[0] instanceof File && e[0].name.endsWith(".zip") && (r = e[0], i = URL.createObjectURL(r), a = e.settings), r) {
if (!r.size)
throw new Error("Empty zip file");
const n = yield F.zipReader(r, i);
a || (a = yield F.createSettings(n)), a._objectURL = F.ZIP_PROTOCOL + F.uid + "/" + a.url;
const o = yield F.unzip(n, a);
o.settings = a, s.source = o, i.startsWith("blob:") && s.live2dModel.once("modelLoaded", (l) => {
l.once("destroy", function() {
URL.revokeObjectURL(i);
});
}), F.releaseReader(n);
}
return t();
});
b.live2DModelMiddlewares.unshift(St.factory);
if (!window.Live2D)
throw new Error("Could not find Cubism 2 runtime. This plugin requires live2d.min.js to be loaded.");
const Qe = Live2DMotion.prototype.updateParam;
Live2DMotion.prototype.updateParam = function(s, t) {
Qe.call(this, s, t), t.isFinished() && this.onFinishHandler && (this.onFinishHandler(this), delete this.onFinishHandler);
};
class ti extends AMotion {
constructor(t) {
super(), this.params = [], this.setFadeIn(t.fade_in > 0 ? t.fade_in : L.expressionFadingDuration), this.setFadeOut(t.fade_out > 0 ? t.fade_out : L.expressionFadingDuration), Array.isArray(t.params) && t.params.forEach((e) => {
const i = e.calc || "add";
if (i === "add") {
const r = e.def || 0;
e.val -= r;
} else if (i === "mult") {
const r = e.def || 1;
e.val /= r;
}
this.params.push({
calc: i,
val: e.val,
id: e.id
});
});
}
updateParamExe(t, e, i, r) {
this.params.forEach((a) => {
t.setParamFloat(a.id, a.val * i);
});
}
}
class ei extends Ut {
constructor(t, e) {
var i;
super(t, e), this.queueManager = new MotionQueueManager(), this.definitions = (i = this.settings.expressions) != null ? i : [], this.init();
}
isFinished() {
return this.queueManager.isFinished();
}
getExpressionIndex(t) {
return this.definitions.findIndex((e) => e.name === t);
}
getExpressionFile(t) {
return t.file;
}
createExpression(t, e) {
return new ti(t);
}
_setExpression(t) {
return this.queueManager.startMotion(t);
}
stopAllExpressions() {
this.queueManager.stopAllMotions();
}
updateParameters(t, e) {
return this.queueManager.updateParam(t);
}
}
class ii extends Pt {
constructor(t, e) {
super(t, e), this.groups = { idle: "idle" }, this.motionDataType = "arraybuffer", this.queueManager = new MotionQueueManager(), this.definitions = this.settings.motions, this.init(e);
}
init(t) {
super.init(t), this.settings.expressions && (this.expressionManager = new ei(this.settings, t));
}
isFinished() {
return this.queueManager.isFinished();
}
createMotion(t, e, i) {
const r = Live2DMotion.loadMotion(t), a = e === this.groups.idle ? L.idleMotionFadingDuration : L.motionFadingDuration;
return r.setFadeIn(i.fade_in > 0 ? i.fade_in : a), r.setFadeOut(i.fade_out > 0 ? i.fade_out : a), r;
}
getMotionFile(t) {
return t.file;
}
getMotionName(t) {
return t.file;
}
getSoundFile(t) {
return t.sound;
}
_startMotion(t, e) {
return t.onFinishHandler = e, this.queueManager.stopAllMotions(), this.queueManager.startMotion(t);
}
_stopAllMotions() {
this.queueManager.stopAllMotions();
}
updateParameters(t, e) {
return this.queueManager.updateParam(t);
}
destroy() {
super.destroy(), this.queueManager = void 0;
}
}
class si {
constructor(t) {
this.coreModel = t, this.blinkInterval = 4e3, this.closingDuration = 100, this.closedDuration = 50, this.openingDuration = 150, this.eyeState = 0, this.eyeParamValue = 1, this.closedTimer = 0, this.nextBlinkTimeLeft = this.blinkInterval, this.leftParam = t.getParamIndex("PARAM_EYE_L_OPEN"), this.rightParam = t.getParamIndex("PARAM_EYE_R_OPEN");
}
setEyeParams(t) {
this.eyeParamValue = xt(t, 0, 1), this.coreModel.setParamFloat(this.leftParam, this.eyeParamValue), this.coreModel.setParamFloat(this.rightParam, this.eyeParamValue);
}
update(t) {
switch (this.eyeState) {
case 0:
this.nextBlinkTimeLeft -= t, this.nextBlinkTimeLeft < 0 && (this.eyeState = 1, this.nextBlinkTimeLeft = this.blinkInterval + this.closingDuration + this.closedDuration + this.openingDuration + Be(0, 2e3));
break;
case 1:
this.setEyeParams(this.eyeParamValue + t / this.closingDuration), this.eyeParamValue <= 0 && (this.eyeState = 2, this.closedTimer = 0);
break;
case 2:
this.closedTimer += t, this.closedTimer >= this.closedDuration && (this.eyeState = 3);
break;
case 3:
this.setEyeParams(this.eyeParamValue + t / this.openingDuration), this.eyeParamValue >= 1 && (this.eyeState = 0);
}
}
}
const W = new Float32Array([
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1
]);
class ri extends _e {
constructor(t, e, i) {
super(), this.textureFlipY = !0, this.drawDataCount = 0, this.disableCulling = !1, this.coreModel = t, this.settings = e, this.motionManager = new ii(e, i), this.eyeBlink = new si(t), this.eyeballXParamIndex = t.getParamIndex("PARAM_EYE_BALL_X"), this.eyeballYParamIndex = t.getParamIndex("PARAM_EYE_BALL_Y"), this.angleXParamIndex = t.getParamIndex("PARAM_ANGLE_X"), this.angleYParamIndex = t.getParamIndex("PARAM_ANGLE_Y"), this.angleZParamIndex = t.getParamIndex("PARAM_ANGLE_Z"), this.bodyAngleXParamIndex = t.getParamIndex("PARAM_BODY_ANGLE_X"), this.breathParamIndex = t.getParamIndex("PARAM_BREATH"), this.init();
}
init() {
super.init(), this.settings.initParams && this.settings.initParams.forEach(({ id: a, value: n }) => this.coreModel.setParamFloat(a, n)), this.settings.initOpacities && this.settings.initOpacities.forEach(({ id: a, value: n }) => this.coreModel.setPartsOpacity(a, n)), this.coreModel.saveParam();
const t = this.coreModel.getModelContext()._$aS;
t != null && t.length && (this.drawDataCount = t.length);
let e = this.coreModel.drawParamWebGL.culling;
Object.defineProperty(this.coreModel.drawParamWebGL, "culling", {
set: (a) => e = a,
get: () => this.disableCulling ? !1 : e
});
const i = this.coreModel.getModelContext().clipManager, r = i.setupClip;
i.setupClip = (a, n) => {
r.call(i, a, n), n.gl.viewport(...this.viewport);
};
}
getSize() {
return [this.coreModel.getCanvasWidth(), this.coreModel.getCanvasHeight()];
}
getLayout() {
const t = {};
if (this.settings.layout)
for (const e of Object.keys(this.settings.layout)) {
let i = e;
e === "center_x" ? i = "centerX" : e === "center_y" && (i = "centerY"), t[i] = this.settings.layout[e];
}
return t;
}
updateWebGLContext(t, e) {
const i = this.coreModel.drawParamWebGL;
i.firstDraw = !0, i.setGL(t), i.glno = e;
for (const n in i)
i.hasOwnProperty(n) && i[n] instanceof WebGLBuffer && (i[n] = null);
const r = this.coreModel.getModelContext().clipManager;
r.curFrameNo = e;
const a = t.getParameter(t.FRAMEBUFFER_BINDING);
r.getMaskRenderTexture(), t.bindFramebuffer(t.FRAMEBUFFER, a);
}
bindTexture(t, e) {
this.coreModel.setTexture(t, e);
}
getHitAreaDefs() {
var t;
return ((t = this.settings.hitAreas) == null ? void 0 : t.map((e) => ({
id: e.id,
name: e.name,
index: this.coreModel.getDrawDataIndex(e.id)
}))) || [];
}
getDrawableIDs() {
const t = this.coreModel.getModelContext(), e = [];
for (let i = 0; i < this.drawDataCount; i++) {
const r = t.getDrawData(i);
r && e.push(r.getDrawDataID().id);
}
return e;
}
getDrawableIndex(t) {
return this.coreModel.getDrawDataIndex(t);
}
getDrawableVertices(t) {
if (typeof t == "string" && (t = this.coreModel.getDrawDataIndex(t), t === -1))
throw new TypeError("Unable to find drawable ID: " + t);
return this.coreModel.getTransformedPoints(t).slice();
}
update(t, e) {
var i, r, a, n;
super.update(t, e);
const o = this.coreModel;
this.emit("beforeMotionUpdate");
const l = this.motionManager.update(this.coreModel, e);
this.emit("afterMotionUpdate"), o.saveParam(), (i = this.motionManager.expressionManager) == null || i.update(o, e), l || (r = this.eyeBlink) == null || r.update(t), this.updateFocus(), this.updateNaturalMovements(t, e), (a = this.physics) == null || a.update(e), (n = this.pose) == null || n.update(t), this.emit("beforeModelUpdate"), o.update(), o.loadParam();
}
updateFocus() {
this.coreModel.addToParamFloat(this.eyeballXParamIndex, this.focusController.x), this.coreModel.addToParamFloat(this.eyeballYParamIndex, this.focusController.y), this.coreModel.addToParamFloat(this.angleXParamIndex, this.focusController.x * 30), this.coreModel.addToParamFloat(this.angleYParamIndex, this.focusController.y * 30), this.coreModel.addToParamFloat(this.angleZParamIndex, this.focusController.x * this.focusController.y * -30), this.coreModel.addToParamFloat(this.bodyAngleXParamIndex, this.focusController.x * 10);
}
updateNaturalMovements(t, e) {
const i = e / 1e3 * 2 * Math.PI;
this.coreModel.addToParamFloat(this.angleXParamIndex, 15 * Math.sin(i / 6.5345) * 0.5), this.coreModel.addToParamFloat(this.angleYParamIndex, 8 * Math.sin(i / 3.5345) * 0.5), this.coreModel.addToParamFloat(this.angleZParamIndex, 10 * Math.sin(i / 5.5345) * 0.5), this.coreModel.addToParamFloat(this.bodyAngleXParamIndex, 4 * Math.sin(i / 15.5345) * 0.5), this.coreModel.setParamFloat(this.breathParamIndex, 0.5 + 0.5 * Math.sin(i / 3.2345));
}
draw(t) {
const e = this.disableCulling;
t.getParameter(t.FRAMEBUFFER_BINDING) && (this.disableCulling = !0);
const i = this.drawingMatrix;
W[0] = i.a, W[1] = i.b, W[4] = i.c, W[5] = i.d, W[12] = i.tx, W[13] = i.ty, this.coreModel.setMatrix(W), this.coreModel.draw(), this.disableCulling = e;
}
destroy() {
super.destroy(), this.coreModel = void 0;
}
}
class ct extends Mt {
constructor(t) {
if (super(t), this.motions = {}, !ct.isValidJSON(t))
throw new TypeError("Invalid JSON.");
this.moc = t.model, at("string", t, this, "textures", "textures"), this.copy(t);
}
static isValidJSON(t) {
var e;
return !!t && typeof t.model == "string" && ((e = t.textures) == null ? void 0 : e.length) > 0 && t.textures.every((i) => typeof i == "string");
}
copy(t) {
rt("string", t, this, "name", "name"), rt("string", t, this, "pose", "pose"), rt("string", t, this, "physics", "physics"), rt("object", t, this, "layout", "layout"), rt("object", t, this, "motions", "motions"), at("object", t, this, "hit_areas", "hitAreas"), at("object", t, this, "expressions", "expressions"), at("object", t, this, "init_params", "initParams"), at("object", t, this, "init_opacities", "initOpacities");
}
replaceFiles(t) {
super.replaceFiles(t);
for (const [e, i] of Object.entries(this.motions))
for (let r = 0; r < i.length; r++)
i[r].file = t(i[r].file, `motions.${e}[${r}].file`), i[r].sound !== void 0 && (i[r].sound = t(i[r].sound, `motions.${e}[${r}].sound`));
if (this.expressions)
for (let e = 0; e < this.expressions.length; e++)
this.expressions[e].file = t(this.expressions[e].file, `expressions[${e}].file`);
}
}
const ai = {
x: PhysicsHair.Src.SRC_TO_X,
y: PhysicsHair.Src.SRC_TO_Y,
angle: PhysicsHair.Src.SRC_TO_G_ANGLE
}, ni = {
x: PhysicsHair.Src.SRC_TO_X,
y: PhysicsHair.Src.SRC_TO_Y,
angle: PhysicsHair.Src.SRC_TO_G_ANGLE
};
class oi {
constructor(t, e) {
this.coreModel = t, this.physicsHairs = [], e.physics_hair && (this.physicsHairs = e.physics_hair.map((i) => {
const r = new PhysicsHair();
return r.setup(i.setup.length, i.setup.regist, i.setup.mass), i.src.forEach(({ id: a, ptype: n, scale: o, weight: l }) => {
const h = ai[n];
h && r.addSrcParam(h, a, o, l);
}), i.targets.forEach(({ id: a, ptype: n, scale: o, weight: l }) => {
const h = ni[n];
h && r.addTargetParam(h, a, o, l);
}), r;
}));
}
update(t) {
this.physicsHairs.forEach((e) => e.update(this.coreModel, t));
}
}
class ae {
constructor(t) {
this.id = t, this.paramIndex = -1, this.partsIndex = -1, this.link = [];
}
initIndex(t) {
this.paramIndex = t.getParamIndex("VISIBLE:" + this.id), this.partsIndex = t.getPartsDataIndex(PartsDataID.getID(this.id)), t.setParamFloat(this.paramIndex, 1);
}
}
class li {
constructor(t, e) {
this.coreModel = t, this.opacityAnimDuration = 500, this.partsGroups = [], e.parts_visible && (this.partsGroups = e.parts_visible.map(({ group: i }) => i.map(({ id: r, link: a }) => {
const n = new ae(r);
return a && (n.link = a.map((o) => new ae(o))), n;
})), this.init());
}
init() {
this.partsGroups.forEach((t) => {
t.forEach((e) => {
if (e.initIndex(this.coreModel), e.paramIndex >= 0) {
const i = this.coreModel.getParamFloat(e.paramIndex) !== 0;
this.coreModel.setPartsOpacity(e.partsIndex, i ? 1 : 0), this.coreModel.setParamFloat(e.paramIndex, i ? 1 : 0), e.link.length > 0 && e.link.forEach((r) => r.initIndex(this.coreModel));
}
});
});
}
normalizePartsOpacityGroup(t, e) {
const i = this.coreModel, r = 0.5, a = 0.15;
let n = 1, o = t.findIndex(({ paramIndex: l, partsIndex: h }) => h >= 0 && i.getParamFloat(l) !== 0);
if (o >= 0) {
const l = i.getPartsOpacity(t[o].partsIndex);
n = xt(l + e / this.opacityAnimDuration, 0, 1);
} else
o = 0, n = 1;
t.forEach(({ partsIndex: l }, h) => {
if (l >= 0)
if (o == h)
i.setPartsOpacity(l, n);
e