From 7656bf0d11ad41afb25e0e827fcfc54699e8d3d5 Mon Sep 17 00:00:00 2001 From: Graham Trott Date: Mon, 13 Apr 2020 12:19:27 +0100 Subject: [PATCH 1/6] Prepare for CDN delivery --- js/easycoder/Browser.js | 3345 +++++++++++++++++++++++++++++++++++++++ js/easycoder/Json.js | 510 ++++++ js/easycoder/Rest.js | 216 +++ 3 files changed, 4071 insertions(+) create mode 100644 js/easycoder/Browser.js create mode 100644 js/easycoder/Json.js create mode 100644 js/easycoder/Rest.js diff --git a/js/easycoder/Browser.js b/js/easycoder/Browser.js new file mode 100644 index 0000000..30e281f --- /dev/null +++ b/js/easycoder/Browser.js @@ -0,0 +1,3345 @@ +const EasyCoder_Browser = { + + name: `EasyCoder_Browser`, + + A: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `a`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Alert: { + + compile: (compiler) => { + const lino = compiler.getLino(); + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `alert`, + lino, + value + }); + return true; + }, + + run: (program) => { + const command = program[program.pc]; + const value = program.getFormattedValue(command.value); + alert(value); + return command.pc + 1; + } + }, + + Attach: { + + compile: (compiler) => { + const lino = compiler.getLino(); + compiler.next(); + if (compiler.isSymbol()) { + // const symbol = compiler.getProgram()[compiler.getSymbol().pc]; + const symbol = compiler.getSymbolRecord(); + let type = symbol.keyword; + switch (type) { + case `a`: + case `blockquote`: + case `button`: + case `canvas`: + case `div`: + case `fieldset`: + case `file`: + case `form`: + case `h1`: + case `h2`: + case `h3`: + case `h4`: + case `h5`: + case `h6`: + case `image`: + case `img`: + case `input`: + case `label`: + case `legend`: + case `li`: + case `option`: + case `p`: + case `pre`: + case `select`: + case `span`: + case `table`: + case `td`: + case `text`: + case `textarea`: + case `tr`: + case `ul`: + compiler.next(); + if (compiler.tokenIs(`to`)) { + let cssID = null; + if (compiler.nextTokenIs(`body`)) { + if (type=== `div`) { + cssId = `body`; + compiler.next(); + } else { + throw Error(`Body variable must be a div`); + } + } + else cssId = compiler.getValue(); + let onError = 0; + if (compiler.tokenIs(`or`)) { + compiler.next(); + onError = compiler.getPc() + 1; + compiler.completeHandler(); + } + compiler.addCommand({ + domain: `browser`, + keyword: `attach`, + lino, + type, + symbol: symbol.name, + cssId, + onError + }); + return true; + } + break; + default: + compiler.addWarning(`type '${symbol.keyword}' not recognized in browser 'attach'`); + return false; + } + } + compiler.addWarning(`Unrecognised syntax in 'attach'`); + return false; + }, + + run: (program) => { + const command = program[program.pc]; + let content = null; + let element = null; + if (command.cssId === `body`) { + element = document.body; + } else { + content = program.value.evaluate(program, command.cssId).content; + element = document.getElementById(content); + } + if (!element) { + if (command.onError) { + program.run(command.onError); + } else { + program.runtimeError(command.lino, `No such element: '${content}'`); + } + return 0; + } + const target = program.getSymbolRecord(command.symbol); + target.element[target.index] = element; + target.value[target.index] = { + type: `constant`, + numeric: false, + content + }; + if (command.type === `popup`) { + // Register a popup + program.popups.push(element.id); + // Handle closing of the popup + window.onclick = function (event) { + if (program.popups.includes(event.target.id)) { + event.target.style.display = `none`; + } + }; + } + return command.pc + 1; + } + }, + + Audioclip: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `audioclip`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + BLOCKQUOTE: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `blockquote`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + BUTTON: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `button`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + CANVAS: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `canvas`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Clear: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextTokenIs(`body`)) { + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `clear`, + lino, + name: null + }); + return true; + } + if (compiler.isSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.extra === `dom`) { + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `clear`, + lino, + name: symbolRecord.name + }); + return true; + } + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + if (command.name) { + const targetRecord = program.getSymbolRecord(command.name); + const target = targetRecord.element[targetRecord.index]; + switch (targetRecord.keyword) { + case `input`: + case `textarea`: + target.value = ``; + break; + default: + target.innerHTML = ``; + break; + } + } else { + document.body.innerHTML = ``; + } + return command.pc + 1; + } + }, + + Convert: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextTokenIs(`whitespace`)) { + if (compiler.nextTokenIs(`in`)) { + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.isVHolder) { + if (compiler.nextTokenIs(`to`)) { + const mode = compiler.nextToken(); + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `convert`, + lino, + name: symbolRecord.name, + mode + }); + return true; + } + } + } + } + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const targetRecord = program.getSymbolRecord(command.name); + const content = targetRecord.value[targetRecord.index].content; + let value = content; + switch (command.mode) { + case `print`: + value = value.split(`%0a`).join(`\n`).split(`%0A`).join(`\n`).split(`%0d`).join(``).split(`$0D`).join(``); + break; + case `html`: + value = value.split(`%0a`).join(`
`).split(`%0A`).join(`
`).split(`%0d`).join(``).split(`$0D`).join(``); + break; + } + targetRecord.value[targetRecord.index].content = value; + return command.pc + 1; + } + }, + + Create: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + const keyword = symbolRecord.keyword; + if (keyword === `audioclip`) { + if (compiler.nextTokenIs(`from`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `create`, + type: `audioclip`, + name: symbolRecord.name, + lino, + value + }); + return true; + } + return false; + } + if ([`a`, + `blockquote`, + `button`, + `canvas`, + `div`, + `fieldset`, + `file`, + `form`, + `h1`, + `h2`, + `h3`, + `h4`, + `h5`, + `h6`, + `hr`, + `image`, + `img`, + `input`, + `label`, + `legend`, + `li`, + `option`, + `p`, + `pre`, + `progress`, + `select`, + `span`, + `table`, + `tr`, + `td`, + `text`, + `textarea`, + `ul` + ].includes(keyword)) { + if (compiler.nextTokenIs(`in`)) { + if (compiler.nextTokenIs(`body`)) { + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `create`, + lino, + name: symbolRecord.name, + parent: `body` + }); + return true; + } + if (compiler.isSymbol()) { + const parentRecord = compiler.getSymbolRecord(); + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `create`, + lino, + name: symbolRecord.name, + parent: parentRecord.name + }); + return true; + } + } else { + const imports = compiler.imports; + if (imports && imports.length > 0) { + // This section is used by Codex to force run in Run panel, which must be the first import + compiler.addCommand({ + domain: `browser`, + keyword: `create`, + lino, + name: symbolRecord.name, + parent: imports[0], + imported: true + }); + return true; + } else { + compiler.addCommand({ + domain: `browser`, + keyword: `create`, + lino, + name: symbolRecord.name, + parent: `body` + }); + return true; + } + } + } + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const targetRecord = program.getSymbolRecord(command.name); + switch (command.type) { + case `audioclip`: + targetRecord.value[targetRecord.index] = command.value; + break; + default: + let parent; + if (command.parent === `body`) { + parent = document.body; + } else { + const p = command.imported ? EasyCoder.scripts[program.parent] : program; + const parentRecord = p.getSymbolRecord(command.parent); + if (!parentRecord.element[parentRecord.index]) { + program.runtimeError(command.pc, `Element ${parentRecord.name} does not exist.`); + } + parent = parentRecord.element[parentRecord.index]; + } + targetRecord.element[targetRecord.index] = document.createElement(targetRecord.keyword); + targetRecord.element[targetRecord.index].id = + `ec-${targetRecord.name}-${targetRecord.index}-${EasyCoder.elementId++}`; + if (targetRecord.keyword === `a`) { + targetRecord.element[targetRecord.index].setAttribute(`href`, `#`); + } + parent.appendChild(targetRecord.element[targetRecord.index]); + break; + } + return command.pc + 1; + } + }, + + Disable: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const symbol = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `disable`, + lino, + symbol + }); + return true; + } + compiler.addWarning(`Unrecognised syntax in 'disable'`); + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const symbol = program.getSymbolRecord(command.symbol); + const target = document.getElementById(symbol.value[symbol.index].content); + target.disabled = `true`; + return command.pc + 1; + } + }, + + DIV: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `div`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Enable: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const symbol = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `enable`, + lino, + symbol + }); + return true; + } + compiler.addWarning(`Unrecognised syntax in 'enable'`); + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const symbol = program.getSymbolRecord(command.symbol); + const target = document.getElementById(symbol.value[symbol.index].content); + target.disabled = false; + return command.pc + 1; + } + }, + + FIELDSET: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `fieldset`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + FILE: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `file`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Focus: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const symbol = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `focus`, + lino, + symbol + }); + return true; + } + compiler.addWarning(`Unrecognised syntax in 'focus'`); + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const symbol = program.getSymbolRecord(command.symbol); + const element = symbol.element[symbol.index]; + element.focus(); + return command.pc + 1; + } + }, + + FORM: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `form`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Get: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const target = compiler.getToken(); + let targetRecord = compiler.getSymbolRecord(); + if (compiler.nextTokenIs(`from`)) { + if (compiler.nextTokenIs(`storage`)) { + if (compiler.nextTokenIs(`as`)) { + const key = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `get`, + action: `getStorage`, + lino, + target, + key + }); + return true; + } else { + compiler.addCommand({ + domain: `browser`, + keyword: `get`, + action: `listStorage`, + lino, + target + }); + return true; + } + } + if (compiler.isSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.keyword === `select`) { + if (targetRecord.keyword === `option`) { + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `get`, + action: `getOption`, + lino, + target, + select: symbolRecord.name + }); + return true; + } + throw Error(`Invalid variable type`); + } + if (symbolRecord.keyword !== `form`) { + throw Error(`Invalid variable type`); + } + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `get`, + action: `getForm`, + lino, + target, + form: symbolRecord.name + }); + return true; + } + else { + let targetRecord = compiler.getSymbolRecord(target); + } + } + } + compiler.addWarning(`Unrecognised syntax in 'get'`); + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const targetRecord = program.getSymbolRecord(command.target); + switch (command.action) { + case `getForm`: + const formRecord = program.getSymbolRecord(command.form); + const form = document.getElementById(formRecord.value[formRecord.index].content); + const data = new FormData(form); + const content = {}; + for (const entry of data) { + content[entry[0]] = entry[1].replace(/\r/g, ``).replace(/\n/g, `%0a`); + } + targetRecord.value[targetRecord.index] = { + type: `constant`, + numeric: false, + content: JSON.stringify(content) + }; + break; + case `listStorage`: + const items = []; + for (let i = 0, len = window.localStorage.length; i < len; i++) { + items.push(localStorage.key(i)); + } + targetRecord.value[targetRecord.index] = { + type: `constant`, + numeric: false, + content: JSON.stringify(items) + }; + break; + case `getStorage`: + let value = window.localStorage.getItem(program.getValue(command.key)); + if (typeof value === `undefined`) { + value = null; + } + targetRecord.value[targetRecord.index] = { + type: `constant`, + numeric: false, + content: value + }; + break; + case `getOption`: + let selectRecord = program.getSymbolRecord(command.select); + let select = selectRecord.element[selectRecord.index]; + let option = select.options[select.selectedIndex]; + targetRecord.element[targetRecord.index] = option; + break; + } + return command.pc + 1; + } + }, + + H1: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `h1`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + H2: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `h2`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + H3: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `h3`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + H4: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `h4`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + H5: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `h5`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + H6: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `h6`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Highlight: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.extra === `dom`) { + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `highlight`, + lino, + name: symbolRecord.name + }); + return true; + } + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const targetRecord = program.getSymbolRecord(command.name); + const element = targetRecord.element[targetRecord.index]; + element.select(); + return command.pc + 1; + } + }, + + History: { + + compile: (compiler) => { + const lino = compiler.getLino(); + const type = compiler.nextToken(); + switch (type) { + case `push`: + case `set`: + case `replace`: + compiler.next(); + let url = ``; + let state = ``; + let title = ``; + while (true) { + const token = compiler.getToken(); + if (token === `url`) { + url = compiler.getNextValue(); + } else if (token === `state`) { + state = compiler.getNextValue(); + } else if (token === `title`) { + title = compiler.getNextValue(); + } else { + break; + } + } + compiler.addCommand({ + domain: `browser`, + keyword: `history`, + lino, + type, + url, + state, + title + }); + return true; + case `pop`: + case `back`: + case `forward`: + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `history`, + lino, + type + }); + return true; + } + return false; + }, + + run: (program) => { + if (!program.script) { + program.script = `script${Date.now()/1000}`; + } + const command = program[program.pc]; + let state = program.getValue(command.state); + if (!state) { + state = `{"script":"${program.script}"}`; + } + let title = program.getValue(command.title); + const url = program.getValue(command.url); + switch (command.type) { + case `push`: + if (!window.history.state) { + program.runtimeError(command.lino, `No state history; you need to call 'history set' on the parent`); + return 0; + } + window.history.pushState(state, ``, url); + break; + case `set`: + case `replace`: + window.history.replaceState(state, title, url); + break; + case `pop`: + case `back`: + window.history.back(); + break; + case `forward`: + window.history.forward(); + break; + } + return command.pc + 1; + } + }, + + HR: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `hr`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + IMAGE: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `image`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + IMG: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `img`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + INPUT: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `input`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + LABEL: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `label`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + LEGEND: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `legend`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + LI: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `li`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Location: { + + compile: (compiler) => { + const lino = compiler.getLino(); + let newWindow = false; + if (compiler.nextTokenIs(`new`)) { + newWindow = true; + compiler.next(); + } + const location = compiler.getValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `location`, + lino, + location, + newWindow + }); + return true; + }, + + run: (program) => { + const command = program[program.pc]; + const location = program.getValue(command.location); + if (command.newWindow) { + window.open(location, `_blank`); + } else { + window.location = location; + } + return command.pc + 1; + } + }, + + Mail: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextTokenIs(`to`)) { + const to = compiler.getNextValue(); + let subject = ``; + let body = ``; + if (compiler.tokenIs(`subject`)) { + subject = compiler.getNextValue(); + if (compiler.tokenIs(`body`) || compiler.tokenIs(`message`)) { + compiler.next(); + body = compiler.getValue(); + } + } + compiler.addCommand({ + domain: `browser`, + keyword: `mail`, + lino, + to, + subject, + body + }); + return true; + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + if (command.subject) { + window.location.href = `mailto:${program.getValue(command.to)}` + + `?subject=${program.getValue(command.subject)}&body=${encodeURIComponent(program.getValue(command.body))}`; + } else { + window.location.href = `mailto:${program.getValue(command.to)}`; + } + return command.pc + 1; + } + }, + + On: { + + compile: (compiler) => { + const lino = compiler.getLino(); + const action = compiler.nextToken(); + switch (action) { + case `change`: + compiler.next(); + if (compiler.isSymbol()) { + const symbol = compiler.getSymbolRecord(); + compiler.next(); + if (symbol.extra !== `dom`) { + return false; + } + compiler.addCommand({ + domain: `browser`, + keyword: `on`, + lino, + action, + symbol: symbol.name + }); + return compiler.completeHandler(); + } + break; + case `click`: + if (compiler.nextTokenIs(`document`)) { + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `on`, + lino, + action: `clickDocument` + }); + return compiler.completeHandler(); + } + if (compiler.isSymbol()) { + const symbol = compiler.getSymbolRecord(); + compiler.next(); + if (symbol.extra !== `dom`) { + return false; + } + compiler.addCommand({ + domain: `browser`, + keyword: `on`, + lino, + action, + symbol: symbol.name + }); + return compiler.completeHandler(); + } + break; + case `key`: + case `leave`: + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `on`, + lino, + action + }); + return compiler.completeHandler(); + case `window`: + if (compiler.nextTokenIs(`resize`)) { + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `on`, + lino, + action: `windowResize` + }); + return compiler.completeHandler(); + } + return false; + case `browser`: + case `restore`: + if (action === `browser` && !compiler.nextTokenIs(`back`)) { + return false; + } + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `on`, + lino, + action: `browserBack` + }); + return compiler.completeHandler(); + case `swipe`: + if ([`left`, `right`].includes(compiler.nextToken())) { + const direction = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `on`, + lino, + action: `swipe`, + direction + }); + return compiler.completeHandler(); + } + return false; + case `pick`: + if (compiler.nextIsSymbol()) { + const symbol = compiler.getSymbolRecord(); + compiler.next(); + if (symbol.extra !== `dom`) { + return false; + } + compiler.addCommand({ + domain: `browser`, + keyword: `on`, + lino, + action, + symbol: symbol.name + }); + return compiler.completeHandler(); + } + return false; + case `drag`: + case `drop`: + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `on`, + lino, + action + }); + return compiler.completeHandler(); + } + compiler.addWarning(`Unrecognised syntax in 'on'`); + return false; + }, + + run: (program) => { + let targetRecord; + const command = program[program.pc]; + switch (command.action) { + case `change`: + targetRecord = program.getSymbolRecord(command.symbol); + targetRecord.program = program.script; + targetRecord.element.forEach(function (target, index) { + if (target) { + target.targetRecord = targetRecord; + target.targetIndex = index; + target.targetPc = command.pc + 2; + target.addEventListener(`change`, (event) => { + event.stopPropagation(); + if (program.length > 0) { + const eventTarget = event.target; + if (typeof eventTarget.targetRecord !== `undefined`) { + eventTarget.targetRecord.index = eventTarget.targetIndex; + setTimeout(function () { + EasyCoder.timestamp = Date.now(); + let p = EasyCoder.scripts[eventTarget.targetRecord.program]; + p.run(eventTarget.targetPc); + }, 1); + } + } + }); + } + }); + break; + case `click`: + targetRecord = program.getSymbolRecord(command.symbol); + targetRecord.program = program.script; + targetRecord.element.forEach(function (target, index) { + if (target) { + target.targetRecord = targetRecord; + target.targetIndex = index; + target.targetPc = command.pc + 2; + target.onclick = function (event) { + event.stopPropagation(); + if (program.length > 0) { + const eventTarget = event.target; + if (eventTarget.type != `radio`) { + eventTarget.blur(); + } + if (typeof eventTarget.targetRecord !== `undefined`) { + eventTarget.targetRecord.index = eventTarget.targetIndex; + setTimeout(function () { + EasyCoder.timestamp = Date.now(); + let p = EasyCoder.scripts[eventTarget.targetRecord.program]; + p.run(eventTarget.targetPc); + }, 1); + } + } + return false; + }; + } + }); + break; + case `clickDocument`: + program.targetPc = command.pc + 2; + const interceptClickEvent = (e) => { + EasyCoder.timestamp = Date.now(); + let target = e.target || e.srcElement; + let href = ``; + while (target.parentNode) { + if (target.tagName === `A`) { + href = target.href; + program.docPath = href.slice(-(href.length - window.location.href.length)); + break; + } + target = target.parentNode; + } + while (target.parentNode) { + if (target.id.indexOf(`ec-`) === 0) { + let id = target.id.slice(3); + let pos = id.indexOf(`-`); + program.varName = id.slice(0, pos); + id = id.slice(pos + 1); + pos = id.indexOf(`-`); + program.varIndex = parseInt(id.slice(0, pos)); + break; + } + target = target.parentNode; + } + if (href.indexOf(window.location.href) === 0) { + program.run(program.targetPc); + e.preventDefault(); + } + }; + if (document.addEventListener) { + document.addEventListener(`click`, interceptClickEvent); + } else if (document.attachEvent) { + document.attachEvent(`onclick`, interceptClickEvent); + } + break; + case `swipe`: + let xDown; + const getTouches = (evt) => { + return evt.touches || // browser API + evt.originalEvent.touches; // jQuery + }; + const handleTouchStart = (evt) => { + const firstTouch = getTouches(evt)[0]; + xDown = firstTouch.clientX; + }; + const handleTouchMove = (evt) => { + evt.stopImmediatePropagation(); + if (!xDown) { + return; + } + const xUp = evt.touches[0].clientX; + const xDiff = xDown - xUp; + if (Math.abs(xDiff) > 150) { + xDown = null; + if (xDiff > 0 && program.onSwipeLeft) { + program.run(program.onSwipeLeft); + } else if (xDiff < 0 && program.onSwipeRight) { + program.run(program.onSwipeRight); + } + } + }; + switch (command.direction) { + case `left`: + program.onSwipeLeft = command.pc + 2; + break; + case `right`: + program.onSwipeRight = command.pc + 2; + break; + } + document.addEventListener(`touchstart`, handleTouchStart, false); + document.addEventListener(`touchmove`, handleTouchMove, false); + break; + case `pick`: + const pickRecord = program.getSymbolRecord(command.symbol); + document.pickRecord = pickRecord; + pickRecord.element.forEach(function (element, index) { + document.pickIndex = index; + element.pickIndex = index; + // Set up the mouse down and up listeners + element.mouseDownPc = command.pc + 2; + // Check if touch device + let isTouchDevice = `ontouchstart` in element; + if (isTouchDevice) { + element.addEventListener(`touchstart`, function (e) { + const element = e.targetTouches[0].target; + document.pickX = e.touches[0].clientX; + document.pickY = e.touches[0].clientY; + element.blur(); + setTimeout(function () { + document.pickRecord.index = element.pickIndex; + program.run(element.mouseDownPc); + }, 1); + }, false); + element.addEventListener(`touchmove`, function (e) { + document.dragX = e.touches[0].clientX; + document.dragY = e.touches[0].clientY; + setTimeout(function () { + program.run(document.mouseMovePc); + }, 1); + return false; + }, false); + element.addEventListener(`touchend`, function () { + setTimeout(function () { + program.run(document.mouseUpPc); + }, 1); + return false; + }); + } else { + element.onmousedown = function (event) { + let e = event ? event : window.event; + e.stopPropagation(); + // IE uses srcElement, others use target + if (program.length > 0) { + const element = e.target ? e.target : e.srcElement; + element.offsetX = e.offsetX; + element.offsetY = e.offsetY; + document.pickX = e.clientX; + document.pickY = e.clientY; + element.blur(); + setTimeout(function () { + document.pickRecord.index = element.pickIndex; + program.run(element.mouseDownPc); + }, 1); + } + document.onmousemove = function (event) { + let e = event ? event : window.event; + e.stopPropagation(); + document.dragX = e.clientX; + document.dragY = e.clientY; + if (document.onmousemove) { + setTimeout(function () { + program.run(document.mouseMovePc); + }, 1); + } + return false; + }; + window.onmouseup = function () { + document.onmousemove = null; + document.onmouseup = null; + setTimeout(function () { + if (program && program.run) { + program.run(document.mouseUpPc); + } + }, 1); + return false; + }; + return false; + }; + } + }); + break; + case `drag`: + // Set up the move listener + document.mouseMovePc = command.pc + 2; + break; + case `drop`: + // Set up the move listener + document.mouseUpPc = command.pc + 2; + break; + case `key`: + if (typeof document.onKeyListeners === `undefined`) { + document.onKeyListeners = []; + } + if (!document.onKeyListeners.includes(program)) { + document.onKeyListeners.push(program); + } + program.onKeyPc = command.pc + 2; + document.onkeypress = function (event) { + for (const program of document.onKeyListeners) { + program.key = event.key; + try { + setTimeout(function () { + program.run(program.onKeyPc); + }, 1); + } catch (err) { + console.log(`Error: ${err.message}`); + } + } + return true; + }; + break; + case `windowResize`: + program.onWindowResize = command.pc + 2; + window.addEventListener('resize', function() { + program.run(program.onWindowResize); + }); + break; + case `browserBack`: + program.onBrowserBack = command.pc + 2; + break; + case `leave`: + window.addEventListener(`beforeunload`, function () { + program.run(command.pc + 2); + }); + break; + default: + break; + } + return command.pc + 1; + } + }, + + OPTION: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `option`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + P: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `p`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Play: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `audioclip`) { + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `play`, + lino, + target: targetRecord.name + }); + return true; + } + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const targetRecord = program.getSymbolRecord(command.target); + const url = program.value.evaluate(program, targetRecord.value[targetRecord.index]).content; + new Audio(url).play(); + return command.pc + 1; + } + }, + + PRE: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `pre`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + PROGRESS: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `progress`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Put: { + + compile: (compiler) => { + const lino = compiler.getLino(); + // Get the value + const value = compiler.getNextValue(); + if (compiler.tokenIs(`into`)) { + if (compiler.nextTokenIs(`storage`)) { + if (compiler.nextTokenIs(`as`)) { + const key = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `put`, + lino, + value, + key + }); + return true; + } + } + } + return false; + }, + + // runtime + + run: (program) => { + const command = program[program.pc]; + window.localStorage.setItem(program.getValue(command.key), program.getValue(command.value)); + return command.pc + 1; + } + }, + + Remove: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextTokenIs(`element`)) { + if (compiler.nextIsSymbol()) { + const element = compiler.getSymbolRecord(); + if (element.extra != `dom`) { + compiler.warning(`'${element.name}' is not a DOM element`); + return false; + } + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `remove`, + type: `removeElement`, + lino, + element: element.name + }); + return true; + } + } + if (compiler.tokenIs(`attribute`)) { + const attribute = compiler.getNextValue(); + if (compiler.tokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.extra !== `dom`) { + throw new Error(`Inappropriate type '${targetRecord.keyword}'`); + } + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `remove`, + type: `removeAttribute`, + lino, + attribute, + target: targetRecord.name + }); + return true; + } + } + } + try { + const key = compiler.getValue(); + if (compiler.tokenIs(`from`)) { + if (compiler.nextTokenIs(`storage`)) { + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `remove`, + type: `removeStorage`, + key + }); + return true; + } + } + } catch (err) { + return false; + } + return false; + }, + + // runtime + + run: (program) => { + const command = program[program.pc]; + switch (command.type) { + case `removeAttribute`: + const attribute = program.getValue(command.attribute); + const targetRecord = program.getSymbolRecord(command.target); + target = targetRecord.element[targetRecord.index]; + target.removeAttribute(attribute); + break; + case `removeElement`: + const elementRecord = program.getSymbolRecord(command.element); + const element = elementRecord.element[elementRecord.index]; + if (element) { + element.parentElement.removeChild(element); + } + break; + case `removeStorage`: + const key = program.getValue(command.key); + window.localStorage.removeItem(key); + break; + } + return command.pc + 1; + } + }, + + Request: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextToken() === `fullscreen`) { + let option = ``; + if (compiler.nextToken() === `exit`) { + option = `exit`; + compiler.next(); + } + compiler.addCommand({ + domain: `browser`, + keyword: `request`, + lino, + option + }); + return true; + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + if (command.option === `exit`) { + document.exitFullscreen(); + } else { + document.documentElement.requestFullscreen(); + } + return command.pc + 1; + } + }, + + SELECT: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `select`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Scroll: { + + compile: (compiler) => { + const lino = compiler.getLino(); + let name = null; + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + name = symbolRecord.name; + compiler.next(); + } + if (compiler.tokenIs(`to`)) { + const to = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `scroll`, + lino, + name, + to + }); + return true; + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const to = program.getValue(command.to); + if (command.name) { + const symbolRecord = program.getSymbolRecord(command.name); + symbolRecord.element[symbolRecord.index].scrollTo(0, to); + } else { + window.scrollTo(0, to); + } + return command.pc + 1; + } + }, + + SECTION: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `section`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Set: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + const target = targetRecord.name; + if (targetRecord.extra === `dom`) { + const token = compiler.nextToken(); + if (token === `from`) { + if (compiler.nextIsSymbol()) { + if (targetRecord.keyword === `select`) { + const sourceRecord = compiler.getSymbolRecord(); + if (sourceRecord.keyword === `variable`) { + var display = null; + if (compiler.nextTokenIs(`as`)) { + display = compiler.getNextValue(); + } + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setSelect`, + select: target, + source: sourceRecord.name, + display + }); + return true; + } + return false; + } + const source = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setContentVar`, + source, + target + }); + return true; + } + } + } + } else { + let token = compiler.getToken(); + if (token === `the`) { + token = compiler.nextToken(); + } + if (token === `title`) { + if (compiler.nextTokenIs(`to`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setTitle`, + value + }); + return true; + } + } else if (token === `content`) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const target = compiler.getToken(); + if (compiler.nextTokenIs(`from`)) { + if (compiler.nextIsSymbol()) { + const source = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setContentVar`, + source, + target + }); + return true; + } + } + if (compiler.tokenIs(`to`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setContent`, + value, + target + }); + return true; + } + } + throw new Error(`'${compiler.getToken()}' is not a symbol`); + } + } else if (token === `class`) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbol = compiler.getSymbolRecord(); + if (symbol.extra === `dom`) { + if (compiler.nextTokenIs(`to`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setClass`, + symbolName: symbol.name, + value + }); + return true; + } + } + } + } + } else if (token === `id`) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbol = compiler.getSymbolRecord(); + if (symbol.extra === `dom`) { + if (compiler.nextTokenIs(`to`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setId`, + symbolName: symbol.name, + value + }); + return true; + } + } + } + } + } else if (token === `text`) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbol = compiler.getSymbolRecord(); + switch (symbol.keyword) { + case `button`: + case `input`: + case `span`: + case `label`: + case `legend`: + if (compiler.nextTokenIs(`to`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setText`, + symbolName: symbol.name, + value + }); + return true; + } + break; + default: + break; + } + } + } + } else if (token === `size`) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbol = compiler.getSymbolRecord(); + switch (symbol.keyword) { + case `input`: + if (compiler.nextTokenIs(`to`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setSize`, + symbolName: symbol.name, + value + }); + return true; + } + } + } + } + } else if (token === `attribute`) { + compiler.next(); + const attributeName = compiler.getValue(); + if (compiler.tokenIs(`of`)) { + if (compiler.nextIsSymbol(true)) { + const symbolRecord = compiler.getSymbolRecord(); + const symbolName = symbolRecord.name; + compiler.next(); + let attributeValue = { + type: `boolean`, + content: true + }; + if (compiler.tokenIs(`to`)) { + attributeValue = compiler.getNextValue(); + } + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setAttribute`, + symbolName, + attributeName, + attributeValue + }); + return true; + } + } + } else if (token === `attributes`) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + const symbolName = symbolRecord.name; + if (symbolRecord.extra !== `dom`) { + compiler.warning(`'${symbolName}' is not a DOM type`); + return false; + } + if (compiler.nextTokenIs(`to`)) { + const attributes = compiler.getNextValue(); + if (attributes) { + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setAttributes`, + symbolName, + attributes + }); + return true; + } + } + } + } + compiler.warning(`'${compiler.getToken()}' is not a symbol`); + return false; + } else if (token === `style`) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + const symbolName = symbolRecord.name; + if (symbolRecord.extra !== `dom`) { + compiler.warning(`'${symbolName}' is not a DOM type`); + return false; + } + if (compiler.nextTokenIs(`to`)) { + const styleValue = compiler.getNextValue(); + if (styleValue) { + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setStyles`, + symbolName, + styleValue + }); + return true; + } + } + } + compiler.warning(`'${compiler.getToken()}' is not a symbol`); + return false; + } + const styleName = compiler.getValue(); + let type = `setStyle`; + let symbolName = ``; + token = compiler.getToken(); + if (token === `of`) { + if (compiler.nextToken() === `body`) { + type = `setBodyStyle`; + } else if (compiler.isSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + symbolName = symbolRecord.name; + if (symbolRecord.extra !== `dom`) { + throw Error(`'${symbolName}' is not a DOM type`); + } + } else { + throw Error(`'${compiler.getToken()}' is not a known symbol`); + } + if (compiler.nextTokenIs(`to`)) { + const styleValue = compiler.getNextValue(); + if (styleValue) { + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type, + symbolName, + styleName, + styleValue + }); + return true; + } + } + } + else if (token === `to`) { + const styleValue = compiler.getNextValue(); + if (styleValue) { + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setHeadStyle`, + styleName, + styleValue + }); + return true; + } + } + } else if (token === `default`) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.keyword === `select`) { + if (compiler.nextTokenIs(`to`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setDefault`, + name: symbolRecord.name, + value + }); + return true; + } + } + } + } + } + } + compiler.addWarning(`Unrecognised syntax in 'set'`); + return false; + }, + + run: (program) => { + const command = program[program.pc]; + let symbol; + let value; + let target; + let targetId; + let targetRecord; + let cssId; + let selectRecord; + switch (command.type) { + case `setContentVar`: + const sourceVar = program.getSymbolRecord(command.source); + targetRecord = program.getSymbolRecord(command.target); + const source = document.getElementById(sourceVar.value[sourceVar.index].content); + target = targetRecord.element[targetRecord.index]; + if (!target) { + targetId = program.getValue(targetRecord.value[targetRecord.index]); + target = document.getElementById(targetId); + } + target.innerHTML = source.innerHTML; + break; + case `setContent`: + value = program.getValue(command.value); + targetRecord = program.getSymbolRecord(command.target); + target = targetRecord.element[targetRecord.index]; + if (!target) { + cssId = targetRecord.value[targetRecord.index].content; + if (!cssId) { + program.runtimeError(command.lino, + `Variable '${targetRecord.name}' has not been attached to a DOM element.`); + return 0; + } + target = document.getElementById(cssId); + } + targetRecord.element[targetRecord.index] = target; + switch (targetRecord.keyword) { + case `text`: + case `textarea`: + target.value = value; + break; + case `input`: + target.value = value; + break; + default: + target.innerHTML = value; + break; + } + break; + case `setSelect`: + // The source is assumed to be an array + sourceRecord = program.getSymbolRecord(command.source); + const sourceData = program.getValue(sourceRecord.value[sourceRecord.index]); + var itemArray = ``; + try { + itemArray = JSON.parse(sourceData); + } catch (err) { + program.runtimeError(command.lino, `Can't parse JSON`); + return 0; + } + // The target is assumed to be a SELECT + selectRecord = program.getSymbolRecord(command.select); + const select = selectRecord.element[selectRecord.index]; + select.options.length = 0; + // Get the name of the display field + const display = program.getValue(command.display); + // For each item, set the title and inner HTML + itemArray.forEach(function (item) { + const title = display ? program.decode(item[display]) : null; + const opt = document.createElement(`option`); + const innerHTML = title ? title : item; + opt.innerHTML = innerHTML; + const value = title ? JSON.stringify(item) : item; + opt.value = value; + select.appendChild(opt); + }); + if (display) { + select.selectedIndex = itemArray.indexOf(display); + } else { + select.selectedIndex = -1; + } + break; + case `setClass`: + symbol = program.getSymbolRecord(command.symbolName); + target = symbol.element[symbol.index]; + if (!target) { + targetId = program.getValue(symbol.value[symbol.index]); + target = document.getElementById(targetId); + } + program.getValue(command.value).split(` `).forEach(function(item) { + target.classList.remove(item); + target.classList.add(item); + }); + break; + case `setId`: + symbol = program.getSymbolRecord(command.symbolName); + target = symbol.element[symbol.index]; + if (!target) { + targetId = program.getValue(symbol.value[symbol.index]); + target = document.getElementById(targetId); + } + target.id = program.getValue(command.value); + break; + case `setText`: + symbol = program.getSymbolRecord(command.symbolName); + target = symbol.element[symbol.index]; + if (!target) { + targetId = program.getValue(symbol.value[symbol.index]); + target = document.getElementById(targetId); + } + value = program.getValue(command.value); + switch (symbol.keyword) { + case `button`: + case `span`: + case `label`: + case `legend`: + target.innerHTML = value; + break; + case `input`: + target.value = value; + break; + default: + break; + } + break; + case `setSize`: + symbol = program.getSymbolRecord(command.symbolName); + if (symbol.keyword === `input`) { + target = symbol.element[symbol.index]; + if (!target) { + targetId = program.getValue(symbol.value[symbol.index]); + target = document.getElementById(targetId); + } + target.size = program.getValue(command.value); + } else { + program.runtimeError(command.lino, `Inappropriate variable type '${symbol.name}'`); + } + break; + case `setAttribute`: + symbol = program.getSymbolRecord(command.symbolName); + target = symbol.element[symbol.index]; + if (!target) { + targetId = program.getValue(symbol.value[symbol.index]); + target = document.getElementById(targetId); + } + const attributeName = program.getValue(command.attributeName); + if (command.attributeValue.type === `boolean`) { + target.setAttribute(attributeName, command.attributeValue.content); + } else { + target.setAttribute(attributeName, program.getValue(command.attributeValue)); + } + break; + case `setAttributes`: + symbol = program.getSymbolRecord(command.symbolName); + target = symbol.element[symbol.index]; + if (!target) { + targetId = program.getValue(symbol.value[symbol.index]); + target = document.getElementById(targetId); + } + for (let n = target.attributes.length - 1; n >= 0; n--) { + target.removeAttribute(target.attributes[n].name); + } + let attributes = program.getValue(command.attributes); + let list = attributes.split(" "); + for (let n = 0; n < list.length; n++) { + let attribute = list[n]; + let p = attribute.indexOf(`=`); + if (p > 0) { + target.setAttribute(attribute.substr(0, p), attribute.substr(p + 1)); + } + else { + target.setAttribute(attribute, attribute); + } + } + break; + case `setStyle`: + case `setStyles`: + symbol = program.getSymbolRecord(command.symbolName); + target = symbol.element[symbol.index]; + if (!target) { + const symbolElement = symbol.value[symbol.index]; + if (!symbolElement.type) { + program.runtimeError(command.lino, `Variable '${symbol.name}' is not attached to a DOM element.`); + return 0; + } + targetId = program.getValue(symbolElement); + target = document.getElementById(targetId); + } + const styleValue = program.getValue(command.styleValue); + if (!symbol.value[symbol.index]) { + program.runtimeError(command.lino, `Variable '${symbol.name}' has not been assigned.`); + return 0; + } + switch (command.type) { + case `setStyle`: + target.style[command.styleName.content] = styleValue; + break; + case `setStyles`: + target.style.cssText = styleValue; + break; + } + break; + case `setHeadStyle`: + const headStyleName = program.getValue(command.styleName); + const headStyleValue = program.getValue(command.styleValue); + var style = document.createElement('style'); + style.innerHTML = `${headStyleName} ${headStyleValue}`; + for (let i = 0; i < document.head.childNodes.length; i++) { + let node = document.head.childNodes[i]; + if (node.tagName === `STYLE`) { + let data = node.innerHTML; + if (data.indexOf(`${headStyleName} `) === 0) { + document.head.removeChild(node); + break; + } + } + } + document.head.appendChild(style); + break; + case `setBodyStyle`: + const bodyStyleValue = program.getValue(command.styleValue); + switch (command.styleName.content) { + case `background`: + document.body.style.background = bodyStyleValue; + break; + default: + program.runtimeError(command.lino, + `Unsupported body attribute '${command.styleName.content}'`); + return 0; + } + break; + case `setTitle`: + document.title = program.getValue(command.value); + break; + case `setDefault`: + selectRecord = program.getSymbolRecord(command.name); + value = program.getValue(command.value); + const element = selectRecord.element[selectRecord.index]; + for (let n = 0; n < element.options.length; n++) { + if (element.options[n].value === value) { + element.selectedIndex = n; + break; + } + } + break; + default: + break; + } + return command.pc + 1; + } + }, + + SPAN: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `span`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + TABLE: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `table`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + TR: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `tr`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + TD: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `td`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + TEXTAREA: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `textarea`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Trace: { + + compile: (compiler) => { + const lino = compiler.getLino(); + const variables = []; + if (compiler.nextIsSymbol()) { + while (compiler.isSymbol()) { + variables.push(compiler.getToken()); + compiler.next(); + } + let alignment = `horizontal`; + if (compiler.tokenIs(`horizontal`) || compiler.tokenIs(`vertical`)) { + alignment = compiler.getToken(); + compiler.next(); + } + compiler.addCommand({ + domain: `browser`, + keyword: `trace`, + variant: `setup`, + lino, + variables, + alignment + }); + return true; + } + compiler.addCommand({ + domain: `browser`, + keyword: `trace`, + variant: `run`, + lino + }); + return true; + }, + + run: (program) => { + const command = program[program.pc]; + switch (command.variant) { + case `setup`: + console.log(`Set up tracer`); + program.tracer = { + variables: command.variables, + alignment: command.alignment + }; + break; + case `run`: + console.log(`Run tracer`); + if (!program.tracer) { + program.tracer = { + variables: [], + alignment: `horizontal` + }; + } + if (!program.tracing) { + const tracer = document.getElementById(`easycoder-tracer`); + if (tracer) { + tracer.innerHTML = + `
` + + `` + + `
` + + `
`; + tracer.style.display = `none`; + } + program.tracing = true; + } + program.stop = false; + break; + } + return program.pc + 1; + } + }, + + UL: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `ul`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Upload: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const file = compiler.getToken(); + if (compiler.nextTokenIs(`to`)) { + const path = compiler.getNextValue(); + if (compiler.tokenIs(`with`)) { + if (compiler.nextIsSymbol()) { + const progress = compiler.getToken(); + if (compiler.nextTokenIs(`and`)) { + if (compiler.nextIsSymbol()) { + const status = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `upload`, + lino, + file, + path, + progress, + status + }); + return true; + } + } + } + } + } + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const fileSpec = program.getSymbolRecord(command.file); + const path = program.getValue(command.path); + const progressSpec = program.getSymbolRecord(command.progress); + const statusSpec = program.getSymbolRecord(command.status); + + const file = fileSpec.element[fileSpec.index]; + const progress = progressSpec.element[progressSpec.index]; + const status = statusSpec.element[statusSpec.index]; + + const setProgress = (value) => { + if (progress) { + progress.value = value; + } + }; + const setStatus = (value) => { + if (status) { + status.innerHTML = value; + } + }; + + const source = file.files[0]; + if (source) { + const formData = new FormData(); + formData.append(`source`, source); + formData.append(`path`, path); + const ajax = new XMLHttpRequest(); + ajax.upload.addEventListener(`progress`, function (event) { + const percent = Math.round((event.loaded / event.total) * 100); + setProgress(percent); + setStatus(`${Math.round(percent)}%...`); + }, false); + ajax.addEventListener(`load`, function (event) { + const response = event.target.responseText; + setProgress(0); + setStatus(``); + console.log(response); + }, false); + ajax.addEventListener(`error`, function () { + setStatus(`Upload failed`); + console.log(`Upload failed`); + }, false); + ajax.addEventListener(`abort`, function () { + setStatus(`Upload aborted`); + console.log(`Upload aborted`); + }, false); + ajax.onreadystatechange = function () { + if (this.readyState === 4) { + const command = program.ajaxCommand; + const status = this.status; + switch (status) { + case 200: + program.run(command.pc + 1); + break; + case 0: + break; + default: + try { + program.runtimeError(command.lino, `Error ${status}`); + } catch (err) { + program.reportError(err, program); + } + break; + } + } + }; + program.ajaxCommand = command; + const postpath = path.startsWith(`http`) ? path : `${window.location.origin}/${EasyCoder_Plugins.rest()}/${path}`; + ajax.open(`POST`, postpath); + ajax.send(formData); + } + return 0; + } + }, + + getHandler: (name) => { + switch (name) { + case `a`: + return EasyCoder_Browser.A; + case `alert`: + return EasyCoder_Browser.Alert; + case `attach`: + return EasyCoder_Browser.Attach; + case `audioclip`: + return EasyCoder_Browser.Audioclip; + case `blockquote`: + return EasyCoder_Browser.BLOCKQUOTE; + case `button`: + return EasyCoder_Browser.BUTTON; + case `canvas`: + return EasyCoder_Browser.CANVAS; + case `clear`: + return EasyCoder_Browser.Clear; + case `convert`: + return EasyCoder_Browser.Convert; + case `create`: + return EasyCoder_Browser.Create; + case `disable`: + return EasyCoder_Browser.Disable; + case `div`: + return EasyCoder_Browser.DIV; + case `enable`: + return EasyCoder_Browser.Enable; + case `fieldset`: + return EasyCoder_Browser.FIELDSET; + case `file`: + return EasyCoder_Browser.FILE; + case `focus`: + return EasyCoder_Browser.Focus; + case `form`: + return EasyCoder_Browser.FORM; + case `fullscreen`: + return EasyCoder_Browser.FullScreen; + case `get`: + return EasyCoder_Browser.Get; + case `h1`: + return EasyCoder_Browser.H1; + case `h2`: + return EasyCoder_Browser.H2; + case `h3`: + return EasyCoder_Browser.H3; + case `h4`: + return EasyCoder_Browser.H4; + case `h5`: + return EasyCoder_Browser.H5; + case `h6`: + return EasyCoder_Browser.H6; + case `highlight`: + return EasyCoder_Browser.Highlight; + case `history`: + return EasyCoder_Browser.History; + case `hr`: + return EasyCoder_Browser.HR; + case `image`: + return EasyCoder_Browser.IMAGE; + case `img`: + return EasyCoder_Browser.IMG; + case `input`: + return EasyCoder_Browser.INPUT; + case `label`: + return EasyCoder_Browser.LABEL; + case `legend`: + return EasyCoder_Browser.LEGEND; + case `li`: + return EasyCoder_Browser.LI; + case `location`: + return EasyCoder_Browser.Location; + case `mail`: + return EasyCoder_Browser.Mail; + case `on`: + return EasyCoder_Browser.On; + case `option`: + return EasyCoder_Browser.OPTION; + case `p`: + return EasyCoder_Browser.P; + case `play`: + return EasyCoder_Browser.Play; + case `pre`: + return EasyCoder_Browser.PRE; + case `progress`: + return EasyCoder_Browser.PROGRESS; + case `put`: + return EasyCoder_Browser.Put; + case `remove`: + return EasyCoder_Browser.Remove; + case `request`: + return EasyCoder_Browser.Request; + case `select`: + return EasyCoder_Browser.SELECT; + case `scroll`: + return EasyCoder_Browser.Scroll; + case `section`: + return EasyCoder_Browser.SECTION; + case `set`: + return EasyCoder_Browser.Set; + case `span`: + return EasyCoder_Browser.SPAN; + case `table`: + return EasyCoder_Browser.TABLE; + case `tr`: + return EasyCoder_Browser.TR; + case `td`: + return EasyCoder_Browser.TD; + case `textarea`: + return EasyCoder_Browser.TEXTAREA; + case `trace`: + return EasyCoder_Browser.Trace; + case `ul`: + return EasyCoder_Browser.UL; + case `upload`: + return EasyCoder_Browser.Upload; + default: + return null; + } + }, + + run: (program) => { + const command = program[program.pc]; + const handler = EasyCoder_Browser.getHandler(command.keyword); + if (!handler) { + program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'browser' package`); + } + return handler.run(program); + }, + + value: { + + compile: (compiler) => { + if (compiler.isSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (compiler.nextTokenIs(`exists`)) { + if (symbolRecord.extra === `dom`) { + compiler.next(); + return { + domain: `browser`, + type: `exists`, + value: symbolRecord.name + }; + } + return null; + } + switch (symbolRecord.keyword) { + case `file`: + case `input`: + case `select`: + case `textarea`: + return { + domain: `browser`, + type: symbolRecord.keyword, + value: symbolRecord.name + }; + } + return null; + } + + if (compiler.tokenIs(`the`)) { + compiler.next(); + } + let offset = false; + if (compiler.tokenIs(`offset`)) { + offset = true; + compiler.next(); + } + + let type = compiler.getToken(); + let text; + let attribute; + switch (type) { + case `mobile`: + case `portrait`: + case `landscape`: + case `br`: + case `location`: + case `key`: + case `hostname`: + compiler.next(); + return { + domain: `browser`, + type + }; + case `content`: + case `text`: + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbol = compiler.getSymbolRecord(); + compiler.next(); + return { + domain: `browser`, + type: `contentOf`, + symbol: symbol.name + }; + } + throw new Error(`'${compiler.getToken()}' is not a symbol`); + } + return null; + case `selected`: + let arg = compiler.nextToken(); + if ([`index`, `item`].includes(arg)) { + if ([`in`, `of`].includes(compiler.nextToken())) { + if (compiler.nextIsSymbol()) { + const symbol = compiler.getSymbolRecord(); + if ([`ul`, `ol`, `select`].includes(symbol.keyword)) { + compiler.next(); + return { + domain: `browser`, + type: `selected`, + symbol: symbol.name, + arg + }; + } + } + } + } + return null; + case `color`: + compiler.next(); + const value = compiler.getValue(); + return { + domain: `browser`, + type, + value + }; + case `attribute`: + attribute = compiler.getNextValue(); + if (compiler.tokenIs(`of`)) { + compiler.next(); + if (compiler.isSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.extra === `dom`) { + compiler.next(); + return { + domain: `browser`, + type: `attributeOf`, + attribute, + symbol: symbolRecord.name + }; + } + } + } + return null; + case `style`: + const style = compiler.getNextValue(); + if (compiler.tokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.extra === `dom`) { + compiler.next(); + return { + domain: `browser`, + type, + style, + target: symbolRecord.name + }; + } + } + } + return null; + case `confirm`: + text = compiler.getNextValue(); + return { + domain: `browser`, + type: `confirm`, + text + }; + case `prompt`: + text = compiler.getNextValue(); + let pre = null; + if (compiler.tokenIs(`with`)) { + pre = compiler.getNextValue(); + } + return { + domain: `browser`, + type: `prompt`, + text, + pre + }; + case `screen`: + attribute = compiler.nextToken(); + if ([`width`, `height`].includes(attribute)) { + compiler.next(); + return { + domain: `browser`, + type, + attribute + }; + } + break; + case `top`: + case `bottom`: + case `left`: + case `right`: + case `width`: + case `height`: + return EasyCoder_Browser.value.getCoord(compiler, type, offset); + case `scroll`: + if (compiler.nextTokenIs(`position`)) { + compiler.next(); + return { + domain: `browser`, + type: `scrollPosition` + }; + } + return null; + case `document`: + if (compiler.nextTokenIs(`path`)) { + compiler.next(); + return { + domain: `browser`, + type: `docPath` + }; + } + return null; + case `storage`: + if (compiler.nextTokenIs(`keys`)) { + compiler.next(); + return { + domain: `browser`, + type: `storageKeys` + }; + } + return null; + case `parent`: + switch (compiler.nextToken()) { + case `name`: + compiler.next(); + return { + domain: `browser`, + type: `varName` + }; + case `index`: + compiler.next(); + return { + domain: `browser`, + type: `varIndex` + }; + } + return null; + case `history`: + if (compiler.nextTokenIs(`state`)) { + compiler.next(); + return { + domain: `browser`, + type: `historyState` + }; + } + return null; + case `pick`: + case `drag`: + if (compiler.nextTokenIs(`position`)) { + compiler.next(); + return { + domain: `browser`, + type: `${type}Position` + }; + } + } + return null; + }, + + getCoord: (compiler, type, offset) => { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextTokenIs(`window`)) { + compiler.next(); + return { + domain: `browser`, + type, + symbol: `window`, + offset + }; + } + let symbolRecord = null; + if (compiler.isSymbol()) { + symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.extra === `dom`) { + compiler.next(); + return { + domain: `browser`, + type, + symbol: symbolRecord.name, + offset + }; + } + } + } + return null; + }, + + get: (program, value) => { + let symbolRecord; + let element; + let target; + let content; + switch (value.type) { + case `file`: + case `input`: + case `select`: + case `textarea`: + symbolRecord = program.getSymbolRecord(value.value); + target = symbolRecord.element[symbolRecord.index]; + return { + type: `constant`, + numeric: false, + content: target.value + }; + case `exists`: + symbolRecord = program.getSymbolRecord(value.value); + return { + domain: `browser`, + type: `boolean`, + content: typeof symbolRecord.element[symbolRecord.index] !== `undefined` + }; + case `mobile`: + return { + domain: `browser`, + type: `boolean`, + content: (typeof window.orientation !== `undefined`) || (navigator.userAgent.indexOf(`IEMobile`) !== -1) + }; + case `portrait`: + return { + domain: `browser`, + type: `boolean`, + content: document.documentElement.clientWidth < document.documentElement.clientHeight + }; + case `landscape`: + return { + domain: `browser`, + type: `boolean`, + content: document.documentElement.clientWidth >= document.documentElement.clientHeight + }; + case `br`: + return { + type: `constant`, + numeric: false, + content: decodeURIComponent(`%3Cbr%20%2F%3E`) + }; + case `attributeOf`: + symbolRecord = program.getSymbolRecord(value.symbol); + const attribute = program.getValue(value.attribute); + target = symbolRecord.element[symbolRecord.index]; + if (attribute.indexOf(`data-`) === 0) { + return program.getSimpleValue(target.dataset[attribute.substr(5)]); + } + return program.getSimpleValue(target[attribute]); + case `style`: + symbolRecord = program.getSymbolRecord(value.target); + const style = program.getValue(value.style); + target = symbolRecord.element[symbolRecord.index]; + return program.getSimpleValue(target.style[style]); + case `confirm`: + return { + type: `boolean`, + content: window.confirm(program.getValue(value.text)) + }; + case `prompt`: + const text = program.getValue(value.text); + const pre = program.getValue(value.pre); + return { + type: `constant`, + numeric: false, + content: pre ? window.prompt(text, pre) : window.prompt(text) + }; + case `contentOf`: + symbolRecord = program.getSymbolRecord(value.symbol); + target = symbolRecord.element[symbolRecord.index]; + switch (symbolRecord.keyword) { + case `input`: + case `textarea`: + content = target.value; + break; + case `pre`: + content = target.innerHTML; + break; + default: + content = target.innerHTML.split(`\n`).join(``); + break; + } + return { + type: `constant`, + numeric: false, + content + }; + case `selected`: + symbolRecord = program.getSymbolRecord(value.symbol); + target = symbolRecord.element[symbolRecord.index]; + let selectedIndex = target.selectedIndex; + let selectedText = selectedIndex >= 0 ? target.options[selectedIndex].text : ``; + content = (value.arg === `index`) ? selectedIndex : selectedText; + return { + type: `constant`, + numeric: false, + content + }; + case `top`: + if (value.symbol == `window`) { + return { + type: `constant`, + numeric: true, + content: window.screenY + }; + } + symbolRecord = program.getSymbolRecord(value.symbol); + element = symbolRecord.element[symbolRecord.index]; + content = Math.round(value.offset ? element.offsetTop : element.getBoundingClientRect().top); + return { + type: `constant`, + numeric: true, + content + }; + case `bottom`: + if (value.symbol == `window`) { + return { + type: `constant`, + numeric: true, + content: window.screenY + window.innerHeight + }; + } + symbolRecord = program.getSymbolRecord(value.symbol); + content = Math.round(symbolRecord.element[symbolRecord.index].getBoundingClientRect().bottom); + return { + type: `constant`, + numeric: true, + content + }; + case `left`: + if (value.symbol == `window`) { + return { + type: `constant`, + numeric: true, + content: window.screenLeft + }; + } + symbolRecord = program.getSymbolRecord(value.symbol); + element = symbolRecord.element[symbolRecord.index]; + content = Math.round(value.offset ? element.offsetLeft : element.getBoundingClientRect().left); + return { + type: `constant`, + numeric: true, + content + }; + case `right`: + if (value.symbol == `window`) { + return { + type: `constant`, + numeric: true, + content: window.screenX + window.innerWidth + }; + } + symbolRecord = program.getSymbolRecord(value.symbol); + content = Math.round(symbolRecord.element[symbolRecord.index].getBoundingClientRect().right); + return { + type: `constant`, + numeric: true, + content + }; + case `width`: + if (value.symbol == `window`) { + return { + type: `constant`, + numeric: true, + content: window.innerWidth + }; + } + symbolRecord = program.getSymbolRecord(value.symbol); + content = Math.round(symbolRecord.element[symbolRecord.index].getBoundingClientRect().width); + return { + type: `constant`, + numeric: true, + content + }; + case `height`: + if (value.symbol == `window`) { + return { + type: `constant`, + numeric: true, + content: window.innerHeight + }; + } + symbolRecord = program.getSymbolRecord(value.symbol); + content = Math.round(symbolRecord.element[symbolRecord.index].getBoundingClientRect().height); + return { + type: `constant`, + numeric: true, + content + }; + case `color`: + const styleValue = program.value.evaluate(program, value.value).content; + const hex = styleValue.toString(16).padStart(6, `0`); + return { + type: `constant`, + numeric: false, + content: `#${hex}` + }; + case `docPath`: + return { + type: `constant`, + numeric: false, + content: program.docPath + }; + case `storageKeys`: + return { + type: `constant`, + numeric: false, + content: JSON.stringify(Object.keys(localStorage)) + }; + case `location`: + return { + type: `constant`, + numeric: false, + content: window.location.href + }; + case `historyState`: + return { + type: `constant`, + numeric: false, + content: window.history.state + }; + case `scrollPosition`: + return { + type: `constant`, + numeric: true, + content: scrollPosition + }; + case `varName`: + return { + type: `constant`, + numeric: false, + content: program.varName + }; + case `varIndex`: + return { + type: `constant`, + numeric: true, + content: program.varIndex + }; + case `key`: + return { + type: `constant`, + numeric: false, + content: program.key + }; + case `hostname`: + return { + type: `constant`, + numeric: false, + content: location.hostname + }; + case `screen`: + return { + type: `constant`, + numeric: true, + content: screen[value.attribute] + }; + case `pickPosition`: + return { + type: `constant`, + numeric: false, + content: JSON.stringify({ + "x": document.pickX, + "y": document.pickY + }) + }; + case `dragPosition`: + return { + type: `constant`, + numeric: false, + content: JSON.stringify({ + "x": document.dragX, + "y": document.dragY + }) + }; + } + } + }, + + condition: { + + compile: (compiler) => { + if (compiler.tokenIs(`confirm`)) { + const value = compiler.getNextValue(); + return { + domain: `browser`, + type: `confirm`, + value + }; + } else if (compiler.tokenIs(`element`)) { + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.extra === `dom`) { + const token = compiler.nextToken(); + if (token === `has`) { + if (compiler.nextTokenIs(`the`)) { + compiler.next(); + } + if (compiler.tokenIs(`focus`)) { + compiler.next(); + return { + domain: `browser`, + type: `focus`, + element: symbolRecord.name + }; + } + } else if (token === `contains`) { + const position = compiler.getNextValue(); + return { + domain: `browser`, + type: `contains`, + element: symbolRecord.name, + position + }; + } + } + } + } + return null; + }, + + test: (program, condition) => { + switch (condition.type) { + case `confirm`: + return confirm(program.getValue(condition.value)); + case `focus`: + const focusRecord = program.getSymbolRecord(condition.element); + return focusRecord.element[focusRecord.index] === document.activeElement; + case `contains`: + const containsRecord = program.getSymbolRecord(condition.element); + const element = containsRecord.element[containsRecord.index]; + const bounds = element.getBoundingClientRect(); + const left = Math.round(bounds.left); + const right = Math.round(bounds.right); + const top = Math.round(bounds.top); + const bottom = Math.round(bounds.bottom); + const position = JSON.parse(program.getValue(condition.position)); + const x = position.x; + const y = position.y; + if (x >= left && x <= right && y >= top && y <= bottom) { + return true; + } + return false; + } + } + }, + + setStyles: (id, styleString) => { + const element = document.getElementById(id); + const styles = styleString.split(`;`); + for (const item of styles) { + const style = item.split(`:`); + element.setAttribute(style[0], style[1]); + } + } +}; + +let scrollPosition = 0; + +window.addEventListener(`scroll`, function () { + scrollPosition = this.scrollY; +}); + +window.onpopstate = function (event) { + window.EasyCoder.timestamp = Date.now(); + const state = JSON.parse(event.state); + if (state && state.script) { + const program = window.EasyCoder.scripts[state.script]; + if (program) { + if (program.onBrowserBack) { + program.run(program.onBrowserBack); + } + } else { + console.log(`No script property in window state object`); + } + } +}; diff --git a/js/easycoder/Json.js b/js/easycoder/Json.js new file mode 100644 index 0000000..d727f8c --- /dev/null +++ b/js/easycoder/Json.js @@ -0,0 +1,510 @@ +const EasyCoder_Json = { + + name: `EasyCoder_JSON`, + + Json: { + + compile: (compiler) => { + const lino = compiler.getLino(); + const request = compiler.nextToken(); + let item; + switch (request) { + case `set`: + compiler.next(); + if (compiler.isSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + if (compiler.nextTokenIs(`to`)) { + const type = compiler.nextToken(); + if (`["array","object"]`.includes(type)) { + compiler.next(); + compiler.addCommand({ + domain: `json`, + keyword: `json`, + lino, + request: `setVariable`, + target: targetRecord.name, + type + }); + return true; + } + } + } else if (targetRecord.keyword === `select`) { + if (compiler.nextTokenIs(`from`)) { + compiler.next(); + if (compiler.isSymbol()) { + const sourceRecord = compiler.getSymbolRecord(); + if (sourceRecord.keyword === `variable`) { + var display = null; + if (compiler.nextTokenIs(`as`)) { + display = compiler.getNextValue(); + } + compiler.addCommand({ + domain: `json`, + keyword: `json`, + lino, + request: `setList`, + target: targetRecord.name, + source: sourceRecord.name, + display + }); + return true; + } + } + } + } + break; + } + break; + case `sort`: + case `shuffle`: + case `format`: + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + compiler.next(); + compiler.addCommand({ + domain: `json`, + keyword: `json`, + lino, + request, + target: targetRecord.name + }); + return true; + } + } + break; + case `parse`: + if (compiler.nextTokenIs(`url`)) { + const source = compiler.getNextValue(); + if (compiler.tokenIs(`as`)) { + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + compiler.next(); + compiler.addCommand({ + domain: `json`, + keyword: `json`, + lino, + request, + source, + target: targetRecord.name + }); + return true; + } + } + } + } + break; + case `delete`: + const what = compiler.nextToken(); + if ([`property`, `element`].includes(what)) { + const value = compiler.getNextValue(); + if ([`from`, `of`].includes(compiler.getToken())) { + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + compiler.next(); + compiler.addCommand({ + domain: `json`, + keyword: `json`, + lino, + request, + what, + value, + target: targetRecord.name + }); + return true; + } + } + } + } + break; + case `rename`: + const oldName = compiler.getNextValue(); + if (compiler.tokenIs(`to`)) { + const newName = compiler.getNextValue(); + if (compiler.tokenIs(`in`)) { + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + compiler.next(); + compiler.addCommand({ + domain: `json`, + keyword: `json`, + lino, + request, + oldName, + newName, + target: targetRecord.name + }); + return true; + } + } + } + } + break; + case `add`: + item = compiler.getNextValue(); + if (compiler.tokenIs(`to`)) { + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + compiler.next(); + compiler.addCommand({ + domain: `json`, + keyword: `json`, + lino, + request, + item, + target: targetRecord.name + }); + return true; + } + } + } + break; + case `split`: + item = compiler.getNextValue(); + let on = `\n`; + if (compiler.tokenIs(`on`)) { + on = compiler.getNextValue(); + } + if ([`giving`, `into`].includes(compiler.getToken())) { + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + compiler.next(); + compiler.addCommand({ + domain: `json`, + keyword: `json`, + lino, + request, + item, + on, + target: targetRecord.name + }); + return true; + } + } + } + break; + case `replace`: + if (compiler.nextTokenIs(`element`)) { + const index = compiler.getNextValue(); + if (compiler.tokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + if ([`by`, `with`].includes(compiler.nextToken())) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `json`, + keyword: `json`, + lino, + request, + target: targetRecord.name, + index, + value + }); + return true; + } + } + } + } + } + break; + } + compiler.addWarning(`Unrecognised json command syntax`); + return false; + }, + + run: (program) => { + const command = program[program.pc]; + let sourceRecord; + let targetRecord; + let record; + let content; + let array; + switch (command.request) { + case `setVariable`: + targetRecord = program.getSymbolRecord(command.target); + content = (command.type === `array`) ? `[]` : `{}`; + targetRecord.value[targetRecord.index] = { + type: `constant`, + numeric: false, + content + }; + break; + case `setList`: + // The source is assumed to be a JSON array + sourceRecord = program.getSymbolRecord(command.source); + const sourceData = program.getValue(sourceRecord.value[sourceRecord.index]); + var itemArray = ``; + try { + itemArray = JSON.parse(sourceData); + } catch (err) { + program.runtimeError(command.lino, `Can't parse JSON`); + return 0; + } + // The target is assumed to be a SELECT + targetRecord = program.getSymbolRecord(command.target); + const target = targetRecord.element[targetRecord.index]; + target.options.length = 0; + // Get the name of the display field + const display = program.getValue(command.display); + // For each item, set the title and inner HTML + itemArray.forEach(function (item) { + const title = display ? program.decode(item[display]) : null; + const opt = document.createElement(`option`); + const innerHTML = title ? title : item; + opt.innerHTML = innerHTML; + const value = title ? JSON.stringify(item) : item; + opt.value = value; + target.appendChild(opt); + }); + target.selectedIndex = -1; + break; + case `sort`: + targetRecord = program.getSymbolRecord(command.target); + const list = program.getValue(targetRecord.value[targetRecord.index]); + content = list ? JSON.stringify(JSON.parse(list).sort()) : null; + targetRecord.value[targetRecord.index] = { + type: `constant`, + numeric: false, + content + }; + break; + case `shuffle`: + targetRecord = program.getSymbolRecord(command.target); + array = JSON.parse(program.getValue(targetRecord.value[targetRecord.index])); + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [array[i], array[j]] = [array[j], array[i]]; + } + targetRecord.value[targetRecord.index] = { + type: `constant`, + numeric: false, + content: JSON.stringify(array) + }; + break; + case `format`: + targetRecord = program.getSymbolRecord(command.target); + const val = JSON.parse(program.getValue(targetRecord.value[targetRecord.index])); + targetRecord.value[targetRecord.index] = { + type: `constant`, + numeric: false, + content: JSON.stringify(val, null, 2) + }; + break; + case `parse`: + var source = program.getValue(command.source); + targetRecord = program.getSymbolRecord(command.target); + content = { + url: source + }; + var n = source.indexOf(`://`); + if (n >= 0) { + n += 3; + content.protocol = source.substr(0, n); + source = source.substr(n); + } + n = source.indexOf(`?`); + if (n > 0) { + content.domain = source.substr(0, n); + content.arg = source.substr(n + 1); + } else { + content.domain = source; + } + if (content.domain.endsWith(`/`)) { + content.domain = content.domain.slice(0, -1); + } + n = content.domain.indexOf(`/`); + if (n > 0) { + content.path = content.domain.substr(n + 1); + content.domain = content.domain.substr(0, n); + } + else { + content.path = ``; + } + targetRecord.value[targetRecord.index] = { + type: `constant`, + numeric: false, + content: JSON.stringify(content, null, 2) + }; + break; + case `delete`: + switch (command.what) { + case `property`: + const name = program.getValue(command.value); + targetRecord = program.getSymbolRecord(command.target); + record = JSON.parse(targetRecord.value[targetRecord.index].content); + delete record[name]; + targetRecord.value[targetRecord.index].content = JSON.stringify(record); + break; + case `element`: + const element = program.getValue(command.value); + targetRecord = program.getSymbolRecord(command.target); + record = JSON.parse(targetRecord.value[targetRecord.index].content); + record.splice(element, 1); + targetRecord.value[targetRecord.index].content = JSON.stringify(record); + break; + } + break; + case `rename`: + const oldName = program.getValue(command.oldName); + const newName = program.getValue(command.newName); + targetRecord = program.getSymbolRecord(command.target); + record = JSON.parse(targetRecord.value[targetRecord.index].content); + content = record[oldName]; + delete record[oldName]; + record[newName] = content; + targetRecord.value[targetRecord.index].content = JSON.stringify(record); + break; + case `add`: + content = program.getValue(command.item); + targetRecord = program.getSymbolRecord(command.target); + const existing = targetRecord.value[targetRecord.index].content; + record = existing ? JSON.parse(existing) : []; + record.push([`[`, `{`].includes(content[0]) ? JSON.parse(content) :content); + targetRecord.value[targetRecord.index] = { + type: `constant`, + numeric: false, + content: JSON.stringify(record) + }; + break; + case `split`: + content = program.getValue(command.item); + const on = program.getValue(command.on); + targetRecord = program.getSymbolRecord(command.target); + targetRecord.value[targetRecord.index] = { + type: `constant`, + numeric: false, + content: JSON.stringify(content.split(on)) + }; + break; + case `replace`: + targetRecord = program.getSymbolRecord(command.target); + const index = program.getValue(command.index); + const value = program.getValue(command.value); + const current = targetRecord.value[targetRecord.index].content; + record = current ? JSON.parse(current) : []; + if (index > record.length - 1) { + program.runtimeError(command.lino, `Index out of range`); + } + record[index] = value; + targetRecord.value[targetRecord.index].content = JSON.stringify(record); + break; + } + return command.pc + 1; + } + }, + + getHandler: (name) => { + switch (name) { + case `json`: + return EasyCoder_Json.Json; + default: + return null; + } + }, + + run: (program) => { + const command = program[program.pc]; + const handler = EasyCoder_Json.getHandler(command.keyword); + if (!handler) { + program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'json' package`); + } + return handler.run(program); + }, + + value: { + + compile: (compiler) => { + if (compiler.tokenIs(`the`)) { + compiler.next(); + } + if (compiler.tokenIs(`json`)) { + const type = compiler.nextToken(); + if ([`size`, `count`, `keys`].includes(type)) { + compiler.skip(`of`); + if (compiler.isSymbol()) { + const target = compiler.getSymbolRecord(); + compiler.next(); + if (target.isVHolder) { + return { + domain: `json`, + type, + name: target.name + }; + } + } + } else if (type === `index`) { + if (compiler.nextTokenIs(`of`)) { + const item = compiler.getNextValue(); + if (compiler.tokenIs(`in`)) { + const list = compiler.getNextValue(); + return { + domain: `json`, + type, + item, + list + }; + } + } + } + } + return null; + }, + + get: (program, value) => { + let symbolRecord; + let data; + let content; + switch (value.type) { + case `size`: + case `count`: + symbolRecord = program.getSymbolRecord(value.name); + data = program.getValue(symbolRecord.value[symbolRecord.index]); + let array; + try { + array = JSON.parse(data); + } catch (err) { + array = []; + } + return { + type: `constant`, + numeric: true, + content: array ? array.length : 0 + }; + case `keys`: + symbolRecord = program.getSymbolRecord(value.name); + data = program.getValue(symbolRecord.value[symbolRecord.index]); + content = data ? JSON.stringify(Object.keys(JSON.parse(data)).sort()) : `[]`; + return { + type: `constant`, + numeric: false, + content + }; + case `index`: + const item = program.getValue(value.item); + const list = JSON.parse(program.getValue(value.list)); + content = list.findIndex(function (value) { + return value === item; + }); + return { + type: `constant`, + numeric: true, + content + }; + } + } + }, + + condition: { + + compile: () => {}, + + test: () => {} + } +}; diff --git a/js/easycoder/Rest.js b/js/easycoder/Rest.js new file mode 100644 index 0000000..3974890 --- /dev/null +++ b/js/easycoder/Rest.js @@ -0,0 +1,216 @@ +const EasyCoder_Rest = { + + name: `EasyCoder_Rest`, + + Rest: { + + compile: (compiler) => { + const lino = compiler.getLino(); + const request = compiler.nextToken(); + switch (request) { + case `get`: + if (compiler.nextIsSymbol(true)) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + if (compiler.nextTokenIs(`from`)) { + const url = compiler.getNextValue(); + let fixup = compiler.getPc(); + compiler.addCommand({ + domain: `rest`, + keyword: `rest`, + lino, + request: `get`, + target: targetRecord.name, + url, + onError: null + }); + if (compiler.tokenIs(`or`)) { + compiler.next(); + compiler.getCommandAt(fixup).onError = compiler.getPc() + 1; + compiler.completeHandler(); + } + return true; + } + } + } + break; + case `post`: + let value = null; + if (compiler.nextTokenIs(`to`)) { + compiler.next(); + } else { + value = compiler.getValue(); + if (compiler.tokenIs(`to`)) { + compiler.next(); + } else { + break; + } + } + const url = compiler.getValue(); + if (!url) { + throw new Error(command.lino, `No URL present`); + } + let target = null; + if (compiler.tokenIs(`giving`)) { + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.isVHolder) { + target = targetRecord.name; + compiler.next(); + } else { + throw new Error(`'${targetRecord.name}' cannot hold a value`); + } + } + } + compiler.addCommand({ + domain: `rest`, + keyword: `rest`, + lino, + request: `post`, + value, + url, + target, + onError: compiler.getPc() + 2 + }); + onError = null; + if (compiler.tokenIs(`or`)) { + compiler.next(); + // onError = compiler.getPc() + 1; + compiler.completeHandler(); + } + return true; + } + return false; + }, + + createCORSRequest: (method, url) => { + var xhr = new XMLHttpRequest(); + if (`withCredentials` in xhr) { + + // Check if the XMLHttpRequest object has a "withCredentials" property. + // "withCredentials" only exists on XMLHTTPRequest2 objects. + xhr.open(method, url, true); + + } else if (typeof XDomainRequest != `undefined`) { + + // Otherwise, check if XDomainRequest. + // XDomainRequest only exists in IE, and is IE's way of making CORS requests. + xhr = new XDomainRequest(); + xhr.open(method, url); + + } else { + + // Otherwise, CORS is not supported by the browser. + xhr = null; + + } + return xhr; + }, + + run: (program) => { + const command = program[program.pc]; + const url = program.getValue(command.url); + const rest = EasyCoder_Plugins.rest(); + const path = url.startsWith(`http`) ? url + : url[0] === `/` ? url.substr(1) + : `${window.location.origin}${rest ? `/${rest}` : ``}/${url}`; + + const request = EasyCoder_Rest.Rest.createCORSRequest(command.request, path); + if (!request) { + program.runtimeError(command.lino, `CORS not supported`); + return; + } + request.script = program.script; + request.pc = program.pc; + + request.onload = function () { + let s = request.script; + let p = EasyCoder.scripts[s]; + let pc = request.pc; + let c = p[pc]; + if (200 <= request.status && request.status < 400) { + var content = request.responseText.trim(); + if (c.target) { + const targetRecord = program.getSymbolRecord(command.target); + targetRecord.value[targetRecord.index] = { + type: `constant`, + numeric: false, + content + }; + targetRecord.used = true; + } + p.run(c.pc + 1); + } else { + const error = `${request.status} ${request.statusText}`; + if (c.onError) { + p.errorMessage = `Exception trapped: ${error}`; + p.run(c.onError); + } else { + p.runtimeError(c.lino, `Error: ${error}`); + } + } + }; + + request.onerror = function () { + if (command.onError) { + program.errorMessage = this.responseText; + program.run(command.onError); + } else { + const error = this.responseText; + program.runtimeError(command.lino, error); + } + }; + + switch (command.request) { + case `get`: + // console.log(`GET from ${path}`); + request.send(); + break; + case `post`: + const value = program.getValue(command.value); + console.log(`POST to ${path}`); + //console.log(`value=${value}`); + request.setRequestHeader(`Content-type`, `application/json; charset=UTF-8`); + request.send(value); + break; + } + return 0; + } + }, + + getHandler: (name) => { + switch (name) { + case `rest`: + return EasyCoder_Rest.Rest; + default: + return null; + } + }, + + run: (program) => { + const command = program[program.pc]; + const handler = EasyCoder_Rest.getHandler(command.keyword); + if (!handler) { + program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'rest' package`); + } + return handler.run(program); + }, + + value: { + + compile: () => { + return null; + }, + + get: () => { + return null; + } + }, + + condition: { + + compile: () => {}, + + test: () => {} + } +}; From f7f4c396c501086a6fff5217135d29e8f70e227a Mon Sep 17 00:00:00 2001 From: Graham Trott Date: Mon, 13 Apr 2020 12:20:06 +0100 Subject: [PATCH 2/6] Prepare for CDN delivery --- easycoder/easycoder-min.js | 332 +- easycoder/easycoder.js | 10590 ++++++++++++++++++++++++----------- easycoder/easycoder.zip | Bin 247306 -> 271028 bytes js/easycoder/Compile.js | 1 + js/easycoder/Core.js | 42 - js/easycoder/Main.js | 126 +- js/plugins/anagrams.js | 5 +- js/plugins/aws.js | 5 +- js/plugins/browser.js | 3345 ----------- js/plugins/ckeditor.js | 3 + js/plugins/codemirror.js | 3 + js/plugins/dummy.js | 5 +- js/plugins/gmap.js | 3 + js/plugins/json.js | 510 -- js/plugins/life.js | 5 +- js/plugins/rest.js | 216 - js/plugins/showdown.js | 3 + js/plugins/svg.js | 3 + js/plugins/ui.js | 3 + js/plugins/vfx.js | 3 + js/plugins/wof.js | 3 + 21 files changed, 7559 insertions(+), 7647 deletions(-) delete mode 100644 js/plugins/browser.js delete mode 100644 js/plugins/json.js delete mode 100644 js/plugins/rest.js diff --git a/easycoder/easycoder-min.js b/easycoder/easycoder-min.js index e2ba2a1..806193a 100644 --- a/easycoder/easycoder-min.js +++ b/easycoder/easycoder-min.js @@ -1,123 +1,227 @@ var $jscomp$this=this,$jscomp=$jscomp||{};$jscomp.scope={};$jscomp.createTemplateTagFirstArg=function(a){return a.raw=a};$jscomp.createTemplateTagFirstArgWithRaw=function(a,b){a.raw=b;return a};$jscomp.arrayIteratorImpl=function(a){var b=0;return function(){return bc&&(c=Math.max(c+e,0));ca?-b:b}},"es6","es3");$jscomp.polyfill("String.prototype.endsWith",function(a){return a?a:function(a,c){var b=$jscomp.checkStringArgs(this,a,"endsWith");a+="";void 0===c&&(c=b.length);c=Math.max(0,Math.min(c|0,b.length));for(var e=a.length;0=e}},"es6","es3"); +$jscomp.polyfill("String.prototype.startsWith",function(a){return a?a:function(a,c){var b=$jscomp.checkStringArgs(this,a,"startsWith");a+="";var e=b.length,f=a.length;c=Math.max(0,Math.min(c|0,b.length));for(var k=0;k=f}},"es6","es3"); +$jscomp.polyfill("String.prototype.repeat",function(a){return a?a:function(a){var b=$jscomp.checkStringArgs(this,null,"repeat");if(0>a||1342177279>>=1)b+=b;return d}},"es6","es3");$jscomp.stringPadding=function(a,b){a=void 0!==a?String(a):" ";return 0=e}},"es6","es3");$jscomp.polyfill("Object.is",function(a){return a?a:function(a,c){return a===c?0!==a||1/a===1/c:a!==a&&c!==c}},"es6","es3"); -$jscomp.polyfill("Array.prototype.includes",function(a){return a?a:function(a,c){var b=this;b instanceof String&&(b=String(b));var e=b.length;c=c||0;for(0>c&&(c=Math.max(c+e,0));ca?-b:b}},"es6","es3");$jscomp.polyfill("String.prototype.repeat",function(a){return a?a:function(a){var b=$jscomp.checkStringArgs(this,null,"repeat");if(0>a||1342177279>>=1)b+=b;return d}},"es6","es3"); -$jscomp.stringPadding=function(a,b){a=void 0!==a?String(a):" ";return 0d?1:c=this.tokens.length?null:this.tokens[this.index]?this.tokens[this.index].token:null},nextToken:function(){this.next();return this.getToken()},tokenIs:function(a){return this.index>=this.tokens.length?!1:a===this.tokens[this.index].token}, -nextTokenIs:function(a){this.next();return this.tokenIs(a)},skip:function(a){if(this.index>=this.tokens.length)return null;this.next();this.tokenIs(a)&&this.next()},prev:function(){this.index--},getLino:function(){return this.index>=this.tokens.length?0:this.tokens[this.index].lino},getTarget:function(a){a=void 0===a?this.index:a;return this.tokens[a].token},getTargetPc:function(a){a=void 0===a?this.index:a;return this.symbols[this.getTarget(a)].pc},getCommandAt:function(a){return this.program[a]}, -isSymbol:function(a){a=void 0===a?!1:a;if(this.getTarget()in this.symbols)return!0;if(a)throw Error("Unknown symbol: '"+this.getTarget()+"'");return!1},nextIsSymbol:function(a){a=void 0===a?!1:a;this.next();return this.isSymbol(a)},getSymbol:function(a){if(this.isSymbol(void 0===a?!1:a))return this.symbols[this.getToken()]},getSymbolPc:function(a){return this.getSymbol(void 0===a?!1:a).pc},getSymbolRecord:function(){var a=this.program[this.getSymbolPc(!0)];a.used=!0;return a},getSymbols:function(){return this.symbols}, -getProgram:function(){return this.program},getPc:function(){return this.program.length},getValue:function(){return this.value.compile(this)},getNextValue:function(){this.next();return this.getValue()},getCondition:function(){return this.condition.compile(this)},constant:function(a,b){return this.value.constant(a,void 0===b?!1:b)},addCommand:function(a){this.program.push(Object.assign({},{pc:this.program.length},a))},addSymbol:function(a,b){this.symbols[a]={pc:b}},mark:function(){this.savedMark=this.index}, -rewind:function(){this.index=this.savedMark},rewindTo:function(a){this.index=a},completeHandler:function(){var a=this.getLino(),b=this.getPc();this.addCommand({domain:"core",keyword:"goto",lino:a,goto:0});this.compileOne();this.continue?(this.addCommand({domain:"core",keyword:"goto",lino:a,goto:this.getPc()+1}),this.continue=!1):this.addCommand({domain:"core",keyword:"stop",lino:a,next:0});this.getCommandAt(b).goto=this.getPc();return!0},compileVariable:function(a,b,c,d){c=void 0===c?!1:c;d=void 0=== -d?null:d;this.next();var e=this.getLino(),f=this.getTokens()[this.getIndex()];if(this.symbols[f.token])throw Error("Duplicate variable name '"+f.token+"'");var g=this.getPc();this.next();this.addSymbol(f.token,g);a={domain:a,keyword:b,lino:e,isSymbol:!0,used:!1,isVHolder:c,name:f.token,elements:1,index:0,value:[{}],element:[],extra:d};"dom"===d&&(a.element=[]);this.addCommand(a);return a},compileToken:function(){var a=this.getToken();if(a){this.mark();for(var b=$jscomp.makeIterator(Object.keys(this.domain)), -c=b.next();!c.done;c=b.next()){if((c=this.domain[c.value])&&(c=c.getHandler(a))&&c.compile(this))return;this.rewind()}console.log("No handler found");throw Error("I don't understand '"+a+"...'");}},compileOne:function(){var a=this.getToken();if(a){this.warnings=[];var b=this.program.length;if(a.endsWith(":")){a=a.substring(0,a.length-1);if(this.symbols[a])throw Error("Duplicate symbol: '"+a+"'");this.symbols[a]={pc:b};this.index++}else this.compileToken()}},compileFromHere:function(a){for(;this.index< -this.tokens.length;){var b=this.tokens[this.index].token;if("else"===b)return this.program;this.compileOne();if(-1=c.elements&&a.runtimeError(b.lino,"Array index "+d+" is out of range for '"+c.name+"'");c.index=d;c.imported&&(EasyCoder.symbols[c.exporter].getSymbolRecord(c.exportedName).index=d);return b.pc+1}},Load:{compile:function(a){var b=a.getLino();switch(a.nextToken()){case "plugin":var c=a.getNextValue();a.addCommand({domain:"core",keyword:"load",lino:b,name:c});return!0}return!1},run:function(a){var b= -a[a.pc],c=a.getValue(b.name);switch(b.keyword){case "load":if(a.checkPlugin(c))return b.pc+1;EasyCoder_Plugins.getLocalPlugin(a.getPluginsPath,c,a.getPlugin,a.addLocalPlugin,function(){a.run(b.pc+1)});return 0}}},Module:{compile:function(a){a.compileVariable("core","module");return!0},run:function(a){return a[a.pc].pc+1}},Multiply:{compile:function(a){var b=a.getLino();a.next();if(a.isSymbol()){var c=a.getSymbol();var d=a.getCommandAt(c.pc).name}c=a.getValue();a.tokenIs("by")&&a.next();var e=a.getValue(); -if(a.tokenIs("giving")){a.next();if(a.isSymbol())return d=a.getSymbol(),d=a.getCommandAt(d.pc).name,a.next(),a.addCommand({domain:"core",keyword:"multiply",lino:b,value1:c,value2:e,target:d}),!0;a.warning("core multiply: Expected value holder")}else return"undefined"===typeof d&&a.warning("core multiply: No target variable given"),a.addCommand({domain:"core",keyword:"multiply",lino:b,value2:e,target:d}),!0;return!1},run:function(a){var b=a[a.pc],c=b.value1,d=b.value2,e=a.getSymbolRecord(b.target); -if(e.isVHolder){var f=e.value[e.index];c?(a=a.getValue(c)*a.getValue(d),e.value[e.index]={type:"constant",numeric:!0,content:a}):(!f.numeric&&isNaN(f.content)&&a.nonNumericValueError(b,lino),a=parseInt(f.content)*parseInt(a.getValue(d)),e.value[e.index]={type:"constant",numeric:!0,content:a})}else a.variableDoesNotHoldAValueError(b.lino,e.name);return b.pc+1}},Negate:{compile:function(a){var b=a.getLino();a.next();if(a.isSymbol()){var c=a.getToken();a.next();a.addCommand({domain:"core",keyword:"negate", -lino:b,symbol:c});return!0}return!1},run:function(a){var b=a[a.pc],c=a.getSymbolRecord(b.symbol);c.isVHolder?c.value[c.index]={type:"constant",numeric:!0,content:-c.value[c.index].content}:a.variableDoesNotHoldAValueError(b.lino,c.name);return b.pc+1}},On:{compile:function(a){var b=a.getLino(),c=a.nextToken();switch(c){case "close":case "message":case "error":return a.next(),a.addCommand({domain:"core",keyword:"on",lino:b,action:c}),a.completeHandler()}return a.isSymbol()&&(c=a.getSymbolRecord(), -"callback"===c.keyword)?(a.next(),a.addCommand({domain:"core",keyword:"on",lino:b,action:c.name}),a.completeHandler()):!1},run:function(a){var b=a[a.pc],c=b.pc+2;switch(b.action){case "close":a.onClose=c;break;case "message":a.onMessage=c;break;case "error":a.onError=c;break;default:var d=a.getSymbolRecord(b.action);if(d)d.cb=c;else return a.runtimeError(b.lino,"Unknown action '"+b.action+"'"),0}return b.pc+1}},Print:{compile:function(a){var b=a.getLino();a.next();var c=a.getValue();a.addCommand({domain:"core", -keyword:"print",lino:b,value:c});return!0},run:function(a){var b=a[a.pc];a=a.getFormattedValue(b.value);console.log("-> "+a);return b.pc+1}},Put:{compile:function(a){var b=a.getLino(),c=a.getNextValue();if(a.tokenIs("into")){if(a.nextIsSymbol()){var d=a.getToken();a.next();a.addCommand({domain:"core",keyword:"put",lino:b,value:c,target:d});return!0}a.warning("core:put: No such variable: '"+a.getToken()+"'")}return!1},run:function(a){var b=a[a.pc],c=a.getSymbolRecord(b.target);c.isVHolder||a.variableDoesNotHoldAValueError(b.lino, -c.name);a=a.evaluate(b.value);c.value[c.index]={type:a.type,numeric:a.numeric,content:a.content};c.imported&&(c=EasyCoder.scripts[c.exporter].getSymbolRecord(c.exportedName),c.value[c.index]=a);return b.pc+1}},Replace:{compile:function(a){var b=a.getLino(),c=a.getNextValue();if(a.tokenIs("with")){var d=a.getNextValue();if(a.tokenIs("in")&&a.nextIsSymbol()){var e=a.getSymbolRecord();if(e.isVHolder)return a.next(),a.addCommand({domain:"core",keyword:"replace",lino:b,original:c,replacement:d,target:e.name}), -!0;throw Error("'"+e.name+"' does not hold a value");}}return!1},run:function(a){var b=a[a.pc],c=a.getValue(b.original),d=a.getValue(b.replacement),e=a.getSymbolRecord(b.target);a=a.getValue(e.value[e.index]).split(c).join(d);e.value[e.index]={type:"constant",numeric:!1,content:a};return b.pc+1}},Require:{compile:function(a){var b=a.getLino(),c=a.nextToken();if(["css","js"].includes(c)){var d=a.getNextValue();a.addCommand({domain:"core",keyword:"require",lino:b,type:c,url:d});return!0}throw Error("File type must be 'css' or 'js'"); -},run:function(a){var b=a[a.pc];a.require(b.type,a.getValue(b.url),function(){a.run(b.pc+1)});return 0}},Return:{compile:function(a){var b=a.getLino();a.next();a.addCommand({domain:"core",keyword:"return",lino:b});return!0},run:function(a){return a.stack.pop()}},Run:{compile:function(a){var b=a.getLino(),c=a.getNextValue(),d=[];if(a.tokenIs("with"))for(;;)if(a.nextIsSymbol(!0)){var e=a.getSymbolRecord();d.push(e.name);a.next();if(!a.tokenIs("and"))break}if(a.tokenIs("as")&&a.nextIsSymbol(!0)){var f= -a.getSymbolRecord();a.next();if("module"!==f.keyword)throw Error("'"+f.name+"' is not a module");f=f.name}var g=!1;a.tokenIs("nowait")&&(a.next(),g=!0);e=a.getPc();a.addCommand({domain:"core",keyword:"run",lino:b,script:c,imports:d,module:f,nowait:g,then:0});a.tokenIs("then")&&(b=a.getPc(),a.addCommand({domain:"core",keyword:"goto",goto:0}),a.getCommandAt(e).then=a.getPc(),a.next(),a.compileOne(!0),a.addCommand({domain:"core",keyword:"stop"}),a.getCommandAt(b).goto=a.getPc());return!0},run:function(a){a.nextPc= -a.pc+1;a.runScript(a);return 0}},Sanitize:{compile:function(a){var b=a.getLino();if(a.nextIsSymbol()){var c=a.getToken();a.next();a.addCommand({domain:"core",keyword:"sanitize",lino:b,name:c});return!0}return!1},run:function(a){var b=a[a.pc];a=a.getSymbolRecord(b.name);a=a.value[a.index];a.content=JSON.stringify(JSON.parse(a.content));return b.pc+1}},Script:{compile:function(a){var b=a.getProgram();b.script=a.nextToken();a.script=b.script;if(EasyCoder.scripts[b.script])throw delete a.script,Error("Script '"+ -b.script+"' is already running.");EasyCoder.scripts[b.script]=b;a.next();return!0},run:function(a){return a[a.pc].pc+1}},Send:{compile:function(a){var b=a.getLino(),c="";a.nextTokenIs("to")||(c=a.getValue());if(a.tokenIs("to")){if(a.nextTokenIs("parent"))var d="parent";else if(a.isSymbol){d=a.getSymbolRecord();if("module"!==d.keyword)throw Error("'"+d.name+"' is not a module");d=d.name}a.next();a.addCommand({domain:"core",keyword:"send",lino:b,message:c,recipient:d})}return!0},run:function(a){var b= -a[a.pc],c=a.getValue(b.message);"parent"===b.recipient?a.parent&&(a=EasyCoder.scripts[a.parent],a.onMessage&&(a.message=c,a.run(a.onMessage))):(a=a.getSymbolRecord(b.recipient),a.program&&(a=EasyCoder.scripts[a.program],a.message=c,a.run(a.onMessage)));return b.pc+1}},Set:{compile:function(a){var b=a.getLino();if(a.nextIsSymbol()){var c=a.getSymbolRecord();if(!c.isVHolder)return!1;if(a.nextTokenIs("to")){var d=a.nextToken();if(["array","object"].includes(d))return a.next(),a.addCommand({domain:"core", -keyword:"set",lino:b,request:"setVarTo",target:c.name,type:d}),!0;for(d=[];;){a.mark();try{d.push(a.getValue())}catch(f){a.rewind();break}}a.addCommand({domain:"core",keyword:"set",lino:b,request:"setArray",target:c.name,value:d});return!0}a.addCommand({domain:"core",keyword:"set",lino:b,request:"setBoolean",target:c.name});return!0}switch(a.getToken()){case "ready":return a.next(),a.addCommand({domain:"core",keyword:"set",lino:b,request:"setReady"}),!0;case "element":c=a.getNextValue();if(a.tokenIs("of")&& -a.nextIsSymbol()&&(d=a.getSymbolRecord(),"variable"===d.keyword&&a.nextTokenIs("to"))){var e=a.getNextValue();a.addCommand({domain:"core",keyword:"set",lino:b,request:"setElement",target:d.name,index:c,value:e});return!0}break;case "property":c=a.getNextValue();if(a.tokenIs("of")&&a.nextIsSymbol()&&(d=a.getSymbolRecord(),"variable"===d.keyword&&a.nextTokenIs("to")))return e=a.getNextValue(),a.addCommand({domain:"core",keyword:"set",lino:b,request:"setProperty",target:d.name,name:c,value:e}),!0;break; -case "arg":if(c=a.getNextValue(),a.tokenIs("of")&&a.nextIsSymbol()&&(d=a.getSymbolRecord(),a.nextTokenIs("to")))return e=a.getNextValue(),a.addCommand({domain:"core",keyword:"set",lino:b,request:"setArg",target:d.name,name:c,value:e}),!0}a.tokenIs("the")&&a.next();switch(a.getToken()){case "elements":a.next();if(a.tokenIs("of")){a.next();if(!a.isSymbol())throw Error("Unknown variable '"+a.getToken()+"'");c=a.getToken();a.next();if(a.tokenIs("to"))return a.next(),d=a.getValue(),a.addCommand({domain:"core", -keyword:"set",lino:b,request:"setElements",symbol:c,value:d}),!0}break;case "encoding":if(a.nextTokenIs("to"))return c=a.getNextValue(),a.addCommand({domain:"core",keyword:"set",request:"encoding",lino:b,encoding:c}),!0;a.addWarning("Unknown encoding option");break;case "payload":if(a.nextTokenIs("of")&&a.nextIsSymbol()&&(c=a.getSymbolRecord(),"callback"===c.keyword&&a.nextTokenIs("to")))return d=a.getNextValue(),a.addCommand({domain:"core",keyword:"set",request:"setPayload",lino:b,callback:c.name, -payload:d}),!0}return!1},run:function(a){var b=a[a.pc];switch(b.request){case "setBoolean":var c=a.getSymbolRecord(b.target);c.isVHolder?(c.value[c.index]={type:"boolean",content:!0},b.numeric=!1):a.variableDoesNotHoldAValueError(b.lino,c.name);break;case "setReady":if(c=EasyCoder.scripts[a.parent])c.run(c.nextPc),c.nextPc=0,a.unblocked=!0;break;case "setArray":c=a.getSymbolRecord(b.target);c.elements=b.value.length;c.value=b.value;break;case "encoding":a.encoding=a.getValue(b.encoding);break;case "setElements":c= -a.getSymbolRecord(b.symbol);var d=c.elements;c.elements=a.getValue(b.value);c.index=0;if(c.elements>d)for(a=d;a"};case "uuid":return{type:"constant",numeric:!1,content:"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=16*Math.random()|0;return("x"==a?b:b&3|8).toString(16)})};case "encode":return{type:"constant",numeric:!1, -content:a.encode(a.getValue(b.value))};case "decode":return{type:"constant",numeric:!1,content:a.decode(a.getValue(b.value))};case "reverse":return{type:"constant",numeric:!1,content:a.getValue(b.value).split("").reverse().join("")};case "lowercase":return{type:"constant",numeric:!1,content:a.getValue(b.value).toLowerCase()};case "hash":a=a.getValue(b.value);b=0;if(0===a.length)return b;for(c=0;c=c.elements&&a.runtimeError(b.lino,"Array index "+d+" is out of range for '"+c.name+"'");c.index=d;c.imported&&(EasyCoder.symbols[c.exporter].getSymbolRecord(c.exportedName).index=d);return b.pc+1}},Load:{compile:function(a){var b=a.getLino();switch(a.nextToken()){case "plugin":var c= +a.getNextValue(),d=a.getValue(),e=a.getValue();a.addCommand({domain:"core",keyword:"load",lino:b,name:c,id:d,url:e});return!0}return!1},run:function(a){var b=a[a.pc];a.getValue(b.name);var c=a.getValue(b.id);a.getValue(b.url);switch(b.keyword){case "load":return"undefined"===typeof EasyCoder.domain.name?(a.require("js",a.getValue(b.url),function(){EasyCoder.domain.name=c;a.run(b.pc+1)}),0):b.pc+1}return!1}},Module:{compile:function(a){a.compileVariable("core","module");return!0},run:function(a){return a[a.pc].pc+ +1}},Multiply:{compile:function(a){var b=a.getLino();a.next();if(a.isSymbol()){var c=a.getSymbol();var d=a.getCommandAt(c.pc).name}c=a.getValue();a.tokenIs("by")&&a.next();var e=a.getValue();if(a.tokenIs("giving")){a.next();if(a.isSymbol())return d=a.getSymbol(),d=a.getCommandAt(d.pc).name,a.next(),a.addCommand({domain:"core",keyword:"multiply",lino:b,value1:c,value2:e,target:d}),!0;a.warning("core multiply: Expected value holder")}else return"undefined"===typeof d&&a.warning("core multiply: No target variable given"), +a.addCommand({domain:"core",keyword:"multiply",lino:b,value2:e,target:d}),!0;return!1},run:function(a){var b=a[a.pc],c=b.value1,d=b.value2,e=a.getSymbolRecord(b.target);if(e.isVHolder){var f=e.value[e.index];c?(a=a.getValue(c)*a.getValue(d),e.value[e.index]={type:"constant",numeric:!0,content:a}):(!f.numeric&&isNaN(f.content)&&a.nonNumericValueError(b,lino),a=parseInt(f.content)*parseInt(a.getValue(d)),e.value[e.index]={type:"constant",numeric:!0,content:a})}else a.variableDoesNotHoldAValueError(b.lino, +e.name);return b.pc+1}},Negate:{compile:function(a){var b=a.getLino();a.next();if(a.isSymbol()){var c=a.getToken();a.next();a.addCommand({domain:"core",keyword:"negate",lino:b,symbol:c});return!0}return!1},run:function(a){var b=a[a.pc],c=a.getSymbolRecord(b.symbol);c.isVHolder?c.value[c.index]={type:"constant",numeric:!0,content:-c.value[c.index].content}:a.variableDoesNotHoldAValueError(b.lino,c.name);return b.pc+1}},On:{compile:function(a){var b=a.getLino(),c=a.nextToken();switch(c){case "close":case "message":case "error":return a.next(), +a.addCommand({domain:"core",keyword:"on",lino:b,action:c}),a.completeHandler()}return a.isSymbol()&&(c=a.getSymbolRecord(),"callback"===c.keyword)?(a.next(),a.addCommand({domain:"core",keyword:"on",lino:b,action:c.name}),a.completeHandler()):!1},run:function(a){var b=a[a.pc],c=b.pc+2;switch(b.action){case "close":a.onClose=c;break;case "message":a.onMessage=c;break;case "error":a.onError=c;break;default:var d=a.getSymbolRecord(b.action);if(d)d.cb=c;else return a.runtimeError(b.lino,"Unknown action '"+ +b.action+"'"),0}return b.pc+1}},Print:{compile:function(a){var b=a.getLino();a.next();var c=a.getValue();a.addCommand({domain:"core",keyword:"print",lino:b,value:c});return!0},run:function(a){var b=a[a.pc];a=a.getFormattedValue(b.value);console.log("-> "+a);return b.pc+1}},Put:{compile:function(a){var b=a.getLino(),c=a.getNextValue();if(a.tokenIs("into")){if(a.nextIsSymbol()){var d=a.getToken();a.next();a.addCommand({domain:"core",keyword:"put",lino:b,value:c,target:d});return!0}a.warning("core:put: No such variable: '"+ +a.getToken()+"'")}return!1},run:function(a){var b=a[a.pc],c=a.getSymbolRecord(b.target);c.isVHolder||a.variableDoesNotHoldAValueError(b.lino,c.name);a=a.evaluate(b.value);c.value[c.index]={type:a.type,numeric:a.numeric,content:a.content};c.imported&&(c=EasyCoder.scripts[c.exporter].getSymbolRecord(c.exportedName),c.value[c.index]=a);return b.pc+1}},Replace:{compile:function(a){var b=a.getLino(),c=a.getNextValue();if(a.tokenIs("with")){var d=a.getNextValue();if(a.tokenIs("in")&&a.nextIsSymbol()){var e= +a.getSymbolRecord();if(e.isVHolder)return a.next(),a.addCommand({domain:"core",keyword:"replace",lino:b,original:c,replacement:d,target:e.name}),!0;throw Error("'"+e.name+"' does not hold a value");}}return!1},run:function(a){var b=a[a.pc],c=a.getValue(b.original),d=a.getValue(b.replacement),e=a.getSymbolRecord(b.target);a=a.getValue(e.value[e.index]).split(c).join(d);e.value[e.index]={type:"constant",numeric:!1,content:a};return b.pc+1}},Require:{compile:function(a){var b=a.getLino(),c=a.nextToken(); +if(["css","js"].includes(c)){var d=a.getNextValue();a.addCommand({domain:"core",keyword:"require",lino:b,type:c,url:d});return!0}throw Error("File type must be 'css' or 'js'");},run:function(a){var b=a[a.pc];a.require(b.type,a.getValue(b.url),function(){a.run(b.pc+1)});return 0}},Return:{compile:function(a){var b=a.getLino();a.next();a.addCommand({domain:"core",keyword:"return",lino:b});return!0},run:function(a){return a.stack.pop()}},Run:{compile:function(a){var b=a.getLino(),c=a.getNextValue(), +d=[];if(a.tokenIs("with"))for(;;)if(a.nextIsSymbol(!0)){var e=a.getSymbolRecord();d.push(e.name);a.next();if(!a.tokenIs("and"))break}if(a.tokenIs("as")&&a.nextIsSymbol(!0)){var f=a.getSymbolRecord();a.next();if("module"!==f.keyword)throw Error("'"+f.name+"' is not a module");f=f.name}var k=!1;a.tokenIs("nowait")&&(a.next(),k=!0);e=a.getPc();a.addCommand({domain:"core",keyword:"run",lino:b,script:c,imports:d,module:f,nowait:k,then:0});a.tokenIs("then")&&(b=a.getPc(),a.addCommand({domain:"core",keyword:"goto", +goto:0}),a.getCommandAt(e).then=a.getPc(),a.next(),a.compileOne(!0),a.addCommand({domain:"core",keyword:"stop"}),a.getCommandAt(b).goto=a.getPc());return!0},run:function(a){a.nextPc=a.pc+1;a.runScript(a);return 0}},Sanitize:{compile:function(a){var b=a.getLino();if(a.nextIsSymbol()){var c=a.getToken();a.next();a.addCommand({domain:"core",keyword:"sanitize",lino:b,name:c});return!0}return!1},run:function(a){var b=a[a.pc];a=a.getSymbolRecord(b.name);a=a.value[a.index];a.content=JSON.stringify(JSON.parse(a.content)); +return b.pc+1}},Script:{compile:function(a){var b=a.getProgram();b.script=a.nextToken();a.script=b.script;if(EasyCoder.scripts[b.script])throw delete a.script,Error("Script '"+b.script+"' is already running.");EasyCoder.scripts[b.script]=b;a.next();return!0},run:function(a){return a[a.pc].pc+1}},Send:{compile:function(a){var b=a.getLino(),c="";a.nextTokenIs("to")||(c=a.getValue());if(a.tokenIs("to")){if(a.nextTokenIs("parent"))var d="parent";else if(a.isSymbol){d=a.getSymbolRecord();if("module"!== +d.keyword)throw Error("'"+d.name+"' is not a module");d=d.name}a.next();a.addCommand({domain:"core",keyword:"send",lino:b,message:c,recipient:d})}return!0},run:function(a){var b=a[a.pc],c=a.getValue(b.message);"parent"===b.recipient?a.parent&&(a=EasyCoder.scripts[a.parent],a.onMessage&&(a.message=c,a.run(a.onMessage))):(a=a.getSymbolRecord(b.recipient),a.program&&(a=EasyCoder.scripts[a.program],a.message=c,a.run(a.onMessage)));return b.pc+1}},Set:{compile:function(a){var b=a.getLino();if(a.nextIsSymbol()){var c= +a.getSymbolRecord();if(!c.isVHolder)return!1;if(a.nextTokenIs("to")){var d=a.nextToken();if(["array","object"].includes(d))return a.next(),a.addCommand({domain:"core",keyword:"set",lino:b,request:"setVarTo",target:c.name,type:d}),!0;for(d=[];;){a.mark();try{d.push(a.getValue())}catch(f){a.rewind();break}}a.addCommand({domain:"core",keyword:"set",lino:b,request:"setArray",target:c.name,value:d});return!0}a.addCommand({domain:"core",keyword:"set",lino:b,request:"setBoolean",target:c.name});return!0}switch(a.getToken()){case "ready":return a.next(), +a.addCommand({domain:"core",keyword:"set",lino:b,request:"setReady"}),!0;case "element":c=a.getNextValue();if(a.tokenIs("of")&&a.nextIsSymbol()&&(d=a.getSymbolRecord(),"variable"===d.keyword&&a.nextTokenIs("to"))){var e=a.getNextValue();a.addCommand({domain:"core",keyword:"set",lino:b,request:"setElement",target:d.name,index:c,value:e});return!0}break;case "property":c=a.getNextValue();if(a.tokenIs("of")&&a.nextIsSymbol()&&(d=a.getSymbolRecord(),"variable"===d.keyword&&a.nextTokenIs("to")))return e= +a.getNextValue(),a.addCommand({domain:"core",keyword:"set",lino:b,request:"setProperty",target:d.name,name:c,value:e}),!0;break;case "arg":if(c=a.getNextValue(),a.tokenIs("of")&&a.nextIsSymbol()&&(d=a.getSymbolRecord(),a.nextTokenIs("to")))return e=a.getNextValue(),a.addCommand({domain:"core",keyword:"set",lino:b,request:"setArg",target:d.name,name:c,value:e}),!0}a.tokenIs("the")&&a.next();switch(a.getToken()){case "elements":a.next();if(a.tokenIs("of")){a.next();if(!a.isSymbol())throw Error("Unknown variable '"+ +a.getToken()+"'");c=a.getToken();a.next();if(a.tokenIs("to"))return a.next(),d=a.getValue(),a.addCommand({domain:"core",keyword:"set",lino:b,request:"setElements",symbol:c,value:d}),!0}break;case "encoding":if(a.nextTokenIs("to"))return c=a.getNextValue(),a.addCommand({domain:"core",keyword:"set",request:"encoding",lino:b,encoding:c}),!0;a.addWarning("Unknown encoding option");break;case "payload":if(a.nextTokenIs("of")&&a.nextIsSymbol()&&(c=a.getSymbolRecord(),"callback"===c.keyword&&a.nextTokenIs("to")))return d= +a.getNextValue(),a.addCommand({domain:"core",keyword:"set",request:"setPayload",lino:b,callback:c.name,payload:d}),!0}return!1},run:function(a){var b=a[a.pc];switch(b.request){case "setBoolean":var c=a.getSymbolRecord(b.target);c.isVHolder?(c.value[c.index]={type:"boolean",content:!0},b.numeric=!1):a.variableDoesNotHoldAValueError(b.lino,c.name);break;case "setReady":if(c=EasyCoder.scripts[a.parent])c.run(c.nextPc),c.nextPc=0,a.unblocked=!0;break;case "setArray":c=a.getSymbolRecord(b.target);c.elements= +b.value.length;c.value=b.value;break;case "encoding":a.encoding=a.getValue(b.encoding);break;case "setElements":c=a.getSymbolRecord(b.symbol);var d=c.elements;c.elements=a.getValue(b.value);c.index=0;if(c.elements>d)for(a=d;a"};case "uuid":return{type:"constant",numeric:!1,content:"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=16*Math.random()|0;return("x"==a?b:b&3|8).toString(16)})}; +case "encode":return{type:"constant",numeric:!1,content:a.encode(a.getValue(b.value))};case "decode":return{type:"constant",numeric:!1,content:a.decode(a.getValue(b.value))};case "reverse":return{type:"constant",numeric:!1,content:a.getValue(b.value).split("").reverse().join("")};case "lowercase":return{type:"constant",numeric:!1,content:a.getValue(b.value).toLowerCase()};case "hash":a=a.getValue(b.value);b=0;if(0===a.length)return b;for(c=0;c=c:0c;case "not":return!a.getValue(b.value); -case "moduleRunning":return c=a.getSymbolRecord(b.name),EasyCoder.scripts.hasOwnProperty(c.program)?(c=EasyCoder.scripts[c.program],b.sense?c.running:!c.running):!b.sense;case "includes":return c=JSON.parse(a.getValue(b.value1)),b=a.getValue(b.value2),c.includes(b)}return!1}}},EasyCoder={name:"EasyCoder_Main",domain:{core:EasyCoder_Core},elementId:0,runtimeError:function(a,b){this.lino=a;this.reportError({message:"Line "+(0<=a?a:"")+": "+b},this.program);this.program&&(this.program.aborted=!0)},nonNumericValueError:function(a){this.runtimeError(a, -"Non-numeric value")},variableDoesNotHoldAValueError:function(a,b){this.runtimeError(a,"Variable '"+b+"' does not hold a value")},reportError:function(a,b,c){if(a.message)if(this.compiling||b){c=c?c:b.source;var d=c.tokens;c=c.scriptLines;d=this.compiling?d[EasyCoder_Compiler.getIndex()].lino:b[b.pc].lino;b=this.compiling?"Compile error":"Runtime error in '"+b.script+"'";b+=":\n";var e=d-5;for(e=0>e?0:e;e')}l+="
"}k.innerHTML=h+" "+l;k.style.display="block";b.$jscomp$loop$prop$run$66=document.getElementById("easycoder-run-button"); -b.$jscomp$loop$prop$step$67=document.getElementById("easycoder-step-button");b.$jscomp$loop$prop$run$66.onclick=function(b){return function(){b.$jscomp$loop$prop$run$66.blur();a.tracing=!1;document.getElementById("easycoder-tracer-content").style.display="none";try{EasyCoder_Run.run(a,a.resume)}catch(p){var c="Error in run handler: "+p.message;console.log(c);alert(c)}}}(b);b.$jscomp$loop$prop$step$67.onclick=function(b){return function(){console.log("step");b.$jscomp$loop$prop$step$67.blur();a.tracing= -!0;document.getElementById("easycoder-tracer-content").style.display="block";try{a.run(a.resume)}catch(p){var c="Error in step handler: "+p.message;console.log(c);alert(c)}}}(b)}a.resume=a.pc;a.pc=0}break}b={$jscomp$loop$prop$run$66:b.$jscomp$loop$prop$run$66,$jscomp$loop$prop$step$67:b.$jscomp$loop$prop$step$67}}},exit:function(a){a.onExit&&a.run(a.onExit);var b=a.parent,c=a.afterExit;delete EasyCoder.scripts[a.script];a.module&&delete a.module.program;Object.keys(a).forEach(function(b){delete a[b]}); -b&&c&&EasyCoder.scripts[b].run(c)}},EasyCoder_Value={name:"EasyCoder_Value",getItem:function(a){var b=a.getToken();if(!b)return null;if("true"===b)return a.next(),{type:"boolean",content:!0};if("false"===b)return a.next(),{type:"boolean",content:!1};if("`"===b.charAt(0))return a.next(),{type:"constant",numeric:!1,content:b.substring(1,b.length-1)};if(b.charAt(0).match(/[0-9-]/)){var c=eval(b);if(Number.isInteger(c))return a.next(),{type:"constant",numeric:!0,content:c};throw Error("'"+b+"' is not an integer"); -}b=a.getIndex();c=$jscomp.makeIterator(Object.keys(a.domain));for(var d=c.next();!d.done;d=c.next())if(d=d.value,a.rewindTo(b),d=a.domain[d].value.compile(a))return d;return null},compile:function(a){var b=a.getToken(),c=EasyCoder_Value.getItem(a);if(!c)throw Error("Undefined value: '"+b+"'");if("cat"===a.getToken()){for(b={type:"cat",numeric:!1,parts:[c]};a.tokenIs("cat");)a.next(),b.parts.push(a.value.getItem(a));return b}return c},doValue:function(a,b){if("undefined"===typeof b.type)return a.runtimeError(a[a.pc].lino, -"Undefined value (variable not initialized?)"),null;switch(b.type){case "cat":return{type:"constant",numeric:!1,content:b.parts.reduce(function(b,c){c=EasyCoder_Value.doValue(a,c);return b+(c?c.content:"")},"")};case "boolean":case "constant":return b;case "symbol":var c=a.getSymbolRecord(b.name);if(c.isVHolder){if(b=c.value[c.index]){c=b.content;if(null===c||"undefined"===typeof c)b.content=b.numeric?0:"";return b}return null}return a.domain[c.domain].value.get(a,b)}return a.domain[b.domain].value.get(a, -b)},constant:function(a,b){return{type:"constant",numeric:b,content:a}},evaluate:function(a,b){if(!b)return{type:"constant",numeric:!1,content:""};var c=EasyCoder_Value.doValue(a,b);if(c)return c;a.runtimeError(a[a.pc].lino,"Can't decode value: "+b)},getValue:function(a,b){return EasyCoder_Value.evaluate(a,b).content},encode:function(a,b){if(a)switch(b){case "ec":return a.replace(/\n/g,"%0a").replace(/\r/g,"%0d").replace(/"/g,"~dq~").replace(/'/g,"~sq~").replace(/\\/g,"~bs~");case "url":return encodeURIComponent(a.replace(/\s/g, -"+"));case "sanitize":return a.normalize("NFD").replace(/[\u0300-\u036f]/g,"")}return a},decode:function(a,b){if(a)switch(b){case "ec":return a.replace(/%0a/g,"\n").replace(/%0d/g,"\r").replace(/~dq~/g,'"').replace(/~sq~/g,"'").replace(/~bs~/g,"\\");case "url":return decodeURIComponent(a).replace(/\+/g," ")}return a}};EasyCoder.version="2.6.1";EasyCoder.timestamp=Date.now();console.log("EasyCoder loaded; waiting for page"); +case "moduleRunning":return c=a.getSymbolRecord(b.name),EasyCoder.scripts.hasOwnProperty(c.program)?(c=EasyCoder.scripts[c.program],b.sense?c.running:!c.running):!b.sense;case "includes":return c=JSON.parse(a.getValue(b.value1)),b=a.getValue(b.value2),c.includes(b)}return!1}}},EasyCoder_Browser={name:"EasyCoder_Browser",A:{compile:function(a){a.compileVariable("browser","a",!1,"dom");return!0},run:function(a){return a[a.pc].pc+1}},Alert:{compile:function(a){var b=a.getLino(),c=a.getNextValue();a.addCommand({domain:"browser", +keyword:"alert",lino:b,value:c});return!0},run:function(a){var b=a[a.pc];a=a.getFormattedValue(b.value);alert(a);return b.pc+1}},Attach:{compile:function(a){var b=a.getLino();a.next();if(a.isSymbol()){var c=a.getSymbolRecord(),d=c.keyword;switch(d){case "a":case "blockquote":case "button":case "canvas":case "div":case "fieldset":case "file":case "form":case "h1":case "h2":case "h3":case "h4":case "h5":case "h6":case "image":case "img":case "input":case "label":case "legend":case "li":case "option":case "p":case "pre":case "select":case "span":case "table":case "td":case "text":case "textarea":case "tr":case "ul":a.next(); +if(a.tokenIs("to")){if(a.nextTokenIs("body"))if("div"===d)cssId="body",a.next();else throw Error("Body variable must be a div");else cssId=a.getValue();var e=0;a.tokenIs("or")&&(a.next(),e=a.getPc()+1,a.completeHandler());a.addCommand({domain:"browser",keyword:"attach",lino:b,type:d,symbol:c.name,cssId:cssId,onError:e});return!0}break;default:return a.addWarning("type '"+c.keyword+"' not recognized in browser 'attach'"),!1}}a.addWarning("Unrecognised syntax in 'attach'");return!1},run:function(a){var b= +a[a.pc],c=null,d=null;"body"===b.cssId?d=document.body:(c=a.value.evaluate(a,b.cssId).content,d=document.getElementById(c));if(!d)return b.onError?a.run(b.onError):a.runtimeError(b.lino,"No such element: '"+c+"'"),0;var e=a.getSymbolRecord(b.symbol);e.element[e.index]=d;e.value[e.index]={type:"constant",numeric:!1,content:c};"popup"===b.type&&(a.popups.push(d.id),window.onclick=function(b){a.popups.includes(b.target.id)&&(b.target.style.display="none")});return b.pc+1}},Audioclip:{compile:function(a){a.compileVariable("browser", +"audioclip");return!0},run:function(a){return a[a.pc].pc+1}},BLOCKQUOTE:{compile:function(a){a.compileVariable("browser","blockquote",!1,"dom");return!0},run:function(a){return a[a.pc].pc+1}},BUTTON:{compile:function(a){a.compileVariable("browser","button",!1,"dom");return!0},run:function(a){return a[a.pc].pc+1}},CANVAS:{compile:function(a){a.compileVariable("browser","canvas",!1,"dom");return!0},run:function(a){return a[a.pc].pc+1}},Clear:{compile:function(a){var b=a.getLino();if(a.nextTokenIs("body"))return a.next(), +a.addCommand({domain:"browser",keyword:"clear",lino:b,name:null}),!0;if(a.isSymbol()){var c=a.getSymbolRecord();if("dom"===c.extra)return a.next(),a.addCommand({domain:"browser",keyword:"clear",lino:b,name:c.name}),!0}return!1},run:function(a){var b=a[a.pc];if(b.name){a=a.getSymbolRecord(b.name);var c=a.element[a.index];switch(a.keyword){case "input":case "textarea":c.value="";break;default:c.innerHTML=""}}else document.body.innerHTML="";return b.pc+1}},Convert:{compile:function(a){var b=a.getLino(); +if(a.nextTokenIs("whitespace")&&a.nextTokenIs("in")&&a.nextIsSymbol()){var c=a.getSymbolRecord();if(c.isVHolder&&a.nextTokenIs("to")){var d=a.nextToken();a.next();a.addCommand({domain:"browser",keyword:"convert",lino:b,name:c.name,mode:d});return!0}}return!1},run:function(a){var b=a[a.pc];a=a.getSymbolRecord(b.name);var c=a.value[a.index].content;switch(b.mode){case "print":c=c.split("%0a").join("\n").split("%0A").join("\n").split("%0d").join("").split("$0D").join("");break;case "html":c=c.split("%0a").join("
").split("%0A").join("
").split("%0d").join("").split("$0D").join("")}a.value[a.index].content= +c;return b.pc+1}},Create:{compile:function(a){var b=a.getLino();if(a.nextIsSymbol()){var c=a.getSymbolRecord(),d=c.keyword;if("audioclip"===d)return a.nextTokenIs("from")?(d=a.getNextValue(),a.addCommand({domain:"browser",keyword:"create",type:"audioclip",name:c.name,lino:b,value:d}),!0):!1;if("a blockquote button canvas div fieldset file form h1 h2 h3 h4 h5 h6 hr image img input label legend li option p pre progress select span table tr td text textarea ul".split(" ").includes(d))if(a.nextTokenIs("in")){if(a.nextTokenIs("body"))return a.next(), +a.addCommand({domain:"browser",keyword:"create",lino:b,name:c.name,parent:"body"}),!0;if(a.isSymbol())return d=a.getSymbolRecord(),a.next(),a.addCommand({domain:"browser",keyword:"create",lino:b,name:c.name,parent:d.name}),!0}else return(d=a.imports)&&0b&&a.onSwipeRight&&a.run(a.onSwipeRight)))},!1);break;case "pick":d=a.getSymbolRecord(b.symbol);document.pickRecord=d;d.element.forEach(function(c, +d){document.pickIndex=d;c.pickIndex=d;c.mouseDownPc=b.pc+2;"ontouchstart"in c?(c.addEventListener("touchstart",function(b){var c=b.targetTouches[0].target;document.pickX=b.touches[0].clientX;document.pickY=b.touches[0].clientY;c.blur();setTimeout(function(){document.pickRecord.index=c.pickIndex;a.run(c.mouseDownPc)},1)},!1),c.addEventListener("touchmove",function(b){document.dragX=b.touches[0].clientX;document.dragY=b.touches[0].clientY;setTimeout(function(){a.run(document.mouseMovePc)},1);return!1}, +!1),c.addEventListener("touchend",function(){setTimeout(function(){a.run(document.mouseUpPc)},1);return!1})):c.onmousedown=function(b){b=b?b:window.event;b.stopPropagation();if(0
', +b.style.display="none";a.tracing=!0}a.stop=!1}return a.pc+1}},UL:{compile:function(a){a.compileVariable("browser","ul",!1,"dom");return!0},run:function(a){return a[a.pc].pc+1}},Upload:{compile:function(a){var b=a.getLino();if(a.nextIsSymbol()){var c=a.getToken();if(a.nextTokenIs("to")){var d=a.getNextValue();if(a.tokenIs("with")&&a.nextIsSymbol()){var e=a.getToken();if(a.nextTokenIs("and")&&a.nextIsSymbol()){var f=a.getToken();a.next();a.addCommand({domain:"browser",keyword:"upload",lino:b,file:c, +path:d,progress:e,status:f});return!0}}}}return!1},run:function(a){var b=a[a.pc],c=a.getSymbolRecord(b.file),d=a.getValue(b.path),e=a.getSymbolRecord(b.progress),f=a.getSymbolRecord(b.status),k=e.element[e.index],g=f.element[f.index],h=function(a){g&&(g.innerHTML=a)};if(e=c.element[c.index].files[0])c=new FormData,c.append("source",e),c.append("path",d),e=new XMLHttpRequest,e.upload.addEventListener("progress",function(a){a=Math.round(a.loaded/a.total*100);k&&(k.value=a);h(Math.round(a)+"%...")}, +!1),e.addEventListener("load",function(a){a=a.target.responseText;k&&(k.value=0);h("");console.log(a)},!1),e.addEventListener("error",function(){h("Upload failed");console.log("Upload failed")},!1),e.addEventListener("abort",function(){h("Upload aborted");console.log("Upload aborted")},!1),e.onreadystatechange=function(){if(4===this.readyState){var b=a.ajaxCommand,c=this.status;switch(c){case 200:a.run(b.pc+1);break;case 0:break;default:try{a.runtimeError(b.lino,"Error "+c)}catch(p){a.reportError(p, +a)}}}},a.ajaxCommand=b,b=d.startsWith("http")?d:window.location.origin+"/"+EasyCoder_Plugins.rest()+"/"+d,e.open("POST",b),e.send(c);return 0}},getHandler:function(a){switch(a){case "a":return EasyCoder_Browser.A;case "alert":return EasyCoder_Browser.Alert;case "attach":return EasyCoder_Browser.Attach;case "audioclip":return EasyCoder_Browser.Audioclip;case "blockquote":return EasyCoder_Browser.BLOCKQUOTE;case "button":return EasyCoder_Browser.BUTTON;case "canvas":return EasyCoder_Browser.CANVAS; +case "clear":return EasyCoder_Browser.Clear;case "convert":return EasyCoder_Browser.Convert;case "create":return EasyCoder_Browser.Create;case "disable":return EasyCoder_Browser.Disable;case "div":return EasyCoder_Browser.DIV;case "enable":return EasyCoder_Browser.Enable;case "fieldset":return EasyCoder_Browser.FIELDSET;case "file":return EasyCoder_Browser.FILE;case "focus":return EasyCoder_Browser.Focus;case "form":return EasyCoder_Browser.FORM;case "fullscreen":return EasyCoder_Browser.FullScreen; +case "get":return EasyCoder_Browser.Get;case "h1":return EasyCoder_Browser.H1;case "h2":return EasyCoder_Browser.H2;case "h3":return EasyCoder_Browser.H3;case "h4":return EasyCoder_Browser.H4;case "h5":return EasyCoder_Browser.H5;case "h6":return EasyCoder_Browser.H6;case "highlight":return EasyCoder_Browser.Highlight;case "history":return EasyCoder_Browser.History;case "hr":return EasyCoder_Browser.HR;case "image":return EasyCoder_Browser.IMAGE;case "img":return EasyCoder_Browser.IMG;case "input":return EasyCoder_Browser.INPUT; +case "label":return EasyCoder_Browser.LABEL;case "legend":return EasyCoder_Browser.LEGEND;case "li":return EasyCoder_Browser.LI;case "location":return EasyCoder_Browser.Location;case "mail":return EasyCoder_Browser.Mail;case "on":return EasyCoder_Browser.On;case "option":return EasyCoder_Browser.OPTION;case "p":return EasyCoder_Browser.P;case "play":return EasyCoder_Browser.Play;case "pre":return EasyCoder_Browser.PRE;case "progress":return EasyCoder_Browser.PROGRESS;case "put":return EasyCoder_Browser.Put; +case "remove":return EasyCoder_Browser.Remove;case "request":return EasyCoder_Browser.Request;case "select":return EasyCoder_Browser.SELECT;case "scroll":return EasyCoder_Browser.Scroll;case "section":return EasyCoder_Browser.SECTION;case "set":return EasyCoder_Browser.Set;case "span":return EasyCoder_Browser.SPAN;case "table":return EasyCoder_Browser.TABLE;case "tr":return EasyCoder_Browser.TR;case "td":return EasyCoder_Browser.TD;case "textarea":return EasyCoder_Browser.TEXTAREA;case "trace":return EasyCoder_Browser.Trace; +case "ul":return EasyCoder_Browser.UL;case "upload":return EasyCoder_Browser.Upload;default:return null}},run:function(a){var b=a[a.pc],c=EasyCoder_Browser.getHandler(b.keyword);c||a.runtimeError(b.lino,"Unknown keyword '"+b.keyword+"' in 'browser' package");return c.run(a)},value:{compile:function(a){if(a.isSymbol()){var b=a.getSymbolRecord();if(a.nextTokenIs("exists"))return"dom"===b.extra?(a.next(),{domain:"browser",type:"exists",value:b.name}):null;switch(b.keyword){case "file":case "input":case "select":case "textarea":return{domain:"browser", +type:b.keyword,value:b.name}}return null}a.tokenIs("the")&&a.next();var c=!1;a.tokenIs("offset")&&(c=!0,a.next());b=a.getToken();switch(b){case "mobile":case "portrait":case "landscape":case "br":case "location":case "key":case "hostname":return a.next(),{domain:"browser",type:b};case "content":case "text":if(a.nextTokenIs("of")){if(a.nextIsSymbol())return b=a.getSymbolRecord(),a.next(),{domain:"browser",type:"contentOf",symbol:b.name};throw Error("'"+a.getToken()+"' is not a symbol");}break;case "selected":b= +a.nextToken();if(["index","item"].includes(b)&&["in","of"].includes(a.nextToken())&&a.nextIsSymbol()&&(c=a.getSymbolRecord(),["ul","ol","select"].includes(c.keyword)))return a.next(),{domain:"browser",type:"selected",symbol:c.name,arg:b};break;case "color":return a.next(),a=a.getValue(),{domain:"browser",type:b,value:a};case "attribute":c=a.getNextValue();if(a.tokenIs("of")&&(a.next(),a.isSymbol()&&(b=a.getSymbolRecord(),"dom"===b.extra)))return a.next(),{domain:"browser",type:"attributeOf",attribute:c, +symbol:b.name};break;case "style":c=a.getNextValue();if(a.tokenIs("of")&&a.nextIsSymbol()){var d=a.getSymbolRecord();if("dom"===d.extra)return a.next(),{domain:"browser",type:b,style:c,target:d.name}}break;case "confirm":return b=a.getNextValue(),{domain:"browser",type:"confirm",text:b};case "prompt":return b=a.getNextValue(),c=null,a.tokenIs("with")&&(c=a.getNextValue()),{domain:"browser",type:"prompt",text:b,pre:c};case "screen":c=a.nextToken();if(["width","height"].includes(c))return a.next(), +{domain:"browser",type:b,attribute:c};break;case "top":case "bottom":case "left":case "right":case "width":case "height":return EasyCoder_Browser.value.getCoord(a,b,c);case "scroll":if(a.nextTokenIs("position"))return a.next(),{domain:"browser",type:"scrollPosition"};break;case "document":if(a.nextTokenIs("path"))return a.next(),{domain:"browser",type:"docPath"};break;case "storage":if(a.nextTokenIs("keys"))return a.next(),{domain:"browser",type:"storageKeys"};break;case "parent":switch(a.nextToken()){case "name":return a.next(), +{domain:"browser",type:"varName"};case "index":return a.next(),{domain:"browser",type:"varIndex"}}break;case "history":if(a.nextTokenIs("state"))return a.next(),{domain:"browser",type:"historyState"};break;case "pick":case "drag":if(a.nextTokenIs("position"))return a.next(),{domain:"browser",type:b+"Position"}}return null},getCoord:function(a,b,c){if(a.nextTokenIs("of")){if(a.nextTokenIs("window"))return a.next(),{domain:"browser",type:b,symbol:"window",offset:c};if(a.isSymbol()){var d=a.getSymbolRecord(); +if("dom"===d.extra)return a.next(),{domain:"browser",type:b,symbol:d.name,offset:c}}}return null},get:function(a,b){switch(b.type){case "file":case "input":case "select":case "textarea":var c=a.getSymbolRecord(b.value);var d=c.element[c.index];return{type:"constant",numeric:!1,content:d.value};case "exists":return c=a.getSymbolRecord(b.value),{domain:"browser",type:"boolean",content:"undefined"!==typeof c.element[c.index]};case "mobile":return{domain:"browser",type:"boolean",content:"undefined"!== +typeof window.orientation||-1!==navigator.userAgent.indexOf("IEMobile")};case "portrait":return{domain:"browser",type:"boolean",content:document.documentElement.clientWidth=document.documentElement.clientHeight};case "br":return{type:"constant",numeric:!1,content:decodeURIComponent("%3Cbr%20%2F%3E")};case "attributeOf":return c=a.getSymbolRecord(b.symbol),b= +a.getValue(b.attribute),d=c.element[c.index],0===b.indexOf("data-")?a.getSimpleValue(d.dataset[b.substr(5)]):a.getSimpleValue(d[b]);case "style":return c=a.getSymbolRecord(b.target),b=a.getValue(b.style),d=c.element[c.index],a.getSimpleValue(d.style[b]);case "confirm":return{type:"boolean",content:window.confirm(a.getValue(b.text))};case "prompt":return d=a.getValue(b.text),b=a.getValue(b.pre),{type:"constant",numeric:!1,content:b?window.prompt(d,b):window.prompt(d)};case "contentOf":c=a.getSymbolRecord(b.symbol); +d=c.element[c.index];switch(c.keyword){case "input":case "textarea":b=d.value;break;case "pre":b=d.innerHTML;break;default:b=d.innerHTML.split("\n").join("")}return{type:"constant",numeric:!1,content:b};case "selected":return c=a.getSymbolRecord(b.symbol),d=c.element[c.index],a=d.selectedIndex,d=0<=a?d.options[a].text:"",b="index"===b.arg?a:d,{type:"constant",numeric:!1,content:b};case "top":if("window"==b.symbol)return{type:"constant",numeric:!0,content:window.screenY};c=a.getSymbolRecord(b.symbol); +a=c.element[c.index];b=Math.round(b.offset?a.offsetTop:a.getBoundingClientRect().top);return{type:"constant",numeric:!0,content:b};case "bottom":if("window"==b.symbol)return{type:"constant",numeric:!0,content:window.screenY+window.innerHeight};c=a.getSymbolRecord(b.symbol);b=Math.round(c.element[c.index].getBoundingClientRect().bottom);return{type:"constant",numeric:!0,content:b};case "left":if("window"==b.symbol)return{type:"constant",numeric:!0,content:window.screenLeft};c=a.getSymbolRecord(b.symbol); +a=c.element[c.index];b=Math.round(b.offset?a.offsetLeft:a.getBoundingClientRect().left);return{type:"constant",numeric:!0,content:b};case "right":if("window"==b.symbol)return{type:"constant",numeric:!0,content:window.screenX+window.innerWidth};c=a.getSymbolRecord(b.symbol);b=Math.round(c.element[c.index].getBoundingClientRect().right);return{type:"constant",numeric:!0,content:b};case "width":if("window"==b.symbol)return{type:"constant",numeric:!0,content:window.innerWidth};c=a.getSymbolRecord(b.symbol); +b=Math.round(c.element[c.index].getBoundingClientRect().width);return{type:"constant",numeric:!0,content:b};case "height":if("window"==b.symbol)return{type:"constant",numeric:!0,content:window.innerHeight};c=a.getSymbolRecord(b.symbol);b=Math.round(c.element[c.index].getBoundingClientRect().height);return{type:"constant",numeric:!0,content:b};case "color":return{type:"constant",numeric:!1,content:"#"+a.value.evaluate(a,b.value).content.toString(16).padStart(6,"0")};case "docPath":return{type:"constant", +numeric:!1,content:a.docPath};case "storageKeys":return{type:"constant",numeric:!1,content:JSON.stringify(Object.keys(localStorage))};case "location":return{type:"constant",numeric:!1,content:window.location.href};case "historyState":return{type:"constant",numeric:!1,content:window.history.state};case "scrollPosition":return{type:"constant",numeric:!0,content:scrollPosition};case "varName":return{type:"constant",numeric:!1,content:a.varName};case "varIndex":return{type:"constant",numeric:!0,content:a.varIndex}; +case "key":return{type:"constant",numeric:!1,content:a.key};case "hostname":return{type:"constant",numeric:!1,content:location.hostname};case "screen":return{type:"constant",numeric:!0,content:screen[b.attribute]};case "pickPosition":return{type:"constant",numeric:!1,content:JSON.stringify({x:document.pickX,y:document.pickY})};case "dragPosition":return{type:"constant",numeric:!1,content:JSON.stringify({x:document.dragX,y:document.dragY})}}}},condition:{compile:function(a){if(a.tokenIs("confirm"))return{domain:"browser", +type:"confirm",value:a.getNextValue()};if(a.tokenIs("element")&&a.nextIsSymbol()){var b=a.getSymbolRecord();if("dom"===b.extra){var c=a.nextToken();if("has"===c){if(a.nextTokenIs("the")&&a.next(),a.tokenIs("focus"))return a.next(),{domain:"browser",type:"focus",element:b.name}}else if("contains"===c)return a=a.getNextValue(),{domain:"browser",type:"contains",element:b.name,position:a}}}return null},test:function(a,b){switch(b.type){case "confirm":return confirm(a.getValue(b.value));case "focus":var c= +a.getSymbolRecord(b.element);return c.element[c.index]===document.activeElement;case "contains":c=a.getSymbolRecord(b.element);var d=c.element[c.index].getBoundingClientRect();c=Math.round(d.left);var e=Math.round(d.right),f=Math.round(d.top);d=Math.round(d.bottom);b=JSON.parse(a.getValue(b.position));a=b.x;b=b.y;return a>=c&&a<=e&&b>=f&&b<=d?!0:!1}}},setStyles:function(a,b){a=document.getElementById(a);b=b.split(";");b=$jscomp.makeIterator(b);for(var c=b.next();!c.done;c=b.next())c=c.value.split(":"), +a.setAttribute(c[0],c[1])}},scrollPosition=0;window.addEventListener("scroll",function(){scrollPosition=this.scrollY});window.onpopstate=function(a){window.EasyCoder.timestamp=Date.now();(a=JSON.parse(a.state))&&a.script&&((a=window.EasyCoder.scripts[a.script])?a.onBrowserBack&&a.run(a.onBrowserBack):console.log("No script property in window state object"))}; +var EasyCoder_Json={name:"EasyCoder_JSON",Json:{compile:function(a){var b=a.getLino(),c=a.nextToken();switch(c){case "set":a.next();if(a.isSymbol())if(c=a.getSymbolRecord(),"variable"===c.keyword){if(a.nextTokenIs("to")){var d=a.nextToken();if('["array","object"]'.includes(d))return a.next(),a.addCommand({domain:"json",keyword:"json",lino:b,request:"setVariable",target:c.name,type:d}),!0}}else if("select"===c.keyword&&a.nextTokenIs("from")&&(a.next(),a.isSymbol()&&(d=a.getSymbolRecord(),"variable"=== +d.keyword))){var e=null;a.nextTokenIs("as")&&(e=a.getNextValue());a.addCommand({domain:"json",keyword:"json",lino:b,request:"setList",target:c.name,source:d.name,display:e});return!0}break;case "sort":case "shuffle":case "format":if(a.nextIsSymbol()&&(d=a.getSymbolRecord(),"variable"===d.keyword))return a.next(),a.addCommand({domain:"json",keyword:"json",lino:b,request:c,target:d.name}),!0;break;case "parse":if(a.nextTokenIs("url")&&(d=a.getNextValue(),a.tokenIs("as")&&a.nextIsSymbol()&&(e=a.getSymbolRecord(), +"variable"===e.keyword)))return a.next(),a.addCommand({domain:"json",keyword:"json",lino:b,request:c,source:d,target:e.name}),!0;break;case "delete":d=a.nextToken();if(["property","element"].includes(d)&&(e=a.getNextValue(),["from","of"].includes(a.getToken())&&a.nextIsSymbol())){var f=a.getSymbolRecord();if("variable"===f.keyword)return a.next(),a.addCommand({domain:"json",keyword:"json",lino:b,request:c,what:d,value:e,target:f.name}),!0}break;case "rename":d=a.getNextValue();if(a.tokenIs("to")&& +(e=a.getNextValue(),a.tokenIs("in")&&a.nextIsSymbol()&&(f=a.getSymbolRecord(),"variable"===f.keyword)))return a.next(),a.addCommand({domain:"json",keyword:"json",lino:b,request:c,oldName:d,newName:e,target:f.name}),!0;break;case "add":d=a.getNextValue();if(a.tokenIs("to")&&a.nextIsSymbol()&&(e=a.getSymbolRecord(),"variable"===e.keyword))return a.next(),a.addCommand({domain:"json",keyword:"json",lino:b,request:c,item:d,target:e.name}),!0;break;case "split":d=a.getNextValue();e="\n";a.tokenIs("on")&& +(e=a.getNextValue());if(["giving","into"].includes(a.getToken())&&a.nextIsSymbol()&&(f=a.getSymbolRecord(),"variable"===f.keyword))return a.next(),a.addCommand({domain:"json",keyword:"json",lino:b,request:c,item:d,on:e,target:f.name}),!0;break;case "replace":if(a.nextTokenIs("element")&&(d=a.getNextValue(),a.tokenIs("of")&&a.nextIsSymbol()&&(e=a.getSymbolRecord(),"variable"===e.keyword&&["by","with"].includes(a.nextToken()))))return f=a.getNextValue(),a.addCommand({domain:"json",keyword:"json",lino:b, +request:c,target:e.name,index:d,value:f}),!0}a.addWarning("Unrecognised json command syntax");return!1},run:function(a){var b=a[a.pc];switch(b.request){case "setVariable":var c=a.getSymbolRecord(b.target);var d="array"===b.type?"[]":"{}";c.value[c.index]={type:"constant",numeric:!1,content:d};break;case "setList":c=a.getSymbolRecord(b.source);c=a.getValue(c.value[c.index]);var e="";try{e=JSON.parse(c)}catch(l){return a.runtimeError(b.lino,"Can't parse JSON"),0}c=a.getSymbolRecord(b.target);var f= +c.element[c.index];f.options.length=0;var k=a.getValue(b.display);e.forEach(function(b){var c=k?a.decode(b[k]):null,d=document.createElement("option");d.innerHTML=c?c:b;b=c?JSON.stringify(b):b;d.value=b;f.appendChild(d)});f.selectedIndex=-1;break;case "sort":c=a.getSymbolRecord(b.target);d=(e=a.getValue(c.value[c.index]))?JSON.stringify(JSON.parse(e).sort()):null;c.value[c.index]={type:"constant",numeric:!1,content:d};break;case "shuffle":c=a.getSymbolRecord(b.target);e=JSON.parse(a.getValue(c.value[c.index])); +for(d=e.length-1;0e.length-1&&a.runtimeError(b.lino,"Index out of range"),e[d]=g, +c.value[c.index].content=JSON.stringify(e)}return b.pc+1}},getHandler:function(a){switch(a){case "json":return EasyCoder_Json.Json;default:return null}},run:function(a){var b=a[a.pc],c=EasyCoder_Json.getHandler(b.keyword);c||a.runtimeError(b.lino,"Unknown keyword '"+b.keyword+"' in 'json' package");return c.run(a)},value:{compile:function(a){a.tokenIs("the")&&a.next();if(a.tokenIs("json")){var b=a.nextToken();if(["size","count","keys"].includes(b)){if(a.skip("of"),a.isSymbol()){var c=a.getSymbolRecord(); +a.next();if(c.isVHolder)return{domain:"json",type:b,name:c.name}}}else if("index"===b&&a.nextTokenIs("of")&&(c=a.getNextValue(),a.tokenIs("in")))return a=a.getNextValue(),{domain:"json",type:b,item:c,list:a}}return null},get:function(a,b){switch(b.type){case "size":case "count":b=a.getSymbolRecord(b.name);a=a.getValue(b.value[b.index]);try{var c=JSON.parse(a)}catch(e){c=[]}return{type:"constant",numeric:!0,content:c?c.length:0};case "keys":return b=a.getSymbolRecord(b.name),c=(a=a.getValue(b.value[b.index]))? +JSON.stringify(Object.keys(JSON.parse(a)).sort()):"[]",{type:"constant",numeric:!1,content:c};case "index":var d=a.getValue(b.item);c=JSON.parse(a.getValue(b.list)).findIndex(function(a){return a===d});return{type:"constant",numeric:!0,content:c}}}},condition:{compile:function(){},test:function(){}}},EasyCoder_Rest={name:"EasyCoder_Rest",Rest:{compile:function(a){var b=a.getLino();switch(a.nextToken()){case "get":if(a.nextIsSymbol(!0)){var c=a.getSymbolRecord();if("variable"===c.keyword&&a.nextTokenIs("from")){var d= +a.getNextValue(),e=a.getPc();a.addCommand({domain:"rest",keyword:"rest",lino:b,request:"get",target:c.name,url:d,onError:null});a.tokenIs("or")&&(a.next(),a.getCommandAt(e).onError=a.getPc()+1,a.completeHandler());return!0}}break;case "post":c=null;if(a.nextTokenIs("to"))a.next();else if(c=a.getValue(),a.tokenIs("to"))a.next();else break;d=a.getValue();if(!d)throw Error(command.lino,"No URL present");e=null;if(a.tokenIs("giving")&&a.nextIsSymbol())if(e=a.getSymbolRecord(),e.isVHolder)e=e.name,a.next(); +else throw Error("'"+e.name+"' cannot hold a value");a.addCommand({domain:"rest",keyword:"rest",lino:b,request:"post",value:c,url:d,target:e,onError:a.getPc()+2});onError=null;a.tokenIs("or")&&(a.next(),a.completeHandler());return!0}return!1},createCORSRequest:function(a,b){var c=new XMLHttpRequest;"withCredentials"in c?c.open(a,b,!0):"undefined"!=typeof XDomainRequest?(c=new XDomainRequest,c.open(a,b)):c=null;return c},run:function(a){var b=a[a.pc],c=a.getValue(b.url),d=EasyCoder_Plugins.rest(); +c=c.startsWith("http")?c:"/"===c[0]?c.substr(1):""+window.location.origin+(d?"/"+d:"")+"/"+c;var e=EasyCoder_Rest.Rest.createCORSRequest(b.request,c);if(e){e.script=a.script;e.pc=a.pc;e.onload=function(){var c=EasyCoder.scripts[e.script],d=c[e.pc];if(200<=e.status&&400>e.status){var g=e.responseText.trim();if(d.target){var h=a.getSymbolRecord(b.target);h.value[h.index]={type:"constant",numeric:!1,content:g};h.used=!0}c.run(d.pc+1)}else g=e.status+" "+e.statusText,d.onError?(c.errorMessage="Exception trapped: "+ +g,c.run(d.onError)):c.runtimeError(d.lino,"Error: "+g)};e.onerror=function(){b.onError?(a.errorMessage=this.responseText,a.run(b.onError)):a.runtimeError(b.lino,this.responseText)};switch(b.request){case "get":e.send();break;case "post":d=a.getValue(b.value),console.log("POST to "+c),e.setRequestHeader("Content-type","application/json; charset=UTF-8"),e.send(d)}return 0}a.runtimeError(b.lino,"CORS not supported")}},getHandler:function(a){switch(a){case "rest":return EasyCoder_Rest.Rest;default:return null}}, +run:function(a){var b=a[a.pc],c=EasyCoder_Rest.getHandler(b.keyword);c||a.runtimeError(b.lino,"Unknown keyword '"+b.keyword+"' in 'rest' package");return c.run(a)},value:{compile:function(){return null},get:function(){return null}},condition:{compile:function(){},test:function(){}}},EasyCoder_Compare=function(a,b,c){b=a.value.evaluate(a,b);a=a.value.evaluate(a,c);c=b.content;var d=a.content;c&&b.numeric?a.numeric||(d=""===d||"-"===d||"undefined"===typeof d?0:parseInt(d)):(d&&a.numeric&&(d=d.toString()), +"undefined"===typeof c&&(c=""),"undefined"===typeof d&&(d=""));return c>d?1:c')}l+="
"}g.innerHTML=h+" "+l;g.style.display="block";b.$jscomp$loop$prop$run$144=document.getElementById("easycoder-run-button");b.$jscomp$loop$prop$step$145=document.getElementById("easycoder-step-button"); +b.$jscomp$loop$prop$run$144.onclick=function(b){return function(){b.$jscomp$loop$prop$run$144.blur();a.tracing=!1;document.getElementById("easycoder-tracer-content").style.display="none";try{EasyCoder_Run.run(a,a.resume)}catch(q){var c="Error in run handler: "+q.message;console.log(c);alert(c)}}}(b);b.$jscomp$loop$prop$step$145.onclick=function(b){return function(){console.log("step");b.$jscomp$loop$prop$step$145.blur();a.tracing=!0;document.getElementById("easycoder-tracer-content").style.display= +"block";try{a.run(a.resume)}catch(q){var c="Error in step handler: "+q.message;console.log(c);alert(c)}}}(b)}a.resume=a.pc;a.pc=0}break}b={$jscomp$loop$prop$run$144:b.$jscomp$loop$prop$run$144,$jscomp$loop$prop$step$145:b.$jscomp$loop$prop$step$145}}},exit:function(a){a.onExit&&a.run(a.onExit);var b=a.parent,c=a.afterExit;delete EasyCoder.scripts[a.script];a.module&&delete a.module.program;Object.keys(a).forEach(function(b){delete a[b]});b&&c&&EasyCoder.scripts[b].run(c)}},EasyCoder_Compiler={name:"EasyCoder_Compiler", +getTokens:function(){return this.tokens},addWarning:function(a){this.warnings.push(a)},warning:function(a){this.addWarning(a)},unrecognisedSymbol:function(a){this.addWarning("Unrecognised symbol '"+a+"'")},getWarnings:function(){return this.warnings},getIndex:function(){return this.index},next:function(a){this.index+=void 0===a?1:a},peek:function(){return this.tokens[this.index+1].token},more:function(){return this.index=this.tokens.length? +null:this.tokens[this.index]?this.tokens[this.index].token:null},nextToken:function(){this.next();return this.getToken()},tokenIs:function(a){return this.index>=this.tokens.length?!1:a===this.tokens[this.index].token},nextTokenIs:function(a){this.next();return this.tokenIs(a)},skip:function(a){if(this.index>=this.tokens.length)return null;this.next();this.tokenIs(a)&&this.next()},prev:function(){this.index--},getLino:function(){return this.index>=this.tokens.length?0:this.tokens[this.index].lino}, +getTarget:function(a){a=void 0===a?this.index:a;return this.tokens[a].token},getTargetPc:function(a){a=void 0===a?this.index:a;return this.symbols[this.getTarget(a)].pc},getCommandAt:function(a){return this.program[a]},isSymbol:function(a){a=void 0===a?!1:a;if(this.getTarget()in this.symbols)return!0;if(a)throw Error("Unknown symbol: '"+this.getTarget()+"'");return!1},nextIsSymbol:function(a){a=void 0===a?!1:a;this.next();return this.isSymbol(a)},getSymbol:function(a){if(this.isSymbol(void 0===a? +!1:a))return this.symbols[this.getToken()]},getSymbolPc:function(a){return this.getSymbol(void 0===a?!1:a).pc},getSymbolRecord:function(){var a=this.program[this.getSymbolPc(!0)];a.used=!0;return a},getSymbols:function(){return this.symbols},getProgram:function(){return this.program},getPc:function(){return this.program.length},getValue:function(){return this.value.compile(this)},getNextValue:function(){this.next();return this.getValue()},getCondition:function(){return this.condition.compile(this)}, +constant:function(a,b){return this.value.constant(a,void 0===b?!1:b)},addCommand:function(a){this.program.push(Object.assign({},{pc:this.program.length},a))},addSymbol:function(a,b){this.symbols[a]={pc:b}},mark:function(){this.savedMark=this.index},rewind:function(){this.index=this.savedMark},rewindTo:function(a){this.index=a},completeHandler:function(){var a=this.getLino(),b=this.getPc();this.addCommand({domain:"core",keyword:"goto",lino:a,goto:0});this.compileOne();this.continue?(this.addCommand({domain:"core", +keyword:"goto",lino:a,goto:this.getPc()+1}),this.continue=!1):this.addCommand({domain:"core",keyword:"stop",lino:a,next:0});this.getCommandAt(b).goto=this.getPc();return!0},compileVariable:function(a,b,c,d){c=void 0===c?!1:c;d=void 0===d?null:d;this.next();var e=this.getLino(),f=this.getTokens()[this.getIndex()];if(this.symbols[f.token])throw Error("Duplicate variable name '"+f.token+"'");var k=this.getPc();this.next();this.addSymbol(f.token,k);a={domain:a,keyword:b,lino:e,isSymbol:!0,used:!1,isVHolder:c, +name:f.token,elements:1,index:0,value:[{}],element:[],extra:d};"dom"===d&&(a.element=[]);this.addCommand(a);return a},compileToken:function(){var a=this.getToken();if(a){this.mark();for(var b=$jscomp.makeIterator(Object.keys(this.domain)),c=b.next();!c.done;c=b.next()){if((c=this.domain[c.value])&&(c=c.getHandler(a))&&c.compile(this))return;this.rewind()}console.log("No handler found");throw Error("I don't understand '"+a+"...'");}},compileOne:function(){var a=this.getToken();if(a){this.warnings= +[];var b=this.program.length;if(a.endsWith(":")){a=a.substring(0,a.length-1);if(this.symbols[a])throw Error("Duplicate symbol: '"+a+"'");this.symbols[a]={pc:b};this.index++}else this.compileToken()}},compileFromHere:function(a){for(;this.indexe?0:e;e { +const EasyCoder_Core = { - const val1 = program.value.evaluate(program, value1); - const val2 = program.value.evaluate(program, value2); - var v1 = val1.content; - var v2 = val2.content; - if (v1 && val1.numeric) { - if (!val2.numeric) { - v2 = (v2 === `` || v2 === `-` || typeof v2 === `undefined`) ? 0 : parseInt(v2); - } - } else { - if (v2 && val2.numeric) { - v2 = v2.toString(); - } - if (typeof v1 === `undefined`) { - v1 = ``; - } - if (typeof v2 === `undefined`) { - v2 = ``; - } - } - if (v1 > v2) { - return 1; - } - if (v1 < v2) { - return -1; - } - return 0; -}; -// eslint-disable-next-line no-unused-vars -const EasyCoder_Compiler = { + name: `EasyCoder_Core`, - name: `EasyCoder_Compiler`, + Add: { - getTokens: function() { - return this.tokens; - }, + compile: compiler => { + const lino = compiler.getLino(); + compiler.next(); + // Get the (first) value + const value1 = compiler.getValue(); + if (compiler.tokenIs(`to`)) { + compiler.next(); + // Check if a value holder is next + if (compiler.isSymbol()) { + const symbol = compiler.getSymbol(); + const variable = compiler.getCommandAt(symbol.pc); + if (variable.isVHolder) { + if (compiler.peek() === `giving`) { + // This variable must be treated as a second value + const value2 = compiler.getValue(); + compiler.next(); + const target = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `add`, + lino, + value1, + value2, + target + }); + } else { + // Here the variable is the target. + const target = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `add`, + lino, + value1, + target + }); + } + return true; + } + compiler.warning(`core 'add': Expected value holder`); + } else { + // Here we have 2 values so 'giving' must come next + const value2 = compiler.getValue(); + if (compiler.tokenIs(`giving`)) { + compiler.next(); + const target = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `add`, + lino, + value1, + value2, + target + }); + return true; + } + compiler.warning(`core 'add'': Expected "giving"`); + } + } + return false; + }, - addWarning: function(message) { - this.warnings.push(message); - }, + // runtime - warning: function(message) { - this.addWarning(message); + run: program => { + const command = program[program.pc]; + const value1 = command.value1; + const value2 = command.value2; + const target = program.getSymbolRecord(command.target); + if (target.isVHolder) { + const value = target.value[target.index]; + if (value2) { + const result = program.getValue(value2) + + program.getValue(value1); + target.value[target.index] = { + type: `constant`, + numeric: true, + content: result + }; + } else { + if (!value.numeric && isNaN(value.content)) { + program.nonNumericValueError(command.lino); + } + const result = parseInt(value.content) + parseInt(program.getValue(value1)); + target.value[target.index] = { + type: `constant`, + numeric: true, + content: result + }; + } + } else { + program.variableDoesNotHoldAValueError(command.lino, target.name); + } + return command.pc + 1; + } }, - unrecognisedSymbol: function(item) { - this.addWarning(`Unrecognised symbol '${item}'`); - }, + Alias: { - getWarnings: function() { - return this.warnings; - }, + compile: compiler => { + const lino = compiler.getLino(); + compiler.next(); + if (compiler.isSymbol()) { + const alias = compiler.getToken(); + compiler.next(); + if (compiler.tokenIs(`to`)) { + compiler.next(); + if (compiler.isSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + symbolRecord.used = true; + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `alias`, + lino, + alias, + symbol: symbolRecord.name + }); + return true; + } + } + } + return false; + }, - getIndex: function() { - return this.index; + run: program => { + const command = program[program.pc]; + const aliasPc = program.symbols[command.alias].pc; + const aliasRecord = program[aliasPc]; + const symbolRecord = program.getSymbolRecord(command.symbol); + program[aliasPc] = { + pc: aliasRecord.pc, + domain: symbolRecord.domain, + keyword: symbolRecord.keyword, + lino: aliasRecord.lino, + name: aliasRecord.name, + alias: command.symbol + }; + return command.pc + 1; + } }, - next: function(step = 1) { - this.index = this.index + step; - }, + Append: { - peek: function() { - return this.tokens[this.index + 1].token; - }, + compile: compiler => { + const lino = compiler.getLino(); + const value = compiler.getNextValue(); + if (compiler.tokenIs(`to`)) { + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.isVHolder) { + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `append`, + lino, + value, + select: symbolRecord.name + }); + return true; + } + } + } + return false; + }, - more: function() { - return this.index < this.tokens.length; + run: program => { + const command = program[program.pc]; + const array = program.getSymbolRecord(command.select); + try { + const v = program.getValue(command.value); + const value = [`{`, `[`].includes(v[0]) ? JSON.parse(v) : v; + const item = array.value[array.index]; + let a = item.content; + if (a) { + a = JSON.parse(a); + } else { + a = []; + } + a.push(value); + item.content = JSON.stringify(a); + return command.pc + 1; + } catch (err) { + program.runtimeError(command.lino, `JSON: Unable to parse value`); + return false; + } + } }, - getToken: function() { - if (this.index >= this.tokens.length) { - return null; + Begin: { + + compile: compiler => { + compiler.next(); + compiler.compileFromHere([`end`]); + return true; + }, + + run: program => { + return program[program.pc].pc + 1; } - const item = this.tokens[this.index]; - return item ? this.tokens[this.index].token : null; }, - nextToken: function() { - this.next(); - return this.getToken(); - }, - - tokenIs: function(token) { - if (this.index >= this.tokens.length) { - return false; - } - return token === this.tokens[this.index].token; - }, + Callback: { - nextTokenIs: function(token) { - this.next(); - return this.tokenIs(token); - }, + compile: compiler => { + compiler.compileVariable(`core`, `callback`); + return true; + }, - skip: function(token) { - if (this.index >= this.tokens.length) { - return null; - } - this.next(); - if (this.tokenIs(token)) { - this.next(); + run: program => { + return program[program.pc].pc + 1; } }, - prev: function() { - this.index--; - }, + Clear: { - getLino: function() { - if (this.index >= this.tokens.length) { - return 0; - } - return this.tokens[this.index].lino; - }, + compile: compiler => { + const lino = compiler.getLino(); + compiler.next(); + if (compiler.isSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.isVHolder) { + const symbol = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `clear`, + lino, + symbol + }); + return true; + } + compiler.warning(`'Variable '${symbolRecord.name}' does not hold a value`); + } + return false; + }, - getTarget: function(index = this.index) { - return this.tokens[index].token; + run: program => { + const command = program[program.pc]; + const symbol = program.getSymbolRecord(command.symbol); + if (symbol.isVHolder) { + const handler = program.domain[symbol.domain]; + handler.value.put(symbol, { + type: `boolean`, + content: false + }); + command.numeric = false; + } else { + program.variableDoesNotHoldAValueError(command.lino, symbol.name); + } + return command.pc + 1; + } }, - getTargetPc: function(index = this.index) { - return this.symbols[this.getTarget(index)].pc; - }, + Close: { - getCommandAt: function(pc) { - return this.program[pc]; - }, + compile: compiler => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const moduleRecord = compiler.getSymbolRecord(); + if (moduleRecord.keyword === `module`) { + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `close`, + lino, + module: moduleRecord.name + }); + return true; + } + } + return false; + }, - isSymbol: function(required = false) { - const isSymbol = this.getTarget() in this.symbols; - if (isSymbol) return true; - if (required) { - throw new Error(`Unknown symbol: '${this.getTarget()}'`); + run: program => { + const command = program[program.pc]; + const moduleRecord = program.getSymbolRecord(command.module); + const p = EasyCoder.scripts[moduleRecord.program]; + p.run(p.onClose); + return command.pc + 1; } - return false; }, - nextIsSymbol: function(required = false) { - this.next(); - return this.isSymbol(required); - }, + Continue: { - getSymbol: function(required = false) { - if (this.isSymbol(required)) { - return this.symbols[this.getToken()]; + compile: compiler => { + compiler.next(); + compiler.continue = true; + return true; } }, - getSymbolPc: function(required = false) { - return this.getSymbol(required).pc; - }, + Debug: { - getSymbolRecord: function() { - const record = this.program[this.getSymbolPc(true)]; - record.used = true; - return record; - }, + compile: compiler => { + const lino = compiler.getLino(); + if (compiler.nextTokenIs(`program`)) { + compiler.next(); + if ([`item`, `pc`].includes(compiler.getToken())) { + const item = compiler.getNextValue(); + compiler.addCommand({ + domain: `core`, + keyword: `debug`, + lino, + item + }); + return true; + } + compiler.addCommand({ + domain: `core`, + keyword: `debug`, + lino, + item: `program` + }); + return true; + } else if (compiler.tokenIs(`symbols`)) { + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `debug`, + lino, + item: `symbols` + }); + return true; + } else if (compiler.tokenIs(`symbol`)) { + const name = compiler.nextToken(); + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `debug`, + lino, + item: `symbol`, + name + }); + return true; + } else if (compiler.tokenIs(`step`)) { + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `debug`, + lino, + item: `step` + }); + return true; + } + return false; + }, - getSymbols: function() { - return this.symbols; + run: program => { + const command = program[program.pc]; + const item = command.item; + switch (item) { + case `symbols`: + console.log(`Symbols: ${JSON.stringify(program.symbols, null, 2)}`); + break; + case `symbol`: + const record = program.getSymbolRecord(command.name); + const exporter = record.exporter.script; + delete record.exporter; + console.log(`Symbol: ${JSON.stringify(record, null, 2)}`); + record.exporter.script = exporter; + break; + case `step`: + program.debugStep = true; + break; + case `program`: + console.log(`Debug program: ${JSON.stringify(program, null, 2)}`); + break; + default: + if (item.content >= 0) { + console.log(`Debug item ${item.content}: ${JSON.stringify(program[item.content], null, 2)}`); + } + break; + } + return command.pc + 1; + } }, - getProgram: function() { - return this.program; - }, + Decode: { - getPc: function() { - return this.program.length; - }, + compile: compiler => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const symbol = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `decode`, + lino, + symbol + }); + return true; + } + return false; + }, - getValue: function() { - return this.value.compile(this); + run: program => { + const command = program[program.pc]; + const target = program.getSymbolRecord(command.symbol); + if (target.isVHolder) { + const content = program.getValue(target.value[target.index]); + target.value[target.index] = { + type: `constant`, + numeric: false, + content: program.decode(content) + }; + command.numeric = false; + } else { + program.variableDoesNotHoldAValueError(command.lino, target.name); + } + return command.pc + 1; + } }, - getNextValue: function() { - this.next(); - return this.getValue(); - }, + Divide: { - getCondition: function() { - return this.condition.compile(this); - }, + compile: compiler => { + const lino = compiler.getLino(); + var target; + if (compiler.nextIsSymbol()) { + // It may be the target + const symbol = compiler.getSymbol(); + target = compiler.getCommandAt(symbol.pc).name; + } + // Get the value even if we have a target + const value1 = compiler.getValue(); + if (compiler.tokenIs(`by`)) { + compiler.next(); + } + // The next item is always a value + const value2 = compiler.getValue(); + // If we now have 'giving' then the target follows + if (compiler.tokenIs(`giving`)) { + compiler.next(); + // Get the target + if (compiler.isSymbol()) { + const symbol = compiler.getSymbol(); + target = compiler.getCommandAt(symbol.pc).name; + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `divide`, + lino, + value1, + value2, + target + }); + return true; + } + compiler.warning(`core 'divide'': Expected value holder`); + } else { + // Here we should already have the target. + if (typeof target === `undefined`) { + compiler.warning(`core 'divide': No target variable given`); + } + compiler.addCommand({ + domain: `core`, + keyword: `divide`, + lino, + value2, + target + }); + return true; + } + return false; + }, - constant: function(content, numeric = false) { - return this.value.constant(content, numeric); + run: program => { + const command = program[program.pc]; + const value1 = command.value1; + const value2 = command.value2; + const target = program.getSymbolRecord(command.target); + if (target.isVHolder) { + const value = target.value[target.index]; + if (value1) { + const result = program.getValue(value1) / program.getValue(value2); + target.value[target.index] = { + type: `constant`, + numeric: true, + content: Math.trunc(result) + }; + } else { + if (!value.numeric && isNaN(value.content)) { + program.nonNumericValueError(command, lino); + } + const result = parseInt(value.content) / parseInt(program.getValue(value2)); + target.value[target.index] = { + type: `constant`, + numeric: true, + content: Math.trunc(result) + }; + } + } else { + program.variableDoesNotHoldAValueError(command.lino, target.name); + } + return command.pc + 1; + } }, - addCommand: function(item) { - const pc = this.program.length; - this.program.push({ - pc, - ...item - }); - }, + Dummy: { - addSymbol: function(name, pc) { - this.symbols[name] = { - pc - }; - }, + compile: compiler => { + const lino = compiler.getLino(); + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `dummy`, + lino + }); + return true; + }, - mark: function() { - this.savedMark = this.index; + run: program => { + return program[program.pc].pc + 1; + } }, - rewind: function() { - this.index = this.savedMark; - }, + Encode: { - rewindTo: function(index) { - this.index = index; + compile: compiler => { + const lino = compiler.getLino(); + compiler.next(); + if (compiler.isSymbol()) { + const symbol = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `encode`, + lino, + symbol + }); + return true; + } + return false; + }, + + run: program => { + const command = program[program.pc]; + const target = program.getSymbolRecord(command.symbol); + if (target.isVHolder) { + const content = program.getValue(target.value[target.index]); + target.value[target.index] = { + type: `constant`, + numeric: false, + content: program.encode(content) + }; + command.numeric = false; + } else { + program.variableDoesNotHoldAValueError(command.lino, target.name); + } + return command.pc + 1; + } }, - completeHandler: function() { - const lino = this.getLino(); - // Add a 'goto' to skip the action - const goto = this.getPc(); - this.addCommand({ - domain: `core`, - keyword: `goto`, - lino, - goto: 0 - }); - // Add the action - this.compileOne(); - // If `continue` is set - if (this.continue) { - this.addCommand({ - domain: `core`, - keyword: `goto`, - lino, - goto: this.getPc() + 1 - }); - this.continue = false; + End: { + + compile: compiler => { + compiler.next(); + return true; + }, + + run: () => { + return 0; } - // else add a 'stop' - else { - this.addCommand({ + }, + + Exit: { + + compile: compiler => { + compiler.next(); + compiler.addCommand({ domain: `core`, - keyword: `stop`, - lino, - next: 0 + keyword: `exit` }); - } - // Fixup the 'goto' - this.getCommandAt(goto).goto = this.getPc(); - return true; - }, + return true; + }, - compileVariable: function(domain, keyword, isVHolder = false, extra = null) { - this.next(); - const lino = this.getLino(); - const item = this.getTokens()[this.getIndex()]; - if (this.symbols[item.token]) { - throw new Error(`Duplicate variable name '${item.token}'`); - } - const pc = this.getPc(); - this.next(); - this.addSymbol(item.token, pc); - const command = { - domain, - keyword, - lino, - isSymbol: true, - used: false, - isVHolder, - name: item.token, - elements: 1, - index: 0, - value: [{}], - element: [], - extra - }; - if (extra === `dom`) { - command.element = []; + run: program => { + let parent = EasyCoder.scripts[program.parent]; + let unblocked = program.unblocked; + program.exit(); + if (!unblocked && parent) { + parent.run(parent.nextPc); + parent.nextPc = 0; + } + return 0; } - this.addCommand(command); - return command; }, - compileToken: function() { - // Try each domain in turn until one can handle the command - const token = this.getToken(); - if (!token) { - return; - } - // console.log(`Compile ${token}`); - this.mark(); - for (const domainName of Object.keys(this.domain)) { - // console.log(`Try domain ${domainName} for token ${token}`); - const domain = this.domain[domainName]; - if (domain) { - const handler = domain.getHandler(token); - if (handler) { - if (handler.compile(this)) { - return; - } + Filter: { + + compile: compiler => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const arrayRecord = compiler.getSymbolRecord(); + if (compiler.nextTokenIs(`with`)) { + const func = compiler.nextToken(); + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `filter`, + lino, + array: arrayRecord.name, + func + }); + return true; } } - this.rewind(); - } - console.log(`No handler found`); - throw new Error(`I don't understand '${token}...'`); - }, + return false; + }, - compileOne: function() { - const keyword = this.getToken(); - if (!keyword) { - return; - } - // console.log(`Compile keyword '${keyword}'`); - this.warnings = []; - const pc = this.program.length; - // First check for a label - if (keyword.endsWith(`:`)) { - const name = keyword.substring(0, keyword.length - 1); - if (this.symbols[name]) { - throw new Error(`Duplicate symbol: '${name}'`); + run: program => { + const command = program[program.pc]; + const variable = program.getSymbolRecord(command.array); + const value = variable.value[variable.index].content; + const func = program.getSymbolRecord(command.func).pc; + try { + const array = JSON.parse(value); + const result = array.filter(function (a) { + variable.a = a; + program.run(func); + return variable.v; + }); + variable.value[variable.index].content = JSON.stringify(result); + } catch (err) { + program.runtimeError(command.lino, `Can't parse this array`); } - this.symbols[name] = { - pc - }; - this.index++; - } else { - this.compileToken(); + return command.pc + 1; } }, - compileFromHere: function(stopOn) { - while (this.index < this.tokens.length) { - const token = this.tokens[this.index]; - const keyword = token.token; - if (keyword === `else`) { - return this.program; - } - this.compileOne(); - if (stopOn.indexOf(keyword) > -1) { - break; - } - } - }, + Fork: { - compile: function(tokens) { - this.tokens = tokens; - this.index = 0; - this.program = []; - this.program.symbols = {}; - this.symbols = this.program.symbols; - this.warnings = []; - this.compileFromHere([]); - this.addCommand({ - domain: `core`, - keyword: `exit`, - lino: this.getLino(), - next: 0 - }); - // console.log('Symbols: ' + JSON.stringify(this.symbols, null, 2)); - for (const symbol in this.symbols) { - const record = this.program[this.symbols[symbol].pc]; - if (record.isSymbol && !record.used && !record.exporter) { - console.log(`Symbol '${record.name}' has not been used.`); + compile: compiler => { + const lino = compiler.getLino(); + compiler.next(); + if (compiler.nextTokenIs(`to`)) { + compiler.next(); } - } - return this.program; - } -}; -// eslint-disable-next-line no-unused-vars -const EasyCoder_Condition = { - - name: `EasyCoder_Condition`, + const label = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `fork`, + lino, + label + }); + return true; + }, - compile: (compiler) => { - // See if any of the domains can handle it - compiler.mark(); - for (const domainName of Object.keys(compiler.domain)) { - // console.log(`Try domain '${domainName}' for condition`); - const domain = compiler.domain[domainName]; - const code = domain.condition.compile(compiler); - if (code) { - return { - domain: name, - ...code - }; + run: program => { + const command = program[program.pc]; + try { + program.run(program.symbols[command.label].pc); + } catch (err) { + console.log(err.message); + alert(err.message); } - compiler.rewind(); + return command.pc + 1; } }, - // runtime - - test: (program, condition) => { - const handler = program.domain[condition.domain]; - return handler.condition.test(program, condition); - } -}; -const EasyCoder_Core = { - - name: `EasyCoder_Core`, - - Add: { + Go: { compile: compiler => { const lino = compiler.getLino(); - compiler.next(); - // Get the (first) value - const value1 = compiler.getValue(); - if (compiler.tokenIs(`to`)) { + if (compiler.nextTokenIs(`to`)) { compiler.next(); - // Check if a value holder is next - if (compiler.isSymbol()) { - const symbol = compiler.getSymbol(); - const variable = compiler.getCommandAt(symbol.pc); - if (variable.isVHolder) { - if (compiler.peek() === `giving`) { - // This variable must be treated as a second value - const value2 = compiler.getValue(); - compiler.next(); - const target = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `core`, - keyword: `add`, - lino, - value1, - value2, - target - }); - } else { - // Here the variable is the target. - const target = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `core`, - keyword: `add`, - lino, - value1, - target - }); - } - return true; - } - compiler.warning(`core 'add': Expected value holder`); - } else { - // Here we have 2 values so 'giving' must come next - const value2 = compiler.getValue(); - if (compiler.tokenIs(`giving`)) { - compiler.next(); - const target = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `core`, - keyword: `add`, - lino, - value1, - value2, - target - }); - return true; - } - compiler.warning(`core 'add'': Expected "giving"`); - } } - return false; + const label = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `go`, + lino, + label + }); + return true; }, - // runtime - run: program => { const command = program[program.pc]; - const value1 = command.value1; - const value2 = command.value2; - const target = program.getSymbolRecord(command.target); - if (target.isVHolder) { - const value = target.value[target.index]; - if (value2) { - const result = program.getValue(value2) + - program.getValue(value1); - target.value[target.index] = { - type: `constant`, - numeric: true, - content: result - }; - } else { - if (!value.numeric && isNaN(value.content)) { - program.nonNumericValueError(command.lino); + if (command.label) { + if (program.verifySymbol(command.label)) { + const pc = program.symbols[command.label]; + if (pc) { + return pc.pc; } - const result = parseInt(value.content) + parseInt(program.getValue(value1)); - target.value[target.index] = { - type: `constant`, - numeric: true, - content: result - }; } - } else { - program.variableDoesNotHoldAValueError(command.lino, target.name); + program.runtimeError(command.lino, `Unknown symbol '${command.label}'`); + return 0; } - return command.pc + 1; + return command.goto; } }, - Alias: { + Gosub: { compile: compiler => { const lino = compiler.getLino(); - compiler.next(); - if (compiler.isSymbol()) { - const alias = compiler.getToken(); + if (compiler.nextTokenIs(`to`)) { compiler.next(); - if (compiler.tokenIs(`to`)) { - compiler.next(); - if (compiler.isSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - symbolRecord.used = true; - compiler.next(); - compiler.addCommand({ - domain: `core`, - keyword: `alias`, - lino, - alias, - symbol: symbolRecord.name - }); - return true; - } - } } - return false; + const label = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `gosub`, + lino, + label + }); + return true; }, run: program => { const command = program[program.pc]; - const aliasPc = program.symbols[command.alias].pc; - const aliasRecord = program[aliasPc]; - const symbolRecord = program.getSymbolRecord(command.symbol); - program[aliasPc] = { - pc: aliasRecord.pc, - domain: symbolRecord.domain, - keyword: symbolRecord.keyword, - lino: aliasRecord.lino, - name: aliasRecord.name, - alias: command.symbol - }; - return command.pc + 1; + if (program.verifySymbol(command.label)) { + program.stack.push(program.pc + 1); + return program.symbols[command.label].pc; + } + program.runtimeError(command.lino, `Unknown symbol '${command.label}'`); + return 0; } }, - Append: { + If: { compile: compiler => { const lino = compiler.getLino(); - const value = compiler.getNextValue(); - if (compiler.tokenIs(`to`)) { - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.isVHolder) { - compiler.next(); - compiler.addCommand({ - domain: `core`, - keyword: `append`, - lino, - value, - select: symbolRecord.name - }); - return true; - } - } + compiler.next(); + const condition = compiler.condition.compile(compiler); + const pc = compiler.getPc(); + compiler.addCommand({ + domain: `core`, + keyword: `if`, + lino, + condition + }); + // Get the 'then' code + compiler.compileOne(); + if (!compiler.getToken()) { + compiler.getCommandAt(pc).else = compiler.getPc(); + return true; } - return false; + if (compiler.tokenIs(`else`)) { + const goto = compiler.getPc(); + // Add a 'goto' to skip the 'else' + compiler.addCommand({ + domain: `core`, + keyword: `goto`, + lino, + goto: 0 + }); + // Fixup the link to the 'else' branch + compiler.getCommandAt(pc).else = compiler.getPc(); + // Process the 'else' branch + compiler.next(); + // Add the 'else' branch + compiler.compileOne(true); + // Fixup the 'goto' + compiler.getCommandAt(goto).goto = compiler.getPc(); + } else { + // We're at the next command + compiler.getCommandAt(pc).else = compiler.getPc(); + } + return true; }, run: program => { const command = program[program.pc]; - const array = program.getSymbolRecord(command.select); - try { - const v = program.getValue(command.value); - const value = [`{`, `[`].includes(v[0]) ? JSON.parse(v) : v; - const item = array.value[array.index]; - let a = item.content; - if (a) { - a = JSON.parse(a); - } else { - a = []; - } - a.push(value); - item.content = JSON.stringify(a); + const condition = command.condition; + const test = program.condition.test(program, condition); + if (test) { return command.pc + 1; - } catch (err) { - program.runtimeError(command.lino, `JSON: Unable to parse value`); - return false; } + return command.else; } }, - Begin: { - - compile: compiler => { - compiler.next(); - compiler.compileFromHere([`end`]); - return true; - }, - - run: program => { - return program[program.pc].pc + 1; - } - }, - - Callback: { + Import: { compile: compiler => { - compiler.compileVariable(`core`, `callback`); + const imports = compiler.imports; + let caller = EasyCoder.scripts[imports.caller]; + const program = compiler.getProgram(); + if (imports.length) { + for (const name of imports) { + let symbolRecord = caller.getSymbolRecord(name); + const thisType = compiler.nextToken(); + const exportedType = symbolRecord.keyword; + if (thisType === exportedType) { + const command = compiler.compileVariable(symbolRecord.domain, exportedType, true); + const newRecord = program[compiler.getSymbols()[command.name].pc]; + newRecord.element = symbolRecord.element; + newRecord.exporter = symbolRecord.exporter ? symbolRecord.exporter : caller.script; + newRecord.exportedName = symbolRecord.name; + newRecord.extra = symbolRecord.extra; + newRecord.isVHolder = symbolRecord.isVHolder; + if (symbolRecord.program) { + newRecord.program = symbolRecord.program.script; + } + newRecord.imported = true; + if (!compiler.tokenIs(`and`)) { + break; + } + } else { + throw new Error(`Mismatched import variable type for '${symbolRecord.name}'`); + } + } + if (compiler.tokenIs(`and`)) { + throw new Error(`Imports do not match exports`); + } + } else { + compiler.next(); + } return true; }, run: program => { - return program[program.pc].pc + 1; + const command = program[program.pc]; + return command.pc + 1; } }, - Clear: { + Index: { compile: compiler => { const lino = compiler.getLino(); - compiler.next(); - if (compiler.isSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.isVHolder) { - const symbol = compiler.getToken(); - compiler.next(); + // get the variable + if (compiler.nextIsSymbol(true)) { + const symbol = compiler.getToken(); + if (compiler.nextTokenIs(`to`)) { + // get the value + const value = compiler.getNextValue(); compiler.addCommand({ domain: `core`, - keyword: `clear`, + keyword: `index`, lino, - symbol + symbol, + value }); return true; } - compiler.warning(`'Variable '${symbolRecord.name}' does not hold a value`); } return false; }, @@ -642,186 +856,83 @@ const EasyCoder_Core = { run: program => { const command = program[program.pc]; const symbol = program.getSymbolRecord(command.symbol); - if (symbol.isVHolder) { - const handler = program.domain[symbol.domain]; - handler.value.put(symbol, { - type: `boolean`, - content: false - }); - command.numeric = false; - } else { - program.variableDoesNotHoldAValueError(command.lino, symbol.name); + const index = program.getValue(command.value); + if (index >= symbol.elements) { + program.runtimeError(command.lino, + `Array index ${index} is out of range for '${symbol.name}'`); + } + symbol.index = index; + if (symbol.imported) { + const exporterRecord = EasyCoder.symbols[symbol.exporter].getSymbolRecord(symbol.exportedName); + exporterRecord.index = index; } return command.pc + 1; } }, - Close: { + Load: { compile: compiler => { const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const moduleRecord = compiler.getSymbolRecord(); - if (moduleRecord.keyword === `module`) { - compiler.next(); - compiler.addCommand({ - domain: `core`, - keyword: `close`, - lino, - module: moduleRecord.name - }); - return true; - } + const type = compiler.nextToken(); + switch (type) { + case `plugin`: + const name = compiler.getNextValue(); + const id = compiler.getValue(); + const url = compiler.getValue(); + compiler.addCommand({ + domain: `core`, + keyword: `load`, + lino, + name, + id, + url + }); + return true; } return false; }, run: program => { const command = program[program.pc]; - const moduleRecord = program.getSymbolRecord(command.module); - const p = EasyCoder.scripts[moduleRecord.program]; - p.run(p.onClose); - return command.pc + 1; + const name = program.getValue(command.name); + const id = program.getValue(command.id); + const url = program.getValue(command.url); + switch (command.keyword) { + case `load`: + if (typeof EasyCoder.domain.name === `undefined`) { + program.require(`js`, program.getValue(command.url), + function () { + EasyCoder.domain.name = id; + program.run(command.pc + 1); + }); + return 0; + } + return command.pc + 1; + } + return false; } }, - Continue: { + Module: { compile: compiler => { - compiler.next(); - compiler.continue = true; + compiler.compileVariable(`core`, `module`); return true; - } - }, - - Debug: { - - compile: compiler => { - const lino = compiler.getLino(); - if (compiler.nextTokenIs(`program`)) { - compiler.next(); - if ([`item`, `pc`].includes(compiler.getToken())) { - const item = compiler.getNextValue(); - compiler.addCommand({ - domain: `core`, - keyword: `debug`, - lino, - item - }); - return true; - } - compiler.addCommand({ - domain: `core`, - keyword: `debug`, - lino, - item: `program` - }); - return true; - } else if (compiler.tokenIs(`symbols`)) { - compiler.next(); - compiler.addCommand({ - domain: `core`, - keyword: `debug`, - lino, - item: `symbols` - }); - return true; - } else if (compiler.tokenIs(`symbol`)) { - const name = compiler.nextToken(); - compiler.next(); - compiler.addCommand({ - domain: `core`, - keyword: `debug`, - lino, - item: `symbol`, - name - }); - return true; - } else if (compiler.tokenIs(`step`)) { - compiler.next(); - compiler.addCommand({ - domain: `core`, - keyword: `debug`, - lino, - item: `step` - }); - return true; - } - return false; - }, - - run: program => { - const command = program[program.pc]; - const item = command.item; - switch (item) { - case `symbols`: - console.log(`Symbols: ${JSON.stringify(program.symbols, null, 2)}`); - break; - case `symbol`: - const record = program.getSymbolRecord(command.name); - const exporter = record.exporter.script; - delete record.exporter; - console.log(`Symbol: ${JSON.stringify(record, null, 2)}`); - record.exporter.script = exporter; - break; - case `step`: - program.debugStep = true; - break; - case `program`: - console.log(`Debug program: ${JSON.stringify(program, null, 2)}`); - break; - default: - if (item.content >= 0) { - console.log(`Debug item ${item.content}: ${JSON.stringify(program[item.content], null, 2)}`); - } - break; - } - return command.pc + 1; - } - }, - - Decode: { - - compile: compiler => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const symbol = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `core`, - keyword: `decode`, - lino, - symbol - }); - return true; - } - return false; }, run: program => { - const command = program[program.pc]; - const target = program.getSymbolRecord(command.symbol); - if (target.isVHolder) { - const content = program.getValue(target.value[target.index]); - target.value[target.index] = { - type: `constant`, - numeric: false, - content: program.decode(content) - }; - command.numeric = false; - } else { - program.variableDoesNotHoldAValueError(command.lino, target.name); - } - return command.pc + 1; + return program[program.pc].pc + 1; } }, - Divide: { + Multiply: { compile: compiler => { const lino = compiler.getLino(); + compiler.next(); var target; - if (compiler.nextIsSymbol()) { + if (compiler.isSymbol()) { // It may be the target const symbol = compiler.getSymbol(); target = compiler.getCommandAt(symbol.pc).name; @@ -843,7 +954,7 @@ const EasyCoder_Core = { compiler.next(); compiler.addCommand({ domain: `core`, - keyword: `divide`, + keyword: `multiply`, lino, value1, value2, @@ -851,15 +962,15 @@ const EasyCoder_Core = { }); return true; } - compiler.warning(`core 'divide'': Expected value holder`); + compiler.warning(`core multiply: Expected value holder`); } else { // Here we should already have the target. if (typeof target === `undefined`) { - compiler.warning(`core 'divide': No target variable given`); + compiler.warning(`core multiply: No target variable given`); } compiler.addCommand({ domain: `core`, - keyword: `divide`, + keyword: `multiply`, lino, value2, target @@ -877,21 +988,22 @@ const EasyCoder_Core = { if (target.isVHolder) { const value = target.value[target.index]; if (value1) { - const result = program.getValue(value1) / program.getValue(value2); + const result = program.getValue(value1) * + program.getValue(value2); target.value[target.index] = { type: `constant`, numeric: true, - content: Math.trunc(result) + content: result }; } else { if (!value.numeric && isNaN(value.content)) { program.nonNumericValueError(command, lino); } - const result = parseInt(value.content) / parseInt(program.getValue(value2)); + const result = parseInt(value.content) * parseInt(program.getValue(value2)); target.value[target.index] = { type: `constant`, numeric: true, - content: Math.trunc(result) + content: result }; } } else { @@ -901,25 +1013,7 @@ const EasyCoder_Core = { } }, - Dummy: { - - compile: compiler => { - const lino = compiler.getLino(); - compiler.next(); - compiler.addCommand({ - domain: `core`, - keyword: `dummy`, - lino - }); - return true; - }, - - run: program => { - return program[program.pc].pc + 1; - } - }, - - Encode: { + Negate: { compile: compiler => { const lino = compiler.getLino(); @@ -929,7 +1023,7 @@ const EasyCoder_Core = { compiler.next(); compiler.addCommand({ domain: `core`, - keyword: `encode`, + keyword: `negate`, lino, symbol }); @@ -940,343 +1034,338 @@ const EasyCoder_Core = { run: program => { const command = program[program.pc]; - const target = program.getSymbolRecord(command.symbol); - if (target.isVHolder) { - const content = program.getValue(target.value[target.index]); - target.value[target.index] = { + const symbol = program.getSymbolRecord(command.symbol); + if (symbol.isVHolder) { + symbol.value[symbol.index] = { type: `constant`, - numeric: false, - content: program.encode(content) + numeric: true, + content: -symbol.value[symbol.index].content }; - command.numeric = false; } else { - program.variableDoesNotHoldAValueError(command.lino, target.name); + program.variableDoesNotHoldAValueError(command.lino, symbol.name); } return command.pc + 1; } }, - End: { + On: { compile: compiler => { - compiler.next(); - return true; + const lino = compiler.getLino(); + const action = compiler.nextToken(); + switch (action) { + case `close`: + case `message`: + case `error`: + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `on`, + lino, + action + }); + return compiler.completeHandler(); + } + if (compiler.isSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.keyword === `callback`) { + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `on`, + lino, + action: symbolRecord.name + }); + return compiler.completeHandler(); + } + } + return false; }, - run: () => { - return 0; + run: program => { + const command = program[program.pc]; + const cb = command.pc + 2; + switch (command.action) { + case `close`: + program.onClose = cb; + break; + case `message`: + program.onMessage = cb; + break; + case `error`: + program.onError = cb; + break; + default: + const callbacklRecord = program.getSymbolRecord(command.action); + if (callbacklRecord) { + callbacklRecord.cb = cb; + } else { + program.runtimeError(command.lino, `Unknown action '${command.action}'`); + return 0; + } + } + return command.pc + 1; } }, - Exit: { + Print: { compile: compiler => { + const lino = compiler.getLino(); compiler.next(); + const value = compiler.getValue(); compiler.addCommand({ domain: `core`, - keyword: `exit` + keyword: `print`, + lino, + value }); return true; }, run: program => { - let parent = EasyCoder.scripts[program.parent]; - let unblocked = program.unblocked; - program.exit(); - if (!unblocked && parent) { - parent.run(parent.nextPc); - parent.nextPc = 0; - } - return 0; + const command = program[program.pc]; + const value = program.getFormattedValue(command.value); + console.log(`-> ` + value); + return command.pc + 1; } }, - Filter: { + Put: { compile: compiler => { const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const arrayRecord = compiler.getSymbolRecord(); - if (compiler.nextTokenIs(`with`)) { - const func = compiler.nextToken(); + // Get the value + const value = compiler.getNextValue(); + if (compiler.tokenIs(`into`)) { + if (compiler.nextIsSymbol()) { + const target = compiler.getToken(); compiler.next(); compiler.addCommand({ domain: `core`, - keyword: `filter`, + keyword: `put`, lino, - array: arrayRecord.name, - func + value, + target }); return true; } + compiler.warning(`core:put: No such variable: '${compiler.getToken()}'`); } return false; }, + // runtime + run: program => { const command = program[program.pc]; - const variable = program.getSymbolRecord(command.array); - const value = variable.value[variable.index].content; - const func = program.getSymbolRecord(command.func).pc; - try { - const array = JSON.parse(value); - const result = array.filter(function (a) { - variable.a = a; - program.run(func); - return variable.v; - }); - variable.value[variable.index].content = JSON.stringify(result); - } catch (err) { - program.runtimeError(command.lino, `Can't parse this array`); + const target = program.getSymbolRecord(command.target); + if (!target.isVHolder) { + program.variableDoesNotHoldAValueError(command.lino, target.name); + } + const value = program.evaluate(command.value); + // target.value[target.index] = value; + target.value[target.index] = { + type: value.type, + numeric: value.numeric, + content: value.content + }; + if (target.imported) { + const exporterRecord = EasyCoder.scripts[target.exporter].getSymbolRecord(target.exportedName); + exporterRecord.value[exporterRecord.index] = value; } return command.pc + 1; } }, - Fork: { + Replace: { compile: compiler => { const lino = compiler.getLino(); - compiler.next(); - if (compiler.nextTokenIs(`to`)) { - compiler.next(); + const original = compiler.getNextValue(); + if (compiler.tokenIs(`with`)) { + const replacement = compiler.getNextValue(); + if (compiler.tokenIs(`in`)) { + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.isVHolder) { + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `replace`, + lino, + original, + replacement, + target: targetRecord.name + }); + return true; + } else { + throw new Error(`'${targetRecord.name}' does not hold a value`); + } + } + } } - const label = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `core`, - keyword: `fork`, - lino, - label - }); - return true; + return false; }, + // runtime + run: program => { const command = program[program.pc]; - try { - program.run(program.symbols[command.label].pc); - } catch (err) { - console.log(err.message); - alert(err.message); - } + const original = program.getValue(command.original); + const replacement = program.getValue(command.replacement); + const target = program.getSymbolRecord(command.target); + const value = program.getValue(target.value[target.index]); + const content = value.split(original).join(replacement); + target.value[target.index] = { + type: `constant`, + numeric: false, + content + }; return command.pc + 1; } }, - Go: { + Require: { compile: compiler => { const lino = compiler.getLino(); - if (compiler.nextTokenIs(`to`)) { - compiler.next(); + const type = compiler.nextToken(); + if ([`css`, `js`].includes(type)) { + const url = compiler.getNextValue(); + compiler.addCommand({ + domain: `core`, + keyword: `require`, + lino, + type, + url + }); + return true; } - const label = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `core`, - keyword: `go`, - lino, - label - }); - return true; + throw new Error(`File type must be 'css' or 'js'`); }, + // runtime + run: program => { const command = program[program.pc]; - if (command.label) { - if (program.verifySymbol(command.label)) { - const pc = program.symbols[command.label]; - if (pc) { - return pc.pc; - } - } - program.runtimeError(command.lino, `Unknown symbol '${command.label}'`); - return 0; - } - return command.goto; + program.require(command.type, program.getValue(command.url), + function () { + program.run(command.pc + 1); + }); + return 0; } }, - Gosub: { + Return: { compile: compiler => { const lino = compiler.getLino(); - if (compiler.nextTokenIs(`to`)) { - compiler.next(); - } - const label = compiler.getToken(); compiler.next(); compiler.addCommand({ domain: `core`, - keyword: `gosub`, - lino, - label + keyword: `return`, + lino }); return true; }, + // runtime + run: program => { - const command = program[program.pc]; - if (program.verifySymbol(command.label)) { - program.stack.push(program.pc + 1); - return program.symbols[command.label].pc; - } - program.runtimeError(command.lino, `Unknown symbol '${command.label}'`); - return 0; + return program.stack.pop(); } }, - If: { + Run: { compile: compiler => { const lino = compiler.getLino(); - compiler.next(); - const condition = compiler.condition.compile(compiler); + const script = compiler.getNextValue(); + const imports = []; + if (compiler.tokenIs(`with`)) { + while (true) { + if (compiler.nextIsSymbol(true)) { + const symbolRecord = compiler.getSymbolRecord(); + imports.push(symbolRecord.name); + compiler.next(); + if (!compiler.tokenIs(`and`)) { + break; + } + } + } + } + let module; + if (compiler.tokenIs(`as`)) { + if (compiler.nextIsSymbol(true)) { + const moduleRecord = compiler.getSymbolRecord(); + // moduleRecord.program = program.script; + compiler.next(); + if (moduleRecord.keyword !== `module`) { + throw new Error(`'${moduleRecord.name}' is not a module`); + } + module = moduleRecord.name; + } + } + let nowait = false; + if (compiler.tokenIs(`nowait`)) { + compiler.next(); + nowait = true; + } const pc = compiler.getPc(); compiler.addCommand({ domain: `core`, - keyword: `if`, + keyword: `run`, lino, - condition + script, + imports, + module, + nowait, + then: 0 }); - // Get the 'then' code - compiler.compileOne(); - if (!compiler.getToken()) { - compiler.getCommandAt(pc).else = compiler.getPc(); - return true; - } - if (compiler.tokenIs(`else`)) { + // Get the 'then' code, if any + if (compiler.tokenIs(`then`)) { const goto = compiler.getPc(); - // Add a 'goto' to skip the 'else' + // Add a 'goto' to skip the 'then' compiler.addCommand({ domain: `core`, keyword: `goto`, - lino, goto: 0 }); - // Fixup the link to the 'else' branch - compiler.getCommandAt(pc).else = compiler.getPc(); - // Process the 'else' branch + // Fixup the link to the 'then' branch + compiler.getCommandAt(pc).then = compiler.getPc(); + // Process the 'then' branch compiler.next(); - // Add the 'else' branch compiler.compileOne(true); + compiler.addCommand({ + domain: `core`, + keyword: `stop` + }); // Fixup the 'goto' compiler.getCommandAt(goto).goto = compiler.getPc(); - } else { - // We're at the next command - compiler.getCommandAt(pc).else = compiler.getPc(); } return true; }, + // runtime + run: program => { - const command = program[program.pc]; - const condition = command.condition; - const test = program.condition.test(program, condition); - if (test) { - return command.pc + 1; - } - return command.else; + program.nextPc = program.pc + 1; + program.runScript(program); + return 0; } }, - Import: { - - compile: compiler => { - const imports = compiler.imports; - let caller = EasyCoder.scripts[imports.caller]; - const program = compiler.getProgram(); - if (imports.length) { - for (const name of imports) { - let symbolRecord = caller.getSymbolRecord(name); - const thisType = compiler.nextToken(); - const exportedType = symbolRecord.keyword; - if (thisType === exportedType) { - const command = compiler.compileVariable(symbolRecord.domain, exportedType, true); - const newRecord = program[compiler.getSymbols()[command.name].pc]; - newRecord.element = symbolRecord.element; - newRecord.exporter = symbolRecord.exporter ? symbolRecord.exporter : caller.script; - newRecord.exportedName = symbolRecord.name; - newRecord.extra = symbolRecord.extra; - newRecord.isVHolder = symbolRecord.isVHolder; - if (symbolRecord.program) { - newRecord.program = symbolRecord.program.script; - } - newRecord.imported = true; - if (!compiler.tokenIs(`and`)) { - break; - } - } else { - throw new Error(`Mismatched import variable type for '${symbolRecord.name}'`); - } - } - if (compiler.tokenIs(`and`)) { - throw new Error(`Imports do not match exports`); - } - } else { - compiler.next(); - } - return true; - }, - - run: program => { - const command = program[program.pc]; - return command.pc + 1; - } - }, - - Index: { - - compile: compiler => { - const lino = compiler.getLino(); - // get the variable - if (compiler.nextIsSymbol(true)) { - const symbol = compiler.getToken(); - if (compiler.nextTokenIs(`to`)) { - // get the value - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `core`, - keyword: `index`, - lino, - symbol, - value - }); - return true; - } - } - return false; - }, - - run: program => { - const command = program[program.pc]; - const symbol = program.getSymbolRecord(command.symbol); - const index = program.getValue(command.value); - if (index >= symbol.elements) { - program.runtimeError(command.lino, - `Array index ${index} is out of range for '${symbol.name}'`); - } - symbol.index = index; - if (symbol.imported) { - const exporterRecord = EasyCoder.symbols[symbol.exporter].getSymbolRecord(symbol.exportedName); - exporterRecord.index = index; - } - return command.pc + 1; - } - }, - - Load: { + Sanitize: { compile: compiler => { const lino = compiler.getLino(); - const type = compiler.nextToken(); - switch (type) { - case `plugin`: - const name = compiler.getNextValue(); + if (compiler.nextIsSymbol()) { + const name = compiler.getToken(); + compiler.next(); compiler.addCommand({ domain: `core`, - keyword: `load`, + keyword: `sanitize`, lino, name }); @@ -1287,29 +1376,25 @@ const EasyCoder_Core = { run: program => { const command = program[program.pc]; - const name = program.getValue(command.name); - switch (command.keyword) { - case `load`: - if (program.checkPlugin(name)) { - return command.pc + 1; - } - EasyCoder_Plugins.getLocalPlugin( - program.getPluginsPath, - name, - program.getPlugin, - program.addLocalPlugin, - function () { - program.run(command.pc + 1); - }); - return 0; - } + const symbolRecord = program.getSymbolRecord(command.name); + const value = symbolRecord.value[symbolRecord.index]; + value.content = JSON.stringify(JSON.parse(value.content)); + return command.pc + 1; } }, - Module: { + Script: { compile: compiler => { - compiler.compileVariable(`core`, `module`); + const program = compiler.getProgram(); + program.script = compiler.nextToken(); + compiler.script = program.script; + if (EasyCoder.scripts[program.script]) { + delete compiler.script; + throw new Error(`Script '${program.script}' is already running.`); + } + EasyCoder.scripts[program.script] = program; + compiler.next(); return true; }, @@ -1318,448 +1403,613 @@ const EasyCoder_Core = { } }, - Multiply: { + Send: { compile: compiler => { const lino = compiler.getLino(); - compiler.next(); - var target; - if (compiler.isSymbol()) { - // It may be the target - const symbol = compiler.getSymbol(); - target = compiler.getCommandAt(symbol.pc).name; - } - // Get the value even if we have a target - const value1 = compiler.getValue(); - if (compiler.tokenIs(`by`)) { - compiler.next(); - } - // The next item is always a value - const value2 = compiler.getValue(); - // If we now have 'giving' then the target follows - if (compiler.tokenIs(`giving`)) { - compiler.next(); - // Get the target - if (compiler.isSymbol()) { - const symbol = compiler.getSymbol(); - target = compiler.getCommandAt(symbol.pc).name; - compiler.next(); - compiler.addCommand({ - domain: `core`, - keyword: `multiply`, - lino, - value1, - value2, - target - }); - return true; - } - compiler.warning(`core multiply: Expected value holder`); - } else { - // Here we should already have the target. - if (typeof target === `undefined`) { - compiler.warning(`core multiply: No target variable given`); - } - compiler.addCommand({ - domain: `core`, - keyword: `multiply`, - lino, - value2, - target - }); - return true; + let message = ``; + if (!compiler.nextTokenIs(`to`)) { + message = compiler.getValue(); } - return false; - }, - - run: program => { - const command = program[program.pc]; - const value1 = command.value1; - const value2 = command.value2; - const target = program.getSymbolRecord(command.target); - if (target.isVHolder) { - const value = target.value[target.index]; - if (value1) { - const result = program.getValue(value1) * - program.getValue(value2); - target.value[target.index] = { - type: `constant`, - numeric: true, - content: result - }; - } else { - if (!value.numeric && isNaN(value.content)) { - program.nonNumericValueError(command, lino); + if (compiler.tokenIs(`to`)) { + var recipient; + if (compiler.nextTokenIs(`parent`)) { + recipient = `parent`; + } else if (compiler.isSymbol) { + const moduleRecord = compiler.getSymbolRecord(); + if (moduleRecord.keyword !== `module`) { + throw new Error(`'${moduleRecord.name}' is not a module`); } - const result = parseInt(value.content) * parseInt(program.getValue(value2)); - target.value[target.index] = { - type: `constant`, - numeric: true, - content: result - }; + recipient = moduleRecord.name; } - } else { - program.variableDoesNotHoldAValueError(command.lino, target.name); - } - return command.pc + 1; - } - }, - - Negate: { - - compile: compiler => { - const lino = compiler.getLino(); - compiler.next(); - if (compiler.isSymbol()) { - const symbol = compiler.getToken(); compiler.next(); compiler.addCommand({ domain: `core`, - keyword: `negate`, + keyword: `send`, lino, - symbol + message, + recipient }); - return true; } - return false; + return true; }, run: program => { const command = program[program.pc]; - const symbol = program.getSymbolRecord(command.symbol); - if (symbol.isVHolder) { - symbol.value[symbol.index] = { - type: `constant`, - numeric: true, - content: -symbol.value[symbol.index].content - }; + const message = program.getValue(command.message); + if (command.recipient === `parent`) { + if (program.parent) { + const parent = EasyCoder.scripts[program.parent]; + const onMessage = parent.onMessage; + if (onMessage) { + parent.message = message; + parent.run(parent.onMessage); + } + } } else { - program.variableDoesNotHoldAValueError(command.lino, symbol.name); + const recipient = program.getSymbolRecord(command.recipient); + if (recipient.program) { + let rprog = EasyCoder.scripts[recipient.program]; + rprog.message = message; + rprog.run(rprog.onMessage); + } } return command.pc + 1; } }, - On: { + Set: { compile: compiler => { + let name; const lino = compiler.getLino(); - const action = compiler.nextToken(); - switch (action) { - case `close`: - case `message`: - case `error`: - compiler.next(); - compiler.addCommand({ - domain: `core`, - keyword: `on`, - lino, - action - }); - return compiler.completeHandler(); - } - if (compiler.isSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.keyword === `callback`) { - compiler.next(); + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (!targetRecord.isVHolder) { + return false; + } + if (compiler.nextTokenIs(`to`)) { + const token = compiler.nextToken(); + if ([`array`, `object`].includes(token)) { + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `set`, + lino, + request: `setVarTo`, + target: targetRecord.name, + type: token + }); + return true; + } + const value = []; + while (true) { + compiler.mark(); + try { + value.push(compiler.getValue()); + } catch (err) { + compiler.rewind(); + break; + } + } compiler.addCommand({ domain: `core`, - keyword: `on`, + keyword: `set`, lino, - action: symbolRecord.name + request: `setArray`, + target: targetRecord.name, + value }); - return compiler.completeHandler(); + return true; } + compiler.addCommand({ + domain: `core`, + keyword: `set`, + lino, + request: `setBoolean`, + target: targetRecord.name + }); + return true; } - return false; - }, - - run: program => { - const command = program[program.pc]; - const cb = command.pc + 2; - switch (command.action) { - case `close`: - program.onClose = cb; - break; - case `message`: - program.onMessage = cb; + switch (compiler.getToken()) { + case `ready`: + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `set`, + lino, + request: `setReady` + }); + return true; + case `element`: + const index = compiler.getNextValue(); + if (compiler.tokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + if (compiler.nextTokenIs(`to`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `core`, + keyword: `set`, + lino, + request: `setElement`, + target: targetRecord.name, + index, + value + }); + return true; + } + } + } + } break; - case `error`: - program.onError = cb; + case `property`: + name = compiler.getNextValue(); + if (compiler.tokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + if (compiler.nextTokenIs(`to`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `core`, + keyword: `set`, + lino, + request: `setProperty`, + target: targetRecord.name, + name, + value + }); + return true; + } + } + } + } break; - default: - const callbacklRecord = program.getSymbolRecord(command.action); - if (callbacklRecord) { - callbacklRecord.cb = cb; - } else { - program.runtimeError(command.lino, `Unknown action '${command.action}'`); - return 0; + case `arg`: + name = compiler.getNextValue(); + if (compiler.tokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (compiler.nextTokenIs(`to`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `core`, + keyword: `set`, + lino, + request: `setArg`, + target: targetRecord.name, + name, + value + }); + return true; + } + } } } - return command.pc + 1; - } - }, - - Print: { - - compile: compiler => { - const lino = compiler.getLino(); - compiler.next(); - const value = compiler.getValue(); - compiler.addCommand({ - domain: `core`, - keyword: `print`, - lino, - value - }); - return true; - }, - - run: program => { - const command = program[program.pc]; - const value = program.getFormattedValue(command.value); - console.log(`-> ` + value); - return command.pc + 1; - } - }, - - Put: { - - compile: compiler => { - const lino = compiler.getLino(); - // Get the value - const value = compiler.getNextValue(); - if (compiler.tokenIs(`into`)) { - if (compiler.nextIsSymbol()) { - const target = compiler.getToken(); + if (compiler.tokenIs(`the`)) { + compiler.next(); + } + switch (compiler.getToken()) { + case `elements`: + compiler.next(); + if (compiler.tokenIs(`of`)) { + compiler.next(); + if (!compiler.isSymbol()) { + throw new Error(`Unknown variable '${compiler.getToken()}'`); + } + const symbol = compiler.getToken(); compiler.next(); + if (compiler.tokenIs(`to`)) { + compiler.next(); + // get the value + const value = compiler.getValue(); + compiler.addCommand({ + domain: `core`, + keyword: `set`, + lino, + request: `setElements`, + symbol, + value + }); + return true; + } + } + break; + case `encoding`: + if (compiler.nextTokenIs(`to`)) { + const encoding = compiler.getNextValue(); compiler.addCommand({ domain: `core`, - keyword: `put`, + keyword: `set`, + request: `encoding`, lino, - value, - target + encoding }); return true; } - compiler.warning(`core:put: No such variable: '${compiler.getToken()}'`); + compiler.addWarning(`Unknown encoding option`); + break; + case `payload`: + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const callbackRecord = compiler.getSymbolRecord(); + if (callbackRecord.keyword === `callback`) { + if (compiler.nextTokenIs(`to`)) { + const payload = compiler.getNextValue(); + compiler.addCommand({ + domain: `core`, + keyword: `set`, + request: `setPayload`, + lino, + callback: callbackRecord.name, + payload + }); + return true; + } + } + } + } } return false; }, - // runtime - run: program => { + let targetRecord; const command = program[program.pc]; - const target = program.getSymbolRecord(command.target); - if (!target.isVHolder) { - program.variableDoesNotHoldAValueError(command.lino, target.name); - } - const value = program.evaluate(command.value); - // target.value[target.index] = value; - target.value[target.index] = { - type: value.type, - numeric: value.numeric, - content: value.content - }; - if (target.imported) { - const exporterRecord = EasyCoder.scripts[target.exporter].getSymbolRecord(target.exportedName); - exporterRecord.value[exporterRecord.index] = value; + switch (command.request) { + case `setBoolean`: + const target = program.getSymbolRecord(command.target); + if (target.isVHolder) { + target.value[target.index] = { + type: `boolean`, + content: true + }; + command.numeric = false; + } else { + program.variableDoesNotHoldAValueError(command.lino, target.name); + } + break; + case `setReady`: + let parent = EasyCoder.scripts[program.parent]; + if (parent) { + parent.run(parent.nextPc); + parent.nextPc = 0; + program.unblocked = true; + } + break; + case `setArray`: + targetRecord = program.getSymbolRecord(command.target); + targetRecord.elements = command.value.length; + targetRecord.value = command.value; + break; + case `encoding`: + program.encoding = program.getValue(command.encoding); + break; + case `setElements`: + const symbol = program.getSymbolRecord(command.symbol); + const oldCount = symbol.elements; + symbol.elements = program.getValue(command.value); + symbol.index = 0; + if (symbol.elements > oldCount) { + for (var n = oldCount; n < symbol.elements; n++) { + symbol.value.push({}); + symbol.element.push(null); + } + } else { + symbol.value = symbol.value.slice(0, symbol.elements); + symbol.element = symbol.element.slice(0, symbol.elements); + } + break; + case `setElement`: + targetRecord = program.getSymbolRecord(command.target); + const index = program.getValue(command.index); + const elements = JSON.parse(program.getValue(targetRecord.value[targetRecord.index])); + const value = program.getValue(command.value); + elements[index] = JSON.parse(value); + targetRecord.value[targetRecord.index].content = JSON.stringify(elements); + break; + case `setProperty`: + // This is the name of the property + const itemName = program.getValue(command.name); + // This is the value of the property + let itemValue = program.getValue(command.value); + if (program.isJsonString(itemValue)) { + itemValue = JSON.parse(itemValue); + } + targetRecord = program.getSymbolRecord(command.target); + let targetValue = targetRecord.value[targetRecord.index]; + // Get the existing JSON + if (!targetValue.numeric) { + let content = targetValue.content; + if (content === ``) { + content = {}; + } + else if (program.isJsonString(content)) { + content = JSON.parse(content); + } + // Set the property + content[itemName] = itemValue; + // Put it back + content = JSON.stringify(content); + targetRecord.value[targetRecord.index] = { + type: `constant`, + numeric: false, + content + }; + } + break; + case `setPayload`: + program.getSymbolRecord(command.callback).payload = program.getValue(command.payload); + break; + case `setArg`: + const name = program.getValue(command.name); + targetRecord = program.getSymbolRecord(command.target); + targetRecord[name] = program.getValue(command.value); + break; + case `setVarTo`: + targetRecord = program.getSymbolRecord(command.target); + targetRecord.value[targetRecord.index] = { + type: `constant`, + numeric: false, + content: command.type === `array` ? `[]` : `{}` + }; + break; + default: + break; } return command.pc + 1; } }, - Replace: { + Sort: { compile: compiler => { const lino = compiler.getLino(); - const original = compiler.getNextValue(); - if (compiler.tokenIs(`with`)) { - const replacement = compiler.getNextValue(); - if (compiler.tokenIs(`in`)) { - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.isVHolder) { - compiler.next(); - compiler.addCommand({ - domain: `core`, - keyword: `replace`, - lino, - original, - replacement, - target: targetRecord.name - }); - return true; - } else { - throw new Error(`'${targetRecord.name}' does not hold a value`); - } - } + if (compiler.nextIsSymbol()) { + const arrayRecord = compiler.getSymbolRecord(); + if (compiler.nextTokenIs(`with`)) { + const func = compiler.nextToken(); + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `sort`, + lino, + array: arrayRecord.name, + func + }); + return true; } } return false; }, - // runtime - run: program => { const command = program[program.pc]; - const original = program.getValue(command.original); - const replacement = program.getValue(command.replacement); - const target = program.getSymbolRecord(command.target); - const value = program.getValue(target.value[target.index]); - const content = value.split(original).join(replacement); - target.value[target.index] = { - type: `constant`, - numeric: false, - content - }; + const variable = program.getSymbolRecord(command.array); + const value = variable.value[variable.index].content; + const func = program.getSymbolRecord(command.func).pc; + try { + const array = JSON.parse(value); + array.sort(function (a, b) { + variable.a = a; + variable.b = b; + program.run(func); + return variable.v; + }); + variable.value[variable.index].content = JSON.stringify(array); + } catch (err) { + program.runtimeError(command.lino, `Can't parse this array`); + } return command.pc + 1; } }, - Require: { + Split: { compile: compiler => { const lino = compiler.getLino(); - const type = compiler.nextToken(); - if ([`css`, `js`].includes(type)) { - const url = compiler.getNextValue(); - compiler.addCommand({ - domain: `core`, - keyword: `require`, - lino, - type, - url - }); - return true; + item = compiler.getNextValue(); + let on = `\n`; + if (compiler.tokenIs(`on`)) { + on = compiler.getNextValue(); } - throw new Error(`File type must be 'css' or 'js'`); + if ([`giving`, `into`].includes(compiler.getToken())) { + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `split`, + lino, + item, + on, + target: targetRecord.name + }); + return true; + } + } + } + return false; }, - // runtime - run: program => { - const command = program[program.pc]; - program.require(command.type, program.getValue(command.url), - function () { - program.run(command.pc + 1); - }); - return 0; + let command = program[program.pc]; + let content = program.getValue(command.item); + let on = program.getValue(command.on); + content = content.split(on); + let elements = content.length; + targetRecord = program.getSymbolRecord(command.target); + targetRecord.elements = elements; + for (let n = 0; n < elements; n++) { + targetRecord.value[n] = { + type: `constant`, + numeric: false, + content: content[n] + }; + } + targetRecord.index = 0; + return command.pc + 1; } }, - Return: { + Stop: { compile: compiler => { const lino = compiler.getLino(); compiler.next(); + if (compiler.more() && compiler.isSymbol() && !compiler.getToken().endsWith(`:`)) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.keyword === `module`) { + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `stop`, + lino, + name: symbolRecord.name + }); + return true; + } else { + return false; + } + } compiler.addCommand({ domain: `core`, - keyword: `return`, - lino + keyword: `stop`, + lino, + next: 0 }); return true; }, - // runtime - run: program => { - return program.stack.pop(); + const command = program[program.pc]; + if (command.name) { + const symbolRecord = program.getSymbolRecord(command.name); + EasyCoder.scripts[symbolRecord.program].exit(); + symbolRecord.program = null; + } else { + return 0; + } + return command.pc + 1; } }, - Run: { + Take: { compile: compiler => { const lino = compiler.getLino(); - const script = compiler.getNextValue(); - const imports = []; - if (compiler.tokenIs(`with`)) { - while (true) { - if (compiler.nextIsSymbol(true)) { - const symbolRecord = compiler.getSymbolRecord(); - imports.push(symbolRecord.name); - compiler.next(); - if (!compiler.tokenIs(`and`)) { - break; + compiler.next(); + // Get the (first) value + const value1 = compiler.getValue(); + if (compiler.tokenIs(`from`)) { + compiler.next(); + if (compiler.isSymbol()) { + const symbol = compiler.getSymbol(); + const variable = compiler.getCommandAt(symbol.pc); + if (variable.isVHolder) { + if (compiler.peek() === `giving`) { + // This variable must be treated as a second value + const value2 = compiler.getValue(); + compiler.next(); + const target = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `take`, + lino, + value1, + value2, + target + }); + } else { + // Here the variable is the target. + const target = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `take`, + lino, + value1, + target + }); } + return true; + } else { + compiler.warning(`core 'take'': Expected value holder`); } - } - } - let module; - if (compiler.tokenIs(`as`)) { - if (compiler.nextIsSymbol(true)) { - const moduleRecord = compiler.getSymbolRecord(); - // moduleRecord.program = program.script; - compiler.next(); - if (moduleRecord.keyword !== `module`) { - throw new Error(`'${moduleRecord.name}' is not a module`); + } else { + // Here we have 2 values so 'giving' must come next + const value2 = compiler.getValue(); + if (compiler.tokenIs(`giving`)) { + compiler.next(); + const target = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `core`, + keyword: `take`, + lino, + value1, + value2, + target + }); + return true; + } else { + compiler.warning(`core 'take'': Expected "giving"`); } - module = moduleRecord.name; } } - let nowait = false; - if (compiler.tokenIs(`nowait`)) { - compiler.next(); - nowait = true; - } - const pc = compiler.getPc(); - compiler.addCommand({ - domain: `core`, - keyword: `run`, - lino, - script, - imports, - module, - nowait, - then: 0 - }); - // Get the 'then' code, if any - if (compiler.tokenIs(`then`)) { - const goto = compiler.getPc(); - // Add a 'goto' to skip the 'then' - compiler.addCommand({ - domain: `core`, - keyword: `goto`, - goto: 0 - }); - // Fixup the link to the 'then' branch - compiler.getCommandAt(pc).then = compiler.getPc(); - // Process the 'then' branch - compiler.next(); - compiler.compileOne(true); - compiler.addCommand({ - domain: `core`, - keyword: `stop` - }); - // Fixup the 'goto' - compiler.getCommandAt(goto).goto = compiler.getPc(); - } - return true; + return false; }, - // runtime - run: program => { - program.nextPc = program.pc + 1; - program.runScript(program); - return 0; + const command = program[program.pc]; + const value1 = command.value1; + const value2 = command.value2; + const target = program.getSymbolRecord(command.target); + if (target.isVHolder) { + const value = target.value[target.index]; + if (value2) { + const result = program.getValue(value2) - + program.getValue(value1); + target.value[target.index] = { + type: `constant`, + numeric: true, + content: result + }; + } else { + if (!value.numeric && isNaN(value.content)) { + program.nonNumericValueError(command.lino); + } + const result = parseInt(program.getValue(value)) - parseInt(program.getValue(value1)); + target.value[target.index] = { + type: `constant`, + numeric: true, + content: result + }; + } + } else { + program.variableDoesNotHoldAValueError(command.lino, target.name); + } + return command.pc + 1; } }, - Sanitize: { + Toggle: { compile: compiler => { const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const name = compiler.getToken(); + compiler.next(); + if (compiler.isSymbol()) { + const symbolPc = compiler.getSymbolPc(); compiler.next(); compiler.addCommand({ domain: `core`, - keyword: `sanitize`, + keyword: `toggle`, lino, - name + symbol: symbolPc }); return true; } @@ -1768,25 +2018,25 @@ const EasyCoder_Core = { run: program => { const command = program[program.pc]; - const symbolRecord = program.getSymbolRecord(command.name); - const value = symbolRecord.value[symbolRecord.index]; - value.content = JSON.stringify(JSON.parse(value.content)); + const symbol = program[command.symbol]; + if (symbol.isVHolder) { + const handler = program.domain[symbol.domain]; + const content = handler.value.get(program, symbol.value[symbol.index]).content; + handler.value.put(symbol, { + type: `boolean`, + content: !content + }); + } else { + program.variableDoesNotHoldAValueError(command.lino, symbol.name); + } return command.pc + 1; } }, - Script: { + Variable: { compile: compiler => { - const program = compiler.getProgram(); - program.script = compiler.nextToken(); - compiler.script = program.script; - if (EasyCoder.scripts[program.script]) { - delete compiler.script; - throw new Error(`Script '${program.script}' is already running.`); - } - EasyCoder.scripts[program.script] = program; - compiler.next(); + compiler.compileVariable(`core`, `variable`, true); return true; }, @@ -1795,430 +2045,2592 @@ const EasyCoder_Core = { } }, - Send: { + Wait: { compile: compiler => { const lino = compiler.getLino(); - let message = ``; - if (!compiler.nextTokenIs(`to`)) { - message = compiler.getValue(); - } - if (compiler.tokenIs(`to`)) { - var recipient; - if (compiler.nextTokenIs(`parent`)) { - recipient = `parent`; - } else if (compiler.isSymbol) { - const moduleRecord = compiler.getSymbolRecord(); - if (moduleRecord.keyword !== `module`) { - throw new Error(`'${moduleRecord.name}' is not a module`); - } - recipient = moduleRecord.name; - } + compiler.next(); + const value = compiler.getValue(compiler); + const scale = compiler.getToken(); + let multiplier = 1000; + switch (scale) { + case `milli`: + case `millis`: compiler.next(); - compiler.addCommand({ - domain: `core`, - keyword: `send`, - lino, - message, - recipient - }); + multiplier = 1; + break; + case `tick`: + case `ticks`: + compiler.next(); + multiplier = 10; + break; + case `second`: + case `seconds`: + compiler.next(); + multiplier = 1000; + break; + case `minute`: + case `minutes`: + compiler.next(); + multiplier = 60000; + break; } + compiler.addCommand({ + domain: `core`, + keyword: `wait`, + lino, + value, + multiplier + }); return true; }, run: program => { const command = program[program.pc]; - const message = program.getValue(command.message); - if (command.recipient === `parent`) { - if (program.parent) { - const parent = EasyCoder.scripts[program.parent]; - const onMessage = parent.onMessage; - if (onMessage) { - parent.message = message; - parent.run(parent.onMessage); - } - } - } else { - const recipient = program.getSymbolRecord(command.recipient); - if (recipient.program) { - let rprog = EasyCoder.scripts[recipient.program]; - rprog.message = message; - rprog.run(rprog.onMessage); + const value = program.getValue(command.value); + setTimeout(function () { + if (program.run) { + program.run(command.pc + 1); } - } - return command.pc + 1; + }, value * command.multiplier); + return 0; } }, - Set: { + While: { compile: compiler => { - let name; const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (!targetRecord.isVHolder) { - return false; - } - if (compiler.nextTokenIs(`to`)) { - const token = compiler.nextToken(); - if ([`array`, `object`].includes(token)) { - compiler.next(); - compiler.addCommand({ + compiler.next(); + const condition = compiler.getCondition(); + const pc = compiler.getPc(); + compiler.addCommand({ + domain: `core`, + keyword: `while`, + lino, + condition + }); + // Skip when test fails + const skip = compiler.getPc(); + compiler.addCommand({ + domain: `core`, + keyword: `goto`, + goto: 0 + }); + // Do the body + compiler.compileOne(); + // Repeat the test + compiler.addCommand({ + domain: `core`, + keyword: `goto`, + goto: pc + }); + // Fixup the 'goto' on completion + compiler.getCommandAt(skip).goto = compiler.getPc(); + return true; + }, + + run: program => { + const command = program[program.pc]; + const condition = command.condition; + const test = program.condition.test(program, condition); + if (test) { + return program.pc + 2; + } + return program.pc + 1; + } + }, + + getHandler: (name) => { + switch (name) { + case `add`: + return EasyCoder_Core.Add; + case `alias`: + return EasyCoder_Core.Alias; + case `append`: + return EasyCoder_Core.Append; + case `begin`: + return EasyCoder_Core.Begin; + case `callback`: + return EasyCoder_Core.Callback; + case `clear`: + return EasyCoder_Core.Clear; + case `close`: + return EasyCoder_Core.Close; + case `continue`: + return EasyCoder_Core.Continue; + case `debug`: + return EasyCoder_Core.Debug; + case `decode`: + return EasyCoder_Core.Decode; + case `divide`: + return EasyCoder_Core.Divide; + case `dummy`: + return EasyCoder_Core.Dummy; + case `encode`: + return EasyCoder_Core.Encode; + case `end`: + return EasyCoder_Core.End; + case `exit`: + return EasyCoder_Core.Exit; + case `filter`: + return EasyCoder_Core.Filter; + case `fork`: + return EasyCoder_Core.Fork; + case `go`: + case `goto`: + return EasyCoder_Core.Go; + case `gosub`: + return EasyCoder_Core.Gosub; + case `if`: + return EasyCoder_Core.If; + case `import`: + return EasyCoder_Core.Import; + case `index`: + return EasyCoder_Core.Index; + case `load`: + return EasyCoder_Core.Load; + case `module`: + return EasyCoder_Core.Module; + case `multiply`: + return EasyCoder_Core.Multiply; + case `negate`: + return EasyCoder_Core.Negate; + case `on`: + return EasyCoder_Core.On; + case `print`: + return EasyCoder_Core.Print; + case `put`: + return EasyCoder_Core.Put; + case `replace`: + return EasyCoder_Core.Replace; + case `require`: + return EasyCoder_Core.Require; + case `return`: + return EasyCoder_Core.Return; + case `run`: + return EasyCoder_Core.Run; + case `sanitize`: + return EasyCoder_Core.Sanitize; + case `script`: + return EasyCoder_Core.Script; + case `send`: + return EasyCoder_Core.Send; + case `set`: + return EasyCoder_Core.Set; + case `sort`: + return EasyCoder_Core.Sort; + case `split`: + return EasyCoder_Core.Split; + case `stop`: + return EasyCoder_Core.Stop; + case `take`: + return EasyCoder_Core.Take; + case `toggle`: + return EasyCoder_Core.Toggle; + case `variable`: + return EasyCoder_Core.Variable; + case `wait`: + return EasyCoder_Core.Wait; + case `while`: + return EasyCoder_Core.While; + default: + return false; + } + }, + + run: program => { + // Look up the appropriate handler and call it + // If it's not there throw an error + const command = program[program.pc]; + const handler = EasyCoder_Core.getHandler(command.keyword); + if (!handler) { + program.runtimeError(command.lino, + `Unknown keyword '${command.keyword}' in 'core' package`); + } + return handler.run(program); + }, + + isNegate: (compiler) => { + const token = compiler.getToken(); + if (token === `not`) { + compiler.next(); + return true; + } + return false; + }, + + value: { + + compile: compiler => { + if (compiler.isSymbol()) { + const name = compiler.getToken(); + const symbolRecord = compiler.getSymbolRecord(); + switch (symbolRecord.keyword) { + case `module`: + compiler.next(); + return { + domain: `core`, + type: `module`, + name + }; + case `variable`: + const type = compiler.nextToken(); + if ([`format`, `modulo`].includes(type)) { + const value = compiler.getNextValue(); + return { domain: `core`, - keyword: `set`, - lino, - request: `setVarTo`, - target: targetRecord.name, - type: token - }); - return true; - } - const value = []; - while (true) { - compiler.mark(); - try { - value.push(compiler.getValue()); - } catch (err) { - compiler.rewind(); - break; - } + type, + name, + value + }; } - compiler.addCommand({ + return { domain: `core`, - keyword: `set`, - lino, - request: `setArray`, - target: targetRecord.name, - value - }); - return true; + type: `symbol`, + name + }; } - compiler.addCommand({ - domain: `core`, - keyword: `set`, - lino, - request: `setBoolean`, - target: targetRecord.name - }); - return true; + return null; } - switch (compiler.getToken()) { - case `ready`: + + var token = compiler.getToken(); + if (token === `true`) { compiler.next(); - compiler.addCommand({ + return { domain: `core`, - keyword: `set`, - lino, - request: `setReady` - }); - return true; - case `element`: - const index = compiler.getNextValue(); + type: `boolean`, + content: true + }; + } + if (token === `false`) { + compiler.next(); + return { + domain: `core`, + type: `boolean`, + content: false + }; + } + if (token === `random`) { + compiler.next(); + const range = compiler.getValue(); + return { + domain: `core`, + type: `random`, + range + }; + } + if (token === `cos`) { + compiler.next(); + const angle_c = compiler.getValue(); + compiler.skip(`radius`); + const radius_c = compiler.getValue(); + return { + domain: `core`, + type: `cos`, + angle_c, + radius_c + }; + } + if (token === `sin`) { + compiler.next(); + const angle_s = compiler.getValue(); + compiler.skip(`radius`); + const radius_s = compiler.getValue(); + return { + domain: `core`, + type: `sin`, + angle_s, + radius_s + }; + } + if (token === `tan`) { + compiler.next(); + const angle_t = compiler.getValue(); + compiler.skip(`radius`); + const radius_t = compiler.getValue(); + return { + domain: `core`, + type: `tan`, + angle_t, + radius_t + }; + } + if ([`now`, `today`, `newline`, `break`, `empty`, `uuid`].includes(token)) { + compiler.next(); + return { + domain: `core`, + type: token + }; + } + if (token === `date`) { + const value = compiler.getNextValue(); + return { + domain: `core`, + type: `date`, + value + }; + } + if ([`encode`, `decode`, `lowercase`, `hash`, `reverse`].includes(token)) { + compiler.next(); + const value = compiler.getValue(); + return { + domain: `core`, + type: token, + value + }; + } + if (token === `element`) { + const element = compiler.getNextValue(); if (compiler.tokenIs(`of`)) { if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - if (compiler.nextTokenIs(`to`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `core`, - keyword: `set`, - lino, - request: `setElement`, - target: targetRecord.name, - index, - value - }); - return true; - } + const symbolRecord = compiler.getSymbolRecord(); + compiler.next(); + if (symbolRecord.keyword === `variable`) { + return { + domain: `core`, + type: `element`, + element, + symbol: symbolRecord.name + }; } } } - break; - case `property`: - name = compiler.getNextValue(); + return null; + } + if (token === `property`) { + const property = compiler.getNextValue(); if (compiler.tokenIs(`of`)) { if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - if (compiler.nextTokenIs(`to`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `core`, - keyword: `set`, - lino, - request: `setProperty`, - target: targetRecord.name, - name, - value - }); - return true; - } + const symbolRecord = compiler.getSymbolRecord(); + compiler.next(); + if (symbolRecord.keyword === `variable`) { + return { + domain: `core`, + type: `property`, + property, + symbol: symbolRecord.name + }; } } } - break; - case `arg`: - name = compiler.getNextValue(); + return null; + } + if (token === `arg`) { + const value = compiler.getNextValue(); if (compiler.tokenIs(`of`)) { if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (compiler.nextTokenIs(`to`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `core`, - keyword: `set`, - lino, - request: `setArg`, - target: targetRecord.name, - name, - value - }); - return true; - } + const target = compiler.getSymbolRecord(); + compiler.next(); + return { + domain: `core`, + type: `arg`, + value, + target: target.name + }; } } } + if ([`character`, `char`].includes(token)) { + let index = compiler.getNextValue(); + if (compiler.tokenIs(`of`)) { + let value = compiler.getNextValue(); + return { + domain: `core`, + type: `char`, + index, + value + }; + } + } if (compiler.tokenIs(`the`)) { compiler.next(); } - switch (compiler.getToken()) { + const type = compiler.getToken(); + switch (type) { case `elements`: - compiler.next(); - if (compiler.tokenIs(`of`)) { - compiler.next(); - if (!compiler.isSymbol()) { - throw new Error(`Unknown variable '${compiler.getToken()}'`); - } - const symbol = compiler.getToken(); - compiler.next(); - if (compiler.tokenIs(`to`)) { + if ([`of`, `in`].includes(compiler.nextToken())) { + if (compiler.nextIsSymbol()) { + const name = compiler.getToken(); compiler.next(); - // get the value - const value = compiler.getValue(); - compiler.addCommand({ + return { domain: `core`, - keyword: `set`, - lino, - request: `setElements`, - symbol, - value - }); - return true; + type, + name + }; } } break; - case `encoding`: - if (compiler.nextTokenIs(`to`)) { - const encoding = compiler.getNextValue(); - compiler.addCommand({ - domain: `core`, - keyword: `set`, - request: `encoding`, - lino, - encoding - }); - return true; - } - compiler.addWarning(`Unknown encoding option`); - break; - case `payload`: + case `index`: if (compiler.nextTokenIs(`of`)) { if (compiler.nextIsSymbol()) { - const callbackRecord = compiler.getSymbolRecord(); - if (callbackRecord.keyword === `callback`) { - if (compiler.nextTokenIs(`to`)) { - const payload = compiler.getNextValue(); - compiler.addCommand({ - domain: `core`, - keyword: `set`, - request: `setPayload`, - lino, - callback: callbackRecord.name, - payload - }); - return true; - } - } - } - } - } - return false; - }, - - run: program => { - let targetRecord; - const command = program[program.pc]; - switch (command.request) { - case `setBoolean`: - const target = program.getSymbolRecord(command.target); - if (target.isVHolder) { - target.value[target.index] = { - type: `boolean`, - content: true - }; - command.numeric = false; - } else { - program.variableDoesNotHoldAValueError(command.lino, target.name); + if (compiler.peek() === `in`) { + const value1 = compiler.getValue(); + const value2 = compiler.getNextValue(); + return { + domain: `core`, + type: `indexOf`, + value1, + value2 + }; + } else { + const name = compiler.getToken(); + compiler.next(); + return { + domain: `core`, + type, + name + }; + } + } else { + const value1 = compiler.getValue(); + if (compiler.tokenIs(`in`)) { + const value2 = compiler.getNextValue(); + return { + domain: `core`, + type: `indexOf`, + value1, + value2 + }; + } + } } break; - case `setReady`: - let parent = EasyCoder.scripts[program.parent]; - if (parent) { - parent.run(parent.nextPc); - parent.nextPc = 0; - program.unblocked = true; + case `value`: + if (compiler.nextTokenIs(`of`)) { + compiler.next(); + const value = compiler.getValue(); + return { + domain: `core`, + type: `valueOf`, + value + }; } break; - case `setArray`: - targetRecord = program.getSymbolRecord(command.target); - targetRecord.elements = command.value.length; - targetRecord.value = command.value; - break; - case `encoding`: - program.encoding = program.getValue(command.encoding); + case `length`: + if (compiler.nextTokenIs(`of`)) { + compiler.next(); + const value = compiler.getValue(); + return { + domain: `core`, + type: `lengthOf`, + value + }; + } break; - case `setElements`: - const symbol = program.getSymbolRecord(command.symbol); - const oldCount = symbol.elements; - symbol.elements = program.getValue(command.value); - symbol.index = 0; - if (symbol.elements > oldCount) { - for (var n = oldCount; n < symbol.elements; n++) { - symbol.value.push({}); - symbol.element.push(null); + case `left`: + case `right`: + try { + const count = compiler.getNextValue(); + if (compiler.tokenIs(`of`)) { + const value = compiler.getNextValue(); + return { + domain: `core`, + type, + count, + value + }; } - } else { - symbol.value = symbol.value.slice(0, symbol.elements); - symbol.element = symbol.element.slice(0, symbol.elements); + } catch (err) { + return null; } break; - case `setElement`: - targetRecord = program.getSymbolRecord(command.target); - const index = program.getValue(command.index); - const elements = JSON.parse(program.getValue(targetRecord.value[targetRecord.index])); - const value = program.getValue(command.value); - elements[index] = JSON.parse(value); - targetRecord.value[targetRecord.index].content = JSON.stringify(elements); + case `from`: + const from = compiler.getNextValue(); + const to = compiler.tokenIs(`to`) ? compiler.getNextValue() : null; + if (compiler.tokenIs(`of`)) { + const value = compiler.getNextValue(); + return { + domain: `core`, + type, + from, + to, + value + }; + } break; - case `setProperty`: - // This is the name of the property - const itemName = program.getValue(command.name); - // This is the value of the property - let itemValue = program.getValue(command.value); - if (program.isJsonString(itemValue)) { - itemValue = JSON.parse(itemValue); + case `position`: + let nocase = false; + if (compiler.nextTokenIs(`nocase`)) { + nocase = true; + compiler.next(); } - targetRecord = program.getSymbolRecord(command.target); - let targetValue = targetRecord.value[targetRecord.index]; - // Get the existing JSON - if (!targetValue.numeric) { - let content = targetValue.content; - if (content === ``) { - content = {}; + if (compiler.tokenIs(`of`)) { + var last = false; + if (compiler.nextTokenIs(`the`)) { + if (compiler.nextTokenIs(`last`)) { + compiler.next(); + last = true; + } } - else if (program.isJsonString(content)) { - content = JSON.parse(content); + const needle = compiler.getValue(); + if (compiler.tokenIs(`in`)) { + const haystack = compiler.getNextValue(); + return { + domain: `core`, + type: `position`, + needle, + haystack, + last, + nocase + }; } - // Set the property - content[itemName] = itemValue; - // Put it back - content = JSON.stringify(content); - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content - }; } break; - case `setPayload`: - program.getSymbolRecord(command.callback).payload = program.getValue(command.payload); - break; - case `setArg`: - const name = program.getValue(command.name); - targetRecord = program.getSymbolRecord(command.target); - targetRecord[name] = program.getValue(command.value); + case `payload`: + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const callbackRecord = compiler.getSymbolRecord(); + if (callbackRecord.keyword === `callback`) { + compiler.next(); + return { + domain: `core`, + type: `payload`, + callback: callbackRecord.name + }; + } + } + } break; - case `setVarTo`: - targetRecord = program.getSymbolRecord(command.target); - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content: command.type === `array` ? `[]` : `{}` + case `message`: + case `error`: + case `millisecond`: + compiler.next(); + return { + domain: `core`, + type }; - break; - default: - break; - } - return command.pc + 1; - } - }, - - Sort: { - compile: compiler => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const arrayRecord = compiler.getSymbolRecord(); - if (compiler.nextTokenIs(`with`)) { - const func = compiler.nextToken(); - compiler.next(); - compiler.addCommand({ - domain: `core`, - keyword: `sort`, - lino, - array: arrayRecord.name, - func - }); - return true; - } } - return false; + return null; }, - run: program => { - const command = program[program.pc]; - const variable = program.getSymbolRecord(command.array); - const value = variable.value[variable.index].content; - const func = program.getSymbolRecord(command.func).pc; - try { - const array = JSON.parse(value); - array.sort(function (a, b) { - variable.a = a; - variable.b = b; - program.run(func); - return variable.v; - }); - variable.value[variable.index].content = JSON.stringify(array); - } catch (err) { - program.runtimeError(command.lino, `Can't parse this array`); - } - return command.pc + 1; - } - }, - - Split: { + get: (program, value) => { + switch (value.type) { + case `boolean`: + return { + type: `boolean`, + numeric: false, + content: value.content + }; + case `elements`: + return { + type: `constant`, + numeric: true, + content: program.getSymbolRecord(value.name).elements + }; + case `index`: + return { + type: `constant`, + numeric: true, + content: program.getSymbolRecord(value.name).index + }; + case `random`: + const range = program.evaluate(value.range); + return { + type: `constant`, + numeric: true, + content: Math.floor((Math.random() * range.content)) + }; + case `cos`: + const angle_c = program.getValue(value.angle_c); + const radius_c = program.getValue(value.radius_c); + return { + type: `constant`, + numeric: true, + content: parseInt(Math.cos(parseFloat(angle_c) * 0.01745329) * radius_c, 10) + }; + case `sin`: + const angle_s = program.getValue(value.angle_s); + const radius_s = program.getValue(value.radius_s); + return { + type: `constant`, + numeric: true, + content: parseInt(Math.sin(parseFloat(angle_s) * 0.01745329) * radius_s, 10) + }; + case `tan`: + const angle_t = program.getValue(value.angle_t); + const radius_t = program.getValue(value.radius_t); + return { + type: `constant`, + numeric: true, + content: parseInt(Math.tan(parseFloat(angle_t) * 0.01745329) * radius_t, 10) + }; + case `valueOf`: + const v = parseInt(program.getValue(value.value)); + return { + type: `constant`, + numeric: true, + content: v ? v : 0 + }; + case `lengthOf`: + return { + type: `constant`, + numeric: true, + content: program.getValue(value.value).length + }; + case `left`: + return { + type: `constant`, + numeric: false, + content: program.getValue(value.value).substr(0, program.getValue(value.count)) + }; + case `right`: + const str = program.getValue(value.value); + return { + type: `constant`, + numeric: false, + content: str.substr(str.length - program.getValue(value.count)) + }; + case `from`: + const from = program.getValue(value.from); + const to = value.to ? program.getValue(value.to) : null; + const fstr = program.getValue(value.value); + return { + type: `constant`, + numeric: false, + content: to ? fstr.substr(from, to) : fstr.substr(from) + }; + case `position`: + let needle = program.getValue(value.needle); + let haystack = program.getValue(value.haystack); + if (value.nocase) { + needle = needle.toLowerCase(); + haystack = haystack.toLowerCase(); + } + return { + type: `constant`, + numeric: true, + content: value.last ? haystack.lastIndexOf(needle) : haystack.indexOf(needle) + }; + case `payload`: + return { + type: `constant`, + numeric: false, + content: program.getSymbolRecord(value.callback).payload + }; + case `modulo`: + const symbolRecord = program.getSymbolRecord(value.name); + const modval = program.evaluate(value.value); + return { + type: `constant`, + numeric: true, + content: symbolRecord.value[symbolRecord.index].content % modval.content + }; + case `format`: + const fmtRecord = program.getSymbolRecord(value.name); + const fmtValue = program.getValue(fmtRecord.value[fmtRecord.index]) * 1000; + try { + const spec = JSON.parse(program.getValue(value.value)); + switch (spec.mode) { + case `time`: + + return { + type: `constant`, + numeric: true, + content: new Date(fmtValue).toLocaleTimeString(spec.locale, spec.options) + }; + case `date`: + default: + const date = new Date(fmtValue); + const content = (spec.format === `iso`) + ? `${date.getFullYear()}-${date.getMonth()+1}-${date.getDate()}` + : date.toLocaleDateString(spec.locale, spec.options); + return { + type: `constant`, + numeric: true, + content + }; + } + } catch (err) { + program.runtimeError(program[program.pc].lino, `Can't parse ${value.value}`); + return null; + } + case `empty`: + return { + type: `constant`, + numeric: false, + content: `` + }; + case `now`: + return { + type: `constant`, + numeric: true, + content: Math.floor(Date.now() / 1000) + }; + case `millisecond`: + return { + type: `constant`, + numeric: true, + content: Math.floor(Date.now()) + }; + case `today`: + const date = new Date(); + date.setHours(0, 0, 0, 0); + return { + type: `constant`, + numeric: true, + content: Math.floor(date.getTime() / 1000) + }; + case `date`: + content = Date.parse(program.getValue(value.value)) / 1000; + if (isNaN(content)) { + program.runtimeError(program[program.pc].lino, `Invalid date format; expecting 'yyyy-mm-dd'`); + return null; + } + return { + type: `constant`, + numeric: true, + content + }; + case `newline`: + return { + type: `constant`, + numeric: false, + content: `\n` + }; + case `break`: + return { + type: `constant`, + numeric: false, + content: `
` + }; + case `uuid`: + return { + type: `constant`, + numeric: false, + content: `xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`.replace(/[xy]/g, function(c) { + var r = Math.random() * 16 | 0, v = c == `x` ? r : (r & 0x3 | 0x8); + return v.toString(16); + }) + }; + case `encode`: + return { + type: `constant`, + numeric: false, + content: program.encode(program.getValue(value.value)) + }; + case `decode`: + return { + type: `constant`, + numeric: false, + content: program.decode(program.getValue(value.value)) + }; + case `reverse`: + return { + type: `constant`, + numeric: false, + content: program.getValue(value.value).split(``).reverse().join(``) + }; + case `lowercase`: + return { + type: `constant`, + numeric: false, + content: program.getValue(value.value).toLowerCase() + }; + case `hash`: + const hashval = program.getValue(value.value); + let hash = 0; + if (hashval.length === 0) return hash; + for (let i = 0; i < hashval.length; i++) { + const chr = hashval.charCodeAt(i); + hash = ((hash << 5) - hash) + chr; + // hash |= 0; // Convert to 32bit integer + } + return { + type: `constant`, + numeric: true, + content: hash + }; + case `element`: + const element = program.getValue(value.element); + const elementRecord = program.getSymbolRecord(value.symbol); + var elementContent = ``; + try { + elementContent = JSON.parse(program.getValue(elementRecord.value[elementRecord.index]))[element]; + } catch (err) { + program.runtimeError(program[program.pc].lino, `Can't parse JSON`); + return null; + } + return { + type: `constant`, + numeric: false, + content: typeof elementContent === `object` ? + JSON.stringify(elementContent) : elementContent + }; + case `property`: + const property = program.getValue(value.property); + const propertyRecord = program.getSymbolRecord(value.symbol); + let propertyContent = program.getValue(propertyRecord.value[propertyRecord.index]); + var content = ``; + if (property && propertyContent) { + if (typeof propertyContent === `object`) { + content = propertyContent[property]; + } else if ([`{`, `]`].includes(propertyContent.charAt(0))) { + try { + content = JSON.parse(propertyContent)[property]; + } catch (err) { + console.log(`Can't parse '${propertyContent}': ${err.message}`); + } + } + } + return { + type: `constant`, + numeric: !Array.isArray(content) && !isNaN(content), + content: typeof content === `object` ? JSON.stringify(content) : content + }; + case `module`: + const module = program.getSymbolRecord(value.name); + return { + type: `boolean`, + numeric: false, + content: module.program + }; + case `message`: + content = program.message; + return { + type: `constant`, + numeric: false, + content + }; + case `error`: + content = program.errorMessage; + return { + type: `constant`, + numeric: false, + content + }; + case `indexOf`: + const value1 = program.getValue(value.value1); + const value2 = program.getValue(value.value2); + try { + content = JSON.parse(value2).indexOf(value1); + return { + type: `constant`, + numeric: true, + content + }; + } catch (err) { + program.runtimeError(program[program.pc].lino, `Can't parse ${value2}`); + } + break; + case `arg`: + const name = program.getValue(value.value); + const target = program.getSymbolRecord(value.target); + content = target[name]; + return { + type: `constant`, + numeric: !isNaN(content), + content + }; + case `char`: + let index = program.getValue(value.index); + let string = program.getValue(value.value); + return { + type: `constant`, + numeric: false, + content: string[index] + }; + } + return null; + }, + + put: (symbol, value) => { + symbol.value[symbol.index] = value; + } + }, + + condition: { + + compile: compiler => { + if (compiler.isSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.keyword === `module`) { + if (compiler.nextTokenIs(`is`)) { + let sense = true; + if (compiler.nextTokenIs(`not`)) { + compiler.next(); + sense = false; + } + if (compiler.tokenIs(`running`)) { + compiler.next(); + return { + domain: `core`, + type: `moduleRunning`, + name: symbolRecord.name, + sense + }; + } + } + return null; + } + } + if (compiler.tokenIs(`not`)) { + const value = compiler.getNextValue(); + return { + domain: `core`, + type: `not`, + value + }; + } + try { + const value1 = compiler.getValue(); + const token = compiler.getToken(); + if (token === `includes`) { + const value2 = compiler.getNextValue(); + return { + domain: `core`, + type: `includes`, + value1, + value2 + }; + } + if (token === `is`) { + compiler.next(); + const negate = EasyCoder_Core.isNegate(compiler); + const test = compiler.getToken(); + switch (test) { + case `numeric`: + compiler.next(); + return { + domain: `core`, + type: `numeric`, + value1, + negate + }; + case `even`: + compiler.next(); + return { + domain: `core`, + type: `even`, + value1 + }; + case `odd`: + compiler.next(); + return { + domain: `core`, + type: `odd`, + value1 + }; + case `greater`: + compiler.next(); + if (compiler.tokenIs(`than`)) { + compiler.next(); + const value2 = compiler.getValue(); + return { + domain: `core`, + type: `greater`, + value1, + value2, + negate + }; + } + return null; + case `less`: + compiler.next(); + if (compiler.tokenIs(`than`)) { + compiler.next(); + const value2 = compiler.getValue(); + return { + domain: `core`, + type: `less`, + value1, + value2, + negate + }; + } + return null; + default: + const value2 = compiler.getValue(); + return { + domain: `core`, + type: `is`, + value1, + value2, + negate + }; + } + } else if (value1) { + // It's a boolean if + return { + domain: `core`, + type: `boolean`, + value: value1 + }; + } + } catch (err) { + compiler.warning(`Can't get a value`); + return 0; + } + return null; + }, + + test: (program, condition) => { + var comparison; + switch (condition.type) { + case `boolean`: + return program.getValue(condition.value); + case `numeric`: + let v = program.getValue(condition.value1); + let test = v === ` ` || isNaN(v); + return condition.negate ? test : !test; + case `even`: + return (program.getValue(condition.value1) % 2) === 0; + case `odd`: + return (program.getValue(condition.value1) % 2) === 1; + case `is`: + comparison = program.compare(program, condition.value1, condition.value2); + return condition.negate ? comparison !== 0 : comparison === 0; + case `greater`: + comparison = program.compare(program, condition.value1, condition.value2); + return condition.negate ? comparison <= 0 : comparison > 0; + case `less`: + comparison = program.compare(program, condition.value1, condition.value2); + return condition.negate ? comparison >= 0 : comparison < 0; + case `not`: + return !program.getValue(condition.value); + case `moduleRunning`: + let moduleRecord = program.getSymbolRecord(condition.name); + if (EasyCoder.scripts.hasOwnProperty(moduleRecord.program) ) { + let p = EasyCoder.scripts[moduleRecord.program]; + return condition.sense ? p.running : !p.running; + } + return !condition.sense; + case `includes`: + const value1 = JSON.parse(program.getValue(condition.value1)); + const value2 = program.getValue(condition.value2); + return value1.includes(value2); + } + return false; + } + } +}; +const EasyCoder_Browser = { + + name: `EasyCoder_Browser`, + + A: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `a`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Alert: { + + compile: (compiler) => { + const lino = compiler.getLino(); + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `alert`, + lino, + value + }); + return true; + }, + + run: (program) => { + const command = program[program.pc]; + const value = program.getFormattedValue(command.value); + alert(value); + return command.pc + 1; + } + }, + + Attach: { + + compile: (compiler) => { + const lino = compiler.getLino(); + compiler.next(); + if (compiler.isSymbol()) { + // const symbol = compiler.getProgram()[compiler.getSymbol().pc]; + const symbol = compiler.getSymbolRecord(); + let type = symbol.keyword; + switch (type) { + case `a`: + case `blockquote`: + case `button`: + case `canvas`: + case `div`: + case `fieldset`: + case `file`: + case `form`: + case `h1`: + case `h2`: + case `h3`: + case `h4`: + case `h5`: + case `h6`: + case `image`: + case `img`: + case `input`: + case `label`: + case `legend`: + case `li`: + case `option`: + case `p`: + case `pre`: + case `select`: + case `span`: + case `table`: + case `td`: + case `text`: + case `textarea`: + case `tr`: + case `ul`: + compiler.next(); + if (compiler.tokenIs(`to`)) { + let cssID = null; + if (compiler.nextTokenIs(`body`)) { + if (type=== `div`) { + cssId = `body`; + compiler.next(); + } else { + throw Error(`Body variable must be a div`); + } + } + else cssId = compiler.getValue(); + let onError = 0; + if (compiler.tokenIs(`or`)) { + compiler.next(); + onError = compiler.getPc() + 1; + compiler.completeHandler(); + } + compiler.addCommand({ + domain: `browser`, + keyword: `attach`, + lino, + type, + symbol: symbol.name, + cssId, + onError + }); + return true; + } + break; + default: + compiler.addWarning(`type '${symbol.keyword}' not recognized in browser 'attach'`); + return false; + } + } + compiler.addWarning(`Unrecognised syntax in 'attach'`); + return false; + }, + + run: (program) => { + const command = program[program.pc]; + let content = null; + let element = null; + if (command.cssId === `body`) { + element = document.body; + } else { + content = program.value.evaluate(program, command.cssId).content; + element = document.getElementById(content); + } + if (!element) { + if (command.onError) { + program.run(command.onError); + } else { + program.runtimeError(command.lino, `No such element: '${content}'`); + } + return 0; + } + const target = program.getSymbolRecord(command.symbol); + target.element[target.index] = element; + target.value[target.index] = { + type: `constant`, + numeric: false, + content + }; + if (command.type === `popup`) { + // Register a popup + program.popups.push(element.id); + // Handle closing of the popup + window.onclick = function (event) { + if (program.popups.includes(event.target.id)) { + event.target.style.display = `none`; + } + }; + } + return command.pc + 1; + } + }, + + Audioclip: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `audioclip`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + BLOCKQUOTE: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `blockquote`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + BUTTON: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `button`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + CANVAS: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `canvas`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Clear: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextTokenIs(`body`)) { + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `clear`, + lino, + name: null + }); + return true; + } + if (compiler.isSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.extra === `dom`) { + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `clear`, + lino, + name: symbolRecord.name + }); + return true; + } + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + if (command.name) { + const targetRecord = program.getSymbolRecord(command.name); + const target = targetRecord.element[targetRecord.index]; + switch (targetRecord.keyword) { + case `input`: + case `textarea`: + target.value = ``; + break; + default: + target.innerHTML = ``; + break; + } + } else { + document.body.innerHTML = ``; + } + return command.pc + 1; + } + }, + + Convert: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextTokenIs(`whitespace`)) { + if (compiler.nextTokenIs(`in`)) { + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.isVHolder) { + if (compiler.nextTokenIs(`to`)) { + const mode = compiler.nextToken(); + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `convert`, + lino, + name: symbolRecord.name, + mode + }); + return true; + } + } + } + } + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const targetRecord = program.getSymbolRecord(command.name); + const content = targetRecord.value[targetRecord.index].content; + let value = content; + switch (command.mode) { + case `print`: + value = value.split(`%0a`).join(`\n`).split(`%0A`).join(`\n`).split(`%0d`).join(``).split(`$0D`).join(``); + break; + case `html`: + value = value.split(`%0a`).join(`
`).split(`%0A`).join(`
`).split(`%0d`).join(``).split(`$0D`).join(``); + break; + } + targetRecord.value[targetRecord.index].content = value; + return command.pc + 1; + } + }, + + Create: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + const keyword = symbolRecord.keyword; + if (keyword === `audioclip`) { + if (compiler.nextTokenIs(`from`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `create`, + type: `audioclip`, + name: symbolRecord.name, + lino, + value + }); + return true; + } + return false; + } + if ([`a`, + `blockquote`, + `button`, + `canvas`, + `div`, + `fieldset`, + `file`, + `form`, + `h1`, + `h2`, + `h3`, + `h4`, + `h5`, + `h6`, + `hr`, + `image`, + `img`, + `input`, + `label`, + `legend`, + `li`, + `option`, + `p`, + `pre`, + `progress`, + `select`, + `span`, + `table`, + `tr`, + `td`, + `text`, + `textarea`, + `ul` + ].includes(keyword)) { + if (compiler.nextTokenIs(`in`)) { + if (compiler.nextTokenIs(`body`)) { + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `create`, + lino, + name: symbolRecord.name, + parent: `body` + }); + return true; + } + if (compiler.isSymbol()) { + const parentRecord = compiler.getSymbolRecord(); + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `create`, + lino, + name: symbolRecord.name, + parent: parentRecord.name + }); + return true; + } + } else { + const imports = compiler.imports; + if (imports && imports.length > 0) { + // This section is used by Codex to force run in Run panel, which must be the first import + compiler.addCommand({ + domain: `browser`, + keyword: `create`, + lino, + name: symbolRecord.name, + parent: imports[0], + imported: true + }); + return true; + } else { + compiler.addCommand({ + domain: `browser`, + keyword: `create`, + lino, + name: symbolRecord.name, + parent: `body` + }); + return true; + } + } + } + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const targetRecord = program.getSymbolRecord(command.name); + switch (command.type) { + case `audioclip`: + targetRecord.value[targetRecord.index] = command.value; + break; + default: + let parent; + if (command.parent === `body`) { + parent = document.body; + } else { + const p = command.imported ? EasyCoder.scripts[program.parent] : program; + const parentRecord = p.getSymbolRecord(command.parent); + if (!parentRecord.element[parentRecord.index]) { + program.runtimeError(command.pc, `Element ${parentRecord.name} does not exist.`); + } + parent = parentRecord.element[parentRecord.index]; + } + targetRecord.element[targetRecord.index] = document.createElement(targetRecord.keyword); + targetRecord.element[targetRecord.index].id = + `ec-${targetRecord.name}-${targetRecord.index}-${EasyCoder.elementId++}`; + if (targetRecord.keyword === `a`) { + targetRecord.element[targetRecord.index].setAttribute(`href`, `#`); + } + parent.appendChild(targetRecord.element[targetRecord.index]); + break; + } + return command.pc + 1; + } + }, + + Disable: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const symbol = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `disable`, + lino, + symbol + }); + return true; + } + compiler.addWarning(`Unrecognised syntax in 'disable'`); + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const symbol = program.getSymbolRecord(command.symbol); + const target = document.getElementById(symbol.value[symbol.index].content); + target.disabled = `true`; + return command.pc + 1; + } + }, + + DIV: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `div`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Enable: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const symbol = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `enable`, + lino, + symbol + }); + return true; + } + compiler.addWarning(`Unrecognised syntax in 'enable'`); + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const symbol = program.getSymbolRecord(command.symbol); + const target = document.getElementById(symbol.value[symbol.index].content); + target.disabled = false; + return command.pc + 1; + } + }, + + FIELDSET: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `fieldset`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + FILE: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `file`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Focus: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const symbol = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `focus`, + lino, + symbol + }); + return true; + } + compiler.addWarning(`Unrecognised syntax in 'focus'`); + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const symbol = program.getSymbolRecord(command.symbol); + const element = symbol.element[symbol.index]; + element.focus(); + return command.pc + 1; + } + }, + + FORM: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `form`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Get: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const target = compiler.getToken(); + let targetRecord = compiler.getSymbolRecord(); + if (compiler.nextTokenIs(`from`)) { + if (compiler.nextTokenIs(`storage`)) { + if (compiler.nextTokenIs(`as`)) { + const key = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `get`, + action: `getStorage`, + lino, + target, + key + }); + return true; + } else { + compiler.addCommand({ + domain: `browser`, + keyword: `get`, + action: `listStorage`, + lino, + target + }); + return true; + } + } + if (compiler.isSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.keyword === `select`) { + if (targetRecord.keyword === `option`) { + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `get`, + action: `getOption`, + lino, + target, + select: symbolRecord.name + }); + return true; + } + throw Error(`Invalid variable type`); + } + if (symbolRecord.keyword !== `form`) { + throw Error(`Invalid variable type`); + } + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `get`, + action: `getForm`, + lino, + target, + form: symbolRecord.name + }); + return true; + } + else { + let targetRecord = compiler.getSymbolRecord(target); + } + } + } + compiler.addWarning(`Unrecognised syntax in 'get'`); + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const targetRecord = program.getSymbolRecord(command.target); + switch (command.action) { + case `getForm`: + const formRecord = program.getSymbolRecord(command.form); + const form = document.getElementById(formRecord.value[formRecord.index].content); + const data = new FormData(form); + const content = {}; + for (const entry of data) { + content[entry[0]] = entry[1].replace(/\r/g, ``).replace(/\n/g, `%0a`); + } + targetRecord.value[targetRecord.index] = { + type: `constant`, + numeric: false, + content: JSON.stringify(content) + }; + break; + case `listStorage`: + const items = []; + for (let i = 0, len = window.localStorage.length; i < len; i++) { + items.push(localStorage.key(i)); + } + targetRecord.value[targetRecord.index] = { + type: `constant`, + numeric: false, + content: JSON.stringify(items) + }; + break; + case `getStorage`: + let value = window.localStorage.getItem(program.getValue(command.key)); + if (typeof value === `undefined`) { + value = null; + } + targetRecord.value[targetRecord.index] = { + type: `constant`, + numeric: false, + content: value + }; + break; + case `getOption`: + let selectRecord = program.getSymbolRecord(command.select); + let select = selectRecord.element[selectRecord.index]; + let option = select.options[select.selectedIndex]; + targetRecord.element[targetRecord.index] = option; + break; + } + return command.pc + 1; + } + }, + + H1: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `h1`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + H2: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `h2`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + H3: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `h3`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + H4: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `h4`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + H5: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `h5`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + H6: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `h6`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Highlight: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.extra === `dom`) { + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `highlight`, + lino, + name: symbolRecord.name + }); + return true; + } + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const targetRecord = program.getSymbolRecord(command.name); + const element = targetRecord.element[targetRecord.index]; + element.select(); + return command.pc + 1; + } + }, + + History: { + + compile: (compiler) => { + const lino = compiler.getLino(); + const type = compiler.nextToken(); + switch (type) { + case `push`: + case `set`: + case `replace`: + compiler.next(); + let url = ``; + let state = ``; + let title = ``; + while (true) { + const token = compiler.getToken(); + if (token === `url`) { + url = compiler.getNextValue(); + } else if (token === `state`) { + state = compiler.getNextValue(); + } else if (token === `title`) { + title = compiler.getNextValue(); + } else { + break; + } + } + compiler.addCommand({ + domain: `browser`, + keyword: `history`, + lino, + type, + url, + state, + title + }); + return true; + case `pop`: + case `back`: + case `forward`: + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `history`, + lino, + type + }); + return true; + } + return false; + }, + + run: (program) => { + if (!program.script) { + program.script = `script${Date.now()/1000}`; + } + const command = program[program.pc]; + let state = program.getValue(command.state); + if (!state) { + state = `{"script":"${program.script}"}`; + } + let title = program.getValue(command.title); + const url = program.getValue(command.url); + switch (command.type) { + case `push`: + if (!window.history.state) { + program.runtimeError(command.lino, `No state history; you need to call 'history set' on the parent`); + return 0; + } + window.history.pushState(state, ``, url); + break; + case `set`: + case `replace`: + window.history.replaceState(state, title, url); + break; + case `pop`: + case `back`: + window.history.back(); + break; + case `forward`: + window.history.forward(); + break; + } + return command.pc + 1; + } + }, + + HR: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `hr`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + IMAGE: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `image`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + IMG: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `img`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + INPUT: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `input`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + LABEL: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `label`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + LEGEND: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `legend`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + LI: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `li`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Location: { + + compile: (compiler) => { + const lino = compiler.getLino(); + let newWindow = false; + if (compiler.nextTokenIs(`new`)) { + newWindow = true; + compiler.next(); + } + const location = compiler.getValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `location`, + lino, + location, + newWindow + }); + return true; + }, + + run: (program) => { + const command = program[program.pc]; + const location = program.getValue(command.location); + if (command.newWindow) { + window.open(location, `_blank`); + } else { + window.location = location; + } + return command.pc + 1; + } + }, + + Mail: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextTokenIs(`to`)) { + const to = compiler.getNextValue(); + let subject = ``; + let body = ``; + if (compiler.tokenIs(`subject`)) { + subject = compiler.getNextValue(); + if (compiler.tokenIs(`body`) || compiler.tokenIs(`message`)) { + compiler.next(); + body = compiler.getValue(); + } + } + compiler.addCommand({ + domain: `browser`, + keyword: `mail`, + lino, + to, + subject, + body + }); + return true; + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + if (command.subject) { + window.location.href = `mailto:${program.getValue(command.to)}` + + `?subject=${program.getValue(command.subject)}&body=${encodeURIComponent(program.getValue(command.body))}`; + } else { + window.location.href = `mailto:${program.getValue(command.to)}`; + } + return command.pc + 1; + } + }, + + On: { + + compile: (compiler) => { + const lino = compiler.getLino(); + const action = compiler.nextToken(); + switch (action) { + case `change`: + compiler.next(); + if (compiler.isSymbol()) { + const symbol = compiler.getSymbolRecord(); + compiler.next(); + if (symbol.extra !== `dom`) { + return false; + } + compiler.addCommand({ + domain: `browser`, + keyword: `on`, + lino, + action, + symbol: symbol.name + }); + return compiler.completeHandler(); + } + break; + case `click`: + if (compiler.nextTokenIs(`document`)) { + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `on`, + lino, + action: `clickDocument` + }); + return compiler.completeHandler(); + } + if (compiler.isSymbol()) { + const symbol = compiler.getSymbolRecord(); + compiler.next(); + if (symbol.extra !== `dom`) { + return false; + } + compiler.addCommand({ + domain: `browser`, + keyword: `on`, + lino, + action, + symbol: symbol.name + }); + return compiler.completeHandler(); + } + break; + case `key`: + case `leave`: + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `on`, + lino, + action + }); + return compiler.completeHandler(); + case `window`: + if (compiler.nextTokenIs(`resize`)) { + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `on`, + lino, + action: `windowResize` + }); + return compiler.completeHandler(); + } + return false; + case `browser`: + case `restore`: + if (action === `browser` && !compiler.nextTokenIs(`back`)) { + return false; + } + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `on`, + lino, + action: `browserBack` + }); + return compiler.completeHandler(); + case `swipe`: + if ([`left`, `right`].includes(compiler.nextToken())) { + const direction = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `on`, + lino, + action: `swipe`, + direction + }); + return compiler.completeHandler(); + } + return false; + case `pick`: + if (compiler.nextIsSymbol()) { + const symbol = compiler.getSymbolRecord(); + compiler.next(); + if (symbol.extra !== `dom`) { + return false; + } + compiler.addCommand({ + domain: `browser`, + keyword: `on`, + lino, + action, + symbol: symbol.name + }); + return compiler.completeHandler(); + } + return false; + case `drag`: + case `drop`: + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `on`, + lino, + action + }); + return compiler.completeHandler(); + } + compiler.addWarning(`Unrecognised syntax in 'on'`); + return false; + }, + + run: (program) => { + let targetRecord; + const command = program[program.pc]; + switch (command.action) { + case `change`: + targetRecord = program.getSymbolRecord(command.symbol); + targetRecord.program = program.script; + targetRecord.element.forEach(function (target, index) { + if (target) { + target.targetRecord = targetRecord; + target.targetIndex = index; + target.targetPc = command.pc + 2; + target.addEventListener(`change`, (event) => { + event.stopPropagation(); + if (program.length > 0) { + const eventTarget = event.target; + if (typeof eventTarget.targetRecord !== `undefined`) { + eventTarget.targetRecord.index = eventTarget.targetIndex; + setTimeout(function () { + EasyCoder.timestamp = Date.now(); + let p = EasyCoder.scripts[eventTarget.targetRecord.program]; + p.run(eventTarget.targetPc); + }, 1); + } + } + }); + } + }); + break; + case `click`: + targetRecord = program.getSymbolRecord(command.symbol); + targetRecord.program = program.script; + targetRecord.element.forEach(function (target, index) { + if (target) { + target.targetRecord = targetRecord; + target.targetIndex = index; + target.targetPc = command.pc + 2; + target.onclick = function (event) { + event.stopPropagation(); + if (program.length > 0) { + const eventTarget = event.target; + if (eventTarget.type != `radio`) { + eventTarget.blur(); + } + if (typeof eventTarget.targetRecord !== `undefined`) { + eventTarget.targetRecord.index = eventTarget.targetIndex; + setTimeout(function () { + EasyCoder.timestamp = Date.now(); + let p = EasyCoder.scripts[eventTarget.targetRecord.program]; + p.run(eventTarget.targetPc); + }, 1); + } + } + return false; + }; + } + }); + break; + case `clickDocument`: + program.targetPc = command.pc + 2; + const interceptClickEvent = (e) => { + EasyCoder.timestamp = Date.now(); + let target = e.target || e.srcElement; + let href = ``; + while (target.parentNode) { + if (target.tagName === `A`) { + href = target.href; + program.docPath = href.slice(-(href.length - window.location.href.length)); + break; + } + target = target.parentNode; + } + while (target.parentNode) { + if (target.id.indexOf(`ec-`) === 0) { + let id = target.id.slice(3); + let pos = id.indexOf(`-`); + program.varName = id.slice(0, pos); + id = id.slice(pos + 1); + pos = id.indexOf(`-`); + program.varIndex = parseInt(id.slice(0, pos)); + break; + } + target = target.parentNode; + } + if (href.indexOf(window.location.href) === 0) { + program.run(program.targetPc); + e.preventDefault(); + } + }; + if (document.addEventListener) { + document.addEventListener(`click`, interceptClickEvent); + } else if (document.attachEvent) { + document.attachEvent(`onclick`, interceptClickEvent); + } + break; + case `swipe`: + let xDown; + const getTouches = (evt) => { + return evt.touches || // browser API + evt.originalEvent.touches; // jQuery + }; + const handleTouchStart = (evt) => { + const firstTouch = getTouches(evt)[0]; + xDown = firstTouch.clientX; + }; + const handleTouchMove = (evt) => { + evt.stopImmediatePropagation(); + if (!xDown) { + return; + } + const xUp = evt.touches[0].clientX; + const xDiff = xDown - xUp; + if (Math.abs(xDiff) > 150) { + xDown = null; + if (xDiff > 0 && program.onSwipeLeft) { + program.run(program.onSwipeLeft); + } else if (xDiff < 0 && program.onSwipeRight) { + program.run(program.onSwipeRight); + } + } + }; + switch (command.direction) { + case `left`: + program.onSwipeLeft = command.pc + 2; + break; + case `right`: + program.onSwipeRight = command.pc + 2; + break; + } + document.addEventListener(`touchstart`, handleTouchStart, false); + document.addEventListener(`touchmove`, handleTouchMove, false); + break; + case `pick`: + const pickRecord = program.getSymbolRecord(command.symbol); + document.pickRecord = pickRecord; + pickRecord.element.forEach(function (element, index) { + document.pickIndex = index; + element.pickIndex = index; + // Set up the mouse down and up listeners + element.mouseDownPc = command.pc + 2; + // Check if touch device + let isTouchDevice = `ontouchstart` in element; + if (isTouchDevice) { + element.addEventListener(`touchstart`, function (e) { + const element = e.targetTouches[0].target; + document.pickX = e.touches[0].clientX; + document.pickY = e.touches[0].clientY; + element.blur(); + setTimeout(function () { + document.pickRecord.index = element.pickIndex; + program.run(element.mouseDownPc); + }, 1); + }, false); + element.addEventListener(`touchmove`, function (e) { + document.dragX = e.touches[0].clientX; + document.dragY = e.touches[0].clientY; + setTimeout(function () { + program.run(document.mouseMovePc); + }, 1); + return false; + }, false); + element.addEventListener(`touchend`, function () { + setTimeout(function () { + program.run(document.mouseUpPc); + }, 1); + return false; + }); + } else { + element.onmousedown = function (event) { + let e = event ? event : window.event; + e.stopPropagation(); + // IE uses srcElement, others use target + if (program.length > 0) { + const element = e.target ? e.target : e.srcElement; + element.offsetX = e.offsetX; + element.offsetY = e.offsetY; + document.pickX = e.clientX; + document.pickY = e.clientY; + element.blur(); + setTimeout(function () { + document.pickRecord.index = element.pickIndex; + program.run(element.mouseDownPc); + }, 1); + } + document.onmousemove = function (event) { + let e = event ? event : window.event; + e.stopPropagation(); + document.dragX = e.clientX; + document.dragY = e.clientY; + if (document.onmousemove) { + setTimeout(function () { + program.run(document.mouseMovePc); + }, 1); + } + return false; + }; + window.onmouseup = function () { + document.onmousemove = null; + document.onmouseup = null; + setTimeout(function () { + if (program && program.run) { + program.run(document.mouseUpPc); + } + }, 1); + return false; + }; + return false; + }; + } + }); + break; + case `drag`: + // Set up the move listener + document.mouseMovePc = command.pc + 2; + break; + case `drop`: + // Set up the move listener + document.mouseUpPc = command.pc + 2; + break; + case `key`: + if (typeof document.onKeyListeners === `undefined`) { + document.onKeyListeners = []; + } + if (!document.onKeyListeners.includes(program)) { + document.onKeyListeners.push(program); + } + program.onKeyPc = command.pc + 2; + document.onkeypress = function (event) { + for (const program of document.onKeyListeners) { + program.key = event.key; + try { + setTimeout(function () { + program.run(program.onKeyPc); + }, 1); + } catch (err) { + console.log(`Error: ${err.message}`); + } + } + return true; + }; + break; + case `windowResize`: + program.onWindowResize = command.pc + 2; + window.addEventListener('resize', function() { + program.run(program.onWindowResize); + }); + break; + case `browserBack`: + program.onBrowserBack = command.pc + 2; + break; + case `leave`: + window.addEventListener(`beforeunload`, function () { + program.run(command.pc + 2); + }); + break; + default: + break; + } + return command.pc + 1; + } + }, - compile: compiler => { + OPTION: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `option`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + P: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `p`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Play: { + + compile: (compiler) => { const lino = compiler.getLino(); - item = compiler.getNextValue(); - let on = `\n`; - if (compiler.tokenIs(`on`)) { - on = compiler.getNextValue(); + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `audioclip`) { + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `play`, + lino, + target: targetRecord.name + }); + return true; + } } - if ([`giving`, `into`].includes(compiler.getToken())) { - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - compiler.next(); + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const targetRecord = program.getSymbolRecord(command.target); + const url = program.value.evaluate(program, targetRecord.value[targetRecord.index]).content; + new Audio(url).play(); + return command.pc + 1; + } + }, + + PRE: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `pre`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + PROGRESS: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `progress`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Put: { + + compile: (compiler) => { + const lino = compiler.getLino(); + // Get the value + const value = compiler.getNextValue(); + if (compiler.tokenIs(`into`)) { + if (compiler.nextTokenIs(`storage`)) { + if (compiler.nextTokenIs(`as`)) { + const key = compiler.getNextValue(); compiler.addCommand({ - domain: `core`, - keyword: `split`, + domain: `browser`, + keyword: `put`, lino, - item, - on, - target: targetRecord.name + value, + key }); return true; } @@ -2227,2134 +4639,3702 @@ const EasyCoder_Core = { return false; }, - run: program => { - let command = program[program.pc]; - let content = program.getValue(command.item); - let on = program.getValue(command.on); - content = content.split(on); - let elements = content.length; - targetRecord = program.getSymbolRecord(command.target); - targetRecord.elements = elements; - for (let n = 0; n < elements; n++) { - targetRecord.value[n] = { - type: `constant`, - numeric: false, - content: content[n] - }; - } - targetRecord.index = 0; + // runtime + + run: (program) => { + const command = program[program.pc]; + window.localStorage.setItem(program.getValue(command.key), program.getValue(command.value)); return command.pc + 1; } }, - Stop: { + Remove: { - compile: compiler => { + compile: (compiler) => { const lino = compiler.getLino(); - compiler.next(); - if (compiler.more() && compiler.isSymbol() && !compiler.getToken().endsWith(`:`)) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.keyword === `module`) { + if (compiler.nextTokenIs(`element`)) { + if (compiler.nextIsSymbol()) { + const element = compiler.getSymbolRecord(); + if (element.extra != `dom`) { + compiler.warning(`'${element.name}' is not a DOM element`); + return false; + } compiler.next(); compiler.addCommand({ - domain: `core`, - keyword: `stop`, + domain: `browser`, + keyword: `remove`, + type: `removeElement`, lino, - name: symbolRecord.name + element: element.name }); return true; - } else { - return false; } } - compiler.addCommand({ - domain: `core`, - keyword: `stop`, - lino, - next: 0 - }); + if (compiler.tokenIs(`attribute`)) { + const attribute = compiler.getNextValue(); + if (compiler.tokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.extra !== `dom`) { + throw new Error(`Inappropriate type '${targetRecord.keyword}'`); + } + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `remove`, + type: `removeAttribute`, + lino, + attribute, + target: targetRecord.name + }); + return true; + } + } + } + try { + const key = compiler.getValue(); + if (compiler.tokenIs(`from`)) { + if (compiler.nextTokenIs(`storage`)) { + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `remove`, + type: `removeStorage`, + key + }); + return true; + } + } + } catch (err) { + return false; + } + return false; + }, + + // runtime + + run: (program) => { + const command = program[program.pc]; + switch (command.type) { + case `removeAttribute`: + const attribute = program.getValue(command.attribute); + const targetRecord = program.getSymbolRecord(command.target); + target = targetRecord.element[targetRecord.index]; + target.removeAttribute(attribute); + break; + case `removeElement`: + const elementRecord = program.getSymbolRecord(command.element); + const element = elementRecord.element[elementRecord.index]; + if (element) { + element.parentElement.removeChild(element); + } + break; + case `removeStorage`: + const key = program.getValue(command.key); + window.localStorage.removeItem(key); + break; + } + return command.pc + 1; + } + }, + + Request: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextToken() === `fullscreen`) { + let option = ``; + if (compiler.nextToken() === `exit`) { + option = `exit`; + compiler.next(); + } + compiler.addCommand({ + domain: `browser`, + keyword: `request`, + lino, + option + }); + return true; + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + if (command.option === `exit`) { + document.exitFullscreen(); + } else { + document.documentElement.requestFullscreen(); + } + return command.pc + 1; + } + }, + + SELECT: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `select`, false, `dom`); return true; }, - run: program => { + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Scroll: { + + compile: (compiler) => { + const lino = compiler.getLino(); + let name = null; + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + name = symbolRecord.name; + compiler.next(); + } + if (compiler.tokenIs(`to`)) { + const to = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `scroll`, + lino, + name, + to + }); + return true; + } + return false; + }, + + run: (program) => { const command = program[program.pc]; + const to = program.getValue(command.to); if (command.name) { const symbolRecord = program.getSymbolRecord(command.name); - EasyCoder.scripts[symbolRecord.program].exit(); - symbolRecord.program = null; + symbolRecord.element[symbolRecord.index].scrollTo(0, to); } else { - return 0; + window.scrollTo(0, to); } return command.pc + 1; } }, - Take: { + SECTION: { - compile: compiler => { + compile: (compiler) => { + compiler.compileVariable(`browser`, `section`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Set: { + + compile: (compiler) => { const lino = compiler.getLino(); - compiler.next(); - // Get the (first) value - const value1 = compiler.getValue(); - if (compiler.tokenIs(`from`)) { - compiler.next(); - if (compiler.isSymbol()) { - const symbol = compiler.getSymbol(); - const variable = compiler.getCommandAt(symbol.pc); - if (variable.isVHolder) { - if (compiler.peek() === `giving`) { - // This variable must be treated as a second value - const value2 = compiler.getValue(); - compiler.next(); - const target = compiler.getToken(); + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + const target = targetRecord.name; + if (targetRecord.extra === `dom`) { + const token = compiler.nextToken(); + if (token === `from`) { + if (compiler.nextIsSymbol()) { + if (targetRecord.keyword === `select`) { + const sourceRecord = compiler.getSymbolRecord(); + if (sourceRecord.keyword === `variable`) { + var display = null; + if (compiler.nextTokenIs(`as`)) { + display = compiler.getNextValue(); + } + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setSelect`, + select: target, + source: sourceRecord.name, + display + }); + return true; + } + return false; + } + const source = compiler.getToken(); compiler.next(); compiler.addCommand({ - domain: `core`, - keyword: `take`, + domain: `browser`, + keyword: `set`, lino, - value1, - value2, + type: `setContentVar`, + source, target }); - } else { - // Here the variable is the target. + return true; + } + } + } + } else { + let token = compiler.getToken(); + if (token === `the`) { + token = compiler.nextToken(); + } + if (token === `title`) { + if (compiler.nextTokenIs(`to`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setTitle`, + value + }); + return true; + } + } else if (token === `content`) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { const target = compiler.getToken(); + if (compiler.nextTokenIs(`from`)) { + if (compiler.nextIsSymbol()) { + const source = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setContentVar`, + source, + target + }); + return true; + } + } + if (compiler.tokenIs(`to`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setContent`, + value, + target + }); + return true; + } + } + throw new Error(`'${compiler.getToken()}' is not a symbol`); + } + } else if (token === `class`) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbol = compiler.getSymbolRecord(); + if (symbol.extra === `dom`) { + if (compiler.nextTokenIs(`to`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setClass`, + symbolName: symbol.name, + value + }); + return true; + } + } + } + } + } else if (token === `id`) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbol = compiler.getSymbolRecord(); + if (symbol.extra === `dom`) { + if (compiler.nextTokenIs(`to`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setId`, + symbolName: symbol.name, + value + }); + return true; + } + } + } + } + } else if (token === `text`) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbol = compiler.getSymbolRecord(); + switch (symbol.keyword) { + case `button`: + case `input`: + case `span`: + case `label`: + case `legend`: + if (compiler.nextTokenIs(`to`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setText`, + symbolName: symbol.name, + value + }); + return true; + } + break; + default: + break; + } + } + } + } else if (token === `size`) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbol = compiler.getSymbolRecord(); + switch (symbol.keyword) { + case `input`: + if (compiler.nextTokenIs(`to`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setSize`, + symbolName: symbol.name, + value + }); + return true; + } + } + } + } + } else if (token === `attribute`) { + compiler.next(); + const attributeName = compiler.getValue(); + if (compiler.tokenIs(`of`)) { + if (compiler.nextIsSymbol(true)) { + const symbolRecord = compiler.getSymbolRecord(); + const symbolName = symbolRecord.name; compiler.next(); + let attributeValue = { + type: `boolean`, + content: true + }; + if (compiler.tokenIs(`to`)) { + attributeValue = compiler.getNextValue(); + } compiler.addCommand({ - domain: `core`, - keyword: `take`, + domain: `browser`, + keyword: `set`, lino, - value1, - target + type: `setAttribute`, + symbolName, + attributeName, + attributeValue }); + return true; } - return true; - } else { - compiler.warning(`core 'take'': Expected value holder`); } - } else { - // Here we have 2 values so 'giving' must come next - const value2 = compiler.getValue(); - if (compiler.tokenIs(`giving`)) { - compiler.next(); - const target = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `core`, - keyword: `take`, - lino, - value1, - value2, - target - }); - return true; - } else { - compiler.warning(`core 'take'': Expected "giving"`); + } else if (token === `attributes`) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + const symbolName = symbolRecord.name; + if (symbolRecord.extra !== `dom`) { + compiler.warning(`'${symbolName}' is not a DOM type`); + return false; + } + if (compiler.nextTokenIs(`to`)) { + const attributes = compiler.getNextValue(); + if (attributes) { + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setAttributes`, + symbolName, + attributes + }); + return true; + } + } + } + } + compiler.warning(`'${compiler.getToken()}' is not a symbol`); + return false; + } else if (token === `style`) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + const symbolName = symbolRecord.name; + if (symbolRecord.extra !== `dom`) { + compiler.warning(`'${symbolName}' is not a DOM type`); + return false; + } + if (compiler.nextTokenIs(`to`)) { + const styleValue = compiler.getNextValue(); + if (styleValue) { + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setStyles`, + symbolName, + styleValue + }); + return true; + } + } + } + compiler.warning(`'${compiler.getToken()}' is not a symbol`); + return false; + } + const styleName = compiler.getValue(); + let type = `setStyle`; + let symbolName = ``; + token = compiler.getToken(); + if (token === `of`) { + if (compiler.nextToken() === `body`) { + type = `setBodyStyle`; + } else if (compiler.isSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + symbolName = symbolRecord.name; + if (symbolRecord.extra !== `dom`) { + throw Error(`'${symbolName}' is not a DOM type`); + } + } else { + throw Error(`'${compiler.getToken()}' is not a known symbol`); + } + if (compiler.nextTokenIs(`to`)) { + const styleValue = compiler.getNextValue(); + if (styleValue) { + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type, + symbolName, + styleName, + styleValue + }); + return true; + } + } + } + else if (token === `to`) { + const styleValue = compiler.getNextValue(); + if (styleValue) { + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setHeadStyle`, + styleName, + styleValue + }); + return true; + } + } + } else if (token === `default`) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.keyword === `select`) { + if (compiler.nextTokenIs(`to`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `browser`, + keyword: `set`, + lino, + type: `setDefault`, + name: symbolRecord.name, + value + }); + return true; + } + } + } } } } + compiler.addWarning(`Unrecognised syntax in 'set'`); return false; }, - run: program => { + run: (program) => { const command = program[program.pc]; - const value1 = command.value1; - const value2 = command.value2; - const target = program.getSymbolRecord(command.target); - if (target.isVHolder) { - const value = target.value[target.index]; - if (value2) { - const result = program.getValue(value2) - - program.getValue(value1); - target.value[target.index] = { - type: `constant`, - numeric: true, - content: result - }; + let symbol; + let value; + let target; + let targetId; + let targetRecord; + let cssId; + let selectRecord; + switch (command.type) { + case `setContentVar`: + const sourceVar = program.getSymbolRecord(command.source); + targetRecord = program.getSymbolRecord(command.target); + const source = document.getElementById(sourceVar.value[sourceVar.index].content); + target = targetRecord.element[targetRecord.index]; + if (!target) { + targetId = program.getValue(targetRecord.value[targetRecord.index]); + target = document.getElementById(targetId); + } + target.innerHTML = source.innerHTML; + break; + case `setContent`: + value = program.getValue(command.value); + targetRecord = program.getSymbolRecord(command.target); + target = targetRecord.element[targetRecord.index]; + if (!target) { + cssId = targetRecord.value[targetRecord.index].content; + if (!cssId) { + program.runtimeError(command.lino, + `Variable '${targetRecord.name}' has not been attached to a DOM element.`); + return 0; + } + target = document.getElementById(cssId); + } + targetRecord.element[targetRecord.index] = target; + switch (targetRecord.keyword) { + case `text`: + case `textarea`: + target.value = value; + break; + case `input`: + target.value = value; + break; + default: + target.innerHTML = value; + break; + } + break; + case `setSelect`: + // The source is assumed to be an array + sourceRecord = program.getSymbolRecord(command.source); + const sourceData = program.getValue(sourceRecord.value[sourceRecord.index]); + var itemArray = ``; + try { + itemArray = JSON.parse(sourceData); + } catch (err) { + program.runtimeError(command.lino, `Can't parse JSON`); + return 0; + } + // The target is assumed to be a SELECT + selectRecord = program.getSymbolRecord(command.select); + const select = selectRecord.element[selectRecord.index]; + select.options.length = 0; + // Get the name of the display field + const display = program.getValue(command.display); + // For each item, set the title and inner HTML + itemArray.forEach(function (item) { + const title = display ? program.decode(item[display]) : null; + const opt = document.createElement(`option`); + const innerHTML = title ? title : item; + opt.innerHTML = innerHTML; + const value = title ? JSON.stringify(item) : item; + opt.value = value; + select.appendChild(opt); + }); + if (display) { + select.selectedIndex = itemArray.indexOf(display); } else { - if (!value.numeric && isNaN(value.content)) { - program.nonNumericValueError(command.lino); + select.selectedIndex = -1; + } + break; + case `setClass`: + symbol = program.getSymbolRecord(command.symbolName); + target = symbol.element[symbol.index]; + if (!target) { + targetId = program.getValue(symbol.value[symbol.index]); + target = document.getElementById(targetId); + } + program.getValue(command.value).split(` `).forEach(function(item) { + target.classList.remove(item); + target.classList.add(item); + }); + break; + case `setId`: + symbol = program.getSymbolRecord(command.symbolName); + target = symbol.element[symbol.index]; + if (!target) { + targetId = program.getValue(symbol.value[symbol.index]); + target = document.getElementById(targetId); + } + target.id = program.getValue(command.value); + break; + case `setText`: + symbol = program.getSymbolRecord(command.symbolName); + target = symbol.element[symbol.index]; + if (!target) { + targetId = program.getValue(symbol.value[symbol.index]); + target = document.getElementById(targetId); + } + value = program.getValue(command.value); + switch (symbol.keyword) { + case `button`: + case `span`: + case `label`: + case `legend`: + target.innerHTML = value; + break; + case `input`: + target.value = value; + break; + default: + break; + } + break; + case `setSize`: + symbol = program.getSymbolRecord(command.symbolName); + if (symbol.keyword === `input`) { + target = symbol.element[symbol.index]; + if (!target) { + targetId = program.getValue(symbol.value[symbol.index]); + target = document.getElementById(targetId); } - const result = parseInt(program.getValue(value)) - parseInt(program.getValue(value1)); - target.value[target.index] = { - type: `constant`, - numeric: true, - content: result - }; + target.size = program.getValue(command.value); + } else { + program.runtimeError(command.lino, `Inappropriate variable type '${symbol.name}'`); } - } else { - program.variableDoesNotHoldAValueError(command.lino, target.name); + break; + case `setAttribute`: + symbol = program.getSymbolRecord(command.symbolName); + target = symbol.element[symbol.index]; + if (!target) { + targetId = program.getValue(symbol.value[symbol.index]); + target = document.getElementById(targetId); + } + const attributeName = program.getValue(command.attributeName); + if (command.attributeValue.type === `boolean`) { + target.setAttribute(attributeName, command.attributeValue.content); + } else { + target.setAttribute(attributeName, program.getValue(command.attributeValue)); + } + break; + case `setAttributes`: + symbol = program.getSymbolRecord(command.symbolName); + target = symbol.element[symbol.index]; + if (!target) { + targetId = program.getValue(symbol.value[symbol.index]); + target = document.getElementById(targetId); + } + for (let n = target.attributes.length - 1; n >= 0; n--) { + target.removeAttribute(target.attributes[n].name); + } + let attributes = program.getValue(command.attributes); + let list = attributes.split(" "); + for (let n = 0; n < list.length; n++) { + let attribute = list[n]; + let p = attribute.indexOf(`=`); + if (p > 0) { + target.setAttribute(attribute.substr(0, p), attribute.substr(p + 1)); + } + else { + target.setAttribute(attribute, attribute); + } + } + break; + case `setStyle`: + case `setStyles`: + symbol = program.getSymbolRecord(command.symbolName); + target = symbol.element[symbol.index]; + if (!target) { + const symbolElement = symbol.value[symbol.index]; + if (!symbolElement.type) { + program.runtimeError(command.lino, `Variable '${symbol.name}' is not attached to a DOM element.`); + return 0; + } + targetId = program.getValue(symbolElement); + target = document.getElementById(targetId); + } + const styleValue = program.getValue(command.styleValue); + if (!symbol.value[symbol.index]) { + program.runtimeError(command.lino, `Variable '${symbol.name}' has not been assigned.`); + return 0; + } + switch (command.type) { + case `setStyle`: + target.style[command.styleName.content] = styleValue; + break; + case `setStyles`: + target.style.cssText = styleValue; + break; + } + break; + case `setHeadStyle`: + const headStyleName = program.getValue(command.styleName); + const headStyleValue = program.getValue(command.styleValue); + var style = document.createElement('style'); + style.innerHTML = `${headStyleName} ${headStyleValue}`; + for (let i = 0; i < document.head.childNodes.length; i++) { + let node = document.head.childNodes[i]; + if (node.tagName === `STYLE`) { + let data = node.innerHTML; + if (data.indexOf(`${headStyleName} `) === 0) { + document.head.removeChild(node); + break; + } + } + } + document.head.appendChild(style); + break; + case `setBodyStyle`: + const bodyStyleValue = program.getValue(command.styleValue); + switch (command.styleName.content) { + case `background`: + document.body.style.background = bodyStyleValue; + break; + default: + program.runtimeError(command.lino, + `Unsupported body attribute '${command.styleName.content}'`); + return 0; + } + break; + case `setTitle`: + document.title = program.getValue(command.value); + break; + case `setDefault`: + selectRecord = program.getSymbolRecord(command.name); + value = program.getValue(command.value); + const element = selectRecord.element[selectRecord.index]; + for (let n = 0; n < element.options.length; n++) { + if (element.options[n].value === value) { + element.selectedIndex = n; + break; + } + } + break; + default: + break; } return command.pc + 1; } }, - Toggle: { + SPAN: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `span`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + TABLE: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `table`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + TR: { + + compile: (compiler) => { + compiler.compileVariable(`browser`, `tr`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + TD: { - compile: compiler => { - const lino = compiler.getLino(); - compiler.next(); - if (compiler.isSymbol()) { - const symbolPc = compiler.getSymbolPc(); - compiler.next(); - compiler.addCommand({ - domain: `core`, - keyword: `toggle`, - lino, - symbol: symbolPc - }); - return true; - } - return false; + compile: (compiler) => { + compiler.compileVariable(`browser`, `td`, false, `dom`); + return true; }, - run: program => { - const command = program[program.pc]; - const symbol = program[command.symbol]; - if (symbol.isVHolder) { - const handler = program.domain[symbol.domain]; - const content = handler.value.get(program, symbol.value[symbol.index]).content; - handler.value.put(symbol, { - type: `boolean`, - content: !content - }); - } else { - program.variableDoesNotHoldAValueError(command.lino, symbol.name); - } - return command.pc + 1; + run: (program) => { + return program[program.pc].pc + 1; } }, - Variable: { + TEXTAREA: { - compile: compiler => { - compiler.compileVariable(`core`, `variable`, true); + compile: (compiler) => { + compiler.compileVariable(`browser`, `textarea`, false, `dom`); return true; }, - run: program => { + run: (program) => { return program[program.pc].pc + 1; } }, - Wait: { + Trace: { - compile: compiler => { + compile: (compiler) => { const lino = compiler.getLino(); - compiler.next(); - const value = compiler.getValue(compiler); - const scale = compiler.getToken(); - let multiplier = 1000; - switch (scale) { - case `milli`: - case `millis`: - compiler.next(); - multiplier = 1; - break; - case `tick`: - case `ticks`: - compiler.next(); - multiplier = 10; - break; - case `second`: - case `seconds`: - compiler.next(); - multiplier = 1000; - break; - case `minute`: - case `minutes`: - compiler.next(); - multiplier = 60000; - break; + const variables = []; + if (compiler.nextIsSymbol()) { + while (compiler.isSymbol()) { + variables.push(compiler.getToken()); + compiler.next(); + } + let alignment = `horizontal`; + if (compiler.tokenIs(`horizontal`) || compiler.tokenIs(`vertical`)) { + alignment = compiler.getToken(); + compiler.next(); + } + compiler.addCommand({ + domain: `browser`, + keyword: `trace`, + variant: `setup`, + lino, + variables, + alignment + }); + return true; } compiler.addCommand({ - domain: `core`, - keyword: `wait`, - lino, - value, - multiplier + domain: `browser`, + keyword: `trace`, + variant: `run`, + lino }); return true; }, - run: program => { + run: (program) => { const command = program[program.pc]; - const value = program.getValue(command.value); - setTimeout(function () { - if (program.run) { - program.run(command.pc + 1); + switch (command.variant) { + case `setup`: + console.log(`Set up tracer`); + program.tracer = { + variables: command.variables, + alignment: command.alignment + }; + break; + case `run`: + console.log(`Run tracer`); + if (!program.tracer) { + program.tracer = { + variables: [], + alignment: `horizontal` + }; } - }, value * command.multiplier); - return 0; + if (!program.tracing) { + const tracer = document.getElementById(`easycoder-tracer`); + if (tracer) { + tracer.innerHTML = + `
` + + `` + + `
` + + `
`; + tracer.style.display = `none`; + } + program.tracing = true; + } + program.stop = false; + break; + } + return program.pc + 1; } }, - While: { + UL: { - compile: compiler => { - const lino = compiler.getLino(); - compiler.next(); - const condition = compiler.getCondition(); - const pc = compiler.getPc(); - compiler.addCommand({ - domain: `core`, - keyword: `while`, - lino, - condition - }); - // Skip when test fails - const skip = compiler.getPc(); - compiler.addCommand({ - domain: `core`, - keyword: `goto`, - goto: 0 - }); - // Do the body - compiler.compileOne(); - // Repeat the test - compiler.addCommand({ - domain: `core`, - keyword: `goto`, - goto: pc - }); - // Fixup the 'goto' on completion - compiler.getCommandAt(skip).goto = compiler.getPc(); + compile: (compiler) => { + compiler.compileVariable(`browser`, `ul`, false, `dom`); return true; }, - run: program => { - const command = program[program.pc]; - const condition = command.condition; - const test = program.condition.test(program, condition); - if (test) { - return program.pc + 2; - } - return program.pc + 1; + run: (program) => { + return program[program.pc].pc + 1; } }, - getHandler: (name) => { - switch (name) { - case `add`: - return EasyCoder_Core.Add; - case `alias`: - return EasyCoder_Core.Alias; - case `append`: - return EasyCoder_Core.Append; - case `begin`: - return EasyCoder_Core.Begin; - case `callback`: - return EasyCoder_Core.Callback; - case `clear`: - return EasyCoder_Core.Clear; - case `close`: - return EasyCoder_Core.Close; - case `continue`: - return EasyCoder_Core.Continue; - case `debug`: - return EasyCoder_Core.Debug; - case `decode`: - return EasyCoder_Core.Decode; - case `divide`: - return EasyCoder_Core.Divide; - case `dummy`: - return EasyCoder_Core.Dummy; - case `encode`: - return EasyCoder_Core.Encode; - case `end`: - return EasyCoder_Core.End; - case `exit`: - return EasyCoder_Core.Exit; - case `filter`: - return EasyCoder_Core.Filter; - case `fork`: - return EasyCoder_Core.Fork; - case `go`: - case `goto`: - return EasyCoder_Core.Go; - case `gosub`: - return EasyCoder_Core.Gosub; - case `if`: - return EasyCoder_Core.If; - case `import`: - return EasyCoder_Core.Import; - case `index`: - return EasyCoder_Core.Index; - case `load`: - return EasyCoder_Core.Load; - case `module`: - return EasyCoder_Core.Module; - case `multiply`: - return EasyCoder_Core.Multiply; - case `negate`: - return EasyCoder_Core.Negate; - case `on`: - return EasyCoder_Core.On; - case `print`: - return EasyCoder_Core.Print; - case `put`: - return EasyCoder_Core.Put; - case `replace`: - return EasyCoder_Core.Replace; - case `require`: - return EasyCoder_Core.Require; - case `return`: - return EasyCoder_Core.Return; - case `run`: - return EasyCoder_Core.Run; - case `sanitize`: - return EasyCoder_Core.Sanitize; - case `script`: - return EasyCoder_Core.Script; - case `send`: - return EasyCoder_Core.Send; - case `set`: - return EasyCoder_Core.Set; - case `sort`: - return EasyCoder_Core.Sort; - case `split`: - return EasyCoder_Core.Split; - case `stop`: - return EasyCoder_Core.Stop; - case `take`: - return EasyCoder_Core.Take; - case `toggle`: - return EasyCoder_Core.Toggle; - case `variable`: - return EasyCoder_Core.Variable; - case `wait`: - return EasyCoder_Core.Wait; - case `while`: - return EasyCoder_Core.While; + Upload: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const file = compiler.getToken(); + if (compiler.nextTokenIs(`to`)) { + const path = compiler.getNextValue(); + if (compiler.tokenIs(`with`)) { + if (compiler.nextIsSymbol()) { + const progress = compiler.getToken(); + if (compiler.nextTokenIs(`and`)) { + if (compiler.nextIsSymbol()) { + const status = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `browser`, + keyword: `upload`, + lino, + file, + path, + progress, + status + }); + return true; + } + } + } + } + } + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const fileSpec = program.getSymbolRecord(command.file); + const path = program.getValue(command.path); + const progressSpec = program.getSymbolRecord(command.progress); + const statusSpec = program.getSymbolRecord(command.status); + + const file = fileSpec.element[fileSpec.index]; + const progress = progressSpec.element[progressSpec.index]; + const status = statusSpec.element[statusSpec.index]; + + const setProgress = (value) => { + if (progress) { + progress.value = value; + } + }; + const setStatus = (value) => { + if (status) { + status.innerHTML = value; + } + }; + + const source = file.files[0]; + if (source) { + const formData = new FormData(); + formData.append(`source`, source); + formData.append(`path`, path); + const ajax = new XMLHttpRequest(); + ajax.upload.addEventListener(`progress`, function (event) { + const percent = Math.round((event.loaded / event.total) * 100); + setProgress(percent); + setStatus(`${Math.round(percent)}%...`); + }, false); + ajax.addEventListener(`load`, function (event) { + const response = event.target.responseText; + setProgress(0); + setStatus(``); + console.log(response); + }, false); + ajax.addEventListener(`error`, function () { + setStatus(`Upload failed`); + console.log(`Upload failed`); + }, false); + ajax.addEventListener(`abort`, function () { + setStatus(`Upload aborted`); + console.log(`Upload aborted`); + }, false); + ajax.onreadystatechange = function () { + if (this.readyState === 4) { + const command = program.ajaxCommand; + const status = this.status; + switch (status) { + case 200: + program.run(command.pc + 1); + break; + case 0: + break; + default: + try { + program.runtimeError(command.lino, `Error ${status}`); + } catch (err) { + program.reportError(err, program); + } + break; + } + } + }; + program.ajaxCommand = command; + const postpath = path.startsWith(`http`) ? path : `${window.location.origin}/${EasyCoder_Plugins.rest()}/${path}`; + ajax.open(`POST`, postpath); + ajax.send(formData); + } + return 0; + } + }, + + getHandler: (name) => { + switch (name) { + case `a`: + return EasyCoder_Browser.A; + case `alert`: + return EasyCoder_Browser.Alert; + case `attach`: + return EasyCoder_Browser.Attach; + case `audioclip`: + return EasyCoder_Browser.Audioclip; + case `blockquote`: + return EasyCoder_Browser.BLOCKQUOTE; + case `button`: + return EasyCoder_Browser.BUTTON; + case `canvas`: + return EasyCoder_Browser.CANVAS; + case `clear`: + return EasyCoder_Browser.Clear; + case `convert`: + return EasyCoder_Browser.Convert; + case `create`: + return EasyCoder_Browser.Create; + case `disable`: + return EasyCoder_Browser.Disable; + case `div`: + return EasyCoder_Browser.DIV; + case `enable`: + return EasyCoder_Browser.Enable; + case `fieldset`: + return EasyCoder_Browser.FIELDSET; + case `file`: + return EasyCoder_Browser.FILE; + case `focus`: + return EasyCoder_Browser.Focus; + case `form`: + return EasyCoder_Browser.FORM; + case `fullscreen`: + return EasyCoder_Browser.FullScreen; + case `get`: + return EasyCoder_Browser.Get; + case `h1`: + return EasyCoder_Browser.H1; + case `h2`: + return EasyCoder_Browser.H2; + case `h3`: + return EasyCoder_Browser.H3; + case `h4`: + return EasyCoder_Browser.H4; + case `h5`: + return EasyCoder_Browser.H5; + case `h6`: + return EasyCoder_Browser.H6; + case `highlight`: + return EasyCoder_Browser.Highlight; + case `history`: + return EasyCoder_Browser.History; + case `hr`: + return EasyCoder_Browser.HR; + case `image`: + return EasyCoder_Browser.IMAGE; + case `img`: + return EasyCoder_Browser.IMG; + case `input`: + return EasyCoder_Browser.INPUT; + case `label`: + return EasyCoder_Browser.LABEL; + case `legend`: + return EasyCoder_Browser.LEGEND; + case `li`: + return EasyCoder_Browser.LI; + case `location`: + return EasyCoder_Browser.Location; + case `mail`: + return EasyCoder_Browser.Mail; + case `on`: + return EasyCoder_Browser.On; + case `option`: + return EasyCoder_Browser.OPTION; + case `p`: + return EasyCoder_Browser.P; + case `play`: + return EasyCoder_Browser.Play; + case `pre`: + return EasyCoder_Browser.PRE; + case `progress`: + return EasyCoder_Browser.PROGRESS; + case `put`: + return EasyCoder_Browser.Put; + case `remove`: + return EasyCoder_Browser.Remove; + case `request`: + return EasyCoder_Browser.Request; + case `select`: + return EasyCoder_Browser.SELECT; + case `scroll`: + return EasyCoder_Browser.Scroll; + case `section`: + return EasyCoder_Browser.SECTION; + case `set`: + return EasyCoder_Browser.Set; + case `span`: + return EasyCoder_Browser.SPAN; + case `table`: + return EasyCoder_Browser.TABLE; + case `tr`: + return EasyCoder_Browser.TR; + case `td`: + return EasyCoder_Browser.TD; + case `textarea`: + return EasyCoder_Browser.TEXTAREA; + case `trace`: + return EasyCoder_Browser.Trace; + case `ul`: + return EasyCoder_Browser.UL; + case `upload`: + return EasyCoder_Browser.Upload; default: - return false; + return null; } }, - run: program => { - // Look up the appropriate handler and call it - // If it's not there throw an error + run: (program) => { const command = program[program.pc]; - const handler = EasyCoder_Core.getHandler(command.keyword); + const handler = EasyCoder_Browser.getHandler(command.keyword); if (!handler) { - program.runtimeError(command.lino, - `Unknown keyword '${command.keyword}' in 'core' package`); + program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'browser' package`); } return handler.run(program); }, - isNegate: (compiler) => { - const token = compiler.getToken(); - if (token === `not`) { - compiler.next(); - return true; - } - return false; - }, - value: { - compile: compiler => { + compile: (compiler) => { if (compiler.isSymbol()) { - const name = compiler.getToken(); const symbolRecord = compiler.getSymbolRecord(); - switch (symbolRecord.keyword) { - case `module`: - compiler.next(); - return { - domain: `core`, - type: `module`, - name - }; - case `variable`: - const type = compiler.nextToken(); - if ([`format`, `modulo`].includes(type)) { - const value = compiler.getNextValue(); + if (compiler.nextTokenIs(`exists`)) { + if (symbolRecord.extra === `dom`) { + compiler.next(); return { - domain: `core`, - type, - name, - value + domain: `browser`, + type: `exists`, + value: symbolRecord.name }; } + return null; + } + switch (symbolRecord.keyword) { + case `file`: + case `input`: + case `select`: + case `textarea`: return { - domain: `core`, - type: `symbol`, - name + domain: `browser`, + type: symbolRecord.keyword, + value: symbolRecord.name }; } return null; } - var token = compiler.getToken(); - if (token === `true`) { - compiler.next(); - return { - domain: `core`, - type: `boolean`, - content: true - }; - } - if (token === `false`) { - compiler.next(); - return { - domain: `core`, - type: `boolean`, - content: false - }; - } - if (token === `random`) { - compiler.next(); - const range = compiler.getValue(); - return { - domain: `core`, - type: `random`, - range - }; - } - if (token === `cos`) { - compiler.next(); - const angle_c = compiler.getValue(); - compiler.skip(`radius`); - const radius_c = compiler.getValue(); - return { - domain: `core`, - type: `cos`, - angle_c, - radius_c - }; - } - if (token === `sin`) { + if (compiler.tokenIs(`the`)) { compiler.next(); - const angle_s = compiler.getValue(); - compiler.skip(`radius`); - const radius_s = compiler.getValue(); - return { - domain: `core`, - type: `sin`, - angle_s, - radius_s - }; } - if (token === `tan`) { + let offset = false; + if (compiler.tokenIs(`offset`)) { + offset = true; compiler.next(); - const angle_t = compiler.getValue(); - compiler.skip(`radius`); - const radius_t = compiler.getValue(); - return { - domain: `core`, - type: `tan`, - angle_t, - radius_t - }; } - if ([`now`, `today`, `newline`, `break`, `empty`, `uuid`].includes(token)) { + + let type = compiler.getToken(); + let text; + let attribute; + switch (type) { + case `mobile`: + case `portrait`: + case `landscape`: + case `br`: + case `location`: + case `key`: + case `hostname`: compiler.next(); return { - domain: `core`, - type: token - }; - } - if (token === `date`) { - const value = compiler.getNextValue(); - return { - domain: `core`, - type: `date`, - value + domain: `browser`, + type }; - } - if ([`encode`, `decode`, `lowercase`, `hash`, `reverse`].includes(token)) { + case `content`: + case `text`: + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbol = compiler.getSymbolRecord(); + compiler.next(); + return { + domain: `browser`, + type: `contentOf`, + symbol: symbol.name + }; + } + throw new Error(`'${compiler.getToken()}' is not a symbol`); + } + return null; + case `selected`: + let arg = compiler.nextToken(); + if ([`index`, `item`].includes(arg)) { + if ([`in`, `of`].includes(compiler.nextToken())) { + if (compiler.nextIsSymbol()) { + const symbol = compiler.getSymbolRecord(); + if ([`ul`, `ol`, `select`].includes(symbol.keyword)) { + compiler.next(); + return { + domain: `browser`, + type: `selected`, + symbol: symbol.name, + arg + }; + } + } + } + } + return null; + case `color`: compiler.next(); const value = compiler.getValue(); return { - domain: `core`, - type: token, + domain: `browser`, + type, value }; - } - if (token === `element`) { - const element = compiler.getNextValue(); + case `attribute`: + attribute = compiler.getNextValue(); if (compiler.tokenIs(`of`)) { - if (compiler.nextIsSymbol()) { + compiler.next(); + if (compiler.isSymbol()) { const symbolRecord = compiler.getSymbolRecord(); - compiler.next(); - if (symbolRecord.keyword === `variable`) { + if (symbolRecord.extra === `dom`) { + compiler.next(); return { - domain: `core`, - type: `element`, - element, + domain: `browser`, + type: `attributeOf`, + attribute, symbol: symbolRecord.name }; } } } return null; - } - if (token === `property`) { - const property = compiler.getNextValue(); + case `style`: + const style = compiler.getNextValue(); if (compiler.tokenIs(`of`)) { if (compiler.nextIsSymbol()) { const symbolRecord = compiler.getSymbolRecord(); - compiler.next(); - if (symbolRecord.keyword === `variable`) { + if (symbolRecord.extra === `dom`) { + compiler.next(); return { - domain: `core`, - type: `property`, - property, - symbol: symbolRecord.name + domain: `browser`, + type, + style, + target: symbolRecord.name }; } } } return null; - } - if (token === `arg`) { - const value = compiler.getNextValue(); - if (compiler.tokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const target = compiler.getSymbolRecord(); - compiler.next(); - return { - domain: `core`, - type: `arg`, - value, - target: target.name - }; - } + case `confirm`: + text = compiler.getNextValue(); + return { + domain: `browser`, + type: `confirm`, + text + }; + case `prompt`: + text = compiler.getNextValue(); + let pre = null; + if (compiler.tokenIs(`with`)) { + pre = compiler.getNextValue(); } - } - if ([`character`, `char`].includes(token)) { - let index = compiler.getNextValue(); - if (compiler.tokenIs(`of`)) { - let value = compiler.getNextValue(); + return { + domain: `browser`, + type: `prompt`, + text, + pre + }; + case `screen`: + attribute = compiler.nextToken(); + if ([`width`, `height`].includes(attribute)) { + compiler.next(); return { - domain: `core`, - type: `char`, - index, - value + domain: `browser`, + type, + attribute }; } - } - if (compiler.tokenIs(`the`)) { - compiler.next(); - } - const type = compiler.getToken(); - switch (type) { - case `elements`: - if ([`of`, `in`].includes(compiler.nextToken())) { - if (compiler.nextIsSymbol()) { - const name = compiler.getToken(); - compiler.next(); - return { - domain: `core`, - type, - name - }; - } - } break; - case `index`: - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - if (compiler.peek() === `in`) { - const value1 = compiler.getValue(); - const value2 = compiler.getNextValue(); - return { - domain: `core`, - type: `indexOf`, - value1, - value2 - }; - } else { - const name = compiler.getToken(); - compiler.next(); - return { - domain: `core`, - type, - name - }; - } - } else { - const value1 = compiler.getValue(); - if (compiler.tokenIs(`in`)) { - const value2 = compiler.getNextValue(); - return { - domain: `core`, - type: `indexOf`, - value1, - value2 - }; - } - } + case `top`: + case `bottom`: + case `left`: + case `right`: + case `width`: + case `height`: + return EasyCoder_Browser.value.getCoord(compiler, type, offset); + case `scroll`: + if (compiler.nextTokenIs(`position`)) { + compiler.next(); + return { + domain: `browser`, + type: `scrollPosition` + }; + } + return null; + case `document`: + if (compiler.nextTokenIs(`path`)) { + compiler.next(); + return { + domain: `browser`, + type: `docPath` + }; } - break; - case `value`: - if (compiler.nextTokenIs(`of`)) { + return null; + case `storage`: + if (compiler.nextTokenIs(`keys`)) { compiler.next(); - const value = compiler.getValue(); return { - domain: `core`, - type: `valueOf`, - value + domain: `browser`, + type: `storageKeys` }; } - break; - case `length`: - if (compiler.nextTokenIs(`of`)) { + return null; + case `parent`: + switch (compiler.nextToken()) { + case `name`: compiler.next(); - const value = compiler.getValue(); return { - domain: `core`, - type: `lengthOf`, - value + domain: `browser`, + type: `varName` + }; + case `index`: + compiler.next(); + return { + domain: `browser`, + type: `varIndex` }; } - break; - case `left`: - case `right`: - try { - const count = compiler.getNextValue(); - if (compiler.tokenIs(`of`)) { - const value = compiler.getNextValue(); - return { - domain: `core`, - type, - count, - value - }; - } - } catch (err) { - return null; + return null; + case `history`: + if (compiler.nextTokenIs(`state`)) { + compiler.next(); + return { + domain: `browser`, + type: `historyState` + }; } - break; - case `from`: - const from = compiler.getNextValue(); - const to = compiler.tokenIs(`to`) ? compiler.getNextValue() : null; - if (compiler.tokenIs(`of`)) { - const value = compiler.getNextValue(); + return null; + case `pick`: + case `drag`: + if (compiler.nextTokenIs(`position`)) { + compiler.next(); return { - domain: `core`, - type, - from, - to, - value + domain: `browser`, + type: `${type}Position` }; } - break; - case `position`: - let nocase = false; - if (compiler.nextTokenIs(`nocase`)) { - nocase = true; + } + return null; + }, + + getCoord: (compiler, type, offset) => { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextTokenIs(`window`)) { compiler.next(); + return { + domain: `browser`, + type, + symbol: `window`, + offset + }; } - if (compiler.tokenIs(`of`)) { - var last = false; - if (compiler.nextTokenIs(`the`)) { - if (compiler.nextTokenIs(`last`)) { - compiler.next(); - last = true; - } - } - const needle = compiler.getValue(); - if (compiler.tokenIs(`in`)) { - const haystack = compiler.getNextValue(); + let symbolRecord = null; + if (compiler.isSymbol()) { + symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.extra === `dom`) { + compiler.next(); return { - domain: `core`, - type: `position`, - needle, - haystack, - last, - nocase + domain: `browser`, + type, + symbol: symbolRecord.name, + offset }; } } - break; - case `payload`: - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const callbackRecord = compiler.getSymbolRecord(); - if (callbackRecord.keyword === `callback`) { - compiler.next(); - return { - domain: `core`, - type: `payload`, - callback: callbackRecord.name - }; - } - } - } - break; - case `message`: - case `error`: - case `millisecond`: - compiler.next(); - return { - domain: `core`, - type - }; - } return null; }, get: (program, value) => { + let symbolRecord; + let element; + let target; + let content; switch (value.type) { - case `boolean`: + case `file`: + case `input`: + case `select`: + case `textarea`: + symbolRecord = program.getSymbolRecord(value.value); + target = symbolRecord.element[symbolRecord.index]; return { - type: `boolean`, + type: `constant`, numeric: false, - content: value.content + content: target.value }; - case `elements`: + case `exists`: + symbolRecord = program.getSymbolRecord(value.value); return { - type: `constant`, - numeric: true, - content: program.getSymbolRecord(value.name).elements + domain: `browser`, + type: `boolean`, + content: typeof symbolRecord.element[symbolRecord.index] !== `undefined` }; - case `index`: + case `mobile`: return { - type: `constant`, - numeric: true, - content: program.getSymbolRecord(value.name).index + domain: `browser`, + type: `boolean`, + content: (typeof window.orientation !== `undefined`) || (navigator.userAgent.indexOf(`IEMobile`) !== -1) }; - case `random`: - const range = program.evaluate(value.range); + case `portrait`: return { - type: `constant`, - numeric: true, - content: Math.floor((Math.random() * range.content)) + domain: `browser`, + type: `boolean`, + content: document.documentElement.clientWidth < document.documentElement.clientHeight }; - case `cos`: - const angle_c = program.getValue(value.angle_c); - const radius_c = program.getValue(value.radius_c); + case `landscape`: return { - type: `constant`, - numeric: true, - content: parseInt(Math.cos(parseFloat(angle_c) * 0.01745329) * radius_c, 10) + domain: `browser`, + type: `boolean`, + content: document.documentElement.clientWidth >= document.documentElement.clientHeight }; - case `sin`: - const angle_s = program.getValue(value.angle_s); - const radius_s = program.getValue(value.radius_s); + case `br`: return { type: `constant`, - numeric: true, - content: parseInt(Math.sin(parseFloat(angle_s) * 0.01745329) * radius_s, 10) + numeric: false, + content: decodeURIComponent(`%3Cbr%20%2F%3E`) }; - case `tan`: - const angle_t = program.getValue(value.angle_t); - const radius_t = program.getValue(value.radius_t); + case `attributeOf`: + symbolRecord = program.getSymbolRecord(value.symbol); + const attribute = program.getValue(value.attribute); + target = symbolRecord.element[symbolRecord.index]; + if (attribute.indexOf(`data-`) === 0) { + return program.getSimpleValue(target.dataset[attribute.substr(5)]); + } + return program.getSimpleValue(target[attribute]); + case `style`: + symbolRecord = program.getSymbolRecord(value.target); + const style = program.getValue(value.style); + target = symbolRecord.element[symbolRecord.index]; + return program.getSimpleValue(target.style[style]); + case `confirm`: return { - type: `constant`, - numeric: true, - content: parseInt(Math.tan(parseFloat(angle_t) * 0.01745329) * radius_t, 10) + type: `boolean`, + content: window.confirm(program.getValue(value.text)) }; - case `valueOf`: - const v = parseInt(program.getValue(value.value)); + case `prompt`: + const text = program.getValue(value.text); + const pre = program.getValue(value.pre); return { type: `constant`, - numeric: true, - content: v ? v : 0 + numeric: false, + content: pre ? window.prompt(text, pre) : window.prompt(text) }; - case `lengthOf`: + case `contentOf`: + symbolRecord = program.getSymbolRecord(value.symbol); + target = symbolRecord.element[symbolRecord.index]; + switch (symbolRecord.keyword) { + case `input`: + case `textarea`: + content = target.value; + break; + case `pre`: + content = target.innerHTML; + break; + default: + content = target.innerHTML.split(`\n`).join(``); + break; + } return { type: `constant`, - numeric: true, - content: program.getValue(value.value).length + numeric: false, + content }; - case `left`: + case `selected`: + symbolRecord = program.getSymbolRecord(value.symbol); + target = symbolRecord.element[symbolRecord.index]; + let selectedIndex = target.selectedIndex; + let selectedText = selectedIndex >= 0 ? target.options[selectedIndex].text : ``; + content = (value.arg === `index`) ? selectedIndex : selectedText; return { type: `constant`, numeric: false, - content: program.getValue(value.value).substr(0, program.getValue(value.count)) + content }; - case `right`: - const str = program.getValue(value.value); + case `top`: + if (value.symbol == `window`) { + return { + type: `constant`, + numeric: true, + content: window.screenY + }; + } + symbolRecord = program.getSymbolRecord(value.symbol); + element = symbolRecord.element[symbolRecord.index]; + content = Math.round(value.offset ? element.offsetTop : element.getBoundingClientRect().top); return { type: `constant`, - numeric: false, - content: str.substr(str.length - program.getValue(value.count)) + numeric: true, + content }; - case `from`: - const from = program.getValue(value.from); - const to = value.to ? program.getValue(value.to) : null; - const fstr = program.getValue(value.value); + case `bottom`: + if (value.symbol == `window`) { + return { + type: `constant`, + numeric: true, + content: window.screenY + window.innerHeight + }; + } + symbolRecord = program.getSymbolRecord(value.symbol); + content = Math.round(symbolRecord.element[symbolRecord.index].getBoundingClientRect().bottom); return { type: `constant`, - numeric: false, - content: to ? fstr.substr(from, to) : fstr.substr(from) + numeric: true, + content }; - case `position`: - let needle = program.getValue(value.needle); - let haystack = program.getValue(value.haystack); - if (value.nocase) { - needle = needle.toLowerCase(); - haystack = haystack.toLowerCase(); + case `left`: + if (value.symbol == `window`) { + return { + type: `constant`, + numeric: true, + content: window.screenLeft + }; } + symbolRecord = program.getSymbolRecord(value.symbol); + element = symbolRecord.element[symbolRecord.index]; + content = Math.round(value.offset ? element.offsetLeft : element.getBoundingClientRect().left); return { type: `constant`, numeric: true, - content: value.last ? haystack.lastIndexOf(needle) : haystack.indexOf(needle) + content }; - case `payload`: + case `right`: + if (value.symbol == `window`) { + return { + type: `constant`, + numeric: true, + content: window.screenX + window.innerWidth + }; + } + symbolRecord = program.getSymbolRecord(value.symbol); + content = Math.round(symbolRecord.element[symbolRecord.index].getBoundingClientRect().right); return { type: `constant`, - numeric: false, - content: program.getSymbolRecord(value.callback).payload + numeric: true, + content }; - case `modulo`: - const symbolRecord = program.getSymbolRecord(value.name); - const modval = program.evaluate(value.value); + case `width`: + if (value.symbol == `window`) { + return { + type: `constant`, + numeric: true, + content: window.innerWidth + }; + } + symbolRecord = program.getSymbolRecord(value.symbol); + content = Math.round(symbolRecord.element[symbolRecord.index].getBoundingClientRect().width); return { type: `constant`, numeric: true, - content: symbolRecord.value[symbolRecord.index].content % modval.content - }; - case `format`: - const fmtRecord = program.getSymbolRecord(value.name); - const fmtValue = program.getValue(fmtRecord.value[fmtRecord.index]) * 1000; - try { - const spec = JSON.parse(program.getValue(value.value)); - switch (spec.mode) { - case `time`: - - return { - type: `constant`, - numeric: true, - content: new Date(fmtValue).toLocaleTimeString(spec.locale, spec.options) - }; - case `date`: - default: - const date = new Date(fmtValue); - const content = (spec.format === `iso`) - ? `${date.getFullYear()}-${date.getMonth()+1}-${date.getDate()}` - : date.toLocaleDateString(spec.locale, spec.options); - return { - type: `constant`, - numeric: true, - content - }; - } - } catch (err) { - program.runtimeError(program[program.pc].lino, `Can't parse ${value.value}`); - return null; + content + }; + case `height`: + if (value.symbol == `window`) { + return { + type: `constant`, + numeric: true, + content: window.innerHeight + }; } - case `empty`: + symbolRecord = program.getSymbolRecord(value.symbol); + content = Math.round(symbolRecord.element[symbolRecord.index].getBoundingClientRect().height); + return { + type: `constant`, + numeric: true, + content + }; + case `color`: + const styleValue = program.value.evaluate(program, value.value).content; + const hex = styleValue.toString(16).padStart(6, `0`); return { type: `constant`, numeric: false, - content: `` + content: `#${hex}` }; - case `now`: + case `docPath`: return { type: `constant`, - numeric: true, - content: Math.floor(Date.now() / 1000) + numeric: false, + content: program.docPath }; - case `millisecond`: + case `storageKeys`: return { type: `constant`, - numeric: true, - content: Math.floor(Date.now()) + numeric: false, + content: JSON.stringify(Object.keys(localStorage)) }; - case `today`: - const date = new Date(); - date.setHours(0, 0, 0, 0); + case `location`: + return { + type: `constant`, + numeric: false, + content: window.location.href + }; + case `historyState`: + return { + type: `constant`, + numeric: false, + content: window.history.state + }; + case `scrollPosition`: return { type: `constant`, numeric: true, - content: Math.floor(date.getTime() / 1000) + content: scrollPosition }; - case `date`: - content = Date.parse(program.getValue(value.value)) / 1000; - if (isNaN(content)) { - program.runtimeError(program[program.pc].lino, `Invalid date format; expecting 'yyyy-mm-dd'`); - return null; - } + case `varName`: + return { + type: `constant`, + numeric: false, + content: program.varName + }; + case `varIndex`: return { type: `constant`, numeric: true, - content + content: program.varIndex }; - case `newline`: + case `key`: return { type: `constant`, numeric: false, - content: `\n` + content: program.key }; - case `break`: + case `hostname`: return { type: `constant`, numeric: false, - content: `
` + content: location.hostname }; - case `uuid`: + case `screen`: + return { + type: `constant`, + numeric: true, + content: screen[value.attribute] + }; + case `pickPosition`: return { type: `constant`, numeric: false, - content: `xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`.replace(/[xy]/g, function(c) { - var r = Math.random() * 16 | 0, v = c == `x` ? r : (r & 0x3 | 0x8); - return v.toString(16); + content: JSON.stringify({ + "x": document.pickX, + "y": document.pickY }) }; - case `encode`: + case `dragPosition`: return { type: `constant`, numeric: false, - content: program.encode(program.getValue(value.value)) + content: JSON.stringify({ + "x": document.dragX, + "y": document.dragY + }) }; - case `decode`: + } + } + }, + + condition: { + + compile: (compiler) => { + if (compiler.tokenIs(`confirm`)) { + const value = compiler.getNextValue(); return { + domain: `browser`, + type: `confirm`, + value + }; + } else if (compiler.tokenIs(`element`)) { + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.extra === `dom`) { + const token = compiler.nextToken(); + if (token === `has`) { + if (compiler.nextTokenIs(`the`)) { + compiler.next(); + } + if (compiler.tokenIs(`focus`)) { + compiler.next(); + return { + domain: `browser`, + type: `focus`, + element: symbolRecord.name + }; + } + } else if (token === `contains`) { + const position = compiler.getNextValue(); + return { + domain: `browser`, + type: `contains`, + element: symbolRecord.name, + position + }; + } + } + } + } + return null; + }, + + test: (program, condition) => { + switch (condition.type) { + case `confirm`: + return confirm(program.getValue(condition.value)); + case `focus`: + const focusRecord = program.getSymbolRecord(condition.element); + return focusRecord.element[focusRecord.index] === document.activeElement; + case `contains`: + const containsRecord = program.getSymbolRecord(condition.element); + const element = containsRecord.element[containsRecord.index]; + const bounds = element.getBoundingClientRect(); + const left = Math.round(bounds.left); + const right = Math.round(bounds.right); + const top = Math.round(bounds.top); + const bottom = Math.round(bounds.bottom); + const position = JSON.parse(program.getValue(condition.position)); + const x = position.x; + const y = position.y; + if (x >= left && x <= right && y >= top && y <= bottom) { + return true; + } + return false; + } + } + }, + + setStyles: (id, styleString) => { + const element = document.getElementById(id); + const styles = styleString.split(`;`); + for (const item of styles) { + const style = item.split(`:`); + element.setAttribute(style[0], style[1]); + } + } +}; + +let scrollPosition = 0; + +window.addEventListener(`scroll`, function () { + scrollPosition = this.scrollY; +}); + +window.onpopstate = function (event) { + window.EasyCoder.timestamp = Date.now(); + const state = JSON.parse(event.state); + if (state && state.script) { + const program = window.EasyCoder.scripts[state.script]; + if (program) { + if (program.onBrowserBack) { + program.run(program.onBrowserBack); + } + } else { + console.log(`No script property in window state object`); + } + } +}; +const EasyCoder_Json = { + + name: `EasyCoder_JSON`, + + Json: { + + compile: (compiler) => { + const lino = compiler.getLino(); + const request = compiler.nextToken(); + let item; + switch (request) { + case `set`: + compiler.next(); + if (compiler.isSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + if (compiler.nextTokenIs(`to`)) { + const type = compiler.nextToken(); + if (`["array","object"]`.includes(type)) { + compiler.next(); + compiler.addCommand({ + domain: `json`, + keyword: `json`, + lino, + request: `setVariable`, + target: targetRecord.name, + type + }); + return true; + } + } + } else if (targetRecord.keyword === `select`) { + if (compiler.nextTokenIs(`from`)) { + compiler.next(); + if (compiler.isSymbol()) { + const sourceRecord = compiler.getSymbolRecord(); + if (sourceRecord.keyword === `variable`) { + var display = null; + if (compiler.nextTokenIs(`as`)) { + display = compiler.getNextValue(); + } + compiler.addCommand({ + domain: `json`, + keyword: `json`, + lino, + request: `setList`, + target: targetRecord.name, + source: sourceRecord.name, + display + }); + return true; + } + } + } + } + break; + } + break; + case `sort`: + case `shuffle`: + case `format`: + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + compiler.next(); + compiler.addCommand({ + domain: `json`, + keyword: `json`, + lino, + request, + target: targetRecord.name + }); + return true; + } + } + break; + case `parse`: + if (compiler.nextTokenIs(`url`)) { + const source = compiler.getNextValue(); + if (compiler.tokenIs(`as`)) { + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + compiler.next(); + compiler.addCommand({ + domain: `json`, + keyword: `json`, + lino, + request, + source, + target: targetRecord.name + }); + return true; + } + } + } + } + break; + case `delete`: + const what = compiler.nextToken(); + if ([`property`, `element`].includes(what)) { + const value = compiler.getNextValue(); + if ([`from`, `of`].includes(compiler.getToken())) { + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + compiler.next(); + compiler.addCommand({ + domain: `json`, + keyword: `json`, + lino, + request, + what, + value, + target: targetRecord.name + }); + return true; + } + } + } + } + break; + case `rename`: + const oldName = compiler.getNextValue(); + if (compiler.tokenIs(`to`)) { + const newName = compiler.getNextValue(); + if (compiler.tokenIs(`in`)) { + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + compiler.next(); + compiler.addCommand({ + domain: `json`, + keyword: `json`, + lino, + request, + oldName, + newName, + target: targetRecord.name + }); + return true; + } + } + } + } + break; + case `add`: + item = compiler.getNextValue(); + if (compiler.tokenIs(`to`)) { + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + compiler.next(); + compiler.addCommand({ + domain: `json`, + keyword: `json`, + lino, + request, + item, + target: targetRecord.name + }); + return true; + } + } + } + break; + case `split`: + item = compiler.getNextValue(); + let on = `\n`; + if (compiler.tokenIs(`on`)) { + on = compiler.getNextValue(); + } + if ([`giving`, `into`].includes(compiler.getToken())) { + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + compiler.next(); + compiler.addCommand({ + domain: `json`, + keyword: `json`, + lino, + request, + item, + on, + target: targetRecord.name + }); + return true; + } + } + } + break; + case `replace`: + if (compiler.nextTokenIs(`element`)) { + const index = compiler.getNextValue(); + if (compiler.tokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + if ([`by`, `with`].includes(compiler.nextToken())) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `json`, + keyword: `json`, + lino, + request, + target: targetRecord.name, + index, + value + }); + return true; + } + } + } + } + } + break; + } + compiler.addWarning(`Unrecognised json command syntax`); + return false; + }, + + run: (program) => { + const command = program[program.pc]; + let sourceRecord; + let targetRecord; + let record; + let content; + let array; + switch (command.request) { + case `setVariable`: + targetRecord = program.getSymbolRecord(command.target); + content = (command.type === `array`) ? `[]` : `{}`; + targetRecord.value[targetRecord.index] = { type: `constant`, numeric: false, - content: program.decode(program.getValue(value.value)) + content }; - case `reverse`: - return { + break; + case `setList`: + // The source is assumed to be a JSON array + sourceRecord = program.getSymbolRecord(command.source); + const sourceData = program.getValue(sourceRecord.value[sourceRecord.index]); + var itemArray = ``; + try { + itemArray = JSON.parse(sourceData); + } catch (err) { + program.runtimeError(command.lino, `Can't parse JSON`); + return 0; + } + // The target is assumed to be a SELECT + targetRecord = program.getSymbolRecord(command.target); + const target = targetRecord.element[targetRecord.index]; + target.options.length = 0; + // Get the name of the display field + const display = program.getValue(command.display); + // For each item, set the title and inner HTML + itemArray.forEach(function (item) { + const title = display ? program.decode(item[display]) : null; + const opt = document.createElement(`option`); + const innerHTML = title ? title : item; + opt.innerHTML = innerHTML; + const value = title ? JSON.stringify(item) : item; + opt.value = value; + target.appendChild(opt); + }); + target.selectedIndex = -1; + break; + case `sort`: + targetRecord = program.getSymbolRecord(command.target); + const list = program.getValue(targetRecord.value[targetRecord.index]); + content = list ? JSON.stringify(JSON.parse(list).sort()) : null; + targetRecord.value[targetRecord.index] = { type: `constant`, numeric: false, - content: program.getValue(value.value).split(``).reverse().join(``) + content }; - case `lowercase`: - return { + break; + case `shuffle`: + targetRecord = program.getSymbolRecord(command.target); + array = JSON.parse(program.getValue(targetRecord.value[targetRecord.index])); + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [array[i], array[j]] = [array[j], array[i]]; + } + targetRecord.value[targetRecord.index] = { type: `constant`, numeric: false, - content: program.getValue(value.value).toLowerCase() + content: JSON.stringify(array) }; - case `hash`: - const hashval = program.getValue(value.value); - let hash = 0; - if (hashval.length === 0) return hash; - for (let i = 0; i < hashval.length; i++) { - const chr = hashval.charCodeAt(i); - hash = ((hash << 5) - hash) + chr; - // hash |= 0; // Convert to 32bit integer + break; + case `format`: + targetRecord = program.getSymbolRecord(command.target); + const val = JSON.parse(program.getValue(targetRecord.value[targetRecord.index])); + targetRecord.value[targetRecord.index] = { + type: `constant`, + numeric: false, + content: JSON.stringify(val, null, 2) + }; + break; + case `parse`: + var source = program.getValue(command.source); + targetRecord = program.getSymbolRecord(command.target); + content = { + url: source + }; + var n = source.indexOf(`://`); + if (n >= 0) { + n += 3; + content.protocol = source.substr(0, n); + source = source.substr(n); + } + n = source.indexOf(`?`); + if (n > 0) { + content.domain = source.substr(0, n); + content.arg = source.substr(n + 1); + } else { + content.domain = source; } - return { + if (content.domain.endsWith(`/`)) { + content.domain = content.domain.slice(0, -1); + } + n = content.domain.indexOf(`/`); + if (n > 0) { + content.path = content.domain.substr(n + 1); + content.domain = content.domain.substr(0, n); + } + else { + content.path = ``; + } + targetRecord.value[targetRecord.index] = { type: `constant`, - numeric: true, - content: hash + numeric: false, + content: JSON.stringify(content, null, 2) }; - case `element`: - const element = program.getValue(value.element); - const elementRecord = program.getSymbolRecord(value.symbol); - var elementContent = ``; - try { - elementContent = JSON.parse(program.getValue(elementRecord.value[elementRecord.index]))[element]; - } catch (err) { - program.runtimeError(program[program.pc].lino, `Can't parse JSON`); - return null; + break; + case `delete`: + switch (command.what) { + case `property`: + const name = program.getValue(command.value); + targetRecord = program.getSymbolRecord(command.target); + record = JSON.parse(targetRecord.value[targetRecord.index].content); + delete record[name]; + targetRecord.value[targetRecord.index].content = JSON.stringify(record); + break; + case `element`: + const element = program.getValue(command.value); + targetRecord = program.getSymbolRecord(command.target); + record = JSON.parse(targetRecord.value[targetRecord.index].content); + record.splice(element, 1); + targetRecord.value[targetRecord.index].content = JSON.stringify(record); + break; } - return { + break; + case `rename`: + const oldName = program.getValue(command.oldName); + const newName = program.getValue(command.newName); + targetRecord = program.getSymbolRecord(command.target); + record = JSON.parse(targetRecord.value[targetRecord.index].content); + content = record[oldName]; + delete record[oldName]; + record[newName] = content; + targetRecord.value[targetRecord.index].content = JSON.stringify(record); + break; + case `add`: + content = program.getValue(command.item); + targetRecord = program.getSymbolRecord(command.target); + const existing = targetRecord.value[targetRecord.index].content; + record = existing ? JSON.parse(existing) : []; + record.push([`[`, `{`].includes(content[0]) ? JSON.parse(content) :content); + targetRecord.value[targetRecord.index] = { type: `constant`, numeric: false, - content: typeof elementContent === `object` ? - JSON.stringify(elementContent) : elementContent + content: JSON.stringify(record) }; - case `property`: - const property = program.getValue(value.property); - const propertyRecord = program.getSymbolRecord(value.symbol); - let propertyContent = program.getValue(propertyRecord.value[propertyRecord.index]); - var content = ``; - if (property && propertyContent) { - if (typeof propertyContent === `object`) { - content = propertyContent[property]; - } else if ([`{`, `]`].includes(propertyContent.charAt(0))) { - try { - content = JSON.parse(propertyContent)[property]; - } catch (err) { - console.log(`Can't parse '${propertyContent}': ${err.message}`); + break; + case `split`: + content = program.getValue(command.item); + const on = program.getValue(command.on); + targetRecord = program.getSymbolRecord(command.target); + targetRecord.value[targetRecord.index] = { + type: `constant`, + numeric: false, + content: JSON.stringify(content.split(on)) + }; + break; + case `replace`: + targetRecord = program.getSymbolRecord(command.target); + const index = program.getValue(command.index); + const value = program.getValue(command.value); + const current = targetRecord.value[targetRecord.index].content; + record = current ? JSON.parse(current) : []; + if (index > record.length - 1) { + program.runtimeError(command.lino, `Index out of range`); + } + record[index] = value; + targetRecord.value[targetRecord.index].content = JSON.stringify(record); + break; + } + return command.pc + 1; + } + }, + + getHandler: (name) => { + switch (name) { + case `json`: + return EasyCoder_Json.Json; + default: + return null; + } + }, + + run: (program) => { + const command = program[program.pc]; + const handler = EasyCoder_Json.getHandler(command.keyword); + if (!handler) { + program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'json' package`); + } + return handler.run(program); + }, + + value: { + + compile: (compiler) => { + if (compiler.tokenIs(`the`)) { + compiler.next(); + } + if (compiler.tokenIs(`json`)) { + const type = compiler.nextToken(); + if ([`size`, `count`, `keys`].includes(type)) { + compiler.skip(`of`); + if (compiler.isSymbol()) { + const target = compiler.getSymbolRecord(); + compiler.next(); + if (target.isVHolder) { + return { + domain: `json`, + type, + name: target.name + }; + } + } + } else if (type === `index`) { + if (compiler.nextTokenIs(`of`)) { + const item = compiler.getNextValue(); + if (compiler.tokenIs(`in`)) { + const list = compiler.getNextValue(); + return { + domain: `json`, + type, + item, + list + }; } } } + } + return null; + }, + + get: (program, value) => { + let symbolRecord; + let data; + let content; + switch (value.type) { + case `size`: + case `count`: + symbolRecord = program.getSymbolRecord(value.name); + data = program.getValue(symbolRecord.value[symbolRecord.index]); + let array; + try { + array = JSON.parse(data); + } catch (err) { + array = []; + } return { type: `constant`, - numeric: !Array.isArray(content) && !isNaN(content), - content: typeof content === `object` ? JSON.stringify(content) : content - }; - case `module`: - const module = program.getSymbolRecord(value.name); - return { - type: `boolean`, - numeric: false, - content: module.program + numeric: true, + content: array ? array.length : 0 }; - case `message`: - content = program.message; + case `keys`: + symbolRecord = program.getSymbolRecord(value.name); + data = program.getValue(symbolRecord.value[symbolRecord.index]); + content = data ? JSON.stringify(Object.keys(JSON.parse(data)).sort()) : `[]`; return { type: `constant`, numeric: false, content }; - case `error`: - content = program.errorMessage; + case `index`: + const item = program.getValue(value.item); + const list = JSON.parse(program.getValue(value.list)); + content = list.findIndex(function (value) { + return value === item; + }); return { type: `constant`, - numeric: false, + numeric: true, content }; - case `indexOf`: - const value1 = program.getValue(value.value1); - const value2 = program.getValue(value.value2); - try { - content = JSON.parse(value2).indexOf(value1); - return { - type: `constant`, - numeric: true, - content - }; - } catch (err) { - program.runtimeError(program[program.pc].lino, `Can't parse ${value2}`); + } + } + }, + + condition: { + + compile: () => {}, + + test: () => {} + } +}; +const EasyCoder_Rest = { + + name: `EasyCoder_Rest`, + + Rest: { + + compile: (compiler) => { + const lino = compiler.getLino(); + const request = compiler.nextToken(); + switch (request) { + case `get`: + if (compiler.nextIsSymbol(true)) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + if (compiler.nextTokenIs(`from`)) { + const url = compiler.getNextValue(); + let fixup = compiler.getPc(); + compiler.addCommand({ + domain: `rest`, + keyword: `rest`, + lino, + request: `get`, + target: targetRecord.name, + url, + onError: null + }); + if (compiler.tokenIs(`or`)) { + compiler.next(); + compiler.getCommandAt(fixup).onError = compiler.getPc() + 1; + compiler.completeHandler(); + } + return true; + } + } } break; - case `arg`: - const name = program.getValue(value.value); - const target = program.getSymbolRecord(value.target); - content = target[name]; + case `post`: + let value = null; + if (compiler.nextTokenIs(`to`)) { + compiler.next(); + } else { + value = compiler.getValue(); + if (compiler.tokenIs(`to`)) { + compiler.next(); + } else { + break; + } + } + const url = compiler.getValue(); + if (!url) { + throw new Error(command.lino, `No URL present`); + } + let target = null; + if (compiler.tokenIs(`giving`)) { + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.isVHolder) { + target = targetRecord.name; + compiler.next(); + } else { + throw new Error(`'${targetRecord.name}' cannot hold a value`); + } + } + } + compiler.addCommand({ + domain: `rest`, + keyword: `rest`, + lino, + request: `post`, + value, + url, + target, + onError: compiler.getPc() + 2 + }); + onError = null; + if (compiler.tokenIs(`or`)) { + compiler.next(); + // onError = compiler.getPc() + 1; + compiler.completeHandler(); + } + return true; + } + return false; + }, + + createCORSRequest: (method, url) => { + var xhr = new XMLHttpRequest(); + if (`withCredentials` in xhr) { + + // Check if the XMLHttpRequest object has a "withCredentials" property. + // "withCredentials" only exists on XMLHTTPRequest2 objects. + xhr.open(method, url, true); + + } else if (typeof XDomainRequest != `undefined`) { + + // Otherwise, check if XDomainRequest. + // XDomainRequest only exists in IE, and is IE's way of making CORS requests. + xhr = new XDomainRequest(); + xhr.open(method, url); + + } else { + + // Otherwise, CORS is not supported by the browser. + xhr = null; + + } + return xhr; + }, + + run: (program) => { + const command = program[program.pc]; + const url = program.getValue(command.url); + const rest = EasyCoder_Plugins.rest(); + const path = url.startsWith(`http`) ? url + : url[0] === `/` ? url.substr(1) + : `${window.location.origin}${rest ? `/${rest}` : ``}/${url}`; + + const request = EasyCoder_Rest.Rest.createCORSRequest(command.request, path); + if (!request) { + program.runtimeError(command.lino, `CORS not supported`); + return; + } + request.script = program.script; + request.pc = program.pc; + + request.onload = function () { + let s = request.script; + let p = EasyCoder.scripts[s]; + let pc = request.pc; + let c = p[pc]; + if (200 <= request.status && request.status < 400) { + var content = request.responseText.trim(); + if (c.target) { + const targetRecord = program.getSymbolRecord(command.target); + targetRecord.value[targetRecord.index] = { + type: `constant`, + numeric: false, + content + }; + targetRecord.used = true; + } + p.run(c.pc + 1); + } else { + const error = `${request.status} ${request.statusText}`; + if (c.onError) { + p.errorMessage = `Exception trapped: ${error}`; + p.run(c.onError); + } else { + p.runtimeError(c.lino, `Error: ${error}`); + } + } + }; + + request.onerror = function () { + if (command.onError) { + program.errorMessage = this.responseText; + program.run(command.onError); + } else { + const error = this.responseText; + program.runtimeError(command.lino, error); + } + }; + + switch (command.request) { + case `get`: + // console.log(`GET from ${path}`); + request.send(); + break; + case `post`: + const value = program.getValue(command.value); + console.log(`POST to ${path}`); + //console.log(`value=${value}`); + request.setRequestHeader(`Content-type`, `application/json; charset=UTF-8`); + request.send(value); + break; + } + return 0; + } + }, + + getHandler: (name) => { + switch (name) { + case `rest`: + return EasyCoder_Rest.Rest; + default: + return null; + } + }, + + run: (program) => { + const command = program[program.pc]; + const handler = EasyCoder_Rest.getHandler(command.keyword); + if (!handler) { + program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'rest' package`); + } + return handler.run(program); + }, + + value: { + + compile: () => { + return null; + }, + + get: () => { + return null; + } + }, + + condition: { + + compile: () => {}, + + test: () => {} + } +}; +// eslint-disable-next-line no-unused-vars +const EasyCoder_Compare = (program, value1, value2) => { + + const val1 = program.value.evaluate(program, value1); + const val2 = program.value.evaluate(program, value2); + var v1 = val1.content; + var v2 = val2.content; + if (v1 && val1.numeric) { + if (!val2.numeric) { + v2 = (v2 === `` || v2 === `-` || typeof v2 === `undefined`) ? 0 : parseInt(v2); + } + } else { + if (v2 && val2.numeric) { + v2 = v2.toString(); + } + if (typeof v1 === `undefined`) { + v1 = ``; + } + if (typeof v2 === `undefined`) { + v2 = ``; + } + } + if (v1 > v2) { + return 1; + } + if (v1 < v2) { + return -1; + } + return 0; +}; +// eslint-disable-next-line no-unused-vars +const EasyCoder_Condition = { + + name: `EasyCoder_Condition`, + + compile: (compiler) => { + // See if any of the domains can handle it + compiler.mark(); + for (const domainName of Object.keys(compiler.domain)) { + // console.log(`Try domain '${domainName}' for condition`); + const domain = compiler.domain[domainName]; + const code = domain.condition.compile(compiler); + if (code) { return { - type: `constant`, - numeric: !isNaN(content), - content + domain: name, + ...code }; - case `char`: - let index = program.getValue(value.index); - let string = program.getValue(value.value); - return { + } + compiler.rewind(); + } + }, + + // runtime + + test: (program, condition) => { + const handler = program.domain[condition.domain]; + return handler.condition.test(program, condition); + } +}; +const EasyCoder_Value = { + + name: `EasyCoder_Value`, + + getItem: (compiler) => { + const token = compiler.getToken(); + if (!token) { + return null; + } + + // Check for a boolean + if (token === `true`) { + compiler.next(); + return { + type: `boolean`, + content: true + }; + } + + if (token === `false`) { + compiler.next(); + return { + type: `boolean`, + content: false + }; + } + + // Check for a string constant + if (token.charAt(0) === `\``) { + compiler.next(); + const value = { + type: `constant`, + numeric: false, + content: token.substring(1, token.length - 1) + }; + return value; + } + + // Check for a numeric constant + if (token.charAt(0).match(/[0-9-]/)) { + const val = eval(token); + if (Number.isInteger(val)) { + compiler.next(); + const value = { type: `constant`, - numeric: false, - content: string[index] + numeric: true, + content: val }; + return value; + } else { + throw new Error(`'${token}' is not an integer`); + } + } + + // See if any of the domains can handle it + const index = compiler.getIndex(); + for (const name of Object.keys(compiler.domain)) { + compiler.rewindTo(index); + const handler = compiler.domain[name]; + const code = handler.value.compile(compiler); + if (code) { + return code; + } + } + return null; + }, + + compile: compiler => { + const token = compiler.getToken(); + const item = EasyCoder_Value.getItem(compiler); + if (!item) { + throw new Error(`Undefined value: '${token}'`); + } + + if (compiler.getToken() === `cat`) { + const value = { + type: `cat`, + numeric: false, + parts: [item] + }; + while (compiler.tokenIs(`cat`)) { + compiler.next(); + value.parts.push(compiler.value.getItem(compiler)); } + return value; + } + + return item; + }, + + // runtime + + doValue: (program, value) => { + // console.log('Value:doValue:value: '+JSON.stringify(value,null,2)); + // See if it's a constant string, a variable or something else + if (typeof value.type === `undefined`) { + program.runtimeError(program[program.pc].lino, `Undefined value (variable not initialized?)`); return null; - }, + } + const type = value.type; + switch (type) { + case `cat`: + return { + type: `constant`, + numeric: false, + content: value.parts.reduce(function (acc, part) { + let value = EasyCoder_Value.doValue(program, part); + return acc + (value ? value.content : ``); + }, ``) + }; + case `boolean`: + case `constant`: + return value; + case `symbol`: + const symbol = program.getSymbolRecord(value.name); + if (symbol.isVHolder) { + const symbolValue = symbol.value[symbol.index]; + if (symbolValue) { + const v = symbolValue.content; + if (v === null || typeof v === `undefined`) { + symbolValue.content = symbolValue.numeric ? 0 : ``; + } + return symbolValue; + } else { + return null; + } + } else { + const handler = program.domain[symbol.domain].value; + return handler.get(program, value); + } + default: + break; + } + // Call the given domain to handle a value + const handler = program.domain[value.domain].value; + return handler.get(program, value); + }, - put: (symbol, value) => { - symbol.value[symbol.index] = value; + constant: (content, numeric) => { + return { + type: `constant`, + numeric, + content + }; + }, + + evaluate: (program, value) => { + if (!value) { + return { + type: `constant`, + numeric: false, + content: `` + }; + } + const result = EasyCoder_Value.doValue(program, value); + if (result) { + return result; } + program.runtimeError(program[program.pc].lino, `Can't decode value: ` + value); }, - condition: { + getValue: (program, value) => { + return EasyCoder_Value.evaluate(program, value).content; + }, + + // tools + + encode: (value, encoding) => { + if (value) { + switch (encoding) { + case `ec`: + return value.replace(/\n/g, `%0a`) + .replace(/\r/g, `%0d`) + .replace(/"/g, `~dq~`) + .replace(/'/g, `~sq~`) + .replace(/\\/g, `~bs~`); + case `url`: + return encodeURIComponent(value.replace(/\s/g, `+`)); + case `sanitize`: + return value.normalize(`NFD`).replace(/[\u0300-\u036f]/g, ``); + default: + return value; + } + } + return value; + }, + + decode: (value, encoding) => { + if (value) { + switch (encoding) { + case `ec`: + return value.replace(/%0a/g, `\n`) + .replace(/%0d/g, `\r`) + .replace(/~dq~/g, `"`) + .replace(/~sq~/g, `'`) + .replace(/~bs~/g, `\\`); + case `url`: + const decoded = decodeURIComponent(value); + return decoded.replace(/\+/g, ` `); + default: + return value; + } + } + return value; + } +}; +const EasyCoder_Run = { + + name: `EasyCoder_Run`, + + run: (program, pc) =>{ + + const queue = []; - compile: compiler => { - if (compiler.isSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.keyword === `module`) { - if (compiler.nextTokenIs(`is`)) { - let sense = true; - if (compiler.nextTokenIs(`not`)) { - compiler.next(); - sense = false; - } - if (compiler.tokenIs(`running`)) { - compiler.next(); - return { - domain: `core`, - type: `moduleRunning`, - name: symbolRecord.name, - sense - }; - } + const minIndent = (scriptLines) => { + let count = 9999; + scriptLines.forEach(function (element) { + const item = element.line; + let n = 0; + while (n < item.length) { + if (item[n] !== ` `) { + break; } - return null; + n++; } - } - if (compiler.tokenIs(`not`)) { - const value = compiler.getNextValue(); - return { - domain: `core`, - type: `not`, - value - }; - } - try { - const value1 = compiler.getValue(); - const token = compiler.getToken(); - if (token === `includes`) { - const value2 = compiler.getNextValue(); - return { - domain: `core`, - type: `includes`, - value1, - value2 - }; + if (n > 0 && n < count) { + count = n; } - if (token === `is`) { - compiler.next(); - const negate = EasyCoder_Core.isNegate(compiler); - const test = compiler.getToken(); - switch (test) { - case `numeric`: - compiler.next(); - return { - domain: `core`, - type: `numeric`, - value1, - negate - }; - case `even`: - compiler.next(); - return { - domain: `core`, - type: `even`, - value1 - }; - case `odd`: - compiler.next(); - return { - domain: `core`, - type: `odd`, - value1 - }; - case `greater`: - compiler.next(); - if (compiler.tokenIs(`than`)) { - compiler.next(); - const value2 = compiler.getValue(); - return { - domain: `core`, - type: `greater`, - value1, - value2, - negate + }); + return 0; + }; + + if (queue.length) { + queue.push(pc); + return; + } + program.register(program); + queue.push(pc); + while (queue.length > 0) { + program.pc = queue.shift(); + program.watchdog = 0; + while (program.running) { + if (program.watchdog > 1000000) { + program.lino = program[program.pc].lino; + program.reportError( + new Error(`Program runaway intercepted.\nHave you forgotten to increment a loop counter?`, program), + program); + break; + } + program.watchdog++; + const domain = program[program.pc].domain; + if (program.debugStep) { + console.log(`${program.script}: Line ${program[program.pc].lino}: PC: ${program.pc} ${domain}:${program[program.pc].keyword}`); + } + const handler = program.domain[domain]; + if (!handler) { + program.runtimeError(program[program.pc].lino, `Unknown domain '${domain}'`); + break; + } + program.pc = handler.run(program); + if (!program.pc) { + break; + } + if (program.stop) { + program.tracing = false; + break; + } + if (program.tracing) { + const command = program[program.pc]; + const scriptLines = program.source.scriptLines; + const minSpace = minIndent(scriptLines); + const tracer = document.getElementById(`easycoder-tracer`); + if (!tracer) { + program.runtimeError(command.lino, `Element 'easycoder-tracer' was not found`); + return; + } + tracer.style.display = `block`; + tracer.style.visibility = `visible`; + var variables = ``; + if (program.tracer) { + const content = document.getElementById(`easycoder-tracer-content`); + if (content) { + program.tracer.variables.forEach(function (name, index, array) { + const symbol = program.getSymbolRecord(name); + if (symbol.elements > 1) { + variables += `${name}: ${symbol.index}/${symbol.elements}: `; + for (var n = 0; n < symbol.elements; n++) { + const value = symbol.value[n]; + if (value) { + variables += `${value.content} `; + } else { + variables += `undefined `; + } + } + } else { + const value = symbol.value[symbol.index]; + if (value) { + variables += `${name}: ${value.content}`; + } else { + variables += `${name}: undefined`; + } + } + switch (program.tracer.alignment) { + case `horizontal`: + if (index < array.length - 1) { + variables += `, `; + } + break; + case `vertical`: + variables += `
`; + break; + } + }); + variables += `
`; + var trace = ``; + for (var n = 5; n > 0; n--) { + if (command.lino) { + const text = scriptLines[command.lino - n].line.substr(minSpace); + trace += ``; + } + trace += `
`; + } + content.innerHTML = `${variables} ${trace}`; + content.style.display = `block`; + const run = document.getElementById(`easycoder-run-button`); + const step = document.getElementById(`easycoder-step-button`); + + run.onclick = function () { + run.blur(); + program.tracing = false; + const content = document.getElementById(`easycoder-tracer-content`); + content.style.display = `none`; + try { + EasyCoder_Run.run(program, program.resume); + } catch (err) { + const message = `Error in run handler: ` + err.message; + console.log(message); + alert(message); + } }; - } - return null; - case `less`: - compiler.next(); - if (compiler.tokenIs(`than`)) { - compiler.next(); - const value2 = compiler.getValue(); - return { - domain: `core`, - type: `less`, - value1, - value2, - negate + + step.onclick = function () { + console.log(`step`); + step.blur(); + program.tracing = true; + const content = document.getElementById(`easycoder-tracer-content`); + content.style.display = `block`; + try { + program.run(program.resume); + } catch (err) { + const message = `Error in step handler: ` + err.message; + console.log(message); + alert(message); + } }; - } - return null; - default: - const value2 = compiler.getValue(); - return { - domain: `core`, - type: `is`, - value1, - value2, - negate - }; - } - } else if (value1) { - // It's a boolean if - return { - domain: `core`, - type: `boolean`, - value: value1 - }; - } - } catch (err) { - compiler.warning(`Can't get a value`); - return 0; - } - return null; - }, + } - test: (program, condition) => { - var comparison; - switch (condition.type) { - case `boolean`: - return program.getValue(condition.value); - case `numeric`: - let v = program.getValue(condition.value1); - let test = v === ` ` || isNaN(v); - return condition.negate ? test : !test; - case `even`: - return (program.getValue(condition.value1) % 2) === 0; - case `odd`: - return (program.getValue(condition.value1) % 2) === 1; - case `is`: - comparison = program.compare(program, condition.value1, condition.value2); - return condition.negate ? comparison !== 0 : comparison === 0; - case `greater`: - comparison = program.compare(program, condition.value1, condition.value2); - return condition.negate ? comparison <= 0 : comparison > 0; - case `less`: - comparison = program.compare(program, condition.value1, condition.value2); - return condition.negate ? comparison >= 0 : comparison < 0; - case `not`: - return !program.getValue(condition.value); - case `moduleRunning`: - let moduleRecord = program.getSymbolRecord(condition.name); - if (EasyCoder.scripts.hasOwnProperty(moduleRecord.program) ) { - let p = EasyCoder.scripts[moduleRecord.program]; - return condition.sense ? p.running : !p.running; + program.resume = program.pc; + program.pc = 0; + } + break; } - return !condition.sense; - case `includes`: - const value1 = JSON.parse(program.getValue(condition.value1)); - const value2 = program.getValue(condition.value2); - return value1.includes(value2); } - return false; + } + }, + + exit: (program) => { + if (program.onExit) { + program.run(program.onExit); + } + let parent = program.parent; + let afterExit = program.afterExit; + delete EasyCoder.scripts[program.script]; + if (program.module) { + delete program.module.program; + } + Object.keys(program).forEach(function(key) { + delete program[key]; + }); + if (parent && afterExit) { + EasyCoder.scripts[parent].run(afterExit); } } }; -const EasyCoder = { +// eslint-disable-next-line no-unused-vars +const EasyCoder_Compiler = { - name: `EasyCoder_Main`, + name: `EasyCoder_Compiler`, - domain: { - core: EasyCoder_Core + getTokens: function() { + return this.tokens; }, - elementId: 0, - - runtimeError: function (lino, message) { - this.lino = lino; - this.reportError({ - message: `Line ${(lino >= 0) ? lino : ``}: ${message}` - }, this.program); - if (this.program) { - this.program.aborted = true; - } + addWarning: function(message) { + this.warnings.push(message); }, - nonNumericValueError: function (lino) { - this.runtimeError(lino, `Non-numeric value`); + + warning: function(message) { + this.addWarning(message); }, - variableDoesNotHoldAValueError: function (lino, name) { - this.runtimeError(lino, `Variable '${name}' does not hold a value`); + + unrecognisedSymbol: function(item) { + this.addWarning(`Unrecognised symbol '${item}'`); }, - reportError: function (err, program, source) { - if (!err.message) { - console.log(`An error occurred - origin was ${err.path[0]}`); - return; - } - if (!this.compiling && !program) { - const errString = `Error: ${err.message}`; - alert(errString); - console.log(errString); - return; - } - // const compiler = EasyCoder_Compiler; - const { - tokens, - scriptLines - } = source ? source : program.source; - const lino = this.compiling ? tokens[EasyCoder_Compiler.getIndex()].lino : program[program.pc].lino; - var errString = this.compiling ? `Compile error` : `Runtime error in '${program.script}'`; - errString += `:\n`; - var start = lino - 5; - start = start < 0 ? 0 : start; - for (var n = start; n < lino; n++) { - const nn = (`` + (n + 1)).padStart(4, ` `); - errString += nn + ` ` + scriptLines[n].line.split(`\\s`).join(` `) + `\n`; - } - errString += `${err.message}\n`; - const warnings = EasyCoder_Compiler.getWarnings(); - if (warnings.length) { - errString += `Warnings:\n`; - for (const warning of warnings) { - errString += `${warning}\n`; - } - } - console.log(errString); - alert(errString); + getWarnings: function() { + return this.warnings; }, - getSymbolRecord: function (name) { - const target = this[this.symbols[name].pc]; - if (target.alias) { - return this.getSymbolRecord(target.alias); - } - if (target.exporter) { - // if (target.exporter != this.script) { - return EasyCoder.scripts[target.exporter].getSymbolRecord(target.exportedName); - // } - } - return target; + getIndex: function() { + return this.index; }, - verifySymbol: function (name) { - return this.symbols.hasOwnProperty(name); + next: function(step = 1) { + this.index = this.index + step; }, - encode: function (value) { - return EasyCoder_Value.encode(value, this.encoding); + peek: function() { + return this.tokens[this.index + 1].token; }, - decode: function (value) { - return EasyCoder_Value.decode(value, this.encoding); + more: function() { + return this.index < this.tokens.length; }, - evaluate: function (value) { - return EasyCoder_Value.evaluate(this, value); + getToken: function() { + if (this.index >= this.tokens.length) { + return null; + } + const item = this.tokens[this.index]; + return item ? this.tokens[this.index].token : null; }, - getValue: function (value) { - return EasyCoder_Value.getValue(this, value); + nextToken: function() { + this.next(); + return this.getToken(); }, - getFormattedValue: function (value) { - const v = EasyCoder_Value.evaluate(this, value); - if (v.numeric) { - return v.content; + tokenIs: function(token) { + if (this.index >= this.tokens.length) { + return false; } - if (v.type === `boolean`) { - return v.content ? `true` : `false`; + return token === this.tokens[this.index].token; + }, + + nextTokenIs: function(token) { + this.next(); + return this.tokenIs(token); + }, + + skip: function(token) { + if (this.index >= this.tokens.length) { + return null; } - if (this.isJsonString(v.content)) { - try { - const parsed = JSON.parse(v.content); - return JSON.stringify(parsed, null, 2); - } catch (err) { - this.reportError(err); - return `{}`; - } + this.next(); + if (this.tokenIs(token)) { + this.next(); } - return v.content; }, - getSimpleValue: function (content) { - if (content === true || content === false) { - return { - type: `boolean`, - content - }; - } - return { - type: `constant`, - numeric: Number.isInteger(content), - content - }; + prev: function() { + this.index--; }, - run: function (pc) { - if (pc) { - this.program = this; - EasyCoder_Run.run(this, pc); + getLino: function() { + if (this.index >= this.tokens.length) { + return 0; } + return this.tokens[this.index].lino; }, - exit: function () { - EasyCoder_Run.exit(this); + getTarget: function(index = this.index) { + return this.tokens[index].token; }, - register: (program) => { - this.program = program; + getTargetPc: function(index = this.index) { + return this.symbols[this.getTarget(index)].pc; }, - require: function(type, src, cb) { - const element = document.createElement(type === `css` ? `link` : `script`); - switch (type) { - case `css`: - element.type = `text/css`; - element.href = src; - element.rel = `stylesheet`; - break; - case `js`: - element.type = `text/javascript`; - element.src = src; - break; - default: - return; + getCommandAt: function(pc) { + return this.program[pc]; + }, + + isSymbol: function(required = false) { + const isSymbol = this.getTarget() in this.symbols; + if (isSymbol) return true; + if (required) { + throw new Error(`Unknown symbol: '${this.getTarget()}'`); } - element.onload = function () { - console.log(`${Date.now() - EasyCoder.timestamp} ms: Library ${src} loaded`); - cb(); - }; - document.head.appendChild(element); + return false; + }, + + nextIsSymbol: function(required = false) { + this.next(); + return this.isSymbol(required); }, - isUndefined: item => { - return typeof item === `undefined`; + getSymbol: function(required = false) { + if (this.isSymbol(required)) { + return this.symbols[this.getToken()]; + } }, - isJsonString: function (str) { - try { - JSON.parse(str); - } catch (e) { - return false; - } - return true; + getSymbolPc: function(required = false) { + return this.getSymbol(required).pc; }, - runScript: function (program) { - const command = program[program.pc]; - const script = program.getValue(command.script); - const imports = command.imports; - imports.caller = program.script; - const moduleRecord = command.module ? program.getSymbolRecord(command.module) : null; - try { - EasyCoder.tokeniseAndCompile(script.split(`\n`), imports, moduleRecord, this.script, command.then); - } catch (err) { - EasyCoder.reportError(err, program, program.source); - if (program.onError) { - program.run(program.onError); - } else { - let parent = EasyCoder.scripts[program.parent]; - if (parent && parent.onError) { - parent.run(parent.onError); - } - } - return; - } - if (command.nowait) { - EasyCoder.run(program.nextPc); - } + getSymbolRecord: function() { + const record = this.program[this.getSymbolPc(true)]; + record.used = true; + return record; }, - close: function () {}, + getSymbols: function() { + return this.symbols; + }, - compileScript: function (source, imports, module, parent) { - const { - tokens - } = source; - this.compiling = true; - const compiler = EasyCoder_Compiler; - this.compiler = compiler; - compiler.value = EasyCoder_Value; - compiler.condition = EasyCoder_Condition; - compiler.domain = this.domain; - compiler.imports = imports; - compiler.continue = false; - const program = EasyCoder_Compiler.compile(tokens); - // console.log('Program: ' + JSON.stringify(program, null, 2)); - this.compiling = false; + getProgram: function() { + return this.program; + }, - program.EasyCoder = this; - program.value = EasyCoder_Value; - program.condition = EasyCoder_Condition; - program.compare = EasyCoder_Compare; - program.source = source; - program.run = this.run; - program.exit = this.exit; - program.runScript = this.runScript; - program.evaluate = this.evaluate; - program.getValue = this.getValue; - program.getFormattedValue = this.getFormattedValue; - program.getSimpleValue = this.getSimpleValue; - program.encode = this.encode; - program.decode = this.decode; - program.domain = this.domain; - program.require = this.require; - program.isUndefined = this.isUndefined; - program.isJsonString = this.isJsonString; - program.checkPlugin = this.checkPlugin; - program.getPlugin = this.getPlugin; - program.addLocalPlugin = this.addLocalPlugin; - program.getPluginsPath = this.getPluginsPath; - program.getSymbolRecord = this.getSymbolRecord; - program.verifySymbol = this.verifySymbol; - program.runtimeError = this.runtimeError; - program.nonNumericValueError = this.nonNumericValueError; - program.variableDoesNotHoldAValueError = this.variableDoesNotHoldAValueError; - program.reportError = this.reportError; - program.register = this.register; - program.symbols = compiler.getSymbols(); - program.unblocked = false; - program.encoding = `ec`; - program.popups = []; - program.stack = []; - program.queue = [0]; - program.module = module; - program.parent = parent; - if (module) { - module.program = program.script; - } - return program; + getPc: function() { + return this.program.length; }, - tokeniseFile: function(file) { - const scriptLines = []; - const tokens = []; - let index = 0; - file.forEach(function (line, lino) { - scriptLines.push({ - lino: lino + 1, - line - }); - const len = line.length; - let token = ``; - let inSpace = true; - for (let n = 0; n < len; n++) { - const c = line[n]; - if (c.trim().length == 0) { - if (inSpace) { - continue; - } - tokens.push({ - index, - lino: lino + 1, - token - }); - index++; - token = ``; - inSpace = true; - continue; - } - inSpace = false; - if (c === `\``) { - m = n; - while (++n < line.length) { - if (line[n] === `\``) { - break; - } - } - token = line.substr(m, n - m + 1); - } else if (c == `!`) { - break; - } else { - token += c; - } - } - if (token.length > 0) { - tokens.push({ - index, - lino: lino + 1, - token - }); - } - }); - return {scriptLines, tokens}; + getValue: function() { + return this.value.compile(this); }, - tokeniseAndCompile: function (file, imports, module, parent, then) { - // console.log('Tokenise script: '); - let program = null; - const startCompile = Date.now(); - const source = this.tokeniseFile(file); - try { - program = this.compileScript(source, imports, module, parent); - this.scriptIndex++; - if (!program.script) { - program.script = this.scriptIndex; - } - const finishCompile = Date.now(); - console.log(`${finishCompile - this.timestamp} ms: ` + - `Compiled ${program.script}: ${source.scriptLines.length} lines (${source.tokens.length} tokens) in ` + - `${finishCompile - startCompile} ms`); - } catch (err) { - if (err.message !== `stop`) { - let parentRecord = EasyCoder.scripts[parent]; - this.reportError(err, parentRecord, source); - if (parentRecord && parentRecord.onError) { - parentRecord.run(parentRecord.onError); - } - // Remove this script - if (EasyCoder_Compiler.script) { - delete EasyCoder.scripts[EasyCoder_Compiler.script]; - delete EasyCoder_Compiler.script; - } - } - return; - } - if (program) { - EasyCoder.scripts[program.script] = program; - if (module) { - module.program = program.script; - } - program.afterExit = then; - program.running = true; - EasyCoder_Run.run(program, 0); - } + getNextValue: function() { + this.next(); + return this.getValue(); }, - tokenise: function(source) { - const script = source.split(`\n`); - if (!this.tokenising) { - try { - this.tokeniseAndCompile(script); - } catch (err) { - this.reportError(err, null, source); - } - this.tokenising = true; - } + getCondition: function() { + return this.condition.compile(this); }, - setPluginCount: function(count) { - EasyCoder.plugins = []; - EasyCoder.pluginCount = count; + constant: function(content, numeric = false) { + return this.value.constant(content, numeric); }, - checkPlugin: function(name) { - return EasyCoder.domain[name]; + addCommand: function(item) { + const pc = this.program.length; + this.program.push({ + pc, + ...item + }); }, - getPlugin: function(name, src, onload) { - if (EasyCoder.domain[name]) { - onload(); - return; - } - const script = document.createElement(`script`); - script.type = `text/javascript`; - let location = document.scripts[0].src; - location = location.substring(0, location.indexOf(`/easycoder.js`)); - // script.src = `${location}/${src}?ver=${EasyCoder.version}`; - script.src = `${src}?ver=${EasyCoder.version}`; - script.onload = function () { - console.log(`${Date.now() - EasyCoder.timestamp} ms: Plugin ${src} loaded`); - onload(); + addSymbol: function(name, pc) { + this.symbols[name] = { + pc }; - document.head.appendChild(script); }, - addGlobalPlugin: function(name, handler) { - // alert(`Add plugin ${name}`); - EasyCoder.plugins.push({ - name, - handler - }); - if (EasyCoder.plugins.length === EasyCoder.pluginCount) { - EasyCoder.plugins.forEach(function (plugin) { - EasyCoder.domain[plugin.name] = plugin.handler; - }); - EasyCoder.tokenise(EasyCoder.source); - } + mark: function() { + this.savedMark = this.index; }, - addLocalPlugin: function(name, handler, callback) { - EasyCoder.domain[name] = handler; - callback(); + rewind: function() { + this.index = this.savedMark; }, - getPluginsPath: function() { - return EasyCoder.pluginsPath; + rewindTo: function(index) { + this.index = index; }, - loadPluginJs: function(path) { - console.log(`${Date.now() - this.timestamp} ms: Load ${path}/easycoder/plugins.js`); - const script = document.createElement(`script`); - script.src = `${window.location.origin}${path}/easycoder/plugins.js?ver=${this.version}`; - script.type = `text/javascript`; - script.onload = () => { - EasyCoder_Plugins.getGlobalPlugins( - this.timestamp, - path, - this.setPluginCount, - this.getPlugin, - this.addGlobalPlugin - ); - }; - script.onerror = () => { - if (path) { - this.loadPluginJs(path.slice(0, path.lastIndexOf(`/`))); - } else { - this.reportError({ - message: `Can't load plugins.js` - }, this.program, this.source); - } - }; - document.head.appendChild(script); - this.pluginsPath = path; + completeHandler: function() { + const lino = this.getLino(); + // Add a 'goto' to skip the action + const goto = this.getPc(); + this.addCommand({ + domain: `core`, + keyword: `goto`, + lino, + goto: 0 + }); + // Add the action + this.compileOne(); + // If `continue` is set + if (this.continue) { + this.addCommand({ + domain: `core`, + keyword: `goto`, + lino, + goto: this.getPc() + 1 + }); + this.continue = false; + } + // else add a 'stop' + else { + this.addCommand({ + domain: `core`, + keyword: `stop`, + lino, + next: 0 + }); + } + // Fixup the 'goto' + this.getCommandAt(goto).goto = this.getPc(); + return true; }, - start: function(source) { - this.source = source; - this.scriptIndex = 0; - let pathname = window.location.pathname; - if (pathname.endsWith(`/`)) { - pathname = pathname.slice(0, -1); - } else { - pathname = ``; - } - if (typeof EasyCoder_Plugins === `undefined`) { - this.loadPluginJs(pathname); - } else { - this.pluginsPath = pathname; - EasyCoder_Plugins.getGlobalPlugins( - this.timestamp, - pathname, - this.setPluginCount, - this.getPlugin, - this.addGlobalPlugin - ); + compileVariable: function(domain, keyword, isVHolder = false, extra = null) { + this.next(); + const lino = this.getLino(); + const item = this.getTokens()[this.getIndex()]; + if (this.symbols[item.token]) { + throw new Error(`Duplicate variable name '${item.token}'`); } - } -}; -const EasyCoder_Run = { - - name: `EasyCoder_Run`, - - run: (program, pc) =>{ - - const queue = []; - - const minIndent = (scriptLines) => { - let count = 9999; - scriptLines.forEach(function (element) { - const item = element.line; - let n = 0; - while (n < item.length) { - if (item[n] !== ` `) { - break; - } - n++; - } - if (n > 0 && n < count) { - count = n; - } - }); - return 0; + const pc = this.getPc(); + this.next(); + this.addSymbol(item.token, pc); + const command = { + domain, + keyword, + lino, + isSymbol: true, + used: false, + isVHolder, + name: item.token, + elements: 1, + index: 0, + value: [{}], + element: [], + extra }; + if (extra === `dom`) { + command.element = []; + } + this.addCommand(command); + return command; + }, - if (queue.length) { - queue.push(pc); + compileToken: function() { + // Try each domain in turn until one can handle the command + const token = this.getToken(); + if (!token) { return; } - program.register(program); - queue.push(pc); - while (queue.length > 0) { - program.pc = queue.shift(); - program.watchdog = 0; - while (program.running) { - if (program.watchdog > 1000000) { - program.lino = program[program.pc].lino; - program.reportError( - new Error(`Program runaway intercepted.\nHave you forgotten to increment a loop counter?`, program), - program); - break; - } - program.watchdog++; - const domain = program[program.pc].domain; - if (program.debugStep) { - console.log(`${program.script}: Line ${program[program.pc].lino}: PC: ${program.pc} ${domain}:${program[program.pc].keyword}`); - } - const handler = program.domain[domain]; - if (!handler) { - program.runtimeError(program[program.pc].lino, `Unknown domain '${domain}'`); - break; - } - program.pc = handler.run(program); - if (!program.pc) { - break; - } - if (program.stop) { - program.tracing = false; - break; - } - if (program.tracing) { - const command = program[program.pc]; - const scriptLines = program.source.scriptLines; - const minSpace = minIndent(scriptLines); - const tracer = document.getElementById(`easycoder-tracer`); - if (!tracer) { - program.runtimeError(command.lino, `Element 'easycoder-tracer' was not found`); + // console.log(`Compile ${token}`); + this.mark(); + for (const domainName of Object.keys(this.domain)) { + // console.log(`Try domain ${domainName} for token ${token}`); + const domain = this.domain[domainName]; + if (domain) { + const handler = domain.getHandler(token); + if (handler) { + if (handler.compile(this)) { return; } - tracer.style.display = `block`; - tracer.style.visibility = `visible`; - var variables = ``; - if (program.tracer) { - const content = document.getElementById(`easycoder-tracer-content`); - if (content) { - program.tracer.variables.forEach(function (name, index, array) { - const symbol = program.getSymbolRecord(name); - if (symbol.elements > 1) { - variables += `${name}: ${symbol.index}/${symbol.elements}: `; - for (var n = 0; n < symbol.elements; n++) { - const value = symbol.value[n]; - if (value) { - variables += `${value.content} `; - } else { - variables += `undefined `; - } - } - } else { - const value = symbol.value[symbol.index]; - if (value) { - variables += `${name}: ${value.content}`; - } else { - variables += `${name}: undefined`; - } - } - switch (program.tracer.alignment) { - case `horizontal`: - if (index < array.length - 1) { - variables += `, `; - } - break; - case `vertical`: - variables += `
`; - break; - } - }); - variables += `
`; - var trace = ``; - for (var n = 5; n > 0; n--) { - if (command.lino) { - const text = scriptLines[command.lino - n].line.substr(minSpace); - trace += ``; - } - trace += `
`; - } - content.innerHTML = `${variables} ${trace}`; - content.style.display = `block`; - const run = document.getElementById(`easycoder-run-button`); - const step = document.getElementById(`easycoder-step-button`); - - run.onclick = function () { - run.blur(); - program.tracing = false; - const content = document.getElementById(`easycoder-tracer-content`); - content.style.display = `none`; - try { - EasyCoder_Run.run(program, program.resume); - } catch (err) { - const message = `Error in run handler: ` + err.message; - console.log(message); - alert(message); - } - }; - - step.onclick = function () { - console.log(`step`); - step.blur(); - program.tracing = true; - const content = document.getElementById(`easycoder-tracer-content`); - content.style.display = `block`; - try { - program.run(program.resume); - } catch (err) { - const message = `Error in step handler: ` + err.message; - console.log(message); - alert(message); - } - }; - } - - program.resume = program.pc; - program.pc = 0; - } - break; } } + this.rewind(); } + console.log(`No handler found`); + throw new Error(`I don't understand '${token}...'`); }, - exit: (program) => { - if (program.onExit) { - program.run(program.onExit); + compileOne: function() { + const keyword = this.getToken(); + if (!keyword) { + return; } - let parent = program.parent; - let afterExit = program.afterExit; - delete EasyCoder.scripts[program.script]; - if (program.module) { - delete program.module.program; + // console.log(`Compile keyword '${keyword}'`); + this.warnings = []; + const pc = this.program.length; + // First check for a label + if (keyword.endsWith(`:`)) { + const name = keyword.substring(0, keyword.length - 1); + if (this.symbols[name]) { + throw new Error(`Duplicate symbol: '${name}'`); + } + this.symbols[name] = { + pc + }; + this.index++; + } else { + this.compileToken(); } - Object.keys(program).forEach(function(key) { - delete program[key]; + }, + + compileFromHere: function(stopOn) { + while (this.index < this.tokens.length) { + const token = this.tokens[this.index]; + const keyword = token.token; + if (keyword === `else`) { + return this.program; + } + this.compileOne(); + if (stopOn.indexOf(keyword) > -1) { + break; + } + } + }, + + compile: function(tokens) { + this.tokens = tokens; + this.index = 0; + this.program = []; + this.program.script = 0; + this.program.symbols = {}; + this.symbols = this.program.symbols; + this.warnings = []; + this.compileFromHere([]); + this.addCommand({ + domain: `core`, + keyword: `exit`, + lino: this.getLino(), + next: 0 }); - if (parent && afterExit) { - EasyCoder.scripts[parent].run(afterExit); + // console.log('Symbols: ' + JSON.stringify(this.symbols, null, 2)); + for (const symbol in this.symbols) { + const record = this.program[this.symbols[symbol].pc]; + if (record.isSymbol && !record.used && !record.exporter) { + console.log(`Symbol '${record.name}' has not been used.`); + } } + return this.program; } }; -const EasyCoder_Value = { +const EasyCoder = { - name: `EasyCoder_Value`, + name: `EasyCoder_Main`, - getItem: (compiler) => { - const token = compiler.getToken(); - if (!token) { - return null; - } + domain: { + core: EasyCoder_Core, + browser: EasyCoder_Browser, + json: EasyCoder_Json, + rest: EasyCoder_Rest + }, - // Check for a boolean - if (token === `true`) { - compiler.next(); - return { - type: `boolean`, - content: true - }; - } + elementId: 0, - if (token === `false`) { - compiler.next(); - return { - type: `boolean`, - content: false - }; + runtimeError: function (lino, message) { + this.lino = lino; + this.reportError({ + message: `Line ${(lino >= 0) ? lino : ``}: ${message}` + }, this.program); + if (this.program) { + this.program.aborted = true; } + }, + nonNumericValueError: function (lino) { + this.runtimeError(lino, `Non-numeric value`); + }, + variableDoesNotHoldAValueError: function (lino, name) { + this.runtimeError(lino, `Variable '${name}' does not hold a value`); + }, - // Check for a string constant - if (token.charAt(0) === `\``) { - compiler.next(); - const value = { - type: `constant`, - numeric: false, - content: token.substring(1, token.length - 1) - }; - return value; + reportError: function (err, program, source) { + if (!err.message) { + console.log(`An error occurred - origin was ${err.path[0]}`); + return; } - - // Check for a numeric constant - if (token.charAt(0).match(/[0-9-]/)) { - const val = eval(token); - if (Number.isInteger(val)) { - compiler.next(); - const value = { - type: `constant`, - numeric: true, - content: val - }; - return value; - } else { - throw new Error(`'${token}' is not an integer`); - } + if (!this.compiling && !program) { + const errString = `Error: ${err.message}`; + alert(errString); + console.log(errString); + return; } - - // See if any of the domains can handle it - const index = compiler.getIndex(); - for (const name of Object.keys(compiler.domain)) { - compiler.rewindTo(index); - const handler = compiler.domain[name]; - const code = handler.value.compile(compiler); - if (code) { - return code; + // const compiler = EasyCoder_Compiler; + const { + tokens, + scriptLines + } = source ? source : program.source; + const lino = this.compiling ? tokens[EasyCoder_Compiler.getIndex()].lino : program[program.pc].lino; + var errString = this.compiling ? `Compile error` : `Runtime error in '${program.script}'`; + errString += `:\n`; + var start = lino - 5; + start = start < 0 ? 0 : start; + for (var n = start; n < lino; n++) { + const nn = (`` + (n + 1)).padStart(4, ` `); + errString += nn + ` ` + scriptLines[n].line.split(`\\s`).join(` `) + `\n`; + } + errString += `${err.message}\n`; + const warnings = EasyCoder_Compiler.getWarnings(); + if (warnings.length) { + errString += `Warnings:\n`; + for (const warning of warnings) { + errString += `${warning}\n`; } } - return null; + console.log(errString); + alert(errString); }, - compile: compiler => { - const token = compiler.getToken(); - const item = EasyCoder_Value.getItem(compiler); - if (!item) { - throw new Error(`Undefined value: '${token}'`); + getSymbolRecord: function (name) { + const target = this[this.symbols[name].pc]; + if (target.alias) { + return this.getSymbolRecord(target.alias); } - - if (compiler.getToken() === `cat`) { - const value = { - type: `cat`, - numeric: false, - parts: [item] - }; - while (compiler.tokenIs(`cat`)) { - compiler.next(); - value.parts.push(compiler.value.getItem(compiler)); - } - return value; + if (target.exporter) { + // if (target.exporter != this.script) { + return EasyCoder.scripts[target.exporter].getSymbolRecord(target.exportedName); + // } } + return target; + }, - return item; + verifySymbol: function (name) { + return this.symbols.hasOwnProperty(name); }, - // runtime + encode: function (value) { + return EasyCoder_Value.encode(value, this.encoding); + }, - doValue: (program, value) => { - // console.log('Value:doValue:value: '+JSON.stringify(value,null,2)); - // See if it's a constant string, a variable or something else - if (typeof value.type === `undefined`) { - program.runtimeError(program[program.pc].lino, `Undefined value (variable not initialized?)`); - return null; + decode: function (value) { + return EasyCoder_Value.decode(value, this.encoding); + }, + + evaluate: function (value) { + return EasyCoder_Value.evaluate(this, value); + }, + + getValue: function (value) { + return EasyCoder_Value.getValue(this, value); + }, + + getFormattedValue: function (value) { + const v = EasyCoder_Value.evaluate(this, value); + if (v.numeric) { + return v.content; } - const type = value.type; - switch (type) { - case `cat`: + if (v.type === `boolean`) { + return v.content ? `true` : `false`; + } + if (this.isJsonString(v.content)) { + try { + const parsed = JSON.parse(v.content); + return JSON.stringify(parsed, null, 2); + } catch (err) { + this.reportError(err); + return `{}`; + } + } + return v.content; + }, + + getSimpleValue: function (content) { + if (content === true || content === false) { return { - type: `constant`, - numeric: false, - content: value.parts.reduce(function (acc, part) { - let value = EasyCoder_Value.doValue(program, part); - return acc + (value ? value.content : ``); - }, ``) + type: `boolean`, + content }; - case `boolean`: - case `constant`: - return value; - case `symbol`: - const symbol = program.getSymbolRecord(value.name); - if (symbol.isVHolder) { - const symbolValue = symbol.value[symbol.index]; - if (symbolValue) { - const v = symbolValue.content; - if (v === null || typeof v === `undefined`) { - symbolValue.content = symbolValue.numeric ? 0 : ``; - } - return symbolValue; - } else { - return null; - } - } else { - const handler = program.domain[symbol.domain].value; - return handler.get(program, value); - } - default: + } + return { + type: `constant`, + numeric: Number.isInteger(content), + content + }; + }, + + run: function (pc) { + if (pc) { + this.program = this; + EasyCoder_Run.run(this, pc); + } + }, + + exit: function () { + EasyCoder_Run.exit(this); + }, + + register: (program) => { + this.program = program; + }, + + require: function(type, src, cb) { + let prefix = ``; + if (src[0] == `/`) { + prefix = window.location + `/`; + } + const element = document.createElement(type === `css` ? `link` : `script`); + switch (type) { + case `css`: + element.type = `text/css`; + element.href = `${prefix}${src}`; + element.rel = `stylesheet`; break; + case `js`: + element.type = `text/javascript`; + element.src = `${prefix}${src}`; + break; + default: + return; } - // Call the given domain to handle a value - const handler = program.domain[value.domain].value; - return handler.get(program, value); + element.onload = function () { + console.log(`${Date.now() - EasyCoder.timestamp} ms: Library ${prefix}${src} loaded`); + cb(); + }; + document.head.appendChild(element); }, - constant: (content, numeric) => { - return { - type: `constant`, - numeric, - content - }; + isUndefined: item => { + return typeof item === `undefined`; }, - evaluate: (program, value) => { - if (!value) { - return { - type: `constant`, - numeric: false, - content: `` - }; + isJsonString: function (str) { + try { + JSON.parse(str); + } catch (e) { + return false; } - const result = EasyCoder_Value.doValue(program, value); - if (result) { - return result; + return true; + }, + + runScript: function (program) { + const command = program[program.pc]; + const script = program.getValue(command.script); + const imports = command.imports; + imports.caller = program.script; + const moduleRecord = command.module ? program.getSymbolRecord(command.module) : null; + try { + EasyCoder.tokeniseAndCompile(script.split(`\n`), imports, moduleRecord, this.script, command.then); + } catch (err) { + EasyCoder.reportError(err, program, program.source); + if (program.onError) { + program.run(program.onError); + } else { + let parent = EasyCoder.scripts[program.parent]; + if (parent && parent.onError) { + parent.run(parent.onError); + } + } + return; + } + if (command.nowait) { + EasyCoder.run(program.nextPc); } - program.runtimeError(program[program.pc].lino, `Can't decode value: ` + value); }, - getValue: (program, value) => { - return EasyCoder_Value.evaluate(program, value).content; + close: function () {}, + + compileScript: function (source, imports, module, parent) { + const { + tokens + } = source; + this.compiling = true; + const compiler = EasyCoder_Compiler; + this.compiler = compiler; + compiler.value = EasyCoder_Value; + compiler.condition = EasyCoder_Condition; + compiler.domain = this.domain; + compiler.imports = imports; + compiler.continue = false; + const program = EasyCoder_Compiler.compile(tokens); + // console.log('Program: ' + JSON.stringify(program, null, 2)); + this.compiling = false; + + program.EasyCoder = this; + program.value = EasyCoder_Value; + program.condition = EasyCoder_Condition; + program.compare = EasyCoder_Compare; + program.source = source; + program.run = this.run; + program.exit = this.exit; + program.runScript = this.runScript; + program.evaluate = this.evaluate; + program.getValue = this.getValue; + program.getFormattedValue = this.getFormattedValue; + program.getSimpleValue = this.getSimpleValue; + program.encode = this.encode; + program.decode = this.decode; + program.domain = this.domain; + program.require = this.require; + program.isUndefined = this.isUndefined; + program.isJsonString = this.isJsonString; + program.getSymbolRecord = this.getSymbolRecord; + program.verifySymbol = this.verifySymbol; + program.runtimeError = this.runtimeError; + program.nonNumericValueError = this.nonNumericValueError; + program.variableDoesNotHoldAValueError = this.variableDoesNotHoldAValueError; + program.reportError = this.reportError; + program.register = this.register; + program.symbols = compiler.getSymbols(); + program.unblocked = false; + program.encoding = `ec`; + program.popups = []; + program.stack = []; + program.queue = [0]; + program.module = module; + program.parent = parent; + if (module) { + module.program = program.script; + } + return program; }, - // tools + tokeniseFile: function(file) { + const scriptLines = []; + const tokens = []; + let index = 0; + file.forEach(function (line, lino) { + scriptLines.push({ + lino: lino + 1, + line + }); + const len = line.length; + let token = ``; + let inSpace = true; + for (let n = 0; n < len; n++) { + const c = line[n]; + if (c.trim().length == 0) { + if (inSpace) { + continue; + } + tokens.push({ + index, + lino: lino + 1, + token + }); + index++; + token = ``; + inSpace = true; + continue; + } + inSpace = false; + if (c === `\``) { + m = n; + while (++n < line.length) { + if (line[n] === `\``) { + break; + } + } + token = line.substr(m, n - m + 1); + } else if (c == `!`) { + break; + } else { + token += c; + } + } + if (token.length > 0) { + tokens.push({ + index, + lino: lino + 1, + token + }); + } + }); + return {scriptLines, tokens}; + }, - encode: (value, encoding) => { - if (value) { - switch (encoding) { - case `ec`: - return value.replace(/\n/g, `%0a`) - .replace(/\r/g, `%0d`) - .replace(/"/g, `~dq~`) - .replace(/'/g, `~sq~`) - .replace(/\\/g, `~bs~`); - case `url`: - return encodeURIComponent(value.replace(/\s/g, `+`)); - case `sanitize`: - return value.normalize(`NFD`).replace(/[\u0300-\u036f]/g, ``); - default: - return value; + tokeniseAndCompile: function (file, imports, module, parent, then) { + // console.log('Tokenise script: '); + let program = null; + const startCompile = Date.now(); + const source = this.tokeniseFile(file); + try { + program = this.compileScript(source, imports, module, parent); + if (!program.script) { + program.script = EasyCoder.scriptIndex; + EasyCoder.scriptIndex++; + } + const finishCompile = Date.now(); + console.log(`${finishCompile - this.timestamp} ms: ` + + `Compiled ${program.script}: ${source.scriptLines.length} lines (${source.tokens.length} tokens) in ` + + `${finishCompile - startCompile} ms`); + } catch (err) { + if (err.message !== `stop`) { + let parentRecord = EasyCoder.scripts[parent]; + this.reportError(err, parentRecord, source); + if (parentRecord && parentRecord.onError) { + parentRecord.run(parentRecord.onError); + } + // Remove this script + if (EasyCoder_Compiler.script) { + delete EasyCoder.scripts[EasyCoder_Compiler.script]; + delete EasyCoder_Compiler.script; + } } + return; + } + if (program) { + EasyCoder.scripts[program.script] = program; + if (module) { + module.program = program.script; + } + program.afterExit = then; + program.running = true; + EasyCoder_Run.run(program, 0); } - return value; }, - decode: (value, encoding) => { - if (value) { - switch (encoding) { - case `ec`: - return value.replace(/%0a/g, `\n`) - .replace(/%0d/g, `\r`) - .replace(/~dq~/g, `"`) - .replace(/~sq~/g, `'`) - .replace(/~bs~/g, `\\`); - case `url`: - const decoded = decodeURIComponent(value); - return decoded.replace(/\+/g, ` `); - default: - return value; + start: function(source) { + EasyCoder.scriptIndex = 0; + const script = source.split(`\n`); + if (!this.tokenising) { + try { + this.tokeniseAndCompile(script); + } catch (err) { + this.reportError(err, null, source); } + this.tokenising = true; } - return value; - } + }, }; EasyCoder.version = `2.6.1`; EasyCoder.timestamp = Date.now(); diff --git a/easycoder/easycoder.zip b/easycoder/easycoder.zip index 205507f6187bea436fe65a9e06f51a2451226fe9..104ee23cda10a299edba29fac810b5e3898d7209 100644 GIT binary patch delta 145991 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
    L+ru`GC7g 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 { - const lino = compiler.getLino(); - const type = compiler.nextToken(); - switch (type) { - case `plugin`: - const name = compiler.getNextValue(); - compiler.addCommand({ - domain: `core`, - keyword: `load`, - lino, - name - }); - return true; - } - return false; - }, - - run: program => { - const command = program[program.pc]; - const name = program.getValue(command.name); - switch (command.keyword) { - case `load`: - if (program.checkPlugin(name)) { - return command.pc + 1; - } - EasyCoder_Plugins.getLocalPlugin( - program.getPluginsPath, - name, - program.getPlugin, - program.addLocalPlugin, - function () { - program.run(command.pc + 1); - }); - return 0; - } - } - }, - Module: { compile: compiler => { @@ -2184,8 +2144,6 @@ const EasyCoder_Core = { return EasyCoder_Core.Import; case `index`: return EasyCoder_Core.Index; - case `load`: - return EasyCoder_Core.Load; case `module`: return EasyCoder_Core.Module; case `multiply`: diff --git a/js/easycoder/Main.js b/js/easycoder/Main.js index 8fb8404..669b878 100644 --- a/js/easycoder/Main.js +++ b/js/easycoder/Main.js @@ -3,7 +3,10 @@ const EasyCoder = { name: `EasyCoder_Main`, domain: { - core: EasyCoder_Core + core: EasyCoder_Core, + browser: EasyCoder_Browser, + json: EasyCoder_Json, + rest: EasyCoder_Rest }, elementId: 0, @@ -144,22 +147,26 @@ const EasyCoder = { }, require: function(type, src, cb) { + let prefix = ``; + if (src[0] == `/`) { + prefix = window.location + `/`; + } const element = document.createElement(type === `css` ? `link` : `script`); switch (type) { case `css`: element.type = `text/css`; - element.href = src; + element.href = `${prefix}${src}`; element.rel = `stylesheet`; break; case `js`: element.type = `text/javascript`; - element.src = src; + element.src = `${prefix}${src}`; break; default: return; } element.onload = function () { - console.log(`${Date.now() - EasyCoder.timestamp} ms: Library ${src} loaded`); + console.log(`${Date.now() - EasyCoder.timestamp} ms: Library ${prefix}${src} loaded`); cb(); }; document.head.appendChild(element); @@ -239,10 +246,6 @@ const EasyCoder = { program.require = this.require; program.isUndefined = this.isUndefined; program.isJsonString = this.isJsonString; - program.checkPlugin = this.checkPlugin; - program.getPlugin = this.getPlugin; - program.addLocalPlugin = this.addLocalPlugin; - program.getPluginsPath = this.getPluginsPath; program.getSymbolRecord = this.getSymbolRecord; program.verifySymbol = this.verifySymbol; program.runtimeError = this.runtimeError; @@ -325,9 +328,9 @@ const EasyCoder = { const source = this.tokeniseFile(file); try { program = this.compileScript(source, imports, module, parent); - this.scriptIndex++; if (!program.script) { - program.script = this.scriptIndex; + program.script = EasyCoder.scriptIndex; + EasyCoder.scriptIndex++; } const finishCompile = Date.now(); console.log(`${finishCompile - this.timestamp} ms: ` + @@ -359,7 +362,8 @@ const EasyCoder = { } }, - tokenise: function(source) { + start: function(source) { + EasyCoder.scriptIndex = 0; const script = source.split(`\n`); if (!this.tokenising) { try { @@ -370,104 +374,4 @@ const EasyCoder = { this.tokenising = true; } }, - - setPluginCount: function(count) { - EasyCoder.plugins = []; - EasyCoder.pluginCount = count; - }, - - checkPlugin: function(name) { - return EasyCoder.domain[name]; - }, - - getPlugin: function(name, src, onload) { - if (EasyCoder.domain[name]) { - onload(); - return; - } - const script = document.createElement(`script`); - script.type = `text/javascript`; - let location = document.scripts[0].src; - location = location.substring(0, location.indexOf(`/easycoder.js`)); - // script.src = `${location}/${src}?ver=${EasyCoder.version}`; - script.src = `${src}?ver=${EasyCoder.version}`; - script.onload = function () { - console.log(`${Date.now() - EasyCoder.timestamp} ms: Plugin ${src} loaded`); - onload(); - }; - document.head.appendChild(script); - }, - - addGlobalPlugin: function(name, handler) { - // alert(`Add plugin ${name}`); - EasyCoder.plugins.push({ - name, - handler - }); - if (EasyCoder.plugins.length === EasyCoder.pluginCount) { - EasyCoder.plugins.forEach(function (plugin) { - EasyCoder.domain[plugin.name] = plugin.handler; - }); - EasyCoder.tokenise(EasyCoder.source); - } - }, - - addLocalPlugin: function(name, handler, callback) { - EasyCoder.domain[name] = handler; - callback(); - }, - - getPluginsPath: function() { - return EasyCoder.pluginsPath; - }, - - loadPluginJs: function(path) { - console.log(`${Date.now() - this.timestamp} ms: Load ${path}/easycoder/plugins.js`); - const script = document.createElement(`script`); - script.src = `${window.location.origin}${path}/easycoder/plugins.js?ver=${this.version}`; - script.type = `text/javascript`; - script.onload = () => { - EasyCoder_Plugins.getGlobalPlugins( - this.timestamp, - path, - this.setPluginCount, - this.getPlugin, - this.addGlobalPlugin - ); - }; - script.onerror = () => { - if (path) { - this.loadPluginJs(path.slice(0, path.lastIndexOf(`/`))); - } else { - this.reportError({ - message: `Can't load plugins.js` - }, this.program, this.source); - } - }; - document.head.appendChild(script); - this.pluginsPath = path; - }, - - start: function(source) { - this.source = source; - this.scriptIndex = 0; - let pathname = window.location.pathname; - if (pathname.endsWith(`/`)) { - pathname = pathname.slice(0, -1); - } else { - pathname = ``; - } - if (typeof EasyCoder_Plugins === `undefined`) { - this.loadPluginJs(pathname); - } else { - this.pluginsPath = pathname; - EasyCoder_Plugins.getGlobalPlugins( - this.timestamp, - pathname, - this.setPluginCount, - this.getPlugin, - this.addGlobalPlugin - ); - } - } }; diff --git a/js/plugins/anagrams.js b/js/plugins/anagrams.js index 594a751..e1c98ab 100644 --- a/js/plugins/anagrams.js +++ b/js/plugins/anagrams.js @@ -40,4 +40,7 @@ const EasyCoder_Anagrams = { compile: () => {} } -}; \ No newline at end of file +}; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.anagrams = EasyCoder_Anagrams; diff --git a/js/plugins/aws.js b/js/plugins/aws.js index d86a1fd..79c5c09 100644 --- a/js/plugins/aws.js +++ b/js/plugins/aws.js @@ -228,4 +228,7 @@ const EasyCoder_AWS = { test: () => {} } -}; \ No newline at end of file +}; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.aws = EasyCoder_AWS; diff --git a/js/plugins/browser.js b/js/plugins/browser.js deleted file mode 100644 index 30e281f..0000000 --- a/js/plugins/browser.js +++ /dev/null @@ -1,3345 +0,0 @@ -const EasyCoder_Browser = { - - name: `EasyCoder_Browser`, - - A: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `a`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Alert: { - - compile: (compiler) => { - const lino = compiler.getLino(); - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `alert`, - lino, - value - }); - return true; - }, - - run: (program) => { - const command = program[program.pc]; - const value = program.getFormattedValue(command.value); - alert(value); - return command.pc + 1; - } - }, - - Attach: { - - compile: (compiler) => { - const lino = compiler.getLino(); - compiler.next(); - if (compiler.isSymbol()) { - // const symbol = compiler.getProgram()[compiler.getSymbol().pc]; - const symbol = compiler.getSymbolRecord(); - let type = symbol.keyword; - switch (type) { - case `a`: - case `blockquote`: - case `button`: - case `canvas`: - case `div`: - case `fieldset`: - case `file`: - case `form`: - case `h1`: - case `h2`: - case `h3`: - case `h4`: - case `h5`: - case `h6`: - case `image`: - case `img`: - case `input`: - case `label`: - case `legend`: - case `li`: - case `option`: - case `p`: - case `pre`: - case `select`: - case `span`: - case `table`: - case `td`: - case `text`: - case `textarea`: - case `tr`: - case `ul`: - compiler.next(); - if (compiler.tokenIs(`to`)) { - let cssID = null; - if (compiler.nextTokenIs(`body`)) { - if (type=== `div`) { - cssId = `body`; - compiler.next(); - } else { - throw Error(`Body variable must be a div`); - } - } - else cssId = compiler.getValue(); - let onError = 0; - if (compiler.tokenIs(`or`)) { - compiler.next(); - onError = compiler.getPc() + 1; - compiler.completeHandler(); - } - compiler.addCommand({ - domain: `browser`, - keyword: `attach`, - lino, - type, - symbol: symbol.name, - cssId, - onError - }); - return true; - } - break; - default: - compiler.addWarning(`type '${symbol.keyword}' not recognized in browser 'attach'`); - return false; - } - } - compiler.addWarning(`Unrecognised syntax in 'attach'`); - return false; - }, - - run: (program) => { - const command = program[program.pc]; - let content = null; - let element = null; - if (command.cssId === `body`) { - element = document.body; - } else { - content = program.value.evaluate(program, command.cssId).content; - element = document.getElementById(content); - } - if (!element) { - if (command.onError) { - program.run(command.onError); - } else { - program.runtimeError(command.lino, `No such element: '${content}'`); - } - return 0; - } - const target = program.getSymbolRecord(command.symbol); - target.element[target.index] = element; - target.value[target.index] = { - type: `constant`, - numeric: false, - content - }; - if (command.type === `popup`) { - // Register a popup - program.popups.push(element.id); - // Handle closing of the popup - window.onclick = function (event) { - if (program.popups.includes(event.target.id)) { - event.target.style.display = `none`; - } - }; - } - return command.pc + 1; - } - }, - - Audioclip: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `audioclip`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - BLOCKQUOTE: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `blockquote`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - BUTTON: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `button`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - CANVAS: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `canvas`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Clear: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextTokenIs(`body`)) { - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `clear`, - lino, - name: null - }); - return true; - } - if (compiler.isSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.extra === `dom`) { - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `clear`, - lino, - name: symbolRecord.name - }); - return true; - } - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - if (command.name) { - const targetRecord = program.getSymbolRecord(command.name); - const target = targetRecord.element[targetRecord.index]; - switch (targetRecord.keyword) { - case `input`: - case `textarea`: - target.value = ``; - break; - default: - target.innerHTML = ``; - break; - } - } else { - document.body.innerHTML = ``; - } - return command.pc + 1; - } - }, - - Convert: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextTokenIs(`whitespace`)) { - if (compiler.nextTokenIs(`in`)) { - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.isVHolder) { - if (compiler.nextTokenIs(`to`)) { - const mode = compiler.nextToken(); - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `convert`, - lino, - name: symbolRecord.name, - mode - }); - return true; - } - } - } - } - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const targetRecord = program.getSymbolRecord(command.name); - const content = targetRecord.value[targetRecord.index].content; - let value = content; - switch (command.mode) { - case `print`: - value = value.split(`%0a`).join(`\n`).split(`%0A`).join(`\n`).split(`%0d`).join(``).split(`$0D`).join(``); - break; - case `html`: - value = value.split(`%0a`).join(`
    `).split(`%0A`).join(`
    `).split(`%0d`).join(``).split(`$0D`).join(``); - break; - } - targetRecord.value[targetRecord.index].content = value; - return command.pc + 1; - } - }, - - Create: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - const keyword = symbolRecord.keyword; - if (keyword === `audioclip`) { - if (compiler.nextTokenIs(`from`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `create`, - type: `audioclip`, - name: symbolRecord.name, - lino, - value - }); - return true; - } - return false; - } - if ([`a`, - `blockquote`, - `button`, - `canvas`, - `div`, - `fieldset`, - `file`, - `form`, - `h1`, - `h2`, - `h3`, - `h4`, - `h5`, - `h6`, - `hr`, - `image`, - `img`, - `input`, - `label`, - `legend`, - `li`, - `option`, - `p`, - `pre`, - `progress`, - `select`, - `span`, - `table`, - `tr`, - `td`, - `text`, - `textarea`, - `ul` - ].includes(keyword)) { - if (compiler.nextTokenIs(`in`)) { - if (compiler.nextTokenIs(`body`)) { - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `create`, - lino, - name: symbolRecord.name, - parent: `body` - }); - return true; - } - if (compiler.isSymbol()) { - const parentRecord = compiler.getSymbolRecord(); - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `create`, - lino, - name: symbolRecord.name, - parent: parentRecord.name - }); - return true; - } - } else { - const imports = compiler.imports; - if (imports && imports.length > 0) { - // This section is used by Codex to force run in Run panel, which must be the first import - compiler.addCommand({ - domain: `browser`, - keyword: `create`, - lino, - name: symbolRecord.name, - parent: imports[0], - imported: true - }); - return true; - } else { - compiler.addCommand({ - domain: `browser`, - keyword: `create`, - lino, - name: symbolRecord.name, - parent: `body` - }); - return true; - } - } - } - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const targetRecord = program.getSymbolRecord(command.name); - switch (command.type) { - case `audioclip`: - targetRecord.value[targetRecord.index] = command.value; - break; - default: - let parent; - if (command.parent === `body`) { - parent = document.body; - } else { - const p = command.imported ? EasyCoder.scripts[program.parent] : program; - const parentRecord = p.getSymbolRecord(command.parent); - if (!parentRecord.element[parentRecord.index]) { - program.runtimeError(command.pc, `Element ${parentRecord.name} does not exist.`); - } - parent = parentRecord.element[parentRecord.index]; - } - targetRecord.element[targetRecord.index] = document.createElement(targetRecord.keyword); - targetRecord.element[targetRecord.index].id = - `ec-${targetRecord.name}-${targetRecord.index}-${EasyCoder.elementId++}`; - if (targetRecord.keyword === `a`) { - targetRecord.element[targetRecord.index].setAttribute(`href`, `#`); - } - parent.appendChild(targetRecord.element[targetRecord.index]); - break; - } - return command.pc + 1; - } - }, - - Disable: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const symbol = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `disable`, - lino, - symbol - }); - return true; - } - compiler.addWarning(`Unrecognised syntax in 'disable'`); - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const symbol = program.getSymbolRecord(command.symbol); - const target = document.getElementById(symbol.value[symbol.index].content); - target.disabled = `true`; - return command.pc + 1; - } - }, - - DIV: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `div`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Enable: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const symbol = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `enable`, - lino, - symbol - }); - return true; - } - compiler.addWarning(`Unrecognised syntax in 'enable'`); - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const symbol = program.getSymbolRecord(command.symbol); - const target = document.getElementById(symbol.value[symbol.index].content); - target.disabled = false; - return command.pc + 1; - } - }, - - FIELDSET: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `fieldset`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - FILE: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `file`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Focus: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const symbol = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `focus`, - lino, - symbol - }); - return true; - } - compiler.addWarning(`Unrecognised syntax in 'focus'`); - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const symbol = program.getSymbolRecord(command.symbol); - const element = symbol.element[symbol.index]; - element.focus(); - return command.pc + 1; - } - }, - - FORM: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `form`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Get: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const target = compiler.getToken(); - let targetRecord = compiler.getSymbolRecord(); - if (compiler.nextTokenIs(`from`)) { - if (compiler.nextTokenIs(`storage`)) { - if (compiler.nextTokenIs(`as`)) { - const key = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `get`, - action: `getStorage`, - lino, - target, - key - }); - return true; - } else { - compiler.addCommand({ - domain: `browser`, - keyword: `get`, - action: `listStorage`, - lino, - target - }); - return true; - } - } - if (compiler.isSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.keyword === `select`) { - if (targetRecord.keyword === `option`) { - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `get`, - action: `getOption`, - lino, - target, - select: symbolRecord.name - }); - return true; - } - throw Error(`Invalid variable type`); - } - if (symbolRecord.keyword !== `form`) { - throw Error(`Invalid variable type`); - } - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `get`, - action: `getForm`, - lino, - target, - form: symbolRecord.name - }); - return true; - } - else { - let targetRecord = compiler.getSymbolRecord(target); - } - } - } - compiler.addWarning(`Unrecognised syntax in 'get'`); - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const targetRecord = program.getSymbolRecord(command.target); - switch (command.action) { - case `getForm`: - const formRecord = program.getSymbolRecord(command.form); - const form = document.getElementById(formRecord.value[formRecord.index].content); - const data = new FormData(form); - const content = {}; - for (const entry of data) { - content[entry[0]] = entry[1].replace(/\r/g, ``).replace(/\n/g, `%0a`); - } - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content: JSON.stringify(content) - }; - break; - case `listStorage`: - const items = []; - for (let i = 0, len = window.localStorage.length; i < len; i++) { - items.push(localStorage.key(i)); - } - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content: JSON.stringify(items) - }; - break; - case `getStorage`: - let value = window.localStorage.getItem(program.getValue(command.key)); - if (typeof value === `undefined`) { - value = null; - } - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content: value - }; - break; - case `getOption`: - let selectRecord = program.getSymbolRecord(command.select); - let select = selectRecord.element[selectRecord.index]; - let option = select.options[select.selectedIndex]; - targetRecord.element[targetRecord.index] = option; - break; - } - return command.pc + 1; - } - }, - - H1: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `h1`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - H2: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `h2`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - H3: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `h3`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - H4: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `h4`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - H5: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `h5`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - H6: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `h6`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Highlight: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.extra === `dom`) { - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `highlight`, - lino, - name: symbolRecord.name - }); - return true; - } - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const targetRecord = program.getSymbolRecord(command.name); - const element = targetRecord.element[targetRecord.index]; - element.select(); - return command.pc + 1; - } - }, - - History: { - - compile: (compiler) => { - const lino = compiler.getLino(); - const type = compiler.nextToken(); - switch (type) { - case `push`: - case `set`: - case `replace`: - compiler.next(); - let url = ``; - let state = ``; - let title = ``; - while (true) { - const token = compiler.getToken(); - if (token === `url`) { - url = compiler.getNextValue(); - } else if (token === `state`) { - state = compiler.getNextValue(); - } else if (token === `title`) { - title = compiler.getNextValue(); - } else { - break; - } - } - compiler.addCommand({ - domain: `browser`, - keyword: `history`, - lino, - type, - url, - state, - title - }); - return true; - case `pop`: - case `back`: - case `forward`: - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `history`, - lino, - type - }); - return true; - } - return false; - }, - - run: (program) => { - if (!program.script) { - program.script = `script${Date.now()/1000}`; - } - const command = program[program.pc]; - let state = program.getValue(command.state); - if (!state) { - state = `{"script":"${program.script}"}`; - } - let title = program.getValue(command.title); - const url = program.getValue(command.url); - switch (command.type) { - case `push`: - if (!window.history.state) { - program.runtimeError(command.lino, `No state history; you need to call 'history set' on the parent`); - return 0; - } - window.history.pushState(state, ``, url); - break; - case `set`: - case `replace`: - window.history.replaceState(state, title, url); - break; - case `pop`: - case `back`: - window.history.back(); - break; - case `forward`: - window.history.forward(); - break; - } - return command.pc + 1; - } - }, - - HR: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `hr`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - IMAGE: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `image`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - IMG: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `img`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - INPUT: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `input`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - LABEL: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `label`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - LEGEND: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `legend`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - LI: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `li`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Location: { - - compile: (compiler) => { - const lino = compiler.getLino(); - let newWindow = false; - if (compiler.nextTokenIs(`new`)) { - newWindow = true; - compiler.next(); - } - const location = compiler.getValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `location`, - lino, - location, - newWindow - }); - return true; - }, - - run: (program) => { - const command = program[program.pc]; - const location = program.getValue(command.location); - if (command.newWindow) { - window.open(location, `_blank`); - } else { - window.location = location; - } - return command.pc + 1; - } - }, - - Mail: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextTokenIs(`to`)) { - const to = compiler.getNextValue(); - let subject = ``; - let body = ``; - if (compiler.tokenIs(`subject`)) { - subject = compiler.getNextValue(); - if (compiler.tokenIs(`body`) || compiler.tokenIs(`message`)) { - compiler.next(); - body = compiler.getValue(); - } - } - compiler.addCommand({ - domain: `browser`, - keyword: `mail`, - lino, - to, - subject, - body - }); - return true; - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - if (command.subject) { - window.location.href = `mailto:${program.getValue(command.to)}` + - `?subject=${program.getValue(command.subject)}&body=${encodeURIComponent(program.getValue(command.body))}`; - } else { - window.location.href = `mailto:${program.getValue(command.to)}`; - } - return command.pc + 1; - } - }, - - On: { - - compile: (compiler) => { - const lino = compiler.getLino(); - const action = compiler.nextToken(); - switch (action) { - case `change`: - compiler.next(); - if (compiler.isSymbol()) { - const symbol = compiler.getSymbolRecord(); - compiler.next(); - if (symbol.extra !== `dom`) { - return false; - } - compiler.addCommand({ - domain: `browser`, - keyword: `on`, - lino, - action, - symbol: symbol.name - }); - return compiler.completeHandler(); - } - break; - case `click`: - if (compiler.nextTokenIs(`document`)) { - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `on`, - lino, - action: `clickDocument` - }); - return compiler.completeHandler(); - } - if (compiler.isSymbol()) { - const symbol = compiler.getSymbolRecord(); - compiler.next(); - if (symbol.extra !== `dom`) { - return false; - } - compiler.addCommand({ - domain: `browser`, - keyword: `on`, - lino, - action, - symbol: symbol.name - }); - return compiler.completeHandler(); - } - break; - case `key`: - case `leave`: - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `on`, - lino, - action - }); - return compiler.completeHandler(); - case `window`: - if (compiler.nextTokenIs(`resize`)) { - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `on`, - lino, - action: `windowResize` - }); - return compiler.completeHandler(); - } - return false; - case `browser`: - case `restore`: - if (action === `browser` && !compiler.nextTokenIs(`back`)) { - return false; - } - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `on`, - lino, - action: `browserBack` - }); - return compiler.completeHandler(); - case `swipe`: - if ([`left`, `right`].includes(compiler.nextToken())) { - const direction = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `on`, - lino, - action: `swipe`, - direction - }); - return compiler.completeHandler(); - } - return false; - case `pick`: - if (compiler.nextIsSymbol()) { - const symbol = compiler.getSymbolRecord(); - compiler.next(); - if (symbol.extra !== `dom`) { - return false; - } - compiler.addCommand({ - domain: `browser`, - keyword: `on`, - lino, - action, - symbol: symbol.name - }); - return compiler.completeHandler(); - } - return false; - case `drag`: - case `drop`: - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `on`, - lino, - action - }); - return compiler.completeHandler(); - } - compiler.addWarning(`Unrecognised syntax in 'on'`); - return false; - }, - - run: (program) => { - let targetRecord; - const command = program[program.pc]; - switch (command.action) { - case `change`: - targetRecord = program.getSymbolRecord(command.symbol); - targetRecord.program = program.script; - targetRecord.element.forEach(function (target, index) { - if (target) { - target.targetRecord = targetRecord; - target.targetIndex = index; - target.targetPc = command.pc + 2; - target.addEventListener(`change`, (event) => { - event.stopPropagation(); - if (program.length > 0) { - const eventTarget = event.target; - if (typeof eventTarget.targetRecord !== `undefined`) { - eventTarget.targetRecord.index = eventTarget.targetIndex; - setTimeout(function () { - EasyCoder.timestamp = Date.now(); - let p = EasyCoder.scripts[eventTarget.targetRecord.program]; - p.run(eventTarget.targetPc); - }, 1); - } - } - }); - } - }); - break; - case `click`: - targetRecord = program.getSymbolRecord(command.symbol); - targetRecord.program = program.script; - targetRecord.element.forEach(function (target, index) { - if (target) { - target.targetRecord = targetRecord; - target.targetIndex = index; - target.targetPc = command.pc + 2; - target.onclick = function (event) { - event.stopPropagation(); - if (program.length > 0) { - const eventTarget = event.target; - if (eventTarget.type != `radio`) { - eventTarget.blur(); - } - if (typeof eventTarget.targetRecord !== `undefined`) { - eventTarget.targetRecord.index = eventTarget.targetIndex; - setTimeout(function () { - EasyCoder.timestamp = Date.now(); - let p = EasyCoder.scripts[eventTarget.targetRecord.program]; - p.run(eventTarget.targetPc); - }, 1); - } - } - return false; - }; - } - }); - break; - case `clickDocument`: - program.targetPc = command.pc + 2; - const interceptClickEvent = (e) => { - EasyCoder.timestamp = Date.now(); - let target = e.target || e.srcElement; - let href = ``; - while (target.parentNode) { - if (target.tagName === `A`) { - href = target.href; - program.docPath = href.slice(-(href.length - window.location.href.length)); - break; - } - target = target.parentNode; - } - while (target.parentNode) { - if (target.id.indexOf(`ec-`) === 0) { - let id = target.id.slice(3); - let pos = id.indexOf(`-`); - program.varName = id.slice(0, pos); - id = id.slice(pos + 1); - pos = id.indexOf(`-`); - program.varIndex = parseInt(id.slice(0, pos)); - break; - } - target = target.parentNode; - } - if (href.indexOf(window.location.href) === 0) { - program.run(program.targetPc); - e.preventDefault(); - } - }; - if (document.addEventListener) { - document.addEventListener(`click`, interceptClickEvent); - } else if (document.attachEvent) { - document.attachEvent(`onclick`, interceptClickEvent); - } - break; - case `swipe`: - let xDown; - const getTouches = (evt) => { - return evt.touches || // browser API - evt.originalEvent.touches; // jQuery - }; - const handleTouchStart = (evt) => { - const firstTouch = getTouches(evt)[0]; - xDown = firstTouch.clientX; - }; - const handleTouchMove = (evt) => { - evt.stopImmediatePropagation(); - if (!xDown) { - return; - } - const xUp = evt.touches[0].clientX; - const xDiff = xDown - xUp; - if (Math.abs(xDiff) > 150) { - xDown = null; - if (xDiff > 0 && program.onSwipeLeft) { - program.run(program.onSwipeLeft); - } else if (xDiff < 0 && program.onSwipeRight) { - program.run(program.onSwipeRight); - } - } - }; - switch (command.direction) { - case `left`: - program.onSwipeLeft = command.pc + 2; - break; - case `right`: - program.onSwipeRight = command.pc + 2; - break; - } - document.addEventListener(`touchstart`, handleTouchStart, false); - document.addEventListener(`touchmove`, handleTouchMove, false); - break; - case `pick`: - const pickRecord = program.getSymbolRecord(command.symbol); - document.pickRecord = pickRecord; - pickRecord.element.forEach(function (element, index) { - document.pickIndex = index; - element.pickIndex = index; - // Set up the mouse down and up listeners - element.mouseDownPc = command.pc + 2; - // Check if touch device - let isTouchDevice = `ontouchstart` in element; - if (isTouchDevice) { - element.addEventListener(`touchstart`, function (e) { - const element = e.targetTouches[0].target; - document.pickX = e.touches[0].clientX; - document.pickY = e.touches[0].clientY; - element.blur(); - setTimeout(function () { - document.pickRecord.index = element.pickIndex; - program.run(element.mouseDownPc); - }, 1); - }, false); - element.addEventListener(`touchmove`, function (e) { - document.dragX = e.touches[0].clientX; - document.dragY = e.touches[0].clientY; - setTimeout(function () { - program.run(document.mouseMovePc); - }, 1); - return false; - }, false); - element.addEventListener(`touchend`, function () { - setTimeout(function () { - program.run(document.mouseUpPc); - }, 1); - return false; - }); - } else { - element.onmousedown = function (event) { - let e = event ? event : window.event; - e.stopPropagation(); - // IE uses srcElement, others use target - if (program.length > 0) { - const element = e.target ? e.target : e.srcElement; - element.offsetX = e.offsetX; - element.offsetY = e.offsetY; - document.pickX = e.clientX; - document.pickY = e.clientY; - element.blur(); - setTimeout(function () { - document.pickRecord.index = element.pickIndex; - program.run(element.mouseDownPc); - }, 1); - } - document.onmousemove = function (event) { - let e = event ? event : window.event; - e.stopPropagation(); - document.dragX = e.clientX; - document.dragY = e.clientY; - if (document.onmousemove) { - setTimeout(function () { - program.run(document.mouseMovePc); - }, 1); - } - return false; - }; - window.onmouseup = function () { - document.onmousemove = null; - document.onmouseup = null; - setTimeout(function () { - if (program && program.run) { - program.run(document.mouseUpPc); - } - }, 1); - return false; - }; - return false; - }; - } - }); - break; - case `drag`: - // Set up the move listener - document.mouseMovePc = command.pc + 2; - break; - case `drop`: - // Set up the move listener - document.mouseUpPc = command.pc + 2; - break; - case `key`: - if (typeof document.onKeyListeners === `undefined`) { - document.onKeyListeners = []; - } - if (!document.onKeyListeners.includes(program)) { - document.onKeyListeners.push(program); - } - program.onKeyPc = command.pc + 2; - document.onkeypress = function (event) { - for (const program of document.onKeyListeners) { - program.key = event.key; - try { - setTimeout(function () { - program.run(program.onKeyPc); - }, 1); - } catch (err) { - console.log(`Error: ${err.message}`); - } - } - return true; - }; - break; - case `windowResize`: - program.onWindowResize = command.pc + 2; - window.addEventListener('resize', function() { - program.run(program.onWindowResize); - }); - break; - case `browserBack`: - program.onBrowserBack = command.pc + 2; - break; - case `leave`: - window.addEventListener(`beforeunload`, function () { - program.run(command.pc + 2); - }); - break; - default: - break; - } - return command.pc + 1; - } - }, - - OPTION: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `option`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - P: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `p`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Play: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `audioclip`) { - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `play`, - lino, - target: targetRecord.name - }); - return true; - } - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const targetRecord = program.getSymbolRecord(command.target); - const url = program.value.evaluate(program, targetRecord.value[targetRecord.index]).content; - new Audio(url).play(); - return command.pc + 1; - } - }, - - PRE: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `pre`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - PROGRESS: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `progress`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Put: { - - compile: (compiler) => { - const lino = compiler.getLino(); - // Get the value - const value = compiler.getNextValue(); - if (compiler.tokenIs(`into`)) { - if (compiler.nextTokenIs(`storage`)) { - if (compiler.nextTokenIs(`as`)) { - const key = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `put`, - lino, - value, - key - }); - return true; - } - } - } - return false; - }, - - // runtime - - run: (program) => { - const command = program[program.pc]; - window.localStorage.setItem(program.getValue(command.key), program.getValue(command.value)); - return command.pc + 1; - } - }, - - Remove: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextTokenIs(`element`)) { - if (compiler.nextIsSymbol()) { - const element = compiler.getSymbolRecord(); - if (element.extra != `dom`) { - compiler.warning(`'${element.name}' is not a DOM element`); - return false; - } - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `remove`, - type: `removeElement`, - lino, - element: element.name - }); - return true; - } - } - if (compiler.tokenIs(`attribute`)) { - const attribute = compiler.getNextValue(); - if (compiler.tokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.extra !== `dom`) { - throw new Error(`Inappropriate type '${targetRecord.keyword}'`); - } - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `remove`, - type: `removeAttribute`, - lino, - attribute, - target: targetRecord.name - }); - return true; - } - } - } - try { - const key = compiler.getValue(); - if (compiler.tokenIs(`from`)) { - if (compiler.nextTokenIs(`storage`)) { - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `remove`, - type: `removeStorage`, - key - }); - return true; - } - } - } catch (err) { - return false; - } - return false; - }, - - // runtime - - run: (program) => { - const command = program[program.pc]; - switch (command.type) { - case `removeAttribute`: - const attribute = program.getValue(command.attribute); - const targetRecord = program.getSymbolRecord(command.target); - target = targetRecord.element[targetRecord.index]; - target.removeAttribute(attribute); - break; - case `removeElement`: - const elementRecord = program.getSymbolRecord(command.element); - const element = elementRecord.element[elementRecord.index]; - if (element) { - element.parentElement.removeChild(element); - } - break; - case `removeStorage`: - const key = program.getValue(command.key); - window.localStorage.removeItem(key); - break; - } - return command.pc + 1; - } - }, - - Request: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextToken() === `fullscreen`) { - let option = ``; - if (compiler.nextToken() === `exit`) { - option = `exit`; - compiler.next(); - } - compiler.addCommand({ - domain: `browser`, - keyword: `request`, - lino, - option - }); - return true; - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - if (command.option === `exit`) { - document.exitFullscreen(); - } else { - document.documentElement.requestFullscreen(); - } - return command.pc + 1; - } - }, - - SELECT: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `select`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Scroll: { - - compile: (compiler) => { - const lino = compiler.getLino(); - let name = null; - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - name = symbolRecord.name; - compiler.next(); - } - if (compiler.tokenIs(`to`)) { - const to = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `scroll`, - lino, - name, - to - }); - return true; - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const to = program.getValue(command.to); - if (command.name) { - const symbolRecord = program.getSymbolRecord(command.name); - symbolRecord.element[symbolRecord.index].scrollTo(0, to); - } else { - window.scrollTo(0, to); - } - return command.pc + 1; - } - }, - - SECTION: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `section`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Set: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - const target = targetRecord.name; - if (targetRecord.extra === `dom`) { - const token = compiler.nextToken(); - if (token === `from`) { - if (compiler.nextIsSymbol()) { - if (targetRecord.keyword === `select`) { - const sourceRecord = compiler.getSymbolRecord(); - if (sourceRecord.keyword === `variable`) { - var display = null; - if (compiler.nextTokenIs(`as`)) { - display = compiler.getNextValue(); - } - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setSelect`, - select: target, - source: sourceRecord.name, - display - }); - return true; - } - return false; - } - const source = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setContentVar`, - source, - target - }); - return true; - } - } - } - } else { - let token = compiler.getToken(); - if (token === `the`) { - token = compiler.nextToken(); - } - if (token === `title`) { - if (compiler.nextTokenIs(`to`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setTitle`, - value - }); - return true; - } - } else if (token === `content`) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const target = compiler.getToken(); - if (compiler.nextTokenIs(`from`)) { - if (compiler.nextIsSymbol()) { - const source = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setContentVar`, - source, - target - }); - return true; - } - } - if (compiler.tokenIs(`to`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setContent`, - value, - target - }); - return true; - } - } - throw new Error(`'${compiler.getToken()}' is not a symbol`); - } - } else if (token === `class`) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbol = compiler.getSymbolRecord(); - if (symbol.extra === `dom`) { - if (compiler.nextTokenIs(`to`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setClass`, - symbolName: symbol.name, - value - }); - return true; - } - } - } - } - } else if (token === `id`) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbol = compiler.getSymbolRecord(); - if (symbol.extra === `dom`) { - if (compiler.nextTokenIs(`to`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setId`, - symbolName: symbol.name, - value - }); - return true; - } - } - } - } - } else if (token === `text`) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbol = compiler.getSymbolRecord(); - switch (symbol.keyword) { - case `button`: - case `input`: - case `span`: - case `label`: - case `legend`: - if (compiler.nextTokenIs(`to`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setText`, - symbolName: symbol.name, - value - }); - return true; - } - break; - default: - break; - } - } - } - } else if (token === `size`) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbol = compiler.getSymbolRecord(); - switch (symbol.keyword) { - case `input`: - if (compiler.nextTokenIs(`to`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setSize`, - symbolName: symbol.name, - value - }); - return true; - } - } - } - } - } else if (token === `attribute`) { - compiler.next(); - const attributeName = compiler.getValue(); - if (compiler.tokenIs(`of`)) { - if (compiler.nextIsSymbol(true)) { - const symbolRecord = compiler.getSymbolRecord(); - const symbolName = symbolRecord.name; - compiler.next(); - let attributeValue = { - type: `boolean`, - content: true - }; - if (compiler.tokenIs(`to`)) { - attributeValue = compiler.getNextValue(); - } - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setAttribute`, - symbolName, - attributeName, - attributeValue - }); - return true; - } - } - } else if (token === `attributes`) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - const symbolName = symbolRecord.name; - if (symbolRecord.extra !== `dom`) { - compiler.warning(`'${symbolName}' is not a DOM type`); - return false; - } - if (compiler.nextTokenIs(`to`)) { - const attributes = compiler.getNextValue(); - if (attributes) { - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setAttributes`, - symbolName, - attributes - }); - return true; - } - } - } - } - compiler.warning(`'${compiler.getToken()}' is not a symbol`); - return false; - } else if (token === `style`) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - const symbolName = symbolRecord.name; - if (symbolRecord.extra !== `dom`) { - compiler.warning(`'${symbolName}' is not a DOM type`); - return false; - } - if (compiler.nextTokenIs(`to`)) { - const styleValue = compiler.getNextValue(); - if (styleValue) { - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setStyles`, - symbolName, - styleValue - }); - return true; - } - } - } - compiler.warning(`'${compiler.getToken()}' is not a symbol`); - return false; - } - const styleName = compiler.getValue(); - let type = `setStyle`; - let symbolName = ``; - token = compiler.getToken(); - if (token === `of`) { - if (compiler.nextToken() === `body`) { - type = `setBodyStyle`; - } else if (compiler.isSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - symbolName = symbolRecord.name; - if (symbolRecord.extra !== `dom`) { - throw Error(`'${symbolName}' is not a DOM type`); - } - } else { - throw Error(`'${compiler.getToken()}' is not a known symbol`); - } - if (compiler.nextTokenIs(`to`)) { - const styleValue = compiler.getNextValue(); - if (styleValue) { - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type, - symbolName, - styleName, - styleValue - }); - return true; - } - } - } - else if (token === `to`) { - const styleValue = compiler.getNextValue(); - if (styleValue) { - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setHeadStyle`, - styleName, - styleValue - }); - return true; - } - } - } else if (token === `default`) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.keyword === `select`) { - if (compiler.nextTokenIs(`to`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setDefault`, - name: symbolRecord.name, - value - }); - return true; - } - } - } - } - } - } - compiler.addWarning(`Unrecognised syntax in 'set'`); - return false; - }, - - run: (program) => { - const command = program[program.pc]; - let symbol; - let value; - let target; - let targetId; - let targetRecord; - let cssId; - let selectRecord; - switch (command.type) { - case `setContentVar`: - const sourceVar = program.getSymbolRecord(command.source); - targetRecord = program.getSymbolRecord(command.target); - const source = document.getElementById(sourceVar.value[sourceVar.index].content); - target = targetRecord.element[targetRecord.index]; - if (!target) { - targetId = program.getValue(targetRecord.value[targetRecord.index]); - target = document.getElementById(targetId); - } - target.innerHTML = source.innerHTML; - break; - case `setContent`: - value = program.getValue(command.value); - targetRecord = program.getSymbolRecord(command.target); - target = targetRecord.element[targetRecord.index]; - if (!target) { - cssId = targetRecord.value[targetRecord.index].content; - if (!cssId) { - program.runtimeError(command.lino, - `Variable '${targetRecord.name}' has not been attached to a DOM element.`); - return 0; - } - target = document.getElementById(cssId); - } - targetRecord.element[targetRecord.index] = target; - switch (targetRecord.keyword) { - case `text`: - case `textarea`: - target.value = value; - break; - case `input`: - target.value = value; - break; - default: - target.innerHTML = value; - break; - } - break; - case `setSelect`: - // The source is assumed to be an array - sourceRecord = program.getSymbolRecord(command.source); - const sourceData = program.getValue(sourceRecord.value[sourceRecord.index]); - var itemArray = ``; - try { - itemArray = JSON.parse(sourceData); - } catch (err) { - program.runtimeError(command.lino, `Can't parse JSON`); - return 0; - } - // The target is assumed to be a SELECT - selectRecord = program.getSymbolRecord(command.select); - const select = selectRecord.element[selectRecord.index]; - select.options.length = 0; - // Get the name of the display field - const display = program.getValue(command.display); - // For each item, set the title and inner HTML - itemArray.forEach(function (item) { - const title = display ? program.decode(item[display]) : null; - const opt = document.createElement(`option`); - const innerHTML = title ? title : item; - opt.innerHTML = innerHTML; - const value = title ? JSON.stringify(item) : item; - opt.value = value; - select.appendChild(opt); - }); - if (display) { - select.selectedIndex = itemArray.indexOf(display); - } else { - select.selectedIndex = -1; - } - break; - case `setClass`: - symbol = program.getSymbolRecord(command.symbolName); - target = symbol.element[symbol.index]; - if (!target) { - targetId = program.getValue(symbol.value[symbol.index]); - target = document.getElementById(targetId); - } - program.getValue(command.value).split(` `).forEach(function(item) { - target.classList.remove(item); - target.classList.add(item); - }); - break; - case `setId`: - symbol = program.getSymbolRecord(command.symbolName); - target = symbol.element[symbol.index]; - if (!target) { - targetId = program.getValue(symbol.value[symbol.index]); - target = document.getElementById(targetId); - } - target.id = program.getValue(command.value); - break; - case `setText`: - symbol = program.getSymbolRecord(command.symbolName); - target = symbol.element[symbol.index]; - if (!target) { - targetId = program.getValue(symbol.value[symbol.index]); - target = document.getElementById(targetId); - } - value = program.getValue(command.value); - switch (symbol.keyword) { - case `button`: - case `span`: - case `label`: - case `legend`: - target.innerHTML = value; - break; - case `input`: - target.value = value; - break; - default: - break; - } - break; - case `setSize`: - symbol = program.getSymbolRecord(command.symbolName); - if (symbol.keyword === `input`) { - target = symbol.element[symbol.index]; - if (!target) { - targetId = program.getValue(symbol.value[symbol.index]); - target = document.getElementById(targetId); - } - target.size = program.getValue(command.value); - } else { - program.runtimeError(command.lino, `Inappropriate variable type '${symbol.name}'`); - } - break; - case `setAttribute`: - symbol = program.getSymbolRecord(command.symbolName); - target = symbol.element[symbol.index]; - if (!target) { - targetId = program.getValue(symbol.value[symbol.index]); - target = document.getElementById(targetId); - } - const attributeName = program.getValue(command.attributeName); - if (command.attributeValue.type === `boolean`) { - target.setAttribute(attributeName, command.attributeValue.content); - } else { - target.setAttribute(attributeName, program.getValue(command.attributeValue)); - } - break; - case `setAttributes`: - symbol = program.getSymbolRecord(command.symbolName); - target = symbol.element[symbol.index]; - if (!target) { - targetId = program.getValue(symbol.value[symbol.index]); - target = document.getElementById(targetId); - } - for (let n = target.attributes.length - 1; n >= 0; n--) { - target.removeAttribute(target.attributes[n].name); - } - let attributes = program.getValue(command.attributes); - let list = attributes.split(" "); - for (let n = 0; n < list.length; n++) { - let attribute = list[n]; - let p = attribute.indexOf(`=`); - if (p > 0) { - target.setAttribute(attribute.substr(0, p), attribute.substr(p + 1)); - } - else { - target.setAttribute(attribute, attribute); - } - } - break; - case `setStyle`: - case `setStyles`: - symbol = program.getSymbolRecord(command.symbolName); - target = symbol.element[symbol.index]; - if (!target) { - const symbolElement = symbol.value[symbol.index]; - if (!symbolElement.type) { - program.runtimeError(command.lino, `Variable '${symbol.name}' is not attached to a DOM element.`); - return 0; - } - targetId = program.getValue(symbolElement); - target = document.getElementById(targetId); - } - const styleValue = program.getValue(command.styleValue); - if (!symbol.value[symbol.index]) { - program.runtimeError(command.lino, `Variable '${symbol.name}' has not been assigned.`); - return 0; - } - switch (command.type) { - case `setStyle`: - target.style[command.styleName.content] = styleValue; - break; - case `setStyles`: - target.style.cssText = styleValue; - break; - } - break; - case `setHeadStyle`: - const headStyleName = program.getValue(command.styleName); - const headStyleValue = program.getValue(command.styleValue); - var style = document.createElement('style'); - style.innerHTML = `${headStyleName} ${headStyleValue}`; - for (let i = 0; i < document.head.childNodes.length; i++) { - let node = document.head.childNodes[i]; - if (node.tagName === `STYLE`) { - let data = node.innerHTML; - if (data.indexOf(`${headStyleName} `) === 0) { - document.head.removeChild(node); - break; - } - } - } - document.head.appendChild(style); - break; - case `setBodyStyle`: - const bodyStyleValue = program.getValue(command.styleValue); - switch (command.styleName.content) { - case `background`: - document.body.style.background = bodyStyleValue; - break; - default: - program.runtimeError(command.lino, - `Unsupported body attribute '${command.styleName.content}'`); - return 0; - } - break; - case `setTitle`: - document.title = program.getValue(command.value); - break; - case `setDefault`: - selectRecord = program.getSymbolRecord(command.name); - value = program.getValue(command.value); - const element = selectRecord.element[selectRecord.index]; - for (let n = 0; n < element.options.length; n++) { - if (element.options[n].value === value) { - element.selectedIndex = n; - break; - } - } - break; - default: - break; - } - return command.pc + 1; - } - }, - - SPAN: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `span`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - TABLE: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `table`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - TR: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `tr`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - TD: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `td`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - TEXTAREA: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `textarea`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Trace: { - - compile: (compiler) => { - const lino = compiler.getLino(); - const variables = []; - if (compiler.nextIsSymbol()) { - while (compiler.isSymbol()) { - variables.push(compiler.getToken()); - compiler.next(); - } - let alignment = `horizontal`; - if (compiler.tokenIs(`horizontal`) || compiler.tokenIs(`vertical`)) { - alignment = compiler.getToken(); - compiler.next(); - } - compiler.addCommand({ - domain: `browser`, - keyword: `trace`, - variant: `setup`, - lino, - variables, - alignment - }); - return true; - } - compiler.addCommand({ - domain: `browser`, - keyword: `trace`, - variant: `run`, - lino - }); - return true; - }, - - run: (program) => { - const command = program[program.pc]; - switch (command.variant) { - case `setup`: - console.log(`Set up tracer`); - program.tracer = { - variables: command.variables, - alignment: command.alignment - }; - break; - case `run`: - console.log(`Run tracer`); - if (!program.tracer) { - program.tracer = { - variables: [], - alignment: `horizontal` - }; - } - if (!program.tracing) { - const tracer = document.getElementById(`easycoder-tracer`); - if (tracer) { - tracer.innerHTML = - `
    ` + - `` + - `
    ` + - `
    `; - tracer.style.display = `none`; - } - program.tracing = true; - } - program.stop = false; - break; - } - return program.pc + 1; - } - }, - - UL: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `ul`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Upload: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const file = compiler.getToken(); - if (compiler.nextTokenIs(`to`)) { - const path = compiler.getNextValue(); - if (compiler.tokenIs(`with`)) { - if (compiler.nextIsSymbol()) { - const progress = compiler.getToken(); - if (compiler.nextTokenIs(`and`)) { - if (compiler.nextIsSymbol()) { - const status = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `upload`, - lino, - file, - path, - progress, - status - }); - return true; - } - } - } - } - } - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const fileSpec = program.getSymbolRecord(command.file); - const path = program.getValue(command.path); - const progressSpec = program.getSymbolRecord(command.progress); - const statusSpec = program.getSymbolRecord(command.status); - - const file = fileSpec.element[fileSpec.index]; - const progress = progressSpec.element[progressSpec.index]; - const status = statusSpec.element[statusSpec.index]; - - const setProgress = (value) => { - if (progress) { - progress.value = value; - } - }; - const setStatus = (value) => { - if (status) { - status.innerHTML = value; - } - }; - - const source = file.files[0]; - if (source) { - const formData = new FormData(); - formData.append(`source`, source); - formData.append(`path`, path); - const ajax = new XMLHttpRequest(); - ajax.upload.addEventListener(`progress`, function (event) { - const percent = Math.round((event.loaded / event.total) * 100); - setProgress(percent); - setStatus(`${Math.round(percent)}%...`); - }, false); - ajax.addEventListener(`load`, function (event) { - const response = event.target.responseText; - setProgress(0); - setStatus(``); - console.log(response); - }, false); - ajax.addEventListener(`error`, function () { - setStatus(`Upload failed`); - console.log(`Upload failed`); - }, false); - ajax.addEventListener(`abort`, function () { - setStatus(`Upload aborted`); - console.log(`Upload aborted`); - }, false); - ajax.onreadystatechange = function () { - if (this.readyState === 4) { - const command = program.ajaxCommand; - const status = this.status; - switch (status) { - case 200: - program.run(command.pc + 1); - break; - case 0: - break; - default: - try { - program.runtimeError(command.lino, `Error ${status}`); - } catch (err) { - program.reportError(err, program); - } - break; - } - } - }; - program.ajaxCommand = command; - const postpath = path.startsWith(`http`) ? path : `${window.location.origin}/${EasyCoder_Plugins.rest()}/${path}`; - ajax.open(`POST`, postpath); - ajax.send(formData); - } - return 0; - } - }, - - getHandler: (name) => { - switch (name) { - case `a`: - return EasyCoder_Browser.A; - case `alert`: - return EasyCoder_Browser.Alert; - case `attach`: - return EasyCoder_Browser.Attach; - case `audioclip`: - return EasyCoder_Browser.Audioclip; - case `blockquote`: - return EasyCoder_Browser.BLOCKQUOTE; - case `button`: - return EasyCoder_Browser.BUTTON; - case `canvas`: - return EasyCoder_Browser.CANVAS; - case `clear`: - return EasyCoder_Browser.Clear; - case `convert`: - return EasyCoder_Browser.Convert; - case `create`: - return EasyCoder_Browser.Create; - case `disable`: - return EasyCoder_Browser.Disable; - case `div`: - return EasyCoder_Browser.DIV; - case `enable`: - return EasyCoder_Browser.Enable; - case `fieldset`: - return EasyCoder_Browser.FIELDSET; - case `file`: - return EasyCoder_Browser.FILE; - case `focus`: - return EasyCoder_Browser.Focus; - case `form`: - return EasyCoder_Browser.FORM; - case `fullscreen`: - return EasyCoder_Browser.FullScreen; - case `get`: - return EasyCoder_Browser.Get; - case `h1`: - return EasyCoder_Browser.H1; - case `h2`: - return EasyCoder_Browser.H2; - case `h3`: - return EasyCoder_Browser.H3; - case `h4`: - return EasyCoder_Browser.H4; - case `h5`: - return EasyCoder_Browser.H5; - case `h6`: - return EasyCoder_Browser.H6; - case `highlight`: - return EasyCoder_Browser.Highlight; - case `history`: - return EasyCoder_Browser.History; - case `hr`: - return EasyCoder_Browser.HR; - case `image`: - return EasyCoder_Browser.IMAGE; - case `img`: - return EasyCoder_Browser.IMG; - case `input`: - return EasyCoder_Browser.INPUT; - case `label`: - return EasyCoder_Browser.LABEL; - case `legend`: - return EasyCoder_Browser.LEGEND; - case `li`: - return EasyCoder_Browser.LI; - case `location`: - return EasyCoder_Browser.Location; - case `mail`: - return EasyCoder_Browser.Mail; - case `on`: - return EasyCoder_Browser.On; - case `option`: - return EasyCoder_Browser.OPTION; - case `p`: - return EasyCoder_Browser.P; - case `play`: - return EasyCoder_Browser.Play; - case `pre`: - return EasyCoder_Browser.PRE; - case `progress`: - return EasyCoder_Browser.PROGRESS; - case `put`: - return EasyCoder_Browser.Put; - case `remove`: - return EasyCoder_Browser.Remove; - case `request`: - return EasyCoder_Browser.Request; - case `select`: - return EasyCoder_Browser.SELECT; - case `scroll`: - return EasyCoder_Browser.Scroll; - case `section`: - return EasyCoder_Browser.SECTION; - case `set`: - return EasyCoder_Browser.Set; - case `span`: - return EasyCoder_Browser.SPAN; - case `table`: - return EasyCoder_Browser.TABLE; - case `tr`: - return EasyCoder_Browser.TR; - case `td`: - return EasyCoder_Browser.TD; - case `textarea`: - return EasyCoder_Browser.TEXTAREA; - case `trace`: - return EasyCoder_Browser.Trace; - case `ul`: - return EasyCoder_Browser.UL; - case `upload`: - return EasyCoder_Browser.Upload; - default: - return null; - } - }, - - run: (program) => { - const command = program[program.pc]; - const handler = EasyCoder_Browser.getHandler(command.keyword); - if (!handler) { - program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'browser' package`); - } - return handler.run(program); - }, - - value: { - - compile: (compiler) => { - if (compiler.isSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (compiler.nextTokenIs(`exists`)) { - if (symbolRecord.extra === `dom`) { - compiler.next(); - return { - domain: `browser`, - type: `exists`, - value: symbolRecord.name - }; - } - return null; - } - switch (symbolRecord.keyword) { - case `file`: - case `input`: - case `select`: - case `textarea`: - return { - domain: `browser`, - type: symbolRecord.keyword, - value: symbolRecord.name - }; - } - return null; - } - - if (compiler.tokenIs(`the`)) { - compiler.next(); - } - let offset = false; - if (compiler.tokenIs(`offset`)) { - offset = true; - compiler.next(); - } - - let type = compiler.getToken(); - let text; - let attribute; - switch (type) { - case `mobile`: - case `portrait`: - case `landscape`: - case `br`: - case `location`: - case `key`: - case `hostname`: - compiler.next(); - return { - domain: `browser`, - type - }; - case `content`: - case `text`: - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbol = compiler.getSymbolRecord(); - compiler.next(); - return { - domain: `browser`, - type: `contentOf`, - symbol: symbol.name - }; - } - throw new Error(`'${compiler.getToken()}' is not a symbol`); - } - return null; - case `selected`: - let arg = compiler.nextToken(); - if ([`index`, `item`].includes(arg)) { - if ([`in`, `of`].includes(compiler.nextToken())) { - if (compiler.nextIsSymbol()) { - const symbol = compiler.getSymbolRecord(); - if ([`ul`, `ol`, `select`].includes(symbol.keyword)) { - compiler.next(); - return { - domain: `browser`, - type: `selected`, - symbol: symbol.name, - arg - }; - } - } - } - } - return null; - case `color`: - compiler.next(); - const value = compiler.getValue(); - return { - domain: `browser`, - type, - value - }; - case `attribute`: - attribute = compiler.getNextValue(); - if (compiler.tokenIs(`of`)) { - compiler.next(); - if (compiler.isSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.extra === `dom`) { - compiler.next(); - return { - domain: `browser`, - type: `attributeOf`, - attribute, - symbol: symbolRecord.name - }; - } - } - } - return null; - case `style`: - const style = compiler.getNextValue(); - if (compiler.tokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.extra === `dom`) { - compiler.next(); - return { - domain: `browser`, - type, - style, - target: symbolRecord.name - }; - } - } - } - return null; - case `confirm`: - text = compiler.getNextValue(); - return { - domain: `browser`, - type: `confirm`, - text - }; - case `prompt`: - text = compiler.getNextValue(); - let pre = null; - if (compiler.tokenIs(`with`)) { - pre = compiler.getNextValue(); - } - return { - domain: `browser`, - type: `prompt`, - text, - pre - }; - case `screen`: - attribute = compiler.nextToken(); - if ([`width`, `height`].includes(attribute)) { - compiler.next(); - return { - domain: `browser`, - type, - attribute - }; - } - break; - case `top`: - case `bottom`: - case `left`: - case `right`: - case `width`: - case `height`: - return EasyCoder_Browser.value.getCoord(compiler, type, offset); - case `scroll`: - if (compiler.nextTokenIs(`position`)) { - compiler.next(); - return { - domain: `browser`, - type: `scrollPosition` - }; - } - return null; - case `document`: - if (compiler.nextTokenIs(`path`)) { - compiler.next(); - return { - domain: `browser`, - type: `docPath` - }; - } - return null; - case `storage`: - if (compiler.nextTokenIs(`keys`)) { - compiler.next(); - return { - domain: `browser`, - type: `storageKeys` - }; - } - return null; - case `parent`: - switch (compiler.nextToken()) { - case `name`: - compiler.next(); - return { - domain: `browser`, - type: `varName` - }; - case `index`: - compiler.next(); - return { - domain: `browser`, - type: `varIndex` - }; - } - return null; - case `history`: - if (compiler.nextTokenIs(`state`)) { - compiler.next(); - return { - domain: `browser`, - type: `historyState` - }; - } - return null; - case `pick`: - case `drag`: - if (compiler.nextTokenIs(`position`)) { - compiler.next(); - return { - domain: `browser`, - type: `${type}Position` - }; - } - } - return null; - }, - - getCoord: (compiler, type, offset) => { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextTokenIs(`window`)) { - compiler.next(); - return { - domain: `browser`, - type, - symbol: `window`, - offset - }; - } - let symbolRecord = null; - if (compiler.isSymbol()) { - symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.extra === `dom`) { - compiler.next(); - return { - domain: `browser`, - type, - symbol: symbolRecord.name, - offset - }; - } - } - } - return null; - }, - - get: (program, value) => { - let symbolRecord; - let element; - let target; - let content; - switch (value.type) { - case `file`: - case `input`: - case `select`: - case `textarea`: - symbolRecord = program.getSymbolRecord(value.value); - target = symbolRecord.element[symbolRecord.index]; - return { - type: `constant`, - numeric: false, - content: target.value - }; - case `exists`: - symbolRecord = program.getSymbolRecord(value.value); - return { - domain: `browser`, - type: `boolean`, - content: typeof symbolRecord.element[symbolRecord.index] !== `undefined` - }; - case `mobile`: - return { - domain: `browser`, - type: `boolean`, - content: (typeof window.orientation !== `undefined`) || (navigator.userAgent.indexOf(`IEMobile`) !== -1) - }; - case `portrait`: - return { - domain: `browser`, - type: `boolean`, - content: document.documentElement.clientWidth < document.documentElement.clientHeight - }; - case `landscape`: - return { - domain: `browser`, - type: `boolean`, - content: document.documentElement.clientWidth >= document.documentElement.clientHeight - }; - case `br`: - return { - type: `constant`, - numeric: false, - content: decodeURIComponent(`%3Cbr%20%2F%3E`) - }; - case `attributeOf`: - symbolRecord = program.getSymbolRecord(value.symbol); - const attribute = program.getValue(value.attribute); - target = symbolRecord.element[symbolRecord.index]; - if (attribute.indexOf(`data-`) === 0) { - return program.getSimpleValue(target.dataset[attribute.substr(5)]); - } - return program.getSimpleValue(target[attribute]); - case `style`: - symbolRecord = program.getSymbolRecord(value.target); - const style = program.getValue(value.style); - target = symbolRecord.element[symbolRecord.index]; - return program.getSimpleValue(target.style[style]); - case `confirm`: - return { - type: `boolean`, - content: window.confirm(program.getValue(value.text)) - }; - case `prompt`: - const text = program.getValue(value.text); - const pre = program.getValue(value.pre); - return { - type: `constant`, - numeric: false, - content: pre ? window.prompt(text, pre) : window.prompt(text) - }; - case `contentOf`: - symbolRecord = program.getSymbolRecord(value.symbol); - target = symbolRecord.element[symbolRecord.index]; - switch (symbolRecord.keyword) { - case `input`: - case `textarea`: - content = target.value; - break; - case `pre`: - content = target.innerHTML; - break; - default: - content = target.innerHTML.split(`\n`).join(``); - break; - } - return { - type: `constant`, - numeric: false, - content - }; - case `selected`: - symbolRecord = program.getSymbolRecord(value.symbol); - target = symbolRecord.element[symbolRecord.index]; - let selectedIndex = target.selectedIndex; - let selectedText = selectedIndex >= 0 ? target.options[selectedIndex].text : ``; - content = (value.arg === `index`) ? selectedIndex : selectedText; - return { - type: `constant`, - numeric: false, - content - }; - case `top`: - if (value.symbol == `window`) { - return { - type: `constant`, - numeric: true, - content: window.screenY - }; - } - symbolRecord = program.getSymbolRecord(value.symbol); - element = symbolRecord.element[symbolRecord.index]; - content = Math.round(value.offset ? element.offsetTop : element.getBoundingClientRect().top); - return { - type: `constant`, - numeric: true, - content - }; - case `bottom`: - if (value.symbol == `window`) { - return { - type: `constant`, - numeric: true, - content: window.screenY + window.innerHeight - }; - } - symbolRecord = program.getSymbolRecord(value.symbol); - content = Math.round(symbolRecord.element[symbolRecord.index].getBoundingClientRect().bottom); - return { - type: `constant`, - numeric: true, - content - }; - case `left`: - if (value.symbol == `window`) { - return { - type: `constant`, - numeric: true, - content: window.screenLeft - }; - } - symbolRecord = program.getSymbolRecord(value.symbol); - element = symbolRecord.element[symbolRecord.index]; - content = Math.round(value.offset ? element.offsetLeft : element.getBoundingClientRect().left); - return { - type: `constant`, - numeric: true, - content - }; - case `right`: - if (value.symbol == `window`) { - return { - type: `constant`, - numeric: true, - content: window.screenX + window.innerWidth - }; - } - symbolRecord = program.getSymbolRecord(value.symbol); - content = Math.round(symbolRecord.element[symbolRecord.index].getBoundingClientRect().right); - return { - type: `constant`, - numeric: true, - content - }; - case `width`: - if (value.symbol == `window`) { - return { - type: `constant`, - numeric: true, - content: window.innerWidth - }; - } - symbolRecord = program.getSymbolRecord(value.symbol); - content = Math.round(symbolRecord.element[symbolRecord.index].getBoundingClientRect().width); - return { - type: `constant`, - numeric: true, - content - }; - case `height`: - if (value.symbol == `window`) { - return { - type: `constant`, - numeric: true, - content: window.innerHeight - }; - } - symbolRecord = program.getSymbolRecord(value.symbol); - content = Math.round(symbolRecord.element[symbolRecord.index].getBoundingClientRect().height); - return { - type: `constant`, - numeric: true, - content - }; - case `color`: - const styleValue = program.value.evaluate(program, value.value).content; - const hex = styleValue.toString(16).padStart(6, `0`); - return { - type: `constant`, - numeric: false, - content: `#${hex}` - }; - case `docPath`: - return { - type: `constant`, - numeric: false, - content: program.docPath - }; - case `storageKeys`: - return { - type: `constant`, - numeric: false, - content: JSON.stringify(Object.keys(localStorage)) - }; - case `location`: - return { - type: `constant`, - numeric: false, - content: window.location.href - }; - case `historyState`: - return { - type: `constant`, - numeric: false, - content: window.history.state - }; - case `scrollPosition`: - return { - type: `constant`, - numeric: true, - content: scrollPosition - }; - case `varName`: - return { - type: `constant`, - numeric: false, - content: program.varName - }; - case `varIndex`: - return { - type: `constant`, - numeric: true, - content: program.varIndex - }; - case `key`: - return { - type: `constant`, - numeric: false, - content: program.key - }; - case `hostname`: - return { - type: `constant`, - numeric: false, - content: location.hostname - }; - case `screen`: - return { - type: `constant`, - numeric: true, - content: screen[value.attribute] - }; - case `pickPosition`: - return { - type: `constant`, - numeric: false, - content: JSON.stringify({ - "x": document.pickX, - "y": document.pickY - }) - }; - case `dragPosition`: - return { - type: `constant`, - numeric: false, - content: JSON.stringify({ - "x": document.dragX, - "y": document.dragY - }) - }; - } - } - }, - - condition: { - - compile: (compiler) => { - if (compiler.tokenIs(`confirm`)) { - const value = compiler.getNextValue(); - return { - domain: `browser`, - type: `confirm`, - value - }; - } else if (compiler.tokenIs(`element`)) { - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.extra === `dom`) { - const token = compiler.nextToken(); - if (token === `has`) { - if (compiler.nextTokenIs(`the`)) { - compiler.next(); - } - if (compiler.tokenIs(`focus`)) { - compiler.next(); - return { - domain: `browser`, - type: `focus`, - element: symbolRecord.name - }; - } - } else if (token === `contains`) { - const position = compiler.getNextValue(); - return { - domain: `browser`, - type: `contains`, - element: symbolRecord.name, - position - }; - } - } - } - } - return null; - }, - - test: (program, condition) => { - switch (condition.type) { - case `confirm`: - return confirm(program.getValue(condition.value)); - case `focus`: - const focusRecord = program.getSymbolRecord(condition.element); - return focusRecord.element[focusRecord.index] === document.activeElement; - case `contains`: - const containsRecord = program.getSymbolRecord(condition.element); - const element = containsRecord.element[containsRecord.index]; - const bounds = element.getBoundingClientRect(); - const left = Math.round(bounds.left); - const right = Math.round(bounds.right); - const top = Math.round(bounds.top); - const bottom = Math.round(bounds.bottom); - const position = JSON.parse(program.getValue(condition.position)); - const x = position.x; - const y = position.y; - if (x >= left && x <= right && y >= top && y <= bottom) { - return true; - } - return false; - } - } - }, - - setStyles: (id, styleString) => { - const element = document.getElementById(id); - const styles = styleString.split(`;`); - for (const item of styles) { - const style = item.split(`:`); - element.setAttribute(style[0], style[1]); - } - } -}; - -let scrollPosition = 0; - -window.addEventListener(`scroll`, function () { - scrollPosition = this.scrollY; -}); - -window.onpopstate = function (event) { - window.EasyCoder.timestamp = Date.now(); - const state = JSON.parse(event.state); - if (state && state.script) { - const program = window.EasyCoder.scripts[state.script]; - if (program) { - if (program.onBrowserBack) { - program.run(program.onBrowserBack); - } - } else { - console.log(`No script property in window state object`); - } - } -}; diff --git a/js/plugins/ckeditor.js b/js/plugins/ckeditor.js index 32d64dd..bbc8578 100644 --- a/js/plugins/ckeditor.js +++ b/js/plugins/ckeditor.js @@ -170,3 +170,6 @@ const EasyCoder_CKEditor = { test: () => {} } }; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.ckeditor = EasyCoder_CKEditor; diff --git a/js/plugins/codemirror.js b/js/plugins/codemirror.js index ccec906..266cb48 100644 --- a/js/plugins/codemirror.js +++ b/js/plugins/codemirror.js @@ -168,3 +168,6 @@ const EasyCoder_CodeMirror = { test: () => {} } }; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.codemirror = EasyCoder_CodeMirror; diff --git a/js/plugins/dummy.js b/js/plugins/dummy.js index fd416c4..36bbd02 100644 --- a/js/plugins/dummy.js +++ b/js/plugins/dummy.js @@ -63,4 +63,7 @@ const EasyCoder_Dummy = { } return handler.run(program); } -}; \ No newline at end of file +}; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.dummy = EasyCoder_Dummy; diff --git a/js/plugins/gmap.js b/js/plugins/gmap.js index 52ce2ea..404f88c 100644 --- a/js/plugins/gmap.js +++ b/js/plugins/gmap.js @@ -556,3 +556,6 @@ const EasyCoder_GMap = { test: () => {} } }; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.gmap = EasyCoder_GMap; diff --git a/js/plugins/json.js b/js/plugins/json.js deleted file mode 100644 index fdf93a4..0000000 --- a/js/plugins/json.js +++ /dev/null @@ -1,510 +0,0 @@ -const EasyCoder_Json = { - - name: `EasyCoder_JSON`, - - Json: { - - compile: (compiler) => { - const lino = compiler.getLino(); - const request = compiler.nextToken(); - let item; - switch (request) { - case `set`: - compiler.next(); - if (compiler.isSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - if (compiler.nextTokenIs(`to`)) { - const type = compiler.nextToken(); - if (`["array","object"]`.includes(type)) { - compiler.next(); - compiler.addCommand({ - domain: `json`, - keyword: `json`, - lino, - request: `setVariable`, - target: targetRecord.name, - type - }); - return true; - } - } - } else if (targetRecord.keyword === `select`) { - if (compiler.nextTokenIs(`from`)) { - compiler.next(); - if (compiler.isSymbol()) { - const sourceRecord = compiler.getSymbolRecord(); - if (sourceRecord.keyword === `variable`) { - var display = null; - if (compiler.nextTokenIs(`as`)) { - display = compiler.getNextValue(); - } - compiler.addCommand({ - domain: `json`, - keyword: `json`, - lino, - request: `setList`, - target: targetRecord.name, - source: sourceRecord.name, - display - }); - return true; - } - } - } - } - break; - } - break; - case `sort`: - case `shuffle`: - case `format`: - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - compiler.next(); - compiler.addCommand({ - domain: `json`, - keyword: `json`, - lino, - request, - target: targetRecord.name - }); - return true; - } - } - break; - case `parse`: - if (compiler.nextTokenIs(`url`)) { - const source = compiler.getNextValue(); - if (compiler.tokenIs(`as`)) { - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - compiler.next(); - compiler.addCommand({ - domain: `json`, - keyword: `json`, - lino, - request, - source, - target: targetRecord.name - }); - return true; - } - } - } - } - break; - case `delete`: - const what = compiler.nextToken(); - if ([`property`, `element`].includes(what)) { - const value = compiler.getNextValue(); - if ([`from`, `of`].includes(compiler.getToken())) { - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - compiler.next(); - compiler.addCommand({ - domain: `json`, - keyword: `json`, - lino, - request, - what, - value, - target: targetRecord.name - }); - return true; - } - } - } - } - break; - case `rename`: - const oldName = compiler.getNextValue(); - if (compiler.tokenIs(`to`)) { - const newName = compiler.getNextValue(); - if (compiler.tokenIs(`in`)) { - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - compiler.next(); - compiler.addCommand({ - domain: `json`, - keyword: `json`, - lino, - request, - oldName, - newName, - target: targetRecord.name - }); - return true; - } - } - } - } - break; - case `add`: - item = compiler.getNextValue(); - if (compiler.tokenIs(`to`)) { - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - compiler.next(); - compiler.addCommand({ - domain: `json`, - keyword: `json`, - lino, - request, - item, - target: targetRecord.name - }); - return true; - } - } - } - break; - case `split`: - item = compiler.getNextValue(); - let on = `\n`; - if (compiler.tokenIs(`on`)) { - on = compiler.getNextValue(); - } - if ([`giving`, `into`].includes(compiler.getToken())) { - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - compiler.next(); - compiler.addCommand({ - domain: `json`, - keyword: `json`, - lino, - request, - item, - on, - target: targetRecord.name - }); - return true; - } - } - } - break; - case `replace`: - if (compiler.nextTokenIs(`element`)) { - const index = compiler.getNextValue(); - if (compiler.tokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - if ([`by`, `with`].includes(compiler.nextToken())) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `json`, - keyword: `json`, - lino, - request, - target: targetRecord.name, - index, - value - }); - return true; - } - } - } - } - } - break; - } - compiler.addWarning(`Unrecognised json command syntax`); - return false; - }, - - run: (program) => { - const command = program[program.pc]; - let sourceRecord; - let targetRecord; - let record; - let content; - let array; - switch (command.request) { - case `setVariable`: - targetRecord = program.getSymbolRecord(command.target); - content = (command.type === `array`) ? `[]` : `{}`; - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content - }; - break; - case `setList`: - // The source is assumed to be a JSON array - sourceRecord = program.getSymbolRecord(command.source); - const sourceData = program.getValue(sourceRecord.value[sourceRecord.index]); - var itemArray = ``; - try { - itemArray = JSON.parse(sourceData); - } catch (err) { - program.runtimeError(command.lino, `Can't parse JSON`); - return 0; - } - // The target is assumed to be a SELECT - targetRecord = program.getSymbolRecord(command.target); - const target = targetRecord.element[targetRecord.index]; - target.options.length = 0; - // Get the name of the display field - const display = program.getValue(command.display); - // For each item, set the title and inner HTML - itemArray.forEach(function (item) { - const title = display ? program.decode(item[display]) : null; - const opt = document.createElement(`option`); - const innerHTML = title ? title : item; - opt.innerHTML = innerHTML; - const value = title ? JSON.stringify(item) : item; - opt.value = value; - target.appendChild(opt); - }); - target.selectedIndex = -1; - break; - case `sort`: - targetRecord = program.getSymbolRecord(command.target); - const list = program.getValue(targetRecord.value[targetRecord.index]); - content = list ? JSON.stringify(JSON.parse(list).sort()) : null; - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content - }; - break; - case `shuffle`: - targetRecord = program.getSymbolRecord(command.target); - array = JSON.parse(program.getValue(targetRecord.value[targetRecord.index])); - for (let i = array.length - 1; i > 0; i--) { - const j = Math.floor(Math.random() * (i + 1)); - [array[i], array[j]] = [array[j], array[i]]; - } - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content: JSON.stringify(array) - }; - break; - case `format`: - targetRecord = program.getSymbolRecord(command.target); - const val = JSON.parse(program.getValue(targetRecord.value[targetRecord.index])); - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content: JSON.stringify(val, null, 2) - }; - break; - case `parse`: - var source = program.getValue(command.source); - targetRecord = program.getSymbolRecord(command.target); - content = { - url: source - }; - var n = source.indexOf(`://`); - if (n >= 0) { - n += 3; - content.protocol = source.substr(0, n); - source = source.substr(n); - } - n = source.indexOf(`?`); - if (n > 0) { - content.domain = source.substr(0, n); - content.arg = source.substr(n + 1); - } else { - content.domain = source; - } - if (content.domain.endsWith(`/`)) { - content.domain = content.domain.slice(0, -1); - } - n = content.domain.indexOf(`/`); - if (n > 0) { - content.path = content.domain.substr(n + 1); - content.domain = content.domain.substr(0, n); - } - else { - content.path = ``; - } - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content: JSON.stringify(content, null, 2) - }; - break; - case `delete`: - switch (command.what) { - case `property`: - const name = program.getValue(command.value); - targetRecord = program.getSymbolRecord(command.target); - record = JSON.parse(targetRecord.value[targetRecord.index].content); - delete record[name]; - targetRecord.value[targetRecord.index].content = JSON.stringify(record); - break; - case `element`: - const element = program.getValue(command.value); - targetRecord = program.getSymbolRecord(command.target); - record = JSON.parse(targetRecord.value[targetRecord.index].content); - record.splice(element, 1); - targetRecord.value[targetRecord.index].content = JSON.stringify(record); - break; - } - break; - case `rename`: - const oldName = program.getValue(command.oldName); - const newName = program.getValue(command.newName); - targetRecord = program.getSymbolRecord(command.target); - record = JSON.parse(targetRecord.value[targetRecord.index].content); - content = record[oldName]; - delete record[oldName]; - record[newName] = content; - targetRecord.value[targetRecord.index].content = JSON.stringify(record); - break; - case `add`: - content = program.getValue(command.item); - targetRecord = program.getSymbolRecord(command.target); - const existing = targetRecord.value[targetRecord.index].content; - record = existing ? JSON.parse(existing) : []; - record.push((`[`, `{`).includes(content[0]) ? JSON.parse(content) :content); - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content: JSON.stringify(record) - }; - break; - case `split`: - content = program.getValue(command.item); - const on = program.getValue(command.on); - targetRecord = program.getSymbolRecord(command.target); - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content: JSON.stringify(content.split(on)) - }; - break; - case `replace`: - targetRecord = program.getSymbolRecord(command.target); - const index = program.getValue(command.index); - const value = program.getValue(command.value); - const current = targetRecord.value[targetRecord.index].content; - record = current ? JSON.parse(current) : []; - if (index > record.length - 1) { - program.runtimeError(command.lino, `Index out of range`); - } - record[index] = value; - targetRecord.value[targetRecord.index].content = JSON.stringify(record); - break; - } - return command.pc + 1; - } - }, - - getHandler: (name) => { - switch (name) { - case `json`: - return EasyCoder_Json.Json; - default: - return null; - } - }, - - run: (program) => { - const command = program[program.pc]; - const handler = EasyCoder_Json.getHandler(command.keyword); - if (!handler) { - program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'json' package`); - } - return handler.run(program); - }, - - value: { - - compile: (compiler) => { - if (compiler.tokenIs(`the`)) { - compiler.next(); - } - if (compiler.tokenIs(`json`)) { - const type = compiler.nextToken(); - if ([`size`, `count`, `keys`].includes(type)) { - compiler.skip(`of`); - if (compiler.isSymbol()) { - const target = compiler.getSymbolRecord(); - compiler.next(); - if (target.isVHolder) { - return { - domain: `json`, - type, - name: target.name - }; - } - } - } else if (type === `index`) { - if (compiler.nextTokenIs(`of`)) { - const item = compiler.getNextValue(); - if (compiler.tokenIs(`in`)) { - const list = compiler.getNextValue(); - return { - domain: `json`, - type, - item, - list - }; - } - } - } - } - return null; - }, - - get: (program, value) => { - let symbolRecord; - let data; - let content; - switch (value.type) { - case `size`: - case `count`: - symbolRecord = program.getSymbolRecord(value.name); - data = program.getValue(symbolRecord.value[symbolRecord.index]); - let array; - try { - array = JSON.parse(data); - } catch (err) { - array = []; - } - return { - type: `constant`, - numeric: true, - content: array ? array.length : 0 - }; - case `keys`: - symbolRecord = program.getSymbolRecord(value.name); - data = program.getValue(symbolRecord.value[symbolRecord.index]); - content = data ? JSON.stringify(Object.keys(JSON.parse(data)).sort()) : `[]`; - return { - type: `constant`, - numeric: false, - content - }; - case `index`: - const item = program.getValue(value.item); - const list = JSON.parse(program.getValue(value.list)); - content = list.findIndex(function (value) { - return value === item; - }); - return { - type: `constant`, - numeric: true, - content - }; - } - } - }, - - condition: { - - compile: () => {}, - - test: () => {} - } -}; diff --git a/js/plugins/life.js b/js/plugins/life.js index 37c6ecd..5d7d4f5 100644 --- a/js/plugins/life.js +++ b/js/plugins/life.js @@ -88,4 +88,7 @@ const EasyCoder_Life = { compile: () => {} } -}; \ No newline at end of file +}; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.life = EasyCoder_Life; diff --git a/js/plugins/rest.js b/js/plugins/rest.js deleted file mode 100644 index 3974890..0000000 --- a/js/plugins/rest.js +++ /dev/null @@ -1,216 +0,0 @@ -const EasyCoder_Rest = { - - name: `EasyCoder_Rest`, - - Rest: { - - compile: (compiler) => { - const lino = compiler.getLino(); - const request = compiler.nextToken(); - switch (request) { - case `get`: - if (compiler.nextIsSymbol(true)) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - if (compiler.nextTokenIs(`from`)) { - const url = compiler.getNextValue(); - let fixup = compiler.getPc(); - compiler.addCommand({ - domain: `rest`, - keyword: `rest`, - lino, - request: `get`, - target: targetRecord.name, - url, - onError: null - }); - if (compiler.tokenIs(`or`)) { - compiler.next(); - compiler.getCommandAt(fixup).onError = compiler.getPc() + 1; - compiler.completeHandler(); - } - return true; - } - } - } - break; - case `post`: - let value = null; - if (compiler.nextTokenIs(`to`)) { - compiler.next(); - } else { - value = compiler.getValue(); - if (compiler.tokenIs(`to`)) { - compiler.next(); - } else { - break; - } - } - const url = compiler.getValue(); - if (!url) { - throw new Error(command.lino, `No URL present`); - } - let target = null; - if (compiler.tokenIs(`giving`)) { - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.isVHolder) { - target = targetRecord.name; - compiler.next(); - } else { - throw new Error(`'${targetRecord.name}' cannot hold a value`); - } - } - } - compiler.addCommand({ - domain: `rest`, - keyword: `rest`, - lino, - request: `post`, - value, - url, - target, - onError: compiler.getPc() + 2 - }); - onError = null; - if (compiler.tokenIs(`or`)) { - compiler.next(); - // onError = compiler.getPc() + 1; - compiler.completeHandler(); - } - return true; - } - return false; - }, - - createCORSRequest: (method, url) => { - var xhr = new XMLHttpRequest(); - if (`withCredentials` in xhr) { - - // Check if the XMLHttpRequest object has a "withCredentials" property. - // "withCredentials" only exists on XMLHTTPRequest2 objects. - xhr.open(method, url, true); - - } else if (typeof XDomainRequest != `undefined`) { - - // Otherwise, check if XDomainRequest. - // XDomainRequest only exists in IE, and is IE's way of making CORS requests. - xhr = new XDomainRequest(); - xhr.open(method, url); - - } else { - - // Otherwise, CORS is not supported by the browser. - xhr = null; - - } - return xhr; - }, - - run: (program) => { - const command = program[program.pc]; - const url = program.getValue(command.url); - const rest = EasyCoder_Plugins.rest(); - const path = url.startsWith(`http`) ? url - : url[0] === `/` ? url.substr(1) - : `${window.location.origin}${rest ? `/${rest}` : ``}/${url}`; - - const request = EasyCoder_Rest.Rest.createCORSRequest(command.request, path); - if (!request) { - program.runtimeError(command.lino, `CORS not supported`); - return; - } - request.script = program.script; - request.pc = program.pc; - - request.onload = function () { - let s = request.script; - let p = EasyCoder.scripts[s]; - let pc = request.pc; - let c = p[pc]; - if (200 <= request.status && request.status < 400) { - var content = request.responseText.trim(); - if (c.target) { - const targetRecord = program.getSymbolRecord(command.target); - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content - }; - targetRecord.used = true; - } - p.run(c.pc + 1); - } else { - const error = `${request.status} ${request.statusText}`; - if (c.onError) { - p.errorMessage = `Exception trapped: ${error}`; - p.run(c.onError); - } else { - p.runtimeError(c.lino, `Error: ${error}`); - } - } - }; - - request.onerror = function () { - if (command.onError) { - program.errorMessage = this.responseText; - program.run(command.onError); - } else { - const error = this.responseText; - program.runtimeError(command.lino, error); - } - }; - - switch (command.request) { - case `get`: - // console.log(`GET from ${path}`); - request.send(); - break; - case `post`: - const value = program.getValue(command.value); - console.log(`POST to ${path}`); - //console.log(`value=${value}`); - request.setRequestHeader(`Content-type`, `application/json; charset=UTF-8`); - request.send(value); - break; - } - return 0; - } - }, - - getHandler: (name) => { - switch (name) { - case `rest`: - return EasyCoder_Rest.Rest; - default: - return null; - } - }, - - run: (program) => { - const command = program[program.pc]; - const handler = EasyCoder_Rest.getHandler(command.keyword); - if (!handler) { - program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'rest' package`); - } - return handler.run(program); - }, - - value: { - - compile: () => { - return null; - }, - - get: () => { - return null; - } - }, - - condition: { - - compile: () => {}, - - test: () => {} - } -}; diff --git a/js/plugins/showdown.js b/js/plugins/showdown.js index 180e1b1..8573440 100644 --- a/js/plugins/showdown.js +++ b/js/plugins/showdown.js @@ -119,3 +119,6 @@ const EasyCoder_Showdown = { test: () => {} } }; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.showdown = EasyCoder_Showdown; diff --git a/js/plugins/svg.js b/js/plugins/svg.js index 09fbe57..8f15b92 100644 --- a/js/plugins/svg.js +++ b/js/plugins/svg.js @@ -616,3 +616,6 @@ const EasyCoder_SVG = { test: () => {} } }; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.svg = EasyCoder_SVG; diff --git a/js/plugins/ui.js b/js/plugins/ui.js index 17d8297..b0ac935 100644 --- a/js/plugins/ui.js +++ b/js/plugins/ui.js @@ -368,3 +368,6 @@ const EasyCoder_UI = { test: () => {} } }; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.ui = EasyCoder_UI; diff --git a/js/plugins/vfx.js b/js/plugins/vfx.js index f2ff5da..a358f76 100644 --- a/js/plugins/vfx.js +++ b/js/plugins/vfx.js @@ -341,3 +341,6 @@ const EasyCoder_VFX = { test: () => {} } }; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.vfx = EasyCoder_VFX; diff --git a/js/plugins/wof.js b/js/plugins/wof.js index 7904cb6..8c63fcd 100644 --- a/js/plugins/wof.js +++ b/js/plugins/wof.js @@ -280,3 +280,6 @@ const EasyCoder_roulette_wheel = { $.rotateWheel($); } }; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.wof = EasyCoder_WOF; From e5fc55ccf6b96c1ed8e0d6d73b825277696b9346 Mon Sep 17 00:00:00 2001 From: Graham Trott Date: Mon, 13 Apr 2020 13:21:54 +0100 Subject: [PATCH 3/6] Moving files --- easycoder/easycoder-min.js | 119 +- easycoder/easycoder.js | 46 - easycoder/easycoder.zip | Bin 271028 -> 232529 bytes easycoder/plugins/anagrams.js | 43 - easycoder/plugins/aws.js | 231 -- easycoder/plugins/browser.js | 3340 --------------------------- easycoder/plugins/ckeditor.js | 172 -- easycoder/plugins/codemirror-ecs.js | 63 - easycoder/plugins/codemirror.js | 170 -- easycoder/plugins/dummy.js | 66 - easycoder/plugins/gmap.js | 558 ----- easycoder/plugins/json.js | 510 ---- easycoder/plugins/rest.js | 216 -- easycoder/plugins/showdown.js | 121 - easycoder/plugins/svg.js | 618 ----- easycoder/plugins/ui.js | 370 --- easycoder/plugins/vfx.js | 343 --- easycoder/plugins/wof.js | 282 --- 18 files changed, 59 insertions(+), 7209 deletions(-) delete mode 100644 easycoder/plugins/anagrams.js delete mode 100644 easycoder/plugins/aws.js delete mode 100644 easycoder/plugins/browser.js delete mode 100644 easycoder/plugins/ckeditor.js delete mode 100644 easycoder/plugins/codemirror-ecs.js delete mode 100644 easycoder/plugins/codemirror.js delete mode 100644 easycoder/plugins/dummy.js delete mode 100644 easycoder/plugins/gmap.js delete mode 100644 easycoder/plugins/json.js delete mode 100644 easycoder/plugins/rest.js delete mode 100644 easycoder/plugins/showdown.js delete mode 100644 easycoder/plugins/svg.js delete mode 100644 easycoder/plugins/ui.js delete mode 100644 easycoder/plugins/vfx.js delete mode 100644 easycoder/plugins/wof.js diff --git a/easycoder/easycoder-min.js b/easycoder/easycoder-min.js index 806193a..1031c7d 100644 --- a/easycoder/easycoder-min.js +++ b/easycoder/easycoder-min.js @@ -33,62 +33,61 @@ alert(c.message)}return b.pc+1}},Go:{compile:function(a){var b=a.getLino();a.nex keyword:"gosub",lino:b,label:c});return!0},run:function(a){var b=a[a.pc];if(a.verifySymbol(b.label))return a.stack.push(a.pc+1),a.symbols[b.label].pc;a.runtimeError(b.lino,"Unknown symbol '"+b.label+"'");return 0}},If:{compile:function(a){var b=a.getLino();a.next();var c=a.condition.compile(a),d=a.getPc();a.addCommand({domain:"core",keyword:"if",lino:b,condition:c});a.compileOne();if(!a.getToken())return a.getCommandAt(d).else=a.getPc(),!0;a.tokenIs("else")?(c=a.getPc(),a.addCommand({domain:"core", keyword:"goto",lino:b,goto:0}),a.getCommandAt(d).else=a.getPc(),a.next(),a.compileOne(!0),a.getCommandAt(c).goto=a.getPc()):a.getCommandAt(d).else=a.getPc();return!0},run:function(a){var b=a[a.pc];return a.condition.test(a,b.condition)?b.pc+1:b.else}},Import:{compile:function(a){var b=a.imports,c=EasyCoder.scripts[b.caller],d=a.getProgram();if(b.length){b=$jscomp.makeIterator(b);for(var e=b.next();!e.done;e=b.next()){e=c.getSymbolRecord(e.value);var f=a.nextToken(),k=e.keyword;if(f===k){if(f=a.compileVariable(e.domain, k,!0),f=d[a.getSymbols()[f.name].pc],f.element=e.element,f.exporter=e.exporter?e.exporter:c.script,f.exportedName=e.name,f.extra=e.extra,f.isVHolder=e.isVHolder,e.program&&(f.program=e.program.script),f.imported=!0,!a.tokenIs("and"))break}else throw Error("Mismatched import variable type for '"+e.name+"'");}if(a.tokenIs("and"))throw Error("Imports do not match exports");}else a.next();return!0},run:function(a){return a[a.pc].pc+1}},Index:{compile:function(a){var b=a.getLino();if(a.nextIsSymbol(!0)){var c= -a.getToken();if(a.nextTokenIs("to")){var d=a.getNextValue();a.addCommand({domain:"core",keyword:"index",lino:b,symbol:c,value:d});return!0}}return!1},run:function(a){var b=a[a.pc],c=a.getSymbolRecord(b.symbol),d=a.getValue(b.value);d>=c.elements&&a.runtimeError(b.lino,"Array index "+d+" is out of range for '"+c.name+"'");c.index=d;c.imported&&(EasyCoder.symbols[c.exporter].getSymbolRecord(c.exportedName).index=d);return b.pc+1}},Load:{compile:function(a){var b=a.getLino();switch(a.nextToken()){case "plugin":var c= -a.getNextValue(),d=a.getValue(),e=a.getValue();a.addCommand({domain:"core",keyword:"load",lino:b,name:c,id:d,url:e});return!0}return!1},run:function(a){var b=a[a.pc];a.getValue(b.name);var c=a.getValue(b.id);a.getValue(b.url);switch(b.keyword){case "load":return"undefined"===typeof EasyCoder.domain.name?(a.require("js",a.getValue(b.url),function(){EasyCoder.domain.name=c;a.run(b.pc+1)}),0):b.pc+1}return!1}},Module:{compile:function(a){a.compileVariable("core","module");return!0},run:function(a){return a[a.pc].pc+ -1}},Multiply:{compile:function(a){var b=a.getLino();a.next();if(a.isSymbol()){var c=a.getSymbol();var d=a.getCommandAt(c.pc).name}c=a.getValue();a.tokenIs("by")&&a.next();var e=a.getValue();if(a.tokenIs("giving")){a.next();if(a.isSymbol())return d=a.getSymbol(),d=a.getCommandAt(d.pc).name,a.next(),a.addCommand({domain:"core",keyword:"multiply",lino:b,value1:c,value2:e,target:d}),!0;a.warning("core multiply: Expected value holder")}else return"undefined"===typeof d&&a.warning("core multiply: No target variable given"), -a.addCommand({domain:"core",keyword:"multiply",lino:b,value2:e,target:d}),!0;return!1},run:function(a){var b=a[a.pc],c=b.value1,d=b.value2,e=a.getSymbolRecord(b.target);if(e.isVHolder){var f=e.value[e.index];c?(a=a.getValue(c)*a.getValue(d),e.value[e.index]={type:"constant",numeric:!0,content:a}):(!f.numeric&&isNaN(f.content)&&a.nonNumericValueError(b,lino),a=parseInt(f.content)*parseInt(a.getValue(d)),e.value[e.index]={type:"constant",numeric:!0,content:a})}else a.variableDoesNotHoldAValueError(b.lino, -e.name);return b.pc+1}},Negate:{compile:function(a){var b=a.getLino();a.next();if(a.isSymbol()){var c=a.getToken();a.next();a.addCommand({domain:"core",keyword:"negate",lino:b,symbol:c});return!0}return!1},run:function(a){var b=a[a.pc],c=a.getSymbolRecord(b.symbol);c.isVHolder?c.value[c.index]={type:"constant",numeric:!0,content:-c.value[c.index].content}:a.variableDoesNotHoldAValueError(b.lino,c.name);return b.pc+1}},On:{compile:function(a){var b=a.getLino(),c=a.nextToken();switch(c){case "close":case "message":case "error":return a.next(), -a.addCommand({domain:"core",keyword:"on",lino:b,action:c}),a.completeHandler()}return a.isSymbol()&&(c=a.getSymbolRecord(),"callback"===c.keyword)?(a.next(),a.addCommand({domain:"core",keyword:"on",lino:b,action:c.name}),a.completeHandler()):!1},run:function(a){var b=a[a.pc],c=b.pc+2;switch(b.action){case "close":a.onClose=c;break;case "message":a.onMessage=c;break;case "error":a.onError=c;break;default:var d=a.getSymbolRecord(b.action);if(d)d.cb=c;else return a.runtimeError(b.lino,"Unknown action '"+ -b.action+"'"),0}return b.pc+1}},Print:{compile:function(a){var b=a.getLino();a.next();var c=a.getValue();a.addCommand({domain:"core",keyword:"print",lino:b,value:c});return!0},run:function(a){var b=a[a.pc];a=a.getFormattedValue(b.value);console.log("-> "+a);return b.pc+1}},Put:{compile:function(a){var b=a.getLino(),c=a.getNextValue();if(a.tokenIs("into")){if(a.nextIsSymbol()){var d=a.getToken();a.next();a.addCommand({domain:"core",keyword:"put",lino:b,value:c,target:d});return!0}a.warning("core:put: No such variable: '"+ -a.getToken()+"'")}return!1},run:function(a){var b=a[a.pc],c=a.getSymbolRecord(b.target);c.isVHolder||a.variableDoesNotHoldAValueError(b.lino,c.name);a=a.evaluate(b.value);c.value[c.index]={type:a.type,numeric:a.numeric,content:a.content};c.imported&&(c=EasyCoder.scripts[c.exporter].getSymbolRecord(c.exportedName),c.value[c.index]=a);return b.pc+1}},Replace:{compile:function(a){var b=a.getLino(),c=a.getNextValue();if(a.tokenIs("with")){var d=a.getNextValue();if(a.tokenIs("in")&&a.nextIsSymbol()){var e= -a.getSymbolRecord();if(e.isVHolder)return a.next(),a.addCommand({domain:"core",keyword:"replace",lino:b,original:c,replacement:d,target:e.name}),!0;throw Error("'"+e.name+"' does not hold a value");}}return!1},run:function(a){var b=a[a.pc],c=a.getValue(b.original),d=a.getValue(b.replacement),e=a.getSymbolRecord(b.target);a=a.getValue(e.value[e.index]).split(c).join(d);e.value[e.index]={type:"constant",numeric:!1,content:a};return b.pc+1}},Require:{compile:function(a){var b=a.getLino(),c=a.nextToken(); -if(["css","js"].includes(c)){var d=a.getNextValue();a.addCommand({domain:"core",keyword:"require",lino:b,type:c,url:d});return!0}throw Error("File type must be 'css' or 'js'");},run:function(a){var b=a[a.pc];a.require(b.type,a.getValue(b.url),function(){a.run(b.pc+1)});return 0}},Return:{compile:function(a){var b=a.getLino();a.next();a.addCommand({domain:"core",keyword:"return",lino:b});return!0},run:function(a){return a.stack.pop()}},Run:{compile:function(a){var b=a.getLino(),c=a.getNextValue(), -d=[];if(a.tokenIs("with"))for(;;)if(a.nextIsSymbol(!0)){var e=a.getSymbolRecord();d.push(e.name);a.next();if(!a.tokenIs("and"))break}if(a.tokenIs("as")&&a.nextIsSymbol(!0)){var f=a.getSymbolRecord();a.next();if("module"!==f.keyword)throw Error("'"+f.name+"' is not a module");f=f.name}var k=!1;a.tokenIs("nowait")&&(a.next(),k=!0);e=a.getPc();a.addCommand({domain:"core",keyword:"run",lino:b,script:c,imports:d,module:f,nowait:k,then:0});a.tokenIs("then")&&(b=a.getPc(),a.addCommand({domain:"core",keyword:"goto", -goto:0}),a.getCommandAt(e).then=a.getPc(),a.next(),a.compileOne(!0),a.addCommand({domain:"core",keyword:"stop"}),a.getCommandAt(b).goto=a.getPc());return!0},run:function(a){a.nextPc=a.pc+1;a.runScript(a);return 0}},Sanitize:{compile:function(a){var b=a.getLino();if(a.nextIsSymbol()){var c=a.getToken();a.next();a.addCommand({domain:"core",keyword:"sanitize",lino:b,name:c});return!0}return!1},run:function(a){var b=a[a.pc];a=a.getSymbolRecord(b.name);a=a.value[a.index];a.content=JSON.stringify(JSON.parse(a.content)); -return b.pc+1}},Script:{compile:function(a){var b=a.getProgram();b.script=a.nextToken();a.script=b.script;if(EasyCoder.scripts[b.script])throw delete a.script,Error("Script '"+b.script+"' is already running.");EasyCoder.scripts[b.script]=b;a.next();return!0},run:function(a){return a[a.pc].pc+1}},Send:{compile:function(a){var b=a.getLino(),c="";a.nextTokenIs("to")||(c=a.getValue());if(a.tokenIs("to")){if(a.nextTokenIs("parent"))var d="parent";else if(a.isSymbol){d=a.getSymbolRecord();if("module"!== -d.keyword)throw Error("'"+d.name+"' is not a module");d=d.name}a.next();a.addCommand({domain:"core",keyword:"send",lino:b,message:c,recipient:d})}return!0},run:function(a){var b=a[a.pc],c=a.getValue(b.message);"parent"===b.recipient?a.parent&&(a=EasyCoder.scripts[a.parent],a.onMessage&&(a.message=c,a.run(a.onMessage))):(a=a.getSymbolRecord(b.recipient),a.program&&(a=EasyCoder.scripts[a.program],a.message=c,a.run(a.onMessage)));return b.pc+1}},Set:{compile:function(a){var b=a.getLino();if(a.nextIsSymbol()){var c= -a.getSymbolRecord();if(!c.isVHolder)return!1;if(a.nextTokenIs("to")){var d=a.nextToken();if(["array","object"].includes(d))return a.next(),a.addCommand({domain:"core",keyword:"set",lino:b,request:"setVarTo",target:c.name,type:d}),!0;for(d=[];;){a.mark();try{d.push(a.getValue())}catch(f){a.rewind();break}}a.addCommand({domain:"core",keyword:"set",lino:b,request:"setArray",target:c.name,value:d});return!0}a.addCommand({domain:"core",keyword:"set",lino:b,request:"setBoolean",target:c.name});return!0}switch(a.getToken()){case "ready":return a.next(), -a.addCommand({domain:"core",keyword:"set",lino:b,request:"setReady"}),!0;case "element":c=a.getNextValue();if(a.tokenIs("of")&&a.nextIsSymbol()&&(d=a.getSymbolRecord(),"variable"===d.keyword&&a.nextTokenIs("to"))){var e=a.getNextValue();a.addCommand({domain:"core",keyword:"set",lino:b,request:"setElement",target:d.name,index:c,value:e});return!0}break;case "property":c=a.getNextValue();if(a.tokenIs("of")&&a.nextIsSymbol()&&(d=a.getSymbolRecord(),"variable"===d.keyword&&a.nextTokenIs("to")))return e= -a.getNextValue(),a.addCommand({domain:"core",keyword:"set",lino:b,request:"setProperty",target:d.name,name:c,value:e}),!0;break;case "arg":if(c=a.getNextValue(),a.tokenIs("of")&&a.nextIsSymbol()&&(d=a.getSymbolRecord(),a.nextTokenIs("to")))return e=a.getNextValue(),a.addCommand({domain:"core",keyword:"set",lino:b,request:"setArg",target:d.name,name:c,value:e}),!0}a.tokenIs("the")&&a.next();switch(a.getToken()){case "elements":a.next();if(a.tokenIs("of")){a.next();if(!a.isSymbol())throw Error("Unknown variable '"+ -a.getToken()+"'");c=a.getToken();a.next();if(a.tokenIs("to"))return a.next(),d=a.getValue(),a.addCommand({domain:"core",keyword:"set",lino:b,request:"setElements",symbol:c,value:d}),!0}break;case "encoding":if(a.nextTokenIs("to"))return c=a.getNextValue(),a.addCommand({domain:"core",keyword:"set",request:"encoding",lino:b,encoding:c}),!0;a.addWarning("Unknown encoding option");break;case "payload":if(a.nextTokenIs("of")&&a.nextIsSymbol()&&(c=a.getSymbolRecord(),"callback"===c.keyword&&a.nextTokenIs("to")))return d= -a.getNextValue(),a.addCommand({domain:"core",keyword:"set",request:"setPayload",lino:b,callback:c.name,payload:d}),!0}return!1},run:function(a){var b=a[a.pc];switch(b.request){case "setBoolean":var c=a.getSymbolRecord(b.target);c.isVHolder?(c.value[c.index]={type:"boolean",content:!0},b.numeric=!1):a.variableDoesNotHoldAValueError(b.lino,c.name);break;case "setReady":if(c=EasyCoder.scripts[a.parent])c.run(c.nextPc),c.nextPc=0,a.unblocked=!0;break;case "setArray":c=a.getSymbolRecord(b.target);c.elements= -b.value.length;c.value=b.value;break;case "encoding":a.encoding=a.getValue(b.encoding);break;case "setElements":c=a.getSymbolRecord(b.symbol);var d=c.elements;c.elements=a.getValue(b.value);c.index=0;if(c.elements>d)for(a=d;a"};case "uuid":return{type:"constant",numeric:!1,content:"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=16*Math.random()|0;return("x"==a?b:b&3|8).toString(16)})}; -case "encode":return{type:"constant",numeric:!1,content:a.encode(a.getValue(b.value))};case "decode":return{type:"constant",numeric:!1,content:a.decode(a.getValue(b.value))};case "reverse":return{type:"constant",numeric:!1,content:a.getValue(b.value).split("").reverse().join("")};case "lowercase":return{type:"constant",numeric:!1,content:a.getValue(b.value).toLowerCase()};case "hash":a=a.getValue(b.value);b=0;if(0===a.length)return b;for(c=0;c=c:0c;case "not":return!a.getValue(b.value); -case "moduleRunning":return c=a.getSymbolRecord(b.name),EasyCoder.scripts.hasOwnProperty(c.program)?(c=EasyCoder.scripts[c.program],b.sense?c.running:!c.running):!b.sense;case "includes":return c=JSON.parse(a.getValue(b.value1)),b=a.getValue(b.value2),c.includes(b)}return!1}}},EasyCoder_Browser={name:"EasyCoder_Browser",A:{compile:function(a){a.compileVariable("browser","a",!1,"dom");return!0},run:function(a){return a[a.pc].pc+1}},Alert:{compile:function(a){var b=a.getLino(),c=a.getNextValue();a.addCommand({domain:"browser", -keyword:"alert",lino:b,value:c});return!0},run:function(a){var b=a[a.pc];a=a.getFormattedValue(b.value);alert(a);return b.pc+1}},Attach:{compile:function(a){var b=a.getLino();a.next();if(a.isSymbol()){var c=a.getSymbolRecord(),d=c.keyword;switch(d){case "a":case "blockquote":case "button":case "canvas":case "div":case "fieldset":case "file":case "form":case "h1":case "h2":case "h3":case "h4":case "h5":case "h6":case "image":case "img":case "input":case "label":case "legend":case "li":case "option":case "p":case "pre":case "select":case "span":case "table":case "td":case "text":case "textarea":case "tr":case "ul":a.next(); +a.getToken();if(a.nextTokenIs("to")){var d=a.getNextValue();a.addCommand({domain:"core",keyword:"index",lino:b,symbol:c,value:d});return!0}}return!1},run:function(a){var b=a[a.pc],c=a.getSymbolRecord(b.symbol),d=a.getValue(b.value);d>=c.elements&&a.runtimeError(b.lino,"Array index "+d+" is out of range for '"+c.name+"'");c.index=d;c.imported&&(EasyCoder.symbols[c.exporter].getSymbolRecord(c.exportedName).index=d);return b.pc+1}},Module:{compile:function(a){a.compileVariable("core","module");return!0}, +run:function(a){return a[a.pc].pc+1}},Multiply:{compile:function(a){var b=a.getLino();a.next();if(a.isSymbol()){var c=a.getSymbol();var d=a.getCommandAt(c.pc).name}c=a.getValue();a.tokenIs("by")&&a.next();var e=a.getValue();if(a.tokenIs("giving")){a.next();if(a.isSymbol())return d=a.getSymbol(),d=a.getCommandAt(d.pc).name,a.next(),a.addCommand({domain:"core",keyword:"multiply",lino:b,value1:c,value2:e,target:d}),!0;a.warning("core multiply: Expected value holder")}else return"undefined"===typeof d&& +a.warning("core multiply: No target variable given"),a.addCommand({domain:"core",keyword:"multiply",lino:b,value2:e,target:d}),!0;return!1},run:function(a){var b=a[a.pc],c=b.value1,d=b.value2,e=a.getSymbolRecord(b.target);if(e.isVHolder){var f=e.value[e.index];c?(a=a.getValue(c)*a.getValue(d),e.value[e.index]={type:"constant",numeric:!0,content:a}):(!f.numeric&&isNaN(f.content)&&a.nonNumericValueError(b,lino),a=parseInt(f.content)*parseInt(a.getValue(d)),e.value[e.index]={type:"constant",numeric:!0, +content:a})}else a.variableDoesNotHoldAValueError(b.lino,e.name);return b.pc+1}},Negate:{compile:function(a){var b=a.getLino();a.next();if(a.isSymbol()){var c=a.getToken();a.next();a.addCommand({domain:"core",keyword:"negate",lino:b,symbol:c});return!0}return!1},run:function(a){var b=a[a.pc],c=a.getSymbolRecord(b.symbol);c.isVHolder?c.value[c.index]={type:"constant",numeric:!0,content:-c.value[c.index].content}:a.variableDoesNotHoldAValueError(b.lino,c.name);return b.pc+1}},On:{compile:function(a){var b= +a.getLino(),c=a.nextToken();switch(c){case "close":case "message":case "error":return a.next(),a.addCommand({domain:"core",keyword:"on",lino:b,action:c}),a.completeHandler()}return a.isSymbol()&&(c=a.getSymbolRecord(),"callback"===c.keyword)?(a.next(),a.addCommand({domain:"core",keyword:"on",lino:b,action:c.name}),a.completeHandler()):!1},run:function(a){var b=a[a.pc],c=b.pc+2;switch(b.action){case "close":a.onClose=c;break;case "message":a.onMessage=c;break;case "error":a.onError=c;break;default:var d= +a.getSymbolRecord(b.action);if(d)d.cb=c;else return a.runtimeError(b.lino,"Unknown action '"+b.action+"'"),0}return b.pc+1}},Print:{compile:function(a){var b=a.getLino();a.next();var c=a.getValue();a.addCommand({domain:"core",keyword:"print",lino:b,value:c});return!0},run:function(a){var b=a[a.pc];a=a.getFormattedValue(b.value);console.log("-> "+a);return b.pc+1}},Put:{compile:function(a){var b=a.getLino(),c=a.getNextValue();if(a.tokenIs("into")){if(a.nextIsSymbol()){var d=a.getToken();a.next();a.addCommand({domain:"core", +keyword:"put",lino:b,value:c,target:d});return!0}a.warning("core:put: No such variable: '"+a.getToken()+"'")}return!1},run:function(a){var b=a[a.pc],c=a.getSymbolRecord(b.target);c.isVHolder||a.variableDoesNotHoldAValueError(b.lino,c.name);a=a.evaluate(b.value);c.value[c.index]={type:a.type,numeric:a.numeric,content:a.content};c.imported&&(c=EasyCoder.scripts[c.exporter].getSymbolRecord(c.exportedName),c.value[c.index]=a);return b.pc+1}},Replace:{compile:function(a){var b=a.getLino(),c=a.getNextValue(); +if(a.tokenIs("with")){var d=a.getNextValue();if(a.tokenIs("in")&&a.nextIsSymbol()){var e=a.getSymbolRecord();if(e.isVHolder)return a.next(),a.addCommand({domain:"core",keyword:"replace",lino:b,original:c,replacement:d,target:e.name}),!0;throw Error("'"+e.name+"' does not hold a value");}}return!1},run:function(a){var b=a[a.pc],c=a.getValue(b.original),d=a.getValue(b.replacement),e=a.getSymbolRecord(b.target);a=a.getValue(e.value[e.index]).split(c).join(d);e.value[e.index]={type:"constant",numeric:!1, +content:a};return b.pc+1}},Require:{compile:function(a){var b=a.getLino(),c=a.nextToken();if(["css","js"].includes(c)){var d=a.getNextValue();a.addCommand({domain:"core",keyword:"require",lino:b,type:c,url:d});return!0}throw Error("File type must be 'css' or 'js'");},run:function(a){var b=a[a.pc];a.require(b.type,a.getValue(b.url),function(){a.run(b.pc+1)});return 0}},Return:{compile:function(a){var b=a.getLino();a.next();a.addCommand({domain:"core",keyword:"return",lino:b});return!0},run:function(a){return a.stack.pop()}}, +Run:{compile:function(a){var b=a.getLino(),c=a.getNextValue(),d=[];if(a.tokenIs("with"))for(;;)if(a.nextIsSymbol(!0)){var e=a.getSymbolRecord();d.push(e.name);a.next();if(!a.tokenIs("and"))break}if(a.tokenIs("as")&&a.nextIsSymbol(!0)){var f=a.getSymbolRecord();a.next();if("module"!==f.keyword)throw Error("'"+f.name+"' is not a module");f=f.name}var k=!1;a.tokenIs("nowait")&&(a.next(),k=!0);e=a.getPc();a.addCommand({domain:"core",keyword:"run",lino:b,script:c,imports:d,module:f,nowait:k,then:0});a.tokenIs("then")&& +(b=a.getPc(),a.addCommand({domain:"core",keyword:"goto",goto:0}),a.getCommandAt(e).then=a.getPc(),a.next(),a.compileOne(!0),a.addCommand({domain:"core",keyword:"stop"}),a.getCommandAt(b).goto=a.getPc());return!0},run:function(a){a.nextPc=a.pc+1;a.runScript(a);return 0}},Sanitize:{compile:function(a){var b=a.getLino();if(a.nextIsSymbol()){var c=a.getToken();a.next();a.addCommand({domain:"core",keyword:"sanitize",lino:b,name:c});return!0}return!1},run:function(a){var b=a[a.pc];a=a.getSymbolRecord(b.name); +a=a.value[a.index];a.content=JSON.stringify(JSON.parse(a.content));return b.pc+1}},Script:{compile:function(a){var b=a.getProgram();b.script=a.nextToken();a.script=b.script;if(EasyCoder.scripts[b.script])throw delete a.script,Error("Script '"+b.script+"' is already running.");EasyCoder.scripts[b.script]=b;a.next();return!0},run:function(a){return a[a.pc].pc+1}},Send:{compile:function(a){var b=a.getLino(),c="";a.nextTokenIs("to")||(c=a.getValue());if(a.tokenIs("to")){if(a.nextTokenIs("parent"))var d= +"parent";else if(a.isSymbol){d=a.getSymbolRecord();if("module"!==d.keyword)throw Error("'"+d.name+"' is not a module");d=d.name}a.next();a.addCommand({domain:"core",keyword:"send",lino:b,message:c,recipient:d})}return!0},run:function(a){var b=a[a.pc],c=a.getValue(b.message);"parent"===b.recipient?a.parent&&(a=EasyCoder.scripts[a.parent],a.onMessage&&(a.message=c,a.run(a.onMessage))):(a=a.getSymbolRecord(b.recipient),a.program&&(a=EasyCoder.scripts[a.program],a.message=c,a.run(a.onMessage)));return b.pc+ +1}},Set:{compile:function(a){var b=a.getLino();if(a.nextIsSymbol()){var c=a.getSymbolRecord();if(!c.isVHolder)return!1;if(a.nextTokenIs("to")){var d=a.nextToken();if(["array","object"].includes(d))return a.next(),a.addCommand({domain:"core",keyword:"set",lino:b,request:"setVarTo",target:c.name,type:d}),!0;for(d=[];;){a.mark();try{d.push(a.getValue())}catch(f){a.rewind();break}}a.addCommand({domain:"core",keyword:"set",lino:b,request:"setArray",target:c.name,value:d});return!0}a.addCommand({domain:"core", +keyword:"set",lino:b,request:"setBoolean",target:c.name});return!0}switch(a.getToken()){case "ready":return a.next(),a.addCommand({domain:"core",keyword:"set",lino:b,request:"setReady"}),!0;case "element":c=a.getNextValue();if(a.tokenIs("of")&&a.nextIsSymbol()&&(d=a.getSymbolRecord(),"variable"===d.keyword&&a.nextTokenIs("to"))){var e=a.getNextValue();a.addCommand({domain:"core",keyword:"set",lino:b,request:"setElement",target:d.name,index:c,value:e});return!0}break;case "property":c=a.getNextValue(); +if(a.tokenIs("of")&&a.nextIsSymbol()&&(d=a.getSymbolRecord(),"variable"===d.keyword&&a.nextTokenIs("to")))return e=a.getNextValue(),a.addCommand({domain:"core",keyword:"set",lino:b,request:"setProperty",target:d.name,name:c,value:e}),!0;break;case "arg":if(c=a.getNextValue(),a.tokenIs("of")&&a.nextIsSymbol()&&(d=a.getSymbolRecord(),a.nextTokenIs("to")))return e=a.getNextValue(),a.addCommand({domain:"core",keyword:"set",lino:b,request:"setArg",target:d.name,name:c,value:e}),!0}a.tokenIs("the")&&a.next(); +switch(a.getToken()){case "elements":a.next();if(a.tokenIs("of")){a.next();if(!a.isSymbol())throw Error("Unknown variable '"+a.getToken()+"'");c=a.getToken();a.next();if(a.tokenIs("to"))return a.next(),d=a.getValue(),a.addCommand({domain:"core",keyword:"set",lino:b,request:"setElements",symbol:c,value:d}),!0}break;case "encoding":if(a.nextTokenIs("to"))return c=a.getNextValue(),a.addCommand({domain:"core",keyword:"set",request:"encoding",lino:b,encoding:c}),!0;a.addWarning("Unknown encoding option"); +break;case "payload":if(a.nextTokenIs("of")&&a.nextIsSymbol()&&(c=a.getSymbolRecord(),"callback"===c.keyword&&a.nextTokenIs("to")))return d=a.getNextValue(),a.addCommand({domain:"core",keyword:"set",request:"setPayload",lino:b,callback:c.name,payload:d}),!0}return!1},run:function(a){var b=a[a.pc];switch(b.request){case "setBoolean":var c=a.getSymbolRecord(b.target);c.isVHolder?(c.value[c.index]={type:"boolean",content:!0},b.numeric=!1):a.variableDoesNotHoldAValueError(b.lino,c.name);break;case "setReady":if(c= +EasyCoder.scripts[a.parent])c.run(c.nextPc),c.nextPc=0,a.unblocked=!0;break;case "setArray":c=a.getSymbolRecord(b.target);c.elements=b.value.length;c.value=b.value;break;case "encoding":a.encoding=a.getValue(b.encoding);break;case "setElements":c=a.getSymbolRecord(b.symbol);var d=c.elements;c.elements=a.getValue(b.value);c.index=0;if(c.elements>d)for(a=d;a"};case "uuid":return{type:"constant",numeric:!1,content:"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, +function(a){var b=16*Math.random()|0;return("x"==a?b:b&3|8).toString(16)})};case "encode":return{type:"constant",numeric:!1,content:a.encode(a.getValue(b.value))};case "decode":return{type:"constant",numeric:!1,content:a.decode(a.getValue(b.value))};case "reverse":return{type:"constant",numeric:!1,content:a.getValue(b.value).split("").reverse().join("")};case "lowercase":return{type:"constant",numeric:!1,content:a.getValue(b.value).toLowerCase()};case "hash":a=a.getValue(b.value);b=0;if(0===a.length)return b; +for(c=0;c=c:0c;case "not":return!a.getValue(b.value);case "moduleRunning":return c=a.getSymbolRecord(b.name),EasyCoder.scripts.hasOwnProperty(c.program)?(c=EasyCoder.scripts[c.program],b.sense?c.running:!c.running):!b.sense;case "includes":return c=JSON.parse(a.getValue(b.value1)),b=a.getValue(b.value2),c.includes(b)}return!1}}},EasyCoder_Browser={name:"EasyCoder_Browser",A:{compile:function(a){a.compileVariable("browser", +"a",!1,"dom");return!0},run:function(a){return a[a.pc].pc+1}},Alert:{compile:function(a){var b=a.getLino(),c=a.getNextValue();a.addCommand({domain:"browser",keyword:"alert",lino:b,value:c});return!0},run:function(a){var b=a[a.pc];a=a.getFormattedValue(b.value);alert(a);return b.pc+1}},Attach:{compile:function(a){var b=a.getLino();a.next();if(a.isSymbol()){var c=a.getSymbolRecord(),d=c.keyword;switch(d){case "a":case "blockquote":case "button":case "canvas":case "div":case "fieldset":case "file":case "form":case "h1":case "h2":case "h3":case "h4":case "h5":case "h6":case "image":case "img":case "input":case "label":case "legend":case "li":case "option":case "p":case "pre":case "select":case "span":case "table":case "td":case "text":case "textarea":case "tr":case "ul":a.next(); if(a.tokenIs("to")){if(a.nextTokenIs("body"))if("div"===d)cssId="body",a.next();else throw Error("Body variable must be a div");else cssId=a.getValue();var e=0;a.tokenIs("or")&&(a.next(),e=a.getPc()+1,a.completeHandler());a.addCommand({domain:"browser",keyword:"attach",lino:b,type:d,symbol:c.name,cssId:cssId,onError:e});return!0}break;default:return a.addWarning("type '"+c.keyword+"' not recognized in browser 'attach'"),!1}}a.addWarning("Unrecognised syntax in 'attach'");return!1},run:function(a){var b= a[a.pc],c=null,d=null;"body"===b.cssId?d=document.body:(c=a.value.evaluate(a,b.cssId).content,d=document.getElementById(c));if(!d)return b.onError?a.run(b.onError):a.runtimeError(b.lino,"No such element: '"+c+"'"),0;var e=a.getSymbolRecord(b.symbol);e.element[e.index]=d;e.value[e.index]={type:"constant",numeric:!1,content:c};"popup"===b.type&&(a.popups.push(d.id),window.onclick=function(b){a.popups.includes(b.target.id)&&(b.target.style.display="none")});return b.pc+1}},Audioclip:{compile:function(a){a.compileVariable("browser", "audioclip");return!0},run:function(a){return a[a.pc].pc+1}},BLOCKQUOTE:{compile:function(a){a.compileVariable("browser","blockquote",!1,"dom");return!0},run:function(a){return a[a.pc].pc+1}},BUTTON:{compile:function(a){a.compileVariable("browser","button",!1,"dom");return!0},run:function(a){return a[a.pc].pc+1}},CANVAS:{compile:function(a){a.compileVariable("browser","canvas",!1,"dom");return!0},run:function(a){return a[a.pc].pc+1}},Clear:{compile:function(a){var b=a.getLino();if(a.nextTokenIs("body"))return a.next(), @@ -121,7 +120,7 @@ switch(b.direction){case "left":a.onSwipeLeft=b.pc+2;break;case "right":a.onSwip d){document.pickIndex=d;c.pickIndex=d;c.mouseDownPc=b.pc+2;"ontouchstart"in c?(c.addEventListener("touchstart",function(b){var c=b.targetTouches[0].target;document.pickX=b.touches[0].clientX;document.pickY=b.touches[0].clientY;c.blur();setTimeout(function(){document.pickRecord.index=c.pickIndex;a.run(c.mouseDownPc)},1)},!1),c.addEventListener("touchmove",function(b){document.dragX=b.touches[0].clientX;document.dragY=b.touches[0].clientY;setTimeout(function(){a.run(document.mouseMovePc)},1);return!1}, !1),c.addEventListener("touchend",function(){setTimeout(function(){a.run(document.mouseUpPc)},1);return!1})):c.onmousedown=function(b){b=b?b:window.event;b.stopPropagation();if(0')}l+="
    "}g.innerHTML=h+" "+l;g.style.display="block";b.$jscomp$loop$prop$run$144=document.getElementById("easycoder-run-button");b.$jscomp$loop$prop$step$145=document.getElementById("easycoder-step-button"); -b.$jscomp$loop$prop$run$144.onclick=function(b){return function(){b.$jscomp$loop$prop$run$144.blur();a.tracing=!1;document.getElementById("easycoder-tracer-content").style.display="none";try{EasyCoder_Run.run(a,a.resume)}catch(q){var c="Error in run handler: "+q.message;console.log(c);alert(c)}}}(b);b.$jscomp$loop$prop$step$145.onclick=function(b){return function(){console.log("step");b.$jscomp$loop$prop$step$145.blur();a.tracing=!0;document.getElementById("easycoder-tracer-content").style.display= -"block";try{a.run(a.resume)}catch(q){var c="Error in step handler: "+q.message;console.log(c);alert(c)}}}(b)}a.resume=a.pc;a.pc=0}break}b={$jscomp$loop$prop$run$144:b.$jscomp$loop$prop$run$144,$jscomp$loop$prop$step$145:b.$jscomp$loop$prop$step$145}}},exit:function(a){a.onExit&&a.run(a.onExit);var b=a.parent,c=a.afterExit;delete EasyCoder.scripts[a.script];a.module&&delete a.module.program;Object.keys(a).forEach(function(b){delete a[b]});b&&c&&EasyCoder.scripts[b].run(c)}},EasyCoder_Compiler={name:"EasyCoder_Compiler", +h+(b+": undefined");switch(a.tracer.alignment){case "horizontal":c')}l+="
    "}g.innerHTML=h+" "+l;g.style.display="block";b.$jscomp$loop$prop$run$143=document.getElementById("easycoder-run-button");b.$jscomp$loop$prop$step$144=document.getElementById("easycoder-step-button"); +b.$jscomp$loop$prop$run$143.onclick=function(b){return function(){b.$jscomp$loop$prop$run$143.blur();a.tracing=!1;document.getElementById("easycoder-tracer-content").style.display="none";try{EasyCoder_Run.run(a,a.resume)}catch(q){var c="Error in run handler: "+q.message;console.log(c);alert(c)}}}(b);b.$jscomp$loop$prop$step$144.onclick=function(b){return function(){console.log("step");b.$jscomp$loop$prop$step$144.blur();a.tracing=!0;document.getElementById("easycoder-tracer-content").style.display= +"block";try{a.run(a.resume)}catch(q){var c="Error in step handler: "+q.message;console.log(c);alert(c)}}}(b)}a.resume=a.pc;a.pc=0}break}b={$jscomp$loop$prop$run$143:b.$jscomp$loop$prop$run$143,$jscomp$loop$prop$step$144:b.$jscomp$loop$prop$step$144}}},exit:function(a){a.onExit&&a.run(a.onExit);var b=a.parent,c=a.afterExit;delete EasyCoder.scripts[a.script];a.module&&delete a.module.program;Object.keys(a).forEach(function(b){delete a[b]});b&&c&&EasyCoder.scripts[b].run(c)}},EasyCoder_Compiler={name:"EasyCoder_Compiler", getTokens:function(){return this.tokens},addWarning:function(a){this.warnings.push(a)},warning:function(a){this.addWarning(a)},unrecognisedSymbol:function(a){this.addWarning("Unrecognised symbol '"+a+"'")},getWarnings:function(){return this.warnings},getIndex:function(){return this.index},next:function(a){this.index+=void 0===a?1:a},peek:function(){return this.tokens[this.index+1].token},more:function(){return this.index=this.tokens.length? null:this.tokens[this.index]?this.tokens[this.index].token:null},nextToken:function(){this.next();return this.getToken()},tokenIs:function(a){return this.index>=this.tokens.length?!1:a===this.tokens[this.index].token},nextTokenIs:function(a){this.next();return this.tokenIs(a)},skip:function(a){if(this.index>=this.tokens.length)return null;this.next();this.tokenIs(a)&&this.next()},prev:function(){this.index--},getLino:function(){return this.index>=this.tokens.length?0:this.tokens[this.index].lino}, getTarget:function(a){a=void 0===a?this.index:a;return this.tokens[a].token},getTargetPc:function(a){a=void 0===a?this.index:a;return this.symbols[this.getTarget(a)].pc},getCommandAt:function(a){return this.program[a]},isSymbol:function(a){a=void 0===a?!1:a;if(this.getTarget()in this.symbols)return!0;if(a)throw Error("Unknown symbol: '"+this.getTarget()+"'");return!1},nextIsSymbol:function(a){a=void 0===a?!1:a;this.next();return this.isSymbol(a)},getSymbol:function(a){if(this.isSymbol(void 0===a? diff --git a/easycoder/easycoder.js b/easycoder/easycoder.js index 372bfdc..f3b904c 100644 --- a/easycoder/easycoder.js +++ b/easycoder/easycoder.js @@ -870,50 +870,6 @@ const EasyCoder_Core = { } }, - Load: { - - compile: compiler => { - const lino = compiler.getLino(); - const type = compiler.nextToken(); - switch (type) { - case `plugin`: - const name = compiler.getNextValue(); - const id = compiler.getValue(); - const url = compiler.getValue(); - compiler.addCommand({ - domain: `core`, - keyword: `load`, - lino, - name, - id, - url - }); - return true; - } - return false; - }, - - run: program => { - const command = program[program.pc]; - const name = program.getValue(command.name); - const id = program.getValue(command.id); - const url = program.getValue(command.url); - switch (command.keyword) { - case `load`: - if (typeof EasyCoder.domain.name === `undefined`) { - program.require(`js`, program.getValue(command.url), - function () { - EasyCoder.domain.name = id; - program.run(command.pc + 1); - }); - return 0; - } - return command.pc + 1; - } - return false; - } - }, - Module: { compile: compiler => { @@ -2188,8 +2144,6 @@ const EasyCoder_Core = { return EasyCoder_Core.Import; case `index`: return EasyCoder_Core.Index; - case `load`: - return EasyCoder_Core.Load; case `module`: return EasyCoder_Core.Module; case `multiply`: diff --git a/easycoder/easycoder.zip b/easycoder/easycoder.zip index 104ee23cda10a299edba29fac810b5e3898d7209..9e75f1fb8cb3d5a65309325ef35d4a3a499ac2e1 100644 GIT binary patch delta 133001 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� z)!}%ix5j2Q@RzheT9Dyat?gEv)jP6@RJFJ9hYB`#`0?r;t!z??;nFG|EAyWQFEw?z zL~FY~)RK_5B~)EXiZ(($rN*#wDYn4dmu3_LR)4(I8h z`Bl{L>^|Ry~B`#`f5@q_%1e;4$WOR`_@J z{xbo5u~sKwj+}xBgh4(fs)S5JY*_ZFiX6&1NNAjT_@k$8^g}|AnvkP}mbAspY^-)c z41bS`DKMSWZ1^5YBuy}`wSrTP)6a^L%KWfrZu({Sg-rXdE6RtEU=Z9k=Ybk9+0=PA zJkE^rnqKb)rcAU*XkyY^TS5p*fKmihm*rOAx_@7una;^fISV&~s4q{a<=KxJGwQ+d z{7P*Kl@YbYw8xOhcum*_=TjC`GsX(GTz``F!nBNALs)yFm~-VXb!7$fGLL2r)qV?4 z!By8hKcIsv*P>OCvtJhIsZ@rLwKTl#>I#Ok89A$as6c&94L}E1=A$hP)s1f_iX}|~ zy~B44iptrCytbn9o+I(dliG-PMsybcQP!|#RO~e&p*k*Mbg~;LcWorQ>+WHrEF1NX z?T1lkgPA~YH~H^7lL1behNQcKwmALqkC$%50~eQT76T^%2bYr;1Emg=#G{)=!cLdX zQKw<#N0(s513s687Xu@IvD>f~QEXeWM85`)1>bJ&qA8u zwY}uYhY3EIXM51Z$!6HqxV;e7((^3Ym2Ik|Dw8!y?rV~!#gLgT-NfC=H_S}*PHK%k z)_p~z9W<K#>Pfw>P ziY|Ul7sGSrahX*w%Noe-VFV`|n&2=? z<-WTihb*Nj6>A@k^R&7#Ij~dmnG`^1Vyi)>+AbePnDI>opJ#6|oO|y$G}k>E0C$nY z0l&2e!t8uLbV>*Xe?7*IAit)UUB?4h8ZADy3n*kavwsoOP12p+z!-t*Q{TYTX?oe0 z&&LBFfAhobci`4eUR#_)2)uLJfx0P1(AA+Y|90b+rTRIG_0U(elNvHf`P+^(sPLr5 zQmmIImCh}6c621&sWsW^j-z`ym?^wV`Z^eBFZl`62ZJjJPDEnai7OF)n)H2kl6%j9 z1H8lEO{UBs7R0wbvKYM4>d_CHo)^9f2HH`Q969z9dgIZp{F)EWVV)F4Q>`- zNOOI+lG~hYwgZ=Ku)A?hJIsxnm~ogFTUIPni|caAi0%1FxNPLrp07i%X#xRrxyQV( z){>DB@9}y9Y$V!fIq-$}<#TI;=XoR{yNWR#IBNA)&4|f+Wkp-NRV37zHkEE@l4yzR ze~MUHrAwoMcDxuBQ@pO8rRFfNp7m&4R$jW!g?4KPDM)s6R*q)lY_8o&oAlWgvHUV< z(XFnx{{)7D`%jL&$0kH`ST=9To83YVlG`?ttWHH^cxmK6-egl%oyuV+@-b$=ERdww z5z|0^$^-Gb=d$r*G)Q(&H#Okn>}Ym!e>3!MbBRd2wA=`(q==9>QJl?_VK6PCJzrc^ zLP>{Bn#=X*egv2b(!KI+p6Ar@#}5u48J!FcWA7yf#f-taKs1I-Q3`y^BHh>o^zhf6 zfE$-aIWzf$*=V%7;c1$9Kqd~;LKCjD$(=11jNJ_Sjj~*wb8sg?*QjILwr$(CZQK6E zHaE77O|o$|wry@~^XC1k-h02gQ#Dm{rmIiQpWV~vJdbPVMpDvW#gD4uoYgj108d9+ z5hL#9z^z2(Q?f51{?Qb(gLVe)rPZl?GW~DFIIDB7rHXq=4FdC< zvcB3T!fY#}ye4ZSpFLx6K0h=>SRs60IS)}EoSgag~9b_u#C zUV+f!j`ub;TQMWM67D1Rx^=xF05EsS<2HDo%L0@~iXx$DUBU*s(#BF(DJ$VGv%q&G z_-lt3g?}4Tny9utaV^KBGX)sEhbmAfF0dZmT>0%dZ?{-+be;n=o57mq3HSGY(z;+E z0f{Y!_#SXw&M4~=K2ZVu!>1+ooX(b|1&{;9fe9%4!$slkuF|%&p*6s#0AXLd60jWG zS5JI>4p{=6oVN0LL@}0`E}8jTaUX5#^C(cs6xT>UJ`dpO984FM;UlrhHllWg_=(&0 zu8RHHP6Tq{C-Fq-WhZY0YgoEF`HFkeO?u((aNk;|a`dximfl+Vx9ZWt6`hS}P~J_goPuImX_UGQ04B72@f<#!;sVTp!Clj$K2{rxu!MGh!o6*dw;lc{3sVto!eGw9l<*(;11TcFP%!Y|EJ| zd#|UK!dnONjJ373qqr^fp-k0#*&}2j@jRM(ohw&SPYcE9QfuxNKo?u5cr7Juz>1Fm zeywEPu%qO;_xu?0DCO!4!c}c&wrBQ_l)k>+Q=XX;_wTbi>@9&4Ow#LRNCsE{SI#=)`+^h z`_SgmF46FO(L4}hq*jd{DlRUj?7R@M_;b5SCUR7cnb$cfBjWA+JKZ=Al#*MJm*Z;us5_mr;L0osMv9(AbV8^ zG*vgj_V<38j~@;hu{#ZE$RFht{a0F_++~I*=`X@@+$WG1G3kRrL=5-)(830@jNA?d z+)8DrjFF5p0NnBKTv6Bg!zjiv8D{Q|fr+hjBDf(v`UTaq$8%MJMwI z-+Rp>oE{lv)T0da?8Ou|MK$1JE*Us%7WL1aR)}mG;I~+WArWhzpqE_c42bUE4Ydmo z&^mS{<#;(ZyWL1~-zt`sOUa==*yk-YNoRN;-Gjs#`!Ql-s7elFP)Z%~zxP&fj^r9YPAnM z^*JbkUnRrd=s`+eK6JO^^VMW*O>G$|7HuL|fWPc2kD`iDQDzpt0XKo{?u6Yse_h*( zypK?PW=7vOrAE`2@G;lIo`n|LZiM_4Ou@nug~GQriH4WJXFQIkc}f4Yd-J|K(lRbq$>%M~eo!Bp*3oKq}m@zB?-xtJI}D-^)#vVQvNhJT*9uXF_GhLXO|12CKyl%+gY|k z527aATgU@Fi||v!vsT+z#SfKC@*g@dnjI4(|31oxs*P?Rk7@$jQ^QN69LASo5L3ct z2{$lo?&M4*f zihARn_VsVUr=!S+L|9FxZEd|rej5Z$XmVHYL1FA4L=Awx1&k_wnoL3GPvJBtthbZ?nU&qAdd^2-P9(%J9je}CY(EOn?2nIybWOd4H2Ji?1LzCf& z9fx_BeI1riUUR{#yq3s46j#~}0W6NHDZ;9PHEHZ?3p&_HCNmgR*PuG7{ex4@)1}FN z+F+wwWJPzQxs@7Z*qCW`j^q^xup7pr$lf9g^MlGUR9E{PsnlmAx8r)R&ESAGV?1mE zKS(e_ojB!(QHoBu`XiFO#l>_3hAq5;DjKrziY`{eF6}x>pvuPJDQOpDg*0;z>Uq zy-?WogyjQWY>RizEjvzDhRj4O%`CY1q%Vtb#^OM&vA#?>rUYpr-u?0aV=QMwI# z+?X+exkCA!e4{Z@AT)YZh);2|P?2U#y?jy7CGD+w7ID)CBV0YCU)GMpNksj`Qi}5L z02|_%qqEvKU`fEi;~zTC38pMxX2wQeRK1}b!w@TgtpFej>7tu>(iD?Q?ZSh|?3usK7)QX5h_@D+&O>Kx^h zc0|q(Wmh{ra=}=Mpglez%T*@0xcni_s!vnLeGZh{g3RPNb_4 zIZzN*90(zr7}OxrAj5DG6cZ4`23gdqcrehOfv$@OA?KK5xU=XA-H*e^8mEW(+E(Q7 zDq3V3(ntLbu>yT`x%1LxB3cR?R}6K=a2*61?>9x7A>j1uT0JDkvs@GY#CQHtU9@Xw zmp?U*vjJ=> zurl3Z$iO;mM1hX~yszST`Y-$JDiBy2BHdQ#4@7`SG)sIM^M3T#$LLUNv?RbR8p=GAW&e!Ac7r;< zQ6p$qvK3WAtdNptzRJqF`m&4FJt}B3)tj+Ca73<~y?$b8XuB z)<5w#VQhuhseG$irtS1OkjoZEH~dXyW2sGN0WDzY0#vat7qEk{je zH%gVKG{csY6!0S<33KKcwMBcQjb68j~aHNl@Dv3KmPGMgrs9m+}&XE z%(|8h!e_K?#x)fv1pxK8!J#iNCt6AbIeG6`k6vLHvsaL8Sr1nm`I+aK|i!PIiyPjq8vOfcCL{(=*ra~xEDqVF#2tx z?Qu?Q9EE0tdVx-Yu{UVXh04vK`29A;5K7r` zJj&LBcy$HEAx^l$jIz33MJsE5$8&I4e>^66uR0qkXm|$j?tWXU6L!wNsI<)P3AHxh&UQ%8!4b1Z6$t zj)LhyDZM02zyU;4v^IsKNg*q!>4i~#J$pb+@;;Q1Smb$_mb`OG7)MY_x4e<6r(n1Y z+xn^St%#~o7Pq)-L$J}7=y0IKO%i&~y6~4@L(Q;7SBf2g-2N+d&cJoo6&aB<8QG|u z_j+PTfSnZ55jup!<922cG5VW^A-{=vK@+N50M2b^{|I18agV1t2yj#^tbjIHiE424 zS)H$KoUPWdw;+TS;3U1BgL5&XFK>YM!C~8qDrmMJ8@s&G1q~)wub(&!X|a35fl}W8#$hNqP(0nk$OFhzc*gq*uD|LxU7d5zQ5U6 z7U&?&V*=pLyFZDID9LLDu@f%}Ic$*jOkXJEXCIXAu%7drap4!Sz>gH}ttVl9Z4pJi zqjA}yYNf4gqJ$JW-@!OgGYeEi13?39v*GoFd3aTofs5}cF1Angis%-38~je*|9L0M zFh1O!^;R`;3GqG1DT;BB<)SWbWTmFpi&klz%>oA8byY%`F7MO*N2_sGnF4K(-?2}1 z^EWP3rd1$nxyfFsTC}Rpf-ZQB?iy{rZ=-Ls(Os_z2LBL_4iqX!IqAoF(wF%clueC_ zJUdsMB6!4WH~TNVJi?7q0#m!Ov$bv!PQPp|4`Vj%&k0zilfAJShlRaDImngWw;<=H zcK}x2HLN4AaMa1C(Fkygaa?iEn?^Fo&+#y9{CO`w`|u9Ucay;z5ZD@(w&_@#;ti|o z^ir;q`}aD9Nq9cIN*Qc6v70ro?=1!eP6+B=p24J$VWWliu1^yL{ya#s>>$%2OnI~< z;jvTlv4kN_?TyX>J5s}<^xxxC2=fHC`2r^P;E_xl*CN52V1{S0KWedF;D)kRqZk3F zJnfyiS+pUd_}b2-NkOoYpt2`CMsp1i_uQD%?zvv90qhNf$hzEgS+B|%mj>)rB9gMN zB*&c|>BHjN?G{wW$Fuq$-VVlG2DOCA2ZnFXw#L3DPuSW~S{8N0VS_b7lgB~Fkbnmh z(FyQ%{9uTPKq*x{!{DSM@7s7OYE6QR&4&5ukTaJbPtM8oAjWB}DBs_{OFXoQ`Id)f z6SYqgu%vCH8GqB3MJUa>wp(~9<{Jn~vZ21^E4-a(DTYY`bZ5;j9sAIZ*IewN)xWSW zyVt`G9N$G(O8%#VRFGlbE_%hW5>R>)A#Hc5a~(W z?gKxVXX?Tiv3toNfxL7}`UH{;OvW|TV(Tr*p!P8_um+Ms!s`%WuCb=)L=~)GLGdW| z*Ra2hr+^9xH&;aPLr;dN#aipY($GjfNEPQc(GGd0UAt`S+OvgKF;`rTDgoeW68u_Z z@Z7zgmyS5kQPGSJLMZrqnHHh5WpX&{ubh#|R51I=c#`o!>5!E_GQ8#GtO2VCMv_gsbdp6?1@~*5sm08jNoqJyQ_|2PLhuMNArpEnmW;IyIS0^NAQdn z*QmcUqSn>{h(O!yKrdH*z<@sSNBQ4MdoVmIW4&fTH(z+Sy#pu6pbo7|Yp-pwU|+3# z+^4B-N5iB+y&j_KcoqA&KAi>!lf`>|&v07RscGBxMouZ(3IPo;vUEu87sqPh#1t3e z`x25j>Al;RDHO{DML4w2AdL(hYbJa+FFd`WhyHRFItJTLu_*DpDS$PO{JBo{Po~GZ zqL^@8i*bSY(A8KQK8;VNc`!_x$)z3<|j-I+JD8jI00*9s@&PYAEm+U*e>mx zqq0uIAR*8m)eSg}PSAK95yo#BGRRX!LYF@KL4;&7j`BgsX-~$CN!ZDcEsu@nwc}?= z8&dcnRgR|AU+<)ie?KEgA1pN8N4#~|m&0L7zRZ%*r?yPtH}9DLEt>y{UiOsu;l}oOjtdmEG;Cl|9&at!?hGXlCD#O6&dr zFA~w;-FKCOFB8#QSXySp!50MACTy?Ak@8V<$VR3P~n1uP&VRH}aE90t6bu0a};qA?Em^X^-4sq+D77|YdaA-^!P*niS zdcG28XMz9VAJyG_*CmFf9qdBXt#D%-H&(%9q+_&QAF(TKMb6pTW|<+RX}fgn>`X;! zt<#FVp8>6eKZ5JV+t*|A{GOF$sLT3Y?PO9#=Tgwu@KBD&RP~^W$tt%=8 zmK*3}Np@x>s=r&&X~f{^h0G~`D-$^UFmDP39{#Sj#qWm#5Ztc`_l5O}!(*JGRh zg9dm_|Jv(jW%eL1XDV2{AH~mM5v%&D$cX(=#l95n+^#W`^#QtU@ruPRllyzel0{iC z)`j84a52g1u_lEA#Fd1%I^nf+zVyMBT8%MMc%kxWrLPl+W&U)3jKAjqP4pyOtO^Aw z0OcElzur|vj^KoV)!y%bgMe28o>*xlxeK6N0E_AnmyH=FDsTm=fmoWWC^*1iiZEXS zmzZ1NdhfI~HBrh!G^#v-R+4zF!Qo;JYdUu5P{a_@B!}T+b>xk{Z^bYXZO$ z2k+7&Wv%QbT-d1`jI7ZS4h=9FBvh_?Mcy7^2km2eI9u`gb(lJfsW5Nc4-aIqSlD5y z#=O|-8JMYZ1@4Vl>*W5p%P#n`ql;b>mzm9`{Mzla(fgYby8e~K;Tn=wt`!NZ94nZj z-1^!)xgm(FxE`fdyl0c-PR0b3%K+?vd;cPm(=O~nm?XZUMD_l#WAP2S^*`R{!!jK9 zBeEC7+uFU5)Et11Jy7S4>YDXjM_+wi=Joz2biEqa`#aqqs-@v8$Enzr<){sG;YPiPs2HCN9ZCPypcZ{viQT ze1Twi0f|2;gjKf7j_!pMF^93vf#UasG!Zql0cxzs5J2A2#KN@pnch`%$Nwc-*n51` z5E-dCawxhgy#22A_tkXbbyTp+4j+8~ z4;Sr|1O>rf`F6?S#<-%p1`41ftjt|cwYSDPz{Tb-#oFlYx|M*fCRhhv7N?_#m=f7%KAA6AiGs3mC+Q#7#>_|*le)65oQw+! z^DqTQvI_&{eM$@{rk)uydlv15oGu#Zt6rh2Xr{NmGhPMSJe)@61_}UrOBRhtJwh{L zzK+d{RfCB?gT>mYtHEUx^=oEveHR0B=9$X#5rMV~tvd1QaXEok$n>_x@MEqh)H`O> zK?hop#Z1vafE8SE$LODWmb2LdFh+fUM5}!pKl=B*DiCM&fkP*U(}#$&lE?Oxx|U-R z<#V<>_Q0QFp+=@^ygI;5x0LGz$kT(=faC4ZW5ur1oEG$9Tmm-3QOp@< z_!)B>C`|lGf8mw$iE_1Ll-!}x33;tMkLU+pNvSvyAZfY$^T1hK!I%F-7lcgVkdch& zi8>RKS8qb8?{Z1`Wlz&kJ#q_8T;~)=HoMt7KO7aK`NVikwI3jMmKXk0>D<}-1E1)5 zdz;u2l(my$;z-W5C&W}Y0CPf)&5&_c4s)8Dm04*g){E4BX|E`1ulUzxe9Dg`$d5lV6dSgeqN)lN%d;Jem_Y7(Z@tW!vT&V0(*jK0; zUOo_-j%GG$Fkn}B5l)1ix9W^qY&&jI6r8s2x&ow<0qo2=M_{Zo-CRy4wp2Jmkep=i z_oZJ-q_szq!)|r`Hg!-Dni{&bW`cY7T{O? zDIgrAFw%Lk6(SAqB}^J{4ah~&2|=)c{DI30Qsoh;X@D8qr)9rWBc_* z;LUqxOWz}!09eP=zZ}3_Y8P9I%Qev>_oh-?jUZ0|^IA2;NAD!EX(J{Ken@+@`(BgfU(P_B7+P>;RpnA3 zY52;3z4;E63sRIH4Z2&e&2w36Xum#>SyaEU4S4&+*NF_NuRiJ8@8u7jGy)Q6Ga<6* z(Y6!E^W)G`4?&nMT-gt5D0&t^;pxKR(vTfds#ddhGt|L}!JCa7J(HI4Ze$BetoYRs zxo_5qbasT{VDJreQ%l7OCM@JAoWVT4zS&)f0SVnaenvR4)&e4|^7)-TJO20tgfJV( z0ce`KR2UlbFb=5Fr41R?Vv%?>Or6e0HwpA3yQShD4oEf*C5`Ow^`QRR;N#uEi(A%# z`d*iMl-7F%XK=**ti9n(cH`FD#@fM?PpNhMbe>Ie_8#z4`nKQy_5=TRtpuEXL-;=e z)wH?4?A>iGk4Y2}UOwABfpyse74H0I09<}hzfxY{%!Ut1)5j+vB9;5olniaNy_z_y{(#Tgf@5pi@h+S*$oW}|nnv#Q z8+F%1T-81U=P z^M3u4Pm>WgCqe$lg5sR#mvU296iX(glDvM3#xA6dxLLdFyfV;{p(~CId`65n#<@dg zD7wn<(wMgy@l>_FoL>8-7;0oo>#c@i0zHRxb9AMQaAo1{K_VJOC*KxI{0WagnrE-? zMH*8`!}MD;&3#cvYng7>qUx2@6)=qek%zLsWUV5G#V511XU?OZ%%DMBlFkqdk~+a3 zHBg2VgphJZm^F$6-sGww;4fdR&2}EF&7qtgiyAl zdP%SDReVp3M$Z)%jYTJnz%QfL=yFK*{UYgU=0RP9F#sB0BSH0Tt)(Frki8@as2rr^5xhyG{qHSf)I|wa=A6iklJEtks{PI zptbhrsmIQysgr=E?zK}%onu&^BhNNgn=G$<-JH|ygc^3TZf(VwFtNpygV7KQ?=Avr zs&h?pDEsXgmRCjbJ%VR+$tCZ3$EqWyyiR%`{f?-o-Yb)b|GAD3=i^2#}c}J)vbJUX0xX-@qW>*S8;D_y4mDU zpHTt=S%0A{{;s1osc3{ggg`$S@j`3AY5l6obCBGxZgxAA9)R%izfd0#`veQ9gc7vf zTcP}SY{mSlx62~v!d_uKa7U}oNi%__>FSeVk20jqe{^$^&f06tvY>NSL~80;R7;9# zS^2KKHpK`P!2#V&4paGF@(z)%2P#+mSdbqbU;|cR5t`u%D zT`I<^?9T-2Qh>_boJLUQ6n99ma0GnN7Y|N6_squz(LoP)sN4xu#gAUVmnvo2u2hqM z#laQtnuZnj4dV|QMY~}AZCMeq=n!$N&hPV&d`DB4e^Q=D1&q9@>x8<=oLwOkEM4Q- z678D(5CZlI>o1Ka$(YT|yMaT7z>ndOTU`iZ<9$!yZ9p4=*ACN-(4=|E-5MWm6zvc5 zqVn!3)(yhV788`>^r-Yazig>GX8$(}=hF$$I#6p~!@n0)8ttqPkHYYEpfh5%Dx)3p zl%Dw-qm3*=HL>*L4=tRFt}q<%%*|M8|5676tZ{xQhv#OzT`H5ahz4`e;=#1Y7f` z@8kzK96TLqP?}!tP6AIw*&+rWf&X^%cP4jqAnpP}Ewj7Fa6I}_d@dzL zpp}-~S$f;`@WL%e7Z)9<w_kM86C(`3BKK)RH*q_ojV($`HHRLt!!%j;9RQGK27MRqDiDISM+HS{tM62RT({dTrcGRtG-7d_%u> zx^^E-+uf%F0EvL7PV%~P*`)L9VVfP1!lPyHb?)Jk#~mU>4;TyQY&H-cYy%gPYqQoS5H^0q_)eUx4$mP}7W;Wc+-Q#TPAO7FIU|(Q`Yk zS3Qj0Ijst+Tl|}Z686?f!jNKY1)kbMj@hgx47+bBIv}Z@g*VOrnfgHiv$2wMM0|PIiDxfz- z6_-10$UYfEws3)nEc<0>T6%$c(Xzb3Jb#m$^z;MDyep*0c2hN#Fp~UQPqy? z`6itV&4*$>Opm~OL7mM>X0Q~#0Jm2f8QTz#0)q7m!da0ZB9{4%dsb0jm?1b|fm9{mVH zr`ef9k^zuH#G~o$3ej}b&d0SO4*m!9)-+gappE~bdOUbwmq_!gV|!P!Qi-{y3Ot(H z-M356h)wQA$Q>JqudLl+eJ?-FAMoKOKp`#1<4obzRMljE<)<%@$qw1kYTYy?WP|(!CW4bB_;{71fqHO>&b$yM#t1W>VXmu%*8N_Hpg91^dnh;Q6a= zro{yH!&iKv$jdb+Fy^@m#{L*01yfb%%FNPfcOYmP&#h~6GhH^MW*4lclRyvvrZRvUjt0aD^) z*^$`_*2)gW9rZcDQLR~ zia{+SLe&{&q0AG6u3pNqKX+}Fv%n4$rKeNlZFnhD|oR{%@3f^S5KC{usH;gja;G2nfR=UT4b z?dLebR18!exGkem43q%?orE<_<_}r`&Z7-Qp4@OFV4mPM{n`BfU7EKtE2(-_jL+`% za#naSHJ}vcFS5I~pa3?YFiDrDkc&`jd?ctEwuhKQcKpYeb*eJtN{O9cN zK0%~t%!(}Q1y$^yz?|X^#yATLNpn7G3Pivhi4GFCL4>#sYc)2Tw;zEMSM^`9K<%(6L+IZ3y)@%CLA~>N7)( z-NAvhho9hytK3M)3nu82k>F9zVV1vlHb~tLhGcF8$^di)LP3#wo0Z)aWip20#4F93 zx|-)PyJgHR7wAdc;fg1|Qb0{Mv; zm{7*|Q(tW`L%>j*onF(L5Hm<$^N}NqQ4UlGOUciQAh*Pfj&$mR+=IVFs2Id`%)RnI zYG;GNe!=$+xf7INuTr7V^TMnsYrz>Wyd5J9T`qhMr(7dkO*Erc*FqGLZzn zDCJ#|C{MqKD$RfT(0;tqq7G?*Gljnkj%WKF=Nzm#kf7mR}H z6;XqckQZN1mc#^x=id@feBwDJSA-H z8Brx%Xg&;ggkKvh7<|-N-Q;5!k=0`aytXYP$11N1B;n2&65moGB7~Fb7|DwH1M9{g zOf2~DeyDP=xNRxWrDlMhrkk=4>8WBZn-w{hxUvEerSI?X$Ts{POxTw457S!;g~+Dg zCXm5mJ>f3;6yKi|YZ%1?1CAf?=r>QRdcTaVK@$3%8KjLx4rpAd7ti1!L|D}^=@Oqz z-GDBA4DE$RLI147je}H)u!X)uYqt%6FsGl+4g=nG*=L#K#5n=8V)9qx*&LKo>hj%y zq<9bY!~!GoG)jXdRycW1WtX@tWZ@Ix318&H-MtI-D$GI6iu zr%|5=9G#Rw&}xOreg4K|(ixCj@I>L{wH{S2uctT+jO1q${pC`lnFMg$dz)q?VIfrn4TV+pB2ByWjg}j8RNzcz~VKP4qK-$l#CbOfoy=3y8~_}7yln&tS6WR z@-Kuiz34US)`w}PC5F&DZ380;lAKZhijs`cZe~D2yWjdJXAKS1CLfZ@kng71-C!a~ z6!fqq#l#?;h@*Nad>Rra(3OBFc>L_A}>e(lO2!>1mTh z^&uDw?rc4B%O!(5z6>~7P+D+Rh-AmL48EU7VBicZ*&hH3V8us}npVZrAjDoovB398 z{iy+qTDzNak7+%KOM~+vmIF%(SIuja323=odylSwd-%-Jw{9>SF4MfKPSGEEMF~iQ7_*=X{*bhG*d74GSxveZy;Nrev?ZhUK4Qd6QM-;R<7%P((!1_sEGnyL&tl3n*9L)_&7nMDOGzIDyi0Bcs{g29IktL z)wa8f{PV^_GH=N`_$@04Ewe&P`c+~mR572w>sY=NWHH}y8Dv~m23hL;%V5z_N3z*N zU-H}I%n3hI?U*n}LkxmaUWz&d!(ADa_N!>8RKa?b>%K>FbaPiuCLO}`jl8MhX{-hU|Z{gPmTNiV)JWYwl0!-pS_gExO!~IE=2lW>So_i zd&g}_+nLNQ@VR|3Jf9gy4dT>}t014^$c&?M(!U&A`^f3I^qX}e@i2@>Bt||O;}!DU zAb<7_v3A}n3IdTl&z_u05*c_-xu#|H9?kK0tcQC}LMC{Kmi$yrIEP&qfW9P?;%18I z0nIBD(qkoVaJx;(x8p%u%_O>_krICV85MmGYrSs0Q_x&>WcSf(THSg{BQ3QUbb}V) z4ZYV-hTpUZb&RYUlqieprlADeA~3zg6#jVJu-Rv5H^7--Fg(@Yn%1Fju0$tPBr*|NhKfy-p zmHhQ{{(_5MfBBnF&9uAgx)(8>dJc6pY$>_;aLoHL?kEIG5vdKbe)mT~aA5mcyq61X zU+70)y!RO4)b-iiL7%8oIEsM4O0Lki+j%V2)pVwPsOmI1s zCDU8ciEsx++3wbZ?ZXxh8nhU71nbu?{CMuPmfRzw4B=XZZ|qD!<3 znoJap@xclg>(mHqTFe=elF2w5VyCtU0}o)bT?o!QqD_ztKo2ds;-(G^N< z-&oCGuaszjiytl#Hc^)R2tJ-k5GTQpiy5{2>U{5m_;(q0478moE;nH?@$VkIm$CQ!5*S!t(YDZFZG#D2UOnpTmdVyByiE8??d_FjZtB|$SMo*==%N}C-3 z@2q;!w+h3@*Cor>ZuqIj zk!+)$(?%a)6KC`jr~fH<=4X@5`)_3!meLIaGVV@oz^~~GzuO!QtG_&#fYL660+%uI zG2G^HBe`=HsZBsQeNedfFVWJWH~=7#m{HB;iU z5U7)X=~XAkJfPs+OwT_PW%h&EP>)W_F=Cu+rN~$vU*(Xp_RqPTV(Cp$%wN)RcMKi@ z)C>;bpnePM>7W^slSeC7uf#t|CWM`oHs+NevEWGvk%~nj0=I8&>2<=YGYK=$6BI{K}NmZxj~7OQ^$&( ze4SF5)BJ_y`7aT%G8qz@(00cU_Md3gb`p;0ydO&oAySd3yhCLD4+2Tb-yEWP!ABzq zzmNKr;?-tD$I85i6L&#K16`IM**2>i9WtcpS|v(G(9Zz_`#9zo^Rw=)7YpF(MwRGm zKddXqw0M%{$?tEDDeW&a89DtPc!crd;TXb%Y2XX2=-28&df*2Gcq|Kj-Z-ob3X6z< zd_OD;EE`23=xtuoN11}0tRA?Q&BOy3WmHSnQ+u%;0-^eIIQ041{VNcDdjPJ|H^dBF zDPz_PUYd0u%AP=de2Qy_ogp9zp?jE1_W0F#^wl$}*GApv@!>C)7{Kd}1Nah~E+_a| zU)!Rzf{ZpcaI3(Q9!sJx@b+z~UpI2-RH*Uykd5&@B+Zr|(4x-mBVn^zL-Y1-(x!cO zgX~^qGtrVWLqZ0o0Ly`8@TN6Gy%Z)#h&Kd@kuc9 z)m556u=7a$1F-CbU#TN_RrtTLTNznE5tPJoMX3{oA$8M{c)ihFF%BjVtLEnQll`8y zLExNvxGaSx`bQ&sPXq@07u{D1gosP!-VTv1qr3-abzZ#d_D_zrwc+os0p-lx?CtJaFn(zto4v?1G45aFAVp{oKi$7fr_`gUYZc#Z`y&s0 zvJ4a2Bo$XBHQ?XjuEdO?H}QG9)+`JYQF=>uZ(DusHg&edF(kg^NQ#rWt!0GLL&KKT zY?|kP2bsCX<1Hv5-8qaYoL$aOwg{?L+L=S6aq0;#lWa%Ekjyx_zm^Qz3y*(o>ixTO zzshl^`X(0X8W;kQ`td<TUq z`B_0RT`Sp1LGX027a#e6lF81~Oh6Q#!pbpi0~*;rI^1u7XLeRO_?$5#(Jf4&fbO)A z?J(X!mos766f5m3ryh`+aF27oSMOYA8>~?2m`HQ%eLzQ*TWg?%%3DN>!l{nSD}EOn^(*hSZ{Vz|<-1KDTa~&Taa|lDPK}((NX=Sht+>;Ef`ePw(V zd}Wb8am~m*;cm^wvp@~59 zF;g<(aGrKuPu^W)qi%Oyg|RgALsV7vKg%DkXKLfiBq4m!RLCCCyypoo(brx>W*G03 z{W~ZDV6%c3gwV(2XeUKzIAR(=!;-#UasUO*$z-5R3|%!pY%J7PIZ?@{64(z`?cjhS$xkB>uF;@}~TZ}P#T$10GJ8)&^cyX2w zJ>B9|I@)JrtASctj!ive7#JTby9s8G2vTPNk#HD^u_ja=QVe-~Z%~XoHC-nnD{$wU zjeq!7uLhEi#QEl%5Z@t3G#*Pv%(@wIr>L{RCTPA^hH829XCBLoYjjsd;oDR6rs&SJ zThlCOD4J%&+FWfMT`)Af8+r&H>_|9BvOVul7rxWYgNVns28YTdYP0DuPbf)(eyf^* z{K}nzf3i?%MFwf{vIjk&wD*>3xi^mMoywxJ1FhC{UQMoweh3~uR02dun!_g6glbvX zL-=f^o^&P)%gf7siPDO_O)xl*HwQwQvH44D+M}lleD_X##F4D|i<`TgfFirNwCcer zAh2XMWnvVKD8ufqq9G*oW9IhjoH=g5b}-ySYt{4UQk7tOY;a>ve*>dH7OVMdH1nLM zJ6eu_9w=Xp@5cF+Y9x}HUV~*H_j6#OtWXRAo;Hjv(zU5%H*>*$LnadJ0A_X}LfkUn z&=)q-!uIms({VoMj(u%*=DHcj4UIBKv*(@x5u9>4v!6YZB5YVbntlz6#d#4Rn3h+# zobDHl9+{M@m`=ge?Vy%m9h3+ni<^UVjBJV#e61#WyK^Ne`Iv1pw4 zCqGEGfc^S4>P`HbECTSNr-vZzdDk^Tgek`r?VrHa`YwsxnMHp$WWpyRT;(vD2Fkj! zRjBdfh&g8U$vmwtgKPAZn)(gvkDcdcg{Z0c?WZ&HKU)CrZU_R$EJZ57Rd>)=3JrrP z^l5pYKJ2Ow#hReAY;#iJRv(f4b4r|ty@XQ5vaD2K<)JtNg6FGX)12oyUmWcp_Qg(N z2;WAczyGXavr=~u8U6N^{$^SfuQ8EAjJRu#0toOkMDj6jLopR z;;Lu7!D;5LR@Wxx(MEd$U4oT8p$Ls{v3i2wMny4?3}BBH*ASCv(_Q?6-@-JV_cBsB zzjI$3GZH$q-xs05D1jZ>Rem<(MaZOE_?(%jGY>FAFA~8QHiC*AqKw_Er9UfNn2htK zq-wzaYgbW5j{c*-67v25 zL#sa89|GR-1V67&0ADNLtrWfLg^qyt><=%s&-(b6Fr(=*Q-t!tzlx4|{iNMZf$wsd z4=|k_f?DPH>eM+6Jh6iL?!d%~yBC-61_J(kT5bOLU-m4mpGQwm6d(8H2cD~q!3iu0 zfhzst`kz5VJ6&mEXta?^10hnFrzYS>ZI$2f=}3YB1R3*spsf53--@5Pz@JtG-n@>3 zXUF;wlgf(cP@SucM4oGa3tSyX(+U{`G)^;W*ESN zS%Lnwh|3s*1!Dl&P{~k+1H%Uqx6HtT1LFjlSN*@S6C4=N|BfgAzj0D{Fuwmi9taP{ z{ofct(lSoz`A|@|+Xx8gt1IIe9*h-a`TynSK>))6Z3(i=&_nm0}c{ zegY)2)*mjyIbBbX#g%F0WRQsR^cjLcBUq+DI1c(uoYOgkfEwn`gNU5BWa5}!3KB6{ z1rh0SW#XOw93=8$HAIAeEhF#rNMWGJ$@LJC4;vUcrymE21nz{0=!md*F!k<-aP~$s zae)j~n_hK@k&h4I_a%)j2O&y0L|NRKGcvoh5uEjACzE;V+vNAt|-Y8%QQ)SdIOMV-lNGh{h$_; z%=AB!Kvf;OAXSpn!=+dhrwj0~uz{o0;l`gwyXG@69DKnHj8KHPwlv<+ouyX%~$ zBu~<709Ts+Gpy5deiyfFZeD(T_xANaUtPa`t-rxn`Yr`wOY=Loj?Tk_AxUJo zk{oZnU#Xv$2S+r!Xu5xA>!M}(AY23Y5(zP0r%9e5NTB1u6@#^#Ly(D?>yMd$m>LJ? zH2>Q&@km+te~3FZ5(cEebk1J;0NQqPQe0cL_r64NkbF5g;eYGTGr9~;7HC;s>i$v?R+{%Z>1@wfS>H2KoMN>c!3ydZI$ z0;I^MtyPEO*@ayf9llappS9r_lr?)@YVqxmK!-VzOl^(BpRdChH#w>32@BG)}M zgs4TCe_=Hl&kLfED2 zJ~S$_KaOI5xd~`jT)12zOC1kLoaH3;nTg8ND4v7TcrL#LPMQv9h$kfwSn%*LVGNu+ z2iY6?OzglUejWNFYE58>|BO1mWM=4kQ=ds{f9SGhE7A=^ijdyW zQGdZP1Gkg8RjU9~AlG3MlgoZgzw|!(-`?9qrci@ zc^@^#qkRP0hgS=$ZsKxEw0lqIS6|o7^D;--C+U2%qH*5OlP;5zeoE(?B@+MZI;B~L zf9BIv?sQ}rO=4LCe4uFX2WRIXh%HoSrT}!uP>@ZSB%oj4h6n;=!|WizOl0yD=I($P z+U1+g%A@G;kn&M>LvG;u;o%zeH;%yVFv&VA|D50-X%C6R#h%R^E)!r3yChx)kQ8Aj z&&kD^2WnqgLkCjRILI&-I!FumQCR^se;qP%4a51IL_r@{#&u8XCE7-%hZBomM)A;p zm{{r^Q@Iteuu`EX&%jSkp81Z6GCe&z^JfFFuV-g;CUx_?ppHvBaJNPpP?I!&dg5qc z6?sb5$_k5h9z>r7_@>1(@YiU{IAOq`F~Th1Z;ddE=WcimVN$w=sJfF5bRY>De=5rm zFqx)+ID?=0>%V<>{{8pgeg9w2bj$dj#B*t)u4Ax>AXt8~0Sm>fBa-yNohXt7NM6E- zK~By=_=1t^nHG8e{JDE>dZQxN589L`WB9%!K>&ZM`GU(O8$IELa6b_D8ht|v-!t&$ zKovnWuD(8vmP7AbqF6Z2HXfe`f7t8+0At&U6KfLOqBuRBfO2jqxXQ#dQUl|WGbM;4 zVSoO!M#9^FzWL$p>yPi=U%k5iZ`a^=KV~e0_-Lrt&jaQ;AQ+YTC)tIYtU9Oe_caI<9D8L ze!2AwvjxlQ0`-ydvQLIQ5J4Dve9#h-a7cZ47u`Mq{evOt#)sst5EvZOu$W<^OpL&! zJs5^LGCmq3$cI5#x0RflY=@e4Dukh)(Kd<9kcWiCZIlX?#e(s8818$i`LQI6dd&dK zT;z}{rLKg*kOH(u`;}L_f5rZF$xze~h`o~l6))5qqpb5^lJ?p@l z$8`*#Vp1(wK-kgDAXh~orWOE6hFBDgDSZ|=v`BK14=gL>B|F~=En1|v_mNGl&o;z} z>i5|>+)#YjPeZ;8e@L_rt2i`KK?cx1q;C5Y9iDnYzWxeDoOTLU`E4U+L&0K8lT9uL z=k`G6Zzm@*VdM3WGyP|Wa9Ux83!B44-BIgTRs~Nkuo|PKhY)?rVuXeTa{CIb-HRlk z>BkpINl_7Ol4_nKXxiHL$H-W)?l(F<1ZwQQR^9q{wa(+ zwfk3J*VNBxAZkXR7|9Hd84#$qgIR*4rm8_m#OaeSsDXCYVB$2cNng}20?A*%Ar%!k zE8WCRB0B}q@Mjj59r(=PyTs*pa#39F-cy(_0Bgwce_@oNy2x>>N%`O@?;-@xe5H1g5e!Ofh;7!#QGa1f5gqmvVEfx@wP0W1;l zAc=4Ib2b@|&>ZzM0B#+0E%R7P5X@tS(%YZ0d~}+!;IoF(*@a+$`dJ0Qd%c$Gufb)|15RSQ6j|9A}^LM?baaZSJe+d@e0D0Se3R3`h<9e4fQEY?pfu_t= z^VW@pY!PKkhCHN8uuO`FmcB92fq4zwVE|1hPw(^deFWg}o97`y*djP?RI7udA2hG$_2v$cMpb6`QEz-Wpm z9%H!uBTeaWisffxrYTa50}?gP0x6&`AO!Y^zi69L-2GWtxuK8^!x!U>Bc@zZl0K=; ztIND!mw8_V0LQs8(~b+Cz9ol)fZvS zw8er?7Dfz2o?pzk3V>ASkn0HV<|PR%C^nQw0~}1tlWx}?oSSx6-{!aYwinAJqh0x| z0_Cb%Yh|&qN`lRjVi@d8JAIIS>uJmdOcirET-!g~t~sQUPaGiDJyhZ`=4H|hf5)ZC zJS8g_j79^fki?8~4Fm;VMe(MErb<&34Seywi+`R0W)Hm;a0v=J3 z$;K!gEY*0K%w+*Hv-`%V;*eD+$hUI7Gfl@!DOor=IKw8w1yuBtn=d3g{kl%lT&brM zKtz&blrJAR4G1;iQ{Yhp>iT8ekYd0LM$KFJfg!g3f|SxSEtod<#k1WQe{f&{4asJi z+mmNtE``-UIcb224C$lu5-*L6Ch$}Be5PjFRt?rmpm6YHF5tNOMZjbL?> z(G`WAy+@at?mxa|Mo&_@3iR zYn@g?WA1?dANe1?q~FN@T(#B9DhW07xn=hW2XRe9yO+RBxL~- z@@*4)%fw&MfJKB6&OZQK;b9XmOZ+^B);pi2;q1zt6wQvXq*u`rqR8Jap{^u+Us$tV zAx2tCa-ar;4Dq4{e~jCuBE4qYfaT4dM`{CuZd$#dR{N8dwZ*aEL?!@M<;T!1)f2~j z8AF8-HqVcV>xsm@5M`KnTi30&Vq$2D^5KFV#c8S=z98{wE~Y%_^#KO%ln*1avyL~yk8QJR*c`Ck_vJ|Rz`|?KZAqDe_j#~Q%5bA@y9EgWn@l4 z63CLKxpt>UwZA2Y(d;)P)jW9wp;$))8^(5t!3=|04)28W%SVL`s1lR;4^=D$klPk% z{3%|<$(Oj#0brq1fEXF4hGwx8ndeEKFfwNw?~kQ)Pa`!T^Ehg^QCO9bz=ir^H-Ru& z!{E9>hMh+ee|l?Ohe!7>fYt;NzAsDtFiz${@BFTk8-Wcb6LY;o+K>9yofThCxp8wxH2p%z22(6$?R zXPMIryMkvq&2nszDsGt<+^*Rkn+Anrh4rW10ur%ze=_i?^*Dz2Nzrts#DZ6yI6GA* z^nKA}tslAsH>sUv@TB++aI-b0PI1e;r{J=yepw_tTwcRUWpv@H9a?#6X~B$N=+<|x z)b4I?f#pdnbc3lD2V_HY8nT#V#-fW5$Vc%M5X>R2@SdpU;Z1RQQCvb$!--bB8QcIw zmx^Eqf9~cfVT0i>{8r(*t0l9LZ;8Sl1c#x#cGX=miHYM^d=?i{y@946AZif1vC1Eh z%1cKK-$dC8y(SI%96(V8!1$k?wgPKI<^C0(JS^8(IQ$Y&E@oLjNZ3vno1o9BkRbq( z9PEzaTk|>APj`Im3k;W@ue1x;5cjgaEj@WUe|X0t;=O;Bgiq|7KV_^dGC!+vqudFe zgFXq-&Cq!^IvLiy*k>sBjZrW%u*E&uBg*vzhBZ3Q-Z8#gs&6Qxj#?rB$Vug+*MdFH}fbqY+VjC=9bB*TE7lr{Sr`Boafsu ze^wOOfwf7OHa#NecS@Y)8FQ`m&>KgAS$-4dQ^fGp_NX8P!_wYSJ1iK<*U2Wv{h^fp zYZIk(X#AQPR&7E{%f%Z(xFXgWa^9NYdMBnW7_FTueZ#k459~=08^VVfmmZsMv&^IQ z^6*;L{;q^Sy7c|KSH4$*mPgmVC4eU_e|;A~ca*++k67TJvie;we*fhOirzgVybo^C?6p<7Z|I!le}+nO%nWYJF4%|PJUM_KFiWhN{#N9-r~5e7p(H8hKElR{3|e_8Q{ z3a!?1SL%2=v}>aQIoascfMM4z4q(oAMYzEMSLm!7n<@{3D4%Ej3w$gkP z>Cd%|K54bfX}G=hAUVC_IW!c<;6IaGA0I;B#KUb|`QJ$4Q*K1dTG(W=!QG$hSE@oOn6t;Tnz z`2G~+AHOD1j9-d6AOzGls_W-5-t+wR*bt(}I$r$@l3&b#wT4&!ku@WcSS#MM<@u~^ zP_j@ZKEH}&#g2WC$fNyJf57b&zkqc5YsSiUd#ejFqxZNq*qPH;a(8_P;yt_kZF)gO zrgum)h}?Tg)_79ddcQd+YOK_SdVxEgHQN)cY&(v*qu|)22Y8x_A2N}4TT2?+%D9yR zY}R0+)TCkKr1~tfSTbQHS}mJYfygm3h3{w$ctIAhLgi?>h35+byHrkd(Ccmc&sW{m&oVqMHdUDuvUd zs-=xyrwER?7a_7fe?r=tGPKSQ^$yUySM?{Hs(Z;-?3j773%uG;BW}y*Nb07oIDRz~ zs;c_a#kQ0DRt@{bH;nlcp~GYerX;xQ0}(OG#qT@rn1r>q9Jya}d(g2*{9aXk7Y4s4 zSxSu>kJ#VWw{Uph6+Gh}S^nmUU#Tvm4$ilqF9HkM3tCNNf3U+u2Cg_8d7wJzhb={R z%tAmvT1PAZ+^S?_U!GTu-DD4pBWdEgE(UG_^o8tMV_(+T)zYRV>&(cnWa4fW$C$)( z(=_d2vtp`=(cl$(p1Ti9S^H+IMSZulb7H>3!nMWygZg1Z@P_*~7Ip1sQ6=x`QeT|a z54YAoOVCk}e~PRZ!#tYh?B>rT{Qyo)WD%kfj|H5fa?QW_3Nep^&SXW>#gL!M4P-Zq zrjw!pD`epz#c%2k#hH_Bx3gJoXkK!Hl+kS1M19mGKgffSrD=5VYDZD)S`n2kW=xN* z61HLVo&n{I5alnvhilk-v)m+XN?h>^fXyXESzSOgf1qrf1W*>-QZ##TdegSpE3q_H zjp1Bo?pbY_m)KD`8pS>u_6Ji&@SiqpDL;xh@|$Q?>WF=1MI5VgVhmn3Z0zQ%r!vP= zWcSLScHx(>fca^JG<2m{73E@0{f6{Gov$rE~HGLK^`s%QSymBX&c1WXo z2v>z8_C8`r^WyeI{at<4nE#YJ{7$p3iNiJcxzkeMF7MXXtyH=NGr6bB+e|-i;p8xv}~nyQBygk76S1)Vij*kwS7Q#9v0uyu?)0~;YH});~sx$_7G<; zou&y*(+ZJD)C%k8Vd@)1U8?=zwoW=}fB&1-DUGN(7Ur`|NO7|U6JwKRPW1Me23&6w zuPPJp>}Gs8CSx5l=%n|-^tWxRV;@OM0FmL+Ks`TQR}Xa*{V z%g_#*;s4gckDB>o4=wMX=D^u4Zq#*_lbo*Vc^VfK1z z!l&lT-f6P*7mH{iaCig&G5NEAIsVdnqQu_KB;o%Cv@Opg!;YG$<;nWECcG8!WyoYf zZ?h_$LsI`G$nbxw`_}F@ZY1sRlUPR(e-k^gcazw!?PMlL(V6WVFC&WN@M6bfbAS7b zDpa8XG|+5P@?T14CuJ?DTbT~_y0`zb>zxe}EcUyM{f4jRD z^YhQb-F3Is2zVDh-33x&&(c2wdAITOIl)&dquL95xAljB@17cN-v0vNyIOw)yMOwx ziNE`HJ{tJ~P4@Tg)-6Qj;jq`4$Ijf9fA=NJ{#RaP5F05{$g^~R!#Dt(-WGWkbZV|- z{aRGXy%);o_RYaQ`^E$*eh#kGf4!~Pe@>cnw=MrQg%Q!w+3U zEj~Bo#PuY*=ECr|Rn}HsL3A(|m%pqJMBfab?8$7iE`8(im-dAi&DYN!HRDdu5ySQXyeEi0-M2F7wZu+Kb`bu)RpeU=F0AoKYT}bu30vpWrUkE~%hH2>!Y5Ev zPr(RAoqUk^^Z?R6+hNV@4&5ht&UP_`BKH-8mt0T+Ui(Vo+d)f~O$&@Ebr(f2XR1_L z5IkiWiJ6Nd;IOYOyi^4-f4st1P`u=V1PALaOYf<;g!lB6MW{$s5CN{dCE+a>m9TNX zqWG4JA^@1LB)rsh=iWLc445kFUDRhY-X#e5@WSyrW{H zIa6Fbe4Y=!pR3{kVd5<%UQ)ry&{yikkc*&0rMDQq<)Rqf?kfo|e+ShlW4j!Lbn{&! zC23DV841iqIr7q1nBG%yikI^gmSKHVbnZREFZuk+h#OBS4F2Jr0nsMDavPpTcJ}ua zr1%F_SbB$h3*&257&R2$vhb9PZv5poTu8ZRdP=erDHlftfw!>qZe&)(e;~nuuvCis zOR2hQ_V1f=_e!0df3F<8RJgqJg}0n|$BY;Vnx0~ya!gWrlj6WRDm zFr-ZyKd5b}oZ4QMZLhfPb@Cb8hRUh!b=mfs+ZLpxy`JaE2gt)J2u#sNnYLZrEY=^| zo6RH-$Q}~3F&8==h_tGFbTyyKR&wAev>`fsiiP;pe^@7NOJQUT467i@1;_NhSi&h6 ze~**ZIDiz7 zX{3*~1sH*H{`?mkg6dbqe^m$3QlkK0O&mb8$W-?TtkL_1;p{GSfSmwYFD|V<+pUat z94E^pe?tIQ{M+1$WlUAgoR=H6*|j6vAunKUhy_Y5}g9ev1vEf5u^Nb zYZ^X&6h^%Fcb z(yiGYM_~27d!eSIhQF$eYxd1*qgx%TP)%9af4bh5G^96f%+21(N}4q{T(fFmIT?+` z5AYpni?kr!q{{Sg_d~FI-8;?)B7xc2nLC_^MWX;dNT1o=%e$M!;%b0U3nA ze_FV5k$pV&Js)a#(X1$h=q09MoP5Ce=YA4FFMy55Q34BdTmNYH9b@=Mm!e;@W5?Yn z{hH|la^u7pm@vA%gv=bxcsWBx0X4IplsQ!zX6Y%%*9Z#`)P`;L(i~h`EMlY@h=z3) z8I{!AJAIBB$}5L!H?(uNs~W4~dP(5ve`}jl0~$dwD2y5>qL68u@lRQC2Y|`g%FJzo znA5Kq)6y+YtS8Kmd4JA7CYVE*}p&f>fwX`lz3#{iLD7x6rzLCSx@zC zr78WL-CKch=j`9A*+iK=6YVwZ**e+Lv$Z8JsE(}<>6j?iuw#6?mV3zM6ToJ@e`bAw zl;ORtaVwWCG~WJZ%j71vH7?&>HJ;VhxZ0$v^|I58TE<(vW~T){jGRHf84V1q}jFu9QGANOT+(ONCs8(xlh0X_+x8dvYu&a z`S#E*e|2tvG~k*uGO_PB(mZ+`*g4nU*|Uc_6lFCv4KTQL2j`xE zjFMF3kYiKb(x7MFhX!(F2JXN0vPh{6d#FpWSrSbf2^*KJy*n9 z6?@!1!DKZDj;WP*<+NR(4*ffEwtg*=B}5ON1}7bS_@nq{ES{XnhxiOz4Eu%ZG(4#3 z^wtR0);02Mim&>AgGyeHRM-+514^}h=wcA?4w=p0@3TA_#{k0<$N7CHye~G8I${p? z@8F8ddlWQ@+GWKn464gwfBk&ES*`>@$A9t37U zx0%`&*zR5*pQp?A{l}^T)bQ@}{qOY8DgNgX{O1Gzch`NgjJaIJMY_5mUh z0aWbKQ36o})$S!BxYp)Z3QOoR_!vaNm8nXGO&~TvFAPJNfBei01{I%|Gi)HO>NAQ! z0w=*SWZxay$*cTxi($&$$qN53w&2mxJ-#JsW<9fKT`;qm!C=}a(53X)ty7=~k*%%M z(Rf#S)=bh-$Hc&E##GMm4?ixLq3CpgkWE%)AQ=XkSZZer9uYwhES)pKv^BOU$ez8XugDuihQF?g*$VA5 z`utg#lGvv@t2Pwy8nq>%GmJkD+-7OVl7tdtEDx|xf0Pweb4%cuVD4qzhEM*`c2{E0 zAqdc~am}aQ*-W#nN|$|`k$aLNR*-F?S!GyM)ui~vdEQXZjU~13$#Yat3G`j{;n0ke znSp^LF+Pp8tyvzfzOp*k;57wNfpeUE^DziCVA{-P;wC(aZNU zh8}@rMUrvDoQp2>cLmNUcx||9F3>*{dLR~@{|x*0=(S?Ch>-VPoRe#bEl09)(lXsE zMaw0%El2m)ZYX>WmY?~dhB zf1NAA2rvuo=SvtNlk7Tx{GY7XNjClriM5pNIWJwZ_!d_Vw+UN_5!dPOn|T@4mTuN- zFe`9$&g>lo2dOv}{&P4fra5|`tFRAM1*p>a@9~-X>w)^~q5A8Q`s*w8*Vp{lM+%C1|O~gl%JeAQ{wD8bLEl4t#3m5=cX%Qgq`f;e$|WDz^?|zR4$Z(U1p-rS6(+1qpwAz%}{J4==y{fA9bI^UJr- z4!EE-+JB3i`kSBMzJ2-AA^*)!2{bBnbzlB05y7#*Q>3zg%IA$&R+mJF+eB ztG2v5fT3=)4AchU2OS97UPbe`2+2ONpcnqDXr!lh7~Q>%0xbtIZUwEd&f_@K&zDeHm1vM&da9 zI--eo9C(Q@+?P$b?mTd*?aXurKbg>C4_##3=(I zUK3dE&oIZg#PB5GR;O;XJVq7gHw(j=uTnTkrIaH(8z!che}keaT|ZzDqba(mfvoN) zp`+_m{XhXTUJ`WTl_T1EkwpQCO6@XdO_>_7_6y5E}qvzbn`B(-*%SAl`to=N7Wfv)QhNZv9hMx|rS3Ld%N&CDvIm7WNu{ z_u|PiM zLZ_;G`tIfH9}n3&prb!<`S3pY{!WsI89~Ed_-UtT;9_J~>-iGlP&`5fqzAo~NHK!L zMhW8K#~W%;DYGeE7JLEHM05VmsCg>*4qw$ZN*;GoRm8rK<_*Cy6ozvSTSg9m^>!H3 z?AduKe=Dy{j_i#;Q8PPcD?)rRJlfaKTMg>3vPm^^5=FcSlxE`oB*Tsub1cib44(EEw=NN-hf_NnORo<=Iu~ zi2mF1{wR`;)BI!xPf*L^OZQ%HaIoAz6FUN3JEvkQFR#QHWuCwyCJO{cn@|~ciq6lA zf#Bi8L|QD2B4Yo6@cvo4s}U^GTUQ4~39&9WrjLQ>lIT#d5&alWW<{?1{bE{5nZc%Y ze^8f`N*9T0c($gb9Tc-=U6PSQBuhBV=Q5#hi~NNY;OwjP`Pl&%>Gw;rEeEwY+&FNAdF*8I@kfOK8XTW+%_qmf_SkR;SFz+UTNWrv+7&aZv2?mxR&G7; z^Pp>;Mo+y^bLjQ&fMRX>Xwd#J-?SlwyuF^cA;P+SOt0EvUmv&Uv-Wyiv^k-8)Eii> zLU-P*G4MBP!5**V^Qs&Us|I?`f0g8R6_s6MeGd;i<|k@LSw-o2r<%v<`RhX{`tmju z{l$+@zCXm9Lpsads^RYsYIfvqwAHZHpI-fZi0Vt)^KUWSAD(>k?1uvymi~sfY53Xq z&whG(NXyc>@itArIHcLhtyn(@!1u=(x$am87*+9}QKobxstVa`F5FM4e^=^q;0NNu z60Q9i3B)0ez)Y#RK0$%Hs=^EQN?Q~Veh~aMohGyEAna?R7HWHLS6->CHN za3G^8CPerDTy115q?Y;GgQg~p$6#Gkk2roYG;zL6gs~aAIS;oOFT2Y`x96`s#YZ;FI^XnI4oQwIa zuu*-WSQv(Ve{+?s@N$o{RL`$wV*seKLyT$@gDJ^C{|0HpJy0R)B7!)_jXemolSnGJ zjJ5H(sa$J2e2HqpwWP~p1ql2)c=;`sQnvM4*6HpQx&|>WhpbZZvA|49q)qh> z#AZyXXu8_~zZ&W*x~FQ|(RV8J4OCsbu*`wKpDffmUP?5th@iH-@UIsg%VKjE>rY*Y z^2xHO-4WW{FU%wUf8zht$x`i6P|Y$?kuCXB%dT(-TiP>|4Gj_V**+FckEMa{m})Ax ziq%tv%f&1om+mqkq&-U@_@6rf65+=j*psf2xmC!D^Z?boaiM;{g3N=EM@c*pw0gIWK6z*t=W0Qs-L5QC(Al@$-B{GE-qMs;y6K1N|f8e5P$?ugg5=IY!k?lHi zyJmW~BX|0)(iaG%cpr+-8ZD{hq!9R#sd)*v(ODR7w_#{y3#ZG}ZDTrg z-CDOG(+@c;E-TBOq8(X0hK_?5 zHnY?ZSKpb6Kgo9B%xVs%>h9-TL!yf&;M)Ma{t=A;PcC1JZt6smMF*>JC)R0spycR8YnaE69wrcy03Qw)x=B@p_sI(;{h)nEod@bnc%;X{B^de&wj0LH1F>E=WHqUIn5btqC@7avekH8t;z=Dfw`JK zI=bav8>paQEVEg}uDQ|&iy_+f8}S`J_wA#{OCFi|wVDZ8wFA$q)ksHj-K zt(gT)}r-vS2Ix$)$zr2K3{wR=!stt!~Mm-|Hl_+j~M-MxiD@YMmWE^gJ}G->K>qs2rw_f;}N zOS3~gnw3Tka33l@zx(?u?eNh}e_RM373g;r&5XG02st4d3cJuphilWT*N1o!03yz9 zmiP6`?_WQAa|k8_$Grx?5gy$B<~E>Fc2X{|npOhkRfs|5O|lA1i`gE4ROOD_RM4n6 zmf%((czY825zoFFL3CHb-jJX4^cq?9+x4Mf5+{K4B<@L zPhbAnR;@;dm|K>G6rU)^DgJuK85wD<7#b(5gaVkmD&cs{KufS#lc&rvO?6gThk3(_ zjz|`8uP;IC&}M|BTti4YBvisRK`QXHv`O$2NJ}PZX|LW!K{#{}(u_^* z(f2EGb<7x3i5UhZx>Q|KJ=7=#8M_)((FoSKksh^N+dGLM1;HRFexIx>1@HvRSDIT=^ZkaMRp&#pbEeZ#F^!+9+Fe@TWEG`4 z7v6lQ2H4Sbxco=CRM;84aB0J&*?sfuhiBg&;;cu}XSZ=9dy|u2V-|nj>nrTP<@pZI zOov?Twx=<82}$>NmBQSe=g8q2kNtW(@ART9RE}uI(+UspM(l#aB$k!b^51SJ++Exu@PJcyY5QTZ3;tCcjLY4@1C^W-ka&)|P*6nygl}3+K!t>&8H0 zT9h*_a&1s+;qGpha3tj41a@y?+DoitW6w_VyB>Ax4;l80y!n_B3V6R!hbo7k^CGg* z3r$dF1Iti{Dt2Na*Auk6p0~F!7rSPzoI2Fq)=ypQmUBn5_0OG#H>i_tJPoB*z?zE^ z6{D$s;9k!jR2_e>8x^sgxQGL@fhDs@v76(#-ArkE0&TjosHNsa&R?lMz;^o@fZIo7 z3ilFa!0NiEyrOoJ&=ZkF6Ljo8rv^wL;ImPeE zn9~n6tWyn#;-2)@|Ls|S1G8bzI8M%p#%<>KzS;|c$F1Hq#ht!S>yUP(AY?={dX&6`kmJMo_oSlcBwtko%fS#s z(>0Ppt_Z3`7!7Ol3Jf(6?4tbJj`e0q%U1Jpf}Z+eJG%~%?n7|cw7aa#q)=j4;5+N6 zq!ENoN8?12nY1Xxm+00iBjF8WQWxXi{qs|V+iHKm@()vs^O<5c%!Jy=u0!l=D15JVV7pRk?|dE>tey^m23+_9>Z%2lj3QPi|{4NG0p1+1fg-o z1eIN(*@6E>wuT{phXbV`KooCN7)QqEVrb$`XHlgXb0qyrQFqI~kP}MFH(7rmVUxMe zhh=B^auFmL5)=-y)6;NRvAgRZTxM5>Dhl};?NNx&D(&ohN2cya z&Z3Mvip4j*^Rc}!1;7-DJEzl&#zJ=EU*nUru(C2mRD_kYiZVvu{C)UJ5GR*aI5~6x zye9+n4&vijTCC^bjJeOk8jdatx7I?HvK8gnvNzG~+0WH#GMW{+?5j`Gpd}f~4qZ~m zVAA=_U0DQKTQ~X&GK#_7R3*-(U}=9d@TwVzc=OJTpF5J;Ba=C5WhY{{pA-b6*&7t+ z>hrPaNjC#-2%_Wo#0?5@3dHn}V_(6`;wlQ>y#4iuXF$Hj9D8_l)We^uadmdE51|$n zfEDWgEMtz?GmDrEn?2>Fip4pTzZkc%V-?lCoMhLd<$ME|u9=ibE@kWs~Bkh`H-_XL^ggasxzAuTLGhSReGq`iN=Pp)&c9A6o z@U~IU#V#TKB#tw&_7+Q3@ynTQ2`q?45Zf zuvuuH(Q?jLeZe|T#RZAJw|ND(zj;flA+b2z%pT}pieytg+TFYXoI-y+IOa{UZf_QC zYv9U2>#XvC^$p@+YF+CPMeLq-pr~kAf{!tvCAv14SjjHlB<#5K%#0e z0i<63C@7NE2T+YHPr2zZ)o%9V^L+B|@wrTbg;{S@c`<-f5;jp%Dy&jyx}0z?ozz%pDliGi%Fe`+i)uG)WJe*DoEb_ zXz_b6ct6S4hMl!y4wpEugo%x>+K_uMV3XbsS z1q3YJbs~;B2s(!srAc7KSsMET1d3fPi39Kd+A@&sO_(+d8Q*_Jgb1>rfU$a!h@Fr} z9K?cVp=7;T8F;tbZR2c*o`@l6&hiL=lvnGq0@t(CVNr)bnsrKN*vl}wj;l#}qY>Eg z=;4qbj*Sq^(a}+7q#bcUoEIxnIQ+x0^AI{7W=47d2>wQga3sVC z;j_Q|_`~z{dO?4l-a>qpE8+;qD?vo@IFgI=$%MOvD$6}`SG1c70~BLU$rA%A9U zs#stIX8}TyEV+nUVpYUHkG7I*=R9pMMz@*iT zjU=-{`%B9_(}Na6DM6y+n$qx|tEN=AHKk<66g)Wf<`54qH%x>Aq0)K_(-zT#3}*OmI3 zOR0Zc4mE|jjQU36@z;GJ;peG*-6?zink`F+d+slYcMqwZ7!~$i`h$ z5)lp(3sUBg>kM&)s78D>^f8VjhpvmGl(pJim#w1*ZyFo3K3b)NjlV3Z|5WRkrNUnv-t(5&)Gfi!ObtkutSN~FY}Gw@ zoNRZ0%a7ISN-j}`*iuGfM`C0)21qwcDk?1iWu!Q|%8`V8++HNvHO5~vUz$l279j^n z7d)qi!3j8?`r_nlECEQ*yi!j5959kf=Ti+6x+>30pFygCI+#*0dS9YDu}05wiIB{T zD-eSYs(XVuFp;qjs(!N*TYar{FZ{8FJVDBTTFRK9g#`edm@8pIYAQc?h&;5Ld8!Q# z1fFFwS(hFkvwW2$3soRh*w^J1RKW`$&sS?0Q5DtLvnc7dr4tZeE(f0fAwrkxLqtf<7iv*75npC@urkmOzG+b#bFZaRb&PyanK&p&z4v z+v&3Fj(5F8)nPE7mLb|&wPhS?6;i=BX=-dLl`e&wEJv`g1|sczI$u_Ig^@%R9T;-Y_@AT1#~`U$4dDDZjg6 znMX@XV+^VWJz^4E>=4u>_S6Xcv|*1VQ3_H2CPP^zyo>p2B7Iw%lLxHq6@O@dj#8!P zaJ2~ z9B&%#iY738hQ2(G_v%clc+Ez;t*B(}3ch^!ZMyvOLGQ~4-+lS;Svli6e^3T+(Mv1Vd&u$?To5W)*gaj@&tisup?5= z-6tFApCj_b=VxP!aWT*A(>ZeJUk|U$=uDE1$SlKGmHQ7#Ln0bos~I`9hxMZ{Yo8 zHu@F`-D}KkErg#%xbs5oRR_-^#odnognr5$#-zA*N{qof{6~BPmjgIx>{5Wb(~(1x zjnA?8P;brZ!$=N)ngWs=?{p6SVyr%1*Pm>@FZACRwgKUq?Z&WCmID z;A_6+XkVqh+M0?AR4?o?4l9=UC8nYU9%9weAyi9#$+jGSH)+I`f@*8(6r>_x|2mC~ z^_t>MR~hZBwcHTqms}rfQ}*bd%J`+#@j_R^H0e#5|7*)eLbQ_X(+%-~nrh3e(xifN z&FEuWxw+TeiZ3oT(M3tcpz>+HT;ARL@%K^+#B?~(2lK(N+w#zfZGFd0Vx}6sNlZ|) zm2Q9H`y3m8tFdV+RWwUEtWWY80!#HbnKmrF_14n-?*vl!T2XCNhVtLG6x+c#K`bq& z_RKOw8UWqswAEaHD9bAZb+&*SFqq;y>I>Jpmt8@AZ#5CI=CPmHnzA*3NHQ6YD0@+Xdeco&ejPci4am&I+b-RC)Rozg4c zcp=%cXlOn~5hXXDG54P8I3cEtPRj&n5@OT-E{dkz4+@?7F{D^d&g0_fD18h#M(KH+ zU)<~UA*0eZQh~14dM4g5mL$X$NFp9UtiC(9P-$|# zSbH;n2>!Bn6=j!aS0VJ;xV++?KmQE_OY2F}%#WqhG(Hm)tW1Knm@n|EH5~fs?T+N1 zoy1%%tVi0OW!}=GqmC$3sf?4Fa~W3P7HSmr`>c~;GEi1LdeH?4WzbVwuDFww!n;k zH^X6RodK8UWbI6Z-fVuf>AAb@P|5BAxXzZ5bmcU|ZkE$P>$wRGw>B5cF<@5+l%TW5 zh>IGpmfH-O7nR3ec*dR=kcnM_WmFsqn3#z(%k15ierBCpG`f^WrRo->h4*^X$T$HV zE12}dJu_)Fo3r=h1R&-mzgzIk4YmA#T4u%&De&wJAC%CKE!R{T>76{g$PIDnnU1^N zMDuA*ppCQQJ;6&>XT{i0qOrzP()h^uPRw1772Ml)9~b18oC7RkFjg3Tk2Bx8)A1Tj z-U)sdTJZV^ITt_;{@YK3;!jz{g<~@NsCN(AWr%k~^%Or#$WywF?;9 z-O^SN@ES!M;%%mmWz4}o|0YVxYjC3fw{{8z1W)~yiz)Act%E9eoJ1OBrs4k-nB-!)28P`Jx~z|-#TFQSNe`gvj8 zQ2o}W=%z%qx(qG_-}%uHoB?#?!hoUf=XXQ_t)pVfE9Q7DdN`l$nu0qy(xh@mv#(QF zsNeYZNT4HOG;$uHy_W3qD#{<1_ciH#U68t>miBzJZqJA9CBTOW&Jb_nQPkSwgmL%? z;~tHgL1v(UQ4O7c06lRR{&VZ#Oswg1L}o(I4-Lz#i8wSB3phQR!Lg#!!URu|*s>eg zuQJfW2x=q6_Ud}FkiutF^_chMiqZQdcEIYF=YmESOWV*YWkm9nmx(vY#Hgh$Qyzq# zJQzDtHG?)OY+{=*M_P+3W|C+;wIKbraT6m!JTfQrJsP1d+3Dsdu*-0*4$d0M(Psavs2&Q@WQ_Gb)Oew1f>uI@^d5a zP!;<{0XJIchJBCuESIpbqUoWi0m)d$1;++z`0YNPPT5W;gz%$n!WK`&Hzn11E#6jb zV6QP9@#{T*GAP%@IgJXZX#x_I)tqW?I#iE=hz(%XTrzauzRJAtZc7}mmXKM?#;mM3 zFbvCr0}=|TxcX5}#Eqi!!7Dbubj!fhXB~EDPcC*TpuekAvgt#`6I+2opjIO1h=Ix(f|Il8Di9}`NpwN1# zS|c^A%O-))aV|Aup^Hvt$Ml*<!L9ZL&cDhVDz^ix z9M!%k*Y<(f9=zgYeyrImb-SR{K}xmLw=ZA6;iTv0Z6Qxs6)|ssI@xcRMJ|?Tl1x{E zzO{jWP9x43M9YZ-Y6dA$h|*u4;uKLm7agkIcp8=U2wF=UlsS(*vs#O31^&|qkTz(6 zTZIE|E$a)>8YqWg`^C6OUOp3p3QjygY@Pf9;nqYE3A~n(PSd1~UHngF=1WyC#LdDU z4nG#;;SjT{1IQ;Zz(qCyOgsSg&~fnOa#cNlCAgj|2$i@jP{Ax(c+l&egPH=N@Q#ii z^?Hx_7i+u<18J};?#LT?gmY%@Kgx^&bt1@^?%eS{BFJbfzT2#d9KcQ`znM!+KFM&6 zRL>>SJN#7s^n@-*BB=5)}`#=yy}&N3B&^8R`oe#E$I3|vX){49ZbLZ z?zS8sL^38z-Pub9Mgu=r^?jF;LghKY0>r6GvBoSh|IUt%1oJKl!bQS=efreN;{e@F zK79&K`H%93iB+&|e$neAAN^tm@pNIoBiTM#5!x>E(holb=MGmj8Om#dmPhV?ROL*FFJ>rUw-=J;MR0Ji-L5QRN|vWBKmxR-|7p^!oI>*WR|g|zB%>`!fsa>h`wKl^@q zCO`cjX_5t6DLDF`!`rz@03tCb7*rCaN*N}dy|voKjsa46|FU=bpQl&%l>h}t6WmZm z>7O) zx!mdHBTUf20j?2m(6@6j>Im~j(pJnVb%$f$=L3Vr?htG_Wr2Qg{K5b!uuH)|7!wnj z*=>JjLL=piew!vvW~U9r4J-5RYMv&Tn;}&!Rbpi$&JzfoLW5NrpQSXJ2ol6I=7 zl59}Bzon0g^akN$E>3xfjGOCBRhZdds+<-tnHcyCDy|MY32mglBGUkX$dc2!|J&^T zCXuv-V_#<#^0HV+de){gI-t^^fo8H4-?-c&`_3#R+3d+4G$XH=dS8Kod z5;FyrBIbeiFvo{W{UJ=1czPTh>kn7>5JmtTY7`+JR#=f=ty)AE;4a34Z`f? zWY9Yo>~?mZB6MCBZZ%+fN#^8-oOLKA1tU}sYcYaI7V#&T%eg?WOmG;=atqY;j3+~> zB6|<)P(B}j#XSI1`M8zG7CiX|xC73feSKb*0$v;raIBx^feGqQxA-f72~KX>qPFCH z@&S3BC8!;Wy!+eidGfAkf0%Ee^P~A%oLZ2yC$nsct_AI+J)O@NZM4G_%Znfqqe?hW zT-hHnX_Ux>`Xj07036NI%?Og!h#A$BK#&sXBkuKc>L;HAVru+26Zap zSy@O)x$N;xbi7d67k6CiQUaD=0b`@*Fx}$n3`x|bgh2~&7oqk-8uuXZ>!X$fhkV$! zQZdZQh17%$ppVjDh(->hUU7ow&JZlntv%8ZVXsD&VHT_yl3%xv?Jtkp?ik z-rkOX>@+`^s2~{d^LLZgB%MqrYw-&Io)!Tm=nOcY7Pf%fb<{kil1fw*@`NIQAEk0~ z_%TLVlpBe2OnwBX=ImT$e_7#y8=u4}>?%;sAuobT(XtS}6GyK%NVQJ~DP$v+d#qq% z-PK?m4==_ione_WP!PEO_@v}v+JRIIj=_O{fWPE4G$DMfdc)oX{T4qhIU&s)MH8da zTJc4oCAR``UvoczF$YoG%FL@$n)TuJdAfWYYz2kGA7k-DQOT)T*Ju`hC1}@dFay6s z&;#TCl2fvXhnMpA=?o8+ax%LP2h)@Im{MEG{8fl{+Xhk}2gfI~ljA_Th>9N_uI1!^ zOis!|f%p8jQs_NmAmSrRW>qGt8c<#<$VxSkc^>k<6oVfhhuf(dq@L7gj3i|`@NN3E zOJd&_K>oe}kFYPqIs4-5(W53CTg&|wI_rY`UZS$EnpCFe0t2iKf7iP6SvH+y*X8wC zGHixQ*k40B-7GttUX2Lb0Vmm=G7M~g@y0DLDJ;ssE71g7<^RriJ*BP@6j~H)k4fVy zR_^cJ8>z)M683<;2XeW9kM?#8l%Q_z8_t%YiiU4@EU9A(dv`E}E#8_c(NCwrv_Yp1 zn71ugEv-9v9a8AhR!H~W?bEN>T9JRsoS*Sa(D@d>Pu7+uaz1+|9_q2R@LTeK1EBYi zu%&2#ONN4Vfw$}fSQEV~#(Fc)H`C(ihzj!qnRqO@85p{s(CKH-pNhLekXFG*3VyQM zXnKWx&%%mUdoqP|hE?sXd?RE-R=KPkx^=Y9pmt@ojmm%!WB#zrd-;MjEkfpd?<=as zl|Z?T7Fr@N-`Y>iP!y?90G=yd5Rp^alVbWLX9Vr!i+lbV4uJnsLI(<(}G3P_`^-k-5nAL`_Z>&Cq z?FgQBHeN}6rwo<5-h@^6(UJCY3jo^hDieo|oSx#kf)COD%i8lTDY8XddE6;b&X8-h zeO!LkPpT6o;RWSPtIA$w2UI6dFZEJYCBBFBn}k+OUP0cyLX=eWX&bR)q`xb$e+Imw zWsBj&>`}-bB`Ay7nrtb5?h&Xk&>p)sDgKqtD7qWZj=uS}sPg$tB#m=arZy@U)#`3R z&XQN3k8T-pWpf?io8Yxr(8dRIoN+Gp@|v zDtTArKZ-Z8erZcnn47}J=6789?c8(A$B8tIX?|y(EvWup5gE#m z>0VF?U>;6KFp;dRl%vLmdC?Z#I$ooGZV7}pCn=`e?ZQUcs_7Hw zeXq%5@g|0_FFAb<0xY$xWt?UoRi>a=Rz4Sy8%z0IRL()-JpmeLB&D)}o170cIp}0d zPRb>nV{t)E#COa2>Yu`X<00(JFEXNdq?P)JhG1=!Q_(4lnw|If$_M=Jf15Q9-L| zDE0bVw;zSpfjH4R9rp%$L*if=zu8x|XFZkk8Gqaw^BcEZr3U8K;1;Zz?YNG#kJy7E zg^0aHRu$z}2e@rB*e(u`H%NMgu8H@`NGI?<1iA+QFMdbg$>pa{#(8^FY66sF`>ydj^?i`7r_HQZ89oRz8( z+to5>z+OaxmKJiU%^(I~?9}|Ylitvrg-qV$i4ce6(mQb=3@T zd2Cj3kzZCdZaQ<(m5~#dX=!&&?K%Sbur2f1_k-7RGUV^Jv^b{91bQ3{TIop~^a1{V zM>0M6=~s9Xi@5i=xajqZL2;fBiqaa@34)VO0m1wwaPuQHv=2m8L$q&Xmj&Bp+~yQ; z6xfR5YD!Ne0#WRq0#?#-%p~bj(C15ZU+M5f9Z}-G|C17A(75PTMn_Q*UF@AU; zPo0w6eG-=*@M;W^ER&dC)~0wv3-ZD=Au^ll2&at!w0C zR0_ZjFiB#9BvG+eV7W_H7pB}yHcNUL_FE;byl`o$`Q??P3VJ6)>OrgdP8{Lk2Zz?d zA$xZP-F^9f_KKhnP-RhZ-tl|?U`cUCu}b^}=5L2Xi?<2_q^VZn@SWQ2g#?vbG%w6jFw?CS~S6(J!qmi~z1_Yj;$hkupP$W76-T*6Guy zduOP9^7$ku+rHPeuHqIfPr7n{wzGpL66=n{qZ(E1khEr@ZEgxJn>GI zk3c!3LgMhETiWLD!;?XQ@b|H}T=J8200CFiSlZlI?;0$mb^=-Me*%w znQ=vCo*wczaRrU({v*REUlf832r{c^VfQQoLdMXOuOQk zi32GZm~NI#!Ct7s^5hnONy%<`;d0rPuL%FjFw09mX|gJw%yPQ>JDHwKDaxZl5^337 zly=wSV#b3VYRAPO8p8+-{S29usIWB6fQvzA{Z8Tt8f1g+6~@?7S;P8^AG0%43i~Dj z`>@s-ED3DJs|@^lr}LE+ZbXt*WmzK2<%n2Glj#Gcw`9$#%#$I1xGm%1U`Y6A)&(+X z4NJAKQ4c*69};+yrU?-bX)_?+nx+L5oT-D8W3@;TR)!$HD6y@vjX~<^YPzGRDb@?| zS(S*b0W;@9B1&OhVwM;NDUw(D8~&2-<%+0M@+Xv~`lHy7r`JaA?=Ne@q1$p@ZUza2(uJ8iX zckRTNo!1`1%4!^bFYLrHT~+z0FGHz#FPbHZ*Vi!36j)_+A=t8imt>qcY?3w zt<3M_uR*HREyHpyK$uCpn;Cl7fZ%+_s|s@qZq@_9>tAet7N~)N6oE;0E&u%crVtxL zT-O7psBtz(iBbW+6lf+D2cXDz8M+X)nA(2lj^DY2D*!#7drs%(XbA3HXvO)6a_R8o z4AeW2N4!+!0L_xJS~LQuzOkTH(Nt79Jue1RmMLd(aydoax!}=e6kW|S-uTm}4tXQ7;VMfaB@;MQQ|a+UuTgFFq=vB-%UInoSaN`C+z=$X6GiF zp5CZHYhao01yGG-DP;8ZNj%&3&PS@Q-90VgNi=0ZKa~Ym07w#5FT%=|5EU$rBkz2z zClp9D-6btB2%&J<4(Yrb_l>${03Q>dh$-hkD>tHlOd{xfD%Nu#~Q%9oFI^8gdu_oY|_-GK_j4u^?uIK|h>ZgFs`!KThN5(3M=@ ztmwK98`aps8bg?BLSj`ql!BySf2}$JI{~#4E3k?O54vA>&w}k>M`8{`VWY|tpFd~= zmnZ6m_=WaDhN`!C9<+r*1=(hCh=lP<)T)|Q100xj8;UI3M{S(;vK7(xj=@y61Xu#> zoFe5B7)ZlW6DMJo^Q2KJY2bh>fkq&O2e?H`7zZV=xOsR8f!?ZYD=52Frg+f$|4>T< z1QY-O00;miV3T-{G6r)-lwJ!)v#^hP0|F#qlPr@q26IM~UJFK(Xp{dFBw&qDJecU_ zA$|Y=5D^0a762TVL45-ilaG`K26IM~UUx>5oRlnovE{_OzOC(KW*$Y)cB#80RotrT zsj8Ok@o0bhOOPN5@KROXYDvyaa?Xy`EM7nm1OX5P#${1A$zEE2dR$Jj>VF=WRhB$R zKCiE@73pcVlZ^Pc(U$n~XfoN6Ro2Gk=`5d$YWPQ$JosLGS%WXo@iZ?=(VhM}JkFZu zqG+&xxvT16aglv&uwDXX#G^ZMI!XL)fvvNd7O?@q+*3=pSt0n%ZXG*y;1*(6D8fr~m5pib;MtnszD-?A1_ zY@05cv=VKcF5bba_38r4)5!!eHZYT0o0O+%UI-cIJPVw|Z`H@}cZ!iH2Jqi1YvxrUXlb6| zr*lpD2;_&fDg;RmBs|H67<^+V+50%l#z1^@500>Rj$Mu0529LnmL>O9n>wk>WJ8hr zhN5XPWM(&UfAS486TOq{R*I}g{}qjYcF?k(k>!l6CR;PCIj74RkVi^?sku5lYvFASWEug*G-ClN%m3A z1KB^o#Z9q5+b~r&%T`PYj(FjUlsQewtPJct=vn zmfZ$TRx~>ZBhpT2N5kxH$dQNGQ}WeUf?d8$Un(ev*caJ*dOAf}yi{%EtoEv^tjuBn z^>4aV%h8rrb@r@ioNobr*daK7GzSDYN=zlhT)I0oRi}m|hGo#Wq+> z;bS#m7d>l}rkGHF-@bY|l;{88Y%|$O&S(dDlZojn(DBe$e^YsFDrCh})Pl-dsIUi7 zYRClYkkQhh!UL7|56JPqmJVn0`eZ<7M@Q0~)=eb@@BHYK={UNV#gOB)8J{GBtTI%r z(Td`DNRAl6Ks(9Lh177HQi)9p%OgIhAs;yj%{+d{j)CNVJ9&q{n@k!0@w6&WK`|Wc zk6@D=Y*Ox}sk?=Av1Wi`13d3>I-MS-Cw%FacrXA+SZOk~#i!Cc213pbTWyJRUBwW^Gvgce@H9GW$CXi&~)@P4-pKl}+ zA>JoN*+?6Ii8fk}d?9}I+}hxI5lP6dVoV1<5ltiwntm1T_pzD!h5QdIE5<9hpf;6m zX_7!i>#!`v0u_3Jj7BA~vQC#q1FbdB2b57=SkJ;aEUITco|bjClHJ-v3R2yimXrB3 zTWELECR!9#R%i8P)S+8lZ2t)i1^1sCdxuSkNIo5ZTk>+Zkb~r|jijnm(Re0WncJCR zJ+AUuQ}45>Vy9}@864h&*|01mNwFiQh5W>J$%}a(3T!=>RWDStbx$`O@JV(!KfWA# zf2VZ=#7oDG5VYSPfiwkY^K4Az!@&9CsuCz2wrMUGqx%V9DoFP*^n$03KYnod$mnEn z7+ZXQ)+lBS)&&BYYFL3o1-@gEE^PvO_=`?pmy8sC%CGf@T%5H3;fqAN?f$4>Z74Yy;JS+fp>@e9)($iZ}&aAC&L(Rqlt0WI9jl=j_wXV@5 zJ4)x%X2+a2On3kOL9)#b6=!TobGJUzHs^6b_G!I?09fY^aQ)=dCt^h=S1h1*t9dJb zXFf2=0QVsp-u3XE-nWsiCf0r%Y0XETK`nmCg$U?#3l_NqGk0JTQLe^jw=S&4K;O_Q z>|ccnx8zmXll&}S(H0TlA{2dh%-y@mGofvypQK-paXRVRP25>2=)v$f;G-mQV^Krg zxsdwO*%v`3S;N&iq%E#P|qtL8?#6IoRQ*;sl+1QY7Jec}dPIcwc#BI5!wc=7K$c9_2+g z3D`-(FzzHTOWlQWD-&dt75q5Az?sL^fh+^VJ3;&P9Dx5yEF-J$d$yA0J$vqUdG_4D3eTP{G+wXhGCw{2bZK`*apn}_ zO@uW8R3q!^ux`1}CEc0r6)V#haxQpjc7<9`R{Wv$d^uW=T8-b2*0a}>gq>9mYyIAY zm5Fh;JrZDx@HCU>ou&b4la8Lp8tmv2%`B+gPI4)rkjAD^J0%;cWUgjoXTaB!Z=V_g zs*{SJNElD^k8?G+sQVtEv4A9pRa%TsE`muh!t1l@p9lc~sgv`dO94fbKcOE1Lz7>j z7y&brc%henUZ$&juitctA=(|ju`&cYT2JT4dBObD-Io%fJ%|+M-undV%qy2^IF**w zt)>El0o{t+%H$Z8VNJlmbgiqsG)H_!x1kj*309-E^9il1up6x`KJ)e09}ta<6eL2e zOFX*E+0CQYW2mMR@t!k0BK!M1ud>1Dw|cbI4j-<6k-f&T!bfCmfgvrBP;)xpY(|i9 zxc4?;-90rVOA@$wU*P-33qL&9k2DuF;w|Jt^I|@2^4awAyouU;qkW&6Km4K@IDhy> z$JY2u@rypi{c|0j(WhqbezA_x7R1YTjCL2|57+1~(lz=&oTK^b9i*=<+Tlfk|Zru|3wMChE z)hF;)Un4*|cCVRZW&l-_X@4r3%Z@ET*CASz!NiTNV5KBq76EcsV1~$@saEjn{U;Tb zh)UO25)q5V+_7=QJfUf2;;2Ow_fM6miUu2hbmh+u{9T1*b9_kTAGtH`2Tc|2v}$%M zhSz~U57ivpm;#KTNxK)Syrm_jd)rR3fnX~ZUI1r{q|rZ^DbCx{ozsP-FDm zK8rZhAU7e-G^&JL(gaK@{n*~?Dlht8EidbL6S_;F`f_{|w!6^G0Cvxd#%Sx8=8?r! zXGN&zX<417jnECF)_v+NI=b_HG7{@SK6fwId^L;ZnqS%%t6#iXu^3B5ob8buVD-#< zHgDo)gw@#%c4n|(LLaZ^f|F`FW(W7OJ6nG5azz;dmXpJyC4YXj7I&HAYJB*V*vphk zIUmn3u<)H3I_Y5h_?;QA&~j&{<{r98ws}z| zAC+_ZJqUJR6f2Hc&!%}ZFf$zfR_4XPgSt0wc5M-%m&6_u?!n3ArRf#A1*lM);~Fk$ z;i{HI+LWFGoQ?Tc`2oLxWeos$V;ryo*dwstMZULTpMU1s@l5Ag+YnRUNWcT-w;H9N zm2W)vD%{Yzbh+$tB_6mD@4W8j+Q&AhE-3rrVoE4b7YHiRV~N~XChAd2Ia8n-gv?iI zd@~Ud+xCa+EWOWOfwf8!A5MUZm1kbJB)}Z_mb7(={?V&izUT2QOT=S1C=Xo3!PGe= z!Ao2DN`JKAE3NzJfgCdmF$)IX1`-U#d!}#is84PfKhf~rH$vgNgJOsmUt5SFxe`Ls zg!z^j%&JlWsn^yu;sDNz@#dVu4W5}st&92_sayR} z=-47~s=vW?0-x%%zKztVLFDj%Rx7$?Pk#Au|#sUf>Eh28VTq=%>ag zx_|3QO?@7C@k6yupD`ay)xd!aBpQ$XqkbP~V#S!+PRG0J!6RAC9L%h|H+3v)KP*8r zV5%Kbt7|7bb}CT`{F3}f->xdNoD|~BUE6467UPD$p6;s=+b(vU)ABBub_C9skX_AD`(Usy&hrGNB~<7aFlOf z>dReAfKknz#af|(JqRivSh@*C`rr}5G>cp;V3{%bk&A5%CT5BVWtlSK>ZWSjDW9@d zfyiaH6GlX#_jSsuXlbkKyfbx)f!vgN&nAJ#R8Sa1m)A~XOg4#5Sbc@*s=wUXE`MgK zgz9}V!?)Z~bY}moGkbr_FDJmtm(`7`^GjO2D{aN-g@mmkt;%u=Skx=~JC*-*ddi@o z$WHq-t=?N~*tk?{S}c^dp1>h%FMl!u;i%{cRrW#1n&et2Zs57lT{>M0x)f|B9w~y+ z)9qS_{;xhSbiy@(1CD|H1J9k;exuc@wh(VBSI=TDRZ=v)9M`@c^L-;nZ=DT#VyQQ& z?7gCXg1N-KYI$^B_o~cqP`fM;DXuRAU32+BD;B!;Ty)z-cix(NNy`^@4}aH-eDCIl zV)C%0}szy_OpQo>XP|~$f(rdj^3zCxa^U^3ufbjbw zqFyAi7)7)bM7IM7CkIXq&ar+>D)t}){)-Vohc}3~@@68tLgE+(po<(iZmgI-Act z6bU2OZoMGPo@5kzc++kfg6aE-tYDMSII?nl@7`XW()X z%j!5wKRHnn!bn_}k!x4}MOis(*7YW3aftw@eJwHp7XlFfahX9+cYnvhr7ITTlvW@K zEP6Wx<{f%c5i?J>G17e;gV^C2PObh()ug4I@mil0FZ2-ANe6FTmI2L(RLe%xRaYRb zM&v=u#hkt)Jkuzq3XMx7k5I;4Zq)6_`w&U|V5drxQMf!VFau=)Q8RGl#Dxff30GP) zabK`w{KY^Ea@gAHVSgs;9972s-kw5H6TGeyVc+zyrCVdESFPI2J{5d!PJ$a6H1Vdsn?j_uGfl*a|-4(yS^I%Mh+qW&lr;lcpCGfLljJ&D( z49RRAn?Kv1v_p#_^vRv(<7}|K<;5G@T@Q@s;kT=ObVuwl8wb)w_C(J(Ym;=UAb$xs z`au%+DR9;%uqv;)B}RtE$!oZ!l)-&5d@KB|Z8mfXn(Xvt?=V|#=L%(^-ht&q-@hz^ zRC=M8*Z*0U#aoGof$53JhNN?XdRvpy@mg!TN_`xUK8;td z$-`u{e=tf!ho8^!qQ;#ud-c9(I{UZ%V~zijy)0ru5h(m4ci9)0yG$i3gTU%C$N zZl~tTU|&a8+)7m70^-0Dx_=H>Hmt#7&V>tICti+U4J>iQRt}41ew0PGR}EI^X(?aE zeAms=xX2sV48`0Wx{E*0EeywN^h0v_mwwz@*q)euMpYt~nF~lEF)I+Wc}Vkv^kS2i z3u$)<8XN*5O>uDvMv3Od0g+P9J=nQnrJDye|T++-pGSdq|=_rV~XW!Zbk2M)|YM~Sxg zh1#%YfY1-_8=($D^x_mETi1e0iV3@sr)X{qavkS6-ZfX;&7iG|i#f0~f=Z(vEQ*Gl z-}mir8uy8cFK$2*9pRa#bJ3|D@;*uOkj)9g3sej%8C^k0Q!)S+ZFi1RY z89@8KYFa0CX#=cFG8bd3Snhl~c2ab|5bQ0Ici%O>6w#fpFI!$`bsc(VYuzfWFS*1w z6$)>La!UOX0K9Ji@cWAe02kHo;6jBfn8Y0aiUGif3&j5pqel#Qr>oArf6GYV@5es<8X=3dm*cjal#Jbo_sqtvwoBR@z_c5Dmd3nn*N;vLJX4~ALcWe4#>UBjI z|HVZ9yl|!>V+o|$LNDpX`Crl%*?U9#u*>&Xm(bevIDhpNDk@vam+dM$NiK=^-uAXq zZneLj?16ddo#xYN&f={@L94SjA3~M67miIneouRa-wSlQ9qv_WY_wlhvPjR{k-ks! zV&3q`^RlFW-`{QrI=_%fM+P%;O*)chww&SD?KZ!{kk8Qz=vokFewvkYdf60uX)fSe zAgY|4<$o4J@*jrdSTryUu;?;>Ims{a)HX)|O{-0e9$3z5uRhY0d~)m2i-C&J2zZo0 z45tq=BNt@(K1%axO;`sh6&dJ{FQ<= z8*{ka$V+fR0)q*5i&%|VxC9Q{!!Z3z<#%UMpnvXr;(;F|N^ebp5ls8Alc@COdfNKf zvQ}k$j--VhpB@=_9%70?L=#3@!i%w%BM}% zy39{y4bq~lS}EzNlSi-}e;tvUGX7y}ZCQh~kjb;#8t5#@ZbsQ~bx4A2YvbKwOZ^un z1Sq!983EhcU>(~Evum}qQAx*ai?Wr=ydo?{B?oD#EHj^w`t$bMb5d7_M{lW*vG8dd z6;-*ljjTf3$cVhHO`w#tn73D-le#7lUrPfWk&v{K7m=-POkg&xf1tGUinr`2fk$Vp zm1)l%yXGz1Gs?B4tvXa7_2D+Tt-APbYfI~UOKrF|CAF0ysja@OVOtorzom^f7T8u& zeQId|3O=bVrRTQlPyy;w57Ss~=8zO8WXb1c`948uQb-zADR!#ZXvB(@W`ok*Eh zRe>vIfo*-C98&jOxqaQE0|}MXQ#*CeUKZc(Fr`cQ*chu&f56Yi4DX$Zu?sxJ04np5 z8#^>xVt>@9M*WE<{?M*BE7_4uK)W~|$$V5My?GhUD$r((3p_4%<{7)1Bf_H9d(Hb&z0f2E(9lHuT?f`RK)_q_UJx#O!aV=5|O7j8i8Uq2! zB%jwKXQoir-cA3>0_a$R;F)==VLGN>L%O2AQ?FMu_113sPaQyKQ?L2d>yD{6=>k)C z-8Gh+dTTfRr{1K_)EhqaCN%YZi2M(%z9}avGGmc_e-I*wyfc!rbFu{a@#o9%hyVGT_mTgEW61={k5tbzj=ew?KB3H)1S zXIUkR7DHOk05^-_wrf@d&pJ$>lVomsffQ)VhE!QN=}E*(s@*R-6nD*)SE9~xNIIDp zD-TO-e*wSn52ZHK;07X=`4Wl0a3&reUpZa;$I^wDZsrH4(?wUfco2ea3FdYgvFI+c zTnotgJ8IHg!jHTVVsC?XJq#1(JU&UQbPVQT!GPgMocqcE0V|3>3Vrocg%;6PB>cLJ z#nmM05OeTakAmATzFk;bbd(&e0!xLE`b9WVfA7?a2t3IbbHVp=L=RnxV!KrQRS+su zNaIB4IY$tS`%1%&MSc2-=)T6dNZaEFr>g7j910Y+D2J7Zcy&ZRgx%?VUg~(y_g(X- zL;OOJ^9YntM(=t!_r-dTY_VVP%5;;zY`GZuhnKCVK)euVmA#RPNBF5XDfJTbOP!U1 ze{QL19W~U8tICg0OpqlTXI>l4=iQ1xpF{KVO^6cI9yY{aTzpq-i{MVa6QhAnprC6y z+P+TfvGAzL!&nE&4gslG4B7rj?oDha{)CvTDK8f#yIEOF7a03S=u{8`Qe-*UaDnhRgvk#wIID9m;u|5~GY~s1P_SuyD z%+Xg~pJeLQmF~+OvgB5(l3<&kdf+WOds|tq?*c;Dzev>Al?XID79I9OYtYqY&V9_k zLyr@A>FWDS6UXEW*$>wd#B~jm!?~4w$REd%+Bv^g0bP0O+x4CLPmAaNr9hXTYtJo8|OYZ(f-y*dg%6B}ZM z*iBKSm9DX}Ih)sPa>8O316lG^e=w0|pkWmA-yUw?`~SZA^Vj$PpTdR$V=KA0?c<`( zivTWy(N!rf>JTnkTIm{>gbOhX9~X5L7j+mHO&Y>Q{D~&wq6y)mrIoI6Nw^Trd|Wh9 zTr^=^Xq}AWTwV4fbjd7vcL@x9|GOxbIw2c zSZAuuYI#9GH1ndvdH|uzm>-?JGmsGx{^%YM9f~h;`EL1L5L%>uS-4Ha#Xli4ID73QPS2oM&oYoH+oG8Ve@jThn?{^RPavG@i6cR+~0;Q$AAtsu406CebQmQA^R;iWFTp~L{v60)f*-IB8$ zsuVHxCU$7DR;V{H=4pWw5LY7#DoDQK4!+B(*;nlf0!0XTM^l$0J^I?iWOVB@bP9-m zDh`0ZWob3oJilX0Ux>a=27jBk@6kdz_$J2k760u>$P5PHb0-F3=9}eK#KC8aRW;}U z9eP_H2ts=6Goi!tkz=)V47I3AOZTOfvB(jPpNvmZ$`30O2#JabizrUE4??}XD>tuy z0QgpvOM)Pvw@8;U%G%t$fr}#vv(B2I%6V0TAc_C~GPH8NJ%9tWpnr{QbGuXJWcx5b z?AFR4D)Nj`{grJ498}3y$@a&up~A=i>vHuo zaVFqNaPM0a+sNM%^fl)yB}vt9$ByzhXm&Z!sD2lPMtgBymC7vx0*^+ULmYUpIsC26 z3n=nnvu>wX1Rc|nJaDArD?JpTfJ^W#daTj{>yw0~Ou{a-5`Pau)b?g#o;TH)u*$?O z&Q;vvJozr+O+^_=mxPkqNhLKvRS(>);BnWZW{_J&Q35oOa3tS-m;4!me8G>+i?7w+`XGTE(@`Q(h%_V{lgsG&6@031s++MZV5yB8#<6{+q&>Z76U6VwFAp~ zYAr0s7H~6c{(snI2@#>sOZj*yM6!RSU8E<-pnSs%8yRN;-zhd^3z z3XvErL5@92#K<~ol3#u0j?6BFaWOpL$ZCX=6*=_{kbejIL{3a1r2WxnaF;xw-jYsp z$)^O5+9ocObU)FN`Bq}{@}LNB5w)P@G!ts%@qq1sja#3cPR}=Xgpwwj5Ahb*Drqf_ z(LJ}v4VeycnAh@OBXP^P>Rbqq?4faR^Tg6QB_3>B$r$z}OeqWIh**}8prGH>>`Sr!+LZH1H*@cq!%xn`#?lD$&roAuQn%v(E z8Q1(>h?R|TmyPEdW0r~jiM#BQ4n4HM+&B9=>;sba%>CsHfn)vG2_0FMI+gru z8QN;)CLWbZCw+VI5zQ#6K&JU5p}OKbS9voghJVA9kz^`yx0%@-+-7tjP1kEC8k$qz ze94aRY5!P<#9Gbs{!2}c5%(0!Yw9g0*DxzwpTkz4#eQCYx>xFTXo9JS9r?tLE}X#Q zEAt#v2zrAfaNqdAyD0K>3g)4Ig&oNv;&aPu7KTK^rdRhE6h>%!HR)y&GY3n{tKc3n zHGjN^VOk0tg&caj-vlh;K5m9$e!TbCulxLb2|`?V=a^Ccs>jM^>;zTOaY>wTt_FcB z{$Bj~hk2ev!tH58recmGd#$sAS8Tdd?q_b_P^fuoy5FVnWM^5iT3}?44kW>$OC1hy zRU<=(eFi?3=|rlo!DFx3Qul#On7y@Z5`Vry7UzU|0$q=02#=%`;PF78`x#H4y8iv5 zNkV^#I11j-_L<3IWS!U1jqOY!xX)Qy663OR&nyi@tAbEfX@aVssI)lecGN~4M2YS~ zo(I5J3k1M=-|I7Tz;;T{p&@en#wC!Y9!|NN&;LBWw^`@rMwp=v9%4EUGo z%l0h5w!Zb#gDCk^a$mjv+$LRF-o8vv_oxa@BYCS;VzF|11>4sApdzqF zp3{~YqfodGTBF*oJiM*i(>m2oHmWacWTth(=|+SWzb;M@HLR7{f2hh2wSNqb2ui(D z2S?uL5gZART*coHJZR4${KKZRIMh8Qqg4ElvTr0K8BlDOKpcn+ZekxUm(=2sfXB;f z5rn&01Gv!Y3U#(p2=*>qw;@!H7T zyl-%9Vg)Dn_|NJSBM#!29^{Z|*Mn8y7 z{EVh)B1g4-tn+_mkAE7F7EMwm{+2^orbYhKLi|^jzjF; zx3(N3YtfTrjU6VE%SQ4ROLT5Iv(%uvy1AF`o!l@via(v+U$p8fnd8Q- z&zw7+Z^($ymEfhvMgEU$0s)k9;>m`ZrsrJQnQqz)`g4Ij*MFkt`cu)QA7zAQ-mxcE zt>V<>DeKL)B)--2UeX<^I~lz!lX@=BS_ET9 z#py<02!2QETYpV@-gS;yHa^uShDF0+z4Vb-POGXrx^SM!@Ks{yCXrl%o_n;UL=qW_ zu$;|jBP%8)Z?faOZXi~BBEPLu1j~|oIGfie+G%N+PY`*K!&kDl1d_9W4ptt?Nbt6w z4`Mpy2eFppX)d31+4NapRN*c>&Y(vBku`@JKNG^L*?*V1`83Ujlf0fyQ}Brr3UrZ; z7_ahgR9ht2`6Mp|*t3;sM!Lhx)`@<2{_636{rAtW-tDalbRv#ksdo3n&+p#7dbzS$ zDCzl1XYlyZ%U>S7UDXUw*uUBtKpv(QDRO-!(Vzs@A}z&aB`YbZbW>PN#3W@Df%A8r ziaV~b|faYdn#z3uBIU~Ywz>+c#0c(6-H z_cMY-`9TLuXyXc;F{ovwADM31!?|b;reS`a69|1x($n+Z2*Q`bO)kha^f27Fk-5AF zcm`9hcx+-@Zf{yKBdmSGtqoTuA=;Ym0NwS~Bc(rWrz8D3=~uBEZ26-|`DA2YGwIS> z+ka0;sah=8q4cCVo%V$U-~9!l@xLt&k#hf9XdS3GWDj;HFEuZV+xd)XDYm2<86V0d ztMJJmoi z4N4cGI)Xp7Y>z*|466S&27Fs!vrQ?(y?_33a?k#G-~Rcv{qr09=b!DL-`YP7w$V;+ ze;wPur6i+&DcijHrR?(NXKwyPd%XTRvwvB?nUQ3`#6d|L<;~BT^`=2%y!mB8Z!7@P z9#4NrflC+6r|KCpdDNq2w>}=nMZbWeo}oSN_0@KIw;bN_jp3Z!od-AgJjmzM5`SoO zKzr_HfuN^dD$<%}5^9VE1g+l#!sw)UjLtr|3q~tf$z)j;CM=>7sIK+ZSGs|Illwiq z$TjG=dpCJ^lGjO{DI1*la}E~q!%qo#1bl?ou!5V6vqVT%U?6`Z{t??Pn{FjS02dO8 zzNP^y-%(x}2*1G9Kuqj!AJ}iIEPtDj)NI|$<3+mvVy3vn4*fj{)~@vHc^TR>9^;_* zlK2vvJl;xtM0jM1wRBUGXtt7)5esE`;AUn`e+k^oICO+;kievAGkF;BjWQUP0~{nK z7{D&;j&s#n6xXUEy<5J)n3uMButFWMN)vnQCCqHRm5lI`D7p37V~ytmMSqz}1Dk!! z>t<*!_s$(u_63YeUwsWYbfwg$M3BSAoZW>wALe2aP|C>0cW!-VbtDqpLfH^XEd}5J z&nCBTpOa_NA^1>)x8&FxQXyMDYMLq+B55`d5@041!~7q9OQvu>OlLD8-aS6ar;|b7 z0m6z}r?&MZuR*@M9(AkjA%Dy2?b8!A)qsUsL9jm{Pi(?&qyH+5C&wARmQ2SgY6TR(#Yx2MDhjQvPyP3m zn}8y-m9o$S>K2?Sq-ei)z09KuEZ!3Ed-2P>?B;91Na_{4vGCWz zqp3AD+m>|1y|2Q#ySxrUYdq$`D&~doiZ2Dc*i<~0AavKwT}Z4D{ak@iv7m95&d)W^s(-a&23oypEWo}f=sg}( zX1Cc;(4xxN&UKu9TM$xdu-8f2q=|}*4e&k@KL_5>)=}UyzSNfyO;N%sAlgiMB)g(< zU}Q8w`E`H$KstWQzwaH`c*DO|5N%k+lhs9qERsGGQG;figlKn9KE6s_f#A&I8}SI4^^E=)T#jVAkvZ5hJR=wy-kp>$RsSLsm{`Xjc}-J z@{BZF;QB%J<|3k>dHkn)tJ1x|Yvd|5ub=L(4D$O|4Efh9gZ%3&hWwkALH^AZL;mNL zLH_3}hWy)=LH_L(L!KX>Od(U;7w+qLz3(SZG?soxZzxvc^=u7`3%!-lMn-jL_O&wp zl!JNd(|<~%d|-?Q-@rBCN{;7y0>UTFmu%uH=#&&vl5b0$3_``cnv$0qD%z}yxJb*I zyqVIn4=18C0aG>4sH)K?bfp^!QUE{<0ScUU;~fcWa( zh&*~>0nIOTuW+I$FmSU#9@z^d>gxtTg029QSbwKG-revzQR9r#k<2nqehUTaLt3?_ zl6*|k6XMRIlKCe@O2Ap2l%(`jR?5Qd~ZBKJ&j5-kC- z;-X<^yh7c(7qU=)*y50{TS@Wqf*6u1M`a{khuI&LGOJFBqp4w2;v-@^ zYggsM{oxaffBrM^zv)Cu%!eU(KaHTrcE}2qMe%(a(xZ$sn!*PD0=U%3D^stQiKc-- zZH5Va2u}iF;bCq~xnorxUzI60&woeBZ8f>kL+tlKOA9^p`B#7oQB$QR{rSx^f%;il zz;ldfV`#FusTHo4J-X-=7TCzIR&{=;I_f^Xk8vt+^FBUFi{n=FQ`_0;A z(IR`pv&aVCPHR7m3z}t##}2i}Ds<^zfry9*gQKG|$t4iaF`Q>h20SC0cYl~YYk!8( z=H(iyTQRbO&_2PC}7_xST3@R9!=`}>IyPuzXF?3Mi8XW1^Mh08^{csVa!SUl*L;tP{ox} zi*5D;K({pUhy!p&QL`^Lz<&|g9Y&SBjU&MvLWii!jV5`Od55ldgK{mDr)H{)4WO4m zgR_?NDiAU24?ez1|`_)Sc|Ebu$;*guY7Q~(&OD&D~_S1;K z!DuGh6#@Err{C4kh`^>R>KRF@b1dD6I7=E>1C53{rL14!8O0x{>1{2ZMkfj@BJ+TDBQxd<{3fr*bhPuWcrQgcIWqAH!_Wqbo2PUqDiL{5Kf)63naAxX;3hS;`s zjeS6EVNFLJ^otJyiYBYZ*{pdCJ;`%I)E{K@Oz4SND+j=e;(zd99?ph!HQpof^;KPM z_|su=wHK8_r1DF6X#;Go(Ty*9KYl4QqyyPKqU46%Vm2c& zdN#N-kUwzu-AO`rO8mNMSChImnFVzM7L&PfIeDQO=eS*79StCC%?NWCl9|hQ9G2}t z3pKT`ExeNOOMiF*Li@WzGP`Ibou!q+aANw|-h#G-Yfb1^==L_H^xorWE-bUTJu8}l zJK~D)4cL^+r~wMCv4>aUeKT7ajRTgCJ!Q_)Mp-hG>rEN$;AB3xeng~96S-#}xFbwT~RZU_{ z%&GmiaP7aD+IlLEy3?s(1c=S*FD?~WX`iy6!0K86n3izP_fY2o;6@DN-#`x5%>LMf z+MU?!L>ryI=~^NHSVa^8VV!6}tf0qT2!E~%!2R=VL8v1yA~f)2A-kQRKoPYe$kcRN zSxz3}zdKq{kv}b!w-_4)=XkaU5r*r;DrQ?rDL7OmBM&D$lu2*ngtx;1O8w_fNDriF zI64xGqR12fj#c^_sbonp#5G*v4)F??q+=YShYey$9?_pkIOKNjZCWIzQzd4`iGOJ^ zYHB5?5Pyl|-EtKV?@VVQ6JaRsVF>Eaa^kj`;7&G18InLx_B)?3WCxE8zA{u^_AAN$ zc$MyXlWj`HVu6Le=;54=V#7gG2XdCTXW9EUPjV7y)4~!L{>aKkWF>zTbBnjwD1e}z zV;DyeYCR?E{9oB8eOlGgfDqC8CVzm3b?&(lscf&@_03&Z_bQNwu1&|WDv78cMFr_r zU||MHBU*S73EHBmH;yUaDx>0?DNDHcTaz0^e_8IZcjg!q(2{W~HN&i`98tHNX2WTD zJQ&G$T06YOcC`7Go0s(_zeG2GL1Rj{hZY%y)PELKZCx5?qBX!G5f4PSC zi5AL>dZk(eQKws~bYekEi1t8r9Z*dtAGBxVhLE+fk<8<=0jabgmra^HdG#VOpgV-q z=EAzlm)4rL`ga$5ru4#euVmf^svG*jfKEngKAfdgP*?;g-IvsKxnk`{26r{Hk z!i+OkX}~xPVZR+t=yb+vi?@m{%%sF5AJwfCer&}>EhcZWzt6M!a+BB(l)u;LXg;0R z<0{K+gnJfcHu$#Q>m~b`lZg7Zu`G9m2+GM;@V>oL*b2NMQE;qNwsk$P*)>8uR2g$G zls+{}p`WtQi+@vllZ1a*%9r!^Tlb>1w|md`9)Wz9-x$D`6R9nZOzs+IF=>dtld*+^|h~O`DHkpe?L|w^3zW(Y7`1 zI{s{6(ls6imL)oJvRz6{zAM4&R|6Fa9TBY8bCW+_rGE_`^EF@bHovayNWJ&7lTyi3 zKkPvoP~Sokf`gG%-QXKuC{?9xFjx9cRkXtn@2AYsyQ7>}<7@%t6`$CWW_%=_?1ew1 z5v9o_ufdA!ISBMm3bkbqhTeDhkJELsnmM+WWiGAGMJz577)!yPcNrrjC1HrvASaIY!DXI)&AFDeG!PZD+ z1^NmyTAh2WTRslz3Wn^)9X=uC-@X6OgMIMW#r*F&;j7}=vqs$~*s( z#P<$X`O3(TzpCb5j{fHbh*iai`<)T1Lze$iboCaK=+z?u*^>;`n}6N{9DR0&1$Y&^ zV-@?N)%Vn_N~d@u?dmFLqCv=rd}Fk0LTxRamJl{we9ti#7)%Rc)}282gZRWCq`biN z7zj?j{0_c^y{qhj))v@%+n)1DTMRiJb`aA00wM*ty$I%4FuBvUH-hB$1hYEc!^iuw0B*hA-{N_c%e9 z1HiwMc>sggvD%Sr$(Ly%Sl9nU5zraF8nRk06Tf<)ETs|+=BJ#v`9*>l*`LoQP5}u` z1%>0fCRG%Dkt&@o+x*6m`tPb6Ls8l%td^|HT&|aM*LH4QjeoPIsDXZ(KYV&N85r2` z9i{z^zF=sxxR?{T42$4I3f8L<@`&sCz;l=O)G|pu6!TBeu{nz(tA2X-;yH*Va`LuF zRS)D*)pwn0l{Fvfcs+LUHC-Y0CAGUfMKR4@(qf0QhhT8dNNQZoYDU_H&wJ^EPsL7B zC1D+A;)qgFF@II^T=sZu=t=O~Tzc;$3pE3uCc5!z5T_cOT<8IRH6EW(UK;H<1*sq~ zZRSR*)Ffs3S|CUvvyb;{$Zr$^TOiUd5^B`=g_#&G?@lt!bcCFo*0sRAT)V?8NyTbb z6}o&mj(Q96MatWrq)i&yd(8KY^0p8Q0e8N<$xa^ucz;AcBf(4P=l^{B>g74)8r`YgK1fvV_FsggCt#94`NzK z`HuR4Zw+c4vFw4K33-Yw9nZ@n`M36nJj%1_gaBbZC8K;6t8AM7pO#gU3HBiucMH;O z%OO;{aeojpBh8+ zSnRMyKYJSJ*dqMOg>F{`!9)CaN6r%~i?(cMJExi>1M7|?Y1d691ibv{6HeOeH^gOd zwbR)wD<4b?x{#02j&Yk#4GMDyk4%6p`fJNG*HmvTB$?8{tX z_KSV`(t6gLqegpXFz5OUi9*-~axmK8#l)WuVPz;#oeK&~Mw{MV;9CI?5$Qe!QGf8o znX0rKsUy?~S|Jv$NO^z!8?KHC9N$;03}Eh^l{NmYaJP^+-tLMJaGLR)V|>q;kXuZD zQGaVivRyCX&4w;poCi;#kpbU{*Dn3lK}F~mS_y=aP`OnqcO9tA-^ zIWgf7h(Cypf)HI*_tp5n)#eX-rF1`&cL>`1E}N+gK6tsJoIBiOkm7&9{Tq@vB?(K>i--9ZX6nE~pV0+OH zyq@-p1Nt&k56>Kn>RyCvvcN!Fh?pu`5r~x-cQd)EtFajZ_{n#&8O}`<+`et+!vGQu zpr(L*mwcYl0d0nv2i80z-O(Lmlk`r-M?!UQ)m;>6X$|7K;tS62-Ala)a} zxnjuo{`&6Go4rRXgI`}JU+pZabiAr)xB5~_O^)Q(=;3RINnG39S53z%vqr$b(_Xa& zp8hCyCw1bfkie0fk50-e|A#o{(rG9(oq5PZs%=72O~1xje^xd57`_{b=|FKO;TC9H zT-UloYBjL5x>zC)UN6BpI-dmsZ5i}#IlwD;5Uya*tvHwwD8oQn7zJfx834F$$6sV0 zEE~@g!EpV<<})Hjn(QPx?F~$$(o&KhL6zF)Wd_AN2^%bgbz8+*h_G}77z=>+W?ne3 zNtKra=&89bf7}%C{R1se5>V;(KoNtIu{UO39J{yiddQgaKg!bj6Wq&Jcld;qlRclv zn)*$ZG%WR(dYdT>*q^Ja4Q`%!Y6 zbQkKWZn9Z>S8qiPzb^rr)03LX9hAgxDpghVCbmyjlRVy40lt%x-eZ4#JIlsBRD7sP zMNy>UsG1MoS$)J=&*5}++J!=K&kj^&(VWi~_$E%;7#K_eF)ny}hQe=JvO=%5p?C|p zHEP%*-HtTOn%8#Z0h%LBE_Rbf5%9z03sDeqhETM$%LaI>feUtz*fUOK@@LFRLw8U5 z*WUGjT1h&!PE2ouN;-cmwyaLkWfcNhJ;k4z1L)6aqa2J>AL8&~4zOM|AVX2fQlq{I z|1JH9L;dx|^Pie#hM~OmfKXwmcts$08_o6;$r^|hlnLOZk|NX8OH1TH)f__K*(AA( zxdEF}hpVS(H$(VGmtDXO8I5Za_PF{avIXQn;UM9NGj07w* z@rTLGIy6_isvPbw0?=;<;AZ}tTCUdpEChK5mf3I;Ju;pW9z=hFASc1W!&UmhkP5l6 z=?jCb+yR7BCj>=V2+42q3HE0;K1qvXo>P~ZJe!le9?I$fi?Vcn{$KMHH?4v80RBOp}N1lZDQ9D3%lk0QtFG`V#pqBd-lx@3&c`v_PS`4g~_eY z3hs0IG&Y=0)ApKy?O$~&su=eZ|8Z^Gtqj+33F;G*c#?9lSy?ywAO;Q~v)tEz5mMq{ zbRu}#XcJtop~4Paq>(fTKp#V)SRUua`Q2Ne_k>RL7<7N4|9L%~i!vY-;DzuF+Uq+u zMRbC-4o0tEy?qCq6+xg>Sp)0Uta#JYOSY*%FIdMWwFnrXd^YTdCvt zBm_INkYk$8;iFw!Rdm~QRfjsHiM*8WY9lL=Mkf1VM>}25Ha!%p@&51gQhTLE+y3zU z)#LyA@1K8Pz1t&=i34W5;m_~hy?SXIjnm>Rtveb$e)RH}M{h}^X{I0V#oIs~(xfcT zy3zkw)gsO0^>9}!S;;mMsi<-n<|UY!Z@=W}@O-S~6 z8KH!edmXiZx<@MC@2Y&CRQ|fF^4FyDH(iy#A(j8!Rr$}P^0!@;za^FP%KfSS)^HY<^V!OPb_lPyG? z&!c}$oT8gywl@t_I})Z`GhpeyBa(rmGSuPYJ$~l!&4!Yb~Jh+s@MjdW4t20 z|_`RkE%&D(@?4*hy8d=VUWsI=1!} zD$^xxq%t3MwUV`Lvzk02jkZ!R8c8FS?xlaDk*q{V8uwU!%uYg^bwWoux_uoIumAcH z>A&f5;7SJr(xi)Py(3(!>DuY<$S&tklH*PA@|uDK7jYe}ppI=a?^?j03C}{4W=8{A z2^vu~39IYpms%h?`0N8oV!K`jxDuPqQ^Qm01=4Gg5Py`PgH;%LUf&VLjiBN)2YDkp}nsN52Q!J0BW&|9a%+N1=+(1Sz>}jxPfC%%fp<%D*zKqmF5jCn~J?!kJA~e zcv!J2OyW{yVzubcld^7Lb<9P7U{7$`h>-?NW8E&X(S>bX6ffdM&$vT2^g4JRbgx-Ol%C1jheMhaaO%A$8uPt}?B8 zc=bA?SS}fpuD`GmB`c4pT1W~B%HWIgoIsXwhsbjQ3O_wa&6FDYt%!k*7fMWlXqR)L?P;McoX&rm1t5?wMJtxY zwx9ElYSh~I`Qmd#_{kKv%y8ahsUbMby}WZ(ol4Ss4vwUgOjBHbzt+76P#fN@+8ebS@RSk$N`MxFzlLsmLtC@_ z^KoE>ELE=@!)omRg06c5JQHfIK`!yb_Qg@AMiV7yHNc;x6})%jfNKpMr0W$ACSPau zM-#gnX<1k4VzKIl#lfXN#sVvwkKa?aG7-daZM*;0XZYj1W&3~AtAAr>ls=4_#}WIP z!{x%(w5W<4uccfcRyuk8x0WvT7`j|dA+V}8Os^5$B4>X7k%QF+*hFPYpt|!lGcBR1YIl83btlblNRDUuJZ8?I`r#}qH{BmU|XIjh{oRwPHrJl)kz~| z;S`_Cqu%&YDHP`7@1wlPCL?cZ)C{>A2nPrv`eT(S$>>~lVUg* zgFHG0uS*jz;Mv{_1>mM^eCOV#Hv?`qUCkWKTO$334wQc~p2BSY0Cc-7A?<&-wKv<#0n@vP4QL@;hvLzr^(ca88ja&(CqO&eREQh-zig`9vJxcm*tSC^ zhdm4;6NKY&Gr+m1IR#%cDx*qUKNPXbOcJRrJ_b*orFJch^iWS%0X~oh6!-$Mg8fha zgzYWLMfdQMWYYh_)xTeLFH>9tu6X>oliP+^K&xut3=o0YI#@CSr@5-52B3*V2VWC8uyf}U=MI|wY zP$Y)}y-RUfg16YpQLF5=Enae47bs?91;kaYXmDlvE^c&P6!I=>X{>qtx)$cSfZ%t! zu>kZQI}31pS?foxGp=g^|LW{4siOT3HkN-x-DRx{xmCLQb@^Q_gT&NjEd#sDyPkFU z-5fLuSC_RC+^Z)Vu~yACgMZQ{bF9ZYxd%(1A#z4p8NJleRa7qbCb!Q+58b}nC02mLJQ4f`^K`};_!R;*iZRDE%~ zayr9~Ljyh|H^LX6AQ@10?2TxgfLA#^(Wy^7+`V`Oqgi6bu0vE~y>nJVEuy=9$L@RJ z4GXu^7b4X@>_Q)+H$UDahJ6_Nulj$;y!pxfq_u3HrN9mPHNgx+M_`6eA(-Ki*AI2X zU=s=UqAya6TbVZPIxkZ~POvL=pL6dKLy6W6kSKMu-1G;$B$soNT;#%B+N0e}^}a8; zo2&jLt*NVJOY|`M*h38&_R2gD_GQqgUWWJTDd64R=G={Is|FzDxL_^roy32g+etg` zU<>w>7{BJ;sTlr3(tc+&wWZvP&A9eUd{(y3jGm`-n(g7exQ9cN)y&1gY;(JttxFev z^4%1Iw>Hs>7~9bq$&2HK7BKOeL`jbT;kwU^C8R)DNGCQL7b(+8Wgn1R*>v3GXF7d= zb8{k>i$bXjmj-m~L@4JS8lZojV#oL+BjXFb2!iEwm~?0xuQhI-((g&SqvX*9I zVOMkY+Lh?6wbnFMkNV1LSLu~9-o2^~&ygT6tZJn0liQcZiLM9dT&zkf)_?=@}Guvp=WmNH3Rv@wk$_OeVA z5CHTntC~;n_*sFC=qRPuJ!0#v=4sv1|Ff1$1=1xPbmCwn-ynY-Gi(c}w9-iD7%-tt zu9B%EWScxaeJ?RGl=fW7G&<-rk!gCykTvi)Z*Bupr|fdH ze^cfbzqxf&t@h1>k$r6;MTTBtVMp{;BToG$D1i!sHt?$Z#fiF#E2pBU>sZ4~)Wiov z46DwALG$=lvU7i5s$~&a-M528`iw3dI(GJ1wxg;%brvp++s;>chPCt5@O@u_vh?m< zWVoiXHrZI!Br|vWd{alm5JX`*=@QS02GdDuaawC3HZR66BR4p@_>=3y2F;m ztAscp6Ae72T_iAYk3?W)#hsB)=0``|VHx6nrO}r+QC)xf(wSgni?mWigdAeDzz6}U zz`C%<)?KfJ>lRN|E}Z$tJjSWJ-ww^IsTVEWgwkCmUO3;9i$n`wbfuSA>o4H2AtegW zeU6)@&zBbZn22Mg;qQq*oTRPd4?d;TvK_pp)K)U`oDzC*NvfA=54)F#SUjo$$q(}f zo%NzKSP*~mQ?A8zQC*d>kSDMn<#d8sBA0l_9!PdjWFPwU7wIrB{@`Cd=?WK)lpyM_ zi@3zp^??V*ii;D}0)Y`0Uj4-vKeqPmOCMYL=)&`L_m&+{OAOat>r0k5u(~}KRoasl zSXLQ_3d{%KcHOqp>|tuRMc?K=+8-U~XL)ffgYKTPf$-H$ZcgKAkMo>e>wF z@FVP2F%MvHaFYjrYkR3o89;!rcGPIPEv&L>`hQwhNtTM$kY_q%e3C<`G~vKqqziv> z0x#p%*&+{*%4$zE9N1eo_~u#yG2OTZ?V48M_=+c^~k8 zbfCkLZ?Yyd0hNN_A^y8#uY!c&G9&N);40L4J;+Z)-I3$2r6%q58%VFES6k(rdVG>k zCj(Jc?+W&A&r2eH=U#-x7$fcqsCa*x*TFZl{n)6-t7Uf{!U$`C3Y$Zi0*Fj>?XR10 zQ&aeb5S#i8aar_Yk0zacF1nT7Yrb(Oxwk7yzlS9E`JFq?R{Tx-XdF#T!CRHPhJd#` z9Y8j*K`yf?>5a56d*06vw$vE=za0R&_w^55oF5!eu6qUR<~dACKsMW!lU;vfTzs2| zd98FsuLEgfm@T>Awvzj;xT9ARAOx6;hUgi?1d-K9eK_%XHPzQ>6l4GkOabbPjSI1J z_byGjT*$}BW>*x+?FY%%y9`b6=)Nh(GI%cbhVdY_1-A6wFeu!?GCL=B%%%6ETfF4#AfFXq8s9NB?K0b%#{kAQ;DRLDydE3K+G??ol8y^9z^2#J1 z-RU$Y(}i~WTBVy2uG$aB`Yo33NlhG;*?pM7K>)z+{xmEW|EkMCEC_!LZG{FWhC%Dy z_q#%(>PflH zdLO7s9avVli0ILCA>&s&wtW=sQjc1R%mCXC!psQ}U4^`JhR(v7ejYN1P%H(NWuM`B zIGfiegZTKKe}DU6lXs?9I@#fCejO(au4b!dL~eE#TUFe*MeCL=RzL#R zcs8RWHMpy{A(7u5c+9P)+Q6 zWNk#xUC3^zY$)X%a@`~qWIuNEfk+-{=z`d6E{Q+V7d;wSmCk<{J};m1R^F$C^Lv5o z^$`9CM!3GzUJ{Js>&@#0Sh~WbUJK@A3b&Oj>%6_}^zBv`f_46n49=r*IS1~RsMzD= zY~tSCrn~xmK2vv|D5v#I3u0{H-M5^P>uh`XDTevwCn3>fG?{k%k)Cs($P-JbX9?JE zj|>vT&)eKJ=>UIZp92_)XJpcBx`!u3KNlx%uU-C8V=KP+EkBIafiRb|tt1*VMCdd> z=!w!1ds$LFab;H2zeH5M!YTuk*i9OJ=7~3He%uq{>tgRx=>=NARy^srHq%Y^nHBcp zulQBJ54nALC)p-ajR}pgR5<5VW7VF(vODkAfd&q7@k@WNAm9plcL^l+i62Pw7%+|y z2|MZu&$!>)EYGT?yjTg|#|)1I6jC4}7k9W9ajH0Rln@_0AXi)Go6F#)H8@YdCYm5)4N-r`jOiw^bhMb4W%Bcz=MW3JmhOx6 zT(_=Uaip4wqQC1kd9sG&_OO!->?(h=^Bv$UNH7to*QwC<#%Td*Ku-iDNvg zExabkXu@2Euo%l<oAhEQUA%#3stcP$SU%MLRYBb)4(tlWhDRR6Ou`;(g(x_v9q41?k*$y1Qu}%MW#5 zewDJAeo`jn8tk6X|GRguvH$xxK&?6upbdXThXtMVmc*Q#)4JURS|KfulD|HYM5!UZ z;p7CNGkqmySbfNajGBz~q?5Ww-AQE*|%D4+Uyqq`-gUY*H4aC?4Zp*kw`$yR^=1Ouo;?YR>wj*c)XE zwBSTASwn+{ys@KWSrfpFqRIvZAz}FC$QBIyK|-{z$xY(x{`R(vX`=^g(q>*mfD)(V zyX2c~>sSH2l-@0>s$!{UVofs$r9Tu3^eLC9^aVt_$gtSW^}=^H@wm8Qm7ITTp2UL1 zMwx?;{saH9_S#HZgU4v2kNMZY#Umb_BiJz%^XG|M0_fF#>WEo9dM#>aL)qbrtgh2z zkakCVAIF(=c@CtP9vt)D#GXFmBAgoF+jxH8==f}Nw324s( z)4==AEwe%@$qFN2x9C|*UgsGwUcY+#4t(MrDDK{6wPf=Lw?4~%1E4m@*MG{=350ff ztajTS*rjmgAV_tZtK;P^7@c>86aogU=E2YJp5FPt!MRhA!&hh0O@4p*+cGJ$hi}Ww z(FG%1-))%$4|&EOznkMH4 zW#5Y?stQsjsKoa3ckbsq_}#Lsi;^G`e$2XUDvZ=ViQ2UV5O04osZXZGC-b&Qs%SM> zPH=B0d9zLw{?oL2uaHmT460Ty@r@F_YccIq6>WcT55srWC+q|mk?l_KAQ;B%_7PQu zh<7g=WZ$-@8X3Gdg8L!m0&Kb*Vrz>aqlG{VEv8Y7w(aiSwr$(CzJ5>cz2`eOxs|NSN+s)8Wu``rIp!E|=W3k?u|gGa z4|KvU@q*B-M6npZ+XDe@?U2FIBMc?BC512t2l)K9=RFR2y>6r&G~9|pe@_mEkqP>z z(=S*>9QGZE4)&w;{z_btp4*5a__-Rj1Mf+oPEeP+H%CLm#dmJa5C>vvFBk*}Ig`TZ zR-G3m32+)qx*CfHj{bYGm`YrnG|OKkgqcDTsSuwu&^8^w`{V{#1xAd=!f}eXz)-7U z@Hv^7>i(5vXs!)=u}Oojqa9j-b8L;FhVdmc>G+xSzvTJ8p6cC{Wl?@tfSi(DoVdD3 zxt|w49Uze_xX_SL%a^OLmP3-4)~$;C1r>Xv(3_N+n}=Hr(wD~U4K0>cAsJPP87Fo^ z0>_VmFSv=(LDvm9nZCfsc&Wxi0*IuPv~_kuIXg~HCt5Tj!G@9qP^I)|HW({Ew;~}L zr@SL1;E@C#)Jj#0Z%uoie>Eh_qa>Eo6I-NtZ`QqQr!oq7u0?HJBCkAHuKVWr4?0q= zLMk9$__@8<7(IUBcE_Tzsbb64G+tA5&GlaznG>_>U1U01UcZyFI~c6ydr2EWQO ztvWMF?yMA!VW~3JzKy}a<%po58Iw9kc2P*b#o0YtM}<|8WTW1RwUBlj)Y_|zG2RS| zbdL4j2J!$w%BBggoTLQwr+?rm4#(1|PkkCY$Q>=|1xJ!Ch=e#rV@GXWl911$j(EoY zz?eDO60HSvPcF^8QZ6!e8_(vNx1*AnxELmcD7zRb1LHH=YSJbr_Gm1%g%Dw{<>$WnP8dGywWj>|kaqW=n3I#`$ zP86D(?|zb!@;UNh4(-x=R^qw`1KPZYZ&<9%nIUSN6Qh*;nK`>-?^zrla?j=y-{6MV zFYU;8;i$KO8!=PY?ntQJhj}qJrJ|~1=n}6kcb0}Aw9nndYbx+bhi8goI1`q{V1xrP zO(_8d$Z;*BO_>^h`SJRHkqZ>BIgY5LT>%u`s*G|JKFh-(v;57MCd779=)j(5Qy(fqBlm)Wu%U?D3mo+Ud*FC?t z3Ghc^kol9hH`HlbODlelu&Ii;io#N>DG0%zF6tIWqN{AveB;vPef(j$sT#7!^|uEY zfvc8ui(#PHN}@m;6siMWX~%T+>-aT~)}2xhgvOB{OtQpfefH)@I((4kB25M?FhZxk z_@@s}5%l(oZ&(=w8k7~A7C!Ht9p9EVDD~SXBXPdvKPUw$*+7Z?T-5N~tnx_;8zTIY zly^}edgzF6P@BR?Ugb>56^lWSx+wtt;OLN}@JLuFBvdc_p4Nkx>j$hYj^I6gaK!Unh92-~GP6!syC3rdY`{Z0Yn$cMt)@EBqAIp+aE;4>}+AwoFJAusL98+j1NLB2mlP>xvfweN|YZ49i z?#m->iiOiZij8aD1T4}vQb(p-Ad^YsP^jvzqWg4q9YRAIL(ONGTK5hx>A&+b zeuzv4(?HNRAV2QlxM)Jj&KZ&a;|CMgmUfhW!DlMM1 zQu}KwU~cscoJ~IJjpP=gxlWmk$t}#BmGF-R5L{;M-H_y}B@=`?5wJ{3nqTL?Ie|Qg z$WRw}y6wrQ0ErIz&5S}oC>tY*6*K)O#-T;)ghp?+6X>FkO@* zUZ~%!1d5V(J7Drjs7@sZW~Og0Erzf|#(+?%ht!e(TV+CNf_ln+DIU*6EcsY998OHL z#g)kcA8uy#(uPFz?h3*t$&mH1GYve^OL-jwc5=e&EswRcLIUOQ-{{tKBm3 z8BMT!i9PLCVQ0kwdhwZB4afABv88m8!m}&-E=5u|B$jUsBu?EDnI~4;IK;PjCFq`u zPL4Q|-3dITaa%NC;z@}<{h8V_QhA!`D&@Un{9d2Sp=epwmz$TK^1ckiwHEcuHtaWB;{vpxac@G_kF7-Qyw9y5h@&0c z3+H3azxsxOV*k~Vc1V7WyrCbK#}=RYKMhC zJGc*Rfb1G_!Lh`e-Y!tp zN**o%eMKd%6|s2&f#MoPLQ3O-D`^&r4dM20C>IpxO=r5k-B*PcQO#S!%6yu7|Ncpw zAmSAIs%z*$$ouWM&0JX6(;!arUooKX8%a?%nULDY$Fg(~s^cGx!ZD74%9>-_#|^5o ze}C13hMh(U8|q|fnEDh?mS50y2A~x3xI^Uugz#d}XHJ_t_~TRs`aCg7fK_NOc7Q3>{`U})+*x!U7VlTdWL?fqoBP@J-gxCJeQP2%AENTvgW z9RNNxMY|g!D85NnesnC_DB&6332m+Us++yCrlcfJ*$T%Th_AW`0vvkTHf35g#dfAR z7YyDV8x53k&5SFi>YJx zP(%@21uOAk04v^@fwmU-jIbw<3idWzh6!$U&&}A%CHJja042+AQ~7*@&7F|9S(I*z z^3@!DXs(@U`!4-<($y>SiC^@I$bHy_Vdwp#i)n!YG~e+o7)g~4UW#lR@N)xz$Vj5Q zN#)7-%@3v!5&u>)@`dgt0=kQY-K*HU&1MJvL?S7zmR6zAXfaE<77I;cH9lJ(JXs`pzgjx@Yj;)WkUG2HYJkx?ZON6R=+(Qi22%j9CN%(s@yS%>=BCi&dB~q@d-J zJo?kFk+X4DF^dL-+{s{|vLz>A9fJ{@83sjilvB^oxakFFn9c~@dlgS?DVy+d0bbuc zp7fzqV0&&_y#-}|tK6|62}*%Bj1DT_@~@!V--enBEO4({%PBf<0>etIC|Zf%7}T5i z0|QBv&X26z4gYrTY{6;jg@?zt&E2k^>h9+&VoI7XmHpKvz;=H39!*Xd4s z|NXQ#)$~P$t?W4~!H`fPpUswp4Q1KH@-BKnZs`8k@ja*(cD``Mc5UN`G5L~XRWH2- z2=eK~II0J};XLDowdBY;ibhI22?o~!mfA1kZJkHSLnUEINF=*F+*Z;Y3e&h*agJK$ zT0jHBn`U@T{808FGDHsmuGa!X>VY&at|%0o&|!?di_pIQ2cHqAq@#xRKb8_3|FP#V z+~f2fK*uF?i8sGHs7tZA=C1zB{A*r=)Tsx(cc^7h1LcB`l4GEo4&HBIxOe@18ti6g z8P>fDJxl=gy;^*PY#_umwtOVdMu=0aOdJwkBgj|61qc=0ZzdkloSGKBNFO#@kPlKU zy!9qK-)|G)u*XUEI5QRY`@FxAwLRa*rPX!{)YH{wWF%$z!Lxlo3Z+i+l+PH=0W7P9%-UOp$~$Eq(GDp$OK!cOXKj)`?V;o$^)9Em6W1TAI6Q zuAs#lGdr*W5%+jxV*|p^%!qAfRN?rSMU~774flkYjFz;UJ`yp;^Ar3iXGOY&J`-Y{!;z5iVBu7Ub`}j6G|F@3iVa?^A3VVrx^_bpStK(&(!q7xu znmBwYlvkF-bLPiu_fhtL8;RYMf`&?-V@jvwG{-_Z!ipF{T7k%%P6jX|vVtB7Ei-mE z@IMYdxpcW_672wmZmxYQ%m?K_3eGlX`?X8}QC&JnT;|zs(n89-ni@yTrHsQqX*#Vf zUQ~AN3V{pPW)lCgPVH?6#A>F=Z8YkN`6VV0-5m}zMtIOjtShzXxo{R)fMkh>7R%;f zTcW_SnOaso?#E8%yU{u%zYvu!cv2w(f8{msUL$`Pa4@=rmJm}XE%!({PKo)R4%Zvt zU@ebY2$Ta?n7Fv}O`&rLYH(;>JL~4fh9&ir_=#JkdG;FgP~qq@=SsbsM5j=H0(g6^ z#s{VoY2b~I*5&M!8cn5dRt?1s95%Ix<4h&2p zcqy6Vo+li$Q$iTmOO9bXbZvA}BKP;b+L)r}ZplF2wQdCz8vMux_^hkqVRRkkycMYS(VU9o&0BVT52fN%H_0Q!&LlLeBYA+9&S-%a4@8HWr!4|f~&4} zccR;x9ek`{DAk77Sk>FwC5HU8Z^#wizeQZA{0{?18aGp-1WNQ@C1Wx2PXmnoim0B@ zuV3DqMf&n!Cu7#SvU?v(=1lznXT7qqo=+i&y4;n+v6GK&LQWHScKmt>H zcJ_r?n}< zruMsUnBrz-EqaXe6)o!fCfcjgJ z1!hB>hy5ycWwoXhUXCOX;>8bBIU>wd6M>+Vm7or6?t%KNrfagzBoa@tKk-gL?EKCv zE|m;nd`4L%7z5aEHjVrv>ovAs-aIh~DxZs;!enLPI5v3_Pn?*|>6_s9#8MsBG4|Lri{4M17~x~SHM_SlozhtmYecD5x#9Il^mf|=52FuVRr8(X)voNAhaqzNS0^4>SL z0ndvmGRzi|vMz^LD3qDe>*K$uR)pD{@iDKoY9Ob~6F-(0~NfB_)=h1AuZm`1j3F7L$0u(H&n5WneU>riMwa zN$x(`HvX7g`BAPy8_ivhd4vJ33M6Ynb*@Z_PNuT2)iv)i6Miv6JT-a;9Eg0nx2r(c51oR-gNd^rT z`(qUoixbr7@#|SE3r+_A2-hXsLLZwL50F;pJ#*3rVo;DOM4QEYnUor_LZKVM!52Lr z#ydOQ1oKKfe~oe8zhT+|LxW(rpfd4-uBLWdpsJa*mWUg%c}KxRKh4}`)har%0~{SX zulEt>(pZK7x8Lk??pm?@(cE>P#m>?X0T#<29||()_3IZ0yJr$|T9d;bYGaV+3c#$q zn@stPPMjAnKwBe{GR9Kcp3?emmSh=ztl8#)!Hc+WCEZ+9>%v!q935gjV8bD zAOdQEY*nI$c%fG)4!xVWltQZggWQ%-+gcpsM5r}FslbI~mpzovT?Yb~CcGlsI=;R^ zQv^|f*+EG_5>h--fE7T=K@wUfQGm((|FcW^+2OPxBm&Q+rNp2BLols)1}Xex<^G=w z1qctw)X>?(*xtm{iNV3f)!fp~nL$+r8VHm#HB4_-C}jc#7#Hn7p}7F0XgyvSARq=# zARz3YV<}9DzywgvVu^ZiKPyE&5ts`YIVCO;m=KVNj!sD_=?a)AZu~gRsYyWRBDsG5 z)Qh7#4I1#(=MBoNRh2X7EQd$$wEb~p8~#nn9i6!B)jcZ9-5y??olK$+d5v@nRj?>qGuUB zz4VW9!5K^4ZRGdkzi7WIy|$3>8Y%Xafe776nJYohbmK3WRijL02oASnMazQsEDIBx`n*P;NcVL^V~p`5xm$Mj&%Q&Y??0A z`m2R;w2KaEO!Pg?2(y&ImJyIut85?lOA06A&ojlW*sL=-T|yRUEyqz55`m`?p*;0? zC3nQr!I~}W;f@qCX{*2m{{fRgv&A!Ic9PLvwB+hrdBd&*)WteQzYT~kP@pP;;d~;S7}d<=C(g94@j+l#r8W zPMJWRMSh-13OWqeXF_Q@D%J2n#v1oBya!RKZjrh1e%Fv#{XS`(9XC~#eEiWkVe!ou| ze;)ZO_8yE?R4Ozle-)xvYMcs*_hIJxEt~M-B^ck`8311H3}p1KVs}0Krn{p@TflrT zVn%XE#2>q8s1+y ze?^=;g7y0b-Atzd`F=chqRvWL)mdrP^Y`qp4-nrcmbs_^K3jk&G+#6H)#+huvj+vy z@vp`)u?P5IJI-3roMzClYHL{C^dv=TpyRlbb#Nmr+}DS#aZM(B=2YLEPVC7S)#lk#)HmUDcdUolE?KG2VPCVkF)-i%IKTB&dTDVk zQ}s*#Ri+R##)}jai&UhPkuT9#pZNvOGy(pe5OPWXIbeBO$i%!Ssyce_iEmZ-z%8mS zMesL={!M#?Ji>&wkB}MV?Y`D!;QkFu*=_WP%!;CMw`;#SlO$7ta}~^DlC`64VCge| z6ba|Fm$HKk&8n$`JL}75cE+(mZa+ICJN2G)9M&spnu8nfX0|!lrwrf)oUF`TL<7Lr z?T2ir%$>){RIyB}8dycd=-wU!YC`UtI_|yAZp5Ez6zKmVnW|E|u zZ$Y-M*SlWvt+wrF7W2>h+R_Tu3r_GxsJ2l|9iOOaU|$T9cHkkGQUSN>6nMt43kBCn zep|TWDzCZCO|V7ltRS%1Lb2(*=>>2z1lFP2c(6T-O-p<-ng$nMg$l-dNP1k4y2siN zecGc`Q;jjug7Ku#4StVrh4>uzfxn~{_>eCj?^#mT3%U}LkA$~FsV2x2coe2Ul)up7 zjT$&Y=&a?BaO*%xdj#?4D_D!F zb#=MDJRDtJJv|&1NNX7C``z~!^^07WY!Hu;$RT-`5XnMJ!*&=MMEP+D3C3#z>bJG^ z6&^57&|CefaR{>2IlIh#XXsW$!9#l|6?^h%b3E$N}LVGQ3!(u0TBG z>4<ENF%hpUKAjlAOqCMmF}EJIt=$m8pPU5-gqG01di&{AL$I`d zfaCe7+JdP~*;v4ZXbmRAi0Ux+FWwq#8$Q~W{Kyo+-`*#v$ND81#_J(Ts*`V2Jl9E! zmzzem(@Q*d;rJo++QVXL@Dqb|)exb?YReb!wd;j8TW)i8h_nE+=*T89!AV$J?KyB0 zvjlJ!sS&!%Z`a&nS>nuALwa5&>I-P)I=wk&Y06Yw_~>9F!no%>cUbEAsJ2lopP=_%ANeq^8|A<@^m|`xl`^*XQ49mY~{s@@tLj2k;q7ZN*2h+az8J55rWeOIREI zy+chc$LLa5_&5L@7g1%VA~*l;brPh4)+XnJ;6e2}c!CNQryUzNLh87G2_huzeFOXb zB}y{&Yiw_&3Vl^9coD+7dUOj%wuY!E5F^p42ct?$U z&CvXppvT)l3euopXg^p83g|xoCj*_%(;5~Ch?Exy2n_2#2xlxC82`T!&UN$wU}C<*^-K zYbr^q_6r)Yb>r`K7~dxlS)ZCXx)D=gq59tS7KM4L{(||*#f^;j7C&k#iLxZ?S)HaS z2dfa4HWpMHJHwi&bQIfcE;E|0tIqNGk(UZDPC6=DS0-})TT&}AZTJeJ3!r4o4+YMhx&#V&MCv4hq?Rbt8k!E?ky5aZ zOqGaW&B0K?CV2ySuZ$O>0YF#&iHkIL)M*F_ciu-a-n^tDz1tz!EhgjNcW})X4>5jr zFvfE8gGSd50)1kN0>nQXz1hReL=VqmJmg4e>`D$7?L+L0>?}OO?^AE7yV1n(Yh&6K z4`F7OWwP;Kk*~aYt21Mu|FREurkSx)%}i%>6n4u_(4R%$3yb%klJy10Z;`fKcFqR* zrJUL0*B@{85YtoM1kOq5&6F_42hZDek6-d8_w>ZIs5h25OHOUl;;h23(}@D$!(_*e z&=u<=_!CVP5r&spH3ckm1>nrd_SRw{e*3`QuEGr!(5GnT0po(L(&?+D{K*660bFm} za4s*$GUl5GI@D=~RuO5fu~r%E4k-^|n2U>7EYj$GlK&bTojtw1y+v04Xe*LEL=g-H zy2EhU816*Mm;8XrPaTZ+HffK93V?X@d-&z1lY^jwSw#{NCYk~))sfSXh;>RbJC%`W zO~j4RxLoXmimU<329rXD)-8nc2pAyEp*qWz**T%|%rQmII6|+bbpAz8yOSnS^_ZmW z*c2Xu7;z%RKQz5@dVTnuX=d{IxM4?n?U16eD}Y-fWbc35Wmb3E5Tt*T zaXk1MsMJ#{lrB?1zD@M}y$NUOie!jO2p**ryR>kkZcw$A?pQRyWYZgDmXbSUQ!0UG zKl2W6D0Jx&QaJe&NJz$qCk(Qsp=*K5u?5Lyz_|k~cl+L)?#fS2=Wna;?Y`y>+Xo4pL!8-MiRv2dEkHr0j-Kxze>%%e=O|R|D zRlKDlRbi9G0F$OJ1flMrR*0T0fhC7LNMV-#+cSCyU7KC0iKy+4)a1V9}wy-!Cx5@ zg!1QNr*Rp>_R1VUaMOz32p?2M794KRJ)q?bSbA!pgeN)lJ?t!Wi@|#vy zw8N~3$~!F>T#OsSend)w$x7+oChH5>H>+rngpx+-#dNJy0H_jCaZj2!Qr%N7Zg z?2Q1f0o1F@zX~m2kTFy;$?cz>x43khfImoq%EG)Z{y26;4?MDcRtHY6)-@9d0D9tqWU1vkWj|@C$3@7KsfLlS$)I+M z)W-EMmapo%i);x_46>)wHp&#b`tni9(ANYZT+nsfW|UryiR$0iLVvOhJSMG{ar z0KTd8(#PKXtqyW2wViyOtZgV9E7Pd|&V@K$0E03(uvXTwYi6Dd3W@7Y?3}Xdw_%u89XR&Wg(7Vo!6C>y2uZ; zNamqaLe}yQ5L+UaBp@Wz4`Dh_^dv3bWVx)V~ZQQ1AG4 zJ;PrFiotF3d@Vjq)hV0oRz~!XY1OK?dbknn`TQ9>ZHISDPmwCN9A!u|K?^Y500#!8 zw2YRZ%{$3_4kg+gg`|xRWb)~`%4?E5Q1{GAdmi`Uj}D8e@#5!hy)@kobIf_xSR>yh zMUhmv08z)^pu(b6a$NMr@tZ)@G_;psJXVGde3Uw)v&~CQFAT^fUaN@oJT$KfGG)#qWL`Kb;<_ z9h^z=3}iNo8ciV;VXogA5r?r!Q?`&Ek}lFITcyBM02kO(b1P_D*IyE2jJ`( zuvH6O0HCyClftOhh&h7*qC^6jT{tr$)EV?X;J#kAKrO@9Xj%$O+3GOSOZ2T)y=qUx zQWL>4^c*m7KxYuvQMZu_yt@Y5cGKlZh3e{|N^Kb&hG7lZ*RFosrMCiNwqKkjMq+!K zOxOsF{S6jC?>!70Ill+dX`Q)83D09FO{ zgK$^9QB?Hu7A5WByO{45tW&p#cm8v&w`Z5L*z=?Fx7vULBx$BeFEcUey2+}`C@~_lLw8N?7iv{~W%+9IvJb~c zn#SBQlqnO6!J`|IWxPZN2;B{pQQE#>;S=`SV(a#_R~K^HjzTmPX9@R!k!&%+(4Xo>Y*=MdQx=MR)cDykbI5&wlaM;Q?Htj&cNH z2O3s2@Or!zE9hVz-5AmHNi=;DwHj@BrRFd_2sON76s@zC;TvW~0k{F?1?z%7uQyUxTFR=~C2l?Ns>2A0@u6b=dU0oXvy+h$9BQpG zo&x~kxs29_U*iw&CTI)zocT?{9@4)vBq3U8ZewVEH$Ds|y*(Aqd;Yh*-jJqvk{c=JhBX;)?Q2Og8zLgJCjBVQ!v- z${O;WE&*_lC#&>D_fD6OK06F5WtUS1^%2#pP1S#*fJ4z@?5jWrLh^)2$?~gG>4fhW zK37sh8kjW2@PBm>%=$M|HTlehU|!~MgeICvxsy2H3l;+YyS$MUqZM@jnxhi`ly)rp z|LVU~1cKuJr;w5867|r2*8f$=m)hFS>#gX%$pG;5Q<>6gS;}<|4?Ou{*9@2XQJMWo z{?c?53gSp6a4SK^nDkk|b|5YA7QOZIsmzn1X+TeJuX{CTXt=YMgG+GarD-4H| zOZ52Ue0DZyk1Z{4#N&DQ6VP#jwG}4G!ex$fd@h^b+bQrpSbXw<-kA~R9^jTdhewsZ zyi31pZ%CDzt?G>R+C+A9E>my-+dXv+wTQ~nr#LpM#gFz(9ji_?b6)KETL%dZJxHA8 zmh;xak~zUevks?tF!b_`VmhFV!VqgO6*%Xc!f`4d=iVyV(=<$~9B`F>6Jv9IxOVT1 z<}*Y$$blVx@rxh#snR}zXwO5%(fD=MPJ)m-#Do-GNVh4K5cy?%g%S3SDlRK&HQsrb6@vmJUQ?sDEPI(ur)f!)rA6eSJz)BXPxltq5Z~&p zWe8WH)l&UPrLDW}?dp|*v5~BGutnj>G3$W4@R8&`Zbnb`xr`)h8 z!It}}JJr}fKV9L}21d*yJf2xqcN+m8_s@fwa>bCO3uiVDLAQN}I$#OpeS_Ma6nb1q z*{Opd&W4dz0&`<2Kq^_(btK6NKK-wFVoSyW7S}cHDWAzFJQ%LI$SyC%#s$8<=L4yK zZD07LQV`gcI-r%~GtO_i0Dhb!=+@RHiiD`1B2he&rU#bBHR+9x)jUybQWXhw?scx{ zta^dhXSu=AlLBmyS4xvNX^Dx1%1bN7e3Sr_gzM?l3~Hore-+t2js5lQuv_O3-j9r0n{PwNQ@hlTP|&Jk$T;NIQl_YTDi;#y#gwwIYV+H4gv}keK7BbPDbA{rxgU zUvz;m0&rHHj_uN2c2(x@2>S@Y26sml`K=5=w>8&D1dVcxJ_A#$P*;Qp2uGt#4<(<1 z86A*Il%}i%0|Fh{w8z$4J}(HF;+jJ}dgIs_fYp9;sX%a>8Jt33{zhisH4u2xOor?t zDK{g!pekP5%Vb_mhsM%7$1n&hKh=^+$JF?-+D{3VHH3|4Vhn;so5Vy0X?km)7aW*J zE(3A4mna_16I^vxE)+r^0a89po=z_;vHVfg33PFXu9DyXppL_nh^Dn=E3Aq`bRGH>_~-Mh$EV~wZrr9Z$>wGTXS ziN}|35HX8YMjr>`KCrDxZP;1>T0Om7J$#@R8^7?EJkN@Z6*8vU-ms5wvq91rNgtAH z{37_FGk0_Pw080Odh@)gzu6z>Or`1v0EYSH1?(oa8q3PX$zQ*nLZBclM^a;8y71*a zAc*|kC8^2by8eBgUdB-#IHWbuYGBbx`5$$pMe8$?RJ;P_n<&EtA0*e^glu%Fv4fM5DM_)tQ|a z4ouBqUO@CyN~==V7So&@Yd4GWI-rchY+=yz3V4ErGSwG3YmOa7H{!sN83>O0f7nE8 zdC*3RDgGuML~nBnGE5shptm9>0a!|hp# z%+iKcF40iE?c#ktP6Seeef=Rg))cLxvIlC~0natH=@;6O&(oXDi_VM0;X&XC0d}=M z+uV`?FHPr_AZ7PRwo!SuSExyNnHPdm8Dwxsg3DL_rnsChucE1Er3g4qNP(BJQl@8j zRctb7=w;?Aw_oCYWekK@0iXxk`km^^_Px9K%EiXAXxAvKbk~mB#hS@#w^<@iZu}Kg zmHan9ci0Pm6kGQI%`%Qx!;P@7&~HRl7I;2>p_6Ga+qc8W*DoF1O=9`vxONUBr0j5q zv=I1hPedb?N3|b7d@hWq{`A-(*d`8Ij;g^o2)n78Q|6qO?d1333Sjh5;k0U65}!}M ztmyonTJh&z$ae}xl;jhGsqbh~uDTA=-6}wcXMt*X2jPGbMT%d9$zx+tU( zb3x>>GKz)|fbj}20V3U@w|`uJ^fPu$VbG5}GF;rv=bp}^sVL6{He-Kps|4WNG05)( zTx-?Wnz)`fAQ$0P;mH}=sB(Lgo|8rNmP&jI7hy}x?s;Ct+iI${aLhRBMhph6|Im(q z*G^jhNkC=~Ow<@4n+Ilu&cZ<>m8vuOZF+?C+&zsj_&tCC4ba?U-oKJj_F~FtX(14E zBUormG9oBmTq#8`6D{%*LZK#p{e3#9HDf&R!O~Um$|qW^`1CQYZ@u6?-K#R=>_6w+ z*n5l5UQPs-?>~bZS#@zc%}S*ND(2m@b(_`~p^{SCEO%AyRh3xT@MocAvz%C?@SBu` zV9NNZiWo|gog-D zaw52*w^j2B8k$8Hi$2g?_tHPqtV)bdTJn`?1^Z69*hh7FgE$g% zlB21X8WZ>lpFS4p49zoPzGu$-SVj2*VU)-lZv7-siflt59mk+xBtmHhyMdJGKW0PI z9W&--AEx9utHZ}|t&s$^6(6o?+Jc_iKR5joJ>PkfTB?3ZZS229P%TL~a$lh3Pk}p~BHI^#C%4DOBSQZ=lrse@*2(*`y=kfBry zApb?33-_DdkDkYdWF0rf;%*xbs~88wSBKIPhnzFX;)w+5biaCi%HZ5+_n3Yx$Zvu!EU)zMMX$o;!2S0ZacUu#8t2m z_Ip~bqmA-v5rxBbfDd=?%GY9jHzc~5eRP+gEl*Soe@?jfU~2NhF3wT;fv;{GfYQ>` zXLi4OfgoH*)G=n;Riu%ZWPcv$i<|tYwW|kt1<1yOnuF)uHR~zw#&%=zip`5Fw`AME z*Ok6w-=j~>Sje2@(sMi2LU=_zxVXDtG#4Mc(oTX9!q}P@LdR#l zs3F|SfmO_CVh>`b#71fz#HIuXfcg0O24CgAas+Xd5kSNxF7|*1 zcEze<(Xl?9=5Y@>%dYUfy)}%5yY7IyL?vS!{3|RR>HGY()g=~s^G(^3r*B~c)C;WQ&UFwA*IQ&y3yA4^NIGV7~wIGYCv_pO4mpF(3b7HDBIVXYH2L=Si~qiO+P7D>?jK? zA7?@flEd{F- zY70>%t6Je5<=55ICGDL-BB}qYyo+>FRC+LFh?af6y9o*2rOT|$82Isg9%d&lU^q9|K5 zb}F`Q+qP}nthn;Uwr$&1#kOr%Y`*lnDAq1xF!A}=N|2pVoM$llz?O2Tml z79+gC*~ge*!`oU7Kq|q4Hbi%)Bc2jgu;%*TFK4;<=3A!0eP_ocM)%;$@!fV~rze0}%CZPg7fGy!632&qUR|+J-&;_Bx z@iOqGJhP|7KU;>CKxffbeJQz8V1+1ea-T!|zD!4*aK&k7jLv(;{LREp%lhCJ+(BcK zE){y|5ba8+^1{_BwzcgO!k&DDB)*?ImHe}XH|FUvzNl0JF`q>B-~;%kKqoV*4LWd5 z!+(%lfQ3j&bZPNDdNJ{zJt-QK21Wy&usDZk6(!jl$LY#=P>1#^ktVnP%ooUit_MTV zdJ&mF9PjrJS&01~28oW|AGhcKPz9n@CgcYg5qT*L>Ln$m#Fip#l-iq;IUR#xg$Ept_o3sPw=o)vrr&3PQo2{$eGQ#37 zn8EahKT~gVmX0opjR}e2I2dn=IMdJP4~uU4o|T zbKKrmF}PevO_EaB=qhydn=#@}$2rSD9LjnP5lmD+m|KBaaZss2UL)8cTZ|3+P z_J;ii`vcc2%r7X!POU80Shw|jSZmsW6d)H3IH(Az6wAyoQW)gy36SsiU)M#VV{RFt zAX_5Fk-Qu^??~CR1?HzFx&nIhs2blsIbYG+`6mMdfyC3dm}1-N4bU6y2^7k_B5x zbJFpgWB(k@IH~LGMb*clf4#|X0vZ4zl7Nx_}4777Y!w@G;u0g z4A%A;kgfn06=m5_mU;NvbscM*azgMBF4{}H-cnLk4B}oUrSu>DIR^zxsWK(xZgi#OcHG@jW$D`+>u8} zd9Eh>(lfHD`!-3)kTqaVQQ5xJd8^3=Zl)@V{;X+qjWd)?5nCcBA|HSqPJF6OugZ7nX!5(uyh%R-1zOxl8pVdWE(mLC{dg1!Ebi0drj%6@ zPbr!Zm4`+-&_eEV$ua8*J<4NPY#ViYrXAREc`DMp=yU?!-v>YQ30*Jf5{QRl4Vn(D ztOSFj4qr^v=Ejv32!Hz|iO$ZsOeEnXDeD#nFb5GxO^E}jN1#;9G;;%U4JGQq-qx@Z z#=z>)Ad1o9bkQ_2%CvwwsN|NjmL)qX6MiEWAL@_oXDm5Bp_5q{@r!vd3?c!eKmiS`&`yTK$BBS^vchRI&bVY|_S5?B#`Xj^R$Nb_DfX(1bHGzf}NeAgI zU1|P#)#agKJEGhT-9!86=EY^$ta5WPwKK`OtJYjB?P`@GWs;ae0WTsydq9n)5+N`h z4wR^i4q1rQ))Wu+L`Z+B(eRP|P9IWGJ^`moa^eMG?nK;nm8@k11Kq#eKKK{eE|Hcd z6h-fwm-kR*m}z4~c1JV?g`=1qxlyS)K7tyJ!N8LimG3x3D-BXN=|*dBx`U6E_d% zr;6FDj0r1;E~27aQzeW9Q9so-(H`<={T+QCE+d<{)WgMT-hAd&|G1Y;_rdCy79T4O zEO;3ddF_q3a=@yswlr=?+OlSESn8Si;Fkkrvf{v{9%PBpUnuAff*40b;`9@3v-hPZMTFAj)#~D|8DFXX~Lc#r%rx8Jq`a?NRJlZnm>h{WAi% z1P%OP3+)gHJCA^bon6?K|CL(x353Jp)}(4L(&9bAQZKPT2=v^#HpQ09W6itj-1YQ| z3jH;=ZPKRdz33BrG1~E>*-?F)#WR3t>O-h|tj$2S8jaEZehA@|v zR-lL6>~?pxSJ5(1s=jM74A(4A>1GY!sQME)ubEk~mYB@~hNc?Ed3gH3&9<@|LbGu> zdfUgOBep0L5&l(e`iEq0Bf!+-uPzs9Dn|_|E?Amhke#de1Um)+o?u5E_=1%tEMsJx z7n=G&Q+0?{D|U$-aH$cSERJ>BxeKLI%W3{piT^caznw7-xx_VBm`cQIMF9e!tPer5 zg=Q`altv1x*m8`5XfTwi-!Ud&!HU(E^v}eG+JoD%3h*cOrcR7cM24>?5!NHLtJ>lP zxTy@jYnhwsJ#xJ3W?KRjMz3PYmJ0F_LTz5Ql?=~9cXOko-LvzfZ033TRV_Z*IPBvA zO}`98zeB+7nZHw^+hL(##BUcsgs;VH*dxwQ`#YUTMFA9gs$eQkKe^NX=SoDv|8;6gtOWk|HfkGoX zqLF1I!nbrO=O5?ZZ65(FnJ-2w`Q8fk9~31=eCHCP8o|aZd6DeKxI1#dR2SR1Pb9{# zE7!v9uI|kv9lK{wlXeP)t2k2k$++sj5<#h6QseiiRDD@5t~qmu_9O0@ESxjna}R8D zK@-qr=bQ)(o%zr z0#lZg*l;0?zCoN#=Fg6R7Qb2C7ny%0uIxeiBhm{6xYA7gdUFcw@7F}<6dTDYKJ)(K z+5zCfPuJNktw^1&-tTPQ-p^jZx%(?b@R^kwX9J3bCy+6ojaLRdP0WJsZxGt&=OE4j zZ6+(wLcIZrk<4OY;u_`FKeHUviFM&~bzLr@m=M z7k@E?1<2_i8BTJc`=$+bcl&n;2;H*QF*Tp-QlrURvLTHXGthl;-7;&sh8p%B;XVc| zj7GX^E|zer_{p#som~tP)hv^0o5`sC7+z3t7F8PxH5p}3fB5g)bjsi`-=5#s^KV8; zbA@Fl1>8?SRO@+6^{TozZnLR_m^E~4FKu`jRP?Kbln6Oe1!-<^F`0Mm$;opjn zUY6KDliMUt6-{cY-tHC_7QT)5+NEYn9Or7vwF=|yHD8|YB{55(+1X{1DP9%k&Sou; z_Y)14=njT}`kac$Y|4z!6jVFqY9k~Ffs4xVSbYk$j@?>;>I&M{M)TL!mf0sA`(s~g zhxLxV>l3e~)1%}Xj~9vcB>S5ZABGh9-{XbZr^vxouE4~(Kff0Y31HlC153Irx8wl|hl3fM^q`x@9S{Wq|$t zheMh$vZv@D^)B`*#O>3}0lvpacW)ShUanK0r(?qrvfGIoHCYPZ@*cI3k&$!5RMyx* zB#h8h$MKb&!YG{0hr42KI<>~xBAcA0=%h<`OdN1HX~uBxYjmv|Bn#qnT?@6XtiH`n z0x4KPvVOplIXjQ%x+yE$;*q-zO#^^LH|c2Mu>onW=%#FZ4}>k zo{-PBs+JRqMdu)&al+U;sl(h&dY0`2pe%bUU%yOb+muXBou*BVmhak$SSLaIgxl`n z1I~U20Jfz4uX3OeQKyFrxPx_RB((&*Kc)&0TW^p+`M$N*NT}k2hT}i4pxMCNN zTrg>-U{ewwHP zwtFB;;GKmwt5d*#XDBdCdFagXq7c>9`XK(T?pL%Xn3+%cl(V!tp0Y&(5|*A^aUn!5v?G2a(82BW-AyigdnXME%szSq##|Q#rFTQOO+ZUQIk%Qliy^hv#-; zJXXh+nehlil;lm(>h%XQS2kpX1t|}}G4RgOIPxUst+Rc;Uln74r8ygKR~Ud|sdT)1 zr(=V}<(J-=cCrDj3(D^*4Z>kZ;H<3D%)MDR8Ih83)q;a=ro$JIx6qN9|YIgdI;=me1Znnq9atd@VW0n ze*Y@fu1h||`}BTt#5@K=xxNuKZv17@4=?LNjVObO^$9f)M=(V-2;mQ_1ESCuZ;CCN z^b0y|9HA}3QAAXV*=8v0I*$Nw&-ZLH8Z=Rqp5bw(c(Na6NIXsUp=8;(E3)~_$!C~L5w#l|pD_#ILeD>X4hSM4f zj=wfk3!-e=8xKaXCL!k^=d;i~c=cD9m#Hh5t5R5?ypEA8@9-*95`U3Mj=DSf?qnYE2km=2;2iUkaNlkJn>~q zaXo}>3bnLrZG(fEs_IVATvaV+#G;;48lSQ1%aa8h0UtUE1)G-HIwi~GbvJL5j`amQ zZ|xPI+0@luRtd=c(BpvnR_FaD%YQ^4r z)Smej$@n)rTp(PYH(5bM7~r3wHaB3^RmR0pAheAR^#+Gpn z&*8*^686>BC78Tp6>8z7p_AkcVucJh^{D*ikBiAgjdgod{H2r&(d5A+Aw^_LbfjxQ zVYe;WP%!0EzIgL*_0Bm>KTrs`K@b8VwK46MuAe~f8@6$2lVSqTRCuGOqGJA<>{+GJ zeTZ)GT6nDvaQCqm`s;bhB^mA9Gm}rFlC)dSUN%mQ1P5`l-Xl)sa}-FJ$~@A8AgJcj zO5Y*=WVZ01;tj4ZAsfs(BM0h%>@plkDzy1@;bwqP;WMF$al9=oH%62NXc9KYCey8F z(OZPAPmu83)mXSkU$BxmwIlQ&yNp&By%E&E#QX}py1}x{vq$B# zFpj6yTe*H$T6)!Xr@+vAYX$Uof~tXQ2~Rc9m*0~2B=*bN?=UENzXx^;*2vuSrC0`OO-YvnEJvbJ!?{5y%`Vv~S6=pkbJSU=TmnUpxi=4ETQ8Qyw4Bsh>}Ngl<|};-bJJRr*zcoTT!5dR3sQC8t)h zLtKzSqi6uO{uLoX_|gzK|GsPBii?!85-N3L^>&@YsA-khITe;_SMMH>J5@vby`t{N z2q)N#iK)DES}!iY!D^c*Si0UqZ0q0iT^=}Z^#PaRF2~X^N;Q@+J3nJcv~w5`rF0(k zE0!a~we3wEDCC-97|JKw8Mt-?#O?;&pPEcxq*-X(-yX)A&Se?~vs3Y`vCHNjSf+_p zQS|6%^l5~X6f^6Nwfi(6Ulb}#(EvJ=a7!~t4<)<~TtQzXM`CxEY{bkRuIUK7O)CKB zJ*x6y83$ZW$I)9(!*OXFYYi^O%i7jrv9dt_Saq;VY+O-Yv&Ij3dIW?z1Qj5%DmDf~ zjG_CbZf6-uasKc4VR_P(B77}Ej1MD0qE?(dHlGo1%fUILUQQQKhdPlpmv)P5dL47s ztnRSaxrCf-xZi>EXu zgb-D?n#2A{CNA6~{;n$_Cv&oYv9w&-p;tP3${xiz&oKY1X zx)b%Uq`9F=7cvPWo0)Jdh>*+mGBv#c5lF+#nxREmi3~ih-Z+rslo!|Da&<^U0d z4zgVAXL>Yu*G>&OIU96MGhbUj^8(cFY9khRay+bKf@*tn43n9Rbbu0>) zhb4SNJ7{3^lSS|wS{_?w)$7e);-UOgt=Hw~uauR~BolEp(EQg9PW4gPy0Go=I={+W z&PfwxNO;^?btQmN-`rQGKrEhou~(%;-@9ybBI9GCos%O8p-PF`*=q*woML(XFY?EQ zeUNfKuc!e#ZW|FGiJn;llrX>iDb*g>B_pJ`2sJK^yz zIWqd3VHexpKFmT$FRY!MfA-@ZSV%m-trb=@{r*faq_j|Swr}`XJU$N=03+NyD(B7h zN`#r+j~c+0#q-YnesSc`-SSS|`ZGB5UDf?xJ{A$+uPINE@V)vyV4*!bcd|g6iSj)C z&;IR&m7X++tZEy5k-`}{G({J{)MJ0pa8zCV_4C&{_Oi#qHV-Rjhu-=C`$Nt=UGF@b z8BWBefq-M+xnt-%%B1%QOtFdO%o+Cl0;lwAABYk7MUm^V0v+YLzxQ`-GpHJd%pas# zKqoJ|ps6RQxmHd8&#H+5*^I~_y?{ay$*u4Il2AQhI%`Pzq1(^l|Chr%RVV}$CG~O^ z7~y~FriV0i92OW+eeD6k@rZImsPN&X>IY_-gJ2+5sQTlgn}c?8C_K)ac4+5-6V9H& z_IY?x{k)c$Bc5D=+{B?QG-SPleaA5rVqaa~HuV_F^ub7+oEaJoTMLR_@7f7(H)5`_=2ZdpotXMeKn?M5^N92 zd96nt^LBxtw}PDVkLA;d%Bd^b+}c8P1+7D|B9B81Q3_u!T46x6xQ(g@w*gHdaD3R1 zEQO|*n7|rA8-PPGMmEDdna~G8K*l?e1bllN1JLZ4nv223Z$%gy5E;Ae|TM`zlK z5@b`@7cmB=5A{?i*zUm{c*8@!$qTqZwzu{uTB}@UQ}V93 z0>m}9_X>GpD0EGtKwb7uYR@nMUpsYBM0@1+on@|n?{p8)$t2BOkwR-7{Gn!>0Zo2b zo-+v62&^%@6saOiio^DZwa$wk#Ak+R-^KB7Jbs8^6Ko?esbl>P_4Ltz=o#q`>!fFG7bjA6Ov3Cykw}7-OP1dWI^Po3}}*ekb=8x!(E?M%)`k4P5*2dX0S!ezZ1ea z11*EjTc=Jn2J|{lOC>XUpeLEgLbFbnpIM!i-+FSwC)!#%EYOEX-WR_cnn$6xl#rV` z>9Dwd6$G{36_Iy^yLsOCcOOOuSC$Q66knJCkDxEl#fU|0XMPV4B$XOm%O5_7W+MpHvyBFkYdjOhM@l>0- z#zw1U=~S-SWV^sForOW@{hq%`K$X4M1P7r-L4`oleTTQ+&bqOh9&D0(S2ehUhSenR zP(f}DgWNBFyYsgci}TNFZJ$aZq(5dn!vvVjd$Wf}wc;TMqFc9v%p5{ok^p#zFyHv| z0yruNK`K_6p-n{9h>k~hWj3RXE^1fBrp9_vPz^s2)NPbXS5=XsW3G^u51jwZl0}_k z-kbe|XSjcKxc>mA|6PN#wK6yR{}bW5)#PFq7!mm>diycd%NwlRxmq^#5s_(tA<>qsK z&RMhNO&dKQ8|~00k3z`qyBKeNQm9kuiHLjEvNa<3mnUvGg~}gDwCr%5a8VJh;nFDm zn(4}GHx>q~@RkF301A#sUjF>`f)h>|C8A4?qL2uob&&!HE;cg#Y`Oei}o{uPjw{@SxhM*oBWB(FOgjC zS9eL>!rQOE`MU8m;ZR}~hw}}HFTFdHJx)^6fENE;XA283c1axKd)kA%wMjWF}p zCZC2*?M|{KSFM_$lx+P0G#RCC!Gjk$K##xdusq#zm_<>qHlD_IB;`MuUsZUt%ek`)qd=o13Gt{xZ z(%+UAu^#HvA4XSl7+5)fS)j7CH~Q<3{ym#giRZeO%DT_rf7<)iO#>i5_{Tz4;Cvj?bzPg3s^zY!Cw;|@c%YgNt5f-#P)+12 zc8DfHnR@aARcu%GPF7OV%aUiA#xa$>Rq zG8Kxxbh9!h?iY`@TpV-%ii1hbc(%sPFQ+S<&1v zHHl7Z3*^QYNRZfSK1vBOM9bmkRIO$sG34xWWsdlL$IYDhUIW0#5QAsDX{Bkqdy>Dq zM@3|xRbT<kf%N+9acN86L~8yi9H=BL9U*Wf>Kv{lHXX6YE98;Q_X>h3 z2+!QtJJp0bqlermU{dXF_Ksf&Wt1kX(e;q*vmvZTiH}w`klfo&R)zm4tAvef-@TbX zerPDCan0K;G-?gpIMh%tLgK|c5UX8-8ufERNM^M1m$lp{vheTm{diE|iBrB;)RhCp{t_t*k1AU4}y!-K}b$Vatg;97W= zi_)?K@j! z_V=qw6aC*s6M_YbnNU)yF|8&Xl!h$XB&N7?SXJSgWZP~+J~N9ly`@ZLK>Z~!_+Jwk z^i_8PMaR21K!ARBw7-LL2((E(h3>s#Z@9Mwzk}-U3v8B~i*f^a*D0BCc>{$-&&`gk zs;OpE!x|28Q^g%K>z+6Kf3QJ)?ALA9Czv#4W6a@eXwiu{NY3$XF4?x-M(AzspkTw z;7C;RpjqWWgJ65rB=eSC zuSn{o-Ga_$@4}{rl!K1!QO5A=)q%4X^OpkDqKB95qk)9FL8+RMC@gG8B=Mm!6RkR| z1v@P7;|_f6(YSbt_A&U>c#?AoC(UGo@RHgeXot z^)4$oBsZ~kF6WAcw5U5UFkf&J=*>saQIropmdts`TmyBQmZRDM$Pzwu#;^K>li=wS zKBVv*S^B-Jx(fm9wE;m5`NLL5-ZahFF)4UO50?x*M^Smb)+GtrvpIl@*GJmJghRqF z0Del&GyyUJAn{fr;LC3QU*3hf62c3R$WwiPI!;~t4b($U8xy7zZwoGed)OAyN+H+? zRcdNN-f+MWB{ny%08P}1NKDI~(J`>!&6Bk1vcDD33>zCXPjvh05`;+zi})HpbBO61 zv0uhqFf=D4C~lG+?MuC{PE>}358e_9V2*ieZ`JX51{A7@{Y3-hnqIPidj)P)J(SPG zZ8|U?TMVC*FSZ%se(cE*bk2)uOW~Bv>jQ~1w?O9{@1x2GG}+7sjK=N4m;EyxA;VZMHOkZSU-b$HDy!U|;oD z$;8%%$KNej?KH@Mgk*4ZbhU0lfzJ(c&XhRt(?`8CYB z!|7o!2O2+Cx(&0j?{e8JESEa;{> zNn#yAfIr_EnD3M*OZk+0vQY|m8C_qXPsH7&g~{L;yIXd(_~~!3Df<`At@-KHUSSm&-!s{=?+e8k994he_Q-Tuubi(vDCME{^E6gI!<;am;$J>n? zCSBpmO7?aRB!Hpg&Wu4M6QYD9-I|m_n%(x_ZK3p>Z75U@q)>R?SNxjD=a;ITD3&*l zY2Z;X^CuedQsDq{KvgkqrAn(WKaL&Vp@~c`86T;z!`q`9(<=Tw>%=0j244$=k665z z1prHZui^X-Xa1PE1;CLo_eaoTYEg{dA8V*BgQTeuZ3FSd0!d(`tNAO`%uhpbisilL z{!`ANQD)_uxE#Z>TlCUTTf*L0vP~o^&<<8IpzmkmFhplb(N#0NH719j!}^o6glTcv zT6<2~?zP2QW{y(5$pb>t_NoHcb=EPPeQ(0?wQ9goX z?^5#Wx46?=yo}#oJjQq9CVX9Gs=`xwx3nGWf!AsKQXy*sJSjn-ynwVee5tuP66nj^ zF3XnzUIWAMJqLCD@V4JzVCAb2SJQIG!At8fjy49Cwgi2P={H-jDIwwSY|f3WO_Yp?wtl6Hperv#}(gfZ!R0fetTlVDs1I>2soDG@HlbIN>(8 zsInS$334`%Ls2oxHw7=CV*~}+t*cPsU)t;C5G+9jy!VPK4*A94=#ZeKS9z7-{Z1g} z;92Fy#*XWE#`l#>oay2wC;1-iYq+AKxS9U);U%s+$sqHs&CT=3(OL{U1i-^oHH8gc z?pS=X_Gk^ELUiPS@+S`Vsbkpm+vo@_peGp54@*=X!C&4e`)N(AJAm!QDG`jQ#22>u zqc8^R7Yy%EW&_+pI{LeXbvN6_nsc8mGns)SBx8(nU|vce#wo}nRUC?%>f|(=`?7*| znyWW`OjaHb-w_1TI*oGQgVsHiemv;Z(?k5)*Gdu*V_Lu*BjgCS5HlY8o6(uX0isSe zLDJS5XB{wuCCR-L%mf4k%Mbi>)%-MF8KI!~ z|F=jupN$5NL__YLM%15dO23782WKjqgvl z$Hq4{7UaM%jy0DCalX&8nwpBAr{>DSN=cl@$*DUTUh=Cp)$^&G(DQ-#t)Z(cX*d;N z%6HC{>s|S9aLirVxHv;UG8VRc5!QQ`d^)7?u#xbV;yy$`u+JMlBVM$?lgKC5o%Xfk z$x99O=^dx{q|TmaB|k2eBW}h|bmI*pLVuK)6vHyz7|GkSI1tuR@FDuKf%mL%2AC^6 zrMfUmcW;o|qr&<7s|<_GO1wUw+*t@P&ZoV&CwRxLace1DC4D`5atE4JnX#|Ki)m|? zn(D-TT4$7Unsg8(FH;zV1|VI@ZSWDCFagp`0^$5%V5j_G%f>Unz2t`s1i2E*vhcd2 z$=<4@?Twm9fO|m|Q_xdS3>@&g$^!w;tvc6AZHRgwSVk8|Ep^2c)pD-!z90t-%{?Az zv7c8}-RP(0@M``sl0J0j z7B#_0nD3kak6_;3LU1Ckt33kDVGvXhqw2e*?(k>wtI$e z5kE7(OU`c$-^-a2gk$^QTM! zv|^DFC!;iZVRcQZa3a)o?+b+UnI_;#gN_T|S-_-v8;Of^*Koh`9OF1tMdx=qD7eyZ z*c(tcrBb4%f~2%Q#T)>Xes&!(=a3lU7s{0W^m#o@t~J_?NqN+H)pSw{2T=)668fx! zC%2}m>q)Yu&oWu1QeHw*=s^bqkOs16oPRKjwXlvUZbV2it)if z!R1(8VgAg`t>$c}@2U^FvpJC$O;G{^KJzZ->?bNh1jUZ&S^XiGzr1?%y;WOj4gNS&1{!G8ebgaNI zF8iN?6{(0xX9WR<`fKe7sRNdZl{4j+R8ykl41SG;r$3M3{2r>K*tbadHF~15o=iES zwpPK3_NwZyM_I_?v9C%UL!}qWdsYi8hf~X*86YB~O9rfrZE-NxR=QMl8mCJtCbdQz zv)XDFWvH&~I+AF-iWKLb=r4$GHz}sGNMHtT)H;S7gn@wxQjM)M@0RAi7Axbv3> z?8Vaib+G+R3UaPNVIF^HvR@buSSjf2$5ch@qTT`Y)*H^8!2L}YhTW^RCsN(TM)UMz61s@HR8Yv@NM?QzAAn&b9MZj^F zuGb87xG>j-{z=>)$h2i8Y&TPV-(&sf4n1VX&WIaV0o@=LC~n=Xq-Ca#9pKME^JTf3 zA_NTZx9($ItfdN=Z6?Lz0dzoFIg6ANg~p4g{QcG}q1%u}8X zchw~;Pan@Q1`+4IMkx4t<4v(}=GrR(T=_%w85JZ{8Nsi7GkPG!4xtJ!`%x~ zLmASH!U=b<1P3dP4(%fPk<`)s0&TDO+UmS}5fFbB%5`-VyQlJb!t#0I@_FL^HggSl z%oR8lKx+xk)&K681+d78f9>~pK1RMDEzO92QhnUsooIe1qdah+^%c#gARMnU59Lv9>oA^+rl13=c3cZjEko3B z;wt}f?Hykl99Id_ZpzR(g*oj0&qRv3TSlsa07nAcPZtpU+r|qhVvwIS3c8ZjJO$EH zRiBWr~BECBV@)t zF76u}<#NkYmJ`e6j09y^t@aaBb1C23tVvB* z(m}!isd@8<#+cnR^iN(a6=HQvbI>gD3*>AZarY8cJV>W0n*GKj?~t1WeuTm}6Q#(+ zagj790NZ)ENWtk}3<*|wstADO-(R1jCq5)#c&y0YJ;`?2lh zq9;dwBw-WWJm6zDQYn<^FTE*zzN(5JrlI@I>0DE()f{B5;vO3pdq~oGN~T#lg(?{t zUIlQ1%MJT?tf%y_({}WTNyWAueBxZ*f-6vOzPgQ_9R>KQySs_K79IfWSK8C(0w}*) zY-ol^V-#7}3J>4H-&V{kb%h=}(`n}r>sJ#I$Qj}gKN+9ffu^fy5-lbx^nQ@G3%17B zR(FA>-@XG;9b)*~mqh?{2;wv1*U;FfQZs^oS7k>z8l61e8xlMtcJ*;j!L$jn`v0z) z-O{GBIbefxkOglo5J3PZjB{dRKx z<83E=(PTEyq1E>xB}clebZo-@Gv14F1p+f^EGoBWzF-OU%KQZ=UFO+XrfM^agZb{p zGs9;!9HR2~r1#AX-8$CBByD!c(rmNYn_WcCwPSQ0)~z2ebY#)>hJ5c;0&6p! z=DI!uk`#fJ-RJ@EZShX2P2S5(u55{E;n&O>J`gfHV8wx{ za^rnR1>(_qHWS0r^b7T+{~*+V+VD+wKziZ>dp{?i2DNG=Bde~K!lsn=CiC<2p(!)* zmhvibIuUTJKwnm}pd%zkMPtl_A{1(#9IE5>)n#XSojc1!g`D=tT6cwMkKwvTLi9p)b$$0-G3}JGxnlG;<Af!q+!C3QsF z5Oc}vbWGvUmzpL37zOc|5pZrwjaV@R9uDlp8SNuGymk{$0cG)G+WHPT%@D7R;38jL zY@@jhn0MFOfghbeuYYXf0KJBz0898g0(3Y}X8;rK+&B6a(QCz(0vuUNPXP~VwJ4v> z$iA#QSy5uVLxx;;lmoJ(f?jLJk;tK?Bc3ka!l;w6g5c|6M7S)L;(o4hqQ-b#=&4|N z+98RnN}v^`nJ#i=mFzeY{X1(>wo)2pxuFVZ322^1J6gN*s0~v!BLR^F5M=4PCqaX6l_Wn4Pyc1Jky@pcBq!D;OFfCy6`Y5h# za}ObnHOz%Mt6H}y=MqidH~NW6xSaDhR# z0>?;sZ@^XCAh+aTc%AUU%3Jap3lJ`)N;(Kr8Pfa;V|Fb+F8pe=6y&326VaMFh$zQZ zMl!}7^6ih)h^!v&mR@Ww`;UyRy6m~OQ7Ow8mDMs0YgC1yFAgwWr`H>uI9I)sIl?hn zT&`)M%*5vD{KWH|W)g^M&yq(BU}u{{9SS?0u8`vb0QMt>zCR5PeLG3T07gUAVAG}G zr$oQ3<}{0TB=~ux!3&*i!wi5h2-?~1t#fR#LCVks{N4AYfoORrt0$M6#||=>*T$PL z`1TVoK55_nD9s7~;`>B*6tYQZ%7q_&AJB_w&$?@h=q(f6Y5aV%f!Ad)R1mmM)Umtxh1N zQ0D8-R1}p_lf5Fp-Q$kSIn7QamW)>vEB%XX;eif}Mpl)z%T#ZYOoG2~8*e!d!z~}+& zTcak-C1zEr!zo(??D(8T#aCknWJf4dFHx*^F2WYbAv%zMT&>SG&qAHA|@o1b~#6YvNf8VF9MDw>K)O zx-~f8Em&6+u(S|1!aiygix*`Ll>*a|O`1xYnPjOKEtK+54B-4jGyZ~nCvxhdu!v&< z@p4`g0o6|(=NZw7)tIzlpBTuGZ`Xm%C)T?J4xZdJbC(Y`-BTy^fB~4AGu~;ao}H<(0}U`X%CU%co)0UP~h_^I3C5J{<&4S>rMF6tDbl zUd9ZS_&_5FpFDZqlZ>SXE}x_Tk}%|kHE_);l7ianbYf)GoH@Ko4pX-Hm*?F{ zSM8q8@kO_mq1S$0V-Tz_p9Clg1|~)Kd!dt@0Aoblxg{Dt!7v=VIR4nBLN(Ues=Kia z)Nfm_x}(Z#>DvBo|5E)oblr`SM?&IgDd$ z04*;t)dq>_di%oz23-}W&Jx@0_t^gjen5f0-rf(v)6}ecUe%H&2E*FssdDs~3FMiV zOJsicOd+H}B4H++i_A;r?}!20peGK0g$!ZjPyi25Hn-VAgn0<0)b(;nsoCrV=-ceW z3D?uchRBXb3+6L86nJJA>Ibi-e^*!<;)`u+7$bl9j0M?a=sT52M-W#&X2F)1*@U8C z04xJ;5n4JD2rbO+SVds1u=zoI-Wn2WcTk34ixCaT72Pwnf|V3(Nw!%rXj)l{)*f6w z#8Apu%2M10J?JCgs-Y%?PbU$DzM3F)!(%O%EE~o^`>(u7NQharfAiP=P1TlDvCN%X z1H*qqY}$UYsX%M{Sp0ZaR|8;J2~(4YY8OB-q96YXa`0w0$0pRS#bzzq@cdQR3;`f2 zf(Y>2L^EPVMBMq{x&hqp$1_45xDg?N&r;UyKqwSJ9|C)tP8!S6&*I;8X{fNDn#wDj z4ODXM?m&j&BGQK0YLrn4m9xylk(tV*v2%aI;c$Rb{<-e612G!T&*`FY@)UoED*c8k zX;Sn_4V$=qvce|mkc4R9gP2oBG#3&UxlJ9W6~uJO)yyz4%|=a?ipvU^1j16Raw+(Y;u)ge8V*Qy_>gSEv6syG)3r&B~ zV@fuR4GT>*$eG`trO(?O&55E-DodvFhgLSAE4ibnQ@q(m0R%N1Lj{6h?Xu?*439=s$Rd=qMN)4V zQ?6Hr=Qrb?aQe3-H^}}n-)3*kF{FQ>Mg5prh9u7|RW}=v?kKzH^w>SE_2|JDTBj=_ zVy8~xCiB4(bluobS4POoy0t35ppSvY5rWInm>%+oo`+gr(irli2M;ExB*4}Iq)x^~Td>L$+xO*%>m(RtcU)X(rLTWxki+a0{tFslh{e zBkP0@T@`Vqz6DX_%Mw>K$r863zAMM3zS2-$95UPT)^Dx}|3n4l1*1~6gQzwvl?AZ~ zPl${_wF6L9C!b_w<3p-zi$?4nmxu6_7QAH>N89^vBL%ueI8`C6ZEklJRx^WI?tvu<_L+i~Sv24?ai%Yd@(T7PO>LH+jm{iMVW#J7fZ8Hf_ZBK_bg$AT? zleFh|f^#S3_w2im$4`IYNS#G(QMFlVY)Zq&v{)iOSPe^gQkJxv3yjSmhG8%ss{hSb;;oitH>%Cj= z^g=!-D5Jh^%*t&g0!y+M?ziV0Tb?^49FAoyw(jOOyF`eCD&_8l(pPFJy| z#2=dS+5FwsjcDy?XK!b#wR}7BZRAB-t4IAj8?}|Wf~8F1;h*Xp>b7!)igBEToEs)j z*jZNmI>tPSHEw^zb_GMbhwISWuw`~f%!e>gl~%!FRF+q?YEA35Kb@F#$xH)lJalBe zcF8b#oI%vD1j?5>!dtH)lW(=@gBR~LFPP2m>UE^X{A@j`FGW`dU-8#t-j4nIpL)o8)~mgYhb^*rI0UNb-NN7xN+wEsX|A0bXP$K%n`< zP$1S+CpCV(C2jRq3(87qX^TwrVITYL9%+NoYDZ!pMIYruKF$k2OB|c)#$s46bgP-8 z>EXHh-u=KYqsD{J#EoHoyaSQv_UKshAx2nx3 zNB4j848+QF#C>JNYLVrC6&b5#c(ClcnWOG64r!Z180wpfbv{ki z;%+(Q2;gYK9U9;^xT6iesEj>Tt5U1pFuyu~Gf^R=hrSuKt5R*v{460bU6|*L5Ey^) zEQDHj1l>#e$$${c0@b4@Ir;n?d<(qG{ejvS*qCjn=A<=-tPX1k>0=6+0&H@cRxXZ* z`RCyMFzYYK<%@oL`CRdgU1qZWj2>X|kJlTM8S&_|Vl;@*h3U+1NIc*yiF9Tci!Ksx ztQQL}!yj$ScO*ew0Kk8fdq5|jZoZ~1VxLjF-BS?L#!Xt$A?v}LoHOt= zt`s#r8N%n>^buFZhB4Q$&IsM2cvejQc&>4Itm|m-Yo_*IOBQ?vE=|OjgzV60-71JFfk`*Fph|y9Qd+Kgk`x;L@n#Lp69o?o1lk2sjjFgXmBZzDNTkrA zdU9M86!UED&PWu~)y#7d@?{0;%_JAGY}<~@*vETD>=~AAJ`n=pd`U?zHvv3kpP}R> z`19Y6_TP0`j@*t0LK2cMA4xrPM7^yzeOU6$yKI2Um!Jiv1&O!B zRW~usiaJgvvc;hjEFo>$Y_9o(2)^VgL?;;x;5~_bsIjoe|o;otOhlt?4*0bvT2*od3M`bXBylMk@_)!cCGS*gA(KR#%WE3% zfleMjt&v|m=!AyNl`#w%?E>QFNRR|usm;?W;}!qriUQDqv(2Nrt<3`5#!eW}MS}o~zjg&W?x@>+5K>=xohlbC}&-K?ts@eQW$r#r*!Ll=^G(7C}4TSu_5Ek2qZ6 z!5#KCi1FVs;~Sztr>2L+B%TJn*3az&N?y}|Y@|AL1H$=gxt-;}WLIvLiLdck=r?Je zZqOP(fhiNEk00A$JJ}ALo=(zJd^1xHZv++j`p&BWYj!J|idJ_bOv0o0_hZ=la(JfMDI=7o08uza{yrs_(==nPZnS3@$Av+@Lx+TDIVvR5ENVa)m8MIyD3Xhm47!yrqKX3x zFG*{TfwB{0!a%8Vp91Hn#zIJcwOPaHyxT7duuf`v3T{>UtP~%!3}tEErmv=CIJs2w z*=YdWhpaH{%6Z7XKa^Gn!vZ!2dJn!B@J}ODz{Y=?3ZJAB;0YJt2^HXKP-xQagYyL* z-71t&PmoY&!k>P{z*_B25-cL1viZ*2(eZD4J3Vuo7;r}{t8Dw4xZj6X(EEckU(Y*g zCU`iZ4veA?H+^rBi4)AFWw#^jqGBr%wxM;P45qX*SvotZ*j(wbmzL?=_Kf=#D0jR~H_3r3Q4v7q_cP1Jjz7L)Nf%S$TIVIZU)@Q4}zv~cz|pS1G% zFW5!fb#now%XMC-h&)&q8}@9jaip=$VEd^1*^3-}&`;^KfUgHTdOW@?vL^$Njdl-O58LJ~{NhMuS*0@rY|x_^RrdzpUYj z@6<-Myl6I;T` zTh)Mv&gf@!FT<}KR4AkD*`C z0$(r$r=<;JfFlWbq*KU;>2*>`OT=dRr3hJtL{_iF zPbmT9XW^sl^mre1^DzQoooYaaw34Pqc@X}4{8)X9IWjPk9yybvUq0423=j}H9 z+E3usKtVx-0>_LL_Dp|0^F(%d%`Ws!2GJAoHei`i6>lZ_--v1zQg|Rr=!mY+C%%T@ zGDe-tYSVAJU3Cy*y-Um{=g!J`iOx483d@-Op?k-oudomi0yX6sH(&p>zMzNHB|JNDMz?L^=xfT<*q>< zb}jpv))zR%U_I#e#y2}HknzN3qk~3P7(MvH;hy5FvHs^Yb*}_`|GZOLMTMWZmuss| zWlS3vp*~U%Phx*5HqMGtZp0t~*emzNFH}qH^oCTX^;RJC8Y-;AK^l4n0qCPk4atHmYWk4t(3*j5ImuGC8=%{Gz^bYoqjzO{t5HM91AbO=JUUBS_ zHLTE6(eZ}Pit2S#o#9En#ZDw?NN4)y=D4^LB0AHMi)Vj2yPF%jD($wcs}6Ng6Lu(H z*M?O>jnwOhHSJ_Q-SmvE#>an8G8vT?Z2NL=f9vo6c)x$VgBqg%%y7f^$H)8cbfbQp zUd2UCqpi(%A2yFrqY;sp_rh(U4r-F6SM})M;l$#uwYu4>-JQMdqn%^iuy(9hyL*Tl&a?icZe3qN9o!_p ztZT7<_!c$LkC4Mcw$K77MQlqJ-hon%ZxkqRP+eDnCP&pVw7>jw*jwSNS_s z`TM%c-=oSu)K&fgRZcF3Bl=$*3g5_jxG6kWbzOhkkkvxX>KOjbp{|@^QH zzTUx2E@~URM%8uXceug3gZGGqQ1E%M$=>G6ojue9MW=_`?7ZH2w~ZPlbq#h=WwHI% zH4)Wx!%M1^)--xctLO%`W9*~e#g(d>2JD4s-KcKEJ3v+8<=&dwvOrJEJ#5^1m%ztM;q@#kJ@8nH@v zq<(|t7q64xX0^~^iLP&lgzFz{qW;SU8!ihlKuzkT)-jS=WgVvgw_Dn)i2 zLk)9$H8_B%$rv?P_Lqt`Z$H!ByRe?F^yG{3B*hMR+yyF>r5kpyi|i}{1oHt1PhNi( z@m;3(6b7(Gh<329FX4?Dw5!!+&rLB`oCeYiShEgJn$Ot>m8?-ced7$*p8Is!At0Ug zbZ9(>>n#T#k1U~VrX2vjII{`In0U@R!1H5dw9a6jSy+T zG?w)eD_dCSMR77-G|VeC!&AjGB%N-H{lygb&-E7$g^{+|&-^!jz{1Z*2HO)AD9lJO zzrfh>Kh<^8V`npP&JB06d#Bwb?T;n{Qgmp0>l_v;LruD5sGe^G`!%lyXQ+R(rxF)1 zvGe&}HbPH6BIvBkz5Z00&OxkA8kN+c2}CV}n+!9U*_)zS|I!Je>$1WI2%(>ivb>7J z!|BhA)A{CtK*fK_^kY~k#MXV(HlH>3uU>5y%QHCHx*WaSW51xX2lQux9$$Med# zMP#ljqAANgf_G?1$Q0-9gS>y|a?_QYS<3&h*U8GzXg}T7>Y`AroF~$uxm5CtRF&(| zoRime_p+3B=I}JN7B0u-3=puJqPg*kZL{DX-l($g>Fje9@S`cNs^Of;Vn?uFdO79hnz{$j#Rx*jM5;oM?W&!KDm5G2BHv3hkX0Hmhe#Kk{yR)D61A3(Q_p)HK}=fl8KU8-mu!+h+&L)VP~9#gYcAs5AAyXvT6 zMk6Dr9pJCx9PYcBfJ=W19klC~2V=Lhnxn}$8>v`V7Glx%!ivFJJjM(woAf_ou`-~< zacA8B;0ydQtzdtA^soGkEQV3aIOIRGq@3TI7BrE=wRq@5tCN?1OYKsQABw{bMPs+@Oj8nNv zd3mL>+ZdiH?Q3*gjjpHB>u9u=F%-?p$9L1@M%GgS6_3{Y6kV;*Qn99=CQa#noG1Nt z5zsFgMZV31l5IJvpm6@)aB?%Ls@5}78czB-J8z61{)EDW{(YXLWYBY_hTV|uK-du= zig>InPiQgoP}+aMu={YGG`>nMV!BgwCv=d_3y8W@`2u!#-f{p}SmVb}SDYD`Zqs(= zpzadMKV+hm{s?CC3+TQ$0fWEV8>SIE09!uY1w#DOi#b7-9_KbVjVDQcf4I9vMRJz1 zjHll`-#W{`dA9b=vsd3d-|4xFjJ+XqupzH(#z-TJ&WV5X=dJ8yL32tc<4r3~+K?FI zv6KG7y4?iRNiN4Cse{ZY1x@Mha^j>&`hMlqXB}7erh7Rx>@MU3nhDpweDuP56u>ji z#&NS9pc-vF#SQy^W2&ZS#Y^HLwi7~5^w0@R5Vpq^kL1Gc6mgr8J5{Rs!HDHyp(HY|^GkdCd zA5TL&Z%#0~XSk(I-1|>z0(F1Sk`&!PaB?f%m>isiwGN>czOMT14xPY6Wr9P+Zf%*6 z%4p1T{6T(g-i1t~VpKY1+z6rPJ;jk?apd*^r*MBfCn^~25Up+wvu;4q6016Eqg;J# zBf>b3061woS{snGhyoC35a1YH7TRKwyHI}<#t$aJ`6+~0iSC+`h+ZCaorw1@LIQr) z`E^*qaWkZ2oCP?(t@T648F#gSzgnEdOti0nu^8%Z zYhBQ((&E?Ut6BzzsoPox<1FuP*5Rw!XgIEJYbDI6o?ymWK3f9+#3ix3$MSIx<2f&x z{`9kvj+Lr2N9-Ax&eI=Ox?@Py8Ruo^ht+?mx7KUVn(X}#Bm(_Bb^Vd@=(06;lX{zn zckG%j==iax?Q7Zd<1_(Xns9U34OR^9iB>S;x+ZDhRmE>CsMI;xT{2 zi(42?6RYUjM>RS+rxj|U-JMu|-&1E;IGw%`sWuT8audD(`95;&!_dFVE%W}h{YhHc zu1J9s^gDtXh7Q0CpL{UGCND4Q(7^@_>{)N5sIW5W+O=+`_<~?t4WF~m5q%G>DU#fRw$?bo)>W6WGLoF+^hvCZ}d`N#(=G5DlLLa{w-l!)} zbaz#7w^&;~04f&?RuSHb!nv(y=PhgjKhg0EGdfkIzhJaqn@w%5@M1Nt{t}**t~18_ zDV}C^dM`7=p(KS7;-J`EbF&WV5}({K1@Ea%@E}HabcNo#&ClM}XF7)n_Vp!g6}ynWI?gZyU>yGEsJ#rQ>W|@H|!Cgk++g3ZL%6wP4!d5~zEdw(F+ZC&o__ zExa#8ojiRR`vCQ1-a7*H!u|lzlCemDCXbUDMbnNP0C?r%1UF?eK;`R;CGDXSI#Ut& z{W9)a#`Zz^;L|L=DHzxvw` z`VU5VRh!a2HVa%bga&69e*h~!X-M<^^G{+ARCrpbnyvQ@S46WTZq}Vgh?-j1nr(R( z1EwRhJ46kGn#>F{Fck;N#ICr)I4w>j{T%0Gw7FYU)}sA}fT=jornS+~HC3eJ@llFS z<8dRGYT4J79l8|#i{+n;(_z+o@ISqS|L=be@2~&QgA=-*XQ_~ee>RenX*ru%BmYuo00LK~IF?xBUfC;KPUDPf!x1(f>RYAkeEi`sAo~CWhH8DF* z;~QE%Nc8m6yi2W!e=fz9FnWT5&zJ5O)%NvvQ#?)GW*T1mRDV#1x8c3jPI5rl@8POt zGA*_OH9sRpJIvI$`{)8HHiN*ZgdxxUNVf8wtCaAEG@}PQOFw2m)@S3M?vS(a#YId< zKD+^W5dQad4xA|_5!xCul7#u`4Xz2MXtj8J}r9<0taI-}^>x`PlnUnE3{Suu<5R_)F_L9iEcM zksUm|=Wt5T1hFE0#Vq)0LDZ@ZvSBsQU?f|q3f?k^IA2( z*Ol1WptI0Wf4LT3B9;@&tY?WacWMpTQw-*YZ$E-7-*CR(>C1x9!nG}|_sl>pu6&K~ zRNmI&EVh;d&aEbFy_M-jtuS!FSrh~B$&U%hKMH3YEQh;oW=gKRlJT^vC2D#vKp zJm`s-kd7X+ zVK4|ZzLQXjH_Fm!b|$qY-0+m!WN&6?N7+MZ5(TP-*rXyxCIQgJ;Y1Yvj zvD>?c`R!5UxCvXO2&LIS=dn(C%>LT;DFV_>Sf~*5-K|s>gG;niS)*;hB%v)5R?Y3G zA$Pqn`S3&ZuH?fHQYFr(!?6!_NF9y^q^QnM@Xavx1g3hl1qglwu^M*C%mdLWd;wyv zfA|#P(2xr%^EdZIC?H^VcLD(PhC&C{%L*IVtlUOTeCQlgU!oa-m^6Mb(1TCDMuf9zfh6uVW&&$M3vR_k6attUiCAC3O-J)|FT%9(KPFIfcqY^AoHbSR zX90Ws9*wMH{y;v5(9v0FaEUY(bE;U0fB99ckh|Z(MLw!eci@EIJ(Z7}@wB&qd5T)s zNG8Y(OmRb$N3MIS>G0OA&)yL)_NOFg19|u0Cv;tu=M7vo-R!oT*M9%if#$RlIO1v- z3gpSG4xak=vPdU_wN3;NuQTbSD$d1FKQ`D=kQx??cXK@|k@KH}PFe%LUW-=Lf5Epy zin8%IpH#dI#Bo+26!4lA2&}-3>91rrH`&3F1E@0v|BmO6@=YQXf;bkxzr>U5HaJ22 zN>gv8KXGdPMDs?AiaDybSF2RzJ}pR)in}kB5z6wAn*Nvvaek zx=Sd1Y6w;@t@MA$;2(iff9vpJ&?#E2YYL{eWCnrUQDM|7Fc$K>Rj9qP6W4HY#ZU1_ zB`S2Co9u&6&e+Q2vD-fqVp%1_xGyNsqT=4>IFzrEL0}>0hZ-3x zyusJX>TIMwYov~jQ%w#{pW##CtD8~sxunZw*iOmd2SCR%pjQX+%|iQ1?8RjO zi+lQ3@%%avTKNkze_eODX+bYvXchZ-L1Gs&i_(|~gCRiN&=y9wiWf4nSobiPmPf`tGbc-zUT zc&RG>)e*D^$OC!2((?M9YrtIU_En(B`MG1VTs7|nINPRAQX2!-N}chjus|jf5G3@ z?qV5`0B}xSe?zI4;)@jz9oEp%OyKpRRjg00DL@O8lS}u@CDl18Tm7(r8r7B8%*i(u zL3F;RZoLI*VjKc_eAhMb4}ng;$-E00%0(KONXJ2umw1CptdAI%CToa{WHa(<+v(&o z*2!hOlgsU9s3miQ8IC$m^P!&Rs1?C&H&<~E))nV1f9p&c*$1PUx_s<|QA9&*Y<|Vg z&qa23&qmyoP~E(uC0-WyindldC)lcEat-7wy1KS_Pm+lFj@0^>gied~A^&M*X-|{2 zld>+?z{(D}IMB8r`=S_wIu5?x4d?X|pJsvSK+mQae(WS$VNiX@xGwv)u<8?<&OgoM zbmR=3e?}16LxTFG?m>n1e)A+7^c_0?Kc~|IqD5HO@+upNbtvle6Z+Sc#Tr+sZ$eE{ ziM&8pXje`ok?_6N;DPS$IXhP41%y}}UQ}v&WORCx&jb~GKKObB;)+7w?3SAnV z4KLWv0lw=(d;K5Mmu%_+ApyXbj_Lv+e$0!Wns^K`0i)=wb6#b@L&!($PXZVJ!X(bm1qU+>@$ve{L!5 zd7IVnW`$OiSb0ON_$O0859=1$POBvG*Vz^ zfs~k)T7@08Fw~wCw&b{PsM?JGQsU%(1kL*;xLec_lNUuc{c->GD=icGIz1-@PuX7* z*Wdf_!!npY{BzS>{=*MILQ8@cf7j$zPpJi-un`lYA5`hX4}JMqY1cMr3O9}ooM_|B zA{lInojhsv*6wDD*pbEwJ#nGa)e$)PI9J+^W@ zhB?&bAE5{1xKdEl!m{o{OE)#y%chr|yuql%Z_ zMglDoSe+{tBCGU`;|?uU@1}GM8-|x1M*=?#krh5}NYC0Z%44|-muN={2AZ!Yz+xVn&PrwmR^RIAu+->-czap}%=>1viU@Ozid2>>C%;R! zx3;$CkU8Smi}Qg6TuGWdLj-iLV@N}~by52nf2$jJnGjW#$Hd+FGzb{(*rj2X-=arD zzPvyOabE$>Ji`XkSZ*uA<8)Rl%D5CWGdqeWyNWs!uxz#tfi?PW%#petKx;S?VSocQ z89D(HAQCy&7vv~1&nm|a;c+(+cAkY+TdueL)x5~Q$B4Jo{8S1Og3!?Srm1s)xS;7KQjMT!BN2B=}yn@R{$z#g~`qglnPwL8!j)*x-OpagLnG<-Ve^WSJ z6ym!^9@T``DCSRwf_3PqvQAKLnEzEWDzhpn$~wtDfqjqW2*aF|I>zo?0a1l`BAJPK ztBFxcb*HAF;TC9=pDS4CvYL@up^4yWI-aW`-Yp?6;eP4s&#Ve!$t}coP-=-o_5X5o z|NfP{o|4F67cB-pLw72CD~9Pj1{eq#4v(yt#Y_SpIa%}ET!C#kpp=bgI_0~4`WLBf zq6VY;5-edMU6_jG+a!eMN_;Y2O|gDem|@LEXaoWb>vfi*ojI2uO#&K!^if_-#_6TR zc~KT>aabL`is?~Rj=@92uXvVz+Qh6KZg;K56F+K+J}ho8W{DQ~ruoT9HVq~?h#i$c zK}%Nj0;hZIU~N2C!^dhcU`b;ZRY`n1F)h$brOJdtfuBrUdvwJG=gut&?B@{98`aVP0QS^AH*hzA*Dp zr#q4O>+R5W$Tekiei`Dpa7oV5B${(CFZN>l%Mr?vT;~(XDTi=>1;wt?oM~)MgdoEq z#x2EffY{X`2F=CKrt1=R8*N1zb-uH}XVnxoi|9{R_hPT{4YuQa(NIx=th>mwYo`RA ziMIHX3j@&gTBhgEPjvzR_}}VmqQ2qZ)vn#%2WykG_-9$3tr1>O$bkfZ#LLIPE!k=2qC!ri6r7YUzkf-GSY}n`Dc!En&*#ach}*OW$+87JuFMS zXHnhQO-@i`|JIJ_OP8B4m z%)c0amuc+`0Im|D5j@>J%q_&$?C~OBDBS~pQ45XNbBM+8eo>xuRx!V|9;#~&> zX<01@G{1Lh7bChzd-Dl-^fm;{eO?>s5lF<%&`i z^n7qXy!cDsc-ZXPhSVcC+{*d{I}z8y)n&+kHP8|USI zHWss(D=d`jpr-qjPHJ;>1XKQDTpp!k)rElAc<@0kB=AoZ`#^quT8cH@NKW+cjYLR) zC-P6b$yw#zf35E(0-oRf?sv({*YDoG-+%IEAAf;kNHK$WPY`8$q9$-z&XS9KJWh@> z=sPb?0F`Ex-autJ6{@VA{r9pA$%9n=xx&jTTklVmicvx;O*05oMJm0|)Js`X>EtY( zuu4C?PA6`q>a@HV38H2d_f(-+a`Yk5W5H6Nt6>k;`xz_Yy9YF+Oa zL%Y5(&-WD{RPH(sIyV@{tSWck%Cqk<4IkAr^C}_ zKO-axSj%&i2M?^c7z|DRPR_r#e&Fkpy>)}MrY=H?C-DH_;hN=V^PA^O1jWV8wSxnSi$Kw|M`&r{D%MhJ^%R! z{_~IQC(6)H$qD~mOlBP3ae9=0jd@9Sk`*Ifl(U~I3KuP!@Ly97h6-%KuXj`4Lk%pC zmvA6x=ucCS3MrQtPT9|yx!Dd|8zNpK%s~S0t|AzB6v_m6I8QUoVD--o5{xHm z;>ntvroFQ86PhfT8;f^;d}BT~>X8iHmQZYC?3!XlpLnP$Du1LmoTkt~XkPe^?b(*I z!*QvJUX7oK~e-k8DLb)s~Qd59FDcnj22Rqa_>r za8gc4mNcRGz0XeasutTUP4L?)MKG3B(hb}MUe@o)MPtd@lHs_l#74vHX{Q=q#l4e7i69p1k?+WN%qBP{RK0&S0FS)0=v7 z7?DJS5?F(@6qA+6Q#+W2E+%4X9ayGq3!SJ?62_TN+l1To=hs$Ry!;x6G5(iI>h zSYgs*V@`!TyN9Gl8o8sm?(0JLxSz|B+3NJPLNG~_uhlw#sv(mI;0V*lS5(FhBzg)p zy7GiWCOd}OcRMAYmc{w}~L^hPKG74?oK2lw7Iq^uWQy zN*Fah|7hR`Ei9plD{#gjm$e}rRO{p96_|$kwRq5{FU+gKeUogJEVlotOwZppQsoM? zKx=Qd%w1TZe>Z#%pJH|IPsz9x)xIJp#k= z6a*BPhjx6Qb#2?18$3a2%610kOB<_VoQ*!!>R|jfikPC*>%3G0!89mcq|_1hQ_J@1 zCzwI?-^PG%3&yq|G~DYSr`z_=hxX5J?4Q54fBwP#`A3(p1OpfX(V3UY1Op*|K(mEe zflC+6#xh0@dGw@Zx9bNXi5uEu$9MDT-Eep>KdOiX+8oebUM;q%NGqC2++d$Yg z!?5t%67A^*{%;jUkt(7RsIK+f-|7baaaNq*(;@nB2x5|*<`v`?ZMr-;zXv64=N(R#Gxzp^CWU-OQ|*SUmpC zj6+9D4QLeMs@*~wEg013hQb;dLR~DZk!n3hK%z+OnxHXfcdpKD(4yskMlF(;^a1#k z2ye-;Go<_>+UYbq25a;G;C$*} ztI!JqsQwd}z%fkpws-&z_GPmG>$|14x0cb^ZpQ}Ny9a00>*(eE;_ds_OWPJ`#=OmK z@x#*MzIEOdh9^fiMIa_u7axL77W#O_sxGJafUAo!Gpzz)*~BJ)Y&ZHZ!+3JS0<+2R zf3kQ_O`2 zT3q`+kF5e-gBRp~e#>=n=h%no#WCOEHji!dc{nkRb>JIW=MpPKKer%MTqBl4hrqCU z)o3OXSe(w|L1lKE4FwIVjO|>hGo&D-(yW-IA88_!egM4B#Lu2Lv~?8ttTI_(Gz%qR z6*XjeImWJNmPKfCfL{-`4$<)&|K2|APqWE59cH};f15r5IG6DU0~3G3IXr^tMNA40 zj5=A>Q$e2j@uhL=mteRSJpJIxo>z3SA#fPnT6s~)b9jxjk&H3#pYjeLm&0_ddQlfw zyQ1Q^P)qzlqLgE|(i@#M5?rL0uirVw5WGfw5h=yqGiZ;A5IRJIm!j8r7*H|wbs`6< zpz^BAa143lr(++9-6DU^tb;`yM{nuFJ&cQrr)p>RA*&OKS{8sFL^`tC5G|y)3HXX^ zqC&XHS|-7e`pNSO?fQ6ZzJ8Fsxrpdy9{+KBS-KZ^johZ@_2a{(LH_WTA^&D+kbiT_ zkpF&ZkpKRcA^*eDApgTHL;lC5LH@^EhCDwx9YY+@FWlGhZr^`ToN6rng5FRp#p~G` z7Uy~^p^c34(Clhu{4odf)a6p6e6*!l2n1?Sp4US7l!A#9f=d2WlDrXy14L&-*Xx%W zD52Cc0U<4`^Lk9nE>1;f0;cIKqpC)SOxj8~l(kSQoQ{bhK!Ve3yi-Onrym5H^rWY; zNMATz(wClor@nu5Bl75lCF#7@y~3%az`)G{d1Nn;sIMCU3AzGIVwLWAcf%{XDkqeV zj?&>r`dcVa7wL4=L{~RB!$$b$XI0YSNUA(h{@4-+#xt|0Zq&Yg5ND2cZfA>q1HmA2MZN7Z{@Sv;sZ0Lzbv4itpo)MIL3G(Iht1FMvyqyfpP{k!TtUsP!;`_u)wZEIiDuE_bZT zPC$0C}^K)V6KCQ zU&-rM$V)&&jS=H4J#XCg*E-Scgvos6bVEm1%Zwz%l0CO>kZD%s|IF@sdq`m4OIWV6 zj2=xYTato|*{{GRlo15!a{-^7ss`}n`>QbK&^~4H77J8ytJGqfeGkwrOg!QMoKVyp z3?QcqXpnzXyp1El972bv%Z*0)H1iH!?*`>gC{NB*7aKrtfCeWG=T#tL)~|egnaCea z(-XS;N7Hih3t{K;d$^XxLJqF3KQ0lO+jX4|POD6Gp7Va3KE2`YU#cbPL*5bvs@f+w z)92~%v}a@GDnI80uhQ9b4&|6@?@Z-eJqLUbZEkuAXK_42U8z$JVUP|~+#_kn|+~l1g_Vfg`G~(M&BLWAbnP^u8=x1NQtDzBr zO;^-2l2qqd`YPfqXk-IOd68*Zr=H6fJL9}mw zQ!&Z`mzuA{CYq+Byo_(4qw#Fo3z5^W+w^9)X-JaNPS{}@Wuw% zT%j9Z^nUV2hmtuxU_}s6=)U)1Z4}YlLx0!_Ola|$oU85f_P7UOYs8dc?vzL1I}XeCpoN^;Hx^zb{1Tpk(Efim zNoE&~r1NwtF`Srwwl<(G;aVg56}r7oDZTSJnhRqx)|W-yb4Oefz5$!Kj2fWO8hdyp z-ZwpWZyCTc!5@$hJd@F?-0O>7qrjP`Qm$NPMvT_zsiS%$v~9IIV_o=cKbTJCIXja= zAA19JmNkzM>BNm@o0?|1-;`mlWwVO(#Nt`9uRis26PzJ`d}ODi&z0e6Xe2 zKTZ#hd{etGFeiZd%WmV?ugmi+Ff_~wq=T1dXW1whoHZmSpraTL>?+}|`VD`Be)?&G zC#yk^0G`9BD?ZDQfn&-kZ9+pb;A_Ds`{_~D!)oh7EZP18*&G@VZeAD=9+*N* zf+WmL85hw?7VZdv?a-5izkz>;AUVjSyBprNP;MRyDQ&%+32Nq@0Dbd5Ja;{-Y^dmX zqF^zF!+^)TFh681`@2EYP+weCgN+bU7IcrX?}8)kfnWIqoh{GGnLq)gHBG=QB1*>! zp%w2AE5g=_s~@80r>B|FJH&>-#Yjfkxi~YefR$IcB+sxIB(1U_YY%@WpNt7*7_yYM zAqjmHTrJc@@aYAjuul`TY`AavlB2^gwEsmmi7_#!_Fu!b|7vRMsW|FRtAY_AHmkq5 zRA8lj%6e%@zbZ{O{|Twc;lowMaOpJlvT7Vwi>hI^bY>y`SP5hdq}mw(U@JKj(KbR%9* zkfAr|dm};H;ZX&CsX-HH(6rFA-dHy7Zef^snr;YTh8c@{@PM@s2<{qQ;obYCJ-x&{ zPPe+_-oO3f{qw!0CD_H$F!|K2&SJK#Fe^gL`~j{ zM}F}hb;}!nxu)zB4U`x4O0@=}R<~4iVo{b5?Sbk#pqfrDv}fa*khN7K%;T~Ksk9)M zO`1G=`#Le8JA~8Z!n(}kb(%>#tv*y`m_Avm>|(*wSHZoL(0|EwKY7FKBh`sz+=qzf zL))$o_gfw>mg9F$fhiy|MLm^OJY6`8O-$W%B6i(m3U{qC=+K&z^G7Y))!OZa+I8rI z6NpI!6k(HQ*_m&_CcCOu)6LO*4p7pL|nN&R6dALsA4?nG;Q&tE-%y0myZIydrdYO8z0X*ph2 zr9`qe;%LPrGab=>4nmuZ7n`I>Keo8MJ- zq|W=7>Q3w_>&4W=7e_EnSw$6Z^Qid$bNFf2!@N zbCi74iF~{aKPwWOJ8UtW4BcktWO{V2p}aq>P9gdaN(zlH)}z{N3xYdku;R#dQdAkl zK9zSAf~}Ft67(fxw7T+GH$Dz(3x@2*9X=)G-@gB^f_?DV#oYpO&10KyTeL1V2)1NA zk&;=keVhn4ifh!jn<9d7oz*>6e;4d9qh3c=+BLIYL0F!B)9HP4%QUFI5(*S`K7peB0R zAf;PlIBwj8$>ucD0p z>=w$1$~*s-#J3Ntd~4*#UsZE2NB{F2#42ON{lbXVA9HOhXkST4Sy<;;t!PI=dpS;Q}(S$`8P(Ck%Vp`Z=0}V zmL11+%i{U0+pKKe*|EbasxB-U1A3Yk4s*X{X8pucPMBrWQVaC*e^_;RA?MS51My8G z3Ck|K8R~xBAp5vns9P4cgUZ&P0Qd z0r|#g*M!=dJ1rq>y7-=BE-)%Bgjsh2-S^@XgOKt9(_Sf8dhSRpa6WHva;9Kfd*E$>d9Z2KTwyGj18*`g2-<)jvUNOv(Jw z=f!9gp|>V8|CpsCxh09r>|@bK;sWo7u%j(m?3v^fC$JDCSm@H$pIk}dfrEd;Cj ze<%W4!&gIA%SGZ>&y}SV(O`b!#LX`f#K``9IdTd}XeuZie^wQ#BI%1%X?5A=H-^-I zSKb(k(k@}Our71CUd&zFxpg(pnxcmC)BOJO<)~+1Q|~D4Z{-W7Y!=sZ0>`ijPNZPH zDj|=!jt@L{X-^H4)I%}<1Ra~RD6;8~`>$VtSb~$cMY4JzkE*`wl&h@yNXzT7>#yk& zv5(a5_7uf5e|t%*I>a7=!8s$TaW$(MXcs>3rH^_lcA82F>nIaPl#GfgljpL>V|`D8 z-{R7HD_O`H_%zXuSA#g&*yKVF_^a{wgm`JR;}oQVz_giLQKcp+%hv)y3YmSpTSI=M z5ZD5dc9Bq{#xKmoaM?f2G}94sa#~da^SE|LS(1v?f1FO0%a`M*Hy2-|yzN<9r=h*a ze9tIv3$YMz=gaHt>3Kxje=#Up9o9LeBmTCCMF@-7b0 zm$5?0fQu6Sr1}bNcoQZpxzo(I%3%)JrnX28y(Nf zWBglte?%VV*?2^Nu%41pKC7y%oBm&v(khH6MDg?az_)<;Uf9p5IWz=e?lSx*Lz*6h!?|FV1A8-AEmwM$ihea7EJl<3Dh9 ze@x)`u3}{XbNg1-_>aQfT;h1MD?-3&#&eGGJ!3*{G2KP2CCPT3gf|MBLT0~z3a_dA>{AB7P`|&6U`pJn2hd}&6Y!rm(s=BYn|D!g4 z*ej*|nY=^L-gj&!Gx(^>73tjJ9)lGBe?9KskVHD=78XuC9eQn_+XoW7rUTh%ap)R^ z^NZc>7y}cZ+!__%;<2(hX|{JojqgB}Ns7%)7i=%uf!EVPaY$cg>fxDVQPqiXO%@nv z3lURAD*~|;BBY0n`+*?~>0GI-t!k^T?WKe=r`d z6REn9up#5Q&_OWi%=$*+l}|9ejd$bbT;?^6Kst51xpL1>dtBo6%#L4n=L!V9V|i|3 zTg3MX-Fd7PHEXYQJG-bgj~!IzqV$>;ye1~_oCVgn)|tVs3#0pvToRJyXy8cmhyig_ za+7FPNlE*8ZIn?ByD#Lf0P}t2?M3-a|(=~77H=?)!iDb^Zu}^Ks#yaDSA}d zyHa}1a;i()4t+BvX5=!>=cfTMA7WwLl(UB4*RSsMKMGWm9Ae=$vm%ZhfZFQw$< zNPdkDzGf5r}tG2+?AIa`eCmst4TygWkX*tdRDUP{x912Zm9`cZC z>yT8_uW_DD>wE~`4a9VyxRY=Lv<lSXy0-$b;8QaE{I0Jv($pJyK|8qZUK;rfToCPa)h*-3QT8<@saOG$bJS!$n` z85Hj%Y_Jg4Z53xB!qO37ECAm7S>eEjDlZ4nQ*&LoDc}c(TAn1J((R!{3`)k{n0ayH z-p1=8W6J*^ORGz`m!EF(2}vh=K9Lpqn<{Bq2woX{JIc?$fBP11IFfwy=$`FZAaPUP z7u`ei{iA#O7fM@??g@0>OCEeTNbZyFLOoS=Hfio^Pt@@H5}-Lf$(d{_N&KEvRYh-N z`()Fd?a8M^tadKM`LWO7tJ2IzdI_dD$4FO{m(}iE~t^^{j35TZnTs zo5+Mq?VyO;D^Z*M)L&k| z`mwGjDwMY#5GwQ~uL$IBquG8USpyXXWdb-_M#%$}8?Y{gh_{~n zE)i0NW*&qRda5h(Nv#oISLLQuF?&LRLG5WR~WEz3lL77 z5ENx0B)`!m?9Xg?nieNKr!F&j)~9*Z$Lau!v~>R7eH-YV9DNu^9k;uzs$p-~vHYcL ze;DsE&PSv|^>Ay;#I7M0cFX%w>WkcBU=OxE`{srPVktH|T{L20^7Us4_Z58_8&0Qb zd(FW1FFO@gjQffIxVGt5hU>Tl^@&M5Nx9ghtZID_0|&q?_tl?;l-L`b3Z6Dt2iI$; zumcxqBn<-4M_(wGCwX!8;Oo!Ng--Moe{`b1zZ=g)84wEaLih&l^&OieI>B0dgLiND z_JOl15GYkvz$)p7MCM0I8%S7|!? zPj+op(QVyU9qN!Kcq!l31}l+9Ci`JaJ6+Ep!bEsdT&dGq1P9%(er^y9sF8>mB?l*M^F`k%^Lq#0fh zx3$7bwvkY+@n)d8)iYU(Hal-?^74bNo)sMid0y}_@VN#&aBXh(;^p&K&-R}0(}t~M zy?FVGP{VOKoVBg%3#dbzOwZa{f4qJFnl!LUNLreSihEemHa=;^!VejtgwySo+COfS z$`9KrKO~jEX{-DVsr>u4%D*R-|Ik+X52W%R+baK&RL)OM$KwCDq3}mtk2ZyLRhO*| zu@-68w&8z#Z!70#COc2G{>#@-et1rsoU}IhfmFAi-|+@--u*Qpb_H{_S{<|ln|GLA0iw*{) zNgLPNCtRy;+v)pcm-8pd@h0l>nt}uuaV@Q&j%_k)TfmJgBQdV0#z;rdI5U1DOuWscU=?i@WDh5>!~}_O1IL_|M>&6204A1cn%A^!EcR+OOed`3(UetT5|=C! zt3`jFmQ@X_V=npwdxFzOj5J^xt9FTvE^OnXco8o;#+8~Qe^v1uL8q6s{nZrT9@{Sx z3Kq6Gy!o%4z#_bl*tXA%qcD=-^n_w3oT}?!fOj)+&kb*~2Z#N<7>;M7tm=vO&OIzt zhMHo@NWIVqZZ@wDcc}A+5?3(c{rsRDla!AHI_Gh3I8>&05$lphBXw8;G0Wfw!;D7u z7HGD=Y(VI?f2gn#LKv3ga@w@RT<#)%CfG@GbUAL$4sD`TH~xNkh7#hW@f9z6?Hr;U_GCf%Ao~kzky=*h7#-7`7#)T zPlGHue<`b6Mon5GW=(qGce?igYQwu#d!x1ko-)E;3eaNkchGHTXe*X~J`SvqrK+W4 zSdRVQ&~;~kCqk_?$R&Q*zBtO%Xrcry2l(@J3h&)G;95fm>3Ye7;p?pKXkvFG4eN?7 z7Rz2(H8}cX%(1fh@FQg_BS9Q@w)?;S41ZiTe{6qx^>6Hq=)A{TrO-)i>k=+ zTGI7lsgu`#Yw1#tq08kI0;_7n^cvAEa`p#A^m%2zTebs6bpKFTW{MxjAka=X);hhB zI1Y?1dX3ph`CeL^6pw~XL%C{xd2XWHFw2y+HF~B--_jT~G&;)|^JbOf`(bhuCsja0 zf71GpplbzM!PabQ(n6fa(|ow29QyS}(YcvOuq{s%RL0+HPHrwy)kz~|;S`_CC2zv@d<&RZPb5V>IN*5S>57#Tw^ZX|V8^C=ix7YJ zXhD#*#d#S!O$JH*>HW*6f+d#)Mm+t^H&2hIzj?Uzn};uc^Ud>tzsS@YvcNW!mAQ{J z(daxsf7!|n7PKIDVmYlWX+vO)O)va~^STM9lb=mgPzN1R3Yv=3<-iM(^oRAsRgiYv z*qiO;km+5-1~eD0L-FX9^(ca88ja(6CqOgWWQZI5Up7^4SqYMOY}+X&r+Vl`CJ4vl zdVq6LbBcP+D2*yj{ZPb8GfAYj_!vBS7TUEi(qosFDFZwLKbM!(DFZHlL)?wvdOk2a zQZ0@?KHwHk#zY0B9lX`~Fgpy2C2du2ZH%c84XT_o~uYH6%_{H_+}m4M(E zy0HNC4m%5Qd{gU3t~2gx0srFcEL72c0UHZZcT?*^Zk29-U4Bu^fS9_eWng!Cce4(^ zn1e>*>ZVqLd-X&k*2>vt@K0K2j`dh4_h9L~bokRxEF7y4XZA3E4NPzQkL&#jgz8ME zb?=WG$zW@+JZ*CDzaS9krz_tcsjn`VW^OXMd1S}F>O!s`mo})APv`B?&yc1DZclsQ zt~uV5g9dB@+?#V5u(bm9z_I%t zdc(r)^tDK}3%k&V=)F((h+!Xw{);{`?_Ii|w3h9&6u3dZBbZ_62+Z&)1T!4+`k{^( zY=mIX`y$1-m1)zi^D-sm1iMuCIrknhlxW=msicmEoBn`*m*iqjlJi`cqdnTqRPXze zySeI5(~7!UHbf7jk3Hm&VXw@qU|$A(@@06Zo&w(8P0rnFZRG%@TrF6Gdna+{cGAu} z*n<5e#;>?{stSLBwBH&{Z6Wt!Gp_v-pOvjMq30=`W^;Hi?%_~p6?1Vg+uZJE>(Zq@ z`EClqTbt;AMU3s}oaDvvLJOF9O`@bjfNIZt4hE|-!=bkoNfOuw8q*EdSvR16YUwZiPxQ+r{c^c$4uMZ_6M>le z?Qcc%ZyzaSh+miR38ssGfBQ&H$yLbRFq@h-&8sf~QFmGvlX6nYI90)bWU8KVpYFr6VA0?VsQa0hz%2tTC7?}_ z2bg$$sir+rB4(-_zrRn1A2n^#uvp=WmNH3Rv>}Zm_NJE+E&~;R{op~8RpY#suIRoQ4$s8rReM2Yoa2X~be@7o>o%C`FVq1q#>R><7$YNFY;Ybky| z?Aq)hG=n@e=i4%B;WjbyVEIE?{*aWTJ#QQ602?SVUoH+lPRIJJcm@0E!T*BLG62Ud z{bLhXDlk@ITWoY8 z>!^78`n&GrqC*dMAg}qXm)QB|YlYGIsJvOI|l7^rGzJyGMae)TZ)-ajcNz{!wH;c*dxvSn+X}z%K(d z0Uww3F9Rel%Uz$ysz7)ax=qx>Ps_2qJs#b~p>;N0z8lWjsbql)SksMcx(?Cj$q*_I z=M$GlFat|}vg<4xww-zJVqhjK(6M_<$6jZge8VIlx!NJ!T4roUVBygnCh0=JX^L7P zy#1&&du_O2#KpURH|)WBud9OqEf63fkq9mdtf_tw!y#xs<}I!1R_`Pjjja@@wAHXn z1OHh4AOq<%G(A`8qEWQN#iw**%z<+raMpxqd4Ms0wl_dyZ5%;}^c@1}Ln$5`i4yAL zB&BC6yYL#CL2QbIpk%0Y*`Y&M7WXTx7-d-8I+Gz9I{W=TbOw8b4(aXCLMGxK5_Ibg z2cHfTl?G=rT$P4WDUGF5U!;?b)AMZfT6|`VUALQNpxibbg2v*YyWuVOOZWT;bihW0 z1s-RAb!H+M2luc_LZa!)CLj@d&Xdt7Nt3mcvM$#k4={)rqGpz)LuEvkeLw}$huHG# zW|`c47{;_MHoMCIWYb?jN3zUhy?~;fWJ|B628%(VC>!bdZIK!HUmi=#YhKK<0YvAK zPx=fK*59b`63=910S-b;5_L$JDLO!`N1KR$G>x#)X%MU{2{`K2sl+}c)LC1ld9oLQ z6MFIBlp4;K1?(!3!Cy3hFjvhts~SBK-7-Wr?L zz+cj8L55$owp(#lZ_6f9)!xD%D%jk?=c_|n*`yT1rBysu=06QyYU*%_)^>fMB_VH1 zsJfICZG?JCjbY_dY=QmhWs;@C(?lYd4l@HzfByQj?db|~pr|=ox-dn0Sn8@S?BnJ3_k?Xhi1ZPgmUW6bHS@bB#X zmjd`=txmukIRz02gM3O<37Lf0u1D12tf>sq=1l zoEhacz1|H>nP`#F#H6>jgb@^{wIxb;!vKuIOZ6puZ-NQy%BkCR7 z52MZoGlAZ2^4~*~0Zy8Rq`QK)IQ{mw$yd~XKz?VRm;5vXHUWE=Gc^OH4xPlKn?}M; zm(5Y9VdSTm<~0LhfAO$kEuz@AVu^kY9t*zR+(lDH)sVGgg&mNh87b#kRF&Tc|NW3S zSt8*2r_Gj1Wj%#sIK`2q4W0$g;kSBx{tLxO6a!49qDf<~H03KGFZ9Jez>}&RROe%~sYf>_Q7lSM;7l+&vccydg(0J33`f4Z4GtbJbdQ;XwZcidO+0X=sSt@tk4LM{f zO{rM>WSpnfjmd$XlFy_7LK9mJGSznZFv5&)D)>Bme~aPVd&i-2AYDghVqGFt=y*-2dXcY3BB8cbUhY*lJ53O42C-tfWEq# zHcQ9wO|EF{B8Ea-+50=*JGs$A#g2Zn3T`SlHJ`_-VL9zg0kf7bi7Rw{#n--}Z}G8R zKq0%CfBlP?Zj$co2F3_fU-|}~PSeXSTMH+nuE~;fKj_?5&Qbt%Jd52<3l3 zqxhd6Y#oAIJ9%w!4k7T)X$R`27(rKuzWm#bTbAnQEY?F`(N1c}B;{{A(xAeV8cVTW znp8Ts(Am+Ebf?y2t2>VFP$C*iV@S9`t=y`~8S%;g^QzFJF0 ze?q*+>j|)tXrtx87vh)Ctqq>%k%a6j#&qDQ)mt?qChwIMZS7W(P-ogyx}iy;C9W%C zWtA?C2HNprR7~-@dX}2Qyn5EtaanokIv3il9i$-H%~?5`jkCFSCvDPaSH$wmphdU3 z-u@F93hqBS_70m6&0*QRC2w{MIY@5Xe@L=A6^-Ggk^gv;O;vR&hn>jBnEkRql43_p z1NkWr#Ot2R#*fh;**)FVfX}j{*~!h&yUisc@zQc5q>>^+;zV&aPlmy?i1vJORS6{> zHfb)`qx%tHDoFRrw|SmZ#~(j9d}MSoIE=lM7!)%G>jKdjGDRuyEsJzx6VSt7e|G|I zTpH!fdf*%If63yWJrCMEdmi3~ zXHOd%?^bk~ot<6Y*j-VaIW@mj9syM3sq(7jJ~wn{_Pkh{mUGQZvs=`9vf@{*=gZN0 z+ZDV9tzOx zx=bTHhvw;Fe~5VKt%NA%BXi8LGJ6!Nii{Bj9$BCZlW%uXRr|6Ee?^#$4#gHrmJ-IJdtd>$XcV17#m`X{ zjo^bxYMfUQ2!*G|60a=1N=A@k*XhhLP#Vt+w-GGtf~9x)e@e&70oM` z(0fMK=SD)dtnRqTF1!btzJ&+ka~dNkgak75z5+3>E_k*pcitJv#l`Dee>dJhmp_h_ zfA8qUqi%75o=0z_H>mfzBh*3$H+2RSg??Qc8#VlHMz`@^)+ij4AThREy9q)~oVi~4 zP@Ty+JI|Z>d2J5S6oM!cFsxsi?c9mA;zjj)omXd|vWhX~;MOn&rg#iH6@FWzRRpGd zgim`8s2}oCaimd+PjwI;MfMesgFz<~f0g`~eXuibQgN@rOsp(Yq87ITs%W{{to4F zqyqKAKH_;mi9O>s6(f2sO3 zFy|K$I9NT@!lo#X}cQ+HoV zg!Z7KF!$akP-ixEnTAtoQQc}RFc{FS$gNDSqB5)q7?`egyO-t)pV4h-1xtd}Xl<4J zkzqGlS$yW}uRrh@#gY^dq1Gi{f4R%q&7*=l%IQSB=M0aKiA#EepR2(}Gkj`|oRp9F zUu0~7AuW(lb2{H_Mv!p0_ZDH@9W^AH0syJvwR+!p?T6?3k>;F6yt!OxUeCsLJ{jMf zH&K&swC_{%t6ww&=U2bz*cyK+e$i)Y|J;RV^qJYaU#w%a1@WdGququ0f7Lbmi*$|t zopUtbzJv6gMLWEXQ}pk?2&d>TF5Kap>?E!K(;R>cob;FI0KD`7G^$+EGS&I#aNi}A zYzTQX-m%_utCq;`EXvH=E`hhY8UbX|wJv4=S(9mhGMdYdEl{pQv?zm#8(YCrNxm!s zx*mN&GdbZ^@s8wj>y;RV!e6=`%2W~%0G z>CWlG(ikuAOT-?91fO}FX%sgh&NQ-wT+#$gD&5%LyJ=o@y;@$>fA1!Amq7L9_$F+2 zp_u^eo)?YL)^E%si_eNs&x>+;mexWyj9T}px9DK=yJR5NgM4mZuGw-H%Qe3=FIKmB zvtlt8ia6ULIl%In_heSb%?Qi08|+MA!Gu0u%>*YsH(5R9UUp~8?_F*wBf!G??N>1c zcZpg_c&lYlAmsAUm&TL=6Mw~z*5WQxT#XN(6nmLciSzLc19RV*DJLD(K7MD$D>U4h z$+?Fv(m1NRoh9$H$v7P@OGSh_tag?Vr`*>e}_$;#@!}?w|@hXx4lF{o@WVU z4t2Y3i3)4@b;rQoOJ}!)q@$N{x(?k6oN}X0NwxLsGWn>S)9pd9`=VHK#A-6m>zr}exl*KzY2x#4vHaOd~KIsL<1auaV^5Qmlaza225|9U*FVQC&3y# zGmTsq`M08O`9q>(gTN{O2G?9Qm3@E`6Oe-;*Rc?@mvW z(D$V4lcadR!CMCPhx6)aafCoh^g$d2%Xqcc8$7s7$dBaz#ov#I4Z&9r%vE!NEdNTV8He^Pk#0y;E z#^A8d5Z%-mNp~HosmlW|eyBF-Gv{Ox>_zn4w?ky{Svm6R>=B{lpFpKe(zn<=^5!)_yozw6x zn05rts?%(kPjZ$IEDV8+!9=80(-J12zACvX5TIY*IbT!SycGcSc zRs^u&07v=ujlSHq1Q^xaS*#Tr*n^<*k)@kZqz@h;OtZ-O0+tz*AGz38!Ng1vp)6B> zMqJ%wZ9C;N)+!LW%yz0xBPMftbAEj%Q_#@>3(S|MlU364YVrb6jV{C z?C(_m)9ERLh9W!dvvm5=V#CIzTG3)5+Ij+qti8wxgrlM(OtT9iYm#fBxPj+dcjCT9p?KU zM{k^s^2CyFQrUY&{RDHD3P%Gb0dtozM*|gqLLm6Yf2_?PL zD>Wx6IX`cVk^~69EF$Ve67x|+GeNXFfN*l))ZiTJC!}HrGT^@$5wv)Ncq`vzXgJL} zy!z~VBI`f23;CLe6-NPm1Syi0Y(+ zw=TaCCzt?o;5bO<+~t zaZ3z_#>p$VrNrRADts&at!*}R3F_?ZP3JIMZs!tZq27VzL*F0fK`On_%d0$ao@VcO>{`;=ETuwek#%=atOw?4Oj*`=JN3|ezY zlF4YXRMi97b-?6f)&BDp<2Nhj-aUwOKaht*qY~k|8t+<6drwW9k%jK#K+_%U9J6M- zrt!NOkWT_q=xS(eyFZ-qyRD5cWW}R>&=hC%X~GH%^AX&bOy_AMIxTgt_pQ1rYhS=j+(QTnL>!>aOCKK zx0J$+;Q09o*ec&6UA{j;y$m z$iM}}fhBYuuxMC=`J4;qx=y?qzZzKLh^-tJ&HN~fcCQ*$p`)dI5%XO;OXDJMTr(7N zbLcMqJhw0$uhtLA@h||Ytpt_vgP7t~?u|<085RWi$I|s#~983MI7*&53f=F+$-LTpQd&1 z{;nkO7$KB*j;)@%Q zL`Qh0>0GpbDU*hF{sp2Wih{T#$B|>8<}ljf8w?Up8v|%RlufIoDs6yu zBy%ygjOEU^V=F~>3&GwXd3Rmo8xh_4`m*J9R@b3-w$_cp`hrV*PonT%D5un~0l>Qk z0Dm}N0B})#Q!P}uf=SHr?-&5QKS%uUFnYv*n{9P}w*Mm|f$x_mC!Lb6+;}ALcW$VP zJym=|Z`W&_c{CjOjsa_xveLT^3~tgw$`4jyi3I|e-JHrW#Du*_+~^42^4H-mX=3dm zsd{>DB-v>nQikGy<5`{Q|~Ie_y-gD^V*q;j3tm} z3%#L#7w3OYmt^k^?ZY|_Z*#Wg?p768|_z?%+vE$r0=u5nAJS;JeG9t`;S|J z&aY+C!C*$NNe5|W!x?_nZu46V`5e7~t^{F!=4V+sqnAygm*xVlIikwpEH@M+zcU=i zqJd$6MVI;WX?}yJwmAZ5T5V$VQ01)l@*_>*lUt8o3{-?hz@r3WI9*^yF39qIoaW<- zup0QfWbjCwClcn#Li9{Vbvi0Xm!ZP|!Yi4&@3Tp!60QUIO9g8(m*9c~1{3U; zYM=rQ7vG&lfqLkP2Y!$!y)^|!RN9A~M5Z^_myVzUFMrIWE)6&M9xB-S<|#x&lc%Z< zX(i;mX=4+pKNR<)@~f(dBI_7A&}>kI^cGqv9kDXYai$1I%{0!7g&R|D5s5- z^g?{MwSP~f3z+^7Z6S%Z9FH%bA^(!o2L<&>BtE zs<9IM+WqcOJT#A6wFd`D<)n%r3|x_{fdGF%fWLUYmP~}$1NpJm6*@JFwMh(Ltl40q zi0!=62^y{8L}NV?+lkvwP^Oht;7VCwTi+*#)IEP!ZeR820HH!XwN>ZrWbtheQ@VhU zjj;*^{A|qd-kBJ?z*87d%6#O;PMIxLf7GW&{;5p-pnX%59}Si>h)@V9LiOT<4|^~dbAEOK#Ve1dh?EOw*(OTpwWed z10R2cy~S#6-ry2H?$aX`KDtwMa22%?Ge+^aLoQd{zydnL=4}H{B--psNxEo|(5Cre*3Cq$}z=^=dg& zZ|tV~)B$uh^@>luYMFYS&M|e@U1PziH+Fy1ed=}UOugn)uR~KmfXM&A>g#eOBQqA+ zg%CmT&Ipb1@JDtwsqy1%mXG2=8?VPyZ1lwV@{B<73p+$K9zNZ%I3kIg?Rn#2O_@G6 zjA3R2wB?Iz3I{O!I8Ccl_;;F}XH!u$AJRGoxS0>PZL=bH)?xabBy;0yq(ECVq{@HX zNlzkPQq6wRp}1?Vyb^VmQ>2r5vGP=jE#Mdaq10v?+(5)KUn21r&cwsxE2oQpUApkn zP5j_=y66@c4?@r_z}#*k7TtB0YYsVoM^2hc_>mVv>}}Alhhf5;ho|W@9fCPnFktu* z=e`&qU`g>up|5VL&^+1-!mrC%TupzX4lxI>)hM{#;@gF_MMufeDljU9)Gxw`dM8&z z;0a&M1>egNJ#-<8ZBy}=L8we2jT52g96>DZOAR*`_30;~`wHVCO^+X(s;;|pC{WnE z92ODr_LzJKyVLu;)bXD0y5>=b__-kG5h$aK-t}DG!Y>@ zXs8}@JD}i*9vtc(haR>1mdL~zgE8ME;!w z#6CRpV25iN3b?&G3O|1n>#GW}o1#c7U1Mo;Hm})m!eSOZEO{ZANZr#giurH#x3>SE z-~Zv8hyNw9A;H*4wzqs-RCy7=MKHQ5#YGjuMMEoHNE3fugIMKNU#JvV9Z(M~{}A|n1-G+LMI9qKlhO2_p?X&fAUMcV5Kh$N z9@_!o_e*Jk>nVH)beqpP|KwwxsW!{y1p(2_iw^4nq+G`Q=NaB6Z8cZ6YrIMu8WV;*~EQV<2bkq1z(35KTYC9ut3>ZWY+}w|XZn&R+Y7(=+H* zlMH0arfBAYlh%4dispTR3%djL^VKusg}9>rarM<$e1mX+1G`p`+UOY&f=0_aZeMt* z3vVb@0BMA5jHMem%f3tzQ?08GP1Xwe2F5%sa023LL_r1QEAHUCteSn*E+LSFpzdg@ za-c_Fd7LH;zWxlI0-|4t1K_V&I_<4rZQ9b;qOa55`u%NMh=Z@ISia)F9haU~0~UX` z<$)liUwb6(>+Jy?paE@Uo7c1$RzbwQ6`AFhXa*W+1!+3v45V3#lQvA1hcD6Yht+f#TwUO$Rxbh2J-ZuJM z;cq1Aa=5%PzCD^I55DuqK}W{r4f9F;w~7Drd-$JA{Zs!p=&J`{y$1)ME)O4^Y$W=L zf6wMxz`F(z`d#bN_8*gf!L9*qSe(@282JQI-KRoY>`jy3CR?ArfeN4gx66Ok&&8Rb zPJ-<}n%GAEmY}aWmnligep_~wzd^H`fkyT_FErYV^R`rO3WLyA?d{dQ$gtt0*EsJ%l6q_S@tS5abJftS9%Oy{h-% zfvx^8gy6x02K&ju5IhW8(9ohfvFv;tfSV# za%=%NQ_Y{6b9ONBln}2@lOn?4QR)sa(}|UIu?je~bYT>rT<%F6HqC#CM&+@GNH_$_ zqo0LzAWj0s^uu|ZR1+{Q@Dh(`COnOk=RO=E8(o9ZjV@e-a4=b)YHz8+8=ViKXu&B| z#9#?>=ux7ItRpA++uyn)vrA#M7#?tBHA2aXocadHLwzDACK1xX;4`>O9#U^fr#bQ| z!K1c_%Ou@TbY#Aj*t~x{D8gGrE@(N@8&>(5T7S8F>$NfXWc>K524X$_9i z9k<6=30?B_iV`b;s`?9IY!}XAH z&EJKpvN7(m@myofBGEt9F1w*aPg!6dntdJi0ZBXN{_=&uA%BR_yqnyFjx0-^O#Zb9 zZ8dTekIK+V-(Gw~GfGO3X+BA)F8R)F-i(RiRLV#)mAKo?WCm_CI*_L8H4_cZsc*ip zBlWa@s6%2c=XrnsjV8y4dy3^1^_Igm%nH}%u+e9+o7bQ2m3keTVCrEx#2YnLn2|*%Xn!0Fo9>kRncFuMa-N#*cPTvCc~&eJ80^u3Bsg@b!vQX9 zWazNVz$chaWZE`(>=j$;K9C8sw}wr^H^}^)P*0%k(G1~{lma{+=yN~g=~Gp|Tr?r{ zH;AL)4Q+pynaoGlc@^E*&J=?CoTVi(E-Tw+X&_n^gsMstrTU3V^K))TZPY=O=q}`W z0DQH;Ak3uZka9oB;i>Ftzz3Z|9p z&?0xH{4lu-Aiwos{Ek6LnD||Q_nimcw+uWGa~Y|8HP1%kN`c)@s=PgaodMn2#ehkA zS?quMr)l-}qIjpwjXgSmHh`@s>^c5~N|q)YUZ|lqfO-g(D%j&>(pQ=lY+Lh#iohCq zPFrS-Qo?o68r5{=;ceB9)~RN)k$qVsGp!R&HzKt7RdI^QVXe&mCrQts(Mw%$K)%5p z2^^w06M8jfIw=91*p1il= z#bFtEGu|HYPj)#txQA(-?`_cRgJ{gZxFBgi1ar+<@#W`=KK`RI<=rnl-Q0>= zxgA`u4<@CFtq@HrOzY_9Vz_k)_)c`n6}z?Fm;TKQS7l><3lv{Ao?x;8w`~My*1Ufz zXVYQUod#9kv{`$69VxYq@@g{1)agVdZ=P?;3};9brjxe726i#pNi9xm4aDYB8z;9{ zc~!I8U1)7Z;&q2Di&shEfJ~ImIz*Nh6)u6wf2=V+Vx6}^kk#+g+41q1z1U>F%l|GJ z%=wzfXn_%eq5`WFE+=t$;F+>@F^YfhpxJcnJ?xjnwO}{~z9l<7dtPv*7g*~r;IJVj z63<nk7CPvu&F8y_iT=6SiHPC;RS~yao zP=8m%W%3cNfReTZf|@(f;hZr$=3D%@#l30iV=EtBc)sr5vIA;~Wxj2F$?^tPx5J{6 zj2WGl6?AkoAHa)%rj;(~PWO_ug`uerUJy1BCoPh0`mpbVz!y;vZ&Kf>Nd?Yv)X)yCS%Lo84b}ZiC7&> zA;q03obsPTl2aLeqj``SQ569Fh%xm8PeI~rf%s*B>@?!kXTPIiQ^tQx7Jy->yurcY zAQ5Es`AR=8pfn=g(^!$4X#INbrh%Nh(qtqN@ZdqRf0}7cJ+G3qszk>lco%Y%B`I3} zC7Q9mW5#Pkn5@n&1!U2)v`#}81I!+!eD`RP=QIy&ADynl4>;&&a*<(y(1&toZ`2{n zpxyfHVv8R73fszsG=P8Yz2~ox?Ai1wuA@sl=7dNV0Hi#9aavkMk<{#HJe?^>{UQ=OK)+2B@&! zhbe%_MA!bV88?45gMX&0SJ#obDZDgZuc=7lhK78EVbhhHp`bDvPCGS2i z?&X**TyLZU?D-%++>m1&{Co)LKF~jOaejD6x$Z5j+m1_62*`TVau(eJly!M4 zdKX9&!))Mw+ejWZ;*MTPfDm9V8lq#71(J`A{t zwVXvm(nkhx?IgTfUmR4`pM@&f8$95eH1Er4RgLpu1~6}KdpL2b8r--`6~N6TMd8RD z%%6EXfF4#QfFXo`sZq7Sdv|ZgQN5_SX zU+wr0e?7FL9<>yi0k+*Ip;^cWmGjNeSvb?rW4eaA6jYW2hUfldR-N_^1_xk*{mkvJ z^3DI&;X3b3uXM7*mwaLaO#ye8%3=d9e+ZEn&Ln*UpanWv2qluR@IGaSbk6;=`+ri; zYv`jX_tB0TJbd-g@#bNu!agDJ>}e;0VJBvmN~cbT*0Azlsm5xdyDalh#mAz&C=z{9 zw)XXBr}wKhu~m{az|vYWNrxX(O$sCpy&4#XGSlB}%1R$_V82f8y>MGxS?8&939E0n zyb!GNe`1$_V*@6C;YT6SWHb^@{0X9SpXjG=3uTgwr8Oab-sY}JCc)?s9w3zAs*5MY zTnXWny|(SHc0qjcTYea;1z|2{nV6dqrf9VJtFCPcjPjpjZ`!pQFWIqP-S;4_~5b7AS?9 zsi?)nPXN4sN7M460^!Sk`d${n*Prn%8<%W0P>cZZZ29{P7$<_R3@I;1VkapX%Sbaj ziCqsV(5S#%a$V}vyy~kLaq!QsE)%+hAYLgD;d-cMV%o3r0zx%mcgpttSiY)*2-a5+ zqs_!;LpGgYk3{H^CowIQYfg*$>5%{+gDtN;Xykf-t`ueQM$!P%W^kHhc1*TYGToc9 z*i>{x9-l+!+5_rYnN@Gf8ia%=@nJR+D=J3^(+(>jIYMZIJ8NXvY`y^a%>cBNnkvEWYO4qPl^P?q9x@J)uNG5c*<#hB1G4Vv{Hffz$$&P zb$G>p+=sLzi=*H)OQ`)9IcLJ~dD?abox32&oV->Yk}>A7N^^olhL1 z2M-dXI;a>=Y{SVyt2#(31L3Da&LQ9J0zpG!vMY0aAqZOiVMEs1iw*XU)WOGN8G@%e z@WB9XDp};ZjDBW2_X4BAFc{&KpwSy?pn8^n>xwQ)?O}517@bDXdLj}A&HWy}Cn!saloJ&%e(74K6 z3blHJfzV9V1q-D880|s3-tRXcAts3Z<#-ba4 zXrd-}BDo9YUlFAdW>KTTnn<%+P&6tmPv5_`TA8JR*n7YOgeKy ztXiRHpjA0Ss2`-6WS%aq>qNNA7wEzvR=25dW!hw{pc!JBKB})o3{HvX)PQ+^W$IdE zfDS+tX$FiRBqHSZs2>d2j)4WqD-au1Z2ohbIZ_>fPH;Jt`JD@;bLXx|LE)%BvZcK` zmdq%iQF<~Zd}BQu?^Id+3mwr7JpeJ~g%Sl{){aMWL zidULu;4n0(>dSFfon~1rKO1|$HqJK;{BwGqD)3p?VzB7&rhng@Z^S6oO<6#yHqnzy zLtORv`ZLKlv`NllkX6MBW;vT&C1=%6@+y}lX#*<-Q3jIl*q2pl11kX@mw{;mG=D#C zy`Pj7sXMR1HlZibz49u1QjC8+t|?45$q%JZ=~O>(i`o7SJ4Pc3|gd zBWgNVA0-K^qySi67T8K3l;lRrtD;U<;!TFkGF8{7zKClm0IQG-P}K(V5#V1g6f3G2 zq2M)SC$3SRN+8DLrMyV<+D8?c8GqbuyyIuma9mcIb0{e*9xkZA8C2{9cU3pk+~_7D z`aje6clFt2)oW{Z>S$pg?XlL7Ss#?*sPD%eL6X%m=1ONMRm$obPedGD{$dsE<|Uh! z4pryHj0J)o>I@s|5D%!os=W-$D-|}O6N&#Q*I#=lyVyzA#DVMzj(U4&$$xP@xC9EQ zRl6^!DOQU+`db5XZ9KeI+&ZE2JPe33TFvp=rJn?)>y;6I(k~!X=}+*t(`rvMY29|u zFjLcm(mYHr>Nl;US-Y;Ie>-)!4n!*R4^As0gOettltGKSsDTxK(eF~HG-RB4-y>vh za3&>7gE9G&)*#2fu0@J?O$&R<+p4zA#RI>d3YXXp0UdvuY~BXS##($e%wcF(#1!$G zQkAgPG+Ls;Ly2cw3CdAKKy(xqq9p__a!5~&s zGpnHu8*hILX{HH$GYCBeUgm+_btAF&E!3VaeHN9NB5LeNgYx}EML34GtM=|s+0-$3 zJ(_b>TD4Ur<>U(gd9q)B>%Kb2ZLELByhAU+nO+-nvZ( zN1h8v$1xm|XJLW^RQ91A7bH3<2ArqkA%v)Asw02n90Sen-`^!2TP(n54+kz#>Jf&i zNHRX)oTaw&w}Ev(0rD$UUl*rv!O**ZUs>}rZrxU$C`|fYF)wU4l$@T8G~dg&6Ce@@ z74gh}aH4@t24C6!sgE~%mm>SVFPMfau$p`VdX>qWkif#xbqg+=U9~IgZYBTJ)*-Sj zHq?J!GiDxNWudYyY`mys3mS`1P7rpGznJv3uliNHUPxic1`(?e#;Re$iRO)h@$liE~Qmiq`% zAg@ki2yjgry!NKT2sda9lKTjNzNs4}-gSQ*T#M?*R)l*>+PuQOQ6)W7M^UK$tR!%_ z=`&;bpwWc|zy>je7Vu53#4twopsLG>*>P6mG$Kzx@1*)>$n?9x`Y?Cdu7awDFlwsu z&Z4Uzo!XQeirw-)J1fsKTs5^t%-{iyhtr;Z8sX18+El+5a$CCf+SO}*+a7;c z`qjA13>y$Ux=0=p6yun2EF`q&T7${tNkL@Rf~(H~W3fsRF!dg6W zOj~+8S(A?zxxS)o3!hp@i-5ThVQkH_BF%Tdp_N-o+%mZj2g37k353CZFQZWhosZxf zIv>497opn?gWVMQ`XpC*gF`Iv#^e0cY~s{?H=IAD)-+== zfo*If=R+{0){ew|hxl2xikKpey`@}sfP!@?32qdLV>RU=m}61JRw!~54xZFKMBTdP z*8v>rhYU_9@CPte?fY*Bx=Qq4iv(gm@0S_RP;OmJuW%ASeS8$_OVc0Z!3fquTaip4w zsyKUh6hSZaULYKt2X>Xe+4&A|7R1BhVD0PAUZ+=U;@l~MPJ=OeZs0XRMib^TgvD6? zf?I=Tuv33qHXUv6D7l!u;P26A34>Kxblk zxBT?&`@Q!XWxcbkJ}rf?i@S&BDEfqX;$iv!^7_?}bv;pSdR7U-zyA_!Ibtr!Y~-3eILbt6&B=FP%g&a6CZHKJMfqE06`ZJ`AJ)iw&lB6Q45?Sxi?5( zIyql`{TZQpELzJyuLja#UHlYXf%8L1^5t@NAOFYO-EPdn4V-@$v0-rWxLa5{pawNg z5B~UN4LPn5HE}kR-bVE80ra}g zP$3O1?k>>N_O}7`Z}7}e`l5-?QJDrT5$^KpI60@w_7#8W&})pdWS$>~oPU@2t5&5~ zPcMu?^oQsB324t?;S{{@$}%fOC0Stv>;^q+!7u^_jCXJM_8}Ih1I2>}tQIzZq|(g? zK&=&D|1nDiJL?Ue%H6gJyA+-}3sN2D@_2aw54Ls_$kQ&`J^E??#peGG&YglBezLzs zjbZb@(no)pJ^V`F99=NN-M!LBFz)!3K458?uk@`z)$lwyUTNu16v4@WduUPPzr=siKu9h%{2OHLrOEDQ)$>*D zWC~XxR$3?$6USEFO~TD2G;wbx@xm73z!rz{A|rnxCP3c^vQp@4RvWes1IB^e0b}6Q zh{7o+T2Mwx->9kWj2MKz5UCtSS%kNZ$}`)s_q%=)lqLhM6+-ApD}8((37O67LHg+l!I9!AWA`R z%LRXvo`O7)jrxBpeoW7^~@8}7hCgZZ4$W_gzj|aw8b6pEr z6xl0*cw+9fHT_5`Ha<(Cxmp({j=@oOG&|X=vk5balUqmc_E5dXjUiOjc=vRNTsuyN zAiK%&uXe%>HOJ)UI+w3==d1(y4-w)WE*^j3<1xSqPgj^+GhnX`TGs@LJi^U2e70`T zpTJujxCr$oBjna0b5?BcM>TP7J=!(#upbY1M5LFo%&%yWptL(;OwA=>H8fDNjgCcM0n4WyuUMqX zC#z_}MrQ}v5FrBFi_?*)Gq5A^hsA%&qswW*yu0YMv=*W2OFdk3C_57#rXmczjDMjP z;)+4&S@Zq&#)|1QTn+r`_tr2Oic31L$h4ws!ly@p3`{Q43wtjUn3wrW>n{!wr{nyj zIOBA#G@H|Mn*UP(myUH9R6R-QrTDEEu)JyB8%Y>K?y9E8KF_ALQ1#fzyuW{MkEY+z z9-VG%#uvMToDNQD2SDtI63T6yjqnH92pEvPAOYD|xP5~7WvU5D)}DPrCkgU|p0*I! zGcW3uOP=<6By*GiBJg=JnaQAGkM2R=_b?{LqkDoduI_u{@*t*5Sku6*rG&bxqP#SVz8W(ybGyNqW)Uh`#$} zF&yXU|LmK=be*H|jNZ4m2t_MPJsBGi3+qkRm&C$?{~G*}tlj}hUC4h>!6;dFLTALH zsUvT|LY`_14g{?rj&-}d11;a{=q=>4jN9OUuw2Ei8Z2h(vN3%ET2PE)5ABP}Q(E25 znmU`sUDVLKxn-;(Zl&8WoL`a!L9~E17gW{-=2NXd6xLeJl=~u zN`wm9Qo&v#@`n$*>N9`!8}xh$p;FYV(s60rbzo)wjH(m*y*3C?9G8=f6D4W^4a4!&ssM8p}Hi)N% z!cU4WRtd9pQNe$eouE?|Oa(3yq&Xrj(B^nztRGhdp?euRx1`0TNw9|2s|wt>)RB_p zwb`7Z45BJr81zj7Md_q%l#4kpg4bQLn`Yn^v0wH`%x>49=k!6cT<9Yn-)L&9npPU6 zhqPfiW}%_FURM*8dXy1Fxg3VR^R}*HbMY{CgAj-Y1Pp(Y!-`ywhA4 zk1pcF9%Lh`PzCnH)f5{++59j%ri$4Ui`VPDVv_ZBJB|PQe%2|m+0olxy(G8$FR$0Y z<4yAk#l3$w(0@|JWh^266u4^vThAo>CvIsr60jQ>r0IUL(XP!13e|cE2{4ts$id+* z|7SLOyw20Ol3PQ)8)UE-3nF}u#;8g8{qVvk4kesvHku7HVsK1{Lww$2?KsqT+KVP8 zmzJnt&{B!A3Qo}@L<*E$JWiOg3SGGLHN^(}ZMJ`goU}gXcPtw8Om{+rtin8_VNC^k z?q(x(0}vAN8wSdcCpgGb$y?KotzO!q%8yO#NZRfr081c4zS z7N0PNx3;K^{(RO2ggk+>w>Nn6;@M!`_I2>L+14;O zTU(p(&mWHuv10`vWgY>gf{VKP1B<_TD+?)B5TS+#kuK833d(O&{~IhJe!Lf#?Ro<< zf5ZMC``ZKh(LC~Y-iR~Pstr^mqu1>w5Dg0?Owi;e%K2>7$W4|lU>M}tL|Sbf_m6II z^xlCLQx6L-uOMT#V8F?5RRm|#5>eJZGvA5@x(je@xYZ)!beE{{c`- z0|XQR000O8Bw&~H%>pV0b4HY2bVipX&H~EaFkFI_a>^%YxP_ zvJdr}@?BP#dgOyDtIqR!c$)NN>vc6~T4l)~t?P7nI@p7fmHgO3*RP?|r&VuImxFcH z#;F2BJgp8c&W_4)f6vxYux1)pbVd}^2(+{~9gQBAXJ=_K>gmo`M&((W7XtCacbP`F z`t&ZlI4`H8;5R_8`5`f3e#*M)*QEhtn$@#uk<`;!riw0C?f)K4v-I7*Mdff@R#^y> zxsRgG7z!h(2|sc4G+>7!hvSB##$d)nOc*0#Hgn;lPN$+te2SNe2X2wPp66~%ums@&Wf5HQmUhV;IOK*O4FcA zo$MSlq^Cg;lp?A0bv6{(F=NPz3I*~7a^*Zz* ztJ@x6%|$Z~xTx_ct<&DR#9zOfjPtrT_**ep@BdonMQc~~7ABrg)Pg>pplFssby{-;A|_0}a~mrGI>#eqgl!WbN)pXN1c&SmQN~xwT{> zNG(0d?;HzQG0rlJz-qD0(4^1rjACmz?FbPP*U{d99O@s6d;fQ^Bn|&qwu6Tj`l3_wV0N2BZA_fD959(OYD6 zD`6o5tW-@UEL?v24bVq^a(P`55?cf)e=&D2s>CO3Q4Gie+4CgTuAMiK_Ot`s3$xnx{wOtfzLf<`es5$bc^EZUI#@K=}bc zUwTr;LI;0WyDqTBL$fY}v+{igfB(Yvfq(y5mS+Q@fEL5?Oi0h#)T>vm3(HkIYqaXLKhS+*maZ6wIxEG@|5f4*afpndL# zYCeTtL`Cc^SmV`D620Y4yH35Xd{Rj=3ftqXIH^yQZ8XoWvNqg9}paa>JSgtRxZ;KFDs+e_V=V zNl;5@<<+4PL3-E{jl3@)e<75`bMYn8mD>q2&R{2Rq_Whd6Xd$VPX1rTT2>B{dD=$7t;KX^v~s zc@Nw!CoWUNu5?A^Xh-(ooMuu4F`u|H)O=pfeH(SX%FH|>zC9j^f2~szN>Uytp2)42 zLUC5XxrKn+15?(z-J4!3tD>}S+XFC!EkzJj#nrof(i_yL%7&*U)ViMLN3+_!f%9cl zK_kEg#%Z0`LKelp%i_fRh>EOwgbv%SJpLp%Th|NCIj=OAVaxy<{Z&jCW_3szz3W`i zdLehWln*5NjMJlRe~fgJ*JC7Pj0r()v^&;CZsWv7J0jHg`8Rcej(xoo(^&uKf4Q?c_ls{@B@0wv(NWokSHr zOjIq|20Hks#^P~49zTRpflrT(=KvJHoTS6NzSt98DN(tee+oiSwFm#Ty}dnPUw%=S z%)7dDm;(RT&2cNeoaQI6#;yhGRhbucZ+k;b?7!um>!m%AZb-wt+JRwYUylV)fDXNC zZ#!PF61L>^A$PLmRiRP)_^InnE|VghdzuD&pSJR8$>JG|+4I5ZIvvSzgVVuJH$0s; zFlNsOqw93!e_0Wn4t~1f={yzv^epG`;aTrGF>@gDt3iD#{Q2PJ3$TJ$S+8Y&A^Wo4 zhN2^^WC}uc^)|JYbqPhC=mBsI5Iq@}Y2D);Gc=EjlVDxl@0=!aK>RC(uAa*RpQZJ) z;-n|w*nn}@iA3HmcAu8#{|-05Fubhf3$$U~u}P)~e+v{unh;nEI-NG^i!FYqpQ3UI zXti3M7XLo;aO~S@=)LJGj6EucGc?c23sD7BZy+mZix zYxSMLf6V>69~q`D2dqN@cmZA7MOPmL)X0y$4`l(<6JG+hQ3nr#JIp4akTZO5Safgb zHPl@hdas1_h1-tiXZI>eirpm?uge@|{|EpKCbp%lW zf9T6ciwpy3>o$yk-;=$Et8{mvu%4DXjK8TS{k;TR!B!CR2mI4p@7Lvl5b}gLvaTpj zQ@&dps*u{NhM~l!XRqZijmzCnlhLQ{x;BsLZTXVQ3=#AnA**=&>owa# zsBaCmUlz8ex@u{tEpNkY3*(R-u6~f!q%Mf$O_jxWTU%|5hWe7TK#Q)f(GJaD*)bZy zxDKc2q`N~jP|p&bp*_YNd8!GQHkRr7JdtP^wYlbw-sM<^0{MX5ItZ7)ZYPzGe`jxrs9a(L*)-7IQ`{9-KpEs=P_YI0UY)I>x z^#Fs%bDp=8KKrD_%yX=0$i{XcAJ1FFy`y|hj6hL@JOsd3;Jc)BJANO?H`#2xx)CqVAKsk8s0wXiGc$e7`-J`>6!PUrfLHD&F z=tv{b3nDKD^>=(V_^eDv*X+1h>G2wsfldJiDhoP(uoe<9Y}4QZ67AetZLA;HW%r;y z)_L`lzRKv;r+L-au>W1!f8Y%=jHZ|UW0p^|-r&~?1Vw#kF)JqTPVlBeckuu0^#9b~ z+3IhN@~SqaeQXxEWC#t;E&x`1(var+#~;KVsPME1HQV+s z224lvsjfjyW`-G zyVQ#4Qd|k6Cn)%Q>3&gdUvD?X)6{LI;k6I-2X%NG-dpV@hlKsUUA0W6#a5u^XT)fS znHqN=T|mWV5Ezv(k`MoztP z(O06p_Hxzvf7~3A&0CG;wVEp`8_YsO;h22RRG?KA3Cnqbu&mbx-2;9$-n(>Py(>611hCqOazFm(o}M2M z1j>-S$}t*=3hF%(X3t*h(`k8*@{E+^h3q~RXgDeIe}4+4**`-`WewuqIwJ16{QVnxzEJZ^p?c+dkeAss!V~buXb5Z`ZD)xZx?c$zIIPj<&7(G?8_f2;8oy$h3{e~8|d{QQGdiSy}j>_Z(=hhqULs`n@OW*B<{Q$5-O1V4gU z4f|x~o#GtN6`vv;8gfBp{`#H>1q96QP5^-3Q0TyVSz!a4mD{L^51nJ`3p67TbEo`p ze>_f4_+8A(%K0hS9D4A{*NAX7Es(^$#!O&MXu++Rh(Z8UBN6K>xanw~?nRh3{>KDr z4$owoy=P6;{8_*rzegkMm_LxuA#`*W8eAex#hfZuVty4Xz-;lymjlde|N--{VB=WK;Aw030)WEc>|YC*SqcJwcmes zs5z|!j=0)|0(mm4gQxyIEz*f#trNk+>r6VSigPj4j}3Mdq=v=f-CT`IVJY&^~<6)yvEoD~QKyk-RgD{y1_JK4=mc5vhX>P*4E>L&{PmEw_Ze2K*5Ya@Jl4teEpn{PosH96k+xKfiP{{2-`GqNGrmdDZ z+6ACNY^83Ph`*jUmWy`Y9paEK4(ad#EDXEe;`&#b{+~e zj+`LX0`CV|jcCtD1loKguQoRaLIL+ySCkF>FC_S@jyqdr^#dJZMF=wRc-R<5n>|!C zJ2#7}yM)q*UOpG;|B%5y0;SgB!=O{NTGtdzZOIG*xue3URbVXSd8<%+X(z7X;)SJ1AtU8%X5enmSGx!3{rHky6&Zh}XTab*ZT1iSq5ke%R?g z?1fkN!*0CeU9aPK<%`{>2@zE!tc$eIa*j!cA-S~2754=NT2$QIe;kMMH8Kb+Hn+XJ;UQ zbQ3W=CC7Hs3OiJy4>lbc$M&Iy$NEgN>FP9~+c0{P-%R#=)B!qrCd!5r+7N)UncqN`vP?n8)Ef9(TZ?683%J?(;%jDzA` zjpMcv0*x)QUjcW!h2nQVrHKcUY40EFPAKJf8_dDgi=q*VCPRXzFNTBK8;j zZS5|W0SN%-)HRfPDZW_o&|wW7%>-UATE+U{ngX;iIk|AZTu_~pvelm#P@}r?nmPHV zB8bk{)UCH5e@%=-Adm052L2(?$v2sIAw#)H0~6^uDDo0-P>J;sX=*u`HC*DEPvjUBx1fJwf-fc(_($d ze_C1E(`4Nxm%HJsN=e3}KO13jB!__3F4he7or{i*^!4qT=xkMv74j=yRhbsaZ2h`r zF;rRE!hufJe=;tqYI8K6P1*f?aN$^!FuW^tX>>NcU^@r+t_$t;|CV;*Ex0e1Q(Q5B zDE)RGjPxo?UucTv`7o3Zm#Y<$6Aaa^k8=n7-uHCNF7idl~A0-sE0a z8mUeWZd|+dY+@1n%v`TMBMxKnXP^r|0p*@lopVcR&)ckqH!HNF#L5d|C11{)PwqSB z`l7Lq^CzRa+KWUvP4g4yXEzG6$)K?4MRw5Wq>%zU3#7!X)GF+#g`xJGuqDTTeM8k| z{Ff3Z_akWDFTvfSj+neCvgwa+o? zpv5)0(Nk)HCv3!o=m%B$`G>xIth8?%G=&?-22QkbW|0iGP?z_%3Av35HuypNG`hCO zU~Raqwv`(Kjzi_=EZTT9k~vg=<$=tHvAE<=733aUIUd6t>hcig`XN%d>d!y0s+I}F zs=rYV+qd`r5CFOD&{*$JmigMyXAV~hVIFCV^4lkr2Q(sO&FNAYh&>*Wt?Xl^nu|6p8THS@%*Y6&pK597Hm@I4!k(5TIS&{H{vd~qkeHQM1`vL?;}C$?yRx0@%KhG`?& z)%o(S^OQ#ozqrsExXlj2w zPp89E`R9YlG#~3y_4&_#vm(=fjaAu$*~zSu2p=3|lRATV1@h<1VO^RZFT`1BKRwEZ z^4IFhTRa~!vBuL!_!hVai818TJ0}Hvke5LTR3#Prz{thYpH0^HNp-k7f=WPf*n)gT zypZqD;Ww>tk)>1e{fQv%zltKLLWiiH7SB~zfZmlacf=O>?~Me1{{3>>`PVBGE#6{( z!0d3uKO|ovgWFb&fDCcC1Fp-vf0C!nDsJgV@{Iw^b(~i#}jG>*})(&1j%s<#^LC{`rRDa-y!! zU_D>rkDdxxohud&BCGU`;|?uU@1}GM8-|x1M*=z#PKT#G5|I@?Zb;ACFv?@O3YTa{ z0y%%_%|pr*lm!CQ8Kc7sZVa+1cD5TfL8ldg0f46oU^bK7L?Ct+>LR{PF04iH0=W## z+dQ~J&~qz38l*IAB~!;;OYwXEw-x1~m_HFLW_jum#cuIOzo+F`Z25T}{WiU^tuhd1 zXg^wH>TQZM35*E5!C78lKIP60PRrSJj_QB%jP4ALI%vDrS4Vi4>WXb(;bM=A9V@v+ zH4DkR;-fznH;`nvCVk4);C=clG+&>vV7y0n3FqritSIl!S>ico3@h$T*d>DbdIXx_ z9lBJ~(jRHLtVh(de9<@5_Lodl+3@~Za*{p9QJgAbsq7CaMVOy}CED4H{E{?Co?3q+ zos+nD<@79txFyIh4VJn;slMi`gVyT+o6V1?BAtEcp)xyVh;SZD8jYu^erToTRr8J$ zHktlJrF$vELR~r>lU5fSQ0_x-NWB-$2y|E~r!6)r?p1G4wO@7jC@)5i%eIw~)!Ev} zBGH!Z6a7$^6;hu9b$-b2zR;<+9}|B%RS_3CHOZ@wRP<8#QPlz!%reBQXsoR(vumYfm+UJeH2mmoxR6|aVwbtq~OrF zxnuB-`g^7He+%lRX(IuSw31c<3bJj8fJfS)Qa~WTbcxs)EQpEWjVRNzVcLJ5HIGo^ zh+09tYZyziKV)}S=W48Gr1@wqHe^}IG}1{hiF|mqFzZXya^o(T%n`#>3leWM+E)ar zQLH*0=|xl1waB~H2}@e@XMDr6H8gOolf?}JwGaIXzh&`2Z(!c=550&cf=2u%`cYS% zHg>rSQlC~K_sNi*u5!D3)e?VqfJ6sA2;0kzxf~$a&>UA9%VD?*)9JjjB(L+)m@%ohR)e_7q>LbAF-ZpnpRDxtIHD8TRM9z zou67=fD}swhRok_Rx&fN`c_AWrA8mbo6{;_-q)j5M3`e#q_SK&`67SW+1}osL*|HM zFU|)Ra3yK-3=z<|jv)={)gB}g}@&X;ieFZr4 z3>!#exvdC~(^;)3<5JAb>?oe>D(XzYve`NW*66!2N9uY2t>H|B0S?t<=mbcBNaR?b zkfX>vs~k6k$K6EOc@~!)O9B*se>1&EO0o3Hqcxe7Rh1v*n`-eR-2q9XiF1DqzEc`uFzK3Ki;3ehBFnuAR!iOAPgga=yA6%y;dEbn8~ebW}wsf$LxKq0Lq1M<7oe#BB26HM~g zoZ#>H39C{X&<&igeP>GK3uN5t5gf`=puX2?s9&IjR%tisOmdHZ%l=jwQ+S6rZSUaT zCUy^joM4QD$d+E^dv&qEWVf^-J<{yM?0a5uN4ok&V(1FyR9q6h#-I3089V{PHV7d) z^x^a;_6ne?cxBj;wz8aly!J1ed)%Id1Hiat6NjLc+jzABGN0(Jn)~%d{JE)bzl|9( z%;1hW1A@D{pUA_1&}C%iZqYR<1X7b&f_K03hCvMgVaX-p^oTvrN=lX34MMj-Kh^sB zs>MnWA6<14sJF7BUkN-&DxpY?Ge;lrlnyQ=p#A|5I#yTUuos=*HCVr^HCXUWAKVpM z6tG9}FaERpwfaZ?{8E3^wd7az>nmCLYxPq##UIZw`KfAus#=?}FTbV@{`98-a)!HN zS< zOos>1z4)-R&8yqNbjh2tPRF)*Sbwnn;VK?o)YXRCmTlwMm6-{zaX&t-M*ejZ@SKZpE$pdOz#+H zNOz7wGdG0R`T_o6n3$ZxCRR9vf}z-d$ntk~|67-TY0-IS_y6dkWAryEh8K3(zu4VU zBjEN@6{p!qP`Ij82^qt*`~s@p+r5V%z+HwM=AHsUk90E4@OCiP!FF2*N5FR*I{2!o zgB80Pcl&0^V8OD{27?)I(JuLL@-q?~K@M4iWua&l_alDkH| zF-`7&T3yE0vwF0QL{(rge#xoYhm_`!Q8^{uru~ z7p$M1-LGjSsHHco2TpIWJ5oX)))6{bmV(z--P_*S-oS1)>nJB zg@iC5-GEi-7lox=+VHr<7j6R~F^`hFA9r?tEvT2156O?&_)F@E0SB4LJ$*53(Q8OiAordZU!#^`iQJ zCf?n2Z8@|s{~n)LmA-c>Rj28wJb!t7TxB&xaNgXBef?|X>-Xc?G(i@&?SDj+M<1IIV#A-Zo!R2%1#=?x+!qF zmZl6-Q*oLK0K6u;KRnlWiR+(woMI?{EkK^|$h?QSnvzXfdX}ZtY?_%5>xyxSuB}B~ z0hCpc14CbpCAiRATMvZpaK74#*)X9iATSiU!S!bHl_gN|tH-(Ez2xilb%&3T*7vTn z^=4b^KV7Nyc5~~UFPoZgUTN?aq+hMIi*(H@tbi}bFnc)znOo52(MBS8&xi?sMl~E; zy?X2ZX#I;?ixM?RxpgHAlvr?dZ}>&82D8HEmtWK{w)n@$1A>GnuW@GuqyaeBlqB3^ za>LGbc_l_x5TEU4H)>u3v?hWBv6eA zX051}jEXmryyk`nhNriQ8T9N>Ul0Z_$VFB6EzNg>3S1>G`+$bEqiJt{{iA?k$|sy$ z!n0|+G0+t4A($wD2$VP&N99>hx;o)XcGU{q=3fG@B_2~AfRQxbKR@|P?4nS7!i&NO zFP=Vs@aE~u7gsWYzCVT-&4aYa&oJN9@5#I)&pgeoK+8){dwW2!daXB`^JjUDT~u~_ ze1=40iaWnPyV0b*H3LvtEh!bY#`eF3?gf0qvSiw2Kv=-nosJ=j*f_V zo0uyc+L@Egpi_!Yw3>I#W~d3T(XKubLd`&Ds&o?l!u&6jQ7Ml4qO6nb1H2g+5HB>r z_icvyxsohyZ6%VKnE0=l`A~Oi3L0LPjq>*j7P_ovWL9Xh0-BD0=W2-W)ex8PX6^1r zRt2%-7GgUnwZx(Ne>%E%?^3EC5;^SgmVwXEok|Ibss9cKld?jS^WZJ2lbO&5^Y_^x zTv=!^Qz5vW%gU$uXp|KLLq}k9HzBMQ*oFhj+titu#j)toK5~xLHkn8P446q28vgeb&xA6{zJDgNu=m97+iSGyAa z)JPxY)nuGrNSqgCp%#bL;j5S)Rpl67eft&9(hr*`ue#l}-nROg5Ei<_A6_L7f_5UC z<|ilFG?+9!c2oidE!lZAaJt71*2Z%+e5?kOAn*f~r$JDEG`Sb^EVXB+U27{83jAdH zdR13kFgNwpybFd$=gut&?B@ z{98`aVP0Qy&O5!cn&*oC%Cb3sVC95`kes7QH0O~cSQO|_M<_>folhjE z9Ksb8yGnDWu{jZf42L)|D1HOPt`0G1E`ByW!D265tw^KJca}`4n!;ug{pspnJ}17x z_M9&oDk_k57kT#Wl%O-w7CkF4sg>_L!KdfXPjvx*|M=hPY@)v5-_^d|-iK?GwD@OP zo~;pHfi)S!@WfnmsVTcPSDT@#=CTv3+8a+jeRH#F+KFj@UkWieFHRn!mnU8^uJd7_ zsl9e>ZOg~C*ug#z^!2Q?LM2-oTj{j+M+JOA3$K%{Bm&`qx#|@IU~?akaduo&IOHf_ zP)MMEigeufo7d&UAB8s;Rbs7i&?jLm2wfzvPQz$;;-le791Txg0H1`>@WesG6Fmh)F%19 zbjPNMZXf&!)?Ui!9wBcgE?s^j2WkT7X;IBxjs>@bO_x*zHH(0x_YH*vN&FkNv~xnD z=wS)idE#N`$=ujErfau2dY-uGc``qG6etVgha-Y91Eiba{$$l)Q6u~)z+x#+(KZ9; zls6KlRp~WwgU!1iIe?dw50~6e0vdlI(dJT?j5LA@g;1Kzac=b`M`P0KsRHUN?O|Es zP4hZYG^&w_ZX3>t(NV*LjlZY7yZ!@iO|J0lg6cy=8v+D|6UWDNAw^ABdwFrg7YI=Tv19$P?>)+ zF4Ni>0Nr;2BY3)dm|KXg+2cjNPyV zVqP|V<6*OJ8`3C4;Z`=zkdwtJTwSJda^nnz>#9gYx-!ZzP1T_SYmiNv>t~qOieG0m zz4UXgdanG=51_c^cYfl8Tjo1I&oL_W2rgdfR-;wu_iiyyH1Y=U_h)~O%`5!-Gsg(K zc3+>-mvmj;LkbeV0)@XC&rb3}6Zjk*!6bedmq+PXbpbxzI=0P*;2#jVM{slb^(Az(F(|=et3Rgzuqw6c zvpH%m=f~H4im;m~Sj_GT=3l6@QS=TPf$oulRyqAaU8lp-Wrz1AMvRs)ky~3mHs}?v+>BP8@h1J`-UtWtl)Hq|J>z2zvMr^;y=IUKmW*nq8{p$obcbpWX9ng zr$;(+i7v@bvSP%Ga`sbY$D&0O{%gv?Pzfivi$uzMsDXdw@e&RMP048rQlTmG!YTVX zGu|O#i(SO?ia8mfPfJxjeU#j%AtW2b>!WgX!Q7OzZ?BA)2~N^9~}ntIpxcYdZCI!Zo{qiD?R zIchL;>!<~0yrhd2=tY@SGjY}`F!rPw2qCpM$Sklf@w=s$1|6;oBr((H0*()%eMF+l zX;puj)Yz>kr`nQ=fhhfIZa4*xmTXSKNjaHK23AZ;US}tH1rb@&1i!6P1Y=1hpHi5F z$U4ruXe?P22NR(<6V4 z-1A-ag|2(t&-EC<>h!dNzQ$rYzOU6fsv(mI;0V*lS5(F}QbUnVe|+=&S)|dWCmb@_ zG1R`>DfzH0-Y?Gr7v~S>r+J+TU3{2zxi(_&>u)sWL|*;;qs$t~mFh5@;bcr_<*4xq zRRce0VF^uKfiniVtPNqvTOatZz%+l%uj`9Ae#`Irt&+v|Kb7hE8)2$kffi`(&9>Zq zP6ViAmxYsQUT99DJCMqqkbd*JH~7PLI#}=jTEhLp-^6aP zS5daT`fS`4l5dWt$=0`FX#8*ULxi+4-#Tb;sSwq`?*5&FnA~SNN_!NO<0*d#C@v4} z_{Qe3QeeT%7_!TilsTZ!P27+l&x=5)b>Zg|N)lV>k>c5Qv z-xiE*KWMnuKTdb-pS$+YFYTXS*+0LwfBw<_X|S#A^!C?@{Tn42{Y%>B%`a(}H$P3* zByEq^KPUFDX-57Q3^=PSCX|0s-uwiEy#67L@#dEWy|w_LJ)ZtRflC+6#xi#ec{r$L zx2p&8i5uEu$9MDT-Eep>KQfO5+8oebUjDYJNGqC2+;|wHn?TqVLmBbg674MtKBN^z zkt(7RsIK+-=emIoiv4XuAKyW)u+zLss!ZD8#Gl~ik{n$m;1TcvQV@R$ZZgagAz6We z{I&Q;Y`1K@kq7}?NF@522CRIT#as>e39g31#NqZ^`%MR4lDVZiE{}7I^$AUJfgSo= z5Ud*>)2q93bH+=#vzx>hevcIi>|vu*SxL!=g(_;5cQdnM;#v7OGY%asH7Hnwt9AlLz=+AP5OZmI39Wi+dU-#2`TF_Nwgs9oZ*p7wu(a5Toi~Ny z$?&s3@HeyG^*E8TBqQCpPeTF?<4WE=M8Ng1wN{0;204`NmxZa zy#T*w=!$>7REH*q`1Nr6EjoVV-#c&n(`+(MhgomyZ_}+4A?Xa(Nl}4C=ra*DXf|26 zwdHRKkHs~@Bp9v*Pd~V_=M`OS2)>7zW!=dBn9Oh^8DqvxDb|eErrjhTt{gi%2Q8ax%f#zX0fsjm|`P$gziU54{8 z7(X5RNbCl2W*sczIC@DR?qO_UJXJfh4_Tc^)Up8dAkvZ5hG-$ZO~6-V6BPzY)-u_| z)KB?OHhM~$&2jx8dvg)d%{>0&&a!kb@EW;E&FjbAr9r-X!;pWuG|0caVaUH)8suNy zFywz|tk>3-tAj<@@M;#6blH}r;LDPGUkusGLS32kJQ zhh|qRMLK15 zUXN+n`Kjnkzy!&wxg!ZaWp6SoO5sq}LaBdnIwpny2~M-|P8q?Reh_TZlb*&Rec^OT zUwZnT`qGWaqZg`&U+rGuR8nBzW`R7i7f96C4S)n)0Vc6Zcf7md6YsqY4#Pu!q)X^0xxd?9z{SBwTm)?%e&zfxf&$VWayvIwn@2?5QO^jES+{mjVg{ zDjXr);Y~Pt54j;6wyFB*zy_cnV9I#8p9CAEd2W|T3Iiio*GrQ&r#CBYK7Ib+ho#-G zt5*v*3;z$xgZ|`(VSn-Jr=@vksCOYZ3IDSP-#>n~Ecn$+mK%lt@ehw*JX+cW)Z?2Q zox#(kL7(3+QMRxv|!U_W~HNGH*WXe$)N!MZa2dT_zST)*pl$wdqm&~-1 z!QYR@Y4J|ytfp!PvD7Ot^q+Ga*U!^@eC?Me3j-)oXa^!9Di|Ccl}Rpv zc#aZgSJA_OXGHT3Nwa6|&%mPGUxT5#5hHsF+D96gtKi{x^12c763|d%#5haeH}3i? zooIH#WWI8`p`)v1MiOGlo?AD_G^_G|X1BdPB(Sd~ELWFV3IN?IjhsNlJ3HGa(68@91d&MC)c_oNFJwYvv`1aF?z`GhZ14Feqk2$%c~0~s}##MhT~wc$^P#noO^5|Pp`;e`#bxk5L-=>6n{5c#Cm^?;I_ z>Q>c*Uk3FWGoy0&D#a|Tmr4!;C;{b{a}EO|9q-er#BgHz+1`M*glmoHSLpU0rS#6@ zXfBKijh~n3U;-ZpNJgu2uP^qO4q*Zuf5+@h3VrMi)LGU%LXZtB}FGXJV(~fTFZtt4e}#Y;BobGY?)pwP&d~bEo-9UZms4@&uGkFj?cT|96&6 zFDTM!s#}BrbMgj&P%qjbd>+;lRV>h0`EXmaf1Dm1`KESXU`_z@m;J`EpO^2m2f)xU zCy)-Fm#|?16@THU37)J5Jpy9uKib2TTjJNcUl#U0I^y9#iar(?Njy> zSX~PM(-JQE9%@|xwGqSkH;{uhvpY7Sb}Kep(MIQQx<&*5tB4{XtP{d1=-4SZQ(w<9G`L~RI|nocXr$#?4CJ*}wVPfLI04aNq+Ii5a-2*Xuk6|;?` z6dY=bk%to=%A~V#!rS2hrT%j-qz6(o93P8Ck>siVj#c_Asbonp#5G*v4)F??q+=YS zgAHOq9?_jiIOKNeZCXW4XHv|J6VrUu)JRSt{u0N#;Ae`IANvXVcFxy74r6hKhNF^nS!wVsl7{-5kZpH@{gAVjpj3E*L!dp?U) zwpZ@@=B}-K8OTG|rsG(ZMAVO>f^;jeFoC2I4ZKc>1Z~mO8^@Gym67qyq$OPZt;r3d zzbtmxJ9CT)Xvr`|%`lrz9Z|O&XZ>+`(i`AAt-a*#M^UG*JYp}sz)d`133+ZDrYq+1 zvgfSIFPEoe0z-d%_2%jFl4k0hEjRfr3b`loC0 zdV&nSLEjq*+8&Q8@LLU53e5|EG@wOcQ6Tds?>e`C>>Lqfn;1{0Fq0&2St#=xZK35SGk7d+WE=AltD>INFM$<>qQq5QqQq^)-^$_C z*E{ly*Qi@w`^z`*8$aZa;`la*MzLC8etxnHAtle zxopzp(aV45i2>aqoF*66Wgf57OxkJnp(?}l$x>w(3!c6T?!AOguKURwW*@0eEaN^z zG#}b_eYoH9c(EM6a|%oWktyn_tm5gyS!`nJrW3L2CR4a;l|hHroSZ*u*)G>^F4V3= zADlo;BA^JHG|T2h;f)Gyb1_h>Psa|04y19Fu;+ibf^#qA_xz_%z)s+CotrwMTBFjq zlt!;@g=?aj=F zm(uBw0=)z1&O!AT4qVQuY&TBDwo&95$ zRo8!;#J(r}y#~j#@wggJv&=@gXHjN@Z|l8YvJW|lsBar%xhq6aPPT;i?Nf=Zz#9?? z$0}u8xAU4^Bg8|MG51306SEZhDGR+gwKqxX4@>ztf4_AnT040B?D4~;#oN)jk#AC4 zJs3{Q@v3~pPiISp88=A(t!FFiVz%(r0NFW@It9dZG*Yex2mEoc6dK!j@}*RY&w6; z=1^YM6I;@ZkED~m@P{;_G#TX;Sdl#kf$oW+fUTKMTI_l&R_kqMl#SfdWtlv&kDI$k z>tLeVfjURYN1e#W%kZ-zvAM?Q$qgj`~Nc72ajFcEg;uCw)wV2 z>tcgoOU4r^nFV`;6X8a2jrw*|L@=(ix~J-b9cI+)$V$6r)@vNtF&T9pe6HOX-;cMz z@`5|l-<$64oQsiN1`!{Wp)D#q?uJ&BbxZ!{Ak0ng=Aw(%Lp{;k>P8#{>ce=Pex_CPJB#ELH*!gtGLf@re?D2QG}cX3i^AUI6v6Ct{JtUa{di$-&IbmCHnHWU9@5t$_ywaQ0jInGj= z8`-3IgxQ$22`gVw9l#s7jk+(r>0Gx>Bj6!H=zGJTN~HK_O7QboJ(_Ar#ZrjdkY7u^hXzweM`?+`?NSGF#vXN01dLCAo7W3+2RZOwn3mJl{we9ti#7?l>ntUH13d+~`uNO^(jF%X=5@f~~(dso^6 ztu3(gw!P$&wit3cY$2p~1w;yP$?39jaRQrvfxRE!`Zr|qB|n4v-0T^*jBoupEx_uZ zpf#ps{^;{!G>Xt0lbL_a(vjSfL}vD}=p*sUaF&#|eMh902~E%mXTT9jhJ5 zmVBKSf>r%L6alT_t0Al9BJr!|%2JAGFh6nP<`)TKWPd&#IRzv%6%-Duid2#GMXI#A zZ1WpK>c1;*3`J>|uv%D`xm+*iuI=2q8fQ&WL-}cbfAMtGGq9<5l=ips1yeSQt2u#V zSOh0huwIprM_hl$2cG-1r-n)Dp_qSyj?GyV+4RRZ&!2%bLujvx8kJRq=6vZ@qNvk@<9)iI+BdKvUs~Kn)KJTTEdMb9BN(t*I6GxPciYb%l zvd3e6PlDg((t9ge$Qk%F(T-PxIN8|bLJ#<>@%V&zX|#Xm6r_T{w3%B`r6wuM*8)Kb znSH!lLw=(W*aDGukx-+?FU-Vnd2^a+rX%F!w5kN=aqW(>Bo(VUohp|v$5C%CzDRl7 zqqI&#dyn~^QQj6}A>huJ*V)+v0FUTrBzOt^{O5z0FZviGw`YOSgcOQL(!M#8!Nasz zt7YU}9H4(O6STs#B5@zniS(kEm?lSA7ffSyj%h3c21&ZI9>lbe@*Vj>y)~$G#IpN( zCgdqLI-Zxu__y|mJkGQ6hyY~1mCHD_i&!7vS`b8wsWdEGO+FlNxQ12Lcq(9FVv*HenVVFt#&$@WW`86dlFUk zt{{$udX+RTRYUntHZs9G&06Rn(R_Ki@*e4AbEk!WNv9LZzRVS7x7epItY^JBYP4qt zbFP2Ck|?CQP#lc*cQx^+MOf(zROf;Mlfk;T7x-3ChX}e)LDV1h;!IZBkJJ%r1g#JY zS0ueZ{sULX1di`2Rt7Nl#>yK1QMj8+9B+0-2sq7n&N04cOvo*!yQsA!*{+lDW-@6L`XqOx*{pfO-o#h=&OG~Zk=d~pG;k3KOO}^KRGes5QsmBje-ze zRrl5Sf7Ip=d!@8LlXnQ(`;N_I1|M~~BAq+jW02y%$Nd|UNT=Mw!ilFtukCaDnFO!t zKsH(&x&q<+W_LTrz{DrFM#Z;ytZYu2oqbW`TTo?^Vsq04+lzMK^>kRgr7tt}@XR-{ zsOm(xCJPL-g@~!56@gfaad(nCx*D4yfS-JW&D7jP!M%HSJ`5ny0BQ=@_sQo89nfZ& zxo?+Q90Mj2y62}oF7bM1&o8@m1%lqOJT{k+90L~%MGIaN6L`!5Yh3A;YV1)IM6%#B6^dGp}=XG;qcTw}zEn}z@N(tw}dFyxPx2KnfQA%FarHxFJvey}w7 z^=0zSmsTDFG!s)CbLlt~n$A4rA=TC)sit4!eV5R10%L!du)#uDw^f{l2unwRu>g3l zXN3bBs=ORPPtA4Vrhp&5)$$|(m2M9uVo);n#>|To_cmS+8B_iTSz2Adz5H~OPe?l1 z^NFm;-&9G{Lh#Dqn^FG$+i&oOBgsei@7Rt75;x_2(H%73-@l`Op|o}XjzH&~Wb4~O za*uQu>ZyOKvq^JT2cm}GmjKP_NzP)EE?HVV)RV`UE0|0W&L)lx=E2 zqBHTCyvqnnly)<^C(}>QmUXhu#y5MW{xpGfIX8bDUhX&_H%92`=wYpLNXf+R&Cb=~ zlTvWg(?uQ4b%Kh<^Rh8Un^3i{66dH+>sj0AHxTD&HjxRJ$Vb=R9G08@h81JK6)O4r zEtsAySe}ddHHO`Ui5^U{VFwi-s!~x@QE^nwhwrSu!db`RbamQ=L~+LsWM$Eu&ldQm znzVm0Fqi^jT=4b`h2OMfgrzL_x?I zLekPc8{j|#7wleP&p46c&zO^j?w<6oz3TzBNII2HOmBlqIxM!Fo++1A2xRp{{nQ*l ze^xfi-az&t4j<+K>s13X6qPJB>WlDS(+_`YsJ}da_G4X7R48vfAXMl}UJ=OMMzj4y zvIZ&&$^>wzq+ptQv_$q~%|7&u8?Y{gh_{}6kqD_mGY>)uJ=GQYB-ap3#-wvy z?eY)(zPSi-@)G0Z{8@RK=t46RuuQ}sCNpc_T(jjIV|9Qg`vQtsTxS#lsYnyImxQAbz60)Lz>{Fd|Ml=L>igwhb`@NJ=^q1tj4>4%u4N*7H#|evzHJ5=l}ln z^37w?m^fg@8~*g>&C3_I(J(FEr&UX%hYw!-{NR8z8fW_PUc3#|Ax+BSeLMOe%37ou zUJtjm!b-N0P_6N1pt;o}S&KG%-`3>m&$fShR&*HTalyyH=Nj<9wYk}or;ndKI(Yns zHf$a1$2o~`9UmFU4)b(gnNLPP# z(b^Dek!Ech{>Rt0a(-sA^F-@Eeg5Ew$F#{wYl9z1b?f;ZZ}8&PPh<-b=ksWjXAi!A z{ERdq-s$l+kAHal;t^?-w>5Z5Dy!qSt%<5;8=eWFw58E=QN=cB9pfeGT|KF4X@D7` zZKJjW?-i*EnR{Dmiz=kSw2hu#y?%d8t1FePt&Pn4N*cCO)vFoVOe!5)a|@a2k~Wf= zkJ?&cE!(Ujk4U4fDvc9JuIU zK$^61tv7^g)onZd4cX=VNpif2y1b?!!9`q4E2v|e%-R<4C&IIoNwcK^R)T*Um9}Weh{a3<)p3*#ES|9 z#g16q6)KFT8#k}3=qw5Zo&bL$5SK-L*Wo>t0_+f?>#Q3Jc*C7`t+*U`Ddw}&NSFa< z*3n7JIftOqHJYc-?r`0?U#@xtWTT#*vUIrq(qWgF81VSGLZ5GYQ5Xv~3l(jzrlGyB z2oI!3QUTOr7du!*TLsy}2`n)|BHX|+XXR1O-xYv~Wt!$SEgOryS`B~G39EQCWmTBO zCCkKW(VwSfRm19-i~hi#;It7V4VcENU1FmP+qfuR#EXt`rRGRgJV(&!Wo>^o#h1tS zi-dxOZ4Ph#D<`lB?<2PDGvg?XBse{x*a@fVIvn8L4BT_Wo9w~ceqId6vr$&{M0@8R z7Aiwcv1FuPXaqN#SBHN))cHe+E12+peo&4{%0~j7^SC!0D$~1&bxEU%&BLqL8pU$K zm~`ERjVM`pMAbl2il7X>D9;IG8Fz@x7ey>(`B(5BEh(Pjy?uYs?_93Ba&vR}PkWu5 z2#s#)wxuqLz{+v14Vo*pd`Q)}9^H5Hp6yJrve34s$Q>T$QI1de6a;bef?>lOC+*`DqI;n@3VNZk4+8RZ3yu zhc)G- z(lIQ@{vYVNGr$v})*9pzKWtwdWok50f|djP`*aHL-8g^XT0;lvddY*~>#Xi*Vs|4A z>xwQG%U)PDIQnDEv9kH_9c3#cK^(WX`|o~)KQ0@#KfU@lc1HAJ)I5&Z&m1lnwx&f@ z%X;hsmIXeateV}wPAXV=oUHq10wpoGT#l`0VBG9C@eF@k7E#MryFaX z-bfq=Mi+m*#_XhgFRe|AM?dZtF-(ik)}I?EXIW|ianVR92E zRX{`1`jDV&1zN$@Y--X%oX69AxThTY^+wUTnMklLPZU(f-z!dTE>YDn0TX5#PTyvRlaZ)(&Gxf}?43Pk0PRZeqJj20bA7Z`jG*DKQZ`AI5HivCOt^56u# zE=|0Er;ndYm#-)TDl3B!e|vvHkhR5m89Pk|N&V^d(}#j3mjy;V{lk|JkEVav-TuSw zlRtdCDLUl z5Ee?b$%~VRC@P6Dgd*7&=v|1*61>G$j#_1JZSj(Oxsmi@opDsl9bt90}0@|#)) z#ME^y1G~$+opt!l95fPF0oRw`Dg!1OT<=dHRA)M^dw<+W2HS(>X_JHhfLq}kSPa&A$kk=1 $)?d)^l*#;r`7cAb|gAt%_Sy3e`yh@nL521q4! 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

    W01??>e@govVHgb2zK`O+3JY>7C>LYzi4QpA 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 diff --git a/easycoder/plugins/anagrams.js b/easycoder/plugins/anagrams.js deleted file mode 100644 index 594a751..0000000 --- a/easycoder/plugins/anagrams.js +++ /dev/null @@ -1,43 +0,0 @@ -// eslint-disable-next-line no-unused-vars -const EasyCoder_Anagrams = { - - name: `EasyCoder_Anagrams`, - - value: { - - compile: (compiler) => { - if (compiler.tokenIs(`anagrams`)) { - if (compiler.nextTokenIs(`of`)) { - const value = compiler.getNextValue(); - return { - domain: `anagrams`, - type: `getAnagrams`, - value - }; - } - } - return null; - }, - - get: (program, value) => { - switch (value.type) { - case `getAnagrams`: - return { - type: `constant`, - numeric: false, - content: JSON.stringify(AnagramFinder.getAnagrams(program.getValue(value.value), EasyCoder_words)) - }; - } - return null; - } - }, - - getHandler: () => { - return null; - }, - - condition: { - - compile: () => {} - } -}; \ No newline at end of file diff --git a/easycoder/plugins/aws.js b/easycoder/plugins/aws.js deleted file mode 100644 index d86a1fd..0000000 --- a/easycoder/plugins/aws.js +++ /dev/null @@ -1,231 +0,0 @@ -const EasyCoder_AWS = { - - name: `EasyCoder_AWS`, - - AWS: { - - compile: (compiler) => { - const lino = compiler.getLino(); - const request = compiler.nextToken(); - switch (request) { - case `get`: - if (compiler.nextIsSymbol(true)) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - if (compiler.nextTokenIs(`from`)) { - const url = compiler.getNextValue(); - let onError = null; - if (compiler.tokenIs(`or`)) { - compiler.next(); - onError = compiler.getPc() + 1; - compiler.completeHandler(); - } - compiler.addCommand({ - domain: `aws`, - keyword: `aws`, - lino, - request: `get`, - target: targetRecord.name, - url, - onError - }); - return true; - } - } - } - break; - case `post`: - const value = compiler.getNextValue(); - let target = null; - if (compiler.tokenIs(`giving`)) { - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.isVHolder) { - target = targetRecord.name; - compiler.next(); - } else { - throw new Error(`'${targetRecord.name}' cannot hold a value`); - } - } - } - onError = null; - if (compiler.tokenIs(`or`)) { - compiler.next(); - onError = compiler.getPc() + 1; - compiler.completeHandler(); - } - compiler.addCommand({ - domain: `aws`, - keyword: `aws`, - lino, - request: `post`, - value, - target, - onError - }); - return true; - case `delete`: - if (compiler.nextIsSymbol(true)) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - let onError = null; - if (compiler.tokenIs(`or`)) { - compiler.next(); - onError = compiler.getPc() + 1; - compiler.completeHandler(); - } - compiler.next(); - compiler.addCommand({ - domain: `aws`, - keyword: `aws`, - lino, - request: `delete`, - target: targetRecord.name, - onError - }); - return true; - } - } - break; - case `set`: - if (compiler.nextTokenIs(`the`)) { - compiler.next(); - } - if (compiler.tokenIs(`url`)) { - if (compiler.nextTokenIs(`to`)) { - const url = compiler.getNextValue(); - compiler.addCommand({ - domain: `aws`, - keyword: `aws`, - lino, - request: `setUrl`, - url - }); - return true; - } - } - return false; - } - return false; - }, - - run: (program) => { - const createCORSRequest = function (method, url) { - let xhr = new XMLHttpRequest(); - if (`withCredentials` in xhr) { - // Most browsers. - xhr.open(method, url, true); - } else if (typeof XDomainRequest != `undefined`) { - // IE8 & IE9 - xhr = new XDomainRequest(); - xhr.open(method, url); - } else { - // CORS not supported. - xhr = null; - } - return xhr; - }; - - const command = program[program.pc]; - if (command.request === `setUrl`) { - EasyCoder_AWS.url = program.getValue(command.url); - return command.pc + 1; - } else if ([`get`, `post`, `delete`].includes(command.request)) { - const method = command.request.toUpperCase(); - const url = `${EasyCoder_AWS.url}${program.getValue(command.url)}`; - const request = createCORSRequest(method, url); - if (!request) { - program.runtimeError(command.lino, `CORS not supported`); - return command.pc + 1; - } - request.setRequestHeader(`Content-Type`, `application/json; charset=UTF-8`); - request.command = command; - switch (command.request) { - case `get`: - case `delete`: - request.send(); - break; - case `post`: - const value = program.getValue(command.value); - console.log(`POST to ${EasyCoder_AWS.url}`); - if ([`[`, `{`].includes(value.charAt(0))) { - request.setRequestHeader(`Content-Type`, `application/json; charset=UTF-8`); - // console.log(`value=${value}`); - request.send(value); - } else { - request.setRequestHeader(`Content-Type`, `text/plain; charset=UTF-8`); - // console.log(`value=${program.encode(value)}`); - request.send(program.encode(value)); - } - break; - } - - request.onload = function () { - var content = request.responseText; - if (content.length > 0 && ![`[`, `{`].includes(content.charAt(0))) { - content = program.decode(content); - // } else { - // content = JSON.parse(content); - } - if (command.target) { - const targetRecord = program.getSymbolRecord(command.target); - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content - }; - } - program.run(command.pc + 1); - }; - - request.onerror = function () { - if (command.onError) { - program.errorMessage = this.responseText; - program.run(command.onError); - } else { - const error = this.responseText; - program.runtimeError(command.lino, error); - } - }; - - return 0; - } - } - }, - - getHandler: (name) => { - switch (name) { - case `aws`: - return EasyCoder_AWS.AWS; - default: - return null; - } - }, - - run: (program) => { - const command = program[program.pc]; - const handler = EasyCoder_AWS.getHandler(command.keyword); - if (!handler) { - program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'aws' package`); - } - return handler.run(program); - }, - - value: { - - compile: () => { - return null; - }, - - get: () => { - return null; - } - }, - - condition: { - - compile: () => {}, - - test: () => {} - } -}; \ No newline at end of file diff --git a/easycoder/plugins/browser.js b/easycoder/plugins/browser.js deleted file mode 100644 index ebce442..0000000 --- a/easycoder/plugins/browser.js +++ /dev/null @@ -1,3340 +0,0 @@ -const EasyCoder_Browser = { - - name: `EasyCoder_Browser`, - - A: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `a`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Alert: { - - compile: (compiler) => { - const lino = compiler.getLino(); - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `alert`, - lino, - value - }); - return true; - }, - - run: (program) => { - const command = program[program.pc]; - const value = program.getFormattedValue(command.value); - alert(value); - return command.pc + 1; - } - }, - - Attach: { - - compile: (compiler) => { - const lino = compiler.getLino(); - compiler.next(); - if (compiler.isSymbol()) { - // const symbol = compiler.getProgram()[compiler.getSymbol().pc]; - const symbol = compiler.getSymbolRecord(); - let type = symbol.keyword; - switch (type) { - case `a`: - case `blockquote`: - case `button`: - case `canvas`: - case `div`: - case `fieldset`: - case `file`: - case `form`: - case `h1`: - case `h2`: - case `h3`: - case `h4`: - case `h5`: - case `h6`: - case `image`: - case `img`: - case `input`: - case `label`: - case `legend`: - case `li`: - case `option`: - case `p`: - case `pre`: - case `select`: - case `span`: - case `table`: - case `td`: - case `text`: - case `textarea`: - case `tr`: - case `ul`: - compiler.next(); - if (compiler.tokenIs(`to`)) { - let cssID = null; - if (compiler.nextTokenIs(`body`)) { - if (type=== `div`) { - cssId = `body`; - compiler.next(); - } else { - throw Error(`Body variable must be a div`); - } - } - else cssId = compiler.getValue(); - let onError = 0; - if (compiler.tokenIs(`or`)) { - compiler.next(); - onError = compiler.getPc() + 1; - compiler.completeHandler(); - } - compiler.addCommand({ - domain: `browser`, - keyword: `attach`, - lino, - type, - symbol: symbol.name, - cssId, - onError - }); - return true; - } - break; - default: - compiler.addWarning(`type '${symbol.keyword}' not recognized in browser 'attach'`); - return false; - } - } - compiler.addWarning(`Unrecognised syntax in 'attach'`); - return false; - }, - - run: (program) => { - const command = program[program.pc]; - let content = null; - let element = null; - if (command.cssId === `body`) { - element = document.body; - } else { - content = program.value.evaluate(program, command.cssId).content; - element = document.getElementById(content); - } - if (!element) { - if (command.onError) { - program.run(command.onError); - } else { - program.runtimeError(command.lino, `No such element: '${content}'`); - } - return 0; - } - const target = program.getSymbolRecord(command.symbol); - target.element[target.index] = element; - target.value[target.index] = { - type: `constant`, - numeric: false, - content - }; - if (command.type === `popup`) { - // Register a popup - program.popups.push(element.id); - // Handle closing of the popup - window.onclick = function (event) { - if (program.popups.includes(event.target.id)) { - event.target.style.display = `none`; - } - }; - } - return command.pc + 1; - } - }, - - Audioclip: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `audioclip`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - BLOCKQUOTE: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `blockquote`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - BUTTON: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `button`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - CANVAS: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `canvas`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Clear: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextTokenIs(`body`)) { - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `clear`, - lino, - name: null - }); - return true; - } - if (compiler.isSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.extra === `dom`) { - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `clear`, - lino, - name: symbolRecord.name - }); - return true; - } - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - if (command.name) { - const targetRecord = program.getSymbolRecord(command.name); - const target = targetRecord.element[targetRecord.index]; - switch (targetRecord.keyword) { - case `input`: - case `textarea`: - target.value = ``; - break; - default: - target.innerHTML = ``; - break; - } - } else { - document.body.innerHTML = ``; - } - return command.pc + 1; - } - }, - - Convert: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextTokenIs(`whitespace`)) { - if (compiler.nextTokenIs(`in`)) { - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.isVHolder) { - if (compiler.nextTokenIs(`to`)) { - const mode = compiler.nextToken(); - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `convert`, - lino, - name: symbolRecord.name, - mode - }); - return true; - } - } - } - } - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const targetRecord = program.getSymbolRecord(command.name); - const content = targetRecord.value[targetRecord.index].content; - let value = content; - switch (command.mode) { - case `print`: - value = value.split(`%0a`).join(`\n`).split(`%0A`).join(`\n`).split(`%0d`).join(``).split(`$0D`).join(``); - break; - case `html`: - value = value.split(`%0a`).join(`
    `).split(`%0A`).join(`
    `).split(`%0d`).join(``).split(`$0D`).join(``); - break; - } - targetRecord.value[targetRecord.index].content = value; - return command.pc + 1; - } - }, - - Create: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - const keyword = symbolRecord.keyword; - if (keyword === `audioclip`) { - if (compiler.nextTokenIs(`from`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `create`, - type: `audioclip`, - name: symbolRecord.name, - lino, - value - }); - return true; - } - return false; - } - if ([`a`, - `blockquote`, - `button`, - `canvas`, - `div`, - `fieldset`, - `file`, - `form`, - `h1`, - `h2`, - `h3`, - `h4`, - `h5`, - `h6`, - `hr`, - `image`, - `img`, - `input`, - `label`, - `legend`, - `li`, - `option`, - `p`, - `pre`, - `progress`, - `select`, - `span`, - `table`, - `tr`, - `td`, - `text`, - `textarea`, - `ul` - ].includes(keyword)) { - if (compiler.nextTokenIs(`in`)) { - if (compiler.nextTokenIs(`body`)) { - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `create`, - lino, - name: symbolRecord.name, - parent: `body` - }); - return true; - } - if (compiler.isSymbol()) { - const parentRecord = compiler.getSymbolRecord(); - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `create`, - lino, - name: symbolRecord.name, - parent: parentRecord.name - }); - return true; - } - } else { - const imports = compiler.imports; - if (imports && imports.length > 0) { - // This section is used by Codex to force run in Run panel, which must be the first import - compiler.addCommand({ - domain: `browser`, - keyword: `create`, - lino, - name: symbolRecord.name, - parent: imports[0], - imported: true - }); - return true; - } else { - compiler.addCommand({ - domain: `browser`, - keyword: `create`, - lino, - name: symbolRecord.name, - parent: `body` - }); - return true; - } - } - } - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const targetRecord = program.getSymbolRecord(command.name); - switch (command.type) { - case `audioclip`: - targetRecord.value[targetRecord.index] = command.value; - break; - default: - let parent; - if (command.parent === `body`) { - parent = document.body; - } else { - const p = command.imported ? EasyCoder.scripts[program.parent] : program; - const parentRecord = p.getSymbolRecord(command.parent); - if (!parentRecord.element[parentRecord.index]) { - program.runtimeError(command.pc, `Element ${parentRecord.name} does not exist.`); - } - parent = parentRecord.element[parentRecord.index]; - } - targetRecord.element[targetRecord.index] = document.createElement(targetRecord.keyword); - targetRecord.element[targetRecord.index].id = - `ec-${targetRecord.name}-${targetRecord.index}-${EasyCoder.elementId++}`; - if (targetRecord.keyword === `a`) { - targetRecord.element[targetRecord.index].setAttribute(`href`, `#`); - } - parent.appendChild(targetRecord.element[targetRecord.index]); - break; - } - return command.pc + 1; - } - }, - - Disable: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const symbol = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `disable`, - lino, - symbol - }); - return true; - } - compiler.addWarning(`Unrecognised syntax in 'disable'`); - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const symbol = program.getSymbolRecord(command.symbol); - const target = document.getElementById(symbol.value[symbol.index].content); - target.disabled = `true`; - return command.pc + 1; - } - }, - - DIV: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `div`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Enable: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const symbol = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `enable`, - lino, - symbol - }); - return true; - } - compiler.addWarning(`Unrecognised syntax in 'enable'`); - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const symbol = program.getSymbolRecord(command.symbol); - const target = document.getElementById(symbol.value[symbol.index].content); - target.disabled = false; - return command.pc + 1; - } - }, - - FIELDSET: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `fieldset`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - FILE: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `file`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Focus: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const symbol = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `focus`, - lino, - symbol - }); - return true; - } - compiler.addWarning(`Unrecognised syntax in 'focus'`); - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const symbol = program.getSymbolRecord(command.symbol); - const element = symbol.element[symbol.index]; - element.focus(); - return command.pc + 1; - } - }, - - FORM: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `form`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Get: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const target = compiler.getToken(); - let targetRecord = compiler.getSymbolRecord(); - if (compiler.nextTokenIs(`from`)) { - if (compiler.nextTokenIs(`storage`)) { - if (compiler.nextTokenIs(`as`)) { - const key = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `get`, - action: `getStorage`, - lino, - target, - key - }); - return true; - } else { - compiler.addCommand({ - domain: `browser`, - keyword: `get`, - action: `listStorage`, - lino, - target - }); - return true; - } - } - if (compiler.isSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.keyword === `select`) { - if (targetRecord.keyword === `option`) { - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `get`, - action: `getOption`, - lino, - target, - select: symbolRecord.name - }); - return true; - } - throw Error(`Invalid variable type`); - } - if (symbolRecord.keyword !== `form`) { - throw Error(`Invalid variable type`); - } - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `get`, - action: `getForm`, - lino, - target, - form: symbolRecord.name - }); - return true; - } - else { - let targetRecord = compiler.getSymbolRecord(target); - } - } - } - compiler.addWarning(`Unrecognised syntax in 'get'`); - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const targetRecord = program.getSymbolRecord(command.target); - switch (command.action) { - case `getForm`: - const formRecord = program.getSymbolRecord(command.form); - const form = document.getElementById(formRecord.value[formRecord.index].content); - const data = new FormData(form); - const content = {}; - for (const entry of data) { - content[entry[0]] = entry[1].replace(/\r/g, ``).replace(/\n/g, `%0a`); - } - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content: JSON.stringify(content) - }; - break; - case `listStorage`: - const items = []; - for (let i = 0, len = window.localStorage.length; i < len; i++) { - items.push(localStorage.key(i)); - } - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content: JSON.stringify(items) - }; - break; - case `getStorage`: - let value = window.localStorage.getItem(program.getValue(command.key)); - if (typeof value === `undefined`) { - value = null; - } - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content: value - }; - break; - case `getOption`: - let selectRecord = program.getSymbolRecord(command.select); - let select = selectRecord.element[selectRecord.index]; - let option = select.options[select.selectedIndex]; - targetRecord.element[targetRecord.index] = option; - break; - } - return command.pc + 1; - } - }, - - H1: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `h1`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - H2: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `h2`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - H3: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `h3`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - H4: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `h4`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - H5: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `h5`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - H6: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `h6`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Highlight: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.extra === `dom`) { - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `highlight`, - lino, - name: symbolRecord.name - }); - return true; - } - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const targetRecord = program.getSymbolRecord(command.name); - const element = targetRecord.element[targetRecord.index]; - element.select(); - return command.pc + 1; - } - }, - - History: { - - compile: (compiler) => { - const lino = compiler.getLino(); - const type = compiler.nextToken(); - switch (type) { - case `push`: - case `set`: - case `replace`: - compiler.next(); - let url = ``; - let state = ``; - while (true) { - const token = compiler.getToken(); - if (token === `url`) { - url = compiler.getNextValue(); - } else if (token === `state`) { - state = compiler.getNextValue(); - } else { - break; - } - } - compiler.addCommand({ - domain: `browser`, - keyword: `history`, - lino, - type, - url, - state - }); - return true; - case `pop`: - case `back`: - case `forward`: - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `history`, - lino, - type - }); - return true; - } - return false; - }, - - run: (program) => { - if (!program.script) { - program.script = `script${Date.now()/1000}`; - } - const command = program[program.pc]; - let state = program.getValue(command.state); - if (!state) { - state = `{"script":"${program.script}"}`; - } - const url = program.getValue(command.url); - switch (command.type) { - case `push`: - if (!window.history.state) { - program.runtimeError(command.lino, `No state history; you need to call 'history set' on the parent`); - return 0; - } - window.history.pushState(state, ``, url); - break; - case `set`: - case `replace`: - window.history.replaceState(state, ``, url); - break; - case `pop`: - case `back`: - window.history.back(); - break; - case `forward`: - window.history.forward(); - break; - } - return command.pc + 1; - } - }, - - HR: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `hr`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - IMAGE: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `image`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - IMG: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `img`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - INPUT: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `input`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - LABEL: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `label`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - LEGEND: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `legend`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - LI: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `li`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Location: { - - compile: (compiler) => { - const lino = compiler.getLino(); - let newWindow = false; - if (compiler.nextTokenIs(`new`)) { - newWindow = true; - compiler.next(); - } - const location = compiler.getValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `location`, - lino, - location, - newWindow - }); - return true; - }, - - run: (program) => { - const command = program[program.pc]; - const location = program.getValue(command.location); - if (command.newWindow) { - window.open(location, `_blank`); - } else { - window.location = location; - } - return command.pc + 1; - } - }, - - Mail: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextTokenIs(`to`)) { - const to = compiler.getNextValue(); - let subject = ``; - let body = ``; - if (compiler.tokenIs(`subject`)) { - subject = compiler.getNextValue(); - if (compiler.tokenIs(`body`) || compiler.tokenIs(`message`)) { - compiler.next(); - body = compiler.getValue(); - } - } - compiler.addCommand({ - domain: `browser`, - keyword: `mail`, - lino, - to, - subject, - body - }); - return true; - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - if (command.subject) { - window.location.href = `mailto:${program.getValue(command.to)}` + - `?subject=${program.getValue(command.subject)}&body=${encodeURIComponent(program.getValue(command.body))}`; - } else { - window.location.href = `mailto:${program.getValue(command.to)}`; - } - return command.pc + 1; - } - }, - - On: { - - compile: (compiler) => { - const lino = compiler.getLino(); - const action = compiler.nextToken(); - switch (action) { - case `change`: - compiler.next(); - if (compiler.isSymbol()) { - const symbol = compiler.getSymbolRecord(); - compiler.next(); - if (symbol.extra !== `dom`) { - return false; - } - compiler.addCommand({ - domain: `browser`, - keyword: `on`, - lino, - action, - symbol: symbol.name - }); - return compiler.completeHandler(); - } - break; - case `click`: - if (compiler.nextTokenIs(`document`)) { - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `on`, - lino, - action: `clickDocument` - }); - return compiler.completeHandler(); - } - if (compiler.isSymbol()) { - const symbol = compiler.getSymbolRecord(); - compiler.next(); - if (symbol.extra !== `dom`) { - return false; - } - compiler.addCommand({ - domain: `browser`, - keyword: `on`, - lino, - action, - symbol: symbol.name - }); - return compiler.completeHandler(); - } - break; - case `key`: - case `leave`: - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `on`, - lino, - action - }); - return compiler.completeHandler(); - case `window`: - if (compiler.nextTokenIs(`resize`)) { - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `on`, - lino, - action: `windowResize` - }); - return compiler.completeHandler(); - } - return false; - case `browser`: - case `restore`: - if (action === `browser` && !compiler.nextTokenIs(`back`)) { - return false; - } - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `on`, - lino, - action: `browserBack` - }); - return compiler.completeHandler(); - case `swipe`: - if ([`left`, `right`].includes(compiler.nextToken())) { - const direction = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `on`, - lino, - action: `swipe`, - direction - }); - return compiler.completeHandler(); - } - return false; - case `pick`: - if (compiler.nextIsSymbol()) { - const symbol = compiler.getSymbolRecord(); - compiler.next(); - if (symbol.extra !== `dom`) { - return false; - } - compiler.addCommand({ - domain: `browser`, - keyword: `on`, - lino, - action, - symbol: symbol.name - }); - return compiler.completeHandler(); - } - return false; - case `drag`: - case `drop`: - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `on`, - lino, - action - }); - return compiler.completeHandler(); - } - compiler.addWarning(`Unrecognised syntax in 'on'`); - return false; - }, - - run: (program) => { - let targetRecord; - const command = program[program.pc]; - switch (command.action) { - case `change`: - targetRecord = program.getSymbolRecord(command.symbol); - targetRecord.program = program.script; - targetRecord.element.forEach(function (target, index) { - if (target) { - target.targetRecord = targetRecord; - target.targetIndex = index; - target.targetPc = command.pc + 2; - target.addEventListener(`change`, (event) => { - event.stopPropagation(); - if (program.length > 0) { - const eventTarget = event.target; - if (typeof eventTarget.targetRecord !== `undefined`) { - eventTarget.targetRecord.index = eventTarget.targetIndex; - setTimeout(function () { - EasyCoder.timestamp = Date.now(); - let p = EasyCoder.scripts[eventTarget.targetRecord.program]; - p.run(eventTarget.targetPc); - }, 1); - } - } - }); - } - }); - break; - case `click`: - targetRecord = program.getSymbolRecord(command.symbol); - targetRecord.program = program.script; - targetRecord.element.forEach(function (target, index) { - if (target) { - target.targetRecord = targetRecord; - target.targetIndex = index; - target.targetPc = command.pc + 2; - target.onclick = function (event) { - event.stopPropagation(); - if (program.length > 0) { - const eventTarget = event.target; - if (eventTarget.type != `radio`) { - eventTarget.blur(); - } - if (typeof eventTarget.targetRecord !== `undefined`) { - eventTarget.targetRecord.index = eventTarget.targetIndex; - setTimeout(function () { - EasyCoder.timestamp = Date.now(); - let p = EasyCoder.scripts[eventTarget.targetRecord.program]; - p.run(eventTarget.targetPc); - }, 1); - } - } - return false; - }; - } - }); - break; - case `clickDocument`: - program.targetPc = command.pc + 2; - const interceptClickEvent = (e) => { - EasyCoder.timestamp = Date.now(); - let target = e.target || e.srcElement; - let href = ``; - while (target.parentNode) { - if (target.tagName === `A`) { - href = target.href; - program.docPath = href.slice(-(href.length - window.location.href.length)); - break; - } - target = target.parentNode; - } - while (target.parentNode) { - if (target.id.indexOf(`ec-`) === 0) { - let id = target.id.slice(3); - let pos = id.indexOf(`-`); - program.varName = id.slice(0, pos); - id = id.slice(pos + 1); - pos = id.indexOf(`-`); - program.varIndex = parseInt(id.slice(0, pos)); - break; - } - target = target.parentNode; - } - if (href.indexOf(window.location.href) === 0) { - program.run(program.targetPc); - e.preventDefault(); - } - }; - if (document.addEventListener) { - document.addEventListener(`click`, interceptClickEvent); - } else if (document.attachEvent) { - document.attachEvent(`onclick`, interceptClickEvent); - } - break; - case `swipe`: - let xDown; - const getTouches = (evt) => { - return evt.touches || // browser API - evt.originalEvent.touches; // jQuery - }; - const handleTouchStart = (evt) => { - const firstTouch = getTouches(evt)[0]; - xDown = firstTouch.clientX; - }; - const handleTouchMove = (evt) => { - evt.stopImmediatePropagation(); - if (!xDown) { - return; - } - const xUp = evt.touches[0].clientX; - const xDiff = xDown - xUp; - if (Math.abs(xDiff) > 150) { - xDown = null; - if (xDiff > 0 && program.onSwipeLeft) { - program.run(program.onSwipeLeft); - } else if (xDiff < 0 && program.onSwipeRight) { - program.run(program.onSwipeRight); - } - } - }; - switch (command.direction) { - case `left`: - program.onSwipeLeft = command.pc + 2; - break; - case `right`: - program.onSwipeRight = command.pc + 2; - break; - } - document.addEventListener(`touchstart`, handleTouchStart, false); - document.addEventListener(`touchmove`, handleTouchMove, false); - break; - case `pick`: - const pickRecord = program.getSymbolRecord(command.symbol); - document.pickRecord = pickRecord; - pickRecord.element.forEach(function (element, index) { - document.pickIndex = index; - element.pickIndex = index; - // Set up the mouse down and up listeners - element.mouseDownPc = command.pc + 2; - // Check if touch device - let isTouchDevice = `ontouchstart` in element; - if (isTouchDevice) { - element.addEventListener(`touchstart`, function (e) { - const element = e.targetTouches[0].target; - document.pickX = e.touches[0].clientX; - document.pickY = e.touches[0].clientY; - element.blur(); - setTimeout(function () { - document.pickRecord.index = element.pickIndex; - program.run(element.mouseDownPc); - }, 1); - }, false); - element.addEventListener(`touchmove`, function (e) { - document.dragX = e.touches[0].clientX; - document.dragY = e.touches[0].clientY; - setTimeout(function () { - program.run(document.mouseMovePc); - }, 1); - return false; - }, false); - element.addEventListener(`touchend`, function () { - setTimeout(function () { - program.run(document.mouseUpPc); - }, 1); - return false; - }); - } else { - element.onmousedown = function (event) { - let e = event ? event : window.event; - e.stopPropagation(); - // IE uses srcElement, others use target - if (program.length > 0) { - const element = e.target ? e.target : e.srcElement; - element.offsetX = e.offsetX; - element.offsetY = e.offsetY; - document.pickX = e.clientX; - document.pickY = e.clientY; - element.blur(); - setTimeout(function () { - document.pickRecord.index = element.pickIndex; - program.run(element.mouseDownPc); - }, 1); - } - document.onmousemove = function (event) { - let e = event ? event : window.event; - e.stopPropagation(); - document.dragX = e.clientX; - document.dragY = e.clientY; - if (document.onmousemove) { - setTimeout(function () { - program.run(document.mouseMovePc); - }, 1); - } - return false; - }; - window.onmouseup = function () { - document.onmousemove = null; - document.onmouseup = null; - setTimeout(function () { - if (program && program.run) { - program.run(document.mouseUpPc); - } - }, 1); - return false; - }; - return false; - }; - } - }); - break; - case `drag`: - // Set up the move listener - document.mouseMovePc = command.pc + 2; - break; - case `drop`: - // Set up the move listener - document.mouseUpPc = command.pc + 2; - break; - case `key`: - if (typeof document.onKeyListeners === `undefined`) { - document.onKeyListeners = []; - } - if (!document.onKeyListeners.includes(program)) { - document.onKeyListeners.push(program); - } - program.onKeyPc = command.pc + 2; - document.onkeypress = function (event) { - for (const program of document.onKeyListeners) { - program.key = event.key; - try { - setTimeout(function () { - program.run(program.onKeyPc); - }, 1); - } catch (err) { - console.log(`Error: ${err.message}`); - } - } - return true; - }; - break; - case `windowResize`: - program.onWindowResize = command.pc + 2; - window.addEventListener('resize', function() { - program.run(program.onWindowResize); - }); - break; - case `browserBack`: - program.onBrowserBack = command.pc + 2; - break; - case `leave`: - window.addEventListener(`beforeunload`, function () { - program.run(command.pc + 2); - }); - break; - default: - break; - } - return command.pc + 1; - } - }, - - OPTION: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `option`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - P: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `p`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Play: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `audioclip`) { - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `play`, - lino, - target: targetRecord.name - }); - return true; - } - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const targetRecord = program.getSymbolRecord(command.target); - const url = program.value.evaluate(program, targetRecord.value[targetRecord.index]).content; - new Audio(url).play(); - return command.pc + 1; - } - }, - - PRE: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `pre`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - PROGRESS: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `progress`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Put: { - - compile: (compiler) => { - const lino = compiler.getLino(); - // Get the value - const value = compiler.getNextValue(); - if (compiler.tokenIs(`into`)) { - if (compiler.nextTokenIs(`storage`)) { - if (compiler.nextTokenIs(`as`)) { - const key = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `put`, - lino, - value, - key - }); - return true; - } - } - } - return false; - }, - - // runtime - - run: (program) => { - const command = program[program.pc]; - window.localStorage.setItem(program.getValue(command.key), program.getValue(command.value)); - return command.pc + 1; - } - }, - - Remove: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextTokenIs(`element`)) { - if (compiler.nextIsSymbol()) { - const element = compiler.getSymbolRecord(); - if (element.extra != `dom`) { - compiler.warning(`'${element.name}' is not a DOM element`); - return false; - } - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `remove`, - type: `removeElement`, - lino, - element: element.name - }); - return true; - } - } - if (compiler.tokenIs(`attribute`)) { - const attribute = compiler.getNextValue(); - if (compiler.tokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.extra !== `dom`) { - throw new Error(`Inappropriate type '${targetRecord.keyword}'`); - } - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `remove`, - type: `removeAttribute`, - lino, - attribute, - target: targetRecord.name - }); - return true; - } - } - } - try { - const key = compiler.getValue(); - if (compiler.tokenIs(`from`)) { - if (compiler.nextTokenIs(`storage`)) { - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `remove`, - type: `removeStorage`, - key - }); - return true; - } - } - } catch (err) { - return false; - } - return false; - }, - - // runtime - - run: (program) => { - const command = program[program.pc]; - switch (command.type) { - case `removeAttribute`: - const attribute = program.getValue(command.attribute); - const targetRecord = program.getSymbolRecord(command.target); - target = targetRecord.element[targetRecord.index]; - target.removeAttribute(attribute); - break; - case `removeElement`: - const elementRecord = program.getSymbolRecord(command.element); - const element = elementRecord.element[elementRecord.index]; - if (element) { - element.parentElement.removeChild(element); - } - break; - case `removeStorage`: - const key = program.getValue(command.key); - window.localStorage.removeItem(key); - break; - } - return command.pc + 1; - } - }, - - Request: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextToken() === `fullscreen`) { - let option = ``; - if (compiler.nextToken() === `exit`) { - option = `exit`; - compiler.next(); - } - compiler.addCommand({ - domain: `browser`, - keyword: `request`, - lino, - option - }); - return true; - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - if (command.option === `exit`) { - document.exitFullscreen(); - } else { - document.documentElement.requestFullscreen(); - } - return command.pc + 1; - } - }, - - SELECT: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `select`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Scroll: { - - compile: (compiler) => { - const lino = compiler.getLino(); - let name = null; - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - name = symbolRecord.name; - compiler.next(); - } - if (compiler.tokenIs(`to`)) { - const to = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `scroll`, - lino, - name, - to - }); - return true; - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const to = program.getValue(command.to); - if (command.name) { - const symbolRecord = program.getSymbolRecord(command.name); - symbolRecord.element[symbolRecord.index].scrollTo(0, to); - } else { - window.scrollTo(0, to); - } - return command.pc + 1; - } - }, - - SECTION: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `section`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Set: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - const target = targetRecord.name; - if (targetRecord.extra === `dom`) { - const token = compiler.nextToken(); - if (token === `from`) { - if (compiler.nextIsSymbol()) { - if (targetRecord.keyword === `select`) { - const sourceRecord = compiler.getSymbolRecord(); - if (sourceRecord.keyword === `variable`) { - var display = null; - if (compiler.nextTokenIs(`as`)) { - display = compiler.getNextValue(); - } - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setSelect`, - select: target, - source: sourceRecord.name, - display - }); - return true; - } - return false; - } - const source = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setContentVar`, - source, - target - }); - return true; - } - } - } - } else { - let token = compiler.getToken(); - if (token === `the`) { - token = compiler.nextToken(); - } - if (token === `title`) { - if (compiler.nextTokenIs(`to`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setTitle`, - value - }); - return true; - } - } else if (token === `content`) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const target = compiler.getToken(); - if (compiler.nextTokenIs(`from`)) { - if (compiler.nextIsSymbol()) { - const source = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setContentVar`, - source, - target - }); - return true; - } - } - if (compiler.tokenIs(`to`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setContent`, - value, - target - }); - return true; - } - } - throw new Error(`'${compiler.getToken()}' is not a symbol`); - } - } else if (token === `class`) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbol = compiler.getSymbolRecord(); - if (symbol.extra === `dom`) { - if (compiler.nextTokenIs(`to`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setClass`, - symbolName: symbol.name, - value - }); - return true; - } - } - } - } - } else if (token === `id`) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbol = compiler.getSymbolRecord(); - if (symbol.extra === `dom`) { - if (compiler.nextTokenIs(`to`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setId`, - symbolName: symbol.name, - value - }); - return true; - } - } - } - } - } else if (token === `text`) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbol = compiler.getSymbolRecord(); - switch (symbol.keyword) { - case `button`: - case `input`: - case `span`: - case `label`: - case `legend`: - if (compiler.nextTokenIs(`to`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setText`, - symbolName: symbol.name, - value - }); - return true; - } - break; - default: - break; - } - } - } - } else if (token === `size`) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbol = compiler.getSymbolRecord(); - switch (symbol.keyword) { - case `input`: - if (compiler.nextTokenIs(`to`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setSize`, - symbolName: symbol.name, - value - }); - return true; - } - } - } - } - } else if (token === `attribute`) { - compiler.next(); - const attributeName = compiler.getValue(); - if (compiler.tokenIs(`of`)) { - if (compiler.nextIsSymbol(true)) { - const symbolRecord = compiler.getSymbolRecord(); - const symbolName = symbolRecord.name; - compiler.next(); - let attributeValue = { - type: `boolean`, - content: true - }; - if (compiler.tokenIs(`to`)) { - attributeValue = compiler.getNextValue(); - } - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setAttribute`, - symbolName, - attributeName, - attributeValue - }); - return true; - } - } - } else if (token === `attributes`) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - const symbolName = symbolRecord.name; - if (symbolRecord.extra !== `dom`) { - compiler.warning(`'${symbolName}' is not a DOM type`); - return false; - } - if (compiler.nextTokenIs(`to`)) { - const attributes = compiler.getNextValue(); - if (attributes) { - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setAttributes`, - symbolName, - attributes - }); - return true; - } - } - } - } - compiler.warning(`'${compiler.getToken()}' is not a symbol`); - return false; - } else if (token === `style`) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - const symbolName = symbolRecord.name; - if (symbolRecord.extra !== `dom`) { - compiler.warning(`'${symbolName}' is not a DOM type`); - return false; - } - if (compiler.nextTokenIs(`to`)) { - const styleValue = compiler.getNextValue(); - if (styleValue) { - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setStyles`, - symbolName, - styleValue - }); - return true; - } - } - } - compiler.warning(`'${compiler.getToken()}' is not a symbol`); - return false; - } - const styleName = compiler.getValue(); - let type = `setStyle`; - let symbolName = ``; - token = compiler.getToken(); - if (token === `of`) { - if (compiler.nextToken() === `body`) { - type = `setBodyStyle`; - } else if (compiler.isSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - symbolName = symbolRecord.name; - if (symbolRecord.extra !== `dom`) { - throw Error(`'${symbolName}' is not a DOM type`); - } - } else { - throw Error(`'${compiler.getToken()}' is not a known symbol`); - } - if (compiler.nextTokenIs(`to`)) { - const styleValue = compiler.getNextValue(); - if (styleValue) { - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type, - symbolName, - styleName, - styleValue - }); - return true; - } - } - } - else if (token === `to`) { - const styleValue = compiler.getNextValue(); - if (styleValue) { - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setHeadStyle`, - styleName, - styleValue - }); - return true; - } - } - } else if (token === `default`) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.keyword === `select`) { - if (compiler.nextTokenIs(`to`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `browser`, - keyword: `set`, - lino, - type: `setDefault`, - name: symbolRecord.name, - value - }); - return true; - } - } - } - } - } - } - compiler.addWarning(`Unrecognised syntax in 'set'`); - return false; - }, - - run: (program) => { - const command = program[program.pc]; - let symbol; - let value; - let target; - let targetId; - let targetRecord; - let cssId; - let selectRecord; - switch (command.type) { - case `setContentVar`: - const sourceVar = program.getSymbolRecord(command.source); - targetRecord = program.getSymbolRecord(command.target); - const source = document.getElementById(sourceVar.value[sourceVar.index].content); - target = targetRecord.element[targetRecord.index]; - if (!target) { - targetId = program.getValue(targetRecord.value[targetRecord.index]); - target = document.getElementById(targetId); - } - target.innerHTML = source.innerHTML; - break; - case `setContent`: - value = program.getValue(command.value); - targetRecord = program.getSymbolRecord(command.target); - target = targetRecord.element[targetRecord.index]; - if (!target) { - cssId = targetRecord.value[targetRecord.index].content; - if (!cssId) { - program.runtimeError(command.lino, - `Variable '${targetRecord.name}' has not been attached to a DOM element.`); - return 0; - } - target = document.getElementById(cssId); - } - targetRecord.element[targetRecord.index] = target; - switch (targetRecord.keyword) { - case `text`: - case `textarea`: - target.value = value; - break; - case `input`: - target.value = value; - break; - default: - target.innerHTML = value; - break; - } - break; - case `setSelect`: - // The source is assumed to be an array - sourceRecord = program.getSymbolRecord(command.source); - const sourceData = program.getValue(sourceRecord.value[sourceRecord.index]); - var itemArray = ``; - try { - itemArray = JSON.parse(sourceData); - } catch (err) { - program.runtimeError(command.lino, `Can't parse JSON`); - return 0; - } - // The target is assumed to be a SELECT - selectRecord = program.getSymbolRecord(command.select); - const select = selectRecord.element[selectRecord.index]; - select.options.length = 0; - // Get the name of the display field - const display = program.getValue(command.display); - // For each item, set the title and inner HTML - itemArray.forEach(function (item) { - const title = display ? program.decode(item[display]) : null; - const opt = document.createElement(`option`); - const innerHTML = title ? title : item; - opt.innerHTML = innerHTML; - const value = title ? JSON.stringify(item) : item; - opt.value = value; - select.appendChild(opt); - }); - if (display) { - select.selectedIndex = itemArray.indexOf(display); - } else { - select.selectedIndex = -1; - } - break; - case `setClass`: - symbol = program.getSymbolRecord(command.symbolName); - target = symbol.element[symbol.index]; - if (!target) { - targetId = program.getValue(symbol.value[symbol.index]); - target = document.getElementById(targetId); - } - program.getValue(command.value).split(` `).forEach(function(item) { - target.classList.remove(item); - target.classList.add(item); - }); - break; - case `setId`: - symbol = program.getSymbolRecord(command.symbolName); - target = symbol.element[symbol.index]; - if (!target) { - targetId = program.getValue(symbol.value[symbol.index]); - target = document.getElementById(targetId); - } - target.id = program.getValue(command.value); - break; - case `setText`: - symbol = program.getSymbolRecord(command.symbolName); - target = symbol.element[symbol.index]; - if (!target) { - targetId = program.getValue(symbol.value[symbol.index]); - target = document.getElementById(targetId); - } - value = program.getValue(command.value); - switch (symbol.keyword) { - case `button`: - case `span`: - case `label`: - case `legend`: - target.innerHTML = value; - break; - case `input`: - target.value = value; - break; - default: - break; - } - break; - case `setSize`: - symbol = program.getSymbolRecord(command.symbolName); - if (symbol.keyword === `input`) { - target = symbol.element[symbol.index]; - if (!target) { - targetId = program.getValue(symbol.value[symbol.index]); - target = document.getElementById(targetId); - } - target.size = program.getValue(command.value); - } else { - program.runtimeError(command.lino, `Inappropriate variable type '${symbol.name}'`); - } - break; - case `setAttribute`: - symbol = program.getSymbolRecord(command.symbolName); - target = symbol.element[symbol.index]; - if (!target) { - targetId = program.getValue(symbol.value[symbol.index]); - target = document.getElementById(targetId); - } - const attributeName = program.getValue(command.attributeName); - if (command.attributeValue.type === `boolean`) { - target.setAttribute(attributeName, command.attributeValue.content); - } else { - target.setAttribute(attributeName, program.getValue(command.attributeValue)); - } - break; - case `setAttributes`: - symbol = program.getSymbolRecord(command.symbolName); - target = symbol.element[symbol.index]; - if (!target) { - targetId = program.getValue(symbol.value[symbol.index]); - target = document.getElementById(targetId); - } - for (let n = target.attributes.length - 1; n >= 0; n--) { - target.removeAttribute(target.attributes[n].name); - } - let attributes = program.getValue(command.attributes); - let list = attributes.split(" "); - for (let n = 0; n < list.length; n++) { - let attribute = list[n]; - let p = attribute.indexOf(`=`); - if (p > 0) { - target.setAttribute(attribute.substr(0, p), attribute.substr(p + 1)); - } - else { - target.setAttribute(attribute, attribute); - } - } - break; - case `setStyle`: - case `setStyles`: - symbol = program.getSymbolRecord(command.symbolName); - target = symbol.element[symbol.index]; - if (!target) { - const symbolElement = symbol.value[symbol.index]; - if (!symbolElement.type) { - program.runtimeError(command.lino, `Variable '${symbol.name}' is not attached to a DOM element.`); - return 0; - } - targetId = program.getValue(symbolElement); - target = document.getElementById(targetId); - } - const styleValue = program.getValue(command.styleValue); - if (!symbol.value[symbol.index]) { - program.runtimeError(command.lino, `Variable '${symbol.name}' has not been assigned.`); - return 0; - } - switch (command.type) { - case `setStyle`: - target.style[command.styleName.content] = styleValue; - break; - case `setStyles`: - target.style.cssText = styleValue; - break; - } - break; - case `setHeadStyle`: - const headStyleName = program.getValue(command.styleName); - const headStyleValue = program.getValue(command.styleValue); - var style = document.createElement('style'); - style.innerHTML = `${headStyleName} ${headStyleValue}`; - for (let i = 0; i < document.head.childNodes.length; i++) { - let node = document.head.childNodes[i]; - if (node.tagName === `STYLE`) { - let data = node.innerHTML; - if (data.indexOf(`${headStyleName} `) === 0) { - document.head.removeChild(node); - break; - } - } - } - document.head.appendChild(style); - break; - case `setBodyStyle`: - const bodyStyleValue = program.getValue(command.styleValue); - switch (command.styleName.content) { - case `background`: - document.body.style.background = bodyStyleValue; - break; - default: - program.runtimeError(command.lino, - `Unsupported body attribute '${command.styleName.content}'`); - return 0; - } - break; - case `setTitle`: - document.title = program.getValue(command.value); - break; - case `setDefault`: - selectRecord = program.getSymbolRecord(command.name); - value = program.getValue(command.value); - const element = selectRecord.element[selectRecord.index]; - for (let n = 0; n < element.options.length; n++) { - if (element.options[n].value === value) { - element.selectedIndex = n; - break; - } - } - break; - default: - break; - } - return command.pc + 1; - } - }, - - SPAN: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `span`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - TABLE: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `table`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - TR: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `tr`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - TD: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `td`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - TEXTAREA: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `textarea`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Trace: { - - compile: (compiler) => { - const lino = compiler.getLino(); - const variables = []; - if (compiler.nextIsSymbol()) { - while (compiler.isSymbol()) { - variables.push(compiler.getToken()); - compiler.next(); - } - let alignment = `horizontal`; - if (compiler.tokenIs(`horizontal`) || compiler.tokenIs(`vertical`)) { - alignment = compiler.getToken(); - compiler.next(); - } - compiler.addCommand({ - domain: `browser`, - keyword: `trace`, - variant: `setup`, - lino, - variables, - alignment - }); - return true; - } - compiler.addCommand({ - domain: `browser`, - keyword: `trace`, - variant: `run`, - lino - }); - return true; - }, - - run: (program) => { - const command = program[program.pc]; - switch (command.variant) { - case `setup`: - console.log(`Set up tracer`); - program.tracer = { - variables: command.variables, - alignment: command.alignment - }; - break; - case `run`: - console.log(`Run tracer`); - if (!program.tracer) { - program.tracer = { - variables: [], - alignment: `horizontal` - }; - } - if (!program.tracing) { - const tracer = document.getElementById(`easycoder-tracer`); - if (tracer) { - tracer.innerHTML = - `

    ` + - `` + - `
    ` + - `
    `; - tracer.style.display = `none`; - } - program.tracing = true; - } - program.stop = false; - break; - } - return program.pc + 1; - } - }, - - UL: { - - compile: (compiler) => { - compiler.compileVariable(`browser`, `ul`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Upload: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const file = compiler.getToken(); - if (compiler.nextTokenIs(`to`)) { - const path = compiler.getNextValue(); - if (compiler.tokenIs(`with`)) { - if (compiler.nextIsSymbol()) { - const progress = compiler.getToken(); - if (compiler.nextTokenIs(`and`)) { - if (compiler.nextIsSymbol()) { - const status = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `browser`, - keyword: `upload`, - lino, - file, - path, - progress, - status - }); - return true; - } - } - } - } - } - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const fileSpec = program.getSymbolRecord(command.file); - const path = program.getValue(command.path); - const progressSpec = program.getSymbolRecord(command.progress); - const statusSpec = program.getSymbolRecord(command.status); - - const file = fileSpec.element[fileSpec.index]; - const progress = progressSpec.element[progressSpec.index]; - const status = statusSpec.element[statusSpec.index]; - - const setProgress = (value) => { - if (progress) { - progress.value = value; - } - }; - const setStatus = (value) => { - if (status) { - status.innerHTML = value; - } - }; - - const source = file.files[0]; - if (source) { - const formData = new FormData(); - formData.append(`source`, source); - formData.append(`path`, path); - const ajax = new XMLHttpRequest(); - ajax.upload.addEventListener(`progress`, function (event) { - const percent = Math.round((event.loaded / event.total) * 100); - setProgress(percent); - setStatus(`${Math.round(percent)}%...`); - }, false); - ajax.addEventListener(`load`, function (event) { - const response = event.target.responseText; - setProgress(0); - setStatus(``); - console.log(response); - }, false); - ajax.addEventListener(`error`, function () { - setStatus(`Upload failed`); - console.log(`Upload failed`); - }, false); - ajax.addEventListener(`abort`, function () { - setStatus(`Upload aborted`); - console.log(`Upload aborted`); - }, false); - ajax.onreadystatechange = function () { - if (this.readyState === 4) { - const command = program.ajaxCommand; - const status = this.status; - switch (status) { - case 200: - program.run(command.pc + 1); - break; - case 0: - break; - default: - try { - program.runtimeError(command.lino, `Error ${status}`); - } catch (err) { - program.reportError(err, program); - } - break; - } - } - }; - program.ajaxCommand = command; - const postpath = path.startsWith(`http`) ? path : `${window.location.origin}/${EasyCoder_Plugins.rest()}/${path}`; - ajax.open(`POST`, postpath); - ajax.send(formData); - } - return 0; - } - }, - - getHandler: (name) => { - switch (name) { - case `a`: - return EasyCoder_Browser.A; - case `alert`: - return EasyCoder_Browser.Alert; - case `attach`: - return EasyCoder_Browser.Attach; - case `audioclip`: - return EasyCoder_Browser.Audioclip; - case `blockquote`: - return EasyCoder_Browser.BLOCKQUOTE; - case `button`: - return EasyCoder_Browser.BUTTON; - case `canvas`: - return EasyCoder_Browser.CANVAS; - case `clear`: - return EasyCoder_Browser.Clear; - case `convert`: - return EasyCoder_Browser.Convert; - case `create`: - return EasyCoder_Browser.Create; - case `disable`: - return EasyCoder_Browser.Disable; - case `div`: - return EasyCoder_Browser.DIV; - case `enable`: - return EasyCoder_Browser.Enable; - case `fieldset`: - return EasyCoder_Browser.FIELDSET; - case `file`: - return EasyCoder_Browser.FILE; - case `focus`: - return EasyCoder_Browser.Focus; - case `form`: - return EasyCoder_Browser.FORM; - case `fullscreen`: - return EasyCoder_Browser.FullScreen; - case `get`: - return EasyCoder_Browser.Get; - case `h1`: - return EasyCoder_Browser.H1; - case `h2`: - return EasyCoder_Browser.H2; - case `h3`: - return EasyCoder_Browser.H3; - case `h4`: - return EasyCoder_Browser.H4; - case `h5`: - return EasyCoder_Browser.H5; - case `h6`: - return EasyCoder_Browser.H6; - case `highlight`: - return EasyCoder_Browser.Highlight; - case `history`: - return EasyCoder_Browser.History; - case `hr`: - return EasyCoder_Browser.HR; - case `image`: - return EasyCoder_Browser.IMAGE; - case `img`: - return EasyCoder_Browser.IMG; - case `input`: - return EasyCoder_Browser.INPUT; - case `label`: - return EasyCoder_Browser.LABEL; - case `legend`: - return EasyCoder_Browser.LEGEND; - case `li`: - return EasyCoder_Browser.LI; - case `location`: - return EasyCoder_Browser.Location; - case `mail`: - return EasyCoder_Browser.Mail; - case `on`: - return EasyCoder_Browser.On; - case `option`: - return EasyCoder_Browser.OPTION; - case `p`: - return EasyCoder_Browser.P; - case `play`: - return EasyCoder_Browser.Play; - case `pre`: - return EasyCoder_Browser.PRE; - case `progress`: - return EasyCoder_Browser.PROGRESS; - case `put`: - return EasyCoder_Browser.Put; - case `remove`: - return EasyCoder_Browser.Remove; - case `request`: - return EasyCoder_Browser.Request; - case `select`: - return EasyCoder_Browser.SELECT; - case `scroll`: - return EasyCoder_Browser.Scroll; - case `section`: - return EasyCoder_Browser.SECTION; - case `set`: - return EasyCoder_Browser.Set; - case `span`: - return EasyCoder_Browser.SPAN; - case `table`: - return EasyCoder_Browser.TABLE; - case `tr`: - return EasyCoder_Browser.TR; - case `td`: - return EasyCoder_Browser.TD; - case `textarea`: - return EasyCoder_Browser.TEXTAREA; - case `trace`: - return EasyCoder_Browser.Trace; - case `ul`: - return EasyCoder_Browser.UL; - case `upload`: - return EasyCoder_Browser.Upload; - default: - return null; - } - }, - - run: (program) => { - const command = program[program.pc]; - const handler = EasyCoder_Browser.getHandler(command.keyword); - if (!handler) { - program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'browser' package`); - } - return handler.run(program); - }, - - value: { - - compile: (compiler) => { - if (compiler.isSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (compiler.nextTokenIs(`exists`)) { - if (symbolRecord.extra === `dom`) { - compiler.next(); - return { - domain: `browser`, - type: `exists`, - value: symbolRecord.name - }; - } - return null; - } - switch (symbolRecord.keyword) { - case `file`: - case `input`: - case `select`: - case `textarea`: - return { - domain: `browser`, - type: symbolRecord.keyword, - value: symbolRecord.name - }; - } - return null; - } - - if (compiler.tokenIs(`the`)) { - compiler.next(); - } - let offset = false; - if (compiler.tokenIs(`offset`)) { - offset = true; - compiler.next(); - } - - let type = compiler.getToken(); - let text; - let attribute; - switch (type) { - case `mobile`: - case `portrait`: - case `landscape`: - case `br`: - case `location`: - case `key`: - case `hostname`: - compiler.next(); - return { - domain: `browser`, - type - }; - case `content`: - case `text`: - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbol = compiler.getSymbolRecord(); - compiler.next(); - return { - domain: `browser`, - type: `contentOf`, - symbol: symbol.name - }; - } - throw new Error(`'${compiler.getToken()}' is not a symbol`); - } - return null; - case `selected`: - let arg = compiler.nextToken(); - if ([`index`, `item`].includes(arg)) { - if ([`in`, `of`].includes(compiler.nextToken())) { - if (compiler.nextIsSymbol()) { - const symbol = compiler.getSymbolRecord(); - if ([`ul`, `ol`, `select`].includes(symbol.keyword)) { - compiler.next(); - return { - domain: `browser`, - type: `selected`, - symbol: symbol.name, - arg - }; - } - } - } - } - return null; - case `color`: - compiler.next(); - const value = compiler.getValue(); - return { - domain: `browser`, - type, - value - }; - case `attribute`: - attribute = compiler.getNextValue(); - if (compiler.tokenIs(`of`)) { - compiler.next(); - if (compiler.isSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.extra === `dom`) { - compiler.next(); - return { - domain: `browser`, - type: `attributeOf`, - attribute, - symbol: symbolRecord.name - }; - } - } - } - return null; - case `style`: - const style = compiler.getNextValue(); - if (compiler.tokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.extra === `dom`) { - compiler.next(); - return { - domain: `browser`, - type, - style, - target: symbolRecord.name - }; - } - } - } - return null; - case `confirm`: - text = compiler.getNextValue(); - return { - domain: `browser`, - type: `confirm`, - text - }; - case `prompt`: - text = compiler.getNextValue(); - let pre = null; - if (compiler.tokenIs(`with`)) { - pre = compiler.getNextValue(); - } - return { - domain: `browser`, - type: `prompt`, - text, - pre - }; - case `screen`: - attribute = compiler.nextToken(); - if ([`width`, `height`].includes(attribute)) { - compiler.next(); - return { - domain: `browser`, - type, - attribute - }; - } - break; - case `top`: - case `bottom`: - case `left`: - case `right`: - case `width`: - case `height`: - return EasyCoder_Browser.value.getCoord(compiler, type, offset); - case `scroll`: - if (compiler.nextTokenIs(`position`)) { - compiler.next(); - return { - domain: `browser`, - type: `scrollPosition` - }; - } - return null; - case `document`: - if (compiler.nextTokenIs(`path`)) { - compiler.next(); - return { - domain: `browser`, - type: `docPath` - }; - } - return null; - case `storage`: - if (compiler.nextTokenIs(`keys`)) { - compiler.next(); - return { - domain: `browser`, - type: `storageKeys` - }; - } - return null; - case `parent`: - switch (compiler.nextToken()) { - case `name`: - compiler.next(); - return { - domain: `browser`, - type: `varName` - }; - case `index`: - compiler.next(); - return { - domain: `browser`, - type: `varIndex` - }; - } - return null; - case `history`: - if (compiler.nextTokenIs(`state`)) { - compiler.next(); - return { - domain: `browser`, - type: `historyState` - }; - } - return null; - case `pick`: - case `drag`: - if (compiler.nextTokenIs(`position`)) { - compiler.next(); - return { - domain: `browser`, - type: `${type}Position` - }; - } - } - return null; - }, - - getCoord: (compiler, type, offset) => { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextTokenIs(`window`)) { - compiler.next(); - return { - domain: `browser`, - type, - symbol: `window`, - offset - }; - } - let symbolRecord = null; - if (compiler.isSymbol()) { - symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.extra === `dom`) { - compiler.next(); - return { - domain: `browser`, - type, - symbol: symbolRecord.name, - offset - }; - } - } - } - return null; - }, - - get: (program, value) => { - let symbolRecord; - let element; - let target; - let content; - switch (value.type) { - case `file`: - case `input`: - case `select`: - case `textarea`: - symbolRecord = program.getSymbolRecord(value.value); - target = symbolRecord.element[symbolRecord.index]; - return { - type: `constant`, - numeric: false, - content: target.value - }; - case `exists`: - symbolRecord = program.getSymbolRecord(value.value); - return { - domain: `browser`, - type: `boolean`, - content: typeof symbolRecord.element[symbolRecord.index] !== `undefined` - }; - case `mobile`: - return { - domain: `browser`, - type: `boolean`, - content: (typeof window.orientation !== `undefined`) || (navigator.userAgent.indexOf(`IEMobile`) !== -1) - }; - case `portrait`: - return { - domain: `browser`, - type: `boolean`, - content: document.documentElement.clientWidth < document.documentElement.clientHeight - }; - case `landscape`: - return { - domain: `browser`, - type: `boolean`, - content: document.documentElement.clientWidth >= document.documentElement.clientHeight - }; - case `br`: - return { - type: `constant`, - numeric: false, - content: decodeURIComponent(`%3Cbr%20%2F%3E`) - }; - case `attributeOf`: - symbolRecord = program.getSymbolRecord(value.symbol); - const attribute = program.getValue(value.attribute); - target = symbolRecord.element[symbolRecord.index]; - if (attribute.indexOf(`data-`) === 0) { - return program.getSimpleValue(target.dataset[attribute.substr(5)]); - } - return program.getSimpleValue(target[attribute]); - case `style`: - symbolRecord = program.getSymbolRecord(value.target); - const style = program.getValue(value.style); - target = symbolRecord.element[symbolRecord.index]; - return program.getSimpleValue(target.style[style]); - case `confirm`: - return { - type: `boolean`, - content: window.confirm(program.getValue(value.text)) - }; - case `prompt`: - const text = program.getValue(value.text); - const pre = program.getValue(value.pre); - return { - type: `constant`, - numeric: false, - content: pre ? window.prompt(text, pre) : window.prompt(text) - }; - case `contentOf`: - symbolRecord = program.getSymbolRecord(value.symbol); - target = symbolRecord.element[symbolRecord.index]; - switch (symbolRecord.keyword) { - case `input`: - case `textarea`: - content = target.value; - break; - case `pre`: - content = target.innerHTML; - break; - default: - content = target.innerHTML.split(`\n`).join(``); - break; - } - return { - type: `constant`, - numeric: false, - content - }; - case `selected`: - symbolRecord = program.getSymbolRecord(value.symbol); - target = symbolRecord.element[symbolRecord.index]; - let selectedIndex = target.selectedIndex; - let selectedText = selectedIndex >= 0 ? target.options[selectedIndex].text : ``; - content = (value.arg === `index`) ? selectedIndex : selectedText; - return { - type: `constant`, - numeric: false, - content - }; - case `top`: - if (value.symbol == `window`) { - return { - type: `constant`, - numeric: true, - content: window.screenY - }; - } - symbolRecord = program.getSymbolRecord(value.symbol); - element = symbolRecord.element[symbolRecord.index]; - content = Math.round(value.offset ? element.offsetTop : element.getBoundingClientRect().top); - return { - type: `constant`, - numeric: true, - content - }; - case `bottom`: - if (value.symbol == `window`) { - return { - type: `constant`, - numeric: true, - content: window.screenY + window.innerHeight - }; - } - symbolRecord = program.getSymbolRecord(value.symbol); - content = Math.round(symbolRecord.element[symbolRecord.index].getBoundingClientRect().bottom); - return { - type: `constant`, - numeric: true, - content - }; - case `left`: - if (value.symbol == `window`) { - return { - type: `constant`, - numeric: true, - content: window.screenLeft - }; - } - symbolRecord = program.getSymbolRecord(value.symbol); - element = symbolRecord.element[symbolRecord.index]; - content = Math.round(value.offset ? element.offsetLeft : element.getBoundingClientRect().left); - return { - type: `constant`, - numeric: true, - content - }; - case `right`: - if (value.symbol == `window`) { - return { - type: `constant`, - numeric: true, - content: window.screenX + window.innerWidth - }; - } - symbolRecord = program.getSymbolRecord(value.symbol); - content = Math.round(symbolRecord.element[symbolRecord.index].getBoundingClientRect().right); - return { - type: `constant`, - numeric: true, - content - }; - case `width`: - if (value.symbol == `window`) { - return { - type: `constant`, - numeric: true, - content: window.innerWidth - }; - } - symbolRecord = program.getSymbolRecord(value.symbol); - content = Math.round(symbolRecord.element[symbolRecord.index].getBoundingClientRect().width); - return { - type: `constant`, - numeric: true, - content - }; - case `height`: - if (value.symbol == `window`) { - return { - type: `constant`, - numeric: true, - content: window.innerHeight - }; - } - symbolRecord = program.getSymbolRecord(value.symbol); - content = Math.round(symbolRecord.element[symbolRecord.index].getBoundingClientRect().height); - return { - type: `constant`, - numeric: true, - content - }; - case `color`: - const styleValue = program.value.evaluate(program, value.value).content; - const hex = styleValue.toString(16).padStart(6, `0`); - return { - type: `constant`, - numeric: false, - content: `#${hex}` - }; - case `docPath`: - return { - type: `constant`, - numeric: false, - content: program.docPath - }; - case `storageKeys`: - return { - type: `constant`, - numeric: false, - content: JSON.stringify(Object.keys(localStorage)) - }; - case `location`: - return { - type: `constant`, - numeric: false, - content: window.location.href - }; - case `historyState`: - return { - type: `constant`, - numeric: false, - content: window.history.state - }; - case `scrollPosition`: - return { - type: `constant`, - numeric: true, - content: scrollPosition - }; - case `varName`: - return { - type: `constant`, - numeric: false, - content: program.varName - }; - case `varIndex`: - return { - type: `constant`, - numeric: true, - content: program.varIndex - }; - case `key`: - return { - type: `constant`, - numeric: false, - content: program.key - }; - case `hostname`: - return { - type: `constant`, - numeric: false, - content: location.hostname - }; - case `screen`: - return { - type: `constant`, - numeric: true, - content: screen[value.attribute] - }; - case `pickPosition`: - return { - type: `constant`, - numeric: false, - content: JSON.stringify({ - "x": document.pickX, - "y": document.pickY - }) - }; - case `dragPosition`: - return { - type: `constant`, - numeric: false, - content: JSON.stringify({ - "x": document.dragX, - "y": document.dragY - }) - }; - } - } - }, - - condition: { - - compile: (compiler) => { - if (compiler.tokenIs(`confirm`)) { - const value = compiler.getNextValue(); - return { - domain: `browser`, - type: `confirm`, - value - }; - } else if (compiler.tokenIs(`element`)) { - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.extra === `dom`) { - const token = compiler.nextToken(); - if (token === `has`) { - if (compiler.nextTokenIs(`the`)) { - compiler.next(); - } - if (compiler.tokenIs(`focus`)) { - compiler.next(); - return { - domain: `browser`, - type: `focus`, - element: symbolRecord.name - }; - } - } else if (token === `contains`) { - const position = compiler.getNextValue(); - return { - domain: `browser`, - type: `contains`, - element: symbolRecord.name, - position - }; - } - } - } - } - return null; - }, - - test: (program, condition) => { - switch (condition.type) { - case `confirm`: - return confirm(program.getValue(condition.value)); - case `focus`: - const focusRecord = program.getSymbolRecord(condition.element); - return focusRecord.element[focusRecord.index] === document.activeElement; - case `contains`: - const containsRecord = program.getSymbolRecord(condition.element); - const element = containsRecord.element[containsRecord.index]; - const bounds = element.getBoundingClientRect(); - const left = Math.round(bounds.left); - const right = Math.round(bounds.right); - const top = Math.round(bounds.top); - const bottom = Math.round(bounds.bottom); - const position = JSON.parse(program.getValue(condition.position)); - const x = position.x; - const y = position.y; - if (x >= left && x <= right && y >= top && y <= bottom) { - return true; - } - return false; - } - } - }, - - setStyles: (id, styleString) => { - const element = document.getElementById(id); - const styles = styleString.split(`;`); - for (const item of styles) { - const style = item.split(`:`); - element.setAttribute(style[0], style[1]); - } - } -}; - -let scrollPosition = 0; - -window.addEventListener(`scroll`, function () { - scrollPosition = this.scrollY; -}); - -window.onpopstate = function (event) { - window.EasyCoder.timestamp = Date.now(); - const state = JSON.parse(event.state); - if (state && state.script) { - const program = window.EasyCoder.scripts[state.script]; - if (program) { - if (program.onBrowserBack) { - program.run(program.onBrowserBack); - } - } else { - console.log(`No script property in window state object`); - } - } -}; diff --git a/easycoder/plugins/ckeditor.js b/easycoder/plugins/ckeditor.js deleted file mode 100644 index 32d64dd..0000000 --- a/easycoder/plugins/ckeditor.js +++ /dev/null @@ -1,172 +0,0 @@ -const EasyCoder_CKEditor = { - - name: `EasyCoder_CKEditor`, - - CKEditor: { - - compile: (compiler) => { - const lino = compiler.getLino(); - const action = compiler.nextToken(); - compiler.next(); - switch (action) { - case `attach`: - if (compiler.tokenIs(`to`)) { - if (compiler.nextIsSymbol()) { - const editor = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `ckeditor`, - keyword: `ckeditor`, - lino, - action, - editor - }); - return true; - } - } - break; - case `close`: - if (compiler.isSymbol()) { - const editor = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `ckeditor`, - keyword: `ckeditor`, - lino, - action, - editor - }); - return true; - } - break; - case `get`: - if (compiler.isSymbol()) { - const target = compiler.getToken(); - if (compiler.nextTokenIs(`from`)) { - compiler.next(); - if (compiler.isSymbol()) { - const editor = compiler.getToken(); - compiler.next(); - compiler.addCommand({ - domain: `ckeditor`, - keyword: `ckeditor`, - lino, - action, - target, - editor - }); - return true; - } - } - } - break; - case `set`: - if (compiler.isSymbol()) { - const editor = compiler.getToken(); - if (compiler.nextTokenIs(`to`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `ckeditor`, - keyword: `ckeditor`, - lino, - action, - editor, - value - }); - return true; - } - } - break; - default: - compiler.addCommand({ - domain: `ckeditor`, - keyword: `ckeditor`, - lino, - action - }); - break; - } - return true; - }, - - run: (program) => { - const command = program[program.pc]; - var editor; - var content; - switch (command.action) { - case `test`: - break; - case `attach`: - editor = program.getSymbolRecord(command.editor); - editor.editor = - CKEDITOR.appendTo(editor.element[editor.index].id, { - height: 400 - }); - break; - case `close`: - editor = program.getSymbolRecord(command.editor); - editor.editor.destroy(); - break; - case `get`: - editor = program.getSymbolRecord(command.editor); - const targetRecord = program.getSymbolRecord(command.target); - content = editor.editor.getData() - .split(`\n`).join(``).split(` `).join(` `); - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content - }; - break; - case `set`: - editor = program.getSymbolRecord(command.editor); - content = program.getValue(command.value); - editor.editor.setData(content, { - callback: function () { - program.run(command.pc + 1); - } - }); - return 0; - case `reset`: - for (const name in CKEDITOR.instances) { - CKEDITOR.instances[name].destroy(); - } - break; - } - return command.pc + 1; - } - }, - - getHandler: (name) => { - switch (name) { - case `ckeditor`: - return EasyCoder_CKEditor.CKEditor; - default: - return null; - } - }, - - run: (program) => { - const command = program[program.pc]; - const handler = EasyCoder_CKEditor.getHandler(command.keyword); - if (!handler) { - program.runtimeError(command.lino, - `Unknown keyword '${command.keyword}' in 'ckeditor' package`); - } - return handler.run(program); - }, - - value: { - - compile: () => { - return null; - }, - get: () => {} - }, - - condition: { - - compile: () => {}, - test: () => {} - } -}; diff --git a/easycoder/plugins/codemirror-ecs.js b/easycoder/plugins/codemirror-ecs.js deleted file mode 100644 index 58d762c..0000000 --- a/easycoder/plugins/codemirror-ecs.js +++ /dev/null @@ -1,63 +0,0 @@ -(function (mod) { - if (typeof exports == `object` && typeof module == `object`) // CommonJS - mod(require(`../../lib/codemirror`)); - else if (typeof define == `function` && define.amd) // AMD - define([`../../lib/codemirror`], mod); - else // Plain browser env - mod(CodeMirror); -})(function (CodeMirror) { - "use strict"; - - - CodeMirror.defineMode(`ecs`, function () { - return { - startState: function () { - return { - inString: false, - inComment: false - }; - }, - token: function (stream, state) { - stream.eatSpace(); - // If a string or a comment starts here - if (!state.inString && stream.peek() === `\``) { - stream.next(); // Skip quote - state.inString = true; - } else if (!state.inComment && stream.peek() === `!`) { - stream.next(); // Skip shriek - state.inComment = true; - } - - if (state.inString) { - if (stream.skipTo(`\``)) { // Quote found on this line - stream.next(); // Skip quote - state.inString = false; // Clear flag - } else { - stream.skipToEnd(); - state.inString = false; // Clear flag - } - return `string`; // Return the token style - } - - else if (state.inComment) { - stream.skipToEnd(); - state.inComment = false; - return `comment`; // Return the token style - } - - else { - if (stream.match(/[A-Z][A-Za-z0-9-_]*/, true)) { - return `attribute`; - } - if (stream.match(/[0-9]+/, true)) { - return `number`; - } - stream.skipTo(` `) || stream.skipToEnd(); - return null; // Unstyled token - } - } - }; - }); - - CodeMirror.defineMIME(`text/x-ecs`, `ecs`); -}); \ No newline at end of file diff --git a/easycoder/plugins/codemirror.js b/easycoder/plugins/codemirror.js deleted file mode 100644 index ccec906..0000000 --- a/easycoder/plugins/codemirror.js +++ /dev/null @@ -1,170 +0,0 @@ -const EasyCoder_CodeMirror = { - - name: `EasyCoder_CodeMirror`, - - CodeMirror: { - - compile: (compiler) => { - const lino = compiler.getLino(); - const action = compiler.nextToken(); - switch (action) { - case `init`: - const mode = compiler.nextToken(); - let profile = ``; - if (compiler.nextTokenIs(`profile`)) { - profile = compiler.getNextValue(); - } - compiler.addCommand({ - domain: `codemirror`, - keyword: `codemirror`, - lino, - action, - mode, - profile - }); - return true; - case `attach`: - if (compiler.nextTokenIs(`to`)) { - if (compiler.nextIsSymbol()) { - const editor = compiler.getToken(); - let mode = `ecs`; - if (compiler.nextTokenIs(`mode`)) { - mode = compiler.nextToken(); - compiler.next(); - } - compiler.addCommand({ - domain: `codemirror`, - keyword: `codemirror`, - lino, - action, - editor, - mode - }); - return true; - } - } - break; - case `set`: - if (compiler.nextTokenIs(`content`)) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const editor = compiler.getSymbolRecord(); - if (compiler.nextTokenIs(`to`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `codemirror`, - keyword: `codemirror`, - lino, - action: `setContent`, - editor: editor.name, - value - }); - return true; - } - } - } - } - break; - case `close`: - if (compiler.nextIsSymbol()) { - const editor = compiler.getSymbolRecord(); - compiler.next(); - compiler.addCommand({ - domain: `codemirror`, - keyword: `codemirror`, - lino, - action: `close`, - editor: editor.name - }); - return true; - } - return false; - default: - throw new Error(`Unrecognized action '${action}'`); - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - var editor; - switch (command.action) { - case `init`: - switch (command.mode) { - case `basic`: - program.require(`css`, `https://codemirror.net/lib/codemirror.css`, - function () { - program.require(`js`, `https://codemirror.net/lib/codemirror.js`, - function () { - if (command.profile) { - program.require(`js`, program.getValue(command.profile), - function () { - program.run(command.pc + 1); - }); - } else { - program.run(command.pc + 1); - } - }); - }); - return 0; - } - break; - case `attach`: - try { - editor = program.getSymbolRecord(command.editor); - const element = document.getElementById(editor.element[editor.index].id); - editor.editor = CodeMirror.fromTextArea(element, { - mode: command.mode, - theme: `default`, - lineNumbers: true - }); - editor.editor.setSize(`100%`, `100%`); - } catch (err) { alert(err); } - break; - case `setContent`: - editor = program.getSymbolRecord(command.editor); - const value = program.getValue(command.value); - editor.editor.setValue(value); - break; - case `close`: - editor = program.getSymbolRecord(command.editor); - editor.editor.toTextArea(); - break; - } - return command.pc + 1; - } - }, - - getHandler: (name) => { - switch (name) { - case `codemirror`: - return EasyCoder_CodeMirror.CodeMirror; - default: - return null; - } - }, - - run: (program) => { - const command = program[program.pc]; - const handler = EasyCoder_CodeMirror.getHandler(command.keyword); - if (!handler) { - program.runtimeError(command.lino, - `Unknown keyword '${command.keyword}' in 'codemirror' package`); - } - return handler.run(program); - }, - - value: { - - compile: () => { - return null; - }, - get: () => {} - }, - - condition: { - - compile: () => {}, - test: () => {} - } -}; diff --git a/easycoder/plugins/dummy.js b/easycoder/plugins/dummy.js deleted file mode 100644 index fd416c4..0000000 --- a/easycoder/plugins/dummy.js +++ /dev/null @@ -1,66 +0,0 @@ -const EasyCoder_Dummy = { - - name: `EasyCoder_Dummy`, - - Dummy: { - - // Command keywords - compile: compiler => { - const lino = compiler.getLino(); - compiler.next(); - compiler.addCommand({ - domain: `dummy`, - keyword: `dummy`, - lino - }); - return true; - }, - - run: program => { - const command = program[program.pc]; - return command.pc + 1; - } - }, - - // Values - value: { - - compile: () => { - return { - domain: `dummy`, - type: `dummy` - }; - }, - - get: (program, value) => { - return value; - } - }, - - // Conditions - condition: { - - compile: () => {}, - - test: () => {} - }, - - // Dispatcher - getHandler: (name) => { - switch (name) { - case `dummy`: - return EasyCoder_Dummy.Dummy; - default: - return false; - } - }, - - run: program => { - const command = program[program.pc]; - const handler = EasyCoder_Dummy.getHandler(command.keyword); - if (!handler) { - program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'dummy' package`); - } - return handler.run(program); - } -}; \ No newline at end of file diff --git a/easycoder/plugins/gmap.js b/easycoder/plugins/gmap.js deleted file mode 100644 index 52ce2ea..0000000 --- a/easycoder/plugins/gmap.js +++ /dev/null @@ -1,558 +0,0 @@ - -const EasyCoder_GMap = { - - name: `EasyCoder_GMap`, - - Create: { - - compile: compiler => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - const type = symbolRecord.keyword; - switch (type) { - case `gmap`: - if (compiler.nextTokenIs(`in`)) { - if (compiler.nextIsSymbol()) { - const parentRecord = compiler.getSymbolRecord(); - if (parentRecord.keyword === `div`) { - compiler.next(); - compiler.addCommand({ - domain: `gmap`, - keyword: `create`, - type, - lino, - name: symbolRecord.name, - parent: parentRecord.name - }); - return true; - } - } - } - return false; - case `marker`: - if (compiler.nextTokenIs(`in`)) { - if (compiler.nextIsSymbol()) { - const parentRecord = compiler.getSymbolRecord(); - if (parentRecord.keyword === `gmap`) { - compiler.next(); - compiler.addCommand({ - domain: `gmap`, - keyword: `create`, - type, - lino, - name: symbolRecord.name, - map: parentRecord.name - }); - return true; - } - } - } - return false; - } - } - return false; - }, - - run: program => { - const command = program[program.pc]; - const symbolRecord = program.getSymbolRecord(command.name); - switch (command.type) { - case `gmap`: - symbolRecord.parent = program.getSymbolRecord(command.parent); - symbolRecord.markers = []; - break; - case `marker`: - const mapRecord = program.getSymbolRecord(command.map); - const element = new google.maps.Marker({ - map: mapRecord.map - }); - symbolRecord.element[symbolRecord.index] = element; - mapRecord.markers.push(element); - element.addListener(`click`, function () { - program.run(symbolRecord.onClick); - }); - break; - } - return command.pc + 1; - } - }, - - GMap: { - - compile: compiler => { - compiler.compileVariable(`gmap`, `gmap`); - return true; - }, - - run: program => { - return program[program.pc].pc + 1; - } - }, - - On: { - - compile: compiler => { - const lino = compiler.getLino(); - const action = compiler.nextToken(); - if ([`click`, `move`, `type`, `zoom`].includes(action)) { - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.keyword === `gmap` || (symbolRecord.keyword === `marker` && action === `click`)) { - compiler.next(); - compiler.addCommand({ - domain: `gmap`, - keyword: `on`, - lino, - action, - name: symbolRecord.name - }); - return compiler.completeHandler(); - } - } - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const symbolRecord = program.getSymbolRecord(command.name); - switch (command.action) { - case `click`: - if (symbolRecord.keyword === `marker`) { - symbolRecord.element.forEach(function (marker, index) { - marker.targetRecord = symbolRecord; - marker.targetIndex = index; - marker.targetPc = command.pc + 2; - marker.addListener(`click`, function () { - if (program.length > 0) { - marker.targetRecord.index = marker.targetIndex; - setTimeout(function () { - EasyCoder.timestamp = Date.now(); - program.run(marker.targetPc); - }, 1); - } - return false; - }); - }); - } else { - symbolRecord.onClick = command.pc + 2; - } - break; - case `move`: - symbolRecord.onMove = command.pc + 2; - break; - case `type`: - symbolRecord.onType = command.pc + 2; - break; - case `zoom`: - symbolRecord.onZoom = command.pc + 2; - break; - default: - program.runtimeError(command.lino, `Unknown action '${command.action}'`); - return 0; - } - return command.pc + 1; - } - }, - - Marker: { - - compile: compiler => { - compiler.compileVariable(`gmap`, `marker`); - return true; - }, - - run: program => { - return program[program.pc].pc + 1; - } - }, - - Remove: { - - compile: compiler => { - const lino = compiler.getLino(); - if (compiler.nextTokenIs(`markers`)) { - if (compiler.nextTokenIs(`from`)) { - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.keyword === `gmap`) { - compiler.next(); - compiler.addCommand({ - domain: `gmap`, - keyword: `remove`, - lino, - name: symbolRecord.name - }); - return true; - } - } - } - } - return false; - }, - - run: program => { - const command = program[program.pc]; - const mapRecord = program.getSymbolRecord(command.name); - for (const marker of mapRecord.markers) { - marker.setMap(null); - } - mapRecord.markers = []; - return command.pc + 1; - } - }, - - Set: { - - compile: compiler => { - const lino = compiler.getLino(); - compiler.skip(`the`); - const attribute = compiler.getToken(); - if ([`key`, `latitude`, `longitude`, `type`, `zoom`].includes(attribute)) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.keyword === `gmap`) { - if (compiler.nextTokenIs(`to`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `gmap`, - keyword: `set`, - lino, - name: symbolRecord.name, - attribute, - value - }); - return true; - } - } - } - } - } else if ([`label`, `title`, `position`, `color`].includes(attribute)) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.keyword === `marker`) { - if (compiler.nextTokenIs(`to`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `gmap`, - keyword: `set`, - lino, - name: symbolRecord.name, - attribute, - value - }); - return true; - } - } - } - } - } - return false; - }, - - run: program => { - function pinSymbol(color) { - return { - path: `M 0,0 C -2,-20 -10,-22 -10,-30 A 10,10 0 1,1 10,-30 C 10,-22 2,-20 0,0 z`, - fillColor: color, - fillOpacity: 1, - strokeColor: `#000`, - strokeWeight: 2, - scale: 1, - labelOrigin: new google.maps.Point(0, -28) - }; - } - const command = program[program.pc]; - const symbolRecord = program.getSymbolRecord(command.name); - if ([`key`, `latitude`, `longitude`, `type`, `zoom`].includes(command.attribute)) { - symbolRecord[command.attribute] = program.getValue(command.value); - } else if (command.attribute === `label`) { - symbolRecord.label = program.getValue(command.value); - const marker = symbolRecord.element[symbolRecord.index]; - marker.setLabel(symbolRecord.label); - } else if (command.attribute === `title`) { - symbolRecord.title = program.getValue(command.value); - const marker = symbolRecord.element[symbolRecord.index]; - marker.setTitle(symbolRecord.title); - } else if (command.attribute === `color`) { - symbolRecord.color = program.getValue(command.value); - const marker = symbolRecord.element[symbolRecord.index]; - marker.setIcon(pinSymbol(symbolRecord.color)); - } else if (command.attribute === `position`) { - const value = JSON.parse(program.getValue(command.value)); - symbolRecord.latitude = value.latitude; - symbolRecord.longitude = value.longitude; - const lat = parseFloat(value.latitude); - const lng = parseFloat(value.longitude); - symbolRecord.element[symbolRecord.index].setPosition(new google.maps.LatLng(lat, lng)); - } - return command.pc + 1; - } - }, - - Show: { - - compile: compiler => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - const type = symbolRecord.keyword; - if (type === `gmap`) { - compiler.next(); - compiler.addCommand({ - domain: `gmap`, - keyword: `show`, - lino, - name: symbolRecord.name - }); - return true; - } - } - return false; - }, - - run: program => { - const command = program[program.pc]; - const mapRecord = program.getSymbolRecord(command.name); - if (mapRecord.keyword !== `gmap`) { - return 0; - } - const parentElement = mapRecord.parent.element[mapRecord.parent.index]; - if (typeof EasyCoder_GMap.loaded === `undefined`) { - const script = document.createElement(`script`); - script.src = `https://maps.googleapis.com/maps/api/js?key=${mapRecord.key}`; - script.async = true; - script.defer = true; - script.onload = function () { - EasyCoder_GMap.setupMap(parentElement, mapRecord, program); - program.run(command.pc + 1); - EasyCoder_GMap.loaded = true; - }; - parentElement.insertBefore(script, null); - return 0; - } - EasyCoder_GMap.setupMap(parentElement, mapRecord, program); - return command.pc + 1; - } - }, - - setupMap: (parentElement, mapRecord, program) => { - const lat = parseFloat(mapRecord.latitude); - const lng = parseFloat(mapRecord.longitude); - const zoom = parseFloat(mapRecord.zoom); - mapRecord.map = new google.maps.Map(parentElement, { - center: { - lat, - lng - }, - zoom, - gestureHandling: `greedy` - }); - mapRecord.map.markers = []; - if (mapRecord.type === `hybrid`) { - mapRecord.map.setMapTypeId(google.maps.MapTypeId.SATELLITE); - } - mapRecord.map.addListener(`center_changed`, function () { - program.run(mapRecord.onMove); - }); - mapRecord.map.addListener(`zoom_changed`, function () { - program.run(mapRecord.onZoom); - }); - mapRecord.map.addListener(`maptypeid_changed`, function () { - program.run(mapRecord.onType); - }); - mapRecord.map.addListener(`click`, function (event) { - mapRecord.clickPosition = { - latitude: event.latLng.lat().toString(), - longitude: event.latLng.lng().toString() - }; - program.run(mapRecord.onClick); - }); - }, - - Update: { - - compile: compiler => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.keyword === `gmap`) { - compiler.next(); - compiler.addCommand({ - domain: `gmap`, - keyword: `update`, - lino, - name: symbolRecord.name - }); - return true; - } - } - return false; - }, - - run: program => { - const command = program[program.pc]; - const mapRecord = program.getSymbolRecord(command.name); - mapRecord.map.setCenter(new google.maps.LatLng(mapRecord.latitude, mapRecord.longitude)); - mapRecord.map.setZoom(parseFloat(mapRecord.zoom)); - return command.pc + 1; - } - }, - - getHandler: name => { - switch (name) { - case `create`: - return EasyCoder_GMap.Create; - case `gmap`: - return EasyCoder_GMap.GMap; - case `marker`: - return EasyCoder_GMap.Marker; - case `on`: - return EasyCoder_GMap.On; - case `remove`: - return EasyCoder_GMap.Remove; - case `set`: - return EasyCoder_GMap.Set; - case `show`: - return EasyCoder_GMap.Show; - case `update`: - return EasyCoder_GMap.Update; - default: - return null; - } - }, - - run: program => { - const command = program[program.pc]; - const handler = EasyCoder_GMap.getHandler(command.keyword); - if (!handler) { - program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'gmap' package`); - } - return handler.run(program); - }, - - value: { - - compile: compiler => { - if (compiler.tokenIs(`the`)) { - compiler.next(); - } - const type = compiler.getToken(); - if (type === `click`) { - if (compiler.nextTokenIs(`position`)) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const mapRecord = compiler.getSymbolRecord(); - if (mapRecord.keyword === `gmap`) { - compiler.next(); - return { - domain: `gmap`, - type, - name: mapRecord.name - }; - } - } - } - } - } - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.keyword === `gmap` && [`latitude`, `longitude`, `type`, `zoom`, `bounds`].includes(type) || - symbolRecord.keyword === `marker` && [`latitude`, `longitude`, `title`].includes(type)) { - compiler.next(); - return { - domain: `gmap`, - type, - name: symbolRecord.name - }; - } - } - } - return null; - }, - - get: (program, value) => { - var symbolRecord; - switch (value.type) { - case `latitude`: - symbolRecord = program.getSymbolRecord(value.name); - switch (symbolRecord.keyword) { - case `gmap`: - return { - type: `constant`, - numeric: false, - content: program.getSymbolRecord(value.name).map.getCenter().lat().toString() - }; - case `marker`: - return { - type: `constant`, - numeric: false, - content: program.getSymbolRecord(value.name).marker.getPosition().lat().toString() - }; - } - break; - case `longitude`: - symbolRecord = program.getSymbolRecord(value.name); - switch (symbolRecord.keyword) { - case `gmap`: - return { - type: `constant`, - numeric: false, - content: program.getSymbolRecord(value.name).map.getCenter().lng().toString() - }; - case `marker`: - return { - type: `constant`, - numeric: false, - content: program.getSymbolRecord(value.name).marker.getPosition().lng().toString() - }; - } - break; - case `type`: - return { - type: `constant`, - numeric: false, - content: program.getSymbolRecord(value.name).map.getMapTypeId() - }; - case `zoom`: - return { - type: `constant`, - numeric: false, - content: program.getSymbolRecord(value.name).map.getZoom().toString() - }; - case `bounds`: - const map = program.getSymbolRecord(value.name).map; - const bounds = map ? JSON.stringify(map.getBounds()) : ``; - return { - type: `constant`, - numeric: false, - content: bounds - }; - case `title`: - return { - type: `constant`, - numeric: false, - content: program.getSymbolRecord(value.name).marker.getTitle() - }; - case `click`: - return { - type: `constant`, - numeric: false, - content: JSON.stringify(program.getSymbolRecord(value.name).clickPosition) - }; - } - return null; - } - }, - - condition: { - - compile: () => {}, - - test: () => {} - } -}; diff --git a/easycoder/plugins/json.js b/easycoder/plugins/json.js deleted file mode 100644 index 80ade2a..0000000 --- a/easycoder/plugins/json.js +++ /dev/null @@ -1,510 +0,0 @@ -const EasyCoder_Json = { - - name: `EasyCoder_JSON`, - - Json: { - - compile: (compiler) => { - const lino = compiler.getLino(); - const request = compiler.nextToken(); - let item; - switch (request) { - case `set`: - compiler.next(); - if (compiler.isSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - if (compiler.nextTokenIs(`to`)) { - const type = compiler.nextToken(); - if (`["array","object"]`.includes(type)) { - compiler.next(); - compiler.addCommand({ - domain: `json`, - keyword: `json`, - lino, - request: `setVariable`, - target: targetRecord.name, - type - }); - return true; - } - } - } else if (targetRecord.keyword === `select`) { - if (compiler.nextTokenIs(`from`)) { - compiler.next(); - if (compiler.isSymbol()) { - const sourceRecord = compiler.getSymbolRecord(); - if (sourceRecord.keyword === `variable`) { - var display = null; - if (compiler.nextTokenIs(`as`)) { - display = compiler.getNextValue(); - } - compiler.addCommand({ - domain: `json`, - keyword: `json`, - lino, - request: `setList`, - target: targetRecord.name, - source: sourceRecord.name, - display - }); - return true; - } - } - } - } - break; - } - break; - case `sort`: - case `shuffle`: - case `format`: - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - compiler.next(); - compiler.addCommand({ - domain: `json`, - keyword: `json`, - lino, - request, - target: targetRecord.name - }); - return true; - } - } - break; - case `parse`: - if (compiler.nextTokenIs(`url`)) { - const source = compiler.getNextValue(); - if (compiler.tokenIs(`as`)) { - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - compiler.next(); - compiler.addCommand({ - domain: `json`, - keyword: `json`, - lino, - request, - source, - target: targetRecord.name - }); - return true; - } - } - } - } - break; - case `delete`: - const what = compiler.nextToken(); - if ([`property`, `element`].includes(what)) { - const value = compiler.getNextValue(); - if ([`from`, `of`].includes(compiler.getToken())) { - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - compiler.next(); - compiler.addCommand({ - domain: `json`, - keyword: `json`, - lino, - request, - what, - value, - target: targetRecord.name - }); - return true; - } - } - } - } - break; - case `rename`: - const oldName = compiler.getNextValue(); - if (compiler.tokenIs(`to`)) { - const newName = compiler.getNextValue(); - if (compiler.tokenIs(`in`)) { - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - compiler.next(); - compiler.addCommand({ - domain: `json`, - keyword: `json`, - lino, - request, - oldName, - newName, - target: targetRecord.name - }); - return true; - } - } - } - } - break; - case `add`: - item = compiler.getNextValue(); - if (compiler.tokenIs(`to`)) { - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - compiler.next(); - compiler.addCommand({ - domain: `json`, - keyword: `json`, - lino, - request, - item, - target: targetRecord.name - }); - return true; - } - } - } - break; - case `split`: - item = compiler.getNextValue(); - let on = `\n`; - if (compiler.tokenIs(`on`)) { - on = compiler.getNextValue(); - } - if ([`giving`, `into`].includes(compiler.getToken())) { - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - compiler.next(); - compiler.addCommand({ - domain: `json`, - keyword: `json`, - lino, - request, - item, - on, - target: targetRecord.name - }); - return true; - } - } - } - break; - case `replace`: - if (compiler.nextTokenIs(`element`)) { - const index = compiler.getNextValue(); - if (compiler.tokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - if ([`by`, `with`].includes(compiler.nextToken())) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `json`, - keyword: `json`, - lino, - request, - target: targetRecord.name, - index, - value - }); - return true; - } - } - } - } - } - break; - } - compiler.addWarning(`Unrecognised json command syntax`); - return false; - }, - - run: (program) => { - const command = program[program.pc]; - let sourceRecord; - let targetRecord; - let record; - let content; - let array; - switch (command.request) { - case `setVariable`: - targetRecord = program.getSymbolRecord(command.target); - content = (command.type === `array`) ? `[]` : `{}`; - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content - }; - break; - case `setList`: - // The source is assumed to be a JSON array - sourceRecord = program.getSymbolRecord(command.source); - const sourceData = program.getValue(sourceRecord.value[sourceRecord.index]); - var itemArray = ``; - try { - itemArray = JSON.parse(sourceData); - } catch (err) { - program.runtimeError(command.lino, `Can't parse JSON`); - return 0; - } - // The target is assumed to be a SELECT - targetRecord = program.getSymbolRecord(command.target); - const target = targetRecord.element[targetRecord.index]; - target.options.length = 0; - // Get the name of the display field - const display = program.getValue(command.display); - // For each item, set the title and inner HTML - itemArray.forEach(function (item) { - const title = display ? program.decode(item[display]) : null; - const opt = document.createElement(`option`); - const innerHTML = title ? title : item; - opt.innerHTML = innerHTML; - const value = title ? JSON.stringify(item) : item; - opt.value = value; - target.appendChild(opt); - }); - target.selectedIndex = -1; - break; - case `sort`: - targetRecord = program.getSymbolRecord(command.target); - const list = program.getValue(targetRecord.value[targetRecord.index]); - content = list ? JSON.stringify(JSON.parse(list).sort()) : null; - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content - }; - break; - case `shuffle`: - targetRecord = program.getSymbolRecord(command.target); - array = JSON.parse(program.getValue(targetRecord.value[targetRecord.index])); - for (let i = array.length - 1; i > 0; i--) { - const j = Math.floor(Math.random() * (i + 1)); - [array[i], array[j]] = [array[j], array[i]]; - } - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content: JSON.stringify(array) - }; - break; - case `format`: - targetRecord = program.getSymbolRecord(command.target); - const val = JSON.parse(program.getValue(targetRecord.value[targetRecord.index])); - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content: JSON.stringify(val, null, 2) - }; - break; - case `parse`: - var source = program.getValue(command.source); - targetRecord = program.getSymbolRecord(command.target); - content = { - url: source - }; - var n = source.indexOf(`://`); - if (n >= 0) { - n += 3; - content.protocol = source.substr(0, n); - source = source.substr(n); - } - n = source.indexOf(`?`); - if (n > 0) { - content.domain = source.substr(0, n); - content.arg = source.substr(n + 1); - } else { - content.domain = source; - } - if (content.domain.endsWith(`/`)) { - content.domain = content.domain.substr(0, content.domain.length - 1); - } - n = content.domain.indexOf(`/`); - if (n > 0) { - content.path = content.domain.substr(n + 1); - content.domain = content.domain.substr(0, n); - } - else { - content.path = ``; - } - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content: JSON.stringify(content, null, 2) - }; - break; - case `delete`: - switch (command.what) { - case `property`: - const name = program.getValue(command.value); - targetRecord = program.getSymbolRecord(command.target); - record = JSON.parse(targetRecord.value[targetRecord.index].content); - delete record[name]; - targetRecord.value[targetRecord.index].content = JSON.stringify(record); - break; - case `element`: - const element = program.getValue(command.value); - targetRecord = program.getSymbolRecord(command.target); - record = JSON.parse(targetRecord.value[targetRecord.index].content); - record.splice(element, 1); - targetRecord.value[targetRecord.index].content = JSON.stringify(record); - break; - } - break; - case `rename`: - const oldName = program.getValue(command.oldName); - const newName = program.getValue(command.newName); - targetRecord = program.getSymbolRecord(command.target); - record = JSON.parse(targetRecord.value[targetRecord.index].content); - content = record[oldName]; - delete record[oldName]; - record[newName] = content; - targetRecord.value[targetRecord.index].content = JSON.stringify(record); - break; - case `add`: - content = program.getValue(command.item); - targetRecord = program.getSymbolRecord(command.target); - const existing = targetRecord.value[targetRecord.index].content; - record = existing ? JSON.parse(existing) : []; - record.push((`[`, `{`).includes(content[0]) ? JSON.parse(content) :content); - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content: JSON.stringify(record) - }; - break; - case `split`: - content = program.getValue(command.item); - const on = program.getValue(command.on); - targetRecord = program.getSymbolRecord(command.target); - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content: JSON.stringify(content.split(on)) - }; - break; - case `replace`: - targetRecord = program.getSymbolRecord(command.target); - const index = program.getValue(command.index); - const value = program.getValue(command.value); - const current = targetRecord.value[targetRecord.index].content; - record = current ? JSON.parse(current) : []; - if (index > record.length - 1) { - program.runtimeError(command.lino, `Index out of range`); - } - record[index] = value; - targetRecord.value[targetRecord.index].content = JSON.stringify(record); - break; - } - return command.pc + 1; - } - }, - - getHandler: (name) => { - switch (name) { - case `json`: - return EasyCoder_Json.Json; - default: - return null; - } - }, - - run: (program) => { - const command = program[program.pc]; - const handler = EasyCoder_Json.getHandler(command.keyword); - if (!handler) { - program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'json' package`); - } - return handler.run(program); - }, - - value: { - - compile: (compiler) => { - if (compiler.tokenIs(`the`)) { - compiler.next(); - } - if (compiler.tokenIs(`json`)) { - const type = compiler.nextToken(); - if ([`size`, `count`, `keys`].includes(type)) { - compiler.skip(`of`); - if (compiler.isSymbol()) { - const target = compiler.getSymbolRecord(); - compiler.next(); - if (target.isVHolder) { - return { - domain: `json`, - type, - name: target.name - }; - } - } - } else if (type === `index`) { - if (compiler.nextTokenIs(`of`)) { - const item = compiler.getNextValue(); - if (compiler.tokenIs(`in`)) { - const list = compiler.getNextValue(); - return { - domain: `json`, - type, - item, - list - }; - } - } - } - } - return null; - }, - - get: (program, value) => { - let symbolRecord; - let data; - let content; - switch (value.type) { - case `size`: - case `count`: - symbolRecord = program.getSymbolRecord(value.name); - data = program.getValue(symbolRecord.value[symbolRecord.index]); - let array; - try { - array = JSON.parse(data); - } catch (err) { - array = []; - } - return { - type: `constant`, - numeric: true, - content: array ? array.length : 0 - }; - case `keys`: - symbolRecord = program.getSymbolRecord(value.name); - data = program.getValue(symbolRecord.value[symbolRecord.index]); - content = data ? JSON.stringify(Object.keys(JSON.parse(data)).sort()) : `[]`; - return { - type: `constant`, - numeric: false, - content - }; - case `index`: - const item = program.getValue(value.item); - const list = JSON.parse(program.getValue(value.list)); - content = list.findIndex(function (value) { - return value === item; - }); - return { - type: `constant`, - numeric: true, - content - }; - } - } - }, - - condition: { - - compile: () => {}, - - test: () => {} - } -}; diff --git a/easycoder/plugins/rest.js b/easycoder/plugins/rest.js deleted file mode 100644 index 3974890..0000000 --- a/easycoder/plugins/rest.js +++ /dev/null @@ -1,216 +0,0 @@ -const EasyCoder_Rest = { - - name: `EasyCoder_Rest`, - - Rest: { - - compile: (compiler) => { - const lino = compiler.getLino(); - const request = compiler.nextToken(); - switch (request) { - case `get`: - if (compiler.nextIsSymbol(true)) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.keyword === `variable`) { - if (compiler.nextTokenIs(`from`)) { - const url = compiler.getNextValue(); - let fixup = compiler.getPc(); - compiler.addCommand({ - domain: `rest`, - keyword: `rest`, - lino, - request: `get`, - target: targetRecord.name, - url, - onError: null - }); - if (compiler.tokenIs(`or`)) { - compiler.next(); - compiler.getCommandAt(fixup).onError = compiler.getPc() + 1; - compiler.completeHandler(); - } - return true; - } - } - } - break; - case `post`: - let value = null; - if (compiler.nextTokenIs(`to`)) { - compiler.next(); - } else { - value = compiler.getValue(); - if (compiler.tokenIs(`to`)) { - compiler.next(); - } else { - break; - } - } - const url = compiler.getValue(); - if (!url) { - throw new Error(command.lino, `No URL present`); - } - let target = null; - if (compiler.tokenIs(`giving`)) { - if (compiler.nextIsSymbol()) { - const targetRecord = compiler.getSymbolRecord(); - if (targetRecord.isVHolder) { - target = targetRecord.name; - compiler.next(); - } else { - throw new Error(`'${targetRecord.name}' cannot hold a value`); - } - } - } - compiler.addCommand({ - domain: `rest`, - keyword: `rest`, - lino, - request: `post`, - value, - url, - target, - onError: compiler.getPc() + 2 - }); - onError = null; - if (compiler.tokenIs(`or`)) { - compiler.next(); - // onError = compiler.getPc() + 1; - compiler.completeHandler(); - } - return true; - } - return false; - }, - - createCORSRequest: (method, url) => { - var xhr = new XMLHttpRequest(); - if (`withCredentials` in xhr) { - - // Check if the XMLHttpRequest object has a "withCredentials" property. - // "withCredentials" only exists on XMLHTTPRequest2 objects. - xhr.open(method, url, true); - - } else if (typeof XDomainRequest != `undefined`) { - - // Otherwise, check if XDomainRequest. - // XDomainRequest only exists in IE, and is IE's way of making CORS requests. - xhr = new XDomainRequest(); - xhr.open(method, url); - - } else { - - // Otherwise, CORS is not supported by the browser. - xhr = null; - - } - return xhr; - }, - - run: (program) => { - const command = program[program.pc]; - const url = program.getValue(command.url); - const rest = EasyCoder_Plugins.rest(); - const path = url.startsWith(`http`) ? url - : url[0] === `/` ? url.substr(1) - : `${window.location.origin}${rest ? `/${rest}` : ``}/${url}`; - - const request = EasyCoder_Rest.Rest.createCORSRequest(command.request, path); - if (!request) { - program.runtimeError(command.lino, `CORS not supported`); - return; - } - request.script = program.script; - request.pc = program.pc; - - request.onload = function () { - let s = request.script; - let p = EasyCoder.scripts[s]; - let pc = request.pc; - let c = p[pc]; - if (200 <= request.status && request.status < 400) { - var content = request.responseText.trim(); - if (c.target) { - const targetRecord = program.getSymbolRecord(command.target); - targetRecord.value[targetRecord.index] = { - type: `constant`, - numeric: false, - content - }; - targetRecord.used = true; - } - p.run(c.pc + 1); - } else { - const error = `${request.status} ${request.statusText}`; - if (c.onError) { - p.errorMessage = `Exception trapped: ${error}`; - p.run(c.onError); - } else { - p.runtimeError(c.lino, `Error: ${error}`); - } - } - }; - - request.onerror = function () { - if (command.onError) { - program.errorMessage = this.responseText; - program.run(command.onError); - } else { - const error = this.responseText; - program.runtimeError(command.lino, error); - } - }; - - switch (command.request) { - case `get`: - // console.log(`GET from ${path}`); - request.send(); - break; - case `post`: - const value = program.getValue(command.value); - console.log(`POST to ${path}`); - //console.log(`value=${value}`); - request.setRequestHeader(`Content-type`, `application/json; charset=UTF-8`); - request.send(value); - break; - } - return 0; - } - }, - - getHandler: (name) => { - switch (name) { - case `rest`: - return EasyCoder_Rest.Rest; - default: - return null; - } - }, - - run: (program) => { - const command = program[program.pc]; - const handler = EasyCoder_Rest.getHandler(command.keyword); - if (!handler) { - program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'rest' package`); - } - return handler.run(program); - }, - - value: { - - compile: () => { - return null; - }, - - get: () => { - return null; - } - }, - - condition: { - - compile: () => {}, - - test: () => {} - } -}; diff --git a/easycoder/plugins/showdown.js b/easycoder/plugins/showdown.js deleted file mode 100644 index 180e1b1..0000000 --- a/easycoder/plugins/showdown.js +++ /dev/null @@ -1,121 +0,0 @@ -const EasyCoder_Showdown = { - - name: `EasyCoder_Showdown`, - - Load: { - - compile: compiler => { - const lino = compiler.getLino(); - if (compiler.nextTokenIs(`showdown`)) { - compiler.next(); - compiler.addCommand({ - domain: `showdown`, - keyword: `load`, - lino - }); - return true; - } - return false; - }, - - run: program => { - const command = program[program.pc]; - if (program.isUndefined(this.showdown_loaded)) { - program.require(`js`, `https://unpkg.com/showdown@1.9.1/./dist/showdown.js`, function () { - this.showdown_loaded = true; - EasyCoder_Showdown.setupExtension(); - program.run(command.pc + 1); - }); - } - else { - EasyCoder_Showdown.setupExtension(); - return command.pc + 1; - } - return 0; - } - }, - - setupExtension: () => { - showdown.extension(`Extension`, { - type: `lang`, - filter: function (text, converter) { - const callback = program.getSymbolRecord(converter.callback); - return text.replace(/~([^~]+)~/g, function (match, group) { - callback.payload = group; - program.run(callback.cb); - return callback.payload; - }); - } - }); - }, - - getHandler: (name) => { - switch (name) { - case `load`: - return EasyCoder_Showdown.Load; - default: - return null; - } - }, - - run: program => { - const command = program[program.pc]; - const handler = EasyCoder_Showdown.getHandler(command.keyword); - if (!handler) { - program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'showdown' package`); - } - return handler.run(program); - }, - - value: { - - compile: compiler => { - if (compiler.tokenIs(`showdown`)) { - if (compiler.nextTokenIs(`decode`)) { - const value = compiler.getNextValue(); - let callback = null; - if (compiler.tokenIs(`with`)) { - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.keyword === `callback`) { - callback = symbolRecord.name; - compiler.next(); - } - } - } - return { - domain: `showdown`, - type: `decode`, - value, - callback - }; - } - } - return null; - }, - - get: (program, value) => { - const converter = new showdown.Converter({ - extensions: [`Extension`] - }); - switch (value.type) { - case `decode`: - converter.callback = value.callback; - const markdown = program.getValue(value.value); - const content = converter.makeHtml(markdown); - return { - type: `constant`, - numeric: false, - content - }; - } - } - }, - - condition: { - - compile: () => {}, - - test: () => {} - } -}; diff --git a/easycoder/plugins/svg.js b/easycoder/plugins/svg.js deleted file mode 100644 index 09fbe57..0000000 --- a/easycoder/plugins/svg.js +++ /dev/null @@ -1,618 +0,0 @@ -const EasyCoder_SVG = { - - name: `EasyCoder_SVG`, - - Circle: { - - compile: (compiler) => { - compiler.compileVariable(`svg`, `circle`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Create: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - compiler.next(); - switch (symbolRecord.keyword) { - case `svg`: - if (compiler.tokenIs(`in`)) { - if (compiler.nextIsSymbol()) { - const parent = compiler.getToken(); - compiler.next(); - var style = null; - var flag = true; - while (flag) { - const token = compiler.getToken(); - compiler.next(); - switch (token) { - case `style`: - style = compiler.getValue(); - break; - default: - compiler.prev(); - flag = false; - break; - } - } - if (!style) { - style = { - type: `constant`, - numeric: false, - content: `width:100%;height:100%` - }; - } - compiler.addCommand({ - domain: `svg`, - keyword: `create`, - lino, - type: `svg`, - name: symbolRecord.name, - style, - parent - }); - return true; - } - } - break; - case `group`: - if (compiler.tokenIs(`in`)) { - if (compiler.nextIsSymbol()) { - const parentRecord = compiler.getSymbolRecord(); - if (![`svg`, `group`].includes(parentRecord.keyword)) { - throw new Error(`Inappropriate type '${parentRecord.keyword}'`); - } - compiler.next(); - compiler.addCommand({ - domain: `svg`, - keyword: `create`, - lino, - type: `group`, - name: symbolRecord.name, - parent: parentRecord.name - }); - return true; - } - } - break; - case `circle`: - case `ellipse`: - case `line`: - case `rect`: - case `svgtext`: - if (compiler.tokenIs(`in`)) { - if (compiler.nextIsSymbol()) { - const parentRecord = compiler.getSymbolRecord(); - if (![`svg`, `group`].includes(parentRecord.keyword)) { - throw new Error(`Inappropriate type '${parentRecord.keyword}'`); - } - compiler.next(); - var text; - flag = true; - while (flag) { - const token = compiler.getToken(); - compiler.next(); - switch (token) { - case `style`: - style = compiler.getValue(); - break; - case `text`: - text = compiler.getValue(); - break; - default: - compiler.prev(); - flag = false; - break; - } - } - compiler.addCommand({ - domain: `svg`, - keyword: `create`, - lino, - type: symbolRecord.keyword === `svgtext` ? `text` : symbolRecord.keyword, - name: symbolRecord.name, - style, - text, - parent: parentRecord.name - }); - return true; - } - } - break; - } - } - return false; - }, - - run: (program) => { - const ns = `http://www.w3.org/2000/svg`; - const command = program[program.pc]; - var parentRecord = program.getSymbolRecord(command.parent); - var group; - const symbolRecord = program.getSymbolRecord(command.name); - if (command.type === `group`) { - symbolRecord.parent = command.parent; - symbolRecord.x = 0; - symbolRecord.y = 0; - } else { - if (parentRecord.keyword === `group`) { - group = parentRecord; - // Add this element to the group - const groupElement = group.value[group.index]; - if (!groupElement.content) { - groupElement.content = []; - } - groupElement.content.push({ - name: symbolRecord.name, - index: symbolRecord.index - }); - // Find the real parent - while (parentRecord.keyword === `group`) { - parentRecord = program.getSymbolRecord(parentRecord.parent); - } - } - const container = parentRecord.element[parentRecord.index]; - const element = document.createElementNS(ns, command.type); - symbolRecord.element[symbolRecord.index] = element; - container.appendChild(element); - // Set the id - const id = `ec-` + symbolRecord.name + `-` + symbolRecord.index; - element.setAttribute(`id`, id); - if (symbolRecord.keyword === `svgtext`) { - element.textContent = program.value.evaluate(program, command.text).content; - } - symbolRecord.value[symbolRecord.index] = { - type: `constant`, - numeric: false, - content: id - }; - if (command.style) { - const style = program.value.evaluate(program, command.style).content; - program.domain.browser.setStyles(id, style); - // Store the location of this shape - const value = symbolRecord.value[symbolRecord.index]; - switch (symbolRecord.keyword) { - case `circle`: - case `ellipse`: - value.x = element.getAttribute(`cx`); - value.y = element.getAttribute(`cy`); - break; - case `line`: - value.x = element.getAttribute(`x1`); - value.y = element.getAttribute(`y1`); - value.x2 = element.getAttribute(`x2`); - value.y2 = element.getAttribute(`y2`); - break; - case `rect`: - case `svgtext`: - value.x = element.getAttribute(`x`); - value.y = element.getAttribute(`y`); - break; - } - if (group) { - // Record the group name and index - value.groupName = group.name; - value.groupIndex = group.index; - } - } - } - return program[program.pc].pc + 1; - } - }, - - Ellipse: { - - compile: (compiler) => { - compiler.compileVariable(`svg`, `ellipse`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Group: { - - compile: (compiler) => { - compiler.compileVariable(`svg`, `group`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Line: { - - compile: (compiler) => { - compiler.compileVariable(`svg`, `line`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Move: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (compiler.nextTokenIs(`to`)) { - const x = compiler.getNextValue(); - const y = compiler.getValue(); - compiler.addCommand({ - domain: `svg`, - keyword: `move`, - lino, - type: `moveTo`, - name: symbolRecord.name, - x, - y - }); - return true; - } - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const newX = program.value.evaluate(program, command.x).content; - const newY = program.value.evaluate(program, command.y).content; - const symbolRecord = program.getSymbolRecord(command.name); - switch (symbolRecord.keyword) { - case `group`: - for (const item of symbolRecord.value[symbolRecord.index].content) { - const itemRecord = program.getSymbolRecord(item.name); - const value = itemRecord.value[item.index]; - const element = document.getElementById(value.content); - const x = parseInt(value.x) + newX; - const y = parseInt(value.y) + newY; - switch (itemRecord.keyword) { - case `circle`: - case `ellipse`: - element.setAttribute(`cx`, x); - element.setAttribute(`cy`, y); - break; - case `line`: - element.setAttribute(`x1`, x); - element.setAttribute(`y1`, y); - element.setAttribute(`x2`, parseInt(value.x2) + newX); - element.setAttribute(`y2`, parseInt(value.y2) + newY); - break; - case `rect`: - case `svgtext`: - element.setAttribute(`x`, x); - element.setAttribute(`y`, y); - break; - } - } - symbolRecord.x = newX; - symbolRecord.y = newY; - break; - case `circle`: - case `ellipse`: - case `line`: - case `rect`: - case `svgtext`: - var px = 0; - var py = 0; - const symRec = symbolRecord.value[symbolRecord.index]; - if (symRec.groupName) { - const parentRecord = program.getSymbolRecord(symRec.groupName); - px = parentRecord.x; - py = parentRecord.y; - } - const symbolValue = symbolRecord.value[symbolRecord.index]; - const element = document.getElementById(symbolRecord.value[symbolRecord.index].content); - switch (symbolRecord.keyword) { - case `circle`: - case `ellipse`: - element.setAttribute(`cx`, px + newX); - element.setAttribute(`cy`, py + newY); - break; - case `line`: - element.setAttribute(`x1`, px + newX); - element.setAttribute(`y1`, py + newY); - const dx = parseInt(symbolValue.x2) - parseInt(symbolValue.x1); - const dy = parseInt(symbolValue.y2) - parseInt(symbolValue.y1); - element.setAttribute(`x2`, px + dx + newX); - element.setAttribute(`y2`, py + dy + newY); - break; - case `rect`: - case `svgtext`: - element.setAttribute(`x`, px + newX); - element.setAttribute(`y`, py + newY); - break; - } - symbolValue.x = newX; - symbolValue.y = newY; - break; - } - return program[program.pc].pc + 1; - } - }, - - On: { - - compile: (compiler) => { - const lino = compiler.getLino(); - const action = compiler.nextToken(); - switch (action) { - case `click`: - if (compiler.nextIsSymbol()) { - const symbol = compiler.getSymbolRecord(); - compiler.next(); - if (symbol.keyword !== `group`) { - return false; - } - compiler.addCommand({ - domain: `svg`, - keyword: `on`, - lino, - action, - symbol: symbol.name - }); - // Add a 'goto' to skip the action - const goto = compiler.getPc(); - compiler.addCommand({ - domain: `core`, - keyword: `goto`, - goto: 0 - }); - // Add the action - compiler.compileOne(); - // Fixup the 'goto' - compiler.getCommandAt(goto).goto = compiler.getPc(); - return true; - } - } - compiler.addWarning(`Unrecognised syntax in 'on'`); - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const targetItem = program.getSymbolRecord(command.symbol); - switch (command.action) { - case `click`: - if (targetItem.keyword === `group`) { - // Iterate the group array - for (const groupValue of targetItem.value) { - if (groupValue.content) { - for (const value of groupValue.content) { - const contentItem = program.getSymbolRecord(value.name); - const contentValue = contentItem.value[value.index]; - if (contentValue.content) { - const target = document.getElementById(contentValue.content); - target.targetPc = command.pc + 2; - target.contentItem = contentItem; - target.contentIndex = value.index; - target.onclick = function (event) { - event.target.blur(); - const contentItem = event.target.contentItem; - contentItem.index = event.target.contentIndex; - const contentValue = contentItem.value[contentItem.index]; - if (contentValue.groupName) { - targetItem.index = contentValue.groupIndex; - // Set the content indices - const group = targetItem.value[targetItem.index]; - for (const gc of group.content) { - const gi = program.getSymbolRecord(gc.name); - gi.index = gc.index; - } - } - try { - program.run(event.target.targetPc); - } catch (err) { - program.reportError(err, program); - } - return false; - }; - } - } - } - } - } - break; - default: - break; - } - return command.pc + 1; - } - }, - - Rect: { - - compile: (compiler) => { - compiler.compileVariable(`svg`, `rect`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Set: { - - compile: (compiler) => { - const lino = compiler.getLino(); - var token = compiler.nextToken(); - if (token === `the`) { - token = compiler.nextToken(); - } - if (token === `text`) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbol = compiler.getSymbolRecord(); - switch (symbol.keyword) { - case `svgtext`: - if (compiler.nextTokenIs(`to`)) { - compiler.next(); - const value = compiler.getValue(); - compiler.addCommand({ - domain: `svg`, - keyword: `set`, - lino, - type: `setText`, - symbolName: symbol.name, - value - }); - return true; - } - break; - default: - break; - } - } - } - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - var symbol; - var value; - var target; - switch (command.type) { - case `setText`: - symbol = program.getSymbolRecord(command.symbolName); - target = document.getElementById(symbol.value[symbol.index].content); - value = program.value.evaluate(program, command.value).content; - switch (symbol.keyword) { - case `svgtext`: - target.innerHTML = value; - break; - default: - break; - } - break; - default: - break; - } - return command.pc + 1; - } - }, - - SVG: { - - compile: (compiler) => { - compiler.compileVariable(`svg`, `svg`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - SVGText: { - - compile: (compiler) => { - compiler.compileVariable(`svg`, `svgtext`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - getHandler: (name) => { - switch (name) { - case `circle`: - return EasyCoder_SVG.Circle; - case `create`: - return EasyCoder_SVG.Create; - case `ellipse`: - return EasyCoder_SVG.Ellipse; - case `group`: - return EasyCoder_SVG.Group; - case `line`: - return EasyCoder_SVG.Line; - case `move`: - return EasyCoder_SVG.Move; - case `on`: - return EasyCoder_SVG.On; - case `rect`: - return EasyCoder_SVG.Rect; - case `set`: - return EasyCoder_SVG.Set; - case `svg`: - return EasyCoder_SVG.SVG; - case `svgtext`: - return EasyCoder_SVG.SVGText; - default: - return null; - } - }, - - run: (program) => { - const command = program[program.pc]; - const handler = EasyCoder_SVG.getHandler(command.keyword); - if (!handler) { - program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'svg' package`); - } - return handler.run(program); - }, - - value: { - - compile: (compiler) => { - if (compiler.tokenIs(`the`)) { - compiler.next(); - } - if (compiler.tokenIs(`text`)) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - compiler.next(); - if (symbolRecord.keyword === `svgtext`) { - return { - domain: `svg`, - type: `svgtext`, - name: symbolRecord.name - }; - } - } - } - } - return null; - }, - - get: (program, value) => { - switch (value.type) { - case `svgtext`: - const symbolRecord = program.getSymbolRecord(value.name); - // console.log('symbolRecord: ' + JSON.stringify(symbolRecord.value[symbolRecord.index], null, 2)); - const element = document.getElementById(symbolRecord.value[symbolRecord.index].content); - return { - type: `constant`, - numeric: false, - content: element.innerHTML - }; - } - } - }, - - condition: { - - compile: () => {}, - - test: () => {} - } -}; diff --git a/easycoder/plugins/ui.js b/easycoder/plugins/ui.js deleted file mode 100644 index 17d8297..0000000 --- a/easycoder/plugins/ui.js +++ /dev/null @@ -1,370 +0,0 @@ -const EasyCoder_UI = { - - name: `EasyCoder_UI`, - - monthNames: [ - `January`, - `February`, - `March`, - `April`, - `May`, - `June`, - `July`, - `August`, - `September`, - `October`, - `November`, - `December` - ], - - renderDate: (dateRecord) => { - const date = new Date(dateRecord.timestamp); - const day = date.getDate(); - const month = date.getMonth(); - const year = date.getFullYear(); - - const daysInMonth = [ - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 - ]; - - if (year % 4 === 0) { - daysInMonth[1] = 29; - } - - // Do the day list - const dayList = dateRecord.day; - while (dayList.firstChild) { - dayList.removeChild(dayList.lastChild); - } - for (var i = 0; i < daysInMonth[month]; i++) { - const option = new Option(String(i)); - option.value = i; - option.text = String(i + 1); - dayList.appendChild(option); - } - dayList.selectedIndex = day - 1; - - // Do the month list - const monthList = dateRecord.month; - while (monthList.firstChild) { - monthList.removeChild(monthList.lastChild); - } - EasyCoder_UI.monthNames.forEach(function (month, index) { - const option = document.createElement(`option`); - option.value = index; - option.text = month; - monthList.appendChild(option); - }); - monthList.selectedIndex = month; - - // Do the year list - const yearList = dateRecord.year; - while (yearList.firstChild) { - yearList.removeChild(yearList.lastChild); - } - const yr = new Date().getUTCFullYear(); - var sel = 0; - for (i = 0; i < 10; i++) { - const option = document.createElement(`option`); - var y = yr - i + 1; - option.value = y; - option.text = String(y); - if (y === year) { - sel = i; - } - yearList.appendChild(option); - } - yearList.selectedIndex = sel; - }, - - Create: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - const type = symbolRecord.keyword; - if (type === `date`) { - if (compiler.nextTokenIs(`in`)) { - if (compiler.nextIsSymbol()) { - const holderRecord = compiler.getSymbolRecord(); - compiler.next(); - var second = compiler.constant(-1, true); - var minute = compiler.constant(-1, true); - var hour = compiler.constant(-1, true); - var day = compiler.constant(-1, true); - var month = compiler.constant(-1, true); - var year = compiler.constant(-1, true); - while (true) { - const token = compiler.getToken(); - if (token === `second`) { - second = compiler.getNextValue(); - } else if (token === `minute`) { - minute = compiler.getNextValue(); - } else if (token === `hour`) { - hour = compiler.getNextValue(); - } else if (token === `day`) { - day = compiler.getNextValue(); - } else if (token === `month`) { - month = compiler.getNextValue(); - } else if (token === `year`) { - year = compiler.getNextValue(); - } else { - break; - } - } - compiler.addCommand({ - domain: `ui`, - keyword: `create`, - lino, - type, - date: symbolRecord.name, - holder: holderRecord.name, - day, - month, - year, - hour, - minute, - second, - format: `date` - }); - return true; - } - } - } - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - switch (command.type) { - case `date`: - const dateRecord = program.getSymbolRecord(command.date); - const dayList = document.createElement(`select`); - dayList.id = `ec-day`; - dateRecord.day = dayList; - const monthList = document.createElement(`select`); - dayList.id = `ec-month`; - dateRecord.month = monthList; - const yearList = document.createElement(`select`); - dayList.id = `ec-year`; - dateRecord.year = yearList; - - const holderRecord = program.getSymbolRecord(command.holder); - const holder = holderRecord.element[holderRecord.index]; - while (holder.firstChild) { - holder.removeChild(holder.lastChild); - } - holder.appendChild(dayList); - holder.appendChild(monthList); - holder.appendChild(yearList); - - // Get the requested values - var day = program.getValue(command.day); - var month = program.getValue(command.month); - var year = program.getValue(command.year); - const date = new Date(); - if (day !== -1) { - date.setDate(day); - } - if (month !== -1) { - date.setMonth(month); - } - if (year !== -1) { - date.setYear(year); - } - dateRecord.timestamp = date.getTime(); - EasyCoder_UI.renderDate(dateRecord); - - dayList.dateRecord = dateRecord; - monthList.dateRecord = dateRecord; - yearList.dateRecord = dateRecord; - - dayList.onchange = function () { - const date = new Date(this.dateRecord.timestamp); - date.setDate(this.selectedIndex + 1); - this.dateRecord.timestamp = date.getTime(); - EasyCoder_UI.renderDate(this.dateRecord); - }; - - monthList.onchange = function () { - const date = new Date(this.dateRecord.timestamp); - date.setMonth(this.selectedIndex); - this.dateRecord.timestamp = date.getTime(); - EasyCoder_UI.renderDate(this.dateRecord); - }; - - yearList.onchange = function () { - const date = new Date(this.dateRecord.timestamp); - date.setYear(this[this.selectedIndex].value); - this.dateRecord.timestamp = date.getTime(); - EasyCoder_UI.renderDate(this.dateRecord); - }; - break; - } - - return command.pc + 1; - } - }, - - Date: { - - compile: (compiler) => { - compiler.compileVariable(`ui`, `date`); - return true; - }, - - run: (program) => { - const command = program[program.pc]; - command.value = { - type: `constant`, - numeric: true, - content: Date.now() - }; - return command.pc + 1; - } - }, - - Set: { - - compile: (compiler) => { - const lino = compiler.getLino(); - compiler.skip(`the`); - const token = compiler.getToken(); - switch (token) { - case `date`: - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const dateRecord = compiler.getSymbolRecord(); - if (dateRecord.keyword === `date`) { - if (compiler.nextTokenIs(`to`)) { - const timestamp = compiler.getNextValue(); - compiler.addCommand({ - domain: `ui`, - keyword: `set`, - lino, - what: `date`, - date: dateRecord.name, - timestamp - }); - return true; - } - } - } - } - break; - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - switch (command.what) { - case `date`: - const dateRecord = program.getSymbolRecord(command.date); - dateRecord.timestamp = program.getValue(command.timestamp) * 1000; - EasyCoder_UI.renderDate(dateRecord); - break; - } - return command.pc + 1; - } - }, - - getHandler: (name) => { - switch (name) { - case `create`: - return EasyCoder_UI.Create; - case `date`: - return EasyCoder_UI.Date; - case `set`: - return EasyCoder_UI.Set; - default: - return null; - } - }, - - run: (program) => { - const command = program[program.pc]; - const handler = EasyCoder_UI.getHandler(command.keyword); - if (!handler) { - program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'ui' package`); - } - return handler.run(program); - }, - - value: { - - compile: (compiler) => { - if (compiler.isSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.keyword === `date`) { - compiler.next(); - return { - domain: `ui`, - type: `date`, - what: `timestamp`, - value: symbolRecord.name - }; - } - return null; - } - if (compiler.tokenIs(`the`)) { - compiler.next(); - } - const what = compiler.getToken(); - if ([`date`, `timestamp`].includes(what)) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.keyword === `date`) { - compiler.next(); - return { - domain: `ui`, - type: `date`, - what, - value: symbolRecord.name - }; - } - return null; - } - } - return null; - } - // Try other value possibilities - return null; - }, - - get: (program, value) => { - switch (value.type) { - case `date`: - const dateRecord = program.getSymbolRecord(value.value); - const day = dateRecord.day.options[dateRecord.day.selectedIndex].text; - const month = dateRecord.month.options[dateRecord.month.selectedIndex].value; - const year = dateRecord.year.options[dateRecord.year.selectedIndex].value; - const date = new Date(year, month, day, 0, 0, 0, 0); - switch (value.what) { - case `date`: - return { - type: `constant`, - numeric: false, - content: `${day} ${EasyCoder_UI.monthNames[month]} ${year}` - }; - case `timestamp`: - return { - type: `constant`, - numeric: true, - content: date.getTime() / 1000 - }; - } - } - } - }, - - condition: { - - compile: () => {}, - - test: () => {} - } -}; diff --git a/easycoder/plugins/vfx.js b/easycoder/plugins/vfx.js deleted file mode 100644 index f2ff5da..0000000 --- a/easycoder/plugins/vfx.js +++ /dev/null @@ -1,343 +0,0 @@ -const EasyCoder_VFX = { - - name: `EasyCoder_VFX`, - - ANIMATION: { - - compile: (compiler) => { - compiler.compileVariable(`vfx`, `animation`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - Create: { - - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - const keyword = symbolRecord.keyword; - if (keyword == `animation`) { - if (compiler.nextTokenIs(`in`)) { - if (compiler.nextIsSymbol()) { - const parentRecord = compiler.getSymbolRecord(); - compiler.next(); - compiler.addCommand({ - domain: `vfx`, - keyword: `create`, - lino, - name: symbolRecord.name, - parent: parentRecord.name - }); - return true; - } - } - } - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const targetRecord = program.getSymbolRecord(command.name); - const p = command.imported ? EasyCoder.scripts[program.parent] : program; - const parentRecord = p.getSymbolRecord(command.parent); - if (!parentRecord.element[parentRecord.index]) { - program.runtimeError(command.pc, `Element ${parentRecord.name} does not exist.`); - } - let parent = parentRecord.element[parentRecord.index]; - // Create the container - let container = document.createElement(`div`); - targetRecord.element[targetRecord.index] = container; - targetRecord.element[targetRecord.index].id = - `ec-${targetRecord.name}-${targetRecord.index}-${EasyCoder.elementId++}`; - parent.appendChild(container); - container.style[`position`] = `relative`; - container.style[`overflow`] = `hidden`; - if (typeof targetRecord.animation === `undefined`) { - targetRecord.animation = []; - for (let n = 0; n < targetRecord.elements; n++) { - targetRecord.animation.push({}); - } - } - const image = document.createElement(`img`); - targetRecord.animation[targetRecord.index].image = image; - container.appendChild(image); - image.style[`display`] = `none`; - image.style[`position`] = `absolute`; - image.style[`max-width`] = `none`; - return command.pc + 1; - } - }, - - On: { - - compile: compiler => { - const lino = compiler.getLino(); - const action = compiler.nextToken(); - switch (action) { - case `trigger`: - if (compiler.nextIsSymbol()) { - let symbolRecord = compiler.getSymbolRecord(); - if (symbolRecord.keyword === `animation`) { - compiler.next(); - compiler.addCommand({ - domain: `vfx`, - keyword: `on`, - lino, - action, - target:symbolRecord.name - }); - return compiler.completeHandler(); - } - break; - } - } - return false; - }, - - run: program => { - const command = program[program.pc]; - const cb = command.pc + 2; - const symbolRecord = program.getSymbolRecord(command.target); - switch (command.action) { - case `trigger`: - symbolRecord.onTrigger = cb; - break; - default: - program.runtimeError(command.lino, `Unknown action '${command.action}'`); - return 0; - } - return command.pc + 1; - } - }, - - Set: { - - compile: (compiler) => { - const lino = compiler.getLino(); - let type = compiler.nextToken(); - if (compiler.tokenIs(`the`)) { - type = compiler.nextToken(); - } - if ([`url`, `specification`, `spec`, `opacity`].includes(type)) { - if (compiler.nextTokenIs(`of`)) { - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - if (compiler.nextTokenIs(`to`)) { - const value = compiler.getNextValue(); - compiler.addCommand({ - domain: `vfx`, - keyword: `set`, - lino, - target: symbolRecord.name, - type, - value - }); - return true; - } - } - } - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - let targetRecord = program.getSymbolRecord(command.target); - let container = targetRecord.element[targetRecord.index]; - let animation; - switch (command.type) { - case `url`: - let url = program.getValue(command.value); - animation.image.setAttribute(`src`, url); - break; - case `specification`: - case `spec`: - animation = targetRecord.animation[targetRecord.index]; - let spec = JSON.parse(program.getValue(command.value)); - animation.spec = spec; - animation.step = spec.steps; - if (['panzoom'].includes(spec.type)) { - container.style.width = spec.width; - container.style.height = spec.height; - let width = container.getBoundingClientRect().width; - let height = container.getBoundingClientRect().height; - animation.widthS = width * 100 / spec.start.width; - let zoomS = animation.widthS / width; - let heightS = height * zoomS; - animation.leftS = width * zoomS * spec.start.left / 100; - animation.topS = height * zoomS * spec.start.top / 100; - animation.widthF = width * 100 / spec.finish.width; - let zoomF = animation.widthF / width; - let heightF = height * zoomF; - animation.leftF = width * zoomF * spec.finish.left / 100; - animation.topF = height * zoomF * spec.finish.top / 100; - - if (spec.start.width > 100) { - throw new Error(`Start width too great for item ${targetRecord.index}`); - } - if (spec.finish.width > 100) { - throw new Error(`Finish width too great for item ${targetRecord.index}`); - } - if (animation.widthS - animation.leftS < width) { - throw new Error(`Insufficient start width for item ${targetRecord.index}`); - } - if (heightS - animation.topS < height) { - throw new Error(`Insufficient start height for item ${targetRecord.index}`); - } - if (animation.widthF - animation.leftF < width) { - throw new Error(`Insufficient finish width for item ${targetRecord.index}`); - } - if (heightF - animation.topF < height) { - throw new Error(`Insufficient finish height for item ${targetRecord.index}`); - } - animation.left = animation.leftS; - animation.top = animation.topS; - animation.width = animation.widthS; - let image = animation.image; - image.style.left = `-${animation.left}px`; - image.style.top = `-${animation.top}px`; - image.style.width = `${animation.width}px`; - image.setAttribute(`src`, spec.url); - } else { - program.runtimeError(command.lino, `Unknown animation type '${spec.type}'`); - return 0; - } - case `opacity`: - animation = targetRecord.animation[targetRecord.index]; - let image = animation.image; - image.style.opacity = command.value; - break; - } - return command.pc + 1; - } - }, - - Start: { - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - const keyword = symbolRecord.keyword; - if (keyword == `animation`) { - compiler.next(); - compiler.addCommand({ - domain: `vfx`, - keyword: `start`, - lino, - target: symbolRecord.name - }); - return true; - } - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const targetRecord = program.getSymbolRecord(command.target); - const animation = targetRecord.animation[targetRecord.index]; - animation.step = 0; - animation.left = animation.leftS; - animation.top = animation.topS; - animation.width = animation.widthS; - animation.image.style.display = `inline-block`; - return command.pc + 1; - } - }, - - Step: { - compile: (compiler) => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const symbolRecord = compiler.getSymbolRecord(); - const keyword = symbolRecord.keyword; - if (keyword == `animation`) { - compiler.next(); - compiler.addCommand({ - domain: `vfx`, - keyword: `step`, - lino, - target: symbolRecord.name - }); - return true; - } - } - return false; - }, - - run: (program) => { - const command = program[program.pc]; - const targetRecord = program.getSymbolRecord(command.target); - for (targetRecord.index = 0; targetRecord.index < targetRecord.elements; targetRecord.index++) { - const animation = targetRecord.animation[targetRecord.index]; - if (animation.step < animation.spec.steps) { - animation.step++; - let proportion = parseFloat(animation.step) / animation.spec.steps; - animation.left = animation.leftS + (animation.leftF - animation.leftS) * proportion; - animation.top = animation.topS + (animation.topF - animation.topS) * proportion; - animation.width = animation.widthS + (animation.widthF - animation.widthS) * proportion; - const image = animation.image; - image.style.left = `-${animation.left}px`; - image.style.top = `-${animation.top}px`; - image.style.width = `${animation.width}px`; - if (animation.step === animation.spec.trigger) { - program.run(targetRecord.onTrigger); - } - } - } - return command.pc + 1; - } - }, - - getHandler: (name) => { - switch (name) { - case `animation`: - return EasyCoder_VFX.ANIMATION; - case `create`: - return EasyCoder_VFX.Create; - case `on`: - return EasyCoder_VFX.On; - case `set`: - return EasyCoder_VFX.Set; - case `start`: - return EasyCoder_VFX.Start; - case `step`: - return EasyCoder_VFX.Step; - default: - return null; - } - }, - - run: program => { - const command = program[program.pc]; - const handler = EasyCoder_VFX.getHandler(command.keyword); - if (!handler) { - program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'vfx' package`); - } - return handler.run(program); - }, - - value: { - - compile: () => { - return null; - }, - - get: () => { - return null; - } - }, - - condition: { - - compile: () => {}, - - test: () => {} - } -}; diff --git a/easycoder/plugins/wof.js b/easycoder/plugins/wof.js deleted file mode 100644 index 7904cb6..0000000 --- a/easycoder/plugins/wof.js +++ /dev/null @@ -1,282 +0,0 @@ -// eslint-disable-next-line no-unused-vars -const EasyCoder_WOF = { - - name: `EasyCoder_WOF`, - - /* - A package to draw and manage a roulette wheel. - */ - - Draw: { - - compile: compiler => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const wheelRecord = compiler.getSymbolRecord(); - if (wheelRecord.keyword === `wheel`) { - if (compiler.nextTokenIs(`in`)) { - if (compiler.nextIsSymbol()) { - const canvasRecord = compiler.getSymbolRecord(); - if (canvasRecord.keyword === `canvas`) { - compiler.next(); - compiler.addCommand({ - domain: `wof`, - keyword: `draw`, - lino, - wheel: wheelRecord.name, - canvas: canvasRecord.name - }); - return true; - } - } - } - } - } - return false; - }, - - run: program => { - const command = program[program.pc]; - const wheelRecord = program.getSymbolRecord(command.wheel); - const canvasRecord = program.getSymbolRecord(command.canvas); - const canvas = canvasRecord.element[canvasRecord.index]; - canvas.width = canvas.clientWidth; - canvas.height = canvas.clientHeight; - const wheel = EasyCoder_roulette_wheel; - wheelRecord.wheel = wheel; - wheel.canvas = canvas; - wheel.init(wheel); - wheel.drawRouletteWheel(wheel); - return command.pc + 1; - } - }, - - Spin: { - - compile: compiler => { - const lino = compiler.getLino(); - if (compiler.nextIsSymbol()) { - const wheelRecord = compiler.getSymbolRecord(); - if (wheelRecord.keyword === `wheel`) { - compiler.next(); - compiler.addCommand({ - domain: `wof`, - keyword: `spin`, - lino, - wheel: wheelRecord.name - }); - return true; - } - } - return false; - }, - - run: program => { - const command = program[program.pc]; - const wheelRecord = program.getSymbolRecord(command.wheel); - wheelRecord.wheel.spin(wheelRecord.wheel); - return command.pc + 1; - } - }, - - Wheel: { - - compile: (compiler) => { - compiler.compileVariable(`wof`, `wheel`, false, `dom`); - return true; - }, - - run: (program) => { - return program[program.pc].pc + 1; - } - }, - - getHandler: (name) => { - switch (name) { - case `draw`: - return EasyCoder_WOF.Draw; - case `spin`: - return EasyCoder_WOF.Spin; - case `wheel`: - return EasyCoder_WOF.Wheel; - default: - return null; - } - }, - - run: (program) => { - const command = program[program.pc]; - const handler = EasyCoder_WOF.getHandler(command.keyword); - if (!handler) { - program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'wof' package`); - } - return handler.run(program); - }, - - value: { - - compile: (compiler) => { - if (compiler.tokenIs(`anagrams`)) { - if (compiler.nextTokenIs(`of`)) { - const value = compiler.getNextValue(); - return { - domain: `anagrams`, - type: `getAnagrams`, - value - }; - } - } - return null; - }, - - get: (program, value) => { - switch (value.type) { - case `getAnagrams`: - return { - type: `constant`, - numeric: false, - content: JSON.stringify(AnagramFinder.getAnagrams(program.getValue(value.value), EasyCoder_words)) - }; - } - return null; - } - }, - - condition: { - - compile: () => {} - }, -}; - -// A sample roulette wheel -const EasyCoder_roulette_wheel = { - - init: ($) => { - $.options = [`$100`, `$10`, `$25`, `$250`, `$30`, `$1000`, `$1`, `$200`, `$45`, `$500`, `$5`, `$20`, `Lose`, `$1000000`, `Lose`, `$350`, `$5`, `$99`]; - $.startAngle = 0; - $.arc = Math.PI / ($.options.length / 2); - $.spinTimeout = null; - $.spinArcStart = 10; - $.spinTime = 0; - $.spinTimeTotal = 0; - $.ctx = null; - }, - - byte2Hex: (n) => { - var nybHexString = `0123456789ABCDEF`; - return String(nybHexString.substr((n >> 4) & 0x0F,1)) + nybHexString.substr(n & 0x0F,1); - }, - - RGB2Color: ($,r,g,b) => { - return `#` + $.byte2Hex(r) + $.byte2Hex(g) + $.byte2Hex(b); - }, - - getColor: ($, item, maxitem) => { - var phase = 0; - var center = 128; - var width = 127; - var frequency = Math.PI*2/maxitem; - - var red = Math.sin(frequency*item+2+phase) * width + center; - var green = Math.sin(frequency*item+0+phase) * width + center; - var blue = Math.sin(frequency*item+4+phase) * width + center; - - return $.RGB2Color($,red,green,blue); - }, - - drawRouletteWheel: ($) => { - const canvas = $.canvas; - const width = canvas.width; - const height = canvas.height; - $.width = width; - $.height = height; - if (canvas.getContext) { - var outsideRadius = 200*width/500; - var textRadius = 160*width/500; - var insideRadius = 125*width/500; - - $.ctx = canvas.getContext(`2d`); - $.ctx.clearRect(0,0,width,height); - - $.ctx.strokeStyle = `black`; - $.ctx.lineWidth = 2; - - $.ctx.font = `bold ${12*width/500}px Helvetica, Arial`; - - for(var i = 0; i < $.options.length; i++) { - var angle = $.startAngle + i * $.arc; - //ctx.fillStyle = colors[i]; - $.ctx.fillStyle = $.getColor($, i, $.options.length); - - $.ctx.beginPath(); - $.ctx.arc(width/2, height/2, outsideRadius, angle, angle + $.arc, false); - $.ctx.arc(width/2, height/2, insideRadius, angle + $.arc, angle, true); - $.ctx.stroke(); - $.ctx.fill(); - - $.ctx.save(); - $.ctx.shadowOffsetX = -1; - $.ctx.shadowOffsetY = -1; - $.ctx.shadowBlur = 0; - $.ctx.shadowColor = `rgb(220,220,220)`; - $.ctx.fillStyle = `black`; - $.ctx.translate(width/2 + Math.cos(angle + $.arc / 2) * textRadius, - height/2 + Math.sin(angle + $.arc / 2) * textRadius); - $.ctx.rotate(angle + $.arc / 2 + Math.PI / 2); - var text = $.options[i]; - $.ctx.fillText(text, -$.ctx.measureText(text).width / 2, 0); - $.ctx.restore(); - } - - //Arrow - $.ctx.fillStyle = `black`; - $.ctx.beginPath(); - $.ctx.moveTo(width/2 - 4, height/2 - (outsideRadius + 5)); - $.ctx.lineTo(width/2 + 4, height/2 - (outsideRadius + 5)); - $.ctx.lineTo(width/2 + 4, height/2 - (outsideRadius - 5)); - $.ctx.lineTo(width/2 + 9, height/2 - (outsideRadius - 5)); - $.ctx.lineTo(width/2 + 0, height/2 - (outsideRadius - 13)); - $.ctx.lineTo(width/2 - 9, height/2 - (outsideRadius - 5)); - $.ctx.lineTo(width/2 - 4, height/2 - (outsideRadius - 5)); - $.ctx.lineTo(width/2 - 4, height/2 - (outsideRadius + 5)); - $.ctx.fill(); - } - }, - - easeOut: (t, b, c, d) => { - var ts = (t/=d)*t; - var tc = ts*t; - return b+c*(tc + -3*ts + 3*t); - }, - - stopRotateWheel: ($) => { - clearTimeout($.spinTimeout); - var degrees = $.startAngle * 180 / Math.PI + 90; - var arcd = $.arc * 180 / Math.PI; - var index = Math.floor((360 - degrees % 360) / arcd); - $.ctx.save(); - $.ctx.font = `bold ${30*$.width/500}px Helvetica, Arial`; - var text = $.options[index]; - $.ctx.fillText(text, $.width/2 - $.ctx.measureText(text).width / 2, $.height/2 + 10*$.height/500); - $.ctx.restore(); - }, - - rotateWheel: ($) => { - $.spinTime += 30; - if($.spinTime >= $.spinTimeTotal) { - $.stopRotateWheel($); - return; - } - var spinAngle = $.spinArcStart - $.easeOut($.spinTime, 0, $.spinArcStart, $.spinTimeTotal); - $.startAngle += (spinAngle * Math.PI / 180); - $.drawRouletteWheel($); - $.spinTimeout = setTimeout(function(){ $.rotateWheel($); }, 30); - }, - - spin: ($) => { - $.spinArcStart = Math.random() * 10 + 10; - $.spinTime = 0; - $.spinTimeTotal = Math.random() * 3 + 4 * 1000; - $.rotateWheel($); - } -}; From f873feaa3f02b59a6e037fa8f2e97fc78b31b2a0 Mon Sep 17 00:00:00 2001 From: Graham Trott Date: Mon, 13 Apr 2020 13:31:57 +0100 Subject: [PATCH 4/6] Setting up CDN --- easycoder/easycoder.zip | Bin 232529 -> 0 bytes easycoder/plugins.js | 126 ---------------- server/plugins-sample.js | 110 -------------- server/scripted | 303 --------------------------------------- 4 files changed, 539 deletions(-) delete mode 100644 easycoder/easycoder.zip delete mode 100644 easycoder/plugins.js delete mode 100644 server/plugins-sample.js delete mode 100644 server/scripted diff --git a/easycoder/easycoder.zip b/easycoder/easycoder.zip deleted file mode 100644 index 9e75f1fb8cb3d5a65309325ef35d4a3a499ac2e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 232529 zcmagFV~{9Hvn|-Rx!bmF+qP}nwr$(CZQIsv+uiTnFW%gVb7$hcipq-mQ~9S>MXX%8 zN?r;W1Pb84#-M48{C_t8dw~ML1~4&j@-VV9HgTj=QHBHn-cn4~{jYFwhXw!yIR^#+ z_|GE$PY#rSPC)>On8nD`>|g1dK>`5C5CQ-o{VRu)k)wsZvx)J4axE$)>;6~#k6b+( zHg?;rNI%}6RO;v*to_$fJ8zoe5^xsTUC{HkkstES{Qluo4sI4wg_MfAw?6HAzD(Z8 z6)9_3x{i?6b>#=$PNx{O1dMhbMdK|$kEQ#P%}J01pnXJpQHFMWy=X0k-KI5OD-%vz9I+xB3BVGG!3GEmx2VSGo(S3S#GaG-XwZ34V$luz59+KkqJUt@uCs8|Ey67_{HQCEF3Lf3&(F(ESQX z=tz_3#`{{Mt2G;vcH?eu)U_6UZp9Q*e@^16_m_Qtxac?t zRC;p|tD=I5Y9My_bJ$l37upTQ&oCw~_{n6pAuK8wY#dfJ41=Y85%eKS z5hU*qmJ*4JF?am;h$l>`^E~HdVuwGJiWA#3(ZS4Em4SM9;bF)+DPI=q6WUE_;*nQd z3uPpXp7>k!JDz#E&SoJuv5BCqCtjpYH)D4NmG9EI)G0R7aqTX(`E{mK+BoM$TR!nA zIT2_nIfehEV25ipGRBaG#pb8ma^)v#xtxhr@}NLBu--C!aOsxYIQFVm;je> zYouNAj_54~7Fo5ICut|^sF)@7i!bpj)YP}(Vp?6y>sC#%RZBJm$PyG{?Zetcv=G=) zcWvtK6~nJvA{|>;XSQZO8oEwYQd7_4lM;@>2Y5C7#!5MIv4qs#-4S3ZjVK9Max+D$ zbCfpWr5RhqC%ymqTY)%2#M>Y|t`FNILZX?}Tp$9d!^UBT+TouEs!@y}w?LYe+CW~; z1Lw(H3uu9$xsP|2AjJU#qY;cozzjry_{5nUs62}AnwPB?3OEis9x-l>RU4r5aOO#p z#f-2))IJ6Z-mLrOmbS~Po3@{RQHk<=W?Edc(4=p1o4G&qMrdnk}C zFUxP1+>EZ^+CPK1>=KwbNdx-%$Q zp%S%9p#+-6#OgfmVi>3GJWP^nQ=uN+PvP$zn%s9royd&f^^>E;z3%^l^q=q^&kJhiVMUp8gMd9?BIS{r|aXv)+D>> zJt1I4JZL1)pnP{6_-_jR8cofq7W1m$^Ei_ApUX9+e9uj~FHzUQ^DOsSY%8r$ zW^>KW-&);GON`8*PSKU7JSDu;^G;9kXvSxzP3$zuN|c#rY5Hyji12u~`DeIEN4^&# z6Z%0}n42{vf5535PJms1Lyw6^Ek6vzn4BP4tY`Usqt7zYb1*h;X7$*XYutM3kgoB8 zT^W7Cz#0Dy)~{Ir)}Wz;7c;QxFH|Y^D1qFwdBgB5ZQlL!#i~ED| z5cQdD2#Eqpy57fi1-N#iV#jBF*AC&TIftqNjCUDZcRT{%^7KdicDRBy-6$mE| z4bYSU0vQzr+LY3UK04)sD19Q>Aa8)5b2|HW!4PR98uzKU#i^&=d2W*vNR1C#zJpxw zA?_E$+%UpejgJMt$YvUhQ8VkY#aCZHUW^BdH~BgCfU$Sjq`6@9F0;h24Va7oLY3;^ zEo0#y7sK53rS4)vPC7cZZ~QSz5%T&YC(B=5%dcSR5n=x+L?f>SK|? zbUki**Ewom^C2;O9oFc->YknG&s?-U!SZ;;?or(zj$llcm9L>N=k)66_Pjq&V+W&~ zeGIZ{2vohG8%1q|^yWy;>2~Ip$UQh=-VaKirrT(>`Z~OvY)qXwLGj_gn5<&q4k`4E z2riaj{o$^kF9)KxmHWN<`*()UE){M#(A_&vgbOhdXNw?`aM%CFfnj0Qq7F`oC9yZj z0UIG&!M9HWzL;8g_aZ2iH|ci`J3RJnV1u3&Q{AG^uUV#Q4jtM&wD_lzX)-K+-M7WC z3cUB_#5I2)Tr7<2hF(BaD>-eS`ku|7G=&H3#{&cq19M(cw> zok?+8^*6);qQVoDxjM2ix|V?|z-SbiK{Rm{cP~yijAqLB0CNblZwR;K^#-BGFAo&G zD5*&P!N|X{bpgm^d2IjqzTiBeE@L7YL{wVPj4bIFaFIF}7ZCn{)``d!h|nQ8?|x8- zOl7}!*q|y(3^=*t`xo@zlr4CBQyU%#0N~~yMu++@%4T9j<7ndKOzZ6K{NJq2?f=W# zOq2#}x9DMd&Zr=s;$hXVKSOatYr+6&>Pv7!b2T+fjQ|^uC7rp6#{1%ukBD{XBB&pD z9unl#?$(i>7@klz6az;&14)J3N0@z}Sw>b+zx3-N347pJ6=8M6uSm;D^#Sc{@o)(g zwiSY{IOKb4f-pEAqOF6_BR}Q0Oo6)d1@wZRBNjO7Vbnu*qGJf?gTYGah2M}3znK&z zrEE=u;adZEi;bzo@Iw5AaJdw5;p*qc6Do}}_FqqLy8!!$qCT zSfg<%9SyW43S~v?H$zBwjh+0KQp^yjSP3wR9 z053&Cv+u~H<0xVn0Y_-g*w#-Tc$81^hoQ7v`94sF@9EnJ&?Jrv z3Nw$zM_R{k;zR74MUfkBs==8>-H1h)>fn0i&yG1aA*xY| z-+{m|UdVW?1b*%679v$*X-@aycH&2}9X3=+oq0yB!xkL9iZh$E99zDGDVNtW7?I!? zhCB%Qf}ddC*xmg5y0NkU6==fUb8x}hqAeX1ZNfwcGZSWww0##%bI5_LG~0cN4>KGX zkv`Kso@GzkeHm{SOc;(pZ=!+E{>bBgY|=gE8=>^8GuaePV&RSa=09h2!~v7+FmTA= zb$^q7KQ4EOj|8>CE~|mhh_)vRfEgo9xNQiE=JsSao-&s;=nwxho1?G1rGE! ziNp&v3WxwsJ*i0?Rf7Mi3>L(aA2 zN6g_EiZ$w6A7&}QJ31&H&wt+E9pReAjG;aRdk6vstp7bqpPN;VwBpQZ5O@f#+xnjI z#RIBYG-E$^&)_k73J%m~gB%uVK>&@U*hdcY@lQ%4u=xRMItPpFIi0&$Y^HttQVC`-G%*YNm zvH-&LE6-s#j9+RBXL^bK;5&)^LBQ}D*dOj_BDk!^+BYYnxrK=vFZ-LD{d2$9%i-SB z{p)3=!fVCA%LcM5>0$4T9-j+DftUbc-tj{=tY%Ha63Y2`aajwd$$}n@CME&jR9o5z zj~`0fEGTa`2oP=$hE_KZw?hr0OeVP~law13unf|S{(en-Pb}9zS7(fk*=`Y}L|-5+ zF?sJ!+&rXLxBim37qmwWb3}I}bf3$=AK7-a7c`~kz#tTvQ}zgB=pAEb3B}<6WPdt; z;mF?>X_k!MWJI_lACJINMZo)bhJBXVb$(gOasp&8FDL$_gXccXJ|m5IAFaKP{tN1Z z87NDjM|MD2;yM6}aRj68>^R>r_a7FKWBXu@Fsy2n|Wz-$?`HFEmjIx zsEh#t8+DFrT1Mitt+n465aiGPeLDWb?mXWRfe7Zb<`LwYP_v5K2q)0@rCtYO{_IuZ zYLn3Z3!QC%jg=LO7-9IS_G@3;=mP5rZYK`uJ$I8R=E$S?K7h>&_C3101Sj79LfB3f z6*K;u)$Js1sBf&8LAJw)IIWJn%e)yq#Ff*n+9y z`K4)u1zh8uH!vcLy88nubc`jBe8Cqg=T5Bhs{(fr|Fzj-X$D;o7-v3yh<@&vIY1O4 zZ4kAl5SS=?W@GAutmYL_u(KbwcKfH~BuBop^T-pzF+B**i~)%WFzU(chR#jF&1ahg z`U=RlWZ$7kahI6bUfTHw-VKtR^lhDVHQ61%1670ZxsgAYz9aFWbHWfNWl0bH=Z95k zpFe2^WvC>WQ30q_6Q~YeDK}&fBKg&Cz@VVh*kAAX*B-VDE_7X}-8A!Q4y7BjF7EWC z&qzVB6Q(kLIu{HVTHr7U?^a@e2H(WM9eN0yy@j%!{0>*uDxR1uDC0byl z^5Uuw^0QVW`>N6afv-ar9_A>*oJYyBMYqA5Z5_^Y3A&tbDX~P43ujuK2Jv#p^mgYP z9IT9pzrDH~yQ6LTX^yn`K;Q{!w8jWixw1ElVRdA$CWdy2o=Nj*HsZwd%z^;s*@!@snHLVc>aJM=guE;B~pzEv1ufK_rd z$Y(kk!$X3}(0ifil<2Z->AUeee|BQfXFb%0b-px9$?qGl(5jUOTVdw*3~qI^^L`yY zU75KtyFKrJjthH|oyYYJc3K4vAqxa}S(q95<808JV+#Vb!$bM#-2yh4im?>By*VLH znqruqt0z@{Z7;5t8QKWlZ*^MmMyt`m+W&47w?UOm)LH_CdN50(N9_Bm@qTA_PiZ>^ zS>WVfDygO&Wjn(AYtBmj-Rl7$Yn%gNSLHteO)yGdYwWJL<)*hIvX~@6tM(1$ET}$K zgEb7Oo=lyFG=1V+E4-^gD?DfZc7$6epCTOq{M&fNN*OmsocX)@j}%j(^HU_wan^+@nT0YT{bCaNDXa2v~jwciXC#i zWYD$e^Qt4}i2^;EtU6o23A9H%7Q86>miuzP!l5)3rB44yN)H^^-OYckyd)F(Nf2m*9i85U-b$7bDxx z-r{4Y3Z9k|eht@3>`tTbZutqJ$ymIHGDweHPG<=+ciEX8{%2#JAc%|w2h0Mq?3st1 zx3OznoGZ$%eG%mb9#MkotbS-3Aev?cpF3_4|3m$WLZrL`0WzFZ>X7_MXnB6Mt*eU! z-zERL`vHji1w=(zOkyNkKr147*Q9uC+wA==Eg|)ZcPd0ShJ5B*yLOorv=skj?}f9J zRb#wD1e%h3nK8JXCa$7^-&jG&&7-6_X@NQ@D5W%9PfMj^O{yBCb_{cNl86 z0(_M1WWbp6VKni&+*o+vh~ea>$*u}A5Z3`s&ORvAMM_n5lutt#2F@R07R&BiXDbvxOzPeeV`r zfe~GHOEf?o5cmi4LwggYpk-kE1rKo(!QqtyaFg7plGp=VP!B!k9Nxnw=k(CX118UG zZW)Mt^IEj7)&&a0ZAfW=c`d~DI?(d^C&-1Y!Y!yok4~VM+hj)plkDT3?Jmv-IN3-f z9eYg!r@^P1@DOW-Uhw@`BC?^eq+grm)mgPoBQ!4*G&vU7g-2B)ajyT~PB|XwC`cML z>2%JtvXS#b9t+C1i7B?-o!oG1{A{gHpiq@t4Hj)4W)RWR6|NYQ8XpPK)OI%Oh%M-5 z?hX{BY3{|dEA7JMcvr+jsN(=kxd5%FT|WP_3UG%;-%8 za2PU#nrM^}%MkHL(OW;a@NV2U)qX{C9%TMIJB2mZgDtDYUij_!#l}uhUNzcw`Q=2w z(web+8N=zSa~ji^xpQA^BQZ|BZB4beqTZx=hSj~85{5lbFEW{6YX+Unb;%gK!ZO(1&$8)7I@ zZHN;lDx=~^$(Cd5?r{8N+*w7sU~6`o!QV}(>N>TM`FD{B8%1$xchjh=SNcDdjnk^S zA|GDtpv|=k)qpboR3W7{nbX}J#u$G%9wS-&AL!@a&z+1QNpi zdNs0tog3%qcQ>ElPfjJOa?tlG$1pG%PS_=rZ?vQP$jnMCsBnfXShPAB6t8rvq(yF2 z@x;Z!>fX=ULC{J%WdJL1atPZ|gX{Xj)E*?@N#zY^b`8hSWv-20VZbC3r z+Ag_pB1@{tpar;vW$&4NL?&P zD;^n8GiZI@`w4Og`QAMRjtbyXT0Ag1XNXO?jj)>YiiJ8A6#79H%BXH`gz_3U(Jc#j zS$lafyEeMGsKHQY)|QoD8W6c~RTt&gvy;OKI6|<%xu2W;Q)!sg^@ojmOQhPDn98LtI}D5+yeNWQ@L1Ykep+Y;0EAkb^u85x`}`&_5$GRyq?D1 z5&QT=EDL*(x+Ggxo;F#fgF{sNd!?pnPQ-ekYhwml67Y??zjj0e*CYJNhSAl{uRd`F ziWriX`1~fU6{p0nWalZdrGG-8Q)xl*gupy)Ab++Fq}fLqWu7_*F*bpP{PrA(jY~FE>I50(*V$N;cD<%I*(<+^=eQaS z>e<20Q>_Y}x2yl0=0)057{YGcStJM$HmSVZO@US5AWnPxErawU%Ka-ory8UD;Bwj6 z*w%$|`wfipv$Ao4RdRQA{5EqBsx&lZ0u5t^6Kus7Edp)|o7kxaX7#y67=q)JK50Ph zmhGrgi`IrB-j}FO1-N*TR8xy%;BM3Flk5JH>*JW$l@*q9Pp0S!H&tPe6-Avqzgt*|R=$qON4v*+7J$ zsg!h$%7R3)mRNGGu5*Al?v7lsUo&eLu)uU0dk+&MV&e6ZwG+_4i~rQq^CC1%SAMDu zbl*x+Gje2%u7MzaOVnrfA{5x7xO7oS&DFz2>>Z15idXvGH+<|S#4MgHn z=~FlW^%!*(yyo@+0cuzoL*zt#kLW}gj|x8CMLl#S%-sUiGCL+!8N+Zl zg_=^@#BmV08&RD8Iz!GD#lbp3J(1p(%EH&&wcBLH%n^57N-xE9+#QdM1foywI(|SnveIhet$iXhpoGoKV^q>>kkhK-u(PA5 zPX4OR8irTQl1Hmn55jYCs&*GoqiN*cajkDE+94+ok;(-J?NsSK_tQO(dwS9S7T`q4 z@<$!i#pp;03wmJ7)TxVXz7z;55uMh73Z*b>bMBG|Vaa#sl5^g(XU~I1bZBk$Z|rdp z_v@8>ZD>+{_j#nX^IYo#&P6z8+h1iGC|p;G@yIxGa>6m1gnq-)WXTOvcMw__?;+0) zrJDP#p~a61!(S`7N^f{qy7$~pF4rk#vXc_|PJ$JJZqijIPhedW&_pp7ALPjFw2tjk zVGSOzPnKMT5hwufn%4X@E7_ydrJfK(fa}~Upb!igPS<7g%4s4}X(nl~;ROQlX_Vv;)Ocq-!HfGO6R3pLi2-tD4!F4v-vzB)@5 zD8Gv>tC>_a;Fq%3H*1}C5b8`7nkO@OJyEKLk3PXS9!Q`V!DKCnCzaQvZ4jv>FEE+r zZZ?lzR$>gb0<(Uc1>6(crcKG#;K3RwbZDw2#o8exjTEuu4QG-qg5j1THZooXzF`E)+cnd{Y*Le4X^uHA z;krR>*?ON%y>q&^;O-_Iw}z8j-X1l;LkA)1l_X_$P*t80G_B7$xq`iDir>6iD*3s6 zk17NsMMFSG(`^nf*xtZ(MF+^AJe~Wq-FDfmrVWh{XkS58e|XJSxx7aoSdQk&2BKKl zmwkO#O51gk`chaGOd9yO_kR5TEyWS2Tvnj}BlI?d005x>Tj>3NI{mc&7dmoB%CP+AHEbKD5Ygmx)COa@HKLIe9^Xi z6u(C>$*Pn($q*<_QJsck9V&n_L|G}JOH833iOO@X7)(Qu$O={x(@Ic$0Tol7)&G(N z4HTJ*-nxc;P`a9(X(hagD|mG*doXlEa+S3mVi>3z>-oZ1q z7p|_fMQXJt)L_@H4E9&*ECbI3tO?vSAcg-CJH~+?bSYhHx4qsAX9yBSoiRWJX5s1R z%e3>+;>Ht=%N%UNAPLf z1I4+);ZSB$GZ^SDo6%Jnfgj-KA>0crE<|OWVwgq7a>fY%cxo(tj*LMJy5-@hh@~w@Wu2j|>D{mmFIIF29DqP*rKCKueLz2-I>|3>va|DrtUoyOtNCtSIF@f#jDW;C{annG@e?-;bS$35)CDffW0 zw%cqA4h$Xd2jJg0yU)L58i57?P{slPK=~KW98C<2ZA|{vPx$|Ffz)X1{UiD!`L5{& zTnOzrQ)?(*ebtY_S6mn0aLCL`ZgyR40}Bfh5+dmX$~S(j?X^M26J8&mo}TI=g$)1n z-?Z)BFs7xY9g2Q@r_7`v<4u{?#I$#JW5?9iBnU((X3cbv3zmPsPecqZM90c@>xASu zTRNM_*n4h(Tz++^gIm0OeI;oh?K!{w@l$P~O&OxQy%#$Qs%ci+nd`e_Qkyc(`O#e3 zxE$GOm?tGCYszoqyowvyoamg#NcK+9x?n21w5PT-yD$9ftGvmdq=b9B$#ie$ixl_f51q(7Z<4L=n}o%Amh?c$Zanc@=!F&axwPZ>mRrMe&4#mbSar z(%sW&wd7@_eHkldFwp(RncNzAJyN0FupR}{Y?vw)qaRwW1zD(>Z~e*vR%ShiVwowhntNfcJc7G#S%C6(n1cU)CbmW z(l> z+X`4g>*RHfKy|SI(!FDaA-me7SFl#Z+%SU&*0avU_oV&XDod%2`**rEJ}cHIkzZs+<6&>x6|gLu#T zxn4wgvUPTpgB!pR7EfWQbbO_K>J#+Y0g&tsE-&U$l@N2Ye`Qer9Z# zHq@Mgj{?9yJ3v9kReA-oDXNa!hPC^CJ0OJ}5M}2$Axx^R@ba^z+_l;F12_;Z?CL95 zHDOYBSGojqFe2t9ivVIahKtls9F2k+!8#g&N1DGM2CjFGRmKvxi#F}OX|7f4Aca!p zHhVSlP0_u=v$*p_8=qMtWUXIQheLG;-L8zHGCk6CY7b3!L(2<$39Uf0;Qq4UNy38UwHSe;@PJL#Nw z#w);3Tx;jC@jWaW8^?&@YJOb@V}lA$UT5T52~!aRcoK+;j)#1X;ePm*;>?1-;Uma+ct_K(!=_%1FHB8EJn3uhWZyrp_9kUXxcw_HN0K z*x)f_)fk;tksa_7E>x6K^{(N}C(d~;57{5YCt5TnWQ1X|ghXmwz`&+eN+V$Kmh3H! zl^-fjD!dVp9HTagW>9kf!Zef@z;O0eRj{%9L-c%eS)L%@dnKetnN&<7r1lOhZpsw< zg3P$VAc@n$ayQ7+BftF_8?Fr~pgj;}ED~ZnBVPP@U;6A)EinrZ1#nfX7Uy#Cnt=`c z6UkqnBCE7b`1+8d0SugV&Jl~C9XJ6UnZz3QRl83oC}~sRHx=!UmAsBm(QaZHV-Ajp zOIM1u%$uIzoIrBJ{O8&+QaS}2Ay^sC;LPFbLZT^-g-)TMJqWvZzYQ37Xn<>CTFU@>HCsSQwi?2v#nk$twUA>A5 z!8OTwDjQSW+H`LpxbCnT**Z?9{r;F?OYG`?0T8d$uFEZfJ#(M_RRU{^Aru33<2%kO zi$(b%`_S+E?z-iY_%_e`B^=sFJi_)>+uZ6@*||*+x!v9+^A{mpQX()KL)wqRAYmrC zn*B@PD5d>OzW0Zn@I0Jy-#mT=a8^X^4}zG^DJ%iD^mCWXyO@~D-vbS+3{0kt==VY4 zx4kRUq~;z`1?gF49t2p1rv1?7>x2YV3?8c#g5UIa&#XJb5f3D_T;F<+iw+Nbu!VF@ zu!wz7b1H=*Z2M(m`8%;6KGPI?G@N#i_+?O@Engz+xF+W5u``@o7d5rgrrg=LU-NdJ zCu!{HU4>xCa&ZJ^lZh{_zwXU9MT&+&Nj)vYcn9q8Js6*eKJJ+6xdpgzya{~pNoBb_ zQN6>ExJ&?D_7tZ{=t&jnbE8z#5sw$%l(Y;KJqM+9BX)Mb2?&ui5f9i?T@_9eHGjRN zo2;0-!7-D>*EWtr(sN=37>?eZUou^KR^Yv1TBd`@u*W<67=v5`%?w%nD8t%syou3RknqTy z4H%-X`nhOuinyOSjb|9RZ|N?N;VNmI9Z65?@}zveyk8_eLLc*);wtHFZ_<)~I{@1$ zq^zQ?K47cr!KHjHn<80ydfds(+!^}ff=@-sSAo=a|1t8p2|*_sql3-`Cdf-xy8kw&IlhxG=fiD>kl!LMTrs7H%!!Tk* z4>l9fY2+w`7-}XW1zeD?f}a`fHLTWcm=3_@I7!x1bpDUHnD^pq;~R;+erFD$=k`j) zAt|4H3h(K?c9;ta(M@9M?b`r~0rXP{<%ArO1{~cYSS=S*$;Y2;i-fO~fsA0&Z6mX$ zx}AG+2at8cm4m{hOuh&(GFlqq^s+uerc3r*5_ZWT;O_(QYT@5K!D4KAr1k67Fm^qE zZ`B0FyYBw4d1{~iI9FyDsSm#FDDl=_bJeQGo|}t)u>3&KqOF0&jI$snuAHz#5MaJ( z>@k+TQD&|%9aw3S5RkB1*n;PNp0HE5@rCG()BG&U;+Q{ezSZb1zeUEMpa{^Eq4mW^ zsX!SId%RavH^-dUQW7D7?$o|sX;0Eg<23`#AhY(7KSSkM2TPX)T@p;|5v%$7J+h@jvY0+dNiITcU}3?^OKCl7y)U zLLRrYZovjAhErH}8;w(rjcp_K+Q9n!M8tr!0Gq24U$<*KbTGQa;uNwsz3TY%OG`^T zOLZ3*exw!mJ9Zg))vJ3ad4e%AM+sD8J%x2>`6xC4Dwe=X_0k`uFi^Q)ebeiPrP z$Y&m=oNq$2*5`_daS<+QOWsLiU>PMR(9@jHzvIY%pKv$P_^szUkG^@t0;vEJm`U2| z95WNSCG-H>7w_^6a&x&-zn95E(qEIKQ<-zm@@Q`YiA$4yI=(Zg*_;JSckS7?WQQ;B zUAGv`hrDkMKUngb3n5?u)#ZHk5}q*+cfPu|`09Fld_V6$9)_y)YI%D* zyxSf>XI8+!KWD1gZgus1yx)JW=hod~4eFnS9a$>r38iw8YMSc9V%2 zbtGcjcI}qurgDffb(nkla?T4)KJm4EUXdUfG|MD%@x}9v_E2+L(tzV5GA`rN{natS z&zOI=81Kb3-om+9kim-koo6$B{8wBZ6}h)sT=fds#e1`}@A{r^F?2%7$lmO}vBIbh zwv11M`*k`{pd#Eth2o$yZV#uk$+6$a$bQaYC-^#Of2<%6?%UqWnBNVxODOyq^OD$Q z9f8X+!xvxzf=^Hwhx^)D2w~+n)IpzDCmvX%Q>EIb|8Ujc01)vnxJ}{X940EX>WaSi zV-Li$_W+cll~?5Ca1GdxlZhEP4onw_f;_hO;k_ww0*jb(^hU*L0kG11%wz-T0?%-- zVS%I`J@4!v6Yo-|`K)nqSfnlm*dc$;${o^Y+9@8=C>X5kEt03rX_vWcNi7jN?gA@? zYbIy7CO!Pqzn=aW0bg_Zj&j&@nfU&Ge|>xW^70eB1HD81dE2V7S-j$t{(7x51zrF* z6?qX;xT0eNypDuUqcW~I0*q+N9_Ce2@W32#QfJPc!V5@B9l|)2fCNF?-iyNk9-HHT z0pmsHl8?{>|B2r;IzQwqiKWZH=-gd4OT_H7-i&k(nkP+-SDRlwJjh1g590*q-56NH=lYTmnmpN*gbOKiU zCk_*0*}pVIwauQBWV5I2v8wL!)FGpQS)6mP+B_S}W6?z3u-Lg*gYdquRw>h@oR`K# zHmr1mIF+RzJQD2J-W4uzUC^ZzO8+_?su45@fs@3T)H}g+ygM(MA?3kWlxhxn5rh~z zy*$yWfL9&`YHSm%xHw?z7Xbf`>){9%NL%@ATseLYHWcj=L(GbRpYaT&;evU-Uk##z z8NR)*x0mNJx7#}1-VeLAV>>=m>cBViO4D*s5A_2}#O0eh6*l|fEdSq?H(i!O~)qLlPw%!moPyqwHut^xqlfwwgn>`kqLXSlp z!R~*8U9=)9CS3C^$^`%XMYKs8hiR7*-xjTqSD+@3`yA*MoyjB7P-a4Ac0v@YjPE=I z6M~rkd##q~`uKgBSWr%Y;6(;Vsk_VsPVEeoH*Tq(ErYW52qQ8zb;bIE7a|}W)|@0& zlIo?dVj1%^!EHx|Kb_Ie9VXNYmvMvEr7=~wXSq?Si&~Oq(P(I>ykOCl zU>RMPUNzWp+-1atkZvVzpj{_ugn<$SPKeNr>}d;-2m{z)5+%IuiWQBZ?BmNwMk<`O zwONx%f6Lmh&Q^X>gjtS?!jm-^Z|UEe--bgNziLt{K6fpEoNeQ^9KaE$#^4_*!D0Yt zE5;P0eG;Ia2~3P(s3c$dWU)U_I4;6lUmjm}<;~S>fw;RXf^6xR>mOI{o0l^LJrefK ze7xk(e_0&YP5>V+^W2BT|s4k**tJGU4`l}=+J zLc`Z;GfjZLLnyk4#OCf8vUE*X%puTHkeaUmX}wI(z5p&AU9MkCWByHrmHrVVnaXR# zYaOH%|CtvY=k90nPyOoMp+}=;0(<*3_<(s#^_=fJg$7Ws^iKNYIg@yI1jD1b%mvT@ zsEM+qx#G_?uwkhm5z(Fbh&r%57ZuV7@{$=bAkQ6%L{J2zjIoE(R{8eCnEs?dxWxA?zq4RRxSYYp z{1*GsU8EMG0t@Cnp*+ux!N>RNjvi$5Tru+)J_++zoD&J=X)M+HD9hZGvUmO*Ld)uD zQ{l$om$;-|Dkg_*)eoJjf=wIc$(YTF@o-a+qFK>kv`NcBPvEoiH9#-WXn=7mq<}c020hqzbFX<3gPv zGsW)amsr3!>1+KsVDpX-PpWx{WFhjp`$O2g%|9M`5#@V|C`3ykfv0k|VzOH|)lG-(ep_EKQl({e($FadB#T6Z zZ9UEN1OIz~K42`oOoHhujr1|OI-iLWHeV2lX_5s2 z#T|7d3oWxUrOVfJ}c_?DoMs*FAwLN=!8CSFFSBx)}ERfiM$i81tg@0y|MOe~*g+Ng0Rv zk4P|KXGrgqo_$J1H&szrq4VwU%t`m#zeM`&0c`%cwiS_Ic_wWKuD`U_D;OeEI=)Rr zZ`^c&bBKA!Z|z!QY#U)A#Wtp&B2OHi+@&e3oFFWbPpNZ@TGO+tjux4&54KVHW!Vdx zNmCRsDs_K(CX?MUB)UTN^AWg}VVNjfP5sJK*DR-h?taR=8Z|@5chR0@YbE!=#G6dZ zk&ieT*nvV((16E9jUEA)s^93dwL<(Uz`duU6%M!g9K+F?a;<=< z+hEoAa5@X93J_?!`p0(gEitocsBVuB4N&!Dbe{SULBtyqAP5n4CN}&myssP12-96t zSJP^2Xddx&5QsBkF^R=Xc5gx37*eerA+uP`wN01QOp?^5gqQYKdzL=+nJwmsXRp|; zhZLupyqB8{km1$xuD}XefSlaPYD%#RV61H&VMzq51 z0Z^bW0(?2@8X*81qzPv?a+sC}g(FWw+Jr}`0fpa2v-sxJ9iBwjFaW4usO1086D}=n zK*>0h$fajA!@7+tah4-u!GEN;Y*SD#iSG~oFk}m$*AP1E6bQ`$NAk4lgNm!w^H)I@ zUe_)CD9DQr+I`m{VS_@YLFE^fYYDnzMN81^OU6uXH!jvF~BM zU#BO>rkduvMvD(`ndmQF{r;m%CbE=)1fA=0c%_^&?i#iL}J)<GN;c2xiB;D&Weel+HFps4D0jKRCe*7j@od+lcs3uC-#G4?qvY)(`7W}P z3zzbIM2r=7jb^?FKdVrBNSXwcEm!(_B$-Af61x|eFJT4Uh+9_eiccO^V+2ik186YCPLrMc=CO%o?xmmmSe$y4V22}!b zKAky@>ICzgj$`deKQ*h1KpZ)cdRq$`+LC&ebX?Y;q12#Z9 zkduX-f1)v__;q~n9b(fPcpdi-D%%Hb`v%k+A?%L(1|5dW@`RPsR>tvan+!V^0g=@N zd=H9mHr+7V4M=I#-jF!TqyPDX3pO)>h2pcUT0S_gZ7Ij+i>!wqxfvlcK|_csR}g2UU3>N$D5U9c1yH6FOWt0(k%6%Kq8aiM&{1HV#Y zMxCQ>KW+jlGH6wi!44G}xZGPAD(!J; z>>QaNUPaZfA3XzWxNn=O=2h|vA9eqze$=skNWG&V6+th$c{Iz}%U?+P0c@IxB1Bmh zb2vrjn%@8lK97UOWJS`&fS=I}WNm}CCPg_;$lODUH>?iC350F8lR9l^UUGtz(QMdK z>y`m%8|6oNF0M3=4qv3TN<|DJwZ*jQky*kvgx)iloDm}Z#dq|~$=)nV5;n!HcpqGI zN>OGPPz@*@CjpcNx8%(p9Nx4|_DW1mC1W_3nRQkhs3mSx4$81Aq#7yH`*x%e{I3(| zVUi$k$f{C@yGI3a?8^BeXlzcfwyO!BV+rytCw>VN*gxlO*}*UEl=gNkTDd`v3FXEc z6Oc0H9n^klC#U2C$VBmH?HF(^H|TV~s-dRp%lEuIjIdX7>J2ptc4cv~l5gBip0t=U zb;|ky%vZ>%(IndPMRDXBVE#iUXC>8TD})Kukjw+{q*S!YGPqN-lN{mehWY7)zbSEUe*{IJA6q?*RCS zcUvT__|9M9sZoo^V3HWJOSX)BIv5u{GOc%kbyK?*f*?H_Hv}c8D#>d$TUlaLivH)V zr)esAY(+ad4Q3@6-OmQp1zULmlM2Rs8PG-y&|dvLOJZ?V9!14gnijQ`QEH(N&m&gx zc2wC1MCV~~vx;q^Vhk@r_YU{?OQVN4dg*LMXjyiMM51WikCHhpmWm9ianYE=i9`q3Va@&?N&3#QAmWCEab=L7v^+kPRzTl zxvlMH-|Q_Qen`mtyB$2r61*i^p8WnM=Z+rz*byu-oQ8Jn2>kJGrIn7_uRp0Q6@zP=%Z5!n(^>1gx9fwp@{SRLSwYJ!HOUt`>NWc~$- zQ@$<(|FN;=rX1cJb(fa1TmZAS7mFn?K1e3tNe$54`O*{NL-SehR9Sk%!dnO&?g4;L z{xo2Qztm1-*t@AD{J&wg<#D9jQ4_U1S$CDRUOB*80bd5p+t=%?O2<;v{}3?%jkr^N ziQUMCyNC`g#bSFsQm+I3 z8t>w$P3wQF`_}F@ZY1sR{1tR>BC$s;nzEhjE~&PTV>_{Tli08AWF|+^+3g!IBZ}nk zV#i~1fBTCnRG|Sh&}>rj&TMi{B6e5fjzU$T>ZyNzDArTM&HJAKidAcm5cg02v1qI< zpL6%S`Do;eG`UsW2YEQ`wdb)dcje!G$-4iQ7bn8T4HW7uo!`(8fGW2&UInC?D_y@9 zV{q?@^0|F;u+N?`L9J4rgEMvSYwSNK&Ba^)F@^E9XU`uFYOK;Xlj(G#oYCQjZlD&Q z8+zh;l3g<~{B61zD49%M7=*!6Q8_F5HoK!EtDBumLBvI-hiTb3Pv!>@`M9fEuZ{N*^)3Cvpme^AO8;JtCcZ z_vWh^uL>DU;~~Sa9==Z8_{la*#9sU!LJDk9#M15CON_4-FrBM-v=G-Eb;^a)u_XrD6l)|I_zzLu7lQj*rp zZwy8(xL^?Vm4p7i%V@koz?YZ0WHWUn-yRS znD3qafWjkD@wE7_3|x2cTk&Ti>s|>-^NZCDg;U+DvhEevy-vPh-B38yy)NrsbKQcK zwAb@I`3UJY1%oNtsI0b&o5lKLd$XD30Vl9;W6EpV5NXw_=&D}qKyVfeau6!CK02F< zM7(XRt+thSQ;h$qkf?*{{6n#XT`v9}C#!J)nSkFHOYz{Uwz&-kuiV2pR_rXQ&sBPu zBcR(8O0~_nD$@eeox{e>is%o`z9sKG`gmyoJy2eqU%m^iz51XU7V%#-y#Oan>_D@K zQ+E%n-ut@YY%Mf^z5CeSEw6L7TN%bUPL@fAIGy;nxfB7Vbmy3t3%1#@BkLjeUTxvl zcyd~&4EwBAojI{jqET=qY+eX!$7szMd$Yy3Hyy<&8D=w5joi+Lp4fI+E0V3NTP1VS z)zCK_Vr;~#VZgT@3ZF)dv(F9H&+k-6w`Ox30n_`gg_?#Mj;JzV**B_<-@{fXe@q!Q%ED0535d)k1Nd%1mF&=vf zBFt_5p514R;rCpse$6%lH=}e|rUS?g0Aql?=ocY$f6+{qGjtTNAM3eyQ)N1qE^vH| zumVAK*!Nj2hwDnJp<`G_kx@wfMW)Z=Lb=;)&9mh$ipHY2T+(;?+Tzp@L{JL~qsI9L zWOiQsQx@C-#4)};<~l*m=~r&a(k^K}6}MW}gA{LT&>VH&jExaBcDlW@e|_}L!w3H^ zfyTZUOA|0AL<6I}`&P{c%50gauVKs9iQY0t!`8lrtq*CK zAZyq#K3&T-J_?<#V&NmuJ-r)L6Z z;4vGj0ivVbJ$JI8nnBUL<+wU_6?98xK&QyT2d`|yCytoYD=216ov7A^-d)&)2VP-H^h zo#G==j|?DNfj*$4$`!Fz#vaE{Fj>u|3$Yxw3$&qsFZR}NMY4pjz|-KQgAacapNz$m zGx-poVTED8P>qHMHI3dHQP{dgp6}SJj@@9A*FzAtB*uVIZJ#wA1iV6K^AGz>k0vod z_r!Mo&D{^t?==Oh2*e*(rU>)gNm zd!Bs@*|wa{347&QaxD+F znu`64r4)j7#j;I$-viB-iKHn$2)k5Zhk)F`d6tDQWf8w+WyT@TrK63#?-pWG8PeE8 ziyLJ!V2j(J1)&X@pvcY>6}WkF5`z5}Y?p8)ia8&mH14G5=ih{<=}ErFxsY1gVnsls z=gRQu3FpiKGY26#>d(;2R0S(uW>*KC5>R?$-l1(lf-%uRxi73ZBuLn1eVmJ!_`vsBL24Fk{AEc=FRBWwF88USrb!4A23N=MSXBsv4lpcN!|C zAa5vaA1J4VhH)10J!+N7+Tc;a2WlEySyO8G@b1P_uZ*57^*WrP?;k63o+s&V+tHaZgkThki_*|0bC5qV?C zu+~*ETjBkTK7JNhBsQt;QX2@ociNKA8J9l}KxTQ5CHW*OJ_p=Slm%3iMqr;{=w;c4 z|Mk#zS7Og0h`g`yxu?}xwJf*XqeSFo<7VWaq_`ENk!a=vgruq@E?}NFv~we6<@1r? z66lob1DF{nGXvX3f_EBoTQfaed}Vg7%aPcc_ggDJ%#O1$qsEQFvMVhaRa&BJ^Wz4k zlONE;QTSLZe9K}&R=2U#VM>t?%>SpFTfB-rlT2T@ z4tqQwj6!;9ql3if&wME(DLyT)UvhUV2ucUq5gx`LkWbla+A-0n<;G1?EGO zq>(zdBh|FtJ<;?&G$gb4iEij`SlDAI>pU}7`2I~ghf*GA%5b90!}t7CWu5{}%z~A$ z-LBA#UVWG`rU+yql7bti)^owSE7V0HYr|1oLp0E zIg*uQmg!z8WdI!H4OUG5yXE}Ds#wOK@MH`sFM{Yv#CY|C9AP$;MwGa#Gzr=cPv$pW@2jHsKp$#B2K7 zW?qJ?rJMB{t`#`!X7(O}epCPo|2do#(;Pj}RXm3(0!(TA_xMcx^+5ggQ2q5t{q>Fd z>s$V7a-&^rPi{u)&l!di5DS3>pXx_3D#}>BG9r-h&FI%c{jpTVuZk(Ce*9~ZDC)KJ zDyAQ*@U@r_{cpjw)Tpl24g6-R9pDzGq7Q#Jo#!8A7(Na-N^IF`^)ip;E9HwZsAeks zP7st}dW>tIw4opdkHVrV0%;K&8AFBIXo%q&^7zS_GuKV?Er(0r#OlvYPrwKp*~kAz zl(xnNWNEtQw@s8gg!acoe46V#fDA9i78%VZe}{CAVoS;fwvT1IAUzE*NEh%guT7U<9wcN5UvYe_0g9Jxk-6Ng$Yc7 zT16B`+Git$;`QCfmpPch5rk2}u%w&_=z^m=={MZdIpYyHg$sM1;;2$4A04d0V_i}S zLCY}pe7~F&nl>FQ=8Mgugki!(iqBROCoS(z@-PA<-T4R6vurxau46q3xgsx5MpEwK zOUy4%KUeFI)1sSCR*Px!F&1*hObC@*2Q%N~lewtKgRrvWnBUP@zvA+{C~f^ zdiQ+)nswfPi-Y>RU*5fY_46Us%Y)_?RX=_5^RG|d9#A!%YPYExLP+;U__A4iMR9J* zLS=ZX0e*uT4&re%ml4qHKoK60W@x=k8e%myYErg8I+F&d^QkTy0e6WRi%LnL>=jmo zks&i^=QSZI27#3m4dmuov3&9Frys>j(pL@6Y!Fmf!qfTeeRBzxL<1AnZ9EbB>H>lx zt4@@4DVDrbt)W=Bp;r%qkaMgA*>%@ifP^Clru3~%PQl$ajhqT@Ln-;XI|Rk8mM~wz z*S#d*ySCrO0GH37c%J7$c{j&Tzv?~Ho*KTIAwtQp`nRjaEChaP_{KVj#`isjOwD(7zWs}5V2D#qC?ectVl!i%N2N-Y-qbYBir)4 zYRj_&1nM^HKy6Td(1D;mK5LI3w8szI<45iBH|_Da?eVgWdW`t*sEu5xjVeo9>MHH& zgwU7Ui?+~5+GsH-R;#wuNZO!^wAV7%__Dpu+rYfq%)#11!Egp|C^5 z8feFcm$<=wS%v$2qH61a(+`+*e_M3WKn-RMR~n^861=r{p3@cf#T{0C*}IB37a+uI zg2?>^#`u=loRsm$X&WuKQN{Vq0%zu<6n0Xn<;cc{iK*tGYD&isT!_&SUDQBP_mj}k zbSi$J5Em~A6Y4`tZy zeOEpbN=FwjgYi`gAbv@GbKVxEOyVbAgRFQ5PT z?CtY+2TZgw!ro%Gzkm7T0mg%tH2B`8UNMNPe>gW8LM!fIiD5Z+x5BE5Z5M0kRBcb+ zzk2i2Axj5r^aoBKo(DhNT~aWP8TP_TJ5>XhAiG-6mk5XAQ7Rzs=dDzV5o|Wf{0=|f zQiaNxO=+;;3(zK-%Xdb}Qz3Wwimoy8c#|vh^@flb3d1*tZ$=J)>n?eLcXVFK!YhL# zTjS5b%#PXWA_D|a$j6K5Ca`kv=^bhG?cS`x?#%bNW9+U#Yg9*cu3^tZ7B;<85MS=W zNp>VeS2Dcp2}|+ZpT3(9L9bBi-S?y$w4@9VQ2|iFvt*sX^=A@)+79ygtG}**Wpr*D3QSSD-8l@}r;x?I3HPt(1ko6l#(pnMb-jN}_7mxa)zuHxeI?5cD`|9yFX6iLTv zelmk6Xl3!`aj(B{u-rcrI|5zXr(!5CuS6eZ0>C1s8wiXxAsY6H&d-a1km18b-dGqU zV*P>g{zaOrF)YzqR|5rwn3o&V$3QemG$`1Jb_^%8BG>(XG2f(2P18E4$w{SFui zQ}Paq*|HAF$f1%Y9OiSG(6>eYQYvuvQTpQSfP-{=b{i?^#e+ktd~mBOA0ATW!&?ap zFCHCI=c8M7^P5Ae{N`3wetSrj-`=Xq$!I)<_}DL(ZRVC2M5S~v=CZ)uGs|0$^h2(Y-l~rSX4-Y%$Cu&7mr1ZQ~P0;k>%^@6pc^i)Y@~0<19OBI(o#k#- z@ec=8J91arYFO*fuYWnj^d;}}Z_(W!pM3ZH#{(*s{)V@y`1udde|~mI&C12QJhpHm7kKy^l*Qp(!0ZfjHZMT-T!m7k+G0k zN^1|An!G%Q+couw;}M_8`!9BAMJWw#MhCajos}JvO4I z(BadC-Nwc&ho{5g&6L$WOn0l$HHdLJWRXga1z}PmZK`*mHe;$p)7=K-)li?& zJx$Y&wiD5JP;~9YvIPENvQYDQDbc(lg4*)Jzg~2#8=JeBe`-pUPnJdPiqOV>VQ%r4 z|EG4As*i$dmWhgN$(LGog*#Z%o{?;L5iy_bbEE0GY2Y(P3Lnm#;(Y6=!sTMtk4twM zP|}_!5c|&!0FCfd4&q7INXaU6MS6f{-ndY|UqebkNRT9+i2gr+FUtK<=zzsc3<@_i z(nAG6iJvbZ-Y*#?GB*{XpD1_}7OMEdMYodQD`6yz7J?w#btG-g^kzryyj-O(5NPp2 zX}?*-rBPzw3PCh#QdvhK@FP>>5^kfjFx+m#aBHf}beOvDm=2w{)@>%v7143PGy%5b zTuf0$K_po>oo;|V{-2&ewO5_wpV7}B+=D^*9zaUP>~*pp3)Z|64K6yT9d^Pzb&2ady9$CW z*6Z6s6CEwUQ0DF=SMVd~eFv}x^0BP?A&13fCEY3BBa6q-aPZNeMAeiz<19pV6h zLRk`F&>PYn9l4%D0&?}8Y50?32ac@fV5-i3J~bq|Xd-s|TlnHf@sn4oUK~M#D!MoD zn+Ufxom$T~*;p)Th*Ho`v?9g;P4Ti=fkrzQ6-;Ky6hG$|;brftE4n8h{bd^gI?1k@ zZszZu2g}Qwn765}T9Q(tfkFlp_Rdp?>d;2)g4c!i zEbR9l>vT9`@Y|ror$Q~2-80OtcpkVDpI7|jfS8zjUV7wKkAy60<$@3BpUJI~!}c|P z-OM+u;@SMetYlqcv1#)u1eZ+6sZA$6wU35(<&e`^VYKTnv1?XLn%`VBzYWw8<31T2 zqo&RkH3ox(7{4|S$op}oB5${=D^OJj^5?Ez0gb0uHTgq3>U(VMPofRfT1}{I)wUZA zo?5xhYx`wUsY_@OnONcYTJX`CDMQ5RMaqUaWSxV(#fl65qpzQYV&dn+p=ddbGX15V z{idG%R$XY`)%Cx#q}1m$X0V738MDe#<9@X&3yeGFs`}{YmTPUGf`XA|vxr?|rFRxX zwCy+IJACeG4KY*ZsXJF?`IjZLNyX6BFV|5hRmW;=E?TtbIQ@CFzW!(NkvHQCgmw3u z`0^?oc;0Ddgz)oc9}&7hB_Y@f@lDxe?F-T31w=)~`f1G~Xc~XoMw!RC%w4MtN@G{E zT)LWxa;S{2rt|sYD?m^DiUjVj{`FtKI(u{`Huf%(tyVM~^tmR2$^BV- z61QkA(AKRU6J!F6Dh$Cc%2tVViy7AYUHQPZX~^>FZAe;(^;m3XGG|AnIkH3mx2@Ro zU%z{KPy{{s?%v`;@bv+;E^bxfG->K>qs2rw_f;}NOS3~gnw3Qja33l@zx(?u?eNh} zTnHZ(=yw&(jJWIwIUy6M#ZrNx4Pm~9=;~x@B2N^@&oP;;-kN zk&)(#p>eWGD1f=D5{}0Vv;>PadCDBaRCg=uxZbd$Ba#K2>r1dYv>72O*AS8p36*dS zkP194?L%fa;mT~I&pc2Nu&Gr z`H#<^9^$M=(Py`DBYT@I=hLPhP=v8IXqwVi!YKGs9GcKL2cGLIY`^9C4$e%69PGBI zF?b0{_ji@T+@0sh;Tn(adN=R%qAXO7XvWiu4DeR0g2ObHm9+BTZYA7Z;Hd+r1_sIz z^>B0~&z&jEa^^*@ z1!_&)-Hj6Vg#4S}-kXH>5-ZtQvy=R;d)@knbo*uAyw3;)ykDvwx_&ec9PH&kwg=8tUjj&NHbvE#jskuyBx+9FGI5zyN@{~@5z|ck2RuG zjfCPJ^w$6FQGW}gVUIWt(XaZ(KX}BgXs0Yzl?DTh;2BorK9~bFJqm}<6oO?rfE~|e z5o0og7Q}<0ljj!kP_h-Cv7yWMD7sp;%n~|FYg@&#uN#`{+5E$-93byRR|A}HKhc>! zy@j0K>QoPHAz{uc$d_7tFN!3W^XF@mEw~UuBQ@-n;##Tl<|Qa$y~uXQ0zLUU627bR z#BJvIzS;|c$8Fv<)t$c2>X3G&B4k7}dW^h;kmJMo_oSlcBwtko%fS#s(>0btt_X@E zjE1#&1%?_3c2WLq$9l7-Wt({^NlL4}+s>v#r27yYHti;>Yf_-t75L6JDtQUQS4ZPS zvYE6f#FyySDkI^I%cL&Gz5BE-Au>{Bui5ArMfXaFFsHYXQZKOLlTCB0}G zisv-0aVpxa!?fn$!E$Ya7>V|jj^?AVe|lEgd#JzHdhDVbzI&V9nnO7DyN*{~8EA0p z>Z0`oJZtE>2i?Q;$AXCixK#yILTK&(u$~S9$k)Z*tTv*C{10oTn*;lJl4*C?X=*U| zPA$W#FeUW<+C3;ODoK|zE;_EEif%hp(XfjiXfC%1U!olIdfk8^G>({{vMRKD;D3^( zVd&rCKp6-S#oJWIQSiAKnt0P$R3T%Dq+cO**ZeCvp|pI1^$%ohGS&I8Y%Cuxf(1i< z!a;U=8V)P>?)nFp*%e_{`G$U_GfS)z@CEbpOd$!LoPZFNLFVoEn4+^N(%<^rErQ-T2q|H zB{*a3v#>^@%fhWSQKfE0IkxOYbbIl0wVI4(MK0Uw(==#GhO$AI)G!!y-g8$LL)PYv zzJiQma5hz$bE#O`0=%jQBHp|s;f_TUW;wT>*($4CkHu0fH-vvXWMsAzB>fEof2B!rs6|T(bfl}qM_HvyF(DO*0(~- zdiVS<@1DGQen9TqQh&cq^~)q{>S!xA!{wFR-35c7bvy1L%qZqYGp?35{A7m;#`ERm z?_!T9)4;lv*WQ@0PmuL%lELH9^gk#IZ))FLL+692g(5WMwh^phv(P-F<(RMfLUf#p z0}_32^9pW%^O{seVsf~eJ4(}*^kfj$@|CWG6@!Dy;1a{1E-{HqP7&X>M2vX$Izdkec%1@YF#YqzkVwy@N-Dp zWqvGMddj{wZ9L&1)9zBd?Vm0FXp2Feh|_Q?&eXv|EGkIe{b=z=F!(UZ*W>>6}XQUfZ%TwnuR)mmSjMS)gD6k07pXf5I+0MPd~m`uNUO$E!0;z zBaVQ)GNQ=zn@02m6pqEpfp3faKCC{$@%|(>b2zvbow_DTFbN0aj{Ze>5`5k53U!P^ z*9%9@RtTW<*6u1#{MABm>H>5vqpBWM1t}wSMxIb)zpI)8M0X?9P<$`H z?3ezc6T$!1o}%%cw`}#63!l%#L6v_*fMJQTq=#LL#qtQkkH?c$7wHi2w`4uZUz0y* zTZ%n_WOB{gV1^HRy}lM{X~I_Y`lb>D7ZV;02!9FvGvlj@1x9cdpcF~UMbr|rBL0bt z=EZ500&oogOsxJaSeTHM#6k_ii`>TdBwUe`;J%jK?Y~}6H{u}-!)guJ-Qr~q;|E}& z!RuFV-vv>M_8Qn0rCYXOE0I`N1ny<96i$Y#a`!20v9eZ*dhI?TQ6iZ_?$#PQc+a#l zlY0#@5-@d{Ine(B({PY(nWNhOQJDpMV4AJ{UtrQ|#zvCap#9V`&-9?hP)d;KxP}_u zbJ3Ivw}x6$FuhFjSVN8k9P&@8@ciVIv`^8$ucLkWE74KnH9x7$5XY$6oP^9z&neE- z7qz8BMlyxi4e7aRNa1~n?tN27`s&S3Oj(Bf)X)o}w@AbjKdSBH4+T%+_^gKP1;hT0 zAJkDjV5*08R1cZzQ61GIruwFi>Kmr|wvOssrc${aYKWOeeIxPs>%Nfi^F&{_%U-5F57u?t>m6^c(!s`0OXfdSJ7%fylf!#n z5}Udy_=ULv>5?^+NMM`p!Q*7RTYsz;S4xR8#FjD=I}#)FWq@?EBvN?;P)3TQs~l;_ z$L&RuU1R(;%cYq_VG(+Obis347@UCPsV`2>#u9+^%q!)@&jBN;bUxKEp{x45^ckcA zsDUX3qxU7c6I=8wmk24mxB@X~qq-NE0}~nBpvpHJvDN2V_rf1*$P;9&rHlz$SOCC@ zxe_L%rtyQj$X&acr&{Mg;aMh=b?Naj%U4;lPz0&MzAlfT3SRhlzFI?%s;I`ENlCY* z>`YFBntR+nF6Mkq<8)Wuxi+Z!S3~yZ=BXJR5Ey1&a>+}jppS`^b$ou&i^~A5C6M7{ zUEJtU+<^56Zvpsc=*Q@Gy6n2+T`$pe7|f?-h_+U28HZYhRPYU&>YGZXOW`KV5lpOs zNIRd-m(^8aq|xv%651^ZFP1WZreAfhw#XGASAb& z#k#IQ8SNiAEXXcjdvE z7sFahbv0kF#pEf!yJ49}OKM{bss=4$7F_I5)Fk%Q2>i5RjU-VDQU9huS!KM7`D!A4 zTbr{7EbKLZX!cU2=Wx{pHsI#<5R7zS?s+4h85^bV8)T=t>Lqdzl@{+2D^BVd^)XLF=jpcL|K1zaEx(L z24d5nY;OtIAKOAcKC;)Cc}}&ji6Nc|REelxcS(N_{eddw1pG`SSTsvJs&=EtS;1XS2M> zKoXMo&v2rg?;v`CCk;16Qy9KLTOP-IH6~TEW~0?sRI+vjUq5`BF28=z`})E6Uq5_a zj<_!0)vrgwM~_ki+)PLLid?%S>Y?1JCOuEq$!QQ?$SNj~+l5`2;g#6>mnl2-eiL4S zv${=qnO=paq*>c=io}XihtHy?&5p*AZ>p-<5*2-M=(ID4+Qcmc9u$TiNzu-z3bb|? zgpel~M1vKPa_&A^NhcTVvu`~LE!7nkM1AIzmXj;;&87#*z-GT`i6E>WyF3SnbgK*4aQ@N>4h2yQcMU<$UZ+x1_-#AbG4qLQ=2P7{fq~)0MwfrQ zn=j;E{tn(xW}~Ob=-yy%YoYus!kq_duiAN5DekuaC-hUUFlNQILt=E^;XmT*xa`0| zeU}Q z4FUU?X=JR|3~##0XlJSAf-t}2^4OZPNApz1FRhH1x)G*HYs&mzTfQX3Tata6AwEz; zZC$H0DWIG)`q(yZ?lrdJi%U&)QCcyWe40;}clCbyqtpU19ZvMoeDK@0+;n1D-*J_g zsYb676Vz;_+n@M8$I5E%G?giuwH&r5`7Q!W^EX{>Sa$2JW%=I;r0%^%wXZUi|F&h= z4#o*$X*sQD)Kw2f4tt2LjAH;g3-u?EtJ2N0|8&MlOhSup8J{$3`t36+mRfJ>M1 z1r^#4!br@$83cdXyNa^Qv#StVZ5&>4&!7K>fu;2%Y39e$X&Rpi4pt_?TFe)C)EW-` z^ma$`&rV{_7M3ILo@L(BqoaK`CiA9g68^dZxNa5xB7aiw3%Rmka2^LH z1!kHY$%69=>}M4oyMh(Q2*uuudJhhnK76fQb7HtlIPIpx0{he+5<))CYaq3aYfFg4 z;2W6nW;iTwXTaq-SvwPBrs(P38z zl;E>QkBb_wmfLihCzbnNc>10fkcnM_WmFsqn3;(^%i`UYzGt0FG`f^qrRo->h4*^X z$T$HVE12}dJu_)F8?z7N1R&<6yj$?d4YmAQX2uYy@azm9l+ceY*H9Vhojj|^4RPri zj=Nn%^Jz|?jkDqd!An+0#aK_Gvc^Nwc+2>9%w6^s+}n0<7nGNr9V}wFtT6l@XTEu- z?KPUb7xFB))Mvnxn~sN=mBnnb6Tb z^O%GcgjPFt7nX<3=~zTN`l&MHJsXB|$)%7)f?!LQ((;@UhTUgRCjw zqZ{vW_XrK+mg6dA=mvbe_5eN>HGq%TI^g5=7Y2MBRskP}77C4x@F=Cj+HuO`PEk97 zq1`NP1_7^8)FF1O^ozffRj0(*+IANnlR&logO-E~Ds&9Ce2|}>%4r-)o5OHA7i7}> zAh!1WrW5|DlLPKqG)*eRV0JMA4xGdfqa55W*7IyW zjawR`-3V|3)bEk#s8P-ZmNL2kUl}}6V)NS^90;`U5fiVZ9q^xBu}LY&`@TF>nMP5p zrjx7?rJkN)Bh+)%miuK}z`s@dvaCFElv_3znuebS2c8DjeCF=?WSvDFY#_Mvsit(6 zz8n2?j|J;Tu$C=o!v?H$l&RuYWeXX-U=hgO&iWL+QL}bN(!eLCJ&(@9N(x`q(&}D! zDLNKBF)0V(U~E1oRpG8iItGqb4!HQcxEx=_xqsa2hh0}txXB>X?rtxlhi?4r?ODL z@a>*JL&9j}+(LUz+2vJ~KQ7N}virIqbww%d`DWdo58F$C4-t|fp2VZ5wZ{(Q@Dav6 z8a0E=Kn0^3Ista#F8t@#!I@anmx#=SmLD3HSrc(+8WwPPv&freB(9%yp=smQ<`#rv`zt-GZoR`!kz-Onvx#5L<^W9v+#EPniq6B1P9TyxMnBlkkcsgY}oe;uL_7%2xBEBiP&KvQzdI$Cf z(-FVfBZG2XoYSaqUQIxPvYK7(O^52aAmR(KYAzW%Z(nC#c(*0?S4+sOWn)&iIM5C2 z1_v}0Fv%fPMzwew8kWeVeQ`B{xFoFo37o}U`nGK0$yp>p{y^^Hvmn&5;|vXJE^Rib zk$Wx%6?bGNXBcrpJGYxfPrl;DClcb?Na{pJGCG!ip0|H_^J9A<1`>^pgFCsqY8znoh37f$R3OD+lj=43~se1aQs!?P`Mn~&Ke4Qnw098>BQlJ$?1&EhjxUPYb!js)%_5w8=hQ7P*+BNitmt{?-OQ zjW}ZvEhjdp8KguZN`HBVLqz3Vbf|RWX;hXYcr7hZmOS>%YAuEpwIPn0nb@B^@TN5M_cr7EFrpX(-_@Bzim!@8bn}szTek#br zA!b(x&`+R)i);XxcmV97d^8fe z5KID=ug^kS)}ENP6F^}(pb>)&mesn2^~#r`a^DpJ9+`yjXR6VX<9kdOx@!yo1wy6+ zKrlqGz%{K>K=B8Mp{H_|PBHUd6o`?WPULR555no7osB_~S;xP;`~LLb0);r3D;)~% zPTV$pu_qAwLV?H!VRKb$>4rs88_%O^wVLZ%Sk#x$wV>$-=~_w*bO`;$xvStygYK(f(41!<^CLgVpGm3P?f?=5lm0_4$z&V8zvID!;;RCB~@Tl69{?O}%&ydiWEwK3`$Lm~d``{|kd^uOhmEbvMp z(f1tQ&P@UkNjSlvk|$nrW96fTL7LHJS;AhZP{Mk(?l@+yZadV}+}Ifhm7!rRQ>`mya+(2M4%D zyg=X0MXw{w8%awsr_>#eb)OFm9=k)a<&*{bx$!Flq`)c#|6oi^WM;Shg&B?1FZyj7 zIGLR`5GSn6yQ_JcU~Yy~iByTXNERU2_Aj%mt*$NrRX9+}S_JUlf{rsfyti7aI9$3d zrSN?It8|1gHaE1=#Vymi1WXJj&qt*(2JMc@fCfuvGMj+HG5LFuUxb1;n=osJTYa)_ z635Xh_mLa~q10@$Lc7F=1Fkxe)PH%N@%Wr{KnYSYVSry9lyP0m2b86anxpJkZ2y;# zUp4L>(hg@?EM;DW$}R0D{je1zFk+zCcuvnORMc^K4);W7Dysmug3Zn|#m?0-lAPSn z_btMR2gZ4Dc;_-LgPg>v!SY6ReJbwXD6TFDwgXG8sw@D>J5^LkHmF_S(nm#lgYY&N zyF5g}&9$d0!tAeANsFgUbbJN{SG%2rHd0@aX#hZUlhe8X`|SQG3cl_oL8v`k%7?lB zFo0+OlmG31^oPgzaAiLH{dattuKp+B2o~_t<=SPF4WJCYK`Z$9Bv8RGs|0w!-wpU9 zaBKjk&NFIIb@g|_qt*?B_3$bzk$;qI1F2wEZJVofdEZl0q z^pefV4>{{lN(M$K9_C^Mku2g*xGracUYX!9lynQU^^7M&X(Iao;!r*x#XSI1`LvbW z7CiX|xB||ee|uh1fh-OiIM#Rbzy$TDQ~Wi+1SdCbQCjjL`G~U463h-o-u->{B6(l5 zKh8JM_|beVb}eYylUcSz*MfG^p3disHr~S&%Znfqy-GMwT-hEmXq3o=+9SE?036NI z%?Og!h!NG3K#&pWBUdPQgta|&_bL=XuXh^dl2~bNy~vlK5ScQ80O?cYCs0iM(Hm^J%?Ve zIKgvg2shBJJ<7Hk-jUxb}gkS0;Lrpvagy4Ypgwr$(4`pUL#+qP|W*|yzf zO`nT1Gyj~6iOB068JV%xj-C0g=V^<(rjOespuj#vO1i$^*onPj;ZH9o#JYQYNm?e! zks-Ifhxy6H0464DH{q z#mR;n0W5H_0|EYhM=UHv-ql(|J78ZJ{IsM**IbbhVkIpHK?2ft;1|6ozCb<*g{>(W z>Lo0fLzj<$H;y$JgfRZmgRp}{WyZRBns2eY+I0g6-!KEn(I?U{6J$jCy!4Q*x)6gN5K4e$t5Q^ww@C`$D8G$rZ2{;*k?D!Syu; zhv4=aJ1*@I8vO1}y3!cZ^Nj(Nb~lS^VV+!&VUQRegPk^=*3QkIqeOwUcEPq+ntY#` zrRX=2v+pSVz=`(1+^}})_}f*7d->SPpgkp`|F-a8>H)Y86Ivl`w<$q?=9%vNYL-WD z28Ot}$TXtKLBo-m!J4m7Sst$+)gPDvtq@$wqY0~$bM#hTSZcNF3A6=lwVI}fm^t|M zqeiE-m3vo+8tN)r6^LN0!!Q1{d8}ic%XqE~<8PtLq zu&T1ZpPv7bbB8Um9~BRfyJGs&Rcw=a-VR?LC3hg;29FM8D9+{!DQYjpACx{mucY|4 z#MmE8E>DVzc~>Lzld!$~lhi+s58L0*MPZ|HecYOA>3C+3iO(02Da&AboJh#LN_OHG z>f2(*bxx)F+Kc92hLN24SoANOLp5DqH%3o{HDdQH%@0$S*e4k}E>$&53GgiG+ko=F zdYK$FCeA7UP`@Hw^Vjh1CKqb_YZ5si$8bGr+GEG+U&UMsD0&L9%~V$|t^$ruFG|#^ ziU(d2eUcUSTT|dsEvUCFu6Dl`T0{Ee51KE}g$i z=#4p4lGf6>n}%1hIR*yKCFM|p7RpP)yQgzHLyApm?-G=r5?M9{OPqD4QY{yq33=YC+RCG< zZ*j#Na2vKJr9w}zsaZNA3zAjB*&NJuu=`XWddK}x?2W$WQq>LZ5PoItGTwJ}oF>Pi zdN7v0<#?nvKYXEG@be2`N~aoA;ky|5p=FA1TlD58iR+>a#QEAw>n|?#W}@RgnY8{J z1s@SL7r(E`e0Va;&9)sHr_iFXHSDuI97rsI5wDPB-Ep{=8KP6Mjg5aeIOLWn(i2H*RljK7TjoeM-%atL;@Ono zCu)D)ljbFI8afvs7#9}YIIE-<#>8GKJ)0|=XXVJg%O|($R_0t1^|;%<6zyl(&lT6r z6Qn~&`{`g|lX#k?_}e9pz>${MstyBwrSu66WPy}Z8UHemogO;YXck2O2SyYb~P-pS-y+->RsJy@I)0}OT*=Z1Wi?2VUlZ#BU5Ieq0WOH zk16q{qxvAczX6hEO4M5KpZNosi4SNbB|lD_ZRpI0IQTgJJP~bR@j*3+u>j{xE(X@W zT(W{c3sqP{pnvb@Os{`E`Fq8qC|G4las95{Mi8>%&oPgK_X6Q5YGjPvx31o5&YN}nuhXnMz}D)O-keybJSCJk&HmZV2$b=b?a7}cEs zL_g>U(=Y$_=;6`axUYwn7I?D3N2U$cQgM3Y&WD|0geDb;HA`|??FSR)v_@aB+fEpsZuF%>3Cd;F5w zg6@PMBEPod7~{%Xfw&++YTk$-zWyJH0&@N@2sb0-7ko_29$!X^KaYZnJ7O+@d&U2# zSbor3pHTE0kcH*{0Q4ql;JZ`pb;|vU2Grxr@wpOUg=@TEHpPeOl8q(#vuPH+jr$Qy zg~LAIJRf6A=N$Gk=(7Fr1;LawZ%}jDl zvyL0bH_L3X`2*UD-9NIc$B=AviwKGofzx=dUQFJ=JdlJrBqRYxh9 zbkwYU-A-tNwo3 zt{p7yF$DctmVe{+DtGn7=f_hxdNF$RsljxAKfQ!2{SIx>l2N)JY`iQJV4IMU_7k4@ zk?q(AZZqhrF%(bH{eu8ZO+Z@{=4Ci#8#!^ z6Mo_eO>ta|J>!ITIj;+EGg#l8yio)nEfJwVR&Uk_&)@>|T}AX2wGDnp-WQvuS6STPrO* znbAbgNP$zkZ5z*hkdqBjFvE4EEg4%el0l~?Q^SdM z-K3uHq#-Jaq<$p}azA?&!oR zy4evwZ-%Bj!?pAJc#7b`>}PbPs9FGEz_J}#cW_ctQ#@b^*EdgqW5|+x+?D0Q%g&Z@ zA;01r>%Q^E#0XD_McVCaifk=1~lf**`8qemMRyF9lVR3>mT}B|Da_J=&%A%X`4wZEluczD^==Q21o&-py8RqweFg>171S!)w&b=gzEud`w`{$ zIMe}K;7T%BVR=V0N$HP_);DMN`n(^HRpUEHISp7eL@#AXxmCphOOg6+?y4yhxZS-5 zJ8{Eo&AknjDh?a26jtRJGee%}ZJ`Mhc%f45zfuvb9g*QV;eeiPR4uW^c;_^bm9eLCNHK(@-E0P<(|G z`r~CTp{dkrX^j;^FC{WN=Jj|#JZ*8hU*m8|omBMoDaabKgrGNga%7^C-=}6qr{d)e zY)nrL&{J^%X}L26LGbx}nq=7^SGd|iMe@M^$?2cs7w%USdy5{dU>f1z-R?%lFWaad zMRf<(J)>1gz8DS1y-4TC(P@0S%EosJZX@I+5w`QuZ=JbFu?F(XvDvm1Zi_ zLf!g9HP~!-ox~#=J0)}D3=U?(1nUhAZOdA3KgCrGmlU5mWS7x*X>-S^Ufx%TnAHW& zAP7>XN|3y!@r?0cb9os;dnk+lV6(sZ9etoO_OS5g-9M>Sz`#6gHs0|R>2{zI_ zfu88OUXkUbKR&b_o%+8VMwdXd-2e>39kPY_@UBruG*(!&RD5+h(03rSqR(sA8f8Ky zfPD8y_cIN{PSf}ONOBU~&p$(67%{Vi%&MdSKBR<7BGuX&O{qiypBR3CIx*tW$S;^dK;uf^tZCwM$7Js9aa z>BE~&Zb7O0KK4;oXmk;gf?EcfN7o%V@1h7vS)dTlxJ3D&^}jvdWF06ZErIY#$(94m z7%(+Uu)!E^oLm?E@^6pj@vmIMSn4O{eotB*TUy_E9V%qQmFF7>Zl*KVx?c_EH% zE*bT$<9!#;MCF&xSac^-{75mb?1}(zutaSWSsr;4FT5SUQg#nm-~XrKK~w!EO7;N) zB83M9!uXGe_rDD=|97uj{-3?>y2siJmpzu^Q}Z3<6w-Ysz+g;)qu~@^I{)^uE^K znlmFqe7;Hdf=&{>t5$(S_?6A4TZ2rR%+b4m7r zrG}rEj$HGJKW>Uj8lNO@b#*oJFUzK+*ypB&w6_OK#??5L_2B~`RbG_!vq%cxo4&Vt z0Q1Z}6SL$@&JPdYd2A;K7T?vc0(y_CGH zaqH3Za{jkI8$o6j%7iuwkI-dXSL>0c=HahHCZ`KQT3MMTqsJ1Qiu%yHMjI#;fEsv! zo?ns>9td|(Gqs1nh71v(M?!4uO;Zmy&PF!6rtVZNlS(ID7RZnOC1As{|8h-j{h3wce6EiS$EYiv4?c-`O ztPzEU2W3WrQ=#gs0W%aZX(35?q%G7+Sn#*&yMYdz&=Cd@M<7#k+3#JbapU)p2%BFYKb)XL3$UPHj zRNQedD|~?PMP*Y%f6x~BLDg1vT&ahaekSf3ky(YEGEhNG4Mc`jn>Uu>sBR%a(ia*% zl$8HC8JufRip#Y1sc1Fqqv4MWGm$_^gM_*;_-NCaJ$AFBD3y8nJOo0wP-cTEr3i|Z#MjVaG z%6_MZoof*4kyzg#lqXu%tjt;C?fPuHQid$kk;-OaPpSo}x?wgAnSEnc1593f^{sb% zy|WBjVF9A9>@RA@ZL;lk_-xsb*QXNuy-F$mr*$nSCYXcL_hHfU_`9Ja4re-rjST`H zd|T3@ulWFu>aoQ)k}62^k4?y|iJ>F@7rj25$wxnj){H9>^X8!LiD3ZxnfqB)Uqv?? zdZQ7Qm7poD%32Tws|kq9xP_&{et^^mTJc__K2JN_yY6rj6LrQ?(7bT6L7sy@%u~?Ga=L2seO!#?CVcrRF6{}s zYa;LpJGrR|?@ZceZc9|!NUEx)cczQE8oJgWu+YE{`Iw#|G7*xzSXz$`?Qub;RWYUI z3JV_8n(6E5dVKY_>WY_jl?G+jD>#JP0UHgB#NsvNMIm3KuA`A|MDW(!sY=Ys_0FCPr*!Ii0x6782JINNG#=Tn z?Yq%qvMrM)Yi&BLF1)|erl+oL(qb_D$E)wcbS{(>0@KmT0fNH%+@Wm2=}g(FLU+oL z0zFAv?^hJ|v5wZ%lqbqWcU!wWt2ir$DJ8dV+lJ#52KP4}CmM?2+GYgirppq*vMx+Z zr0(D4lc)tn>>1jo>}>P>JgSTRe+P$P++Qj1G5on))33N(ZP8|J&aPjf4qw z*z#?woyiPD8K!=p@K85i@3I%$;;M+2T`{f41apNbeJ3K2_pLxtx`AoDbdlt$hV>fQ zD#kf>0L+Ja!62=N>N5%dlzOu$SUZ&HE}rwheNM;X*E#w5s&Telrz@(P8jL3c55g;j zkYdQ|h6EG`x}#l}*9zT-xxH>~MPI^5j}w_eyDC)!9lPVS4}v5hI_FPW(lZ6M}1d1&1Jc9-3sko?hZ3%#J!f_8)k$#14Zv zagPL95Z6S8XzqzBB{##ZNib|vaQ;8^4kryRgj4-@a&x}Ckb8ZJ(z87yI-Vj=U5fSu zt^a7|q{pTk*>EFiMm!4sb_X}Y?_DTkxiuypv${}NgdN?yVv6c}#GPG@6(hGufB}%|m3OLnr115)k>}}!mMep~y=-DT#O6d@2 z%~71*nC-LCq+8^3Nt8`%RcuN+A%d;4HV~Iwh!*WEmTsq=%;yWMgVK*4O@r2w-5>60 zYCbt8Xa#%@KLb{~`ka|;Jkwhu)T?;7V!_zLfuj6?fuwWDecZ}O-K2sU(=4H913Wyj ze&c&m6GeuVY3i1Zd3F_pFvsZc#2NU~(67Vp!IH)tKHxxsHkhR4bjtmzP=rbo&%1*= zX~_|GUO9=V8;8lrz4Ehh@vTXTVGT3m8}CV9o*nrp{8X^;u{>NcXM1=HJ&d{dmwxxqRF2qgIWq&_^|-6YvW?$pn1rb%<@^2Mpbn+#Y#j99I>0$M1c9o}tXplyAv7 zQRc^wmMU5=D!HDgJ=(K zs$98(*0L5C;$~Q^^&|Jr1o-N-5g3rp_l~d-$o2=hfmYi3KYD-hFqj$gk2reTH>dnh#U} ztyZy+gBhbm^}o#;Y6W+;_y10`RnbhO5=v={YQLrTC-cOwiO+-Z2ryABjb5^D%+wm9 zY4b;185&7O71mb!1uHzIoYY^CWofFyJgR(mbv}XXteL?JGxFP5BtRTvA!MSh%V4>n zQV7{>ZU$321!c6zE8T3w(YX+ru-Io0b@Z!_XTcw50FuyIUsQsEhd0&T^jsAMXT3|l z$+b=BW{`E@y?{JegsF*_-@QMxGft0oze9Vz+X=eI+{DL@)MV-+HtH(qMPRY*ZYfCC z*%j0m0j?+NM+P&nxly@mH)>)3DfEoF3mL3idCLM@hF}&njL4hHT2a zf4ERzEu($c(+uSHsF!9C2brLeO`9ufa3+T{?@IxfsZni;p7 zQ4I^Z>KiZxnc~9wnW5eq zbQqQ4Ub0+!JdfqgV-+Lz$TJh|iNjav_9=5=XbO-8h1p2}H z$C#Lm*Q&1BY(I8^Ef5Uo{ZpPSXdgV!3s&wK=;n9|!lRyvdt>7#%;s2PNh{-{v9b9^Mh z*a($eQbSh`4Z5x=h~&;SGdV8(j_hieR1rN)>3A@Q{H`73VB#Zrh}*(`!H&6*zizg2 zr4~E$=R;h^-7=qu&X?>;tL!czE%DlvYYZ@;eip(uk1C$$$N&8&EB(|RGj-JcO@Zi{ zf#j9Oi6Cw(cx$W*#pu+umymB}czq{}ivE2^j@HYCfJt1*hqD)Y(|+F^sLKu6zWGVo z`C_l>_tIl^wcMiES*Ri?kr#yD>4yo)N|5)BUhSI|#uRH`Grd}0e2NicDvZ`TaqsIz z#*59)@C;N{)32*(gMnZ^y;*SbWv6L`8&kJ``F}4_!I88Td;4LuEp#i={hCz4fcPn4 zZkfF@RqCXYMl-}?*@-SG{@^}Fuo?`vj03AJ|Kzo)WGPO9S%&)hb-dfR2A{2~Kh(|X z+sj+Rt?sdvzUC8~Hf*wERZ7SOa+=3u9toW|`ux7byTTU7`hnrAXEiUzjAY_Bd+&D~ zty36KRkqNi_?hg3n46r&c|17br51GXJ#?+Xgew?SuWoBcmS=h>UF=BRt5c!}x^l2| z7cSe#8Vh%qxeWp8f9#+o#qH5t@H){sj>WPPt+Fsp9~3#ucC&6hHk zfT>z<64dq`^La@uP)T}o08^>`;oVLIdIZ*5SRs8EACq|_>2IPzE*r|{aX=cW&@Kx0bf+byv3G5i!E2HJ%Z1wx1<(hJuk3O$m7l0-ex zHe#rf0x#CnUJVE3pr1svL=dsf8x3=;qjKedOW)z>>#aUT31oFQ!)c+rurIcI5-u=~ z>aX~QScU%kZ11DjK&njmk3UHf*jeSZM=0LAmmp2RLGxTGIMcOS1##}R@S-Z*y}L&X z`n}Jiqk&K4@(-|~p#BYY@Ovz?BXGqK{FR!P&Sg4^SMu_mjgt=Rszh|>=%@X_A=yr1 zSGrfJ#xW82t&!W8eqhT~x8k`Mqn?~zJ$db3#-2CBN0iM(?Dx-g*GKd&m+)U@W3=t3 z;!-|)k=KHa(%E#xQmZ|If05lVM8!TtmIfmYy|TmYr@e$~GXyiWoh+`@7J}4#Y=&io ziscqmeD0KTFki{DC{+)C*f^z_v>N>t8eEB2Gvx%QxkwSnob=-w(w$Q73E!)Pn26w4%hJ4V<03(u(|q z8DnzoXZ8b+^?wJH?OOHCTd8V?v!_&&LzIrWCdPf#7XeYGO;x6z)6F zI?!w3>8$lqJz+1`#Rx}RO$(^)@Xkkv)%Bw5ye{OnpXn(+hW$WWjq<)d2{n4CFFs;l zPqR*DhoE^x4fKg+ln*8(xknNh5}Q z4K{xbG&m8U9OPV0kQB)~?*C&XGPe(ZP~)9duupP%f6;WCP@U({mNUtFM&bKma!nWD zmf4FZ$PJN~09O^j>F!AA*;i-@+_GJcn({of597%N<%ayXvN@#8GiSyef5tz-dbazp z7nU1rFqFNAn{OLXVcvONGU}Q?-gw4n5Juwj<>(mjMZck~w%D9u#0i=frD4>r`EIFI znj}X;H#Ocu{Zm+-&3fsX)YvZKzu1eB;SUQO{?k6qz!ourSIprABxebp*k9NtY_L;6 zj?VZ9_(i-u#u$#5OEP~Ery{F0iCy<3c`t;hm=nFQVv0Q%Ezx2_f|J4jkbi6>w~L%> ziKZMfN_sF$eMrZC;TjwpHyqohTylSoe$1w zWBbIA6xH zF>!t81sX`ih|Ps)*V$iQ*>@AEzw5z3Hgdh0y1yviG>P)M&Lp;@;uGqf9y^nFEx%DP zg7khQ_vpyBw(}r_aa{{J`gpgw%-2br%k*nO^jTz9LADXZTBtl=t5w`PXFZ3HeT=%# ze8pwSkxRrBC)Q`Eg_!a4LlEVK(qV63rN(}gHmExO`uA`1toaF&q~QY_L;Oh^$a&KHBz&=foTrR1h6XdySM z)^P*W17rxh(|nHPQqy$wq<4BDBL7>8reU;2S)p!NyJvyoTU=@db$an=o+Jr$Llr8`7fdRHi;dd)mJ4Ex87bG zkDO(fvz!{2s`}m|lwB2yZfq&(M{%ILUf}*)dJG^PmA)WY^xAylluv00AObq1AMR*; z#=V?cu9t6G;($KtxHvCT-HyK!d-huj=w2G$lJ={=I3F!I?(jfYxJ*k{e_?Hzq$(3s z52C<=)pl|!8iqrADYnlecQ4lk=`IX!2-h=qVurgkOkf<&_p`r|lH3}ztv)=Y8Yeq! zWlXnr2;Q#z9a_4Kr2CGF`1IJ95gkR5Kt<47h*)b>BBq&aBo#D ztXcF`nk3}55&PtwjCAiOoSI7h^!9Bd0DOs(V&Tk=G65trHk?Cso3_3oM0rJ+b1j6^ zpDfg;e;XigGU6$EqH68s)6dO!{J9fiVX5-hUb=-%Y_{uDW5UaYYvKTx2@9* zWzPV8OATbkaO&6{k+u^C41jfsR*TW-fP`Herhk_xi8N6tyzt)lBchbFmG(oG`m9N+ zgqrZ$`q*ezG4VNN?GgF={F1)^;lZHh@n%WbxzcdUEOW88Ef=_$HPf8m>8Uo<#x)!B zm|xk0EH}8!Dnp``#W%)VkQ(<;wMH!$xXe02Yj`g~>22sm!Ws!!-2uB?Q%kyX@ZDND zf>z0YB9hYe0xcKRIx_bVht&*fPS4BrwXy|5xA8fz+2$Ht3>;b#B$TIg>Ax1SHof0o z;hQXzUFn>jHGy9!tk$AD&v>=7CZNV-_$s2@%>33^2z~mj?`iyZC#T}JDR~45nM~h? z*0%o^j(>C8#5ohGq!_Q*9886vmsOCrDRBO5X&K;ZML(IcvMgE%U&k<|-gTEv50!eE zSJFITB6>Q#ZaFQkMR4CyA}HEiWTTREvi_wR(we~Ns+}c3X~}3`$4BlWYtfSm!8J-~ zNm_@Yy_v3Ht#xd%`{i}z;BRhHlVUlG_hArs4RTz)poT{k|L(xQrKaoM)>6XTQ^KYb zoVYQ`vZSWJQcoNGdv`&s>ZdhDC0t9(e^Sm$+M~UOOU3_v$$Y6vwjdoPaVi+_T1c}? zPC)>(UO+V>hwinN9xtF5gvvjW<&uNPZqKH^ytlRtoZ+ALubSoXBDkZWD#WM+O$ zRU}uiM19O*={-71G3ny9AQ>>rqrS|CO~Q$aA!yL{dmSjii#P*X5Q0h1_BR)6WJ`i{ zuVB-@AZhEPR+&z7DN@XnL^GKke1cMCB}m#Z$mV+}M{$2g;%lckBnnl9hpSaWk4^h_ zfOy(nCZlVv|7kS#4mYZ?x>Go?$}F*)gGKo8cX?X$J8H~xfv&w;BQdYPs}@fpcB#zZ z15+k>{!BN9JKfbZv+KG93J^yE?%I_5)swd)Zl!9}p@K^UuT~lcp;*dSw~u(cHb}V7 z(goUJ0OH_|VHjJTRRm}@Xy}$f8hjXTF=)J0J@H+VWe}MC{6Zls)ENlSVLlfQI$#U< zq`ms1pTaZK?B{SJ9V__+RD%ivBw3QLPW+EdL3K~ocM|wq1K0rbquLNarY96k#HUQJ z&g`OQ`)?kX|DRI5$BI=vW%~v2(i<)V8qTK`yLb5>$(#yy?+aOriw~qJ0u3K!IhE>> z-yeh`NFJ~xGnaSbu3XkfV{bfp!$S;u(G_d%;rGWG{s)+@juyP$@5YWoN{pM2qeD12 z%&pNCqMxj^{3htQ{db2XHS&AARNPZkip^LHo}ty6aBaFxzui{?Ub34V7hy?Qwb>*l z2Q6iO`^sPE{wa{Ks_jN`@e^K{=st7PFoJzW_odLxfM7=onog7W3}HsTd7V5z;7_IN z1~Bt)Wz%&Ijs)d9Ni(!fh10nu9BT>u*;PzBLGeABLG-$Ax-?8@IK7wDDlulbgMonK zKiE>|d(&4GQ9P^4qiPOs{k^|xN~1)k7?wV@;)%B9i+nk_QCM_jfv!OnytFtFVO*vr zvM1Ra0Nd+N?0Keywpnse7pRaSghMVgyB)ALr;Z~)b5SBM^1?bQx{=Gwp{fgcqHtCx z%2_Qkd`bL3bVYdks5C~ zCbhVF;_JOcDft@&{O^5At&%1(PmWY29e%)_)Pv_C)pjkl9+$#v0$3~Zm(`FxUDADC zmj?HX1|pw2(oIokJz8ckVi11X@Gobj~-%VtAg}9~JtvcHSDEO~E|scSkE zmbhX(;rA@r!f2+c!l=FJ7x26Md3hJ^w7ng9sW^04)IdBAjYFe)XokWR_dd*xc--d{ zcu%YZ5{Nw=_IMF^t)6HTB5+}Pieu!=Dfl5REwRV-OJ^qTEVNRW4G4eKfFe-e_|XWT zDKj9sb*2>hua^~H_g9gqhwUPN*8pNtX4bpqlTb05u*MV310z^K;fvCLo*h1ReqLts z`g(tU(Adzhv?qFO2{2vsz#NdH)1({~!yM)pq*mKWbiy@X+sljE%ZJ)67Le!;;^>eu zWuY)>|E()M7-Dg9SQv3o2z@AYX@W*zzI{t^uQ)te>PjYZ+caz<@tn*Lx-aEXz)uu? zi0UtNX$32U#1pp6jy$3A)Y} zGfPCKDGC6p@AHHJ9;u|DTCA(=l!GwVDHSYv7Ynsftd~YHzU4%qNW?2gO`HH-e#-%B zA%GSufvOv%aoj*(fu@0{fLQa5^y&lL))Xg-N6eWt|2MC|^HiFUV_caeTPe=V0y21a zHU-?y{}t(sEzkLTVvI}KR&5Fvq%Z^Xb{P~(cl6W!GN&LS{7(GE|4hLsJhY-pIOjo~b89k7sIt%sNIM zkHdnNyu`dWg@d76zHhvzRX5V=9f7)jj3^CM7)`x3_(Wtb5RpZ*&Ez$#z5Tu_Noa6t zysYVYYWA@LsZRxagK$!qP>&U(JZv^n8;+ua-~+nbovzwUud+H4g-}0tW+(3X{38gQ~H$3fkrN1srYu!F^7?T6+j9hiE_ToZj3_y9@j7ZG8G;O~T z__V7l1tHJotnURh=C$*n@p9vEt4fT^MOC#r{}D+PHy0Ja3#}SRz6k!RN;V0e*UBtq+DJD_DRlO!R>5<>iplHc#tj{$ zMHK1pU9`^Eh4dvPPwiifzTVVJ-T214)UdXrCRxY;nDfN z_0y{IBA9{Y1HE=LEkwUl^KY5eDJ3g?xm}a{1e>M;#Gbk+ST>>_D^={U58PNba1Z)} zX8!9Nq(A~>mJ4^!@3ZvSqX1$&{qq7KaGgN=dE*oejXV+>XcX6i6nCV;R(90K?ut<~ z6*3gZ+TX~h6K>GWm%X{?3axqz$nl@RtuERBE) zJdG7)YeUT@|187Dv6F1P7#`B$s>RZ926u(+eN!&gM7mKVC2CAD;K}9OVZ+5}3l)5i z@L=J5o=;f`$O96AQi4Cj!Lt3${n9*z8TZ37xgQR}HUM}r_D%=v!G!ad`koRPdjKEU zLZEW^umQBwmE!NwNyVhk3u-qLSIX$9ePD4l;$+|P3VVN^IdUf>rC--^d_i4Dz)z`w zOldw+_a!#RjN*@o*y%QutTaeb_o#Ak+OiA<;y6efNSlAZ%K@If4aCVT^WNcY{c4id zj?p(AymsSYVME=iKR6NEVp69}2N<8;Z*=4M#}PH_#5%-25aD@WgE z`~9fU^Sdliu}JLxT8bb2fT?DBQ;|sOzo?+4=E@KNSGI zsW~-j_WN=fuJg^PIEz>baHbg~=w#-WMqIK066J`lndy@~wjyEUPCe#%gRJ)x zY1d%+k1?+CWvkp5eXGu>_A(7UWqZz!P|f{!+}3xR=g0TO9;G^ARD9m6adKC{elUuD z#%a3HoHlO2$0+2EXhNAX1L7C;l>`QIp0-{S0|^RSPv=-ZgV1J`Bs+ULr-qgu_)B=j zJ}=y&(jLXp+~yaV0rHC@Guq=}&zSG_>8Ui*K_|C$^n*ID8k;eBd1S2g0hk3VlnV0G z!7TsuBMFLt{4XYSXWVt`9Q1CZ#T+Mo=Z{dK8Rf+66%>Ji?BOM2~Zs5`_`=c`_j`brYy?4 z^swSxXzQ#D2JvNgteuTH%z)1ylo+hE6fZMNLM`;*N-0#8FOiZF&bA`93qmOX=EL}R zua*IlS)wgP2f@*u$`i{$Sb5%3gmi4bU&UAp@=x_=ISo^pP}{gQTvlbr%bJ+f^>H*_ zct$lhArs&XE8gC1NHI+l@g;mMHf%0~>wfs>&ar72DI5V4!T>R89f_5Ct@Q*FJ%IHgyLB2X zWYA>}XW8|5-*!27rNXsQ(MOY*xdv5^@OSg8i(_QDVa@cnu&Qslse_2ZMG6WIx9^^y7s5UPo8U;n4JCHTfnTx@G4_PNQ5V>OK(#&UheHPodK?&!UT!4em1x}B zvrmfZBQ3t|cD@M4rvD`+5U!jx;i{XXx8-bW2`V;E5*@89+x+mkDNDS-V(^9;|7c?_ zk5wkXyRk9kUi1ioJGt|3$qGf;2fNjG(2UP67wZ~}g!ScblgUJs@W}Z9F?Jo#Cr+e1 z;Z0N47e%L~X57A?kM8Chg-Z7wmeDlrF=hHc3z_J$56sUW6tktMsFACq8z(+N#;DXB z9b*A4>6z2RX!lcxh z_xk9NMSn^i9)}~%C~pghhrho@epl-DT_VHR{k4|IScpJ4(bgUC^zeB|>;2L*;xc@9t)>W8fu3!L3-99E-gipPyjWx?#JRbkeVK(*3yLAFlPqG3DIEoA8&-E%Dza}oVh0t zl4-Kx;9}@EgNJZde+e|5%kPHW6|J^7LNiebh}91kkA>d?F)529H8C01b?;2UD*u&evYdZ)+#YI{OPB@7e-?$SweYpI9Q908k&yR@;vq zq^0(raGuJW9kpVBbF#`AFtG zdxLyy!@(4#u;v_LPFJ5->3z|aYoRX57rkpBl|M3BUhJ7QiLR&RD>%7w#0gJIK6BAh zU*c|C9|`AY^8ktRr7mP8z*G3y!0kclv9Ud8Ha*oyx-#LuKt`xGMeW_7H&sOZ+_f!P zP$M-4+tYA!Rf8^spnYq)-_s9JPc^z;EpAAEs6LDq0^F($54M;O_+J2GK%Ku4sw4PQ z%l7ya%%J*jW5BlsHrtdk-0L4F_w1kd?Vn%UKfkem{@MQdt^Lzr8}0P=*RlOuN;3MF zvdx=c$}Vqy=H^ed$LpUn`*H};^b08J8QSAsUu~y%%i$g07|zMvd2oZzgM2yo8|XK=-@}VsgO0m*lXoY1 zoz$7K!HGZTU=ct3lz>OTM|ce@xXCz6gk%K<^0(q2vE8!iRw4v&A(7~78nE&m<&}Z( z3tSDv#Qyey{ie#Y2}#Y?y*yr|`!8mSOYG3!gJA7Szn+(&J>xMBdM}ADvFYHg#7Bfj zrdUfiC5dJ$DH*X)mIrQT*7TRa&5T1w$OZ{anl_V%0pBQtVL8A-VuAtevhFxnokel2 zD$={<8;p5rn+Ge@0jo5zw_d``##_kM)IG_cvnyl#f(a_`(hWnaLk z^wrmZLsv>|N(4D<%-LP2^IruDb9M~JXpoN5MJ@6fESyJ#}dRYGeTr7E_|QIR)Ma;GjhM>y0~-f!}Q{q?{S;Qw)rBQ zn1ws?jI0ZZ6{4Rj5Gocl&eHk0=2^8?%s{JGjRn{j1--|E%Ir293R+Yd+qsUjZwo>y z4fZ-on>108u>syE;^)8{+Byn+#+UjsqA5yP1w@-Ek7QRg4vdT@D8KG+A4tb<`S-m8 z8*lj63Zf0Gc(S^vkVVpGB5KfVvv6z6-!c)XBGL8~7_J3RKe)2z6 z%*24*N~SW<4tj^nAo$pejR>232eo);SlO-eMrVx#7a8Q6*N!m>UMs$cltLmLpvOcA z9iqW=(QD}GvDztO>YGFk#CVF>CGh;YnCMYnWE0Ey^?+_n)GNW68?q^cqu2D|o{HlI zr)qEZp{f&!S`~mEL^`tC5G|y)3Gx-0gvB(~SsJhr4wX%wlV%HCKd9bZMD#O{|8#Fv zx)*qjT&3pq)BTk}e*cOg|9WMRe|^P}f3q^kzqw+_|GYBD|9r)ef4efszrA9}^W&2# zWQzO3eI2j&{ltmJ((mXE#Y()MtzmJYw-VaOs1D7(R>q%lFi(A2X_OC)(cl}n23*PU zd{035r1_FfTm_wyLQ3*&sgpsdm{(KsQbR?XRS_3yS(7(YTK3^YbS7Y`<{4Er`h>1@ zBS8uPh#^3M({8*Yfzn7n5^U0wp2jkL$?1~5^z?i6r5lk)FD#(>h3*wj6a@xu7RV!e zfkb`X07%dkU=r(e$GaO|Cu*EgI+9t&$#0=ReMqa;l-!p%!&dkgXI0AK2w9GDanh^K zOM&*)U$;KnoL6@t%hNe|rL@Rfd`+NHg-TYiht>`C8^JTX^z%&x*Ug=qGSof+`urw^ zjqc;x<7lUF9shQnNuF6PJ6)CfEB}y+i_bv73A<=Q5usc#lFR%47pS z35}`QNQCYr--Ju=Avc7>HdQ|z*Z}lB7;2#QlVF2eiJ7^lHnuWir)&JkdY5a^Hb8WT zy1m1fL8KGDkDZ42(Qn&RAAGwqX|uXoY4iEZM?bFYejQ&eTrK=Rt`7R+D~A2mo1a(a zoq_K{t`hzikA8UiVpZ_tOO`8z|LKoUUp-mb1n}|AmCoS#%An7$81izQhO!<>zr)v#)`>nJrdp)Z+fC8Pg2oTkNlq(P=;5KBFRq5oXqxPF=D(@TFh zPhXg8Rk2H@l49~)CSh_EQh3ckio(&X-5WJs8 z&|^Dfh03D%J`L$n#u-gv1AhTrYUGuvSIb1xK%h3m1U`f(0kH5ex2D{&Dvz(ql$+O~%#s$r?#AAorV->pe zuRugZgu&5KndB0P=NQhjB?F!j%{$DVwLimX^KuQeTOF%=7 z5z{O^Yu)u1I??Qe$$ZsxLq}J~j1iXjnk-1yf>EX1>MCS$X$61nWcKeMjNgwK#C{Wct!Kt36WQU)3h{VfKsez-(1*t8 zmI?N&mlFO{v3tcKH+v(9Jw29M8u9I?5rKozOtdQk^z%-?tDzBrO;^-2l2qqdx)E`f zG_VF54RuOczru5hNgzORoaCojId90ivO(7Dqkp)4tDE!`;zQVbPtx03JdI8iRz&6j z?M7zI8Td`!jOl3STgg50+dNP(LHisVO62Z~sziV6uZ8zlcM$EX-&Blpz@_Gf*hE!2 z$;sT>l*uj+QOQSI_MW41QbnHjk8(v7dYW$SM*H?A5;ZKLf)m~Hzk;*UOl?|}DMmN6b{rHv4kPc+` zh>{z2i}m1_LA}Pzq#VCV#TI)YVHnn8>e=AVK>onpcP9ziDe>#3T}|rNWERv3SWM=^ z<>ZBCoa1(ReKdfuH6zSnNMi5yUr4jZf_7{}eaCfCfPH_z=^D$d+0KhBGE`c$2O zs>v=i`0c;vS@nq`T@8OCl_Lqko>;vm00h2hgYbE>o~UAhmX-InHT##-gCpP69tz9} zVE($>I`+%*EDH<`a{}q$`RQpk$pvQ(i3!qCOb+ZS;ja1(gMR#ZCQnv_9sxXuQCEDD z9|6ZyQ@R5U$$&2fqa3D(^*~nJ6k^G}Kaes!h>TnabVO{mq7Xs$nSwE#3V?<%+R;bXO-EDzx9*C5#UQPuy^G<-ic^{s;o>ew5I-V$4PT?@%@h;2{ zRm=Wv(KPUjt7@q&@H}pGjxS({e6QFo7)tW)V?3MTFM8J6RF7R$ToM zJwHClgx(=Ggj|edlAVb&(+XI5EtlkpECxxdEXdk}$tPn%nG9J<+mM7l2v-L+5qx@q zDD2Y&EgQbGe96&a7~21;n#7oxQ~Ph>+J7^(^;8^nr&GZQ5S!IsTq>~AK4m|F)wKXH zE#aK+q0R-sjTpwifgG%v{jmwPJF(e`HadUPwL}20iYNlYI?;kyL65r-To-`*=h=c# zM_xo|;LAdGJ3)aWYD18z>9n$(Jj8!@w4x$^S}JcbHVDq~{3%2jt`n=6Z6&4PP?d~4 zobXU4y^Ryz4hJappF1HvkfPz}NGysXPy9Pp>2IWxCB+ceaEUv_D_oL}aflu^h$VSM zeDOg#i*&3oI?C1j(5vdJiIfVg-nE@xQ8LAKg)^RW`aA}7-dKT zJ=yPk#*iI6Hu%a=dD*Wd`{Px*=S{XL6^jKH`l5$(Hi``gO&!Qt-kxRe+dRohpiK)) zT=*j^8ze=`*16|Kq_Vwo*Ee@v z-K#(zx;7ohswAR*6cwaffrS|)jcDOTBxsAK-Z-XwtBi_orYzy&Z%u9x{bjks-kD=e zKugA{)C{w#azx#7nhmGr@n9t1Y3(GpK8rd-^oTw80ypu5CFHqrn68-1%Z{@ue<2?u zi-U~IlbAM?N6&_pmn??D=%IsYDv4}s>RjT&{Db}0b8Atjs@QZ!hnXO(Y+g*uG$I7j zS@B_`vtgm=7kviy`pvuNt4o@xbGBUNvy3;Z0)BSIa8J`!y;5H=qU1vH5?W%%`{|!9 z#p?+&^ag!z6lgmb&4I#{A#^M1yU>yR2`-WF|^LAxV zFJ&I5E8TH#U;p^_>E6l`?8?z(@~JDG#e7v^R)m=OBV3OP8Pmks>YtV^{Qf2{=p&*< zV#xLlA-g~X**3=0E6gOxTNcXvMq6n4$qXKg8`;Ht#H!$v`W3LEP?Wg3Pn5W=_**$S z_069A;;qyzFa6~j+9z5lFY1+Q4Md%8snUrBEg{+i)pbBMoqW)qjT=JN#zr!a%Lb&< zf?PIf^5pf)#DMM)PMZtsDv#GHQ+8T?sH!l1sub;F!P6Jv-bv`>`k%aE_L1tuGVVh} z^Py|khx;v$mdo+GpuiLmnWCP`7*7|@ViQw0orzsHtKhCx1s&ROa{l15oo`%Ss9lFX zIDwc%KoK@+md%O68x`6XVxU%^jvWd;NaG@5&#wjNUdZpoPoIFDz~eesbwqVWrEw{Z zUei*x5IwL=CF2i&LHXSE?dciNO#5a!6B@Yixuylqi|O=n#NLy@`V0@`f`s;FX2VPA zbjWdNwuHG*kls!RGtOA00pl=){dPE^(;2HR-YU8x}nQeXzrfdOcZb-^_Zg13M<8-h(f+8{_-&8dzR%XZm~7 z-JJ_DvhyI~gEF*5WzXHviL!pl-yDRw>D^p((YpM?$U{`$Ja6W8nQJ`Wxb-yu+`0*;XUTg8)iyXP->^Jo~2$z75&*Q zR1uYT{w0a;9jx+|ksp6m&AlA`&kGQ%iV^oaBUXnj|E1_^4;JK0WNXA5q07UOT}EPv zg6KtbA18$tf|DtIB1E@{wTHHQ)oSjJPF(5GX5zmfky&!VRX!}sX_nI5$R@=j%*L!u zSow3so_0$g%BZ(W?g=3ip($G83!nS9C5;668d#x3Jpe?bc{{u8vul*}J}QH(|r zdSx>6Pgy!qTaw7kJ{El>URW+hE5ny|sakbw&csS5UlI}p$O;< zUkzC;mx*7!P?l1O2J=%+-25UzjO@?n6Q_WLrh>w8U6U$`zDSi$mu-GyNd0%!jiD&* z6IM&sWiHptxobPOuEtqY)IdMYA3i;w3=C}ej?(@{Uof;;T+9hvhDC591?yD_dBpX6 z;JHhCYMG=Siuot#*qlX?RX@FZ`2xfeIeA;8st59@>bp+0%9@XKydJywnywK0lG@## zqL^kcX|Y4uLohgJBsH#PH6!i9=e_j7r(!3mlCTalaYU)8m@0WLdptJuB=~JEy?2s@ znt@Lf-FP*KQ;kh7^nkw_k54Esjdq-ZR1lapb0bx1lCpd)5TuaV$NM$pHwu9*5NQ_) zHER6AObnNICz)nCLQYQWT3}wT-C>rbVl}G@UA`Pgy@mK9WKHyt}T1PB})blY+Wm2Mn_3`zP4(Ed7G~xZ`h=7A`VDazTIgN0R)~cwQr;i`hO1)&$M+R01DJbf zWsQF;+$|)Ix4R+)oMt@d7~eA{CtQV+{2$|S{|J1*E>v;(iF{o;VW%+$j($D+Cy;hHQk&=w-5idF<-CC1%M zZt7}mh5&x@oot4469u<#+xaknL<6WPVBaO5XLLZDVdjA~&&YVVPNeEq!iJ3JLI;sa zXEwJIuY4xc+juu_&ShTP2&7ZDn{)U4w8y2qp4susu3dqkcPvj$Y>W6lp*xSYqGs*2 zerFf8=COmyT$EnWg4f0bp0dCi7dkW8bzyYhkxN3d94#Da5iuZ+N^TOZ>-@OLCc{<} zQOkuzkfiO7fwFxzVW3ofPJ!{$Vj(8Kx?6*FJ{;FIXeS*#MUN_bS4yv0PIPJ4p>L+d zj9jMq;xqu}Ls=L%jI!b}Fhzzt=q31~QY8ZQ({&clNKcQ?uC=c1m^W@Xg~h7JP}@j!XZgr`NLw}rS> z$bKOo+V1cL)F#(ujUxJD9S`iqOyfjiTgb@Z2Ax{Wj2@EMOd1YmTj#cmqafg?8`os?Dn4{^+;(@|0ef^&2}3k2FS=-qOFSMVTQ!Ju1lFe6ZgfwV9R%EmGP zaNUl-$Uay$o+pCg`iISDM2s}qNp#v9m`0_gBt3#Ewa?28igyw=SP1L3in9=5=?E|u z0PpR*aA1=vF9*<5b6vP8;QI$!o+O~s?SUc&C1Y>Qyf}7m( zDJOeAku~+3Drs5>UK@Qk$o6$X)etxm4lXX75+B5a%8Kld(>hN+$`Ls1cPfrhP%ps)`ySF=6 zhfhkuO;46}G}j3#TF=YY7;Qq;zDS&-CT-?jqhCRsqxnoFTp}M`cXL>7`Wse^{YF&s z_ggSMTd+D8^Ggi72@~C$W#b+yK2)WmC{l4$&4=%-KH{wBaJo9}LZP^42dc7Y&SwjJ z6DMs945ok>7rZ?~;WsT=q1W0_yan7EHEfY?M;d0$8$0p<%@HOSyGf%6_+j#eCE{KvvK2r{)0q zGukKzBh`mEe3%2QR}IKeRI=2lFT#IIKjKh-efi?2rkP{Y0_` zA_ZjvIH{z_H1*OFIZ!o+(04XT?qY7hrW7LHX7V42kSa9uAe1n`uE-~~hF~%#o$G4n ze;N+WMTnD^SWeELm6wSwG$R4aO#ERovkuMGt}2K7ivaZ70l1m}rk1O9KMO&gfn_$F zM30Q8ga^@|AjnB@@NkuWFr-3mZ2H0=D|Z0l)CoaR7DDoye1iR%jZf0znCH}GCeP+1 zuZOZaz@jXj-?(oBy^~`IgoCOcNYbPeM@#`%a+sP1oXo7gqP!ftuLl=>pK z7_tZ3o_%w}0A~8qc^Yj-T`Mt5GYmFzNq|L!Okq?n5J|1XxCO1-8Nm-p$=&xFXg-1$V#M<$$r?; zPS>+d55;P{|NFeuUTM*`KfHMT_`m-9=hyF^lE%aVGv4s$ckf=mvW>=RahBE{jUGRG z^~<9@(rB9L$9wTMP=_=ri?eR@KUTF!GkHDS)k;>fjf83~ZwA_1JyEr2v$L)y&wsJi zv!cf!PYXVVe69fxT-%#Hd;avrlf9?!Xv5C2o;`m-sNtv_&%4(38PuUos?)9(uiw5T z4QvvUj%K3bo~&paA9rHm$BaOR}-ve z8=eZGw4>2WQN=ds9OE_V9iLQnG>{phZKJLO?+vL6nR`2Giz=i+)kRNl-ae((Q6=kY zqw>CzhMiRPW==K}rekYwp)y_4Mk@1BS1Vb|Hmk`a(r7F7qLDOG>0UY-$x3vjagXK4 z>?E{VCv=pf+t(rS`fnbQ{+k{Lu5>UUO}e<&JHoY^uATml>~j7jIo<>>uPI1y5!cZQ z>ewdpt_A#=@GLZGb~KQcpb=G*u)2PJsipF;b+M;$5#0urR4=Oeuvnp=CTo)qjGzN~ zr-kiN*XpCZ{amQPL;AH1al109GG!bNG!SnH)oA=)W^u&1Yjoh)QY$5ToJ5T@eD%11 z=!h7#RP>jYoVOpv>0LXiD+BSO0zt7O7I#F2(RAbHb&Sq}An*hbfw(OAU5EEX1=t}( z*I73d@P<3>T5&n>Qp{(kkuU?!tfP}wa}GhJYqU?F-Ql`(KVSC<$VNRqVd-%FrITIC z#DGUfwesBn+SyyV#Lcv{jHjoRB3ZNQ4_W=CnM_`MUxz zu~cc^(6Xu6tMxdYv5JQktHLBMRVG%8{yZt`23E&h^au6?r;QkCz%B!4<(K;$@}?HIVC9{33Sfm z-f*Z)?;_SEjaKTg1Y(xK4~7|y>@Co2f7yW0T~T2pgfK3rW!1LBPJ~7`b=yi8MPTJ9*9OhCMm?lzU61}ddB=9IOGRhio)+4| z>8x1*0{K$3Vp(kaIsd3et$m*_K1YO~OmWK$=S`Lxg2UX)J6F}IB)#Y0NIJ=+MUx(^ z=J{y{FIz-XH*S@>^L0vL;fFR&Ib#xK*)-)TlPa?#CeT&ZII9ZOEUA#0*(z~GT^<&& zo{vj(Xpytul4AB2iuId(8H~ZFMV6eEb*`c&tq`*&z3>~|djPfJ-KxD&y8%xb;jaW} zG58zkwl}mj%Re6nR>)HI$}z0Q{x9gdH^4KY)*9pzKWtwdWok50f>s0kSz5t+Hx9Vg z&_TLh@nG_GR(~|HyOEZ4l`a;mURWGl`eQ7xvibNuWh)aw9M`t{Z+(V8&Re!Wz4|wH zM(M+-c^t8yIb1GmO^d3?@mk9DVWpGTe{1PdkD<%e6auSi!}J=_Epqk;MD#^vzALr^ zMs)vBSZ0bJ#~{#6H`Y46l{gNJE_#jG34JfEO^QcDrlDLlzdSS1ZJ1@s+8RAmqi<;p z8XBEtjCr%F@%=EliIXazC24&~(6s`sU~4utX(7(zDj)BlL%-fAIyVyuw&jU}X#Bn4 zWv?jLSZicKFW)1GV-QI&5)~saDX79KUP`gqF7oeU0~#UxIvMg z<;STwDTZ?~$fINMx-{_uoMSKZ50oQ#ba*BaT=`1=GJx^Z)&(LLiWb>QA#g$gwM zt;`GZ{=kc^bYXJv7S_3hy7G0kxjSqC6B7xJ6#KPxKq}T)#`uHy+Nuj3Muk;6kh>9F z&qroQ;^OGz18(6|OjJB6fMmb0XD0x&%D5@pWXuyK*L$NS7T$SSZmZFODBe zQAvy;6v?4L?^0Zr;4QXt)GB*zim9BnWepkyNF?CtX!0z&{ zXB~bw2aUqjWvvAF>WN0IRkO|DpR~yw>#~u5GP!wF$G+-9t{+!6sFP3U_2F-jrUq_L z2jH$b-BW`GYy#Yya}}_-?_y7??8x8n^sa8zLu2Ri6?M?hg5Iz%Gq}HxglfgQ^+wef zw=1VJ>^L;wb8;hm@d=UvWyju##tC?p(-WQg#KYZ-S1_6-R_r=NHP$<4CDbCi+js1~ z2i~x7JAENi?ZYngA$s%UO=8%Gq5rCn%$uLwPg=|NSqj{sUlYtQbOdJj6oMHJdHqmF z3^tKqFZv?IxRq(suJbY_ScJZo&w(8ZO+}ewrT)Ujtkb}-bviKowV}~ zwqQSr@oVm#is3IL?RQ2~TgtuIjBCHdXJzZm=y^(~*&g1DdpI;%&0HMJHn+Rkx^&?u z-%TNSYZJYQu^pX}yf|KH0TZuDl=KJ?uKUbbLJEY1bYi1%kusfB_5rz-O~*}srqc&F zHz#trD3rQzX+XzLgmT`Y0oo~cj6X6mzR-&xSWbsYhqeLh4%fs~FVyU#YD$Acuqri0 zXnr*d*0fey4KY{;gH@T~(A$b632Y0E=?0su8&I|Mm*GeHJ$*g?hAMzSZlf7G4t_5n_2 z|K5Rq4tu^1QQhQS5K|Roxc&8Y)Lr~YSm==Kg~IZBQIVr$>ECwOA!MTNv@B-jtX6TV zf&s~}o^hWZ!n0t};1sC)iD)-0$`5isX|$-m2z9FPW%2{m({b-IpcnZEfR@iN0Ghr| zmJ}^I@&Hhk>wVf(@&FUBFV(b1O2kaj@%x8#{9e;04T}}7XepEAMH|y7Vz0_X0RceI zva0z6kDnFTh>lWf-6OW%YM$0D{Xc8DR3Kf#K_?DI@(t24!?u7*D~)uH0TbHfDw*m< zr{C45A+~b^Ot(Gy>hicmw#n1e_YxyRY0s5Rqk}#ZnWkq9Sp$#r<~AU8$}UIyH)U?| zn_D;4YTrB<+1D0QWauRpc0^w_;?!?~5~v_(1FyPYoT#g~aw>|tjy23gO?)uKu>m3JNKnp7J=1$J4mF@=)$36XP;#|s>)Mm;ljA>e3fTdJ5LSY_Z28h@7_g*YbtA# zja5xDbGOeobubi^H&A?{ZieR&hrr7xWcMz%;RMMTIUMhlD(kP55|du-kH zO1N(EWaYw{f6QZ?y8G?WyqbE^!c8dMW#WbNExAav@I_a8iM9R$4jWRU@Z9IPS^9iw zp^u3;RvP}E_`^xsD*oV8N-f*LYf5b;BhM+J7nh`Znf9=Id5FcM8j$=jf6!SkI)eov zKjm6n7u8i63wZ+TQBEhAC31;(?15wlMfRaje~}LJ;t&4Sldf>#NC~3;x`<0mT_1R0 zthhKqEf5%C;niP!@ndV>zVxw`k1jl4cW>DNwZw4UwZ3F|1FPF(QKda;fn}9(sK9&x zZr5!q%^s$9Tl8)2qy5owewG)Mh? zQ~NUK3=6>W<()H%&JU%GC!>HY5MXLCp|6|dR;zw5taHm%rUmvI*(JlJv}>0(y&Qah zNvi^!zeYb7l>qU$$m?v9zBu$wdW=SgV92A;meaDQ~naPMIxS>V? zOqb(bvN3yk|uvK9oZ#GWrB=eVi5>kWotX zDhDv{vT*aTgxH8}d{XBuTxR6mA6$hxuLt>ws5^4pwbZ1&ego;X^lGb|Q;$#b>0}_P>RrL!?RiPW z@7#;97-Pg;0Toa4I{0R`9~<>}wd~GA7-0=iVRHym0FjBV{dF^LY6`y)VpE?XE{k65 z(WJA_MYpnh%{T5O_jX0;_mJd1zjMdgioaP5b&0#1IQ*e$YnMqy^;21 z&-?komKtOKw*x@;zW$+$^MeD*b+2IEJcmgM$Y$GevTKZsZxb=Em9FS@AWaOjCHLD_ za=#UK^hyGR0CUk0J!6<4vKpxmCqA#H`WlUb3}AsNKz*@sA$IQGr74#S`54*kiXyrF zAo+Tip$Q({H|1Cc&&A#_9>li5mfjl%1-weZj1D1y9y;Iiz9T-ST zH0tpY9l*7d@M=SGP+^|1yIhmzeL1b_X+F*X<~#R1oH$htZrr5`;KpRc<%9V%?*`Dr zssb>CFdS72yw}I)u)N>4Wj95x!X|HfSda#DJ!In}fK^_ZwCPG75ZGs0E- z;aI=L(mkn(qcXb>GdKtU*xjFo#o}Le8Hfdep{>y1#4u>R`+iqQR6R+zK(Uc=5?gkE zT^cHvxPXcx7OSwM+uk!pn_-m|oL?(j4~s`6Yn&QVHYa)hP45FWsRPRj7ZE*rE@b>_ z$F`56UFuOQkr`myL6|uKqN|X1&d^yn)6YZZ5Q?Rsvg|WF4`=iGWUxQl2NUdPZhw{i z?{6P$^3L>1Cp&!2uj7Ql)oj&_$j#1TtBU)!Xx*~K3P|7@&t`O_26y!~B=S3qi<7&) z(}*tvRB&~edGE6w?alM5qA`<}+*7(6z6(?#-BBP1s)>D%tc~co3)u~o4W*nzuA8KS z?8k0C5XmDAT@ahiCGki4qDKR((iy|&<#XQ3`;>5gFL1pc!vDYs*O%H$f^mGkdA$Hj zSD4gm!JJItwsK{ix0jv1-ReTH&i|3Yc{DEPz}*rRdz_q2+`HR!SHI6^>dq78w4P}} zj4izTmNRmlZSOwCFu(jHB$|vS(~dvVbM6y)VhQyu0sHNdL4x>so4Y0*fb4SsBk_z( znoalcgy`qu#O<}qKWc2n7r*6)u{sdua<-L3V}=Nw<_A4dI$|$Nswb|@iu#v`s#jQL zU=q7Yqt86?Ce4p~LVR89T`Ijm3)qS$9oJ^M$v(5fUi=lm>h~eHFYhGVM5-~N5ta() zylSl46IgcV-8#^~AufLD6$D%%?=FGFKJf!-9s|Y^B4I~8;TiXPo8?)xlou<(`+E!)kZI1OZ zay|rI+jbQ0d-$>0Dq@P%2TqEl>I%~wlaaSu)}O5E8EkAQE6UhJfcmoPchFcGR8IG&Emt>^LUw|j3j$_A%d zb5c&W61jWyVGNhOA5Y|T#q$64<%^%1W`=EWborhc9AF<;*+gujTnse=&0n-r^Iylg zK0e9D??J@_pC{fIK6+11(pr$tO{cq?=CS-x_vKe9i|Hq2LaxE?3H`r&_XhjFj|0@I z0|DAlbXd?yZ%NF_Ij!4GpcT^cDEaFXNt7Dm8%|CTI@8x;hSi5$$f(I!PntJ36LET_ zvk*9Z{&Y+Eh1KHEjXL=t^aKIQY5E@Qk@}=>zA^jDn#|1Q#x*RfT#S8w z>$8OFp=hoCJeSV3qjT|7bOk=PA<37^*+cn1-tKmNhqvUs?DoCE#p8bNp+F6c6nLCX z%7PTdW84e7OsZg))|rjT_t{v@S$`CJqfCJooCqdsXwZ;1c62Oj0+>-$*`OdK48I)N zf?+>Mi1szPNqpVk-j*?K^k7Ze%xefx;*@-se6wvGD}a~MyG2!1EcHyRX$GP6heClq z$ZKh|EGNo(*JZS*n!8n}4GqjLm1 zhGPCaaZ3Qb+D{!Zi$||T?QAGJe3{jCdJNL;=;_CCCS6_yl;B7zWRF{)WhK*>fmU}H zmTG6tX42aTmfu(9_er^oM1Kzi1la)3OhrDDpk#ek zye9h@!2g0oIf9gf`o|sl3$+qmNL7)C$+nOkrOoLT zBehSWc5MN~UMBU)wD@G+7D*MY2FnTV?Ids3iNb%HR__(^Nt{8|>J`3GqIWH(ovNbk z5AI?3uKI+X03)*92_6K)nB6|2su1z+WrOV7_EaN-_eO9(q+EbamqToA5oELwXrZN* za13K&5*`kRP=DQum;6y^m4TjR=vFc)fd=H!;zxHdSNEW>5&7k`?UYo3oV>%QZ5gnXRQ3lhnFWSz~(0kBR?H$WU|f;k2C&bBdu zL6X-SI%M!-iyBN&Xl_KIt98A!5(sB3scx)jFxeL$&6%>g*-W(hL%|t>X!WQWY^#iz zqhCjDP;vQ@0q5veA;rp~M~xNW@;bmz`3cK*`57retIaKSj1_R9Sg}y)M<6i3F2v~t98)@;SnAxxDpdIbi-6Y zI8%l%!KiaJiIMdp(g#y~6_El>_3B=<+m|mlt6!uKAe~jTU0z zP(%>ra+q^=Z0a5t;$iG^-(iwNWRM(I$@R$lS#RBc*78Y$Qne)nEt9W1c7F>K21rkv zk-I$tn?7yZ?=!GC?j-vF>Ve(QA5O%G!K?vk)9&)7l!T$|S9wpHT4!N&5m&h&8^JzU(|`sF5l+dS3uhRmp2=5i=g=ga_=p9C#5di zlMU;r()9QbWpuhx&;3ZjW| zKST>6eAY_0b<9FPtd#5AOP@HDaH?!FA7{j)B^{5!q+D4uCB2V!wTTs^;3h5Hh=HbuUnqJIky1mF)C(j;6~+ijuW6q$)|)ei788_) zsbA@7!!06~GzeJ=9m>{LK3b|`_|@;14a6ARLZW7wqx$W%KHnJUx$FUqb}>=P9m|iC`-#Swy{_9P{)e zicImL%;4^?#a(e+j{dZrj_~G^e5>%=#Q%0ve)`|Z-~ZSDwxPb&p>Mzbsy-gp|Eo<7 z5=;oa%ivU4`1$Q~Fb$Rk#3XS+uVq)aM=VoHox%zGk1RCn0>Tx***h4$diG?rY5Us$ zb-w-e_Vyk4=i8$L*)hV$@|*ig1s8So2f3z-sIF)s#R^KOA-%ebbg_c!TjhU)C6pg; z2ENt!Z6okatf1=j*T_PmElDB)jP&X+e?__LE7m8=d|M8aTxdCho~-kzsZV?wdAAQj zdXbD6&EnA6-{+Y;-N8%T6rSb9mb!m_Ax__#`{YZvc~Rs4iT@<%q-G!lkj{$3 zPEAyVbXF0taw=TH0GK5NexeppB;Tp5B+7Ka{MTf-pyD980Rlrp1O?wmZ>_j}o1Er0 zt^in=VGKDnBEhJM7E}UYg0H%5+SPiNL@I|-6-g~dtO053asBKVvY=G-$|TSl5kf~I zff4K}A;4C3>XZCPYgYR62QZLK%436P?3J8Ah26v~=ZIu#~nel31V&$8rGIS2F5aoLDd3B;eg7+30v zeVRVQ`Wi&X4z+Y{n#IWA?uF znR}j`?xIWRMdF$c*j-{AHcOhjeouqZm2KxxHoBsph#@U!Ar(vR8Do}=o_^r}uYSaaZKrP!;IZ08*bMd z$%jH*W<@mkU_E@E}yv`5vY2L_s^4B!eHRXjU zS~}{)hIR24l+IQ!sCi=47m0VUjh!Niu|qtg`M^U1VBmz6H%`h+4JCd>>>wrz$yYe7*T8P5iw|Ryb zZm(oU3eBPHO!#Z2F!aoPbIu_2oX!3A#!}%lTo3%|_tr9*fW@V4TG2J()1yEJCKu_& znqzi@^D=*Fb-*EFp}`y%r<~4Bn&T?}2c$yOGPs$fx_|i2i)+_5@2w;ZA(IKs*k@VQ zU-Lw(~S)bYwXm_9iO15gZ90iPGMxw7d#xCwpVlvh0uZVJLUzd1^7uP5Gr z=pJ^{x)AA+!Cg{PB=n@y4F39SEtJ~d%DfnW3?J=PvhxQwKjf3r236N>AMKv{Wi?A@Dl0D#hf@~!_A)83IX+M&T2}!DNJx&Z! z@y_AAX-G6v!_S2P*{>6*NqW)Uh`xtqF`nk*_dzdBUFUE*r_aGUgrc>To{TMsh4m)u zOP)-_e@q{yvZ2uc!0&U;PQ2h_YCEA*;&3bdM}@cw3wfd)48im!nhvqzF7H6g_xP1= zv{W>20v{|_v8x7)*|}^?pMVw=qq2wYMdgvtuVzi1&EhU9b@pB5D$1>NHOr_=T#;GM z!g*A{t4L*Mo6Etj214IWXCLz>;C{-}hdvdR{JTQ8g0@u12MB4!!#k;hUHqIL2|XJc zks789Dq&nQ|CIw*dfnuw!_#sypK4JDJK^7k_)|kmoe(q@JlT05J_kG97ks@_kZ3`- zrCYXb+qP}nwr$(CZQHhOW0&o!UA@nLZgj`JeY@8~M&`qsk@>P_qdotN?w8&q_OI7CLo}eXSc=^JqZ3|=q$D?+ zI-q3dKh&7apKK_eKJKJE`)L?o89QZ~W=DIqnX(!f03W za??~-A(|801!Ac!lc%J#9{UpI;OoOrumCyZI`23UP9D6gb_y!~7*!P!HpfnlAcoWC z(r2E655q6+CTv$jf?S01(Gf?(yzb=0m}i5l-`YDjh&D7iwHHBc8b2tLk$e{*cu3h&PvL-5vO}1@NBN5H`y<6jx2Pcp}} zuv=Z!F`b?-c4O32 zF!-Q_Wtn5;z{VjCkel(IQr2B4`aCUd&B)~ztT)R8{OUi2i%TiotwM;U*vOLRgTQlP zq>VfSJVjQ4WB!zb1WkVh%HY@ODdd#K6ezpzaibzqqF|^gFprks8->-;-mGghrW&M> zmFOgf3t`$yRRMTQ+J#debekpH4xwP`V|MG1?a4ftkoBs$c&EweN6p7JT)9u_cAX$D z)ylB<9(6DB@B`sC{#^~?C-BC&^<~xBpwbqc@ni{>rpEsH&R{$6LlcEPYfGE*m%&#E zd@dm7w?xbb)n_bF8#S9xrB8$D1;(jlLUsd*QmO57f<_AlrqEt|xF%x0=i^JZHZg2oFP&hOrJG0x%p6(-@SJw;}nXAdZzvH zaiwOwt;J&3js$28ng}Au0>d-`=ltr5QfvUvKARajM;wb9>0k66drMFKo%urJ$g9*Z)r390 zp{zwS@t{~)_vN1CT@|U^+Wv>R;kfnZ<1a`hHXCKfcNWlSl0@KU}?Pb z3Xu`A(Ri(h!kHoqF;4MvSqKpQ6D|VIpa=*-YZ;xnsj(ZB!9zu5z;#l)&%!%X20LjtxTp>0!1aRx7jKYAO$jF4M6Qcna<<| zDG!R+WOVMco3DC$A&<#?Ir#96#SYr_?3(e4frMEPxqaX>m1Ixf+89KeZq$qE3530v zM{%a}AP6K`XhI8X-`y2dXd^a9=8&SU zuME5}*!f`rE$n){9cd()JYeu^AgPF17gXday@V9)+?7x+-7Tt*1P7l~G0-zR0K01Whz>zl$jv|&v#{P%T6 zS7`J|GOu8N%aH69?wP~H-mVxeI6&Y1TIjq~gWof=I9;jHW8?FAtvtyIZLFg>-%mmG z9u?^3nxhlFjU)lVB0xNIkv&pM!HX|3DC3!i{jaZ^J}L0&(YgL(0Zpy0|3g8GTtCwK zhKvk$uCA$jM($l<(zs~>rvuL5)cHNnxlgoV8g}~ZO}T0HncAa*C|JuY@hH<;RFg+3 z4eSyJQVv-r?voqKgH|;6){G%=jL^AOj=z%GOLY^V=ewd$M(s!#c@$h3Dxo(PBp{J8 z%LOQ>sC0lJA1-4x)iG{kXeB^x=L1+LGWqtBO}sd0*ecaHljF2VPBWE7!Si)W;jqbG z&(BS;^Q)K2G`3Vu>kjNUf`Rj+D9#mx9@SZN=fwCQ6JcR&ClFV1dn;{8<>4D2C@BG0 z&j;L&uvVtHA|}r$i8;yd`V+`{WE!ZTG5&v&oxKJytA_^!_)1@Vm@0QT$NrYigW!Bj z(PH)_#P^e~DUNu1)Sp8sYJb~tZC_!cJvW#*HST^iV%`!Mg~)4xgo*q@o%Bloe(AP{ z)3R?{IH=?$P<-V3KL>Yq8zgJXAC zCeBHt>~aSAt@;2B6V@aeBuGU3Yo#c)@UBS^WVvUSvo7f8NHkDIB>FLe`&jqCQr-(8T)ovSRDK0*_6J`q zmv#z9x_roxWujGYueJM<@1q-?e%*)&FW-S(Kz}(auZu-4ID!++20Tn7NDkboeiOAB zuhbGp#A3M2wy>nXjakF9`bXTKmGrd4x>f4^ser30RmDPKhT?elWFqx3=8fmech*A_ zNI%rz-0|>`9?P>xV8@=)7A}ApLSJBV>R;twNNz+xAVAg9-kZ52(Yq&twY}!-^})9y zXD1H)JEKi0ei53F6yE1vOQgU;;EXP^E}F_7#`S%x&>sxLLC1D68r_p_{t0 z>OqZ(U$s~YZ=8yIiXVH`%fg^yjEasuWP}|rQFAsj6vq5pw~0a#k7eBS5Tp7~yU3YV z0*$@S3bKa>S$WjEV{$p7KqSc`Bo&L9`W&noQ_lp1|Ji--n(oJoSU_Fx${P8koj(dQ z?^#L({04ohsGo15SeqWl;&w}; zr`t(TlbHZ39bSF9CG%)W=>@}-JR9Ue8_;bqNe%Tuq)ztL{9#9~Q+OrYKQ7N#X?z1L z+>zH(sL?lQ-Y;X+c3S;{(Y8YJ1>UEwuN4^uHF5RSv2Fx$tF*kuv|uY}sCex#0ke>M zQXp}x+zrkxh^)EQ@oPp>IvtiiHxcRWux7J+L5$&d9n)-F+|^HM-cr^5-xT{*8bX8C z6>>W*fhs_Y8OYnbupS1>nSrN|u>8qm%T04R!jV`}KeGi4SGAXDbFp?vMZe6x{_eS% zwjaRJd1zo(uceF+D(EacS@aT3T*gQ=YzTyDtFXIcjZkh+NwU)6k2=T-WGvwx0za(l z_ESpmwLom<#|5Yjod4WNXJ+@12o$c|^c9qA(A=Nf(M~R@cpa>(FB=y1C@i&LZ$wg( zCh*p%iT{@9Gra%^Q_8>J2eoW1%V@RlGS93$2V{j`fch_UWwj<>iNX`+!HG~k!OKw- z1t*i0qzGyofJju+HQiwlNhUj<`Nk)7`sNXnN(VE(B(D*S_d9MkiT0H7p4zHvpB)8~ zFTiB7W5gnD2h_<;<47@#nFzs@#jL?%j=E+qu=m+-+3bN$t!eqN&KO$!!;C#-Nu@Td zuGqH?&amd>FT&K?cU|@*z^~MB*N6vOB+QKwe_E=|oiTd{nhVR8Ji_ABvpRaVX);1F z!QVd{?q-u~o>8LZBwvrB_!FU~6h{R7p-|Jh_8g;EihrbRHn>kfeZJk_X{ZuHpx!v8 zdPae;25?)i4dHPta}2BLC)?AJ3VyV8!3knQrOD(#D42Tm1)x9@vkYztBt zUt*9aEM;8>E(UC-V;N z8Ys^Ykf+2|Aqzpc0mID{$WsFxRF{}QegTNnAz=6iSviphEX~>NSQc7KMn;76ro`ck zP3wu7eIWT7gz>`tlxKwhZLwrsyWbg|C{O`W{wIYOYs184_*EWXqlo~r>TWy8vID3( zR{RFk9Eui4xBZ}LQ1e-i*w1kt zn$kwu-gergg{oA)rd+l7E(MQ7&754drNtPRIpL1NZuptWE(41Ruus{FJ!%Pd4pLWi zlA@*V^9jedWc~X*e}1xzt9?g20?5-BNjSiI>7ezFK&(R$*oXuG;Iqsw2_#5-_w!mD zR%nYS-Md&0tPJi6mP@{+J_aFfMuX47#SpMTQKm3eF7s7NM${&mZZtb@%u*!p&#_kM zcfy5x^o!wblP)M~ID-|H**6q*_4{H~jhyWi?5Le*c5a$^rVi^4k=cE~*svx2UkR=) z74R@e?XH)uRcpWPy$`wUOhe!xar{Z)z$0GtbZqS2sfZaZjt59BAzmBiRsAGN*EC{0 zxIx;QQRMNK()MK54~xVrFjH-|&-7jdLz~%VB3ifp!c=Xkowe9GphM4&h~_~#bqes- zC3W$)@O`+u*gxXKb~tvU8mX$8skpA}fZZ@KFh@%;$Rf4b!sB)6Jqh{qDYEXA(YM$K zL|z&baWo{Hip5fWLi#|# zc_22)PJLTAl)~!*Lflu8JKG%+MJP4GDL{o~S3Q+4Tt$}07RMb%YD4nIy8U+0K{_x0FeLRLOPi`yU^O$8ynitIaoOSXV1a^8bbf; zSgsz>0DvHWfB^vhGu&wD${%x}_@1k4D3+$ET6$!Z-wr`AX6mXnGZdMsQwyX@?yMz@ zWNz5DSAFikZP_iMWU&Y+2_Qqmk~H4&zHRZ1<3DYmJD}VWQly1?5lXHGy%YBlmX?&9u~oRHhiw>015$SXlpoMLqzyG+O}@r zZ1^j4ZvwpC??_;19-%jRh`wu!ZKHUa{O|5Q$MMW zBkHksPRxZcTk>-0EIj@)wB{pK_^YTaED@YEI+#Q7w0FnN;ZPY3dT3@|JC+3-d(xQb zYMhV&OLhcA*^+)-_*6uvKWr7qY%S*_(<@pg%_T6aa@MpkK59Hn7?~xu{?{!3)!>h} zF-A4w)3M(7IsDg>*wjU$Wr16l_Q51WtjZ@lYQ_9`UI1LE*&+=d2ddW!rGc`;#r!+` zKYTcdSIhkEZDes+EJ#Z~Eo)Nzd)W!7R z!ne!2rF08c5o152&jAAu3A@<&Si<+ZV4F;liR@9h(OMrPnpj(-&AmI~Abd8qozF!Q zU>J<~e6%@u7W#?mJwk(JK-!2Q-Fagl(Y2KL2{j zz-@qy+Me4KhiYeSgqxa!^{pm7>l=wF^P2wqt`F047UeefUSaMf?YpzItz|^ea?=Mz;LlZX?y}4~ z)=KCWQf}2;JPM>_`Os}I6CpL*Rpr1oD*pBMrd*aMrLGjw`48{8AU;SGaf>TX$=?YY z?PQz8DQkKrWd)9BB0}rS4Wwh@4lcYOd)D&AefqBWIAY;3=v;B9jGUlPl36|eWlGZh zQ%X{fY3Ef^q1>qQ_QOXAJW?_R<;hjQR~GV()JLzXLEL9E!V3bNFg(|WnJ`jH7WoY% z#bcr(!Z!wd#66qw94CZHGw|_C z#%?Z>I~S20@J=kmM=q08Mvno!8F6{Q(k*jPb!k@ zgmUMyr4U{8GX;UN`N^eC&-K3R!se$vQJjE0Z`x4Yg1h2=`99rE-IW-|_M`y;{Ep7w z9vju02T^V=O(`7*oW6e0@h{GiI=!f+@Qqe9)e_NIl_?abK_0eH5t{6JzVr7Q&>PmE zHYrAsCa(&Wt*O_KHllVY0%`Xp!Zd1k)33VFdZs z#uCXu?Z3HkLLP=boB005%)<>&aVRYVlHqhqq=uM4WRV3tF)l#ZaXPnuWczfob9^pvNZeDdPOA{f# zAy>{|PfBfgD+4}>j+%87^Iuh$^;xA)Sv*bE_q(v9)dU|rcz5IoynN0}+YW?ku+Cr9 zdL%|$(eY3CU3~fWzVQDm$NYCfh_>XDm&TeN*I@$yNZJ7a_=mg(_+LroKgsHUE&u0? z*4EOF&dT{eDS`AMQTP8RCG7B6J8w%k?SD`cs6>IqA;@^z+anJ&Oj%F2_i0VnwYt+& zqE52{h!MmQ2mltCqK^LN-Fh0{7l=r8ogn!$JY-y4T)4lnJjbSt_5Tz{MV(S1^tZQX z*V5PNzWa*;-wa;O=llOUyuMsN#Sbn@zFmBb*Pqw-_xv7TUxlyd-}?N1Tu1-qD@(VO z<4#(ls;dI+q?l zOB{LYnl(Q9;xXeNOb{V&Y;R#OR1i1*!8IKR-&{WHcRjmn-#yXcGjUVP`mS?0WzVYh zD(DY9853MNe_>g{4lQY9>=2A>4cKI~mF&T^X-DgA;eThXmDELXw?{s6$^m0HDhrCh zAGW*4Zt>n~I`vj&`xP5NE%;~RT$BepK3sL|62{fY92xb)G^<7$$!vu?i)-CfYucJ@ zI@iChhTa&&rQ)*^4^X<1h1 zq@fVGk#J#U(xmNWr{m4#lK8SBjVxV@Xs%%KQ zsUUcz6B$#k>%FMELC3(c%Yit_6kr0|%%Y}J&oNg$&<+Q6O;`EPoaD;`S2`2nC7 zxtLfMc4V#nl2p!w*%?n3DCD=f{TGfV>gKFzmZ{*jE=Oc9;CsMMPw_MXR-<-pQ%jr7 zdW)|J0br+GN&;T~d!z^_P#Y<8z9BpKFr&B*TY=^i0DU{abx|h!6S4=+{I_UBK<@|i zJ=hX0jaydGhu>5`!0rMDIlEmZ?OKN1ekZ2E5@{ zlWV(FU@TSENn(_|dDqM{NG5xv0N1xp51Cw%Kc!_(17)2>y(L@|F$;0A8@;HU6cBC1 zG!t&w9S~LZy-OJoUB1*y8vxTpt+DdW2^o^|q~JD!OEWkm{^LpA&|b>0&VWPVyJ$V) z-e#lVhXn*M%nVt}7K4_*T{2Y#*usFdidcjxjaQzUI@p}OY<&Q0=BAJ`Ed4W;4>0S# zW(-G|1-L=!TX3_JK1Nv6uBzCcir9p#2o-?B*#{G1FM5B790UKcFi2(BFejjY`lu)&*fQv~HE$v<;U25OGtV4f-dghZ=UX;1rKQ_~k8&&-??r(? zM+H#tJ28Y%IKgW(z#~yS8c6UZc)`~nceA*@nf@^!X(^&{hHFzA#FuL1^u>-Jo=I0GRQcVIPb{jpSP^-3~|d+A^Mp1zEczXP_}MpmD32 zxf4me-?>j9rQ0cdyHoVJ&|@NzhUdtJUMq_2JX|bBx|67y@T74K!d^7`b%z&G&Fr1C z${G~@C^B<(2eFr1tg*s^WG1M|4hzZuJt;-hCL&OmC!%(#(_nF8>4z}?wi>KUD0ZR1 zrMy_>qP_5-p;M@js~a<>ngszZ5LYg<7vUp5+EgWAxrUu&^a2nX8*7SK#~k54Bgx5_ z2k@;+QMXeW2^b2GxA*@=wKmZ2>-&2D`p{nPd~8<-B*L*FIHH*9dSq}H8=)^_&ePNF zJW>_5EtUnnAyfzm2?zM{1W# zN5Q#sLhT`Cb$vR*S^|==sUj-2QzJ?91asIUz#*oVkTKrxAhU#x8V8z1m0Z|+@XFRc z;ShtLa8;Ov8s8eiAXLkHfCQ*SC15H+P#Q{D!oWt=0u(+RY-5UWKT=c7th2$BsL?F^J1p(H6xFwEpMp)S+^*FvR% z)YweqFwIHZFOX$qPpl;FoKgq^OE&?OZi0aKes1$Q^YFJRmy`bUT1P^2iPrA~zyyXW zv)PgIFM^7PM6YJqj<=jmJ_zC;2#wU9S8<7O1h6S^6P`F72HO@HVh5xnD5Z0T1*`JF zq}_X$%UTIdMFwRxi|strAn(Mdfx%G0KWm{5qHQ-YLV>D;D8Vw$@2(RE8D_||3F?Oz zk>Yw`<>TagD3p*YUxw*OElSth+PbZ!Mqz`H6*~3rh-|4LW$%b{Inrl~^o?~0o8G8) zMCVA=geON%Xd?IdO~@u!A~cV#5)FWy-%2zVdaxx~hzp4Nwz&6h{^X``C@;^wBDbvm zTAkIdp-Szpb=}88-oiUz06X@%i(K@UDkPp-i~sl!-Q*el*1@oP8+JAKYk{;8g~Qni z98HOLi~+bfV?x`t%XI7wvQ6yC0;VP)q=r{D6uLWtt=}u({ zpkegJbGMuc<*nqoM&C!Sjv2YHdH3G%;ZL$}YD7i%g(?H7?-~NGY(KuIu${HK9kB#@ zgCG{*Oj!Sf5e^WjjXcR^R*7|5!;4P01A<;&JMHxYm-l1F9~c@sOZHrnAS=hl|G59l zJscsd%Y6DfFa{1{!ClL3Cy2TyBQWvrx}3yOK2S5|6{7JCfGAV~hQJY5C<0EXApZzg z>WIM~Wg2vn|HPl+nXqOQl#@vJ8(fyG1+#_>OKaem5Sk06v}Wa4SX9_!iiHxsB0R6& zeE{y+(9{Qom==SFftgc9nF77|W0lcL`eP?%83};zbQrNQb@!vhUuon-Tc!r=GE z#RsKHs8LNqwr7Z;S}r-EBp}Wak*%7ddih)H@8iCck7u_ioC46lP$0~HJNx;WDLaSaWF1t6y{_nu}IGZ z)GWdSORgy>rZ^dy#p3d3aapL{L$K9m?ENU2ByfAE!xDv7yLQWgc_(l%4QHOz`H^V&%YcpE}8TM+3CQBRoc0K`o1!ftuqB>&1 z;Ld3gm5dEz+{@%JB=Cp;rke0X>F`iIW{cA-G!Q7D9}iYH^UgEe#tEDQU>6E!R2md5 zYY-lu8r19H4(7Bf?LQ4=Jar~q3B?s%!Zy8{1F+3oxrHbdpjQFQb<-Xk$}O&ae@LjPKU)sLd@_~f*;uM6 z3U9(-rdIJDS8mX&#J36Od3|sP+3Keyxs8-{AR?oSMyj%si00LO1TBt}(+jK8m$%`j zrO;r(XlG1{1}hw)%lLxgY!+4oo`$lOuPiw&tI3DEVJdv`)`kME+NLp;N?FFJ1(b~w z!e&!|#V{ZAvEUs)Ai_%tJi0Fa-6?UP!$Le@pYS4`yRfi3z~QmRe<4b!-A^HfkRST> zu|UFOmE;H{$$3t8AWFVhkRF2Epc6w7i*e{D!8wLv0Taj}2>De(!n@$!d^QO}_2Wv5 z-m&j28gnX)lAcC&nqK8GN`vmCfKjJ_Sr_O*k(4$ik%~#M)Fv0fRULz764J6nM6E`l z{2S?7Qo4dZWNGuPrlKmwe|tnhttB#e=8EI(o0S-NUviTvT0=A>o)*!YhfP|U_ft8&~HYRCQbwSpB^ z(GbCiW~Ao#Fch7WWuCQxHc(@+qBXVn`nym%0=1|X-5SxNi3V(#kt{;dZ=U0;9|*Cm z!Gbu0xhoTgr(o#h$pi<1OZ zK3Yb6MTb!gWmPBM#&(`-D$9w6KX=NcGhJOh>N}_3Jo>?az@!x6K)#@=d$wj$g4c%d z!-2*WfYA7|9kg~X8Y}X(D;%{Z2*(yk(O>~YzFE(lvJ#F>R3@mqE%a95y)SX7=(Zph zi$O_9XhCWEav-n_#J$2La5s=D!hzPvWU=)d;DSun=bWhngD;>0*&&&GBu74=17IA4 zs5K5J(2FJ~T8PhW6jhx6sK>+-dR*sP9BA+LqgzX`rkgz2l&ah!mGgnKsbg#Hmw;xXeT4?(@;)j z8)`&i8S~e(eLjC)x6I}sQDE&X!S)fBTxb|~F^@vp;C!%7e)4vL@h4|}-$+|M7?=%$ zyyDU{HpYe_8$Y|Yr7FP&f8KK|Okkt|&+%K%>7lD(gQ@9NXt4N>_PKc$05n*rm~x-q zLL9HbnGC(W3nzi%F-?NdCm7Idf=IM3wObTUS^_LH($fq$O{Ss}U*+!AG%s$NH`P#J zIOi(_qPi8q48{%Tqj{1>Mu|dd$;bhTMp_VJlpx7Ael_z@l`ET1)g=PKCzH)t>f~xy zTLm$Xu7-e-sFSiM`vCBe|3y%6G4l5I`urlU->s~gii^HqHAa{9kz3Q&Ni8Z(YZ_a( z`MH=k69$7S%$WnPSBLM@BtbogfVT7(Ae2q}1ZL!CinsKzs}sX%pF}+2+8|YQof!JN z=_Hbi2kHfxih2y&tZRM?IoJ20j63bFX(TXni(i@A)@v-x>l06^ub;*&p&18E$68(1K7B!P_s@xd%|bkDw<2-Z`fD;b(`Yi8 zvdc#w0mklUmpm_x|IVrUe%by~xv|bwx0oR84NgpISqAa-${UjG#2;HeMb|-f6f;;aAhpBC!wRZ2k=T4|OL|U#))~tNNxD_8V8?eiOYp>9etLylQ?vE!px&?(tv`o? z5k2OSY%VIl9kM0$7ej$>+M~pU>4K-dur^#N;m#qn1Mao5@@g-QMe3DKU-VgV+`^th zI!K{JvhgUjhR3!#uxd57YteyBTkHA6>tNRocF-(B4_5ei2-tSXW_;>C>S>(RX6|eA zsC#eRHlLOc!5bj?=vPcgi*d~@r78ip31LxXB{PRb4(Wr%S2V;Wouz7GND%Xkg{C#U zm&lj3BgSN2mJ)HT_cdaO(JZwM7IzBiyCT#?`t>79Jr?!?DOvMd6+$F#Hg`$mZrKz! zE(Sy||7r%C%NQK1*tr$%-@7EOVwQtP4x>AwhN`!K_Gq-DZ9p<>40!m627WJ+!uGkZ zY4CO!7}mt8Z`0qt@nidc>U ze&ttFt~a{sQ>!h$xU$|#!*;~w*IQt}^j~}FZGmxmYZ^ki4W1_XPSGc!HaMwKq-arh zX|b-8{cXt}4_b+q*~)%lL^${Jkk9sa!~S#yz9Bn=MZStAyI!2kLG3}Jv}nQ0$yg1X zXL%2k{@7$gNrWEG)$P$n=+tub9z$xi-t@$tA@imfw94r-OCPvqV8@6k`KzRc!22tg z$B_c(fXKUa94Ua!r9`r3kZl~%VjO5I?cE^!C9B9dm?meq0?9H)AG3TAqhAA(dFuw~ zCf&LN=$0=EPWRXj19EN~P+=A`LI6aaeO%zXnaKBZG59#~K=0tvPQQQG&GhG;eWDY97se5G-`MHD52K?Tj1{F8tVt(wFuj_h#3>eel91-N@fP{LDbuho(DE$d) z%YrNxg-zIabs?~EV+fy;khg|X+Q|0PZ@CuMyo0wmrqCg*;$p(6MsYwYPuU=fM3?JPt5BIWl^rA0(YkDzMx(*G;EL zArU_s<}O`QarJsTe|Nrr1!vzHlJ1lin)IJ>Z!}+05%OBjwgG%?M%_Jvf5WZ%{JC1r zzFKxe=KjQS-R0-C%zc^chMcnyz9ge6;3s~b!X*9%ep%}Ix|YqiVl^OQzJUG`Qm*H2_u9hNvtAwpl~J8I6F|7F!2JTR|V zt7Hvt^>Tuq-MTFJ>g5W{GHe0+HX(rYIF>x ze#I7#rvQaicc`l<07Uhw;q0 z^%l`OU!I63V;m^l3YM~>MSF|=76;CJdoM-w~iV&3L16c@76D=OlPkYbJC!1Rw(#f^=EJ zexGlT-}nqRPDxL3EY{+{oQ%2$i`cle)?&E|W~_2`1x? zB)3)^vpk1exG(JkY~-~+0TEK>*f@oztT3Tr7}?h%uCO-Uh5-~L*g9yX|El_xG}GsZ zZ&t5EJ9py?VGNE$JY9s;=Sjz38fsUe^6Atb`0+3>FFE6HUdD zG7z0ZNVh<{cS%oa7^B+33Z~uws&p#H-N^GKw`JuSt3`58n^$8jnsdqi!awM`Hc8EJ zTliV2GW=Z?Xt$$)nZrwrN%qI~!vw~XFqXtT4QX~x#*gBe@urk9PejW|maZ1TVx-Mx zVY5r5uP#4ZrFh$mo?C_)nETeV3<%p&aq{|##llednTV1JKI87h5Y#x=&Age3q*5|O z6QhcnNHm|kFO&!|^Z}D0In^X!>1$$o`ty;uGKoJ*J9{x^r&m2lqYX|v8Yqc&hfj%M zjlCdkh3udMo`FevVaRHXfPZqAW{f{AX6V;*#C%v3Jo4|W9pEj5Lv(9W)o0sA)lsA8 zS6Y3(A=9)S+KbDoj{#-$=-d|TT>OSlF9$C6Og54XcJp>Mx_WMutGaavfnask z`&7R6l;63SEqQ;HQDDCg1(kuEhK5{lBnr+7VV_1)^$0~-_5`X0=*&%%@hY0;hQ9DMq8lHD;F*7NsF=ewKHicibm@XvjP)3EP z`Y0sIlF3FXdYiO{3yeG6?!k@j0pW7z)+J}gCbT3%t@x&=_ZCv>Yr4#4`kY>Lk){p@ z_)u?iEUS9NjzTL|;Xrp}j`R3o$5a^IteT>~Y-K&;}2lHs9DL_M9zeWFv(?!R4 z);-6D5Ih`5uvn2UAp_~pcKnNwqfDDx0K_|l=!NH`SwBJKmaVw-`gEW(xjnDnAGWWE zEwWARTyM+S=c=*qEGXaigNA_*hvMRX6m6Qc#UUZVJsN5rUet?DI`zQf9p@=r{&iVE z`iPigT`gc7f2B0L_AX*;-l}776(`+!+M&WT<;7*=MSb}go#hCG=K`&}7U2Djz_lEeT0U`gYW zt?a|tMuyR>q`|ViFCh|&!mUQ&hN=L|f#A^$Ri-SRjbceb9E*m-Hk1OzD1D6ZzE|KD1W>O;(nH< zKY8fATdj@GS|FXDa!%hZ6b^o_5jvN)4cjFSZ z9A_O}9AX8*>`u@L2-3G@>sQ^#rhcihGxTtOzWU3W#RCAxhebS9vIM5bwbgcv@9^|B zdcHO*V>{iDT=ln%eWzTpMW22W!eB=j+XP|hRXWYm=&3R#dE#6B7exBe4qGVIC2nEI z%HmkjA7vFIoPvm6v^d{sJ#qf7PL+V9W~ZJwl`&KLRZcA*X(rP?h?RnbuCz2gXrCvt zwxxpaQ^f;sX7WTul|4}eMCV3ACQUCU)aXbh=s+18n;x~(lC@Yn&15NxH$jujqeT=Y zYGB@1I;rfyC66OYkf0xPX?XrylSu=zy1dI|^3%IQy7ad*A84P>j;W2s8%vTNlW>P4 zk)-c%*UEh3ZO(afLHlBY(lB|OKW@azIgLtAPN_>)g*=ileq0|HIi3Ysv9vQ17oSm&wr zky?nD;&iN^$raHJ%`LR<(EgsXVR-0QgY$v96~P-kAuy)mlnK%FOet_;CH)7R-clfi zSk2TS!6OL|=t<-wGB|b_=J~*im47EHPOXi=f}6bgv=vfk&H$b)E>TY7D_c3Qbn*N1yhhyxc10VY@h)(!1SsBKNZ* zYZCVAbX@ltpxCHsCkdazf@y1amF;w=sl{Yvky~ZvFK;seH7E;PbFlh|tR~i0LM3`M zh_}@QV$Yzb_P5s5O^uZ|Is%B=Y!gaXX5ZiDWWy8u=h)Eiyke)U`=05vziRXF^%5If z-ABFbPU>sFv|oA$=N?yEJ;z@56nps%RvUFVVV?$yB?~Cl4bBi8gVqTDp7yc5de-ZU z-c%Md&VCg`u1*ltVs@@eKt+OH<~F&)K>8;)ZUoBWr%&hjCv1PYB?}MZ7!lj_w#ExS zS~c`_&jf#;t!&kXqUV(^4Mv)uJAD$lEcr~ z!f$Ee=kMn%&}3LYdcH-ydup*dn6TAKrEj z*dw+Xw78ueUKua;IN_u~FHSmy!n!yB0QdS??nc~zKasaPhaNo3EIJ;a0=UiOuTa+7 ztHt-ktcBfGgc9BKZ5W(g&2jDQb|)RTW7vo1Yt54=dl=;MdM&1WUFQM`D@8~Mg~?z;3vh0?w~<+$-QLyQGQrkLnp-W+2l(@`WuH}1Fv zTbriC3QJ)WT&{U)*l&>~FhBl9VU79TXR|e2C1{EkllT(X;<1&!YziiR!wl0HfU&4>8F6ZXiU$Sadk60ytLOXQuRqpt{7=0( z!ZDuU!7y~;UN)$-(Jrv{REbqz?yHX1CUG%b*7+LZn44t13{0}y5^eFAnJC;&k|6b1 z%qPnISHg_NV@Z4Ejt}Ps%ge%xZfzB_i#anx@P&K%pvb@4x zF&bIpS_(Rk;}FA)YuOkuzMqP{U^&MhW}e6E;t1t=kiucUOMFRNquw02jh5CQvUKoR zkJ+*tvQ9IO_NysYc|0_8OA;+&g8Vid3xalCOZ(#Qz>!~{jS&Y~CmSgCeb(AP?HbK< ziAW_%me~yOO(1|aRZ-A$8C0RIkH5hbdeQlUW!WvlN#w!Wrnd?@s&~E{cIv1D{GWd( zLx7$V8x&gkprx&yWs+H*UyZ|UuU-^^T9EBL@4X7s(@X8jRr;pZcFpNsfa~DyOVZJO zl$W0itDAW)90~oqi?Wdk_mCM$_lPVmwJoa3waFU|uEp6fz3E^i%L<2ZqGf`6G#5vS z`=wg_#rpA;SdJ{a#LAtZ{=i(T(|31$67@`cjzX>&s})~jd#IFJODaV#hwZEMbM9u# zV1MqPw2uoW#Q{q-cseF;^QZg=5aoWKnjR;AkQ2>t#;@_XWNT zIS3EL7o}P{dss%is*TpZmc!#|T!((adGo;tKU%o)auftK5#hDh$;1P zWxRzHsrv)b2q2G7K>oqGjM?RH?cA)e>@=E4vP7)t+F|W+d|P_)#$`6Zy3f2ZmN{kZ z1PilvHpP0W$d@G7wypUpOKu&sU9806gf9;hqiG5f{W)o$8+~alE}~WtZy>t{-raP+ zO?{_G-LI0GGMBb1Q01hUn6RYRucbqXwZsRCfo8Gl&*TxsVqtJNv|^qS-4Kr0YOjOEqaSTfRO%Q*V+@a zp#&ySk?Aq9NVhJ2?FH`#6vUT<${+3%;l{~I)W0X4=OX%eR6NZhB@msRR>nk%%h+}8TA=_L4t ztcX_NpQRaovF6@c=@d1bZ4>j9~JUjO7LLaE#iy%-~==?_VSK0S~q zMGCq;f;X>x82#D$um@k3erhqN!#aEnkvCvYpeKGEgiihu>Oyn&-nrs}=xuX8&F6i! z{?3eLNU2jVoL)azRzhxlqe;FAm4Z$^L1~N?nIBfga*Q4T8 z9UxSG9_sf|q9jxy;i>Yl?zWC0SPT`fRQiR65gyYTZ>C67k>}Q@>`# zi~iY%TQ6Pot!Vo2jN9FE6qasj_QmWy8%b^{?7r2!??Kr9Lfy2qDJ5@7Nvy;&;O3FO zawb=eN+tzhIzVp4XX?KB%6F^eJ1BA)dKZjxc zS()fQA}bN`#SKxK?niZ`PPO8sh!yQmq(JV#^Az_Wg6RGpF*r9*_9+kByDVRdeUC85 zuyw?GdXfw5MP#hegSF%j%bFPR#;v{yNPIpJ_Q2f8bGe*lXMYLMLgvdL7*8}kMQ3XF zbz6}pDB>9X#_ISy_-~lvhj!Xm%tbYPz8u6&m)*0UwA&-KG^_@BuyIed9|%+OQ!QO> z)p|1sxB~3jO%^KSkXbyrXJ+UJmP702IB*nCGh;v@-2cJYIRt4IZCN-~Y1^u_ZQHhO zqtdo*+s;32+qP}HUd4;(=t&QHdPjG3&f5E|wZ0@xK!wL*I{Kn+aTkcrP$JBs4$UL& zFWK=3Pi03%Pt@!TH6oxlPmCcv#s_wt9N!qA3P9kD46+T-74KlOB4c{(q+?=#oGYh% zpw%NjWT&O39mpv3p=|d{){|}}S5U_?R~VblNMNhAI&3OTq^)61EF3~i<-QS*z!g~5 z^PgYohqh>Lewn71F5md1bn$`H$-l&!MbxzECz@rVfIrcExO1jqq6d+tEB(fVIr%z0 zcB#22ue+cvJez;x(hEu4jGXxN*z~bn0^&rDX-f2l|Am#94AfF~X`n-zz1m08B=*r1 zvF;s<+&i5{TZC3L(yU>Y^2q#^MIG{Ob3H{5wDc@gcMD=mkAl~Vd8mgYnn_gADAr6t zWBI<$%Y;myNg(ODfC`&Ze0UWwMVoA@*<@UZhwgP`1}hV!H}Xj&M-2k?wHi~Be>;}T zj$A;9@gMj|Mk0a#^OG~58Wycfb4+p}+cKfcYj+U*ArEoj9pmR8gs0RAg zlWY5iZ}P#O-y@}SO%w#F_x1DF?v_%qCr~Ga3b@@~Cu+$Xcx0bMu}{TVDm@e`4?Aw`s4 zl#{3`qR)XCx-6pqv9AI8qgwDmm@HN8%^h!4ZIF5rV`%U`n4e+eZcs^Eh4Aoo^e4Hr7PlD`1tESsF&~n z_zp~+#19s@F#FvruMC&)e&R?!SuLyawgY>Z*vVTAq#5!wgp_2W%S>n_M~=8~v5aX! zch56=h@hYXc_aPUZ{FravJBCKINgC<4BJ<#E*7Kcn|G1k#10hr za-{^y-UiH+JlEj6()BIFR&@4n3(W$iERz2K@kzZ+dF=e9m&93}MA$d2ST)V$zEVw`dHO=Ew57 zz;{GU6Nh|doTqH|bFRimtumMOoFb&#sg8=|Of_s5kQ9nfF-JY#d}X(2-N&_Z04hw# z$ghhtwTIQgJ9LPy$b9KnUs4M=OU>q7fUqJ^PEX+2C7O2b!{GT0yJPTbR0h9!m{5`( z%o2+~BKqM+Xc7GoD?vxSRY_P=AMjt<71eFH5Fo@Blg8Ox%y12Gy<5M{N?*@!j*^(P z;Quq$4fsc1B$gkMK~PcMzKRc4;UZq5c~PCrz{ukU$j`e)hNCLdX=Yg>XG~4F1nj3Q zVTb70h1`!-p4&u2UwS*lNi=E5A-92y585TeY~UwA?>}_X*U1n?e@H~8f03~({cN?9 zQVF$t>XyLNl)OG+b4JtBtM~nd)1&v5*iG4fourNRX#^{E01k#p24)CRFUcA>)~f9= zVbZIun@7L{ubNhP_BWWOE$T(S%nOC{ZTer$XE(&r{KT=;7;>+yaiW%>1uQ26*C%sE92ws0phbj5NoxjqE z6(4+?Bqu=NaBBHRZ5lngs78b>pFS0mSXXEo)LihcM!?zc$-0twEISQaGkvUT87O`j zqWzqdZ0YfQL`Ww5t)?33Rs-vBG(Ph5r&(%bwaV9?rqPlo-w;+LAoOb6 zU$ahC=vK%{*5itCXu^|)3%h{?`zhZP;HkUtZqrDZq(s`40}^nD(;Pn&#L-DLba;qt zfFZ*f-T}ye6Ck%S<4hg7slqK{XY7#YSFM|*A1k);d= z&ip)ep-I~FRRgMUEhV6eX_x*hY?8px|`JZlTriI zVk>G{l)qYF6vv9xHQAgF#V6`hf1OxnT&~a7MaTs9q=fL?r@L=p25?vf+4Sfx8hfDQ zdJYX&&EluU!zGf#g5AFtHwK!8bb6HuFE);#yz5Y`qtybdJ?Ah0YPc4+;q9sGRuUHf zER|@;)3=(_h7uUlE=lga#-*>?X+k$4bL5KC49jK8A(}@+!c?ep{-IPBX}(5kA$V*q zFq0ij{*7t+lDE^>X!4X83kET{)$AYR?kww)Ur{3bA-kq>i~!%h(s0h&EU=brpW|qd zy0EPM5@TLbPUdO@2^Cf3>|{H!`r{dl192K$N%b(@dx^eJ3y14qWRM>AVsZ9OdzS{9 zt5Jinvta4*hq>$RDu11AW7SRj&vHU0I14 zs|?7Gsl$k-AkT1R&b4mxy74j~Alm)@_oyt;rMAC*Yi4gSa@AW`TpJ*|X1*{wp|e`> zPgGE>QQoI_kN?AACKt``3{D~wuJBIag;HO!PBfTp$7yvC*R7tZ}M zxH4L7>hRSy-1g1Cj^zy?z$pJ3-rR!udHK$}%C*=>~keGAwb_4R70M;nGNWdNR}(d3NtRAf(D6_>txm=C-PU{JW{tr z@-Rg8U|;k`G*i{*Ju;_@s=Rx&NalZblAgwQes=EKI%poUDDY<=JRZDnFYWn0Kh^X8 z9xk)*eji5J|NLAubt`s-{-n+Vznr>_&rWugPmFJS`oKDKaPr{I9t<1R<1UsZ3`+%| zOyyoi&dSM0E*gWd5}5RUDZ#E59gnfnh=q5ssswTD2`a zTKMy`QvJERb=2IZ3Z7bYY7e(J3~1z$Ui!GYQW>tP9qSKySE4^;nM^$BJUWH;+|?9s zYRl9W3o51v_3b1EjvUyA+I0=meg12;a5=x7E6?YZ#9t>bF76|-^!s0?aH=lVF`+yI zHdWMDaY()Bj7zUN(fsLlp271+2-sq-0y?i^L&c-|G8*MgoHk>3^e&y1`(pD7GPB>T zCp5u8VA!WoswRz+f8gP_8vJF+h2Ikr+t`v4#yPAa%r4*Dv*>;7O_)2_*SAj1DODDE zBnsK1<&&ffrtFd#<;2lsHMS1HdPsPpXvSKtsxmIy+TZ8-wuxPpkPUCp#Q-}qaNiRI z8?C{svPFd?>}qd;O%vOO2O-ves-fjvyvJFB&%C?^w+|0@*yPrzArlR{U7OHo77r?= zFJS_u;FPbh4FpNHu$dmtPs$9{!#0}5D4LIBjFIRiHYG1L!SeRBlgA3H`zwv_N5^8m z3m;wVKls4>>L~?!8Fi6Z@vSu_ZC?$Sr?yTwC0MFKV*bb=qKc*|pcA8Mj_=d5FCAlP zl8W005uvhTbAyQ3#PQ@8rxn=ny%+kU^ICrih)^yoghCW!0xy_C-Ush|CE-iF4I(j&6Jx9M@Z_brabD)6PMd;&?g<) zj&|gXt<1_bY&|)oU`TRTTM6I&OyxQ}E*}kk0!5zUb-CkT1aL$rbgM;$7|KXAwB^P) zbMpR~yQs`#Q6FX+_OwKe`oum19tiLpGq-FOzzYfqD8b`BNQ<;{ID;@a;ZYM05{y}Y zSUZ12e;PAwNva8OnZ;WC0{_tGzI?Fl*cwRYWNaRQ$Z-QXl@>0DT`?0z8)q$p0DoUB zi$3Xan}J@3ls;{Ni{l8clcdt6DAJ*7OYK?&^I7?9BCb3@*1$=bMjQgN zX{|Mgr&()iQM3rlGO0P^uO02uE6i88U8Ct;vJ`$i#XUUrCuFuv>!Y<>(~^O1XCEu7tkl+sJ7KyC@YLW#S|>u-MiD|8VN^r3fnOkG9M{Jdivxfo2GVKv@I@<&tSyTS zAz4I1rIfu9W3H!!4K!r{{)Rx6Efm(kfp7F@Xd`_h*fojZ|5w$R_qKbgv+0=PXSj+sU8D{w&9$^xHT_N8PUeb??07|h*y zERq1$AG#nP%l>ZL5NjrL$w&=q#D&F)rKpixct0AFY04-tM?I6v5=op@n-t}Wssg*h zz~)7&2P(QZvZf1VpaU@ObF+j{#>ly_*PE%pD>IWo4(3{*VZljlI6Dz31knW!dI?oU zsjhYW?yp?`txtxS&mag|%Qc;6$h>rb@Em8&^CH)WI!slC`~fE-60JgytcbR@w1gVX z8biijdSaDGUPkK)znQ+2n8c6f!JS_^U%CCJ>xe^of5jwZ6Sx=klT|H+p_ofLPcu^} zJ+1m&T2gym7%#M1@m{El3ZSdKNav)|2!`P zV5Mlb2krs!Ja2Z+WCN6Sl!EH5kRh&r*x3GY@Hq2Zh1+1lUjywYqj}IfMt^(sPMJm$ zX4QKt$<%1k7d5b;69~@)#Stow9W^%db{5zC&L&rz%ObA$5o56&QP`W$3l)_b%-bH~ zHR1MQLhn1KOIp{KRd@VX%bEB~Q0jM#;KnCW4IRYdxQj&w#8VyTt25|!n@ƁBpe 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 z%0A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 G3Gja*(}3du diff --git a/easycoder/plugins.js b/easycoder/plugins.js deleted file mode 100644 index 908b4df..0000000 --- a/easycoder/plugins.js +++ /dev/null @@ -1,126 +0,0 @@ -// eslint-disable-next-line no-unused-vars -const EasyCoder_Plugins = { - - getGlobalPlugins: (timestamp, path, setPluginCount, getPlugin, addPlugin) => { - - console.log(`${Date.now() - timestamp} ms: Load plugins`); - - /* - * To include EasyCoder global plugins in your site, add them here. - * It adds the selected plugins to every page of your site that uses EasyCoder. - * You can also dynamically load plugins before launching a script; see getLocalPlugin() below. - * - * setPluginCount() sets the number of plugins to add. - * getPlugin() loads a plugin from any URL. - * addPlugin() adds it to the EasyCoder system. - * When all the plugins have been added, EasyCoder starts up. - */ - - setPluginCount(6); // *** IMPORTANT *** the number of plugins you will be adding - - getPlugin(`browser`, - `easycoder/plugins/browser.js`, - function () { - addPlugin(`browser`, EasyCoder_Browser); - }); - - getPlugin(`json`, - `easycoder/plugins/json.js`, - function () { - addPlugin(`json`, EasyCoder_Json); - }); - - getPlugin(`rest`, - `easycoder/plugins/rest.js`, - function () { - addPlugin(`rest`, EasyCoder_Rest); - }); - - getPlugin(`svg`, - `easycoder/plugins/svg.js`, - function () { - addPlugin(`svg`, EasyCoder_SVG); - }); - - getPlugin(`showdown`, - `easycoder/plugins/showdown.js`, - function () { - addPlugin(`showdown`, EasyCoder_Showdown); - }); - - getPlugin(`vfx`, - `easycoder/plugins/vfx.js`, - function () { - addPlugin(`vfx`, EasyCoder_VFX); - }); - - }, - - getLocalPlugin: (path, name, getPlugin, addPlugin, callback) => { - - /* - * This lets you add a plugin before launching a script, using the 'plugin' command. - * You must provide a case for every plugin you will be adding; - * use 'ckeditor' as the pattern to follow. - */ - - switch (name) { - case `codemirror`: - getPlugin(name, - `easycoder/plugins/codemirror.js`, - function () { - addPlugin(name, EasyCoder_CodeMirror, callback); - }); - break; - case `ckeditor`: - getPlugin(name, - `easycoder/plugins/ckeditor.js`, - function () { - addPlugin(name, EasyCoder_CKEditor, callback); - }); - break; - case `ui`: - getPlugin(name, - `easycoder/plugins/ui.js`, - function () { - addPlugin(name, EasyCoder_UI, callback); - }); - break; - case `anagrams`: - getPlugin(name, - `easycoder/plugins/anagrams.js`, - function () { - addPlugin(name, EasyCoder_Anagrams, callback); - }); - break; - case `gmap`: - getPlugin(name, - `easycoder/plugins/gmap.js`, - function () { - addPlugin(name, EasyCoder_GMap, callback); - }); - break; - case `life`: - getPlugin(name, - `easycoder/plugins/life.js`, - function () { - addPlugin(name, EasyCoder_Life, callback); - }); - break; - case `wof`: - getPlugin(name, - `easycoder/plugins/wof.js`, - function () { - addPlugin(name, EasyCoder_WOF, callback); - }); - break; - default: - console.log(`Plugin '${name}' not found.`); - break; - } - }, - - rest: () => { - return `rest.php`; - } -}; diff --git a/server/plugins-sample.js b/server/plugins-sample.js deleted file mode 100644 index c1d0f1d..0000000 --- a/server/plugins-sample.js +++ /dev/null @@ -1,110 +0,0 @@ -const EasyCoder_Plugins = { - - getGlobalPlugins: (timestamp, path, setPluginCount, getPlugin, addPlugin) => { - - console.log(`${Date.now() - timestamp} ms: Load plugins`); - - /* - * To include EasyCoder global plugins in your site, add them here. - * It adds the selected plugins to every page of your site that uses EasyCoder. - * You can also dynamically load plugins before launching a script; see getLocalPlugin() below. - * - * setPluginCount() sets the number of plugins to add. - * getPlugin() loads a plugin from any URL. - * addPlugin() adds it to the EasyCoder system. - * When all the plugins have been added, EasyCoder starts up. - */ - - setPluginCount(3); // *** IMPORTANT *** the number of plugins you will be adding - - getPlugin(`browser`, - `${window.location.origin}${path}/wp-content/plugins/easycoder/plugins/browser.js`, - function () { - addPlugin(`browser`, EasyCoder_Browser); - }); - - getPlugin(`json`, - `${window.location.origin}${path}/wp-content/plugins/easycoder/plugins/json.js`, - function () { - addPlugin(`json`, EasyCoder_Json); - }); - - getPlugin(`rest`, - `${window.location.origin}${path}/wp-content/plugins/easycoder/plugins/rest.js`, - function () { - addPlugin(`rest`, EasyCoder_Rest); - }); - - }, - - getLocalPlugin: (path, name, getPlugin, addPlugin, callback) => { - - /* - * This lets you add a plugin before launching a script, using the 'plugin' command. - * You must provide a case for every plugin you will be adding; - * use any one of them as the pattern to follow. - */ - - switch (name) { - case `ckeditor`: - getPlugin(name, - `${window.location.origin}${path()}/wp-content/plugins/easycoder/plugins/ckeditor.js`, - function () { - addPlugin(name, EasyCoder_CKEditor, callback); - }); - break; - - case `codemirror`: - getPlugin(name, - `${window.location.origin}${path()}/wp-content/plugins/easycoder/plugins/codemirror.js`, - function () { - addPlugin(name, EasyCoder_CodeMirror, callback); - }); - break; - - case `ui`: - getPlugin(name, - `${window.location.origin}${path()}/wp-content/plugins/easycoder/plugins/ui.js`, - function () { - addPlugin(name, EasyCoder_UI, callback); - }); - break; - - case `gmap`: - getPlugin(name, - `${window.location.origin}${path()}/wp-content/plugins/easycoder/plugins/gmap.js`, - function () { - addPlugin(name, EasyCoder_GMap, callback); - }); - break; - - case `showdown`: - getPlugin(name, - `${window.location.origin}${path()}/wp-content/plugins/easycoder/plugins/showdown.js`, - function () { - addPlugin(name, EasyCoder_Showdown, callback); - }); - break; - - case `svg`: - getPlugin(name, - `${window.location.origin}${path()}/wp-content/plugins/easycoder/plugins/svg.js`, - function () { - addPlugin(name, EasyCoder_SVG, callback); - }); - break; - - default: - console.log(`Unknown plugin '${name}'`); - break; - } - }, - - rest: () => { - return `wp-content/plugins/easycoder/rest.php`; - } -}; - -exports = { - EasyCoder_Plugins -}; \ No newline at end of file diff --git a/server/scripted b/server/scripted deleted file mode 100644 index 431fb3b..0000000 --- a/server/scripted +++ /dev/null @@ -1,303 +0,0 @@ - script ScriptEditor - - div Body - div Container - div Buttons - div ScriptName - div ContentDiv - input NameEditor - textarea ContentEditor - span Status - span Span - button Open - button Save - button Delete - variable Hash - variable Name - variable CurrentName - variable Content - variable Current - variable Password - variable Password2 - variable Valid - -! The browser - div Overlay - div Scroller - div Media - div FileListing - div FileRow - button CloseButton - a FileName - variable Alpha - variable FileList - variable FileCount - variable File - variable Files - variable N - variable FileIsOpen - variable Item - - set the title to `Script Editor` - -GetPassword: - rest get Hash from `_load/hash` - if Hash is empty - begin - put prompt `Please type the admin password` with `` into Password - if Password is empty - begin - alert `You must set the admin password to continue.` - goto GetPassword - end - put prompt `Please confirm the admin password` with `` into Password2 - if Password2 is not Password - begin - alert `Passwords do not match. Please start again.` - goto GetPassword - end - rest get Hash from `_hash/` cat Password - rest post Hash to `_save/hash` - goto Start - end - -Login: - get Password from storage as `.ec-password` - if Password is empty - put prompt `Please type the admin password` with `` into Password - rest get Valid from `_verify/` cat Password or - begin - alert `Server error; please restart.` - exit - end - if Valid is `yes` put Password into storage as `.ec-password` - else - begin - alert `Incorrect password; please retry` - goto Login - end - -Start: - clear body - create Body in body - set the style of Body to `width:100vw;height:100vh` - create Container in Body - set the style of Container to - `width:70%;height:100%;margin:0 auto;background #ffe;display:flex;flex-direction:column` - - create Buttons in Container - set the style of Buttons to `height:3em;text-align:center` - - create Open in Buttons - set the style of Open to `margin-right:0.5em` - set the text of Open to `Open` - create Save in Buttons - set the text of Save to `Save` - set the style of Save to `margin-right:4em` - create Delete in Buttons - set the text of Delete to `Delete` - create Status in Buttons - set the style of Status to `float:right;padding:1em 2em 0 0;color:green` - - create ScriptName in Container - set the style of ScriptName to `height:2em;display:flex;margin:0.5em 0` - create Span in ScriptName - set the style of Span to `flex:15` - set the content of Span to `Script name: ` - create NameEditor in ScriptName - set the style of NameEditor to `flex:85;display:inline-block` - set the size of NameEditor to 40 - - create ContentDiv in Container - set the style of ContentDiv to `flex:1;width:100%;border:1px solid lightgray;overflow-y:scroll` - - create ContentEditor in ContentDiv - set the style of ContentEditor to `width:100%;height:100%` - - codemirror init basic profile `/wp-content/plugins/easycoder/plugins/codemirror-ecs.js` - require css `https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.46.0/addon/dialog/dialog.css` - require js `https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.46.0/addon/dialog/dialog.js` - require js `https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.46.0/addon/search/search.js` - require js `https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.46.0/addon/search/searchcursor.js` - require js `https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.46.0/addon/search/jump-to-line.js` - - create Overlay in body - set the style of Overlay to - `position:absolute;top:0;left:0;width:100vw;height:100vh;background:rgba(0,0,0,0.0);display:none` - - create Media in Overlay - set style of Media to `display:none;width:100%;height:100%;text-align:center` - - create FileListing in Media - set the style of FileListing to - `display:none;width:50%;height:75%;margin:auto;background-color:white;` - cat `padding:2em 2em 3em 2em;text-align:center;position: absolute;top: 50%;left: 50%;` - cat `transform: translateX(-50%) translateY(-50%)` - - create Scroller in FileListing - set the style of Scroller to `height:100%;overflow:scroll;text-align:left` - - create CloseButton in FileListing - set the text of CloseButton to `Close` - - codemirror attach to ContentEditor - codemirror set content of ContentEditor to Content - set FileIsOpen - - put empty into Current - - on click Save - begin - put the content of NameEditor into Name - if Name is empty - begin - set the content of Status to `No script name has been given` - go to ResetStatus - end - replace ` ` with `_` in Name - codemirror close ContentEditor - put the content of ContentEditor into Content - if Content is not Current - begin - rest post Content to `_save/scripts~` cat Name - put Content into Current - set the content of Status to `Script '` cat Name cat `' saved` - fork to ResetStatus - end - else - begin - set the content of Status to `Nothing has changed` - fork to ResetStatus - end - codemirror attach to ContentEditor - end - - on click Open go to DoOpen - - on click Delete - begin - put the content of NameEditor into Name - if Name is empty - begin - alert `Nothing to delete.` - stop - end - if confirm `Are you sure you want to delete '` cat Name cat `'?` - begin - codemirror close ContentEditor - rest post to `_delete/scripts~` cat Name - set the content of Status to `Script '` cat Name cat `' deleted` - set the content of NameEditor to empty - put empty into Content - set the content of ContentEditor to Content - put Content into Current - go to ResetStatus - end - end - stop - -DoOpen: - if FileIsOpen codemirror close ContentEditor - put the content of ContentEditor into Content - if Content is not Current - begin - if confirm `Content has changed. Do you want to save it?` - begin - rest post Content to `_save/scripts~` cat CurrentName -! rest post Content to `ec_scripts/set/name/` cat CurrentName - end - end - -! Animate the background - set style `display` of Overlay to `block` - put 0 into Alpha - while Alpha is less than 8 - begin - set style `background-color` of Overlay to `rgba(0,0,0,0.` cat Alpha cat `)` - wait 4 ticks - add 1 to Alpha - end - wait 10 ticks - -! Make the browser panel visible - set style `display` of Media to `block` - set style `display` of FileListing to `inline-block` - -! Fill the browser with content from the server - rest get Files from `_list/scripts` - put the json count of Files into FileCount - put empty into Content - put 0 into N - while N is less than FileCount - begin - put element N of Files into Item - if property `type` of Item is `file` json add Item to Content - add 1 to N - end - put empty into FileList - json sort Content - put empty into FileList - put the json count of Content into FileCount - set the elements of File to FileCount - set the elements of FileName to FileCount -! Add a row for each file - put empty into FileList - put 0 into N - while N is less than FileCount - begin - index File to N - index FileName to N - put `
    ` - cat `
    ` into File - replace `INDEX` with N in File - if N is even replace `ODDEVEN` with `ec-even` in File - else replace `ODDEVEN` with `ec-odd` in File - put FileList cat File into FileList - add 1 to N - end - - set the content of Scroller to FileList -! Add the document names - put 0 into N - while N is less than FileCount - begin - index File to N - index FileName to N - put element N of Content into File - attach FileRow to `ec-file-row-` cat N - attach FileName to `ec-file-name-` cat N - put property `name` of File into File - set the content of FileName to File - if N is even set style `background` of FileRow to `lightgray` - on click FileName go to SelectFile - add 1 to N - end - on click CloseButton - begin - put Current into Content - go to CloseBrowser - end - stop - -SelectFile: - index File to the index of FileName - set the content of NameEditor to File - rest get Content from `_load/scripts~` cat File - replace `\` with `\\` in Content - put Content into Current - set the content of Status to `Script '` cat File cat `' loaded` - fork to ResetStatus - set the title to `Script Editor - ` cat File - -CloseBrowser: - set style `background-color` of Overlay to `rgba(0,0,0,0.0)` - set style `display` of Overlay to `none` - set style `display` of Media to `none` - codemirror attach to ContentEditor - codemirror set content of ContentEditor to Content - stop - -ResetStatus: - wait 2 - set the content of Status to `` - stop From 6b9ca16f66cfe21c547b695e4cc9af0e7445fb62 Mon Sep 17 00:00:00 2001 From: Graham Trott Date: Mon, 13 Apr 2020 13:32:14 +0100 Subject: [PATCH 5/6] Setting up CDN --- easycoder/plugins/anagrams.js | 46 +++ easycoder/plugins/aws.js | 234 +++++++++++ easycoder/plugins/ckeditor.js | 175 ++++++++ easycoder/plugins/codemirror-ecs.js | 63 +++ easycoder/plugins/codemirror.js | 173 ++++++++ easycoder/plugins/dummy.js | 69 ++++ easycoder/plugins/gmap.js | 561 +++++++++++++++++++++++++ easycoder/plugins/life.js | 94 +++++ easycoder/plugins/showdown.js | 124 ++++++ easycoder/plugins/svg.js | 621 ++++++++++++++++++++++++++++ easycoder/plugins/ui.js | 373 +++++++++++++++++ easycoder/plugins/vfx.js | 346 ++++++++++++++++ easycoder/plugins/wof.js | 285 +++++++++++++ 13 files changed, 3164 insertions(+) create mode 100644 easycoder/plugins/anagrams.js create mode 100644 easycoder/plugins/aws.js create mode 100644 easycoder/plugins/ckeditor.js create mode 100644 easycoder/plugins/codemirror-ecs.js create mode 100644 easycoder/plugins/codemirror.js create mode 100644 easycoder/plugins/dummy.js create mode 100644 easycoder/plugins/gmap.js create mode 100644 easycoder/plugins/life.js create mode 100644 easycoder/plugins/showdown.js create mode 100644 easycoder/plugins/svg.js create mode 100644 easycoder/plugins/ui.js create mode 100644 easycoder/plugins/vfx.js create mode 100644 easycoder/plugins/wof.js diff --git a/easycoder/plugins/anagrams.js b/easycoder/plugins/anagrams.js new file mode 100644 index 0000000..e1c98ab --- /dev/null +++ b/easycoder/plugins/anagrams.js @@ -0,0 +1,46 @@ +// eslint-disable-next-line no-unused-vars +const EasyCoder_Anagrams = { + + name: `EasyCoder_Anagrams`, + + value: { + + compile: (compiler) => { + if (compiler.tokenIs(`anagrams`)) { + if (compiler.nextTokenIs(`of`)) { + const value = compiler.getNextValue(); + return { + domain: `anagrams`, + type: `getAnagrams`, + value + }; + } + } + return null; + }, + + get: (program, value) => { + switch (value.type) { + case `getAnagrams`: + return { + type: `constant`, + numeric: false, + content: JSON.stringify(AnagramFinder.getAnagrams(program.getValue(value.value), EasyCoder_words)) + }; + } + return null; + } + }, + + getHandler: () => { + return null; + }, + + condition: { + + compile: () => {} + } +}; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.anagrams = EasyCoder_Anagrams; diff --git a/easycoder/plugins/aws.js b/easycoder/plugins/aws.js new file mode 100644 index 0000000..79c5c09 --- /dev/null +++ b/easycoder/plugins/aws.js @@ -0,0 +1,234 @@ +const EasyCoder_AWS = { + + name: `EasyCoder_AWS`, + + AWS: { + + compile: (compiler) => { + const lino = compiler.getLino(); + const request = compiler.nextToken(); + switch (request) { + case `get`: + if (compiler.nextIsSymbol(true)) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + if (compiler.nextTokenIs(`from`)) { + const url = compiler.getNextValue(); + let onError = null; + if (compiler.tokenIs(`or`)) { + compiler.next(); + onError = compiler.getPc() + 1; + compiler.completeHandler(); + } + compiler.addCommand({ + domain: `aws`, + keyword: `aws`, + lino, + request: `get`, + target: targetRecord.name, + url, + onError + }); + return true; + } + } + } + break; + case `post`: + const value = compiler.getNextValue(); + let target = null; + if (compiler.tokenIs(`giving`)) { + if (compiler.nextIsSymbol()) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.isVHolder) { + target = targetRecord.name; + compiler.next(); + } else { + throw new Error(`'${targetRecord.name}' cannot hold a value`); + } + } + } + onError = null; + if (compiler.tokenIs(`or`)) { + compiler.next(); + onError = compiler.getPc() + 1; + compiler.completeHandler(); + } + compiler.addCommand({ + domain: `aws`, + keyword: `aws`, + lino, + request: `post`, + value, + target, + onError + }); + return true; + case `delete`: + if (compiler.nextIsSymbol(true)) { + const targetRecord = compiler.getSymbolRecord(); + if (targetRecord.keyword === `variable`) { + let onError = null; + if (compiler.tokenIs(`or`)) { + compiler.next(); + onError = compiler.getPc() + 1; + compiler.completeHandler(); + } + compiler.next(); + compiler.addCommand({ + domain: `aws`, + keyword: `aws`, + lino, + request: `delete`, + target: targetRecord.name, + onError + }); + return true; + } + } + break; + case `set`: + if (compiler.nextTokenIs(`the`)) { + compiler.next(); + } + if (compiler.tokenIs(`url`)) { + if (compiler.nextTokenIs(`to`)) { + const url = compiler.getNextValue(); + compiler.addCommand({ + domain: `aws`, + keyword: `aws`, + lino, + request: `setUrl`, + url + }); + return true; + } + } + return false; + } + return false; + }, + + run: (program) => { + const createCORSRequest = function (method, url) { + let xhr = new XMLHttpRequest(); + if (`withCredentials` in xhr) { + // Most browsers. + xhr.open(method, url, true); + } else if (typeof XDomainRequest != `undefined`) { + // IE8 & IE9 + xhr = new XDomainRequest(); + xhr.open(method, url); + } else { + // CORS not supported. + xhr = null; + } + return xhr; + }; + + const command = program[program.pc]; + if (command.request === `setUrl`) { + EasyCoder_AWS.url = program.getValue(command.url); + return command.pc + 1; + } else if ([`get`, `post`, `delete`].includes(command.request)) { + const method = command.request.toUpperCase(); + const url = `${EasyCoder_AWS.url}${program.getValue(command.url)}`; + const request = createCORSRequest(method, url); + if (!request) { + program.runtimeError(command.lino, `CORS not supported`); + return command.pc + 1; + } + request.setRequestHeader(`Content-Type`, `application/json; charset=UTF-8`); + request.command = command; + switch (command.request) { + case `get`: + case `delete`: + request.send(); + break; + case `post`: + const value = program.getValue(command.value); + console.log(`POST to ${EasyCoder_AWS.url}`); + if ([`[`, `{`].includes(value.charAt(0))) { + request.setRequestHeader(`Content-Type`, `application/json; charset=UTF-8`); + // console.log(`value=${value}`); + request.send(value); + } else { + request.setRequestHeader(`Content-Type`, `text/plain; charset=UTF-8`); + // console.log(`value=${program.encode(value)}`); + request.send(program.encode(value)); + } + break; + } + + request.onload = function () { + var content = request.responseText; + if (content.length > 0 && ![`[`, `{`].includes(content.charAt(0))) { + content = program.decode(content); + // } else { + // content = JSON.parse(content); + } + if (command.target) { + const targetRecord = program.getSymbolRecord(command.target); + targetRecord.value[targetRecord.index] = { + type: `constant`, + numeric: false, + content + }; + } + program.run(command.pc + 1); + }; + + request.onerror = function () { + if (command.onError) { + program.errorMessage = this.responseText; + program.run(command.onError); + } else { + const error = this.responseText; + program.runtimeError(command.lino, error); + } + }; + + return 0; + } + } + }, + + getHandler: (name) => { + switch (name) { + case `aws`: + return EasyCoder_AWS.AWS; + default: + return null; + } + }, + + run: (program) => { + const command = program[program.pc]; + const handler = EasyCoder_AWS.getHandler(command.keyword); + if (!handler) { + program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'aws' package`); + } + return handler.run(program); + }, + + value: { + + compile: () => { + return null; + }, + + get: () => { + return null; + } + }, + + condition: { + + compile: () => {}, + + test: () => {} + } +}; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.aws = EasyCoder_AWS; diff --git a/easycoder/plugins/ckeditor.js b/easycoder/plugins/ckeditor.js new file mode 100644 index 0000000..bbc8578 --- /dev/null +++ b/easycoder/plugins/ckeditor.js @@ -0,0 +1,175 @@ +const EasyCoder_CKEditor = { + + name: `EasyCoder_CKEditor`, + + CKEditor: { + + compile: (compiler) => { + const lino = compiler.getLino(); + const action = compiler.nextToken(); + compiler.next(); + switch (action) { + case `attach`: + if (compiler.tokenIs(`to`)) { + if (compiler.nextIsSymbol()) { + const editor = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `ckeditor`, + keyword: `ckeditor`, + lino, + action, + editor + }); + return true; + } + } + break; + case `close`: + if (compiler.isSymbol()) { + const editor = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `ckeditor`, + keyword: `ckeditor`, + lino, + action, + editor + }); + return true; + } + break; + case `get`: + if (compiler.isSymbol()) { + const target = compiler.getToken(); + if (compiler.nextTokenIs(`from`)) { + compiler.next(); + if (compiler.isSymbol()) { + const editor = compiler.getToken(); + compiler.next(); + compiler.addCommand({ + domain: `ckeditor`, + keyword: `ckeditor`, + lino, + action, + target, + editor + }); + return true; + } + } + } + break; + case `set`: + if (compiler.isSymbol()) { + const editor = compiler.getToken(); + if (compiler.nextTokenIs(`to`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `ckeditor`, + keyword: `ckeditor`, + lino, + action, + editor, + value + }); + return true; + } + } + break; + default: + compiler.addCommand({ + domain: `ckeditor`, + keyword: `ckeditor`, + lino, + action + }); + break; + } + return true; + }, + + run: (program) => { + const command = program[program.pc]; + var editor; + var content; + switch (command.action) { + case `test`: + break; + case `attach`: + editor = program.getSymbolRecord(command.editor); + editor.editor = + CKEDITOR.appendTo(editor.element[editor.index].id, { + height: 400 + }); + break; + case `close`: + editor = program.getSymbolRecord(command.editor); + editor.editor.destroy(); + break; + case `get`: + editor = program.getSymbolRecord(command.editor); + const targetRecord = program.getSymbolRecord(command.target); + content = editor.editor.getData() + .split(`\n`).join(``).split(` `).join(` `); + targetRecord.value[targetRecord.index] = { + type: `constant`, + numeric: false, + content + }; + break; + case `set`: + editor = program.getSymbolRecord(command.editor); + content = program.getValue(command.value); + editor.editor.setData(content, { + callback: function () { + program.run(command.pc + 1); + } + }); + return 0; + case `reset`: + for (const name in CKEDITOR.instances) { + CKEDITOR.instances[name].destroy(); + } + break; + } + return command.pc + 1; + } + }, + + getHandler: (name) => { + switch (name) { + case `ckeditor`: + return EasyCoder_CKEditor.CKEditor; + default: + return null; + } + }, + + run: (program) => { + const command = program[program.pc]; + const handler = EasyCoder_CKEditor.getHandler(command.keyword); + if (!handler) { + program.runtimeError(command.lino, + `Unknown keyword '${command.keyword}' in 'ckeditor' package`); + } + return handler.run(program); + }, + + value: { + + compile: () => { + return null; + }, + get: () => {} + }, + + condition: { + + compile: () => {}, + test: () => {} + } +}; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.ckeditor = EasyCoder_CKEditor; diff --git a/easycoder/plugins/codemirror-ecs.js b/easycoder/plugins/codemirror-ecs.js new file mode 100644 index 0000000..58d762c --- /dev/null +++ b/easycoder/plugins/codemirror-ecs.js @@ -0,0 +1,63 @@ +(function (mod) { + if (typeof exports == `object` && typeof module == `object`) // CommonJS + mod(require(`../../lib/codemirror`)); + else if (typeof define == `function` && define.amd) // AMD + define([`../../lib/codemirror`], mod); + else // Plain browser env + mod(CodeMirror); +})(function (CodeMirror) { + "use strict"; + + + CodeMirror.defineMode(`ecs`, function () { + return { + startState: function () { + return { + inString: false, + inComment: false + }; + }, + token: function (stream, state) { + stream.eatSpace(); + // If a string or a comment starts here + if (!state.inString && stream.peek() === `\``) { + stream.next(); // Skip quote + state.inString = true; + } else if (!state.inComment && stream.peek() === `!`) { + stream.next(); // Skip shriek + state.inComment = true; + } + + if (state.inString) { + if (stream.skipTo(`\``)) { // Quote found on this line + stream.next(); // Skip quote + state.inString = false; // Clear flag + } else { + stream.skipToEnd(); + state.inString = false; // Clear flag + } + return `string`; // Return the token style + } + + else if (state.inComment) { + stream.skipToEnd(); + state.inComment = false; + return `comment`; // Return the token style + } + + else { + if (stream.match(/[A-Z][A-Za-z0-9-_]*/, true)) { + return `attribute`; + } + if (stream.match(/[0-9]+/, true)) { + return `number`; + } + stream.skipTo(` `) || stream.skipToEnd(); + return null; // Unstyled token + } + } + }; + }); + + CodeMirror.defineMIME(`text/x-ecs`, `ecs`); +}); \ No newline at end of file diff --git a/easycoder/plugins/codemirror.js b/easycoder/plugins/codemirror.js new file mode 100644 index 0000000..266cb48 --- /dev/null +++ b/easycoder/plugins/codemirror.js @@ -0,0 +1,173 @@ +const EasyCoder_CodeMirror = { + + name: `EasyCoder_CodeMirror`, + + CodeMirror: { + + compile: (compiler) => { + const lino = compiler.getLino(); + const action = compiler.nextToken(); + switch (action) { + case `init`: + const mode = compiler.nextToken(); + let profile = ``; + if (compiler.nextTokenIs(`profile`)) { + profile = compiler.getNextValue(); + } + compiler.addCommand({ + domain: `codemirror`, + keyword: `codemirror`, + lino, + action, + mode, + profile + }); + return true; + case `attach`: + if (compiler.nextTokenIs(`to`)) { + if (compiler.nextIsSymbol()) { + const editor = compiler.getToken(); + let mode = `ecs`; + if (compiler.nextTokenIs(`mode`)) { + mode = compiler.nextToken(); + compiler.next(); + } + compiler.addCommand({ + domain: `codemirror`, + keyword: `codemirror`, + lino, + action, + editor, + mode + }); + return true; + } + } + break; + case `set`: + if (compiler.nextTokenIs(`content`)) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const editor = compiler.getSymbolRecord(); + if (compiler.nextTokenIs(`to`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `codemirror`, + keyword: `codemirror`, + lino, + action: `setContent`, + editor: editor.name, + value + }); + return true; + } + } + } + } + break; + case `close`: + if (compiler.nextIsSymbol()) { + const editor = compiler.getSymbolRecord(); + compiler.next(); + compiler.addCommand({ + domain: `codemirror`, + keyword: `codemirror`, + lino, + action: `close`, + editor: editor.name + }); + return true; + } + return false; + default: + throw new Error(`Unrecognized action '${action}'`); + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + var editor; + switch (command.action) { + case `init`: + switch (command.mode) { + case `basic`: + program.require(`css`, `https://codemirror.net/lib/codemirror.css`, + function () { + program.require(`js`, `https://codemirror.net/lib/codemirror.js`, + function () { + if (command.profile) { + program.require(`js`, program.getValue(command.profile), + function () { + program.run(command.pc + 1); + }); + } else { + program.run(command.pc + 1); + } + }); + }); + return 0; + } + break; + case `attach`: + try { + editor = program.getSymbolRecord(command.editor); + const element = document.getElementById(editor.element[editor.index].id); + editor.editor = CodeMirror.fromTextArea(element, { + mode: command.mode, + theme: `default`, + lineNumbers: true + }); + editor.editor.setSize(`100%`, `100%`); + } catch (err) { alert(err); } + break; + case `setContent`: + editor = program.getSymbolRecord(command.editor); + const value = program.getValue(command.value); + editor.editor.setValue(value); + break; + case `close`: + editor = program.getSymbolRecord(command.editor); + editor.editor.toTextArea(); + break; + } + return command.pc + 1; + } + }, + + getHandler: (name) => { + switch (name) { + case `codemirror`: + return EasyCoder_CodeMirror.CodeMirror; + default: + return null; + } + }, + + run: (program) => { + const command = program[program.pc]; + const handler = EasyCoder_CodeMirror.getHandler(command.keyword); + if (!handler) { + program.runtimeError(command.lino, + `Unknown keyword '${command.keyword}' in 'codemirror' package`); + } + return handler.run(program); + }, + + value: { + + compile: () => { + return null; + }, + get: () => {} + }, + + condition: { + + compile: () => {}, + test: () => {} + } +}; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.codemirror = EasyCoder_CodeMirror; diff --git a/easycoder/plugins/dummy.js b/easycoder/plugins/dummy.js new file mode 100644 index 0000000..36bbd02 --- /dev/null +++ b/easycoder/plugins/dummy.js @@ -0,0 +1,69 @@ +const EasyCoder_Dummy = { + + name: `EasyCoder_Dummy`, + + Dummy: { + + // Command keywords + compile: compiler => { + const lino = compiler.getLino(); + compiler.next(); + compiler.addCommand({ + domain: `dummy`, + keyword: `dummy`, + lino + }); + return true; + }, + + run: program => { + const command = program[program.pc]; + return command.pc + 1; + } + }, + + // Values + value: { + + compile: () => { + return { + domain: `dummy`, + type: `dummy` + }; + }, + + get: (program, value) => { + return value; + } + }, + + // Conditions + condition: { + + compile: () => {}, + + test: () => {} + }, + + // Dispatcher + getHandler: (name) => { + switch (name) { + case `dummy`: + return EasyCoder_Dummy.Dummy; + default: + return false; + } + }, + + run: program => { + const command = program[program.pc]; + const handler = EasyCoder_Dummy.getHandler(command.keyword); + if (!handler) { + program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'dummy' package`); + } + return handler.run(program); + } +}; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.dummy = EasyCoder_Dummy; diff --git a/easycoder/plugins/gmap.js b/easycoder/plugins/gmap.js new file mode 100644 index 0000000..404f88c --- /dev/null +++ b/easycoder/plugins/gmap.js @@ -0,0 +1,561 @@ + +const EasyCoder_GMap = { + + name: `EasyCoder_GMap`, + + Create: { + + compile: compiler => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + const type = symbolRecord.keyword; + switch (type) { + case `gmap`: + if (compiler.nextTokenIs(`in`)) { + if (compiler.nextIsSymbol()) { + const parentRecord = compiler.getSymbolRecord(); + if (parentRecord.keyword === `div`) { + compiler.next(); + compiler.addCommand({ + domain: `gmap`, + keyword: `create`, + type, + lino, + name: symbolRecord.name, + parent: parentRecord.name + }); + return true; + } + } + } + return false; + case `marker`: + if (compiler.nextTokenIs(`in`)) { + if (compiler.nextIsSymbol()) { + const parentRecord = compiler.getSymbolRecord(); + if (parentRecord.keyword === `gmap`) { + compiler.next(); + compiler.addCommand({ + domain: `gmap`, + keyword: `create`, + type, + lino, + name: symbolRecord.name, + map: parentRecord.name + }); + return true; + } + } + } + return false; + } + } + return false; + }, + + run: program => { + const command = program[program.pc]; + const symbolRecord = program.getSymbolRecord(command.name); + switch (command.type) { + case `gmap`: + symbolRecord.parent = program.getSymbolRecord(command.parent); + symbolRecord.markers = []; + break; + case `marker`: + const mapRecord = program.getSymbolRecord(command.map); + const element = new google.maps.Marker({ + map: mapRecord.map + }); + symbolRecord.element[symbolRecord.index] = element; + mapRecord.markers.push(element); + element.addListener(`click`, function () { + program.run(symbolRecord.onClick); + }); + break; + } + return command.pc + 1; + } + }, + + GMap: { + + compile: compiler => { + compiler.compileVariable(`gmap`, `gmap`); + return true; + }, + + run: program => { + return program[program.pc].pc + 1; + } + }, + + On: { + + compile: compiler => { + const lino = compiler.getLino(); + const action = compiler.nextToken(); + if ([`click`, `move`, `type`, `zoom`].includes(action)) { + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.keyword === `gmap` || (symbolRecord.keyword === `marker` && action === `click`)) { + compiler.next(); + compiler.addCommand({ + domain: `gmap`, + keyword: `on`, + lino, + action, + name: symbolRecord.name + }); + return compiler.completeHandler(); + } + } + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const symbolRecord = program.getSymbolRecord(command.name); + switch (command.action) { + case `click`: + if (symbolRecord.keyword === `marker`) { + symbolRecord.element.forEach(function (marker, index) { + marker.targetRecord = symbolRecord; + marker.targetIndex = index; + marker.targetPc = command.pc + 2; + marker.addListener(`click`, function () { + if (program.length > 0) { + marker.targetRecord.index = marker.targetIndex; + setTimeout(function () { + EasyCoder.timestamp = Date.now(); + program.run(marker.targetPc); + }, 1); + } + return false; + }); + }); + } else { + symbolRecord.onClick = command.pc + 2; + } + break; + case `move`: + symbolRecord.onMove = command.pc + 2; + break; + case `type`: + symbolRecord.onType = command.pc + 2; + break; + case `zoom`: + symbolRecord.onZoom = command.pc + 2; + break; + default: + program.runtimeError(command.lino, `Unknown action '${command.action}'`); + return 0; + } + return command.pc + 1; + } + }, + + Marker: { + + compile: compiler => { + compiler.compileVariable(`gmap`, `marker`); + return true; + }, + + run: program => { + return program[program.pc].pc + 1; + } + }, + + Remove: { + + compile: compiler => { + const lino = compiler.getLino(); + if (compiler.nextTokenIs(`markers`)) { + if (compiler.nextTokenIs(`from`)) { + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.keyword === `gmap`) { + compiler.next(); + compiler.addCommand({ + domain: `gmap`, + keyword: `remove`, + lino, + name: symbolRecord.name + }); + return true; + } + } + } + } + return false; + }, + + run: program => { + const command = program[program.pc]; + const mapRecord = program.getSymbolRecord(command.name); + for (const marker of mapRecord.markers) { + marker.setMap(null); + } + mapRecord.markers = []; + return command.pc + 1; + } + }, + + Set: { + + compile: compiler => { + const lino = compiler.getLino(); + compiler.skip(`the`); + const attribute = compiler.getToken(); + if ([`key`, `latitude`, `longitude`, `type`, `zoom`].includes(attribute)) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.keyword === `gmap`) { + if (compiler.nextTokenIs(`to`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `gmap`, + keyword: `set`, + lino, + name: symbolRecord.name, + attribute, + value + }); + return true; + } + } + } + } + } else if ([`label`, `title`, `position`, `color`].includes(attribute)) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.keyword === `marker`) { + if (compiler.nextTokenIs(`to`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `gmap`, + keyword: `set`, + lino, + name: symbolRecord.name, + attribute, + value + }); + return true; + } + } + } + } + } + return false; + }, + + run: program => { + function pinSymbol(color) { + return { + path: `M 0,0 C -2,-20 -10,-22 -10,-30 A 10,10 0 1,1 10,-30 C 10,-22 2,-20 0,0 z`, + fillColor: color, + fillOpacity: 1, + strokeColor: `#000`, + strokeWeight: 2, + scale: 1, + labelOrigin: new google.maps.Point(0, -28) + }; + } + const command = program[program.pc]; + const symbolRecord = program.getSymbolRecord(command.name); + if ([`key`, `latitude`, `longitude`, `type`, `zoom`].includes(command.attribute)) { + symbolRecord[command.attribute] = program.getValue(command.value); + } else if (command.attribute === `label`) { + symbolRecord.label = program.getValue(command.value); + const marker = symbolRecord.element[symbolRecord.index]; + marker.setLabel(symbolRecord.label); + } else if (command.attribute === `title`) { + symbolRecord.title = program.getValue(command.value); + const marker = symbolRecord.element[symbolRecord.index]; + marker.setTitle(symbolRecord.title); + } else if (command.attribute === `color`) { + symbolRecord.color = program.getValue(command.value); + const marker = symbolRecord.element[symbolRecord.index]; + marker.setIcon(pinSymbol(symbolRecord.color)); + } else if (command.attribute === `position`) { + const value = JSON.parse(program.getValue(command.value)); + symbolRecord.latitude = value.latitude; + symbolRecord.longitude = value.longitude; + const lat = parseFloat(value.latitude); + const lng = parseFloat(value.longitude); + symbolRecord.element[symbolRecord.index].setPosition(new google.maps.LatLng(lat, lng)); + } + return command.pc + 1; + } + }, + + Show: { + + compile: compiler => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + const type = symbolRecord.keyword; + if (type === `gmap`) { + compiler.next(); + compiler.addCommand({ + domain: `gmap`, + keyword: `show`, + lino, + name: symbolRecord.name + }); + return true; + } + } + return false; + }, + + run: program => { + const command = program[program.pc]; + const mapRecord = program.getSymbolRecord(command.name); + if (mapRecord.keyword !== `gmap`) { + return 0; + } + const parentElement = mapRecord.parent.element[mapRecord.parent.index]; + if (typeof EasyCoder_GMap.loaded === `undefined`) { + const script = document.createElement(`script`); + script.src = `https://maps.googleapis.com/maps/api/js?key=${mapRecord.key}`; + script.async = true; + script.defer = true; + script.onload = function () { + EasyCoder_GMap.setupMap(parentElement, mapRecord, program); + program.run(command.pc + 1); + EasyCoder_GMap.loaded = true; + }; + parentElement.insertBefore(script, null); + return 0; + } + EasyCoder_GMap.setupMap(parentElement, mapRecord, program); + return command.pc + 1; + } + }, + + setupMap: (parentElement, mapRecord, program) => { + const lat = parseFloat(mapRecord.latitude); + const lng = parseFloat(mapRecord.longitude); + const zoom = parseFloat(mapRecord.zoom); + mapRecord.map = new google.maps.Map(parentElement, { + center: { + lat, + lng + }, + zoom, + gestureHandling: `greedy` + }); + mapRecord.map.markers = []; + if (mapRecord.type === `hybrid`) { + mapRecord.map.setMapTypeId(google.maps.MapTypeId.SATELLITE); + } + mapRecord.map.addListener(`center_changed`, function () { + program.run(mapRecord.onMove); + }); + mapRecord.map.addListener(`zoom_changed`, function () { + program.run(mapRecord.onZoom); + }); + mapRecord.map.addListener(`maptypeid_changed`, function () { + program.run(mapRecord.onType); + }); + mapRecord.map.addListener(`click`, function (event) { + mapRecord.clickPosition = { + latitude: event.latLng.lat().toString(), + longitude: event.latLng.lng().toString() + }; + program.run(mapRecord.onClick); + }); + }, + + Update: { + + compile: compiler => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.keyword === `gmap`) { + compiler.next(); + compiler.addCommand({ + domain: `gmap`, + keyword: `update`, + lino, + name: symbolRecord.name + }); + return true; + } + } + return false; + }, + + run: program => { + const command = program[program.pc]; + const mapRecord = program.getSymbolRecord(command.name); + mapRecord.map.setCenter(new google.maps.LatLng(mapRecord.latitude, mapRecord.longitude)); + mapRecord.map.setZoom(parseFloat(mapRecord.zoom)); + return command.pc + 1; + } + }, + + getHandler: name => { + switch (name) { + case `create`: + return EasyCoder_GMap.Create; + case `gmap`: + return EasyCoder_GMap.GMap; + case `marker`: + return EasyCoder_GMap.Marker; + case `on`: + return EasyCoder_GMap.On; + case `remove`: + return EasyCoder_GMap.Remove; + case `set`: + return EasyCoder_GMap.Set; + case `show`: + return EasyCoder_GMap.Show; + case `update`: + return EasyCoder_GMap.Update; + default: + return null; + } + }, + + run: program => { + const command = program[program.pc]; + const handler = EasyCoder_GMap.getHandler(command.keyword); + if (!handler) { + program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'gmap' package`); + } + return handler.run(program); + }, + + value: { + + compile: compiler => { + if (compiler.tokenIs(`the`)) { + compiler.next(); + } + const type = compiler.getToken(); + if (type === `click`) { + if (compiler.nextTokenIs(`position`)) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const mapRecord = compiler.getSymbolRecord(); + if (mapRecord.keyword === `gmap`) { + compiler.next(); + return { + domain: `gmap`, + type, + name: mapRecord.name + }; + } + } + } + } + } + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.keyword === `gmap` && [`latitude`, `longitude`, `type`, `zoom`, `bounds`].includes(type) || + symbolRecord.keyword === `marker` && [`latitude`, `longitude`, `title`].includes(type)) { + compiler.next(); + return { + domain: `gmap`, + type, + name: symbolRecord.name + }; + } + } + } + return null; + }, + + get: (program, value) => { + var symbolRecord; + switch (value.type) { + case `latitude`: + symbolRecord = program.getSymbolRecord(value.name); + switch (symbolRecord.keyword) { + case `gmap`: + return { + type: `constant`, + numeric: false, + content: program.getSymbolRecord(value.name).map.getCenter().lat().toString() + }; + case `marker`: + return { + type: `constant`, + numeric: false, + content: program.getSymbolRecord(value.name).marker.getPosition().lat().toString() + }; + } + break; + case `longitude`: + symbolRecord = program.getSymbolRecord(value.name); + switch (symbolRecord.keyword) { + case `gmap`: + return { + type: `constant`, + numeric: false, + content: program.getSymbolRecord(value.name).map.getCenter().lng().toString() + }; + case `marker`: + return { + type: `constant`, + numeric: false, + content: program.getSymbolRecord(value.name).marker.getPosition().lng().toString() + }; + } + break; + case `type`: + return { + type: `constant`, + numeric: false, + content: program.getSymbolRecord(value.name).map.getMapTypeId() + }; + case `zoom`: + return { + type: `constant`, + numeric: false, + content: program.getSymbolRecord(value.name).map.getZoom().toString() + }; + case `bounds`: + const map = program.getSymbolRecord(value.name).map; + const bounds = map ? JSON.stringify(map.getBounds()) : ``; + return { + type: `constant`, + numeric: false, + content: bounds + }; + case `title`: + return { + type: `constant`, + numeric: false, + content: program.getSymbolRecord(value.name).marker.getTitle() + }; + case `click`: + return { + type: `constant`, + numeric: false, + content: JSON.stringify(program.getSymbolRecord(value.name).clickPosition) + }; + } + return null; + } + }, + + condition: { + + compile: () => {}, + + test: () => {} + } +}; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.gmap = EasyCoder_GMap; diff --git a/easycoder/plugins/life.js b/easycoder/plugins/life.js new file mode 100644 index 0000000..5d7d4f5 --- /dev/null +++ b/easycoder/plugins/life.js @@ -0,0 +1,94 @@ +// eslint-disable-next-line no-unused-vars +const EasyCoder_Life = { + + name: `EasyCoder_Life`, + + value: { + + compile: (compiler) => { + if (compiler.tokenIs(`the`)) { + compiler.nextToken(); + } + if (compiler.tokenIs(`neighbours`)) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.keyword == `variable`) { + if (compiler.nextTokenIs(`cell`)) { + const cell = compiler.getNextValue(); + return { + domain: `life`, + type: `getNeighbours`, + name: symbolRecord.name, + cell + }; + } + } + } + } + } + return null; + }, + + get: (program, value) => { + switch (value.type) { + case `getNeighbours`: + const symbolRecord = program.getSymbolRecord(value.name); + const size = Math.sqrt(symbolRecord.elements); + const cell = program.getValue(value.cell); + const row = Math.trunc(cell / size); + const column = cell % size; + const map = symbolRecord.value; + let count = 0; + if (column > 0) { + if (map[cell - 1].content) { + count++; + } + } + if (column < size - 1) { + if (map[cell + 1].content) { + count++; + } + } + if (row > 0) { + for (let c = -1; c < 2; c++) { + let cc = column + c; + if (cc >= 0 && cc < size) { + if (map[cell - size + c].content) { + count++; + } + } + } + } + if (row < size - 1) { + for (let c = -1; c < 2; c++) { + let cc = column + c; + if (cc >= 0 && cc < size) { + if (map[cell + size + c].content) { + count++; + } + } + } + } + return { + type: `constant`, + numeric: true, + content: count + }; + } + return null; + } + }, + + getHandler: () => { + return null; + }, + + condition: { + + compile: () => {} + } +}; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.life = EasyCoder_Life; diff --git a/easycoder/plugins/showdown.js b/easycoder/plugins/showdown.js new file mode 100644 index 0000000..8573440 --- /dev/null +++ b/easycoder/plugins/showdown.js @@ -0,0 +1,124 @@ +const EasyCoder_Showdown = { + + name: `EasyCoder_Showdown`, + + Load: { + + compile: compiler => { + const lino = compiler.getLino(); + if (compiler.nextTokenIs(`showdown`)) { + compiler.next(); + compiler.addCommand({ + domain: `showdown`, + keyword: `load`, + lino + }); + return true; + } + return false; + }, + + run: program => { + const command = program[program.pc]; + if (program.isUndefined(this.showdown_loaded)) { + program.require(`js`, `https://unpkg.com/showdown@1.9.1/./dist/showdown.js`, function () { + this.showdown_loaded = true; + EasyCoder_Showdown.setupExtension(); + program.run(command.pc + 1); + }); + } + else { + EasyCoder_Showdown.setupExtension(); + return command.pc + 1; + } + return 0; + } + }, + + setupExtension: () => { + showdown.extension(`Extension`, { + type: `lang`, + filter: function (text, converter) { + const callback = program.getSymbolRecord(converter.callback); + return text.replace(/~([^~]+)~/g, function (match, group) { + callback.payload = group; + program.run(callback.cb); + return callback.payload; + }); + } + }); + }, + + getHandler: (name) => { + switch (name) { + case `load`: + return EasyCoder_Showdown.Load; + default: + return null; + } + }, + + run: program => { + const command = program[program.pc]; + const handler = EasyCoder_Showdown.getHandler(command.keyword); + if (!handler) { + program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'showdown' package`); + } + return handler.run(program); + }, + + value: { + + compile: compiler => { + if (compiler.tokenIs(`showdown`)) { + if (compiler.nextTokenIs(`decode`)) { + const value = compiler.getNextValue(); + let callback = null; + if (compiler.tokenIs(`with`)) { + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.keyword === `callback`) { + callback = symbolRecord.name; + compiler.next(); + } + } + } + return { + domain: `showdown`, + type: `decode`, + value, + callback + }; + } + } + return null; + }, + + get: (program, value) => { + const converter = new showdown.Converter({ + extensions: [`Extension`] + }); + switch (value.type) { + case `decode`: + converter.callback = value.callback; + const markdown = program.getValue(value.value); + const content = converter.makeHtml(markdown); + return { + type: `constant`, + numeric: false, + content + }; + } + } + }, + + condition: { + + compile: () => {}, + + test: () => {} + } +}; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.showdown = EasyCoder_Showdown; diff --git a/easycoder/plugins/svg.js b/easycoder/plugins/svg.js new file mode 100644 index 0000000..8f15b92 --- /dev/null +++ b/easycoder/plugins/svg.js @@ -0,0 +1,621 @@ +const EasyCoder_SVG = { + + name: `EasyCoder_SVG`, + + Circle: { + + compile: (compiler) => { + compiler.compileVariable(`svg`, `circle`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Create: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + compiler.next(); + switch (symbolRecord.keyword) { + case `svg`: + if (compiler.tokenIs(`in`)) { + if (compiler.nextIsSymbol()) { + const parent = compiler.getToken(); + compiler.next(); + var style = null; + var flag = true; + while (flag) { + const token = compiler.getToken(); + compiler.next(); + switch (token) { + case `style`: + style = compiler.getValue(); + break; + default: + compiler.prev(); + flag = false; + break; + } + } + if (!style) { + style = { + type: `constant`, + numeric: false, + content: `width:100%;height:100%` + }; + } + compiler.addCommand({ + domain: `svg`, + keyword: `create`, + lino, + type: `svg`, + name: symbolRecord.name, + style, + parent + }); + return true; + } + } + break; + case `group`: + if (compiler.tokenIs(`in`)) { + if (compiler.nextIsSymbol()) { + const parentRecord = compiler.getSymbolRecord(); + if (![`svg`, `group`].includes(parentRecord.keyword)) { + throw new Error(`Inappropriate type '${parentRecord.keyword}'`); + } + compiler.next(); + compiler.addCommand({ + domain: `svg`, + keyword: `create`, + lino, + type: `group`, + name: symbolRecord.name, + parent: parentRecord.name + }); + return true; + } + } + break; + case `circle`: + case `ellipse`: + case `line`: + case `rect`: + case `svgtext`: + if (compiler.tokenIs(`in`)) { + if (compiler.nextIsSymbol()) { + const parentRecord = compiler.getSymbolRecord(); + if (![`svg`, `group`].includes(parentRecord.keyword)) { + throw new Error(`Inappropriate type '${parentRecord.keyword}'`); + } + compiler.next(); + var text; + flag = true; + while (flag) { + const token = compiler.getToken(); + compiler.next(); + switch (token) { + case `style`: + style = compiler.getValue(); + break; + case `text`: + text = compiler.getValue(); + break; + default: + compiler.prev(); + flag = false; + break; + } + } + compiler.addCommand({ + domain: `svg`, + keyword: `create`, + lino, + type: symbolRecord.keyword === `svgtext` ? `text` : symbolRecord.keyword, + name: symbolRecord.name, + style, + text, + parent: parentRecord.name + }); + return true; + } + } + break; + } + } + return false; + }, + + run: (program) => { + const ns = `http://www.w3.org/2000/svg`; + const command = program[program.pc]; + var parentRecord = program.getSymbolRecord(command.parent); + var group; + const symbolRecord = program.getSymbolRecord(command.name); + if (command.type === `group`) { + symbolRecord.parent = command.parent; + symbolRecord.x = 0; + symbolRecord.y = 0; + } else { + if (parentRecord.keyword === `group`) { + group = parentRecord; + // Add this element to the group + const groupElement = group.value[group.index]; + if (!groupElement.content) { + groupElement.content = []; + } + groupElement.content.push({ + name: symbolRecord.name, + index: symbolRecord.index + }); + // Find the real parent + while (parentRecord.keyword === `group`) { + parentRecord = program.getSymbolRecord(parentRecord.parent); + } + } + const container = parentRecord.element[parentRecord.index]; + const element = document.createElementNS(ns, command.type); + symbolRecord.element[symbolRecord.index] = element; + container.appendChild(element); + // Set the id + const id = `ec-` + symbolRecord.name + `-` + symbolRecord.index; + element.setAttribute(`id`, id); + if (symbolRecord.keyword === `svgtext`) { + element.textContent = program.value.evaluate(program, command.text).content; + } + symbolRecord.value[symbolRecord.index] = { + type: `constant`, + numeric: false, + content: id + }; + if (command.style) { + const style = program.value.evaluate(program, command.style).content; + program.domain.browser.setStyles(id, style); + // Store the location of this shape + const value = symbolRecord.value[symbolRecord.index]; + switch (symbolRecord.keyword) { + case `circle`: + case `ellipse`: + value.x = element.getAttribute(`cx`); + value.y = element.getAttribute(`cy`); + break; + case `line`: + value.x = element.getAttribute(`x1`); + value.y = element.getAttribute(`y1`); + value.x2 = element.getAttribute(`x2`); + value.y2 = element.getAttribute(`y2`); + break; + case `rect`: + case `svgtext`: + value.x = element.getAttribute(`x`); + value.y = element.getAttribute(`y`); + break; + } + if (group) { + // Record the group name and index + value.groupName = group.name; + value.groupIndex = group.index; + } + } + } + return program[program.pc].pc + 1; + } + }, + + Ellipse: { + + compile: (compiler) => { + compiler.compileVariable(`svg`, `ellipse`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Group: { + + compile: (compiler) => { + compiler.compileVariable(`svg`, `group`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Line: { + + compile: (compiler) => { + compiler.compileVariable(`svg`, `line`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Move: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (compiler.nextTokenIs(`to`)) { + const x = compiler.getNextValue(); + const y = compiler.getValue(); + compiler.addCommand({ + domain: `svg`, + keyword: `move`, + lino, + type: `moveTo`, + name: symbolRecord.name, + x, + y + }); + return true; + } + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const newX = program.value.evaluate(program, command.x).content; + const newY = program.value.evaluate(program, command.y).content; + const symbolRecord = program.getSymbolRecord(command.name); + switch (symbolRecord.keyword) { + case `group`: + for (const item of symbolRecord.value[symbolRecord.index].content) { + const itemRecord = program.getSymbolRecord(item.name); + const value = itemRecord.value[item.index]; + const element = document.getElementById(value.content); + const x = parseInt(value.x) + newX; + const y = parseInt(value.y) + newY; + switch (itemRecord.keyword) { + case `circle`: + case `ellipse`: + element.setAttribute(`cx`, x); + element.setAttribute(`cy`, y); + break; + case `line`: + element.setAttribute(`x1`, x); + element.setAttribute(`y1`, y); + element.setAttribute(`x2`, parseInt(value.x2) + newX); + element.setAttribute(`y2`, parseInt(value.y2) + newY); + break; + case `rect`: + case `svgtext`: + element.setAttribute(`x`, x); + element.setAttribute(`y`, y); + break; + } + } + symbolRecord.x = newX; + symbolRecord.y = newY; + break; + case `circle`: + case `ellipse`: + case `line`: + case `rect`: + case `svgtext`: + var px = 0; + var py = 0; + const symRec = symbolRecord.value[symbolRecord.index]; + if (symRec.groupName) { + const parentRecord = program.getSymbolRecord(symRec.groupName); + px = parentRecord.x; + py = parentRecord.y; + } + const symbolValue = symbolRecord.value[symbolRecord.index]; + const element = document.getElementById(symbolRecord.value[symbolRecord.index].content); + switch (symbolRecord.keyword) { + case `circle`: + case `ellipse`: + element.setAttribute(`cx`, px + newX); + element.setAttribute(`cy`, py + newY); + break; + case `line`: + element.setAttribute(`x1`, px + newX); + element.setAttribute(`y1`, py + newY); + const dx = parseInt(symbolValue.x2) - parseInt(symbolValue.x1); + const dy = parseInt(symbolValue.y2) - parseInt(symbolValue.y1); + element.setAttribute(`x2`, px + dx + newX); + element.setAttribute(`y2`, py + dy + newY); + break; + case `rect`: + case `svgtext`: + element.setAttribute(`x`, px + newX); + element.setAttribute(`y`, py + newY); + break; + } + symbolValue.x = newX; + symbolValue.y = newY; + break; + } + return program[program.pc].pc + 1; + } + }, + + On: { + + compile: (compiler) => { + const lino = compiler.getLino(); + const action = compiler.nextToken(); + switch (action) { + case `click`: + if (compiler.nextIsSymbol()) { + const symbol = compiler.getSymbolRecord(); + compiler.next(); + if (symbol.keyword !== `group`) { + return false; + } + compiler.addCommand({ + domain: `svg`, + keyword: `on`, + lino, + action, + symbol: symbol.name + }); + // Add a 'goto' to skip the action + const goto = compiler.getPc(); + compiler.addCommand({ + domain: `core`, + keyword: `goto`, + goto: 0 + }); + // Add the action + compiler.compileOne(); + // Fixup the 'goto' + compiler.getCommandAt(goto).goto = compiler.getPc(); + return true; + } + } + compiler.addWarning(`Unrecognised syntax in 'on'`); + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const targetItem = program.getSymbolRecord(command.symbol); + switch (command.action) { + case `click`: + if (targetItem.keyword === `group`) { + // Iterate the group array + for (const groupValue of targetItem.value) { + if (groupValue.content) { + for (const value of groupValue.content) { + const contentItem = program.getSymbolRecord(value.name); + const contentValue = contentItem.value[value.index]; + if (contentValue.content) { + const target = document.getElementById(contentValue.content); + target.targetPc = command.pc + 2; + target.contentItem = contentItem; + target.contentIndex = value.index; + target.onclick = function (event) { + event.target.blur(); + const contentItem = event.target.contentItem; + contentItem.index = event.target.contentIndex; + const contentValue = contentItem.value[contentItem.index]; + if (contentValue.groupName) { + targetItem.index = contentValue.groupIndex; + // Set the content indices + const group = targetItem.value[targetItem.index]; + for (const gc of group.content) { + const gi = program.getSymbolRecord(gc.name); + gi.index = gc.index; + } + } + try { + program.run(event.target.targetPc); + } catch (err) { + program.reportError(err, program); + } + return false; + }; + } + } + } + } + } + break; + default: + break; + } + return command.pc + 1; + } + }, + + Rect: { + + compile: (compiler) => { + compiler.compileVariable(`svg`, `rect`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Set: { + + compile: (compiler) => { + const lino = compiler.getLino(); + var token = compiler.nextToken(); + if (token === `the`) { + token = compiler.nextToken(); + } + if (token === `text`) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbol = compiler.getSymbolRecord(); + switch (symbol.keyword) { + case `svgtext`: + if (compiler.nextTokenIs(`to`)) { + compiler.next(); + const value = compiler.getValue(); + compiler.addCommand({ + domain: `svg`, + keyword: `set`, + lino, + type: `setText`, + symbolName: symbol.name, + value + }); + return true; + } + break; + default: + break; + } + } + } + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + var symbol; + var value; + var target; + switch (command.type) { + case `setText`: + symbol = program.getSymbolRecord(command.symbolName); + target = document.getElementById(symbol.value[symbol.index].content); + value = program.value.evaluate(program, command.value).content; + switch (symbol.keyword) { + case `svgtext`: + target.innerHTML = value; + break; + default: + break; + } + break; + default: + break; + } + return command.pc + 1; + } + }, + + SVG: { + + compile: (compiler) => { + compiler.compileVariable(`svg`, `svg`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + SVGText: { + + compile: (compiler) => { + compiler.compileVariable(`svg`, `svgtext`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + getHandler: (name) => { + switch (name) { + case `circle`: + return EasyCoder_SVG.Circle; + case `create`: + return EasyCoder_SVG.Create; + case `ellipse`: + return EasyCoder_SVG.Ellipse; + case `group`: + return EasyCoder_SVG.Group; + case `line`: + return EasyCoder_SVG.Line; + case `move`: + return EasyCoder_SVG.Move; + case `on`: + return EasyCoder_SVG.On; + case `rect`: + return EasyCoder_SVG.Rect; + case `set`: + return EasyCoder_SVG.Set; + case `svg`: + return EasyCoder_SVG.SVG; + case `svgtext`: + return EasyCoder_SVG.SVGText; + default: + return null; + } + }, + + run: (program) => { + const command = program[program.pc]; + const handler = EasyCoder_SVG.getHandler(command.keyword); + if (!handler) { + program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'svg' package`); + } + return handler.run(program); + }, + + value: { + + compile: (compiler) => { + if (compiler.tokenIs(`the`)) { + compiler.next(); + } + if (compiler.tokenIs(`text`)) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + compiler.next(); + if (symbolRecord.keyword === `svgtext`) { + return { + domain: `svg`, + type: `svgtext`, + name: symbolRecord.name + }; + } + } + } + } + return null; + }, + + get: (program, value) => { + switch (value.type) { + case `svgtext`: + const symbolRecord = program.getSymbolRecord(value.name); + // console.log('symbolRecord: ' + JSON.stringify(symbolRecord.value[symbolRecord.index], null, 2)); + const element = document.getElementById(symbolRecord.value[symbolRecord.index].content); + return { + type: `constant`, + numeric: false, + content: element.innerHTML + }; + } + } + }, + + condition: { + + compile: () => {}, + + test: () => {} + } +}; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.svg = EasyCoder_SVG; diff --git a/easycoder/plugins/ui.js b/easycoder/plugins/ui.js new file mode 100644 index 0000000..b0ac935 --- /dev/null +++ b/easycoder/plugins/ui.js @@ -0,0 +1,373 @@ +const EasyCoder_UI = { + + name: `EasyCoder_UI`, + + monthNames: [ + `January`, + `February`, + `March`, + `April`, + `May`, + `June`, + `July`, + `August`, + `September`, + `October`, + `November`, + `December` + ], + + renderDate: (dateRecord) => { + const date = new Date(dateRecord.timestamp); + const day = date.getDate(); + const month = date.getMonth(); + const year = date.getFullYear(); + + const daysInMonth = [ + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 + ]; + + if (year % 4 === 0) { + daysInMonth[1] = 29; + } + + // Do the day list + const dayList = dateRecord.day; + while (dayList.firstChild) { + dayList.removeChild(dayList.lastChild); + } + for (var i = 0; i < daysInMonth[month]; i++) { + const option = new Option(String(i)); + option.value = i; + option.text = String(i + 1); + dayList.appendChild(option); + } + dayList.selectedIndex = day - 1; + + // Do the month list + const monthList = dateRecord.month; + while (monthList.firstChild) { + monthList.removeChild(monthList.lastChild); + } + EasyCoder_UI.monthNames.forEach(function (month, index) { + const option = document.createElement(`option`); + option.value = index; + option.text = month; + monthList.appendChild(option); + }); + monthList.selectedIndex = month; + + // Do the year list + const yearList = dateRecord.year; + while (yearList.firstChild) { + yearList.removeChild(yearList.lastChild); + } + const yr = new Date().getUTCFullYear(); + var sel = 0; + for (i = 0; i < 10; i++) { + const option = document.createElement(`option`); + var y = yr - i + 1; + option.value = y; + option.text = String(y); + if (y === year) { + sel = i; + } + yearList.appendChild(option); + } + yearList.selectedIndex = sel; + }, + + Create: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + const type = symbolRecord.keyword; + if (type === `date`) { + if (compiler.nextTokenIs(`in`)) { + if (compiler.nextIsSymbol()) { + const holderRecord = compiler.getSymbolRecord(); + compiler.next(); + var second = compiler.constant(-1, true); + var minute = compiler.constant(-1, true); + var hour = compiler.constant(-1, true); + var day = compiler.constant(-1, true); + var month = compiler.constant(-1, true); + var year = compiler.constant(-1, true); + while (true) { + const token = compiler.getToken(); + if (token === `second`) { + second = compiler.getNextValue(); + } else if (token === `minute`) { + minute = compiler.getNextValue(); + } else if (token === `hour`) { + hour = compiler.getNextValue(); + } else if (token === `day`) { + day = compiler.getNextValue(); + } else if (token === `month`) { + month = compiler.getNextValue(); + } else if (token === `year`) { + year = compiler.getNextValue(); + } else { + break; + } + } + compiler.addCommand({ + domain: `ui`, + keyword: `create`, + lino, + type, + date: symbolRecord.name, + holder: holderRecord.name, + day, + month, + year, + hour, + minute, + second, + format: `date` + }); + return true; + } + } + } + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + switch (command.type) { + case `date`: + const dateRecord = program.getSymbolRecord(command.date); + const dayList = document.createElement(`select`); + dayList.id = `ec-day`; + dateRecord.day = dayList; + const monthList = document.createElement(`select`); + dayList.id = `ec-month`; + dateRecord.month = monthList; + const yearList = document.createElement(`select`); + dayList.id = `ec-year`; + dateRecord.year = yearList; + + const holderRecord = program.getSymbolRecord(command.holder); + const holder = holderRecord.element[holderRecord.index]; + while (holder.firstChild) { + holder.removeChild(holder.lastChild); + } + holder.appendChild(dayList); + holder.appendChild(monthList); + holder.appendChild(yearList); + + // Get the requested values + var day = program.getValue(command.day); + var month = program.getValue(command.month); + var year = program.getValue(command.year); + const date = new Date(); + if (day !== -1) { + date.setDate(day); + } + if (month !== -1) { + date.setMonth(month); + } + if (year !== -1) { + date.setYear(year); + } + dateRecord.timestamp = date.getTime(); + EasyCoder_UI.renderDate(dateRecord); + + dayList.dateRecord = dateRecord; + monthList.dateRecord = dateRecord; + yearList.dateRecord = dateRecord; + + dayList.onchange = function () { + const date = new Date(this.dateRecord.timestamp); + date.setDate(this.selectedIndex + 1); + this.dateRecord.timestamp = date.getTime(); + EasyCoder_UI.renderDate(this.dateRecord); + }; + + monthList.onchange = function () { + const date = new Date(this.dateRecord.timestamp); + date.setMonth(this.selectedIndex); + this.dateRecord.timestamp = date.getTime(); + EasyCoder_UI.renderDate(this.dateRecord); + }; + + yearList.onchange = function () { + const date = new Date(this.dateRecord.timestamp); + date.setYear(this[this.selectedIndex].value); + this.dateRecord.timestamp = date.getTime(); + EasyCoder_UI.renderDate(this.dateRecord); + }; + break; + } + + return command.pc + 1; + } + }, + + Date: { + + compile: (compiler) => { + compiler.compileVariable(`ui`, `date`); + return true; + }, + + run: (program) => { + const command = program[program.pc]; + command.value = { + type: `constant`, + numeric: true, + content: Date.now() + }; + return command.pc + 1; + } + }, + + Set: { + + compile: (compiler) => { + const lino = compiler.getLino(); + compiler.skip(`the`); + const token = compiler.getToken(); + switch (token) { + case `date`: + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const dateRecord = compiler.getSymbolRecord(); + if (dateRecord.keyword === `date`) { + if (compiler.nextTokenIs(`to`)) { + const timestamp = compiler.getNextValue(); + compiler.addCommand({ + domain: `ui`, + keyword: `set`, + lino, + what: `date`, + date: dateRecord.name, + timestamp + }); + return true; + } + } + } + } + break; + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + switch (command.what) { + case `date`: + const dateRecord = program.getSymbolRecord(command.date); + dateRecord.timestamp = program.getValue(command.timestamp) * 1000; + EasyCoder_UI.renderDate(dateRecord); + break; + } + return command.pc + 1; + } + }, + + getHandler: (name) => { + switch (name) { + case `create`: + return EasyCoder_UI.Create; + case `date`: + return EasyCoder_UI.Date; + case `set`: + return EasyCoder_UI.Set; + default: + return null; + } + }, + + run: (program) => { + const command = program[program.pc]; + const handler = EasyCoder_UI.getHandler(command.keyword); + if (!handler) { + program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'ui' package`); + } + return handler.run(program); + }, + + value: { + + compile: (compiler) => { + if (compiler.isSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.keyword === `date`) { + compiler.next(); + return { + domain: `ui`, + type: `date`, + what: `timestamp`, + value: symbolRecord.name + }; + } + return null; + } + if (compiler.tokenIs(`the`)) { + compiler.next(); + } + const what = compiler.getToken(); + if ([`date`, `timestamp`].includes(what)) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.keyword === `date`) { + compiler.next(); + return { + domain: `ui`, + type: `date`, + what, + value: symbolRecord.name + }; + } + return null; + } + } + return null; + } + // Try other value possibilities + return null; + }, + + get: (program, value) => { + switch (value.type) { + case `date`: + const dateRecord = program.getSymbolRecord(value.value); + const day = dateRecord.day.options[dateRecord.day.selectedIndex].text; + const month = dateRecord.month.options[dateRecord.month.selectedIndex].value; + const year = dateRecord.year.options[dateRecord.year.selectedIndex].value; + const date = new Date(year, month, day, 0, 0, 0, 0); + switch (value.what) { + case `date`: + return { + type: `constant`, + numeric: false, + content: `${day} ${EasyCoder_UI.monthNames[month]} ${year}` + }; + case `timestamp`: + return { + type: `constant`, + numeric: true, + content: date.getTime() / 1000 + }; + } + } + } + }, + + condition: { + + compile: () => {}, + + test: () => {} + } +}; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.ui = EasyCoder_UI; diff --git a/easycoder/plugins/vfx.js b/easycoder/plugins/vfx.js new file mode 100644 index 0000000..a358f76 --- /dev/null +++ b/easycoder/plugins/vfx.js @@ -0,0 +1,346 @@ +const EasyCoder_VFX = { + + name: `EasyCoder_VFX`, + + ANIMATION: { + + compile: (compiler) => { + compiler.compileVariable(`vfx`, `animation`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + Create: { + + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + const keyword = symbolRecord.keyword; + if (keyword == `animation`) { + if (compiler.nextTokenIs(`in`)) { + if (compiler.nextIsSymbol()) { + const parentRecord = compiler.getSymbolRecord(); + compiler.next(); + compiler.addCommand({ + domain: `vfx`, + keyword: `create`, + lino, + name: symbolRecord.name, + parent: parentRecord.name + }); + return true; + } + } + } + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const targetRecord = program.getSymbolRecord(command.name); + const p = command.imported ? EasyCoder.scripts[program.parent] : program; + const parentRecord = p.getSymbolRecord(command.parent); + if (!parentRecord.element[parentRecord.index]) { + program.runtimeError(command.pc, `Element ${parentRecord.name} does not exist.`); + } + let parent = parentRecord.element[parentRecord.index]; + // Create the container + let container = document.createElement(`div`); + targetRecord.element[targetRecord.index] = container; + targetRecord.element[targetRecord.index].id = + `ec-${targetRecord.name}-${targetRecord.index}-${EasyCoder.elementId++}`; + parent.appendChild(container); + container.style[`position`] = `relative`; + container.style[`overflow`] = `hidden`; + if (typeof targetRecord.animation === `undefined`) { + targetRecord.animation = []; + for (let n = 0; n < targetRecord.elements; n++) { + targetRecord.animation.push({}); + } + } + const image = document.createElement(`img`); + targetRecord.animation[targetRecord.index].image = image; + container.appendChild(image); + image.style[`display`] = `none`; + image.style[`position`] = `absolute`; + image.style[`max-width`] = `none`; + return command.pc + 1; + } + }, + + On: { + + compile: compiler => { + const lino = compiler.getLino(); + const action = compiler.nextToken(); + switch (action) { + case `trigger`: + if (compiler.nextIsSymbol()) { + let symbolRecord = compiler.getSymbolRecord(); + if (symbolRecord.keyword === `animation`) { + compiler.next(); + compiler.addCommand({ + domain: `vfx`, + keyword: `on`, + lino, + action, + target:symbolRecord.name + }); + return compiler.completeHandler(); + } + break; + } + } + return false; + }, + + run: program => { + const command = program[program.pc]; + const cb = command.pc + 2; + const symbolRecord = program.getSymbolRecord(command.target); + switch (command.action) { + case `trigger`: + symbolRecord.onTrigger = cb; + break; + default: + program.runtimeError(command.lino, `Unknown action '${command.action}'`); + return 0; + } + return command.pc + 1; + } + }, + + Set: { + + compile: (compiler) => { + const lino = compiler.getLino(); + let type = compiler.nextToken(); + if (compiler.tokenIs(`the`)) { + type = compiler.nextToken(); + } + if ([`url`, `specification`, `spec`, `opacity`].includes(type)) { + if (compiler.nextTokenIs(`of`)) { + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + if (compiler.nextTokenIs(`to`)) { + const value = compiler.getNextValue(); + compiler.addCommand({ + domain: `vfx`, + keyword: `set`, + lino, + target: symbolRecord.name, + type, + value + }); + return true; + } + } + } + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + let targetRecord = program.getSymbolRecord(command.target); + let container = targetRecord.element[targetRecord.index]; + let animation; + switch (command.type) { + case `url`: + let url = program.getValue(command.value); + animation.image.setAttribute(`src`, url); + break; + case `specification`: + case `spec`: + animation = targetRecord.animation[targetRecord.index]; + let spec = JSON.parse(program.getValue(command.value)); + animation.spec = spec; + animation.step = spec.steps; + if (['panzoom'].includes(spec.type)) { + container.style.width = spec.width; + container.style.height = spec.height; + let width = container.getBoundingClientRect().width; + let height = container.getBoundingClientRect().height; + animation.widthS = width * 100 / spec.start.width; + let zoomS = animation.widthS / width; + let heightS = height * zoomS; + animation.leftS = width * zoomS * spec.start.left / 100; + animation.topS = height * zoomS * spec.start.top / 100; + animation.widthF = width * 100 / spec.finish.width; + let zoomF = animation.widthF / width; + let heightF = height * zoomF; + animation.leftF = width * zoomF * spec.finish.left / 100; + animation.topF = height * zoomF * spec.finish.top / 100; + + if (spec.start.width > 100) { + throw new Error(`Start width too great for item ${targetRecord.index}`); + } + if (spec.finish.width > 100) { + throw new Error(`Finish width too great for item ${targetRecord.index}`); + } + if (animation.widthS - animation.leftS < width) { + throw new Error(`Insufficient start width for item ${targetRecord.index}`); + } + if (heightS - animation.topS < height) { + throw new Error(`Insufficient start height for item ${targetRecord.index}`); + } + if (animation.widthF - animation.leftF < width) { + throw new Error(`Insufficient finish width for item ${targetRecord.index}`); + } + if (heightF - animation.topF < height) { + throw new Error(`Insufficient finish height for item ${targetRecord.index}`); + } + animation.left = animation.leftS; + animation.top = animation.topS; + animation.width = animation.widthS; + let image = animation.image; + image.style.left = `-${animation.left}px`; + image.style.top = `-${animation.top}px`; + image.style.width = `${animation.width}px`; + image.setAttribute(`src`, spec.url); + } else { + program.runtimeError(command.lino, `Unknown animation type '${spec.type}'`); + return 0; + } + case `opacity`: + animation = targetRecord.animation[targetRecord.index]; + let image = animation.image; + image.style.opacity = command.value; + break; + } + return command.pc + 1; + } + }, + + Start: { + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + const keyword = symbolRecord.keyword; + if (keyword == `animation`) { + compiler.next(); + compiler.addCommand({ + domain: `vfx`, + keyword: `start`, + lino, + target: symbolRecord.name + }); + return true; + } + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const targetRecord = program.getSymbolRecord(command.target); + const animation = targetRecord.animation[targetRecord.index]; + animation.step = 0; + animation.left = animation.leftS; + animation.top = animation.topS; + animation.width = animation.widthS; + animation.image.style.display = `inline-block`; + return command.pc + 1; + } + }, + + Step: { + compile: (compiler) => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const symbolRecord = compiler.getSymbolRecord(); + const keyword = symbolRecord.keyword; + if (keyword == `animation`) { + compiler.next(); + compiler.addCommand({ + domain: `vfx`, + keyword: `step`, + lino, + target: symbolRecord.name + }); + return true; + } + } + return false; + }, + + run: (program) => { + const command = program[program.pc]; + const targetRecord = program.getSymbolRecord(command.target); + for (targetRecord.index = 0; targetRecord.index < targetRecord.elements; targetRecord.index++) { + const animation = targetRecord.animation[targetRecord.index]; + if (animation.step < animation.spec.steps) { + animation.step++; + let proportion = parseFloat(animation.step) / animation.spec.steps; + animation.left = animation.leftS + (animation.leftF - animation.leftS) * proportion; + animation.top = animation.topS + (animation.topF - animation.topS) * proportion; + animation.width = animation.widthS + (animation.widthF - animation.widthS) * proportion; + const image = animation.image; + image.style.left = `-${animation.left}px`; + image.style.top = `-${animation.top}px`; + image.style.width = `${animation.width}px`; + if (animation.step === animation.spec.trigger) { + program.run(targetRecord.onTrigger); + } + } + } + return command.pc + 1; + } + }, + + getHandler: (name) => { + switch (name) { + case `animation`: + return EasyCoder_VFX.ANIMATION; + case `create`: + return EasyCoder_VFX.Create; + case `on`: + return EasyCoder_VFX.On; + case `set`: + return EasyCoder_VFX.Set; + case `start`: + return EasyCoder_VFX.Start; + case `step`: + return EasyCoder_VFX.Step; + default: + return null; + } + }, + + run: program => { + const command = program[program.pc]; + const handler = EasyCoder_VFX.getHandler(command.keyword); + if (!handler) { + program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'vfx' package`); + } + return handler.run(program); + }, + + value: { + + compile: () => { + return null; + }, + + get: () => { + return null; + } + }, + + condition: { + + compile: () => {}, + + test: () => {} + } +}; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.vfx = EasyCoder_VFX; diff --git a/easycoder/plugins/wof.js b/easycoder/plugins/wof.js new file mode 100644 index 0000000..8c63fcd --- /dev/null +++ b/easycoder/plugins/wof.js @@ -0,0 +1,285 @@ +// eslint-disable-next-line no-unused-vars +const EasyCoder_WOF = { + + name: `EasyCoder_WOF`, + + /* + A package to draw and manage a roulette wheel. + */ + + Draw: { + + compile: compiler => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const wheelRecord = compiler.getSymbolRecord(); + if (wheelRecord.keyword === `wheel`) { + if (compiler.nextTokenIs(`in`)) { + if (compiler.nextIsSymbol()) { + const canvasRecord = compiler.getSymbolRecord(); + if (canvasRecord.keyword === `canvas`) { + compiler.next(); + compiler.addCommand({ + domain: `wof`, + keyword: `draw`, + lino, + wheel: wheelRecord.name, + canvas: canvasRecord.name + }); + return true; + } + } + } + } + } + return false; + }, + + run: program => { + const command = program[program.pc]; + const wheelRecord = program.getSymbolRecord(command.wheel); + const canvasRecord = program.getSymbolRecord(command.canvas); + const canvas = canvasRecord.element[canvasRecord.index]; + canvas.width = canvas.clientWidth; + canvas.height = canvas.clientHeight; + const wheel = EasyCoder_roulette_wheel; + wheelRecord.wheel = wheel; + wheel.canvas = canvas; + wheel.init(wheel); + wheel.drawRouletteWheel(wheel); + return command.pc + 1; + } + }, + + Spin: { + + compile: compiler => { + const lino = compiler.getLino(); + if (compiler.nextIsSymbol()) { + const wheelRecord = compiler.getSymbolRecord(); + if (wheelRecord.keyword === `wheel`) { + compiler.next(); + compiler.addCommand({ + domain: `wof`, + keyword: `spin`, + lino, + wheel: wheelRecord.name + }); + return true; + } + } + return false; + }, + + run: program => { + const command = program[program.pc]; + const wheelRecord = program.getSymbolRecord(command.wheel); + wheelRecord.wheel.spin(wheelRecord.wheel); + return command.pc + 1; + } + }, + + Wheel: { + + compile: (compiler) => { + compiler.compileVariable(`wof`, `wheel`, false, `dom`); + return true; + }, + + run: (program) => { + return program[program.pc].pc + 1; + } + }, + + getHandler: (name) => { + switch (name) { + case `draw`: + return EasyCoder_WOF.Draw; + case `spin`: + return EasyCoder_WOF.Spin; + case `wheel`: + return EasyCoder_WOF.Wheel; + default: + return null; + } + }, + + run: (program) => { + const command = program[program.pc]; + const handler = EasyCoder_WOF.getHandler(command.keyword); + if (!handler) { + program.runtimeError(command.lino, `Unknown keyword '${command.keyword}' in 'wof' package`); + } + return handler.run(program); + }, + + value: { + + compile: (compiler) => { + if (compiler.tokenIs(`anagrams`)) { + if (compiler.nextTokenIs(`of`)) { + const value = compiler.getNextValue(); + return { + domain: `anagrams`, + type: `getAnagrams`, + value + }; + } + } + return null; + }, + + get: (program, value) => { + switch (value.type) { + case `getAnagrams`: + return { + type: `constant`, + numeric: false, + content: JSON.stringify(AnagramFinder.getAnagrams(program.getValue(value.value), EasyCoder_words)) + }; + } + return null; + } + }, + + condition: { + + compile: () => {} + }, +}; + +// A sample roulette wheel +const EasyCoder_roulette_wheel = { + + init: ($) => { + $.options = [`$100`, `$10`, `$25`, `$250`, `$30`, `$1000`, `$1`, `$200`, `$45`, `$500`, `$5`, `$20`, `Lose`, `$1000000`, `Lose`, `$350`, `$5`, `$99`]; + $.startAngle = 0; + $.arc = Math.PI / ($.options.length / 2); + $.spinTimeout = null; + $.spinArcStart = 10; + $.spinTime = 0; + $.spinTimeTotal = 0; + $.ctx = null; + }, + + byte2Hex: (n) => { + var nybHexString = `0123456789ABCDEF`; + return String(nybHexString.substr((n >> 4) & 0x0F,1)) + nybHexString.substr(n & 0x0F,1); + }, + + RGB2Color: ($,r,g,b) => { + return `#` + $.byte2Hex(r) + $.byte2Hex(g) + $.byte2Hex(b); + }, + + getColor: ($, item, maxitem) => { + var phase = 0; + var center = 128; + var width = 127; + var frequency = Math.PI*2/maxitem; + + var red = Math.sin(frequency*item+2+phase) * width + center; + var green = Math.sin(frequency*item+0+phase) * width + center; + var blue = Math.sin(frequency*item+4+phase) * width + center; + + return $.RGB2Color($,red,green,blue); + }, + + drawRouletteWheel: ($) => { + const canvas = $.canvas; + const width = canvas.width; + const height = canvas.height; + $.width = width; + $.height = height; + if (canvas.getContext) { + var outsideRadius = 200*width/500; + var textRadius = 160*width/500; + var insideRadius = 125*width/500; + + $.ctx = canvas.getContext(`2d`); + $.ctx.clearRect(0,0,width,height); + + $.ctx.strokeStyle = `black`; + $.ctx.lineWidth = 2; + + $.ctx.font = `bold ${12*width/500}px Helvetica, Arial`; + + for(var i = 0; i < $.options.length; i++) { + var angle = $.startAngle + i * $.arc; + //ctx.fillStyle = colors[i]; + $.ctx.fillStyle = $.getColor($, i, $.options.length); + + $.ctx.beginPath(); + $.ctx.arc(width/2, height/2, outsideRadius, angle, angle + $.arc, false); + $.ctx.arc(width/2, height/2, insideRadius, angle + $.arc, angle, true); + $.ctx.stroke(); + $.ctx.fill(); + + $.ctx.save(); + $.ctx.shadowOffsetX = -1; + $.ctx.shadowOffsetY = -1; + $.ctx.shadowBlur = 0; + $.ctx.shadowColor = `rgb(220,220,220)`; + $.ctx.fillStyle = `black`; + $.ctx.translate(width/2 + Math.cos(angle + $.arc / 2) * textRadius, + height/2 + Math.sin(angle + $.arc / 2) * textRadius); + $.ctx.rotate(angle + $.arc / 2 + Math.PI / 2); + var text = $.options[i]; + $.ctx.fillText(text, -$.ctx.measureText(text).width / 2, 0); + $.ctx.restore(); + } + + //Arrow + $.ctx.fillStyle = `black`; + $.ctx.beginPath(); + $.ctx.moveTo(width/2 - 4, height/2 - (outsideRadius + 5)); + $.ctx.lineTo(width/2 + 4, height/2 - (outsideRadius + 5)); + $.ctx.lineTo(width/2 + 4, height/2 - (outsideRadius - 5)); + $.ctx.lineTo(width/2 + 9, height/2 - (outsideRadius - 5)); + $.ctx.lineTo(width/2 + 0, height/2 - (outsideRadius - 13)); + $.ctx.lineTo(width/2 - 9, height/2 - (outsideRadius - 5)); + $.ctx.lineTo(width/2 - 4, height/2 - (outsideRadius - 5)); + $.ctx.lineTo(width/2 - 4, height/2 - (outsideRadius + 5)); + $.ctx.fill(); + } + }, + + easeOut: (t, b, c, d) => { + var ts = (t/=d)*t; + var tc = ts*t; + return b+c*(tc + -3*ts + 3*t); + }, + + stopRotateWheel: ($) => { + clearTimeout($.spinTimeout); + var degrees = $.startAngle * 180 / Math.PI + 90; + var arcd = $.arc * 180 / Math.PI; + var index = Math.floor((360 - degrees % 360) / arcd); + $.ctx.save(); + $.ctx.font = `bold ${30*$.width/500}px Helvetica, Arial`; + var text = $.options[index]; + $.ctx.fillText(text, $.width/2 - $.ctx.measureText(text).width / 2, $.height/2 + 10*$.height/500); + $.ctx.restore(); + }, + + rotateWheel: ($) => { + $.spinTime += 30; + if($.spinTime >= $.spinTimeTotal) { + $.stopRotateWheel($); + return; + } + var spinAngle = $.spinArcStart - $.easeOut($.spinTime, 0, $.spinArcStart, $.spinTimeTotal); + $.startAngle += (spinAngle * Math.PI / 180); + $.drawRouletteWheel($); + $.spinTimeout = setTimeout(function(){ $.rotateWheel($); }, 30); + }, + + spin: ($) => { + $.spinArcStart = Math.random() * 10 + 10; + $.spinTime = 0; + $.spinTimeTotal = Math.random() * 3 + 4 * 1000; + $.rotateWheel($); + } +}; + +// eslint-disable-next-line no-unused-vars +EasyCoder.domain.wof = EasyCoder_WOF; From 0ffaf17b196d1f3d361da6ff8138254489ee5ef6 Mon Sep 17 00:00:00 2001 From: Graham Trott Date: Mon, 13 Apr 2020 14:09:41 +0100 Subject: [PATCH 6/6] Remove plugins lists --- easycoder/easycoder-min.js | 117 ++++++++++++++++++------------------- easycoder/easycoder.js | 6 +- js/easycoder/Browser.js | 2 +- js/easycoder/Rest.js | 4 +- js/plugins-all.js | 25 -------- js/plugins-st.js | 24 -------- 6 files changed, 62 insertions(+), 116 deletions(-) delete mode 100644 js/plugins-all.js delete mode 100644 js/plugins-st.js diff --git a/easycoder/easycoder-min.js b/easycoder/easycoder-min.js index 1031c7d..c3699a1 100644 --- a/easycoder/easycoder-min.js +++ b/easycoder/easycoder-min.js @@ -150,29 +150,29 @@ variant:"setup",lino:b,variables:c,alignment:d});return!0}a.addCommand({domain:" b.style.display="none";a.tracing=!0}a.stop=!1}return a.pc+1}},UL:{compile:function(a){a.compileVariable("browser","ul",!1,"dom");return!0},run:function(a){return a[a.pc].pc+1}},Upload:{compile:function(a){var b=a.getLino();if(a.nextIsSymbol()){var c=a.getToken();if(a.nextTokenIs("to")){var d=a.getNextValue();if(a.tokenIs("with")&&a.nextIsSymbol()){var e=a.getToken();if(a.nextTokenIs("and")&&a.nextIsSymbol()){var f=a.getToken();a.next();a.addCommand({domain:"browser",keyword:"upload",lino:b,file:c, path:d,progress:e,status:f});return!0}}}}return!1},run:function(a){var b=a[a.pc],c=a.getSymbolRecord(b.file),d=a.getValue(b.path),e=a.getSymbolRecord(b.progress),f=a.getSymbolRecord(b.status),k=e.element[e.index],g=f.element[f.index],h=function(a){g&&(g.innerHTML=a)};if(e=c.element[c.index].files[0])c=new FormData,c.append("source",e),c.append("path",d),e=new XMLHttpRequest,e.upload.addEventListener("progress",function(a){a=Math.round(a.loaded/a.total*100);k&&(k.value=a);h(Math.round(a)+"%...")}, !1),e.addEventListener("load",function(a){a=a.target.responseText;k&&(k.value=0);h("");console.log(a)},!1),e.addEventListener("error",function(){h("Upload failed");console.log("Upload failed")},!1),e.addEventListener("abort",function(){h("Upload aborted");console.log("Upload aborted")},!1),e.onreadystatechange=function(){if(4===this.readyState){var b=a.ajaxCommand,c=this.status;switch(c){case 200:a.run(b.pc+1);break;case 0:break;default:try{a.runtimeError(b.lino,"Error "+c)}catch(p){a.reportError(p, -a)}}}},a.ajaxCommand=b,b=d.startsWith("http")?d:window.location.origin+"/"+EasyCoder_Plugins.rest()+"/"+d,e.open("POST",b),e.send(c);return 0}},getHandler:function(a){switch(a){case "a":return EasyCoder_Browser.A;case "alert":return EasyCoder_Browser.Alert;case "attach":return EasyCoder_Browser.Attach;case "audioclip":return EasyCoder_Browser.Audioclip;case "blockquote":return EasyCoder_Browser.BLOCKQUOTE;case "button":return EasyCoder_Browser.BUTTON;case "canvas":return EasyCoder_Browser.CANVAS; -case "clear":return EasyCoder_Browser.Clear;case "convert":return EasyCoder_Browser.Convert;case "create":return EasyCoder_Browser.Create;case "disable":return EasyCoder_Browser.Disable;case "div":return EasyCoder_Browser.DIV;case "enable":return EasyCoder_Browser.Enable;case "fieldset":return EasyCoder_Browser.FIELDSET;case "file":return EasyCoder_Browser.FILE;case "focus":return EasyCoder_Browser.Focus;case "form":return EasyCoder_Browser.FORM;case "fullscreen":return EasyCoder_Browser.FullScreen; -case "get":return EasyCoder_Browser.Get;case "h1":return EasyCoder_Browser.H1;case "h2":return EasyCoder_Browser.H2;case "h3":return EasyCoder_Browser.H3;case "h4":return EasyCoder_Browser.H4;case "h5":return EasyCoder_Browser.H5;case "h6":return EasyCoder_Browser.H6;case "highlight":return EasyCoder_Browser.Highlight;case "history":return EasyCoder_Browser.History;case "hr":return EasyCoder_Browser.HR;case "image":return EasyCoder_Browser.IMAGE;case "img":return EasyCoder_Browser.IMG;case "input":return EasyCoder_Browser.INPUT; -case "label":return EasyCoder_Browser.LABEL;case "legend":return EasyCoder_Browser.LEGEND;case "li":return EasyCoder_Browser.LI;case "location":return EasyCoder_Browser.Location;case "mail":return EasyCoder_Browser.Mail;case "on":return EasyCoder_Browser.On;case "option":return EasyCoder_Browser.OPTION;case "p":return EasyCoder_Browser.P;case "play":return EasyCoder_Browser.Play;case "pre":return EasyCoder_Browser.PRE;case "progress":return EasyCoder_Browser.PROGRESS;case "put":return EasyCoder_Browser.Put; -case "remove":return EasyCoder_Browser.Remove;case "request":return EasyCoder_Browser.Request;case "select":return EasyCoder_Browser.SELECT;case "scroll":return EasyCoder_Browser.Scroll;case "section":return EasyCoder_Browser.SECTION;case "set":return EasyCoder_Browser.Set;case "span":return EasyCoder_Browser.SPAN;case "table":return EasyCoder_Browser.TABLE;case "tr":return EasyCoder_Browser.TR;case "td":return EasyCoder_Browser.TD;case "textarea":return EasyCoder_Browser.TEXTAREA;case "trace":return EasyCoder_Browser.Trace; -case "ul":return EasyCoder_Browser.UL;case "upload":return EasyCoder_Browser.Upload;default:return null}},run:function(a){var b=a[a.pc],c=EasyCoder_Browser.getHandler(b.keyword);c||a.runtimeError(b.lino,"Unknown keyword '"+b.keyword+"' in 'browser' package");return c.run(a)},value:{compile:function(a){if(a.isSymbol()){var b=a.getSymbolRecord();if(a.nextTokenIs("exists"))return"dom"===b.extra?(a.next(),{domain:"browser",type:"exists",value:b.name}):null;switch(b.keyword){case "file":case "input":case "select":case "textarea":return{domain:"browser", -type:b.keyword,value:b.name}}return null}a.tokenIs("the")&&a.next();var c=!1;a.tokenIs("offset")&&(c=!0,a.next());b=a.getToken();switch(b){case "mobile":case "portrait":case "landscape":case "br":case "location":case "key":case "hostname":return a.next(),{domain:"browser",type:b};case "content":case "text":if(a.nextTokenIs("of")){if(a.nextIsSymbol())return b=a.getSymbolRecord(),a.next(),{domain:"browser",type:"contentOf",symbol:b.name};throw Error("'"+a.getToken()+"' is not a symbol");}break;case "selected":b= -a.nextToken();if(["index","item"].includes(b)&&["in","of"].includes(a.nextToken())&&a.nextIsSymbol()&&(c=a.getSymbolRecord(),["ul","ol","select"].includes(c.keyword)))return a.next(),{domain:"browser",type:"selected",symbol:c.name,arg:b};break;case "color":return a.next(),a=a.getValue(),{domain:"browser",type:b,value:a};case "attribute":c=a.getNextValue();if(a.tokenIs("of")&&(a.next(),a.isSymbol()&&(b=a.getSymbolRecord(),"dom"===b.extra)))return a.next(),{domain:"browser",type:"attributeOf",attribute:c, -symbol:b.name};break;case "style":c=a.getNextValue();if(a.tokenIs("of")&&a.nextIsSymbol()){var d=a.getSymbolRecord();if("dom"===d.extra)return a.next(),{domain:"browser",type:b,style:c,target:d.name}}break;case "confirm":return b=a.getNextValue(),{domain:"browser",type:"confirm",text:b};case "prompt":return b=a.getNextValue(),c=null,a.tokenIs("with")&&(c=a.getNextValue()),{domain:"browser",type:"prompt",text:b,pre:c};case "screen":c=a.nextToken();if(["width","height"].includes(c))return a.next(), -{domain:"browser",type:b,attribute:c};break;case "top":case "bottom":case "left":case "right":case "width":case "height":return EasyCoder_Browser.value.getCoord(a,b,c);case "scroll":if(a.nextTokenIs("position"))return a.next(),{domain:"browser",type:"scrollPosition"};break;case "document":if(a.nextTokenIs("path"))return a.next(),{domain:"browser",type:"docPath"};break;case "storage":if(a.nextTokenIs("keys"))return a.next(),{domain:"browser",type:"storageKeys"};break;case "parent":switch(a.nextToken()){case "name":return a.next(), -{domain:"browser",type:"varName"};case "index":return a.next(),{domain:"browser",type:"varIndex"}}break;case "history":if(a.nextTokenIs("state"))return a.next(),{domain:"browser",type:"historyState"};break;case "pick":case "drag":if(a.nextTokenIs("position"))return a.next(),{domain:"browser",type:b+"Position"}}return null},getCoord:function(a,b,c){if(a.nextTokenIs("of")){if(a.nextTokenIs("window"))return a.next(),{domain:"browser",type:b,symbol:"window",offset:c};if(a.isSymbol()){var d=a.getSymbolRecord(); -if("dom"===d.extra)return a.next(),{domain:"browser",type:b,symbol:d.name,offset:c}}}return null},get:function(a,b){switch(b.type){case "file":case "input":case "select":case "textarea":var c=a.getSymbolRecord(b.value);var d=c.element[c.index];return{type:"constant",numeric:!1,content:d.value};case "exists":return c=a.getSymbolRecord(b.value),{domain:"browser",type:"boolean",content:"undefined"!==typeof c.element[c.index]};case "mobile":return{domain:"browser",type:"boolean",content:"undefined"!== -typeof window.orientation||-1!==navigator.userAgent.indexOf("IEMobile")};case "portrait":return{domain:"browser",type:"boolean",content:document.documentElement.clientWidth=document.documentElement.clientHeight};case "br":return{type:"constant",numeric:!1,content:decodeURIComponent("%3Cbr%20%2F%3E")};case "attributeOf":return c=a.getSymbolRecord(b.symbol),b= -a.getValue(b.attribute),d=c.element[c.index],0===b.indexOf("data-")?a.getSimpleValue(d.dataset[b.substr(5)]):a.getSimpleValue(d[b]);case "style":return c=a.getSymbolRecord(b.target),b=a.getValue(b.style),d=c.element[c.index],a.getSimpleValue(d.style[b]);case "confirm":return{type:"boolean",content:window.confirm(a.getValue(b.text))};case "prompt":return d=a.getValue(b.text),b=a.getValue(b.pre),{type:"constant",numeric:!1,content:b?window.prompt(d,b):window.prompt(d)};case "contentOf":c=a.getSymbolRecord(b.symbol); -d=c.element[c.index];switch(c.keyword){case "input":case "textarea":b=d.value;break;case "pre":b=d.innerHTML;break;default:b=d.innerHTML.split("\n").join("")}return{type:"constant",numeric:!1,content:b};case "selected":return c=a.getSymbolRecord(b.symbol),d=c.element[c.index],a=d.selectedIndex,d=0<=a?d.options[a].text:"",b="index"===b.arg?a:d,{type:"constant",numeric:!1,content:b};case "top":if("window"==b.symbol)return{type:"constant",numeric:!0,content:window.screenY};c=a.getSymbolRecord(b.symbol); -a=c.element[c.index];b=Math.round(b.offset?a.offsetTop:a.getBoundingClientRect().top);return{type:"constant",numeric:!0,content:b};case "bottom":if("window"==b.symbol)return{type:"constant",numeric:!0,content:window.screenY+window.innerHeight};c=a.getSymbolRecord(b.symbol);b=Math.round(c.element[c.index].getBoundingClientRect().bottom);return{type:"constant",numeric:!0,content:b};case "left":if("window"==b.symbol)return{type:"constant",numeric:!0,content:window.screenLeft};c=a.getSymbolRecord(b.symbol); -a=c.element[c.index];b=Math.round(b.offset?a.offsetLeft:a.getBoundingClientRect().left);return{type:"constant",numeric:!0,content:b};case "right":if("window"==b.symbol)return{type:"constant",numeric:!0,content:window.screenX+window.innerWidth};c=a.getSymbolRecord(b.symbol);b=Math.round(c.element[c.index].getBoundingClientRect().right);return{type:"constant",numeric:!0,content:b};case "width":if("window"==b.symbol)return{type:"constant",numeric:!0,content:window.innerWidth};c=a.getSymbolRecord(b.symbol); -b=Math.round(c.element[c.index].getBoundingClientRect().width);return{type:"constant",numeric:!0,content:b};case "height":if("window"==b.symbol)return{type:"constant",numeric:!0,content:window.innerHeight};c=a.getSymbolRecord(b.symbol);b=Math.round(c.element[c.index].getBoundingClientRect().height);return{type:"constant",numeric:!0,content:b};case "color":return{type:"constant",numeric:!1,content:"#"+a.value.evaluate(a,b.value).content.toString(16).padStart(6,"0")};case "docPath":return{type:"constant", -numeric:!1,content:a.docPath};case "storageKeys":return{type:"constant",numeric:!1,content:JSON.stringify(Object.keys(localStorage))};case "location":return{type:"constant",numeric:!1,content:window.location.href};case "historyState":return{type:"constant",numeric:!1,content:window.history.state};case "scrollPosition":return{type:"constant",numeric:!0,content:scrollPosition};case "varName":return{type:"constant",numeric:!1,content:a.varName};case "varIndex":return{type:"constant",numeric:!0,content:a.varIndex}; -case "key":return{type:"constant",numeric:!1,content:a.key};case "hostname":return{type:"constant",numeric:!1,content:location.hostname};case "screen":return{type:"constant",numeric:!0,content:screen[b.attribute]};case "pickPosition":return{type:"constant",numeric:!1,content:JSON.stringify({x:document.pickX,y:document.pickY})};case "dragPosition":return{type:"constant",numeric:!1,content:JSON.stringify({x:document.dragX,y:document.dragY})}}}},condition:{compile:function(a){if(a.tokenIs("confirm"))return{domain:"browser", -type:"confirm",value:a.getNextValue()};if(a.tokenIs("element")&&a.nextIsSymbol()){var b=a.getSymbolRecord();if("dom"===b.extra){var c=a.nextToken();if("has"===c){if(a.nextTokenIs("the")&&a.next(),a.tokenIs("focus"))return a.next(),{domain:"browser",type:"focus",element:b.name}}else if("contains"===c)return a=a.getNextValue(),{domain:"browser",type:"contains",element:b.name,position:a}}}return null},test:function(a,b){switch(b.type){case "confirm":return confirm(a.getValue(b.value));case "focus":var c= -a.getSymbolRecord(b.element);return c.element[c.index]===document.activeElement;case "contains":c=a.getSymbolRecord(b.element);var d=c.element[c.index].getBoundingClientRect();c=Math.round(d.left);var e=Math.round(d.right),f=Math.round(d.top);d=Math.round(d.bottom);b=JSON.parse(a.getValue(b.position));a=b.x;b=b.y;return a>=c&&a<=e&&b>=f&&b<=d?!0:!1}}},setStyles:function(a,b){a=document.getElementById(a);b=b.split(";");b=$jscomp.makeIterator(b);for(var c=b.next();!c.done;c=b.next())c=c.value.split(":"), -a.setAttribute(c[0],c[1])}},scrollPosition=0;window.addEventListener("scroll",function(){scrollPosition=this.scrollY});window.onpopstate=function(a){window.EasyCoder.timestamp=Date.now();(a=JSON.parse(a.state))&&a.script&&((a=window.EasyCoder.scripts[a.script])?a.onBrowserBack&&a.run(a.onBrowserBack):console.log("No script property in window state object"))}; +a)}}}},a.ajaxCommand=b,b=d.startsWith("http")?d:window.location.origin+"//"+d,e.open("POST",b),e.send(c);return 0}},getHandler:function(a){switch(a){case "a":return EasyCoder_Browser.A;case "alert":return EasyCoder_Browser.Alert;case "attach":return EasyCoder_Browser.Attach;case "audioclip":return EasyCoder_Browser.Audioclip;case "blockquote":return EasyCoder_Browser.BLOCKQUOTE;case "button":return EasyCoder_Browser.BUTTON;case "canvas":return EasyCoder_Browser.CANVAS;case "clear":return EasyCoder_Browser.Clear; +case "convert":return EasyCoder_Browser.Convert;case "create":return EasyCoder_Browser.Create;case "disable":return EasyCoder_Browser.Disable;case "div":return EasyCoder_Browser.DIV;case "enable":return EasyCoder_Browser.Enable;case "fieldset":return EasyCoder_Browser.FIELDSET;case "file":return EasyCoder_Browser.FILE;case "focus":return EasyCoder_Browser.Focus;case "form":return EasyCoder_Browser.FORM;case "fullscreen":return EasyCoder_Browser.FullScreen;case "get":return EasyCoder_Browser.Get;case "h1":return EasyCoder_Browser.H1; +case "h2":return EasyCoder_Browser.H2;case "h3":return EasyCoder_Browser.H3;case "h4":return EasyCoder_Browser.H4;case "h5":return EasyCoder_Browser.H5;case "h6":return EasyCoder_Browser.H6;case "highlight":return EasyCoder_Browser.Highlight;case "history":return EasyCoder_Browser.History;case "hr":return EasyCoder_Browser.HR;case "image":return EasyCoder_Browser.IMAGE;case "img":return EasyCoder_Browser.IMG;case "input":return EasyCoder_Browser.INPUT;case "label":return EasyCoder_Browser.LABEL;case "legend":return EasyCoder_Browser.LEGEND; +case "li":return EasyCoder_Browser.LI;case "location":return EasyCoder_Browser.Location;case "mail":return EasyCoder_Browser.Mail;case "on":return EasyCoder_Browser.On;case "option":return EasyCoder_Browser.OPTION;case "p":return EasyCoder_Browser.P;case "play":return EasyCoder_Browser.Play;case "pre":return EasyCoder_Browser.PRE;case "progress":return EasyCoder_Browser.PROGRESS;case "put":return EasyCoder_Browser.Put;case "remove":return EasyCoder_Browser.Remove;case "request":return EasyCoder_Browser.Request; +case "select":return EasyCoder_Browser.SELECT;case "scroll":return EasyCoder_Browser.Scroll;case "section":return EasyCoder_Browser.SECTION;case "set":return EasyCoder_Browser.Set;case "span":return EasyCoder_Browser.SPAN;case "table":return EasyCoder_Browser.TABLE;case "tr":return EasyCoder_Browser.TR;case "td":return EasyCoder_Browser.TD;case "textarea":return EasyCoder_Browser.TEXTAREA;case "trace":return EasyCoder_Browser.Trace;case "ul":return EasyCoder_Browser.UL;case "upload":return EasyCoder_Browser.Upload; +default:return null}},run:function(a){var b=a[a.pc],c=EasyCoder_Browser.getHandler(b.keyword);c||a.runtimeError(b.lino,"Unknown keyword '"+b.keyword+"' in 'browser' package");return c.run(a)},value:{compile:function(a){if(a.isSymbol()){var b=a.getSymbolRecord();if(a.nextTokenIs("exists"))return"dom"===b.extra?(a.next(),{domain:"browser",type:"exists",value:b.name}):null;switch(b.keyword){case "file":case "input":case "select":case "textarea":return{domain:"browser",type:b.keyword,value:b.name}}return null}a.tokenIs("the")&& +a.next();var c=!1;a.tokenIs("offset")&&(c=!0,a.next());b=a.getToken();switch(b){case "mobile":case "portrait":case "landscape":case "br":case "location":case "key":case "hostname":return a.next(),{domain:"browser",type:b};case "content":case "text":if(a.nextTokenIs("of")){if(a.nextIsSymbol())return b=a.getSymbolRecord(),a.next(),{domain:"browser",type:"contentOf",symbol:b.name};throw Error("'"+a.getToken()+"' is not a symbol");}break;case "selected":b=a.nextToken();if(["index","item"].includes(b)&& +["in","of"].includes(a.nextToken())&&a.nextIsSymbol()&&(c=a.getSymbolRecord(),["ul","ol","select"].includes(c.keyword)))return a.next(),{domain:"browser",type:"selected",symbol:c.name,arg:b};break;case "color":return a.next(),a=a.getValue(),{domain:"browser",type:b,value:a};case "attribute":c=a.getNextValue();if(a.tokenIs("of")&&(a.next(),a.isSymbol()&&(b=a.getSymbolRecord(),"dom"===b.extra)))return a.next(),{domain:"browser",type:"attributeOf",attribute:c,symbol:b.name};break;case "style":c=a.getNextValue(); +if(a.tokenIs("of")&&a.nextIsSymbol()){var d=a.getSymbolRecord();if("dom"===d.extra)return a.next(),{domain:"browser",type:b,style:c,target:d.name}}break;case "confirm":return b=a.getNextValue(),{domain:"browser",type:"confirm",text:b};case "prompt":return b=a.getNextValue(),c=null,a.tokenIs("with")&&(c=a.getNextValue()),{domain:"browser",type:"prompt",text:b,pre:c};case "screen":c=a.nextToken();if(["width","height"].includes(c))return a.next(),{domain:"browser",type:b,attribute:c};break;case "top":case "bottom":case "left":case "right":case "width":case "height":return EasyCoder_Browser.value.getCoord(a, +b,c);case "scroll":if(a.nextTokenIs("position"))return a.next(),{domain:"browser",type:"scrollPosition"};break;case "document":if(a.nextTokenIs("path"))return a.next(),{domain:"browser",type:"docPath"};break;case "storage":if(a.nextTokenIs("keys"))return a.next(),{domain:"browser",type:"storageKeys"};break;case "parent":switch(a.nextToken()){case "name":return a.next(),{domain:"browser",type:"varName"};case "index":return a.next(),{domain:"browser",type:"varIndex"}}break;case "history":if(a.nextTokenIs("state"))return a.next(), +{domain:"browser",type:"historyState"};break;case "pick":case "drag":if(a.nextTokenIs("position"))return a.next(),{domain:"browser",type:b+"Position"}}return null},getCoord:function(a,b,c){if(a.nextTokenIs("of")){if(a.nextTokenIs("window"))return a.next(),{domain:"browser",type:b,symbol:"window",offset:c};if(a.isSymbol()){var d=a.getSymbolRecord();if("dom"===d.extra)return a.next(),{domain:"browser",type:b,symbol:d.name,offset:c}}}return null},get:function(a,b){switch(b.type){case "file":case "input":case "select":case "textarea":var c= +a.getSymbolRecord(b.value);var d=c.element[c.index];return{type:"constant",numeric:!1,content:d.value};case "exists":return c=a.getSymbolRecord(b.value),{domain:"browser",type:"boolean",content:"undefined"!==typeof c.element[c.index]};case "mobile":return{domain:"browser",type:"boolean",content:"undefined"!==typeof window.orientation||-1!==navigator.userAgent.indexOf("IEMobile")};case "portrait":return{domain:"browser",type:"boolean",content:document.documentElement.clientWidth=document.documentElement.clientHeight};case "br":return{type:"constant",numeric:!1,content:decodeURIComponent("%3Cbr%20%2F%3E")};case "attributeOf":return c=a.getSymbolRecord(b.symbol),b=a.getValue(b.attribute),d=c.element[c.index],0===b.indexOf("data-")?a.getSimpleValue(d.dataset[b.substr(5)]):a.getSimpleValue(d[b]);case "style":return c=a.getSymbolRecord(b.target),b=a.getValue(b.style),d=c.element[c.index], +a.getSimpleValue(d.style[b]);case "confirm":return{type:"boolean",content:window.confirm(a.getValue(b.text))};case "prompt":return d=a.getValue(b.text),b=a.getValue(b.pre),{type:"constant",numeric:!1,content:b?window.prompt(d,b):window.prompt(d)};case "contentOf":c=a.getSymbolRecord(b.symbol);d=c.element[c.index];switch(c.keyword){case "input":case "textarea":b=d.value;break;case "pre":b=d.innerHTML;break;default:b=d.innerHTML.split("\n").join("")}return{type:"constant",numeric:!1,content:b};case "selected":return c= +a.getSymbolRecord(b.symbol),d=c.element[c.index],a=d.selectedIndex,d=0<=a?d.options[a].text:"",b="index"===b.arg?a:d,{type:"constant",numeric:!1,content:b};case "top":if("window"==b.symbol)return{type:"constant",numeric:!0,content:window.screenY};c=a.getSymbolRecord(b.symbol);a=c.element[c.index];b=Math.round(b.offset?a.offsetTop:a.getBoundingClientRect().top);return{type:"constant",numeric:!0,content:b};case "bottom":if("window"==b.symbol)return{type:"constant",numeric:!0,content:window.screenY+ +window.innerHeight};c=a.getSymbolRecord(b.symbol);b=Math.round(c.element[c.index].getBoundingClientRect().bottom);return{type:"constant",numeric:!0,content:b};case "left":if("window"==b.symbol)return{type:"constant",numeric:!0,content:window.screenLeft};c=a.getSymbolRecord(b.symbol);a=c.element[c.index];b=Math.round(b.offset?a.offsetLeft:a.getBoundingClientRect().left);return{type:"constant",numeric:!0,content:b};case "right":if("window"==b.symbol)return{type:"constant",numeric:!0,content:window.screenX+ +window.innerWidth};c=a.getSymbolRecord(b.symbol);b=Math.round(c.element[c.index].getBoundingClientRect().right);return{type:"constant",numeric:!0,content:b};case "width":if("window"==b.symbol)return{type:"constant",numeric:!0,content:window.innerWidth};c=a.getSymbolRecord(b.symbol);b=Math.round(c.element[c.index].getBoundingClientRect().width);return{type:"constant",numeric:!0,content:b};case "height":if("window"==b.symbol)return{type:"constant",numeric:!0,content:window.innerHeight};c=a.getSymbolRecord(b.symbol); +b=Math.round(c.element[c.index].getBoundingClientRect().height);return{type:"constant",numeric:!0,content:b};case "color":return{type:"constant",numeric:!1,content:"#"+a.value.evaluate(a,b.value).content.toString(16).padStart(6,"0")};case "docPath":return{type:"constant",numeric:!1,content:a.docPath};case "storageKeys":return{type:"constant",numeric:!1,content:JSON.stringify(Object.keys(localStorage))};case "location":return{type:"constant",numeric:!1,content:window.location.href};case "historyState":return{type:"constant", +numeric:!1,content:window.history.state};case "scrollPosition":return{type:"constant",numeric:!0,content:scrollPosition};case "varName":return{type:"constant",numeric:!1,content:a.varName};case "varIndex":return{type:"constant",numeric:!0,content:a.varIndex};case "key":return{type:"constant",numeric:!1,content:a.key};case "hostname":return{type:"constant",numeric:!1,content:location.hostname};case "screen":return{type:"constant",numeric:!0,content:screen[b.attribute]};case "pickPosition":return{type:"constant", +numeric:!1,content:JSON.stringify({x:document.pickX,y:document.pickY})};case "dragPosition":return{type:"constant",numeric:!1,content:JSON.stringify({x:document.dragX,y:document.dragY})}}}},condition:{compile:function(a){if(a.tokenIs("confirm"))return{domain:"browser",type:"confirm",value:a.getNextValue()};if(a.tokenIs("element")&&a.nextIsSymbol()){var b=a.getSymbolRecord();if("dom"===b.extra){var c=a.nextToken();if("has"===c){if(a.nextTokenIs("the")&&a.next(),a.tokenIs("focus"))return a.next(),{domain:"browser", +type:"focus",element:b.name}}else if("contains"===c)return a=a.getNextValue(),{domain:"browser",type:"contains",element:b.name,position:a}}}return null},test:function(a,b){switch(b.type){case "confirm":return confirm(a.getValue(b.value));case "focus":var c=a.getSymbolRecord(b.element);return c.element[c.index]===document.activeElement;case "contains":c=a.getSymbolRecord(b.element);var d=c.element[c.index].getBoundingClientRect();c=Math.round(d.left);var e=Math.round(d.right),f=Math.round(d.top);d= +Math.round(d.bottom);b=JSON.parse(a.getValue(b.position));a=b.x;b=b.y;return a>=c&&a<=e&&b>=f&&b<=d?!0:!1}}},setStyles:function(a,b){a=document.getElementById(a);b=b.split(";");b=$jscomp.makeIterator(b);for(var c=b.next();!c.done;c=b.next())c=c.value.split(":"),a.setAttribute(c[0],c[1])}},scrollPosition=0;window.addEventListener("scroll",function(){scrollPosition=this.scrollY}); +window.onpopstate=function(a){window.EasyCoder.timestamp=Date.now();(a=JSON.parse(a.state))&&a.script&&((a=window.EasyCoder.scripts[a.script])?a.onBrowserBack&&a.run(a.onBrowserBack):console.log("No script property in window state object"))}; var EasyCoder_Json={name:"EasyCoder_JSON",Json:{compile:function(a){var b=a.getLino(),c=a.nextToken();switch(c){case "set":a.next();if(a.isSymbol())if(c=a.getSymbolRecord(),"variable"===c.keyword){if(a.nextTokenIs("to")){var d=a.nextToken();if('["array","object"]'.includes(d))return a.next(),a.addCommand({domain:"json",keyword:"json",lino:b,request:"setVariable",target:c.name,type:d}),!0}}else if("select"===c.keyword&&a.nextTokenIs("from")&&(a.next(),a.isSymbol()&&(d=a.getSymbolRecord(),"variable"=== d.keyword))){var e=null;a.nextTokenIs("as")&&(e=a.getNextValue());a.addCommand({domain:"json",keyword:"json",lino:b,request:"setList",target:c.name,source:d.name,display:e});return!0}break;case "sort":case "shuffle":case "format":if(a.nextIsSymbol()&&(d=a.getSymbolRecord(),"variable"===d.keyword))return a.next(),a.addCommand({domain:"json",keyword:"json",lino:b,request:c,target:d.name}),!0;break;case "parse":if(a.nextTokenIs("url")&&(d=a.getNextValue(),a.tokenIs("as")&&a.nextIsSymbol()&&(e=a.getSymbolRecord(), "variable"===e.keyword)))return a.next(),a.addCommand({domain:"json",keyword:"json",lino:b,request:c,source:d,target:e.name}),!0;break;case "delete":d=a.nextToken();if(["property","element"].includes(d)&&(e=a.getNextValue(),["from","of"].includes(a.getToken())&&a.nextIsSymbol())){var f=a.getSymbolRecord();if("variable"===f.keyword)return a.next(),a.addCommand({domain:"json",keyword:"json",lino:b,request:c,what:d,value:e,target:f.name}),!0}break;case "rename":d=a.getNextValue();if(a.tokenIs("to")&& @@ -188,39 +188,38 @@ c.value[c.index].content=JSON.stringify(e)}return b.pc+1}},getHandler:function(a a.next();if(c.isVHolder)return{domain:"json",type:b,name:c.name}}}else if("index"===b&&a.nextTokenIs("of")&&(c=a.getNextValue(),a.tokenIs("in")))return a=a.getNextValue(),{domain:"json",type:b,item:c,list:a}}return null},get:function(a,b){switch(b.type){case "size":case "count":b=a.getSymbolRecord(b.name);a=a.getValue(b.value[b.index]);try{var c=JSON.parse(a)}catch(e){c=[]}return{type:"constant",numeric:!0,content:c?c.length:0};case "keys":return b=a.getSymbolRecord(b.name),c=(a=a.getValue(b.value[b.index]))? JSON.stringify(Object.keys(JSON.parse(a)).sort()):"[]",{type:"constant",numeric:!1,content:c};case "index":var d=a.getValue(b.item);c=JSON.parse(a.getValue(b.list)).findIndex(function(a){return a===d});return{type:"constant",numeric:!0,content:c}}}},condition:{compile:function(){},test:function(){}}},EasyCoder_Rest={name:"EasyCoder_Rest",Rest:{compile:function(a){var b=a.getLino();switch(a.nextToken()){case "get":if(a.nextIsSymbol(!0)){var c=a.getSymbolRecord();if("variable"===c.keyword&&a.nextTokenIs("from")){var d= a.getNextValue(),e=a.getPc();a.addCommand({domain:"rest",keyword:"rest",lino:b,request:"get",target:c.name,url:d,onError:null});a.tokenIs("or")&&(a.next(),a.getCommandAt(e).onError=a.getPc()+1,a.completeHandler());return!0}}break;case "post":c=null;if(a.nextTokenIs("to"))a.next();else if(c=a.getValue(),a.tokenIs("to"))a.next();else break;d=a.getValue();if(!d)throw Error(command.lino,"No URL present");e=null;if(a.tokenIs("giving")&&a.nextIsSymbol())if(e=a.getSymbolRecord(),e.isVHolder)e=e.name,a.next(); -else throw Error("'"+e.name+"' cannot hold a value");a.addCommand({domain:"rest",keyword:"rest",lino:b,request:"post",value:c,url:d,target:e,onError:a.getPc()+2});onError=null;a.tokenIs("or")&&(a.next(),a.completeHandler());return!0}return!1},createCORSRequest:function(a,b){var c=new XMLHttpRequest;"withCredentials"in c?c.open(a,b,!0):"undefined"!=typeof XDomainRequest?(c=new XDomainRequest,c.open(a,b)):c=null;return c},run:function(a){var b=a[a.pc],c=a.getValue(b.url),d=EasyCoder_Plugins.rest(); -c=c.startsWith("http")?c:"/"===c[0]?c.substr(1):""+window.location.origin+(d?"/"+d:"")+"/"+c;var e=EasyCoder_Rest.Rest.createCORSRequest(b.request,c);if(e){e.script=a.script;e.pc=a.pc;e.onload=function(){var c=EasyCoder.scripts[e.script],d=c[e.pc];if(200<=e.status&&400>e.status){var g=e.responseText.trim();if(d.target){var h=a.getSymbolRecord(b.target);h.value[h.index]={type:"constant",numeric:!1,content:g};h.used=!0}c.run(d.pc+1)}else g=e.status+" "+e.statusText,d.onError?(c.errorMessage="Exception trapped: "+ -g,c.run(d.onError)):c.runtimeError(d.lino,"Error: "+g)};e.onerror=function(){b.onError?(a.errorMessage=this.responseText,a.run(b.onError)):a.runtimeError(b.lino,this.responseText)};switch(b.request){case "get":e.send();break;case "post":d=a.getValue(b.value),console.log("POST to "+c),e.setRequestHeader("Content-type","application/json; charset=UTF-8"),e.send(d)}return 0}a.runtimeError(b.lino,"CORS not supported")}},getHandler:function(a){switch(a){case "rest":return EasyCoder_Rest.Rest;default:return null}}, -run:function(a){var b=a[a.pc],c=EasyCoder_Rest.getHandler(b.keyword);c||a.runtimeError(b.lino,"Unknown keyword '"+b.keyword+"' in 'rest' package");return c.run(a)},value:{compile:function(){return null},get:function(){return null}},condition:{compile:function(){},test:function(){}}},EasyCoder_Compare=function(a,b,c){b=a.value.evaluate(a,b);a=a.value.evaluate(a,c);c=b.content;var d=a.content;c&&b.numeric?a.numeric||(d=""===d||"-"===d||"undefined"===typeof d?0:parseInt(d)):(d&&a.numeric&&(d=d.toString()), -"undefined"===typeof c&&(c=""),"undefined"===typeof d&&(d=""));return c>d?1:c')}l+="
    "}g.innerHTML=h+" "+l;g.style.display="block";b.$jscomp$loop$prop$run$143=document.getElementById("easycoder-run-button");b.$jscomp$loop$prop$step$144=document.getElementById("easycoder-step-button"); -b.$jscomp$loop$prop$run$143.onclick=function(b){return function(){b.$jscomp$loop$prop$run$143.blur();a.tracing=!1;document.getElementById("easycoder-tracer-content").style.display="none";try{EasyCoder_Run.run(a,a.resume)}catch(q){var c="Error in run handler: "+q.message;console.log(c);alert(c)}}}(b);b.$jscomp$loop$prop$step$144.onclick=function(b){return function(){console.log("step");b.$jscomp$loop$prop$step$144.blur();a.tracing=!0;document.getElementById("easycoder-tracer-content").style.display= -"block";try{a.run(a.resume)}catch(q){var c="Error in step handler: "+q.message;console.log(c);alert(c)}}}(b)}a.resume=a.pc;a.pc=0}break}b={$jscomp$loop$prop$run$143:b.$jscomp$loop$prop$run$143,$jscomp$loop$prop$step$144:b.$jscomp$loop$prop$step$144}}},exit:function(a){a.onExit&&a.run(a.onExit);var b=a.parent,c=a.afterExit;delete EasyCoder.scripts[a.script];a.module&&delete a.module.program;Object.keys(a).forEach(function(b){delete a[b]});b&&c&&EasyCoder.scripts[b].run(c)}},EasyCoder_Compiler={name:"EasyCoder_Compiler", -getTokens:function(){return this.tokens},addWarning:function(a){this.warnings.push(a)},warning:function(a){this.addWarning(a)},unrecognisedSymbol:function(a){this.addWarning("Unrecognised symbol '"+a+"'")},getWarnings:function(){return this.warnings},getIndex:function(){return this.index},next:function(a){this.index+=void 0===a?1:a},peek:function(){return this.tokens[this.index+1].token},more:function(){return this.index=this.tokens.length? -null:this.tokens[this.index]?this.tokens[this.index].token:null},nextToken:function(){this.next();return this.getToken()},tokenIs:function(a){return this.index>=this.tokens.length?!1:a===this.tokens[this.index].token},nextTokenIs:function(a){this.next();return this.tokenIs(a)},skip:function(a){if(this.index>=this.tokens.length)return null;this.next();this.tokenIs(a)&&this.next()},prev:function(){this.index--},getLino:function(){return this.index>=this.tokens.length?0:this.tokens[this.index].lino}, -getTarget:function(a){a=void 0===a?this.index:a;return this.tokens[a].token},getTargetPc:function(a){a=void 0===a?this.index:a;return this.symbols[this.getTarget(a)].pc},getCommandAt:function(a){return this.program[a]},isSymbol:function(a){a=void 0===a?!1:a;if(this.getTarget()in this.symbols)return!0;if(a)throw Error("Unknown symbol: '"+this.getTarget()+"'");return!1},nextIsSymbol:function(a){a=void 0===a?!1:a;this.next();return this.isSymbol(a)},getSymbol:function(a){if(this.isSymbol(void 0===a? -!1:a))return this.symbols[this.getToken()]},getSymbolPc:function(a){return this.getSymbol(void 0===a?!1:a).pc},getSymbolRecord:function(){var a=this.program[this.getSymbolPc(!0)];a.used=!0;return a},getSymbols:function(){return this.symbols},getProgram:function(){return this.program},getPc:function(){return this.program.length},getValue:function(){return this.value.compile(this)},getNextValue:function(){this.next();return this.getValue()},getCondition:function(){return this.condition.compile(this)}, -constant:function(a,b){return this.value.constant(a,void 0===b?!1:b)},addCommand:function(a){this.program.push(Object.assign({},{pc:this.program.length},a))},addSymbol:function(a,b){this.symbols[a]={pc:b}},mark:function(){this.savedMark=this.index},rewind:function(){this.index=this.savedMark},rewindTo:function(a){this.index=a},completeHandler:function(){var a=this.getLino(),b=this.getPc();this.addCommand({domain:"core",keyword:"goto",lino:a,goto:0});this.compileOne();this.continue?(this.addCommand({domain:"core", -keyword:"goto",lino:a,goto:this.getPc()+1}),this.continue=!1):this.addCommand({domain:"core",keyword:"stop",lino:a,next:0});this.getCommandAt(b).goto=this.getPc();return!0},compileVariable:function(a,b,c,d){c=void 0===c?!1:c;d=void 0===d?null:d;this.next();var e=this.getLino(),f=this.getTokens()[this.getIndex()];if(this.symbols[f.token])throw Error("Duplicate variable name '"+f.token+"'");var k=this.getPc();this.next();this.addSymbol(f.token,k);a={domain:a,keyword:b,lino:e,isSymbol:!0,used:!1,isVHolder:c, -name:f.token,elements:1,index:0,value:[{}],element:[],extra:d};"dom"===d&&(a.element=[]);this.addCommand(a);return a},compileToken:function(){var a=this.getToken();if(a){this.mark();for(var b=$jscomp.makeIterator(Object.keys(this.domain)),c=b.next();!c.done;c=b.next()){if((c=this.domain[c.value])&&(c=c.getHandler(a))&&c.compile(this))return;this.rewind()}console.log("No handler found");throw Error("I don't understand '"+a+"...'");}},compileOne:function(){var a=this.getToken();if(a){this.warnings= -[];var b=this.program.length;if(a.endsWith(":")){a=a.substring(0,a.length-1);if(this.symbols[a])throw Error("Duplicate symbol: '"+a+"'");this.symbols[a]={pc:b};this.index++}else this.compileToken()}},compileFromHere:function(a){for(;this.indexe?0:e;ed.status){var g=d.responseText.trim();if(e.target){var h=a.getSymbolRecord(b.target);h.value[h.index]={type:"constant",numeric:!1,content:g};h.used=!0}c.run(e.pc+1)}else g=d.status+" "+d.statusText,e.onError?(c.errorMessage="Exception trapped: "+g,c.run(e.onError)):c.runtimeError(e.lino, +"Error: "+g)};d.onerror=function(){b.onError?(a.errorMessage=this.responseText,a.run(b.onError)):a.runtimeError(b.lino,this.responseText)};switch(b.request){case "get":d.send();break;case "post":var e=a.getValue(b.value);console.log("POST to "+c);d.setRequestHeader("Content-type","application/json; charset=UTF-8");d.send(e)}return 0}a.runtimeError(b.lino,"CORS not supported")}},getHandler:function(a){switch(a){case "rest":return EasyCoder_Rest.Rest;default:return null}},run:function(a){var b=a[a.pc], +c=EasyCoder_Rest.getHandler(b.keyword);c||a.runtimeError(b.lino,"Unknown keyword '"+b.keyword+"' in 'rest' package");return c.run(a)},value:{compile:function(){return null},get:function(){return null}},condition:{compile:function(){},test:function(){}}},EasyCoder_Compare=function(a,b,c){b=a.value.evaluate(a,b);a=a.value.evaluate(a,c);c=b.content;var d=a.content;c&&b.numeric?a.numeric||(d=""===d||"-"===d||"undefined"===typeof d?0:parseInt(d)):(d&&a.numeric&&(d=d.toString()),"undefined"===typeof c&& +(c=""),"undefined"===typeof d&&(d=""));return c>d?1:c')}l+="
    "}g.innerHTML=h+" "+l;g.style.display="block";b.$jscomp$loop$prop$run$143=document.getElementById("easycoder-run-button");b.$jscomp$loop$prop$step$144=document.getElementById("easycoder-step-button");b.$jscomp$loop$prop$run$143.onclick= +function(b){return function(){b.$jscomp$loop$prop$run$143.blur();a.tracing=!1;document.getElementById("easycoder-tracer-content").style.display="none";try{EasyCoder_Run.run(a,a.resume)}catch(q){var c="Error in run handler: "+q.message;console.log(c);alert(c)}}}(b);b.$jscomp$loop$prop$step$144.onclick=function(b){return function(){console.log("step");b.$jscomp$loop$prop$step$144.blur();a.tracing=!0;document.getElementById("easycoder-tracer-content").style.display="block";try{a.run(a.resume)}catch(q){var c= +"Error in step handler: "+q.message;console.log(c);alert(c)}}}(b)}a.resume=a.pc;a.pc=0}break}b={$jscomp$loop$prop$run$143:b.$jscomp$loop$prop$run$143,$jscomp$loop$prop$step$144:b.$jscomp$loop$prop$step$144}}},exit:function(a){a.onExit&&a.run(a.onExit);var b=a.parent,c=a.afterExit;delete EasyCoder.scripts[a.script];a.module&&delete a.module.program;Object.keys(a).forEach(function(b){delete a[b]});b&&c&&EasyCoder.scripts[b].run(c)}},EasyCoder_Compiler={name:"EasyCoder_Compiler",getTokens:function(){return this.tokens}, +addWarning:function(a){this.warnings.push(a)},warning:function(a){this.addWarning(a)},unrecognisedSymbol:function(a){this.addWarning("Unrecognised symbol '"+a+"'")},getWarnings:function(){return this.warnings},getIndex:function(){return this.index},next:function(a){this.index+=void 0===a?1:a},peek:function(){return this.tokens[this.index+1].token},more:function(){return this.index=this.tokens.length?null:this.tokens[this.index]?this.tokens[this.index].token: +null},nextToken:function(){this.next();return this.getToken()},tokenIs:function(a){return this.index>=this.tokens.length?!1:a===this.tokens[this.index].token},nextTokenIs:function(a){this.next();return this.tokenIs(a)},skip:function(a){if(this.index>=this.tokens.length)return null;this.next();this.tokenIs(a)&&this.next()},prev:function(){this.index--},getLino:function(){return this.index>=this.tokens.length?0:this.tokens[this.index].lino},getTarget:function(a){a=void 0===a?this.index:a;return this.tokens[a].token}, +getTargetPc:function(a){a=void 0===a?this.index:a;return this.symbols[this.getTarget(a)].pc},getCommandAt:function(a){return this.program[a]},isSymbol:function(a){a=void 0===a?!1:a;if(this.getTarget()in this.symbols)return!0;if(a)throw Error("Unknown symbol: '"+this.getTarget()+"'");return!1},nextIsSymbol:function(a){a=void 0===a?!1:a;this.next();return this.isSymbol(a)},getSymbol:function(a){if(this.isSymbol(void 0===a?!1:a))return this.symbols[this.getToken()]},getSymbolPc:function(a){return this.getSymbol(void 0=== +a?!1:a).pc},getSymbolRecord:function(){var a=this.program[this.getSymbolPc(!0)];a.used=!0;return a},getSymbols:function(){return this.symbols},getProgram:function(){return this.program},getPc:function(){return this.program.length},getValue:function(){return this.value.compile(this)},getNextValue:function(){this.next();return this.getValue()},getCondition:function(){return this.condition.compile(this)},constant:function(a,b){return this.value.constant(a,void 0===b?!1:b)},addCommand:function(a){this.program.push(Object.assign({}, +{pc:this.program.length},a))},addSymbol:function(a,b){this.symbols[a]={pc:b}},mark:function(){this.savedMark=this.index},rewind:function(){this.index=this.savedMark},rewindTo:function(a){this.index=a},completeHandler:function(){var a=this.getLino(),b=this.getPc();this.addCommand({domain:"core",keyword:"goto",lino:a,goto:0});this.compileOne();this.continue?(this.addCommand({domain:"core",keyword:"goto",lino:a,goto:this.getPc()+1}),this.continue=!1):this.addCommand({domain:"core",keyword:"stop",lino:a, +next:0});this.getCommandAt(b).goto=this.getPc();return!0},compileVariable:function(a,b,c,d){c=void 0===c?!1:c;d=void 0===d?null:d;this.next();var e=this.getLino(),f=this.getTokens()[this.getIndex()];if(this.symbols[f.token])throw Error("Duplicate variable name '"+f.token+"'");var k=this.getPc();this.next();this.addSymbol(f.token,k);a={domain:a,keyword:b,lino:e,isSymbol:!0,used:!1,isVHolder:c,name:f.token,elements:1,index:0,value:[{}],element:[],extra:d};"dom"===d&&(a.element=[]);this.addCommand(a); +return a},compileToken:function(){var a=this.getToken();if(a){this.mark();for(var b=$jscomp.makeIterator(Object.keys(this.domain)),c=b.next();!c.done;c=b.next()){if((c=this.domain[c.value])&&(c=c.getHandler(a))&&c.compile(this))return;this.rewind()}console.log("No handler found");throw Error("I don't understand '"+a+"...'");}},compileOne:function(){var a=this.getToken();if(a){this.warnings=[];var b=this.program.length;if(a.endsWith(":")){a=a.substring(0,a.length-1);if(this.symbols[a])throw Error("Duplicate symbol: '"+ +a+"'");this.symbols[a]={pc:b};this.index++}else this.compileToken()}},compileFromHere:function(a){for(;this.indexe?0:e;e { const command = program[program.pc]; const url = program.getValue(command.url); - const rest = EasyCoder_Plugins.rest(); const path = url.startsWith(`http`) ? url - : url[0] === `/` ? url.substr(1) - : `${window.location.origin}${rest ? `/${rest}` : ``}/${url}`; + : url[0] === `/` ? url.substr(1) : `${window.location.origin}/${url}`; const request = EasyCoder_Rest.Rest.createCORSRequest(command.request, path); if (!request) { diff --git a/js/easycoder/Browser.js b/js/easycoder/Browser.js index 30e281f..474d9a8 100644 --- a/js/easycoder/Browser.js +++ b/js/easycoder/Browser.js @@ -2558,7 +2558,7 @@ const EasyCoder_Browser = { } }; program.ajaxCommand = command; - const postpath = path.startsWith(`http`) ? path : `${window.location.origin}/${EasyCoder_Plugins.rest()}/${path}`; + const postpath = path.startsWith(`http`) ? path : `${window.location.origin}//${path}`; ajax.open(`POST`, postpath); ajax.send(formData); } diff --git a/js/easycoder/Rest.js b/js/easycoder/Rest.js index 3974890..581f3bf 100644 --- a/js/easycoder/Rest.js +++ b/js/easycoder/Rest.js @@ -110,10 +110,8 @@ const EasyCoder_Rest = { run: (program) => { const command = program[program.pc]; const url = program.getValue(command.url); - const rest = EasyCoder_Plugins.rest(); const path = url.startsWith(`http`) ? url - : url[0] === `/` ? url.substr(1) - : `${window.location.origin}${rest ? `/${rest}` : ``}/${url}`; + : url[0] === `/` ? url.substr(1) : `${window.location.origin}/${url}`; const request = EasyCoder_Rest.Rest.createCORSRequest(command.request, path); if (!request) { diff --git a/js/plugins-all.js b/js/plugins-all.js deleted file mode 100644 index 378b8e0..0000000 --- a/js/plugins-all.js +++ /dev/null @@ -1,25 +0,0 @@ -// eslint-disable-next-line no-unused-vars -const EasyCoder_Plugins = { - - // eslint-disable-next-line no-unused-vars - getGlobalPlugins: (timestamp, path, setPluginCount, getPlugin, addPlugin) => { - setPluginCount(11); // *** IMPORTANT *** the number of plugins you will be adding - - addPlugin(`browser`, EasyCoder_Browser); - addPlugin(`json`, EasyCoder_Json); - addPlugin(`rest`, EasyCoder_Rest); - addPlugin(`ckeditor`, EasyCoder_CKEditor); - addPlugin(`codemirror`, EasyCoder_CodeMirror); - addPlugin(`gmap`, EasyCoder_GMap); - addPlugin(`showdown`, EasyCoder_Showdown); - addPlugin(`svg`, EasyCoder_SVG); - addPlugin(`ui`, EasyCoder_UI); - addPlugin(`vfx`, EasyCoder_WOF); - addPlugin(`wof`, EasyCoder_WOF); - addPlugin(`anagrams`, EasyCoder_Anagrams); - }, - - rest: () => { - return ``; - } -}; diff --git a/js/plugins-st.js b/js/plugins-st.js deleted file mode 100644 index 7d10406..0000000 --- a/js/plugins-st.js +++ /dev/null @@ -1,24 +0,0 @@ -// Plugins for StoryTeller - -// eslint-disable-next-line no-unused-vars -const EasyCoder_Plugins = { - - // eslint-disable-next-line no-unused-vars - getGlobalPlugins: (timestamp, path, setPluginCount, getPlugin, addPlugin) => { - setPluginCount(9); // *** IMPORTANT *** the number of plugins you will be adding - - addPlugin(`browser`, EasyCoder_Browser); - addPlugin(`json`, EasyCoder_Json); - addPlugin(`rest`, EasyCoder_Rest); - addPlugin(`gmap`, EasyCoder_GMap); - addPlugin(`showdown`, EasyCoder_Showdown); - addPlugin(`codemirror`, EasyCoder_CodeMirror); - addPlugin(`svg`, EasyCoder_SVG); - addPlugin(`ui`, EasyCoder_UI); - addPlugin(`vfx`, EasyCoder_VFX); - }, - - rest: () => { - return ``; - } -};