local p = {} table.insert(package.searchers, 1, function (mod) print('?',mod, not not p[mod]) local mod = p[mod] return mod and function () return load(table.unpack(mod))() end end) p["mmm.component"] = {"local tohtml\ tohtml = function(val)\ if 'string' == type(val) then\ return document:createTextNode(val)\ end\ if 'table' == type(val) then\ assert(val.node, \"Table doesn't have .node\")\ val = val.node\ end\ if 'userdata' == type(val) then\ assert((js.instanceof(val, js.global.Node)), \"userdata is not a Node\")\ return val\ else\ return error(\"not a Node: \" .. tostring(val) .. \", \" .. tostring(type(val)))\ end\ end\ local fromhtml\ fromhtml = function(node)\ return {\ node = node\ }\ end\ local text\ text = function(str)\ return document:createTextNode(tostring(str))\ end\ local ReactiveVar\ do\ local _class_0\ local _base_0 = {\ set = function(self, value)\ local old = self.value\ self.value = value\ for k, callback in pairs(self.listeners) do\ callback(self.value, old)\ end\ end,\ get = function(self)\ return self.value\ end,\ transform = function(self, transform)\ return self:set(transform(self:get()))\ end,\ subscribe = function(self, callback)\ do\ local _with_0\ _with_0 = function()\ self.listeners[callback] = nil\ end\ self.listeners[callback] = callback\ return _with_0\ end\ end,\ map = function(self, transform)\ do\ local _with_0 = ReactiveVar(transform(self.value))\ _with_0.upstream = self:subscribe(function(...)\ return _with_0:set(transform(...))\ end)\ return _with_0\ end\ end\ }\ _base_0.__index = _base_0\ _class_0 = setmetatable({\ __init = function(self, value)\ self.value = value\ self.listeners = setmetatable({ }, {\ __mode = 'kv'\ })\ end,\ __base = _base_0,\ __name = \"ReactiveVar\"\ }, {\ __index = _base_0,\ __call = function(cls, ...)\ local _self_0 = setmetatable({}, _base_0)\ cls.__init(_self_0, ...)\ return _self_0\ end\ })\ _base_0.__class = _class_0\ local self = _class_0\ self.isinstance = function(val)\ return 'table' == (type(val)) and val.subscribe\ end\ ReactiveVar = _class_0\ end\ local ReactiveElement\ do\ local _class_0\ local _base_0 = {\ destroy = function(self)\ local _list_0 = self._subscriptions\ for _index_0 = 1, #_list_0 do\ local unsub = _list_0[_index_0]\ unsub()\ end\ end,\ set = function(self, attr, value)\ if attr == 'class' then\ attr = 'className'\ end\ if 'table' == (type(value)) and ReactiveVar.isinstance(value) then\ table.insert(self._subscriptions, value:subscribe(function(...)\ return self:set(attr, ...)\ end))\ value = value:get()\ end\ if attr == 'style' and 'table' == type(value) then\ for k, v in pairs(value) do\ self.node.style[k] = v\ end\ return \ end\ self.node[attr] = value\ end,\ prepend = function(self, child, last)\ return self:append(child, last, 'prepend')\ end,\ append = function(self, child, last, mode)\ if mode == nil then\ mode = 'append'\ end\ if ReactiveVar.isinstance(child) then\ table.insert(self._subscriptions, child:subscribe(function(...)\ return self:append(...)\ end))\ child = child:get()\ end\ if 'string' == type(last) then\ error('cannot replace string node')\ end\ if child == nil then\ if last then\ self:remove(last)\ end\ return \ end\ child = tohtml(child)\ if last then\ return self.node:replaceChild(child, tohtml(last))\ else\ local _exp_0 = mode\ if 'append' == _exp_0 then\ return self.node:appendChild(child)\ elseif 'prepend' == _exp_0 then\ return self.node:insertBefore(child, self.node.firstChild)\ end\ end\ end,\ remove = function(self, child)\ self.node:removeChild(tohtml(child))\ if 'table' == (type(child)) and child.destroy then\ return child:destroy()\ end\ end\ }\ _base_0.__index = _base_0\ _class_0 = setmetatable({\ __init = function(self, element, ...)\ if 'userdata' == type(element) then\ self.node = element\ else\ self.node = document:createElement(element)\ end\ self._subscriptions = { }\ local children = {\ ...\ }\ local attributes = children[#children]\ if 'table' == (type(attributes)) and (not ReactiveElement.isinstance(attributes)) and (not ReactiveVar.isinstance(attributes)) then\ table.remove(children)\ else\ attributes = { }\ end\ for k, v in pairs(attributes) do\ if 'string' == type(k) then\ self:set(k, v)\ end\ end\ if #children == 0 then\ children = attributes\ end\ for _index_0 = 1, #children do\ local child = children[_index_0]\ self:append(child)\ end\ end,\ __base = _base_0,\ __name = \"ReactiveElement\"\ }, {\ __index = _base_0,\ __call = function(cls, ...)\ local _self_0 = setmetatable({}, _base_0)\ cls.__init(_self_0, ...)\ return _self_0\ end\ })\ _base_0.__class = _class_0\ local self = _class_0\ self.isinstance = function(val)\ return 'table' == (type(val)) and val.node\ end\ ReactiveElement = _class_0\ end\ local get_or_create\ get_or_create = function(elem, id, ...)\ elem = (document:getElementById(id)) or elem\ do\ local _with_0 = ReactiveElement(elem, ...)\ _with_0:set('id', id)\ return _with_0\ end\ end\ local elements = setmetatable({ }, {\ __index = function(self, name)\ do\ local val\ val = function(...)\ return ReactiveElement(name, ...)\ end\ self[name] = val\ return val\ end\ end\ })\ return {\ ReactiveVar = ReactiveVar,\ ReactiveElement = ReactiveElement,\ get_or_create = get_or_create,\ tohtml = tohtml,\ fromhtml = fromhtml,\ text = text,\ elements = elements\ }", "mmm/component/init.client.moon"} p["mmm.refs"] = {"return {\ depth = 0,\ count = 0,\ push = function(self)\ self.depth = self.depth + 1\ end,\ pop = function(self)\ self.depth = self.depth - 1\ if self.depth == 0 then\ self.count = 0\ end\ end,\ get = function(self)\ self.count = self.count + 1\ return self.count\ end\ }", "mmm/refs.moon"} p["mmm.color"] = {"local rgb\ rgb = function(r, g, b)\ if 'table' == type(r) then\ r, g, b = table.unpack(r)\ end\ return \"rgb(\" .. tostring(r * 255) .. \", \" .. tostring(g * 255) .. \", \" .. tostring(b * 255) .. \")\"\ end\ local rgba\ rgba = function(r, g, b, a)\ if 'table' == type(r) then\ r, g, b, a = table.unpack(r)\ end\ return \"rgba(\" .. tostring(r * 255) .. \", \" .. tostring(g * 255) .. \", \" .. tostring(b * 255) .. \", \" .. tostring(a or 1) .. \")\"\ end\ local hsl\ hsl = function(h, s, l)\ if 'table' == type(h) then\ h, s, l = table.unpack(h)\ end\ return \"hsl(\" .. tostring(h * 360) .. \", \" .. tostring(s * 100) .. \"%, \" .. tostring(l * 100) .. \"%)\"\ end\ local hsla\ hsla = function(h, s, l, a)\ if 'table' == type(h) then\ h, s, l, a = table.unpack(h)\ end\ return \"hsla(\" .. tostring(h * 360) .. \", \" .. tostring(s * 100) .. \"%, \" .. tostring(l * 100) .. \"%, \" .. tostring(a or 1) .. \")\"\ end\ return {\ rgb = rgb,\ rgba = rgba,\ hsl = hsl,\ hsla = hsla\ }", "mmm/color.moon"} p["mmm.highlighting"] = {"local code\ code = require('mmm.dom').code\ local trim\ trim = function(str)\ return str:match('^ *(..-) *$')\ end\ local highlight\ if MODE == 'SERVER' then\ highlight = function(lang, str)\ assert(str, 'no string to highlight')\ return code((trim(str)), {\ class = \"hljs lang-\" .. tostring(lang)\ })\ end\ else\ highlight = function(lang, str)\ assert(str, 'no string to highlight')\ if not window.hljs:getLanguage(lang) then\ lang = 'markdown'\ end\ local result = window.hljs:highlight(lang, (trim(str)), true)\ do\ local _with_0 = code({\ class = \"hljs lang-\" .. tostring(lang)\ })\ _with_0.innerHTML = result.value\ return _with_0\ end\ end\ end\ local languages = setmetatable({ }, {\ __index = function(self, name)\ do\ local val\ val = function(str)\ return highlight(name, str)\ end\ self[name] = val\ return val\ end\ end\ })\ return {\ highlight = highlight,\ languages = languages\ }", "mmm/highlighting.moon"} p["mmm.dom"] = {"local element\ element = function(element)\ return function(...)\ local children = {\ ...\ }\ local attributes = children[#children]\ if 'table' == (type(attributes)) and not attributes.node then\ table.remove(children)\ else\ attributes = { }\ end\ local e\ if element then\ e = document:createElement(element)\ else\ e = document:createDocumentFragment()\ end\ for k, v in pairs(attributes) do\ if k == 'class' then\ k = 'className'\ end\ if k == 'style' and 'table' == type(v) then\ for kk, vv in pairs(v) do\ e.style[kk] = vv\ end\ elseif 'string' == type(k) then\ e[k] = v\ end\ end\ if #children == 0 then\ children, attributes = attributes, { }\ end\ if not element then\ assert(not (next(attributes)), \"_frag cannot take attributes\")\ end\ for _index_0 = 1, #children do\ local child = children[_index_0]\ if 'string' == type(child) then\ child = document:createTextNode(child)\ end\ e:appendChild(child)\ end\ return e\ end\ end\ return setmetatable({\ _frag = element()\ }, {\ __index = function(self, name)\ do\ local val = element(name)\ self[name] = val\ return val\ end\ end\ })", "mmm/dom/init.client.moon"} p["mmm.canvasapp"] = {"local window = js.global\ local js = require('js')\ local a, canvas, div, button, script\ do\ local _obj_0 = require('mmm.dom')\ a, canvas, div, button, script = _obj_0.a, _obj_0.canvas, _obj_0.div, _obj_0.button, _obj_0.script\ end\ local CanvasApp\ do\ local _class_0\ local _base_0 = {\ width = 500,\ height = 400,\ update = function(self, dt)\ self.time = self.time + dt\ if self.length and self.time > self.length then\ self.time = self.time - self.length\ return true\ end\ end,\ render = function(self, fps)\ if fps == nil then\ fps = 60\ end\ assert(self.length, 'cannot render CanvasApp without length set')\ self.paused = true\ local actual_render\ actual_render = function()\ local writer = js.new(window.Whammy.Video, fps)\ local doFrame\ doFrame = function()\ local done = self:update(1 / fps)\ self.ctx:resetTransform()\ self:draw()\ writer:add(self.canvas)\ if done or self.time >= self.length then\ local blob = writer:compile()\ local name = tostring(self.__class.__name) .. \"_\" .. tostring(fps) .. \"fps.webm\"\ return self.node.lastChild:appendChild(a(name, {\ download = name,\ href = window.URL:createObjectURL(blob)\ }))\ else\ return window:setTimeout(doFrame)\ end\ end\ self.time = 0\ return doFrame()\ end\ if window.Whammy then\ return actual_render()\ else\ window.global = window.global or window\ return document.body:appendChild(script({\ onload = actual_render,\ src = 'https://cdn.jsdelivr.net/npm/whammy@0.0.1/whammy.min.js'\ }))\ end\ end\ }\ _base_0.__index = _base_0\ _class_0 = setmetatable({\ __init = function(self, show_menu, paused)\ if show_menu == nil then\ show_menu = false\ end\ self.paused = paused\ self.canvas = canvas({\ width = self.width,\ height = self.height\ })\ self.ctx = self.canvas:getContext('2d')\ self.time = 0\ self.canvas.tabIndex = 0\ self.canvas:addEventListener('click', function(_, e)\ return self.click and self:click(e.offsetX, e.offsetY, e.button)\ end)\ self.canvas:addEventListener('keydown', function(_, e)\ return self.keydown and self:keydown(e.key, e.code)\ end)\ local lastMillis = window.performance:now()\ local animationFrame\ animationFrame = function(_, millis)\ self:update((millis - lastMillis) / 1000)\ self.ctx:resetTransform()\ self:draw()\ lastMillis = millis\ if not self.paused then\ return window:setTimeout((function()\ return window:requestAnimationFrame(animationFrame)\ end), 0)\ end\ end\ window:requestAnimationFrame(animationFrame)\ if show_menu then\ self.node = div({\ className = 'canvas_app',\ self.canvas,\ div({\ className = 'overlay',\ button('render 30fps', {\ onclick = function()\ return self:render(30)\ end\ }),\ button('render 60fps', {\ onclick = function()\ return self:render(60)\ end\ })\ })\ })\ else\ self.node = self.canvas\ end\ end,\ __base = _base_0,\ __name = \"CanvasApp\"\ }, {\ __index = _base_0,\ __call = function(cls, ...)\ local _self_0 = setmetatable({}, _base_0)\ cls.__init(_self_0, ...)\ return _self_0\ end\ })\ _base_0.__class = _class_0\ CanvasApp = _class_0\ end\ return {\ CanvasApp = CanvasApp\ }", "mmm/canvasapp.client.moon"} p["mmm.ordered"] = {"local sort\ sort = function(t, order_fn, only_strings)\ do\ local index\ do\ local _accum_0 = { }\ local _len_0 = 1\ for k, v in pairs(t) do\ if (not only_strings) or 'string' == type(k) then\ _accum_0[_len_0] = k\ _len_0 = _len_0 + 1\ end\ end\ index = _accum_0\ end\ table.sort(index, order_fn)\ return index\ end\ end\ local onext\ onext = function(state, key)\ state.i = state.i + state.step\ local t, index, i\ t, index, i = state.t, state.index, state.i\ do\ key = index[i]\ if key then\ return key, t[key]\ end\ end\ end\ local opairs\ opairs = function(t, order_fn, only_strings)\ if only_strings == nil then\ only_strings = false\ end\ local state = {\ t = t,\ i = 0,\ step = 1,\ index = sort(t, order_fn, only_strings)\ }\ return onext, state, nil\ end\ local ropairs\ ropairs = function(t, order_fn, only_strings)\ if only_strings == nil then\ only_strings = false\ end\ local index = sort(t, order_fn, only_strings)\ local state = {\ t = t,\ index = index,\ i = #index + 1,\ step = -1\ }\ return onext, state, nil\ end\ return {\ onext = onext,\ opairs = opairs,\ ropairs = ropairs\ }", "mmm/ordered.moon"} p["mmm.mmmfs.fileder"] = {"local get_conversions, apply_conversions\ do\ local _obj_0 = require('mmm.mmmfs.conversion')\ get_conversions, apply_conversions = _obj_0.get_conversions, _obj_0.apply_conversions\ end\ local dir_base\ dir_base = function(path)\ local dir, base = path:match('(.-)([^/]-)$')\ if dir and #dir > 0 then\ dir = dir:sub(1, #dir - 1)\ end\ return dir, base\ end\ local Key\ do\ local _class_0\ local _base_0 = {\ tostring = function(self, strict)\ if strict == nil then\ strict = false\ end\ if not strict and self.name == '' then\ return self.type\ else\ return tostring(self.name) .. \": \" .. tostring(self.type)\ end\ end,\ __tostring = function(self)\ return self:tostring()\ end\ }\ _base_0.__index = _base_0\ _class_0 = setmetatable({\ __init = function(self, opts, second)\ if 'string' == type(second) then\ self.name, self.type = (opts or ''), second\ elseif 'string' == type(opts) then\ self.name, self.type = opts:match('^([%w-_]*): *(.+)$')\ if not self.name then\ self.name = ''\ self.type = opts:match('^ *(.+)$')\ end\ elseif 'table' == type(opts) then\ self.name = opts.name or ''\ self.type = opts.type\ else\ error(\"wrong argument type: \" .. tostring(type(opts)) .. \", \" .. tostring(type(second)))\ end\ assert(('string' == type(self.name)), \"name is not a string: '\" .. tostring(self.name) .. \"'\")\ return assert(('string' == type(self.type)), \"type is not a string: '\" .. tostring(self.type) .. \"'\")\ end,\ __base = _base_0,\ __name = \"Key\"\ }, {\ __index = _base_0,\ __call = function(cls, ...)\ local _self_0 = setmetatable({}, _base_0)\ cls.__init(_self_0, ...)\ return _self_0\ end\ })\ _base_0.__class = _class_0\ Key = _class_0\ end\ local inext\ inext = function(tbl, i)\ i = i + 1\ do\ local v = tbl[i]\ if v then\ return i, v\ end\ end\ end\ local Fileder\ do\ local _class_0\ local _base_0 = {\ load = function(self, index)\ assert(not self.loaded, \"already loaded!\")\ self.loaded = true\ index = index or self.store:get_index(self.path)\ local _list_0 = index.children\ for _index_0 = 1, #_list_0 do\ local path_or_index = _list_0[_index_0]\ local child = Fileder(self.store, path_or_index, self.root)\ local name = child:get('name: alpha')\ if '$' ~= name:sub(1, 1) then\ table.insert(self.children, child)\ else\ self.children[name] = child\ end\ end\ local _list_1 = index.facets\ for _index_0 = 1, #_list_1 do\ local key = _list_1[_index_0]\ key = Key(key)\ self.facet_keys[key] = key\ if MODE == 'CLIENT' and key.type:match('text/moonscript') then\ local copy = Key(key.name, key.type:gsub('text/moonscript', 'text/lua'))\ self.facet_keys[copy] = copy\ end\ end\ local _, name = dir_base(self.path)\ local name_key = Key('name: alpha')\ self.facet_keys[name_key] = name_key\ self.facets[name_key] = name\ end,\ walk = function(self, path)\ if path == '' then\ return self\ end\ if '/' ~= path:sub(1, 1) then\ path = tostring(self.path) .. \"/\" .. tostring(path)\ end\ if not (self.path == path:sub(1, #self.path)) then\ return \ end\ if #path == #self.path then\ return self\ end\ if not (self.loaded) then\ self:load()\ end\ do\ local match = self.children['$mmm'] and self.children['$mmm']:walk(path)\ if match then\ return match\ end\ end\ local _list_0 = self.children\ for _index_0 = 1, #_list_0 do\ local child = _list_0[_index_0]\ do\ local match = child:walk(path)\ if match then\ return match\ end\ end\ end\ end,\ mount = function(self, path, mount_as)\ if not mount_as then\ path = path .. self:gett('name: alpha')\ end\ assert(not self.path or self.path == path, \"mounted twice: \" .. tostring(self.path) .. \" and now \" .. tostring(path))\ self.path = path\ local _list_0 = self.children\ for _index_0 = 1, #_list_0 do\ local child = _list_0[_index_0]\ child:mount(self.path .. '/')\ end\ end,\ iterate = function(self, depth)\ if depth == nil then\ depth = 0\ end\ coroutine.yield(self)\ if depth == 1 then\ return \ end\ local _list_0 = self.children\ for _index_0 = 1, #_list_0 do\ local child = _list_0[_index_0]\ child:iterate(depth - 1)\ end\ end,\ get_facets = function(self)\ local names = { }\ for str, key in pairs(self.facet_keys) do\ names[key.name] = true\ end\ local _accum_0 = { }\ local _len_0 = 1\ for name in pairs(names) do\ _accum_0[_len_0] = name\ _len_0 = _len_0 + 1\ end\ return _accum_0\ end,\ has = function(self, ...)\ local want = Key(...)\ return self.facet_keys[want]\ end,\ has_facet = function(self, want)\ for str, key in pairs(self.facet_keys) do\ local _continue_0 = false\ repeat\ if key.original then\ _continue_0 = true\ break\ end\ if key.name == want then\ return key\ end\ _continue_0 = true\ until true\ if not _continue_0 then\ break\ end\ end\ end,\ find = function(self, key, key2, ...)\ local want = Key(key, key2)\ local matching\ do\ local _accum_0 = { }\ local _len_0 = 1\ for str, key in pairs(self.facet_keys) do\ if key.name == want.name then\ _accum_0[_len_0] = key\ _len_0 = _len_0 + 1\ end\ end\ matching = _accum_0\ end\ if not (#matching > 0) then\ return \ end\ local shortest_path, start = get_conversions(self, want.type, (function()\ local _accum_0 = { }\ local _len_0 = 1\ for _index_0 = 1, #matching do\ local key = matching[_index_0]\ _accum_0[_len_0] = key.type\ _len_0 = _len_0 + 1\ end\ return _accum_0\ end)(), ...)\ if start then\ for _index_0 = 1, #matching do\ local key = matching[_index_0]\ if key.type == start then\ return key, shortest_path\ end\ end\ return error(\"couldn't find key after resolution?\")\ end\ end,\ get = function(self, ...)\ local want = Key(...)\ do\ local val = self.facets[want]\ if val then\ return val, want\ end\ end\ do\ local val = CACHE and CACHE:get(self, want)\ if val then\ return val, want\ end\ end\ local key, conversions = self:find(want)\ if key then\ local value = apply_conversions(self, conversions, self.facets[key], key)\ if CACHE then\ CACHE:set(self, want, value)\ end\ return value, key\ end\ end,\ gett = function(self, ...)\ local want = Key(...)\ local value, key = self:get(want)\ assert(value, tostring(self) .. \" doesn't have value for '\" .. tostring(want) .. \"'\")\ return value, key\ end,\ set = function(self, key, key2, value)\ if value then\ key = Key(key, key2)\ else\ key = Key(key)\ value = key2\ end\ if value == nil then\ self.store:remove_facet(self.path, key.name, key.type)\ elseif self.facet_keys[key] then\ self.store:update_facet(self.path, key.name, key.type, value)\ else\ self.store:create_facet(self.path, key.name, key.type, value)\ end\ self.facets[key] = value\ end,\ add_child = function(self, name)\ local new_path = self.store:create_fileder(self.path, name)\ do\ local new_child = Fileder(self.store, new_path, self.root)\ table.insert(self.children, new_child)\ return new_child\ end\ end,\ remove_child = function(self, i)\ local removed = table.remove(self.children, i)\ assert(removed, \"no such child fileder\")\ return self.store:remove_fileder(removed.path)\ end,\ swap_children = function(self, ia, ib)\ local a, b = self.children[ia], self.children[ib]\ self.store:swap_fileders(self.path, (a:gett('name: alpha')), (b:gett('name: alpha')))\ self.children[ia], self.children[ib] = b, a\ end,\ __tostring = function(self)\ return \"Fileder:\" .. tostring(self.path)\ end\ }\ _base_0.__index = _base_0\ _class_0 = setmetatable({\ __init = function(self, store, path, root)\ if path == nil then\ path = ''\ end\ if root == nil then\ root = self\ end\ self.store, self.path, self.root = store, path, root\ self.loaded = false\ self.children = setmetatable({ }, {\ __len = function(t)\ if not (self.loaded) then\ self:load()\ end\ return rawlen(t)\ end,\ __ipairs = function(t)\ if not (self.loaded) then\ self:load()\ end\ return inext, t, 0\ end,\ __index = function(t, k)\ if not (self.loaded) then\ self:load()\ end\ if 'string' == type(k) and '$' ~= k:sub(1, 1) then\ return self:walk(tostring(self.path) .. \"/\" .. tostring(k))\ end\ end,\ __newindex = function(t, k, child)\ rawset(t, k, child)\ if child.path then\ return \ end\ return child:mount(self.path .. '/')\ end\ })\ self.facet_keys = setmetatable({ }, {\ __pairs = function(t)\ if not (self.loaded) then\ self:load()\ end\ return next, t\ end,\ __index = function(t, k)\ local canonical = rawget(t, tostring(k))\ return canonical\ end,\ __newindex = function(t, k, v)\ k = Key(k)\ return rawset(t, (tostring(k)), v)\ end\ })\ self.facets = setmetatable({ }, {\ __index = function(t, k)\ if not (self.loaded) then\ self:load()\ end\ k = self.facet_keys[k]\ if not (k) then\ return \ end\ do\ local v = rawget(t, k)\ if v then\ return v\ end\ end\ do\ local v = self.store:load_facet(self.path, k.name, k.type)\ rawset(t, k, v)\ return v\ end\ end,\ __pairs = function(t)\ if not (self.loaded) then\ self:load()\ end\ for k, v in pairs(self.facet_keys) do\ local _ = t[v]\ end\ return next, t\ end,\ __newindex = function(t, k, v)\ local key = self.facet_keys[k]\ if not key then\ key = Key(k)\ self.facet_keys[key] = key\ end\ rawset(t, key, v)\ if not v then\ self.facet_keys[key] = nil\ end\ end\ })\ if 'table' == type(self.path) then\ local index = self.path\ self.path = index.path\ self:load(index)\ end\ return assert(('string' == type(self.path)), \"invalid path: '\" .. tostring(self.path) .. \"'\")\ end,\ __base = _base_0,\ __name = \"Fileder\"\ }, {\ __index = _base_0,\ __call = function(cls, ...)\ local _self_0 = setmetatable({}, _base_0)\ cls.__init(_self_0, ...)\ return _self_0\ end\ })\ _base_0.__class = _class_0\ Fileder = _class_0\ end\ return {\ Key = Key,\ Fileder = Fileder,\ dir_base = dir_base\ }", "mmm/mmmfs/fileder.moon"} p["mmm.mmmfs.conversion"] = {"local refs = require('mmm.refs')\ local Queue\ Queue = require('mmm.mmmfs.queue').Queue\ local get_plugins\ get_plugins = require('mmm.mmmfs.meta').get_plugins\ local builtins = require('mmm.mmmfs.builtins')\ local count\ count = function(base, pattern)\ if pattern == nil then\ pattern = '->'\ end\ return select(2, base:gsub(pattern, ''))\ end\ local escape_pattern\ escape_pattern = function(inp)\ if '*' == inp:sub(-1) then\ inp = inp:sub(1, -2)\ return \"^\" .. tostring(inp:gsub('([^%w])', '%%%1'))\ else\ return \"^\" .. tostring(inp:gsub('([^%w])', '%%%1')) .. \"$\"\ end\ end\ local escape_inp\ escape_inp = function(inp)\ return \"^\" .. tostring(inp:gsub('([-/])', '%%%1')) .. \"$\"\ end\ local MermaidDebugger\ do\ local _class_0\ local _base_0 = {\ prepend = function(self, line)\ self.buf = \" \" .. tostring(line) .. \"\\n\" .. self.buf\ end,\ append = function(self, line)\ self.buf = self.buf .. \" \" .. tostring(line) .. \"\\n\"\ end,\ found_type = function(self, type)\ local type_id = self.type_id[type]\ end,\ type_cost = function(self, type, cost)\ do\ local old_cost = self.cost[type]\ if old_cost then\ cost = math.min(old_cost, cost)\ end\ end\ self.cost[type] = cost\ end,\ type_class = function(self, type, klass)\ return self:append(\"class \" .. tostring(self.type_id[type]) .. \" \" .. tostring(klass))\ end,\ found_link = function(self, frm, to, cost)\ return self:prepend(tostring(self.type_id[frm]) .. \" -- cost: \" .. tostring(cost) .. \" --> \" .. tostring(self.type_id[to]))\ end,\ render = function(self)\ for type, id in pairs(self.type_id) do\ local cost = self.cost[type] or -1\ self:prepend(tostring(id) .. \"[\\\"\" .. tostring(type) .. \" [\" .. tostring(cost) .. \"]\\\"]\")\ end\ self:append(\"classDef have fill:#ada\")\ self:append(\"classDef want fill:#add\")\ self:append(\"classDef cant fill:#daa\")\ return \"graph TD\\n\" .. self.buf\ end\ }\ _base_0.__index = _base_0\ _class_0 = setmetatable({\ __init = function(self)\ local nextid = 0\ self.type_id = setmetatable({ }, {\ __index = function(t, k)\ nextid = nextid + 1\ do\ local val = \"type-\" .. tostring(nextid)\ t[k] = val\ return val\ end\ end\ })\ self.cost = { }\ self.buf = \"\"\ end,\ __base = _base_0,\ __name = \"MermaidDebugger\"\ }, {\ __index = _base_0,\ __call = function(cls, ...)\ local _self_0 = setmetatable({}, _base_0)\ cls.__init(_self_0, ...)\ return _self_0\ end\ })\ _base_0.__class = _class_0\ MermaidDebugger = _class_0\ end\ local get_converts\ get_converts = function(fileder)\ local converts\ do\ local _accum_0 = { }\ local _len_0 = 1\ local _list_0 = builtins.converts\ for _index_0 = 1, #_list_0 do\ local c = _list_0[_index_0]\ _accum_0[_len_0] = c\ _len_0 = _len_0 + 1\ end\ converts = _accum_0\ end\ for plugin in get_plugins(fileder) do\ local _list_0 = (plugin:get('converts: table') or { })\ for _index_0 = 1, #_list_0 do\ local c = _list_0[_index_0]\ table.insert(converts, c)\ end\ end\ return converts\ end\ local get_conversions\ get_conversions = function(fileder, want, have, converts, limit, debug)\ if limit == nil then\ limit = 5\ end\ converts = converts or get_converts(fileder)\ assert(have, 'need starting type(s)')\ assert(converts, 'need to pass list of converts')\ if 'string' == type(have) then\ have = {\ have\ }\ end\ assert(#have > 0, 'need starting type(s) (list was empty)')\ want = escape_pattern(want)\ limit = limit + 3 * math.max(table.unpack((function()\ local _accum_0 = { }\ local _len_0 = 1\ for _index_0 = 1, #have do\ local type = have[_index_0]\ _accum_0[_len_0] = count(type)\ _len_0 = _len_0 + 1\ end\ return _accum_0\ end)()))\ if debug then\ debug:found_type(want)\ debug:type_cost(want, limit)\ debug:type_class(want, 'want')\ end\ local had = { }\ local queue = Queue()\ for _index_0 = 1, #have do\ local start = have[_index_0]\ if start:match(want) then\ return { }, start\ end\ queue:add({\ start = start,\ rest = start,\ conversions = { }\ }, 0, start)\ if debug then\ debug:found_type(start)\ debug:type_cost(start, 0)\ debug:type_class(start, 'have')\ end\ end\ local best = Queue()\ while true do\ local entry, cost = queue:pop()\ if not entry then\ break\ end\ if cost > limit then\ if debug then\ debug:type_class(entry.rest, 'cant')\ end\ break\ end\ local start, rest, conversions\ start, rest, conversions = entry.start, entry.rest, entry.conversions\ had[rest] = true\ for _index_0 = 1, #converts do\ local _continue_0 = false\ repeat\ local convert = converts[_index_0]\ local inp = escape_inp(convert.inp)\ if not (rest:match(inp)) then\ _continue_0 = true\ break\ end\ local result = rest:gsub(inp, convert.out)\ if not (result) then\ _continue_0 = true\ break\ end\ if had[result] then\ _continue_0 = true\ break\ end\ local next_entry = {\ start = start,\ rest = result,\ cost = cost + convert.cost,\ conversions = {\ {\ convert = convert,\ from = rest,\ to = result\ },\ table.unpack(conversions)\ }\ }\ if debug then\ debug:found_type(result)\ debug:type_cost(result, next_entry.cost)\ debug:found_link(rest, result, convert.cost)\ end\ if result:match(want) then\ best:add(next_entry, next_entry.cost)\ if debug then\ debug:found_link(result, want, 0)\ end\ else\ queue:add(next_entry, next_entry.cost, result)\ end\ _continue_0 = true\ until true\ if not _continue_0 then\ break\ end\ end\ end\ do\ local solution = best:pop()\ if solution then\ if solution then\ return solution.conversions, solution.start\ end\ end\ end\ end\ local print_conversions\ print_conversions = function(conversions)\ print(\"converting:\")\ for i = #conversions, 1, -1 do\ local step = conversions[i]\ print(\"- \" .. tostring(step.from) .. \" -> \" .. tostring(step.to) .. \" (\" .. tostring(step.convert.cost) .. \")\")\ end\ end\ local err_and_trace\ err_and_trace = function(msg)\ return debug.traceback(msg, 2)\ end\ local apply_conversions\ apply_conversions = function(fileder, conversions, value, key)\ for i = #conversions, 1, -1 do\ refs:push()\ local step = conversions[i]\ local ok\ ok, value = xpcall(step.convert.transform, err_and_trace, step, value, fileder, key)\ refs:pop()\ if not ok then\ error(\"error while converting \" .. tostring(fileder) .. \" \" .. tostring(key) .. \" from '\" .. tostring(step.from) .. \"' to '\" .. tostring(step.to) .. \"':\\n\" .. tostring(value))\ end\ end\ return value\ end\ local convert\ convert = function(have, want, value, fileder, key)\ local conversions, start = get_conversions(fileder, want, have)\ if not conversions then\ warn(\"couldn't convert from '\" .. tostring(have) .. \"' to '\" .. tostring(want) .. \"'\")\ return \ end\ if 'string' ~= type(have) then\ value = value[start]\ end\ return apply_conversions(fileder, conversions, value, key)\ end\ return {\ MermaidDebugger = MermaidDebugger,\ get_conversions = get_conversions,\ apply_conversions = apply_conversions,\ convert = convert\ }", "mmm/mmmfs/conversion.moon"} p["mmm.mmmfs.cache"] = {"local Cache\ do\ local _class_0\ local _base_0 = {\ get = function(self, fileder, key)\ key = tostring(key)\ local _update_0 = fileder.path\ self.cache[_update_0] = self.cache[_update_0] or { }\ return self.cache[fileder.path][key]\ end,\ set = function(self, fileder, key, val)\ key = tostring(key)\ local _update_0 = fileder.path\ self.cache[_update_0] = self.cache[_update_0] or { }\ self.cache[fileder.path][key] = val\ end\ }\ _base_0.__index = _base_0\ _class_0 = setmetatable({\ __init = function(self)\ self.cache = { }\ end,\ __base = _base_0,\ __name = \"Cache\"\ }, {\ __index = _base_0,\ __call = function(cls, ...)\ local _self_0 = setmetatable({}, _base_0)\ cls.__init(_self_0, ...)\ return _self_0\ end\ })\ _base_0.__class = _class_0\ Cache = _class_0\ end\ local init_cache\ init_cache = function()\ CACHE = Cache()\ end\ return {\ init_cache = init_cache\ }", "mmm/mmmfs/cache.moon"} p["mmm.mmmfs.queue"] = {"local Queue\ do\ local _class_0\ local _base_0 = {\ add = function(self, value, priority, key)\ local entry = {\ value = value,\ key = key,\ priority = priority\ }\ if key then\ do\ local old_entry = self.index[key]\ if old_entry then\ if old_entry.priority < priority then\ return \ end\ local i\ for ii, entry in ipairs(self.values) do\ if entry == old_entry then\ i = ii\ break\ end\ end\ table.remove(self.values, i)\ end\ end\ self.index[key] = entry\ end\ for i, v in ipairs(self.values) do\ if v.priority < priority then\ table.insert(self.values, i, entry)\ return \ end\ end\ return table.insert(self.values, entry)\ end,\ peek = function(self)\ local entry = self.values[#self.values]\ if entry then\ local value, priority, key\ value, priority, key = entry.value, entry.priority, entry.key\ if key then\ self.index[key] = nil\ end\ return value, priority\ end\ end,\ pop = function(self)\ local entry = table.remove(self.values)\ if entry then\ local value, priority, key\ value, priority, key = entry.value, entry.priority, entry.key\ if key then\ self.index[key] = nil\ end\ return value, priority\ end\ end,\ poll = function(self)\ return self.pop, self\ end\ }\ _base_0.__index = _base_0\ _class_0 = setmetatable({\ __init = function(self)\ self.values = { }\ self.index = { }\ end,\ __base = _base_0,\ __name = \"Queue\"\ }, {\ __index = _base_0,\ __call = function(cls, ...)\ local _self_0 = setmetatable({}, _base_0)\ cls.__init(_self_0, ...)\ return _self_0\ end\ })\ _base_0.__class = _class_0\ Queue = _class_0\ end\ return {\ Queue = Queue\ }", "mmm/mmmfs/queue.moon"} p["mmm.mmmfs.stores"] = {"local Store\ do\ local _class_0\ local _base_0 = {\ list_fileders_in = function(self)\ return error(\"not implemented\")\ end,\ list_all_fileders = function(self, path)\ if path == nil then\ path = ''\ end\ return coroutine.wrap(function()\ for path in self:list_fileders_in(path) do\ coroutine.yield(path)\ for p in self:list_all_fileders(path) do\ coroutine.yield(p)\ end\ end\ end)\ end,\ get_index = function(self, path, depth)\ if path == nil then\ path = ''\ end\ if depth == nil then\ depth = 1\ end\ if depth == 0 then\ return path\ end\ return {\ path = path,\ facets = (function()\ local _accum_0 = { }\ local _len_0 = 1\ for name, type in self:list_facets(path) do\ _accum_0[_len_0] = {\ name = name,\ type = type\ }\ _len_0 = _len_0 + 1\ end\ return _accum_0\ end)(),\ children = (function()\ local _accum_0 = { }\ local _len_0 = 1\ for child in self:list_fileders_in(path) do\ _accum_0[_len_0] = self:get_index(child, depth - 1)\ _len_0 = _len_0 + 1\ end\ return _accum_0\ end)()\ }\ end,\ create_fileder = function(self)\ return error(\"not implemented\")\ end,\ remove_fileder = function(self)\ return error(\"not implemented\")\ end,\ rename_fileder = function(self)\ return error(\"not implemented\")\ end,\ move_fileder = function(self)\ return error(\"not implemented\")\ end,\ list_facets = function(self)\ return error(\"not implemented\")\ end,\ create_facet = function(self)\ return error(\"not implemented\")\ end,\ remove_facet = function(self)\ return error(\"not implemented\")\ end,\ load_facet = function(self)\ return error(\"not implemented\")\ end,\ rename_facet = function(self, path, name, type, next_name)\ self:log(\"renaming facet \" .. tostring(path) .. \" | \" .. tostring(name) .. \": \" .. tostring(type) .. \" -> \" .. tostring(next_name))\ local blob = assert(\"no such facet\", self:load_facet(path, name, type))\ self:create_facet(path, next_name, type, blob)\ return self:remove_facet(path, name, type({\ update_facet = function(self)\ return error(\"not implemented\")\ end\ }))\ end,\ close = function(self) end,\ fsck = function(self) end,\ log = function(self, ...)\ return print(\"[\" .. tostring(self.__class.__name) .. \"]\", ...)\ end\ }\ _base_0.__index = _base_0\ _class_0 = setmetatable({\ __init = function(self, opts)\ opts.verbose = opts.verbose or false\ if not opts.verbose then\ self.log = function() end\ end\ end,\ __base = _base_0,\ __name = \"Store\"\ }, {\ __index = _base_0,\ __call = function(cls, ...)\ local _self_0 = setmetatable({}, _base_0)\ cls.__init(_self_0, ...)\ return _self_0\ end\ })\ _base_0.__class = _class_0\ Store = _class_0\ end\ local get_store\ get_store = function(args, opts)\ if args == nil then\ args = 'fs'\ end\ if opts == nil then\ opts = { }\ end\ local type, arg = args:match('(%w+):(.*)')\ if not (type) then\ type = args\ end\ local _exp_0 = type:lower()\ if 'sql' == _exp_0 then\ local SQLStore\ SQLStore = require('mmm.mmmfs.stores.sql').SQLStore\ if arg == 'MEMORY' then\ opts.memory = true\ else\ opts.file = arg\ end\ return SQLStore(opts)\ elseif 'fs' == _exp_0 then\ local FSStore\ FSStore = require('mmm.mmmfs.stores.fs').FSStore\ opts.root = arg\ return FSStore(opts)\ else\ warn(\"unknown or missing value for STORE: valid types values are sql, fs\")\ return os.exit(1)\ end\ end\ return {\ Store = Store,\ get_store = get_store\ }", "mmm/mmmfs/stores/init.moon"} p["mmm.mmmfs.stores.web"] = {"local Store\ Store = require('mmm.mmmfs.stores').Store\ local location, XMLHttpRequest, JSON, Object, Array\ do\ local _obj_0 = js.global\ location, XMLHttpRequest, JSON, Object, Array = _obj_0.location, _obj_0.XMLHttpRequest, _obj_0.JSON, _obj_0.Object, _obj_0.Array\ end\ local dir_base\ dir_base = function(path)\ local dir, base = path:match('(.-)([^/]-)$')\ if dir and #dir > 0 then\ dir = dir:sub(1, #dir - 1)\ end\ return dir, base\ end\ local req\ req = function(method, url, content)\ if content == nil then\ content = js.null\ end\ if not url then\ url = method\ method = 'GET'\ end\ local request = js.new(XMLHttpRequest)\ request:open(method, url, false)\ request:send(content)\ assert(request.status == 200, \"unexpected status code: \" .. tostring(request.status))\ return request.responseText\ end\ local parse_json\ do\ local fix\ fix = function(val)\ local _exp_0 = type(val)\ if 'userdata' == _exp_0 then\ if Array:isArray(val) then\ local _accum_0 = { }\ local _len_0 = 1\ for x in js.of(val) do\ _accum_0[_len_0] = fix(x)\ _len_0 = _len_0 + 1\ end\ return _accum_0\ else\ local _tbl_0 = { }\ for e in js.of(Object:entries(val)) do\ _tbl_0[(fix(e[0]))] = (fix(e[1]))\ end\ return _tbl_0\ end\ else\ return val\ end\ end\ parse_json = function(string)\ return fix(JSON:parse(string))\ end\ end\ local WebStore\ do\ local _class_0\ local _parent_0 = Store\ local _base_0 = {\ get_index = function(self, path, depth)\ if path == nil then\ path = ''\ end\ if depth == nil then\ depth = 1\ end\ local pseudo\ if depth > 1 or depth < 0 then\ pseudo = '?tree'\ else\ pseudo = '?index'\ end\ local json = req(tostring(self.host .. path) .. \"/\" .. tostring(pseudo) .. \": text/json\")\ return parse_json(json)\ end,\ list_fileders_in = function(self, path)\ if path == nil then\ path = ''\ end\ return coroutine.wrap(function()\ local json = req(tostring(self.host .. path) .. \"/?index: text/json\")\ local index = parse_json(json)\ for child in js.of(index.children) do\ coroutine.yield(child.path)\ end\ end)\ end,\ create_fileder = function(self, parent, name)\ local path = tostring(parent) .. \"/\" .. tostring(name)\ self:log(\"creating fileder \" .. tostring(path))\ return req('POST', tostring(self.host .. path) .. \"/\")\ end,\ remove_fileder = function(self, path)\ self:log(\"removing fileder \" .. tostring(path))\ return req('DELETE', tostring(self.host .. path) .. \"/\")\ end,\ rename_fileder = function(self, path, next_name)\ self:log(\"renaming fileder \" .. tostring(path) .. \" -> '\" .. tostring(next_name) .. \"'\")\ return error(\"not implemented\")\ end,\ move_fileder = function(self, path, next_parent)\ self:log(\"moving fileder \" .. tostring(path) .. \" -> \" .. tostring(next_parent) .. \"/\")\ return error(\"not implemented\")\ end,\ swap_fileders = function(self, parent, child_a, child_b)\ return req('PUT', tostring(self.host .. parent) .. \"/\", \"swap\\n\" .. tostring(child_a) .. \"\\n\" .. tostring(child_b))\ end,\ list_facets = function(self, path)\ return coroutine.wrap(function()\ local json = req(tostring(self.host .. path) .. \"/?index: text/json\")\ local index = JSON:parse(json)\ for facet in js.of(index.facets) do\ coroutine.yield(facet.name, facet.type)\ end\ end)\ end,\ load_facet = function(self, path, name, type)\ self:log(\"loading facet \" .. tostring(path) .. \" \" .. tostring(name) .. \": \" .. tostring(type))\ return req(tostring(self.host .. path) .. \"/\" .. tostring(name) .. \": \" .. tostring(type))\ end,\ create_facet = function(self, path, name, type, blob)\ self:log(\"creating facet \" .. tostring(path) .. \" | \" .. tostring(name) .. \": \" .. tostring(type))\ return req('POST', tostring(self.host .. path) .. \"/\" .. tostring(name) .. \": \" .. tostring(type), blob)\ end,\ remove_facet = function(self, path, name, type)\ self:log(\"removing facet \" .. tostring(path) .. \" | \" .. tostring(name) .. \": \" .. tostring(type))\ return req('DELETE', tostring(self.host .. path) .. \"/\" .. tostring(name) .. \": \" .. tostring(type))\ end,\ rename_facet = function(self, path, name, type, next_name)\ self:log(\"renaming facet \" .. tostring(path) .. \" | \" .. tostring(name) .. \": \" .. tostring(type) .. \" -> \" .. tostring(next_name))\ local blob = assert(\"no such facet\", self:load_facet(path, name, type))\ self:create_facet(path, next_name, type, blob)\ return self:remove_facet(path, name, type)\ end,\ update_facet = function(self, path, name, type, blob)\ self:log(\"updating facet \" .. tostring(path) .. \" | \" .. tostring(name) .. \": \" .. tostring(type))\ return req('PUT', tostring(self.host .. path) .. \"/\" .. tostring(name) .. \": \" .. tostring(type), blob)\ end\ }\ _base_0.__index = _base_0\ setmetatable(_base_0, _parent_0.__base)\ _class_0 = setmetatable({\ __init = function(self, opts)\ if opts == nil then\ opts = { }\ end\ _class_0.__parent.__init(self, opts)\ if MODE == 'CLIENT' then\ local origin = location.origin\ opts.host = opts.host or origin\ end\ self.host = opts.host:match('^(.-)/?$')\ return self:log(\"connecting to '\" .. tostring(self.host) .. \"'...\")\ end,\ __base = _base_0,\ __name = \"WebStore\",\ __parent = _parent_0\ }, {\ __index = function(cls, name)\ local val = rawget(_base_0, name)\ if val == nil then\ local parent = rawget(cls, \"__parent\")\ if parent then\ return parent[name]\ end\ else\ return val\ end\ end,\ __call = function(cls, ...)\ local _self_0 = setmetatable({}, _base_0)\ cls.__init(_self_0, ...)\ return _self_0\ end\ })\ _base_0.__class = _class_0\ if _parent_0.__inherited then\ _parent_0.__inherited(_parent_0, _class_0)\ end\ WebStore = _class_0\ end\ return {\ WebStore = WebStore\ }", "mmm/mmmfs/stores/web.moon"} p["mmm.mmmfs.stores.sql"] = {"local sqlite = require('sqlite3')\ local Store\ Store = require('mmm.mmmfs.stores').Store\ local SQLStore\ do\ local _class_0\ local _parent_0 = Store\ local _base_0 = {\ close = function(self)\ return self.db:close()\ end,\ fetch = function(self, q, ...)\ local stmt = assert(self.db:prepare(q))\ if 0 < select('#', ...) then\ stmt:bind(...)\ end\ return stmt:irows()\ end,\ fetch_one = function(self, q, ...)\ local stmt = assert(self.db:prepare(q))\ if 0 < select('#', ...) then\ stmt:bind(...)\ end\ return stmt:first_irow()\ end,\ exec = function(self, q, ...)\ local stmt = assert(self.db:prepare(q))\ if 0 < select('#', ...) then\ stmt:bind(...)\ end\ local res = assert(stmt:exec())\ end,\ list_fileders_in = function(self, path)\ if path == nil then\ path = ''\ end\ return coroutine.wrap(function()\ for _des_0 in self:fetch('SELECT path\\n FROM fileder WHERE parent IS ?', path) do\ path = _des_0[1]\ coroutine.yield(path)\ end\ end)\ end,\ create_fileder = function(self, parent, name)\ local path = tostring(parent) .. \"/\" .. tostring(name)\ self:log(\"creating fileder \" .. tostring(path))\ self:exec('INSERT INTO fileder (path, parent)\\n VALUES (:path, :parent)', {\ path = path,\ parent = parent\ })\ local changes = self:fetch_one('SELECT changes()')\ assert(changes[1] == 1, \"couldn't create fileder - parent missing?\")\ return path\ end,\ remove_fileder = function(self, path)\ self:log(\"removing fileder \" .. tostring(path))\ return self:exec('DELETE FROM fileder\\n WHERE path LIKE :path || \"/%\"\\n OR path = :path', path)\ end,\ rename_fileder = function(self, path, next_name)\ self:log(\"renaming fileder \" .. tostring(path) .. \" -> '\" .. tostring(next_name) .. \"'\")\ error('not implemented')\ return self:exec('UPDATE fileder\\n SET path = parent || \"/\" || :next_name\\n WHERE path = :path', {\ path = path,\ next_name = next_name\ })\ end,\ move_fileder = function(self, path, next_parent)\ self:log(\"moving fileder \" .. tostring(path) .. \" -> \" .. tostring(next_parent) .. \"/\")\ return error('not implemented')\ end,\ list_facets = function(self, path)\ return coroutine.wrap(function()\ for _des_0 in self:fetch('SELECT facet.name, facet.type\\n FROM facet\\n INNER JOIN fileder ON facet.fileder_id = fileder.id\\n WHERE fileder.path = ?', path) do\ local name, type\ name, type = _des_0[1], _des_0[2]\ coroutine.yield(name, type)\ end\ end)\ end,\ load_facet = function(self, path, name, type)\ local v = self:fetch_one('SELECT facet.value\\n FROM facet\\n INNER JOIN fileder ON facet.fileder_id = fileder.id\\n WHERE fileder.path = :path\\n AND facet.name = :name\\n AND facet.type = :type', {\ path = path,\ name = name,\ type = type\ })\ return v and v[1]\ end,\ create_facet = function(self, path, name, type, blob)\ self:log(\"creating facet \" .. tostring(path) .. \" | \" .. tostring(name) .. \": \" .. tostring(type))\ self:exec('INSERT INTO facet (fileder_id, name, type, value)\\n SELECT id, :name, :type, :blob\\n FROM fileder\\n WHERE fileder.path = :path', {\ path = path,\ name = name,\ type = type,\ blob = blob\ })\ local changes = self:fetch_one('SELECT changes()')\ return assert(changes[1] == 1, \"couldn't create facet - fileder missing?\")\ end,\ remove_facet = function(self, path, name, type)\ self:log(\"removing facet \" .. tostring(path) .. \" | \" .. tostring(name) .. \": \" .. tostring(type))\ self:exec('DELETE FROM facet\\n WHERE name = :name\\n AND type = :type\\n AND fileder_id = (SELECT id FROM fileder WHERE path = :path)', {\ path = path,\ name = name,\ type = type\ })\ local changes = self:fetch_one('SELECT changes()')\ return assert(changes[1] == 1, \"no such facet\")\ end,\ rename_facet = function(self, path, name, type, next_name)\ self:log(\"renaming facet \" .. tostring(path) .. \" | \" .. tostring(name) .. \": \" .. tostring(type) .. \" -> \" .. tostring(next_name))\ self:exec('UPDATE facet\\n SET name = :next_name\\n WHERE name = :name\\n AND type = :type\\n AND fileder_id = (SELECT id FROM fileder WHERE path = :path)', {\ path = path,\ name = name,\ next_name = next_name,\ type = type\ })\ local changes = self:fetch_one('SELECT changes()')\ return assert(changes[1] == 1, \"no such facet\")\ end,\ update_facet = function(self, path, name, type, blob)\ self:log(\"updating facet \" .. tostring(path) .. \" | \" .. tostring(name) .. \": \" .. tostring(type))\ self:exec('UPDATE facet\\n SET value = :blob\\n WHERE facet.name = :name\\n AND facet.type = :type\\n AND facet.fileder_id = (SELECT id FROM fileder WHERE path = :path)', {\ path = path,\ name = name,\ type = type,\ blob = blob\ })\ local changes = self:fetch_one('SELECT changes()')\ return assert(changes[1] == 1, \"no such facet\")\ end\ }\ _base_0.__index = _base_0\ setmetatable(_base_0, _parent_0.__base)\ _class_0 = setmetatable({\ __init = function(self, opts)\ if opts == nil then\ opts = { }\ end\ _class_0.__parent.__init(self, opts)\ opts.file = opts.file or 'db.sqlite3'\ opts.memory = opts.memory or false\ if opts.memory then\ self:log(\"opening in-memory DB...\")\ self.db = sqlite.open_memory()\ else\ self:log(\"opening '\" .. tostring(opts.file) .. \"'...\")\ self.db = sqlite.open(opts.file)\ end\ return assert(self.db:exec([[ PRAGMA foreign_keys = ON;\ PRAGMA case_sensitive_like = ON;\ CREATE TABLE IF NOT EXISTS fileder (\ id INTEGER NOT NULL PRIMARY KEY,\ path TEXT NOT NULL UNIQUE,\ parent TEXT REFERENCES fileder(path)\ ON DELETE CASCADE\ ON UPDATE CASCADE\ );\ INSERT OR IGNORE INTO fileder (path, parent) VALUES (\"\", NULL);\ \ CREATE TABLE IF NOT EXISTS facet (\ fileder_id INTEGER NOT NULL\ REFERENCES fileder\ ON UPDATE CASCADE\ ON DELETE CASCADE,\ name TEXT NOT NULL,\ type TEXT NOT NULL,\ value BLOB NOT NULL,\ PRIMARY KEY (fileder_id, name, type)\ );\ CREATE INDEX IF NOT EXISTS facet_fileder_id ON facet(fileder_id);\ CREATE INDEX IF NOT EXISTS facet_name ON facet(name);\ ]]))\ end,\ __base = _base_0,\ __name = \"SQLStore\",\ __parent = _parent_0\ }, {\ __index = function(cls, name)\ local val = rawget(_base_0, name)\ if val == nil then\ local parent = rawget(cls, \"__parent\")\ if parent then\ return parent[name]\ end\ else\ return val\ end\ end,\ __call = function(cls, ...)\ local _self_0 = setmetatable({}, _base_0)\ cls.__init(_self_0, ...)\ return _self_0\ end\ })\ _base_0.__class = _class_0\ if _parent_0.__inherited then\ _parent_0.__inherited(_parent_0, _class_0)\ end\ SQLStore = _class_0\ end\ return {\ SQLStore = SQLStore\ }", "mmm/mmmfs/stores/sql.moon"} p["mmm.mmmfs.stores.fs"] = {"local lfs = require('lfs')\ local Store\ Store = require('mmm.mmmfs.stores').Store\ local dir_base\ dir_base = function(path)\ local dir, base = path:match('(.-)([^/]-)$')\ if dir and #dir > 0 then\ dir = dir:sub(1, #dir - 1)\ end\ return dir, base\ end\ local FSStore\ do\ local _class_0\ local _parent_0 = Store\ local _base_0 = {\ get_order = function(self, path, forgiving, include_meta)\ if forgiving == nil then\ forgiving = false\ end\ if include_meta == nil then\ include_meta = false\ end\ local entries = { }\ local sorted = { }\ for name in lfs.dir(self.root .. path) do\ local _continue_0 = false\ repeat\ if '.' == name:sub(1, 1) then\ _continue_0 = true\ break\ end\ if '$' == name:sub(1, 1) and not include_meta then\ _continue_0 = true\ break\ end\ local entry_path = tostring(self.root) .. tostring(path) .. \"/\" .. tostring(name)\ if 'directory' ~= lfs.attributes(entry_path, 'mode') then\ _continue_0 = true\ break\ end\ local entry = {\ name = name,\ path = tostring(path) .. \"/\" .. tostring(name)\ }\ entries[name] = entry\ if '$' == name:sub(1, 1) then\ table.insert(sorted, entry)\ sorted[name] = true\ end\ _continue_0 = true\ until true\ if not _continue_0 then\ break\ end\ end\ local order_file = tostring(self.root) .. tostring(path) .. \"/$order\"\ if 'file' == lfs.attributes(order_file, 'mode') then\ for line in io.lines(order_file) do\ local _continue_0 = false\ repeat\ local entry = entries[line]\ if not entry then\ if forgiving then\ self:log(\"removed stale entry '\" .. tostring(line) .. \"' from \" .. tostring(path) .. \"/$order\")\ _continue_0 = true\ break\ end\ error(\"entry in $order but not on disk: \" .. tostring(line) .. \" (at \" .. tostring(path) .. \")\")\ end\ table.insert(sorted, entry)\ sorted[line] = true\ _continue_0 = true\ until true\ if not _continue_0 then\ break\ end\ end\ else\ forgiving = true\ end\ local unsorted\ do\ local _accum_0 = { }\ local _len_0 = 1\ for name, entry in pairs(entries) do\ if not sorted[entry.name] then\ _accum_0[_len_0] = entry\ _len_0 = _len_0 + 1\ end\ end\ unsorted = _accum_0\ end\ if forgiving then\ for _index_0 = 1, #unsorted do\ local entry = unsorted[_index_0]\ self:log(\"adding new entry '\" .. tostring(entry.name) .. \"' in \" .. tostring(path) .. \"/$order\")\ table.insert(sorted, entry)\ end\ else\ assert(#unsorted == 0, unsorted[1] and \"entry on disk but not in $order: \" .. tostring(unsorted[1].path) .. \" (at \" .. tostring(path) .. \")\")\ end\ return sorted\ end,\ write_order = function(self, path, order)\ if order == nil then\ order = self:get_order(path, true)\ end\ local order_file = tostring(self.root) .. tostring(path) .. \"/$order\"\ if #order == 0 then\ os.remove(order_file)\ return \ end\ local file = assert(io.open(order_file, 'w'))\ for _index_0 = 1, #order do\ local _des_0 = order[_index_0]\ local name\ name = _des_0.name\ file:write(tostring(name) .. \"\\n\")\ end\ return file:close()\ end,\ list_fileders_in = function(self, path)\ if path == nil then\ path = ''\ end\ local sorted = self:get_order(path, nil, true)\ return coroutine.wrap(function()\ for _index_0 = 1, #sorted do\ local _des_0 = sorted[_index_0]\ path = _des_0.path\ coroutine.yield(path)\ end\ end)\ end,\ create_fileder = function(self, parent, name)\ local path = tostring(parent) .. \"/\" .. tostring(name)\ self:log(\"creating fileder \" .. tostring(path))\ assert(lfs.mkdir(self.root .. path))\ self:write_order(parent)\ return path\ end,\ remove_fileder = function(self, path)\ self:log(\"removing fileder \" .. tostring(path))\ local rmdir\ rmdir = function(path)\ for file in lfs.dir(path) do\ local _continue_0 = false\ repeat\ if '.' == file:sub(1, 1) then\ _continue_0 = true\ break\ end\ local file_path = tostring(path) .. \"/\" .. tostring(file)\ local _exp_0 = lfs.attributes(file_path, 'mode')\ if 'file' == _exp_0 then\ assert(os.remove(file_path))\ elseif 'directory' == _exp_0 then\ assert(rmdir(file_path))\ end\ _continue_0 = true\ until true\ if not _continue_0 then\ break\ end\ end\ return lfs.rmdir(path)\ end\ rmdir(self.root .. path)\ local parent = dir_base(path)\ return self:write_order(parent)\ end,\ rename_fileder = function(self, path, next_name)\ self:log(\"renaming fileder \" .. tostring(path) .. \" -> '\" .. tostring(next_name) .. \"'\")\ local parent, name = dir_base(path)\ return assert(os.rename(path, tostring(self.root) .. tostring(parent) .. \"/\" .. tostring(next_name)))\ end,\ move_fileder = function(self, path, next_parent)\ self:log(\"moving fileder \" .. tostring(path) .. \" -> \" .. tostring(next_parent) .. \"/\")\ local parent, name = dir_base(path)\ return assert(os.rename(self.root .. path, tostring(self.root) .. tostring(next_parent) .. \"/\" .. tostring(name)))\ end,\ swap_fileders = function(self, parent, name_a, name_b)\ self:log(\"swapping \" .. tostring(name_a) .. \" and \" .. tostring(name_b) .. \" in \" .. tostring(parent))\ local order = self:get_order(parent)\ local a, b\ for i, entry in ipairs(order) do\ if entry.name == name_a then\ a = i\ end\ if entry.name == name_b then\ b = i\ end\ if a and b then\ break\ end\ end\ assert(a, \"couldn't find \" .. tostring(parent) .. \"/\" .. tostring(name_a) .. \" in $order\")\ assert(b, \"couldn't find \" .. tostring(parent) .. \"/\" .. tostring(name_b) .. \" in $order\")\ order[a], order[b] = order[b], order[a]\ return self:write_order(parent, order)\ end,\ list_facets = function(self, path)\ return coroutine.wrap(function()\ for entry_name in lfs.dir(self.root .. path) do\ local _continue_0 = false\ repeat\ if '.' == entry_name:sub(1, 1) then\ _continue_0 = true\ break\ end\ if entry_name == '$order' then\ _continue_0 = true\ break\ end\ local entry_path = tostring(self.root .. path) .. \"/\" .. tostring(entry_name)\ if 'file' == lfs.attributes(entry_path, 'mode') then\ entry_name = (entry_name:match('(.*)%.%w+')) or entry_name\ entry_name = entry_name:gsub('%$', '/')\ local name, type = entry_name:match('([%w-_]+): *(.+)')\ if not name then\ name = ''\ type = entry_name\ end\ coroutine.yield(name, type)\ end\ _continue_0 = true\ until true\ if not _continue_0 then\ break\ end\ end\ end)\ end,\ tofp = function(self, path, name, type)\ if #name > 0 then\ type = tostring(name) .. \": \" .. tostring(type)\ end\ type = type:gsub('%/', '$')\ return self.root .. tostring(path) .. \"/\" .. tostring(type)\ end,\ locate = function(self, path, name, type)\ if not (lfs.attributes(self.root .. path, 'mode')) then\ return \ end\ type = type:gsub('%/', '$')\ if #name > 0 then\ name = tostring(name) .. \": \"\ end\ name = name .. type\ name = name:gsub('([^%w])', '%%%1')\ local file_name\ for entry_name in lfs.dir(self.root .. path) do\ local _continue_0 = false\ repeat\ if '.' == entry_name:sub(1, 1) then\ _continue_0 = true\ break\ end\ if (entry_name:match(\"^\" .. tostring(name) .. \"$\")) or entry_name:match(\"^\" .. tostring(name) .. \"%.%w+$\") then\ if file_name then\ error(\"two files match \" .. tostring(name) .. \": \" .. tostring(file_name) .. \" and \" .. tostring(entry_name) .. \"!\")\ end\ file_name = entry_name\ end\ _continue_0 = true\ until true\ if not _continue_0 then\ break\ end\ end\ return file_name and self.root .. tostring(path) .. \"/\" .. tostring(file_name)\ end,\ load_facet = function(self, path, name, type)\ local filepath = self:locate(path, name, type)\ if not (filepath) then\ return \ end\ local file = assert((io.open(filepath, 'rb')), \"couldn't open facet file '\" .. tostring(filepath) .. \"'\")\ do\ local _with_0 = file:read('*all')\ file:close()\ return _with_0\ end\ end,\ create_facet = function(self, path, name, type, blob)\ self:log(\"creating facet \" .. tostring(path) .. \" | \" .. tostring(name) .. \": \" .. tostring(type))\ assert(blob, \"cant create facet without value!\")\ local filepath = self:locate(path, name, type)\ assert(not filepath, \"facet file already exists!\")\ filepath = self:tofp(path, name, type)\ local file = assert((io.open(filepath, 'wb')), \"couldn't open facet file '\" .. tostring(filepath) .. \"'\")\ file:write(blob)\ return file:close()\ end,\ remove_facet = function(self, path, name, type)\ self:log(\"removing facet \" .. tostring(path) .. \" | \" .. tostring(name) .. \": \" .. tostring(type))\ local filepath = self:locate(path, name, type)\ assert(filepath, \"couldn't locate facet!\")\ return assert(os.remove(filepath))\ end,\ rename_facet = function(self, path, name, type, next_name)\ self:log(\"renaming facet \" .. tostring(path) .. \" | \" .. tostring(name) .. \": \" .. tostring(type) .. \" -> \" .. tostring(next_name))\ local filepath = self:locate(path, name, type)\ assert(filepath, \"couldn't locate facet!\")\ return assert(os.rename(filepath, self:tofp(path, next_name, type)))\ end,\ update_facet = function(self, path, name, type, blob)\ self:log(\"updating facet \" .. tostring(path) .. \" | \" .. tostring(name) .. \": \" .. tostring(type))\ local filepath = self:locate(path, name, type)\ assert(filepath, \"couldn't locate facet!\")\ local file = assert((io.open(filepath, 'wb')), \"couldn't open facet file '\" .. tostring(filepath) .. \"'\")\ file:write(blob)\ return file:close()\ end,\ fsck = function(self, path)\ if path == nil then\ path = ''\ end\ local order = self:get_order(path, true)\ self:write_order(path, order)\ for _index_0 = 1, #order do\ local _des_0 = order[_index_0]\ path = _des_0.path\ self:fsck(path)\ end\ end\ }\ _base_0.__index = _base_0\ setmetatable(_base_0, _parent_0.__base)\ _class_0 = setmetatable({\ __init = function(self, opts)\ if opts == nil then\ opts = { }\ end\ _class_0.__parent.__init(self, opts)\ opts.root = opts.root or 'root'\ self.root = opts.root:match('^(.-)/?$')\ return self:log(\"opening '\" .. tostring(opts.root) .. \"'...\")\ end,\ __base = _base_0,\ __name = \"FSStore\",\ __parent = _parent_0\ }, {\ __index = function(cls, name)\ local val = rawget(_base_0, name)\ if val == nil then\ local parent = rawget(cls, \"__parent\")\ if parent then\ return parent[name]\ end\ else\ return val\ end\ end,\ __call = function(cls, ...)\ local _self_0 = setmetatable({}, _base_0)\ cls.__init(_self_0, ...)\ return _self_0\ end\ })\ _base_0.__class = _class_0\ if _parent_0.__inherited then\ _parent_0.__inherited(_parent_0, _class_0)\ end\ FSStore = _class_0\ end\ return {\ FSStore = FSStore\ }", "mmm/mmmfs/stores/fs.moon"} p["mmm.mmmfs.browser"] = {"local Key\ Key = require('mmm.mmmfs.fileder').Key\ local converts\ converts = require('mmm.mmmfs.builtins').converts\ local get_conversions, apply_conversions\ do\ local _obj_0 = require('mmm.mmmfs.conversion')\ get_conversions, apply_conversions = _obj_0.get_conversions, _obj_0.apply_conversions\ end\ local ReactiveVar, get_or_create, text, elements, tohtml\ do\ local _obj_0 = require('mmm.component')\ ReactiveVar, get_or_create, text, elements, tohtml = _obj_0.ReactiveVar, _obj_0.get_or_create, _obj_0.text, _obj_0.elements, _obj_0.tohtml\ end\ local pre, div, nav, span, button, a, code, select, option\ pre, div, nav, span, button, a, code, select, option = elements.pre, elements.div, elements.nav, elements.span, elements.button, elements.a, elements.code, elements.select, elements.option\ local link_to\ link_to = (require('mmm.mmmfs.util'))(elements).link_to\ local languages\ languages = require('mmm.highlighting').languages\ local keep\ keep = function(var)\ local last = var:get()\ return var:map(function(val)\ last = val or last\ return last\ end)\ end\ local combine\ combine = function(...)\ local res = { }\ local lists = {\ ...\ }\ for _index_0 = 1, #lists do\ local list = lists[_index_0]\ for _index_1 = 1, #list do\ local val = list[_index_1]\ table.insert(res, val)\ end\ end\ return res\ end\ local casts = {\ {\ inp = 'URL.*',\ out = 'mmm/dom',\ cost = 0,\ transform = function(self, href)\ return span(a((code(href)), {\ href = href\ }))\ end\ }\ }\ local get_casts\ get_casts = function()\ return combine(casts, converts)\ end\ local Browser\ do\ local _class_0\ local err_and_trace, default_convert\ local _base_0 = {\ refresh = function(self, facet)\ if facet == nil then\ facet = self.facet:get()\ end\ if facet == true then\ return self.fileder:transform(function(i)\ return i\ end)\ else\ return self.content:set(self:get_content(facet))\ end\ end,\ get_content = function(self, prop, err, convert)\ if err == nil then\ err = self.error\ end\ if convert == nil then\ convert = default_convert\ end\ local clear_error\ clear_error = function()\ if MODE == 'CLIENT' then\ return err:set()\ end\ end\ local disp_error\ disp_error = function(msg)\ if MODE == 'CLIENT' then\ err:set(pre(msg))\ end\ warn(\"ERROR rendering content: \" .. tostring(msg))\ return div()\ end\ local active = self.fileder:get()\ if not (active) then\ return disp_error(\"fileder not found!\")\ end\ if not (prop) then\ return disp_error(\"facet not found!\")\ end\ local ok, res = xpcall(convert, err_and_trace, active, prop)\ if MODE == 'CLIENT' then\ document.body.classList:remove('loading')\ end\ if ok and res then\ clear_error()\ return res\ elseif ok then\ return div(\"[no conversion path to \" .. tostring(prop.type) .. \"]\")\ elseif res and res:match('%[nossr%]') then\ return div(\"[this page could not be pre-rendered on the server]\")\ else\ return disp_error(res)\ end\ end,\ get_inspector = function(self)\ self.inspect_prop = self.facet:map(function(prop)\ local active = self.fileder:get()\ local key = active and active:find(prop)\ if key and key.original then\ key = key.original\ end\ return key\ end)\ self.inspect_err = ReactiveVar()\ do\ local _with_0 = div({\ class = 'view inspector'\ })\ _with_0:append(nav({\ span('inspector'),\ button('close', {\ onclick = function(_, e)\ return self.inspect:set(false)\ end\ })\ }))\ _with_0:append(div({\ class = 'subnav',\ self.inspect_prop:map(function(current)\ current = current and current:tostring()\ local fileder = self.fileder:get()\ local onchange\ onchange = function(_, e)\ local facet = e.target.value\ if facet == '' then\ return \ end\ return self.inspect_prop:set(Key(facet))\ end\ do\ local _with_1 = select({\ onchange = onchange\ })\ _with_1:append(option('(none)', {\ value = '',\ disabled = true,\ selected = not value\ }))\ if fileder then\ for value in pairs(fileder.facet_keys) do\ _with_1:append(option(value, {\ value = value,\ selected = value == current\ }))\ end\ end\ return _with_1\ end\ end),\ div({\ style = {\ flex = '1'\ }\ })\ }))\ _with_0:append((function()\ do\ local _with_1 = div({\ class = self.inspect_err:map(function(e)\ if e then\ return 'error-wrap'\ else\ return 'error-wrap empty'\ end\ end)\ })\ _with_1:append(span(\"an error occured while rendering this view:\"))\ _with_1:append(self.inspect_err)\ return _with_1\ end\ end)())\ _with_0:append((function()\ do\ local _with_1 = pre({\ class = 'content'\ })\ _with_1:append(keep(self.inspect_prop:map(function(prop, old)\ return self:get_content(prop, self.inspect_err, function(fileder, facet)\ local value, key = fileder:get(facet)\ assert(key, \"couldn't @get \" .. tostring(facet))\ local conversions = get_conversions(fileder, 'mmm/dom', key.type, get_casts())\ assert(conversions, \"cannot cast '\" .. tostring(key.type) .. \"'\")\ return apply_conversions(fileder, conversions, value, facet)\ end)\ end)))\ return _with_1\ end\ end)())\ _with_0:append(nav({\ class = 'thing',\ span('children'),\ button('add', {\ onclick = function(_, e)\ local name = window:prompt(\"please enter the name of the child fileder:\", 'unnamed_fileder')\ if not name or name == '' or name == js.null then\ return \ end\ local child = self.fileder:get():add_child(name)\ return self:refresh(true)\ end\ })\ }))\ _with_0:append(self.fileder:map(function(fileder)\ do\ local _with_1 = div({\ class = 'children'\ })\ local num = #fileder.children\ for i, child in ipairs(fileder.children) do\ local name = child:gett('name: alpha')\ _with_1:append(div({\ style = {\ display = 'flex',\ ['justify-content'] = 'space-between'\ },\ span('- ', (link_to(child, code(name))), {\ style = {\ flex = 1\ }\ })\ }))\ end\ return _with_1\ end\ end))\ return _with_0\ end\ end,\ navigate = function(self, new)\ return self.path:set(new)\ end,\ todom = function(self)\ return tohtml(self)\ end\ }\ _base_0.__index = _base_0\ _class_0 = setmetatable({\ __init = function(self, root, path, facet, rehydrate)\ if rehydrate == nil then\ rehydrate = false\ end\ self.root = root\ BROWSER = self\ assert(self.root, 'root fileder is nil')\ self.path = ReactiveVar(path or '')\ self.fileder = self.path:map((function()\ local _base_1 = self.root\ local _fn_0 = _base_1.walk\ return function(...)\ return _fn_0(_base_1, ...)\ end\ end)())\ self.facet = ReactiveVar(Key(facet, 'mmm/dom'))\ if MODE == 'CLIENT' then\ self.fileder:subscribe(function(fileder)\ if not (fileder) then\ return \ end\ local last = self.facet and self.facet:get()\ return self.facet:set(Key((function()\ if last then\ return last.type\ else\ return 'mmm/dom'\ end\ end)()))\ end)\ end\ if MODE == 'CLIENT' then\ local logo = document:querySelector('header h1 > a > svg')\ local spin\ spin = function()\ logo.classList:add('spin')\ local _ = logo.parentElement.offsetWidth\ return logo.classList:remove('spin')\ end\ self.facet:subscribe(function(facet)\ document.body.classList:add('loading')\ spin()\ if self.skip then\ return \ end\ path = self.path:get()\ local state = js.global:eval('new Object()')\ state.path = path\ state.name = facet.name\ state.type = facet.type\ return window.history:pushState(state, '', tostring(path) .. \"/\" .. tostring((Key(facet.name, 'text/html+interactive')):tostring(true)))\ end)\ window.onpopstate = function(_, event)\ local state = event.state\ if state ~= js.null then\ self.skip = true\ self.path:set(state.path)\ self.facet:set(Key(state.name, state.type))\ self.skip = nil\ end\ end\ end\ self.inspect = ReactiveVar((MODE == 'CLIENT' and window.location.hash == '#inspect'))\ local main = get_or_create('div', 'browser-root', {\ class = 'main view'\ })\ if MODE == 'SERVER' then\ main:append(nav({\ id = 'browser-navbar',\ span('please stand by... interactivity loading :)')\ }))\ else\ main:prepend((function()\ do\ local _with_0 = get_or_create('nav', 'browser-navbar')\ _with_0.node.innerHTML = ''\ _with_0:append(span('path: ', self.path:map(function(path)\ do\ local _with_1 = div({\ class = 'path',\ style = {\ display = 'inline-block'\ }\ })\ local path_segment\ path_segment = function(name, href)\ return a(name, {\ href = tostring(href) .. \"/\",\ onclick = function(_, e)\ e:preventDefault()\ return self:navigate(href)\ end\ })\ end\ local href = ''\ path = path:match('^/(.*)')\ _with_1:append(path_segment('root', ''))\ while path do\ local name, rest = path:match('^([%w%-_%.]+)/(.*)')\ if not name then\ name = path\ end\ path = rest\ href = tostring(href) .. \"/\" .. tostring(name)\ _with_1:append('/')\ _with_1:append(path_segment(name, href))\ end\ return _with_1\ end\ end)))\ _with_0:append(span('view facet:', {\ style = {\ ['margin-right'] = '0'\ }\ }))\ _with_0:append(self.fileder:map(function(fileder)\ local onchange\ onchange = function(_, e)\ local type\ type = self.facet:get().type\ return self.facet:set(Key({\ name = e.target.value,\ type = type\ }))\ end\ local current = self.facet:get()\ current = current and current.name\ do\ local _with_1 = elements.select({\ onchange = onchange,\ disabled = not fileder,\ value = self.facet:map(function(f)\ return f and f.name\ end)\ })\ local has_main = fileder and fileder:has_facet('')\ _with_1:append(option('(main)', {\ value = '',\ disabled = not has_main,\ selected = current == ''\ }))\ if fileder then\ for i, value in ipairs(fileder:get_facets()) do\ local _continue_0 = false\ repeat\ if value == '' then\ _continue_0 = true\ break\ end\ _with_1:append(option(value, {\ value = value,\ selected = value == current\ }))\ _continue_0 = true\ until true\ if not _continue_0 then\ break\ end\ end\ end\ return _with_1\ end\ end))\ _with_0:append(self.inspect:map(function(enabled)\ if not enabled then\ return button('inspect', {\ onclick = function(_, e)\ return self.inspect:set(true)\ end\ })\ end\ end))\ return _with_0\ end\ end)())\ end\ self.error = ReactiveVar()\ main:append((function()\ do\ local _with_0 = get_or_create('div', 'browser-error', {\ class = self.error:map(function(e)\ if e then\ return 'error-wrap'\ else\ return 'error-wrap empty'\ end\ end)\ })\ _with_0:append((span(\"an error occured while rendering this view:\")), (rehydrate and _with_0.node.firstChild))\ _with_0:append(self.error)\ return _with_0\ end\ end)())\ main:append((function()\ do\ local _with_0 = get_or_create('div', 'browser-content', {\ class = 'content'\ })\ self.content = ReactiveVar((function()\ if rehydrate then\ return _with_0.node.lastChild\ else\ return self:get_content(self.facet:get())\ end\ end)())\ _with_0:append(keep(self.content))\ if MODE == 'CLIENT' then\ self.facet:subscribe(function(p)\ return window:setTimeout((function()\ return self:refresh(p)\ end), 150)\ end)\ end\ return _with_0\ end\ end)())\ if rehydrate then\ self.facet:set(self.facet:get())\ end\ local inspector = self.inspect:map(function(enabled)\ if enabled then\ return self:get_inspector()\ end\ end)\ local wrapper = get_or_create('div', 'browser-wrapper', main, inspector, {\ class = 'browser'\ })\ self.node = wrapper.node\ do\ local _base_1 = wrapper\ local _fn_0 = _base_1.render\ self.render = function(...)\ return _fn_0(_base_1, ...)\ end\ end\ end,\ __base = _base_0,\ __name = \"Browser\"\ }, {\ __index = _base_0,\ __call = function(cls, ...)\ local _self_0 = setmetatable({}, _base_0)\ cls.__init(_self_0, ...)\ return _self_0\ end\ })\ _base_0.__class = _class_0\ local self = _class_0\ err_and_trace = function(msg)\ return debug.traceback(msg, 2)\ end\ default_convert = function(self, key)\ return self:get(key.name, 'mmm/dom')\ end\ default_convert = function(self, key)\ return self:get(key.name, 'mmm/dom')\ end\ Browser = _class_0\ end\ return {\ Browser = Browser\ }", "mmm/mmmfs/browser.moon"} p["mmm.mmmfs.meta"] = {"local yield_ancestors\ do\ local step\ step = function(self, path)\ if '/' ~= path:sub(1, 1) then\ path = tostring(self.path) .. \"/\" .. tostring(path)\ end\ if not (self.path == path:sub(1, #self.path)) then\ return \ end\ if #path == #self.path then\ return \ end\ coroutine.yield(self)\ local _list_0 = self.children\ for _index_0 = 1, #_list_0 do\ local child = _list_0[_index_0]\ step(child, path)\ end\ end\ yield_ancestors = function(self, path)\ return coroutine.wrap(function()\ return step(self, path)\ end)\ end\ end\ local get_meta\ get_meta = function(fileder, path)\ if path then\ path = \"$mmm/\" .. tostring(path)\ else\ path = '$mmm'\ end\ local guard_self\ local max_path = fileder.path\ do\ local closest = max_path:match('(.-)/$mmm')\ if closest then\ max_path = closest\ guard_self = true\ end\ end\ assert(fileder.root, \"'\" .. tostring(fileder) .. \"' has no root!\")\ return coroutine.wrap(function()\ for ancestor in yield_ancestors(fileder.root, max_path) do\ if guard_self and ancestor.path == max_path then\ break\ end\ do\ local result = ancestor:walk(path)\ if result then\ coroutine.yield(result)\ end\ end\ end\ do\ local result = not guard_self and fileder:walk(path)\ if result then\ return coroutine.yield(result)\ end\ end\ end)\ end\ local get_plugins\ get_plugins = function(fileder)\ return coroutine.wrap(function()\ for plugins in get_meta(fileder, 'plugins') do\ local _list_0 = plugins.children\ for _index_0 = 1, #_list_0 do\ local plugin = _list_0[_index_0]\ coroutine.yield(plugin)\ end\ end\ end)\ end\ return {\ get_meta = get_meta,\ get_plugins = get_plugins\ }", "mmm/mmmfs/meta.moon"} p["mmm.mmmfs.util"] = {"local refs = require('mmm.refs')\ local merge\ merge = function(orig, extra)\ if orig == nil then\ orig = { }\ end\ if extra == nil then\ extra = { }\ end\ do\ local attr\ do\ local _tbl_0 = { }\ for k, v in pairs(orig) do\ _tbl_0[k] = v\ end\ attr = _tbl_0\ end\ for k, v in pairs(extra) do\ attr[k] = v\ end\ return attr\ end\ end\ local tourl\ tourl = function(path, _view)\ path = path .. '/'\ if STATIC and STATIC.root then\ path = STATIC.root .. path\ end\ if _view then\ path = path .. _view\ end\ return path\ end\ return function(elements)\ local a, div, span, sup, b, pre\ a, div, span, sup, b, pre = elements.a, elements.div, elements.span, elements.sup, elements.b, elements.pre\ local find_fileder\ find_fileder = function(path, origin)\ if 'string' == type(path) then\ if path == '' then\ assert(origin, \"cannot resolve empty path without origin!\")\ return origin\ end\ if '/' ~= path:sub(1, 1) then\ assert(origin, \"cannot resolve relative path '\" .. tostring(path) .. \"' without origin!\")\ path = tostring(origin.path) .. \"/\" .. tostring(path)\ end\ while path:match('/([^/]-)/%.%./') do\ path = path:gsub('/([^/]-)/%.%./', '/')\ end\ if origin.path == path:sub(1, #origin.path) then\ return assert((origin:walk(path)), \"couldn't resolve path '\" .. tostring(path) .. \"' from \" .. tostring(origin))\ else\ return assert((origin.root:walk(path)), \"couldn't resolve path '\" .. tostring(path) .. \"'\")\ end\ else\ return assert(path, \"no path passed.\")\ end\ end\ local navigate_to\ navigate_to = function(path, name, opts)\ if opts == nil then\ opts = { }\ end\ opts.href = tourl(path)\ if MODE == 'CLIENT' then\ opts.onclick = function(self, e)\ e:preventDefault()\ return BROWSER:navigate(path)\ end\ end\ return a(name, opts)\ end\ local link_to\ link_to = function(fileder, name, origin, attr, _view)\ fileder = find_fileder(fileder, origin)\ name = name or fileder:get('title: mmm/dom')\ name = name or fileder:gett('name: alpha')\ do\ local href = fileder:get('link: URL*')\ if href then\ return a(name, merge(attr, {\ href = href,\ target = '_blank'\ }))\ else\ return a(name, merge(attr, {\ href = tourl(fileder.path, _view),\ onclick = (function()\ if MODE == 'CLIENT' then\ return function(self, e)\ e:preventDefault()\ return BROWSER:navigate(fileder.path)\ end\ end\ end)()\ }))\ end\ end\ end\ local interactive_link\ interactive_link = function(text, view)\ if view == nil then\ view = ':text/html+interactive'\ end\ assert(MODE == 'SERVER')\ local path = BROWSER.path\ if 'table' == type(BROWSER.path) then\ path = table.concat(path, '/')\ end\ return a(text, {\ href = tourl(path, view)\ })\ end\ local embed\ embed = function(fileder, name, origin, opts)\ if name == nil then\ name = ''\ end\ if opts == nil then\ opts = { }\ end\ if opts.raw then\ warn(\"deprecated option 'raw' set on embed\")\ assert(not opts.wrap, \"raw and wrap cannot both be set on embed\")\ opts.wrap = 'raw'\ end\ opts.wrap = opts.wrap or 'well'\ fileder = find_fileder(fileder, origin)\ local ok, node = pcall(fileder.gett, fileder, name, 'mmm/dom')\ if not ok then\ warn(\"couldn't embed \" .. tostring(fileder) .. \" \" .. tostring(name) .. \": \" .. tostring(node))\ return span({\ class = 'embed',\ style = {\ background = 'var(--gray-fail)',\ padding = '1em'\ },\ \"couldn't embed \" .. tostring(fileder) .. \" \" .. tostring(name),\ (pre(node))\ })\ end\ local klass = 'embed'\ if opts.desc then\ klass = klass .. ' desc'\ end\ if opts.inline then\ klass = klass .. ' inline'\ end\ local _exp_0 = opts.wrap\ if 'raw' == _exp_0 then\ return node\ elseif 'well' == _exp_0 then\ node = span({\ class = klass,\ style = opts.style,\ node,\ (function()\ if opts.desc then\ return div(opts.desc, {\ class = 'description'\ })\ end\ end)()\ })\ if opts.nolink then\ return node\ else\ return link_to(fileder, node, nil, opts.attr)\ end\ elseif 'sidenote' == _exp_0 then\ local key = tostring(refs:get())\ local id = \"sideref-\" .. tostring(key)\ local intext = sup(a(key, {\ href = \"#\" .. tostring(id)\ }))\ return span(intext, div({\ class = 'sidenote',\ style = opts.style or 'margin-top: -1.25rem;',\ div({\ id = id,\ class = 'hook'\ }),\ b(key, {\ class = 'ref'\ }),\ ' ',\ opts.desc or '',\ node\ }))\ elseif 'marginnote' == _exp_0 then\ return div({\ class = 'sidenote',\ style = opts.style,\ opts.desc or '',\ node\ })\ else\ return error(\"unknown embed 'wrap': '\" .. tostring(opts.wrap) .. \"'\")\ end\ end\ return {\ tourl = tourl,\ find_fileder = find_fileder,\ link_to = link_to,\ interactive_link = interactive_link,\ navigate_to = navigate_to,\ embed = embed\ }\ end", "mmm/mmmfs/util.moon"} p["mmm.mmmfs.builtins"] = {"local div, pre, code, img, video, span, source\ do\ local _obj_0 = require('mmm.dom')\ div, pre, code, img, video, span, source = _obj_0.div, _obj_0.pre, _obj_0.code, _obj_0.img, _obj_0.video, _obj_0.span, _obj_0.source\ end\ local find_fileder, link_to, embed\ do\ local _obj_0 = (require('mmm.mmmfs.util'))(require('mmm.dom'))\ find_fileder, link_to, embed = _obj_0.find_fileder, _obj_0.link_to, _obj_0.embed\ end\ local tohtml\ tohtml = require('mmm.component').tohtml\ local js_fix\ if MODE == 'CLIENT' then\ js_fix = function(arg)\ if arg == js.null then\ return \ end\ if arg == '' then\ return \ end\ return arg\ end\ end\ local js_bool\ if MODE == 'CLIENT' then\ js_bool = function(arg)\ if arg == js.null then\ return nil\ end\ if arg == 'false' then\ return false\ end\ return true\ end\ end\ local single\ single = function(func)\ return function(self, val)\ return func(val)\ end\ end\ local loadwith\ loadwith = function(_load)\ return function(self, val, fileder, key)\ local func = assert(_load(val, tostring(fileder) .. \"#\" .. tostring(key)))\ return func()\ end\ end\ string.yieldable_gsub = function(str, pat, f)\ str = str:gsub('%%', '%%|')\ local matches = { }\ local cnt\ str, cnt = str:gsub(pat, function(...)\ table.insert(matches, {\ ...\ })\ return \"%\" .. tostring(#matches)\ end)\ for _index_0 = 1, #matches do\ local match = matches[_index_0]\ match.replacement = f(table.unpack(match))\ end\ str = str:gsub('%%(%d+)', function(i)\ i = tonumber(i)\ return matches[i].replacement\ end)\ str = str:gsub('%%|', '%%')\ return str, cnt\ end\ local converts = {\ {\ inp = 'fn -> (.+)',\ out = '%1',\ cost = 1,\ transform = function(self, val, fileder)\ return val(fileder)\ end\ },\ {\ inp = 'mmm/component',\ out = 'mmm/dom',\ cost = 3,\ transform = single(tohtml)\ },\ {\ inp = 'mmm/dom',\ out = 'text/html+frag',\ cost = 3,\ transform = function(self, node)\ if MODE == 'SERVER' then\ return node\ else\ return node.outerHTML\ end\ end\ },\ {\ inp = 'text/html%+frag',\ out = 'mmm/dom',\ cost = 0.1,\ transform = (function()\ if MODE == 'SERVER' then\ return function(self, html, fileder)\ html = html:yieldable_gsub('(.-)', function(attrs, text)\ if #text == 0 then\ text = nil\ end\ local path, facet = '', ''\ while attrs and attrs ~= '' do\ local key, val, _attrs = attrs:match('^(%w+)=\"([^\"]-)\"%s*(.*)')\ if not key then\ key, _attrs = attrs:match('^(%w+)%s*(.*)$')\ val = true\ end\ attrs = _attrs\ local _exp_0 = key\ if 'path' == _exp_0 then\ path = val\ elseif 'facet' == _exp_0 then\ facet = val\ else\ warn(\"unkown attribute '\" .. tostring(key) .. \"=\\\"\" .. tostring(val) .. \"\\\"' in \")\ end\ end\ return link_to(path, text, fileder)\ end)\ html = html:yieldable_gsub('(.-)', function(attrs, desc)\ local path, facet = '', ''\ local opts = { }\ if #desc ~= 0 then\ opts.desc = desc\ end\ while attrs and attrs ~= '' do\ local key, val, _attrs = attrs:match('^(%w+)=\"([^\"]-)\"%s*(.*)')\ if not key then\ key, _attrs = attrs:match('^(%w+)%s*(.*)$')\ val = true\ end\ attrs = _attrs\ local _exp_0 = key\ if 'path' == _exp_0 then\ path = val\ elseif 'facet' == _exp_0 then\ facet = val\ elseif 'wrap' == _exp_0 then\ opts.wrap = val\ elseif 'style' == _exp_0 then\ opts.style = val\ elseif 'nolink' == _exp_0 then\ opts.nolink = true\ elseif 'inline' == _exp_0 then\ opts.inline = true\ elseif 'raw' == _exp_0 then\ opts.raw = true\ else\ warn(\"unkown attribute '\" .. tostring(key) .. \"=\\\"\" .. tostring(val) .. \"\\\"' in \")\ end\ end\ return embed(path, facet, fileder, opts)\ end)\ return html\ end\ else\ return function(self, html, fileder)\ local parent\ do\ local _with_0 = document:createElement('div')\ _with_0.innerHTML = html\ local embeds = _with_0:getElementsByTagName('mmm-embed')\ do\ local _accum_0 = { }\ local _len_0 = 1\ for i = 0, embeds.length - 1 do\ _accum_0[_len_0] = embeds[i]\ _len_0 = _len_0 + 1\ end\ embeds = _accum_0\ end\ for _index_0 = 1, #embeds do\ local element = embeds[_index_0]\ local path = js_fix(element:getAttribute('path'))\ local facet = js_fix(element:getAttribute('facet'))\ local wrap = js_fix(element:getAttribute('wrap'))\ local style = js_fix(element:getAttribute('style'))\ local nolink = js_bool(element:getAttribute('nolink'))\ local inline = js_bool(element:getAttribute('inline'))\ local desc = js_fix(element.innerText)\ if desc == '' then\ desc = nil\ end\ local raw = js_bool(element:getAttribute('raw'))\ local opts = {\ wrap = wrap,\ style = style,\ nolink = nolink,\ inline = inline,\ desc = desc,\ raw = raw\ }\ element:replaceWith(embed(path or '', facet or '', fileder, opts))\ end\ embeds = _with_0:getElementsByTagName('mmm-link')\ do\ local _accum_0 = { }\ local _len_0 = 1\ for i = 0, embeds.length - 1 do\ _accum_0[_len_0] = embeds[i]\ _len_0 = _len_0 + 1\ end\ embeds = _accum_0\ end\ for _index_0 = 1, #embeds do\ local element = embeds[_index_0]\ local text = js_fix(element.innerText)\ local path = js_fix(element:getAttribute('path'))\ element:replaceWith(link_to(path or '', text, fileder))\ end\ parent = _with_0\ end\ assert(1 == parent.childElementCount, \"text/html with more than one child!\")\ return parent.firstElementChild\ end\ end\ end)()\ },\ {\ inp = 'mmm/tpl -> (.+)',\ out = '%1',\ cost = 1,\ transform = function(self, source, fileder)\ return source:yieldable_gsub('{{(.-)}}', function(expr)\ local path, facet = expr:match('^([%w%-_%./]*)%+(.*)')\ assert(path, \"couldn't match TPL expression '\" .. tostring(expr) .. \"'\")\ return (find_fileder(path, fileder)):gett(facet)\ end)\ end\ },\ {\ inp = 'time/iso8601-date',\ out = 'time/unix',\ cost = 0.5,\ transform = function(self, val)\ local year, _, month, day = val:match('^%s*(%d%d%d%d)(%-?)([01]%d)%2([0-3]%d)%s*$')\ assert(year, \"failed to parse ISO 8601 date: '\" .. tostring(val) .. \"'\")\ return os.time({\ year = year,\ month = month,\ day = day\ })\ end\ },\ {\ inp = 'URL -> image/.+',\ out = 'mmm/dom',\ cost = -4,\ transform = function(self, src, fileder)\ return img({\ src = src\ })\ end\ },\ {\ inp = 'URL -> video/.+%+gif',\ out = 'mmm/dom',\ cost = -4.01,\ transform = function(self, src)\ return video((source({\ src = src\ })), {\ controls = 'auto',\ loop = true,\ autoplay = true,\ muted = true\ })\ end\ },\ {\ inp = 'URL -> video/.+',\ out = 'mmm/dom',\ cost = -4,\ transform = function(self, src)\ return video((source({\ src = src\ })), {\ controls = true,\ loop = true\ })\ end\ },\ {\ inp = 'text/plain',\ out = 'mmm/dom',\ cost = 2,\ transform = function(self, val)\ return span(val)\ end\ },\ {\ inp = 'alpha',\ out = 'mmm/dom',\ cost = 2,\ transform = single(code)\ },\ {\ inp = 'URL -> (.+)',\ out = '%1',\ cost = 4,\ transform = (function()\ if MODE == 'CLIENT' then\ return function(self, uri)\ local request = js.new(js.global.XMLHttpRequest)\ request:open('GET', uri, false)\ request:send(js.null)\ assert(request.status == 200, \"unexpected status code: \" .. tostring(request.status))\ return request.responseText\ end\ else\ return function(self, uri)\ local request = require('http.request')\ local req = request.new_from_uri(uri)\ req.headers:upsert('origin', 'null')\ local headers, stream = assert(req:go(8))\ return assert(stream:get_body_as_string())\ end\ end\ end)()\ },\ {\ inp = 'table',\ out = 'mmm/dom',\ cost = 5,\ transform = (function()\ local deep_tostring\ deep_tostring = function(tbl, space)\ if space == nil then\ space = ''\ end\ local buf = space .. tostring(tbl)\ if not ('table' == type(tbl)) then\ return buf\ end\ buf = buf .. ' {\\n'\ for k, v in pairs(tbl) do\ buf = buf .. tostring(space) .. \" [\" .. tostring(k) .. \"]: \" .. tostring(deep_tostring(v, space .. ' ')) .. \"\\n\"\ end\ buf = buf .. tostring(space) .. \"}\"\ return buf\ end\ return function(self, tbl)\ return pre(code(deep_tostring(tbl)))\ end\ end)()\ }\ }\ if STATIC then\ local extensions = {\ ['image/jpeg'] = 'jpg',\ ['image/png'] = 'png',\ ['image/svg+xml'] = 'svg',\ ['video/webm'] = 'webm',\ ['video/mp4'] = 'mp4',\ ['text/javascript'] = 'js',\ ['text/css'] = 'css',\ ['model/gltf-binary'] = 'glb'\ }\ table.insert(converts, {\ inp = '(.+)',\ out = 'URL -> %1',\ cost = 5,\ transform = function(self, val, fileder, key)\ local escaped_from = self.from:gsub('/', '_')\ do\ local ext = extensions[self.from]\ if ext then\ escaped_from = escaped_from .. \".\" .. tostring(ext)\ end\ end\ local prefix = STATIC.root or ''\ return prefix .. (function()\ do\ local url = tostring(fileder.path) .. \"/\" .. tostring(key.name) .. \":\" .. tostring(escaped_from)\ print(\" rendering asset \" .. tostring(url))\ STATIC.spit(url, val)\ return url\ end\ end)()\ end\ })\ else\ table.insert(converts, {\ inp = '(.+)',\ out = 'URL -> %1',\ cost = 5,\ transform = function(self, _, fileder, key)\ return tostring(fileder.path) .. \"/\" .. tostring(key.name) .. \":\" .. tostring(self.from)\ end\ })\ end\ if MODE == 'CLIENT' or UNSAFE then\ table.insert(converts, {\ inp = 'text/lua -> (.+)',\ out = '%1',\ cost = 0.5,\ transform = loadwith(load or loadstring)\ })\ end\ if MODE == 'CLIENT' then\ table.insert(converts, {\ inp = 'text/javascript -> (.+)',\ out = '%1',\ cost = 1,\ transform = function(self, source)\ local f = js.new(window.Function, source)\ return f()\ end\ })\ end\ local json_encode\ json_encode = function(obj)\ local _exp_0 = type(obj)\ if 'string' == _exp_0 then\ return string.format('%q', obj)\ elseif 'table' == _exp_0 then\ if obj[1] or not next(obj) then\ return \"[\" .. tostring(table.concat((function()\ local _accum_0 = { }\ local _len_0 = 1\ for _index_0 = 1, #obj do\ local c = obj[_index_0]\ _accum_0[_len_0] = json_encode(c)\ _len_0 = _len_0 + 1\ end\ return _accum_0\ end)(), ',')) .. \"]\"\ else\ return \"{\" .. tostring(table.concat((function()\ local _accum_0 = { }\ local _len_0 = 1\ for k, v in pairs(obj) do\ _accum_0[_len_0] = tostring(json_encode(k)) .. \": \" .. tostring(json_encode(v))\ _len_0 = _len_0 + 1\ end\ return _accum_0\ end)(), ', ')) .. \"}\"\ end\ elseif 'number' == _exp_0 then\ return tostring(obj)\ elseif 'boolean' == _exp_0 then\ return tostring(obj)\ elseif 'nil' == _exp_0 then\ return 'null'\ else\ return error(\"unknown type '\" .. tostring(type(obj)) .. \"'\")\ end\ end\ local json_decode\ if MODE == 'CLIENT' then\ local Array, Object, JSON\ do\ local _obj_0 = js.global\ Array, Object, JSON = _obj_0.Array, _obj_0.Object, _obj_0.JSON\ end\ local fix\ fix = function(val)\ local _exp_0 = type(val)\ if 'userdata' == _exp_0 then\ if Array:isArray(val) then\ local _accum_0 = { }\ local _len_0 = 1\ for x in js.of(val) do\ _accum_0[_len_0] = fix(x)\ _len_0 = _len_0 + 1\ end\ return _accum_0\ else\ local _tbl_0 = { }\ for e in js.of(Object:entries(val)) do\ _tbl_0[(fix(e[0]))] = (fix(e[1]))\ end\ return _tbl_0\ end\ else\ return val\ end\ end\ json_decode = function(str)\ return fix(JSON:parse(str))\ end\ else\ do\ local cjson = require('cjson')\ if cjson then\ json_decode = cjson.decode\ else\ warn('only partial JSON support, please install cjson')\ json_decode = nil\ end\ end\ end\ table.insert(converts, {\ inp = 'table',\ out = 'text/json',\ cost = 2,\ transform = function(self, val)\ return json_encode(val)\ end\ })\ if json_decode then\ table.insert(converts, {\ inp = 'text/json',\ out = 'table',\ cost = 1,\ transform = function(self, val)\ return json_decode(val)\ end\ })\ end\ return {\ converts = converts\ }", "mmm/mmmfs/builtins.moon"} p["mmm"] = {"window = js.global\ local console\ document, console = window.document, window.console\ MODE = 'CLIENT'\ UNSAFE = true\ local deep_tostring\ deep_tostring = function(tbl, space, recur)\ if space == nil then\ space = ''\ end\ if recur == nil then\ recur = { }\ end\ local buf = space .. tostring(tbl)\ if not ('table' == (type(tbl)) and not tbl.__tostring and not recur[tbl]) then\ return buf\ end\ recur[tbl] = true\ buf = buf .. ' {\\n'\ for k, v in pairs(tbl) do\ buf = buf .. tostring(space) .. \" [\" .. tostring(k) .. \"]: \" .. tostring(deep_tostring(v, space .. ' ', recur)) .. \"\\n\"\ end\ buf = buf .. tostring(space) .. \"}\"\ return buf\ end\ print = function(...)\ local contents\ do\ local _accum_0 = { }\ local _len_0 = 1\ local _list_0 = {\ ...\ }\ for _index_0 = 1, #_list_0 do\ local v = _list_0[_index_0]\ _accum_0[_len_0] = deep_tostring(v)\ _len_0 = _len_0 + 1\ end\ contents = _accum_0\ end\ return console:log(table.unpack(contents))\ end\ warn = function(...)\ local contents\ do\ local _accum_0 = { }\ local _len_0 = 1\ local _list_0 = {\ ...\ }\ for _index_0 = 1, #_list_0 do\ local v = _list_0[_index_0]\ _accum_0[_len_0] = deep_tostring(v)\ _len_0 = _len_0 + 1\ end\ contents = _accum_0\ end\ return console:warn(table.unpack(contents))\ end\ package.path = '/?.lua;/?/init.lua'\ if on_load then\ for _index_0 = 1, #on_load do\ local f = on_load[_index_0]\ f()\ end\ end\ on_load = setmetatable({ }, {\ __newindex = function(t, k, v)\ rawset(t, k, v)\ return v()\ end\ })", "mmm/init.client.moon"}