{"version":3,"sources":["https://lively-kernel.org/lively4/lively4-eventsourcing/src/components/demo/lively-simulation.js"],"names":["Morph","Engine","History","_","EMPTY_PLACEHOLDER","RESERVED_CELL_NAMES","LivelySimulation","initialize","initializeEngine","initializeController","initializeContainerRoot","velocity","has","undefined","stopOnError","time","dt","collectCells","engine","controller","get","hideController","hasAttribute","parentElement","initializeHistory","getInnerHTML","attachedCallback","detachedCallback","history","stop","shutdown","livelyPrepareSave","timeDeltaPerStepInSeconds","livelyAcceptsDrop","onKeyDown","event","isCellFocusActive","matched","toggleStartStop","increaseVelocity","decreaseVelocity","step","reset","addCell","preventDefault","selector","shadowRoot","querySelector","querySelectorAll","resolve","cell","appendChild","setName","ensureUniqueCellName","getName","startGrabbing","cellNameProposal","counterSlug","cellNameProposalWithSlug","cellNames","concat","map","reject","isMirrorCell","toAlphaNumeric","sameNameCount","filter","name","toLowerCase","str","replace","revert","snapshot","cells","some","isFocused","cloneCell","clone","cloneNode","mirrorCell","setAttribute","removeAttribute","executeSingleCell","setTime","forEach","clearLog","innerHTML","getForegroundCell","maxBy","getEngine","getHistory","toggleHighlight","cellRef","currentHighlight","highlight","removeMirrorCells","mirrorCells","isEqual","delete"],"mappings":"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","file":"lively-simulation.js","sourcesContent":["/*MD\n  ![](https://lively-kernel.org/lively4/lively4-core/demos/lively-simulation/screenshots/simulation.png){width=500px}\nMD*/\n\n\"enable aexpr\";\n\nimport Morph from 'src/components/widgets/lively-morph.js';\nimport Engine from 'demos/lively-simulation/engine.js';\nimport History from 'demos/lively-simulation/history.js';\nimport _ from 'src/external/lodash/lodash.js';\n\nconst EMPTY_PLACEHOLDER = 'EMPTY';\nconst RESERVED_CELL_NAMES = ['simulation'];\n\nexport default class LivelySimulation extends Morph {\n  \n  // life cycle\n  initialize() {\n    this.windowTitle = 'Simulation';\n    lively.html.registerKeys(this);\n    this.initializeEngine();\n    this.initializeController();\n    this.initializeContainerRoot();\n  }\n  \n  initializeEngine() {\n    const velocity = _.has(this.dataset, 'velocity') ? parseInt(this.dataset['velocity']) : undefined;\n    const stopOnError = this.dataset['stoponerror'] || undefined;\n    const time = _.has(this.dataset, 'time') ? parseInt(this.dataset['time']) : undefined;\n    const dt = _.has(this.dataset, 'dt') ? parseFloat(this.dataset['dt']) : undefined;\n    this.engine = new Engine(velocity, () => this.collectCells(), stopOnError, time, dt);\n  }\n  \n  initializeController() {\n    const { engine } = this;\n    const controller = this.get('#controller');\n    controller.initializeEngine(engine);\n    const hideController = !!this.hasAttribute('data-hide-controller');\n    if (hideController) controller.style.display = 'none';\n  }\n  \n  initializeContainerRoot() {\n    const { parentElement } = this;\n    if (parentElement.id === 'container-root') {\n      parentElement.style.width = '100%';\n      parentElement.style.height = '100%';\n    }\n  }\n  \n  initializeHistory() {\n    this.history = new History(() => this.getInnerHTML());\n  }\n  \n  attachedCallback() {\n    this.initializeHistory();\n  }\n  \n  detachedCallback() {\n    const { engine, history } = this;\n    engine.stop();\n    history.shutdown();\n  }\n  \n  livelyPrepareSave() {\n    const { engine: { stopOnError, time, timeDeltaPerStepInSeconds, velocity } } = this;\n    this.dataset['velocity'] = velocity;\n    this.dataset['stoponerror'] = stopOnError;\n    this.dataset['time'] = time;\n    this.dataset['dt'] = timeDeltaPerStepInSeconds;\n  }\n  \n  livelyAcceptsDrop() { return true; }\n  \n  // event listener\n  onKeyDown(event) {\n    const { engine } = this;\n    if(this.isCellFocusActive() || this.get('#controller').isFocused()) return;\n    let matched = true;\n    switch (event.key) {\n      case ' ':\n        engine.toggleStartStop();\n        break;\n      case '+':\n        engine.increaseVelocity();\n        break;\n      case '-':\n        engine.decreaseVelocity();\n        break;\n      case 's':\n        engine.step();\n        break;\n      case 'r':\n        this.reset();\n        break;\n      case 'a':\n        this.addCell();\n        break;\n      default:\n        matched = false;\n    }\n    if (matched) event.preventDefault();\n  }\n  \n  // other\n  get(selector) {\n    const { shadowRoot } = this;\n    return shadowRoot.querySelector(selector);\n  }\n  \n  collectCells() {\n    return [...this.querySelectorAll('lively-simulation-cell')];\n  }\n  \n  addCell(event) {\n    return Promise\n      .resolve(<lively-simulation-cell></lively-simulation-cell>)\n      .then(cell => {\n        this.appendChild(cell);\n        cell.setName(this.ensureUniqueCellName(cell.getName()));\n        if (!event) return;\n        cell.startGrabbing(event);\n      });\n  }\n  \n  ensureUniqueCellName(cellNameProposal, counterSlug = 1) {\n    const cellNameProposalWithSlug = \n        counterSlug > 1 ? `${cellNameProposal} (${counterSlug})` : cellNameProposal;\n    const cellNames = _.concat(\n      _.map(_.reject(this.collectCells(), cell => cell.isMirrorCell()), cell => this.toAlphaNumeric(cell.getName().toLowerCase())), \n      RESERVED_CELL_NAMES\n    );\n    const sameNameCount = _.filter(cellNames, name => name === this.toAlphaNumeric(cellNameProposalWithSlug.toLowerCase())).length;\n    if (sameNameCount - (counterSlug === 1) <= 0) return cellNameProposalWithSlug;\n    return this.ensureUniqueCellName(cellNameProposal, counterSlug + 1);\n  }\n  \n  toAlphaNumeric(str) {\n    return str.replace(/\\W/g, '');\n  }\n  \n  revert(snapshot) {\n    this.innerHTML = snapshot === EMPTY_PLACEHOLDER ? '' : snapshot;\n  }\n  \n  isCellFocusActive() {\n    const cells = this.collectCells();\n    return _.some(cells, cell => cell.isFocused());\n  }\n  \n  cloneCell(event, cell) {\n    cell.livelyPrepareSave();\n    const clone = cell.cloneNode();\n    this.appendChild(clone);\n    setTimeout(() => {\n      clone.setName(this.ensureUniqueCellName(clone.getName()));\n      clone.startGrabbing(event);\n    }, 0);\n  }\n  \n  mirrorCell(event, cell) {\n    cell.setAttribute('data-is-mirror', true);\n    cell.livelyPrepareSave();\n    const clone = cell.cloneNode();\n    this.appendChild(clone);\n    setTimeout(() => {\n      clone.startGrabbing(event);\n      cell.removeAttribute('data-is-mirror');\n      cell.livelyPrepareSave();\n    }, 0);\n  }\n  \n  executeSingleCell(cell) {\n    const { engine } = this;\n    return engine.step([ cell ]);\n  }\n  \n  reset() {\n    const { engine } = this;\n    engine.setTime(0);\n    _.forEach(this.collectCells(), cell => cell.clearLog());\n  }\n  \n  getInnerHTML() {\n    const { innerHTML } = this;\n    return innerHTML.length ? innerHTML : EMPTY_PLACEHOLDER;\n  }\n  \n  getForegroundCell() {\n    return _.maxBy(this.collectCells(), cell => parseInt(cell.style.zIndex || 1));\n  }\n  \n  getEngine() {\n    const { engine } = this;\n    return engine;\n  }\n  \n  getHistory() {\n    const { history } = this;\n    return history.get();\n  }\n  \n  toggleHighlight(cellRef) {\n    const { currentHighlight } = this;\n    this.currentHighlight = (currentHighlight === cellRef) ? undefined : cellRef;\n    const cells = this.collectCells();\n    _.forEach(cells, cell => cell.highlight(this.currentHighlight));\n    \n  }\n  \n  removeMirrorCells(name) {\n    const cells = this.collectCells();\n    const mirrorCells = _.filter(cells, cell => cell.isMirrorCell() && _.isEqual(cell.getName(), name));\n    _.forEach(mirrorCells, mirrorCell => mirrorCell.delete());\n  }\n  \n//   livelyExample() {\n//     this.innerHTML = `\n//       <lively-simulation-cell style=\"top: 798.6px; left: 40px; width: 541.453px; height: 261.359px; z-index: 120;\" data-name=\"ResetSimulation\" data-state=\"{}\" data-snippet=\"#Fuel.gas = 5 * 2 * 3600 // two hours gas\n// #HeatStorage.energy = 0\n// #Battery.energy = 0 \n// #ElectricConsumer.consumed = 0\n// #ElectricConsumer.demand = 1.5\n// #ElectricConsumer.extra = 0\n// #HeatConsumer.consumed = 0\n// #HeatConsumer.demand = 3\n// #HeatConsumer.extra = 0\n// #ThermalPowerStation.heat = 0\n// #HeatingSystem.heat = 0\n// #Battery.max = 0.1 * 3600 // 1h 2kw\n// #HeatStorage.max = 0.1 * 3600 // 1h 3kw\" data-view=\"codeView\" data-loginterval=\"1\" data-lively-id=\"db4cfe19-7ed2-4d9b-9b2b-2aa517e80e5f\" data-should-skip=\"true\"></lively-simulation-cell><lively-simulation-cell style=\"top: 320px; left: 23.2561px; width: 246.35px; height: 148.399px; z-index: 119;\" data-name=\"Fuel\" data-state=\"{&quot;gas&quot;:36000}\" data-snippet=\"if (gas < 0) {\n//     throw Error(&quot;Gas Empty&quot;)\n// }\" data-view=\"codeView\" data-loginterval=\"1\" data-lively-id=\"358a6017-4bb6-4d57-b998-4221423bfda2\"><img src=\"https://image.flaticon.com/icons/svg/2362/2362783.svg\" style=\"position: relative; width: 53px; height: 62px; left: 119px; top: 4px;\" class=\"\">\n// <div class=\"lively-text lively-content\" contenteditable=\"true\" style=\"width: 183px;position: absolute;left: 24px;top: -59px;height: 63px;\">Click here to see all cell that require fuel<div>|</div></div></lively-simulation-cell><lively-simulation-cell style=\"top: 498.74px; left: 322.256px; width: 539.826px; height: 279.414px; z-index: 124;\" data-name=\"Thermal Power Station\" data-state=\"{&quot;heat&quot;:0,&quot;factor&quot;:10,&quot;max&quot;:7.5}\" data-snippet=\"var full = max * factor;\n// if (heat < full &amp;&amp; #Fuel.gas > max * dt\n//     &amp;&amp; (#Battery.energy < 0.9 * #Battery.max )) {\n//     var gas = max * dt;\n//     #Fuel.gas -= gas;\n//     heat += 1.0 * gas\n// }\n// var delta = heat / factor * dt;\n// if (heat > 2) {\n//     heat -= delta;\n//     if(#HeatStorage.energy < #HeatStorage.max) {\n//         #HeatStorage.energy += 0.5 * delta;\n//     }\n//     if (#Battery.energy < #Battery.max ) {\n//         #Battery.energy += 0.4 * delta;\n//     }\n// }\" data-view=\"codeView\" data-loginterval=\"1\" data-lively-id=\"c6eae5ef-cdc4-46df-9258-c0db109f88b8\"><img src=\"https://image.flaticon.com/icons/svg/857/857761.svg\" style=\"width: 75px;height: 58px;position: relative;left: 10px;top: 0px;\"><img src=\"https://image.flaticon.com/icons/svg/2983/2983973.svg\" style=\"width: 53px;height: 37px;position: absolute;left: 101px;top: 232px;\"></lively-simulation-cell><lively-simulation-cell style=\"top: 79px; left: 348.709px; z-index: 123; width: 500px; height: 264.28px;\" data-name=\"Heating System\" data-state=\"{&quot;heat&quot;:0,&quot;factor&quot;:20,&quot;max&quot;:5}\" data-snippet=\"var full = max  * factor\n// if (heat < full &amp;&amp; #Fuel.gas > max * dt &amp;&amp;\n//     #HeatStorage.energy < 0.3 * #HeatStorage.max) {\n//     var gas = max * dt;\n//     #Fuel.gas -= gas;\n//     heat += gas;\n// }\n\n// var delta = (heat / factor) * dt;\n// if (heat > 2 * max  &amp;&amp; #HeatStorage.energy < #HeatStorage.max ) {\n//     heat -= delta;\n//     #HeatStorage.energy += 0.8 * delta;\n// } else {\n//     heat -= 0.2 * delta;\n// }\" data-view=\"codeView\" data-loginterval=\"1\" data-lively-id=\"80937f3f-2786-45de-8691-c83825696023\"><img src=\"https://image.flaticon.com/icons/svg/857/857761.svg\" style=\"width: 75px; height: 58px; position: relative; left: -2px; top: -2px;\">\n// <div class=\"lively-text lively-content\" contenteditable=\"true\" style=\"width: 300px; position: absolute; left: 143px; top: 216px;\">A heating system requires fuel and produces heat</div></lively-simulation-cell><lively-simulation-cell style=\"top: 282px; left: 861.269px; z-index: 125; width: 284.115px; height: 74.4531px;\" data-name=\"Heat Storage\" data-state=\"{&quot;energy&quot;:0,&quot;max&quot;:360}\" data-snippet=\"// Enter simulation code here\" data-view=\"codeView\" data-loginterval=\"1\" data-lively-id=\"79eca28f-b50d-49b9-9d0e-b426c590fb67\">\n// <img src=\"https://image.flaticon.com/icons/svg/870/870620.svg\" style=\"width: 28px;height: 44px;position: relative;left: 30px;top: 0;\"></lively-simulation-cell><lively-simulation-cell style=\"top: 394.26px; left: 863px; z-index: 126; width: 164.533px; height: 100px;\" data-name=\"Battery\" data-state=\"{&quot;energy&quot;:0,&quot;max&quot;:360}\" data-snippet=\"\" data-view=\"codeView\" data-loginterval=\"1\" data-lively-id=\"15c89e50-98bf-4476-91fb-eec24c7173da\"><img src=\"https://image.flaticon.com/icons/svg/3165/3165660.svg\" style=\"width: 174px;height: 46px;position: relative;left: -36px;top: 0;\"></lively-simulation-cell><lively-simulation-cell style=\"top: 183px; left: 1191.27px; z-index: 128; width: 468.533px; height: 200px; position: absolute;\" data-name=\"Heat Consumer\" data-state=\"{&quot;consumed&quot;:0,&quot;extra&quot;:0,&quot;demand&quot;:3}\" data-snippet=\"var delta = demand * dt\n// if (#HeatStorage.energy > delta) {\n//     #HeatStorage.energy -= delta\n//     consumed += delta\n//     // TODO consume Extra\n// } else {\n//     extra  +=  delta\n//     throw Error(&quot;RoomToCold&quot;)\n// }\n// \" data-view=\"codeView\" data-loginterval=\"1\" data-lively-id=\"8c62075a-2da9-4c8a-b389-2db5668abc39\"><img src=\"https://image.flaticon.com/icons/svg/1422/1422837.svg\" style=\"width: 48px;height: 38px;position: relative;left: 71px;top: -3px;\"></lively-simulation-cell><lively-simulation-cell style=\"top: 399.735px; left: 1189px; z-index: 127; width: 447.844px; height: 180px;\" data-name=\"Electric Consumer\" data-state=\"{&quot;consumed&quot;:0,&quot;extra&quot;:0,&quot;demand&quot;:1.5}\" data-snippet=\"demand += (Math.random() - 0.5) * 0.01 * dt\n// var delta = demand * dt\n// if (#Battery.energy > delta) {\n//     #Battery.energy -= delta\n//     consumed += delta\n// } else {\n//     extra += delta\n//     throw Error(&quot;EngeryToLow&quot;)\n// }\n// \" data-view=\"codeView\" data-loginterval=\"1\" data-lively-id=\"5ee77098-fadb-4e95-9dea-1870e9af548a\"><img src=\"https://image.flaticon.com/icons/svg/2910/2910875.svg\" style=\"width: 137px;height: 59px;position: relative;left: 163px;top: 0;\"></lively-simulation-cell>\n// `;\n//       this.engine.setVelocity(10);\n//       this.engine.stopOnError = false;\n//       this.engine.setTimeDeltaPerStepInSeconds(0.1);\n//   }\n}"]}