(function (root, factory) { "use strict"; const api = Object.freeze(factory()); if (typeof module === "object" && module.exports) module.exports = api; if (root) root.MbnCandleOptionsWorkflow = api; })(typeof globalThis === "object" ? globalThis : this, function () { "use strict"; const CANDLE_BUILDER_KEY = "s8010"; const supportedSources = Object.freeze([ "legacy-stock-workflow", "legacy-fixed-workflow", "legacy-industry-workflow", "legacy-overseas-workflow", "legacy-trading-halt-workflow" ]); function normalizeOptions(ma5, ma20) { if (typeof ma5 !== "boolean" || typeof ma20 !== "boolean") { throw new TypeError("Global moving-average flags must be boolean values."); } return Object.freeze({ ma5, ma20 }); } function expectedGraphicType(ma5, ma20) { const options = normalizeOptions(ma5, ma20); const flags = []; if (options.ma5) flags.push("MA5"); if (options.ma20) flags.push("MA20"); return flags.join(","); } function hasAdapters(value) { return value && typeof value === "object" && !Array.isArray(value) && value.stock && value.fixed && value.industry && value.overseas && value.tradingHalt; } function recreateCandleEntry(value, ma5, ma20, adapters, now = new Date()) { const movingAverages = normalizeOptions(ma5, ma20); if (!value || typeof value !== "object" || Array.isArray(value) || value.builderKey !== CANDLE_BUILDER_KEY || typeof value.enabled !== "boolean" || !hasAdapters(adapters)) return null; const operator = value.operator; if (!operator || typeof operator !== "object" || !supportedSources.includes(operator.source)) return null; const options = { id: value.id, fadeDuration: value.fadeDuration, ma5: movingAverages.ma5, ma20: movingAverages.ma20 }; let recreated = null; try { switch (operator.source) { case "legacy-stock-workflow": { const cut = adapters.stock.getStockCut(operator.cutId); if (cut?.kind !== "candle") return null; recreated = adapters.stock.createStockPlaylistEntry(operator.stock, cut.id, options); break; } case "legacy-fixed-workflow": { const action = adapters.fixed.actions.find(item => item.id === operator.actionId); if (action?.builderKey !== CANDLE_BUILDER_KEY || action.available !== true) return null; recreated = adapters.fixed.createFixedPlaylistEntry(action.id, { ...options, now }); break; } case "legacy-industry-workflow": { const cut = adapters.industry.cuts.find(item => item.id === operator.cutId); if (cut?.kind !== "candle") return null; recreated = adapters.industry.createIndustryPlaylistEntry(operator.market, cut.id, { ...options, selected: operator.selected, pair: operator.pair, now }); break; } case "legacy-overseas-workflow": { const action = adapters.overseas.stockActions.find(item => item.id === operator.actionId); if (operator.kind !== "stock" || action?.kind !== "candle") return null; recreated = adapters.overseas.createOverseasStockPlaylistEntry( operator.identity, action.id, options); break; } case "legacy-trading-halt-workflow": { const action = adapters.tradingHalt.getAction(operator.actionId); if (action?.kind !== "candle") return null; recreated = adapters.tradingHalt.createTradingHaltPlaylistEntry( operator.tradingHalt, action.id, options); break; } default: return null; } } catch { return null; } return recreated ? { ...recreated, enabled: value.enabled } : null; } function entryAlreadyMatches(value, ma5, ma20) { const graphicType = expectedGraphicType(ma5, ma20); return value?.selection?.graphicType === graphicType && value?.graphicType === graphicType && value?.operator?.movingAverages?.ma5 === ma5 && value?.operator?.movingAverages?.ma20 === ma20; } function synchronizePlaylist(values, ma5, ma20, adapters, now = new Date()) { normalizeOptions(ma5, ma20); if (!Array.isArray(values)) throw new TypeError("A playlist array is required."); const invalidIds = []; let changed = false; const playlist = values.map(value => { if (value?.builderKey !== CANDLE_BUILDER_KEY) return value; if (entryAlreadyMatches(value, ma5, ma20)) return value; const recreated = recreateCandleEntry(value, ma5, ma20, adapters, now); if (!recreated) { invalidIds.push(typeof value?.id === "string" ? value.id : ""); return value; } changed = true; return recreated; }); return Object.freeze({ playlist: Object.freeze(playlist), changed, valid: invalidIds.length === 0, invalidIds: Object.freeze(invalidIds) }); } return { candleBuilderKey: CANDLE_BUILDER_KEY, supportedSources, normalizeOptions, expectedGraphicType, recreateCandleEntry, synchronizePlaylist }; });