';
if (at.kind === 'text') {
rows += ced_renderTagHelp('trigger');
}
}
});
if (hasAny) {
return '
' + rows + '
';
}
return '';
}
// ── Render messages sub-list (plain strings) ──
function ie_renderMessages(step, secId, idx, si, secPath) {
var present = step && Array.isArray(step.messages);
if (!present) {
return '';
}
var msgs = step.messages;
var rmFn = 'ie_removeMessage(this,\'' + escAttr(secId) + '\',\'' + escAttr(secPath) + '\',' + idx + ',' + si + ')';
var h = '
';
h += '
Messages
';
h += '
';
msgs.forEach(function(m, mi) {
var upBtn = mi > 0
? ''
: '';
var dnBtn = mi < msgs.length - 1
? ''
: '';
h += '
' + upBtn + dnBtn + '
';
});
h += '
';
h += '';
h += ced_renderTagHelp('trigger');
h += '
';
return h;
}
// ── Render steps list of a trigger entry ──
function ie_renderStepList(steps, secId, idx, secPath) {
steps = steps || [];
var h = '
';
steps.forEach(function(step, si) {
var stepCond = step && step.condition && typeof step.condition === 'object';
h += '
';
h += '
';
h += 'Step ' + (si + 1) + '';
h += '';
if (!stepCond) {
h += '';
}
h += '';
if (si > 0) h += '';
if (si < steps.length - 1) h += '';
h += '';
h += '
';
if (stepCond) {
h += '
';
h += ie_renderCond(step.condition || null, secId, idx, secPath, 'step-' + si);
h += '
';
return h;
}
// ── Collect effects (everything except messages and condition) ──
function ie_collectAct(container) {
if (!container) return null;
var r = {};
container.querySelectorAll('.ie-act-kv').forEach(function(kvEl) {
var key = kvEl.getAttribute('data-ie-act-key');
if (!key) return;
if (key === 'messages') return;
if (key === 'drop_table') {
var dt = ie_collectDropTableBlock(kvEl.querySelector('.ie-drop-table'));
if (dt) r.drop_table = dt;
return;
}
var map = {};
kvEl.querySelectorAll('.ie-kv-row').forEach(function(row) {
var kEl = row.querySelector('.ie-kv-key');
var vEl = row.querySelector('.ie-kv-val');
if (kEl && kEl.value.trim() && vEl) {
var v = vEl.value.trim();
var num = parseFloat(v);
map[kEl.value.trim()] = v === 'true' ? true : (v === 'false' ? false : (!isNaN(num) ? num : v));
}
});
r[key] = map;
});
container.querySelectorAll('.ie-act-input').forEach(function(el) {
var key = el.getAttribute('data-ie-act-key');
if (!key) return;
var kind = el.getAttribute('data-ie-act-kind');
if (kind === 'checkbox') {
r[key] = el.checked;
} else if (kind === 'number') {
var n = parseFloat(el.value);
if (isNaN(n)) return;
r[key] = n;
} else {
r[key] = el.value.trim();
}
});
if (Object.keys(r).length === 0) return null;
return r;
}
// ── Collect messages (plain strings) ──
function ie_collectMessages(container) {
if (!container) return null;
var msgsKv = container.querySelector('.ie-act-kv[data-ie-act-key="messages"]');
if (!msgsKv) return null;
var list = [];
msgsKv.querySelectorAll('.ie-kv-row .ie-act-msg').forEach(function(el) {
list.push(el.value.trim());
});
return list;
}
// ── Sync a single step's DOM back into data ──
function ie_syncStep(ed, secId, secPath, idx, si) {
var card = document.querySelector('.obj-card[data-card="' + secId + '"]');
if (!card) return;
var stepRow = card.querySelector('.obj-sub-row.ie-inter-row[data-idx="' + idx + '"] .ie-step-row[data-step="' + si + '"]');
if (!stepRow) return;
if (!ed[secPath] || !ed[secPath][idx] || !ed[secPath][idx].steps || !ed[secPath][idx].steps[si]) return;
var step = ed[secPath][idx].steps[si];
var condRoot = stepRow.querySelector(':scope > .ie-step-cond-panel .ie-cond-root');
if (condRoot) {
var cond = ie_collectCond(condRoot);
if (cond) step.condition = cond; else delete step.condition;
}
var effContainer = stepRow.querySelector(':scope > .ie-step-effects');
if (effContainer) {
var act = ie_collectAct(effContainer);
if (act) {
Object.keys(act).forEach(function(k) { step[k] = act[k]; });
}
// Drop keys the user X'd out (no longer present in the DOM among the rendered IE_ACT_TYPES set).
IE_ACT_TYPES.forEach(function(at) {
if (at.key === 'messages') return;
if (!Object.prototype.hasOwnProperty.call(act || {}, at.key)) {
if (Object.prototype.hasOwnProperty.call(step, at.key)) delete step[at.key];
}
});
}
var msgsContainer = stepRow.querySelector(':scope > .ie-step-messages');
if (msgsContainer) {
var list = ie_collectMessages(msgsContainer);
if (list !== null) step.messages = list;
else delete step.messages;
if (Array.isArray(step.messages) && step.messages.length === 0) {
// keep empty array — survives next render, ced_cleanOutput will strip
// it on save.
}
}
}
// ── Sync all interaction DOM back to data ──
function ie_syncAllInteractions(data, secs) {
if (!data || !secs) return;
secs.forEach(function(sec) {
if (!sec.interactionStyle || !sec.isArray) return;
var p = sec.path;
if (!data[p]) return;
var card = document.querySelector('.obj-card[data-card="' + sec.id + '"]');
if (!card) return;
var rows = card.querySelectorAll('.obj-sub-row.ie-inter-row');
rows.forEach(function(row, idx) {
if (!data[p][idx]) data[p][idx] = {};
var lockCb = row.querySelector(':scope > .ie-inter-header .ie-lock-cb');
if (lockCb) {
if (lockCb.checked) data[p][idx].lock = true;
else delete data[p][idx].lock;
}
var entryCondRoot = row.querySelector(':scope > .ie-inter-panel .ie-cond-root');
if (entryCondRoot) {
var cond = ie_collectCond(entryCondRoot);
if (cond) data[p][idx].condition = cond;
else delete data[p][idx].condition;
}
if (!data[p][idx].steps) data[p][idx].steps = [];
var stepRows = row.querySelectorAll(':scope > .ie-inter-steps .ie-step-row');
stepRows.forEach(function(stepRow) {
var si = parseInt(stepRow.getAttribute('data-step'), 10);
if (isNaN(si)) return;
ie_syncStep(data, sec.id, p, idx, si);
});
});
});
}
// ── Add/Remove/Toggle: Condition ──
function ie_addLeaf(el, secId, secPath, idx, kind, groupPath, leafType) {
var c = _ie_condCtx(el, secId, secPath, idx, kind);
var cond = c.get();
var leaf = {};
leaf[leafType] = (leafType === 'min_credits' || leafType === 'room') ? 0 : '';
var group = ie_condAt(cond, groupPath);
var newGroup;
if (!group) {
newGroup = leaf;
} else if (group.all_of || group.any_of) {
var mode = group.all_of ? 'all_of' : 'any_of';
var children = (group.all_of || group.any_of).concat([leaf]);
newGroup = {};
if (group.not) newGroup.not = true;
newGroup[mode] = children;
} else {
newGroup = {all_of: [group, leaf]};
}
cond = ie_condReplace(cond, groupPath, newGroup);
c.set(cond);
c.change();
}
function ie_removeCond(el, secId, secPath, idx, kind, groupPath, childIdx) {
var c = _ie_condCtx(el, secId, secPath, idx, kind);
var cond = c.get();
if (childIdx === IE_ROOT_LEAF) {
c.set(null);
c.change();
return;
}
var group = ie_condAt(cond, groupPath);
if (!group) return;
if (group.all_of || group.any_of) {
var mode = group.all_of ? 'all_of' : 'any_of';
var children = (group.all_of || group.any_of).slice();
children.splice(childIdx, 1);
var newGroup;
if (children.length === 0) {
newGroup = null;
} else if (children.length === 1 && !group.not) {
newGroup = children[0];
} else {
newGroup = {};
if (group.not) newGroup.not = true;
newGroup[mode] = children;
}
cond = ie_condReplace(cond, groupPath, newGroup);
} else {
cond = ie_condReplace(cond, groupPath, null);
}
c.set(cond);
c.change();
}
function ie_removeGroup(el, secId, secPath, idx, kind, groupPath) {
var c = _ie_condCtx(el, secId, secPath, idx, kind);
var cond = c.get();
if (!groupPath) {
c.set(null);
c.change();
return;
}
var parts = groupPath.split('-').map(Number);
var childIdx = parts[parts.length - 1];
var parentPath = parts.slice(0, -1).join('-');
var parent = ie_condAt(cond, parentPath);
if (!parent || !(parent.all_of || parent.any_of)) return;
var mode = parent.all_of ? 'all_of' : 'any_of';
var children = parent[mode].slice();
children.splice(childIdx, 1);
var newParent;
if (children.length === 0) {
newParent = null;
} else if (children.length === 1 && !parent.not) {
newParent = children[0];
} else {
newParent = {};
if (parent.not) newParent.not = true;
newParent[mode] = children;
}
cond = ie_condReplace(cond, parentPath, newParent);
c.set(cond);
c.change();
}
function ie_addRootConditionGroup(secPath, idx, kind) {
var ed = window._editorData;
if (!ed) return;
if (!ed[secPath]) ed[secPath] = [];
if (!ed[secPath][idx]) ed[secPath][idx] = {};
var si = _ie_kindStep(kind);
if (si < 0) {
if (!ed[secPath][idx].condition || typeof ed[secPath][idx].condition !== 'object') {
ed[secPath][idx].condition = {all_of: []};
}
} else {
if (!ed[secPath][idx].steps) ed[secPath][idx].steps = [];
if (!ed[secPath][idx].steps[si]) ed[secPath][idx].steps[si] = {};
if (!ed[secPath][idx].steps[si].condition || typeof ed[secPath][idx].steps[si].condition !== 'object') {
ed[secPath][idx].steps[si].condition = {all_of: []};
}
}
ced_syncDOMToData(ed);
window._ieRenderOnly();
}
function ie_addStepCond(el, secId, secPath, idx, si) {
if (el && el.nodeType && _ie_scopeFromEl(el)) {
var c = _ie_condCtx(el, secId, secPath, idx, 'step-' + si);
c.get();
c.change();
return;
}
ie_addRootConditionGroup(secPath, idx, 'step-' + si);
}
function ie_addGroup(el, secId, secPath, idx, kind, groupPath) {
var c = _ie_condCtx(el, secId, secPath, idx, kind);
var cond = c.get();
var group = ie_condAt(cond, groupPath);
var newSub = {all_of: []};
var newGroup;
if (!group) {
newGroup = newSub;
} else if (group.all_of || group.any_of) {
var mode = group.all_of ? 'all_of' : 'any_of';
var children = (group.all_of || group.any_of).concat([newSub]);
newGroup = {};
if (group.not) newGroup.not = true;
newGroup[mode] = children;
} else {
newGroup = {all_of: [group, newSub]};
}
cond = ie_condReplace(cond, groupPath, newGroup);
c.set(cond);
c.change();
}
function ie_addOuterLeaf(el, secId, secPath, idx, kind, leafType) {
var c = _ie_condCtx(el, secId, secPath, idx, kind);
var cond = c.get();
var leaf = {};
leaf[leafType] = (leafType === 'min_credits' || leafType === 'room') ? 0 : '';
if (!cond) {
cond = leaf;
} else {
cond = {all_of: [cond, leaf]};
}
c.set(cond);
c.change();
}
function ie_addOuterGroup(el, secId, secPath, idx, kind) {
var c = _ie_condCtx(el, secId, secPath, idx, kind);
var cond = c.get();
var newSub = {all_of: []};
if (!cond) {
cond = newSub;
} else {
cond = {all_of: [cond, newSub]};
}
c.set(cond);
c.change();
}
function ie_toggleCondMode(el, secId, secPath, idx, kind, groupPath) {
var c = _ie_condCtx(el, secId, secPath, idx, kind);
c.get();
c.change();
}
function ie_toggleCondNot(el, secId, secPath, idx, kind, groupPath) {
var c = _ie_condCtx(el, secId, secPath, idx, kind);
c.get();
c.change();
}
function ie_toggleNotLeaf(el, secId, secPath, idx, kind, groupPath, ci) {
var c = _ie_condCtx(el, secId, secPath, idx, kind);
c.get();
c.change();
}
// ── Add/Remove: Steps ──
function ie_removeStep(el, secId, secPath, idx, si) {
var ed = window._editorData;
if (!ed) return;
ced_syncDOMToData(ed);
if (window._ieSyncAll) window._ieSyncAll(ed);
if (!ed[secPath] || !ed[secPath][idx] || !ed[secPath][idx].steps) return;
ed[secPath][idx].steps.splice(si, 1);
window._ieRenderCurrent();
}
function ie_moveStep(el, secId, secPath, idx, fromSi, toSi) {
var ed = window._editorData;
if (!ed) return;
ced_syncDOMToData(ed);
if (window._ieSyncAll) window._ieSyncAll(ed);
var steps = ed[secPath] && ed[secPath][idx] && ed[secPath][idx].steps;
if (!steps || fromSi < 0 || fromSi >= steps.length || toSi < 0 || toSi >= steps.length) return;
var m = steps.splice(fromSi, 1)[0];
steps.splice(toSi, 0, m);
window._ieRenderOnly();
}
function ie_moveRow(secPath, fromIdx, toIdx) {
var ed = window._editorData;
if (!ed) return;
ced_syncDOMToData(ed);
if (window._ieSyncAll) window._ieSyncAll(ed);
var arr = ed[secPath];
if (!arr || fromIdx < 0 || fromIdx >= arr.length || toIdx < 0 || toIdx >= arr.length) return;
var m = arr.splice(fromIdx, 1)[0];
arr.splice(toIdx, 0, m);
window._ieRenderOnly();
}
function ie_moveMessage(el, secId, secPath, idx, si, fromMi, toMi) {
var c = _ie_actCtx(el, secId, secPath, idx, si);
var step = c.get();
if (!step || !Array.isArray(step.messages)) return;
if (fromMi < 0 || fromMi >= step.messages.length || toMi < 0 || toMi >= step.messages.length) return;
var m = step.messages.splice(fromMi, 1)[0];
step.messages.splice(toMi, 0, m);
c.set(step);
c.change();
}
// ── Add/Remove: Action effects ──
function ie_addActEffect(el, secId, secPath, idx, si, effectKey) {
var c = _ie_actCtx(el, secId, secPath, idx, si);
var step = c.get();
var at = IE_ACT_TYPES.find(function(a) { return a.key === effectKey; });
if (!at) return;
if (at.kind === 'kv') step[effectKey] = {};
else if (at.kind === 'checkbox') step[effectKey] = true;
else if (at.kind === 'number') step[effectKey] = 0;
else if (at.kind === 'droptable') step[effectKey] = [];
else step[effectKey] = '';
c.set(step);
c.change();
}
function ie_removeActEffect(el, secId, secPath, idx, si, effectKey) {
var c = _ie_actCtx(el, secId, secPath, idx, si);
var step = c.get();
delete step[effectKey];
c.set(step);
c.change();
}
// ── Add/Remove: KV row ──
function ie_addKVRow(el, secId, secPath, idx, si, effectKey) {
if (_ie_scopeFromEl(el)) {
var c = _ie_actCtx(el, secId, secPath, idx, si);
var step = c.get();
if (!step[effectKey] || typeof step[effectKey] !== 'object') step[effectKey] = {};
step[effectKey][''] = '';
c.set(step);
c.change();
return;
}
var ed = window._editorData;
if (!ed) return;
ie_syncStep(ed, secId, secPath, idx, si);
var card = document.querySelector('.obj-card[data-card="' + secId + '"]');
if (!card) return;
var stepRow = card.querySelector('.obj-sub-row.ie-inter-row[data-idx="' + idx + '"] .ie-step-row[data-step="' + si + '"]');
if (!stepRow) return;
var list = stepRow.querySelector('.ie-act-kv[data-ie-act-key="' + effectKey + '"] .ie-kv-list');
if (!list) return;
var rowEl = document.createElement('div');
rowEl.className = 'ie-kv-row';
rowEl.innerHTML = '';
list.appendChild(rowEl);
rowEl.querySelector('.ie-kv-key').focus();
}
function ie_removeKVRow(rowEl, secId, secPath, idx, si, effectKey) {
if (rowEl && rowEl.closest) {
var kvRow = rowEl.closest('.ie-kv-row');
if (kvRow) rowEl = kvRow;
}
var c = _ie_actCtx(rowEl, secId, secPath, idx, si);
var step = c.get();
if (!step || !step.hasOwnProperty(effectKey)) return;
var keyEl = rowEl.querySelector('.ie-kv-key');
var k = keyEl ? keyEl.value.trim() : '';
if (k && step[effectKey].hasOwnProperty(k)) delete step[effectKey][k];
if (Object.keys(step[effectKey]).length === 0) delete step[effectKey];
c.set(step);
c.change();
}
// ── Add/Remove: Messages ──
function ie_addMessages(el, secId, secPath, idx, si) {
var c = _ie_actCtx(el, secId, secPath, idx, si);
var step = c.get();
if (!step.messages || !Array.isArray(step.messages)) step.messages = [];
step.messages.push('');
c.set(step);
c.change();
}
// ── Drop Table row add/remove ──
function ie_addDropRow(el, secId, secPath, idx, si, kind) {
var c = _ie_actCtx(el, secId, secPath, idx, si);
var step = c.get();
if (!Array.isArray(step.drop_table)) step.drop_table = [];
if (kind === 'table') {
step.drop_table.push({table: '', weight: 10, quantity: 1, _kind: 'table'});
} else {
step.drop_table.push({item_id: '', weight: 10, quantity: 1, _kind: 'item'});
}
c.set(step);
c.change();
}
function ie_removeDropRow(el, secId, secPath, idx, si, ri) {
var c = _ie_actCtx(el, secId, secPath, idx, si);
var step = c.get();
if (!Array.isArray(step.drop_table)) return;
step.drop_table.splice(ri, 1);
c.set(step);
c.change();
}
function ie_addMessage(el, secId, secPath, idx, si) {
if (_ie_scopeFromEl(el)) {
var c = _ie_actCtx(el, secId, secPath, idx, si);
var step = c.get();
if (!step.messages || !Array.isArray(step.messages)) step.messages = [];
step.messages.push('');
c.set(step);
c.change();
return;
}
var ed = window._editorData;
if (!ed) return;
ie_syncStep(ed, secId, secPath, idx, si);
var card = document.querySelector('.obj-card[data-card="' + secId + '"]');
if (!card) return;
var stepRow = card.querySelector('.obj-sub-row.ie-inter-row[data-idx="' + idx + '"] .ie-step-row[data-step="' + si + '"]');
if (!stepRow) return;
var list = stepRow.querySelector('.ie-act-kv[data-ie-act-key="messages"] .ie-kv-list');
if (!list) return;
var rowEl = document.createElement('div');
rowEl.className = 'ie-kv-row ie-msg-row';
var rmFn = 'ie_removeMessage(this,\'' + escAttr(secId) + '\',\'' + escAttr(secPath) + '\',' + idx + ',' + si + ')';
rowEl.innerHTML = '';
list.appendChild(rowEl);
rowEl.querySelector('.ie-act-msg').focus();
}
function ie_removeMessage(rowEl, secId, secPath, idx, si) {
if (rowEl && rowEl.closest) {
var kvRow = rowEl.closest('.ie-kv-row');
if (kvRow) rowEl = kvRow;
}
var c = _ie_actCtx(rowEl, secId, secPath, idx, si);
var step = c.get();
if (!step || !Array.isArray(step.messages)) return;
var kvRows = document.querySelectorAll('.ie-act-kv[data-ie-act-key="messages"] .ie-kv-row');
for (var ri = 0; ri < kvRows.length; ri++) {
if (kvRows[ri] === rowEl || kvRows[ri].contains(rowEl)) {
step.messages.splice(ri, 1);
break;
}
}
if (step.messages.length === 0) delete step.messages;
c.set(step);
c.change();
}
// ── Shared trigger-style array-section renderer ──
function ie_renderArraySection(ctx) {
var sec = ctx.sec;
var data = ctx.data;
var visMap = ctx.visMap;
var arr = data[sec.path] || [];
var h = '';
var allowItem = sec.itemIDAllowed !== false;
arr.forEach(function(item, idx) {
visMap[idx] = visMap[idx] || {};
var vis = visMap[idx];
var showItem = allowItem && (vis.item_id || (item.item_id && item.item_id !== ''));
var condExists = !!(item.condition && typeof item.condition === 'object');
var lockVal = !!item.lock;
var steps = item.steps || [];
h += '
';
h += '
';
h += '';
if (idx > 0) h += '';
if (idx < arr.length - 1) h += '';
if (allowItem) {
if (!showItem) {
h += '';
} else {
h += ctx.renderField(sec, sec.fields[0], data, idx, 'flex:1;min-width:0');
h += '';
}
}
if (!condExists) {
h += '';
}
h += '';
h += '';
h += '